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 *************** */
/* usually used within a loop, so we got a N^2 slowdown */
bPoseChannel *get_pose_channel(const bPose *pose, const char *name)
{
bPoseChannel *chan;
@@ -173,6 +174,7 @@ bPoseChannel *get_pose_channel(const bPose *pose, const char *name)
if(pose==NULL) return NULL;
for (chan=pose->chanbase.first; chan; chan=chan->next) {
if(chan->name[0] == name[0])
if (!strcmp (chan->name, name))
return chan;
}

View File

@@ -1936,7 +1936,7 @@ void makeBevelList(Object *ob)
* 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)
{
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-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];
}
}
}
}
}
if(bezt->h1==HD_VECT) { /* vector */
dx/=3.0;
dy/=3.0;
@@ -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;

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[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 */
prev= bezt;

View File

@@ -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
@@ -335,29 +335,30 @@ typedef short IPO_Channel;
#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

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)
{
/* 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) {

View File

@@ -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: