Added a euler filter script, to filter out discontineouities in euler curves (e.g...
authorJoseph Eagar <joeedh@gmail.com>
Sun, 14 Feb 2010 03:18:43 +0000 (03:18 +0000)
committerJoseph Eagar <joeedh@gmail.com>
Sun, 14 Feb 2010 03:18:43 +0000 (03:18 +0000)
release/scripts/op/euler_filter.py [new file with mode: 0644]
release/scripts/ui/space_graph.py

diff --git a/release/scripts/op/euler_filter.py b/release/scripts/op/euler_filter.py
new file mode 100644 (file)
index 0000000..f3bd0fa
--- /dev/null
@@ -0,0 +1,64 @@
+from math import *
+import bpy
+from Mathutils import *
+
+def main(context):
+    def cleanupEulCurve(fcv):
+        keys = []
+    
+        for k in fcv.keyframe_points:
+            keys.append([k.handle1.copy(), k.co.copy(), k.handle2.copy()])   
+        print(keys)
+    
+        for i in range(len(keys)):
+            cur = keys[i]
+            prev = keys[i-1] if i > 0 else None
+            next = keys[i+1] if i < len(keys)-1 else None
+    
+            if prev == None:
+                continue
+            
+            th = pi
+            if abs(prev[1][1] - cur[1][1]) >= th: # more than 180 degree jump
+                fac = pi*2
+                if prev[1][1] > cur[1][1]:
+                    while abs(cur[1][1]-prev[1][1]) >= th: # < prev[1][1]:
+                        cur[0][1] += fac
+                        cur[1][1] += fac
+                        cur[2][1] += fac
+                elif prev[1][1] < cur[1][1]:
+                    while abs(cur[1][1]-prev[1][1]) >= th:
+                        cur[0][1] -= fac
+                        cur[1][1] -= fac
+                        cur[2][1] -= fac
+    
+        for i in range(len(keys)):
+            for x in range(2):
+               fcv.keyframe_points[i].handle1[x] = keys[i][0][x]
+               fcv.keyframe_points[i].co[x] = keys[i][1][x]
+               fcv.keyframe_points[i].handle2[x] = keys[i][2][x]
+      
+    flist = bpy.context.active_object.animation_data.action.fcurves
+    for f in flist:
+        if f.selected and f.data_path.endswith("rotation_euler"):
+            cleanupEulCurve(f)
+
+class DiscontFilterOp(bpy.types.Operator):
+    """
+    Fixes the most common causes of gimbal lock in the fcurves of
+    the active bone.
+    """
+    bl_idname = "graph.discont_filter"
+    bl_label = "Filter out discontinuities in the active fcurves"
+
+    def poll(self, context):
+        return context.active_object != None
+
+    def execute(self, context):
+        main(context)
+        return {'FINISHED'}
+
+bpy.types.register(DiscontFilterOp)
+
+if __name__ == "__main__":
+    bpy.ops.graph.discont_filter()
\ No newline at end of file
index 1bbae9978463b528bd97b8d702246902e390f917..16a615d2be7c997f03b11456f0d64cce31760109 100644 (file)
@@ -147,6 +147,9 @@ class GRAPH_MT_channel(bpy.types.Menu):
         layout.operator("anim.channels_expand")
         layout.operator("anim.channels_collapse")
 
+        layout.separator()
+        layout.operator("graph.discont_filter", text="Discontinuity (Euler) Filter")
+
 
 class GRAPH_MT_key(bpy.types.Menu):
     bl_label = "Key"
@@ -182,7 +185,6 @@ class GRAPH_MT_key(bpy.types.Menu):
         layout.operator("graph.copy")
         layout.operator("graph.paste")
 
-
 class GRAPH_MT_key_transform(bpy.types.Menu):
     bl_label = "Transform"