Hi dear gegl developers :),
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 <[email protected]>
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
[email protected]
https://lists.XCF.Berkeley.EDU/mailman/listinfo/gegl-developer