1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
|
/* SPDX-License-Identifier: GPL-2.0-or-later
* Copyright 2008 Blender Foundation. All rights reserved. */
/** \file
* \ingroup edsculpt
*/
#pragma once
#include "BKE_paint.h"
#include "BLI_compiler_compat.h"
#include "BLI_math.h"
#include "BLI_rect.h"
#include "DNA_scene_types.h"
#ifdef __cplusplus
extern "C" {
#endif
struct ARegion;
struct Brush;
struct ColorManagedDisplay;
struct ColorSpace;
struct ImagePool;
struct MTex;
struct Object;
struct Paint;
struct PaintStroke;
struct PointerRNA;
struct RegionView3D;
struct Scene;
struct VPaint;
struct ViewContext;
struct bContext;
struct wmEvent;
struct wmKeyConfig;
struct wmOperator;
struct wmOperatorType;
typedef struct CoNo {
float co[3];
float no[3];
} CoNo;
/* paint_stroke.c */
typedef bool (*StrokeGetLocation)(struct bContext *C, float location[3], const float mouse[2]);
typedef bool (*StrokeTestStart)(struct bContext *C, struct wmOperator *op, const float mouse[2]);
typedef void (*StrokeUpdateStep)(struct bContext *C,
struct PaintStroke *stroke,
struct PointerRNA *itemptr);
typedef void (*StrokeRedraw)(const struct bContext *C, struct PaintStroke *stroke, bool final);
typedef void (*StrokeDone)(const struct bContext *C, struct PaintStroke *stroke);
struct PaintStroke *paint_stroke_new(struct bContext *C,
struct wmOperator *op,
StrokeGetLocation get_location,
StrokeTestStart test_start,
StrokeUpdateStep update_step,
StrokeRedraw redraw,
StrokeDone done,
int event_type);
void paint_stroke_free(struct bContext *C, struct wmOperator *op, struct PaintStroke *stroke);
/**
* Returns zero if the stroke dots should not be spaced, non-zero otherwise.
*/
bool paint_space_stroke_enabled(struct Brush *br, enum ePaintMode mode);
/**
* Return true if the brush size can change during paint (normally used for pressure).
*/
bool paint_supports_dynamic_size(struct Brush *br, enum ePaintMode mode);
/**
* Return true if the brush size can change during paint (normally used for pressure).
*/
bool paint_supports_dynamic_tex_coords(struct Brush *br, enum ePaintMode mode);
bool paint_supports_smooth_stroke(struct Brush *br, enum ePaintMode mode);
bool paint_supports_texture(enum ePaintMode mode);
bool paint_supports_jitter(enum ePaintMode mode);
/**
* Called in paint_ops.c, on each regeneration of key-maps.
*/
struct wmKeyMap *paint_stroke_modal_keymap(struct wmKeyConfig *keyconf);
int paint_stroke_modal(struct bContext *C,
struct wmOperator *op,
const struct wmEvent *event,
struct PaintStroke *stroke);
int paint_stroke_exec(struct bContext *C, struct wmOperator *op, struct PaintStroke *stroke);
void paint_stroke_cancel(struct bContext *C, struct wmOperator *op, struct PaintStroke *stroke);
bool paint_stroke_flipped(struct PaintStroke *stroke);
bool paint_stroke_inverted(struct PaintStroke *stroke);
struct ViewContext *paint_stroke_view_context(struct PaintStroke *stroke);
void *paint_stroke_mode_data(struct PaintStroke *stroke);
float paint_stroke_distance_get(struct PaintStroke *stroke);
void paint_stroke_set_mode_data(struct PaintStroke *stroke, void *mode_data);
bool PAINT_brush_tool_poll(struct bContext *C);
void paint_cursor_start(struct Paint *p, bool (*poll)(struct bContext *C));
/**
* Delete overlay cursor textures to preserve memory and invalidate all overlay flags.
*/
void paint_cursor_delete_textures(void);
/* paint_vertex.c */
bool weight_paint_poll(struct bContext *C);
bool weight_paint_poll_ignore_tool(bContext *C);
bool weight_paint_mode_poll(struct bContext *C);
bool vertex_paint_poll(struct bContext *C);
bool vertex_paint_poll_ignore_tool(struct bContext *C);
/**
* Returns true if vertex paint mode is active.
*/
bool vertex_paint_mode_poll(struct bContext *C);
typedef void (*VPaintTransform_Callback)(const float col[3],
const void *user_data,
float r_col[3]);
void PAINT_OT_weight_paint_toggle(struct wmOperatorType *ot);
void PAINT_OT_weight_paint(struct wmOperatorType *ot);
void PAINT_OT_weight_set(struct wmOperatorType *ot);
enum {
WPAINT_GRADIENT_TYPE_LINEAR,
WPAINT_GRADIENT_TYPE_RADIAL,
};
void PAINT_OT_weight_gradient(struct wmOperatorType *ot);
void PAINT_OT_vertex_paint_toggle(struct wmOperatorType *ot);
void PAINT_OT_vertex_paint(struct wmOperatorType *ot);
unsigned int vpaint_get_current_col(struct Scene *scene, struct VPaint *vp, bool secondary);
/* paint_vertex_color_utils.c */
/**
* \note weight-paint has an equivalent function: #ED_wpaint_blend_tool
*/
unsigned int ED_vpaint_blend_tool(int tool, uint col, uint paintcol, int alpha_i);
/**
* Apply callback to each vertex of the active vertex color layer.
*/
bool ED_vpaint_color_transform(struct Object *ob,
VPaintTransform_Callback vpaint_tx_fn,
const void *user_data);
/* paint_vertex_weight_utils.c */
/**
* \param weight: Typically the current weight: #MDeformWeight.weight
*
* \return The final weight, note that this is _not_ clamped from [0-1].
* Clamping must be done on the final #MDeformWeight.weight
*
* \note vertex-paint has an equivalent function: #ED_vpaint_blend_tool
*/
float ED_wpaint_blend_tool(int tool, float weight, float paintval, float alpha);
/* Utility for tools to ensure vertex groups exist before they begin. */
enum eWPaintFlag {
WPAINT_ENSURE_MIRROR = (1 << 0),
};
struct WPaintVGroupIndex {
int active;
int mirror;
};
/**
* Ensure we have data on wpaint start, add if needed.
*/
bool ED_wpaint_ensure_data(struct bContext *C,
struct ReportList *reports,
enum eWPaintFlag flag,
struct WPaintVGroupIndex *vgroup_index);
/** Return -1 when invalid. */
int ED_wpaint_mirror_vgroup_ensure(struct Object *ob, int vgroup_active);
/* paint_vertex_color_ops.c */
void PAINT_OT_vertex_color_set(struct wmOperatorType *ot);
void PAINT_OT_vertex_color_from_weight(struct wmOperatorType *ot);
void PAINT_OT_vertex_color_smooth(struct wmOperatorType *ot);
void PAINT_OT_vertex_color_brightness_contrast(struct wmOperatorType *ot);
void PAINT_OT_vertex_color_hsv(struct wmOperatorType *ot);
void PAINT_OT_vertex_color_invert(struct wmOperatorType *ot);
void PAINT_OT_vertex_color_levels(struct wmOperatorType *ot);
/* paint_vertex_weight_ops.c */
void PAINT_OT_weight_from_bones(struct wmOperatorType *ot);
void PAINT_OT_weight_sample(struct wmOperatorType *ot);
void PAINT_OT_weight_sample_group(struct wmOperatorType *ot);
/* paint_vertex_proj.c */
struct VertProjHandle;
struct VertProjHandle *ED_vpaint_proj_handle_create(struct Depsgraph *depsgraph,
struct Scene *scene,
struct Object *ob,
struct CoNo **r_vcosnos);
void ED_vpaint_proj_handle_update(struct Depsgraph *depsgraph,
struct VertProjHandle *vp_handle,
/* runtime vars */
struct ARegion *region,
const float mval_fl[2]);
void ED_vpaint_proj_handle_free(struct VertProjHandle *vp_handle);
/* paint_image.c */
typedef struct ImagePaintPartialRedraw {
rcti dirty_region;
} ImagePaintPartialRedraw;
bool image_texture_paint_poll(struct bContext *C);
void imapaint_image_update(struct SpaceImage *sima,
struct Image *image,
struct ImBuf *ibuf,
struct ImageUser *iuser,
short texpaint);
struct ImagePaintPartialRedraw *get_imapaintpartial(void);
void set_imapaintpartial(struct ImagePaintPartialRedraw *ippr);
void imapaint_region_tiles(
struct ImBuf *ibuf, int x, int y, int w, int h, int *tx, int *ty, int *tw, int *th);
bool get_imapaint_zoom(struct bContext *C, float *zoomx, float *zoomy);
void *paint_2d_new_stroke(struct bContext *, struct wmOperator *, int mode);
void paint_2d_redraw(const struct bContext *C, void *ps, bool final);
void paint_2d_stroke_done(void *ps);
void paint_2d_stroke(void *ps,
const float prev_mval[2],
const float mval[2],
bool eraser,
float pressure,
float distance,
float size);
/**
* This function expects linear space color values.
*/
void paint_2d_bucket_fill(const struct bContext *C,
const float color[3],
struct Brush *br,
const float mouse_init[2],
const float mouse_final[2],
void *ps);
void paint_2d_gradient_fill(const struct bContext *C,
struct Brush *br,
const float mouse_init[2],
const float mouse_final[2],
void *ps);
void *paint_proj_new_stroke(struct bContext *C, struct Object *ob, const float mouse[2], int mode);
void paint_proj_stroke(const struct bContext *C,
void *ps_handle_p,
const float prev_pos[2],
const float pos[2],
bool eraser,
float pressure,
float distance,
float size);
void paint_proj_redraw(const struct bContext *C, void *ps_handle_p, bool final);
void paint_proj_stroke_done(void *ps_handle_p);
void paint_brush_color_get(struct Scene *scene,
struct Brush *br,
bool color_correction,
bool invert,
float distance,
float pressure,
float color[3],
struct ColorManagedDisplay *display);
bool paint_use_opacity_masking(struct Brush *brush);
void paint_brush_init_tex(struct Brush *brush);
void paint_brush_exit_tex(struct Brush *brush);
void PAINT_OT_grab_clone(struct wmOperatorType *ot);
void PAINT_OT_sample_color(struct wmOperatorType *ot);
void PAINT_OT_brush_colors_flip(struct wmOperatorType *ot);
void PAINT_OT_texture_paint_toggle(struct wmOperatorType *ot);
void PAINT_OT_project_image(struct wmOperatorType *ot);
void PAINT_OT_image_from_view(struct wmOperatorType *ot);
void PAINT_OT_add_texture_paint_slot(struct wmOperatorType *ot);
void PAINT_OT_image_paint(struct wmOperatorType *ot);
void PAINT_OT_add_simple_uvs(struct wmOperatorType *ot);
/* paint_image_2d_curve_mask.cc */
/**
* \brief Caching structure for curve mask.
*
* When 2d painting images the curve mask is used as an input.
*/
typedef struct CurveMaskCache {
/**
* \brief Last #CurveMapping.changed_timestamp being read.
*
* When different the input cache needs to be recalculated.
*/
int last_curve_timestamp;
/**
* \brief sampled version of the brush curve-mapping.
*/
float *sampled_curve;
/**
* \brief Size in bytes of the curve_mask field.
*
* Used to determine if the curve_mask needs to be re-allocated.
*/
size_t curve_mask_size;
/**
* \brief Curve mask that can be passed as curve_mask parameter when.
*/
ushort *curve_mask;
} CurveMaskCache;
void paint_curve_mask_cache_free_data(CurveMaskCache *curve_mask_cache);
void paint_curve_mask_cache_update(CurveMaskCache *curve_mask_cache,
const struct Brush *brush,
int diameter,
float radius,
const float cursor_position[2]);
/* sculpt_uv.c */
void SCULPT_OT_uv_sculpt_stroke(struct wmOperatorType *ot);
/* paint_utils.c */
/**
* Convert the object-space axis-aligned bounding box (expressed as
* its minimum and maximum corners) into a screen-space rectangle,
* returns zero if the result is empty.
*/
bool paint_convert_bb_to_rect(struct rcti *rect,
const float bb_min[3],
const float bb_max[3],
const struct ARegion *region,
struct RegionView3D *rv3d,
struct Object *ob);
/**
* Get four planes in object-space that describe the projection of
* screen_rect from screen into object-space (essentially converting a
* 2D screens-space bounding box into four 3D planes).
*/
void paint_calc_redraw_planes(float planes[4][4],
const struct ARegion *region,
struct Object *ob,
const struct rcti *screen_rect);
float paint_calc_object_space_radius(struct ViewContext *vc,
const float center[3],
float pixel_radius);
float paint_get_tex_pixel(
const struct MTex *mtex, float u, float v, struct ImagePool *pool, int thread);
void paint_get_tex_pixel_col(const struct MTex *mtex,
float u,
float v,
float rgba[4],
struct ImagePool *pool,
int thread,
bool convert,
struct ColorSpace *colorspace);
/**
* Used for both 3D view and image window.
*/
void paint_sample_color(
struct bContext *C, struct ARegion *region, int x, int y, bool texpaint_proj, bool palette);
void paint_stroke_operator_properties(struct wmOperatorType *ot);
void BRUSH_OT_curve_preset(struct wmOperatorType *ot);
void PAINT_OT_face_select_linked(struct wmOperatorType *ot);
void PAINT_OT_face_select_linked_pick(struct wmOperatorType *ot);
void PAINT_OT_face_select_all(struct wmOperatorType *ot);
void PAINT_OT_face_select_hide(struct wmOperatorType *ot);
void PAINT_OT_face_select_reveal(struct wmOperatorType *ot);
void PAINT_OT_vert_select_all(struct wmOperatorType *ot);
void PAINT_OT_vert_select_ungrouped(struct wmOperatorType *ot);
bool vert_paint_poll(struct bContext *C);
bool mask_paint_poll(struct bContext *C);
bool paint_curve_poll(struct bContext *C);
bool facemask_paint_poll(struct bContext *C);
/**
* Uses symm to selectively flip any axis of a coordinate.
*/
BLI_INLINE void flip_v3_v3(float out[3], const float in[3], const ePaintSymmetryFlags symm)
{
if (symm & PAINT_SYMM_X) {
out[0] = -in[0];
}
else {
out[0] = in[0];
}
if (symm & PAINT_SYMM_Y) {
out[1] = -in[1];
}
else {
out[1] = in[1];
}
if (symm & PAINT_SYMM_Z) {
out[2] = -in[2];
}
else {
out[2] = in[2];
}
}
BLI_INLINE void flip_qt_qt(float out[4], const float in[4], const ePaintSymmetryFlags symm)
{
float axis[3], angle;
quat_to_axis_angle(axis, &angle, in);
normalize_v3(axis);
if (symm & PAINT_SYMM_X) {
axis[0] *= -1.0f;
angle *= -1.0f;
}
if (symm & PAINT_SYMM_Y) {
axis[1] *= -1.0f;
angle *= -1.0f;
}
if (symm & PAINT_SYMM_Z) {
axis[2] *= -1.0f;
angle *= -1.0f;
}
axis_angle_normalized_to_quat(out, axis, angle);
}
BLI_INLINE void flip_v3(float v[3], const ePaintSymmetryFlags symm)
{
flip_v3_v3(v, v, symm);
}
BLI_INLINE void flip_qt(float quat[4], const ePaintSymmetryFlags symm)
{
flip_qt_qt(quat, quat, symm);
}
/* stroke operator */
typedef enum BrushStrokeMode {
BRUSH_STROKE_NORMAL,
BRUSH_STROKE_INVERT,
BRUSH_STROKE_SMOOTH,
} BrushStrokeMode;
/* paint_hide.c */
typedef enum {
PARTIALVIS_HIDE,
PARTIALVIS_SHOW,
} PartialVisAction;
typedef enum {
PARTIALVIS_INSIDE,
PARTIALVIS_OUTSIDE,
PARTIALVIS_ALL,
PARTIALVIS_MASKED,
} PartialVisArea;
void PAINT_OT_hide_show(struct wmOperatorType *ot);
/* paint_mask.c */
typedef enum {
PAINT_MASK_FLOOD_VALUE,
PAINT_MASK_FLOOD_VALUE_INVERSE,
PAINT_MASK_INVERT,
} PaintMaskFloodMode;
void PAINT_OT_mask_flood_fill(struct wmOperatorType *ot);
void PAINT_OT_mask_lasso_gesture(struct wmOperatorType *ot);
void PAINT_OT_mask_box_gesture(struct wmOperatorType *ot);
void PAINT_OT_mask_line_gesture(struct wmOperatorType *ot);
/* paint_curve.c */
void PAINTCURVE_OT_new(struct wmOperatorType *ot);
void PAINTCURVE_OT_add_point(struct wmOperatorType *ot);
void PAINTCURVE_OT_delete_point(struct wmOperatorType *ot);
void PAINTCURVE_OT_select(struct wmOperatorType *ot);
void PAINTCURVE_OT_slide(struct wmOperatorType *ot);
void PAINTCURVE_OT_draw(struct wmOperatorType *ot);
void PAINTCURVE_OT_cursor(struct wmOperatorType *ot);
/* image painting blur kernel */
typedef struct {
float *wdata; /* actual kernel */
int side; /* kernel side */
int side_squared; /* data side */
int pixel_len; /* pixels around center that kernel is wide */
} BlurKernel;
enum eBlurKernelType;
/**
* Paint blur kernels. Projective painting enforces use of a 2x2 kernel due to lagging.
* Can be extended to other blur kernels later,
*/
BlurKernel *paint_new_blur_kernel(struct Brush *br, bool proj);
void paint_delete_blur_kernel(BlurKernel *);
/* paint curve defines */
#define PAINT_CURVE_NUM_SEGMENTS 40
#ifdef __cplusplus
}
#endif
|