diff --git a/scripts/startup/bl_ui/space_view3d.py b/scripts/startup/bl_ui/space_view3d.py index ef75e104829..c19092a76fb 100644 --- a/scripts/startup/bl_ui/space_view3d.py +++ b/scripts/startup/bl_ui/space_view3d.py @@ -126,6 +126,13 @@ class VIEW3D_HT_tool_header(Header): elif tool_mode == 'VERTEX_GPENCIL': if is_valid_context: layout.popover("VIEW3D_PT_tools_grease_pencil_vertex_appearance") + elif tool_mode == "PAINT_GREASE_PENCIL": + if is_valid_context: + brush = context.tool_settings.gpencil_paint.brush + if brush: + if brush.gpencil_tool != 'ERASE': + if brush.gpencil_tool not in {'FILL', 'TINT'}: + layout.popover("VIEW3D_PT_tools_grease_pencil_v3_brush_stroke") def draw_mode_settings(self, context): layout = self.layout diff --git a/scripts/startup/bl_ui/space_view3d_toolbar.py b/scripts/startup/bl_ui/space_view3d_toolbar.py index babbb5f1cc6..71f5539ebb5 100644 --- a/scripts/startup/bl_ui/space_view3d_toolbar.py +++ b/scripts/startup/bl_ui/space_view3d_toolbar.py @@ -2659,6 +2659,32 @@ class VIEW3D_PT_tools_grease_pencil_v3_brush_mix_palette(View3DPanel, Panel): col.template_palette(settings, "palette", color=True) +class VIEW3D_PT_tools_grease_pencil_v3_brush_stroke(Panel, View3DPanel): + bl_context = ".grease_pencil_paint" + bl_parent_id = "VIEW3D_PT_tools_grease_pencil_v3_brush_settings" + bl_label = "Stroke" + bl_category = "Tool" + bl_options = {'DEFAULT_CLOSED'} + bl_ui_units_x = 12 + + @classmethod + def poll(cls, context): + brush = context.tool_settings.gpencil_paint.brush + return brush is not None and brush.gpencil_tool == 'DRAW' + + def draw(self, _context): + layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False + + +class VIEW3D_PT_tools_grease_pencil_v3_brush_stabilize_stroke(View3DPanel, Panel, SmoothStrokePanel): + bl_context = ".grease_pencil_paint" # dot on purpose (access from topbar) + bl_label = "Stabilize Stroke" + bl_parent_id = "VIEW3D_PT_tools_grease_pencil_v3_brush_stroke" + bl_options = {'DEFAULT_CLOSED'} + + classes = ( VIEW3D_MT_brush_context_menu, VIEW3D_MT_brush_gpencil_context_menu, @@ -2754,6 +2780,8 @@ classes = ( VIEW3D_PT_tools_grease_pencil_v3_brush_settings, VIEW3D_PT_tools_grease_pencil_v3_brush_mixcolor, VIEW3D_PT_tools_grease_pencil_v3_brush_mix_palette, + VIEW3D_PT_tools_grease_pencil_v3_brush_stroke, + VIEW3D_PT_tools_grease_pencil_v3_brush_stabilize_stroke, VIEW3D_PT_tools_grease_pencil_brush_paint_falloff, VIEW3D_PT_tools_grease_pencil_brush_sculpt_falloff, diff --git a/source/blender/editors/sculpt_paint/grease_pencil_paint.cc b/source/blender/editors/sculpt_paint/grease_pencil_paint.cc index 21634b3ba8f..700c21917f7 100644 --- a/source/blender/editors/sculpt_paint/grease_pencil_paint.cc +++ b/source/blender/editors/sculpt_paint/grease_pencil_paint.cc @@ -172,6 +172,10 @@ struct PaintOperationExecutor { settings_->vertex_factor) : float4(0.0f); srgb_to_linearrgb_v4(vertex_color_, vertex_color_); + paint->paint_cursor_col[0] = uint(vertex_color_[0] * 255); + paint->paint_cursor_col[1] = uint(vertex_color_[1] * 255); + paint->paint_cursor_col[2] = uint(vertex_color_[2] * 255); + paint->paint_cursor_col[3] = 128; /* TODO: UI setting. */ hardness_ = 1.0f; diff --git a/source/blender/editors/sculpt_paint/paint_intern.hh b/source/blender/editors/sculpt_paint/paint_intern.hh index 04866b09974..9383dfa66d4 100644 --- a/source/blender/editors/sculpt_paint/paint_intern.hh +++ b/source/blender/editors/sculpt_paint/paint_intern.hh @@ -88,7 +88,7 @@ bool paint_supports_dynamic_size(Brush *br, PaintMode mode); * Return true if the brush size can change during paint (normally used for pressure). */ bool paint_supports_dynamic_tex_coords(Brush *br, PaintMode mode); -bool paint_supports_smooth_stroke(Brush *br, PaintMode mode); +bool paint_supports_smooth_stroke(Brush *br, PaintMode mode, const wmEvent *event); bool paint_supports_texture(PaintMode mode); /** diff --git a/source/blender/editors/sculpt_paint/paint_stroke.cc b/source/blender/editors/sculpt_paint/paint_stroke.cc index ccf325c20ba..fe16f10a1bd 100644 --- a/source/blender/editors/sculpt_paint/paint_stroke.cc +++ b/source/blender/editors/sculpt_paint/paint_stroke.cc @@ -628,16 +628,19 @@ static void paint_brush_stroke_add_step( static bool paint_smooth_stroke(PaintStroke *stroke, const PaintSample *sample, PaintMode mode, + const wmEvent *event, float r_mouse[2], float *r_pressure) { - if (paint_supports_smooth_stroke(stroke->brush, mode)) { + if (paint_supports_smooth_stroke(stroke->brush, mode, event)) { float radius = stroke->brush->smooth_stroke_radius * stroke->zoom_2d; float u = stroke->brush->smooth_stroke_factor; /* If the mouse is moving within the radius of the last move, * don't update the mouse position. This allows sharp turns. */ - if (len_squared_v2v2(stroke->last_mouse_position, sample->mouse) < square_f(radius)) { + if (len_squared_v2v2(stroke->last_mouse_position, sample->mouse) < square_f(radius) && + stroke->tot_samples != 0) + { return false; } @@ -1091,8 +1094,13 @@ bool paint_supports_dynamic_size(Brush *br, PaintMode mode) return true; } -bool paint_supports_smooth_stroke(Brush *br, PaintMode mode) +bool paint_supports_smooth_stroke(Brush *br, PaintMode mode, const wmEvent *event) { + /* Grease pencil draw mode allows for holding `shift` to toggle smoothing. */ + if ((mode == PaintMode::GPencil) && (br->gpencil_tool == GPAINT_TOOL_DRAW)) { + return ((br->flag & BRUSH_SMOOTH_STROKE) != 0) ^ (event->modifier & KM_SHIFT); + } + if (!(br->flag & BRUSH_SMOOTH_STROKE) || (br->flag & (BRUSH_ANCHORED | BRUSH_DRAG_DOT | BRUSH_LINE))) { @@ -1488,15 +1496,28 @@ int paint_stroke_modal(bContext *C, wmOperator *op, const wmEvent *event, PaintS return OPERATOR_FINISHED; } - if (paint_supports_smooth_stroke(br, mode)) { - stroke->stroke_cursor = WM_paint_cursor_activate( - SPACE_TYPE_ANY, RGN_TYPE_ANY, paint_brush_tool_poll, paint_draw_smooth_cursor, stroke); - } - stroke->stroke_init = true; first_modal = true; } + /* Smoothing can be activated and deactivated while running, so the cursor has to update. */ + if ((br->flag & BRUSH_LINE) == 0) { + if (paint_supports_smooth_stroke(br, mode, event)) { + /* Activate if it is not active. */ + if (!stroke->stroke_cursor) { + stroke->stroke_cursor = WM_paint_cursor_activate( + SPACE_TYPE_ANY, RGN_TYPE_ANY, paint_brush_tool_poll, paint_draw_smooth_cursor, stroke); + } + } + else { + /* Deactivate it if it is active. */ + if (stroke->stroke_cursor) { + WM_paint_cursor_end(static_cast(stroke->stroke_cursor)); + stroke->stroke_cursor = nullptr; + } + } + } + /* one time stroke initialization */ if (!stroke->stroke_started) { stroke->last_pressure = sample_average.pressure; @@ -1577,7 +1598,7 @@ int paint_stroke_modal(bContext *C, wmOperator *op, const wmEvent *event, PaintS ((br->flag & BRUSH_AIRBRUSH) && event->type == TIMER && event->customdata == stroke->timer)) { - if (paint_smooth_stroke(stroke, &sample_average, mode, mouse, &pressure)) { + if (paint_smooth_stroke(stroke, &sample_average, mode, event, mouse, &pressure)) { if (stroke->stroke_started) { if (paint_space_stroke_enabled(br, mode)) { if (paint_space_stroke(C, op, stroke, mouse, pressure)) {