From ec58f413b1c77bcaa0ad0db4f751e75753cb5b03 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Sun, 23 Oct 2005 21:36:24 +0000 Subject: [PATCH] Autohandles in Ipo Window still could overshoot. Added a new clamping to ensure the handles never result in a curve that goes beyond the neighbour control points. http://www.blender.org/cms/Animation_Curve_Handle.717.0.html --- source/blender/blenkernel/intern/curve.c | 52 ++++++++++++++++++++++- source/blender/makesdna/DNA_curve_types.h | 9 ++-- source/blender/src/editipo_mods.c | 6 +-- source/blender/src/header_ipo.c | 13 +++++- source/blender/src/space.c | 2 +- 5 files changed, 71 insertions(+), 11 deletions(-) diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index 7cf12b807dd..9cdc8be9e57 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -1980,7 +1980,8 @@ void calchandleNurb(BezTriple *bezt, BezTriple *prev, BezTriple *next, int mode) vz= dz1/len2 + dz/len1; len= 2.5614f*(float)sqrt(vx*vx + vy*vy + vz*vz); if(len!=0.0f) { - + int leftviolate=0, rightviolate=0; /* for mode==2 */ + if(len1>5.0f*len2) len1= 5.0f*len2; if(len2>5.0f*len1) len2= 5.0f*len1; @@ -1996,6 +1997,20 @@ void calchandleNurb(BezTriple *bezt, BezTriple *prev, BezTriple *next, int mode) if( (ydiff1<=0.0 && ydiff2<=0.0) || (ydiff1>=0.0 && ydiff2>=0.0) ) { bezt->vec[0][1]= bezt->vec[1][1]; } + else { // handles should not be beyond y coord of two others + if(ydiff1<=0.0) { + if(prev->vec[1][1] > bezt->vec[0][1]) { + bezt->vec[0][1]= prev->vec[1][1]; + leftviolate= 1; + } + } + else { + if(prev->vec[1][1] < bezt->vec[0][1]) { + bezt->vec[0][1]= prev->vec[1][1]; + leftviolate= 1; + } + } + } } } if(bezt->h2==HD_AUTO) { @@ -2010,6 +2025,41 @@ void calchandleNurb(BezTriple *bezt, BezTriple *prev, BezTriple *next, int mode) if( (ydiff1<=0.0 && ydiff2<=0.0) || (ydiff1>=0.0 && ydiff2>=0.0) ) { bezt->vec[2][1]= bezt->vec[1][1]; } + else { // handles should not be beyond y coord of two others + if(ydiff1<=0.0) { + if(next->vec[1][1] < bezt->vec[2][1]) { + bezt->vec[2][1]= next->vec[1][1]; + rightviolate= 1; + } + } + else { + if(next->vec[1][1] > bezt->vec[2][1]) { + bezt->vec[2][1]= next->vec[1][1]; + rightviolate= 1; + } + } + } + } + } + if(leftviolate || rightviolate) { /* align left handle */ + float h1[3], h2[3]; + + VecSubf(h1, p2-3, p2); + VecSubf(h2, p2, p2+3); + len1= Normalise(h1); + len2= Normalise(h2); + + vz= INPR(h1, h2); + + if(leftviolate) { + *(p2+3)= *(p2) - vz*len2*h1[0]; + *(p2+4)= *(p2+1) - vz*len2*h1[1]; + *(p2+5)= *(p2+2) - vz*len2*h1[2]; + } + else { + *(p2-3)= *(p2) + vz*len1*h2[0]; + *(p2-2)= *(p2+1) + vz*len1*h2[1]; + *(p2-1)= *(p2+2) + vz*len1*h2[2]; } } diff --git a/source/blender/makesdna/DNA_curve_types.h b/source/blender/makesdna/DNA_curve_types.h index 2078875215f..b5ed8c9102a 100644 --- a/source/blender/makesdna/DNA_curve_types.h +++ b/source/blender/makesdna/DNA_curve_types.h @@ -237,10 +237,11 @@ typedef struct IpoCurve { #define CU_CYCLIC 1 /* h1 h2 (beztriple) */ -#define HD_FREE 0 -#define HD_AUTO 1 -#define HD_VECT 2 -#define HD_ALIGN 3 +#define HD_FREE 0 +#define HD_AUTO 1 +#define HD_VECT 2 +#define HD_ALIGN 3 +#define HD_AUTO_ANIM 4 /* *************** CHARINFO **************** */ diff --git a/source/blender/src/editipo_mods.c b/source/blender/src/editipo_mods.c index 91698300ef5..468e49b3ec8 100644 --- a/source/blender/src/editipo_mods.c +++ b/source/blender/src/editipo_mods.c @@ -588,17 +588,17 @@ void sethandles_ipo(int code) if(G.sipo->ipo && G.sipo->ipo->id.lib) return; switch(code) { - case 1: + case HD_AUTO: /*** Set to auto ***/ selected_bezier_loop(vis_edit_icu_bez, set_bezier_auto, calchandles_ipocurve); break; - case 2: + case HD_VECT: /*** Set to vector ***/ selected_bezier_loop(vis_edit_icu_bez, set_bezier_vector, calchandles_ipocurve); break; - case 4: + case HD_AUTO_ANIM: /* set to enforce autohandles to be horizontal on extremes */ ipo_curves_auto_horiz(); diff --git a/source/blender/src/header_ipo.c b/source/blender/src/header_ipo.c index 1508c61830d..73439ec22bf 100644 --- a/source/blender/src/header_ipo.c +++ b/source/blender/src/header_ipo.c @@ -390,6 +390,9 @@ static void do_ipo_editmenu_handlemenu(void *arg, int event) case 3: sethandles_ipo(HD_VECT); break; + case 4: + sethandles_ipo(HD_AUTO_ANIM); + break; } } @@ -402,6 +405,7 @@ static uiBlock *ipo_editmenu_handlemenu(void *arg_unused) uiBlockSetButmFunc(block, do_ipo_editmenu_handlemenu, NULL); uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Auto|Shift H", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 0, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Auto Clamped|Alt H", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 4, ""); uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Aligned|H", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, ""); uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Free|H", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, ""); uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Vector|V", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 3, ""); @@ -531,6 +535,10 @@ static void do_ipo_editmenu(void *arg, int event) case 6: /*IPO Editmode*/ set_editflag_editipo(); + break; + case 7: + sethandles_ipo(HD_AUTO_ANIM); + break; } } @@ -587,9 +595,10 @@ static uiBlock *ipo_editmenu(void *arg_unused) uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Delete|X", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 0, ""); uiDefIconTextBlockBut(block, ipo_editmenu_joinmenu, NULL, ICON_RIGHTARROW_THIN, "Join", 0, yco-=20, 120, 19, ""); + uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Auto Clamped Handles|ALT H", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 7, ""); + if (!G.sipo->showkey){ - uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, ""); - uiDefIconTextBlockBut(block, ipo_editmenu_extendmenu, NULL, ICON_RIGHTARROW_THIN, "Extend Mode", 0, yco-=20, 120, 19, ""); uiDefIconTextBlockBut(block, ipo_editmenu_intpolmenu, NULL, ICON_RIGHTARROW_THIN, "Interpolation Mode", 0, yco-=20, 120, 20, ""); if(ei != NULL && (ei->flag & IPO_EDIT)) diff --git a/source/blender/src/space.c b/source/blender/src/space.c index db2ae93cb0a..17722bb090e 100644 --- a/source/blender/src/space.c +++ b/source/blender/src/space.c @@ -2076,7 +2076,7 @@ static void winqreadipospace(ScrArea *sa, void *spacedata, BWinEvent *evt) break; case HKEY: if(G.qual==LR_ALTKEY) - sethandles_ipo(4); // tsk tsk ton! + sethandles_ipo(HD_AUTO_ANIM); if(G.qual==LR_SHIFTKEY) sethandles_ipo(HD_AUTO); else if(G.qual==0)