[Bf-blender-cvs] [25bed6791be] temp-modifiers-instancing: do instancing with dupli system

Jacques Lucke noreply at git.blender.org
Tue Nov 10 16:39:19 CET 2020


Commit: 25bed6791befa572405dae789ea82168efdf938e
Author: Jacques Lucke
Date:   Tue Nov 10 15:42:52 2020 +0100
Branches: temp-modifiers-instancing
https://developer.blender.org/rB25bed6791befa572405dae789ea82168efdf938e

do instancing with dupli system

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

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.c
M	source/blender/blenkernel/intern/object_dupli.c
M	source/blender/depsgraph/DEG_depsgraph_query.h
M	source/blender/depsgraph/intern/depsgraph_query_iter.cc

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

diff --git a/source/blender/blenkernel/BKE_geometry_set.h b/source/blender/blenkernel/BKE_geometry_set.h
index e192bacbbad..f2414a941cf 100644
--- a/source/blender/blenkernel/BKE_geometry_set.h
+++ b/source/blender/blenkernel/BKE_geometry_set.h
@@ -24,10 +24,19 @@
 extern "C" {
 #endif
 
+struct Object;
+
 typedef struct GeometrySetC GeometrySetC;
+typedef struct InstancesComponentC InstancesComponentC;
+
+void BKE_geometry_set_user_add(GeometrySetC *geometry_set_c);
+void BKE_geometry_set_user_remove(GeometrySetC *geometry_set_c);
+
+bool BKE_geometry_set_has_instances(const GeometrySetC *geometry_set_c);
 
-void BKE_geometry_set_user_add(GeometrySetC *geometry_set);
-void BKE_geometry_set_user_remove(GeometrySetC *geometry_set);
+int BKE_geometry_set_instances(const GeometrySetC *geometry_set_c,
+                               float (**r_positions)[3],
+                               struct Object ***r_objects);
 
 #ifdef __cplusplus
 }
diff --git a/source/blender/blenkernel/BKE_geometry_set.hh b/source/blender/blenkernel/BKE_geometry_set.hh
index a88736b8c3e..e7979260f2a 100644
--- a/source/blender/blenkernel/BKE_geometry_set.hh
+++ b/source/blender/blenkernel/BKE_geometry_set.hh
@@ -197,16 +197,18 @@ class PointCloudComponent : public GeometryComponent {
 class InstancesComponent : public GeometryComponent {
  private:
   Vector<float3> positions_;
-  const Object *instanced_object_ = nullptr;
+  Vector<const Object *> objects_;
 
  public:
   ~InstancesComponent() = default;
   GeometryComponent *copy() const override;
 
-  void replace(Vector<float3> positions, const Object *instanced_object);
+  void replace(Vector<float3> positions, Vector<const Object *> objects);
+  void replace(Vector<float3> positions, const Object *object);
 
-  const Object *instanced_object() const;
+  Span<const Object *> objects() const;
   Span<float3> positions() const;
+  int instances_amount() const;
 
   static constexpr inline GeometryComponentType type = GeometryComponentType::Instances;
 };
@@ -216,9 +218,19 @@ inline GeometrySetC *wrap(blender::bke::GeometrySet *geometry_set)
   return reinterpret_cast<GeometrySetC *>(geometry_set);
 }
 
+inline const GeometrySetC *wrap(const blender::bke::GeometrySet *geometry_set)
+{
+  return reinterpret_cast<const GeometrySetC *>(geometry_set);
+}
+
 inline blender::bke::GeometrySet *unwrap(GeometrySetC *geometry_set_c)
 {
   return reinterpret_cast<blender::bke::GeometrySet *>(geometry_set_c);
 }
 
+inline const blender::bke::GeometrySet *unwrap(const GeometrySetC *geometry_set_c)
+{
+  return reinterpret_cast<const blender::bke::GeometrySet *>(geometry_set_c);
+}
+
 }  // namespace blender::bke
diff --git a/source/blender/blenkernel/intern/geometry_set.cc b/source/blender/blenkernel/intern/geometry_set.cc
index 48ffa0631ab..9fda0ab04f6 100644
--- a/source/blender/blenkernel/intern/geometry_set.cc
+++ b/source/blender/blenkernel/intern/geometry_set.cc
@@ -386,19 +386,27 @@ GeometryComponent *InstancesComponent::copy() const
 {
   InstancesComponent *new_component = new InstancesComponent();
   new_component->positions_ = positions_;
-  new_component->instanced_object_ = instanced_object_;
+  new_component->objects_ = objects_;
   return new_component;
 }
 
-void InstancesComponent::replace(Vector<float3> positions, const Object *instanced_object)
+void InstancesComponent::replace(Vector<float3> positions, Vector<const Object *> objects)
 {
+  BLI_assert(positions.size() == objects.size());
   positions_ = std::move(positions);
-  instanced_object_ = instanced_object;
+  objects_ = std::move(objects);
 }
 
-const Object *InstancesComponent::instanced_object() const
+void InstancesComponent::replace(Vector<float3> positions, const Object *object)
 {
-  return instanced_object_;
+  positions_ = std::move(positions);
+  objects_.clear();
+  objects_.append_n_times(object, positions_.size());
+}
+
+Span<const Object *> InstancesComponent::objects() const
+{
+  return objects_;
 }
 
 Span<float3> InstancesComponent::positions() const
@@ -406,6 +414,12 @@ Span<float3> InstancesComponent::positions() const
   return positions_;
 }
 
+int InstancesComponent::instances_amount() const
+{
+  BLI_assert(positions_.size() == objects_.size());
+  return objects_.size();
+}
+
 /** \} */
 
 }  // namespace blender::bke
@@ -414,14 +428,35 @@ Span<float3> InstancesComponent::positions() const
 /** \name C API
  * \{ */
 
-void BKE_geometry_set_user_add(GeometrySetC *geometry_set)
+void BKE_geometry_set_user_add(GeometrySetC *geometry_set_c)
 {
-  blender::bke::unwrap(geometry_set)->user_add();
+  blender::bke::unwrap(geometry_set_c)->user_add();
 }
 
-void BKE_geometry_set_user_remove(GeometrySetC *geometry_set)
+void BKE_geometry_set_user_remove(GeometrySetC *geometry_set_c)
 {
-  blender::bke::unwrap(geometry_set)->user_remove();
+  blender::bke::unwrap(geometry_set_c)->user_remove();
+}
+
+bool BKE_geometry_set_has_instances(const GeometrySetC *geometry_set_c)
+{
+  return blender::bke::unwrap(geometry_set_c)
+             ->get_component_for_read<blender::bke::InstancesComponent>() != nullptr;
+}
+
+int BKE_geometry_set_instances(const GeometrySetC *geometry_set_c,
+                               float (**r_positions)[3],
+                               Object ***r_objects)
+{
+  using namespace blender::bke;
+  const GeometrySet *geometry_set = unwrap(geometry_set_c);
+  const InstancesComponent *component = geometry_set->get_component_for_read<InstancesComponent>();
+  if (component == nullptr) {
+    return 0;
+  }
+  *r_positions = (float(*)[3])component->positions().data();
+  *r_objects = (Object **)component->objects().data();
+  return component->instances_amount();
 }
 
 /** \} */
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 9edf4056145..ce5fabfa605 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -1779,6 +1779,10 @@ int BKE_object_visibility(const Object *ob, const int dag_eval_mode)
     visibility |= OB_VISIBLE_INSTANCES;
   }
 
+  if (ob->runtime.geometry_set_eval != NULL) {
+    visibility |= OB_VISIBLE_INSTANCES;
+  }
+
   /* Optional hiding of self if there are particles or instancers. */
   if (visibility & (OB_VISIBLE_PARTICLES | OB_VISIBLE_INSTANCES)) {
     switch ((eEvaluationMode)dag_eval_mode) {
diff --git a/source/blender/blenkernel/intern/object_dupli.c b/source/blender/blenkernel/intern/object_dupli.c
index a1b01bce6c9..a64858287c7 100644
--- a/source/blender/blenkernel/intern/object_dupli.c
+++ b/source/blender/blenkernel/intern/object_dupli.c
@@ -47,6 +47,7 @@
 #include "BKE_editmesh.h"
 #include "BKE_editmesh_cache.h"
 #include "BKE_font.h"
+#include "BKE_geometry_set.h"
 #include "BKE_global.h"
 #include "BKE_idprop.h"
 #include "BKE_lattice.h"
@@ -806,6 +807,35 @@ static const DupliGenerator gen_dupli_verts_pointcloud = {
 
 /** \} */
 
+/* -------------------------------------------------------------------- */
+/** \name Instances Geometry Component Implementation
+ * \{ */
+
+static void make_duplis_instances_component(const DupliContext *ctx)
+{
+  float(*positions)[3];
+  Object **objects;
+  const int amount = BKE_geometry_set_instances(
+      ctx->object->runtime.geometry_set_eval, &positions, &objects);
+
+  for (int i = 0; i < amount; i++) {
+    Object *object = objects[i];
+    float mat[4][4];
+    unit_m4(mat);
+    copy_v3_v3(mat[3], positions[i]);
+    mul_m4_m4_pre(mat, ctx->object->obmat);
+    make_dupli(ctx, object, mat, i);
+    make_recursive_duplis(ctx, object, mat, i);
+  }
+}
+
+static const DupliGenerator gen_dupli_instances_component = {
+    0,
+    make_duplis_instances_component,
+};
+
+/** \} */
+
 /* -------------------------------------------------------------------- */
 /** \name Dupli-Faces Implementation (#OB_DUPLIFACES)
  * \{ */
@@ -1473,7 +1503,7 @@ static const DupliGenerator *get_dupli_generator(const DupliContext *ctx)
   int transflag = ctx->object->transflag;
   int restrictflag = ctx->object->restrictflag;
 
-  if ((transflag & OB_DUPLI) == 0) {
+  if ((transflag & OB_DUPLI) == 0 && ctx->object->runtime.geometry_set_eval == NULL) {
     return NULL;
   }
 
@@ -1483,6 +1513,12 @@ static const DupliGenerator *get_dupli_generator(const DupliContext *ctx)
     return NULL;
   }
 
+  if (ctx->object->runtime.geometry_set_eval != NULL) {
+    if (BKE_geometry_set_has_instances(ctx->object->runtime.geometry_set_eval)) {
+      return &gen_dupli_instances_component;
+    }
+  }
+
   if (transflag & OB_DUPLIPARTS) {
     return &gen_dupli_particles;
   }
diff --git a/source/blender/depsgraph/DEG_depsgraph_query.h b/source/blender/depsgraph/DEG_depsgraph_query.h
index 48b7c60a9f8..7eb5f1ccec1 100644
--- a/source/blender/depsgraph/DEG_depsgraph_query.h
+++ b/source/blender/depsgraph/DEG_depsgraph_query.h
@@ -160,9 +160,6 @@ typedef struct DEGObjectIterData {
    * other users of the iterator. */
   struct Object temp_dupli_object;
 
-  /* **** Iteration over Geometry Set. ****/
-  int instances_component_index;
-
   /* **** Iteration over ID nodes **** */
   size_t id_node_index;
   size_t num_id_nodes;
diff --git a/source/blender/depsgraph/intern/depsgraph_query_iter.cc b/source/blender/depsgraph/intern/depsgraph_query_iter.cc
index 0d049f1d410..40ac8323283 100644
--- a/source/blender/depsgraph/intern/depsgraph_query_iter.cc
+++ b/source/blender/depsgraph/intern/depsgraph_query_iter.cc
@@ -227,7 +227,8 @@ void deg_iterator_objects_step(BLI_Iterator *iter, deg::IDNode *id_node)
   }
 
   if (ob_visibility & OB_VISIBLE_INSTANCES) {
-    if ((data->flag & DEG_ITER_OBJECT_FLAG_DUPLI) && (object->transflag & OB_DUPLI)) {
+    if ((data->flag & DEG_ITER_OBJECT_FLAG_DUPLI) &&
+        ((object->transflag & OB_DUPLI) || object->runtime.geometry_set_eval != nullptr)) {
       data->dupli_parent = object;
       data->dupli_list = object_duplilist(data->graph, data->scene, object);
       data->dupli_object_next = (DupliObject *)data->dupli_list->first;
@@ -237,7 +238,6 @@ void deg_iterator_objects_step(BLI_Iterator *iter, deg::IDNode *id_node)
   if (ob_visibility & (OB_VISIBLE_SELF | OB_VISIBLE_PARTICLES)) {
     iter->current = object;
     iter->skip = fal

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list