diff options
author | Dennis Ranish <Codec> | 2022-06-08 22:10:32 +0300 |
---|---|---|
committer | Joseph Eagar <joeedh@gmail.com> | 2022-06-08 22:10:32 +0300 |
commit | 9c28f0eb37aebd6e5eae0763b008ef02d5ce081b (patch) | |
tree | 65bc5d816ffc13a30ebf9aa454dd6fee7f512ed1 /source/blender/blenkernel/intern | |
parent | f69c565a33ca58bb95a2bd22de0e211799508182 (diff) |
D14823: Adds operator to duplicate the active color attribute layer
Fixes T97706
Adds operator to duplicate the active color attribute layer.
Adds `"Color Attribute Specials"` menu to color attribute ui to access the `"geometry.color_attribute_duplicate"` operator.
Internally adds a function that duplicates a referenced CustomDataLayer
- `BKE_id_attribute_duplicate` mostly copies the existing `BKE_id_attribute_new`
- but gets the type and domain from the referenced layer
- and copies the data from the old layer into the new layer
Reviewed By: Joseph Eagar & Hans Goudey & Julien Kaspar
Differential Revision: https://developer.blender.org/D14823
Ref D14823
Diffstat (limited to 'source/blender/blenkernel/intern')
-rw-r--r-- | source/blender/blenkernel/intern/attribute.cc | 53 |
1 files changed, 51 insertions, 2 deletions
diff --git a/source/blender/blenkernel/intern/attribute.cc b/source/blender/blenkernel/intern/attribute.cc index eac42d19b52..b2ea8b833b3 100644 --- a/source/blender/blenkernel/intern/attribute.cc +++ b/source/blender/blenkernel/intern/attribute.cc @@ -208,6 +208,55 @@ CustomDataLayer *BKE_id_attribute_new( return (index == -1) ? nullptr : &(customdata->layers[index]); } +CustomDataLayer *BKE_id_attribute_duplicate(ID *id, CustomDataLayer *layer, ReportList *reports) +{ + DomainInfo info[ATTR_DOMAIN_NUM]; + get_domains(id, info); + + eCustomDataType type = (eCustomDataType)layer->type; + eAttrDomain domain = BKE_id_attribute_domain(id, layer); + + CustomData *customdata = info[domain].customdata; + if (customdata == nullptr) { + BKE_report(reports, RPT_ERROR, "Attribute domain not supported by this geometry type"); + return nullptr; + } + + char name[MAX_CUSTOMDATA_LAYER_NAME]; + char uniquename[MAX_CUSTOMDATA_LAYER_NAME]; + + /* Make a copy of name in case CustomData API reallocates the layers. */ + BLI_strncpy(name, layer->name, MAX_CUSTOMDATA_LAYER_NAME); + BKE_id_attribute_calc_unique_name(id, layer->name, uniquename); + + switch (GS(id->name)) { + case ID_ME: { + Mesh *me = (Mesh *)id; + BMEditMesh *em = me->edit_mesh; + if (em != nullptr) { + BM_data_layer_add_named(em->bm, customdata, type, uniquename); + } + else { + CustomData_add_layer_named( + customdata, type, CD_DEFAULT, nullptr, info[domain].length, uniquename); + } + break; + } + default: { + CustomData_add_layer_named( + customdata, type, CD_DEFAULT, nullptr, info[domain].length, uniquename); + break; + } + } + + int from_index = CustomData_get_named_layer_index(customdata, type, name); + int to_index = CustomData_get_named_layer_index(customdata, type, uniquename); + CustomData_copy_data_layer( + customdata, customdata, from_index, to_index, 0, 0, info[domain].length); + + return (to_index == -1) ? nullptr : &(customdata->layers[to_index]); +} + bool BKE_id_attribute_remove(ID *id, const char *name, ReportList *reports) { if (BKE_id_attribute_required(id, name)) { @@ -283,7 +332,7 @@ CustomDataLayer *BKE_id_attribute_search(const ID *id, } CustomData *customdata = info[domain].customdata; - if (customdata == NULL) { + if (customdata == nullptr) { continue; } @@ -295,7 +344,7 @@ CustomDataLayer *BKE_id_attribute_search(const ID *id, } } - return NULL; + return nullptr; } int BKE_id_attributes_length(const ID *id, eAttrDomainMask domain_mask, eCustomDataMask mask) |