I want to access the keyframes for a specific bone in animation_data.action, just so I can reset them to a default value. My main problem is I dont know how to just access a specific bone.
The general purpose of this is to automatically reset the hand positions of bvh animation loaded onto a manuelbastionilab model. The bvh animation loads it in fine, but because there isnt really any hand data, it sets the animation to a default splayed out position. And because it assigns it to the wrong bones, it comes in with a crooked little finger. So I just want a simple python script to reset any animations I load in to a good default.
I think I should be able to get to the animation data for the keyframes with
myaction = bpy.context.active_object.animation_data.action
But I dont know what comes next, I dont know how to access the fcurves for a specific bone like a joint / bone in my little finger called pinky02_L
This seems incredibly basic but Ive spent ages googling it and failed miserably.
I suspect I might have problems with setting the data too ! I am using quaternions and so I want to access say the z rotation quaternion. So how do I access the z rot channel, I think its some array offset for the fcurve or something ? So once I have found the fcurve for pinky02l (pinky02lfcurve = ?), is it something like curve = pinky02lfcurve to access the z rotation channel ? Or have I got it all horribly wrong ?
keyframePoints = curve.keyframe_points for keyframe in keyframePoints:
And Once I have a keyframe how do I set it to a value like :
keyframe.value = math.radians(8.0)
. Is it that simple ? I bet its not!
Any answers to any parts of this would be great ! p.s. thank you to batFinger and Scott Milner for answering my question about it setting it to the wrong degrees the other day.
So from the post lemon refers too I if I am understanding it correctly if I use:
for curve in pinky02lfcurve if curve.data_path.endswith('rotation_quaternion') if curve.array_index == 2 # or is it 3 for z with quaternions ? keyframePoints = curve.keyframe_points for keyframe in keyframePoints: keyframe.co = math.radians(8.0)
Ok so re writing to take into account batFingers post I think the following should do what I want !
myaction = bpy.context.active_object.animation_data.action fcurves = myaction.fcurves rot = Euler(0,0,8) myquat = rot.to_quaternion() pinkyb = bpy.data.objects['MyArmature'].pose.bones['pinky02_L'] dpath = pinkyb.path_from_id("rotation_quaternion") fc = fcurves.find(dpath, index=0) keyframePoints = fc.keyframe_points for keyframe in keyframePoints: keyframe.co = myquat.w fc = fcurves.find(dpath, index=1) keyframePoints = fc.keyframe_points for keyframe in keyframePoints: keyframe.co = myquat.x fc = fcurves.find(dpath, index=2) keyframePoints = fc.keyframe_points for keyframe in keyframePoints: keyframe.co = myquat.y fc = fcurves.find(dpath, index=3) keyframePoints = fc.keyframe_points for keyframe in keyframePoints: keyframe.co = myquat.z
So I hope this should be good apart from the curve control points which are still at their original positions I think. Though I also still need to work out what angle I actually want to set it too ! Thanks again batFinger and lemon.