having a "mini gimp" in image editor

{ hope it does not break builds .. mscv6 .. scons works fine here }
This commit is contained in:
Jens Ole Wund 2005-09-09 22:31:23 +00:00
parent 9d2f0fe302
commit 42ee04702c
13 changed files with 990 additions and 70 deletions

@ -423,6 +423,10 @@ SOURCE=..\..\..\source\blender\src\headerbuttons.c
# End Source File
# Begin Source File
SOURCE=..\..\..\source\blender\src\imagepaint.c
# End Source File
# Begin Source File
SOURCE=..\..\..\source\blender\src\imasel.c
# End Source File
# Begin Source File

@ -46,6 +46,7 @@ extern "C" {
extern IMG_BrushPtr IMG_BrushCreate(unsigned int width, unsigned int height, float red, float green, float blue, float alpha);
extern void IMG_BrushDispose(IMG_BrushPtr brush);
extern void IMG_BrushSetInnerRaduisRatio(IMG_BrushPtr brush,float aspect);
extern IMG_CanvasPtr IMG_CanvasCreate(unsigned int width, unsigned int height);
extern IMG_CanvasPtr IMG_CanvasCreateFromPtr(void* imagePtr, unsigned int width, unsigned int height, size_t rowBytes);
@ -54,6 +55,11 @@ extern void IMG_CanvasDraw(IMG_CanvasPtr canvas, IMG_BrushPtr brush, unsigned
extern void IMG_CanvasDrawUV(IMG_CanvasPtr canvas, IMG_BrushPtr brush, float u, float v);
extern void IMG_CanvasDrawLine(IMG_CanvasPtr canvas, IMG_BrushPtr brush, unsigned int xStart, unsigned int yStart, unsigned int xEns, unsigned int yEnd);
extern void IMG_CanvasDrawLineUV(IMG_CanvasPtr canvas, IMG_BrushPtr brush, float uStart, float vStart, float uEnd, float vEnd);
extern void IMG_CanvasDrawLineUVEX(IMG_CanvasPtr canvas, IMG_BrushPtr brush, float uStart, float vStart, float uEnd, float vEnd,char mode);
extern void IMG_CanvasSoftenAt(IMG_CanvasPtr canvas,float u, float v, unsigned int size,float alpha, float aspect,char mode);
extern void IMG_CanvasFill(IMG_CanvasPtr canvas, float red, float green, float blue, float alpha);
extern void IMG_CanvasSmear(IMG_CanvasPtr canvas,float uStart, float vStart, float uEnd, float vEnd, unsigned int size, float alpha, float aspect,char mode);
extern void IMG_CanvasCloneAt(IMG_CanvasPtr canvas,IMG_CanvasPtr other,float u,float v,float cu,float cv,int size,float alpha,float aspect);
#ifdef __cplusplus
}

@ -59,6 +59,23 @@ void IMG_BrushDispose(IMG_BrushPtr brush)
}
}
void IMG_BrushSetInnerRaduisRatio(IMG_BrushPtr brush,float aspect)
{
if (brush) {
TUns32 he = ((IMG_BrushRGBA32*)brush)->getHeight();
TUns32 we = ((IMG_BrushRGBA32*)brush)->getWidth();
TUns32 si = we;
if (he > si) si = we;
he = si/2;
we = (TUns32)(aspect*si/2);
if (we < 2) we = 2;
((IMG_BrushRGBA32*)brush)->setRadii(we,he);
}
}
IMG_CanvasPtr IMG_CanvasCreate(unsigned int w, unsigned int h)
{
@ -121,3 +138,34 @@ void IMG_CanvasDrawLineUV(IMG_CanvasPtr canvas, IMG_BrushPtr brush, float uStart
if (!(canvas && brush)) return;
((IMG_CanvasRGBA32*)canvas)->blendPixmap(uStart, vStart, uEnd, vEnd, *((IMG_BrushRGBA32*)brush));
}
void IMG_CanvasDrawLineUVEX(IMG_CanvasPtr canvas, IMG_BrushPtr brush, float uStart, float vStart, float uEnd, float vEnd,char mode)
{
if (!(canvas && brush)) return;
((IMG_CanvasRGBA32*)canvas)->blendPixmap(uStart, vStart, uEnd, vEnd, *((IMG_BrushRGBA32*)brush),mode);
}
void IMG_CanvasSoftenAt(IMG_CanvasPtr canvas,float u, float v, unsigned int size,float alpha, float aspect,char mode)
{
((IMG_CanvasRGBA32*)canvas)->SoftenAt(u,v,(TUns32)size,alpha,aspect,mode);
}
void IMG_CanvasFill(IMG_CanvasPtr canvas,float red, float green, float blue, float alpha)
{
IMG_ColorRGB c (red, green, blue);
IMG_Rect R (0, 0, ((IMG_CanvasRGBA32*)canvas)->getWidth(),
((IMG_CanvasRGBA32*)canvas)->getHeight()); // Bounds of this pixmap
((IMG_CanvasRGBA32*)canvas)->fillRect(R,c);
}
void IMG_CanvasSmear(IMG_CanvasPtr canvas,float uStart, float vStart, float uEnd, float vEnd, unsigned int size, float alpha, float aspect,char mode)
{
((IMG_CanvasRGBA32*)canvas)->Smear(uStart,vStart,uEnd,vEnd,size,alpha,aspect,mode);
}
void IMG_CanvasCloneAt(IMG_CanvasPtr canvas,IMG_CanvasPtr other,float u,float v,float cu,float cv,int size,float alpha,float aspect)
{
((IMG_CanvasRGBA32*)canvas)->CloneAt((IMG_CanvasRGBA32*)other, u, v, cu, cv, size, alpha, aspect);
}

@ -48,16 +48,18 @@ IMG_CanvasRGBA32::IMG_CanvasRGBA32(void* image, TUns32 width, TUns32 height, TUn
void IMG_CanvasRGBA32::blendPixmap(
TUns32 xStart, TUns32 yStart, TUns32 xEnd, TUns32 yEnd,
const IMG_PixmapRGBA32& pixmap)
const IMG_PixmapRGBA32& pixmap,char mode)
{
// Determine visibility of the line
IMG_Line l (xStart, yStart, xEnd, yEnd); // Line used for blending
IMG_Rect bnds (0, 0, m_width, m_height); // Bounds of this pixmap
TVisibility v = bnds.getVisibility(l);
if (mode == 'c'){
if (v == kNotVisible) return;
if (v == kPartiallyVisible) {
bnds.clip(l);
}
}
float numSteps = (((float)l.getLength()) / ((float)pixmap.getWidth() / 4));
//numSteps *= 4;
@ -66,7 +68,12 @@ void IMG_CanvasRGBA32::blendPixmap(
TInt32 x, y;
for (TUns32 s = 0; s < numSteps; s++) {
l.getPoint(step, x, y);
if (mode == 'c') {
IMG_PixmapRGBA32::blendPixmap((TUns32)x, (TUns32)y, pixmap);
}
else {
if (mode == 't') IMG_PixmapRGBA32::blendPixmapTorus((TUns32)x, (TUns32)y, pixmap);
}
step += stepSize;
}
}
@ -74,11 +81,257 @@ void IMG_CanvasRGBA32::blendPixmap(
void IMG_CanvasRGBA32::blendPixmap(
float uStart, float vStart, float uEnd, float vEnd,
const IMG_PixmapRGBA32& pixmap)
const IMG_PixmapRGBA32& pixmap, char mode)
{
TUns32 xStart, yStart, xEnd, yEnd;
getPixelAddress(uStart, vStart, xStart, yStart);
getPixelAddress(uEnd, vEnd, xEnd, yEnd);
blendPixmap(xStart, yStart, xEnd, yEnd, pixmap);
blendPixmap(xStart, yStart, xEnd, yEnd, pixmap,mode);
}
void IMG_CanvasRGBA32::SoftenAt(float u, float v, TUns32 size, float alpha, float aspect,char mode)
{
IMG_BrushRGBA32* brush = 0;
int flag=0;
try {
IMG_ColorRGB c (1.0, 1.0, 1.0);
brush = new IMG_BrushRGBA32 (size, size, c, alpha);
}
catch (...) {
/* no brush , no fun ! */
return;
}
TUns32 ro,ri;
ro = size/2;
ri = (int)(aspect/2.0f * size);
if (ri > 2 ) ri =2;
if (ri > ro ) ri =ro;
brush->setRadii(ri,ro);
TUns32 x, y;
TUns32 xx, yy;
getPixelAddress(u, v, x, y);
xx = x - size/2;
yy = y - size/2;
if(mode == 't') flag = 1;
/* now modify brush */
for (int i= 0 ; i<(int)size;i++){
for (int j= 0 ; j<(int)size;j++){
float sR,sG,sB,sA;
float cR,cG,cB=0.0;
if(mode == 't')
IMG_PixmapRGBA32::getRGBAatTorus(xx+i,yy+j ,&cR,&cG,&cB,0);
else
IMG_PixmapRGBA32::getRGBAat(xx+i,yy+j ,&cR,&cG,&cB,0);
int ccount = 1;
/*
cR += 7.0*cR;
cG += 7.0*cG;
cB += 7.0*cB;
ccount += 7.0;
*/
add_if_in(xx+i+1,yy+j+1,cR,cG,cB,ccount,flag);
add_if_in(xx+i+1,yy+j ,cR,cG,cB,ccount,flag);
add_if_in(xx+i+1,yy+j-1,cR,cG,cB,ccount,flag);
add_if_in(xx+i,yy+j+1,cR,cG,cB,ccount,flag);
add_if_in(xx+i,yy+j-1,cR,cG,cB,ccount,flag);
add_if_in(xx+i-1,yy+j+1,cR,cG,cB,ccount,flag);
add_if_in(xx+i-1,yy+j ,cR,cG,cB,ccount,flag);
add_if_in(xx+i-1,yy+j-1,cR,cG,cB,ccount,flag);
sR =cR*255.0f/ccount;
sG =cG*255.0f/ccount;
sB =cB*255.0f/ccount;
sA =255.0;
brush->setRGBAat(i,j,&sR,&sG,&sB,NULL);
}
}
/* apply */
if(mode == 't')
IMG_PixmapRGBA32::blendPixmapTorus(x, y, *brush);
else
IMG_PixmapRGBA32::blendPixmap(x, y, *brush);
/* done clean up */
if (brush) {
delete ((IMG_BrushRGBA32*)brush);
brush = 0;
}
}
IMG_BrushRGBA32* IMG_CanvasRGBA32::LiftBrush(TUns32 x, TUns32 y, TUns32 size, float alpha, float aspect, short flags )
{
IMG_BrushRGBA32* brush = 0;
float mR,mG,mB=0.0;
try {
IMG_ColorRGB c (1.0, 1.0, 1.0);
brush = new IMG_BrushRGBA32 (size, size, c, alpha);
}
catch (...) {
/* no brush , no fun ! */
return(NULL);
}
TUns32 ro,ri;
ro = size/2;
ri = (int)(aspect/2.0f * size);
if (ri > 2 ) ri =2;
if (ri > ro ) ri =ro;
brush->setRadii(ri,ro);
TUns32 xx, yy;
xx = x - size/2;
yy = y - size/2;
IMG_PixmapRGBA32::getRGBAat(xx,yy,&mR,&mG,&mB,0);
for (int i= 0 ; i<(int)size;i++){
for (int j= 0 ; j<(int)size;j++){
float cR,cG,cB,cA=0.0;
cR = mR; cG = mG; cB = mB;
int res =IMG_PixmapRGBA32::getRGBAat(xx+i,yy+j ,&cR,&cG,&cB,0);
cR *= 255.0f;
cG *= 255.0f;
cB *= 255.0f;
cA *= 0.0;
if (res)
brush->setRGBAat(i,j,&cR,&cG,&cB,NULL);
else
brush->setRGBAat(i,j,&cR,&cG,&cB,&cA);
}
}
return(brush);
}
IMG_BrushRGBA32* IMG_CanvasRGBA32::LiftBrush(float u, float v, TUns32 size, float alpha, float aspect, short flags )
{
IMG_BrushRGBA32* brush = 0;
float mR,mG,mB=0.0;
try {
IMG_ColorRGB c (1.0, 1.0, 1.0);
brush = new IMG_BrushRGBA32 (size, size, c, alpha);
}
catch (...) {
/* no brush , no fun ! */
return(NULL);
}
TUns32 ro,ri;
ro = size/2;
ri = (int)(aspect/2.0f * size);
if (ri > 2 ) ri =2;
if (ri > ro ) ri =ro;
brush->setRadii(ri,ro);
TUns32 x, y;
TUns32 xx, yy;
getPixelAddress(u, v, x, y);
xx = x - size/2;
yy = y - size/2;
IMG_PixmapRGBA32::getRGBAat(xx,yy,&mR,&mG,&mB,0);
for (int i= 0 ; i<(int)size;i++){
for (int j= 0 ; j<(int)size;j++){
float cR,cG,cB=0.0;
if (flags & 0x1)
IMG_PixmapRGBA32::getRGBAatTorus(xx+i,yy+j ,&cR,&cG,&cB,0);
else {
cR = mR; cG = mG; cB = mB;
IMG_PixmapRGBA32::getRGBAat(xx+i,yy+j ,&cR,&cG,&cB,0);
}
cR *= 255.0f;
cG *= 255.0f;
cB *= 255.0f;
brush->setRGBAat(i,j,&cR,&cG,&cB,NULL);
}
}
return(brush);
}
void IMG_CanvasRGBA32::Smear(float uStart, float vStart, float uEnd, float vEnd, TUns32 size, float alpha, float aspect,char mode)
{
IMG_BrushRGBA32* brush = NULL;
float du,dv;
du = uEnd - uStart;
dv = vEnd - vStart;
try {
brush = LiftBrush(uStart-du,vStart-dv,size,alpha,aspect,1);
}
catch (...) {
/* no brush , no fun ! */
return;
}
if (brush){
blendPixmap(uStart,vStart,uEnd,vEnd,*brush,mode);
delete(brush);
}
}
void IMG_CanvasRGBA32::CloneAt(IMG_CanvasRGBA32* other,float u,float v,float cu,float cv,TUns32 size,float alpha,float aspect)
{
TUns32 x, y;
TUns32 cx, cy;
TUns32 xx, yy;
getPixelAddress(u, v, x, y);
getPixelAddress(cu, cv, cx, cy);
xx = (x-cx);// - size/2;
yy = (y-cy);// - size/2;
if (other == NULL) return;
IMG_BrushRGBA32* brush = NULL;
try {
brush = other->LiftBrush(xx,yy,size,alpha,aspect,1);
}
catch (...) {
/* no brush , no fun ! */
return;
}
if (brush){
IMG_PixmapRGBA32::blendPixmap(x, y, *brush);
delete(brush);
}
}
int IMG_CanvasRGBA32::add_if_in(int x, int y,float &R,float &G,float &B, int &count, short flags)
{
float r,g,b= 0.0f;
if ((flags & 0x1) == 0)
{
if (IMG_PixmapRGBA32::getRGBAat(x,y,&r,&g,&b,0))
{
R += r;
G += g;
B += b;
count++;
}
}
else {
IMG_PixmapRGBA32::getRGBAatTorus(x,y,&r,&g,&b,0);
R += r;
G += g;
B += b;
count++;
}
return 1;
}

@ -46,6 +46,12 @@
class IMG_CanvasRGBA32 : public IMG_PixmapRGBA32 {
public:
int add_if_in(int x, int y,float &R,float &G,float &B, int &count, short flags);
void Smear(float uStart, float vStart, float uEnd, float vEnd ,TUns32 size, float alpha, float aspect,char mode);
IMG_BrushRGBA32* LiftBrush(float u, float v, TUns32 size, float alpha, float aspect, short flags );
IMG_BrushRGBA32* LiftBrush(TUns32 x, TUns32 y, TUns32 size, float alpha, float aspect, short flags);
void SoftenAt(float u,float v,TUns32 size,float alpha,float aspect,char mode);
void CloneAt(IMG_CanvasRGBA32* other,float u,float v,float cu,float cv,TUns32 size,float alpha,float aspect);
/**
* Constructor.
* @throw <IMG_MemPtr::Size> when an invalid width and/or height is passed.
@ -76,7 +82,7 @@ public:
* @param y y-coordinate of the center location of the image.
* @param pixmap the pixmap to blend
*/
virtual void blendPixmap(TUns32 xStart, TUns32 yStart, TUns32 xEnd, TUns32 yEnd, const IMG_PixmapRGBA32& pixmap);
virtual void blendPixmap(TUns32 xStart, TUns32 yStart, TUns32 xEnd, TUns32 yEnd, const IMG_PixmapRGBA32& pixmap,char mode = 'c');
/**
* Blends a pixmap into this pixmap over a line in (u,v) coordinates.
@ -88,7 +94,7 @@ public:
* @param v v-coordinate of the center location of the image.
* @param pixmap the pixmap to blend
*/
virtual void blendPixmap(float uStart, float vStart, float uEnd, float vEnd, const IMG_PixmapRGBA32& pixmap);
virtual void blendPixmap(float uStart, float vStart, float uEnd, float vEnd, const IMG_PixmapRGBA32& pixmap,char mode = 'c');
};

@ -262,3 +262,71 @@ void IMG_PixmapRGBA32::blendPixmap(float u, float v, const IMG_PixmapRGBA32& pix
getPixelAddress(u, v, x, y);
blendPixmap(x, y, pixmap);
}
int IMG_PixmapRGBA32::getRGBAat(TUns32 x, TUns32 y, float *R, float *G, float *B, float *A) const
{
TPixelPtr srcPtr = 0;
if ((x >= m_width) || (y >= m_height) ) return 0;
srcPtr = getPixelPtr(x,y);
if (srcPtr){
IMG_ColorRGBA srcColor;
getColor(*srcPtr, srcColor);
if(R) *R = srcColor.m_r;
if(G) *G = srcColor.m_g;
if(B) *B = srcColor.m_b;
if(A) *A = srcColor.m_a;
return 1;
}
return 0;
}
int IMG_PixmapRGBA32::getRGBAatTorus(int x, int y, float *R, float *G, float *B, float *A)
{
x %= m_width;
y %= m_height;
return getRGBAat(x,y,R,G,B,A);
}
void IMG_PixmapRGBA32::setRGBAat(TUns32 x, TUns32 y, float *R, float *G, float *B, float *A)
{
TPixelPtr desPtr = 0;
desPtr = getPixelPtr(x,y);
if (desPtr){
if(R) ((TUns8*)desPtr)[bi_r] = (TUns8)(*R);
if(G) ((TUns8*)desPtr)[bi_g] = (TUns8)(*G);
if(B) ((TUns8*)desPtr)[bi_b] = (TUns8)(*B);
if(A) ((TUns8*)desPtr)[bi_a] = (TUns8)(*A);
}
}
void IMG_PixmapRGBA32::blendPixmapTorus(TUns32 x, TUns32 y,const IMG_PixmapRGBA32 &pixmap)
{
float sR,sG,sB,sA, bR,bG,bB,bA;
IMG_Rect bnds;
pixmap.getBounds(bnds);
int ym = bnds.getHeight();
int xm = bnds.getWidth();
for (int xa = 0; xa < xm; xa ++)
for (int ya = 0; ya < ym; ya ++){
int xt = (xa-xm/2 + x) % (m_width );
int yt = (ya-xm/2 + y) % (m_height);
getRGBAat(xt,yt,&sR,&sG,&sB,&sA);
pixmap.getRGBAat(xa,ya,&bR,&bG,&bB,&bA);
sR = sR*(1-bA) + bR*bA;
sG = sG*(1-bA) + bG*bA;
sB = sB*(1-bA) + bB*bA;
sR *= 255.0f;
sG *= 255.0f;
sB *= 255.0f;
setRGBAat(xt,yt,&sR,&sG,&sB,0);
}
}

@ -49,6 +49,11 @@
class IMG_PixmapRGBA32 : public IMG_Pixmap {
public:
virtual void blendPixmapTorus(TUns32 x, TUns32 y,const IMG_PixmapRGBA32& pixmap);
void setRGBAat(TUns32 x, TUns32 y, float* R, float* G, float* B,float* A);
int getRGBAat(TUns32 x, TUns32 y, float* R, float* G, float* B,float* A) const;
int getRGBAatTorus(int x, int y, float *R, float *G, float *B, float *A);
/**
* The pixel type in this pixmap.
*/

@ -85,5 +85,14 @@ typedef struct VPaint {
short mode, flag;
} VPaint;
/*BM_TEXTUREPAINT */
typedef struct BrushUIdata {
float r, g, b, a;
float size;
float softradius;
float brushtiming;
} BrushUIdata;
#define PAINTPANELMESSAGEEATER 9000
#endif /* BSE_TRANS_TYPES_H */

@ -89,6 +89,7 @@ source_files = ['B.blend.c',
'header_text.c',
'header_time.c',
'header_view3d.c',
'imagepaint.c',
'imasel.c',
'interface.c',
'interface_panel.c',

@ -89,6 +89,64 @@
#include "mydevice.h"
#include "blendef.h"
#include "butspace.h" // event codes
// #ifdef BM_TEXTUREPAINT
extern Image* UVTEXTTOOL_cloneimage;
extern short UVTEXTTOOL_imanr;
extern short UVTEXTTOOL_POS[];
extern float UVTEXTTOOL_RAD[];
extern short UVTEXTTOOL_SHAPE;
extern short UVTEXTTOOL_INDEX;
extern short UVTEXTTOOL_uiflags;
extern float UVTEXTTOOL_cloneoffx;
extern float UVTEXTTOOL_cloneoffy;
extern float UVTEXTTOOL_clonealpha;
extern BrushUIdata UVTEXTTOOL_DATA[];
void setcloneimagealpha(char a,unsigned int *rect)
{
unsigned int size;
char *cp= (char *)rect;
if (UVTEXTTOOL_cloneimage == NULL) return;
if (rect == NULL) return;
size = UVTEXTTOOL_cloneimage->ibuf->x*UVTEXTTOOL_cloneimage->ibuf->y;
while(size-- > 0) {
cp[3]= a;
cp+= 4;
}
}
/* resolve UVTEXTTOOL_imanr to set UVTEXTTOOL_cloneimage pointer */
void setcloneimage()
{
int nr;
ID *id, *idtest;
UVTEXTTOOL_cloneimage = NULL;
if (UVTEXTTOOL_imanr){
nr= 1;
id= (ID *)UVTEXTTOOL_cloneimage;
idtest= G.main->image.first;
while(idtest) {
if(nr==UVTEXTTOOL_imanr) {
break;
}
nr++;
idtest= idtest->next;
}
if(idtest==0) {
return;
}
if(idtest!=id) {
UVTEXTTOOL_cloneimage= (Image *)idtest;
}
}
}
/**
* Sets up the fields of the View2D member of the SpaceImage struct
@ -561,6 +619,17 @@ static void draw_image_view_icon(void)
glDisable(GL_BLEND);
}
// #ifdef BM_TEXTUREPAINT
static void draw_image_view_tool(void)
{
if(UVTEXTTOOL_SHAPE) {
fdrawXORcirc(UVTEXTTOOL_POS[0],UVTEXTTOOL_POS[1],UVTEXTTOOL_RAD[0]);
if ( UVTEXTTOOL_RAD[0] != UVTEXTTOOL_RAD[1])
fdrawXORcirc(UVTEXTTOOL_POS[0],UVTEXTTOOL_POS[1],UVTEXTTOOL_RAD[1]);
}
}
/* ************ panel stuff ************* */
// button define is local, only events defined here possible
@ -726,6 +795,23 @@ void do_imagebuts(unsigned short event)
}
}
break;
// #ifdef BM_TEXTUREPAINT
case B_SIMABROWSE:
setcloneimage();
UVTEXTTOOL_cloneoffx = 0.0;
UVTEXTTOOL_cloneoffy = 0.0;
allqueue(REDRAWIMAGE, 0);
image_changed(G.sima, 0);
break;
case B_IMAGEDELETE:
UVTEXTTOOL_cloneimage=NULL;
UVTEXTTOOL_imanr = -2;
allqueue(REDRAWIMAGE, 0);
image_changed(G.sima, 0);
break;
}
}
@ -762,24 +848,65 @@ static void image_panel_properties(short cntrl) // IMAGE_HANDLER_PROPERTIES
image_editvertex_buts(block);
}
// #ifdef BM_TEXTUREPAINT
static void image_panel_paint(short cntrl) // IMAGE_HANDLER_PROPERTIES
{
extern VPaint Gvp; /* from vpaint - this was copied from the paint panel*/
static float hsv[3], old[3]; // used as temp mem for picker
BrushUIdata *data = NULL;
uiBlock *block;
data = &UVTEXTTOOL_DATA[UVTEXTTOOL_INDEX];
if (!data) return;
block= uiNewBlock(&curarea->uiblocks, "image_panel_paint", UI_EMBOSS, UI_HELV, curarea->win);
uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl);
uiSetPanelHandler(IMAGE_HANDLER_PAINT); // for close and esc
if(uiNewPanel(curarea, block, "Paint", "Image", 10, 230, 318, 204)==0)
if(uiNewPanel(curarea, block, "Image Paint", "Image", 10, 230, 318, 204)==0)
return;
uiBlockPickerButtons(block, &Gvp.r, hsv, old, 'f', B_NOP); /* 'f' is for floating panel */
// offset= FPICK+2*DPICK+BPICK in interface.c... this goes wrong when defines change
/* Having that nice color picker we won't need that
uiBlockBeginAlign(block);
uiDefButF(block, NUM, B_NOP, "A: ", 180+12+24,160,80,20, &Gvp.a, 0.0, 1.0, 0, 0, "The amount of pressure on the brush");
uiDefButF(block, NUM, B_NOP, "Size ", 180+12+24,140,80,20, &Gvp.size, 2.0, 64.0, 0, 0, "The size of the brush");
uiDefButF(block, NUMSLI, 0, "R ", 979,160,194,19, &data->r, 0.0, 1.0, B_VPCOLSLI, 0, "The amount of red used for painting");
uiDefButF(block, NUMSLI, 0, "G ", 979,140,194,19, &data->g, 0.0, 1.0, B_VPCOLSLI, 0, "The amount of green used for painting");
uiDefButF(block, NUMSLI, 0, "B ", 979,120,194,19, &data->b, 0.0, 1.0, B_VPCOLSLI, 0, "The amount of blue used for painting");
uiBlockEndAlign(block);
*/
// uiDefButF(block, COL, B_VPCOLSLI, "", 979,160,230,19, &(data->r), 0, 0, 0, 0, "");
uiBlockBeginAlign(block);
uiDefButF(block, COL, B_VPCOLSLI, "", 979,160,230,19, &(data->r), 0, 0, 0, 0, "");
uiDefButF(block, NUMSLI, 0, "Opacity ", 979,140,230,19, &data->a, 0.0, 1.0, 0, 0, "The amount of pressure on the brush");
uiDefButF(block, NUMSLI, 0, "Size ", 979,120,230,19, &data->size, 2.0, 64.0, 0, 0, "The size of the brush");
uiDefButF(block, NUMSLI, 0, "Fall ", 979,100,230,19, &data->softradius, 0.0, 1.0, 0, 0, "The fall off radius of the brush");
if((UVTEXTTOOL_INDEX ==0) || (UVTEXTTOOL_INDEX ==5) ){ /* brush has no flow */
uiDefButF(block, NUMSLI, 0, "Stepsize ", 979,80,230,19, &data->brushtiming, 1.0, 100.0, 0, 0, "Repeating Paint On %of Brush diameter");
}
else { /* but stepsize */
uiDefButF(block, NUMSLI, 0, "Flow ", 979,80,230,19, &data->brushtiming, 1.0, 100.0, 0, 0, "Paint Flow for Air Brush");
}
uiBlockEndAlign(block);
uiBlockBeginAlign(block);
/* FLOATPANELMESSAGEEATER catching LMB on the panel buttons */
/* so LMB does not "GO" through the floating panel */
uiDefButS(block,ROW, PAINTPANELMESSAGEEATER ,"Brush",890,160,80,19,&UVTEXTTOOL_INDEX, 7.0, 0.0, 0, 0, "Brush");
uiDefButS(block,ROW, PAINTPANELMESSAGEEATER ,"AirBrush" ,890,140,80,19,&UVTEXTTOOL_INDEX, 7.0, 1.0, 0, 0, "AirBrush");
uiDefButS(block,ROW, PAINTPANELMESSAGEEATER ,"Soften" ,890,120,80,19,&UVTEXTTOOL_INDEX, 7.0, 2.0, 0, 0, "Soften");
uiDefButS(block,ROW, PAINTPANELMESSAGEEATER ,"Aux AB1" ,890,100,80,19,&UVTEXTTOOL_INDEX, 7.0, 3.0, 0, 0, "Aux Air Brush1");
uiDefButS(block,ROW, PAINTPANELMESSAGEEATER ,"Aux AB2" ,890,80,80,19,&UVTEXTTOOL_INDEX, 7.0, 4.0, 0, 0, "Aux Air Brush2");
uiDefButS(block,ROW, PAINTPANELMESSAGEEATER ,"Smear " ,890,60,80,19,&UVTEXTTOOL_INDEX, 7.0, 5.0, 0, 0, "Smaer");
uiDefButS(block,ROW, PAINTPANELMESSAGEEATER ,"Clone " ,890,40,80,19,&UVTEXTTOOL_INDEX, 7.0, 6.0, 0, 0, "Clone Brush / use RMB to drag source image");
uiBlockEndAlign(block);
setcloneimage();
uiBlockBeginAlign(block);
std_libbuttons(block, 979, 40, 0, NULL, B_SIMABROWSE, (ID *)UVTEXTTOOL_cloneimage , 0,&UVTEXTTOOL_imanr, 0, 0, B_IMAGEDELETE, 0, 0);
uiDefButF(block, NUMSLI, 0, "B ",979,20,230,19,&UVTEXTTOOL_clonealpha , 0.0, 1.0, 0, 0, "Blend clone image");
uiBlockEndAlign(block);
// uiDefButF(block, NUMSLI, 0, "B", 1100,1,100,19,&UVTEXTTOOL_clonealpha , 0.0, 1.0, 0, 0, "Blend clone image");
uiDefButS(block, TOG|BIT|0, 9999, "TD",890,1,50,19,&UVTEXTTOOL_uiflags, 0, 0, 0, 0, "Enables tool shape while drawing");
uiDefButS(block, TOG|BIT|1, 9999, "TP",940,1,50,19,&UVTEXTTOOL_uiflags, 0, 0, 0, 0, "Enables tool shape while not drawing");
uiDefButS(block, TOG|BIT|2, 9999, "Torus",990,1,50,19,&UVTEXTTOOL_uiflags, 0, 0, 0, 0, "Enables torus wrapping");
}
static void image_blockhandlers(ScrArea *sa)
@ -841,7 +968,6 @@ void drawimagespace(ScrArea *sa, void *spacedata)
tag_image_time(G.sima->image);
ibuf= G.sima->image->ibuf;
}
if(ibuf==0 || ibuf->rect==0) {
calc_image_view(G.sima, 'f');
myortho2(G.v2d->cur.xmin, G.v2d->cur.xmax, G.v2d->cur.ymin, G.v2d->cur.ymax);
@ -916,6 +1042,37 @@ void drawimagespace(ScrArea *sa, void *spacedata)
else
glaDrawPixelsSafe(x1, y1, ibuf->x, ibuf->y, ibuf->rect);
// #ifdef BM_TEXTUREPAINT
setcloneimage();
if (UVTEXTTOOL_cloneimage){
unsigned int* clonedrect=NULL;
if(UVTEXTTOOL_cloneimage->ibuf==0) {
load_image(UVTEXTTOOL_cloneimage, IB_rect, G.sce, G.scene->r.cfra);
}
if (UVTEXTTOOL_cloneimage->ibuf){ /* full paranoia check */
if (UVTEXTTOOL_cloneimage->ibuf->rect){
/* make a copy of image data so we can modify alpha for drawing */
/* ok this is kind of brute force, since it copies all the time */
/* but keeps code simple .. no need for globals etc.. */
/* and is save if global UVTEXTTOOL_cloneimage is changed to
something 2d space specific */
clonedrect= MEM_dupallocN(UVTEXTTOOL_cloneimage->ibuf->rect);
}
if (clonedrect){
int offx,offy;
offx = G.sima->zoom*ibuf->x * + UVTEXTTOOL_cloneoffx;
offy = G.sima->zoom*ibuf->y * + UVTEXTTOOL_cloneoffy;
setcloneimagealpha(255*UVTEXTTOOL_clonealpha,clonedrect);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
glaDrawPixelsSafe(x1+offx, y1+offy, UVTEXTTOOL_cloneimage->ibuf->x, UVTEXTTOOL_cloneimage->ibuf->y, clonedrect);
MEM_freeN(clonedrect); /* clean up ! */
glDisable(GL_BLEND);
}
}
}
// #endif
glPixelZoom(1.0, 1.0);
draw_tfaces();
@ -927,6 +1084,9 @@ void drawimagespace(ScrArea *sa, void *spacedata)
draw_image_transform(ibuf);
myortho2(-0.375, sa->winx-0.375, -0.375, sa->winy-0.375);
// #ifdef BM_TEXTUREPAINT
draw_image_view_tool();
// #endif
draw_image_view_icon();
draw_area_emboss(sa);

@ -81,6 +81,9 @@
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
#include "IMG_Api.h"
#include "BSE_trans_types.h"
#include "blendef.h"
#include "mydevice.h"
@ -716,6 +719,54 @@ static void do_image_imagemenu(void *arg, int event)
allqueue(REDRAWIMAGE, 0);
allqueue(REDRAWVIEW3D, 0);
break;
case 7: /* New Image */
{
// #ifdef BM_TEXTUREPAINT
static int x=256,y=256;
short depth;
char str[256];
Image *ima;
ImBuf *ibuf;
char name[256];
BrushUIdata *data = NULL;
extern short UVTEXTTOOL_INDEX;
extern BrushUIdata UVTEXTTOOL_DATA[] ;
IMG_CanvasPtr canvas;
int rowBytes;
data = &UVTEXTTOOL_DATA[UVTEXTTOOL_INDEX];
strcpy(str, "MEMORY");
/* i must get used to this may to create a modal dialog BM :) */
add_numbut(0, TEX, "Name IM:",0 , 255, str, NULL);
add_numbut(1, NUM|INT, "Width:", 1, 5000, &x, NULL);
add_numbut(2, NUM|INT, "Height:", 1, 5000, &y, NULL);
if (!do_clever_numbuts("New Image", 3, REDRAW))
return;
ima = alloc_libblock(&G.main->image, ID_IM, str);
if (ima)
{
depth= 24;
ibuf = IMB_allocImBuf(x, y, depth, IB_rect, 0);
ima->ibuf = ibuf;
strcpy(ibuf->name,"UNTITLED");
strcpy(ima->name, "UNTITLED");
G.sima->image = ima;
rowBytes = G.sima->image->ibuf->skipx ? G.sima->image->ibuf->skipx : G.sima->image->ibuf->x * 4;
canvas = IMG_CanvasCreateFromPtr(G.sima->image->ibuf->rect, G.sima->image->ibuf->x, G.sima->image->ibuf->y, rowBytes);
IMG_CanvasFill(canvas,data->r,data->g,data->b,0.0);
IMG_CanvasDispose(canvas);
ima->ok= 1;
image_changed(G.sima, 0);
}
allqueue(REDRAWIMAGE, 0);
allqueue(REDRAWVIEW3D, 0);
// #endif
break;
}
}
}
@ -727,6 +778,7 @@ static uiBlock *image_imagemenu(void *arg_unused)
block= uiNewBlock(&curarea->uiblocks, "image_imagemenu", UI_EMBOSSP, UI_HELV, curarea->headwin);
uiBlockSetButmFunc(block, do_image_imagemenu, NULL);
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "New...", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 7, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Open...", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 0, "");
if (G.sima->image) {

@ -0,0 +1,354 @@
/**
* $Id$
* imagepaint.c
*
* 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
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version. The Blender
* Foundation also sells licenses for use in proprietary software under
* the Blender License. See http://www.blender.org/BL/ for information
* about this.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): Jens Ole Wund (bjornmose)
*
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
#include <string.h>
#include <stdio.h>
#include <math.h>
#include "PIL_time.h"
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#ifdef WIN32
#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"
#include "BKE_global.h"
#include "BIF_mywindow.h"
#include "BIF_screen.h"
#include "BIF_space.h"
#include "BIF_toolbox.h"
#include "BSE_drawipo.h"
#include "BDR_vpaint.h"
#include "BDR_drawmesh.h"
#include "mydevice.h"
#include "TPT_DependKludge.h"
#include "BSE_trans_types.h"
#include "IMG_Api.h"
#include "SYS_System.h" /* for the user def menu ... should move elsewhere. */
/* 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;
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}};
void texturepaintoff()
{
UVTEXTTOOL_SHAPE = 0;
}
int uv_paint_panel_but(short val)
{
/* 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;
}
int UVtimedaction(int action)
{
if (( action== 1.0)
|| (action == 2.0)
|| (action == 3.0)
|| (action == 4.0)) return 1;
return 0;
}
void UVTexturePaintToolAt(short* where)
/* keep drawimage informed on actual tool position/setting */
{
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;
}
void UVTexturePaintMsg( void *spacedata, unsigned short event,short val)
/* handle events in texturepaint mode of UV-Image Editor*/
{
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;
}
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;
}
dtxy_prev[0] = dtxy_curr[0];
dtxy_prev[1] = dtxy_curr[1];
break;
}
}
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;
}
brush = IMG_BrushCreate((int)(data->size), (int)(data->size), data->r, data->g, data->b, data->a);
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() & L_MOUSE) {
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;
force_draw(0);
}
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);
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() & R_MOUSE) {
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;
}
}
}

@ -3775,67 +3775,21 @@ static void winqreadimagespace(ScrArea *sa, void *spacedata, BWinEvent *evt)
}
if (sima->flag & SI_DRAWTOOL) {
#ifdef NAN_TPT
/* Draw tool is active */
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;
}
brush = IMG_BrushCreate(Gvp.size, Gvp.size, Gvp.r, Gvp.g, Gvp.b, Gvp.a);
/* 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);
getmouseco_areawin(xy_prev);
while (get_mbut() & mousebut) {
getmouseco_areawin(xy_curr);
/* Check if mouse position changed */
if ((xy_prev[0] != xy_curr[0]) || (xy_prev[1] != xy_curr[1])) {
/* 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]);
IMG_CanvasDrawLineUV(canvas, brush, uv_prev[0], uv_prev[1], uv_curr[0], uv_curr[1]);
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);
}
else {
/* Redraw only this view */
force_draw(0);
}
xy_prev[0] = xy_curr[0];
xy_prev[1] = xy_curr[1];
}
}
/* 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, 1);
}
IMG_BrushDispose(brush);
IMG_CanvasDispose(canvas);
allqueue(REDRAWHEADERS, 0);
break;
case RIGHTMOUSE:
sample_vpaint();
break;
case CKEY:
add_blockhandler(curarea, IMAGE_HANDLER_PAINT, UI_PNL_UNSTOW);
scrarea_queue_winredraw(curarea);
break;
default:
UVTexturePaintMsg(spacedata,event,val);
}
#endif /* NAN_TPT */
}
else {
/* Draw tool is inactive */
// #ifdef BM_TEXTUREPAINT
texturepaintoff();
// #endif /* else BM_TEXTUREPAINT*/
switch(event) {
case LEFTMOUSE: