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