[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