- Tweaked icons for Box Select, Circle Select & Lasso Select. - Tweaked icons for Rip Region & Rip Edge. - Added icons for Bone Envelope, Bone Size, Pose Breakdown, Pose Push & Pose Relax. - Added icons for curve Extrude, Extrude Cursor. Also removed grease pencil mirror tool which wasn't an active tool, and is now consistent with regular Edit Mode.
2085 lines
64 KiB
Python
2085 lines
64 KiB
Python
# ##### BEGIN GPL LICENSE BLOCK #####
|
|
#
|
|
# This program is free software; you can redistribute it and/or
|
|
# modify it under the terms of the GNU General Public License
|
|
# as published by the Free Software Foundation; either version 2
|
|
# of the License, or (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program; if not, write to the Free Software Foundation,
|
|
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
#
|
|
# ##### END GPL LICENSE BLOCK #####
|
|
|
|
# <pep8 compliant>
|
|
|
|
# For now group all tools together
|
|
# we may want to move these into per space-type files.
|
|
#
|
|
# For now keep this in a single file since it's an area that may change,
|
|
# so avoid making changes all over the place.
|
|
|
|
import bpy
|
|
from bpy.types import Panel
|
|
|
|
from .space_toolsystem_common import (
|
|
ToolSelectPanelHelper,
|
|
ToolDef,
|
|
)
|
|
from .properties_material_gpencil import (
|
|
GPENCIL_UL_matslots,
|
|
)
|
|
from .properties_grease_pencil_common import (
|
|
AnnotationDataPanel,
|
|
)
|
|
|
|
def generate_from_brushes_ex(
|
|
context, *,
|
|
icon_prefix,
|
|
brush_test_attr,
|
|
brush_category_attr,
|
|
brush_category_layout,
|
|
):
|
|
# Categories
|
|
brush_categories = {}
|
|
if context.mode != 'GPENCIL_PAINT':
|
|
for brush in context.blend_data.brushes:
|
|
if getattr(brush, brush_test_attr) and brush.gpencil_settings is None:
|
|
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,
|
|
)
|
|
)
|
|
)
|
|
else:
|
|
def draw_settings(context, layout, tool):
|
|
_defs_gpencil_paint.draw_settings_common(context, layout, tool)
|
|
|
|
for brush_type in brush_category_layout:
|
|
for brush in context.blend_data.brushes:
|
|
if brush.gpencil_settings and getattr(brush, brush_test_attr) and brush.gpencil_settings.gp_icon == brush_type[0]:
|
|
category = brush_type[0]
|
|
name = brush.name
|
|
text = name
|
|
|
|
# Define icon.
|
|
icon_name = {
|
|
'PENCIL': 'draw_pencil',
|
|
'PEN': 'draw_pen',
|
|
'INK': 'draw_ink',
|
|
'INKNOISE': 'draw_noise',
|
|
'BLOCK': 'draw_block',
|
|
'MARKER': 'draw_marker',
|
|
'FILL': 'draw_fill',
|
|
'SOFT': 'draw.eraser_soft',
|
|
'HARD': 'draw.eraser_hard',
|
|
'STROKE': 'draw.eraser_stroke',
|
|
}[category]
|
|
brush_categories.setdefault(category, []).append(
|
|
ToolDef.from_dict(
|
|
dict(
|
|
text=text,
|
|
icon=icon_prefix + icon_name,
|
|
data_block=name,
|
|
widget=None,
|
|
operator="gpencil.draw",
|
|
draw_settings=draw_settings,
|
|
)
|
|
)
|
|
)
|
|
|
|
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.
|
|
if brush_categories:
|
|
print(brush_categories)
|
|
assert(len(brush_categories) == 0)
|
|
return tool_defs
|
|
|
|
|
|
def generate_from_enum_ex(
|
|
context, *,
|
|
icon_prefix,
|
|
data,
|
|
attr,
|
|
):
|
|
tool_defs = []
|
|
for enum in data.rna_type.properties[attr].enum_items_static:
|
|
name = enum.name
|
|
identifier = enum.identifier
|
|
tool_defs.append(
|
|
ToolDef.from_dict(
|
|
dict(
|
|
text=name,
|
|
icon=icon_prefix + identifier.lower(),
|
|
data_block=identifier,
|
|
)
|
|
)
|
|
)
|
|
return tuple(tool_defs)
|
|
|
|
|
|
class _defs_view3d_generic:
|
|
@ToolDef.from_fn
|
|
def cursor():
|
|
def draw_settings(context, layout, tool):
|
|
props = tool.operator_properties("view3d.cursor3d")
|
|
layout.prop(props, "use_depth")
|
|
layout.prop(props, "orientation")
|
|
return dict(
|
|
text="Cursor",
|
|
description=(
|
|
"Set the cursor location, drag to transform"
|
|
),
|
|
icon="ops.generic.cursor",
|
|
keymap=(
|
|
("view3d.cursor3d", dict(), dict(type='ACTIONMOUSE', value='PRESS')),
|
|
("transform.translate",
|
|
dict(release_confirm=True, cursor_transform=True),
|
|
dict(type='EVT_TWEAK_A', value='ANY'),
|
|
),
|
|
),
|
|
draw_settings=draw_settings,
|
|
)
|
|
|
|
@ToolDef.from_fn
|
|
def cursor_click():
|
|
return dict(
|
|
text="None",
|
|
icon="ops.generic.cursor",
|
|
keymap=(
|
|
# This is a dummy keymap entry, until particle system is properly working with toolsystem.
|
|
("view3d.cursor3d", dict(), dict(type='ACTIONMOUSE', value='CLICK', ctrl=True, alt=True, shift=True)),
|
|
),
|
|
)
|
|
|
|
@ToolDef.from_fn
|
|
def ruler():
|
|
return dict(
|
|
text="Measure",
|
|
description=(
|
|
"Measure distance and angles.\n"
|
|
"\u2022 Drag anywhere for new measurement.\n"
|
|
"\u2022 Drag ruler segment to measure an angle.\n"
|
|
"\u2022 Drag ruler outside the view to remove.\n"
|
|
"\u2022 Ctrl to snap.\n"
|
|
"\u2022 Shift to measure surface thickness"
|
|
),
|
|
icon="ops.view3d.ruler",
|
|
widget="VIEW3D_GGT_ruler",
|
|
keymap=(
|
|
("view3d.ruler_add", dict(), dict(type='EVT_TWEAK_A', value='ANY')),
|
|
),
|
|
)
|
|
|
|
|
|
def _defs_annotate_factory():
|
|
|
|
class _defs_annotate:
|
|
@staticmethod
|
|
def draw_settings_common(context, layout, tool):
|
|
if type(context.gpencil_data_owner) is bpy.types.Object:
|
|
gpd = context.scene.grease_pencil
|
|
else:
|
|
gpd = context.gpencil_data
|
|
|
|
if gpd is not None:
|
|
if gpd.layers.active_note is not None:
|
|
text = gpd.layers.active_note
|
|
maxw = 25
|
|
if len(text) > maxw:
|
|
text = text[:maxw - 5] + '..' + text[-3:]
|
|
else:
|
|
text = ""
|
|
|
|
layout.label(text="Annotation:")
|
|
gpl = context.active_gpencil_layer
|
|
if gpl is not None:
|
|
sub = layout.row(align=True)
|
|
sub.ui_units_x = 8
|
|
|
|
sub.prop(gpl, "color", text="")
|
|
sub.popover(
|
|
panel="TOPBAR_PT_annotation_layers",
|
|
text=text,
|
|
)
|
|
|
|
tool_settings = context.tool_settings
|
|
space_type = tool.space_type
|
|
if space_type == 'VIEW_3D':
|
|
layout.separator()
|
|
|
|
row = layout.row(align=True)
|
|
row.prop(tool_settings, "annotation_stroke_placement_view3d", text="Placement")
|
|
if tool_settings.gpencil_stroke_placement_view3d == 'CURSOR':
|
|
row.prop(tool_settings.gpencil_sculpt, "lockaxis")
|
|
elif tool_settings.gpencil_stroke_placement_view3d in {'SURFACE', 'STROKE'}:
|
|
row.prop(tool_settings, "use_gpencil_stroke_endpoints")
|
|
|
|
@ToolDef.from_fn
|
|
def scribble():
|
|
def draw_settings(context, layout, tool):
|
|
_defs_annotate.draw_settings_common(context, layout, tool)
|
|
return dict(
|
|
text="Annotate",
|
|
icon="ops.gpencil.draw",
|
|
cursor='PAINT_BRUSH',
|
|
keymap=(
|
|
("gpencil.annotate",
|
|
dict(mode='DRAW', wait_for_input=False),
|
|
dict(type='ACTIONMOUSE', value='PRESS')),
|
|
),
|
|
draw_settings=draw_settings,
|
|
)
|
|
|
|
@ToolDef.from_fn
|
|
def line():
|
|
def draw_settings(context, layout, tool):
|
|
_defs_annotate.draw_settings_common(context, layout, tool)
|
|
return dict(
|
|
text="Annotate Line",
|
|
icon="ops.gpencil.draw.line",
|
|
cursor='CROSSHAIR',
|
|
keymap=(
|
|
("gpencil.annotate",
|
|
dict(mode='DRAW_STRAIGHT', wait_for_input=False),
|
|
dict(type='EVT_TWEAK_A', value='ANY')),
|
|
),
|
|
draw_settings=draw_settings,
|
|
)
|
|
|
|
@ToolDef.from_fn
|
|
def poly():
|
|
def draw_settings(context, layout, tool):
|
|
_defs_annotate.draw_settings_common(context, layout, tool)
|
|
return dict(
|
|
text="Annotate Polygon",
|
|
icon="ops.gpencil.draw.poly",
|
|
cursor='CROSSHAIR',
|
|
keymap=(
|
|
("gpencil.annotate",
|
|
dict(mode='DRAW_POLY', wait_for_input=False),
|
|
dict(type='ACTIONMOUSE', value='PRESS')),
|
|
),
|
|
draw_settings=draw_settings,
|
|
)
|
|
|
|
@ToolDef.from_fn
|
|
def eraser():
|
|
def draw_settings(context, layout, tool):
|
|
# TODO: Move this setting to tool_settings
|
|
user_prefs = context.user_preferences
|
|
layout.prop(user_prefs.edit, "grease_pencil_eraser_radius", text="Radius")
|
|
return dict(
|
|
text="Annotate Eraser",
|
|
icon="ops.gpencil.draw.eraser",
|
|
cursor='CROSSHAIR', # XXX: Always show brush circle when enabled
|
|
keymap=(
|
|
("gpencil.annotate",
|
|
dict(mode='ERASER', wait_for_input=False),
|
|
dict(type='ACTIONMOUSE', value='PRESS')),
|
|
),
|
|
draw_settings=draw_settings,
|
|
)
|
|
return _defs_annotate
|
|
|
|
|
|
# Needed so annotation gets a keymap per space type.
|
|
_defs_annotate_image = _defs_annotate_factory()
|
|
_defs_annotate_view3d = _defs_annotate_factory()
|
|
|
|
|
|
class _defs_transform:
|
|
|
|
@ToolDef.from_fn
|
|
def translate():
|
|
return dict(
|
|
text="Move",
|
|
# cursor='SCROLL_XY',
|
|
icon="ops.transform.translate",
|
|
widget="TRANSFORM_GGT_gizmo",
|
|
operator="transform.translate",
|
|
keymap=(
|
|
("transform.translate", dict(release_confirm=True), dict(type='EVT_TWEAK_A', value='ANY')),
|
|
),
|
|
)
|
|
|
|
@ToolDef.from_fn
|
|
def rotate():
|
|
return dict(
|
|
text="Rotate",
|
|
# cursor='SCROLL_XY',
|
|
icon="ops.transform.rotate",
|
|
widget="TRANSFORM_GGT_gizmo",
|
|
operator="transform.rotate",
|
|
keymap=(
|
|
("transform.rotate", dict(release_confirm=True), dict(type='EVT_TWEAK_A', value='ANY')),
|
|
),
|
|
)
|
|
|
|
@ToolDef.from_fn
|
|
def scale():
|
|
return dict(
|
|
text="Scale",
|
|
# cursor='SCROLL_XY',
|
|
icon="ops.transform.resize",
|
|
widget="TRANSFORM_GGT_gizmo",
|
|
operator="transform.resize",
|
|
keymap=(
|
|
("transform.resize", dict(release_confirm=True), dict(type='EVT_TWEAK_A', value='ANY')),
|
|
),
|
|
)
|
|
|
|
@ToolDef.from_fn
|
|
def scale_cage():
|
|
return dict(
|
|
text="Scale Cage",
|
|
icon="ops.transform.resize.cage",
|
|
widget="VIEW3D_GGT_xform_cage",
|
|
operator="transform.resize",
|
|
)
|
|
|
|
@ToolDef.from_fn
|
|
def transform():
|
|
def draw_settings(context, layout, tool):
|
|
layout.label(text="Gizmos:")
|
|
tool_settings = context.tool_settings
|
|
layout.prop(tool_settings, "use_gizmo_mode")
|
|
|
|
props = tool.gizmo_group_properties("TRANSFORM_GGT_gizmo")
|
|
layout.prop(props, "drag_action")
|
|
|
|
return dict(
|
|
text="Transform",
|
|
description=(
|
|
"Supports any combination of grab, rotate & scale at once"
|
|
),
|
|
icon="ops.transform.transform",
|
|
widget="TRANSFORM_GGT_gizmo",
|
|
keymap=(
|
|
("transform.from_gizmo", dict(), dict(type='EVT_TWEAK_A', value='ANY')),
|
|
),
|
|
draw_settings=draw_settings,
|
|
)
|
|
|
|
|
|
class _defs_view3d_select:
|
|
|
|
@ToolDef.from_fn
|
|
def border():
|
|
def draw_settings(context, layout, tool):
|
|
props = tool.operator_properties("view3d.select_box")
|
|
layout.prop(props, "mode", expand=True)
|
|
return dict(
|
|
text="Select Box",
|
|
icon="ops.generic.select_box",
|
|
widget=None,
|
|
keymap=(
|
|
("view3d.select_box",
|
|
dict(mode='ADD'),
|
|
dict(type='EVT_TWEAK_A', value='ANY')),
|
|
("view3d.select_box",
|
|
dict(mode='SUB'),
|
|
dict(type='EVT_TWEAK_A', value='ANY', ctrl=True)),
|
|
),
|
|
draw_settings=draw_settings,
|
|
)
|
|
|
|
@ToolDef.from_fn
|
|
def circle():
|
|
def draw_settings(context, layout, tool):
|
|
props = tool.operator_properties("view3d.select_circle")
|
|
layout.prop(props, "radius")
|
|
return dict(
|
|
text="Select Circle",
|
|
icon="ops.generic.select_circle",
|
|
widget=None,
|
|
keymap=(
|
|
("view3d.select_circle",
|
|
dict(deselect=False),
|
|
dict(type='ACTIONMOUSE', value='PRESS')),
|
|
("view3d.select_circle",
|
|
dict(deselect=True),
|
|
dict(type='ACTIONMOUSE', value='PRESS', ctrl=True)),
|
|
),
|
|
draw_settings=draw_settings,
|
|
)
|
|
|
|
@ToolDef.from_fn
|
|
def lasso():
|
|
def draw_settings(context, layout, tool):
|
|
props = tool.operator_properties("view3d.select_lasso")
|
|
layout.prop(props, "mode", expand=True)
|
|
return dict(
|
|
text="Select Lasso",
|
|
icon="ops.generic.select_lasso",
|
|
widget=None,
|
|
keymap=(
|
|
("view3d.select_lasso",
|
|
dict(mode='ADD'),
|
|
dict(type='EVT_TWEAK_A', value='ANY')),
|
|
("view3d.select_lasso",
|
|
dict(mode='SUB'),
|
|
dict(type='EVT_TWEAK_A', value='ANY', ctrl=True)),
|
|
),
|
|
draw_settings=draw_settings,
|
|
)
|
|
# -----------------------------------------------------------------------------
|
|
# Object Modes (named based on context.mode)
|
|
|
|
|
|
class _defs_edit_armature:
|
|
|
|
@ToolDef.from_fn
|
|
def roll():
|
|
return dict(
|
|
text="Roll",
|
|
icon="ops.armature.bone.roll",
|
|
widget=None,
|
|
keymap=(
|
|
("transform.transform",
|
|
dict(release_confirm=True, mode='BONE_ROLL'),
|
|
dict(type='EVT_TWEAK_A', value='ANY'),),
|
|
),
|
|
)
|
|
|
|
@ToolDef.from_fn
|
|
def bone_envelope():
|
|
return dict(
|
|
text="Bone Envelope",
|
|
icon="ops.transform.bone_envelope",
|
|
widget=None,
|
|
keymap=(
|
|
("transform.transform",
|
|
dict(release_confirm=True, mode='BONE_ENVELOPE'),
|
|
dict(type='ACTIONMOUSE', value='PRESS')),
|
|
),
|
|
)
|
|
|
|
@ToolDef.from_fn
|
|
def bone_size():
|
|
return dict(
|
|
text="Bone Size",
|
|
icon="ops.transform.bone_size",
|
|
widget=None,
|
|
keymap=(
|
|
("transform.transform",
|
|
dict(release_confirm=True, mode='BONE_SIZE'),
|
|
dict(type='ACTIONMOUSE', value='PRESS')),
|
|
),
|
|
)
|
|
|
|
@ToolDef.from_fn
|
|
def extrude():
|
|
return dict(
|
|
text="Extrude",
|
|
icon="ops.armature.extrude_move",
|
|
widget=None,
|
|
keymap=(
|
|
("armature.extrude_move",
|
|
dict(TRANSFORM_OT_translate=dict(release_confirm=True)),
|
|
dict(type='EVT_TWEAK_A', value='ANY')),
|
|
),
|
|
)
|
|
|
|
@ToolDef.from_fn
|
|
def extrude_cursor():
|
|
return dict(
|
|
text="Extrude to Cursor",
|
|
icon="ops.armature.extrude_cursor",
|
|
widget=None,
|
|
keymap=(
|
|
("armature.click_extrude", dict(), dict(type='ACTIONMOUSE', value='PRESS')),
|
|
),
|
|
)
|
|
|
|
|
|
class _defs_edit_mesh:
|
|
|
|
@ToolDef.from_fn
|
|
def cube_add():
|
|
return dict(
|
|
text="Add Cube",
|
|
icon="ops.mesh.primitive_cube_add_gizmo",
|
|
widget=None,
|
|
keymap=(
|
|
("view3d.cursor3d", dict(), dict(type='ACTIONMOUSE', value='CLICK')),
|
|
("mesh.primitive_cube_add_gizmo", dict(), dict(type='EVT_TWEAK_A', value='ANY')),
|
|
),
|
|
)
|
|
|
|
@ToolDef.from_fn
|
|
def rip_region():
|
|
def draw_settings(context, layout, tool):
|
|
props = tool.operator_properties("mesh.rip_move")
|
|
props_macro = props.MESH_OT_rip
|
|
layout.prop(props_macro, "use_fill")
|
|
|
|
return dict(
|
|
text="Rip Region",
|
|
icon="ops.mesh.rip",
|
|
widget=None,
|
|
keymap=(
|
|
("mesh.rip_move",
|
|
dict(TRANSFORM_OT_translate=dict(release_confirm=True)),
|
|
dict(type='ACTIONMOUSE', value='PRESS')),
|
|
),
|
|
draw_settings=draw_settings,
|
|
)
|
|
|
|
@ToolDef.from_fn
|
|
def rip_edge():
|
|
return dict(
|
|
text="Rip Edge",
|
|
icon="ops.mesh.rip_edge",
|
|
widget=None,
|
|
keymap=(
|
|
("mesh.rip_edge_move",
|
|
dict(TRANSFORM_OT_translate=dict(release_confirm=True)),
|
|
dict(type='ACTIONMOUSE', value='PRESS')),
|
|
),
|
|
)
|
|
|
|
@ToolDef.from_fn
|
|
def poly_build():
|
|
return dict(
|
|
text="Poly Build",
|
|
icon="ops.mesh.polybuild_hover",
|
|
widget="VIEW3D_GGT_mesh_preselect_elem",
|
|
keymap=(
|
|
("mesh.polybuild_face_at_cursor_move",
|
|
dict(TRANSFORM_OT_translate=dict(release_confirm=True)),
|
|
dict(type='ACTIONMOUSE', value='PRESS')),
|
|
("mesh.polybuild_split_at_cursor_move",
|
|
dict(TRANSFORM_OT_translate=dict(release_confirm=True)),
|
|
dict(type='ACTIONMOUSE', value='PRESS', ctrl=True)),
|
|
("mesh.polybuild_dissolve_at_cursor", dict(), dict(type='ACTIONMOUSE', value='CLICK', alt=True)),
|
|
),
|
|
)
|
|
|
|
@ToolDef.from_fn
|
|
def edge_slide():
|
|
def draw_settings(context, layout, tool):
|
|
props = tool.operator_properties("transform.edge_slide")
|
|
layout.prop(props, "correct_uv")
|
|
|
|
return dict(
|
|
text="Edge Slide",
|
|
icon="ops.transform.edge_slide",
|
|
widget=None,
|
|
keymap=(
|
|
("transform.edge_slide", dict(release_confirm=True),
|
|
dict(type='ACTIONMOUSE', value='PRESS')
|
|
),
|
|
),
|
|
draw_settings=draw_settings,
|
|
)
|
|
|
|
@ToolDef.from_fn
|
|
def vert_slide():
|
|
def draw_settings(context, layout, tool):
|
|
props = tool.operator_properties("transform.vert_slide")
|
|
layout.prop(props, "correct_uv")
|
|
|
|
return dict(
|
|
text="Vertex Slide",
|
|
icon="ops.transform.vert_slide",
|
|
widget=None,
|
|
keymap=(
|
|
("transform.vert_slide", dict(release_confirm=True),
|
|
dict(type='ACTIONMOUSE', value='PRESS')),
|
|
),
|
|
draw_settings=draw_settings,
|
|
)
|
|
|
|
@ToolDef.from_fn
|
|
def spin():
|
|
def draw_settings(context, layout, tool):
|
|
props = tool.operator_properties("mesh.spin")
|
|
layout.prop(props, "steps")
|
|
props = tool.gizmo_group_properties("MESH_GGT_spin")
|
|
layout.prop(props, "axis")
|
|
|
|
return dict(
|
|
text="Spin",
|
|
icon="ops.mesh.spin",
|
|
widget="MESH_GGT_spin",
|
|
keymap=(
|
|
("mesh.spin", dict(),
|
|
dict(type='EVT_TWEAK_A', value='ANY')),
|
|
),
|
|
draw_settings=draw_settings,
|
|
)
|
|
|
|
@ToolDef.from_fn
|
|
def spin_duplicate():
|
|
def draw_settings(context, layout, tool):
|
|
props = tool.operator_properties("mesh.spin")
|
|
layout.prop(props, "steps")
|
|
props = tool.gizmo_group_properties("MESH_GGT_spin")
|
|
layout.prop(props, "axis")
|
|
|
|
return dict(
|
|
text="Spin (Duplicate)",
|
|
icon="ops.mesh.spin.duplicate",
|
|
widget="MESH_GGT_spin",
|
|
keymap=(
|
|
("mesh.spin", dict(dupli=True),
|
|
dict(type='EVT_TWEAK_A', value='ANY')),
|
|
),
|
|
draw_settings=draw_settings,
|
|
)
|
|
|
|
@ToolDef.from_fn
|
|
def inset():
|
|
def draw_settings(context, layout, tool):
|
|
props = tool.operator_properties("mesh.inset")
|
|
layout.prop(props, "use_outset")
|
|
layout.prop(props, "use_individual")
|
|
layout.prop(props, "use_even_offset")
|
|
layout.prop(props, "use_relative_offset")
|
|
|
|
return dict(
|
|
text="Inset Faces",
|
|
icon="ops.mesh.inset",
|
|
widget=None,
|
|
keymap=(
|
|
("mesh.inset", dict(release_confirm=True),
|
|
dict(type='ACTIONMOUSE', value='PRESS')),
|
|
),
|
|
draw_settings=draw_settings,
|
|
)
|
|
|
|
@ToolDef.from_fn
|
|
def bevel():
|
|
def draw_settings(context, layout, tool):
|
|
props = tool.operator_properties("mesh.bevel")
|
|
layout.prop(props, "offset_type")
|
|
layout.prop(props, "segments")
|
|
layout.prop(props, "profile", slider=True)
|
|
layout.prop(props, "vertex_only")
|
|
|
|
return dict(
|
|
text="Bevel",
|
|
icon="ops.mesh.bevel",
|
|
widget=None,
|
|
keymap=(
|
|
("mesh.bevel", dict(release_confirm=True),
|
|
dict(type='ACTIONMOUSE', value='PRESS')),
|
|
),
|
|
draw_settings=draw_settings,
|
|
)
|
|
|
|
@ToolDef.from_fn
|
|
def extrude():
|
|
def draw_settings(context, layout, tool):
|
|
props = tool.gizmo_group_properties("MESH_GGT_extrude")
|
|
layout.prop(props, "axis_type", expand=True)
|
|
return dict(
|
|
text="Extrude Region",
|
|
# The operator description isn't useful in this case, give our own.
|
|
description=(
|
|
"Extrude freely or along an axis"
|
|
),
|
|
icon="ops.mesh.extrude_region_move",
|
|
widget="MESH_GGT_extrude",
|
|
# Important to use same operator as 'E' key.
|
|
operator="view3d.edit_mesh_extrude_move_normal",
|
|
keymap=(
|
|
("mesh.extrude_context_move",
|
|
dict(TRANSFORM_OT_translate=dict(release_confirm=True)),
|
|
dict(type='EVT_TWEAK_A', value='ANY')),
|
|
),
|
|
draw_settings=draw_settings,
|
|
)
|
|
|
|
@ToolDef.from_fn
|
|
def extrude_normals():
|
|
def draw_settings(context, layout, tool):
|
|
props = tool.operator_properties("mesh.extrude_region_shrink_fatten")
|
|
props_macro = props.TRANSFORM_OT_shrink_fatten
|
|
layout.prop(props_macro, "use_even_offset")
|
|
return dict(
|
|
text="Extrude Along Normals",
|
|
icon="ops.mesh.extrude_region_shrink_fatten",
|
|
widget=None,
|
|
operator="mesh.extrude_region_shrink_fatten",
|
|
keymap=(
|
|
("mesh.extrude_region_shrink_fatten",
|
|
dict(TRANSFORM_OT_shrink_fatten=dict(release_confirm=True)),
|
|
dict(type='EVT_TWEAK_A', value='ANY')),
|
|
),
|
|
draw_settings=draw_settings,
|
|
)
|
|
|
|
@ToolDef.from_fn
|
|
def extrude_individual():
|
|
return dict(
|
|
text="Extrude Individual",
|
|
icon="ops.mesh.extrude_faces_move",
|
|
widget=None,
|
|
keymap=(
|
|
("mesh.extrude_faces_move", dict(TRANSFORM_OT_shrink_fatten=dict(release_confirm=True)),
|
|
dict(type='EVT_TWEAK_A', value='ANY')),
|
|
),
|
|
)
|
|
|
|
@ToolDef.from_fn
|
|
def extrude_cursor():
|
|
def draw_settings(context, layout, tool):
|
|
props = tool.operator_properties("mesh.dupli_extrude_cursor")
|
|
layout.prop(props, "rotate_source")
|
|
|
|
return dict(
|
|
text="Extrude to Cursor",
|
|
icon="ops.mesh.dupli_extrude_cursor",
|
|
widget=None,
|
|
keymap=(
|
|
("mesh.dupli_extrude_cursor", dict(), dict(type='ACTIONMOUSE', value='PRESS')),
|
|
),
|
|
draw_settings=draw_settings,
|
|
)
|
|
|
|
@ToolDef.from_fn
|
|
def loopcut_slide():
|
|
|
|
def draw_settings(context, layout, tool):
|
|
props = tool.operator_properties("mesh.loopcut_slide")
|
|
props_macro = props.MESH_OT_loopcut
|
|
layout.prop(props_macro, "number_cuts")
|
|
props_macro = props.TRANSFORM_OT_edge_slide
|
|
layout.prop(props_macro, "correct_uv")
|
|
|
|
return dict(
|
|
text="Loop Cut",
|
|
icon="ops.mesh.loopcut_slide",
|
|
widget="VIEW3D_GGT_mesh_preselect_edgering",
|
|
keymap=(
|
|
("mesh.loopcut_slide",
|
|
dict(TRANSFORM_OT_edge_slide=dict(release_confirm=True)),
|
|
dict(type='ACTIONMOUSE', value='PRESS')),
|
|
),
|
|
draw_settings=draw_settings,
|
|
)
|
|
|
|
@ToolDef.from_fn
|
|
def offset_edge_loops_slide():
|
|
return dict(
|
|
text="Offset Edge Loop Cut",
|
|
icon="ops.mesh.offset_edge_loops_slide",
|
|
widget=None,
|
|
keymap=(
|
|
("mesh.offset_edge_loops_slide", dict(), dict(type='ACTIONMOUSE', value='PRESS')),
|
|
),
|
|
)
|
|
|
|
@ToolDef.from_fn
|
|
def vertex_smooth():
|
|
def draw_settings(context, layout, tool):
|
|
props = tool.operator_properties("mesh.vertices_smooth")
|
|
layout.prop(props, "repeat")
|
|
return dict(
|
|
text="Smooth",
|
|
icon="ops.mesh.vertices_smooth",
|
|
widget="WM_GGT_value_operator_redo",
|
|
keymap=(
|
|
# Use 0.0, so dragging increases from nothing.
|
|
("mesh.vertices_smooth", dict(factor=0.0),
|
|
dict(type='ACTIONMOUSE', value='PRESS')),
|
|
),
|
|
draw_settings=draw_settings,
|
|
)
|
|
|
|
@ToolDef.from_fn
|
|
def vertex_randomize():
|
|
def draw_settings(context, layout, tool):
|
|
props = tool.operator_properties("transform.vertex_random")
|
|
layout.prop(props, "uniform")
|
|
layout.prop(props, "normal")
|
|
layout.prop(props, "seed")
|
|
return dict(
|
|
text="Randomize",
|
|
icon="ops.transform.vertex_random",
|
|
widget="WM_GGT_value_operator_redo",
|
|
keymap=(
|
|
# Use 0.0, so dragging increases from nothing.
|
|
("transform.vertex_random", dict(offset=0.0),
|
|
dict(type='ACTIONMOUSE', value='PRESS')),
|
|
),
|
|
draw_settings=draw_settings,
|
|
)
|
|
|
|
@ToolDef.from_fn
|
|
def shear():
|
|
def draw_settings(context, layout, tool):
|
|
props = tool.operator_properties("transform.shear")
|
|
layout.label(text="View Axis:")
|
|
layout.prop(props, "shear_axis", expand=True)
|
|
return dict(
|
|
text="Shear",
|
|
icon="ops.transform.shear",
|
|
widget="VIEW3D_GGT_xform_shear",
|
|
keymap=(
|
|
("transform.shear", dict(release_confirm=True),
|
|
dict(type='EVT_TWEAK_A', value='ANY')),
|
|
),
|
|
draw_settings=draw_settings,
|
|
)
|
|
|
|
@ToolDef.from_fn
|
|
def tosphere():
|
|
return dict(
|
|
text="To Sphere",
|
|
icon="ops.transform.tosphere",
|
|
widget=None,
|
|
keymap=(
|
|
("transform.tosphere", dict(release_confirm=True),
|
|
dict(type='ACTIONMOUSE', value='PRESS')),
|
|
),
|
|
)
|
|
|
|
@ToolDef.from_fn
|
|
def shrink_fatten():
|
|
def draw_settings(context, layout, tool):
|
|
props = tool.operator_properties("transform.shrink_fatten")
|
|
layout.prop(props, "use_even_offset")
|
|
|
|
return dict(
|
|
text="Shrink/Fatten",
|
|
icon="ops.transform.shrink_fatten",
|
|
widget=None,
|
|
keymap=(
|
|
("transform.shrink_fatten", dict(release_confirm=True),
|
|
dict(type='ACTIONMOUSE', value='PRESS')),
|
|
),
|
|
draw_settings=draw_settings,
|
|
)
|
|
|
|
@ToolDef.from_fn
|
|
def push_pull():
|
|
return dict(
|
|
text="Push/Pull",
|
|
icon="ops.transform.push_pull",
|
|
widget=None,
|
|
keymap=(
|
|
("transform.push_pull", dict(release_confirm=True),
|
|
dict(type='ACTIONMOUSE', value='PRESS')),
|
|
),
|
|
)
|
|
|
|
@ToolDef.from_fn
|
|
def knife():
|
|
def draw_settings(context, layout, tool):
|
|
props = tool.operator_properties("mesh.knife_tool")
|
|
layout.prop(props, "use_occlude_geometry")
|
|
layout.prop(props, "only_selected")
|
|
|
|
return dict(
|
|
text="Knife",
|
|
icon="ops.mesh.knife_tool",
|
|
widget=None,
|
|
keymap=(
|
|
("mesh.knife_tool",
|
|
dict(wait_for_input=False),
|
|
dict(type='ACTIONMOUSE', value='PRESS')),
|
|
),
|
|
draw_settings=draw_settings,
|
|
)
|
|
|
|
@ToolDef.from_fn
|
|
def bisect():
|
|
def draw_settings(context, layout, tool):
|
|
props = tool.operator_properties("mesh.bisect")
|
|
layout.prop(props, "use_fill")
|
|
layout.prop(props, "clear_inner")
|
|
layout.prop(props, "clear_outer")
|
|
layout.prop(props, "threshold")
|
|
return dict(
|
|
text="Bisect",
|
|
icon="ops.mesh.bisect",
|
|
widget=None,
|
|
keymap=(
|
|
("mesh.bisect",
|
|
dict(),
|
|
dict(type='EVT_TWEAK_A', value='ANY')),
|
|
),
|
|
draw_settings=draw_settings,
|
|
)
|
|
|
|
|
|
class _defs_edit_curve:
|
|
|
|
@ToolDef.from_fn
|
|
def draw():
|
|
def draw_settings(context, layout, tool):
|
|
# Tool settings initialize operator options.
|
|
tool_settings = context.tool_settings
|
|
cps = tool_settings.curve_paint_settings
|
|
|
|
col = layout.row()
|
|
|
|
col.prop(cps, "curve_type")
|
|
|
|
if cps.curve_type == 'BEZIER':
|
|
col.prop(cps, "error_threshold")
|
|
col.prop(cps, "fit_method")
|
|
col.prop(cps, "use_corners_detect")
|
|
|
|
col = layout.row()
|
|
col.active = cps.use_corners_detect
|
|
col.prop(cps, "corner_angle")
|
|
|
|
return dict(
|
|
text="Draw",
|
|
cursor='PAINT_BRUSH',
|
|
icon="ops.curve.draw",
|
|
widget=None,
|
|
keymap=(
|
|
("curve.draw", dict(wait_for_input=False), dict(type='ACTIONMOUSE', value='PRESS')),
|
|
),
|
|
draw_settings=draw_settings,
|
|
)
|
|
|
|
@ToolDef.from_fn
|
|
def extrude():
|
|
return dict(
|
|
text="Extrude",
|
|
icon="ops.curve.extrude_move",
|
|
widget=None,
|
|
keymap=(
|
|
("curve.extrude_move",
|
|
dict(TRANSFORM_OT_translate=dict(release_confirm=True)),
|
|
dict(type='EVT_TWEAK_A', value='ANY')),
|
|
),
|
|
)
|
|
|
|
@ToolDef.from_fn
|
|
def extrude_cursor():
|
|
return dict(
|
|
text="Extrude Cursor",
|
|
icon="ops.curve.extrude_cursor",
|
|
widget=None,
|
|
keymap=(
|
|
("curve.vertex_add", dict(), dict(type='ACTIONMOUSE', value='PRESS')),
|
|
),
|
|
)
|
|
|
|
|
|
class _defs_pose:
|
|
|
|
@ToolDef.from_fn
|
|
def breakdown():
|
|
return dict(
|
|
text="Breakdowner",
|
|
icon="ops.pose.breakdowner",
|
|
widget=None,
|
|
keymap=(
|
|
("pose.breakdown", dict(), dict(type='ACTIONMOUSE', value='PRESS')),
|
|
),
|
|
)
|
|
|
|
@ToolDef.from_fn
|
|
def push():
|
|
return dict(
|
|
text="Push",
|
|
icon="ops.pose.push",
|
|
widget=None,
|
|
keymap=(
|
|
("pose.push", dict(), dict(type='ACTIONMOUSE', value='PRESS')),
|
|
),
|
|
)
|
|
|
|
@ToolDef.from_fn
|
|
def relax():
|
|
return dict(
|
|
text="Relax",
|
|
icon="ops.pose.relax",
|
|
widget=None,
|
|
keymap=(
|
|
("pose.relax", dict(), dict(type='ACTIONMOUSE', value='PRESS')),
|
|
),
|
|
)
|
|
|
|
|
|
class _defs_particle:
|
|
|
|
@staticmethod
|
|
def generate_from_brushes(context):
|
|
return generate_from_enum_ex(
|
|
context,
|
|
icon_prefix="brush.particle.",
|
|
data=context.tool_settings.particle_edit,
|
|
attr="tool",
|
|
)
|
|
|
|
|
|
class _defs_sculpt:
|
|
|
|
@staticmethod
|
|
def generate_from_brushes(context):
|
|
return generate_from_brushes_ex(
|
|
context,
|
|
icon_prefix="brush.sculpt.",
|
|
brush_test_attr="use_paint_sculpt",
|
|
brush_category_attr="sculpt_tool",
|
|
brush_category_layout=(
|
|
('DRAW',),
|
|
('GRAB', 'THUMB'),
|
|
('SNAKE_HOOK',),
|
|
('BLOB', 'INFLATE'),
|
|
('SMOOTH', 'SCRAPE', 'FLATTEN'),
|
|
('CREASE', 'PINCH'),
|
|
('CLAY', 'CLAY_STRIPS'),
|
|
('LAYER',),
|
|
('NUDGE', 'ROTATE'),
|
|
('FILL',),
|
|
('SIMPLIFY',),
|
|
('MASK',),
|
|
)
|
|
)
|
|
|
|
@ToolDef.from_fn
|
|
def hide_border():
|
|
return dict(
|
|
text="Box Hide",
|
|
icon="ops.sculpt.border_hide",
|
|
widget=None,
|
|
keymap=(
|
|
("paint.hide_show", dict(action='HIDE'), dict(type='EVT_TWEAK_A', value='ANY')),
|
|
("paint.hide_show", dict(action='SHOW'), dict(type='EVT_TWEAK_A', value='ANY', ctrl=True)),
|
|
("paint.hide_show", dict(action='SHOW', area='ALL'), dict(type='SELECTMOUSE', value='PRESS')),
|
|
),
|
|
)
|
|
|
|
@ToolDef.from_fn
|
|
def mask_border():
|
|
return dict(
|
|
text="Box Mask",
|
|
icon="ops.sculpt.border_mask",
|
|
widget=None,
|
|
keymap=(
|
|
("view3d.select_box", dict(mode='ADD'), dict(type='EVT_TWEAK_A', value='ANY')),
|
|
("view3d.select_box", dict(mode='SUB'), dict(type='EVT_TWEAK_A', value='ANY', ctrl=True)),
|
|
),
|
|
)
|
|
|
|
|
|
class _defs_vertex_paint:
|
|
|
|
@staticmethod
|
|
def poll_select_mask(context):
|
|
ob = context.active_object
|
|
return ob.type == 'MESH' and ob.data.use_paint_mask
|
|
|
|
@staticmethod
|
|
def generate_from_brushes(context):
|
|
return generate_from_brushes_ex(
|
|
context,
|
|
icon_prefix="brush.paint_vertex.",
|
|
brush_test_attr="use_paint_vertex",
|
|
brush_category_attr="vertex_tool",
|
|
brush_category_layout=(
|
|
('MIX',),
|
|
('BLUR', 'AVERAGE'),
|
|
('SMEAR',),
|
|
(
|
|
'ADD', 'SUB', 'MUL', 'LIGHTEN', 'DARKEN',
|
|
'COLORDODGE', 'DIFFERENCE', 'SCREEN', 'HARDLIGHT',
|
|
'OVERLAY', 'SOFTLIGHT', 'EXCLUSION', 'LUMINOCITY',
|
|
'SATURATION', 'HUE', 'ERASE_ALPHA', 'ADD_ALPHA',
|
|
),
|
|
)
|
|
)
|
|
|
|
|
|
class _defs_texture_paint:
|
|
|
|
@staticmethod
|
|
def generate_from_brushes(context):
|
|
return generate_from_brushes_ex(
|
|
context,
|
|
icon_prefix="brush.paint_texture.",
|
|
brush_test_attr="use_paint_image",
|
|
brush_category_attr="image_tool",
|
|
brush_category_layout=(
|
|
('DRAW',),
|
|
('SOFTEN',),
|
|
('SMEAR',),
|
|
('CLONE',),
|
|
('FILL',),
|
|
('MASK',),
|
|
)
|
|
)
|
|
|
|
|
|
class _defs_weight_paint:
|
|
|
|
@staticmethod
|
|
def poll_select_mask(context):
|
|
ob = context.active_object
|
|
return (ob.type == 'MESH' and
|
|
(ob.data.use_paint_mask or
|
|
ob.data.use_paint_mask_vertex))
|
|
|
|
@staticmethod
|
|
def generate_from_brushes(context):
|
|
return generate_from_brushes_ex(
|
|
context,
|
|
icon_prefix="brush.paint_weight.",
|
|
brush_test_attr="use_paint_weight",
|
|
brush_category_attr="vertex_tool",
|
|
brush_category_layout=(
|
|
('MIX',),
|
|
('BLUR', 'AVERAGE'),
|
|
('SMEAR',),
|
|
(
|
|
'ADD', 'SUB', 'MUL', 'LIGHTEN', 'DARKEN',
|
|
'COLORDODGE', 'DIFFERENCE', 'SCREEN', 'HARDLIGHT',
|
|
'OVERLAY', 'SOFTLIGHT', 'EXCLUSION', 'LUMINOCITY',
|
|
'SATURATION', 'HUE',
|
|
),
|
|
)
|
|
)
|
|
|
|
@ToolDef.from_fn
|
|
def sample_weight():
|
|
return dict(
|
|
text="Sample Weight",
|
|
icon="ops.paint.weight_sample",
|
|
widget=None,
|
|
keymap=(
|
|
("paint.weight_sample", dict(), dict(type='ACTIONMOUSE', value='PRESS')),
|
|
),
|
|
)
|
|
|
|
@ToolDef.from_fn
|
|
def sample_weight_group():
|
|
return dict(
|
|
text="Sample Vertex Group",
|
|
icon="ops.paint.weight_sample_group",
|
|
widget=None,
|
|
keymap=(
|
|
("paint.weight_sample_group", dict(), dict(type='ACTIONMOUSE', value='PRESS')),
|
|
),
|
|
)
|
|
|
|
@ToolDef.from_fn
|
|
def gradient():
|
|
def draw_settings(context, layout, tool):
|
|
brush = context.tool_settings.weight_paint.brush
|
|
if brush is not None:
|
|
from .properties_paint_common import UnifiedPaintPanel
|
|
UnifiedPaintPanel.prop_unified_weight(layout, context, brush, "weight", slider=True, text="Weight")
|
|
props = tool.operator_properties("paint.weight_gradient")
|
|
layout.prop(props, "type")
|
|
|
|
return dict(
|
|
text="Gradient",
|
|
icon="ops.paint.weight_gradient",
|
|
widget=None,
|
|
keymap=(
|
|
("paint.weight_gradient", dict(), dict(type='EVT_TWEAK_A', value='ANY')),
|
|
),
|
|
draw_settings=draw_settings,
|
|
)
|
|
|
|
|
|
class _defs_image_generic:
|
|
|
|
@staticmethod
|
|
def poll_uvedit(context):
|
|
ob = context.edit_object
|
|
if ob is not None:
|
|
data = ob.data
|
|
if data is not None:
|
|
return bool(getattr(data, "uv_layers", False))
|
|
return False
|
|
|
|
@ToolDef.from_fn
|
|
def cursor():
|
|
return dict(
|
|
text="Cursor",
|
|
description=(
|
|
"Set the cursor location, drag to transform"
|
|
),
|
|
icon="ops.generic.cursor",
|
|
keymap=(
|
|
("uv.cursor_set", dict(), dict(type='ACTIONMOUSE', value='PRESS')),
|
|
("transform.translate",
|
|
dict(release_confirm=True, cursor_transform=True),
|
|
dict(type='EVT_TWEAK_A', value='ANY'),
|
|
),
|
|
),
|
|
)
|
|
|
|
|
|
class _defs_image_uv_transform:
|
|
|
|
@ToolDef.from_fn
|
|
def transform():
|
|
return dict(
|
|
text="Transform",
|
|
description=(
|
|
"Supports any combination of grab, rotate & scale at once"
|
|
),
|
|
icon="ops.transform.transform",
|
|
widget="IMAGE_GGT_gizmo2d",
|
|
# No keymap default action, only for gizmo!
|
|
)
|
|
|
|
|
|
class _defs_image_uv_select:
|
|
|
|
@ToolDef.from_fn
|
|
def border():
|
|
def draw_settings(context, layout, tool):
|
|
props = tool.operator_properties("uv.select_box")
|
|
layout.prop(props, "deselect")
|
|
return dict(
|
|
text="Select Box",
|
|
icon="ops.generic.select_box",
|
|
widget=None,
|
|
keymap=(
|
|
("uv.select_box",
|
|
dict(),
|
|
dict(type='EVT_TWEAK_A', value='ANY')),
|
|
("uv.select_box",
|
|
dict(deselect=True),
|
|
dict(type='EVT_TWEAK_A', value='ANY', ctrl=True)),
|
|
),
|
|
draw_settings=draw_settings,
|
|
)
|
|
|
|
@ToolDef.from_fn
|
|
def circle():
|
|
def draw_settings(context, layout, tool):
|
|
props = tool.operator_properties("uv.select_circle")
|
|
layout.prop(props, "radius")
|
|
return dict(
|
|
text="Select Circle",
|
|
icon="ops.generic.select_circle",
|
|
widget=None,
|
|
keymap=(
|
|
("uv.select_circle",
|
|
dict(deselect=False),
|
|
dict(type='ACTIONMOUSE', value='PRESS')),
|
|
("uv.select_circle",
|
|
dict(deselect=True),
|
|
dict(type='ACTIONMOUSE', value='PRESS', ctrl=True)),
|
|
),
|
|
draw_settings=draw_settings,
|
|
)
|
|
|
|
@ToolDef.from_fn
|
|
def lasso():
|
|
return dict(
|
|
text="Select Lasso",
|
|
icon="ops.generic.select_lasso",
|
|
widget=None,
|
|
keymap=(
|
|
("uv.select_lasso",
|
|
dict(deselect=False),
|
|
dict(type='EVT_TWEAK_A', value='ANY')),
|
|
# ("uv.select_lasso",
|
|
# dict(deselect=True),
|
|
# dict(type='EVT_TWEAK_A', value='ANY', ctrl=True)),
|
|
),
|
|
)
|
|
|
|
|
|
class _defs_image_uv_sculpt:
|
|
|
|
@staticmethod
|
|
def generate_from_brushes(context):
|
|
return generate_from_enum_ex(
|
|
context,
|
|
icon_prefix="brush.uv_sculpt.",
|
|
data=context.tool_settings,
|
|
attr="uv_sculpt_tool",
|
|
)
|
|
|
|
|
|
class _defs_gpencil_paint:
|
|
@staticmethod
|
|
def draw_color_selector(context, layout):
|
|
brush = context.active_gpencil_brush
|
|
gp_settings = brush.gpencil_settings
|
|
ma = gp_settings.material
|
|
row = layout.row(align=True)
|
|
|
|
icon_id = 0
|
|
if ma:
|
|
icon_id = ma.id_data.preview.icon_id
|
|
txt_ma = ma.name
|
|
maxw = 25
|
|
if len(txt_ma) > maxw:
|
|
txt_ma = txt_ma[:maxw - 5] + '..' + txt_ma[-3:]
|
|
else:
|
|
txt_ma = ""
|
|
|
|
row.label(text="Material:")
|
|
sub = row.row()
|
|
sub.ui_units_x = 8
|
|
sub.popover(
|
|
panel="TOPBAR_PT_gpencil_materials",
|
|
text=txt_ma,
|
|
icon_value=icon_id,
|
|
)
|
|
|
|
row.prop(gp_settings, "pin_material", text="")
|
|
|
|
@staticmethod
|
|
def draw_settings_common(context, layout, tool):
|
|
ob = context.active_object
|
|
if ob and ob.mode == 'GPENCIL_PAINT':
|
|
brush = context.active_gpencil_brush
|
|
gp_settings = brush.gpencil_settings
|
|
|
|
if gp_settings.gpencil_brush_type == 'ERASE':
|
|
row = layout.row(align=True)
|
|
row.prop(brush, "size", text="Radius")
|
|
row.prop(gp_settings, "use_pressure", text="", icon='STYLUS_PRESSURE')
|
|
if gp_settings.eraser_mode == 'SOFT':
|
|
row = layout.row(align=True)
|
|
row.prop(gp_settings, "pen_strength", slider=True)
|
|
row.prop(gp_settings, "use_strength_pressure", text="", icon='STYLUS_PRESSURE')
|
|
elif gp_settings.gpencil_brush_type == 'FILL':
|
|
row = layout.row()
|
|
row.prop(gp_settings, "gpencil_fill_leak", text="Leak Size")
|
|
row.prop(brush, "size", text="Thickness")
|
|
row.prop(gp_settings, "gpencil_fill_simplyfy_level", text="Simplify")
|
|
|
|
_defs_gpencil_paint.draw_color_selector(context, layout)
|
|
|
|
row = layout.row(align=True)
|
|
row.prop(gp_settings, "gpencil_fill_draw_mode", text="")
|
|
row.prop(gp_settings, "gpencil_fill_show_boundary", text="", icon='GRID')
|
|
|
|
else: # bgpsettings.gpencil_brush_type == 'DRAW':
|
|
row = layout.row(align=True)
|
|
row.prop(brush, "size", text="Radius")
|
|
row.prop(gp_settings, "use_pressure", text="", icon='STYLUS_PRESSURE')
|
|
row = layout.row(align=True)
|
|
row.prop(gp_settings, "pen_strength", slider=True)
|
|
row.prop(gp_settings, "use_strength_pressure", text="", icon='STYLUS_PRESSURE')
|
|
|
|
_defs_gpencil_paint.draw_color_selector(context, layout)
|
|
|
|
@staticmethod
|
|
def generate_from_brushes(context):
|
|
return generate_from_brushes_ex(
|
|
context,
|
|
icon_prefix="brush.gpencil.",
|
|
brush_test_attr="use_paint_grease_pencil",
|
|
brush_category_attr="grease_pencil_tool",
|
|
brush_category_layout=(
|
|
('PENCIL',),
|
|
('PEN',),
|
|
('INK',),
|
|
('INKNOISE',),
|
|
('BLOCK',),
|
|
('MARKER',),
|
|
('FILL',),
|
|
('SOFT',),
|
|
('HARD',),
|
|
('STROKE',),
|
|
)
|
|
)
|
|
|
|
|
|
class _defs_gpencil_edit:
|
|
@ToolDef.from_fn
|
|
def bend():
|
|
return dict(
|
|
text="Bend",
|
|
icon="ops.gpencil.edit_bend",
|
|
widget=None,
|
|
keymap=(
|
|
("transform.bend",
|
|
dict(release_confirm=True),
|
|
dict(type='EVT_TWEAK_A', value='ANY')),
|
|
),
|
|
)
|
|
|
|
@ToolDef.from_fn
|
|
def box_select():
|
|
return dict(
|
|
text="Select Box",
|
|
icon="ops.generic.select_box",
|
|
widget=None,
|
|
keymap=(
|
|
("gpencil.select_box",
|
|
dict(),
|
|
dict(type='EVT_TWEAK_A', value='ANY')),
|
|
),
|
|
)
|
|
|
|
@ToolDef.from_fn
|
|
def circle_select():
|
|
return dict(
|
|
text="Select Circle",
|
|
icon="ops.generic.select_circle",
|
|
widget=None,
|
|
keymap=(
|
|
("gpencil.select_circle",
|
|
dict(),
|
|
dict(type='EVT_TWEAK_A', value='ANY')),
|
|
),
|
|
)
|
|
|
|
@ToolDef.from_fn
|
|
def lasso_select():
|
|
return dict(
|
|
text="Select Lasso",
|
|
icon="ops.generic.select_lasso",
|
|
widget=None,
|
|
keymap=(
|
|
("gpencil.select_lasso",
|
|
dict(),
|
|
dict(type='EVT_TWEAK_A', value='ANY')),
|
|
),
|
|
)
|
|
|
|
@ToolDef.from_fn
|
|
def shear():
|
|
return dict(
|
|
text="Shear",
|
|
icon="ops.gpencil.edit_shear",
|
|
widget=None,
|
|
keymap=(
|
|
("transform.shear",
|
|
dict(release_confirm=True),
|
|
dict(type='EVT_TWEAK_A', value='ANY')),
|
|
),
|
|
)
|
|
|
|
@ToolDef.from_fn
|
|
def tosphere():
|
|
return dict(
|
|
text="To Sphere",
|
|
icon="ops.transform.tosphere",
|
|
widget=None,
|
|
keymap=(
|
|
("transform.tosphere",
|
|
dict(release_confirm=True),
|
|
dict(type='EVT_TWEAK_A', value='ANY')),
|
|
),
|
|
)
|
|
|
|
|
|
class _defs_gpencil_sculpt:
|
|
@staticmethod
|
|
def draw_settings_common(context, layout, tool):
|
|
ob = context.active_object
|
|
if ob and ob.mode == 'GPENCIL_SCULPT':
|
|
tool_settings = context.tool_settings
|
|
settings = tool_settings.gpencil_sculpt
|
|
tool = settings.tool
|
|
brush = settings.brush
|
|
|
|
layout.prop(brush, "size", slider=True)
|
|
|
|
row = layout.row(align=True)
|
|
row.prop(brush, "strength", slider=True)
|
|
row.prop(brush, "use_pressure_strength", text="")
|
|
|
|
if tool in {'THICKNESS', 'STRENGTH', 'PINCH', 'TWIST'}:
|
|
row.separator()
|
|
row.prop(brush, "direction", expand=True, text="")
|
|
|
|
@ToolDef.from_fn
|
|
def smooth():
|
|
def draw_settings(context, layout, tool):
|
|
_defs_gpencil_sculpt.draw_settings_common(context, layout, tool)
|
|
|
|
return dict(
|
|
text="Smooth",
|
|
icon="ops.gpencil.sculpt_smooth",
|
|
widget=None,
|
|
keymap=(
|
|
("gpencil.brush_paint",
|
|
dict(mode='SMOOTH', wait_for_input=False),
|
|
dict(type='EVT_TWEAK_A', value='ANY')),
|
|
),
|
|
draw_settings=draw_settings,
|
|
)
|
|
|
|
@ToolDef.from_fn
|
|
def thickness():
|
|
def draw_settings(context, layout, tool):
|
|
_defs_gpencil_sculpt.draw_settings_common(context, layout, tool)
|
|
|
|
return dict(
|
|
text="Thickness",
|
|
icon="ops.gpencil.sculpt_thickness",
|
|
widget=None,
|
|
keymap=(
|
|
("gpencil.brush_paint",
|
|
dict(mode='THICKNESS', wait_for_input=False),
|
|
dict(type='EVT_TWEAK_A', value='ANY')),
|
|
),
|
|
draw_settings=draw_settings,
|
|
)
|
|
|
|
@ToolDef.from_fn
|
|
def strength():
|
|
def draw_settings(context, layout, tool):
|
|
_defs_gpencil_sculpt.draw_settings_common(context, layout, tool)
|
|
|
|
return dict(
|
|
text="Strength",
|
|
icon="ops.gpencil.sculpt_strength",
|
|
widget=None,
|
|
keymap=(
|
|
("gpencil.brush_paint",
|
|
dict(mode='STRENGTH', wait_for_input=False),
|
|
dict(type='EVT_TWEAK_A', value='ANY')),
|
|
),
|
|
draw_settings=draw_settings,
|
|
)
|
|
|
|
@ToolDef.from_fn
|
|
def grab():
|
|
def draw_settings(context, layout, tool):
|
|
_defs_gpencil_sculpt.draw_settings_common(context, layout, tool)
|
|
|
|
return dict(
|
|
text="Grab",
|
|
icon="ops.gpencil.sculpt_grab",
|
|
widget=None,
|
|
keymap=(
|
|
("gpencil.brush_paint",
|
|
dict(mode='GRAB', wait_for_input=False),
|
|
dict(type='EVT_TWEAK_A', value='ANY')),
|
|
),
|
|
draw_settings=draw_settings,
|
|
)
|
|
|
|
@ToolDef.from_fn
|
|
def push():
|
|
def draw_settings(context, layout, tool):
|
|
_defs_gpencil_sculpt.draw_settings_common(context, layout, tool)
|
|
|
|
return dict(
|
|
text="Push",
|
|
icon="ops.gpencil.sculpt_push",
|
|
widget=None,
|
|
keymap=(
|
|
("gpencil.brush_paint",
|
|
dict(mode='PUSH', wait_for_input=False),
|
|
dict(type='EVT_TWEAK_A', value='ANY')),
|
|
),
|
|
draw_settings=draw_settings,
|
|
)
|
|
|
|
@ToolDef.from_fn
|
|
def twist():
|
|
def draw_settings(context, layout, tool):
|
|
_defs_gpencil_sculpt.draw_settings_common(context, layout, tool)
|
|
|
|
return dict(
|
|
text="Twist",
|
|
icon="ops.gpencil.sculpt_twist",
|
|
widget=None,
|
|
keymap=(
|
|
("gpencil.brush_paint",
|
|
dict(mode='TWIST', wait_for_input=False),
|
|
dict(type='EVT_TWEAK_A', value='ANY')),
|
|
),
|
|
draw_settings=draw_settings,
|
|
)
|
|
|
|
@ToolDef.from_fn
|
|
def pinch():
|
|
def draw_settings(context, layout, tool):
|
|
_defs_gpencil_sculpt.draw_settings_common(context, layout, tool)
|
|
|
|
return dict(
|
|
text="Pinch",
|
|
icon="ops.gpencil.sculpt_pinch",
|
|
widget=None,
|
|
keymap=(
|
|
("gpencil.brush_paint",
|
|
dict(mode='PINCH', wait_for_input=False),
|
|
dict(type='EVT_TWEAK_A', value='ANY')),
|
|
),
|
|
draw_settings=draw_settings,
|
|
)
|
|
|
|
@ToolDef.from_fn
|
|
def randomize():
|
|
def draw_settings(context, layout, tool):
|
|
_defs_gpencil_sculpt.draw_settings_common(context, layout, tool)
|
|
|
|
return dict(
|
|
text="Randomize",
|
|
icon="ops.gpencil.sculpt_randomize",
|
|
widget=None,
|
|
keymap=(
|
|
("gpencil.brush_paint",
|
|
dict(mode='RANDOMIZE', wait_for_input=False),
|
|
dict(type='EVT_TWEAK_A', value='ANY')),
|
|
),
|
|
draw_settings=draw_settings,
|
|
)
|
|
|
|
@ToolDef.from_fn
|
|
def clone():
|
|
def draw_settings(context, layout, tool):
|
|
_defs_gpencil_sculpt.draw_settings_common(context, layout, tool)
|
|
|
|
return dict(
|
|
text="Clone",
|
|
icon="ops.gpencil.sculpt_clone",
|
|
widget=None,
|
|
keymap=(
|
|
("gpencil.brush_paint",
|
|
dict(mode='CLONE', wait_for_input=False),
|
|
dict(type='EVT_TWEAK_A', value='ANY')),
|
|
),
|
|
draw_settings=draw_settings,
|
|
)
|
|
|
|
|
|
class _defs_gpencil_weight:
|
|
@staticmethod
|
|
def draw_settings_common(context, layout, tool):
|
|
ob = context.active_object
|
|
if ob and ob.mode == 'GPENCIL_WEIGHT':
|
|
settings = context.tool_settings.gpencil_sculpt
|
|
brush = settings.brush
|
|
|
|
layout.prop(brush, "size", slider=True)
|
|
|
|
row = layout.row(align=True)
|
|
row.prop(brush, "strength", slider=True)
|
|
row.prop(brush, "use_pressure_strength", text="")
|
|
|
|
@ToolDef.from_fn
|
|
def paint():
|
|
def draw_settings(context, layout, tool):
|
|
_defs_gpencil_weight.draw_settings_common(context, layout, tool)
|
|
|
|
return dict(
|
|
text="Draw",
|
|
icon="ops.gpencil.sculpt_weight",
|
|
widget=None,
|
|
keymap=(
|
|
("gpencil.brush_paint",
|
|
dict(mode='WEIGHT', wait_for_input=False),
|
|
dict(type='EVT_TWEAK_A', value='ANY')),
|
|
),
|
|
draw_settings=draw_settings,
|
|
)
|
|
|
|
|
|
class TOPBAR_PT_gpencil_materials(Panel):
|
|
bl_space_type = 'VIEW_3D'
|
|
bl_region_type = 'HEADER'
|
|
bl_label = "Materials"
|
|
bl_ui_units_x = 14
|
|
|
|
@classmethod
|
|
def poll(cls, context):
|
|
ob = context.object
|
|
return ob and ob.type == 'GPENCIL'
|
|
|
|
@staticmethod
|
|
def draw(self, context):
|
|
layout = self.layout
|
|
ob = context.object
|
|
|
|
if ob:
|
|
is_sortable = len(ob.material_slots) > 1
|
|
rows = 1
|
|
if (is_sortable):
|
|
rows = 10
|
|
|
|
row = layout.row()
|
|
|
|
row.template_list("GPENCIL_UL_matslots", "", ob, "material_slots", ob, "active_material_index", rows=rows)
|
|
|
|
col = row.column(align=True)
|
|
col.menu("GPENCIL_MT_color_specials", icon='DOWNARROW_HLT', text="")
|
|
|
|
if is_sortable:
|
|
col.separator()
|
|
|
|
col.operator("object.material_slot_move", icon='TRIA_UP', text="").direction = 'UP'
|
|
col.operator("object.material_slot_move", icon='TRIA_DOWN', text="").direction = 'DOWN'
|
|
|
|
col.separator()
|
|
|
|
sub = col.column(align=True)
|
|
sub.operator("gpencil.color_isolate", icon='LOCKED', text="").affect_visibility = False
|
|
sub.operator("gpencil.color_isolate", icon='HIDE_OFF', text="").affect_visibility = True
|
|
|
|
|
|
class IMAGE_PT_tools_active(ToolSelectPanelHelper, Panel):
|
|
bl_space_type = 'IMAGE_EDITOR'
|
|
bl_region_type = 'TOOLS'
|
|
bl_category = "Tools"
|
|
bl_label = "Tools" # not visible
|
|
bl_options = {'HIDE_HEADER'}
|
|
|
|
# Satisfy the 'ToolSelectPanelHelper' API.
|
|
keymap_prefix = "Image Editor Tool:"
|
|
|
|
@classmethod
|
|
def tools_from_context(cls, context, mode=None):
|
|
if mode is None:
|
|
if context.space_data is None:
|
|
mode = 'VIEW'
|
|
else:
|
|
mode = context.space_data.mode
|
|
for tools in (cls._tools[None], cls._tools.get(mode, ())):
|
|
for item in tools:
|
|
if not (type(item) is ToolDef) and callable(item):
|
|
yield from item(context)
|
|
else:
|
|
yield item
|
|
|
|
@classmethod
|
|
def tools_all(cls):
|
|
yield from cls._tools.items()
|
|
|
|
# for reuse
|
|
_tools_transform = (
|
|
_defs_image_uv_transform.transform,
|
|
)
|
|
|
|
_tools_select = (
|
|
(
|
|
_defs_image_uv_select.border,
|
|
_defs_image_uv_select.circle,
|
|
_defs_image_uv_select.lasso,
|
|
),
|
|
)
|
|
|
|
_tools_annotate = (
|
|
(
|
|
_defs_annotate_image.scribble,
|
|
_defs_annotate_image.line,
|
|
_defs_annotate_image.poly,
|
|
_defs_annotate_image.eraser,
|
|
),
|
|
)
|
|
|
|
_tools = {
|
|
None: [
|
|
# for all modes
|
|
],
|
|
'VIEW': [
|
|
],
|
|
'UV': [
|
|
_defs_image_generic.cursor,
|
|
*_tools_select,
|
|
None,
|
|
*_tools_transform,
|
|
None,
|
|
*_tools_annotate,
|
|
None,
|
|
lambda context: (
|
|
_defs_image_uv_sculpt.generate_from_brushes(context)
|
|
if _defs_image_generic.poll_uvedit(context)
|
|
else ()
|
|
),
|
|
],
|
|
'MASK': [
|
|
None,
|
|
],
|
|
'PAINT': [
|
|
_defs_texture_paint.generate_from_brushes,
|
|
],
|
|
}
|
|
|
|
|
|
class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel):
|
|
bl_space_type = 'VIEW_3D'
|
|
bl_region_type = 'TOOLS'
|
|
bl_category = "Tools"
|
|
bl_label = "Tools" # not visible
|
|
bl_options = {'HIDE_HEADER'}
|
|
|
|
# Satisfy the 'ToolSelectPanelHelper' API.
|
|
keymap_prefix = "3D View Tool:"
|
|
|
|
@classmethod
|
|
def tools_from_context(cls, context, mode=None):
|
|
if mode is None:
|
|
mode = context.mode
|
|
for tools in (cls._tools[None], cls._tools.get(mode, ())):
|
|
for item in tools:
|
|
if not (type(item) is ToolDef) and callable(item):
|
|
yield from item(context)
|
|
else:
|
|
yield item
|
|
|
|
@classmethod
|
|
def tools_all(cls):
|
|
yield from cls._tools.items()
|
|
|
|
# for reuse
|
|
_tools_transform = (
|
|
_defs_transform.transform,
|
|
_defs_transform.translate,
|
|
_defs_transform.rotate,
|
|
(
|
|
_defs_transform.scale,
|
|
_defs_transform.scale_cage,
|
|
),
|
|
)
|
|
|
|
_tools_select = (
|
|
(
|
|
_defs_view3d_select.border,
|
|
_defs_view3d_select.circle,
|
|
_defs_view3d_select.lasso,
|
|
),
|
|
)
|
|
|
|
_tools_annotate = (
|
|
(
|
|
_defs_annotate_view3d.scribble,
|
|
_defs_annotate_view3d.line,
|
|
_defs_annotate_view3d.poly,
|
|
_defs_annotate_view3d.eraser,
|
|
),
|
|
_defs_view3d_generic.ruler,
|
|
)
|
|
|
|
_tools_gpencil_select = (
|
|
(
|
|
_defs_gpencil_edit.box_select,
|
|
_defs_gpencil_edit.circle_select,
|
|
_defs_gpencil_edit.lasso_select,
|
|
),
|
|
)
|
|
|
|
_tools = {
|
|
None: [
|
|
# Don't use this! because of paint modes.
|
|
# _defs_view3d_generic.cursor,
|
|
# End group.
|
|
],
|
|
'OBJECT': [
|
|
_defs_view3d_generic.cursor,
|
|
*_tools_select,
|
|
None,
|
|
*_tools_transform,
|
|
None,
|
|
*_tools_annotate,
|
|
],
|
|
'POSE': [
|
|
_defs_view3d_generic.cursor,
|
|
*_tools_select,
|
|
None,
|
|
*_tools_transform,
|
|
None,
|
|
*_tools_annotate,
|
|
None,
|
|
(
|
|
_defs_pose.breakdown,
|
|
_defs_pose.push,
|
|
_defs_pose.relax,
|
|
),
|
|
],
|
|
'EDIT_ARMATURE': [
|
|
_defs_view3d_generic.cursor,
|
|
*_tools_select,
|
|
None,
|
|
*_tools_transform,
|
|
None,
|
|
*_tools_annotate,
|
|
_defs_edit_armature.roll,
|
|
(
|
|
_defs_edit_armature.bone_size,
|
|
_defs_edit_armature.bone_envelope,
|
|
),
|
|
None,
|
|
(
|
|
_defs_edit_armature.extrude,
|
|
_defs_edit_armature.extrude_cursor,
|
|
),
|
|
],
|
|
'EDIT_MESH': [
|
|
_defs_view3d_generic.cursor,
|
|
*_tools_select,
|
|
None,
|
|
*_tools_transform,
|
|
None,
|
|
*_tools_annotate,
|
|
None,
|
|
_defs_edit_mesh.cube_add,
|
|
None,
|
|
(
|
|
_defs_edit_mesh.extrude,
|
|
_defs_edit_mesh.extrude_normals,
|
|
_defs_edit_mesh.extrude_individual,
|
|
_defs_edit_mesh.extrude_cursor,
|
|
),
|
|
_defs_edit_mesh.inset,
|
|
_defs_edit_mesh.bevel,
|
|
(
|
|
_defs_edit_mesh.loopcut_slide,
|
|
_defs_edit_mesh.offset_edge_loops_slide,
|
|
),
|
|
(
|
|
_defs_edit_mesh.knife,
|
|
_defs_edit_mesh.bisect,
|
|
),
|
|
_defs_edit_mesh.poly_build,
|
|
(
|
|
_defs_edit_mesh.spin,
|
|
_defs_edit_mesh.spin_duplicate,
|
|
),
|
|
(
|
|
_defs_edit_mesh.vertex_smooth,
|
|
_defs_edit_mesh.vertex_randomize,
|
|
),
|
|
(
|
|
_defs_edit_mesh.edge_slide,
|
|
_defs_edit_mesh.vert_slide,
|
|
),
|
|
(
|
|
_defs_edit_mesh.shrink_fatten,
|
|
_defs_edit_mesh.push_pull,
|
|
),
|
|
(
|
|
_defs_edit_mesh.shear,
|
|
_defs_edit_mesh.tosphere,
|
|
),
|
|
(
|
|
_defs_edit_mesh.rip_region,
|
|
_defs_edit_mesh.rip_edge,
|
|
),
|
|
],
|
|
'EDIT_CURVE': [
|
|
_defs_view3d_generic.cursor,
|
|
*_tools_select,
|
|
None,
|
|
*_tools_transform,
|
|
None,
|
|
*_tools_annotate,
|
|
None,
|
|
_defs_edit_curve.draw,
|
|
(
|
|
_defs_edit_curve.extrude,
|
|
_defs_edit_curve.extrude_cursor,
|
|
)
|
|
],
|
|
'PARTICLE': [
|
|
_defs_view3d_generic.cursor,
|
|
_defs_particle.generate_from_brushes,
|
|
],
|
|
'SCULPT': [
|
|
_defs_sculpt.generate_from_brushes,
|
|
None,
|
|
_defs_sculpt.hide_border,
|
|
_defs_sculpt.mask_border,
|
|
],
|
|
'PAINT_TEXTURE': [
|
|
_defs_texture_paint.generate_from_brushes,
|
|
],
|
|
'PAINT_VERTEX': [
|
|
_defs_vertex_paint.generate_from_brushes,
|
|
None,
|
|
lambda context: (
|
|
VIEW3D_PT_tools_active._tools_select
|
|
if _defs_vertex_paint.poll_select_mask(context)
|
|
else ()
|
|
),
|
|
],
|
|
'PAINT_WEIGHT': [
|
|
# TODO, check for mixed pose mode
|
|
_defs_view3d_generic.cursor,
|
|
_defs_weight_paint.generate_from_brushes,
|
|
None,
|
|
_defs_weight_paint.sample_weight,
|
|
_defs_weight_paint.sample_weight_group,
|
|
None,
|
|
lambda context: (
|
|
VIEW3D_PT_tools_active._tools_select
|
|
if _defs_weight_paint.poll_select_mask(context)
|
|
else ()
|
|
),
|
|
None,
|
|
_defs_weight_paint.gradient,
|
|
],
|
|
'GPENCIL_PAINT': [
|
|
_defs_gpencil_paint.generate_from_brushes,
|
|
],
|
|
'GPENCIL_EDIT': [
|
|
_defs_view3d_generic.cursor,
|
|
_defs_gpencil_edit.box_select,
|
|
_defs_gpencil_edit.circle_select,
|
|
_defs_gpencil_edit.lasso_select,
|
|
None,
|
|
_defs_gpencil_edit.bend,
|
|
_defs_gpencil_edit.shear,
|
|
_defs_gpencil_edit.tosphere,
|
|
],
|
|
'GPENCIL_SCULPT': [
|
|
_defs_gpencil_sculpt.smooth,
|
|
_defs_gpencil_sculpt.thickness,
|
|
_defs_gpencil_sculpt.strength,
|
|
_defs_gpencil_sculpt.grab,
|
|
_defs_gpencil_sculpt.push,
|
|
_defs_gpencil_sculpt.twist,
|
|
_defs_gpencil_sculpt.pinch,
|
|
_defs_gpencil_sculpt.randomize,
|
|
_defs_gpencil_sculpt.clone,
|
|
None,
|
|
*_tools_gpencil_select,
|
|
],
|
|
'GPENCIL_WEIGHT': [
|
|
_defs_gpencil_weight.paint,
|
|
],
|
|
}
|
|
|
|
class TOPBAR_PT_annotation_layers(Panel, AnnotationDataPanel):
|
|
bl_space_type = 'VIEW_3D'
|
|
bl_region_type = 'HEADER'
|
|
bl_label = "Layers"
|
|
bl_ui_units_x = 14
|
|
|
|
|
|
classes = (
|
|
IMAGE_PT_tools_active,
|
|
VIEW3D_PT_tools_active,
|
|
TOPBAR_PT_gpencil_materials,
|
|
TOPBAR_PT_annotation_layers,
|
|
)
|
|
|
|
if __name__ == "__main__": # only for live edit.
|
|
from bpy.utils import register_class
|
|
for cls in classes:
|
|
register_class(cls)
|