Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/blenkernel/BKE_geometry_set.h13
-rw-r--r--source/blender/blenkernel/BKE_geometry_set.hh98
-rw-r--r--source/blender/blenkernel/intern/geometry_component_instances.cc84
-rw-r--r--source/blender/blenkernel/intern/geometry_set_instances.cc62
-rw-r--r--source/blender/blenkernel/intern/object_dupli.cc36
-rw-r--r--source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc30
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_collection_info.cc8
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc31
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_object_info.cc5
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_point_instance.cc66
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_transform.cc2
11 files changed, 268 insertions, 167 deletions
diff --git a/source/blender/blenkernel/BKE_geometry_set.h b/source/blender/blenkernel/BKE_geometry_set.h
index cb5526cd690..5f6a9ec7b91 100644
--- a/source/blender/blenkernel/BKE_geometry_set.h
+++ b/source/blender/blenkernel/BKE_geometry_set.h
@@ -43,19 +43,6 @@ 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;
-
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenkernel/BKE_geometry_set.hh b/source/blender/blenkernel/BKE_geometry_set.hh
index 2d0f099e5ce..106af8172d1 100644
--- a/source/blender/blenkernel/BKE_geometry_set.hh
+++ b/source/blender/blenkernel/BKE_geometry_set.hh
@@ -30,6 +30,7 @@
#include "BLI_map.hh"
#include "BLI_set.hh"
#include "BLI_user_counter.hh"
+#include "BLI_vector_set.hh"
#include "BKE_attribute_access.hh"
#include "BKE_geometry_set.h"
@@ -505,12 +506,81 @@ class CurveComponent : public GeometryComponent {
const blender::bke::ComponentAttributeProviders *get_attribute_providers() const final;
};
+class InstanceReference {
+ public:
+ enum class Type {
+ /**
+ * An empty instance. This allows an `InstanceReference` to be default constructed without
+ * being in an invalid state. There might also be other use cases that we haven't explored much
+ * yet (such as changing the instance later on, and "disabling" some instances).
+ */
+ None,
+ Object,
+ Collection,
+ };
+
+ private:
+ Type type_ = Type::None;
+ /** Depending on the type this is either null, an Object or Collection pointer. */
+ void *data_ = nullptr;
+
+ public:
+ InstanceReference() = default;
+
+ InstanceReference(Object &object) : type_(Type::Object), data_(&object)
+ {
+ }
+
+ InstanceReference(Collection &collection) : type_(Type::Collection), data_(&collection)
+ {
+ }
+
+ Type type() const
+ {
+ return type_;
+ }
+
+ Object &object() const
+ {
+ BLI_assert(type_ == Type::Object);
+ return *(Object *)data_;
+ }
+
+ Collection &collection() const
+ {
+ BLI_assert(type_ == Type::Collection);
+ return *(Collection *)data_;
+ }
+
+ uint64_t hash() const
+ {
+ return blender::get_default_hash(data_);
+ }
+
+ friend bool operator==(const InstanceReference &a, const InstanceReference &b)
+ {
+ return a.data_ == b.data_;
+ }
+};
+
/** A geometry component that stores instances. */
class InstancesComponent : public GeometryComponent {
private:
- blender::Vector<blender::float4x4> transforms_;
- blender::Vector<int> ids_;
- blender::Vector<InstancedData> instanced_data_;
+ /**
+ * Indexed set containing information about the data that is instanced.
+ * Actual instances store an index ("handle") into this set.
+ */
+ blender::VectorSet<InstanceReference> references_;
+
+ /** Index into `references_`. Determines what data is instanced. */
+ blender::Vector<int> instance_reference_handles_;
+ /** Transformation of the instances. */
+ blender::Vector<blender::float4x4> instance_transforms_;
+ /**
+ * IDs of the instances. They are used for consistency over multiple frames for things like
+ * motion blur.
+ */
+ blender::Vector<int> instance_ids_;
/* These almost unique ids are generated based on `ids_`, which might not contain unique ids at
* all. They are *almost* unique, because under certain very unlikely circumstances, they are not
@@ -525,14 +595,20 @@ class InstancesComponent : public GeometryComponent {
GeometryComponent *copy() const override;
void clear();
- void add_instance(Object *object, blender::float4x4 transform, const int id = -1);
- void add_instance(Collection *collection, blender::float4x4 transform, const int id = -1);
- void add_instance(InstancedData data, blender::float4x4 transform, const int id = -1);
-
- blender::Span<InstancedData> instanced_data() const;
- blender::Span<blender::float4x4> transforms() const;
- blender::Span<int> ids() const;
- blender::MutableSpan<blender::float4x4> transforms();
+
+ void reserve(int min_capacity);
+
+ int add_reference(InstanceReference reference);
+ void add_instance(int instance_handle, const blender::float4x4 &transform, const int id = -1);
+
+ blender::Span<InstanceReference> references() const;
+
+ blender::Span<int> instance_reference_handles() const;
+ blender::MutableSpan<blender::float4x4> instance_transforms();
+ blender::Span<blender::float4x4> instance_transforms() const;
+ blender::MutableSpan<int> instance_ids();
+ blender::Span<int> instance_ids() const;
+
int instances_amount() const;
blender::Span<int> almost_unique_ids() const;
diff --git a/source/blender/blenkernel/intern/geometry_component_instances.cc b/source/blender/blenkernel/intern/geometry_component_instances.cc
index feb30e8575a..55025ed5ac9 100644
--- a/source/blender/blenkernel/intern/geometry_component_instances.cc
+++ b/source/blender/blenkernel/intern/geometry_component_instances.cc
@@ -42,72 +42,86 @@ InstancesComponent::InstancesComponent() : GeometryComponent(GEO_COMPONENT_TYPE_
GeometryComponent *InstancesComponent::copy() const
{
InstancesComponent *new_component = new InstancesComponent();
- new_component->transforms_ = transforms_;
- new_component->instanced_data_ = instanced_data_;
- new_component->ids_ = ids_;
+ new_component->instance_reference_handles_ = instance_reference_handles_;
+ new_component->instance_transforms_ = instance_transforms_;
+ new_component->instance_ids_ = instance_ids_;
+ new_component->references_ = references_;
return new_component;
}
-void InstancesComponent::clear()
+void InstancesComponent::reserve(int min_capacity)
{
- instanced_data_.clear();
- transforms_.clear();
- ids_.clear();
+ instance_reference_handles_.reserve(min_capacity);
+ instance_transforms_.reserve(min_capacity);
+ instance_ids_.reserve(min_capacity);
}
-void InstancesComponent::add_instance(Object *object, float4x4 transform, const int id)
+void InstancesComponent::clear()
{
- InstancedData data;
- data.type = INSTANCE_DATA_TYPE_OBJECT;
- data.data.object = object;
- this->add_instance(data, transform, id);
+ instance_reference_handles_.clear();
+ instance_transforms_.clear();
+ instance_ids_.clear();
+
+ references_.clear();
}
-void InstancesComponent::add_instance(Collection *collection, float4x4 transform, const int id)
+void InstancesComponent::add_instance(const int instance_handle,
+ const float4x4 &transform,
+ const int id)
{
- InstancedData data;
- data.type = INSTANCE_DATA_TYPE_COLLECTION;
- data.data.collection = collection;
- this->add_instance(data, transform, id);
+ BLI_assert(instance_handle >= 0);
+ BLI_assert(instance_handle < references_.size());
+ instance_reference_handles_.append(instance_handle);
+ instance_transforms_.append(transform);
+ instance_ids_.append(id);
}
-void InstancesComponent::add_instance(InstancedData data, float4x4 transform, const int id)
+blender::Span<int> InstancesComponent::instance_reference_handles() const
{
- instanced_data_.append(data);
- transforms_.append(transform);
- ids_.append(id);
+ return instance_reference_handles_;
}
-Span<InstancedData> InstancesComponent::instanced_data() const
+blender::MutableSpan<blender::float4x4> InstancesComponent::instance_transforms()
+{
+ return instance_transforms_;
+}
+blender::Span<blender::float4x4> InstancesComponent::instance_transforms() const
{
- return instanced_data_;
+ return instance_transforms_;
}
-Span<float4x4> InstancesComponent::transforms() const
+blender::MutableSpan<int> InstancesComponent::instance_ids()
+{
+ return instance_ids_;
+}
+blender::Span<int> InstancesComponent::instance_ids() const
{
- return transforms_;
+ return instance_ids_;
}
-Span<int> InstancesComponent::ids() const
+/**
+ * Returns a handle for the given reference.
+ * If the reference exists already, the handle of the existing reference is returned.
+ * Otherwise a new handle is added.
+ */
+int InstancesComponent::add_reference(InstanceReference reference)
{
- return ids_;
+ return references_.index_of_or_add_as(reference);
}
-MutableSpan<float4x4> InstancesComponent::transforms()
+blender::Span<InstanceReference> InstancesComponent::references() const
{
- return transforms_;
+ return references_;
}
int InstancesComponent::instances_amount() const
{
- const int size = instanced_data_.size();
- BLI_assert(transforms_.size() == size);
- return size;
+ return instance_transforms_.size();
}
bool InstancesComponent::is_empty() const
{
- return transforms_.size() == 0;
+ return this->instance_reference_handles_.size() == 0;
}
bool InstancesComponent::owns_direct_data() const
@@ -178,8 +192,8 @@ static blender::Array<int> generate_unique_instance_ids(Span<int> original_ids)
blender::Span<int> InstancesComponent::almost_unique_ids() const
{
std::lock_guard lock(almost_unique_ids_mutex_);
- if (almost_unique_ids_.size() != ids_.size()) {
- almost_unique_ids_ = generate_unique_instance_ids(ids_);
+ if (almost_unique_ids_.size() != instance_ids_.size()) {
+ almost_unique_ids_ = generate_unique_instance_ids(instance_ids_);
}
return almost_unique_ids_;
}
diff --git a/source/blender/blenkernel/intern/geometry_set_instances.cc b/source/blender/blenkernel/intern/geometry_set_instances.cc
index 7e994b32ded..a792e268d5c 100644
--- a/source/blender/blenkernel/intern/geometry_set_instances.cc
+++ b/source/blender/blenkernel/intern/geometry_set_instances.cc
@@ -149,21 +149,28 @@ static void geometry_set_collect_recursive(const GeometrySet &geometry_set,
const InstancesComponent &instances_component =
*geometry_set.get_component_for_read<InstancesComponent>();
- Span<float4x4> transforms = instances_component.transforms();
- Span<InstancedData> instances = instances_component.instanced_data();
- for (const int i : instances.index_range()) {
- const InstancedData &data = instances[i];
+ Span<float4x4> transforms = instances_component.instance_transforms();
+ Span<int> handles = instances_component.instance_reference_handles();
+ Span<InstanceReference> references = instances_component.references();
+ for (const int i : transforms.index_range()) {
+ const InstanceReference &reference = references[handles[i]];
const float4x4 instance_transform = transform * transforms[i];
- if (data.type == INSTANCE_DATA_TYPE_OBJECT) {
- BLI_assert(data.data.object != nullptr);
- const Object &object = *data.data.object;
- geometry_set_collect_recursive_object(object, instance_transform, r_sets);
- }
- else if (data.type == INSTANCE_DATA_TYPE_COLLECTION) {
- BLI_assert(data.data.collection != nullptr);
- const Collection &collection = *data.data.collection;
- geometry_set_collect_recursive_collection_instance(collection, instance_transform, r_sets);
+ switch (reference.type()) {
+ case InstanceReference::Type::Object: {
+ Object &object = reference.object();
+ geometry_set_collect_recursive_object(object, instance_transform, r_sets);
+ break;
+ }
+ case InstanceReference::Type::Collection: {
+ Collection &collection = reference.collection();
+ geometry_set_collect_recursive_collection_instance(
+ collection, instance_transform, r_sets);
+ break;
+ }
+ case InstanceReference::Type::None: {
+ break;
+ }
}
}
}
@@ -267,19 +274,24 @@ static bool instances_attribute_foreach_recursive(const GeometrySet &geometry_se
return true;
}
- for (const InstancedData &data : instances_component->instanced_data()) {
- if (data.type == INSTANCE_DATA_TYPE_OBJECT) {
- BLI_assert(data.data.object != nullptr);
- const Object &object = *data.data.object;
- if (!object_instance_attribute_foreach(object, callback, limit, count)) {
- return false;
+ for (const InstanceReference &reference : instances_component->references()) {
+ switch (reference.type()) {
+ case InstanceReference::Type::Object: {
+ const Object &object = reference.object();
+ if (!object_instance_attribute_foreach(object, callback, limit, count)) {
+ return false;
+ }
+ break;
}
- }
- else if (data.type == INSTANCE_DATA_TYPE_COLLECTION) {
- BLI_assert(data.data.collection != nullptr);
- const Collection &collection = *data.data.collection;
- if (!collection_instance_attribute_foreach(collection, callback, limit, count)) {
- return false;
+ case InstanceReference::Type::Collection: {
+ const Collection &collection = reference.collection();
+ if (!collection_instance_attribute_foreach(collection, callback, limit, count)) {
+ return false;
+ }
+ break;
+ }
+ case InstanceReference::Type::None: {
+ break;
}
}
}
diff --git a/source/blender/blenkernel/intern/object_dupli.cc b/source/blender/blenkernel/intern/object_dupli.cc
index 835b62c06bf..768fa9373c1 100644
--- a/source/blender/blenkernel/intern/object_dupli.cc
+++ b/source/blender/blenkernel/intern/object_dupli.cc
@@ -842,38 +842,38 @@ static void make_duplis_instances_component(const DupliContext *ctx)
return;
}
- Span<float4x4> instance_offset_matrices = component->transforms();
+ Span<float4x4> instance_offset_matrices = component->instance_transforms();
+ Span<int> instance_reference_handles = component->instance_reference_handles();
Span<int> almost_unique_ids = component->almost_unique_ids();
- Span<InstancedData> instanced_data = component->instanced_data();
+ Span<InstanceReference> references = component->references();
- for (int i = 0; i < component->instances_amount(); i++) {
- const InstancedData &data = instanced_data[i];
+ for (int64_t i : instance_offset_matrices.index_range()) {
+ const InstanceReference &reference = references[instance_reference_handles[i]];
const int id = almost_unique_ids[i];
- if (data.type == INSTANCE_DATA_TYPE_OBJECT) {
- Object *object = data.data.object;
- if (object != nullptr) {
+ switch (reference.type()) {
+ case InstanceReference::Type::Object: {
+ Object &object = reference.object();
float matrix[4][4];
mul_m4_m4m4(matrix, ctx->object->obmat, instance_offset_matrices[i].values);
- make_dupli(ctx, object, matrix, id);
+ make_dupli(ctx, &object, matrix, id);
float space_matrix[4][4];
- mul_m4_m4m4(space_matrix, instance_offset_matrices[i].values, object->imat);
+ mul_m4_m4m4(space_matrix, instance_offset_matrices[i].values, object.imat);
mul_m4_m4_pre(space_matrix, ctx->object->obmat);
- make_recursive_duplis(ctx, object, space_matrix, id);
+ make_recursive_duplis(ctx, &object, space_matrix, id);
+ break;
}
- }
- else if (data.type == INSTANCE_DATA_TYPE_COLLECTION) {
- Collection *collection = data.data.collection;
- if (collection != nullptr) {
+ case InstanceReference::Type::Collection: {
+ Collection &collection = reference.collection();
float collection_matrix[4][4];
unit_m4(collection_matrix);
- sub_v3_v3(collection_matrix[3], collection->instance_offset);
+ sub_v3_v3(collection_matrix[3], collection.instance_offset);
mul_m4_m4_pre(collection_matrix, instance_offset_matrices[i].values);
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) {
+ FOREACH_COLLECTION_VISIBLE_OBJECT_RECURSIVE_BEGIN (&collection, object, mode) {
if (object == ctx->object) {
continue;
}
@@ -885,6 +885,10 @@ static void make_duplis_instances_component(const DupliContext *ctx)
make_recursive_duplis(ctx, object, collection_matrix, id);
}
FOREACH_COLLECTION_VISIBLE_OBJECT_RECURSIVE_END;
+ break;
+ }
+ case InstanceReference::Type::None: {
+ break;
}
}
}
diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc b/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc
index bd459944cff..02ffa1259fc 100644
--- a/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc
+++ b/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc
@@ -276,25 +276,31 @@ std::unique_ptr<ColumnValues> InstancesDataSource::get_column_values(
const int size = this->tot_rows();
if (STREQ(column_id.name, "Name")) {
- Span<InstancedData> instance_data = component_->instanced_data();
+ Span<int> reference_handles = component_->instance_reference_handles();
+ Span<InstanceReference> references = component_->references();
std::unique_ptr<ColumnValues> values = column_values_from_function(
- "Name", size, [instance_data](int index, CellValue &r_cell_value) {
- const InstancedData &data = instance_data[index];
- if (data.type == INSTANCE_DATA_TYPE_OBJECT) {
- if (data.data.object != nullptr) {
- r_cell_value.value_object = ObjectCellValue{data.data.object};
+ "Name", size, [reference_handles, references](int index, CellValue &r_cell_value) {
+ const InstanceReference &reference = references[reference_handles[index]];
+ switch (reference.type()) {
+ case InstanceReference::Type::Object: {
+ Object &object = reference.object();
+ r_cell_value.value_object = ObjectCellValue{&object};
+ break;
}
- }
- else if (data.type == INSTANCE_DATA_TYPE_COLLECTION) {
- if (data.data.collection != nullptr) {
- r_cell_value.value_collection = CollectionCellValue{data.data.collection};
+ case InstanceReference::Type::Collection: {
+ Collection &collection = reference.collection();
+ r_cell_value.value_collection = CollectionCellValue{&collection};
+ break;
+ }
+ case InstanceReference::Type::None: {
+ break;
}
}
});
values->default_width = 8.0f;
return values;
}
- Span<float4x4> transforms = component_->transforms();
+ Span<float4x4> transforms = component_->instance_transforms();
if (STREQ(column_id.name, "Position")) {
return column_values_from_function(
column_id.name,
@@ -322,7 +328,7 @@ std::unique_ptr<ColumnValues> InstancesDataSource::get_column_values(
},
default_float3_column_width);
}
- Span<int> ids = component_->ids();
+ Span<int> ids = component_->instance_ids();
if (STREQ(column_id.name, "ID")) {
/* Make the column a bit wider by default, since the IDs tend to be large numbers. */
return column_values_from_function(
diff --git a/source/blender/nodes/geometry/nodes/node_geo_collection_info.cc b/source/blender/nodes/geometry/nodes/node_geo_collection_info.cc
index 0ad495aa4db..5800d46b70d 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_collection_info.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_collection_info.cc
@@ -58,10 +58,6 @@ static void geo_node_collection_info_exec(GeoNodeExecParams params)
const bool transform_space_relative = (node_storage->transform_space ==
GEO_NODE_TRANSFORM_SPACE_RELATIVE);
- InstancedData instance;
- instance.type = INSTANCE_DATA_TYPE_COLLECTION;
- instance.data.collection = collection;
-
InstancesComponent &instances = geometry_set_out.get_component_for_write<InstancesComponent>();
float transform_mat[4][4];
@@ -73,7 +69,9 @@ static void geo_node_collection_info_exec(GeoNodeExecParams params)
mul_m4_m4_pre(transform_mat, self_object->imat);
}
- instances.add_instance(instance, transform_mat, -1);
+
+ const int handle = instances.add_reference(*collection);
+ instances.add_instance(handle, transform_mat, -1);
params.set_output("Geometry", geometry_set_out);
}
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 edc2fb58e01..68bb3614751 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc
@@ -243,13 +243,30 @@ static void join_components(Span<const PointCloudComponent *> src_components, Ge
static void join_components(Span<const InstancesComponent *> src_components, GeometrySet &result)
{
InstancesComponent &dst_component = result.get_component_for_write<InstancesComponent>();
- for (const InstancesComponent *component : src_components) {
- const int size = component->instances_amount();
- Span<InstancedData> instanced_data = component->instanced_data();
- Span<float4x4> transforms = component->transforms();
- Span<int> ids = component->ids();
- for (const int i : IndexRange(size)) {
- dst_component.add_instance(instanced_data[i], transforms[i], ids[i]);
+
+ int tot_instances = 0;
+ for (const InstancesComponent *src_component : src_components) {
+ tot_instances += src_component->instances_amount();
+ }
+ dst_component.reserve(tot_instances);
+
+ for (const InstancesComponent *src_component : src_components) {
+ Span<InstanceReference> src_references = src_component->references();
+ Array<int> handle_map(src_references.size());
+ for (const int src_handle : src_references.index_range()) {
+ handle_map[src_handle] = dst_component.add_reference(src_references[src_handle]);
+ }
+
+ Span<float4x4> src_transforms = src_component->instance_transforms();
+ Span<int> src_ids = src_component->instance_ids();
+ Span<int> src_reference_handles = src_component->instance_reference_handles();
+
+ for (const int i : src_transforms.index_range()) {
+ const int src_handle = src_reference_handles[i];
+ const int dst_handle = handle_map[src_handle];
+ const float4x4 &transform = src_transforms[i];
+ const int id = src_ids[i];
+ dst_component.add_instance(dst_handle, transform, id);
}
}
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_object_info.cc b/source/blender/nodes/geometry/nodes/node_geo_object_info.cc
index bd42b4c11d6..de099b8062f 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_object_info.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_object_info.cc
@@ -73,14 +73,15 @@ static void geo_node_object_info_exec(GeoNodeExecParams params)
if (object != self_object) {
InstancesComponent &instances = geometry_set.get_component_for_write<InstancesComponent>();
+ const int handle = instances.add_reference(*object);
if (transform_space_relative) {
- instances.add_instance(object, transform);
+ instances.add_instance(handle, transform);
}
else {
float unit_transform[4][4];
unit_m4(unit_transform);
- instances.add_instance(object, unit_transform);
+ instances.add_instance(handle, unit_transform);
}
}
}
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 f199ed71067..7929a5a1546 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_point_instance.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_point_instance.cc
@@ -65,8 +65,8 @@ static void geo_node_point_instance_update(bNodeTree *UNUSED(tree), bNode *node)
seed_socket, type == GEO_NODE_POINT_INSTANCE_TYPE_COLLECTION && !use_whole_collection);
}
-static void get_instanced_data__object(const GeoNodeExecParams &params,
- MutableSpan<std::optional<InstancedData>> r_instances_data)
+static void get_instance_references__object(const GeoNodeExecParams &params,
+ MutableSpan<InstanceReference> r_references)
{
bke::PersistentObjectHandle object_handle = params.get_input<bke::PersistentObjectHandle>(
"Object");
@@ -75,17 +75,13 @@ static void get_instanced_data__object(const GeoNodeExecParams &params,
object = nullptr;
}
if (object != nullptr) {
- InstancedData instance;
- instance.type = INSTANCE_DATA_TYPE_OBJECT;
- instance.data.object = object;
- r_instances_data.fill(instance);
+ r_references.fill(*object);
}
}
-static void get_instanced_data__collection(
- const GeoNodeExecParams &params,
- const GeometryComponent &component,
- MutableSpan<std::optional<InstancedData>> r_instances_data)
+static void get_instance_references__collection(const GeoNodeExecParams &params,
+ const GeometryComponent &component,
+ MutableSpan<InstanceReference> r_references)
{
const bNode &node = params.node();
NodeGeometryPointInstance *node_storage = (NodeGeometryPointInstance *)node.storage;
@@ -106,62 +102,51 @@ static void get_instanced_data__collection(
const bool use_whole_collection = (node_storage->flag &
GEO_NODE_POINT_INSTANCE_WHOLE_COLLECTION) != 0;
if (use_whole_collection) {
- InstancedData instance;
- instance.type = INSTANCE_DATA_TYPE_COLLECTION;
- instance.data.collection = collection;
- r_instances_data.fill(instance);
+ r_references.fill(*collection);
}
else {
- Vector<InstancedData> possible_instances;
+ Vector<InstanceReference> possible_references;
/* Direct child objects are instanced as objects. */
LISTBASE_FOREACH (CollectionObject *, cob, &collection->gobject) {
- Object *object = cob->ob;
- InstancedData instance;
- instance.type = INSTANCE_DATA_TYPE_OBJECT;
- instance.data.object = object;
- possible_instances.append(instance);
+ possible_references.append(*cob->ob);
}
/* Direct child collections are instanced as collections. */
LISTBASE_FOREACH (CollectionChild *, child, &collection->children) {
- Collection *child_collection = child->collection;
- InstancedData instance;
- instance.type = INSTANCE_DATA_TYPE_COLLECTION;
- instance.data.collection = child_collection;
- possible_instances.append(instance);
+ possible_references.append(*child->collection);
}
- if (!possible_instances.is_empty()) {
+ if (!possible_references.is_empty()) {
const int seed = params.get_input<int>("Seed");
Array<uint32_t> ids = get_geometry_element_ids_as_uints(component, ATTR_DOMAIN_POINT);
- for (const int i : r_instances_data.index_range()) {
- const int index = BLI_hash_int_2d(ids[i], seed) % possible_instances.size();
- r_instances_data[i] = possible_instances[index];
+ for (const int i : r_references.index_range()) {
+ const int index = BLI_hash_int_2d(ids[i], seed) % possible_references.size();
+ r_references[i] = possible_references[index];
}
}
}
}
-static Array<std::optional<InstancedData>> get_instanced_data(const GeoNodeExecParams &params,
- const GeometryComponent &component,
- const int amount)
+static Array<InstanceReference> get_instance_references(const GeoNodeExecParams &params,
+ const GeometryComponent &component,
+ const int amount)
{
const bNode &node = params.node();
NodeGeometryPointInstance *node_storage = (NodeGeometryPointInstance *)node.storage;
const GeometryNodePointInstanceType type = (GeometryNodePointInstanceType)
node_storage->instance_type;
- Array<std::optional<InstancedData>> instances_data(amount);
+ Array<InstanceReference> references(amount);
switch (type) {
case GEO_NODE_POINT_INSTANCE_TYPE_OBJECT: {
- get_instanced_data__object(params, instances_data);
+ get_instance_references__object(params, references);
break;
}
case GEO_NODE_POINT_INSTANCE_TYPE_COLLECTION: {
- get_instanced_data__collection(params, component, instances_data);
+ get_instance_references__collection(params, component, references);
break;
}
}
- return instances_data;
+ return references;
}
static void add_instances_from_geometry_component(InstancesComponent &instances,
@@ -171,8 +156,7 @@ static void add_instances_from_geometry_component(InstancesComponent &instances,
const AttributeDomain domain = ATTR_DOMAIN_POINT;
const int domain_size = src_geometry.attribute_domain_size(domain);
- Array<std::optional<InstancedData>> instances_data = get_instanced_data(
- params, src_geometry, domain_size);
+ Array<InstanceReference> references = get_instance_references(params, src_geometry, domain_size);
GVArray_Typed<float3> positions = src_geometry.attribute_get_for_read<float3>(
"position", domain, {0, 0, 0});
@@ -183,9 +167,11 @@ static void add_instances_from_geometry_component(InstancesComponent &instances,
GVArray_Typed<int> ids = src_geometry.attribute_get_for_read<int>("id", domain, -1);
for (const int i : IndexRange(domain_size)) {
- if (instances_data[i].has_value()) {
+ const InstanceReference &reference = references[i];
+ if (reference.type() != InstanceReference::Type::None) {
const float4x4 matrix = float4x4::from_loc_eul_scale(positions[i], rotations[i], scales[i]);
- instances.add_instance(*instances_data[i], matrix, ids[i]);
+ const int handle = instances.add_reference(reference);
+ instances.add_instance(handle, matrix, ids[i]);
}
}
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_transform.cc b/source/blender/nodes/geometry/nodes/node_geo_transform.cc
index cba2c53907f..ce52dc90668 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_transform.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_transform.cc
@@ -101,7 +101,7 @@ static void transform_instances(InstancesComponent &instances,
const float3 rotation,
const float3 scale)
{
- MutableSpan<float4x4> transforms = instances.transforms();
+ MutableSpan<float4x4> transforms = instances.instance_transforms();
/* Use only translation if rotation and scale don't apply. */
if (use_translate(rotation, scale)) {