Ben Traje
← Back to maya

Get Joints Copy Skin Weights

05 Jun 26 (18d ago)

Basically, just one script to do two things:

  1. Get the ordered selection. First is the driver. Second the driven
  2. Get the skinned joints of the driver then bind it to the driven
  3. Then do a typical copy skin weights command.

Pretty simple to be honest, but I do this a lot specially when doing some proxy geometry to block weights or doing isolated weights (for meshes that have multiple components/parts/props etc)

import maya.cmds as cmds
import maya.mel as mel

def transfer_skin_weights():
    # Store selection
    selection = cmds.ls(selection=True)

    # Check to ensure exactly two objects are selected
    if len(selection) != 2:
        cmds.error("Please select exactly two objects: 1) Driver (skinned), 2) Driven (unskinned).")

    driver = selection[0]
    driven = selection[1]

    # Helper function to find skin cluster using MEL's built-in finder
    def get_skin_cluster(obj):
        skin = mel.eval('findRelatedSkinCluster("{}")'.format(obj))
        return skin if skin else None

    driver_skin = get_skin_cluster(driver)
    driven_skin = get_skin_cluster(driven)

    # Validate skin clusters
    if not driver_skin:
        cmds.error("Driver object '{}' doesn't have a skinCluster.".format(driver))
        
    if driven_skin:
        cmds.error("Driven object '{}' already has a skinCluster. Unbind it first.".format(driven))

    # Get all joints influencing the driver's skinCluster
    bind_joints = cmds.skinCluster(driver_skin, query=True, influence=True)

    # Bind the driven object to the acquired joints
    # toSelectedBones=True ensures it only uses the exact joints from the driver
    new_skin_nodes = cmds.skinCluster(
        bind_joints, 
        driven, 
        toSelectedBones=True, 
        bindMethod=0,       # Closest distance
        skinMethod=0,       # Classic linear
        normalizeWeights=1  # Interactive
    )
    
    new_skin = new_skin_nodes[0]

    # Copy skin weights from driver to driven
    cmds.copySkinWeights(
        sourceSkin=driver_skin,
        destinationSkin=new_skin,
        noMirror=True,
        surfaceAssociation='closestPoint',
        influenceAssociation=['name', 'closestJoint', 'oneToOne']
    )

    print("Success: Bound '{}' to driver joints and copied skin weights from '{}'.".format(driven, driver))

# Execute the function
transfer_skin_weights()