diff --git a/source/blender/blenkernel/BKE_attribute.hh b/source/blender/blenkernel/BKE_attribute.hh index 6b887b8eeda..d7339e14dbc 100644 --- a/source/blender/blenkernel/BKE_attribute.hh +++ b/source/blender/blenkernel/BKE_attribute.hh @@ -86,6 +86,8 @@ struct AttributeInit { VArray, /** #AttributeInitMoveArray. */ MoveArray, + /** #AttributeInitShared. */ + Shared, }; Type type; AttributeInit(const Type type) : type(type) {} @@ -121,9 +123,6 @@ 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. */ @@ -133,6 +132,20 @@ struct AttributeInitMoveArray : public AttributeInit { 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; + + AttributeInitShared(const void *data, const ImplicitSharingInfo &sharing_info) + : AttributeInit(Type::Shared), data(data), sharing_info(&sharing_info) + { + } +}; + /* Returns false when the iteration should be stopped. */ using AttributeForeachCallback = FunctionRef; @@ -151,6 +164,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 +298,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 +495,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 +512,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 +523,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 +537,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 +665,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..89802d9cb71 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.cc +++ b/source/blender/blenkernel/intern/DerivedMesh.cc @@ -658,11 +658,18 @@ 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) { + 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/blenkernel/intern/attribute_access.cc b/source/blender/blenkernel/intern/attribute_access.cc index b2c1ce0fcbe..1253d11217a 100644 --- a/source/blender/blenkernel/intern/attribute_access.cc +++ b/source/blender/blenkernel/intern/attribute_access.cc @@ -218,6 +218,12 @@ static bool add_builtin_type_custom_data_layer_from_init(CustomData &custom_data } 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; + } } BLI_assert_unreachable(); @@ -293,6 +299,16 @@ static bool add_custom_data_layer_from_attribute_init(const AttributeIDRef &attr 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, + domain_num, + const_cast(init.data), + init.sharing_info); + break; + } } return old_layer_num < custom_data.totlayer; } @@ -314,7 +330,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) { @@ -326,22 +342,23 @@ 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 GVArray::ForSpan({type, nullptr, 0}); + return {GVArray::ForSpan({type, nullptr, 0}), 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 GVArray::ForSpan({type, data, element_num}); + const CustomDataLayer &layer = custom_data->layers[index]; + return {GVArray::ForSpan({type, layer.data, element_num}), domain_, layer.sharing_info}; } GAttributeWriter BuiltinCustomDataLayerProvider::try_get_for_write(void *owner) const @@ -472,7 +489,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 {}; } @@ -729,50 +746,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 @@ -921,7 +940,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 b10c0974b31..7d750773a50 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; @@ -196,7 +196,7 @@ class BuiltinCustomDataLayerProvider final : public BuiltinAttributeProvider { { } - 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; @@ -279,7 +279,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_instances.cc b/source/blender/blenkernel/intern/geometry_component_instances.cc index 80f97ceebc6..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 diff --git a/source/blender/blenkernel/intern/geometry_component_mesh.cc b/source/blender/blenkernel/intern/geometry_component_mesh.cc index eed603870c7..0f70d9ac48a 100644 --- a/source/blender/blenkernel/intern/geometry_component_mesh.cc +++ b/source/blender/blenkernel/intern/geometry_component_mesh.cc @@ -1114,7 +1114,7 @@ static ComponentAttributeProviders create_attribute_providers_for_mesh() ATTR_DOMAIN_POINT, CD_PROP_FLOAT3, CD_PROP_FLOAT3, - BuiltinAttributeProvider::NonCreatable, + BuiltinAttributeProvider::Creatable, BuiltinAttributeProvider::NonDeletable, point_access, tag_component_positions_changed); diff --git a/source/blender/blenkernel/intern/geometry_component_pointcloud.cc b/source/blender/blenkernel/intern/geometry_component_pointcloud.cc index 7a6b62fab4d..267daad48d7 100644 --- a/source/blender/blenkernel/intern/geometry_component_pointcloud.cc +++ b/source/blender/blenkernel/intern/geometry_component_pointcloud.cc @@ -139,7 +139,7 @@ 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, tag_component_positions_changed); diff --git a/source/blender/blenkernel/intern/geometry_fields.cc b/source/blender/blenkernel/intern/geometry_fields.cc index 64a000ca4cf..f3ce41bcdae 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::AttributeInitMoveArray(buffer))) { 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 b67696432d4..14be0979940 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 bd157162961..bcfc19335d1 100644 --- a/source/blender/draw/intern/draw_cache_impl_curves.cc +++ b/source/blender/draw/intern/draw_cache_impl_curves.cc @@ -268,7 +268,7 @@ static void curves_batch_cache_ensure_edit_points_selection(const bke::CurvesGeo MutableSpan data(static_cast(GPU_vertbuf_get_data(cache.edit_points_selection)), curves.points_num()); - const VArray attribute = curves.attributes().lookup_or_default( + const VArray attribute = *curves.attributes().lookup_or_default( ".selection", ATTR_DOMAIN_POINT, true); attribute.materialize(data); } @@ -343,14 +343,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..c0aeb92e473 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); 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..6150f78bcde 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,15 @@ 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::AttributeInitMoveArray(new_data))) { + 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..ab601ddaa74 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_selection.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_selection.cc @@ -18,7 +18,7 @@ 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()}); 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_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..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, - bke::cpp_type_to_custom_data_type(store.data.type()), - bke::AttributeInitMoveArray(store.data.data()))) { + 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_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..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 @@ -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,28 @@ 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 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 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 && + 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); + } + 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..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 @@ -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(id); + 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); + } + 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..1b119f63bc0 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(); @@ -579,14 +578,16 @@ static void interpolate_curve_attributes(bke::CurvesGeometry &child_curves, 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; + const GAttributeReader src = point_attributes.lookup(id); + 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)); } - src.materialize(dst.span.data()); - dst.finish(); return true; }); } @@ -673,7 +674,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..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 @@ -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,30 @@ 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 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"); + 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()); + 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 +108,32 @@ 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 (!src) { + /* Domain interpolation can fail if the source domain is empty. */ + continue; + } + + 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); + } + 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..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 @@ -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) { + /* 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(); + } + 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 && 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); + } + 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__));