Transfer Skin Vertex Weights in Blender
04 May 26 (2d ago)
The skin weights in Blender are stored in the vertex groups. Interestingly. vertex groups are not exclusive to vertex weights unlike in Maya and Cinema4D. For better or worse, this allows you to manipulate skint weights outside the joint dependency.
For illustration, in Maya or Cinema4D, if you have mesh A bound to joint A, B, C D, and you delete joint A, B, C, D (or the rig if you will), you will lose the skin weights. To keep a copy of it, you need to store in an external file like the Deformer>Export Weights command
In Blender, even if you delete the rig, you still have skin weights, since it is just in vertex groups. And if you want to store it into external file, you can freely do so with API. Nothing stop you.
But the mere fact that there is independence of skin weights and joint objects gives some interesting behaviour.
Anyway, this article is not about that. LOL
To transfer vertex weights in Blender, you can just hit Ctrl+L > Transfer Mesh Data > Vertex Groups.
Or if you are after more complicated process such as transferring weights that do not have equal point count, you need to add a Data Transfer modifier and just bake the modifier result
The script below is just the Ctrl+L version but checks if both meshes have the same count. Just for sanity sake when dealing with multiple minor versions of the same mesh.
import bpy
def transfer_vertex_groups():
# Get all currently selected objects
selected = bpy.context.selected_objects
# 1. Check if exactly two objects are selected
if len(selected) != 2:
print("Error: You must select exactly two objects.")
return
# 2. Determine Source (Driver) and Target (Driven)
# The last selected object becomes the active object in Blender.
target_obj = bpy.context.active_object
source_obj = selected[0] if selected[1] == target_obj else selected[1]
# 3. Ensure both objects are meshes
if source_obj.type != 'MESH' or target_obj.type != 'MESH':
print("Error: Both selected objects must be meshes.")
return
# 4. Check if vertex counts match exactly
source_verts = len(source_obj.data.vertices)
target_verts = len(target_obj.data.vertices)
if source_verts != target_verts:
print(f"Error: Vertex count mismatch! Source has {source_verts}, Target has {target_verts}.")
return
print(f"Transferring vertex groups from '{source_obj.name}' to '{target_obj.name}'...")
# Clear existing vertex groups on the target to ensure a clean 1:1 transfer
target_obj.vertex_groups.clear()
# 5. Recreate the empty vertex groups on the target object
for vg in source_obj.vertex_groups:
target_obj.vertex_groups.new(name=vg.name)
# 6. Iterate through vertices and transfer the exact weights
for v in source_obj.data.vertices:
for g in v.groups:
# Identify the group name and the weight on the source vertex
group_name = source_obj.vertex_groups[g.group].name
weight = g.weight
# Find the matching group on the target and assign the exact same weight to the matching vertex index
target_vg = target_obj.vertex_groups.get(group_name)
if target_vg is not None:
target_vg.add([v.index], weight, 'REPLACE')
print("Success: Vertex group transfer complete!")
# Execute the function
transfer_vertex_groups()