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