[Bf-blender-cvs] [6ce4d39e6bd] master: Geometry Nodes: initial attribute list for meshes

Jacques Lucke noreply at git.blender.org
Mon Jun 28 16:56:58 CEST 2021


Commit: 6ce4d39e6bd585257845e29a3de4eb278b941fd3
Author: Jacques Lucke
Date:   Mon Jun 28 16:52:49 2021 +0200
Branches: master
https://developer.blender.org/rB6ce4d39e6bd585257845e29a3de4eb278b941fd3

Geometry Nodes: initial attribute list for meshes

This adds a new Attributes panel in the mesh properties editor.
It shows a list of all the generic attributes on the mesh.
In the future, we want to show built-in and other attributes in the
list as well. Related technical design tasks: T88460, T89054.

There is also a new simple name collision check that warns the user
when there are multiple attributes with the same name. This can be
problematic when the attribute is supposed to be used in geometry
nodes or during rendering.

Differential Revision: https://developer.blender.org/D11276

===================================================================

M	release/scripts/startup/bl_ui/properties_data_mesh.py
M	source/blender/editors/geometry/geometry_attributes.c
M	source/blender/makesrna/intern/rna_attribute.c

===================================================================

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
@@ -108,14 +108,6 @@ void GEOMETRY_OT_attribute_add(wmOperatorType *ot)
   prop = RNA_def_string(ot->srna, "name", "Attribute", MAX_NAME, "Name", "Name of new attribute");
   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,
@@ -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);



More information about the Bf-blender-cvs mailing list