Shape Keys
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Thu, 22 Oct 2009 09:31:07 +0000 (09:31 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Thu, 22 Oct 2009 09:31:07 +0000 (09:31 +0000)
Internal change to not apply the shape keys to the Mesh vertex coordinates,
but rather use it as part of the derivedmesh/displist evaluation. This only
has one practical advantage right now, which is that you can now make a
linked duplicate and pin it's shape key to a different shape than the first
object.

Further, this makes shape keys correctly fit into the modifier stack design,
which will help implement some other features later. Also it means the mesh
vertex coordinates are now really the orco's.

19 files changed:
source/blender/blenkernel/BKE_blender.h
source/blender/blenkernel/BKE_curve.h
source/blender/blenkernel/BKE_key.h
source/blender/blenkernel/BKE_mesh.h
source/blender/blenkernel/intern/DerivedMesh.c
source/blender/blenkernel/intern/curve.c
source/blender/blenkernel/intern/displist.c
source/blender/blenkernel/intern/key.c
source/blender/blenkernel/intern/lattice.c
source/blender/blenkernel/intern/mesh.c
source/blender/blenloader/intern/readfile.c
source/blender/editors/mesh/editmesh.c
source/blender/editors/mesh/meshtools.c
source/blender/editors/object/object_modifier.c
source/blender/editors/object/object_shapekey.c
source/blender/makesrna/intern/rna_object.c
source/gameengine/Converter/BL_ShapeDeformer.cpp
source/gameengine/Converter/BL_SkinDeformer.cpp
source/gameengine/Converter/BL_SkinDeformer.h

index e91e434b97d21c9517bd98541fba0fcd7ddc3ef1..ebeec31c98458b919816b1e5b1ade96e82b6dff8 100644 (file)
@@ -43,7 +43,7 @@ struct bContext;
 struct ReportList;
 
 #define BLENDER_VERSION                        250
-#define BLENDER_SUBVERSION             6
+#define BLENDER_SUBVERSION             7
 
 #define BLENDER_MINVERSION             250
 #define BLENDER_MINSUBVERSION  0
index 78a2f13a7cc7f86fdfc39f1731fb8f203e1427e7..2d1bec09dbfb37bc92b27ce55bde3124f0d4b557 100644 (file)
@@ -92,6 +92,9 @@ void switchdirectionNurb( struct Nurb *nu);
 float (*curve_getVertexCos(struct Curve *cu, struct ListBase *lb, int *numVerts_r))[3];
 void curve_applyVertexCos(struct Curve *cu, struct ListBase *lb, float (*vertexCos)[3]);
 
+float (*curve_getKeyVertexCos(struct Curve *cu, struct ListBase *lb, float *key))[3];
+void curve_applyKeyVertexTilts(struct Curve *cu, struct ListBase *lb, float *key);
+
 /* nurb checks if they can be drawn, also clamp order func */
 int check_valid_nurb_u( struct Nurb *nu);
 int check_valid_nurb_v( struct Nurb *nu);
index 1b4cbc1cf2a6dba0e2bc480e3965b22586f22c14..59d7f99112ecc932e83b634920fcb4fe642984d0 100644 (file)
@@ -56,10 +56,7 @@ void key_curve_position_weights(float t, float *data, int type);
 void key_curve_tangent_weights(float t, float *data, int type);
 void key_curve_normal_weights(float t, float *data, int type);
 
-/* only exported to curve.c! */
-void cp_cu_key(struct Curve *cu, struct KeyBlock *kb, int start, int end);
-
-int do_ob_key(struct Scene *scene, struct Object *ob);
+float *do_ob_key(struct Scene *scene, struct Object *ob);
 
 struct Key *ob_get_key(struct Object *ob);
 struct KeyBlock *ob_get_keyblock(struct Object *ob);
index d2f5e0faa0f905a806942bd151859ae85f03f775..09c1ab9f7d6865b3768fe2667e38bed930a72efb 100644 (file)
@@ -92,7 +92,6 @@ void mesh_calc_normals(struct MVert *mverts, int numVerts, struct MFace *mfaces,
        /* Return a newly MEM_malloc'd array of all the mesh vertex locations
         * (_numVerts_r_ may be NULL) */
 float (*mesh_getVertexCos(struct Mesh *me, int *numVerts_r))[3];
-float (*mesh_getRefKeyCos(struct Mesh *me, int *numVerts_r))[3];
 
 /* map from uv vertex to face (for select linked, stitch, uv suburf) */
 
index a8ea83a45fcaf46f024422aaa7d405cbe42c8cda..59cf786af1e5bb2296e95b79dad22c4512c30b8f 100644 (file)
@@ -1755,8 +1755,8 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
        *final_r = NULL;
 
        if(useDeform) {
-               if(useDeform > 0 && do_ob_key(scene, ob)) /* shape key makes deform verts */
-                       deformedVerts = mesh_getVertexCos(me, &numVerts);
+               if(useDeform > 0)
+                       deformedVerts= (float(*)[3])do_ob_key(scene, ob); /* shape key makes deform verts */
                else if(inputVertexCos)
                        deformedVerts = inputVertexCos;
                
@@ -1800,7 +1800,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
                if(inputVertexCos)
                        deformedVerts = inputVertexCos;
                else
-                       deformedVerts = mesh_getRefKeyCos(me, &numVerts);
+                       deformedVerts = mesh_getVertexCos(me, &numVerts);
        }
 
 
@@ -2031,6 +2031,9 @@ static void editmesh_calc_modifiers(Scene *scene, Object *ob, EditMesh *em, Deri
 
        datamasks = modifiers_calcDataMasks(ob, md, dataMask, required_mode);
 
+       /* doesn't work, shape keys are not updated from editmesh.
+          deformedVerts= (float(*)[3])do_ob_key(scene, ob); */
+
        curr = datamasks;
        for(i = 0; md; i++, md = md->next, curr = curr->next) {
                ModifierTypeInfo *mti = modifierType_getInfo(md->type);
index c0391bb5406d7afeb6c261ef2e95444c939234c6..f31f4cd975385dbef6fb2ef5242fa7d60c48896a 100644 (file)
@@ -1099,8 +1099,7 @@ float *make_orco_curve(Scene *scene, Object *ob)
        float *fp, *coord_array;
        int remakeDisp = 0;
 
-       if (!(cu->flag&CU_UV_ORCO) && cu->key && cu->key->refkey) {
-               cp_cu_key(cu, cu->key->refkey, 0, count_curveverts(&cu->nurb));
+       if (!(cu->flag&CU_UV_ORCO) && cu->key && cu->key->block.first) {
                makeDispListCurveTypes(scene, ob, 1);
                remakeDisp = 1;
        }
@@ -2905,6 +2904,64 @@ void curve_applyVertexCos(Curve *cu, ListBase *lb, float (*vertexCos)[3])
        }
 }
 
+float (*curve_getKeyVertexCos(Curve *cu, ListBase *lb, float *key))[3]
+{
+       int i, numVerts;
+       float *co, (*cos)[3] = MEM_mallocN(sizeof(*cos)*numVerts, "cu_vcos");
+       Nurb *nu;
+
+       co = cos[0];
+       for (nu=lb->first; nu; nu=nu->next) {
+               if (nu->type == CU_BEZIER) {
+                       BezTriple *bezt = nu->bezt;
+
+                       for (i=0; i<nu->pntsu; i++,bezt++) {
+                               VECCOPY(co, key); co+=3; key+=3;
+                               VECCOPY(co, key); co+=3; key+=3;
+                               VECCOPY(co, key); co+=3; key+=3;
+                               key++; /* skip tilt */
+                       }
+               }
+               else {
+                       BPoint *bp = nu->bp;
+
+                       for(i=0; i<nu->pntsu*nu->pntsv; i++,bp++) {
+                               VECCOPY(co, key); co+=3; key+=3;
+                               key++; /* skip tilt */
+                       }
+               }
+       }
+
+       return cos;
+}
+
+void curve_applyKeyVertexTilts(Curve *cu, ListBase *lb, float *key)
+{
+       Nurb *nu;
+       int i;
+
+       for(nu=lb->first; nu; nu=nu->next) {
+               if(nu->type == CU_BEZIER) {
+                       BezTriple *bezt = nu->bezt;
+
+                       for(i=0; i<nu->pntsu; i++,bezt++) {
+                               key+=3*3;
+                               bezt->alfa= *key;
+                               key++;
+                       }
+               }
+               else {
+                       BPoint *bp = nu->bp;
+
+                       for(i=0; i<nu->pntsu*nu->pntsv; i++,bp++) {
+                               key+=3;
+                               bp->alfa= *key;
+                               key++;
+                       }
+               }
+       }
+}
+
 int check_valid_nurb_u( struct Nurb *nu )
 {
        if (nu==NULL)                                           return 0;
index 266a528dc57b03d3ddd0bc0fb14ae424f2d0d3e5..39b07cae2ab276460bfae9ec166738889bcb6b5b 100644 (file)
@@ -1245,6 +1245,7 @@ static void curve_calc_modifiers_pre(Scene *scene, Object *ob, int forRender, fl
        int editmode = (!forRender && cu->editnurb);
        float (*originalVerts)[3] = NULL;
        float (*deformedVerts)[3] = NULL;
+       float *keyVerts= NULL;
        int required_mode;
 
        if(forRender) required_mode = eModifierMode_Render;
@@ -1254,9 +1255,15 @@ static void curve_calc_modifiers_pre(Scene *scene, Object *ob, int forRender, fl
        
        if(editmode) required_mode |= eModifierMode_Editmode;
 
-       if(cu->editnurb==NULL && do_ob_key(scene, ob)) {
-               deformedVerts = curve_getVertexCos(ob->data, nurb, &numVerts);
-               originalVerts = MEM_dupallocN(deformedVerts);
+       if(cu->editnurb==NULL) {
+               keyVerts= do_ob_key(scene, ob);
+
+               if(keyVerts) {
+                       /* split coords from key data, the latter also includes
+                          tilts, which is passed through in the modifier stack */
+                       deformedVerts= curve_getKeyVertexCos(cu, nurb, keyVerts);
+                       originalVerts= MEM_dupallocN(deformedVerts);
+               }
        }
        
        if (preTesselatePoint) {
@@ -1270,7 +1277,7 @@ static void curve_calc_modifiers_pre(Scene *scene, Object *ob, int forRender, fl
                        if (mti->type!=eModifierTypeType_OnlyDeform) continue;
 
                        if (!deformedVerts) {
-                               deformedVerts = curve_getVertexCos(ob->data, nurb, &numVerts);
+                               deformedVerts = curve_getVertexCos(cu, nurb, &numVerts);
                                originalVerts = MEM_dupallocN(deformedVerts);
                        }
                        
@@ -1281,9 +1288,13 @@ static void curve_calc_modifiers_pre(Scene *scene, Object *ob, int forRender, fl
                }
        }
 
-       if (deformedVerts) {
-               curve_applyVertexCos(ob->data, nurb, deformedVerts);
-       }
+       if (deformedVerts)
+               curve_applyVertexCos(cu, nurb, deformedVerts);
+       if (keyVerts) /* these are not passed through modifier stack */
+               curve_applyKeyVertexTilts(cu, nurb, keyVerts);
+       
+       if(keyVerts)
+               MEM_freeN(keyVerts);
 
        *originalVerts_r = originalVerts;
        *deformedVerts_r = deformedVerts;
index 0f0f63a668b163adda15468ba67e8ab1a113fa6d..78b9c04e4d2e34c6a229b1573debc63931ebc37c 100644 (file)
@@ -168,7 +168,7 @@ Key *copy_key(Key *key)
        while(kbn) {
                
                if(kbn->data) kbn->data= MEM_dupallocN(kbn->data);
-               if( kb==key->refkey ) keyn->refkey= kbn;
+               if(kb==key->refkey) keyn->refkey= kbn;
                
                kbn= kbn->next;
                kb= kb->next;
@@ -497,7 +497,34 @@ static void rel_flerp(int aantal, float *in, float *ref, float *out, float fac)
        }
 }
 
-static void cp_key(int start, int end, int tot, char *poin, Key *key, KeyBlock *k, float *weights, int mode)
+static void *key_block_get_data(Key *key, KeyBlock *kb)
+{
+       /* editmode shape key apply test */
+#if 0
+       EditVert *eve;
+       Mesh *me;
+       float (*co)[3];
+       int a;
+
+       if(kb != key->refkey) {
+               if(GS(key->from->name) == ID_ME) {
+                       me= (Mesh*)key->from;
+
+                       if(me->edit_mesh) {
+                               a= 0;
+                               co= kb->data;
+
+                               for(eve=me->edit_mesh->verts.first; eve; eve=eve->next, a++)
+                                       VECCOPY(co[a], eve->co);
+                       }
+               }
+       }
+#endif
+
+       return kb->data;
+}
+
+static void cp_key(int start, int end, int tot, char *poin, Key *key, KeyBlock *kb, float *weights, int mode)
 {
        float ktot = 0.0, kd = 0.0;
        int elemsize, poinsize = 0, a, *ofsp, ofs[32], flagflo=0;
@@ -507,34 +534,33 @@ static void cp_key(int start, int end, int tot, char *poin, Key *key, KeyBlock *
        if(key->from==NULL) return;
 
        if( GS(key->from->name)==ID_ME ) {
-               ofs[0]= sizeof(MVert);
+               ofs[0]= sizeof(float)*3;
                ofs[1]= 0;
                poinsize= ofs[0];
        }
        else if( GS(key->from->name)==ID_LT ) {
-               ofs[0]= sizeof(BPoint);
+               ofs[0]= sizeof(float)*3;
                ofs[1]= 0;
                poinsize= ofs[0];
        }
        else if( GS(key->from->name)==ID_CU ) {
-               if(mode==KEY_BPOINT) ofs[0]= sizeof(BPoint);
-               else ofs[0]= sizeof(BezTriple);
+               if(mode==KEY_BPOINT) ofs[0]= sizeof(float)*4;
+               else ofs[0]= sizeof(float)*10;
                
                ofs[1]= 0;
                poinsize= ofs[0];
        }
 
-
        if(end>tot) end= tot;
        
-       k1= k->data;
-       kref= key->refkey->data;
+       k1= key_block_get_data(key, kb);
+       kref= key_block_get_data(key, key->refkey);
        
-       if(tot != k->totelem) {
+       if(tot != kb->totelem) {
                ktot= 0.0;
                flagflo= 1;
-               if(k->totelem) {
-                       kd= k->totelem/(float)tot;
+               if(kb->totelem) {
+                       kd= kb->totelem/(float)tot;
                }
                else return;
        }
@@ -575,33 +601,24 @@ static void cp_key(int start, int end, int tot, char *poin, Key *key, KeyBlock *
                        
                        switch(cp[1]) {
                        case IPO_FLOAT:
-                               
                                if(weights) {
-                                       memcpy(poin, kref, sizeof(float)*cp[0]);
+                                       memcpy(poin, kref, sizeof(float)*3);
                                        if(*weights!=0.0f)
                                                rel_flerp(cp[0], (float *)poin, (float *)kref, (float *)k1, *weights);
                                        weights++;
                                }
                                else 
-                                       memcpy(poin, k1, sizeof(float)*cp[0]);
-
-                               poin+= ofsp[0];
-
+                                       memcpy(poin, k1, sizeof(float)*3);
                                break;
                        case IPO_BPOINT:
-                               memcpy(poin, k1, 3*sizeof(float));
-                               memcpy(poin+4*sizeof(float), k1+3*sizeof(float), sizeof(float));
-                               
-                               poin+= ofsp[0];                         
-
+                               memcpy(poin, k1, sizeof(float)*4);
                                break;
                        case IPO_BEZTRIPLE:
                                memcpy(poin, k1, sizeof(float)*10);
-                               poin+= ofsp[0]; 
-
                                break;
                        }
                        
+                       poin+= ofsp[0]; 
                        cp+= 2; ofsp++;
                }
                
@@ -623,44 +640,34 @@ static void cp_key(int start, int end, int tot, char *poin, Key *key, KeyBlock *
        }
 }
 
-void cp_cu_key(Curve *cu, KeyBlock *kb, int start, int end)
+static void cp_cu_key(Curve *cu, KeyBlock *kb, int start, int end, char *out, int tot)
 {
        Nurb *nu;
-       int a, step = 0, tot, a1, a2;
        char *poin;
+       int a, step, a1, a2;
 
-       tot= count_curveverts(&cu->nurb);
-       nu= cu->nurb.first;
-       a= 0;
-       while(nu) {
+       for(a=0, nu=cu->nurb.first; nu; nu=nu->next, a+=step) {
                if(nu->bp) {
-                       
                        step= nu->pntsu*nu->pntsv;
                        
                        /* exception because keys prefer to work with complete blocks */
-                       poin= (char *)nu->bp->vec;
-                       poin -= a*sizeof(BPoint);
-                       
+                       poin= out - a*sizeof(float)*4;
                        a1= MAX2(a, start);
                        a2= MIN2(a+step, end);
                        
                        if(a1<a2) cp_key(a1, a2, tot, poin, cu->key, kb, NULL, KEY_BPOINT);
                }
                else if(nu->bezt) {
-                       
                        step= 3*nu->pntsu;
                        
-                       poin= (char *)nu->bezt->vec;
-                       poin -= a*sizeof(BezTriple);
-
+                       poin= out - a*sizeof(float)*10;
                        a1= MAX2(a, start);
                        a2= MIN2(a+step, end);
 
                        if(a1<a2) cp_key(a1, a2, tot, poin, cu->key, kb, NULL, KEY_BEZTRIPLE);
-                       
                }
-               a+= step;
-               nu=nu->next;
+               else
+                       step= 0;
        }
 }
 
@@ -673,19 +680,17 @@ void do_rel_key(int start, int end, int tot, char *basispoin, Key *key, int mode
        
        if(key->from==NULL) return;
        
-       if (G.f & G_DEBUG) printf("do_rel_key() \n");
-       
        if( GS(key->from->name)==ID_ME ) {
-               ofs[0]= sizeof(MVert);
+               ofs[0]= sizeof(float)*3;
                ofs[1]= 0;
        }
        else if( GS(key->from->name)==ID_LT ) {
-               ofs[0]= sizeof(BPoint);
+               ofs[0]= sizeof(float)*3;
                ofs[1]= 0;
        }
        else if( GS(key->from->name)==ID_CU ) {
-               if(mode==KEY_BPOINT) ofs[0]= sizeof(BPoint);
-               else ofs[0]= sizeof(BezTriple);
+               if(mode==KEY_BPOINT) ofs[0]= sizeof(float)*4;
+               else ofs[0]= sizeof(float)*10;
                
                ofs[1]= 0;
        }
@@ -710,21 +715,17 @@ void do_rel_key(int start, int end, int tot, char *basispoin, Key *key, int mode
                if(kb!=key->refkey) {
                        float icuval= kb->curval;
                        
-                       if (G.f & G_DEBUG) printf("\tdo rel key %s : %s = %f \n", key->id.name+2, kb->name, icuval);
-                       
                        /* only with value, and no difference allowed */
                        if(!(kb->flag & KEYBLOCK_MUTE) && icuval!=0.0f && kb->totelem==tot) {
                                KeyBlock *refb;
                                float weight, *weights= kb->weights;
                                
-                               if (G.f & G_DEBUG) printf("\t\tnot skipped \n");
-                               
                                poin= basispoin;
-                               from= kb->data;
+                               from= key_block_get_data(key, kb);
                                /* reference now can be any block */
                                refb= BLI_findlink(&key->block, kb->relative);
                                if(refb==NULL) continue;
-                               reffrom= refb->data;
+                               reffrom= key_block_get_data(key, refb);
                                
                                poin+= start*ofs[0];
                                reffrom+= key->elemsize*start;  // key elemsize yes!
@@ -746,17 +747,13 @@ void do_rel_key(int start, int end, int tot, char *basispoin, Key *key, int mode
                                                
                                                switch(cp[1]) {
                                                case IPO_FLOAT:
-                                                       rel_flerp(cp[0], (float *)poin, (float *)reffrom, (float *)from, weight);
-                                                       
+                                                       rel_flerp(3, (float *)poin, (float *)reffrom, (float *)from, weight);
                                                        break;
                                                case IPO_BPOINT:
-                                                       rel_flerp(3, (float *)poin, (float *)reffrom, (float *)from, icuval);
-                                                       rel_flerp(1, (float *)(poin+16), (float *)(reffrom+16), (float *)(from+16), icuval);
-                       
+                                                       rel_flerp(4, (float *)poin, (float *)reffrom, (float *)from, weight);
                                                        break;
                                                case IPO_BEZTRIPLE:
-                                                       rel_flerp(9, (float *)poin, (float *)reffrom, (float *)from, icuval);
-                       
+                                                       rel_flerp(10, (float *)poin, (float *)reffrom, (float *)from, weight);
                                                        break;
                                                }
                                                
@@ -789,21 +786,19 @@ static void do_key(int start, int end, int tot, char *poin, Key *key, KeyBlock *
 
        if(key->from==0) return;
 
-       if (G.f & G_DEBUG) printf("do_key() \n");
-       
        if( GS(key->from->name)==ID_ME ) {
-               ofs[0]= sizeof(MVert);
+               ofs[0]= sizeof(float)*3;
                ofs[1]= 0;
                poinsize= ofs[0];
        }
        else if( GS(key->from->name)==ID_LT ) {
-               ofs[0]= sizeof(BPoint);
+               ofs[0]= sizeof(float)*3;
                ofs[1]= 0;
                poinsize= ofs[0];
        }
        else if( GS(key->from->name)==ID_CU ) {
-               if(mode==KEY_BPOINT) ofs[0]= sizeof(BPoint);
-               else ofs[0]= sizeof(BezTriple);
+               if(mode==KEY_BPOINT) ofs[0]= sizeof(float)*4;
+               else ofs[0]= sizeof(float)*10;
                
                ofs[1]= 0;
                poinsize= ofs[0];
@@ -811,10 +806,10 @@ static void do_key(int start, int end, int tot, char *poin, Key *key, KeyBlock *
        
        if(end>tot) end= tot;
 
-       k1= k[0]->data;
-       k2= k[1]->data;
-       k3= k[2]->data;
-       k4= k[3]->data;
+       k1= key_block_get_data(key, k[0]);
+       k2= key_block_get_data(key, k[1]);
+       k3= key_block_get_data(key, k[2]);
+       k4= key_block_get_data(key, k[3]);
 
        /*  test for more or less points (per key!) */
        if(tot != k[0]->totelem) {
@@ -922,26 +917,17 @@ static void do_key(int start, int end, int tot, char *poin, Key *key, KeyBlock *
                        
                        switch(cp[1]) {
                        case IPO_FLOAT:
-                               flerp(cp[0], (float *)poin, (float *)k1, (float *)k2, (float *)k3, (float *)k4, t);
-                               poin+= ofsp[0];                         
-
+                               flerp(3, (float *)poin, (float *)k1, (float *)k2, (float *)k3, (float *)k4, t);
                                break;
                        case IPO_BPOINT:
-                               flerp(3, (float *)poin, (float *)k1, (float *)k2, (float *)k3, (float *)k4, t);
-                               flerp(1, (float *)(poin+16), (float *)(k1+12), (float *)(k2+12), (float *)(k3+12), (float *)(k4+12), t);
-                               
-                               poin+= ofsp[0];                         
-
+                               flerp(4, (float *)poin, (float *)k1, (float *)k2, (float *)k3, (float *)k4, t);
                                break;
                        case IPO_BEZTRIPLE:
-                               flerp(9, (void *)poin, (void *)k1, (void *)k2, (void *)k3, (void *)k4, t);
-                               flerp(1, (float *)(poin+36), (float *)(k1+36), (float *)(k2+36), (float *)(k3+36), (float *)(k4+36), t);
-                               poin+= ofsp[0];                         
-
+                               flerp(10, (void *)poin, (void *)k1, (void *)k2, (void *)k3, (void *)k4, t);
                                break;
                        }
                        
-
+                       poin+= ofsp[0];                         
                        cp+= 2;
                        ofsp++;
                }
@@ -1038,41 +1024,30 @@ static float *get_weights_array(Object *ob, char *vgroup)
        return NULL;
 }
 
-static int do_mesh_key(Scene *scene, Object *ob, Mesh *me)
+static void do_mesh_key(Scene *scene, Object *ob, Key *key, char *out, int tot)
 {
        KeyBlock *k[4];
-       float cfra, ctime, t[4], delta, loc[3], size[3];
+       float cfra, ctime, t[4], delta;
        int a, flag = 0, step;
        
-       if(me->totvert==0) return 0;
-       if(me->key==NULL) return 0;
-       if(me->key->block.first==NULL) return 0;
-       
-       /* prevent python from screwing this up? anyhoo, the from pointer could be dropped */
-       me->key->from= (ID *)me;
-       
-       if (G.f & G_DEBUG) printf("do mesh key ob:%s me:%s ke:%s \n", ob->id.name+2, me->id.name+2, me->key->id.name+2);
-       
-       if(me->key->slurph && me->key->type!=KEY_RELATIVE ) {
-               if (G.f & G_DEBUG) printf("\tslurph key\n");
-               
-               delta= me->key->slurph;
-               delta/= me->totvert;
+       if(key->slurph && key->type!=KEY_RELATIVE ) {
+               delta= key->slurph;
+               delta/= tot;
                
                step= 1;
-               if(me->totvert>100 && slurph_opt) {
-                       step= me->totvert/50;
+               if(tot>100 && slurph_opt) {
+                       step= tot/50;
                        delta*= step;
                        /* in do_key and cp_key the case a>tot is handled */
                }
                
                cfra= (float)scene->r.cfra;
                
-               for(a=0; a<me->totvert; a+=step, cfra+= delta) {
+               for(a=0; a<tot; a+=step, cfra+= delta) {
                        
                        ctime= bsystem_time(scene, 0, cfra, 0.0); // xxx  ugly cruft!
 #if 0 // XXX old animation system
-                       if(calc_ipo_spec(me->key->ipo, KEY_SPEED, &ctime)==0) {
+                       if(calc_ipo_spec(key->ipo, KEY_SPEED, &ctime)==0) {
                                ctime /= 100.0;
                                CLAMP(ctime, 0.0, 1.0);
                        }
@@ -1081,42 +1056,33 @@ static int do_mesh_key(Scene *scene, Object *ob, Mesh *me)
                        ctime /= 100.0f;
                        CLAMP(ctime, 0.0f, 1.0f); // XXX for compat, we use this, but this clamping was confusing
                
-                       flag= setkeys(ctime, &me->key->block, k, t, 0);
-                       if(flag==0) {
-                               
-                               do_key(a, a+step, me->totvert, (char *)me->mvert->co, me->key, k, t, 0);
-                       }
-                       else {
-                               cp_key(a, a+step, me->totvert, (char *)me->mvert->co, me->key, k[2], NULL, 0);
-                       }
+                       flag= setkeys(ctime, &key->block, k, t, 0);
+
+                       if(flag==0)
+                               do_key(a, a+step, tot, (char *)out, key, k, t, 0);
+                       else
+                               cp_key(a, a+step, tot, (char *)out, key, k[2], NULL, 0);
                }
-               
-               if(flag && k[2]==me->key->refkey) tex_space_mesh(me);
-               else boundbox_mesh(me, loc, size);
        }
        else {
-               if(me->key->type==KEY_RELATIVE) {
+               if(key->type==KEY_RELATIVE) {
                        KeyBlock *kb;
                        
-                       if (G.f & G_DEBUG) printf("\tdo relative \n");
-                       
-                       for(kb= me->key->block.first; kb; kb= kb->next)
+                       for(kb= key->block.first; kb; kb= kb->next)
                                kb->weights= get_weights_array(ob, kb->vgroup);
 
-                       do_rel_key(0, me->totvert, me->totvert, (char *)me->mvert->co, me->key, 0);
+                       do_rel_key(0, tot, tot, (char *)out, key, 0);
                        
-                       for(kb= me->key->block.first; kb; kb= kb->next) {
+                       for(kb= key->block.first; kb; kb= kb->next) {
                                if(kb->weights) MEM_freeN(kb->weights);
                                kb->weights= NULL;
                        }
                }
                else {
-                       if (G.f & G_DEBUG) printf("\tdo absolute \n");
-                       
                        ctime= bsystem_time(scene, ob, (float)scene->r.cfra, 0.0f); // xxx old cruft
                        
 #if 0 // XXX old animation system
-                       if(calc_ipo_spec(me->key->ipo, KEY_SPEED, &ctime)==0) {
+                       if(calc_ipo_spec(key->ipo, KEY_SPEED, &ctime)==0) {
                                ctime /= 100.0;
                                CLAMP(ctime, 0.0, 1.0);
                        }
@@ -1125,106 +1091,69 @@ static int do_mesh_key(Scene *scene, Object *ob, Mesh *me)
                        ctime /= 100.0f;
                        CLAMP(ctime, 0.0f, 1.0f); // XXX for compat, we use this, but this clamping was confusing
                        
-                       flag= setkeys(ctime, &me->key->block, k, t, 0);
-                       if(flag==0) {
-                               do_key(0, me->totvert, me->totvert, (char *)me->mvert->co, me->key, k, t, 0);
-                       }
-                       else {
-                               cp_key(0, me->totvert, me->totvert, (char *)me->mvert->co, me->key, k[2], NULL, 0);
-                       }
-                       
-                       if(flag && k[2]==me->key->refkey) tex_space_mesh(me);
-                       else boundbox_mesh(me, loc, size);
+                       flag= setkeys(ctime, &key->block, k, t, 0);
+
+                       if(flag==0)
+                               do_key(0, tot, tot, (char *)out, key, k, t, 0);
+                       else
+                               cp_key(0, tot, tot, (char *)out, key, k[2], NULL, 0);
                }
        }
-       return 1;
 }
 
-static void do_cu_key(Curve *cu, KeyBlock **k, float *t)
+static void do_cu_key(Curve *cu, KeyBlock **k, float *t, char *out, int tot)
 {
        Nurb *nu;
-       int a, step = 0, tot;
        char *poin;
+       int a, step;
        
-       tot= count_curveverts(&cu->nurb);
-       nu= cu->nurb.first;
-       a= 0;
-       
-       while(nu) {
+       for(a=0, nu=cu->nurb.first; nu; nu=nu->next, a+=step) {
                if(nu->bp) {
-                       
                        step= nu->pntsu*nu->pntsv;
-                       
-                       /* exception because keys prefer to work with complete blocks */
-                       poin= (char *)nu->bp->vec;
-                       poin -= a*sizeof(BPoint);
-                       
+                       poin= out - a*sizeof(float)*4;
                        do_key(a, a+step, tot, poin, cu->key, k, t, KEY_BPOINT);
                }
                else if(nu->bezt) {
-                       
                        step= 3*nu->pntsu;
-                       
-                       poin= (char *)nu->bezt->vec;
-                       poin -= a*sizeof(BezTriple);
-
+                       poin= out - a*sizeof(float)*10;
                        do_key(a, a+step, tot, poin, cu->key, k, t, KEY_BEZTRIPLE);
-                       
                }
-               a+= step;
-               nu=nu->next;
+               else
+                       step= 0;
        }
 }
 
-static void do_rel_cu_key(Curve *cu, float ctime)
+static void do_rel_cu_key(Curve *cu, float ctime, char *out, int tot)
 {
        Nurb *nu;
-       int a, step = 0, tot;
        char *poin;
+       int a, step;
        
-       tot= count_curveverts(&cu->nurb);
-       nu= cu->nurb.first;
-       a= 0;
-       while(nu) {
+       for(a=0, nu=cu->nurb.first; nu; nu=nu->next, a+=step) {
                if(nu->bp) {
-                       
                        step= nu->pntsu*nu->pntsv;
-                       
-                       /* exception because keys prefer to work with complete blocks */
-                       poin= (char *)nu->bp->vec;
-                       poin -= a*sizeof(BPoint);
-                       
-                       do_rel_key(a, a+step, tot, poin, cu->key, KEY_BPOINT);
+                       poin= out - a*sizeof(float)*3;
+                       do_rel_key(a, a+step, tot, out, cu->key, KEY_BPOINT);
                }
                else if(nu->bezt) {
-                       
                        step= 3*nu->pntsu;
-                       
-                       poin= (char *)nu->bezt->vec;
-                       poin -= a*sizeof(BezTriple);
-
+                       poin= out - a*sizeof(float)*10;
                        do_rel_key(a, a+step, tot, poin, cu->key, KEY_BEZTRIPLE);
                }
-               a+= step;
-               
-               nu=nu->next;
+               else
+                       step= 0;
        }
 }
 
-static int do_curve_key(Scene *scene, Curve *cu)
+static void do_curve_key(Scene *scene, Object *ob, Key *key, char *out, int tot)
 {
+       Curve *cu= ob->data;
        KeyBlock *k[4];
        float cfra, ctime, t[4], delta;
-       int a, flag = 0, step = 0, tot;
-       
-       tot= count_curveverts(&cu->nurb);
-       
-       if(tot==0) return 0;
-       if(cu->key==NULL) return 0;
-       if(cu->key->block.first==NULL) return 0;
+       int a, flag = 0, step = 0;
        
-       if(cu->key->slurph) {
-               delta= cu->key->slurph;
+       if(key->slurph) {
+               delta= key->slurph;
                delta/= tot;
                
                step= 1;
@@ -1239,66 +1168,52 @@ static int do_curve_key(Scene *scene, Curve *cu)
                for(a=0; a<tot; a+=step, cfra+= delta) {
                        ctime= bsystem_time(scene, 0, cfra, 0.0f); // XXX old cruft
 #if 0 // XXX old animation system
-                       if(calc_ipo_spec(cu->key->ipo, KEY_SPEED, &ctime)==0) {
+                       if(calc_ipo_spec(key->ipo, KEY_SPEED, &ctime)==0) {
                                ctime /= 100.0;
                                CLAMP(ctime, 0.0, 1.0);
                        }
 #endif // XXX old animation system
                
-                       flag= setkeys(ctime, &cu->key->block, k, t, 0);
-                       if(flag==0) {
-                               
-                               /* do_key(a, a+step, tot, (char *)cu->mvert->co, cu->key, k, t, 0); */
-                       }
-                       else {
-                               /* cp_key(a, a+step, tot, (char *)cu->mvert->co, cu->key, k[2],0); */
-                       }
-               }
+                       flag= setkeys(ctime, &key->block, k, t, 0);
 
-               if(flag && k[2]==cu->key->refkey) tex_space_curve(cu);
-               
-               
+                       if(flag==0)
+                               ; /* do_key(a, a+step, tot, (char *)out, key, k, t, 0); */
+                       else
+                               ; /* cp_key(a, a+step, tot, (char *)out, key, k[2],0); */
+               }
        }
        else {
                
                ctime= bsystem_time(scene, NULL, (float)scene->r.cfra, 0.0);
                
-               if(cu->key->type==KEY_RELATIVE) {
-                       do_rel_cu_key(cu, ctime);
+               if(key->type==KEY_RELATIVE) {
+                       do_rel_cu_key(cu, ctime, out, tot);
                }
                else {
 #if 0 // XXX old animation system
-                       if(calc_ipo_spec(cu->key->ipo, KEY_SPEED, &ctime)==0) {
+                       if(calc_ipo_spec(key->ipo, KEY_SPEED, &ctime)==0) {
                                ctime /= 100.0;
                                CLAMP(ctime, 0.0, 1.0);
                        }
 #endif // XXX old animation system
                        
-                       flag= setkeys(ctime, &cu->key->block, k, t, 0);
+                       flag= setkeys(ctime, &key->block, k, t, 0);
                        
-                       if(flag==0) do_cu_key(cu, k, t);
-                       else cp_cu_key(cu, k[2], 0, tot);
-                                       
-                       if(flag && k[2]==cu->key->refkey) tex_space_curve(cu);
+                       if(flag==0) do_cu_key(cu, k, t, out, tot);
+                       else cp_cu_key(cu, k[2], 0, tot, out, tot);
                }
        }
-       
-       return 1;
 }
 
-static int do_latt_key(Scene *scene, Object *ob, Lattice *lt)
+static void do_latt_key(Scene *scene, Object *ob, Key *key, char *out, int tot)
 {
+       Lattice *lt= ob->data;
        KeyBlock *k[4];
        float delta, cfra, ctime, t[4];
-       int a, tot, flag;
+       int a, flag;
        
-       if(lt->key==NULL) return 0;
-       if(lt->key->block.first==NULL) return 0;
-
-       tot= lt->pntsu*lt->pntsv*lt->pntsw;
-
-       if(lt->key->slurph) {
-               delta= lt->key->slurph;
+       if(key->slurph) {
+               delta= key->slurph;
                delta/= (float)tot;
                
                cfra= (float)scene->r.cfra;
@@ -1307,74 +1222,109 @@ static int do_latt_key(Scene *scene, Object *ob, Lattice *lt)
                        
                        ctime= bsystem_time(scene, 0, cfra, 0.0); // XXX old cruft
 #if 0 // XXX old animation system
-                       if(calc_ipo_spec(lt->key->ipo, KEY_SPEED, &ctime)==0) {
+                       if(calc_ipo_spec(key->ipo, KEY_SPEED, &ctime)==0) {
                                ctime /= 100.0;
                                CLAMP(ctime, 0.0, 1.0);
                        }
 #endif // XXX old animation system
                
-                       flag= setkeys(ctime, &lt->key->block, k, t, 0);
-                       if(flag==0) {
-                               
-                               do_key(a, a+1, tot, (char *)lt->def->vec, lt->key, k, t, 0);
-                       }
-                       else {
-                               cp_key(a, a+1, tot, (char *)lt->def->vec, lt->key, k[2], NULL, 0);
-                       }
+                       flag= setkeys(ctime, &key->block, k, t, 0);
+
+                       if(flag==0)
+                               do_key(a, a+1, tot, (char *)out, key, k, t, 0);
+                       else
+                               cp_key(a, a+1, tot, (char *)out, key, k[2], NULL, 0);
                }               
        }
        else {
-               ctime= bsystem_time(scene, NULL, (float)scene->r.cfra, 0.0);
-       
-               if(lt->key->type==KEY_RELATIVE) {
+               if(key->type==KEY_RELATIVE) {
                        KeyBlock *kb;
                        
-                       for(kb= lt->key->block.first; kb; kb= kb->next)
+                       for(kb= key->block.first; kb; kb= kb->next)
                                kb->weights= get_weights_array(ob, kb->vgroup);
                        
-                       do_rel_key(0, tot, tot, (char *)lt->def->vec, lt->key, 0);
+                       do_rel_key(0, tot, tot, (char *)out, key, 0);
                        
-                       for(kb= lt->key->block.first; kb; kb= kb->next) {
+                       for(kb= key->block.first; kb; kb= kb->next) {
                                if(kb->weights) MEM_freeN(kb->weights);
                                kb->weights= NULL;
                        }
                }
                else {
+                       ctime= bsystem_time(scene, NULL, (float)scene->r.cfra, 0.0);
+
 #if 0 // XXX old animation system
-                       if(calc_ipo_spec(lt->key->ipo, KEY_SPEED, &ctime)==0) {
+                       if(calc_ipo_spec(key->ipo, KEY_SPEED, &ctime)==0) {
                                ctime /= 100.0;
                                CLAMP(ctime, 0.0, 1.0);
                        }
 #endif // XXX old animation system
                        
-                       flag= setkeys(ctime, &lt->key->block, k, t, 0);
-                       if(flag==0) {
-                               do_key(0, tot, tot, (char *)lt->def->vec, lt->key, k, t, 0);
-                       }
-                       else {
-                               cp_key(0, tot, tot, (char *)lt->def->vec, lt->key, k[2], NULL, 0);
-                       }
+                       flag= setkeys(ctime, &key->block, k, t, 0);
+
+                       if(flag==0)
+                               do_key(0, tot, tot, (char *)out, key, k, t, 0);
+                       else
+                               cp_key(0, tot, tot, (char *)out, key, k[2], NULL, 0);
                }
        }
        
        if(lt->flag & LT_OUTSIDE) outside_lattice(lt);
-       
-       return 1;
 }
 
-/* returns 1 when key applied */
-int do_ob_key(Scene *scene, Object *ob)
+/* returns key coordinates (+ tilt) when key applied, NULL otherwise */
+float *do_ob_key(Scene *scene, Object *ob)
 {
        Key *key= ob_get_key(ob);
+       char *out;
+       int tot= 0, size= 0;
+       
+       if(key==NULL || key->block.first==NULL)
+               return NULL;
+
+       /* compute size of output array */
+       if(ob->type == OB_MESH) {
+               Mesh *me= ob->data;
+
+               tot= me->totvert;
+               size= tot*3*sizeof(float);
+       }
+       else if(ob->type == OB_LATTICE) {
+               Lattice *lt= ob->data;
+
+               tot= lt->pntsu*lt->pntsv*lt->pntsw;
+               size= tot*3*sizeof(float);
+       }
+       else if(ELEM(ob->type, OB_CURVE, OB_SURF)) {
+               Curve *cu= ob->data;
+               Nurb *nu;
+
+               for(nu=cu->nurb.first; nu; nu=nu->next) {
+                       if(nu->bezt) {
+                               tot += 3*nu->pntsu;
+                               size += nu->pntsu*10*sizeof(float);
+                       }
+                       else if(nu->bp) {
+                               tot += nu->pntsu*nu->pntsv;
+                               size += nu->pntsu*nu->pntsv*10*sizeof(float);
+                       }
+               }
+       }
+
+       /* if nothing to interpolate, cancel */
+       if(tot == 0 || size == 0)
+               return NULL;
        
-       if(key==NULL)
-               return 0;
+       /* allocate array */
+       out= MEM_callocN(size, "do_ob_key out");
+
+       /* prevent python from screwing this up? anyhoo, the from pointer could be dropped */
+       key->from= (ID *)ob->data;
                
        if(ob->shapeflag & OB_SHAPE_LOCK) {
+               /* shape locked, copy the locked shape instead of blending */
                KeyBlock *kb= BLI_findlink(&key->block, ob->shapenr-1);
                
-               if (G.f & G_DEBUG) printf("ob %s, key %s locked \n", ob->id.name+2, key->id.name+2);
-               
                if(kb && (kb->flag & KEYBLOCK_MUTE))
                        kb= key->refkey;
 
@@ -1383,46 +1333,29 @@ int do_ob_key(Scene *scene, Object *ob)
                        ob->shapenr= 1;
                }
                
-               if(ob->type==OB_MESH) {
-                       Mesh *me= ob->data;
+               if(ELEM(ob->type, OB_MESH, OB_LATTICE)) {
                        float *weights= get_weights_array(ob, kb->vgroup);
 
-                       cp_key(0, me->totvert, me->totvert, (char *)me->mvert->co, key, kb, weights, 0);
-                       
-                       if(weights) MEM_freeN(weights);
-               }
-               else if(ob->type==OB_LATTICE) {
-                       Lattice *lt= ob->data;
-                       float *weights= get_weights_array(ob, kb->vgroup);
-                       int tot= lt->pntsu*lt->pntsv*lt->pntsw;
-                       
-                       cp_key(0, tot, tot, (char *)lt->def->vec, key, kb, weights, 0);
-                       
+                       cp_key(0, tot, tot, (char*)out, key, kb, weights, 0);
+
                        if(weights) MEM_freeN(weights);
                }
-               else if ELEM(ob->type, OB_CURVE, OB_SURF) {
-                       Curve *cu= ob->data;
-                       int tot= count_curveverts(&cu->nurb);
-                       
-                       cp_cu_key(cu, kb, 0, tot);
-               }
-               return 1;
+               else if(ELEM(ob->type, OB_CURVE, OB_SURF))
+                       cp_cu_key(ob->data, kb, 0, tot, out, tot);
        }
        else {
                /* do shapekey local drivers */
                float ctime= (float)scene->r.cfra; // XXX this needs to be checked
                
-               if (G.f & G_DEBUG) 
-                       printf("ob %s - do shapekey (%s) drivers \n", ob->id.name+2, key->id.name+2);
                BKE_animsys_evaluate_animdata(&key->id, key->adt, ctime, ADT_RECALC_DRIVERS);
                
-               if(ob->type==OB_MESH) return do_mesh_key(scene, ob, ob->data);
-               else if(ob->type==OB_CURVE) return do_curve_key(scene, ob->data);
-               else if(ob->type==OB_SURF) return do_curve_key(scene, ob->data);
-               else if(ob->type==OB_LATTICE) return do_latt_key(scene, ob, ob->data);
+               if(ob->type==OB_MESH) do_mesh_key(scene, ob, key, out, tot);
+               else if(ob->type==OB_LATTICE) do_latt_key(scene, ob, key, out, tot);
+               else if(ob->type==OB_CURVE) do_curve_key(scene, ob, key, out, tot);
+               else if(ob->type==OB_SURF) do_curve_key(scene, ob, key, out, tot);
        }
        
-       return 0;
+       return (float*)out;
 }
 
 Key *ob_get_key(Object *ob)
index a957be4704c20888dfdd61e037775f0352fe47ac..128d3229a3cfddd3f664bedd69ff25cee04ae86c 100644 (file)
@@ -995,9 +995,8 @@ void lattice_calc_modifiers(Scene *scene, Object *ob)
 
        freedisplist(&ob->disp);
 
-       if (!editmode) {
-               do_ob_key(scene, ob);
-       }
+       if (!editmode)
+               vertexCos= (float(*)[3])do_ob_key(scene, ob);
 
        for (; md; md=md->next) {
                ModifierTypeInfo *mti = modifierType_getInfo(md->type);
index 0065c348ad00a643849ebe3c22ddf34ef7468aca..6ef557ca8796c1e557c092652de11719c757572c 100644 (file)
@@ -362,35 +362,12 @@ void boundbox_mesh(Mesh *me, float *loc, float *size)
 
 void tex_space_mesh(Mesh *me)
 {
-       KeyBlock *kb;
-       float *fp, loc[3], size[3], min[3], max[3];
+       float loc[3], size[3];
        int a;
 
        boundbox_mesh(me, loc, size);
 
        if(me->texflag & AUTOSPACE) {
-               if(me->key) {
-                       kb= me->key->refkey;
-                       if (kb) {
-                               
-                               INIT_MINMAX(min, max);
-                               
-                               fp= kb->data;
-                               for(a=0; a<kb->totelem; a++, fp+=3) {   
-                                       DO_MINMAX(fp, min, max);
-                               }
-                               if(kb->totelem) {
-                                       loc[0]= (min[0]+max[0])/2.0f; loc[1]= (min[1]+max[1])/2.0f; loc[2]= (min[2]+max[2])/2.0f;
-                                       size[0]= (max[0]-min[0])/2.0f; size[1]= (max[1]-min[1])/2.0f; size[2]= (max[2]-min[2])/2.0f;
-                               }
-                               else {
-                                       loc[0]= loc[1]= loc[2]= 0.0;
-                                       size[0]= size[1]= size[2]= 0.0;
-                               }
-                               
-                       }
-               }
-
                for (a=0; a<3; a++) {
                        if(size[a]==0.0) size[a]= 1.0;
                        else if(size[a]>0.0 && size[a]<0.00001) size[a]= 0.00001;
@@ -430,26 +407,20 @@ void mesh_get_texspace(Mesh *me, float *loc_r, float *rot_r, float *size_r)
 float *get_mesh_orco_verts(Object *ob)
 {
        Mesh *me = ob->data;
+       MVert *mvert = NULL;
+       Mesh *tme = me->texcomesh?me->texcomesh:me;
        int a, totvert;
        float (*vcos)[3] = NULL;
 
        /* Get appropriate vertex coordinates */
-       if(me->key && me->texcomesh==0 && me->key->refkey) {
-               vcos= mesh_getRefKeyCos(me, &totvert);
-       }
-       else {
-               MVert *mvert = NULL;            
-               Mesh *tme = me->texcomesh?me->texcomesh:me;
-
-               vcos = MEM_callocN(sizeof(*vcos)*me->totvert, "orco mesh");
-               mvert = tme->mvert;
-               totvert = MIN2(tme->totvert, me->totvert);
-
-               for(a=0; a<totvert; a++, mvert++) {
-                       vcos[a][0]= mvert->co[0];
-                       vcos[a][1]= mvert->co[1];
-                       vcos[a][2]= mvert->co[2];
-               }
+       vcos = MEM_callocN(sizeof(*vcos)*me->totvert, "orco mesh");
+       mvert = tme->mvert;
+       totvert = MIN2(tme->totvert, me->totvert);
+
+       for(a=0; a<totvert; a++, mvert++) {
+               vcos[a][0]= mvert->co[0];
+               vcos[a][1]= mvert->co[1];
+               vcos[a][2]= mvert->co[2];
        }
 
        return (float*)vcos;
@@ -1220,29 +1191,6 @@ float (*mesh_getVertexCos(Mesh *me, int *numVerts_r))[3]
        return cos;
 }
 
-float (*mesh_getRefKeyCos(Mesh *me, int *numVerts_r))[3]
-{
-       KeyBlock *kb;
-       float (*cos)[3] = NULL;
-       int totvert;
-       
-       if(me->key && me->key->refkey) {
-               if(numVerts_r) *numVerts_r= me->totvert;
-               
-               kb= me->key->refkey;
-               
-               /* prevent accessing invalid memory */
-               if (me->totvert > kb->totelem)          cos= MEM_callocN(sizeof(*cos)*me->totvert, "vertexcos1");
-               else                                                            cos= MEM_mallocN(sizeof(*cos)*me->totvert, "vertexcos1");
-               
-               totvert= MIN2(kb->totelem, me->totvert);
-
-               memcpy(cos, kb->data, sizeof(*cos)*totvert);
-       }
-
-       return cos;
-}
-
 UvVertMap *make_uv_vert_map(struct MFace *mface, struct MTFace *tface, unsigned int totface, unsigned int totvert, int selected, float *limit)
 {
        UvVertMap *vmap;
index 6f9a41893e359756eca1308946db7aa42fe67fbb..658e238e81d6db0de6715ca90de3fbe4024c1daa 100644 (file)
@@ -9924,7 +9924,6 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                }
        }
 
-       /* put 2.50 compatibility code here until next subversion bump */
        if (main->versionfile < 250 || (main->versionfile == 250 && main->subversionfile < 6)) {
                Object *ob;
                Lamp *la;
@@ -9950,6 +9949,71 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                        la->compressthresh= 0.05f;
        }
 
+       if (main->versionfile < 250 || (main->versionfile == 250 && main->subversionfile < 7)) {
+               Mesh *me;
+               Nurb *nu;
+               Lattice *lt;
+               Curve *cu;
+               Key *key;
+               float *data;
+               int a, tot;
+
+               /* shape keys are no longer applied to the mesh itself, but rather
+                  to the derivedmesh/displist, so here we ensure that the basis
+                  shape key is always set in the mesh coordinates. */
+
+               for(me= main->mesh.first; me; me= me->id.next) {
+                       if((key = newlibadr(fd, lib, me->key)) && key->refkey) {
+                               data= key->refkey->data;
+                               tot= MIN2(me->totvert, key->refkey->totelem);
+
+                               for(a=0; a<tot; a++, data+=3)
+                                       VECCOPY(me->mvert[a].co, data)
+                       }
+               }
+
+               for(lt= main->latt.first; lt; lt= lt->id.next) {
+                       if((key = newlibadr(fd, lib, lt->key)) && key->refkey) {
+                               data= key->refkey->data;
+                               tot= MIN2(lt->pntsu*lt->pntsv*lt->pntsw, key->refkey->totelem);
+
+                               for(a=0; a<tot; a++, data+=3)
+                                       VECCOPY(lt->def[a].vec, data)
+                       }
+               }
+
+               for(cu= main->curve.first; cu; cu= cu->id.next) {
+                       if((key = newlibadr(fd, lib, cu->key)) && key->refkey) {
+                               data= key->refkey->data;
+
+                               for(nu=cu->nurb.first; nu; nu=nu->next) {
+                                       if(nu->bezt) {
+                                               BezTriple *bezt = nu->bezt;
+
+                                               for(a=0; a<nu->pntsu; a++, bezt++) {
+                                                       VECCOPY(bezt->vec[0], data); data+=3;
+                                                       VECCOPY(bezt->vec[1], data); data+=3;
+                                                       VECCOPY(bezt->vec[2], data); data+=3;
+                                                       bezt->alfa= *data; data++;
+                                               }
+                                       }
+                                       else if(nu->bp) {
+                                               BPoint *bp = nu->bp;
+
+                                               for(a=0; a<nu->pntsu*nu->pntsv; a++, bp++) {
+                                                       VECCOPY(bp->vec, data); data+=3;
+                                                       bp->alfa= *data; data++;
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+
+       /* put 2.50 compatibility code here until next subversion bump */
+       {
+       }
+
        /* WATCH IT!!!: pointers from libdata have not been converted yet here! */
        /* WATCH IT 2!: Userdef struct init has to be in src/usiblender.c! */
 
index b0c5113104138113e9ebd2836ab8d087e5a7382c..408c793751be143a95c20efe3f3e52e02dc67be0 100644 (file)
@@ -756,7 +756,7 @@ void make_editMesh(Scene *scene, Object *ob)
        EditFace *efa;
        EditEdge *eed;
        EditSelection *ese;
-       float *co;
+       float *co, (*keyco)[3]= NULL;
        int tot, a, eekadoodle= 0;
 
        if(me->edit_mesh==NULL)
@@ -782,9 +782,9 @@ void make_editMesh(Scene *scene, Object *ob)
 
        actkey = ob_get_keyblock(ob);
        if(actkey) {
-               tot= actkey->totelem;
                /* undo-ing in past for previous editmode sessions gives corrupt 'keyindex' values */
                undo_editmode_clear();
+               keyco= actkey->data;
        }
 
        /* make editverts */
@@ -797,8 +797,8 @@ void make_editMesh(Scene *scene, Object *ob)
                co= mvert->co;
 
                /* edit the shape key coordinate if available */
-               if(actkey && a < actkey->totelem)
-                       co= (float*)actkey->data + 3*a;
+               if(keyco && a < actkey->totelem)
+                       co= keyco[a];
 
                eve= addvertlist(em, co, NULL);
                evlist[a]= eve;
@@ -1201,7 +1201,7 @@ void load_editMesh(Scene *scene, Object *ob)
                        while(eve) {
                                if (eve->keyindex >= 0 && eve->keyindex < currkey->totelem) { // valid old vertex
                                        if(currkey == actkey) {
-                                               if (actkey == me->key->refkey) {
+                                               if(actkey == me->key->refkey) {
                                                        VECCOPY(fp, mvert->co);
                                                }
                                                else {
index fad73e19e16f05a71d88e5820029b563d0d21e7f..8bd8629a5952430ef72d191398e2ddebabf88cfc 100644 (file)
@@ -795,7 +795,7 @@ static void mesh_octree_add_nodes(MocNode **basetable, float *co, float *offs, f
        
 }
 
-static intptr_t mesh_octree_find_index(MocNode **bt, float (*orco)[3], MVert *mvert, float *co)
+static intptr_t mesh_octree_find_index(MocNode **bt, MVert *mvert, float *co)
 {
        float *vec;
        int a;
@@ -806,12 +806,7 @@ static intptr_t mesh_octree_find_index(MocNode **bt, float (*orco)[3], MVert *mv
        for(a=0; a<MOC_NODE_RES; a++) {
                if((*bt)->index[a]) {
                        /* does mesh verts and editmode, code looks potential dangerous, octree should really be filled OK! */
-                       if(orco) {
-                               vec= orco[(*bt)->index[a]-1];
-                               if(FloatCompare(vec, co, MOC_THRESH))
-                                       return (*bt)->index[a]-1;
-                       }
-                       else if(mvert) {
+                       if(mvert) {
                                vec= (mvert+(*bt)->index[a]-1)->co;
                                if(FloatCompare(vec, co, MOC_THRESH))
                                        return (*bt)->index[a]-1;
@@ -825,7 +820,7 @@ static intptr_t mesh_octree_find_index(MocNode **bt, float (*orco)[3], MVert *mv
                else return -1;
        }
        if( (*bt)->next)
-               return mesh_octree_find_index(&(*bt)->next, orco, mvert, co);
+               return mesh_octree_find_index(&(*bt)->next, mvert, co);
        
        return -1;
 }
@@ -833,9 +828,7 @@ static intptr_t mesh_octree_find_index(MocNode **bt, float (*orco)[3], MVert *mv
 static struct {
        MocNode **table;
        float offs[3], div[3];
-       float (*orco)[3];
-       float orcoloc[3];
-} MeshOctree = {NULL, {0, 0, 0}, {0, 0, 0}, NULL};
+} MeshOctree = {NULL, {0, 0, 0}, {0, 0, 0}};
 
 /* mode is 's' start, or 'e' end, or 'u' use */
 /* if end, ob can be NULL */
@@ -851,9 +844,9 @@ intptr_t mesh_octree_table(Object *ob, EditMesh *em, float *co, char mode)
                        Mesh *me= ob->data;
                        bt= MeshOctree.table + mesh_octree_get_base_offs(co, MeshOctree.offs, MeshOctree.div);
                        if(em)
-                               return mesh_octree_find_index(bt, NULL, NULL, co);
+                               return mesh_octree_find_index(bt, NULL, co);
                        else
-                               return mesh_octree_find_index(bt, MeshOctree.orco, me->mvert, co);
+                               return mesh_octree_find_index(bt, me->mvert, co);
                }
                return -1;
        }
@@ -873,16 +866,10 @@ intptr_t mesh_octree_table(Object *ob, EditMesh *em, float *co, char mode)
                }
                else {          
                        MVert *mvert;
-                       float *vco;
-                       int a, totvert;
-                       
-                       MeshOctree.orco= mesh_getRefKeyCos(me, &totvert);
-                       mesh_get_texspace(me, MeshOctree.orcoloc, NULL, NULL);
+                       int a;
                        
-                       for(a=0, mvert= me->mvert; a<me->totvert; a++, mvert++) {
-                               vco= (MeshOctree.orco)? MeshOctree.orco[a]: mvert->co;
-                               DO_MINMAX(vco, min, max);
-                       }
+                       for(a=0, mvert= me->mvert; a<me->totvert; a++, mvert++)
+                               DO_MINMAX(mvert->co, min, max);
                }
                
                /* for quick unit coordinate calculus */
@@ -915,13 +902,10 @@ intptr_t mesh_octree_table(Object *ob, EditMesh *em, float *co, char mode)
                }
                else {          
                        MVert *mvert;
-                       float *vco;
                        int a;
                        
-                       for(a=0, mvert= me->mvert; a<me->totvert; a++, mvert++) {
-                               vco= (MeshOctree.orco)? MeshOctree.orco[a]: mvert->co;
-                               mesh_octree_add_nodes(MeshOctree.table, vco, MeshOctree.offs, MeshOctree.div, a+1);
-                       }
+                       for(a=0, mvert= me->mvert; a<me->totvert; a++, mvert++)
+                               mesh_octree_add_nodes(MeshOctree.table, mvert->co, MeshOctree.offs, MeshOctree.div, a+1);
                }
        }
        else if(mode=='e') { /* end table */
@@ -934,10 +918,6 @@ intptr_t mesh_octree_table(Object *ob, EditMesh *em, float *co, char mode)
                        MEM_freeN(MeshOctree.table);
                        MeshOctree.table= NULL;
                }
-               if(MeshOctree.orco) {
-                       MEM_freeN(MeshOctree.orco);
-                       MeshOctree.orco= NULL;
-               }
        }
        return 0;
 }
@@ -948,19 +928,10 @@ int mesh_get_x_mirror_vert(Object *ob, int index)
        MVert *mvert;
        float vec[3];
        
-       if(MeshOctree.orco) {
-               float *loc= MeshOctree.orcoloc;
-
-               vec[0]= -(MeshOctree.orco[index][0] + loc[0]) - loc[0];
-               vec[1]= MeshOctree.orco[index][1];
-               vec[2]= MeshOctree.orco[index][2];
-       }
-       else {
-               mvert= me->mvert+index;
-               vec[0]= -mvert->co[0];
-               vec[1]= mvert->co[1];
-               vec[2]= mvert->co[2];
-       }
+       mvert= me->mvert+index;
+       vec[0]= -mvert->co[0];
+       vec[1]= mvert->co[1];
+       vec[2]= mvert->co[2];
        
        return mesh_octree_table(ob, NULL, vec, 'u');
 }
index f58e8cfeb9dbfa6e71ed5acb08c49ea119742645..1b0dc95480ac42c03e511d2de2517ea3ebadea55 100644 (file)
@@ -349,10 +349,10 @@ int ED_object_modifier_apply(ReportList *reports, Scene *scene, Object *ob, Modi
        
                mesh_pmv_off(ob, me);
 
-               /* Multires: ensure that recent sculpting is applied */
-               if(md->type == eModifierType_Multires)
-                       multires_force_update(ob);
-       
+          /* Multires: ensure that recent sculpting is applied */
+          if(md->type == eModifierType_Multires)
+                          multires_force_update(ob);
+
                dm = mesh_create_derived_for_modifier(scene, ob, md);
                if (!dm) {
                        BKE_report(reports, RPT_ERROR, "Modifier is disabled or returned error, skipping apply");
index 53970596f55f162e0381912d5a055ffddb9acc62..5f3d73ec34880a25df48f9d445cc1f6b33f600f7 100644 (file)
@@ -383,6 +383,7 @@ void insert_curvekey(Scene *scene, Curve *cu, short rel)
 {
        Key *key;
        KeyBlock *kb;
+       ListBase *lb= (cu->editnurb)? cu->editnurb: &cu->nurb;
        
        if(cu->key==NULL) {
                cu->key= add_key( (ID *)cu);
@@ -396,8 +397,7 @@ void insert_curvekey(Scene *scene, Curve *cu, short rel)
        
        kb= add_keyblock(scene, key);
        
-       if(cu->editnurb->first) curve_to_key(cu, kb, cu->editnurb);
-       else curve_to_key(cu, kb, &cu->nurb);
+       curve_to_key(cu, kb, lb);
 }
 
 /*********************** add shape key ***********************/
@@ -634,7 +634,6 @@ void OBJECT_OT_shape_key_clear(wmOperatorType *ot)
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 }
 
-
 static int shape_key_mirror_exec(bContext *C, wmOperator *op)
 {
        Scene *scene= CTX_data_scene(C);
index 834cea93864de0be43947c2e2f0ec219e449a1ce..3fb132b24fd63f063c3744bc17db5bd86fc98e67 100644 (file)
@@ -759,14 +759,6 @@ static PointerRNA rna_Object_active_shape_key_get(PointerRNA *ptr)
        return keyptr;
 }
 
-static void rna_Object_shape_key_lock_set(PointerRNA *ptr, int value)
-{
-       Object *ob= (Object*)ptr->id.data;
-
-       if(value) ob->shapeflag |= OB_SHAPE_LOCK;
-       else ob->shapeflag &= ~OB_SHAPE_LOCK;
-}
-
 static PointerRNA rna_Object_field_get(PointerRNA *ptr)
 {
        Object *ob= (Object*)ptr->id.data;
@@ -1646,7 +1638,6 @@ static void rna_def_object(BlenderRNA *brna)
        /* shape keys */
        prop= RNA_def_property(srna, "shape_key_lock", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "shapeflag", OB_SHAPE_LOCK);
-       RNA_def_property_boolean_funcs(prop, NULL, "rna_Object_shape_key_lock_set");
        RNA_def_property_ui_text(prop, "Shape Key Lock", "Always show the current Shape for this Object.");
        RNA_def_property_ui_icon(prop, ICON_UNPINNED, 1);
        RNA_def_property_update(prop, 0, "rna_Object_update_data");
index 20ca7f07f2b19984ec981064901b97f0c9fc9719..41ff3cc327441e75e45855dcb7d782a12853b731 100644 (file)
@@ -148,10 +148,13 @@ bool BL_ShapeDeformer::Update(void)
                // make sure the vertex weight cache is in line with this object
                m_pMeshObject->CheckWeightCache(blendobj);
 
-               /* we will blend the key directly in mvert array: it is used by armature as the start position */
+               /* we will blend the key directly in m_transverts array: it is used by armature as the start position */
                /* m_bmesh->key can be NULL in case of Modifier deformer */
                if (m_bmesh->key) {
-                       do_rel_key(0, m_bmesh->totvert, m_bmesh->totvert, (char *)m_bmesh->mvert->co, m_bmesh->key, 0);
+                       /* store verts locally */
+                       VerifyStorage();
+
+                       do_rel_key(0, m_bmesh->totvert, m_bmesh->totvert, (char *)(float *)m_transverts, m_bmesh->key, 0);
                        m_bDynamic = true;
                }
 
@@ -167,18 +170,12 @@ bool BL_ShapeDeformer::Update(void)
                bShapeUpdate = true;
        }
        // check for armature deform
-       bSkinUpdate = BL_SkinDeformer::Update();
+       bSkinUpdate = BL_SkinDeformer::UpdateInternal(bShapeUpdate && m_bDynamic);
 
        // non dynamic deformer = Modifer without armature and shape keys, no need to create storage
        if (!bSkinUpdate && bShapeUpdate && m_bDynamic) {
-               // this means that there is no armature, we still need to copy the vertex to m_transverts
-               // and update the normal (was not done after shape key calculation)
-
-               /* store verts locally */
-               VerifyStorage();
-
-               for (int v =0; v<m_bmesh->totvert; v++)
-                       VECCOPY(m_transverts[v], m_bmesh->mvert[v].co);
+               // this means that there is no armature, we still need to 
+               // update the normal (was not done after shape key calculation)
 
 #ifdef __NLA_DEFNORMALS
                if (m_recalcNormal)
index a13f78e1b27ef5175bcd71b18221f9bc1495feca..f166a7252ad2fa433bd1966db3f1a21f8a4672e7 100644 (file)
@@ -172,7 +172,7 @@ void BL_SkinDeformer::ProcessReplica()
 
 //void where_is_pose (Object *ob);
 //void armature_deform_verts(Object *armOb, Object *target, float (*vertexCos)[3], int numVerts, int deformflag); 
-bool BL_SkinDeformer::Update(void)
+bool BL_SkinDeformer::UpdateInternal(bool shape_applied)
 {
        /* See if the armature has been updated for this frame */
        if (PoseUpdated()){     
@@ -182,12 +182,14 @@ bool BL_SkinDeformer::Update(void)
                /* but it requires the blender object pointer... */
                Object* par_arma = m_armobj->GetArmatureObject();
 
-               /* store verts locally */
-               VerifyStorage();
-       
-               /* duplicate */
-               for (int v =0; v<m_bmesh->totvert; v++)
-                       VECCOPY(m_transverts[v], m_bmesh->mvert[v].co);
+               if(!shape_applied) {
+                       /* store verts locally */
+                       VerifyStorage();
+               
+                       /* duplicate */
+                       for (int v =0; v<m_bmesh->totvert; v++)
+                               VECCOPY(m_transverts[v], m_bmesh->mvert[v].co);
+               }
 
                m_armobj->ApplyPose();
 
@@ -219,6 +221,11 @@ bool BL_SkinDeformer::Update(void)
        return false;
 }
 
+bool BL_SkinDeformer::Update(void)
+{
+       return UpdateInternal(false);
+}
+
 /* XXX note: I propose to drop this function */
 void BL_SkinDeformer::SetArmature(BL_ArmatureObject *armobj)
 {
index b83895d5609ad5ea510f7fb9f8d487a28c40ba3a..9c6f5db2b951f4c2fc18ada02ed5b84c6c363436 100644 (file)
@@ -72,6 +72,7 @@ public:
 
        virtual ~BL_SkinDeformer();
        bool Update (void);
+       bool UpdateInternal (bool shape_applied);
        bool Apply (class RAS_IPolyMaterial *polymat);
        bool UpdateBuckets(void) 
        {