forked from blender/blender
Realize depth code review fixes #6
@ -12,7 +12,7 @@ namespace blender::geometry {
|
|||||||
bke::GeometrySet join_geometries(Span<bke::GeometrySet> geometries,
|
bke::GeometrySet join_geometries(Span<bke::GeometrySet> geometries,
|
||||||
const bke::AnonymousAttributePropagationInfo &propagation_info);
|
const bke::AnonymousAttributePropagationInfo &propagation_info);
|
||||||
|
|
||||||
void join_attributes(Span<const bke::GeometryComponent *> src_components,
|
void join_attributes(const Span<const bke::GeometryComponent *> src_components,
|
||||||
Span<StringRef> ignored_attributes,
|
bke::GeometryComponent &r_result,
|
||||||
bke::GeometryComponent &r_result);
|
const Span<StringRef> ignored_attributes = {});
|
||||||
} // namespace blender::geometry
|
} // namespace blender::geometry
|
||||||
|
@ -74,8 +74,8 @@ static void fill_new_attribute(const Span<const GeometryComponent *> src_compone
|
|||||||
}
|
}
|
||||||
|
|
||||||
void join_attributes(const Span<const GeometryComponent *> src_components,
|
void join_attributes(const Span<const GeometryComponent *> src_components,
|
||||||
const Span<StringRef> ignored_attributes,
|
GeometryComponent &result,
|
||||||
GeometryComponent &r_result)
|
const Span<StringRef> ignored_attributes)
|
||||||
{
|
{
|
||||||
const Map<AttributeIDRef, AttributeMetaData> info = get_final_attribute_info(src_components,
|
const Map<AttributeIDRef, AttributeMetaData> info = get_final_attribute_info(src_components,
|
||||||
ignored_attributes);
|
ignored_attributes);
|
||||||
@ -85,7 +85,7 @@ void join_attributes(const Span<const GeometryComponent *> src_components,
|
|||||||
const AttributeMetaData &meta_data = item.value;
|
const AttributeMetaData &meta_data = item.value;
|
||||||
|
|
||||||
bke::GSpanAttributeWriter write_attribute =
|
bke::GSpanAttributeWriter write_attribute =
|
||||||
r_result.attributes_for_write()->lookup_or_add_for_write_only_span(
|
result.attributes_for_write()->lookup_or_add_for_write_only_span(
|
||||||
attribute_id, meta_data.domain, meta_data.data_type);
|
attribute_id, meta_data.domain, meta_data.data_type);
|
||||||
if (!write_attribute) {
|
if (!write_attribute) {
|
||||||
continue;
|
continue;
|
||||||
@ -97,7 +97,7 @@ void join_attributes(const Span<const GeometryComponent *> src_components,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void join_instances(const Span<const GeometryComponent *> src_components,
|
static void join_instances(const Span<const GeometryComponent *> src_components,
|
||||||
GeometrySet &r_result)
|
GeometrySet &result)
|
||||||
{
|
{
|
||||||
Array<int> offsets_data(src_components.size() + 1);
|
Array<int> offsets_data(src_components.size() + 1);
|
||||||
for (const int i : src_components.index_range()) {
|
for (const int i : src_components.index_range()) {
|
||||||
@ -127,9 +127,9 @@ static void join_instances(const Span<const GeometryComponent *> src_components,
|
|||||||
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
r_result.replace_instances(dst_instances.release());
|
result.replace_instances(dst_instances.release());
|
||||||
auto &dst_component = r_result.get_component_for_write<bke::InstancesComponent>();
|
auto &dst_component = result.get_component_for_write<bke::InstancesComponent>();
|
||||||
join_attributes(src_components, {".reference_index"}, dst_component);
|
join_attributes(src_components, dst_component, {".reference_index"});
|
||||||
}
|
}
|
||||||
|
|
||||||
static void join_volumes(const Span<const GeometryComponent *> /*src_components*/,
|
static void join_volumes(const Span<const GeometryComponent *> /*src_components*/,
|
||||||
@ -142,7 +142,7 @@ static void join_volumes(const Span<const GeometryComponent *> /*src_components*
|
|||||||
static void join_component_type(const bke::GeometryComponent::Type component_type,
|
static void join_component_type(const bke::GeometryComponent::Type component_type,
|
||||||
const Span<GeometrySet> src_geometry_sets,
|
const Span<GeometrySet> src_geometry_sets,
|
||||||
const bke::AnonymousAttributePropagationInfo &propagation_info,
|
const bke::AnonymousAttributePropagationInfo &propagation_info,
|
||||||
GeometrySet &r_result)
|
GeometrySet &result)
|
||||||
{
|
{
|
||||||
Vector<const GeometryComponent *> components;
|
Vector<const GeometryComponent *> components;
|
||||||
for (const GeometrySet &geometry_set : src_geometry_sets) {
|
for (const GeometrySet &geometry_set : src_geometry_sets) {
|
||||||
@ -156,16 +156,16 @@ static void join_component_type(const bke::GeometryComponent::Type component_typ
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (components.size() == 1) {
|
if (components.size() == 1) {
|
||||||
r_result.add(*components.first());
|
result.add(*components.first());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (component_type) {
|
switch (component_type) {
|
||||||
case bke::GeometryComponent::Type::Instance:
|
case bke::GeometryComponent::Type::Instance:
|
||||||
join_instances(components, r_result);
|
join_instances(components, result);
|
||||||
return;
|
return;
|
||||||
case bke::GeometryComponent::Type::Volume:
|
case bke::GeometryComponent::Type::Volume:
|
||||||
join_volumes(components, r_result);
|
join_volumes(components, result);
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -185,10 +185,9 @@ 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;
|
||||||
|
|
||||||
GeometrySet joined_components = realize_instances(
|
GeometrySet joined_components = realize_instances(
|
||||||
GeometrySet::from_instances(instances.release()), options);
|
GeometrySet::from_instances(instances.release()), options);
|
||||||
r_result.add(joined_components.get_component_for_write(component_type));
|
result.add(joined_components.get_component_for_write(component_type));
|
||||||
}
|
}
|
||||||
|
|
||||||
GeometrySet join_geometries(const Span<GeometrySet> geometries,
|
GeometrySet join_geometries(const Span<GeometrySet> geometries,
|
||||||
|
@ -168,7 +168,7 @@ struct RealizeCurveTask {
|
|||||||
CurvesElementStartIndices start_indices;
|
CurvesElementStartIndices start_indices;
|
||||||
|
|
||||||
const RealizeCurveInfo *curve_info;
|
const RealizeCurveInfo *curve_info;
|
||||||
/* Transformation applied to the position of control points and handles. */
|
/** Transformation applied to the position of control points and handles. */
|
||||||
float4x4 transform;
|
float4x4 transform;
|
||||||
AttributeFallbacksArray attribute_fallbacks;
|
AttributeFallbacksArray attribute_fallbacks;
|
||||||
/** Only used when the output contains an output attribute. */
|
/** Only used when the output contains an output attribute. */
|
||||||
@ -220,7 +220,7 @@ struct AllCurvesInfo {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct AllInstancesInfo {
|
struct AllInstancesInfo {
|
||||||
/** store an array of void pointer to attributes for each component. */
|
/** Stores 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. */
|
||||||
Vector<bke::GeometryComponentPtr> instances_components_to_merge;
|
Vector<bke::GeometryComponentPtr> instances_components_to_merge;
|
||||||
@ -500,36 +500,35 @@ static Vector<std::pair<int, GSpan>> prepare_attribute_fallbacks(
|
|||||||
return attributes_to_override;
|
return attributes_to_override;
|
||||||
}
|
}
|
||||||
|
|
||||||
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()) {
|
switch (reference.type()) {
|
||||||
case InstanceReference::Type::Object: {
|
case InstanceReference::Type::Object: {
|
||||||
const Object &object = reference.object();
|
const Object &object = reference.object();
|
||||||
r_geometry_set = bke::object_get_evaluated_geometry_set(object);
|
const bke::GeometrySet geometry_set = bke::object_get_evaluated_geometry_set(object);
|
||||||
|
return geometry_set;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case InstanceReference::Type::Collection: {
|
case InstanceReference::Type::Collection: {
|
||||||
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());
|
||||||
r_geometry_set.replace_instances(instances.release());
|
bke::GeometrySet geometry_set;
|
||||||
|
geometry_set.replace_instances(instances.release());
|
||||||
|
return geometry_set;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case InstanceReference::Type::GeometrySet: {
|
case InstanceReference::Type::GeometrySet: {
|
||||||
r_geometry_set = reference.geometry_set();
|
const bke::GeometrySet geometry_set = reference.geometry_set();
|
||||||
|
return geometry_set;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case InstanceReference::Type::None: {
|
case InstanceReference::Type::None: {
|
||||||
r_geometry_set = bke::GeometrySet(); // Return an empty GeometrySet for None type
|
return {}; // Return an empty GeometrySet for None type
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
r_geometry_set = bke::GeometrySet();
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return r_geometry_set;
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -543,8 +542,7 @@ static void foreach_geometry_in_reference(
|
|||||||
FunctionRef<void(const bke::GeometrySet &geometry_set, const float4x4 &transform, uint32_t id)>
|
FunctionRef<void(const bke::GeometrySet &geometry_set, const float4x4 &transform, uint32_t id)>
|
||||||
fn)
|
fn)
|
||||||
{
|
{
|
||||||
bke::GeometrySet geometry_set;
|
bke::GeometrySet geometry_set = geometry_set_from_reference(reference);
|
||||||
geometry_set_from_reference(reference, geometry_set);
|
|
||||||
fn(geometry_set, base_transform, id);
|
fn(geometry_set, base_transform, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -585,7 +583,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[i] : 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];
|
||||||
@ -765,7 +763,7 @@ static bool attribute_foreach(const bke::GeometrySet &geometry_set,
|
|||||||
const bke::GeometrySet::AttributeForeachCallback callback)
|
const bke::GeometrySet::AttributeForeachCallback callback)
|
||||||
{
|
{
|
||||||
|
|
||||||
/*Initialize flag to track if child instances have the specified components.*/
|
/* Initialize flag to track if child instances have the specified components.*/
|
||||||
bool child_has_component = true;
|
bool child_has_component = true;
|
||||||
|
|
||||||
if (geometry_set.has_instances()) {
|
if (geometry_set.has_instances()) {
|
||||||
@ -778,10 +776,9 @@ static bool attribute_foreach(const bke::GeometrySet &geometry_set,
|
|||||||
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 = (0 == current_depth) ? instance_depth[i] : depth_target;
|
const int depth_target_tmp = (0 == current_depth) ? instance_depth[i] : depth_target;
|
||||||
bke::GeometrySet instance_geometry_set;
|
bke::GeometrySet instance_geometry_set = geometry_set_from_reference(
|
||||||
geometry_set_from_reference(instances.references()[instances.reference_handles()[i]],
|
instances.references()[instances.reference_handles()[i]]);
|
||||||
instance_geometry_set);
|
/* Process child instances with a recursive call.*/
|
||||||
/*Process child instances with a recursive call.*/
|
|
||||||
if (current_depth != depth_target_tmp) {
|
if (current_depth != depth_target_tmp) {
|
||||||
child_has_component = child_has_component | attribute_foreach(instance_geometry_set,
|
child_has_component = child_has_component | attribute_foreach(instance_geometry_set,
|
||||||
component_types,
|
component_types,
|
||||||
@ -794,17 +791,17 @@ static bool attribute_foreach(const bke::GeometrySet &geometry_set,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*Flag to track if any relevant attributes were found.*/
|
/* Flag to track if any relevant attributes were found.*/
|
||||||
bool is_relevant = false;
|
bool is_relevant = false;
|
||||||
|
|
||||||
for (const bke::GeometryComponent::Type component_type : component_types) {
|
for (const bke::GeometryComponent::Type component_type : component_types) {
|
||||||
if (geometry_set.has(component_type)) {
|
if (geometry_set.has(component_type)) {
|
||||||
/*Check if the current instance components is the main one*/
|
/* Check if the current instance components is the main one*/
|
||||||
const bool is_special_instance = (bke::GeometryComponent::Type::Instance ==
|
const bool is_special_instance = (bke::GeometryComponent::Type::Instance ==
|
||||||
component_type) &&
|
component_type) &&
|
||||||
(component_types.size() > 1);
|
(component_types.size() > 1);
|
||||||
if (!is_special_instance || child_has_component) {
|
if (!is_special_instance || child_has_component) {
|
||||||
/*Process attributes for the current component.*/
|
/* Process attributes for the current component.*/
|
||||||
const bke::GeometryComponent &component = *geometry_set.get_component(component_type);
|
const bke::GeometryComponent &component = *geometry_set.get_component(component_type);
|
||||||
const std::optional<bke::AttributeAccessor> attributes = component.attributes();
|
const std::optional<bke::AttributeAccessor> attributes = component.attributes();
|
||||||
if (attributes.has_value()) {
|
if (attributes.has_value()) {
|
||||||
@ -828,7 +825,7 @@ static bool attribute_foreach(const bke::GeometrySet &geometry_set,
|
|||||||
* Specialized for Specialized attribute_foreach to get:
|
* Specialized for Specialized attribute_foreach to get:
|
||||||
* current_depth, depth_target, instance_depth and selection.
|
* current_depth, depth_target, instance_depth and selection.
|
||||||
*/
|
*/
|
||||||
void static gather_attributes_for_propagation(
|
static void gather_attributes_for_propagation(
|
||||||
bke::GeometrySet re_geometry_set,
|
bke::GeometrySet re_geometry_set,
|
||||||
const Span<bke::GeometryComponent::Type> component_types,
|
const Span<bke::GeometryComponent::Type> component_types,
|
||||||
const bke::GeometryComponent::Type dst_component_type,
|
const bke::GeometryComponent::Type dst_component_type,
|
||||||
@ -945,13 +942,14 @@ static void execute_instances_tasks(
|
|||||||
std::unique_ptr<bke::Instances> dst_instances = std::make_unique<bke::Instances>();
|
std::unique_ptr<bke::Instances> dst_instances = std::make_unique<bke::Instances>();
|
||||||
dst_instances->resize(offsets.total_size());
|
dst_instances->resize(offsets.total_size());
|
||||||
|
|
||||||
/* Prepare generic output attributes. */
|
/* Makes sure generic output attributes exists. */
|
||||||
for (const int attribute_index : all_instances_attributes.index_range()) {
|
for (const int attribute_index : all_instances_attributes.index_range()) {
|
||||||
bke::AttrDomain domain = bke::AttrDomain::Instance;
|
bke::AttrDomain domain = bke::AttrDomain::Instance;
|
||||||
bke::AttributeIDRef id = all_instances_attributes.ids[attribute_index];
|
bke::AttributeIDRef id = all_instances_attributes.ids[attribute_index];
|
||||||
eCustomDataType type = all_instances_attributes.kinds[attribute_index].data_type;
|
eCustomDataType type = all_instances_attributes.kinds[attribute_index].data_type;
|
||||||
blender::bke::MutableAttributeAccessor attr = dst_instances->attributes_for_write();
|
dst_instances->attributes_for_write()
|
||||||
attr.lookup_or_add_for_write_only_span(id, domain, type).finish();
|
.lookup_or_add_for_write_only_span(id, domain, type)
|
||||||
|
.finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
MutableSpan<float4x4> all_transforms = dst_instances->transforms_for_write();
|
MutableSpan<float4x4> all_transforms = dst_instances->transforms_for_write();
|
||||||
@ -1000,8 +998,8 @@ static void execute_instances_tasks(
|
|||||||
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 &transform : all_transforms.slice(dst_range)) {
|
||||||
transfrom *= src_base_transform;
|
transform = src_base_transform * transform;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1014,7 +1012,7 @@ static void execute_instances_tasks(
|
|||||||
}
|
}
|
||||||
|
|
||||||
join_attributes(
|
join_attributes(
|
||||||
for_join_attributes, {"position", ".reference_index", "instance_transform"}, dst_component);
|
for_join_attributes, dst_component, {"position", ".reference_index", "instance_transform"});
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \} */
|
/** \} */
|
||||||
|
@ -23,7 +23,9 @@ static void node_declare(NodeDeclarationBuilder &b)
|
|||||||
b.add_input<decl::Bool>("Realize All")
|
b.add_input<decl::Bool>("Realize All")
|
||||||
.default_value(true)
|
.default_value(true)
|
||||||
.field_on_all()
|
.field_on_all()
|
||||||
.description("Determine wether to realize nested instances completly");
|
.description(
|
||||||
|
"Realize all levels of nested instances for a top-level instances. Overrides the value "
|
||||||
|
"of the Depth input");
|
||||||
b.add_input<decl::Int>("Depth").default_value(0).min(0).field_on_all().description(
|
b.add_input<decl::Int>("Depth").default_value(0).min(0).field_on_all().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();
|
||||||
|
Loading…
Reference in New Issue
Block a user