diff options
-rw-r--r-- | release/scripts/startup/bl_ui/properties_data_mesh.py | 18 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_attribute.h | 7 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/attribute.cc | 53 | ||||
-rw-r--r-- | source/blender/editors/geometry/geometry_attributes.cc | 52 | ||||
-rw-r--r-- | source/blender/editors/geometry/geometry_intern.hh | 1 | ||||
-rw-r--r-- | source/blender/editors/geometry/geometry_ops.cc | 1 |
6 files changed, 129 insertions, 3 deletions
diff --git a/release/scripts/startup/bl_ui/properties_data_mesh.py b/release/scripts/startup/bl_ui/properties_data_mesh.py index 15d25f71419..764299e7ce3 100644 --- a/release/scripts/startup/bl_ui/properties_data_mesh.py +++ b/release/scripts/startup/bl_ui/properties_data_mesh.py @@ -64,6 +64,18 @@ class MESH_MT_shape_key_context_menu(Menu): layout.operator("object.shape_key_move", icon='TRIA_DOWN_BAR', text="Move to Bottom").type = 'BOTTOM' +class MESH_MT_color_attribute_context_menu(Menu): + bl_label = "Color Attribute Specials" + + def draw(self, _context): + layout = self.layout + + props = layout.operator( + "geometry.color_attribute_duplicate", + icon='DUPLICATE', + ) + + class MESH_MT_attribute_context_menu(Menu): bl_label = "Attribute Specials" @@ -660,12 +672,16 @@ class DATA_PT_vertex_colors(DATA_PT_mesh_attributes, Panel): col.operator("geometry.color_attribute_add", icon='ADD', text="") col.operator("geometry.color_attribute_remove", icon='REMOVE', text="") - self.draw_attribute_warnings(context, layout) + col.separator() + col.menu("MESH_MT_color_attribute_context_menu", icon='DOWNARROW_HLT', text="") + + self.draw_attribute_warnings(context, layout) classes = ( MESH_MT_vertex_group_context_menu, MESH_MT_shape_key_context_menu, + MESH_MT_color_attribute_context_menu, MESH_MT_attribute_context_menu, MESH_UL_vgroups, MESH_UL_fmaps, diff --git a/source/blender/blenkernel/BKE_attribute.h b/source/blender/blenkernel/BKE_attribute.h index 52a3e01026c..5755ddb3018 100644 --- a/source/blender/blenkernel/BKE_attribute.h +++ b/source/blender/blenkernel/BKE_attribute.h @@ -60,6 +60,13 @@ struct CustomDataLayer *BKE_id_attribute_new( struct ID *id, const char *name, int type, eAttrDomain domain, struct ReportList *reports); bool BKE_id_attribute_remove(struct ID *id, const char *name, struct ReportList *reports); +/** + * Creates a duplicate attribute layer. + */ +struct CustomDataLayer *BKE_id_attribute_duplicate(struct ID *id, + struct CustomDataLayer *layer, + struct ReportList *reports); + struct CustomDataLayer *BKE_id_attribute_find(const struct ID *id, const char *name, int type, 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) diff --git a/source/blender/editors/geometry/geometry_attributes.cc b/source/blender/editors/geometry/geometry_attributes.cc index 63059a49a9e..37ec7a61bcb 100644 --- a/source/blender/editors/geometry/geometry_attributes.cc +++ b/source/blender/editors/geometry/geometry_attributes.cc @@ -498,6 +498,7 @@ static bool geometry_color_attributes_remove_poll(bContext *C) return false; } + void GEOMETRY_OT_color_attribute_remove(wmOperatorType *ot) { /* identifiers */ @@ -513,6 +514,57 @@ void GEOMETRY_OT_color_attribute_remove(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } +static int geometry_color_attribute_duplicate_exec(bContext *C, wmOperator *op) +{ + Object *ob = ED_object_context(C); + ID *id = static_cast<ID *>(ob->data); + CustomDataLayer *layer = BKE_id_attributes_active_color_get(id); + + if (layer == nullptr) { + return OPERATOR_CANCELLED; + } + + CustomDataLayer *newLayer = BKE_id_attribute_duplicate(id, layer, op->reports); + + BKE_id_attributes_active_color_set(id, newLayer); + + DEG_id_tag_update(id, ID_RECALC_GEOMETRY); + WM_main_add_notifier(NC_GEOM | ND_DATA, id); + + return OPERATOR_FINISHED; +} + +static bool geometry_color_attributes_duplicate_poll(bContext *C) +{ + if (!geometry_attributes_poll(C)) { + return false; + } + + Object *ob = ED_object_context(C); + ID *data = ob ? static_cast<ID *>(ob->data) : nullptr; + + if (BKE_id_attributes_active_color_get(data) != nullptr) { + return true; + } + + return false; +} + +void GEOMETRY_OT_color_attribute_duplicate(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Duplicate Color Attribute"; + ot->description = "Duplicate color attribute"; + ot->idname = "GEOMETRY_OT_color_attribute_duplicate"; + + /* api callbacks */ + ot->exec = geometry_color_attribute_duplicate_exec; + ot->poll = geometry_color_attributes_duplicate_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + static void geometry_attribute_convert_ui(bContext *UNUSED(C), wmOperator *op) { uiLayout *layout = op->layout; diff --git a/source/blender/editors/geometry/geometry_intern.hh b/source/blender/editors/geometry/geometry_intern.hh index bbcb682d6bf..a1000a5d01f 100644 --- a/source/blender/editors/geometry/geometry_intern.hh +++ b/source/blender/editors/geometry/geometry_intern.hh @@ -17,6 +17,7 @@ void GEOMETRY_OT_attribute_remove(struct wmOperatorType *ot); void GEOMETRY_OT_color_attribute_add(struct wmOperatorType *ot); void GEOMETRY_OT_color_attribute_remove(struct wmOperatorType *ot); void GEOMETRY_OT_color_attribute_render_set(struct wmOperatorType *ot); +void GEOMETRY_OT_color_attribute_duplicate(struct wmOperatorType *ot); void GEOMETRY_OT_attribute_convert(struct wmOperatorType *ot); } // namespace blender::ed::geometry diff --git a/source/blender/editors/geometry/geometry_ops.cc b/source/blender/editors/geometry/geometry_ops.cc index 23f6e6f29f4..acac757ecf1 100644 --- a/source/blender/editors/geometry/geometry_ops.cc +++ b/source/blender/editors/geometry/geometry_ops.cc @@ -22,5 +22,6 @@ void ED_operatortypes_geometry(void) WM_operatortype_append(GEOMETRY_OT_color_attribute_add); WM_operatortype_append(GEOMETRY_OT_color_attribute_remove); WM_operatortype_append(GEOMETRY_OT_color_attribute_render_set); + WM_operatortype_append(GEOMETRY_OT_color_attribute_duplicate); WM_operatortype_append(GEOMETRY_OT_attribute_convert); } |