//======================================================================================== // Script name: snSkelCreation.mel // Author : Sean Nolan // sean@snolan.net // // Date: October 16, 2004 // // Desc : Create a skeletal rig. Creates spheres as guides for joint placement // Can also translate and rotate bones before orienting. After orienting // the joints will be zeroed out. // // Usage: For creating a custom skeletal rig. // Features: 1. Interactive guide placement for joint creation // 2. Interactive joint insertion // 3. Custom joint orienting. // 4. Rename joint chain // 5. Mirror joints faster. Automatically replaces names for the right side // 6. Able to scale guides to fit character // // This script was inspired by other scripts such as FinalRig by radiantsquare, templateSkelton by // Paul Thuroit and dwRiggingTools by David Walden. //======================================================================================== //================================================================== // Main Window proc //================================================================== global proc snSkelCreation() { int $winWidth = 350; int $winHeight = 500; string $window = "snSkelCreationWin"; if(`window -ex $window `) deleteUI $window ; window -t "Skeleton Rig Creation" -wh $winWidth $winHeight -mb 1 $window ; menu -l "Help" -p $window mainMenu; menuItem -p mainMenu -l "Help" -c "helpWin" snHelpMenu; menuItem -d 1; scrollLayout -horizontalScrollBarThickness 0 -verticalScrollBarThickness 16 -h 200; columnLayout -adjustableColumn true; text -al "center" -fn "boldLabelFont" "Step by Step process for creating a Skeletal Rig\n"; separator; //StepOneFrame rowColumnLayout -nc 1 -cw 1 300; frameLayout -label "Step One: Setup Guides" -labelAlign "top" -borderStyle "etchedIn" -cll true -ann "Place guides where joints should go" stepOneFrame; rowColumnLayout -nc 2 -cw 1 150 -cw 2 150; button -l "Create Guides" -w ($winWidth/3) -h 32 -ann "Create Guides" -c createDaGuides; button -l "Joint Tool" -w ($winWidth/3) -h 32 -ann "Draw your own Joints" -c "JointTool"; setParent..;//rowColumnLayout setParent..;//rowColumnLayout //StepTwoFrame frameLayout -label "Step Two: Create the Joints" -labelAlign "top" -borderStyle "etchedIn" -cll true -cl true -ann "Creates the joints from the guide locations" stepTwoFrame; rowColumnLayout -nc 2 -cw 1 150 -cw 2 40; button -l "Create Template" -w ($winWidth/3) -h 32 -ann "Create Joints from guide locations" -c createDaBones; text -l ""; text -l ""; text -l ""; text -fn "boldLabelFont" -l "Joint Scale:"; text -l ""; floatSlider -min 0 -max 1 -v 1 -cc "floatField -e -v `floatSlider -q -v jointScaleSlider` jointScaleValue;\ scaleJoints (`floatSlider -q -v jointScaleSlider`);" jointScaleSlider; floatField -ed 0 -precision 2 -w 32 -v `floatSlider -q -v jointScaleSlider` -cc "floatSlider -e -v `floatField -q -v jointScaleValue` jointScaleSlider" jointScaleValue; setParent..;//columnLayout setParent..;//columnLayout //StepThreeFrame frameLayout -label "Step Three: Insert or Remove Joints" -labelAlign "top" -borderStyle "etchedIn" -cll true -cl true -ann "Inserts and removes joints from skeleton" stepThreeFrame; rowColumnLayout -nc 2 -cw 1 150 -cw 2 150; button -l "Insert Joint" -w ($winWidth/3) -h 32 -ann "Insert Joints. Use Slider to position the bone" -c insertAJoint; button -l "Remove Joint" -w ($winWidth/3) -h 32 -ann "Removes joint from chain" -c "RemoveJoint"; text -l ""; text -l ""; rowColumnLayout -nc 2 -cw 1 100 -cw 2 50 ; floatSlider -ann "Position the joint along the current joint vector." -min 0 -max 1 -v 0.5 -cc "floatField -e -v `floatSlider -q -v jointPositionSlider` jointPositionValue;\ moveJoint (`floatSlider -q -v jointPositionSlider`);" jointPositionSlider; floatField -ann "Shows the current position of the joint relative to the joints before and after." -ed 0 -precision 2 -w 32 -v `floatSlider -q -v jointPositionSlider` -cc "floatSlider -e -v `floatField -q -v jointPositionValue` jointPositionSlider" jointPositionValue; button -l "Reset" -c "floatSlider -e -v .5 jointPositionSlider;\ moveJoint (`floatSlider -q -v jointPositionSlider`);\ floatField -e -v `floatSlider -q -v jointPositionSlider` jointPositionValue"; setParent..;//rowColumnLayout setParent..;//rowColumnLayout setParent..;//rowColumnLayout //StepFourFrame frameLayout -label "Step Four: Orient Joints" -labelAlign "top" -borderStyle "etchedIn" -cll true -cl true -ann "Orients Joints along Z+" stepFourFrame; rowColumnLayout -nc 2 -cw 1 150 -cw 2 150; button -l "Orient Joints" -w ($winWidth/3) -h 32 -ann "Places arrows in the direction Z+ in facing" -c "snTemplateSkeleton_createTemp_doIt"; button -l "ReDraw from Temp" -w ($winWidth/3) -h 32 -ann "Redraws joints in correct orientation" -c "pickWalk -d up;pickWalk -d up;snTemplateSkeleton_reBuildChain_doIt;"; setParent..;//rowColumnLayout setParent..;//rowColumnLayout //StepFiveFrame Rename frameLayout -label "Step Five: Rename Joints" -labelAlign "top" -borderStyle "etchedIn" -cll true -cl true -ann "Orients Joints along Z+" stepFiveFrame; columnLayout -adj 1 -rs 4 -co "both" 1 -cw $winWidth ; string $suffix = `radioButtonGrp -cw 1 ($winWidth/4) -cw 2 ($winWidth/4) -cw 3 ($winWidth/4) -cal 1 "left" -l "Suffix:" -numberOfRadioButtons 2 -labelArray2 "None" "Left" -sl 1 suffixRB`; separator; rowColumnLayout -nc 2 -cw 1 150 -cw 2 150; string $jointNameTxt = `textField -w 120 -changeCommand "reNameJoints" nameMe`; $renameButton = `button -l "ReName" -ann "Names the entire chain"`; setParent..;//rowColumnLayout button -e -c "reNameJoints" $renameButton; setParent..;//rowColumnLayout setParent..;//rowColumnLayout //StepSixFrame Mirror frameLayout -label "Step Six: Mirror Joints" -labelAlign "top" -borderStyle "etchedIn" -cll true -cl true -ann "Mirror the joints" stepSixFrame; rowColumnLayout -nc 2 -cw 1 150 -cw 2 150; button -l "Mirror Joint" -w ($winWidth/3) -h 32 -ann "Mirrors the joints over" -c "mirrorMyJoints"; setParent..;//frameLayout setParent..;//rowColumnLayout setParent..; window -edit -wh $winWidth $winHeight $window; showWindow $window ; } //================================================================== // Description : Scale joints //================================================================== global proc scaleJoints(float $jointScale) { jointDisplayScale $jointScale; } //================================================================== // Description : Help window //================================================================== global proc helpWin() { int $uiLabelWidth = 300; int $uiInputWidth = 500; int $uiWidth = $uiLabelWidth + $uiInputWidth + 220; if ( `window -exists snSkelCreationHelpWin` ) deleteUI snSkelCreationHelpWin; window -maximizeButton false -resizeToFitChildren false -title "SkelCreation Help" snSkelCreationHelpWin; tabLayout -innerMarginWidth 5 -innerMarginHeight 5 -childResizable true helpTab; string $form1 = `formLayout -numberOfDivisions 100 "SkelCreation"`; string $scroll1 = `scrollLayout -hst 16 -vst 16 -childResizable true -minChildWidth $uiWidth`; columnLayout -adjustableColumn true -rowSpacing 6; // snSkelCreation - instructions frameLayout -label "Instructions" -labelAlign "center" -cll false -lw $uiWidth -mh 3 -borderStyle "etchedIn" -bv true; columnLayout -adjustableColumn true; rowLayout -numberOfColumns 1 -cat 1 "left" 5; text sninstructions1; setParent ..; setParent ..; setParent ..; setParent ..; setParent ..; string $button1 = `button -label "Close" -command "deleteUI snSkelCreationHelpWin"`; setParent ..; string $form2 = `formLayout -numberOfDivisions 100 "About"`; string $scroll2 = `scrollLayout -hst 16 -vst 16 -childResizable true -minChildWidth $uiWidth`; columnLayout -adjustableColumn true -rowSpacing 6; // about frameLayout -label "About snSkelCreation" -labelAlign "center" -cll false -lw $uiWidth -mh 3 -borderStyle "etchedIn" -bv true; columnLayout -adjustableColumn true; rowLayout -numberOfColumns 1 -cat 1 "left" 5; text sninstructions2; setParent ..; setParent ..; setParent ..; setParent ..; setParent ..; string $button2 = `button -label "Close" -command "deleteUI $window"`; // set form layouts formLayout -edit -attachForm $scroll1 "top" 4 -attachForm $scroll1 "left" 4 -attachControl $scroll1 "bottom" 4 $button1 -attachForm $scroll1 "right" 4 $form1; formLayout -edit -attachNone $button1 "top" -attachForm $button1 "left" 4 -attachForm $button1 "bottom" 4 -attachForm $button1 "right" 4 $form1; formLayout -edit -attachForm $scroll2 "top" 4 -attachForm $scroll2 "left" 4 -attachControl $scroll2 "bottom" 4 $button2 -attachForm $scroll2 "right" 4 $form2; formLayout -edit -attachNone $button2 "top" -attachForm $button2 "left" 4 -attachForm $button2 "bottom" 4 -attachForm $button2 "right" 4 $form2; string $sninstructions1 = "\nThis script is to assist Character TD's or anyone who needs to build a custom skeleton\n" + "fast without the headaches of improper joint rotation. The tools can be used out of order\n" + "and do not have to used in the step by step process\n\n" + "Step One - Setup Guides\n" + " Button one will create spheres as guides that can be translated, rotated and scaled.\n" + " Button two is just the joint tool for creating your own system.\n\n" + "Step Two - Create the Joints\n" + " the creation button is used for creating the joints from the guides.\n\n" + "Step Three - Insert or Remove Joints\n" + " This section will let you interactively insert joints and there is a slider that will \n" + " tranlate the joint relative to the joints from either ends.\n\n" + "Step Four - Orient Joints\n" + " The first button will create arrows on each joint in the chain except the end.\n Select the root" + " joint and press the arrow button. Each joint will have a new attribute called \"Rotate Arrow\".\n" + " Use this new attribute to rotate the arrow in the direction that you want Z+ to be facing.\n" + " Once you have the arrows rotated, select the root joint and press the pencil button. This button\n" + " will redraw the joints with the proper rotation\n\n" + "Step Five - Rename Joints\n" + " There are two radio buttons that are used in the renaming of the joints. None will give no suffix\n" + " and the left will add the \"L\" to the joint. \n" + " \nThe naming convention is as follows for the joints: name(for joint)L(for left) and _#(for number of).\n\n" + "Step Six - Mirror Joints\n" + " Before mirroring parent the joints to there respected roots :\n " + " Hip->Spine\n"+ " Thumb->Wrist\n"+ " Pinky->Wrist\n"+ " Index->Palm\n"+ " Middle->Palm\n"+ " Ring->Palm\n"+ " Clavicle->Spine.\n\n" + " Once you are complete then you mirror the joints over and the joints are automatically renamed\n" + " on the other side\n" + "\nHope this is helpful to you and if you have any comments or suggestions then feel free to contact me"; string $sninstructions2 = "snSkelCreation V1.0\n" + "\n" + "Written by Sean Nolan, 2004\n" + "\n" + "This script may be freely distributed.\n" + "Modify at your own risk.\n" + "\n" + "Email: sean@snolan.net\n"; text -e -label $sninstructions1 sninstructions1; text -e -label $sninstructions2 sninstructions2; window -e -w 600 -h 600 snSkelCreationHelpWin; showWindow snSkelCreationHelpWin; } //================================================================== // Description : Procedure for renaming the joints in the hierachy //================================================================== global proc reNameJoints() { string $side; int $rtLf = `radioButtonGrp -q -sl suffixRB`; if ($rtLf == 2) { $side = "L"; } else { $side = ""; } string $suffix = $side; string $newlyNamed[]; clear($newlyNamed); string $rename[]; clear($rename); string $namePrefix = `textField -q -tx nameMe`; string $readSuffixTxt = $suffix; string $sel[] = `ls -type joint -sl`; string $children[] = `listRelatives -c $sel[0]`; if(`size($sel)` < 1) error("-> Select one joint"); string $selHier[] = `ls -type joint -dag $sel[0]`; for ($i = 0; $i < size($selHier); $i++) { if($i == 0 ) { $rename[$i] = ("bone_" + $readSuffixTxt + $namePrefix); } else { $rename[$i] = ("bone_" + $readSuffixTxt + $namePrefix + $i); } } if($readSuffixTxt != "") { $newlyNamed[(size($rename)-1)] = `rename $selHier[(size($rename)-1)] ("bone_" + $readSuffixTxt + $namePrefix +($i + 1))`; } else { $newlyNamed[(size($rename)-1)] = `rename $selHier[(size($rename)-1)] ("bone_" + $readSuffixTxt + $namePrefix + ($i + 1))`; } for($j = size($rename)-2; $j >= 0; $j--) { $newlyNamed[$j] = `rename $selHier[$j] $rename[$j]`; } if(`size($children)` == 0) { $newlyNamed[(size($rename))] = `rename $selHier[(size($rename)-1)] ("bone_" + $readSuffixTxt + $namePrefix )`; } pickWalk -d down; } //================================================================== // Description: Reading the suffix for the radioButtons //================================================================== global proc string readSuffix(string $suffix) { string $side; int $rtLf = `radioButtonGrp -q -sl $suffix`; if ($rtLf == 2) { $side = "L"; } else { $side = ""; } return $side; } //====================================================================== // DESCRIPTION: Creates the guides to be placed for joint placement //====================================================================== global proc createDaGuides() { // create guide scale string $guideScale[] = `circle -c 0 0 0 -nr 0 1 0 -sw 360 -r 6 -d 3 -ut 0 -tol 0.01 -s 8 -ch 1 -name "guideScale"`; select -r guideScale; DeleteHistory; select -cl; // Create the left leg curve string $legCurve = `curve -d 1 -p 1.640851 12.821001 -0.803479 -p 1.640851 6.861675 0.111522 -p 1.640851 2.087343 -0.925597 -p 1.640851 0.0645615 1.456594 -p 1.640851 0.0645615 2.789828 -k 0 -k 1 -k 2 -k 3 -k 4 -name "ltLegCurve" `; // Create the spine curve string $spineCurve = `curve -d 1 -p 0 13.470925 -0.753479 -p 0 14.470925 -0.753479 -p 0 15.470925 -0.753479 -p 0 16.470925 -0.753479 -p 0 17.470925 -0.753479 -p 0 18.470925 -0.753479 -p 0 19.470925 -0.753479 -p 0 20.470925 -0.753479 -p 0 21.135415 -0.757378 -p 0 22.156642 -0.757378 -p 0 24.52502 -0.757378 -k 0 -k 1 -k 2 -k 3 -k 4 -k 5 -k 6 -k 7 -k 8 -k 9 -k 10 -name "spineCurve"`; //create the arm Curve string $armCurve =`curve -d 1 -p 0.588487 20.370144 -0.996978 -p 3.187335 20.351657 -0.998068 -p 6.28821 20.329598 -0.999369 -p 9.876875 20.30407 -1.000874 -k 0 -k 1 -k 2 -k 3 -name "ltArmCurve"`; //Thumb Curve string $thumbCurve = `curve -d 1 -p 9.993154 20.301521 -0.642345 -p 10.213599 20.240813 -0.283308 -p 10.409658 20.176515 -0.0685768 -p 10.732559 20.064121 0.241602 -k 0 -k 1 -k 2 -k 3 -name "ltThumbCurve"` ; //Index Finger string $indexCurve = `curve -d 1 -p 10.702477 20.292566 -0.51586 -p 11.362413 20.286834 -0.3374 -p 11.721185 20.283718 -0.239295 -k 0 -k 1 -k 2 -name "ltIndexCurve"`; //Middle Finger string $middleCurve = `curve -d 1 -p 10.772884 20.291806 -0.795933 -p 11.473165 20.285644 -0.766378 -p 11.864258 20.282208 -0.737966 -k 0 -k 1 -k 2 -name "ltMiddleCurve"` ; //Ring Finger string $ringCurve = `curve -d 1 -p 10.799495 20.291416 -1.108748 -p 11.43739 20.285746 -1.197087 -p 11.788797 20.282624 -1.241038 -k 0 -k 1 -k 2 -name "ltRingCurve"`; //Pinky Finger string $pinkyCurve = `curve -d 1 -p 10.139066 20.297126 -1.342001 -p 10.687056 20.220765 -1.390702 -p 11.266868 20.232679 -1.537768 -p 11.530955 20.216215 -1.605732 -k 0 -k 1 -k 2 -k 3 -name "pinkyCurve"`; // template the curves select -r ltLegCurve ; select -tgl spineCurve ; select -tgl ltArmCurve ; select -tgl ltThumbCurve ; select -tgl ltIndexCurve ; select -tgl ltMiddleCurve ; select -tgl ltRingCurve ; select -tgl pinkyCurve ; group -name "guideCurves"; TemplateObject; select -cl; // create the clusters and spheres // create a blue shader for the spheres if( !`objExists "sphereColorShader"`) { shadingNode -asShader lambert -n "sphereColorShader"; sets -renderable true -noSurfaceShader true -empty -name "sphereColorShaderSG"; connectAttr -f sphereColorShader.outColor sphereColorShaderSG.surfaceShader; setAttr sphereColorShader.color 0 0 1; } // create the spheres with a prefix name select $armCurve; clusterOnCurve("ltArm"); select $spineCurve; clusterOnCurve("spine"); select $legCurve; clusterOnCurve("ltLeg"); select $thumbCurve; clusterOnCurve("ltThumb"); select $indexCurve; clusterOnCurve("ltIndex"); select $middleCurve; clusterOnCurve("ltMiddle"); select $ringCurve; clusterOnCurve("ltRing"); select $pinkyCurve; clusterOnCurve("ltPinky"); //then parent the ends of the spheres parent ltArmLoc1 guideScale; parent ltThumbLoc1 ltArmLoc4; parent ltIndexLoc1 ltArmLoc4; parent ltMiddleLoc1 ltArmLoc4; parent ltRingLoc1 ltArmLoc4; parent ltPinkyLoc1 ltArmLoc4; // delete emptyNodes groups select -r ltArm; select -add ltThumb; select -add ltIndex; select -add ltMiddle; select -add ltMiddle; select -add ltRing; select -add ltPinky; delete; select -cl; //set the focus to the perspective panel //and change the display mode setFocus "modelPanel4"; DisplayShadedAndTextured; changeSelectMode -object; } //====================================================================== // DESCRIPTION: calls joint on curve proc with the name of the curve //====================================================================== global proc createDaBones() { jointOnCurve("bone_Lleg","ltLegCurve",0,0); jointOnCurve("bone_spine","spineCurve",0,0); jointOnCurve("bone_LArm","ltArmCurve",0,0); jointOnCurve("bone_Lthumb","ltThumbCurve",0,0); jointOnCurve("bone_Lindex","ltIndexCurve",0,0); jointOnCurve("bone_Lmiddle","ltMiddleCurve",0,0); jointOnCurve("bone_Lring","ltRingCurve",0,0); jointOnCurve("bone_Lpinky","pinkyCurve",0,0); delete guideScale; delete guideCurves; } //====================================================================== // DESCRIPTION: A proc used to create a number of joint on a degree one curve //====================================================================== global proc jointOnCurve (string $jointName, string $curve,int $startLoop,int $endLoop) { int $i = 1; string $j[]; createNode curveInfo -n ($curve +"_curveLength"); string $curveShape[] = `listRelatives $curve`; connectAttr -f ($curveShape[0] + ".worldSpace[0]") ($curve +"_curveLength.inputCurve"); int $curveDegree = `getAttr ($curveShape[0] +".degree")`; int $curveSpans = `getAttr ($curveShape[0] +".spans")`; int $curveCvNum = ($curveDegree + $curveSpans); for ($i = $startLoop;$i<$curveCvNum - $endLoop;$i++) { float $cvPos[] = `getAttr ($curve +"_curveLength.controlPoints["+$i+"]")`; $j[$i] = `joint -p $cvPos[0] $cvPos[1] $cvPos[2] -n ($jointName + ($i +1))`; if($startLoop == 0) { setAttr ($j[$i] + ".jointOrientX") 0; setAttr ($j[$i] + ".jointOrientY") 0; setAttr ($j[$i] + ".jointOrientZ") 0; } } select -r ($jointName +"1"); if($jointName == "bone_spine" || $jointName == "bone_Lleg" ||$jointName == "bone_Lthumb") { joint -e -oj xzy -secondaryAxisOrient xup -ch -zso; } if($jointName == "bone_Lindex" || $jointName == "bone_Lmiddle" || $jointName == "bone_Lring" || $jointName == "bone_Lpinky" ) { joint -e -oj xzy -secondaryAxisOrient zdown -ch -zso; } if($jointName == "bone_LArm") { joint -e -oj xzy -secondaryAxisOrient ydown -ch -zso; } select -r $j[$i -1]; joint -e -oj none -zso; select -cl; } //====================================================================== // DESCRIPTION: Create a cluster for each CV of selected curve(s). //====================================================================== global proc clusterOnCurve(string $prefix) { int $num = 1; string $sel[] = `ls -sl`; for ($s in $sel) { //Determine if the shape of the selection is a nurbsCurve. string $shape[] = `listRelatives -s $s`; if ((`size $shape`) && (`nodeType $shape[0]` == "nurbsCurve")) { string $cvs[] = `ls -fl ($s + ".cv[*]")`; for ($cv in $cvs) { //create a cluster at that cv cluster -name ($prefix + $num) $cv; //select the cluster select -r ($prefix + $num +"Handle"); //get the selection and rename it //then hide the clusters string $sel[] = `ls -sl`; string $newCluster = `rename $sel ($prefix + "Cluster" + $num)`; select $newCluster; HideSelectedObjects; // create a sphere and pointconstraint to the cluster // Delete the constraint // Then constrain the cluster to the sphere switch ($prefix) { case "ltArm": string $sphere[] = `sphere -name ($prefix + "Loc" + $num) -r 0.2`; string $con[] = `pointConstraint $newCluster $sphere`; delete $con; makeIdentity -apply true -t 1 $sphere[0]; pointConstraint $sphere $newCluster; break; case "ltLeg": string $sphere[] = `sphere -name ($prefix + "Loc" + $num) -r 0.2`; string $con[] = `pointConstraint $newCluster $sphere`; delete $con; makeIdentity -apply true -t 1 $sphere[0]; pointConstraint $sphere $newCluster; break; case "spine": string $sphere[] = `sphere -name ($prefix + "Loc" + $num) -r 0.2`; string $con[] = `pointConstraint $newCluster $sphere`; delete $con; makeIdentity -apply true -t 1 $sphere[0]; pointConstraint $sphere $newCluster; break; case "ltThumb": string $sphere[] = `sphere -name ($prefix + "Loc" + $num) -r 0.1`; string $con[] = `pointConstraint $newCluster $sphere`; delete $con; makeIdentity -apply true -t 1 $sphere[0]; pointConstraint $sphere $newCluster; break; case "ltIndex": string $sphere[] = `sphere -name ($prefix + "Loc" + $num) -r 0.1`; string $con[] = `pointConstraint $newCluster $sphere`; delete $con; makeIdentity -apply true -t 1 $sphere[0]; pointConstraint $sphere $newCluster; break; case "ltMiddle": string $sphere[] = `sphere -name ($prefix + "Loc" + $num) -r 0.1`; string $con[] = `pointConstraint $newCluster $sphere`; delete $con; makeIdentity -apply true -t 1 $sphere[0]; pointConstraint $sphere $newCluster; break; case "ltRing": string $sphere[] = `sphere -name ($prefix + "Loc" + $num) -r 0.1`; string $con[] = `pointConstraint $newCluster $sphere`; delete $con; makeIdentity -apply true -t 1 $sphere[0]; pointConstraint $sphere $newCluster; break; case "ltPinky": string $sphere[] = `sphere -name ($prefix + "Loc" + $num) -r 0.1`; string $con[] = `pointConstraint $newCluster $sphere`; delete $con; makeIdentity -apply true -t 1 $sphere[0]; pointConstraint $sphere $newCluster; break; }//end case //assign the blue shader to the sphere sets -e -forceElement sphereColorShaderSG; $num++; }//end for }//end if }//end for select -cl; $num = $num -1; // freeze transformation on the spheres for ($i = 1; $i <=$num; $i++) { select -r ($prefix + "Loc" + $i); //makeIdentity -apply true -t 1; DeleteHistory; select -cl; } // select all the sphere locators on the curve for ($i = 1; $i <=$num; $i++) { select -add($prefix + "Loc" + $i); } //group under the guideScale string $grp = `group -name $prefix`; parent $grp guideScale; select -cl; // select all the clusters for that curve for ($i = 1; $i <=$num; $i++) { select -add($prefix + "Cluster" + $i); } // group under the guideScale string $grp = `group -name ($prefix + "Clusters")`; parent $grp guideScale; select -cl; // parent the sphere loc ators in a hierachy for ($i = $num; $i > 1; $i--) { int $temp = $i -1; parent ($prefix + "Loc" + $i) ($prefix + "Loc" + $temp); } } //==================================================================== // DESCRIPTION: will take the topNode and relist the joint children. //====================================================================== proc string[] snTemplateSkeleton_reList(string $topNode) { int $i; global string $gJointNames[]; string $relisted[]; clear($relisted); $relisted = `ls -type joint -sl -dag`; for($i = 0; $i < `size($relisted)`;$i++) { $gJointNames[$i] = $relisted[$i]; print $gJointNames[$i]; } return $relisted; } //==================================================================== // DESCRIPTION: will lock and make unkeyable all attrs on node. //====================================================================== proc snTemplateSkeleton_lockOff(string $node) { string $attrs[] = `listAttr -k $node`; for($each in $attrs) setAttr -k 0 -l 1 ($node + "." + $each); } //==================================================================== // DESCRIPTION: this will create the rotation group and return its name. //====================================================================== proc string snTemplateSkeleton_createRotGrp(string $fromJt, string $toJt, string $xtraGrp) { string $rotGrpA = `group -em -name ($fromJt+"RotGrpAN_#")`; string $rotGrpB = `group -em -name ($fromJt+"RotGrpBN_#")`; string $rotGrpC = `group -em -name ($fromJt+"ManRotGrpCN_#")`; // create arrows that show z rotation string $arrow = `curve -d 1 -p 0 0.6 0 -p -0.4 0 0 -p -0.2 0 0 -p -0.2 -0.6 0 -p 0.2 -0.6 0 -p 0.2 0 0 -p 0.4 0 0 -p 0 0.6 0 -k 0 -k 1 -k 2 -k 3 -k 4 -k 5 -k 6 -k 7 -name ($fromJt + "upArrow_#")`; //move arrow in y move -os 0 1 0; select -r $arrow; if(!`attributeExists "toJoint" $arrow`) addAttr -dt "string" -ln "toJoint" $arrow; if(!`attributeExists "toUpLoc" $fromJt`) addAttr -dt "string" -ln "toUpLoc" $fromJt; connectAttr -f ($fromJt+".toUpLoc")($arrow +".toJoint"); connectAttr -f ($fromJt+".rotateArrow") ($rotGrpB +".rx"); parent $arrow $rotGrpC; parent $rotGrpC $rotGrpB; parent $rotGrpB $rotGrpA; pointConstraint $fromJt $rotGrpA; aimConstraint -u 0 1 0 -wut "scene" $toJt $rotGrpA; snTemplateSkeleton_lockOff $rotGrpC; setAttr -e -l 0 -k 1 ($rotGrpC +".rx"); snTemplateSkeleton_lockOff $rotGrpB; string $parent[] = `parent $rotGrpA $xtraGrp`; return $parent[0]; } //====================================================================== // DESCRIPTION: this will find the up vector locator via connections //====================================================================== proc string snTemplateSkeleton_getAimUpObj(string $joint) { string $loc[] = `listConnections -s 0 -d 1 -scn 1 ($joint+".toUpLoc")`; if(!`objExists $loc[0]`) error("snTemplateSkeleton_getAimUpObj -> "+$loc[0]+" doesn't exist"); return $loc[0]; } //====================================================================== // DESCRIPTION: will create the Template Joint Chains via selection //====================================================================== global proc snTemplateSkeleton_createTemp_doIt() { string $sel[] = `ls -sl -type "joint"`; if(size($sel) < 1) error("snTemplateSkeleton_createTemp_doIt -> Select one or more Joints"); for($each in $sel) snTemplateSkeleton_createTemp $each; select -cl; } //====================================================================== // DESCRIPTION: will create the reBuilt Joint Chains from templates // via selection //====================================================================== global proc snTemplateSkeleton_reBuildChain_doIt() { string $sel[] = `ls -sl`; if(size($sel) < 1) error("snTemplateSkeleton_reBuildChain_doIt -> Select at least one templateChain TopNode"); select -cl; for($each in $sel) snTemplateSkeleton_reBuildChain $each; select -cl; } //==================================================================== // DESCRIPTION: this will create the template chain group //==================================================================== global proc string snTemplateSkeleton_createTemp(string $chainTopNode) { //to surpress any cycle errors cycleCheck -e off; string $tempChainTop; if(!`objExists $chainTopNode`) error("snTemplateSkeleton_createTemp -> "+$chainTopNode+" doesn't exist"); if(!`objectType -i "joint" $chainTopNode`) error("snTemplateSkeleton_createTemp -> "+$chainTopNode+" not of type \"joint\""); string $grpTopNode = `group -em -n "snTemplateSkeletonN_#"`; string $jointTopNode = `group -em -n "jointsN_#"`; string $xtrasTopNode = `group -em -n "xtrasN_#"`; snTemplateSkeleton_lockOff $grpTopNode; snTemplateSkeleton_lockOff $jointTopNode; snTemplateSkeleton_lockOff $xtrasTopNode; if(!`attributeExists "rotateArrowScale" $grpTopNode`) { addAttr -ln "rotateArrowScale" -at double -min 0 -dv 1.0 $grpTopNode; } setAttr -e -keyable true ($grpTopNode+".rotateArrowScale"); string $fullPathNames[] = `parent $jointTopNode $xtrasTopNode $grpTopNode`; // print $fullPathNames; string $topJoint[] = `parent $chainTopNode $fullPathNames[0]`; string $reListed[] = `snTemplateSkeleton_reList $topJoint[0]`; for ($i = 0; $i < (size($reListed) - 1); $i++) { if(!`attributeExists "rotateArrow" $reListed[$i]`) { addAttr -ln "rotateArrow" -at double -min -360 -max 360 $reListed[$i]; } setAttr -e -keyable true ($reListed[$i]+".rotateArrow"); string $rotGrp = `snTemplateSkeleton_createRotGrp $reListed[$i] $reListed[($i+1)] $xtrasTopNode`; connectAttr -f ($grpTopNode + ".rotateArrowScale") ($rotGrp + ".sx"); connectAttr -f ($grpTopNode + ".rotateArrowScale") ($rotGrp + ".sy"); connectAttr -f ($grpTopNode + ".rotateArrowScale") ($rotGrp + ".sz"); snTemplateSkeleton_lockOff $rotGrp; } select $grpTopNode; print "Done creating Template Skeleton"; $tempChainTop = $grpTopNode; return $tempChainTop; } //====================================================================== // DESCRIPTION: this will create the rebuilt chain with correct axis //====================================================================== global proc string snTemplateSkeleton_reBuildChain(string $chainTopNode) { string $rebuiltChain; global string $gJointNames[]; string $newSkele[]; float $jointRadius[]; clear($newSkele); if(!`objExists $chainTopNode`) error("snTemplateSkeleton_reBuildChain -> "+$chainTopNode+" doesn't exist"); string $joints[] = `ls -type joint -dag $chainTopNode`; print $joints; for($i = 0; $i < size($joints); $i++) { $newSkele[$i] = `joint -p $i 0 0`; $jointRadius[$i] = `getAttr ($joints[$i] + ".radius")`; } for($i = 0; $i < (size($joints)-1); $i++) { float $xyzs[] =`xform -q -a -ws -t $joints[$i]`; xform -a -ws -t $xyzs[0] $xyzs[1] $xyzs[2] $newSkele[$i]; string $aimObj = `snTemplateSkeleton_getAimUpObj $joints[$i]`; string $aims[]=`aimConstraint -aim 1 0 0 -u 0 1 0 -wuo $aimObj -wut "objectrotation" $joints[$i+1] $newSkele[$i]`; float $rotss[]=`getAttr ($newSkele[$i]+".rotate")`; delete $aims; setAttr ($newSkele[$i]+".rotate") 0 0 0; setAttr ($newSkele[$i]+".jointOrient") $rotss[0] $rotss[1] $rotss[2]; //Maya 7 feature. Keep the same joint raduis setAttr($newSkele[$i] + ".radius") $jointRadius[$i]; } //Make the last joint the same radius setAttr($newSkele[$i + 1] + ".radius") $jointRadius[$i]; float $trans[] =`xform -q -a -ws -t $joints[$i]`; xform -a -ws -t $trans[0] $trans[1] $trans[2] $newSkele[$i]; for($each in $newSkele) setAttr ($each + ".rotateOrder") 3; string $parentTest[] = `listRelatives -p -pa $newSkele[0]`; if(`objExists $parentTest[0]`) { string $newParent[]=`parent -w $newSkele[0]`; $rebuiltChain = $newParent[0]; } else $rebuiltChain = $newSkele[0]; delete $chainTopNode; //rename new joints to what the old joints were named for($i = 0; $i < `size($joints)`; $i++) rename $newSkele[$i] $gJointNames[$i]; return $rebuiltChain; } //====================================================================== // DESCRIPTION: slides the new joint in X. Keeps the joint on proper position //====================================================================== global proc moveJoint(float $sliderPosition) { string $newJoint[] = `ls -sl -type joint`; if (size($newJoint) == 0) error "No joint selected. Select a joint and retry."; string $jointA[] = `listRelatives -pa -p -type joint $newJoint[0]`; if (size($jointA) == 0) error "Joint must have parent joint."; string $jointB[] = `listRelatives -pa -c -type joint $newJoint[0]`; if (size($jointB[0]) == 0) error "Joint must have child joint."; float $posA[3] = `xform -q -ws -t $jointA[0]`; float $posB[3] = `xform -q -ws -t $jointB[0]`; vector $vectorA = <<$posA[0], $posA[1], $posA[2]>>; vector $vectorB = <<$posB[0], $posB[1], $posB[2]>>; vector $lengthVector = ($vectorB - $vectorA) * $sliderPosition; vector $startVector = $lengthVector + $vectorA; move -a ($startVector.x) ($startVector.y) ($startVector.z) ($newJoint[0] + ".rotatePivot") ($newJoint[0] + ".scalePivot"); move -a $posB[0] $posB[1] $posB[2] $jointB[0]; select -r $newJoint[0]; } //====================================================================== // DESCRIPTION: Procedure for inserting a single joint. //====================================================================== global proc insertAJoint() { float $position = `floatSlider -q -v jointPositionSlider`; string $startJoint[] = `ls -sl -type joint`; string $endJoint[] = `listRelatives -path -c -type joint $startJoint`; if (! `size $startJoint`) error "No joint specified. Try again."; if (! `size $endJoint`) error "Joint has no child joints. Try again."; if (`size $endJoint` > 1) error "Joint has multiple child joints. This causes unexpected results. Select a joint with one child joint and try again."; float $posA[] = `xform -q -ws -t $startJoint`; float $posB[] = `xform -q -ws -t $endJoint[0]`; vector $vectorA = <<$posA[0], $posA[1], $posA[2]>>; vector $vectorB = <<$posB[0], $posB[1], $posB[2]>>; vector $lengthVector = ($vectorB - $vectorA) * $position; vector $startVector = $lengthVector + $vectorA; string $newJoint = `insertJoint $startJoint`; move -a ($startVector.x) ($startVector.y) ($startVector.z) ($newJoint + ".rotatePivot") ($newJoint + ".scalePivot"); } //====================================================================== // DESCRIPTION: Gets the selection and mirrors the joints //====================================================================== global proc mirrorMyJoints() { string $sel[] = `ls -sl -type joint `; if(`size($sel)` < 1) error("-> Select one joint"); if(`size($sel)` > 1) error("-> Select one joint"); mirrorJoint -mirrorBehavior -myz -searchReplace "_L" "_R" $sel; }