From 5b38b1fb6620ac3dc5f894a35a46203e781ec314 Mon Sep 17 00:00:00 2001 From: "david.haver" Date: Mon, 11 Mar 2024 22:06:11 +0200 Subject: [PATCH 01/10] remove temp_geometry_set --- .../geometry/intern/realize_instances.cc | 31 ++++++++----------- 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/source/blender/geometry/intern/realize_instances.cc b/source/blender/geometry/intern/realize_instances.cc index 358ee99606c..3c4ab5b874c 100644 --- a/source/blender/geometry/intern/realize_instances.cc +++ b/source/blender/geometry/intern/realize_instances.cc @@ -639,9 +639,7 @@ static void gather_realize_tasks_recursive(GatherTasksInfo &gather_info, const bke::GeometryComponent::Type type = component->type(); switch (type) { case bke::GeometryComponent::Type::Mesh: { - const bke::MeshComponent &mesh_component = *static_cast( - component); - const Mesh *mesh = mesh_component.get(); + const Mesh *mesh = (*static_cast(component)).get(); if (mesh != nullptr && mesh->verts_num > 0) { const int mesh_index = gather_info.meshes.order.index_of(mesh); const MeshRealizeInfo &mesh_info = gather_info.meshes.realize_info[mesh_index]; @@ -697,9 +695,8 @@ static void gather_realize_tasks_recursive(GatherTasksInfo &gather_info, gather_info.instances.instances_components_transforms.append(base_transform); } else { - const auto &instances_component = *static_cast( - component); - const Instances *instances = instances_component.get(); + const Instances *instances = + (*static_cast(component)).get(); if (instances != nullptr && instances->instances_num() > 0) { gather_realize_tasks_for_instances(gather_info, current_depth, @@ -712,8 +709,9 @@ static void gather_realize_tasks_recursive(GatherTasksInfo &gather_info, break; } case bke::GeometryComponent::Type::Volume: { - const auto *volume_component = static_cast(component); if (!gather_info.r_tasks.first_volume) { + const bke::VolumeComponent *volume_component = static_cast( + component); volume_component->add_user(); gather_info.r_tasks.first_volume = ImplicitSharingPtr( volume_component); @@ -721,9 +719,9 @@ static void gather_realize_tasks_recursive(GatherTasksInfo &gather_info, break; } case bke::GeometryComponent::Type::Edit: { - const auto *edit_component = static_cast( - component); if (!gather_info.r_tasks.first_edit_data) { + const bke::GeometryComponentEditData *edit_component = + static_cast(component); edit_component->add_user(); gather_info.r_tasks.first_edit_data = ImplicitSharingPtr(edit_component); @@ -1957,9 +1955,9 @@ bke::GeometrySet realize_instances(bke::GeometrySet geometry_set, return geometry_set; } - bke::GeometrySet temp_geometry_set; - propagate_instances_to_keep( - geometry_set, options.selection, temp_geometry_set, options.propagation_info); + Vector instances_components_to_merge; + instances_components_to_merge.append( + &geometry_set.get_component_for_write()); if (options.keep_original_ids) { remove_id_attribute_from_instances(geometry_set); @@ -1990,12 +1988,9 @@ bke::GeometrySet realize_instances(bke::GeometrySet geometry_set, const float4x4 transform = float4x4::identity(); InstanceContext attribute_fallbacks(gather_info); - if (temp_geometry_set.has_instances()) { - gather_info.instances.instances_components_to_merge.append( - &temp_geometry_set.get_component_for_write()); - gather_info.instances.instances_components_transforms.append(float4x4::identity()); - gather_info.instances.attribute_fallback.append((gather_info.instances_attriubutes.size())); - } + gather_info.instances.instances_components_to_merge = std::move(instances_components_to_merge); + gather_info.instances.instances_components_transforms.append(float4x4::identity()); + gather_info.instances.attribute_fallback.append((gather_info.instances_attriubutes.size())); gather_realize_tasks_recursive(gather_info, 0, -1, geometry_set, transform, attribute_fallbacks); -- 2.30.2 From 3b376b2f2bf0f4bd57fd7ec06dce757a718513bb Mon Sep 17 00:00:00 2001 From: "david.haver" Date: Tue, 12 Mar 2024 17:21:43 +0200 Subject: [PATCH 02/10] returned temp_geometry_set as not_to_realize_set and fixed memory issue --- .../geometry/intern/realize_instances.cc | 44 ++++++++++++------- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/source/blender/geometry/intern/realize_instances.cc b/source/blender/geometry/intern/realize_instances.cc index 3c4ab5b874c..e82fc9e5953 100644 --- a/source/blender/geometry/intern/realize_instances.cc +++ b/source/blender/geometry/intern/realize_instances.cc @@ -501,31 +501,36 @@ static Vector> prepare_attribute_fallbacks( * Calls #fn for every geometry in the given #InstanceReference. Also passes on the transformation * that is applied to every instance. */ -static bke::GeometrySet geometry_set_from_reference(const InstanceReference &reference) +static bke::GeometrySet &geometry_set_from_reference(const InstanceReference &reference, + bke::GeometrySet &r_geometry_set) { switch (reference.type()) { case InstanceReference::Type::Object: { const Object &object = reference.object(); - return bke::object_get_evaluated_geometry_set(object); + r_geometry_set = bke::object_get_evaluated_geometry_set(object); + break; } case InstanceReference::Type::Collection: { Collection *collection_ptr = &reference.collection(); std::unique_ptr instances = std::make_unique(); realize_collections(collection_ptr, instances.get()); - bke::GeometrySet collection_geometry = bke::GeometrySet::from_instances(instances.release()); - collection_geometry.get_component(bke::GeometryComponent::Type::Instance)->add_user(); - return collection_geometry; + r_geometry_set = bke::GeometrySet::from_instances(instances.release()); + break; } case InstanceReference::Type::GeometrySet: { - return reference.geometry_set(); + r_geometry_set = reference.geometry_set(); + break; } case InstanceReference::Type::None: { - return bke::GeometrySet(); // Return an empty GeometrySet for None type + r_geometry_set = bke::GeometrySet(); // Return an empty GeometrySet for None type + break; } default: { - return bke::GeometrySet(); + r_geometry_set = bke::GeometrySet(); + break; } } + return r_geometry_set; } static void foreach_geometry_in_reference( @@ -535,7 +540,8 @@ static void foreach_geometry_in_reference( FunctionRef fn) { - const bke::GeometrySet geometry_set = geometry_set_from_reference(reference); + bke::GeometrySet geometry_set; + geometry_set_from_reference(reference, geometry_set); fn(geometry_set, base_transform, id); } @@ -769,8 +775,9 @@ bool static attribute_foreach(const bke::GeometrySet &geometry_set, for (const int index : indices.index_range()) { const int i = indices[index]; const int depth_target_tmp = (current_depth == 0) ? instance_depth[i] : depth_target; - bke::GeometrySet instance_geometry_set = geometry_set_from_reference( - instances.references()[instances.reference_handles()[i]]); + bke::GeometrySet instance_geometry_set; + geometry_set_from_reference(instances.references()[instances.reference_handles()[i]], + instance_geometry_set); /*Process child instances with a recursive call.*/ if (current_depth != depth_target_tmp) { is_child_has_component = attribute_foreach(instance_geometry_set, @@ -1955,9 +1962,9 @@ bke::GeometrySet realize_instances(bke::GeometrySet geometry_set, return geometry_set; } - Vector instances_components_to_merge; - instances_components_to_merge.append( - &geometry_set.get_component_for_write()); + bke::GeometrySet not_to_realize_set; + propagate_instances_to_keep( + geometry_set, options.selection, not_to_realize_set, options.propagation_info); if (options.keep_original_ids) { remove_id_attribute_from_instances(geometry_set); @@ -1988,9 +1995,12 @@ bke::GeometrySet realize_instances(bke::GeometrySet geometry_set, const float4x4 transform = float4x4::identity(); InstanceContext attribute_fallbacks(gather_info); - gather_info.instances.instances_components_to_merge = std::move(instances_components_to_merge); - gather_info.instances.instances_components_transforms.append(float4x4::identity()); - gather_info.instances.attribute_fallback.append((gather_info.instances_attriubutes.size())); + if (not_to_realize_set.has_instances()) { + gather_info.instances.instances_components_to_merge.append( + ¬_to_realize_set.get_component_for_write()); + gather_info.instances.instances_components_transforms.append(float4x4::identity()); + gather_info.instances.attribute_fallback.append((gather_info.instances_attriubutes.size())); + } gather_realize_tasks_recursive(gather_info, 0, -1, geometry_set, transform, attribute_fallbacks); -- 2.30.2 From 52893077e673fa92799e40de94a8be08899353dc Mon Sep 17 00:00:00 2001 From: "david.haver" Date: Wed, 13 Mar 2024 21:50:15 +0200 Subject: [PATCH 03/10] fixed compents being freed premutrely --- .../geometry/intern/realize_instances.cc | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/source/blender/geometry/intern/realize_instances.cc b/source/blender/geometry/intern/realize_instances.cc index e82fc9e5953..5024a4bd6ee 100644 --- a/source/blender/geometry/intern/realize_instances.cc +++ b/source/blender/geometry/intern/realize_instances.cc @@ -231,7 +231,7 @@ struct AllInstancesInfo { /** store an array of void pointer to attributes for each component. */ Vector attribute_fallback; /** Instance components to merge for output geometry. */ - Vector instances_components_to_merge; + Vector instances_components_to_merge; /** Base transform for each instance component. */ Vector instances_components_transforms; }; @@ -697,7 +697,7 @@ static void gather_realize_tasks_recursive(GatherTasksInfo &gather_info, case bke::GeometryComponent::Type::Instance: { if (current_depth == target_depth) { gather_info.instances.attribute_fallback.append(base_instance_context.instances); - gather_info.instances.instances_components_to_merge.append(component); + gather_info.instances.instances_components_to_merge.append(component->copy()); gather_info.instances.instances_components_transforms.append(base_transform); } else { @@ -1045,7 +1045,7 @@ static void execute_realize_pointcloud_task( dst_attribute_writers); } static void execute_instances_tasks( - const Span src_components, + const Span src_components, Span src_base_transforms, OrderedAttributes all_instances_attributes, Span attribute_fallback, @@ -1060,7 +1060,7 @@ static void execute_instances_tasks( VArray::ForSpan(src_base_transforms); Array offsets_data(src_components.size() + 1); for (const int component_index : src_components.index_range()) { - const auto &src_component = static_cast( + const bke::InstancesComponent &src_component = static_cast( *src_components[component_index]); offsets_data[component_index] = src_component.get()->instances_num(); } @@ -1127,8 +1127,14 @@ static void execute_instances_tasks( } result.replace_instances(dst_instances.release()); auto &dst_component = result.get_component_for_write(); + Vector for_join_attributes; + for (bke::GeometryComponentPtr compent : src_components) + { + for_join_attributes.append(compent.get()); + } + join_attributes( - src_components, dst_component, {"position", ".reference_index", "instance_transform"}); + for_join_attributes, dst_component, {"position", ".reference_index", "instance_transform"}); } static void execute_realize_pointcloud_tasks(const RealizeInstancesOptions &options, @@ -1997,7 +2003,7 @@ bke::GeometrySet realize_instances(bke::GeometrySet geometry_set, if (not_to_realize_set.has_instances()) { gather_info.instances.instances_components_to_merge.append( - ¬_to_realize_set.get_component_for_write()); + (not_to_realize_set.get_component_for_write()).copy()); gather_info.instances.instances_components_transforms.append(float4x4::identity()); gather_info.instances.attribute_fallback.append((gather_info.instances_attriubutes.size())); } -- 2.30.2 From 92b690bf12ef2385592eefaad796475a56d40f49 Mon Sep 17 00:00:00 2001 From: David-Haver Date: Sat, 16 Mar 2024 18:59:13 +0200 Subject: [PATCH 04/10] includes cleanup --- source/blender/geometry/intern/realize_instances.cc | 9 --------- 1 file changed, 9 deletions(-) diff --git a/source/blender/geometry/intern/realize_instances.cc b/source/blender/geometry/intern/realize_instances.cc index 5024a4bd6ee..e0948493df3 100644 --- a/source/blender/geometry/intern/realize_instances.cc +++ b/source/blender/geometry/intern/realize_instances.cc @@ -2,23 +2,14 @@ * * SPDX-License-Identifier: GPL-2.0-or-later */ -#include "BKE_geometry_set.hh" #include "GEO_join_geometries.hh" #include "GEO_realize_instances.hh" #include "DNA_collection_types.h" -#include "DNA_layer_types.h" -#include "DNA_object_types.h" -#include "DNA_pointcloud_types.h" #include "BLI_array_utils.hh" -#include "BLI_listbase.h" -#include "BLI_math_matrix.hh" -#include "BLI_math_rotation.hh" #include "BLI_noise.hh" -#include "BLI_task.hh" -#include "BKE_collection.hh" #include "BKE_curves.hh" #include "BKE_customdata.hh" #include "BKE_geometry_set_instances.hh" -- 2.30.2 From 530014b766541a3cb3dd698b9b31851183836788 Mon Sep 17 00:00:00 2001 From: David-Haver Date: Sat, 16 Mar 2024 19:00:41 +0200 Subject: [PATCH 05/10] styling fixes --- .../blender/geometry/GEO_join_geometries.hh | 6 ++--- .../geometry/intern/join_geometries.cc | 22 +++++++++---------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/source/blender/geometry/GEO_join_geometries.hh b/source/blender/geometry/GEO_join_geometries.hh index 9e45bd5ab2b..0ee05a08014 100644 --- a/source/blender/geometry/GEO_join_geometries.hh +++ b/source/blender/geometry/GEO_join_geometries.hh @@ -12,7 +12,7 @@ namespace blender::geometry { bke::GeometrySet join_geometries(Span geometries, const bke::AnonymousAttributePropagationInfo &propagation_info); -void join_attributes(const Span src_components, - bke::GeometryComponent &result, - const Span ignored_attributes); +void join_attributes(Span src_components, + bke::GeometryComponent &r_result, + Span ignored_attributes = {}); } // namespace blender::geometry diff --git a/source/blender/geometry/intern/join_geometries.cc b/source/blender/geometry/intern/join_geometries.cc index 21c8303365d..e35d07e4719 100644 --- a/source/blender/geometry/intern/join_geometries.cc +++ b/source/blender/geometry/intern/join_geometries.cc @@ -74,8 +74,8 @@ static void fill_new_attribute(const Span src_compone } void join_attributes(const Span src_components, - GeometryComponent &result, - const Span ignored_attributes = {}) + GeometryComponent &r_result, + const Span ignored_attributes) { const Map info = get_final_attribute_info(src_components, ignored_attributes); @@ -85,7 +85,7 @@ void join_attributes(const Span src_components, const AttributeMetaData &meta_data = item.value; bke::GSpanAttributeWriter write_attribute = - result.attributes_for_write()->lookup_or_add_for_write_only_span( + r_result.attributes_for_write()->lookup_or_add_for_write_only_span( attribute_id, meta_data.domain, meta_data.data_type); if (!write_attribute) { continue; @@ -97,7 +97,7 @@ void join_attributes(const Span src_components, } static void join_instances(const Span src_components, - GeometrySet &result) + GeometrySet &r_result) { Array offsets_data(src_components.size() + 1); for (const int i : src_components.index_range()) { @@ -127,8 +127,8 @@ static void join_instances(const Span src_components, array_utils::gather(handle_map.as_span(), src_handles, all_handles.slice(dst_range)); } - result.replace_instances(dst_instances.release()); - auto &dst_component = result.get_component_for_write(); + r_result.replace_instances(dst_instances.release()); + auto &dst_component = r_result.get_component_for_write(); join_attributes(src_components, dst_component, {".reference_index"}); } @@ -142,7 +142,7 @@ static void join_volumes(const Span /*src_components* static void join_component_type(const bke::GeometryComponent::Type component_type, const Span src_geometry_sets, const bke::AnonymousAttributePropagationInfo &propagation_info, - GeometrySet &result) + GeometrySet &r_result) { Vector components; for (const GeometrySet &geometry_set : src_geometry_sets) { @@ -156,16 +156,16 @@ static void join_component_type(const bke::GeometryComponent::Type component_typ return; } if (components.size() == 1) { - result.add(*components.first()); + r_result.add(*components.first()); return; } switch (component_type) { case bke::GeometryComponent::Type::Instance: - join_instances(components, result); + join_instances(components, r_result); return; case bke::GeometryComponent::Type::Volume: - join_volumes(components, result); + join_volumes(components, r_result); return; default: break; @@ -191,7 +191,7 @@ static void join_component_type(const bke::GeometryComponent::Type component_typ VArray::ForSingle(true, instances.get()->instances_num()), memory); GeometrySet joined_components = realize_instances( GeometrySet::from_instances(instances.release()), options); - result.add(joined_components.get_component_for_write(component_type)); + r_result.add(joined_components.get_component_for_write(component_type)); } GeometrySet join_geometries(const Span geometries, -- 2.30.2 From 04c55458275ce6839f0e54e38b517c2403624d8c Mon Sep 17 00:00:00 2001 From: David-Haver Date: Tue, 19 Mar 2024 21:12:14 +0200 Subject: [PATCH 06/10] splited selection and depths iuy of RealizeInstancesOptions + miscellaneous --- .../blender/geometry/GEO_realize_instances.hh | 28 ++- .../geometry/intern/join_geometries.cc | 5 +- .../geometry/intern/realize_instances.cc | 229 ++++++++++-------- .../nodes/node_geo_realize_instances.cc | 33 +-- 4 files changed, 176 insertions(+), 119 deletions(-) diff --git a/source/blender/geometry/GEO_realize_instances.hh b/source/blender/geometry/GEO_realize_instances.hh index 42532655b36..6092585eb0a 100644 --- a/source/blender/geometry/GEO_realize_instances.hh +++ b/source/blender/geometry/GEO_realize_instances.hh @@ -8,6 +8,9 @@ namespace blender::geometry { +/** + * General options for realize_instances. + */ struct RealizeInstancesOptions { /** * The default is to generate new ids for every element (when there was any id attribute in the @@ -22,6 +25,13 @@ struct RealizeInstancesOptions { */ bool realize_instance_attributes = true; + bke::AnonymousAttributePropagationInfo propagation_info; +}; + +/** + * Allow the user to choice which instances to realize and to what depth. + */ +struct SpecificInstancesChoice { /** * Selection of top-level instances to realize. */ @@ -32,7 +42,7 @@ struct RealizeInstancesOptions { */ VArray depths; - bke::AnonymousAttributePropagationInfo propagation_info; + static const int MAX_DEPTH = -1; }; /** @@ -48,4 +58,20 @@ struct RealizeInstancesOptions { bke::GeometrySet realize_instances(bke::GeometrySet geometry_set, const RealizeInstancesOptions &options); +/** + * Join all instances into a single geometry component for each geometry type. For example, all + * mesh instances (including the already realized mesh) are joined into a single mesh. The output + * geometry set does not contain any instances. If the input did not contain any instances, it is + * returned directly. + * + * The `id` attribute has special handling. If there is an id attribute on any component, the + * output will contain an `id` attribute as well. The output id is generated by mixing/hashing ids + * of instances and of the instanced geometry data. + * + * Will realize only the instaces chosen by chosen_instaces to there chosen depth. + */ +bke::GeometrySet realize_instances(bke::GeometrySet geometry_set, + const RealizeInstancesOptions &options, + const SpecificInstancesChoice &chosen_instaces); + } // namespace blender::geometry diff --git a/source/blender/geometry/intern/join_geometries.cc b/source/blender/geometry/intern/join_geometries.cc index e35d07e4719..92912e9fa1a 100644 --- a/source/blender/geometry/intern/join_geometries.cc +++ b/source/blender/geometry/intern/join_geometries.cc @@ -185,10 +185,7 @@ static void join_component_type(const bke::GeometryComponent::Type component_typ options.keep_original_ids = true; options.realize_instance_attributes = false; options.propagation_info = propagation_info; - options.depths = VArray::ForSingle(-1, instances.get()->instances_num()); - IndexMaskMemory memory; - options.selection = IndexMask::from_bools( - VArray::ForSingle(true, instances.get()->instances_num()), memory); + GeometrySet joined_components = realize_instances( GeometrySet::from_instances(instances.release()), options); r_result.add(joined_components.get_component_for_write(component_type)); diff --git a/source/blender/geometry/intern/realize_instances.cc b/source/blender/geometry/intern/realize_instances.cc index e0948493df3..4c296632772 100644 --- a/source/blender/geometry/intern/realize_instances.cc +++ b/source/blender/geometry/intern/realize_instances.cc @@ -49,13 +49,13 @@ struct OrderedAttributes { } }; +/** + * Instance attribute values used as fallback when the geometry does not have the + * corresponding attributes itself. The pointers point to attributes stored in the instances + * component or in #r_temporary_arrays. The order depends on the corresponding #OrderedAttributes + * instance. + */ struct AttributeFallbacksArray { - /** - * Instance attribute values used as fallback when the geometry does not have the - * corresponding attributes itself. The pointers point to attributes stored in the instances - * component or in #r_temporary_arrays. The order depends on the corresponding #OrderedAttributes - * instance. - */ Array array; AttributeFallbacksArray(int size) : array(size, nullptr) {} @@ -400,12 +400,12 @@ static void copy_generic_attributes_to_result( }); } -static void create_result_ids(const RealizeInstancesOptions &options, +static void create_result_ids(bool keep_original_ids, Span stored_ids, const int task_id, MutableSpan dst_ids) { - if (options.keep_original_ids) { + if (keep_original_ids) { if (stored_ids.is_empty()) { dst_ids.fill(0); } @@ -733,6 +733,15 @@ static void gather_realize_tasks_recursive(GatherTasksInfo &gather_info, } } +/** + * This function iterates through a set of geometries, applying a callback to each attribute of + * eligible children based on specified conditions. Attributes should not be removed or added + * by the callback. Relevant children are determined by three criteria: the component type + * (e.g., mesh, curve), a depth value greater than 0 and aselection. If the primary component + * is an instance, the condition is true only when the depthis exactly 0. Additionally, the + * function extends its operation to instances if any of theirnested children meet the first + * condition. Also, an initial depth of 0 is equal to infinity for iteration easier use. + */ bool static attribute_foreach(const bke::GeometrySet &geometry_set, const Span component_types, const int current_depth, @@ -741,44 +750,32 @@ bool static attribute_foreach(const bke::GeometrySet &geometry_set, const IndexMask selection, const bke::GeometrySet::AttributeForeachCallback callback) { - /** - * This function iterates through a set of geometries, applying a callback to each attribute of - * eligible children based on specified conditions. Relevant children are determined by three - * criteria: the component type (e.g., mesh, curve), a depth value greater than 0 and a - * selection. If the primary component is an instance, the condition is true only when the depth - * is exactly 0. Additionally, the function extends its operation to instances if any of their - * nested children meet the first condition. Also, an initial depth of 0 is equal to infinity for - * easier use. - */ /*Initialize flag to track if child instances have the specified components.*/ - bool is_child_has_component = true; + bool child_has_component = true; if (geometry_set.has_instances()) { - is_child_has_component = false; + child_has_component = false; const Instances &instances = *geometry_set.get_instances(); - /*ensure objects and collection are included.*/ - Instances ensure_instances = instances; - const IndexMask indices = (current_depth == 0) ? + const IndexMask indices = (0 == current_depth) ? selection : IndexMask(IndexRange(instances.instances_num())); for (const int index : indices.index_range()) { const int i = indices[index]; - const int depth_target_tmp = (current_depth == 0) ? instance_depth[i] : depth_target; + const int depth_target_tmp = (0 == current_depth) ? instance_depth[i] : depth_target; bke::GeometrySet instance_geometry_set; geometry_set_from_reference(instances.references()[instances.reference_handles()[i]], instance_geometry_set); /*Process child instances with a recursive call.*/ if (current_depth != depth_target_tmp) { - is_child_has_component = attribute_foreach(instance_geometry_set, - component_types, - current_depth + 1, - depth_target_tmp, - instance_depth, - selection, - callback) || - is_child_has_component; + child_has_component = child_has_component | attribute_foreach(instance_geometry_set, + component_types, + current_depth + 1, + depth_target_tmp, + instance_depth, + selection, + callback); } } } @@ -787,27 +784,25 @@ bool static attribute_foreach(const bke::GeometrySet &geometry_set, bool is_relevant = false; for (const bke::GeometryComponent::Type component_type : component_types) { - if (!geometry_set.has(component_type)) { - continue; - } + if (geometry_set.has(component_type)) { + /*Check if the current instance components is the main one*/ + const bool is_special_instance = (bke::GeometryComponent::Type::Instance == + component_type) && + (component_types.size() > 1); + if (!is_special_instance || child_has_component) { + /*Process attributes for the current component.*/ + const bke::GeometryComponent &component = *geometry_set.get_component(component_type); + const std::optional attributes = component.attributes(); + if (attributes.has_value()) { + attributes->for_all( + [&](const AttributeIDRef &attributeId, const AttributeMetaData &metaData) { + callback(attributeId, metaData, component); + return true; + }); - /*Check if the current instance components is the main one*/ - const bool is_special_instance = (component_type == bke::GeometryComponent::Type::Instance) && - (component_types.size() > 1); - if (is_special_instance && !is_child_has_component) { - continue; - } - /*Process attributes for the current component.*/ - const bke::GeometryComponent &component = *geometry_set.get_component(component_type); - const std::optional attributes = component.attributes(); - if (attributes.has_value()) { - attributes->for_all( - [&](const AttributeIDRef &attributeId, const AttributeMetaData &metaData) { - callback(attributeId, metaData, component); - return true; - }); - - is_relevant = true; + is_relevant = true; + } + } } } @@ -830,7 +825,7 @@ void static gather_attributes_for_propagation( attribute_foreach(re_geometry_set, component_types, 0, - -1, + SpecificInstancesChoice::MAX_DEPTH, instance_depth, selection, [&](const AttributeIDRef &attribute_id, @@ -881,7 +876,7 @@ void static gather_attributes_for_propagation( static OrderedAttributes gather_generic_instance_attributes_to_propagate( const bke::GeometrySet &in_geometry_set, const RealizeInstancesOptions &options, - bool &r_create_id) + const SpecificInstancesChoice &chosen_instances) { Vector src_component_types; src_component_types.append(bke::GeometryComponent::Type::Instance); @@ -890,13 +885,13 @@ static OrderedAttributes gather_generic_instance_attributes_to_propagate( gather_attributes_for_propagation(in_geometry_set, src_component_types, bke::GeometryComponent::Type::Instance, - options.depths, - options.selection, + chosen_instances.depths, + chosen_instances.selection, options.propagation_info, attributes_to_propagate); attributes_to_propagate.remove("position"); attributes_to_propagate.remove("radius"); - r_create_id = attributes_to_propagate.pop_try("id").has_value(); + attributes_to_propagate.pop_try("id").has_value(); OrderedAttributes ordered_attributes; for (const auto item : attributes_to_propagate.items()) { ordered_attributes.ids.add_new(item.key); @@ -908,6 +903,7 @@ static OrderedAttributes gather_generic_instance_attributes_to_propagate( static OrderedAttributes gather_generic_pointcloud_attributes_to_propagate( const bke::GeometrySet &in_geometry_set, const RealizeInstancesOptions &options, + const SpecificInstancesChoice &chosen_instances, bool &r_create_radii, bool &r_create_id) { @@ -919,15 +915,15 @@ static OrderedAttributes gather_generic_pointcloud_attributes_to_propagate( Map attributes_to_propagate; // in_geometry_set.gather_attributes_for_propagation(src_component_types, // bke::GeometryComponent::Type::PointCloud, - // options.depths, - // options.selection, + // chosen_instances.depths, + // chosen_instances.selection, // options.propagation_info, // attributes_to_propagate); gather_attributes_for_propagation(in_geometry_set, src_component_types, bke::GeometryComponent::Type::PointCloud, - options.depths, - options.selection, + chosen_instances.depths, + chosen_instances.selection, options.propagation_info, attributes_to_propagate); attributes_to_propagate.remove("position"); @@ -957,11 +953,15 @@ static void gather_pointclouds_to_realize(const bke::GeometrySet &geometry_set, } static AllPointCloudsInfo preprocess_pointclouds(const bke::GeometrySet &geometry_set, - const RealizeInstancesOptions &options) + const RealizeInstancesOptions &options, + const SpecificInstancesChoice &chosen_instances) { AllPointCloudsInfo info; - info.attributes = gather_generic_pointcloud_attributes_to_propagate( - geometry_set, options, info.create_radius_attribute, info.create_id_attribute); + info.attributes = gather_generic_pointcloud_attributes_to_propagate(geometry_set, + options, + chosen_instances, + info.create_radius_attribute, + info.create_id_attribute); gather_pointclouds_to_realize(geometry_set, info.order); info.realize_info.reinitialize(info.order.size()); @@ -1000,7 +1000,7 @@ static AllPointCloudsInfo preprocess_pointclouds(const bke::GeometrySet &geometr } static void execute_realize_pointcloud_task( - const RealizeInstancesOptions &options, + bool keep_original_ids, const RealizePointCloudTask &task, const OrderedAttributes &ordered_attributes, MutableSpan dst_attribute_writers, @@ -1018,7 +1018,7 @@ static void execute_realize_pointcloud_task( /* Create point ids. */ if (!all_dst_ids.is_empty()) { create_result_ids( - options, pointcloud_info.stored_ids, task.id, all_dst_ids.slice(point_slice)); + keep_original_ids, pointcloud_info.stored_ids, task.id, all_dst_ids.slice(point_slice)); } if (!all_dst_radii.is_empty()) { pointcloud_info.radii.materialize(all_dst_radii.slice(point_slice)); @@ -1035,6 +1035,7 @@ static void execute_realize_pointcloud_task( }, dst_attribute_writers); } + static void execute_instances_tasks( const Span src_components, Span src_base_transforms, @@ -1119,16 +1120,15 @@ static void execute_instances_tasks( result.replace_instances(dst_instances.release()); auto &dst_component = result.get_component_for_write(); Vector for_join_attributes; - for (bke::GeometryComponentPtr compent : src_components) - { + for (bke::GeometryComponentPtr compent : src_components) { for_join_attributes.append(compent.get()); } - + join_attributes( for_join_attributes, dst_component, {"position", ".reference_index", "instance_transform"}); } -static void execute_realize_pointcloud_tasks(const RealizeInstancesOptions &options, +static void execute_realize_pointcloud_tasks(bool keep_original_ids, const AllPointCloudsInfo &all_pointclouds_info, const Span tasks, const OrderedAttributes &ordered_attributes, @@ -1180,7 +1180,7 @@ static void execute_realize_pointcloud_tasks(const RealizeInstancesOptions &opti threading::parallel_for(tasks.index_range(), 100, [&](const IndexRange task_range) { for (const int task_index : task_range) { const RealizePointCloudTask &task = tasks[task_index]; - execute_realize_pointcloud_task(options, + execute_realize_pointcloud_task(keep_original_ids, task, ordered_attributes, dst_attribute_writers, @@ -1208,6 +1208,7 @@ static void execute_realize_pointcloud_tasks(const RealizeInstancesOptions &opti static OrderedAttributes gather_generic_mesh_attributes_to_propagate( const bke::GeometrySet &in_geometry_set, const RealizeInstancesOptions &options, + const SpecificInstancesChoice &chosen_instances, bool &r_create_id, bool &r_create_material_index) { @@ -1221,8 +1222,8 @@ static OrderedAttributes gather_generic_mesh_attributes_to_propagate( gather_attributes_for_propagation(in_geometry_set, src_component_types, bke::GeometryComponent::Type::Mesh, - options.depths, - options.selection, + chosen_instances.depths, + chosen_instances.selection, options.propagation_info, attributes_to_propagate); attributes_to_propagate.remove("position"); @@ -1255,11 +1256,16 @@ static void gather_meshes_to_realize(const bke::GeometrySet &geometry_set, } static AllMeshesInfo preprocess_meshes(const bke::GeometrySet &geometry_set, - const RealizeInstancesOptions &options) + const RealizeInstancesOptions &options, + const SpecificInstancesChoice &chosen_instances) { AllMeshesInfo info; info.attributes = gather_generic_mesh_attributes_to_propagate( - geometry_set, options, info.create_id_attribute, info.create_material_index_attribute); + geometry_set, + options, + chosen_instances, + info.create_id_attribute, + info.create_material_index_attribute); gather_meshes_to_realize(geometry_set, info.order); for (const Mesh *mesh : info.order) { @@ -1337,7 +1343,7 @@ static AllMeshesInfo preprocess_meshes(const bke::GeometrySet &geometry_set, return info; } -static void execute_realize_mesh_task(const RealizeInstancesOptions &options, +static void execute_realize_mesh_task(bool keep_original_ids, const RealizeMeshTask &task, const OrderedAttributes &ordered_attributes, MutableSpan dst_attribute_writers, @@ -1421,7 +1427,7 @@ static void execute_realize_mesh_task(const RealizeInstancesOptions &options, } if (!all_dst_vertex_ids.is_empty()) { - create_result_ids(options, + create_result_ids(keep_original_ids, mesh_info.stored_vertex_ids, task.id, all_dst_vertex_ids.slice(task.start_indices.vertex, mesh.verts_num)); @@ -1449,7 +1455,7 @@ static void execute_realize_mesh_task(const RealizeInstancesOptions &options, dst_attribute_writers); } -static void execute_realize_mesh_tasks(const RealizeInstancesOptions &options, +static void execute_realize_mesh_tasks(bool keep_original_ids, const AllMeshesInfo &all_meshes_info, const Span tasks, const OrderedAttributes &ordered_attributes, @@ -1532,7 +1538,7 @@ static void execute_realize_mesh_tasks(const RealizeInstancesOptions &options, threading::parallel_for(tasks.index_range(), 100, [&](const IndexRange task_range) { for (const int task_index : task_range) { const RealizeMeshTask &task = tasks[task_index]; - execute_realize_mesh_task(options, + execute_realize_mesh_task(keep_original_ids, task, ordered_attributes, dst_attribute_writers, @@ -1573,6 +1579,7 @@ static void execute_realize_mesh_tasks(const RealizeInstancesOptions &options, static OrderedAttributes gather_generic_curve_attributes_to_propagate( const bke::GeometrySet &in_geometry_set, const RealizeInstancesOptions &options, + const SpecificInstancesChoice &chosen_instances, bool &r_create_id) { Vector src_component_types; @@ -1585,8 +1592,8 @@ static OrderedAttributes gather_generic_curve_attributes_to_propagate( gather_attributes_for_propagation(in_geometry_set, src_component_types, bke::GeometryComponent::Type::Curve, - options.depths, - options.selection, + chosen_instances.depths, + chosen_instances.selection, options.propagation_info, attributes_to_propagate); attributes_to_propagate.remove("position"); @@ -1621,11 +1628,12 @@ static void gather_curves_to_realize(const bke::GeometrySet &geometry_set, } static AllCurvesInfo preprocess_curves(const bke::GeometrySet &geometry_set, - const RealizeInstancesOptions &options) + const RealizeInstancesOptions &options, + const SpecificInstancesChoice &chosen_instances) { AllCurvesInfo info; info.attributes = gather_generic_curve_attributes_to_propagate( - geometry_set, options, info.create_id_attribute); + geometry_set, options, chosen_instances, info.create_id_attribute); gather_curves_to_realize(geometry_set, info.order); info.realize_info.reinitialize(info.order.size()); @@ -1684,7 +1692,7 @@ static AllCurvesInfo preprocess_curves(const bke::GeometrySet &geometry_set, return info; } -static void execute_realize_curve_task(const RealizeInstancesOptions &options, +static void execute_realize_curve_task(bool keep_original_ids, const AllCurvesInfo &all_curves_info, const RealizeCurveTask &task, const OrderedAttributes &ordered_attributes, @@ -1767,7 +1775,7 @@ static void execute_realize_curve_task(const RealizeInstancesOptions &options, if (!all_dst_ids.is_empty()) { create_result_ids( - options, curves_info.stored_ids, task.id, all_dst_ids.slice(dst_point_range)); + keep_original_ids, curves_info.stored_ids, task.id, all_dst_ids.slice(dst_point_range)); } copy_generic_attributes_to_result( @@ -1788,7 +1796,7 @@ static void execute_realize_curve_task(const RealizeInstancesOptions &options, dst_attribute_writers); } -static void execute_realize_curve_tasks(const RealizeInstancesOptions &options, +static void execute_realize_curve_tasks(bool keep_original_ids, const AllCurvesInfo &all_curves_info, const Span tasks, const OrderedAttributes &ordered_attributes, @@ -1867,7 +1875,7 @@ static void execute_realize_curve_tasks(const RealizeInstancesOptions &options, threading::parallel_for(tasks.index_range(), 100, [&](const IndexRange task_range) { for (const int task_index : task_range) { const RealizeCurveTask &task = tasks[task_index]; - execute_realize_curve_task(options, + execute_realize_curve_task(keep_original_ids, all_curves_info, task, ordered_attributes, @@ -1947,6 +1955,23 @@ static void propagate_instances_to_keep( bke::GeometrySet realize_instances(bke::GeometrySet geometry_set, const RealizeInstancesOptions &options) +{ + if (!geometry_set.has_instances()) { + return geometry_set; + } + + SpecificInstancesChoice all_instances; + all_instances.depths = VArray::ForSingle(SpecificInstancesChoice::MAX_DEPTH, + geometry_set.get_instances()->instances_num()); + IndexMaskMemory memory; + all_instances.selection = IndexMask::from_bools( + VArray::ForSingle(true, geometry_set.get_instances()->instances_num()), memory); + return realize_instances(geometry_set, options, all_instances); +} + +bke::GeometrySet realize_instances(bke::GeometrySet geometry_set, + const RealizeInstancesOptions &options, + const SpecificInstancesChoice &chosen_instances) { /* The algorithm works in three steps: * 1. Preprocess each unique geometry that is instanced (e.g. each `Mesh`). @@ -1961,18 +1986,18 @@ bke::GeometrySet realize_instances(bke::GeometrySet geometry_set, bke::GeometrySet not_to_realize_set; propagate_instances_to_keep( - geometry_set, options.selection, not_to_realize_set, options.propagation_info); + geometry_set, chosen_instances.selection, not_to_realize_set, options.propagation_info); if (options.keep_original_ids) { remove_id_attribute_from_instances(geometry_set); } - AllPointCloudsInfo all_pointclouds_info = preprocess_pointclouds(geometry_set, options); - AllMeshesInfo all_meshes_info = preprocess_meshes(geometry_set, options); - AllCurvesInfo all_curves_info = preprocess_curves(geometry_set, options); - bool tmp = true; + AllPointCloudsInfo all_pointclouds_info = preprocess_pointclouds( + geometry_set, options, chosen_instances); + AllMeshesInfo all_meshes_info = preprocess_meshes(geometry_set, options, chosen_instances); + AllCurvesInfo all_curves_info = preprocess_curves(geometry_set, options, chosen_instances); OrderedAttributes all_instance_attributes = gather_generic_instance_attributes_to_propagate( - geometry_set, options, tmp); + geometry_set, options, chosen_instances); Vector>> temporary_arrays; const bool create_id_attribute = all_pointclouds_info.create_id_attribute || @@ -1983,8 +2008,8 @@ bke::GeometrySet realize_instances(bke::GeometrySet geometry_set, all_curves_info, all_instance_attributes, create_id_attribute, - options.selection, - options.depths, + chosen_instances.selection, + chosen_instances.depths, temporary_arrays}; bke::GeometrySet new_geometry_set; @@ -1999,25 +2024,33 @@ bke::GeometrySet realize_instances(bke::GeometrySet geometry_set, gather_info.instances.attribute_fallback.append((gather_info.instances_attriubutes.size())); } - gather_realize_tasks_recursive(gather_info, 0, -1, geometry_set, transform, attribute_fallbacks); + gather_realize_tasks_recursive(gather_info, + 0, + SpecificInstancesChoice::MAX_DEPTH, + geometry_set, + transform, + attribute_fallbacks); execute_instances_tasks(gather_info.instances.instances_components_to_merge, gather_info.instances.instances_components_transforms, all_instance_attributes, gather_info.instances.attribute_fallback, new_geometry_set); - execute_realize_pointcloud_tasks(options, + + execute_realize_pointcloud_tasks(options.keep_original_ids, all_pointclouds_info, gather_info.r_tasks.pointcloud_tasks, all_pointclouds_info.attributes, new_geometry_set); - execute_realize_mesh_tasks(options, + + execute_realize_mesh_tasks(options.keep_original_ids, all_meshes_info, gather_info.r_tasks.mesh_tasks, all_meshes_info.attributes, all_meshes_info.materials, new_geometry_set); - execute_realize_curve_tasks(options, + + execute_realize_curve_tasks(options.keep_original_ids, all_curves_info, gather_info.r_tasks.curve_tasks, all_curves_info.attributes, diff --git a/source/blender/nodes/geometry/nodes/node_geo_realize_instances.cc b/source/blender/nodes/geometry/nodes/node_geo_realize_instances.cc index 34c1b8f11c7..d912728ff5e 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_realize_instances.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_realize_instances.cc @@ -19,13 +19,13 @@ static void node_declare(NodeDeclarationBuilder &b) .default_value(true) .hide_value() .supports_field() - .description(("Which top-level instances to realize")); + .description("Which top-level instances to realize"); b.add_input("Realize All") .default_value(true) .supports_field() - .description(("Determine wether to realize nested instances completly")); + .description("Determine wether to realize nested instances completly"); b.add_input("Depth").default_value(0).min(0).supports_field().description( - ("Number of levels of nested instances to realize for each top-level instance")); + "Number of levels of nested instances to realize for each top-level instance"); b.add_output("Geometry").propagate_all(); } @@ -36,6 +36,7 @@ static void node_geo_exec(GeoNodeExecParams params) params.set_output("Geometry", std::move(geometry_set)); return; } + GeometryComponentEditData::remember_deformed_positions_if_necessary(geometry_set); Field selection_field = params.extract_input>("Selection"); Field realize_all_filed = params.extract_input>("Realize All"); @@ -43,35 +44,35 @@ static void node_geo_exec(GeoNodeExecParams params) static auto depth_override = mf::build::SI2_SO( "depth_override", - [](int value, bool realize) { return realize ? -1 : std::max(value, 0); }, + [](int value, bool realize) { return realize ? -1 : value; }, mf::build::exec_presets::AllSpanOrSingle()); - static auto selction_override = mf::build::SI2_SO( - "selction_override", + static auto selection_override = mf::build::SI2_SO( + "selection_override", [](int value, bool selection) { return value == 0 ? false : selection; }, mf::build::exec_presets::AllSpanOrSingle()); - const bke::Instances &instances = *geometry_set.get_instances(); - const bke::InstancesFieldContext field_context{instances}; - fn::FieldEvaluator evaluator{field_context, instances.instances_num()}; - Field depth_field_overrided( FieldOperation::Create(depth_override, {depth_field, realize_all_filed})); Field selection_field_overrided( - FieldOperation::Create(selction_override, {depth_field_overrided, selection_field})); + FieldOperation::Create(selection_override, {depth_field_overrided, selection_field})); - evaluator.add(depth_field_overrided); + const bke::Instances &instances = *geometry_set.get_instances(); + const bke::InstancesFieldContext field_context(instances); + fn::FieldEvaluator evaluator(field_context, instances.instances_num()); + + const int evaluated_depth_index = evaluator.add(depth_field_overrided); evaluator.set_selection(selection_field_overrided); evaluator.evaluate(); - const VArray depths = evaluator.get_evaluated(0); - const IndexMask selection = evaluator.get_evaluated_selection_as_mask(); + + geometry::SpecificInstancesChoice chosen_instances; + chosen_instances.depths = evaluator.get_evaluated(evaluated_depth_index); + chosen_instances.selection = evaluator.get_evaluated_selection_as_mask(); geometry::RealizeInstancesOptions options; options.keep_original_ids = false; options.realize_instance_attributes = true; options.propagation_info = params.get_output_propagation_info("Geometry"); - options.depths = depths; - options.selection = selection; geometry_set = geometry::realize_instances(geometry_set, options); params.set_output("Geometry", std::move(geometry_set)); } -- 2.30.2 From 24f953b5620e3354b483e8aa089691df002a3305 Mon Sep 17 00:00:00 2001 From: David-Haver Date: Wed, 20 Mar 2024 22:02:32 +0200 Subject: [PATCH 07/10] changed realize_instances to the correct overload --- .../blender/nodes/geometry/nodes/node_geo_realize_instances.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/nodes/geometry/nodes/node_geo_realize_instances.cc b/source/blender/nodes/geometry/nodes/node_geo_realize_instances.cc index d912728ff5e..b7ae1f1863e 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_realize_instances.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_realize_instances.cc @@ -73,7 +73,7 @@ static void node_geo_exec(GeoNodeExecParams params) options.keep_original_ids = false; options.realize_instance_attributes = true; options.propagation_info = params.get_output_propagation_info("Geometry"); - geometry_set = geometry::realize_instances(geometry_set, options); + geometry_set = geometry::realize_instances(geometry_set, options, chosen_instances); params.set_output("Geometry", std::move(geometry_set)); } -- 2.30.2 From 9ce905cbaaf2e3f303ff73debf7640166f45d750 Mon Sep 17 00:00:00 2001 From: David-Haver Date: Thu, 21 Mar 2024 01:19:39 +0200 Subject: [PATCH 08/10] making the code more readable --- .../blender/geometry/GEO_join_geometries.hh | 2 +- .../blender/geometry/GEO_realize_instances.hh | 3 + .../geometry/intern/realize_instances.cc | 291 +++++++++--------- 3 files changed, 154 insertions(+), 142 deletions(-) diff --git a/source/blender/geometry/GEO_join_geometries.hh b/source/blender/geometry/GEO_join_geometries.hh index 0ee05a08014..8003cf5028b 100644 --- a/source/blender/geometry/GEO_join_geometries.hh +++ b/source/blender/geometry/GEO_join_geometries.hh @@ -3,9 +3,9 @@ * SPDX-License-Identifier: GPL-2.0-or-later */ #pragma once + #include "BKE_anonymous_attribute_id.hh" #include "BKE_geometry_set.hh" -#include "BLI_math_matrix_types.hh" namespace blender::geometry { diff --git a/source/blender/geometry/GEO_realize_instances.hh b/source/blender/geometry/GEO_realize_instances.hh index 6092585eb0a..090b5382473 100644 --- a/source/blender/geometry/GEO_realize_instances.hh +++ b/source/blender/geometry/GEO_realize_instances.hh @@ -42,6 +42,9 @@ struct SpecificInstancesChoice { */ VArray depths; + /** + * Use this value to realize the instance completely + */ static const int MAX_DEPTH = -1; }; diff --git a/source/blender/geometry/intern/realize_instances.cc b/source/blender/geometry/intern/realize_instances.cc index 4c296632772..ac1fda29584 100644 --- a/source/blender/geometry/intern/realize_instances.cc +++ b/source/blender/geometry/intern/realize_instances.cc @@ -49,13 +49,13 @@ struct OrderedAttributes { } }; -/** - * Instance attribute values used as fallback when the geometry does not have the - * corresponding attributes itself. The pointers point to attributes stored in the instances - * component or in #r_temporary_arrays. The order depends on the corresponding #OrderedAttributes - * instance. - */ struct AttributeFallbacksArray { + /** + * Instance attribute values used as fallback when the geometry does not have the + * corresponding attributes itself. The pointers point to attributes stored in the instances + * component or in #r_temporary_arrays. The order depends on the corresponding #OrderedAttributes + * instance. + */ Array array; AttributeFallbacksArray(int size) : array(size, nullptr) {} @@ -218,6 +218,7 @@ struct AllCurvesInfo { bool create_nurbs_weight_attribute = false; bool create_custom_normal_attribute = false; }; + struct AllInstancesInfo { /** store an array of void pointer to attributes for each component. */ Vector attribute_fallback; @@ -226,6 +227,7 @@ struct AllInstancesInfo { /** Base transform for each instance component. */ Vector instances_components_transforms; }; + /** Collects all tasks that need to be executed to realize all instances. */ struct GatherTasks { Vector pointcloud_tasks; @@ -296,33 +298,25 @@ struct InstanceContext { curves(gather_info.curves.attributes.size()), instances(gather_info.instances_attriubutes.size()) { + // empty } }; static void realize_collections(Collection *collection, bke::Instances *instances) { - Vector children_collections; LISTBASE_FOREACH (CollectionChild *, collection_child, &collection->children) { - children_collections.append(collection_child->collection); - } - Vector children_objects; - LISTBASE_FOREACH (CollectionObject *, collection_object, &collection->gobject) { - children_objects.append(collection_object->ob); + float4x4 transform = float4x4::identity(); + transform.location() += float3((collection_child->collection)->instance_offset); + transform.location() -= float3(collection->instance_offset); + const int handle = instances->add_reference(*(collection_child->collection)); + instances->add_instance(handle, transform); } - for (Collection *child_collection : children_collections) { - float4x4 transform = float4x4::identity(); - transform.location() += float3(child_collection->instance_offset); - transform.location() -= float3(collection->instance_offset); - const int handle = instances->add_reference(*child_collection); - instances->add_instance(handle, transform); - // entries.append({handle, &(child_collection->id.name[2]), transform}); - } - for (Object *child_object : children_objects) { - const int handle = instances->add_reference(*child_object); + LISTBASE_FOREACH (CollectionObject *, collection_object, &collection->gobject) { float4x4 transform = float4x4::identity(); transform.location() -= float3(collection->instance_offset); - transform *= child_object->object_to_world(); + transform *= (collection_object->ob)->object_to_world(); + const int handle = instances->add_reference(*(collection_object->ob)); instances->add_instance(handle, transform); } } @@ -488,10 +482,6 @@ static Vector> prepare_attribute_fallbacks( return attributes_to_override; } -/** - * Calls #fn for every geometry in the given #InstanceReference. Also passes on the transformation - * that is applied to every instance. - */ static bke::GeometrySet &geometry_set_from_reference(const InstanceReference &reference, bke::GeometrySet &r_geometry_set) { @@ -505,7 +495,7 @@ static bke::GeometrySet &geometry_set_from_reference(const InstanceReference &re Collection *collection_ptr = &reference.collection(); std::unique_ptr instances = std::make_unique(); realize_collections(collection_ptr, instances.get()); - r_geometry_set = bke::GeometrySet::from_instances(instances.release()); + r_geometry_set.replace_instances(instances.release()); break; } case InstanceReference::Type::GeometrySet: { @@ -524,6 +514,10 @@ static bke::GeometrySet &geometry_set_from_reference(const InstanceReference &re return r_geometry_set; } +/** + * Calls #fn for every geometry in the given #InstanceReference. Also passes on the transformation + * that is applied to every instance. + */ static void foreach_geometry_in_reference( const InstanceReference &reference, const float4x4 &base_transform, @@ -737,12 +731,14 @@ static void gather_realize_tasks_recursive(GatherTasksInfo &gather_info, * This function iterates through a set of geometries, applying a callback to each attribute of * eligible children based on specified conditions. Attributes should not be removed or added * by the callback. Relevant children are determined by three criteria: the component type - * (e.g., mesh, curve), a depth value greater than 0 and aselection. If the primary component - * is an instance, the condition is true only when the depthis exactly 0. Additionally, the - * function extends its operation to instances if any of theirnested children meet the first - * condition. Also, an initial depth of 0 is equal to infinity for iteration easier use. + * (e.g., mesh, curve), a depth value greater than 0 and a selection. If the primary component + * is an instance, the condition is true only when the depth is exactly 0. Additionally, the + * function extends its operation to instances if any of their nested children meet the first + * condition. + * + * Based on bke::GeometrySet::attribute_foreach */ -bool static attribute_foreach(const bke::GeometrySet &geometry_set, +static bool attribute_foreach(const bke::GeometrySet &geometry_set, const Span component_types, const int current_depth, const int depth_target, @@ -809,6 +805,11 @@ bool static attribute_foreach(const bke::GeometrySet &geometry_set, return is_relevant; } +/** + * Based on bke::GeometrySet::gather_attributes_for_propagation. + * Specialized for Specialized attribute_foreach to get: + * current_depth, depth_target, instance_depth and selection. + */ void static gather_attributes_for_propagation( bke::GeometrySet re_geometry_set, const Span component_types, @@ -867,10 +868,11 @@ void static gather_attributes_for_propagation( r_attributes.add_or_modify(attribute_id, add_info, modify_info); }); } + /** \} */ /* -------------------------------------------------------------------- */ -/** \name Point Cloud +/** \name Instance * \{ */ static OrderedAttributes gather_generic_instance_attributes_to_propagate( @@ -900,6 +902,109 @@ static OrderedAttributes gather_generic_instance_attributes_to_propagate( return ordered_attributes; } +static void execute_instances_tasks( + const Span src_components, + Span src_base_transforms, + OrderedAttributes all_instances_attributes, + Span attribute_fallback, + bke::GeometrySet &r_realized_geometry) +{ + BLI_assert(src_components.size() == src_base_transforms.size() && + src_components.size() == attribute_fallback.size()); + if (src_components.is_empty()) { + return; + } + + VArray::ForSpan(src_base_transforms); + Array offsets_data(src_components.size() + 1); + for (const int component_index : src_components.index_range()) { + const bke::InstancesComponent &src_component = static_cast( + *src_components[component_index]); + offsets_data[component_index] = src_component.get()->instances_num(); + } + const OffsetIndices offsets = offset_indices::accumulate_counts_to_offsets(offsets_data); + + std::unique_ptr dst_instances = std::make_unique(); + dst_instances->resize(offsets.total_size()); + + /* Prepare generic output attributes. */ + for (const int attribute_index : all_instances_attributes.index_range()) { + bke::AttrDomain domain = bke::AttrDomain::Instance; + bke::AttributeIDRef id = all_instances_attributes.ids[attribute_index]; + eCustomDataType type = all_instances_attributes.kinds[attribute_index].data_type; + blender::bke::MutableAttributeAccessor attr = dst_instances->attributes_for_write(); + attr.lookup_or_add_for_write_only_span(id, domain, type).finish(); + } + + MutableSpan all_transforms = dst_instances->transforms_for_write(); + MutableSpan all_handles = dst_instances->reference_handles_for_write(); + + for (const int component_index : src_components.index_range()) { + const bke::InstancesComponent &src_component = static_cast( + *src_components[component_index]); + const bke::Instances &src_instances = *src_component.get(); + const blender::float4x4 src_base_transform = src_base_transforms[component_index]; + const Array attribute_fallback_array = attribute_fallback[component_index].array; + const Span src_references = src_instances.references(); + Array handle_map(src_references.size()); + + for (const int src_handle : src_references.index_range()) { + handle_map[src_handle] = dst_instances->add_reference(src_references[src_handle]); + } + const IndexRange dst_range = offsets[component_index]; + for (const int attribute_index : all_instances_attributes.index_range()) { + bke::AttributeIDRef id = all_instances_attributes.ids[attribute_index]; + eCustomDataType type = all_instances_attributes.kinds[attribute_index].data_type; + const CPPType *cpp_type = bke::custom_data_type_to_cpp_type(type); + BLI_assert(cpp_type != nullptr); + bke::GSpanAttributeWriter write_attribute = + dst_instances->attributes_for_write().lookup_for_write_span(id); + GMutableSpan dst_span = write_attribute.span; + + if (!write_attribute) { // do not override existing attributes + continue; + } + + const void *attribute_ptr; + if (attribute_fallback_array[attribute_index] != nullptr) { + attribute_ptr = attribute_fallback_array[attribute_index]; + } + else { + attribute_ptr = cpp_type->default_value(); + } + + GVArray src_span = GVArray::ForSingle(*cpp_type, dst_range.size(), attribute_ptr); + array_utils::copy(src_span, dst_span.slice(dst_range)); + write_attribute.finish(); + } + + const Span src_handles = src_instances.reference_handles(); + array_utils::gather(handle_map.as_span(), src_handles, all_handles.slice(dst_range)); + array_utils::copy(src_instances.transforms(), all_transforms.slice(dst_range)); + + for (blender::float4x4 &transfrom : all_transforms.slice(dst_range)) { + transfrom *= src_base_transform; + } + } + + r_realized_geometry.replace_instances(dst_instances.release()); + auto &dst_component = r_realized_geometry.get_component_for_write(); + + Vector for_join_attributes; + for (bke::GeometryComponentPtr compent : src_components) { + for_join_attributes.append(compent.get()); + } + + join_attributes( + for_join_attributes, dst_component, {"position", ".reference_index", "instance_transform"}); +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Point Cloud + * \{ */ + static OrderedAttributes gather_generic_pointcloud_attributes_to_propagate( const bke::GeometrySet &in_geometry_set, const RealizeInstancesOptions &options, @@ -912,13 +1017,8 @@ static OrderedAttributes gather_generic_pointcloud_attributes_to_propagate( if (options.realize_instance_attributes) { src_component_types.append(bke::GeometryComponent::Type::Instance); } + Map attributes_to_propagate; - // in_geometry_set.gather_attributes_for_propagation(src_component_types, - // bke::GeometryComponent::Type::PointCloud, - // chosen_instances.depths, - // chosen_instances.selection, - // options.propagation_info, - // attributes_to_propagate); gather_attributes_for_propagation(in_geometry_set, src_component_types, bke::GeometryComponent::Type::PointCloud, @@ -926,6 +1026,7 @@ static OrderedAttributes gather_generic_pointcloud_attributes_to_propagate( chosen_instances.selection, options.propagation_info, attributes_to_propagate); + attributes_to_propagate.remove("position"); r_create_id = attributes_to_propagate.pop_try("id").has_value(); r_create_radii = attributes_to_propagate.pop_try("radius").has_value(); @@ -1036,98 +1137,6 @@ static void execute_realize_pointcloud_task( dst_attribute_writers); } -static void execute_instances_tasks( - const Span src_components, - Span src_base_transforms, - OrderedAttributes all_instances_attributes, - Span attribute_fallback, - bke::GeometrySet &result) -{ - BLI_assert(src_components.size() == src_base_transforms.size() && - src_components.size() == attribute_fallback.size()); - if (src_components.is_empty()) { - return; - } - - VArray::ForSpan(src_base_transforms); - Array offsets_data(src_components.size() + 1); - for (const int component_index : src_components.index_range()) { - const bke::InstancesComponent &src_component = static_cast( - *src_components[component_index]); - offsets_data[component_index] = src_component.get()->instances_num(); - } - const OffsetIndices offsets = offset_indices::accumulate_counts_to_offsets(offsets_data); - - std::unique_ptr dst_instances = std::make_unique(); - dst_instances->resize(offsets.total_size()); - - /* Prepare generic output attributes. */ - for (const int attribute_index : all_instances_attributes.index_range()) { - bke::AttrDomain domain = bke::AttrDomain::Instance; - bke::AttributeIDRef id = all_instances_attributes.ids[attribute_index]; - eCustomDataType type = all_instances_attributes.kinds[attribute_index].data_type; - blender::bke::MutableAttributeAccessor attr = dst_instances->attributes_for_write(); - attr.lookup_or_add_for_write_only_span(id, domain, type).finish(); - } - - MutableSpan all_transforms = dst_instances->transforms_for_write(); - MutableSpan all_handles = dst_instances->reference_handles_for_write(); - - for (const int component_index : src_components.index_range()) { - const auto &src_component = static_cast( - *src_components[component_index]); - const bke::Instances &src_instances = *src_component.get(); - const blender::float4x4 src_base_transform = src_base_transforms[component_index]; - const Array attribute_fallback_array = attribute_fallback[component_index].array; - - const Span src_references = src_instances.references(); - Array handle_map(src_references.size()); - for (const int src_handle : src_references.index_range()) { - handle_map[src_handle] = dst_instances->add_reference(src_references[src_handle]); - } - const IndexRange dst_range = offsets[component_index]; - for (const int attribute_index : all_instances_attributes.index_range()) { - bke::AttributeIDRef id = all_instances_attributes.ids[attribute_index]; - eCustomDataType type = all_instances_attributes.kinds[attribute_index].data_type; - - const CPPType *cpp_type = bke::custom_data_type_to_cpp_type(type); - BLI_assert(cpp_type != nullptr); - bke::GSpanAttributeWriter write_attribute = - dst_instances->attributes_for_write().lookup_for_write_span(id); - GMutableSpan dst_span = write_attribute.span; - if (!write_attribute) { // do not override existing attributes - continue; - } - - const void *attribute_ptr; // Declare a pointer to an integer - if (attribute_fallback_array[attribute_index] != nullptr) { - attribute_ptr = attribute_fallback_array[attribute_index]; - } - else { - attribute_ptr = cpp_type->default_value(); - } - GVArray src_span = GVArray::ForSingle(*cpp_type, dst_range.size(), attribute_ptr); - array_utils::copy(src_span, dst_span.slice(dst_range)); - write_attribute.finish(); - } - const Span src_handles = src_instances.reference_handles(); - array_utils::gather(handle_map.as_span(), src_handles, all_handles.slice(dst_range)); - array_utils::copy(src_instances.transforms(), all_transforms.slice(dst_range)); - for (blender::float4x4 &transfrom : all_transforms.slice(dst_range)) { - transfrom *= src_base_transform; - } - } - result.replace_instances(dst_instances.release()); - auto &dst_component = result.get_component_for_write(); - Vector for_join_attributes; - for (bke::GeometryComponentPtr compent : src_components) { - for_join_attributes.append(compent.get()); - } - - join_attributes( - for_join_attributes, dst_component, {"position", ".reference_index", "instance_transform"}); -} - static void execute_realize_pointcloud_tasks(bool keep_original_ids, const AllPointCloudsInfo &all_pointclouds_info, const Span tasks, @@ -1945,11 +1954,11 @@ static void propagate_instances_to_keep( return; } - bke::InstancesComponent &new_instances_components = - new_geometry_set.get_component_for_write(); - std::unique_ptr new_instances = std::make_unique(instances); new_instances->remove(inverse_selection, propagation_info); + + bke::InstancesComponent &new_instances_components = + new_geometry_set.get_component_for_write(); new_instances_components.replace(new_instances.release(), bke::GeometryOwnershipType::Owned); } @@ -1999,10 +2008,10 @@ bke::GeometrySet realize_instances(bke::GeometrySet geometry_set, OrderedAttributes all_instance_attributes = gather_generic_instance_attributes_to_propagate( geometry_set, options, chosen_instances); - Vector>> temporary_arrays; const bool create_id_attribute = all_pointclouds_info.create_id_attribute || all_meshes_info.create_id_attribute || all_curves_info.create_id_attribute; + Vector>> temporary_arrays; GatherTasksInfo gather_info = {all_pointclouds_info, all_meshes_info, all_curves_info, @@ -2012,11 +2021,6 @@ bke::GeometrySet realize_instances(bke::GeometrySet geometry_set, chosen_instances.depths, temporary_arrays}; - bke::GeometrySet new_geometry_set; - - const float4x4 transform = float4x4::identity(); - InstanceContext attribute_fallbacks(gather_info); - if (not_to_realize_set.has_instances()) { gather_info.instances.instances_components_to_merge.append( (not_to_realize_set.get_component_for_write()).copy()); @@ -2024,6 +2028,9 @@ bke::GeometrySet realize_instances(bke::GeometrySet geometry_set, gather_info.instances.attribute_fallback.append((gather_info.instances_attriubutes.size())); } + const float4x4 transform = float4x4::identity(); + InstanceContext attribute_fallbacks(gather_info); + gather_realize_tasks_recursive(gather_info, 0, SpecificInstancesChoice::MAX_DEPTH, @@ -2031,6 +2038,8 @@ bke::GeometrySet realize_instances(bke::GeometrySet geometry_set, transform, attribute_fallbacks); + bke::GeometrySet new_geometry_set; + execute_instances_tasks(gather_info.instances.instances_components_to_merge, gather_info.instances.instances_components_transforms, all_instance_attributes, -- 2.30.2 From a331c835f2ad090126612dfb32f3c126f391f608 Mon Sep 17 00:00:00 2001 From: David-Haver Date: Thu, 21 Mar 2024 14:22:33 +0200 Subject: [PATCH 09/10] SpecificInstancesChoice -> VariedDepthOption --- .../blender/geometry/GEO_realize_instances.hh | 6 +- .../geometry/intern/realize_instances.cc | 60 +++++++++---------- .../nodes/node_geo_realize_instances.cc | 8 +-- 3 files changed, 37 insertions(+), 37 deletions(-) diff --git a/source/blender/geometry/GEO_realize_instances.hh b/source/blender/geometry/GEO_realize_instances.hh index 090b5382473..08a0d8a6da1 100644 --- a/source/blender/geometry/GEO_realize_instances.hh +++ b/source/blender/geometry/GEO_realize_instances.hh @@ -31,7 +31,7 @@ struct RealizeInstancesOptions { /** * Allow the user to choice which instances to realize and to what depth. */ -struct SpecificInstancesChoice { +struct VariedDepthOption { /** * Selection of top-level instances to realize. */ @@ -71,10 +71,10 @@ bke::GeometrySet realize_instances(bke::GeometrySet geometry_set, * output will contain an `id` attribute as well. The output id is generated by mixing/hashing ids * of instances and of the instanced geometry data. * - * Will realize only the instaces chosen by chosen_instaces to there chosen depth. + * Will realize only the instances chosen by varied_depth_option to there chosen depth. */ bke::GeometrySet realize_instances(bke::GeometrySet geometry_set, const RealizeInstancesOptions &options, - const SpecificInstancesChoice &chosen_instaces); + const VariedDepthOption &varied_depth_option); } // namespace blender::geometry diff --git a/source/blender/geometry/intern/realize_instances.cc b/source/blender/geometry/intern/realize_instances.cc index 262e969cbb5..7679f979507 100644 --- a/source/blender/geometry/intern/realize_instances.cc +++ b/source/blender/geometry/intern/realize_instances.cc @@ -827,7 +827,7 @@ void static gather_attributes_for_propagation( attribute_foreach(re_geometry_set, component_types, 0, - SpecificInstancesChoice::MAX_DEPTH, + VariedDepthOption::MAX_DEPTH, instance_depth, selection, [&](const AttributeIDRef &attribute_id, @@ -878,7 +878,7 @@ void static gather_attributes_for_propagation( static OrderedAttributes gather_generic_instance_attributes_to_propagate( const bke::GeometrySet &in_geometry_set, const RealizeInstancesOptions &options, - const SpecificInstancesChoice &chosen_instances) + const VariedDepthOption &varied_depth_option) { Vector src_component_types; src_component_types.append(bke::GeometryComponent::Type::Instance); @@ -887,8 +887,8 @@ static OrderedAttributes gather_generic_instance_attributes_to_propagate( gather_attributes_for_propagation(in_geometry_set, src_component_types, bke::GeometryComponent::Type::Instance, - chosen_instances.depths, - chosen_instances.selection, + varied_depth_option.depths, + varied_depth_option.selection, options.propagation_info, attributes_to_propagate); attributes_to_propagate.remove("position"); @@ -1008,7 +1008,7 @@ static void execute_instances_tasks( static OrderedAttributes gather_generic_pointcloud_attributes_to_propagate( const bke::GeometrySet &in_geometry_set, const RealizeInstancesOptions &options, - const SpecificInstancesChoice &chosen_instances, + const VariedDepthOption &varied_depth_option, bool &r_create_radii, bool &r_create_id) { @@ -1022,8 +1022,8 @@ static OrderedAttributes gather_generic_pointcloud_attributes_to_propagate( gather_attributes_for_propagation(in_geometry_set, src_component_types, bke::GeometryComponent::Type::PointCloud, - chosen_instances.depths, - chosen_instances.selection, + varied_depth_option.depths, + varied_depth_option.selection, options.propagation_info, attributes_to_propagate); @@ -1055,12 +1055,12 @@ static void gather_pointclouds_to_realize(const bke::GeometrySet &geometry_set, static AllPointCloudsInfo preprocess_pointclouds(const bke::GeometrySet &geometry_set, const RealizeInstancesOptions &options, - const SpecificInstancesChoice &chosen_instances) + const VariedDepthOption &varied_depth_option) { AllPointCloudsInfo info; info.attributes = gather_generic_pointcloud_attributes_to_propagate(geometry_set, options, - chosen_instances, + varied_depth_option, info.create_radius_attribute, info.create_id_attribute); @@ -1217,7 +1217,7 @@ static void execute_realize_pointcloud_tasks(bool keep_original_ids, static OrderedAttributes gather_generic_mesh_attributes_to_propagate( const bke::GeometrySet &in_geometry_set, const RealizeInstancesOptions &options, - const SpecificInstancesChoice &chosen_instances, + const VariedDepthOption &varied_depth_option, bool &r_create_id, bool &r_create_material_index) { @@ -1231,8 +1231,8 @@ static OrderedAttributes gather_generic_mesh_attributes_to_propagate( gather_attributes_for_propagation(in_geometry_set, src_component_types, bke::GeometryComponent::Type::Mesh, - chosen_instances.depths, - chosen_instances.selection, + varied_depth_option.depths, + varied_depth_option.selection, options.propagation_info, attributes_to_propagate); attributes_to_propagate.remove("position"); @@ -1266,13 +1266,13 @@ static void gather_meshes_to_realize(const bke::GeometrySet &geometry_set, static AllMeshesInfo preprocess_meshes(const bke::GeometrySet &geometry_set, const RealizeInstancesOptions &options, - const SpecificInstancesChoice &chosen_instances) + const VariedDepthOption &varied_depth_option) { AllMeshesInfo info; info.attributes = gather_generic_mesh_attributes_to_propagate( geometry_set, options, - chosen_instances, + varied_depth_option, info.create_id_attribute, info.create_material_index_attribute); @@ -1588,7 +1588,7 @@ static void execute_realize_mesh_tasks(bool keep_original_ids, static OrderedAttributes gather_generic_curve_attributes_to_propagate( const bke::GeometrySet &in_geometry_set, const RealizeInstancesOptions &options, - const SpecificInstancesChoice &chosen_instances, + const VariedDepthOption &varied_depth_option, bool &r_create_id) { Vector src_component_types; @@ -1601,8 +1601,8 @@ static OrderedAttributes gather_generic_curve_attributes_to_propagate( gather_attributes_for_propagation(in_geometry_set, src_component_types, bke::GeometryComponent::Type::Curve, - chosen_instances.depths, - chosen_instances.selection, + varied_depth_option.depths, + varied_depth_option.selection, options.propagation_info, attributes_to_propagate); attributes_to_propagate.remove("position"); @@ -1638,11 +1638,11 @@ static void gather_curves_to_realize(const bke::GeometrySet &geometry_set, static AllCurvesInfo preprocess_curves(const bke::GeometrySet &geometry_set, const RealizeInstancesOptions &options, - const SpecificInstancesChoice &chosen_instances) + const VariedDepthOption &varied_depth_option) { AllCurvesInfo info; info.attributes = gather_generic_curve_attributes_to_propagate( - geometry_set, options, chosen_instances, info.create_id_attribute); + geometry_set, options, varied_depth_option, info.create_id_attribute); gather_curves_to_realize(geometry_set, info.order); info.realize_info.reinitialize(info.order.size()); @@ -1969,8 +1969,8 @@ bke::GeometrySet realize_instances(bke::GeometrySet geometry_set, return geometry_set; } - SpecificInstancesChoice all_instances; - all_instances.depths = VArray::ForSingle(SpecificInstancesChoice::MAX_DEPTH, + VariedDepthOption all_instances; + all_instances.depths = VArray::ForSingle(VariedDepthOption::MAX_DEPTH, geometry_set.get_instances()->instances_num()); IndexMaskMemory memory; all_instances.selection = IndexMask::from_bools( @@ -1980,7 +1980,7 @@ bke::GeometrySet realize_instances(bke::GeometrySet geometry_set, bke::GeometrySet realize_instances(bke::GeometrySet geometry_set, const RealizeInstancesOptions &options, - const SpecificInstancesChoice &chosen_instances) + const VariedDepthOption &varied_depth_option) { /* The algorithm works in three steps: * 1. Preprocess each unique geometry that is instanced (e.g. each `Mesh`). @@ -1995,18 +1995,18 @@ bke::GeometrySet realize_instances(bke::GeometrySet geometry_set, bke::GeometrySet not_to_realize_set; propagate_instances_to_keep( - geometry_set, chosen_instances.selection, not_to_realize_set, options.propagation_info); + geometry_set, varied_depth_option.selection, not_to_realize_set, options.propagation_info); if (options.keep_original_ids) { remove_id_attribute_from_instances(geometry_set); } AllPointCloudsInfo all_pointclouds_info = preprocess_pointclouds( - geometry_set, options, chosen_instances); - AllMeshesInfo all_meshes_info = preprocess_meshes(geometry_set, options, chosen_instances); - AllCurvesInfo all_curves_info = preprocess_curves(geometry_set, options, chosen_instances); + geometry_set, options, varied_depth_option); + AllMeshesInfo all_meshes_info = preprocess_meshes(geometry_set, options, varied_depth_option); + AllCurvesInfo all_curves_info = preprocess_curves(geometry_set, options, varied_depth_option); OrderedAttributes all_instance_attributes = gather_generic_instance_attributes_to_propagate( - geometry_set, options, chosen_instances); + geometry_set, options, varied_depth_option); const bool create_id_attribute = all_pointclouds_info.create_id_attribute || all_meshes_info.create_id_attribute || @@ -2017,8 +2017,8 @@ bke::GeometrySet realize_instances(bke::GeometrySet geometry_set, all_curves_info, all_instance_attributes, create_id_attribute, - chosen_instances.selection, - chosen_instances.depths, + varied_depth_option.selection, + varied_depth_option.depths, temporary_arrays}; if (not_to_realize_set.has_instances()) { @@ -2033,7 +2033,7 @@ bke::GeometrySet realize_instances(bke::GeometrySet geometry_set, gather_realize_tasks_recursive(gather_info, 0, - SpecificInstancesChoice::MAX_DEPTH, + VariedDepthOption::MAX_DEPTH, geometry_set, transform, attribute_fallbacks); diff --git a/source/blender/nodes/geometry/nodes/node_geo_realize_instances.cc b/source/blender/nodes/geometry/nodes/node_geo_realize_instances.cc index b7ae1f1863e..b52d4f0445f 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_realize_instances.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_realize_instances.cc @@ -65,15 +65,15 @@ static void node_geo_exec(GeoNodeExecParams params) evaluator.set_selection(selection_field_overrided); evaluator.evaluate(); - geometry::SpecificInstancesChoice chosen_instances; - chosen_instances.depths = evaluator.get_evaluated(evaluated_depth_index); - chosen_instances.selection = evaluator.get_evaluated_selection_as_mask(); + geometry::VariedDepthOption varied_depth_option; + varied_depth_option.depths = evaluator.get_evaluated(evaluated_depth_index); + varied_depth_option.selection = evaluator.get_evaluated_selection_as_mask(); geometry::RealizeInstancesOptions options; options.keep_original_ids = false; options.realize_instance_attributes = true; options.propagation_info = params.get_output_propagation_info("Geometry"); - geometry_set = geometry::realize_instances(geometry_set, options, chosen_instances); + geometry_set = geometry::realize_instances(geometry_set, options, varied_depth_option); params.set_output("Geometry", std::move(geometry_set)); } -- 2.30.2 From 059c73dc9fc30bd9030bee216c8e1bbc2ed3f79d Mon Sep 17 00:00:00 2001 From: David-Haver Date: Thu, 21 Mar 2024 15:53:26 +0200 Subject: [PATCH 10/10] returned std::max(value, 0) in depth_override --- .../blender/nodes/geometry/nodes/node_geo_realize_instances.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/nodes/geometry/nodes/node_geo_realize_instances.cc b/source/blender/nodes/geometry/nodes/node_geo_realize_instances.cc index b52d4f0445f..2fd19b7b9df 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_realize_instances.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_realize_instances.cc @@ -44,7 +44,7 @@ static void node_geo_exec(GeoNodeExecParams params) static auto depth_override = mf::build::SI2_SO( "depth_override", - [](int value, bool realize) { return realize ? -1 : value; }, + [](int value, bool realize) { return realize ? -1 : std::max(value, 0); }, mf::build::exec_presets::AllSpanOrSingle()); static auto selection_override = mf::build::SI2_SO( -- 2.30.2