[Bf-blender-cvs] [9a7c4e2d444] master: Annotations: Add Stabilization for draw tool

Juanfran Matheu noreply at git.blender.org
Mon May 11 12:42:29 CEST 2020


Commit: 9a7c4e2d444f2cbd48cd724a775ea057dad1a88b
Author: Juanfran Matheu
Date:   Fri May 8 20:18:12 2020 +0200
Branches: master
https://developer.blender.org/rB9a7c4e2d444f2cbd48cd724a775ea057dad1a88b

Annotations: Add Stabilization for draw tool

This patch adds the stabilizer feature of GP to the annotations.

It has a toggle to activate it "Use Stabilizer", and two properties to control the behaviour of the smooth effect (factor and radius).
You can also use shift at start or in the air to temporaly use this feature.

{F8518283}

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

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

M	release/scripts/presets/keyconfig/keymap_data/blender_default.py
M	release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
M	source/blender/editors/gpencil/annotate_paint.c

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

diff --git a/release/scripts/presets/keyconfig/keymap_data/blender_default.py b/release/scripts/presets/keyconfig/keymap_data/blender_default.py
index 2e83f3c86c6..b9d84c55ac4 100644
--- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py
+++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py
@@ -3028,6 +3028,8 @@ def km_grease_pencil(_params):
         # Draw
         ("gpencil.annotate", {"type": 'LEFTMOUSE', "value": 'PRESS', "key_modifier": 'D'},
          {"properties": [("mode", 'DRAW'), ("wait_for_input", False)]}),
+        ("gpencil.annotate", {"type": 'LEFTMOUSE', "value": 'PRESS', "key_modifier": 'D', "shift": True},
+         {"properties": [("mode", 'DRAW'), ("wait_for_input", False)]}),
         # Draw - straight lines
         ("gpencil.annotate", {"type": 'LEFTMOUSE', "value": 'PRESS', "alt": True, "key_modifier": 'D'},
          {"properties": [("mode", 'DRAW_STRAIGHT'), ("wait_for_input", False)]}),
diff --git a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
index b10b451c7f8..baff94b067f 100644
--- a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
@@ -204,6 +204,14 @@ class _defs_annotate:
                 col = layout.row().column(align=True)
                 col.prop(props, "arrowstyle_start", text="Style Start")
                 col.prop(props, "arrowstyle_end", text="End")
+        elif tool.idname == "builtin.annotate" and region_type != 'TOOL_HEADER':
+            layout.separator()
+            props = tool.operator_properties("gpencil.annotate")
+            layout.prop(props, "use_stabilizer", text="Stabilize Stroke")
+            col = layout.column(align=False)
+            col.active = props.use_stabilizer
+            col.prop(props, "stabilizer_radius", text="Radius", slider=True)
+            col.prop(props, "stabilizer_factor", text="Factor", slider=True)
 
     @ToolDef.from_fn.with_args(draw_settings=draw_settings_common)
     def scribble(*, draw_settings):
diff --git a/source/blender/editors/gpencil/annotate_paint.c b/source/blender/editors/gpencil/annotate_paint.c
index 8bbac80445a..47370eaa248 100644
--- a/source/blender/editors/gpencil/annotate_paint.c
+++ b/source/blender/editors/gpencil/annotate_paint.c
@@ -100,6 +100,9 @@ typedef enum eGPencil_PaintFlags {
   GP_PAINTFLAG_STROKEADDED = (1 << 1),
   GP_PAINTFLAG_V3D_ERASER_DEPTH = (1 << 2),
   GP_PAINTFLAG_SELECTMASK = (1 << 3),
+  /* Flags used to indicate if stabilization is being used. */
+  GP_PAINTFLAG_USE_STABILIZER = (1 << 7),
+  GP_PAINTFLAG_USE_STABILIZER_TEMP = (1 << 8),
 } eGPencil_PaintFlags;
 
 /* Temporary 'Stroke' Operation data
@@ -148,6 +151,11 @@ typedef struct tGPsdata {
   /** radius of influence for eraser. */
   short radius;
 
+  /* Stabilizer. */
+  float stabilizer_factor;
+  char stabilizer_radius;
+  void *stabilizer_cursor;
+
   /** current mouse-position. */
   float mval[2];
   /** previous recorded mouse-position. */
@@ -278,6 +286,18 @@ static bool gp_stroke_filtermval(tGPsdata *p, const float mval[2], float pmval[2
      * - aims to eliminate some jitter-noise from input when trying to draw straight lines freehand
      */
   }
+  /* If lazy mouse, check minimum distance. */
+  else if (p->flags & GP_PAINTFLAG_USE_STABILIZER_TEMP) {
+    if ((dx * dx + dy * dy) > (p->stabilizer_radius * p->stabilizer_radius)) {
+      return true;
+    }
+    else {
+      /* If the mouse is moving within the radius of the last move,
+       * don't update the mouse position. This allows sharp turns. */
+      copy_v2_v2(p->mval, p->mvalo);
+      return false;
+    }
+  }
   else if ((dx > MIN_MANHATTEN_PX) && (dy > MIN_MANHATTEN_PX)) {
     return true;
 
@@ -586,9 +606,13 @@ static short gp_stroke_addpoint(tGPsdata *p, const float mval[2], float pressure
 
     /* increment counters */
     gpd->runtime.sbuffer_used++;
-    /* smooth while drawing previous points with a reduction factor for previous */
-    for (int s = 0; s < 3; s++) {
-      gp_smooth_buffer(p, 0.5f * ((3.0f - s) / 3.0f), gpd->runtime.sbuffer_used - s);
+
+    /* Don't smooth if stabilizer is on. */
+    if ((p->flags & GP_PAINTFLAG_USE_STABILIZER_TEMP) == 0) {
+      /* smooth while drawing previous points with a reduction factor for previous */
+      for (int s = 0; s < 3; s++) {
+        gp_smooth_buffer(p, 0.5f * ((3.0f - s) / 3.0f), gpd->runtime.sbuffer_used - s);
+      }
     }
 
     return GP_STROKEADD_NORMAL;
@@ -1722,6 +1746,67 @@ static void gpencil_draw_toggle_eraser_cursor(bContext *C, tGPsdata *p, short en
                                                p);
   }
 }
+static void gpencil_draw_stabilizer(bContext *C, int x, int y, void *p_ptr)
+{
+  ARegion *region = CTX_wm_region(C);
+  tGPsdata *p = (tGPsdata *)p_ptr;
+  bGPdata_Runtime runtime = p->gpd->runtime;
+  const tGPspoint *points = runtime.sbuffer;
+  int totpoints = runtime.sbuffer_used;
+  if (totpoints < 2) {
+    return;
+  }
+  const tGPspoint *pt = &points[totpoints - 1];
+
+  GPUVertFormat *format = immVertexFormat();
+  uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+  immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+  GPU_line_smooth(true);
+  GPU_blend(true);
+  GPU_line_width(1.25f);
+  const float color[3] = {1.0f, 0.39f, 0.39f};
+
+  /* default radius and color */
+  float darkcolor[3];
+  const float radius = 4.0f;
+
+  /* Inner Ring: Color from UI panel */
+  immUniformColor4f(color[0], color[1], color[2], 0.8f);
+  imm_draw_circle_wire_2d(pos, x, y, radius, 40);
+
+  /* Outer Ring: Dark color for contrast on light backgrounds (e.g. gray on white) */
+  mul_v3_v3fl(darkcolor, color, 0.40f);
+  immUniformColor4f(darkcolor[0], darkcolor[1], darkcolor[2], 0.8f);
+  imm_draw_circle_wire_2d(pos, x, y, radius + 1, 40);
+
+  /* Rope Simple. */
+  immUniformColor4f(color[0], color[1], color[2], 0.8f);
+  immBegin(GPU_PRIM_LINES, 2);
+  immVertex2f(pos, pt->x + region->winrct.xmin, pt->y + region->winrct.ymin);
+  immVertex2f(pos, x, y);
+  immEnd();
+
+  /* Returns back all GPU settings */
+  GPU_blend(false);
+  GPU_line_smooth(false);
+
+  immUnbindProgram();
+}
+
+/* Turn *stabilizer* brush cursor in 3D view on/off */
+static void gpencil_draw_toggle_stabilizer_cursor(bContext *C, tGPsdata *p, short enable)
+{
+  if (p->stabilizer_cursor && !enable) {
+    /* clear cursor */
+    WM_paint_cursor_end(CTX_wm_manager(C), p->stabilizer_cursor);
+    p->stabilizer_cursor = NULL;
+  }
+  else if (enable && !p->stabilizer_cursor) {
+    /* enable cursor */
+    p->stabilizer_cursor = WM_paint_cursor_activate(
+        CTX_wm_manager(C), SPACE_TYPE_ANY, RGN_TYPE_ANY, NULL, gpencil_draw_stabilizer, p);
+  }
+}
 
 /* Check if tablet eraser is being used (when processing events) */
 static bool gpencil_is_tablet_eraser_active(const wmEvent *event)
@@ -1745,6 +1830,9 @@ static void gpencil_draw_exit(bContext *C, wmOperator *op)
       /* turn off radial brush cursor */
       gpencil_draw_toggle_eraser_cursor(C, p, false);
     }
+    else if (p->paintmode == GP_PAINTMODE_DRAW) {
+      gpencil_draw_toggle_stabilizer_cursor(C, p, false);
+    }
 
     /* always store the new eraser size to be used again next time
      * NOTE: Do this even when not in eraser mode, as eraser may
@@ -1832,8 +1920,8 @@ static void gpencil_draw_status_indicators(bContext *C, tGPsdata *p)
                    "ESC/Enter to end  (or click outside this area)"));
           break;
         default:
-          /* Do nothing - the others are self explanatory, exit quickly once the mouse is released
-           * Showing any text would just be annoying as it would flicker.
+          /* Do nothing - the others are self explanatory, exit quickly once the mouse is
+           * released Showing any text would just be annoying as it would flicker.
            */
           break;
       }
@@ -1898,6 +1986,16 @@ static void gpencil_draw_apply(wmOperator *op, tGPsdata *p, Depsgraph *depsgraph
   /* Only add current point to buffer if mouse moved
    * (even though we got an event, it might be just noise). */
   else if (gp_stroke_filtermval(p, p->mval, p->mvalo)) {
+    /* If lazy mouse, interpolate the last and current mouse positions. */
+    if (p->flags & GP_PAINTFLAG_USE_STABILIZER_TEMP) {
+      float now_mouse[2];
+      float last_mouse[2];
+      copy_v2_v2(now_mouse, p->mval);
+      copy_v2_v2(last_mouse, p->mvalo);
+      interp_v2_v2v2(now_mouse, now_mouse, last_mouse, min_ff(p->stabilizer_factor, .995f));
+      copy_v2_v2(p->mval, now_mouse);
+    }
+
     /* try to add point */
     short ok = gp_stroke_addpoint(p, p->mval, p->pressure, p->curtime);
 
@@ -1941,7 +2039,7 @@ static void gpencil_draw_apply(wmOperator *op, tGPsdata *p, Depsgraph *depsgraph
 
 /* handle draw event */
 static void annotation_draw_apply_event(
-    wmOperator *op, const wmEvent *event, Depsgraph *depsgraph, float x, float y)
+    bContext *C, wmOperator *op, const wmEvent *event, Depsgraph *depsgraph, float x, float y)
 {
   tGPsdata *p = op->customdata;
   PointerRNA itemptr;
@@ -1953,8 +2051,23 @@ static void annotation_draw_apply_event(
   p->mval[0] = (float)event->mval[0] - x;
   p->mval[1] = (float)event->mval[1] - y;
 
+  /* Key to toggle stabilization. */
+  if (event->shift > 0 && p->paintmode == GP_PAINTMODE_DRAW) {
+    /* Using permanent stabilization, shift will deactivate the flag. */
+    if (p->flags & (GP_PAINTFLAG_USE_STABILIZER)) {
+      if (p->flags & GP_PAINTFLAG_USE_STABILIZER_TEMP) {
+        gpencil_draw_toggle_stabilizer_cursor(C, p, false);
+        p->flags &= ~GP_PAINTFLAG_USE_STABILIZER_TEMP;
+      }
+    }
+    /* Not using any stabilization flag. Activate temporal one. */
+    else if ((p->flags & GP_PAINTFLAG_USE_STABILIZER_TEMP) == 0) {
+      p->flags |= GP_PAINTFLAG_USE_STABILIZER_TEMP;
+      gpencil_draw_toggle_stabilizer_cursor(C, p, true);
+    }
+  }
   /* verify key status for straight lines */
-  if ((event->ctrl > 0) || (event->alt > 0)) {
+  else if ((event->ctrl > 0) || (event->alt > 0)) {
     if (p->straight[0] == 0) {
       int dx = abs((int)(p->mval[0] - p->mvalo[0]))

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list