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