Conversational MEL Part 3


Topics Covered:Online MEL command reference; query and edit mode flags; UI layouts; sliders Sample
Script:Basic turntable animation and UI

Introduction


In the past two articles we've covered a lot of MEL: commands, flags, variables, arrays, and even a basic loop. But this wild ride ain't over yet – MEL the language has a lot more to offer. I would, however, like to take this moment to bring your attention to the two other members of the MEL family: MEL the user interface and MEL the command library. When people talk about MEL, they are usually referring to something that's a little bit language, a little bit user interface, and a little bit command library. Up until now we've been primarily focused on the language – the rules and concepts that govern how you write a MEL script. In this article we're going to spend some quality time with MEL the user interface and MEL the command library – and in the process we might just stumble onto a script for setting up a turntable animation.

In this article we will go over:
  1. The online MEL Command Reference
  2. UI layouts and controls
  3. Turntable animation

Play it, DJ


In flagrant disregard for the well ordered list above, we're going to start off with the turntable animation. This will give us something concrete to sink our teeth into (how's that for a mixed metaphor?) when we cover the other, more abstract, sections later.

What is it?


A turntable animation is a simple animation used to give the viewer a 360 degree look at a model or scene. The model is placed at the camera's center of interest and rotates around like it was sitting on a record player turntable. Alternatively the model can sit still while the camera revolves around it. Here're four images from a turntable animation of the Stanford Bunny:

Turntable animation


Spinning, Scratching, Cutting, and Pasting


For the first pass at our turntable animation script we're going to rely on the same cut and paste technique that served us so well in the first article. Let's forget the MEL for a moment and start pushing buttons and pulling widgets.
First load something worth looking at - ideally something that'll look different when you spin it around (you may note that our tutorial examples have been upgraded – no cones and spheres here!).

Bunny

There are many ways to create a turntable animation but we're going to try and let Maya do most of the work
  1. Create a curve circle
  2. Create a camera
  3. Set the circle as the camera's motion path
  4. Point the camera towards the bunny

As you do each step make sure to grab the MEL code that Maya spits out.

Creating a circle:

Create a NURBS circle

Instead of a regular camera we'll create a “Camera and Aim”:

Create a camera

When adding the circle as the Camera's motion path turn off the Follow option – the aim widget is already controlling the camera's rotation so the motion path should not:

Attach to motion path

And finally point the camera at the bunny by dragging the aim widget over to the bunny's center.

Position the aim widget

And that's it! According to my calculations we should have collected the following MEL script:

Turntable MEL script

circle -c 0 0 0 -nr 0 1 0 -sw 360 -r 1 -d 3 -ut 0 -tol 0.000109361 -s 8 -ch 1;
objectMoveCommand;

camera -centerOfInterest 5 -focalLength 35 -lensSqueezeRatio 1 -cameraScale 1
-horizontalFilmAperture 1.4173 -horizontalFilmOffset 0
-verticalFilmAperture 0.9449 -verticalFilmOffset 0 -filmFit Vertical
-overscan 1 -motionBlur 0 -shutterAngle 144 -nearClipPlane 0.01
-farClipPlane 1000 -orthographic 0 -orthographicWidth 30;
objectMoveCommand;
cameraMakeNode 2 "";

select -cl ;
select -r camera1 ;
select -tgl nurbsCircle1 ;

pathAnimation -fractionMode true -follow false
-startTimeU `playbackOptions -query -minTime`
-endTimeU `playbackOptions -query -maxTime`;

select -r camera1_aim ;
move -r 0 0 5 ;

Let's activate the turntable camera...

Switch to the turntable camera

... and take a look!

Bad turntable

... Well that's certainly not pretty.

It looks like our setup might be in need of a little tweak or two. Luckily for this article the tweak is the pillar upon which this fine industry rests and Maya is bursting with little gadgets and doohickeys to help us out. In order to find those gadgets and use those doohickeys we're going to have to put on our readin' hats and take a look at:


The Online MEL Command Reference


As we saw last article with the 'rename', 'ls', and 'substitute' commands – Maya ships with some pretty powerful tools built in. But how do you find these nuggets of MEL gold? Enter the online MEL Command Reference. The command reference lists all of the built-in MEL commands, as well as descriptions, and example uses.

The easiest way to get at the command reference is by hitting the F1 key when running Maya. Doing so will bring you to the Maya docs:

Maya docs

We'll pass by “Using Maya” and the fun sounding topics like “Fluid Effects” and “Toon Shading”, and move down to “Developer Resources”, where the light is darker, the air danker, and the likes of “File Formats” and “Environment Variables” live. Click “MEL Commands” to launch the online MEL Command Reference.

Developer Resources

The initial screen is divided into three parts: the search box, a list of command categories, and the full list of commands.

MEL Command Reference

Let's find some information about the 'button' command:

Search for the button command

This page which lists every command that contains the word 'button' – this can be very useful if you only remember part of a command name (e.g. 'poly', or 'slider'). Click 'button' to open its command documentation.

There are three parts to the command documentation: synopsis, flags, and examples:

Parts of a MEL command

The synopsis provides a highlevel overview of the command, as well providing information about the command target and return value.

Command synopsis

The next section lists all of the flags. Flags are listed by long and short names. To help you keep your brain young and agile, Maya does not alphabetize them. Below each flag name is a brief description of how they modify the behavior of the command. Over to the right you'll find the data type of any arguments the flag requires. And at the end, are a list of properties:

Flag docs

The properties of a flag indicate how the flag can be used. Q stands for query, C for create, and E for edit. Up until now we've only used flags in the create mode, the default.

Create


A create mode flag is used when you first create something, like a sphere or button, or when you are causing some action to occur, like renaming or moving an object. The sphere button we created in the first article has several examples of create mode flags:

button
-label "Sphere"
-command "polySphere;move -r 0 0 -2; move -r 0 1 0 ; ";

'-label', '-command' are create mode flags that set the label and command of a newly created button. '-r' is a create mode flag that indicates how an object is to be moved. Revisiting the spoken command example:

sit -location “here”;

'-location' is a create mode flag used to tell your dog where to sit.

Query


Many create mode flags are also query and edit mode flags. In order to use a flag in query mode you have to add the special '-q' flag to the command. When a flag is used in query mode, instead of setting some bit of data, it returns some bit of data. For example:

button -q -label button1;
// Result: Sphere //

Here, instead of setting the button's label, we're asking it to tell us what its current label is. Often a create mode flag requires a flag argument, but when you use that flag in query mode, no command argument is needed and none should be given. You may, however, note the 'button1' lurking at the end of the query command. Because there may be many buttons in your scene, when you query a flag you have to indicate which button it is you're talking to. In this case it's the cleverly named 'button1'.

Edit


Edit mode flags are very similar to create mode flags, except that they are used after an object has been created. To use a flag in edit mode you have to add the special '-e' flag to the command. Like create flags, edit flags often require a flag argument, and, like query flags, often need a command argument at the end to indicate which object should be edited. We could turn our “Sphere” button into the long sought after “Make My Scene Pretty” button with a simple edit command:

button -e -label “Make My Scene Pretty” button1;

A real life example of query and edit flags might occur when you're talking with your dog: “Pooch, where you sitting?”, upon which he might answer “Over here.” This would be like using a query flag:

sit -q -location pooch;
// Result: Over here //

And if you then followed up with: “Hmm... I think I'd prefer it if you sat over there”, that would be like using an edit flag:

sit -e -location “over there” pooch;

Examples


Okay let's check out the examples section:

Examples docs

As expected, the examples section provides examples of how a command might be used. Often you can just grab some of the examples, paste it into Maya, and go from there.

To recap:
  1. The online MEL docs provide information about Maya's built-in commands and flags.A create flag is used when you first create something, or when you are causing some action to occur.A query flag returns information about Maya or an object.An edit flag are used to make changes to an object after it has been created.

UI in Maya


We embarked on this journey into the MEL Command Reference in hopes that it would help make our turntable animation suck less. As a reminder, a few frames from our animation:

Bad turntable

I swear this hasn't been a digression, we really have made some progress. But first, let's try and define “suck less”. Basically we want to provide the user with some controls for editing the turntable animation – for example moving the camera a bit higher and maybe a bit further away. Something like this:

Basic turntable UI

Not the swankiest piece of UI, I know – but it'll get the job done. Let's return to the MEL docs and see what Maya has to offer:

Windows category of MEL commands

Up in the categories section we see a whole column devoted to UI – windows, panels, controls, etc... Clicking on these links gives lists upon lists of UI related commands. So much in fact that it may be a little daunting. So let's take a step back and try to make some sense of it all.
There are three main components to UI in Maya: windows, layouts, and controls. Almost all MEL UI you create will be contained in a window. You can think of a window as the foundation of your UI - all other components are built on top of it.

Window

The next layers on top of windows are layouts - they organize and position any buttons, fields, checkboxes, etc... (Generically called ‘controls’) contained in the UI. A 'columnLayout' organizes the controls in a column from top to bottom:

Column layout

A button is an example of a MEL control - like text fields, checkboxes, option menus, and any number of other controls, a button allows the user to interact with (i.e. to control) the UI. She can click a button, check a checkbox, select an option from an option menu and that change will trigger any MEL commands attached to that control.

Buttons in a layout

If this sounds familiar to you, it's because it was lifted from the first article. This time, though, we're going to go a bit further with layouts and introduce some swankier controls.

Layouts


Clicking on the “Layouts” link in the MEL Command docs, you can see that the 'columnLayout' is just one of many ways to organize your controls:

Layouts category of MEL commands

That being said, you can create some pretty complex UI arrangements using only columnLayouts and rowLayouts. The key lies in your ability to nest one layout inside another. 'columnLayouts' can contain a column of 'rowLayouts', each of which contains a row of 'columnLayouts', which in turn contain more 'rowLayouts', and on and on! The possibilities are literally endless. Literally! Some examples of the sorts of layouts you can make by combining rows and columns:

Layout ALayout B

Layout C

Nor are these are simply contrived examples. Nested layouts can be found throughout the Maya user interface and in real life as well - in swanky new phones, in swedish furniture, at the farm...

CellphoneSwedish shelving

Pigs>All controls and layouts are arranged according to their parent layout. If a bunch of controls all share the same 'columnLayout' as a parent, they are arranged in a column – the “My Settings” window from the first article is an example of this:

My Settings window

window -title "My Settings";
columnLayout -adjustableColumn true;
button
-label "Joint Size 1"
-command "jointDisplayScale 1;";
button
-label "Joint Size 0.5"
-command "jointDisplayScale 0.5;";
button
-label "HW Render"
-command "setCurrentRenderer mayaHardware;";
button
-label "SW Render"
-command "setCurrentRenderer mayaSoftware;";
button
-label "Sphere"
-command "polySphere;move -r 0 0 -2;move -r 0 1 0 ; ";
showWindow;

By default the last layout created before a given control or layout becomes that control or layout's parent.

Let's try this out in the following example, inspired by the oldie-but-goodie “54 Mugs of Beer on the Wall”:


 54 Mugs of Beer Grid UI

One way to figure out how to build this UI is to start with the biggest layouts and move down towards the smaller, nested layouts. Looking at the picture we can see that the shelves are stacked one on top of the other – meaning we probably want to start with a 'columnLayout':

 No shelves Grid UI with column layout highlighted

window;
columnLayout;
showWindow;

After that we might notice that, on each shelf, the beer mugs are arranged side-by-side – meaning we probably want to nest a bunch of 'rowLayouts' inside the 'columnLayout', one for each shelf:

 Shelves but no mugs Grid UI with row layouts highlighted

window;
columnLayout;
rowLayout;
rowLayout;
rowLayout;
rowLayout;
rowLayout;
rowLayout;
showWindow;

But wait, this isn't quite enough. By default all layouts are parented to the layout above them. The first few lines of this code would give us something like:

 Diagram showing the incorrect parentingPicture of the incorrect parenting

When in fact we want something like:

 Diagram of the correct parenting Picture of the correct parenting

In order to make sure each 'rowLayout' is parented to the 'columnLayout' instead of the preceding 'rowLayout' we have to use the 'setParent' command. The 'setParent' command changes the – wait, let's see what the docs say :)

“This command changes the default parent to be the specified parent. Two special parents are "/" which indicates the top of the hierarchy, or ".." which indicates one level up in the hierarchy.”

See, I told you the command reference would come in handy. In this case we want to use the 'setParent ..' command. This is like each 'rowLayout' telling the guy after him “No no, don't use me – use my parent”

Diagram illustrating setParent command

window;
columnLayout;
rowLayout;
setParent ..;
rowLayout;
setParent ..;
rowLayout;
setParent ..;
rowLayout;
setParent ..;
rowLayout;
setParent ..;
rowLayout;
setParent ..;
showWindow;

Finally let's add the beer bottles and buttons themselves, several to each shelf-like 'rowLayout':

window;
columnLayout;
rowLayout;
button -label "54";
button -label "53";
button -label "52";
button -label "51";
button -label "50";
button -label "49";
button -label "48";
button -label "47";
button -label "46";
setParent ..;
rowLayout;
...
setParent ..;
rowLayout;
...
setParent ..;
rowLayout;
...
setParent ..;
rowLayout;
...
setParent ..;
rowLayout;
...
setParent ..;
showWindow;

Unfortunately there's one more step. The 'rowLayout' is a little more uptight than the 'columnLayout' - it needs to be told beforehand exactly how many child controls or layouts it can expect. You do this using the '-numberOfColumns' flag. In our example there are 9 beer mugs per shelf, meaning each row has 9 columns. And now the final code:

 Shelf with mugsGrid UI

window;
columnLayout;
rowLayout -numberOfColumns 9;
button -label "54";
button -label "53";
button -label "52";
button -label "51";
button -label "50";
button -label "49";
button -label "48";
button -label "47";
button -label "46";
setParent ..;
rowLayout -numberOfColumns 9;
...
setParent ..;
rowLayout -numberOfColumns 9;
...
setParent ..;
rowLayout -numberOfColumns 9;
...
setParent ..;
rowLayout -numberOfColumns 9;
...
setParent ..;
rowLayout -numberOfColumns 9;
...
setParent ..;
showWindow;

To recap:
  1. Windows are the foundation that other UI components are built on.
  2. Layouts arrange controls and other layouts.
  3. Controls are the buttons, sliders, and menus that the user interacts with.
  4. Layouts can be nested within each other.
  5. All layouts and controls are arranged according their parent layout, which, by default, is the last layout created before them.
  6. Use the setParent command to change the current parent layout. 'setParent ..' bumps the current parent layout up one level.
  7. When using 'rowLayouts' you need to tell it the number of children it can expect using the '-numberOfColumns' flag.

Tweakin'


Armed with the MEL command reference and our newfound intimacy with layouts we can finally go about making our turntable animation suck less. As mentioned before this means raising the camera and moving it back a bit.

First let's try this by hand. Select the nurbs circle, activate the move tool and move it up a bit:

Move the circle

We don't have a use for it yet, but we will, so grab the MEL that gets spit out and save it for later. Next we want to move the camera back a bit. Activate the scale tool, grab the little yellow box at the center and scale the circle outward:

Scale the circle


Once again, stick that MEL in your pocket for safekeeping. Let's activate the turntable camera and playback:

Good turntable

Much better! If we weren't having so much fun we might stop here and call it a day. But we are having fun, right? Woo! Okay, let's get moving on our UI. If you remember our goal is something like this:

Basic UI

Our layout trained eyes can easily detect a 'columnLayout' in there, so let's jot down the first few lines of code (you can stick them before or after the turntable animation code):

window;
columnLayout;
showWindow;

Next let's add some controls. Nope, those funny slidery looking things aren't buttons. Contrary to what you might be thinking if you've been following these articles closely, the Maya UI can do more than create stacks and grids of buttons. In this case we're going to install brand spanking new sliders. Typing 'slider' into the MEL docs search box gives us a list of candidates:

Slider commands

Since the circle's height and size are represented as float values (see the last article for a brief overview of the different data types), we can cull the list down to four possibilities. Let's take a look - Goldilocks style:

floatSlider


floatSlider

This slider is too plain.

floatSlider2


floatSlider2

Whoa, this slider is too crazy!

floatSliderButtonGrp


floatSliderButtonGrp

This slider's got too many buttons.

floatSliderGrp


floatSliderGrp

Ahhh, this slider is just right.

When you first get started with a new command, you might want to check out the examples at the bottom. Particularly with UI widgets this sample code can be a great starting point (all of the preceding slider windows were created by executing the corresponding example code). In the interest of time, though, we're going to be a little more focused in our approach. Namely we're looking for two things: A label (i.e. “Height” and “Distance”) and, like the buttons from the first article, a way to execute a command whenever the slider changes. Skimming through the docs we find a few possibilities:

slider command flags

Which we can narrow down to just two after reading the descriptions: '-label', and '-dragCommand'.

Okay let's add the height slider:

window;
columnLayout;
floatSliderGrp
-label “Height”
-dragCommand Uh Oh!
showWindow;

Uh oh, we've hit a little snag. Let's try using the MEL command we copied from the script editor earlier:

window;
columnLayout;
floatSliderGrp
-label “Height”
-dragCommand “select -r nurbsCircle1 ; move -r 0 2.448686 0 ;”;
showWindow;

And give it a run....

Off the chart

Yoik, that circle got the heck outta here pretty quick, eh? Hmm... “Aha!”, he says, remembering the 'move' command discussion from the first article, “The -r flag moves the object relative to its current position!” Every time we drag the slider the circle is moved upwards again. Let's do a new scene, get rid of that flag and execute the whole script again:

window;
columnLayout;
floatSliderGrp
-label “Height”
-dragCommand “select -r nurbsCircle1 ; move 0 2.448686 0 ;”;
showWindow;

... hmm... it's something... I guess. But the circle kinda moves to the same place no matter what I do with the slider. Not great. Really what we want to do is change the arguments to the 'move' command based on the slider – kind of like how we changed the 'substitute' and 'rename' command using variables in the last article.

First we need to "query" the current "value" of the floatSliderGrp:

floatSliderGrp -q -value Uh oh

Oh yeah, right: in order to query values from an object we need to know the object's name. Let's close our window, add a name to the slider (by tacking it on the end as a command argument), and try again:

window;
columnLayout;
floatSliderGrp
-label “Height”
-dragCommand “select -r nurbsCircle1 ; move 0 2.448686 0 ;”
heightSlider;
showWindow;

Running our query gives us:

floatSliderGrp -q -value heightSlider;
// Result: 27.66 //

Wonderful. Now we need a way to stuff it into the command. One way would be to use the approach discussed in the second article: first stick the return value of the query into a variable, and then pass the variable into the move command. Like this:

float $heightValue = `floatSliderGrp -q -value heightSlider`;
move 0 $heightValue 0 ;

Let's see if we can cram that extra code into our script:

window;
columnLayout;
floatSliderGrp
-label “Height”
-dragCommand “select -r nurbsCircle1 ; \
float $heightValue = `floatSliderGrp -q -value heightSlider`; \
move 0 $heightValue 0 ;

heightSlider;
showWindow;

And, crossing our fingers, let's give it a go...

... Success! Sure that command is getting kinda long and awkward – but it works. Adding the Distance slider should be cake now. We just pull the 'scale' command out of our pocket, slap it in a new slider and go:

window;
columnLayout;
floatSliderGrp
-label “Height”
-dragCommand “select -r nurbsCircle1 ; \
float $heightValue = `floatSliderGrp -q -value heightSlider`; \
move 0 $heightValue 0 ;”
heightSlider;
floatSliderGrp
-label "Distance"
-dragCommand "select -r nurbsCircle1 ; \
float $distanceValue = `floatSliderGrp -q -value distanceSlider`; \
scale $distanceValue $distanceValue $distanceValue;"
distanceSlider;

showWindow;

You'll note we used the '$distanceValue' variable three times in the scale command – this is to make sure we scale the circle out evenly in all directions. Giving it a run we end up with this beautiful piece of UI, as well as a fully tweakable turntable animation. How's that for sucking less!

Basic UI

Bunny turntable

Well... actually the UI isn't all that beautiful... and since we spent all that time on nested layouts it would be a shame if we couldn't use atleast one in our final example... Okay, I guess just this once we could loosen our ties, muss up our hair, and add a little pizzazz to our UI. It ain't much, but how about this:

Swanky UI

First we need to identify the layouts:

Swanky UI with layouts

Next figure out what command we can use to load an image – searching the docs comes up with the surprisingly well-named 'image' command and equally apt, if redundant, 'image' flag. Mashing it all together we get:

window;
rowLayout -numberOfColumns 2;
image -image "c:/some/path/to/an/image.jpg";

columnLayout;
floatSliderGrp
-label "Height"
-dragCommand "select -r nurbsCircle1 ; \
float $heightValue = `floatSliderGrp -q -value heightSlider`; \
move 0 $heightValue 0 ;"
heightSlider;
floatSliderGrp -label "Distance"
-dragCommand "select -r nurbsCircle1 ; \
float $distanceValue = `floatSliderGrp -q -value distanceSlider`; \
scale $distanceValue $distanceValue $distanceValue;"
distanceSlider;
showWindow;

Let's give it a go:

Messed up UI

Oops. It turns out that it's best to explicitly specify the image's width and height using the '-width' and '-height' commands – otherwise the row layout gets a little panicked:

window;
rowLayout -numberOfColumns 2;
image
-image "c:/some/path/to/an/image.jpg"
-width 100
-height 62

columnLayout;
floatSliderGrp
-label "Height"
-dragCommand "select -r nurbsCircle1 ; \
float $heightValue = `floatSliderGrp -q -value heightSlider`; \
move 0 $heightValue 0 ;"
heightSlider;
floatSliderGrp
-label "Distance"
-dragCommand "select -r nurbsCircle1 ; \
float $distanceValue = `floatSliderGrp -q -value distanceSlider`; \
scale $distanceValue $distanceValue $distanceValue;"
distanceSlider;
showWindow;

Voila:

Swanky UI

Like much of Maya, building UI can be a tweaker's nightmare. You might see the above UI and think “Man, those sliders are a little far from that image” or “There's gotta be a better name than 'window2'” - and MEL will will let you futz over those details forever. For example we could tighten up the empty space by editing the floatSliderGrp:

window;
rowLayout -numberOfColumns 2;
image
-width 100
-height 62
-image "c:/some/path/to/an/image.jpg";
columnLayout;
floatSliderGrp
-label "Height"
-columnWidth 1 75
-dragCommand "select -r nurbsCircle1 ; \
float $heightValue = `floatSliderGrp -q -value heightSlider`; \
move 0 $heightValue 0 ;"
heightSlider;
floatSliderGrp
-label "Distance"
-columnWidth 1 75
-dragCommand "select -r nurbsCircle1 ; \
float $distanceValue = `floatSliderGrp -q -value distanceSlider`; \
scale $distanceValue $distanceValue $distanceValue;"
distanceSlider;
showWindow;

And add a better title:

window -title “Deck 1.0”;
rowLayout -numberOfColumns 2;
image
-width 100
-height 62
-image "c:/some/path/to/an/image.jpg";
columnLayout;
floatSliderGrp
-label "Height"
-columnWidth 1 75
-dragCommand "select -r nurbsCircle1 ; \
float $heightValue = `floatSliderGrp -q -value heightSlider`; \
move 0 $heightValue 0 ;"
heightSlider;
floatSliderGrp
-label "Distance"
-columnWidth 1 75
-dragCommand "select -r nurbsCircle1 ; \
float $distanceValue = `floatSliderGrp -q -value distanceSlider`; \
scale $distanceValue $distanceValue $distanceValue;"
distanceSlider;
showWindow;

And on and on and on.

Our final script and UI, in all its glory:

Final UI

circle -c 0 0 0 -nr 0 1 0 -sw 360 -r 1 -d 3 -ut 0 -tol 0.000109361 -s 8 -ch 1;
objectMoveCommand;

camera -centerOfInterest 5 -focalLength 35 -lensSqueezeRatio 1
-cameraScale 1 -horizontalFilmAperture 1.4173
-horizontalFilmOffset 0 -verticalFilmAperture 0.9449
-verticalFilmOffset 0 -filmFit Vertical -overscan 1
-motionBlur 0 -shutterAngle 144 -nearClipPlane 0.01
-farClipPlane 1000 -orthographic 0 -orthographicWidth 30;
objectMoveCommand;
cameraMakeNode 2 "";

select -cl ;
select -r camera1 ;
select -tgl nurbsCircle1 ;
pathAnimation -fractionMode true -follow false
-startTimeU `playbackOptions -query -minTime`
-endTimeU `playbackOptions -query -maxTime`;

select -r camera1_aim ;
move -r 0 0 5 ;

window -title "Deck 1.0";
rowLayout -numberOfColumns 2;
image
-width 100
-height 62
-image "c:/some/path/to/an/image.jpg";
columnLayout;
floatSliderGrp
-label "Height"
-columnWidth 1 75
-dragCommand "select -r nurbsCircle1 ; \
float $heightValue = `floatSliderGrp -q -value heightSlider`; \
move 0 $heightValue 0 ;"
heightSlider;
floatSliderGrp
-label "Distance"
-columnWidth 1 75
-dragCommand "select -r nurbsCircle1 ; \
float $distanceValue = `floatSliderGrp -q -value distanceSlider`; \
scale $distanceValue $distanceValue $distanceValue;"
distanceSlider;
showWindow;


Summary


In this lesson we took a break from MEL language constructs and focused on the UI and command library aspects of the Maya Embedded Language. We covered:
  1. How to navigate the online MEL docs.
  2. The query, edit, and create modes for command flags.
  3. How to arrange controls by nesting layouts.
  4. The 'columnLayout', 'rowLayout', 'floatSliderGrp', and 'image' commands.
  5. A quick way to automate and tweak a turntable animation.

There are a few caveats, though. The script we wrote today is what some might call “fragile” - try running it twice in a row to see why:

Error when running script twice

As the complexity of our scripts increases, we're going to have to start spending time on writing solid, robust code. Some problems with the above script:
  1. The camera and circle have hardcoded names – trouble if there are already nodes in the scene using those names.
  2. The slider commands are a little long and awkward – making them difficult to edit and update.
  3. There aren't any comments – meaning someone else (or yourself in two months) may have trouble fixing or extending this code later.

We will look at these, and other issues, in later articles. I hope this article was helpful and, as always, if you have any questions or comments, please don't hesitate to email us at This email address is being protected from spam bots, you need Javascript enabled to view it .