Geometry Nodes: avoid data copy in store named attribute node
This commit is contained in:
parent
120a17a45a
commit
fd5e5dac89
|
@ -91,18 +91,34 @@ static void try_capture_field_on_geometry(GeometryComponent &component,
|
|||
const int domain_size = component.attribute_domain_size(domain);
|
||||
const IndexMask mask{IndexMask(domain_size)};
|
||||
|
||||
const CustomDataType data_type = bke::cpp_type_to_custom_data_type(field.cpp_type());
|
||||
const CPPType &type = field.cpp_type();
|
||||
const CustomDataType data_type = bke::cpp_type_to_custom_data_type(type);
|
||||
|
||||
/* Could avoid allocating a new buffer if:
|
||||
* - We are writing to an attribute that exists already.
|
||||
* - The field does not depend on that attribute (we can't easily check for that yet). */
|
||||
void *buffer = MEM_mallocN(type.size() * domain_size, __func__);
|
||||
|
||||
/* Don't use #add_with_destination because the field might depend on an attribute
|
||||
* with that name, and changing it as part of evaluation might affect the result. */
|
||||
fn::FieldEvaluator evaluator{field_context, &mask};
|
||||
evaluator.add(field);
|
||||
evaluator.add_with_destination(field, GMutableSpan{type, buffer, domain_size});
|
||||
evaluator.evaluate();
|
||||
const GVArray &result = evaluator.get_evaluated(0);
|
||||
OutputAttribute attribute = component.attribute_try_get_for_output_only(name, domain, data_type);
|
||||
if (attribute) {
|
||||
result.materialize(attribute.as_span().data());
|
||||
attribute.save();
|
||||
|
||||
component.attribute_try_delete(name);
|
||||
if (component.attribute_exists(name)) {
|
||||
WriteAttributeLookup write_attribute = component.attribute_try_get_for_write(name);
|
||||
if (write_attribute && write_attribute.domain == domain &&
|
||||
write_attribute.varray.type() == type) {
|
||||
write_attribute.varray.set_all(buffer);
|
||||
write_attribute.tag_modified_fn();
|
||||
}
|
||||
else {
|
||||
/* Cannot change type of built-in attribute. */
|
||||
}
|
||||
type.destruct_n(buffer, domain_size);
|
||||
MEM_freeN(buffer);
|
||||
}
|
||||
else {
|
||||
component.attribute_try_create(name, domain, data_type, AttributeInitMove{buffer});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue