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:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user