Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacques Lucke <jacques@blender.org>2021-09-20 13:49:11 +0300
committerJacques Lucke <jacques@blender.org>2021-09-20 13:49:28 +0300
commit8c7c4549d1fba8eb2236fa397d95b32ad1262789 (patch)
tree3d22e7b87086722a8ce031fcc0daf821373192f9
parent11e11c41f2695f6f412079d438b675516aa8151a (diff)
Geometry Nodes: support Set Position node on instances
Previously, the node would always realize instances implicitly. Now it can change the position of entire instances. The Realize Instances node can be used before if the old behavior is required. Differential Revision: https://developer.blender.org/D12555
-rw-r--r--source/blender/blenkernel/BKE_geometry_set.hh5
-rw-r--r--source/blender/blenkernel/intern/geometry_component_instances.cc83
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_set_position.cc7
3 files changed, 92 insertions, 3 deletions
diff --git a/source/blender/blenkernel/BKE_geometry_set.hh b/source/blender/blenkernel/BKE_geometry_set.hh
index bf38294257a..98f5de43f84 100644
--- a/source/blender/blenkernel/BKE_geometry_set.hh
+++ b/source/blender/blenkernel/BKE_geometry_set.hh
@@ -591,12 +591,17 @@ class InstancesComponent : public GeometryComponent {
blender::Span<int> almost_unique_ids() const;
+ int attribute_domain_size(const AttributeDomain domain) const final;
+
bool is_empty() const final;
bool owns_direct_data() const override;
void ensure_owns_direct_data() override;
static constexpr inline GeometryComponentType static_type = GEO_COMPONENT_TYPE_INSTANCES;
+
+ private:
+ const blender::bke::ComponentAttributeProviders *get_attribute_providers() const final;
};
/** A geometry component that stores volume grids. */
diff --git a/source/blender/blenkernel/intern/geometry_component_instances.cc b/source/blender/blenkernel/intern/geometry_component_instances.cc
index 26ef827d36d..c4e1fe2f8e9 100644
--- a/source/blender/blenkernel/intern/geometry_component_instances.cc
+++ b/source/blender/blenkernel/intern/geometry_component_instances.cc
@@ -25,6 +25,8 @@
#include "BKE_geometry_set.hh"
+#include "attribute_access_intern.hh"
+
using blender::float4x4;
using blender::Map;
using blender::MutableSpan;
@@ -225,4 +227,85 @@ blender::Span<int> InstancesComponent::almost_unique_ids() const
return almost_unique_ids_;
}
+int InstancesComponent::attribute_domain_size(const AttributeDomain domain) const
+{
+ if (domain != ATTR_DOMAIN_POINT) {
+ return 0;
+ }
+ return this->instances_amount();
+}
+
+namespace blender::bke {
+
+static float3 get_transform_position(const float4x4 &transform)
+{
+ return transform.translation();
+}
+
+static void set_transform_position(float4x4 &transform, const float3 position)
+{
+ copy_v3_v3(transform.values[3], position);
+}
+
+class InstancePositionAttributeProvider final : public BuiltinAttributeProvider {
+ public:
+ InstancePositionAttributeProvider()
+ : BuiltinAttributeProvider(
+ "position", ATTR_DOMAIN_POINT, CD_PROP_FLOAT3, NonCreatable, Writable, NonDeletable)
+ {
+ }
+
+ GVArrayPtr try_get_for_read(const GeometryComponent &component) const final
+ {
+ const InstancesComponent &instances_component = static_cast<const InstancesComponent &>(
+ component);
+ Span<float4x4> transforms = instances_component.instance_transforms();
+ return std::make_unique<fn::GVArray_For_DerivedSpan<float4x4, float3, get_transform_position>>(
+ transforms);
+ }
+
+ GVMutableArrayPtr try_get_for_write(GeometryComponent &component) const final
+ {
+ InstancesComponent &instances_component = static_cast<InstancesComponent &>(component);
+ MutableSpan<float4x4> transforms = instances_component.instance_transforms();
+ return std::make_unique<fn::GVMutableArray_For_DerivedSpan<float4x4,
+ float3,
+ get_transform_position,
+ set_transform_position>>(
+ transforms);
+ }
+
+ bool try_delete(GeometryComponent &UNUSED(component)) const final
+ {
+ return false;
+ }
+
+ bool try_create(GeometryComponent &UNUSED(component),
+ const AttributeInit &UNUSED(initializer)) const final
+ {
+ return false;
+ }
+
+ bool exists(const GeometryComponent &UNUSED(component)) const final
+ {
+ return true;
+ }
+};
+
+static ComponentAttributeProviders create_attribute_providers_for_instances()
+{
+ static InstancePositionAttributeProvider position;
+
+ return ComponentAttributeProviders({&position}, {});
+}
+} // namespace blender::bke
+
+const blender::bke::ComponentAttributeProviders *InstancesComponent::get_attribute_providers()
+ const
+{
+ static blender::bke::ComponentAttributeProviders providers =
+ blender::bke::create_attribute_providers_for_instances();
+ return &providers;
+}
+
/** \} */
diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_position.cc b/source/blender/nodes/geometry/nodes/node_geo_set_position.cc
index 4c754ddb643..832db76e731 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_set_position.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_set_position.cc
@@ -51,12 +51,13 @@ static void set_position_in_component(GeometryComponent &component,
static void geo_node_set_position_exec(GeoNodeExecParams params)
{
GeometrySet geometry = params.extract_input<GeometrySet>("Geometry");
- geometry = geometry_set_realize_instances(geometry);
Field<bool> selection_field = params.extract_input<Field<bool>>("Selection");
Field<float3> position_field = params.extract_input<Field<float3>>("Position");
- for (const GeometryComponentType type :
- {GEO_COMPONENT_TYPE_MESH, GEO_COMPONENT_TYPE_POINT_CLOUD, GEO_COMPONENT_TYPE_CURVE}) {
+ for (const GeometryComponentType type : {GEO_COMPONENT_TYPE_MESH,
+ GEO_COMPONENT_TYPE_POINT_CLOUD,
+ GEO_COMPONENT_TYPE_CURVE,
+ GEO_COMPONENT_TYPE_INSTANCES}) {
if (geometry.has(type)) {
set_position_in_component(
geometry.get_component_for_write(type), selection_field, position_field);