Minor render memory usage optimization, removed layer and
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Wed, 23 Jan 2008 13:35:51 +0000 (13:35 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Wed, 23 Jan 2008 13:35:51 +0000 (13:35 +0000)
radface from VlakRen, saves about 100mb for 10 million faces.

12 files changed:
source/blender/radiosity/intern/source/radrender.c
source/blender/render/intern/include/render_types.h
source/blender/render/intern/include/renderdatabase.h
source/blender/render/intern/source/convertblender.c
source/blender/render/intern/source/envmap.c
source/blender/render/intern/source/rayshade.c
source/blender/render/intern/source/rendercore.c
source/blender/render/intern/source/renderdatabase.c
source/blender/render/intern/source/shadbuf.c
source/blender/render/intern/source/shadeoutput.c
source/blender/render/intern/source/strand.c
source/blender/render/intern/source/zbuf.c

index ee52956bbd2510bc2e4f65054177cbe1fac0ce73..52e2b46d506341f6805772d2b941d498e36b4edf 100644 (file)
@@ -84,22 +84,23 @@ static float maxenergy;
 
 /* find the face with maximum energy to become shooter */
 /* nb: _rr means rad-render version of existing radio call */
-static VlakRen *findshoot_rr(Render *re)
+static void findshoot_rr(Render *re, VlakRen **shoot_p, RadFace **shootrf_p)
 {
-       RadFace *rf;
+       RadFace *rf, *shootrf, **radface;
        ObjectRen *obr;
        VlakRen *vlr=NULL, *shoot;
        float energy;
        int a;
        
        shoot= NULL;
+       shootrf= NULL;
        maxenergy= 0.0;
        
        for(obr=re->objecttable.first; obr; obr=obr->next) {
                for(a=0; a<obr->totvlak; a++) {
                        if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++;
-                       if(vlr->radface) {
-                               rf= vlr->radface;
+                       if((radface=RE_vlakren_get_radface(obr, vlr, 0))) {
+                               rf= *radface;
                                rf->flag &= ~RAD_SHOOT;
                                
                                energy= rf->unshot[0]*rf->area;
@@ -108,26 +109,31 @@ static VlakRen *findshoot_rr(Render *re)
 
                                if(energy>maxenergy) {
                                        shoot= vlr;
+                                       shootrf= rf;
                                        maxenergy= energy;
                                }
                        }
                }
        }
 
-       if(shoot) {
+       if(shootrf) {
                maxenergy/= RG.totenergy;
-               if(maxenergy<RG.convergence) return NULL;
-               shoot->radface->flag |= RAD_SHOOT;
+               if(maxenergy<RG.convergence) {
+                       *shoot_p= NULL;
+                       *shootrf_p= NULL;
+               }
+               shootrf->flag |= RAD_SHOOT;
        }
 
-       return shoot;
+       *shoot_p= shoot;
+       *shootrf_p= shootrf;
 }
 
-static void backface_test_rr(Render *re, VlakRen *shoot)
+static void backface_test_rr(Render *re, VlakRen *shoot, RadFace *shootrf)
 {
        ObjectRen *obr;
        VlakRen *vlr=NULL;
-       RadFace *rf;
+       RadFace *rf, **radface;
        float tvec[3];
        int a;
        
@@ -135,9 +141,9 @@ static void backface_test_rr(Render *re, VlakRen *shoot)
        for(obr=re->objecttable.first; obr; obr=obr->next) {
                for(a=0; a<obr->totvlak; a++) {
                        if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++;
-                       if(vlr->radface && vlr!=shoot) {
-                               rf= vlr->radface;
-                               VecSubf(tvec, shoot->radface->cent, rf->cent);
+                       if(vlr != shoot && (radface=RE_vlakren_get_radface(obr, vlr, 0))) {
+                               rf= *radface;
+                               VecSubf(tvec, shootrf->cent, rf->cent);
                                
                                if(tvec[0]*rf->norm[0]+ tvec[1]*rf->norm[1]+ tvec[2]*rf->norm[2] < 0.0)
                                        rf->flag |= RAD_BACKFACE;
@@ -150,7 +156,7 @@ static void clear_backface_test_rr(Render *re)
 {
        ObjectRen *obr;
        VlakRen *vlr=NULL;
-       RadFace *rf;
+       RadFace *rf, **radface;
        int a;
        
        /* backface flag clear */
@@ -158,8 +164,8 @@ static void clear_backface_test_rr(Render *re)
                for(a=0; a<obr->totvlak; a++) {
                        if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++;
                        
-                       if(vlr->radface) {
-                               rf= vlr->radface;
+                       if((radface=RE_vlakren_get_radface(obr, vlr, 0))) {
+                               rf= *radface;
                                rf->flag &= ~RAD_BACKFACE;
                        }
                }
@@ -169,11 +175,11 @@ static void clear_backface_test_rr(Render *re)
 extern RadView hemitop, hemiside; // radfactors.c
 
 /* hemi-zbuffering, delivers formfactors array */
-static void makeformfactors_rr(Render *re, VlakRen *shoot)
+static void makeformfactors_rr(Render *re, VlakRen *shoot, RadFace *shootrf)
 {
        ObjectRen *obr;
        VlakRen *vlr=NULL;
-       RadFace *rf;
+       RadFace *rf, **radface;
        float len, vec[3], up[3], side[3], tar[5][3], *fp;
        int a;
 
@@ -182,25 +188,25 @@ static void makeformfactors_rr(Render *re, VlakRen *shoot)
        /* set up hemiview */
        /* first: upvector for hemitop, we use diagonal hemicubes to prevent aliasing */
        
-       VecSubf(vec, shoot->v1->co, shoot->radface->cent);
-       Crossf(up, shoot->radface->norm, vec);
+       VecSubf(vec, shoot->v1->co, shootrf->cent);
+       Crossf(up, shootrf->norm, vec);
        len= Normalize(up);
        
        VECCOPY(hemitop.up, up);
-       VECCOPY(hemiside.up, shoot->radface->norm);
+       VECCOPY(hemiside.up, shootrf->norm);
 
-       Crossf(side, shoot->radface->norm, up);
+       Crossf(side, shootrf->norm, up);
 
        /* five targets */
-       VecAddf(tar[0], shoot->radface->cent, shoot->radface->norm);
-       VecAddf(tar[1], shoot->radface->cent, up);
-       VecSubf(tar[2], shoot->radface->cent, up);
-       VecAddf(tar[3], shoot->radface->cent, side);
-       VecSubf(tar[4], shoot->radface->cent, side);
+       VecAddf(tar[0], shootrf->cent, shootrf->norm);
+       VecAddf(tar[1], shootrf->cent, up);
+       VecSubf(tar[2], shootrf->cent, up);
+       VecAddf(tar[3], shootrf->cent, side);
+       VecSubf(tar[4], shootrf->cent, side);
 
        /* camera */
-       VECCOPY(hemiside.cam, shoot->radface->cent);
-       VECCOPY(hemitop.cam, shoot->radface->cent);
+       VECCOPY(hemiside.cam, shootrf->cent);
+       VECCOPY(hemitop.cam, shootrf->cent);
 
        /* do it! */
        VECCOPY(hemitop.tar, tar[0]);
@@ -218,10 +224,10 @@ static void makeformfactors_rr(Render *re, VlakRen *shoot)
                for(a=0; a<obr->totvlak; a++) {
                        if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++;
                        
-                       if(vlr->radface) {
-                               rf= vlr->radface;
+                       if((radface=RE_vlakren_get_radface(obr, vlr, 0))) {
+                               rf= *radface;
                                if(*fp!=0.0 && rf->area!=0.0) {
-                                       *fp *= shoot->radface->area/rf->area;
+                                       *fp *= shootrf->area/rf->area;
                                        if(*fp>1.0) *fp= 1.0001;
                                }
                                fp++;
@@ -231,17 +237,17 @@ static void makeformfactors_rr(Render *re, VlakRen *shoot)
 }
 
 /* based at RG.formfactors array, distribute shoot energy over other faces */
-static void applyformfactors_rr(Render *re, VlakRen *shoot)
+static void applyformfactors_rr(Render *re, VlakRen *shoot, RadFace *shootrf)
 {
        ObjectRen *obr;
        VlakRen *vlr=NULL;
-       RadFace *rf;
+       RadFace *rf, **radface;
        float *fp, *ref, unr, ung, unb, r, g, b;
        int a;
 
-       unr= shoot->radface->unshot[0];
-       ung= shoot->radface->unshot[1];
-       unb= shoot->radface->unshot[2];
+       unr= shootrf->unshot[0];
+       ung= shootrf->unshot[1];
+       unb= shootrf->unshot[2];
 
        fp= RG.formfactors;
        
@@ -249,8 +255,8 @@ static void applyformfactors_rr(Render *re, VlakRen *shoot)
                for(a=0; a<obr->totvlak; a++) {
                        if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++;
                        
-                       if(vlr->radface) {
-                               rf= vlr->radface;
+                       if((radface=RE_vlakren_get_radface(obr, vlr, 0))) {
+                               rf= *radface;
                                if(*fp!= 0.0) {
                                        
                                        ref= &(vlr->mat->r);
@@ -274,7 +280,7 @@ static void applyformfactors_rr(Render *re, VlakRen *shoot)
                }
        }
        /* shoot energy has been shot */
-       shoot->radface->unshot[0]= shoot->radface->unshot[1]= shoot->radface->unshot[2]= 0.0;
+       shootrf->unshot[0]= shootrf->unshot[1]= shootrf->unshot[2]= 0.0;
 }
 
 
@@ -282,29 +288,30 @@ static void applyformfactors_rr(Render *re, VlakRen *shoot)
 static void progressiverad_rr(Render *re)
 {
        VlakRen *shoot;
+       RadFace *shootrf;
        float unshot[3];
        int it= 0;
        
-       shoot= findshoot_rr(re);
+       findshoot_rr(re, &shoot, &shootrf);
        while( shoot ) {
                
                /* backfaces receive no energy, but are zbuffered... */
-               backface_test_rr(re, shoot);
+               backface_test_rr(re, shoot, shootrf);
                
                /* ...unless it's two sided */
-               if(shoot->radface->flag & RAD_TWOSIDED) {
-                       VECCOPY(unshot, shoot->radface->unshot);
-                       VecMulf(shoot->radface->norm, -1.0);
-                       makeformfactors_rr(re, shoot);
-                       applyformfactors_rr(re, shoot);
-                       VecMulf(shoot->radface->norm, -1.0);
-                       VECCOPY(shoot->radface->unshot, unshot);
+               if(shootrf->flag & RAD_TWOSIDED) {
+                       VECCOPY(unshot, shootrf->unshot);
+                       VecMulf(shootrf->norm, -1.0);
+                       makeformfactors_rr(re, shoot, shootrf);
+                       applyformfactors_rr(re, shoot, shootrf);
+                       VecMulf(shootrf->norm, -1.0);
+                       VECCOPY(shootrf->unshot, unshot);
                }
 
                /* hemi-zbuffers */
-               makeformfactors_rr(re, shoot);
+               makeformfactors_rr(re, shoot, shootrf);
                /* based at RG.formfactors array, distribute shoot energy over other faces */
-               applyformfactors_rr(re, shoot);
+               applyformfactors_rr(re, shoot, shootrf);
                
                it++;
                re->timecursor(it);
@@ -314,7 +321,7 @@ static void progressiverad_rr(Render *re)
                if(re->test_break()) break;
                if(RG.maxiter && RG.maxiter<=it) break;
                
-               shoot= findshoot_rr(re);
+               findshoot_rr(re, &shoot, &shootrf);
        }
        printf(" Unshot energy:%f\n", 1000.0*maxenergy);
        
@@ -327,7 +334,7 @@ static void initradfaces(Render *re)
 {
        ObjectRen *obr;
        VlakRen *vlr= NULL;
-       RadFace *rf;
+       RadFace *rf, **radface;
        int a, b;
        
        /* globals */
@@ -393,7 +400,8 @@ printf(" Rad elems: %d emittors %d\n", RG.totelem, RG.totpatch);
        // uncommented; this isnt satisfying, but i leave it in the code for now (ton)                  
        //                      if(vlr->mat->translucency!=0.0) rf->flag |= RAD_TWOSIDED;
                                
-                               vlr->radface= rf++;
+                               radface=RE_vlakren_get_radface(obr, vlr, 1);
+                               *radface= rf++;
                        }
                }
        }
@@ -428,7 +436,7 @@ static void make_vertex_rad_values(Render *re)
        ObjectRen *obr;
        VertRen *v1=NULL;
        VlakRen *vlr=NULL;
-       RadFace *rf;
+       RadFace *rf, **radface;
        float *col;
        int a;
 
@@ -440,8 +448,8 @@ static void make_vertex_rad_values(Render *re)
                for(a=0; a<obr->totvlak; a++) {
                        if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++;
                        
-                       if(vlr->radface) {
-                               rf= vlr->radface;
+                       if((radface=RE_vlakren_get_radface(obr, vlr, 0))) {
+                               rf= *radface;
                                
                                /* apply correction */
                                rf->totrad[0]= RG.radfactor*pow( rf->totrad[0], RG.igamma);
index 05d8324dfc6e8a54c47de2d09aa2563c1a545dd2..46b5face22a7962be7b1089ad82184b571fdb12f 100644 (file)
@@ -244,7 +244,7 @@ typedef struct ObjectRen {
        struct ObjectRen *next, *prev;
        struct Object *ob, *par;
        struct Scene *sce;
-       int index, psysindex, flag;
+       int index, psysindex, flag, lay;
 
        int totvert, totvlak, totstrand, tothalo;
        int vertnodeslen, vlaknodeslen, strandnodeslen, blohalen;
@@ -309,12 +309,10 @@ typedef struct RadFace {
 
 typedef struct VlakRen {
        struct VertRen *v1, *v2, *v3, *v4;      /* keep in order for ** addressing */
-       unsigned int lay;
        float n[3];
        struct Material *mat;
        char puno;
        char flag, ec;
-       RadFace *radface;
        int index;
 } VlakRen;
 
index a74579acc4af1aa6ccb53fe036e27cf7e36ae86c..cfcbb4e777560bcf7ae6aac641ff429095e58ead 100644 (file)
@@ -42,6 +42,7 @@ struct CustomData;
 struct StrandBuffer;
 struct StrandRen;
 struct ObjectInstanceRen;
+struct RadFace;
 
 #define RE_QUAD_MASK   0x7FFFFFF
 #define RE_QUAD_OFFS   0x8000000
@@ -63,6 +64,7 @@ typedef struct VlakTableNode {
        struct MCol *mcol;
        int totmtface, totmcol;
        float *surfnor;
+       struct RadFace **radface;
 } VlakTableNode;
 
 typedef struct StrandTableNode {
@@ -94,7 +96,7 @@ struct HaloRen *RE_inithalo(struct Render *re, struct ObjectRen *obr, struct Mat
 struct HaloRen *RE_inithalo_particle(struct Render *re, struct ObjectRen *obr, struct DerivedMesh *dm, struct Material *ma,   float *vec,   float *vec1, float *orco, float *uvco, float hasize, float vectsize, int seed);
 struct StrandBuffer *RE_addStrandBuffer(struct ObjectRen *obr, int totvert);
 
-struct ObjectRen *RE_addRenderObject(struct Render *re, struct Object *ob, struct Object *par, int index, int psysindex);
+struct ObjectRen *RE_addRenderObject(struct Render *re, struct Object *ob, struct Object *par, int index, int psysindex, int lay);
 struct ObjectInstanceRen *RE_addRenderInstance(struct Render *re, struct ObjectRen *obr, struct Object *ob, struct Object *par, int index, int psysindex, float mat[][4]);
 void RE_makeRenderInstances(struct Render *re);
 void RE_instanceTransformNormal(struct ObjectInstanceRen *obi, float *nor, float *tnor);
@@ -109,6 +111,7 @@ float *RE_vertren_get_winspeed(struct ObjectInstanceRen *obi, struct VertRen *ve
 struct MTFace *RE_vlakren_get_tface(struct ObjectRen *obr, VlakRen *ren, int n, char **name, int verify);
 struct MCol *RE_vlakren_get_mcol(struct ObjectRen *obr, VlakRen *ren, int n, char **name, int verify);
 float *RE_vlakren_get_surfnor(struct ObjectRen *obr, VlakRen *ren, int verify);
+RadFace **RE_vlakren_get_radface(struct ObjectRen *obr, VlakRen *ren, int verify);
 int RE_vlakren_get_normal(struct Render *re, struct ObjectInstanceRen *obi, struct VlakRen *vlr, float *nor);
 
 float *RE_strandren_get_surfnor(struct ObjectRen *obr, struct StrandRen *strand, int verify);
index de87d2c8cd9958f36a7f34ceab905abad5986182..69ae280dc4c73dabd0001145d8b7a4aebf54e195 100644 (file)
@@ -230,7 +230,7 @@ void RE_make_stars(Render *re, void (*initfunc)(void),
        }
 
        if(re) /* add render object for stars */
-               obr= RE_addRenderObject(re, NULL, NULL, 0, 0);
+               obr= RE_addRenderObject(re, NULL, NULL, 0, 0, 0);
        
        for (x = sx, fx = sx * stargrid; x <= ex; x++, fx += stargrid) {
                for (y = sy, fy = sy * stargrid; y <= ey ; y++, fy += stargrid) {
@@ -1075,7 +1075,6 @@ static void static_particle_strand(Render *re, ObjectRen *obr, Material *ma, flo
                
                vlr->mat= ma;
                vlr->ec= ME_V2V3;
-               vlr->lay= obr->ob->lay;
 
                if(surfnor) {
                        float *snor= RE_vlakren_get_surfnor(obr, vlr, 1);
@@ -1192,7 +1191,6 @@ static void static_particle_strand(Render *re, ObjectRen *obr, Material *ma, flo
                
                vlr->mat= ma;
                vlr->ec= ME_V2V3;
-               vlr->lay= obr->ob->lay;
 
                if(surfnor) {
                        float *snor= RE_vlakren_get_surfnor(obr, vlr, 1);
@@ -1244,7 +1242,6 @@ static void static_particle_wire(ObjectRen *obr, Material *ma, float *vec, float
                
                vlr->mat= ma;
                vlr->ec= ME_V1V2;
-               vlr->lay= obr->ob->lay;
 
        }
        else if(first) {
@@ -1267,7 +1264,6 @@ static void static_particle_wire(ObjectRen *obr, Material *ma, float *vec, float
                
                vlr->mat= ma;
                vlr->ec= ME_V1V2;
-               vlr->lay= obr->ob->lay;
        }
 
 }
@@ -1366,7 +1362,6 @@ static void particle_billboard(Render *re, ObjectRen *obr, Material *ma, Object
        
        vlr->mat= ma;
        vlr->ec= ME_V2V3;
-       vlr->lay= obr->ob->lay;
 
        if(uv_split>1){
                uvdx=uvdy=1.0f/(float)uv_split;
@@ -2304,7 +2299,6 @@ static void init_render_mball(Render *re, ObjectRen *obr)
                vlr->mat= ma;
                vlr->flag= ME_SMOOTH+R_NOPUNOFLIP;
                vlr->ec= 0;
-               vlr->lay= ob->lay;
 
                /* mball -too bad- always has triangles, because quads can be non-planar */
                if(index[3] && index[3]!=index[2]) {
@@ -2418,7 +2412,6 @@ static int dl_surf_to_renderdata(ObjectRen *obr, DispList *dl, Material **matar,
                        flen= CalcNormFloat4(vlr->v4->co, vlr->v3->co, vlr->v2->co, vlr->v1->co, n1);
                        VECCOPY(vlr->n, n1);
                        
-                       vlr->lay= ob->lay;
                        vlr->mat= matar[ dl->col];
                        vlr->ec= ME_V1V2+ME_V2V3;
                        vlr->flag= dl->rt;
@@ -2652,7 +2645,6 @@ static void init_render_curve(Render *re, ObjectRen *obr, int only_verts)
                                                vlr->flag |= R_NOPUNOFLIP;
                                        }
                                        vlr->ec= 0;
-                                       vlr->lay= ob->lay;
                                }
                        }
                }
@@ -2705,7 +2697,6 @@ static void init_render_curve(Render *re, ObjectRen *obr, int only_verts)
                                                        if(a==0) vlr->ec+= ME_V1V2;
 
                                                        vlr->flag= dl->rt;
-                                                       vlr->lay= ob->lay;
 
                                                        /* this is not really scientific: the vertices
                                                                * 2, 3 en 4 seem to give better vertexnormals than 1 2 3:
@@ -3105,7 +3096,6 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int only_verts)
                                                                vlr->flag |= R_NOPUNOFLIP;
                                                        }
                                                        vlr->ec= 0; /* mesh edges rendered separately */
-                                                       vlr->lay= ob->lay;
 
                                                        if(len==0) obr->totvlak--;
                                                        else {
@@ -3176,7 +3166,6 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int only_verts)
                                                vlr->mat= ma;
                                                vlr->flag= 0;
                                                vlr->ec= ME_V1V2;
-                                               vlr->lay= ob->lay;
                                        }
                                }
                                if(edgetable)
@@ -4006,7 +3995,7 @@ static void add_render_object(Render *re, Object *ob, Object *par, int index, in
 
        /* one render object for the data itself */
        if(allow_render) {
-               obr= RE_addRenderObject(re, ob, par, index, 0);
+               obr= RE_addRenderObject(re, ob, par, index, 0, ob->lay);
                if(instanceable) {
                        obr->flag |= R_INSTANCEABLE;
                        Mat4CpyMat4(obr->obmat, ob->obmat);
@@ -4024,7 +4013,7 @@ static void add_render_object(Render *re, Object *ob, Object *par, int index, in
        if(ob->particlesystem.first) {
                psysindex= 1;
                for(psys=ob->particlesystem.first; psys; psys=psys->next, psysindex++) {
-                       obr= RE_addRenderObject(re, ob, par, index, psysindex);
+                       obr= RE_addRenderObject(re, ob, par, index, psysindex, ob->lay);
                        if(instanceable) {
                                obr->flag |= R_INSTANCEABLE;
                                Mat4CpyMat4(obr->obmat, ob->obmat);
index b1b907aebb62b3ec371746955b43cb8aeaf06ef4..6d93d91ae971fdaefb234eb340638a8d0573177e 100644 (file)
@@ -313,12 +313,13 @@ static void env_layerflags(Render *re, unsigned int notlay)
        notlay= ~notlay;
        
        for(obr=re->objecttable.first; obr; obr=obr->next) {
-               for(a=0; a<obr->totvlak; a++) {
-                       if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak;
-                       else vlr++;
+               if((obr->lay & notlay)==0) {
+                       for(a=0; a<obr->totvlak; a++) {
+                               if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak;
+                               else vlr++;
 
-                       if((vlr->lay & notlay)==0)
                                vlr->flag |= R_HIDDEN;
+                       }
                }
        }
 }
index b7541bcbd740744281d30553398ce4aadbd7f913..218f5fe931ed27a609c74e20d0cbae40bd6b85ed 100644 (file)
@@ -79,13 +79,14 @@ static void vlr_face_coords(RayFace *face, float **v1, float **v2, float **v3, f
 
 static int vlr_check_intersect(Isect *is, int ob, RayFace *face)
 {
+       ObjectInstanceRen *obi= RAY_OBJECT_GET((Render*)is->userdata, ob);
        VlakRen *vlr = (VlakRen*)face;
 
        /* I know... cpu cycle waste, might do smarter once */
        if(is->mode==RE_RAY_MIRROR)
                return !(vlr->mat->mode & MA_ONLYCAST);
        else
-               return (is->lay & vlr->lay);
+               return (is->lay & obi->obr->lay);
 }
 
 static float *vlr_get_transform(void *userdata, int i)
index 46f94c81c63e06603892aa0fc612bbd36cbb6058..be96fe8f7945d2a7a572aef0d04e48d5897cc1f3 100644 (file)
@@ -1722,6 +1722,8 @@ void add_halo_flare(Render *re)
 void RE_shade_external(Render *re, ShadeInput *shi, ShadeResult *shr)
 {
        static VlakRen vlr;
+       static ObjectRen obr;
+       static ObjectInstanceRen obi;
        
        /* init */
        if(re) {
@@ -1729,11 +1731,16 @@ void RE_shade_external(Render *re, ShadeInput *shi, ShadeResult *shr)
                
                /* fake render face */
                memset(&vlr, 0, sizeof(VlakRen));
-               vlr.lay= -1;
+               memset(&obr, 0, sizeof(ObjectRen));
+               memset(&obi, 0, sizeof(ObjectInstanceRen));
+               obr.lay= -1;
+               obi.obr= &obr;
                
                return;
        }
        shi->vlr= &vlr;
+       shi->obr= &obr;
+       shi->obi= &obi;
        
        if(shi->mat->nodetree && shi->mat->use_nodes)
                ntreeShaderExecTree(shi->mat->nodetree, shi, shr);
index 8aaf29b65c4f9a135907187abf1b52de33cfcedb..27daad9dc266b6c7fab217a7daec4312fedc8112 100644 (file)
 #define RE_MCOL_ELEMS          4
 #define RE_UV_ELEMS                    2
 #define RE_SURFNOR_ELEMS       3
+#define RE_RADFACE_ELEMS       1
 #define RE_SIMPLIFY_ELEMS      2
 #define RE_FACE_ELEMS  1
 
@@ -363,12 +364,28 @@ float *RE_vlakren_get_surfnor(ObjectRen *obr, VlakRen *vlak, int verify)
        return surfnor + (vlak->index & 255)*RE_SURFNOR_ELEMS;
 }
 
+RadFace **RE_vlakren_get_radface(ObjectRen *obr, VlakRen *vlak, int verify)
+{
+       RadFace **radface;
+       int nr= vlak->index>>8;
+       
+       radface= obr->vlaknodes[nr].radface;
+       if(radface==NULL) {
+               if(verify) 
+                       radface= obr->vlaknodes[nr].radface= MEM_callocN(256*RE_RADFACE_ELEMS*sizeof(void*), "radface table");
+               else
+                       return NULL;
+       }
+       return radface + (vlak->index & 255)*RE_RADFACE_ELEMS;
+}
+
 VlakRen *RE_vlakren_copy(ObjectRen *obr, VlakRen *vlr)
 {
        VlakRen *vlr1 = RE_findOrAddVlak(obr, obr->totvlak++);
        MTFace *mtface, *mtface1;
        MCol *mcol, *mcol1;
        float *surfnor, *surfnor1;
+       RadFace **radface, **radface1;
        int i, index = vlr1->index;
        char *name;
 
@@ -391,6 +408,12 @@ VlakRen *RE_vlakren_copy(ObjectRen *obr, VlakRen *vlr)
                VECCOPY(surfnor1, surfnor);
        }
 
+       radface= RE_vlakren_get_radface(obr, vlr, 0);
+       if(radface) {
+               radface1= RE_vlakren_get_radface(obr, vlr1, 1);
+               *radface1= *radface;
+       }
+
        return vlr1;
 }
 
@@ -695,7 +718,7 @@ StrandBuffer *RE_addStrandBuffer(ObjectRen *obr, int totvert)
 
 /* ------------------------------------------------------------------------ */
 
-ObjectRen *RE_addRenderObject(Render *re, Object *ob, Object *par, int index, int psysindex)
+ObjectRen *RE_addRenderObject(Render *re, Object *ob, Object *par, int index, int psysindex, int lay)
 {
        ObjectRen *obr= MEM_callocN(sizeof(ObjectRen), "object render struct");
        
@@ -704,6 +727,7 @@ ObjectRen *RE_addRenderObject(Render *re, Object *ob, Object *par, int index, in
        obr->par= par;
        obr->index= index;
        obr->psysindex= psysindex;
+       obr->lay= lay;
 
        return obr;
 }
@@ -749,6 +773,8 @@ void free_renderdata_vlaknodes(VlakTableNode *vlaknodes)
                        MEM_freeN(vlaknodes[a].mcol);
                if(vlaknodes[a].surfnor)
                        MEM_freeN(vlaknodes[a].surfnor);
+               if(vlaknodes[a].radface)
+                       MEM_freeN(vlaknodes[a].radface);
        }
        
        MEM_freeN(vlaknodes);
index 42086d078f67c7e04943f6d0bf1456bbd885bd0f..fcd9220df0ea636fcf58803d8e4e6810fda873c8 100644 (file)
@@ -325,7 +325,7 @@ static void shadowbuf_autoclip(Render *re, LampRen *lar)
                                if((ma->mode & MA_SHADBUF)==0) ok= 0;
                        }
                        
-                       if(ok && (vlr->lay & lay)) {
+                       if(ok && (obr->lay & lay)) {
                                clipflag[vlr->v1->index]= 1;
                                clipflag[vlr->v2->index]= 1;
                                clipflag[vlr->v3->index]= 1;
@@ -1558,7 +1558,7 @@ static void isb_bsp_fillfaces(Render *re, LampRen *lar, ISBBranch *root)
                                zspanstrand.shad_alpha= zspan.shad_alpha= ma->shad_alpha;
                        }
                        
-                       if(ok && (vlr->lay & lay)) {
+                       if(ok && (obr->lay & lay)) {
                                float hoco[4][4];
                                int c1, c2, c3, c4=0;
                                int d1, d2, d3, d4=0;
index 1498683baab82d96349a2f269cdc0799500d5f45..8af98158981956c75cd7686f7d3fe8cb441937dd 100644 (file)
@@ -355,7 +355,7 @@ void renderspothalo(ShadeInput *shi, float *col, float alpha)
                if(lar->type==LA_SPOT && (lar->mode & LA_HALO) && lar->haint>0) {
                        
                        if(lar->mode & LA_LAYER) 
-                               if(shi->vlr && (lar->lay & shi->vlr->lay)==0) 
+                               if(shi->vlr && (lar->lay & shi->obr->lay)==0) 
                                        continue;
                        if((lar->lay & shi->lay)==0) 
                                continue;
@@ -1460,7 +1460,7 @@ static void shade_lamp_loop_only_shadow(ShadeInput *shi, ShadeResult *shr)
                        /* yafray: ignore shading by photonlights, not used in Blender */
                        if (lar->type==LA_YF_PHOTON) continue;
                        
-                       if(lar->mode & LA_LAYER) if((lar->lay & shi->vlr->lay)==0) continue;
+                       if(lar->mode & LA_LAYER) if((lar->lay & shi->obr->lay)==0) continue;
                        if((lar->lay & shi->lay)==0) continue;
                        
                        if(lar->shb || (lar->mode & LA_SHAD_RAY)) {
@@ -1520,7 +1520,6 @@ static void wrld_exposure_correct(float *diff)
 void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr)
 {
        Material *ma= shi->mat;
-       VlakRen *vlr= shi->vlr;
        int passflag= shi->passflag;
        
        memset(shr, 0, sizeof(ShadeResult));
@@ -1597,7 +1596,7 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr)
                        if (lar->type==LA_YF_PHOTON) continue;
                        
                        /* test for lamp layer */
-                       if(lar->mode & LA_LAYER) if((lar->lay & vlr->lay)==0) continue;
+                       if(lar->mode & LA_LAYER) if((lar->lay & shi->obr->lay)==0) continue;
                        if((lar->lay & shi->lay)==0) continue;
                        
                        /* accumulates in shr->diff and shr->spec and shr->shad (diffuse with shadow!) */
index 3a4f44b11d3eec4c50bbe0f905b9755d772783fe..7a3e44328725afbac9dc1d67bb3ca2bf1a6cc54b 100644 (file)
@@ -686,7 +686,6 @@ static void strand_shade_point(Render *re, ShadeSample *ssamp, StrandSegment *ss
 
        memset(&vlr, 0, sizeof(vlr));
        vlr.flag= R_SMOOTH;
-       vlr.lay= sseg->strand->buffer->lay;
        if(sseg->buffer->ma->mode & MA_TANGENT_STR)
                vlr.flag |= R_TANGENT;
 
index 2ad1f6bac5328af5840fcf18adf09e6a18e91fa7..3dcefbfdca0ce996567ea7f9066d7476e79b55b3 100644 (file)
@@ -2003,7 +2003,7 @@ void zbuffer_solid(RenderPart *pa, unsigned int lay, short layflag, void(*fillfu
                        else vlr++;
 
                        /* three cases, visible for render, only z values and nothing */
-                       if(vlr->lay & lay) {
+                       if(obr->lay & lay) {
                                if(vlr->mat!=ma) {
                                        ma= vlr->mat;
                                        nofill= ma->mode & (MA_ZTRA|MA_ONLYCAST);
@@ -2191,7 +2191,7 @@ void RE_zbufferall_radio(struct RadView *vw, RNode **rg_elem, int rg_totelem, Re
        else {  /* radio render */
                ObjectRen *obr;
                VlakRen *vlr=NULL;
-               RadFace *rf;
+               RadFace **radface, *rf;
                int totface=0;
                
                /* note: radio render doesn't support duplis */
@@ -2201,8 +2201,8 @@ void RE_zbufferall_radio(struct RadView *vw, RNode **rg_elem, int rg_totelem, Re
                        for(a=0; a<obr->totvlak; a++) {
                                if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++;
                        
-                               if(vlr->radface) {
-                                       rf= vlr->radface;
+                               if((radface=RE_vlakren_get_radface(obr, vlr, 0))) {
+                                       rf= *radface;
                                        if( (rf->flag & RAD_SHOOT)==0 ) {    /* no shootelement */
                                                
                                                if( rf->flag & RAD_TWOSIDED) zvlnr= totface;
@@ -2293,7 +2293,7 @@ void zbuffer_shadow(Render *re, float winmat[][4], LampRen *lar, int *rectz, int
                                if((ma->mode & MA_SHADBUF)==0) ok= 0;
                        }
 
-                       if(ok && (vlr->lay & lay) && !(vlr->flag & R_HIDDEN)) {
+                       if(ok && (obr->lay & lay) && !(vlr->flag & R_HIDDEN)) {
                                c1= zbuf_shadow_project(cache, vlr->v1->index, obwinmat, vlr->v1->co, ho1);
                                c2= zbuf_shadow_project(cache, vlr->v2->index, obwinmat, vlr->v2->co, ho2);
                                c3= zbuf_shadow_project(cache, vlr->v3->index, obwinmat, vlr->v3->co, ho3);
@@ -2508,7 +2508,7 @@ void zbuffer_sss(RenderPart *pa, unsigned int lay, void *handle, void (*func)(vo
                        
                        if(material_in_material(vlr->mat, sss_ma)) {
                                /* three cases, visible for render, only z values and nothing */
-                               if(vlr->lay & lay) {
+                               if(obr->lay & lay) {
                                        if(vlr->mat!=ma) {
                                                ma= vlr->mat;
                                                nofill= ma->mode & MA_ONLYCAST;
@@ -3214,7 +3214,7 @@ static int zbuffer_abuf(RenderPart *pa, APixstr *APixbuf, ListBase *apsmbase, un
                        }
                        
                        if(dofill) {
-                               if(!(vlr->flag & R_HIDDEN) && (vlr->lay & lay)) {
+                               if(!(vlr->flag & R_HIDDEN) && (obr->lay & lay)) {
                                        unsigned short partclip;
                                        
                                        v1= vlr->v1;