I have two armatures with different rest pose I wonder if there is a proper way to copy the animation from on the other as shown in the image.

Here is an example of the blend file https://ufile.io/7h1l48gv

enter image description here

this the code attempt for one frame but it didn't work as expected .

pos_bones = bpy.data.objects["Uncorrect"].pose.bones
pos_bones1 = bpy.data.objects["Correct"].pose.bones

for bon in range(0,len(pos_bones)):
    bone = pos_bones[bon]
    matrixPoseOrignal = pos_bones1[bon].matrix
    matrixLocalChanged = bpy.data.objects["Uncorrect"].data.bones[bone.name].matrix_local

    bone.matrix = matrixLocalChanged
    mat = matrixPoseOrignal.inverted() @ bone.matrix
    bone.matrix = mat

1 Answer 1


Make constraints to visualize, then convert.

Not at all sure how the code in question is going to even be close to what you wish to achieve.

Would look at doing something akin to answer here.

PoseBone local rotation values to global with axis changed

The last example of which shows how to run thru pose bones, convert space, change the alignment and convert back.

Create pose from existing armature

This one has two armatures with two distinct rest poses, (the one with animation is an abomination) To create the animation on t pose rig from other have added constraints to copy the transforms from source to target, then loop thru and create the animation.

For your example since the bones are not using same axes, could instead copy location to but "Incorrect" bones heads at "Correct" bones heads, and use a track to constraint.

Script to constraint target pose bones to source.

import bpy
from math import pi
context = bpy.context
scene = context.scene

source = scene.objects.get("Correct")
# Incorrect (sp)
target = scene.objects.get("Uncorrect")
target.animation_data_clear() # remove any ad

for pbc, pbi in zip(source.pose.bones, target.pose.bones):
    # clear  for testing
    while pbi.constraints:

    # locations
    cl = pbi.constraints.new('COPY_LOCATION')
    cl.target = pbc.id_data
    cl.subtarget = pbc.name
    cl.owner_space = 'POSE'
    cl.target_space = 'POSE'
    # rotations
    tt = pbi.constraints.new('TRACK_TO')
    tt.target = pbc.id_data
    tt.subtarget = pbc.name
    tt.owner_space = 'POSE'
    tt.target_space = 'POSE' 
    tt.head_tail = 1
    tt.track_axis = 'TRACK_X'
    tt.up_axis = 'UP_Z'
    tt.use_target_z = True  

Script to convert constraints to keyframe animation

import bpy
from math import pi
context = bpy.context
scene = context.scene

remove_constraints = True

source = scene.objects.get("Correct")
# Incorrect (sp)
target = scene.objects.get("Uncorrect")

action = source.animation_data.action

f = action.frame_range.x
# add a keyframe to each frame of new rig
while f <= action.frame_range.y:
    r2 = target.evaluated_get(context.evaluated_depsgraph_get())
    for pb in target.pose.bones:
        #pb2 = rig1.pose.bones.get(pb.name)
        m = r2.convert_space(
        if pb.rotation_mode == 'QUATERNION':
            pb.rotation_quaternion = m.to_quaternion()
            pb.keyframe_insert("rotation_quaternion", frame=f)

        # add rot mode checking 
            pb.rotation_euler = m.to_euler(pb.rotation_mode)
            pb.keyframe_insert("rotation_euler", frame=f)
        pb.location = m.to_translation()

        pb.keyframe_insert("location", frame=f)
    f += 1

for pb in target.pose.bones:
    # clear  for testing
    while pb.constraints:
  • $\begingroup$ that is a great and works as expected but in some cases the track axis for some bones need to change from X and Y to fix some deformation is there any way to know which the bones needs a different track axis as you can see in this image pasteboard.co/JZJg6uR.png $\endgroup$
    – A bou
    Apr 30, 2021 at 13:30
  • $\begingroup$ Do they flip or are they consistently the other way? If latter could prob test via rest poses, or make a dictionary source - > target My initial idea was to use transform mapping constraint, as wondered if this could be an issue with track to. $\endgroup$
    – batFINGER
    Apr 30, 2021 at 13:42
  • $\begingroup$ will send you the full armature to check one second $\endgroup$
    – A bou
    Apr 30, 2021 at 13:49
  • $\begingroup$ here it's ufile.io/a8sb781a check it out and thank you again $\endgroup$
    – A bou
    Apr 30, 2021 at 13:54
  • $\begingroup$ if there is no solution for that i can accept this as solution for now $\endgroup$
    – A bou
    May 3, 2021 at 16:29

You must log in to answer this question.

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