diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2010-07-25 15:57:36 +0400 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2010-07-25 15:57:36 +0400 |
commit | cc0f3146e798479be0758b5c152ef67ef42ea8dc (patch) | |
tree | 669704799ec2a83908777d1b0d9cc1517dfb871c /source/blender/blenkernel | |
parent | 61a09d96b1c10decb732f77a50421101e43cf401 (diff) |
Shapekeys for curves/surfeces
Fix #21498: Edit curve Shape key /252_r 27318
Added full support of shape keys for curves and nurbs surfaces including
topology changing in edit mode, undo stuff, updating relative keys when
working under basis and so on.
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r-- | source/blender/blenkernel/BKE_curve.h | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/anim.c | 12 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/curve.c | 26 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/displist.c | 17 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/key.c | 151 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/object.c | 13 |
6 files changed, 131 insertions, 90 deletions
diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h index ca45c2f318c..e83ea4b809c 100644 --- a/source/blender/blenkernel/BKE_curve.h +++ b/source/blender/blenkernel/BKE_curve.h @@ -105,5 +105,7 @@ int check_valid_nurb_v( struct Nurb *nu); int clamp_nurb_order_u( struct Nurb *nu); int clamp_nurb_order_v( struct Nurb *nu); +ListBase *BKE_curve_nurbs(struct Curve *cu); + #endif diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index 157c0743c50..412084f7cd1 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -66,6 +66,8 @@ #include "BKE_utildefines.h" #include "BKE_depsgraph.h" +#include "ED_curve.h" /* for ED_curve_nurbs */ + // XXX bad level call... /* --------------------- */ @@ -458,17 +460,17 @@ void calc_curvepath(Object *ob) float *fp, *dist, *maxdist, xyz[3]; float fac, d=0, fac1, fac2; int a, tot, cycl=0; + ListBase *nurbs; /* in a path vertices are with equal differences: path->len = number of verts */ /* NOW WITH BEVELCURVE!!! */ if(ob==NULL || ob->type != OB_CURVE) return; cu= ob->data; - if(cu->editnurb) - nu= cu->editnurb->first; - else - nu= cu->nurb.first; - + + nurbs= BKE_curve_nurbs(cu); + nu= nurbs->first; + if(cu->path) free_path(cu->path); cu->path= NULL; diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index d355a520a8c..4142ad7128f 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -58,6 +58,8 @@ #include "BKE_object.h" #include "BKE_utildefines.h" // VECCOPY +#include "ED_curve.h" + /* globals */ /* local */ @@ -104,13 +106,8 @@ void free_curve(Curve *cu) BLI_freelistN(&cu->bev); freedisplist(&cu->disp); BKE_free_editfont(cu); - - if(cu->editnurb) { - freeNurblist(cu->editnurb); - MEM_freeN(cu->editnurb); - cu->editnurb= NULL; - } + free_curve_editNurb(cu); unlink_curve(cu); BKE_free_animdata((ID *)cu); @@ -2008,8 +2005,10 @@ void makeBevelList(Object *ob) /* STEP 1: MAKE POLYS */ BLI_freelistN(&(cu->bev)); - if(cu->editnurb && ob->type!=OB_FONT) nu= cu->editnurb->first; - else nu= cu->nurb.first; + if(cu->editnurb && ob->type!=OB_FONT) { + ListBase *nurbs= ED_curve_editnurbs(cu); + nu= nurbs->first; + } else nu= cu->nurb.first; while(nu) { @@ -2999,7 +2998,7 @@ float (*curve_getKeyVertexCos(Curve *cu, ListBase *lb, float *key))[3] VECCOPY(co, key); co+=3; key+=3; VECCOPY(co, key); co+=3; key+=3; VECCOPY(co, key); co+=3; key+=3; - key++; /* skip tilt */ + key+=3; /* skip tilt */ } } else { @@ -3099,5 +3098,12 @@ int clamp_nurb_order_v( struct Nurb *nu) return change; } +/* Get edit nurbs or normal nurbs list */ +ListBase *BKE_curve_nurbs(Curve *cu) +{ + if (cu->editnurb) { + return ED_curve_editnurbs(cu); + } - + return &cu->nurb; +} diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index bb020c936a6..ca659faa972 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -63,6 +63,7 @@ #include "BLO_sys_types.h" // for intptr_t support +#include "ED_curve.h" /* for BKE_curve_nurbs */ static void boundbox_displist(Object *ob); @@ -1221,7 +1222,7 @@ static void curve_calc_modifiers_pre(Scene *scene, Object *ob, int forRender, fl ModifierData *md = modifiers_getVirtualModifierList(ob); ModifierData *preTesselatePoint; Curve *cu= ob->data; - ListBase *nurb= cu->editnurb?cu->editnurb:&cu->nurb; + ListBase *nurb= BKE_curve_nurbs(cu); int numVerts = 0; int editmode = (!forRender && cu->editnurb); float (*originalVerts)[3] = NULL; @@ -1324,8 +1325,9 @@ static void curve_calc_modifiers_post(Scene *scene, Object *ob, ListBase *dispba ModifierData *md = modifiers_getVirtualModifierList(ob); ModifierData *preTesselatePoint; Curve *cu= ob->data; - ListBase *nurb= cu->editnurb?cu->editnurb:&cu->nurb; - int required_mode, totvert = 0; + ListBase *nurb= BKE_curve_nurbs(cu); + DispList *dl; + int required_mode = 0, totvert = 0; int editmode = (!forRender && cu->editnurb); DerivedMesh *dm= NULL, *ndm; float (*vertCos)[3] = NULL; @@ -1590,9 +1592,9 @@ void makeDispListSurf(Scene *scene, Object *ob, ListBase *dispbase, int numVerts; float (*originalVerts)[3]; float (*deformedVerts)[3]; - + if(!forRender && cu->editnurb) - nubase= cu->editnurb; + nubase= ED_curve_editnurbs(cu); else nubase= &cu->nurb; @@ -1689,10 +1691,7 @@ static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispba cu->taperobj = NULL; } - if(cu->editnurb) - nubase= cu->editnurb; - else - nubase= &cu->nurb; + nubase= BKE_curve_nurbs(cu); BLI_freelistN(&(cu->bev)); diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c index b8219c4aa35..354b3b0e7d8 100644 --- a/source/blender/blenkernel/intern/key.c +++ b/source/blender/blenkernel/intern/key.c @@ -542,11 +542,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; @@ -612,7 +616,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; } @@ -644,28 +648,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; @@ -679,26 +680,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; @@ -730,7 +739,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; @@ -756,7 +765,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; } @@ -803,11 +812,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; @@ -929,7 +942,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; } @@ -1137,19 +1150,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; @@ -1159,19 +1169,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; @@ -1184,35 +1191,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 { @@ -1336,11 +1369,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); } } } diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 75b5e6d9331..efff3d138e6 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -1885,13 +1885,12 @@ static void give_parvert(Object *par, int nr, float *vec) BPoint *bp; BezTriple *bezt; int found= 0; - + ListBase *nurbs; + cu= par->data; - if(cu->editnurb) - nu= cu->editnurb->first; - else - nu= cu->nurb.first; - + nurbs= BKE_curve_nurbs(cu); + nu= nurbs->first; + count= 0; while(nu && !found) { if(nu->type == CU_BEZIER) { @@ -2946,7 +2945,7 @@ static KeyBlock *insert_curvekey(Scene *scene, Object *ob, char *name, int from_ Curve *cu= ob->data; Key *key= cu->key; KeyBlock *kb; - ListBase *lb= (cu->editnurb)? cu->editnurb: &cu->nurb; + ListBase *lb= BKE_curve_nurbs(cu); int newkey= 0; if(key==NULL) { |