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:

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, 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_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, 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, 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, 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

◆ BORDER_MIN

#define BORDER_MIN   0.00005f

◆ HARDNESS_MAX

#define HARDNESS_MAX   1.0f

◆ HARDNESS_MIN

#define HARDNESS_MIN   0.00001f

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.

References _brush_get_XY(), a, b, c, d, sqf(), 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.

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.

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.

References MAX, 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.

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

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.

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

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.

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?

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

◆ _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

◆ _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.

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, 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()

◆ _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

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, 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

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

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,
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

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

References dt_masks_form_gui_points_t::border, dt_masks_form_gui_points_t::border_count, FALSE, i, 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()

◆ _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,
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()

static int _brush_get_mask_roi ( const dt_iop_module_t *const  module,
const dt_dev_pixelpipe_iop_t *const  piece,
dt_masks_form_t *const  mask_form,
const dt_iop_roi_t roi,
float *  buffer 
)
static

◆ _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

References _brush_get_XY(), g_list_next_bounded(), 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_iop_t piece,
dt_masks_form_t mask_form,
int *  width,
int *  height,
int *  offset_x,
int *  offset_y 
)
static

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

References a, b, c, d, sqf(), 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

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

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

References FALSE, i, 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.

References dot(), sqf(), and 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

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

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

References dt_masks_dynbuf_reserve_n(), i, 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

References delta, dt_masks_dynbuf_reserve_n(), i, 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

References dt_masks_dynbuf_reserve_n(), i, 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

◆ _brush_set_form_name()

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

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

◆ _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()

◆ _change_size()

◆ _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,
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.

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, dt_dev_pixelpipe_iop_t::pipe, 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

◆ _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

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)
Definition develop/masks/brush.c:3107
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)
Definition develop/masks/brush.c:3187
static int _find_closest_handle(dt_masks_form_t *mask_form, dt_masks_form_gui_t *mask_gui, int form_index)
Definition develop/masks/brush.c:1323
static float _brush_get_interaction_value(const dt_masks_form_t *mask_form, dt_masks_interaction_t interaction)
Definition develop/masks/brush.c:1361
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)
Definition develop/masks/brush.c:1842
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)
Definition develop/masks/brush.c:1236
static int _brush_get_area(const dt_iop_module_t *const module, 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)
Definition develop/masks/brush.c:2681
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)
Definition develop/masks/brush.c:1425
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)
Definition develop/masks/brush.c:2134
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.
Definition develop/masks/brush.c:1979
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)
Definition develop/masks/brush.c:1521
static void _brush_set_form_name(struct dt_masks_form_t *const mask_form, const size_t form_number)
Definition develop/masks/brush.c:3083
static int _brush_get_source_area(dt_iop_module_t *module, dt_dev_pixelpipe_iop_t *piece, dt_masks_form_t *mask_form, int *width, int *height, int *offset_x, int *offset_y)
Definition develop/masks/brush.c:2675
static void _brush_events_post_expose(cairo_t *cr, float zoom_scale, dt_masks_form_gui_t *mask_gui, int index, int node_count)
Definition develop/masks/brush.c:2268
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)
Definition develop/masks/brush.c:1644
static int _brush_get_mask_roi(const dt_iop_module_t *const module, 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.
Definition develop/masks/brush.c:2903
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.
Definition develop/masks/brush.c:1104
static void _brush_init_ctrl_points(dt_masks_form_t *mask_form)
Initialize all control points to match a Catmull-Rom-like spline.
Definition develop/masks/brush.c:366
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)
Definition develop/masks/brush.c:1964
static void _brush_sanitize_config(dt_masks_type_t type)
Definition develop/masks/brush.c:3078
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)
Definition develop/masks/brush.c:3088
static gboolean _brush_get_gravity_center(const dt_masks_form_t *mask_form, float center[2], float *area)
Definition develop/masks/brush.c:1393
static void _brush_duplicate_points(dt_develop_t *const dev, dt_masks_form_t *const base, dt_masks_form_t *const dest)
Definition develop/masks/brush.c:3101
static int _brush_get_mask(const dt_iop_module_t *const module, 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.
Definition develop/masks/brush.c:2724
Definition masks.h:259

Referenced by _brush_events_post_expose(), and dt_masks_create().