[Bf-blender-cvs] [3db975f30dd] master: Fix T84326: No ID for geometry nodes instances after scattering

Hans Goudey noreply at git.blender.org
Thu Jan 7 16:30:47 CET 2021


Commit: 3db975f30dd327381dc1a0e08305460a1a12eba4
Author: Hans Goudey
Date:   Thu Jan 7 09:27:42 2021 -0600
Branches: master
https://developer.blender.org/rB3db975f30dd327381dc1a0e08305460a1a12eba4

Fix T84326: No ID for geometry nodes instances after scattering

Instances are created with an "index" parameter used for persistence over
time through animation. Currently the geometry nodes instancer passes
the index in the array for this value, but the arrays created by the
"Point Distribution" node aren't necessarily stable  in this way when
the input mesh is deformed. In D9832 we already mostly solved this
problem with an `id` attribute. The solution here is to create instances
with this attribute as well.

It's important to note that deforming the instanced points *after*
distribution will usually be a better solution for this problem. This
solution is likely still important though.

Differential Revision: https://developer.blender.org/D10024

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

M	source/blender/blenkernel/BKE_geometry_set.h
M	source/blender/blenkernel/BKE_geometry_set.hh
M	source/blender/blenkernel/intern/geometry_set.cc
M	source/blender/blenkernel/intern/object_dupli.c
M	source/blender/nodes/geometry/nodes/node_geo_point_instance.cc

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

diff --git a/source/blender/blenkernel/BKE_geometry_set.h b/source/blender/blenkernel/BKE_geometry_set.h
index 37a3ed82bb8..5b8273def66 100644
--- a/source/blender/blenkernel/BKE_geometry_set.h
+++ b/source/blender/blenkernel/BKE_geometry_set.h
@@ -49,6 +49,7 @@ int BKE_geometry_set_instances(const struct GeometrySet *geometry_set,
                                float (**r_positions)[3],
                                float (**r_rotations)[3],
                                float (**r_scales)[3],
+                               int **r_ids,
                                struct InstancedData **r_instanced_data);
 
 #ifdef __cplusplus
diff --git a/source/blender/blenkernel/BKE_geometry_set.hh b/source/blender/blenkernel/BKE_geometry_set.hh
index e4232a84a00..9dc2b80d4d4 100644
--- a/source/blender/blenkernel/BKE_geometry_set.hh
+++ b/source/blender/blenkernel/BKE_geometry_set.hh
@@ -364,6 +364,7 @@ class InstancesComponent : public GeometryComponent {
   blender::Vector<blender::float3> positions_;
   blender::Vector<blender::float3> rotations_;
   blender::Vector<blender::float3> scales_;
+  blender::Vector<int> ids_;
   blender::Vector<InstancedData> instanced_data_;
 
  public:
@@ -375,20 +376,24 @@ class InstancesComponent : public GeometryComponent {
   void add_instance(Object *object,
                     blender::float3 position,
                     blender::float3 rotation = {0, 0, 0},
-                    blender::float3 scale = {1, 1, 1});
+                    blender::float3 scale = {1, 1, 1},
+                    const int id = -1);
   void add_instance(Collection *collection,
                     blender::float3 position,
                     blender::float3 rotation = {0, 0, 0},
-                    blender::float3 scale = {1, 1, 1});
+                    blender::float3 scale = {1, 1, 1},
+                    const int id = -1);
   void add_instance(InstancedData data,
                     blender::float3 position,
                     blender::float3 rotation,
-                    blender::float3 scale);
+                    blender::float3 scale,
+                    const int id = -1);
 
   blender::Span<InstancedData> instanced_data() const;
   blender::Span<blender::float3> positions() const;
   blender::Span<blender::float3> rotations() const;
   blender::Span<blender::float3> scales() const;
+  blender::Span<int> ids() const;
   blender::MutableSpan<blender::float3> positions();
   int instances_amount() const;
 
diff --git a/source/blender/blenkernel/intern/geometry_set.cc b/source/blender/blenkernel/intern/geometry_set.cc
index 2a21a60ccc6..5d2b82dcc5f 100644
--- a/source/blender/blenkernel/intern/geometry_set.cc
+++ b/source/blender/blenkernel/intern/geometry_set.cc
@@ -476,34 +476,38 @@ void InstancesComponent::clear()
 void InstancesComponent::add_instance(Object *object,
                                       blender::float3 position,
                                       blender::float3 rotation,
-                                      blender::float3 scale)
+                                      blender::float3 scale,
+                                      const int id)
 {
   InstancedData data;
   data.type = INSTANCE_DATA_TYPE_OBJECT;
   data.data.object = object;
-  this->add_instance(data, position, rotation, scale);
+  this->add_instance(data, position, rotation, scale, id);
 }
 
 void InstancesComponent::add_instance(Collection *collection,
                                       blender::float3 position,
                                       blender::float3 rotation,
-                                      blender::float3 scale)
+                                      blender::float3 scale,
+                                      const int id)
 {
   InstancedData data;
   data.type = INSTANCE_DATA_TYPE_COLLECTION;
   data.data.collection = collection;
-  this->add_instance(data, position, rotation, scale);
+  this->add_instance(data, position, rotation, scale, id);
 }
 
 void InstancesComponent::add_instance(InstancedData data,
                                       blender::float3 position,
                                       blender::float3 rotation,
-                                      blender::float3 scale)
+                                      blender::float3 scale,
+                                      const int id)
 {
   instanced_data_.append(data);
   positions_.append(position);
   rotations_.append(rotation);
   scales_.append(scale);
+  ids_.append(id);
 }
 
 Span<InstancedData> InstancesComponent::instanced_data() const
@@ -516,16 +520,21 @@ Span<float3> InstancesComponent::positions() const
   return positions_;
 }
 
-blender::Span<blender::float3> InstancesComponent::rotations() const
+Span<float3> InstancesComponent::rotations() const
 {
   return rotations_;
 }
 
-blender::Span<blender::float3> InstancesComponent::scales() const
+Span<float3> InstancesComponent::scales() const
 {
   return scales_;
 }
 
+Span<int> InstancesComponent::ids() const
+{
+  return ids_;
+}
+
 MutableSpan<float3> InstancesComponent::positions()
 {
   return positions_;
@@ -565,6 +574,7 @@ int BKE_geometry_set_instances(const GeometrySet *geometry_set,
                                float (**r_positions)[3],
                                float (**r_rotations)[3],
                                float (**r_scales)[3],
+                               int **r_ids,
                                InstancedData **r_instanced_data)
 {
   const InstancesComponent *component = geometry_set->get_component_for_read<InstancesComponent>();
@@ -574,6 +584,8 @@ int BKE_geometry_set_instances(const GeometrySet *geometry_set,
   *r_positions = (float(*)[3])component->positions().data();
   *r_rotations = (float(*)[3])component->rotations().data();
   *r_scales = (float(*)[3])component->scales().data();
+  *r_ids = (int *)component->ids().data();
+  *r_instanced_data = (InstancedData *)component->instanced_data().data();
   *r_instanced_data = (InstancedData *)component->instanced_data().data();
   return component->instances_amount();
 }
diff --git a/source/blender/blenkernel/intern/object_dupli.c b/source/blender/blenkernel/intern/object_dupli.c
index 8fa708f31cb..d5317864480 100644
--- a/source/blender/blenkernel/intern/object_dupli.c
+++ b/source/blender/blenkernel/intern/object_dupli.c
@@ -816,9 +816,14 @@ static void make_duplis_instances_component(const DupliContext *ctx)
   float(*positions)[3];
   float(*rotations)[3];
   float(*scales)[3];
+  int *ids;
   InstancedData *instanced_data;
-  const int amount = BKE_geometry_set_instances(
-      ctx->object->runtime.geometry_set_eval, &positions, &rotations, &scales, &instanced_data);
+  const int amount = BKE_geometry_set_instances(ctx->object->runtime.geometry_set_eval,
+                                                &positions,
+                                                &rotations,
+                                                &scales,
+                                                &ids,
+                                                &instanced_data);
 
   for (int i = 0; i < amount; i++) {
     InstancedData *data = &instanced_data[i];
@@ -831,17 +836,19 @@ static void make_duplis_instances_component(const DupliContext *ctx)
     mul_m4_m4m4(instance_offset_matrix, rotation_matrix, scale_matrix);
     copy_v3_v3(instance_offset_matrix[3], positions[i]);
 
+    const int id = ids[i] != -1 ? ids[i] : i;
+
     if (data->type == INSTANCE_DATA_TYPE_OBJECT) {
       Object *object = data->data.object;
       if (object != NULL) {
         float matrix[4][4];
         mul_m4_m4m4(matrix, ctx->object->obmat, instance_offset_matrix);
-        make_dupli(ctx, object, matrix, i);
+        make_dupli(ctx, object, matrix, id);
 
         float space_matrix[4][4];
         mul_m4_m4m4(space_matrix, instance_offset_matrix, object->imat);
         mul_m4_m4_pre(space_matrix, ctx->object->obmat);
-        make_recursive_duplis(ctx, object, space_matrix, i);
+        make_recursive_duplis(ctx, object, space_matrix, id);
       }
     }
     else if (data->type == INSTANCE_DATA_TYPE_COLLECTION) {
@@ -862,8 +869,8 @@ static void make_duplis_instances_component(const DupliContext *ctx)
           float instance_matrix[4][4];
           mul_m4_m4m4(instance_matrix, collection_matrix, object->obmat);
 
-          make_dupli(ctx, object, instance_matrix, i);
-          make_recursive_duplis(ctx, object, collection_matrix, i);
+          make_dupli(ctx, object, instance_matrix, id);
+          make_recursive_duplis(ctx, object, collection_matrix, id);
         }
         FOREACH_COLLECTION_VISIBLE_OBJECT_RECURSIVE_END;
       }
diff --git a/source/blender/nodes/geometry/nodes/node_geo_point_instance.cc b/source/blender/nodes/geometry/nodes/node_geo_point_instance.cc
index 0a07af37115..d9e69adb860 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_point_instance.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_point_instance.cc
@@ -161,10 +161,11 @@ static void add_instances_from_geometry_component(InstancesComponent &instances,
       "rotation", domain, {0, 0, 0});
   Float3ReadAttribute scales = src_geometry.attribute_get_for_read<float3>(
       "scale", domain, {1, 1, 1});
+  Int32ReadAttribute ids = src_geometry.attribute_get_for_read<int>("id", domain, -1);
 
   for (const int i : IndexRange(domain_size)) {
     if (instances_data[i].has_value()) {
-      instances.add_instance(*instances_data[i], positions[i], rotations[i], scales[i]);
+      instances.add_instance(*instances_data[i], positions[i], rotations[i], scales[i], ids[i]);
     }
   }
 }



More information about the Bf-blender-cvs mailing list