Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
brush.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 dependency graph for develop/masks/brush.c:

Go to the source code of this file.

Macros

#define HARDNESS_MIN   0.00001f
 
#define HARDNESS_MAX   1.0f
 
#define BORDER_MIN   0.00005f
 
#define BORDER_MAX   0.5f
 

Functions

static float _brush_point_line_distance2 (int point_index, int point_count, const float *point_buffer, const float *payload_buffer)
 Get squared distance of a point to the segment, including payload deltas.
 
static GList * _brush_ramer_douglas_peucker (const float *point_buffer, int point_count, const float *payload_buffer, float epsilon2)
 Remove unneeded points (Ramer-Douglas-Peucker) and return the reduced path.
 
static void _brush_get_XY (float p0_x, float p0_y, float p1_x, float p1_y, float p2_x, float p2_y, float p3_x, float p3_y, float t, float *out_x, float *out_y)
 Evaluate a cubic Bezier at t in [0, 1].
 
static void _brush_border_get_XY (float p0_x, float p0_y, float p1_x, float p1_y, float p2_x, float p2_y, float p3_x, float p3_y, float t, float radius, float *point_x, float *point_y, float *border_x, float *border_y)
 Evaluate a cubic Bezier and compute its offset border point.
 
static void _brush_ctrl2_to_handle (float point_x, float point_y, float ctrl_x, float ctrl_y, float *handle_x, float *handle_y, gboolean clockwise)
 Convert control point 2 into the handle position (orthonormal space).
 
static gboolean _brush_get_border_handle_resampled (const dt_masks_form_gui_points_t *gui_points, int node_count, int node_index, float *handle_x, float *handle_y)
 get the border handle position corresponding to a node, by looking for the closest border point in the resampled points of the form GUI.
 
static gboolean _brush_get_border_handle_mirrored (const dt_masks_form_gui_points_t *gui_points, int node_count, int node_index, float *handle_x, float *handle_y)
 
static void _brush_handle_to_ctrl (float ptx, float pty, float fx, float fy, float *ctrl1x, float *ctrl1y, float *ctrl2x, float *ctrl2y, gboolean clockwise)
 
static void _brush_catmull_to_bezier (float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4, float *bezier1_x, float *bezier1_y, float *bezier2_x, float *bezier2_y)
 Get Bezier control points that match a Catmull-Rom segment.
 
static void _brush_init_ctrl_points (dt_masks_form_t *mask_form)
 Initialize all control points to match a Catmull-Rom-like spline.
 
static void _brush_points_recurs_border_gaps (float *cmax, float *bmin, float *bmin2, float *bmax, dt_masks_dynbuf_t *dpoints, dt_masks_dynbuf_t *dborder, gboolean clockwise)
 
static void _brush_points_recurs_border_small_gaps (float *cmax, float *bmin, float *bmin2, float *bmax, dt_masks_dynbuf_t *dpoints, dt_masks_dynbuf_t *dborder)
 
static void _brush_points_stamp (float *cmax, float *bmin, dt_masks_dynbuf_t *dpoints, dt_masks_dynbuf_t *dborder, gboolean clockwise)
 
static gboolean _is_within_pxl_threshold (float *min, float *max, int pixel_threshold)
 
static void _brush_payload_sync (dt_masks_dynbuf_t *dpayload, dt_masks_dynbuf_t *dpoints, const float v0, const float v1)
 
static void _brush_points_recurs (float *p1, float *p2, double tmin, double tmax, float *points_min, float *points_max, float *border_min, float *border_max, float *rpoints, float *rborder, float *rpayload, dt_masks_dynbuf_t *dpoints, dt_masks_dynbuf_t *dborder, dt_masks_dynbuf_t *dpayload, const int pixel_threshold)
 
static int _brush_cyclic_cursor (int n, int nb)
 
static int _brush_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, float **payload_buffer, int *payload_count, int use_source)
 
static void _brush_get_distance (float point_x, float point_y, float radius, dt_masks_form_gui_t *mask_gui, int form_index, int corner_count, int *inside, int *inside_border, int *near, int *inside_source, float *distance)
 Get the distance between a point and the brush path/border.
 
static int _brush_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 use_source, const dt_iop_module_t *module)
 
static float _brush_get_position_in_segment (float point_x, float point_y, dt_masks_form_t *mask_form, int segment_index)
 
static gboolean _brush_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)
 Brush-specific border handle lookup.
 
static void _brush_curve_handle_cb (const dt_masks_form_gui_points_t *gui_points, int node_index, float *handle_x, float *handle_y, void *user_data)
 Brush-specific curve handle lookup.
 
static void _brush_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)
 Brush-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 int _init_hardness (dt_masks_form_t *mask_form, int parentid, dt_masks_form_gui_t *mask_gui, const float amount, const dt_masks_increment_t increment, const int flow)
 
static int _init_size (dt_masks_form_t *mask_form, int parentid, dt_masks_form_gui_t *mask_gui, const float amount, const dt_masks_increment_t increment, const int flow)
 
static int _init_opacity (dt_masks_form_t *mask_form, int parentid, dt_masks_form_gui_t *mask_gui, const float amount, const dt_masks_increment_t increment, const int flow)
 
static float _brush_get_interaction_value (const dt_masks_form_t *mask_form, dt_masks_interaction_t interaction)
 
static gboolean _brush_get_gravity_center (const dt_masks_form_t *mask_form, float center[2], float *area)
 
static int _change_hardness (dt_masks_form_t *mask_form, int parentid, dt_masks_form_gui_t *mask_gui, struct dt_iop_module_t *module, int index, const float amount, const dt_masks_increment_t increment, const int flow)
 
static int _change_size (dt_masks_form_t *mask_form, int parentid, dt_masks_form_gui_t *mask_gui, struct dt_iop_module_t *module, int index, const float amount, const dt_masks_increment_t increment, const int flow)
 
static float _brush_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 int _brush_events_mouse_scrolled (struct dt_iop_module_t *module, double widget_x, double widget_y, int scroll_up, const int flow, uint32_t state, dt_masks_form_t *mask_form, int parentid, dt_masks_form_gui_t *mask_gui, int index, dt_masks_interaction_t interaction)
 
static void _get_pressure_sensitivity (dt_masks_form_gui_t *mask_gui)
 
static void _add_node_to_segment (struct dt_iop_module_t *module, dt_masks_form_t *mask_form, int parentid, dt_masks_form_gui_t *mask_gui, int index)
 
static void _brush_translate_node (dt_masks_node_brush_t *node, const float delta_x, const float delta_y)
 
static void _brush_translate_all_nodes (dt_masks_form_t *mask_form, const float delta_x, const float delta_y)
 
static int _brush_events_button_pressed (struct dt_iop_module_t *module, double widget_x, double widget_y, double pressure, int which, int type, uint32_t state, dt_masks_form_t *mask_form, int parentid, dt_masks_form_gui_t *mask_gui, int index)
 
static float _get_brush_smoothing ()
 
static void _apply_pen_pressure (dt_masks_form_gui_t *mask_gui, float *payload_buffer)
 
static int _brush_events_button_released (struct dt_iop_module_t *module, double widget_x, double widget_y, int which, uint32_t state, dt_masks_form_t *mask_form, int parentid, dt_masks_form_gui_t *mask_gui, int index)
 
static int _brush_events_key_pressed (struct dt_iop_module_t *module, GdkEventKey *event, dt_masks_form_t *mask_form, int parentid, dt_masks_form_gui_t *mask_gui, int index)
 
static int _brush_events_mouse_moved (struct dt_iop_module_t *module, double widget_x, double widget_y, double pressure, int which, dt_masks_form_t *mask_form, int parentid, dt_masks_form_gui_t *mask_gui, int index)
 Brush mouse-move handler.
 
static void _brush_draw_shape (cairo_t *cr, const float *points, const int points_count, const int node_nb, const gboolean border, const gboolean source)
 
static float _brush_line_length (const float *line, const int first_pt, const int last_pt)
 
static gboolean _brush_line_point_at_length (const float *line, const int first_pt, const int last_pt, const float target_len, float *x, float *y)
 
static gboolean _brush_get_line_midpoint (const float *line, const int first_pt, const int last_pt, float *mx, float *my)
 
static gboolean _brush_get_source_center (const dt_masks_form_gui_points_t *gui_points, const int node_count, dt_masks_gui_center_point_t *center_pt)
 
static void _brush_events_post_expose (cairo_t *cr, float zoom_scale, dt_masks_form_gui_t *mask_gui, int index, int node_count)
 
static void _brush_bounding_box_raw (const float *const restrict points, const float *const restrict border, const int node_count, const int total_points, float *x_min, float *x_max, float *y_min, float *y_max)
 Compute the bounding box (min/max) for both brush centerline and border points.
 
static void _brush_bounding_box (const float *const points, const float *const border, const int node_count, const int total_points, int *width, int *height, int *offset_x, int *offset_y)
 Compute integer bounds used for buffer allocation.
 
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 *offset_x, int *offset_y, int include_source)
 Compute the minimal bounding box for a brush (optionally including the source path).
 
static int _brush_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 *offset_x, int *offset_y)
 
static int _brush_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 *offset_x, int *offset_y)
 
static void _brush_falloff (float *const restrict buffer, int segment_start[2], int segment_end[2], int offset_x, int offset_y, int buffer_width, float hardness, float density)
 
static int _brush_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 *offset_x, int *offset_y)
 Build a full-resolution brush mask into a newly allocated buffer.
 
static void _brush_falloff_roi (float *buffer, const int *segment_start, const int *segment_end, int buffer_width, int buffer_height, float hardness, float density)
 
static int _brush_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)
 Build a brush mask directly into an ROI-sized buffer.
 
static void _brush_sanitize_config (dt_masks_type_t type)
 
static void _brush_set_form_name (struct dt_masks_form_t *const mask_form, const size_t form_number)
 
static void _brush_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 _brush_duplicate_points (dt_develop_t *const dev, dt_masks_form_t *const base, dt_masks_form_t *const dest)
 
static void _brush_initial_source_pos (const float iwd, const float iht, float *x, float *y)
 
static void _brush_switch_node_callback (GtkWidget *widget, gpointer user_data)
 
static void _brush_reset_round_node_callback (GtkWidget *widget, gpointer user_data)
 
static void _brush_add_node_callback (GtkWidget *menu, gpointer user_data)
 
static int _brush_populate_context_menu (GtkWidget *menu, struct dt_masks_form_t *mask_form, struct dt_masks_form_gui_t *mask_gui, const float pointer_x, const float pointer_y)
 

Variables

const dt_masks_functions_t dt_masks_functions_brush
 

Macro Definition Documentation

◆ BORDER_MAX

#define BORDER_MAX   0.5f

Definition at line 53 of file develop/masks/brush.c.

◆ BORDER_MIN

#define BORDER_MIN   0.00005f

Definition at line 52 of file develop/masks/brush.c.

◆ HARDNESS_MAX

#define HARDNESS_MAX   1.0f

Definition at line 50 of file develop/masks/brush.c.

◆ HARDNESS_MIN

#define HARDNESS_MIN   0.00001f

Definition at line 49 of file develop/masks/brush.c.

Function Documentation

◆ _add_node_to_segment()

◆ _apply_pen_pressure()

◆ _brush_add_node_callback()

◆ _brush_border_get_XY()

static void _brush_border_get_XY ( float  p0_x,
float  p0_y,
float  p1_x,
float  p1_y,
float  p2_x,
float  p2_y,
float  p3_x,
float  p3_y,
float  t,
float  radius,
float *  point_x,
float *  point_y,
float *  border_x,
float *  border_y 
)
static

Evaluate a cubic Bezier and compute its offset border point.

Definition at line 212 of file develop/masks/brush.c.

References _brush_get_XY(), d, and t.

Referenced by _brush_get_pts_border(), and _brush_points_recurs().

◆ _brush_border_handle_cb()

static gboolean _brush_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

Brush-specific border handle lookup.

Uses mirrored border handles computed from resampled border points.

Definition at line 1289 of file develop/masks/brush.c.

References _brush_get_border_handle_mirrored().

Referenced by _find_closest_handle().

◆ _brush_bounding_box()

static void _brush_bounding_box ( const float *const  points,
const float *const  border,
const int  node_count,
const int  total_points,
int *  width,
int *  height,
int *  offset_x,
int *  offset_y 
)
static

Compute integer bounds used for buffer allocation.

Adds a 2-pixel padding on each side to avoid rounding gaps.

Definition at line 2624 of file develop/masks/brush.c.

References _brush_bounding_box_raw(), height, and width.

Referenced by _brush_get_mask(), and _get_area().

◆ _brush_bounding_box_raw()

static void _brush_bounding_box_raw ( const float *const restrict  points,
const float *const restrict  border,
const int  node_count,
const int  total_points,
float *  x_min,
float *  x_max,
float *  y_min,
float *  y_max 
)
static

Compute the bounding box (min/max) for both brush centerline and border points.

Assumes point arrays contain interleaved x/y coordinates and that indices before node_count * 3 are control points which should be ignored for bounds.

Definition at line 2588 of file develop/masks/brush.c.

References __OMP_PARALLEL_FOR__, MAX, max, MIN, and min.

Referenced by _brush_bounding_box(), and _brush_get_mask_roi().

◆ _brush_catmull_to_bezier()

static void _brush_catmull_to_bezier ( float  x1,
float  y1,
float  x2,
float  y2,
float  x3,
float  y3,
float  x4,
float  y4,
float *  bezier1_x,
float *  bezier1_y,
float *  bezier2_x,
float *  bezier2_y 
)
static

Get Bezier control points that match a Catmull-Rom segment.

Definition at line 351 of file develop/masks/brush.c.

Referenced by _brush_init_ctrl_points().

◆ _brush_ctrl2_to_handle()

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

Convert control point 2 into the handle position (orthonormal space).

Definition at line 244 of file develop/masks/brush.c.

Referenced by _brush_curve_handle_cb(), _brush_events_button_pressed(), and _brush_events_post_expose().

◆ _brush_curve_handle_cb()

static void _brush_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

Brush-specific curve handle lookup.

Converts the node's second control point into the GUI handle position.

Definition at line 1300 of file develop/masks/brush.c.

References _brush_ctrl2_to_handle(), dt_masks_form_gui_points_t::points, and TRUE.

Referenced by _find_closest_handle().

◆ _brush_cyclic_cursor()

static int _brush_cyclic_cursor ( int  n,
int  nb 
)
inlinestatic

converts n into a cyclical sequence counting upwards from 0 to nb-1 and back down again, counting endpoints twice

Definition at line 701 of file develop/masks/brush.c.

References n, and p.

Referenced by _brush_get_pts_border().

◆ _brush_distance_cb()

static void _brush_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

Brush-specific inside/border/segment hit testing.

Definition at line 1311 of file develop/masks/brush.c.

References _brush_get_distance(), and dist().

Referenced by _find_closest_handle().

◆ _brush_draw_shape()

static void _brush_draw_shape ( cairo_t *  cr,
const float *  points,
const int  points_count,
const int  node_nb,
const gboolean  border,
const gboolean  source 
)
static
Todo:
: Why not just avoid having NaN points in the array?

Definition at line 2129 of file develop/masks/brush.c.

References i.

◆ _brush_duplicate_points()

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

Definition at line 3098 of file develop/masks/brush.c.

References dt_masks_duplicate_points().

◆ _brush_events_button_pressed()

static int _brush_events_button_pressed ( struct dt_iop_module_t module,
double  widget_x,
double  widget_y,
double  pressure,
int  which,
int  type,
uint32_t  state,
dt_masks_form_t mask_form,
int  parentid,
dt_masks_form_gui_t mask_gui,
int  index 
)
static

◆ _brush_events_button_released()

◆ _brush_events_key_pressed()

static int _brush_events_key_pressed ( struct dt_iop_module_t module,
GdkEventKey *  event,
dt_masks_form_t mask_form,
int  parentid,
dt_masks_form_gui_t mask_gui,
int  index 
)
static

Definition at line 1959 of file develop/masks/brush.c.

◆ _brush_events_mouse_moved()

static int _brush_events_mouse_moved ( struct dt_iop_module_t module,
double  widget_x,
double  widget_y,
double  pressure,
int  which,
dt_masks_form_t mask_form,
int  parentid,
dt_masks_form_gui_t mask_gui,
int  index 
)
static

Brush 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.

Definition at line 1974 of file develop/masks/brush.c.

References _brush_get_border_handle_mirrored(), _brush_handle_to_ctrl(), _brush_init_ctrl_points(), _brush_translate_all_nodes(), _brush_translate_node(), dt_masks_node_brush_t::border, dt_masks_form_gui_t::creation, dt_masks_node_brush_t::ctrl1, dt_masks_node_brush_t::ctrl2, darktable, darktable_t::develop, dt_dev_coordinates_image_abs_to_raw_norm(), dt_masks_border_from_projected_handle(), DT_MASKS_CLONE, dt_masks_dynbuf_add_2(), dt_masks_dynbuf_get(), 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(), dt_masks_form_gui_t::guipoints, dt_masks_form_gui_t::guipoints_count, dt_masks_form_gui_t::guipoints_payload, dt_masks_form_gui_t::handle_border_dragging, dt_masks_form_gui_t::handle_dragging, IS_NULL_PTR, dt_masks_node_brush_t::node, dt_masks_form_gui_t::node_dragging, 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_brush_t::state, TRUE, and dt_masks_form_t::type.

◆ _brush_events_mouse_scrolled()

static int _brush_events_mouse_scrolled ( struct dt_iop_module_t module,
double  widget_x,
double  widget_y,
int  scroll_up,
const int  flow,
uint32_t  state,
dt_masks_form_t mask_form,
int  parentid,
dt_masks_form_gui_t mask_gui,
int  index,
dt_masks_interaction_t  interaction 
)
static

◆ _brush_events_post_expose()

static void _brush_events_post_expose ( cairo_t *  cr,
float  zoom_scale,
dt_masks_form_gui_t mask_gui,
int  index,
int  node_count 
)
static

Definition at line 2263 of file develop/masks/brush.c.

References _brush_ctrl2_to_handle(), _brush_get_border_handle_mirrored(), _brush_get_source_center(), dt_masks_form_gui_points_t::border, dt_masks_form_gui_points_t::border_count, BORDER_MAX, BORDER_MIN, dt_masks_form_gui_t::border_selected, dt_masks_form_gui_t::creation, darktable, darktable_t::develop, dt_masks_functions_t::draw_shape, dt_conf_get_float(), dt_draw_handle(), dt_draw_node(), dt_draw_set_dash_style(), dt_draw_shape_lines(), DT_DRAW_SIZE_LINE, dt_draw_stroke_line(), DT_GUI_COLOR_BRUSH_CURSOR, DT_GUI_COLOR_BRUSH_TRACE, dt_gui_gtk_set_source_rgba(), DT_MASKS_CLONE, DT_MASKS_DASH_ROUND, DT_MASKS_DASH_STICK, dt_masks_draw_path_seg_by_seg(), dt_masks_draw_source(), dt_masks_draw_source_preview(), dt_masks_dynbuf_buffer(), dt_masks_functions_brush, dt_masks_get_set_conf_value(), 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_gui_selected_segment_index(), DT_MASKS_INCREMENT_SCALE, DT_MASKS_NO_DASH, dt_masks_node_is_cusp(), DT_MASKS_PRESSURE_BRUSHSIZE_REL, DT_MASKS_PRESSURE_HARDNESS_ABS, DT_MASKS_PRESSURE_HARDNESS_REL, DT_MASKS_PRESSURE_OFF, DT_MASKS_PRESSURE_OPACITY_ABS, DT_MASKS_PRESSURE_OPACITY_REL, DT_PIXEL_APPLY_DPI, FALSE, dt_masks_form_gui_t::form_dragging, dt_masks_form_gui_t::form_selected, dt_masks_form_gui_t::group_selected, dt_masks_form_gui_t::guipoints, dt_masks_form_gui_t::guipoints_count, dt_masks_form_gui_t::guipoints_payload, dt_masks_form_gui_t::handle_border_hovered, dt_masks_form_gui_t::handle_border_selected, dt_masks_form_gui_t::handle_hovered, dt_masks_form_gui_t::handle_selected, HARDNESS_MAX, HARDNESS_MIN, i, IS_NULL_PTR, k, M_PI, MAX, MIN, n, dt_masks_form_gui_t::node_dragging, dt_masks_form_gui_t::node_hovered, dt_masks_form_gui_t::node_selected, 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_t::pressure_sensitivity, dt_develop_t::raw_height, dt_develop_t::raw_width, dt_develop_t::roi, dt_masks_form_gui_t::seg_selected, dt_masks_form_gui_points_t::source, dt_masks_form_gui_points_t::source_count, TRUE, dt_masks_form_t::type, and x.

◆ _brush_falloff()

static void _brush_falloff ( float *const restrict  buffer,
int  segment_start[2],
int  segment_end[2],
int  offset_x,
int  offset_y,
int  buffer_width,
float  hardness,
float  density 
)
static

we write a falloff segment

Definition at line 2688 of file develop/masks/brush.c.

References MAX, and x.

Referenced by _brush_get_mask().

◆ _brush_falloff_roi()

static void _brush_falloff_roi ( float *  buffer,
const int *  segment_start,
const int *  segment_end,
int  buffer_width,
int  buffer_height,
float  hardness,
float  density 
)
inlinestatic

we write a falloff segment respecting limits of buffer

Definition at line 2843 of file develop/masks/brush.c.

References MAX, and x.

Referenced by _brush_get_mask_roi().

◆ _brush_get_area()

static int _brush_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 *  offset_x,
int *  offset_y 
)
static

Definition at line 2679 of file develop/masks/brush.c.

References _get_area(), height, and width.

◆ _brush_get_border_handle_mirrored()

static gboolean _brush_get_border_handle_mirrored ( const dt_masks_form_gui_points_t gui_points,
int  node_count,
int  node_index,
float *  handle_x,
float *  handle_y 
)
static

◆ _brush_get_border_handle_resampled()

static gboolean _brush_get_border_handle_resampled ( const dt_masks_form_gui_points_t gui_points,
int  node_count,
int  node_index,
float *  handle_x,
float *  handle_y 
)
static

get the border handle position corresponding to a node, by looking for the closest border point in the resampled points of the form GUI.

This is used when we have to initialize control points for a node that has been set manually by the user, so we want to get the corresponding handle position to eventually match a catmull-rom like spline. The values should be in orthonormal space.

Parameters
gui_pointsthe form GUI points
node_countthe number of nodes in the form
node_indexthe index of the node for which we want to get the border handle position
xthe x coordinate of the border handle position (output)
ythe y coordinate of the border handle position (output)
Returns
gboolean TRUE if the border handle position has been successfully retrieved, FALSE otherwise

Definition at line 273 of file develop/masks/brush.c.

References dt_masks_form_gui_points_t::border, dt_masks_form_gui_points_t::border_count, FALSE, i, IS_NULL_PTR, MIN, dt_masks_form_gui_points_t::points, and dt_masks_form_gui_points_t::points_count.

Referenced by _brush_get_border_handle_mirrored().

◆ _brush_get_distance()

static void _brush_get_distance ( float  point_x,
float  point_y,
float  radius,
dt_masks_form_gui_t mask_gui,
int  form_index,
int  corner_count,
int *  inside,
int *  inside_border,
int *  near,
int *  inside_source,
float *  distance 
)
static

◆ _brush_get_gravity_center()

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

◆ _brush_get_interaction_value()

static float _brush_get_interaction_value ( const dt_masks_form_t mask_form,
dt_masks_interaction_t  interaction 
)
static

◆ _brush_get_line_midpoint()

static gboolean _brush_get_line_midpoint ( const float *  line,
const int  first_pt,
const int  last_pt,
float *  mx,
float *  my 
)
static

◆ _brush_get_mask()

static int _brush_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 *  offset_x,
int *  offset_y 
)
static

◆ _brush_get_mask_roi()

◆ _brush_get_points_border()

static int _brush_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  use_source,
const dt_iop_module_t module 
)
static

◆ _brush_get_position_in_segment()

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

find relative position within a brush segment that is closest to the point given by coordinates x and y; we only need to find the minimum with a resolution of 1%, so we just do an exhaustive search without any frills

Definition at line 1247 of file develop/masks/brush.c.

References _brush_get_XY(), g_list_next_bounded(), IS_NULL_PTR, dt_masks_node_brush_t::node, dt_masks_form_t::points, and t.

Referenced by _add_node_to_segment().

◆ _brush_get_pts_border()

static int _brush_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,
float **  payload_buffer,
int *  payload_count,
int  use_source 
)
static

◆ _brush_get_source_area()

static int _brush_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 *  offset_x,
int *  offset_y 
)
static

Definition at line 2672 of file develop/masks/brush.c.

References _get_area(), height, and width.

◆ _brush_get_source_center()

◆ _brush_get_XY()

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

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

Definition at line 197 of file develop/masks/brush.c.

References d, and t.

Referenced by _brush_border_get_XY(), and _brush_get_position_in_segment().

◆ _brush_handle_to_ctrl()

static void _brush_handle_to_ctrl ( float  ptx,
float  pty,
float  fx,
float  fy,
float *  ctrl1x,
float *  ctrl1y,
float *  ctrl2x,
float *  ctrl2y,
gboolean  clockwise 
)
static

get bezier control points from feather extremity the values should be in orthonormal space

Definition at line 328 of file develop/masks/brush.c.

References fx.

Referenced by _brush_events_mouse_moved().

◆ _brush_init_ctrl_points()

static void _brush_init_ctrl_points ( dt_masks_form_t mask_form)
static

◆ _brush_initial_source_pos()

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

◆ _brush_line_length()

static float _brush_line_length ( const float *  line,
const int  first_pt,
const int  last_pt 
)
static

Definition at line 2159 of file develop/masks/brush.c.

References i.

Referenced by _brush_get_line_midpoint().

◆ _brush_line_point_at_length()

static gboolean _brush_line_point_at_length ( const float *  line,
const int  first_pt,
const int  last_pt,
const float  target_len,
float *  x,
float *  y 
)
static

Definition at line 2179 of file develop/masks/brush.c.

References FALSE, i, IS_NULL_PTR, t, TRUE, and x.

Referenced by _brush_get_line_midpoint().

◆ _brush_payload_sync()

static void _brush_payload_sync ( dt_masks_dynbuf_t dpayload,
dt_masks_dynbuf_t dpoints,
const float  v0,
const float  v1 
)
inlinestatic

◆ _brush_point_line_distance2()

static float _brush_point_line_distance2 ( int  point_index,
int  point_count,
const float *  point_buffer,
const float *  payload_buffer 
)
static

Get squared distance of a point to the segment, including payload deltas.

Uses the first and last points as segment endpoints and adds weighted distance in border/hardness/density space to preserve brush dynamics.

Definition at line 61 of file develop/masks/brush.c.

References t.

Referenced by _brush_ramer_douglas_peucker().

◆ _brush_points_recurs()

static void _brush_points_recurs ( float *  p1,
float *  p2,
double  tmin,
double  tmax,
float *  points_min,
float *  points_max,
float *  border_min,
float *  border_max,
float *  rpoints,
float *  rborder,
float *  rpayload,
dt_masks_dynbuf_t dpoints,
dt_masks_dynbuf_t dborder,
dt_masks_dynbuf_t dpayload,
const int  pixel_threshold 
)
static

recursive function to get all points of the brush AND all point of the border the function takes care to avoid big gaps between points

Definition at line 623 of file develop/masks/brush.c.

References _brush_border_get_XY(), _brush_payload_sync(), _brush_points_recurs(), _brush_points_recurs_border_small_gaps(), _is_within_pxl_threshold(), dt_masks_dynbuf_add_2(), and IS_NULL_PTR.

Referenced by _brush_get_pts_border(), and _brush_points_recurs().

◆ _brush_points_recurs_border_gaps()

static void _brush_points_recurs_border_gaps ( float *  cmax,
float *  bmin,
float *  bmin2,
float *  bmax,
dt_masks_dynbuf_t dpoints,
dt_masks_dynbuf_t dborder,
gboolean  clockwise 
)
static

fill the gap between 2 points with an arc of circle this function is here because we can have gap in border, esp. if the corner is very sharp

Definition at line 444 of file develop/masks/brush.c.

References dt_masks_dynbuf_reserve_n(), i, IS_NULL_PTR, and M_PI.

Referenced by _brush_get_pts_border().

◆ _brush_points_recurs_border_small_gaps()

static void _brush_points_recurs_border_small_gaps ( float *  cmax,
float *  bmin,
float *  bmin2,
float *  bmax,
dt_masks_dynbuf_t dpoints,
dt_masks_dynbuf_t dborder 
)
static

fill small gap between 2 points with an arc of circle in contrast to the previous function it will always run the shortest path (max. PI) and does not consider clock or anti-clockwise action

Definition at line 510 of file develop/masks/brush.c.

References delta, dt_masks_dynbuf_reserve_n(), i, IS_NULL_PTR, and M_PI.

Referenced by _brush_points_recurs().

◆ _brush_points_stamp()

static void _brush_points_stamp ( float *  cmax,
float *  bmin,
dt_masks_dynbuf_t dpoints,
dt_masks_dynbuf_t dborder,
gboolean  clockwise 
)
static

draw a circle with given radius. can be used to terminate a stroke and to draw junctions where attributes (opacity) change

Definition at line 569 of file develop/masks/brush.c.

References dt_masks_dynbuf_reserve_n(), i, IS_NULL_PTR, and M_PI.

Referenced by _brush_get_pts_border().

◆ _brush_populate_context_menu()

◆ _brush_ramer_douglas_peucker()

static GList * _brush_ramer_douglas_peucker ( const float *  point_buffer,
int  point_count,
const float *  payload_buffer,
float  epsilon2 
)
static

◆ _brush_reset_round_node_callback()

◆ _brush_sanitize_config()

static void _brush_sanitize_config ( dt_masks_type_t  type)
static

Definition at line 3075 of file develop/masks/brush.c.

◆ _brush_set_form_name()

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

Definition at line 3080 of file develop/masks/brush.c.

References dt_masks_form_t::name.

◆ _brush_set_hint_message()

static void _brush_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

◆ _brush_set_interaction_value()

static float _brush_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

◆ _brush_switch_node_callback()

◆ _brush_translate_all_nodes()

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

Definition at line 1634 of file develop/masks/brush.c.

References _brush_translate_node(), and dt_masks_form_t::points.

Referenced by _brush_events_mouse_moved().

◆ _brush_translate_node()

static void _brush_translate_node ( dt_masks_node_brush_t node,
const float  delta_x,
const float  delta_y 
)
inlinestatic

◆ _change_hardness()

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

◆ _change_size()

static int _change_size ( dt_masks_form_t mask_form,
int  parentid,
dt_masks_form_gui_t mask_gui,
struct dt_iop_module_t module,
int  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 *  offset_x,
int *  offset_y,
int  include_source 
)
static

Compute the minimal bounding box for a brush (optionally including the source path).

Used by both ROI and full-frame paths to size temporary buffers.

Definition at line 2640 of file develop/masks/brush.c.

References _brush_bounding_box(), _brush_get_pts_border(), dt_iop_module_t::dev, DT_DEV_TRANSFORM_DIR_BACK_INCL, dt_pixelpipe_cache_free_align, height, dt_iop_module_t::iop_order, IS_NULL_PTR, dt_masks_form_t::points, and width.

Referenced by _brush_get_area(), and _brush_get_source_area().

◆ _get_brush_smoothing()

static float _get_brush_smoothing ( )
static

Definition at line 1791 of file develop/masks/brush.c.

References dt_conf_get_string_const(), and factor.

Referenced by _brush_events_button_released().

◆ _get_pressure_sensitivity()

◆ _init_hardness()

static int _init_hardness ( dt_masks_form_t mask_form,
int  parentid,
dt_masks_form_gui_t mask_gui,
const float  amount,
const dt_masks_increment_t  increment,
const int  flow 
)
static

◆ _init_opacity()

static int _init_opacity ( dt_masks_form_t mask_form,
int  parentid,
dt_masks_form_gui_t mask_gui,
const float  amount,
const dt_masks_increment_t  increment,
const int  flow 
)
static

◆ _init_size()

static int _init_size ( dt_masks_form_t mask_form,
int  parentid,
dt_masks_form_gui_t mask_gui,
const float  amount,
const dt_masks_increment_t  increment,
const int  flow 
)
static

◆ _is_within_pxl_threshold()

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

Definition at line 603 of file develop/masks/brush.c.

References max, and min.

Referenced by _brush_points_recurs().

Variable Documentation

◆ dt_masks_functions_brush

const dt_masks_functions_t dt_masks_functions_brush
Initial value:
= {
.point_struct_size = sizeof(struct dt_masks_node_brush_t),
.sanitize_config = _brush_sanitize_config,
.set_form_name = _brush_set_form_name,
.set_hint_message = _brush_set_hint_message,
.duplicate_points = _brush_duplicate_points,
.initial_source_pos = _brush_initial_source_pos,
.get_distance = _brush_get_distance,
.get_points_border = _brush_get_points_border,
.get_mask = _brush_get_mask,
.get_mask_roi = _brush_get_mask_roi,
.get_area = _brush_get_area,
.get_source_area = _brush_get_source_area,
.get_gravity_center = _brush_get_gravity_center,
.get_interaction_value = _brush_get_interaction_value,
.set_interaction_value = _brush_set_interaction_value,
.update_hover = _find_closest_handle,
.mouse_moved = _brush_events_mouse_moved,
.mouse_scrolled = _brush_events_mouse_scrolled,
.button_pressed = _brush_events_button_pressed,
.button_released = _brush_events_button_released,
.key_pressed = _brush_events_key_pressed,
.post_expose = _brush_events_post_expose,
.draw_shape = _brush_draw_shape,
.init_ctrl_points = _brush_init_ctrl_points,
.populate_context_menu = _brush_populate_context_menu
}
static void _brush_initial_source_pos(const float iwd, const float iht, float *x, float *y)
static int _brush_populate_context_menu(GtkWidget *menu, struct dt_masks_form_t *mask_form, struct dt_masks_form_gui_t *mask_gui, const float pointer_x, const float pointer_y)
static int _find_closest_handle(dt_masks_form_t *mask_form, dt_masks_form_gui_t *mask_gui, int form_index)
static float _brush_get_interaction_value(const dt_masks_form_t *mask_form, dt_masks_interaction_t interaction)
static int _brush_events_button_released(struct dt_iop_module_t *module, double widget_x, double widget_y, int which, uint32_t state, dt_masks_form_t *mask_form, int parentid, dt_masks_form_gui_t *mask_gui, int index)
static int _brush_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 use_source, const dt_iop_module_t *module)
static float _brush_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 int _brush_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 *offset_x, int *offset_y)
static int _brush_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)
Build a brush mask directly into an ROI-sized buffer.
static int _brush_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 *offset_x, int *offset_y)
Build a full-resolution brush mask into a newly allocated buffer.
static void _brush_draw_shape(cairo_t *cr, const float *points, const int points_count, const int node_nb, const gboolean border, const gboolean source)
static int _brush_events_mouse_moved(struct dt_iop_module_t *module, double widget_x, double widget_y, double pressure, int which, dt_masks_form_t *mask_form, int parentid, dt_masks_form_gui_t *mask_gui, int index)
Brush mouse-move handler.
static int _brush_events_mouse_scrolled(struct dt_iop_module_t *module, double widget_x, double widget_y, int scroll_up, const int flow, uint32_t state, dt_masks_form_t *mask_form, int parentid, dt_masks_form_gui_t *mask_gui, int index, dt_masks_interaction_t interaction)
static int _brush_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 *offset_x, int *offset_y)
static void _brush_set_form_name(struct dt_masks_form_t *const mask_form, const size_t form_number)
static void _brush_events_post_expose(cairo_t *cr, float zoom_scale, dt_masks_form_gui_t *mask_gui, int index, int node_count)
static int _brush_events_button_pressed(struct dt_iop_module_t *module, double widget_x, double widget_y, double pressure, int which, int type, uint32_t state, dt_masks_form_t *mask_form, int parentid, dt_masks_form_gui_t *mask_gui, int index)
static void _brush_get_distance(float point_x, float point_y, float radius, dt_masks_form_gui_t *mask_gui, int form_index, int corner_count, int *inside, int *inside_border, int *near, int *inside_source, float *distance)
Get the distance between a point and the brush path/border.
static void _brush_init_ctrl_points(dt_masks_form_t *mask_form)
Initialize all control points to match a Catmull-Rom-like spline.
static int _brush_events_key_pressed(struct dt_iop_module_t *module, GdkEventKey *event, dt_masks_form_t *mask_form, int parentid, dt_masks_form_gui_t *mask_gui, int index)
static void _brush_sanitize_config(dt_masks_type_t type)
static void _brush_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 gboolean _brush_get_gravity_center(const dt_masks_form_t *mask_form, float center[2], float *area)
static void _brush_duplicate_points(dt_develop_t *const dev, dt_masks_form_t *const base, dt_masks_form_t *const dest)

Definition at line 3234 of file develop/masks/brush.c.

Referenced by _brush_events_post_expose(), and dt_masks_create().