[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