Files
test/scripts/startup/bl_ui/properties_grease_pencil_common.py
Falk David 5f5b1b83d0 GPv3: Rename mode enum names and python identifiers
This renames the mode identifiers to be consistent with e.g. the context mode identifiers and other names used for the new Grease Pencil.

For `object.mode`:
* `PAINT_GPENCIL` -> `PAINT_GREASE_PENCIL`
* `SCULPT_GPENCIL` -> `SCULPT_GREASE_PENCIL`
* `VERTEX_GPENCIL` -> `VERTEX_GREASE_PENCIL`
* `WEIGHT_GPENCIL` -> `WEIGHT_GREASE_PENCIL`

For the internal `ob->mode` flag:
* `OB_MODE_PAINT_GPENCIL_LEGACY` -> `OB_MODE_PAINT_GREASE_PENCIL`
* `OB_MODE_SCULPT_GPENCIL_LEGACY` -> `OB_MODE_SCULPT_GREASE_PENCIL`
* `OB_MODE_VERTEX_GPENCIL_LEGACY` -> `OB_MODE_VERTEX_GREASE_PENCIL`
* `OB_MODE_WEIGHT_GPENCIL_LEGACY` -> `OB_MODE_WEIGHT_GREASE_PENCIL`

Resolves #127374.

Pull Request: https://projects.blender.org/blender/blender/pulls/128604
2024-10-04 19:20:00 +02:00

824 lines
29 KiB
Python

# SPDX-FileCopyrightText: 2009-2023 Blender Authors
#
# SPDX-License-Identifier: GPL-2.0-or-later
import bpy
from bpy.types import Menu, UIList, Operator
from bpy.app.translations import pgettext_iface as iface_
# XXX: To be replaced with active tools
# Currently only used by the clip editor
class AnnotationDrawingToolsPanel:
# subclass must set
# bl_space_type = 'IMAGE_EDITOR'
bl_label = "Annotation"
bl_category = "Annotation"
bl_region_type = 'TOOLS'
def draw(self, context):
layout = self.layout
tool_settings = context.tool_settings
col = layout.column(align=True)
col.label(text="Draw:")
row = col.row(align=True)
row.operator("gpencil.annotate", icon='GREASEPENCIL', text="Draw").mode = 'DRAW'
# XXX: Needs a dedicated icon
row.operator("gpencil.annotate", icon='FORCE_CURVE', text="Erase").mode = 'ERASER'
row = col.row(align=True)
row.operator("gpencil.annotate", icon='LINE_DATA', text="Line").mode = 'DRAW_STRAIGHT'
row.operator("gpencil.annotate", icon='MESH_DATA', text="Poly").mode = 'DRAW_POLY'
col.separator()
col.label(text="Stroke Placement:")
row = col.row(align=True)
row.prop_enum(tool_settings, "annotation_stroke_placement_view2d", 'VIEW')
row.prop_enum(tool_settings, "annotation_stroke_placement_view2d", 'IMAGE', text="Image")
class GreasePencilSculptAdvancedPanel:
def draw(self, context):
layout = self.layout
layout.use_property_split = True
layout.use_property_decorate = False
tool_settings = context.scene.tool_settings
brush = tool_settings.gpencil_sculpt_paint.brush
tool = brush.gpencil_sculpt_tool
gp_settings = brush.gpencil_settings
if tool in {'SMOOTH', 'RANDOMIZE'}:
col = layout.column(heading="Affect", align=True)
col.prop(gp_settings, "use_edit_position", text="Position")
col.prop(gp_settings, "use_edit_strength", text="Strength")
col.prop(gp_settings, "use_edit_thickness", text="Thickness")
col.prop(gp_settings, "use_edit_uv", text="UV")
# GP Object Tool Settings
class GreasePencilDisplayPanel:
bl_label = "Brush Tip"
bl_options = {'DEFAULT_CLOSED'}
@classmethod
def poll(cls, context):
ob = context.active_object
if context.mode == 'SCULPT_GREASE_PENCIL':
brush = context.tool_settings.gpencil_sculpt_paint.brush
elif context.mode == 'WEIGHT_GREASE_PENCIL':
brush = context.tool_settings.gpencil_weight_paint.brush
else:
brush = context.tool_settings.gpencil_paint.brush
if ob and ob.type in {'GPENCIL', 'GREASEPENCIL'} and brush:
return True
return False
def draw_header(self, context):
if self.is_popover:
return
tool_settings = context.tool_settings
if context.mode == 'PAINT_GPENCIL':
settings = tool_settings.gpencil_paint
elif context.mode == 'SCULPT_GPENCIL':
settings = tool_settings.gpencil_sculpt_paint
elif context.mode == 'WEIGHT_GPENCIL' or context.mode == 'WEIGHT_GREASE_PENCIL':
settings = tool_settings.gpencil_weight_paint
elif context.mode == 'VERTEX_GPENCIL' or context.mode == 'VERTEX_GREASE_PENCIL':
settings = tool_settings.gpencil_vertex_paint
brush = settings.brush
if brush:
self.layout.prop(settings, "show_brush", text="")
def draw(self, context):
layout = self.layout
layout.use_property_split = True
layout.use_property_decorate = False
tool_settings = context.tool_settings
if context.mode == 'PAINT_GPENCIL' or context.mode == 'PAINT_GREASE_PENCIL':
settings = tool_settings.gpencil_paint
elif context.mode == 'SCULPT_GPENCIL' or context.mode == 'SCULPT_GREASE_PENCIL':
settings = tool_settings.gpencil_sculpt_paint
elif context.mode == 'WEIGHT_GPENCIL' or context.mode == 'WEIGHT_GREASE_PENCIL':
settings = tool_settings.gpencil_weight_paint
elif context.mode == 'VERTEX_GPENCIL' or context.mode == 'VERTEX_GREASE_PENCIL':
settings = tool_settings.gpencil_vertex_paint
brush = settings.brush
gp_settings = brush.gpencil_settings
ob = context.active_object
if self.is_popover and ob.mode not in {'PAINT_GREASE_PENCIL', 'VERTEX_GREASE_PENCIL'}:
row = layout.row(align=True)
row.use_property_split = False
row.prop(settings, "show_brush", text="Display Cursor")
if ob.mode == 'PAINT_GREASE_PENCIL':
if self.is_popover:
row = layout.row(align=True)
row.prop(settings, "show_brush", text="Display Cursor")
if brush.gpencil_tool == 'DRAW':
row = layout.row(align=True)
row.active = settings.show_brush
row.prop(gp_settings, "show_lasso", text="Show Fill Color While Drawing")
elif ob.mode == 'SCULPT_GREASE_PENCIL':
col = layout.column(align=True)
col.active = settings.show_brush
col.prop(brush, "cursor_color_add", text="Cursor Color")
if brush.gpencil_sculpt_tool in {'THICKNESS', 'STRENGTH', 'PINCH', 'TWIST'}:
col.prop(brush, "cursor_color_subtract", text="Inverse Color")
elif ob.mode == 'WEIGHT_GREASE_PENCIL':
col = layout.column(align=True)
col.active = settings.show_brush
col.prop(brush, "cursor_color_add", text="Cursor Color")
elif ob.mode == 'VERTEX_GREASE_PENCIL':
row = layout.row(align=True)
row.prop(settings, "show_brush", text="Display Cursor")
class GreasePencilBrushFalloff:
bl_label = "Falloff"
bl_options = {'DEFAULT_CLOSED'}
def draw(self, context):
layout = self.layout
tool_settings = context.tool_settings
settings = None
if context.mode == 'PAINT_GPENCIL':
settings = tool_settings.gpencil_paint
if context.mode == 'SCULPT_GPENCIL':
settings = tool_settings.gpencil_sculpt_paint
elif context.mode == 'WEIGHT_GPENCIL' or context.mode == 'WEIGHT_GREASE_PENCIL':
settings = tool_settings.gpencil_weight_paint
elif context.mode == 'VERTEX_GPENCIL':
settings = tool_settings.gpencil_vertex_paint
if settings:
brush = settings.brush
col = layout.column(align=True)
row = col.row(align=True)
row.prop(brush, "curve_preset", text="")
if brush.curve_preset == 'CUSTOM':
layout.template_curve_mapping(brush, "curve", brush=True)
col = layout.column(align=True)
row = col.row(align=True)
row.operator("brush.curve_preset", icon='SMOOTHCURVE', text="").shape = 'SMOOTH'
row.operator("brush.curve_preset", icon='SPHERECURVE', text="").shape = 'ROUND'
row.operator("brush.curve_preset", icon='ROOTCURVE', text="").shape = 'ROOT'
row.operator("brush.curve_preset", icon='SHARPCURVE', text="").shape = 'SHARP'
row.operator("brush.curve_preset", icon='LINCURVE', text="").shape = 'LINE'
row.operator("brush.curve_preset", icon='NOCURVE', text="").shape = 'MAX'
class GREASE_PENCIL_MT_move_to_layer(Menu):
bl_label = "Move to Layer"
def draw(self, context):
layout = self.layout
layout.operator_context = 'INVOKE_REGION_WIN'
grease_pencil = context.active_object.data
layout.operator("grease_pencil.move_to_layer", text="New Layer", icon='ADD').add_new_layer = True
if not grease_pencil.layers:
return
layout.separator()
for i in range(len(grease_pencil.layers) - 1, -1, -1):
layer = grease_pencil.layers[i]
if layer == grease_pencil.layers.active:
icon = 'GREASEPENCIL'
else:
icon = 'NONE'
layout.operator("grease_pencil.move_to_layer", text=layer.name, icon=icon).target_layer_name = layer.name
class GREASE_PENCIL_MT_layer_active(Menu):
bl_label = "Change Active Layer"
def draw(self, context):
layout = self.layout
layout.operator_context = 'INVOKE_REGION_WIN'
obd = context.active_object.data
nlop = layout.operator("grease_pencil.layer_add", text="New Layer", icon='ADD')
nlop.new_layer_name = "Layer"
if not obd.layers:
return
layout.separator()
for i in range(len(obd.layers) - 1, -1, -1):
layer = obd.layers[i]
if layer == obd.layers.active:
icon = 'GREASEPENCIL'
else:
icon = 'NONE'
layout.operator("grease_pencil.layer_active", text=layer.name, icon=icon).layer = i
class GPENCIL_UL_annotation_layer(UIList):
def draw_item(self, _context, layout, _data, item, icon, _active_data, _active_propname, _index):
# assert(isinstance(item, bpy.types.GPencilLayer)
gpl = item
if self.layout_type in {'DEFAULT', 'COMPACT'}:
if gpl.lock:
layout.active = False
split = layout.split(factor=0.2)
split.prop(gpl, "color", text="", emboss=True)
split.prop(gpl, "info", text="", emboss=False)
row = layout.row(align=True)
row.prop(gpl, "show_in_front", text="", icon='XRAY' if gpl.show_in_front else 'FACESEL', emboss=False)
row.prop(gpl, "annotation_hide", text="", emboss=False)
elif self.layout_type == 'GRID':
layout.alignment = 'CENTER'
layout.label(text="", icon_value=icon)
class AnnotationDataPanel:
bl_label = "Annotations"
bl_region_type = 'UI'
bl_options = {'DEFAULT_CLOSED'}
def draw_header(self, context):
space = context.space_data
if space.type not in {
'VIEW_3D',
'TOPBAR',
'SEQUENCE_EDITOR',
'IMAGE_EDITOR',
'NODE_EDITOR',
'PROPERTIES',
}:
self.layout.prop(space, "show_annotation", text="")
def draw(self, context):
layout = self.layout
layout.use_property_decorate = False
space = context.space_data
is_clip_editor = space.type == 'CLIP_EDITOR'
# Grease Pencil owner.
gpd_owner = context.annotation_data_owner
gpd = context.annotation_data
# Owner selector.
if is_clip_editor:
col = layout.column()
col.label(text="Data Source:")
row = col.row()
row.prop(space, "annotation_source", expand=True)
# Only allow adding annotation ID if its owner exist
if context.annotation_data_owner is None:
row = layout.row()
row.active = False
row.label(text="No annotation source")
return
row = layout.row()
row.template_ID(gpd_owner, "grease_pencil", new="gpencil.annotation_add", unlink="gpencil.data_unlink")
# List of layers/notes.
if gpd and gpd.layers:
self.draw_layers(context, layout, gpd)
def draw_layers(self, context, layout, gpd):
row = layout.row()
col = row.column()
if len(gpd.layers) >= 2:
layer_rows = 5
else:
layer_rows = 3
col.template_list(
"GPENCIL_UL_annotation_layer", "", gpd, "layers", gpd.layers, "active_index",
rows=layer_rows, sort_reverse=True, sort_lock=True,
)
col = row.column()
sub = col.column(align=True)
sub.operator("gpencil.layer_annotation_add", icon='ADD', text="")
sub.operator("gpencil.layer_annotation_remove", icon='REMOVE', text="")
gpl = context.active_annotation_layer
if gpl:
if len(gpd.layers) > 1:
col.separator()
sub = col.column(align=True)
sub.operator("gpencil.layer_annotation_move", icon='TRIA_UP', text="").type = 'UP'
sub.operator("gpencil.layer_annotation_move", icon='TRIA_DOWN', text="").type = 'DOWN'
tool_settings = context.tool_settings
if gpd and gpl:
layout.prop(gpl, "annotation_opacity", text="Opacity", slider=True)
layout.prop(gpl, "thickness")
else:
layout.prop(tool_settings, "annotation_thickness", text="Thickness")
if gpl:
# Full-Row - Frame Locking (and Delete Frame)
row = layout.row(align=True)
row.active = not gpl.lock
if gpl.active_frame:
lock_status = iface_("Locked") if gpl.lock_frame else iface_("Unlocked")
lock_label = iface_("Frame: {:d} ({:s})").format(gpl.active_frame.frame_number, lock_status)
else:
lock_label = iface_("Lock Frame")
row.prop(gpl, "lock_frame", text=lock_label, icon='UNLOCKED')
row.operator("gpencil.annotation_active_frame_delete", text="", icon='X')
class AnnotationOnionSkin:
bl_label = "Onion Skin"
bl_region_type = 'UI'
bl_options = {'DEFAULT_CLOSED'}
@classmethod
def poll(cls, context):
# Show this panel as long as someone that might own this exists
# AND the owner isn't an object (e.g. GP Object)
if context.annotation_data_owner is None:
return False
elif type(context.annotation_data_owner) is bpy.types.Object:
return False
else:
gpl = context.active_annotation_layer
if gpl is None:
return False
return True
def draw_header(self, context):
gpl = context.active_annotation_layer
self.layout.prop(gpl, "use_annotation_onion_skinning", text="")
def draw(self, context):
layout = self.layout
layout.use_property_decorate = False
gpl = context.active_annotation_layer
col = layout.column()
col.prop(gpl, "annotation_onion_use_custom_color")
split = col.split(factor=0.5)
split.active = gpl.use_annotation_onion_skinning
# - Before Frames
sub = split.column(align=True)
row = sub.row(align=True)
if gpl.annotation_onion_use_custom_color:
row.prop(gpl, "annotation_onion_before_color", text="")
sub.prop(gpl, "annotation_onion_before_range", text="Before")
# - After Frames
sub = split.column(align=True)
row = sub.row(align=True)
if gpl.annotation_onion_use_custom_color:
row.prop(gpl, "annotation_onion_after_color", text="")
sub.prop(gpl, "annotation_onion_after_range", text="After")
class GreasePencilMaterialsPanel:
# Mix-in, use for properties editor and top-bar.
def draw(self, context):
layout = self.layout
show_full_ui = (self.bl_space_type == 'PROPERTIES')
is_view3d = (self.bl_space_type == 'VIEW_3D')
tool_settings = context.scene.tool_settings
gpencil_paint = tool_settings.gpencil_paint
brush = gpencil_paint.brush if gpencil_paint else None
ob = context.object
row = layout.row()
if ob:
is_sortable = len(ob.material_slots) > 1
rows = 7
row.template_list("GPENCIL_UL_matslots", "", ob, "material_slots", ob, "active_material_index", rows=rows)
# if top-bar popover and brush pinned, disable.
if is_view3d and brush is not None:
gp_settings = brush.gpencil_settings
if gp_settings.use_material_pin:
row.enabled = False
col = row.column(align=True)
if show_full_ui:
col.operator("object.material_slot_add", icon='ADD', text="")
col.operator("object.material_slot_remove", icon='REMOVE', text="")
col.separator()
col.menu("GPENCIL_MT_material_context_menu", 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(
"grease_pencil.material_isolate",
icon='RESTRICT_VIEW_ON',
text="").affect_visibility = True
sub.operator("grease_pencil.material_isolate", icon='LOCKED', text="").affect_visibility = False
if show_full_ui:
row = layout.row()
row.template_ID(ob, "active_material", new="material.new", live_icon=True)
slot = context.material_slot
if slot:
icon_link = 'MESH_DATA' if slot.link == 'DATA' else 'OBJECT_DATA'
row.prop(slot, "link", icon=icon_link, icon_only=True)
if ob.mode == 'EDIT':
row = layout.row(align=True)
row.operator("grease_pencil.stroke_material_set", text="Assign")
row.operator("grease_pencil.material_select", text="Select").deselect = False
row.operator("grease_pencil.material_select", text="Deselect").deselect = True
# stroke color
ma = None
if is_view3d and brush is not None:
gp_settings = brush.gpencil_settings
if gp_settings.use_material_pin is False:
if len(ob.material_slots) > 0 and ob.active_material_index >= 0:
ma = ob.material_slots[ob.active_material_index].material
else:
ma = gp_settings.material
else:
if len(ob.material_slots) > 0 and ob.active_material_index >= 0:
ma = ob.material_slots[ob.active_material_index].material
if is_view3d and ma is not None and ma.grease_pencil is not None:
gpcolor = ma.grease_pencil
col = layout.column(align=True)
if gpcolor.show_stroke and gpcolor.stroke_style == 'SOLID':
col.prop(gpcolor, "color", text="Stroke Color")
if gpcolor.show_fill and gpcolor.fill_style == 'SOLID':
col.prop(gpcolor, "fill_color", text="Fill Color")
else:
space = context.space_data
row.template_ID(space, "pin_id")
class GreasePencilVertexcolorPanel:
def draw(self, context):
layout = self.layout
layout.use_property_split = True
layout.use_property_decorate = False
tool_settings = context.scene.tool_settings
is_vertex = context.mode == 'VERTEX_GPENCIL'
gpencil_paint = tool_settings.gpencil_vertex_paint if is_vertex else tool_settings.gpencil_paint
brush = gpencil_paint.brush
gp_settings = brush.gpencil_settings
tool = brush.gpencil_vertex_tool if is_vertex else brush.gpencil_tool
ob = context.object
if ob:
col = layout.column()
col.template_color_picker(brush, "color", value_slider=True)
sub_row = layout.row(align=True)
sub_row.prop(brush, "color", text="")
sub_row.prop(brush, "secondary_color", text="")
sub_row.operator("gpencil.tint_flip", icon='FILE_REFRESH', text="")
row = layout.row(align=True)
row.template_ID(gpencil_paint, "palette", new="palette.new")
if gpencil_paint.palette:
layout.template_palette(gpencil_paint, "palette", color=True)
if tool in {'DRAW', 'FILL'} and is_vertex is False:
row = layout.row(align=True)
row.prop(gp_settings, "vertex_mode", text="Mode")
row = layout.row(align=True)
row.prop(gp_settings, "vertex_color_factor", slider=True, text="Mix Factor")
class GPENCIL_UL_layer(UIList):
def draw_item(self, _context, layout, _data, item, icon, _active_data, _active_propname, _index):
# assert(isinstance(item, bpy.types.GPencilLayer)
gpl = item
if self.layout_type in {'DEFAULT', 'COMPACT'}:
if gpl.lock:
layout.active = False
row = layout.row(align=True)
row.label(
text="",
icon='BONE_DATA' if gpl.is_parented else 'BLANK1',
)
row.prop(gpl, "info", text="", emboss=False)
row = layout.row(align=True)
icon_mask = 'CLIPUV_DEHLT' if gpl.use_mask_layer else 'CLIPUV_HLT'
row.prop(gpl, "use_mask_layer", text="", icon=icon_mask, emboss=False)
subrow = row.row(align=True)
subrow.prop(
gpl,
"use_onion_skinning",
text="",
icon='ONIONSKIN_ON' if gpl.use_onion_skinning else 'ONIONSKIN_OFF',
emboss=False,
)
row.prop(gpl, "hide", text="", emboss=False)
row.prop(gpl, "lock", text="", emboss=False)
elif self.layout_type == 'GRID':
layout.alignment = 'CENTER'
layout.label(
text="",
icon_value=icon,
)
class GreasePencilSimplifyPanel:
def draw_header(self, context):
rd = context.scene.render
self.layout.prop(rd, "simplify_gpencil", text="")
def draw(self, context):
layout = self.layout
layout.use_property_split = True
layout.use_property_decorate = False
rd = context.scene.render
layout.active = rd.use_simplify and rd.simplify_gpencil
col = layout.column()
col.prop(rd, "simplify_gpencil_onplay")
col.prop(rd, "simplify_gpencil_view_fill")
col.prop(rd, "simplify_gpencil_modifier")
col.prop(rd, "simplify_gpencil_shader_fx")
col.prop(rd, "simplify_gpencil_tint")
col.prop(rd, "simplify_gpencil_antialiasing")
class GreasePencilLayerTransformPanel:
def draw(self, context):
layout = self.layout
layout.use_property_split = True
ob = context.object
gpd = ob.data
gpl = gpd.layers.active
layout.active = not gpl.lock
row = layout.row(align=True)
row.prop(gpl, "location")
row = layout.row(align=True)
row.prop(gpl, "rotation")
row = layout.row(align=True)
row.prop(gpl, "scale")
class GreasePencilLayerAdjustmentsPanel:
def draw(self, context):
layout = self.layout
layout.use_property_split = True
ob = context.object
gpd = ob.data
gpl = gpd.layers.active
layout.active = not gpl.lock
# Layer options
# Offsets - Color Tint
layout.enabled = not gpl.lock
col = layout.column(align=True)
col.prop(gpl, "tint_color")
col.prop(gpl, "tint_factor", text="Factor", slider=True)
# Offsets - Thickness
col = layout.row(align=True)
col.prop(gpl, "line_change", text="Stroke Thickness")
class GPENCIL_UL_masks(UIList):
def draw_item(self, _context, layout, _data, item, icon, _active_data, _active_propname, _index):
mask = item
if self.layout_type in {'DEFAULT', 'COMPACT'}:
row = layout.row(align=True)
row.prop(mask, "name", text="", emboss=False, icon_value=icon)
row.prop(mask, "invert", text="", emboss=False)
row.prop(mask, "hide", text="", emboss=False)
elif self.layout_type == 'GRID':
layout.alignment = 'CENTER'
layout.prop(mask, "name", text="", emboss=False, icon_value=icon)
class GreasePencilLayerRelationsPanel:
def draw(self, context):
layout = self.layout
layout.use_property_split = True
layout.use_property_decorate = False
scene = context.scene
ob = context.object
gpd = ob.data
gpl = gpd.layers.active
col = layout.column()
col.active = not gpl.lock
col.prop(gpl, "parent")
col.prop(gpl, "parent_type", text="Type")
parent = gpl.parent
if parent and gpl.parent_type == 'BONE' and parent.type == 'ARMATURE':
col.prop_search(gpl, "parent_bone", parent.data, "bones", text="Bone")
layout.separator()
col = layout.row(align=True)
col.prop(gpl, "pass_index")
col = layout.row(align=True)
col.prop_search(gpl, "viewlayer_render", scene, "view_layers", text="View Layer")
col = layout.row(align=True)
# Only enable this property when a view layer is selected.
col.enabled = bool(gpl.viewlayer_render)
col.prop(gpl, "use_viewlayer_masks")
class GreasePencilLayerDisplayPanel:
def draw(self, context):
layout = self.layout
layout.use_property_split = True
layout.use_property_decorate = False
ob = context.object
gpd = ob.data
gpl = gpd.layers.active
use_colors = context.preferences.edit.use_anim_channel_group_colors
col = layout.column(align=True)
col.active = use_colors
row = col.row(align=True)
row.prop(gpl, "channel_color")
if not use_colors:
col.label(text="Channel Colors are disabled in Animation preferences")
row = layout.row(align=True)
row.prop(gpl, "use_solo_mode", text="Show Only on Keyframed")
class GreasePencilFlipTintColors(Operator):
"""Switch tint colors"""
bl_label = "Flip Colors"
bl_idname = "gpencil.tint_flip"
@classmethod
def poll(cls, context):
tool_settings = context.tool_settings
settings = None
if context.mode == 'PAINT_GPENCIL':
settings = tool_settings.gpencil_paint
if context.mode == 'SCULPT_GPENCIL':
settings = tool_settings.gpencil_sculpt_paint
elif context.mode == 'WEIGHT_GPENCIL' or context.mode == 'WEIGHT_GREASE_PENCIL':
settings = tool_settings.gpencil_weight_paint
elif context.mode == 'VERTEX_GPENCIL':
settings = tool_settings.gpencil_vertex_paint
return settings and settings.brush
def execute(self, context):
tool_settings = context.tool_settings
settings = None
if context.mode == 'PAINT_GPENCIL':
settings = tool_settings.gpencil_paint
if context.mode == 'SCULPT_GPENCIL':
settings = tool_settings.gpencil_sculpt_paint
elif context.mode == 'WEIGHT_GPENCIL' or context.mode == 'WEIGHT_GREASE_PENCIL':
settings = tool_settings.gpencil_weight_paint
elif context.mode == 'VERTEX_GPENCIL':
settings = tool_settings.gpencil_vertex_paint
brush = settings.brush
color = brush.color
secondary_color = brush.secondary_color
orig_prim = color.hsv
orig_sec = secondary_color.hsv
color.hsv = orig_sec
secondary_color.hsv = orig_prim
return {'FINISHED'}
class GREASE_PENCIL_MT_snap(Menu):
bl_label = "Snap"
def draw(self, _context):
layout = self.layout
layout.operator("grease_pencil.snap_to_grid", text="Selection to Grid")
layout.operator("grease_pencil.snap_to_cursor", text="Selection to Cursor").use_offset = False
layout.operator("grease_pencil.snap_to_cursor", text="Selection to Cursor (Keep Offset)").use_offset = True
layout.separator()
layout.operator("grease_pencil.snap_cursor_to_selected", text="Cursor to Selected")
layout.operator("view3d.snap_cursor_to_center", text="Cursor to World Origin")
layout.operator("view3d.snap_cursor_to_grid", text="Cursor to Grid")
class GREASE_PENCIL_MT_snap_pie(Menu):
bl_label = "Snap"
def draw(self, _context):
layout = self.layout
pie = layout.menu_pie()
pie.operator("view3d.snap_cursor_to_grid", text="Cursor to Grid", icon='CURSOR')
pie.operator("grease_pencil.snap_to_grid", text="Selection to Grid", icon='RESTRICT_SELECT_OFF')
pie.operator("grease_pencil.snap_cursor_to_selected", text="Cursor to Selected", icon='CURSOR')
pie.operator(
"grease_pencil.snap_to_cursor",
text="Selection to Cursor",
icon='RESTRICT_SELECT_OFF',
).use_offset = False
pie.operator(
"grease_pencil.snap_to_cursor",
text="Selection to Cursor (Keep Offset)",
icon='RESTRICT_SELECT_OFF',
).use_offset = True
pie.separator()
pie.operator("view3d.snap_cursor_to_center", text="Cursor to World Origin", icon='CURSOR')
pie.separator()
classes = (
GPENCIL_UL_annotation_layer,
GPENCIL_UL_layer,
GPENCIL_UL_masks,
GREASE_PENCIL_MT_move_to_layer,
GREASE_PENCIL_MT_layer_active,
GREASE_PENCIL_MT_snap,
GREASE_PENCIL_MT_snap_pie,
GreasePencilFlipTintColors,
)
if __name__ == "__main__": # only for live edit.
from bpy.utils import register_class
for cls in classes:
register_class(cls)