[Bf-blender-cvs] [0e1d4dec7a7] master: Fix T68722: Improve Smooth algorithm for Thickness and Strength

Antonioya noreply at git.blender.org
Sat Aug 17 12:52:27 CEST 2019


Commit: 0e1d4dec7a7d50867c97179299775d31ac30938e
Author: Antonioya
Date:   Thu Aug 15 17:49:55 2019 +0200
Branches: master
https://developer.blender.org/rB0e1d4dec7a7d50867c97179299775d31ac30938e

Fix T68722: Improve Smooth algorithm for Thickness and Strength

Now the GPencil smooth algorithm uses a average value instead to use only two points and the interpolated value.

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

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

M	source/blender/blenkernel/intern/gpencil.c
M	source/blender/editors/gpencil/gpencil_edit.c

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

diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c
index 728f4890189..0354aeaf0ca 100644
--- a/source/blender/blenkernel/intern/gpencil.c
+++ b/source/blender/blenkernel/intern/gpencil.c
@@ -1784,33 +1784,55 @@ bool BKE_gpencil_smooth_stroke_strength(bGPDstroke *gps, int point_index, float
   bGPDspoint *ptb = &gps->points[point_index];
 
   /* Do nothing if not enough points */
-  if (gps->totpoints <= 2) {
+  if ((gps->totpoints <= 2) || (point_index < 1)) {
     return false;
   }
+  /* Only affect endpoints by a fraction of the normal influence */
+  float inf = influence;
+  if ((point_index == 0) || (point_index == gps->totpoints - 1)) {
+    inf *= 0.01f;
+  }
+  /* Limit max influence to reduce pop effect. */
+  CLAMP_MAX(inf, 0.98f);
 
-  /* Compute theoretical optimal value using distances */
-  bGPDspoint *pta, *ptc;
-  int before = point_index - 1;
-  int after = point_index + 1;
+  float total = 0.0f;
+  float max_strength = 0.0f;
+  const int steps = 4;
+  const float average_fac = 1.0f / (float)(steps * 2 + 1);
+  int step;
 
-  CLAMP_MIN(before, 0);
-  CLAMP_MAX(after, gps->totpoints - 1);
+  /* add the point itself */
+  total += ptb->strength * average_fac;
+  max_strength = ptb->strength;
 
-  pta = &gps->points[before];
-  ptc = &gps->points[after];
+  /* n-steps before/after current point */
+  for (step = 1; step <= steps; step++) {
+    bGPDspoint *pt1, *pt2;
+    int before = point_index - step;
+    int after = point_index + step;
 
-  /* the optimal value is the corresponding to the interpolation of the strength
-   * at the distance of point b
-   */
-  float fac = line_point_factor_v3(&ptb->x, &pta->x, &ptc->x);
-  /* sometimes the factor can be wrong due stroke geometry, so use middle point */
-  if ((fac < 0.0f) || (fac > 1.0f)) {
-    fac = 0.5f;
+    CLAMP_MIN(before, 0);
+    CLAMP_MAX(after, gps->totpoints - 1);
+
+    pt1 = &gps->points[before];
+    pt2 = &gps->points[after];
+
+    /* add both these points to the average-sum (s += p[i]/n) */
+    total += pt1->strength * average_fac;
+    total += pt2->strength * average_fac;
+    /* Save max value. */
+    if (max_strength < pt1->strength) {
+      max_strength = pt1->strength;
+    }
+    if (max_strength < pt2->strength) {
+      max_strength = pt2->strength;
+    }
   }
-  const float optimal = (1.0f - fac) * pta->strength + fac * ptc->strength;
 
-  /* Based on influence factor, blend between original and optimal */
-  ptb->strength = (1.0f - influence) * ptb->strength + influence * optimal;
+  /* Based on influence factor, blend between original and optimal smoothed value. */
+  ptb->strength = interpf(ptb->strength, total, inf);
+  /* Clamp to maximum stroke strength to avoid weird results. */
+  CLAMP_MAX(ptb->strength, max_strength);
 
   return true;
 }
@@ -1825,31 +1847,52 @@ bool BKE_gpencil_smooth_stroke_thickness(bGPDstroke *gps, int point_index, float
   if ((gps->totpoints <= 2) || (point_index < 1)) {
     return false;
   }
+  /* Only affect endpoints by a fraction of the normal influence */
+  float inf = influence;
+  if ((point_index == 0) || (point_index == gps->totpoints - 1)) {
+    inf *= 0.01f;
+  }
+  /* Limit max influence to reduce pop effect. */
+  CLAMP_MAX(inf, 0.98f);
 
-  /* Compute theoretical optimal value using distances */
-  bGPDspoint *pta, *ptc;
-  int before = point_index - 1;
-  int after = point_index + 1;
+  float total = 0.0f;
+  float max_pressure = 0.0f;
+  const int steps = 4;
+  const float average_fac = 1.0f / (float)(steps * 2 + 1);
+  int step;
 
-  CLAMP_MIN(before, 0);
-  CLAMP_MAX(after, gps->totpoints - 1);
+  /* add the point itself */
+  total += ptb->pressure * average_fac;
+  max_pressure = ptb->pressure;
 
-  pta = &gps->points[before];
-  ptc = &gps->points[after];
+  /* n-steps before/after current point */
+  for (step = 1; step <= steps; step++) {
+    bGPDspoint *pt1, *pt2;
+    int before = point_index - step;
+    int after = point_index + step;
 
-  /* the optimal value is the corresponding to the interpolation of the pressure
-   * at the distance of point b
-   */
-  float fac = line_point_factor_v3(&ptb->x, &pta->x, &ptc->x);
-  /* sometimes the factor can be wrong due stroke geometry, so use middle point */
-  if ((fac < 0.0f) || (fac > 1.0f)) {
-    fac = 0.5f;
-  }
-  float optimal = interpf(ptc->pressure, pta->pressure, fac);
+    CLAMP_MIN(before, 0);
+    CLAMP_MAX(after, gps->totpoints - 1);
 
-  /* Based on influence factor, blend between original and optimal */
-  ptb->pressure = interpf(optimal, ptb->pressure, influence);
+    pt1 = &gps->points[before];
+    pt2 = &gps->points[after];
+
+    /* add both these points to the average-sum (s += p[i]/n) */
+    total += pt1->pressure * average_fac;
+    total += pt2->pressure * average_fac;
+    /* Save max value. */
+    if (max_pressure < pt1->pressure) {
+      max_pressure = pt1->pressure;
+    }
+    if (max_pressure < pt2->pressure) {
+      max_pressure = pt2->pressure;
+    }
+  }
 
+  /* Based on influence factor, blend between original and optimal smoothed value. */
+  ptb->pressure = interpf(ptb->pressure, total, inf);
+  /* Clamp to maximum stroke thickness to avoid weird results. */
+  CLAMP_MAX(ptb->pressure, max_pressure);
   return true;
 }
 
diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c
index f509be9312a..878f7a1995b 100644
--- a/source/blender/editors/gpencil/gpencil_edit.c
+++ b/source/blender/editors/gpencil/gpencil_edit.c
@@ -3546,7 +3546,7 @@ static void gp_smooth_stroke(bContext *C, wmOperator *op)
           }
           if (smooth_thickness) {
             /* thickness need to repeat process several times */
-            for (int r2 = 0; r2 < r * 10; r2++) {
+            for (int r2 = 0; r2 < r * 20; r2++) {
               BKE_gpencil_smooth_stroke_thickness(gps, i, factor);
             }
           }
@@ -4302,7 +4302,7 @@ void GPENCIL_OT_stroke_smooth(wmOperatorType *ot)
   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
 
   /* properties */
-  prop = RNA_def_int(ot->srna, "repeat", 1, 1, 10, "Repeat", "", 1, 5);
+  prop = RNA_def_int(ot->srna, "repeat", 1, 1, 50, "Repeat", "", 1, 20);
   RNA_def_property_flag(prop, PROP_SKIP_SAVE);
 
   RNA_def_float(ot->srna, "factor", 0.5f, 0.0f, 2.0f, "Factor", "", 0.0f, 2.0f);



More information about the Bf-blender-cvs mailing list