[Bf-blender-cvs] [a44c1284823] master: GPencil: show brush size in Draw tool cursor

Sietse Brouwer noreply at git.blender.org
Fri Dec 23 16:14:56 CET 2022


Commit: a44c1284823a1017283cec5ff58f099956e03abd
Author: Sietse Brouwer
Date:   Fri Dec 23 16:02:01 2022 +0100
Branches: master
https://developer.blender.org/rBa44c1284823a1017283cec5ff58f099956e03abd

GPencil: show brush size in Draw tool cursor

When drawing strokes in Grease Pencil, it was always a bit hard
to predict how thick the strokes would be, because there was
no visual reference of the thickness in the cursor.
This patch adds that visual reference. It shows the brush size
as a circle in the draw cursor.
Showing the brush size can be toggled in the Cursor menu
of the Grease Pencil draw tool.

Request in RCS with 26 upvotes for this option:
https://blender.community/c/rightclickselect/0zfbbc

On the technical side: the brush size is calculated
in 3D space and takes zoom level into account, as well as
object/layer transfrom, layer thickness change (gpl->line_change)
and thickness scale (gpd->pixfactor).

Reviewed By: mendio, antoniov

Differential Revision: https://developer.blender.org/D16851

===================================================================

M	release/scripts/startup/bl_ui/properties_grease_pencil_common.py
M	source/blender/editors/gpencil/gpencil_utils.c
M	source/blender/makesdna/DNA_brush_enums.h
M	source/blender/makesrna/intern/rna_brush.c

===================================================================

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 3aa8879c594..1e68b2df97d 100644
--- a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py
+++ b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py
@@ -117,11 +117,13 @@ class GreasePencilDisplayPanel:
                 row = layout.row(align=True)
                 row.prop(settings, "show_brush", text="Display Cursor")
 
-            col = layout.column(align=True)
-            col.active = settings.show_brush
-
             if brush.gpencil_tool == 'DRAW':
-                col.prop(gp_settings, "show_lasso", text="Show Fill Color While Drawing")
+                row = layout.row(align=True)
+                row.active = settings.show_brush
+                row.prop(gp_settings, "show_brush_size", text="Show Brush Size")
+                row = layout.row(align=True)
+                row.active = settings.show_brush
+                row.prop(gp_settings, "show_lasso", text="Show Fill Color While Drawing")
 
         elif ob.mode == 'SCULPT_GPENCIL':
             col = layout.column(align=True)
diff --git a/source/blender/editors/gpencil/gpencil_utils.c b/source/blender/editors/gpencil/gpencil_utils.c
index 7516e84805c..3abb04c6360 100644
--- a/source/blender/editors/gpencil/gpencil_utils.c
+++ b/source/blender/editors/gpencil/gpencil_utils.c
@@ -1750,6 +1750,7 @@ static void gpencil_brush_cursor_draw(bContext *C, int x, int y, void *customdat
   float color[3] = {1.0f, 1.0f, 1.0f};
   float darkcolor[3];
   float radius = 3.0f;
+  bool fixed_radius = true;
 
   const int mval_i[2] = {x, y};
   /* Check if cursor is in drawing region and has valid data-block. */
@@ -1787,16 +1788,61 @@ static void gpencil_brush_cursor_draw(bContext *C, int x, int y, void *customdat
     if (ma) {
       gp_style = ma->gp_style;
 
-      /* after some testing, display the size of the brush is not practical because
-       * is too disruptive and the size of cursor does not change with zoom factor.
-       * The decision was to use a fix size, instead of brush->thickness value.
+      /* Follow user settings for the size of the draw cursor:
+       * - Fixed size, or
+       * - Brush size (i.e. stroke thickness)
        */
       if ((gp_style) && GPENCIL_PAINT_MODE(gpd) &&
           ((brush->gpencil_settings->flag & GP_BRUSH_STABILIZE_MOUSE) == 0) &&
           ((brush->gpencil_settings->flag & GP_BRUSH_STABILIZE_MOUSE_TEMP) == 0) &&
           (brush->gpencil_tool == GPAINT_TOOL_DRAW)) {
-        radius = 2.0f;
-        copy_v3_v3(color, gp_style->stroke_rgba);
+
+        /* Check user setting for cursor size. */
+        fixed_radius = ((brush->gpencil_settings->flag & GP_BRUSH_SHOW_DRAW_SIZE) == 0);
+
+        if (fixed_radius) {
+          /* Show fixed radius. */
+          radius = 2.0f;
+          copy_v3_v3(color, gp_style->stroke_rgba);
+        }
+        else {
+          /* Show brush size. */
+          tGPspoint point2D;
+          float p1[3];
+          float p2[3];
+          float distance;
+
+          /* Strokes in screen space or world space? */
+          if ((gpd->flag & GP_DATA_STROKE_KEEPTHICKNESS) != 0) {
+            /* In screen space the cursor radius matches the brush size. */
+            radius = (float)brush->size * 0.5f;
+          }
+          else {
+            /* To calculate the brush size in world space, we have to establish the zoom level.
+             * For this we take two 2D screen coordinates with a fixed offset,
+             * convert them to 3D coordinates and measure the offset distance in 3D.
+             * A small distance means a high zoom level. */
+            point2D.m_xy[0] = (float)x;
+            point2D.m_xy[1] = (float)y;
+            gpencil_stroke_convertcoords_tpoint(scene, region, ob, &point2D, NULL, p1);
+            point2D.m_xy[0] = (float)(x + 64);
+            gpencil_stroke_convertcoords_tpoint(scene, region, ob, &point2D, NULL, p2);
+            /* Clip extreme zoom level (and avoid division by zero). */
+            distance = MAX2(len_v3v3(p1, p2), 0.001f);
+
+            /* Handle layer thickness change. */
+            float brush_size = (float)brush->size;
+            bGPDlayer *gpl = BKE_gpencil_layer_active_get(gpd);
+            if (gpl != NULL) {
+              brush_size = MAX2(1.0f, brush_size + gpl->line_change);
+            }
+
+            /* Convert the 3D offset distance to a brush radius. */
+            radius = (1 / distance) * 2.0f * gpd->pixfactor * (brush_size / 64);
+          }
+
+          copy_v3_v3(color, brush->rgb);
+        }
       }
       else {
         /* Only Tint tool must show big cursor. */
@@ -1876,7 +1922,7 @@ static void gpencil_brush_cursor_draw(bContext *C, int x, int y, void *customdat
 
   /* Inner Ring: Color from UI panel */
   immUniformColor4f(color[0], color[1], color[2], 0.8f);
-  if ((gp_style) && GPENCIL_PAINT_MODE(gpd) &&
+  if ((gp_style) && GPENCIL_PAINT_MODE(gpd) && (fixed_radius) &&
       ((brush->gpencil_settings->flag & GP_BRUSH_STABILIZE_MOUSE) == 0) &&
       ((brush->gpencil_settings->flag & GP_BRUSH_STABILIZE_MOUSE_TEMP) == 0) &&
       (brush->gpencil_tool == GPAINT_TOOL_DRAW)) {
diff --git a/source/blender/makesdna/DNA_brush_enums.h b/source/blender/makesdna/DNA_brush_enums.h
index 72357ea6734..ce90a8e05c1 100644
--- a/source/blender/makesdna/DNA_brush_enums.h
+++ b/source/blender/makesdna/DNA_brush_enums.h
@@ -91,6 +91,8 @@ typedef enum eGPDbrush_Flag {
   GP_BRUSH_OUTLINE_STROKE = (1 << 17),
   /* Collide with stroke. */
   GP_BRUSH_FILL_STROKE_COLLIDE = (1 << 18),
+  /* Show brush size */
+  GP_BRUSH_SHOW_DRAW_SIZE = (1 << 19),
 } eGPDbrush_Flag;
 
 typedef enum eGPDbrush_Flag2 {
diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c
index ce51b52de39..1d2adc386cf 100644
--- a/source/blender/makesrna/intern/rna_brush.c
+++ b/source/blender/makesrna/intern/rna_brush.c
@@ -2005,6 +2005,12 @@ static void rna_def_gpencil_options(BlenderRNA *brna)
       prop, "Show Lasso", "Do not display fill color while drawing the stroke");
   RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
 
+  prop = RNA_def_property(srna, "show_brush_size", PROP_BOOLEAN, PROP_NONE);
+  RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_BRUSH_SHOW_DRAW_SIZE);
+  RNA_def_property_boolean_default(prop, true);
+  RNA_def_property_ui_text(prop, "Show Brush Size", "Show the real size of the draw brush");
+  RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+
   prop = RNA_def_property(srna, "use_occlude_eraser", PROP_BOOLEAN, PROP_NONE);
   RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_BRUSH_OCCLUDE_ERASER);
   RNA_def_property_ui_text(prop, "Occlude Eraser", "Erase only strokes visible and not occluded");



More information about the Bf-blender-cvs mailing list