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:
Diffstat (limited to 'source/blender/editors/gpencil/gpencil_utils.c')
-rw-r--r--source/blender/editors/gpencil/gpencil_utils.c98
1 files changed, 98 insertions, 0 deletions
diff --git a/source/blender/editors/gpencil/gpencil_utils.c b/source/blender/editors/gpencil/gpencil_utils.c
index a23628e6507..8e56cf8199e 100644
--- a/source/blender/editors/gpencil/gpencil_utils.c
+++ b/source/blender/editors/gpencil/gpencil_utils.c
@@ -533,4 +533,102 @@ bool gp_point_xy_to_3d(GP_SpaceConversion *gsc, Scene *scene, const float screen
}
}
+/* Apply smooth to stroke point
+* gps Stroke to smooth
+* i Point index
+* inf Smooth factor
+*/
+bool gp_smooth_stroke(bGPDstroke *gps, int i, float inf)
+{
+ bGPDspoint *pt = &gps->points[i];
+ float sco[3] = { 0.0f };
+
+ /* Do nothing if not enough points to smooth out */
+ if (gps->totpoints <= 2) {
+ return false;
+ }
+
+ /* Only affect endpoints by a fraction of the normal strength,
+ * to prevent the stroke from shrinking too much
+ */
+ if ((i == 0) || (i == gps->totpoints - 1)) {
+ inf *= 0.1f;
+ }
+
+ /* Compute smoothed coordinate by taking the ones nearby */
+ /* XXX: This is potentially slow, and suffers from accumulation error as earlier points are handled before later ones */
+ {
+ // XXX: this is hardcoded to look at 2 points on either side of the current one (i.e. 5 items total)
+ const int steps = 2;
+ const float average_fac = 1.0f / (float)(steps * 2 + 1);
+ int step;
+
+ /* add the point itself */
+ madd_v3_v3fl(sco, &pt->x, average_fac);
+
+ /* n-steps before/after current point */
+ // XXX: review how the endpoints are treated by this algorithm
+ // XXX: falloff measures should also introduce some weighting variations, so that further-out points get less weight
+ for (step = 1; step <= steps; step++) {
+ bGPDspoint *pt1, *pt2;
+ int before = i - step;
+ int after = i + step;
+
+ 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) */
+ madd_v3_v3fl(sco, &pt1->x, average_fac);
+ madd_v3_v3fl(sco, &pt2->x, average_fac);
+
+ }
+ }
+
+ /* Based on influence factor, blend between original and optimal smoothed coordinate */
+ interp_v3_v3v3(&pt->x, &pt->x, sco, inf);
+
+ return true;
+}
+
+/* subdivide a stroke
+* gps Stroke data
+* new_totpoints Total number of points
+*/
+void gp_subdivide_stroke(bGPDstroke *gps, const int new_totpoints)
+{
+ int i;
+ // Subdivide stroke adding a point half way existing points
+ bGPDspoint *pt_a;
+ bGPDspoint *pt_b;
+ bGPDspoint *pt_n;
+
+ /* Move points to insert subdivision */
+ int y = 1;
+ for (i = gps->totpoints - 1; i > 0; --i)
+ {
+ pt_n = &gps->points[i];
+ gps->points[new_totpoints - y] = *pt_n;
+ y = y + 2;
+ }
+ /* Create interpolated points */
+ for (i = 0; i < new_totpoints - 1; ++i)
+ {
+ pt_a = &gps->points[i];
+ pt_n = &gps->points[i + 1];
+ pt_b = &gps->points[i + 2];
+ // Interpolate all values
+ interp_v3_v3v3(&pt_n->x, &pt_a->x, &pt_b->x, 0.5f);
+ pt_n->pressure = interpf(pt_a->pressure, pt_b->pressure, 0.5f);
+ pt_n->time = interpf(pt_a->time, pt_b->time, 0.5f);
+
+ ++i; // add to loop to jump next pair
+ }
+
+ gps->totpoints = new_totpoints; // Increase number of points
+
+}
+
/* ******************************************************** */