[Bf-extensions-cvs] [9c2c541] master: Fix T45487: fbx exporting weird keyframes.

Bastien Montagne noreply at git.blender.org
Sun Jul 19 15:41:16 CEST 2015


Commit: 9c2c5413b26d7664b780ef42c21eea7826c6dc5f
Author: Bastien Montagne
Date:   Sun Jul 19 12:56:17 2015 +0200
Branches: master
https://developer.blender.org/rBA9c2c5413b26d7664b780ef42c21eea7826c6dc5f

Fix T45487: fbx exporting weird keyframes.

Previous 'simplifying' code was not handling correctly micro-fluctuations around zero
(caused by ugly float precision issues). Rewrote it more or less completely,
new code is simpler and only based on relative difference (by default, it
keys each time the diff is above 1e-4, and above 1e-4 * magnitude_of_values).

Might produce more keys in some cases, but at least 'noise' shall never be
exported again.

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

M	io_scene_fbx/__init__.py
M	io_scene_fbx/fbx_utils.py

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

diff --git a/io_scene_fbx/__init__.py b/io_scene_fbx/__init__.py
index 119e8ed..243c9a2 100644
--- a/io_scene_fbx/__init__.py
+++ b/io_scene_fbx/__init__.py
@@ -21,7 +21,7 @@
 bl_info = {
     "name": "FBX format",
     "author": "Campbell Barton, Bastien Montagne, Jens Restemeier",
-    "version": (3, 5, 1),
+    "version": (3, 5, 2),
     "blender": (2, 74, 0),
     "location": "File > Import-Export",
     "description": "FBX IO meshes, UV's, vertex colors, materials, textures, cameras, lamps and actions",
@@ -409,7 +409,8 @@ class ExportFBX(bpy.types.Operator, ExportHelper, IOFBXOrientationHelper):
     bake_anim_simplify_factor = FloatProperty(
             name="Simplify",
             description="How much to simplify baked values (0.0 to disable, the higher the more simplified)",
-            min=0.0, max=10.0,  # No simplification to up to 0.05 slope/100 max_frame_step.
+            min=0.0, max=100.0,  # No simplification to up to 10% of current magnitude tolerance.
+            soft_min=0.0, soft_max=10.0,
             default=1.0,  # default: min slope: 0.005, max frame step: 10.
             )
     # Anim - 6.1
diff --git a/io_scene_fbx/fbx_utils.py b/io_scene_fbx/fbx_utils.py
index c4ae338..56442a3 100644
--- a/io_scene_fbx/fbx_utils.py
+++ b/io_scene_fbx/fbx_utils.py
@@ -770,49 +770,43 @@ class AnimationCurveNodeWrapper:
     def simplify(self, fac, step, force_keep=False):
         """
         Simplifies sampled curves by only enabling samples when:
-            * their values differ significantly from the previous sample ones, or
-            * their values differ significantly from the previous validated sample ones, or
-            * the previous validated samples are far enough from current ones in time.
+            * their values relatively differ from the previous sample ones.
         """
         if not self._keys:
             return
 
         # So that, with default factor and step values (1), we get:
-        max_frame_diff = step * fac * 10  # max step of 10 frames.
-        value_diff_fac = fac / 1000  # min value evolution: 0.1% of whole range.
-        min_significant_diff = 1.0e-5
+        min_reldiff_fac = fac * 1.0e-3  # min relative value evolution: 0.1% of current 'order of magnitude'.
+        min_absdiff_fac = 0.1  # A tenth of reldiff...
         keys = self._keys
 
-        extremums = tuple((min(values), max(values)) for values in zip(*(k[1] for k in keys)))
-        min_diffs = tuple(max((mx - mn) * value_diff_fac, min_significant_diff) for mn, mx in extremums)
-
         p_currframe, p_key, p_key_write = keys[0]
-        p_keyed = [(p_currframe - max_frame_diff, val) for val in p_key]
+        p_keyed = list(p_key)
         are_keyed = [False] * len(p_key)
         for currframe, key, key_write in keys:
             for idx, (val, p_val) in enumerate(zip(key, p_key)):
                 key_write[idx] = False
-                p_keyedframe, p_keyedval = p_keyed[idx]
+                p_keyedval = p_keyed[idx]
                 if val == p_val:
                     # Never write keyframe when value is exactly the same as prev one!
                     continue
-                if abs(val - p_val) >= min_diffs[idx]:
+                # This is contracted form of relative + absolute-near-zero difference:
+                #     absdiff = abs(a - b)
+                #     if absdiff < min_reldiff_fac * min_absdiff_fac:
+                #         return False
+                #     return (absdiff / ((abs(a) + abs(b)) / 2)) > min_reldiff_fac
+                # Note that we ignore the '/ 2' part here, since it's not much significant for us.
+                if abs(val - p_val) > (min_reldiff_fac * max(abs(val) + abs(p_val), min_absdiff_fac)):
                     # If enough difference from previous sampled value, key this value *and* the previous one!
                     key_write[idx] = True
                     p_key_write[idx] = True
-                    p_keyed[idx] = (currframe, val)
+                    p_keyed[idx] = val
+                    are_keyed[idx] = True
+                elif abs(val - p_keyedval) > (min_reldiff_fac * max((abs(val) + abs(p_keyedval)), min_absdiff_fac)):
+                    # Else, if enough difference from previous keyed value, key this value only!
+                    key_write[idx] = True
+                    p_keyed[idx] = val
                     are_keyed[idx] = True
-                else:
-                    frame_diff = currframe - p_keyedframe
-                    val_diff = abs(val - p_keyedval)
-                    if ((val_diff >= min_diffs[idx]) or
-                        ((val_diff >= min_significant_diff) and (frame_diff >= max_frame_diff))):
-                        # Else, if enough difference from previous keyed value
-                        # (or any significant difference and max gap between keys is reached),
-                        # key this value only!
-                        key_write[idx] = True
-                        p_keyed[idx] = (currframe, val)
-                        are_keyed[idx] = True
             p_currframe, p_key, p_key_write = currframe, key, key_write
 
         # If we write nothing (action doing nothing) and are in 'force_keep' mode, we key everything! :P



More information about the Bf-extensions-cvs mailing list