Commit 041104b5 authored by Thomas Manni's avatar Thomas Manni

Paint Select tool: enable viewport-based local selection

The tool now takes care of the portion of the layer effectively displayed
on the screen. This allows faster expansion/shrink of the selection since
an area smaller than the whole layer is used.

It will also limit the impact of the incoming multilevels processing, which
tends to decrease the segmentation accuracy on thin structures, since users
often zoom-in to work on such thin details.
parent d21911eb
Pipeline #248125 passed with stages
in 53 minutes and 1 second
......@@ -55,6 +55,7 @@
#include "display/gimpdisplay.h"
#include "display/gimpdisplayshell.h"
#include "display/gimpdisplayshell-scroll.h"
#include "display/gimptoolgui.h"
#include "core/gimptooloptions.h"
......@@ -132,6 +133,14 @@ static gboolean gimp_paint_select_tool_paint_scribble (GimpPaintSelectTool
static void gimp_paint_select_tool_toggle_scribbles_visibility (GimpPaintSelectTool *ps_tool);
static GeglRectangle gimp_paint_select_tool_get_local_region (GimpDisplay *display,
gint brush_x,
gint brush_y,
gint drawable_off_x,
gint drawable_off_y,
gint drawable_width,
gint drawable_height);
static gfloat euclidean_distance (gint x1,
gint y1,
gint x2,
......@@ -454,8 +463,16 @@ gimp_paint_select_tool_motion (GimpTool *tool,
if (gimp_paint_select_tool_paint_scribble (ps_tool))
{
GimpPaintSelectOptions *options = GIMP_PAINT_SELECT_TOOL_GET_OPTIONS (ps_tool);
GeglRectangle local_region;
GeglBuffer *result;
GTimer *timer = g_timer_new ();
GTimer *timer;
local_region = gimp_paint_select_tool_get_local_region (display,
coords->x, coords->y,
ps_tool->drawable_off_x,
ps_tool->drawable_off_y,
ps_tool->drawable_width,
ps_tool->drawable_height);
if (options->mode == GIMP_PAINT_SELECT_MODE_ADD)
{
......@@ -468,12 +485,29 @@ gimp_paint_select_tool_motion (GimpTool *tool,
gegl_node_set (ps_tool->threshold_node, "value", 0.01, NULL);
}
if (local_region.width < ps_tool->drawable_width ||
local_region.height < ps_tool->drawable_height)
{
gegl_node_set (ps_tool->ps_node,
"use_local_region", TRUE,
"region_x", local_region.x,
"region_y", local_region.y,
"region_width", local_region.width,
"region_height", local_region.height,
NULL);
}
else
{
gegl_node_set (ps_tool->ps_node,
"use_local_region", FALSE, NULL);
}
gegl_node_set (ps_tool->render_node, "buffer", &result, NULL);
g_timer_start (timer);
timer = g_timer_new ();;
gegl_node_process (ps_tool->render_node);
g_timer_stop (timer);
g_printerr ("processing graph takes %.3f s\n", g_timer_elapsed (timer, NULL));
g_printerr ("processing graph takes %.3f s\n\n", g_timer_elapsed (timer, NULL));
g_timer_destroy (timer);
gimp_paint_select_tool_update_image_mask (ps_tool,
......@@ -630,6 +664,8 @@ gimp_paint_select_tool_init_buffers (GimpPaintSelectTool *ps_tool,
gimp_item_get_offset (GIMP_ITEM (drawable),
&ps_tool->drawable_off_x,
&ps_tool->drawable_off_y);
ps_tool->drawable_width = gimp_item_get_width (GIMP_ITEM (drawable));
ps_tool->drawable_height = gimp_item_get_height (GIMP_ITEM (drawable));
ps_tool->drawable = gimp_drawable_get_buffer (drawable);
......@@ -845,6 +881,54 @@ gimp_paint_select_tool_toggle_scribbles_visibility (GimpPaintSelectTool *ps_too
}
}
static GeglRectangle
gimp_paint_select_tool_get_local_region (GimpDisplay *display,
gint brush_x,
gint brush_y,
gint drawable_off_x,
gint drawable_off_y,
gint drawable_width,
gint drawable_height)
{
GimpDisplayShell *shell;
GeglRectangle brush_window;
GeglRectangle drawable_region;
GeglRectangle viewport;
GeglRectangle local_region;
gdouble x, y, w, h;
shell = gimp_display_get_shell (display);
gimp_display_shell_scroll_get_viewport (shell, &x, &y, &w, &h);
viewport.x = (gint) x;
viewport.y = (gint) y;
viewport.width = (gint) w;
viewport.height = (gint) h;
brush_window.x = brush_x - viewport.width / 2;
brush_window.y = brush_y - viewport.height / 2;
brush_window.width = viewport.width;
brush_window.height = viewport.height;
gegl_rectangle_bounding_box (&local_region, &brush_window, &viewport);
drawable_region.x = drawable_off_x;
drawable_region.y = drawable_off_y;
drawable_region.width = drawable_width;
drawable_region.height = drawable_height;
gegl_rectangle_intersect (&local_region, &local_region, &drawable_region);
local_region.x -= drawable_off_x;
local_region.y -= drawable_off_y;
g_printerr ("local region: (%d,%d) %d x %d\n",
local_region.x, local_region.y,
local_region.width, local_region.height);
return local_region;
}
static gfloat
euclidean_distance (gint x1,
gint y1,
......
......@@ -46,6 +46,8 @@ struct _GimpPaintSelectTool
gint drawable_off_x;
gint drawable_off_y;
gint drawable_width;
gint drawable_height;
GeglNode *graph;
GeglNode *ps_node;
......
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