diff options
author | Joshua Leung <aligorith@gmail.com> | 2007-01-14 12:30:04 +0300 |
---|---|---|
committer | Joshua Leung <aligorith@gmail.com> | 2007-01-14 12:30:04 +0300 |
commit | 444246d016e3be6d943707f5a01db20040c35afa (patch) | |
tree | afdd78b9b598d7526a4706ab42b1250767b5395d | |
parent | 1807fb24845d65946211e2086a0f2a1b743f943f (diff) |
== IPO Cleaning ==
Rewrote the core-function responsible for ipo-cleaning. Now, it is in a less
wacko form. What is still not done is the conversion of a bunch of points
describing an arc to an arc defined by the handles of the keyframes on
either side of the arc. That will have to wait for the next development cycle.
This rewrite fixes two big bugs with the code:
* All but first curve got hidden aften cleaning
* Cleaning a curve with only two verts resulted in only one vert, even though
the values were not the same.
-rw-r--r-- | source/blender/blenkernel/BKE_utildefines.h | 2 | ||||
-rw-r--r-- | source/blender/src/editipo.c | 140 |
2 files changed, 69 insertions, 73 deletions
diff --git a/source/blender/blenkernel/BKE_utildefines.h b/source/blender/blenkernel/BKE_utildefines.h index 232a2a2cd9e..81dd2807812 100644 --- a/source/blender/blenkernel/BKE_utildefines.h +++ b/source/blender/blenkernel/BKE_utildefines.h @@ -115,6 +115,8 @@ #define IS_EQ(a,b) ((fabs((double)(a)-(b)) >= (double) FLT_EPSILON) ? 0 : 1) +#define IS_EQT(a, b, c) ((a > b)? (((a-b) <= c)? 1:0) : ((((b-a) <= c)? 1:0))) +#define IN_RANGE(a, b, c) ((b < c)? ((b<a && a<c)? 1:0) : ((c<a && a<b)? 1:0)) /* this weirdo pops up in two places ... */ #if !defined(WIN32) && !defined(__BeOS) diff --git a/source/blender/src/editipo.c b/source/blender/src/editipo.c index f040abe7343..d3a4abbaf6a 100644 --- a/source/blender/src/editipo.c +++ b/source/blender/src/editipo.c @@ -3112,7 +3112,7 @@ void clean_ipo(void) void clean_ipo_curve(IpoCurve *icu) { BezTriple *bezt=NULL, *beztn=NULL; - BezTriple *newb, *newbs, *newbz; + BezTriple *newb, *newbs; int totCount, newCount, i; float thresh; @@ -3123,94 +3123,88 @@ void clean_ipo_curve(IpoCurve *icu) if (totCount<=1) return; /* get threshold for match-testing */ - if ((G.scene) && (G.scene->toolsettings)) - thresh= G.scene->toolsettings->clean_thresh; - else - thresh= 0.1f; + thresh= G.scene->toolsettings->clean_thresh; - /* pointers to points */ + /* add first keyframe and setup tempolary array of beztriples */ newb = newbs = MEM_callocN(sizeof(BezTriple)*totCount, "NewBeztriples"); bezt= icu->bezt; *newb= *bezt; bezt++; - if (totCount > 2) beztn= (bezt + 1); /* loop through beztriples, comparing them */ - for (i=0; i<totCount; i++) { - float timeAB, valAB, valAC; - short hasC, hasD; - - /* precalculate the differences in values */ - timeAB= fabs(bezt->vec[1][0] - newb->vec[1][0]); - valAB= fabs(bezt->vec[1][1] - newb->vec[1][1]); - if (beztn!=NULL) { - valAC= fabs(beztn->vec[1][1] - newb->vec[1][1]); - hasC= 1; + for (i=0; i<totCount && newCount<totCount; i++, bezt++) { + float prev[2], cur[2], next[2]; + + /* get references for quicker access */ + memcpy(prev, newb->vec[1], 8); + memcpy(cur, bezt->vec[1], 8); + + if (i < (totCount - 1)) { + beztn = (bezt + 1); + memcpy(next, beztn->vec[1], 8); } else { - valAC= 0.0f; - hasC= 0; + beztn = NULL; + next[0] = next[1] = 0.0f; } - hasD= ((i+2) < totCount)?1:0; - - /* determine what to do with bezt */ - if ((timeAB <= thresh) && (valAB <= thresh)) { - /* same time and value - set bezt to beztn */ - if (hasC) - bezt++; - else - break; - if (hasD) - beztn++; - else - beztn= NULL; - } - else if ((valAB <= thresh) && (hasC) && (valAC <= thresh)) { - /* three consecutive values - set bezt to beztn */ - if (hasC) - bezt++; - else - break; - if (hasD) - beztn++; - else - beztn= NULL; + + /* check if current bezt occurs at same time as last ok */ + if ((cur[0] - prev[0]) <= thresh) { + /* only add if values are a considerable distance apart */ + if (IS_EQT(cur[1], prev[1], thresh) == 0) { + /* add new keyframe */ + newCount++; + newb++; + *newb = *bezt; + } } - else if (hasC) { - /* fine to add */ - newb++; - *newb= *bezt; - newCount++; - - if (hasC) - bezt++; - else - break; - if (hasD) - beztn++; - else - beztn= NULL; - } else { - /* no more */ - break; + /* checks required are dependent on whether this is last keyframe or not */ + if (beztn) { + /* does current have same value as previous and next? */ + if (IS_EQT(cur[1], prev[1], thresh) == 0) { + /* add new keyframe*/ + newb++; + *newb = *bezt; + newCount++; + } + else if (IS_EQT(cur[1], next[1], thresh) == 0) { + /* add new keyframe */ + newb++; + *newb = *bezt; + newCount++; + } + } + else { + /* add if value doesn't equal that of previous */ + if (IS_EQT(cur[1], prev[1], thresh) == 0) { + /* add new keyframe */ + newb++; + *newb = *bezt; + newCount++; + } + } } } - /* make better sized list */ - newbz= MEM_callocN(sizeof(BezTriple)*newCount, "BezTriples"); - for (i=0; i<newCount; i++) { - BezTriple *atar, *bsrc; - atar= (newbz + i); - bsrc= (newbs + i); - *atar= *bsrc; + /* we only need to free stuff if the number of verts changed */ + if (totCount != newCount) { + BezTriple *newbz; + + /* make better sized list */ + newbz= MEM_callocN(sizeof(BezTriple)*newCount, "BezTriples"); + memcpy(newbz, newbs, sizeof(BezTriple)*newCount); + + /* free and assign new */ + MEM_freeN(icu->bezt); + MEM_freeN(newbs); + icu->bezt= newbz; + icu->totvert= newCount; + } + else { + /* free memory we used */ + MEM_freeN(newbs); } - - /* free and assign new */ - MEM_freeN(icu->bezt); - MEM_freeN(newbs); - icu->bezt= newbz; - icu->totvert= newCount; /* fix up handles and make sure points are in order */ sort_time_ipocurve(icu); |