[Bf-blender-cvs] [990019de56d] greasepencil-object: GPencil: Add smooth in interpolated strokes

Antonio Vazquez noreply at git.blender.org
Wed Sep 25 09:44:07 CEST 2019


Commit: 990019de56d4097b1b688fd63406cdc0526ec432
Author: Antonio Vazquez
Date:   Wed Sep 25 09:42:59 2019 +0200
Branches: greasepencil-object
https://developer.blender.org/rB990019de56d4097b1b688fd63406cdc0526ec432

GPencil: Add smooth in interpolated strokes

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

M	source/blender/editors/gpencil/gpencil_paint.c

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

diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c
index 5e240b288ab..2aad2670ab4 100644
--- a/source/blender/editors/gpencil/gpencil_paint.c
+++ b/source/blender/editors/gpencil/gpencil_paint.c
@@ -636,6 +636,44 @@ static void gp_smooth_buffer(tGPsdata *p, float inf, int idx)
   ptc->strength = interpf(ptc->strength, strength, inf);
 }
 
+static void gp_smooth_fake_events(tGPsdata *p, int size_before, int size_after)
+{
+  bGPdata *gpd = p->gpd;
+  const short totpoints = size_after - size_before - 1;
+  /* Do nothing if not enough data to smooth out */
+  if (totpoints < 1) {
+    return;
+  }
+
+  /* Back two points to get smoother effect. */
+  size_before -= 2;
+  CLAMP_MIN(size_before, 1);
+
+  tGPspoint *points = (tGPspoint *)gpd->runtime.sbuffer;
+  /* Extreme points. */
+  const tGPspoint *pta = &points[size_before - 1];
+  const tGPspoint *ptb = &points[size_after - 1];
+  tGPspoint *pt1, *pt2;
+  int i;
+
+  /* Get total length of the segment to smooth. */
+  float totlen = 0.0f;
+  for (i = size_before; i < size_after; i++) {
+    pt1 = &points[i - 1];
+    pt2 = &points[i];
+    totlen += len_v2v2(&pt1->x, &pt2->x);
+  }
+  /* Smooth interpolating the position of the points. */
+  float pointlen = 0.0f;
+  for (i = size_before; i < size_after - 1; i++) {
+    pt1 = &points[i - 1];
+    pt2 = &points[i];
+    pointlen += len_v2v2(&pt1->x, &pt2->x);
+    pt2->pressure = interpf(ptb->pressure, pta->pressure, pointlen / totlen);
+    pt2->strength = interpf(ptb->strength, pta->strength, pointlen / totlen);
+  }
+}
+
 /* Apply subdivide to buffer while drawing
  *
  * \param p: Temp data
@@ -3478,7 +3516,7 @@ static void gpencil_move_last_stroke_to_back(bContext *C)
 }
 
 /* add events for missing mouse movements when the artist draw very fast */
-static void gpencil_add_missing_events(bContext *C,
+static bool gpencil_add_missing_events(bContext *C,
                                        wmOperator *op,
                                        const wmEvent *event,
                                        tGPsdata *p)
@@ -3487,14 +3525,14 @@ static void gpencil_add_missing_events(bContext *C,
   GP_Sculpt_Guide *guide = &p->scene->toolsettings->gp_sculpt.guide;
   Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
   int input_samples = brush->gpencil_settings->input_samples;
-
+  bool added_events = false;
   /* ensure sampling when using circular guide */
   if (guide->use_guide && (guide->type == GP_GUIDE_CIRCULAR)) {
     input_samples = GP_MAX_INPUT_SAMPLES;
   }
 
   if (input_samples == 0) {
-    return;
+    return added_events;
   }
 
   RegionView3D *rv3d = p->ar->regiondata;
@@ -3545,6 +3583,7 @@ static void gpencil_add_missing_events(bContext *C,
     sub_v2_v2v2(pt, b, pt);
     /* create fake event */
     gpencil_draw_apply_event(C, op, event, depsgraph, pt[0], pt[1]);
+    added_events = true;
   }
   else if (dist >= factor) {
     int slices = 2 + (int)((dist - 1.0) / factor);
@@ -3554,8 +3593,10 @@ static void gpencil_add_missing_events(bContext *C,
       sub_v2_v2v2(pt, b, pt);
       /* create fake event */
       gpencil_draw_apply_event(C, op, event, depsgraph, pt[0], pt[1]);
+      added_events = true;
     }
   }
+  return added_events;
 }
 
 /* events handling during interactive drawing part of operator */
@@ -3861,11 +3902,19 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
       /* handle drawing event */
       /* printf("\t\tGP - add point\n"); */
 
+      int size_before = p->gpd->runtime.sbuffer_used;
+      bool added_events = false;
       if (((p->flags & GP_PAINTFLAG_FIRSTRUN) == 0) && (p->paintmode != GP_PAINTMODE_ERASER)) {
-        gpencil_add_missing_events(C, op, event, p);
+        added_events = gpencil_add_missing_events(C, op, event, p);
       }
 
       gpencil_draw_apply_event(C, op, event, CTX_data_depsgraph_pointer(C), 0.0f, 0.0f);
+      int size_after = p->gpd->runtime.sbuffer_used;
+
+      /* Smooth the fake events to get smoother strokes, specially at ends. */
+      if ((added_events) && (size_before < size_after)) {
+        gp_smooth_fake_events(p, size_before, size_after);
+      }
 
       /* finish painting operation if anything went wrong just now */
       if (p->status == GP_STATUS_ERROR) {



More information about the Bf-blender-cvs mailing list