diff --git a/source/blender/blenkernel/BKE_attribute.h b/source/blender/blenkernel/BKE_attribute.h index 81d57ddcd5a..40596bc38e1 100644 --- a/source/blender/blenkernel/BKE_attribute.h +++ b/source/blender/blenkernel/BKE_attribute.h @@ -79,10 +79,15 @@ struct CustomDataLayer *BKE_id_attribute_find(const struct ID *id, eCustomDataType type, eAttrDomain domain); -struct CustomDataLayer *BKE_id_attribute_search(struct ID *id, - const char *name, - eCustomDataMask type, - eAttrDomainMask domain_mask); +const struct CustomDataLayer *BKE_id_attribute_search(const struct ID *id, + const char *name, + eCustomDataMask type, + eAttrDomainMask domain_mask); + +struct CustomDataLayer *BKE_id_attribute_search_for_write(struct ID *id, + const char *name, + eCustomDataMask type, + eAttrDomainMask domain_mask); eAttrDomain BKE_id_attribute_domain(const struct ID *id, const struct CustomDataLayer *layer); int BKE_id_attribute_data_length(struct ID *id, struct CustomDataLayer *layer); diff --git a/source/blender/blenkernel/intern/attribute.cc b/source/blender/blenkernel/intern/attribute.cc index 1cb3e2b3b64..68c20c91d4e 100644 --- a/source/blender/blenkernel/intern/attribute.cc +++ b/source/blender/blenkernel/intern/attribute.cc @@ -158,7 +158,7 @@ static bool bke_id_attribute_rename_if_exists(ID *id, const char *new_name, ReportList *reports) { - CustomDataLayer *layer = BKE_id_attribute_search( + CustomDataLayer *layer = BKE_id_attribute_search_for_write( id, old_name, CD_MASK_PROP_ALL, ATTR_DOMAIN_MASK_ALL); if (layer == nullptr) { return false; @@ -194,7 +194,7 @@ bool BKE_id_attribute_rename(ID *id, } } - CustomDataLayer *layer = BKE_id_attribute_search( + CustomDataLayer *layer = BKE_id_attribute_search_for_write( id, old_name, CD_MASK_PROP_ALL, ATTR_DOMAIN_MASK_ALL); if (layer == nullptr) { BKE_report(reports, RPT_ERROR, "Attribute is not part of this geometry"); @@ -383,7 +383,7 @@ CustomDataLayer *BKE_id_attribute_duplicate(ID *id, const char *name, ReportList BKE_uv_map_pin_name_get(uniquename, buffer_dst)); } - return BKE_id_attribute_search(id, uniquename, CD_MASK_PROP_ALL, ATTR_DOMAIN_MASK_ALL); + return BKE_id_attribute_search_for_write(id, uniquename, CD_MASK_PROP_ALL, ATTR_DOMAIN_MASK_ALL); } static int color_name_to_index(ID *id, const char *name) @@ -540,10 +540,10 @@ CustomDataLayer *BKE_id_attribute_find(const ID *id, return nullptr; } -CustomDataLayer *BKE_id_attribute_search(ID *id, - const char *name, - const eCustomDataMask type_mask, - const eAttrDomainMask domain_mask) +const CustomDataLayer *BKE_id_attribute_search(const ID *id, + const char *name, + const eCustomDataMask type_mask, + const eAttrDomainMask domain_mask) { if (!name) { return nullptr; @@ -574,6 +574,28 @@ CustomDataLayer *BKE_id_attribute_search(ID *id, return nullptr; } +CustomDataLayer *BKE_id_attribute_search_for_write(ID *id, + const char *name, + const eCustomDataMask type_mask, + const eAttrDomainMask domain_mask) +{ + /* Reuse the implementation of the const version. + * Implicit sharing for the layer's data is handled below. */ + CustomDataLayer *layer = const_cast( + BKE_id_attribute_search(id, name, type_mask, domain_mask)); + if (!layer) { + return nullptr; + } + + DomainInfo info[ATTR_DOMAIN_NUM]; + get_domains(id, info); + + const eAttrDomain domain = BKE_id_attribute_domain(id, layer); + CustomData_ensure_data_is_mutable(layer, info[domain].length); + + return layer; +} + int BKE_id_attributes_length(const ID *id, eAttrDomainMask domain_mask, eCustomDataMask mask) { DomainInfo info[ATTR_DOMAIN_NUM]; diff --git a/source/blender/blenkernel/intern/pbvh.cc b/source/blender/blenkernel/intern/pbvh.cc index 1e2eb2902ef..e7d5e772078 100644 --- a/source/blender/blenkernel/intern/pbvh.cc +++ b/source/blender/blenkernel/intern/pbvh.cc @@ -1430,7 +1430,7 @@ static void pbvh_update_BB_redraw(PBVH *pbvh, Span nodes, int flag) bool BKE_pbvh_get_color_layer(Mesh *me, CustomDataLayer **r_layer, eAttrDomain *r_domain) { - *r_layer = BKE_id_attribute_search( + *r_layer = BKE_id_attribute_search_for_write( &me->id, me->active_color_attribute, CD_MASK_COLOR_ALL, ATTR_DOMAIN_MASK_COLOR); *r_domain = *r_layer ? BKE_id_attribute_domain(&me->id, *r_layer) : ATTR_DOMAIN_POINT; return *r_layer != nullptr; diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.cc b/source/blender/editors/sculpt_paint/sculpt_undo.cc index 270e840737a..f9eb45f201c 100644 --- a/source/blender/editors/sculpt_paint/sculpt_undo.cc +++ b/source/blender/editors/sculpt_paint/sculpt_undo.cc @@ -1766,7 +1766,7 @@ static void sculpt_undo_set_active_layer(bContext *C, SculptAttrRef *attr) * domain and just unconvert it. */ if (!layer) { - layer = BKE_id_attribute_search(&me->id, attr->name, CD_MASK_PROP_ALL, ATTR_DOMAIN_MASK_ALL); + layer = BKE_id_attribute_search_for_write(&me->id, attr->name, CD_MASK_PROP_ALL, ATTR_DOMAIN_MASK_ALL); if (layer) { if (ED_geometry_attribute_convert( me, attr->name, eCustomDataType(attr->type), attr->domain, nullptr)) diff --git a/source/blender/makesrna/intern/rna_attribute.cc b/source/blender/makesrna/intern/rna_attribute.cc index 62304d2937f..dbd846e1851 100644 --- a/source/blender/makesrna/intern/rna_attribute.cc +++ b/source/blender/makesrna/intern/rna_attribute.cc @@ -590,10 +590,11 @@ static void rna_AttributeGroup_update_active(Main *bmain, Scene *scene, PointerR static PointerRNA rna_AttributeGroup_active_color_get(PointerRNA *ptr) { ID *id = ptr->owner_id; - CustomDataLayer *layer = BKE_id_attribute_search(ptr->owner_id, - BKE_id_attributes_active_color_name(id), - CD_MASK_COLOR_ALL, - ATTR_DOMAIN_MASK_COLOR); + CustomDataLayer *layer = BKE_id_attribute_search_for_write( + ptr->owner_id, + BKE_id_attributes_active_color_name(id), + CD_MASK_COLOR_ALL, + ATTR_DOMAIN_MASK_COLOR); PointerRNA attribute_ptr = RNA_pointer_create(id, &RNA_Attribute, layer); return attribute_ptr; diff --git a/source/blender/makesrna/intern/rna_mesh.cc b/source/blender/makesrna/intern/rna_mesh.cc index 7b4a8a45fa2..6624570d2ff 100644 --- a/source/blender/makesrna/intern/rna_mesh.cc +++ b/source/blender/makesrna/intern/rna_mesh.cc @@ -1080,7 +1080,7 @@ DEFINE_CUSTOMDATA_LAYER_COLLECTION(vertex_color, ldata, CD_PROP_BYTE_COLOR) static PointerRNA rna_Mesh_vertex_color_active_get(PointerRNA *ptr) { Mesh *mesh = (Mesh *)ptr->data; - CustomDataLayer *layer = BKE_id_attribute_search( + CustomDataLayer *layer = BKE_id_attribute_search_for_write( &mesh->id, mesh->active_color_attribute, CD_MASK_PROP_BYTE_COLOR, ATTR_DOMAIN_MASK_CORNER); return rna_pointer_inherit_refine(ptr, &RNA_MeshLoopColorLayer, layer); } @@ -1102,7 +1102,7 @@ static void rna_Mesh_vertex_color_active_set(PointerRNA *ptr, static int rna_Mesh_vertex_color_active_index_get(PointerRNA *ptr) { Mesh *mesh = (Mesh *)ptr->data; - CustomDataLayer *layer = BKE_id_attribute_search( + const CustomDataLayer *layer = BKE_id_attribute_search( &mesh->id, mesh->active_color_attribute, CD_MASK_PROP_BYTE_COLOR, ATTR_DOMAIN_MASK_CORNER); if (!layer) { return 0;