Wednesday 24 November 2010

Cleaning multiple bind poses

A common problem that crops up in our pipeline is multiple bind poses on a character. These are introduced as meshes are updated and replaced and also as a by-product of creating modified bind poses for volume preservation (see previous post).
This used to be a real pain in the early days before I wrote the Pose Manager tool as Maya is really poor at managing multiple bind poses. However, parts of our character export pipeline and some other custom tools still require a single bind pose for a character and it is for this reason that it's important that a skeleton only has a single bind pose (dagPose) associated with it.

This is a simple script I put together that rebuilds a single dagPose for the selected skeletal hierarchy. Obviously you need to run this when the skeleton is in your bind pose which is where the Pose Manager tool comes in useful once more. Don't forget that if you have a modified bind pose for volume preservation you need to set your skeleton to that rather than the model pose.

NT_rebuildDagPose.mel

To run, select the top joint of your skeletal hierarchy and run NT_rebuildDagPose.

5 comments:

  1. URL to mel script doen't work

    ReplyDelete

  2. global proc NT_rebuildDagPose()
    {
    string $dagPoses[];
    string $connectedSkinClusters[];
    string $sel[] = `ls -sl`;
    // if ($sel[0] == "root") {
    // build dagPose node list
    string $jointList[] = `listRelatives -pa -ad -type "joint" $sel[0]`;
    $jointList[`size $jointList`] = $sel[0];
    for ($joint in $jointList) { // $joint = "root"
    string $dagConnections[] = `listConnections -type "dagPose" $joint`;
    int $arraySize = `size $dagConnections`;
    appendStringArray $dagPoses $dagConnections $arraySize;
    }
    $dagPoses = stringArrayRemoveDuplicates($dagPoses);

    // build mesh connection list
    for ($dagPose in $dagPoses) { // $dagPose = "bindPose1"
    string $skinClusters[] = `listConnections -type "skinCluster" $dagPose`;
    int $arraySize = `size $skinClusters`;
    appendStringArray $connectedSkinClusters $skinClusters $arraySize;
    }
    $connectedSkinClusters = stringArrayRemoveDuplicates($connectedSkinClusters);

    // delete and recreate dagPose;
    print "Deleting dagPoses:\n";
    print $dagPoses;
    delete $dagPoses;
    select -r $jointList;
    string $dagPose = `dagPose -sl -s -bp`;
    print ("New dagPose created: "+($dagPose)+"\n");
    for ($skinCluster in $connectedSkinClusters) {
    print ("Connecting "+($dagPose)+".message to "+($skinCluster)+".bindPose\n");
    connectAttr (($dagPose)+".message") (($skinCluster)+".bindPose");
    }


    // }
    // else
    // error "Please select character root";
    }

    ReplyDelete
    Replies
    1. Tried this out and got the warning:

      // Warning: Line 30.39 : Redeclaration of variable "$dagPose" shadows previous declaration at line 18. Previous value will be overwritten by explicit initializer.

      Delete
    2. To fix this error, find the following line -

      for ($dagPose in $dagPoses) { // $dagPose = "bindPose1"
      string $skinClusters[] = `listConnections -type "skinCluster" $dagPose`;


      And change $dagPose to $pose, like this -

      for ($pose in $dagPoses) { // $pose = "bindPose1"
      string $skinClusters[] = `listConnections -type "skinCluster" $pose`;

      Delete