[Bf-blender-cvs] [f0ac729] master: Fix T39207: FCurve evaluation regressions following 2aff243

Joshua Leung noreply at git.blender.org
Wed Mar 19 14:24:01 CET 2014


Commit: f0ac7294fafcd12abc83aa706f41af909ddad96d
Author: Joshua Leung
Date:   Thu Mar 20 02:19:35 2014 +1300
https://developer.blender.org/rBf0ac7294fafcd12abc83aa706f41af909ddad96d

Fix T39207: FCurve evaluation regressions following 2aff243

This commit attempts to fix some of the FCurve evaluation regressions arising from
an earlier commit to speed up the process using binary search. Further tweaks may still
be needed though to get this to an acceptable level of reliability (namely, tuning the
threshold defining which keyframes get considered "close together"). Since we're still
in an early stage of the 2.71 dev cycle, for now it's still worth trying to get this
working instead of simply reverting this (which can still be done later if it proves too
problematic).

Specific fixes:
* The previous code was somewhat dangerous in that it allowed out-of-bounds accessing
  of memory when a == 0. It turns out this was more common than originally anticipated
  (as the assert I added here ended up failing in the "action_bug.blend" file in the report)
* Tweaked the code used to test for closely-spaced points so that the "Clive.blend" example
  for driver curves won't fail. The approach used here has the downside though that
  since "exact" uses a might coarser threshold for equality, there may be some precision
  loss issues causing backwards compat issues (namely with closely spaced keyframes, or
  for certain NLA strips).

For now, I've left in some debug prints that can be enabled by running Blender in debug
mode (i.e. "blender -d"), which can provide some useful tuning info should we need to
look more into our approach here.

===================================================================

M	source/blender/blenkernel/intern/fcurve.c

===================================================================

diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c
index 55c6df5..8121293 100644
--- a/source/blender/blenkernel/intern/fcurve.c
+++ b/source/blender/blenkernel/intern/fcurve.c
@@ -2041,20 +2041,21 @@ static float fcurve_eval_keyframes(FCurve *fcu, BezTriple *bezts, float evaltime
 		/* evaltime occurs somewhere in the middle of the curve */
 		/* - use binary search to find appropriate keyframes */
 		a = binarysearch_bezt_index(bezts, evaltime, fcu->totvert, &exact);
-		BLI_assert(a > 0); /* a == 0, prevbezt = invalid access */
+		if (G.f & G_DEBUG) printf("eval fcurve '%s' - %f => %d/%d, %d\n", fcu->rna_path, evaltime, a, fcu->totvert, exact);
 		
-		bezt = bezts;
-		bezt += a;
-		prevbezt = bezt - 1;
+		bezt = bezts + a;
+		prevbezt = (a > 0) ? bezt - 1 : bezt;
 		
 		/* use if the key is directly on the frame, rare cases this is needed else we get 0.0 instead. */
-		/* NOTE: Although we could just check if exact == true here, the thresholds for equality are
-		 *       different (0.01 for exact, vs 1e-8 for SMALL_NUMBER). For backwards compatibility,
-		 *       and to avoid introducing regressions for a few rare cases, let's keep the old
-		 *       method/thresholds here for now.
-		 *       -- Aligorith (2014Mar14)
+		/* XXX: the threshold for "exact" is BEZT_BINARYSEARCH_THRESH (currently 0.01), while older versions
+		 *      used a finer threshold (1e-8 or "SMALL_NUMBER"). In order to avoid problems introduced in
+		 *      2aff243 (such as those mentioned in T39207 - specifically, in the "Clive.blend" example),
+		 *      we need a coarser threshold to avoid this slipping right through. However, 0.01 may be
+		 *      too much when dealing with some driver curves, so we'll need to revisit this in due course
+		 *      when problematic files arise.       
+		 *      -- Aligorith (2014Mar19)
 		 */
-		if (fabsf(bezt->vec[1][0] - evaltime) < SMALL_NUMBER) {
+		if ((fabsf(bezt->vec[1][0] - evaltime) < SMALL_NUMBER) || (exact)) {
 			cvalue = bezt->vec[1][1];
 		}
 		/* evaltime occurs within the interval defined by these two keyframes */
@@ -2102,6 +2103,9 @@ static float fcurve_eval_keyframes(FCurve *fcu, BezTriple *bezts, float evaltime
 				}
 			}
 		}
+		else {
+			if (G.f & G_DEBUG) printf("   ERROR: failed eval - p=%f b=%f, t=%f (%f)\n", prevbezt->vec[1][0], bezt->vec[1][0], evaltime, fabsf(bezt->vec[1][0] - evaltime));
+		}
 	}
 	
 	/* return value */




More information about the Bf-blender-cvs mailing list