Fix for bug #8073: texture nodes connected to a viewer could crash.
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Mon, 7 Apr 2008 15:21:25 +0000 (15:21 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Mon, 7 Apr 2008 15:21:25 +0000 (15:21 +0000)
Also fixed a bug where procedural buffers did not convert correctly
to different buffer types (e.g. value -> rgba would give red).

source/blender/nodes/intern/CMP_nodes/CMP_texture.c
source/blender/nodes/intern/CMP_util.c
source/blender/nodes/intern/CMP_util.h

index c0845a582d3898205f32fa234352df3f0d73158f..c1f1948dba183afd92f8881366b070ca72406787 100644 (file)
@@ -42,12 +42,12 @@ static bNodeSocketType cmp_node_texture_out[]= {
 };
 
 /* called without rect allocated */
 };
 
 /* called without rect allocated */
-static void texture_procedural(CompBuf *cbuf, float *col, float xco, float yco)
+static void texture_procedural(CompBuf *cbuf, float *out, float xco, float yco)
 {
        bNode *node= cbuf->node;
        TexResult texres= {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL};
 {
        bNode *node= cbuf->node;
        TexResult texres= {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL};
-       float vec[3], *size, nor[3]={0.0f, 0.0f, 0.0f};
-       int retval, type= cbuf->type;
+       float vec[3], *size, nor[3]={0.0f, 0.0f, 0.0f}, col[4];
+       int retval, type= cbuf->procedural_type;
        
        size= cbuf->procedural_size;
        
        
        size= cbuf->procedural_size;
        
@@ -79,6 +79,8 @@ static void texture_procedural(CompBuf *cbuf, float *col, float xco, float yco)
        else { 
                VECCOPY(col, nor);
        }
        else { 
                VECCOPY(col, nor);
        }
+
+       typecheck_compbuf_color(out, col, cbuf->type, cbuf->procedural_type);
 }
 
 /* texture node outputs get a small rect, to make sure all other nodes accept it */
 }
 
 /* texture node outputs get a small rect, to make sure all other nodes accept it */
@@ -107,6 +109,7 @@ static void node_composit_exec_texture(void *data, bNode *node, bNodeStack **in,
                prevbuf->node= node;
                VECCOPY(prevbuf->procedural_offset, in[0]->vec);
                VECCOPY(prevbuf->procedural_size, in[1]->vec);
                prevbuf->node= node;
                VECCOPY(prevbuf->procedural_offset, in[0]->vec);
                VECCOPY(prevbuf->procedural_size, in[1]->vec);
+               prevbuf->procedural_type= CB_RGBA;
                composit1_pixel_processor(node, prevbuf, prevbuf, out[0]->vec, do_copy_rgba, CB_RGBA);
                generate_preview(node, prevbuf);
                free_compbuf(prevbuf);
                composit1_pixel_processor(node, prevbuf, prevbuf, out[0]->vec, do_copy_rgba, CB_RGBA);
                generate_preview(node, prevbuf);
                free_compbuf(prevbuf);
@@ -118,6 +121,7 @@ static void node_composit_exec_texture(void *data, bNode *node, bNodeStack **in,
                        stackbuf->node= node;
                        VECCOPY(stackbuf->procedural_offset, in[0]->vec);
                        VECCOPY(stackbuf->procedural_size, in[1]->vec);
                        stackbuf->node= node;
                        VECCOPY(stackbuf->procedural_offset, in[0]->vec);
                        VECCOPY(stackbuf->procedural_size, in[1]->vec);
+                       stackbuf->procedural_type= CB_VAL;
                        
                        out[0]->data= stackbuf; 
                }
                        
                        out[0]->data= stackbuf; 
                }
@@ -128,6 +132,7 @@ static void node_composit_exec_texture(void *data, bNode *node, bNodeStack **in,
                        stackbuf->node= node;
                        VECCOPY(stackbuf->procedural_offset, in[0]->vec);
                        VECCOPY(stackbuf->procedural_size, in[1]->vec);
                        stackbuf->node= node;
                        VECCOPY(stackbuf->procedural_offset, in[0]->vec);
                        VECCOPY(stackbuf->procedural_size, in[1]->vec);
+                       stackbuf->procedural_type= CB_RGBA;
                        
                        out[1]->data= stackbuf;
                }
                        
                        out[1]->data= stackbuf;
                }
index a2629aa396ec43c1d995bc6389de23e598e65936..f9805645115002e6c32b457c82ac165c020c16c6 100644 (file)
@@ -225,17 +225,100 @@ CompBuf *scalefast_compbuf(CompBuf *inbuf, int newx, int newy)
        return outbuf;
 }
 
        return outbuf;
 }
 
+void typecheck_compbuf_color(float *out, float *in, int outtype, int intype)
+{
+       if(intype == outtype) {
+               memcpy(out, in, sizeof(float)*outtype);
+       }
+       else if(outtype==CB_VAL) {
+               if(intype==CB_VEC2) {
+                       *out= 0.5f*(in[0]+in[1]);
+               }
+               else if(intype==CB_VEC3) {
+                       *out= 0.333333f*(in[0]+in[1]+in[2]);
+               }
+               else if(intype==CB_RGBA) {
+                       *out= in[0]*0.35f + in[1]*0.45f + in[2]*0.2f;
+               }
+       }
+       else if(outtype==CB_VEC2) {
+               if(intype==CB_VAL) {
+                       out[0]= in[0];
+                       out[1]= in[0];
+               }
+               else if(intype==CB_VEC3) {
+                       out[0]= in[0];
+                       out[1]= in[1];
+               }
+               else if(intype==CB_RGBA) {
+                       out[0]= in[0];
+                       out[1]= in[1];
+               }
+       }
+       else if(outtype==CB_VEC3) {
+               if(intype==CB_VAL) {
+                       out[0]= in[0];
+                       out[1]= in[0];
+                       out[2]= in[0];
+               }
+               else if(intype==CB_VEC2) {
+                       out[0]= in[0];
+                       out[1]= in[1];
+                       out[2]= 0.0f;
+               }
+               else if(intype==CB_RGBA) {
+                       out[0]= in[0];
+                       out[1]= in[1];
+                       out[2]= in[2];
+               }
+       }
+       else if(outtype==CB_RGBA) {
+               if(intype==CB_VAL) {
+                       out[0]= in[0];
+                       out[1]= in[0];
+                       out[2]= in[0];
+                       out[3]= 1.0f;
+               }
+               else if(intype==CB_VEC2) {
+                       out[0]= in[0];
+                       out[1]= in[1];
+                       out[2]= 0.0f;
+                       out[3]= 1.0f;
+               }
+               else if(intype==CB_VEC3) {
+                       out[0]= in[0];
+                       out[1]= in[1];
+                       out[2]= in[2];
+                       out[3]= 1.0f;
+               }
+       }
+}
+
 CompBuf *typecheck_compbuf(CompBuf *inbuf, int type)
 {
 CompBuf *typecheck_compbuf(CompBuf *inbuf, int type)
 {
-       if(inbuf && inbuf->type!=type && inbuf->rect_procedural==NULL) {
-               CompBuf *outbuf= alloc_compbuf(inbuf->x, inbuf->y, type, 1); 
-               float *inrf= inbuf->rect;
-               float *outrf= outbuf->rect;
-               int x= inbuf->x*inbuf->y;
-               
+       if(inbuf && inbuf->type!=type) {
+               CompBuf *outbuf;
+               float *inrf, *outrf;
+               int x;
+
+               outbuf= alloc_compbuf(inbuf->x, inbuf->y, type, 1); 
+
                /* warning note: xof and yof are applied in pixelprocessor, but should be copied otherwise? */
                outbuf->xof= inbuf->xof;
                outbuf->yof= inbuf->yof;
                /* warning note: xof and yof are applied in pixelprocessor, but should be copied otherwise? */
                outbuf->xof= inbuf->xof;
                outbuf->yof= inbuf->yof;
+
+               if(inbuf->rect_procedural) {
+                       outbuf->rect_procedural= inbuf->rect_procedural;
+                       VECCOPY(outbuf->procedural_size, inbuf->procedural_size);
+                       VECCOPY(outbuf->procedural_offset, inbuf->procedural_offset);
+                       outbuf->procedural_type= inbuf->procedural_type;
+                       outbuf->node= inbuf->node;
+                       return outbuf;
+               }
+
+               inrf= inbuf->rect;
+               outrf= outbuf->rect;
+               x= inbuf->x*inbuf->y;
                
                if(type==CB_VAL) {
                        if(inbuf->type==CB_VEC2) {
                
                if(type==CB_VAL) {
                        if(inbuf->type==CB_VEC2) {
@@ -502,6 +585,25 @@ CompBuf *valbuf_from_rgbabuf(CompBuf *cbuf, int channel)
        return valbuf;
 }
 
        return valbuf;
 }
 
+static CompBuf *generate_procedural_preview(CompBuf *cbuf, int newx, int newy)
+{
+       CompBuf *outbuf;
+       float *outfp;
+       int xrad, yrad, x, y;
+       
+       outbuf= alloc_compbuf(newx, newy, CB_RGBA, 1);
+
+       outfp= outbuf->rect;
+       xrad= outbuf->xrad;
+       yrad= outbuf->yrad;
+       
+       for(y= -yrad; y<-yrad+outbuf->y; y++)
+               for(x= -xrad; x<-xrad+outbuf->x; x++, outfp+=outbuf->type)
+                       cbuf->rect_procedural(cbuf, outfp, (float)x/(float)xrad, (float)y/(float)yrad);
+
+       return outbuf;
+}
+
 void generate_preview(bNode *node, CompBuf *stackbuf)
 {
        bNodePreview *preview= node->preview;
 void generate_preview(bNode *node, CompBuf *stackbuf)
 {
        bNodePreview *preview= node->preview;
@@ -509,7 +611,7 @@ void generate_preview(bNode *node, CompBuf *stackbuf)
        if(preview && stackbuf) {
                CompBuf *cbuf, *stackbuf_use;
                
        if(preview && stackbuf) {
                CompBuf *cbuf, *stackbuf_use;
                
-               if(stackbuf->rect==NULL) return;
+               if(stackbuf->rect==NULL && stackbuf->rect_procedural==NULL) return;
                
                stackbuf_use= typecheck_compbuf(stackbuf, CB_RGBA);
                
                
                stackbuf_use= typecheck_compbuf(stackbuf, CB_RGBA);
                
@@ -522,7 +624,10 @@ void generate_preview(bNode *node, CompBuf *stackbuf)
                        preview->xsize= (140*stackbuf->x)/stackbuf->y;
                }
                
                        preview->xsize= (140*stackbuf->x)/stackbuf->y;
                }
                
-               cbuf= scalefast_compbuf(stackbuf_use, preview->xsize, preview->ysize);
+               if(stackbuf_use->rect_procedural)
+                       cbuf= generate_procedural_preview(stackbuf_use, preview->xsize, preview->ysize);
+               else
+                       cbuf= scalefast_compbuf(stackbuf_use, preview->xsize, preview->ysize);
                
                /* this ensures free-compbuf does the right stuff */
                SWAP(float *, cbuf->rect, node->preview->rect);
                
                /* this ensures free-compbuf does the right stuff */
                SWAP(float *, cbuf->rect, node->preview->rect);
index 0d7bda0604cf97ca75654b84a51ada722295cc04..e111632a195355f6a4a6b9a78af97b68fe3f122a 100644 (file)
@@ -108,6 +108,7 @@ typedef struct CompBuf {
        
        void (*rect_procedural)(struct CompBuf *, float *, float, float);
        float procedural_size[3], procedural_offset[3];
        
        void (*rect_procedural)(struct CompBuf *, float *, float, float);
        float procedural_size[3], procedural_offset[3];
+       int procedural_type;
        bNode *node;            /* only in use for procedural bufs */
        
        struct CompBuf *next, *prev;    /* for pass-on, works nicer than reference counting */
        bNode *node;            /* only in use for procedural bufs */
        
        struct CompBuf *next, *prev;    /* for pass-on, works nicer than reference counting */
@@ -138,6 +139,7 @@ void node_compo_pass_on(struct bNode *node, struct bNodeStack **nsin, struct bNo
 CompBuf *get_cropped_compbuf(rcti *drect, float *rectf, int rectx, int recty, int type);
 CompBuf *scalefast_compbuf(CompBuf *inbuf, int newx, int newy);
 CompBuf *typecheck_compbuf(CompBuf *inbuf, int type);
 CompBuf *get_cropped_compbuf(rcti *drect, float *rectf, int rectx, int recty, int type);
 CompBuf *scalefast_compbuf(CompBuf *inbuf, int newx, int newy);
 CompBuf *typecheck_compbuf(CompBuf *inbuf, int type);
+void typecheck_compbuf_color(float *out, float *in, int outtype, int intype);
 float *compbuf_get_pixel(CompBuf *cbuf, float *rectf, int x, int y, int xrad, int yrad);
 
 /* **************************************************** */
 float *compbuf_get_pixel(CompBuf *cbuf, float *rectf, int x, int y, int xrad, int yrad);
 
 /* **************************************************** */