diff options
Diffstat (limited to 'source/blender/blenkernel/intern/key.c')
-rw-r--r-- | source/blender/blenkernel/intern/key.c | 377 |
1 files changed, 300 insertions, 77 deletions
diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c index 31b0a809ebe..708403ab1f7 100644 --- a/source/blender/blenkernel/intern/key.c +++ b/source/blender/blenkernel/intern/key.c @@ -38,6 +38,7 @@ #include "BLI_blenlib.h" #include "BLI_editVert.h" +#include "BLI_math_vector.h" #include "DNA_anim_types.h" #include "DNA_key_types.h" @@ -49,6 +50,7 @@ #include "BKE_animsys.h" #include "BKE_curve.h" #include "BKE_customdata.h" +#include "BKE_deform.h" #include "BKE_global.h" #include "BKE_key.h" #include "BKE_lattice.h" @@ -60,10 +62,6 @@ #include "RNA_access.h" -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - #define KEY_BPOINT 1 #define KEY_BEZTRIPLE 2 @@ -545,11 +543,15 @@ static void cp_key(int start, int end, int tot, char *poin, Key *key, KeyBlock * poinsize= ofs[0]; } else if( GS(key->from->name)==ID_CU ) { - if(mode==KEY_BPOINT) ofs[0]= sizeof(float)*4; - else ofs[0]= sizeof(float)*10; - + if(mode==KEY_BPOINT) { + ofs[0]= sizeof(float)*4; + poinsize= ofs[0]; + }else { + ofs[0]= sizeof(float)*12; + poinsize= ofs[0]/3; + } + ofs[1]= 0; - poinsize= ofs[0]; } if(end>tot) end= tot; @@ -615,7 +617,7 @@ static void cp_key(int start, int end, int tot, char *poin, Key *key, KeyBlock * memcpy(poin, k1, sizeof(float)*4); break; case IPO_BEZTRIPLE: - memcpy(poin, k1, sizeof(float)*10); + memcpy(poin, k1, sizeof(float)*12); break; } @@ -647,28 +649,25 @@ static void cp_key(int start, int end, int tot, char *poin, Key *key, KeyBlock * static void cp_cu_key(Curve *cu, Key *key, KeyBlock *actkb, KeyBlock *kb, int start, int end, char *out, int tot) { Nurb *nu; - char *poin; int a, step, a1, a2; 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= out - a*sizeof(float)*4; + a1= MAX2(a, start); a2= MIN2(a+step, end); - - if(a1<a2) cp_key(a1, a2, tot, poin, key, actkb, kb, NULL, KEY_BPOINT); + + if(a1<a2) cp_key(a1, a2, tot, out, key, actkb, kb, NULL, KEY_BPOINT); } else if(nu->bezt) { step= 3*nu->pntsu; - - poin= out - a*sizeof(float)*10; + + /* exception because keys prefer to work with complete blocks */ a1= MAX2(a, start); a2= MIN2(a+step, end); - if(a1<a2) cp_key(a1, a2, tot, poin, key, actkb, kb, NULL, KEY_BEZTRIPLE); + if(a1<a2) cp_key(a1, a2, tot, out, key, actkb, kb, NULL, KEY_BEZTRIPLE); } else step= 0; @@ -682,26 +681,34 @@ void do_rel_key(int start, int end, int tot, char *basispoin, Key *key, KeyBlock int *ofsp, ofs[3], elemsize, b; char *cp, *poin, *reffrom, *from, elemstr[8]; char *freefrom, *freereffrom; - + int poinsize= 0; + if(key->from==NULL) return; - + if( GS(key->from->name)==ID_ME ) { ofs[0]= sizeof(float)*3; ofs[1]= 0; + poinsize= ofs[0]; } else if( GS(key->from->name)==ID_LT ) { 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(float)*4; - else ofs[0]= sizeof(float)*10; - + if(mode==KEY_BPOINT) { + ofs[0]= sizeof(float)*4; + poinsize= ofs[0]; + } else { + ofs[0]= sizeof(float)*12; + poinsize= ofs[0] / 3; + } + ofs[1]= 0; } - + if(end>tot) end= tot; - + /* in case of beztriple */ elemstr[0]= 1; /* nr of ipofloats */ elemstr[1]= IPO_BEZTRIPLE; @@ -733,7 +740,7 @@ void do_rel_key(int start, int end, int tot, char *basispoin, Key *key, KeyBlock from= key_block_get_data(key, actkb, kb, &freefrom); reffrom= key_block_get_data(key, actkb, refb, &freereffrom); - poin+= start*ofs[0]; + poin+= start*poinsize; reffrom+= key->elemsize*start; // key elemsize yes! from+= key->elemsize*start; @@ -759,7 +766,7 @@ void do_rel_key(int start, int end, int tot, char *basispoin, Key *key, KeyBlock rel_flerp(4, (float *)poin, (float *)reffrom, (float *)from, weight); break; case IPO_BEZTRIPLE: - rel_flerp(10, (float *)poin, (float *)reffrom, (float *)from, weight); + rel_flerp(12, (float *)poin, (float *)reffrom, (float *)from, weight); break; } @@ -806,11 +813,15 @@ static void do_key(int start, int end, int tot, char *poin, Key *key, KeyBlock * poinsize= ofs[0]; } else if( GS(key->from->name)==ID_CU ) { - if(mode==KEY_BPOINT) ofs[0]= sizeof(float)*4; - else ofs[0]= sizeof(float)*10; - + if(mode==KEY_BPOINT) { + ofs[0]= sizeof(float)*4; + poinsize= ofs[0]; + } else { + ofs[0]= sizeof(float)*12; + poinsize= ofs[0] / 3; + } + ofs[1]= 0; - poinsize= ofs[0]; } if(end>tot) end= tot; @@ -932,7 +943,7 @@ static void do_key(int start, int end, int tot, char *poin, Key *key, KeyBlock * flerp(4, (float *)poin, (float *)k1, (float *)k2, (float *)k3, (float *)k4, t); break; case IPO_BEZTRIPLE: - flerp(10, (void *)poin, (void *)k1, (void *)k2, (void *)k3, (void *)k4, t); + flerp(12, (void *)poin, (void *)k1, (void *)k2, (void *)k3, (void *)k4, t); break; } @@ -993,7 +1004,6 @@ static void do_key(int start, int end, int tot, char *poin, Key *key, KeyBlock * static float *get_weights_array(Object *ob, char *vgroup) { - bDeformGroup *curdef; MDeformVert *dvert= NULL; EditMesh *em= NULL; EditVert *eve; @@ -1020,11 +1030,8 @@ static float *get_weights_array(Object *ob, char *vgroup) if(dvert==NULL) return NULL; /* find the group (weak loop-in-loop) */ - for (curdef = ob->defbase.first; curdef; curdef=curdef->next, index++) - if (!strcmp(curdef->name, vgroup)) - break; - - if(curdef) { + index= defgroup_name_index(ob, vgroup); + if(index >= 0) { float *weights; int i, j; @@ -1140,19 +1147,16 @@ static void do_mesh_key(Scene *scene, Object *ob, Key *key, char *out, int tot) static void do_cu_key(Curve *cu, Key *key, KeyBlock *actkb, KeyBlock **k, float *t, char *out, int tot) { Nurb *nu; - char *poin; int a, step; for(a=0, nu=cu->nurb.first; nu; nu=nu->next, a+=step) { if(nu->bp) { step= nu->pntsu*nu->pntsv; - poin= out - a*sizeof(float)*4; - do_key(a, a+step, tot, poin, key, actkb, k, t, KEY_BPOINT); + do_key(a, a+step, tot, out, key, actkb, k, t, KEY_BPOINT); } else if(nu->bezt) { step= 3*nu->pntsu; - poin= out - a*sizeof(float)*10; - do_key(a, a+step, tot, poin, key, actkb, k, t, KEY_BEZTRIPLE); + do_key(a, a+step, tot, out, key, actkb, k, t, KEY_BEZTRIPLE); } else step= 0; @@ -1162,19 +1166,16 @@ static void do_cu_key(Curve *cu, Key *key, KeyBlock *actkb, KeyBlock **k, float static void do_rel_cu_key(Curve *cu, Key *key, KeyBlock *actkb, float ctime, char *out, int tot) { Nurb *nu; - char *poin; int a, step; for(a=0, nu=cu->nurb.first; nu; nu=nu->next, a+=step) { if(nu->bp) { step= nu->pntsu*nu->pntsv; - 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= out - a*sizeof(float)*10; - do_rel_key(a, a+step, tot, poin, key, actkb, KEY_BEZTRIPLE); + do_rel_key(a, a+step, tot, out, key, actkb, KEY_BEZTRIPLE); } else step= 0; @@ -1187,35 +1188,61 @@ static void do_curve_key(Scene *scene, Object *ob, Key *key, char *out, int tot) KeyBlock *k[4], *actkb= ob_get_keyblock(ob); float cfra, ctime, t[4], delta; int a, flag = 0, step = 0; - - if(key->slurph) { - delta= key->slurph; - delta/= tot; - + + if(key->slurph && key->type!=KEY_RELATIVE) { + Nurb *nu; + int mode, i= 0, remain= 0, estep, count; + + delta= (float)key->slurph / tot; + step= 1; if(tot>100 && slurph_opt) { step= tot/50; delta*= step; /* in do_key and cp_key the case a>tot has been handled */ } - + cfra= (float)scene->r.cfra; - - 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(key->ipo, KEY_SPEED, &ctime)==0) { - ctime /= 100.0; - CLAMP(ctime, 0.0, 1.0); + + for(nu=cu->nurb.first; nu; nu=nu->next) { + if(nu->bp) { + mode= KEY_BPOINT; + estep= nu->pntsu*nu->pntsv; + } + else if(nu->bezt) { + mode= KEY_BEZTRIPLE; + estep= 3*nu->pntsu; } -#endif // XXX old animation system - - 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); + step= 0; + + a= 0; + while (a < estep) { + if (remain <= 0) { + cfra+= delta; + ctime= bsystem_time(scene, 0, cfra, 0.0f); // XXX old cruft + + ctime /= 100.0f; + CLAMP(ctime, 0.0f, 1.0f); // XXX for compat, we use this, but this clamping was confusing + flag= setkeys(ctime, &key->block, k, t, 0); + + remain= step; + } + + count= MIN2(remain, estep); + if (mode == KEY_BEZTRIPLE) { + count += 3 - count % 3; + } + + if(flag==0) + do_key(i, i+count, tot, (char *)out, key, actkb, k, t, mode); + else + cp_key(i, i+count, tot, (char *)out, key, actkb, k[2], NULL, mode); + + a += count; + i += count; + remain -= count; + } } } else { @@ -1339,11 +1366,11 @@ float *do_ob_key(Scene *scene, Object *ob) for(nu=cu->nurb.first; nu; nu=nu->next) { if(nu->bezt) { tot += 3*nu->pntsu; - size += nu->pntsu*10*sizeof(float); + size += nu->pntsu*12*sizeof(float); } else if(nu->bp) { tot += nu->pntsu*nu->pntsv; - size += nu->pntsu*nu->pntsv*10*sizeof(float); + size += nu->pntsu*nu->pntsv*12*sizeof(float); } } } @@ -1509,14 +1536,8 @@ KeyBlock *key_get_keyblock(Key *key, int index) /* get the appropriate KeyBlock given a name to search for */ KeyBlock *key_get_named_keyblock(Key *key, const char name[]) { - KeyBlock *kb; - - if (key && name) { - for (kb= key->block.first; kb; kb= kb->next) { - if (strcmp(name, kb->name)==0) - return kb; - } - } + if (key && name) + return BLI_findstring(&key->block, name, offsetof(KeyBlock, name)); return NULL; } @@ -1723,3 +1744,205 @@ void key_to_mesh(KeyBlock *kb, Mesh *me) VECCOPY(mvert->co, fp); } } + +/************************* vert coords ************************/ +float (*key_to_vertcos(Object *ob, KeyBlock *kb))[3] +{ + float (*vertCos)[3], *co; + float *fp= kb->data; + int tot= 0, a; + + /* Count of vertex coords in array */ + if(ob->type == OB_MESH) { + Mesh *me= (Mesh*)ob->data; + tot= me->totvert; + } else if(ob->type == OB_LATTICE) { + Lattice *lt= (Lattice*)ob->data; + tot= lt->pntsu*lt->pntsv*lt->pntsw; + } else if(ELEM(ob->type, OB_CURVE, OB_SURF)) { + Curve *cu= (Curve*)ob->data; + tot= count_curveverts(&cu->nurb); + } + + if (tot == 0) return NULL; + + vertCos= MEM_callocN(tot*sizeof(*vertCos), "key_to_vertcos vertCos"); + + /* Copy coords to array */ + co= (float*)vertCos; + + if(ELEM(ob->type, OB_MESH, OB_LATTICE)) { + for (a= 0; a<tot; a++, fp+=3, co+=3) { + copy_v3_v3(co, fp); + } + } else if(ELEM(ob->type, OB_CURVE, OB_SURF)) { + Curve *cu= (Curve*)ob->data; + Nurb *nu= cu->nurb.first; + BezTriple *bezt; + BPoint *bp; + + while (nu) { + if(nu->bezt) { + int i; + bezt= nu->bezt; + a= nu->pntsu; + + while (a--) { + for (i= 0; i<3; i++) { + copy_v3_v3(co, fp); + fp+= 3; co+= 3; + } + + fp+= 3; /* skip alphas */ + + bezt++; + } + } + else { + bp= nu->bp; + a= nu->pntsu*nu->pntsv; + + while (a--) { + copy_v3_v3(co, fp); + + fp+= 4; + co+= 3; + + bp++; + } + } + + nu= nu->next; + } + } + + return vertCos; +} + +void vertcos_to_key(Object *ob, KeyBlock *kb, float (*vertCos)[3]) +{ + float *co= (float*)vertCos, *fp; + int tot= 0, a, elemsize; + + if (kb->data) MEM_freeN(kb->data); + + /* Count of vertex coords in array */ + if(ob->type == OB_MESH) { + Mesh *me= (Mesh*)ob->data; + tot= me->totvert; + elemsize= me->key->elemsize; + } else if(ob->type == OB_LATTICE) { + Lattice *lt= (Lattice*)ob->data; + tot= lt->pntsu*lt->pntsv*lt->pntsw; + elemsize= lt->key->elemsize; + } else if(ELEM(ob->type, OB_CURVE, OB_SURF)) { + Curve *cu= (Curve*)ob->data; + elemsize= cu->key->elemsize; + tot= count_curveverts(&cu->nurb); + } + + if (tot == 0) { + kb->data= NULL; + return; + } + + fp= kb->data= MEM_callocN(tot*elemsize, "key_to_vertcos vertCos"); + + /* Copy coords to keyblock */ + + if(ELEM(ob->type, OB_MESH, OB_LATTICE)) { + for (a= 0; a<tot; a++, fp+=3, co+=3) { + copy_v3_v3(fp, co); + } + } else if(ELEM(ob->type, OB_CURVE, OB_SURF)) { + Curve *cu= (Curve*)ob->data; + Nurb *nu= cu->nurb.first; + BezTriple *bezt; + BPoint *bp; + + while (nu) { + if(nu->bezt) { + int i; + bezt= nu->bezt; + a= nu->pntsu; + + while (a--) { + for (i= 0; i<3; i++) { + copy_v3_v3(fp, co); + fp+= 3; co+= 3; + } + + fp+= 3; /* skip alphas */ + + bezt++; + } + } + else { + bp= nu->bp; + a= nu->pntsu*nu->pntsv; + + while (a--) { + copy_v3_v3(fp, co); + + fp+= 4; + co+= 3; + + bp++; + } + } + + nu= nu->next; + } + } +} + +void offset_to_key(Object *ob, KeyBlock *kb, float (*ofs)[3]) +{ + int a; + float *co= (float*)ofs, *fp= kb->data; + + if(ELEM(ob->type, OB_MESH, OB_LATTICE)) { + for (a= 0; a<kb->totelem; a++, fp+=3, co+=3) { + add_v3_v3(fp, co); + } + } else if(ELEM(ob->type, OB_CURVE, OB_SURF)) { + Curve *cu= (Curve*)ob->data; + Nurb *nu= cu->nurb.first; + BezTriple *bezt; + BPoint *bp; + + while (nu) { + if(nu->bezt) { + int i; + bezt= nu->bezt; + a= nu->pntsu; + + while (a--) { + for (i= 0; i<3; i++) { + add_v3_v3(fp, co); + fp+= 3; co+= 3; + } + + fp+= 3; /* skip alphas */ + + bezt++; + } + } + else { + bp= nu->bp; + a= nu->pntsu*nu->pntsv; + + while (a--) { + add_v3_v3(fp, co); + + fp+= 4; + co+= 3; + + bp++; + } + } + + nu= nu->next; + } + } +} |