davidhaver-WIP-realize-depth #3

Closed
David-Haver wants to merge 65 commits from David-Haver/blender-old:davidhaver-WIP-realize-depth into WIP-realize-depth

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
6 changed files with 98 additions and 83 deletions
Showing only changes of commit e3e234702e - Show all commits

View File

@ -9,8 +9,8 @@
#include "BLT_translation.h" #include "BLT_translation.h"
#include "BKE_attribute.hh" #include "BKE_attribute.hh"
#include "BKE_curves.hh"
#include "BKE_collection.h" #include "BKE_collection.h"
#include "BKE_curves.hh"
#include "BKE_geometry_set.hh" #include "BKE_geometry_set.hh"
#include "BKE_geometry_set_instances.hh" #include "BKE_geometry_set_instances.hh"
#include "BKE_grease_pencil.hh" #include "BKE_grease_pencil.hh"
@ -606,17 +606,26 @@ bool GeometrySet::attribute_foreach(const Span<GeometryComponent::Type> componen
// ensure objects and collection are included. // ensure objects and collection are included.
Instances ensure_instances = instances; Instances ensure_instances = instances;
ensure_instances.ensure_geometry_instances(); ensure_instances.ensure_geometry_instances();
const IndexMask indices = (current_depth == 0) ? selection : IndexMask(IndexRange(ensure_instances.instances_num())); const IndexMask indices = (current_depth == 0) ?
selection :
IndexMask(IndexRange(ensure_instances.instances_num()));
for (const int index : indices.index_range()) { for (const int index : indices.index_range()) {
const int i = indices[index]; const int i = indices[index];
const int depth_target_tmp = (current_depth == 0) ? instance_depth[i] : depth_target; const int depth_target_tmp = (current_depth == 0) ? instance_depth[i] : depth_target;
bke::InstanceReference reference = ensure_instances.references()[ensure_instances.reference_handles()[i]]; bke::InstanceReference reference =
ensure_instances.references()[ensure_instances.reference_handles()[i]];
// Process child instances with a recursive call. // Process child instances with a recursive call.
if (reference.type() == InstanceReference::Type::GeometrySet) { if (reference.type() == InstanceReference::Type::GeometrySet) {
bke::GeometrySet instance_geometry_set = reference.geometry_set(); bke::GeometrySet instance_geometry_set = reference.geometry_set();
if (current_depth != depth_target_tmp) { if (current_depth != depth_target_tmp) {
is_child_has_component = instance_geometry_set.attribute_foreach(component_types, include_instances, current_depth + 1, depth_target_tmp, instance_depth, selection, callback); is_child_has_component = instance_geometry_set.attribute_foreach(component_types,
include_instances,
current_depth + 1,
depth_target_tmp,
instance_depth,
selection,
callback);
} }
} }
} }
@ -633,7 +642,8 @@ bool GeometrySet::attribute_foreach(const Span<GeometryComponent::Type> componen
} }
// Check for a special instance condition. // Check for a special instance condition.
const bool is_special_instance = (component_type == GeometryComponent::Type::Instance) && (component_types.size() > 1); const bool is_special_instance = (component_type == GeometryComponent::Type::Instance) &&
(component_types.size() > 1);
if (is_special_instance && !is_child_has_component) { if (is_special_instance && !is_child_has_component) {
continue; continue;
} }

View File

@ -3,9 +3,9 @@
* SPDX-License-Identifier: GPL-2.0-or-later */ * SPDX-License-Identifier: GPL-2.0-or-later */
#pragma once #pragma once
#include "BLI_math_matrix_types.hh"
#include "BKE_anonymous_attribute_id.hh" #include "BKE_anonymous_attribute_id.hh"
#include "BKE_geometry_set.hh" #include "BKE_geometry_set.hh"
#include "BLI_math_matrix_types.hh"
namespace blender::geometry { namespace blender::geometry {
@ -15,4 +15,4 @@ bke::GeometrySet join_geometries(Span<bke::GeometrySet> geometries,
void join_attributes(const Span<const bke::GeometryComponent *> src_components, void join_attributes(const Span<const bke::GeometryComponent *> src_components,
bke::GeometryComponent &result, bke::GeometryComponent &result,
const Span<StringRef> ignored_attributes); const Span<StringRef> ignored_attributes);
} } // namespace blender::geometry

View File

@ -32,7 +32,6 @@ struct RealizeInstancesOptions {
*/ */
VArray<int> depths; VArray<int> depths;
bke::AnonymousAttributePropagationInfo propagation_info; bke::AnonymousAttributePropagationInfo propagation_info;
}; };

View File

@ -185,9 +185,10 @@ static void join_component_type(const bke::GeometryComponent::Type component_typ
options.keep_original_ids = true; options.keep_original_ids = true;
options.realize_instance_attributes = false; options.realize_instance_attributes = false;
options.propagation_info = propagation_info; options.propagation_info = propagation_info;
options.depths = VArray<int>::ForSingle( 99, instances.get()->instances_num()); options.depths = VArray<int>::ForSingle(99, instances.get()->instances_num());
IndexMaskMemory memory; IndexMaskMemory memory;
options.selection = IndexMask::from_bools(VArray<bool>::ForSingle(true, instances.get()->instances_num()), memory); options.selection = IndexMask::from_bools(
VArray<bool>::ForSingle(true, instances.get()->instances_num()), memory);
GeometrySet joined_components = realize_instances( GeometrySet joined_components = realize_instances(
GeometrySet::from_instances(instances.release()), options); GeometrySet::from_instances(instances.release()), options);
result.add(joined_components.get_component_for_write(component_type)); result.add(joined_components.get_component_for_write(component_type));

View File

@ -2,9 +2,9 @@
* *
* SPDX-License-Identifier: GPL-2.0-or-later */ * SPDX-License-Identifier: GPL-2.0-or-later */
#include "BKE_geometry_set.hh"
#include "GEO_join_geometries.hh" #include "GEO_join_geometries.hh"
#include "GEO_realize_instances.hh" #include "GEO_realize_instances.hh"
#include "BKE_geometry_set.hh"
#include "DNA_collection_types.h" #include "DNA_collection_types.h"
#include "DNA_layer_types.h" #include "DNA_layer_types.h"
@ -232,7 +232,7 @@ struct AllCurvesInfo {
bool create_nurbs_weight_attribute = false; bool create_nurbs_weight_attribute = false;
bool create_custom_normal_attribute = false; bool create_custom_normal_attribute = false;
}; };
struct AllInstancesInfo{ struct AllInstancesInfo {
/** store an array of void pointer to attributes for each component. */ /** store an array of void pointer to attributes for each component. */
Vector<AttributeFallbacksArray> attribute_fallback; Vector<AttributeFallbacksArray> attribute_fallback;
/** Instance components to merge for output geometry. */ /** Instance components to merge for output geometry. */
@ -281,7 +281,6 @@ struct GatherTasksInfo {
*/ */
Vector<std::unique_ptr<GArray<>>> &r_temporary_arrays; Vector<std::unique_ptr<GArray<>>> &r_temporary_arrays;
AllInstancesInfo instances; AllInstancesInfo instances;
/** All gathered tasks. */ /** All gathered tasks. */
@ -314,7 +313,8 @@ struct InstanceContext {
} }
}; };
static void realize_collections(Collection *collection, bke::Instances* instances){ static void realize_collections(Collection *collection, bke::Instances *instances)
{
Vector<Collection *> children_collections; Vector<Collection *> children_collections;
LISTBASE_FOREACH (CollectionChild *, collection_child, &collection->children) { LISTBASE_FOREACH (CollectionChild *, collection_child, &collection->children) {
children_collections.append(collection_child->collection); children_collections.append(collection_child->collection);
@ -529,7 +529,8 @@ static void foreach_geometry_in_reference(
Collection *collection_ptr = &reference.collection(); Collection *collection_ptr = &reference.collection();
std::unique_ptr<bke::Instances> instances = std::make_unique<bke::Instances>(); std::unique_ptr<bke::Instances> instances = std::make_unique<bke::Instances>();
realize_collections(collection_ptr, instances.get()); realize_collections(collection_ptr, instances.get());
const bke::GeometrySet colleciton_geometry = bke::GeometrySet::from_instances(instances.release()); const bke::GeometrySet colleciton_geometry = bke::GeometrySet::from_instances(
instances.release());
/* important as otherwise the Instances pointer would be deleted with the GeomtrySet*/ /* important as otherwise the Instances pointer would be deleted with the GeomtrySet*/
colleciton_geometry.get_component(bke::GeometryComponent::Type::Instance)->add_user(); colleciton_geometry.get_component(bke::GeometryComponent::Type::Instance)->add_user();
fn(colleciton_geometry, base_transform, id); fn(colleciton_geometry, base_transform, id);
@ -576,9 +577,9 @@ static void gather_realize_tasks_for_instances(GatherTasksInfo &gather_info,
Vector<std::pair<int, GSpan>> instance_attributes_to_override = prepare_attribute_fallbacks( Vector<std::pair<int, GSpan>> instance_attributes_to_override = prepare_attribute_fallbacks(
gather_info, instances, gather_info.instances_attriubutes); gather_info, instances, gather_info.instances_attriubutes);
/* If at top level, get instance indices from selection field, else use all instances. */ /* If at top level, get instance indices from selection field, else use all instances. */
const IndexMask indices = current_depth == 0 ? gather_info.selection :IndexMask(IndexRange(instances.instances_num())); const IndexMask indices = current_depth == 0 ? gather_info.selection :
IndexMask(IndexRange(instances.instances_num()));
for (const int mask_index : indices.index_range()) { for (const int mask_index : indices.index_range()) {
const int i = indices[mask_index]; const int i = indices[mask_index];
@ -703,8 +704,9 @@ static void gather_realize_tasks_recursive(GatherTasksInfo &gather_info,
gather_info.instances.instances_components_to_merge.append(component); gather_info.instances.instances_components_to_merge.append(component);
gather_info.instances.instances_components_transforms.append(base_transform); gather_info.instances.instances_components_transforms.append(base_transform);
} }
else{ else {
const auto &instances_component = *static_cast<const bke::InstancesComponent *>(component); const auto &instances_component = *static_cast<const bke::InstancesComponent *>(
component);
const Instances *instances = instances_component.get(); const Instances *instances = instances_component.get();
if (instances != nullptr && instances->instances_num() > 0) { if (instances != nullptr && instances->instances_num() > 0) {
gather_realize_tasks_for_instances(gather_info, gather_realize_tasks_for_instances(gather_info,
@ -901,21 +903,24 @@ static void execute_realize_pointcloud_task(
}, },
dst_attribute_writers); dst_attribute_writers);
} }
static void execute_instances_tasks(const Span<const bke::GeometryComponent *> src_components, static void execute_instances_tasks(
const Span<const bke::GeometryComponent *> src_components,
Span<blender::float4x4> src_base_transforms, Span<blender::float4x4> src_base_transforms,
OrderedAttributes all_instances_attributes, OrderedAttributes all_instances_attributes,
Span<blender::geometry::AttributeFallbacksArray> attribute_fallback, Span<blender::geometry::AttributeFallbacksArray> attribute_fallback,
bke::GeometrySet &result) bke::GeometrySet &result)
{ {
BLI_assert(src_components.size() == src_base_transforms.size() && src_components.size() == attribute_fallback.size()); BLI_assert(src_components.size() == src_base_transforms.size() &&
if (src_components.is_empty()){ src_components.size() == attribute_fallback.size());
if (src_components.is_empty()) {
return; return;
} }
VArray<blender::float4x4>::ForSpan(src_base_transforms); VArray<blender::float4x4>::ForSpan(src_base_transforms);
Array<int> offsets_data(src_components.size() + 1); Array<int> offsets_data(src_components.size() + 1);
for (const int component_index : src_components.index_range()) { for (const int component_index : src_components.index_range()) {
const auto &src_component = static_cast<const bke::InstancesComponent &>(*src_components[component_index]); const auto &src_component = static_cast<const bke::InstancesComponent &>(
*src_components[component_index]);
offsets_data[component_index] = src_component.get()->instances_num(); offsets_data[component_index] = src_component.get()->instances_num();
} }
const OffsetIndices offsets = offset_indices::accumulate_counts_to_offsets(offsets_data); const OffsetIndices offsets = offset_indices::accumulate_counts_to_offsets(offsets_data);
@ -936,7 +941,8 @@ static void execute_instances_tasks(const Span<const bke::GeometryComponent *> s
MutableSpan<int> all_handles = dst_instances->reference_handles(); MutableSpan<int> all_handles = dst_instances->reference_handles();
for (const int component_index : src_components.index_range()) { for (const int component_index : src_components.index_range()) {
const auto &src_component = static_cast<const bke::InstancesComponent &>(*src_components[component_index]); const auto &src_component = static_cast<const bke::InstancesComponent &>(
*src_components[component_index]);
const bke::Instances &src_instances = *src_component.get(); const bke::Instances &src_instances = *src_component.get();
const blender::float4x4 src_base_transform = src_base_transforms[component_index]; const blender::float4x4 src_base_transform = src_base_transforms[component_index];
const Array<const void *> attribute_fallback_array = attribute_fallback[component_index].array; const Array<const void *> attribute_fallback_array = attribute_fallback[component_index].array;
@ -953,30 +959,30 @@ static void execute_instances_tasks(const Span<const bke::GeometryComponent *> s
const CPPType *cpp_type = bke::custom_data_type_to_cpp_type(type); const CPPType *cpp_type = bke::custom_data_type_to_cpp_type(type);
BLI_assert(cpp_type != nullptr); BLI_assert(cpp_type != nullptr);
bke::GSpanAttributeWriter write_attribute = dst_instances->attributes_for_write().lookup_for_write_span(id); bke::GSpanAttributeWriter write_attribute =
dst_instances->attributes_for_write().lookup_for_write_span(id);
GMutableSpan dst_span = write_attribute.span; GMutableSpan dst_span = write_attribute.span;
if (!write_attribute) { // do not override existing attributes if (!write_attribute) { // do not override existing attributes
continue; continue;
} }
const void *attribute_ptr; // Declare a pointer to an integer const void *attribute_ptr; // Declare a pointer to an integer
if (attribute_fallback_array[attribute_index] != nullptr){ if (attribute_fallback_array[attribute_index] != nullptr) {
attribute_ptr = attribute_fallback_array[attribute_index]; attribute_ptr = attribute_fallback_array[attribute_index];
} }
else{ else {
attribute_ptr = cpp_type->default_value(); attribute_ptr = cpp_type->default_value();
} }
GVArray src_span = GVArray::ForSingle(*cpp_type, dst_range.size() , attribute_ptr); GVArray src_span = GVArray::ForSingle(*cpp_type, dst_range.size(), attribute_ptr);
array_utils::copy(src_span, dst_span.slice(dst_range)); array_utils::copy(src_span, dst_span.slice(dst_range));
write_attribute.finish(); write_attribute.finish();
} }
const Span<int> src_handles = src_instances.reference_handles(); const Span<int> src_handles = src_instances.reference_handles();
array_utils::gather(handle_map.as_span(), src_handles, all_handles.slice(dst_range)); 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)); array_utils::copy(src_instances.transforms(), all_transforms.slice(dst_range));
for (blender::float4x4& transfrom : all_transforms.slice(dst_range)){ for (blender::float4x4 &transfrom : all_transforms.slice(dst_range)) {
transfrom *= src_base_transform; transfrom *= src_base_transform;
} }
} }
result.replace_instances(dst_instances.release()); result.replace_instances(dst_instances.release());
auto &dst_component = result.get_component_for_write<bke::InstancesComponent>(); auto &dst_component = result.get_component_for_write<bke::InstancesComponent>();
@ -1826,7 +1832,8 @@ bke::GeometrySet realize_instances(bke::GeometrySet geometry_set,
AllMeshesInfo all_meshes_info = preprocess_meshes(geometry_set, options); AllMeshesInfo all_meshes_info = preprocess_meshes(geometry_set, options);
AllCurvesInfo all_curves_info = preprocess_curves(geometry_set, options); AllCurvesInfo all_curves_info = preprocess_curves(geometry_set, options);
bool tmp = true; bool tmp = true;
OrderedAttributes all_instance_attributes = gather_generic_instance_attributes_to_propagate(geometry_set, options, tmp); OrderedAttributes all_instance_attributes = gather_generic_instance_attributes_to_propagate(
geometry_set, options, tmp);
Vector<std::unique_ptr<GArray<>>> temporary_arrays; Vector<std::unique_ptr<GArray<>>> temporary_arrays;
const bool create_id_attribute = all_pointclouds_info.create_id_attribute || const bool create_id_attribute = all_pointclouds_info.create_id_attribute ||

View File

@ -25,11 +25,7 @@ static void node_declare(NodeDeclarationBuilder &b)
.default_value(true) .default_value(true)
.supports_field() .supports_field()
.description(("Determine wether to realize nested instances completly")); .description(("Determine wether to realize nested instances completly"));
b.add_input<decl::Int>("Depth") b.add_input<decl::Int>("Depth").default_value(99).min(0).supports_field().description(
.default_value(99)
.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<decl::Geometry>("Geometry").propagate_all(); b.add_output<decl::Geometry>("Geometry").propagate_all();
} }
@ -48,7 +44,7 @@ static void node_geo_exec(GeoNodeExecParams params)
static auto depth_override = mf::build::SI2_SO<int, bool, int>( static auto depth_override = mf::build::SI2_SO<int, bool, int>(
"depth_override", "depth_override",
[](int value, bool realize) { return realize ? -1 : std::max(value , 0); }, [](int value, bool realize) { return realize ? -1 : std::max(value, 0); },
mf::build::exec_presets::AllSpanOrSingle()); mf::build::exec_presets::AllSpanOrSingle());
static auto selction_override = mf::build::SI2_SO<int, bool, bool>( static auto selction_override = mf::build::SI2_SO<int, bool, bool>(
@ -60,8 +56,10 @@ static void node_geo_exec(GeoNodeExecParams params)
const bke::InstancesFieldContext field_context{instances}; const bke::InstancesFieldContext field_context{instances};
fn::FieldEvaluator evaluator{field_context, instances.instances_num()}; fn::FieldEvaluator evaluator{field_context, instances.instances_num()};
Field<int> depth_field_overrided(FieldOperation::Create(depth_override, {depth_field, realize_all_filed})); Field<int> depth_field_overrided(
Field<bool> selection_field_overrided(FieldOperation::Create(selction_override, {depth_field_overrided, selection_field})); FieldOperation::Create(depth_override, {depth_field, realize_all_filed}));
Field<bool> selection_field_overrided(
FieldOperation::Create(selction_override, {depth_field_overrided, selection_field}));
evaluator.add(depth_field_overrided); evaluator.add(depth_field_overrided);
evaluator.set_selection(selection_field_overrided); evaluator.set_selection(selection_field_overrided);