I have a proposition to refactor [gegl_]path_calc_values :
static void path_calc_values (GeglPathList *path,
+ gdouble pos_min,
+ gdouble pos_max,
guint num_samples,
gdouble *xs,
gdouble *ys)
This modification is consistent with gegl_curve_calc_values which can return a windowed lookup table.
The refactoring merge redundant code (path_calc and path_calc_values).
It also fixed what appeared to me as a bug : offset value was just dropped in the 'M' case, which could lead to a noticeable rounding error.
See attached patch :
[PATCH] Refactor [gegl_]path_calc_values
* moded gegl/property-types/gegl-path.[c|h]
Add pos_min and pos_max parameters to get sample points on an arbitrary portion of the path
This reduces code and should be very useful to extract gegl_path_stroke in a proper operation.
I did not build a test case yet (if anyone has such code and is willing to share, i'd be grateful).
Please review.
Regards.
Damien
From c82ebc3cb0cf7dad45eedc6122bf901215d49ed7 Mon Sep 17 00:00:00 2001 From: Damien de Lemeny <d.delemeny@xxxxxxxxx> Date: Sun, 30 May 2010 04:52:11 +0200 Subject: [PATCH] Refactor [gegl_]path_calc_values * moded gegl/property-types/gegl-path.[c|h] Add pos_min and pos_max parameters to get sample points on an arbitrary portion of the path This reduces code and should be very useful to extract gegl_path_stroke in a proper operation. --- gegl/property-types/gegl-path.c | 109 ++++++++++++++++++++++++++++++++++----- gegl/property-types/gegl-path.h | 4 ++ 2 files changed, 100 insertions(+), 13 deletions(-) diff --git a/gegl/property-types/gegl-path.c b/gegl/property-types/gegl-path.c index bf514ca..9b20e53 100644 --- a/gegl/property-types/gegl-path.c +++ b/gegl/property-types/gegl-path.c @@ -383,6 +383,7 @@ GeglPathList * gegl_path_list_append (GeglPathList *head, return head; } +#if 0 static void path_calc (GeglPathList *path, gdouble pos, @@ -467,7 +468,6 @@ path_calc (GeglPathList *path, iter=iter->next; } } - static void path_calc_values (GeglPathList *path, guint num_samples, gdouble *xs, @@ -559,7 +559,96 @@ static void path_calc_values (GeglPathList *path, iter=iter->next; } } +#endif +static void path_calc_values (GeglPathList *path, + gdouble pos_min, + gdouble pos_max, + guint num_samples, + gdouble *xs, + gdouble *ys) +{ + gdouble length = path_get_length (path); + GeglPathList *iter = path; + + gint count_samples=0; + + gfloat x = 0, y = 0; + gfloat spacing = 0; + gfloat pos = 0, next_pos = 0, next_sample = 0, start = pos_min, stop = pos_max; + gboolean to_end = FALSE; + + if ((pos_max > length) || (pos_max < pos_min)) + /* Use the last point of the path as end */ + { + stop = length; + count_samples++; + to_end = TRUE; + } + spacing = (start - stop) / num_samples; + next_sample = start; + + while (iter) + { + switch (iter->d.type) + { + case 'M': + x = iter->d.point[0].x; + y = iter->d.point[0].y; + break; + case 'L': + { + Point a,b; + gfloat distance; + + a.x = x; + a.y = y; + b.x = iter->d.point[0].x; + b.y = iter->d.point[0].y; + + distance = point_dist (&a, &b); + next_pos += distance; + + while (next_pos > next_sample) + { + Point spot; + gfloat ratio = (next_sample - pos) / (next_pos - pos); + + lerp (&spot, &a, &b, ratio); + + xs[count_samples]=spot.x; + ys[count_samples]=spot.y; + + count_samples++; + if (count_samples < num_samples) + next_sample += spacing; + else + { + if (to_end) + { + while (iter->next); + xs[num_samples-1]=b.x; + ys[num_samples-1]=b.y; + } + return; + } + } + x = b.x; + y = b.y; + } + break; + case 'u': + g_error ("can't compute length for uninitialized path\n"); + break; + case 's': + break; + default: + g_error ("can't compute length for instruction: %i\n", iter->d.type); + break; + } + iter=iter->next; + } +} #if 0 /* FIXME: this is terribly inefficient */ static void @@ -796,12 +885,6 @@ static void ensure_flattened (GeglPath *vector) } static void -path_calc_values (GeglPathList *path, - guint num_samples, - gdouble *xs, - gdouble *ys); - -static void gegl_path_init (GeglPath *self) { GeglPathPrivate *priv; @@ -1002,7 +1085,6 @@ void gegl_path_get_bounds (GeglPath *self, } - void gegl_path_calc (GeglPath *self, gdouble pos, @@ -1013,12 +1095,14 @@ gegl_path_calc (GeglPath *self, if (!self) return; ensure_flattened (self); - path_calc (priv->flat_path, pos, xd, yd); + path_calc_values (priv->flat_path, pos, pos, 1, xd, yd); } void gegl_path_calc_values (GeglPath *self, + gdouble pos_min, + gdouble pos_max, guint num_samples, gdouble *xs, gdouble *ys) @@ -1027,10 +1111,9 @@ gegl_path_calc_values (GeglPath *self, if (!self) return; ensure_flattened (self); - path_calc_values (priv->flat_path, num_samples, xs, ys); + path_calc_values (priv->flat_path, 0, -1, num_samples, xs, ys); } - /* -------------------------------------------------------------------------- * A GParamSpec class to describe behavior of GeglPath as an object property * follows. @@ -1621,7 +1704,7 @@ gegl_path_closest_point (GeglPath *path, return 0.0; } - gegl_path_calc_values (path, n, samples_x, samples_y); + gegl_path_calc_values (path, 0, -1, n, samples_x, samples_y); for (i=0;i<n;i++) { @@ -1800,7 +1883,7 @@ void gegl_path_fill (GeglBuffer *buffer, xs = g_newa (gdouble, samples); ys = g_newa (gdouble, samples); - path_calc_values (priv->flat_path, samples, xs, ys); + path_calc_values (priv->flat_path, 0, -1, samples, xs, ys); /* clear scanline intersection lists */ scanlines = g_newa (GSList*, extent.height * versubi); diff --git a/gegl/property-types/gegl-path.h b/gegl/property-types/gegl-path.h index e872e8a..5a1f7eb 100644 --- a/gegl/property-types/gegl-path.h +++ b/gegl/property-types/gegl-path.h @@ -239,6 +239,8 @@ void gegl_path_calc (GeglPath *path, /** * gegl_path_calc_values: * @path: a #GeglPath + * @pos_min: start sampling position + * @pos_max: stop sampling position, -1 for the end of the path * @num_samples: number of samples to compute * @xs: return location for x coordinates * @ys: return location for y coordinates @@ -247,6 +249,8 @@ void gegl_path_calc (GeglPath *path, * the returned values include the start and end positions of the path. */ void gegl_path_calc_values (GeglPath *path, + gdouble pos_min, + gdouble pos_max, guint num_samples, gdouble *xs, gdouble *ys); -- 1.6.3.3
_______________________________________________ Gegl-developer mailing list Gegl-developer@xxxxxxxxxxxxxxxxxxxxxx https://lists.XCF.Berkeley.EDU/mailman/listinfo/gegl-developer