Adverti horiz upsell
Conversational MEL Part 3
Conversational MEL Part 3
JamesPiechota, updated 2006-11-30 18:04:17 UTC 39,325 views  Rating:
(1 rating)
Page 4 of 4

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 -image "c:/some/path/to/an/image.jpg";
-width 100
-height 62
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 -image "c:/some/path/to/an/image.jpg";
-width 100
-height 62
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 -image "c:/some/path/to/an/image.jpg";
-width 100
-height 62
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 info@NimbleStudiosInc.com.