Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntonioya <blendergit@gmail.com>2018-07-31 11:22:19 +0300
committerAntonioya <blendergit@gmail.com>2018-07-31 11:50:43 +0300
commit66da2f537ae80ce2b31d1eaf34ad8c03d858938d (patch)
tree4776b9d2e43e4280d01d6f0b7088e6d4f417db0f /release/scripts/startup/bl_ui/properties_grease_pencil_common.py
parent27496cc46bbfd76e98ad3b1ccb8fea534763ffb5 (diff)
New Grease Pencil object for 2D animation
This commit merge the full development done in greasepencil-object branch and include mainly the following features. - New grease pencil object. - New drawing engine. - New grease pencil modes Draw/Sculpt/Edit and Weight Paint. - New brushes for grease pencil. - New modifiers for grease pencil. - New shaders FX. - New material system (replace old palettes and colors). - Split of annotations (old grease pencil) and new grease pencil object. - UI adapted to blender 2.8. You can get more info here: https://code.blender.org/2017/12/drawing-2d-animation-in-blender-2-8/ https://code.blender.org/2018/07/grease-pencil-status-update/ This is the result of nearly two years of development and I want thanks firstly the other members of the grease pencil team: Daniel M. Lara, Matias Mendiola and Joshua Leung for their support, ideas and to keep working in the project all the time, without them this project had been impossible. Also, I want thanks other Blender developers for their help, advices and to be there always to help me, and specially to Clément Foucault, Dalai Felinto, Pablo Vázquez and Campbell Barton.
Diffstat (limited to 'release/scripts/startup/bl_ui/properties_grease_pencil_common.py')
-rw-r--r--release/scripts/startup/bl_ui/properties_grease_pencil_common.py785
1 files changed, 237 insertions, 548 deletions
diff --git a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py
index 55b798d103a..252f87d369f 100644
--- a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py
+++ b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py
@@ -18,45 +18,30 @@
# <pep8 compliant>
-
+import bpy
from bpy.types import Menu, UIList
from bpy.app.translations import pgettext_iface as iface_
def gpencil_stroke_placement_settings(context, layout):
if context.space_data.type == 'VIEW_3D':
- propname = "gpencil_stroke_placement_view3d"
+ propname = "annotation_stroke_placement_view3d"
elif context.space_data.type == 'SEQUENCE_EDITOR':
- propname = "gpencil_stroke_placement_sequencer_preview"
+ propname = "annotation_stroke_placement_sequencer_preview"
elif context.space_data.type == 'IMAGE_EDITOR':
- propname = "gpencil_stroke_placement_image_editor"
+ propname = "annotation_stroke_placement_image_editor"
else:
- propname = "gpencil_stroke_placement_view2d"
+ propname = "annotation_stroke_placement_view2d"
ts = context.tool_settings
col = layout.column(align=True)
- col.label(text="Stroke Placement:")
-
- row = col.row(align=True)
- row.prop_enum(ts, propname, 'VIEW')
- row.prop_enum(ts, propname, 'CURSOR')
-
- if context.space_data.type == 'VIEW_3D':
+ if context.space_data.type != 'VIEW_3D':
+ col.label(text="Stroke Placement:")
row = col.row(align=True)
- row.prop_enum(ts, propname, 'SURFACE')
- row.prop_enum(ts, propname, 'STROKE')
-
- row = col.row(align=False)
- row.active = getattr(ts, propname) in {'SURFACE', 'STROKE'}
- row.prop(ts, "use_gpencil_stroke_endpoints")
-
- if context.scene.tool_settings.gpencil_stroke_placement_view3d == 'CURSOR':
- row = col.row(align=True)
- row.label("Lock axis:")
- row = col.row(align=True)
- row.prop(ts.gpencil_sculpt, "lockaxis", expand=True)
+ row.prop_enum(ts, propname, 'VIEW')
+ row.prop_enum(ts, propname, 'CURSOR', text="Cursor")
def gpencil_active_brush_settings_simple(context, layout):
@@ -73,7 +58,7 @@ def gpencil_active_brush_settings_simple(context, layout):
row.operator_menu_enum("gpencil.brush_change", "brush", text="", icon='BRUSH_DATA')
row.prop(brush, "name", text="")
- col.prop(brush, "line_width", slider=True)
+ col.prop(brush, "size", slider=True)
row = col.row(align=True)
row.prop(brush, "use_random_pressure", text="", icon='RNDCURVE')
row.prop(brush, "pen_sensitivity_factor", slider=True)
@@ -90,6 +75,7 @@ def gpencil_active_brush_settings_simple(context, layout):
row.prop(brush, "angle_factor", text="Factor", slider=True)
+# XXX: To be replaced with active tools
class GreasePencilDrawingToolsPanel:
# subclass must set
# bl_space_type = 'IMAGE_EDITOR'
@@ -99,8 +85,7 @@ class GreasePencilDrawingToolsPanel:
@classmethod
def poll(cls, context):
- # XXX - disabled in 2.8 branch.
- return False
+ return True
@staticmethod
def draw(self, context):
@@ -113,12 +98,12 @@ class GreasePencilDrawingToolsPanel:
col.label(text="Draw:")
row = col.row(align=True)
- row.operator("gpencil.draw", icon='GREASEPENCIL', text="Draw").mode = 'DRAW'
- row.operator("gpencil.draw", icon='FORCE_CURVE', text="Erase").mode = 'ERASER' # XXX: Needs a dedicated icon
+ row.operator("gpencil.annotate", icon='GREASEPENCIL', text="Draw").mode = 'DRAW'
+ row.operator("gpencil.annotate", icon='FORCE_CURVE', text="Erase").mode = 'ERASER' # XXX: Needs a dedicated icon
row = col.row(align=True)
- row.operator("gpencil.draw", icon='LINE_DATA', text="Line").mode = 'DRAW_STRAIGHT'
- row.operator("gpencil.draw", icon='MESH_DATA', text="Poly").mode = 'DRAW_POLY'
+ 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()
@@ -126,15 +111,15 @@ class GreasePencilDrawingToolsPanel:
sub.operator("gpencil.blank_frame_add", icon='NEW')
sub.operator("gpencil.active_frames_delete_all", icon='X', text="Delete Frame(s)")
- sub = col.column(align=True)
- sub.prop(context.tool_settings, "use_gpencil_additive_drawing", text="Additive Drawing")
- sub.prop(context.tool_settings, "use_gpencil_continuous_drawing", text="Continuous Drawing")
- sub.prop(context.tool_settings, "use_gpencil_draw_onback", text="Draw on Back")
+ #sub = col.column(align=True)
+ #sub.prop(context.tool_settings, "use_gpencil_additive_drawing", text="Additive Drawing")
+ #sub.prop(context.tool_settings, "use_gpencil_continuous_drawing", text="Continuous Drawing")
+ #sub.prop(context.tool_settings, "use_gpencil_draw_onback", text="Draw on Back")
col.separator()
col.separator()
- if context.space_data.type in {'VIEW_3D', 'CLIP_EDITOR'}:
+ if context.space_data.type in {'CLIP_EDITOR'}:
col.separator()
col.label("Data Source:")
row = col.row(align=True)
@@ -143,8 +128,8 @@ class GreasePencilDrawingToolsPanel:
elif is_clip_editor:
row.prop(context.space_data, "grease_pencil_source", expand=True)
- col.separator()
- col.separator()
+ #col.separator()
+ #col.separator()
gpencil_stroke_placement_settings(context, col)
@@ -157,28 +142,16 @@ class GreasePencilDrawingToolsPanel:
col = layout.column(align=True)
col.prop(gpd, "use_stroke_edit_mode", text="Enable Editing", icon='EDIT', toggle=True)
- if is_3d_view:
- col.separator()
- col.separator()
-
- col.label(text="Tools:")
- col.operator_menu_enum("gpencil.convert", text="Convert to Geometry...", property="type")
- col.operator("view3d.ruler")
-
class GreasePencilStrokeEditPanel:
# subclass must set
# bl_space_type = 'IMAGE_EDITOR'
bl_label = "Edit Strokes"
- bl_category = "Grease Pencil"
+ bl_category = "Tools"
bl_region_type = 'TOOLS'
- bl_options = {'DEFAULT_CLOSED'}
@classmethod
def poll(cls, context):
- # XXX - disabled in 2.8 branch.
- return False
-
if context.gpencil_data is None:
return False
@@ -204,7 +177,7 @@ class GreasePencilStrokeEditPanel:
col.operator("gpencil.select_linked")
col.operator("gpencil.select_more")
col.operator("gpencil.select_less")
- col.operator("gpencil.palettecolor_select")
+ col.operator("gpencil.select_alternate")
layout.label(text="Edit:")
row = layout.row(align=True)
@@ -228,258 +201,124 @@ class GreasePencilStrokeEditPanel:
layout.separator()
- col = layout.column(align=True)
- col.operator("transform.bend", text="Bend")
- col.operator("transform.mirror", text="Mirror")
- col.operator("transform.shear", text="Shear")
- col.operator("transform.tosphere", text="To Sphere")
-
layout.separator()
col = layout.column(align=True)
col.operator_menu_enum("gpencil.stroke_arrange", text="Arrange Strokes...", property="direction")
col.operator("gpencil.stroke_change_color", text="Move to Color")
- if is_3d_view:
- layout.separator()
-
layout.separator()
col = layout.column(align=True)
col.operator("gpencil.stroke_subdivide", text="Subdivide")
- col.operator("gpencil.stroke_join", text="Join").type = 'JOIN'
- col.operator("gpencil.stroke_join", text="Join & Copy").type = 'JOINCOPY'
- col.operator("gpencil.stroke_flip", text="Flip Direction")
-
- gpd = context.gpencil_data
- if gpd:
- col.prop(gpd, "show_stroke_direction", text="Show Directions")
-
- if is_3d_view:
- layout.separator()
- layout.operator_menu_enum("gpencil.reproject", text="Reproject Strokes...", property="type")
-
-
-class GreasePencilInterpolatePanel:
- bl_space_type = 'VIEW_3D'
- bl_label = "Interpolate"
- bl_category = "Grease Pencil"
- bl_region_type = 'TOOLS'
- bl_options = {'DEFAULT_CLOSED'}
-
- @classmethod
- def poll(cls, context):
- # XXX - disabled in 2.8 branch.
- return False
-
- if context.gpencil_data is None:
- return False
- elif context.space_data.type != 'VIEW_3D':
- return False
-
- gpd = context.gpencil_data
- return bool(context.editable_gpencil_strokes) and bool(gpd.use_stroke_edit_mode)
-
- @staticmethod
- def draw(self, context):
- layout = self.layout
- settings = context.tool_settings.gpencil_interpolate
-
- col = layout.column(align=True)
- col.operator("gpencil.interpolate", text="Interpolate")
- col.operator("gpencil.interpolate_sequence", text="Sequence")
- col.operator("gpencil.interpolate_reverse", text="Remove Breakdowns")
-
- col = layout.column(align=True)
- col.label(text="Options:")
- col.prop(settings, "interpolate_all_layers")
- col.prop(settings, "interpolate_selected_only")
-
- col = layout.column(align=True)
- col.label(text="Sequence Options:")
- col.prop(settings, "type")
- if settings.type == 'CUSTOM':
- box = layout.box()
- # TODO: Options for loading/saving curve presets?
- box.template_curve_mapping(settings, "interpolation_curve", brush=True)
- elif settings.type != 'LINEAR':
- col.prop(settings, "easing")
-
- if settings.type == 'BACK':
- layout.prop(settings, "back")
- elif setting.type == 'ELASTIC':
- sub = layout.column(align=True)
- sub.prop(settings, "amplitude")
- sub.prop(settings, "period")
-
-
-class GreasePencilBrushPanel:
- # subclass must set
- # bl_space_type = 'IMAGE_EDITOR'
- bl_label = "Drawing Brushes"
- bl_category = "Grease Pencil"
- bl_region_type = 'TOOLS'
-
- @classmethod
- def poll(cls, context):
- # XXX - disabled in 2.8 branch.
- return False
+ row = col.row(align=True)
+ row.operator("gpencil.stroke_simplify_fixed", text="Simplify")
+ row.operator("gpencil.stroke_simplify", text="Adaptative")
- @staticmethod
- def draw(self, context):
- layout = self.layout
+ col.separator()
- row = layout.row()
- col = row.column()
- ts = context.scene.tool_settings
- if len(ts.gpencil_brushes) >= 2:
- brows = 3
- else:
- brows = 2
- col.template_list("GPENCIL_UL_brush", "", ts, "gpencil_brushes", ts.gpencil_brushes, "active_index", rows=brows)
+ row = col.row(align=True)
+ row.operator("gpencil.stroke_join", text="Join").type = 'JOIN'
+ row.operator("gpencil.stroke_join", text="& Copy").type = 'JOINCOPY'
- col = row.column()
+ col.operator("gpencil.stroke_flip", text="Flip Direction")
- sub = col.column(align=True)
- sub.operator("gpencil.brush_add", icon='ZOOMIN', text="")
- sub.operator("gpencil.brush_remove", icon='ZOOMOUT', text="")
- sub.menu("GPENCIL_MT_brush_specials", icon='DOWNARROW_HLT', text="")
- brush = context.active_gpencil_brush
- if brush:
- if len(ts.gpencil_brushes) > 1:
- col.separator()
- sub = col.column(align=True)
- sub.operator("gpencil.brush_move", icon='TRIA_UP', text="").type = 'UP'
- sub.operator("gpencil.brush_move", icon='TRIA_DOWN', text="").type = 'DOWN'
+ if is_3d_view:
+ layout.separator()
- # Brush details
- if brush is not None:
- row = layout.row()
- row.prop(brush, "line_width")
- row = layout.row(align=True)
- row.prop(brush, "use_random_pressure", text="", icon='RNDCURVE')
- row.prop(brush, "pen_sensitivity_factor", slider=True)
- row.prop(brush, "use_pressure", text="", icon='STYLUS_PRESSURE')
- row = layout.row(align=True)
- row.prop(brush, "use_random_strength", text="", icon='RNDCURVE')
- row.prop(brush, "strength", slider=True)
- row.prop(brush, "use_strength_pressure", text="", icon='STYLUS_PRESSURE')
- row = layout.row(align=True)
- row.prop(brush, "random_press", slider=True)
+ col = layout.column(align=True)
+ col.operator_menu_enum("gpencil.stroke_separate", text="Separate...", property="mode")
+ col.operator("gpencil.stroke_split", text="Split")
- row = layout.row(align=True)
- row.prop(brush, "jitter", slider=True)
- row.prop(brush, "use_jitter_pressure", text="", icon='STYLUS_PRESSURE')
- row = layout.row()
- row.prop(brush, "angle", slider=True)
- row.prop(brush, "angle_factor", text="Factor", slider=True)
-
- box = layout.box()
- col = box.column(align=True)
- col.label(text="Stroke Quality:")
- col.prop(brush, "pen_smooth_factor")
- col.prop(brush, "pen_smooth_steps")
- col.separator()
- row = col.row(align=False)
- row.prop(brush, "pen_subdivision_steps")
- row.prop(brush, "random_subdiv", text="Randomness", slider=True)
+ col = layout.column(align=True)
+ col.label(text="Cleanup:")
+ col.operator_menu_enum("gpencil.reproject", text="Reproject Strokes...", property="type")
+ col.operator_menu_enum("gpencil.frame_clean_fill", text="Clean Boundary Strokes...", property="mode")
class GreasePencilStrokeSculptPanel:
# subclass must set
# bl_space_type = 'IMAGE_EDITOR'
bl_label = "Sculpt Strokes"
- bl_category = "Grease Pencil"
- bl_region_type = 'TOOLS'
-
- @classmethod
- def poll(cls, context):
- # XXX - disabled in 2.8 branch.
- return False
-
- if context.gpencil_data is None:
- return False
-
- gpd = context.gpencil_data
- return bool(context.editable_gpencil_strokes) and bool(gpd.use_stroke_edit_mode)
+ bl_category = "Tools"
@staticmethod
def draw(self, context):
layout = self.layout
+ layout.use_property_split = True
+ layout.use_property_decorate = False
settings = context.tool_settings.gpencil_sculpt
tool = settings.tool
brush = settings.brush
- layout.column().prop(settings, "tool")
+ layout.template_icon_view(settings, "tool", show_labels=True)
- col = layout.column()
- col.prop(brush, "size", slider=True)
- row = col.row(align=True)
+ layout.prop(brush, "size", slider=True)
+ row = layout.row(align=True)
row.prop(brush, "strength", slider=True)
row.prop(brush, "use_pressure_strength", text="")
- col.prop(brush, "use_falloff")
- if tool in {'SMOOTH', 'RANDOMIZE'}:
- row = layout.row(align=True)
- row.prop(settings, "affect_position", text="Position", icon='MESH_DATA', toggle=True)
- row.prop(settings, "affect_strength", text="Strength", icon='COLOR', toggle=True)
- row.prop(settings, "affect_thickness", text="Thickness", icon='LINE_DATA', toggle=True)
- layout.separator()
+ layout.prop(brush, "use_falloff")
- if tool == 'THICKNESS':
- layout.row().prop(brush, "direction", expand=True)
- elif tool == 'PINCH':
- row = layout.row(align=True)
- row.prop_enum(brush, "direction", 'ADD', text="Pinch")
- row.prop_enum(brush, "direction", 'SUBTRACT', text="Inflate")
- elif settings.tool == 'TWIST':
- row = layout.row(align=True)
- row.prop_enum(brush, "direction", 'SUBTRACT', text="CW")
- row.prop_enum(brush, "direction", 'ADD', text="CCW")
+ if tool in {'SMOOTH', 'RANDOMIZE'}:
+ layout.prop(settings, "affect_position", text="Affect Position")
+ layout.prop(settings, "affect_strength", text="Affect Strength")
+ layout.prop(settings, "affect_thickness", text="Affect Thickness")
- row = layout.row(align=True)
- row.prop(settings, "use_select_mask")
- row = layout.row(align=True)
- row.prop(settings, "selection_alpha", slider=True)
+ if tool == 'SMOOTH':
+ layout.prop(brush, "affect_pressure")
- if tool == 'SMOOTH':
- layout.prop(brush, "affect_pressure")
+ layout.prop(settings, "affect_uv", text="Affect UV")
+ if tool in {'THICKNESS', 'PINCH', 'TWIST'}:
+ layout.prop(brush, "direction", expand=True)
-class GreasePencilBrushCurvesPanel:
- # subclass must set
- # bl_space_type = 'IMAGE_EDITOR'
- bl_label = "Brush Curves"
- bl_category = "Grease Pencil"
- bl_region_type = 'TOOLS'
+
+# GP Object Tool Settings
+class GreasePencilAppearancePanel:
+ bl_label = "Brush Appearance"
bl_options = {'DEFAULT_CLOSED'}
@classmethod
def poll(cls, context):
- # XXX - disabled in 2.8 branch.
- return False
-
- if context.active_gpencil_brush is None:
- return False
-
- brush = context.active_gpencil_brush
- return bool(brush)
+ ob = context.active_object
+ return ob and ob.type == 'GPENCIL'
@staticmethod
def draw(self, context):
layout = self.layout
- brush = context.active_gpencil_brush
- # Brush
- layout.label("Sensitivity")
- box = layout.box()
- box.template_curve_mapping(brush, "curve_sensitivity", brush=True)
+ layout.use_property_split = True
+ layout.use_property_decorate = False
- layout.label("Strength")
- box = layout.box()
- box.template_curve_mapping(brush, "curve_strength", brush=True)
+ ob = context.active_object
- layout.label("Jitter")
- box = layout.box()
- box.template_curve_mapping(brush, "curve_jitter", brush=True)
+ if ob.mode == 'GPENCIL_PAINT':
+ brush = context.active_gpencil_brush
+ gp_settings = brush.gpencil_settings
+
+ layout.prop(gp_settings, "gpencil_brush_type", text="Brush Type")
+
+ sub = layout.column(align=True)
+ sub.enabled = not brush.use_custom_icon
+ sub.prop(gp_settings, "gp_icon", text="Icon")
+
+ layout.prop(brush, "use_custom_icon")
+ sub = layout.column()
+ sub.active = brush.use_custom_icon
+ sub.prop(brush, "icon_filepath", text="")
+
+ layout.prop(gp_settings, "use_cursor", text="Show Brush")
+
+ if gp_settings.gpencil_brush_type == 'FILL':
+ layout.prop(brush, "cursor_color_add", text="Color")
+
+ elif ob.mode in ('GPENCIL_SCULPT', 'GPENCIL_WEIGHT'):
+ settings = context.tool_settings.gpencil_sculpt
+ brush = settings.brush
+
+ col = layout.column(align=True)
+ col.prop(brush, "use_cursor", text="Show Brush")
+ col.row().prop(brush, "cursor_color_add", text="Add")
+ col.row().prop(brush, "cursor_color_sub", text="Subtract")
###############################
@@ -539,6 +378,7 @@ class GPENCIL_MT_pie_tool_palette(Menu):
col.operator("gpencil.select_border", text="Border Select", icon='BORDER_RECT')
col.operator("gpencil.select_circle", text="Circle Select", icon='META_EMPTY')
col.operator("gpencil.select_lasso", text="Lasso Select", icon='BORDER_LASSO')
+ col.operator("gpencil.select_alternate", text="Alternate Select", icon='BORDER_LASSO')
# SW - Edit Tools
col = pie.column()
@@ -566,7 +406,7 @@ class GPENCIL_MT_pie_settings_palette(Menu):
pie = layout.menu_pie()
gpd = context.gpencil_data
gpl = context.active_gpencil_layer
- palcolor = context.active_gpencil_palettecolor
+ palcolor = None #context.active_gpencil_palettecolor
brush = context.active_gpencil_brush
is_editmode = bool(gpd and gpd.use_stroke_edit_mode and context.editable_gpencil_strokes)
@@ -737,6 +577,16 @@ class GPENCIL_MT_snap(Menu):
layout.operator("view3d.snap_cursor_to_grid", text="Cursor to Grid")
+class GPENCIL_MT_separate(Menu):
+ bl_label = "Separate"
+
+ def draw(self, context):
+ layout = self.layout
+ layout.operator("gpencil.stroke_separate", text="Selected Points").mode = 'POINT'
+ layout.operator("gpencil.stroke_separate", text="Selected Strokes").mode = 'STROKE'
+ layout.operator("gpencil.stroke_separate", text="Active Layer").mode = 'LAYER'
+
+
class GPENCIL_MT_gpencil_edit_specials(Menu):
bl_label = "GPencil Specials"
@@ -747,6 +597,14 @@ class GPENCIL_MT_gpencil_edit_specials(Menu):
layout.operator_context = 'INVOKE_REGION_WIN'
layout.operator("gpencil.stroke_subdivide", text="Subdivide")
+ layout.operator("gpencil.stroke_simplify_fixed", text="Simplify")
+ layout.operator("gpencil.stroke_simplify", text="Simplify Adaptative")
+
+ layout.separator()
+ layout.menu("GPENCIL_MT_separate", text="Separate")
+
+ layout.separator()
+ layout.operator("gpencil.stroke_split", text="Split")
layout.separator()
@@ -754,167 +612,129 @@ class GPENCIL_MT_gpencil_edit_specials(Menu):
layout.operator("gpencil.stroke_join", text="Join & Copy").type = 'JOINCOPY'
layout.operator("gpencil.stroke_flip", text="Flip Direction")
+ layout.separator()
+ layout.operator("gpencil.frame_duplicate", text="Duplicate Active Frame")
+ layout.operator("gpencil.frame_duplicate", text="Duplicate Active Frame All Layers").mode = 'ALL'
+
if is_3d_view:
layout.separator()
layout.operator("gpencil.reproject")
-###############################
-
-
-class GPENCIL_UL_brush(UIList):
- def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
- # assert(isinstance(item, bpy.types.GPencilBrush)
- brush = item
-
- if self.layout_type in {'DEFAULT', 'COMPACT'}:
- row = layout.row(align=True)
- row.prop(brush, "name", text="", emboss=False, icon='BRUSH_DATA')
- elif self.layout_type == 'GRID':
- layout.alignment = 'CENTER'
- layout.label(text="", icon_value=icon)
-
-
-class GPENCIL_UL_palettecolor(UIList):
- def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
- # assert(isinstance(item, bpy.types.PaletteColor)
- palcolor = item
-
- if self.layout_type in {'DEFAULT', 'COMPACT'}:
- if palcolor.lock:
- layout.active = False
-
- split = layout.split(percentage=0.25)
- row = split.row(align=True)
- row.enabled = not palcolor.lock
- row.prop(palcolor, "color", text="", emboss=palcolor.is_stroke_visible)
- row.prop(palcolor, "fill_color", text="", emboss=palcolor.is_fill_visible)
- split.prop(palcolor, "name", text="", emboss=False)
-
- row = layout.row(align=True)
- row.prop(palcolor, "lock", text="", emboss=False)
- row.prop(palcolor, "hide", text="", emboss=False)
- if palcolor.ghost is True:
- icon = 'GHOST_DISABLED'
- else:
- icon = 'GHOST_ENABLED'
- row.prop(palcolor, "ghost", text="", icon=icon, emboss=False)
-
- elif self.layout_type == 'GRID':
- layout.alignment = 'CENTER'
- layout.label(text="", icon_value=icon)
-
+class GPENCIL_MT_gpencil_sculpt_specials(Menu):
+ bl_label = "GPencil Specials"
-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
+ def draw(self, context):
+ layout = self.layout
+ is_3d_view = context.space_data.type == 'VIEW_3D'
- if self.layout_type in {'DEFAULT', 'COMPACT'}:
- if gpl.lock:
- layout.active = False
+ layout.operator_context = 'INVOKE_REGION_WIN'
- row = layout.row(align=True)
- if gpl.is_parented:
- icon = 'BONE_DATA'
- else:
- icon = 'BLANK1'
+ layout.operator("gpencil.frame_duplicate", text="Duplicate Active Frame")
+ layout.operator("gpencil.frame_duplicate", text="Duplicate Active Frame All Layers").mode = 'ALL'
- row.label(text="", icon=icon)
- row.prop(gpl, "info", text="", emboss=False)
+ layout.separator()
- row = layout.row(align=True)
- row.prop(gpl, "lock", text="", emboss=False)
- row.prop(gpl, "hide", text="", emboss=False)
- row.prop(gpl, "unlock_color", text="", emboss=False)
- elif self.layout_type == 'GRID':
- layout.alignment = 'CENTER'
- layout.label(text="", icon_value=icon)
+ layout.operator("gpencil.stroke_subdivide", text="Subdivide")
+ layout.operator("gpencil.stroke_simplify_fixed", text="Simplify")
+ layout.operator("gpencil.stroke_simplify", text="Simplify Adaptative")
-class GPENCIL_MT_layer_specials(Menu):
- bl_label = "Layer"
+class GPENCIL_MT_gpencil_draw_specials(Menu):
+ bl_label = "GPencil Draw Specials"
def draw(self, context):
layout = self.layout
+ is_3d_view = context.space_data.type == 'VIEW_3D'
- layout.operator("gpencil.layer_duplicate", icon='COPY_ID') # XXX: needs a dedicated icon
-
- layout.separator()
+ layout.operator_context = 'INVOKE_REGION_WIN'
- layout.operator("gpencil.reveal", icon='RESTRICT_VIEW_OFF', text="Show All")
- layout.operator("gpencil.hide", icon='RESTRICT_VIEW_ON', text="Hide Others").unselected = True
+ layout.operator("gpencil.frame_duplicate", text="Duplicate Active Frame")
+ layout.operator("gpencil.frame_duplicate", text="Duplicate Active Frame All Layers").mode = 'ALL'
layout.separator()
+ layout.operator("gpencil.primitive", text="Line", icon='IPO_CONSTANT').type = 'LINE'
+ layout.operator("gpencil.primitive", text="Rectangle", icon='UV_FACESEL').type = 'BOX'
+ layout.operator("gpencil.primitive", text="Circle", icon='ANTIALIASED').type = 'CIRCLE'
- layout.operator("gpencil.lock_all", icon='LOCKED', text="Lock All")
- layout.operator("gpencil.unlock_all", icon='UNLOCKED', text="UnLock All")
-
+ # colors
layout.separator()
+ layout.operator("gpencil.colorpick", text="Colors", icon="GROUP_VCOL")
- layout.operator("gpencil.layer_merge", icon='NLA', text="Merge Down")
-
-class GPENCIL_MT_brush_specials(Menu):
- bl_label = "Layer"
+class GPENCIL_MT_gpencil_draw_delete(Menu):
+ bl_label = "GPencil Draw Delete"
def draw(self, context):
layout = self.layout
- layout.operator("gpencil.brush_copy", icon='PASTEDOWN', text="Copy Current Drawing Brush")
- layout.operator("gpencil.brush_presets_create", icon='HELP', text="Create a Set of Predefined Brushes")
-
+ is_3d_view = context.space_data.type == 'VIEW_3D'
-class GPENCIL_MT_palettecolor_specials(Menu):
- bl_label = "Layer"
+ layout.operator_context = 'INVOKE_REGION_WIN'
- def draw(self, context):
- layout = self.layout
+ layout.operator("gpencil.active_frames_delete_all", text="Delete Frame")
- layout.operator("gpencil.palettecolor_reveal", icon='RESTRICT_VIEW_OFF', text="Show All")
- layout.operator("gpencil.palettecolor_hide", icon='RESTRICT_VIEW_ON', text="Hide Others").unselected = True
- layout.separator()
+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
+ gpd = context.gpencil_data
- layout.operator("gpencil.palettecolor_lock_all", icon='LOCKED', text="Lock All")
- layout.operator("gpencil.palettecolor_unlock_all", icon='UNLOCKED', text="UnLock All")
- layout.operator("gpencil.palettecolor_copy", icon='PASTEDOWN', text="Copy Color")
+ if self.layout_type in {'DEFAULT', 'COMPACT'}:
+ if gpl.lock:
+ layout.active = False
- layout.separator()
+ split = layout.split(percentage=0.2)
+ split.prop(gpl, "color", text="", emboss=True)
+ split.prop(gpl, "info", text="", emboss=False)
- layout.operator("gpencil.palettecolor_select", icon='COLOR', text="Select Strokes")
- layout.operator("gpencil.stroke_change_color", icon='MAN_TRANS', text="Move to Color")
+ row = layout.row(align=True)
+ # row.prop(gpl, "lock", text="", emboss=False)
+ row.prop(gpl, "hide", text="", emboss=False)
+ elif self.layout_type == 'GRID':
+ layout.alignment = 'CENTER'
+ layout.label(text="", icon_value=icon)
class GreasePencilDataPanel:
- # subclass must set
- # bl_space_type = 'IMAGE_EDITOR'
- bl_label = "Grease Pencil Layers"
+ bl_label = "Annotations"
bl_region_type = 'UI'
+ @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.gpencil_data_owner is None:
+ return False
+ elif type(context.gpencil_data_owner) is bpy.types.Object:
+ return False
+ else:
+ return True
+
@staticmethod
def draw_header(self, context):
- self.layout.prop(context.space_data, "show_grease_pencil", text="")
+ if context.space_data.type != 'VIEW_3D':
+ self.layout.prop(context.space_data, "show_annotation", text="")
@staticmethod
def draw(self, context):
layout = self.layout
+ #layout.use_property_split = True
+ layout.use_property_decorate = False
# owner of Grease Pencil data
gpd_owner = context.gpencil_data_owner
gpd = context.gpencil_data
# Owner Selector
- if context.space_data.type == 'VIEW_3D':
- layout.row().prop(context.tool_settings, "grease_pencil_source", expand=True)
- elif context.space_data.type == 'CLIP_EDITOR':
+ if context.space_data.type == 'CLIP_EDITOR':
layout.row().prop(context.space_data, "grease_pencil_source", expand=True)
-
# Grease Pencil data selector
layout.template_ID(gpd_owner, "grease_pencil", new="gpencil.data_add", unlink="gpencil.data_unlink")
# Grease Pencil data...
if (gpd is None) or (not gpd.layers):
- layout.operator("gpencil.layer_add", text="New Layer")
+ layout.operator("gpencil.layer_add", text="New Note")
else:
self.draw_layers(context, layout, gpd)
@@ -926,7 +746,7 @@ class GreasePencilDataPanel:
layer_rows = 5
else:
layer_rows = 2
- col.template_list("GPENCIL_UL_layer", "", gpd, "layers", gpd.layers, "active_index", rows=layer_rows)
+ col.template_list("GPENCIL_UL_annotation_layer", "", gpd, "layers", gpd.layers, "active_index", rows=layer_rows)
col = row.column()
@@ -936,8 +756,6 @@ class GreasePencilDataPanel:
gpl = context.active_gpencil_layer
if gpl:
- sub.menu("GPENCIL_MT_layer_specials", icon='DOWNARROW_HLT', text="")
-
if len(gpd.layers) > 1:
col.separator()
@@ -945,203 +763,70 @@ class GreasePencilDataPanel:
sub.operator("gpencil.layer_move", icon='TRIA_UP', text="").type = 'UP'
sub.operator("gpencil.layer_move", icon='TRIA_DOWN', text="").type = 'DOWN'
- col.separator()
-
- sub = col.column(align=True)
- sub.operator("gpencil.layer_isolate", icon='LOCKED', text="").affect_visibility = False
- sub.operator("gpencil.layer_isolate", icon='RESTRICT_VIEW_OFF', text="").affect_visibility = True
-
if gpl:
- self.draw_layer(context, layout, gpl)
-
- def draw_layer(self, context, layout, gpl):
- row = layout.row(align=True)
- row.prop(gpl, "opacity", text="Opacity", slider=True)
-
- # Layer options
- split = layout.split(percentage=0.5)
- split.active = not gpl.lock
- split.prop(gpl, "show_x_ray")
- split.prop(gpl, "show_points")
-
- # Offsets + Parenting (where available)
- if context.space_data.type == 'VIEW_3D':
- split = layout.split(percentage=0.5)
- else:
- split = layout.column() # parenting is not available in 2D editors...
- split.active = not gpl.lock
-
- # Offsets - Color Tint
- col = split.column()
- subcol = col.column(align=True)
- subcol.label("Tint")
- subcol.enabled = not gpl.lock
- subcol.prop(gpl, "tint_color", text="")
- subcol.prop(gpl, "tint_factor", text="Factor", slider=True)
-
- # Offsets - Thickness
- row = col.row(align=True)
- row.prop(gpl, "line_change", text="Thickness Change", slider=True)
- row.operator("gpencil.stroke_apply_thickness", icon='STYLUS_PRESSURE', text="")
+ # layout.prop(gpl, "opacity", text="Opacity", slider=True)
+ # layout.prop(gpl, "thickness", text="Thickness")
+ #
+ # layout.separator()
- # Parenting
- if context.space_data.type == 'VIEW_3D':
- col = split.column(align=True)
- col.label(text="Parent:")
- col.prop(gpl, "parent", text="")
+ # Full-Row - Frame Locking (and Delete Frame)
+ row = layout.row(align=True)
+ row.active = not gpl.lock
- sub = col.column()
- sub.prop(gpl, "parent_type", text="")
- parent = gpl.parent
- if parent and gpl.parent_type == 'BONE' and parent.type == 'ARMATURE':
- sub.prop_search(gpl, "parent_bone", parent.data, "bones", text="")
+ if gpl.active_frame:
+ lock_status = iface_("Locked") if gpl.lock_frame else iface_("Unlocked")
+ lock_label = iface_("Frame: %d (%s)") % (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.active_frame_delete", text="", icon='X')
- layout.separator()
- # 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)") % (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.active_frame_delete", text="", icon='X')
-
- layout.separator()
+class GreasePencilOnionPanel:
+ @staticmethod
+ def draw_settings(layout, gp):
+ col = layout.column()
- # Onion skinning
- col = layout.column(align=True)
- col.active = not gpl.lock
+ col.prop(gp, "onion_mode")
row = col.row()
- row.prop(gpl, "use_onion_skinning")
- sub = row.row(align=True)
- icon = 'RESTRICT_RENDER_OFF' if gpl.use_ghosts_always else 'RESTRICT_RENDER_ON'
- sub.prop(gpl, "use_ghosts_always", text="", icon=icon)
- sub.prop(gpl, "use_ghost_custom_colors", text="", icon='COLOR')
-
- split = col.split(percentage=0.5)
- split.active = gpl.use_onion_skinning
+ row.prop(gp, "onion_factor", text="Opacity", slider=True)
# - Before Frames
- sub = split.column(align=True)
+ sub = layout.column(align=True)
row = sub.row(align=True)
- row.active = gpl.use_ghost_custom_colors
- row.prop(gpl, "before_color", text="")
- sub.prop(gpl, "ghost_before_range", text="Before")
+ row.active = gp.use_ghost_custom_colors
+ row.prop(gp, "before_color", text="Color Before")
- # - After Frames
- sub = split.column(align=True)
row = sub.row(align=True)
- row.active = gpl.use_ghost_custom_colors
- row.prop(gpl, "after_color", text="")
- sub.prop(gpl, "ghost_after_range", text="After")
-
-
-class GreasePencilPaletteColorPanel:
- # subclass must set
- bl_label = "Grease Pencil Colors"
- bl_region_type = 'UI'
-
- @classmethod
- def poll(cls, context):
- # XXX - disabled in 2.8 branch.
- return False
-
- if context.gpencil_data is None:
- return False
-
- gpd = context.gpencil_data
- return bool(gpd.layers.active)
-
- @staticmethod
- def draw(self, context):
- layout = self.layout
- palette = context.active_gpencil_palette
+ row.active = gp.onion_mode in ('ABSOLUTE', 'RELATIVE')
+ row.prop(gp, "ghost_before_range", text="Frames Before")
- if palette:
- row = layout.row(align=True)
- row.operator_context = 'EXEC_REGION_WIN'
- row.operator_menu_enum("gpencil.palette_change", "palette", text="", icon='COLOR')
- row.prop(palette, "name", text="")
- row.operator("gpencil.palette_add", icon='ZOOMIN', text="")
- row.operator("gpencil.palette_remove", icon='X', text="")
-
- # Palette colors
- row = layout.row()
- col = row.column()
- if len(palette.colors) >= 2:
- color_rows = 5
- else:
- color_rows = 2
- col.template_list("GPENCIL_UL_palettecolor", "", palette, "colors", palette.colors, "active_index",
- rows=color_rows)
-
- col = row.column()
+ # - After Frames
+ sub = layout.column(align=True)
+ row = sub.row(align=True)
+ row.active = gp.use_ghost_custom_colors
+ row.prop(gp, "after_color", text="Color After")
- sub = col.column(align=True)
- sub.operator("gpencil.palettecolor_add", icon='ZOOMIN', text="")
- sub.operator("gpencil.palettecolor_remove", icon='ZOOMOUT', text="")
+ row = sub.row(align=True)
+ row.active = gp.onion_mode in ('ABSOLUTE', 'RELATIVE')
+ row.prop(gp, "ghost_after_range", text="Frames After")
- palcol = context.active_gpencil_palettecolor
- if palcol:
- sub.menu("GPENCIL_MT_palettecolor_specials", icon='DOWNARROW_HLT', text="")
+ layout.prop(gp, "use_ghost_custom_colors", text="Use Custom Color")
+ layout.prop(gp, "use_ghosts_always", text="View In Render")
- if len(palette.colors) > 1:
- col.separator()
+ # - fade and loop
+ row = layout.row()
+ row.active = gp.use_onion_skinning
+ row.prop(gp, "use_onion_fade", text="Fade")
+ if hasattr(gp, "use_onion_loop"): # XXX
+ subrow = layout.row()
+ subrow.active = gp.onion_mode in ('RELATIVE', 'SELECTED')
+ subrow.prop(gp, "use_onion_loop", text="Loop")
- sub = col.column(align=True)
- sub.operator("gpencil.palettecolor_move", icon='TRIA_UP', text="").direction = 'UP'
- sub.operator("gpencil.palettecolor_move", icon='TRIA_DOWN', text="").direction = 'DOWN'
-
- row = layout.row()
- sub = row.row(align=True)
- sub.label(text="Isolate:") # based on active color only
- sub.operator("gpencil.palettecolor_isolate", icon='LOCKED', text="").affect_visibility = False
- sub.operator("gpencil.palettecolor_isolate", icon='RESTRICT_VIEW_OFF', text="").affect_visibility = True
- sub = row.row(align=True)
- sub.label(text="Lock:") # based on other stuff...
- sub.operator("gpencil.stroke_lock_color", icon='BORDER_RECT', text="")
- sub.operator("gpencil.palette_lock_layer", icon='COLOR', text="")
-
- pcolor = palette.colors.active
- if pcolor:
- self.draw_palettecolors(layout, pcolor)
-
- # Draw palette colors
- def draw_palettecolors(self, layout, pcolor):
- # color settings
- split = layout.split(percentage=0.5)
- split.active = not pcolor.lock
-
- # Column 1 - Stroke
- col = split.column(align=True)
- col.enabled = not pcolor.lock
- col.label(text="Stroke:")
- col.prop(pcolor, "color", text="")
- col.prop(pcolor, "alpha", slider=True)
-
- # Column 2 - Fill
- col = split.column(align=True)
- col.enabled = not pcolor.lock
- col.label(text="Fill:")
- col.prop(pcolor, "fill_color", text="")
- col.prop(pcolor, "fill_alpha", text="Opacity", slider=True)
-
- # Options
- split = layout.split(percentage=0.5)
- split.active = not pcolor.lock
-
- col = split.column(align=True)
- col.active = not pcolor.lock
- col.prop(pcolor, "use_volumetric_strokes")
- col = split.column(align=True)
- col.active = not pcolor.lock
- col.prop(pcolor, "use_hq_fill")
+###############################
class GreasePencilToolsPanel:
# For use in "2D" Editors without their own toolbar
@@ -1150,6 +835,7 @@ class GreasePencilToolsPanel:
# bl_options = {'DEFAULT_CLOSED'}
bl_label = "Grease Pencil Settings"
bl_region_type = 'UI'
+ bl_options = {'DEFAULT_CLOSED'}
@classmethod
def poll(cls, context):
@@ -1183,20 +869,23 @@ class GreasePencilToolsPanel:
gpencil_stroke_placement_settings(context, layout)
+###############################
classes = (
GPENCIL_MT_pie_tool_palette,
GPENCIL_MT_pie_settings_palette,
GPENCIL_MT_pie_tools_more,
GPENCIL_MT_pie_sculpt,
+
GPENCIL_MT_snap,
+ GPENCIL_MT_separate,
+
GPENCIL_MT_gpencil_edit_specials,
- GPENCIL_UL_brush,
- GPENCIL_UL_palettecolor,
- GPENCIL_UL_layer,
- GPENCIL_MT_layer_specials,
- GPENCIL_MT_brush_specials,
- GPENCIL_MT_palettecolor_specials,
+ GPENCIL_MT_gpencil_sculpt_specials,
+ GPENCIL_MT_gpencil_draw_specials,
+ GPENCIL_MT_gpencil_draw_delete,
+
+ GPENCIL_UL_annotation_layer,
)
if __name__ == "__main__": # only for live edit.