[Bf-blender-cvs] [e70e618ce74] temp-gpencil-bezier-stroke-type: GPencil: Curve smoothing BKE

Falk David noreply at git.blender.org
Fri Apr 30 15:47:54 CEST 2021


Commit: e70e618ce74521b007a78fad3b08f279aa446d42
Author: Falk David
Date:   Fri Apr 30 15:47:42 2021 +0200
Branches: temp-gpencil-bezier-stroke-type
https://developer.blender.org/rBe70e618ce74521b007a78fad3b08f279aa446d42

GPencil: Curve smoothing BKE

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

M	source/blender/blenkernel/BKE_gpencil_curve.h
M	source/blender/blenkernel/intern/gpencil_curve.c
M	source/blender/editors/gpencil/gpencil_edit.c

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

diff --git a/source/blender/blenkernel/BKE_gpencil_curve.h b/source/blender/blenkernel/BKE_gpencil_curve.h
index 9afe660031c..0ba2c531da9 100644
--- a/source/blender/blenkernel/BKE_gpencil_curve.h
+++ b/source/blender/blenkernel/BKE_gpencil_curve.h
@@ -74,7 +74,15 @@ bool BKE_gpencil_editcurve_recalculate_handles(struct bGPDstroke *gps);
 void BKE_gpencil_editcurve_subdivide(struct bGPDstroke *gps, const int cuts);
 void BKE_gpencil_editcurve_simplify_adaptive(struct bGPDstroke *gps, const float threshold);
 void BKE_gpencil_editcurve_simplify_fixed(struct bGPDstroke *gps, const int count);
-
+void BKE_gpencil_editcurve_smooth(struct bGPDstroke *gps,
+                                  const float factor,
+                                  const uint step_size,
+                                  const uint repeat,
+                                  const bool only_selected,
+                                  const bool affect_endpoints,
+                                  const bool do_positions,
+                                  const bool do_pressure,
+                                  const bool do_strength);
 #ifdef __cplusplus
 }
 #endif
diff --git a/source/blender/blenkernel/intern/gpencil_curve.c b/source/blender/blenkernel/intern/gpencil_curve.c
index 82c890f5680..80120236dcf 100644
--- a/source/blender/blenkernel/intern/gpencil_curve.c
+++ b/source/blender/blenkernel/intern/gpencil_curve.c
@@ -2092,4 +2092,140 @@ void BKE_gpencil_editcurve_simplify_fixed(bGPDstroke *gps, const int count)
   }
 }
 
+/**
+ * Smooth curve
+ */
+void BKE_gpencil_editcurve_smooth(bGPDstroke *gps,
+                                  const float factor,
+                                  const uint step_size,
+                                  const uint repeat,
+                                  const bool only_selected,
+                                  const bool affect_endpoints,
+                                  const bool do_positions,
+                                  const bool do_pressure,
+                                  const bool do_strength)
+{
+  bGPDcurve *gpc = gps->editcurve;
+  if (gpc == NULL || gpc->tot_curve_points < 2 || factor == 0.0f || repeat < 1) {
+    return;
+  }
+
+  if (!(do_positions || do_pressure || do_strength)) {
+    return;
+  }
+
+  const bool is_cyclic = gps->flag & GP_STROKE_CYCLIC;
+  /* Total number of cubic points. */
+  const uint tot_points = gpc->tot_curve_points * 3;
+  for (uint r = 0; r < repeat; r++) {
+    /**/
+    uint start_idx = (affect_endpoints || is_cyclic) ? 0 : 2;
+    uint end_idx = (affect_endpoints || is_cyclic) ? tot_points : tot_points - 2;
+
+    for (uint i = start_idx; i < end_idx; i++) {
+      /* bGPDcurve_point index */
+      uint pt_idx = i / 3;
+      /* BezTriple handle index */
+      uint hd_idx = i % 3;
+
+      bGPDcurve_point *gpc_pt = &gpc->curve_points[pt_idx];
+      if ((gpc_pt->flag & GP_CURVE_POINT_SELECT) == 0 && only_selected) {
+        continue;
+      }
+      BezTriple *bezt = &gpc_pt->bezt;
+      float sco[3] = {0.0f};
+      float smoothed_pressure = 0.0f;
+      float smoothed_strength = 0.0f;
+
+      const float average_fac = 1.0f / (float)(step_size * 2 + 1);
+
+      if (do_positions) {
+        /* Include the current point. */
+        madd_v3_v3fl(sco, bezt->vec[hd_idx], average_fac);
+
+        for (uint step = 1; step <= step_size; step++) {
+          int prev_idx = i - step;
+          int next_idx = i + step;
+
+          if (is_cyclic) {
+            prev_idx = mod_i(prev_idx, tot_points);
+            next_idx = next_idx % tot_points;
+          }
+          else {
+            CLAMP_MIN(prev_idx, 0);
+            CLAMP_MAX(next_idx, tot_points - 1);
+          }
+
+          uint prev_pt_idx = prev_idx / 3;
+          uint prev_hd_idx = prev_idx % 3;
+          uint next_pt_idx = next_idx / 3;
+          uint next_hd_idx = next_idx % 3;
+
+          bGPDcurve_point *gpc_prev_pt = &gpc->curve_points[prev_pt_idx];
+          bGPDcurve_point *gpc_next_pt = &gpc->curve_points[next_pt_idx];
+          BezTriple *prev_bezt = &gpc_prev_pt->bezt;
+          BezTriple *next_bezt = &gpc_next_pt->bezt;
+
+          madd_v3_v3fl(sco, prev_bezt->vec[prev_hd_idx], average_fac);
+          madd_v3_v3fl(sco, next_bezt->vec[next_hd_idx], average_fac);
+        }
+
+        interp_v3_v3v3(bezt->vec[hd_idx], bezt->vec[hd_idx], sco, factor);
+      }
+
+      if (do_pressure && hd_idx == 1) {
+        /* Include the current point. */
+        smoothed_pressure += gpc_pt->pressure * average_fac;
+
+        for (uint step = 1; step <= step_size; step++) {
+          int prev_idx = pt_idx - step;
+          int next_idx = pt_idx + step;
+
+          if (is_cyclic) {
+            prev_idx = mod_i(prev_idx, gpc->tot_curve_points);
+            next_idx = next_idx % gpc->tot_curve_points;
+          }
+          else {
+            CLAMP_MIN(prev_idx, 0);
+            CLAMP_MAX(next_idx, gpc->tot_curve_points - 1);
+          }
+
+          bGPDcurve_point *gpc_prev_pt = &gpc->curve_points[prev_idx];
+          bGPDcurve_point *gpc_next_pt = &gpc->curve_points[next_idx];
+          smoothed_pressure += gpc_prev_pt->pressure * average_fac;
+          smoothed_pressure += gpc_next_pt->pressure * average_fac;
+        }
+
+        gpc_pt->pressure = interpf(smoothed_pressure, gpc_pt->pressure, factor);
+      }
+
+      if (do_strength && hd_idx == 1) {
+        /* Include the current point. */
+        smoothed_strength += gpc_pt->strength * average_fac;
+
+        for (uint step = 1; step <= step_size; step++) {
+          int prev_idx = pt_idx - step;
+          int next_idx = pt_idx + step;
+
+          if (is_cyclic) {
+            prev_idx = mod_i(prev_idx, gpc->tot_curve_points);
+            next_idx = next_idx % gpc->tot_curve_points;
+          }
+          else {
+            CLAMP_MIN(prev_idx, 0);
+            CLAMP_MAX(next_idx, gpc->tot_curve_points - 1);
+          }
+
+          bGPDcurve_point *gpc_prev_pt = &gpc->curve_points[prev_idx];
+          bGPDcurve_point *gpc_next_pt = &gpc->curve_points[next_idx];
+          smoothed_strength += gpc_prev_pt->strength * average_fac;
+          smoothed_strength += gpc_next_pt->strength * average_fac;
+        }
+
+        gpc_pt->strength = interpf(smoothed_strength, gpc_pt->strength, factor);
+      }
+    }
+  }
+}
+
 /** \} */
diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c
index 0f402334a61..5c270d5ffc9 100644
--- a/source/blender/editors/gpencil/gpencil_edit.c
+++ b/source/blender/editors/gpencil/gpencil_edit.c
@@ -1935,8 +1935,8 @@ static int gpencil_move_to_layer_exec(bContext *C, wmOperator *op)
           }
 
           bool is_stroke_selected = GPENCIL_STROKE_TYPE_BEZIER(gps) ?
-                                    gps->editcurve->flag & GP_CURVE_SELECT :
-                                    gps->flag & GP_STROKE_SELECT;
+                                        gps->editcurve->flag & GP_CURVE_SELECT :
+                                        gps->flag & GP_STROKE_SELECT;
 
           /* TODO: Don't just move entire strokes - instead, only copy the selected portions... */
           if (is_stroke_selected) {
@@ -4295,6 +4295,22 @@ static void gpencil_smooth_stroke(bContext *C, wmOperator *op)
         }
       }
     }
+    else if (GPENCIL_STROKE_TYPE_BEZIER(gps)) {
+      bGPDcurve *gpc = gps->editcurve;
+      if (gpc->flag & GP_CURVE_SELECT) {
+        BKE_gpencil_editcurve_smooth(gps,
+                                     factor,
+                                     2,
+                                     repeat,
+                                     only_selected,
+                                     false,
+                                     smooth_position,
+                                     smooth_thickness,
+                                     smooth_strength);
+        BKE_gpencil_editcurve_recalculate_handles(gps);
+        BKE_gpencil_stroke_geometry_update(gpd_, gps, GP_GEO_UPDATE_DEFAULT);
+      }
+    }
   }
   GP_EDITABLE_STROKES_END(gpstroke_iter);
 }
@@ -5390,7 +5406,7 @@ void GPENCIL_OT_stroke_smooth(wmOperatorType *ot)
   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);
+  RNA_def_float(ot->srna, "factor", 0.5f, 0.0f, 2.0f, "Factor", "", 0.0f, 1.0f);
   RNA_def_boolean(ot->srna,
                   "only_selected",
                   true,



More information about the Bf-blender-cvs mailing list