forked from blender/blender
davidhaver-WIP-realize-depth #3
@ -236,9 +236,12 @@ struct GeometrySet {
|
|||||||
const AttributeMetaData &meta_data,
|
const AttributeMetaData &meta_data,
|
||||||
const GeometryComponent &component)>;
|
const GeometryComponent &component)>;
|
||||||
|
|
||||||
void attribute_foreach(Span<GeometryComponent::Type> component_types,
|
bool attribute_foreach(Span<GeometryComponent::Type> component_types,
|
||||||
bool include_instances,
|
bool include_instances,
|
||||||
|
const int current_depth,
|
||||||
|
const int depth_target,
|
||||||
const VArray<int> instance_depth,
|
const VArray<int> instance_depth,
|
||||||
|
const IndexMask selection,
|
||||||
AttributeForeachCallback callback) const;
|
AttributeForeachCallback callback) const;
|
||||||
|
|
||||||
void attribute_foreach(Span<GeometryComponent::Type> component_types,
|
void attribute_foreach(Span<GeometryComponent::Type> component_types,
|
||||||
@ -250,7 +253,7 @@ struct GeometrySet {
|
|||||||
MutableAttributeAccessor dst_attributes,
|
MutableAttributeAccessor dst_attributes,
|
||||||
const AnonymousAttributePropagationInfo &propagation_info);
|
const AnonymousAttributePropagationInfo &propagation_info);
|
||||||
|
|
||||||
void gather_attributes_for_propagation(Span<GeometryComponent::Type> component_types, //old variation.
|
void gather_attributes_for_propagation(Span<GeometryComponent::Type> component_types,
|
||||||
GeometryComponent::Type dst_component_type,
|
GeometryComponent::Type dst_component_type,
|
||||||
bool include_instances,
|
bool include_instances,
|
||||||
const AnonymousAttributePropagationInfo &propagation_info,
|
const AnonymousAttributePropagationInfo &propagation_info,
|
||||||
@ -260,6 +263,7 @@ struct GeometrySet {
|
|||||||
GeometryComponent::Type dst_component_type,
|
GeometryComponent::Type dst_component_type,
|
||||||
bool include_instances,
|
bool include_instances,
|
||||||
const VArray<int> instance_depth,
|
const VArray<int> instance_depth,
|
||||||
|
const IndexMask selection,
|
||||||
const AnonymousAttributePropagationInfo &propagation_info,
|
const AnonymousAttributePropagationInfo &propagation_info,
|
||||||
Map<AttributeIDRef, AttributeKind> &r_attributes) const;
|
Map<AttributeIDRef, AttributeKind> &r_attributes) const;
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
#include "BKE_attribute.hh"
|
#include "BKE_attribute.hh"
|
||||||
#include "BKE_curves.hh"
|
#include "BKE_curves.hh"
|
||||||
|
#include "BKE_collection.h"
|
||||||
#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"
|
||||||
@ -573,40 +574,88 @@ GreasePencil *GeometrySet::get_grease_pencil_for_write()
|
|||||||
return component == nullptr ? nullptr : component->get_for_write();
|
return component == nullptr ? nullptr : component->get_for_write();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GeometrySet::attribute_foreach(const Span<GeometryComponent::Type> component_types,
|
bool GeometrySet::attribute_foreach(const Span<GeometryComponent::Type> component_types,
|
||||||
const bool include_instances,
|
const bool include_instances,
|
||||||
|
const int current_depth,
|
||||||
|
const int depth_target,
|
||||||
const VArray<int> instance_depth,
|
const VArray<int> instance_depth,
|
||||||
|
const IndexMask selection,
|
||||||
const AttributeForeachCallback callback) const
|
const AttributeForeachCallback callback) const
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Iterate over attributes of a geometric set and its instances.
|
||||||
|
* Parameters:
|
||||||
|
* - component_types: Types of components to consider.
|
||||||
|
* - include_instances: Flag indicating whether to include instances.
|
||||||
|
* - current_depth: Current depth in the hierarchy.
|
||||||
|
* - depth_target: Target depth for attribute processing.
|
||||||
|
* - instance_depth: Depth information for instances.
|
||||||
|
* - selection: Index mask for selection.
|
||||||
|
* - callback: Callback function for attribute processing.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Initialize flag to track if child instances have the specified components.
|
||||||
|
bool is_child_has_component = true;
|
||||||
|
|
||||||
|
// Process instances if required and instances are available.
|
||||||
|
if (include_instances && this->has_instances()) {
|
||||||
|
is_child_has_component = false;
|
||||||
|
|
||||||
|
// Iterate over instances based on the selection index mask.
|
||||||
|
const Instances &instances = *this->get_instances();
|
||||||
|
// ensure objects and collection are included.
|
||||||
|
Instances ensure_instances = instances;
|
||||||
|
ensure_instances.ensure_geometry_instances();
|
||||||
|
const IndexMask indices = (current_depth == 0) ? selection : IndexMask(IndexRange(ensure_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;
|
||||||
|
bke::InstanceReference reference = ensure_instances.references()[ensure_instances.reference_handles()[i]];
|
||||||
|
|
||||||
|
// Process child instances with a recursive call.
|
||||||
|
if (reference.type() == InstanceReference::Type::GeometrySet) {
|
||||||
|
bke::GeometrySet instance_geometry_set = reference.geometry_set();
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Flag to track if any relevant attributes were found.
|
||||||
|
bool is_relevant = false;
|
||||||
|
|
||||||
|
// Iterate over specified component types.
|
||||||
for (const GeometryComponent::Type component_type : component_types) {
|
for (const GeometryComponent::Type component_type : component_types) {
|
||||||
|
// Skip if the component type is not present.
|
||||||
if (!this->has(component_type)) {
|
if (!this->has(component_type)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check for a special instance condition.
|
||||||
|
const bool is_special_instance = (component_type == GeometryComponent::Type::Instance) && (component_types.size() > 1);
|
||||||
|
if (is_special_instance && !is_child_has_component) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process attributes for the current component.
|
||||||
const GeometryComponent &component = *this->get_component(component_type);
|
const GeometryComponent &component = *this->get_component(component_type);
|
||||||
const std::optional<AttributeAccessor> attributes = component.attributes();
|
const std::optional<AttributeAccessor> attributes = component.attributes();
|
||||||
if (attributes.has_value()) {
|
if (attributes.has_value()) {
|
||||||
|
// Invoke callback for each attribute.
|
||||||
attributes->for_all(
|
attributes->for_all(
|
||||||
[&](const AttributeIDRef &attribute_id, const AttributeMetaData &meta_data) {
|
[&](const AttributeIDRef &attributeId, const AttributeMetaData &metaData) {
|
||||||
callback(attribute_id, meta_data, component);
|
callback(attributeId, metaData, component);
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Set the flag indicating relevant attributes were found.
|
||||||
|
is_relevant = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (include_instances && this->has_instances()) {
|
|
||||||
const Instances &instances = *this->get_instances();
|
|
||||||
|
|
||||||
// instances.foreach_referenced_geometry([&](const GeometrySet &instance_geometry_set) {
|
// Return whether any relevant attributes were found.
|
||||||
// });
|
return is_relevant;
|
||||||
BLI_assert(instances.instances_num() == instance_depth.size());
|
|
||||||
size_t index = 0;
|
|
||||||
instances.foreach_referenced_geometry([&](const GeometrySet &instance_geometry_set) {
|
|
||||||
if (instance_depth[index] > 0){
|
|
||||||
const VArray<int> intsnace_depth_tmp = VArray<int>::ForSingle(instance_depth[index]-1, instances.instances_num());
|
|
||||||
instance_geometry_set.attribute_foreach(component_types, include_instances, intsnace_depth_tmp, callback);
|
|
||||||
}
|
|
||||||
index ++;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GeometrySet::attribute_foreach(const Span<GeometryComponent::Type> component_types,
|
void GeometrySet::attribute_foreach(const Span<GeometryComponent::Type> component_types,
|
||||||
@ -719,6 +768,7 @@ void GeometrySet::gather_attributes_for_propagation(
|
|||||||
const GeometryComponent::Type dst_component_type,
|
const GeometryComponent::Type dst_component_type,
|
||||||
bool include_instances,
|
bool include_instances,
|
||||||
const VArray<int> instance_depth,
|
const VArray<int> instance_depth,
|
||||||
|
const IndexMask selection,
|
||||||
const AnonymousAttributePropagationInfo &propagation_info,
|
const AnonymousAttributePropagationInfo &propagation_info,
|
||||||
Map<AttributeIDRef, AttributeKind> &r_attributes) const
|
Map<AttributeIDRef, AttributeKind> &r_attributes) const
|
||||||
{
|
{
|
||||||
@ -728,7 +778,10 @@ void GeometrySet::gather_attributes_for_propagation(
|
|||||||
this->attribute_foreach(
|
this->attribute_foreach(
|
||||||
component_types,
|
component_types,
|
||||||
include_instances,
|
include_instances,
|
||||||
|
0,
|
||||||
|
-1,
|
||||||
instance_depth,
|
instance_depth,
|
||||||
|
selection,
|
||||||
[&](const AttributeIDRef &attribute_id,
|
[&](const AttributeIDRef &attribute_id,
|
||||||
const AttributeMetaData &meta_data,
|
const AttributeMetaData &meta_data,
|
||||||
const GeometryComponent &component) {
|
const GeometryComponent &component) {
|
||||||
|
@ -552,7 +552,7 @@ static void gather_realize_tasks_for_instances(GatherTasksInfo &gather_info,
|
|||||||
const int i = indices[mask_index];
|
const int i = indices[mask_index];
|
||||||
|
|
||||||
/* If at top level, retrieve depth from gather_info, else continue with target_depth. */
|
/* If at top level, retrieve depth from gather_info, else continue with target_depth. */
|
||||||
const int depth_target = current_depth == 0 ? gather_info.depths[mask_index] : target_depth;
|
const int depth_target = current_depth == 0 ? gather_info.depths[mask_index] : target_depth;
|
||||||
const int handle = handles[i];
|
const int handle = handles[i];
|
||||||
const float4x4 &transform = transforms[i];
|
const float4x4 &transform = transforms[i];
|
||||||
const InstanceReference &reference = references[handle];
|
const InstanceReference &reference = references[handle];
|
||||||
@ -732,6 +732,7 @@ static OrderedAttributes gather_generic_instance_attributes_to_propagate(
|
|||||||
bke::GeometryComponent::Type::Instance,
|
bke::GeometryComponent::Type::Instance,
|
||||||
true,
|
true,
|
||||||
options.depths,
|
options.depths,
|
||||||
|
options.selection,
|
||||||
options.propagation_info,
|
options.propagation_info,
|
||||||
attributes_to_propagate);
|
attributes_to_propagate);
|
||||||
attributes_to_propagate.remove("position");
|
attributes_to_propagate.remove("position");
|
||||||
@ -756,12 +757,12 @@ static OrderedAttributes gather_generic_pointcloud_attributes_to_propagate(
|
|||||||
if (options.realize_instance_attributes) {
|
if (options.realize_instance_attributes) {
|
||||||
src_component_types.append(bke::GeometryComponent::Type::Instance);
|
src_component_types.append(bke::GeometryComponent::Type::Instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<AttributeIDRef, AttributeKind> attributes_to_propagate;
|
Map<AttributeIDRef, AttributeKind> attributes_to_propagate;
|
||||||
in_geometry_set.gather_attributes_for_propagation(src_component_types,
|
in_geometry_set.gather_attributes_for_propagation(src_component_types,
|
||||||
bke::GeometryComponent::Type::PointCloud,
|
bke::GeometryComponent::Type::PointCloud,
|
||||||
true,
|
true,
|
||||||
options.depths,
|
options.depths,
|
||||||
|
options.selection,
|
||||||
options.propagation_info,
|
options.propagation_info,
|
||||||
attributes_to_propagate);
|
attributes_to_propagate);
|
||||||
attributes_to_propagate.remove("position");
|
attributes_to_propagate.remove("position");
|
||||||
@ -941,7 +942,6 @@ static void execute_instances_tasks(const Span<const bke::GeometryComponent *> s
|
|||||||
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;
|
||||||
}
|
}
|
||||||
@ -1046,6 +1046,7 @@ static OrderedAttributes gather_generic_mesh_attributes_to_propagate(
|
|||||||
bke::GeometryComponent::Type::Mesh,
|
bke::GeometryComponent::Type::Mesh,
|
||||||
true,
|
true,
|
||||||
options.depths,
|
options.depths,
|
||||||
|
options.selection,
|
||||||
options.propagation_info,
|
options.propagation_info,
|
||||||
attributes_to_propagate);
|
attributes_to_propagate);
|
||||||
attributes_to_propagate.remove("position");
|
attributes_to_propagate.remove("position");
|
||||||
@ -1394,6 +1395,7 @@ static OrderedAttributes gather_generic_curve_attributes_to_propagate(
|
|||||||
bke::GeometryComponent::Type::Curve,
|
bke::GeometryComponent::Type::Curve,
|
||||||
true,
|
true,
|
||||||
options.depths,
|
options.depths,
|
||||||
|
options.selection,
|
||||||
options.propagation_info,
|
options.propagation_info,
|
||||||
attributes_to_propagate);
|
attributes_to_propagate);
|
||||||
attributes_to_propagate.remove("position");
|
attributes_to_propagate.remove("position");
|
||||||
@ -1777,8 +1779,8 @@ bke::GeometrySet realize_instances(bke::GeometrySet geometry_set,
|
|||||||
AllPointCloudsInfo all_pointclouds_info = preprocess_pointclouds(geometry_set, options);
|
AllPointCloudsInfo all_pointclouds_info = preprocess_pointclouds(geometry_set, options);
|
||||||
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 a = true;
|
bool tmp = true;
|
||||||
OrderedAttributes all_instance_attributes = gather_generic_instance_attributes_to_propagate(geometry_set, options, a);
|
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 ||
|
||||||
@ -1802,8 +1804,7 @@ bke::GeometrySet realize_instances(bke::GeometrySet geometry_set,
|
|||||||
gather_info.instances.instances_components_to_merge.append(
|
gather_info.instances.instances_components_to_merge.append(
|
||||||
&temp_geometry_set.get_component_for_write<bke::InstancesComponent>());
|
&temp_geometry_set.get_component_for_write<bke::InstancesComponent>());
|
||||||
gather_info.instances.instances_components_transforms.append(float4x4::identity());
|
gather_info.instances.instances_components_transforms.append(float4x4::identity());
|
||||||
const void *null_ptr = nullptr;
|
gather_info.instances.attribute_fallback.append((gather_info.instances_attriubutes.size()));
|
||||||
gather_info.instances.attribute_fallback.append((null_ptr, 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, -1, geometry_set, transform, attribute_fallbacks);
|
||||||
|
@ -21,6 +21,10 @@ static void node_declare(NodeDeclarationBuilder &b)
|
|||||||
.hide_value()
|
.hide_value()
|
||||||
.supports_field()
|
.supports_field()
|
||||||
.description(("Which top-level instances to realize"));
|
.description(("Which top-level instances to realize"));
|
||||||
|
b.add_input<decl::Bool>("Realize All")
|
||||||
|
.default_value(true)
|
||||||
|
.supports_field()
|
||||||
|
.description(("Determine wether to realize nested instances completly"));
|
||||||
b.add_input<decl::Int>("Depth")
|
b.add_input<decl::Int>("Depth")
|
||||||
.default_value(99)
|
.default_value(99)
|
||||||
.min(0)
|
.min(0)
|
||||||
@ -39,13 +43,28 @@ static void node_geo_exec(GeoNodeExecParams params)
|
|||||||
}
|
}
|
||||||
GeometryComponentEditData::remember_deformed_positions_if_necessary(geometry_set);
|
GeometryComponentEditData::remember_deformed_positions_if_necessary(geometry_set);
|
||||||
Field<bool> selection_field = params.extract_input<Field<bool>>("Selection");
|
Field<bool> selection_field = params.extract_input<Field<bool>>("Selection");
|
||||||
|
Field<bool> realize_all_filed = params.extract_input<Field<bool>>("Realize All");
|
||||||
Field<int> depth_field = params.extract_input<Field<int>>("Depth");
|
Field<int> depth_field = params.extract_input<Field<int>>("Depth");
|
||||||
|
|
||||||
|
static auto depth_override = mf::build::SI2_SO<int, bool, int>(
|
||||||
|
"depth_override",
|
||||||
|
[](int value, bool realize) { return realize ? -1 : std::max(value , 0); },
|
||||||
|
mf::build::exec_presets::AllSpanOrSingle());
|
||||||
|
|
||||||
|
static auto selction_override = mf::build::SI2_SO<int, bool, bool>(
|
||||||
|
"selction_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::Instances &instances = *geometry_set.get_instances();
|
||||||
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()};
|
||||||
evaluator.set_selection(selection_field);
|
|
||||||
evaluator.add(depth_field);
|
Field<int> depth_field_overrided(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.set_selection(selection_field_overrided);
|
||||||
evaluator.evaluate();
|
evaluator.evaluate();
|
||||||
const VArray<int> depths = evaluator.get_evaluated<int>(0);
|
const VArray<int> depths = evaluator.get_evaluated<int>(0);
|
||||||
const IndexMask selection = evaluator.get_evaluated_selection_as_mask();
|
const IndexMask selection = evaluator.get_evaluated_selection_as_mask();
|
||||||
@ -56,7 +75,6 @@ static void node_geo_exec(GeoNodeExecParams params)
|
|||||||
options.propagation_info = params.get_output_propagation_info("Geometry");
|
options.propagation_info = params.get_output_propagation_info("Geometry");
|
||||||
options.depths = depths;
|
options.depths = depths;
|
||||||
options.selection = selection;
|
options.selection = selection;
|
||||||
|
|
||||||
geometry_set = geometry::realize_instances(geometry_set, options);
|
geometry_set = geometry::realize_instances(geometry_set, options);
|
||||||
params.set_output("Geometry", std::move(geometry_set));
|
params.set_output("Geometry", std::move(geometry_set));
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user