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.
This commit is contained in:
2005-07-10 12:50:14 +00:00
parent 227a67e105
commit 31f50d9247
6 changed files with 72 additions and 19 deletions

View File

@@ -166,6 +166,7 @@ bAction* copy_action(bAction *src)
/* ************************ Pose channels *************** */ /* ************************ 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 *get_pose_channel(const bPose *pose, const char *name)
{ {
bPoseChannel *chan; bPoseChannel *chan;
@@ -173,6 +174,7 @@ bPoseChannel *get_pose_channel(const bPose *pose, const char *name)
if(pose==NULL) return NULL; if(pose==NULL) return NULL;
for (chan=pose->chanbase.first; chan; chan=chan->next) { for (chan=pose->chanbase.first; chan; chan=chan->next) {
if(chan->name[0] == name[0])
if (!strcmp (chan->name, name)) if (!strcmp (chan->name, name))
return chan; return chan;
} }

View File

@@ -1936,7 +1936,7 @@ void makeBevelList(Object *ob)
* 1: nothing, 1:auto, 2:vector, 3:aligned * 1: nothing, 1:auto, 2:vector, 3:aligned
*/ */
/* mode: is not zero when IpoCurve, is 2 when forced horizontal for autohandles */
void calchandleNurb(BezTriple *bezt, BezTriple *prev, BezTriple *next, int mode) void calchandleNurb(BezTriple *bezt, BezTriple *prev, BezTriple *next, int mode)
{ {
float *p1,*p2,*p3,pt[3]; float *p1,*p2,*p3,pt[3];
@@ -2006,16 +2006,33 @@ void calchandleNurb(BezTriple *bezt,BezTriple *prev, BezTriple *next, int mode)
*(p2-3)= *p2-vx*len1; *(p2-3)= *p2-vx*len1;
*(p2-2)= *(p2+1)-vy*len1; *(p2-2)= *(p2+1)-vy*len1;
*(p2-1)= *(p2+2)-vz*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) { if(bezt->h2==HD_AUTO) {
len2/=len; len2/=len;
*(p2+3)= *p2+vx*len2; *(p2+3)= *p2+vx*len2;
*(p2+4)= *(p2+1)+vy*len2; *(p2+4)= *(p2+1)+vy*len2;
*(p2+5)= *(p2+2)+vz*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];
} }
} }
} }
}
}
if(bezt->h1==HD_VECT) { /* vector */ if(bezt->h1==HD_VECT) { /* vector */
dx/=3.0; dx/=3.0;
dy/=3.0; dy/=3.0;
@@ -2037,6 +2054,7 @@ void calchandleNurb(BezTriple *bezt,BezTriple *prev, BezTriple *next, int mode)
len1= VecLenf(p2, p2-3); len1= VecLenf(p2, p2-3);
if(len1==0.0) len1=1.0; if(len1==0.0) len1=1.0;
if(len2==0.0) len2=1.0; if(len2==0.0) len2=1.0;
if(bezt->f1 & 1) { /* order of calculation */ if(bezt->f1 & 1) { /* order of calculation */
if(bezt->h2==HD_ALIGN) { /* aligned */ if(bezt->h2==HD_ALIGN) { /* aligned */
len= len2/len1; len= len2/len1;
@@ -2224,7 +2242,8 @@ void sethandlesNurb(short code)
{ {
/* code==1: set autohandle */ /* code==1: set autohandle */
/* code==2: set vectorhandle */ /* 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; Nurb *nu;
BezTriple *bezt; BezTriple *bezt;
short a, ok=0; short a, ok=0;

View File

@@ -404,6 +404,9 @@ 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[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]; if(bezt->vec[2][0]<bezt->vec[1][0]) bezt->vec[2][0]= bezt->vec[1][0];
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 */ calchandleNurb(bezt, prev, next, 1); /* 1==special autohandle */
prev= bezt; prev= bezt;

View File

@@ -320,10 +320,10 @@ typedef short IPO_Channel;
#define CO_ROLL 9 #define CO_ROLL 9
*/ */
/* these are ipo-specific */ /* these are IpoCurve specific */
/* **************** IPO ********************* */ /* **************** IPO ********************* */
/* vartype */ /* icu->vartype */
#define IPO_CHAR 0 #define IPO_CHAR 0
#define IPO_SHORT 1 #define IPO_SHORT 1
#define IPO_INT 2 #define IPO_INT 2
@@ -335,29 +335,30 @@ typedef short IPO_Channel;
#define IPO_BEZTRIPLE 100 #define IPO_BEZTRIPLE 100
#define IPO_BPOINT 101 #define IPO_BPOINT 101
/* icu->vartype */
#define IPO_BITS 16 #define IPO_BITS 16
#define IPO_CHAR_BIT 16 #define IPO_CHAR_BIT 16
#define IPO_SHORT_BIT 17 #define IPO_SHORT_BIT 17
#define IPO_INT_BIT 18 #define IPO_INT_BIT 18
/* ipo */ /* icu->ipo */
#define IPO_CONST 0 #define IPO_CONST 0
#define IPO_LIN 1 #define IPO_LIN 1
#define IPO_BEZ 2 #define IPO_BEZ 2
#define IPO_MIXED 3 #define IPO_MIXED 3
/* extrap */ /* icu->extrap */
#define IPO_HORIZ 0 #define IPO_HORIZ 0
#define IPO_DIR 1 #define IPO_DIR 1
#define IPO_CYCL 2 #define IPO_CYCL 2
#define IPO_CYCLX 3 #define IPO_CYCLX 3
/* flag */ /* icu->flag */
#define IPO_VISIBLE 1 #define IPO_VISIBLE 1
#define IPO_SELECT 2 #define IPO_SELECT 2
#define IPO_EDIT 4 #define IPO_EDIT 4
#define IPO_LOCK 8 #define IPO_LOCK 8
#define IPO_AUTO_HORIZ 16
#endif #endif

View File

@@ -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) void sethandles_ipo(int code)
{ {
/* this function lets you set bezier handles all to /* 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, selected_bezier_loop(vis_edit_icu_bez, set_bezier_vector,
calchandles_ipocurve); calchandles_ipocurve);
break; break;
case 4:
/* set to enforce autohandles to be horizontal on extremes */
ipo_curves_auto_horiz();
break;
default: default:
if (selected_bezier_loop(vis_edit_icu_bez, bezier_isfree, NULL) ) { if (selected_bezier_loop(vis_edit_icu_bez, bezier_isfree, NULL) ) {
/*** Set to free ***/ /*** Set to free ***/
@@ -3156,7 +3182,7 @@ void del_ipo()
if( okee("Erase selected")==0 ) return; if( okee("Erase selected")==0 ) return;
// eerste doorloop, kunnen hele stukken weg? // first round, can we delete entire parts?
ei= G.sipo->editipo; ei= G.sipo->editipo;
for(a=0; a<G.sipo->totipo; a++, ei++) { 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; ei= G.sipo->editipo;
for(b=0; b<G.sipo->totipo; b++, ei++) { for(b=0; b<G.sipo->totipo; b++, ei++) {
if ISPOIN(ei, flag & IPO_VISIBLE, icu) { if ISPOIN(ei, flag & IPO_VISIBLE, icu) {

View File

@@ -2015,9 +2015,11 @@ static void winqreadipospace(ScrArea *sa, void *spacedata, BWinEvent *evt)
transform_ipo('g'); transform_ipo('g');
break; break;
case HKEY: 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); sethandles_ipo(HD_AUTO);
else if((G.qual==0)) else if(G.qual==0)
sethandles_ipo(HD_ALIGN); sethandles_ipo(HD_ALIGN);
break; break;
case JKEY: case JKEY: