[gimp] GimpCageConfig: use a GArray to store cage's point, to make easier further improvement
- From: Michael Muré <mmure src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] GimpCageConfig: use a GArray to store cage's point, to make easier further improvement
- Date: Wed, 20 Apr 2011 16:52:06 +0000 (UTC)
commit 5d771014d40d4c5bff8813aea004235931f5d759
Author: Michael Muré <batolettre gmail com>
Date: Wed Apr 20 18:40:13 2011 +0200
GimpCageConfig: use a GArray to store cage's point, to make easier
further improvement
app/gegl/gimpcageconfig.c | 314 ++++++++++++++++++++-------------
app/gegl/gimpcageconfig.h | 8 +-
app/gegl/gimpoperationcagecoefcalc.c | 29 ++-
app/gegl/gimpoperationcagetransform.c | 41 +++--
app/tools/gimpcagetool.c | 26 ++-
5 files changed, 248 insertions(+), 170 deletions(-)
---
diff --git a/app/gegl/gimpcageconfig.c b/app/gegl/gimpcageconfig.c
index ce91c76..b0816b8 100644
--- a/app/gegl/gimpcageconfig.c
+++ b/app/gegl/gimpcageconfig.c
@@ -60,29 +60,30 @@ G_DEFINE_TYPE_WITH_CODE (GimpCageConfig, gimp_cage_config,
#define parent_class gimp_cage_config_parent_class
-
#ifdef DEBUG_CAGE
static void
print_cage (GimpCageConfig *gcc)
{
gint i;
GeglRectangle bounding_box;
+ GimpCagePoint *point;
g_return_if_fail (GIMP_IS_CAGE_CONFIG (gcc));
bounding_box = gimp_cage_config_get_bounding_box (gcc);
- for (i = 0; i < gcc->n_cage_vertices; i++)
+ for (i = 0; i < gcc->cage_points->len; i++)
{
+ point = &g_array_index (gcc->cage_points, GimpCagePoint, i);
g_printerr ("cgx: %.0f cgy: %.0f cvdx: %.0f cvdy: %.0f sf: %.2f normx: %.2f normy: %.2f %s\n",
- gcc->cage_points[i].src_point.x + ((gcc->cage_mode==GIMP_CAGE_MODE_CAGE_CHANGE)?gcc->displacement_x:0),
- gcc->cage_points[i].src_point.y + ((gcc->cage_mode==GIMP_CAGE_MODE_CAGE_CHANGE)?gcc->displacement_y:0),
- gcc->cage_points[i].dest_point.x + ((gcc->cage_mode==GIMP_CAGE_MODE_DEFORM)?gcc->displacement_x:0),
- gcc->cage_points[i].dest_point.y + ((gcc->cage_mode==GIMP_CAGE_MODE_DEFORM)?gcc->displacement_y:0),
- gcc->cage_points[i].edge_scaling_factor,
- gcc->cage_points[i].edge_normal.x,
- gcc->cage_points[i].edge_normal.y,
- ((gcc->cage_points[i].selected) ? "S" : "NS"));
+ point->src_point.x + ((gcc->cage_mode==GIMP_CAGE_MODE_CAGE_CHANGE)?gcc->displacement_x:0),
+ point->src_point.y + ((gcc->cage_mode==GIMP_CAGE_MODE_CAGE_CHANGE)?gcc->displacement_y:0),
+ point->dest_point.x + ((gcc->cage_mode==GIMP_CAGE_MODE_DEFORM)?gcc->displacement_x:0),
+ point->dest_point.y + ((gcc->cage_mode==GIMP_CAGE_MODE_DEFORM)?gcc->displacement_y:0),
+ point->edge_scaling_factor,
+ point->edge_normal.x,
+ point->edge_normal.y,
+ ((point->selected) ? "S" : "NS"));
}
g_printerr ("bounding box: x: %d y: %d width: %d height: %d\n", bounding_box.x, bounding_box.y, bounding_box.width, bounding_box.height);
@@ -105,10 +106,8 @@ gimp_cage_config_class_init (GimpCageConfigClass *klass)
static void
gimp_cage_config_init (GimpCageConfig *self)
{
- self->n_cage_vertices = 0;
- self->max_cage_vertices = 50; /*pre-allocation for 50 vertices for the cage.*/
-
- self->cage_points = g_new0 (GimpCagePoint, self->max_cage_vertices);
+ /*pre-allocation for 50 vertices for the cage.*/
+ self->cage_points = g_array_sized_new (FALSE, FALSE, sizeof(GimpCagePoint), 50);
}
static void
@@ -116,7 +115,7 @@ gimp_cage_config_finalize (GObject *object)
{
GimpCageConfig *gcc = GIMP_CAGE_CONFIG (object);
- g_free (gcc->cage_points);
+ g_array_free (gcc->cage_points, TRUE);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@@ -150,6 +149,18 @@ gimp_cage_config_set_property (GObject *object,
}
/**
+ * gimp_cage_config_get_n_points:
+ * @gcc: the cage config
+ *
+ * Returns: the number of points of the cage
+ */
+guint
+gimp_cage_config_get_n_points (GimpCageConfig *gcc)
+{
+ return gcc->cage_points->len;
+}
+
+/**
* gimp_cage_config_add_cage_point:
* @gcc: the cage config
* @x: x value of the new point
@@ -163,25 +174,17 @@ gimp_cage_config_add_cage_point (GimpCageConfig *gcc,
gdouble x,
gdouble y)
{
- g_return_if_fail (GIMP_IS_CAGE_CONFIG (gcc));
-
- /* reallocate memory if needed */
- if (gcc->n_cage_vertices >= gcc->max_cage_vertices)
- {
- gcc->max_cage_vertices += N_ITEMS_PER_ALLOC;
+ GimpCagePoint point;
- gcc->cage_points = g_renew (GimpCagePoint,
- gcc->cage_points,
- gcc->max_cage_vertices);
- }
+ g_return_if_fail (GIMP_IS_CAGE_CONFIG (gcc));
- gcc->cage_points[gcc->n_cage_vertices].src_point.x = x + DELTA;
- gcc->cage_points[gcc->n_cage_vertices].src_point.y = y + DELTA;
+ point.src_point.x = x + DELTA;
+ point.src_point.y = y + DELTA;
- gcc->cage_points[gcc->n_cage_vertices].dest_point.x = x + DELTA;
- gcc->cage_points[gcc->n_cage_vertices].dest_point.y = y + DELTA;
+ point.dest_point.x = x + DELTA;
+ point.dest_point.y = y + DELTA;
- gcc->n_cage_vertices++;
+ g_array_append_val (gcc->cage_points, point);
gimp_cage_config_compute_scaling_factor (gcc);
gimp_cage_config_compute_edges_normal (gcc);
@@ -198,8 +201,8 @@ gimp_cage_config_remove_last_cage_point (GimpCageConfig *gcc)
{
g_return_if_fail (GIMP_IS_CAGE_CONFIG (gcc));
- if (gcc->n_cage_vertices >= 1)
- gcc->n_cage_vertices--;
+ if (gcc->cage_points->len > 0)
+ g_array_remove_index (gcc->cage_points, gcc->cage_points->len - 1);
gimp_cage_config_compute_scaling_factor (gcc);
gimp_cage_config_compute_edges_normal (gcc);
@@ -218,40 +221,43 @@ gimp_cage_config_get_point_coordinate (GimpCageConfig *gcc,
GimpCageMode mode,
gint point_number)
{
- GimpVector2 point = { 0.0, 0.0 };
+ GimpVector2 result = { 0.0, 0.0 };
+ GimpCagePoint *point;
+
+ g_return_val_if_fail (GIMP_IS_CAGE_CONFIG (gcc), result);
+ g_return_val_if_fail (point_number < gcc->cage_points->len, result);
+ g_return_val_if_fail (point_number >= 0, result);
- g_return_val_if_fail (GIMP_IS_CAGE_CONFIG (gcc), point);
- g_return_val_if_fail (point_number < gcc->n_cage_vertices, point);
- g_return_val_if_fail (point_number >= 0, point);
+ point = &g_array_index (gcc->cage_points, GimpCagePoint, point_number);
- if (gcc->cage_points[point_number].selected)
+ if (point->selected)
{
if (mode == GIMP_CAGE_MODE_CAGE_CHANGE)
{
- point.x = gcc->cage_points[point_number].src_point.x + gcc->displacement_x;
- point.y = gcc->cage_points[point_number].src_point.y + gcc->displacement_y;
+ result.x = point->src_point.x + gcc->displacement_x;
+ result.y = point->src_point.y + gcc->displacement_y;
}
else
{
- point.x = gcc->cage_points[point_number].dest_point.x + gcc->displacement_x;
- point.y = gcc->cage_points[point_number].dest_point.y + gcc->displacement_y;
+ result.x = point->dest_point.x + gcc->displacement_x;
+ result.y = point->dest_point.y + gcc->displacement_y;
}
}
else
{
if (mode == GIMP_CAGE_MODE_CAGE_CHANGE)
{
- point.x = gcc->cage_points[point_number].src_point.x;
- point.y = gcc->cage_points[point_number].src_point.y;
+ result.x = point->src_point.x;
+ result.y = point->src_point.y;
}
else
{
- point.x = gcc->cage_points[point_number].dest_point.x;
- point.y = gcc->cage_points[point_number].dest_point.y;
+ result.x = point->dest_point.x;
+ result.y = point->dest_point.y;
}
}
- return point;
+ return result;
}
/**
@@ -295,21 +301,24 @@ gimp_cage_config_commit_displacement (GimpCageConfig *gcc)
g_return_if_fail (GIMP_IS_CAGE_CONFIG (gcc));
- for (i = 0; i < gcc->n_cage_vertices; i++)
+ for (i = 0; i < gcc->cage_points->len; i++)
{
- if (gcc->cage_points[i].selected)
+ GimpCagePoint *point;
+ point = &g_array_index (gcc->cage_points, GimpCagePoint, i);
+
+ if (point->selected)
{
if (gcc->cage_mode == GIMP_CAGE_MODE_CAGE_CHANGE)
{
- gcc->cage_points[i].src_point.x += gcc->displacement_x;
- gcc->cage_points[i].src_point.y += gcc->displacement_y;
- gcc->cage_points[i].dest_point.x += gcc->displacement_x;
- gcc->cage_points[i].dest_point.y += gcc->displacement_y;
+ point->src_point.x += gcc->displacement_x;
+ point->src_point.y += gcc->displacement_y;
+ point->dest_point.x += gcc->displacement_x;
+ point->dest_point.y += gcc->displacement_y;
}
else
{
- gcc->cage_points[i].dest_point.x += gcc->displacement_x;
- gcc->cage_points[i].dest_point.y += gcc->displacement_y;
+ point->dest_point.x += gcc->displacement_x;
+ point->dest_point.y += gcc->displacement_y;
}
}
}
@@ -345,39 +354,43 @@ gimp_cage_config_reset_displacement (GimpCageConfig *gcc)
GeglRectangle
gimp_cage_config_get_bounding_box (GimpCageConfig *gcc)
{
- GeglRectangle bounding_box = { 0, };
- gint i;
+ GeglRectangle bounding_box = { 0, 0, 0, 0};
+ gint i;
+ GimpCagePoint *point;
g_return_val_if_fail (GIMP_IS_CAGE_CONFIG (gcc), bounding_box);
- g_return_val_if_fail (gcc->n_cage_vertices >= 0, bounding_box);
+ g_return_val_if_fail (gcc->cage_points->len >= 0, bounding_box);
+
+ if (gcc->cage_points->len == 0)
+ return bounding_box;
- if (gcc->cage_points[0].selected)
+ point = &g_array_index (gcc->cage_points, GimpCagePoint, 0);
+
+ if (point->selected)
{
- bounding_box.x = gcc->cage_points[0].src_point.x + gcc->displacement_x;
- bounding_box.y = gcc->cage_points[0].src_point.y + gcc->displacement_y;
+ bounding_box.x = point->src_point.x + gcc->displacement_x;
+ bounding_box.y = point->src_point.y + gcc->displacement_y;
}
else
{
- bounding_box.x = gcc->cage_points[0].src_point.x;
- bounding_box.y = gcc->cage_points[0].src_point.y;
+ bounding_box.x = point->src_point.x;
+ bounding_box.y = point->src_point.y;
}
- bounding_box.height = 0;
- bounding_box.width = 0;
-
- for (i = 1; i < gcc->n_cage_vertices; i++)
+ for (i = 1; i < gcc->cage_points->len; i++)
{
gdouble x,y;
+ point = &g_array_index (gcc->cage_points, GimpCagePoint, i);
- if (gcc->cage_points[i].selected)
+ if (point->selected)
{
- x = gcc->cage_points[i].src_point.x + gcc->displacement_x;
- y = gcc->cage_points[i].src_point.y + gcc->displacement_y;
+ x = point->src_point.x + gcc->displacement_x;
+ y = point->src_point.y + gcc->displacement_y;
}
else
{
- x = gcc->cage_points[i].src_point.x;
- y = gcc->cage_points[i].src_point.y;
+ x = point->src_point.x;
+ y = point->src_point.y;
}
if (x < bounding_box.x)
@@ -422,11 +435,14 @@ gimp_cage_config_reverse_cage (GimpCageConfig *gcc)
g_return_if_fail (GIMP_IS_CAGE_CONFIG (gcc));
- for (i = 0; i < gcc->n_cage_vertices / 2; i++)
+ for (i = 0; i < gcc->cage_points->len / 2; i++)
{
- temp = gcc->cage_points[i];
- gcc->cage_points[i] = gcc->cage_points[gcc->n_cage_vertices - i - 1];
- gcc->cage_points[gcc->n_cage_vertices - i - 1] = temp;
+ temp = g_array_index (gcc->cage_points, GimpCagePoint, i);
+
+ g_array_index (gcc->cage_points, GimpCagePoint, i) =
+ g_array_index (gcc->cage_points, GimpCagePoint, gcc->cage_points->len - i - 1);
+
+ g_array_index (gcc->cage_points, GimpCagePoint, gcc->cage_points->len - i - 1) = temp;
}
gimp_cage_config_compute_scaling_factor (gcc);
@@ -457,14 +473,14 @@ gimp_cage_config_reverse_cage_if_needed (GimpCageConfig *gcc)
/* this is a bit crappy, but should works most of the case */
/* we do the sum of the projection of each point to the previous
segment, and see the final sign */
- for (i = 0; i < gcc->n_cage_vertices ; i++)
+ for (i = 0; i < gcc->cage_points->len ; i++)
{
GimpVector2 P1, P2, P3;
gdouble z;
- P1 = gcc->cage_points[i].src_point;
- P2 = gcc->cage_points[(i+1) % gcc->n_cage_vertices].src_point;
- P3 = gcc->cage_points[(i+2) % gcc->n_cage_vertices].src_point;
+ P1 = (g_array_index (gcc->cage_points, GimpCagePoint, i)).src_point;
+ P2 = (g_array_index (gcc->cage_points, GimpCagePoint, (i+1) % gcc->cage_points->len)).src_point;
+ P3 = (g_array_index (gcc->cage_points, GimpCagePoint, (i+2) % gcc->cage_points->len)).src_point;
z = P1.x * (P2.y - P3.y) + P2.x * (P3.y - P1.y) + P3.x * (P1.y - P2.y);
@@ -488,25 +504,33 @@ gimp_cage_config_reverse_cage_if_needed (GimpCageConfig *gcc)
static void
gimp_cage_config_compute_scaling_factor (GimpCageConfig *gcc)
{
- GimpVector2 edge;
- gdouble length, length_d;
- gint i;
+ GimpVector2 edge;
+ gdouble length, length_d;
+ gint i;
+ GimpCagePoint *current, *last;
g_return_if_fail (GIMP_IS_CAGE_CONFIG (gcc));
+ if (gcc->cage_points->len < 2)
+ return;
+
+ last = &g_array_index (gcc->cage_points, GimpCagePoint, 0);
- for (i = 0; i < gcc->n_cage_vertices; i++)
+ for (i = 1; i <= gcc->cage_points->len; i++)
{
+ current = &g_array_index (gcc->cage_points, GimpCagePoint, i % gcc->cage_points->len);
+
gimp_vector2_sub (&edge,
- &gcc->cage_points[i].src_point,
- &gcc->cage_points[(i + 1) % gcc->n_cage_vertices].src_point);
+ &(last->src_point),
+ &(current->src_point));
length = gimp_vector2_length (&edge);
gimp_vector2_sub (&edge,
- &gcc->cage_points[i].dest_point,
- &gcc->cage_points[(i + 1) % gcc->n_cage_vertices].dest_point);
+ &(last->dest_point),
+ &(current->dest_point));
length_d = gimp_vector2_length (&edge);
- gcc->cage_points[i].edge_scaling_factor = length_d / length;
+ last->edge_scaling_factor = length_d / length;
+ last = current;
}
}
@@ -520,18 +544,24 @@ gimp_cage_config_compute_scaling_factor (GimpCageConfig *gcc)
static void
gimp_cage_config_compute_edges_normal (GimpCageConfig *gcc)
{
- GimpVector2 normal;
- gint i;
+ GimpVector2 normal;
+ gint i;
+ GimpCagePoint *current, *last;
g_return_if_fail (GIMP_IS_CAGE_CONFIG (gcc));
- for (i = 0; i < gcc->n_cage_vertices; i++)
+ last = &g_array_index (gcc->cage_points, GimpCagePoint, 0);
+
+ for (i = 1; i <= gcc->cage_points->len; i++)
{
+ current = &g_array_index (gcc->cage_points, GimpCagePoint, i % gcc->cage_points->len);
+
gimp_vector2_sub (&normal,
- &gcc->cage_points[(i + 1) % gcc->n_cage_vertices].dest_point,
- &gcc->cage_points[i].dest_point);
+ &(current->dest_point),
+ &(last->dest_point));
- gcc->cage_points[i].edge_normal = gimp_vector2_normal (&normal);
+ last->edge_normal = gimp_vector2_normal (&normal);
+ last = current;
}
}
@@ -552,25 +582,26 @@ gimp_cage_config_point_inside (GimpCageConfig *gcc,
gfloat x,
gfloat y)
{
- GimpVector2 *cpi, *cpj;
- gboolean inside = FALSE;
- gint i, j;
+ GimpVector2 *last, *current;
+ gboolean inside = FALSE;
+ gint i;
g_return_val_if_fail (GIMP_IS_CAGE_CONFIG (gcc), FALSE);
- for (i = 0, j = gcc->n_cage_vertices - 1;
- i < gcc->n_cage_vertices;
- j = i++)
+ last = &((g_array_index (gcc->cage_points, GimpCagePoint, gcc->cage_points->len - 1)).src_point);
+
+ for (i = 0; i < gcc->cage_points->len; i++)
{
- cpi = &(gcc->cage_points[i].src_point);
- cpj = &(gcc->cage_points[j].src_point);
+ current = &((g_array_index (gcc->cage_points, GimpCagePoint, i)).src_point);
- if ((((cpi->y <= y) && (y < cpj->y))
- || ((cpj->y <= y) && (y < cpi->y)))
- && (x < (cpj->x - cpi->x) * (y - cpi->y) / (cpj->y - cpi->y) + cpi->x))
+ if ((((current->y <= y) && (y < last->y))
+ || ((last->y <= y) && (y < current->y)))
+ && (x < (last->x - current->x) * (y - current->y) / (last->y - current->y) + current->x))
{
inside = !inside;
}
+
+ last = current;
}
return inside;
@@ -587,21 +618,24 @@ void
gimp_cage_config_select_point (GimpCageConfig *gcc,
gint point_number)
{
- gint i;
+ gint i;
+ GimpCagePoint *point;
g_return_if_fail (GIMP_IS_CAGE_CONFIG (gcc));
- g_return_if_fail (point_number < gcc->n_cage_vertices);
+ g_return_if_fail (point_number < gcc->cage_points->len);
g_return_if_fail (point_number >= 0);
- for (i = 0; i < gcc->n_cage_vertices; i++)
+ for (i = 0; i < gcc->cage_points->len; i++)
{
+ point = &g_array_index (gcc->cage_points, GimpCagePoint, i);
+
if (i == point_number)
{
- gcc->cage_points[i].selected = TRUE;
+ point->selected = TRUE;
}
else
{
- gcc->cage_points[i].selected = FALSE;
+ point->selected = FALSE;
}
}
}
@@ -638,30 +672,33 @@ gimp_cage_config_select_add_area (GimpCageConfig *gcc,
GimpCageMode mode,
GeglRectangle area)
{
- gint i;
+ gint i;
+ GimpCagePoint *point;
g_return_if_fail (GIMP_IS_CAGE_CONFIG (gcc));
- for (i = 0; i < gcc->n_cage_vertices; i++)
+ for (i = 0; i < gcc->cage_points->len; i++)
{
+ point = &g_array_index (gcc->cage_points, GimpCagePoint, i);
+
if (mode == GIMP_CAGE_MODE_CAGE_CHANGE)
{
- if (gcc->cage_points[i].src_point.x >= area.x &&
- gcc->cage_points[i].src_point.x <= area.x + area.width &&
- gcc->cage_points[i].src_point.y >= area.y &&
- gcc->cage_points[i].src_point.y <= area.y + area.height)
+ if (point->src_point.x >= area.x &&
+ point->src_point.x <= area.x + area.width &&
+ point->src_point.y >= area.y &&
+ point->src_point.y <= area.y + area.height)
{
- gcc->cage_points[i].selected = TRUE;
+ point->selected = TRUE;
}
}
else
{
- if (gcc->cage_points[i].dest_point.x >= area.x &&
- gcc->cage_points[i].dest_point.x <= area.x + area.width &&
- gcc->cage_points[i].dest_point.y >= area.y &&
- gcc->cage_points[i].dest_point.y <= area.y + area.height)
+ if (point->dest_point.x >= area.x &&
+ point->dest_point.x <= area.x + area.width &&
+ point->dest_point.y >= area.y &&
+ point->dest_point.y <= area.y + area.height)
{
- gcc->cage_points[i].selected = TRUE;
+ point->selected = TRUE;
}
}
}
@@ -678,11 +715,14 @@ void
gimp_cage_config_toggle_point_selection (GimpCageConfig *gcc,
gint point_number)
{
+ GimpCagePoint *point;
+
g_return_if_fail (GIMP_IS_CAGE_CONFIG (gcc));
- g_return_if_fail (point_number < gcc->n_cage_vertices);
+ g_return_if_fail (point_number < gcc->cage_points->len);
g_return_if_fail (point_number >= 0);
- gcc->cage_points[point_number].selected = ! gcc->cage_points[point_number].selected;
+ point = &g_array_index (gcc->cage_points, GimpCagePoint, point_number);
+ point->selected = ! point->selected;
}
/**
@@ -698,8 +738,30 @@ gimp_cage_config_deselect_points (GimpCageConfig *gcc)
g_return_if_fail (GIMP_IS_CAGE_CONFIG (gcc));
- for (i = 0; i < gcc->n_cage_vertices; i++)
+ for (i = 0; i < gcc->cage_points->len; i++)
{
- gcc->cage_points[i].selected = FALSE;
+ (g_array_index (gcc->cage_points, GimpCagePoint, i)).selected = FALSE;
}
}
+
+/**
+ * gimp_cage_config_point_is_selected:
+ * @gcc: the cage config
+ * @point_number: the index of the point to test
+ *
+ * Returns: TRUE if the point is selected, FALSE otherwise.
+ */
+gboolean
+gimp_cage_config_point_is_selected (GimpCageConfig *gcc,
+ gint point_number)
+{
+ GimpCagePoint *point;
+
+ g_return_val_if_fail (GIMP_IS_CAGE_CONFIG (gcc), FALSE);
+ g_return_val_if_fail (point_number < gcc->cage_points->len, FALSE);
+ g_return_val_if_fail (point_number >= 0, FALSE);
+
+ point = &(g_array_index (gcc->cage_points, GimpCagePoint, point_number));
+
+ return point->selected;
+}
diff --git a/app/gegl/gimpcageconfig.h b/app/gegl/gimpcageconfig.h
index c553522..6d8c544 100644
--- a/app/gegl/gimpcageconfig.h
+++ b/app/gegl/gimpcageconfig.h
@@ -48,14 +48,11 @@ struct _GimpCageConfig
{
GimpImageMapConfig parent_instance;
- gint n_cage_vertices; /* vertices used by the cage */
- gint max_cage_vertices; /* vertices allocated */
+ GArray *cage_points;
gdouble displacement_x;
gdouble displacement_y;
GimpCageMode cage_mode; /* Cage mode, used to commit displacement */
-
- GimpCagePoint *cage_points;
};
struct _GimpCageConfigClass
@@ -66,6 +63,7 @@ struct _GimpCageConfigClass
GType gimp_cage_config_get_type (void) G_GNUC_CONST;
+guint gimp_cage_config_get_n_points (GimpCageConfig *gcc);
void gimp_cage_config_add_cage_point (GimpCageConfig *gcc,
gdouble x,
gdouble y);
@@ -96,6 +94,8 @@ void gimp_cage_config_select_add_area (GimpCageConfig *gcc,
void gimp_cage_config_toggle_point_selection (GimpCageConfig *gcc,
gint point_number);
void gimp_cage_config_deselect_points (GimpCageConfig *gcc);
+gboolean gimp_cage_config_point_is_selected (GimpCageConfig *gcc,
+ gint point_number);
#endif /* __GIMP_CAGE_CONFIG_H__ */
diff --git a/app/gegl/gimpoperationcagecoefcalc.c b/app/gegl/gimpoperationcagecoefcalc.c
index 5455577..e355068 100644
--- a/app/gegl/gimpoperationcagecoefcalc.c
+++ b/app/gegl/gimpoperationcagecoefcalc.c
@@ -96,7 +96,7 @@ gimp_operation_cage_coef_calc_prepare (GeglOperation *operation)
gegl_operation_set_format (operation,
"output",
babl_format_n (babl_type ("float"),
- 2 * config->n_cage_vertices));
+ 2 * gimp_cage_config_get_n_points (config)));
}
static void
@@ -193,13 +193,17 @@ gimp_operation_cage_coef_calc_process (GeglOperation *operation,
GimpOperationCageCoefCalc *occc = GIMP_OPERATION_CAGE_COEF_CALC (operation);
GimpCageConfig *config = GIMP_CAGE_CONFIG (occc->config);
- Babl *format = babl_format_n (babl_type ("float"), 2 * config->n_cage_vertices);
+ Babl *format = babl_format_n (babl_type ("float"), 2 * gimp_cage_config_get_n_points (config));
GeglBufferIterator *it;
+ guint n_cage_vertices;
+ GimpCagePoint *current, *last;
if (! config)
return FALSE;
+ n_cage_vertices = gimp_cage_config_get_n_points (config);
+
it = gegl_buffer_iterator_new (output, roi, format, GEGL_BUFFER_READWRITE);
while (gegl_buffer_iterator_next (it))
@@ -216,13 +220,16 @@ gimp_operation_cage_coef_calc_process (GeglOperation *operation,
{
if (gimp_cage_config_point_inside(config, x, y))
{
- for( j = 0; j < config->n_cage_vertices; j++)
+ last = &(g_array_index (config->cage_points, GimpCagePoint, 0));
+
+ for( j = 0; j < n_cage_vertices; j++)
{
GimpVector2 v1,v2,a,b,p;
gdouble BA,SRT,L0,L1,A0,A1,A10,L10, Q,S,R, absa;
- v1 = config->cage_points[j].src_point;
- v2 = config->cage_points[(j+1)%config->n_cage_vertices].src_point;
+ current = &(g_array_index (config->cage_points, GimpCagePoint, (j+1) % n_cage_vertices));
+ v1 = last->src_point;
+ v2 = current->src_point;
p.x = x;
p.y = y;
a.x = v2.x - v1.x;
@@ -245,23 +252,25 @@ gimp_operation_cage_coef_calc_process (GeglOperation *operation,
L10 = L1 - L0;
/* edge coef */
- coef[j + config->n_cage_vertices] = (-absa / (4.0 * M_PI)) * ((4.0*S-(R*R)/Q) * A10 + (R / (2.0 * Q)) * L10 + L1 - 2.0);
+ coef[j + n_cage_vertices] = (-absa / (4.0 * M_PI)) * ((4.0*S-(R*R)/Q) * A10 + (R / (2.0 * Q)) * L10 + L1 - 2.0);
- if (isnan(coef[j + config->n_cage_vertices]))
+ if (isnan(coef[j + n_cage_vertices]))
{
- coef[j + config->n_cage_vertices] = 0.0;
+ coef[j + n_cage_vertices] = 0.0;
}
/* vertice coef */
if (!gimp_operation_cage_coef_calc_is_on_straight (&v1, &v2, &p))
{
coef[j] += (BA / (2.0 * M_PI)) * (L10 /(2.0*Q) - A10 * (2.0 + R / Q));
- coef[(j+1)%config->n_cage_vertices] -= (BA / (2.0 * M_PI)) * (L10 / (2.0 * Q) - A10 * (R / Q));
+ coef[(j+1)%n_cage_vertices] -= (BA / (2.0 * M_PI)) * (L10 / (2.0 * Q) - A10 * (R / Q));
}
+
+ last = current;
}
}
- coef += 2 * config->n_cage_vertices;
+ coef += 2 * n_cage_vertices;
/* update x and y coordinates */
x++;
diff --git a/app/gegl/gimpoperationcagetransform.c b/app/gegl/gimpoperationcagetransform.c
index 64f613c..4affa9a 100644
--- a/app/gegl/gimpoperationcagetransform.c
+++ b/app/gegl/gimpoperationcagetransform.c
@@ -210,7 +210,7 @@ gimp_operation_cage_transform_prepare (GeglOperation *operation)
gegl_operation_set_format (operation, "input",
babl_format_n (babl_type ("float"),
- 2 * config->n_cage_vertices));
+ 2 * gimp_cage_config_get_n_points (config)));
gegl_operation_set_format (operation, "output",
babl_format_n (babl_type ("float"), 2));
}
@@ -232,13 +232,18 @@ gimp_operation_cage_transform_process (GeglOperation *operation,
GeglBufferIterator *it;
gint x, y;
gboolean output_set;
+ GimpCagePoint *point;
+ guint n_cage_vertices;
/* pre-fill the out buffer with no-displacement coordinate */
it = gegl_buffer_iterator_new (out_buf, roi, NULL, GEGL_BUFFER_WRITE);
cage_bb = gimp_cage_config_get_bounding_box (config);
- plain_color.x = (gint) config->cage_points[0].src_point.x;
- plain_color.y = (gint) config->cage_points[0].src_point.y;
+ point = &(g_array_index (config->cage_points, GimpCagePoint, 0));
+ plain_color.x = (gint) point->src_point.x;
+ plain_color.y = (gint) point->src_point.y;
+
+ n_cage_vertices = gimp_cage_config_get_n_points (config);
while (gegl_buffer_iterator_next (it))
{
@@ -290,8 +295,8 @@ gimp_operation_cage_transform_process (GeglOperation *operation,
/* pre-allocate memory outside of the loop */
coords = g_slice_alloc (2 * sizeof (gfloat));
- coef = g_malloc (config->n_cage_vertices * 2 * sizeof (gfloat));
- format_coef = babl_format_n (babl_type ("float"), 2 * config->n_cage_vertices);
+ coef = g_malloc (n_cage_vertices * 2 * sizeof (gfloat));
+ format_coef = babl_format_n (babl_type ("float"), 2 * n_cage_vertices);
/* compute, reverse and interpolate the transformation */
for (y = cage_bb.y; y < cage_bb.y + cage_bb.height - 1; y++)
@@ -536,14 +541,14 @@ gimp_cage_transform_compute_destination (GimpCageConfig *config,
GeglBuffer *coef_buf,
GimpVector2 coords)
{
- gdouble pos_x, pos_y;
- GimpVector2 result;
- gint cvn = config->n_cage_vertices;
+ GimpVector2 result = {0, 0};
+ gint n_cage_vertices = gimp_cage_config_get_n_points (config);
gint i;
+ GimpCagePoint *point;
/* When Gegl bug #645810 will be solved, this should be a good optimisation */
#ifdef GEGL_BUG_645810_SOLVED
- gegl_buffer_sample (coef_buf, coords.x, coords.y, 1.0, coef, format_coef, GEGL_INTERPOLATION_LANCZOS);
+ gegl_buffer_sample (coef_buf, coords.x, coords.y, 1.0, coef, format_coef, GEGL_INTERPOLATION_NEAREST);
#else
GeglRectangle rect;
@@ -555,20 +560,16 @@ gimp_cage_transform_compute_destination (GimpCageConfig *config,
gegl_buffer_get (coef_buf, 1, &rect, format_coef, coef, GEGL_AUTO_ROWSTRIDE);
#endif
- pos_x = 0;
- pos_y = 0;
-
- for (i = 0; i < cvn; i++)
+ for (i = 0; i < n_cage_vertices; i++)
{
- pos_x += coef[i] * config->cage_points[i].dest_point.x;
- pos_y += coef[i] * config->cage_points[i].dest_point.y;
+ point = &g_array_index (config->cage_points, GimpCagePoint, i);
- pos_x += coef[i + cvn] * config->cage_points[i].edge_scaling_factor * config->cage_points[i].edge_normal.x;
- pos_y += coef[i + cvn] * config->cage_points[i].edge_scaling_factor * config->cage_points[i].edge_normal.y;
- }
+ result.x += coef[i] * point->dest_point.x;
+ result.y += coef[i] * point->dest_point.y;
- result.x = pos_x;
- result.y = pos_y;
+ result.x += coef[i + n_cage_vertices] * point->edge_scaling_factor * point->edge_normal.x;
+ result.y += coef[i + n_cage_vertices] * point->edge_scaling_factor * point->edge_normal.y;
+ }
return result;
}
diff --git a/app/tools/gimpcagetool.c b/app/tools/gimpcagetool.c
index d8d8201..ee3b882 100644
--- a/app/tools/gimpcagetool.c
+++ b/app/tools/gimpcagetool.c
@@ -547,10 +547,10 @@ gimp_cage_tool_button_press (GimpTool *tool,
coords->x - ct->offset_x,
coords->y - ct->offset_y);
gimp_cage_config_select_point (ct->config,
- ct->config->n_cage_vertices - 1);
+ gimp_cage_config_get_n_points (ct->config) - 1);
ct->tool_state = CAGE_STATE_MOVE_HANDLE;
}
- else if (handle == 0 && ct->config->n_cage_vertices > 2)
+ else if (handle == 0 && gimp_cage_config_get_n_points (ct->config) > 2)
{
/* User clicked on the first handle, we wait for
* release for closing the cage and switching to
@@ -573,7 +573,7 @@ gimp_cage_tool_button_press (GimpTool *tool,
{
/* New selection */
- if (! ct->config->cage_points[handle].selected)
+ if (! gimp_cage_config_point_is_selected (ct->config, handle))
{
gimp_cage_config_select_point (ct->config, handle);
}
@@ -610,7 +610,7 @@ gimp_cage_tool_button_press (GimpTool *tool,
{
/* New selection */
- if (! ct->config->cage_points[handle].selected)
+ if (! gimp_cage_config_point_is_selected (ct->config, handle))
{
gimp_cage_config_select_point (ct->config, handle);
}
@@ -646,7 +646,7 @@ gimp_cage_tool_button_press (GimpTool *tool,
{
/* New selection */
- if (! ct->config->cage_points[handle].selected)
+ if (! gimp_cage_config_point_is_selected (ct->config, handle))
{
gimp_cage_config_select_point (ct->config, handle);
}
@@ -819,7 +819,10 @@ gimp_cage_tool_draw (GimpDrawTool *draw_tool)
gint i;
GimpHandleType handle;
- n_vertices = config->n_cage_vertices;
+ n_vertices = gimp_cage_config_get_n_points (config);
+
+ if (n_vertices == 0)
+ return;
if (ct->tool_state == CAGE_STATE_INIT)
return;
@@ -896,7 +899,7 @@ gimp_cage_tool_draw (GimpDrawTool *draw_tool)
GIMP_TOOL_HANDLE_SIZE_CIRCLE,
GIMP_HANDLE_ANCHOR_CENTER);
- if (ct->config->cage_points[i].selected)
+ if (gimp_cage_config_point_is_selected (ct->config, i))
{
gimp_draw_tool_add_handle (draw_tool,
GIMP_HANDLE_SQUARE,
@@ -933,13 +936,16 @@ gimp_cage_tool_is_on_handle (GimpCageTool *ct,
gdouble dist = G_MAXDOUBLE;
gint i;
GimpVector2 cage_point;
+ guint n_cage_vertices;
g_return_val_if_fail (GIMP_IS_CAGE_TOOL (ct), -1);
- if (config->n_cage_vertices == 0)
+ n_cage_vertices = gimp_cage_config_get_n_points (config);
+
+ if (n_cage_vertices == 0)
return -1;
- for (i = 0; i < config->n_cage_vertices; i++)
+ for (i = 0; i < n_cage_vertices; i++)
{
cage_point = gimp_cage_config_get_point_coordinate (config,
options->cage_mode,
@@ -996,7 +1002,7 @@ gimp_cage_tool_compute_coef (GimpCageTool *ct,
}
format = babl_format_n (babl_type ("float"),
- config->n_cage_vertices * 2);
+ gimp_cage_config_get_n_points (config) * 2);
gegl = gegl_node_new ();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]