diff options
author | Antonio Vazquez <blendergit@gmail.com> | 2020-03-09 18:27:24 +0300 |
---|---|---|
committer | Antonio Vazquez <blendergit@gmail.com> | 2020-03-09 18:27:24 +0300 |
commit | 29f3af95272590d26f610ae828b2eeee89c82a00 (patch) | |
tree | a696a58a2561c48f7ec6166e369e22081e0a64d8 /release | |
parent | dcb93126876879d969a30a7865700abd072066f8 (diff) |
GPencil: Refactor of Draw Engine, Vertex Paint and all internal functions
This commit is a full refactor of the grease pencil modules including Draw Engine, Modifiers, VFX, depsgraph update, improvements in operators and conversion of Sculpt and Weight paint tools to real brushes.
Also, a huge code cleanup has been done at all levels.
Thanks to @fclem for his work and yo @pepeland and @mendio for the testing and help in the development.
Differential Revision: https://developer.blender.org/D6293
Diffstat (limited to 'release')
23 files changed, 2077 insertions, 972 deletions
diff --git a/release/datafiles/userdef/userdef_default.c b/release/datafiles/userdef/userdef_default.c index 576cff5bd0e..18750c12d55 100644 --- a/release/datafiles/userdef/userdef_default.c +++ b/release/datafiles/userdef/userdef_default.c @@ -187,7 +187,6 @@ const UserDef U_default = { .pie_menu_radius = 100, .pie_menu_threshold = 12, .opensubdiv_compute_type = 0, - .gpencil_multisamples = 4, .factor_display_type = USER_FACTOR_AS_FACTOR, .render_display_type = USER_RENDER_DISPLAY_WINDOW, .filebrowser_display_type = USER_TEMP_SPACE_DISPLAY_WINDOW, diff --git a/release/scripts/modules/bl_keymap_utils/keymap_from_toolbar.py b/release/scripts/modules/bl_keymap_utils/keymap_from_toolbar.py index da4a47783ad..505223872fe 100644 --- a/release/scripts/modules/bl_keymap_utils/keymap_from_toolbar.py +++ b/release/scripts/modules/bl_keymap_utils/keymap_from_toolbar.py @@ -199,6 +199,9 @@ def generate(context, space_type, use_fallback_keys=True, use_reset=True): 'WEIGHT_PAINT': "weight_tool", 'TEXTURE_PAINT': "image_tool", 'PAINT_GPENCIL': "gpencil_tool", + 'VERTEX_GPENCIL': "gpencil_vertex_tool", + 'SCULPT_GPENCIL': "gpencil_sculpt_tool", + 'WEIGHT_GPENCIL': "gpencil_weight_tool", }.get(mode, None) if attr is not None: setattr(kmi_hack_brush_select_properties, attr, item.data_block) diff --git a/release/scripts/modules/bl_keymap_utils/keymap_hierarchy.py b/release/scripts/modules/bl_keymap_utils/keymap_hierarchy.py index 35b5f217247..3b829de405a 100644 --- a/release/scripts/modules/bl_keymap_utils/keymap_hierarchy.py +++ b/release/scripts/modules/bl_keymap_utils/keymap_hierarchy.py @@ -194,9 +194,26 @@ _km_hierarchy = [ ('Grease Pencil Stroke Paint (Draw brush)', 'EMPTY', 'WINDOW', []), ('Grease Pencil Stroke Paint (Fill)', 'EMPTY', 'WINDOW', []), ('Grease Pencil Stroke Paint (Erase)', 'EMPTY', 'WINDOW', []), + ('Grease Pencil Stroke Paint (Tint)', 'EMPTY', 'WINDOW', []), ('Grease Pencil Stroke Paint Mode', 'EMPTY', 'WINDOW', []), ('Grease Pencil Stroke Sculpt Mode', 'EMPTY', 'WINDOW', []), + ('Grease Pencil Stroke Sculpt (Smooth)', 'EMPTY', 'WINDOW', []), + ('Grease Pencil Stroke Sculpt (Thickness)', 'EMPTY', 'WINDOW', []), + ('Grease Pencil Stroke Sculpt (Strength)', 'EMPTY', 'WINDOW', []), + ('Grease Pencil Stroke Sculpt (Grab)', 'EMPTY', 'WINDOW', []), + ('Grease Pencil Stroke Sculpt (Push)', 'EMPTY', 'WINDOW', []), + ('Grease Pencil Stroke Sculpt (Twist)', 'EMPTY', 'WINDOW', []), + ('Grease Pencil Stroke Sculpt (Pinch)', 'EMPTY', 'WINDOW', []), + ('Grease Pencil Stroke Sculpt (Randomize)', 'EMPTY', 'WINDOW', []), + ('Grease Pencil Stroke Sculpt (Clone)', 'EMPTY', 'WINDOW', []), ('Grease Pencil Stroke Weight Mode', 'EMPTY', 'WINDOW', []), + ('Grease Pencil Stroke Weight (Draw)', 'EMPTY', 'WINDOW', []), + ('Grease Pencil Stroke Vertex Mode', 'EMPTY', 'WINDOW', []), + ('Grease Pencil Stroke Vertex (Draw)', 'EMPTY', 'WINDOW', []), + ('Grease Pencil Stroke Vertex (Blur)', 'EMPTY', 'WINDOW', []), + ('Grease Pencil Stroke Vertex (Average)', 'EMPTY', 'WINDOW', []), + ('Grease Pencil Stroke Vertex (Smear)', 'EMPTY', 'WINDOW', []), + ('Grease Pencil Stroke Vertex (Replace)', 'EMPTY', 'WINDOW', []), ]), ('Mask Editing', 'EMPTY', 'WINDOW', []), ('Frames', 'EMPTY', 'WINDOW', []), # frame navigation (per region) diff --git a/release/scripts/presets/gpencil_material/fill_only.py b/release/scripts/presets/gpencil_material/fill_only.py index c60811d25bc..57d5dc3b860 100644 --- a/release/scripts/presets/gpencil_material/fill_only.py +++ b/release/scripts/presets/gpencil_material/fill_only.py @@ -7,8 +7,6 @@ gpcolor.stroke_style = 'SOLID' gpcolor.color = (0.0, 0.0, 0.0, 0.0) gpcolor.stroke_image = None gpcolor.pixel_size = 100.0 -gpcolor.use_stroke_pattern = False -gpcolor.use_stroke_texture_mix = False gpcolor.mix_stroke_factor = 0.0 gpcolor.alignment_mode = 'PATH' gpcolor.fill_style = 'SOLID' @@ -18,18 +16,11 @@ gpcolor.gradient_type = 'LINEAR' gpcolor.mix_color = (1.0, 1.0, 1.0, 0.2) gpcolor.mix_factor = 0.0 gpcolor.flip = False -gpcolor.pattern_shift = (0.0, 0.0) -gpcolor.pattern_scale = (1.0, 1.0) -gpcolor.pattern_radius = 0.5 -gpcolor.pattern_angle = 0.0 -gpcolor.pattern_gridsize = 0.1 -gpcolor.use_fill_pattern = False gpcolor.texture_offset = (0.0, 0.0) gpcolor.texture_scale = (1.0, 1.0) gpcolor.texture_angle = 0.0 gpcolor.texture_opacity = 1.0 gpcolor.texture_clamp = False -gpcolor.use_fill_texture_mix = False gpcolor.mix_factor = 0.0 gpcolor.show_stroke = False gpcolor.show_fill = True diff --git a/release/scripts/presets/gpencil_material/stroke_and_fill.py b/release/scripts/presets/gpencil_material/stroke_and_fill.py index ee18eeb0114..eff728a7857 100644 --- a/release/scripts/presets/gpencil_material/stroke_and_fill.py +++ b/release/scripts/presets/gpencil_material/stroke_and_fill.py @@ -7,8 +7,6 @@ gpcolor.stroke_style = 'SOLID' gpcolor.color = (0.0, 0.0, 0.0, 1.0) gpcolor.stroke_image = None gpcolor.pixel_size = 100.0 -gpcolor.use_stroke_pattern = False -gpcolor.use_stroke_texture_mix = False gpcolor.mix_stroke_factor = 0.0 gpcolor.alignment_mode = 'PATH' gpcolor.fill_style = 'SOLID' @@ -18,18 +16,11 @@ gpcolor.gradient_type = 'LINEAR' gpcolor.mix_color = (1.0, 1.0, 1.0, 0.2) gpcolor.mix_factor = 0.0 gpcolor.flip = False -gpcolor.pattern_shift = (0.0, 0.0) -gpcolor.pattern_scale = (1.0, 1.0) -gpcolor.pattern_radius = 0.5 -gpcolor.pattern_angle = 0.0 -gpcolor.pattern_gridsize = 0.1 -gpcolor.use_fill_pattern = False gpcolor.texture_offset = (0.0, 0.0) gpcolor.texture_scale = (1.0, 1.0) gpcolor.texture_angle = 0.0 gpcolor.texture_opacity = 1.0 gpcolor.texture_clamp = False -gpcolor.use_fill_texture_mix = False gpcolor.mix_factor = 0.0 gpcolor.show_stroke = True gpcolor.show_fill = True diff --git a/release/scripts/presets/gpencil_material/stroke_only.py b/release/scripts/presets/gpencil_material/stroke_only.py index 3ca05c6a073..1724a62bffc 100644 --- a/release/scripts/presets/gpencil_material/stroke_only.py +++ b/release/scripts/presets/gpencil_material/stroke_only.py @@ -7,8 +7,6 @@ gpcolor.stroke_style = 'SOLID' gpcolor.color = (0.0, 0.0, 0.0, 1.0) gpcolor.stroke_image = None gpcolor.pixel_size = 100.0 -gpcolor.use_stroke_pattern = False -gpcolor.use_stroke_texture_mix = False gpcolor.mix_stroke_factor = 0.0 gpcolor.alignment_mode = 'PATH' gpcolor.fill_style = 'SOLID' @@ -18,18 +16,11 @@ gpcolor.gradient_type = 'LINEAR' gpcolor.mix_color = (1.0, 1.0, 1.0, 0.2) gpcolor.mix_factor = 0.0 gpcolor.flip = False -gpcolor.pattern_shift = (0.0, 0.0) -gpcolor.pattern_scale = (1.0, 1.0) -gpcolor.pattern_radius = 0.5 -gpcolor.pattern_angle = 0.0 -gpcolor.pattern_gridsize = 0.1 -gpcolor.use_fill_pattern = False gpcolor.texture_offset = (0.0, 0.0) gpcolor.texture_scale = (1.0, 1.0) gpcolor.texture_angle = 0.0 gpcolor.texture_opacity = 1.0 gpcolor.texture_clamp = False -gpcolor.use_fill_texture_mix = False gpcolor.mix_factor = 0.0 gpcolor.show_stroke = True gpcolor.show_fill = False diff --git a/release/scripts/presets/keyconfig/keymap_data/blender_default.py b/release/scripts/presets/keyconfig/keymap_data/blender_default.py index 5aff2a75e03..bf1ff0604ad 100644 --- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py +++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py @@ -3168,6 +3168,10 @@ def km_grease_pencil_stroke_edit_mode(params): {"properties": [("mode", 1)]}), ("gpencil.selectmode_toggle", {"type": 'THREE', "value": 'PRESS'}, {"properties": [("mode", 2)]}), + # Active layer + op_menu("GPENCIL_MT_layer_active", {"type": 'Y', "value": 'PRESS'}), + # Keyframe menu + op_menu("VIEW3D_MT_gpencil_animation", {"type": 'I', "value": 'PRESS'}), # Context menu *_template_items_context_menu("VIEW3D_MT_gpencil_edit_context_menu", params.context_menu_event), ]) @@ -3211,6 +3215,10 @@ def km_grease_pencil_stroke_paint_mode(params): {"properties": [("unselected", False)]}), ("gpencil.hide", {"type": 'H', "value": 'PRESS', "shift": True}, {"properties": [("unselected", True)]}), + # Active layer + op_menu("GPENCIL_MT_layer_active", {"type": 'Y', "value": 'PRESS'}), + # Keyframe menu + op_menu("VIEW3D_MT_gpencil_animation", {"type": 'I', "value": 'PRESS'}), # Draw context menu *_template_items_context_panel("VIEW3D_PT_gpencil_draw_context_menu", params.context_menu_event), ]) @@ -3322,6 +3330,25 @@ def km_grease_pencil_stroke_paint_fill(params): return keymap +def km_grease_pencil_stroke_paint_tint(params): + items = [] + keymap = ( + "Grease Pencil Stroke Paint (Tint)", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ + # Tint + ("gpencil.vertex_paint", {"type": 'LEFTMOUSE', "value": 'PRESS'}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.vertex_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True}, + {"properties": [("wait_for_input", False)]}), + ]) + + return keymap + + def km_grease_pencil_stroke_sculpt_mode(params): items = [] keymap = ( @@ -3336,14 +3363,22 @@ def km_grease_pencil_stroke_sculpt_mode(params): # Brush strength ("wm.radial_control", {"type": 'F', "value": 'PRESS', "shift": True}, - {"properties": [("data_path_primary", 'tool_settings.gpencil_sculpt.brush.strength')]}), + {"properties": [("data_path_primary", 'tool_settings.gpencil_sculpt_paint.brush.strength')]}), # Brush size ("wm.radial_control", {"type": 'F', "value": 'PRESS'}, - {"properties": [("data_path_primary", 'tool_settings.gpencil_sculpt.brush.size')]}), + {"properties": [("data_path_primary", 'tool_settings.gpencil_sculpt_paint.brush.size')]}), # Copy ("gpencil.copy", {"type": 'C', "value": 'PRESS', "ctrl": True}, None), # Display *_grease_pencil_display(), + # Keyframe menu + ("gpencil.blank_frame_add", {"type": 'I', "value": 'PRESS', "shift": True}, None), + ("gpencil.active_frames_delete_all", {"type": 'X', "value": 'PRESS', "shift": True}, None), + ("gpencil.active_frames_delete_all", {"type": 'DEL', "value": 'PRESS', "shift": True}, None), + # Active layer + op_menu("GPENCIL_MT_layer_active", {"type": 'Y', "value": 'PRESS'}), + # Keyframe menu + op_menu("VIEW3D_MT_gpencil_animation", {"type": 'I', "value": 'PRESS'}), # Context menu *_template_items_context_panel("VIEW3D_PT_gpencil_sculpt_context_menu", params.context_menu_event), ]) @@ -3351,28 +3386,385 @@ def km_grease_pencil_stroke_sculpt_mode(params): return keymap -def km_grease_pencil_stroke_weight_mode(_params): +def km_grease_pencil_stroke_sculpt_smooth(_params): items = [] keymap = ( - "Grease Pencil Stroke Weight Mode", + "Grease Pencil Stroke Sculpt (Smooth)", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS'}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True}, + {"properties": [("wait_for_input", False)]}), + ]) + + return keymap + + +def km_grease_pencil_stroke_sculpt_thickness(_params): + items = [] + keymap = ( + "Grease Pencil Stroke Sculpt (Thickness)", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS'}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True}, + {"properties": [("wait_for_input", False)]}), + ]) + + return keymap + + +def km_grease_pencil_stroke_sculpt_strength(_params): + items = [] + keymap = ( + "Grease Pencil Stroke Sculpt (Strength)", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS'}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True}, + {"properties": [("wait_for_input", False)]}), + ]) + + return keymap + + +def km_grease_pencil_stroke_sculpt_grab(_params): + items = [] + keymap = ( + "Grease Pencil Stroke Sculpt (Grab)", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS'}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True}, + {"properties": [("wait_for_input", False)]}), + ]) + + return keymap + + +def km_grease_pencil_stroke_sculpt_push(_params): + items = [] + keymap = ( + "Grease Pencil Stroke Sculpt (Push)", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS'}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True}, + {"properties": [("wait_for_input", False)]}), + ]) + + return keymap + + +def km_grease_pencil_stroke_sculpt_twist(_params): + items = [] + keymap = ( + "Grease Pencil Stroke Sculpt (Twist)", {"space_type": 'EMPTY', "region_type": 'WINDOW'}, {"items": items}, ) items.extend([ - # Painting + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS'}, + {"properties": [("wait_for_input", False)]}), ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True}, {"properties": [("wait_for_input", False)]}), ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True}, {"properties": [("wait_for_input", False)]}), + ]) + + return keymap + + +def km_grease_pencil_stroke_sculpt_pinch(_params): + items = [] + keymap = ( + "Grease Pencil Stroke Sculpt (Pinch)", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS'}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True}, + {"properties": [("wait_for_input", False)]}), + ]) + + return keymap + + +def km_grease_pencil_stroke_sculpt_randomize(_params): + items = [] + keymap = ( + "Grease Pencil Stroke Sculpt (Randomize)", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS'}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True}, + {"properties": [("wait_for_input", False)]}), + ]) + + return keymap + + +def km_grease_pencil_stroke_sculpt_clone(_params): + items = [] + keymap = ( + "Grease Pencil Stroke Sculpt (Clone)", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS'}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True}, + {"properties": [("wait_for_input", False)]}), + ]) + + return keymap + + +def km_grease_pencil_stroke_weight_mode(params): + items = [] + keymap = ( + "Grease Pencil Stroke Weight Mode", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ # Brush strength ("wm.radial_control", {"type": 'F', "value": 'PRESS', "shift": True}, - {"properties": [("data_path_primary", 'tool_settings.gpencil_sculpt.weight_brush.strength')]}), - # Brush sze + {"properties": [("data_path_primary", 'tool_settings.gpencil_weight_paint.brush.strength')]}), + # Brush size ("wm.radial_control", {"type": 'F', "value": 'PRESS'}, - {"properties": [("data_path_primary", 'tool_settings.gpencil_sculpt.weight_brush.size')]}), + {"properties": [("data_path_primary", 'tool_settings.gpencil_weight_paint.brush.size')]}), # Display *_grease_pencil_display(), + # Keyframe menu + ("gpencil.blank_frame_add", {"type": 'I', "value": 'PRESS', "shift": True}, None), + ("gpencil.active_frames_delete_all", {"type": 'X', "value": 'PRESS', "shift": True}, None), + ("gpencil.active_frames_delete_all", {"type": 'DEL', "value": 'PRESS', "shift": True}, None), + # Active layer + op_menu("GPENCIL_MT_layer_active", {"type": 'Y', "value": 'PRESS'}), + # Keyframe menu + op_menu("VIEW3D_MT_gpencil_animation", {"type": 'I', "value": 'PRESS'}), + # Context menu + *_template_items_context_panel("VIEW3D_PT_gpencil_weight_context_menu", params.context_menu_event), + ]) + + return keymap + + +def km_grease_pencil_stroke_weight_draw(_params): + items = [] + keymap = ( + "Grease Pencil Stroke Weight (Draw)", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ + # Draw + ("gpencil.weight_paint", {"type": 'LEFTMOUSE', "value": 'PRESS'}, + {"properties": [("wait_for_input", False)]}), + ]) + + return keymap + + +def km_grease_pencil_stroke_vertex_mode(params): + items = [] + keymap = ( + "Grease Pencil Stroke Vertex Mode", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ + # Selection + *_grease_pencil_selection(params), + # Brush strength + ("wm.radial_control", {"type": 'F', "value": 'PRESS', "shift": True}, + {"properties": [("data_path_primary", 'tool_settings.gpencil_vertex_paint.brush.gpencil_settings.pen_strength')]}), + # Brush size + ("wm.radial_control", {"type": 'F', "value": 'PRESS'}, + {"properties": [("data_path_primary", 'tool_settings.gpencil_vertex_paint.brush.size')]}), + # Display + *_grease_pencil_display(), + # Tools + op_tool("builtin_brush.Draw", {"type": 'D', "value": 'PRESS'}), + op_tool("builtin_brush.Blur", {"type": 'F', "value": 'PRESS'}), + op_tool("builtin_brush.Average", {"type": 'E', "value": 'PRESS'}), + op_tool("builtin.brush.Smear", {"type": 'K', "value": 'PRESS'}), + # Keyframe menu + ("gpencil.blank_frame_add", {"type": 'I', "value": 'PRESS', "shift": True}, None), + ("gpencil.active_frames_delete_all", {"type": 'X', "value": 'PRESS', "shift": True}, None), + ("gpencil.active_frames_delete_all", {"type": 'DEL', "value": 'PRESS', "shift": True}, None), + # Active layer + op_menu("GPENCIL_MT_layer_active", {"type": 'Y', "value": 'PRESS'}), + # Keyframe menu + op_menu("VIEW3D_MT_gpencil_animation", {"type": 'I', "value": 'PRESS'}), + # Vertex Paint context menu + op_panel("VIEW3D_PT_gpencil_vertex_context_menu", params.context_menu_event), + ]) + + return keymap + + +def km_grease_pencil_stroke_vertex_draw(params): + items = [] + keymap = ( + "Grease Pencil Stroke Vertex (Draw)", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ + # Tint + ("gpencil.vertex_paint", {"type": 'LEFTMOUSE', "value": 'PRESS'}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.vertex_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True}, + {"properties": [("wait_for_input", False)]}), + # Brush strength + ("wm.radial_control", {"type": 'F', "value": 'PRESS', "shift": True}, + {"properties": [("data_path_primary", 'tool_settings.gpencil_vertex_paint.brush.gpencil_settings.pen_strength')]}), + # Brush size + ("wm.radial_control", {"type": 'F', "value": 'PRESS'}, + {"properties": [("data_path_primary", 'tool_settings.gpencil_vertex_paint.brush.size')]}), + ]) + + return keymap + + +def km_grease_pencil_stroke_vertex_blur(params): + items = [] + keymap = ( + "Grease Pencil Stroke Vertex (Blur)", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ + # Tint + ("gpencil.vertex_paint", {"type": 'LEFTMOUSE', "value": 'PRESS'}, + {"properties": [("wait_for_input", False)]}), + # Brush strength + ("wm.radial_control", {"type": 'F', "value": 'PRESS', "shift": True}, + {"properties": [("data_path_primary", 'tool_settings.gpencil_vertex_paint.brush.gpencil_settings.pen_strength')]}), + # Brush size + ("wm.radial_control", {"type": 'F', "value": 'PRESS'}, + {"properties": [("data_path_primary", 'tool_settings.gpencil_vertex_paint.brush.size')]}), + ]) + + return keymap + + +def km_grease_pencil_stroke_vertex_average(params): + items = [] + keymap = ( + "Grease Pencil Stroke Vertex (Average)", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ + # Tint + ("gpencil.vertex_paint", {"type": 'LEFTMOUSE', "value": 'PRESS'}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.vertex_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True}, + {"properties": [("wait_for_input", False)]}), + # Brush strength + ("wm.radial_control", {"type": 'F', "value": 'PRESS', "shift": True}, + {"properties": [("data_path_primary", 'tool_settings.gpencil_vertex_paint.brush.gpencil_settings.pen_strength')]}), + # Brush size + ("wm.radial_control", {"type": 'F', "value": 'PRESS'}, + {"properties": [("data_path_primary", 'tool_settings.gpencil_vertex_paint.brush.size')]}), + ]) + + return keymap + + +def km_grease_pencil_stroke_vertex_smear(params): + items = [] + keymap = ( + "Grease Pencil Stroke Vertex (Smear)", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ + # Tint + ("gpencil.vertex_paint", {"type": 'LEFTMOUSE', "value": 'PRESS'}, + {"properties": [("wait_for_input", False)]}), + # Brush strength + ("wm.radial_control", {"type": 'F', "value": 'PRESS', "shift": True}, + {"properties": [("data_path_primary", 'tool_settings.gpencil_vertex_paint.brush.gpencil_settings.pen_strength')]}), + # Brush size + ("wm.radial_control", {"type": 'F', "value": 'PRESS'}, + {"properties": [("data_path_primary", 'tool_settings.gpencil_vertex_paint.brush.size')]}), + ]) + + return keymap + + +def km_grease_pencil_stroke_vertex_replace(params): + items = [] + keymap = ( + "Grease Pencil Stroke Vertex (Replace)", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ + # Tint + ("gpencil.vertex_paint", {"type": 'LEFTMOUSE', "value": 'PRESS'}, + {"properties": [("wait_for_input", False)]}), + # Brush size + ("wm.radial_control", {"type": 'F', "value": 'PRESS'}, + {"properties": [("data_path_primary", 'tool_settings.gpencil_vertex_paint.brush.size')]}), ]) return keymap @@ -6053,18 +6445,13 @@ def km_3d_view_tool_edit_gpencil_to_sphere(params): ) -# Also used for weight paint. -def km_3d_view_tool_sculpt_gpencil_paint(_params): +def km_3d_view_tool_edit_gpencil_transform_fill(params): return ( - "3D View Tool: Sculpt Gpencil, Paint", + "3D View Tool: Edit Gpencil, Transform Fill", {"space_type": 'VIEW_3D', "region_type": 'WINDOW'}, {"items": [ - ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS'}, - {"properties": [("wait_for_input", False)]}), - ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True}, - {"properties": [("wait_for_input", False)]}), - ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True}, - {"properties": [("wait_for_input", False)]}), + ("gpencil.transform_fill", {"type": params.tool_tweak, "value": 'ANY'}, + {"properties": [("release_confirm", True)]}), ]}, ) @@ -6201,8 +6588,25 @@ def generate_keymaps(params=None): km_grease_pencil_stroke_paint_draw_brush(params), km_grease_pencil_stroke_paint_erase(params), km_grease_pencil_stroke_paint_fill(params), + km_grease_pencil_stroke_paint_tint(params), km_grease_pencil_stroke_sculpt_mode(params), + km_grease_pencil_stroke_sculpt_smooth(params), + km_grease_pencil_stroke_sculpt_thickness(params), + km_grease_pencil_stroke_sculpt_strength(params), + km_grease_pencil_stroke_sculpt_grab(params), + km_grease_pencil_stroke_sculpt_push(params), + km_grease_pencil_stroke_sculpt_twist(params), + km_grease_pencil_stroke_sculpt_pinch(params), + km_grease_pencil_stroke_sculpt_randomize(params), + km_grease_pencil_stroke_sculpt_clone(params), km_grease_pencil_stroke_weight_mode(params), + km_grease_pencil_stroke_weight_draw(params), + km_grease_pencil_stroke_vertex_mode(params), + km_grease_pencil_stroke_vertex_draw(params), + km_grease_pencil_stroke_vertex_blur(params), + km_grease_pencil_stroke_vertex_average(params), + km_grease_pencil_stroke_vertex_smear(params), + km_grease_pencil_stroke_vertex_replace(params), km_face_mask(params), km_weight_paint_vertex_selection(params), km_pose(params), @@ -6345,7 +6749,7 @@ def generate_keymaps(params=None): km_3d_view_tool_edit_gpencil_bend(params), km_3d_view_tool_edit_gpencil_shear(params), km_3d_view_tool_edit_gpencil_to_sphere(params), - km_3d_view_tool_sculpt_gpencil_paint(params), + km_3d_view_tool_edit_gpencil_transform_fill(params), km_3d_view_tool_sculpt_gpencil_select(params), km_3d_view_tool_sculpt_gpencil_select_box(params), km_3d_view_tool_sculpt_gpencil_select_circle(params), diff --git a/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py b/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py index b0b7c542df3..18acbb54b34 100644 --- a/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py +++ b/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py @@ -2364,6 +2364,10 @@ def km_grease_pencil_stroke_paint_mode(params): op_tool_cycle("builtin_brush.Erase", {"type": 'E', "value": 'PRESS'}), op_tool_cycle("builtin.cutter", {"type": 'K', "value": 'PRESS'}), op_tool_cycle("builtin.cursor", {"type": 'C', "value": 'PRESS'}), + # Active layer + op_menu("GPENCIL_MT_layer_active", {"type": 'M', "value": 'PRESS'}), + # Keyframe menu + op_menu("VIEW3D_MT_gpencil_animation", {"type": 'I', "value": 'PRESS'}), ]) return keymap @@ -2470,6 +2474,25 @@ def km_grease_pencil_stroke_paint_fill(params): return keymap +def km_grease_pencil_stroke_paint_tint(params): + items = [] + keymap = ( + "Grease Pencil Stroke Paint (Tint)", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ + # Tint + ("gpencil.vertex_paint", {"type": 'LEFTMOUSE', "value": 'PRESS'}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.vertex_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True}, + {"properties": [("wait_for_input", False)]}), + ]) + + return keymap + + def km_grease_pencil_stroke_sculpt_mode(params): items = [] keymap = ( @@ -2481,30 +2504,246 @@ def km_grease_pencil_stroke_sculpt_mode(params): items.extend([ # Selection *_grease_pencil_selection(params), - # Painting + + # Brush strength + ("wm.radial_control", {"type": 'F', "value": 'PRESS', "shift": True}, + {"properties": [("data_path_primary", 'tool_settings.gpencil_sculpt_paint.brush.strength')]}), + # Brush size + ("wm.radial_control", {"type": 'F', "value": 'PRESS'}, + {"properties": [("data_path_primary", 'tool_settings.gpencil_sculpt_paint.brush.size')]}), + # Copy + ("gpencil.copy", {"type": 'C', "value": 'PRESS', "ctrl": True}, None), + # Display + *_grease_pencil_display(), + # Context menu + op_panel("VIEW3D_PT_gpencil_sculpt_context_menu", params.context_menu_event), + ]) + + return keymap + + +def km_grease_pencil_stroke_sculpt_smooth(_params): + items = [] + keymap = ( + "Grease Pencil Stroke Sculpt (Smooth)", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS'}, {"properties": [("wait_for_input", False)]}), ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True}, {"properties": [("wait_for_input", False)]}), ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True}, {"properties": [("wait_for_input", False)]}), + ]) + + return keymap + + +def km_grease_pencil_stroke_sculpt_thickness(_params): + items = [] + keymap = ( + "Grease Pencil Stroke Sculpt (Thickness)", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS'}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True}, + {"properties": [("wait_for_input", False)]}), + ]) + + return keymap + + +def km_grease_pencil_stroke_sculpt_strength(_params): + items = [] + keymap = ( + "Grease Pencil Stroke Sculpt (Strength)", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS'}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True}, + {"properties": [("wait_for_input", False)]}), + ]) + + return keymap + + +def km_grease_pencil_stroke_sculpt_grab(_params): + items = [] + keymap = ( + "Grease Pencil Stroke Sculpt (Grab)", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS'}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True}, + {"properties": [("wait_for_input", False)]}), + ]) + + return keymap + + +def km_grease_pencil_stroke_sculpt_push(_params): + items = [] + keymap = ( + "Grease Pencil Stroke Sculpt (Push)", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS'}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True}, + {"properties": [("wait_for_input", False)]}), + ]) + + return keymap + + +def km_grease_pencil_stroke_sculpt_twist(_params): + items = [] + keymap = ( + "Grease Pencil Stroke Sculpt (Twist)", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS'}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True}, + {"properties": [("wait_for_input", False)]}), + ]) + + return keymap + + +def km_grease_pencil_stroke_sculpt_pinch(_params): + items = [] + keymap = ( + "Grease Pencil Stroke Sculpt (Pinch)", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS'}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True}, + {"properties": [("wait_for_input", False)]}), + ]) + + return keymap + + +def km_grease_pencil_stroke_sculpt_randomize(_params): + items = [] + keymap = ( + "Grease Pencil Stroke Sculpt (Randomize)", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS'}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True}, + {"properties": [("wait_for_input", False)]}), + ]) + + return keymap + + +def km_grease_pencil_stroke_sculpt_clone(_params): + items = [] + keymap = ( + "Grease Pencil Stroke Sculpt (Clone)", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS'}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True}, + {"properties": [("wait_for_input", False)]}), + ]) + + return keymap + + +def km_grease_pencil_stroke_weight_mode(params): + items = [] + keymap = ( + "Grease Pencil Stroke Weight Mode", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ # Brush strength - ("wm.radial_control", {"type": 'U', "value": 'PRESS'}, - {"properties": [("data_path_primary", 'tool_settings.gpencil_sculpt.brush.strength')]}), + ("wm.radial_control", {"type": 'F', "value": 'PRESS', "shift": True}, + {"properties": [("data_path_primary", 'tool_settings.gpencil_weight_paint.brush.strength')]}), # Brush size ("wm.radial_control", {"type": 'S', "value": 'PRESS'}, {"properties": [("data_path_primary", 'tool_settings.gpencil_sculpt.brush.size')]}), # Context menu - *_template_items_context_panel("VIEW3D_PT_gpencil_sculpt_context_menu", {"type": 'RIGHTMOUSE', "value": 'PRESS'}), + *_template_items_context_panel("VIEW3D_PT_gpencil_weight_context_menu", {"type": 'RIGHTMOUSE', "value": 'PRESS'}), ]) return keymap -def km_grease_pencil_stroke_weight_mode(params): +def km_grease_pencil_stroke_weight_draw(_params): items = [] keymap = ( - "Grease Pencil Stroke Weight Mode", + "Grease Pencil Stroke Weight (Draw)", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ + ("gpencil.weight_paint", {"type": 'LEFTMOUSE', "value": 'PRESS'}, + {"properties": [("wait_for_input", False)]}), + ]) + + return keymap + + +def km_grease_pencil_stroke_vertex_mode(params): + items = [] + keymap = ( + "Grease Pencil Stroke Vertex Mode", {"space_type": 'EMPTY', "region_type": 'WINDOW'}, {"items": items}, ) @@ -2512,22 +2751,141 @@ def km_grease_pencil_stroke_weight_mode(params): items.extend([ # Selection *_grease_pencil_selection(params), - # Painting - ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True}, + # Brush strength + ("wm.radial_control", {"type": 'F', "value": 'PRESS', "shift": True}, + {"properties": [("data_path_primary", 'tool_settings.gpencil_vertex_paint.brush.gpencil_settings.pen_strength')]}), + # Brush size + ("wm.radial_control", {"type": 'F', "value": 'PRESS'}, + {"properties": [("data_path_primary", 'tool_settings.gpencil_vertex_paint.brush.size')]}), + # Display + *_grease_pencil_display(), + # Tools + op_tool("builtin_brush.Draw", {"type": 'D', "value": 'PRESS'}), + op_tool("builtin_brush.Blur", {"type": 'F', "value": 'PRESS'}), + op_tool("builtin_brush.Average", {"type": 'E', "value": 'PRESS'}), + op_tool("builtin.brush.Smear", {"type": 'K', "value": 'PRESS'}), + op_tool("builtin.brush.Replace", {"type": 'R', "value": 'PRESS'}), + # Vertex Paint context menu + op_panel("VIEW3D_PT_gpencil_vertex_context_menu", params.context_menu_event), + ]) + + return keymap + +def km_grease_pencil_stroke_vertex_draw(params): + items = [] + keymap = ( + "Grease Pencil Stroke Vertex (Draw)", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ + # Tint + ("gpencil.vertex_paint", {"type": 'LEFTMOUSE', "value": 'PRESS'}, {"properties": [("wait_for_input", False)]}), - ("gpencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True}, + ("gpencil.vertex_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True}, + {"properties": [("wait_for_input", False)]}), + # Brush strength + ("wm.radial_control", {"type": 'F', "value": 'PRESS', "shift": True}, + {"properties": [("data_path_primary", 'tool_settings.gpencil_vertex_paint.brush.gpencil_settings.pen_strength')]}), + # Brush size + ("wm.radial_control", {"type": 'F', "value": 'PRESS'}, + {"properties": [("data_path_primary", 'tool_settings.gpencil_vertex_paint.brush.size')]}), + ]) + + return keymap + + +def km_grease_pencil_stroke_vertex_blur(params): + items = [] + keymap = ( + "Grease Pencil Stroke Vertex (Blur)", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ + # Tint + ("gpencil.vertex_paint", {"type": 'LEFTMOUSE', "value": 'PRESS'}, + {"properties": [("wait_for_input", False)]}), + # Brush strength + ("wm.radial_control", {"type": 'F', "value": 'PRESS', "shift": True}, + {"properties": [("data_path_primary", 'tool_settings.gpencil_vertex_paint.brush.gpencil_settings.pen_strength')]}), + # Brush size + ("wm.radial_control", {"type": 'F', "value": 'PRESS'}, + {"properties": [("data_path_primary", 'tool_settings.gpencil_vertex_paint.brush.size')]}), + ]) + + return keymap + + +def km_grease_pencil_stroke_vertex_average(params): + items = [] + keymap = ( + "Grease Pencil Stroke Vertex (Average)", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ + # Tint + ("gpencil.vertex_paint", {"type": 'LEFTMOUSE', "value": 'PRESS'}, + {"properties": [("wait_for_input", False)]}), + ("gpencil.vertex_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True}, + {"properties": [("wait_for_input", False)]}), + # Brush strength + ("wm.radial_control", {"type": 'F', "value": 'PRESS', "shift": True}, + {"properties": [("data_path_primary", 'tool_settings.gpencil_vertex_paint.brush.gpencil_settings.pen_strength')]}), + # Brush size + ("wm.radial_control", {"type": 'F', "value": 'PRESS'}, + {"properties": [("data_path_primary", 'tool_settings.gpencil_vertex_paint.brush.size')]}), + ]) + + return keymap + + +def km_grease_pencil_stroke_vertex_smear(params): + items = [] + keymap = ( + "Grease Pencil Stroke Vertex (Smear)", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ + # Tint + ("gpencil.vertex_paint", {"type": 'LEFTMOUSE', "value": 'PRESS'}, {"properties": [("wait_for_input", False)]}), # Brush strength ("wm.radial_control", {"type": 'U', "value": 'PRESS', "shift": True}, - {"properties": [("data_path_primary", 'tool_settings.gpencil_sculpt.weight_brush.strength')]}), - # Brush size. + {"properties": [("data_path_primary", 'tool_settings.gpencil_vertex_paint.brush.gpencil_settings.pen_strength')]}), + # Brush size ("wm.radial_control", {"type": 'S', "value": 'PRESS'}, - {"properties": [("data_path_primary", 'tool_settings.gpencil_sculpt.weight_brush.size')]}), + {"properties": [("data_path_primary", 'tool_settings.gpencil_vertex_paint.brush.size')]}), ]) return keymap +def km_grease_pencil_stroke_vertex_replace(params): + items = [] + keymap = ( + "Grease Pencil Stroke Vertex (Replace)", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ + # Tint + ("gpencil.vertex_paint", {"type": 'LEFTMOUSE', "value": 'PRESS'}, + {"properties": [("wait_for_input", False)]}), + # Brush size + ("wm.radial_control", {"type": 'F', "value": 'PRESS'}, + {"properties": [("data_path_primary", 'tool_settings.gpencil_vertex_paint.brush.size')]}), + ]) + + return keymap + def km_face_mask(params): items = [] keymap = ( @@ -3679,8 +4037,25 @@ def generate_keymaps_impl(params=None): km_grease_pencil_stroke_paint_draw_brush(params), km_grease_pencil_stroke_paint_erase(params), km_grease_pencil_stroke_paint_fill(params), + km_grease_pencil_stroke_paint_tint(params), km_grease_pencil_stroke_sculpt_mode(params), + km_grease_pencil_stroke_sculpt_smooth(params), + km_grease_pencil_stroke_sculpt_thickness(params), + km_grease_pencil_stroke_sculpt_strength(params), + km_grease_pencil_stroke_sculpt_grab(params), + km_grease_pencil_stroke_sculpt_push(params), + km_grease_pencil_stroke_sculpt_twist(params), + km_grease_pencil_stroke_sculpt_pinch(params), + km_grease_pencil_stroke_sculpt_randomize(params), + km_grease_pencil_stroke_sculpt_clone(params), km_grease_pencil_stroke_weight_mode(params), + km_grease_pencil_stroke_weight_draw(params), + km_grease_pencil_stroke_vertex_mode(params), + km_grease_pencil_stroke_vertex_draw(params), + km_grease_pencil_stroke_vertex_blur(params), + km_grease_pencil_stroke_vertex_average(params), + km_grease_pencil_stroke_vertex_smear(params), + km_grease_pencil_stroke_vertex_replace(params), km_face_mask(params), km_weight_paint_vertex_selection(params), km_pose(params), diff --git a/release/scripts/startup/bl_operators/presets.py b/release/scripts/startup/bl_operators/presets.py index b94edc23f4e..c83d0b9f4d8 100644 --- a/release/scripts/startup/bl_operators/presets.py +++ b/release/scripts/startup/bl_operators/presets.py @@ -642,10 +642,7 @@ class AddPresetGpencilBrush(AddPresetBase, Operator): "brush.smooth_stroke_factor", "settings.pen_smooth_factor", "settings.pen_smooth_steps", - "settings.pen_thick_smooth_factor", - "settings.pen_thick_smooth_steps", "settings.pen_subdivision_steps", - "settings.random_subdiv", "settings.use_settings_random", "settings.random_pressure", "settings.random_strength", @@ -675,8 +672,6 @@ class AddPresetGpencilMaterial(AddPresetBase, Operator): "gpcolor.color", "gpcolor.stroke_image", "gpcolor.pixel_size", - "gpcolor.use_stroke_pattern", - "gpcolor.use_stroke_texture_mix", "gpcolor.mix_stroke_factor", "gpcolor.alignment_mode", "gpcolor.fill_style", @@ -686,18 +681,11 @@ class AddPresetGpencilMaterial(AddPresetBase, Operator): "gpcolor.mix_color", "gpcolor.mix_factor", "gpcolor.flip", - "gpcolor.pattern_shift", - "gpcolor.pattern_scale", - "gpcolor.pattern_radius", - "gpcolor.pattern_angle", - "gpcolor.pattern_gridsize", - "gpcolor.use_fill_pattern", "gpcolor.texture_offset", "gpcolor.texture_scale", "gpcolor.texture_angle", "gpcolor.texture_opacity", "gpcolor.texture_clamp", - "gpcolor.use_fill_texture_mix", "gpcolor.mix_factor", "gpcolor.show_stroke", "gpcolor.show_fill", diff --git a/release/scripts/startup/bl_ui/properties_data_gpencil.py b/release/scripts/startup/bl_ui/properties_data_gpencil.py index 883673ffd7a..4ed5264549f 100644 --- a/release/scripts/startup/bl_ui/properties_data_gpencil.py +++ b/release/scripts/startup/bl_ui/properties_data_gpencil.py @@ -22,6 +22,7 @@ from bpy.types import Menu, Panel, UIList from rna_prop_ui import PropertyPanel from bl_ui.properties_grease_pencil_common import ( + GreasePencilLayerMasksPanel, GreasePencilLayerAdjustmentsPanel, GreasePencilLayerRelationsPanel, GreasePencilLayerDisplayPanel, @@ -116,7 +117,7 @@ class DATA_PT_gpencil_layers(DataButtonsPanel, Panel): def draw(self, context): layout = self.layout - #layout.use_property_split = True + # layout.use_property_split = True layout.use_property_decorate = False gpd = context.gpencil @@ -166,7 +167,6 @@ class DATA_PT_gpencil_layers(DataButtonsPanel, Panel): col = layout.column(align=True) if gpl: - layout = self.layout layout.use_property_split = True layout.use_property_decorate = True @@ -178,6 +178,15 @@ class DATA_PT_gpencil_layers(DataButtonsPanel, Panel): col = layout.row(align=True) col.prop(gpl, "opacity", text="Opacity", slider=True) + col = layout.row(align=True) + col.prop(gpl, "use_lights") + + +class DATA_PT_gpencil_layer_masks(LayerDataButtonsPanel, GreasePencilLayerMasksPanel, Panel): + bl_label = "Masks" + bl_parent_id = 'DATA_PT_gpencil_layers' + bl_options = {'DEFAULT_CLOSED'} + class DATA_PT_gpencil_layer_adjustments(LayerDataButtonsPanel, GreasePencilLayerAdjustmentsPanel, Panel): bl_label = "Adjustments" @@ -264,7 +273,7 @@ class DATA_PT_gpencil_onion_skinning_display(DataButtonsPanel, Panel): col.prop(gpd, "use_onion_fade", text="Fade") sub = layout.column() sub.active = gpd.onion_mode in {'RELATIVE', 'SELECTED'} - sub.prop(gpd, "use_onion_loop", text="Loop") + sub.prop(gpd, "use_onion_loop", text="Show Start Frame") class GPENCIL_MT_gpencil_vertex_group(Menu): @@ -364,9 +373,6 @@ class DATA_PT_gpencil_strokes(DataButtonsPanel, Panel): sub.active = gpd.stroke_thickness_space == 'WORLDSPACE' sub.prop(gpd, "pixel_factor", text="Thickness Scale") - layout.prop(gpd, "use_force_fill_recalc", text="Force Fill Update") - layout.prop(gpd, "use_adaptive_uv", text="Adaptive UVs") - class DATA_PT_gpencil_display(DataButtonsPanel, Panel): bl_label = "Viewport Display" @@ -381,8 +387,6 @@ class DATA_PT_gpencil_display(DataButtonsPanel, Panel): gpl = gpd.layers.active layout.prop(gpd, "edit_line_color", text="Edit Line Color") - if gpl: - layout.prop(gpd, "show_stroke_direction", text="Show Stroke Directions") class DATA_PT_gpencil_canvas(DataButtonsPanel, Panel): @@ -411,6 +415,7 @@ class DATA_PT_custom_props_gpencil(DataButtonsPanel, PropertyPanel, Panel): _context_path = "object.data" _property_type = bpy.types.GreasePencil + ############################### @@ -420,6 +425,7 @@ classes = ( DATA_PT_gpencil_onion_skinning, DATA_PT_gpencil_onion_skinning_custom_colors, DATA_PT_gpencil_onion_skinning_display, + DATA_PT_gpencil_layer_masks, DATA_PT_gpencil_layer_adjustments, DATA_PT_gpencil_layer_relations, DATA_PT_gpencil_layer_display, @@ -437,5 +443,6 @@ classes = ( if __name__ == "__main__": # only for live edit. from bpy.utils import register_class + for cls in classes: register_class(cls) diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py index 603c873c290..9070aa5faee 100644 --- a/release/scripts/startup/bl_ui/properties_data_modifier.py +++ b/release/scripts/startup/bl_ui/properties_data_modifier.py @@ -1746,132 +1746,102 @@ class DATA_PT_gpencil_modifiers(ModifierButtonsPanel, Panel): # ...to avoid lengthy if statements # so each type must have a function here. - def GP_NOISE(self, layout, ob, md): + def gpencil_masking(self, layout, ob, md, use_vertex, use_curve=False): gpd = ob.data - split = layout.split() - - col = split.column() - row = col.row(align=True) - row.prop(md, "factor") - row.prop(md, "random", text="", icon='TIME', toggle=True) - row = col.row() - row.enabled = md.random - row.prop(md, "step") - row = col.row() - row.enabled = md.random - row.prop(md, "seed") - col.prop(md, "full_stroke") - col.prop(md, "move_extreme") - - row = layout.row(align=True) - row.label(text="Affect:") - row = layout.row(align=True) - row.prop(md, "use_edit_position", text="Position", icon='MESH_DATA', toggle=True) - row.prop(md, "use_edit_strength", text="Strength", icon='COLOR', toggle=True) - row.prop(md, "use_edit_thickness", text="Thickness", icon='LINE_DATA', toggle=True) - row.prop(md, "use_edit_uv", text="UV", icon='MOD_UVPROJECT', toggle=True) + layout.separator() + layout.label(text="Influence Filters:") - col = layout.column() - col.separator() - col.label(text="Vertex Group:") - row = col.row(align=True) - row.prop_search(md, "vertex_group", ob, "vertex_groups", text="") - row.prop(md, "invert_vertex", text="", icon='ARROW_LEFTRIGHT') + split = layout.split(factor=0.25) - col = layout.column() - col.separator() + col1 = split.column() - col.label(text="Material:") - row = col.row(align=True) - row.prop_search(md, "material", gpd, "materials", text="", icon='SHADING_TEXTURE') - row.prop(md, "invert_materials", text="", icon='ARROW_LEFTRIGHT') - row = layout.row(align=True) - row.prop(md, "pass_index", text="Pass") - row.prop(md, "invert_material_pass", text="", icon='ARROW_LEFTRIGHT') + col1.label(text="Layer:") + col1.label(text="Material:") + if use_vertex: + col1.label(text="Vertex Group:") - col = layout.column() - col.separator() + col2 = split.column() - col.label(text="Layer:") - row = col.row(align=True) + split = col2.split(factor=0.6) + row = split.row(align=True) row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL') row.prop(md, "invert_layers", text="", icon='ARROW_LEFTRIGHT') - row = layout.row(align=True) + + row = split.row(align=True) row.prop(md, "layer_pass", text="Pass") row.prop(md, "invert_layer_pass", text="", icon='ARROW_LEFTRIGHT') - def GP_SMOOTH(self, layout, ob, md): - gpd = ob.data - col = layout.column() - col.prop(md, "factor") - col.prop(md, "step") + split = col2.split(factor=0.6) - col.label(text="Affect:") - row = col.row(align=True) - row.prop(md, "use_edit_position", text="Position", icon='MESH_DATA', toggle=True) - row.prop(md, "use_edit_strength", text="Strength", icon='COLOR', toggle=True) - row.prop(md, "use_edit_thickness", text="Thickness", icon='LINE_DATA', toggle=True) - row.prop(md, "use_edit_uv", text="UV", icon='MOD_UVPROJECT', toggle=True) - - col.separator() - col.label(text="Vertex Group:") - row = col.row(align=True) - row.prop_search(md, "vertex_group", ob, "vertex_groups", text="") - row.prop(md, "invert_vertex", text="", icon='ARROW_LEFTRIGHT') - - col = layout.column() - col.separator() - - col.label(text="Material:") - row = col.row(align=True) + row = split.row(align=True) row.prop_search(md, "material", gpd, "materials", text="", icon='SHADING_TEXTURE') row.prop(md, "invert_materials", text="", icon='ARROW_LEFTRIGHT') - row = layout.row(align=True) + + row = split.row(align=True) row.prop(md, "pass_index", text="Pass") row.prop(md, "invert_material_pass", text="", icon='ARROW_LEFTRIGHT') - col = layout.column() - col.separator() + if use_vertex: + row = col2.row(align=True) + row.prop_search(md, "vertex_group", ob, "vertex_groups", text="") + row.prop(md, "invert_vertex", text="", icon='ARROW_LEFTRIGHT') - col.label(text="Layer:") - row = col.row(align=True) - row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL') - row.prop(md, "invert_layers", text="", icon='ARROW_LEFTRIGHT') - row = layout.row(align=True) - row.prop(md, "layer_pass", text="Pass") - row.prop(md, "invert_layer_pass", text="", icon='ARROW_LEFTRIGHT') + if use_curve: + col = layout.column() + col.separator() + col.prop(md, "use_custom_curve") + if md.use_custom_curve: + col.template_curve_mapping(md, "curve") - def GP_SUBDIV(self, layout, ob, md): - gpd = ob.data + def GP_NOISE(self, layout, ob, md): split = layout.split() col = split.column() row = col.row(align=True) - row.prop(md, "level") - row.prop(md, "simple", text="", icon='PARTICLE_POINT') + row.prop(md, "factor", text="Position") + row = col.row(align=True) + row.prop(md, "factor_strength", text="Strength") + row = col.row(align=True) + row.prop(md, "factor_thickness", text="Thickness") + row = col.row(align=True) + row.prop(md, "factor_uvs", text="UV") - col = layout.column() col.separator() - - col.label(text="Material:") row = col.row(align=True) + row.prop(md, "random", text="", icon='TIME', toggle=True) - row.prop_search(md, "material", gpd, "materials", text="", icon='SHADING_TEXTURE') - row.prop(md, "invert_materials", text="", icon='ARROW_LEFTRIGHT') - row = layout.row(align=True) - row.prop(md, "pass_index", text="Pass") - row.prop(md, "invert_material_pass", text="", icon='ARROW_LEFTRIGHT') + subrow = row.row(align=True) + subrow.enabled = md.random + subrow.prop(md, "step") + subrow.prop(md, "seed") - col = layout.column() col.separator() + col.prop(md, "noise_scale") - col.label(text="Layer:") + self.gpencil_masking(layout, ob, md, True, True) + + def GP_SMOOTH(self, layout, ob, md): + col = layout.column() + col.prop(md, "factor") + col.prop(md, "step", text="Repeat") + + col.label(text="Affect:") row = col.row(align=True) - row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL') - row.prop(md, "invert_layers", text="", icon='ARROW_LEFTRIGHT') - row = layout.row(align=True) - row.prop(md, "layer_pass", text="Pass") - row.prop(md, "invert_layer_pass", text="", icon='ARROW_LEFTRIGHT') + row.prop(md, "use_edit_position", text="Position", toggle=True) + row.prop(md, "use_edit_strength", text="Strength", toggle=True) + row.prop(md, "use_edit_thickness", text="Thickness", toggle=True) + row.prop(md, "use_edit_uv", text="UV", toggle=True) + + self.gpencil_masking(layout, ob, md, True, True) + + def GP_SUBDIV(self, layout, ob, md): + layout.row().prop(md, "subdivision_type", expand=True) + split = layout.split() + col = split.column() + row = col.row(align=True) + row.prop(md, "level", text="Subdivisions") + + self.gpencil_masking(layout, ob, md, False) def GP_SIMPLIFY(self, layout, ob, md): gpd = ob.data @@ -1893,77 +1863,21 @@ class DATA_PT_gpencil_modifiers(ModifierButtonsPanel, Panel): elif md.mode == 'MERGE': col.prop(md, "distance") - col = layout.column() - col.separator() - - col.label(text="Material:") - row = col.row(align=True) - row.prop_search(md, "material", gpd, "materials", text="", icon='SHADING_TEXTURE') - row.prop(md, "invert_materials", text="", icon='ARROW_LEFTRIGHT') - row = layout.row(align=True) - row.prop(md, "pass_index", text="Pass") - row.prop(md, "invert_material_pass", text="", icon='ARROW_LEFTRIGHT') - - col = layout.column() - col.separator() - - col.label(text="Layer:") - row = col.row(align=True) - row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL') - row.prop(md, "invert_layers", text="", icon='ARROW_LEFTRIGHT') - row = layout.row(align=True) - row.prop(md, "layer_pass", text="Pass") - row.prop(md, "invert_layer_pass", text="", icon='ARROW_LEFTRIGHT') + self.gpencil_masking(layout, ob, md, False) def GP_THICK(self, layout, ob, md): - gpd = ob.data - split = layout.split() - - col = split.column() - row = col.row(align=True) - row.prop(md, "thickness", text="Thickness Factor") - - col.prop(md, "normalize_thickness") - - if not md.normalize_thickness: - split = layout.split() - col = split.column() - col.prop(md, "use_custom_curve") - - if md.use_custom_curve: - col.template_curve_mapping(md, "curve") - - col = layout.column() - col.separator() - col.label(text="Vertex Group:") - row = col.row(align=True) - row.prop_search(md, "vertex_group", ob, "vertex_groups", text="") - row.prop(md, "invert_vertex", text="", icon='ARROW_LEFTRIGHT') - col = layout.column() - col.separator() - col.label(text="Material:") - row = col.row(align=True) - row.prop_search(md, "material", gpd, "materials", text="", icon='SHADING_TEXTURE') - row.prop(md, "invert_materials", text="", icon='ARROW_LEFTRIGHT') - row = layout.row(align=True) - row.prop(md, "pass_index", text="Pass") - row.prop(md, "invert_material_pass", text="", icon='ARROW_LEFTRIGHT') + col.prop(md, "normalize_thickness") - col = layout.column() - col.separator() + if md.normalize_thickness: + col.prop(md, "thickness") + else: + col.prop(md, "thickness_factor") - col.label(text="Layer:") - row = col.row(align=True) - row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL') - row.prop(md, "invert_layers", text="", icon='ARROW_LEFTRIGHT') - row = layout.row(align=True) - row.prop(md, "layer_pass", text="Pass") - row.prop(md, "invert_layer_pass", text="", icon='ARROW_LEFTRIGHT') + self.gpencil_masking(layout, ob, md, True, True) def GP_TINT(self, layout, ob, md): - gpd = ob.data split = layout.split() col = split.column() @@ -1971,30 +1885,9 @@ class DATA_PT_gpencil_modifiers(ModifierButtonsPanel, Panel): col.prop(md, "factor") row = layout.row() - row.prop(md, "create_materials") row.prop(md, "modify_color") - col = layout.column() - col.separator() - - col.label(text="Material:") - row = col.row(align=True) - row.prop_search(md, "material", gpd, "materials", text="", icon='SHADING_TEXTURE') - row.prop(md, "invert_materials", text="", icon='ARROW_LEFTRIGHT') - row = layout.row(align=True) - row.prop(md, "pass_index", text="Pass") - row.prop(md, "invert_material_pass", text="", icon='ARROW_LEFTRIGHT') - - col = layout.column() - col.separator() - - col.label(text="Layer:") - row = col.row(align=True) - row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL') - row.prop(md, "invert_layers", text="", icon='ARROW_LEFTRIGHT') - row = layout.row(align=True) - row.prop(md, "layer_pass", text="Pass") - row.prop(md, "invert_layer_pass", text="", icon='ARROW_LEFTRIGHT') + self.gpencil_masking(layout, ob, md, False, True) def GP_TIME(self, layout, ob, md): gpd = ob.data @@ -2040,7 +1933,6 @@ class DATA_PT_gpencil_modifiers(ModifierButtonsPanel, Panel): row.prop(md, "invert_layer_pass", text="", icon='ARROW_LEFTRIGHT') def GP_COLOR(self, layout, ob, md): - gpd = ob.data split = layout.split() col = split.column() @@ -2050,134 +1942,66 @@ class DATA_PT_gpencil_modifiers(ModifierButtonsPanel, Panel): col.prop(md, "value", text="V", slider=True) row = layout.row() - row.prop(md, "create_materials") row.prop(md, "modify_color") - col = layout.column() - col.separator() - - col.label(text="Material:") - row = col.row(align=True) - row.prop_search(md, "material", gpd, "materials", text="", icon='SHADING_TEXTURE') - row.prop(md, "invert_materials", text="", icon='ARROW_LEFTRIGHT') - row = layout.row(align=True) - row.prop(md, "pass_index", text="Pass") - row.prop(md, "invert_material_pass", text="", icon='ARROW_LEFTRIGHT') - - col = layout.column() - col.separator() - - col.label(text="Layer:") - row = col.row(align=True) - row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL') - row.prop(md, "invert_layers", text="", icon='ARROW_LEFTRIGHT') - row = layout.row(align=True) - row.prop(md, "layer_pass", text="Pass") - row.prop(md, "invert_layer_pass", text="", icon='ARROW_LEFTRIGHT') + self.gpencil_masking(layout, ob, md, False, True) def GP_OPACITY(self, layout, ob, md): - gpd = ob.data split = layout.split() col = split.column() - col.label(text="Opacity:") - col.prop(md, "factor") - - row = layout.row() - row.prop(md, "opacity_mode", text="Mode") - - if md.opacity_mode == 'MATERIAL': - row = layout.row() - row.prop(md, "create_materials") - row.prop(md, "modify_color", text="Change") + col.prop(md, "normalize_opacity") + if md.normalize_opacity is True: + text="Strength" else: - col = layout.column() - col.separator() - col.label(text="Vertex Group:") - row = col.row(align=True) - row.prop_search(md, "vertex_group", ob, "vertex_groups", text="") - row.prop(md, "invert_vertex", text="", icon='ARROW_LEFTRIGHT') - - col = layout.column() - col.separator() - - col.label(text="Material:") - row = col.row(align=True) - row.prop_search(md, "material", gpd, "materials", text="", icon='SHADING_TEXTURE') - row.prop(md, "invert_materials", text="", icon='ARROW_LEFTRIGHT') - row = layout.row(align=True) - row.prop(md, "pass_index", text="Pass") - row.prop(md, "invert_material_pass", text="", icon='ARROW_LEFTRIGHT') + text="Opacity Factor" - col = layout.column() - col.separator() + col.prop(md, "factor", text=text) + col.prop(md, "modify_color") - col.label(text="Layer:") - row = col.row(align=True) - row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL') - row.prop(md, "invert_layers", text="", icon='ARROW_LEFTRIGHT') - row = layout.row(align=True) - row.prop(md, "layer_pass", text="Pass") - row.prop(md, "invert_layer_pass", text="", icon='ARROW_LEFTRIGHT') + self.gpencil_masking(layout, ob, md, True, True) def GP_ARRAY(self, layout, ob, md): - gpd = ob.data - col = layout.column() col.prop(md, "count") split = layout.split() col = split.column() - col.label(text="Offset:") - col.prop(md, "offset", text="") - col.prop(md, "offset_object", text="Object") + col.prop(md, "use_constant_offset", text="Constant Offset") + subcol = col.column() + subcol.enabled = md.use_constant_offset + subcol.prop(md, "constant_offset", text="") + + col.prop(md, "use_object_offset") + subcol = col.column() + subcol.enabled = md.use_object_offset + subcol.prop(md, "offset_object", text="") col = split.column() - col.label(text="Shift:") - col.prop(md, "shift", text="") + col.prop(md, "use_relative_offset", text="Relative Offset") + subcol = col.column() + subcol.enabled = md.use_relative_offset + subcol.prop(md, "relative_offset", text="") split = layout.split() col = split.column() - col.label(text="Rotation:") - col.prop(md, "rotation", text="") - col.separator() - row = col.row(align=True) - row.prop(md, "random_rot", text="", icon='TIME', toggle=True) - row.prop(md, "rot_factor", text="") + col.label(text="Random Offset:") + col.prop(md, "random_offset", text="") col = split.column() - col.label(text="Scale:") - col.prop(md, "scale", text="") - col.separator() - row = col.row(align=True) - row.prop(md, "random_scale", text="", icon='TIME', toggle=True) - row.prop(md, "scale_factor", text="") + col.label(text="Random Rotation:") + col.prop(md, "random_rotation", text="") - col = layout.column() - col.prop(md, "replace_material", text="Material") - col.prop(md, "keep_on_top", text="Keep original stroke on top") - - col = layout.column() - col.separator() - - col.label(text="Material:") - row = col.row(align=True) - row.prop_search(md, "material", gpd, "materials", text="", icon='SHADING_TEXTURE') - row.prop(md, "invert_materials", text="", icon='ARROW_LEFTRIGHT') - row = layout.row(align=True) - row.prop(md, "pass_index", text="Pass") - row.prop(md, "invert_material_pass", text="", icon='ARROW_LEFTRIGHT') + col = split.column() + col.label(text="Random Scale:") + col.prop(md, "random_scale", text="") col = layout.column() + col.prop(md, "seed") col.separator() + col.prop(md, "replace_material", text="Material Override") - col.label(text="Layer:") - row = col.row(align=True) - row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL') - row.prop(md, "invert_layers", text="", icon='ARROW_LEFTRIGHT') - row = layout.row(align=True) - row.prop(md, "layer_pass", text="Pass") - row.prop(md, "invert_layer_pass", text="", icon='ARROW_LEFTRIGHT') + self.gpencil_masking(layout, ob, md, False) def GP_BUILD(self, layout, ob, md): gpd = ob.data @@ -2215,7 +2039,6 @@ class DATA_PT_gpencil_modifiers(ModifierButtonsPanel, Panel): row.prop(md, "invert_layer_pass", text="", icon='ARROW_LEFTRIGHT') def GP_LATTICE(self, layout, ob, md): - gpd = ob.data split = layout.split() col = split.column() @@ -2224,70 +2047,20 @@ class DATA_PT_gpencil_modifiers(ModifierButtonsPanel, Panel): layout.prop(md, "strength", slider=True) - col = layout.column() - col.separator() - col.label(text="Vertex Group:") - row = col.row(align=True) - row.prop_search(md, "vertex_group", ob, "vertex_groups", text="") - row.prop(md, "invert_vertex", text="", icon='ARROW_LEFTRIGHT') - - col = layout.column() - col.separator() - - col.label(text="Material:") - row = col.row(align=True) - row.prop_search(md, "material", gpd, "materials", text="", icon='SHADING_TEXTURE') - row.prop(md, "invert_materials", text="", icon='ARROW_LEFTRIGHT') - row = layout.row(align=True) - row.prop(md, "pass_index", text="Pass") - row.prop(md, "invert_material_pass", text="", icon='ARROW_LEFTRIGHT') - - col = layout.column() - col.separator() - - col.label(text="Layer:") - row = col.row(align=True) - row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL') - row.prop(md, "invert_layers", text="", icon='ARROW_LEFTRIGHT') - row = layout.row(align=True) - row.prop(md, "layer_pass", text="Pass") - row.prop(md, "invert_layer_pass", text="", icon='ARROW_LEFTRIGHT') + self.gpencil_masking(layout, ob, md, True) def GP_MIRROR(self, layout, ob, md): - gpd = ob.data - row = layout.row(align=True) row.prop(md, "x_axis") row.prop(md, "y_axis") row.prop(md, "z_axis") - layout.label(text="Object:") + layout.label(text="Mirror Object:") layout.prop(md, "object", text="") - col = layout.column() - col.separator() - - col.label(text="Material:") - row = col.row(align=True) - row.prop_search(md, "material", gpd, "materials", text="", icon='SHADING_TEXTURE') - row.prop(md, "invert_materials", text="", icon='ARROW_LEFTRIGHT') - row = layout.row(align=True) - row.prop(md, "pass_index", text="Pass") - row.prop(md, "invert_material_pass", text="", icon='ARROW_LEFTRIGHT') - - col = layout.column() - col.separator() - - col.label(text="Layer:") - row = col.row(align=True) - row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL') - row.prop(md, "invert_layers", text="", icon='ARROW_LEFTRIGHT') - row = layout.row(align=True) - row.prop(md, "layer_pass", text="Pass") - row.prop(md, "invert_layer_pass", text="", icon='ARROW_LEFTRIGHT') + self.gpencil_masking(layout, ob, md, False) def GP_HOOK(self, layout, ob, md): - gpd = ob.data split = layout.split() col = split.column() @@ -2317,71 +2090,16 @@ class DATA_PT_gpencil_modifiers(ModifierButtonsPanel, Panel): col = split.column() col.prop(md, "use_falloff_uniform") - col = layout.column() - col.separator() - col.label(text="Vertex Group:") - row = col.row(align=True) - row.prop_search(md, "vertex_group", ob, "vertex_groups", text="") - row.prop(md, "invert_vertex", text="", icon='ARROW_LEFTRIGHT') - - col = layout.column() - col.separator() - - col.label(text="Material:") - row = col.row(align=True) - row.prop_search(md, "material", gpd, "materials", text="", icon='SHADING_TEXTURE') - row.prop(md, "invert_materials", text="", icon='ARROW_LEFTRIGHT') - row = layout.row(align=True) - row.prop(md, "pass_index", text="Pass") - row.prop(md, "invert_material_pass", text="", icon='ARROW_LEFTRIGHT') - - col = layout.column() - col.separator() - - col.label(text="Layer:") - row = col.row(align=True) - row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL') - row.prop(md, "invert_layers", text="", icon='ARROW_LEFTRIGHT') - row = layout.row(align=True) - row.prop(md, "layer_pass", text="Pass") - row.prop(md, "invert_layer_pass", text="", icon='ARROW_LEFTRIGHT') + self.gpencil_masking(layout, ob, md, True) def GP_OFFSET(self, layout, ob, md): - gpd = ob.data - col = layout.column() - - col.prop(md, "location") - col.prop(md, "scale") - col.prop(md, "rotation") - - col = layout.column() - col.separator() - col.label(text="Vertex Group:") - row = col.row(align=True) - row.prop_search(md, "vertex_group", ob, "vertex_groups", text="") - row.prop(md, "invert_vertex", text="", icon='ARROW_LEFTRIGHT') - - col = layout.column() - col.separator() - - col.label(text="Material:") - row = col.row(align=True) - row.prop_search(md, "material", gpd, "materials", text="", icon='SHADING_TEXTURE') - row.prop(md, "invert_materials", text="", icon='ARROW_LEFTRIGHT') - row = layout.row(align=True) - row.prop(md, "pass_index", text="Pass") - row.prop(md, "invert_material_pass", text="", icon='ARROW_LEFTRIGHT') + split = layout.split() - col = layout.column() - col.separator() + split.column().prop(md, "location") + split.column().prop(md, "rotation") + split.column().prop(md, "scale") - col.label(text="Layer:") - row = col.row(align=True) - row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL') - row.prop(md, "invert_layers", text="", icon='ARROW_LEFTRIGHT') - row = layout.row(align=True) - row.prop(md, "layer_pass", text="Pass") - row.prop(md, "invert_layer_pass", text="", icon='ARROW_LEFTRIGHT') + self.gpencil_masking(layout, ob, md, True) def GP_ARMATURE(self, layout, ob, md): split = layout.split() @@ -2407,50 +2125,42 @@ class DATA_PT_gpencil_modifiers(ModifierButtonsPanel, Panel): sub.prop(md, "invert_vertex_group", text="", icon='ARROW_LEFTRIGHT') def GP_MULTIPLY(self, layout, ob, md): - gpd = ob.data col = layout.column() - col.prop(md, "duplications") + col.prop(md, "duplicates") subcol = col.column() - subcol.enabled = md.duplications > 0 + subcol.enabled = md.duplicates > 0 subcol.prop(md, "distance") subcol.prop(md, "offset", slider=True) subcol.separator() - subcol.prop(md, "enable_fading") - if md.enable_fading: + subcol.prop(md, "use_fade") + if md.use_fade: subcol.prop(md, "fading_center") subcol.prop(md, "fading_thickness", slider=True) subcol.prop(md, "fading_opacity", slider=True) - subcol.separator() - - col.prop(md, "enable_angle_splitting") - if md.enable_angle_splitting: - col.prop(md, "split_angle") + self.gpencil_masking(layout, ob, md, False) + def GP_VERTEXCOLOR(self, layout, ob, md): col = layout.column() - col.separator() + col.label(text="Object:") + col.prop(md, "object", text="") - col.label(text="Material:") + col.separator() row = col.row(align=True) - row.prop_search(md, "material", gpd, "materials", text="", icon='SHADING_TEXTURE') - row.prop(md, "invert_materials", text="", icon='ARROW_LEFTRIGHT') - row = layout.row(align=True) - row.prop(md, "pass_index", text="Pass") - row.prop(md, "invert_material_pass", text="", icon='ARROW_LEFTRIGHT') + row.prop(md, "radius") + row.prop(md, "factor", text="Strength", slider=True) - col = layout.column() col.separator() + col.label(text="Colors:") + col.template_color_ramp(md, "colors") - col.label(text="Layer:") - row = col.row(align=True) - row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL') - row.prop(md, "invert_layers", text="", icon='ARROW_LEFTRIGHT') - row = layout.row(align=True) - row.prop(md, "layer_pass", text="Pass") - row.prop(md, "invert_layer_pass", text="", icon='ARROW_LEFTRIGHT') + col.separator() + col.prop(md, "vertex_mode") + + self.gpencil_masking(layout, ob, md, True, True) classes = ( @@ -2460,5 +2170,6 @@ classes = ( if __name__ == "__main__": # only for live edit. from bpy.utils import register_class + for cls in classes: register_class(cls) diff --git a/release/scripts/startup/bl_ui/properties_data_shaderfx.py b/release/scripts/startup/bl_ui/properties_data_shaderfx.py index fce86446dfc..48a851e8bef 100644 --- a/release/scripts/startup/bl_ui/properties_data_shaderfx.py +++ b/release/scripts/startup/bl_ui/properties_data_shaderfx.py @@ -56,27 +56,30 @@ class DATA_PT_shader_fx(ShaderFxButtonsPanel, Panel): def FX_BLUR(self, layout, fx): - layout.prop(fx, "factor", text="Factor") + layout.prop(fx, "use_dof_mode", text="Use as Depth Of Field") + layout.separator() + + col = layout.column() + col.enabled = not fx.use_dof_mode + col.prop(fx, "size", text="Size") + col.separator() + col.prop(fx, "rotation") + layout.prop(fx, "samples", text="Samples") - layout.separator() - layout.prop(fx, "use_dof_mode") - if fx.use_dof_mode: - layout.prop(fx, "coc") def FX_COLORIZE(self, layout, fx): layout.prop(fx, "mode", text="Mode") - if fx.mode == 'BITONE': + if fx.mode == 'DUOTONE': layout.prop(fx, "low_color", text="Low Color") if fx.mode == 'CUSTOM': layout.prop(fx, "low_color", text="Color") - if fx.mode == 'BITONE': + if fx.mode == 'DUOTONE': layout.prop(fx, "high_color", text="High Color") - if fx.mode in {'BITONE', 'CUSTOM', 'TRANSPARENT'}: - layout.prop(fx, "factor") + layout.prop(fx, "factor") def FX_WAVE(self, layout, fx): row = layout.row(align=True) @@ -127,16 +130,21 @@ class DATA_PT_shader_fx(ShaderFxButtonsPanel, Panel): def FX_GLOW(self, layout, fx): layout.prop(fx, "mode") - layout.prop(fx, "glow_color") if fx.mode == 'LUMINANCE': layout.prop(fx, "threshold") else: layout.prop(fx, "select_color") + layout.prop(fx, "glow_color") layout.separator() - layout.prop(fx, "radius") + layout.prop(fx, "blend_mode", text="Blend") + layout.prop(fx, "opacity") + + layout.prop(fx, "size") + layout.prop(fx, "rotation") layout.prop(fx, "samples") - layout.prop(fx, "use_alpha_mode", text="Use Alpha Mode") + + layout.prop(fx, "use_glow_under", text="Glow Under") def FX_SWIRL(self, layout, fx): layout.prop(fx, "object", text="Object") @@ -144,18 +152,10 @@ class DATA_PT_shader_fx(ShaderFxButtonsPanel, Panel): layout.prop(fx, "radius") layout.prop(fx, "angle") - layout.prop(fx, "use_transparent") - def FX_FLIP(self, layout, fx): layout.prop(fx, "flip_horizontal") layout.prop(fx, "flip_vertical") - def FX_LIGHT(self, layout, fx): - layout.prop(fx, "object", text="Object") - - layout.prop(fx, "energy") - layout.prop(fx, "ambient") - classes = ( DATA_PT_shader_fx, 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 2001f46820f..fced848641e 100644 --- a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py +++ b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py @@ -19,7 +19,7 @@ # <pep8 compliant> import bpy -from bpy.types import Menu, UIList +from bpy.types import Menu, UIList, Operator from bpy.app.translations import pgettext_iface as iface_ @@ -108,11 +108,6 @@ class AnnotationDrawingToolsPanel: sub.operator("gpencil.blank_frame_add", icon='FILE_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_draw_additive", 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() @@ -125,9 +120,6 @@ class AnnotationDrawingToolsPanel: elif is_clip_editor: row.prop(context.space_data, "grease_pencil_source", expand=True) - # col.separator() - # col.separator() - gpencil_stroke_placement_settings(context, col) @@ -136,29 +128,33 @@ class GreasePencilSculptOptionsPanel: @classmethod def poll(cls, context): - settings = context.tool_settings.gpencil_sculpt - tool = settings.sculpt_tool + tool_settings = context.scene.tool_settings + settings = tool_settings.gpencil_sculpt_paint + brush = settings.brush + tool = brush.gpencil_sculpt_tool - return bool(tool in {'SMOOTH', 'RANDOMIZE', 'SMOOTH'}) + return bool(tool in {'SMOOTH', 'RANDOMIZE'}) 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.sculpt_tool + tool_settings = context.scene.tool_settings + settings = tool_settings.gpencil_sculpt_paint brush = settings.brush + gp_settings = brush.gpencil_settings + tool = brush.gpencil_sculpt_tool if tool in {'SMOOTH', 'RANDOMIZE'}: - layout.prop(settings, "use_edit_position", text="Affect Position") - layout.prop(settings, "use_edit_strength", text="Affect Strength") - layout.prop(settings, "use_edit_thickness", text="Affect Thickness") + layout.prop(gp_settings, "use_edit_position", text="Affect Position") + layout.prop(gp_settings, "use_edit_strength", text="Affect Strength") + layout.prop(gp_settings, "use_edit_thickness", text="Affect Thickness") if tool == 'SMOOTH': - layout.prop(brush, "use_edit_pressure") + layout.prop(gp_settings, "use_edit_pressure") - layout.prop(settings, "use_edit_uv", text="Affect UV") + layout.prop(gp_settings, "use_edit_uv", text="Affect UV") # GP Object Tool Settings @@ -174,7 +170,7 @@ class GreasePencilDisplayPanel: if context.mode == 'PAINT_GPENCIL': return brush.gpencil_tool != 'ERASE' else: - # GP Sculpt and Weight Paint always have Brush Tip panel. + # GP Sculpt, Vertex and Weight Paint always have Brush Tip panel. return True return False @@ -182,16 +178,18 @@ class GreasePencilDisplayPanel: if self.is_popover: return + tool_settings = context.tool_settings if context.mode == 'PAINT_GPENCIL': - brush = context.tool_settings.gpencil_paint.brush - gp_settings = brush.gpencil_settings - - self.layout.prop(gp_settings, "use_cursor", text="") - elif context.mode in {'SCULPT_GPENCIL', 'WEIGHT_GPENCIL'}: - settings = context.tool_settings.gpencil_sculpt - brush = settings.brush - - self.layout.prop(brush, "use_cursor", text="") + settings = tool_settings.gpencil_paint + elif context.mode == 'SCULPT_GPENCIL': + settings = tool_settings.gpencil_sculpt_paint + elif context.mode == 'WEIGHT_GPENCIL': + settings = tool_settings.gpencil_weight_paint + elif context.mode == 'VERTEX_GPENCIL': + 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 @@ -199,279 +197,101 @@ class GreasePencilDisplayPanel: layout.use_property_decorate = False tool_settings = context.tool_settings - ob = context.active_object + 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': + settings = tool_settings.gpencil_weight_paint + elif context.mode == 'VERTEX_GPENCIL': + settings = tool_settings.gpencil_vertex_paint + brush = settings.brush + gp_settings = brush.gpencil_settings + ob = context.active_object if ob.mode == 'PAINT_GPENCIL': - brush = tool_settings.gpencil_paint.brush - gp_settings = brush.gpencil_settings if self.is_popover: row = layout.row(align=True) - row.prop(gp_settings, "use_cursor", text="") + row.prop(settings, "show_brush", text="") row.label(text="Display Cursor") col = layout.column(align=True) - col.active = gp_settings.use_cursor + col.active = settings.show_brush if brush.gpencil_tool == 'DRAW': col.prop(gp_settings, "show_lasso", text="Show Fill Color While Drawing") - if brush.gpencil_tool == 'FILL': - col.prop(brush, "cursor_color_add", text="Cursor Color") - - elif ob.mode in {'SCULPT_GPENCIL', 'WEIGHT_GPENCIL'}: - settings = tool_settings.gpencil_sculpt - brush = settings.brush - tool = settings.sculpt_tool - - if self.is_popover: - row = layout.row(align=True) - row.prop(brush, "use_cursor", text="") - row.label(text="Display Cursor") - + elif ob.mode == 'SCULPT_GPENCIL': col = layout.column(align=True) - col.active = brush.use_cursor + col.active = settings.show_brush col.prop(brush, "cursor_color_add", text="Cursor Color") - if tool in {'THICKNESS', 'STRENGTH', 'PINCH', 'TWIST'}: - col.prop(brush, "cursor_color_sub", text="Inverse Cursor Color") - - -class GPENCIL_MT_pie_tool_palette(Menu): - """A pie menu for quick access to Grease Pencil tools""" - bl_label = "Grease Pencil Tools" - - def draw(self, context): - layout = self.layout - - pie = layout.menu_pie() - gpd = context.gpencil_data - - # W - Drawing Types - col = pie.column() - col.operator("gpencil.draw", text="Draw", icon='GREASEPENCIL').mode = 'DRAW' - col.operator("gpencil.draw", text="Straight Lines", icon='LINE_DATA').mode = 'DRAW_STRAIGHT' - col.operator("gpencil.draw", text="Poly", icon='MESH_DATA').mode = 'DRAW_POLY' - - # E - Eraser - # XXX: needs a dedicated icon... - col = pie.column() - col.operator("gpencil.draw", text="Eraser", icon='FORCE_CURVE').mode = 'ERASER' - - # E - "Settings" Palette is included here too, since it needs to be in a stable position... - if gpd and gpd.layers.active: - col.separator() - col.operator( - "wm.call_menu_pie", - text="Settings...", - icon='SCRIPTWIN').name = "GPENCIL_MT_pie_settings_palette" - - # Editing tools - if gpd: - if gpd.use_stroke_edit_mode and context.editable_gpencil_strokes: - # S - Exit Edit Mode - pie.operator("gpencil.editmode_toggle", text="Exit Edit Mode", icon='EDIT') - - # N - Transforms - col = pie.column() - row = col.row(align=True) - row.operator("transform.translate", icon='MAN_TRANS') - row.operator("transform.rotate", icon='MAN_ROT') - row.operator("transform.resize", text="Scale", icon='MAN_SCALE') - row = col.row(align=True) - row.label(text="Proportional Edit:") - row.prop(context.tool_settings, "use_proportional_edit", text="", icon_only=True) - row.prop(context.tool_settings, "proportional_edit_falloff", text="", icon_only=True) - - # NW - Select (Non-Modal) - col = pie.column() - col.operator("gpencil.select_all", text="Select All", icon='PARTICLE_POINT') - col.operator("gpencil.select_all", text="Select Inverse", icon='BLANK1') - col.operator("gpencil.select_linked", text="Select Linked", icon='LINKED') - col.operator("gpencil.palettecolor_select", text="Select Color", icon='COLOR') - - # NE - Select (Modal) - col = pie.column() - col.operator("gpencil.select_box", text="Box 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() - col.operator("gpencil.duplicate_move", icon='PARTICLE_PATH', text="Duplicate") - col.operator("gpencil.delete", icon='X', text="Delete...") - - # SE - More Tools - pie.operator("wm.call_menu_pie", text="More...").name = "GPENCIL_MT_pie_tools_more" - else: - # Toggle Edit Mode - pie.operator("gpencil.editmode_toggle", text="Enable Stroke Editing", icon='EDIT') + if brush.gpencil_sculpt_tool in {'THICKNESS', 'STRENGTH', 'PINCH', 'TWIST'}: + col.prop(brush, "cursor_color_subtract", text="Inverse Cursor Color") + elif ob.mode == 'WEIGHT_GPENCIL': + col = layout.column(align=True) + col.active = settings.show_brush -class GPENCIL_MT_pie_settings_palette(Menu): - """A pie menu for quick access to Grease Pencil settings""" - bl_label = "Grease Pencil Settings" + col.prop(brush, "cursor_color_add", text="Cursor Color") - @classmethod - def poll(cls, context): - return bool(context.gpencil_data and context.active_gpencil_layer) + elif ob.mode == 'VERTEX_GPENCIL': + row = layout.row(align=True) + row.prop(settings, "show_brush", text="") + row.label(text="Display Cursor") - def draw(self, context): - layout = self.layout - pie = layout.menu_pie() - gpd = context.gpencil_data - gpl = context.active_gpencil_layer - palcolor = None # context.active_gpencil_palettecolor - - is_editmode = bool(gpd and gpd.use_stroke_edit_mode and context.editable_gpencil_strokes) - - # W - Stroke draw settings - col = pie.column(align=True) - if palcolor is not None: - col.enabled = not palcolor.lock - col.label(text="Stroke") - col.prop(palcolor, "color", text="") - col.prop(palcolor, "alpha", text="", slider=True) - - # E - Fill draw settings - col = pie.column(align=True) - if palcolor is not None: - col.enabled = not palcolor.lock - col.label(text="Fill") - col.prop(palcolor, "fill_color", text="") - col.prop(palcolor, "fill_alpha", text="", slider=True) - - # S Brush settings - gpencil_active_brush_settings_simple(context, pie) - - # N - Active Layer - col = pie.column() - col.label(text="Active Layer: ") - - row = col.row() - row.operator_context = 'EXEC_REGION_WIN' - row.operator_menu_enum("gpencil.layer_change", "layer", text="", icon='GREASEPENCIL') - row.prop(gpl, "info", text="") - row.operator("gpencil.layer_remove", text="", icon='X') - - row = col.row() - row.prop(gpl, "lock") - row.prop(gpl, "hide") - col.prop(gpl, "use_onion_skinning") - - # NW/NE/SW/SE - These operators are only available in editmode - # as they require strokes to be selected to work - if is_editmode: - # NW - Move stroke Down - col = pie.column(align=True) - col.label(text="Arrange Strokes") - col.operator("gpencil.stroke_arrange", text="Send to Back").direction = 'BOTTOM' - col.operator("gpencil.stroke_arrange", text="Send Backward").direction = 'DOWN' - - # NE - Move stroke Up - col = pie.column(align=True) - col.label(text="Arrange Strokes") - col.operator("gpencil.stroke_arrange", text="Bring to Front").direction = 'TOP' - col.operator("gpencil.stroke_arrange", text="Bring Forward").direction = 'UP' - - # SW - Move stroke to color - col = pie.column(align=True) - col.operator("gpencil.stroke_change_color", text="Move to Color") - - # SE - Join strokes - col = pie.column(align=True) - col.label(text="Join Strokes") - row = col.row() - row.operator("gpencil.stroke_join", text="Join").type = 'JOIN' - row.operator("gpencil.stroke_join", text="Join & Copy").type = 'JOINCOPY' - col.operator("gpencil.stroke_flip", text="Flip Direction") - - col.prop(gpd, "show_stroke_direction", text="Show Drawing Direction") - - -class GPENCIL_MT_pie_tools_more(Menu): - """A pie menu for accessing more Grease Pencil tools""" - bl_label = "More Grease Pencil Tools" +class GreasePencilBrushFalloff: + bl_label = "Falloff" + bl_options = {'DEFAULT_CLOSED'} @classmethod def poll(cls, context): - gpd = context.gpencil_data - return bool(gpd and gpd.use_stroke_edit_mode and context.editable_gpencil_strokes) - - def draw(self, _context): - layout = self.layout - - pie = layout.menu_pie() - # gpd = context.gpencil_data - - col = pie.column(align=True) - col.operator("gpencil.copy", text="Copy", icon='COPYDOWN') - col.operator("gpencil.paste", text="Paste", icon='PASTEDOWN').type = 'ACTIVE' - col.operator("gpencil.paste", text="Paste by Layer").type = 'LAYER' - - col = pie.column(align=True) - col.operator("gpencil.select_more", icon='ADD') - col.operator("gpencil.select_less", icon='REMOVE') - - pie.operator("transform.mirror", icon='MOD_MIRROR') - pie.operator("transform.bend", icon='MOD_SIMPLEDEFORM') - pie.operator("transform.shear", icon='MOD_TRIANGULATE') - pie.operator("transform.tosphere", icon='MOD_MULTIRES') - - pie.operator("gpencil.convert", icon='OUTLINER_OB_CURVE', text="Convert...") - pie.operator("wm.call_menu_pie", text="Back to Main Palette...").name = "GPENCIL_MT_pie_tool_palette" - - -class GPENCIL_MT_pie_sculpt(Menu): - """A pie menu for accessing Grease Pencil stroke sculpt settings""" - bl_label = "Grease Pencil Sculpt" + ts = context.tool_settings + settings = None + if context.mode == 'PAINT_GPENCIL': + settings = ts.gpencil_paint + if context.mode == 'SCULPT_GPENCIL': + settings = ts.gpencil_sculpt_paint + elif context.mode == 'WEIGHT_GPENCIL': + settings = ts.gpencil_weight_paint + elif context.mode == 'VERTEX_GPENCIL': + settings = ts.gpencil_vertex_paint - @classmethod - def poll(cls, context): - gpd = context.gpencil_data - return bool(gpd and gpd.use_stroke_edit_mode and context.editable_gpencil_strokes) + return (settings and settings.brush and settings.brush.curve) def draw(self, context): layout = self.layout + ts = context.tool_settings + settings = None + if context.mode == 'PAINT_GPENCIL': + settings = ts.gpencil_paint + if context.mode == 'SCULPT_GPENCIL': + settings = ts.gpencil_sculpt_paint + elif context.mode == 'WEIGHT_GPENCIL': + settings = ts.gpencil_weight_paint + elif context.mode == 'VERTEX_GPENCIL': + settings = ts.gpencil_vertex_paint + + if settings: + brush = settings.brush - pie = layout.menu_pie() - - settings = context.tool_settings.gpencil_sculpt - brush = settings.brush - - # W - Launch Sculpt Mode - col = pie.column() - # col.label(text="Tool:") - col.prop(settings, "sculpt_tool", text="") - col.operator("gpencil.sculpt_paint", text="Sculpt", icon='SCULPTMODE_HLT') - - # E - Common Settings - col = pie.column(align=True) - col.prop(brush, "size", slider=True) - row = col.row(align=True) - row.prop(brush, "strength", slider=True) - # row.prop(brush, "use_pressure_strength", text="", icon_only=True) - col.prop(brush, "use_falloff") - if settings.sculpt_tool in {'SMOOTH', 'RANDOMIZE'}: + col = layout.column(align=True) row = col.row(align=True) - row.prop(settings, "use_edit_position", text="Position", icon='MESH_DATA', toggle=True) - row.prop(settings, "use_edit_strength", text="Strength", icon='COLOR', toggle=True) - row.prop(settings, "use_edit_thickness", text="Thickness", icon='LINE_DATA', toggle=True) + row.prop(brush, "curve_preset", text="") - # S - Change Brush Type Shortcuts - row = pie.row() - row.prop_enum(settings, "tool", value='GRAB') - row.prop_enum(settings, "tool", value='PUSH') - row.prop_enum(settings, "tool", value='CLONE') + if brush.curve_preset == 'CUSTOM': + layout.template_curve_mapping(brush, "curve", brush=True) - # N - Change Brush Type Shortcuts - row = pie.row() - row.prop_enum(settings, "tool", value='SMOOTH') - row.prop_enum(settings, "tool", value='THICKNESS') - row.prop_enum(settings, "tool", value='STRENGTH') - row.prop_enum(settings, "tool", value='RANDOMIZE') + 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 GPENCIL_MT_snap(Menu): @@ -515,6 +335,32 @@ class GPENCIL_MT_move_to_layer(Menu): layout.operator("gpencil.layer_add", text="New Layer", icon='ADD') +class GPENCIL_MT_layer_active(Menu): + bl_label = "Change Active Layer" + + def draw(self, context): + layout = self.layout + layout.operator_context = 'INVOKE_REGION_WIN' + + gpd = context.gpencil_data + if gpd: + gpl_active = context.active_gpencil_layer + tot_layers = len(gpd.layers) + i = tot_layers - 1 + while i >= 0: + gpl = gpd.layers[i] + if gpl.info == gpl_active.info: + icon = 'GREASEPENCIL' + else: + icon = 'NONE' + layout.operator("gpencil.layer_active", text=gpl.info, icon=icon).layer = i + i -= 1 + + layout.separator() + + layout.operator("gpencil.layer_add", text="New Layer", icon='ADD') + + class GPENCIL_MT_gpencil_draw_delete(Menu): bl_label = "Delete" @@ -800,11 +646,7 @@ class GreasePencilMaterialsPanel: if ma is not None and ma.grease_pencil is not None: gpcolor = ma.grease_pencil - if ( - gpcolor.stroke_style == 'SOLID' or - gpcolor.use_stroke_pattern or - gpcolor.use_stroke_texture_mix - ): + if gpcolor.stroke_style == 'SOLID': row = layout.row() row.prop(gpcolor, "color", text="Stroke Color") @@ -813,6 +655,48 @@ class GreasePencilMaterialsPanel: 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 + + ts = context.scene.tool_settings + is_vertex = context.mode == 'VERTEX_GPENCIL' + gpencil_paint = ts.gpencil_vertex_paint if is_vertex else ts.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") + + if tool == 'TINT' or is_vertex is True: + row = layout.row(align=True) + row.prop(gp_settings, "vertex_mode", text="Mode") + + 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) @@ -830,9 +714,10 @@ class GPENCIL_UL_layer(UIList): row.prop(gpl, "info", text="", emboss=False) row = layout.row(align=True) - row.prop(gpl, "mask_layer", text="", - icon='MOD_MASK' if gpl.mask_layer else 'LAYER_ACTIVE', - emboss=False) + + icon_mask = 'MOD_MASK' if gpl.use_mask_layer else 'LAYER_ACTIVE' + + row.prop(gpl, "use_mask_layer", text="", icon=icon_mask, emboss=False) subrow = row.row(align=True) subrow.prop( @@ -868,16 +753,12 @@ class GreasePencilSimplifyPanel: layout.active = rd.simplify_gpencil col = layout.column() - col.prop(rd, "simplify_gpencil_onplay", text="Playback Only") - col.prop(rd, "simplify_gpencil_view_modifier", text="Modifiers") - col.prop(rd, "simplify_gpencil_shader_fx", text="ShaderFX") - col.prop(rd, "simplify_gpencil_blend", text="Layers Blending") - col.prop(rd, "simplify_gpencil_tint", text="Layers Tinting") - + col.prop(rd, "simplify_gpencil_onplay") col.prop(rd, "simplify_gpencil_view_fill") - sub = col.column() - sub.active = rd.simplify_gpencil_view_fill - sub.prop(rd, "simplify_gpencil_remove_lines", text="Lines") + 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 GreasePencilLayerAdjustmentsPanel: @@ -913,6 +794,65 @@ class GreasePencilLayerAdjustmentsPanel: col.prop(gpl, "lock_material") +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 GPENCIL_MT_layer_mask_menu(Menu): + bl_label = "Layer Specials" + + def draw(self, context): + layout = self.layout + ob = context.object + gpd = ob.data + gpl_active = gpd.layers.active + done = False + for gpl in gpd.layers: + if gpl != gpl_active and gpl.info not in gpl_active.mask_layers: + done = True + layout.operator("gpencil.layer_mask_add", text=gpl.info).name=gpl.info + + if done is False: + layout.label(text="No layers to add") + + +class GreasePencilLayerMasksPanel: + def draw_header(self, context): + ob = context.active_object + gpd = ob.data + gpl = gpd.layers.active + + self.layout.prop(gpl, "use_mask_layer", text="") + + def draw(self, context): + ob = context.active_object + gpd = ob.data + gpl = gpd.layers.active + + layout = self.layout + layout.enabled = gpl.use_mask_layer + + if gpl: + rows = 4 + row = layout.row() + col = row.column() + col.template_list("GPENCIL_UL_masks", "", gpl, "mask_layers", gpl.mask_layers, + "active_mask_index", rows=rows, sort_lock=True) + + col2 = row.column(align=True) + col2.menu("GPENCIL_MT_layer_mask_menu", icon='ADD', text="") + col2.operator("gpencil.layer_mask_remove", icon='REMOVE', text="") + + class GreasePencilLayerRelationsPanel: def draw(self, context): @@ -952,20 +892,58 @@ class GreasePencilLayerDisplayPanel: col.prop(gpl, "use_solo_mode", text="Show Only On Keyframed") -classes = ( - GPENCIL_MT_pie_tool_palette, - GPENCIL_MT_pie_settings_palette, - GPENCIL_MT_pie_tools_more, - GPENCIL_MT_pie_sculpt, +class GreasePencilFlipTintColors(Operator): + bl_label = "Flip Colors" + bl_idname = "gpencil.tint_flip" + bl_description = "Switch Tint colors" + + def execute(self, context): + try: + ts = context.tool_settings + settings = None + if context.mode == 'PAINT_GPENCIL': + settings = ts.gpencil_paint + if context.mode == 'SCULPT_GPENCIL': + settings = ts.gpencil_sculpt_paint + elif context.mode == 'WEIGHT_GPENCIL': + settings = ts.gpencil_weight_paint + elif context.mode == 'VERTEX_GPENCIL': + settings = ts.gpencil_vertex_paint + brush = settings.brush + if brush is not None: + 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'} + + except Exception as e: + utils_core.error_handlers(self, "gpencil.tint_flip", e, + "Flip Colors could not be completed") + + return {'CANCELLED'} + + +classes = ( GPENCIL_MT_snap, GPENCIL_MT_cleanup, GPENCIL_MT_move_to_layer, + GPENCIL_MT_layer_active, GPENCIL_MT_gpencil_draw_delete, + GPENCIL_MT_layer_mask_menu, GPENCIL_UL_annotation_layer, GPENCIL_UL_layer, + GPENCIL_UL_masks, + + GreasePencilFlipTintColors, ) if __name__ == "__main__": # only for live edit. diff --git a/release/scripts/startup/bl_ui/properties_material_gpencil.py b/release/scripts/startup/bl_ui/properties_material_gpencil.py index 4f419ec1f18..56201b29e7f 100644 --- a/release/scripts/startup/bl_ui/properties_material_gpencil.py +++ b/release/scripts/startup/bl_ui/properties_material_gpencil.py @@ -47,6 +47,11 @@ class GPENCIL_MT_color_context_menu(Menu): layout.separator() layout.operator("object.material_slot_remove_unused") + layout.operator("gpencil.stroke_merge_material", text="Merge Similar") + + layout.separator() + layout.operator("gpencil.material_to_vertex_color", text="Convert Materials to Vertex Color") + layout.operator("gpencil.extract_palette_vertex", text="Extract Palette from Vertex Color") class GPENCIL_UL_matslots(UIList): @@ -142,27 +147,25 @@ class MATERIAL_PT_gpencil_strokecolor(GPMaterialButtonsPanel, Panel): col.prop(gpcolor, "stroke_style", text="Style") + row = col.row() + row.prop(gpcolor, "color", text="Base Color") + if gpcolor.stroke_style == 'TEXTURE': row = col.row() row.enabled = not gpcolor.lock col = row.column(align=True) col.template_ID(gpcolor, "stroke_image", open="image.open") + + if gpcolor.stroke_style == 'TEXTURE': + row = col.row() + row.prop(gpcolor, "mix_stroke_factor", text="Blend", slider=True) if gpcolor.mode == 'LINE': col.prop(gpcolor, "pixel_size", text="UV Factor") - col.prop(gpcolor, "use_stroke_pattern", text="Use As Stencil Mask") - if gpcolor.use_stroke_pattern is False: - col.prop(gpcolor, "use_stroke_texture_mix", text="Mix Color") - if gpcolor.use_stroke_texture_mix is True: - col.prop(gpcolor, "mix_stroke_factor", text="Factor") - - if (gpcolor.stroke_style == 'SOLID' or gpcolor.use_stroke_pattern or gpcolor.use_stroke_texture_mix): - col.prop(gpcolor, "color", text="Color") - if gpcolor.mode in {'DOTS', 'BOX'}: col.prop(gpcolor, "alignment_mode") - if gpcolor.mode == 'LINE' and gpcolor.stroke_style != 'TEXTURE': + if gpcolor.mode == 'LINE': col.prop(gpcolor, "use_overlap_strokes") @@ -188,55 +191,35 @@ class MATERIAL_PT_gpencil_fillcolor(GPMaterialButtonsPanel, Panel): col.enabled = not gpcolor.lock col.prop(gpcolor, "fill_style", text="Style") - if gpcolor.fill_style == 'GRADIENT': - col.prop(gpcolor, "gradient_type") - if gpcolor.fill_style != 'TEXTURE': - col.prop(gpcolor, "fill_color", text="Color") + if gpcolor.fill_style == 'SOLID': + col.prop(gpcolor, "fill_color", text="Base Color") - if gpcolor.fill_style in {'GRADIENT', 'CHECKER'}: - col.prop(gpcolor, "mix_color", text="Secondary Color") - - if gpcolor.fill_style == 'GRADIENT': - col.prop(gpcolor, "mix_factor", text="Mix Factor", slider=True) - - if gpcolor.fill_style in {'GRADIENT', 'CHECKER'}: - col.prop(gpcolor, "flip", text="Flip Colors") - - col.prop(gpcolor, "pattern_shift", text="Location") - col.prop(gpcolor, "pattern_scale", text="Scale") + elif gpcolor.fill_style == 'GRADIENT': + col.prop(gpcolor, "gradient_type") - if gpcolor.gradient_type == 'RADIAL' and gpcolor.fill_style not in {'SOLID', 'CHECKER'}: - col.prop(gpcolor, "pattern_radius", text="Radius") - else: - if gpcolor.fill_style != 'SOLID': - col.prop(gpcolor, "pattern_angle", text="Angle") + col.prop(gpcolor, "fill_color", text="Base Color") + col.prop(gpcolor, "mix_color", text="Secondary Color") + col.prop(gpcolor, "mix_factor", text="Blend in Fill Gradient", slider=True) + col.prop(gpcolor, "flip", text="Flip Colors") - if gpcolor.fill_style == 'CHECKER': - col.prop(gpcolor, "pattern_gridsize", text="Box Size") + col.prop(gpcolor, "texture_offset", text="Location") + col.prop(gpcolor, "texture_scale", text="Scale") + if gpcolor.gradient_type == 'LINEAR': + col.prop(gpcolor, "texture_angle", text="Rotation") - # Texture - if gpcolor.fill_style == 'TEXTURE' or (gpcolor.use_fill_texture_mix is True and gpcolor.fill_style == 'SOLID'): + elif gpcolor.fill_style == 'TEXTURE': col.template_ID(gpcolor, "fill_image", open="image.open") - if gpcolor.fill_style == 'TEXTURE': - col.prop(gpcolor, "use_fill_pattern", text="Use as Stencil Mask") - if gpcolor.use_fill_pattern is True: - col.prop(gpcolor, "fill_color", text="Color") + col.prop(gpcolor, "fill_color", text="Base Color") + col.prop(gpcolor, "texture_opacity", slider=True) + col.prop(gpcolor, "mix_factor", text="Blend in Fill Texture", slider=True) - col.prop(gpcolor, "texture_offset", text="Offset") + col.prop(gpcolor, "texture_offset", text="Location") + col.prop(gpcolor, "texture_angle", text="Rotation") col.prop(gpcolor, "texture_scale", text="Scale") - col.prop(gpcolor, "texture_angle") - col.prop(gpcolor, "texture_opacity") col.prop(gpcolor, "texture_clamp", text="Clip Image") - if gpcolor.use_fill_pattern is False: - col.prop(gpcolor, "use_fill_texture_mix", text="Mix with Color") - - if gpcolor.use_fill_texture_mix is True: - col.prop(gpcolor, "fill_color", text="Mix Color") - col.prop(gpcolor, "mix_factor", text="Mix Factor", slider=True) - class MATERIAL_PT_gpencil_preview(GPMaterialButtonsPanel, Panel): bl_label = "Preview" @@ -291,5 +274,6 @@ classes = ( if __name__ == "__main__": # only for live edit. from bpy.utils import register_class + for cls in classes: register_class(cls) diff --git a/release/scripts/startup/bl_ui/properties_object.py b/release/scripts/startup/bl_ui/properties_object.py index bb020084b03..33ba981e235 100644 --- a/release/scripts/startup/bl_ui/properties_object.py +++ b/release/scripts/startup/bl_ui/properties_object.py @@ -397,6 +397,27 @@ class OBJECT_PT_visibility(ObjectButtonsPanel, Panel): col.prop(ob, "hide_select", text="Selectable", toggle=False, invert_checkbox=True) +class OBJECT_PT_greasepencil_light(ObjectButtonsPanel, Panel): + bl_label = "Grease Pencil" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} + + @classmethod + def poll(cls, context): + return (context.object) and (context.engine in cls.COMPAT_ENGINES) and (context.object.type == 'GPENCIL') + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + + flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False) + layout = self.layout + ob = context.object + + col = flow.column() + col.prop(ob, "use_grease_pencil_lights", toggle=False) + + class OBJECT_PT_custom_props(ObjectButtonsPanel, PropertyPanel, Panel): COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} _context_path = "object" @@ -417,6 +438,7 @@ classes = ( OBJECT_PT_display, OBJECT_PT_display_bounds, OBJECT_PT_visibility, + OBJECT_PT_greasepencil_light, OBJECT_PT_custom_props, ) diff --git a/release/scripts/startup/bl_ui/properties_paint_common.py b/release/scripts/startup/bl_ui/properties_paint_common.py index f1f6e9898b1..df3dc930f97 100644 --- a/release/scripts/startup/bl_ui/properties_paint_common.py +++ b/release/scripts/startup/bl_ui/properties_paint_common.py @@ -89,8 +89,12 @@ class UnifiedPaintPanel: # Grease Pencil settings elif mode == 'PAINT_GPENCIL': return tool_settings.gpencil_paint - elif mode in {'SCULPT_GPENCIL', 'WEIGHT_GPENCIL'}: - return tool_settings.gpencil_sculpt + elif mode == 'SCULPT_GPENCIL': + return tool_settings.gpencil_sculpt_paint + elif mode == 'WEIGHT_GPENCIL': + return tool_settings.gpencil_weight_paint + elif mode == 'VERTEX_GPENCIL': + return tool_settings.gpencil_vertex_paint return None @staticmethod @@ -1019,6 +1023,8 @@ def brush_basic_texpaint_settings(layout, context, brush, *, compact=False): def brush_basic_gpencil_paint_settings(layout, context, brush, *, compact=False): + tool_settings = context.tool_settings + settings = tool_settings.gpencil_paint gp_settings = brush.gpencil_settings tool = context.workspace.tools.from_space_view3d_mode(context.mode, create=False) if gp_settings is None: @@ -1043,7 +1049,7 @@ def brush_basic_gpencil_paint_settings(layout, context, brush, *, compact=False) row.prop(gp_settings, "eraser_thickness_factor") row = layout.row(align=True) - row.prop(gp_settings, "use_cursor", text="Display Cursor") + row.prop(settings, "show_brush", text="Display Cursor") # FIXME: tools must use their own UI drawing! elif brush.gpencil_tool == 'FILL': @@ -1091,52 +1097,63 @@ def brush_basic_gpencil_paint_settings(layout, context, brush, *, compact=False) def brush_basic_gpencil_sculpt_settings(layout, context, brush, *, compact=False): - tool_settings = context.tool_settings - settings = tool_settings.gpencil_sculpt - tool = settings.sculpt_tool + gp_settings = brush.gpencil_settings + tool = brush.gpencil_sculpt_tool row = layout.row(align=True) row.prop(brush, "size", slider=True) sub = row.row(align=True) sub.enabled = tool not in {'GRAB', 'CLONE'} - sub.prop(brush, "use_pressure_radius", text="") + sub.prop(gp_settings, "use_pressure", text="") row = layout.row(align=True) row.prop(brush, "strength", slider=True) row.prop(brush, "use_pressure_strength", text="") - layout.prop(brush, "use_falloff") - if compact: if tool in {'THICKNESS', 'STRENGTH', 'PINCH', 'TWIST'}: row.separator() - row.prop(brush, "direction", expand=True, text="") + row.prop(gp_settings, "direction", expand=True, text="") else: use_property_split_prev = layout.use_property_split layout.use_property_split = False if tool in {'THICKNESS', 'STRENGTH'}: - layout.row().prop(brush, "direction", expand=True) + layout.row().prop(gp_settings, "direction", expand=True) elif tool == 'PINCH': row = layout.row(align=True) - row.prop_enum(brush, "direction", value='ADD', text="Pinch") - row.prop_enum(brush, "direction", value='SUBTRACT', text="Inflate") + row.prop_enum(gp_settings, "direction", value='ADD', text="Pinch") + row.prop_enum(gp_settings, "direction", value='SUBTRACT', text="Inflate") elif tool == 'TWIST': row = layout.row(align=True) - row.prop_enum(brush, "direction", value='ADD', text="CCW") - row.prop_enum(brush, "direction", value='SUBTRACT', text="CW") + row.prop_enum(gp_settings, "direction", value='ADD', text="CCW") + row.prop_enum(gp_settings, "direction", value='SUBTRACT', text="CW") layout.use_property_split = use_property_split_prev def brush_basic_gpencil_weight_settings(layout, _context, brush, *, compact=False): + gp_settings = brush.gpencil_settings layout.prop(brush, "size", slider=True) row = layout.row(align=True) row.prop(brush, "strength", slider=True) row.prop(brush, "use_pressure_strength", text="") + layout.prop(brush, "weight", slider=True) - layout.prop(brush, "use_falloff") +def brush_basic_gpencil_vertex_settings(layout, _context, brush, *, compact=False): + gp_settings = brush.gpencil_settings + + # Brush details + row = layout.row(align=True) + row.prop(brush, "size", text="Radius") + row.prop(gp_settings, "use_pressure", text="", icon='STYLUS_PRESSURE') + + if brush.gpencil_vertex_tool in {'DRAW', 'BLUR', 'SMEAR'}: + row = layout.row(align=True) + row.prop(gp_settings, "pen_strength", slider=True) + row.prop(gp_settings, "use_strength_pressure", text="", icon='STYLUS_PRESSURE') + classes = ( VIEW3D_MT_tools_projectpaint_clone, ) diff --git a/release/scripts/startup/bl_ui/space_dopesheet.py b/release/scripts/startup/bl_ui/space_dopesheet.py index a09e263fd87..41adea0b922 100644 --- a/release/scripts/startup/bl_ui/space_dopesheet.py +++ b/release/scripts/startup/bl_ui/space_dopesheet.py @@ -26,6 +26,7 @@ from bpy.types import ( ) from bl_ui.properties_grease_pencil_common import ( + GreasePencilLayerMasksPanel, GreasePencilLayerAdjustmentsPanel, GreasePencilLayerRelationsPanel, GreasePencilLayerDisplayPanel, @@ -699,6 +700,15 @@ class DOPESHEET_PT_gpencil_mode(LayersDopeSheetPanel, Panel): row = layout.row(align=True) row.prop(gpl, "opacity", text="Opacity", slider=True) + row = layout.row(align=True) + row.prop(gpl, "use_lights") + + +class DOPESHEET_PT_gpencil_layer_masks(LayersDopeSheetPanel, GreasePencilLayerMasksPanel, Panel): + bl_label = "Masks" + bl_parent_id = 'DOPESHEET_PT_gpencil_mode' + bl_options = {'DEFAULT_CLOSED'} + class DOPESHEET_PT_gpencil_layer_adjustments(LayersDopeSheetPanel, GreasePencilLayerAdjustmentsPanel, Panel): bl_label = "Adjustments" @@ -736,6 +746,7 @@ classes = ( DOPESHEET_MT_snap_pie, DOPESHEET_PT_filters, DOPESHEET_PT_gpencil_mode, + DOPESHEET_PT_gpencil_layer_masks, DOPESHEET_PT_gpencil_layer_adjustments, DOPESHEET_PT_gpencil_layer_relations, DOPESHEET_PT_gpencil_layer_display, diff --git a/release/scripts/startup/bl_ui/space_image.py b/release/scripts/startup/bl_ui/space_image.py index c6f490f9d26..980f89eaaa4 100644 --- a/release/scripts/startup/bl_ui/space_image.py +++ b/release/scripts/startup/bl_ui/space_image.py @@ -238,6 +238,11 @@ class IMAGE_MT_image(Menu): layout.separator() layout.operator("image.pack", text="Pack") + if ima: + layout.separator() + layout.operator("palette.extract_from_image", text="Extract Palette") + layout.operator("gpencil.image_to_grease_pencil", text="Generate Grease Pencil") + class IMAGE_MT_image_invert(Menu): bl_label = "Invert" diff --git a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py index 63fb72a71bd..583d8ea44cf 100644 --- a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py +++ b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py @@ -1455,6 +1455,11 @@ class _defs_gpencil_paint: @ToolDef.from_fn def eyedropper(): + def draw_settings(context, layout, tool): + props = tool.operator_properties("ui.eyedropper_gpencil_color") + row = layout.row() + row.use_property_split = False + row.prop(props, "mode", expand=True) return dict( idname="builtin.eyedropper", label="Eyedropper", @@ -1462,6 +1467,7 @@ class _defs_gpencil_paint: cursor='EYEDROPPER', widget=None, keymap=(), + draw_settings=draw_settings, ) @@ -1594,6 +1600,23 @@ class _defs_gpencil_edit: draw_settings=_template_widget.VIEW3D_GGT_xform_extrude.draw_settings, ) + @ToolDef.from_fn + def transform_fill(): + def draw_settings(context, layout, tool): + props = tool.operator_properties("gpencil.transform_fill") + row = layout.row() + row.use_property_split = False + row.prop(props, "mode", expand=True) + + return dict( + idname="builtin.transform_fill", + label="Transform Fill", + icon="ops.gpencil.transform_fill", + cursor='DEFAULT', + widget=None, + keymap=(), + draw_settings=draw_settings, + ) class _defs_gpencil_sculpt: @@ -1613,11 +1636,10 @@ class _defs_gpencil_sculpt: context, idname_prefix="builtin_brush.", icon_prefix="ops.gpencil.sculpt_", - type=bpy.types.GPencilSculptSettings, - attr="sculpt_tool", + type=bpy.types.Brush, + attr="gpencil_sculpt_tool", tooldef_keywords=dict( operator="gpencil.sculpt_paint", - keymap="3D View Tool: Sculpt Gpencil, Paint", ), ) @@ -1630,11 +1652,37 @@ class _defs_gpencil_weight: context, idname_prefix="builtin_brush.", icon_prefix="ops.gpencil.sculpt_", - type=bpy.types.GPencilSculptSettings, - attr="weight_tool", + type=bpy.types.Brush, + attr="gpencil_weight_tool", tooldef_keywords=dict( - operator="gpencil.sculpt_paint", - keymap="3D View Tool: Sculpt Gpencil, Paint", + operator="gpencil.weight_paint", + ), + ) + + +class _defs_gpencil_vertex: + + @staticmethod + def poll_select_mask(context): + if context is None: + return True + ob = context.active_object + ts = context.scene.tool_settings + return ob and ob.type == 'GPENCIL' and (ts.use_gpencil_vertex_select_mask_point or + ts.use_gpencil_vertex_select_mask_stroke or + ts.use_gpencil_vertex_select_mask_segment) + + @staticmethod + def generate_from_brushes(context): + return generate_from_enum_ex( + context, + idname_prefix="builtin_brush.", + icon_prefix="brush.paint_vertex.", + type=bpy.types.Brush, + attr="gpencil_vertex_tool", + cursor='DOT', + tooldef_keywords=dict( + operator="gpencil.vertex_paint", ), ) @@ -2202,6 +2250,8 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel): _defs_gpencil_edit.tosphere, ), None, + _defs_gpencil_edit.transform_fill, + None, *_tools_annotate, ], 'SCULPT_GPENCIL': [ @@ -2219,6 +2269,17 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel): None, *_tools_annotate, ], + 'VERTEX_GPENCIL': [ + _defs_gpencil_vertex.generate_from_brushes, + None, + *_tools_annotate, + None, + lambda context: ( + VIEW3D_PT_tools_active._tools_gpencil_select + if _defs_gpencil_vertex.poll_select_mask(context) + else () + ), + ], } class SEQUENCER_PT_tools_active(ToolSelectPanelHelper, Panel): bl_space_type = 'SEQUENCE_EDITOR' diff --git a/release/scripts/startup/bl_ui/space_topbar.py b/release/scripts/startup/bl_ui/space_topbar.py index 192b239ac03..1f52323f540 100644 --- a/release/scripts/startup/bl_ui/space_topbar.py +++ b/release/scripts/startup/bl_ui/space_topbar.py @@ -165,11 +165,11 @@ class TOPBAR_PT_gpencil_layers(Panel): srow = col.row(align=True) srow.prop(gpl, "opacity", text="Opacity", slider=True) - srow.prop(gpl, "mask_layer", text="", - icon='MOD_MASK' if gpl.mask_layer else 'LAYER_ACTIVE') + srow.prop(gpl, "use_mask_layer", text="", + icon='MOD_MASK' if gpl.use_mask_layer else 'LAYER_ACTIVE') srow = col.row(align=True) - srow.prop(gpl, "use_solo_mode", text="Show Only On Keyframed") + srow.prop(gpl, "use_lights") col = row.column() diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py index c3c99ebb826..b8051a1d98a 100644 --- a/release/scripts/startup/bl_ui/space_userpref.py +++ b/release/scripts/startup/bl_ui/space_userpref.py @@ -668,7 +668,6 @@ class USERPREF_PT_viewport_quality(ViewportPanel, CenterAlignMixIn, Panel): flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False) flow.prop(system, "viewport_aa") - flow.prop(system, "gpencil_multi_sample", text="Grease Pencil Multisampling") flow.prop(system, "use_overlay_smooth_wire") flow.prop(system, "use_edit_mode_smooth_wire") diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 078ad967789..447386b8f9d 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -31,6 +31,7 @@ from bl_ui.properties_grease_pencil_common import ( AnnotationDataPanel, AnnotationOnionSkin, GreasePencilMaterialsPanel, + GreasePencilVertexcolorPanel, ) from bl_ui.space_toolsystem_common import ( ToolActivePanelHelper, @@ -119,21 +120,27 @@ class VIEW3D_HT_tool_header(Header): if is_valid_context: brush = context.tool_settings.gpencil_paint.brush if brush.gpencil_tool != 'ERASE': - layout.popover("VIEW3D_PT_tools_grease_pencil_brush_advanced") + if brush.gpencil_tool != 'TINT': + layout.popover("VIEW3D_PT_tools_grease_pencil_brush_advanced") - if brush.gpencil_tool != 'FILL': + if brush.gpencil_tool not in {'FILL', 'TINT'}: layout.popover("VIEW3D_PT_tools_grease_pencil_brush_stroke") layout.popover("VIEW3D_PT_tools_grease_pencil_brushcurves") layout.popover("VIEW3D_PT_tools_grease_pencil_paint_appearance") elif tool_mode == 'SCULPT_GPENCIL': - settings = context.tool_settings.gpencil_sculpt - tool = settings.sculpt_tool - if tool in {'SMOOTH', 'RANDOMIZE', 'SMOOTH'}: - layout.popover("VIEW3D_PT_tools_grease_pencil_sculpt_options") - layout.popover("VIEW3D_PT_tools_grease_pencil_sculpt_appearance") + if is_valid_context: + brush = context.tool_settings.gpencil_sculpt_paint.brush + tool = brush.gpencil_tool + if tool in ('SMOOTH', 'RANDOMIZE'): + layout.popover("VIEW3D_PT_tools_grease_pencil_sculpt_options") + layout.popover("VIEW3D_PT_tools_grease_pencil_sculpt_appearance") elif tool_mode == 'WEIGHT_GPENCIL': - layout.popover("VIEW3D_PT_tools_grease_pencil_weight_appearance") + if is_valid_context: + layout.popover("VIEW3D_PT_tools_grease_pencil_weight_appearance") + elif tool_mode == 'VERTEX_GPENCIL': + if is_valid_context: + layout.popover("VIEW3D_PT_tools_grease_pencil_vertex_appearance") def draw_mode_settings(self, context): layout = self.layout @@ -425,6 +432,15 @@ class _draw_tool_settings_context_mode: row.prop(gp_settings, "use_material_pin", text="") + if brush.gpencil_tool in {'DRAW', 'FILL'} and ma: + row.separator(factor=1.0) + subrow = row.row(align=True) + row.prop_enum(settings, "color_mode", 'MATERIAL', text="", icon='MATERIAL') + row.prop_enum(settings, "color_mode", 'VERTEXCOLOR', text="", icon='VPAINT_HLT') + sub_row = row.row(align=True) + sub_row.enabled = settings.color_mode == 'VERTEXCOLOR' + sub_row.prop_with_popover(brush, "color", text="", panel="TOPBAR_PT_gpencil_vertexcolor") + row = layout.row(align=True) tool_settings = context.scene.tool_settings settings = tool_settings.gpencil_paint @@ -433,6 +449,10 @@ class _draw_tool_settings_context_mode: if context.object and brush.gpencil_tool in {'FILL', 'DRAW'}: draw_color_selector() + if context.object and brush.gpencil_tool == 'TINT': + row.separator(factor=0.4) + row.prop_with_popover(brush, "color", text="", panel="TOPBAR_PT_gpencil_vertexcolor") + from bl_ui.properties_paint_common import ( brush_basic_gpencil_paint_settings, ) @@ -444,9 +464,8 @@ class _draw_tool_settings_context_mode: def SCULPT_GPENCIL(context, layout, tool): if (tool is None) or (not tool.has_datablock): return False - tool_settings = context.tool_settings - settings = tool_settings.gpencil_sculpt - brush = settings.brush + paint = context.tool_settings.gpencil_sculpt_paint + brush = paint.brush from bl_ui.properties_paint_common import ( brush_basic_gpencil_sculpt_settings, @@ -459,9 +478,8 @@ class _draw_tool_settings_context_mode: def WEIGHT_GPENCIL(context, layout, tool): if (tool is None) or (not tool.has_datablock): return False - tool_settings = context.tool_settings - settings = tool_settings.gpencil_sculpt - brush = settings.brush + paint = context.tool_settings.gpencil_weight_paint + brush = paint.brush from bl_ui.properties_paint_common import ( brush_basic_gpencil_weight_settings, @@ -471,6 +489,31 @@ class _draw_tool_settings_context_mode: return True @staticmethod + def VERTEX_GPENCIL(context, layout, tool): + if (tool is None) or (not tool.has_datablock): + return False + + paint = context.tool_settings.gpencil_vertex_paint + brush = paint.brush + + row = layout.row(align=True) + tool_settings = context.scene.tool_settings + settings = tool_settings.gpencil_vertex_paint + row.template_ID_preview(settings, "brush", rows=3, cols=8, hide_buttons=True) + + if brush.gpencil_vertex_tool not in {'BLUR', 'AVERAGE', 'SMEAR'}: + row.separator(factor=0.4) + row.prop_with_popover(brush, "color", text="", panel="TOPBAR_PT_gpencil_vertexcolor") + + from bl_ui.properties_paint_common import ( + brush_basic_gpencil_vertex_settings, + ) + + brush_basic_gpencil_vertex_settings(layout, context, brush, compact=True) + + return True + + @staticmethod def PARTICLE(context, layout, tool): if (tool is None) or (not tool.has_datablock): return False @@ -550,7 +593,7 @@ class VIEW3D_HT_header(Header): else: if (object_mode not in { 'SCULPT', 'VERTEX_PAINT', 'WEIGHT_PAINT', 'TEXTURE_PAINT', - 'PAINT_GPENCIL', 'SCULPT_GPENCIL', 'WEIGHT_GPENCIL' + 'PAINT_GPENCIL', 'SCULPT_GPENCIL', 'WEIGHT_GPENCIL', 'VERTEX_GPENCIL' }) or has_pose_mode: show_snap = True else: @@ -687,7 +730,14 @@ class VIEW3D_HT_header(Header): row.prop(tool_settings, "use_gpencil_select_mask_stroke", text="") row.prop(tool_settings, "use_gpencil_select_mask_segment", text="") - if gpd.use_stroke_edit_mode or gpd.is_stroke_sculpt_mode or gpd.is_stroke_weight_mode: + # Select mode for Vertex Paint + if gpd.is_stroke_vertex_mode: + row = layout.row(align=True) + row.prop(tool_settings, "use_gpencil_vertex_select_mask_point", text="") + row.prop(tool_settings, "use_gpencil_vertex_select_mask_stroke", text="") + row.prop(tool_settings, "use_gpencil_vertex_select_mask_segment", text="") + + if gpd.use_stroke_edit_mode or gpd.is_stroke_sculpt_mode or gpd.is_stroke_weight_mode or gpd.is_stroke_vertex_mode: row = layout.row(align=True) row.prop(gpd, "use_multiedit", text="", icon='GP_MULTIFRAME_EDITING') @@ -812,7 +862,8 @@ class VIEW3D_MT_editor_menus(Menu): obj = context.active_object mode_string = context.mode edit_object = context.edit_object - gp_edit = obj and obj.mode in {'EDIT_GPENCIL', 'PAINT_GPENCIL', 'SCULPT_GPENCIL', 'WEIGHT_GPENCIL'} + gp_edit = obj and obj.mode in {'EDIT_GPENCIL', 'PAINT_GPENCIL', 'SCULPT_GPENCIL', + 'WEIGHT_GPENCIL', 'VERTEX_GPENCIL'} ts = context.scene.tool_settings layout.menu("VIEW3D_MT_view") @@ -827,6 +878,8 @@ class VIEW3D_MT_editor_menus(Menu): layout.menu("VIEW3D_MT_select_gpencil") elif mode_string == 'EDIT_GPENCIL': layout.menu("VIEW3D_MT_select_gpencil") + elif mode_string == 'VERTEX_GPENCIL': + layout.menu("VIEW3D_MT_select_gpencil") elif mode_string in {'PAINT_WEIGHT', 'PAINT_VERTEX', 'PAINT_TEXTURE'}: mesh = obj.data if mesh.use_paint_mask: @@ -4650,6 +4703,10 @@ class VIEW3D_MT_paint_gpencil(Menu): layout = self.layout + layout.menu("GPENCIL_MT_layer_active", text="Active Layer") + + layout.separator() + layout.menu("VIEW3D_MT_gpencil_animation") layout.menu("VIEW3D_MT_edit_gpencil_interpolate") @@ -4708,6 +4765,10 @@ class VIEW3D_MT_edit_gpencil(Menu): layout.separator() + layout.menu("GPENCIL_MT_layer_active", text="Active Layer") + + layout.separator() + layout.menu("VIEW3D_MT_gpencil_animation") layout.menu("VIEW3D_MT_edit_gpencil_interpolate") @@ -4742,6 +4803,7 @@ class VIEW3D_MT_edit_gpencil_stroke(Menu): def draw(self, _context): layout = self.layout + settings = _context.tool_settings.gpencil_sculpt layout.operator("gpencil.stroke_subdivide", text="Subdivide").only_selected = False layout.menu("VIEW3D_MT_gpencil_simplify") @@ -4767,6 +4829,10 @@ class VIEW3D_MT_edit_gpencil_stroke(Menu): layout.operator("gpencil.stroke_cyclical_set", text="Toggle Cyclic").type = 'TOGGLE' layout.operator_menu_enum("gpencil.stroke_caps_set", text="Toggle Caps", property="type") layout.operator("gpencil.stroke_flip", text="Switch Direction") + layout.prop(settings, "use_scale_thickness") + + layout.separator() + layout.operator("gpencil.reset_transform_fill", text="Reset Fill Transform") class VIEW3D_MT_edit_gpencil_point(Menu): @@ -4811,6 +4877,22 @@ class VIEW3D_MT_weight_gpencil(Menu): layout.menu("VIEW3D_MT_gpencil_autoweights") +class VIEW3D_MT_vertex_gpencil(Menu): + bl_label = "Paint" + + def draw(self, _context): + layout = self.layout + layout.operator("gpencil.vertex_color_set", text="Set Vertex Colors") + layout.separator() + layout.operator("gpencil.vertex_color_invert", text="Invert") + layout.operator("gpencil.vertex_color_levels", text="Levels") + layout.operator("gpencil.vertex_color_hsv", text="Hue Saturation Value") + layout.operator("gpencil.vertex_color_brightness_contrast", text="Bright/Contrast") + + layout.separator() + layout.menu("VIEW3D_MT_join_palette") + + class VIEW3D_MT_gpencil_animation(Menu): bl_label = "Animation" @@ -6473,6 +6555,7 @@ class VIEW3D_PT_overlay_gpencil_options(Panel): 'EDIT_GPENCIL': "Edit Grease Pencil", 'SCULPT_GPENCIL': "Sculpt Grease Pencil", 'WEIGHT_GPENCIL': "Weight Grease Pencil", + 'VERTEX_GPENCIL': "Vertex Grease Pencil", 'OBJECT': "Grease Pencil", }[context.mode]) @@ -6497,17 +6580,32 @@ class VIEW3D_PT_overlay_gpencil_options(Panel): sub.prop(overlay, "gpencil_fade_layer", text="Fade Layers", slider=True) row = col.row() - row.prop(overlay, "use_gpencil_paper", text="") + row.prop(overlay, "use_gpencil_fade_objects", text="") sub = row.row(align=True) - sub.active = overlay.use_gpencil_paper - sub.prop(overlay, "gpencil_paper_opacity", text="Fade Objects", slider=True) - sub.prop(overlay, "use_gpencil_fade_objects", text="", icon='OUTLINER_OB_GREASEPENCIL') + sub.active = overlay.use_gpencil_fade_objects + sub.prop(overlay, "gpencil_fade_objects", text="Fade Objects", slider=True) + sub.prop(overlay, "use_gpencil_fade_gp_objects", text="", icon='OUTLINER_OB_GREASEPENCIL') + + if context.object.mode in {'EDIT_GPENCIL', 'SCULPT_GPENCIL', 'WEIGHT_GPENCIL', 'VERTEX_GPENCIL'}: + split = layout.split() + col = split.column() + col.prop(overlay, "use_gpencil_edit_lines", text="Edit Lines") + col = split.column() + col.prop(overlay, "use_gpencil_multiedit_line_only", text="Only in Multiframe") + + if context.object.mode == 'EDIT_GPENCIL': + split = layout.split() + col = split.column() + col.prop(overlay, "use_gpencil_show_directions") + col = split.column() + col.prop(overlay, "use_gpencil_show_material_name", text="Material Name") - if context.object.mode in {'EDIT_GPENCIL', 'SCULPT_GPENCIL', 'WEIGHT_GPENCIL'}: - layout.prop(overlay, "use_gpencil_edit_lines", text="Edit Lines") - layout.prop(overlay, "use_gpencil_multiedit_line_only", text="Show Edit Lines only in multiframe") layout.prop(overlay, "vertex_opacity", text="Vertex Opacity", slider=True) + if context.object.mode in {'PAINT_GPENCIL', 'VERTEX_GPENCIL'}: + layout.label(text="Vertex Paint") + layout.prop(overlay, "gpencil_vertex_paint_opacity", text="Opacity", slider=True) + class VIEW3D_PT_quad_view(Panel): bl_space_type = 'VIEW_3D' @@ -6783,77 +6881,127 @@ class VIEW3D_MT_gpencil_edit_context_menu(Menu): col.operator("gpencil.reproject", text="Reproject Strokes") +def draw_gpencil_layer_active(context, layout): + gpl = context.active_gpencil_layer + if gpl: + layout.label(text="Active Layer") + row = layout.row(align=True) + row.operator_context = 'EXEC_REGION_WIN' + row.operator_menu_enum("gpencil.layer_change", "layer", text="", icon='GREASEPENCIL') + row.prop(gpl, "info", text="") + row.operator("gpencil.layer_remove", text="", icon='X') + + class VIEW3D_PT_gpencil_sculpt_context_menu(Panel): bl_space_type = 'VIEW_3D' bl_region_type = 'WINDOW' bl_label = "Sculpt Context Menu" + bl_ui_units_x = 12 def draw(self, context): - brush = context.tool_settings.gpencil_sculpt.brush + ts = context.tool_settings + settings = ts.gpencil_paint + brush = settings.brush layout = self.layout - if context.mode == 'WEIGHT_GPENCIL': - layout.prop(brush, "weight") layout.prop(brush, "size", slider=True) layout.prop(brush, "strength") - layout.separator() - - # Frames - layout.label(text="Frames:") + # Layers + draw_gpencil_layer_active(context, layout) - layout.operator_context = 'INVOKE_REGION_WIN' - layout.operator("gpencil.blank_frame_add", text="Insert Blank in Active Layer", icon='ADD') - layout.operator("gpencil.blank_frame_add", text="Insert Blank in All Layers", icon='ADD').all_layers = True +class VIEW3D_PT_gpencil_weight_context_menu(Panel): + bl_space_type = 'VIEW_3D' + bl_region_type = 'WINDOW' + bl_label = "Weight Paint Context Menu" + bl_ui_units_x = 12 - layout.separator() + def draw(self, context): + ts = context.tool_settings + settings = ts.gpencil_paint + brush = settings.brush - layout.operator("gpencil.frame_duplicate", text="Duplicate Active Layer", icon='DUPLICATE') - layout.operator("gpencil.frame_duplicate", text="Duplicate All Layers", icon='DUPLICATE').mode = 'ALL' + layout = self.layout - layout.separator() + layout.prop(brush, "size", slider=True) + layout.prop(brush, "strength") + layout.prop(brush, "weight") - layout.operator("gpencil.delete", text="Delete Active Layer", icon='REMOVE').type = 'FRAME' - layout.operator("gpencil.active_frames_delete_all", text="Delete All Layers", icon='REMOVE') + # Layers + draw_gpencil_layer_active(context, layout) class VIEW3D_PT_gpencil_draw_context_menu(Panel): bl_space_type = 'VIEW_3D' bl_region_type = 'WINDOW' bl_label = "Draw Context Menu" + bl_ui_units_x = 12 def draw(self, context): - brush = context.tool_settings.gpencil_paint.brush + ts = context.tool_settings + settings = ts.gpencil_paint + brush = settings.brush gp_settings = brush.gpencil_settings layout = self.layout + if brush.gpencil_tool not in {'ERASE', 'CUTTER', 'EYEDROPPER'} and settings.color_mode == 'VERTEXCOLOR': + split = layout.split(factor=0.1) + split.prop(brush, "color", text="") + split.template_color_picker(brush, "color", value_slider=True) + + col = layout.column() + col.separator() + col.prop_menu_enum(gp_settings, "vertex_mode", text="Mode") + col.separator() + if brush.gpencil_tool not in {'FILL', 'CUTTER'}: layout.prop(brush, "size", slider=True) if brush.gpencil_tool not in {'ERASE', 'FILL', 'CUTTER'}: layout.prop(gp_settings, "pen_strength") - layout.separator() + # Layers + draw_gpencil_layer_active(context, layout) - # Frames - layout.label(text="Frames:") - layout.operator_context = 'INVOKE_REGION_WIN' +class VIEW3D_PT_gpencil_vertex_context_menu(Panel): + bl_space_type = 'VIEW_3D' + bl_region_type = 'WINDOW' + bl_label = "Vertex Paint Context Menu" + bl_ui_units_x = 12 - layout.operator("gpencil.blank_frame_add", text="Insert Blank in Active Layer", icon='ADD') - layout.operator("gpencil.blank_frame_add", text="Insert Blank in All Layers", icon='ADD').all_layers = True + def draw(self, context): + layout = self.layout + ts = context.tool_settings + settings = ts.gpencil_vertex_paint + brush = settings.brush + gp_settings = brush.gpencil_settings - layout.separator() + col = layout.column() - layout.operator("gpencil.frame_duplicate", text="Duplicate Active Layer", icon='DUPLICATE') - layout.operator("gpencil.frame_duplicate", text="Duplicate All Layers", icon='DUPLICATE').mode = 'ALL' + if brush.gpencil_vertex_tool in {'DRAW', 'REPLACE'}: + split = layout.split(factor=0.1) + split.prop(brush, "color", text="") + split.template_color_picker(brush, "color", value_slider=True) - layout.separator() + col = layout.column() + col.separator() + col.prop_menu_enum(gp_settings, "vertex_mode", text="Mode") + col.separator() + + row = col.row(align=True) + row.prop(brush, "size", text="Radius") + row.prop(gp_settings, "use_pressure", text="", icon='STYLUS_PRESSURE') - layout.operator("gpencil.delete", text="Delete Active Layer", icon='REMOVE').type = 'FRAME' - layout.operator("gpencil.active_frames_delete_all", text="Delete All Layers", icon='REMOVE') + if brush.gpencil_vertex_tool in {'DRAW', 'BLUR', 'SMEAR'}: + row = layout.row(align=True) + row.prop(gp_settings, "pen_strength", slider=True) + row.prop(gp_settings, "use_strength_pressure", text="", icon='STYLUS_PRESSURE') + + # Layers + draw_gpencil_layer_active(context, layout) class VIEW3D_PT_paint_vertex_context_menu(Panel): @@ -7037,6 +7185,17 @@ class TOPBAR_PT_gpencil_materials(GreasePencilMaterialsPanel, Panel): return ob and ob.type == 'GPENCIL' +class TOPBAR_PT_gpencil_vertexcolor(GreasePencilVertexcolorPanel, Panel): + bl_space_type = 'VIEW_3D' + bl_region_type = 'HEADER' + bl_label = "Vertex Color" + bl_ui_units_x = 10 + + @classmethod + def poll(cls, context): + ob = context.object + return ob and ob.type == 'GPENCIL' + classes = ( VIEW3D_HT_header, VIEW3D_HT_tool_header, @@ -7163,6 +7322,7 @@ classes = ( VIEW3D_MT_edit_gpencil_delete, VIEW3D_MT_edit_gpencil_showhide, VIEW3D_MT_weight_gpencil, + VIEW3D_MT_vertex_gpencil, VIEW3D_MT_gpencil_animation, VIEW3D_MT_gpencil_simplify, VIEW3D_MT_gpencil_copy_layer, @@ -7249,10 +7409,13 @@ classes = ( VIEW3D_PT_paint_vertex_context_menu, VIEW3D_PT_paint_texture_context_menu, VIEW3D_PT_paint_weight_context_menu, + VIEW3D_PT_gpencil_vertex_context_menu, VIEW3D_PT_gpencil_sculpt_context_menu, + VIEW3D_PT_gpencil_weight_context_menu, VIEW3D_PT_gpencil_draw_context_menu, VIEW3D_PT_sculpt_context_menu, TOPBAR_PT_gpencil_materials, + TOPBAR_PT_gpencil_vertexcolor, TOPBAR_PT_annotation_layers, ) diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py index 1990e9a7260..9ad339b418c 100644 --- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py +++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py @@ -21,6 +21,7 @@ from bpy.types import Menu, Panel, UIList from bl_ui.properties_grease_pencil_common import ( GreasePencilSculptOptionsPanel, GreasePencilDisplayPanel, + GreasePencilBrushFalloff, ) from bl_ui.properties_paint_common import ( UnifiedPaintPanel, @@ -71,6 +72,33 @@ class VIEW3D_MT_brush_context_menu(Menu): layout.operator("brush.reset") +class VIEW3D_MT_brush_gpencil_context_menu(Menu): + bl_label = "Brush Specials" + + def draw(self, context): + layout = self.layout + ts = context.tool_settings + + settings = None + if context.mode == 'PAINT_GPENCIL': + settings = ts.gpencil_paint + if context.mode == 'SCULPT_GPENCIL': + settings = ts.gpencil_sculpt_paint + elif context.mode == 'WEIGHT_GPENCIL': + settings = ts.gpencil_weight_paint + elif context.mode == 'VERTEX_GPENCIL': + settings = ts.gpencil_vertex_paint + + brush = getattr(settings, "brush", None) + # skip if no active brush + if not brush: + layout.label(text="No Brushes currently available", icon='INFO') + return + + layout.operator("gpencil.brush_reset") + layout.operator("gpencil.brush_reset_all") + + class VIEW3D_MT_brush_context_menu_paint_modes(Menu): bl_label = "Enabled Modes" @@ -1339,7 +1367,7 @@ class VIEW3D_PT_tools_particlemode_options_display(View3DPanel, Panel): # Grease Pencil drawing brushes -class GreasePencilPanel: +class GreasePencilPaintPanel: bl_context = ".greasepencil_paint" bl_category = "Tool" @@ -1355,7 +1383,7 @@ class GreasePencilPanel: return True -class VIEW3D_PT_tools_grease_pencil_brush_select(Panel, View3DPanel, GreasePencilPanel): +class VIEW3D_PT_tools_grease_pencil_brush_select(Panel, View3DPanel, GreasePencilPaintPanel): bl_label = "Brushes" def draw(self, context): @@ -1370,7 +1398,7 @@ class VIEW3D_PT_tools_grease_pencil_brush_select(Panel, View3DPanel, GreasePenci row.column().template_ID_preview(gpencil_paint, "brush", new="brush.add_gpencil", rows=3, cols=8) col = row.column() - col.operator("gpencil.brush_presets_create", icon='PRESET_NEW', text="") + col.menu("VIEW3D_MT_brush_gpencil_context_menu", icon='DOWNARROW_HLT', text="") if context.mode == 'PAINT_GPENCIL': brush = tool_settings.gpencil_paint.brush @@ -1383,7 +1411,7 @@ class VIEW3D_PT_tools_grease_pencil_brush_select(Panel, View3DPanel, GreasePenci layout.row().prop(brush, "icon_filepath", text="") -class VIEW3D_PT_tools_grease_pencil_brush_settings(Panel, View3DPanel, GreasePencilPanel): +class VIEW3D_PT_tools_grease_pencil_brush_settings(Panel, View3DPanel, GreasePencilPaintPanel): bl_label = "Brush Settings" # What is the point of brush presets? Seems to serve the exact same purpose as brushes themselves?? @@ -1431,7 +1459,7 @@ class VIEW3D_PT_tools_grease_pencil_brush_advanced(View3DPanel, Panel): @classmethod def poll(cls, context): brush = context.tool_settings.gpencil_paint.brush - return brush is not None and brush.gpencil_tool != 'ERASE' + return brush is not None and brush.gpencil_tool not in {'ERASE', 'TINT'} def draw(self, context): layout = self.layout @@ -1463,11 +1491,11 @@ class VIEW3D_PT_tools_grease_pencil_brush_advanced(View3DPanel, Panel): ma = brush.gpencil_settings.material col.separator() + col.prop(gp_settings, "hardeness", slider=True) subcol = col.column(align=True) if ma and ma.grease_pencil.mode == 'LINE': subcol.enabled = False - subcol.prop(gp_settings, "gradient_factor", slider=True) - subcol.prop(gp_settings, "gradient_shape") + subcol.prop(gp_settings, "aspect") elif brush.gpencil_tool == 'FILL': row = col.row(align=True) @@ -1479,6 +1507,7 @@ class VIEW3D_PT_tools_grease_pencil_brush_advanced(View3DPanel, Panel): col.prop(gp_settings, "show_fill", text="Ignore Transparent Strokes") col.prop(gp_settings, "fill_threshold", text="Threshold") + class VIEW3D_PT_tools_grease_pencil_brush_stroke(Panel, View3DPanel): bl_context = ".greasepencil_paint" bl_parent_id = 'VIEW3D_PT_tools_grease_pencil_brush_settings' @@ -1545,7 +1574,7 @@ class VIEW3D_PT_tools_grease_pencil_brush_post_processing(View3DPanel, Panel): @classmethod def poll(cls, context): brush = context.tool_settings.gpencil_paint.brush - return brush is not None and brush.gpencil_tool not in {'ERASE', 'FILL'} + return brush is not None and brush.gpencil_tool not in {'ERASE', 'FILL', 'TINT'} def draw_header(self, context): if self.is_popover: @@ -1576,12 +1605,7 @@ class VIEW3D_PT_tools_grease_pencil_brush_post_processing(View3DPanel, Panel): col1.prop(gp_settings, "pen_smooth_steps") col1 = col.column(align=True) - col1.prop(gp_settings, "pen_thick_smooth_factor") - col1.prop(gp_settings, "pen_thick_smooth_steps", text="Iterations") - - col1 = col.column(align=True) col1.prop(gp_settings, "pen_subdivision_steps") - col1.prop(gp_settings, "random_subdiv", text="Randomness", slider=True) col1 = col.column(align=True) col1.prop(gp_settings, "simplify_factor") @@ -1600,7 +1624,7 @@ class VIEW3D_PT_tools_grease_pencil_brush_random(View3DPanel, Panel): @classmethod def poll(cls, context): brush = context.tool_settings.gpencil_paint.brush - return brush is not None and brush.gpencil_tool not in {'ERASE', 'FILL'} + return brush is not None and brush.gpencil_tool not in {'ERASE', 'FILL', 'TINT'} def draw_header(self, context): if self.is_popover: @@ -1646,7 +1670,7 @@ class VIEW3D_PT_tools_grease_pencil_brushcurves(View3DPanel, Panel): @classmethod def poll(cls, context): brush = context.tool_settings.gpencil_paint.brush - return brush is not None and brush.gpencil_tool not in {'ERASE', 'FILL'} + return brush is not None and brush.gpencil_tool not in {'ERASE', 'FILL', 'TINT'} def draw(self, context): pass @@ -1703,6 +1727,24 @@ class VIEW3D_PT_tools_grease_pencil_brushcurves_jitter(View3DPanel, Panel): use_negative_slope=True) +class VIEW3D_PT_tools_grease_pencil_brush_paint_falloff(GreasePencilBrushFalloff, Panel, View3DPaintPanel): + bl_context = ".greasepencil_paint" + bl_label = "Falloff" + bl_options = {'DEFAULT_CLOSED'} + + @classmethod + def poll(cls, context): + ts = context.tool_settings + settings = ts.gpencil_paint + brush = settings.brush + if brush is None: + return False + + tool = brush.gpencil_tool + + return (settings and settings.brush and settings.brush.curve and tool == 'TINT') + + # Grease Pencil stroke interpolation tools class VIEW3D_PT_tools_grease_pencil_interpolate(Panel): bl_space_type = 'VIEW_3D' @@ -1751,25 +1793,49 @@ class VIEW3D_PT_tools_grease_pencil_interpolate(Panel): # Grease Pencil stroke sculpting tools - -class VIEW3D_PT_tools_grease_pencil_sculpt_select(Panel, View3DPanel): +class GreasePencilSculptPanel: bl_context = ".greasepencil_sculpt" - bl_label = "Brushes" bl_category = "Tool" + @classmethod + def poll(cls, context): + if context.space_data.type in ('VIEW_3D', 'PROPERTIES'): + if context.gpencil_data is None: + return False + + gpd = context.gpencil_data + return bool(gpd.is_stroke_sculpt_mode) + else: + return True + + +class VIEW3D_PT_tools_grease_pencil_sculpt_select(Panel, View3DPanel, GreasePencilSculptPanel): + bl_label = "Brushes" + 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 = context.scene.tool_settings + gpencil_paint = tool_settings.gpencil_sculpt_paint - layout.template_icon_view(settings, "sculpt_tool", show_labels=True) + row = layout.row() + row.column().template_ID_preview(gpencil_paint, "brush", new="brush.add_gpencil", rows=3, cols=8) + col = row.column() + col.menu("VIEW3D_MT_brush_gpencil_context_menu", icon='DOWNARROW_HLT', text="") -class VIEW3D_PT_tools_grease_pencil_sculpt_settings(Panel, View3DPanel): - bl_context = ".greasepencil_sculpt" - bl_category = "Tool" + if context.mode == 'SCULPT_GPENCIL': + brush = tool_settings.gpencil_sculpt_paint.brush + if brush is not None: + col.prop(brush, "use_custom_icon", toggle=True, icon='FILE_IMAGE', text="") + + if(brush.use_custom_icon): + layout.row().prop(brush, "icon_filepath", text="") + + +class VIEW3D_PT_tools_grease_pencil_sculpt_settings(Panel, View3DPanel, GreasePencilSculptPanel): bl_label = "Brush Settings" def draw(self, context): @@ -1777,7 +1843,8 @@ class VIEW3D_PT_tools_grease_pencil_sculpt_settings(Panel, View3DPanel): layout.use_property_split = True layout.use_property_decorate = False - settings = context.tool_settings.gpencil_sculpt + tool_settings = context.scene.tool_settings + settings = tool_settings.gpencil_sculpt_paint brush = settings.brush if not self.is_popover: @@ -1786,27 +1853,63 @@ class VIEW3D_PT_tools_grease_pencil_sculpt_settings(Panel, View3DPanel): ) brush_basic_gpencil_sculpt_settings(layout, context, brush) -# Grease Pencil weight painting tools +class VIEW3D_PT_tools_grease_pencil_brush_sculpt_falloff(GreasePencilBrushFalloff, Panel, View3DPaintPanel): + bl_context = ".greasepencil_sculpt" + bl_label = "Falloff" + bl_options = {'DEFAULT_CLOSED'} + + @classmethod + def poll(cls, context): + ts = context.tool_settings + settings = ts.gpencil_sculpt_paint + return (settings and settings.brush and settings.brush.curve) -class VIEW3D_PT_tools_grease_pencil_weight_paint_select(View3DPanel, Panel): + +# Grease Pencil weight painting tools +class GreasePencilWeightPanel: bl_context = ".greasepencil_weight" - bl_label = "Brushes" bl_category = "Tool" + @classmethod + def poll(cls, context): + if context.space_data.type in ('VIEW_3D', 'PROPERTIES'): + if context.gpencil_data is None: + return False + + gpd = context.gpencil_data + return bool(gpd.is_stroke_weight_mode) + else: + return True + + +class VIEW3D_PT_tools_grease_pencil_weight_paint_select(View3DPanel, Panel, GreasePencilWeightPanel): + bl_label = "Brushes" + 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 = context.scene.tool_settings + gpencil_paint = tool_settings.gpencil_weight_paint - layout.template_icon_view(settings, "weight_tool", show_labels=True) + row = layout.row() + row.column().template_ID_preview(gpencil_paint, "brush", new="brush.add_gpencil", rows=3, cols=8) + col = row.column() + col.menu("VIEW3D_MT_brush_gpencil_context_menu", icon='DOWNARROW_HLT', text="") -class VIEW3D_PT_tools_grease_pencil_weight_paint_settings(Panel, View3DPanel): - bl_context = ".greasepencil_weight" - bl_category = "Tool" + if context.mode == 'WEIGHT_GPENCIL': + brush = tool_settings.gpencil_weight_paint.brush + if brush is not None: + col.prop(brush, "use_custom_icon", toggle=True, icon='FILE_IMAGE', text="") + + if(brush.use_custom_icon): + layout.row().prop(brush, "icon_filepath", text="") + + +class VIEW3D_PT_tools_grease_pencil_weight_paint_settings(Panel, View3DPanel, GreasePencilWeightPanel): bl_label = "Brush Settings" def draw(self, context): @@ -1814,7 +1917,8 @@ class VIEW3D_PT_tools_grease_pencil_weight_paint_settings(Panel, View3DPanel): layout.use_property_split = True layout.use_property_decorate = False - settings = context.tool_settings.gpencil_sculpt + tool_settings = context.scene.tool_settings + settings = tool_settings.gpencil_weight_paint brush = settings.brush if not self.is_popover: @@ -1824,6 +1928,272 @@ class VIEW3D_PT_tools_grease_pencil_weight_paint_settings(Panel, View3DPanel): brush_basic_gpencil_weight_settings(layout, context, brush) +class VIEW3D_PT_tools_grease_pencil_brush_weight_falloff(GreasePencilBrushFalloff, Panel, View3DPaintPanel): + bl_context = ".greasepencil_weight" + bl_label = "Falloff" + bl_options = {'DEFAULT_CLOSED'} + + @classmethod + def poll(cls, context): + ts = context.tool_settings + settings = ts.gpencil_weight_paint + brush = settings.brush + return (settings and settings.brush and settings.brush.curve) + + +# Grease Pencil vertex painting tools +class GreasePencilVertexPanel: + bl_context = ".greasepencil_vertex" + bl_category = "Tool" + + @classmethod + def poll(cls, context): + if context.space_data.type in ('VIEW_3D', 'PROPERTIES'): + if context.gpencil_data is None: + return False + + gpd = context.gpencil_data + return bool(gpd.is_stroke_vertex_mode) + else: + return True + + +class VIEW3D_PT_tools_grease_pencil_vertex_paint_select(View3DPanel, Panel, GreasePencilVertexPanel): + bl_label = "Brushes" + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False + + tool_settings = context.scene.tool_settings + gpencil_paint = tool_settings.gpencil_vertex_paint + + row = layout.row() + row.column().template_ID_preview(gpencil_paint, "brush", new="brush.add_gpencil", rows=3, cols=8) + + col = row.column() + col.menu("VIEW3D_MT_brush_gpencil_context_menu", icon='DOWNARROW_HLT', text="") + + if context.mode == 'VERTEX_GPENCIL': + brush = tool_settings.gpencil_vertex_paint.brush + if brush is not None: + col.prop(brush, "use_custom_icon", toggle=True, icon='FILE_IMAGE', text="") + + if(brush.use_custom_icon): + layout.row().prop(brush, "icon_filepath", text="") + + +class VIEW3D_PT_tools_grease_pencil_vertex_paint_settings(Panel, View3DPanel, GreasePencilVertexPanel): + bl_label = "Brush Settings" + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False + + tool_settings = context.scene.tool_settings + settings = tool_settings.gpencil_vertex_paint + brush = settings.brush + + if not self.is_popover: + from bl_ui.properties_paint_common import ( + brush_basic_gpencil_vertex_settings, + ) + brush_basic_gpencil_vertex_settings(layout, context, brush) + + +class VIEW3D_PT_tools_grease_pencil_brush_vertex_color(View3DPanel, Panel): + bl_context = ".greasepencil_vertex" + bl_label = "Color" + bl_category = "Tool" + + @classmethod + def poll(cls, context): + ob = context.object + ts = context.tool_settings + settings = ts.gpencil_vertex_paint + brush = settings.brush + + if ob is None or brush is None: + return False + + if context.region.type == 'TOOL_HEADER' or brush.gpencil_vertex_tool in {'BLUR', 'AVERAGE', 'SMEAR'}: + return False + + return True + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False + ts = context.tool_settings + settings = ts.gpencil_vertex_paint + brush = settings.brush + gp_settings = brush.gpencil_settings + + col = layout.column() + + col.template_color_picker(brush, "color", value_slider=True) + + sub_row = col.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="") + + col.prop(gp_settings, "vertex_mode", text="Mode") + + +class VIEW3D_PT_tools_grease_pencil_brush_vertex_falloff(GreasePencilBrushFalloff, Panel, View3DPaintPanel): + bl_context = ".greasepencil_vertex" + bl_label = "Falloff" + bl_options = {'DEFAULT_CLOSED'} + + @classmethod + def poll(cls, context): + ts = context.tool_settings + settings = ts.gpencil_vertex_paint + return (settings and settings.brush and settings.brush.curve) + + +class VIEW3D_PT_tools_grease_pencil_brush_vertex_palette(View3DPanel, Panel): + bl_context = ".greasepencil_vertex" + bl_label = "Palette" + bl_category = "Tool" + bl_parent_id = 'VIEW3D_PT_tools_grease_pencil_brush_vertex_color' + + @classmethod + def poll(cls, context): + ob = context.object + ts = context.tool_settings + settings = ts.gpencil_vertex_paint + brush = settings.brush + + if ob is None or brush is None: + return False + + if brush.gpencil_vertex_tool in {'BLUR', 'AVERAGE', 'SMEAR'}: + return False + + return True + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False + ts = context.tool_settings + settings = ts.gpencil_vertex_paint + + col = layout.column() + + row = col.row(align=True) + row.template_ID(settings, "palette", new="palette.new") + if settings.palette: + col.template_palette(settings, "palette", color=True) + + +class VIEW3D_PT_tools_grease_pencil_brush_mixcolor(View3DPanel, Panel): + bl_context = ".greasepencil_paint" + bl_label = "Color" + bl_category = "Tool" + bl_options = {'DEFAULT_CLOSED'} + + @classmethod + def poll(cls, context): + ob = context.object + ts = context.tool_settings + settings = ts.gpencil_paint + brush = settings.brush + + if ob is None or brush is None: + return False + + if context.region.type == 'TOOL_HEADER': + return False + + if brush.gpencil_tool == 'TINT': + return True + + if brush.gpencil_tool not in {'DRAW', 'FILL'}: + return False + + return True + + def draw(self, context): + layout = self.layout + ts = context.tool_settings + settings = ts.gpencil_paint + brush = settings.brush + gp_settings = brush.gpencil_settings + + if brush.gpencil_tool != 'TINT': + row = layout.row() + row.prop(settings, "color_mode", expand=True) + + layout.use_property_split = True + layout.use_property_decorate = False + col = layout.column() + col.enabled = settings.color_mode == 'VERTEXCOLOR' or brush.gpencil_tool == 'TINT' + + col.template_color_picker(brush, "color", value_slider=True) + + sub_row = col.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="") + + if brush.gpencil_tool in {'DRAW', 'FILL'}: + col.prop(gp_settings, "vertex_mode", text="Mode") + col.prop(gp_settings, "vertex_color_factor", slider=True, text="Mix Factor") + + if brush.gpencil_tool == 'TINT': + col.prop(gp_settings, "vertex_mode", text="Mode") + + +class VIEW3D_PT_tools_grease_pencil_brush_mix_palette(View3DPanel, Panel): + bl_context = ".greasepencil_paint" + bl_label = "Palette" + bl_category = "Tool" + bl_parent_id = 'VIEW3D_PT_tools_grease_pencil_brush_mixcolor' + bl_options = {'DEFAULT_CLOSED'} + + @classmethod + def poll(cls, context): + ob = context.object + ts = context.tool_settings + settings = ts.gpencil_paint + brush = settings.brush + + if ob is None or brush is None: + return False + + if brush.gpencil_tool == 'TINT': + return True + + if brush.gpencil_tool not in {'DRAW', 'FILL'}: + return False + + return True + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False + ts = context.tool_settings + settings = ts.gpencil_paint + brush = settings.brush + + col = layout.column() + col.enabled = settings.color_mode == 'VERTEXCOLOR' or brush.gpencil_tool == 'TINT' + + row = col.row(align=True) + row.template_ID(settings, "palette", new="palette.new") + if settings.palette: + col.template_palette(settings, "palette", color=True) + + class VIEW3D_PT_tools_grease_pencil_sculpt_options(GreasePencilSculptOptionsPanel, Panel, View3DPanel): bl_context = ".greasepencil_sculpt" bl_parent_id = 'VIEW3D_PT_tools_grease_pencil_sculpt_settings' @@ -1852,6 +2222,11 @@ class VIEW3D_PT_tools_grease_pencil_weight_appearance(GreasePencilDisplayPanel, bl_category = "Tool" bl_label = "Cursor" +class VIEW3D_PT_tools_grease_pencil_vertex_appearance(GreasePencilDisplayPanel, Panel, View3DPanel): + bl_context = ".greasepencil_vertex" + bl_parent_id = 'VIEW3D_PT_tools_grease_pencil_vertex_paint_settings' + bl_category = "Tool" + bl_label = "Cursor" class VIEW3D_PT_gpencil_brush_presets(Panel, PresetPanel): """Brush settings""" @@ -1863,6 +2238,7 @@ class VIEW3D_PT_gpencil_brush_presets(Panel, PresetPanel): classes = ( VIEW3D_MT_brush_context_menu, + VIEW3D_MT_brush_gpencil_context_menu, VIEW3D_MT_brush_context_menu_paint_modes, VIEW3D_PT_tools_object_options, VIEW3D_PT_tools_object_options_transform, @@ -1940,7 +2316,19 @@ classes = ( VIEW3D_PT_tools_grease_pencil_weight_paint_select, VIEW3D_PT_tools_grease_pencil_weight_paint_settings, VIEW3D_PT_tools_grease_pencil_weight_appearance, + VIEW3D_PT_tools_grease_pencil_vertex_paint_select, + VIEW3D_PT_tools_grease_pencil_vertex_paint_settings, + VIEW3D_PT_tools_grease_pencil_vertex_appearance, VIEW3D_PT_tools_grease_pencil_interpolate, + VIEW3D_PT_tools_grease_pencil_brush_mixcolor, + VIEW3D_PT_tools_grease_pencil_brush_mix_palette, + + VIEW3D_PT_tools_grease_pencil_brush_paint_falloff, + VIEW3D_PT_tools_grease_pencil_brush_sculpt_falloff, + VIEW3D_PT_tools_grease_pencil_brush_weight_falloff, + VIEW3D_PT_tools_grease_pencil_brush_vertex_color, + VIEW3D_PT_tools_grease_pencil_brush_vertex_palette, + VIEW3D_PT_tools_grease_pencil_brush_vertex_falloff, ) if __name__ == "__main__": # only for live edit. |