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
$\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$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.