[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