Clean fcurves

How do I use the bpy.ops.action.clean or bpy.ops.graph.clean from a script using the fcurves collection?

i dont know.
But because you try to play with the fcurves in armature-pose-action,
maybe this could help:


import bpy
from mathutils import *

action = bpy.data.actions["ArmatureAction"]

def print_action(a):
    print(a.name)
    print(a.frame_range)
    print(len(a.fcurves))
    if len(a.fcurves):
        print(a.fcurves[0].data_path)
        print(a.fcurves[0].array_index) #(location 3, rotation 3-4)
        print(len(a.fcurves[0].keyframe_points))
        if len( a.fcurves[0].keyframe_points ):
            print(a.fcurves[0].keyframe_points[0].co)
    
def empty_action(a):
    for f in a.fcurves:
        if len( f.keyframe_points ):
            for p in f.keyframe_points: #use first index, rest will follow
                f.keyframe_points.remove(f.keyframe_points[0])

def copy_action(a, b):
    fn = 0
    for f in a.fcurves:
        d_f = b.fcurves[fn]
        fn += 1
        for p in f.keyframe_points:
            d_f.keyframe_points.add(frame= p.co[0], value= p.co[1])
            
def copy_action_translation(a, b, v=(0.,0.,0.)):
    fn = 0
    for f in a.fcurves:
        d_f = b.fcurves[fn]
        fn += 1
        for p in f.keyframe_points:
            v_add = 0.0
            if "location" in d_f.data_path:
                v_add = v[ d_f.array_index ]
            d_f.keyframe_points.add(frame= p.co[0], value= p.co[1]+v_add)

def get_action_first_location(a, bonename="Bone"):
    v = [0.,0.,0]
    for f in a.fcurves:
        #print(f.data_path)
        if f.data_path == "pose.bones[\"%s\"].location"%(bonename):
            #print(f.array_index)
            if len( f.keyframe_points ):
                v[f.array_index] = f.keyframe_points[0].co[1]
    return(v)
def get_action_last_location(a, bonename="Bone"):
    v = [0.,0.,0]
    for f in a.fcurves:
        #print(f.data_path)
        if f.data_path == "pose.bones[\"%s\"].location"%(bonename):
            #print(f.array_index)
            if len( f.keyframe_points ):
                v[f.array_index] = f.keyframe_points[ len(f.keyframe_points)-1].co[1]
    return(v)

def get_location_object(o):
    return(o.location)                
def get_quaternion_object(o):
    return(o.rotation_quaternion)

def set_action_first_quaternion(a, bonename="Bone", quat=[1.,0.,0.,0.]):
    q = Quaternion()
    for f in a.fcurves:
        if f.data_path == "pose.bones[\"%s\"].rotation_quaternion"%(bonename):
            if len (f.keyframe_points ):
                q[f.array_index] = f.keyframe_points[0].co[1]
    print(q)
# dont know .. bones need to be rotated like what?
#    q = q.cross(quat)
#    print(quat)
#    print(q)
    q = quat
    for f in a.fcurves:
        if f.data_path == "pose.bones[\"%s\"].rotation_quaternion"%(bonename):
            if len (f.keyframe_points ):
                f.keyframe_points[0].co[1] = q[f.array_index]

# duplicate with new name, set name - fails if the action already exists -> .001
a = action.copy()
a.name = "dummy"
a = bpy.data.actions["dummy"]
print_action(a)
empty_action(a)
print_action(a)
copy_action_translation(action, a, (1.,2.,0.))
print(get_action_first_location(a))
print(get_action_last_location(a))

i still want to create a new action based on the old one, but with different orientation, new location and scaling in time …

Hey thanks for the reply…

Interesting a bit of code kinda answered another question where you have done the “bruteforce” compare against “data_path” … it was late when I put up a thread about it and was calling it “rna_path”… It would be handy if you could index from it directly. Well you kinda can using exec but that will give the value for the current frame…

Hey I posted a script that kinda does something similar to actions. It changes the orientation of mocap actions and also normalises them to make the curves relative to linear motion from start point to end point. It’s at http://blenderartists.org/forum/showthread.php?t=204377

I’ve also been dabbling with a script that changes rest pose to match a t-pose… Quat rots have me a little stumped too… but you can toEuler them and change them back… Another handy reference script i have been using is the bvh import script that came with http://blenderartists.org/forum/showthread.php?t=164765&highlight=2.5+sample+scripts

Yet another way to go I’m thinking of is using drivers and a script as discussed with Atom here http://blenderartists.org/forum/showthread.php?t=203982 Wondering if a script attached to a driver passing rotational differences may be the way to go…