MEL and Python code to change / reset the bind pose of a skinned mesh in Maya

The MEL procedure below takes the name of a skincluster in input and will set the joint's current position to be the bind pose of the input skin cluster. Both bindPose node and preBindMatrix attribute are updated.

global proc setAttrMatrix(string $attr, float $m[]){
    setAttr ($attr) -type "matrix" $m[0] $m[1] $m[2] $m[3] $m[4] $m[5] $m[6] $m[7] $m[8] $m[9] $m[10] $m[11] $m[12] $m[13] $m[14] $m[15];
}

global proc reset_bindPoseNode_skinCluster(string $skinClusterName)
{
    // Find bind pose node:     
    string $myAttr = $skinClusterName + ".bindPose"; 

    string $connectedNode = "";
    string $connections[] = `listConnections -type "dagPose" -source true -destination false $myAttr`;
    if (size($connections) > 0) {
        $connectedNode = $connections[0];
    }


    // delete bind pose of skincluster:
    if( objExists($connectedNode) )
        delete $connectedNode;

    // Select bones
    string $joints[] = `skinCluster -q -inf $skinClusterName`;

    // Reset prebind matrices    
    int $acc = 0;
    for ($joint in $joints) {
        float $m[] = `getAttr ($joint+".worldInverseMatrix[0]")`;        
        setAttrMatrix( $skinClusterName + ".bindPreMatrix["+$acc+"]", $m );
        $acc = $acc + 1;
    }
    

    // Create a new bind pose node according to selection:
    string $bindPoseNodeName = `dagPose -bp -save -selection $joints`;

    connectAttr ($bindPoseNodeName+".message") ($skinClusterName+".bindPose");
}


reset_bindPoseNode_skinCluster("skinCluster1");

Here the Python code to change the bind pose of your skinned mesh to whatever you wish it to be (just pose the joints to the desired positions before execute this code)

import maya.cmds as cmds
from typing import List
   
def reset_bindPoseNode_skinCluster(skinClusterName : str):
    # Find bind pose node:
    myAttr : str = skinClusterName + ".bindPose"

    connectedNode : str = ""
    connections : List[str] = cmds.listConnections(myAttr, type="dagPose", source=True, destination=False)
    if (connections is not None) and len(connections) > 0:
        connectedNode = connections[0]

    # delete bind pose of skincluster:
    if cmds.objExists(connectedNode):
        cmds.delete(connectedNode)

    # Select bones
    joints : List[str] = cmds.skinCluster(skinClusterName, query=True, inf=True)

    # Reset prebind matrices   
    for i, joint in enumerate(joints):               
        curInvMat : List[float] = cmds.getAttr( f"{joint}.worldInverseMatrix" )  
        # The asterix '*' unpacks the elements of the list to individual parameters:
        # curInvMat[0], curInvMat[1], ..., curInvMat[15]
        cmds.setAttr(f"{skinClusterName}.bindPreMatrix[ {i} ]", type="matrix", *curInvMat)                

    # Create a new bind pose node according to selection:
    bindPoseNodeName : str = cmds.dagPose(joints, bp=True, save=True, selection=True)

    cmds.connectAttr(bindPoseNodeName + ".message", skinClusterName + ".bindPose")


reset_bindPoseNode_skinCluster("skinCluster1")

No comments

(optional field, I won't disclose or spam but it's necessary to notify you if I respond to your comment)
All html tags except <b> and <i> will be removed from your comment. You can make links by just typing the url or mail-address.
Anti-spam question: