From ed151b09c988f72be7783bd188707327d586255c Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Mon, 17 Apr 2023 23:46:12 -0400 Subject: [PATCH 1/4] WIP: Attributes: Integrate implicit sharing with the attribute API Add the ability to retrieve implicit sharing info directly from the C++ attribute API, which simplifies memory usage and performance optimizations making use of it. This commit uses the additions to the API to avoid copies in a few places: - The "rest_position" attribute in the mesh modifier stack - Instance on Points node - Instances to points node - Mesh to points node - Points to vertices node Many files are affected because in order to include the new information in the API's returned data, I had to switch a bunch of types from `VArray` to `AttributeReader`. This generally makes sense anyway, since it allows retrieving the domain, which wasn't possible before in some cases. I overloaded the `*` deference operator for some syntactic sugar to avoid the (very ugly) `.varray` that would be necessary otherwise. TODO: - [ ] Fix tests - [ ] cycles_pointcloud_cpu (Failed) - [ ] geo_node_attributes_test_attribute_curve_map (Failed) - [ ] geo_node_attributes_test_attribute_map_range (Failed) - [ ] geo_node_attributes_test_attribute_proximity (Failed) - [ ] geo_node_curves_test_handle_type_selection (Failed) - [ ] geo_node_curves_test_spline_parameter (Failed) - [ ] geo_node_geometry_test_delete_geometry (SEGFAULT) - [ ] geo_node_geometry_test_realize_instances_materials (Subprocess aborted) - [ ] geo_node_instance_test_instance_on_points (Subprocess aborted) - [ ] geo_node_instance_test_instance_to_points (Subprocess aborted) - [ ] geo_node_instance_test_instance_transforms (Subprocess aborted) - [ ] geo_node_mesh_test_set_position_normals_update (Subprocess aborted) - [ ] geo_node_points_test_point_instance (Subprocess aborted) - [ ] geo_node_utilities_test_accumulate_field_column_grid (Subprocess aborted) - [ ] geo_node_vector_test_vector_map_range (Subprocess aborted) --- source/blender/blenkernel/BKE_attribute.hh | 88 ++++++++++----- .../blender/blenkernel/intern/DerivedMesh.cc | 11 +- .../blenkernel/intern/attribute_access.cc | 104 ++++++++++-------- .../intern/attribute_access_intern.hh | 24 +--- source/blender/blenkernel/intern/bvhutils.cc | 2 +- .../intern/curve_to_mesh_convert.cc | 6 +- source/blender/blenkernel/intern/fluid.cc | 5 +- .../intern/geometry_component_curves.cc | 30 ----- .../intern/geometry_component_instances.cc | 8 +- .../intern/geometry_component_mesh.cc | 69 +++--------- .../intern/geometry_component_pointcloud.cc | 8 +- .../blenkernel/intern/geometry_fields.cc | 8 +- .../blenkernel/intern/gpencil_geom_legacy.cc | 4 +- source/blender/blenkernel/intern/mesh.cc | 10 +- .../blenkernel/intern/mesh_boolean_convert.cc | 2 +- .../blender/blenkernel/intern/mesh_convert.cc | 2 +- .../blenkernel/intern/mesh_evaluate.cc | 16 +-- .../blenkernel/intern/mesh_legacy_convert.cc | 14 +-- .../blenkernel/intern/mesh_remesh_voxel.cc | 4 +- .../blender/blenkernel/intern/mesh_tangent.cc | 2 +- .../blender/blenkernel/intern/object_dupli.cc | 2 +- source/blender/blenkernel/intern/paint.cc | 2 +- .../blender/blenkernel/intern/pbvh_pixels.cc | 2 +- .../blender/blenkernel/intern/pointcloud.cc | 4 +- .../engines/overlay/overlay_sculpt_curves.cc | 2 +- .../overlay/overlay_viewer_attribute.cc | 2 +- .../draw/intern/draw_cache_impl_curve.cc | 4 +- .../draw/intern/draw_cache_impl_curves.cc | 6 +- .../draw/intern/draw_cache_impl_pointcloud.cc | 6 +- .../intern/draw_cache_impl_subdivision.cc | 3 +- source/blender/draw/intern/draw_curves.cc | 2 +- .../extract_mesh_vbo_attributes.cc | 6 +- .../editors/curves/intern/curves_edit.cc | 2 +- .../editors/curves/intern/curves_ops.cc | 9 +- .../editors/curves/intern/curves_selection.cc | 8 +- .../editors/geometry/geometry_attributes.cc | 9 +- source/blender/editors/mesh/editface.cc | 46 ++++---- source/blender/editors/mesh/mesh_data.cc | 2 +- .../blender/editors/object/object_remesh.cc | 2 +- .../blender/editors/object/object_vgroup.cc | 16 +-- .../editors/sculpt_paint/curves_sculpt_add.cc | 6 +- .../sculpt_paint/curves_sculpt_comb.cc | 2 +- .../sculpt_paint/curves_sculpt_density.cc | 6 +- .../sculpt_paint/curves_sculpt_grow_shrink.cc | 2 +- .../sculpt_paint/curves_sculpt_pinch.cc | 2 +- .../sculpt_paint/curves_sculpt_puff.cc | 2 +- .../sculpt_paint/curves_sculpt_selection.cc | 4 +- .../sculpt_paint/curves_sculpt_slide.cc | 10 +- .../sculpt_paint/curves_sculpt_smooth.cc | 2 +- .../sculpt_paint/curves_sculpt_snake_hook.cc | 2 +- .../editors/sculpt_paint/paint_vertex.cc | 36 +++--- .../sculpt_paint/paint_vertex_color_ops.cc | 8 +- .../editors/sculpt_paint/sculpt_face_set.cc | 10 +- .../editors/space_view3d/view3d_select.cc | 4 +- .../transform/transform_convert_curves.cc | 2 +- .../blender_interface/BlenderFileLoader.cpp | 4 +- .../geometry/intern/mesh_split_edges.cc | 2 +- .../geometry/intern/mesh_to_curve_convert.cc | 2 +- .../intern/point_merge_by_distance.cc | 2 +- .../geometry/intern/realize_instances.cc | 22 ++-- .../geometry/intern/resample_curves.cc | 4 +- .../intern/lineart/lineart_cpu.cc | 4 +- .../io/alembic/exporter/abc_writer_mesh.cc | 4 +- .../blender/io/collada/GeometryExporter.cpp | 6 +- .../ply/exporter/ply_export_load_plydata.cc | 4 +- .../blender/io/usd/intern/usd_writer_mesh.cc | 6 +- .../exporter/obj_export_file_writer.cc | 4 +- .../wavefront_obj/exporter/obj_export_mesh.cc | 8 +- source/blender/modifiers/intern/MOD_array.cc | 4 +- source/blender/modifiers/intern/MOD_nodes.cc | 4 +- .../geometry/nodes/node_geo_convex_hull.cc | 12 +- .../nodes/node_geo_curve_to_points.cc | 33 +++--- .../node_geo_deform_curves_on_surface.cc | 16 +-- .../nodes/node_geo_input_curve_handles.cc | 2 +- .../nodes/node_geo_instance_on_points.cc | 35 +++--- .../nodes/node_geo_instances_to_points.cc | 31 +++--- .../nodes/node_geo_interpolate_curves.cc | 36 +++--- .../geometry/nodes/node_geo_join_geometry.cc | 2 +- .../nodes/node_geo_material_selection.cc | 2 +- .../node_geo_mesh_primitive_ico_sphere.cc | 2 +- .../geometry/nodes/node_geo_mesh_to_points.cc | 53 ++++++--- .../nodes/node_geo_points_to_vertices.cc | 32 ++++-- .../nodes/node_geo_points_to_volume.cc | 3 +- .../geometry/nodes/node_geo_set_position.cc | 6 +- source/blender/render/intern/bake.cc | 4 +- 85 files changed, 496 insertions(+), 503 deletions(-) diff --git a/source/blender/blenkernel/BKE_attribute.hh b/source/blender/blenkernel/BKE_attribute.hh index 6b887b8eeda..0f6318b353e 100644 --- a/source/blender/blenkernel/BKE_attribute.hh +++ b/source/blender/blenkernel/BKE_attribute.hh @@ -84,7 +84,7 @@ struct AttributeInit { DefaultValue, /** #AttributeInitVArray. */ VArray, - /** #AttributeInitMoveArray. */ + /** #AttributeInitData. */ MoveArray, }; Type type; @@ -121,16 +121,17 @@ struct AttributeInitVArray : public AttributeInit { * Sometimes data is created before a geometry component is available. In that case, it's * preferable to move data directly to the created attribute to avoid a new allocation and a copy. * - * Note that this will only have a benefit for attributes that are stored directly as contiguous - * arrays, so not for some built-in attributes. - * - * The array must be allocated with MEM_*, since `attribute_try_create` will free the array if it - * can't be used directly, and that is generally how Blender expects custom data to be allocated. + * Implicit sharing info can be provided if the array is shared. In that case the sharing info + * has ownership of the provided array. */ -struct AttributeInitMoveArray : public AttributeInit { - void *data = nullptr; +struct AttributeInitData : public AttributeInit { + const void *data = nullptr; + const ImplicitSharingInfo *sharing_info = nullptr; - AttributeInitMoveArray(void *data) : AttributeInit(Type::MoveArray), data(data) {} + AttributeInitData(const void *data, const ImplicitSharingInfo *sharing_info) + : AttributeInit(Type::MoveArray), data(data), sharing_info(sharing_info) + { + } }; /* Returns false when the iteration should be stopped. */ @@ -151,6 +152,21 @@ template struct AttributeReader { */ eAttrDomain domain; + /** + * Information about shared ownership of the attribute array. This will only be provided + * if the virtual array directly references the contiguous original attribute array. + */ + const ImplicitSharingInfo *sharing_info; + + const VArray &operator*() const + { + return this->varray; + } + VArray &operator*() + { + return this->varray; + } + operator bool() const { return this->varray; @@ -270,15 +286,25 @@ template struct SpanAttributeWriter { struct GAttributeReader { GVArray varray; eAttrDomain domain; + const ImplicitSharingInfo *sharing_info; operator bool() const { return this->varray; } + const GVArray &operator*() const + { + return this->varray; + } + GVArray &operator*() + { + return this->varray; + } + template AttributeReader typed() const { - return {varray.typed(), domain}; + return {varray.typed(), domain, sharing_info}; } }; @@ -457,15 +483,15 @@ class AttributeAccessor { * Get read-only access to the attribute. If necessary, the attribute is interpolated to the * given domain, and converted to the given type, in that order. The result may be empty. */ - GVArray lookup(const AttributeIDRef &attribute_id, - const std::optional domain, - const std::optional data_type) const; + GAttributeReader lookup(const AttributeIDRef &attribute_id, + const std::optional domain, + const std::optional data_type) const; /** * Get read-only access to the attribute whereby the attribute is interpolated to the given * domain. The result may be empty. */ - GVArray lookup(const AttributeIDRef &attribute_id, const eAttrDomain domain) const + GAttributeReader lookup(const AttributeIDRef &attribute_id, const eAttrDomain domain) const { return this->lookup(attribute_id, domain, std::nullopt); } @@ -474,7 +500,8 @@ class AttributeAccessor { * Get read-only access to the attribute whereby the attribute is converted to the given type. * The result may be empty. */ - GVArray lookup(const AttributeIDRef &attribute_id, const eCustomDataType data_type) const + GAttributeReader lookup(const AttributeIDRef &attribute_id, + const eCustomDataType data_type) const { return this->lookup(attribute_id, std::nullopt, data_type); } @@ -484,8 +511,8 @@ class AttributeAccessor { * given domain and then converted to the given type, in that order. The result may be empty. */ template - VArray lookup(const AttributeIDRef &attribute_id, - const std::optional domain = std::nullopt) const + AttributeReader lookup(const AttributeIDRef &attribute_id, + const std::optional domain = std::nullopt) const { const CPPType &cpp_type = CPPType::get(); const eCustomDataType data_type = cpp_type_to_custom_data_type(cpp_type); @@ -498,23 +525,23 @@ class AttributeAccessor { * If the attribute does not exist, a virtual array with the given default value is returned. * If the passed in default value is null, the default value of the type is used (generally 0). */ - GVArray lookup_or_default(const AttributeIDRef &attribute_id, - const eAttrDomain domain, - const eCustomDataType data_type, - const void *default_value = nullptr) const; + GAttributeReader lookup_or_default(const AttributeIDRef &attribute_id, + const eAttrDomain domain, + const eCustomDataType data_type, + const void *default_value = nullptr) const; /** * Same as the generic version above, but should be used when the type is known at compile time. */ template - VArray lookup_or_default(const AttributeIDRef &attribute_id, - const eAttrDomain domain, - const T &default_value) const + AttributeReader lookup_or_default(const AttributeIDRef &attribute_id, + const eAttrDomain domain, + const T &default_value) const { - if (VArray varray = this->lookup(attribute_id, domain)) { + if (AttributeReader varray = this->lookup(attribute_id, domain)) { return varray; } - return VArray::ForSingle(default_value, this->domain_size(domain)); + return {VArray::ForSingle(default_value, this->domain_size(domain)), domain}; } /** @@ -626,6 +653,15 @@ class MutableAttributeAccessor : public AttributeAccessor { { return fn_->add(owner_, attribute_id, domain, data_type, initializer); } + template + bool add(const AttributeIDRef &attribute_id, + const eAttrDomain domain, + const AttributeInit &initializer) + { + const CPPType &cpp_type = CPPType::get(); + const eCustomDataType data_type = cpp_type_to_custom_data_type(cpp_type); + return this->add(attribute_id, domain, data_type, initializer); + } /** * Find an attribute with the given id, domain and data type. If it does not exist, create a new diff --git a/source/blender/blenkernel/intern/DerivedMesh.cc b/source/blender/blenkernel/intern/DerivedMesh.cc index 8731df1f350..4ae99d83539 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.cc +++ b/source/blender/blenkernel/intern/DerivedMesh.cc @@ -658,11 +658,12 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph, ASSERT_IS_VALID_MESH(mesh_final); } MutableAttributeAccessor attributes = mesh_final->attributes_for_write(); - SpanAttributeWriter rest_positions = - attributes.lookup_or_add_for_write_only_span("rest_position", ATTR_DOMAIN_POINT); - if (rest_positions && attributes.domain_size(ATTR_DOMAIN_POINT) > 0) { - attributes.lookup("position").materialize(rest_positions.span); - rest_positions.finish(); + const AttributeReader positions = attributes.lookup("position"); + if (positions) { + attributes.add( + "rest_position", + ATTR_DOMAIN_POINT, + AttributeInitData(positions.varray.common_info().data, positions.sharing_info)); } } diff --git a/source/blender/blenkernel/intern/attribute_access.cc b/source/blender/blenkernel/intern/attribute_access.cc index 722eb63a477..1a377c5532f 100644 --- a/source/blender/blenkernel/intern/attribute_access.cc +++ b/source/blender/blenkernel/intern/attribute_access.cc @@ -206,17 +206,10 @@ static bool add_builtin_type_custom_data_layer_from_init(CustomData &custom_data return true; } case AttributeInit::Type::MoveArray: { - void *src_data = static_cast(initializer).data; + const AttributeInitData &init = static_cast(initializer); const void *stored_data = CustomData_add_layer_with_data( - &custom_data, data_type, src_data, domain_num, nullptr); - if (stored_data == nullptr) { - return false; - } - if (stored_data != src_data) { - MEM_freeN(src_data); - return true; - } - return true; + &custom_data, data_type, const_cast(init.data), domain_num, init.sharing_info); + return stored_data != nullptr; } } @@ -288,9 +281,13 @@ static bool add_custom_data_layer_from_attribute_init(const AttributeIDRef &attr break; } case AttributeInit::Type::MoveArray: { - void *data = static_cast(initializer).data; - add_generic_custom_data_layer_with_existing_data( - custom_data, data_type, attribute_id, domain_num, data, nullptr); + const AttributeInitData &init = static_cast(initializer); + add_generic_custom_data_layer_with_existing_data(custom_data, + data_type, + attribute_id, + domain_num, + const_cast(init.data), + init.sharing_info); break; } } @@ -314,7 +311,7 @@ bool BuiltinCustomDataLayerProvider::layer_exists(const CustomData &custom_data) return CustomData_has_layer(&custom_data, stored_type_); } -GVArray BuiltinCustomDataLayerProvider::try_get_for_read(const void *owner) const +GAttributeReader BuiltinCustomDataLayerProvider::try_get_for_read(const void *owner) const { const CustomData *custom_data = custom_data_access_.get_const_custom_data(owner); if (custom_data == nullptr) { @@ -325,22 +322,27 @@ GVArray BuiltinCustomDataLayerProvider::try_get_for_read(const void *owner) cons const int element_num = custom_data_access_.get_element_num(owner); if (element_num == 0) { if (this->layer_exists(*custom_data)) { - return as_read_attribute_(nullptr, 0); + return {GVArray::ForSingle(*custom_data_type_to_cpp_type(data_type_), 0, nullptr), + domain_, + nullptr}; } return {}; } - const void *data = nullptr; + int index; if (stored_as_named_attribute_) { - data = CustomData_get_layer_named(custom_data, stored_type_, name_.c_str()); + index = CustomData_get_named_layer_index(custom_data, stored_type_, name_.c_str()); } else { - data = CustomData_get_layer(custom_data, stored_type_); + index = CustomData_get_layer_index(custom_data, stored_type_); } - if (data == nullptr) { + if (index == -1) { return {}; } - return as_read_attribute_(data, element_num); + const CustomDataLayer &layer = custom_data->layers[index]; + return {GVArray::ForSpan({*custom_data_type_to_cpp_type(data_type_), layer.data, element_num}), + domain_, + layer.sharing_info}; } GAttributeWriter BuiltinCustomDataLayerProvider::try_get_for_write(void *owner) const @@ -356,26 +358,30 @@ GAttributeWriter BuiltinCustomDataLayerProvider::try_get_for_write(void *owner) } /* When the number of elements is zero, layers might have null data but still exist. */ + const CPPType &type = *custom_data_type_to_cpp_type(data_type_); const int element_num = custom_data_access_.get_element_num(owner); if (element_num == 0) { if (this->layer_exists(*custom_data)) { - return {as_write_attribute_(nullptr, 0), domain_, std::move(tag_modified_fn)}; + return {GVMutableArray::ForSpan({type, nullptr, 0}), domain_, std::move(tag_modified_fn)}; } return {}; } - void *data = nullptr; + int index; if (stored_as_named_attribute_) { - data = CustomData_get_layer_named_for_write( - custom_data, stored_type_, name_.c_str(), element_num); + index = CustomData_get_named_layer_index(custom_data, stored_type_, name_.c_str()); } else { - data = CustomData_get_layer_for_write(custom_data, stored_type_, element_num); + index = CustomData_get_layer_index(custom_data, stored_type_); } - if (data == nullptr) { + if (index == -1) { return {}; } - return {as_write_attribute_(data, element_num), domain_, std::move(tag_modified_fn)}; + CustomDataLayer &layer = custom_data->layers[index]; + + return {GVMutableArray::ForSpan({type, layer.data, element_num}), + domain_, + std::move(tag_modified_fn)}; } bool BuiltinCustomDataLayerProvider::try_delete(void *owner) const @@ -470,7 +476,7 @@ GAttributeReader CustomDataAttributeProvider::try_get_for_read( continue; } GSpan data{*type, layer.data, element_num}; - return {GVArray::ForSpan(data), domain_}; + return {GVArray::ForSpan(data), domain_, layer.sharing_info}; } return {}; } @@ -727,50 +733,52 @@ static blender::GVArray try_adapt_data_type(blender::GVArray varray, return conversions.try_convert(std::move(varray), to_type); } -GVArray AttributeAccessor::lookup(const AttributeIDRef &attribute_id, - const std::optional domain, - const std::optional data_type) const +GAttributeReader AttributeAccessor::lookup(const AttributeIDRef &attribute_id, + const std::optional domain, + const std::optional data_type) const { GAttributeReader attribute = this->lookup(attribute_id); if (!attribute) { return {}; } - GVArray varray = std::move(attribute.varray); if (domain.has_value()) { if (attribute.domain != domain) { - varray = this->adapt_domain(varray, attribute.domain, *domain); - if (!varray) { + attribute.varray = this->adapt_domain(attribute.varray, attribute.domain, *domain); + attribute.domain = *domain; + attribute.sharing_info = nullptr; + if (!attribute.varray) { return {}; } } } if (data_type.has_value()) { const CPPType &type = *custom_data_type_to_cpp_type(*data_type); - if (varray.type() != type) { - varray = try_adapt_data_type(std::move(varray), type); - if (!varray) { + if (attribute.varray.type() != type) { + attribute.varray = try_adapt_data_type(std::move(attribute.varray), type); + attribute.sharing_info = nullptr; + if (!attribute.varray) { return {}; } } } - return varray; + return attribute; } -GVArray AttributeAccessor::lookup_or_default(const AttributeIDRef &attribute_id, - const eAttrDomain domain, - const eCustomDataType data_type, - const void *default_value) const +GAttributeReader AttributeAccessor::lookup_or_default(const AttributeIDRef &attribute_id, + const eAttrDomain domain, + const eCustomDataType data_type, + const void *default_value) const { - GVArray varray = this->lookup(attribute_id, domain, data_type); - if (varray) { - return varray; + GAttributeReader attribute = this->lookup(attribute_id, domain, data_type); + if (attribute) { + return attribute; } const CPPType &type = *custom_data_type_to_cpp_type(data_type); const int64_t domain_size = this->domain_size(domain); if (default_value == nullptr) { - return GVArray::ForSingleRef(type, domain_size, type.default_value()); + return {GVArray::ForSingleRef(type, domain_size, type.default_value()), domain, nullptr}; } - return GVArray::ForSingle(type, domain_size, default_value); + return {GVArray::ForSingle(type, domain_size, default_value), domain, nullptr}; } Set AttributeAccessor::all_ids() const @@ -919,7 +927,7 @@ Vector retrieve_attributes_for_transfer( return true; } - GVArray src = src_attributes.lookup(id, meta_data.domain); + GVArray src = *src_attributes.lookup(id, meta_data.domain); BLI_assert(src); bke::GSpanAttributeWriter dst = dst_attributes.lookup_or_add_for_write_only_span( id, meta_data.domain, meta_data.data_type); diff --git a/source/blender/blenkernel/intern/attribute_access_intern.hh b/source/blender/blenkernel/intern/attribute_access_intern.hh index a1a74e3b81c..7da35cc8573 100644 --- a/source/blender/blenkernel/intern/attribute_access_intern.hh +++ b/source/blender/blenkernel/intern/attribute_access_intern.hh @@ -66,7 +66,7 @@ class BuiltinAttributeProvider { { } - virtual GVArray try_get_for_read(const void *owner) const = 0; + virtual GAttributeReader try_get_for_read(const void *owner) const = 0; virtual GAttributeWriter try_get_for_write(void *owner) const = 0; virtual bool try_delete(void *owner) const = 0; virtual bool try_create(void *onwer, const AttributeInit &initializer) const = 0; @@ -163,16 +163,6 @@ class CustomDataAttributeProvider final : public DynamicAttributesProvider { } }; -template GVArray make_array_read_attribute(const void *data, const int domain_num) -{ - return VArray::ForSpan(Span((const T *)data, domain_num)); -} - -template GVMutableArray make_array_write_attribute(void *data, const int domain_num) -{ - return VMutableArray::ForSpan(MutableSpan((T *)data, domain_num)); -} - /** * This provider is used to provide access to builtin attributes. It supports making internal types * available as different types. @@ -181,14 +171,12 @@ template GVMutableArray make_array_write_attribute(void *data, const * if the stored type is the same as the attribute type. */ class BuiltinCustomDataLayerProvider final : public BuiltinAttributeProvider { - using AsReadAttribute = GVArray (*)(const void *data, int element_num); + using AsReadAttribute = GAttributeReader (*)(const void *data, int element_num); using AsWriteAttribute = GVMutableArray (*)(void *data, int element_num); using UpdateOnRead = void (*)(const void *owner); using UpdateOnChange = void (*)(void *owner); const eCustomDataType stored_type_; const CustomDataAccessInfo custom_data_access_; - const AsReadAttribute as_read_attribute_; - const AsWriteAttribute as_write_attribute_; const UpdateOnChange update_on_change_; bool stored_as_named_attribute_; @@ -200,22 +188,18 @@ class BuiltinCustomDataLayerProvider final : public BuiltinAttributeProvider { const CreatableEnum creatable, const DeletableEnum deletable, const CustomDataAccessInfo custom_data_access, - const AsReadAttribute as_read_attribute, - const AsWriteAttribute as_write_attribute, const UpdateOnChange update_on_write, const AttributeValidator validator = {}) : BuiltinAttributeProvider( std::move(attribute_name), domain, attribute_type, creatable, deletable, validator), stored_type_(stored_type), custom_data_access_(custom_data_access), - as_read_attribute_(as_read_attribute), - as_write_attribute_(as_write_attribute), update_on_change_(update_on_write), stored_as_named_attribute_(data_type_ == stored_type_) { } - GVArray try_get_for_read(const void *owner) const final; + GAttributeReader try_get_for_read(const void *owner) const final; GAttributeWriter try_get_for_write(void *owner) const final; bool try_delete(void *owner) const final; bool try_create(void *owner, const AttributeInit &initializer) const final; @@ -298,7 +282,7 @@ inline GAttributeReader lookup(const void *owner, const AttributeIDRef &attribut const StringRef name = attribute_id.name(); if (const BuiltinAttributeProvider *provider = providers.builtin_attribute_providers().lookup_default_as(name, nullptr)) { - return {provider->try_get_for_read(owner), provider->domain()}; + return provider->try_get_for_read(owner); } } for (const DynamicAttributesProvider *provider : providers.dynamic_attribute_providers()) { diff --git a/source/blender/blenkernel/intern/bvhutils.cc b/source/blender/blenkernel/intern/bvhutils.cc index 2075ae1d0f9..9a267e66573 100644 --- a/source/blender/blenkernel/intern/bvhutils.cc +++ b/source/blender/blenkernel/intern/bvhutils.cc @@ -1280,7 +1280,7 @@ BVHTree *BKE_bvhtree_from_mesh_get(struct BVHTreeFromMesh *data, blender::bke::AttributeAccessor attributes = mesh->attributes(); mask = looptri_no_hidden_map_get( mesh->polys(), - attributes.lookup_or_default(".hide_poly", ATTR_DOMAIN_FACE, false), + *attributes.lookup_or_default(".hide_poly", ATTR_DOMAIN_FACE, false), looptris.size(), &mask_bits_act_len); ATTR_FALLTHROUGH; diff --git a/source/blender/blenkernel/intern/curve_to_mesh_convert.cc b/source/blender/blenkernel/intern/curve_to_mesh_convert.cc index 89e80a6a11e..45bbca42871 100644 --- a/source/blender/blenkernel/intern/curve_to_mesh_convert.cc +++ b/source/blender/blenkernel/intern/curve_to_mesh_convert.cc @@ -747,7 +747,7 @@ Mesh *curve_to_mesh_sweep(const CurvesGeometry &main, Span radii = {}; if (main_attributes.contains("radius")) { radii = evaluated_attribute_if_necessary( - main_attributes.lookup_or_default("radius", ATTR_DOMAIN_POINT, 1.0f), + *main_attributes.lookup_or_default("radius", ATTR_DOMAIN_POINT, 1.0f), main, main.curve_type_counts(), eval_buffer) @@ -805,7 +805,7 @@ Mesh *curve_to_mesh_sweep(const CurvesGeometry &main, const eAttrDomain src_domain = meta_data.domain; const eCustomDataType type = meta_data.data_type; - GVArray src = main_attributes.lookup(id, src_domain, type); + const GVArray src = *main_attributes.lookup(id, src_domain, type); const eAttrDomain dst_domain = get_attribute_domain_for_mesh(mesh_attributes, id); GSpanAttributeWriter dst = mesh_attributes.lookup_or_add_for_write_only_span( @@ -841,7 +841,7 @@ Mesh *curve_to_mesh_sweep(const CurvesGeometry &main, } const eAttrDomain src_domain = meta_data.domain; const eCustomDataType type = meta_data.data_type; - GVArray src = profile_attributes.lookup(id, src_domain, type); + const GVArray src = *profile_attributes.lookup(id, src_domain, type); const eAttrDomain dst_domain = get_attribute_domain_for_mesh(mesh_attributes, id); GSpanAttributeWriter dst = mesh_attributes.lookup_or_add_for_write_only_span( diff --git a/source/blender/blenkernel/intern/fluid.cc b/source/blender/blenkernel/intern/fluid.cc index 32cdb4da630..88105132d83 100644 --- a/source/blender/blenkernel/intern/fluid.cc +++ b/source/blender/blenkernel/intern/fluid.cc @@ -3237,8 +3237,9 @@ static Mesh *create_liquid_geometry(FluidDomainSettings *fds, blender::MutableSpan poly_offsets = me->poly_offsets_for_write(); blender::MutableSpan corner_verts = me->corner_verts_for_write(); - const bool is_sharp = orgmesh->attributes().lookup_or_default( - "sharp_face", ATTR_DOMAIN_FACE, false)[0]; + const bool is_sharp = orgmesh->attributes() + .lookup_or_default("sharp_face", ATTR_DOMAIN_FACE, false) + .varray[0]; BKE_mesh_smooth_flag_set(me, !is_sharp); /* Get size (dimension) but considering scaling. */ diff --git a/source/blender/blenkernel/intern/geometry_component_curves.cc b/source/blender/blenkernel/intern/geometry_component_curves.cc index 0552b15df2d..eb185d979a8 100644 --- a/source/blender/blenkernel/intern/geometry_component_curves.cc +++ b/source/blender/blenkernel/intern/geometry_component_curves.cc @@ -375,8 +375,6 @@ static ComponentAttributeProviders create_attribute_providers_for_curve() BuiltinAttributeProvider::NonCreatable, BuiltinAttributeProvider::NonDeletable, point_access, - make_array_read_attribute, - make_array_write_attribute, tag_component_positions_changed); static BuiltinCustomDataLayerProvider radius("radius", @@ -386,8 +384,6 @@ static ComponentAttributeProviders create_attribute_providers_for_curve() BuiltinAttributeProvider::Creatable, BuiltinAttributeProvider::Deletable, point_access, - make_array_read_attribute, - make_array_write_attribute, tag_component_radii_changed); static BuiltinCustomDataLayerProvider id("id", @@ -397,8 +393,6 @@ static ComponentAttributeProviders create_attribute_providers_for_curve() BuiltinAttributeProvider::Creatable, BuiltinAttributeProvider::Deletable, point_access, - make_array_read_attribute, - make_array_write_attribute, nullptr); static BuiltinCustomDataLayerProvider tilt("tilt", @@ -408,8 +402,6 @@ static ComponentAttributeProviders create_attribute_providers_for_curve() BuiltinAttributeProvider::Creatable, BuiltinAttributeProvider::Deletable, point_access, - make_array_read_attribute, - make_array_write_attribute, tag_component_normals_changed); static BuiltinCustomDataLayerProvider handle_right("handle_right", @@ -419,8 +411,6 @@ static ComponentAttributeProviders create_attribute_providers_for_curve() BuiltinAttributeProvider::Creatable, BuiltinAttributeProvider::Deletable, point_access, - make_array_read_attribute, - make_array_write_attribute, tag_component_positions_changed); static BuiltinCustomDataLayerProvider handle_left("handle_left", @@ -430,8 +420,6 @@ static ComponentAttributeProviders create_attribute_providers_for_curve() BuiltinAttributeProvider::Creatable, BuiltinAttributeProvider::Deletable, point_access, - make_array_read_attribute, - make_array_write_attribute, tag_component_positions_changed); static auto handle_type_clamp = mf::build::SI1_SO( @@ -447,8 +435,6 @@ static ComponentAttributeProviders create_attribute_providers_for_curve() BuiltinAttributeProvider::Creatable, BuiltinAttributeProvider::Deletable, point_access, - make_array_read_attribute, - make_array_write_attribute, tag_component_topology_changed, AttributeValidator{&handle_type_clamp}); @@ -459,8 +445,6 @@ static ComponentAttributeProviders create_attribute_providers_for_curve() BuiltinAttributeProvider::Creatable, BuiltinAttributeProvider::Deletable, point_access, - make_array_read_attribute, - make_array_write_attribute, tag_component_topology_changed, AttributeValidator{&handle_type_clamp}); @@ -471,8 +455,6 @@ static ComponentAttributeProviders create_attribute_providers_for_curve() BuiltinAttributeProvider::Creatable, BuiltinAttributeProvider::Deletable, point_access, - make_array_read_attribute, - make_array_write_attribute, tag_component_positions_changed); static const auto nurbs_order_clamp = mf::build::SI1_SO( @@ -486,8 +468,6 @@ static ComponentAttributeProviders create_attribute_providers_for_curve() BuiltinAttributeProvider::Creatable, BuiltinAttributeProvider::Deletable, curve_access, - make_array_read_attribute, - make_array_write_attribute, tag_component_topology_changed, AttributeValidator{&nurbs_order_clamp}); @@ -504,8 +484,6 @@ static ComponentAttributeProviders create_attribute_providers_for_curve() BuiltinAttributeProvider::Creatable, BuiltinAttributeProvider::Deletable, curve_access, - make_array_read_attribute, - make_array_write_attribute, tag_component_normals_changed, AttributeValidator{&normal_mode_clamp}); @@ -522,8 +500,6 @@ static ComponentAttributeProviders create_attribute_providers_for_curve() BuiltinAttributeProvider::Creatable, BuiltinAttributeProvider::Deletable, curve_access, - make_array_read_attribute, - make_array_write_attribute, tag_component_topology_changed, AttributeValidator{&knots_mode_clamp}); @@ -540,8 +516,6 @@ static ComponentAttributeProviders create_attribute_providers_for_curve() BuiltinAttributeProvider::Creatable, BuiltinAttributeProvider::Deletable, curve_access, - make_array_read_attribute, - make_array_write_attribute, tag_component_curve_types_changed, AttributeValidator{&curve_type_clamp}); @@ -556,8 +530,6 @@ static ComponentAttributeProviders create_attribute_providers_for_curve() BuiltinAttributeProvider::Creatable, BuiltinAttributeProvider::Deletable, curve_access, - make_array_read_attribute, - make_array_write_attribute, tag_component_topology_changed, AttributeValidator{&resolution_clamp}); @@ -568,8 +540,6 @@ static ComponentAttributeProviders create_attribute_providers_for_curve() BuiltinAttributeProvider::Creatable, BuiltinAttributeProvider::Deletable, curve_access, - make_array_read_attribute, - make_array_write_attribute, tag_component_topology_changed); static CustomDataAttributeProvider curve_custom_data(ATTR_DOMAIN_CURVE, curve_access); diff --git a/source/blender/blenkernel/intern/geometry_component_instances.cc b/source/blender/blenkernel/intern/geometry_component_instances.cc index 8ea6264e6f3..ce465d67f21 100644 --- a/source/blender/blenkernel/intern/geometry_component_instances.cc +++ b/source/blender/blenkernel/intern/geometry_component_instances.cc @@ -131,14 +131,16 @@ class InstancePositionAttributeProvider final : public BuiltinAttributeProvider { } - GVArray try_get_for_read(const void *owner) const final + GAttributeReader try_get_for_read(const void *owner) const final { const Instances *instances = static_cast(owner); if (instances == nullptr) { return {}; } Span transforms = instances->transforms(); - return VArray::ForDerivedSpan(transforms); + return {VArray::ForDerivedSpan(transforms), + domain_, + nullptr}; } GAttributeWriter try_get_for_write(void *owner) const final @@ -200,8 +202,6 @@ static ComponentAttributeProviders create_attribute_providers_for_instances() BuiltinAttributeProvider::Creatable, BuiltinAttributeProvider::Deletable, instance_custom_data_access, - make_array_read_attribute, - make_array_write_attribute, nullptr); static CustomDataAttributeProvider instance_custom_data(ATTR_DOMAIN_INSTANCE, diff --git a/source/blender/blenkernel/intern/geometry_component_mesh.cc b/source/blender/blenkernel/intern/geometry_component_mesh.cc index bed38e43afb..0f70d9ac48a 100644 --- a/source/blender/blenkernel/intern/geometry_component_mesh.cc +++ b/source/blender/blenkernel/intern/geometry_component_mesh.cc @@ -859,23 +859,6 @@ static blender::GVArray adapt_mesh_attribute_domain(const Mesh &mesh, namespace blender::bke { -template -static GVArray make_derived_read_attribute(const void *data, const int domain_num) -{ - return VArray::template ForDerivedSpan( - Span((const StructT *)data, domain_num)); -} - -template -static GVMutableArray make_derived_write_attribute(void *data, const int domain_num) -{ - return VMutableArray::template ForDerivedSpan( - MutableSpan((StructT *)data, domain_num)); -} - static void tag_component_positions_changed(void *owner) { Mesh *mesh = static_cast(owner); @@ -884,16 +867,6 @@ static void tag_component_positions_changed(void *owner) } } -static float get_crease(const float &crease) -{ - return crease; -} - -static void set_crease(float &crease, const float value) -{ - crease = std::clamp(value, 0.0f, 1.0f); -} - class VArrayImpl_For_VertexWeights final : public VMutableArrayImpl { private: MDeformVert *dverts_; @@ -1141,11 +1114,9 @@ static ComponentAttributeProviders create_attribute_providers_for_mesh() ATTR_DOMAIN_POINT, CD_PROP_FLOAT3, CD_PROP_FLOAT3, - BuiltinAttributeProvider::NonCreatable, + BuiltinAttributeProvider::Creatable, BuiltinAttributeProvider::NonDeletable, point_access, - make_array_read_attribute, - make_array_write_attribute, tag_component_positions_changed); static BuiltinCustomDataLayerProvider id("id", @@ -1155,8 +1126,6 @@ static ComponentAttributeProviders create_attribute_providers_for_mesh() BuiltinAttributeProvider::Creatable, BuiltinAttributeProvider::Deletable, point_access, - make_array_read_attribute, - make_array_write_attribute, nullptr); static const auto material_index_clamp = mf::build::SI1_SO( @@ -1173,8 +1142,6 @@ static ComponentAttributeProviders create_attribute_providers_for_mesh() BuiltinAttributeProvider::Creatable, BuiltinAttributeProvider::Deletable, face_access, - make_array_read_attribute, - make_array_write_attribute, nullptr, AttributeValidator{&material_index_clamp}); @@ -1189,8 +1156,6 @@ static ComponentAttributeProviders create_attribute_providers_for_mesh() BuiltinAttributeProvider::NonCreatable, BuiltinAttributeProvider::NonDeletable, edge_access, - make_array_read_attribute, - make_array_write_attribute, nullptr, AttributeValidator{&int2_index_clamp}); @@ -1207,8 +1172,6 @@ static ComponentAttributeProviders create_attribute_providers_for_mesh() BuiltinAttributeProvider::NonCreatable, BuiltinAttributeProvider::NonDeletable, corner_access, - make_array_read_attribute, - make_array_write_attribute, nullptr, AttributeValidator{&int_index_clamp}); static BuiltinCustomDataLayerProvider corner_edge(".corner_edge", @@ -1218,8 +1181,6 @@ static ComponentAttributeProviders create_attribute_providers_for_mesh() BuiltinAttributeProvider::NonCreatable, BuiltinAttributeProvider::NonDeletable, corner_access, - make_array_read_attribute, - make_array_write_attribute, nullptr, AttributeValidator{&int_index_clamp}); @@ -1230,8 +1191,6 @@ static ComponentAttributeProviders create_attribute_providers_for_mesh() BuiltinAttributeProvider::Creatable, BuiltinAttributeProvider::Deletable, face_access, - make_array_read_attribute, - make_array_write_attribute, nullptr); static BuiltinCustomDataLayerProvider sharp_edge("sharp_edge", @@ -1241,21 +1200,21 @@ static ComponentAttributeProviders create_attribute_providers_for_mesh() BuiltinAttributeProvider::Creatable, BuiltinAttributeProvider::Deletable, edge_access, - make_array_read_attribute, - make_array_write_attribute, nullptr); - static BuiltinCustomDataLayerProvider crease( - "crease", - ATTR_DOMAIN_EDGE, - CD_PROP_FLOAT, - CD_CREASE, - BuiltinAttributeProvider::Creatable, - BuiltinAttributeProvider::Deletable, - edge_access, - make_array_read_attribute, - make_derived_write_attribute, - nullptr); + static const auto crease_clamp = mf::build::SI1_SO( + "Crease Clamp", + [](float value) { return std::clamp(value, 0.0f, 1.0f); }, + mf::build::exec_presets::AllSpanOrSingle()); + static BuiltinCustomDataLayerProvider crease("crease", + ATTR_DOMAIN_EDGE, + CD_PROP_FLOAT, + CD_CREASE, + BuiltinAttributeProvider::Creatable, + BuiltinAttributeProvider::Deletable, + edge_access, + nullptr, + AttributeValidator{&crease_clamp}); static VertexGroupsAttributeProvider vertex_groups; static CustomDataAttributeProvider corner_custom_data(ATTR_DOMAIN_CORNER, corner_access); diff --git a/source/blender/blenkernel/intern/geometry_component_pointcloud.cc b/source/blender/blenkernel/intern/geometry_component_pointcloud.cc index edc9baa2fbd..267daad48d7 100644 --- a/source/blender/blenkernel/intern/geometry_component_pointcloud.cc +++ b/source/blender/blenkernel/intern/geometry_component_pointcloud.cc @@ -139,11 +139,9 @@ static ComponentAttributeProviders create_attribute_providers_for_point_cloud() ATTR_DOMAIN_POINT, CD_PROP_FLOAT3, CD_PROP_FLOAT3, - BuiltinAttributeProvider::NonCreatable, + BuiltinAttributeProvider::Creatable, BuiltinAttributeProvider::NonDeletable, point_access, - make_array_read_attribute, - make_array_write_attribute, tag_component_positions_changed); static BuiltinCustomDataLayerProvider radius("radius", ATTR_DOMAIN_POINT, @@ -152,8 +150,6 @@ static ComponentAttributeProviders create_attribute_providers_for_point_cloud() BuiltinAttributeProvider::Creatable, BuiltinAttributeProvider::Deletable, point_access, - make_array_read_attribute, - make_array_write_attribute, tag_component_radius_changed); static BuiltinCustomDataLayerProvider id("id", ATTR_DOMAIN_POINT, @@ -162,8 +158,6 @@ static ComponentAttributeProviders create_attribute_providers_for_point_cloud() BuiltinAttributeProvider::Creatable, BuiltinAttributeProvider::Deletable, point_access, - make_array_read_attribute, - make_array_write_attribute, nullptr); static CustomDataAttributeProvider point_custom_data(ATTR_DOMAIN_POINT, point_access); return ComponentAttributeProviders({&position, &radius, &id}, {&point_custom_data}); diff --git a/source/blender/blenkernel/intern/geometry_fields.cc b/source/blender/blenkernel/intern/geometry_fields.cc index 64a000ca4cf..1f08c0793b7 100644 --- a/source/blender/blenkernel/intern/geometry_fields.cc +++ b/source/blender/blenkernel/intern/geometry_fields.cc @@ -248,7 +248,7 @@ GVArray AttributeFieldInput::get_varray_for_context(const GeometryFieldContext & { const eCustomDataType data_type = cpp_type_to_custom_data_type(*type_); if (auto attributes = context.attributes()) { - return attributes->lookup(name_, context.domain(), data_type); + return *attributes->lookup(name_, context.domain(), data_type); } return {}; } @@ -304,7 +304,7 @@ GVArray IDAttributeFieldInput::get_varray_for_context(const GeometryFieldContext const StringRef name = get_random_id_attribute_name(context.domain()); if (auto attributes = context.attributes()) { - if (GVArray attribute = attributes->lookup(name, context.domain(), CD_PROP_INT32)) { + if (GVArray attribute = *attributes->lookup(name, context.domain(), CD_PROP_INT32)) { return attribute; } } @@ -334,7 +334,7 @@ GVArray AnonymousAttributeFieldInput::get_varray_for_context(const GeometryField const IndexMask /*mask*/) const { const eCustomDataType data_type = cpp_type_to_custom_data_type(*type_); - return context.attributes()->lookup(*anonymous_id_, context.domain(), data_type); + return *context.attributes()->lookup(*anonymous_id_, context.domain(), data_type); } std::string AnonymousAttributeFieldInput::socket_inspection_name() const @@ -474,7 +474,7 @@ bool try_capture_field_on_geometry(GeometryComponent &component, } attributes.remove(attribute_id); - if (attributes.add(attribute_id, domain, data_type, bke::AttributeInitMoveArray{buffer})) { + if (attributes.add(attribute_id, domain, data_type, bke::AttributeInitData(buffer, nullptr))) { return true; } diff --git a/source/blender/blenkernel/intern/gpencil_geom_legacy.cc b/source/blender/blenkernel/intern/gpencil_geom_legacy.cc index ae96ce2316b..86caad72296 100644 --- a/source/blender/blenkernel/intern/gpencil_geom_legacy.cc +++ b/source/blender/blenkernel/intern/gpencil_geom_legacy.cc @@ -2507,7 +2507,7 @@ static void gpencil_generate_edgeloops(Object *ob, const Span dverts = me->deform_verts(); const blender::Span vert_normals = me->vert_normals(); const bke::AttributeAccessor attributes = me->attributes(); - const VArray uv_seams = attributes.lookup_or_default( + const VArray uv_seams = *attributes.lookup_or_default( ".uv_seam", ATTR_DOMAIN_EDGE, false); /* Arrays for all edge vertices (forward and backward) that form a edge loop. @@ -2753,7 +2753,7 @@ bool BKE_gpencil_convert_mesh(Main *bmain, gpl_fill, scene->r.cfra + frame_offset, GP_GETFRAME_ADD_NEW); int i; - const VArray mesh_material_indices = me_eval->attributes().lookup_or_default( + const VArray mesh_material_indices = *me_eval->attributes().lookup_or_default( "material_index", ATTR_DOMAIN_FACE, 0); for (i = 0; i < polys_len; i++) { const IndexRange poly = polys[i]; diff --git a/source/blender/blenkernel/intern/mesh.cc b/source/blender/blenkernel/intern/mesh.cc index 466ff704b17..538a4806bed 100644 --- a/source/blender/blenkernel/intern/mesh.cc +++ b/source/blender/blenkernel/intern/mesh.cc @@ -1486,7 +1486,7 @@ bool BKE_mesh_material_index_used(Mesh *me, short index) using namespace blender; using namespace blender::bke; const AttributeAccessor attributes = me->attributes(); - const VArray material_indices = attributes.lookup_or_default( + const VArray material_indices = *attributes.lookup_or_default( "material_index", ATTR_DOMAIN_FACE, 0); if (material_indices.is_single()) { return material_indices.get_internal_single() == index; @@ -1718,11 +1718,11 @@ void BKE_mesh_mselect_validate(Mesh *me) (me->totselect), sizeof(MSelect), "Mesh selection history"); const AttributeAccessor attributes = me->attributes(); - const VArray select_vert = attributes.lookup_or_default( + const VArray select_vert = *attributes.lookup_or_default( ".select_vert", ATTR_DOMAIN_POINT, false); - const VArray select_edge = attributes.lookup_or_default( + const VArray select_edge = *attributes.lookup_or_default( ".select_edge", ATTR_DOMAIN_EDGE, false); - const VArray select_poly = attributes.lookup_or_default( + const VArray select_poly = *attributes.lookup_or_default( ".select_poly", ATTR_DOMAIN_FACE, false); for (i_src = 0, i_dst = 0; i_src < me->totselect; i_src++) { @@ -1830,7 +1830,7 @@ void BKE_mesh_count_selected_items(const Mesh *mesh, int r_count[3]) void BKE_mesh_vert_coords_get(const Mesh *mesh, float (*vert_coords)[3]) { blender::bke::AttributeAccessor attributes = mesh->attributes(); - VArray positions = attributes.lookup_or_default( + VArray positions = *attributes.lookup_or_default( "position", ATTR_DOMAIN_POINT, float3(0)); positions.materialize({(float3 *)vert_coords, mesh->totvert}); } diff --git a/source/blender/blenkernel/intern/mesh_boolean_convert.cc b/source/blender/blenkernel/intern/mesh_boolean_convert.cc index 2ab87b78bd8..cd7d7d88982 100644 --- a/source/blender/blenkernel/intern/mesh_boolean_convert.cc +++ b/source/blender/blenkernel/intern/mesh_boolean_convert.cc @@ -411,7 +411,7 @@ static void copy_poly_attributes(Mesh *dest_mesh, } /* Fix material indices after they have been transferred as a generic attribute. */ - const VArray src_material_indices = orig_me->attributes().lookup_or_default( + const VArray src_material_indices = *orig_me->attributes().lookup_or_default( "material_index", ATTR_DOMAIN_FACE, 0); const int src_index = src_material_indices[index_in_orig_me]; if (material_remap.index_range().contains(src_index)) { diff --git a/source/blender/blenkernel/intern/mesh_convert.cc b/source/blender/blenkernel/intern/mesh_convert.cc index 598ec19f1d1..c1decc6b9cb 100644 --- a/source/blender/blenkernel/intern/mesh_convert.cc +++ b/source/blender/blenkernel/intern/mesh_convert.cc @@ -1087,7 +1087,7 @@ static void move_shapekey_layers_to_keyblocks(const Mesh &mesh, if (kb->uid == actshape_uid) { kb->data = MEM_malloc_arrayN(kb->totelem, sizeof(float3), __func__); MutableSpan kb_coords(static_cast(kb->data), kb->totelem); - mesh.attributes().lookup("position").materialize(kb_coords); + mesh.attributes().lookup("position").varray.materialize(kb_coords); } else { kb->data = layer.data; diff --git a/source/blender/blenkernel/intern/mesh_evaluate.cc b/source/blender/blenkernel/intern/mesh_evaluate.cc index 9cd71ba40ee..f7fba92f2a2 100644 --- a/source/blender/blenkernel/intern/mesh_evaluate.cc +++ b/source/blender/blenkernel/intern/mesh_evaluate.cc @@ -623,7 +623,7 @@ void BKE_mesh_flush_hidden_from_verts(Mesh *me) using namespace blender::bke; MutableAttributeAccessor attributes = me->attributes_for_write(); - const VArray hide_vert = attributes.lookup_or_default( + const VArray hide_vert = *attributes.lookup_or_default( ".hide_vert", ATTR_DOMAIN_POINT, false); if (hide_vert.is_single() && !hide_vert.get_internal_single()) { attributes.remove(".hide_edge"); @@ -662,7 +662,7 @@ void BKE_mesh_flush_hidden_from_polys(Mesh *me) using namespace blender::bke; MutableAttributeAccessor attributes = me->attributes_for_write(); - const VArray hide_poly = attributes.lookup_or_default( + const VArray hide_poly = *attributes.lookup_or_default( ".hide_poly", ATTR_DOMAIN_FACE, false); if (hide_poly.is_single() && !hide_poly.get_internal_single()) { attributes.remove(".hide_vert"); @@ -705,7 +705,7 @@ void BKE_mesh_flush_select_from_polys(Mesh *me) { using namespace blender::bke; MutableAttributeAccessor attributes = me->attributes_for_write(); - const VArray select_poly = attributes.lookup_or_default( + const VArray select_poly = *attributes.lookup_or_default( ".select_poly", ATTR_DOMAIN_FACE, false); if (select_poly.is_single() && !select_poly.get_internal_single()) { attributes.remove(".select_vert"); @@ -720,9 +720,9 @@ void BKE_mesh_flush_select_from_polys(Mesh *me) /* Use generic domain interpolation to read the polygon attribute on the other domains. * Assume selected faces are not hidden and none of their vertices/edges are hidden. */ attributes.lookup_or_default(".select_poly", ATTR_DOMAIN_POINT, false) - .materialize(select_vert.span); + .varray.materialize(select_vert.span); attributes.lookup_or_default(".select_poly", ATTR_DOMAIN_EDGE, false) - .materialize(select_edge.span); + .varray.materialize(select_edge.span); select_vert.finish(); select_edge.finish(); @@ -759,7 +759,7 @@ void BKE_mesh_flush_select_from_verts(Mesh *me) { using namespace blender::bke; MutableAttributeAccessor attributes = me->attributes_for_write(); - const VArray select_vert = attributes.lookup_or_default( + const VArray select_vert = *attributes.lookup_or_default( ".select_vert", ATTR_DOMAIN_POINT, false); if (select_vert.is_single() && !select_vert.get_internal_single()) { attributes.remove(".select_edge"); @@ -774,8 +774,8 @@ void BKE_mesh_flush_select_from_verts(Mesh *me) me->edges(), me->polys(), me->corner_verts(), - attributes.lookup_or_default(".hide_edge", ATTR_DOMAIN_EDGE, false), - attributes.lookup_or_default(".hide_poly", ATTR_DOMAIN_FACE, false), + *attributes.lookup_or_default(".hide_edge", ATTR_DOMAIN_EDGE, false), + *attributes.lookup_or_default(".hide_poly", ATTR_DOMAIN_FACE, false), select_vert, select_edge.span, select_poly.span); diff --git a/source/blender/blenkernel/intern/mesh_legacy_convert.cc b/source/blender/blenkernel/intern/mesh_legacy_convert.cc index 69ae70e6dfe..140f61487c1 100644 --- a/source/blender/blenkernel/intern/mesh_legacy_convert.cc +++ b/source/blender/blenkernel/intern/mesh_legacy_convert.cc @@ -1550,7 +1550,7 @@ void BKE_mesh_legacy_convert_hide_layers_to_flags(Mesh *mesh, const AttributeAccessor attributes = mesh->attributes(); MutableSpan verts(mesh->mvert, mesh->totvert); - const VArray hide_vert = attributes.lookup_or_default( + const VArray hide_vert = *attributes.lookup_or_default( ".hide_vert", ATTR_DOMAIN_POINT, false); threading::parallel_for(verts.index_range(), 4096, [&](IndexRange range) { for (const int i : range) { @@ -1559,7 +1559,7 @@ void BKE_mesh_legacy_convert_hide_layers_to_flags(Mesh *mesh, }); MutableSpan edges(mesh->medge, mesh->totedge); - const VArray hide_edge = attributes.lookup_or_default( + const VArray hide_edge = *attributes.lookup_or_default( ".hide_edge", ATTR_DOMAIN_EDGE, false); threading::parallel_for(edges.index_range(), 4096, [&](IndexRange range) { for (const int i : range) { @@ -1567,7 +1567,7 @@ void BKE_mesh_legacy_convert_hide_layers_to_flags(Mesh *mesh, } }); - const VArray hide_poly = attributes.lookup_or_default( + const VArray hide_poly = *attributes.lookup_or_default( ".hide_poly", ATTR_DOMAIN_FACE, false); threading::parallel_for(legacy_polys.index_range(), 4096, [&](IndexRange range) { for (const int i : range) { @@ -1643,7 +1643,7 @@ void BKE_mesh_legacy_convert_material_indices_to_mpoly(Mesh *mesh, using namespace blender; using namespace blender::bke; const AttributeAccessor attributes = mesh->attributes(); - const VArray material_indices = attributes.lookup_or_default( + const VArray material_indices = *attributes.lookup_or_default( "material_index", ATTR_DOMAIN_FACE, 0); threading::parallel_for(legacy_polys.index_range(), 4096, [&](IndexRange range) { for (const int i : range) { @@ -1897,7 +1897,7 @@ void BKE_mesh_legacy_convert_selection_layers_to_flags(Mesh *mesh, const AttributeAccessor attributes = mesh->attributes(); MutableSpan verts(mesh->mvert, mesh->totvert); - const VArray select_vert = attributes.lookup_or_default( + const VArray select_vert = *attributes.lookup_or_default( ".select_vert", ATTR_DOMAIN_POINT, false); threading::parallel_for(verts.index_range(), 4096, [&](IndexRange range) { for (const int i : range) { @@ -1906,7 +1906,7 @@ void BKE_mesh_legacy_convert_selection_layers_to_flags(Mesh *mesh, }); MutableSpan edges(mesh->medge, mesh->totedge); - const VArray select_edge = attributes.lookup_or_default( + const VArray select_edge = *attributes.lookup_or_default( ".select_edge", ATTR_DOMAIN_EDGE, false); threading::parallel_for(edges.index_range(), 4096, [&](IndexRange range) { for (const int i : range) { @@ -1914,7 +1914,7 @@ void BKE_mesh_legacy_convert_selection_layers_to_flags(Mesh *mesh, } }); - const VArray select_poly = attributes.lookup_or_default( + const VArray select_poly = *attributes.lookup_or_default( ".select_poly", ATTR_DOMAIN_FACE, false); threading::parallel_for(legacy_polys.index_range(), 4096, [&](IndexRange range) { for (const int i : range) { diff --git a/source/blender/blenkernel/intern/mesh_remesh_voxel.cc b/source/blender/blenkernel/intern/mesh_remesh_voxel.cc index d21949a9e3b..aa0aecb676f 100644 --- a/source/blender/blenkernel/intern/mesh_remesh_voxel.cc +++ b/source/blender/blenkernel/intern/mesh_remesh_voxel.cc @@ -317,8 +317,8 @@ void BKE_remesh_reproject_sculpt_face_sets(Mesh *target, const Mesh *source) const OffsetIndices target_polys = target->polys(); const Span target_corner_verts = target->corner_verts(); - const VArray src_face_sets = src_attributes.lookup(".sculpt_face_set", - ATTR_DOMAIN_FACE); + const VArray src_face_sets = + * src_attributes.lookup(".sculpt_face_set", ATTR_DOMAIN_FACE); if (!src_face_sets) { return; } diff --git a/source/blender/blenkernel/intern/mesh_tangent.cc b/source/blender/blenkernel/intern/mesh_tangent.cc index 9b2b5702b39..885410258af 100644 --- a/source/blender/blenkernel/intern/mesh_tangent.cc +++ b/source/blender/blenkernel/intern/mesh_tangent.cc @@ -126,7 +126,7 @@ void BKE_mesh_calc_loop_tangent_single(Mesh *mesh, } const AttributeAccessor attributes = mesh->attributes(); - const VArraySpan uv_map = attributes.lookup(uvmap, ATTR_DOMAIN_CORNER); + const VArraySpan uv_map = *attributes.lookup(uvmap, ATTR_DOMAIN_CORNER); if (uv_map.is_empty()) { BKE_reportf(reports, RPT_ERROR, diff --git a/source/blender/blenkernel/intern/object_dupli.cc b/source/blender/blenkernel/intern/object_dupli.cc index b3ada3066e5..87363380294 100644 --- a/source/blender/blenkernel/intern/object_dupli.cc +++ b/source/blender/blenkernel/intern/object_dupli.cc @@ -1833,7 +1833,7 @@ static bool find_geonode_attribute_rgba(const DupliObject *dupli, /* Attempt to look up the attribute. */ std::optional attributes = component->attributes(); - const VArray data = attributes->lookup(name); + const VArray data = *attributes->lookup(name); /* If the attribute was found and converted to float RGBA successfully, output it. */ if (data) { diff --git a/source/blender/blenkernel/intern/paint.cc b/source/blender/blenkernel/intern/paint.cc index 04784fe9378..0785af55f83 100644 --- a/source/blender/blenkernel/intern/paint.cc +++ b/source/blender/blenkernel/intern/paint.cc @@ -2127,7 +2127,7 @@ void BKE_sculpt_sync_face_visibility_to_grids(Mesh *mesh, SubdivCCG *subdiv_ccg) } const AttributeAccessor attributes = mesh->attributes(); - const VArray hide_poly = attributes.lookup_or_default( + const VArray hide_poly = *attributes.lookup_or_default( ".hide_poly", ATTR_DOMAIN_FACE, false); if (hide_poly.is_single() && !hide_poly.get_internal_single()) { /* Nothing is hidden, so we can just remove all visibility bitmaps. */ diff --git a/source/blender/blenkernel/intern/pbvh_pixels.cc b/source/blender/blenkernel/intern/pbvh_pixels.cc index aac285faaa3..2711fa89eb4 100644 --- a/source/blender/blenkernel/intern/pbvh_pixels.cc +++ b/source/blender/blenkernel/intern/pbvh_pixels.cc @@ -668,7 +668,7 @@ static bool update_pixels(PBVH *pbvh, Mesh *mesh, Image *image, ImageUser *image } const AttributeAccessor attributes = mesh->attributes(); - const VArraySpan uv_map = attributes.lookup(active_uv_name, ATTR_DOMAIN_CORNER); + const VArraySpan uv_map = *attributes.lookup(active_uv_name, ATTR_DOMAIN_CORNER); uv_islands::MeshData mesh_data( {pbvh->looptri, pbvh->totprim}, diff --git a/source/blender/blenkernel/intern/pointcloud.cc b/source/blender/blenkernel/intern/pointcloud.cc index 289d9df0f35..c342c82176a 100644 --- a/source/blender/blenkernel/intern/pointcloud.cc +++ b/source/blender/blenkernel/intern/pointcloud.cc @@ -274,9 +274,9 @@ bool PointCloud::bounds_min_max(blender::float3 &min, blender::float3 &max) cons } this->runtime->bounds_cache.ensure([&](Bounds &r_bounds) { const AttributeAccessor attributes = this->attributes(); - const VArraySpan positions = attributes.lookup(POINTCLOUD_ATTR_POSITION); + const Span positions = this->positions(); if (attributes.contains(POINTCLOUD_ATTR_RADIUS)) { - const VArraySpan radii = attributes.lookup(POINTCLOUD_ATTR_RADIUS); + const VArraySpan radii = *attributes.lookup(POINTCLOUD_ATTR_RADIUS); r_bounds = *bounds::min_max_with_radii(positions, radii); } else { diff --git a/source/blender/draw/engines/overlay/overlay_sculpt_curves.cc b/source/blender/draw/engines/overlay/overlay_sculpt_curves.cc index c73386f7897..7114c01cd3a 100644 --- a/source/blender/draw/engines/overlay/overlay_sculpt_curves.cc +++ b/source/blender/draw/engines/overlay/overlay_sculpt_curves.cc @@ -52,7 +52,7 @@ static bool everything_selected(const Curves &curves_id) { using namespace blender; const bke::CurvesGeometry &curves = curves_id.geometry.wrap(); - const VArray selection = curves.attributes().lookup_or_default( + const VArray selection = *curves.attributes().lookup_or_default( ".selection", ATTR_DOMAIN_POINT, true); return selection.is_single() && selection.get_internal_single(); } diff --git a/source/blender/draw/engines/overlay/overlay_viewer_attribute.cc b/source/blender/draw/engines/overlay/overlay_viewer_attribute.cc index fe20fb135c5..84acae41411 100644 --- a/source/blender/draw/engines/overlay/overlay_viewer_attribute.cc +++ b/source/blender/draw/engines/overlay/overlay_viewer_attribute.cc @@ -59,7 +59,7 @@ static void populate_cache_for_instance(Object &object, const InstancesComponent &instances = *base_geometry.get_component_for_read(); const AttributeAccessor instance_attributes = *instances.attributes(); - const VArray attribute = instance_attributes.lookup(".viewer"); + const VArray attribute = *instance_attributes.lookup(".viewer"); if (!attribute) { return; } diff --git a/source/blender/draw/intern/draw_cache_impl_curve.cc b/source/blender/draw/intern/draw_cache_impl_curve.cc index ff4d9235a4b..cede4e279ab 100644 --- a/source/blender/draw/intern/draw_cache_impl_curve.cc +++ b/source/blender/draw/intern/draw_cache_impl_curve.cc @@ -495,8 +495,8 @@ static void curve_create_attribute(CurveRenderData *rdata, GPUVertBuf *vbo_attr) const bke::CurvesGeometry &curves = rdata->curve_eval->geometry.wrap(); curves.ensure_can_interpolate_to_evaluated(); - const VArraySpan colors = curves.attributes().lookup( - ".viewer", ATTR_DOMAIN_POINT); + const VArraySpan colors = *curves.attributes().lookup(".viewer", + ATTR_DOMAIN_POINT); ColorGeometry4f *vbo_data = static_cast(GPU_vertbuf_get_data(vbo_attr)); curves.interpolate_to_evaluated(colors, MutableSpan{vbo_data, vert_len}); } diff --git a/source/blender/draw/intern/draw_cache_impl_curves.cc b/source/blender/draw/intern/draw_cache_impl_curves.cc index 92891cee332..d8f713b28c8 100644 --- a/source/blender/draw/intern/draw_cache_impl_curves.cc +++ b/source/blender/draw/intern/draw_cache_impl_curves.cc @@ -271,7 +271,7 @@ static void curves_batch_cache_ensure_edit_points_selection(const bke::CurvesGeo const OffsetIndices points_by_curve = curves.points_by_curve(); - const VArray selection = curves.attributes().lookup_or_default( + const VArray selection = *curves.attributes().lookup_or_default( ".selection", selection_domain, true); switch (selection_domain) { case ATTR_DOMAIN_POINT: @@ -365,14 +365,14 @@ static void curves_batch_ensure_attribute(const Curves &curves, * the Blender convention, it should be `vec4(s, s, s, 1)`. This could be resolved using a * similar texture state swizzle to map the attribute correctly as for volume attributes, so we * can control the conversion ourselves. */ - VArray attribute = attributes.lookup_or_default( + bke::AttributeReader attribute = attributes.lookup_or_default( request.attribute_name, request.domain, {0.0f, 0.0f, 0.0f, 1.0f}); MutableSpan vbo_span{ static_cast(GPU_vertbuf_get_data(attr_vbo)), attributes.domain_size(request.domain)}; - attribute.materialize(vbo_span); + attribute.varray.materialize(vbo_span); /* Existing final data may have been for a different attribute (with a different name or domain), * free the data. */ diff --git a/source/blender/draw/intern/draw_cache_impl_pointcloud.cc b/source/blender/draw/intern/draw_cache_impl_pointcloud.cc index 5c909ec16e5..d04caf63506 100644 --- a/source/blender/draw/intern/draw_cache_impl_pointcloud.cc +++ b/source/blender/draw/intern/draw_cache_impl_pointcloud.cc @@ -251,7 +251,7 @@ static void pointcloud_extract_position_and_radius(const PointCloud &pointcloud, const bke::AttributeAccessor attributes = pointcloud.attributes(); const Span positions = pointcloud.positions(); - const VArray radii = attributes.lookup("radius", ATTR_DOMAIN_POINT); + const VArray radii = *attributes.lookup("radius"); static GPUVertFormat format = {0}; if (format.attr_len == 0) { GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); @@ -303,7 +303,7 @@ static void pointcloud_extract_attribute(const PointCloud &pointcloud, * the Blender convention, it should be `vec4(s, s, s, 1)`. This could be resolved using a * similar texture state swizzle to map the attribute correctly as for volume attributes, so we * can control the conversion ourselves. */ - VArray attribute = attributes.lookup_or_default( + bke::AttributeReader attribute = attributes.lookup_or_default( request.attribute_name, request.domain, {0.0f, 0.0f, 0.0f, 1.0f}); static GPUVertFormat format = {0}; @@ -316,7 +316,7 @@ static void pointcloud_extract_attribute(const PointCloud &pointcloud, MutableSpan vbo_data{ static_cast(GPU_vertbuf_get_data(attr_buf)), pointcloud.totpoint}; - attribute.materialize(vbo_data); + attribute.varray.materialize(vbo_data); } /** \} */ diff --git a/source/blender/draw/intern/draw_cache_impl_subdivision.cc b/source/blender/draw/intern/draw_cache_impl_subdivision.cc index 6cfbb84be6d..d63da3d9bd3 100644 --- a/source/blender/draw/intern/draw_cache_impl_subdivision.cc +++ b/source/blender/draw/intern/draw_cache_impl_subdivision.cc @@ -2040,7 +2040,8 @@ static void draw_subdiv_cache_ensure_mat_offsets(DRWSubdivCache *cache, return; } - const blender::VArraySpan material_indices = mesh_eval->attributes().lookup_or_default( + const blender::bke::AttributeAccessor attributes = mesh_eval->attributes(); + const blender::VArraySpan material_indices = *attributes.lookup_or_default( "material_index", ATTR_DOMAIN_FACE, 0); /* Count number of subdivided polygons for each material. */ diff --git a/source/blender/draw/intern/draw_curves.cc b/source/blender/draw/intern/draw_curves.cc index 8a093f949db..f44cd9ca0f4 100644 --- a/source/blender/draw/intern/draw_curves.cc +++ b/source/blender/draw/intern/draw_curves.cc @@ -329,7 +329,7 @@ DRWShadingGroup *DRW_shgroup_curves_create_sub(Object *object, * use for now because we can't use a per-point radius yet. */ const blender::bke::CurvesGeometry &curves = curves_id.geometry.wrap(); if (curves.curves_num() >= 1) { - blender::VArray radii = curves.attributes().lookup_or_default( + blender::VArray radii = *curves.attributes().lookup_or_default( "radius", ATTR_DOMAIN_POINT, 0.005f); const blender::IndexRange first_curve_points = curves.points_by_curve()[0]; const float first_radius = radii[first_curve_points.first()]; diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_attributes.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_attributes.cc index dc1c5335763..a2ad86f7651 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_attributes.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_attributes.cc @@ -438,9 +438,9 @@ static void extract_mesh_attr_viewer_init(const MeshRenderData *mr, const StringRefNull attr_name = ".viewer"; const bke::AttributeAccessor attributes = mr->me->attributes(); - attributes - .lookup_or_default(attr_name, ATTR_DOMAIN_CORNER, {1.0f, 0.0f, 1.0f, 1.0f}) - .materialize(attr); + const bke::AttributeReader attribute = attributes.lookup_or_default( + attr_name, ATTR_DOMAIN_CORNER, {1.0f, 0.0f, 1.0f, 1.0f}); + attribute.varray.materialize(attr); } constexpr MeshExtract create_extractor_attr_viewer() diff --git a/source/blender/editors/curves/intern/curves_edit.cc b/source/blender/editors/curves/intern/curves_edit.cc index 9d5e7730ba0..b9151b10ad5 100644 --- a/source/blender/editors/curves/intern/curves_edit.cc +++ b/source/blender/editors/curves/intern/curves_edit.cc @@ -15,7 +15,7 @@ namespace blender::ed::curves { bool remove_selection(bke::CurvesGeometry &curves, const eAttrDomain selection_domain) { const bke::AttributeAccessor attributes = curves.attributes(); - const VArray selection = attributes.lookup_or_default( + const VArray selection = *attributes.lookup_or_default( ".selection", selection_domain, true); const int domain_size_orig = attributes.domain_size(selection_domain); Vector indices; diff --git a/source/blender/editors/curves/intern/curves_ops.cc b/source/blender/editors/curves/intern/curves_ops.cc index 196bfc15b0e..6b09a7233c5 100644 --- a/source/blender/editors/curves/intern/curves_ops.cc +++ b/source/blender/editors/curves/intern/curves_ops.cc @@ -585,9 +585,8 @@ static void snap_curves_to_surface_exec_object(Object &curves_ob, VArraySpan surface_uv_map; if (curves_id.surface_uv_map != nullptr) { const bke::AttributeAccessor surface_attributes = surface_mesh.attributes(); - surface_uv_map = surface_attributes - .lookup(curves_id.surface_uv_map, ATTR_DOMAIN_CORNER, CD_PROP_FLOAT2) - .typed(); + surface_uv_map = *surface_attributes.lookup(curves_id.surface_uv_map, + ATTR_DOMAIN_CORNER); } const OffsetIndices points_by_curve = curves.points_by_curve(); @@ -795,7 +794,7 @@ static int curves_set_selection_domain_exec(bContext *C, wmOperator *op) continue; } - if (const GVArray src = attributes.lookup(".selection", domain)) { + if (const GVArray src = *attributes.lookup(".selection", domain)) { const CPPType &type = src.type(); void *dst = MEM_malloc_arrayN(attributes.domain_size(domain), type.size(), __func__); src.materialize(dst); @@ -804,7 +803,7 @@ static int curves_set_selection_domain_exec(bContext *C, wmOperator *op) if (!attributes.add(".selection", domain, bke::cpp_type_to_custom_data_type(type), - bke::AttributeInitMoveArray(dst))) { + bke::AttributeInitData(dst, nullptr))) { MEM_freeN(dst); } } diff --git a/source/blender/editors/curves/intern/curves_selection.cc b/source/blender/editors/curves/intern/curves_selection.cc index 16c9e074815..8b2e5aec326 100644 --- a/source/blender/editors/curves/intern/curves_selection.cc +++ b/source/blender/editors/curves/intern/curves_selection.cc @@ -34,7 +34,7 @@ static IndexMask retrieve_selected_curves(const bke::CurvesGeometry &curves, if (meta_data && meta_data->domain == ATTR_DOMAIN_POINT) { /* Avoid the interpolation from interpolating the attribute to the * curve domain by retrieving the point domain values directly. */ - const VArray selection = attributes.lookup_or_default( + const VArray selection = *attributes.lookup_or_default( ".selection", ATTR_DOMAIN_POINT, true); if (selection.is_single()) { return selection.get_internal_single() ? IndexMask(curves_range) : IndexMask(); @@ -49,7 +49,7 @@ static IndexMask retrieve_selected_curves(const bke::CurvesGeometry &curves, return point_selection.as_span().contains(true); }); } - const VArray selection = attributes.lookup_or_default( + const VArray selection = *attributes.lookup_or_default( ".selection", ATTR_DOMAIN_CURVE, true); return index_mask_ops::find_indices_from_virtual_array(curves_range, selection, 2048, r_indices); } @@ -64,7 +64,7 @@ IndexMask retrieve_selected_points(const bke::CurvesGeometry &curves, Vector(".selection", ATTR_DOMAIN_POINT, true), + *curves.attributes().lookup_or_default(".selection", ATTR_DOMAIN_POINT, true), 2048, r_indices); } @@ -166,7 +166,7 @@ bool has_anything_selected(const VArray &varray, const IndexRange range_to bool has_anything_selected(const bke::CurvesGeometry &curves) { - const VArray selection = curves.attributes().lookup(".selection"); + const VArray selection = *curves.attributes().lookup(".selection"); return !selection || contains(selection, selection.index_range(), true); } diff --git a/source/blender/editors/geometry/geometry_attributes.cc b/source/blender/editors/geometry/geometry_attributes.cc index 3eb3c538ff7..872404047db 100644 --- a/source/blender/editors/geometry/geometry_attributes.cc +++ b/source/blender/editors/geometry/geometry_attributes.cc @@ -270,7 +270,7 @@ static int geometry_attribute_convert_exec(bContext *C, wmOperator *op) } case ConvertAttributeMode::VertexGroup: { Array src_weights(mesh->totvert); - VArray src_varray = attributes.lookup_or_default( + VArray src_varray = *attributes.lookup_or_default( name, ATTR_DOMAIN_POINT, 0.0f); src_varray.materialize(src_weights); attributes.remove(name); @@ -703,13 +703,16 @@ bool ED_geometry_attribute_convert(Mesh *mesh, } const std::string name_copy = name; - const GVArray varray = attributes.lookup_or_default(name_copy, dst_domain, dst_type); + const GVArray varray = *attributes.lookup_or_default(name_copy, dst_domain, dst_type); const CPPType &cpp_type = varray.type(); void *new_data = MEM_malloc_arrayN(varray.size(), cpp_type.size(), __func__); varray.materialize_to_uninitialized(new_data); attributes.remove(name_copy); - attributes.add(name_copy, dst_domain, dst_type, bke::AttributeInitMoveArray(new_data)); + if (!attributes.add( + name_copy, dst_domain, dst_type, bke::AttributeInitData(new_data, nullptr))) { + MEM_freeN(new_data); + } return true; } diff --git a/source/blender/editors/mesh/editface.cc b/source/blender/editors/mesh/editface.cc index 835c6c942cb..151272ca212 100644 --- a/source/blender/editors/mesh/editface.cc +++ b/source/blender/editors/mesh/editface.cc @@ -80,7 +80,7 @@ void paintface_flush_flags(bContext *C, if (me_orig != nullptr && me_eval != nullptr && me_orig->totpoly == me->totpoly) { /* Update the COW copy of the mesh. */ if (flush_hidden) { - const VArray hide_poly_me = attributes_me.lookup_or_default( + const VArray hide_poly_me = *attributes_me.lookup_or_default( ".hide_poly", ATTR_DOMAIN_FACE, false); bke::SpanAttributeWriter hide_poly_orig = attributes_orig.lookup_or_add_for_write_only_span(".hide_poly", ATTR_DOMAIN_FACE); @@ -88,7 +88,7 @@ void paintface_flush_flags(bContext *C, hide_poly_orig.finish(); } if (flush_selection) { - const VArray select_poly_me = attributes_me.lookup_or_default( + const VArray select_poly_me = *attributes_me.lookup_or_default( ".select_poly", ATTR_DOMAIN_FACE, false); bke::SpanAttributeWriter select_poly_orig = attributes_orig.lookup_or_add_for_write_only_span(".select_poly", @@ -100,7 +100,7 @@ void paintface_flush_flags(bContext *C, /* Mesh polys => Final derived polys */ if ((index_array = (const int *)CustomData_get_layer(&me_eval->pdata, CD_ORIGINDEX))) { if (flush_hidden) { - const VArray hide_poly_orig = attributes_orig.lookup_or_default( + const VArray hide_poly_orig = *attributes_orig.lookup_or_default( ".hide_poly", ATTR_DOMAIN_FACE, false); bke::SpanAttributeWriter hide_poly_eval = attributes_eval.lookup_or_add_for_write_only_span(".hide_poly", @@ -114,7 +114,7 @@ void paintface_flush_flags(bContext *C, hide_poly_eval.finish(); } if (flush_selection) { - const VArray select_poly_orig = attributes_orig.lookup_or_default( + const VArray select_poly_orig = *attributes_orig.lookup_or_default( ".select_poly", ATTR_DOMAIN_FACE, false); bke::SpanAttributeWriter select_poly_eval = attributes_eval.lookup_or_add_for_write_only_span(".select_poly", @@ -194,7 +194,7 @@ void paintface_reveal(bContext *C, Object *ob, const bool select) bke::MutableAttributeAccessor attributes = me->attributes_for_write(); if (select) { - const VArray hide_poly = attributes.lookup_or_default( + const VArray hide_poly = *attributes.lookup_or_default( ".hide_poly", ATTR_DOMAIN_FACE, false); bke::SpanAttributeWriter select_poly = attributes.lookup_or_add_for_write_span( ".select_poly", ATTR_DOMAIN_FACE); @@ -228,9 +228,9 @@ static void build_poly_connections(blender::AtomicDisjointSet &islands, const Span corner_edges = mesh.corner_edges(); const bke::AttributeAccessor attributes = mesh.attributes(); - const VArray uv_seams = attributes.lookup_or_default( + const VArray uv_seams = *attributes.lookup_or_default( ".uv_seam", ATTR_DOMAIN_EDGE, false); - const VArray hide_poly = attributes.lookup_or_default( + const VArray hide_poly = *attributes.lookup_or_default( ".hide_poly", ATTR_DOMAIN_FACE, false); /* Polys are connected if they share edges. By connecting all edges of a loop (as long as they @@ -277,7 +277,7 @@ static void paintface_select_linked_faces(Mesh &mesh, const Span corner_edges = mesh.corner_edges(); bke::MutableAttributeAccessor attributes = mesh.attributes_for_write(); - const VArray uv_seams = attributes.lookup_or_default( + const VArray uv_seams = *attributes.lookup_or_default( ".uv_seam", ATTR_DOMAIN_EDGE, false); bke::SpanAttributeWriter select_poly = attributes.lookup_or_add_for_write_span( ".select_poly", ATTR_DOMAIN_FACE); @@ -380,7 +380,7 @@ void paintface_select_more(Mesh *mesh, const bool face_step) ".select_poly", ATTR_DOMAIN_FACE); bke::SpanAttributeWriter select_vert = attributes.lookup_or_add_for_write_span( ".select_vert", ATTR_DOMAIN_POINT); - const VArray hide_poly = attributes.lookup_or_default( + const VArray hide_poly = *attributes.lookup_or_default( ".hide_poly", ATTR_DOMAIN_FACE, false); const OffsetIndices polys = mesh->polys(); @@ -432,7 +432,7 @@ void paintface_select_less(Mesh *mesh, const bool face_step) bke::MutableAttributeAccessor attributes = mesh->attributes_for_write(); bke::SpanAttributeWriter select_poly = attributes.lookup_or_add_for_write_span( ".select_poly", ATTR_DOMAIN_FACE); - const VArray hide_poly = attributes.lookup_or_default( + const VArray hide_poly = *attributes.lookup_or_default( ".hide_poly", ATTR_DOMAIN_FACE, false); const OffsetIndices polys = mesh->polys(); @@ -478,7 +478,7 @@ bool paintface_deselect_all_visible(bContext *C, Object *ob, int action, bool fl } bke::MutableAttributeAccessor attributes = me->attributes_for_write(); - const VArray hide_poly = attributes.lookup_or_default( + const VArray hide_poly = *attributes.lookup_or_default( ".hide_poly", ATTR_DOMAIN_FACE, false); bke::SpanAttributeWriter select_poly = attributes.lookup_or_add_for_write_span( ".select_poly", ATTR_DOMAIN_FACE); @@ -545,9 +545,9 @@ bool paintface_minmax(Object *ob, float r_min[3], float r_max[3]) const OffsetIndices polys = me->polys(); const Span corner_verts = me->corner_verts(); bke::AttributeAccessor attributes = me->attributes(); - const VArray hide_poly = attributes.lookup_or_default( + const VArray hide_poly = *attributes.lookup_or_default( ".hide_poly", ATTR_DOMAIN_FACE, false); - const VArray select_poly = attributes.lookup_or_default( + const VArray select_poly = *attributes.lookup_or_default( ".select_poly", ATTR_DOMAIN_FACE, false); for (int i = 0; i < me->totpoly; i++) { @@ -581,7 +581,7 @@ bool paintface_mouse_select(bContext *C, Mesh *me = BKE_mesh_from_object(ob); bke::MutableAttributeAccessor attributes = me->attributes_for_write(); - const VArray hide_poly = attributes.lookup_or_default( + const VArray hide_poly = *attributes.lookup_or_default( ".hide_poly", ATTR_DOMAIN_FACE, false); bke::AttributeWriter select_poly = attributes.lookup_or_add_for_write( ".select_poly", ATTR_DOMAIN_FACE); @@ -656,7 +656,7 @@ void paintvert_flush_flags(Object *ob) const int *orig_indices = (const int *)CustomData_get_layer(&me_eval->vdata, CD_ORIGINDEX); - const VArray hide_vert_orig = attributes_orig.lookup_or_default( + const VArray hide_vert_orig = *attributes_orig.lookup_or_default( ".hide_vert", ATTR_DOMAIN_POINT, false); bke::SpanAttributeWriter hide_vert_eval = attributes_eval.lookup_or_add_for_write_only_span(".hide_vert", ATTR_DOMAIN_POINT); @@ -672,7 +672,7 @@ void paintvert_flush_flags(Object *ob) } hide_vert_eval.finish(); - const VArray select_vert_orig = attributes_orig.lookup_or_default( + const VArray select_vert_orig = *attributes_orig.lookup_or_default( ".select_vert", ATTR_DOMAIN_POINT, false); bke::SpanAttributeWriter select_vert_eval = attributes_eval.lookup_or_add_for_write_only_span(".select_vert", ATTR_DOMAIN_POINT); @@ -784,9 +784,9 @@ void paintvert_select_more(Mesh *mesh, const bool face_step) bke::MutableAttributeAccessor attributes = mesh->attributes_for_write(); bke::SpanAttributeWriter select_vert = attributes.lookup_or_add_for_write_span( ".select_vert", ATTR_DOMAIN_POINT); - const VArray hide_edge = attributes.lookup_or_default( + const VArray hide_edge = *attributes.lookup_or_default( ".hide_edge", ATTR_DOMAIN_EDGE, false); - const VArray hide_poly = attributes.lookup_or_default( + const VArray hide_poly = *attributes.lookup_or_default( ".hide_poly", ATTR_DOMAIN_FACE, false); const OffsetIndices polys = mesh->polys(); @@ -840,9 +840,9 @@ void paintvert_select_less(Mesh *mesh, const bool face_step) bke::MutableAttributeAccessor attributes = mesh->attributes_for_write(); bke::SpanAttributeWriter select_vert = attributes.lookup_or_add_for_write_span( ".select_vert", ATTR_DOMAIN_POINT); - const VArray hide_edge = attributes.lookup_or_default( + const VArray hide_edge = *attributes.lookup_or_default( ".hide_edge", ATTR_DOMAIN_EDGE, false); - const VArray hide_poly = attributes.lookup_or_default( + const VArray hide_poly = *attributes.lookup_or_default( ".hide_poly", ATTR_DOMAIN_FACE, false); const OffsetIndices polys = mesh->polys(); @@ -911,7 +911,7 @@ bool paintvert_deselect_all_visible(Object *ob, int action, bool flush_flags) } bke::MutableAttributeAccessor attributes = me->attributes_for_write(); - const VArray hide_vert = attributes.lookup_or_default( + const VArray hide_vert = *attributes.lookup_or_default( ".hide_vert", ATTR_DOMAIN_POINT, false); bke::SpanAttributeWriter select_vert = attributes.lookup_or_add_for_write_span( ".select_vert", ATTR_DOMAIN_POINT); @@ -987,7 +987,7 @@ void paintvert_select_ungrouped(Object *ob, bool extend, bool flush_flags) } bke::MutableAttributeAccessor attributes = me->attributes_for_write(); - const VArray hide_vert = attributes.lookup_or_default( + const VArray hide_vert = *attributes.lookup_or_default( ".hide_vert", ATTR_DOMAIN_POINT, false); bke::SpanAttributeWriter select_vert = attributes.lookup_or_add_for_write_span( ".select_vert", ATTR_DOMAIN_POINT); @@ -1051,7 +1051,7 @@ void paintvert_reveal(bContext *C, Object *ob, const bool select) } bke::MutableAttributeAccessor attributes = me->attributes_for_write(); - const VArray hide_vert = attributes.lookup_or_default( + const VArray hide_vert = *attributes.lookup_or_default( ".hide_vert", ATTR_DOMAIN_POINT, false); bke::SpanAttributeWriter select_vert = attributes.lookup_or_add_for_write_span( ".select_vert", ATTR_DOMAIN_POINT); diff --git a/source/blender/editors/mesh/mesh_data.cc b/source/blender/editors/mesh/mesh_data.cc index 0630dfed7d5..74948de6492 100644 --- a/source/blender/editors/mesh/mesh_data.cc +++ b/source/blender/editors/mesh/mesh_data.cc @@ -1481,7 +1481,7 @@ void ED_mesh_split_faces(Mesh *mesh) const Span corner_edges = mesh->corner_edges(); const float split_angle = (mesh->flag & ME_AUTOSMOOTH) != 0 ? mesh->smoothresh : float(M_PI); const bke::AttributeAccessor attributes = mesh->attributes(); - const VArray mesh_sharp_edges = attributes.lookup_or_default( + const VArray mesh_sharp_edges = *attributes.lookup_or_default( "sharp_edge", ATTR_DOMAIN_EDGE, false); const bool *sharp_faces = static_cast( CustomData_get_layer_named(&mesh->pdata, CD_PROP_BOOL, "sharp_face")); diff --git a/source/blender/editors/object/object_remesh.cc b/source/blender/editors/object/object_remesh.cc index 4c4f845d841..f9bad0c6e06 100644 --- a/source/blender/editors/object/object_remesh.cc +++ b/source/blender/editors/object/object_remesh.cc @@ -135,7 +135,7 @@ static int voxel_remesh_exec(bContext *C, wmOperator *op) /* Output mesh will be all smooth or all flat shading. */ const bke::AttributeAccessor attributes = mesh->attributes(); - const VArray sharp_faces = attributes.lookup_or_default( + const VArray sharp_faces = *attributes.lookup_or_default( "sharp_face", ATTR_DOMAIN_FACE, false); const bool smooth_normals = !sharp_faces[0]; diff --git a/source/blender/editors/object/object_vgroup.cc b/source/blender/editors/object/object_vgroup.cc index 1cff9966afe..55e7e71b9e2 100644 --- a/source/blender/editors/object/object_vgroup.cc +++ b/source/blender/editors/object/object_vgroup.cc @@ -211,7 +211,7 @@ bool ED_vgroup_parray_alloc(ID *id, if (use_vert_sel) { const bke::AttributeAccessor attributes = me->attributes(); - const VArray select_vert = attributes.lookup_or_default( + const VArray select_vert = *attributes.lookup_or_default( ".select_vert", ATTR_DOMAIN_POINT, false); for (int i = 0; i < me->totvert; i++) { @@ -671,7 +671,7 @@ static void vgroup_copy_active_to_sel(Object *ob, eVGroupSelect subset_type) } else { const bke::AttributeAccessor attributes = me->attributes(); - const VArray select_vert = attributes.lookup_or_default( + const VArray select_vert = *attributes.lookup_or_default( ".select_vert", ATTR_DOMAIN_POINT, false); int v_act; @@ -1063,7 +1063,7 @@ static void vgroup_select_verts(Object *ob, int select) const Span dverts = me->deform_verts(); if (!dverts.is_empty()) { bke::MutableAttributeAccessor attributes = me->attributes_for_write(); - const VArray hide_vert = attributes.lookup_or_default( + const VArray hide_vert = *attributes.lookup_or_default( ".hide_vert", ATTR_DOMAIN_POINT, false); bke::SpanAttributeWriter select_vert = attributes.lookup_or_add_for_write_only_span(".select_vert", ATTR_DOMAIN_POINT); @@ -1628,7 +1628,7 @@ static void vgroup_smooth_subset(Object *ob, } else { const bke::AttributeAccessor attributes = me->attributes(); - const VArray select_vert = attributes.lookup_or_default( + const VArray select_vert = *attributes.lookup_or_default( ".select_vert", ATTR_DOMAIN_POINT, false); const blender::Span edges = me->edges(); @@ -1704,7 +1704,7 @@ static void vgroup_smooth_subset(Object *ob, } else { const bke::AttributeAccessor attributes = me->attributes(); - const VArray select_vert = attributes.lookup_or_default( + const VArray select_vert = *attributes.lookup_or_default( ".select_vert", ATTR_DOMAIN_POINT, false); int j; @@ -2118,7 +2118,7 @@ void ED_vgroup_mirror(Object *ob, BLI_bitmap *vert_tag = BLI_BITMAP_NEW(me->totvert, __func__); MutableSpan dverts = me->deform_verts_for_write(); const bke::AttributeAccessor attributes = me->attributes(); - const VArray select_vert = attributes.lookup_or_default( + const VArray select_vert = *attributes.lookup_or_default( ".select_vert", ATTR_DOMAIN_POINT, false); for (int vidx = 0; vidx < me->totvert; vidx++) { @@ -2278,7 +2278,7 @@ static void vgroup_assign_verts(Object *ob, const float weight) } else { const bke::AttributeAccessor attributes = me->attributes(); - const VArray select_vert = attributes.lookup_or_default( + const VArray select_vert = *attributes.lookup_or_default( ".select_vert", ATTR_DOMAIN_POINT, false); MutableSpan dverts = me->deform_verts_for_write(); @@ -3907,7 +3907,7 @@ static void vgroup_copy_active_to_sel_single(Object *ob, const int def_nr) MutableSpan dverts = me->deform_verts_for_write(); const bke::AttributeAccessor attributes = me->attributes(); - const VArray select_vert = attributes.lookup_or_default( + const VArray select_vert = *attributes.lookup_or_default( ".select_vert", ATTR_DOMAIN_POINT, false); for (i = 0; i < me->totvert; i++) { diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_add.cc b/source/blender/editors/sculpt_paint/curves_sculpt_add.cc index b86d7cd4a9a..d7531a6bc70 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_add.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_add.cc @@ -164,9 +164,9 @@ struct AddOperationExecutor { /* Find UV map. */ VArraySpan surface_uv_map; if (curves_id_orig_->surface_uv_map != nullptr) { - surface_uv_map = surface_orig.attributes().lookup(curves_id_orig_->surface_uv_map, - ATTR_DOMAIN_CORNER); - surface_uv_map_eval_ = surface_eval_->attributes().lookup( + surface_uv_map = *surface_orig.attributes().lookup(curves_id_orig_->surface_uv_map, + ATTR_DOMAIN_CORNER); + surface_uv_map_eval_ = *surface_eval_->attributes().lookup( curves_id_orig_->surface_uv_map, ATTR_DOMAIN_CORNER); } diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_comb.cc b/source/blender/editors/sculpt_paint/curves_sculpt_comb.cc index 6a28b891e54..f63cef873e0 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_comb.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_comb.cc @@ -133,7 +133,7 @@ struct CombOperationExecutor { transforms_ = CurvesSurfaceTransforms(*curves_ob_orig_, curves_id_orig_->surface); - point_factors_ = curves_orig_->attributes().lookup_or_default( + point_factors_ = *curves_orig_->attributes().lookup_or_default( ".selection", ATTR_DOMAIN_POINT, 1.0f); curve_selection_ = curves::retrieve_selected_curves(*curves_id_orig_, selected_curve_indices_); diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_density.cc b/source/blender/editors/sculpt_paint/curves_sculpt_density.cc index dda6707b001..11da2fb15c4 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_density.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_density.cc @@ -134,9 +134,9 @@ struct DensityAddOperationExecutor { /* Find UV map. */ VArraySpan surface_uv_map; if (curves_id_orig_->surface_uv_map != nullptr) { - surface_uv_map = surface_orig_->attributes().lookup(curves_id_orig_->surface_uv_map, - ATTR_DOMAIN_CORNER); - surface_uv_map_eval_ = surface_eval_->attributes().lookup( + surface_uv_map = *surface_orig_->attributes().lookup(curves_id_orig_->surface_uv_map, + ATTR_DOMAIN_CORNER); + surface_uv_map_eval_ = *surface_eval_->attributes().lookup( curves_id_orig_->surface_uv_map, ATTR_DOMAIN_CORNER); } if (surface_uv_map.is_empty()) { diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_grow_shrink.cc b/source/blender/editors/sculpt_paint/curves_sculpt_grow_shrink.cc index 8006f4bbd59..bb733f8453e 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_grow_shrink.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_grow_shrink.cc @@ -277,7 +277,7 @@ struct CurvesEffectOperationExecutor { return; } - curve_selection_factors_ = curves_->attributes().lookup_or_default( + curve_selection_factors_ = *curves_->attributes().lookup_or_default( ".selection", ATTR_DOMAIN_CURVE, 1.0f); curve_selection_ = curves::retrieve_selected_curves(*curves_id_, selected_curve_indices_); diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_pinch.cc b/source/blender/editors/sculpt_paint/curves_sculpt_pinch.cc index 9a630b835d6..8df28efe171 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_pinch.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_pinch.cc @@ -105,7 +105,7 @@ struct PinchOperationExecutor { transforms_ = CurvesSurfaceTransforms(*object_, curves_id_->surface); - point_factors_ = curves_->attributes().lookup_or_default( + point_factors_ = *curves_->attributes().lookup_or_default( ".selection", ATTR_DOMAIN_POINT, 1.0f); curve_selection_ = curves::retrieve_selected_curves(*curves_id_, selected_curve_indices_); diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_puff.cc b/source/blender/editors/sculpt_paint/curves_sculpt_puff.cc index c00e45e1916..2aea6a073c5 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_puff.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_puff.cc @@ -104,7 +104,7 @@ struct PuffOperationExecutor { brush_strength_ = brush_strength_get(*ctx_.scene, *brush_, stroke_extension); brush_pos_re_ = stroke_extension.mouse_position; - point_factors_ = curves_->attributes().lookup_or_default( + point_factors_ = *curves_->attributes().lookup_or_default( ".selection", ATTR_DOMAIN_POINT, 1.0f); curve_selection_ = curves::retrieve_selected_curves(*curves_id_, selected_curve_indices_); diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_selection.cc b/source/blender/editors/sculpt_paint/curves_sculpt_selection.cc index 73472e86023..da6cdec32d0 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_selection.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_selection.cc @@ -18,14 +18,14 @@ bke::SpanAttributeWriter float_selection_ensure(Curves &curves_id) if (const auto meta_data = attributes.lookup_meta_data(".selection")) { if (meta_data->data_type == CD_PROP_BOOL) { - const VArray selection = attributes.lookup(".selection"); + const VArray selection = *attributes.lookup(".selection"); float *dst = static_cast( MEM_malloc_arrayN(selection.size(), sizeof(float), __func__)); selection.materialize({dst, selection.size()}); attributes.remove(".selection"); attributes.add( - ".selection", meta_data->domain, CD_PROP_FLOAT, bke::AttributeInitMoveArray(dst)); + ".selection", meta_data->domain, CD_PROP_FLOAT, bke::AttributeInitData(dst, nullptr)); } } else { diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_slide.cc b/source/blender/editors/sculpt_paint/curves_sculpt_slide.cc index 810daf0b4d2..0da248ea175 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_slide.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_slide.cc @@ -155,7 +155,7 @@ struct SlideOperationExecutor { brush_radius_factor_ = brush_radius_factor(*brush_, stroke_extension); brush_strength_ = brush_strength_get(*ctx_.scene, *brush_, stroke_extension); - curve_factors_ = curves_orig_->attributes().lookup_or_default( + curve_factors_ = *curves_orig_->attributes().lookup_or_default( ".selection", ATTR_DOMAIN_CURVE, 1.0f); curve_selection_ = curves::retrieve_selected_curves(*curves_id_orig_, selected_curve_indices_); @@ -170,8 +170,8 @@ struct SlideOperationExecutor { return; } surface_looptris_orig_ = surface_orig_->looptris(); - surface_uv_map_orig_ = surface_orig_->attributes().lookup(uv_map_name, - ATTR_DOMAIN_CORNER); + surface_uv_map_orig_ = *surface_orig_->attributes().lookup(uv_map_name, + ATTR_DOMAIN_CORNER); if (surface_uv_map_orig_.is_empty()) { report_missing_uv_map_on_original_surface(stroke_extension.reports); return; @@ -198,8 +198,8 @@ struct SlideOperationExecutor { surface_looptris_eval_ = surface_eval_->looptris(); surface_positions_eval_ = surface_eval_->vert_positions(); surface_corner_verts_eval_ = surface_eval_->corner_verts(); - surface_uv_map_eval_ = surface_eval_->attributes().lookup(uv_map_name, - ATTR_DOMAIN_CORNER); + surface_uv_map_eval_ = *surface_eval_->attributes().lookup(uv_map_name, + ATTR_DOMAIN_CORNER); if (surface_uv_map_eval_.is_empty()) { report_missing_uv_map_on_evaluated_surface(stroke_extension.reports); return; diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_smooth.cc b/source/blender/editors/sculpt_paint/curves_sculpt_smooth.cc index e8dcc0ff88e..f032de83548 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_smooth.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_smooth.cc @@ -77,7 +77,7 @@ struct SmoothOperationExecutor { brush_strength_ = brush_strength_get(*ctx_.scene, *brush_, stroke_extension); brush_pos_re_ = stroke_extension.mouse_position; - point_factors_ = curves_->attributes().lookup_or_default( + point_factors_ = *curves_->attributes().lookup_or_default( ".selection", ATTR_DOMAIN_POINT, 1.0f); curve_selection_ = curves::retrieve_selected_curves(*curves_id_, selected_curve_indices_); transforms_ = CurvesSurfaceTransforms(*object_, curves_id_->surface); diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_snake_hook.cc b/source/blender/editors/sculpt_paint/curves_sculpt_snake_hook.cc index a5990fadfe7..e794093bbc5 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_snake_hook.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_snake_hook.cc @@ -123,7 +123,7 @@ struct SnakeHookOperatorExecutor { transforms_ = CurvesSurfaceTransforms(*object_, curves_id_->surface); - curve_factors_ = curves_->attributes().lookup_or_default( + curve_factors_ = *curves_->attributes().lookup_or_default( ".selection", ATTR_DOMAIN_CURVE, 1.0f); curve_selection_ = curves::retrieve_selected_curves(*curves_id_, selected_curve_indices_); diff --git a/source/blender/editors/sculpt_paint/paint_vertex.cc b/source/blender/editors/sculpt_paint/paint_vertex.cc index 10eeb2a63e4..0f313aa6029 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.cc +++ b/source/blender/editors/sculpt_paint/paint_vertex.cc @@ -137,7 +137,7 @@ struct NormalAnglePrecalc { /* Returns number of elements. */ static int get_vcol_elements(Mesh *me, size_t *r_elem_size) { - const std::optional meta_data = me->attributes().lookup_meta_data( + const std::optional meta_data = *me->attributes().lookup_meta_data( me->active_color_attribute); if (r_elem_size) { @@ -1953,7 +1953,7 @@ static void do_wpaint_brush_blur_task_cb_ex(void *__restrict userdata, ss, data->brush->falloff_shape); const blender::bke::AttributeAccessor attributes = data->me->attributes(); - const blender::VArray select_vert = attributes.lookup_or_default( + const blender::VArray select_vert = *attributes.lookup_or_default( ".select_vert", ATTR_DOMAIN_POINT, false); /* For each vertex */ @@ -2042,7 +2042,7 @@ static void do_wpaint_brush_smear_task_cb_ex(void *__restrict userdata, project_plane_v3_v3v3(brush_dir, brush_dir, cache->view_normal); const blender::bke::AttributeAccessor attributes = data->me->attributes(); - const blender::VArray select_vert = attributes.lookup_or_default( + const blender::VArray select_vert = *attributes.lookup_or_default( ".select_vert", ATTR_DOMAIN_POINT, false); if (cache->is_last_valid && (normalize_v3(brush_dir) != 0.0f)) { @@ -2157,7 +2157,7 @@ static void do_wpaint_brush_draw_task_cb_ex(void *__restrict userdata, ss, data->brush->falloff_shape); const blender::bke::AttributeAccessor attributes = data->me->attributes(); - const blender::VArray select_vert = attributes.lookup_or_default( + const blender::VArray select_vert = *attributes.lookup_or_default( ".select_vert", ATTR_DOMAIN_POINT, false); /* For each vertex */ @@ -2228,7 +2228,7 @@ static void do_wpaint_brush_calc_average_weight_cb_ex(void *__restrict userdata, ss, data->brush->falloff_shape); const blender::bke::AttributeAccessor attributes = data->me->attributes(); - const blender::VArray select_vert = attributes.lookup_or_default( + const blender::VArray select_vert = *attributes.lookup_or_default( ".select_vert", ATTR_DOMAIN_POINT, false); /* For each vertex */ @@ -2859,7 +2859,7 @@ static void *vpaint_init_vpaint(bContext *C, vpd->is_texbrush = !(brush->vertexpaint_tool == VPAINT_TOOL_BLUR) && brush->mtex.tex; if (brush->vertexpaint_tool == VPAINT_TOOL_SMEAR) { - const GVArray attribute = me->attributes().lookup(me->active_color_attribute, domain); + const GVArray attribute = *me->attributes().lookup(me->active_color_attribute, domain); vpd->smear.color_prev = MEM_malloc_arrayN(attribute.size(), attribute.type().size(), __func__); attribute.materialize(vpd->smear.color_prev); @@ -2896,7 +2896,7 @@ static bool vpaint_stroke_test_start(bContext *C, wmOperator *op, const float mo ED_mesh_color_ensure(me, nullptr); - const std::optional meta_data = me->attributes().lookup_meta_data( + const std::optional meta_data = *me->attributes().lookup_meta_data( me->active_color_attribute); if (!meta_data) { @@ -2957,9 +2957,9 @@ static void do_vpaint_brush_blur_loops(bContext *C, Color *previous_color = static_cast(ss->cache->prev_colors_vpaint); - const blender::VArray select_vert = me->attributes().lookup_or_default( + const blender::VArray select_vert = *me->attributes().lookup_or_default( ".select_vert", ATTR_DOMAIN_POINT, false); - const blender::VArray select_poly = me->attributes().lookup_or_default( + const blender::VArray select_poly = *me->attributes().lookup_or_default( ".select_poly", ATTR_DOMAIN_FACE, false); blender::threading::parallel_for(nodes.index_range(), 1LL, [&](IndexRange range) { @@ -3100,9 +3100,9 @@ static void do_vpaint_brush_blur_verts(bContext *C, Color *previous_color = static_cast(ss->cache->prev_colors_vpaint); - const blender::VArray select_vert = me->attributes().lookup_or_default( + const blender::VArray select_vert = *me->attributes().lookup_or_default( ".select_vert", ATTR_DOMAIN_POINT, false); - const blender::VArray select_poly = me->attributes().lookup_or_default( + const blender::VArray select_poly = *me->attributes().lookup_or_default( ".select_poly", ATTR_DOMAIN_FACE, false); blender::threading::parallel_for(nodes.index_range(), 1LL, [&](IndexRange range) { @@ -3248,9 +3248,9 @@ static void do_vpaint_brush_smear(bContext *C, Color *color_prev_smear = static_cast(vpd->smear.color_prev); Color *color_prev = reinterpret_cast(ss->cache->prev_colors_vpaint); - const blender::VArray select_vert = me->attributes().lookup_or_default( + const blender::VArray select_vert = *me->attributes().lookup_or_default( ".select_vert", ATTR_DOMAIN_POINT, false); - const blender::VArray select_poly = me->attributes().lookup_or_default( + const blender::VArray select_poly = *me->attributes().lookup_or_default( ".select_poly", ATTR_DOMAIN_FACE, false); blender::threading::parallel_for(nodes.index_range(), 1LL, [&](IndexRange range) { @@ -3415,7 +3415,7 @@ static void calculate_average_color(VPaintData *vpd, { using Blend = typename Traits::BlendType; - const blender::VArray select_vert = me->attributes().lookup_or_default( + const blender::VArray select_vert = *me->attributes().lookup_or_default( ".select_vert", ATTR_DOMAIN_POINT, false); VPaintAverageAccum *accum = (VPaintAverageAccum *)MEM_mallocN( @@ -3532,9 +3532,9 @@ static void vpaint_do_draw(bContext *C, Color *previous_color = static_cast(ss->cache->prev_colors_vpaint); - const blender::VArray select_vert = me->attributes().lookup_or_default( + const blender::VArray select_vert = *me->attributes().lookup_or_default( ".select_vert", ATTR_DOMAIN_POINT, false); - const blender::VArray select_poly = me->attributes().lookup_or_default( + const blender::VArray select_poly = *me->attributes().lookup_or_default( ".select_poly", ATTR_DOMAIN_FACE, false); blender::threading::parallel_for(nodes.index_range(), 1LL, [&](IndexRange range) { @@ -4083,9 +4083,9 @@ static void fill_mesh_face_or_corner_attribute(Mesh &mesh, const bool use_vert_sel, const bool use_face_sel) { - const VArray select_vert = mesh.attributes().lookup_or_default( + const VArray select_vert = *mesh.attributes().lookup_or_default( ".select_vert", ATTR_DOMAIN_POINT, false); - const VArray select_poly = mesh.attributes().lookup_or_default( + const VArray select_poly = *mesh.attributes().lookup_or_default( ".select_poly", ATTR_DOMAIN_FACE, false); const OffsetIndices polys = mesh.polys(); diff --git a/source/blender/editors/sculpt_paint/paint_vertex_color_ops.cc b/source/blender/editors/sculpt_paint/paint_vertex_color_ops.cc index 37423650187..53172b0bd13 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex_color_ops.cc +++ b/source/blender/editors/sculpt_paint/paint_vertex_color_ops.cc @@ -102,7 +102,7 @@ static bool vertex_paint_from_weight(Object *ob) /* Retrieve the vertex group with the domain and type of the existing color * attribute, in order to let the attribute API handle both conversions. */ - const GVArray vertex_group = attributes.lookup( + const GVArray vertex_group = *attributes.lookup( deform_group->name, ATTR_DOMAIN_POINT, bke::cpp_type_to_custom_data_type(color_attribute.varray.type())); @@ -162,13 +162,13 @@ static IndexMask get_selected_indices(const Mesh &mesh, const bke::AttributeAccessor attributes = mesh.attributes(); if (mesh.editflag & ME_EDIT_PAINT_FACE_SEL) { - const VArray selection = attributes.lookup_or_default( + const VArray selection = *attributes.lookup_or_default( ".select_poly", domain, false); return index_mask_ops::find_indices_from_virtual_array( selection.index_range(), selection, 4096, indices); } if (mesh.editflag & ME_EDIT_PAINT_VERT_SEL) { - const VArray selection = attributes.lookup_or_default( + const VArray selection = *attributes.lookup_or_default( ".select_vert", domain, false); return index_mask_ops::find_indices_from_virtual_array( selection.index_range(), selection, 4096, indices); @@ -190,7 +190,7 @@ static void face_corner_color_equalize_verts(Mesh &mesh, const IndexMask selecti return; } - GVArray color_attribute_point = attributes.lookup(name, ATTR_DOMAIN_POINT); + GVArray color_attribute_point = *attributes.lookup(name, ATTR_DOMAIN_POINT); GVArray color_attribute_corner = attributes.adapt_domain( color_attribute_point, ATTR_DOMAIN_POINT, ATTR_DOMAIN_CORNER); color_attribute_corner.materialize(selection, attribute.span.data()); diff --git a/source/blender/editors/sculpt_paint/sculpt_face_set.cc b/source/blender/editors/sculpt_paint/sculpt_face_set.cc index 7c44a22e80d..fb635f3ed5a 100644 --- a/source/blender/editors/sculpt_paint/sculpt_face_set.cc +++ b/source/blender/editors/sculpt_paint/sculpt_face_set.cc @@ -417,7 +417,7 @@ static int sculpt_face_set_create_exec(bContext *C, wmOperator *op) if (mode == SCULPT_FACE_SET_SELECTION) { const bke::AttributeAccessor attributes = mesh->attributes(); - const VArraySpan select_poly = attributes.lookup_or_default( + const VArraySpan select_poly = *attributes.lookup_or_default( ".select_poly", ATTR_DOMAIN_FACE, false); threading::parallel_for(select_poly.index_range(), 4096, [&](const IndexRange range) { for (const int i : range) { @@ -605,7 +605,7 @@ static void sculpt_face_sets_init_loop(Object *ob, const int mode) if (mode == SCULPT_FACE_SETS_FROM_MATERIALS) { const bke::AttributeAccessor attributes = mesh->attributes(); - const VArraySpan material_indices = attributes.lookup_or_default( + const VArraySpan material_indices = *attributes.lookup_or_default( "material_index", ATTR_DOMAIN_FACE, 0); for (const int i : IndexRange(mesh->totpoly)) { ss->face_sets[i] = material_indices[i] + 1; @@ -656,7 +656,7 @@ static int sculpt_face_set_init_exec(bContext *C, wmOperator *op) switch (mode) { case SCULPT_FACE_SETS_FROM_LOOSE_PARTS: { - const VArray hide_poly = attributes.lookup_or_default( + const VArray hide_poly = *attributes.lookup_or_default( ".hide_poly", ATTR_DOMAIN_FACE, false); sculpt_face_sets_init_flood_fill( ob, [&](const int from_face, const int /*edge*/, const int to_face) { @@ -677,7 +677,7 @@ static int sculpt_face_set_init_exec(bContext *C, wmOperator *op) break; } case SCULPT_FACE_SETS_FROM_UV_SEAMS: { - const VArraySpan uv_seams = mesh->attributes().lookup_or_default( + const VArraySpan uv_seams = *mesh->attributes().lookup_or_default( ".uv_seam", ATTR_DOMAIN_EDGE, false); sculpt_face_sets_init_flood_fill( ob, [&](const int /*from_face*/, const int edge, const int /*to_face*/) -> bool { @@ -695,7 +695,7 @@ static int sculpt_face_set_init_exec(bContext *C, wmOperator *op) break; } case SCULPT_FACE_SETS_FROM_SHARP_EDGES: { - const VArraySpan sharp_edges = mesh->attributes().lookup_or_default( + const VArraySpan sharp_edges = *mesh->attributes().lookup_or_default( "sharp_edge", ATTR_DOMAIN_EDGE, false); sculpt_face_sets_init_flood_fill( ob, [&](const int /*from_face*/, const int edge, const int /*to_face*/) -> bool { diff --git a/source/blender/editors/space_view3d/view3d_select.cc b/source/blender/editors/space_view3d/view3d_select.cc index e9e3ccd58a8..dbbe47f73f5 100644 --- a/source/blender/editors/space_view3d/view3d_select.cc +++ b/source/blender/editors/space_view3d/view3d_select.cc @@ -349,7 +349,7 @@ static bool edbm_backbuf_check_and_select_verts_obmode(Mesh *me, bke::MutableAttributeAccessor attributes = me->attributes_for_write(); bke::SpanAttributeWriter select_vert = attributes.lookup_or_add_for_write_span( ".select_vert", ATTR_DOMAIN_POINT); - const VArray hide_vert = attributes.lookup_or_default( + const VArray hide_vert = *attributes.lookup_or_default( ".hide_vert", ATTR_DOMAIN_POINT, false); for (int index = 0; index < me->totvert; index++) { @@ -380,7 +380,7 @@ static bool edbm_backbuf_check_and_select_faces_obmode(Mesh *me, bke::MutableAttributeAccessor attributes = me->attributes_for_write(); bke::SpanAttributeWriter select_poly = attributes.lookup_or_add_for_write_span( ".select_poly", ATTR_DOMAIN_FACE); - const VArray hide_poly = attributes.lookup_or_default( + const VArray hide_poly = *attributes.lookup_or_default( ".hide_poly", ATTR_DOMAIN_FACE, false); for (int index = 0; index < me->totpoly; index++) { diff --git a/source/blender/editors/transform/transform_convert_curves.cc b/source/blender/editors/transform/transform_convert_curves.cc index 9a835bb95a1..0fe2fa84b53 100644 --- a/source/blender/editors/transform/transform_convert_curves.cc +++ b/source/blender/editors/transform/transform_convert_curves.cc @@ -101,7 +101,7 @@ static void createTransCurvesVerts(bContext * /*C*/, TransInfo *t) MutableSpan positions = curves.positions_for_write(); if (use_proportional_edit) { const OffsetIndices points_by_curve = curves.points_by_curve(); - const VArray selection = curves.attributes().lookup_or_default( + const VArray selection = *curves.attributes().lookup_or_default( ".selection", ATTR_DOMAIN_POINT, true); threading::parallel_for(curves.curves_range(), 512, [&](const IndexRange range) { Vector closest_distances; diff --git a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp index 69f4da30f33..424365b3bf3 100644 --- a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp +++ b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp @@ -513,9 +513,9 @@ void BlenderFileLoader::insertShapeNode(Object *ob, Mesh *me, int id) FrsMaterial tmpMat; const bke::AttributeAccessor attributes = me->attributes(); - const VArray material_indices = attributes.lookup_or_default( + const VArray material_indices = *attributes.lookup_or_default( "material_index", ATTR_DOMAIN_FACE, 0); - const VArray sharp_faces = attributes.lookup_or_default( + const VArray sharp_faces = *attributes.lookup_or_default( "sharp_face", ATTR_DOMAIN_FACE, false); // We parse the vlak nodes again and import meshes while applying the clipping diff --git a/source/blender/geometry/intern/mesh_split_edges.cc b/source/blender/geometry/intern/mesh_split_edges.cc index b3b6a21f415..04fec824116 100644 --- a/source/blender/geometry/intern/mesh_split_edges.cc +++ b/source/blender/geometry/intern/mesh_split_edges.cc @@ -154,7 +154,7 @@ static void add_new_edges(Mesh &mesh, attributes.add(new_data.local_id, ATTR_DOMAIN_EDGE, bke::cpp_type_to_custom_data_type(new_data.type), - bke::AttributeInitMoveArray(new_data.array)); + bke::AttributeInitData(new_data.array, nullptr)); } } diff --git a/source/blender/geometry/intern/mesh_to_curve_convert.cc b/source/blender/geometry/intern/mesh_to_curve_convert.cc index 955ee5c5115..14dfcc5bacb 100644 --- a/source/blender/geometry/intern/mesh_to_curve_convert.cc +++ b/source/blender/geometry/intern/mesh_to_curve_convert.cc @@ -52,7 +52,7 @@ bke::CurvesGeometry create_curve_from_vert_indices( continue; } - const GVArray mesh_attribute = mesh_attributes.lookup(attribute_id, ATTR_DOMAIN_POINT); + const GVArray mesh_attribute = *mesh_attributes.lookup(attribute_id, ATTR_DOMAIN_POINT); /* Some attributes might not exist if they were builtin attribute on domains that don't * have any elements, i.e. a face attribute on the output of the line primitive node. */ if (!mesh_attribute) { diff --git a/source/blender/geometry/intern/point_merge_by_distance.cc b/source/blender/geometry/intern/point_merge_by_distance.cc index 1772a23c5f4..aeed32cd337 100644 --- a/source/blender/geometry/intern/point_merge_by_distance.cc +++ b/source/blender/geometry/intern/point_merge_by_distance.cc @@ -108,7 +108,7 @@ PointCloud *point_merge_by_distance(const PointCloud &src_points, /* Transfer the ID attribute if it exists, using the ID of the first merged point. */ if (attribute_ids.contains("id")) { - VArraySpan src = src_attributes.lookup_or_default("id", ATTR_DOMAIN_POINT, 0); + VArraySpan src = *src_attributes.lookup_or_default("id", ATTR_DOMAIN_POINT, 0); bke::SpanAttributeWriter dst = dst_attributes.lookup_or_add_for_write_only_span( "id", ATTR_DOMAIN_POINT); diff --git a/source/blender/geometry/intern/realize_instances.cc b/source/blender/geometry/intern/realize_instances.cc index 01efa2a57d1..30324dbdab1 100644 --- a/source/blender/geometry/intern/realize_instances.cc +++ b/source/blender/geometry/intern/realize_instances.cc @@ -699,7 +699,7 @@ static AllPointCloudsInfo preprocess_pointclouds(const GeometrySet &geometry_set const eCustomDataType data_type = info.attributes.kinds[attribute_index].data_type; const eAttrDomain domain = info.attributes.kinds[attribute_index].domain; if (attributes.contains(attribute_id)) { - GVArray attribute = attributes.lookup_or_default(attribute_id, domain, data_type); + GVArray attribute = *attributes.lookup_or_default(attribute_id, domain, data_type); pointcloud_info.attributes[attribute_index].emplace(std::move(attribute)); } } @@ -710,9 +710,9 @@ static AllPointCloudsInfo preprocess_pointclouds(const GeometrySet &geometry_set } } if (info.create_radius_attribute) { - pointcloud_info.radii = attributes.lookup_or_default("radius", ATTR_DOMAIN_POINT, 0.01f); + pointcloud_info.radii = *attributes.lookup_or_default("radius", ATTR_DOMAIN_POINT, 0.01f); } - const VArray position_attribute = attributes.lookup_or_default( + const VArray position_attribute = *attributes.lookup_or_default( "position", ATTR_DOMAIN_POINT, float3(0)); pointcloud_info.positions = position_attribute.get_internal_span(); } @@ -929,7 +929,7 @@ static AllMeshesInfo preprocess_meshes(const GeometrySet &geometry_set, const eCustomDataType data_type = info.attributes.kinds[attribute_index].data_type; const eAttrDomain domain = info.attributes.kinds[attribute_index].domain; if (attributes.contains(attribute_id)) { - GVArray attribute = attributes.lookup_or_default(attribute_id, domain, data_type); + GVArray attribute = *attributes.lookup_or_default(attribute_id, domain, data_type); mesh_info.attributes[attribute_index].emplace(std::move(attribute)); } } @@ -939,8 +939,8 @@ static AllMeshesInfo preprocess_meshes(const GeometrySet &geometry_set, mesh_info.stored_vertex_ids = ids_attribute.varray.get_internal_span().typed(); } } - mesh_info.material_indices = attributes.lookup_or_default( - "material_index", ATTR_DOMAIN_FACE, 0); + mesh_info.material_indices =* + attributes.lookup_or_default("material_index", ATTR_DOMAIN_FACE, 0); } info.no_loose_edges_hint = std::all_of( @@ -1231,7 +1231,7 @@ static AllCurvesInfo preprocess_curves(const GeometrySet &geometry_set, const AttributeIDRef &attribute_id = info.attributes.ids[attribute_index]; const eCustomDataType data_type = info.attributes.kinds[attribute_index].data_type; if (attributes.contains(attribute_id)) { - GVArray attribute = attributes.lookup_or_default(attribute_id, domain, data_type); + GVArray attribute = *attributes.lookup_or_default(attribute_id, domain, data_type); curve_info.attributes[attribute_index].emplace(std::move(attribute)); } } @@ -1244,12 +1244,12 @@ static AllCurvesInfo preprocess_curves(const GeometrySet &geometry_set, if (attributes.contains("radius")) { curve_info.radius = - attributes.lookup("radius", ATTR_DOMAIN_POINT).get_internal_span(); + attributes.lookup("radius", ATTR_DOMAIN_POINT).varray.get_internal_span(); info.create_radius_attribute = true; } if (attributes.contains("nurbs_weight")) { curve_info.nurbs_weight = - attributes.lookup("nurbs_weight", ATTR_DOMAIN_POINT).get_internal_span(); + attributes.lookup("nurbs_weight", ATTR_DOMAIN_POINT).varray.get_internal_span(); info.create_nurbs_weight_attribute = true; } curve_info.resolution = curves.resolution(); @@ -1258,9 +1258,9 @@ static AllCurvesInfo preprocess_curves(const GeometrySet &geometry_set, } if (attributes.contains("handle_right")) { curve_info.handle_left = - attributes.lookup("handle_left", ATTR_DOMAIN_POINT).get_internal_span(); + attributes.lookup("handle_left", ATTR_DOMAIN_POINT).varray.get_internal_span(); curve_info.handle_right = - attributes.lookup("handle_right", ATTR_DOMAIN_POINT).get_internal_span(); + attributes.lookup("handle_right", ATTR_DOMAIN_POINT).varray.get_internal_span(); info.create_handle_postion_attributes = true; } } diff --git a/source/blender/geometry/intern/resample_curves.cc b/source/blender/geometry/intern/resample_curves.cc index 93865471aed..218928c6027 100644 --- a/source/blender/geometry/intern/resample_curves.cc +++ b/source/blender/geometry/intern/resample_curves.cc @@ -94,9 +94,9 @@ static void retrieve_attribute_spans(const Span ids, Vector &dst, Vector &dst_attributes) { + const bke::AttributeAccessor src_attributes = src_curves.attributes(); for (const int i : ids.index_range()) { - GVArray src_attribute = src_curves.attributes().lookup(ids[i], ATTR_DOMAIN_POINT); - BLI_assert(src_attribute); + const GVArray src_attribute = *src_attributes.lookup(ids[i], ATTR_DOMAIN_POINT); src.append(src_attribute.get_internal_span()); const eCustomDataType data_type = bke::cpp_type_to_custom_data_type(src_attribute.type()); diff --git a/source/blender/gpencil_modifiers_legacy/intern/lineart/lineart_cpu.cc b/source/blender/gpencil_modifiers_legacy/intern/lineart/lineart_cpu.cc index 85ed4453412..b2276d85f68 100644 --- a/source/blender/gpencil_modifiers_legacy/intern/lineart/lineart_cpu.cc +++ b/source/blender/gpencil_modifiers_legacy/intern/lineart/lineart_cpu.cc @@ -2077,9 +2077,9 @@ static void lineart_geometry_object_load(LineartObjectInfo *ob_info, edge_feat_settings.func_reduce = feat_data_sum_reduce; const bke::AttributeAccessor attributes = me->attributes(); - const VArray sharp_edges = attributes.lookup_or_default( + const VArray sharp_edges = *attributes.lookup_or_default( "sharp_edge", ATTR_DOMAIN_EDGE, false); - const VArray sharp_faces = attributes.lookup_or_default( + const VArray sharp_faces = *attributes.lookup_or_default( "sharp_face", ATTR_DOMAIN_FACE, false); EdgeFeatData edge_feat_data = {nullptr}; diff --git a/source/blender/io/alembic/exporter/abc_writer_mesh.cc b/source/blender/io/alembic/exporter/abc_writer_mesh.cc index 467f99365a4..84fcffa3b96 100644 --- a/source/blender/io/alembic/exporter/abc_writer_mesh.cc +++ b/source/blender/io/alembic/exporter/abc_writer_mesh.cc @@ -394,7 +394,7 @@ void ABCGenericMeshWriter::get_geo_groups(Object *object, std::map> &geo_groups) { const bke::AttributeAccessor attributes = mesh->attributes(); - const VArraySpan material_indices = attributes.lookup_or_default( + const VArraySpan material_indices = *attributes.lookup_or_default( "material_index", ATTR_DOMAIN_FACE, 0); for (const int i : material_indices.index_range()) { @@ -452,7 +452,7 @@ static void get_topology(struct Mesh *mesh, const OffsetIndices polys = mesh->polys(); const Span corner_verts = mesh->corner_verts(); const bke::AttributeAccessor attributes = mesh->attributes(); - const VArray sharp_faces = attributes.lookup_or_default( + const VArray sharp_faces = *attributes.lookup_or_default( "sharp_face", ATTR_DOMAIN_FACE, false); for (const int i : sharp_faces.index_range()) { if (sharp_faces[i]) { diff --git a/source/blender/io/collada/GeometryExporter.cpp b/source/blender/io/collada/GeometryExporter.cpp index 016947e1790..0f22bdfbf61 100644 --- a/source/blender/io/collada/GeometryExporter.cpp +++ b/source/blender/io/collada/GeometryExporter.cpp @@ -294,7 +294,7 @@ static bool collect_vertex_counts_per_poly(Mesh *me, { const blender::OffsetIndices polys = me->polys(); const blender::bke::AttributeAccessor attributes = me->attributes(); - const blender::VArray material_indices = attributes.lookup_or_default( + const blender::VArray material_indices = *attributes.lookup_or_default( "material_index", ATTR_DOMAIN_FACE, 0); bool is_triangulated = true; @@ -404,7 +404,7 @@ void GeometryExporter::create_mesh_primitive_list(short material_index, prepareToAppendValues(is_triangulated, *primitive_list, vcount_list); const blender::bke::AttributeAccessor attributes = me->attributes(); - const blender::VArray material_indices = attributes.lookup_or_default( + const blender::VArray material_indices = *attributes.lookup_or_default( "material_index", ATTR_DOMAIN_FACE, 0); /*

*/ @@ -623,7 +623,7 @@ void GeometryExporter::create_normals(std::vector &normals, bool use_custom_normals = false; const bke::AttributeAccessor attributes = me->attributes(); - const VArray sharp_faces = attributes.lookup_or_default( + const VArray sharp_faces = *attributes.lookup_or_default( "sharp_face", ATTR_DOMAIN_FACE, false); BKE_mesh_calc_normals_split(me); diff --git a/source/blender/io/ply/exporter/ply_export_load_plydata.cc b/source/blender/io/ply/exporter/ply_export_load_plydata.cc index 1d6602022f3..1a83a768b1a 100644 --- a/source/blender/io/ply/exporter/ply_export_load_plydata.cc +++ b/source/blender/io/ply/exporter/ply_export_load_plydata.cc @@ -89,7 +89,7 @@ static void generate_vertex_map(const Mesh *mesh, const StringRef uv_name = CustomData_get_active_layer_name(&mesh->ldata, CD_PROP_FLOAT2); if (!uv_name.is_empty()) { const bke::AttributeAccessor attributes = mesh->attributes(); - uv_map = attributes.lookup(uv_name, ATTR_DOMAIN_CORNER); + uv_map = *attributes.lookup(uv_name, ATTR_DOMAIN_CORNER); export_uv = !uv_map.is_empty(); } } @@ -245,7 +245,7 @@ void load_plydata(PlyData &plyData, Depsgraph *depsgraph, const PLYExportParams if (!name.is_empty()) { const bke::AttributeAccessor attributes = mesh->attributes(); const VArray color_attribute = - attributes.lookup_or_default( + *attributes.lookup_or_default( name, ATTR_DOMAIN_POINT, {0.0f, 0.0f, 0.0f, 0.0f}); if (!color_attribute.is_empty()) { plyData.vertex_colors.reserve(ply_to_vertex.size()); diff --git a/source/blender/io/usd/intern/usd_writer_mesh.cc b/source/blender/io/usd/intern/usd_writer_mesh.cc index 870f46f561a..e4c5332c6ee 100644 --- a/source/blender/io/usd/intern/usd_writer_mesh.cc +++ b/source/blender/io/usd/intern/usd_writer_mesh.cc @@ -108,7 +108,7 @@ void USDGenericMeshWriter::write_color_data(const Mesh *mesh, pxr::UsdGeomPrimvar colors_pv = pvApi.CreatePrimvar( primvar_name, pxr::SdfValueTypeNames->Color3fArray, prim_varying); - const VArray attribute = mesh->attributes().lookup_or_default( + const VArray attribute = *mesh->attributes().lookup_or_default( attribute_id, meta_data.domain, {0.0f, 0.0f, 0.0f, 1.0f}); pxr::VtArray colors_data; @@ -345,7 +345,7 @@ static void get_loops_polys(const Mesh *mesh, USDMeshData &usd_mesh_data) /* Only construct face groups (a.k.a. geometry subsets) when we need them for material * assignments. */ const bke::AttributeAccessor attributes = mesh->attributes(); - const VArray material_indices = attributes.lookup_or_default( + const VArray material_indices = *attributes.lookup_or_default( "material_index", ATTR_DOMAIN_FACE, 0); if (!material_indices.is_single() && mesh->totcol > 1) { const VArraySpan indices_span(material_indices); @@ -513,7 +513,7 @@ void USDGenericMeshWriter::write_normals(const Mesh *mesh, pxr::UsdGeomMesh usd_ bke::AttributeAccessor attributes = mesh->attributes(); const Span vert_normals = mesh->vert_normals(); const Span poly_normals = mesh->poly_normals(); - const VArray sharp_faces = attributes.lookup_or_default( + const VArray sharp_faces = *attributes.lookup_or_default( "sharp_face", ATTR_DOMAIN_FACE, false); for (const int i : polys.index_range()) { const IndexRange poly = polys[i]; diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc b/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc index 4d3bc1c6c01..2fc64a9aeac 100644 --- a/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc +++ b/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc @@ -254,7 +254,7 @@ void OBJWriter::write_vertex_coords(FormatHandler &fh, const StringRef name = mesh->active_color_attribute; if (write_colors && !name.is_empty()) { const bke::AttributeAccessor attributes = mesh->attributes(); - const VArray attribute = attributes.lookup_or_default( + const VArray attribute = *attributes.lookup_or_default( name, ATTR_DOMAIN_POINT, {0.0f, 0.0f, 0.0f, 0.0f}); BLI_assert(tot_count == attribute.size()); @@ -338,7 +338,7 @@ void OBJWriter::write_poly_elements(FormatHandler &fh, const int tot_deform_groups = obj_mesh_data.tot_deform_groups(); threading::EnumerableThreadSpecific> group_weights; const bke::AttributeAccessor attributes = obj_mesh_data.get_mesh()->attributes(); - const VArray material_indices = attributes.lookup_or_default( + const VArray material_indices = *attributes.lookup_or_default( "material_index", ATTR_DOMAIN_FACE, 0); obj_parallel_chunked_output(fh, tot_polygons, [&](FormatHandler &buf, int idx) { diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc b/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc index 066d960a78d..09695ede2e1 100644 --- a/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc +++ b/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc @@ -44,7 +44,7 @@ OBJMesh::OBJMesh(Depsgraph *depsgraph, const OBJExportParams &export_params, Obj mesh_edges_ = export_mesh_->edges(); mesh_polys_ = export_mesh_->polys(); mesh_corner_verts_ = export_mesh_->corner_verts(); - sharp_faces_ = export_mesh_->attributes().lookup_or_default( + sharp_faces_ = *export_mesh_->attributes().lookup_or_default( "sharp_face", ATTR_DOMAIN_FACE, false); } else { @@ -78,7 +78,7 @@ void OBJMesh::set_mesh(Mesh *mesh) mesh_edges_ = mesh->edges(); mesh_polys_ = mesh->polys(); mesh_corner_verts_ = mesh->corner_verts(); - sharp_faces_ = export_mesh_->attributes().lookup_or_default( + sharp_faces_ = *export_mesh_->attributes().lookup_or_default( "sharp_face", ATTR_DOMAIN_FACE, false); } @@ -214,7 +214,7 @@ void OBJMesh::calc_smooth_groups(const bool use_bitflags) void OBJMesh::calc_poly_order() { const bke::AttributeAccessor attributes = export_mesh_->attributes(); - const VArray material_indices = attributes.lookup_or_default( + const VArray material_indices = *attributes.lookup_or_default( "material_index", ATTR_DOMAIN_FACE, 0); if (material_indices.is_single() && material_indices.get_internal_single() == 0) { return; @@ -296,7 +296,7 @@ void OBJMesh::store_uv_coords_and_indices() return; } const bke::AttributeAccessor attributes = export_mesh_->attributes(); - const VArraySpan uv_map = attributes.lookup(active_uv_name, ATTR_DOMAIN_CORNER); + const VArraySpan uv_map = *attributes.lookup(active_uv_name, ATTR_DOMAIN_CORNER); if (uv_map.is_empty()) { uv_coords_.clear(); return; diff --git a/source/blender/modifiers/intern/MOD_array.cc b/source/blender/modifiers/intern/MOD_array.cc index 5736d2f1e33..80ea448ed51 100644 --- a/source/blender/modifiers/intern/MOD_array.cc +++ b/source/blender/modifiers/intern/MOD_array.cc @@ -333,8 +333,8 @@ static void mesh_merge_transform(Mesh *result, } const bke::AttributeAccessor cap_attributes = cap_mesh->attributes(); - if (const VArray cap_material_indices = cap_attributes.lookup("material_index", - ATTR_DOMAIN_FACE)) { + if (const VArray cap_material_indices = *cap_attributes.lookup("material_index", + ATTR_DOMAIN_FACE)) { bke::MutableAttributeAccessor result_attributes = result->attributes_for_write(); bke::SpanAttributeWriter result_material_indices = result_attributes.lookup_or_add_for_write_span("material_index", ATTR_DOMAIN_FACE); diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc index adb60b91de8..87cdfc6d625 100644 --- a/source/blender/modifiers/intern/MOD_nodes.cc +++ b/source/blender/modifiers/intern/MOD_nodes.cc @@ -1088,8 +1088,8 @@ static void store_computed_output_attributes( * attribute didn't exist before, or if it existed but was removed above. */ if (attributes.add(store.name, store.domain, - bke::cpp_type_to_custom_data_type(store.data.type()), - bke::AttributeInitMoveArray(store.data.data()))) { + data_type, + bke::AttributeInitData(store.data.data(), nullptr))) { continue; } diff --git a/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc b/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc index bc422dac086..9073614b262 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc @@ -138,8 +138,7 @@ static Mesh *compute_hull(const GeometrySet &geometry_set) if (const Mesh *mesh = geometry_set.get_mesh_for_read()) { count++; - if (const VArray positions = mesh->attributes().lookup("position", - ATTR_DOMAIN_POINT)) { + if (const VArray positions = *mesh->attributes().lookup("position")) { if (positions.is_span()) { span_count++; positions_span = positions.get_internal_span(); @@ -150,8 +149,7 @@ static Mesh *compute_hull(const GeometrySet &geometry_set) if (const PointCloud *points = geometry_set.get_pointcloud_for_read()) { count++; - if (const VArray positions = points->attributes().lookup("position", - ATTR_DOMAIN_POINT)) { + if (const VArray positions = *points->attributes().lookup("position")) { if (positions.is_span()) { span_count++; positions_span = positions.get_internal_span(); @@ -182,16 +180,14 @@ static Mesh *compute_hull(const GeometrySet &geometry_set) int offset = 0; if (const Mesh *mesh = geometry_set.get_mesh_for_read()) { - if (const VArray varray = mesh->attributes().lookup("position", - ATTR_DOMAIN_POINT)) { + if (const VArray varray = *mesh->attributes().lookup("position")) { varray.materialize(positions.as_mutable_span().slice(offset, varray.size())); offset += varray.size(); } } if (const PointCloud *points = geometry_set.get_pointcloud_for_read()) { - if (const VArray varray = points->attributes().lookup("position", - ATTR_DOMAIN_POINT)) { + if (const VArray varray = *points->attributes().lookup("position")) { varray.materialize(positions.as_mutable_span().slice(offset, varray.size())); offset += varray.size(); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_to_points.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_to_points.cc index 075ed8a6ce4..80bd70e1a01 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_to_points.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_to_points.cc @@ -82,20 +82,21 @@ static void fill_rotation_attribute(const Span tangents, static void copy_curve_domain_attributes(const AttributeAccessor curve_attributes, MutableAttributeAccessor point_attributes) { - curve_attributes.for_all([&](const bke::AttributeIDRef &id, - const bke::AttributeMetaData &meta_data) { - if (curve_attributes.is_builtin(id)) { - return true; - } - if (meta_data.domain != ATTR_DOMAIN_CURVE) { - return true; - } - point_attributes.add(id, - ATTR_DOMAIN_POINT, - meta_data.data_type, - bke::AttributeInitVArray(curve_attributes.lookup(id, ATTR_DOMAIN_POINT))); - return true; - }); + curve_attributes.for_all( + [&](const bke::AttributeIDRef &id, const bke::AttributeMetaData &meta_data) { + if (curve_attributes.is_builtin(id)) { + return true; + } + if (meta_data.domain != ATTR_DOMAIN_CURVE) { + return true; + } + point_attributes.add( + id, + ATTR_DOMAIN_POINT, + meta_data.data_type, + bke::AttributeInitVArray(*curve_attributes.lookup(id, ATTR_DOMAIN_POINT))); + return true; + }); } static PointCloud *pointcloud_from_curves(bke::CurvesGeometry curves, @@ -108,8 +109,8 @@ static PointCloud *pointcloud_from_curves(bke::CurvesGeometry curves, if (rotation_id) { MutableAttributeAccessor attributes = curves.attributes_for_write(); - const VArraySpan tangents = attributes.lookup(tangent_id, ATTR_DOMAIN_POINT); - const VArraySpan normals = attributes.lookup(normal_id, ATTR_DOMAIN_POINT); + const VArraySpan tangents = *attributes.lookup(tangent_id, ATTR_DOMAIN_POINT); + const VArraySpan normals = *attributes.lookup(normal_id, ATTR_DOMAIN_POINT); SpanAttributeWriter rotations = attributes.lookup_or_add_for_write_only_span( rotation_id, ATTR_DOMAIN_POINT); fill_rotation_attribute(tangents, normals, rotations.span); diff --git a/source/blender/nodes/geometry/nodes/node_geo_deform_curves_on_surface.cc b/source/blender/nodes/geometry/nodes/node_geo_deform_curves_on_surface.cc index d487085e0f3..9adec795cda 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_deform_curves_on_surface.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_deform_curves_on_surface.cc @@ -298,13 +298,13 @@ static void node_geo_exec(GeoNodeExecParams params) TIP_("Curves are not attached to any UV map")); return; } - const VArraySpan uv_map_orig = mesh_attributes_orig.lookup(uv_map_name, - ATTR_DOMAIN_CORNER); - const VArraySpan uv_map_eval = mesh_attributes_eval.lookup(uv_map_name, - ATTR_DOMAIN_CORNER); - const VArraySpan rest_positions = mesh_attributes_eval.lookup(rest_position_name, - ATTR_DOMAIN_POINT); - const VArraySpan surface_uv_coords = curves.attributes().lookup_or_default( + const VArraySpan uv_map_orig = *mesh_attributes_orig.lookup(uv_map_name, + ATTR_DOMAIN_CORNER); + const VArraySpan uv_map_eval = *mesh_attributes_eval.lookup(uv_map_name, + ATTR_DOMAIN_CORNER); + const VArraySpan rest_positions = *mesh_attributes_eval.lookup(rest_position_name, + ATTR_DOMAIN_POINT); + const VArraySpan surface_uv_coords = *curves.attributes().lookup_or_default( "surface_uv_coordinate", ATTR_DOMAIN_CURVE, float2(0)); const Span looptris_orig = surface_mesh_orig->looptris(); @@ -374,7 +374,7 @@ static void node_geo_exec(GeoNodeExecParams params) invalid_uv_count); /* Then also deform edit curve information for use in sculpt mode. */ const CurvesGeometry &curves_orig = edit_hints->curves_id_orig.geometry.wrap(); - const VArraySpan surface_uv_coords_orig = curves_orig.attributes().lookup_or_default( + const VArraySpan surface_uv_coords_orig = *curves_orig.attributes().lookup_or_default( "surface_uv_coordinate", ATTR_DOMAIN_CURVE, float2(0)); if (!surface_uv_coords_orig.is_empty()) { deform_curves(curves_orig, diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_curve_handles.cc b/source/blender/nodes/geometry/nodes/node_geo_input_curve_handles.cc index 4256724e883..04f294c2b87 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_curve_handles.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_curve_handles.cc @@ -41,7 +41,7 @@ class HandlePositionFieldInput final : public bke::CurvesFieldInput { const AttributeAccessor attributes = curves.attributes(); StringRef side = left_ ? "handle_left" : "handle_right"; - VArray handles = attributes.lookup_or_default( + VArray handles = *attributes.lookup_or_default( side, ATTR_DOMAIN_POINT, {0, 0, 0}); if (relative.is_single()) { diff --git a/source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc b/source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc index 9e0f66217b0..ae27e8d35e0 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc @@ -76,6 +76,7 @@ static void add_instances_from_component( if (selection.is_empty()) { return; } + const AttributeAccessor src_attributes = *src_component.attributes(); /* The initial size of the component might be non-zero when this function is called for multiple * component types. */ @@ -86,8 +87,7 @@ static void add_instances_from_component( MutableSpan dst_handles = dst_component.reference_handles().slice(start_len, select_len); MutableSpan dst_transforms = dst_component.transforms().slice(start_len, select_len); - VArray positions = src_component.attributes()->lookup_or_default( - "position", domain, {0, 0, 0}); + const VArraySpan positions = *src_attributes.lookup("position"); const bke::Instances *src_instances = instance.get_instances_for_read(); @@ -158,24 +158,25 @@ static void add_instances_from_component( } } - bke::CustomDataAttributes &instance_attributes = dst_component.custom_data_attributes(); + bke::MutableAttributeAccessor dst_attributes = dst_component.attributes_for_write(); for (const auto item : attributes_to_propagate.items()) { - const AttributeIDRef &attribute_id = item.key; - const AttributeKind attribute_kind = item.value; + const AttributeIDRef &id = item.key; + const eCustomDataType type = item.value.data_type; - const GVArray src_attribute = src_component.attributes()->lookup_or_default( - attribute_id, ATTR_DOMAIN_POINT, attribute_kind.data_type); - BLI_assert(src_attribute); - std::optional dst_attribute_opt = instance_attributes.get_for_write( - attribute_id); - if (!dst_attribute_opt) { - if (!instance_attributes.create(attribute_id, attribute_kind.data_type)) { - continue; - } - dst_attribute_opt = instance_attributes.get_for_write(attribute_id); + const bke::GAttributeReader src = src_attributes.lookup_or_default( + id, ATTR_DOMAIN_POINT, type); + if (src.varray.size() == dst_component.instances_num()) { + dst_attributes.add(id, + ATTR_DOMAIN_INSTANCE, + type, + bke::AttributeInitData(src.varray.common_info().data, src.sharing_info)); + } + else { + GSpanAttributeWriter dst = dst_attributes.lookup_or_add_for_write_only_span( + id, ATTR_DOMAIN_INSTANCE, type); + array_utils::gather(src.varray, selection, dst.span.slice(start_len, select_len)); + dst.finish(); } - BLI_assert(dst_attribute_opt); - array_utils::gather(src_attribute, selection, dst_attribute_opt->slice(start_len, select_len)); } } diff --git a/source/blender/nodes/geometry/nodes/node_geo_instances_to_points.cc b/source/blender/nodes/geometry/nodes/node_geo_instances_to_points.cc index bec31586411..406d8402103 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_instances_to_points.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_instances_to_points.cc @@ -50,12 +50,13 @@ static void convert_instances_to_points(GeometrySet &geometry_set, geometry_set.replace_pointcloud(pointcloud); array_utils::gather(positions, selection, pointcloud->positions_for_write()); - bke::MutableAttributeAccessor point_attributes = pointcloud->attributes_for_write(); + bke::MutableAttributeAccessor dst_attributes = pointcloud->attributes_for_write(); bke::SpanAttributeWriter point_radii = - point_attributes.lookup_or_add_for_write_only_span("radius", ATTR_DOMAIN_POINT); + dst_attributes.lookup_or_add_for_write_only_span("radius", ATTR_DOMAIN_POINT); array_utils::gather(radii, selection, point_radii.span); point_radii.finish(); + const bke::AttributeAccessor src_attributes = instances.attributes(); Map attributes_to_propagate; geometry_set.gather_attributes_for_propagation({GEO_COMPONENT_TYPE_INSTANCES}, GEO_COMPONENT_TYPE_POINT_CLOUD, @@ -67,18 +68,22 @@ static void convert_instances_to_points(GeometrySet &geometry_set, attributes_to_propagate.remove("radius"); for (const auto item : attributes_to_propagate.items()) { - const AttributeIDRef &attribute_id = item.key; - const AttributeKind attribute_kind = item.value; + const AttributeIDRef &id = item.key; + const eCustomDataType type = item.value.data_type; - const GVArray src = instances.attributes().lookup_or_default( - attribute_id, ATTR_DOMAIN_INSTANCE, attribute_kind.data_type); - BLI_assert(src); - GSpanAttributeWriter dst = point_attributes.lookup_or_add_for_write_only_span( - attribute_id, ATTR_DOMAIN_POINT, attribute_kind.data_type); - BLI_assert(dst); - - src.materialize_compressed_to_uninitialized(selection, dst.span.data()); - dst.finish(); + const GAttributeReader src = src_attributes.lookup_or_default(id, ATTR_DOMAIN_INSTANCE, type); + if (selection.size() == instances.instances_num()) { + dst_attributes.add(id, + ATTR_DOMAIN_POINT, + type, + bke::AttributeInitData(src.varray.common_info().data, src.sharing_info)); + } + else { + GSpanAttributeWriter dst = dst_attributes.lookup_or_add_for_write_only_span( + id, ATTR_DOMAIN_POINT, type); + array_utils::gather(src.varray, selection, dst.span); + dst.finish(); + } } } diff --git a/source/blender/nodes/geometry/nodes/node_geo_interpolate_curves.cc b/source/blender/nodes/geometry/nodes/node_geo_interpolate_curves.cc index ca5423f0744..a19bb42642c 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_interpolate_curves.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_interpolate_curves.cc @@ -446,7 +446,8 @@ static void interpolate_curve_attributes(bke::CurvesGeometry &child_curves, if (id.is_anonymous() && !propagation_info.propagate(id.anonymous_id())) { return true; } - if (meta_data.data_type == CD_PROP_STRING) { + const eCustomDataType type = meta_data.data_type; + if (type == CD_PROP_STRING) { return true; } if (guide_curve_attributes.is_builtin(id) && @@ -455,15 +456,14 @@ static void interpolate_curve_attributes(bke::CurvesGeometry &child_curves, } if (meta_data.domain == ATTR_DOMAIN_CURVE) { - const GVArraySpan src_generic = guide_curve_attributes.lookup( - id, ATTR_DOMAIN_CURVE, meta_data.data_type); + const GVArraySpan src_generic = *guide_curve_attributes.lookup(id, ATTR_DOMAIN_CURVE, type); GSpanAttributeWriter dst_generic = children_attributes.lookup_or_add_for_write_only_span( - id, ATTR_DOMAIN_CURVE, meta_data.data_type); + id, ATTR_DOMAIN_CURVE, type); if (!dst_generic) { return true; } - attribute_math::convert_to_static_type(meta_data.data_type, [&](auto dummy) { + attribute_math::convert_to_static_type(type, [&](auto dummy) { using T = decltype(dummy); const Span src = src_generic.typed(); MutableSpan dst = dst_generic.span.typed(); @@ -490,15 +490,14 @@ static void interpolate_curve_attributes(bke::CurvesGeometry &child_curves, } else { BLI_assert(meta_data.domain == ATTR_DOMAIN_POINT); - const GVArraySpan src_generic = guide_curve_attributes.lookup( - id, ATTR_DOMAIN_POINT, meta_data.data_type); + const GVArraySpan src_generic = *guide_curve_attributes.lookup(id, ATTR_DOMAIN_POINT, type); GSpanAttributeWriter dst_generic = children_attributes.lookup_or_add_for_write_only_span( - id, ATTR_DOMAIN_POINT, meta_data.data_type); + id, ATTR_DOMAIN_POINT, type); if (!dst_generic) { return true; } - attribute_math::convert_to_static_type(meta_data.data_type, [&](auto dummy) { + attribute_math::convert_to_static_type(type, [&](auto dummy) { using T = decltype(dummy); const Span src = src_generic.typed(); MutableSpan dst = dst_generic.span.typed(); @@ -575,18 +574,17 @@ static void interpolate_curve_attributes(bke::CurvesGeometry &child_curves, if (id.is_anonymous() && !propagation_info.propagate(id.anonymous_id())) { return true; } - if (meta_data.data_type == CD_PROP_STRING) { + const eCustomDataType type = meta_data.data_type; + if (type == CD_PROP_STRING) { return true; } - const GVArray src = point_attributes.lookup(id, ATTR_DOMAIN_POINT, meta_data.data_type); - GSpanAttributeWriter dst = children_attributes.lookup_or_add_for_write_only_span( - id, ATTR_DOMAIN_CURVE, meta_data.data_type); - if (!dst) { - return true; - } - src.materialize(dst.span.data()); - dst.finish(); + const GAttributeReader src = point_attributes.lookup(id, ATTR_DOMAIN_POINT, type); + children_attributes.add( + id, + ATTR_DOMAIN_CURVE, + type, + bke::AttributeInitData(src.varray.common_info().data, src.sharing_info)); return true; }); } @@ -673,7 +671,7 @@ static GeometrySet generate_interpolated_curves( } }); - const VArraySpan point_positions = point_attributes.lookup("position"); + const VArraySpan point_positions = *point_attributes.lookup("position"); const int num_child_curves = point_attributes.domain_size(ATTR_DOMAIN_POINT); /* The set of guides per child are stored in a flattened array to allow fast access, reduce diff --git a/source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc b/source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc index 18a662289aa..df3e610fd45 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc @@ -65,7 +65,7 @@ static void fill_new_attribute(Span src_components, if (domain_num == 0) { continue; } - GVArray read_attribute = component->attributes()->lookup_or_default( + GVArray read_attribute = *component->attributes()->lookup_or_default( attribute_id, domain, data_type, nullptr); GVArraySpan src_span{read_attribute}; diff --git a/source/blender/nodes/geometry/nodes/node_geo_material_selection.cc b/source/blender/nodes/geometry/nodes/node_geo_material_selection.cc index bd1408c0f31..ae85c1fbd92 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_material_selection.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_material_selection.cc @@ -35,7 +35,7 @@ static VArray select_mesh_faces_by_material(const Mesh &mesh, } const AttributeAccessor attributes = mesh.attributes(); - const VArray material_indices = attributes.lookup_or_default( + const VArray material_indices = *attributes.lookup_or_default( "material_index", ATTR_DOMAIN_FACE, 0); if (material_indices.is_single()) { const int slot_i = material_indices.get_internal_single(); diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_ico_sphere.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_ico_sphere.cc index 9af63b9b514..3253cd918ea 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_ico_sphere.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_ico_sphere.cc @@ -93,7 +93,7 @@ static Mesh *create_ico_sphere_mesh(const int subdivisions, * have a simple utility for that yet though so there is some overhead right now. */ MutableAttributeAccessor attributes = mesh->attributes_for_write(); if (create_uv_map) { - const VArraySpan orig_uv_map = attributes.lookup("UVMap"); + const VArraySpan orig_uv_map = *attributes.lookup("UVMap"); SpanAttributeWriter uv_map = attributes.lookup_or_add_for_write_only_span( uv_map_id, ATTR_DOMAIN_CORNER); uv_map.span.copy_from(orig_uv_map); diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc index f6ed43d3e20..d71f9199887 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc @@ -62,6 +62,7 @@ static void geometry_set_mesh_to_points(GeometrySet &geometry_set, geometry_set.remove_geometry_during_modify(); return; } + const AttributeAccessor src_attributes = mesh->attributes(); bke::MeshFieldContext field_context{*mesh, domain}; fn::FieldEvaluator evaluator{field_context, domain_size}; evaluator.set_selection(selection_field); @@ -72,16 +73,32 @@ static void geometry_set_mesh_to_points(GeometrySet &geometry_set, evaluator.add(radius_field); evaluator.evaluate(); const IndexMask selection = evaluator.get_evaluated_selection_as_mask(); + const VArray positions_eval = evaluator.get_evaluated(0); + const VArray radii_eval = evaluator.get_evaluated(1); + + const bool share_arrays = selection.size() == domain_size; + const bool share_position = share_arrays && positions_eval.is_span() && + positions_eval.get_internal_span().data() == + mesh->vert_positions().data(); + + PointCloud *pointcloud; + if (share_position) { + /* Create an empty point cloud so the positions can be easily shared with a generic utility. */ + pointcloud = BKE_pointcloud_new_nomain(0); + CustomData_free_layer_named(&pointcloud->pdata, "position", pointcloud->totpoint); + pointcloud->totpoint = mesh->totvert; + const bke::AttributeReader src = src_attributes.lookup("position"); + pointcloud->attributes_for_write().add( + "position", + ATTR_DOMAIN_POINT, + bke::AttributeInitData(src.varray.common_info().data, src.sharing_info)); + } + else { + pointcloud = BKE_pointcloud_new_nomain(selection.size()); + array_utils::gather(positions_eval, selection, pointcloud->positions_for_write()); + } - PointCloud *pointcloud = BKE_pointcloud_new_nomain(selection.size()); - geometry_set.replace_pointcloud(pointcloud); MutableAttributeAccessor dst_attributes = pointcloud->attributes_for_write(); - - GSpanAttributeWriter position = dst_attributes.lookup_or_add_for_write_only_span( - "position", ATTR_DOMAIN_POINT, CD_PROP_FLOAT3); - array_utils::gather(evaluator.get_evaluated(0), selection, position.span); - position.finish(); - GSpanAttributeWriter radius = dst_attributes.lookup_or_add_for_write_only_span( "radius", ATTR_DOMAIN_POINT, CD_PROP_FLOAT); array_utils::gather(evaluator.get_evaluated(1), selection, radius.span); @@ -93,22 +110,28 @@ static void geometry_set_mesh_to_points(GeometrySet &geometry_set, false, propagation_info, attributes); + attributes.remove("radius"); attributes.remove("position"); - const AttributeAccessor src_attributes = mesh->attributes(); - for (Map::Item entry : attributes.items()) { const AttributeIDRef attribute_id = entry.key; const eCustomDataType data_type = entry.value.data_type; - GVArray src = src_attributes.lookup_or_default(attribute_id, domain, data_type); - GSpanAttributeWriter dst = dst_attributes.lookup_or_add_for_write_only_span( - attribute_id, ATTR_DOMAIN_POINT, data_type); - if (dst && src) { - array_utils::gather(src, selection, dst.span); + const bke::GAttributeReader src = src_attributes.lookup(attribute_id, domain, data_type); + if (share_arrays && src.domain == domain) { + dst_attributes.add(attribute_id, + ATTR_DOMAIN_POINT, + data_type, + bke::AttributeInitData(src.varray.common_info().data, src.sharing_info)); + } + else { + GSpanAttributeWriter dst = dst_attributes.lookup_or_add_for_write_only_span( + attribute_id, ATTR_DOMAIN_POINT, data_type); + array_utils::gather(src.varray, selection, dst.span); dst.finish(); } } + geometry_set.replace_pointcloud(pointcloud); geometry_set.keep_only_during_modify({GEO_COMPONENT_TYPE_POINT_CLOUD}); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_points_to_vertices.cc b/source/blender/nodes/geometry/nodes/node_geo_points_to_vertices.cc index 92ac14046ec..6d7dc4a1b4e 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_points_to_vertices.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_points_to_vertices.cc @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ -#include "BLI_task.hh" +#include "BLI_array_utils.hh" #include "DNA_pointcloud_types.h" @@ -49,26 +49,40 @@ static void geometry_set_points_to_vertices( propagation_info, attributes); - Mesh *mesh = BKE_mesh_new_nomain(selection.size(), 0, 0, 0); - geometry_set.replace_mesh(mesh); + Mesh *mesh; + if (selection.size() == points->totpoint) { + mesh = BKE_mesh_new_nomain(0, 0, 0, 0); + CustomData_free_layer_named(&mesh->vdata, "position", mesh->totvert); + mesh->totvert = selection.size(); + } + else { + mesh = BKE_mesh_new_nomain(selection.size(), 0, 0, 0); + } const AttributeAccessor src_attributes = points->attributes(); MutableAttributeAccessor dst_attributes = mesh->attributes_for_write(); for (Map::Item entry : attributes.items()) { - const AttributeIDRef attribute_id = entry.key; + const AttributeIDRef id = entry.key; const eCustomDataType data_type = entry.value.data_type; - GVArray src = src_attributes.lookup_or_default(attribute_id, ATTR_DOMAIN_POINT, data_type); - GSpanAttributeWriter dst = dst_attributes.lookup_or_add_for_write_only_span( - attribute_id, ATTR_DOMAIN_POINT, data_type); - if (dst && src) { - src.materialize_compressed_to_uninitialized(selection, dst.span.data()); + const GAttributeReader src = src_attributes.lookup(id); + if (selection.size() == points->totpoint) { + dst_attributes.add(id, + ATTR_DOMAIN_POINT, + data_type, + bke::AttributeInitData(src.varray.common_info().data, src.sharing_info)); + } + else { + GSpanAttributeWriter dst = dst_attributes.lookup_or_add_for_write_only_span( + id, ATTR_DOMAIN_POINT, data_type); + array_utils::gather(src.varray, selection, dst.span); dst.finish(); } } mesh->loose_edges_tag_none(); + geometry_set.replace_mesh(mesh); geometry_set.keep_only_during_modify({GEO_COMPONENT_TYPE_MESH}); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_points_to_volume.cc b/source/blender/nodes/geometry/nodes/node_geo_points_to_volume.cc index 3bb0d74695d..4a801fe7deb 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_points_to_volume.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_points_to_volume.cc @@ -28,8 +28,7 @@ static void gather_point_data_from_component(Field radius_field, if (component.is_empty()) { return; } - VArray positions = component.attributes()->lookup_or_default( - "position", ATTR_DOMAIN_POINT, {0, 0, 0}); + const VArray positions = *component.attributes()->lookup("position"); bke::GeometryFieldContext field_context{component, ATTR_DOMAIN_POINT}; const int domain_num = component.attribute_domain_size(ATTR_DOMAIN_POINT); diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_position.cc b/source/blender/nodes/geometry/nodes/node_geo_set_position.cc index 57781534d63..428bf42ae40 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_set_position.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_set_position.cc @@ -31,10 +31,10 @@ static void set_computed_position_and_offset(GeometryComponent &component, MutableAttributeAccessor attributes = *component.attributes_for_write(); /* Optimize the case when `in_positions` references the original positions array. */ - const VArray positions_read_only = attributes.lookup("position"); + const bke::AttributeReader positions_read_only = attributes.lookup("position"); bool positions_are_original = false; - if (positions_read_only.is_span() && in_positions.is_span()) { - positions_are_original = positions_read_only.get_internal_span().data() == + if (positions_read_only.varray.is_span() && in_positions.is_span()) { + positions_are_original = positions_read_only.varray.get_internal_span().data() == in_positions.get_internal_span().data(); } diff --git a/source/blender/render/intern/bake.cc b/source/blender/render/intern/bake.cc index 63d3f812882..b6600a43d9e 100644 --- a/source/blender/render/intern/bake.cc +++ b/source/blender/render/intern/bake.cc @@ -466,8 +466,8 @@ static TriTessFace *mesh_calc_tri_tessface(Mesh *me, bool tangent, Mesh *me_eval const blender::OffsetIndices polys = me->polys(); const blender::Span corner_verts = me->corner_verts(); const bke::AttributeAccessor attributes = me->attributes(); - const VArray sharp_faces = attributes.lookup_or_default( - "sharp_face", ATTR_DOMAIN_FACE, false); + const VArray sharp_faces = + attributes.lookup_or_default("sharp_face", ATTR_DOMAIN_FACE, false).varray; looptri = static_cast(MEM_mallocN(sizeof(*looptri) * tottri, __func__)); triangles = static_cast(MEM_callocN(sizeof(TriTessFace) * tottri, __func__)); -- 2.30.2 From 5c578d29e19d0c383184b846a961b0064f6057e5 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 18 Apr 2023 08:44:35 -0400 Subject: [PATCH 2/4] Separate a new AttributeInit type --- source/blender/blenkernel/BKE_attribute.hh | 24 ++++++++++++++----- .../blender/blenkernel/intern/DerivedMesh.cc | 4 ++-- .../blenkernel/intern/attribute_access.cc | 23 ++++++++++++++++-- .../blenkernel/intern/geometry_fields.cc | 2 +- .../editors/curves/intern/curves_ops.cc | 2 +- .../editors/geometry/geometry_attributes.cc | 3 +-- .../sculpt_paint/curves_sculpt_selection.cc | 2 +- .../geometry/intern/mesh_split_edges.cc | 2 +- source/blender/modifiers/intern/MOD_nodes.cc | 6 ++--- .../nodes/node_geo_instance_on_points.cc | 14 +++++------ .../nodes/node_geo_instances_to_points.cc | 11 ++++----- .../nodes/node_geo_interpolate_curves.cc | 12 ++++------ .../geometry/nodes/node_geo_mesh_to_points.cc | 17 ++++++------- .../nodes/node_geo_points_to_vertices.cc | 10 ++++---- 14 files changed, 75 insertions(+), 57 deletions(-) diff --git a/source/blender/blenkernel/BKE_attribute.hh b/source/blender/blenkernel/BKE_attribute.hh index 0f6318b353e..d7339e14dbc 100644 --- a/source/blender/blenkernel/BKE_attribute.hh +++ b/source/blender/blenkernel/BKE_attribute.hh @@ -84,8 +84,10 @@ struct AttributeInit { DefaultValue, /** #AttributeInitVArray. */ VArray, - /** #AttributeInitData. */ + /** #AttributeInitMoveArray. */ MoveArray, + /** #AttributeInitShared. */ + Shared, }; Type type; AttributeInit(const Type type) : type(type) {} @@ -121,15 +123,25 @@ struct AttributeInitVArray : public AttributeInit { * Sometimes data is created before a geometry component is available. In that case, it's * preferable to move data directly to the created attribute to avoid a new allocation and a copy. * - * Implicit sharing info can be provided if the array is shared. In that case the sharing info - * has ownership of the provided array. + * The array must be allocated with MEM_*, since `attribute_try_create` will free the array if it + * can't be used directly, and that is generally how Blender expects custom data to be allocated. */ -struct AttributeInitData : public AttributeInit { +struct AttributeInitMoveArray : public AttributeInit { + void *data = nullptr; + + AttributeInitMoveArray(void *data) : AttributeInit(Type::MoveArray), data(data) {} +}; + +/** + * Create a shared attribute by adding a user to a shared data array. + * The sharing info has ownership of the provided contiguous array. + */ +struct AttributeInitShared : public AttributeInit { const void *data = nullptr; const ImplicitSharingInfo *sharing_info = nullptr; - AttributeInitData(const void *data, const ImplicitSharingInfo *sharing_info) - : AttributeInit(Type::MoveArray), data(data), sharing_info(sharing_info) + AttributeInitShared(const void *data, const ImplicitSharingInfo &sharing_info) + : AttributeInit(Type::Shared), data(data), sharing_info(&sharing_info) { } }; diff --git a/source/blender/blenkernel/intern/DerivedMesh.cc b/source/blender/blenkernel/intern/DerivedMesh.cc index 4ae99d83539..09f688049d7 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.cc +++ b/source/blender/blenkernel/intern/DerivedMesh.cc @@ -658,12 +658,12 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph, ASSERT_IS_VALID_MESH(mesh_final); } MutableAttributeAccessor attributes = mesh_final->attributes_for_write(); - const AttributeReader positions = attributes.lookup("position"); + const AttributeReader positions = attributes.lookup("position"); if (positions) { attributes.add( "rest_position", ATTR_DOMAIN_POINT, - AttributeInitData(positions.varray.common_info().data, positions.sharing_info)); + AttributeInitShared(positions.varray.common_info().data, *positions.sharing_info)); } } diff --git a/source/blender/blenkernel/intern/attribute_access.cc b/source/blender/blenkernel/intern/attribute_access.cc index 1a377c5532f..40d97eec96c 100644 --- a/source/blender/blenkernel/intern/attribute_access.cc +++ b/source/blender/blenkernel/intern/attribute_access.cc @@ -206,7 +206,20 @@ static bool add_builtin_type_custom_data_layer_from_init(CustomData &custom_data return true; } case AttributeInit::Type::MoveArray: { - const AttributeInitData &init = static_cast(initializer); + void *src_data = static_cast(initializer).data; + const void *stored_data = CustomData_add_layer_with_data( + &custom_data, data_type, src_data, domain_num, nullptr); + if (stored_data == nullptr) { + return false; + } + if (stored_data != src_data) { + MEM_freeN(src_data); + return true; + } + return true; + } + case AttributeInit::Type::Shared: { + const AttributeInitShared &init = static_cast(initializer); const void *stored_data = CustomData_add_layer_with_data( &custom_data, data_type, const_cast(init.data), domain_num, init.sharing_info); return stored_data != nullptr; @@ -281,7 +294,13 @@ static bool add_custom_data_layer_from_attribute_init(const AttributeIDRef &attr break; } case AttributeInit::Type::MoveArray: { - const AttributeInitData &init = static_cast(initializer); + void *data = static_cast(initializer).data; + add_generic_custom_data_layer_with_existing_data( + custom_data, data_type, attribute_id, domain_num, data, nullptr); + break; + } + case AttributeInit::Type::Shared: { + const AttributeInitShared &init = static_cast(initializer); add_generic_custom_data_layer_with_existing_data(custom_data, data_type, attribute_id, diff --git a/source/blender/blenkernel/intern/geometry_fields.cc b/source/blender/blenkernel/intern/geometry_fields.cc index 1f08c0793b7..f3ce41bcdae 100644 --- a/source/blender/blenkernel/intern/geometry_fields.cc +++ b/source/blender/blenkernel/intern/geometry_fields.cc @@ -474,7 +474,7 @@ bool try_capture_field_on_geometry(GeometryComponent &component, } attributes.remove(attribute_id); - if (attributes.add(attribute_id, domain, data_type, bke::AttributeInitData(buffer, nullptr))) { + if (attributes.add(attribute_id, domain, data_type, bke::AttributeInitMoveArray(buffer))) { return true; } diff --git a/source/blender/editors/curves/intern/curves_ops.cc b/source/blender/editors/curves/intern/curves_ops.cc index 6b09a7233c5..c0aeb92e473 100644 --- a/source/blender/editors/curves/intern/curves_ops.cc +++ b/source/blender/editors/curves/intern/curves_ops.cc @@ -803,7 +803,7 @@ static int curves_set_selection_domain_exec(bContext *C, wmOperator *op) if (!attributes.add(".selection", domain, bke::cpp_type_to_custom_data_type(type), - bke::AttributeInitData(dst, nullptr))) { + bke::AttributeInitMoveArray(dst))) { MEM_freeN(dst); } } diff --git a/source/blender/editors/geometry/geometry_attributes.cc b/source/blender/editors/geometry/geometry_attributes.cc index 872404047db..6150f78bcde 100644 --- a/source/blender/editors/geometry/geometry_attributes.cc +++ b/source/blender/editors/geometry/geometry_attributes.cc @@ -709,8 +709,7 @@ bool ED_geometry_attribute_convert(Mesh *mesh, void *new_data = MEM_malloc_arrayN(varray.size(), cpp_type.size(), __func__); varray.materialize_to_uninitialized(new_data); attributes.remove(name_copy); - if (!attributes.add( - name_copy, dst_domain, dst_type, bke::AttributeInitData(new_data, nullptr))) { + if (!attributes.add(name_copy, dst_domain, dst_type, bke::AttributeInitMoveArray(new_data))) { MEM_freeN(new_data); } diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_selection.cc b/source/blender/editors/sculpt_paint/curves_sculpt_selection.cc index da6cdec32d0..ab601ddaa74 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_selection.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_selection.cc @@ -25,7 +25,7 @@ bke::SpanAttributeWriter float_selection_ensure(Curves &curves_id) attributes.remove(".selection"); attributes.add( - ".selection", meta_data->domain, CD_PROP_FLOAT, bke::AttributeInitData(dst, nullptr)); + ".selection", meta_data->domain, CD_PROP_FLOAT, bke::AttributeInitMoveArray(dst)); } } else { diff --git a/source/blender/geometry/intern/mesh_split_edges.cc b/source/blender/geometry/intern/mesh_split_edges.cc index 04fec824116..b3b6a21f415 100644 --- a/source/blender/geometry/intern/mesh_split_edges.cc +++ b/source/blender/geometry/intern/mesh_split_edges.cc @@ -154,7 +154,7 @@ static void add_new_edges(Mesh &mesh, attributes.add(new_data.local_id, ATTR_DOMAIN_EDGE, bke::cpp_type_to_custom_data_type(new_data.type), - bke::AttributeInitData(new_data.array, nullptr)); + bke::AttributeInitMoveArray(new_data.array)); } } diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc index 87cdfc6d625..655e1d826ba 100644 --- a/source/blender/modifiers/intern/MOD_nodes.cc +++ b/source/blender/modifiers/intern/MOD_nodes.cc @@ -1086,10 +1086,8 @@ static void store_computed_output_attributes( /* Try to create the attribute reusing the stored buffer. This will only succeed if the * attribute didn't exist before, or if it existed but was removed above. */ - if (attributes.add(store.name, - store.domain, - data_type, - bke::AttributeInitData(store.data.data(), nullptr))) { + if (attributes.add( + store.name, store.domain, data_type, bke::AttributeInitMoveArray(store.data.data()))) { continue; } diff --git a/source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc b/source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc index ae27e8d35e0..07b0111bec7 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc @@ -161,15 +161,13 @@ static void add_instances_from_component( bke::MutableAttributeAccessor dst_attributes = dst_component.attributes_for_write(); for (const auto item : attributes_to_propagate.items()) { const AttributeIDRef &id = item.key; - const eCustomDataType type = item.value.data_type; - const bke::GAttributeReader src = src_attributes.lookup_or_default( - id, ATTR_DOMAIN_POINT, type); - if (src.varray.size() == dst_component.instances_num()) { - dst_attributes.add(id, - ATTR_DOMAIN_INSTANCE, - type, - bke::AttributeInitData(src.varray.common_info().data, src.sharing_info)); + const bke::GAttributeReader src = src_attributes.lookup(id, ATTR_DOMAIN_POINT); + const eCustomDataType type = bke::cpp_type_to_custom_data_type(src.varray.type()); + if (src.varray.size() == dst_component.instances_num() && src.sharing_info) { + const bke::AttributeInitShared init(src.varray.get_internal_span().data(), + *src.sharing_info); + dst_attributes.add(id, ATTR_DOMAIN_INSTANCE, type, init); } else { GSpanAttributeWriter dst = dst_attributes.lookup_or_add_for_write_only_span( diff --git a/source/blender/nodes/geometry/nodes/node_geo_instances_to_points.cc b/source/blender/nodes/geometry/nodes/node_geo_instances_to_points.cc index 406d8402103..7de691ef08a 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_instances_to_points.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_instances_to_points.cc @@ -71,12 +71,11 @@ static void convert_instances_to_points(GeometrySet &geometry_set, const AttributeIDRef &id = item.key; const eCustomDataType type = item.value.data_type; - const GAttributeReader src = src_attributes.lookup_or_default(id, ATTR_DOMAIN_INSTANCE, type); - if (selection.size() == instances.instances_num()) { - dst_attributes.add(id, - ATTR_DOMAIN_POINT, - type, - bke::AttributeInitData(src.varray.common_info().data, src.sharing_info)); + const GAttributeReader src = src_attributes.lookup(id); + if (selection.size() == instances.instances_num() && src.sharing_info) { + const bke::AttributeInitShared init(src.varray.get_internal_span().data(), + *src.sharing_info); + dst_attributes.add(id, ATTR_DOMAIN_POINT, type, init); } else { GSpanAttributeWriter dst = dst_attributes.lookup_or_add_for_write_only_span( diff --git a/source/blender/nodes/geometry/nodes/node_geo_interpolate_curves.cc b/source/blender/nodes/geometry/nodes/node_geo_interpolate_curves.cc index a19bb42642c..aa82815012b 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_interpolate_curves.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_interpolate_curves.cc @@ -574,17 +574,13 @@ static void interpolate_curve_attributes(bke::CurvesGeometry &child_curves, if (id.is_anonymous() && !propagation_info.propagate(id.anonymous_id())) { return true; } - const eCustomDataType type = meta_data.data_type; - if (type == CD_PROP_STRING) { + if (meta_data.data_type == CD_PROP_STRING) { return true; } - const GAttributeReader src = point_attributes.lookup(id, ATTR_DOMAIN_POINT, type); - children_attributes.add( - id, - ATTR_DOMAIN_CURVE, - type, - bke::AttributeInitData(src.varray.common_info().data, src.sharing_info)); + const GAttributeReader src = point_attributes.lookup(id); + const bke::AttributeInitShared init(src.varray.get_internal_span().data(), *src.sharing_info); + children_attributes.add(id, ATTR_DOMAIN_CURVE, meta_data.data_type, init); return true; }); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc index d71f9199887..78f482150d9 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc @@ -83,15 +83,13 @@ static void geometry_set_mesh_to_points(GeometrySet &geometry_set, PointCloud *pointcloud; if (share_position) { - /* Create an empty point cloud so the positions can be easily shared with a generic utility. */ + /* Create an empty point cloud so the positions can be shared. */ pointcloud = BKE_pointcloud_new_nomain(0); CustomData_free_layer_named(&pointcloud->pdata, "position", pointcloud->totpoint); pointcloud->totpoint = mesh->totvert; const bke::AttributeReader src = src_attributes.lookup("position"); - pointcloud->attributes_for_write().add( - "position", - ATTR_DOMAIN_POINT, - bke::AttributeInitData(src.varray.common_info().data, src.sharing_info)); + const bke::AttributeInitShared init(src.varray.get_internal_span().data(), *src.sharing_info); + pointcloud->attributes_for_write().add("position", ATTR_DOMAIN_POINT, init); } else { pointcloud = BKE_pointcloud_new_nomain(selection.size()); @@ -117,11 +115,10 @@ static void geometry_set_mesh_to_points(GeometrySet &geometry_set, const AttributeIDRef attribute_id = entry.key; const eCustomDataType data_type = entry.value.data_type; const bke::GAttributeReader src = src_attributes.lookup(attribute_id, domain, data_type); - if (share_arrays && src.domain == domain) { - dst_attributes.add(attribute_id, - ATTR_DOMAIN_POINT, - data_type, - bke::AttributeInitData(src.varray.common_info().data, src.sharing_info)); + if (share_arrays && src.domain == domain && src.sharing_info) { + const bke::AttributeInitShared init(src.varray.get_internal_span().data(), + *src.sharing_info); + dst_attributes.add(attribute_id, ATTR_DOMAIN_POINT, data_type, init); } else { GSpanAttributeWriter dst = dst_attributes.lookup_or_add_for_write_only_span( diff --git a/source/blender/nodes/geometry/nodes/node_geo_points_to_vertices.cc b/source/blender/nodes/geometry/nodes/node_geo_points_to_vertices.cc index 6d7dc4a1b4e..203f0effcdf 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_points_to_vertices.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_points_to_vertices.cc @@ -51,6 +51,7 @@ static void geometry_set_points_to_vertices( Mesh *mesh; if (selection.size() == points->totpoint) { + /* Create a mesh without positions so the attribute can be shared. */ mesh = BKE_mesh_new_nomain(0, 0, 0, 0); CustomData_free_layer_named(&mesh->vdata, "position", mesh->totvert); mesh->totvert = selection.size(); @@ -66,11 +67,10 @@ static void geometry_set_points_to_vertices( const AttributeIDRef id = entry.key; const eCustomDataType data_type = entry.value.data_type; const GAttributeReader src = src_attributes.lookup(id); - if (selection.size() == points->totpoint) { - dst_attributes.add(id, - ATTR_DOMAIN_POINT, - data_type, - bke::AttributeInitData(src.varray.common_info().data, src.sharing_info)); + if (selection.size() == points->totpoint && src.sharing_info) { + const bke::AttributeInitShared init(src.varray.get_internal_span().data(), + *src.sharing_info); + dst_attributes.add(id, ATTR_DOMAIN_POINT, data_type, init); } else { GSpanAttributeWriter dst = dst_attributes.lookup_or_add_for_write_only_span( -- 2.30.2 From 3321664220341042f4cad887700104a22bcb1e61 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 18 Apr 2023 11:57:48 -0400 Subject: [PATCH 3/4] Fix missing check for empty virtual array --- .../nodes/geometry/nodes/node_geo_instance_on_points.cc | 6 +++++- .../blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc | 5 +++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc b/source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc index 07b0111bec7..f401459191e 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc @@ -161,8 +161,12 @@ static void add_instances_from_component( bke::MutableAttributeAccessor dst_attributes = dst_component.attributes_for_write(); for (const auto item : attributes_to_propagate.items()) { const AttributeIDRef &id = item.key; - const bke::GAttributeReader src = src_attributes.lookup(id, ATTR_DOMAIN_POINT); + if (!src) { + /* Domain interpolation can fail if the source domain is empty. */ + continue; + } + const eCustomDataType type = bke::cpp_type_to_custom_data_type(src.varray.type()); if (src.varray.size() == dst_component.instances_num() && src.sharing_info) { const bke::AttributeInitShared init(src.varray.get_internal_span().data(), diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc index 78f482150d9..57f4ada34ce 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc @@ -115,6 +115,11 @@ static void geometry_set_mesh_to_points(GeometrySet &geometry_set, const AttributeIDRef attribute_id = entry.key; const eCustomDataType data_type = entry.value.data_type; const bke::GAttributeReader src = src_attributes.lookup(attribute_id, domain, data_type); + if (!src) { + /* Domain interpolation can fail if the source domain is empty. */ + continue; + } + if (share_arrays && src.domain == domain && src.sharing_info) { const bke::AttributeInitShared init(src.varray.get_internal_span().data(), *src.sharing_info); -- 2.30.2 From 21ef74bbb320a576a68adda24f088cdb30e50c7e Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 18 Apr 2023 17:20:06 -0400 Subject: [PATCH 4/4] Check for .is_span() and don't assume attributes are shared in two places --- source/blender/blenkernel/intern/DerivedMesh.cc | 14 ++++++++++---- .../geometry/nodes/node_geo_instance_on_points.cc | 3 ++- .../geometry/nodes/node_geo_instances_to_points.cc | 3 ++- .../geometry/nodes/node_geo_interpolate_curves.cc | 11 +++++++++-- .../geometry/nodes/node_geo_mesh_to_points.cc | 2 +- .../geometry/nodes/node_geo_points_to_vertices.cc | 2 +- 6 files changed, 25 insertions(+), 10 deletions(-) diff --git a/source/blender/blenkernel/intern/DerivedMesh.cc b/source/blender/blenkernel/intern/DerivedMesh.cc index 09f688049d7..89802d9cb71 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.cc +++ b/source/blender/blenkernel/intern/DerivedMesh.cc @@ -660,10 +660,16 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph, MutableAttributeAccessor attributes = mesh_final->attributes_for_write(); const AttributeReader positions = attributes.lookup("position"); if (positions) { - attributes.add( - "rest_position", - ATTR_DOMAIN_POINT, - AttributeInitShared(positions.varray.common_info().data, *positions.sharing_info)); + if (positions.sharing_info && positions.varray.is_span()) { + attributes.add("rest_position", + ATTR_DOMAIN_POINT, + AttributeInitShared(positions.varray.get_internal_span().data(), + *positions.sharing_info)); + } + else { + attributes.add( + "rest_position", ATTR_DOMAIN_POINT, AttributeInitVArray(positions.varray)); + } } } diff --git a/source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc b/source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc index f401459191e..f164329cc96 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc @@ -168,7 +168,8 @@ static void add_instances_from_component( } const eCustomDataType type = bke::cpp_type_to_custom_data_type(src.varray.type()); - if (src.varray.size() == dst_component.instances_num() && src.sharing_info) { + if (src.varray.size() == dst_component.instances_num() && src.sharing_info && + src.varray.is_span()) { const bke::AttributeInitShared init(src.varray.get_internal_span().data(), *src.sharing_info); dst_attributes.add(id, ATTR_DOMAIN_INSTANCE, type, init); diff --git a/source/blender/nodes/geometry/nodes/node_geo_instances_to_points.cc b/source/blender/nodes/geometry/nodes/node_geo_instances_to_points.cc index 7de691ef08a..f0145741e32 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_instances_to_points.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_instances_to_points.cc @@ -72,7 +72,8 @@ static void convert_instances_to_points(GeometrySet &geometry_set, const eCustomDataType type = item.value.data_type; const GAttributeReader src = src_attributes.lookup(id); - if (selection.size() == instances.instances_num() && src.sharing_info) { + if (selection.size() == instances.instances_num() && src.sharing_info && + src.varray.is_span()) { const bke::AttributeInitShared init(src.varray.get_internal_span().data(), *src.sharing_info); dst_attributes.add(id, ATTR_DOMAIN_POINT, type, init); diff --git a/source/blender/nodes/geometry/nodes/node_geo_interpolate_curves.cc b/source/blender/nodes/geometry/nodes/node_geo_interpolate_curves.cc index aa82815012b..1b119f63bc0 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_interpolate_curves.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_interpolate_curves.cc @@ -579,8 +579,15 @@ static void interpolate_curve_attributes(bke::CurvesGeometry &child_curves, } const GAttributeReader src = point_attributes.lookup(id); - const bke::AttributeInitShared init(src.varray.get_internal_span().data(), *src.sharing_info); - children_attributes.add(id, ATTR_DOMAIN_CURVE, meta_data.data_type, init); + if (src.sharing_info && src.varray.is_span()) { + const bke::AttributeInitShared init(src.varray.get_internal_span().data(), + *src.sharing_info); + children_attributes.add(id, ATTR_DOMAIN_CURVE, meta_data.data_type, init); + } + else { + children_attributes.add( + id, ATTR_DOMAIN_CURVE, meta_data.data_type, bke::AttributeInitVArray(src.varray)); + } return true; }); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc index 57f4ada34ce..f6b44a9ac47 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc @@ -120,7 +120,7 @@ static void geometry_set_mesh_to_points(GeometrySet &geometry_set, continue; } - if (share_arrays && src.domain == domain && src.sharing_info) { + if (share_arrays && src.domain == domain && src.sharing_info && src.varray.is_span()) { const bke::AttributeInitShared init(src.varray.get_internal_span().data(), *src.sharing_info); dst_attributes.add(attribute_id, ATTR_DOMAIN_POINT, data_type, init); diff --git a/source/blender/nodes/geometry/nodes/node_geo_points_to_vertices.cc b/source/blender/nodes/geometry/nodes/node_geo_points_to_vertices.cc index 203f0effcdf..e97f4de5b65 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_points_to_vertices.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_points_to_vertices.cc @@ -67,7 +67,7 @@ static void geometry_set_points_to_vertices( const AttributeIDRef id = entry.key; const eCustomDataType data_type = entry.value.data_type; const GAttributeReader src = src_attributes.lookup(id); - if (selection.size() == points->totpoint && src.sharing_info) { + if (selection.size() == points->totpoint && src.sharing_info && src.varray.is_span()) { const bke::AttributeInitShared init(src.varray.get_internal_span().data(), *src.sharing_info); dst_attributes.add(id, ATTR_DOMAIN_POINT, data_type, init); -- 2.30.2