diff options
author | Chris Want <cwant@ualberta.ca> | 2003-01-28 06:11:27 +0300 |
---|---|---|
committer | Chris Want <cwant@ualberta.ca> | 2003-01-28 06:11:27 +0300 |
commit | 53b540c627a5667b20807fb3d5f88a3f8cb3d018 (patch) | |
tree | ae8678b4c4f8063fd0410bbf7a716f82695be3c3 /source/blender/src/editipo.c | |
parent | 30861557bcbb0054d552dc4f262eb2164cc092d9 (diff) |
Added support for manipulating Ipo bezier handles through
the action window. Selecting action keys and pressing VKEY,
HKEY, or shift-HKEY modifies the handles of the keys in
the same way it does in the IPO window. (suggested by Lyubomir)
Diffstat (limited to 'source/blender/src/editipo.c')
-rw-r--r-- | source/blender/src/editipo.c | 329 |
1 files changed, 277 insertions, 52 deletions
diff --git a/source/blender/src/editipo.c b/source/blender/src/editipo.c index ba9a9ae8e4c..c5923cbe83c 100644 --- a/source/blender/src/editipo.c +++ b/source/blender/src/editipo.c @@ -2663,76 +2663,301 @@ void mouse_select_ipo() } } -void sethandles_ipo(int code) +int icu_keys_bezier_loop(IpoCurve *icu, + int (*bezier_function)(BezTriple *), + void (ipocurve_function)(struct IpoCurve *icu)) { - /* code==1: set autohandle */ - /* code==2: set vectorhandle */ - /* als code==3 (HD_ALIGN) toggelt het, vectorhandles worden HD_FREE */ + /* This loops through the beziers in the Ipocurve, and executes + * the generic user provided 'bezier_function' on each one. + * Optionally executes the generic function ipocurve_function on the + * IPO curve after looping (eg. calchandles_ipocurve) + */ + + int b; + BezTriple *bezt; + + b = icu->totvert; + bezt = icu->bezt; + + /* if bezier_function has been specified + * then loop through each bezier executing + * it. + */ + + if (bezier_function != NULL) { + while(b--) { + /* exit with return code 1 if the bezier function + * returns 1 (good for when you are only interested + * in finding the first bezier that + * satisfies a condition). + */ + if (bezier_function(bezt)) return 1; + bezt++; + } + } + + /* if ipocurve_function has been specified + * then execute it + */ + if (ipocurve_function != NULL) + ipocurve_function(icu); + + return 0; + +} + +int ipo_keys_bezier_loop(Ipo *ipo, + int (*bezier_function)(BezTriple *), + void (ipocurve_function)(struct IpoCurve *icu)) +{ + /* This loops through the beziers that are attached to + * the selected keys on the Ipocurves of the Ipo, and executes + * the generic user provided 'bezier_function' on each one. + * Optionally executes the generic function ipocurve_function on a + * IPO curve after looping (eg. calchandles_ipocurve) + */ + + IpoCurve *icu; + + /* Loop through each curve in the Ipo + */ + for (icu=ipo->curve.first; icu; icu=icu->next){ + if (icu_keys_bezier_loop(icu,bezier_function, ipocurve_function)) + return 1; + } + + return 0; +} + +int selected_bezier_loop(int (*looptest)(EditIpo *), + int (*bezier_function)(BezTriple *), + void (ipocurve_function)(struct IpoCurve *icu)) +{ + /* This loops through the beziers that are attached to + * selected keys in editmode in the IPO window, and executes + * the generic user-provided 'bezier_function' on each one + * that satisfies the 'looptest' function. Optionally executes + * the generic function ipocurve_function on a IPO curve + * after looping (eg. calchandles_ipocurve) + */ + EditIpo *ei; BezTriple *bezt; - int a, b, ok=0; + int a, b; - if(G.sipo->ipo && G.sipo->ipo->id.lib) return; + /* Get the first Edit Ipo from the selected Ipos + */ + ei= G.sipo->editipo; - if(code==1 || code==2) { - ei= G.sipo->editipo; - for(a=0; a<G.sipo->totipo; a++, ei++) { - if ISPOIN4(ei, flag & IPO_VISIBLE, flag & IPO_EDIT, icu, icu->bezt) { - bezt= ei->icu->bezt; - b= ei->icu->totvert; + /* Loop throught all of the selected Ipo's + */ + for(a=0; a<G.sipo->totipo; a++, ei++) { + /* Do a user provided test on the Edit Ipo + * to determine whether we want to process it + */ + if (looptest(ei)) { + /* Loop through the selected + * beziers on the Edit Ipo + */ + bezt = ei->icu->bezt; + b = ei->icu->totvert; + + /* if bezier_function has been specified + * then loop through each bezier executing + * it. + */ + if (bezier_function != NULL) { while(b--) { - if(bezt->f1 || bezt->f3) { - if(bezt->f1) bezt->h1= code; - if(bezt->f3) bezt->h2= code; - - if(bezt->h1!=bezt->h2) { - if ELEM(bezt->h1, HD_ALIGN, HD_AUTO) bezt->h1= HD_FREE; - if ELEM(bezt->h2, HD_ALIGN, HD_AUTO) bezt->h2= HD_FREE; - } - } + /* exit with return code 1 if the bezier function + * returns 1 (good for when you are only interested + * in finding the first bezier that + * satisfies a condition). + */ + if (bezier_function(bezt)) return 1; bezt++; } - calchandles_ipocurve(ei->icu); } + + /* if ipocurve_function has been specified + * then execute it + */ + if (ipocurve_function != NULL) + ipocurve_function(ei->icu); } + /* nufte flourdje zim ploopydu <-- random dutch looking comment ;) */ } - else { - /* is er 1 handle NIET vrij: alles vrijmaken, else ALIGNED maken */ - - ei= G.sipo->editipo; - for(a=0; a<G.sipo->totipo; a++, ei++) { - if ISPOIN4(ei, flag & IPO_VISIBLE, flag & IPO_EDIT, icu, icu->bezt) { - bezt= ei->icu->bezt; - b= ei->icu->totvert; - while(b--) { - if(bezt->f1 && bezt->h1) ok= 1; - if(bezt->f3 && bezt->h2) ok= 1; - if(ok) break; - bezt++; - } - } + + return 0; +} + +int set_bezier_auto(BezTriple *bezt) +{ + /* Sets the selected bezier handles to type 'auto' + */ + + /* is a handle selected? If so + * set it to type auto + */ + if(bezt->f1 || bezt->f3) { + if(bezt->f1) bezt->h1= 1; /* the secret code for auto */ + if(bezt->f3) bezt->h2= 1; + + /* if the handles are not of the same type, set them + * to type free + */ + if(bezt->h1!=bezt->h2) { + if ELEM(bezt->h1, HD_ALIGN, HD_AUTO) bezt->h1= HD_FREE; + if ELEM(bezt->h2, HD_ALIGN, HD_AUTO) bezt->h2= HD_FREE; } - if(ok) ok= HD_FREE; - else ok= HD_ALIGN; - - ei= G.sipo->editipo; - for(a=0; a<G.sipo->totipo; a++, ei++) { - if ISPOIN4(ei, flag & IPO_VISIBLE, flag & IPO_EDIT, icu, icu->bezt) { - bezt= ei->icu->bezt; - b= ei->icu->totvert; - while(b--) { - if(bezt->f1) bezt->h1= ok; - if(bezt->f3 ) bezt->h2= ok; + } + return 0; +} + +int set_bezier_vector(BezTriple *bezt) +{ + /* Sets the selected bezier handles to type 'vector' + */ + + /* is a handle selected? If so + * set it to type vector + */ + if(bezt->f1 || bezt->f3) { + if(bezt->f1) bezt->h1= 2; /* the code for vector */ + if(bezt->f3) bezt->h2= 2; + + /* if the handles are not of the same type, set them + * to type free + */ + if(bezt->h1!=bezt->h2) { + if ELEM(bezt->h1, HD_ALIGN, HD_AUTO) bezt->h1= HD_FREE; + if ELEM(bezt->h2, HD_ALIGN, HD_AUTO) bezt->h2= HD_FREE; + } + } + return 0; +} + +int bezier_isfree(BezTriple *bezt) +{ + /* queries whether the handle should be set + * to type 'free' (I think) + */ + if(bezt->f1 && bezt->h1) return 1; + if(bezt->f3 && bezt->h2) return 1; + return 0; +} + +int set_bezier_free(BezTriple *bezt) +{ + /* Sets selected bezier handles to type 'free' + */ + if(bezt->f1) bezt->h1= HD_FREE; + if(bezt->f3) bezt->h2= HD_FREE; + return 0; +} + +int set_bezier_align(BezTriple *bezt) +{ + /* Sets selected bezier handles to type 'align' + */ + if(bezt->f1) bezt->h1= HD_ALIGN; + if(bezt->f3) bezt->h2= HD_ALIGN; + return 0; +} + +int vis_edit_icu_bez(EditIpo *ei) { + /* A 4 part test for an EditIpo : + * is it a) visible + * b) in edit mode + * c) does it contain an Ipo Curve + * d) does that ipo curve have a bezier + * + * (The reason why I don't just use the macro + * is I need a pointer to a function.) + */ + return ISPOIN4(ei, flag & IPO_VISIBLE, flag & IPO_EDIT, icu, icu->bezt); +} + +void sethandles_ipo_keys(Ipo *ipo, int code) +{ + /* this function lets you set bezier handles all to + * one type for some Ipo's (e.g. with hotkeys through + * the action window). + */ + + /* code==1: set autohandle */ + /* code==2: set vectorhandle */ + /* als code==3 (HD_ALIGN) toggelt het, vectorhandles worden HD_FREE */ - bezt++; - } - calchandles_ipocurve(ei->icu); - } + switch(code) { + case 1: + /*** Set to auto ***/ + ipo_keys_bezier_loop(ipo, set_bezier_auto, + calchandles_ipocurve); + break; + case 2: + /*** Set to vector ***/ + ipo_keys_bezier_loop(ipo, set_bezier_vector, + calchandles_ipocurve); + break; + default: + if ( ipo_keys_bezier_loop(ipo, bezier_isfree, NULL) ) { + /*** Set to free ***/ + ipo_keys_bezier_loop(ipo, set_bezier_free, + calchandles_ipocurve); + } + else { + /*** Set to align ***/ + ipo_keys_bezier_loop(ipo, set_bezier_align, + calchandles_ipocurve); } + break; } + + +} + +void sethandles_ipo(int code) +{ + /* this function lets you set bezier handles all to + * one type for some selected keys in edit mode in the + * IPO window (e.g. with hotkeys) + */ + + /* code==1: set autohandle */ + /* code==2: set vectorhandle */ + /* als code==3 (HD_ALIGN) toggelt het, vectorhandles worden HD_FREE */ + + if(G.sipo->ipo && G.sipo->ipo->id.lib) return; + + switch(code) { + case 1: + /*** Set to auto ***/ + selected_bezier_loop(vis_edit_icu_bez, set_bezier_auto, + calchandles_ipocurve); + break; + case 2: + /*** Set to vector ***/ + selected_bezier_loop(vis_edit_icu_bez, set_bezier_vector, + calchandles_ipocurve); + break; + default: + if (selected_bezier_loop(vis_edit_icu_bez, bezier_isfree, NULL) ) { + /*** Set to free ***/ + selected_bezier_loop(vis_edit_icu_bez, set_bezier_free, + calchandles_ipocurve); + } + else { + /*** Set to align ***/ + selected_bezier_loop(vis_edit_icu_bez, set_bezier_align, + calchandles_ipocurve); + } + break; + } + editipo_changed(G.sipo, 1); } + void set_ipotype() { EditIpo *ei; |