[Bf-blender-cvs] [2ba67cda80a] temp-geometry-nodes-instance-collections: Geometry Nodes: initial collection instancing

Jacques Lucke noreply at git.blender.org
Thu Dec 3 15:30:27 CET 2020


Commit: 2ba67cda80a379cfe493c11cf38c36663ed2e36c
Author: Jacques Lucke
Date:   Thu Dec 3 13:12:47 2020 +0100
Branches: temp-geometry-nodes-instance-collections
https://developer.blender.org/rB2ba67cda80a379cfe493c11cf38c36663ed2e36c

Geometry Nodes: initial collection instancing

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

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_join_geometry.cc
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 026f4d39d51..daa2bb204b8 100644
--- a/source/blender/blenkernel/BKE_geometry_set.h
+++ b/source/blender/blenkernel/BKE_geometry_set.h
@@ -26,16 +26,31 @@ extern "C" {
 
 struct Object;
 struct GeometrySet;
+struct Collection;
 
 void BKE_geometry_set_free(struct GeometrySet *geometry_set);
 
 bool BKE_geometry_set_has_instances(const struct GeometrySet *geometry_set);
 
+enum InstancedDataType {
+  INSTANCE_DATA_TYPE_OBJECT = 0,
+  INSTANCE_DATA_TYPE_COLLECTION = 1,
+};
+
+typedef struct InstancedData {
+  /* InstancedDataType, use `int` because C and C++ might use different sizes otherwise. */
+  int type;
+  union {
+    struct Object *object;
+    struct Collection *collection;
+  } data;
+} InstancedData;
+
 int BKE_geometry_set_instances(const struct GeometrySet *geometry_set,
                                float (**r_positions)[3],
                                float (**r_rotations)[3],
                                float (**r_scales)[3],
-                               struct Object ***r_objects);
+                               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 ef3ae3c381c..8d049ee6575 100644
--- a/source/blender/blenkernel/BKE_geometry_set.hh
+++ b/source/blender/blenkernel/BKE_geometry_set.hh
@@ -35,6 +35,7 @@
 struct Mesh;
 struct PointCloud;
 struct Object;
+struct Collection;
 
 /* Each geometry component has a specific type. The type determines what kind of data the component
  * stores. Functions modifying a geometry will usually just modify a subset of the component types.
@@ -347,7 +348,7 @@ class InstancesComponent : public GeometryComponent {
   blender::Vector<blender::float3> positions_;
   blender::Vector<blender::float3> rotations_;
   blender::Vector<blender::float3> scales_;
-  blender::Vector<const Object *> objects_;
+  blender::Vector<InstancedData> instanced_data_;
 
  public:
   InstancesComponent();
@@ -355,12 +356,20 @@ class InstancesComponent : public GeometryComponent {
   GeometryComponent *copy() const override;
 
   void clear();
-  void add_instance(const Object *object,
+  void add_instance(Object *object,
                     blender::float3 position,
                     blender::float3 rotation = {0, 0, 0},
                     blender::float3 scale = {1, 1, 1});
+  void add_instance(Collection *collection,
+                    blender::float3 position,
+                    blender::float3 rotation = {0, 0, 0},
+                    blender::float3 scale = {1, 1, 1});
+  void add_instance(InstancedData data,
+                    blender::float3 position,
+                    blender::float3 rotation,
+                    blender::float3 scale);
 
-  blender::Span<const Object *> objects() const;
+  blender::Span<InstancedData> instanced_data() const;
   blender::Span<blender::float3> positions() const;
   blender::Span<blender::float3> rotations() const;
   blender::Span<blender::float3> scales() const;
diff --git a/source/blender/blenkernel/intern/geometry_set.cc b/source/blender/blenkernel/intern/geometry_set.cc
index 28695d769d3..e6a67b191f8 100644
--- a/source/blender/blenkernel/intern/geometry_set.cc
+++ b/source/blender/blenkernel/intern/geometry_set.cc
@@ -460,31 +460,54 @@ GeometryComponent *InstancesComponent::copy() const
   new_component->positions_ = positions_;
   new_component->rotations_ = rotations_;
   new_component->scales_ = scales_;
-  new_component->objects_ = objects_;
+  new_component->instanced_data_ = instanced_data_;
   return new_component;
 }
 
 void InstancesComponent::clear()
 {
-  objects_.clear();
+  instanced_data_.clear();
   positions_.clear();
   rotations_.clear();
   scales_.clear();
 }
-void InstancesComponent::add_instance(const Object *object,
+
+void InstancesComponent::add_instance(Object *object,
+                                      blender::float3 position,
+                                      blender::float3 rotation,
+                                      blender::float3 scale)
+{
+  InstancedData data;
+  data.type = INSTANCE_DATA_TYPE_OBJECT;
+  data.data.object = object;
+  this->add_instance(data, position, rotation, scale);
+}
+
+void InstancesComponent::add_instance(Collection *collection,
+                                      blender::float3 position,
+                                      blender::float3 rotation,
+                                      blender::float3 scale)
+{
+  InstancedData data;
+  data.type = INSTANCE_DATA_TYPE_COLLECTION;
+  data.data.collection = collection;
+  this->add_instance(data, position, rotation, scale);
+}
+
+void InstancesComponent::add_instance(InstancedData data,
                                       blender::float3 position,
                                       blender::float3 rotation,
                                       blender::float3 scale)
 {
-  objects_.append(object);
+  instanced_data_.append(data);
   positions_.append(position);
   rotations_.append(rotation);
   scales_.append(scale);
 }
 
-Span<const Object *> InstancesComponent::objects() const
+Span<InstancedData> InstancesComponent::instanced_data() const
 {
-  return objects_;
+  return instanced_data_;
 }
 
 Span<float3> InstancesComponent::positions() const
@@ -509,8 +532,11 @@ MutableSpan<float3> InstancesComponent::positions()
 
 int InstancesComponent::instances_amount() const
 {
-  BLI_assert(positions_.size() == objects_.size());
-  return objects_.size();
+  const int size = instanced_data_.size();
+  BLI_assert(positions_.size() == size);
+  BLI_assert(rotations_.size() == size);
+  BLI_assert(scales_.size() == size);
+  return size;
 }
 
 bool InstancesComponent::is_empty() const
@@ -538,7 +564,7 @@ int BKE_geometry_set_instances(const GeometrySet *geometry_set,
                                float (**r_positions)[3],
                                float (**r_rotations)[3],
                                float (**r_scales)[3],
-                               Object ***r_objects)
+                               InstancedData **r_instanced_data)
 {
   const InstancesComponent *component = geometry_set->get_component_for_read<InstancesComponent>();
   if (component == nullptr) {
@@ -547,7 +573,7 @@ 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_objects = (Object **)component->objects().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 9a8c560f116..ca31828a239 100644
--- a/source/blender/blenkernel/intern/object_dupli.c
+++ b/source/blender/blenkernel/intern/object_dupli.c
@@ -816,15 +816,13 @@ static void make_duplis_instances_component(const DupliContext *ctx)
   float(*positions)[3];
   float(*rotations)[3];
   float(*scales)[3];
-  Object **objects;
+  InstancedData *instanced_data;
   const int amount = BKE_geometry_set_instances(
-      ctx->object->runtime.geometry_set_eval, &positions, &rotations, &scales, &objects);
+      ctx->object->runtime.geometry_set_eval, &positions, &rotations, &scales, &instanced_data);
 
   for (int i = 0; i < amount; i++) {
-    Object *object = objects[i];
-    if (object == NULL) {
-      continue;
-    }
+    InstancedData *data = &instanced_data[i];
+
     float scale_matrix[4][4];
     size_to_mat4(scale_matrix, scales[i]);
     float rotation_matrix[4][4];
@@ -834,8 +832,36 @@ static void make_duplis_instances_component(const DupliContext *ctx)
     copy_v3_v3(matrix[3], positions[i]);
     mul_m4_m4_pre(matrix, ctx->object->obmat);
 
-    make_dupli(ctx, object, matrix, i);
-    make_recursive_duplis(ctx, object, matrix, i);
+    if (data->type == INSTANCE_DATA_TYPE_OBJECT) {
+      Object *object = data->data.object;
+      if (object != NULL) {
+        make_dupli(ctx, object, matrix, i);
+        make_recursive_duplis(ctx, object, matrix, i);
+      }
+    }
+    else if (data->type == INSTANCE_DATA_TYPE_COLLECTION) {
+      Collection *collection = data->data.collection;
+      if (collection != NULL) {
+        float collection_matrix[4][4];
+        unit_m4(collection_matrix);
+        sub_v3_v3(collection_matrix[3], collection->instance_offset);
+        mul_m4_m4_pre(collection_matrix, matrix);
+
+        eEvaluationMode mode = DEG_get_mode(ctx->depsgraph);
+        FOREACH_COLLECTION_VISIBLE_OBJECT_RECURSIVE_BEGIN (collection, object, mode) {
+          if (object == ctx->object) {
+            continue;
+          }
+
+          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, instance_matrix, i);
+        }
+        FOREACH_COLLECTION_VISIBLE_OBJECT_RECURSIVE_END;
+      }
+    }
   }
 }
 
diff --git a/source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc b/source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc
index dedc3213a1f..80ac45aed4e 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc
@@ -218,12 +218,12 @@ static void join_components(Span<const InstancesComponent *> src_components, Geo
   InstancesComponent &dst_component = result.get_component_for_write<InstancesComponent>();
   for (const InstancesComponent *component : src_components) {
     const int size = component->instances_amount();
-    Span<const Object *> objects = component->objects();
+    Span<InstancedData> instanced_data = component->instanced_data();
     Span<float3> positions = component->positions();
     Span<float3> rotations = component->rotations();
     Span<float3> scales = component->scales();
     for (const int i : IndexRange(size)) {
-      dst_component.add_instance(objects

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list