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.
Showing only changes of commit f421076caa - Show all commits

View File

@ -501,6 +501,33 @@ static Vector<std::pair<int, GSpan>> prepare_attribute_fallbacks(
* Calls #fn for every geometry in the given #InstanceReference. Also passes on the transformation * Calls #fn for every geometry in the given #InstanceReference. Also passes on the transformation
* that is applied to every instance. * that is applied to every instance.
*/ */
static bke::GeometrySet geometry_set_from_reference(const InstanceReference &reference)
{
switch (reference.type()) {
case InstanceReference::Type::Object: {
const Object &object = reference.object();
return bke::object_get_evaluated_geometry_set(object);
}
case InstanceReference::Type::Collection: {
Collection *collection_ptr = &reference.collection();
std::unique_ptr<bke::Instances> instances = std::make_unique<bke::Instances>();
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;
}
case InstanceReference::Type::GeometrySet: {
return reference.geometry_set();
}
case InstanceReference::Type::None: {
return bke::GeometrySet(); // Return an empty GeometrySet for None type
}
default: {
return bke::GeometrySet();
}
}
}
static void foreach_geometry_in_reference( static void foreach_geometry_in_reference(
const InstanceReference &reference, const InstanceReference &reference,
const float4x4 &base_transform, const float4x4 &base_transform,
@ -508,33 +535,8 @@ 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)
{ {
switch (reference.type()) { const bke::GeometrySet geometry_set = geometry_set_from_reference(reference);
case InstanceReference::Type::Object: { fn(geometry_set, base_transform, id);
const Object &object = reference.object();
const bke::GeometrySet object_geometry = bke::object_get_evaluated_geometry_set(object);
fn(object_geometry, base_transform, id);
break;
}
case InstanceReference::Type::Collection: {
Collection *collection_ptr = &reference.collection();
std::unique_ptr<bke::Instances> instances = std::make_unique<bke::Instances>();
realize_collections(collection_ptr, instances.get());
const bke::GeometrySet colleciton_geometry = bke::GeometrySet::from_instances(
instances.release());
/* important as otherwise the Instances pointer would be deleted with the GeomtrySet*/
colleciton_geometry.get_component(bke::GeometryComponent::Type::Instance)->add_user();
fn(colleciton_geometry, base_transform, id);
break;
}
case InstanceReference::Type::GeometrySet: {
const bke::GeometrySet &instance_geometry_set = reference.geometry_set();
fn(instance_geometry_set, base_transform, id);
break;
}
case InstanceReference::Type::None: {
break;
}
}
} }
static void gather_realize_tasks_for_instances(GatherTasksInfo &gather_info, static void gather_realize_tasks_for_instances(GatherTasksInfo &gather_info,
@ -736,13 +738,13 @@ static void gather_realize_tasks_recursive(GatherTasksInfo &gather_info,
} }
} }
bool attribute_foreach(const bke::GeometrySet& geometry_set, bool static attribute_foreach(const bke::GeometrySet &geometry_set,
const Span<bke::GeometryComponent::Type> component_types, const Span<bke::GeometryComponent::Type> component_types,
const int current_depth, const int current_depth,
const int depth_target, const int depth_target,
const VArray<int> instance_depth, const VArray<int> instance_depth,
const IndexMask selection, const IndexMask selection,
const bke::GeometrySet::AttributeForeachCallback callback) const bke::GeometrySet::AttributeForeachCallback callback)
{ {
/** /**
* This function iterates through a set of geometries, applying a callback to each attribute of * This function iterates through a set of geometries, applying a callback to each attribute of
@ -763,29 +765,24 @@ bool attribute_foreach(const bke::GeometrySet& geometry_set,
const Instances &instances = *geometry_set.get_instances(); const Instances &instances = *geometry_set.get_instances();
/*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();
const IndexMask indices = (current_depth == 0) ? const IndexMask indices = (current_depth == 0) ?
selection : selection :
IndexMask(IndexRange(ensure_instances.instances_num())); IndexMask(IndexRange(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 = bke::GeometrySet instance_geometry_set = geometry_set_from_reference(
ensure_instances.references()[ensure_instances.reference_handles()[i]]; instances.references()[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 (current_depth != depth_target_tmp) {
bke::GeometrySet instance_geometry_set = reference.geometry_set(); is_child_has_component = attribute_foreach(instance_geometry_set,
if (current_depth != depth_target_tmp) { component_types,
is_child_has_component = attribute_foreach(instance_geometry_set, current_depth + 1,
component_types, depth_target_tmp,
current_depth + 1, instance_depth,
depth_target_tmp, selection,
instance_depth, callback) ||
selection, is_child_has_component;
callback) ||
is_child_has_component;
}
} }
} }
} }
@ -821,8 +818,7 @@ bool attribute_foreach(const bke::GeometrySet& geometry_set,
return is_relevant; return is_relevant;
} }
void static gather_attributes_for_propagation(
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,
@ -833,51 +829,52 @@ void gather_attributes_for_propagation(
{ {
/* Only needed right now to check if an attribute is built-in on this component type. /* Only needed right now to check if an attribute is built-in on this component type.
* TODO: Get rid of the dummy component. */ * TODO: Get rid of the dummy component. */
const bke::GeometryComponentPtr dummy_component = bke::GeometryComponent::create(dst_component_type); const bke::GeometryComponentPtr dummy_component = bke::GeometryComponent::create(
attribute_foreach( dst_component_type);
re_geometry_set, attribute_foreach(re_geometry_set,
component_types, component_types,
0, 0,
-1, -1,
instance_depth, instance_depth,
selection, selection,
[&](const AttributeIDRef &attribute_id, [&](const AttributeIDRef &attribute_id,
const AttributeMetaData &meta_data, const AttributeMetaData &meta_data,
const bke::GeometryComponent &component) { const bke::GeometryComponent &component) {
if (component.attributes()->is_builtin(attribute_id)) { if (component.attributes()->is_builtin(attribute_id)) {
if (!dummy_component->attributes()->is_builtin(attribute_id)) { if (!dummy_component->attributes()->is_builtin(attribute_id)) {
/* Don't propagate built-in attributes that are not built-in on the destination /* Don't propagate built-in attributes that are not built-in on the
* component. */ * destination component. */
return; return;
} }
} }
if (meta_data.data_type == CD_PROP_STRING) { if (meta_data.data_type == CD_PROP_STRING) {
/* Propagating string attributes is not supported yet. */ /* Propagating string attributes is not supported yet. */
return; return;
} }
if (attribute_id.is_anonymous() && if (attribute_id.is_anonymous() &&
!propagation_info.propagate(attribute_id.anonymous_id())) { !propagation_info.propagate(attribute_id.anonymous_id())) {
return; return;
} }
AttrDomain domain = meta_data.domain; AttrDomain domain = meta_data.domain;
if (dst_component_type != bke::GeometryComponent::Type::Instance && if (dst_component_type != bke::GeometryComponent::Type::Instance &&
domain == AttrDomain::Instance) { domain == AttrDomain::Instance)
domain = AttrDomain::Point; {
} domain = AttrDomain::Point;
}
auto add_info = [&](AttributeKind *attribute_kind) { auto add_info = [&](AttributeKind *attribute_kind) {
attribute_kind->domain = domain; attribute_kind->domain = domain;
attribute_kind->data_type = meta_data.data_type; attribute_kind->data_type = meta_data.data_type;
}; };
auto modify_info = [&](AttributeKind *attribute_kind) { auto modify_info = [&](AttributeKind *attribute_kind) {
attribute_kind->domain = bke::attribute_domain_highest_priority( attribute_kind->domain = bke::attribute_domain_highest_priority(
{attribute_kind->domain, domain}); {attribute_kind->domain, domain});
attribute_kind->data_type = bke::attribute_data_type_highest_complexity( attribute_kind->data_type = bke::attribute_data_type_highest_complexity(
{attribute_kind->data_type, meta_data.data_type}); {attribute_kind->data_type, meta_data.data_type});
}; };
r_attributes.add_or_modify(attribute_id, add_info, modify_info); r_attributes.add_or_modify(attribute_id, add_info, modify_info);
}); });
} }
/** \} */ /** \} */
@ -1125,7 +1122,8 @@ static void execute_instances_tasks(
} }
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>();
join_attributes(src_components, dst_component, {"position", ".reference_index", "instance_transform"}); join_attributes(
src_components, dst_component, {"position", ".reference_index", "instance_transform"});
} }
static void execute_realize_pointcloud_tasks(const RealizeInstancesOptions &options, static void execute_realize_pointcloud_tasks(const RealizeInstancesOptions &options,