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:
Diffstat (limited to 'source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc')
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc56
1 files changed, 26 insertions, 30 deletions
diff --git a/source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc b/source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc
index c6f214e72ac..64546684186 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc
@@ -2,6 +2,7 @@
#include "DNA_collection_types.h"
+#include "BLI_array_utils.hh"
#include "BLI_hash.h"
#include "BLI_task.hh"
@@ -9,6 +10,7 @@
#include "UI_resources.h"
#include "BKE_attribute_math.hh"
+#include "BKE_instances.hh"
#include "node_geometry_util.hh"
@@ -43,7 +45,7 @@ static void node_declare(NodeDeclarationBuilder &b)
}
static void add_instances_from_component(
- InstancesComponent &dst_component,
+ bke::Instances &dst_component,
const GeometryComponent &src_component,
const GeometrySet &instance,
const GeoNodeExecParams &params,
@@ -80,25 +82,23 @@ static void add_instances_from_component(
const int select_len = selection.index_range().size();
dst_component.resize(start_len + select_len);
- MutableSpan<int> dst_handles = dst_component.instance_reference_handles().slice(start_len,
- select_len);
- MutableSpan<float4x4> dst_transforms = dst_component.instance_transforms().slice(start_len,
- select_len);
+ MutableSpan<int> dst_handles = dst_component.reference_handles().slice(start_len, select_len);
+ MutableSpan<float4x4> dst_transforms = dst_component.transforms().slice(start_len, select_len);
VArray<float3> positions = src_component.attributes()->lookup_or_default<float3>(
"position", domain, {0, 0, 0});
- const InstancesComponent *src_instances = instance.get_component_for_read<InstancesComponent>();
+ const bke::Instances *src_instances = instance.get_instances_for_read();
/* Maps handles from the source instances to handles on the new instance. */
Array<int> handle_mapping;
/* Only fill #handle_mapping when it may be used below. */
if (src_instances != nullptr &&
(!pick_instance.is_single() || pick_instance.get_internal_single())) {
- Span<InstanceReference> src_references = src_instances->references();
+ Span<bke::InstanceReference> src_references = src_instances->references();
handle_mapping.reinitialize(src_references.size());
for (const int src_instance_handle : src_references.index_range()) {
- const InstanceReference &reference = src_references[src_instance_handle];
+ const bke::InstanceReference &reference = src_references[src_instance_handle];
const int dst_instance_handle = dst_component.add_reference(reference);
handle_mapping[src_instance_handle] = dst_instance_handle;
}
@@ -106,7 +106,7 @@ static void add_instances_from_component(
const int full_instance_handle = dst_component.add_reference(instance);
/* Add this reference last, because it is the most likely one to be removed later on. */
- const int empty_reference_handle = dst_component.add_reference(InstanceReference());
+ const int empty_reference_handle = dst_component.add_reference(bke::InstanceReference());
threading::parallel_for(selection.index_range(), 1024, [&](IndexRange selection_range) {
for (const int range_i : selection_range) {
@@ -129,12 +129,11 @@ static void add_instances_from_component(
const int index = mod_i(original_index, std::max(src_instances_num, 1));
if (index < src_instances_num) {
/* Get the reference to the source instance. */
- const int src_handle = src_instances->instance_reference_handles()[index];
+ const int src_handle = src_instances->reference_handles()[index];
dst_handle = handle_mapping[src_handle];
/* Take transforms of the source instance into account. */
- mul_m4_m4_post(dst_transform.values,
- src_instances->instance_transforms()[index].values);
+ mul_m4_m4_post(dst_transform.values, src_instances->transforms()[index].values);
}
}
}
@@ -157,7 +156,7 @@ static void add_instances_from_component(
}
}
- bke::CustomDataAttributes &instance_attributes = dst_component.instance_attributes();
+ bke::CustomDataAttributes &instance_attributes = dst_component.custom_data_attributes();
for (const auto item : attributes_to_propagate.items()) {
const AttributeIDRef &attribute_id = item.key;
const AttributeKind attribute_kind = item.value;
@@ -174,18 +173,7 @@ static void add_instances_from_component(
dst_attribute_opt = instance_attributes.get_for_write(attribute_id);
}
BLI_assert(dst_attribute_opt);
- const GMutableSpan dst_attribute = dst_attribute_opt->slice(start_len, select_len);
- threading::parallel_for(selection.index_range(), 1024, [&](IndexRange selection_range) {
- attribute_math::convert_to_static_type(attribute_kind.data_type, [&](auto dummy) {
- using T = decltype(dummy);
- VArray<T> src = src_attribute.typed<T>();
- MutableSpan<T> dst = dst_attribute.typed<T>();
- for (const int range_i : selection_range) {
- const int i = selection[range_i];
- dst[range_i] = src[i];
- }
- });
- });
+ array_utils::gather(src_attribute, selection, dst_attribute_opt->slice(start_len, select_len));
}
}
@@ -196,7 +184,15 @@ static void node_geo_exec(GeoNodeExecParams params)
instance.ensure_owns_direct_data();
geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
- InstancesComponent &instances = geometry_set.get_component_for_write<InstancesComponent>();
+ /* It's important not to invalidate the existing #InstancesComponent because it owns references
+ * to other geometry sets that are processed by this node. */
+ InstancesComponent &instances_component =
+ geometry_set.get_component_for_write<InstancesComponent>();
+ bke::Instances *dst_instances = instances_component.get_for_write();
+ if (dst_instances == nullptr) {
+ dst_instances = new bke::Instances();
+ instances_component.replace(dst_instances);
+ }
const Array<GeometryComponentType> types{
GEO_COMPONENT_TYPE_MESH, GEO_COMPONENT_TYPE_POINT_CLOUD, GEO_COMPONENT_TYPE_CURVE};
@@ -208,14 +204,13 @@ static void node_geo_exec(GeoNodeExecParams params)
for (const GeometryComponentType type : types) {
if (geometry_set.has(type)) {
- add_instances_from_component(instances,
+ add_instances_from_component(*dst_instances,
*geometry_set.get_component_for_read(type),
instance,
params,
attributes_to_propagate);
}
}
-
geometry_set.remove_geometry_during_modify();
});
@@ -223,8 +218,9 @@ static void node_geo_exec(GeoNodeExecParams params)
* process them needlessly.
* This should eventually be moved into the loop above, but currently this is quite tricky
* because it might remove references that the loop still wants to iterate over. */
- InstancesComponent &instances = geometry_set.get_component_for_write<InstancesComponent>();
- instances.remove_unused_references();
+ if (bke::Instances *instances = geometry_set.get_instances_for_write()) {
+ instances->remove_unused_references();
+ }
params.set_output("Instances", std::move(geometry_set));
}