diff options
-rw-r--r-- | release/scripts/startup/bl_ui/properties_data_mesh.py | 86 | ||||
-rw-r--r-- | source/blender/editors/geometry/geometry_attributes.c | 21 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_attribute.c | 10 |
3 files changed, 108 insertions, 9 deletions
diff --git a/release/scripts/startup/bl_ui/properties_data_mesh.py b/release/scripts/startup/bl_ui/properties_data_mesh.py index c6a0f0b1d05..fb8aedd1f49 100644 --- a/release/scripts/startup/bl_ui/properties_data_mesh.py +++ b/release/scripts/startup/bl_ui/properties_data_mesh.py @@ -20,6 +20,7 @@ import bpy from bpy.types import Menu, Panel, UIList from rna_prop_ui import PropertyPanel +from collections import defaultdict class MESH_MT_vertex_group_context_menu(Menu): @@ -566,6 +567,89 @@ class DATA_PT_custom_props_mesh(MeshButtonsPanel, PropertyPanel, Panel): _property_type = bpy.types.Mesh +class MESH_UL_attributes(UIList): + display_domain_names = { + 'POINT': "Vertex", + 'EDGE': "Edge", + 'FACE': "Face", + 'CORNER': "Face Corner", + } + + def draw_item(self, _context, layout, _data, attribute, _icon, _active_data, _active_propname, _index): + data_type = attribute.bl_rna.properties['data_type'].enum_items[attribute.data_type] + + domain_name = self.display_domain_names.get(attribute.domain, "") + + split = layout.split(factor=0.50) + split.emboss = 'NONE' + split.prop(attribute, "name", text="") + sub = split.row() + sub.alignment = 'RIGHT' + sub.active = False + sub.label(text="%s ▶ %s" % (domain_name, data_type.name)) + + +class DATA_PT_mesh_attributes(MeshButtonsPanel, Panel): + bl_label = "Attributes" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} + + def draw(self, context): + mesh = context.mesh + + layout = self.layout + row = layout.row() + + col = row.column() + col.template_list( + "MESH_UL_attributes", + "attributes", + mesh, + "attributes", + mesh.attributes, + "active_index", + rows=3, + ) + + col = row.column(align=True) + col.operator("geometry.attribute_add", icon='ADD', text="") + col.operator("geometry.attribute_remove", icon='REMOVE', text="") + + self.draw_attribute_warnings(context, layout) + + def draw_attribute_warnings(self, context, layout): + attributes_by_name = defaultdict(list) + + ob = context.object + mesh = ob.data + + builtin_attribute = object() + + def add_builtin(name): + attributes_by_name[name].append(builtin_attribute) + + def add_attributes(layers): + for layer in layers: + attributes_by_name[layer.name].append(layer) + + add_builtin("position") + add_builtin("material_index") + add_builtin("shade_smooth") + add_builtin("normal") + add_builtin("crease") + + add_attributes(mesh.attributes) + add_attributes(mesh.uv_layers) + add_attributes(mesh.vertex_colors) + add_attributes(ob.vertex_groups) + + colliding_names = [name for name, layers in attributes_by_name.items() if len(layers) >= 2] + if len(colliding_names) == 0: + return + + layout.label(text="Name Collisions: {}".format(", ".join(colliding_names)), icon='INFO') + + classes = ( MESH_MT_vertex_group_context_menu, MESH_MT_shape_key_context_menu, @@ -574,6 +658,7 @@ classes = ( MESH_UL_shape_keys, MESH_UL_uvmaps, MESH_UL_vcols, + MESH_UL_attributes, DATA_PT_context_mesh, DATA_PT_vertex_groups, DATA_PT_shape_keys, @@ -581,6 +666,7 @@ classes = ( DATA_PT_vertex_colors, DATA_PT_sculpt_vertex_colors, DATA_PT_face_maps, + DATA_PT_mesh_attributes, DATA_PT_normals, DATA_PT_texture_space, DATA_PT_remesh, diff --git a/source/blender/editors/geometry/geometry_attributes.c b/source/blender/editors/geometry/geometry_attributes.c index b2ecee90a57..9b034d82a51 100644 --- a/source/blender/editors/geometry/geometry_attributes.c +++ b/source/blender/editors/geometry/geometry_attributes.c @@ -109,14 +109,6 @@ void GEOMETRY_OT_attribute_add(wmOperatorType *ot) RNA_def_property_flag(prop, PROP_SKIP_SAVE); prop = RNA_def_enum(ot->srna, - "data_type", - rna_enum_attribute_type_items, - CD_PROP_FLOAT, - "Data Type", - "Type of data stored in attribute"); - RNA_def_property_flag(prop, PROP_SKIP_SAVE); - - prop = RNA_def_enum(ot->srna, "domain", rna_enum_attribute_domain_items, ATTR_DOMAIN_POINT, @@ -124,6 +116,14 @@ void GEOMETRY_OT_attribute_add(wmOperatorType *ot) "Type of element that attribute is stored on"); RNA_def_enum_funcs(prop, geometry_attribute_domain_itemf); RNA_def_property_flag(prop, PROP_SKIP_SAVE); + + prop = RNA_def_enum(ot->srna, + "data_type", + rna_enum_attribute_type_items, + CD_PROP_FLOAT, + "Data Type", + "Type of data stored in attribute"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); } static int geometry_attribute_remove_exec(bContext *C, wmOperator *op) @@ -140,6 +140,11 @@ static int geometry_attribute_remove_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } + int *active_index = BKE_id_attributes_active_index_p(id); + if (*active_index > 0) { + *active_index -= 1; + } + DEG_id_tag_update(id, ID_RECALC_GEOMETRY); WM_main_add_notifier(NC_GEOM | ND_DATA, id); diff --git a/source/blender/makesrna/intern/rna_attribute.c b/source/blender/makesrna/intern/rna_attribute.c index a256002ffc1..b4ea70c33ab 100644 --- a/source/blender/makesrna/intern/rna_attribute.c +++ b/source/blender/makesrna/intern/rna_attribute.c @@ -162,6 +162,9 @@ const EnumPropertyItem *rna_enum_attribute_domain_itemf(ID *id, bool *r_free) const ID_Type id_type = GS(id->name); int totitem = 0, a; + static EnumPropertyItem mesh_vertex_domain_item = { + ATTR_DOMAIN_POINT, "POINT", 0, "Vertex", "Attribute per point/vertex"}; + for (a = 0; rna_enum_attribute_domain_items[a].identifier; a++) { domain_item = &rna_enum_attribute_domain_items[a]; @@ -175,7 +178,12 @@ const EnumPropertyItem *rna_enum_attribute_domain_itemf(ID *id, bool *r_free) continue; } - RNA_enum_item_add(&item, &totitem, domain_item); + if (domain_item->value == ATTR_DOMAIN_POINT && id_type == ID_ME) { + RNA_enum_item_add(&item, &totitem, &mesh_vertex_domain_item); + } + else { + RNA_enum_item_add(&item, &totitem, domain_item); + } } RNA_enum_item_end(&item, &totitem); |