[Bf-blender-cvs] [8b7cd1ed2a1] master: Painting: Canvas switcher for painting brushes/tools.

Jeroen Bakker noreply at git.blender.org
Fri Apr 8 16:42:51 CEST 2022


Commit: 8b7cd1ed2a17e40661101eea4adae99e8e3d02e9
Author: Jeroen Bakker
Date:   Fri Apr 8 16:37:35 2022 +0200
Branches: master
https://developer.blender.org/rB8b7cd1ed2a17e40661101eea4adae99e8e3d02e9

Painting: Canvas switcher for painting brushes/tools.

This patch adds color attributes to TexPaintSlot. This allows an easier selection
when painting color attributes.

Previously when selecting a paint tool the user had to start a stroke, before the
UI reflected the correct TexPaintSlot. Now when switching the slot the active
tool is checked and immediate the UI is drawn correctly.

In the future the canvas selector will also be used to select an image or image texture node
to paint on. Basic implementation has already been done inside this patch.

A limitation of this patch is that is isn't possible anymore to rename images directly from
the selection panel. This is currently allowed in master. But as CustomDataLayers
aren't ID fields and not owned by the material supporting this wouldn't be easy.

{F12953989}

In the future we should update the create slot operator to also include color attributes.
Sources could also be extended to use other areas of the object that use image textures
(particles, geom nodes, etc... ).

Reviewed By: brecht

Maniphest Tasks: T96709

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

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

M	release/scripts/startup/bl_ui/properties_data_mesh.py
M	release/scripts/startup/bl_ui/properties_paint_common.py
M	release/scripts/startup/bl_ui/space_view3d_toolbar.py
M	source/blender/blenkernel/BKE_attribute.h
M	source/blender/blenkernel/BKE_material.h
M	source/blender/blenkernel/BKE_node.h
M	source/blender/blenkernel/BKE_paint.h
M	source/blender/blenkernel/intern/attribute.c
M	source/blender/blenkernel/intern/material.c
M	source/blender/blenkernel/intern/node.cc
M	source/blender/blenkernel/intern/paint.c
M	source/blender/draw/engines/workbench/workbench_engine.c
M	source/blender/editors/include/ED_paint.h
M	source/blender/editors/sculpt_paint/CMakeLists.txt
A	source/blender/editors/sculpt_paint/paint_canvas.cc
M	source/blender/editors/sculpt_paint/paint_image_proj.c
M	source/blender/editors/sculpt_paint/paint_utils.c
M	source/blender/editors/sculpt_paint/sculpt.c
M	source/blender/editors/sculpt_paint/sculpt_filter_color.c
M	source/blender/editors/space_view3d/space_view3d.c
M	source/blender/makesdna/DNA_material_types.h
M	source/blender/makesdna/DNA_node_types.h
M	source/blender/makesdna/DNA_scene_types.h
M	source/blender/makesrna/intern/rna_material.c
M	source/blender/makesrna/intern/rna_scene.c
M	source/blender/makesrna/intern/rna_sculpt_paint.c
M	source/blender/makesrna/intern/rna_workspace.c
M	source/blender/nodes/shader/node_shader_util.cc

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

diff --git a/release/scripts/startup/bl_ui/properties_data_mesh.py b/release/scripts/startup/bl_ui/properties_data_mesh.py
index 97519e55b48..1bfd82cc790 100644
--- a/release/scripts/startup/bl_ui/properties_data_mesh.py
+++ b/release/scripts/startup/bl_ui/properties_data_mesh.py
@@ -565,7 +565,7 @@ class DATA_PT_mesh_attributes(MeshButtonsPanel, Panel):
         layout.label(text="Name collisions: " + ", ".join(set(colliding_names)), icon='ERROR')
 
 
-class MESH_UL_color_attributes(UIList):
+class ColorAttributesListBase():
     display_domain_names = {
         'POINT': "Vertex",
         'EDGE': "Edge",
@@ -588,6 +588,8 @@ class MESH_UL_color_attributes(UIList):
 
         return ret, idxs
 
+
+class MESH_UL_color_attributes(UIList, ColorAttributesListBase):
     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]
 
@@ -613,6 +615,12 @@ class MESH_UL_color_attributes(UIList):
         sub.label(text="%s ▶ %s" % (domain_name, data_type.name))
 
 
+class MESH_UL_color_attributes_selector(UIList, ColorAttributesListBase):
+    def draw_item(self, _context, layout, data, attribute, _icon, _active_data, _active_propname, _index):
+        layout.emboss = 'NONE'
+        layout.prop(attribute, "name", text="", icon='COLOR')
+
+
 class DATA_PT_vertex_colors(DATA_PT_mesh_attributes, Panel):
     bl_label = "Color Attributes"
     bl_options = {'DEFAULT_CLOSED'}
@@ -663,6 +671,7 @@ classes = (
     DATA_PT_customdata,
     DATA_PT_custom_props_mesh,
     MESH_UL_color_attributes,
+    MESH_UL_color_attributes_selector,
 )
 
 if __name__ == "__main__":  # only for live edit.
diff --git a/release/scripts/startup/bl_ui/properties_paint_common.py b/release/scripts/startup/bl_ui/properties_paint_common.py
index 9e40a8d364a..064a99034d3 100644
--- a/release/scripts/startup/bl_ui/properties_paint_common.py
+++ b/release/scripts/startup/bl_ui/properties_paint_common.py
@@ -238,7 +238,7 @@ class ClonePanel(BrushPanel):
                 col.label(text="Source Clone Slot")
                 col.template_list(
                     "TEXTURE_UL_texpaintslots", "",
-                    mat, "texture_paint_images",
+                    mat, "texture_paint_slots",
                     mat, "paint_clone_slot",
                     rows=2,
                 )
diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
index 750e9b527f0..332933be68a 100644
--- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
@@ -280,7 +280,7 @@ class TEXTURE_UL_texpaintslots(UIList):
         # mat = data
 
         if self.layout_type in {'DEFAULT', 'COMPACT'}:
-            layout.prop(item, "name", text="", emboss=False, icon_value=icon)
+            layout.prop(item, "name", text="", emboss=False, icon_value=item.icon_value)
         elif self.layout_type == 'GRID':
             layout.alignment = 'CENTER'
             layout.label(text="")
@@ -459,15 +459,11 @@ class VIEW3D_MT_tools_projectpaint_uvlayer(Menu):
             props.value = i
 
 
-class VIEW3D_PT_slots_projectpaint(View3DPanel, Panel):
+class SelectPaintSlotHelper:
     bl_category = "Tool"
-    bl_context = ".imagepaint"  # dot on purpose (access from topbar)
-    bl_label = "Texture Slots"
 
-    @classmethod
-    def poll(cls, context):
-        brush = context.tool_settings.image_paint.brush
-        return (brush is not None and context.active_object is not None)
+    canvas_source_attr_name = "canvas_source"
+    canvas_image_attr_name = "canvas_image"
 
     def draw(self, context):
         layout = self.layout
@@ -475,51 +471,66 @@ class VIEW3D_PT_slots_projectpaint(View3DPanel, Panel):
         layout.use_property_decorate = False
 
         settings = context.tool_settings.image_paint
+        mode_settings = self.get_mode_settings(context)
 
         ob = context.active_object
 
-        layout.prop(settings, "mode", text="Mode")
+        layout.prop(mode_settings, self.canvas_source_attr_name, text="Mode")
         layout.separator()
 
-        if settings.mode == 'MATERIAL':
-            if len(ob.material_slots) > 1:
-                layout.template_list("MATERIAL_UL_matslots", "layers",
-                                     ob, "material_slots",
-                                     ob, "active_material_index", rows=2)
-            mat = ob.active_material
-            if mat and mat.texture_paint_images:
-                row = layout.row()
-                row.template_list("TEXTURE_UL_texpaintslots", "",
-                                  mat, "texture_paint_images",
-                                  mat, "paint_active_slot", rows=2)
-
-                if mat.texture_paint_slots:
-                    slot = mat.texture_paint_slots[mat.paint_active_slot]
+        have_image = False
+
+        match getattr(mode_settings, self.canvas_source_attr_name):
+            case 'MATERIAL':
+                if len(ob.material_slots) > 1:
+                    layout.template_list("MATERIAL_UL_matslots", "layers",
+                                        ob, "material_slots",
+                                        ob, "active_material_index", rows=2)
+                mat = ob.active_material
+                if mat and mat.texture_paint_images:
+                    row = layout.row()
+                    row.template_list("TEXTURE_UL_texpaintslots", "",
+                                    mat, "texture_paint_slots",
+                                    mat, "paint_active_slot", rows=2)
+
+                    if mat.texture_paint_slots:
+                        slot = mat.texture_paint_slots[mat.paint_active_slot]
+                    else:
+                        slot = None
+
+                    have_image = slot is not None
                 else:
-                    slot = None
+                    row = layout.row()
 
-                have_image = slot is not None
-            else:
-                row = layout.row()
-
-                box = row.box()
-                box.label(text="No Textures")
-                have_image = False
+                    box = row.box()
+                    box.label(text="No Textures")
 
-            sub = row.column(align=True)
-            sub.operator_menu_enum("paint.add_texture_paint_slot", "type", icon='ADD', text="")
+                sub = row.column(align=True)
+                sub.operator_menu_enum("paint.add_texture_paint_slot", "type", icon='ADD', text="")
 
-        elif settings.mode == 'IMAGE':
-            mesh = ob.data
-            uv_text = mesh.uv_layers.active.name if mesh.uv_layers.active else ""
-            layout.template_ID(settings, "canvas", new="image.new", open="image.open")
-            if settings.missing_uvs:
-                layout.operator("paint.add_simple_uvs", icon='ADD', text="Add UVs")
-            else:
-                layout.menu("VIEW3D_MT_tools_projectpaint_uvlayer", text=uv_text, translate=False)
-            have_image = settings.canvas is not None
-
-            layout.prop(settings, "interpolation", text="")
+            case 'IMAGE':
+                mesh = ob.data
+                uv_text = mesh.uv_layers.active.name if mesh.uv_layers.active else ""
+                layout.template_ID(mode_settings, self.canvas_image_attr_name, new="image.new", open="image.open")
+                if settings.missing_uvs:
+                    layout.operator("paint.add_simple_uvs", icon='ADD', text="Add UVs")
+                else:
+                    layout.menu("VIEW3D_MT_tools_projectpaint_uvlayer", text=uv_text, translate=False)
+                have_image = getattr(settings, self.canvas_image_attr_name) is not None
+                
+                self.draw_image_interpolation(layout=layout, mode_settings=mode_settings)
+
+            case 'COLOR_ATTRIBUTE':
+                mesh = ob.data
+                layout.template_list(
+                    "MESH_UL_color_attributes_selector",
+                    "color_attributes",
+                    mesh,
+                    "color_attributes",
+                    mesh.color_attributes,
+                    "active_color_index",
+                    rows=3,
+                )
 
         if settings.missing_uvs:
             layout.separator()
@@ -531,6 +542,50 @@ class VIEW3D_PT_slots_projectpaint(View3DPanel, Panel):
             layout.operator("image.save_all_modified", text="Save All Images", icon='FILE_TICK')
 
 
+class VIEW3D_PT_slots_projectpaint(SelectPaintSlotHelper, View3DPanel, Panel):
+    bl_category = "Tool"
+    bl_context = ".imagepaint"  # dot on purpose (access from topbar)
+    bl_label = "Texture Slots"
+
+    canvas_source_attr_name = "mode"
+    canvas_image_attr_name = "canvas"
+
+    @classmethod
+    def poll(cls, context):
+        brush = context.tool_settings.image_paint.brush
+        return (brush is not None and context.active_object is not None)
+
+    def get_mode_settings(self, context):
+        return context.tool_settings.image_paint
+
+    def draw_image_interpolation(self, layout, mode_settings):
+        layout.prop(mode_settings, "interpolation", text="")
+
+
+
+class VIEW3D_PT_slots_paint_canvas(SelectPaintSlotHelper, View3DPanel, Panel):
+    bl_category = "Tool"
+    bl_context = ".sculpt_mode"  # dot on purpose (access from topbar)
+    bl_label = "Canvas"
+
+    @classmethod
+    def poll(cls, context):
+        if not context.preferences.experimental.use_sculpt_texture_paint:
+            return False
+
+        from bl_ui.space_toolsystem_common import ToolSelectPanelHelper
+        tool = ToolSelectPanelHelper.tool_active_from_context(context)
+        if tool is None:
+            return False
+        return tool.use_paint_canvas
+
+    def get_mode_settings(self, context):
+        return context.tool_settings.paint_mode
+
+    def draw_image_interpolation(self, **kwargs):
+        pass
+
+
 class VIEW3D_PT_mask(View3DPanel, Panel):
     bl_category = "Tool"
     bl_context = ".imagepaint"  # dot on purpose (access from topbar)
@@ -2232,6 +2287,7 @@ classes = (

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list