|

Interfaces using
MEL
To introduce the use of user interfaces using MEL we first have to have
an idea of the kind of interface we wish to design.
For this example we are going to create an interface to implement the
creation and options for a custom primitive, a pill, primitive.
First things first lets write a simple script to create a pill
primitive.
|
Step 1: create a sphere
sphere -p 0 0 0 -ax 0 1
0 -r 1 -n tmpSphere; // new sphere radius 1, at
the origin with Y as the up axis. |

|
|
Step 2: select its middle
isoparm and use it to split the sphere in two.
detachSurface -ch 1
-rpo 1 -n detSphere tmpSphere.u[2]; // split it
down the centre |

|
|
Step 3: move the halves
equally above and below the axis
setAttr
"detSphere.translateY" 1; // top hemisphere up
by 1 setAttr "tmpSphere.translateY" -1; // bottom hemisphere down by
1 |

|
|
Step 4: attach the two halves
into a pill shape
select -r
detSphere.u[2] ; // top hemisphere
isoparm select -tgl tmpSphere.u[2] ; // bottom hemisphere
isoparm attachWithoutMoving; |

|
|
Step 5: Clean up the surface
and give it a name
makeIdentity -apply
true -t 1 -r 1 -s 1 tmpSphere; // freeze
transformations xform -cp tmpSphere; // centre its pivot rename "tmpSphere"
"nurbsPill1"; |
 |
Here is the code all together if you want to cut and paste it into the
script editor
sphere -p 0 0 0 -ax 0 1 0 -r 1 -n tmpSphere;
detachSurface -ch 1 -rpo 1 -n detSphere tmpSphere.u[2]; setAttr
"detSphere.translateY" 1; setAttr "tmpSphere.translateY" -1; delete
-ch tmpSphere detSphere; select -r
detSphere.u[2] ; select -tgl tmpSphere.u[2]
; attachWithoutMoving; xform -cp tmpSphere; makeIdentity -apply
true -t 1 -r 1 -s 1 tmpSphere; rename "tmpSphere"
"nurbsPill1"; delete detSphere;
With our script already working nicely we want to design a user
interface that will allow us to specify the radius and length of the
pill.
The first step in creating a user interface is to create a window. In
MEL it is quite simply "window". In calling the window
function we should also give it a name a title and tell Maya how
big we want it to be, so we have thus;
window -w 400 -h 200
-title "NURBS Pill Options" pillWindow; showWindow pillWindow;
This will create the following window.

There is a problem though here. If you close the window then repaste
the code in you should get the following error.
| |
Error: Object's name is not unique:
pillWindow |
This is because although we have closed the window, it still exists
deep within the bowels of Maya, so we need to flush it out first, before
we can reuse this code. To do this we use a "deleteUI" command , with an initial test to see if it already exists.
if (`window -exists
pillWindow`) deleteUI
pillWindow;
window -w 400 -h 200 -title
"NURBS Pill Options" pillWindow; showWindow pillWindow;
UI Layouts
Before we start to put things into our windows we need to create some
kind of formatting of the window into rows and columns. The most simple
kind of format is to simply say that the window consists of columns using
the "columnLayout" command. It
can have a multitude of parameters, but for now lets leave it simple.
Without its options set it defaults to a single column layout and every
new additional element is simply put onto the next row.
Now for some controls
So now we have our window we would like to create some controls that
allow us to specify the radius and length of our pill.
To create a slider we can use the "floatSliderGrp" command labelled Radius
if (`window -exists pillWindow`) deleteUI
pillWindow; window -w 400 -h 200 -title "NURBS Pill Options"
pillWindow; columnLayout; floatSliderGrp -label "Radius
"pillRadius; showWindow pillWindow;
To add a field that allows us to see and modify the current value of
the radius we can add the -field
true flag
if (`window -exists pillWindow`) deleteUI
pillWindow; window -w 400 -h 200 -title "NURBS Pill Options"
pillWindow; columnLayout; floatSliderGrp -label "Radius" -field true
pillRadius; showWindow pillWindow;

The next thing
we may wish to change is the maximum and minimum range of our slider. We
do this by specifying maxValue and minValue flags. We may also wish to set a default
value for the slider and this is done with the -value
flag.
if (`window -exists pillWindow`) deleteUI
pillWindow; window -w 400 -h 200 -title "NURBS Pill Options"
pillWindow; columnLayout; floatSliderGrp -label "Radius"
-field true
-minValue 0 -maxValue
1 -value 1 pillRadius; showWindow
pillWindow;
We can repeat this now for a slider that will specify the pill's
length. Note that by not specifying the maxValue the slider can reach
values up to 100.
if (`window -exists pillWindow`) deleteUI
pillWindow; window -w 400 -h 200 -title "NURBS Pill Options"
pillWindow; columnLayout; floatSliderGrp -label "Radius "
-field true
-minValue 0 -maxValue 1 -value 1 pillRadius; floatSliderGrp -label
"Length" -field true -minValue 0 -value 1
pillLength; showWindow
pillWindow;

Finally we need some buttons to control the creation of our pill.
Before we create our button, lets add some more formatting. We will use a
rowLayout command now with 5 columns and a
width of 500. In each column of the row we will
create a columnLayout that spans the buttons over the
column, creates a spacer of 10 pixels
between the sliders and the buttons, a 5 pixel
spacer between each button
if
(`window -exists pillWindow`) deleteUI pillWindow; window -w 500 -h
200 -title "NURBS Pill Options" pillWindow; columnLayout
; floatSliderGrp -label "Radius "
-field true
-minValue 0 -maxValue 1 -value 1 pillRadius; floatSliderGrp -label "Length"
-field true -minValue
0 -value 1 pillLength; rowLayout -numberOfColumns 5 -width
500 MainRow; columnLayout -columnAttach
"both" 5 -rowSpacing
10 -parent MainRow Column1; // A
Spacer columnLayout -columnAttach "both"
5 -rowSpacing 10
-parent MainRow Column2; button;
columnLayout -columnAttach "both" 5 -rowSpacing 10 -parent
MainRow Column3; button; columnLayout
-columnAttach "both" 5 -rowSpacing 10 -parent
MainRow Column4; button; columnLayout -columnAttach "both" 5
-rowSpacing 10 -parent MainRow
Column5;
// A
Spacer showWindow
pillWindow;

Now we want to give each of the buttons a function. The first will call
our initial pill creation script, the second will reset the Radius and
Length to 1 and the last one will close the window. The functions of the
buttons are carried out by assigning a "command" flag to the button.
To close the window, we can assign a deleteUI command to the close
button
button -label "Close" -command
"deleteUI pillWindow";
To reset the sliders we will have to set the floatSliderGrp value flags
both to 1.
button -label "Reset" -command
"floatSliderGrp -e
-value 1 pillLength; floatSliderGrp -e -value 1
pillRadius";
And finally we need to call our create pill procedure when we click the
"create" button.
button -label "Create" -command
"createPill";
With the createPill procedure being
proc createPill() { float
$Rad = `floatSliderGrp -q -value pillRadius`;
// query the slider as to the
current radius float $Len =
`floatSliderGrp -q -value pillLength`;
// query the slider as to the
current length print("create a pill of radius "+$Rad+" and
length "+$Len); // Insert the rest of the Pill code here... }
The entire code now becomes thus
if (`window -exists pillWindow`) deleteUI
pillWindow; window -w 500 -h 200 -title "NURBS Pill Options"
pillWindow; columnLayout ; floatSliderGrp -label "Radius "
-field true -minValue 0 -maxValue 1 -value 1
pillRadius; floatSliderGrp -label "Length" -field true
-minValue 0 -value 1 pillLength; rowLayout -numberOfColumns 5
-width 500 MainRow; columnLayout -columnAttach "both" 5 -rowSpacing
10 -parent MainRow Column1; // A Spacer columnLayout -columnAttach
"both" 5 -rowSpacing 10 -parent MainRow Column2; button -label "Create" -command
"createPill";
columnLayout -columnAttach "both" 5 -rowSpacing 10 -parent
MainRow Column3; button -label "Reset"
-command "floatSliderGrp -e -value 1 pillLength; floatSliderGrp -e
-value 1 pillRadius"; // Reset
columnLayout -columnAttach "both" 5 -rowSpacing 10 -parent
MainRow Column4; button -label "Close" -command "deleteUI
pillWindow"; // Close
the dialog columnLayout -columnAttach "both" 5 -rowSpacing
10 -parent MainRow Column5; // A Spacer showWindow pillWindow;
proc createPill() { float
$Rad = `floatSliderGrp -q -value pillRadius`; float $Len =
`floatSliderGrp -q -value pillLength`;
print("create a pill of radius "+$Rad+"
and length "+$Len); // Insert the rest of the Pill code here... }
All we have to do now is to modify our script into a procedure that has
both the radius and
length as parameters. Radius is simple, we just substitute this
value into the sphere command. The length on the other hand needs a bit of
thought. When length = 1, we have a special case, ie, a sphere. In this
case the translations of the hemispheres will be 0. For all other cases,
the length will be divided by 2 and added/subtracted from the upper and
lower hemispheres respectively. So the operation would be to first
subtract 1 from the height, and use half of the remainder to add/subtract
respectively. This raises an exception for the sliders. We must therefore
force a minimum length of 1 not 0 as before.
sphere -p 0 0 0 -ax 0 1 0 -r $Rad -n tmpSphere; detachSurface -ch 1
-rpo 1 -n detSphere tmpSphere.u[2]; setAttr "detSphere.translateY"
($Len-1)/2; setAttr
"tmpSphere.translateY" -($Len-1)/2; delete -ch tmpSphere
detSphere; select -r detSphere.u[2] ; select -tgl tmpSphere.u[2]
; attachWithoutMoving; xform -cp tmpSphere; makeIdentity -apply
true -t 1 -r 1 -s 1 tmpSphere; rename "tmpSphere"
"nurbsPill1"; delete detSphere;
So now our final code will be thus
=============================================================================================
if (`window -exists pillWindow`) deleteUI
pillWindow;
window -w 500 -h 200 -title "NURBS Pill Options"
pillWindow; columnLayout ; floatSliderGrp -label "Radius "
-field true -minValue 0 -maxValue 1 -value 1
pillRadius; floatSliderGrp -label "Length" -field true
-minValue 0 -value 1 pillLength; rowLayout -numberOfColumns 5
-width 500 MainRow; columnLayout -columnAttach "both" 5 -rowSpacing
10 -parent MainRow Column1; // A Spacer columnLayout -columnAttach
"both" 5 -rowSpacing 10 -parent MainRow Column2; button -label
"Create" -command "createPill"; columnLayout -columnAttach
"both" 5 -rowSpacing 10 -parent MainRow Column3; button -label
"Reset" -command "floatSliderGrp -e -value 1 pillLength;
floatSliderGrp -e -value 1 pillRadius"; // Reset columnLayout
-columnAttach "both" 5 -rowSpacing 10 -parent MainRow Column4; button
-label "Close" -command "deleteUI pillWindow"; // Close the
dialog columnLayout -columnAttach "both" 5 -rowSpacing 10 -parent
MainRow Column5; // A Spacer
showWindow pillWindow;
proc createPill() { float $Rad =
`floatSliderGrp -q -value pillRadius`;
float $Len = `floatSliderGrp -q
-value pillLength`; sphere -p 0 0 0 -ax 0
1 0 -r $Rad -n tmpSphere; detachSurface -ch 1 -rpo 1 -n detSphere
tmpSphere.u[2]; setAttr "detSphere.translateY" (($Len-1)/2); setAttr
"tmpSphere.translateY" (-($Len-1)/2); delete -ch tmpSphere detSphere;
select -r detSphere.u[2] ; select -tgl tmpSphere.u[2]
; attachWithoutMoving; xform -cp tmpSphere; makeIdentity -apply
true -t 1 -r 1 -s 1 tmpSphere; rename "tmpSphere"
"nurbsPill1"; delete detSphere; }
=============================================================================================
A simple application of how we can create a custom MEL command
interface. |