diff options
author | Ton Roosendaal <ton@blender.org> | 2005-07-10 16:50:14 +0400 |
---|---|---|
committer | Ton Roosendaal <ton@blender.org> | 2005-07-10 16:50:14 +0400 |
commit | 31f50d9247edd6427bc76514b94cea72a3d0eb44 (patch) | |
tree | 091eb0769fc90af1a76c58f52803fa1ee4de4efb /source | |
parent | 227a67e1057f5a8595e1129422fdacfbe17b48c2 (diff) |
For long on the wanna-have list;
Ipocurves with "Auto" handles now have option to remain horizontal on the
extrema (tops & valleys). Use ALT+H to set this per selected curve.
Note this is a per-curve feature, not per-handle.
If it works satisfying I can check on making this the default new added
curve.
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/intern/action.c | 8 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/curve.c | 25 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/ipo.c | 7 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_ipo_types.h | 15 | ||||
-rw-r--r-- | source/blender/src/editipo.c | 30 | ||||
-rw-r--r-- | source/blender/src/space.c | 6 |
6 files changed, 72 insertions, 19 deletions
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index 5078c61c788..4f2b5eac15c 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -166,15 +166,17 @@ bAction* copy_action(bAction *src) /* ************************ Pose channels *************** */ +/* usually used within a loop, so we got a N^2 slowdown */ bPoseChannel *get_pose_channel(const bPose *pose, const char *name) { bPoseChannel *chan; if(pose==NULL) return NULL; - for (chan=pose->chanbase.first; chan; chan=chan->next){ - if (!strcmp (chan->name, name)) - return chan; + for (chan=pose->chanbase.first; chan; chan=chan->next) { + if(chan->name[0] == name[0]) + if (!strcmp (chan->name, name)) + return chan; } return NULL; diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index c118a109b8f..c53a70156c4 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -1936,8 +1936,8 @@ void makeBevelList(Object *ob) * 1: nothing, 1:auto, 2:vector, 3:aligned */ - -void calchandleNurb(BezTriple *bezt,BezTriple *prev, BezTriple *next, int mode) +/* mode: is not zero when IpoCurve, is 2 when forced horizontal for autohandles */ +void calchandleNurb(BezTriple *bezt, BezTriple *prev, BezTriple *next, int mode) { float *p1,*p2,*p3,pt[3]; float dx1,dy1,dz1,dx,dy,dz,vx,vy,vz,len,len1,len2; @@ -2006,13 +2006,30 @@ void calchandleNurb(BezTriple *bezt,BezTriple *prev, BezTriple *next, int mode) *(p2-3)= *p2-vx*len1; *(p2-2)= *(p2+1)-vy*len1; *(p2-1)= *(p2+2)-vz*len1; + + if(mode==2 && next && prev) { // keep horizontal if extrema + float ydiff1= prev->vec[1][1] - bezt->vec[1][1]; + float ydiff2= next->vec[1][1] - bezt->vec[1][1]; + if( (ydiff1<0.0 && ydiff2<0.0) || (ydiff1>0.0 && ydiff2>0.0) ) { + bezt->vec[0][1]= bezt->vec[1][1]; + } + } } if(bezt->h2==HD_AUTO) { len2/=len; *(p2+3)= *p2+vx*len2; *(p2+4)= *(p2+1)+vy*len2; *(p2+5)= *(p2+2)+vz*len2; + + if(mode==2 && next && prev) { // keep horizontal if extrema + float ydiff1= prev->vec[1][1] - bezt->vec[1][1]; + float ydiff2= next->vec[1][1] - bezt->vec[1][1]; + if( (ydiff1<0.0 && ydiff2<0.0) || (ydiff1>0.0 && ydiff2>0.0) ) { + bezt->vec[2][1]= bezt->vec[1][1]; + } + } } + } } @@ -2037,6 +2054,7 @@ void calchandleNurb(BezTriple *bezt,BezTriple *prev, BezTriple *next, int mode) len1= VecLenf(p2, p2-3); if(len1==0.0) len1=1.0; if(len2==0.0) len2=1.0; + if(bezt->f1 & 1) { /* order of calculation */ if(bezt->h2==HD_ALIGN) { /* aligned */ len= len2/len1; @@ -2224,7 +2242,8 @@ void sethandlesNurb(short code) { /* code==1: set autohandle */ /* code==2: set vectorhandle */ - /* if code==3 (HD_ALIGN) it toggle, vectorhandles become HD_FREE */ + /* code==3 (HD_ALIGN) it toggle, vectorhandles become HD_FREE */ + /* code==4: sets icu flag to become IPO_AUTO_HORIZ, horizontal extremes on auto-handles */ Nurb *nu; BezTriple *bezt; short a, ok=0; diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c index a03eb0e35c4..d7cde3deae7 100644 --- a/source/blender/blenkernel/intern/ipo.c +++ b/source/blender/blenkernel/intern/ipo.c @@ -404,8 +404,11 @@ void calchandles_ipocurve(IpoCurve *icu) if(bezt->vec[0][0]>bezt->vec[1][0]) bezt->vec[0][0]= bezt->vec[1][0]; if(bezt->vec[2][0]<bezt->vec[1][0]) bezt->vec[2][0]= bezt->vec[1][0]; - calchandleNurb(bezt, prev, next, 1); /* 1==special autohandle */ - + if(icu->flag & IPO_AUTO_HORIZ) + calchandleNurb(bezt, prev, next, 2); /* 2==special autohandle && keep extrema horizontal */ + else + calchandleNurb(bezt, prev, next, 1); /* 1==special autohandle */ + prev= bezt; if(a==1) { next= 0; diff --git a/source/blender/makesdna/DNA_ipo_types.h b/source/blender/makesdna/DNA_ipo_types.h index 352a2589c14..c658d40db79 100644 --- a/source/blender/makesdna/DNA_ipo_types.h +++ b/source/blender/makesdna/DNA_ipo_types.h @@ -320,10 +320,10 @@ typedef short IPO_Channel; #define CO_ROLL 9 */ -/* these are ipo-specific */ +/* these are IpoCurve specific */ /* **************** IPO ********************* */ -/* vartype */ +/* icu->vartype */ #define IPO_CHAR 0 #define IPO_SHORT 1 #define IPO_INT 2 @@ -331,33 +331,34 @@ typedef short IPO_Channel; #define IPO_FLOAT 4 #define IPO_DOUBLE 5 #define IPO_FLOAT_DEGR 6 -/* very special case, in keys */ + /* very special case, in keys */ #define IPO_BEZTRIPLE 100 #define IPO_BPOINT 101 - +/* icu->vartype */ #define IPO_BITS 16 #define IPO_CHAR_BIT 16 #define IPO_SHORT_BIT 17 #define IPO_INT_BIT 18 -/* ipo */ +/* icu->ipo */ #define IPO_CONST 0 #define IPO_LIN 1 #define IPO_BEZ 2 #define IPO_MIXED 3 -/* extrap */ +/* icu->extrap */ #define IPO_HORIZ 0 #define IPO_DIR 1 #define IPO_CYCL 2 #define IPO_CYCLX 3 -/* flag */ +/* icu->flag */ #define IPO_VISIBLE 1 #define IPO_SELECT 2 #define IPO_EDIT 4 #define IPO_LOCK 8 +#define IPO_AUTO_HORIZ 16 #endif diff --git a/source/blender/src/editipo.c b/source/blender/src/editipo.c index d2647534016..63e48d1d760 100644 --- a/source/blender/src/editipo.c +++ b/source/blender/src/editipo.c @@ -2926,6 +2926,27 @@ void sethandles_ipo_keys(Ipo *ipo, int code) } +static void ipo_curves_auto_horiz(void) +{ + EditIpo *ei; + int a, set= 1; + + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++, ei++) { + if ISPOIN3(ei, flag & IPO_VISIBLE, flag & IPO_SELECT, icu) + if(ei->flag & IPO_AUTO_HORIZ) set= 0; + } + + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++, ei++) { + if ISPOIN3(ei, flag & IPO_VISIBLE, flag & IPO_SELECT, icu) { + if(set) ei->flag |= IPO_AUTO_HORIZ; + else ei->flag &= ~IPO_AUTO_HORIZ; + } + } + update_editipo_flags(); +} + void sethandles_ipo(int code) { /* this function lets you set bezier handles all to @@ -2950,6 +2971,11 @@ void sethandles_ipo(int code) selected_bezier_loop(vis_edit_icu_bez, set_bezier_vector, calchandles_ipocurve); break; + case 4: + /* set to enforce autohandles to be horizontal on extremes */ + ipo_curves_auto_horiz(); + + break; default: if (selected_bezier_loop(vis_edit_icu_bez, bezier_isfree, NULL) ) { /*** Set to free ***/ @@ -3156,7 +3182,7 @@ void del_ipo() if( okee("Erase selected")==0 ) return; - // eerste doorloop, kunnen hele stukken weg? + // first round, can we delete entire parts? ei= G.sipo->editipo; for(a=0; a<G.sipo->totipo; a++, ei++) { @@ -3197,7 +3223,7 @@ void del_ipo() } } - // tweede doorloop, kleine stukken weg: alleen curves + // 2nd round, small parts: just curves ei= G.sipo->editipo; for(b=0; b<G.sipo->totipo; b++, ei++) { if ISPOIN(ei, flag & IPO_VISIBLE, icu) { diff --git a/source/blender/src/space.c b/source/blender/src/space.c index 0b29c47f2b1..906f4c61eee 100644 --- a/source/blender/src/space.c +++ b/source/blender/src/space.c @@ -2015,9 +2015,11 @@ static void winqreadipospace(ScrArea *sa, void *spacedata, BWinEvent *evt) transform_ipo('g'); break; case HKEY: - if((G.qual==LR_SHIFTKEY)) + if(G.qual==LR_ALTKEY) + sethandles_ipo(4); // tsk tsk ton! + if(G.qual==LR_SHIFTKEY) sethandles_ipo(HD_AUTO); - else if((G.qual==0)) + else if(G.qual==0) sethandles_ipo(HD_ALIGN); break; case JKEY: |