Cleanup: style, use braces for editors
[blender.git] / source / blender / editors / sculpt_paint / paint_image.c
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * along with this program; if not, write to the Free Software Foundation,
13  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
14  *
15  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
16  * All rights reserved.
17  *
18  * The Original Code is: some of this file.
19  */
20
21 /** \file
22  * \ingroup edsculpt
23  * \brief Functions to paint images in 2D and 3D.
24  */
25
26 #include <float.h>
27 #include <string.h>
28 #include <stdio.h>
29 #include <math.h>
30
31 #include "MEM_guardedalloc.h"
32
33 #include "BLI_math.h"
34 #include "BLI_blenlib.h"
35 #include "BLI_utildefines.h"
36
37 #include "BLT_translation.h"
38
39 #include "IMB_imbuf.h"
40 #include "IMB_imbuf_types.h"
41
42 #include "DNA_brush_types.h"
43 #include "DNA_mesh_types.h"
44 #include "DNA_node_types.h"
45 #include "DNA_object_types.h"
46
47 #include "BKE_colorband.h"
48 #include "BKE_context.h"
49 #include "BKE_brush.h"
50 #include "BKE_main.h"
51 #include "BKE_material.h"
52 #include "BKE_mesh.h"
53 #include "BKE_node.h"
54 #include "BKE_paint.h"
55 #include "BKE_undo_system.h"
56
57 #include "DEG_depsgraph.h"
58
59 #include "UI_interface.h"
60 #include "UI_view2d.h"
61
62 #include "ED_image.h"
63 #include "ED_object.h"
64 #include "ED_paint.h"
65 #include "ED_screen.h"
66 #include "ED_view3d.h"
67
68 #include "WM_api.h"
69 #include "WM_types.h"
70 #include "WM_message.h"
71 #include "WM_toolsystem.h"
72
73 #include "RNA_access.h"
74 #include "RNA_define.h"
75
76 #include "GPU_draw.h"
77 #include "GPU_immediate.h"
78 #include "GPU_state.h"
79
80 #include "IMB_colormanagement.h"
81
82 #include "paint_intern.h"
83
84 /**
85  * This is a static resource for non-global access.
86  * Maybe it should be exposed as part of the paint operation,
87  * but for now just give a public interface.
88  */
89 static ImagePaintPartialRedraw imapaintpartial = {0, 0, 0, 0, 0};
90
91 ImagePaintPartialRedraw *get_imapaintpartial(void)
92 {
93   return &imapaintpartial;
94 }
95
96 void set_imapaintpartial(struct ImagePaintPartialRedraw *ippr)
97 {
98   imapaintpartial = *ippr;
99 }
100
101 /* Imagepaint Partial Redraw & Dirty Region */
102
103 void ED_imapaint_clear_partial_redraw(void)
104 {
105   memset(&imapaintpartial, 0, sizeof(imapaintpartial));
106 }
107
108 void imapaint_region_tiles(
109     ImBuf *ibuf, int x, int y, int w, int h, int *tx, int *ty, int *tw, int *th)
110 {
111   int srcx = 0, srcy = 0;
112
113   IMB_rectclip(ibuf, NULL, &x, &y, &srcx, &srcy, &w, &h);
114
115   *tw = ((x + w - 1) >> IMAPAINT_TILE_BITS);
116   *th = ((y + h - 1) >> IMAPAINT_TILE_BITS);
117   *tx = (x >> IMAPAINT_TILE_BITS);
118   *ty = (y >> IMAPAINT_TILE_BITS);
119 }
120
121 void ED_imapaint_dirty_region(Image *ima, ImBuf *ibuf, int x, int y, int w, int h, bool find_old)
122 {
123   ImBuf *tmpibuf = NULL;
124   int tilex, tiley, tilew, tileh, tx, ty;
125   int srcx = 0, srcy = 0;
126
127   IMB_rectclip(ibuf, NULL, &x, &y, &srcx, &srcy, &w, &h);
128
129   if (w == 0 || h == 0) {
130     return;
131   }
132
133   if (!imapaintpartial.enabled) {
134     imapaintpartial.x1 = x;
135     imapaintpartial.y1 = y;
136     imapaintpartial.x2 = x + w;
137     imapaintpartial.y2 = y + h;
138     imapaintpartial.enabled = 1;
139   }
140   else {
141     imapaintpartial.x1 = min_ii(imapaintpartial.x1, x);
142     imapaintpartial.y1 = min_ii(imapaintpartial.y1, y);
143     imapaintpartial.x2 = max_ii(imapaintpartial.x2, x + w);
144     imapaintpartial.y2 = max_ii(imapaintpartial.y2, y + h);
145   }
146
147   imapaint_region_tiles(ibuf, x, y, w, h, &tilex, &tiley, &tilew, &tileh);
148
149   ListBase *undo_tiles = ED_image_undo_get_tiles();
150
151   for (ty = tiley; ty <= tileh; ty++) {
152     for (tx = tilex; tx <= tilew; tx++) {
153       image_undo_push_tile(undo_tiles, ima, ibuf, &tmpibuf, tx, ty, NULL, NULL, false, find_old);
154     }
155   }
156
157   ibuf->userflags |= IB_BITMAPDIRTY;
158
159   if (tmpibuf) {
160     IMB_freeImBuf(tmpibuf);
161   }
162 }
163
164 void imapaint_image_update(SpaceImage *sima, Image *image, ImBuf *ibuf, short texpaint)
165 {
166   if (imapaintpartial.x1 != imapaintpartial.x2 && imapaintpartial.y1 != imapaintpartial.y2) {
167     IMB_partial_display_buffer_update_delayed(
168         ibuf, imapaintpartial.x1, imapaintpartial.y1, imapaintpartial.x2, imapaintpartial.y2);
169   }
170
171   if (ibuf->mipmap[0]) {
172     ibuf->userflags |= IB_MIPMAP_INVALID;
173   }
174
175   /* todo: should set_tpage create ->rect? */
176   if (texpaint || (sima && sima->lock)) {
177     int w = imapaintpartial.x2 - imapaintpartial.x1;
178     int h = imapaintpartial.y2 - imapaintpartial.y1;
179     if (w && h) {
180       /* Testing with partial update in uv editor too */
181       GPU_paint_update_image(
182           image, (sima ? &sima->iuser : NULL), imapaintpartial.x1, imapaintpartial.y1, w, h);
183     }
184   }
185 }
186
187 /* paint blur kernels. Projective painting enforces use of a 2x2 kernel due to lagging */
188 BlurKernel *paint_new_blur_kernel(Brush *br, bool proj)
189 {
190   int i, j;
191   BlurKernel *kernel = MEM_mallocN(sizeof(BlurKernel), "blur kernel");
192   float radius;
193   int side;
194   eBlurKernelType type = br->blur_mode;
195
196   if (proj) {
197     radius = 0.5f;
198
199     side = kernel->side = 2;
200     kernel->side_squared = kernel->side * kernel->side;
201     kernel->wdata = MEM_mallocN(sizeof(float) * kernel->side_squared, "blur kernel data");
202     kernel->pixel_len = radius;
203   }
204   else {
205     if (br->blur_kernel_radius <= 0) {
206       br->blur_kernel_radius = 1;
207     }
208
209     radius = br->blur_kernel_radius;
210
211     side = kernel->side = radius * 2 + 1;
212     kernel->side_squared = kernel->side * kernel->side;
213     kernel->wdata = MEM_mallocN(sizeof(float) * kernel->side_squared, "blur kernel data");
214     kernel->pixel_len = br->blur_kernel_radius;
215   }
216
217   switch (type) {
218     case KERNEL_BOX:
219       for (i = 0; i < kernel->side_squared; i++) {
220         kernel->wdata[i] = 1.0;
221       }
222       break;
223
224     case KERNEL_GAUSSIAN: {
225       /* at 3.0 standard deviations distance, kernel is about zero */
226       float standard_dev = radius / 3.0f;
227
228       /* make the necessary adjustment to the value for use in the normal distribution formula */
229       standard_dev = -standard_dev * standard_dev * 2;
230
231       for (i = 0; i < side; i++) {
232         for (j = 0; j < side; j++) {
233           float idist = radius - i;
234           float jdist = radius - j;
235           float value = exp((idist * idist + jdist * jdist) / standard_dev);
236
237           kernel->wdata[i + j * side] = value;
238         }
239       }
240
241       break;
242     }
243
244     default:
245       printf("unidentified kernel type, aborting\n");
246       MEM_freeN(kernel->wdata);
247       MEM_freeN(kernel);
248       return NULL;
249   }
250
251   return kernel;
252 }
253
254 void paint_delete_blur_kernel(BlurKernel *kernel)
255 {
256   if (kernel->wdata) {
257     MEM_freeN(kernel->wdata);
258   }
259 }
260
261 /************************ image paint poll ************************/
262
263 static Brush *image_paint_brush(bContext *C)
264 {
265   Scene *scene = CTX_data_scene(C);
266   ToolSettings *settings = scene->toolsettings;
267
268   return BKE_paint_brush(&settings->imapaint.paint);
269 }
270
271 static bool image_paint_poll_ex(bContext *C, bool check_tool)
272 {
273   Object *obact;
274
275   if (!image_paint_brush(C)) {
276     return 0;
277   }
278
279   obact = CTX_data_active_object(C);
280   if ((obact && obact->mode & OB_MODE_TEXTURE_PAINT) && CTX_wm_region_view3d(C)) {
281     if (!check_tool || WM_toolsystem_active_tool_is_brush(C)) {
282       return 1;
283     }
284   }
285   else {
286     SpaceImage *sima = CTX_wm_space_image(C);
287
288     if (sima) {
289       ARegion *ar = CTX_wm_region(C);
290
291       if ((sima->mode == SI_MODE_PAINT) && ar->regiontype == RGN_TYPE_WINDOW) {
292         return 1;
293       }
294     }
295   }
296
297   return 0;
298 }
299
300 static bool image_paint_poll(bContext *C)
301 {
302   return image_paint_poll_ex(C, true);
303 }
304
305 static bool image_paint_poll_ignore_tool(bContext *C)
306 {
307   return image_paint_poll_ex(C, false);
308 }
309
310 static bool image_paint_2d_clone_poll(bContext *C)
311 {
312   Brush *brush = image_paint_brush(C);
313
314   if (!CTX_wm_region_view3d(C) && image_paint_poll(C)) {
315     if (brush && (brush->imagepaint_tool == PAINT_TOOL_CLONE)) {
316       if (brush->clone.image) {
317         return 1;
318       }
319     }
320   }
321
322   return 0;
323 }
324
325 /************************ paint operator ************************/
326 typedef enum eTexPaintMode {
327   PAINT_MODE_2D,
328   PAINT_MODE_3D_PROJECT,
329 } eTexPaintMode;
330
331 typedef struct PaintOperation {
332   eTexPaintMode mode;
333
334   void *custom_paint;
335
336   float prevmouse[2];
337   float startmouse[2];
338   double starttime;
339
340   void *cursor;
341   ViewContext vc;
342 } PaintOperation;
343
344 bool paint_use_opacity_masking(Brush *brush)
345 {
346   return ((brush->flag & BRUSH_AIRBRUSH) || (brush->flag & BRUSH_DRAG_DOT) ||
347                   (brush->flag & BRUSH_ANCHORED) || (brush->imagepaint_tool == PAINT_TOOL_SMEAR) ||
348                   (brush->imagepaint_tool == PAINT_TOOL_SOFTEN) ||
349                   (brush->imagepaint_tool == PAINT_TOOL_FILL) ||
350                   (brush->flag & BRUSH_USE_GRADIENT) ||
351                   (brush->mtex.tex && !ELEM(brush->mtex.brush_map_mode,
352                                             MTEX_MAP_MODE_TILED,
353                                             MTEX_MAP_MODE_STENCIL,
354                                             MTEX_MAP_MODE_3D)) ?
355               false :
356               true);
357 }
358
359 void paint_brush_color_get(struct Scene *scene,
360                            struct Brush *br,
361                            bool color_correction,
362                            bool invert,
363                            float distance,
364                            float pressure,
365                            float color[3],
366                            struct ColorManagedDisplay *display)
367 {
368   if (invert) {
369     copy_v3_v3(color, BKE_brush_secondary_color_get(scene, br));
370   }
371   else {
372     if (br->flag & BRUSH_USE_GRADIENT) {
373       float color_gr[4];
374       switch (br->gradient_stroke_mode) {
375         case BRUSH_GRADIENT_PRESSURE:
376           BKE_colorband_evaluate(br->gradient, pressure, color_gr);
377           break;
378         case BRUSH_GRADIENT_SPACING_REPEAT: {
379           float coord = fmod(distance / br->gradient_spacing, 1.0);
380           BKE_colorband_evaluate(br->gradient, coord, color_gr);
381           break;
382         }
383         case BRUSH_GRADIENT_SPACING_CLAMP: {
384           BKE_colorband_evaluate(br->gradient, distance / br->gradient_spacing, color_gr);
385           break;
386         }
387       }
388       copy_v3_v3(color, color_gr);
389     }
390     else {
391       copy_v3_v3(color, BKE_brush_color_get(scene, br));
392     }
393   }
394   if (color_correction) {
395     IMB_colormanagement_display_to_scene_linear_v3(color, display);
396   }
397 }
398
399 void paint_brush_init_tex(Brush *brush)
400 {
401   /* init mtex nodes */
402   if (brush) {
403     MTex *mtex = &brush->mtex;
404     if (mtex->tex && mtex->tex->nodetree) {
405       /* has internal flag to detect it only does it once */
406       ntreeTexBeginExecTree(mtex->tex->nodetree);
407     }
408     mtex = &brush->mask_mtex;
409     if (mtex->tex && mtex->tex->nodetree) {
410       ntreeTexBeginExecTree(mtex->tex->nodetree);
411     }
412   }
413 }
414
415 void paint_brush_exit_tex(Brush *brush)
416 {
417   if (brush) {
418     MTex *mtex = &brush->mtex;
419     if (mtex->tex && mtex->tex->nodetree) {
420       ntreeTexEndExecTree(mtex->tex->nodetree->execdata);
421     }
422     mtex = &brush->mask_mtex;
423     if (mtex->tex && mtex->tex->nodetree) {
424       ntreeTexEndExecTree(mtex->tex->nodetree->execdata);
425     }
426   }
427 }
428
429 static void gradient_draw_line(bContext *UNUSED(C), int x, int y, void *customdata)
430 {
431   PaintOperation *pop = (PaintOperation *)customdata;
432
433   if (pop) {
434     GPU_line_smooth(true);
435     GPU_blend(true);
436
437     GPUVertFormat *format = immVertexFormat();
438     uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
439
440     ARegion *ar = pop->vc.ar;
441
442     immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
443
444     GPU_line_width(4.0);
445     immUniformColor4ub(0, 0, 0, 255);
446
447     immBegin(GPU_PRIM_LINES, 2);
448     immVertex2i(pos, x, y);
449     immVertex2i(pos, pop->startmouse[0] + ar->winrct.xmin, pop->startmouse[1] + ar->winrct.ymin);
450     immEnd();
451
452     GPU_line_width(2.0);
453     immUniformColor4ub(255, 255, 255, 255);
454
455     immBegin(GPU_PRIM_LINES, 2);
456     immVertex2i(pos, x, y);
457     immVertex2i(pos, pop->startmouse[0] + ar->winrct.xmin, pop->startmouse[1] + ar->winrct.ymin);
458     immEnd();
459
460     immUnbindProgram();
461
462     GPU_blend(false);
463     GPU_line_smooth(false);
464   }
465 }
466
467 static PaintOperation *texture_paint_init(bContext *C, wmOperator *op, const float mouse[2])
468 {
469   Scene *scene = CTX_data_scene(C);
470   ToolSettings *settings = scene->toolsettings;
471   PaintOperation *pop = MEM_callocN(sizeof(PaintOperation), "PaintOperation"); /* caller frees */
472   Brush *brush = BKE_paint_brush(&settings->imapaint.paint);
473   int mode = RNA_enum_get(op->ptr, "mode");
474   ED_view3d_viewcontext_init(C, &pop->vc);
475
476   copy_v2_v2(pop->prevmouse, mouse);
477   copy_v2_v2(pop->startmouse, mouse);
478
479   /* initialize from context */
480   if (CTX_wm_region_view3d(C)) {
481     ViewLayer *view_layer = CTX_data_view_layer(C);
482     Object *ob = OBACT(view_layer);
483     bool uvs, mat, tex, stencil;
484     if (!BKE_paint_proj_mesh_data_check(scene, ob, &uvs, &mat, &tex, &stencil)) {
485       BKE_paint_data_warning(op->reports, uvs, mat, tex, stencil);
486       MEM_freeN(pop);
487       WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, NULL);
488       return NULL;
489     }
490     pop->mode = PAINT_MODE_3D_PROJECT;
491     pop->custom_paint = paint_proj_new_stroke(C, ob, mouse, mode);
492   }
493   else {
494     pop->mode = PAINT_MODE_2D;
495     pop->custom_paint = paint_2d_new_stroke(C, op, mode);
496   }
497
498   if (!pop->custom_paint) {
499     MEM_freeN(pop);
500     return NULL;
501   }
502
503   if ((brush->imagepaint_tool == PAINT_TOOL_FILL) && (brush->flag & BRUSH_USE_GRADIENT)) {
504     pop->cursor = WM_paint_cursor_activate(CTX_wm_manager(C),
505                                            SPACE_TYPE_ANY,
506                                            RGN_TYPE_ANY,
507                                            image_paint_poll,
508                                            gradient_draw_line,
509                                            pop);
510   }
511
512   settings->imapaint.flag |= IMAGEPAINT_DRAWING;
513   ED_image_undo_push_begin(op->type->name, PAINT_MODE_TEXTURE_2D);
514
515   return pop;
516 }
517
518 static void paint_stroke_update_step(bContext *C, struct PaintStroke *stroke, PointerRNA *itemptr)
519 {
520   PaintOperation *pop = paint_stroke_mode_data(stroke);
521   Scene *scene = CTX_data_scene(C);
522   ToolSettings *toolsettings = CTX_data_tool_settings(C);
523   UnifiedPaintSettings *ups = &toolsettings->unified_paint_settings;
524   Brush *brush = BKE_paint_brush(&toolsettings->imapaint.paint);
525
526   float alphafac = (brush->flag & BRUSH_ACCUMULATE) ? ups->overlap_factor : 1.0f;
527
528   /* initial brush values. Maybe it should be considered moving these to stroke system */
529   float startalpha = BKE_brush_alpha_get(scene, brush);
530
531   float mouse[2];
532   float pressure;
533   float size;
534   float distance = paint_stroke_distance_get(stroke);
535   int eraser;
536
537   RNA_float_get_array(itemptr, "mouse", mouse);
538   pressure = RNA_float_get(itemptr, "pressure");
539   eraser = RNA_boolean_get(itemptr, "pen_flip");
540   size = max_ff(1.0f, RNA_float_get(itemptr, "size"));
541
542   /* stroking with fill tool only acts on stroke end */
543   if (brush->imagepaint_tool == PAINT_TOOL_FILL) {
544     copy_v2_v2(pop->prevmouse, mouse);
545     return;
546   }
547
548   if (BKE_brush_use_alpha_pressure(scene, brush)) {
549     BKE_brush_alpha_set(scene, brush, max_ff(0.0f, startalpha * pressure * alphafac));
550   }
551   else {
552     BKE_brush_alpha_set(scene, brush, max_ff(0.0f, startalpha * alphafac));
553   }
554
555   if ((brush->flag & BRUSH_DRAG_DOT) || (brush->flag & BRUSH_ANCHORED)) {
556     UndoStack *ustack = CTX_wm_manager(C)->undo_stack;
557     ED_image_undo_restore(ustack->step_init);
558   }
559
560   if (pop->mode == PAINT_MODE_3D_PROJECT) {
561     paint_proj_stroke(
562         C, pop->custom_paint, pop->prevmouse, mouse, eraser, pressure, distance, size);
563   }
564   else {
565     paint_2d_stroke(pop->custom_paint, pop->prevmouse, mouse, eraser, pressure, distance, size);
566   }
567
568   copy_v2_v2(pop->prevmouse, mouse);
569
570   /* restore brush values */
571   BKE_brush_alpha_set(scene, brush, startalpha);
572 }
573
574 static void paint_stroke_redraw(const bContext *C, struct PaintStroke *stroke, bool final)
575 {
576   PaintOperation *pop = paint_stroke_mode_data(stroke);
577
578   if (pop->mode == PAINT_MODE_3D_PROJECT) {
579     paint_proj_redraw(C, pop->custom_paint, final);
580   }
581   else {
582     paint_2d_redraw(C, pop->custom_paint, final);
583   }
584 }
585
586 static void paint_stroke_done(const bContext *C, struct PaintStroke *stroke)
587 {
588   Scene *scene = CTX_data_scene(C);
589   ToolSettings *toolsettings = scene->toolsettings;
590   PaintOperation *pop = paint_stroke_mode_data(stroke);
591   Brush *brush = BKE_paint_brush(&toolsettings->imapaint.paint);
592
593   toolsettings->imapaint.flag &= ~IMAGEPAINT_DRAWING;
594
595   if (brush->imagepaint_tool == PAINT_TOOL_FILL) {
596     if (brush->flag & BRUSH_USE_GRADIENT) {
597       if (pop->mode == PAINT_MODE_2D) {
598         paint_2d_gradient_fill(C, brush, pop->startmouse, pop->prevmouse, pop->custom_paint);
599       }
600       else {
601         paint_proj_stroke(C,
602                           pop->custom_paint,
603                           pop->startmouse,
604                           pop->prevmouse,
605                           paint_stroke_flipped(stroke),
606                           1.0,
607                           0.0,
608                           BKE_brush_size_get(scene, brush));
609         /* two redraws, one for GPU update, one for notification */
610         paint_proj_redraw(C, pop->custom_paint, false);
611         paint_proj_redraw(C, pop->custom_paint, true);
612       }
613     }
614     else {
615       if (pop->mode == PAINT_MODE_2D) {
616         float color[3];
617         if (paint_stroke_inverted(stroke)) {
618           srgb_to_linearrgb_v3_v3(color, BKE_brush_secondary_color_get(scene, brush));
619         }
620         else {
621           srgb_to_linearrgb_v3_v3(color, BKE_brush_color_get(scene, brush));
622         }
623         paint_2d_bucket_fill(C, color, brush, pop->prevmouse, pop->custom_paint);
624       }
625       else {
626         paint_proj_stroke(C,
627                           pop->custom_paint,
628                           pop->startmouse,
629                           pop->prevmouse,
630                           paint_stroke_flipped(stroke),
631                           1.0,
632                           0.0,
633                           BKE_brush_size_get(scene, brush));
634         /* two redraws, one for GPU update, one for notification */
635         paint_proj_redraw(C, pop->custom_paint, false);
636         paint_proj_redraw(C, pop->custom_paint, true);
637       }
638     }
639   }
640   if (pop->mode == PAINT_MODE_3D_PROJECT) {
641     paint_proj_stroke_done(pop->custom_paint);
642   }
643   else {
644     paint_2d_stroke_done(pop->custom_paint);
645   }
646
647   if (pop->cursor) {
648     WM_paint_cursor_end(CTX_wm_manager(C), pop->cursor);
649   }
650
651   ED_image_undo_push_end();
652
653   /* duplicate warning, see texpaint_init */
654 #if 0
655   if (pop->s.warnmultifile)
656     BKE_reportf(op->reports,
657                 RPT_WARNING,
658                 "Image requires 4 color channels to paint: %s",
659                 pop->s.warnmultifile);
660   if (pop->s.warnpackedfile)
661     BKE_reportf(op->reports,
662                 RPT_WARNING,
663                 "Packed MultiLayer files cannot be painted: %s",
664                 pop->s.warnpackedfile);
665 #endif
666   MEM_freeN(pop);
667 }
668
669 static bool paint_stroke_test_start(bContext *C, wmOperator *op, const float mouse[2])
670 {
671   PaintOperation *pop;
672
673   /* TODO Should avoid putting this here. Instead, last position should be requested
674    * from stroke system. */
675
676   if (!(pop = texture_paint_init(C, op, mouse))) {
677     return false;
678   }
679
680   paint_stroke_set_mode_data(op->customdata, pop);
681
682   return true;
683 }
684
685 static int paint_invoke(bContext *C, wmOperator *op, const wmEvent *event)
686 {
687   int retval;
688
689   op->customdata = paint_stroke_new(C,
690                                     op,
691                                     NULL,
692                                     paint_stroke_test_start,
693                                     paint_stroke_update_step,
694                                     paint_stroke_redraw,
695                                     paint_stroke_done,
696                                     event->type);
697
698   if ((retval = op->type->modal(C, op, event)) == OPERATOR_FINISHED) {
699     paint_stroke_data_free(op);
700     return OPERATOR_FINISHED;
701   }
702   /* add modal handler */
703   WM_event_add_modal_handler(C, op);
704
705   OPERATOR_RETVAL_CHECK(retval);
706   BLI_assert(retval == OPERATOR_RUNNING_MODAL);
707
708   return OPERATOR_RUNNING_MODAL;
709 }
710
711 static int paint_exec(bContext *C, wmOperator *op)
712 {
713   PropertyRNA *strokeprop;
714   PointerRNA firstpoint;
715   float mouse[2];
716
717   strokeprop = RNA_struct_find_property(op->ptr, "stroke");
718
719   if (!RNA_property_collection_lookup_int(op->ptr, strokeprop, 0, &firstpoint)) {
720     return OPERATOR_CANCELLED;
721   }
722
723   RNA_float_get_array(&firstpoint, "mouse", mouse);
724
725   op->customdata = paint_stroke_new(C,
726                                     op,
727                                     NULL,
728                                     paint_stroke_test_start,
729                                     paint_stroke_update_step,
730                                     paint_stroke_redraw,
731                                     paint_stroke_done,
732                                     0);
733   /* frees op->customdata */
734   return paint_stroke_exec(C, op);
735 }
736
737 void PAINT_OT_image_paint(wmOperatorType *ot)
738 {
739   /* identifiers */
740   ot->name = "Image Paint";
741   ot->idname = "PAINT_OT_image_paint";
742   ot->description = "Paint a stroke into the image";
743
744   /* api callbacks */
745   ot->invoke = paint_invoke;
746   ot->modal = paint_stroke_modal;
747   ot->exec = paint_exec;
748   ot->poll = image_paint_poll;
749   ot->cancel = paint_stroke_cancel;
750
751   /* flags */
752   ot->flag = OPTYPE_BLOCKING;
753
754   paint_stroke_operator_properties(ot);
755 }
756
757 int get_imapaint_zoom(bContext *C, float *zoomx, float *zoomy)
758 {
759   RegionView3D *rv3d = CTX_wm_region_view3d(C);
760
761   if (!rv3d) {
762     SpaceImage *sima = CTX_wm_space_image(C);
763
764     if (sima->mode == SI_MODE_PAINT) {
765       ARegion *ar = CTX_wm_region(C);
766       ED_space_image_get_zoom(sima, ar, zoomx, zoomy);
767
768       return 1;
769     }
770   }
771
772   *zoomx = *zoomy = 1;
773
774   return 0;
775 }
776
777 /************************ cursor drawing *******************************/
778
779 static void toggle_paint_cursor(bContext *C, int enable)
780 {
781   wmWindowManager *wm = CTX_wm_manager(C);
782   Scene *scene = CTX_data_scene(C);
783   ToolSettings *settings = scene->toolsettings;
784
785   if (settings->imapaint.paintcursor && !enable) {
786     WM_paint_cursor_end(wm, settings->imapaint.paintcursor);
787     settings->imapaint.paintcursor = NULL;
788     paint_cursor_delete_textures();
789   }
790   else if (enable) {
791     paint_cursor_start(C, image_paint_poll);
792   }
793 }
794
795 /* enable the paint cursor if it isn't already.
796  *
797  * purpose is to make sure the paint cursor is shown if paint
798  * mode is enabled in the image editor. the paint poll will
799  * ensure that the cursor is hidden when not in paint mode */
800 void ED_space_image_paint_update(Main *bmain, wmWindowManager *wm, Scene *scene)
801 {
802   ToolSettings *settings = scene->toolsettings;
803   ImagePaintSettings *imapaint = &settings->imapaint;
804   bool enabled = false;
805
806   for (wmWindow *win = wm->windows.first; win; win = win->next) {
807     bScreen *screen = WM_window_get_active_screen(win);
808
809     for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
810       if (sa->spacetype == SPACE_IMAGE) {
811         if (((SpaceImage *)sa->spacedata.first)->mode == SI_MODE_PAINT) {
812           enabled = true;
813         }
814       }
815     }
816   }
817
818   if (enabled) {
819     BKE_paint_init(bmain, scene, PAINT_MODE_TEXTURE_2D, PAINT_CURSOR_TEXTURE_PAINT);
820
821     paint_cursor_start_explicit(&imapaint->paint, wm, image_paint_poll);
822   }
823   else {
824     paint_cursor_delete_textures();
825   }
826 }
827
828 /************************ grab clone operator ************************/
829
830 typedef struct GrabClone {
831   float startoffset[2];
832   int startx, starty;
833 } GrabClone;
834
835 static void grab_clone_apply(bContext *C, wmOperator *op)
836 {
837   Brush *brush = image_paint_brush(C);
838   float delta[2];
839
840   RNA_float_get_array(op->ptr, "delta", delta);
841   add_v2_v2(brush->clone.offset, delta);
842   ED_region_tag_redraw(CTX_wm_region(C));
843 }
844
845 static int grab_clone_exec(bContext *C, wmOperator *op)
846 {
847   grab_clone_apply(C, op);
848
849   return OPERATOR_FINISHED;
850 }
851
852 static int grab_clone_invoke(bContext *C, wmOperator *op, const wmEvent *event)
853 {
854   Brush *brush = image_paint_brush(C);
855   GrabClone *cmv;
856
857   cmv = MEM_callocN(sizeof(GrabClone), "GrabClone");
858   copy_v2_v2(cmv->startoffset, brush->clone.offset);
859   cmv->startx = event->x;
860   cmv->starty = event->y;
861   op->customdata = cmv;
862
863   WM_event_add_modal_handler(C, op);
864
865   return OPERATOR_RUNNING_MODAL;
866 }
867
868 static int grab_clone_modal(bContext *C, wmOperator *op, const wmEvent *event)
869 {
870   Brush *brush = image_paint_brush(C);
871   ARegion *ar = CTX_wm_region(C);
872   GrabClone *cmv = op->customdata;
873   float startfx, startfy, fx, fy, delta[2];
874   int xmin = ar->winrct.xmin, ymin = ar->winrct.ymin;
875
876   switch (event->type) {
877     case LEFTMOUSE:
878     case MIDDLEMOUSE:
879     case RIGHTMOUSE:  // XXX hardcoded
880       MEM_freeN(op->customdata);
881       return OPERATOR_FINISHED;
882     case MOUSEMOVE:
883       /* mouse moved, so move the clone image */
884       UI_view2d_region_to_view(
885           &ar->v2d, cmv->startx - xmin, cmv->starty - ymin, &startfx, &startfy);
886       UI_view2d_region_to_view(&ar->v2d, event->x - xmin, event->y - ymin, &fx, &fy);
887
888       delta[0] = fx - startfx;
889       delta[1] = fy - startfy;
890       RNA_float_set_array(op->ptr, "delta", delta);
891
892       copy_v2_v2(brush->clone.offset, cmv->startoffset);
893
894       grab_clone_apply(C, op);
895       break;
896   }
897
898   return OPERATOR_RUNNING_MODAL;
899 }
900
901 static void grab_clone_cancel(bContext *UNUSED(C), wmOperator *op)
902 {
903   MEM_freeN(op->customdata);
904 }
905
906 void PAINT_OT_grab_clone(wmOperatorType *ot)
907 {
908   /* identifiers */
909   ot->name = "Grab Clone";
910   ot->idname = "PAINT_OT_grab_clone";
911   ot->description = "Move the clone source image";
912
913   /* api callbacks */
914   ot->exec = grab_clone_exec;
915   ot->invoke = grab_clone_invoke;
916   ot->modal = grab_clone_modal;
917   ot->cancel = grab_clone_cancel;
918   ot->poll = image_paint_2d_clone_poll;
919
920   /* flags */
921   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING;
922
923   /* properties */
924   RNA_def_float_vector(ot->srna,
925                        "delta",
926                        2,
927                        NULL,
928                        -FLT_MAX,
929                        FLT_MAX,
930                        "Delta",
931                        "Delta offset of clone image in 0.0..1.0 coordinates",
932                        -1.0f,
933                        1.0f);
934 }
935
936 /******************** sample color operator ********************/
937 typedef struct {
938   bool show_cursor;
939   short event_type;
940   float initcolor[3];
941   bool sample_palette;
942 } SampleColorData;
943
944 static void sample_color_update_header(SampleColorData *data, bContext *C)
945 {
946   char msg[UI_MAX_DRAW_STR];
947   ScrArea *sa = CTX_wm_area(C);
948
949   if (sa) {
950     BLI_snprintf(msg,
951                  sizeof(msg),
952                  IFACE_("Sample color for %s"),
953                  !data->sample_palette ?
954                      IFACE_("Brush. Use Left Click to sample for palette instead") :
955                      IFACE_("Palette. Use Left Click to sample more colors"));
956     ED_workspace_status_text(C, msg);
957   }
958 }
959
960 static int sample_color_exec(bContext *C, wmOperator *op)
961 {
962   Paint *paint = BKE_paint_get_active_from_context(C);
963   Brush *brush = BKE_paint_brush(paint);
964   ePaintMode mode = BKE_paintmode_get_active_from_context(C);
965   ARegion *ar = CTX_wm_region(C);
966   wmWindow *win = CTX_wm_window(C);
967   const bool show_cursor = ((paint->flags & PAINT_SHOW_BRUSH) != 0);
968   int location[2];
969   paint->flags &= ~PAINT_SHOW_BRUSH;
970
971   /* force redraw without cursor */
972   WM_paint_cursor_tag_redraw(win, ar);
973   WM_redraw_windows(C);
974
975   RNA_int_get_array(op->ptr, "location", location);
976   const bool use_palette = RNA_boolean_get(op->ptr, "palette");
977   const bool use_sample_texture = (mode == PAINT_MODE_TEXTURE_3D) &&
978                                   !RNA_boolean_get(op->ptr, "merged");
979
980   paint_sample_color(C, ar, location[0], location[1], use_sample_texture, use_palette);
981
982   if (show_cursor) {
983     paint->flags |= PAINT_SHOW_BRUSH;
984   }
985
986   WM_event_add_notifier(C, NC_BRUSH | NA_EDITED, brush);
987
988   return OPERATOR_FINISHED;
989 }
990
991 static int sample_color_invoke(bContext *C, wmOperator *op, const wmEvent *event)
992 {
993   Scene *scene = CTX_data_scene(C);
994   Paint *paint = BKE_paint_get_active_from_context(C);
995   Brush *brush = BKE_paint_brush(paint);
996   SampleColorData *data = MEM_mallocN(sizeof(SampleColorData), "sample color custom data");
997   ARegion *ar = CTX_wm_region(C);
998   wmWindow *win = CTX_wm_window(C);
999
1000   data->event_type = event->type;
1001   data->show_cursor = ((paint->flags & PAINT_SHOW_BRUSH) != 0);
1002   copy_v3_v3(data->initcolor, BKE_brush_color_get(scene, brush));
1003   data->sample_palette = false;
1004   op->customdata = data;
1005   paint->flags &= ~PAINT_SHOW_BRUSH;
1006
1007   sample_color_update_header(data, C);
1008
1009   WM_event_add_modal_handler(C, op);
1010
1011   /* force redraw without cursor */
1012   WM_paint_cursor_tag_redraw(win, ar);
1013   WM_redraw_windows(C);
1014
1015   RNA_int_set_array(op->ptr, "location", event->mval);
1016
1017   ePaintMode mode = BKE_paintmode_get_active_from_context(C);
1018   const bool use_sample_texture = (mode == PAINT_MODE_TEXTURE_3D) &&
1019                                   !RNA_boolean_get(op->ptr, "merged");
1020
1021   paint_sample_color(C, ar, event->mval[0], event->mval[1], use_sample_texture, false);
1022   WM_cursor_modal_set(win, BC_EYEDROPPER_CURSOR);
1023
1024   WM_event_add_notifier(C, NC_BRUSH | NA_EDITED, brush);
1025
1026   return OPERATOR_RUNNING_MODAL;
1027 }
1028
1029 static int sample_color_modal(bContext *C, wmOperator *op, const wmEvent *event)
1030 {
1031   Scene *scene = CTX_data_scene(C);
1032   SampleColorData *data = op->customdata;
1033   Paint *paint = BKE_paint_get_active_from_context(C);
1034   Brush *brush = BKE_paint_brush(paint);
1035
1036   if ((event->type == data->event_type) && (event->val == KM_RELEASE)) {
1037     if (data->show_cursor) {
1038       paint->flags |= PAINT_SHOW_BRUSH;
1039     }
1040
1041     if (data->sample_palette) {
1042       BKE_brush_color_set(scene, brush, data->initcolor);
1043       RNA_boolean_set(op->ptr, "palette", true);
1044     }
1045     WM_cursor_modal_restore(CTX_wm_window(C));
1046     MEM_freeN(data);
1047     ED_workspace_status_text(C, NULL);
1048
1049     return OPERATOR_FINISHED;
1050   }
1051
1052   ePaintMode mode = BKE_paintmode_get_active_from_context(C);
1053   const bool use_sample_texture = (mode == PAINT_MODE_TEXTURE_3D) &&
1054                                   !RNA_boolean_get(op->ptr, "merged");
1055
1056   switch (event->type) {
1057     case MOUSEMOVE: {
1058       ARegion *ar = CTX_wm_region(C);
1059       RNA_int_set_array(op->ptr, "location", event->mval);
1060       paint_sample_color(C, ar, event->mval[0], event->mval[1], use_sample_texture, false);
1061       WM_event_add_notifier(C, NC_BRUSH | NA_EDITED, brush);
1062       break;
1063     }
1064
1065     case LEFTMOUSE:
1066       if (event->val == KM_PRESS) {
1067         ARegion *ar = CTX_wm_region(C);
1068         RNA_int_set_array(op->ptr, "location", event->mval);
1069         paint_sample_color(C, ar, event->mval[0], event->mval[1], use_sample_texture, true);
1070         if (!data->sample_palette) {
1071           data->sample_palette = true;
1072           sample_color_update_header(data, C);
1073         }
1074         WM_event_add_notifier(C, NC_BRUSH | NA_EDITED, brush);
1075       }
1076       break;
1077   }
1078
1079   return OPERATOR_RUNNING_MODAL;
1080 }
1081
1082 static bool sample_color_poll(bContext *C)
1083 {
1084   return (image_paint_poll_ignore_tool(C) || vertex_paint_poll_ignore_tool(C));
1085 }
1086
1087 void PAINT_OT_sample_color(wmOperatorType *ot)
1088 {
1089   /* identifiers */
1090   ot->name = "Sample Color";
1091   ot->idname = "PAINT_OT_sample_color";
1092   ot->description = "Use the mouse to sample a color in the image";
1093
1094   /* api callbacks */
1095   ot->exec = sample_color_exec;
1096   ot->invoke = sample_color_invoke;
1097   ot->modal = sample_color_modal;
1098   ot->poll = sample_color_poll;
1099
1100   /* flags */
1101   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1102
1103   /* properties */
1104   PropertyRNA *prop;
1105
1106   prop = RNA_def_int_vector(ot->srna, "location", 2, NULL, 0, INT_MAX, "Location", "", 0, 16384);
1107   RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN);
1108
1109   RNA_def_boolean(ot->srna, "merged", 0, "Sample Merged", "Sample the output display color");
1110   RNA_def_boolean(ot->srna, "palette", 0, "Add to Palette", "");
1111 }
1112
1113 /******************** texture paint toggle operator ********************/
1114
1115 static bool texture_paint_toggle_poll(bContext *C)
1116 {
1117   Object *ob = CTX_data_active_object(C);
1118   if (ob == NULL || ob->type != OB_MESH) {
1119     return 0;
1120   }
1121   if (!ob->data || ID_IS_LINKED(ob->data)) {
1122     return 0;
1123   }
1124   if (CTX_data_edit_object(C)) {
1125     return 0;
1126   }
1127
1128   return 1;
1129 }
1130
1131 static int texture_paint_toggle_exec(bContext *C, wmOperator *op)
1132 {
1133   struct wmMsgBus *mbus = CTX_wm_message_bus(C);
1134   Main *bmain = CTX_data_main(C);
1135   Scene *scene = CTX_data_scene(C);
1136   Object *ob = CTX_data_active_object(C);
1137   const int mode_flag = OB_MODE_TEXTURE_PAINT;
1138   const bool is_mode_set = (ob->mode & mode_flag) != 0;
1139
1140   if (!is_mode_set) {
1141     if (!ED_object_mode_compat_set(C, ob, mode_flag, op->reports)) {
1142       return OPERATOR_CANCELLED;
1143     }
1144   }
1145
1146   if (ob->mode & mode_flag) {
1147     ob->mode &= ~mode_flag;
1148
1149     if (U.glreslimit != 0) {
1150       GPU_free_images(bmain);
1151     }
1152     GPU_paint_set_mipmap(bmain, 1);
1153
1154     toggle_paint_cursor(C, 0);
1155   }
1156   else {
1157     bScreen *sc;
1158     Image *ima = NULL;
1159     ImagePaintSettings *imapaint = &scene->toolsettings->imapaint;
1160
1161     /* This has to stay here to regenerate the texture paint
1162      * cache in case we are loading a file */
1163     BKE_texpaint_slots_refresh_object(scene, ob);
1164
1165     BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL);
1166
1167     /* entering paint mode also sets image to editors */
1168     if (imapaint->mode == IMAGEPAINT_MODE_MATERIAL) {
1169       /* set the current material active paint slot on image editor */
1170       Material *ma = give_current_material(ob, ob->actcol);
1171
1172       if (ma && ma->texpaintslot) {
1173         ima = ma->texpaintslot[ma->paint_active_slot].ima;
1174       }
1175     }
1176     else if (imapaint->mode == IMAGEPAINT_MODE_IMAGE) {
1177       ima = imapaint->canvas;
1178     }
1179
1180     if (ima) {
1181       for (sc = bmain->screens.first; sc; sc = sc->id.next) {
1182         ScrArea *sa;
1183         for (sa = sc->areabase.first; sa; sa = sa->next) {
1184           SpaceLink *sl;
1185           for (sl = sa->spacedata.first; sl; sl = sl->next) {
1186             if (sl->spacetype == SPACE_IMAGE) {
1187               SpaceImage *sima = (SpaceImage *)sl;
1188
1189               if (!sima->pin) {
1190                 Object *obedit = CTX_data_edit_object(C);
1191                 ED_space_image_set(bmain, sima, obedit, ima, true);
1192               }
1193             }
1194           }
1195         }
1196       }
1197     }
1198
1199     ob->mode |= mode_flag;
1200
1201     BKE_paint_init(bmain, scene, PAINT_MODE_TEXTURE_3D, PAINT_CURSOR_TEXTURE_PAINT);
1202
1203     BKE_paint_toolslots_brush_validate(bmain, &imapaint->paint);
1204
1205     if (U.glreslimit != 0) {
1206       GPU_free_images(bmain);
1207     }
1208     GPU_paint_set_mipmap(bmain, 0);
1209
1210     toggle_paint_cursor(C, 1);
1211   }
1212
1213   Mesh *me = BKE_mesh_from_object(ob);
1214   BLI_assert(me != NULL);
1215   DEG_id_tag_update(&me->id, ID_RECALC_COPY_ON_WRITE);
1216
1217   WM_event_add_notifier(C, NC_SCENE | ND_MODE, scene);
1218
1219   WM_msg_publish_rna_prop(mbus, &ob->id, ob, Object, mode);
1220
1221   WM_toolsystem_update_from_context_view3d(C);
1222
1223   return OPERATOR_FINISHED;
1224 }
1225
1226 void PAINT_OT_texture_paint_toggle(wmOperatorType *ot)
1227 {
1228   /* identifiers */
1229   ot->name = "Texture Paint Toggle";
1230   ot->idname = "PAINT_OT_texture_paint_toggle";
1231   ot->description = "Toggle texture paint mode in 3D view";
1232
1233   /* api callbacks */
1234   ot->exec = texture_paint_toggle_exec;
1235   ot->poll = texture_paint_toggle_poll;
1236
1237   /* flags */
1238   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_USE_EVAL_DATA;
1239 }
1240
1241 static int brush_colors_flip_exec(bContext *C, wmOperator *UNUSED(op))
1242 {
1243   Scene *scene = CTX_data_scene(C);
1244   UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
1245
1246   ViewLayer *view_layer = CTX_data_view_layer(C);
1247   Paint *paint = BKE_paint_get_active(scene, view_layer);
1248   Brush *br = BKE_paint_brush(paint);
1249
1250   if (ups->flag & UNIFIED_PAINT_COLOR) {
1251     swap_v3_v3(ups->rgb, ups->secondary_rgb);
1252   }
1253   else if (br) {
1254     swap_v3_v3(br->rgb, br->secondary_rgb);
1255   }
1256   WM_event_add_notifier(C, NC_BRUSH | NA_EDITED, br);
1257
1258   return OPERATOR_FINISHED;
1259 }
1260
1261 static bool brush_colors_flip_poll(bContext *C)
1262 {
1263   if (image_paint_poll(C)) {
1264     Brush *br = image_paint_brush(C);
1265     if (ELEM(br->imagepaint_tool, PAINT_TOOL_DRAW, PAINT_TOOL_FILL)) {
1266       return true;
1267     }
1268   }
1269   else {
1270     Object *ob = CTX_data_active_object(C);
1271     if (ob != NULL) {
1272       if (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_TEXTURE_PAINT)) {
1273         return true;
1274       }
1275     }
1276   }
1277   return false;
1278 }
1279
1280 void PAINT_OT_brush_colors_flip(wmOperatorType *ot)
1281 {
1282   /* identifiers */
1283   ot->name = "Brush Colors Flip";
1284   ot->idname = "PAINT_OT_brush_colors_flip";
1285   ot->description = "Toggle foreground and background brush colors";
1286
1287   /* api callbacks */
1288   ot->exec = brush_colors_flip_exec;
1289   ot->poll = brush_colors_flip_poll;
1290
1291   /* flags */
1292   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1293 }
1294
1295 void ED_imapaint_bucket_fill(struct bContext *C, float color[3], wmOperator *op)
1296 {
1297   wmWindowManager *wm = CTX_wm_manager(C);
1298   SpaceImage *sima = CTX_wm_space_image(C);
1299   Image *ima = sima->image;
1300
1301   BKE_undosys_step_push_init_with_type(wm->undo_stack, C, op->type->name, BKE_UNDOSYS_TYPE_IMAGE);
1302
1303   ED_image_undo_push_begin(op->type->name, PAINT_MODE_TEXTURE_2D);
1304
1305   paint_2d_bucket_fill(C, color, NULL, NULL, NULL);
1306
1307   BKE_undosys_step_push(wm->undo_stack, C, op->type->name);
1308
1309   DEG_id_tag_update(&ima->id, 0);
1310 }
1311
1312 static bool texture_paint_poll(bContext *C)
1313 {
1314   if (texture_paint_toggle_poll(C)) {
1315     if (CTX_data_active_object(C)->mode & OB_MODE_TEXTURE_PAINT) {
1316       return 1;
1317     }
1318   }
1319
1320   return 0;
1321 }
1322
1323 bool image_texture_paint_poll(bContext *C)
1324 {
1325   return (texture_paint_poll(C) || image_paint_poll(C));
1326 }
1327
1328 bool facemask_paint_poll(bContext *C)
1329 {
1330   return BKE_paint_select_face_test(CTX_data_active_object(C));
1331 }
1332
1333 bool vert_paint_poll(bContext *C)
1334 {
1335   return BKE_paint_select_vert_test(CTX_data_active_object(C));
1336 }
1337
1338 bool mask_paint_poll(bContext *C)
1339 {
1340   return BKE_paint_select_elem_test(CTX_data_active_object(C));
1341 }