[Bf-blender-cvs] [f5dc34ec9c0] master: Geometry Nodes: support instancing collections

Jacques Lucke noreply at git.blender.org
Fri Dec 11 18:06:48 CET 2020


Commit: f5dc34ec9c05cc8f1163313baafe634f4798c29b
Author: Jacques Lucke
Date:   Fri Dec 11 18:00:37 2020 +0100
Branches: master
https://developer.blender.org/rBf5dc34ec9c05cc8f1163313baafe634f4798c29b

Geometry Nodes: support instancing collections

The Point Instance node can instance entire collections now.
Before, only individual collections were supported.

Randomly selecting objects from the collection on a per point basis
is not support, yet.

Last part of D9739.

Ref T82372.

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

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/editors/space_node/drawnode.c
M	source/blender/makesdna/DNA_node_types.h
M	source/blender/makesrna/intern/rna_nodetree.c
M	source/blender/nodes/NOD_static_types.h
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..87bb96be145 100644
--- a/source/blender/blenkernel/BKE_geometry_set.h
+++ b/source/blender/blenkernel/BKE_geometry_set.h
@@ -26,16 +26,30 @@ 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);
 
+typedef enum InstancedDataType {
+  INSTANCE_DATA_TYPE_OBJECT = 0,
+  INSTANCE_DATA_TYPE_COLLECTION = 1,
+} InstancedDataType;
+
+typedef struct InstancedData {
+  InstancedDataType 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 b7cb9320086..617e0c45ae4 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.
@@ -358,7 +359,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();
@@ -366,12 +367,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 d5434710e23..8fa708f31cb 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];
@@ -833,14 +831,43 @@ 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]);
 
-    float matrix[4][4];
-    mul_m4_m4m4(matrix, ctx->object->obmat, instance_offset_matrix);
-    make_dupli(ctx, object, matrix, 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);
+
+        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);
+      }
+    }
+    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, instance_offset_matrix);
+        mul_m4_m4_pre(collection_matrix, ctx->object->obmat);
+
+        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);
 
-    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_dupli(ctx, object, instance_matrix, i);
+          make_recursive_duplis(ctx, object, collection_matrix, i);
+        }
+        FOREACH_COLLECTION_VISIBLE_OBJECT_RECURSIVE_END;
+      }
+    }
   }
 }
 
diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c
index f1ab433c639..f8c71791054 100644
--- a/source/blender/editors/space_node/drawnode.c
+++ b/source/blender/editors/space_node/drawnode.c
@@ -3182,6 +3182,13 @@ static void node_geometry_buts_attribute_math(uiLayout *layout,
   uiItemR(layout, ptr, "input_type_b", DEFAULT_FLAGS, IFACE

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list