|

Creating new Maya
Tools using MEL
Another much less used feature of Maya is the creation of a custom
tool. We already use tools like the Birail, or IK handle, or joint tool,
all of which are tools which use the scriptCtx command to
create a new tool based on the selection tool.
In this tutorial we will first create a simple tool that implements our
Stretchy
IK arm script that we developed earlier.
To create a tool we first have to define the tool using the
scriptCtx command, and then invoke the tool with the
setToolTo command. The minimum number of flags needed for
a tool is the number of selections sets
required
scriptCtx -totalSelectionSets 1 StretchyIK; setToolTo StretchyIK;
Next we can give it a title
scriptCtx -totalSelectionSets
1 -title "Stretchy IK" StretchyIK; setToolTo
StretchyIK;
Pasting this into the script editor will come up
with the following error;
| |
Error: Object's name is not unique:
StretchyIK |
So as with our User Interface example we will have to do a test to see
if the tool exists first
if( `scriptCtx -exists StretchyIK`
) deleteUI StretchyIK; scriptCtx
-totalSelectionSets 1 -title "Stretchy
IK" StretchyIK; setToolTo StretchyIK;
The next thing we can do is specify which icon we wish to be displayed
in the active tool slot on the tool bar
if( `scriptCtx -exists StretchyIK` )
deleteUI StretchyIK; scriptCtx -totalSelectionSets 1 -title
"Stretchy IK" -i1 "blendSurface.xpm"
StretchyIK; setToolTo StretchyIK;
We can also specify which type of cursor we wish the tool to use
if( `scriptCtx -exists StretchyIK` )
deleteUI StretchyIK; scriptCtx -totalSelectionSets 1 -title
"Stretchy IK" -i1 "blendSurface.xpm" -toolCursorType
"create" StretchyIK; setToolTo StretchyIK;
Next we can give some instructions as to how the tool is used
if( `scriptCtx -exists StretchyIK` )
deleteUI StretchyIK; scriptCtx -totalSelectionSets 1 -title
"Stretchy IK" -i1 "blendSurface.xpm" -toolCursorType
"create" -setNoSelectionPrompt "Select the shoulder and wrist
joint for the IK arm" StretchyIK; setToolTo StretchyIK;
Note now, that if we select an object the tool instantly completes its
function. This is because we have not specified how the tool is to handle
multiple selections. First we need to specify how many
objects we want to be selectable, and we want to be able to add the second selection into the selection set,
that is, to toggle the selection set
if( `scriptCtx -exists StretchyIK` )
deleteUI StretchyIK; scriptCtx -totalSelectionSets 1 -title
"Stretchy IK" -i1 "blendSurface.xpm" -toolCursorType
"create" -setNoSelectionPrompt "Select the shoulder and wrist joint for
the IK arm" -setSelectionCount
2 -setAutoToggleSelection true StretchyIK; setToolTo StretchyIK;
Now that we can select both objects we can give some instructions after
the first selection is made
if( `scriptCtx -exists StretchyIK` )
deleteUI StretchyIK; scriptCtx -totalSelectionSets 1 -title
"Stretchy IK" -i1 "blendSurface.xpm" -toolCursorType
"create" -setNoSelectionPrompt "Select the shoulder and wrist joint for
the IK arm" -setSelectionPrompt "Shoulder selected, please now
select the wrist" -setAutoToggleSelection
true -setSelectionCount 2 StretchyIK; setToolTo
StretchyIK;
and some nice words of wisdom to terminate the tool action
if( `scriptCtx -exists StretchyIK` )
deleteUI StretchyIK; scriptCtx -totalSelectionSets 1 -title
"Stretchy IK" -i1 "blendSurface.xpm" -toolCursorType
"create" -setNoSelectionPrompt "Select the shoulder and wrist joint for
the IK arm" -setSelectionPrompt "Shoulder selected, please now select
the wrist" -setDoneSelectionPrompt "Wrist
selected" -setAutoToggleSelection true -setSelectionCount
2 StretchyIK; setToolTo StretchyIK;
We can now limit the tool so that it only works on joints
if( `scriptCtx -exists StretchyIK` )
deleteUI StretchyIK; scriptCtx -totalSelectionSets 1 -title
"Stretchy IK" -i1 "blendSurface.xpm" -toolCursorType
"create" -setNoSelectionPrompt "Select the shoulder and wrist joint for
the IK arm" -setSelectionPrompt "Shoulder selected, please now select
the wrist" -setDoneSelectionPrompt "Wrist
selected" -setAutoToggleSelection true -setSelectionCount
2 -joint true StretchyIK; setToolTo StretchyIK;
Now that our tool interface is setup, we can actually make it DO
something
if( `scriptCtx -exists StretchyIK` )
deleteUI StretchyIK; scriptCtx -totalSelectionSets 1 -title
"Stretchy IK" -i1 "blendSurface.xpm" -toolCursorType
"create" -setNoSelectionPrompt "Select the shoulder and wrist joint for
the IK arm" -setSelectionPrompt "Shoulder selected, please now select
the wrist" -setDoneSelectionPrompt "Wrist
selected" -setAutoToggleSelection true -setSelectionCount
2 -joint true -finalCommandScript ( "performStretchyIK
$Selection1 $Selection2") StretchyIK; setToolTo StretchyIK;
proc performStretchyIK($Selection1,
$Selection2) { print("yay "+$Selection1+"
"+$Selection2); } setToolTo StretchyIK;
Now that we have our tool working nicely we just have to insert our
stretchy IK code into the performStretchyIK code.
Here is the final code
===========================================================================
if( `scriptCtx -exists StretchyIK` )
deleteUI StretchyIK; scriptCtx -totalSelectionSets 1 -title
"Stretchy IK" -i1 "blendSurface.xpm" -toolCursorType
"create" -setNoSelectionPrompt "Select the shoulder and wrist joint for
the IK arm" -setSelectionPrompt "Shoulder selected, please now select
the wrist" -setDoneSelectionPrompt "Wrist
selected" -setAutoToggleSelection true -setSelectionCount
2 -joint true -finalCommandScript (
"performStretchyIK;") StretchyIK; setToolTo StretchyIK;
proc
performStretchyIK() { string $jointSelection[]; float $jointTrans1[], $jointTrans2[]; $jointSelection
= `ls -sl`; string $topJoint = $jointSelection[0]; string $botJoint
= $jointSelection[1]; string $allDescendent[] = eval("listRelatives -ad
"+$jointSelection[1]); for($i in
$allDescendent) { if($i==$jointSelection[0]) { $topJoint =
$jointSelection[1]; $botJoint =
$jointSelection[0]; } } $jointTrans1 = eval("pointPosition -w
"+$topJoint+".selectHandle"); $jointTrans2 = eval("pointPosition -w
"+$botJoint+".selectHandle"); distanceDimension -sp $jointTrans1[0] $jointTrans1[1] $jointTrans1[2] -ep $jointTrans2[0] $jointTrans2[1] $jointTrans2[2]; string
$distanceMeasures[]; $distanceMeasures = `ls -sl`; rename
$distanceMeasures[1] "stretchLimit"; string $mLocators[]; $mLocators
= ` listConnections stretchLimitShape`; pointConstraint -n pc0
$topJoint $mLocators[0]; pointConstraint -n pc1 $botJoint
$mLocators[1]; createNode -n wrist_controllerShape
implicitSphere; group -n wrist_grp wrist_controller; move
$jointTrans2[0] $jointTrans2[1] $jointTrans2[2] wrist_grp; ikHandle -n
wrist_IK -sj $topJoint -ee $botJoint; parent wrist_IK wrist_controller;
shadingNode -n limitCondition -asUtility condition; setAttr
limitCondition.operation 2; //Greater Than shadingNode -n stretchScale
-asUtility multiplyDivide; setAttr stretchScale.operation 2; //Divide
Operation setAttr "wrist_controller.translateX" 10; float
$unitStretch = `getAttr stretchLimitShape.distance`; connectAttr -f
stretchLimitShape.distance limitCondition.firstTerm; setAttr
"limitCondition.secondTerm" $unitStretch; connectAttr -f
stretchLimitShape.distance stretchScale.input1X; setAttr
"stretchScale.input2X" $unitStretch; connectAttr -f
stretchScale.outputX limitCondition.colorIfTrueR; setAttr
"wrist_controller.translateX" 0; delete pc1; parent $mLocators[1]
wrist_controller; eval("connectAttr -f limitCondition.outColorR
"+$topJoint+".scaleX"); $elbowJoint = `listRelatives - c
$topJoint`; eval("connectAttr -f limitCondition.outColorR
"+$elbowJoint[0]+".scaleX"); setAttr "stretchLimit.visibility"
0; eval("setAttr "+$mLocators[0]+".visibility 0");
eval("setAttr "+$mLocators[1]+".visibility 0"); }
===========================================================================
|