UI: add vertex paint tools

Generalize logic to show the paintbrush as a tool so
different paint modes can use it.
This commit is contained in:
Campbell Barton 2018-04-30 15:21:04 +02:00
parent b5f5e6ce29
commit d9f395ac39
3 changed files with 104 additions and 46 deletions

@ -31,6 +31,52 @@ from .space_toolsystem_common import (
ToolDef, ToolDef,
) )
def generate_from_brushes_ex(
context, *,
icon_prefix,
brush_test_attr,
brush_category_attr,
brush_category_layout,
):
# Categories
brush_categories = {}
for brush in context.blend_data.brushes:
if getattr(brush, brush_test_attr):
category = getattr(brush, brush_category_attr)
name = brush.name
brush_categories.setdefault(category, []).append(
ToolDef.from_dict(
dict(
text=name,
icon=icon_prefix + category.lower(),
data_block=name,
)
)
)
def tools_from_brush_group(groups):
assert(type(groups) is tuple)
if len(groups) == 1:
tool_defs = tuple(brush_categories.pop(groups[0], ()))
else:
tool_defs = tuple(item for g in groups for item in brush_categories.pop(g, ()))
if len(tool_defs) > 1:
return (tool_defs,)
else:
return tool_defs
# Each item below is a single toolbar entry:
# Grouped for multiple or none if no brushes are found.
tool_defs = tuple(
tool_def
for category in brush_category_layout
for tool_def in tools_from_brush_group(category)
)
# Ensure we use all types.
assert(len(brush_categories) == 0)
return tool_defs
class _defs_view3d_generic: class _defs_view3d_generic:
@ToolDef.from_fn @ToolDef.from_fn
def cursor(): def cursor():
@ -504,51 +550,48 @@ class _defs_sculpt:
@staticmethod @staticmethod
def generate_from_brushes(context): def generate_from_brushes(context):
# Categories return generate_from_brushes_ex(
brush_categories = {} context,
for brush in context.blend_data.brushes: icon_prefix="brush.sculpt.",
if brush.use_paint_sculpt: brush_test_attr="use_paint_sculpt",
sculpt_tool = brush.sculpt_tool brush_category_attr="sculpt_tool",
name = brush.name brush_category_layout=(
brush_categories.setdefault(sculpt_tool, []).append( ('DRAW',),
ToolDef.from_dict( ('GRAB', 'THUMB'),
dict( ('SNAKE_HOOK',),
text=name, ('BLOB', 'INFLATE'),
icon="brush.sculpt." + sculpt_tool.lower(), ('SMOOTH', 'SCRAPE' , 'FLATTEN'),
data_block=name, ('CREASE', 'PINCH'),
) ('CLAY', 'CLAY_STRIPS'),
) ('LAYER',),
) ('NUDGE', 'ROTATE'),
('FILL',),
def tools_from_brush_group(*groups): ('SIMPLIFY',),
if len(groups) == 1: ('MASK',),
tool_defs = tuple(brush_categories.pop(groups[0], ())) )
else: )
tool_defs = tuple(item for g in groups for item in brush_categories.pop(g, ()))
if len(tool_defs) > 1: class _defs_vertexpaint:
return (tool_defs,)
else: @staticmethod
return tool_defs def generate_from_brushes(context):
return generate_from_brushes_ex(
# Each item below is a single toolbar entry: context,
# Grouped for multiple or none if no brushes are found. icon_prefix="brush.vertexpaint.",
tool_defs = ( brush_test_attr="use_paint_vertex",
*tools_from_brush_group("DRAW"), brush_category_attr="vertex_tool",
*tools_from_brush_group("GRAB", "THUMB"), brush_category_layout=(
*tools_from_brush_group("SNAKE_HOOK"), ('MIX',),
*tools_from_brush_group("BLOB", "INFLATE"), ('BLUR', 'AVERAGE'),
*tools_from_brush_group("SMOOTH", "SCRAPE" , "FLATTEN"), ('SMEAR',),
*tools_from_brush_group("CREASE", "PINCH"), (
*tools_from_brush_group("CLAY", "CLAY_STRIPS"), 'ADD', 'SUB', 'MUL', 'LIGHTEN', 'DARKEN',
*tools_from_brush_group("LAYER"), 'COLORDODGE', 'DIFFERENCE', 'SCREEN', 'HARDLIGHT',
*tools_from_brush_group("NUDGE", "ROTATE"), 'OVERLAY', 'SOFTLIGHT', 'EXCLUSION', 'LUMINOCITY',
*tools_from_brush_group("FILL"), 'SATURATION', 'HUE',
*tools_from_brush_group("SIMPLIFY"), ),
*tools_from_brush_group("MASK"), )
) )
# Ensure we use all types.
assert(len(brush_categories) == 0)
return tool_defs
class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel): class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel):
@ -691,6 +734,9 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel):
'SCULPT': [ 'SCULPT': [
_defs_sculpt.generate_from_brushes, _defs_sculpt.generate_from_brushes,
], ],
'PAINT_VERTEX': [
_defs_vertexpaint.generate_from_brushes,
],
} }

@ -148,6 +148,7 @@ class TOPBAR_HT_lower_bar(Header):
layout.popover_group(space_type='VIEW_3D', region_type='TOOLS', context=".dummy", category="") layout.popover_group(space_type='VIEW_3D', region_type='TOOLS', context=".dummy", category="")
elif mode == 'PAINT_VERTEX': elif mode == 'PAINT_VERTEX':
layout.popover_group(space_type='VIEW_3D', region_type='TOOLS', context=".dummy", category="") layout.popover_group(space_type='VIEW_3D', region_type='TOOLS', context=".dummy", category="")
layout.popover_group(space_type='VIEW_3D', region_type='TOOLS', context=".vertexpaint", category="")
elif mode == 'PAINT_WEIGHT': elif mode == 'PAINT_WEIGHT':
layout.popover_group(space_type='VIEW_3D', region_type='TOOLS', context="", category="") layout.popover_group(space_type='VIEW_3D', region_type='TOOLS', context="", category="")
elif mode == 'PAINT_TEXTURE': elif mode == 'PAINT_TEXTURE':
@ -191,6 +192,17 @@ class _draw_left_context_mode:
UnifiedPaintPanel.prop_unified_strength(layout, context, brush, "strength", slider=True, text="Strength") UnifiedPaintPanel.prop_unified_strength(layout, context, brush, "strength", slider=True, text="Strength")
layout.prop(brush, "direction", text="", expand=True) layout.prop(brush, "direction", text="", expand=True)
def PAINT_VERTEX(context, layout):
brush = context.tool_settings.vertex_paint.brush
if brush is None:
return
from .properties_paint_common import UnifiedPaintPanel
layout.prop(brush, "color", text="")
UnifiedPaintPanel.prop_unified_size(layout, context, brush, "size", slider=True, text="Radius")
UnifiedPaintPanel.prop_unified_strength(layout, context, brush, "strength", slider=True, text="Strength")
class TOPBAR_PT_redo(Panel): class TOPBAR_PT_redo(Panel):
bl_label = "Redo" bl_label = "Redo"
bl_space_type = 'TOPBAR' bl_space_type = 'TOPBAR'

@ -1094,7 +1094,7 @@ class VIEW3D_PT_tools_weightpaint_options(Panel, View3DPaintPanel):
class VIEW3D_PT_tools_vertexpaint(Panel, View3DPaintPanel): class VIEW3D_PT_tools_vertexpaint(Panel, View3DPaintPanel):
bl_category = "Options" bl_category = "Options"
bl_context = "vertexpaint" bl_context = ".vertexpaint" # dot on purpose (access from topbar)
bl_label = "Options" bl_label = "Options"
def draw(self, context): def draw(self, context):
@ -1110,7 +1110,7 @@ class VIEW3D_PT_tools_vertexpaint(Panel, View3DPaintPanel):
class VIEW3D_PT_tools_vertexpaint_symmetry(Panel, View3DPaintPanel): class VIEW3D_PT_tools_vertexpaint_symmetry(Panel, View3DPaintPanel):
bl_category = "Tools" bl_category = "Tools"
bl_context = "vertexpaint" bl_context = ".vertexpaint" # dot on purpose (access from topbar)
bl_options = {'DEFAULT_CLOSED'} bl_options = {'DEFAULT_CLOSED'}
bl_label = "Symmetry" bl_label = "Symmetry"