Commit 5a4754f3 authored by Jehan's avatar Jehan

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.
parent 3467acf0
......@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment