mirror of https://github.com/GNOME/gimp.git
app: properly (bucket) fill created splines and segments in line art.
For this, I needed distmap of the closed version of the line art (after splines and segments are created). This will result in invisible stroke borders added when flooding in the end. These invisible borders will have a thickness of 0.0, which means that flooding will stop at once after these single pixels are filled, which makes it quick, and is perfect since created splines and segments are 1-pixel thick anyway. Only downside is having to run "gegl:distance-transform" a second time, but this still stays fast.
This commit is contained in:
parent
3467acf096
commit
5a4754f32b
|
@ -105,8 +105,7 @@ static GArray * gimp_lineart_line_segment_until_hit (const GeglBuffer
|
|||
Pixel start,
|
||||
GimpVector2 direction,
|
||||
int size);
|
||||
static gfloat * gimp_lineart_estimate_strokes_radii (GeglBuffer *mask,
|
||||
gfloat **lineart_distmap);
|
||||
static gfloat * gimp_lineart_estimate_strokes_radii (GeglBuffer *mask);
|
||||
|
||||
/* Some callback-type functions. */
|
||||
|
||||
|
@ -188,7 +187,7 @@ static void gimp_edgelset_next8 (const GeglBuffer *buffer,
|
|||
* @segments_max_length: the maximum length for creating segments
|
||||
* between end points. Unlike splines, segments
|
||||
* are straight lines.
|
||||
* @lineart_distmap: a distance map of the line art pixels.
|
||||
* @closed_distmap: a distance map of the closed line art pixels.
|
||||
* @lineart_radii: a map of estimated radii of line art border pixels.
|
||||
*
|
||||
* Creates a binarized version of the strokes of @buffer, detected either
|
||||
|
@ -224,7 +223,7 @@ gimp_lineart_close (GeglBuffer *buffer,
|
|||
gint created_regions_minimum_area,
|
||||
gboolean small_segments_from_spline_sources,
|
||||
gint segments_max_length,
|
||||
gfloat **lineart_distmap,
|
||||
gfloat **closed_distmap,
|
||||
gfloat **lineart_radii)
|
||||
{
|
||||
const Babl *gray_format;
|
||||
|
@ -313,7 +312,7 @@ gimp_lineart_close (GeglBuffer *buffer,
|
|||
smoothed_curvatures,
|
||||
normal_estimate_mask_size);
|
||||
|
||||
radii = gimp_lineart_estimate_strokes_radii (strokes, lineart_distmap);
|
||||
radii = gimp_lineart_estimate_strokes_radii (strokes);
|
||||
threshold = 1.0f - end_point_rate;
|
||||
clamped_threshold = MAX (0.25f, threshold);
|
||||
for (i = 0; i < width; i++)
|
||||
|
@ -457,6 +456,33 @@ gimp_lineart_close (GeglBuffer *buffer,
|
|||
point++;
|
||||
}
|
||||
|
||||
if (closed_distmap)
|
||||
{
|
||||
GeglNode *graph;
|
||||
GeglNode *input;
|
||||
GeglNode *op;
|
||||
|
||||
/* Flooding needs a distance map for closed line art. */
|
||||
*closed_distmap = g_new (gfloat, width * height);
|
||||
|
||||
graph = gegl_node_new ();
|
||||
input = gegl_node_new_child (graph,
|
||||
"operation", "gegl:buffer-source",
|
||||
"buffer", closed,
|
||||
NULL);
|
||||
op = gegl_node_new_child (graph,
|
||||
"operation", "gegl:distance-transform",
|
||||
"metric", GEGL_DISTANCE_METRIC_EUCLIDEAN,
|
||||
"normalize", FALSE,
|
||||
NULL);
|
||||
gegl_node_connect_to (input, "output",
|
||||
op, "input");
|
||||
gegl_node_blit (op, 1.0, gegl_buffer_get_extent (closed),
|
||||
NULL, *closed_distmap,
|
||||
GEGL_AUTO_ROWSTRIDE, GEGL_BLIT_DEFAULT);
|
||||
g_object_unref (graph);
|
||||
}
|
||||
|
||||
g_hash_table_destroy (visited);
|
||||
g_array_free (keypoints, TRUE);
|
||||
g_object_unref (strokes);
|
||||
|
@ -1276,8 +1302,7 @@ gimp_lineart_line_segment_until_hit (const GeglBuffer *mask,
|
|||
}
|
||||
|
||||
static gfloat *
|
||||
gimp_lineart_estimate_strokes_radii (GeglBuffer *mask,
|
||||
gfloat **lineart_distmap)
|
||||
gimp_lineart_estimate_strokes_radii (GeglBuffer *mask)
|
||||
{
|
||||
GeglBufferIterator *gi;
|
||||
gfloat *dist;
|
||||
|
@ -1422,10 +1447,7 @@ gimp_lineart_estimate_strokes_radii (GeglBuffer *mask,
|
|||
}
|
||||
}
|
||||
|
||||
if (lineart_distmap)
|
||||
*lineart_distmap = dist;
|
||||
else
|
||||
g_free (dist);
|
||||
g_free (dist);
|
||||
g_object_unref (distmap);
|
||||
|
||||
return thickness;
|
||||
|
|
|
@ -437,10 +437,10 @@ gimp_pickable_contiguous_region_by_seed (GimpPickable *pickable,
|
|||
for (y = 0; y < height; y++)
|
||||
for (x = 0; x < width; x++)
|
||||
{
|
||||
gfloat thickness = thickmap[x + y * width];
|
||||
|
||||
if (thickness > 0.0)
|
||||
if (distmap[x + y * width] == 1.0)
|
||||
{
|
||||
gfloat thickness = thickmap[x + y * width];
|
||||
|
||||
if (x > 0)
|
||||
{
|
||||
nx = x - 1;
|
||||
|
|
Loading…
Reference in New Issue