Code cleanup: indentation
[blender.git] / source / blender / editors / sculpt_paint / paint_image.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * along with this program; if not, write to the Free Software Foundation,
15  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16  *
17  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
18  * All rights reserved.
19  *
20  * The Original Code is: some of this file.
21  *
22  * Contributor(s): Jens Ole Wund (bjornmose), Campbell Barton (ideasman42)
23  *
24  * ***** END GPL LICENSE BLOCK *****
25  */
26
27 /** \file blender/editors/sculpt_paint/paint_image.c
28  *  \ingroup edsculpt
29  *  \brief Functions to paint images in 2D and 3D.
30  */
31
32 #include <float.h>
33 #include <string.h>
34 #include <stdio.h>
35 #include <math.h>
36
37 #include "MEM_guardedalloc.h"
38
39 #ifdef WIN32
40 #  include "BLI_winstuff.h"
41 #endif
42
43 #include "BLI_math.h"
44 #include "BLI_blenlib.h"
45 #include "BLI_utildefines.h"
46
47 #include "PIL_time.h"
48
49 #include "IMB_imbuf.h"
50 #include "IMB_imbuf_types.h"
51
52 #include "DNA_brush_types.h"
53 #include "DNA_mesh_types.h"
54 #include "DNA_node_types.h"
55 #include "DNA_object_types.h"
56
57 #include "BKE_context.h"
58 #include "BKE_depsgraph.h"
59 #include "BKE_brush.h"
60 #include "BKE_image.h"
61 #include "BKE_main.h"
62 #include "BKE_mesh.h"
63 #include "BKE_node.h"
64 #include "BKE_paint.h"
65
66 #include "BKE_editmesh.h"
67
68 #include "UI_view2d.h"
69
70 #include "ED_image.h"
71 #include "ED_object.h"
72 #include "ED_screen.h"
73 #include "ED_sculpt.h"
74 #include "ED_view3d.h"
75
76 #include "WM_api.h"
77 #include "WM_types.h"
78
79 #include "RNA_access.h"
80 #include "RNA_define.h"
81 #include "RNA_enum_types.h"
82
83 #include "GPU_draw.h"
84
85 #include "IMB_colormanagement.h"
86
87 #include "paint_intern.h"
88
89 typedef struct UndoImageTile {
90         struct UndoImageTile *next, *prev;
91
92         char idname[MAX_ID_NAME];  /* name instead of pointer*/
93         char ibufname[IB_FILENAME_SIZE];
94
95         union {
96                 float        *fp;
97                 unsigned int *uint;
98                 void         *pt;
99         } rect;
100
101         unsigned short *mask;
102
103         int x, y;
104
105         short source, use_float;
106         char gen_type;
107 } UndoImageTile;
108
109 /* this is a static resource for non-globality,
110  * Maybe it should be exposed as part of the
111  * paint operation, but for now just give a public interface */
112 static ImagePaintPartialRedraw imapaintpartial = {0, 0, 0, 0, 0};
113
114 ImagePaintPartialRedraw *get_imapaintpartial(void)
115 {
116         return &imapaintpartial;
117 }
118
119 void set_imapaintpartial(struct ImagePaintPartialRedraw *ippr)
120 {
121         imapaintpartial = *ippr;
122 }
123
124 /* UNDO */
125
126 static void undo_copy_tile(UndoImageTile *tile, ImBuf *tmpibuf, ImBuf *ibuf, int restore)
127 {
128         /* copy or swap contents of tile->rect and region in ibuf->rect */
129         IMB_rectcpy(tmpibuf, ibuf, 0, 0, tile->x * IMAPAINT_TILE_SIZE,
130                     tile->y * IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE);
131
132         if (ibuf->rect_float) {
133                 SWAP(float *, tmpibuf->rect_float, tile->rect.fp);
134         }
135         else {
136                 SWAP(unsigned int *, tmpibuf->rect, tile->rect.uint);
137         }
138         
139         if (restore)
140                 IMB_rectcpy(ibuf, tmpibuf, tile->x * IMAPAINT_TILE_SIZE,
141                             tile->y * IMAPAINT_TILE_SIZE, 0, 0, IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE);
142 }
143
144 void *image_undo_find_tile(Image *ima, ImBuf *ibuf, int x_tile, int y_tile, unsigned short **mask)
145 {
146         ListBase *lb = undo_paint_push_get_list(UNDO_PAINT_IMAGE);
147         UndoImageTile *tile;
148         short use_float = ibuf->rect_float ? 1 : 0;
149
150         for (tile = lb->first; tile; tile = tile->next) {
151                 if (tile->x == x_tile && tile->y == y_tile && ima->gen_type == tile->gen_type && ima->source == tile->source) {
152                         if (tile->use_float == use_float) {
153                                 if (strcmp(tile->idname, ima->id.name) == 0 && strcmp(tile->ibufname, ibuf->name) == 0) {
154                                         if (mask) {
155                                                 /* allocate mask if requested */
156                                                 if (!tile->mask) {
157                                                         tile->mask = MEM_callocN(sizeof(unsigned short) * IMAPAINT_TILE_SIZE * IMAPAINT_TILE_SIZE,
158                                                                                  "UndoImageTile.mask");
159                                                 }
160
161                                                 *mask = tile->mask;
162                                         }
163
164                                         return tile->rect.pt;
165                                 }
166                         }
167                 }
168         }
169         
170         return NULL;
171 }
172
173 void *image_undo_push_tile(Image *ima, ImBuf *ibuf, ImBuf **tmpibuf, int x_tile, int y_tile)
174 {
175         ListBase *lb = undo_paint_push_get_list(UNDO_PAINT_IMAGE);
176         UndoImageTile *tile;
177         int allocsize;
178         short use_float = ibuf->rect_float ? 1 : 0;
179         void *data;
180
181         /* check if tile is already pushed */
182         data = image_undo_find_tile(ima, ibuf, x_tile, y_tile, NULL);
183         if (data)
184                 return data;
185         
186         if (*tmpibuf == NULL)
187                 *tmpibuf = IMB_allocImBuf(IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE, 32, IB_rectfloat | IB_rect);
188         
189         tile = MEM_callocN(sizeof(UndoImageTile), "UndoImageTile");
190         BLI_strncpy(tile->idname, ima->id.name, sizeof(tile->idname));
191         tile->x = x_tile;
192         tile->y = y_tile;
193
194         allocsize = IMAPAINT_TILE_SIZE * IMAPAINT_TILE_SIZE * 4;
195         allocsize *= (ibuf->rect_float) ? sizeof(float) : sizeof(char);
196         tile->rect.pt = MEM_mapallocN(allocsize, "UndeImageTile.rect");
197
198         BLI_strncpy(tile->ibufname, ibuf->name, sizeof(tile->ibufname));
199
200         tile->gen_type = ima->gen_type;
201         tile->source = ima->source;
202         tile->use_float = use_float;
203
204         undo_copy_tile(tile, *tmpibuf, ibuf, 0);
205         undo_paint_push_count_alloc(UNDO_PAINT_IMAGE, allocsize);
206
207         BLI_addtail(lb, tile);
208         
209         return tile->rect.pt;
210 }
211
212 void image_undo_remove_masks(void)
213 {
214         ListBase *lb = undo_paint_push_get_list(UNDO_PAINT_IMAGE);
215         UndoImageTile *tile;
216
217         for (tile = lb->first; tile; tile = tile->next) {
218                 if (tile->mask) {
219                         MEM_freeN(tile->mask);
220                         tile->mask = NULL;
221                 }
222         }
223 }
224
225 void ED_image_undo_restore(bContext *C, ListBase *lb)
226 {
227         Main *bmain = CTX_data_main(C);
228         Image *ima = NULL;
229         ImBuf *ibuf, *tmpibuf;
230         UndoImageTile *tile;
231
232         tmpibuf = IMB_allocImBuf(IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE, 32,
233                                  IB_rectfloat | IB_rect);
234
235         for (tile = lb->first; tile; tile = tile->next) {
236                 short use_float;
237
238                 /* find image based on name, pointer becomes invalid with global undo */
239                 if (ima && strcmp(tile->idname, ima->id.name) == 0) {
240                         /* ima is valid */
241                 }
242                 else {
243                         ima = BLI_findstring(&bmain->image, tile->idname, offsetof(ID, name));
244                 }
245
246                 ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
247
248                 if (ima && ibuf && strcmp(tile->ibufname, ibuf->name) != 0) {
249                         /* current ImBuf filename was changed, probably current frame
250                          * was changed when paiting on image sequence, rather than storing
251                          * full image user (which isn't so obvious, btw) try to find ImBuf with
252                          * matched file name in list of already loaded images */
253
254                         BKE_image_release_ibuf(ima, ibuf, NULL);
255
256                         ibuf = BKE_image_get_ibuf_with_name(ima, tile->ibufname);
257                 }
258
259                 if (!ima || !ibuf || !(ibuf->rect || ibuf->rect_float)) {
260                         BKE_image_release_ibuf(ima, ibuf, NULL);
261                         continue;
262                 }
263
264                 if (ima->gen_type != tile->gen_type || ima->source != tile->source) {
265                         BKE_image_release_ibuf(ima, ibuf, NULL);
266                         continue;
267                 }
268
269                 use_float = ibuf->rect_float ? 1 : 0;
270
271                 if (use_float != tile->use_float) {
272                         BKE_image_release_ibuf(ima, ibuf, NULL);
273                         continue;
274                 }
275
276                 undo_copy_tile(tile, tmpibuf, ibuf, 1);
277
278                 GPU_free_image(ima); /* force OpenGL reload */
279                 if (ibuf->rect_float)
280                         ibuf->userflags |= IB_RECT_INVALID; /* force recreate of char rect */
281                 if (ibuf->mipmap[0])
282                         ibuf->userflags |= IB_MIPMAP_INVALID;  /* force mipmap recreatiom */
283                 ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
284
285                 BKE_image_release_ibuf(ima, ibuf, NULL);
286         }
287
288         IMB_freeImBuf(tmpibuf);
289 }
290
291 void ED_image_undo_free(ListBase *lb)
292 {
293         UndoImageTile *tile;
294
295         for (tile = lb->first; tile; tile = tile->next)
296                 MEM_freeN(tile->rect.pt);
297 }
298
299 /* Imagepaint Partial Redraw & Dirty Region */
300
301 void ED_imapaint_clear_partial_redraw(void)
302 {
303         memset(&imapaintpartial, 0, sizeof(imapaintpartial));
304 }
305
306 void imapaint_region_tiles(ImBuf *ibuf, int x, int y, int w, int h, int *tx, int *ty, int *tw, int *th)
307 {
308         int srcx = 0, srcy = 0;
309
310         IMB_rectclip(ibuf, NULL, &x, &y, &srcx, &srcy, &w, &h);
311
312         *tw = ((x + w - 1) >> IMAPAINT_TILE_BITS);
313         *th = ((y + h - 1) >> IMAPAINT_TILE_BITS);
314         *tx = (x >> IMAPAINT_TILE_BITS);
315         *ty = (y >> IMAPAINT_TILE_BITS);
316 }
317
318 void ED_imapaint_dirty_region(Image *ima, ImBuf *ibuf, int x, int y, int w, int h)
319 {
320         ImBuf *tmpibuf = NULL;
321         int tilex, tiley, tilew, tileh, tx, ty;
322         int srcx = 0, srcy = 0;
323
324         IMB_rectclip(ibuf, NULL, &x, &y, &srcx, &srcy, &w, &h);
325
326         if (w == 0 || h == 0)
327                 return;
328         
329         if (!imapaintpartial.enabled) {
330                 imapaintpartial.x1 = x;
331                 imapaintpartial.y1 = y;
332                 imapaintpartial.x2 = x + w;
333                 imapaintpartial.y2 = y + h;
334                 imapaintpartial.enabled = 1;
335         }
336         else {
337                 imapaintpartial.x1 = min_ii(imapaintpartial.x1, x);
338                 imapaintpartial.y1 = min_ii(imapaintpartial.y1, y);
339                 imapaintpartial.x2 = max_ii(imapaintpartial.x2, x + w);
340                 imapaintpartial.y2 = max_ii(imapaintpartial.y2, y + h);
341         }
342
343         imapaint_region_tiles(ibuf, x, y, w, h, &tilex, &tiley, &tilew, &tileh);
344
345         for (ty = tiley; ty <= tileh; ty++)
346                 for (tx = tilex; tx <= tilew; tx++)
347                         image_undo_push_tile(ima, ibuf, &tmpibuf, tx, ty);
348
349         ibuf->userflags |= IB_BITMAPDIRTY;
350         
351         if (tmpibuf)
352                 IMB_freeImBuf(tmpibuf);
353 }
354
355 void imapaint_image_update(SpaceImage *sima, Image *image, ImBuf *ibuf, short texpaint)
356 {
357         if (imapaintpartial.x1 != imapaintpartial.x2 &&
358             imapaintpartial.y1 != imapaintpartial.y2)
359         {
360                 IMB_partial_display_buffer_update_delayed(ibuf, imapaintpartial.x1, imapaintpartial.y1,
361                                                           imapaintpartial.x2, imapaintpartial.y2);
362         }
363         
364         if (ibuf->mipmap[0])
365                 ibuf->userflags |= IB_MIPMAP_INVALID;
366
367         /* todo: should set_tpage create ->rect? */
368         if (texpaint || (sima && sima->lock)) {
369                 int w = imapaintpartial.x2 - imapaintpartial.x1;
370                 int h = imapaintpartial.y2 - imapaintpartial.y1;
371                 /* Testing with partial update in uv editor too */
372                 GPU_paint_update_image(image, imapaintpartial.x1, imapaintpartial.y1, w, h); //!texpaint);
373         }
374 }
375
376 /************************ image paint poll ************************/
377
378 static Brush *image_paint_brush(bContext *C)
379 {
380         Scene *scene = CTX_data_scene(C);
381         ToolSettings *settings = scene->toolsettings;
382
383         return BKE_paint_brush(&settings->imapaint.paint);
384 }
385
386 static int image_paint_poll(bContext *C)
387 {
388         Object *obact = CTX_data_active_object(C);
389
390         if (!image_paint_brush(C))
391                 return 0;
392
393         if ((obact && obact->mode & OB_MODE_TEXTURE_PAINT) && CTX_wm_region_view3d(C)) {
394                 return 1;
395         }
396         else {
397                 SpaceImage *sima = CTX_wm_space_image(C);
398
399                 if (sima) {
400                         ARegion *ar = CTX_wm_region(C);
401
402                         if ((sima->mode == SI_MODE_PAINT) && ar->regiontype == RGN_TYPE_WINDOW) {
403                                 return 1;
404                         }
405                 }
406         }
407
408         return 0;
409 }
410
411 static int image_paint_2d_clone_poll(bContext *C)
412 {
413         Brush *brush = image_paint_brush(C);
414
415         if (!CTX_wm_region_view3d(C) && image_paint_poll(C))
416                 if (brush && (brush->imagepaint_tool == PAINT_TOOL_CLONE))
417                         if (brush->clone.image)
418                                 return 1;
419         
420         return 0;
421 }
422
423 /************************ paint operator ************************/
424 typedef enum TexPaintMode {
425         PAINT_MODE_2D,
426         PAINT_MODE_3D_PROJECT
427 } TexPaintMode;
428
429 typedef struct PaintOperation {
430         TexPaintMode mode;
431
432         void *custom_paint;
433
434         float prevmouse[2];
435         double starttime;
436
437         ViewContext vc;
438 } PaintOperation;
439
440 void paint_brush_init_tex(Brush *brush)
441 {
442         /* init mtex nodes */
443         if (brush) {
444                 MTex *mtex = &brush->mtex;
445                 if (mtex->tex && mtex->tex->nodetree)
446                         ntreeTexBeginExecTree(mtex->tex->nodetree);  /* has internal flag to detect it only does it once */
447                 mtex = &brush->mask_mtex;
448                 if (mtex->tex && mtex->tex->nodetree)
449                         ntreeTexBeginExecTree(mtex->tex->nodetree);
450         }
451 }
452
453 void paint_brush_exit_tex(Brush *brush)
454 {
455         if (brush) {
456                 MTex *mtex = &brush->mtex;
457                 if (mtex->tex && mtex->tex->nodetree)
458                         ntreeTexEndExecTree(mtex->tex->nodetree->execdata);
459                 mtex = &brush->mask_mtex;
460                 if (mtex->tex && mtex->tex->nodetree)
461                         ntreeTexEndExecTree(mtex->tex->nodetree->execdata);
462         }
463 }
464
465
466 static PaintOperation *texture_paint_init(bContext *C, wmOperator *op, float mouse[2])
467 {
468         Scene *scene = CTX_data_scene(C);
469         ToolSettings *settings = scene->toolsettings;
470         PaintOperation *pop = MEM_callocN(sizeof(PaintOperation), "PaintOperation"); /* caller frees */
471         int mode = RNA_enum_get(op->ptr, "mode");
472         view3d_set_viewcontext(C, &pop->vc);
473
474         pop->prevmouse[0] = mouse[0];
475         pop->prevmouse[1] = mouse[1];
476
477         /* initialize from context */
478         if (CTX_wm_region_view3d(C)) {
479                 pop->mode = PAINT_MODE_3D_PROJECT;
480                 pop->custom_paint = paint_proj_new_stroke(C, OBACT, pop->prevmouse, mode);
481         }
482         else {
483                 pop->mode = PAINT_MODE_2D;
484                 pop->custom_paint = paint_2d_new_stroke(C, op);
485         }
486
487         if (!pop->custom_paint) {
488                 MEM_freeN(pop);
489                 return NULL;
490         }
491
492         settings->imapaint.flag |= IMAGEPAINT_DRAWING;
493         ED_undo_paint_push_begin(UNDO_PAINT_IMAGE, op->type->name,
494                                  ED_image_undo_restore, ED_image_undo_free);
495
496         {
497                 UnifiedPaintSettings *ups = &settings->unified_paint_settings;
498                 ups->stroke_active = true;
499         }
500
501         return pop;
502 }
503
504 static void paint_stroke_update_step(bContext *C, struct PaintStroke *stroke, PointerRNA *itemptr)
505 {
506         PaintOperation *pop = paint_stroke_mode_data(stroke);
507         Scene *scene = CTX_data_scene(C);
508         Brush *brush = BKE_paint_brush(&scene->toolsettings->imapaint.paint);
509
510         /* initial brush values. Maybe it should be considered moving these to stroke system */
511         float startsize = (float)BKE_brush_size_get(scene, brush);
512         float startalpha = BKE_brush_alpha_get(scene, brush);
513
514         float mouse[2];
515         float pressure;
516         int eraser;
517
518         RNA_float_get_array(itemptr, "mouse", mouse);
519         pressure = RNA_float_get(itemptr, "pressure");
520         eraser = RNA_boolean_get(itemptr, "pen_flip");
521
522         if (BKE_brush_use_alpha_pressure(scene, brush))
523                 BKE_brush_alpha_set(scene, brush, max_ff(0.0f, startalpha * pressure));
524         if (BKE_brush_use_size_pressure(scene, brush))
525                 BKE_brush_size_set(scene, brush, (int)max_ff(1.0f, startsize * pressure));
526
527         if (pop->mode == PAINT_MODE_3D_PROJECT) {
528                 paint_proj_stroke(C, pop->custom_paint, pop->prevmouse, mouse);
529         }
530         else {
531                 paint_2d_stroke(pop->custom_paint, pop->prevmouse, mouse, eraser);
532         }
533
534         pop->prevmouse[0] = mouse[0];
535         pop->prevmouse[1] = mouse[1];
536
537         /* restore brush values */
538         BKE_brush_alpha_set(scene, brush, startalpha);
539         BKE_brush_size_set(scene, brush, startsize);
540 }
541
542 static void paint_stroke_redraw(const bContext *C, struct PaintStroke *stroke, bool final)
543 {
544         PaintOperation *pop = paint_stroke_mode_data(stroke);
545
546         if (pop->mode == PAINT_MODE_3D_PROJECT) {
547                 paint_proj_redraw(C, pop->custom_paint, final);
548         }
549         else {
550                 paint_2d_redraw(C, pop->custom_paint, final);
551         }
552 }
553
554 static void paint_stroke_done(const bContext *C, struct PaintStroke *stroke)
555 {
556         Scene *scene = CTX_data_scene(C);
557         ToolSettings *settings = scene->toolsettings;
558         PaintOperation *pop = paint_stroke_mode_data(stroke);
559
560         settings->imapaint.flag &= ~IMAGEPAINT_DRAWING;
561
562         if (pop->mode == PAINT_MODE_3D_PROJECT) {
563                 paint_proj_stroke_done(pop->custom_paint);
564         }
565         else {
566                 paint_2d_stroke_done(pop->custom_paint);
567         }
568
569         ED_undo_paint_push_end(UNDO_PAINT_IMAGE);
570
571         /* duplicate warning, see texpaint_init */
572 #if 0
573         if (pop->s.warnmultifile)
574                 BKE_reportf(op->reports, RPT_WARNING, "Image requires 4 color channels to paint: %s", pop->s.warnmultifile);
575         if (pop->s.warnpackedfile)
576                 BKE_reportf(op->reports, RPT_WARNING, "Packed MultiLayer files cannot be painted: %s", pop->s.warnpackedfile);
577 #endif
578         MEM_freeN(pop);
579
580         {
581                 UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
582                 ups->stroke_active = false;
583         }
584 }
585
586 static bool paint_stroke_test_start(bContext *UNUSED(C), wmOperator *UNUSED(op), const float UNUSED(mouse[2]))
587 {
588         return true;
589 }
590
591
592 static int paint_invoke(bContext *C, wmOperator *op, const wmEvent *event)
593 {
594         PaintOperation *pop;
595         float mouse[2];
596         int retval;
597
598         /* TODO Should avoid putting this here. Instead, last position should be requested
599          * from stroke system. */
600         mouse[0] = event->mval[0];
601         mouse[1] = event->mval[1];
602
603         if (!(pop = texture_paint_init(C, op, mouse))) {
604                 return OPERATOR_CANCELLED;
605         }
606
607         op->customdata = paint_stroke_new(C, NULL, paint_stroke_test_start,
608                                           paint_stroke_update_step,
609                                           paint_stroke_redraw,
610                                           paint_stroke_done, event->type);
611         paint_stroke_set_mode_data(op->customdata, pop);
612         /* add modal handler */
613         WM_event_add_modal_handler(C, op);
614
615         retval = op->type->modal(C, op, event);
616         OPERATOR_RETVAL_CHECK(retval);
617         BLI_assert(retval == OPERATOR_RUNNING_MODAL);
618
619         return OPERATOR_RUNNING_MODAL;
620 }
621
622 static int paint_exec(bContext *C, wmOperator *op)
623 {
624         PaintOperation *pop;
625         PropertyRNA *strokeprop;
626         PointerRNA firstpoint;
627         float mouse[2];
628
629         strokeprop = RNA_struct_find_property(op->ptr, "stroke");
630
631         if (!RNA_property_collection_lookup_int(op->ptr, strokeprop, 0, &firstpoint))
632                 return OPERATOR_CANCELLED;
633
634         RNA_float_get_array(&firstpoint, "mouse", mouse);
635
636         if (!(pop = texture_paint_init(C, op, mouse))) {
637                 return OPERATOR_CANCELLED;
638         }
639
640         op->customdata = paint_stroke_new(C, NULL, paint_stroke_test_start,
641                                           paint_stroke_update_step,
642                                           paint_stroke_redraw,
643                                           paint_stroke_done, 0);
644         paint_stroke_set_mode_data(op->customdata, pop);
645
646         /* frees op->customdata */
647         paint_stroke_exec(C, op);
648
649         return OPERATOR_FINISHED;
650 }
651
652 void PAINT_OT_image_paint(wmOperatorType *ot)
653 {
654         static EnumPropertyItem stroke_mode_items[] = {
655                 {BRUSH_STROKE_NORMAL, "NORMAL", 0, "Normal", "Apply brush normally"},
656                 {BRUSH_STROKE_INVERT, "INVERT", 0, "Invert", "Invert action of brush for duration of stroke"},
657                 {0}
658         };
659
660         /* identifiers */
661         ot->name = "Image Paint";
662         ot->idname = "PAINT_OT_image_paint";
663         ot->description = "Paint a stroke into the image";
664
665         /* api callbacks */
666         ot->invoke = paint_invoke;
667         ot->modal = paint_stroke_modal;
668         ot->exec = paint_exec;
669         ot->poll = image_paint_poll;
670         ot->cancel = paint_stroke_cancel;
671
672         /* flags */
673         ot->flag = OPTYPE_BLOCKING;
674
675         RNA_def_enum(ot->srna, "mode", stroke_mode_items, BRUSH_STROKE_NORMAL,
676                      "Paint Stroke Mode",
677                      "Action taken when a paint stroke is made");
678
679         RNA_def_collection_runtime(ot->srna, "stroke", &RNA_OperatorStrokeElement, "Stroke", "");
680 }
681
682
683 int get_imapaint_zoom(bContext *C, float *zoomx, float *zoomy)
684 {
685         RegionView3D *rv3d = CTX_wm_region_view3d(C);
686
687         if (!rv3d) {
688                 SpaceImage *sima = CTX_wm_space_image(C);
689                 ARegion *ar = CTX_wm_region(C);
690
691                 if (sima->mode == SI_MODE_PAINT) {
692                         ED_space_image_get_zoom(sima, ar, zoomx, zoomy);
693
694                         return 1;
695                 }
696         }
697
698         *zoomx = *zoomy = 1;
699
700         return 0;
701 }
702
703 /************************ cursor drawing *******************************/
704
705 static void toggle_paint_cursor(bContext *C, int enable)
706 {
707         wmWindowManager *wm = CTX_wm_manager(C);
708         Scene *scene = CTX_data_scene(C);
709         ToolSettings *settings = scene->toolsettings;
710
711         if (settings->imapaint.paintcursor && !enable) {
712                 WM_paint_cursor_end(wm, settings->imapaint.paintcursor);
713                 settings->imapaint.paintcursor = NULL;
714                 paint_cursor_delete_textures();
715         }
716         else if (enable)
717                 paint_cursor_start(C, image_paint_poll);
718 }
719
720 /* enable the paint cursor if it isn't already.
721  *
722  * purpose is to make sure the paint cursor is shown if paint
723  * mode is enabled in the image editor. the paint poll will
724  * ensure that the cursor is hidden when not in paint mode */
725 void ED_space_image_paint_update(wmWindowManager *wm, ToolSettings *settings)
726 {
727         wmWindow *win;
728         ScrArea *sa;
729         ImagePaintSettings *imapaint = &settings->imapaint;
730         bool enabled = false;
731
732         for (win = wm->windows.first; win; win = win->next)
733                 for (sa = win->screen->areabase.first; sa; sa = sa->next)
734                         if (sa->spacetype == SPACE_IMAGE)
735                                 if (((SpaceImage *)sa->spacedata.first)->mode == SI_MODE_PAINT)
736                                         enabled = true;
737
738         if (enabled) {
739                 BKE_paint_init(&imapaint->paint, PAINT_CURSOR_TEXTURE_PAINT);
740
741                 paint_cursor_start_explicit(&imapaint->paint, wm, image_paint_poll);
742         }
743         else {
744                 paint_cursor_delete_textures();
745         }
746 }
747
748 /************************ grab clone operator ************************/
749
750 typedef struct GrabClone {
751         float startoffset[2];
752         int startx, starty;
753 } GrabClone;
754
755 static void grab_clone_apply(bContext *C, wmOperator *op)
756 {
757         Brush *brush = image_paint_brush(C);
758         float delta[2];
759
760         RNA_float_get_array(op->ptr, "delta", delta);
761         add_v2_v2(brush->clone.offset, delta);
762         ED_region_tag_redraw(CTX_wm_region(C));
763 }
764
765 static int grab_clone_exec(bContext *C, wmOperator *op)
766 {
767         grab_clone_apply(C, op);
768
769         return OPERATOR_FINISHED;
770 }
771
772 static int grab_clone_invoke(bContext *C, wmOperator *op, const wmEvent *event)
773 {
774         Brush *brush = image_paint_brush(C);
775         GrabClone *cmv;
776
777         cmv = MEM_callocN(sizeof(GrabClone), "GrabClone");
778         copy_v2_v2(cmv->startoffset, brush->clone.offset);
779         cmv->startx = event->x;
780         cmv->starty = event->y;
781         op->customdata = cmv;
782
783         WM_event_add_modal_handler(C, op);
784
785         return OPERATOR_RUNNING_MODAL;
786 }
787
788 static int grab_clone_modal(bContext *C, wmOperator *op, const wmEvent *event)
789 {
790         Brush *brush = image_paint_brush(C);
791         ARegion *ar = CTX_wm_region(C);
792         GrabClone *cmv = op->customdata;
793         float startfx, startfy, fx, fy, delta[2];
794         int xmin = ar->winrct.xmin, ymin = ar->winrct.ymin;
795
796         switch (event->type) {
797                 case LEFTMOUSE:
798                 case MIDDLEMOUSE:
799                 case RIGHTMOUSE: // XXX hardcoded
800                         MEM_freeN(op->customdata);
801                         return OPERATOR_FINISHED;
802                 case MOUSEMOVE:
803                         /* mouse moved, so move the clone image */
804                         UI_view2d_region_to_view(&ar->v2d, cmv->startx - xmin, cmv->starty - ymin, &startfx, &startfy);
805                         UI_view2d_region_to_view(&ar->v2d, event->x - xmin, event->y - ymin, &fx, &fy);
806
807                         delta[0] = fx - startfx;
808                         delta[1] = fy - startfy;
809                         RNA_float_set_array(op->ptr, "delta", delta);
810
811                         copy_v2_v2(brush->clone.offset, cmv->startoffset);
812
813                         grab_clone_apply(C, op);
814                         break;
815         }
816
817         return OPERATOR_RUNNING_MODAL;
818 }
819
820 static void grab_clone_cancel(bContext *UNUSED(C), wmOperator *op)
821 {
822         MEM_freeN(op->customdata);
823 }
824
825 void PAINT_OT_grab_clone(wmOperatorType *ot)
826 {
827         /* identifiers */
828         ot->name = "Grab Clone";
829         ot->idname = "PAINT_OT_grab_clone";
830         ot->description = "Move the clone source image";
831         
832         /* api callbacks */
833         ot->exec = grab_clone_exec;
834         ot->invoke = grab_clone_invoke;
835         ot->modal = grab_clone_modal;
836         ot->cancel = grab_clone_cancel;
837         ot->poll = image_paint_2d_clone_poll;
838
839         /* flags */
840         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING;
841
842         /* properties */
843         RNA_def_float_vector(ot->srna, "delta", 2, NULL, -FLT_MAX, FLT_MAX, "Delta", "Delta offset of clone image in 0.0..1.0 coordinates", -1.0f, 1.0f);
844 }
845
846 /******************** sample color operator ********************/
847 typedef struct {
848         bool show_cursor;
849         short event_type;
850 } SampleColorData;
851
852 static int sample_color_exec(bContext *C, wmOperator *op)
853 {
854         Paint *paint = BKE_paint_get_active_from_context(C);
855         Brush *brush = BKE_paint_brush(paint);
856         ARegion *ar = CTX_wm_region(C);
857         wmWindow *win = CTX_wm_window(C);
858         bool show_cursor = ((paint->flags & PAINT_SHOW_BRUSH) != 0);
859         int location[2];
860
861         paint->flags &= ~PAINT_SHOW_BRUSH;
862
863         /* force redraw without cursor */
864         WM_paint_cursor_tag_redraw(win, ar);
865         WM_redraw_windows(C);
866
867         RNA_int_get_array(op->ptr, "location", location);
868         paint_sample_color(C, ar, location[0], location[1]);
869
870         if (show_cursor) {
871                 paint->flags |= PAINT_SHOW_BRUSH;
872         }
873
874         WM_event_add_notifier(C, NC_BRUSH | NA_EDITED, brush);
875         
876         return OPERATOR_FINISHED;
877 }
878
879 static int sample_color_invoke(bContext *C, wmOperator *op, const wmEvent *event)
880 {
881         Paint *paint = BKE_paint_get_active_from_context(C);
882         Brush *brush = BKE_paint_brush(paint);
883         SampleColorData *data = MEM_mallocN(sizeof(SampleColorData), "sample color custom data");
884         ARegion *ar = CTX_wm_region(C);
885         wmWindow *win = CTX_wm_window(C);
886
887         data->event_type = event->type;
888         data->show_cursor = ((paint->flags & PAINT_SHOW_BRUSH) != 0);
889         op->customdata = data;
890         paint->flags &= ~PAINT_SHOW_BRUSH;
891
892         /* force redraw without cursor */
893         WM_paint_cursor_tag_redraw(win, ar);
894         WM_redraw_windows(C);
895
896         RNA_int_set_array(op->ptr, "location", event->mval);
897         paint_sample_color(C, ar, event->mval[0], event->mval[1]);
898         WM_cursor_modal_set(win, BC_EYEDROPPER_CURSOR);
899
900         WM_event_add_modal_handler(C, op);
901         WM_event_add_notifier(C, NC_BRUSH | NA_EDITED, brush);
902
903         return OPERATOR_RUNNING_MODAL;
904 }
905
906 static int sample_color_modal(bContext *C, wmOperator *op, const wmEvent *event)
907 {
908         SampleColorData *data = op->customdata;
909         Paint *paint = BKE_paint_get_active_from_context(C);
910         Brush *brush = BKE_paint_brush(paint);
911
912         if ((event->type == data->event_type) && (event->val == KM_RELEASE)) {
913                 if (data->show_cursor) {
914                         paint->flags |= PAINT_SHOW_BRUSH;
915                 }
916
917                 WM_cursor_modal_restore(CTX_wm_window(C));
918                 MEM_freeN(data);
919                 return OPERATOR_FINISHED;
920         }
921
922         switch (event->type) {
923                 case MOUSEMOVE:
924                 {
925                         ARegion *ar = CTX_wm_region(C);
926                         RNA_int_set_array(op->ptr, "location", event->mval);
927                         paint_sample_color(C, ar, event->mval[0], event->mval[1]);
928                         WM_event_add_notifier(C, NC_BRUSH | NA_EDITED, brush);
929                         break;
930                 }
931         }
932
933         return OPERATOR_RUNNING_MODAL;
934 }
935
936 static int sample_color_poll(bContext *C)
937 {
938         return (image_paint_poll(C) || vertex_paint_poll(C));
939 }
940
941 void PAINT_OT_sample_color(wmOperatorType *ot)
942 {
943         /* identifiers */
944         ot->name = "Sample Color";
945         ot->idname = "PAINT_OT_sample_color";
946         ot->description = "Use the mouse to sample a color in the image";
947         
948         /* api callbacks */
949         ot->exec = sample_color_exec;
950         ot->invoke = sample_color_invoke;
951         ot->modal = sample_color_modal;
952         ot->poll = sample_color_poll;
953
954         /* flags */
955         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
956
957         /* properties */
958         RNA_def_int_vector(ot->srna, "location", 2, NULL, 0, INT_MAX, "Location", "Cursor location in region coordinates", 0, 16384);
959 }
960
961 /******************** texture paint toggle operator ********************/
962
963 static int texture_paint_toggle_poll(bContext *C)
964 {
965         Object *ob = CTX_data_active_object(C);
966         if (ob == NULL || ob->type != OB_MESH)
967                 return 0;
968         if (!ob->data || ((ID *)ob->data)->lib)
969                 return 0;
970         if (CTX_data_edit_object(C))
971                 return 0;
972
973         return 1;
974 }
975
976 static int texture_paint_toggle_exec(bContext *C, wmOperator *op)
977 {
978         Scene *scene = CTX_data_scene(C);
979         Object *ob = CTX_data_active_object(C);
980         const int mode_flag = OB_MODE_TEXTURE_PAINT;
981         const bool is_mode_set = (ob->mode & mode_flag) != 0;
982         Mesh *me;
983
984         if (!is_mode_set) {
985                 if (!ED_object_mode_compat_set(C, ob, mode_flag, op->reports)) {
986                         return OPERATOR_CANCELLED;
987                 }
988         }
989
990         me = BKE_mesh_from_object(ob);
991
992         if (ob->mode & mode_flag) {
993                 ob->mode &= ~mode_flag;
994
995                 if (U.glreslimit != 0)
996                         GPU_free_images();
997                 GPU_paint_set_mipmap(1);
998
999                 toggle_paint_cursor(C, 0);
1000         }
1001         else {
1002                 ob->mode |= mode_flag;
1003
1004                 if (me->mtface == NULL)
1005                         me->mtface = CustomData_add_layer(&me->fdata, CD_MTFACE, CD_DEFAULT,
1006                                                           NULL, me->totface);
1007
1008                 BKE_paint_init(&scene->toolsettings->imapaint.paint, PAINT_CURSOR_TEXTURE_PAINT);
1009
1010                 if (U.glreslimit != 0)
1011                         GPU_free_images();
1012                 GPU_paint_set_mipmap(0);
1013
1014                 toggle_paint_cursor(C, 1);
1015         }
1016
1017         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
1018         WM_event_add_notifier(C, NC_SCENE | ND_MODE, scene);
1019
1020         return OPERATOR_FINISHED;
1021 }
1022
1023 void PAINT_OT_texture_paint_toggle(wmOperatorType *ot)
1024 {
1025         /* identifiers */
1026         ot->name = "Texture Paint Toggle";
1027         ot->idname = "PAINT_OT_texture_paint_toggle";
1028         ot->description = "Toggle texture paint mode in 3D view";
1029         
1030         /* api callbacks */
1031         ot->exec = texture_paint_toggle_exec;
1032         ot->poll = texture_paint_toggle_poll;
1033
1034         /* flags */
1035         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1036 }
1037
1038 static int texture_paint_poll(bContext *C)
1039 {
1040         if (texture_paint_toggle_poll(C))
1041                 if (CTX_data_active_object(C)->mode & OB_MODE_TEXTURE_PAINT)
1042                         return 1;
1043         
1044         return 0;
1045 }
1046
1047 int image_texture_paint_poll(bContext *C)
1048 {
1049         return (texture_paint_poll(C) || image_paint_poll(C));
1050 }
1051
1052 int facemask_paint_poll(bContext *C)
1053 {
1054         return BKE_paint_select_face_test(CTX_data_active_object(C));
1055 }
1056
1057 int vert_paint_poll(bContext *C)
1058 {
1059         return BKE_paint_select_vert_test(CTX_data_active_object(C));
1060 }
1061
1062 int mask_paint_poll(bContext *C)
1063 {
1064         return BKE_paint_select_elem_test(CTX_data_active_object(C));
1065 }
1066