[gimp/soc-2010-cage-2] precompute edge normal
- From: Michael Muré <mmure src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp/soc-2010-cage-2] precompute edge normal
- Date: Sat, 14 Aug 2010 23:08:13 +0000 (UTC)
commit b7c2b26defcefd566a27595eec468a9dfa0de860
Author: Michael Muré <batolettre gmail com>
Date: Sat Aug 14 23:52:41 2010 +0200
precompute edge normal
app/gegl/gimpcageconfig.c | 148 +++++++++++++++++---------------
app/gegl/gimpcageconfig.h | 13 +---
app/gegl/gimpoperationcagepreview.c | 9 +-
app/gegl/gimpoperationcagetransform.c | 4 +-
4 files changed, 87 insertions(+), 87 deletions(-)
---
diff --git a/app/gegl/gimpcageconfig.c b/app/gegl/gimpcageconfig.c
index 354f1f0..1002178 100644
--- a/app/gegl/gimpcageconfig.c
+++ b/app/gegl/gimpcageconfig.c
@@ -58,6 +58,7 @@ static void gimp_cage_config_set_property (GObject *obj
const GValue *value,
GParamSpec *pspec);
static void gimp_cage_config_compute_scaling_factor (GimpCageConfig *gcc);
+static void gimp_cage_config_compute_edge_normal (GimpCageConfig *gcc);
/* FIXME: to debug only */
static void
@@ -66,12 +67,12 @@ print_cage (GimpCageConfig *gcc)
gint i;
GeglRectangle bounding_box;
g_return_if_fail (GIMP_IS_CAGE_CONFIG (gcc));
-
+
bounding_box = gimp_cage_config_get_bounding_box (gcc);
-
+
for (i = 0; i < gcc->cage_vertice_number; i++)
{
- printf("cgx: %.0f cgy: %.0f cvdx: %.0f cvdy: %.0f sf: %.2f\n", gcc->cage_vertices[i].x, gcc->cage_vertices[i].y, gcc->cage_vertices_d[i].x, gcc->cage_vertices_d[i].y, gcc->scaling_factor[i]);
+ printf("cgx: %.0f cgy: %.0f cvdx: %.0f cvdy: %.0f sf: %.2f normx: %.2f normy: %.2f\n", gcc->cage_vertices[i].x, gcc->cage_vertices[i].y, gcc->cage_vertices_d[i].x, gcc->cage_vertices_d[i].y, gcc->scaling_factor[i], gcc->normal_d[i].x, gcc->normal_d[i].y);
}
printf("bounding box: x: %d y: %d width: %d height: %d\n", bounding_box.x, bounding_box.y, bounding_box.width, bounding_box.height);
printf("done\n");
@@ -85,7 +86,7 @@ gimp_cage_config_class_init (GimpCageConfigClass *klass)
object_class->set_property = gimp_cage_config_set_property;
object_class->get_property = gimp_cage_config_get_property;
-
+
object_class->finalize = gimp_cage_config_finalize;
}
@@ -94,20 +95,22 @@ gimp_cage_config_init (GimpCageConfig *self)
{
self->cage_vertice_number = 0;
self->cage_vertices_max = 50; //pre-allocation for 50 vertices for the cage.
-
+
self->cage_vertices = g_new(GimpVector2, self->cage_vertices_max);
self->cage_vertices_d = g_new(GimpVector2, self->cage_vertices_max);
self->scaling_factor = g_malloc (self->cage_vertices_max * sizeof(gfloat));
+ self->normal_d = g_new(GimpVector2, self->cage_vertices_max);
}
static void
gimp_cage_config_finalize (GObject *object)
{
GimpCageConfig *gcc = GIMP_CAGE_CONFIG (object);
-
+
g_free(gcc->cage_vertices);
g_free(gcc->cage_vertices_d);
g_free(gcc->scaling_factor);
+ g_free(gcc->normal_d);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@@ -152,22 +155,26 @@ gimp_cage_config_add_cage_point (GimpCageConfig *gcc,
gdouble y)
{
g_return_if_fail (GIMP_IS_CAGE_CONFIG (gcc));
-
+
/* reallocate memory if needed */
if (gcc->cage_vertice_number >= gcc->cage_vertices_max)
{
gcc->cage_vertices_max += N_ITEMS_PER_ALLOC;
gcc->cage_vertices = g_renew(GimpVector2,
- gcc->cage_vertices,
- gcc->cage_vertices_max);
-
+ gcc->cage_vertices,
+ gcc->cage_vertices_max);
+
gcc->cage_vertices_d = g_renew(GimpVector2,
- gcc->cage_vertices_d,
- gcc->cage_vertices_max);
+ gcc->cage_vertices_d,
+ gcc->cage_vertices_max);
gcc->scaling_factor = g_realloc (gcc->scaling_factor,
- gcc->cage_vertices_max * sizeof(gfloat));
+ gcc->cage_vertices_max * sizeof(gfloat));
+
+ gcc->normal_d = g_renew(GimpVector2,
+ gcc->normal_d,
+ gcc->cage_vertices_max);
}
gcc->cage_vertices[gcc->cage_vertice_number].x = x;
@@ -175,20 +182,21 @@ gimp_cage_config_add_cage_point (GimpCageConfig *gcc,
gcc->cage_vertices_d[gcc->cage_vertice_number].x = x;
gcc->cage_vertices_d[gcc->cage_vertice_number].y = y;
-
+
gcc->cage_vertice_number++;
-
+
gimp_cage_config_compute_scaling_factor (gcc);
+ gimp_cage_config_compute_edge_normal (gcc);
}
void
gimp_cage_config_remove_last_cage_point (GimpCageConfig *gcc)
{
g_return_if_fail (GIMP_IS_CAGE_CONFIG (gcc));
-
+
if (gcc->cage_vertice_number >= 1)
gcc->cage_vertice_number--;
-
+
gimp_cage_config_compute_scaling_factor (gcc);
}
@@ -201,12 +209,12 @@ gimp_cage_config_is_on_handle (GimpCageConfig *gcc,
{
gint i;
gdouble vert_x, vert_y;
-
+
g_return_val_if_fail (GIMP_IS_CAGE_CONFIG (gcc), -1);
-
+
if (gcc->cage_vertice_number == 0)
return -1;
-
+
for (i = 0; i < gcc->cage_vertice_number; i++)
{
if (mode == GIMP_CAGE_MODE_CAGE_CHANGE)
@@ -219,14 +227,14 @@ gimp_cage_config_is_on_handle (GimpCageConfig *gcc,
vert_x = gcc->cage_vertices_d[i].x;
vert_y = gcc->cage_vertices_d[i].y;
}
-
+
if (x < vert_x + handle_size / 2 && x > vert_x -handle_size / 2 &&
y < vert_y + handle_size / 2 && y > vert_y -handle_size / 2)
{
return i;
}
}
-
+
return -1;
}
@@ -240,7 +248,7 @@ gimp_cage_config_move_cage_point (GimpCageConfig *gcc,
g_return_if_fail (GIMP_IS_CAGE_CONFIG (gcc));
g_return_if_fail (point_number < gcc->cage_vertice_number);
g_return_if_fail (point_number >= 0);
-
+
if (mode == GIMP_CAGE_MODE_CAGE_CHANGE)
{
gcc->cage_vertices[point_number].x = x;
@@ -251,25 +259,9 @@ gimp_cage_config_move_cage_point (GimpCageConfig *gcc,
gcc->cage_vertices_d[point_number].x = x;
gcc->cage_vertices_d[point_number].y = y;
}
-
+
gimp_cage_config_compute_scaling_factor (gcc);
-}
-
-GimpVector2
-gimp_cage_config_get_edge_normal (GimpCageConfig *gcc,
- gint edge_index)
-{
- GimpVector2 result;
-
- g_return_val_if_fail (GIMP_IS_CAGE_CONFIG (gcc), gimp_vector2_new(1,0));
- g_return_val_if_fail (edge_index >= 0, gimp_vector2_new(1,0));
- g_return_val_if_fail (edge_index < gcc->cage_vertice_number, gimp_vector2_new(1,0));
-
- gimp_vector2_sub (&result,
- &gcc->cage_vertices_d[(edge_index+1) % gcc->cage_vertice_number],
- &gcc->cage_vertices_d[edge_index]);
-
- return gimp_vector2_normal (&result);
+ gimp_cage_config_compute_edge_normal (gcc);
}
GeglRectangle
@@ -277,45 +269,45 @@ gimp_cage_config_get_bounding_box (GimpCageConfig *gcc)
{
gint i;
GeglRectangle bounding_box = {0, };
-
+
g_return_val_if_fail (GIMP_IS_CAGE_CONFIG (gcc), bounding_box);
g_return_val_if_fail (gcc->cage_vertice_number >= 0, bounding_box);
-
+
bounding_box.x = gcc->cage_vertices[0].x;
bounding_box.y = gcc->cage_vertices[0].y;
bounding_box.height = 0;
bounding_box.width = 0;
-
+
for (i = 1; i < gcc->cage_vertice_number; i++)
{
gdouble x,y;
-
+
x = gcc->cage_vertices[i].x;
y = gcc->cage_vertices[i].y;
-
+
if (x < bounding_box.x)
{
bounding_box.width += bounding_box.x - x;
bounding_box.x = x;
}
-
+
if (y < bounding_box.y)
{
bounding_box.height += bounding_box.y - y;
bounding_box.y = y;
}
-
+
if (x > bounding_box.x + bounding_box.width)
{
bounding_box.width = x - bounding_box.x;
}
-
+
if (y > bounding_box.y + bounding_box.height)
{
bounding_box.height = y - bounding_box.y;
}
}
-
+
return bounding_box;
}
@@ -324,20 +316,20 @@ gimp_cage_config_reverse_cage (GimpCageConfig *gcc)
{
gint i;
GimpVector2 temp;
-
+
g_return_if_fail (GIMP_IS_CAGE_CONFIG (gcc));
-
+
for (i = 0; i < gcc->cage_vertice_number / 2; i++)
{
temp = gcc->cage_vertices[i];
gcc->cage_vertices[i] = gcc->cage_vertices[gcc->cage_vertice_number - i -1];
gcc->cage_vertices[gcc->cage_vertice_number - i -1] = temp;
-
+
temp = gcc->cage_vertices_d[i];
gcc->cage_vertices_d[i] = gcc->cage_vertices_d[gcc->cage_vertice_number - i -1];
gcc->cage_vertices_d[gcc->cage_vertice_number - i -1] = temp;
}
-
+
gimp_cage_config_compute_scaling_factor (gcc);
}
@@ -346,27 +338,27 @@ gimp_cage_config_reverse_cage_if_needed (GimpCageConfig *gcc)
{
gint i;
gdouble sum;
-
+
g_return_if_fail (GIMP_IS_CAGE_CONFIG (gcc));
-
+
sum = 0.0;
-
+
/* 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->cage_vertice_number ; i++)
{
GimpVector2 P1, P2, P3;
gdouble z;
-
+
P1 = gcc->cage_vertices[i];
P2 = gcc->cage_vertices[(i+1) % gcc->cage_vertice_number];
P3 = gcc->cage_vertices[(i+2) % gcc->cage_vertice_number];
-
+
z = P1.x * (P2.y - P3.y) + P2.x * (P3.y - P1.y) + P3.x * (P1.y - P2.y);
-
+
sum += z;
}
-
+
/* sum > 0 mean a cage defined counter-clockwise, so we reverse it */
if (sum > 0)
{
@@ -383,25 +375,43 @@ static void
gimp_cage_config_compute_scaling_factor (GimpCageConfig *gcc)
{
gint i;
- gdouble length, length_d;
GimpVector2 edge;
-
+ gdouble length, length_d;
+
g_return_if_fail (GIMP_IS_CAGE_CONFIG (gcc));
-
+
for (i = 0; i < gcc->cage_vertice_number; i++)
{
gimp_vector2_sub ( &edge, &gcc->cage_vertices[i], &gcc->cage_vertices[(i+1) % gcc->cage_vertice_number]);
length = gimp_vector2_length (&edge);
-
+
gimp_vector2_sub ( &edge, &gcc->cage_vertices_d[i], &gcc->cage_vertices_d[(i+1) % gcc->cage_vertice_number]);
length_d = gimp_vector2_length (&edge);
-
+
gcc->scaling_factor[i] = length_d / length;
}
print_cage (gcc);
}
+static void
+gimp_cage_config_compute_edge_normal (GimpCageConfig *gcc)
+{
+ gint i;
+ GimpVector2 normal;
+
+ g_return_if_fail (GIMP_IS_CAGE_CONFIG (gcc));
+
+ for (i = 0; i < gcc->cage_vertice_number; i++)
+ {
+ gimp_vector2_sub (&normal,
+ &gcc->cage_vertices_d[(i+1) % gcc->cage_vertice_number],
+ &gcc->cage_vertices_d[i]);
+
+ gcc->normal_d[i] = gimp_vector2_normal (&normal);
+ }
+}
+
gboolean
gimp_cage_config_point_inside (GimpCageConfig *gcc,
gfloat x,
@@ -410,9 +420,9 @@ gimp_cage_config_point_inside (GimpCageConfig *gcc,
gint i, j;
gboolean inside = FALSE;
GimpVector2 *cv = gcc->cage_vertices;
-
+
g_return_val_if_fail (GIMP_IS_CAGE_CONFIG (gcc), FALSE);
-
+
for (i = 0, j = gcc->cage_vertice_number - 1; i < gcc->cage_vertice_number; j = i++)
{
if ((((cv[i].y <= y) && (y < cv[j].y))
@@ -422,6 +432,6 @@ gimp_cage_config_point_inside (GimpCageConfig *gcc,
inside = !inside;
}
}
-
+
return inside;
}
diff --git a/app/gegl/gimpcageconfig.h b/app/gegl/gimpcageconfig.h
index 6d85d3c..1e21778 100644
--- a/app/gegl/gimpcageconfig.h
+++ b/app/gegl/gimpcageconfig.h
@@ -44,6 +44,7 @@ struct _GimpCageConfig
GimpVector2 *cage_vertices; /* cage before deformation */
GimpVector2 *cage_vertices_d; /* cage after deformation */
gdouble *scaling_factor;
+ GimpVector2 *normal_d;
};
@@ -110,18 +111,6 @@ void gimp_cage_config_move_cage_point (GimpCageConfig *gcc,
gdouble y);
/**
- * gimp_cage_config_get_edge_normal:
- * @gcc: the cage config
- * @edge_index: the index of the edge considered
- *
- * Compute the normal vector to an edge of the cage
- *
- * Returns: The normal vector to the specified edge of the cage. This vector is normalized (length = 1.0)
- */
-GimpVector2 gimp_cage_config_get_edge_normal (GimpCageConfig *gcc,
- gint edge_index);
-
-/**
* gimp_cage_config_get_bounding_box:
* @gcc: the cage config
*
diff --git a/app/gegl/gimpoperationcagepreview.c b/app/gegl/gimpoperationcagepreview.c
index 54a041b..5aa4c31 100644
--- a/app/gegl/gimpoperationcagepreview.c
+++ b/app/gegl/gimpoperationcagepreview.c
@@ -213,6 +213,7 @@ gimp_operation_cage_preview_process (GeglOperation *operation,
pos_x = 0;
pos_y = 0;
+
for(i = 0; i < cvn; i++)
{
pos_x += coef[i] * config->cage_vertices_d[i].x;
@@ -221,12 +222,12 @@ gimp_operation_cage_preview_process (GeglOperation *operation,
for(i = 0; i < cvn; i++)
{
- pos_x += coef[i + cvn] * config->scaling_factor[i] * gimp_cage_config_get_edge_normal (config, i).x;
- pos_y += coef[i + cvn] * config->scaling_factor[i] * gimp_cage_config_get_edge_normal (config, i).y;
+ pos_x += coef[i + cvn] * config->scaling_factor[i] * config->normal_d[i].x;
+ pos_y += coef[i + cvn] * config->scaling_factor[i] * config->normal_d[i].y;
}
- rect.x = (gint) rint(pos_x);
- rect.y = (gint) rint(pos_y);
+ rect.x = (gint) rint(pos_x) - 1;
+ rect.y = (gint) rint(pos_y) - 1;
/* copy the source pixel in the out buffer */
gegl_buffer_set(out_buf,
diff --git a/app/gegl/gimpoperationcagetransform.c b/app/gegl/gimpoperationcagetransform.c
index 69b8267..52e90b8 100644
--- a/app/gegl/gimpoperationcagetransform.c
+++ b/app/gegl/gimpoperationcagetransform.c
@@ -462,8 +462,8 @@ gimp_cage_transform_compute_destination (GimpCageConfig *config,
for(i = 0; i < cvn; i++)
{
- pos_x += coef[i + cvn] * config->scaling_factor[i] * gimp_cage_config_get_edge_normal (config, i).x;
- pos_y += coef[i + cvn] * config->scaling_factor[i] * gimp_cage_config_get_edge_normal (config, i).y;
+ pos_x += coef[i + cvn] * config->scaling_factor[i] * config->normal_d[i].x;
+ pos_y += coef[i + cvn] * config->scaling_factor[i] * config->normal_d[i].y;
}
result.x = pos_x;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]