Documente Academic
Documente Profesional
Documente Cultură
If you are new to Maya or haven't had a chance to get under the hood with MEL, this session will help
to familiarize you with it. While this session is not designed to give you an in-depth knowledge of
MEL, it will take you through the broad strokes of the language. Topics covered include variables and
procedures, frequently used MEL commands, scripting workflow, regular and particle expressions.
In Maya 5.0, A|W has done a thorough job of not only documenting MEL commands and functions
but also explaining variables and syntax. Since you are already at Siggraph and most likely do not
have access to the documentation, I have included these pages at the end of this document.
I Scripting Basics
What is scripting?
Scripting is a simple form of programming. It does not involve compiling against libraries and the
generation of executables and such. It can be a quick and dirty method of stringing together several
commands to speed up a task or an elaborate set of procedures and algorithms that become tools on
their own.
There are many different scripting and programming languages out there: C, C++, PERL, JAVA,
ASP, etc. They all act as a layer between you and the 0s and 1s of your CPU. Terms like “if” and
“else” and mathematical functions like “+” and “-“ all get converted down into 0s and 1s. Depending
on the language, you may be very near the 0s and 1s layer, and you may need to do things like
manually allocate memory blocks or cue processes to be sent to the CPU. Thankfully, MEL is several
layers above the 0s and 1s and is full of language and commands that the common person can
understand.
Like an attribute, a variable is given a name, ideally an intuitive one, but any name will do, provided
that it,
To differentiate between what is a variable and say a node name, or a MEL command, the $ symbol
is placed at the beginning of the variable. For example, a variable that is used to keep count of how
many surfaces are selected might be called “counter”, but it would written as “$counter “.
*Refer to the attached Maya documentation for more information about variable types.
Declaring Variables
When creating a new variable in a script it is recommended that you declare it as containing a certain
data type. This is done for several reasons, but the key reasons are that depending on the data type
and the operation you are performing on the data, Maya can more efficiently process the information
and certain operations cannot be performed on differing data types. For example, if you had a
variable containing a persons name and another holding a number, you couldn’t multiply one against
the other.
*Refer to the attached Maya documentation for more information about declaring variables.
Syntax
Each programming language has its own syntax. You can think of syntax as the punctuation of the
programming world. In English, when we conclude a sentence, we use a period “.”. In MEL, we
conclude a command using a semi-colon “;”. In English, we capitalize the first letter of a sentence. In
MEL, we put a “$” (also known as “dollar sign” or “string”) in front of variables.
whereas we can read senTEnces in English with poor punctuation _and #syNtax , MEL will not
understand your good intentions and will return an error.
MEL does have some tolerance for different syntax styles, which is both good and bad. There have
been many discussions on listservers and user group forums about which style of syntax MEL uses
and I have seen people give examples of styles that I had no idea MEL accepted. Apparently, it has
also been discovered that there are some differences in which syntax MEL understands based on the
platform you are using. As a result, a script that runs on Windows may fail on Linux.
For example “getAttr” is a MEL command that functions on a Maya object whereas “mag” is a MEL
function that operates on a piece of data. For MEL functions, there are two syntax’ for storing the
results of the function,
1.
float $x = mag (<<0,3,0>>);
// Result: 3 //
2.
float $x = `mag (<<0,3,0>>)`;
// Result: 3 //
In the first example, no backticks “`” are needed to encapsulate the function. In the second, backticks
are used. Both work, both are valid syntax’ for functions.
However, for MEL commands, you must use the backticks to encapsulate the command, otherwise
an error is returned as shown below,
1.
float $x = getAttr nurbsSphere1.translateX;
// Error: float $x = getAttr nurbsSphere1.translateX;
//
// Error: Invalid use of Maya object "getAttr". //
2.
float $x = `getAttr nurbsSphere1.translateX`;
// Result: 3.5 //
In my MEL scripts, I always use the backtick approach for storing the results of any MEL command or
function.
Conditional Statements "if", "else" and "for"
When you are writing a programme, you often want to perform a certain function only when a
condition is met, if “this” do “that” else do “the other”. All programming languages have conditional
statements, however many of them have different syntax.
You do not have to have an “if” “else” relationship. You can simply write,
if ($x >5){
print “X is greater than 5”;
}
If you only have a single command to be executed after the “if” or “else” statement, you do not need
to put the curly braces “{}”around it.
if ($x > 5)
print “X is greater than 5”;
else
print “X is not greater than 5”;
*Refer to the attached Maya documentation for more information about conditional
statements.
In the above example, I could have removed all formatting and MEL would have understood what
was written, but it would have looked like this,
Spaces, indents and blank lines all help to make your code readable.
/*
this code tests if x is greater than 5
and if it is greater than 5
this code then prints something
*/
In the sections on Scripting Workflow and Hacking MEL, you will see how commenting code is an
important part of scripting.
Return Values
Procedures can return either a single data value or an array of data values. The value can be a float,
int, vector, or string.
Procedure Syntax
proc myProc(){
If your procedure returns a value, you must indicate what type of value it returns in its declaration and
the procedure must have a return statement. The following declares that myProc returns a float
value,
return ($returnValue);
}
return ($returnValue);
}
*Refer to the attached Maya documentation for more information about procedures.
return ($returnValue);
}
you make it known to all of Maya. This means that it can be called from the Script Editor, a tool shelf
icon, or even another MEL script.
You should use local procedures whenever possible and only use a global procedure for the
procedure that is called by the user from the Script Editor or Maya UI.
*Refer to the attached Maya documentation for more information about local and global
procedures.
Executing Procedures
source “PATH_TO_FILE/myScript.mel”
The source function causes MEL to compile and execute the contents of a script that is stored in a
file.
When you save a .mel file in a directory that is seen by your MAYA_SCRIPT_PATH such as,
$HOME/maya/scripts, if your procedure is a global procedure and has the same name as your .mel
file (without the .mel extension) you do not need to source the MEL script for Maya to know about the
procedure. However, if you make any changes to your script after Maya has called one of its
functions, you will need to re-source it for it Maya to know about the changes made.
*Refer to the attached Maya documentation for more information about executing procedures.
Maya’s documentation is quite thorough and covers the entire spectrum of the software
extensively. While you may be inclined to browse through the docs once or twice before tackling
problems, when working with MEL, the documentation is more of a tool than a reference. There are
hundreds of MEL commands and node types, with dozens of flags and attributes for each so
memorization is not an option. You need to be able to quickly figure out what you are looking for,
where to find it, and how to understand it.
The MEL Documentation Page has several different search methods.
Flags
Flags are the options to specify distinct behaviors or functions within the command. Commands
frequently have dozens of flags and you may need to use several of them to get the results that you
want. For example, the xform command has options for moving objects relative to their position and
moving them in worldSpace vs. objectSpace.An xform command that moved an object 10 units in the
Y axis in worldSpace, relative to its current position may look like this,
The order that the flags are specified in does not matter.
Some flags are written on their own, others require you to specify information with them. The xform
command’s –relative option does not require any additional information, but the –translation flag
does. The documentation describes the translation as,
Flags, like attributes can sometimes have two names, a long name and a short name. For example,
the attribute translateX can also be referred to as tx . The translation flag of the xform command can
also be referred to as t . The short or long form can be used interchangeably, so if you don’t feel like
typing the long form, use the short.
Some commands can be used to query, edit and create information in Maya. The xform command is
an example of this. By default, the xform command operates in a “create” mode where it creates
transformational information in your scene. If you were to specify that the command was to run in a
query mode using the –query flag, the command would get information from the scene as opposed to
changing it. Each flag in the documentation tells you if it can be put into a “Q” – query, “C” – create,
“E” – edit mode or “M” – multiple mode.
UI commands in Maya such as the command to create a window, window , tend to have 3 modes,
“Q”, “E” or “C”, as UI can be queried to get a value or check a setting, edited to change a label name
or add a menu bar, or created, to create a new UI element.
Return Values
When you write a MEL script, most of the time you execute commands and capture their resulting
information to be used later in your script. For example, you may create a sphere using the sphere
command and then want to set its scale or translation. The sphere command returns a string (text
data) array with the name of the object and the name of the node, in this case, its shape. By
capturing this data in a string array variable, you can then use the name in a setAttr or move
command.
Most commands have a return value. UI commands may return the name of the new UI element it
created, or the value of a slider. Object creation commands like sphere or particle return the name of
the transform and the shape created. The move command on the other hand does not return any
value. In the documentation under the Return Value heading of the command page, there is a
description of the type or types of data returned. In some cases, the description is quite clear, like
that of the sphere command,
which tells you that it returns a string[] with the “[]” meaning array, so it returns an array of strings. In
the “()” it tells you that the first element of the array is the object name and second is the node name.
Other commands like the getAttr command, return a variety of data types and formats, depending on
the attribute queried. It is best to know what kind of data you are requesting, so that you know what
type of variable to use to store it.
The first question to ask is, what I am looking for? Am I looking for a MEL command or information
about what the different attributes of a node are?
If the question is the latter and relates to nodes and their attributes, simply open the Attribute Editor
for the node in question and under the Help menu, select the appropriate “Help on “ menu item. This
will open the node description page of the docs automatically.
However, if you are trying to find information about a MEL command, the task can be more difficult.
When you open the MEL documentation in your browser, you’ll most likely be overwhelmed by the
number of different search methods you are presented with. The interface is not really intuitive and I
often find myself lost in windows and frames, not knowing how to get back to where I just was. That
being said, the docs have been broken down and sorted every which way you can imagine, so there
is usually a route to get to what you need.
I find that there are several different ways to go about finding the information I am looking for, and
they depend on what information I already know.
Whenever a command is executed through the UI, the Script Editor displays the command. In many
cases, the command that is shown in the Script Editor is the exact MEL command used. An example
of this would be moving an object. When you move an object, the Script Editor displays the following
message,
move -r 0 0 8.37974 ;
From the results, I can see that the move command was issued and it used a –r flag. –r is most likely
the short form for something, so I can now use the alphabetized index of the docs to find the move
command to find out more information.
If nothing is returned in the Script Editor after executing the UI function, turn ON the Echo All
Commands flag in the Script Editor. Turning this flag on causes Maya to become extremely verbose
and you will often end up with dozens of lines returned to the Script Editor. Over time, you will learn
how to quickly filter through all the unimportant commands like those that show and hide the menu
you just selected from.
Often times, the command that is returned to the script is not really a command, but a call to a MEL
procedure. As Maya’s UI is constructed from MEL scripts, it is not uncommon that a click in the UI is
actually a call to a MEL script that in turn executes a series of MEL commands. It is quite easy to
determine if what is being called is a MEL procedure or an actual MEL command.
The first clue is to see if there are any flags specified. MEL procedures are not designed to take flags
as inputs (hacks can be made to simulate this, but A|W doesn’t use them), so if you see a “-“ sign in
the call, it is most likely a proper MEL command.
If you are still unsure, you can simply use the whatIs command. The whatIs command tells you if the
function being called is a MEL command, MEL runtime command, or a MEL procedure.
*A runtime command is like a MEL command, but it is not documented and has no options
If the whatIs command tells you that the function is actually a MEL procedure, it also returns the
location of the MEL script. You can then edit the MEL script in a text editor to figure out what it is
doing. An example of this would be if I wanted to find the command being used to change the stroke
display quality of my paint effects curves, I would use the Display->Stroke Display Quality menu item.
This returns the following in the Script Editor,
editMenuUpdate MayaWindow|mainEditMenu;
setStrokeQuality 25.0;
editMenuUpdate MayaWindow|mainEditMenu;
I ignore the two editMenuUpdate commands and see the setStrokeQuality command. Notice that it
doesn’t have any flags, so it is most likely a MEL procedure. Using the whatIs command, I verify this
whatIs setStrokeQuality ;
// Result: Mel procedure found in: D:/Program
Files/AliasWavefront/Maya5.0/scripts/paintEffects/setStrokeQuality.mel //
If you are looking for a MEL command that has to do with keyframes, try searching for commands
with the word “key” in it. Go to the doc page that has the entire list of all MEL commands and using
the “Find” mechanism of your web browser, find any command with the word “key” in it. This
approach is actually quite fast and often times it will help you to stumble upon other commands that
may be useful and relate to the task you are performing. Other root words that useful are “attr” for
attribute, “poly” for polygonal tools and “get” for getting information.
At the end of each command documentation page is a list of related commands. If you know the
getAttr command and you are looking for a command that relates to attributes, you can open the
command page for the getAttr command and at the bottom see that the,
I think of the search engine as a brute force approach as it will most likely yield hundreds of results.
But reading documentation is always a good thing and you will stumble across many commands that
do incredibly useful things.
In most MEL scripts, the function of the tool that you are writing is to change the value or property of
something in your scene. Since Maya is a node based architecture at its core, the process of
manipulating those objects is done by changing the values of their attributes. Changing attribute
values is done by either setting the attribute to a specified value or connecting another node’s
attribute to it. If you take a look at a Maya ascii format file in a text editor, you’ll see that any scene is
simply made up of nodes that have either their attributes set or connected.
setAttr Usage:
setAttr nurbsSphere1.translateX;
Common setAttr Flags :
-tye or –type
If you are setting the value for the translate attribute of an object and do not want to specifically set
the translateX or translateZ, you can set all three attributes with one setAttr command since translate
is a type of attribute called a double3 meaning it is made up of 3 components, translateX, translateY
and translateZ.
Example.
Instead of
setAttr nurbsSphere1.translateX;
setAttr nurbsSphere1.translateY;
setAttr nurbsSphere1.translateZ;
connectAttr Usage :
-f or –force
If an attribute is already connected to another attribute and you simply use the connectAttr command,
it will return an error. The –force flag forces the command to break the old connection and make the
new one.
Example.
NOTE : In MEL, the commands that are used to set and connect attributes are setAttr and
connectAttr. It is important to note that the root word of the command is “attr”, from the word
“attribute”. Why is this important? As I mentioned earlier in this document, there are hundreds of
different MEL commands and it is unlikely that you will ever be able to remember them all. By having
an idea of where to start your search of the docs, you will be able to quickly find what you are looking
for. If you are performing functions on keyframes, you will most likely find the word “key” in the
command, or if you were looking for polygon functions, you would most likely find the word “poly” in
the command. Unfortunately, Maya is not consistent with the location of the root word in the
command name, so most polygon commands begin with the word “poly” while most keyframe
commands end with “key”, similar to the “attr” commands.
getAttr
Setting attributes values is a method of changing objects in your scene, however, often times, you
need to find out what value an attribute is currently set to so that you can use that value in your script.
The command for getting attribute values is called getAttr.
getAttr Usage :
getAttr nurbsSphere1.tx;
Common getAttr Flags :
There are options for the getAttr flag, but they are for specific functions that are too detailed for this
brief overview.
createNode
The first three commands allow you to set and manipulate the attributes of any node in Maya,
however in many scripts, you might need to explicitly create a node that you then manipulate. The
createNode command enables you to create any node in Maya. Once a node is created, you then
use the setAttr and connectAttr commands to adjust its attributes to get the desired result.
createNode Usage :
The createNode command functions differently from most other commands as you must specify the
name of the node to create immediately after the command name, before any flags are specified.
createNode nurbsSurface;
-n or –name
By default, when you create a node, Maya will name that node “nodeName#” so if I created two
nurbsSurface nodes they would be called “nurbsSphere1” and “nurbsSphere2”. However, using the
-name flag, you can specify the resulting name of the newly created node.
Example .
These 4 commands are the backbone of Maya and are the only commands needed to generate a
scene complete with surfaces, animation, lights, deformers and whatever else is needed. If you can’t
believe that it is that simple, once again, take a look at your Maya ascii file.
Note however, that in a Maya ascii file, the setAttr commands do not specify the node name that they
are operating on and simply specify a “.attributeName”. As nodes are created in the ascii file, they
become the currently selected object and as such, the setAttr command will default to using the
currently selected node to operate on when a node name is not specified. There are no guarantees
that copying lines from a Maya ascii file and executing them in the Script Editor will work as there
other subtle differences between how Maya may evaluate a Maya file vs. a MEL script.
ls
The easiest and most intuitive way to tell your script what objects you want to perform your function
on is to simply select those objects in your scene and then run the script. To find out what objects are
currently selected, the ls command is used. ls comes from the UNIX command, ls which lists the
contents of a directory. In MEL terms, ls list objects in your scene. ls on its own will list ALL objects
in your scene.
Common ls Flags :
-sl or –selection
-typ or –type
To only list objects in your scene of a certain node type, you would use the –type flag followed by the
node type.
Example.
ls –type nurbsSurface
While these commands will enable you to create a scene from scratch, there are hundreds of other
commands that make that process much easier.
xform
If you need to perform any queries or change the transformations of an object that are more complex
than simply setting or getting their translate, rotate and scale, use the xform command. For example,
moving an object that is parented under joint 10 units in the axis in world space, simply setting its
translateX axis to 10, will not take into account the transformations of the joint above it and will not
give you desired result. The xform command has dozens of flags for transforming, rotating and
scaling an object in world space or object space by a percentage of its current value, using the
specified pivot and more.
keyframe
If you are working with keyframes, the keyframe command can handle most operations. It can offset
keys in time or value, operate on a selected range of keys as well as return information about
keyframes.
float $y = rand(1);
// Result: 0.176643 //
float $y = `rand(1)`;
// Result: 0.041631 //
Notice how the rand function successfully evaluated with or without the use of the single quote.
Initially, when I first starting working with MEL, I encapsulated anything that I wanted to get the results
of in single quotes. I found that visually, I could understand my scripts better by being able to see
when I was calling functions and commands. Over time, I stopped encapsulating my functions with
single quotes. The choice is yours.
When calling functions in MEL scripts, you do not need to use the single quotes, as MEL scripts and
procedures are types of functions not commands.
Here’s an example:
You have a Maya scene with 50 point lights and you wanted to connect all of their intensity values to
a master control node, but you don’t want to manually make each connection.
/*
given the selection of point lights in my scene, connect the light’s intensity
attribute to a master control node
*/
3 Refine the outline into step by step processes and try to replace plain language with MEL
language.
/*
given the selection of point lights in my scene, connect the first selected light’s
intensity attribute to all of the other point light attributes
/*
given the selection of point lights in my scene, connect the first selected light’s
intensity attribute to all of the other point light attributes
*/
5 Find out which commands you don’t know and find them in the docs
The two commands that are unknown are how to create an attribute on a node and how to
find out if a selected object is a point light.
There are two methods for finding out a command, execute something in the UI that performs
the command you are looking for and then check the Script Editor to see what command was
used, or find the command by searching through the docs.
In the UI, I know that there is a GUI for adding attributes, so I try that first. I create a locator
and then open the Modify->Add Attribute window. I type “intensity” and add the attribute. In
the Script Editor, I see the following results,
From the results, I can see that two commands were issued. The first was “addAttr” with some
flags specifying the “-ln” and “-at”. What do those flags do? They must be short for something.
From here, I go into the docs and look up the addAttr command and find out that “ln” is short for
“longName” and “at” is short for “attributeType”. So I now understand the command that was
issued as reading,
The second command executed was “setAttr” and it used a “-e” flag. Again, I go back to the docs
to find out what the “-e” is short for. And in this case, and in all cases, “-e” is short for “-edit”. You
find the “-edit” flag used primarily in UI creation commands but also in some MEL commands like
setAttr. In this case, it tells the command that you are not changing the value stored in an
attribute but instead changing something about the attribute itself, in this case whether or not it is
keyable. If an attribute is keyable it is displayed in the channel box, which is what we want.
The next command that we need to find is one that tells us what type of node an object is. Since
I don’t know of anywhere in the UI that does, I need to go into the docs. Unfortunately, “node” is
a very common term in Maya and a search for “node” yields hundreds of results. My next best
guess would be to check the “createNode” command and see if it has any related commands that
do what I want. No luck here either, but a good try. Next, I list all commands in the docs and do
a find for the word “node”. This last approach quickly yields success and after a dozen or so
finds, I come across the “nodeType” command.
/*
given the selection of point lights in my scene, connect the first selected light’s
intensity attribute to all of the other point light attributes
This script has several limitations. When you select an object in your scene, by default Maya selects
the transform node, not the shape node. As a result, the script fails to find any shape nodes. You
could add additional lines to find the shape node under the selected transform and check if they are
pointLights, or you could simply pickwalk down after selecting your objects and then run the script.
You could also add a “pickWalk -d down;” command as the first line in the script and then list
the selected objects.
There are dozens of different ways to solve the same problem. Using a storyboard or script writing
technique makes finding those ways much easier and helps to simplify a complex task.
Reverse Engineering
Whether you need to customize a part of Maya’s UI by editing one of its default scripts or you need to
modify someone else’s script to fix a bug or add a feature, you will at some point be faced with the
task of disassembling and interpreting someone else’s code. Sometimes, this can be a valuable
learning experience. More often than not, you will tear your hair out and curse the author’s name as
you try to figure out their poorly laid out, uncommented code.
I have been in both of these situation many times. In fact, much of my formatting and commenting
styles have been learned by viewing other people’s code and seeing what is easy to read and
understand and what is not.
Either way, I recommend that you work your way back from the final code to the story behind the
script.
• start by commenting any variables that are declared
• search for any MEL commands being executed and comment those, they are your actions
and tell you what the script is actually doing when it is not engaged in for loops and math
functions
• search for for loops and add comments to them next, the majority of data processing is
usually done in for loops as many programs involve iterative processes
• add comments to any remaining steps
• copy and paste comments into the top section of the script, between the /* and */
• order the comments as they appear in the script
Now you can quickly read what the script is doing and figure out where to insert your additional code.
This process can be tedious, but it is an incredibly powerful learning tool. You may be new to MEL
and feel nervous about opening a script with 500 lines of code, but this technique will allow you to
quickly gain confidence in your abilities by demonstrating how even the most complex script is made
up of simple parts.
Hacking Maya
The whatIs command is the key to Maya’s gateway. By turning on the Echo All Commands in the
Script Editor, you can quickly discover what makes Maya’s UI tick and where to find the files to hack
it.
NEVER modify a MEL script located in Maya’s installation path. Copy the MEL script to your local
scripts directory and make changes there. When Maya loads, it looks in your local scripts directory
first, to find the procedures that it needs, so your local copy will be used instead of the one in the
installation directory.
IV Regular Expressions
Expression workflow
Expressions are customizable nodes. They allow you to write your own functions for how the node
behaves and they can have an unlimited number of inputs and outputs. Whereas a nurbsSurface
node takes points in space and weights as an input and outputs a surface, expressions take input
connections, apply user defined functions to them, and outputs data. To illustrate this, try this simple
example,
nurbsSphere1.tx = nurbsSphere2.tx;
Expression Editor containing expression.
As you can see, there is an expression node called “expression1” in-between nurbsSphere2 and
nurbsSphere1.
nurbsSphere2.translateX is connected to expression1.input[0]
If you view the connections, you can see that nurbsSphere2.tx is connected to
expression1.input[0]
4. Delete nurbsSphere2.
5. Open the expression for the expression you just created.
The input connection from nurbsSphere2 is gone, but a placeholder remains, .I[0]
The expression still exists, but instead of it reading that nurbsSphere1.tx = nurbsSphere2.tx,
it reads nurbsSphere1.tx = .I[0];
The connection to the expression is missing, but the expression is still valid, it just doesn’t have
anything connected to its input. You could now connect any attribute of any object to the of the
expression and it would now drive nurbsSphere1.tx .
When you write “myObject.attribute = “ you are making a new output for the expression.
Anytime you write “something = myObject.attribute” you are making a new input.
Inside an expression, you access attributes by typing their nodeName.attributeName. In MEL, to get
and set attribute values, you use getAttr and setAttr commands.
Expression nodes automatically have a connection to the time node which allows you to access the
values for time in seconds and frame number directly. In MEL, you use the currentTime command to
query time.
Expressions have the ability to automatically create unitConversion nodes which act as convenience
nodes to do things like convert rotations from Maya’s internal units, radians, to degrees, or convert
time data to float data. In MEL, any conversions of data types must be done through math functions.
If an input to an expression changes its value, the expression automatically recalculates itself and
executes its functions. In MEL, you either need to setup scriptJob functions that monitor Maya for
certain changes and then execute a function or execute your MEL script manually.
Even with these differences, you can run any MEL command or procedure from within an expression,
which means that you have access to all of Maya’s power from within an expression. You can run for
loops, create and delete geometry, assign shaders, execute system commands, etc.
Another key reason for not using getAttr and setAttr commands in expressions is that if the object that
the command is functioning on is renamed, the expression will fail because the command is looking
for a specific name and not relying on a direct connection. This problem always rears its ugly head
when you reference or import files with expressions as the node names change. In the case of
referenced files, you cannot edit the expression manually to reflect the changes because they are
locked, leaving you with a broken file.
V Particle Expressions
/*
create a custom particle system with 500 points in random positions
for 100 frames, increment the position of each particle in the Y axis by 1
*/
This FICTITIOUS script is an extremely simplified version of what a particle expression does. Maya’s
particle expression are much more user-friendly.
Maya executes its particle expressions for each particle in the particle object whenever time
advances. It also updates the current value of any of its per particle attributes to be that of the current
particle that it is evaluating. This way, you know that if you are using the position attribute in your
expression, you are always getting the position of the current particle that it is evaluating. Another
nice thing about particle expressions is that you do not need to refer to attributes of the current
particle as nodeName.attribute like particleShape1.position, you simply refer to the attribute as
position . Here is how you would write an expression to do what the code above does,
As you can see, this is much cleaner and much more simple than the FICTITIOUS MEL example.
When you reload your expression, Maya will automatically replace the attribute name with the
nodeName.attribute formatting. The expression will then read as,
Creation expressions are useful because they allow you to initialize a particle’s attributes with
characteristics. You may want each particle born to have a random mass or color that will keep with
it for the rest of its life. Or, you may use the creation expression to initialize the size of a particle
sprite when it is first born and then use a runtime expression to have it grow by 20% for each frame of
the rest of its life.
The key point to remember is that a Create Expression is evaluated once at birth and Runtime
Expressions are evaluated for every subsequent frame..
You use variables as symbolic names for values. Variables can hold different values at different points in
a script.
Variable names always start with a dollar sign ($). The name can contain letters, numbers, and
underscores (_). The first character of the name (after the $) cannot be a number.
Variable names are case sensitive. MEL considers $X and $x to be different variables.
Variable names such as $x, $t, and $wtb are not as informative as $carIndex, $timeLeft, and
$wingTipBend. However, do not be too verbose. For example, $indexForMyNameArray, is overly
descriptive.
Before you can use a variable you need to declare it. Declaring the variable tells Maya you intend to use
a variable with this name, and specifies the type of values the variables can hold.
To declare a variable, use a explicit type keyword followed by the variable name. For example:
float $param;
int $counter;
string $name;
vector $position;
Having to declare variables before you use them prevents a set of common problems where misspelled
or misplaced variables create hard-to-find bugs. The MEL interpreter will complain if you try to do the
following:
• The MEL interpreter comes across code that tries to access a variable you haven't declared.
• You try to declare the same variable twice with different types.
Non-decimal numbers
You can type integers using hexadecimal (base 16) notation by adding 0x to the beginning of the number:
0xA0 // equals 160
0xFFF // equals 4095
Vectors
A vector is a triple of floating point numbers (usually representing X, Y, and Z). It's convenient to have a
triple-float data type in MEL because so many operations in 3D involve manipulating X,Y,Z values.
Literal representation
The literal representation of a vector is three floats separated by commas, surrounded by << and >>. For
example:
vector $roger = <<3.0, 7.7, 9.1>>;
vector $more = <<4.5, 6.789, 9.12356>>;
Strings
Strings are sequences of characters. The literal representation of a string is surrounded by double
quotes. For example:
"MEL is fun!"
"abcdef012345"
":<>()&^%ABC"
Within strings you can use codes to include some special characters:
Code Character
\" quotation mark
\n newline
\t tab
\r carriage return
\\ backslash
Concatenating strings
You can stick strings together (concatenate them, in programmer parlance) using the + operator:
"MEL" + " is fun!"
// This is the same as "MEL is fun!"
Arrays
An array is an ordered list of values. All values in an array must be of the same type. You can make
arrays of integers, floats, strings, or vectors. Arrays grow as you add elements to them.
Literal representation
The literal representation of an array is a list of values separated by commas (all of the same type, of
course), surrounded by curly braces:
{1, 2, 3, 4}
{"blue", "red", "black"}
You can assign literal values to an array variable with or without explicit declaration:
$rip = {1, 2, 3, 4};
string $hats = {"blue", "red", "black"};
string $shoes[3] = {"black", "brown", "blue suede"};
Once you have declared a variable you can assign values to it using the = operator. The variable on the
left side of the = operator is assigned the value of the expression on the right side of the operator. For
example:
$x = $y * 10;
If you assign a value that does not match the type of the variable, the MEL interpreter will try to convert
the value into the variables type.
For example:
// Declare the variables...
float $foo;
float $bar;
int $baz;
// Now assign values...
$test = 5.4;
// value of $test is 5.4
$bar = $test + 2;
// value of $bar is 7.4
$baz = $bar;
// the value of $baz is 7
// MEL converted the value to an integer.
An assignment evaluates as the assigned value.
Chaining assignments
When you are assigning the same value to several variables, you can chain the assignments together:
$x = $y = $z = 0;
Conditional Statements
Comparison operators
Logic operators
Boolean values
MEL uses 1 to represent true and 0 to represent false. When operators return boolean values, they use 1
or 0.
MEL also lets you use true and false as well as on and off for boolean values to help readability.
In a logical operator, any non-zero value evaluates to true (1), and zero (0) evaluates to false. However,
remember that in MEL, a value may evaluate to true, but not be equal to true:
int $xsv = 5;
if ($xsv) print("true\n"); // True
if (true) print("true\n"); // True
if ($xsv == true) print("true\n"); // False
Avoid trying to compare values to "true".
if...else if...else
You'll often want you program to make decisions and change its behavior based on testing some
condition. For example, only print a value if it is greater than 10. Like most languages, MEL has an if
control sturcture:
if ($x > 10) {
print("It's greater than 10!\n");
print("Run!!!\n");
}
You can also specify code to run when the condition is not true with the else keyword:
if ($x > 10) {
print("It's greater than 10!\n");
print("Run!!!\n");
} else {
print("It's not above 10.\n");
print("It's safe... for now.\n");
}
You can specify several alternatives with the else if statement:
if ( $color == "blue" )
print("Sky\n");
else if ( $color == "red" )
print("Fire\n");
else if ($color == "yellow" )
print("Sun\n");
else
print("I give up!\n");
for
• The initialization sets up the initial value of a looping variable, for example $i = 0 or $i =
$v+1. This expression is run only once before the loop starts.
• The condition is checked at the start of each iteration of the loop. If it's true, the block executes. If
it's false, the loop ends and execution continues after the loop. For example $i < 5 or $i <
size($words).
• The change of condition is run at the end of each iteration of the loop. This expression should
make some change that gets each iteration closer to the end goal of the loop. For example $i++ or
$i += 5.
A for loop evaluates the termination condition before executing each statement. The condition compares
variable, attribute, or constant values.
int $i;
for ($i = 10; $i > 0; $i--) {
print($i+"...\n");
}
print("Blastoff!!!");
for-in
The most common use of a for loop is to iterate over every element of an array. MEL has a special form
of the for loop that lets you do this very easily.
Procedures
You can define your own functions that work like MEL's built-in functions. User defined functions are
called procedures. Use procedures the encapsulate a series of commands you use often into a reusable
part.
Like any function in MEL, a procedure can take any number of arguments (including no arguments),
perform calculations, and return a value.
Global procedures
Once you define a global procedure, you can call it anywhere: from any script file, within any function, or
from the command line. The general form of a global procedure declaration is:
global proc return_type procedure_name ( arguments ) {
MEL_statements
}
• the global keyword makes the new procedure available everywhere.
• After proc you can add a keyword for the return type of the procedure. For example, if the
procedure returns an integer, type int. If the procedure does not return a value, you can leave this
out.
• A list of arguments in brackets, separated by commas. Each argument is a variable name (with
the $ at the beginning) preceded by its type (for example string).
If you leave the global keyword off the beginning of a procedure declaration, the procedure is local to
the file in which it is defined.
// This is a local procedure
// that is only visible to the code in this file.
proc red5() {print("red5 standing by...\n");}
This is very useful for making "helper" procedures that do work for other procedures. You can expose just
one or two global procedures, hiding the helper code from other people using your scripts.
You cannot define a local procedure in the script editor, they are only available in external script files.
Calling procedures
Using a defined MEL procedure is the same as using any other MEL command or function. To execute
the above MEL procedure helloValue, enter the name of the MEL procedure in a script, the Script Editor,
or the Command Line.
helloValue( 1, "Jake" );
// Result: Hello Jake, number 1 //
The helloValue procedure requires an integer and a string argument in order to be successfully called.
Another way to execute a procedure does not use parentheses or commas. For example, to execute the
helloValue procedure this way, enter the following:
helloValue 7 "Torq";
// Result: Hello Torq, number 7 //
If Maya encounters a command without a definition, it searches through the script paths for a MEL script
with the same name as the command (minus the .mel extension on the file name).
If it finds the file, it declares all the global MEL procedures within that file, and if the procedure you called
exists in the file, it executes.
For example, you have a file sayWhat.mel in one of the script folders with the following contents:
// This is a local procedure
// that is only visible to the code in this file.
proc red5() {print("red5 standing by...\n");}
1. Since there is no internal command sayWhat, Maya searches through all its script paths for a file
called sayWhat or sayWhat.mel.
2. If it finds the file sayWhat.mel script in one of the script directories, it sources the contents of the
file.
In this example, the global procedures sayWhat and GoGo are declared.
3. Maya checks whether a procedure with the name you tried to call exists in the file. If it does,
Maya calls the procedure. In this example, a procedure named sayWhat exists in the file and so it
executes and prints:
sayWhat online
4. Since the GoGo global procedure has been declared, you could now type GoGo in the Command
Line or Script Editor to execute the procedure.