[Bf-blender-cvs] [2234bfbcdb1] master: GPencil: Simplify sample modifier improvements.
YimingWu
noreply at git.blender.org
Tue Feb 22 05:55:12 CET 2022
Commit: 2234bfbcdb14299aa2ed28ed3ee6682c6d9a7a0c
Author: YimingWu
Date: Tue Feb 22 12:54:35 2022 +0800
Branches: master
https://developer.blender.org/rB2234bfbcdb14299aa2ed28ed3ee6682c6d9a7a0c
GPencil: Simplify sample modifier improvements.
1. Now handles cyclic strokes correctly.
2. Added a sharp threshold value to allow preservation of sharp corners.
Reviewed By: Antonio Vazquez (antoniov), Aleš Jelovčan (frogstomp)
Ref D14044
===================================================================
M source/blender/blenkernel/BKE_gpencil_geom.h
M source/blender/blenkernel/intern/gpencil_curve.c
M source/blender/blenkernel/intern/gpencil_geom.cc
M source/blender/editors/gpencil/gpencil_edit.c
M source/blender/editors/gpencil/gpencil_trace_utils.c
M source/blender/gpencil_modifiers/intern/MOD_gpencilsimplify.c
M source/blender/io/gpencil/intern/gpencil_io_export_pdf.cc
M source/blender/io/gpencil/intern/gpencil_io_export_svg.cc
M source/blender/makesdna/DNA_gpencil_modifier_types.h
M source/blender/makesrna/intern/rna_gpencil_modifier.c
===================================================================
diff --git a/source/blender/blenkernel/BKE_gpencil_geom.h b/source/blender/blenkernel/BKE_gpencil_geom.h
index eb61bd32eee..4127030e96f 100644
--- a/source/blender/blenkernel/BKE_gpencil_geom.h
+++ b/source/blender/blenkernel/BKE_gpencil_geom.h
@@ -208,11 +208,13 @@ void BKE_gpencil_point_coords_apply_with_mat4(struct bGPdata *gpd,
* \param gpd: Grease pencil data-block
* \param gps: Stroke to sample
* \param dist: Distance of one segment
+ * \param sharp_threshold: Threshold for preserving sharp corners
*/
bool BKE_gpencil_stroke_sample(struct bGPdata *gpd,
struct bGPDstroke *gps,
- float dist,
- bool select);
+ const float dist,
+ const bool select,
+ const float sharp_threshold);
/**
* Apply smooth position to stroke point.
* \param gps: Stroke to smooth
diff --git a/source/blender/blenkernel/intern/gpencil_curve.c b/source/blender/blenkernel/intern/gpencil_curve.c
index 5ce45f6df5a..ee6b77e6463 100644
--- a/source/blender/blenkernel/intern/gpencil_curve.c
+++ b/source/blender/blenkernel/intern/gpencil_curve.c
@@ -443,7 +443,7 @@ static void gpencil_convert_spline(Main *bmain,
}
if (sample > 0.0f) {
- BKE_gpencil_stroke_sample(gpd, gps, sample, false);
+ BKE_gpencil_stroke_sample(gpd, gps, sample, false, 0);
}
/* Recalc fill geometry. */
diff --git a/source/blender/blenkernel/intern/gpencil_geom.cc b/source/blender/blenkernel/intern/gpencil_geom.cc
index 365171b300f..1823d84d48d 100644
--- a/source/blender/blenkernel/intern/gpencil_geom.cc
+++ b/source/blender/blenkernel/intern/gpencil_geom.cc
@@ -202,8 +202,8 @@ static int stroke_march_next_point(const bGPDstroke *gps,
int next_point_index = index_next_pt;
bGPDspoint *pt = nullptr;
- if (!(next_point_index < gps->totpoints)) {
- return -1;
+ if (next_point_index == gps->totpoints) {
+ next_point_index = 0;
}
copy_v3_v3(step_start, current);
@@ -211,15 +211,33 @@ static int stroke_march_next_point(const bGPDstroke *gps,
copy_v3_v3(point, &pt->x);
remaining_till_next = len_v3v3(point, step_start);
- while (remaining_till_next < remaining_march) {
+ while (remaining_till_next < remaining_march && next_point_index) {
remaining_march -= remaining_till_next;
pt = &gps->points[next_point_index];
+ if (pt->flag & GP_SPOINT_TEMP_TAG) {
+ pt = &gps->points[next_point_index];
+ copy_v3_v3(result, &pt->x);
+ *pressure = gps->points[next_point_index].pressure;
+ *strength = gps->points[next_point_index].strength;
+ memcpy(vert_color, gps->points[next_point_index].vert_color, sizeof(float[4]));
+
+ *index_from = next_point_index == 0 ? (gps->totpoints - 1) : (next_point_index - 1);
+ *index_to = next_point_index;
+ *ratio_result = 1.0f;
+ next_point_index++;
+ return next_point_index == 0 ? gps->totpoints : next_point_index;
+ }
+ next_point_index++;
copy_v3_v3(point, &pt->x);
copy_v3_v3(step_start, point);
- next_point_index++;
if (!(next_point_index < gps->totpoints)) {
- next_point_index = gps->totpoints - 1;
- break;
+ if (gps->flag & GP_STROKE_CYCLIC) {
+ next_point_index = 0;
+ }
+ else {
+ next_point_index = gps->totpoints - 1;
+ break;
+ }
}
pt = &gps->points[next_point_index];
copy_v3_v3(point, &pt->x);
@@ -232,35 +250,37 @@ static int stroke_march_next_point(const bGPDstroke *gps,
*strength = gps->points[next_point_index].strength;
memcpy(vert_color, gps->points[next_point_index].vert_color, sizeof(float[4]));
- *index_from = next_point_index - 1;
+ *index_from = next_point_index == 0 ? (gps->totpoints - 1) : (next_point_index - 1);
*index_to = next_point_index;
*ratio_result = 1.0f;
return 0;
}
+ *index_from = next_point_index == 0 ? (gps->totpoints - 1) : (next_point_index - 1);
+ *index_to = next_point_index;
+
float ratio = remaining_march / remaining_till_next;
interp_v3_v3v3(result, step_start, point, ratio);
+ *ratio_result = ratio;
+
*pressure = interpf(
- gps->points[next_point_index].pressure, gps->points[next_point_index - 1].pressure, ratio);
+ gps->points[next_point_index].pressure, gps->points[*index_from].pressure, ratio);
*strength = interpf(
- gps->points[next_point_index].strength, gps->points[next_point_index - 1].strength, ratio);
+ gps->points[next_point_index].strength, gps->points[*index_from].strength, ratio);
interp_v4_v4v4(vert_color,
- gps->points[next_point_index - 1].vert_color,
+ gps->points[*index_from].vert_color,
gps->points[next_point_index].vert_color,
ratio);
- *index_from = next_point_index - 1;
- *index_to = next_point_index;
- *ratio_result = ratio;
-
- return next_point_index;
+ return next_point_index == 0 ? gps->totpoints : next_point_index;
}
static int stroke_march_next_point_no_interp(const bGPDstroke *gps,
const int index_next_pt,
const float *current,
const float dist,
+ const float sharp_threshold,
float *result)
{
float remaining_till_next = 0.0f;
@@ -270,8 +290,8 @@ static int stroke_march_next_point_no_interp(const bGPDstroke *gps,
int next_point_index = index_next_pt;
bGPDspoint *pt = nullptr;
- if (!(next_point_index < gps->totpoints)) {
- return -1;
+ if (next_point_index == gps->totpoints) {
+ next_point_index = 0;
}
copy_v3_v3(step_start, current);
@@ -279,15 +299,29 @@ static int stroke_march_next_point_no_interp(const bGPDstroke *gps,
copy_v3_v3(point, &pt->x);
remaining_till_next = len_v3v3(point, step_start);
- while (remaining_till_next < remaining_march) {
+ while (remaining_till_next < remaining_march && next_point_index) {
remaining_march -= remaining_till_next;
pt = &gps->points[next_point_index];
+ if (next_point_index < gps->totpoints - 1 &&
+ angle_v3v3v3(&gps->points[next_point_index - 1].x,
+ &gps->points[next_point_index].x,
+ &gps->points[next_point_index + 1].x) < sharp_threshold) {
+ copy_v3_v3(result, &pt->x);
+ pt->flag |= GP_SPOINT_TEMP_TAG;
+ next_point_index++;
+ return next_point_index == 0 ? gps->totpoints : next_point_index;
+ }
+ next_point_index++;
copy_v3_v3(point, &pt->x);
copy_v3_v3(step_start, point);
- next_point_index++;
if (!(next_point_index < gps->totpoints)) {
- next_point_index = gps->totpoints - 1;
- break;
+ if (gps->flag & GP_STROKE_CYCLIC) {
+ next_point_index = 0;
+ }
+ else {
+ next_point_index = gps->totpoints - 1;
+ break;
+ }
}
pt = &gps->points[next_point_index];
copy_v3_v3(point, &pt->x);
@@ -296,15 +330,16 @@ static int stroke_march_next_point_no_interp(const bGPDstroke *gps,
if (remaining_till_next < remaining_march) {
pt = &gps->points[next_point_index];
copy_v3_v3(result, &pt->x);
+ /* Stroke marching only terminates here. */
return 0;
}
float ratio = remaining_march / remaining_till_next;
interp_v3_v3v3(result, step_start, point, ratio);
- return next_point_index;
+ return next_point_index == 0 ? gps->totpoints : next_point_index;
}
-static int stroke_march_count(const bGPDstroke *gps, const float dist)
+static int stroke_march_count(const bGPDstroke *gps, const float dist, const float sharp_threshold)
{
int point_count = 0;
float point[3];
@@ -315,8 +350,13 @@ static int stroke_march_count(const bGPDstroke *gps, const float dist)
copy_v3_v3(point, &pt->x);
point_count++;
+ /* Sharp points will be tagged by the stroke_march_next_point_no_interp() call below. */
+ for (int i = 0; i < gps->totpoints; i++) {
+ gps->points[i].flag &= (~GP_SPOINT_TEMP_TAG);
+ }
+
while ((next_point_index = stroke_march_next_point_no_interp(
- gps, next_point_index, point, dist, point)) > -1) {
+ gps, next_point_index, point, dist, sharp_threshold, point)) > -1) {
point_count++;
if (next_point_index == 0) {
break; /* last point finished */
@@ -394,7 +434,11 @@ static void stroke_interpolate_deform_weights(
}
}
-bool BKE_gpencil_stroke_sample(bGPdata *gpd, bGPDstroke *gps, const float dist, const bool select)
+bool BKE_gpencil_stroke_sample(bGPdata *gpd,
+ bGPDstroke *gps,
+ const float dist,
+ const bool select,
+ const float sharp_threshold)
{
bGPDspoint *pt = gps->points;
bGPDspoint *pt1 = nullptr;
@@ -406,7 +450,7 @@ bool BKE_gpencil_stroke_sample(bGPdata *gpd, bGPDstroke *gps, const float dist,
return false;
}
/* TODO: Implement feature point preservation. */
- int count = stroke_march_count(gps, dist);
+ int count = stroke_march_count(gps, dist, sharp_threshold);
bGPDspoint *new_pt = (bGPDspoint *)MEM_callocN(sizeof(bGPDspoint) * count,
"gp_stroke_points_sampled");
@@ -491,6 +535,8 @@ bool BKE_gpencil_stroke_sample(bGPdata *gpd, bGPDstroke *gps, const float dist,
gps->totpoints = i;
+ gps->flag &= (~GP_STROKE_CYCLIC);
+
/* Calc geometry data. */
BKE_gpencil_stroke_geometry_update(gpd, gps);
diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c
index 680b313c47b..d734fb2678e 100644
--- a/source/blender/editors/gpencil/gpencil_edit.c
+++ b/source/blender/editors/gpencil/gpencil_edit.c
@@ -4356,6 +4356,7 @@ static int gpencil_stroke_sample_exec(bContext *C, wmOperator *op)
{
bGPdata *gpd = ED_gpencil_data_get_active(C);
const float length = RNA_float_get(op->ptr, "length");
+ const float sharp_threshold = RNA_float_get(op->ptr, "sharp_threshold");
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list