forked from bartvdbraak/blender
having a "mini gimp" in image editor
{ hope it does not break builds .. mscv6 .. scons works fine here }
This commit is contained in:
parent
9d2f0fe302
commit
42ee04702c
@ -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) {
|
||||
|
354
source/blender/src/imagepaint.c
Normal file
354
source/blender/src/imagepaint.c
Normal file
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user