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:
parent
0f1e93e78a
commit
b020173984
|
@ -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]) {
|
||||
|
|
Loading…
Reference in New Issue