code cleanup:
[blender.git] / source / blender / editors / sculpt_paint / paint_image_2d.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  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): none yet.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file blender/editors/sculpt_paint/paint_image_2d.c
29  *  \ingroup bke
30  */
31 //#include <math.h>
32 #include <string.h>
33
34 #include "MEM_guardedalloc.h"
35
36 #include "DNA_brush_types.h"
37 #include "DNA_scene_types.h"
38 #include "DNA_space_types.h"
39 #include "DNA_object_types.h"
40
41 #include "BLI_math.h"
42
43 #include "BKE_context.h"
44 #include "BKE_brush.h"
45 #include "BKE_main.h"
46 #include "BKE_image.h"
47 #include "BKE_paint.h"
48 #include "BKE_report.h"
49
50 #include "ED_screen.h"
51
52 #include "IMB_imbuf.h"
53 #include "IMB_imbuf_types.h"
54 #include "IMB_colormanagement.h"
55
56 #include "WM_api.h"
57 #include "WM_types.h"
58
59 #include "UI_view2d.h"
60
61 #include "RE_shader_ext.h"
62
63 #include "GPU_draw.h"
64
65 #include "paint_intern.h"
66
67 /* Brush Painting for 2D image editor */
68
69 /* Defines and Structs */
70 /* FTOCHAR as inline function */
71 BLI_INLINE unsigned char f_to_char(const float val)
72 {
73         return FTOCHAR(val);
74 }
75 #define IMAPAINT_FLOAT_RGB_TO_CHAR(c, f)  {                                   \
76         (c)[0] = f_to_char((f)[0]);                                               \
77         (c)[1] = f_to_char((f)[1]);                                               \
78         (c)[2] = f_to_char((f)[2]);                                               \
79 } (void)0
80
81 #define IMAPAINT_CHAR_RGB_TO_FLOAT(f, c)  {                                   \
82         (f)[0] = IMAPAINT_CHAR_TO_FLOAT((c)[0]);                                  \
83         (f)[1] = IMAPAINT_CHAR_TO_FLOAT((c)[1]);                                  \
84         (f)[2] = IMAPAINT_CHAR_TO_FLOAT((c)[2]);                                  \
85 } (void)0
86
87 #define IMAPAINT_FLOAT_RGB_COPY(a, b) copy_v3_v3(a, b)
88
89 typedef struct BrushPainterCache {
90         short enabled;
91
92         int size;           /* size override, if 0 uses 2*BKE_brush_size_get(brush) */
93         short flt;          /* need float imbuf? */
94         short texonly;      /* no alpha, color or fallof, only texture in imbuf */
95
96         int lastsize;
97         float lastalpha;
98         float lastjitter;
99         float last_rotation;
100
101         ImBuf *ibuf;
102         ImBuf *texibuf;
103         ImBuf *maskibuf;
104 } BrushPainterCache;
105
106 typedef struct BrushPainter {
107         Scene *scene;
108         Brush *brush;
109
110         float lastpaintpos[2];  /* position of last paint op */
111         float startpaintpos[2]; /* position of first paint */
112
113         short firsttouch;       /* first paint op */
114
115         BrushPainterCache cache;
116 } BrushPainter;
117
118 typedef struct ImagePaintRegion {
119         int destx, desty;
120         int srcx, srcy;
121         int width, height;
122 } ImagePaintRegion;
123
124 typedef struct ImagePaintState {
125         BrushPainter *painter;
126         SpaceImage *sima;
127         View2D *v2d;
128         Scene *scene;
129         bScreen *screen;
130
131         Brush *brush;
132         short tool, blend;
133         Image *image;
134         ImBuf *canvas;
135         ImBuf *clonecanvas;
136         char *warnpackedfile;
137         char *warnmultifile;
138
139         /* viewport texture paint only, but _not_ project paint */
140         Object *ob;
141         int faceindex;
142         float uv[2];
143         int do_facesel;
144 } ImagePaintState;
145
146
147 static BrushPainter *brush_painter_2d_new(Scene *scene, Brush *brush)
148 {
149         BrushPainter *painter = MEM_callocN(sizeof(BrushPainter), "BrushPainter");
150
151         painter->brush = brush;
152         painter->scene = scene;
153         painter->firsttouch = 1;
154         painter->cache.lastsize = -1; /* force ibuf create in refresh */
155
156         return painter;
157 }
158
159
160 static void brush_painter_2d_require_imbuf(BrushPainter *painter, short flt, short texonly, int size)
161 {
162         if ((painter->cache.flt != flt) || (painter->cache.size != size) ||
163             ((painter->cache.texonly != texonly) && texonly))
164         {
165                 if (painter->cache.ibuf) IMB_freeImBuf(painter->cache.ibuf);
166                 if (painter->cache.maskibuf) IMB_freeImBuf(painter->cache.maskibuf);
167                 painter->cache.ibuf = painter->cache.maskibuf = NULL;
168                 painter->cache.lastsize = -1; /* force ibuf create in refresh */
169         }
170
171         if (painter->cache.flt != flt) {
172                 if (painter->cache.texibuf) IMB_freeImBuf(painter->cache.texibuf);
173                 painter->cache.texibuf = NULL;
174                 painter->cache.lastsize = -1; /* force ibuf create in refresh */
175         }
176
177         painter->cache.size = size;
178         painter->cache.flt = flt;
179         painter->cache.texonly = texonly;
180         painter->cache.enabled = 1;
181 }
182
183 static void brush_painter_2d_free(BrushPainter *painter)
184 {
185         if (painter->cache.ibuf) IMB_freeImBuf(painter->cache.ibuf);
186         if (painter->cache.texibuf) IMB_freeImBuf(painter->cache.texibuf);
187         if (painter->cache.maskibuf) IMB_freeImBuf(painter->cache.maskibuf);
188         MEM_freeN(painter);
189 }
190
191 static void brush_painter_2d_do_partial(BrushPainter *painter, ImBuf *oldtexibuf,
192                                      int x, int y, int w, int h, int xt, int yt,
193                                      const float pos[2])
194 {
195         Scene *scene = painter->scene;
196         Brush *brush = painter->brush;
197         ImBuf *ibuf, *maskibuf, *texibuf;
198         float *bf, *mf, *tf, *otf = NULL, xoff, yoff, xy[2], rgba[4];
199         unsigned char *b, *m, *t, *ot = NULL;
200         int dotexold, origx = x, origy = y;
201         const int radius = BKE_brush_size_get(painter->scene, brush);
202
203         xoff = -radius + 0.5f;
204         yoff = -radius + 0.5f;
205         xoff += (int)pos[0] - (int)painter->startpaintpos[0];
206         yoff += (int)pos[1] - (int)painter->startpaintpos[1];
207
208         ibuf = painter->cache.ibuf;
209         texibuf = painter->cache.texibuf;
210         maskibuf = painter->cache.maskibuf;
211
212         dotexold = (oldtexibuf != NULL);
213
214         /* not sure if it's actually needed or it's a mistake in coords/sizes
215          * calculation in brush_painter_fixed_tex_partial_update(), but without this
216          * limitation memory gets corrupted at fast strokes with quite big spacing (sergey) */
217         w = min_ii(w, ibuf->x);
218         h = min_ii(h, ibuf->y);
219
220         if (painter->cache.flt) {
221                 for (; y < h; y++) {
222                         bf = ibuf->rect_float + (y * ibuf->x + origx) * 4;
223                         tf = texibuf->rect_float + (y * texibuf->x + origx) * 4;
224                         mf = maskibuf->rect_float + (y * maskibuf->x + origx) * 4;
225
226                         if (dotexold)
227                                 otf = oldtexibuf->rect_float + ((y - origy + yt) * oldtexibuf->x + xt) * 4;
228
229                         for (x = origx; x < w; x++, bf += 4, mf += 4, tf += 4) {
230                                 if (dotexold) {
231                                         copy_v4_v4(tf, otf);
232                                         otf += 4;
233                                 }
234                                 else {
235                                         xy[0] = x + xoff;
236                                         xy[1] = y + yoff;
237
238                                         BKE_brush_sample_tex_2D(scene, brush, xy, tf);
239                                 }
240
241                                 bf[0] = tf[0] * mf[0];
242                                 bf[1] = tf[1] * mf[1];
243                                 bf[2] = tf[2] * mf[2];
244                                 bf[3] = tf[3] * mf[3];
245                         }
246                 }
247         }
248         else {
249                 for (; y < h; y++) {
250                         b = (unsigned char *)ibuf->rect + (y * ibuf->x + origx) * 4;
251                         t = (unsigned char *)texibuf->rect + (y * texibuf->x + origx) * 4;
252                         m = (unsigned char *)maskibuf->rect + (y * maskibuf->x + origx) * 4;
253
254                         if (dotexold)
255                                 ot = (unsigned char *)oldtexibuf->rect + ((y - origy + yt) * oldtexibuf->x + xt) * 4;
256
257                         for (x = origx; x < w; x++, b += 4, m += 4, t += 4) {
258                                 if (dotexold) {
259                                         t[0] = ot[0];
260                                         t[1] = ot[1];
261                                         t[2] = ot[2];
262                                         t[3] = ot[3];
263                                         ot += 4;
264                                 }
265                                 else {
266                                         xy[0] = x + xoff;
267                                         xy[1] = y + yoff;
268
269                                         BKE_brush_sample_tex_2D(scene, brush, xy, rgba);
270                                         rgba_float_to_uchar(t, rgba);
271                                 }
272
273                                 b[0] = t[0] * m[0] / 255;
274                                 b[1] = t[1] * m[1] / 255;
275                                 b[2] = t[2] * m[2] / 255;
276                                 b[3] = t[3] * m[3] / 255;
277                         }
278                 }
279         }
280 }
281
282 static void brush_painter_2d_tiled_tex_partial_update(BrushPainter *painter, const float pos[2])
283 {
284         const Scene *scene = painter->scene;
285         Brush *brush = painter->brush;
286         BrushPainterCache *cache = &painter->cache;
287         ImBuf *oldtexibuf, *ibuf;
288         int imbflag, destx, desty, srcx, srcy, w, h, x1, y1, x2, y2;
289         const int diameter = 2 * BKE_brush_size_get(scene, brush);
290
291         imbflag = (cache->flt) ? IB_rectfloat : IB_rect;
292         if (!cache->ibuf)
293                 cache->ibuf = IMB_allocImBuf(diameter, diameter, 32, imbflag);
294         ibuf = cache->ibuf;
295
296         oldtexibuf = cache->texibuf;
297         cache->texibuf = IMB_allocImBuf(diameter, diameter, 32, imbflag);
298         if (oldtexibuf) {
299                 srcx = srcy = 0;
300                 destx = (int)painter->lastpaintpos[0] - (int)pos[0];
301                 desty = (int)painter->lastpaintpos[1] - (int)pos[1];
302                 w = oldtexibuf->x;
303                 h = oldtexibuf->y;
304
305                 IMB_rectclip(cache->texibuf, oldtexibuf, &destx, &desty, &srcx, &srcy, &w, &h);
306         }
307         else {
308                 srcx = srcy = 0;
309                 destx = desty = 0;
310                 w = h = 0;
311         }
312         
313         x1 = destx;
314         y1 = desty;
315         x2 = destx + w;
316         y2 = desty + h;
317
318         /* blend existing texture in new position */
319         if ((x1 < x2) && (y1 < y2))
320                 brush_painter_2d_do_partial(painter, oldtexibuf, x1, y1, x2, y2, srcx, srcy, pos);
321
322         if (oldtexibuf)
323                 IMB_freeImBuf(oldtexibuf);
324
325         /* sample texture in new areas */
326         if ((0 < x1) && (0 < ibuf->y))
327                 brush_painter_2d_do_partial(painter, NULL, 0, 0, x1, ibuf->y, 0, 0, pos);
328         if ((x2 < ibuf->x) && (0 < ibuf->y))
329                 brush_painter_2d_do_partial(painter, NULL, x2, 0, ibuf->x, ibuf->y, 0, 0, pos);
330         if ((x1 < x2) && (0 < y1))
331                 brush_painter_2d_do_partial(painter, NULL, x1, 0, x2, y1, 0, 0, pos);
332         if ((x1 < x2) && (y2 < ibuf->y))
333                 brush_painter_2d_do_partial(painter, NULL, x1, y2, x2, ibuf->y, 0, 0, pos);
334 }
335
336 static void brush_painter_2d_refresh_cache(BrushPainter *painter, const float pos[2], int use_color_correction)
337 {
338         const Scene *scene = painter->scene;
339         UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
340         Brush *brush = painter->brush;
341         BrushPainterCache *cache = &painter->cache;
342         MTex *mtex = &brush->mtex;
343         int size;
344         short flt;
345         const int diameter = 2 * BKE_brush_size_get(scene, brush);
346         const float alpha = BKE_brush_alpha_get(scene, brush);
347         const bool do_tiled = ELEM(brush->mtex.brush_map_mode, MTEX_MAP_MODE_TILED, MTEX_MAP_MODE_3D);
348         float rotation = -mtex->rot;
349
350         if (mtex->brush_map_mode == MTEX_MAP_MODE_VIEW) {
351                 rotation += ups->brush_rotation;
352         }
353
354         if (diameter != cache->lastsize ||
355             alpha != cache->lastalpha ||
356             brush->jitter != cache->lastjitter ||
357             rotation != cache->last_rotation)
358         {
359                 if (cache->ibuf) {
360                         IMB_freeImBuf(cache->ibuf);
361                         cache->ibuf = NULL;
362                 }
363                 if (cache->maskibuf) {
364                         IMB_freeImBuf(cache->maskibuf);
365                         cache->maskibuf = NULL;
366                 }
367
368                 flt = cache->flt;
369                 size = (cache->size) ? cache->size : diameter;
370
371                 if (do_tiled) {
372                         BKE_brush_imbuf_new(scene, brush, flt, 3, size, &cache->maskibuf, use_color_correction);
373                         brush_painter_2d_tiled_tex_partial_update(painter, pos);
374                 }
375                 else
376                         BKE_brush_imbuf_new(scene, brush, flt, 2, size, &cache->ibuf, use_color_correction);
377
378                 cache->lastsize = diameter;
379                 cache->lastalpha = alpha;
380                 cache->lastjitter = brush->jitter;
381                 cache->last_rotation = rotation;
382         }
383         else if (do_tiled && mtex && mtex->tex) {
384                 int dx = (int)painter->lastpaintpos[0] - (int)pos[0];
385                 int dy = (int)painter->lastpaintpos[1] - (int)pos[1];
386
387                 if ((dx != 0) || (dy != 0))
388                         brush_painter_2d_tiled_tex_partial_update(painter, pos);
389         }
390 }
391
392 /* keep these functions in sync */
393 static void paint_2d_ibuf_rgb_get(ImBuf *ibuf, int x, int y, const short is_torus, float r_rgb[3])
394 {
395         if (is_torus) {
396                 x %= ibuf->x;
397                 if (x < 0) x += ibuf->x;
398                 y %= ibuf->y;
399                 if (y < 0) y += ibuf->y;
400         }
401
402         if (ibuf->rect_float) {
403                 float *rrgbf = ibuf->rect_float + (ibuf->x * y + x) * 4;
404                 IMAPAINT_FLOAT_RGB_COPY(r_rgb, rrgbf);
405         }
406         else {
407                 char *rrgb = (char *)ibuf->rect + (ibuf->x * y + x) * 4;
408                 IMAPAINT_CHAR_RGB_TO_FLOAT(r_rgb, rrgb);
409         }
410 }
411 static void paint_2d_ibuf_rgb_set(ImBuf *ibuf, int x, int y, const short is_torus, const float rgb[3])
412 {
413         if (is_torus) {
414                 x %= ibuf->x;
415                 if (x < 0) x += ibuf->x;
416                 y %= ibuf->y;
417                 if (y < 0) y += ibuf->y;
418         }
419
420         if (ibuf->rect_float) {
421                 float *rrgbf = ibuf->rect_float + (ibuf->x * y + x) * 4;
422                 IMAPAINT_FLOAT_RGB_COPY(rrgbf, rgb);
423         }
424         else {
425                 char *rrgb = (char *)ibuf->rect + (ibuf->x * y + x) * 4;
426                 IMAPAINT_FLOAT_RGB_TO_CHAR(rrgb, rgb);
427         }
428 }
429
430 static int paint_2d_ibuf_add_if(ImBuf *ibuf, unsigned int x, unsigned int y, float *outrgb, short torus)
431 {
432         float inrgb[3];
433
434         // XXX: signed unsigned mismatch
435         if ((x >= (unsigned int)(ibuf->x)) || (y >= (unsigned int)(ibuf->y))) {
436                 if (torus) paint_2d_ibuf_rgb_get(ibuf, x, y, 1, inrgb);
437                 else return 0;
438         }
439         else {
440                 paint_2d_ibuf_rgb_get(ibuf, x, y, 0, inrgb);
441         }
442
443         outrgb[0] += inrgb[0];
444         outrgb[1] += inrgb[1];
445         outrgb[2] += inrgb[2];
446
447         return 1;
448 }
449
450 static void paint_2d_lift_soften(ImBuf *ibuf, ImBuf *ibufb, int *pos, const short is_torus)
451 {
452         int x, y, count, xi, yi, xo, yo;
453         int out_off[2], in_off[2], dim[2];
454         float outrgb[3];
455
456         dim[0] = ibufb->x;
457         dim[1] = ibufb->y;
458         in_off[0] = pos[0];
459         in_off[1] = pos[1];
460         out_off[0] = out_off[1] = 0;
461
462         if (!is_torus) {
463                 IMB_rectclip(ibuf, ibufb, &in_off[0], &in_off[1], &out_off[0],
464                              &out_off[1], &dim[0], &dim[1]);
465
466                 if ((dim[0] == 0) || (dim[1] == 0))
467                         return;
468         }
469
470         for (y = 0; y < dim[1]; y++) {
471                 for (x = 0; x < dim[0]; x++) {
472                         /* get input pixel */
473                         xi = in_off[0] + x;
474                         yi = in_off[1] + y;
475
476                         count = 1;
477                         paint_2d_ibuf_rgb_get(ibuf, xi, yi, is_torus, outrgb);
478
479                         count += paint_2d_ibuf_add_if(ibuf, xi - 1, yi - 1, outrgb, is_torus);
480                         count += paint_2d_ibuf_add_if(ibuf, xi - 1, yi, outrgb, is_torus);
481                         count += paint_2d_ibuf_add_if(ibuf, xi - 1, yi + 1, outrgb, is_torus);
482
483                         count += paint_2d_ibuf_add_if(ibuf, xi, yi - 1, outrgb, is_torus);
484                         count += paint_2d_ibuf_add_if(ibuf, xi, yi + 1, outrgb, is_torus);
485
486                         count += paint_2d_ibuf_add_if(ibuf, xi + 1, yi - 1, outrgb, is_torus);
487                         count += paint_2d_ibuf_add_if(ibuf, xi + 1, yi, outrgb, is_torus);
488                         count += paint_2d_ibuf_add_if(ibuf, xi + 1, yi + 1, outrgb, is_torus);
489
490                         mul_v3_fl(outrgb, 1.0f / (float)count);
491
492                         /* write into brush buffer */
493                         xo = out_off[0] + x;
494                         yo = out_off[1] + y;
495                         paint_2d_ibuf_rgb_set(ibufb, xo, yo, 0, outrgb);
496                 }
497         }
498 }
499
500 static void paint_2d_set_region(ImagePaintRegion *region, int destx, int desty, int srcx, int srcy, int width, int height)
501 {
502         region->destx = destx;
503         region->desty = desty;
504         region->srcx = srcx;
505         region->srcy = srcy;
506         region->width = width;
507         region->height = height;
508 }
509
510 static int paint_2d_torus_split_region(ImagePaintRegion region[4], ImBuf *dbuf, ImBuf *sbuf)
511 {
512         int destx = region->destx;
513         int desty = region->desty;
514         int srcx = region->srcx;
515         int srcy = region->srcy;
516         int width = region->width;
517         int height = region->height;
518         int origw, origh, w, h, tot = 0;
519
520         /* convert destination and source coordinates to be within image */
521         destx = destx % dbuf->x;
522         if (destx < 0) destx += dbuf->x;
523         desty = desty % dbuf->y;
524         if (desty < 0) desty += dbuf->y;
525         srcx = srcx % sbuf->x;
526         if (srcx < 0) srcx += sbuf->x;
527         srcy = srcy % sbuf->y;
528         if (srcy < 0) srcy += sbuf->y;
529
530         /* clip width of blending area to destination imbuf, to avoid writing the
531          * same pixel twice */
532         origw = w = (width > dbuf->x) ? dbuf->x : width;
533         origh = h = (height > dbuf->y) ? dbuf->y : height;
534
535         /* clip within image */
536         IMB_rectclip(dbuf, sbuf, &destx, &desty, &srcx, &srcy, &w, &h);
537         paint_2d_set_region(&region[tot++], destx, desty, srcx, srcy, w, h);
538
539         /* do 3 other rects if needed */
540         if (w < origw)
541                 paint_2d_set_region(&region[tot++], (destx + w) % dbuf->x, desty, (srcx + w) % sbuf->x, srcy, origw - w, h);
542         if (h < origh)
543                 paint_2d_set_region(&region[tot++], destx, (desty + h) % dbuf->y, srcx, (srcy + h) % sbuf->y, w, origh - h);
544         if ((w < origw) && (h < origh))
545                 paint_2d_set_region(&region[tot++], (destx + w) % dbuf->x, (desty + h) % dbuf->y, (srcx + w) % sbuf->x, (srcy + h) % sbuf->y, origw - w, origh - h);
546
547         return tot;
548 }
549
550 static void paint_2d_lift_smear(ImBuf *ibuf, ImBuf *ibufb, int *pos)
551 {
552         ImagePaintRegion region[4];
553         int a, tot;
554
555         paint_2d_set_region(region, 0, 0, pos[0], pos[1], ibufb->x, ibufb->y);
556         tot = paint_2d_torus_split_region(region, ibufb, ibuf);
557
558         for (a = 0; a < tot; a++)
559                 IMB_rectblend(ibufb, ibuf, region[a].destx, region[a].desty,
560                               region[a].srcx, region[a].srcy,
561                               region[a].width, region[a].height, IMB_BLEND_COPY_RGB);
562 }
563
564 static ImBuf *paint_2d_lift_clone(ImBuf *ibuf, ImBuf *ibufb, int *pos)
565 {
566         /* note: allocImbuf returns zero'd memory, so regions outside image will
567          * have zero alpha, and hence not be blended onto the image */
568         int w = ibufb->x, h = ibufb->y, destx = 0, desty = 0, srcx = pos[0], srcy = pos[1];
569         ImBuf *clonebuf = IMB_allocImBuf(w, h, ibufb->planes, ibufb->flags);
570
571         IMB_rectclip(clonebuf, ibuf, &destx, &desty, &srcx, &srcy, &w, &h);
572         IMB_rectblend(clonebuf, ibuf, destx, desty, srcx, srcy, w, h,
573                       IMB_BLEND_COPY_RGB);
574         IMB_rectblend(clonebuf, ibufb, destx, desty, destx, desty, w, h,
575                       IMB_BLEND_COPY_ALPHA);
576
577         return clonebuf;
578 }
579
580 static void paint_2d_convert_brushco(ImBuf *ibufb, const float pos[2], int ipos[2])
581 {
582         ipos[0] = (int)floorf((pos[0] - ibufb->x / 2) + 1.0f);
583         ipos[1] = (int)floorf((pos[1] - ibufb->y / 2) + 1.0f);
584 }
585
586 static int paint_2d_op(void *state, ImBuf *ibufb, const float lastpos[2], const float pos[2])
587 {
588         ImagePaintState *s = ((ImagePaintState *)state);
589         ImBuf *clonebuf = NULL, *frombuf;
590         ImagePaintRegion region[4];
591         short torus = s->brush->flag & BRUSH_TORUS;
592         short blend = s->blend;
593         float *offset = s->brush->clone.offset;
594         float liftpos[2];
595         int bpos[2], blastpos[2], bliftpos[2];
596         int a, tot;
597
598         paint_2d_convert_brushco(ibufb, pos, bpos);
599
600         /* lift from canvas */
601         if (s->tool == PAINT_TOOL_SOFTEN) {
602                 paint_2d_lift_soften(s->canvas, ibufb, bpos, torus);
603         }
604         else if (s->tool == PAINT_TOOL_SMEAR) {
605                 if (lastpos[0] == pos[0] && lastpos[1] == pos[1])
606                         return 0;
607
608                 paint_2d_convert_brushco(ibufb, lastpos, blastpos);
609                 paint_2d_lift_smear(s->canvas, ibufb, blastpos);
610         }
611         else if (s->tool == PAINT_TOOL_CLONE && s->clonecanvas) {
612                 liftpos[0] = pos[0] - offset[0] * s->canvas->x;
613                 liftpos[1] = pos[1] - offset[1] * s->canvas->y;
614
615                 paint_2d_convert_brushco(ibufb, liftpos, bliftpos);
616                 clonebuf = paint_2d_lift_clone(s->clonecanvas, ibufb, bliftpos);
617         }
618
619         frombuf = (clonebuf) ? clonebuf : ibufb;
620
621         if (torus) {
622                 paint_2d_set_region(region, bpos[0], bpos[1], 0, 0, frombuf->x, frombuf->y);
623                 tot = paint_2d_torus_split_region(region, s->canvas, frombuf);
624         }
625         else {
626                 paint_2d_set_region(region, bpos[0], bpos[1], 0, 0, frombuf->x, frombuf->y);
627                 tot = 1;
628         }
629
630         /* blend into canvas */
631         for (a = 0; a < tot; a++) {
632                 imapaint_dirty_region(s->image, s->canvas,
633                                       region[a].destx, region[a].desty,
634                                       region[a].width, region[a].height);
635
636                 IMB_rectblend(s->canvas, frombuf,
637                               region[a].destx, region[a].desty,
638                               region[a].srcx, region[a].srcy,
639                               region[a].width, region[a].height, blend);
640         }
641
642         if (clonebuf) IMB_freeImBuf(clonebuf);
643
644         return 1;
645 }
646
647
648 static int paint_2d_canvas_set(ImagePaintState *s, Image *ima)
649 {
650         ImBuf *ibuf = BKE_image_acquire_ibuf(ima, s->sima ? &s->sima->iuser : NULL, NULL);
651
652         /* verify that we can paint and set canvas */
653         if (ima == NULL) {
654                 return 0;
655         }
656         else if (ima->packedfile && ima->rr) {
657                 s->warnpackedfile = ima->id.name + 2;
658                 return 0;
659         }
660         else if (ibuf && ibuf->channels != 4) {
661                 s->warnmultifile = ima->id.name + 2;
662                 return 0;
663         }
664         else if (!ibuf || !(ibuf->rect || ibuf->rect_float))
665                 return 0;
666
667         s->image = ima;
668         s->canvas = ibuf;
669
670         /* set clone canvas */
671         if (s->tool == PAINT_TOOL_CLONE) {
672                 ima = s->brush->clone.image;
673                 ibuf = BKE_image_acquire_ibuf(ima, s->sima ? &s->sima->iuser : NULL, NULL);
674
675                 if (!ima || !ibuf || !(ibuf->rect || ibuf->rect_float)) {
676                         BKE_image_release_ibuf(ima, ibuf, NULL);
677                         BKE_image_release_ibuf(s->image, s->canvas, NULL);
678                         return 0;
679                 }
680
681                 s->clonecanvas = ibuf;
682
683                 /* temporarily add float rect for cloning */
684                 if (s->canvas->rect_float && !s->clonecanvas->rect_float) {
685                         IMB_float_from_rect(s->clonecanvas);
686                 }
687                 else if (!s->canvas->rect_float && !s->clonecanvas->rect)
688                         IMB_rect_from_float(s->clonecanvas);
689         }
690
691         return 1;
692 }
693
694 static void paint_2d_canvas_free(ImagePaintState *s)
695 {
696         BKE_image_release_ibuf(s->image, s->canvas, NULL);
697         BKE_image_release_ibuf(s->brush->clone.image, s->clonecanvas, NULL);
698 }
699
700 int paint_2d_stroke(void *ps, const int prev_mval[2], const int mval[2], int eraser)
701 {
702         float newuv[2], olduv[2];
703         int redraw = 0;
704         ImagePaintState *s = ps;
705         BrushPainter *painter = s->painter;
706         ImBuf *ibuf = BKE_image_acquire_ibuf(s->image, s->sima ? &s->sima->iuser : NULL, NULL);
707         const bool is_data = (ibuf && ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA);
708
709         if (!ibuf)
710                 return 0;
711
712         s->blend = s->brush->blend;
713         if (eraser)
714                 s->blend = IMB_BLEND_ERASE_ALPHA;
715
716         UI_view2d_region_to_view(s->v2d, mval[0], mval[1], &newuv[0], &newuv[1]);
717         UI_view2d_region_to_view(s->v2d, prev_mval[0], prev_mval[1], &olduv[0], &olduv[1]);
718
719         newuv[0] *= ibuf->x;
720         newuv[1] *= ibuf->y;
721
722         olduv[0] *= ibuf->x;
723         olduv[1] *= ibuf->y;
724
725         if (painter->firsttouch) {
726                 /* paint exactly once on first touch */
727                 painter->startpaintpos[0] = newuv[0];
728                 painter->startpaintpos[1] = newuv[1];
729
730                 painter->firsttouch = 0;
731                 copy_v2_v2(painter->lastpaintpos, newuv);
732         }
733         else {
734                 copy_v2_v2(painter->lastpaintpos, olduv);
735         }
736         /* OCIO_TODO: float buffers are now always linear, so always use color correction
737          *            this should probably be changed when texture painting color space is supported
738          */
739         brush_painter_2d_require_imbuf(painter, ((ibuf->rect_float) ? 1 : 0), 0, 0);
740
741         if (painter->cache.enabled)
742                 brush_painter_2d_refresh_cache(painter, newuv, is_data == false);
743
744         if (paint_2d_op(s, painter->cache.ibuf, olduv, newuv)) {
745                 imapaint_image_update(s->sima, s->image, ibuf, false);
746                 BKE_image_release_ibuf(s->image, ibuf, NULL);
747                 redraw |= 1;
748         }
749         else {
750                 BKE_image_release_ibuf(s->image, ibuf, NULL);
751         }
752
753         if (redraw)
754                 imapaint_clear_partial_redraw();
755
756         return redraw;
757 }
758
759 void *paint_2d_new_stroke(bContext *C, wmOperator *op)
760 {
761         Scene *scene = CTX_data_scene(C);
762         ToolSettings *settings = scene->toolsettings;
763         Brush *brush = paint_brush(&settings->imapaint.paint);
764
765         ImagePaintState *s = MEM_callocN(sizeof(ImagePaintState), "ImagePaintState");
766
767         s->sima = CTX_wm_space_image(C);
768         s->v2d = &CTX_wm_region(C)->v2d;
769         s->scene = scene;
770         s->screen = CTX_wm_screen(C);
771
772         s->brush = brush;
773         s->tool = brush->imagepaint_tool;
774         s->blend = brush->blend;
775
776         s->image = s->sima->image;
777
778         if (!paint_2d_canvas_set(s, s->image)) {
779                 if (s->warnmultifile)
780                         BKE_report(op->reports, RPT_WARNING, "Image requires 4 color channels to paint");
781                 if (s->warnpackedfile)
782                         BKE_report(op->reports, RPT_WARNING, "Packed MultiLayer files cannot be painted");
783
784                 MEM_freeN(s);
785                 return NULL;
786         }
787
788         paint_brush_init_tex(s->brush);
789
790         /* create painter */
791         s->painter = brush_painter_2d_new(scene, s->brush);
792
793         return s;
794 }
795
796 void paint_2d_redraw(const bContext *C, void *ps, int final)
797 {
798         ImagePaintState *s = ps;
799
800         if (final) {
801                 if (s->image && !(s->sima && s->sima->lock))
802                         GPU_free_image(s->image);
803
804                 /* compositor listener deals with updating */
805                 WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, s->image);
806         }
807         else {
808                 if (!s->sima || !s->sima->lock)
809                         ED_region_tag_redraw(CTX_wm_region(C));
810                 else
811                         WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, s->image);
812         }
813 }
814
815 void paint_2d_stroke_done(void *ps)
816 {
817         ImagePaintState *s = ps;
818
819         paint_2d_canvas_free(s);
820         brush_painter_2d_free(s->painter);
821         paint_brush_exit_tex(s->brush);
822
823         MEM_freeN(s);
824 }