diff options
Diffstat (limited to 'source/blender/blenkernel/intern/attribute_access.cc')
-rw-r--r-- | source/blender/blenkernel/intern/attribute_access.cc | 135 |
1 files changed, 63 insertions, 72 deletions
diff --git a/source/blender/blenkernel/intern/attribute_access.cc b/source/blender/blenkernel/intern/attribute_access.cc index 3f2c1f13337..1a4265d936b 100644 --- a/source/blender/blenkernel/intern/attribute_access.cc +++ b/source/blender/blenkernel/intern/attribute_access.cc @@ -23,6 +23,7 @@ #include "BKE_geometry_set.hh" #include "BKE_mesh.h" #include "BKE_pointcloud.h" +#include "BKE_type_conversions.hh" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" @@ -36,8 +37,6 @@ #include "CLG_log.h" -#include "NOD_type_conversions.hh" - #include "attribute_access_intern.hh" static CLG_LogRef LOG = {"bke.attribute_access"}; @@ -50,7 +49,7 @@ using blender::bke::AttributeIDRef; using blender::bke::OutputAttribute; using blender::fn::GMutableSpan; using blender::fn::GSpan; -using blender::fn::GVMutableArrayImpl_For_GMutableSpan; +using blender::fn::GVArrayImpl_For_GSpan; namespace blender::bke { @@ -183,10 +182,6 @@ static int attribute_domain_priority(const AttributeDomain domain) } } -/** - * Domains with a higher "information density" have a higher priority, in order - * to choose a domain that will not lose data through domain conversion. - */ AttributeDomain attribute_domain_highest_priority(Span<AttributeDomain> domains) { int highest_priority = INT_MIN; @@ -288,7 +283,7 @@ static void *add_generic_custom_data_layer(CustomData &custom_data, char attribute_name_c[MAX_NAME]; attribute_id.name().copy(attribute_name_c); return CustomData_add_layer_named( - &custom_data, data_type, CD_DEFAULT, nullptr, domain_size, attribute_name_c); + &custom_data, data_type, alloctype, layer_data, domain_size, attribute_name_c); } const AnonymousAttributeID &anonymous_id = attribute_id.anonymous_id(); return CustomData_add_layer_anonymous( @@ -400,7 +395,9 @@ WriteAttributeLookup BuiltinCustomDataLayerProvider::try_get_for_write( } if (data != new_data) { - custom_data_access_.update_custom_data_pointers(component); + if (custom_data_access_.update_custom_data_pointers) { + custom_data_access_.update_custom_data_pointers(component); + } data = new_data; } @@ -441,7 +438,9 @@ bool BuiltinCustomDataLayerProvider::try_delete(GeometryComponent &component) co const bool delete_success = CustomData_free_layer( custom_data, stored_type_, domain_size, layer_index); if (delete_success) { - custom_data_access_.update_custom_data_pointers(component); + if (custom_data_access_.update_custom_data_pointers) { + custom_data_access_.update_custom_data_pointers(component); + } } return delete_success; } @@ -476,7 +475,9 @@ bool BuiltinCustomDataLayerProvider::try_create(GeometryComponent &component, *custom_data, stored_type_, domain_size, initializer); } if (success) { - custom_data_access_.update_custom_data_pointers(component); + if (custom_data_access_.update_custom_data_pointers) { + custom_data_access_.update_custom_data_pointers(component); + } } return success; } @@ -644,7 +645,9 @@ WriteAttributeLookup NamedLegacyCustomDataProvider::try_get_for_write( void *data_new = CustomData_duplicate_referenced_layer_named( custom_data, stored_type_, layer.name, domain_size); if (data_old != data_new) { - custom_data_access_.update_custom_data_pointers(component); + if (custom_data_access_.update_custom_data_pointers) { + custom_data_access_.update_custom_data_pointers(component); + } } return {as_write_attribute_(layer.data, domain_size), domain_}; } @@ -666,7 +669,9 @@ bool NamedLegacyCustomDataProvider::try_delete(GeometryComponent &component, if (custom_data_layer_matches_attribute_id(layer, attribute_id)) { const int domain_size = component.attribute_domain_size(domain_); CustomData_free_layer(custom_data, stored_type_, domain_size, i); - custom_data_access_.update_custom_data_pointers(component); + if (custom_data_access_.update_custom_data_pointers) { + custom_data_access_.update_custom_data_pointers(component); + } return true; } } @@ -734,7 +739,6 @@ CustomDataAttributes &CustomDataAttributes::operator=(const CustomDataAttributes std::optional<GSpan> CustomDataAttributes::get_for_read(const AttributeIDRef &attribute_id) const { - BLI_assert(size_ != 0); for (const CustomDataLayer &layer : Span(data.layers, data.totlayer)) { if (custom_data_layer_matches_attribute_id(layer, attribute_id)) { const CPPType *cpp_type = custom_data_type_to_cpp_type((CustomDataType)layer.type); @@ -745,11 +749,6 @@ std::optional<GSpan> CustomDataAttributes::get_for_read(const AttributeIDRef &at return {}; } -/** - * Return a virtual array for a stored attribute, or a single value virtual array with the default - * value if the attribute doesn't exist. If no default value is provided, the default value for the - * type will be used. - */ GVArray CustomDataAttributes::get_for_read(const AttributeIDRef &attribute_id, const CustomDataType data_type, const void *default_value) const @@ -766,15 +765,13 @@ GVArray CustomDataAttributes::get_for_read(const AttributeIDRef &attribute_id, if (attribute->type() == *type) { return GVArray::ForSpan(*attribute); } - const blender::nodes::DataTypeConversions &conversions = - blender::nodes::get_implicit_type_conversions(); + const blender::bke::DataTypeConversions &conversions = + blender::bke::get_implicit_type_conversions(); return conversions.try_convert(GVArray::ForSpan(*attribute), *type); } std::optional<GMutableSpan> CustomDataAttributes::get_for_write(const AttributeIDRef &attribute_id) { - /* If this assert hits, it most likely means that #reallocate was not called at some point. */ - BLI_assert(size_ != 0); for (CustomDataLayer &layer : MutableSpan(data.layers, data.totlayer)) { if (custom_data_layer_matches_attribute_id(layer, attribute_id)) { const CPPType *cpp_type = custom_data_type_to_cpp_type((CustomDataType)layer.type); @@ -821,6 +818,12 @@ void CustomDataAttributes::reallocate(const int size) CustomData_realloc(&data, size); } +void CustomDataAttributes::clear() +{ + CustomData_free(&data, size_); + size_ = 0; +} + bool CustomDataAttributes::foreach_attribute(const AttributeForeachCallback callback, const AttributeDomain domain) const { @@ -1044,10 +1047,6 @@ Set<AttributeIDRef> GeometryComponent::attribute_ids() const return attributes; } -/** - * \return False if the callback explicitly returned false at any point, otherwise true, - * meaning the callback made it all the way through. - */ bool GeometryComponent::attribute_foreach(const AttributeForeachCallback callback) const { using namespace blender::bke; @@ -1112,8 +1111,8 @@ std::optional<AttributeMetaData> GeometryComponent::attribute_get_meta_data( static blender::fn::GVArray try_adapt_data_type(blender::fn::GVArray varray, const blender::fn::CPPType &to_type) { - const blender::nodes::DataTypeConversions &conversions = - blender::nodes::get_implicit_type_conversions(); + const blender::bke::DataTypeConversions &conversions = + blender::bke::get_implicit_type_conversions(); return conversions.try_convert(std::move(varray), to_type); } @@ -1178,8 +1177,8 @@ blender::bke::ReadAttributeLookup GeometryComponent::attribute_try_get_for_read( if (attribute.varray.type() == *type) { return attribute; } - const blender::nodes::DataTypeConversions &conversions = - blender::nodes::get_implicit_type_conversions(); + const blender::bke::DataTypeConversions &conversions = + blender::bke::get_implicit_type_conversions(); return {conversions.try_convert(std::move(attribute.varray), *type), attribute.domain}; } @@ -1200,8 +1199,7 @@ blender::fn::GVArray GeometryComponent::attribute_get_for_read(const AttributeID return blender::fn::GVArray::ForSingle(*type, domain_size, default_value); } -class GVMutableAttribute_For_OutputAttribute - : public blender::fn::GVMutableArrayImpl_For_GMutableSpan { +class GVMutableAttribute_For_OutputAttribute : public blender::fn::GVArrayImpl_For_GSpan { public: GeometryComponent *component; std::string attribute_name; @@ -1210,7 +1208,7 @@ class GVMutableAttribute_For_OutputAttribute GVMutableAttribute_For_OutputAttribute(GMutableSpan data, GeometryComponent &component, const AttributeIDRef &attribute_id) - : blender::fn::GVMutableArrayImpl_For_GMutableSpan(data), component(&component) + : blender::fn::GVArrayImpl_For_GSpan(data), component(&component) { if (attribute_id.is_named()) { this->attribute_name = attribute_id.name(); @@ -1300,7 +1298,7 @@ static OutputAttribute create_output_attribute(GeometryComponent &component, const CPPType *cpp_type = custom_data_type_to_cpp_type(data_type); BLI_assert(cpp_type != nullptr); - const nodes::DataTypeConversions &conversions = nodes::get_implicit_type_conversions(); + const DataTypeConversions &conversions = get_implicit_type_conversions(); if (component.attribute_is_builtin(attribute_id)) { const StringRef attribute_name = attribute_id.name(); @@ -1409,23 +1407,27 @@ OutputAttribute GeometryComponent::attribute_try_get_for_output_only( namespace blender::bke { -GVArray AttributeFieldInput::get_varray_for_context(const fn::FieldContext &context, - IndexMask UNUSED(mask), - ResourceScope &UNUSED(scope)) const +GVArray GeometryFieldInput::get_varray_for_context(const fn::FieldContext &context, + IndexMask mask, + ResourceScope &UNUSED(scope)) const { if (const GeometryComponentFieldContext *geometry_context = dynamic_cast<const GeometryComponentFieldContext *>(&context)) { const GeometryComponent &component = geometry_context->geometry_component(); const AttributeDomain domain = geometry_context->domain(); - const CustomDataType data_type = cpp_type_to_custom_data_type(*type_); - GVArray attribute = component.attribute_try_get_for_read(name_, domain, data_type); - if (attribute) { - return attribute; - } + return this->get_varray_for_context(component, domain, mask); } return {}; } +GVArray AttributeFieldInput::get_varray_for_context(const GeometryComponent &component, + const AttributeDomain domain, + IndexMask UNUSED(mask)) const +{ + const CustomDataType data_type = cpp_type_to_custom_data_type(*type_); + return component.attribute_try_get_for_read(name_, domain, data_type); +} + std::string AttributeFieldInput::socket_inspection_name() const { std::stringstream ss; @@ -1457,25 +1459,20 @@ static StringRef get_random_id_attribute_name(const AttributeDomain domain) } } -GVArray IDAttributeFieldInput::get_varray_for_context(const fn::FieldContext &context, - IndexMask mask, - ResourceScope &scope) const +GVArray IDAttributeFieldInput::get_varray_for_context(const GeometryComponent &component, + const AttributeDomain domain, + IndexMask mask) const { - if (const GeometryComponentFieldContext *geometry_context = - dynamic_cast<const GeometryComponentFieldContext *>(&context)) { - const GeometryComponent &component = geometry_context->geometry_component(); - const AttributeDomain domain = geometry_context->domain(); - const StringRef name = get_random_id_attribute_name(domain); - GVArray attribute = component.attribute_try_get_for_read(name, domain, CD_PROP_INT32); - if (attribute) { - BLI_assert(attribute.size() == component.attribute_domain_size(domain)); - return attribute; - } - /* Use the index as the fallback if no random ID attribute exists. */ - return fn::IndexFieldInput::get_index_varray(mask, scope); + const StringRef name = get_random_id_attribute_name(domain); + GVArray attribute = component.attribute_try_get_for_read(name, domain, CD_PROP_INT32); + if (attribute) { + BLI_assert(attribute.size() == component.attribute_domain_size(domain)); + return attribute; } - return {}; + + /* Use the index as the fallback if no random ID attribute exists. */ + return fn::IndexFieldInput::get_index_varray(mask); } std::string IDAttributeFieldInput::socket_inspection_name() const @@ -1495,20 +1492,12 @@ bool IDAttributeFieldInput::is_equal_to(const fn::FieldNode &other) const return dynamic_cast<const IDAttributeFieldInput *>(&other) != nullptr; } -GVArray AnonymousAttributeFieldInput::get_varray_for_context(const fn::FieldContext &context, - IndexMask UNUSED(mask), - ResourceScope &UNUSED(scope)) const +GVArray AnonymousAttributeFieldInput::get_varray_for_context(const GeometryComponent &component, + const AttributeDomain domain, + IndexMask UNUSED(mask)) const { - if (const GeometryComponentFieldContext *geometry_context = - dynamic_cast<const GeometryComponentFieldContext *>(&context)) { - const GeometryComponent &component = geometry_context->geometry_component(); - const AttributeDomain domain = geometry_context->domain(); - const CustomDataType data_type = cpp_type_to_custom_data_type(*type_); - GVArray attribute = component.attribute_try_get_for_read( - anonymous_id_.get(), domain, data_type); - return attribute; - } - return {}; + const CustomDataType data_type = cpp_type_to_custom_data_type(*type_); + return component.attribute_try_get_for_read(anonymous_id_.get(), domain, data_type); } std::string AnonymousAttributeFieldInput::socket_inspection_name() const @@ -1533,3 +1522,5 @@ bool AnonymousAttributeFieldInput::is_equal_to(const fn::FieldNode &other) const } } // namespace blender::bke + +/** \} */ |