// =========================================================================== // Copyright 2018 Autodesk, Inc. All rights reserved. // // Use of this software is subject to the terms of the Autodesk license // agreement provided at the time of installation or download, or which // otherwise accompanies this software in either electronic or hard copy form. // =========================================================================== // -------------------------------------------------------------------------- /* * cMuscleConvertSkin() - Main entry. */ global proc cMuscleConvertSkin() { string $objs[] = `ls -sl` ; string $obj ; if (size($objs) <= 0) error -sl 0 (uiRes("m_cMuscleConvertSkin.kMustSelectObjectDeformedBySkinCluster")) ; string $labelDelete = (uiRes("m_cMuscleConvertSkin.kConvertSkinDelete")); string $labelDisable = (uiRes("m_cMuscleConvertSkin.kConvertSkinDisable")); string $labelCancel = (uiRes("m_cMuscleConvertSkin.kConvertSkinCancel")); string $ret = `confirmDialog -title (uiRes("m_cMuscleConvertSkin.kSkinClusterToMuscleConversion")) -message (uiRes("m_cMuscleConvertSkin.kSkinClusterToMuscleConversionMessage")) -button $labelDelete -button $labelDisable -button $labelCancel -defaultButton $labelDelete -cancelButton $labelCancel -dismissString $labelCancel `; int $deleteSkinCl ; if ($ret == $labelDelete) $deleteSkinCl = 1 ; else if ($ret == $labelDisable) $deleteSkinCl = 0 ; else return ; // Now convert all selected objects. for ($obj in $objs) { cMCS_convertSkin($obj, $deleteSkinCl ) ; } // Reselect at end... select -r $objs ; } proc string cMCS_findBindPoseFromSkin(string $skinClusterName) { string $skinBindPosePlug = $skinClusterName + ".bindPose"; string $bindPose[]; $bindPose = `listConnections -d false -s true -type dagPose $skinBindPosePlug`; if(size($bindPose) > 0) { return $bindPose[0]; } else { //for legacy scenes (prior to Maya 2008) the skin cluster may not be connected //to the bindpose. In this case we'll have to try to find the bind pose a //different way. string $influences[]; $influences = `skinCluster -q -inf $skinClusterName`; for($inf in $influences) { $bindPose = `dagPose -q -bp $inf`; if(size($bindPose)>0) { return $bindPose[0]; } } } return ""; } // -------------------------------------------------------------------------- /* * cMCS_convertSkin() - Real worker proc to take Maya skin and convert it to * a Maya Muscle deformer. */ global proc cMCS_convertSkin(string $geo, int $deleteSkinCl) { if ($geo == "" || objExists($geo) != true) return ; // First we get the skinCluster from the obj.... string $skinCls[] = cMCS_getSkinFromGeo($geo) ; if ($skinCls[0] == "") { string $msg = (uiRes("m_cMuscleConvertSkin.kObjectDoesNotHaveSkinCluster")); $msg = `format -stringArg $geo $msg`; warning -sl 0 ($msg) ; return ; } string $skinCl = $skinCls[0] ; //Make sure we are at the bind pose. If we are not at the bind pose it may look to the user as if the mesh has moved //from the influences after the operation (bug 283154) string $bndPose = cMCS_findBindPoseFromSkin($skinCl); if($bndPose != "") { dagPose -r -g $bndPose; } // Now get a list of all joints in the skinCluster... // string $jnts[] = `skinCluster -q -inf $skinCl` ; int $nJnts = size($jnts) ; // Now convert each joint to a capsule... // string $msg = (uiRes("m_cMuscleConvertSkin.kConvertingJointsToCapsule")); $msg = `format -stringArg $skinCl $msg`; print ($msg) ; int $i; select -r $jnts ; cMuscle_makeMuscle(0) ; // Make all objects into cMucsleObject compatible stuff. // What surface shape is it deforming? string $surfs[] = `skinCluster -q -g $skinCl` ; string $surf = $surfs[0] ; string $pts[] ; int $nPts ; if (nodeType($surf) == "nurbsSurface") { select -r ($surf+".cv[*]") ; $pts = `ls -sl -fl` ; $nPts = size($pts) ; } else if (nodeType($surf) == "mesh") { select -r ($surf+".vtx[*]") ; $pts = `ls -sl -fl` ; $nPts = size($pts) ; } else if (nodeType($surf) == "subdiv") { select -r ($surf+".smp[*]") ; $pts = `ls -sl -fl` ; $nPts = size($pts) ; } else { string $msg = (uiRes("m_cMuscleConvertSkin.kCannotConvertThisType")); $msg = `format -stringArg $surf $msg`; warning -sl 0 ($msg) ; return ; } select -cl ; // Apply a Maya Muscle deformer if needed... // string $hist[] = `listHistory -pdo true -il 1 $geo`; string $mSs[] = `ls -type "cMuscleSystem" $hist` ; $mSs = stringArrayRemoveDuplicates($mSs) ; string $mS = "" ; if (size($mSs) <= 0) { select -r $geo ; $mS = cMuscle_makeMuscleSystem(0) ; } else $mS = $mSs[0] ; // Connect the given cMuscleObject joints/capsules into the deformer // print (uiRes("m_cMuscleConvertSkin.kConnectingCapsules")) ; select -r $jnts ; select -add $mS ; cMuscle_connectToSystem() ; select -cl ; refresh ; setAttr ($mS+".envelope") 0.0 ; // disable for speed during set... refresh ; // Now copy weights from the skinCluster to the Maya Muscle deformer. // $msg = (uiRes("m_cMuscleConvertSkin.kCopyingSkinWeightsToMuscleSystem")); $msg = `format -stringArg $mS $msg`; print ($msg) ; $msg = (uiRes("m_cMuscleConvertSkin.kInitialPointProgress")); $msg = `format -stringArg $nPts $msg`; progressWindow -title (uiRes("m_cMuscleConvertSkin.kConvertingWeightsFromSkinCluster")) -progress 0 -status ($msg) -isInterruptable true -min 0 -max 100 ; for ($i=0; $i < $nPts; ++$i) { if ( `progressWindow -query -isCancelled` ) break; float $pct = (100.0 * $i / ($nPts-1.0)) ; string $msg = (uiRes("m_cMuscleConvertSkin.kConvertingPointProgress")); $msg = `format -stringArg ($i+1) -stringArg $nPts -stringArg ((int)$pct) $msg`; progressWindow -e -progress ((int)($pct)) -status ($msg ) ; // What joints are being used? string $inf[] ; clear $inf ; $inf = `skinPercent -ib 0.001 -q -t $skinCl $pts[$i]` ; // And what are their skinPercent weights? float $wts[] ; clear $wts ; $wts = `skinPercent -ib 0.001 -q -v $skinCl $pts[$i]` ; int $nInf = size($inf) ; // Figure out what cMuscleObjects are actually under these transforms... // And set the weight int $j; for ($j=0; $j < $nInf; ++$j) { string $mOs[] = `listRelatives -shapes -ni -type "cMuscleObject" $inf[$j]`; string $mO = $mOs[0] ; if ($mO == "") // This should never happen... continue ; // Weight the given point on the given Maya Muscle deformer // to the proper wt for the given mus. We are setting basic sticky // weights, and since all weights default to 0, and we are going to set // each xform individually we want normalize on only for the last entry. // cMuscleWeight -mus $mO -v $wts[$j] -normalize ($j==$nInf-1) -wt "sticky" -sys $mS $pts[$i] ; } } // end of each pt progressWindow -endProgress ; setAttr ($skinCl+".envelope") 0.0 ; // Disable skinCluster.... setAttr ($mS+".envelope") 1.0 ; // enable // Actually delete the original skinCl if desired. if ($deleteSkinCl) delete $skinCl ; $msg = (uiRes("m_cMuscleConvertSkin.kFinishedConvertingSkinClusterToMuscleSystem")); $msg = `format -stringArg $skinCl -stringArg $mS $msg`; print $msg ; } // -------------------------------------------------------------------------- // -------------------------------------------------------------------------- // Helper Procs // -------------------------------------------------------------------------- // -------------------------------------------------------------------------- /* * cMCS_getSkinFromGeo() - Returns the names of any skinClusters * tied to the history of passed in node. */ global proc string[] cMCS_getSkinFromGeo(string $geo) { string $skins[] ; clear $skins ; if ($geo == "" || objExists($geo) != true) return $skins ; string $hist[] = `listHistory -pdo 1 -il 2 $geo` ; string $h ; for ($h in $hist) { if (nodeType($h) == "skinCluster") { $skins[size($skins)] = $h ; // Store it } } return $skins ; } // --------------------------------------------------------------------------