diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2005-09-17 00:17:09 +0400 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2005-09-17 00:17:09 +0400 |
commit | 0804d66f7932279539bbf1026990b26491ee59e2 (patch) | |
tree | 38c00c77e2e292e1ccde46d1b0e9a4b783070712 /source/blender/src/imagepaint.c | |
parent | 7c29e6d551127453154d4a97698d77992f2180f7 (diff) |
- Imagepaint code cleanup:
- Move UVTEXTTOOL variables into global Gip struct (like Gvp for
vertex paint). This will probably be moved into SpaceImage later,
so it is saved with the .blend file.
- Disable tool drawing. a better solution needs to be found.
- Panel button layout is still the same, this will change.
- Removed the NAN_TPT define, it has no use anymore.
Diffstat (limited to 'source/blender/src/imagepaint.c')
-rw-r--r-- | source/blender/src/imagepaint.c | 457 |
1 files changed, 202 insertions, 255 deletions
diff --git a/source/blender/src/imagepaint.c b/source/blender/src/imagepaint.c index 69355a10600..7fa2f9c3cca 100644 --- a/source/blender/src/imagepaint.c +++ b/source/blender/src/imagepaint.c @@ -5,7 +5,6 @@ * Functions to edit the "2D UV/Image " * and handle user events sent to it. * - * * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** * * This program is free software; you can redistribute it and/or @@ -34,6 +33,7 @@ * * ***** END GPL/BL DUAL LICENSE BLOCK ***** */ + #include <string.h> #include <stdio.h> #include <math.h> @@ -47,15 +47,9 @@ #include "BLI_winstuff.h" #endif - -#ifdef INTERNATIONAL -#include "BIF_language.h" -#endif - #include "IMB_imbuf_types.h" #include "DNA_image_types.h" -#include "DNA_object_types.h" #include "DNA_screen_types.h" #include "DNA_space_types.h" @@ -67,288 +61,241 @@ #include "BIF_toolbox.h" #include "BSE_drawipo.h" +#include "BSE_trans_types.h" -#include "BDR_vpaint.h" #include "BDR_drawmesh.h" +#include "BDR_imagepaint.h" +#include "BDR_vpaint.h" + +#include "IMG_Api.h" #include "mydevice.h" -#include "TPT_DependKludge.h" -#include "BSE_trans_types.h" -#include "IMG_Api.h" +struct ImagePaint Gip = { + {NULL, {0.0f, 0.0f}, 0.5f}, + {{{1.0f, 1.0f, 1.0f, 0.2f}, 25, 0.5f, 100.0f}, /* brush */ + {{1.0f, 1.0f, 1.0f, 0.1f}, 25, 0.1f, 100.0f}, /* airbrush */ + {{0.5f, 0.5f, 0.5f, 1.0f}, 25, 0.5f, 100.0f}, /* soften */ + {{1.0f, 1.0f, 1.0f, 0.1f}, 25, 0.1f, 100.0f}, /* aux1 */ + {{0.0f, 0.0f, 0.0f, 0.1f}, 25, 0.1f, 100.0f}, /* aux2 */ + {{1.0f, 1.0f, 1.0f, 0.5f}, 25, 0.1f, 20.0f}, /* smear */ + {{1.0f, 1.0f, 1.0f, 0.5f}, 25, 0.1f, 20.0f}}, /* clone */ + 0, IMAGEPAINT_BRUSH +}; -#include "SYS_System.h" /* for the user def menu ... should move elsewhere. */ +static int imagepaint_init(IMG_BrushPtr **brush, IMG_CanvasPtr **canvas, IMG_CanvasPtr **clonecanvas) +{ + ImBuf *ibuf= NULL, *cloneibuf= NULL; + ImagePaintTool *tool= &Gip.tool[Gip.current]; + /* verify that we can paint */ + if(!G.sima->image || !G.sima->image->ibuf) + return 0; + else if(G.sima->image->packedfile) { + error("Painting in packed images not supported"); + return 0; + } + ibuf= G.sima->image->ibuf; -/* this data should be a new datablock, used by G.sima .. G.sima->painttoolbox.yadayada */ -/* so get the rest working and then care for this */ -/* using UVTEXTTOOL_ as prefix so a grep will find 'em all later*/ -Image* UVTEXTTOOL_cloneimage = NULL; -short UVTEXTTOOL_imanr= -2; -float UVTEXTTOOL_cloneoffx = 0.0; -float UVTEXTTOOL_cloneoffy = 0.0; -float UVTEXTTOOL_clonealpha = 0.5; + if(Gip.current == IMAGEPAINT_CLONE) { + if(!Gip.clone.image || !Gip.clone.image->ibuf) + return 0; -short UVTEXTTOOL_POS[2]; -float UVTEXTTOOL_RAD[2]; -short UVTEXTTOOL_SHAPE; -short UVTEXTTOOL_INDEX = 0; -short UVTEXTTOOL_uiflags = 0; -BrushUIdata UVTEXTTOOL_DATA[7] = { - /* r,g,b,a,size,softradius,timing*/ - { 1.0f , 1.0f , 1.0f ,0.2f , 25.0f, 0.5f,100.0f}, /* brush */ - { 1.0f , 1.0f , 1.0f ,0.1f , 25.0f, 0.1f,100.0f}, /* air brush */ - { 0.5f , 0.5f , 0.5f ,1.0f , 25.0f, 0.5f,100.0f}, /* soften */ - { 1.0f , 1.0f , 1.0f ,0.1f , 25.0f, 0.1f,100.0f}, - { 0.0f , 0.0f , 0.0f ,0.1f , 25.0f, 0.1f,100.0f}, - { 1.0f , 0.0f , 1.0f ,0.5f , 25.0f, 0.1f, 20.0f}, - { 1.0f , 0.0f , 1.0f ,0.5f , 25.0f, 0.1f, 20.0f}}; + cloneibuf= Gip.clone.image->ibuf; + } + /* create brush */ + *brush= IMG_BrushCreate(tool->size, tool->size, tool->rgba); + IMG_BrushSetInnerRaduisRatio(*brush, tool->innerradius); + /* create canvas */ + *canvas= IMG_CanvasCreateFromPtr(ibuf->rect, ibuf->x, ibuf->y, ibuf->x*4); -void texturepaintoff() - { - UVTEXTTOOL_SHAPE = 0; + if(Gip.current == IMAGEPAINT_CLONE) { + int w= cloneibuf->x, h= cloneibuf->y; + *clonecanvas= IMG_CanvasCreateFromPtr(cloneibuf->rect, w, h, cloneibuf->x*4); } + else + *clonecanvas= NULL; + + /* initialize paint settings */ + if(Gip.current >= IMAGEPAINT_AIRBRUSH && Gip.current <= IMAGEPAINT_SOFTEN) + Gip.flag |= IMAGEPAINT_TIMED; + else + Gip.flag &= ~IMAGEPAINT_TIMED; + + return 1; +} -int uv_paint_panel_but(short val) +static void imagepaint_free(IMG_BrushPtr *brush, IMG_CanvasPtr *canvas, IMG_CanvasPtr *clonecanvas) { - /* but still i don't know if i like that crowded floating panel */ - switch(val){ - case PAINTPANELMESSAGEEATER: - force_draw(0);/* tool changes so redraw settings */ - } - return 0; + IMG_BrushDispose(brush); + IMG_CanvasDispose(canvas); + + if(Gip.current == IMAGEPAINT_CLONE) + IMG_CanvasDispose(clonecanvas); +} + +void imagepaint_redraw_tool(void) +{ + if(Gip.flag & IMAGEPAINT_DRAW_TOOL_DRAWING) + force_draw(0); } -int UVtimedaction(int action) +static void imagepaint_redraw(int final, int painted) { - if (( action== 1.0) - || (action == 2.0) - || (action == 3.0) - || (action == 4.0)) return 1; - return 0; + if(!final && !painted) { + imagepaint_redraw_tool(); + return; + } + + if(final || painted) { + if (final || G.sima->lock) { + /* Make OpenGL aware of a changed texture */ + free_realtime_image(G.sima->image); + force_draw_plus(SPACE_VIEW3D,0); + } + else + force_draw(0); + } + + if(final) + allqueue(REDRAWHEADERS, 0); } -void UVTexturePaintToolAt(short* where) -/* keep drawimage informed on actual tool position/setting */ +static void imagepaint_compute_uvco(short *mval, float *uv) { - SpaceImage *sima= curarea->spacedata.first; - BrushUIdata *data = NULL; - - data = &UVTEXTTOOL_DATA[UVTEXTTOOL_INDEX]; - if(!data) return; - UVTEXTTOOL_POS[0] = where[0]; - UVTEXTTOOL_POS[1] = where[1]; - UVTEXTTOOL_RAD[0] = data->size*sima->zoom/2; - UVTEXTTOOL_RAD[1] = data->softradius*data->size*sima->zoom/2; + areamouseco_to_ipoco(G.v2d, mval, &uv[0], &uv[1]); } -void UVTexturePaintMsg( void *spacedata, unsigned short event,short val,short paintmousebut) -/* handle events in texturepaint mode of UV-Image Editor*/ +static void imagepaint_paint_tool(IMG_BrushPtr *brush, IMG_CanvasPtr *canvas, IMG_CanvasPtr *clonecanvas, float *prevuv, float *uv) { - SpaceImage *sima= curarea->spacedata.first; - BrushUIdata *data=NULL; - IMG_BrushPtr brush; - IMG_CanvasPtr canvas,clonecanvas =NULL; - short xy_prev[2], xy_curr[2]; - static short dtxy_prev[2], dtxy_curr[2]; - float uv_prev[2], uv_curr[2]; - int rowBytes,clonerowBytes; - double brushtime; - int firsttouch = 1; - float duv[2]; - float dduv; - char extensionmode; - View2D *v2d= &sima->v2d; - - data = &UVTEXTTOOL_DATA[UVTEXTTOOL_INDEX]; - if (!data) return; - switch(event){ - case UI_BUT_EVENT: - { - if (uv_paint_panel_but(val)) break; + int torus = Gip.flag & IMAGEPAINT_TORUS; + ImagePaintTool *tool= &Gip.tool[Gip.current]; + + if(Gip.current == IMAGEPAINT_SOFTEN) + IMG_CanvasSoftenAt(canvas, prevuv[0], prevuv[1], tool->size, tool->rgba[3], tool->innerradius, torus); + else if(Gip.current == IMAGEPAINT_SMEAR) + IMG_CanvasSmear(canvas, prevuv[0], prevuv[1], uv[0], uv[1], tool->size, tool->rgba[3], tool->innerradius, torus); + else if(Gip.current == IMAGEPAINT_CLONE) { + float offx= Gip.clone.offset[0]; + float offy= Gip.clone.offset[1]; + + IMG_CanvasCloneAt(canvas, clonecanvas, prevuv[0], prevuv[1], offx, offy, tool->size, tool->rgba[3], tool->innerradius); } - case MOUSEX: - case MOUSEY: - { - /* tool preview */ - if (UVTEXTTOOL_uiflags & 2) { - getmouseco_areawin(dtxy_curr); - if ( dtxy_curr[0]!=dtxy_prev[0] || dtxy_curr[1]!=dtxy_prev[1]) { - UVTexturePaintToolAt(dtxy_curr); - UVTEXTTOOL_SHAPE = 1; - force_draw(0); - } - } - else { - UVTEXTTOOL_SHAPE = 0; - + else + IMG_CanvasDrawLineUVEX(canvas, brush, prevuv[0], prevuv[1], uv[0], uv[1], torus); +} + +void imagepaint_paint(short mousebutton) +{ + IMG_BrushPtr *brush; + IMG_CanvasPtr *canvas, *clonecanvas; + short prevmval[2], mval[2]; + double prevtime, curtime; + float prevuv[2], uv[2]; + int paint= 0, moved= 0; + ImagePaintTool *tool= &Gip.tool[Gip.current]; + + if(!imagepaint_init(&brush, &canvas, &clonecanvas)) + return; + + getmouseco_areawin(prevmval); + prevtime = PIL_check_seconds_timer(); + + Gip.flag |= IMAGEPAINT_DRAWING; + + while(get_mbut() & mousebutton) { + getmouseco_areawin(mval); + + moved= paint= (prevmval[0] != mval[0]) || (prevmval[1] != mval[1]); + + if(Gip.flag & IMAGEPAINT_TIMED) { + /* see if need to draw because of timer */ + curtime = PIL_check_seconds_timer(); + + if((curtime - prevtime) > (5.0/tool->timing)) { + prevtime= curtime; + paint= 1; } - + } + else if(paint) { + /* check if we moved enough to draw */ + float dmval[2], d, dlimit; - dtxy_prev[0] = dtxy_curr[0]; - dtxy_prev[1] = dtxy_curr[1]; - break; + dmval[0]= prevmval[0] - mval[0]; + dmval[1]= prevmval[1] - mval[1]; + + d= sqrt(dmval[0]*dmval[0] + dmval[1]*dmval[1]); + dlimit= tool->size*G.sima->zoom*tool->timing/200.0; + + if (d < dlimit) + paint= 0; } - - } - - - switch(event) { - case LEFTMOUSE: - /* Paranoia checks */ - if (!sima) break; - if (!sima->image) break; - if (!sima->image->ibuf) break; - if (sima->image->packedfile) { - error("Painting in packed images not supported"); - break; + + if(paint) { + /* do the actual painting */ + imagepaint_compute_uvco(prevmval, prevuv); + imagepaint_compute_uvco(mval, uv); + + imagepaint_paint_tool(brush, canvas, clonecanvas, prevuv, uv); + + prevmval[0]= mval[0]; + prevmval[1]= mval[1]; } - brush = IMG_BrushCreate((int)(data->size), (int)(data->size), data->r, data->g, data->b, data->a); + + if(paint) + imagepaint_redraw(0, paint); + else if(moved && (Gip.flag & IMAGEPAINT_DRAW_TOOL)) + imagepaint_redraw(0, paint); + } + + Gip.flag &= ~IMAGEPAINT_DRAWING; + + imagepaint_free(brush, canvas, clonecanvas); + G.sima->image->ibuf->userflags |= IB_BITMAPDIRTY; + + imagepaint_redraw(1, 0); +} + +void imagepaint_pick(short mousebutton) +{ + ImagePaintTool *tool= &Gip.tool[Gip.current]; + + if(Gip.current == IMAGEPAINT_CLONE) { + if(Gip.clone.image && Gip.clone.image->ibuf) { + short prevmval[2], mval[2]; + float prevuv[2], uv[2]; - IMG_BrushSetInnerRaduisRatio(brush,data->softradius); - /* skipx is not set most of the times. Make a guess. */ - rowBytes = sima->image->ibuf->skipx ? sima->image->ibuf->skipx : sima->image->ibuf->x * 4; - canvas = IMG_CanvasCreateFromPtr(sima->image->ibuf->rect, sima->image->ibuf->x, sima->image->ibuf->y, rowBytes); - if (UVTEXTTOOL_cloneimage){ - if (UVTEXTTOOL_cloneimage->ibuf){ - clonerowBytes = UVTEXTTOOL_cloneimage->ibuf->skipx ? UVTEXTTOOL_cloneimage->ibuf->skipx : UVTEXTTOOL_cloneimage->ibuf->x * 4; - clonecanvas = IMG_CanvasCreateFromPtr(UVTEXTTOOL_cloneimage->ibuf->rect, UVTEXTTOOL_cloneimage->ibuf->x, UVTEXTTOOL_cloneimage->ibuf->y, clonerowBytes); - } - } - getmouseco_areawin(xy_prev); - brushtime = PIL_check_seconds_timer(); - while (get_mbut() & paintmousebut) { - UVTEXTTOOL_SHAPE = 0; - getmouseco_areawin(xy_curr); - /* check for timed actions */ - if (UVtimedaction(UVTEXTTOOL_INDEX)){ - if ((PIL_check_seconds_timer()-brushtime) > (5.0/data->brushtiming) ) - { - brushtime=PIL_check_seconds_timer(); - firsttouch = 1; - xy_prev[0] = xy_curr[0]; - xy_prev[1] = xy_curr[1]; - } - } - /* check for movement actions */ - if ((xy_prev[0] != xy_curr[0]) || (xy_prev[1] != xy_curr[1]) || firsttouch) { - /* so now we know we did move at all */ - /* Convert mouse coordinates to u,v and draw */ - areamouseco_to_ipoco(v2d, xy_prev, &uv_prev[0], &uv_prev[1]); - areamouseco_to_ipoco(v2d, xy_curr, &uv_curr[0], &uv_curr[1]); - /* do some gearing down in % of brush diameter*/ - duv[0] = (float)(xy_prev[0]- xy_curr[0]); - duv[1] = (float)(xy_prev[1]- xy_curr[1]); - dduv = (float)sqrt(duv[0] * duv[0] + duv[1] * duv[1]); - if ((dduv < (data->size*sima->zoom * data->brushtiming/200.0) ) && (firsttouch == 0)){ - if (UVTEXTTOOL_uiflags & 1){ /* this spoils all efforts reducing redraw needs */ - static short m_prev[2]; - /* doing a brute force toolshape update by backbuffer drawing */ - if ((m_prev[0] != xy_curr[0]) || (m_prev[1] != xy_curr[1])) { - UVTexturePaintToolAt(xy_curr); - UVTEXTTOOL_SHAPE = UVTEXTTOOL_uiflags & 1; - force_draw(0); - } - m_prev[0] = xy_curr[0]; - m_prev[1] = xy_curr[1]; - } - continue; - } - /* respect timed actions */ - if (UVtimedaction(UVTEXTTOOL_INDEX) && (firsttouch == 0)){ - continue; - } - - - firsttouch = 0; - if (UVTEXTTOOL_uiflags & 4) - extensionmode = 't'; - else - extensionmode = 'c'; - switch(UVTEXTTOOL_INDEX) { - case 2: - IMG_CanvasSoftenAt(canvas,uv_prev[0],uv_prev[1],(int)(data->size),data->a,data->softradius,extensionmode); - break; - case 5: - IMG_CanvasSmear(canvas,uv_prev[0], uv_prev[1], uv_curr[0], uv_curr[1],(int)(data->size),data->a,data->softradius,extensionmode); - break; - case 6: - IMG_CanvasCloneAt(canvas,clonecanvas,uv_prev[0],uv_prev[1],UVTEXTTOOL_cloneoffx,UVTEXTTOOL_cloneoffy,(int)(data->size),data->a,data->softradius); - break; - default: -// IMG_CanvasDrawLineUVEX(canvas, brush, uv_prev[0], uv_prev[1], uv_curr[0], uv_curr[1],'c'); - IMG_CanvasDrawLineUVEX(canvas, brush, uv_prev[0], uv_prev[1], uv_curr[0], uv_curr[1],extensionmode); - } - - if (G.sima->lock) { - /* Make OpenGL aware of a changed texture */ - free_realtime_image(sima->image); - /* Redraw this view and the 3D view */ - UVTexturePaintToolAt(xy_curr); - UVTEXTTOOL_SHAPE = UVTEXTTOOL_uiflags & 1; - force_draw_plus(SPACE_VIEW3D,0); - - } - else { - /* Redraw only this view */ - UVTexturePaintToolAt(xy_curr); - UVTEXTTOOL_SHAPE = UVTEXTTOOL_uiflags & 1; + getmouseco_areawin(prevmval); + + while(get_mbut() & mousebutton) { + getmouseco_areawin(mval); + + if((prevmval[0] != mval[0]) || (prevmval[1] != mval[1]) ) { + /* mouse moved, so move the clone image */ + imagepaint_compute_uvco(prevmval, prevuv); + imagepaint_compute_uvco(mval, uv); + + Gip.clone.offset[0] += uv[0] - prevuv[0]; + Gip.clone.offset[1] += uv[1] - prevuv[1]; + force_draw(0); + + prevmval[0]= mval[0]; + prevmval[1]= mval[1]; } - - xy_prev[0] = xy_curr[0]; - xy_prev[1] = xy_curr[1]; } } - UVTEXTTOOL_SHAPE = UVTEXTTOOL_uiflags & 2; - /* Set the dirty bit in the image so that it is clear that it has been modified. */ - sima->image->ibuf->userflags |= IB_BITMAPDIRTY; - if (!G.sima->lock) { - /* Make OpenGL aware of a changed texture */ - free_realtime_image(sima->image); - /* Redraw this view and the 3D view */ - force_draw_plus(SPACE_VIEW3D,0); - } - IMG_BrushDispose(brush); - IMG_CanvasDispose(canvas); - if (clonecanvas) IMG_CanvasDispose(clonecanvas); - allqueue(REDRAWHEADERS, 0); + } + else { + extern VPaint Gvp; - break; - case RIGHTMOUSE: - { - extern float UVTEXTTOOL_cloneoffx; - extern float UVTEXTTOOL_cloneoffy; - /* call the color lifter */ - if (UVTEXTTOOL_INDEX==6){ - getmouseco_areawin(xy_prev); - while (get_mbut() & paintmousebut) { - getmouseco_areawin(xy_curr); - /* check for movement actions */ - if ((xy_prev[0] != xy_curr[0]) || (xy_prev[1] != xy_curr[1]) ) { - /* so now we know we did move at all */ - /* Convert mouse coordinates to u,v and draw */ - areamouseco_to_ipoco(v2d, xy_prev, &uv_prev[0], &uv_prev[1]); - areamouseco_to_ipoco(v2d, xy_curr, &uv_curr[0], &uv_curr[1]); - UVTEXTTOOL_cloneoffx += uv_curr[0] -uv_prev[0]; - UVTEXTTOOL_cloneoffy += uv_curr[1] -uv_prev[1]; - force_draw(0); - - - - } - xy_prev[0] = xy_curr[0]; - xy_prev[1] = xy_curr[1]; - - } - } - else sample_vpaint(); - break; - } - - } - + sample_vpaint(); + tool->rgba[0]= Gvp.r; + tool->rgba[1]= Gvp.g; + tool->rgba[2]= Gvp.b; + } } + |