New feature: "Stress" texture input channel
authorTon Roosendaal <ton@blender.org>
Thu, 8 Dec 2005 22:05:42 +0000 (22:05 +0000)
committerTon Roosendaal <ton@blender.org>
Thu, 8 Dec 2005 22:05:42 +0000 (22:05 +0000)
(As usual movies disappears after while)

Face example showing stress values on a blend. White is stretch, black
is squeeze
http://www.blender.org/bf/0001_0014.avi

Quick test with softbody stretch
http://www.blender.org/bf/0001_0100.avi

Based on the difference of the "Orco" (original undeformed coordinate)
and the actual render coordinate, a stress value is computed to make
textures react to stretching or wrinking skin.

The texture coordinate is neutral (0) on relaxed state. -1 is squeezed
to zero, +1 is stretched to infinity.
Note that scaling (object itself or parent) also will result in
stress values.

The reason for the huge commit is a cleanup in allocating memory for
the vertices. These were growing too large with new options, so now it
allocates the optional coordinates dynamically.
Saves about 20 MB memory per 1M vertices already. But best of all is that
I now can add much more fun... so tangents, here we come!

14 files changed:
source/blender/blenkernel/intern/material.c
source/blender/makesdna/DNA_material_types.h
source/blender/radiosity/intern/source/radrender.c
source/blender/render/extern/include/render.h
source/blender/render/extern/include/render_types.h
source/blender/render/intern/source/envmap.c
source/blender/render/intern/source/initrender.c
source/blender/render/intern/source/renderHelp.c
source/blender/render/intern/source/rendercore.c
source/blender/render/intern/source/renderdatabase.c
source/blender/render/intern/source/texture.c
source/blender/render/intern/source/zbuf.c
source/blender/renderconverter/intern/convertBlenderScene.c
source/blender/src/buttons_shading.c

index c9c1b4fa98d17c163ed3e7f30c743f10fd0ebe47..b0c57eef25d829c302a9752b504d353089208b7b 100644 (file)
@@ -596,7 +596,7 @@ void init_render_material(Material *ma)
                                if ELEM3(mtex->tex->type, TEX_IMAGE, TEX_PLUGIN, TEX_ENVMAP) ma->texco |= TEXCO_OSA;
                        }
                        
-                       if(ma->texco & (TEXCO_ORCO|TEXCO_REFL|TEXCO_NORM|TEXCO_STRAND)) needuv= 1;
+                       if(ma->texco & (TEXCO_ORCO|TEXCO_REFL|TEXCO_NORM|TEXCO_STRAND|TEXCO_STRESS)) needuv= 1;
                        else if(ma->texco & (TEXCO_GLOB|TEXCO_UV|TEXCO_OBJECT)) needuv= 1;
                        else if(ma->texco & (TEXCO_LAVECTOR|TEXCO_VIEW|TEXCO_STICKY)) needuv= 1;
                        
index bbe7d0f8125e43be30c469d1bf546615370462dc..ff2eb7194eb1ca988943c5a7e191355ed3c51f49 100644 (file)
@@ -221,6 +221,7 @@ typedef struct Material {
 #define TEXCO_OPTIM            4096
        /* stored in vertex->accum, 1 D */
 #define TEXCO_STRAND   8192
+#define TEXCO_STRESS   16384
 
 /* mapto */
 #define MAP_COL                        1
index 50b9569c09f0ebd56427bd506d7989e78147cd37..a6ff8657d0c76f88ea5771bb45503d496f8ebc75 100644 (file)
@@ -399,100 +399,16 @@ static void vecaddfac(float *vec, float *v1, float *v2, float fac)
 
 }
 
-#if 0
-/* unused now, doesnt work... */
-static void filter_rad_values(void)
-{
-       VlakRen *vlr=NULL;
-       VertRen *v1=NULL;
-       RadFace *rf;
-       float n1[3], n2[3], n3[4], n4[3], co[4];
-       int a;
-       
-       /* one filter pass */
-       for(a=0; a<R.totvert; a++) {
-               if((a & 255)==0) v1= R.blove[a>>8]; else v1++;
-               if(v1->accum>0.0) {
-                       v1->rad[0]= v1->rad[0]/v1->accum;
-                       v1->rad[1]= v1->rad[1]/v1->accum;
-                       v1->rad[2]= v1->rad[2]/v1->accum;
-                       v1->accum= 0.0;
-               }
-       }
-       /* cosines in verts accumulate in faces */
-       for(a=0; a<R.totvlak; a++) {
-               if((a & 255)==0) vlr= R.blovl[a>>8]; else vlr++;
-               
-               if(vlr->radface) {
-                       rf= vlr->radface;
-                       
-                       /* calculate cosines of angles, for weighted add (irregular faces) */
-                       VecSubf(n1, vlr->v2->co, vlr->v1->co);
-                       VecSubf(n2, vlr->v3->co, vlr->v2->co);
-                       Normalise(n1);
-                       Normalise(n2);
-       
-                       if(vlr->v4==NULL) {
-                               VecSubf(n3, vlr->v1->co, vlr->v3->co);
-                               Normalise(n3);
-                               
-                               co[0]= saacos(-n3[0]*n1[0]-n3[1]*n1[1]-n3[2]*n1[2])/M_PI;
-                               co[1]= saacos(-n1[0]*n2[0]-n1[1]*n2[1]-n1[2]*n2[2])/M_PI;
-                               co[2]= saacos(-n2[0]*n3[0]-n2[1]*n3[1]-n2[2]*n3[2])/M_PI;
-                               co[0]= co[1]= co[2]= 1.0/3.0;
-                       }
-                       else {
-                               VecSubf(n3, vlr->v4->co, vlr->v3->co);
-                               VecSubf(n4, vlr->v1->co, vlr->v4->co);
-                               Normalise(n3);
-                               Normalise(n4);
-                               
-                               co[0]= saacos(-n4[0]*n1[0]-n4[1]*n1[1]-n4[2]*n1[2])/M_PI;
-                               co[1]= saacos(-n1[0]*n2[0]-n1[1]*n2[1]-n1[2]*n2[2])/M_PI;
-                               co[2]= saacos(-n2[0]*n3[0]-n2[1]*n3[1]-n2[2]*n3[2])/M_PI;
-                               co[3]= saacos(-n3[0]*n4[0]-n3[1]*n4[1]-n3[2]*n4[2])/M_PI;
-                               co[0]= co[1]= co[2]= co[3]= 1.0/4.0;
-                       }
-                       
-                       rf->totrad[0]= rf->totrad[1]= rf->totrad[2]= 0.0;
+/* unused now, doesnt work..., find it in cvs of nov 2005 or older */
+/* static void filter_rad_values(void) */
 
-                       vecaddfac(rf->totrad, rf->totrad, vlr->v1->rad, co[0]); 
-                       vecaddfac(rf->totrad, rf->totrad, vlr->v2->rad, co[1]); 
-                       vecaddfac(rf->totrad, rf->totrad, vlr->v3->rad, co[2]); 
-                       if(vlr->v4) {
-                               vecaddfac(rf->totrad, rf->totrad, vlr->v4->rad, co[3]); 
-                       }
-               }
-       }
-
-       /* accumulate vertexcolors again */
-       for(a=0; a<R.totvlak; a++) {
-               if((a & 255)==0) vlr= R.blovl[a>>8]; else vlr++;
-               
-               if(vlr->radface) {
-                       rf= vlr->radface;
-
-                       vecaddfac(vlr->v1->rad, vlr->v1->rad, rf->totrad, rf->area); 
-                       vlr->v1->accum+= rf->area;
-                       vecaddfac(vlr->v2->rad, vlr->v2->rad, rf->totrad, rf->area); 
-                       vlr->v2->accum+= rf->area;
-                       vecaddfac(vlr->v3->rad, vlr->v3->rad, rf->totrad, rf->area); 
-                       vlr->v3->accum+= rf->area;
-                       if(vlr->v4) {
-                               vecaddfac(vlr->v4->rad, vlr->v4->rad, rf->totrad, rf->area); 
-                               vlr->v4->accum+= rf->area;
-                       }
-               }
-       }
-
-}
-#endif
 
 static void make_vertex_rad_values()
 {
        VertRen *v1=NULL;
        VlakRen *vlr=NULL;
        RadFace *rf;
+       float *col;
        int a;
 
        RG.igamma= 1.0/RG.gamma;
@@ -515,26 +431,34 @@ static void make_vertex_rad_values()
                        if(vlr->mat->g > 0.0) rf->totrad[1]/= vlr->mat->g;
                        if(vlr->mat->b > 0.0) rf->totrad[2]/= vlr->mat->b;
                        
-                       vecaddfac(vlr->v1->rad, vlr->v1->rad, rf->totrad, rf->area); 
-                       vlr->v1->accum+= rf->area;
-                       vecaddfac(vlr->v2->rad, vlr->v2->rad, rf->totrad, rf->area); 
-                       vlr->v2->accum+= rf->area;
-                       vecaddfac(vlr->v3->rad, vlr->v3->rad, rf->totrad, rf->area); 
-                       vlr->v3->accum+= rf->area;
+                       col= RE_vertren_get_rad(vlr->v1, 1);
+                       vecaddfac(col, col, rf->totrad, rf->area); 
+                       col[3]+= rf->area;
+                       
+                       col= RE_vertren_get_rad(vlr->v2, 1);
+                       vecaddfac(col, col, rf->totrad, rf->area); 
+                       col[3]+= rf->area;
+                       
+                       col= RE_vertren_get_rad(vlr->v3, 1);
+                       vecaddfac(col, col, rf->totrad, rf->area); 
+                       col[3]+= rf->area;
+
                        if(vlr->v4) {
-                               vecaddfac(vlr->v4->rad, vlr->v4->rad, rf->totrad, rf->area); 
-                               vlr->v4->accum+= rf->area;
+                               col= RE_vertren_get_rad(vlr->v4, 1);
+                               vecaddfac(col, col, rf->totrad, rf->area); 
+                               col[3]+= rf->area;
                        }
                }
        }
        
        /* make vertex colors */
        for(a=0; a<R.totvert; a++) {
-               if((a & 255)==0) v1= R.blove[a>>8]; else v1++;
-               if(v1->accum>0.0) {
-                       v1->rad[0]/= v1->accum;
-                       v1->rad[1]/= v1->accum;
-                       v1->rad[2]/= v1->accum;                 
+               if((a & 255)==0) v1= RE_findOrAddVert(a); else v1++;
+               col= RE_vertren_get_rad(v1, 0);
+               if(col[3]>0.0) {
+                       col[0]/= col[3];
+                       col[1]/= col[3];
+                       col[2]/= col[3];
                }
        }
 
index ec724b55846c8f260fa527b929dd8fabdffcd5c4..5f8ceb45b15037c608bf2ee0966b71cb8eb6646c 100644 (file)
@@ -199,7 +199,7 @@ void init_ao_sphere(float *sphere, int tot, int iter);
 
 
 /* --------------------------------------------------------------------- */
-/* renderdatabase (3)                                                    */
+/* renderdatabase ()                                                    */
 /* --------------------------------------------------------------------- */
 struct VlakRen *RE_findOrAddVlak(int nr);
 struct VertRen *RE_findOrAddVert(int nr);
@@ -207,6 +207,15 @@ struct HaloRen *RE_findOrAddHalo(int nr);
 HaloRen *RE_inithalo(struct Material *ma, float *vec, float *vec1, float *orco, float hasize, 
                                        float vectsize, int seed);
 
+float *RE_vertren_get_sticky(struct VertRen *ver, int verify);
+float *RE_vertren_get_stress(struct VertRen *ver, int verify);
+float *RE_vertren_get_rad(struct VertRen *ver, int verify);
+float *RE_vertren_get_strand(struct VertRen *ver, int verify);
+float *RE_vertren_get_tangent(struct VertRen *ver, int verify);
+
+void RE_free_vertex_tables(void);
+void RE_init_vertex_tables(void);
+
 /**
        * callbacks (11):
        *
index 531a7fc5ceba1e902f6aebcd8c1111d04b75f278..dc2f5616f29cf7fb8dea18613dcd8f39375f39df 100644 (file)
@@ -89,7 +89,7 @@ typedef struct ShadeInput
        
        /* texture coordinates */
        float lo[3], gl[3], uv[3], ref[3], orn[3], winco[3], sticky[3], vcol[3], rad[3];
-       float vn[3], vno[3], facenor[3], view[3], refcol[4], displace[3], strand, tang[3];
+       float vn[3], vno[3], facenor[3], view[3], refcol[4], displace[3], strand, tang[3], stress;
        
        /* dx/dy OSA coordinates */
        float dxco[3], dyco[3];
@@ -110,6 +110,7 @@ typedef struct ShadeInput
 } ShadeInput;
 
 struct MemArena;
+struct VertTableNode;
 
 /* here only stuff to initalize the render itself */
 typedef struct RE_Render
@@ -149,7 +150,7 @@ typedef struct RE_Render
        ListBase lights;
        struct LampRen **la;
        struct VlakRen **blovl;
-       struct VertRen **blove;
+       struct VertTableNode *vertnodes;
        struct HaloRen **bloha;
 
        /* arena for allocating data for use during render, for
@@ -198,13 +199,11 @@ typedef struct VertRen
        float co[3];
        float n[3];
        float ho[4];
-       float rad[3];                   /* result radio rendering */
        float *orco;
-       float *sticky;
-       void *svert;                    /* smooth vert, only used during initrender */
        short clip;     
-       short flag;                             /* in use for clipping ztra parts */
+       short flag;                             /* in use for clipping ztra parts, temp setting stuff in convertBlenderscene.c */
        float accum;                    /* accum for radio weighting, and for strand texco static particles */
+       int index;                      /* index allows extending vertren with any property */
 } VertRen;
 
 /* ------------------------------------------------------------------------- */
index f7c31fa099a96efb61eec0ca22a9cfca0353127a..aba3a34929cf49f0a340bd1731e1b434a18ffeca 100644 (file)
@@ -289,7 +289,7 @@ static void env_rotate_scene(float mat[][4], int mode)
        }
        
        for(a=0; a<R.totvert; a++) {
-               if((a & 255)==0) ver= R.blove[a>>8];
+               if((a & 255)==0) ver= RE_findOrAddVert(a);
                else ver++;
                
                MTC_Mat4MulVecfl(tmat, ver->co);
index 1f1ffc20cf578da100467b7fbfacaa2e97d7eaf0..ba9216fa80e5e674c6640adf1db6cc230d68b402 100644 (file)
@@ -479,11 +479,12 @@ static void init_def_material(void)
        init_render_material(ma);
 }
 
+/* this is called in creator.c, on startup */
 void RE_init_render_data(void)
 {
        memset(&R, 0, sizeof(RE_Render));
        
-       R.blove= (VertRen **)MEM_callocN(sizeof(void *)*(TABLEINITSIZE),"Blove");
+       RE_init_vertex_tables();
        R.blovl= (VlakRen **)MEM_callocN(sizeof(void *)*(TABLEINITSIZE),"Blovl");
        R.bloha= (HaloRen **)MEM_callocN(sizeof(void *)*(TABLEINITSIZE),"Bloha");
        
@@ -491,10 +492,11 @@ void RE_init_render_data(void)
        init_filt_mask();
 }
 
+/* called in usiblender.c on exit, also for blender -b render */
 void RE_free_render_data()
 {
-       MEM_freeN(R.blove);
-       R.blove= NULL;
+       MEM_freeN(R.vertnodes);
+       R.vertnodes= NULL;
        MEM_freeN(R.blovl);
        R.blovl= NULL;
        MEM_freeN(R.bloha);
index aa966268acae74a19b699767e3fbbe976804a1af..aba780794724cd33c2c5896a466f1118ef052406 100644 (file)
@@ -149,7 +149,7 @@ void setzbufvlaggen( void (*projectfunc)(float *, float *) )
 
    /* calculate view coordinates (and zbuffer value) */
        for(a=0; a< R.totvert;a++) {
-               if((a & 255)==0) ver= R.blove[a>>8];
+               if((a & 255)==0) ver= RE_findOrAddVert(a);
                else ver++;
 
                if(R.r.mode & R_PANORAMA) {
index 99e9384f5b8212ebf7bb48ac5088d6fe746ae17f..3ca504e2ce49988e14f5db82b605929a24bb97bf 100644 (file)
@@ -2141,9 +2141,20 @@ void shade_input_set_coords(ShadeInput *shi, float u, float v, int i1, int i2, i
                        shi->orn[2]= -shi->vn[2];
                }
                if(mode & MA_RADIO) {
-                       shi->rad[0]= (l*v3->rad[0] - u*v1->rad[0] - v*v2->rad[0]);
-                       shi->rad[1]= (l*v3->rad[1] - u*v1->rad[1] - v*v2->rad[1]);
-                       shi->rad[2]= (l*v3->rad[2] - u*v1->rad[2] - v*v2->rad[2]);
+                       float *r1, *r2, *r3;
+                       
+                       r1= RE_vertren_get_rad(v1, 0);
+                       r2= RE_vertren_get_rad(v2, 0);
+                       r3= RE_vertren_get_rad(v3, 0);
+                       
+                       if(r1 && r2 && r3) {
+                               shi->rad[0]= (l*r3[0] - u*r1[0] - v*r2[0]);
+                               shi->rad[1]= (l*r3[1] - u*r1[1] - v*r2[1]);
+                               shi->rad[2]= (l*r3[2] - u*r1[2] - v*r2[2]);
+                       }
+                       else {
+                               shi->rad[0]= shi->rad[1]= shi->rad[2]= 0.0;
+                       }
                }
                else {
                        shi->rad[0]= shi->rad[1]= shi->rad[2]= 0.0;
@@ -2152,7 +2163,19 @@ void shade_input_set_coords(ShadeInput *shi, float u, float v, int i1, int i2, i
                        /* mirror reflection colour textures (and envmap) */
                        calc_R_ref(shi);
                }
-               
+               if(texco & TEXCO_STRESS) {
+                       float *s1, *s2, *s3;
+                       
+                       s1= RE_vertren_get_stress(v1, 0);
+                       s2= RE_vertren_get_stress(v2, 0);
+                       s3= RE_vertren_get_stress(v3, 0);
+                       if(s1 && s2 && s3) {
+                               shi->stress= l*s3[0] - u*s1[0] - v*s2[0];
+                               if(shi->stress<1.0f) shi->stress-= 1.0f;
+                               else shi->stress= (shi->stress-1.0f)/shi->stress;
+                       }
+                       else shi->stress= 0.0f;
+               }
        }
        else {
                shi->rad[0]= shi->rad[1]= shi->rad[2]= 0.0;
@@ -2225,7 +2248,7 @@ void *shadepixel(float x, float y, int z, int facenr, int mask, float *col, floa
                VECCOPY(rco, col);
        }
        else if( (facenr & 0x7FFFFF) <= R.totvlak) {
-               VertRen *v1, *v2, *v3;
+               VertRen *v1;
                Material *mat;
                MaterialLayer *ml;
                float alpha, fac, zcor;
@@ -2349,17 +2372,24 @@ void *shadepixel(float x, float y, int z, int facenr, int mask, float *col, floa
                }
                /* after this the u and v AND shi.dxuv and shi.dyuv are incorrect */
                if(shi.mat->texco & TEXCO_STICKY) {
-                       if(v1->sticky) {
+                       VertRen *v2, *v3;
+                       float *s1, *s2, *s3;
+                       
+                       if(facenr & 0x800000) {
+                               v2= vlr->v3; v3= vlr->v4;
+                       } else {
+                               v2= vlr->v2; v3= vlr->v3;
+                       }
+                       
+                       s1= RE_vertren_get_sticky(v1, 0);
+                       s2= RE_vertren_get_sticky(v2, 0);
+                       s3= RE_vertren_get_sticky(v3, 0);
+                       
+                       if(s1 && s2 && s3) {
                                extern float Zmulx, Zmuly;
-                               float *o1, *o2, *o3, hox, hoy, l, dl, u, v;
+                               float hox, hoy, l, dl, u, v;
                                float s00, s01, s10, s11, detsh;
                                
-                               if(facenr & 0x800000) {
-                                       v2= vlr->v3; v3= vlr->v4;
-                               } else {
-                                       v2= vlr->v2; v3= vlr->v3;
-                               }
-                               
                                s00= v3->ho[0]/v3->ho[3] - v1->ho[0]/v1->ho[3];
                                s01= v3->ho[1]/v3->ho[3] - v1->ho[1]/v1->ho[3];
                                s10= v3->ho[0]/v3->ho[3] - v2->ho[0]/v2->ho[3];
@@ -2376,12 +2406,8 @@ void *shadepixel(float x, float y, int z, int facenr, int mask, float *col, floa
                                v= (hoy - v3->ho[1]/v3->ho[3])*s00 - (hox - v3->ho[0]/v3->ho[3])*s01;
                                l= 1.0+u+v;
                                
-                               o1= v1->sticky;
-                               o2= v2->sticky;
-                               o3= v3->sticky;
-                               
-                               shi.sticky[0]= l*o3[0]-u*o1[0]-v*o2[0];
-                               shi.sticky[1]= l*o3[1]-u*o1[1]-v*o2[1];
+                               shi.sticky[0]= l*s3[0]-u*s1[0]-v*s2[0];
+                               shi.sticky[1]= l*s3[1]-u*s1[1]-v*s2[1];
                                shi.sticky[2]= 0.0;
                                
                                if(shi.osatex) {
@@ -2391,11 +2417,11 @@ void *shadepixel(float x, float y, int z, int facenr, int mask, float *col, floa
                                        shi.dyuv[1]=  s00/Zmuly;
                                        
                                        dl= shi.dxuv[0]+shi.dxuv[1];
-                                       shi.dxsticky[0]= dl*o3[0]-shi.dxuv[0]*o1[0]-shi.dxuv[1]*o2[0];
-                                       shi.dxsticky[1]= dl*o3[1]-shi.dxuv[0]*o1[1]-shi.dxuv[1]*o2[1];
+                                       shi.dxsticky[0]= dl*s3[0]-shi.dxuv[0]*s1[0]-shi.dxuv[1]*s2[0];
+                                       shi.dxsticky[1]= dl*s3[1]-shi.dxuv[0]*s1[1]-shi.dxuv[1]*s2[1];
                                        dl= shi.dyuv[0]+shi.dyuv[1];
-                                       shi.dysticky[0]= dl*o3[0]-shi.dyuv[0]*o1[0]-shi.dyuv[1]*o2[0];
-                                       shi.dysticky[1]= dl*o3[1]-shi.dyuv[0]*o1[1]-shi.dyuv[1]*o2[1];
+                                       shi.dysticky[0]= dl*s3[0]-shi.dyuv[0]*s1[0]-shi.dyuv[1]*s2[0];
+                                       shi.dysticky[1]= dl*s3[1]-shi.dyuv[0]*s1[1]-shi.dyuv[1]*s2[1];
                                }
                        }
                }
index b2f7cdfca48230a20836ad0a24a5691272b3577a..4c7453bf1b10b228c0c18f6ca2438549ad3d5abf 100644 (file)
@@ -44,7 +44,7 @@
  * offset in a 256-entry block.
  *
  * - If the 256-entry block entry has an entry in the
- * blove/bloha/blovl array of the current block, the i-th entry in
+ * vertnodes/bloha/blovl array of the current block, the i-th entry in
  * that block is allocated to this entry.
  *
  * - If the entry has no block allocated for it yet, memory is
 
 /* ------------------------------------------------------------------------- */
 
-#if 0
-/* proposal for more dynamic allocation of options for render vertices, so we dont
-   have to reserve this space inside vertices */
+
+/* More dynamic allocation of options for render vertices, so we dont
+   have to reserve this space inside vertices.
+   Important; vertices should have been created already (to get tables checked) 
+   that's a reason why the calls demand VertRen * as arg, not the index */
+
+/* NOTE! the hardcoded table size 256 is used still in code for going quickly over vertices/faces */
+
+#define RE_STICKY_ELEMS                2
+#define RE_STRESS_ELEMS                1
+#define RE_RAD_ELEMS           4
+#define RE_STRAND_ELEMS                1
+#define RE_TANGENT_ELEMS       3
+#define RE_STRESS_ELEMS                1
+
+/* render allocates totvert/256 of these nodes, for lookup and quick alloc */
 typedef struct VertTableNode {
-       VertRen *vert;
+       struct VertRen *vert;
        float *rad;
        float *sticky;
        float *strand;
@@ -86,55 +99,162 @@ typedef struct VertTableNode {
        float *stress;
 } VertTableNode;
 
-#define RE_STICKY_ELEMS        3
 float *RE_vertren_get_sticky(VertRen *ver, int verify)
 {
        float *sticky;
-       int a= ver->index>>8;
+       int nr= ver->index>>8;
        
-       sticky= R.blove[a].sticky;
+       sticky= R.vertnodes[nr].sticky;
        if(sticky==NULL) {
                if(verify) 
-                       sticky= R.blove[a].sticky= MEM_mallocN(RE_STICKY_ELEMS*sizeof(float), "sticky table");
+                       sticky= R.vertnodes[nr].sticky= MEM_mallocN(256*RE_STICKY_ELEMS*sizeof(float), "sticky table");
+               else
+                       return NULL;
+       }
+       return sticky + (ver->index & 255)*RE_STICKY_ELEMS;
+}
+
+float *RE_vertren_get_stress(VertRen *ver, int verify)
+{
+       float *stress;
+       int nr= ver->index>>8;
+       
+       stress= R.vertnodes[nr].stress;
+       if(stress==NULL) {
+               if(verify) 
+                       stress= R.vertnodes[nr].stress= MEM_mallocN(256*RE_STRESS_ELEMS*sizeof(float), "stress table");
+               else
+                       return NULL;
+       }
+       return stress + (ver->index & 255)*RE_STRESS_ELEMS;
+}
+
+/* this one callocs! */
+float *RE_vertren_get_rad(VertRen *ver, int verify)
+{
+       float *rad;
+       int nr= ver->index>>8;
+       
+       rad= R.vertnodes[nr].rad;
+       if(rad==NULL) {
+               if(verify) 
+                       rad= R.vertnodes[nr].rad= MEM_callocN(256*RE_RAD_ELEMS*sizeof(float), "rad table");
+               else
+                       return NULL;
+       }
+       return rad + (ver->index & 255)*RE_RAD_ELEMS;
+}
+
+float *RE_vertren_get_strand(VertRen *ver, int verify)
+{
+       float *strand;
+       int nr= ver->index>>8;
+       
+       strand= R.vertnodes[nr].strand;
+       if(strand==NULL) {
+               if(verify) 
+                       strand= R.vertnodes[nr].strand= MEM_mallocN(256*RE_STRAND_ELEMS*sizeof(float), "strand table");
                else
                        return NULL;
        }
-       sticky+= (nr & 255)*RE_STICKY_ELEMS;
+       return strand + (ver->index & 255)*RE_STRAND_ELEMS;
 }
-#endif
+
+float *RE_vertren_get_tangent(VertRen *ver, int verify)
+{
+       float *tangent;
+       int nr= ver->index>>8;
+       
+       tangent= R.vertnodes[nr].tangent;
+       if(tangent==NULL) {
+               if(verify) 
+                       tangent= R.vertnodes[nr].tangent= MEM_mallocN(256*RE_TANGENT_ELEMS*sizeof(float), "tangent table");
+               else
+                       return NULL;
+       }
+       return tangent + (ver->index & 255)*RE_TANGENT_ELEMS;
+}
+
 
 VertRen *RE_findOrAddVert(int nr)
 {
-       VertRen *v, **temp;
-       static int rblovelen=TABLEINITSIZE;
+       VertTableNode *temp;
+       VertRen *v;
+       static int rvertnodeslen=TABLEINITSIZE;
        int a;
 
        if(nr<0) {
                printf("error in findOrAddVert: %d\n",nr);
-               return R.blove[0];
+               return R.vertnodes[0].vert;
        }
        a= nr>>8;
        
-       if (a>=rblovelen-1){  /* Need to allocate more columns..., and keep last element NULL for free loop */
-               //printf("Allocating %i more vert groups.  %i total.\n", 
-               //      TABLEINITSIZE, rblovelen+TABLEINITSIZE );
-               temp=R.blove;
-               R.blove=(VertRen**)MEM_callocN(sizeof(void*)*(rblovelen+TABLEINITSIZE) , "Blove");
-               memcpy(R.blove, temp, rblovelen*sizeof(void*));
-               memset(&(R.blove[rblovelen]), 0, TABLEINITSIZE*sizeof(void*));
-               rblovelen+=TABLEINITSIZE; 
+       if (a>=rvertnodeslen-1){  /* Need to allocate more columns..., and keep last element NULL for free loop */
+               temp= R.vertnodes;
+               
+               R.vertnodes= MEM_mallocN(sizeof(VertTableNode)*(rvertnodeslen+TABLEINITSIZE) , "vertnodes");
+               memcpy(R.vertnodes, temp, rvertnodeslen*sizeof(VertTableNode));
+               memset(R.vertnodes+rvertnodeslen, 0, TABLEINITSIZE*sizeof(VertTableNode));
+               
+               rvertnodeslen+=TABLEINITSIZE; 
                MEM_freeN(temp);        
        }
        
-       v= R.blove[a];
-       if(v==0) {
+       v= R.vertnodes[a].vert;
+       if(v==NULL) {
+               int i;
+               
                v= (VertRen *)MEM_callocN(256*sizeof(VertRen),"findOrAddVert");
-               R.blove[a]= v;
+               R.vertnodes[a].vert= v;
+               
+               for(i= (nr & 0xFFFFFF00), a=0; a<256; a++, i++) {
+                       v[a].index= i;
+               }
        }
        v+= (nr & 255);
        return v;
 }
 
+void RE_free_vertex_tables(void)
+{
+       int a=0;
+       
+       while(R.vertnodes[a].vert) {
+               if(R.vertnodes[a].vert) {
+                       MEM_freeN(R.vertnodes[a].vert);
+                       R.vertnodes[a].vert= NULL;
+
+                       if(R.vertnodes[a].rad) {
+                               MEM_freeN(R.vertnodes[a].rad);
+                               R.vertnodes[a].rad= NULL;
+                       }
+                       if(R.vertnodes[a].sticky) {
+                               MEM_freeN(R.vertnodes[a].sticky);
+                               R.vertnodes[a].sticky= NULL;
+                       }
+                       if(R.vertnodes[a].strand) {
+                               MEM_freeN(R.vertnodes[a].strand);
+                               R.vertnodes[a].strand= NULL;
+                       }
+                       if(R.vertnodes[a].tangent) {
+                               MEM_freeN(R.vertnodes[a].tangent);
+                               R.vertnodes[a].tangent= NULL;
+                       }
+                       if(R.vertnodes[a].stress) {
+                               MEM_freeN(R.vertnodes[a].stress);
+                               R.vertnodes[a].stress= NULL;
+                       }
+               }
+               a++;
+       }
+}
+
+/* only once, on startup */
+void RE_init_vertex_tables(void)
+{
+       R.vertnodes= MEM_callocN(sizeof(VertTableNode)*TABLEINITSIZE , "vertnodes");
+}
+
 /* ------------------------------------------------------------------------ */
 int rblohalen=TABLEINITSIZE;
 HaloRen *RE_findOrAddHalo(int nr)
index 344957608fe8795820e1a3a87a4d60743ff76715..38936ec89fa2ec82afd927cfaaaea4ea40885f90 100644 (file)
@@ -1462,6 +1462,15 @@ void do_material_tex(ShadeInput *shi)
                                dy[0]= shi->dystrand;
                                dy[1]= dy[2]= 0.0f;
                        }
+                       else if(mtex->texco==TEXCO_STRESS) {
+                               co= tempvec; dx= dxt; dy= dyt;
+                               co[0]= shi->stress;
+                               co[1]= co[2]= 0.0f;
+                               dx[0]= 0.0f;
+                               dx[1]= dx[2]= 0.0f;
+                               dy[0]= 0.0f;
+                               dy[1]= dy[2]= 0.0f;
+                       }
                        else continue;  // can happen when texco defines disappear and it renders old files
                        
                        /* de pointer defines if bumping happens */
index f7480c4cb2f17a57116f7d5cf03c84f65b329476..368acfe1a4177a13991dc2855d37633a27569e60 100644 (file)
@@ -2559,9 +2559,7 @@ static void set_faces_raycountflag(void)
        maxy= (float)(2*Amaxy-R.recty+2)/(float)R.recty;
        
        for(v=0; v<R.totvert; v++) {
-               if((v & 255)==0) {
-                       ver= R.blove[v>>8];
-               }
+               if((v & 255)==0) ver= RE_findOrAddVert(v);
                else ver++;
                
                wco= ver->ho[3];
index 776d656abafeec86b646db74ace3830485c67a83..509e42637c0644f6f49bba8f9ffe9c2783d5b4d1 100644 (file)
@@ -314,6 +314,14 @@ void RE_make_stars(void (*initfunc)(void),
 
 /* ------------------------------------------------------------------------- */
 
+static VertRen *RE_duplicate_vertren(VertRen *ver)
+{
+       VertRen *v1= RE_findOrAddVert(R.totvert++);
+       int index= v1->index;
+       *v1= *ver;
+       v1->index= index;
+}
+
 static void split_v_renderfaces(int startvlak, int startvert, int usize, int vsize, int uIndex, int cyclu, int cyclv)
 {
        int vLen = vsize-1+(!!cyclv);
@@ -322,10 +330,9 @@ static void split_v_renderfaces(int startvlak, int startvert, int usize, int vsi
 
        for (v=0; v<vLen; v++) {
                VlakRen *vlr = RE_findOrAddVlak(startvlak + vLen*uIndex + v);
-               VertRen *vert = RE_findOrAddVert(R.totvert++);
+               VertRen *vert = RE_duplicate_vertren(vlr->v2);
 
                if (cyclv) {
-                       *vert = *vlr->v2;
                        vlr->v2 = vert;
 
                        if (v==vLen-1) {
@@ -336,7 +343,6 @@ static void split_v_renderfaces(int startvlak, int startvert, int usize, int vsi
                                vlr->v1 = vert;
                        }
                } else {
-                       *vert = *vlr->v2;
                        vlr->v2 = vert;
 
                        if (v<vLen-1) {
@@ -345,60 +351,12 @@ static void split_v_renderfaces(int startvlak, int startvert, int usize, int vsi
                        }
 
                        if (v==0) {
-                               vert = RE_findOrAddVert(R.totvert++);
-                               *vert = *vlr->v1;
-                               vlr->v1 = vert;
+                               vlr->v1 = RE_duplicate_vertren(vlr->v1);
                        } 
                }
        }
 }
 
-#if 0
-static void DBG_show_shared_render_faces(int firstvert, int firstface)
-{
-       int i;
-
-       for (i=firstvert; i<R.totvert; i++) {
-               VertRen *ver = RE_findOrAddVert(i);
-
-               ver->n[0] = ver->n[1] = ver->n[2] = 0.0;
-               ver->sticky = 0;
-       }
-
-       for (i=firstface; i<R.totvlak; i++) {
-               VlakRen *vlr = RE_findOrAddVlak(i);
-               float cent[3];
-
-               if (vlr->v4) {
-                       CalcCent4f(cent, vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->v4->co);
-                       VecAddf(vlr->v4->n, vlr->v4->n, cent);
-                       vlr->v4->sticky = (float*) (((int) vlr->v4->sticky) + 1);
-               } else {
-                       CalcCent3f(cent, vlr->v1->co, vlr->v2->co, vlr->v3->co);
-               }
-
-               VecAddf(vlr->v1->n, vlr->v1->n, cent);
-               VecAddf(vlr->v2->n, vlr->v2->n, cent);
-               VecAddf(vlr->v3->n, vlr->v3->n, cent);
-
-               vlr->v1->sticky = (float*) (((int) vlr->v1->sticky) + 1);
-               vlr->v2->sticky = (float*) (((int) vlr->v2->sticky) + 1);
-               vlr->v3->sticky = (float*) (((int) vlr->v3->sticky) + 1);
-       }
-
-       for (i=firstvert; i<R.totvert; i++) {
-               VertRen *ver = RE_findOrAddVert(i);
-
-               VecMulf(ver->n, 1.f/(int) ver->sticky);
-
-               VecLerpf(ver->co, ver->co, ver->n, 0.3);
-               ver->sticky = 0;
-       }
-
-       calc_vertexnormals(firstvert, firstface);
-}
-#endif
-
 /* ------------------------------------------------------------------------- */
 
 static int contrpuntnormr(float *n, float *puno)
@@ -412,6 +370,78 @@ static int contrpuntnormr(float *n, float *puno)
 
 /* ------------------------------------------------------------------------- */
 
+static void calc_edge_stress_add(float *accum, VertRen *v1, VertRen *v2)
+{
+       float len= VecLenf(v1->co, v2->co)/VecLenf(v1->orco, v2->orco);
+       float *acc;
+       
+       acc= accum + 2*v1->index;
+       acc[0]+= len;
+       acc[1]+= 1.0f;
+       
+       acc= accum + 2*v2->index;
+       acc[0]+= len;
+       acc[1]+= 1.0f;
+}
+
+static void calc_edge_stress(Mesh *me, int startvert, int startvlak)
+{
+       float loc[3], size[3], *accum, *acc, *accumoffs, *stress;
+       int a;
+       
+       if(startvert==R.totvert) return;
+       
+       mesh_get_texspace(me, loc, NULL, size);
+       
+       accum= MEM_callocN(2*sizeof(float)*(R.totvert-startvert), "temp accum for stress");
+       
+       /* de-normalize orco */
+       for(a=startvert; a<R.totvert; a++, acc+=2) {
+               VertRen *ver= RE_findOrAddVert(a);
+               if(ver->orco) {
+                       ver->orco[0]= ver->orco[0]*size[0] +loc[0];
+                       ver->orco[1]= ver->orco[1]*size[1] +loc[1];
+                       ver->orco[2]= ver->orco[2]*size[2] +loc[2];
+               }
+       }
+       
+       /* add stress values */
+       accumoffs= accum - 2*startvert; /* so we can use vertex index */
+       for(a=startvlak; a<R.totvlak; a++) {
+               VlakRen *vlr= RE_findOrAddVlak(a);
+
+               if(vlr->v1->orco && vlr->v4) {
+                       calc_edge_stress_add(accumoffs, vlr->v1, vlr->v2);
+                       calc_edge_stress_add(accumoffs, vlr->v2, vlr->v3);
+                       calc_edge_stress_add(accumoffs, vlr->v3, vlr->v1);
+                       if(vlr->v4) {
+                               calc_edge_stress_add(accumoffs, vlr->v3, vlr->v4);
+                               calc_edge_stress_add(accumoffs, vlr->v4, vlr->v1);
+                               calc_edge_stress_add(accumoffs, vlr->v2, vlr->v4);
+                       }
+               }
+       }
+       
+       for(a=startvert; a<R.totvert; a++) {
+               VertRen *ver= RE_findOrAddVert(a);
+               if(ver->orco) {
+                       /* find stress value */
+                       acc= accumoffs + 2*ver->index;
+                       if(acc[1]!=0.0f)
+                               acc[0]/= acc[1];
+                       stress= RE_vertren_get_stress(ver, 1);
+                       *stress= *acc;
+                       
+                       /* restore orcos */
+                       ver->orco[0] = (ver->orco[0]-loc[0])/size[0];
+                       ver->orco[1] = (ver->orco[1]-loc[1])/size[1];
+                       ver->orco[2] = (ver->orco[2]-loc[2])/size[2];
+               }
+       }
+       
+       MEM_freeN(accum);
+}
+
 static void calc_vertexnormals(int startvert, int startvlak)
 {
        int a;
@@ -543,30 +573,21 @@ typedef struct ASface {
        VertRen *nver[4];
 } ASface;
 
-/* prototypes: */
-static int as_testvertex(VlakRen *vlr, VertRen *ver, ASvert *asv, float thresh);
-static VertRen *as_findvertex(VlakRen *vlr, VertRen *ver, ASvert *asv, float thresh);
-
-
-static void as_addvert(VertRen *v1, VlakRen *vlr)
+static void as_addvert(ASvert *asv, VertRen *v1, VlakRen *vlr)
 {
-       ASvert *asv;
        ASface *asf;
        int a;
        
        if(v1 == NULL) return;
        
-       if(v1->svert==0) {
-               v1->svert= MEM_callocN(sizeof(ASvert), "asvert");
-               asv= v1->svert;
+       if(asv->faces.first==NULL) {
                asf= MEM_callocN(sizeof(ASface), "asface");
                BLI_addtail(&asv->faces, asf);
        }
        
-       asv= v1->svert;
        asf= asv->faces.last;
        for(a=0; a<4; a++) {
-               if(asf->vlr[a]==0) {
+               if(asf->vlr[a]==NULL) {
                        asf->vlr[a]= vlr;
                        asv->totface++;
                        break;
@@ -582,16 +603,6 @@ static void as_addvert(VertRen *v1, VlakRen *vlr)
        }
 }
 
-static void as_freevert(VertRen *ver)
-{
-       ASvert *asv;
-
-       asv= ver->svert;
-       BLI_freelistN(&asv->faces);
-       MEM_freeN(asv);
-       ver->svert= NULL;
-}
-
 static int as_testvertex(VlakRen *vlr, VertRen *ver, ASvert *asv, float thresh) 
 {
        /* return 1: vertex needs a copy */
@@ -643,37 +654,35 @@ static VertRen *as_findvertex(VlakRen *vlr, VertRen *ver, ASvert *asv, float thr
 
 static void autosmooth(int startvert, int startvlak, int degr)
 {
-       ASvert *asv;
+       ASvert *asv, *asverts, *asvertoffs;
        ASface *asf;
        VertRen *ver, *v1;
        VlakRen *vlr;
        float thresh;
        int a, b, totvert;
        
-       thresh= cos( M_PI*((float)degr)/180.0 );
+       if(startvert==R.totvert) return;
+       asverts= MEM_callocN(sizeof(ASvert)*(R.totvert-startvert), "all smooth verts");
+       asvertoffs= asverts-startvert;   /* se we can use indices */
        
-       /* initialize */
-       for(a=startvert; a<R.totvert; a++) {
-               ver= RE_findOrAddVert(a);
-               ver->svert= 0;
-       }
+       thresh= cos( M_PI*((float)degr)/180.0 );
        
        /* step one: construct listbase of all vertices and pointers to faces */
        for(a=startvlak; a<R.totvlak; a++) {
                vlr= RE_findOrAddVlak(a);
                
-               as_addvert(vlr->v1, vlr);
-               as_addvert(vlr->v2, vlr);
-               as_addvert(vlr->v3, vlr);
-               as_addvert(vlr->v4, vlr);
+               as_addvert(asvertoffs+vlr->v1->index, vlr->v1, vlr);
+               as_addvert(asvertoffs+vlr->v2->index, vlr->v2, vlr);
+               as_addvert(asvertoffs+vlr->v3->index, vlr->v3, vlr);
+               if(vlr->v4) 
+                       as_addvert(asvertoffs+vlr->v4->index, vlr->v4, vlr);
        }
        
        /* we now test all vertices, when faces have a normal too much different: they get a new vertex */
        totvert= R.totvert;
-       for(a=startvert; a<totvert; a++) {
-               ver= RE_findOrAddVert(a);
-               asv= ver->svert;
+       for(a=startvert, asv=asverts; a<totvert; a++, asv++) {
                if(asv && asv->totface>1) {
+                       ver= RE_findOrAddVert(a);
                        
                        asf= asv->faces.first;
                        while(asf) {
@@ -685,11 +694,9 @@ static void autosmooth(int startvert, int startvlak, int degr)
                                                
                                                /* already made a new vertex within threshold? */
                                                v1= as_findvertex(vlr, ver, asv, thresh);
-                                               if(v1==0) {
+                                               if(v1==NULL) {
                                                        /* make a new vertex */
-                                                       v1= RE_findOrAddVert(R.totvert++);
-                                                       *v1= *ver;
-                                                       v1->svert= 0;
+                                                       v1= RE_duplicate_vertren(ver);
                                                }
                                                asf->nver[b]= v1;
                                                if(vlr->v1==ver) vlr->v1= v1;
@@ -704,11 +711,10 @@ static void autosmooth(int startvert, int startvlak, int degr)
        }
        
        /* free */
-       for(a=startvert; a<R.totvert; a++) {
-               ver= RE_findOrAddVert(a);
-               if(ver->svert) as_freevert(ver);
+       for(a=0; a<totvert-startvert; a++) {
+               BLI_freelistN(&asverts[a].faces);
        }
-       
+       MEM_freeN(asverts);
 }
 
 /* ------------------------------------------------------------------------- */
@@ -1387,7 +1393,7 @@ static void init_render_mesh(Object *ob)
        unsigned int *vertcol;
        float xn, yn, zn,  imat[3][3], mat[4][4];  //nor[3],
        float *orco=0;
-       int a, a1, ok, need_orco=0, totvlako, totverto, vertofs;
+       int a, a1, ok, need_orco=0, need_stress=0, totvlako, totverto, vertofs;
        int end, do_autosmooth=0, totvert = 0, dm_needsfree;
        
        me= ob->data;
@@ -1415,10 +1421,10 @@ static void init_render_mesh(Object *ob)
        for(a=1; a<=ob->totcol; a++) {
                ma= give_render_material(ob, a);
                if(ma) {
-                       if(ma->texco & TEXCO_ORCO) {
+                       if(ma->texco & (TEXCO_ORCO|TEXCO_STRESS))
                                need_orco= 1;
-                               break;
-                       }
+                       if(ma->texco & TEXCO_STRESS)
+                               need_stress= 1;
                }
        }
        
@@ -1460,7 +1466,9 @@ static void init_render_mesh(Object *ob)
                                orco+=3;
                        }
                        if(ms) {
-                               ver->sticky= (float *)ms;
+                               float *sticky= RE_vertren_get_sticky(ver, 1);
+                               sticky[0]= ms->co[0];
+                               sticky[1]= ms->co[1];
                                ms++;
                        }
                }
@@ -1634,6 +1642,9 @@ static void init_render_mesh(Object *ob)
 
        calc_vertexnormals(totverto, totvlako);
 
+       if(need_stress)
+               calc_edge_stress(me, totverto, totvlako);
+       
        if(dlm) displistmesh_free(dlm);
        if(dm_needsfree) dm->release(dm);
 }
@@ -2132,11 +2143,11 @@ static void init_render_curve(Object *ob)
 
                                if(ver->co[2] < 0.0) {
                                        VECCOPY(ver->n, n);
-                                       ver->sticky = (float*) 1;
+                                       ver->flag = 1;
                                }
                                else {
                                        ver->n[0]= -n[0]; ver->n[1]= -n[1]; ver->n[2]= -n[2];
-                                       ver->sticky = (float*) 0;
+                                       ver->flag = 0;
                                }
 
                                if (orco) {
@@ -2156,7 +2167,7 @@ static void init_render_curve(Object *ob)
                                vlr->v3= RE_findOrAddVert(startvert+index[2]);
                                vlr->v4= NULL;
                                
-                               if(vlr->v1->sticky) {
+                               if(vlr->v1->flag) {
                                        VECCOPY(vlr->n, n);
                                }
                                else {
@@ -2255,15 +2266,15 @@ static void init_render_curve(Object *ob)
                        for(a=startvert; a<R.totvert; a++) {
                                ver= RE_findOrAddVert(a);
                                len= Normalise(ver->n);
-                               if(len==0.0) ver->sticky= (float *)1;
-                               else ver->sticky= 0;
+                               if(len==0.0) ver->flag= 1;      /* flag use, its only used in zbuf now  */
+                               else ver->flag= 1;
                        }
                        for(a= startvlak; a<R.totvlak; a++) {
                                vlr= RE_findOrAddVlak(a);
-                               if(vlr->v1->sticky) VECCOPY(vlr->v1->n, vlr->n);
-                               if(vlr->v2->sticky) VECCOPY(vlr->v2->n, vlr->n);
-                               if(vlr->v3->sticky) VECCOPY(vlr->v3->n, vlr->n);
-                               if(vlr->v4->sticky) VECCOPY(vlr->v4->n, vlr->n);
+                               if(vlr->v1->flag) VECCOPY(vlr->v1->n, vlr->n);
+                               if(vlr->v2->flag) VECCOPY(vlr->v2->n, vlr->n);
+                               if(vlr->v3->flag) VECCOPY(vlr->v3->n, vlr->n);
+                               if(vlr->v4->flag) VECCOPY(vlr->v4->n, vlr->n);
                        }
                }
 
@@ -2396,13 +2407,8 @@ void RE_freeRotateBlenderScene(void)
        BLI_freelistN(&R.lights);
 
        /* note; these pointer arrays were allocated, with last element NULL to stop loop */
-       a=0;
-       while(R.blove[a]) {
-               MEM_freeN(R.blove[a]);
-               R.blove[a]= NULL;
-               a++;
-       }
-
+       RE_free_vertex_tables();
+       
        a=0;
        while(R.blovl[a]) {
                MEM_freeN(R.blovl[a]);
@@ -2615,6 +2621,7 @@ void RE_rotateBlenderScene(void)
 
        R.memArena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE);
        R.totvlak=R.totvert=R.totlamp=R.tothalo= 0;
+       R.lights.first= R.lights.last= NULL;
        
        slurph_opt= 0;
 
@@ -2914,8 +2921,13 @@ static void displace_render_vert(ShadeInput *shi, VertRen *vr, float *scale)
        if ((texco & TEXCO_ORCO) && (vr->orco)) {
                VECCOPY(shi->lo, vr->orco);
        }
-       if ((texco & TEXCO_STICKY) && (vr->sticky)) {
-               VECCOPY(shi->sticky, vr->sticky);
+       if (texco & TEXCO_STICKY) {
+               float *sticky= RE_vertren_get_sticky(vr, 0);
+               if(sticky) {
+                       shi->sticky[0]= sticky[0];
+                       shi->sticky[1]= sticky[1];
+                       shi->sticky[2]= 0.0f;
+               }
        }
        if (texco & TEXCO_GLOB) {
                VECCOPY(shi->gl, shi->co);
index d8121fd458ff56cb9d6077a8b27008bfaf6bb345..b697d4cab340737a37867ba6de3c69a2e1848f60 100644 (file)
@@ -2857,11 +2857,12 @@ static void material_panel_map_input(Object *ob, Material *ma)
        /* TEXCO */
        uiBlockBeginAlign(block);
        uiDefButS(block, ROW, B_MATPRV, "UV",                   630,166,40,18, &(mtex->texco), 4.0, (float)TEXCO_UV, 0, 0, "Uses UV coordinates for texture coordinates");
-       uiDefButS(block, ROW, B_MATPRV, "Object",               670,166,75,18, &(mtex->texco), 4.0, (float)TEXCO_OBJECT, 0, 0, "Uses linked object's coordinates for texture coordinates");
-       uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_MATPRV, "",745,166,163,18, &(mtex->object), "");
+       uiDefButS(block, ROW, B_MATPRV, "Glob",                 670,166,45,18, &(mtex->texco), 4.0, (float)TEXCO_GLOB, 0, 0, "Uses global coordinates for the texture coordinates");
+       uiDefButS(block, ROW, B_MATPRV, "Object",               715,166,75,18, &(mtex->texco), 4.0, (float)TEXCO_OBJECT, 0, 0, "Uses linked object's coordinates for texture coordinates");
+       uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_MATPRV, "",790,166,118,18, &(mtex->object), "");
        
-       uiDefButS(block, ROW, B_MATPRV, "Glob",                 630,146,45,18, &(mtex->texco), 4.0, (float)TEXCO_GLOB, 0, 0, "Uses global coordinates for the texture coordinates");
-       uiDefButS(block, ROW, B_MATPRV, "Orco",                 675,146,50,18, &(mtex->texco), 4.0, (float)TEXCO_ORCO, 0, 0, "Uses the original coordinates of the mesh");
+       uiDefButS(block, ROW, B_MATPRV, "Orco",                 630,146,45,18, &(mtex->texco), 4.0, (float)TEXCO_ORCO, 0, 0, "Uses the original undeformed coordinates of the object");
+       uiDefButS(block, ROW, B_MATPRV, "Stress",               675,146,50,18, &(mtex->texco), 4.0, (float)TEXCO_STRESS, 0, 0, "Uses the difference of edge lengths compared to original coordinates of the mesh");
        if( give_parteff(ob) )
                uiDefButS(block, ROW, B_MATPRV, "Strand",       725,146,50,18, &(mtex->texco), 4.0, (float)TEXCO_STRAND, 0, 0, "Uses normalized strand texture coordinate (1D)");
        else