Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntonioya <blendergit@gmail.com>2019-08-15 18:49:55 +0300
committerAntonioya <blendergit@gmail.com>2019-08-17 13:51:05 +0300
commit0e1d4dec7a7d50867c97179299775d31ac30938e (patch)
tree1c12c30c6fac5e840582b5c2f539b176eb1c8fc8
parenta477c2e0e07943553e319d430dce0df1015d790b (diff)
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
-rw-r--r--source/blender/blenkernel/intern/gpencil.c119
-rw-r--r--source/blender/editors/gpencil/gpencil_edit.c4
2 files changed, 83 insertions, 40 deletions
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);