diff options
Diffstat (limited to 'source/blender/blenkernel/intern/key.c')
-rw-r--r-- | source/blender/blenkernel/intern/key.c | 566 |
1 files changed, 272 insertions, 294 deletions
diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c index 2d3b84bbdb3..742214ab28e 100644 --- a/source/blender/blenkernel/intern/key.c +++ b/source/blender/blenkernel/intern/key.c @@ -35,6 +35,9 @@ #include "MEM_guardedalloc.h" +#include "BLI_blenlib.h" +#include "BLI_editVert.h" + #include "DNA_anim_types.h" #include "DNA_curve_types.h" #include "DNA_key_types.h" @@ -53,11 +56,12 @@ #include "BKE_lattice.h" #include "BKE_library.h" #include "BKE_mesh.h" +#include "BKE_tessmesh.h" #include "BKE_main.h" #include "BKE_object.h" #include "BKE_utildefines.h" -#include "BLI_blenlib.h" +#include "RNA_access.h" #include "BLI_cellalloc.h" @@ -167,7 +171,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; @@ -496,48 +500,80 @@ 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 char *key_block_get_data(Key *key, KeyBlock *actkb, KeyBlock *kb, char **freedata) +{ + if(kb == actkb) { + /* this hack makes it possible to edit shape keys in + edit mode with shape keys blending applied */ + if(GS(key->from->name) == ID_ME) { + Mesh *me; + BMVert *eve; + BMIter iter; + float (*co)[3]; + int a; + + me= (Mesh*)key->from; + + if(me->edit_btmesh && me->edit_btmesh->bm->totvert == kb->totelem) { + a= 0; + co= MEM_callocN(sizeof(float)*3*me->edit_btmesh->bm->totvert, "key_block_get_data"); + + BM_ITER(eve, &iter, me->edit_btmesh->bm, BM_VERTS_OF_MESH, NULL) { + VECCOPY(co[a], eve->co); + a++; + } + + *freedata= (char*)co; + return (char*)co; + } + } + } + + *freedata= NULL; + return kb->data; +} + +static void cp_key(int start, int end, int tot, char *poin, Key *key, KeyBlock *actkb, KeyBlock *kb, float *weights, int mode) { float ktot = 0.0, kd = 0.0; int elemsize, poinsize = 0, a, *ofsp, ofs[32], flagflo=0; - char *k1, *kref; + char *k1, *kref, *freek1, *freekref; char *cp, elemstr[8]; 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; - - 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; } + k1= key_block_get_data(key, actkb, kb, &freek1); + kref= key_block_get_data(key, actkb, key->refkey, &freekref); + /* this exception is needed for slurphing */ if(start!=0) { @@ -574,33 +610,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++; } @@ -620,71 +647,63 @@ static void cp_key(int start, int end, int tot, char *poin, Key *key, KeyBlock * if(mode==KEY_BEZTRIPLE) a+=2; } + + if(freek1) MEM_freeN(freek1); + if(freekref) MEM_freeN(freekref); } -void cp_cu_key(Curve *cu, KeyBlock *kb, int start, int end) +static void cp_cu_key(Curve *cu, Key *key, KeyBlock *actkb, 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); + if(a1<a2) cp_key(a1, a2, tot, poin, key, actkb, 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); - + if(a1<a2) cp_key(a1, a2, tot, poin, key, actkb, kb, NULL, KEY_BEZTRIPLE); } - a+= step; - nu=nu->next; + else + step= 0; } } -void do_rel_key(int start, int end, int tot, char *basispoin, Key *key, int mode) +void do_rel_key(int start, int end, int tot, char *basispoin, Key *key, KeyBlock *actkb, int mode) { KeyBlock *kb; int *ofsp, ofs[3], elemsize, b; char *cp, *poin, *reffrom, *from, elemstr[8]; + char *freefrom, *freereffrom; 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; } @@ -701,7 +720,7 @@ void do_rel_key(int start, int end, int tot, char *basispoin, Key *key, int mode if(mode==KEY_BEZTRIPLE) elemsize*= 3; /* step 1 init */ - cp_key(start, end, tot, basispoin, key, key->refkey, NULL, mode); + cp_key(start, end, tot, basispoin, key, actkb, key->refkey, NULL, mode); /* step 2: do it */ @@ -709,21 +728,18 @@ 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; + /* reference now can be any block */ refb= BLI_findlink(&key->block, kb->relative); if(refb==NULL) continue; - reffrom= refb->data; + + poin= basispoin; + from= key_block_get_data(key, actkb, kb, &freefrom); + reffrom= key_block_get_data(key, actkb, refb, &freereffrom); poin+= start*ofs[0]; reffrom+= key->elemsize*start; // key elemsize yes! @@ -745,17 +761,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; } @@ -771,38 +783,39 @@ void do_rel_key(int start, int end, int tot, char *basispoin, Key *key, int mode if(mode==KEY_BEZTRIPLE) b+= 2; if(weights) weights++; } + + if(freefrom) MEM_freeN(freefrom); + if(freereffrom) MEM_freeN(freereffrom); } } } } -static void do_key(int start, int end, int tot, char *poin, Key *key, KeyBlock **k, float *t, int mode) +static void do_key(int start, int end, int tot, char *poin, Key *key, KeyBlock *actkb, KeyBlock **k, float *t, int mode) { float k1tot = 0.0, k2tot = 0.0, k3tot = 0.0, k4tot = 0.0; float k1d = 0.0, k2d = 0.0, k3d = 0.0, k4d = 0.0; int a, ofs[32], *ofsp; int flagdo= 15, flagflo=0, elemsize, poinsize=0; - char *k1, *k2, *k3, *k4; + char *k1, *k2, *k3, *k4, *freek1, *freek2, *freek3, *freek4; char *cp, elemstr[8];; 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]; @@ -810,10 +823,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, actkb, k[0], &freek1); + k2= key_block_get_data(key, actkb, k[1], &freek2); + k3= key_block_get_data(key, actkb, k[2], &freek3); + k4= key_block_get_data(key, actkb, k[3], &freek4); /* test for more or less points (per key!) */ if(tot != k[0]->totelem) { @@ -921,26 +934,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++; } @@ -988,6 +992,11 @@ static void do_key(int start, int end, int tot, char *poin, Key *key, KeyBlock * if(mode==KEY_BEZTRIPLE) a+= 2; } + + if(freek1) MEM_freeN(freek1); + if(freek2) MEM_freeN(freek2); + if(freek3) MEM_freeN(freek3); + if(freek4) MEM_freeN(freek4); } static float *get_weights_array(Object *ob, char *vgroup) @@ -1037,41 +1046,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]; + KeyBlock *k[4], *actkb= ob_get_keyblock(ob); + 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); } @@ -1080,42 +1078,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, actkb, k, t, 0); + else + cp_key(a, a+step, tot, (char *)out, key, actkb, 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, actkb, 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); } @@ -1124,106 +1113,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, actkb, k, t, 0); + else + cp_key(0, tot, tot, (char *)out, key, actkb, k[2], NULL, 0); } } - return 1; } -static void do_cu_key(Curve *cu, KeyBlock **k, float *t) +static void do_cu_key(Curve *cu, Key *key, KeyBlock *actkb, 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); - - do_key(a, a+step, tot, poin, cu->key, k, t, KEY_BPOINT); + poin= out - a*sizeof(float)*4; + do_key(a, a+step, tot, poin, key, actkb, k, t, KEY_BPOINT); } else if(nu->bezt) { - step= 3*nu->pntsu; - - poin= (char *)nu->bezt->vec; - poin -= a*sizeof(BezTriple); - - do_key(a, a+step, tot, poin, cu->key, k, t, KEY_BEZTRIPLE); - + poin= out - a*sizeof(float)*10; + do_key(a, a+step, tot, poin, key, actkb, 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, Key *key, KeyBlock *actkb, 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, key, actkb, KEY_BPOINT); } else if(nu->bezt) { - step= 3*nu->pntsu; - - poin= (char *)nu->bezt->vec; - poin -= a*sizeof(BezTriple); - - do_rel_key(a, a+step, tot, poin, cu->key, KEY_BEZTRIPLE); + poin= out - a*sizeof(float)*10; + do_rel_key(a, a+step, tot, poin, key, actkb, 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) { - KeyBlock *k[4]; + Curve *cu= ob->data; + KeyBlock *k[4], *actkb= ob_get_keyblock(ob); float cfra, ctime, t[4], delta; - int a, flag = 0, step = 0, tot; - - tot= count_curveverts(&cu->nurb); + int a, flag = 0, step = 0; - if(tot==0) return 0; - if(cu->key==NULL) return 0; - if(cu->key->block.first==NULL) return 0; - - if(cu->key->slurph) { - delta= cu->key->slurph; + if(key->slurph) { + delta= key->slurph; delta/= tot; step= 1; @@ -1238,66 +1190,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, cu->key, actkb, 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, key, actkb, k, t, out, tot); + else cp_cu_key(cu, key, actkb, 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) { - KeyBlock *k[4]; + Lattice *lt= ob->data; + KeyBlock *k[4], *actkb= ob_get_keyblock(ob); 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; @@ -1306,74 +1244,110 @@ 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, <->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, actkb, k, t, 0); + else + cp_key(a, a+1, tot, (char *)out, key, actkb, 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, actkb, 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, <->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, actkb, k, t, 0); + else + cp_key(0, tot, tot, (char *)out, key, actkb, 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); + KeyBlock *actkb= ob_get_keyblock(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; @@ -1382,46 +1356,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, actkb, 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, key, actkb, 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) @@ -1490,3 +1447,24 @@ KeyBlock *key_get_named_keyblock(Key *key, const char name[]) return NULL; } + +/* Get RNA-Path for 'value' setting of the given ShapeKey + * NOTE: the user needs to free the returned string once they're finishe with it + */ +char *key_get_curValue_rnaPath(Key *key, KeyBlock *kb) +{ + PointerRNA ptr; + PropertyRNA *prop; + + /* sanity checks */ + if ELEM(NULL, key, kb) + return NULL; + + /* create the RNA pointer */ + RNA_pointer_create(&key->id, &RNA_ShapeKey, kb, &ptr); + /* get pointer to the property too */ + prop= RNA_struct_find_property(&ptr, "value"); + + /* return the path */ + return RNA_path_from_ID_to_property(&ptr, prop); +} |