2 * $Id: imagepaint.c 10466 2007-04-05 12:42:07Z broken $
5 * Functions to paint images in 2D and 3D.
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
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 *****
44 #include "MEM_guardedalloc.h"
47 #include "BLI_winstuff.h"
49 #include "BLI_arithb.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"
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"
81 #include "BSE_trans_types.h"
84 #include "BDR_drawmesh.h"
85 #include "BDR_imagepaint.h"
86 #include "BDR_vpaint.h"
88 #include "GHOST_Types.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
{
115 short clonefreefloat
;
116 char *warnpackedfile
;
119 /* texture paint only */
126 typedef struct ImagePaintUndo
{
133 typedef struct ImagePaintPartialRedraw
{
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
)
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
])
161 SWAP(void*, imapaintundo
.tilebuf
->rect
, imapaintundo
.tiles
[tile
])
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)
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;
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
) {
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
)
224 imb_freerectImBuf(ibuf
); /* force recreate of char rect */
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
)
242 allqueue(REDRAWIMAGE
, 0);
243 else if(!G
.sima
->lock
) {
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?) */
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
);
269 else if(!texpaint
&& G
.sima
->lock
)
270 force_draw_plus(SPACE_VIEW3D
, 0);
275 void imagepaint_undo()
277 Image
*ima
= imapaintundo
.image
;
278 ImBuf
*ibuf
= BKE_image_get_ibuf(ima
, G
.sima
?&G
.sima
->iuser
:NULL
);
281 if (!ima
|| !ibuf
|| !(ibuf
->rect
|| ibuf
->rect_float
))
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 */
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
)
321 if (x
< 0) x
+= ibuf
->x
;
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
)
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
)
344 if ((x
>= ibuf
->x
) || (y
>= ibuf
->y
)) {
345 if (torus
) imapaint_ibuf_get_set_rgb(ibuf
, x
, y
, 1, 0, inrgb
);
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];
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];
367 out_off
[0] = out_off
[1] = 0;
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))
377 for (y
=0; y
< dim
[1]; y
++) {
378 for (x
=0; x
< dim
[0]; x
++) {
379 /* get input pixel */
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
);
401 /* write into brush buffer */
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
,
425 IMB_rectblend(clonebuf
, ibufb
, destx
, desty
, destx
, desty
, w
, h
,
426 IMB_BLEND_COPY_ALPHA
);
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
;
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])
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 */
472 IMB_rectblend_torus(s
->canvas
, (clonebuf
)? clonebuf
: ibufb
,
473 bpos
[0], bpos
[1], 0, 0, ibufb
->x
, ibufb
->y
, blend
);
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
);
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
)
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;
519 else if(ibuf
&& ibuf
->channels
!=4) {
520 s
->warnmultifile
= ima
->id
.name
+ 2;
523 else if(!ima
|| !ibuf
|| !(ibuf
->rect
|| ibuf
->rect_float
))
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
))
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
);
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
);
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
)) {
572 imapaint_image_update(image
, ibuf
, texpaint
);
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;
587 /* pick new face and image */
588 if (facesel_face_pick(s
->me
, mval
, &newfaceindex
, 0)) {
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
);
598 newuv
[0] = newuv
[1] = 0.0f
;
602 newuv
[0] = newuv
[1] = 0.0f
;
604 /* see if stroke is broken, and if so finish painting in old position */
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
);
615 fwuv
[0]= fwuv
[1]= 0.0f
;
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
);
626 if (newimage
&& (newimage
!= s
->image
))
627 if (!imapaint_canvas_set(s
, newimage
))
630 /* paint in new image */
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
);
641 s
->faceindex
= newfaceindex
;
646 imapaint_compute_uvco(mval
, newuv
);
647 redraw
|= imapaint_paint_sub_stroke(s
, painter
, s
->image
, texpaint
, newuv
,
652 imapaint_redraw(0, texpaint
, NULL
);
653 imapaint_clear_partial_redraw();
657 void imagepaint_paint(short mousebutton
, short texpaint
)
660 BrushPainter
*painter
;
661 ToolSettings
*settings
= G
.scene
->toolsettings
;
662 short prevmval
[2], mval
[2];
666 if(!settings
->imapaint
.brush
)
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
;
679 if (!s
.ob
|| !(s
.ob
->lay
& G
.vd
->lay
)) return;
680 s
.me
= get_mesh(s
.ob
);
686 s
.image
= G
.sima
->image
;
688 if(!imapaint_canvas_set(&s
, G
.sima
->image
)) {
690 error("Image requires 4 color channels to paint");
692 error("Packed MultiLayer files cannot be painted");
697 settings
->imapaint
.flag
|= IMAGEPAINT_DRAWING
;
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
);
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
);
735 BIF_wait_for_statechange();
737 /* do mouse checking at the end, so don't check twice, and potentially
739 } while(get_mbut() & mousebutton
);
742 settings
->imapaint
.flag
&= ~IMAGEPAINT_DRAWING
;
743 imapaint_canvas_free(&s
);
744 brush_painter_free(painter
);
746 imapaint_redraw(1, texpaint
, s
.image
);
750 error("Image requires 4 color channels to paint: %s", s
.warnmultifile
);
752 error("Packed MultiLayer files cannot be painted %s", s
.warnpackedfile
);
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];
783 prevmval
[0]= mval
[0];
784 prevmval
[1]= mval
[1];