diff --git a/app/gegl/gimpcageconfig.c b/app/gegl/gimpcageconfig.c index ce91c766c6..b0816b8596 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); } @@ -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; +} diff --git a/app/gegl/gimpcageconfig.h b/app/gegl/gimpcageconfig.h index c5535227a6..6d8c54405c 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 54555778d2..e35506829a 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 64f613cbba..4affa9a409 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,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; } diff --git a/app/tools/gimpcagetool.c b/app/tools/gimpcagetool.c index d8d8201119..ee3b8828a1 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 ();