Fix #114120: support output attributes on instanced geometry in geometry nodes modifier

Pull Request: https://projects.blender.org/blender/blender/pulls/119016
This commit is contained in:
Jacques Lucke 2024-03-10 13:02:56 +01:00
parent 0f1e93e78a
commit b020173984
1 changed files with 14 additions and 5 deletions

View File

@ -631,7 +631,7 @@ static MultiValueMap<bke::AttrDomain, OutputAttributeInfo> find_output_attribute
const int index = socket->index();
bke::SocketValueVariant &value_variant = *output_values[index].get<bke::SocketValueVariant>();
const fn::GField field = value_variant.extract<fn::GField>();
const fn::GField field = value_variant.get<fn::GField>();
const bNodeTreeInterfaceSocket *interface_socket = tree.interface_outputs()[index];
const bke::AttrDomain domain = bke::AttrDomain(interface_socket->attribute_domain);
@ -649,7 +649,8 @@ static MultiValueMap<bke::AttrDomain, OutputAttributeInfo> find_output_attribute
*/
static Vector<OutputAttributeToStore> compute_attributes_to_store(
const bke::GeometrySet &geometry,
const MultiValueMap<bke::AttrDomain, OutputAttributeInfo> &outputs_by_domain)
const MultiValueMap<bke::AttrDomain, OutputAttributeInfo> &outputs_by_domain,
const bool do_instances)
{
Vector<OutputAttributeToStore> attributes_to_store;
for (const auto component_type : {bke::GeometryComponent::Type::Mesh,
@ -660,6 +661,9 @@ static Vector<OutputAttributeToStore> compute_attributes_to_store(
if (!geometry.has(component_type)) {
continue;
}
if (!do_instances && component_type == bke::GeometryComponent::Type::Instance) {
continue;
}
const bke::GeometryComponent &component = *geometry.get_component(component_type);
const bke::AttributeAccessor attributes = *component.attributes();
for (const auto item : outputs_by_domain.items()) {
@ -735,14 +739,15 @@ static void store_computed_output_attributes(
static void store_output_attributes(bke::GeometrySet &geometry,
const bNodeTree &tree,
const IDProperty *properties,
Span<GMutablePointer> output_values)
Span<GMutablePointer> output_values,
const bool do_instances)
{
/* All new attribute values have to be computed before the geometry is actually changed. This is
* necessary because some fields might depend on attributes that are overwritten. */
MultiValueMap<bke::AttrDomain, OutputAttributeInfo> outputs_by_domain =
find_output_attributes_to_store(tree, properties, output_values);
Vector<OutputAttributeToStore> attributes_to_store = compute_attributes_to_store(
geometry, outputs_by_domain);
geometry, outputs_by_domain, do_instances);
store_computed_output_attributes(geometry, attributes_to_store);
}
@ -839,7 +844,11 @@ bke::GeometrySet execute_geometry_nodes_on_geometry(const bNodeTree &btree,
}
bke::GeometrySet output_geometry = std::move(*param_outputs[0].get<bke::GeometrySet>());
store_output_attributes(output_geometry, btree, properties, param_outputs);
output_geometry.modify_geometry_sets([&](bke::GeometrySet &geometry) {
/* Instance attributes should only be created for the top-level geometry. */
const bool do_instances = &output_geometry == &geometry;
store_output_attributes(geometry, btree, properties, param_outputs, do_instances);
});
for (const int i : IndexRange(num_outputs)) {
if (param_set_outputs[i]) {