// =========================================================================== // 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. // =========================================================================== /* * Includes */ /* * globals */ // -------------------------------------------------------------------------- // -------------------------------------------------------------------------- // Helper Procs // -------------------------------------------------------------------------- // -------------------------------------------------------------------------- /* * cMuscle_getGeoFromDeformer() - For each deformer passed in, returns related geo-xform */ global proc string[] cMuscle_getGeoFromDeformer(string $defs[]) { string $geos[] ; clear $geos ; int $i; for ($i=0; $i < size($defs); ++$i) { if ($defs[$i] == "" || objExists($defs[$i]) != true) { $geos[$i] = "" ; continue ; } string $shapes[] = `deformer -q -geometry $defs[$i]` ; string $xforms[] = `listRelatives -parent $shapes[0]` ; $geos[$i] = $xforms[0] ; } return $geos ; } // -------------------------------------------------------------------------- /* * cMuscle_getDeformers() - This lets you easily get back a list of * deformer nodes based on what is selected by looking at their history. * Most typically used to get cMuscleSystem deformers from the user * selecting the mesh that is being deformed by something like * string $mSs[] = cMuscle_getSelectedDeformers("cMuscleSystem") ; */ global proc string[] cMuscle_getDeformers(string $deformerType, string $items[]) { string $defs[] ; // What we are returning clear $defs ; // Look for the given deformer in what is chosen... string $hist[] = `listHistory -pdo true -il 1 $items`; $defs = `ls -type $deformerType $hist` ; $defs = stringArrayRemoveDuplicates($defs) ; return $defs ; } // -------------------------------------------------------------------------- /* * cMuscle_getSelectedDeformers() - This lets you easily get back a list of * deformer nodes based on what is selected by looking at their history. * Most typically used to get cMuscleSystem deformers from the user * selecting the mesh that is being deformed by something like * string $mSs[] = cMuscle_getSelectedDeformers("cMuscleSystem") ; */ global proc string[] cMuscle_getSelectedDeformers(string $deformerType) { string $defs[] ; // What we are returning clear $defs ; string $objs[] = `ls -sl`; if (size($objs) <= 0) return $defs ; // Look for the given deformer in what is chosen... string $hist[] = `listHistory -pdo true -il 1 $objs`; $defs = `ls -type $deformerType $hist` ; $defs = stringArrayRemoveDuplicates($defs) ; return $defs ; } // -------------------------------------------------------------------------- /* * cMuscle_getSelectedShapes() - This lets you easily get back a list of * shape nodes based on what is selected by looking at relatives. * Most typically used to get cMuscleObject shapes from the user * selecting the transform. * string $mOs[] = cMuscle_getSelectedShapes("cMuscleObject") ; */ global proc string[] cMuscle_getSelectedShapes(string $shapeType) { string $shapes[] ; // What we are returning clear $shapes ; string $objs[] = `ls -sl`; if (size($objs) <= 0) return $shapes ; // Look for shapes of objects. $shapes = `listRelatives -shapes -ni -type $shapeType $objs`; return $shapes ; } // -------------------------------------------------------------------------- /* * cMuscle_cleanMayaShape() - This hides some rather useless Maya7 channelbox * stuff from all of our locator shape nodes... */ global proc cMuscle_cleanMayaShape(string $shape) { // string $ver = `about -version` ; // Get Maya version // float $fVer = (float)$ver ; // if ($fVer >= 7.0) if (objExists($shape+".localPositionX")) { eval("setAttr -k false -channelBox false "+$shape+".localPositionX ;") ; eval("setAttr -k false -channelBox false "+$shape+".localPositionY ;") ; eval("setAttr -k false -channelBox false "+$shape+".localPositionZ ;") ; eval("setAttr -k false -channelBox false "+$shape+".localScaleX ;") ; eval("setAttr -k false -channelBox false "+$shape+".localScaleY ;") ; eval("setAttr -k false -channelBox false "+$shape+".localScaleZ ;") ; } } // -------------------------------------------------------------------------- /* * cMuscle_objDist() - Get dist between two objs */ global proc float cMuscle_objDist(string $o1, string $o2) { float $p1[3] = `xform -q -ws -rp $o1` ; float $p2[3] = `xform -q -ws -rp $o2` ; float $dist = (($p2[0]-$p1[0])*($p2[0]-$p1[0])) + (($p2[1]-$p1[1])*($p2[1]-$p1[1])) + (($p2[2]-$p1[2])*($p2[2]-$p1[2])) ; $dist = sqrt($dist) ; return $dist; } // -------------------------------------------------------------------------- /* * cMuscle_snap() - Does a simple snap so slave gets put onto master location */ global proc cMuscle_snap(string $master, string $slave) { // Now snap the target to the endParent...which is the pose string $pCs[] = `pointConstraint -w 1 $master $slave` ; string $oCs[] = `orientConstraint -w 1 $master $slave` ; refresh ; // See if this helps weirdness where transfom info for these curves somehow goes to -1.#IND delete $pCs $oCs ; } // -------------------------------------------------------------------------- /* * cMuscle_snapBetween() - Does a simple snap so slave gets put between 2 masters */ global proc cMuscle_snapBetween(string $master1, string $master2, string $slave) { // Now snap the target to the endParent...which is the pose string $pCs[] = `pointConstraint -w 1 $master1 $master2 $slave` ; string $oCs[] = `orientConstraint -w 1 $master1 $master2 $slave` ; delete $pCs $oCs ; } // -------------------------------------------------------------------------- /* * cMuscle_duplicateObject() - Duplicates an object, searching for a name and replacing it as provided */ global proc string cMuscle_duplicateObject(string $orig, string $search, string $replace, int $bParentToMirror) { string $newName = cMuscle_strSearchReplace($orig, $search, $replace) ; if (objExists($newName)) // Uh-oh...exists already...return it as is. return $newName ; string $dups[] = `duplicate -rr -rc $orig` ; $dups[0] = `rename $dups[0] $newName` ; if ($bParentToMirror) { string $parents[] = `listRelatives -ni -parent $orig` ; string $parentNew = cMuscle_strSearchReplace($parents[0], $search, $replace) ; if ($parentNew != "" && $parentNew != $parents[0] && objExists($parentNew)) // Only reparent if we have one, it's not the original one (ie we find a mirror) and it exists { $dups = `parent $dups[0] $parentNew` ; } } select -r $dups[0] ; return ($dups[0]) ; } // -------------------------------------------------------------------------- /* * cMuscle_mirrorObject() - Takes the current object and mirrors it * for behavior * * $nAxis. 0=X 1=Y 2=Z which axis to mirror across */ global proc cMuscle_mirrorObject(string $obj, int $nAxis) { if ($obj == "" || objExists($obj) != true) { string $msg = (uiRes("m_cMuscleHelper.kObjectDoesNotExist")); $msg = `format -stringArg $obj $msg`; warning -sl 0 ($msg) ; return ; } // First move to new spot float $pos[3] = `xform -q -ws -t $obj` ; $pos[$nAxis] *= -1.0 ; xform -a -ws -t $pos[0] $pos[1] $pos[2] $obj ; // Now mirror rotation. We simply do an aim on the object, // but with everything backwards. We can pick any two axis. // I will just pick Y as aim and X as up, but it doesn't really // matter at all, so long as the way we move them matches the // aim constraint later. // // string $aimTgt = `group -em -w -n "grpAimTgtMirrorTEMP"` ; string $aimUp = `group -em -w -n "grpAimUpTgtMirrorTEMP"` ; parent $aimTgt $obj ; parent $aimUp $obj ; // Now snap these to the same spot string $pCons[], $oCons[] ; $pCons = `pointConstraint -w 1 $obj $aimTgt` ; $oCons = `orientConstraint -w 1 $obj $aimTgt` ; refresh -f; delete $pCons $oCons ; $pCons = `pointConstraint -w 1 $obj $aimUp` ; $oCons = `orientConstraint -w 1 $obj $aimUp` ; refresh -f; delete $pCons $oCons ; // Now we have two groups at same spot...move them down axis, but reverse. xform -r -os -t 0 -1 0 $aimTgt ; xform -r -os -t -1 0 0 $aimUp ; // Now how did aimTgt move, what is world vector float $posTgt[3] = `xform -q -ws -t $aimTgt` ; float $posUp[3] = `xform -q -ws -t $aimUp` ; float $deltaTgt[3] = {($posTgt[0]-$pos[0]), ($posTgt[1]-$pos[1]), ($posTgt[2]-$pos[2]) } ; float $deltaUp[3] = {($posUp[0]-$pos[0]), ($posUp[1]-$pos[1]), ($posUp[2]-$pos[2]) } ; // Now mirror that vector as needed $deltaTgt[$nAxis] *= -1.0 ; $deltaUp[$nAxis] *= -1.0 ; xform -r -os -t 0 1 0 $aimTgt ; // Then move aim tgt back xform -r -os -t 1 0 0 $aimUp ; // Then move aim up back xform -r -ws -t $deltaTgt[0] $deltaTgt[1] $deltaTgt[2] $aimTgt ; // Then move right way... xform -r -ws -t $deltaUp[0] $deltaUp[1] $deltaUp[2] $aimUp ; // Then move right way... // unparent. parent -w $aimTgt ; parent -w $aimUp ; // Now use these to do the aimConstraint. string $aCons[] = `aimConstraint -aim 0 1 0 -u 1 0 0 -wut "object" -wuo $aimUp -w 1 $aimTgt $obj` ; refresh -f; delete $aCons ; delete $aimTgt $aimUp ; // Also zero out rotation on joint if what we have is a joint, so it does // something like a joint align // if (nodeType($obj) == "joint") makeIdentity -apply true -t 1 -r 1 -s 1 -n 0 $obj ; select -r $obj ; // Done! } // -------------------------------------------------------------------------- /* * cMuscle_guessPrimaryAxis() - Given two objects, a parent and what woiuld be a child * determines the primary axis down the chain. This is typically used for joints * but it doesn't have to be joints. We simply look at a temp grp we make at the child * location and parented to the parent...then we determine the largest Translate value * which would be the largest axis... and return 0,1,2 for x y or z axis. If negative return 3,4,5 */ global proc int cMuscle_guessPrimaryAxis(string $parent, string $child) { string $grpTemp = `group -em -w -n "grpTempPrimaryGuessDELETEME#"`; parent $grpTemp $parent ; cMuscle_snap($child, $grpTemp) ; float $x = `getAttr ($child+".translateX")` ; float $y = `getAttr ($child+".translateY")` ; float $z = `getAttr ($child+".translateZ")` ; int $axis = 0 ; float $max = $x ; if (abs($y) > abs($x) && abs($y) > abs($z)) { $axis = 1; $max = $y ; } else if (abs($z) > abs($x) && abs($z) > abs($y)) { $axis = 2 ; $max = $z ; } delete $grpTemp ; // Remove temp node if ($max < 0.0) // If negative axis...increase... $axis += 3 ; return $axis ; } // -------------------------------------------------------------------------- /* * cMuscle_mirrorObjectProvided() - Given two objects that already exist... * snap the slave to the mirror location of the master */ global proc cMuscle_mirrorObjectProvided(string $master, string $slave, int $nAxis) { // Make a temp grp at master location string $temp = `group -em -w -n ("grpMirrorProvidedTEMPDELETEME")` ; cMuscle_snap($master, $temp) ; // Mirror the temp grp cMuscle_mirrorObject($temp, $nAxis) ; // Now snap the slave to the mirror cMuscle_snap($temp, $slave) ; delete $temp ; } // -------------------------------------------------------------------------- /* * cMuscle_getCompsFromNodes() - Given Muscle, Direction or Smart nodes, figure out what pts they affect. */ global proc string[] cMuscle_getCompsFromNodes(string $mS, string $nodes[], string $shape, int $ptMode, string $ptModeStr) { string $comps[] ; clear $comps ; // Select all comps as a start to determine how many etc.... if (nodeType($shape) == "nurbsSurface" || nodeType($shape) == "nurbsCurve") select -r ($shape+".cv[*]") ; else if (nodeType($shape) == "mesh") select -r ($shape+".vtx[*]") ; else if (nodeType($shape) == "subdiv") select -r ($shape+".smp[*]") ; else if (nodeType($shape) == "lattice") select -r ($shape+".pt[*]") ; else return $comps ; // So what are all the components? string $allComps[] = `ls -sl -flatten` ; select -cl ; string $shapeType ; if ($ptMode <= 3) $shapeType = "cMuscleObject" ; else if ($ptMode == 4) $shapeType = "cMuscleDirection" ; else if ($ptMode >= 5 && $ptMode <= 15) $shapeType = "cMuscleSmartCollide" ; // Convert nodes to shapes we actually want string $node ; string $nodeShapes[] ; for ($node in $nodes) { string $shapes[] = `listRelatives -ni -shapes -type $shapeType $node` ; // Get actual shape we want from xform $nodeShapes[size($nodeShapes)] = $shapes[0] ; } waitCursor -state on ; string $c; for ($c in $allComps) { string $nodeShape ; for ($nodeShape in $nodeShapes) { // What is the weight of the current component for this node? float $wts[] = `cMuscleWeight -system $mS -muscle $nodeShape -wt $ptModeStr -q -v $c` ; if ($wts[0] > 0.0) { // If it is non zero, then see if it is one of the joints we want.. $comps[size($comps)] = $c ; break ; } // end of if wt > 0 } // end of each node } // end of each comp waitCursor -state off ; return $comps ; } // -------------------------------------------------------------------------- /* * cMuscle_getCompsFromWtMode() - Given a pt mode for a single wt type, return the pts that are not 0. */ global proc string[] cMuscle_getCompsFromWtMode(string $mS, string $shape, int $ptMode, string $ptModeStr) { string $comps[] ; clear $comps ; // Select all comps as a start to determine how many etc.... if (nodeType($shape) == "nurbsSurface" || nodeType($shape) == "nurbsCurve") select -r ($shape+".cv[*]") ; else if (nodeType($shape) == "mesh") select -r ($shape+".vtx[*]") ; else if (nodeType($shape) == "subdiv") select -r ($shape+".smp[*]") ; else if (nodeType($shape) == "lattice") select -r ($shape+".pt[*]") ; else return $comps ; // So what are all the components? string $allComps[] = `ls -sl -flatten` ; select -cl ; waitCursor -state on ; string $c; for ($c in $allComps) { // What is the weight of the current component for this node? float $wts[] = `cMuscleWeight -system $mS -wt $ptModeStr -q -v $c` ; if ($wts[0] > 0.0) { // If it is non zero, then see if it is one of the joints we want.. $comps[size($comps)] = $c ; } // end of if wt > 0 } // end of each comp waitCursor -state off ; return $comps ; } // -------------------------------------------------------------------------- /* * cMuscle_getSelComps() - Returns a list of obj.comp[] for any selected components * that match the current system node... * * if $bAutoSelect is true, then it will auto select all comps of the sys geo * if none are chosen. */ global proc string[] cMuscle_getSelComps(string $def, int $bAutoSelect) { string $sel[] = `ls -sl -fl`; int $nSel = size($sel) ; if ($def == "" || objExists($def) != true) return {} ; //print ("// Getting selected components of deformed geometry. //\n") ; waitCursor -state on ; // Now much better than hacky way of looking at points before... we use the deformer set. // This has the advantage of also respecting true edit membership... // string $defSets[] = `listConnections -s 0 -d 1 -p 0 -scn 1 -type "objectSet" ($def+".message")` ; string $defSet = $defSets[0] ; // Get the pts in membership. string $ptsInMembership[] = `sets -q $defSet` ; // Now we have selection and we have proper membership...we want the intersection only! // The quick way to do this is to create a set of the selected comps, and then // interesect that with the real set... and get the result... // Since we have sel selected the set will have that selection.... string $tempSet = `sets -name "setTempISect"` ; string $comps[] ; clear $comps ; $comps = `sets -intersection $tempSet $defSet` ; // Delete temp set. delete $tempSet ; // Auto select all comps of object if none are... if (size($comps) <= 0 && $bAutoSelect) { // Then set to whatever is in membership! $comps = $ptsInMembership ; } // Flatten! $comps = `ls -fl $comps` ; waitCursor -state off ; return $comps ; } // -------------------------------------------------------------------------- /* * cMuscle_getNodesFromComps() - */ global proc string[] cMuscle_getNodesFromComps(string $mS, string $comps[], string $shape, int $ptMode, string $ptModeStr ) { string $nodes[] ; clear $nodes ; // Get all nodes used in this wt type for this mS string $skinNodes[] ; if ($ptMode <= 3) $skinNodes = `cMuscleQuery -sys $mS -muscle`; else if ($ptMode == 4) $skinNodes = `cMuscleQuery -sys $mS -direction` ; else if ($ptMode >= 5 && $ptMode <= 15) $skinNodes = `cMuscleQuery -sys $mS -smartcollide` ; waitCursor -state on ; string $c; for ($c in $comps) { string $node ; for ($node in $skinNodes) { // Get weights for this component... for this node float $wts[] = `cMuscleWeight -system $mS -muscle $node -wt $ptModeStr -q -v $c` ; // Now if non zero weight... if ($wts[0] > 0.0) { // If it is non zero, then add the node to the list // if it hasn't been added yet. int $idx = -1 ; int $n ; for ($n=0; $n < size($nodes); ++$n) { if ($nodes[$n] == $node) { $idx = $n ; break ; } } if ($idx == -1) // If still -1, then we haven't seen it yet! { $nodes[size($nodes)] = $node ; } } // end of if wt > 0 } // end of each node } // end of each comp // Now convert the shape node names we found to their nicely name xform nodes... string $node ; string $nodeXForms[] ; for ($node in $nodes) { string $parents[] = `listRelatives -ni -parent $node` ; // Get actual xform $nodeXForms[size($nodeXForms)] = $parents[0] ; } waitCursor -state off ; return $nodeXForms ; } // --------------------------------------------------------------------------