From 41b84e4ef00df31043cb2e966173a1ff1ea66f45 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Mon, 13 Nov 2006 10:16:07 +0000 Subject: [PATCH] Previous commit (Smooth Ipo) was indeed not too useful. I've rewritten the code (less code now) so that it is more useful, and doesn't just duplicate the functionality of another feature. Now, IPO smooth works only on the selected keyframes in selected frames. It finds the average value of all the selected keyframes, and finds the halfway point between each keyframe value and this average value. Handles are also automatically set to 'aligned'. --- source/blender/src/editipo.c | 140 ++++++++++------------------------- 1 file changed, 40 insertions(+), 100 deletions(-) diff --git a/source/blender/src/editipo.c b/source/blender/src/editipo.c index f0a5020025a..f0a9edd5826 100644 --- a/source/blender/src/editipo.c +++ b/source/blender/src/editipo.c @@ -3166,92 +3166,6 @@ void clean_ipo_curve(IpoCurve *icu) calchandles_ipocurve(icu); } -static void smooth_bezt_handles(BezTriple *prev, BezTriple *me, BezTriple *next) -{ - /* Smoothes (i.e. aligns) handles on the beztriple called me! - * - * The code here has been adapted from the "Smooth Ipo" - * python script (author unknown). - */ - - float ptA[2], ptB[2], ptC[2]; - float tdx, udx; - float tdy, udy; - float tx, ux; - float max_udy, max_tdy; - float slopu, slopt; - float medianSlope, slope; - float simpleudy, simpletdy; - float ty, uy; - - /* get center-points of beztriples */ - ptA[0]= prev->vec[1][0]; - ptA[1]= prev->vec[1][1]; - ptB[0]= me->vec[1][0]; - ptB[1]= me->vec[1][1]; - if (next != NULL) { - ptC[0]= next->vec[1][0]; - ptC[1]= next->vec[1][1]; - } - else { - ptC[0]= ptB[0] + 1.0f; - ptC[1]= ptB[1]; - } - - /* varios factors (are all of these needed?) */ - tdx= (ptA[0]-ptB[0]) / 3.0f; - udx= (ptC[0]-ptB[0]) / 3.0f; - tx= ptB[0] + tdx; - ux= ptB[0] + udx; - max_udy= ptC[1] - ptB[1]; - max_tdy= ptA[1] - ptB[1]; - - /* compute slopes */ - if ((ptC[0]-ptB[0])==0.0) - slopu= 0.0f; - else - slopu= (ptC[1]-ptB[1]) / (ptC[0]-ptB[0]); - if ((ptA[0]-ptB[0])==0.0) - slopt= 0.0f; - else - slopt= (ptA[1]-ptB[1]) / (ptA[0]-ptB[0]); - if ((slopu*slopt) < 0) { - udy= 0; - tdy= 0; - } - else { - /* compute median slope */ - medianSlope= (slopu+slopt) / 2.0; - simpleudy= medianSlope * udx; - simpletdy= medianSlope * tdx; - - if ((simpleudy < max_udy) && (simpletdy < max_tdy)) { - udy= simpleudy; - tdy= simpletdy; - } - else { - /* use smallest slope */ - slope = (slopu < slopt)?slopu:slopt; - slope = slope * ((slopu < 0)?-1:1); - udy= slope*udx; - tdy= slope*tdx; - } - } - - /* calculate any remaining values */ - ty= ptB[1] + tdy; - uy= ptB[1] + udy; - - /* set new values of the handles of of beztriple being acted on */ - me->vec[0][0]= tx; - me->vec[0][1]= ty; - me->vec[1][0]= ptB[0]; - me->vec[1][1]= ptB[1]; - me->vec[2][0]= ux; - me->vec[2][1]= uy; - me->vec[0][2] = me->vec[1][2] = me->vec[2][2] = 0.0f; -} - void smooth_ipo(void) { EditIpo *ei; @@ -3271,23 +3185,49 @@ void smooth_ipo(void) if(ok) { IpoCurve *icu= ei->icu; + BezTriple *bezt; + float meanValSum = 0.0f, meanVal; + float valDiff; + int i, totSel = 0; /* check if enough points */ - if (icu->totvert <= 3) { - BezTriple *prev, *me, *next; - int i; - - for (i=1; i < icu->totvert; i++) { - /* try to get next point */ - prev = (icu->bezt + (i - 1)); - me = (icu->bezt + i); - if (i < (icu->totvert - 1)) - next = (icu->bezt + (i + 1)); - else - next = NULL; + if (icu->totvert >= 3) { + /* first loop through - obtain average value */ + bezt= icu->bezt; + for (i=1; i < icu->totvert; i++, bezt++) { + if (BEZSELECTED(bezt)) { + /* line point's handles up with point's vertical position */ + bezt->vec[0][1]= bezt->vec[2][1]= bezt->vec[1][1]; + if(bezt->h1==HD_AUTO || bezt->h1==HD_VECT) bezt->h1= HD_ALIGN; + if(bezt->h2==HD_AUTO || bezt->h2==HD_VECT) bezt->h2= HD_ALIGN; - /* smooth handles of current beztriple (me) */ - smooth_bezt_handles(prev, me, next); + /* add value to total */ + meanValSum += bezt->vec[1][1]; + totSel++; + } + } + + /* calculate mean value */ + meanVal= meanValSum / totSel; + + /* second loop through - update point positions */ + bezt= icu->bezt; + for (i=0; i < icu->totvert; i++, bezt++) { + if (BEZSELECTED(bezt)) { + /* 1. calculate difference between the points + * 2. move point half-way along that distance + */ + if (bezt->vec[1][1] > meanVal) { + /* bezt val above mean */ + valDiff= bezt->vec[1][1] - meanVal; + bezt->vec[1][1]= meanVal + (valDiff / 2); + } + else { + /* bezt val below mean */ + valDiff= meanVal - bezt->vec[1][1]; + bezt->vec[1][1] = bezt->vec[1][1] + (valDiff / 2); + } + } } }