3
$\begingroup$

I'm having issues loading Action from Armature A to Armature B because the first one has Euler rotation bones and the second has Quartenion.

If I manually copy all bones from Armature A and paste on Armature B in pose mode it works great.

but the Armature A bones has over 800 frames and I can't manually copy and paste each one of them.

Is there a way to write a python script to perform this by the Armature name?


I came across this script from this anwer: Question and it works great if the armature of destination has Euler but since it is Quartenion if doesn't rotate. I wanna use the code below but using the copy bones and paste instead of setting attributes.

import bpy

active_obj = bpy.context.object
ad = bpy.context.object.animation_data

properties = [p.identifier for p in ad.bl_rna.properties if not p.is_readonly]
objects = [o for o in bpy.context.selected_objects if o.type == active_obj.type]
objects.remove(active_obj)

for obj in objects :
    if obj.animation_data == None :
        obj.animation_data_create()
    ad2 = obj.animation_data

    for prop in properties:
        setattr(ad2, prop, getattr(ad, prop))
$\endgroup$

1 Answer 1

1
$\begingroup$

Here's an old brute force script of mine to convert euler kfps to quaternion. Note it will add full wxyz keyframes for any frame that has any x, y or z euler rot keyframe point.

import bpy
context = bpy.context
scene = context.scene
arm_obj = context.active_object
#arm_obj = scene.objects.get("ArmatureName") # None if doesn't exist
# all pose bones
for pb in arm_obj.pose.bones:
    if pb.rotation_mode == 'QUATERNION':
        continue
    frames = []
    fcurves = []
    dp = 'pose.bones["%s"].rotation_euler' % pb.name
    for index in [0, 1, 2]:
        # search for rotation euler kfps
        fc = arm_obj.animation_data.action.fcurves.find(dp, index=index)
        # make a list of frames that have euler rot keyframes
        if fc:
            frames.extend([kfp.co[0] for kfp in fc.keyframe_points])
            fcurves.append(fc)
    # run thru and keyframe in 
    for f in set(frames):
        scene.frame_set(f)
        pb.rotation_quaternion = pb.matrix_channel.to_quaternion()
        pb.keyframe_insert("rotation_quaternion", frame=f)

    # clean up by removing euler fcurves (will coexist ok)
    '''
    for fc in fcurves:
        arm_obj.animation_data.fcurves.remove(fc)
    pb.rotation_mode = 'QUATERNION'
    '''
$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .