mirror of https://github.com/GNOME/gimp.git
GimpCageConfig: use a GArray to store cage's point, to make easier
further improvement
This commit is contained in:
parent
9b3e1c91fd
commit
5d771014d4
|
@ -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);
|
||||
}
|
||||
|
@ -149,6 +148,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
|
||||
|
@ -163,25 +174,17 @@ gimp_cage_config_add_cage_point (GimpCageConfig *gcc,
|
|||
gdouble x,
|
||||
gdouble y)
|
||||
{
|
||||
GimpCagePoint point;
|
||||
|
||||
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;
|
||||
point.src_point.x = x + DELTA;
|
||||
point.src_point.y = y + DELTA;
|
||||
|
||||
gcc->cage_points = g_renew (GimpCagePoint,
|
||||
gcc->cage_points,
|
||||
gcc->max_cage_vertices);
|
||||
}
|
||||
point.dest_point.x = x + DELTA;
|
||||
point.dest_point.y = y + DELTA;
|
||||
|
||||
gcc->cage_points[gcc->n_cage_vertices].src_point.x = x + DELTA;
|
||||
gcc->cage_points[gcc->n_cage_vertices].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;
|
||||
|
||||
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), point);
|
||||
g_return_val_if_fail (point_number < gcc->n_cage_vertices, point);
|
||||
g_return_val_if_fail (point_number >= 0, 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);
|
||||
|
||||
if (gcc->cage_points[point_number].selected)
|
||||
point = &g_array_index (gcc->cage_points, GimpCagePoint, point_number);
|
||||
|
||||
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[0].selected)
|
||||
if (gcc->cage_points->len == 0)
|
||||
return bounding_box;
|
||||
|
||||
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;
|
||||
|
||||
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 (&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++)
|
||||
{
|
||||
gimp_vector2_sub (&normal,
|
||||
&gcc->cage_points[(i + 1) % gcc->n_cage_vertices].dest_point,
|
||||
&gcc->cage_points[i].dest_point);
|
||||
last = &g_array_index (gcc->cage_points, GimpCagePoint, 0);
|
||||
|
||||
gcc->cage_points[i].edge_normal = gimp_vector2_normal (&normal);
|
||||
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,
|
||||
&(current->dest_point),
|
||||
&(last->dest_point));
|
||||
|
||||
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++)
|
||||
{
|
||||
cpi = &(gcc->cage_points[i].src_point);
|
||||
cpj = &(gcc->cage_points[j].src_point);
|
||||
last = &((g_array_index (gcc->cage_points, GimpCagePoint, gcc->cage_points->len - 1)).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))
|
||||
for (i = 0; i < gcc->cage_points->len; i++)
|
||||
{
|
||||
current = &((g_array_index (gcc->cage_points, GimpCagePoint, i)).src_point);
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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__ */
|
||||
|
|
|
@ -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++;
|
||||
|
|
|
@ -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,21 +560,17 @@ 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 += 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;
|
||||
}
|
||||
|
||||
result.x = pos_x;
|
||||
result.y = pos_y;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 ();
|
||||
|
|
Loading…
Reference in New Issue