[Bf-blender-cvs] [8c7c4549d1f] master: Geometry Nodes: support Set Position node on instances

Jacques Lucke noreply at git.blender.org
Mon Sep 20 13:02:41 CEST 2021


Commit: 8c7c4549d1fba8eb2236fa397d95b32ad1262789
Author: Jacques Lucke
Date:   Mon Sep 20 12:49:11 2021 +0200
Branches: master
https://developer.blender.org/rB8c7c4549d1fba8eb2236fa397d95b32ad1262789

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

===================================================================

M	source/blender/blenkernel/BKE_geometry_set.hh
M	source/blender/blenkernel/intern/geometry_component_instances.cc
M	source/blender/nodes/geometry/nodes/node_geo_set_position.cc

===================================================================

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);



More information about the Bf-blender-cvs mailing list