diff options
Diffstat (limited to 'source/blender/editors/geometry/geometry_attributes.cc')
-rw-r--r-- | source/blender/editors/geometry/geometry_attributes.cc | 213 |
1 files changed, 209 insertions, 4 deletions
diff --git a/source/blender/editors/geometry/geometry_attributes.cc b/source/blender/editors/geometry/geometry_attributes.cc index 5d9d02db660..75094b46c8b 100644 --- a/source/blender/editors/geometry/geometry_attributes.cc +++ b/source/blender/editors/geometry/geometry_attributes.cc @@ -16,6 +16,7 @@ #include "BKE_deform.h" #include "BKE_geometry_set.hh" #include "BKE_lib_id.h" +#include "BKE_mesh.h" #include "BKE_object_deform.h" #include "BKE_report.h" @@ -103,6 +104,35 @@ static int geometry_attribute_add_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } +static void next_color_attribute(struct ID *id, CustomDataLayer *layer, bool is_render) +{ + int index = BKE_id_attribute_to_index(id, layer, ATTR_DOMAIN_MASK_COLOR, CD_MASK_COLOR_ALL); + + index++; + + layer = BKE_id_attribute_from_index(id, index, ATTR_DOMAIN_MASK_COLOR, CD_MASK_COLOR_ALL); + + if (!layer) { + index = 0; + layer = BKE_id_attribute_from_index(id, index, ATTR_DOMAIN_MASK_COLOR, CD_MASK_COLOR_ALL); + } + + if (layer) { + if (is_render) { + BKE_id_attributes_active_color_set(id, layer); + } + else { + BKE_id_attributes_render_color_set(id, layer); + } + } +} + +static void next_color_attributes(struct ID *id, CustomDataLayer *layer) +{ + next_color_attribute(id, layer, false); /* active */ + next_color_attribute(id, layer, true); /* render */ +} + void GEOMETRY_OT_attribute_add(wmOperatorType *ot) { /* identifiers */ @@ -148,9 +178,7 @@ static int geometry_attribute_remove_exec(bContext *C, wmOperator *op) ID *id = static_cast<ID *>(ob->data); CustomDataLayer *layer = BKE_id_attributes_active_get(id); - if (layer == nullptr) { - return OPERATOR_CANCELLED; - } + next_color_attributes(id, layer); if (!BKE_id_attribute_remove(id, layer, op->reports)) { return OPERATOR_CANCELLED; @@ -182,6 +210,33 @@ void GEOMETRY_OT_attribute_remove(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } +static int geometry_color_attribute_add_exec(bContext *C, wmOperator *op) +{ + Object *ob = ED_object_context(C); + ID *id = static_cast<ID *>(ob->data); + + char name[MAX_NAME]; + RNA_string_get(op->ptr, "name", name); + CustomDataType type = (CustomDataType)RNA_enum_get(op->ptr, "data_type"); + AttributeDomain domain = (AttributeDomain)RNA_enum_get(op->ptr, "domain"); + CustomDataLayer *layer = BKE_id_attribute_new(id, name, type, domain, op->reports); + + if (layer == nullptr) { + return OPERATOR_CANCELLED; + } + + BKE_id_attributes_active_color_set(id, layer); + + if (!BKE_id_attributes_render_color_get(id)) { + BKE_id_attributes_render_color_set(id, layer); + } + + DEG_id_tag_update(id, ID_RECALC_GEOMETRY); + WM_main_add_notifier(NC_GEOM | ND_DATA, id); + + return OPERATOR_FINISHED; +} + enum class ConvertAttributeMode { Generic, UVMap, @@ -304,6 +359,156 @@ static int geometry_attribute_convert_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } +void GEOMETRY_OT_color_attribute_add(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Add Geometry Attribute"; + ot->description = "Add attribute to geometry"; + ot->idname = "GEOMETRY_OT_color_attribute_add"; + + /* api callbacks */ + ot->poll = geometry_attributes_poll; + ot->exec = geometry_color_attribute_add_exec; + ot->invoke = WM_operator_props_popup_confirm; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + PropertyRNA *prop; + + prop = RNA_def_string(ot->srna, "name", "Color", MAX_NAME, "Name", "Name of color attribute"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); + + static EnumPropertyItem domains[3] = {{ATTR_DOMAIN_POINT, "POINT", 0, "Point", ""}, + {ATTR_DOMAIN_CORNER, "CORNER", 0, "Face Corner", ""}, + {0, nullptr, 0, nullptr, nullptr}}; + + static EnumPropertyItem types[3] = {{CD_PROP_COLOR, "COLOR", 0, "Color", ""}, + {CD_MLOOPCOL, "BYTE_COLOR", 0, "Byte Color", ""}, + {0, nullptr, 0, nullptr, nullptr}}; + + prop = RNA_def_enum(ot->srna, + "domain", + domains, + ATTR_DOMAIN_POINT, + "Domain", + "Type of element that attribute is stored on"); + + RNA_def_property_flag(prop, PROP_SKIP_SAVE); + + prop = RNA_def_enum(ot->srna, + "data_type", + types, + CD_PROP_COLOR, + "Data Type", + "Type of data stored in attribute"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); +} + +static int geometry_color_attribute_set_render_exec(bContext *C, wmOperator *op) +{ + Object *ob = ED_object_context(C); + ID *id = static_cast<ID *>(ob->data); + + char name[MAX_NAME]; + RNA_string_get(op->ptr, "name", name); + + CustomDataLayer *layer = BKE_id_attribute_find(id, name, CD_PROP_COLOR, ATTR_DOMAIN_POINT); + layer = !layer ? BKE_id_attribute_find(id, name, CD_MLOOPCOL, ATTR_DOMAIN_POINT) : layer; + layer = !layer ? BKE_id_attribute_find(id, name, CD_PROP_COLOR, ATTR_DOMAIN_CORNER) : layer; + layer = !layer ? BKE_id_attribute_find(id, name, CD_MLOOPCOL, ATTR_DOMAIN_CORNER) : layer; + + if (layer) { + BKE_id_attributes_render_color_set(id, layer); + + DEG_id_tag_update(id, ID_RECALC_GEOMETRY); + WM_main_add_notifier(NC_GEOM | ND_DATA, id); + + return OPERATOR_FINISHED; + } + + return OPERATOR_CANCELLED; +} + +void GEOMETRY_OT_color_attribute_render_set(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Set Render Color Attribute"; + ot->description = "Set default color attribute used for rendering"; + ot->idname = "GEOMETRY_OT_color_attribute_render_set"; + + /* api callbacks */ + ot->poll = geometry_attributes_poll; + ot->exec = geometry_color_attribute_set_render_exec; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_INTERNAL; + + /* properties */ + PropertyRNA *prop; + + prop = RNA_def_string(ot->srna, "name", "Color", MAX_NAME, "Name", "Name of color attribute"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); +} + +static int geometry_color_attribute_remove_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; + } + + next_color_attributes(id, layer); + + if (!BKE_id_attribute_remove(id, layer, op->reports)) { + return OPERATOR_CANCELLED; + } + + if (GS(id->name) == ID_ME) { + Mesh *me = static_cast<Mesh *>(ob->data); + BKE_mesh_update_customdata_pointers(me, true); + } + + 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_remove_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_remove(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Remove Color Attribute"; + ot->description = "Remove color attribute from geometry"; + ot->idname = "GEOMETRY_OT_color_attribute_remove"; + + /* api callbacks */ + ot->exec = geometry_color_attribute_remove_exec; + ot->poll = geometry_color_attributes_remove_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + static void geometry_attribute_convert_ui(bContext *UNUSED(C), wmOperator *op) { uiLayout *layout = op->layout; @@ -345,7 +550,7 @@ void GEOMETRY_OT_attribute_convert(wmOperatorType *ot) {int(ConvertAttributeMode::Generic), "GENERIC", 0, "Generic", ""}, {int(ConvertAttributeMode::UVMap), "UV_MAP", 0, "UV Map", ""}, {int(ConvertAttributeMode::VertexGroup), "VERTEX_GROUP", 0, "Vertex Group", ""}, - {int(ConvertAttributeMode::VertexColor), "VERTEX_COLOR", 0, "Vertex Color", ""}, + {int(ConvertAttributeMode::VertexColor), "VERTEX_COLOR", 0, "Color Attribute", ""}, {0, nullptr, 0, nullptr, nullptr}, }; |