From cc01bb83f63b9299a7baa0d9eba4f7a48a0a87b7 Mon Sep 17 00:00:00 2001 From: Philipp Oeser Date: Tue, 29 Aug 2023 13:44:35 +0200 Subject: [PATCH] Fix #111490: paint radius set to 1 (shift-smoothing but brush missing) This affected sculpt, vertex- and weightpaint. So attempting to (temporarily) switching to the smooth/blur tools from another tool using the "Shift" shortcut can fail if the corresponding smooth/blur brush is not found/missing [which was the case in the report because the brush was deleted]. In this case, brushes dont really get switched, but blender would still try to cache the size (because the smooth/blur brush temporarily uses the same size as the previous brush) of the smooth brush in `StrokeCache` (see `smooth_brush_toggle_on`). Then in `smooth_brush_toggle_off` it was assumed brushes were actually switched and the (non-existing) size of the (missing) smooth brush was applied to the **actual** brush. Now restructure code a bit so in the case of a missing brush we can early out (without affecting the **actual** brush then). Pull Request: https://projects.blender.org/blender/blender/pulls/111516 --- .../editors/sculpt_paint/paint_vertex.cc | 47 +++++++++------ source/blender/editors/sculpt_paint/sculpt.cc | 57 +++++++++++-------- 2 files changed, 63 insertions(+), 41 deletions(-) diff --git a/source/blender/editors/sculpt_paint/paint_vertex.cc b/source/blender/editors/sculpt_paint/paint_vertex.cc index c7595be1a35..65dc7c9bfd0 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.cc +++ b/source/blender/editors/sculpt_paint/paint_vertex.cc @@ -13,6 +13,8 @@ #include "MEM_guardedalloc.h" +#include "CLG_log.h" + #include "BLI_array_utils.h" #include "BLI_color.hh" #include "BLI_color_mix.hh" @@ -76,6 +78,8 @@ using namespace blender::color; using namespace blender::ed::sculpt_paint; /* For vwpaint namespace. */ using blender::ed::sculpt_paint::vwpaint::NormalAnglePrecalc; +static CLG_LogRef LOG = {"ed.sculpt_paint"}; + /* -------------------------------------------------------------------- */ /** \name Internal Utilities * \{ */ @@ -436,16 +440,18 @@ bool mode_toggle_poll_test(bContext *C) void smooth_brush_toggle_off(const bContext *C, Paint *paint, StrokeCache *cache) { Main *bmain = CTX_data_main(C); - Scene *scene = CTX_data_scene(C); Brush *brush = BKE_paint_brush(paint); /* The current brush should match with what we have stored in the cache. */ BLI_assert(brush == cache->brush); - /* Try to switch back to the saved/previous brush. */ - BKE_brush_size_set(scene, brush, cache->saved_smooth_size); - brush = (Brush *)BKE_libblock_find_name(bmain, ID_BR, cache->saved_active_brush_name); - if (brush) { - BKE_paint_brush_set(paint, brush); + /* If saved_active_brush_name is not set, brush was not switched/affected in + * smooth_brush_toggle_on(). */ + Brush *saved_active_brush = (Brush *)BKE_libblock_find_name( + bmain, ID_BR, cache->saved_active_brush_name); + if (saved_active_brush) { + Scene *scene = CTX_data_scene(C); + BKE_brush_size_set(scene, brush, cache->saved_smooth_size); + BKE_paint_brush_set(paint, saved_active_brush); } } /* Initialize the stroke cache invariants from operator properties */ @@ -590,19 +596,26 @@ void last_stroke_update(Scene *scene, const float location[3]) void smooth_brush_toggle_on(const bContext *C, Paint *paint, StrokeCache *cache) { Scene *scene = CTX_data_scene(C); - Brush *brush = paint->brush; - int cur_brush_size = BKE_brush_size_get(scene, brush); - STRNCPY(cache->saved_active_brush_name, brush->id.name + 2); - - /* Switch to the blur (smooth) brush. */ - brush = BKE_paint_toolslots_brush_get(paint, WPAINT_TOOL_BLUR); - if (brush) { - BKE_paint_brush_set(paint, brush); - cache->saved_smooth_size = BKE_brush_size_get(scene, brush); - BKE_brush_size_set(scene, brush, cur_brush_size); - BKE_curvemapping_init(brush->curve); + /* Switch to the blur (smooth) brush if possible. */ + /* Note: used for both vertexpaint and weightpaint, VPAINT_TOOL_BLUR & WPAINT_TOOL_BLUR are the + * same, see comments for eBrushVertexPaintTool & eBrushWeightPaintTool. */ + Brush *smooth_brush = BKE_paint_toolslots_brush_get(paint, WPAINT_TOOL_BLUR); + if (!smooth_brush) { + CLOG_WARN(&LOG, "Switching to the blur (smooth) brush not possible, corresponding brush not"); + cache->saved_active_brush_name[0] = '\0'; + return; } + + Brush *cur_brush = paint->brush; + int cur_brush_size = BKE_brush_size_get(scene, cur_brush); + + STRNCPY(cache->saved_active_brush_name, cur_brush->id.name + 2); + + BKE_paint_brush_set(paint, smooth_brush); + cache->saved_smooth_size = BKE_brush_size_get(scene, smooth_brush); + BKE_brush_size_set(scene, smooth_brush, cur_brush_size); + BKE_curvemapping_init(smooth_brush->curve); } /** \} */ } // namespace blender::ed::sculpt_paint::vwpaint diff --git a/source/blender/editors/sculpt_paint/sculpt.cc b/source/blender/editors/sculpt_paint/sculpt.cc index ea22eeb9edf..ff0f1e39db6 100644 --- a/source/blender/editors/sculpt_paint/sculpt.cc +++ b/source/blender/editors/sculpt_paint/sculpt.cc @@ -13,6 +13,8 @@ #include "MEM_guardedalloc.h" +#include "CLG_log.h" + #include "BLI_array_utils.hh" #include "BLI_blenlib.h" #include "BLI_dial_2d.h" @@ -85,6 +87,8 @@ using blender::Set; using blender::Span; using blender::Vector; +static CLG_LogRef LOG = {"ed.sculpt_paint"}; + static float sculpt_calc_radius(ViewContext *vc, const Brush *brush, const Scene *scene, @@ -4299,40 +4303,43 @@ static void sculpt_init_mirror_clipping(Object *ob, SculptSession *ss) static void smooth_brush_toggle_on(const bContext *C, Paint *paint, StrokeCache *cache) { Scene *scene = CTX_data_scene(C); - Brush *brush = paint->brush; + Brush *cur_brush = paint->brush; - if (brush->sculpt_tool == SCULPT_TOOL_MASK) { - cache->saved_mask_brush_tool = brush->mask_tool; - brush->mask_tool = BRUSH_MASK_SMOOTH; + if (cur_brush->sculpt_tool == SCULPT_TOOL_MASK) { + cache->saved_mask_brush_tool = cur_brush->mask_tool; + cur_brush->mask_tool = BRUSH_MASK_SMOOTH; } - else if (ELEM(brush->sculpt_tool, + else if (ELEM(cur_brush->sculpt_tool, SCULPT_TOOL_SLIDE_RELAX, SCULPT_TOOL_DRAW_FACE_SETS, SCULPT_TOOL_PAINT, SCULPT_TOOL_SMEAR)) { /* Do nothing, this tool has its own smooth mode. */ + return; } - else { - int cur_brush_size = BKE_brush_size_get(scene, brush); - STRNCPY(cache->saved_active_brush_name, brush->id.name + 2); - - /* Switch to the smooth brush. */ - brush = BKE_paint_toolslots_brush_get(paint, SCULPT_TOOL_SMOOTH); - if (brush) { - BKE_paint_brush_set(paint, brush); - cache->saved_smooth_size = BKE_brush_size_get(scene, brush); - BKE_brush_size_set(scene, brush, cur_brush_size); - BKE_curvemapping_init(brush->curve); - } + /* Switch to the smooth brush if possible. */ + Brush *smooth_brush = BKE_paint_toolslots_brush_get(paint, SCULPT_TOOL_SMOOTH); + if (!smooth_brush) { + CLOG_WARN(&LOG, "Switching to the smooth brush not possible, corresponding brush not"); + cache->saved_active_brush_name[0] = '\0'; + return; } + + int cur_brush_size = BKE_brush_size_get(scene, cur_brush); + + STRNCPY(cache->saved_active_brush_name, cur_brush->id.name + 2); + + BKE_paint_brush_set(paint, smooth_brush); + cache->saved_smooth_size = BKE_brush_size_get(scene, smooth_brush); + BKE_brush_size_set(scene, smooth_brush, cur_brush_size); + BKE_curvemapping_init(smooth_brush->curve); } static void smooth_brush_toggle_off(const bContext *C, Paint *paint, StrokeCache *cache) { Main *bmain = CTX_data_main(C); - Scene *scene = CTX_data_scene(C); Brush *brush = BKE_paint_brush(paint); if (brush->sculpt_tool == SCULPT_TOOL_MASK) { @@ -4346,13 +4353,15 @@ static void smooth_brush_toggle_off(const bContext *C, Paint *paint, StrokeCache { /* Do nothing. */ } - else { - /* Try to switch back to the saved/previous brush. */ + + /* If saved_active_brush_name is not set, brush was not switched/affected in + * smooth_brush_toggle_on(). */ + Brush *saved_active_brush = (Brush *)BKE_libblock_find_name( + bmain, ID_BR, cache->saved_active_brush_name); + if (saved_active_brush) { + Scene *scene = CTX_data_scene(C); BKE_brush_size_set(scene, brush, cache->saved_smooth_size); - brush = (Brush *)BKE_libblock_find_name(bmain, ID_BR, cache->saved_active_brush_name); - if (brush) { - BKE_paint_brush_set(paint, brush); - } + BKE_paint_brush_set(paint, saved_active_brush); } }