[Bf-blender-cvs] [ae334532cff] master: GPencil: Smooth thickness when joining strokes

Antonio Vazquez noreply at git.blender.org
Fri Sep 3 15:31:15 CEST 2021


Commit: ae334532cffb2dd9074454b9a7ba095430f18735
Author: Antonio Vazquez
Date:   Fri Sep 3 15:24:01 2021 +0200
Branches: master
https://developer.blender.org/rBae334532cffb2dd9074454b9a7ba095430f18735

GPencil: Smooth thickness when joining strokes

When joining two strokes in paint mode using the auto merge option, the join was very hard if the thickness was too different.

This patch adds a smooth to the join in order to get better transition.

Also fixed the problem to join existing strokes very far from actual stroke.

Some cleanup and rename of old code is included in order to make code more readable.

Reviewed By: pepeland

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

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

M	source/blender/blenkernel/BKE_gpencil_geom.h
M	source/blender/blenkernel/intern/gpencil_geom.cc
M	source/blender/editors/gpencil/gpencil_edit.c
M	source/blender/editors/gpencil/gpencil_fill.c
M	source/blender/editors/gpencil/gpencil_interpolate.c
M	source/blender/editors/gpencil/gpencil_paint.c
M	source/blender/editors/gpencil/gpencil_primitive.c
M	source/blender/editors/gpencil/gpencil_sculpt_paint.c
M	source/blender/editors/gpencil/gpencil_utils.c
M	source/blender/editors/include/ED_gpencil.h
M	source/blender/gpencil_modifiers/intern/MOD_gpencilsmooth.c

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

diff --git a/source/blender/blenkernel/BKE_gpencil_geom.h b/source/blender/blenkernel/BKE_gpencil_geom.h
index 29e3a74b1b2..d472fd6f02b 100644
--- a/source/blender/blenkernel/BKE_gpencil_geom.h
+++ b/source/blender/blenkernel/BKE_gpencil_geom.h
@@ -101,7 +101,7 @@ bool BKE_gpencil_stroke_sample(struct bGPdata *gpd,
                                struct bGPDstroke *gps,
                                const float dist,
                                const bool select);
-bool BKE_gpencil_stroke_smooth(struct bGPDstroke *gps, int i, float inf);
+bool BKE_gpencil_stroke_smooth_point(struct bGPDstroke *gps, int i, float inf);
 bool BKE_gpencil_stroke_smooth_strength(struct bGPDstroke *gps, int point_index, float influence);
 bool BKE_gpencil_stroke_smooth_thickness(struct bGPDstroke *gps, int point_index, float influence);
 bool BKE_gpencil_stroke_smooth_uv(struct bGPDstroke *gps, int point_index, float influence);
@@ -151,7 +151,8 @@ void BKE_gpencil_stroke_set_random_color(struct bGPDstroke *gps);
 void BKE_gpencil_stroke_join(struct bGPDstroke *gps_a,
                              struct bGPDstroke *gps_b,
                              const bool leave_gaps,
-                             const bool fit_thickness);
+                             const bool fit_thickness,
+                             const bool smooth);
 void BKE_gpencil_stroke_copy_to_keyframes(struct bGPdata *gpd,
                                           struct bGPDlayer *gpl,
                                           struct bGPDframe *gpf,
diff --git a/source/blender/blenkernel/intern/gpencil_geom.cc b/source/blender/blenkernel/intern/gpencil_geom.cc
index 5bca20ecd44..8ff026231f5 100644
--- a/source/blender/blenkernel/intern/gpencil_geom.cc
+++ b/source/blender/blenkernel/intern/gpencil_geom.cc
@@ -800,7 +800,7 @@ bool BKE_gpencil_stroke_shrink(bGPDstroke *gps, const float dist, const short mo
  * \param i: Point index
  * \param inf: Amount of smoothing to apply
  */
-bool BKE_gpencil_stroke_smooth(bGPDstroke *gps, int i, float inf)
+bool BKE_gpencil_stroke_smooth_point(bGPDstroke *gps, int i, float inf)
 {
   bGPDspoint *pt = &gps->points[i];
   float sco[3] = {0.0f};
@@ -3248,7 +3248,8 @@ static void gpencil_stroke_copy_point(bGPDstroke *gps,
 void BKE_gpencil_stroke_join(bGPDstroke *gps_a,
                              bGPDstroke *gps_b,
                              const bool leave_gaps,
-                             const bool fit_thickness)
+                             const bool fit_thickness,
+                             const bool smooth)
 {
   bGPDspoint point;
   bGPDspoint *pt;
@@ -3326,16 +3327,51 @@ void BKE_gpencil_stroke_join(bGPDstroke *gps_a,
     gpencil_stroke_copy_point(gps_a, nullptr, &point, delta, 0.0f, 0.0f, deltatime);
   }
 
+  /* Ratio to apply in the points to keep the same thickness in the joined stroke using the
+   * destination stroke thickness. */
   const float ratio = (fit_thickness && gps_a->thickness > 0.0f) ?
                           (float)gps_b->thickness / (float)gps_a->thickness :
                           1.0f;
 
   /* 3rd: add all points */
+  const int totpoints_a = gps_a->totpoints;
   for (i = 0, pt = gps_b->points; i < gps_b->totpoints && pt; i++, pt++) {
     MDeformVert *dvert = (gps_b->dvert) ? &gps_b->dvert[i] : nullptr;
     gpencil_stroke_copy_point(
         gps_a, dvert, pt, delta, pt->pressure * ratio, pt->strength, deltatime);
   }
+  /* Smooth the join to avoid hard thickness changes. */
+  if (smooth) {
+    const int sample_points = 8;
+    /* Get the segment to smooth using n points on each side of the join. */
+    int start = MAX2(0, totpoints_a - sample_points);
+    int end = MIN2(gps_a->totpoints - 1, start + (sample_points * 2));
+    const int len = (end - start);
+    float step = 1.0f / ((len / 2) + 1);
+
+    /* Calc the average pressure. */
+    float avg_pressure = 0.0f;
+    for (i = start; i < end; i++) {
+      pt = &gps_a->points[i];
+      avg_pressure += pt->pressure;
+    }
+    avg_pressure = avg_pressure / len;
+
+    /* Smooth segment thickness and position. */
+    float ratio = step;
+    for (i = start; i < end; i++) {
+      pt = &gps_a->points[i];
+      pt->pressure += (avg_pressure - pt->pressure) * ratio;
+      BKE_gpencil_stroke_smooth_point(gps_a, i, ratio * 0.6f);
+
+      ratio += step;
+      /* In the center, reverse the ratio. */
+      if (ratio > 1.0f) {
+        ratio = ratio - step - step;
+        step *= -1.0f;
+      }
+    }
+  }
 }
 
 /* Copy the stroke of the frame to all frames selected (except current). */
diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c
index 8d1f841da6c..aa3178ddc2c 100644
--- a/source/blender/editors/gpencil/gpencil_edit.c
+++ b/source/blender/editors/gpencil/gpencil_edit.c
@@ -3618,7 +3618,7 @@ static int gpencil_stroke_join_exec(bContext *C, wmOperator *op)
     }
     elem = &strokes_list[i];
     /* Join new_stroke and stroke B. */
-    BKE_gpencil_stroke_join(gps_new, elem->gps, leave_gaps, true);
+    BKE_gpencil_stroke_join(gps_new, elem->gps, leave_gaps, true, false);
     elem->used = true;
   }
 
@@ -3967,7 +3967,7 @@ static void gpencil_smooth_stroke(bContext *C, wmOperator *op)
 
           /* perform smoothing */
           if (smooth_position) {
-            BKE_gpencil_stroke_smooth(gps, i, factor);
+            BKE_gpencil_stroke_smooth_point(gps, i, factor);
           }
           if (smooth_strength) {
             BKE_gpencil_stroke_smooth_strength(gps, i, factor);
diff --git a/source/blender/editors/gpencil/gpencil_fill.c b/source/blender/editors/gpencil/gpencil_fill.c
index 0c88d678ef4..f5474a7cdc3 100644
--- a/source/blender/editors/gpencil/gpencil_fill.c
+++ b/source/blender/editors/gpencil/gpencil_fill.c
@@ -1569,7 +1569,7 @@ static void gpencil_stroke_from_buffer(tGPDfill *tgpf)
   float smoothfac = 1.0f;
   for (int r = 0; r < 1; r++) {
     for (int i = 0; i < gps->totpoints; i++) {
-      BKE_gpencil_stroke_smooth(gps, i, smoothfac - reduce);
+      BKE_gpencil_stroke_smooth_point(gps, i, smoothfac - reduce);
     }
     reduce += 0.25f; /* reduce the factor */
   }
diff --git a/source/blender/editors/gpencil/gpencil_interpolate.c b/source/blender/editors/gpencil/gpencil_interpolate.c
index a8bd3b11bb1..fdd9f44605e 100644
--- a/source/blender/editors/gpencil/gpencil_interpolate.c
+++ b/source/blender/editors/gpencil/gpencil_interpolate.c
@@ -333,7 +333,7 @@ static void gpencil_interpolate_smooth_stroke(bGPDstroke *gps,
   float reduce = 0.0f;
   for (int r = 0; r < smooth_steps; r++) {
     for (int i = 0; i < gps->totpoints - 1; i++) {
-      BKE_gpencil_stroke_smooth(gps, i, smooth_factor - reduce);
+      BKE_gpencil_stroke_smooth_point(gps, i, smooth_factor - reduce);
       BKE_gpencil_stroke_smooth_strength(gps, i, smooth_factor);
     }
     reduce += 0.25f; /* reduce the factor */
diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c
index 28a22633742..9b157224178 100644
--- a/source/blender/editors/gpencil/gpencil_paint.c
+++ b/source/blender/editors/gpencil/gpencil_paint.c
@@ -1209,7 +1209,8 @@ static void gpencil_stroke_newfrombuffer(tGPsdata *p)
       float reduce = 0.0f;
       for (int r = 0; r < brush->gpencil_settings->draw_smoothlvl; r++) {
         for (i = 0; i < gps->totpoints - 1; i++) {
-          BKE_gpencil_stroke_smooth(gps, i, brush->gpencil_settings->draw_smoothfac - reduce);
+          BKE_gpencil_stroke_smooth_point(
+              gps, i, brush->gpencil_settings->draw_smoothfac - reduce);
           BKE_gpencil_stroke_smooth_strength(gps, i, brush->gpencil_settings->draw_smoothfac);
         }
         reduce += 0.25f; /* reduce the factor */
@@ -1221,7 +1222,7 @@ static void gpencil_stroke_newfrombuffer(tGPsdata *p)
       float ifac = (float)brush->gpencil_settings->input_samples / 10.0f;
       float sfac = interpf(1.0f, 0.2f, ifac);
       for (i = 0; i < gps->totpoints - 1; i++) {
-        BKE_gpencil_stroke_smooth(gps, i, sfac);
+        BKE_gpencil_stroke_smooth_point(gps, i, sfac);
         BKE_gpencil_stroke_smooth_strength(gps, i, sfac);
       }
     }
@@ -1288,11 +1289,23 @@ static void gpencil_stroke_newfrombuffer(tGPsdata *p)
   /* Join with existing strokes. */
   if (ts->gpencil_flags & GP_TOOL_FLAG_AUTOMERGE_STROKE) {
     if (gps->prev != NULL) {
+      BKE_gpencil_stroke_boundingbox_calc(gps);
+      float diff_mat[4][4], ctrl1[2], ctrl2[2];
+      BKE_gpencil_layer_transform_matrix_get(depsgraph, p->ob, gpl, diff_mat);
+      ED_gpencil_stroke_extremes_to2d(&p->gsc, diff_mat, gps, ctrl1, ctrl2);
+
       int pt_index = 0;
       bool doit = true;
       while (doit && gps) {
-        bGPDstroke *gps_target = ED_gpencil_stroke_nearest_to_ends(
-            p->C, &p->gsc, gpl, gpl->actframe, gps, GPENCIL_MINIMUM_JOIN_DIST, &pt_index);
+        bGPDstroke *gps_target = ED_gpencil_stroke_nearest_to_ends(p->C,
+                                                                   &p->gsc,
+                                                                   gpl,
+                                                                   gpl->actframe,
+                                                                   gps,
+                                                                   ctrl1,
+                                                                   ctrl2,
+                                                                   GPENCIL_MINIMUM_JOIN_DIST,
+                                                                   &pt_index);
         if (gps_target != NULL) {
           gps = ED_gpencil_stroke_join_and_trim(p->gpd, p->gpf, gps, gps_target, pt_index);
         }
diff --git a/source/blender/editors/gpencil/gpencil_primitive.c b/source/blender/editors/gpencil/gpencil_primitive.c
index 5ecb6d9a212..f8cfc130e35 100644
--- a/source/blender/editors/gpencil/gpencil_primitive.c
+++ b/source/blender/editors/gpencil/gpencil_primitive.c
@@ -1382,11 +1382,23 @@ static void gpencil_primitive_interaction_end(bContext *C,
   if (ts->gpencil_flags & GP_TOOL_FLAG_AUTOMERGE_STROKE) {
     if (ELEM(tgpi->type, GP_STROKE_ARC, GP_STROKE_LINE, GP_STROKE_CURVE, GP_STROKE

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list