More compositing goodies.
authorTon Roosendaal <ton@blender.org>
Sun, 19 Feb 2006 14:55:16 +0000 (14:55 +0000)
committerTon Roosendaal <ton@blender.org>
Sun, 19 Feb 2006 14:55:16 +0000 (14:55 +0000)
- Texture Node
Allows to use any Blender Texture block as input for masks or color
blending. The texture node doesn't generate a real image, but adjusts to
the size as mapped with during an operation. So it won't work to use it
as Image input for Blur or Filter nodes.

Note; the Vector inputs for this node only work with manual input now!

- Translation Node
Give any image an offset in X or Y direction

For the Texture node to work, I needed to move the central 'pixel
processor' up one level... to allow differently sized images to merge
and allow 'procedural images' without size.

Temporal image of the day: http://www.blender.org/bf/rt.jpg

source/blender/blenkernel/BKE_node.h
source/blender/blenkernel/intern/node.c
source/blender/blenkernel/intern/node_composite.c
source/blender/blenkernel/intern/object.c
source/blender/include/butspace.h
source/blender/include/mydevice.h
source/blender/src/buttons_shading.c
source/blender/src/drawnode.c
source/blender/src/interface.c
source/blender/src/space.c

index 9bb01431a6843428b5bbd00960d7c9db05b57753..431917d09d3665d8bde40b538ae2e546028e5527 100644 (file)
@@ -33,6 +33,7 @@
 #ifndef BKE_NODE_H
 #define BKE_NODE_H
 
+struct ID;
 struct bNodeTree;
 struct bNode;
 struct bNodeLink;
@@ -134,6 +135,7 @@ struct bNode        *nodeGetActiveID(struct bNodeTree *ntree, short idtype);
 void                   nodeClearActiveID(struct bNodeTree *ntree, short idtype);
 
 void                   NodeTagChanged(struct bNodeTree *ntree, struct bNode *node);
+void                   NodeTagIDChanged(struct bNodeTree *ntree, struct ID *id);
 
 /* ************** Groups ****************** */
 
@@ -214,11 +216,12 @@ void                      set_node_shader_lamp_loop(void (*lamp_loop_func)(struct ShadeInput *, str
 #define CMP_NODE_SEPHSVA       217
 #define CMP_NODE_SETALPHA      218
 #define CMP_NODE_HUE_SAT       219
-
 #define CMP_NODE_IMAGE                 220
 #define CMP_NODE_R_RESULT              221
 #define CMP_NODE_COMPOSITE             222
 #define CMP_NODE_OUTPUT_FILE   223
+#define CMP_NODE_TEXTURE               224
+#define CMP_NODE_TRANSLATE             225
 
 
 /* filter types */
index 792e7bfeab04344b04ff52f127bb21325c391745..74812c5e4bc433865bcaa977d7dc06725b8ff610 100644 (file)
@@ -1409,6 +1409,18 @@ void NodeTagChanged(bNodeTree *ntree, bNode *node)
        }
 }
 
+void NodeTagIDChanged(bNodeTree *ntree, ID *id)
+{
+       if(ntree->type==NTREE_COMPOSIT) {
+               bNode *node;
+               
+               for(node= ntree->nodes.first; node; node= node->next)
+                       if(node->id==id)
+                               NodeTagChanged(ntree, node);
+       }
+}
+
+
 #pragma mark /* *************** preview *********** */
 
 /* if node->preview, then we assume the rect to exist */
index 6fefd3119bec2ac5df414dfa5b22c62f6c97c8da..b737265a793a77d5b38e696f4d1f2e7219e71fc5 100644 (file)
 #include "IMB_imbuf_types.h"
 
 #include "RE_pipeline.h"
+#include "RE_shader_ext.h"             /* <- TexResult */
 
 /* *************************** operations support *************************** */
 
 /* general signal that's in output sockets, and goes over the wires */
 typedef struct CompBuf {
        float *rect;
-       int x, y;
+       int x, y, xrad, yrad;
        short type, malloc;
        rcti disprect;          /* cropped part of image */
        int xof, yof;           /* relative to center of target image */
+       
+       void (*rect_procedural)(struct CompBuf *, float *, float, float);
+       bNode *node;
 } CompBuf;
 
 /* defines also used for pixel size */
@@ -87,6 +91,9 @@ static CompBuf *alloc_compbuf(int sizex, int sizey, int type, int alloc)
        
        cbuf->x= sizex;
        cbuf->y= sizey;
+       cbuf->xrad= sizex/2;
+       cbuf->yrad= sizey/2;
+       
        cbuf->type= type;
        if(alloc) {
                if(cbuf->type==CB_RGBA)
@@ -190,84 +197,45 @@ static CompBuf *scalefast_compbuf(CompBuf *inbuf, int newx, int newy)
        return outbuf;
 }
 
-
-
-/* **************************************************** */
-
-#if 0
-/* on first call, disprect should be initialized to 'out', then you can call this on all 'src' images */
-static void get_overlap_rct(CompBuf *out, CompBuf *src, rcti *disprect)
+float *compbuf_get_pixel(CompBuf *cbuf, float *rectf, int x, int y, int xrad, int yrad)
 {
-       rcti rect;
-       /* output center is considered (0,0) */
-       
-       if(src==NULL) return;
-       
-       /* translate src into output space */
-       rect= src->disprect;
-       BLI_translate_rcti(&rect, out->xof-src->xof, out->xof-src->xof);
-       /* intersect rect with current disprect */
-       
-       BLI_isect_rcti(&rect, disprect, disprect);
+       if(cbuf) {
+               if(cbuf->rect_procedural) {
+                       cbuf->rect_procedural(cbuf, rectf, (float)x/(float)xrad, (float)y/(float)yrad);
+                       return rectf;
+               }
+               else {
+                       static float col[4]= {0.0f, 0.0f, 0.0f, 0.0f};
+                       
+                       /* map coords */
+                       x-= cbuf->xof;
+                       y-= cbuf->yof;
+                       
+                       if(y<-cbuf->yrad || y>= -cbuf->yrad+cbuf->y) return col;
+                       if(x<-cbuf->xrad || x>= -cbuf->xrad+cbuf->x) return col;
+                       
+                       return cbuf->rect + cbuf->type*( (cbuf->yrad+y)*cbuf->x + (cbuf->xrad+x) );
+               }
+       }
+       else return rectf;
 }
 
-static void get_scanline_rcti(CompBuf *out, rcti *disprect, CompBuf *src, rcti *srcrect)
-{
-       int xof, yof;
-       
-       /* translate src into output space */
-       xof= out->xof-src->xof;
-       yof= out->xof-src->xof;
-       
-       srcrect->xmin= disprect->xmin + xof;
-       srcrect->ymin= disprect->ymin + yof;
-       srcrect->xmax= disprect->xmax + xof;
-       srcrect->ymax= disprect->ymax + yof;
-}
-#endif
+/* **************************************************** */
 
 /* Pixel-to-Pixel operation, 1 Image in, 1 out */
 static void composit1_pixel_processor(bNode *node, CompBuf *out, CompBuf *src_buf, float *src_col,
                                                                          void (*func)(bNode *, float *, float *))
 {
-       float *outfp, *srcfp, *out_data, *src_data;
-       int outx, outy;
-       int srcx, srcy;
-       int out_pix, out_stride, src_stride, src_pix, x, y;
-       
-       outx= out->x;
-       outy= out->y;
-       out_pix= out->type;
-       out_stride= out->x;
-       out_data= out->rect;
+       float *outfp=out->rect, *srcfp;
+       int xrad, yrad, x, y;
        
-       /* handle case when input is constant color */
-       if(src_buf==NULL) {
-               srcx= outx; srcy= outy;
-               src_stride= 0;
-               src_pix= 0;
-               src_data= src_col;
-       }
-       else {
-               srcx= src_buf->x;
-               srcy= src_buf->y;
-               src_stride= srcx;
-               src_pix= src_buf->type;
-               src_data= src_buf->rect;
-       }
+       xrad= out->xrad;
+       yrad= out->yrad;
        
-       outx= MIN2(outx, srcx);
-       outy= MIN2(outy, srcy);
-
-       for(y=0; y<outy; y++) {
-               /* set scanlines on right location */
-               srcfp= src_data + src_pix*y*src_stride;
-               outfp= out_data + out_pix*y*out_stride;
-                       
-               for(x=0; x<outx; x++) {
+       for(y= -yrad; y<-yrad+out->y; y++) {
+               for(x= -xrad; x<-xrad+out->x; x++, outfp+=out->type) {
+                       srcfp= compbuf_get_pixel(src_buf, src_col, x, y, xrad, yrad);
                        func(node, outfp, srcfp);
-                       srcfp += src_pix;
-                       outfp += out_pix;
                }
        }
 }
@@ -276,100 +244,18 @@ static void composit1_pixel_processor(bNode *node, CompBuf *out, CompBuf *src_bu
 static void composit2_pixel_processor(bNode *node, CompBuf *out, CompBuf *src_buf, float *src_col,
                                                                          CompBuf *fac_buf, float *fac, void (*func)(bNode *, float *, float *, float *))
 {
-       float *outfp, *srcfp, *src_data, *facfp, *fac_data;
-       int outx= out->x, outy= out->y;
-       int srcx, srcy, facx, facy;
-       int out_pix, src_stride, src_pix, fac_stride, fac_pix, x, y;
+       float *outfp=out->rect, *srcfp, *facfp;
+       int xrad, yrad, x, y;
        
-       out_pix= out->type;
+       xrad= out->xrad;
+       yrad= out->yrad;
        
-       /* handle case when input is constant color */
-       if(src_buf==NULL) {
-               srcx= outx; srcy= outy;
-               src_stride= 0;
-               src_pix= 0;
-               src_data= src_col;
-       }
-       else {
-               srcx= src_buf->x;
-               srcy= src_buf->y;
-               src_stride= srcx;
-               src_pix= src_buf->type;
-               src_data= src_buf->rect;
-       }
-       
-       /* factor buf or constant? */
-       if(fac_buf==NULL) {
-               facx= outx; facy= outy;
-               fac_stride= 0;
-               fac_pix= 0;
-               fac_data= fac;
-       }
-       else {
-               facx= fac_buf->x;
-               facy= fac_buf->y;
-               fac_stride= facx;
-               fac_pix= fac_buf->type;
-               fac_data= fac_buf->rect;
-       }
-       
-       if(fac_data==NULL) {
-               printf("fac buffer error, node %s\n", node->name);
-               return;
-       }
-       
-       facx= MIN2(facx, srcx);
-       facy= MIN2(facy, srcy);
-       
-#if 0  
-       if(src_buf) {
-               rcti disprect;
-               
-               disprect= out->disprect;
-               get_overlap_rct(out, src_buf, &disprect);
-               printf("%s\n", node->name);
-               printf("union %d %d %d %d\n", disprect.xmin,disprect.ymin,disprect.xmax,disprect.ymax);
-       }
-       /* new approach */
-       outfp= out->rect_float + src.ymin*outx + ;
-       for(y=src.ymin; y<src.ymax; y++) {
-               
-               /* all operators available */
-               if(y>=disp.ymin && y<disp.ymax) {
-                       srcfp= src_data + (src_stride*(y+scrc.ymin) + src.xmin);
-                       facfp= fac_data + (fac_stride*(y+fac.ymin) + fac.xmin);
+       for(y= -yrad; y<-yrad+out->y; y++) {
+               for(x= -xrad; x<-xrad+out->x; x++, outfp+=out->type) {
+                       srcfp= compbuf_get_pixel(src_buf, src_col, x, y, xrad, yrad);
+                       facfp= compbuf_get_pixel(fac_buf, fac, x, y, xrad, yrad);
                        
-                       for(x= src.xmin; x<src.xmax; x++) {
-                               if(x>=disp.xmin && x<disp.xmax) {
-                                       
-                                       srcfp+= src_pix;
-                                       facfp+= fac_pix;
-                               }
-                               else {
-                                       /* copy src1 */
-                               }
-                       }
-               }
-               else {
-                       /* copy src1 */
-                       srcfp= src_data + (src_stride*(y+scrc.ymin) + src.xmin);
-                       
-                       QUATCOPY(outfp, srcfp);
-               }
-       }       
-#endif
-       
-       outfp= out->rect;
-       for(y=0; y<outy; y++) {
-               /* set source scanline on right location */
-               srcfp= src_data + src_pix*y*src_stride;
-               facfp= fac_data + fac_pix*y*fac_stride;
-               
-               for(x=0; x<outx; x++, outfp+=out_pix) {
-                       if(x<facx && y<facy)
-                               func(node, outfp, srcfp, facfp);
-                       srcfp += src_pix;
-                       facfp += fac_pix;
+                       func(node, outfp, srcfp, facfp);
                }
        }
 }
@@ -378,72 +264,19 @@ static void composit2_pixel_processor(bNode *node, CompBuf *out, CompBuf *src_bu
 static void composit3_pixel_processor(bNode *node, CompBuf *out, CompBuf *src1_buf, float *src1_col, CompBuf *src2_buf, float *src2_col, 
                                                                          CompBuf *fac_buf, float fac, void (*func)(bNode *, float *, float *, float *, float))
 {
-       float *outfp, *src1fp, *src2fp, *facfp, *src1_data, *src2_data, *fac_data;
-       int outx= out->x, outy= out->y;
-       int src1x, src1y, src2x, src2y, facx, facy;
-       int src1_stride, src1_pix, src2_stride, src2_pix, fac_stride, fac_pix, x, y;
-
-       /* handle case when input has constant color */
-       if(src1_buf==NULL) {
-               src1x= outx; src1y= outy;
-               src1_stride= 0;
-               src1_pix= 0;
-               src1_data= src1_col;
-       }
-       else {
-               src1x= src1_buf->x;
-               src1y= src1_buf->y;
-               src1_stride= src1x;
-               src1_pix= src1_buf->type;
-               src1_data= src1_buf->rect;
-       }
-       
-       if(src2_buf==NULL) {
-               src2x= outx; src2y= outy;
-               src2_stride= 0;
-               src2_pix= 0;
-               src2_data= src2_col;
-       }
-       else {
-               src2x= src2_buf->x;
-               src2y= src2_buf->y;
-               src2_stride= src2x;
-               src2_pix= src2_buf->type;
-               src2_data= src2_buf->rect;
-       }
-       
-       /* factor buf or constant? */
-       if(fac_buf==NULL) {
-               facx= outx; facy= outy;
-               fac_stride= 0;
-               fac_pix= 0;
-               fac_data= &fac;
-       }
-       else {
-               facx= fac_buf->x;
-               facy= fac_buf->y;
-               fac_stride= facx;
-               fac_pix= 1;
-               fac_data= fac_buf->rect;
-       }
+       float *outfp=out->rect, *src1fp, *src2fp, *facfp;
+       int xrad, yrad, x, y;
        
-       facx= MIN3(facx, src1x, src2x);
-       facy= MIN3(facy, src1y, src2y);
+       xrad= out->xrad;
+       yrad= out->yrad;
        
-       outfp= out->rect;
-       for(y=0; y<outy; y++) {
-               
-               /* set source scanlines on right location */
-               src1fp= src1_data + src1_pix*y*src1_stride;
-               src2fp= src2_data + src2_pix*y*src2_stride;
-               facfp= fac_data + y*fac_stride;
-               
-               for(x=0; x<outx; x++, outfp+=4) {
-                       if(x<facx && y<facy)
-                               func(node, outfp, src1fp, src2fp, *facfp);
-                       src1fp+= src1_pix;
-                       src2fp+= src2_pix;
-                       facfp+= fac_pix;
+       for(y= -yrad; y<-yrad+out->y; y++) {
+               for(x= -xrad; x<-xrad+out->x; x++, outfp+=out->type) {
+                       src1fp= compbuf_get_pixel(src1_buf, src1_col, x, y, xrad, yrad);
+                       src2fp= compbuf_get_pixel(src2_buf, src2_col, x, y, xrad, yrad);
+                       facfp= compbuf_get_pixel(fac_buf, &fac, x, y, xrad, yrad);
+                       
+                       func(node, outfp, src1fp, src2fp, *facfp);
                }
        }
 }
@@ -474,6 +307,8 @@ static void generate_preview(bNode *node, CompBuf *stackbuf)
        if(preview && stackbuf) {
                CompBuf *cbuf;
                
+               if(stackbuf->rect==NULL) return;
+               
                if(stackbuf->x > stackbuf->y) {
                        preview->xsize= 140;
                        preview->ysize= (140*stackbuf->y)/stackbuf->x;
@@ -1044,6 +879,107 @@ static bNodeType cmp_node_rresult= {
        
 };
 
+/* **************** TEXTURE ******************** */
+static bNodeSocketType cmp_node_texture_in[]= {
+       {       SOCK_VECTOR, 0, "Offset",               0.0f, 0.0f, 0.0f, 0.0f, -2.0f, 2.0f},
+       {       SOCK_VECTOR, 0, "Scale",                1.0f, 1.0f, 1.0f, 1.0f, -10.0f, 10.0f},
+       {       -1, 0, ""       }
+};
+static bNodeSocketType cmp_node_texture_out[]= {
+       {       SOCK_VALUE, 0, "Value",         1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
+       {       SOCK_RGBA , 0, "Color",         1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f},
+       {       -1, 0, ""       }
+};
+
+/* called without rect allocated */
+static void texture_procedural(CompBuf *cbuf, float *col, float xco, float yco)
+{
+       bNode *node= cbuf->node;
+       bNodeSocket *sock= node->inputs.first;
+       TexResult texres;
+       float vec[3], *size, nor[3]={0.0f, 0.0f, 0.0f};
+       int retval, type= cbuf->type;
+       
+       texres.nor= NULL;
+       size= sock->next->ns.vec;
+       
+       vec[0]= size[0]*(xco + sock->ns.vec[0]);
+       vec[1]= size[1]*(yco + sock->ns.vec[1]);
+       vec[2]= size[2]*sock->ns.vec[2];
+       
+       retval= multitex((Tex *)node->id, vec, NULL, NULL, 0, &texres);
+       
+       if(type==1) {
+               if(texres.talpha)
+                       col[0]= texres.ta;
+               else
+                       col[0]= texres.tin;
+       }
+       else if(type==4) {
+               if(texres.talpha)
+                       col[3]= texres.ta;
+               else
+                       col[3]= texres.tin;
+               
+               if((retval & TEX_RGB)) {
+                       col[0]= texres.tr;
+                       col[1]= texres.tg;
+                       col[2]= texres.tb;
+               }
+               else col[0]= col[1]= col[2]= col[3];
+       }
+       else { 
+               VECCOPY(col, nor);
+       }
+}
+
+/* texture node outputs get a small rect, to make sure all other nodes accept it */
+/* only the pixel-processor nodes do something with it though */
+static void node_composit_exec_texture(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
+{
+       /* outputs: value, color, normal */
+       
+       if(node->id) {
+               /* first make the preview image */
+               CompBuf *prevbuf= alloc_compbuf(140, 140, CB_RGBA, 1); // alloc
+               
+               prevbuf->rect_procedural= texture_procedural;
+               prevbuf->node= node;
+               composit1_pixel_processor(node, prevbuf, prevbuf, out[0]->vec, do_copy_rgba);
+               generate_preview(node, prevbuf);
+               free_compbuf(prevbuf);
+               
+               if(out[0]->hasoutput) {
+                       CompBuf *stackbuf= alloc_compbuf(140, 140, CB_VAL, 1); // alloc
+                       
+                       stackbuf->rect_procedural= texture_procedural;
+                       stackbuf->node= node;
+                       
+                       out[0]->data= stackbuf;
+               }
+               if(out[1]->hasoutput) {
+                       CompBuf *stackbuf= alloc_compbuf(140, 140, CB_RGBA, 1); // alloc
+                       
+                       stackbuf->rect_procedural= texture_procedural;
+                       stackbuf->node= node;
+                       
+                       out[1]->data= stackbuf;
+               }
+       }
+}
+
+static bNodeType cmp_node_texture= {
+       /* type code   */       CMP_NODE_TEXTURE,
+       /* name        */       "Texture",
+       /* width+range */       120, 80, 240,
+       /* class+opts  */       NODE_CLASS_INPUT, NODE_OPTIONS|NODE_PREVIEW,
+       /* input sock  */       cmp_node_texture_in,
+       /* output sock */       cmp_node_texture_out,
+       /* storage     */       "",
+       /* execfunc    */       node_composit_exec_texture
+       
+};
+
 /* **************** NORMAL  ******************** */
 static bNodeSocketType cmp_node_normal_in[]= {
        {       SOCK_VECTOR, 1, "Normal",       0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f},
@@ -1083,7 +1019,7 @@ static void node_composit_exec_normal(void *data, bNode *node, bNodeStack **in,
                CompBuf *cbuf= in[0]->data;
                CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_VAL, 1); // allocs
                
-               composit1_pixel_processor(node, stackbuf, in[0]->data, NULL, do_normal);
+               composit1_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, do_normal);
                
                out[1]->data= stackbuf;
        }
@@ -1220,7 +1156,7 @@ static void node_composit_exec_curve_rgb(void *data, bNode *node, bNodeStack **i
                if(in[0]->data)
                        composit2_pixel_processor(node, stackbuf, in[1]->data, in[1]->vec, in[0]->data, in[0]->vec, do_curves_fac);
                else
-                       composit1_pixel_processor(node, stackbuf, in[1]->data, NULL, do_curves);
+                       composit1_pixel_processor(node, stackbuf, in[1]->data, in[1]->vec, do_curves);
                
                out[0]->data= stackbuf;
        }
@@ -1328,6 +1264,7 @@ static void node_composit_exec_hue_sat(void *data, bNode *node, bNodeStack **in,
 {
        /* stack order in: Fac, Image */
        /* stack order out: Image */
+       if(out[0]->hasoutput==0) return;
        
        /* input no image? then only color operation */
        if(in[1]->data==NULL) {
@@ -1386,6 +1323,8 @@ static void node_composit_exec_mix_rgb(void *data, bNode *node, bNodeStack **in,
        /* stack order out: Image */
        float fac= in[0]->vec[0];
        
+       if(out[0]->hasoutput==0) return;
+       
        CLAMP(fac, 0.0f, 1.0f);
        
        /* input no image? then only color operation */
@@ -1487,10 +1426,10 @@ static void do_filter3(CompBuf *out, CompBuf *in, float *filter, float fac)
        }
 }
 
-static float soft[9]= {1/16.0f, 2/16.0f, 1/16.0f, 2/16.0f, 4/16.0f, 2/16.0f, 1/16.0f, 2/16.0f, 1/16.0f};
 
 static void node_composit_exec_filter(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
 {
+       static float soft[9]= {1/16.0f, 2/16.0f, 1/16.0f, 2/16.0f, 4/16.0f, 2/16.0f, 1/16.0f, 2/16.0f, 1/16.0f};
        float sharp[9]= {-1,-1,-1,-1,9,-1,-1,-1,-1};
        float laplace[9]= {1/8.0f, -1/8.0f, 1/8.0f, -1/8.0f, 1.0f, -1/8.0f, 1/8.0f, -1/8.0f, 1/8.0f};
        float sobel[9]= {1,2,1,0,0,0,-1,-2,-1};
@@ -1498,6 +1437,8 @@ static void node_composit_exec_filter(void *data, bNode *node, bNodeStack **in,
        float kirsch[9]= {5,5,5,-3,-3,-3,-2,-2,-2};
        float shadow[9]= {1,2,1,0,1,0,-1,-2,-1};
        
+       if(out[0]->hasoutput==0) return;
+       
        /* stack order in: Image */
        /* stack order out: Image */
        
@@ -1569,6 +1510,9 @@ static void node_composit_exec_valtorgb(void *data, bNode *node, bNodeStack **in
        /* stack order in: fac */
        /* stack order out: col, alpha */
        
+       if(out[0]->hasoutput==0 || out[1]->hasoutput==0) 
+               return;
+       
        if(node->storage) {
                /* input no image? then only color operation */
                if(in[0]->data==NULL) {
@@ -1579,7 +1523,7 @@ static void node_composit_exec_valtorgb(void *data, bNode *node, bNodeStack **in
                        CompBuf *cbuf= in[0]->data;
                        CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); // allocs
                        
-                       composit1_pixel_processor(node, stackbuf, in[0]->data, NULL, do_colorband_composit);
+                       composit1_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, do_colorband_composit);
                        
                        out[0]->data= stackbuf;
                        
@@ -1623,6 +1567,9 @@ static void node_composit_exec_rgbtobw(void *data, bNode *node, bNodeStack **in,
        /* stack order out: bw */
        /* stack order in: col */
        
+       if(out[0]->hasoutput==0)
+               return;
+       
        /* input no image? then only color operation */
        if(in[0]->data==NULL) {
                do_rgbtobw(node, out[0]->vec, in[0]->vec);
@@ -1632,7 +1579,7 @@ static void node_composit_exec_rgbtobw(void *data, bNode *node, bNodeStack **in,
                CompBuf *cbuf= in[0]->data;
                CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_VAL, 1); // allocs
                
-               composit1_pixel_processor(node, stackbuf, in[0]->data, NULL, do_rgbtobw);
+               composit1_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, do_rgbtobw);
                
                out[0]->data= stackbuf;
        }
@@ -1751,7 +1698,7 @@ static void node_composit_exec_sephsva(void *data, bNode *node, bNodeStack **in,
                CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); // allocs
 
                /* convert the RGB stackbuf to an HSV representation */
-               composit1_pixel_processor(node, stackbuf, in[0]->data, NULL, do_sephsva);
+               composit1_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, do_sephsva);
 
                /* separate each of those channels */
                if(out[0]->hasoutput)
@@ -1854,20 +1801,11 @@ static void do_alphaover_premul(bNode *node, float *out, float *src, float *over
        }
        else {
                float mul= 1.0f - over[3];
-               
-               /* handle case where backdrop has no alpha, but still color */
-               if(src[0]==0.0f) {
-                       out[0]= over[0];
-                       out[1]= (mul*src[1]) + over[1];
-                       out[2]= (mul*src[2]) + over[2];
-                       out[3]= (mul*src[3]) + over[3];
-               }
-               else {
-                       out[0]= (mul*src[0]) + over[0];
-                       out[1]= (mul*src[1]) + over[1];
-                       out[2]= (mul*src[2]) + over[2];
-                       out[3]= (mul*src[3]) + over[3];
-               }
+
+               out[0]= (mul*src[0]) + over[0];
+               out[1]= (mul*src[1]) + over[1];
+               out[2]= (mul*src[2]) + over[2];
+               out[3]= (mul*src[3]) + over[3];
        }       
 }
 
@@ -1884,20 +1822,11 @@ static void do_alphaover_key(bNode *node, float *out, float *src, float *over)
        else {
                float premul= over[3];
                float mul= 1.0f - premul;
-               
-               /* handle case where backdrop has no alpha, but still color */
-               if(src[0]==0.0f) {
-                       out[0]= over[0];
-                       out[1]= (mul*src[1]) + premul*over[1];
-                       out[2]= (mul*src[2]) + premul*over[2];
-                       out[3]= (mul*src[3]) + premul*over[3];
-               }
-               else {
-                       out[0]= (mul*src[0]) + premul*over[0];
-                       out[1]= (mul*src[1]) + premul*over[1];
-                       out[2]= (mul*src[2]) + premul*over[2];
-                       out[3]= (mul*src[3]) + premul*over[3];
-               }
+
+               out[0]= (mul*src[0]) + premul*over[0];
+               out[1]= (mul*src[1]) + premul*over[1];
+               out[2]= (mul*src[2]) + premul*over[2];
+               out[3]= (mul*src[3]) + premul*over[3];
        }       
 }
 
@@ -1906,6 +1835,8 @@ static void node_composit_exec_alphaover(void *data, bNode *node, bNodeStack **i
 {
        /* stack order in: col col */
        /* stack order out: col */
+       if(out[0]->hasoutput==0) 
+               return;
        
        /* input no image? then only color operation */
        if(in[0]->data==NULL) {
@@ -1965,6 +1896,7 @@ static void node_composit_exec_map_value(void *data, bNode *node, bNodeStack **i
 {
        /* stack order in: col col */
        /* stack order out: col */
+       if(out[0]->hasoutput==0) return;
        
        /* input no image? then only value operation */
        if(in[0]->data==NULL) {
@@ -2635,6 +2567,44 @@ static bNodeType cmp_node_vecblur= {
        
 };
 
+/* **************** Translate  ******************** */
+
+static bNodeSocketType cmp_node_translate_in[]= {
+       {       SOCK_RGBA, 1, "Image",                  0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
+       {       SOCK_VALUE, 0, "X",     0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f},
+       {       SOCK_VALUE, 0, "Y",     0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f},
+       {       -1, 0, ""       }
+};
+static bNodeSocketType cmp_node_translate_out[]= {
+       {       SOCK_RGBA, 0, "Image",                  0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
+       {       -1, 0, ""       }
+};
+
+static void node_composit_exec_translate(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
+{
+       if(in[0]->data) {
+               CompBuf *cbuf= in[0]->data;
+               CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, cbuf->type, 0); // no alloc
+       
+               stackbuf->xof= (int)floor(in[1]->vec[0]);
+               stackbuf->yof= (int)floor(in[2]->vec[0]);
+               
+               stackbuf->rect= cbuf->rect;
+               out[0]->data= stackbuf;
+       }
+}
+
+static bNodeType cmp_node_translate= {
+       /* type code   */       CMP_NODE_TRANSLATE,
+       /* name        */       "Translate",
+       /* width+range */       140, 100, 320,
+       /* class+opts  */       NODE_CLASS_CONVERTOR, NODE_OPTIONS,
+       /* input sock  */       cmp_node_translate_in,
+       /* output sock */       cmp_node_translate_out,
+       /* storage     */       "",
+       /* execfunc    */       node_composit_exec_translate
+};
+
 
 /* ****************** types array for all shaders ****************** */
 
@@ -2663,6 +2633,8 @@ bNodeType *node_all_composit[]= {
        &cmp_node_seprgba,
        &cmp_node_sephsva,
        &cmp_node_setalpha,
+       &cmp_node_texture,
+       &cmp_node_translate,
        NULL
 };
 
index 073cea53d32648aed93e7b204fc25fbc5ee14472..bcc87ad9bed592397fd08137f3a62c94d4310139 100644 (file)
@@ -579,6 +579,7 @@ void *add_lamp(void)
        la->soft= 3.0;
        la->ray_samp= la->ray_sampy= la->ray_sampz= 1; 
        la->area_size=la->area_sizey=la->area_sizez= 1.0; 
+       la->buffers= 1;
        
        return la;
 }
index 4218707523c6aeedc69f7da07edc3015af1daf09..999213083ca62041feed5d7d1bb032bad4b09b1d 100644 (file)
@@ -176,7 +176,6 @@ void curvemap_buttons(struct uiBlock *block, struct CurveMapping *cumap, char la
 #define B_MATPRV               1206
 #define B_LAMPPRV              1207
 #define B_WORLDPRV             1208
-#define B_TEXPRV               1209
 #define B_MTEXCOL              1210
 #define B_TEXCLEAR             1211
 #define B_MTEXPASTE            1212
@@ -215,6 +214,7 @@ void curvemap_buttons(struct uiBlock *block, struct CurveMapping *cumap, char la
 #define B_REDRAWCBAND  1318
 #define B_BANDCOL              1319
 #define B_LOADTEXIMA1  1320
+#define B_TEXPRV               1321
 
 #define B_PLUGBUT              1325
 /* B_PLUGBUT reserves 24 buttons at least! */
index 8db7d7ce194769aae2afbe4469cd2b1433c0f602..113b281a017f0f61709e03e87a66e59a198511ad 100644 (file)
 #define SCREEN_HANDLER         0x4036
 #define REDRAWANIM                     0x4037
 #define REDRAWNODE                     0x4038
+#define RECALC_COMPOSITE       0x4039
 
 #endif /* !__MYDEVICE_H__ */
 
index f38d31b09a7ddf2b3712d272f790fb4decc9d815..d27f07fcd9b144c7922ead58db58b25e8e24af0c 100644 (file)
@@ -277,6 +277,15 @@ void do_texbuts(unsigned short event)
        tex= G.buts->lockpoin;
        
        switch(event) {
+       case B_TEXPRV:
+               BIF_preview_changed(ID_TE);
+               allqueue(REDRAWBUTSSHADING, 0);
+               
+               if(tex && G.scene->nodetree) {
+                       NodeTagIDChanged(G.scene->nodetree, &tex->id);
+                       allqueue(RECALC_COMPOSITE, 0);
+               }
+               break;
        case B_TEXCHANNEL:
                scrarea_queue_headredraw(curarea);
                BIF_preview_changed(ID_TE);
@@ -287,6 +296,11 @@ void do_texbuts(unsigned short event)
                tex->stype= 0;
                allqueue(REDRAWBUTSSHADING, 0);
                BIF_preview_changed(ID_TE);
+               
+               if(tex && G.scene->nodetree) {
+                       NodeTagIDChanged(G.scene->nodetree, &tex->id);
+                       allqueue(RECALC_COMPOSITE, 0);
+               }
                break;
        case B_DEFTEXVAR:
                if(tex==0) return;
@@ -2450,10 +2464,6 @@ void do_matbuts(unsigned short event)
                allqueue(REDRAWBUTSSHADING, 0);
                shade_buttons_change_3d();
                break;
-       case B_TEXPRV:
-               BIF_preview_changed(ID_TE);
-               allqueue(REDRAWBUTSSHADING, 0);
-               break;
        case B_LAMPPRV:
                BIF_preview_changed(ID_LA);
                allqueue(REDRAWBUTSSHADING, 0);
index 9c7dd8657cdef94b283a031e74505b5d80a00ff8..aeb046f89979b66fd8ddc07e2d022fcc24eb9843 100644 (file)
@@ -111,22 +111,44 @@ static void snode_drawstring(SpaceNode *snode, char *str, int okwidth)
 
 /* **************  Socket callbacks *********** */
 
+static void socket_vector_menu_cb(void *node_v, void *ntree_v)
+{
+       NodeTagChanged(ntree_v, node_v); 
+       addqueue(curarea->win, UI_BUT_EVENT, B_NODE_EXEC+((bNode *)node_v)->nr);
+}
+
 /* NOTE: this is a block-menu, needs 0 events, otherwise the menu closes */
-/* also: butpoin is to the first element of socket nodestack struct */
-static uiBlock *socket_vector_menu(void *butpoin_v)
+static uiBlock *socket_vector_menu(void *socket_v)
 {
-       bNodeStack *ns= butpoin_v;
+       SpaceNode *snode= curarea->spacedata.first;
+       bNode *node;
+       bNodeSocket *sock= socket_v;
+       bNodeStack *ns= &sock->ns;
        uiBlock *block;
+       uiBut *bt;
        
-       block= uiNewBlock(&curarea->uiblocks, "socket menu", UI_EMBOSS, UI_HELV, curarea->win);
+       /* a bit ugly... retrieve the node the socket comes from */
+       for(node= snode->nodetree->nodes.first; node; node= node->next) {
+               bNodeSocket *sockt;
+               for(sockt= node->inputs.first; sockt; sockt= sockt->next)
+                       if(sockt==sock)
+                               break;
+               if(sockt)
+                       break;
+       }
        
+       block= uiNewBlock(&curarea->uiblocks, "socket menu", UI_EMBOSS, UI_HELV, curarea->win);
+
        /* use this for a fake extra empy space around the buttons */
        uiDefBut(block, LABEL, 0, "",                   -4, -4, 188, 68, NULL, 0, 0, 0, 0, "");
        
        uiBlockBeginAlign(block);
-       uiDefButF(block, NUMSLI, 0, "X ",        0,40,180,20, ns->vec, ns->min, ns->max, 10, 0, "");
-       uiDefButF(block, NUMSLI, 0, "Y ",        0,20,180,20, ns->vec+1, ns->min, ns->max, 10, 0, "");
-       uiDefButF(block, NUMSLI, 0, "Z ",        0,0,180,20, ns->vec+2, ns->min, ns->max, 10, 0, "");
+       bt= uiDefButF(block, NUMSLI, 0, "X ",    0,40,180,20, ns->vec, ns->min, ns->max, 10, 0, "");
+       uiButSetFunc(bt, socket_vector_menu_cb, node, snode->nodetree);
+       bt= uiDefButF(block, NUMSLI, 0, "Y ",    0,20,180,20, ns->vec+1, ns->min, ns->max, 10, 0, "");
+       uiButSetFunc(bt, socket_vector_menu_cb, node, snode->nodetree);
+       bt= uiDefButF(block, NUMSLI, 0, "Z ",    0,0,180,20, ns->vec+2, ns->min, ns->max, 10, 0, "");
+       uiButSetFunc(bt, socket_vector_menu_cb, node, snode->nodetree);
        
        uiBlockSetDirection(block, UI_TOP);
        
@@ -295,6 +317,59 @@ static int node_buts_normal(uiBlock *block, bNodeTree *ntree, bNode *node, rctf
        return (int)(node->width-NODE_DY);
 }
 
+static void node_browse_tex_cb(void *ntree_v, void *node_v)
+{
+       bNodeTree *ntree= ntree_v;
+       bNode *node= node_v;
+       Tex *tex;
+       
+       if(node->menunr<1) return;
+       
+       if(node->id) {
+               node->id->us--;
+               node->id= NULL;
+       }
+       tex= BLI_findlink(&G.main->tex, node->menunr-1);
+
+       node->id= &tex->id;
+       id_us_plus(node->id);
+       BLI_strncpy(node->name, node->id->name+2, 21);
+       
+       nodeSetActive(ntree, node);
+       
+       allqueue(REDRAWBUTSSHADING, 0);
+       allqueue(REDRAWNODE, 0);
+       NodeTagChanged(ntree, node); 
+       
+       node->menunr= 0;
+}
+
+static int node_buts_texture(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
+{
+       if(block) {
+               uiBut *bt;
+               char *strp;
+               
+               /* browse button texture */
+               uiBlockBeginAlign(block);
+               IDnames_to_pupstring(&strp, NULL, "", &(G.main->tex), NULL, NULL);
+               node->menunr= 0;
+               bt= uiDefButS(block, MENU, B_NODE_EXEC+node->nr, strp, 
+                                         butr->xmin, butr->ymin, 20, 19, 
+                                         &node->menunr, 0, 0, 0, 0, "Browse texture");
+               uiButSetFunc(bt, node_browse_tex_cb, ntree, node);
+               if(strp) MEM_freeN(strp);
+               
+               if(node->id) {
+                       bt= uiDefBut(block, TEX, B_NOP, "TE:",
+                                                butr->xmin+19, butr->ymin, butr->xmax-butr->xmin-19, 19, 
+                                                node->id->name+2, 0.0, 19.0, 0, 0, "Texture name");
+                       uiButSetFunc(bt, node_ID_title_cb, node, NULL);
+               }
+               
+       }       
+       return 19;
+}
 
 
 /* ****************** BUTTON CALLBACKS FOR SHADER NODES ***************** */
@@ -443,21 +518,6 @@ static int node_shader_buts_material(uiBlock *block, bNodeTree *ntree, bNode *no
        return 38;
 }
 
-static int node_shader_buts_texture(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
-{
-       if(block) {
-               uiBut *bt;
-               
-               bt= uiDefIDPoinBut(block, test_texpoin_but, ID_TE, B_NODE_EXEC+node->nr, "",
-                                                  butr->xmin, butr->ymin, butr->xmax-butr->xmin, 19, 
-                                                  &node->id,  ""); 
-               uiButSetFunc(bt, node_ID_title_cb, node, NULL);
-               
-       }       
-       return 19;
-}
-
-
 static int node_shader_buts_mapping(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
 {
        if(block) {
@@ -519,7 +579,7 @@ static void node_shader_set_butfunc(bNodeType *ntype)
                        ntype->butfunc= node_shader_buts_material;
                        break;
                case SH_NODE_TEXTURE:
-                       ntype->butfunc= node_shader_buts_texture;
+                       ntype->butfunc= node_buts_texture;
                        break;
                case SH_NODE_NORMAL:
                        ntype->butfunc= node_buts_normal;
@@ -970,6 +1030,9 @@ static void node_composit_set_butfunc(bNodeType *ntype)
                case CMP_NODE_HUE_SAT:
                        ntype->butfunc= node_composit_buts_hue_sat;
                        break;
+               case CMP_NODE_TEXTURE:
+                       ntype->butfunc= node_buts_texture;
+                       break;
                default:
                        ntype->butfunc= NULL;
        }
@@ -1504,7 +1567,7 @@ static void node_draw_basis(ScrArea *sa, SpaceNode *snode, bNode *node)
                                        uiButSetFunc(bt, node_sync_cb, snode, node);
                                }
                                else if(sock->type==SOCK_VECTOR) {
-                                       uiDefBlockBut(node->block, socket_vector_menu, butpoin, sock->name, 
+                                       uiDefBlockBut(node->block, socket_vector_menu, sock, sock->name, 
                                                  (short)sock->locx+NODE_DYS, (short)sock->locy-9, (short)node->width-NODE_DY, 17, 
                                                  "");
                                }
index 89b5f1ae50b0d53ecf10099bedf81d55bed86b2e..26116126c76b29f681c2cb754c37f2b4ba81282f 100644 (file)
@@ -2336,7 +2336,6 @@ static int ui_do_but_SLI(uiBut *but)
        float f, fstart, tempf = 0.0, deler, value;
        int sx, h, temp, pos=0, lvalue, redraw;
        short mval[2], qual;
-       float curmatrix[4][4];
 
        value= ui_get_but_val(but);
        uiGetMouse(mywinget(), mval);
@@ -2420,9 +2419,13 @@ static int ui_do_but_SLI(uiBut *but)
                           because button callback function MIGHT change it
                           - which has until now occured through the Python API
                        */
-                       Mat4CpyMat4(curmatrix, UIwinmat);
+                       /* This is really not possible atm... nothing in Blender
+                          supports such functionality even now. Calling function 
+                          callbacks while using a button screws up the UI (ton) 
+                       */
+                       /* Mat4CpyMat4(curmatrix, UIwinmat);
                        uibut_do_func(but);
-                       Mat4CpyMat4(UIwinmat, curmatrix);
+                       Mat4CpyMat4(UIwinmat, curmatrix); */
                } 
                else BIF_wait_for_statechange();
        }
@@ -2451,11 +2454,12 @@ static int ui_do_but_SLI(uiBut *but)
                                ui_set_but_val(but, tempf);
 
                }
-               uibut_do_func(but);
        }
+
        ui_check_but(but);
        ui_draw_but(but);
        ui_block_flush_back(but->block);
+       uibut_do_func(but);
        
        return but->retval;
 }
index e0b163f4b65ebedd9382d34f023a25eeed5589df..715c8a6027150928023bc607be2e8e78a705460f 100644 (file)
 
 #include "BPY_extern.h"
 
+#include "butspace.h"
 #include "mydevice.h"
 #include "blendef.h"
 #include "datatoc.h"
@@ -5075,6 +5076,11 @@ void allqueue(unsigned short event, short val)
                                        scrarea_queue_winredraw(sa);
                                }
                                break;
+                       case RECALC_COMPOSITE:
+                               if(sa->spacetype==SPACE_NODE) {
+                                       addqueue(sa->win, UI_BUT_EVENT, B_NODE_TREE_EXEC);
+                               }
+                               break;
                        case REDRAWANIM:
                                if ELEM6(sa->spacetype, SPACE_IPO, SPACE_SOUND, SPACE_TIME, SPACE_NLA, SPACE_ACTION, SPACE_SEQ) {
                                        scrarea_queue_winredraw(sa);