The solution is rather simple.
You need to add Bone Constraint -> Copy Transforms to armature without animation. As Target add armature with animation, and as a Bone, bone with the same name. Rinse and repeat for all bones.
Here is the code that automates all:
- Creates constraints and link bones with other armature
- Iterate over all frames, apply transform, and insert keyframes for all bones
- Delete constrains
Just fill source and target armature, and animation from and to.
Moreover, you can just call add_constraints() function which will link armatures and bones.
import bpy
source = "Bip001"
target = "Bip001.001"
frame_from = 0
frame_to = 35
# add constrains and link them with target bones
def add_constraints():
global source, target
source_ob = bpy.data.objects[source]
for bone in source_ob.pose.bones:
sel_bone=source_ob.data.bones[bone.name]
sel_bone.select=True
bpy.context.object.data.bones.active=sel_bone
trans_bone = bpy.context.object.pose.bones[bone.name]
if trans_bone.constraints.find('Copy Transforms') == -1:
if bpy.data.objects[target].pose.bones.get(bone.name) is not None:
bpy.ops.pose.constraint_add(type='COPY_TRANSFORMS')
trans_bone.constraints["Copy Transforms"].target = bpy.data.objects[target]
trans_bone.constraints["Copy Transforms"].subtarget = bone.name
# delete previously created constrains
def del_constraints( ):
for bone in bpy.context.selected_pose_bones:
copyLocConstraints = [ c for c in bone.constraints if c.type == 'COPY_TRANSFORMS' ]
# Iterate over all the bone's copy location constraints and delete them all
for c in copyLocConstraints:
bone.constraints.remove( c ) # Remove constraint
def apply_animation():
global source, target, frame_from, frame_to
#set keying set to whole character
#we have all bones selected
scene = bpy.context.scene
for frame in range(frame_from, frame_to ):
scene.frame_current = frame
scene.frame_set(scene.frame_current)
# apply visual transfrom to pose Ctrl+A
bpy.ops.pose.visual_transform_apply()
# insert all keyframes -> press I
bpy.ops.anim.keyframe_insert_menu(type='__ACTIVE__', confirm_success=True)
def select_all_bones():
global source, target
ob = bpy.data.objects[source]
for bone in ob.pose.bones:
b=ob.data.bones[bone.name]
b.select=True
bpy.context.object.data.bones.active=b
ks = bpy.data.scenes["Scene"].keying_sets_all
ks.active = ks['Whole Character']
ob = bpy.data.objects[source]
# uncomment line below if you are using Blender version below 2.8 and comment out 2nd line
#bpy.context.scene.objects.active = ob
bpy.context.view_layer.objects.active = ob
bpy.ops.object.mode_set(mode='POSE')
#select_all_bones()
add_constraints()
apply_animation()
del_constraints()