// // Fresh Skin // // // Author: Tyler Hurd, www.tylerhurd.com // // This will dupe the object passed in, copy the skin weights over to it, and clean up. // It solves so many problems, it's a little ridiculous. // // WARNING: You will lose all history except skin clusters, so // any other deformers or corrective blendshapes will have to be // reconstructed manually. global proc int freshSkinMain( string $obj ) { string $bodyA = $obj; // first turn off bind poses by deleting them // string $bindPoses[] = `ls -type "dagPose"`; if( `size $bindPoses` > 0 ) { delete $bindPoses; } // check if passing in a shape, redirect to transform above it // if( `nodeType $bodyA`== "mesh" ) { string $trans[] = `listRelatives -p $bodyA`; $bodyA = $trans[0]; } // get orig skin cluster and influences // string $clusterA = `findRelatedSkinCluster $bodyA`; if( $clusterA == "" ) { warning ("No skin cluster found for "+$bodyA+"! Possibly too much history on it for the findRelatedSkinCluster command."); return 0; } string $dupe[] = `duplicate -rr $bodyA`; $bodyB = $dupe[0]; // reorder skin cluster to be first in chain // //$bodyAShape = `listRelatives -c -type "mesh" $bodyA`; //string $tweak[] = `listConnections -type "tweak" $bodyAShape[0]`; //if( $tweak[0] != "" ) { // reorderDeformers $tweak[0] $clusterA $bodyA; //} // use same influences to bind to new geom // string $influences[] = `skinCluster -q -inf $bodyA`; select -r $influences $bodyB; setFreshSkinningSettings; SmoothBindSkin; string $clusterB = findRelatedSkinCluster($bodyB); select -cl; // now copy wieghts to new geom // copySkinWeights -nm -ss $clusterA -ds $clusterB -surfaceAssociation closestPoint -influenceAssociation oneToOne -influenceAssociation name ; delete $bodyA; rename $bodyB (getShortestName($bodyA)); rename $clusterB $clusterA; return 1; } global proc setFreshSkinningSettings() { optionVar -intValue "multipleBindPosesOpt" 0; optionVar -intValue "removeUnusedInfluences" 0; optionVar -intValue "bindTo" 2; optionVar -intValue "normalizeWeights" 2; } global proc string getShortestName( string $fullname ) { return python("\""+$fullname+"\".split('|')[-1]"); } global proc freshSkin() { // get selection and filter out the polymeshes // string $skins[] = `filterExpand -sm 12`; if( `size $skins` == 0 ) error "You must select some bound geometry to create a fresh skin with.\n"; // progress window // progressWindow -title "Creating Fresh Skins..." -progress 0 -status "Starting... " -isInterruptable false ; int $success = 0; for( $obj in $skins ) { if( `nodeType $obj`== "mesh" ) { string $trans[] = `listRelatives -p $obj`; $obj = $trans[0]; } progressWindow -e -step 1 -max (`size $skins`) -status ( $obj + "..." ); $success = `freshSkinMain $obj`; } progressWindow -endProgress; if( $success ) { print "Success! Fresh skins created!\n"; } }