Blender V5.0
paint_image_ops_paint.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9
10#include "DNA_brush_types.h"
11#include "DNA_scene_types.h"
12#include "DNA_space_types.h"
13
14#include "BLI_math_color.h"
15#include "BLI_math_vector.h"
16
17#include "BKE_brush.hh"
18#include "BKE_colortools.hh"
19#include "BKE_context.hh"
20#include "BKE_layer.hh"
21#include "BKE_paint.hh"
22#include "BKE_paint_types.hh"
23#include "BKE_undo_system.hh"
24
25#include "ED_paint.hh"
26#include "ED_view3d.hh"
27
28#include "GPU_immediate.hh"
29#include "GPU_state.hh"
30
31#include "MEM_guardedalloc.h"
32
33#include "RNA_access.hh"
34
35#include "WM_api.hh"
36#include "WM_types.hh"
37
38#include "ED_image.hh"
39
40#include "paint_intern.hh"
41
43
49 public:
50 virtual ~AbstractPaintMode() = default;
51 virtual void *paint_new_stroke(
52 bContext *C, wmOperator *op, Object *ob, const float mouse[2], int mode) = 0;
53 virtual void paint_stroke(bContext *C,
54 void *stroke_handle,
55 float prev_mouse[2],
56 float mouse[2],
57 int eraser,
58 float pressure,
59 float distance,
60 float size) = 0;
61
62 virtual void paint_stroke_redraw(const bContext *C, void *stroke_handle, bool final) = 0;
63 virtual void paint_stroke_done(void *stroke_handle) = 0;
64 virtual void paint_gradient_fill(const bContext *C,
65 const Paint *paint,
66 Brush *brush,
67 PaintStroke *stroke,
68 void *stroke_handle,
69 float mouse_start[2],
70 float mouse_end[2]) = 0;
71 virtual void paint_bucket_fill(const bContext *C,
72 const Paint *paint,
73 Brush *brush,
74 PaintStroke *stroke,
75 void *stroke_handle,
76 float mouse_start[2],
77 float mouse_end[2]) = 0;
78};
79
81 public:
83 bContext *C, wmOperator *op, Object * /*ob*/, const float /*mouse*/[2], int mode) override
84 {
85 return paint_2d_new_stroke(C, op, mode);
86 }
87
88 void paint_stroke(bContext * /*C*/,
89 void *stroke_handle,
90 float prev_mouse[2],
91 float mouse[2],
92 int eraser,
93 float pressure,
94 float distance,
95 float size) override
96 {
97 paint_2d_stroke(stroke_handle, prev_mouse, mouse, eraser, pressure, distance, size);
98 }
99
100 void paint_stroke_redraw(const bContext *C, void *stroke_handle, bool final) override
101 {
102 paint_2d_redraw(C, stroke_handle, final);
103 }
104
105 void paint_stroke_done(void *stroke_handle) override
106 {
107 paint_2d_stroke_done(stroke_handle);
108 }
109
111 const Paint * /*paint*/,
112 Brush *brush,
113 PaintStroke * /*stroke*/,
114 void *stroke_handle,
115 float mouse_start[2],
116 float mouse_end[2]) override
117 {
118 paint_2d_gradient_fill(C, brush, mouse_start, mouse_end, stroke_handle);
119 }
120
122 const Paint *paint,
123 Brush *brush,
124 PaintStroke *stroke,
125 void *stroke_handle,
126 float mouse_start[2],
127 float mouse_end[2]) override
128 {
129 float color[3];
130 if (paint_stroke_inverted(stroke)) {
132 }
133 else {
135 }
136 paint_2d_bucket_fill(C, color, brush, mouse_start, mouse_end, stroke_handle);
137 }
138};
139
141 public:
143 bContext *C, wmOperator * /*op*/, Object *ob, const float mouse[2], int mode) override
144 {
145 return paint_proj_new_stroke(C, ob, mouse, mode);
146 }
147
149 void *stroke_handle,
150 float prev_mouse[2],
151 float mouse[2],
152 int eraser,
153 float pressure,
154 float distance,
155 float size) override
156 {
157 paint_proj_stroke(C, stroke_handle, prev_mouse, mouse, eraser, pressure, distance, size);
158 };
159
160 void paint_stroke_redraw(const bContext *C, void *stroke_handle, bool final) override
161 {
162 paint_proj_redraw(C, stroke_handle, final);
163 }
164
165 void paint_stroke_done(void *stroke_handle) override
166 {
167 paint_proj_stroke_done(stroke_handle);
168 }
169
171 const Paint *paint,
172 Brush *brush,
173 PaintStroke *stroke,
174 void *stroke_handle,
175 float mouse_start[2],
176 float mouse_end[2]) override
177 {
178 paint_fill(C, paint, brush, stroke, stroke_handle, mouse_start, mouse_end);
179 }
180
182 const Paint *paint,
183 Brush *brush,
184 PaintStroke *stroke,
185 void *stroke_handle,
186 float mouse_start[2],
187 float mouse_end[2]) override
188 {
189 paint_fill(C, paint, brush, stroke, stroke_handle, mouse_start, mouse_end);
190 }
191
192 private:
193 void paint_fill(const bContext *C,
194 const Paint *paint,
195 Brush *brush,
196 PaintStroke *stroke,
197 void *stroke_handle,
198 float mouse_start[2],
199 float mouse_end[2])
200 {
202 stroke_handle,
203 mouse_start,
204 mouse_end,
205 paint_stroke_flipped(stroke),
206 1.0,
207 0.0,
209 /* two redraws, one for GPU update, one for notification */
210 paint_proj_redraw(C, stroke_handle, false);
211 paint_proj_redraw(C, stroke_handle, true);
212 }
213};
214
217
218 void *stroke_handle = nullptr;
219
220 float prevmouse[2] = {0.0f, 0.0f};
221 float startmouse[2] = {0.0f, 0.0f};
222 double starttime = 0.0;
223
225 ViewContext vc = {nullptr};
226
227 PaintOperation() = default;
229 {
230 MEM_delete(mode);
231 mode = nullptr;
232
233 if (cursor) {
235 cursor = nullptr;
236 }
237 }
238};
239
240static void gradient_draw_line(bContext * /*C*/,
241 const blender::int2 &xy,
242 const blender::float2 & /*tilt*/,
243 void *customdata)
244{
245 PaintOperation *pop = (PaintOperation *)customdata;
246
247 if (pop) {
248 GPU_line_smooth(true);
250
252 uint pos = GPU_vertformat_attr_add(format, "pos", blender::gpu::VertAttrType::SFLOAT_32_32);
253
254 ARegion *region = pop->vc.region;
255
257
258 GPU_line_width(4.0);
259 immUniformColor4ub(0, 0, 0, 255);
260
264 pos, pop->startmouse[0] + region->winrct.xmin, pop->startmouse[1] + region->winrct.ymin);
265 immEnd();
266
267 GPU_line_width(2.0);
268 immUniformColor4ub(255, 255, 255, 255);
269
273 pos, pop->startmouse[0] + region->winrct.xmin, pop->startmouse[1] + region->winrct.ymin);
274 immEnd();
275
277
279 GPU_line_smooth(false);
280 }
281}
282
283static std::unique_ptr<PaintOperation> texture_paint_init(bContext *C,
284 wmOperator *op,
285 const float mouse[2])
286{
288 Scene *scene = CTX_data_scene(C);
289 ToolSettings *settings = scene->toolsettings;
290 std::unique_ptr<PaintOperation> pop = std::make_unique<PaintOperation>();
291 Brush *brush = BKE_paint_brush(&settings->imapaint.paint);
292 int mode = RNA_enum_get(op->ptr, "mode");
294
295 copy_v2_v2(pop->prevmouse, mouse);
296 copy_v2_v2(pop->startmouse, mouse);
297
298 ViewLayer *view_layer = CTX_data_view_layer(C);
299 BKE_view_layer_synced_ensure(scene, view_layer);
301
302 /* initialize from context */
303 if (CTX_wm_region_view3d(C)) {
304 bool uvs, mat, tex, stencil;
305 if (!ED_paint_proj_mesh_data_check(*scene, *ob, &uvs, &mat, &tex, &stencil)) {
306 ED_paint_data_warning(op->reports, uvs, mat, tex, stencil);
308 return nullptr;
309 }
310 pop->mode = MEM_new<ProjectionPaintMode>("ProjectionPaintMode");
311 }
312 else {
313 pop->mode = MEM_new<ImagePaintMode>("ImagePaintMode");
314 }
315
316 pop->stroke_handle = pop->mode->paint_new_stroke(C, op, ob, mouse, mode);
317 if (!pop->stroke_handle) {
318 return nullptr;
319 }
320
322 (brush->flag & BRUSH_USE_GRADIENT))
323 {
324 pop->cursor = WM_paint_cursor_activate(
326 }
327
328 settings->imapaint.flag |= IMAGEPAINT_DRAWING;
330
331 return pop;
332}
333
335 wmOperator *op,
336 PaintStroke *stroke,
337 PointerRNA *itemptr)
338{
339 PaintOperation *pop = static_cast<PaintOperation *>(paint_stroke_mode_data(stroke));
341 bke::PaintRuntime *paint_runtime = paint->runtime;
342 Brush *brush = BKE_paint_brush(paint);
343
344 float alphafac = (brush->flag & BRUSH_ACCUMULATE) ? paint_runtime->overlap_factor : 1.0f;
345
346 /* initial brush values. Maybe it should be considered moving these to stroke system */
347 float startalpha = BKE_brush_alpha_get(paint, brush);
348
349 float mouse[2];
350 float pressure;
351 float size;
352 float distance = paint_stroke_distance_get(stroke);
353 int eraser;
354
355 RNA_float_get_array(itemptr, "mouse", mouse);
356 pressure = RNA_float_get(itemptr, "pressure");
357 eraser = RNA_boolean_get(op->ptr, "pen_flip");
358 size = RNA_float_get(itemptr, "size");
359
360 /* stroking with fill tool only acts on stroke end */
362 copy_v2_v2(pop->prevmouse, mouse);
363 return;
364 }
365
366 if (BKE_brush_use_alpha_pressure(brush)) {
367 pressure = BKE_curvemapping_evaluateF(brush->curve_strength, 0, pressure);
368 BKE_brush_alpha_set(paint, brush, max_ff(0.0f, startalpha * pressure * alphafac));
369 }
370 else {
371 BKE_brush_alpha_set(paint, brush, max_ff(0.0f, startalpha * alphafac));
372 }
373
374 if ((brush->flag & BRUSH_DRAG_DOT) || (brush->flag & BRUSH_ANCHORED)) {
375 UndoStack *ustack = CTX_wm_manager(C)->runtime->undo_stack;
377 }
378
379 pop->mode->paint_stroke(
380 C, pop->stroke_handle, pop->prevmouse, mouse, eraser, pressure, distance, size);
381
382 copy_v2_v2(pop->prevmouse, mouse);
383
384 /* restore brush values */
385 BKE_brush_alpha_set(paint, brush, startalpha);
386}
387
388static void paint_stroke_redraw(const bContext *C, PaintStroke *stroke, bool final)
389{
390 PaintOperation *pop = static_cast<PaintOperation *>(paint_stroke_mode_data(stroke));
391 pop->mode->paint_stroke_redraw(C, pop->stroke_handle, final);
392}
393
394static void paint_stroke_done(const bContext *C, PaintStroke *stroke)
395{
396 Scene *scene = CTX_data_scene(C);
397 ToolSettings *toolsettings = scene->toolsettings;
398 PaintOperation *pop = static_cast<PaintOperation *>(paint_stroke_mode_data(stroke));
400 Brush *brush = BKE_paint_brush(&toolsettings->imapaint.paint);
401
402 toolsettings->imapaint.flag &= ~IMAGEPAINT_DRAWING;
403
405 if (brush->flag & BRUSH_USE_GRADIENT) {
407 C, paint, brush, stroke, pop->stroke_handle, pop->startmouse, pop->prevmouse);
408 }
409 else {
411 C, paint, brush, stroke, pop->stroke_handle, pop->startmouse, pop->prevmouse);
412 }
413 }
415 pop->stroke_handle = nullptr;
416
418
419/* duplicate warning, see texpaint_init */
420#if 0
421 if (pop->s.warnmultifile) {
422 BKE_reportf(op->reports,
424 "Image requires 4 color channels to paint: %s",
425 pop->s.warnmultifile);
426 }
427 if (pop->s.warnpackedfile) {
428 BKE_reportf(op->reports,
430 "Packed MultiLayer files cannot be painted: %s",
431 pop->s.warnpackedfile);
432 }
433#endif
434}
435
436static bool paint_stroke_test_start(bContext *C, wmOperator *op, const float mouse[2])
437{
438 std::unique_ptr<PaintOperation> pop;
439
440 /* TODO: Should avoid putting this here. Instead, last position should be requested
441 * from stroke system. */
442
443 if (!(pop = texture_paint_init(C, op, mouse))) {
444 return false;
445 }
446
447 paint_stroke_set_mode_data(static_cast<PaintStroke *>(op->customdata), std::move(pop));
448
449 return true;
450}
451
453{
455 op,
456 nullptr,
461 event->type);
462
463 const wmOperatorStatus retval = op->type->modal(C, op, event);
464 OPERATOR_RETVAL_CHECK(retval);
465
466 if (retval == OPERATOR_FINISHED) {
467 paint_stroke_free(C, op, static_cast<PaintStroke *>(op->customdata));
468 return OPERATOR_FINISHED;
469 }
470 /* add modal handler */
472
474
476}
477
479{
480 PropertyRNA *strokeprop;
481 PointerRNA firstpoint;
482 float mouse[2];
483
484 strokeprop = RNA_struct_find_property(op->ptr, "stroke");
485
486 if (!RNA_property_collection_lookup_int(op->ptr, strokeprop, 0, &firstpoint)) {
487 return OPERATOR_CANCELLED;
488 }
489
490 RNA_float_get_array(&firstpoint, "mouse", mouse);
491
493 op,
494 nullptr,
499 0);
500 op->customdata = stroke;
501
502 /* Make sure we have proper coordinates for sampling (mask) textures -- these get stored in
503 * #UnifiedPaintSettings -- as well as support randomness and jitter. */
506 const Brush &brush = *BKE_paint_brush_for_read(&paint);
507 float pressure;
508 pressure = RNA_float_get(&firstpoint, "pressure");
509 float mouse_out[2];
510 bool dummy;
511 float dummy_location[3];
512
513 paint_stroke_jitter_pos(*stroke, mode, brush, pressure, mouse, mouse_out);
514 paint_brush_update(C, brush, mode, stroke, mouse, mouse_out, pressure, dummy_location, &dummy);
515
516 /* frees op->customdata */
517 return paint_stroke_exec(C, op, static_cast<PaintStroke *>(op->customdata));
518}
519
521{
522 return paint_stroke_modal(C, op, event, reinterpret_cast<PaintStroke **>(&op->customdata));
523}
524
526{
527 paint_stroke_cancel(C, op, static_cast<PaintStroke *>(op->customdata));
528}
529} // namespace blender::ed::sculpt_paint::image::ops::paint
530
532{
534
535 /* identifiers */
536 ot->name = "Image Paint";
537 ot->idname = "PAINT_OT_image_paint";
538 ot->description = "Paint a stroke into the image";
539
540 /* API callbacks. */
541 ot->invoke = paint_invoke;
542 ot->modal = paint_modal;
543 ot->exec = paint_exec;
545 ot->cancel = paint_cancel;
546
547 /* flags */
548 ot->flag = OPTYPE_BLOCKING;
549
551}
bool BKE_brush_use_alpha_pressure(const Brush *brush)
Definition brush.cc:1290
float BKE_brush_alpha_get(const Paint *paint, const Brush *brush)
Definition brush.cc:1357
const float * BKE_brush_color_get(const Paint *paint, const Brush *brush)
Definition brush.cc:1161
const float * BKE_brush_secondary_color_get(const Paint *paint, const Brush *brush)
Definition brush.cc:1205
float BKE_brush_radius_get(const Paint *paint, const Brush *brush)
Definition brush.cc:1272
void BKE_brush_alpha_set(Paint *paint, Brush *brush, float alpha)
Definition brush.cc:1344
float BKE_curvemapping_evaluateF(const CurveMapping *cumap, int cur, float value)
Depsgraph * CTX_data_ensure_evaluated_depsgraph(const bContext *C)
Scene * CTX_data_scene(const bContext *C)
RegionView3D * CTX_wm_region_view3d(const bContext *C)
wmWindowManager * CTX_wm_manager(const bContext *C)
ViewLayer * CTX_data_view_layer(const bContext *C)
void BKE_view_layer_synced_ensure(const Scene *scene, ViewLayer *view_layer)
Object * BKE_view_layer_active_object_get(const ViewLayer *view_layer)
const Brush * BKE_paint_brush_for_read(const Paint *paint)
Definition paint.cc:650
Paint * BKE_paint_get_active_from_context(const bContext *C)
Definition paint.cc:476
Brush * BKE_paint_brush(Paint *paint)
Definition paint.cc:645
PaintMode BKE_paintmode_get_active_from_context(const bContext *C)
Definition paint.cc:505
PaintMode
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
@ RPT_WARNING
Definition BKE_report.hh:38
#define BLI_assert(a)
Definition BLI_assert.h:46
MINLINE float max_ff(float a, float b)
MINLINE void copy_v2_v2(float r[2], const float a[2])
MINLINE void copy_v3_v3(float r[3], const float a[3])
unsigned int uint
@ BRUSH_DRAG_DOT
@ BRUSH_ACCUMULATE
@ BRUSH_ANCHORED
@ BRUSH_USE_GRADIENT
@ IMAGE_PAINT_BRUSH_TYPE_FILL
@ IMAGEPAINT_DRAWING
#define RGN_TYPE_ANY
#define SPACE_TYPE_ANY
@ OPERATOR_CANCELLED
@ OPERATOR_FINISHED
@ OPERATOR_RUNNING_MODAL
#define OPERATOR_RETVAL_CHECK(ret)
bool ED_image_tools_paint_poll(bContext *C)
void ED_image_undo_push_begin(const char *name, PaintMode paint_mode)
void ED_image_undo_push_end()
void ED_paint_data_warning(ReportList *reports, bool has_uvs, bool has_mat, bool has_tex, bool has_stencil)
void ED_image_undo_restore(UndoStep *us)
bool ED_paint_proj_mesh_data_check(Scene &scene, Object &ob, bool *r_has_uvs, bool *r_has_mat, bool *r_has_tex, bool *r_has_stencil)
ViewContext ED_view3d_viewcontext_init(bContext *C, Depsgraph *depsgraph)
void immEnd()
void immUnbindProgram()
void immBindBuiltinProgram(GPUBuiltinShader shader_id)
void immVertex2f(uint attr_id, float x, float y)
void immVertex2fv(uint attr_id, const float data[2])
void immUniformColor4ub(unsigned char r, unsigned char g, unsigned char b, unsigned char a)
GPUVertFormat * immVertexFormat()
void immBegin(GPUPrimType, uint vertex_len)
@ GPU_PRIM_LINES
@ GPU_SHADER_3D_UNIFORM_COLOR
void GPU_line_width(float width)
Definition gpu_state.cc:166
void GPU_line_smooth(bool enable)
Definition gpu_state.cc:78
@ GPU_BLEND_NONE
Definition GPU_state.hh:85
@ GPU_BLEND_ALPHA
Definition GPU_state.hh:87
void GPU_blend(GPUBlend blend)
Definition gpu_state.cc:42
uint GPU_vertformat_attr_add(GPUVertFormat *format, blender::StringRef name, blender::gpu::VertAttrType type)
Read Guarded memory(de)allocation.
#define C
Definition RandGen.cpp:29
#define NC_SCENE
Definition WM_types.hh:378
@ OPTYPE_BLOCKING
Definition WM_types.hh:184
#define ND_TOOLSETTINGS
Definition WM_types.hh:449
BPy_StructRNA * depsgraph
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
virtual void paint_stroke_redraw(const bContext *C, void *stroke_handle, bool final)=0
virtual void paint_bucket_fill(const bContext *C, const Paint *paint, Brush *brush, PaintStroke *stroke, void *stroke_handle, float mouse_start[2], float mouse_end[2])=0
virtual void paint_stroke(bContext *C, void *stroke_handle, float prev_mouse[2], float mouse[2], int eraser, float pressure, float distance, float size)=0
virtual void * paint_new_stroke(bContext *C, wmOperator *op, Object *ob, const float mouse[2], int mode)=0
virtual void paint_gradient_fill(const bContext *C, const Paint *paint, Brush *brush, PaintStroke *stroke, void *stroke_handle, float mouse_start[2], float mouse_end[2])=0
void paint_gradient_fill(const bContext *C, const Paint *, Brush *brush, PaintStroke *, void *stroke_handle, float mouse_start[2], float mouse_end[2]) override
void paint_stroke(bContext *, void *stroke_handle, float prev_mouse[2], float mouse[2], int eraser, float pressure, float distance, float size) override
void * paint_new_stroke(bContext *C, wmOperator *op, Object *, const float[2], int mode) override
void paint_stroke_redraw(const bContext *C, void *stroke_handle, bool final) override
void paint_bucket_fill(const bContext *C, const Paint *paint, Brush *brush, PaintStroke *stroke, void *stroke_handle, float mouse_start[2], float mouse_end[2]) override
void * paint_new_stroke(bContext *C, wmOperator *, Object *ob, const float mouse[2], int mode) override
void paint_gradient_fill(const bContext *C, const Paint *paint, Brush *brush, PaintStroke *stroke, void *stroke_handle, float mouse_start[2], float mouse_end[2]) override
void paint_bucket_fill(const bContext *C, const Paint *paint, Brush *brush, PaintStroke *stroke, void *stroke_handle, float mouse_start[2], float mouse_end[2]) override
void paint_stroke_redraw(const bContext *C, void *stroke_handle, bool final) override
void paint_stroke(bContext *C, void *stroke_handle, float prev_mouse[2], float mouse[2], int eraser, float pressure, float distance, float size) override
uint pos
float distance(VecOp< float, D >, VecOp< float, D >) RET
format
static wmOperatorStatus paint_exec(bContext *C, wmOperator *op)
static bool paint_stroke_test_start(bContext *C, wmOperator *op, const float mouse[2])
static std::unique_ptr< PaintOperation > texture_paint_init(bContext *C, wmOperator *op, const float mouse[2])
static void gradient_draw_line(bContext *, const blender::int2 &xy, const blender::float2 &, void *customdata)
static wmOperatorStatus paint_modal(bContext *C, wmOperator *op, const wmEvent *event)
static void paint_stroke_update_step(bContext *C, wmOperator *op, PaintStroke *stroke, PointerRNA *itemptr)
static void paint_stroke_done(const bContext *C, PaintStroke *stroke)
static wmOperatorStatus paint_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static void paint_stroke_redraw(const bContext *C, PaintStroke *stroke, bool final)
static void paint_cancel(bContext *C, wmOperator *op)
void paint_stroke_jitter_pos(const PaintStroke &stroke, PaintMode mode, const Brush &brush, float pressure, const float mval[2], float r_mouse_out[2])
wmOperatorStatus paint_stroke_exec(bContext *C, wmOperator *op, PaintStroke *stroke)
void paint_stroke_cancel(bContext *C, wmOperator *op, PaintStroke *stroke)
bool paint_stroke_flipped(PaintStroke *stroke)
wmOperatorStatus paint_stroke_modal(bContext *C, wmOperator *op, const wmEvent *event, PaintStroke **stroke_p)
bool paint_brush_update(bContext *C, const Brush &brush, PaintMode mode, PaintStroke *stroke, const float mouse_init[2], float mouse[2], float pressure, float r_location[3], bool *r_location_is_set)
void * paint_stroke_mode_data(PaintStroke *stroke)
float paint_stroke_distance_get(PaintStroke *stroke)
void paint_stroke_free(bContext *C, wmOperator *op, PaintStroke *stroke)
PaintStroke * paint_stroke_new(bContext *C, wmOperator *op, StrokeGetLocation get_location, StrokeTestStart test_start, StrokeUpdateStep update_step, StrokeRedraw redraw, StrokeDone done, int event_type)
bool paint_stroke_inverted(PaintStroke *stroke)
void paint_stroke_set_mode_data(PaintStroke *stroke, std::unique_ptr< PaintModeData > mode_data)
VecBase< int32_t, 2 > int2
VecBase< float, 2 > float2
void * paint_2d_new_stroke(bContext *C, wmOperator *op, int mode)
void paint_2d_bucket_fill(const bContext *C, const float color[3], Brush *br, const float mouse_init[2], const float mouse_final[2], void *ps)
void paint_2d_gradient_fill(const bContext *C, Brush *br, const float mouse_init[2], const float mouse_final[2], void *ps)
void paint_2d_stroke_done(void *ps)
void paint_2d_stroke(void *ps, const float prev_mval[2], const float mval[2], const bool eraser, float pressure, float distance, float base_size)
void paint_2d_redraw(const bContext *C, void *ps, bool final)
void PAINT_OT_image_paint(wmOperatorType *ot)
void * paint_proj_new_stroke(bContext *C, Object *ob, const float mouse[2], int mode)
void paint_proj_stroke(const bContext *C, void *ps_handle_p, const float prev_pos[2], const float pos[2], const bool eraser, float pressure, float distance, float size)
void paint_proj_redraw(const bContext *C, void *ps_handle_p, bool final)
void paint_proj_stroke_done(void *ps_handle_p)
void paint_stroke_operator_properties(wmOperatorType *ot)
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
void RNA_float_get_array(PointerRNA *ptr, const char *name, float *values)
float RNA_float_get(PointerRNA *ptr, const char *name)
bool RNA_property_collection_lookup_int(PointerRNA *ptr, PropertyRNA *prop, int key, PointerRNA *r_ptr)
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
int RNA_enum_get(PointerRNA *ptr, const char *name)
char image_brush_type
struct CurveMapping * curve_strength
struct ToolSettings * toolsettings
struct ImagePaintSettings imapaint
UndoStep * step_init
ARegion * region
Definition ED_view3d.hh:77
int ymin
int xmin
wmEventType type
Definition WM_types.hh:757
const char * name
Definition WM_types.hh:1033
wmOperatorStatus(* modal)(bContext *C, wmOperator *op, const wmEvent *event) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1081
struct ReportList * reports
struct wmOperatorType * type
struct PointerRNA * ptr
WindowManagerRuntimeHandle * runtime
int xy[2]
Definition wm_draw.cc:178
wmEventHandler_Op * WM_event_add_modal_handler(bContext *C, wmOperator *op)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
wmOperatorType * ot
Definition wm_files.cc:4237
bool WM_paint_cursor_end(wmPaintCursor *handle)
wmPaintCursor * WM_paint_cursor_activate(short space_type, short region_type, bool(*poll)(bContext *C), wmPaintCursorDraw draw, void *customdata)