MEL and Python code to change / reset the bind pose of a skinned mesh in Maya
How to edit the bind pose of a skin cluster in Maya - 04/2023 - #Jumble
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