fix bug with unitialized variable (thanks VS)
[plumiferos.git] / source / blender / src / imagepaint.c
blob58266554a49a933291d2b5bce8c04c1a1db60ffb
1 /**
2 * $Id: imagepaint.c 10466 2007-04-05 12:42:07Z broken $
3 * imagepaint.c
5 * Functions to paint images in 2D and 3D.
6 *
7 * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version. The Blender
13 * Foundation also sells licenses for use in proprietary software under
14 * the Blender License. See http://www.blender.org/BL/ for information
15 * about this.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software Foundation,
24 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
27 * All rights reserved.
29 * The Original Code is: all of this file.
31 * Contributor(s): Jens Ole Wund (bjornmose)
33 * ***** END GPL/BL DUAL LICENSE BLOCK *****
36 #include <string.h>
37 #include <stdio.h>
38 #include <math.h>
40 #ifdef HAVE_CONFIG_H
41 #include <config.h>
42 #endif
44 #include "MEM_guardedalloc.h"
46 #ifdef WIN32
47 #include "BLI_winstuff.h"
48 #endif
49 #include "BLI_arithb.h"
50 #include "PIL_time.h"
52 #include "IMB_imbuf.h"
53 #include "IMB_imbuf_types.h"
55 #include "DNA_brush_types.h"
56 #include "DNA_image_types.h"
57 #include "DNA_mesh_types.h"
58 #include "DNA_meshdata_types.h"
59 #include "DNA_node_types.h"
60 #include "DNA_object_types.h"
61 #include "DNA_scene_types.h"
62 #include "DNA_screen_types.h"
63 #include "DNA_space_types.h"
64 #include "DNA_userdef_types.h"
65 #include "DNA_view3d_types.h"
67 #include "BKE_brush.h"
68 #include "BKE_global.h"
69 #include "BKE_image.h"
70 #include "BKE_mesh.h"
71 #include "BKE_node.h"
72 #include "BKE_utildefines.h"
74 #include "BIF_mywindow.h"
75 #include "BIF_screen.h"
76 #include "BIF_space.h"
77 #include "BIF_toolbox.h"
79 #include "BSE_drawipo.h"
80 #include "BSE_node.h"
81 #include "BSE_trans_types.h"
82 #include "BSE_view.h"
84 #include "BDR_drawmesh.h"
85 #include "BDR_imagepaint.h"
86 #include "BDR_vpaint.h"
88 #include "GHOST_Types.h"
90 #include "blendef.h"
91 #include "butspace.h"
92 #include "mydevice.h"
94 /* Defines and Structs */
96 #define IMAPAINT_FLOAT_TO_CHAR(f) ((char)(f*255))
97 #define IMAPAINT_CHAR_TO_FLOAT(c) (c/255.0f)
99 #define IMAPAINT_FLOAT_RGB_TO_CHAR(c, f) { c[0]=IMAPAINT_FLOAT_TO_CHAR(f[0]); \
100 c[1]=IMAPAINT_FLOAT_TO_CHAR(f[1]); c[2]=IMAPAINT_FLOAT_TO_CHAR(f[2]); }
101 #define IMAPAINT_CHAR_RGB_TO_FLOAT(f, c) { f[0]=IMAPAINT_CHAR_TO_FLOAT(c[0]); \
102 f[1]=IMAPAINT_CHAR_TO_FLOAT(c[1]); f[2]=IMAPAINT_CHAR_TO_FLOAT(c[2]); }
103 #define IMAPAINT_FLOAT_RGB_COPY(a, b) VECCOPY(a, b)
105 #define IMAPAINT_TILE_BITS 6
106 #define IMAPAINT_TILE_SIZE (1 << IMAPAINT_TILE_BITS)
107 #define IMAPAINT_TILE_NUMBER(size) (((size)+IMAPAINT_TILE_SIZE-1) >> IMAPAINT_TILE_BITS)
109 typedef struct ImagePaintState {
110 Brush *brush;
111 short tool, blend;
112 Image *image;
113 ImBuf *canvas;
114 ImBuf *clonecanvas;
115 short clonefreefloat;
116 char *warnpackedfile;
117 char *warnmultifile;
119 /* texture paint only */
120 Object *ob;
121 Mesh *me;
122 int faceindex;
123 float uv[2];
124 } ImagePaintState;
126 typedef struct ImagePaintUndo {
127 Image *image;
128 ImBuf *tilebuf;
129 void **tiles;
130 int xtiles, ytiles;
131 } ImagePaintUndo;
133 typedef struct ImagePaintPartialRedraw {
134 int x1, y1, x2, y2;
135 int enabled;
136 } ImagePaintPartialRedraw;
138 static ImagePaintUndo imapaintundo = {NULL, NULL, NULL, 0, 0};
139 static ImagePaintPartialRedraw imapaintpartial = {0, 0, 0, 0, 0};
141 static void init_imagapaint_undo(Image *ima, ImBuf *ibuf)
143 int xt, yt;
145 imapaintundo.image = ima;
146 imapaintundo.xtiles = xt = IMAPAINT_TILE_NUMBER(ibuf->x);
147 imapaintundo.ytiles = yt = IMAPAINT_TILE_NUMBER(ibuf->y);
148 imapaintundo.tiles = MEM_callocN(sizeof(void*)*xt*yt, "ImagePaintUndoTiles");
149 imapaintundo.tilebuf = IMB_allocImBuf(IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE,
150 ibuf->depth, (ibuf->rect_float)? IB_rectfloat: IB_rect, 0);
153 static void imapaint_copy_tile(ImBuf *ibuf, int tile, int x, int y, int swapundo)
155 IMB_rectcpy(imapaintundo.tilebuf, ibuf, 0, 0, x*IMAPAINT_TILE_SIZE,
156 y*IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE);
158 if (imapaintundo.tilebuf->rect_float)
159 SWAP(void*, imapaintundo.tilebuf->rect_float, imapaintundo.tiles[tile])
160 else
161 SWAP(void*, imapaintundo.tilebuf->rect, imapaintundo.tiles[tile])
163 if (swapundo)
164 IMB_rectcpy(ibuf, imapaintundo.tilebuf, x*IMAPAINT_TILE_SIZE,
165 y*IMAPAINT_TILE_SIZE, 0, 0, IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE);
168 static void imapaint_clear_partial_redraw()
170 memset(&imapaintpartial, 0, sizeof(imapaintpartial));
173 static void imapaint_dirty_region(Image *ima, ImBuf *ibuf, int x, int y, int w, int h)
175 int srcx= 0, srcy= 0, origx, tile, allocsize;
177 IMB_rectclip(ibuf, NULL, &x, &y, &srcx, &srcy, &w, &h);
179 if (w == 0 || h == 0)
180 return;
182 if (!imapaintpartial.enabled) {
183 imapaintpartial.x1 = x;
184 imapaintpartial.y1 = y;
185 imapaintpartial.x2 = x+w;
186 imapaintpartial.y2 = y+h;
187 imapaintpartial.enabled = 1;
189 else {
190 imapaintpartial.x1 = MIN2(imapaintpartial.x1, x);
191 imapaintpartial.y1 = MIN2(imapaintpartial.y1, y);
192 imapaintpartial.x2 = MAX2(imapaintpartial.x2, x+w);
193 imapaintpartial.y2 = MAX2(imapaintpartial.y2, y+h);
196 w = ((x + w - 1) >> IMAPAINT_TILE_BITS);
197 h = ((y + h - 1) >> IMAPAINT_TILE_BITS);
198 origx = (x >> IMAPAINT_TILE_BITS);
199 y = (y >> IMAPAINT_TILE_BITS);
201 for (; y <= h; y++) {
202 for (x=origx; x <= w; x++) {
203 if (ima != imapaintundo.image) {
204 free_imagepaint();
205 init_imagapaint_undo(ima, ibuf);
208 tile = y*imapaintundo.xtiles + x;
209 if (!imapaintundo.tiles[tile]) {
210 allocsize= (ibuf->rect_float)? sizeof(float): sizeof(char);
211 imapaintundo.tiles[tile]= MEM_mapallocN(allocsize*4*
212 IMAPAINT_TILE_SIZE*IMAPAINT_TILE_SIZE, "ImagePaintUndoTile");
213 imapaint_copy_tile(ibuf, tile, x, y, 0);
218 ibuf->userflags |= IB_BITMAPDIRTY;
221 static void imapaint_image_update(Image *image, ImBuf *ibuf, short texpaint)
223 if(ibuf->rect_float)
224 imb_freerectImBuf(ibuf); /* force recreate of char rect */
225 if(ibuf->mipmap[0])
226 imb_freemipmapImBuf(ibuf);
228 /* todo: should set_tpage create ->rect? */
229 if(texpaint || G.sima->lock) {
230 int w = imapaintpartial.x2 - imapaintpartial.x1;
231 int h = imapaintpartial.y2 - imapaintpartial.y1;
232 update_realtime_image(image, imapaintpartial.x1, imapaintpartial.y1, w, h);
236 /* note; gets called for both 2d image paint and 3d texture paint. in the
237 latter case image may be NULL and G.sima may not exist */
238 static void imapaint_redraw(int final, int texpaint, Image *image)
240 if(final) {
241 if(texpaint)
242 allqueue(REDRAWIMAGE, 0);
243 else if(!G.sima->lock) {
244 if(image)
245 free_realtime_image(image); /* force OpenGL reload */
246 allqueue(REDRAWVIEW3D, 0);
248 allqueue(REDRAWHEADERS, 0);
250 if(!texpaint && image) {
251 /* after paint, tag Image or RenderResult nodes changed */
252 if(G.scene->nodetree) {
253 imagepaint_composite_tags(G.scene->nodetree, image, &G.sima->iuser);
255 /* signal composite (hurmf, need an allqueue?) */
256 if(G.sima->lock) {
257 ScrArea *sa;
258 for(sa=G.curscreen->areabase.first; sa; sa= sa->next) {
259 if(sa->spacetype==SPACE_NODE) {
260 if(((SpaceNode *)sa->spacedata.first)->treetype==NTREE_COMPOSIT) {
261 addqueue(sa->win, UI_BUT_EVENT, B_NODE_TREE_EXEC);
262 break;
269 else if(!texpaint && G.sima->lock)
270 force_draw_plus(SPACE_VIEW3D, 0);
271 else
272 force_draw(0);
275 void imagepaint_undo()
277 Image *ima= imapaintundo.image;
278 ImBuf *ibuf= BKE_image_get_ibuf(ima, G.sima?&G.sima->iuser:NULL);
279 int x, y, tile;
281 if (!ima || !ibuf || !(ibuf->rect || ibuf->rect_float))
282 return;
284 for (tile = 0, y = 0; y < imapaintundo.ytiles; y++)
285 for (x = 0; x < imapaintundo.xtiles; x++, tile++)
286 if (imapaintundo.tiles[tile])
287 imapaint_copy_tile(ibuf, tile, x, y, 1);
289 free_realtime_image(ima); /* force OpenGL reload */
290 if(ibuf->rect_float)
291 imb_freerectImBuf(ibuf); /* force recreate of char rect */
293 allqueue(REDRAWIMAGE, 0);
294 allqueue(REDRAWVIEW3D, 0);
297 void free_imagepaint()
299 /* todo: does this need to be in the same places as editmode_undo_clear,
300 vertex paint isn't? */
301 int i, size = imapaintundo.xtiles*imapaintundo.ytiles;
303 if (imapaintundo.tiles) {
304 for (i = 0; i < size; i++)
305 if (imapaintundo.tiles[i])
306 MEM_freeN(imapaintundo.tiles[i]);
307 MEM_freeN(imapaintundo.tiles);
309 if (imapaintundo.tilebuf)
310 IMB_freeImBuf(imapaintundo.tilebuf);
312 memset(&imapaintundo, 0, sizeof(imapaintundo));
315 /* Image Paint Operations */
317 static void imapaint_ibuf_get_set_rgb(ImBuf *ibuf, int x, int y, short torus, short set, float *rgb)
319 if (torus) {
320 x %= ibuf->x;
321 if (x < 0) x += ibuf->x;
322 y %= ibuf->y;
323 if (y < 0) y += ibuf->y;
326 if (ibuf->rect_float) {
327 float *rrgbf = ibuf->rect_float + (ibuf->x*y + x)*4;
329 if (set) IMAPAINT_FLOAT_RGB_COPY(rrgbf, rgb)
330 else IMAPAINT_FLOAT_RGB_COPY(rgb, rrgbf)
332 else {
333 char *rrgb = (char*)ibuf->rect + (ibuf->x*y + x)*4;
335 if (set) IMAPAINT_FLOAT_RGB_TO_CHAR(rrgb, rgb)
336 else IMAPAINT_CHAR_RGB_TO_FLOAT(rgb, rrgb)
340 static int imapaint_ibuf_add_if(ImBuf *ibuf, unsigned int x, unsigned int y, float *outrgb, short torus)
342 float inrgb[3];
344 if ((x >= ibuf->x) || (y >= ibuf->y)) {
345 if (torus) imapaint_ibuf_get_set_rgb(ibuf, x, y, 1, 0, inrgb);
346 else return 0;
348 else imapaint_ibuf_get_set_rgb(ibuf, x, y, 0, 0, inrgb);
350 outrgb[0] += inrgb[0];
351 outrgb[1] += inrgb[1];
352 outrgb[2] += inrgb[2];
354 return 1;
357 static void imapaint_lift_soften(ImBuf *ibuf, ImBuf *ibufb, int *pos, short torus)
359 int x, y, count, xi, yi, xo, yo;
360 int out_off[2], in_off[2], dim[2];
361 float outrgb[3];
363 dim[0] = ibufb->x;
364 dim[1] = ibufb->y;
365 in_off[0] = pos[0];
366 in_off[1] = pos[1];
367 out_off[0] = out_off[1] = 0;
369 if (!torus) {
370 IMB_rectclip(ibuf, ibufb, &in_off[0], &in_off[1], &out_off[0],
371 &out_off[1], &dim[0], &dim[1]);
373 if ((dim[0] == 0) || (dim[1] == 0))
374 return;
377 for (y=0; y < dim[1]; y++) {
378 for (x=0; x < dim[0]; x++) {
379 /* get input pixel */
380 xi = in_off[0] + x;
381 yi = in_off[1] + y;
383 count = 1;
384 imapaint_ibuf_get_set_rgb(ibuf, xi, yi, torus, 0, outrgb);
386 count += imapaint_ibuf_add_if(ibuf, xi-1, yi-1, outrgb, torus);
387 count += imapaint_ibuf_add_if(ibuf, xi-1, yi , outrgb, torus);
388 count += imapaint_ibuf_add_if(ibuf, xi-1, yi+1, outrgb, torus);
390 count += imapaint_ibuf_add_if(ibuf, xi , yi-1, outrgb, torus);
391 count += imapaint_ibuf_add_if(ibuf, xi , yi+1, outrgb, torus);
393 count += imapaint_ibuf_add_if(ibuf, xi+1, yi-1, outrgb, torus);
394 count += imapaint_ibuf_add_if(ibuf, xi+1, yi , outrgb, torus);
395 count += imapaint_ibuf_add_if(ibuf, xi+1, yi+1, outrgb, torus);
397 outrgb[0] /= count;
398 outrgb[1] /= count;
399 outrgb[2] /= count;
401 /* write into brush buffer */
402 xo = out_off[0] + x;
403 yo = out_off[1] + y;
404 imapaint_ibuf_get_set_rgb(ibufb, xo, yo, 0, 1, outrgb);
409 static void imapaint_lift_smear(ImBuf *ibuf, ImBuf *ibufb, int *pos)
411 IMB_rectblend_torus(ibufb, ibuf, 0, 0, pos[0], pos[1],
412 ibufb->x, ibufb->y, IMB_BLEND_COPY_RGB);
415 static ImBuf *imapaint_lift_clone(ImBuf *ibuf, ImBuf *ibufb, int *pos)
417 /* note: allocImbuf returns zero'd memory, so regions outside image will
418 have zero alpha, and hence not be blended onto the image */
419 int w=ibufb->x, h=ibufb->y, destx=0, desty=0, srcx=pos[0], srcy=pos[1];
420 ImBuf *clonebuf= IMB_allocImBuf(w, h, ibufb->depth, ibufb->flags, 0);
422 IMB_rectclip(clonebuf, ibuf, &destx, &desty, &srcx, &srcy, &w, &h);
423 IMB_rectblend(clonebuf, ibuf, destx, desty, srcx, srcy, w, h,
424 IMB_BLEND_COPY_RGB);
425 IMB_rectblend(clonebuf, ibufb, destx, desty, destx, desty, w, h,
426 IMB_BLEND_COPY_ALPHA);
428 return clonebuf;
431 static void imapaint_convert_brushco(ImBuf *ibufb, float *pos, int *ipos)
433 ipos[0]= (int)(pos[0] - ibufb->x/2);
434 ipos[1]= (int)(pos[1] - ibufb->y/2);
437 static int imapaint_paint_op(void *state, ImBuf *ibufb, float *lastpos, float *pos)
439 ImagePaintState *s= ((ImagePaintState*)state);
440 ImBuf *clonebuf= NULL;
441 short torus= s->brush->flag & BRUSH_TORUS;
442 short blend= s->blend;
443 float *offset= s->brush->clone.offset;
444 float liftpos[2];
445 int bpos[2], blastpos[2], bliftpos[2];
447 imapaint_convert_brushco(ibufb, pos, bpos);
449 /* lift from canvas */
450 if(s->tool == PAINT_TOOL_SOFTEN) {
451 imapaint_lift_soften(s->canvas, ibufb, bpos, torus);
453 else if(s->tool == PAINT_TOOL_SMEAR) {
454 if (lastpos[0]==pos[0] && lastpos[1]==pos[1])
455 return 0;
457 imapaint_convert_brushco(ibufb, lastpos, blastpos);
458 imapaint_lift_smear(s->canvas, ibufb, blastpos);
460 else if(s->tool == PAINT_TOOL_CLONE && s->clonecanvas) {
461 liftpos[0]= pos[0] - offset[0]*s->canvas->x;
462 liftpos[1]= pos[1] - offset[1]*s->canvas->y;
464 imapaint_convert_brushco(ibufb, liftpos, bliftpos);
465 clonebuf= imapaint_lift_clone(s->clonecanvas, ibufb, bliftpos);
468 imapaint_dirty_region(s->image, s->canvas, bpos[0], bpos[1], ibufb->x, ibufb->y);
470 /* blend into canvas */
471 if(torus)
472 IMB_rectblend_torus(s->canvas, (clonebuf)? clonebuf: ibufb,
473 bpos[0], bpos[1], 0, 0, ibufb->x, ibufb->y, blend);
474 else
475 IMB_rectblend(s->canvas, (clonebuf)? clonebuf: ibufb,
476 bpos[0], bpos[1], 0, 0, ibufb->x, ibufb->y, blend);
478 if(clonebuf) IMB_freeImBuf(clonebuf);
480 return 1;
483 /* 2D ImagePaint */
485 static void imapaint_compute_uvco(short *mval, float *uv)
487 areamouseco_to_ipoco(G.v2d, mval, &uv[0], &uv[1]);
490 /* 3D TexturePaint */
492 int facesel_face_pick(Mesh *me, short *mval, unsigned int *index, short rect);
493 void texpaint_pick_uv(Object *ob, Mesh *mesh, unsigned int faceindex, short *xy, float *mousepos);
495 static int texpaint_break_stroke(float *prevuv, float *fwuv, float *bkuv, float *uv)
497 float d1[2], d2[2];
498 float mismatch = Vec2Lenf(fwuv, uv);
499 float len1 = Vec2Lenf(prevuv, fwuv);
500 float len2 = Vec2Lenf(bkuv, uv);
502 Vec2Subf(d1, fwuv, prevuv);
503 Vec2Subf(d2, uv, bkuv);
505 return ((Inp2f(d1, d2) < 0.0f) || (mismatch > MAX2(len1, len2)*2));
508 /* ImagePaint Common */
510 static int imapaint_canvas_set(ImagePaintState *s, Image *ima)
512 ImBuf *ibuf= BKE_image_get_ibuf(ima, G.sima?&G.sima->iuser:NULL);
514 /* verify that we can paint and set canvas */
515 if(ima->packedfile && ima->rr) {
516 s->warnpackedfile = ima->id.name + 2;
517 return 0;
519 else if(ibuf && ibuf->channels!=4) {
520 s->warnmultifile = ima->id.name + 2;
521 return 0;
523 else if(!ima || !ibuf || !(ibuf->rect || ibuf->rect_float))
524 return 0;
526 s->image= ima;
527 s->canvas= ibuf;
529 /* set clone canvas */
530 if(s->tool == PAINT_TOOL_CLONE) {
531 ima= s->brush->clone.image;
532 ibuf= BKE_image_get_ibuf(ima, G.sima?&G.sima->iuser:NULL);
534 if(!ima || !ibuf || !(ibuf->rect || ibuf->rect_float))
535 return 0;
537 s->clonecanvas= ibuf;
539 if(s->canvas->rect_float && !s->clonecanvas->rect_float) {
540 /* temporarily add float rect for cloning */
541 IMB_float_from_rect(s->clonecanvas);
542 s->clonefreefloat= 1;
544 else if(!s->canvas->rect_float && !s->clonecanvas->rect)
545 IMB_rect_from_float(s->clonecanvas);
548 return 1;
551 static void imapaint_canvas_free(ImagePaintState *s)
553 if (s->clonefreefloat)
554 imb_freerectfloatImBuf(s->clonecanvas);
557 static int imapaint_paint_sub_stroke(ImagePaintState *s, BrushPainter *painter, Image *image, short texpaint, float *uv, double time, int update, float pressure)
559 ImBuf *ibuf= BKE_image_get_ibuf(image, G.sima?&G.sima->iuser:NULL);
560 float pos[2];
562 if(!ibuf)
563 return 0;
565 pos[0] = uv[0]*ibuf->x;
566 pos[1] = uv[1]*ibuf->y;
568 brush_painter_require_imbuf(painter, ((ibuf->rect_float)? 1: 0), 0, 0);
570 if (brush_painter_paint(painter, imapaint_paint_op, pos, time, pressure, s)) {
571 if (update)
572 imapaint_image_update(image, ibuf, texpaint);
573 return 1;
575 else return 0;
578 static void imapaint_paint_stroke(ImagePaintState *s, BrushPainter *painter, short texpaint, short *prevmval, short *mval, double time, float pressure)
580 Image *newimage = NULL;
581 float fwuv[2], bkuv[2], newuv[2];
582 unsigned int newfaceindex;
583 int breakstroke = 0, redraw = 0;
585 if (texpaint) {
587 /* pick new face and image */
588 if (facesel_face_pick(s->me, mval, &newfaceindex, 0)) {
589 ImBuf *ibuf;
591 newimage = (Image*)((s->me->mtface+newfaceindex)->tpage);
592 ibuf= BKE_image_get_ibuf(newimage, G.sima?&G.sima->iuser:NULL);
594 if(ibuf && ibuf->rect)
595 texpaint_pick_uv(s->ob, s->me, newfaceindex, mval, newuv);
596 else {
597 newimage = NULL;
598 newuv[0] = newuv[1] = 0.0f;
601 else
602 newuv[0] = newuv[1] = 0.0f;
604 /* see if stroke is broken, and if so finish painting in old position */
605 if (s->image) {
606 texpaint_pick_uv(s->ob, s->me, s->faceindex, mval, fwuv);
607 texpaint_pick_uv(s->ob, s->me, newfaceindex, prevmval, bkuv);
609 if (newimage == s->image)
610 breakstroke= texpaint_break_stroke(s->uv, fwuv, bkuv, newuv);
611 else
612 breakstroke= 1;
614 else
615 fwuv[0]= fwuv[1]= 0.0f;
617 if (breakstroke) {
618 texpaint_pick_uv(s->ob, s->me, s->faceindex, mval, fwuv);
619 redraw |= imapaint_paint_sub_stroke(s, painter, s->image, texpaint,
620 fwuv, time, 1, pressure);
621 imapaint_clear_partial_redraw();
622 brush_painter_break_stroke(painter);
625 /* set new canvas */
626 if (newimage && (newimage != s->image))
627 if (!imapaint_canvas_set(s, newimage))
628 newimage = NULL;
630 /* paint in new image */
631 if (newimage) {
632 if (breakstroke)
633 redraw|= imapaint_paint_sub_stroke(s, painter, newimage,
634 texpaint, bkuv, time, 0, pressure);
635 redraw|= imapaint_paint_sub_stroke(s, painter, newimage, texpaint,
636 newuv, time, 1, pressure);
639 /* update state */
640 s->image = newimage;
641 s->faceindex = newfaceindex;
642 s->uv[0] = newuv[0];
643 s->uv[1] = newuv[1];
645 else {
646 imapaint_compute_uvco(mval, newuv);
647 redraw |= imapaint_paint_sub_stroke(s, painter, s->image, texpaint, newuv,
648 time, 1, pressure);
651 if (redraw) {
652 imapaint_redraw(0, texpaint, NULL);
653 imapaint_clear_partial_redraw();
657 void imagepaint_paint(short mousebutton, short texpaint)
659 ImagePaintState s;
660 BrushPainter *painter;
661 ToolSettings *settings= G.scene->toolsettings;
662 short prevmval[2], mval[2];
663 double time;
664 float pressure;
666 if(!settings->imapaint.brush)
667 return;
669 /* initialize state */
670 memset(&s, 0, sizeof(s));
671 s.brush = settings->imapaint.brush;
672 s.tool = settings->imapaint.tool;
673 if(texpaint && (s.tool == PAINT_TOOL_CLONE))
674 s.tool = PAINT_TOOL_DRAW;
675 s.blend = s.brush->blend;
677 if(texpaint) {
678 s.ob = OBACT;
679 if (!s.ob || !(s.ob->lay & G.vd->lay)) return;
680 s.me = get_mesh(s.ob);
681 if (!s.me) return;
683 persp(PERSP_VIEW);
685 else {
686 s.image = G.sima->image;
688 if(!imapaint_canvas_set(&s, G.sima->image)) {
689 if(s.warnmultifile)
690 error("Image requires 4 color channels to paint");
691 if(s.warnpackedfile)
692 error("Packed MultiLayer files cannot be painted");
693 return;
697 settings->imapaint.flag |= IMAGEPAINT_DRAWING;
698 free_imagepaint();
700 /* create painter and paint once */
701 painter= brush_painter_new(s.brush);
703 getmouseco_areawin(mval);
705 pressure = get_pressure();
706 s.blend = (get_activedevice() == 2)? BRUSH_BLEND_ERASE_ALPHA: s.brush->blend;
708 time= PIL_check_seconds_timer();
709 prevmval[0]= mval[0];
710 prevmval[1]= mval[1];
712 /* special exception here for too high pressure values on first touch in
713 windows for some tablets */
714 if (!((s.brush->flag & (BRUSH_ALPHA_PRESSURE|BRUSH_SIZE_PRESSURE|
715 BRUSH_SPACING_PRESSURE|BRUSH_RAD_PRESSURE)) && (get_activedevice() != 0) && (pressure >= 0.99f)))
716 imapaint_paint_stroke(&s, painter, texpaint, prevmval, mval, time, pressure);
718 /* paint loop */
719 do {
720 getmouseco_areawin(mval);
722 pressure = get_pressure();
723 s.blend = (get_activedevice() == 2)? BRUSH_BLEND_ERASE_ALPHA: s.brush->blend;
725 time= PIL_check_seconds_timer();
727 if((mval[0] != prevmval[0]) || (mval[1] != prevmval[1])) {
728 imapaint_paint_stroke(&s, painter, texpaint, prevmval, mval, time, pressure);
729 prevmval[0]= mval[0];
730 prevmval[1]= mval[1];
732 else if (s.brush->flag & BRUSH_AIRBRUSH)
733 imapaint_paint_stroke(&s, painter, texpaint, prevmval, mval, time, pressure);
734 else
735 BIF_wait_for_statechange();
737 /* do mouse checking at the end, so don't check twice, and potentially
738 miss a short tap */
739 } while(get_mbut() & mousebutton);
741 /* clean up */
742 settings->imapaint.flag &= ~IMAGEPAINT_DRAWING;
743 imapaint_canvas_free(&s);
744 brush_painter_free(painter);
746 imapaint_redraw(1, texpaint, s.image);
748 if (texpaint) {
749 if (s.warnmultifile)
750 error("Image requires 4 color channels to paint: %s", s.warnmultifile);
751 if(s.warnpackedfile)
752 error("Packed MultiLayer files cannot be painted %s", s.warnpackedfile);
754 persp(PERSP_WIN);
758 void imagepaint_pick(short mousebutton)
760 ToolSettings *settings= G.scene->toolsettings;
761 Brush *brush= settings->imapaint.brush;
763 if(brush && (settings->imapaint.tool == PAINT_TOOL_CLONE)) {
764 if(brush->clone.image) {
765 short prevmval[2], mval[2];
766 float lastmousepos[2], mousepos[2];
768 getmouseco_areawin(prevmval);
770 while(get_mbut() & mousebutton) {
771 getmouseco_areawin(mval);
773 if((prevmval[0] != mval[0]) || (prevmval[1] != mval[1]) ) {
774 /* mouse moved, so move the clone image */
775 imapaint_compute_uvco(prevmval, lastmousepos);
776 imapaint_compute_uvco(mval, mousepos);
778 brush->clone.offset[0] += mousepos[0] - lastmousepos[0];
779 brush->clone.offset[1] += mousepos[1] - lastmousepos[1];
781 force_draw(0);
783 prevmval[0]= mval[0];
784 prevmval[1]= mval[1];
789 else if(brush)
790 sample_vpaint();