I have four meshes with shape keys. Two cubes and two spheres. Across all meshes, the shape key names are identical and transform the meshes in similar ways. The shape keys on the first cube and the first sphere are animated with keyframes. Using this script (curtesey of @Harry McKenzie), it is possible to copy over the animated shape keys from Cube 1 to Cube 2 and from Sphere 1 to Sphere 2, because they have matching vertex counts respectively.
def copy_shape_keys(src, tgt):
# Throw error if vertex count doesn't match
if len(src.data.vertices) != len(tgt.data.vertices):
raise RuntimeError('Objects have different vertex count!')
# Delete all shape keys of the target mesh
if tgt.data.shape_keys:
for key in tgt.data.shape_keys.key_blocks:
tgt.shape_key_remove(key)
keys = src.data.shape_keys
for key in keys.key_blocks:
# Rebuild shape keys of target mesh using vertex data from source mesh
k = tgt.shape_key_add(name=key.name, from_mix=False)
for i, v in enumerate(src.data.vertices):
k.data[i].co = key.data[i].co
k.value = key.value
# Create new action for every animated shape key
data = tgt.data.shape_keys.animation_data_create()
data.action = bpy.data.actions.new(name=key.name+"_action")
# Copy fcurves from source to target
for fc in keys.animation_data.action.fcurves:
tgt_fc = data.action.fcurves.new(data_path=fc.data_path)
for kf in fc.keyframe_points:
tgt_fc.keyframe_points.insert(kf.co.x, kf.co.y)
source_obj = bpy.data.objects.get("Cube 1")
target_obj = bpy.data.objects.get("Cube 2")
copy_shape_keys(source_obj, target_obj)
Because this script relies on a perfect topology match, it fails to copy the animated shape keys from Cube 1 to any sphere or from Sphere 1 to any cube.
How can this script be altered to allow all scenarios to work? In other words: How can this script be altered to only look at the shape key names, and not vertex data from other meshes, to copy over keyframes?
This question is a follow up to this thread.

