Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
polygon.c File Reference
#include "common/darktable.h"
#include "bauhaus/bauhaus.h"
#include "common/debug.h"
#include "common/imagebuf.h"
#include "common/undo.h"
#include "control/conf.h"
#include "develop/blend.h"
#include "develop/imageop.h"
#include "develop/masks.h"
#include "develop/openmp_maths.h"
#include "gui/actions/menu.h"
#include <assert.h>
+ Include dependency graph for polygon.c:

Macros

#define HARDNESS_MIN   0.0005f
 
#define HARDNESS_MAX   1.0f
 
#define BORDER_MIN   0.00005f
 
#define BORDER_MAX   0.5f
 
#define POLYGON_MAX_SELF_INTERSECTIONS(nb_nodes)   ((nb_nodes) * 4)
 

Functions

static void _polygon_bounding_box_raw (const float *const point_buffer, const float *border_buffer, const int corner_count, const int point_count, int border_count, float *x_min, float *x_max, float *y_min, float *y_max)
 Compute raw bounding box for polygon points and border samples.
 
static void _polygon_get_XY (const float p0_x, const float p0_y, const float p1_x, const float p1_y, const float p2_x, const float p2_y, const float p3_x, const float p3_y, const float t, float *out_x, float *out_y)
 Evaluate a cubic Bezier at t in [0, 1].
 
static void _polygon_border_get_XY (const float p0_x, const float p0_y, const float p1_x, const float p1_y, const float p2_x, const float p2_y, const float p3_x, const float p3_y, const float t, const float radius, float *center_x, float *center_y, float *border_x, float *border_y)
 Evaluate a cubic Bezier and its border offset at t in [0, 1].
 
static void _polygon_ctrl2_to_handle (const float point_x, const float point_y, const float ctrl_x, const float ctrl_y, float *handle_x, float *handle_y, const gboolean clockwise)
 Convert control point #2 into a handle extremity.
 
static void _polygon_handle_to_ctrl (const float point_x, const float point_y, const float handle_x, const float handle_y, float *ctrl1_x, float *ctrl1_y, float *ctrl2_x, float *ctrl2_y, const gboolean clockwise)
 Convert a handle extremity into symmetric Bezier control points.
 
static void _polygon_catmull_to_bezier (const float x1, const float y1, const float x2, const float y2, const float x3, const float y3, const float x4, const float y4, float *bezier_x1, float *bezier_y1, float *bezier_x2, float *bezier_y2)
 Convert a Catmull-Rom segment to Bezier control points.
 
static void _polygon_init_ctrl_points (dt_masks_form_t *mask_form)
 Initialize control points to match a Catmull-Rom-like spline.
 
static gboolean _polygon_is_clockwise (dt_masks_form_t *mask_form)
 Determine polygon winding order.
 
static int _polygon_fill_gaps (int last_x, int last_y, int target_x, int target_y, dt_masks_dynbuf_t *points)
 Fill gaps between two points with an integer Bresenham line.
 
static void _polygon_points_recurs_border_gaps (float *center_max, float *border_min, float *border_min2, float *border_max, dt_masks_dynbuf_t *draw_points, dt_masks_dynbuf_t *draw_border, gboolean clockwise)
 Fill gaps between border points with a circular arc.
 
static gboolean _is_within_pxl_threshold (float *min, float *max, int pixel_threshold)
 
static void _polygon_points_recurs (float *segment_start, float *segment_end, double t_min, double t_max, float *polygon_min, float *polygon_max, float *border_min, float *border_max, float *result_polygon, float *result_border, dt_masks_dynbuf_t *draw_points, dt_masks_dynbuf_t *draw_border, int with_border, const int pixel_threshold)
 Recursive subdivision to sample polygon and border points.
 
static int _polygon_find_self_intersection (dt_masks_dynbuf_t *intersections, int node_count, float *border_points, int border_point_count, int *intersection_count_out)
 Find all self-intersection segments in a polygon border.
 
static int _polygon_get_pts_border (dt_develop_t *develop, dt_masks_form_t *mask_form, const double iop_order, const int transform_direction, dt_dev_pixelpipe_t *pipe, float **point_buffer, int *point_count, float **border_buffer, int *border_count, gboolean source)
 Build point and border buffers for a polygon mask.
 
static float _polygon_get_position_in_segment (float point_x, float point_y, dt_masks_form_t *mask_form, int segment_index)
 Find the parametric position along a segment closest to a point.
 
static void _add_node_to_segment (struct dt_iop_module_t *module, dt_masks_form_t *mask_form, int parent_id, dt_masks_form_gui_t *mask_gui, int form_index)
 
static void _polygon_translate_node (dt_masks_node_polygon_t *node, const float delta_x, const float delta_y)
 
static void _polygon_translate_all_nodes (dt_masks_form_t *mask_form, const float delta_x, const float delta_y)
 
static int _polygon_get_points_border (dt_develop_t *develop, dt_masks_form_t *mask_form, float **point_buffer, int *point_count, float **border_buffer, int *border_count, int source, const dt_iop_module_t *module)
 
static void _polygon_get_sizes (struct dt_iop_module_t *module, dt_masks_form_t *mask_form, dt_masks_form_gui_t *mask_gui, int form_index, float *mask_size, float *border_size)
 
static gboolean _polygon_form_gravity_center (const dt_masks_form_t *mask_form, float *center_x, float *center_y, float *area)
 Compute polygon centroid from the form nodes (normalized space).
 
static float _polygon_get_interaction_value (const dt_masks_form_t *mask_form, dt_masks_interaction_t interaction)
 
static gboolean _polygon_get_gravity_center (const dt_masks_form_t *mask_form, float center[2], float *area)
 
static int _change_size (dt_masks_form_t *mask_form, int parent_id, dt_masks_form_gui_t *mask_gui, struct dt_iop_module_t *module, int form_index, const float amount, const dt_masks_increment_t increment, const int flow)
 Scale the polygon around its centroid.
 
static int _change_hardness (dt_masks_form_t *mask_form, int parent_id, dt_masks_form_gui_t *mask_gui, struct dt_iop_module_t *module, int form_index, const float amount, const dt_masks_increment_t increment, int flow)
 Change polygon hardness for the active node scope or the full shape.
 
static float _polygon_set_interaction_value (dt_masks_form_t *mask_form, dt_masks_interaction_t interaction, float value, dt_masks_increment_t increment, int flow, dt_masks_form_gui_t *mask_gui, struct dt_iop_module_t *module)
 
static void _polygon_get_distance (float point_x, float point_y, float radius, dt_masks_form_gui_t *mask_gui, int form_index, int node_count, int *inside, int *inside_border, int *near, int *inside_source, float *dist)
 Compute proximity between a point and the polygon GUI shape.
 
static gboolean _polygon_border_handle_cb (const dt_masks_form_gui_points_t *gui_points, int node_count, int node_index, float *handle_x, float *handle_y, void *user_data)
 Polygon-specific border handle lookup.
 
static void _polygon_curve_handle_cb (const dt_masks_form_gui_points_t *gui_points, int node_index, float *handle_x, float *handle_y, void *user_data)
 Polygon-specific curve handle lookup (depends on winding direction).
 
static void _polygon_distance_cb (float pointer_x, float pointer_y, float cursor_radius, dt_masks_form_gui_t *mask_gui, int form_index, int node_count, int *inside, int *inside_border, int *near, int *inside_source, float *dist, void *user_data)
 Polygon-specific inside/border/segment hit testing.
 
static int _find_closest_handle (dt_masks_form_t *mask_form, dt_masks_form_gui_t *mask_gui, int form_index)
 
static void _polygon_gui_gravity_center (const float *point_buffer, int point_count, float *center_x, float *center_y, float *area)
 Compute polygon centroid from GUI points using the shoelace formula.
 
static int _init_hardness (dt_masks_form_t *mask_form, const float amount, const dt_masks_increment_t increment, const int flow, const float mask_size, const float border_size)
 Initialize hardness from config and emit the toast with a size-normalized percentage.
 
static int _polygon_events_mouse_scrolled (struct dt_iop_module_t *module, double x, double y, int up, int flow, uint32_t state, dt_masks_form_t *mask_form, int parent_id, dt_masks_form_gui_t *mask_gui, int form_index, dt_masks_interaction_t interaction)
 Handle mouse wheel updates for polygon size/hardness/opacity.
 
static int _polygon_creation_closing_form (dt_masks_form_t *mask_form, dt_masks_form_gui_t *mask_gui)
 Close the polygon creation by removing the temporary last node.
 
static int _polygon_events_button_pressed (struct dt_iop_module_t *module, double x, double y, double pressure, int which, int type, uint32_t state, dt_masks_form_t *mask_form, int parent_id, dt_masks_form_gui_t *mask_gui, int form_index)
 
static int _polygon_events_button_released (struct dt_iop_module_t *module, double x, double y, int which, uint32_t state, dt_masks_form_t *mask_form, int parent_id, dt_masks_form_gui_t *mask_gui, int form_index)
 
static int _polygon_events_key_pressed (struct dt_iop_module_t *module, GdkEventKey *event, dt_masks_form_t *mask_form, int parent_id, dt_masks_form_gui_t *mask_gui, int form_index)
 
static int _polygon_events_mouse_moved (struct dt_iop_module_t *module, double x, double y, double pressure, int which, dt_masks_form_t *mask_form, int parent_id, dt_masks_form_gui_t *mask_gui, int form_index)
 Polygon mouse-move handler.
 
static void _polygon_draw_shape (cairo_t *cr, const float *point_buffer, const int point_count, const int node_count, const gboolean draw_border, const gboolean draw_source)
 Draw a polygon or border polyline, skipping NaN points.
 
static void _polygon_events_post_expose (cairo_t *cr, float zoom_scale, dt_masks_form_gui_t *mask_gui, int form_index, int node_count)
 Draw polygon overlays (nodes, handles, borders, source) after exposure.
 
static void _polygon_bounding_box (const float *const point_buffer, const float *border_buffer, const int corner_count, const int point_count, int border_count, int *width, int *height, int *posx, int *posy)
 Compute bounding box and add a small padding for rasterization safety.
 
static int _get_area (const dt_iop_module_t *const module, dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *const piece, dt_masks_form_t *const mask_form, int *width, int *height, int *posx, int *posy, gboolean get_source)
 
static int _polygon_get_source_area (dt_iop_module_t *module, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece, dt_masks_form_t *mask_form, int *width, int *height, int *posx, int *posy)
 
static int _polygon_get_area (const dt_iop_module_t *const module, dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *const piece, dt_masks_form_t *const mask_form, int *width, int *height, int *posx, int *posy)
 
void _polygon_falloff (float *const restrict buffer, int *p0, int *p1, int posx, int posy, int buffer_width)
 Write a falloff segment into the mask buffer.
 
static int _polygon_get_mask (const dt_iop_module_t *const module, dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *const piece, dt_masks_form_t *const mask_form, float **buffer, int *width, int *height, int *posx, int *posy)
 
static int _polygon_crop_to_roi (float *polygon, const int point_count, float xmin, float xmax, float ymin, float ymax)
 
static void _polygon_falloff_roi (float *buffer, int *p0, int *p1, int bw, int bh)
 
static int _polygon_get_mask_roi (const dt_iop_module_t *const module, dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *const piece, dt_masks_form_t *const mask_form, const dt_iop_roi_t *roi, float *buffer)
 
static void _polygon_sanitize_config (dt_masks_type_t type)
 
static void _polygon_set_form_name (struct dt_masks_form_t *const mask_form, const size_t form_number)
 Assign a default name for a polygon form.
 
static void _polygon_set_hint_message (const dt_masks_form_gui_t *const mask_gui, const dt_masks_form_t *const mask_form, const int opacity, char *const restrict msgbuf, const size_t msgbuf_len)
 
static void _polygon_duplicate_points (dt_develop_t *const dev, dt_masks_form_t *const base, dt_masks_form_t *const dest)
 
static void _polygon_initial_source_pos (const float iwd, const float iht, float *x, float *y)
 
static void _polygon_creation_closing_form_callback (GtkWidget *widget, gpointer user_data)
 
static void _polygon_switch_node_callback (GtkWidget *widget, gpointer user_data)
 
static void _polygon_reset_round_node_callback (GtkWidget *widget, gpointer user_data)
 
static void _polygon_add_node_callback (GtkWidget *menu, gpointer user_data)
 
static int _polygon_populate_context_menu (GtkWidget *menu, struct dt_masks_form_t *mask_form, struct dt_masks_form_gui_t *mask_gui, const float pzx, const float pzy)
 

Variables

const dt_masks_functions_t dt_masks_functions_polygon
 

Macro Definition Documentation

◆ BORDER_MAX

#define BORDER_MAX   0.5f

◆ BORDER_MIN

#define BORDER_MIN   0.00005f

◆ HARDNESS_MAX

#define HARDNESS_MAX   1.0f

◆ HARDNESS_MIN

#define HARDNESS_MIN   0.0005f

◆ POLYGON_MAX_SELF_INTERSECTIONS

#define POLYGON_MAX_SELF_INTERSECTIONS (   nb_nodes)    ((nb_nodes) * 4)

Function Documentation

◆ _add_node_to_segment()

◆ _change_hardness()

static int _change_hardness ( dt_masks_form_t mask_form,
int  parent_id,
dt_masks_form_gui_t mask_gui,
struct dt_iop_module_t module,
int  form_index,
const float  amount,
const dt_masks_increment_t  increment,
int  flow 
)
static

◆ _change_size()

static int _change_size ( dt_masks_form_t mask_form,
int  parent_id,
dt_masks_form_gui_t mask_gui,
struct dt_iop_module_t module,
int  form_index,
const float  amount,
const dt_masks_increment_t  increment,
const int  flow 
)
static

◆ _find_closest_handle()

static int _find_closest_handle ( dt_masks_form_t mask_form,
dt_masks_form_gui_t mask_gui,
int  form_index 
)
static

◆ _get_area()

static int _get_area ( const dt_iop_module_t *const  module,
dt_dev_pixelpipe_t pipe,
const dt_dev_pixelpipe_iop_t *const  piece,
dt_masks_form_t *const  mask_form,
int *  width,
int *  height,
int *  posx,
int *  posy,
gboolean  get_source 
)
static

◆ _init_hardness()

static int _init_hardness ( dt_masks_form_t mask_form,
const float  amount,
const dt_masks_increment_t  increment,
const int  flow,
const float  mask_size,
const float  border_size 
)
static

Initialize hardness from config and emit the toast with a size-normalized percentage.

References dt_masks_get_set_conf_value(), dt_toast_log(), HARDNESS_MAX, and HARDNESS_MIN.

Referenced by _change_hardness().

◆ _is_within_pxl_threshold()

static gboolean _is_within_pxl_threshold ( float *  min,
float *  max,
int  pixel_threshold 
)
inlinestatic

References max, and min.

Referenced by _polygon_points_recurs().

◆ _polygon_add_node_callback()

◆ _polygon_border_get_XY()

static void _polygon_border_get_XY ( const float  p0_x,
const float  p0_y,
const float  p1_x,
const float  p1_y,
const float  p2_x,
const float  p2_y,
const float  p3_x,
const float  p3_y,
const float  t,
const float  radius,
float *  center_x,
float *  center_y,
float *  border_x,
float *  border_y 
)
static

Evaluate a cubic Bezier and its border offset at t in [0, 1].

The border point is offset along the normal, scaled by rad.

References _polygon_get_XY(), a, b, c, d, double(), and t.

Referenced by _polygon_get_pts_border(), and _polygon_points_recurs().

◆ _polygon_border_handle_cb()

static gboolean _polygon_border_handle_cb ( const dt_masks_form_gui_points_t gui_points,
int  node_count,
int  node_index,
float *  handle_x,
float *  handle_y,
void user_data 
)
static

Polygon-specific border handle lookup.

Polygon borders are stored directly in gui_points->border at node indices.

References dt_masks_form_gui_points_t::border, and FALSE.

Referenced by _find_closest_handle().

◆ _polygon_bounding_box()

static void _polygon_bounding_box ( const float *const  point_buffer,
const float *  border_buffer,
const int  corner_count,
const int  point_count,
int  border_count,
int *  width,
int *  height,
int *  posx,
int *  posy 
)
static

Compute bounding box and add a small padding for rasterization safety.

References _polygon_bounding_box_raw(), height, and width.

Referenced by _get_area(), and _polygon_get_mask().

◆ _polygon_bounding_box_raw()

static void _polygon_bounding_box_raw ( const float *const  point_buffer,
const float *  border_buffer,
const int  corner_count,
const int  point_count,
int  border_count,
float *  x_min,
float *  x_max,
float *  y_min,
float *  y_max 
)
static

Compute raw bounding box for polygon points and border samples.

References MAX, and MIN.

Referenced by _polygon_bounding_box(), and _polygon_get_mask_roi().

◆ _polygon_catmull_to_bezier()

static void _polygon_catmull_to_bezier ( const float  x1,
const float  y1,
const float  x2,
const float  y2,
const float  x3,
const float  y3,
const float  x4,
const float  y4,
float *  bezier_x1,
float *  bezier_y1,
float *  bezier_x2,
float *  bezier_y2 
)
static

Convert a Catmull-Rom segment to Bezier control points.

Referenced by _polygon_init_ctrl_points().

◆ _polygon_creation_closing_form()

◆ _polygon_creation_closing_form_callback()

static void _polygon_creation_closing_form_callback ( GtkWidget widget,
gpointer  user_data 
)
static

◆ _polygon_crop_to_roi()

static int _polygon_crop_to_roi ( float *  polygon,
const int  point_count,
float  xmin,
float  xmax,
float  ymin,
float  ymax 
)
static

crop polygon to roi given by xmin, xmax, ymin, ymax. polygon segments outside of roi are replaced by nodes lying on roi borders.

References delta, dt_free, n, r, and x.

Referenced by _polygon_get_mask_roi().

◆ _polygon_ctrl2_to_handle()

static void _polygon_ctrl2_to_handle ( const float  point_x,
const float  point_y,
const float  ctrl_x,
const float  ctrl_y,
float *  handle_x,
float *  handle_y,
const gboolean  clockwise 
)
static

Convert control point #2 into a handle extremity.

The values are expected in orthonormal space.

Referenced by _polygon_curve_handle_cb(), _polygon_events_button_pressed(), and _polygon_events_post_expose().

◆ _polygon_curve_handle_cb()

static void _polygon_curve_handle_cb ( const dt_masks_form_gui_points_t gui_points,
int  node_index,
float *  handle_x,
float *  handle_y,
void user_data 
)
static

Polygon-specific curve handle lookup (depends on winding direction).

References _polygon_ctrl2_to_handle(), dt_masks_form_gui_points_t::clockwise, and dt_masks_form_gui_points_t::points.

Referenced by _find_closest_handle().

◆ _polygon_distance_cb()

static void _polygon_distance_cb ( float  pointer_x,
float  pointer_y,
float  cursor_radius,
dt_masks_form_gui_t mask_gui,
int  form_index,
int  node_count,
int *  inside,
int *  inside_border,
int *  near,
int *  inside_source,
float *  dist,
void user_data 
)
static

Polygon-specific inside/border/segment hit testing.

References _polygon_get_distance(), and dist().

Referenced by _find_closest_handle().

◆ _polygon_draw_shape()

static void _polygon_draw_shape ( cairo_t *  cr,
const float *  point_buffer,
const int  point_count,
const int  node_count,
const gboolean  draw_border,
const gboolean  draw_source 
)
static

Draw a polygon or border polyline, skipping NaN points.

Todo:
: Why not just avoid having NaN points in the array?

◆ _polygon_duplicate_points()

static void _polygon_duplicate_points ( dt_develop_t *const  dev,
dt_masks_form_t *const  base,
dt_masks_form_t *const  dest 
)
static

◆ _polygon_events_button_pressed()

static int _polygon_events_button_pressed ( struct dt_iop_module_t module,
double  x,
double  y,
double  pressure,
int  which,
int  type,
uint32_t  state,
dt_masks_form_t mask_form,
int  parent_id,
dt_masks_form_gui_t mask_gui,
int  form_index 
)
static

◆ _polygon_events_button_released()

static int _polygon_events_button_released ( struct dt_iop_module_t module,
double  x,
double  y,
int  which,
uint32_t  state,
dt_masks_form_t mask_form,
int  parent_id,
dt_masks_form_gui_t mask_gui,
int  form_index 
)
static

◆ _polygon_events_key_pressed()

◆ _polygon_events_mouse_moved()

static int _polygon_events_mouse_moved ( struct dt_iop_module_t module,
double  x,
double  y,
double  pressure,
int  which,
dt_masks_form_t mask_form,
int  parent_id,
dt_masks_form_gui_t mask_gui,
int  form_index 
)
static

Polygon mouse-move handler.

Widget-space coordinates are only used by the top-level dispatcher. Absolute output-image coordinates come from mask_gui->pos, normalized output-image coordinates come from mask_gui->rel_pos, and raw-space edits are derived locally through the appropriate backtransform helper.

References _polygon_handle_to_ctrl(), _polygon_init_ctrl_points(), _polygon_is_clockwise(), _polygon_translate_all_nodes(), _polygon_translate_node(), dt_masks_node_polygon_t::border, dt_masks_form_gui_points_t::border, dt_masks_form_gui_points_t::clockwise, dt_masks_form_gui_t::creation, dt_masks_form_gui_t::creation_closing_form, dt_masks_node_polygon_t::ctrl1, dt_masks_node_polygon_t::ctrl2, darktable, darktable_t::develop, dt_dev_coordinates_image_abs_to_raw_norm(), DT_GUI_MOUSE_EFFECT_RADIUS_SCALED, dt_masks_border_from_projected_handle(), DT_MASKS_CLONE, dt_masks_gui_delta_from_raw_anchor(), dt_masks_gui_delta_to_image_abs(), dt_masks_gui_delta_to_raw_norm(), dt_masks_gui_form_create(), dt_masks_gui_form_create_throttled(), DT_MASKS_POINT_STATE_USER, dt_masks_project_on_line(), dt_masks_set_ctrl_points(), dt_masks_translate_source(), dt_masks_form_gui_t::form_dragging, g_list_next_wraparound(), g_list_shorter_than(), dt_masks_form_gui_t::handle_border_dragging, dt_masks_form_gui_t::handle_dragging, dt_masks_node_polygon_t::node, dt_masks_form_gui_t::node_dragging, p, dt_masks_form_t::points, dt_masks_form_gui_points_t::points, dt_masks_form_gui_t::points, dt_masks_form_gui_t::pos, dt_develop_t::raw_height, dt_develop_t::raw_width, dt_develop_t::roi, dt_masks_form_gui_t::seg_dragging, dt_masks_form_t::source, dt_masks_form_gui_t::source_dragging, dt_masks_node_polygon_t::state, and dt_masks_form_t::type.

◆ _polygon_events_mouse_scrolled()

static int _polygon_events_mouse_scrolled ( struct dt_iop_module_t module,
double  x,
double  y,
int  up,
int  flow,
uint32_t  state,
dt_masks_form_t mask_form,
int  parent_id,
dt_masks_form_gui_t mask_gui,
int  form_index,
dt_masks_interaction_t  interaction 
)
static

◆ _polygon_events_post_expose()

static void _polygon_events_post_expose ( cairo_t *  cr,
float  zoom_scale,
dt_masks_form_gui_t mask_gui,
int  form_index,
int  node_count 
)
static

Draw polygon overlays (nodes, handles, borders, source) after exposure.

References _polygon_ctrl2_to_handle(), _polygon_gui_gravity_center(), _polygon_is_clockwise(), dt_masks_form_gui_points_t::border, dt_masks_form_gui_points_t::border_count, dt_masks_form_gui_t::border_selected, dt_masks_form_gui_points_t::clockwise, dt_masks_form_gui_t::creation, darktable, darktable_t::develop, dt_masks_functions_t::draw_shape, dt_draw_handle(), dt_draw_node(), dt_draw_shape_lines(), DT_MASKS_CLONE, DT_MASKS_DASH_STICK, dt_masks_draw_path_seg_by_seg(), dt_masks_draw_source(), dt_masks_draw_source_preview(), dt_masks_functions_polygon, dt_masks_get_from_id(), dt_masks_get_visible_form(), dt_masks_gui_selected_handle_border_index(), dt_masks_gui_selected_handle_index(), dt_masks_gui_selected_node_index(), DT_MASKS_IS_RETOUCHE, dt_masks_node_is_cusp(), FALSE, dt_masks_form_group_t::formid, dt_masks_form_gui_t::group_selected, dt_masks_form_gui_t::handle_border_hovered, dt_masks_form_gui_t::handle_hovered, dt_masks_form_gui_t::handle_selected, dt_masks_gui_center_point_t::main, dt_masks_form_gui_t::node_dragging, dt_masks_form_gui_t::node_hovered, dt_masks_form_gui_t::node_selected, dt_masks_form_t::points, dt_masks_form_gui_points_t::points, dt_masks_form_gui_t::points, dt_masks_form_gui_points_t::points_count, dt_masks_form_gui_t::pos, dt_masks_form_gui_points_t::source, dt_masks_gui_center_point_t::source, dt_masks_form_gui_points_t::source_count, TRUE, dt_masks_form_t::type, dt_masks_form_gui_t::type, x, dt_masks_gui_center_point_t::x, and dt_masks_gui_center_point_t::y.

◆ _polygon_falloff()

void _polygon_falloff ( float *const restrict  buffer,
int *  p0,
int *  p1,
int  posx,
int  posy,
int  buffer_width 
)

Write a falloff segment into the mask buffer.

References i, sqf(), and x.

Referenced by _polygon_get_mask().

◆ _polygon_falloff_roi()

static void _polygon_falloff_roi ( float *  buffer,
int *  p0,
int *  p1,
int  bw,
int  bh 
)
inlinestatic

we write a falloff segment respecting limits of buffer

References i, MAX, and x.

Referenced by _polygon_get_mask_roi().

◆ _polygon_fill_gaps()

static int _polygon_fill_gaps ( int  last_x,
int  last_y,
int  target_x,
int  target_y,
dt_masks_dynbuf_t points 
)
static

Fill gaps between two points with an integer Bresenham line.

This avoids repeated floating-point division and rounding errors.

References dt_masks_dynbuf_add_2(), and dt_masks_dynbuf_reset().

Referenced by _polygon_find_self_intersection().

◆ _polygon_find_self_intersection()

static int _polygon_find_self_intersection ( dt_masks_dynbuf_t intersections,
int  node_count,
float *  border_points,
int  border_point_count,
int *  intersection_count_out 
)
static

◆ _polygon_form_gravity_center()

static gboolean _polygon_form_gravity_center ( const dt_masks_form_t mask_form,
float *  center_x,
float *  center_y,
float *  surface 
)
static

Compute polygon centroid from the form nodes (normalized space).

References FALSE, g_list_next_wraparound(), g_list_shorter_than(), dt_masks_node_polygon_t::node, dt_masks_form_t::points, and TRUE.

Referenced by _change_size().

◆ _polygon_get_area()

static int _polygon_get_area ( const dt_iop_module_t *const  module,
dt_dev_pixelpipe_t pipe,
const dt_dev_pixelpipe_iop_t *const  piece,
dt_masks_form_t *const  mask_form,
int *  width,
int *  height,
int *  posx,
int *  posy 
)
static

References _get_area(), FALSE, height, and width.

◆ _polygon_get_distance()

static void _polygon_get_distance ( float  point_x,
float  point_y,
float  radius,
dt_masks_form_gui_t mask_gui,
int  form_index,
int  node_count,
int *  inside,
int *  inside_border,
int *  near,
int *  inside_source,
float *  dist 
)
static

◆ _polygon_get_gravity_center()

static gboolean _polygon_get_gravity_center ( const dt_masks_form_t mask_form,
float  center[2],
float *  area 
)
static

◆ _polygon_get_interaction_value()

◆ _polygon_get_mask()

◆ _polygon_get_mask_roi()

◆ _polygon_get_points_border()

static int _polygon_get_points_border ( dt_develop_t develop,
dt_masks_form_t mask_form,
float **  point_buffer,
int *  point_count,
float **  border_buffer,
int *  border_count,
int  source,
const dt_iop_module_t module 
)
static

◆ _polygon_get_position_in_segment()

static float _polygon_get_position_in_segment ( float  point_x,
float  point_y,
dt_masks_form_t mask_form,
int  segment_index 
)
static

Find the parametric position along a segment closest to a point.

We only need 1% precision, so we use exhaustive sampling.

References _polygon_get_XY(), dist(), g_list_next_bounded(), i, dt_masks_node_polygon_t::node, dt_masks_form_t::points, and t.

Referenced by _add_node_to_segment().

◆ _polygon_get_pts_border()

static int _polygon_get_pts_border ( dt_develop_t develop,
dt_masks_form_t mask_form,
const double  iop_order,
const int  transform_direction,
dt_dev_pixelpipe_t pipe,
float **  point_buffer,
int *  point_count,
float **  border_buffer,
int *  border_count,
gboolean  source 
)
static

◆ _polygon_get_sizes()

◆ _polygon_get_source_area()

static int _polygon_get_source_area ( dt_iop_module_t module,
dt_dev_pixelpipe_t pipe,
dt_dev_pixelpipe_iop_t piece,
dt_masks_form_t mask_form,
int *  width,
int *  height,
int *  posx,
int *  posy 
)
static

References _get_area(), height, TRUE, and width.

◆ _polygon_get_XY()

static void _polygon_get_XY ( const float  p0_x,
const float  p0_y,
const float  p1_x,
const float  p1_y,
const float  p2_x,
const float  p2_y,
const float  p3_x,
const float  p3_y,
const float  t,
float *  out_x,
float *  out_y 
)
static

Evaluate a cubic Bezier at t in [0, 1].

Uses the four control points (p0..p3) and returns the interpolated point.

References a, b, c, d, and t.

Referenced by _polygon_border_get_XY(), and _polygon_get_position_in_segment().

◆ _polygon_gui_gravity_center()

static void _polygon_gui_gravity_center ( const float *  point_buffer,
int  point_count,
float *  center_x,
float *  center_y,
float *  area 
)
static

Compute polygon centroid from GUI points using the shoelace formula.

This treats the polygon as simple and closed, using the node positions only (no border points). The area is returned with sign (clockwise vs counter).

Referenced by _polygon_events_post_expose().

◆ _polygon_handle_to_ctrl()

static void _polygon_handle_to_ctrl ( const float  point_x,
const float  point_y,
const float  handle_x,
const float  handle_y,
float *  ctrl1_x,
float *  ctrl1_y,
float *  ctrl2_x,
float *  ctrl2_y,
const gboolean  clockwise 
)
static

Convert a handle extremity into symmetric Bezier control points.

The values are expected in orthonormal space.

Referenced by _polygon_events_mouse_moved().

◆ _polygon_init_ctrl_points()

static void _polygon_init_ctrl_points ( dt_masks_form_t mask_form)
static

◆ _polygon_initial_source_pos()

static void _polygon_initial_source_pos ( const float  iwd,
const float  iht,
float *  x,
float *  y 
)
static

◆ _polygon_is_clockwise()

static gboolean _polygon_is_clockwise ( dt_masks_form_t mask_form)
static

◆ _polygon_points_recurs()

static void _polygon_points_recurs ( float *  segment_start,
float *  segment_end,
double  t_min,
double  t_max,
float *  polygon_min,
float *  polygon_max,
float *  border_min,
float *  border_max,
float *  result_polygon,
float *  result_border,
dt_masks_dynbuf_t draw_points,
dt_masks_dynbuf_t draw_border,
int  with_border,
const int  pixel_threshold 
)
static

Recursive subdivision to sample polygon and border points.

This avoids large gaps by subdividing until points are within a pixel threshold.

References _is_within_pxl_threshold(), _polygon_border_get_XY(), _polygon_points_recurs(), and dt_masks_dynbuf_add_2().

Referenced by _polygon_get_pts_border(), and _polygon_points_recurs().

◆ _polygon_points_recurs_border_gaps()

static void _polygon_points_recurs_border_gaps ( float *  center_max,
float *  border_min,
float *  border_min2,
float *  border_max,
dt_masks_dynbuf_t draw_points,
dt_masks_dynbuf_t draw_border,
gboolean  clockwise 
)
static

Fill gaps between border points with a circular arc.

This is used when the border has gaps, especially near sharp nodes.

References dt_masks_dynbuf_reserve_n(), and M_PI.

Referenced by _polygon_get_pts_border().

◆ _polygon_populate_context_menu()

◆ _polygon_reset_round_node_callback()

◆ _polygon_sanitize_config()

static void _polygon_sanitize_config ( dt_masks_type_t  type)
static

◆ _polygon_set_form_name()

static void _polygon_set_form_name ( struct dt_masks_form_t *const  mask_form,
const size_t  form_number 
)
static

Assign a default name for a polygon form.

References dt_masks_form_t::name.

◆ _polygon_set_hint_message()

static void _polygon_set_hint_message ( const dt_masks_form_gui_t *const  mask_gui,
const dt_masks_form_t *const  mask_form,
const int  opacity,
char *const restrict  msgbuf,
const size_t  msgbuf_len 
)
static

◆ _polygon_set_interaction_value()

static float _polygon_set_interaction_value ( dt_masks_form_t mask_form,
dt_masks_interaction_t  interaction,
float  value,
dt_masks_increment_t  increment,
int  flow,
dt_masks_form_gui_t mask_gui,
struct dt_iop_module_t module 
)
static

◆ _polygon_switch_node_callback()

◆ _polygon_translate_all_nodes()

static void _polygon_translate_all_nodes ( dt_masks_form_t mask_form,
const float  delta_x,
const float  delta_y 
)
static

◆ _polygon_translate_node()

static void _polygon_translate_node ( dt_masks_node_polygon_t node,
const float  delta_x,
const float  delta_y 
)
inlinestatic

Variable Documentation

◆ dt_masks_functions_polygon

const dt_masks_functions_t dt_masks_functions_polygon
Initial value:
= {
.point_struct_size = sizeof(struct dt_masks_node_polygon_t),
.sanitize_config = _polygon_sanitize_config,
.set_form_name = _polygon_set_form_name,
.set_hint_message = _polygon_set_hint_message,
.duplicate_points = _polygon_duplicate_points,
.initial_source_pos = _polygon_initial_source_pos,
.get_distance = _polygon_get_distance,
.get_points_border = _polygon_get_points_border,
.get_mask = _polygon_get_mask,
.get_mask_roi = _polygon_get_mask_roi,
.get_area = _polygon_get_area,
.get_source_area = _polygon_get_source_area,
.get_gravity_center = _polygon_get_gravity_center,
.get_interaction_value = _polygon_get_interaction_value,
.set_interaction_value = _polygon_set_interaction_value,
.update_hover = _find_closest_handle,
.mouse_scrolled = _polygon_events_mouse_scrolled,
.button_pressed = _polygon_events_button_pressed,
.button_released = _polygon_events_button_released,
.draw_shape = _polygon_draw_shape,
.init_ctrl_points = _polygon_init_ctrl_points,
.populate_context_menu = _polygon_populate_context_menu
}
static gboolean _polygon_get_gravity_center(const dt_masks_form_t *mask_form, float center[2], float *area)
Definition polygon.c:1248
static int _polygon_populate_context_menu(GtkWidget *menu, struct dt_masks_form_t *mask_form, struct dt_masks_form_gui_t *mask_gui, const float pzx, const float pzy)
Definition polygon.c:3594
static int _find_closest_handle(dt_masks_form_t *mask_form, dt_masks_form_gui_t *mask_gui, int form_index)
Definition polygon.c:1455
static float _polygon_get_interaction_value(const dt_masks_form_t *mask_form, dt_masks_interaction_t interaction)
Definition polygon.c:1215
static int _polygon_get_mask_roi(const dt_iop_module_t *const module, dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *const piece, dt_masks_form_t *const mask_form, const dt_iop_roi_t *roi, float *buffer)
Definition polygon.c:3053
static void _polygon_events_post_expose(cairo_t *cr, float zoom_scale, dt_masks_form_gui_t *mask_gui, int form_index, int node_count)
Draw polygon overlays (nodes, handles, borders, source) after exposure.
Definition polygon.c:2164
static float _polygon_set_interaction_value(dt_masks_form_t *mask_form, dt_masks_interaction_t interaction, float value, dt_masks_increment_t increment, int flow, dt_masks_form_gui_t *mask_gui, struct dt_iop_module_t *module)
Definition polygon.c:1281
static int _polygon_get_area(const dt_iop_module_t *const module, dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *const piece, dt_masks_form_t *const mask_form, int *width, int *height, int *posx, int *posy)
Definition polygon.c:2403
static void _polygon_set_form_name(struct dt_masks_form_t *const mask_form, const size_t form_number)
Assign a default name for a polygon form.
Definition polygon.c:3468
static int _polygon_events_mouse_moved(struct dt_iop_module_t *module, double x, double y, double pressure, int which, dt_masks_form_t *mask_form, int parent_id, dt_masks_form_gui_t *mask_gui, int form_index)
Polygon mouse-move handler.
Definition polygon.c:1962
static int _polygon_events_button_pressed(struct dt_iop_module_t *module, double x, double y, double pressure, int which, int type, uint32_t state, dt_masks_form_t *mask_form, int parent_id, dt_masks_form_gui_t *mask_gui, int form_index)
Definition polygon.c:1719
static int _polygon_events_mouse_scrolled(struct dt_iop_module_t *module, double x, double y, int up, int flow, uint32_t state, dt_masks_form_t *mask_form, int parent_id, dt_masks_form_gui_t *mask_gui, int form_index, dt_masks_interaction_t interaction)
Handle mouse wheel updates for polygon size/hardness/opacity.
Definition polygon.c:1664
static void _polygon_initial_source_pos(const float iwd, const float iht, float *x, float *y)
Definition polygon.c:3506
static int _polygon_events_button_released(struct dt_iop_module_t *module, double x, double y, int which, uint32_t state, dt_masks_form_t *mask_form, int parent_id, dt_masks_form_gui_t *mask_gui, int form_index)
Definition polygon.c:1897
static int _polygon_events_key_pressed(struct dt_iop_module_t *module, GdkEventKey *event, dt_masks_form_t *mask_form, int parent_id, dt_masks_form_gui_t *mask_gui, int form_index)
Definition polygon.c:1912
static int _polygon_get_source_area(dt_iop_module_t *module, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece, dt_masks_form_t *mask_form, int *width, int *height, int *posx, int *posy)
Definition polygon.c:2396
static void _polygon_set_hint_message(const dt_masks_form_gui_t *const mask_gui, const dt_masks_form_t *const mask_form, const int opacity, char *const restrict msgbuf, const size_t msgbuf_len)
Definition polygon.c:3473
static void _polygon_duplicate_points(dt_develop_t *const dev, dt_masks_form_t *const base, dt_masks_form_t *const dest)
Definition polygon.c:3500
static void _polygon_init_ctrl_points(dt_masks_form_t *mask_form)
Initialize control points to match a Catmull-Rom-like spline.
Definition polygon.c:193
static int _polygon_get_mask(const dt_iop_module_t *const module, dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *const piece, dt_masks_form_t *const mask_form, float **buffer, int *width, int *height, int *posx, int *posy)
Definition polygon.c:2439
static void _polygon_get_distance(float point_x, float point_y, float radius, dt_masks_form_gui_t *mask_gui, int form_index, int node_count, int *inside, int *inside_border, int *near, int *inside_source, float *dist)
Compute proximity between a point and the polygon GUI shape.
Definition polygon.c:1305
static void _polygon_draw_shape(cairo_t *cr, const float *point_buffer, const int point_count, const int node_count, const gboolean draw_border, const gboolean draw_source)
Draw a polygon or border polyline, skipping NaN points.
Definition polygon.c:2133
static int _polygon_get_points_border(dt_develop_t *develop, dt_masks_form_t *mask_form, float **point_buffer, int *point_count, float **border_buffer, int *border_count, int source, const dt_iop_module_t *module)
Definition polygon.c:1144
static void _polygon_sanitize_config(dt_masks_type_t type)
Definition polygon.c:3460
Definition masks.h:249

Referenced by _polygon_events_post_expose(), and dt_masks_create().