[Bf-blender-cvs] [b4cb9b9b9fb] temp-sculpt-brush-channel: temp-sculpt-brush-channel: Fix RNA bugs and add UI

Joseph Eagar noreply at git.blender.org
Mon Aug 8 11:36:34 CEST 2022


Commit: b4cb9b9b9fbc52d5a216038c54352331f5905668
Author: Joseph Eagar
Date:   Mon Aug 8 02:35:34 2022 -0700
Branches: temp-sculpt-brush-channel
https://developer.blender.org/rBb4cb9b9b9fbc52d5a216038c54352331f5905668

temp-sculpt-brush-channel: Fix RNA bugs and add UI

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

M	release/scripts/startup/bl_ui/properties_paint_common.py
M	source/blender/blenkernel/BKE_brush_channel.h
M	source/blender/blenkernel/intern/brush.cc
M	source/blender/blenkernel/intern/brush_channel.cc
M	source/blender/editors/sculpt_paint/paint_intern.h
M	source/blender/editors/sculpt_paint/paint_ops.c
M	source/blender/editors/sculpt_paint/paint_utils.c
M	source/blender/makesrna/intern/rna_brush_channels.c
M	source/blender/makesrna/intern/rna_scene.c

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

diff --git a/release/scripts/startup/bl_ui/properties_paint_common.py b/release/scripts/startup/bl_ui/properties_paint_common.py
index 9b1cf11f6e7..8d188444f8d 100644
--- a/release/scripts/startup/bl_ui/properties_paint_common.py
+++ b/release/scripts/startup/bl_ui/properties_paint_common.py
@@ -1,6 +1,22 @@
 # SPDX-License-Identifier: GPL-2.0-or-later
 from bpy.types import Menu
 
+def template_curve(layout, base, propname, full_path, use_negative_slope=None):
+    layout.template_curve_mapping(base, propname, brush=True, use_negative_slope=use_negative_slope)
+
+    path = full_path
+
+    col = layout.column(align=True)
+    row = col.row(align=True)
+
+    shapes = ['SMOOTH', 'ROUND', 'ROOT', 'SHARP', 'LINE', 'MAX']
+    icons = ['SMOOTHCURVE', 'SPHERECURVE', 'ROOTCURVE', 'SHARPCURVE', 'LINCURVE', 'NOCURVE']
+
+    for i, shape in enumerate(shapes):
+        props = row.operator("brush.curve_preset_load", icon=icons[i], text="")
+        props.invert = not use_negative_slope
+        props.shape = shape
+        props.path = path
 
 class UnifiedPaintPanel:
     # subclass must set
@@ -9,15 +25,16 @@ class UnifiedPaintPanel:
 
     @staticmethod
     def get_brush_mode(context):
-        """ Get the correct mode for this context. For any context where this returns None,
-            no brush options should be displayed."""
+        """Get the correct mode for this context. For any context where this returns None,
+        no brush options should be displayed."""
         mode = context.mode
 
-        if mode == 'PARTICLE':
+        if mode == "PARTICLE":
             # Particle brush settings currently completely do their own thing.
             return None
 
         from bl_ui.space_toolsystem_common import ToolSelectPanelHelper
+
         tool = ToolSelectPanelHelper.tool_active_from_context(context)
 
         if not tool:
@@ -33,12 +50,12 @@ class UnifiedPaintPanel:
 
         if space_data:
             space_type = space_data.type
-            if space_type == 'IMAGE_EDITOR':
+            if space_type == "IMAGE_EDITOR":
                 if space_data.show_uvedit:
-                    return 'UV_SCULPT'
-                return 'PAINT_2D'
-            elif space_type in {'VIEW_3D', 'PROPERTIES'}:
-                if mode == 'PAINT_TEXTURE':
+                    return "UV_SCULPT"
+                return "PAINT_2D"
+            elif space_type in {"VIEW_3D", "PROPERTIES"}:
+                if mode == "PAINT_TEXTURE":
                     if tool_settings.image_paint:
                         return mode
                     else:
@@ -53,37 +70,292 @@ class UnifiedPaintPanel:
         mode = UnifiedPaintPanel.get_brush_mode(context)
 
         # 3D paint settings
-        if mode == 'SCULPT':
+        if mode == "SCULPT":
             return tool_settings.sculpt
-        elif mode == 'PAINT_VERTEX':
+        elif mode == "PAINT_VERTEX":
             return tool_settings.vertex_paint
-        elif mode == 'PAINT_WEIGHT':
+        elif mode == "PAINT_WEIGHT":
             return tool_settings.weight_paint
-        elif mode == 'PAINT_TEXTURE':
+        elif mode == "PAINT_TEXTURE":
             return tool_settings.image_paint
-        elif mode == 'PARTICLE':
+        elif mode == "PARTICLE":
             return tool_settings.particle_edit
         # 2D paint settings
-        elif mode == 'PAINT_2D':
+        elif mode == "PAINT_2D":
             return tool_settings.image_paint
-        elif mode == 'UV_SCULPT':
+        elif mode == "UV_SCULPT":
             return tool_settings.uv_sculpt
         # Grease Pencil settings
-        elif mode == 'PAINT_GPENCIL':
+        elif mode == "PAINT_GPENCIL":
             return tool_settings.gpencil_paint
-        elif mode == 'SCULPT_GPENCIL':
+        elif mode == "SCULPT_GPENCIL":
             return tool_settings.gpencil_sculpt_paint
-        elif mode == 'WEIGHT_GPENCIL':
+        elif mode == "WEIGHT_GPENCIL":
             return tool_settings.gpencil_weight_paint
-        elif mode == 'VERTEX_GPENCIL':
+        elif mode == "VERTEX_GPENCIL":
             return tool_settings.gpencil_vertex_paint
-        elif mode == 'SCULPT_CURVES':
+        elif mode == "SCULPT_CURVES":
             return tool_settings.curves_sculpt
         return None
+    
+    @staticmethod
+    def channel_unified(layout, context, brush, prop_name, icon='NONE', pressure=None, text=None, baselayout=None,
+                        slider=False, header=False, show_reorder=False, expand=None, toolsettings_only=False, ui_editing=None,
+                        show_mappings=True, brush_only=False, use_negative_slope=None):
+        """ Generalized way of adding brush options to the UI,
+            along with their pen pressure setting and global toggle
+
+            note that ui_editing is no longer a bool, it can also be "mappings_only"
+            to just show the input mappings controls.
+
+            for curve channels, if use_negative_slope is None then
+            `channel.curve_preset_negative_slope` will be used.
+        """
+
+        if baselayout is None:
+            baselayout = layout
+
+        if slider is None:
+            slider = False
+
+        if header:
+            ui_editing = False
+            show_mappings = False
+        elif ui_editing is None:
+            ui_editing = True
+
+        #XXX
+        if 1: #not context.tool_settings.unified_paint_settings.brush_editor_mode:
+            ui_editing = False
+            show_reorder = False
+
+        if context.mode != "SCULPT":
+            return UnifiedPaintPanel.prop_unified(layout, context, brush, prop_name, icon=icon, text=text, slider=slider, header=header, expand=expand)
+
+        ch = brush.channels[prop_name]
+
+        # dynamically switch to unprojected radius if necassary
+        if prop_name == "size":
+            size_mode = brush.use_locked_size == "SCENE"
+            if size_mode:
+                prop_name = "unprojected_radius"
+                ch = brush.channels[prop_name]
+
+        finalch = ch
+
+        if prop_name in {"direction", "use_locked_size", "automasking"}:
+            expand = True
+
+        if ch.type == "BITMASK":
+            layout = layout.column(align=True)
+
+        row = layout.row(align=True)
+        row.use_property_split = True
+        row.use_property_decorate = False
+
+        if pressure is None:
+            pressure = ch.type not in ["VEC3", "VEC4", "BITMASK", "ENUM", "BOOL"]
+
+        if text is None:
+            text = ch.name
+
+        path = ""
+        proppath = ""
+
+        pressurech = ch
+
+        if not brush_only and (ch.inherit or toolsettings_only):
+            sd = context.tool_settings.sculpt
+            # ensure channel exists in tool settings channel set
+            sd.channels.ensure(ch)
+
+            finalch = sd.channels[prop_name]
+
+            path = "tool_settings.unified_channels[\"%s\"]" % ch.idname
+            proppath = "tool_settings.unified_properties"
+        else:
+            path = "tool_settings.sculpt.brush.channels[\"%s\"]" % ch.idname
+            proppath = "tool_settings.sculpt.brush"
+
+        finalowner = context.path_resolve(proppath)
+        
+        if not (ch.inherit and ch.mappings["PRESSURE"].inherit_mode == "NEVER"):
+            pressurech = finalch
+
+            if pressurech == ch and ch.mappings["PRESSURE"].inherit_mode == "ALWAYS":
+                sd = context.tool_settings.sculpt
+                sd.channels.ensure(ch)
+                pressurech = sd.channels[ch.idname]
+
+        if show_reorder:
+            props = row.operator("brush.change_channel_order", text="", icon="TRIA_UP")
+            props.channel = ch.idname
+            props.filterkey = "show_in_workspace"
+            props.direction = -1
+
+            props = row.operator("brush.change_channel_order", text="", icon="TRIA_DOWN")
+            props.filterkey = "show_in_workspace"
+            props.channel = ch.idname
+            props.direction = 1
+
+        if ui_editing and not header:
+            row2 = row.row(align=True)
+            row2.prop(ch, "show_in_workspace", text="", icon="WORKSPACE")
+            row2.prop(ch, "show_in_context_menu", text="", icon="MENU_PANEL")
+            row2.prop(ch, "show_in_header", text="", icon="TOPBAR")
+
+        if ch.type == "CURVE":
+            row.prop(finalch.curve, "curve_preset", text=text)
+
+            if use_negative_slope is None:
+                use_negative_slope = finalch.curve.preset_slope_negative
+
+            if not header and finalch.curve.curve_preset == "CUSTOM":
+                path2 = path + ".curve.curve"
+                template_curve(layout, finalch.curve, "curve", path2, use_negative_slope=use_negative_slope)
+
+        elif ch.type == "BITMASK":
+            if header or not expand:
+                row.label(text=text)
+                row.prop_menu_enum(finalowner, prop_name, text=text)
+            else:
+                # why is it so hard to make bitflag checkboxes? - joeedh
+
+                row.label(text=text)
+                col = layout.column(align=True)
+                col.emboss = "NONE"
+                col.use_property_decorate = False
+                col.use_property_split = False
+                
+                for j, item in enumerate(finalch.enum_items):
+                    if item.identifier in finalch.value:
+                        itemicon = "CHECKBOX_HLT"
+                    else:
+                        itemicon = "CHECKBOX_DEHLT"
+                    col.prop_enum(finalowner, prop_name, item.identifier, icon=itemicon)
+
+        elif header and ch.idname == "direction":
+            row2 = row.row(align=True)
+            row2.use_property_split = False
+            row2.use_property_decorate = False
+
+            # replicate pre-existing functionality of direction showing up as
+            # +/- in the header
+            row2.prop_enum(finalowner, prop_name, "ADD", text="")
+            row2.prop_enum(finalowner, prop_name, "SUBTRACT", text="")
+        elif expand is not None:
+            row.prop(finalowner, prop_name, icon=icon, text=text, slider=slider, expand=expand)
+        else:
+            row.prop(finalo

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list