MEL - Writing scripts

From TOI-Pedia

Commands

You can enter MEL commands in the Script Editor. If you want to execute your command (or commands), you need to press Ctrl + enter (or the enter of your numpad). When you just press enter without crtl, the cursor will go to a new line.

A script really is just a list of commands which are executed one by one (from top to bottom) once you execute the script (Ctrl + enter). In a bit you'll see various ways to influence which commands in your script are executed (which should be skipped or repeated).

Command reference

The list of commands may seem endless at first and the number of options for each command is even longer. It's madness to know each and every one by heart and it's completely useless to try. The Maya help contains a complete Command Reference, which describes every command and the flags for that command. You can open the Command Reference directly through the Help menu: Help > MEL Command Reference.

polyCube -w 1 -h 1 -d 1 -sx 1 -sy 1 -sz 1 -ax 0 1 0 -tx 1 -ch 1;

creates a new cube. The last created object will automatically be selected.

move -r 0 4 -2.6;

moves the selected object. -r denotes a relative translation (see Command Reference). The object is in this case translated by: 4 units in the y and -2,6 in z. There is no translation in x. An absolute translation would move the pivot point of the object to the specified coordinates.


Syntax

Computers aren't too intelligent. They need very strict rules in order to understand the commands in your script. Therefore some rules should be applied when writing a script. Those rules are called syntax. You can compare it to the grammar of a language.

  • everything is case sensitive. the command polycube won't work, polyCube will
  • Each command is terminated by a ; at the end of the line (after the flags, if applicable). Only if you enter just a single command, you may omit the semicolon , but that is not recommended.
  • Comments (which shouldn't be executed) are preceded by // and end at the end of the line.
  • Large blocks of comments (multiple lines) are placed between /* [comment] */

Especially when your script is getting more complex or very long, it's of vital importance to use comments. It helps you (and others) to keep an overview and it makes it easier to understand your script if you use it at any later date. It helps you to understand the structure and find out how the script works.


Variables

If you enter all commands with all values (numbers, sizes, etc) manually, a script isn't really too useful. It's very likely that the 'normal' interface will prove to be faster or at least more convenient. Scripting gets powerful when you use variables.

You may know variables (x, y, t) from math; variables are labels that refer to a value that may not be known at a given time. They correspond to a value (at a time). A variable has three key properties:

  • a variable has a name
  • a variable has a value
  • a variable has a type

Variable names start with a $ to denote a variable. Variable names may not contain spaces, points or any special character. They can't begin with a number either.

example: $height (variable with the name height)

A variable can be assigned a value:

$height = 6.2;

Once that command has been executed, the variable $height has a value of 6.2. The computer will keep this value for height in memory until you assign a new value (or you shutdown Maya).

This variable can now be used in any command, for example:

polyCube -h $height;

This will create a cube. As soon as the command is executed, Maya will read the value of $height from memory and use that in this command. If this example is executed directly after the previous example, the value will be 6.2.

Take a look at the example below and analyze what happens when each line is executed in order:

$height = 6.2;
polyCube -h $height;
$height = 4;
polyCube -h $height;

All in all not too exciting yet, but we're getting there. This is the first step in writing more complex (and useful) scripts.

Types

There are a few types of variables. The type of a variable determines what kind of values can be stored. The most important types are:

  • float - numbers with a decimal precision
  • integer (int) - numbers without decimals
  • string - text
  • vector - vectors (we won't use them for now)

As soon as a variable is created and is set to a specific type, it can only store values of that type. If you try to assign a value of a different type, you may gat an error or warning or you can get strange results. Only assigning a integer number to a float variable will work without errors; if you assign a decimal number to a variable with type int, all decimals will be ignored.

You cannot change the type of a variable. You need to restart Maya to start with a clean slate.

Declaring variables

To prevent any confusion or errors from occurring related to the type of a variable, it is recommended to declare' a variable on first use. This will look something like this:

int $integer_number;
float $name_of_my_var;

Declaring a variable should be done once for each variable in each script. To keep track of the variables you've used (declared) so far, it's recommended to place all of the at the top of your script. Use comments to describe the use of variables.

You can declare a variable and assign it a value in one go:

int $number = 4;
float $length = 25.3;
string $text = "a piece of text";

Using variables in calculations

You can do calculations with your variables where you apply them. The calculation will be done and the result is used in the command. For example:

float $gridsize = 0.3;
polyCube -w (4*$gridsize);
polyCube -w (6*$gridsize);

Notice the round brackets around the calculation (4 * $gridsize). The are compulsory to ensure that Maya will first determine the result of the calculation 'value of $gridsize times four' and then use the result of that calculation in the command (polyCube).

Arrays

An array is a special class of variables: it can store multiple values. The only restriction is that all values have the same type (int, float, string, etc). Each value is stored with an index reference:

indexvalue
0value1
1value2
2value3
3value4

To store or read a specific value to/from an array, the index number is used. The index is specified withing square brackets directly after the variable name:

$myArray[0]
$myArray[1]
...
$myArray[224]


Arrays are especially useful when you don't know the number of values you need to store in advance or when you have a large sequence of values to store. Creating separate variables for each of the values would be impractical (even impossible) in these cases.

Float array

//declaring a float array. Note the [] after the name of the variable to indicate an array
float $coord[];
 
 
// assigning a value (index 0, 1 and 2)
$coord[0] = 5.4;
$coord[1] = 3.8;
$coord[2] = 4.2;
 
 
// reading the values, combined with (for example) the curve command
curve -d 1 -p $coord[0] 0 0 -p $coord[1] 0 0 -p $coord[2] 0 0;

The contents of the array $coord now is:

indexvalue
05.4
13.8
24.2

String array

A list of object names:

string $lines[];
$lines[0] = "curve1";
$lines[1] = "curve3";
$lines[2] = "Mycurve";

A list of values can be assigned to an array directly. These values will be stored in successive index numbers, starting at 0.

string $newlines[] = {"curve1","curve3","Mycurve"};

The contents of the array $newlines is:

indexvalue
0curve1
1curve3
2Mycurve

Printing variable values

Function: print

string $name = "test 1";
print($name);
test 1
 
float $array[] = { 5.4, 3.8, 7.2 };
print($array);
5.4
3.8
7.2


Control structures

Before was mentioned that a script, a list of commands, was executed line by line (sequentially) from start to end. But other than the default of executing a script sequentially, you can influence the 'flow' of the execution of your script. You might want to execute a part of your script only in special cases (determined by some condition you set). It is also possible to repeat the execution of one or more lines several times, without putting the command in your script multiple times (copy paste).

This is achieved by the so called control structures. These structures determine the execution of your script. The next section covers the IF-structure and two repetitive structures: the WHILE-loop and the FOR-loop.

Comparisons (tests)

Most control structures use some form of comparison, called tests. Two values are compared and tested. The test will yield true or false. You can compare the value of a variable to a fixed value, but you can also test (the values of) two variables or some form of calculation. Some examples:

$a == 4
equal to; see ! below
$a < 5
less than
$a > $b
greater than
5 >= $b
greater than or equal to
$a <= $b
less than or equal to
$a != (2*$b)
not equal to

! Notice: In comparisons, there is a fundamental difference between == and =

= denotes assigning a value to a variable and will always result in true.

== denotes the comparison of two values. It will only result in true when both values are equal.

IF

if ( $a < $b ) {
  polyCube -h $a;
}

In this example the value of variable $a is compared to the value of variable $b. If (and only if) the value of $a is less than the value of $b (the result of the test is true), the command (or commands) between the curly brackets { ... } is executed.

This structure can be expanded to an If-else structure:

if ( $a < $b ) {
  polyCube -h $a;
} else {
  polyCube -h 5;
  move -r 0 4 0;
}

The if-part is equal to the example before, but here we've added a part: the keyword else and a second block enclosed by curly brackets. This second block is executed when the test is not true, false.

WHILE loop

float $distance = 0;
while ( $distance < 50 ) {
  polyCube;
  move -r $distance 0 0;
  $distance = $distance + 7.2;
}

In a While-loop, the command(s) between the curly brackets is executed repeatedly for as long as the test results true.

iteration

The While structure will do the test and only if it results true, the commands between curly brackets are executed. This is called an iteration. After a single iteration, the structure will repeat the events. It will test the expression and if it results true (again), it will execute the commands. If the expression results false it will terminate the entire structure. A loop has zero or more iterations, but in most cases one or more.

infinite loops

If none of the parameters of the expression (comparison) change, the loop will be repeated forever as the test will return true each and every time. If an infnite loop is executed, you need to terminate Maya through the task manager. Not saving any of the files that are open.

Warning: Make sure you don't create an infinite loop and save your script before executing it!

So you need to incorporate a command in a While-loop that influences the test that determines if a next iteration is to be executed.

FOR loop

for ( $i = 1; $i < 10; $i = $i + 1 ) {
  polyCube;
  move -r ($i * 3) 0 0;
}

Maya script result 001.jpg

The For-loop is a variation to the While-loop. It is often used when 'something' needs to be repeated 'a (counted) number of times'. This type of loop uses a counter that keeps track of the number of iterations.

In the For-loop there are three components between the round brackets separated by semicolons: initialization, condition and iteration.

Initialization
$i = 1
A variable $i that is used as a counter is set to its starting value
Condition
$i < 10
The test that determines whether the loop is continued to be executed. In the example $i must be less than 10.
Iteration
$i = $i + 1
In each iteration this command is executed after the command between curly brackets have been executed. In the example the value of $i is increased by 1.

You can do the exact same thing using a While-loop. It would look something like this:

int $i = 1;
while ( $i < 10 ) {
  polyCube;
  move -r ($i * 3) 0 0;
  $i = $i + 1;
}

Both options are correct, only the For-loop will be a more clear in most cases. Especially when the commands between curly brackets is very long.

Loop in loop

Loop in Loop

you can create a new loop within the curly brackets of a loop. An example of the application of a loop-in-a-loop is when you want to create a grid of objects:

for ( $i=0; $i < 10; $i++ ) {
  for ( $j=0; $j < 5; $j++ ) {
    polyCube;
    move ($i * 3) 0 ($j * 2);
  }
}
$i++: $i++ is the same as $i = $i + 1. It's a shorthand notation.

Arrays and loops

We've seen that arrays are a special 'type' of variables that can hold multiple values. Thos values are indexed by sequential number. Working with arrays get useful and practical when they're combined with loops.

Storing values in an array using a loop

//declare variables
int $i;
string $name;
string $lines[];
 
// loop
for ( $i=0; $i<10; $i++ ) {
  // use the name of the curve; store string value in $name.
  $name = `curve -d 1 -p 0 0 0 -p 10 0 $i`;
  // store the name in the array $lines. $i is used as the index number.
  $lines[$i] = $name;
}

Result:

print ($lines);
curve1
curve2
curve3
curve4
curve5
curve6
curve7
curve8
curve9
curve10

Looping through all values in an array

A special variant of the for-loop, can be used to cycle through all values in any given array:

//declare variables
string $lines[] = {"curve1","curve2","curve3"};
string $curvename;
string $profile[] = `circle -c 0 0 0 -nr 1 0 0 -r 0.06 -name "Profiel"`;
 
for ( $curvename in $lines ) {
 extrude -et 2 -po 0 -fpt 1 -ucp 1 -upn 1 -rsp 1 $profile[0] $curvename;
}

Until now, we've seen three parts between the round brackets of a for loop (initialisation, condition, iteration). In this variant there's the keyword in. This for-loop can be interpreted as: loop through all elements (values) in the array given after the in keyword. Each value is stored in the variable given before the in keyword. This will result in one or more iterations of the loop, executing the code between the curly brackets.

It's recommended to make sure any variables used in this structure are properly declared.

Drawing curves

Function: curve

curve -degree 1 -p 0 0 0 -p 5 0 0;

The command is curve with several flags (options):

-degree
specifies the degree of the curve. 1 for straight lines, 3 for curved lines.
-p
Specifies a point of the curve. The flag is followed by three numbers (floats) separated by spaces. Those are the X, Y and Z coordinates of the point.

Obviously a curve consists of several points. A minimum of two points is required for a first degree curve. A Third degree curve needs at least four points. Each of these points is specified by repeating the -p flag.

A 3rd degree curve has a minimum of four points (the CV's): a starting- and end point and two points for the curvature a the start- and end point.


Extruding surfaces

Function: extrude

extrude -et 2 -po 0 -fpt 1 -upn 1 -rsp 1 "Profile" "Path";

This example uses multiple flags. A complete overview of the available flags can be found in the Command Reference. A brief overview:

-et, -extrudeType
2 for a Tube extrusion
-po, -polygon
0 for NURBS
-fpt, -fixedPath
1 (place at the path curve)
-upn, -useProfileNormal
1 (true)


Using object names

When you create a curve using the curve command, it would be nice to know the name of the object that was created, so you can use that name in subsequent commands. For example when using that curve with the extrude function.

Although it's possible to specify a name for the object with the curve command (using the -name flag), you cannot be sure that it will be the exact, final name. A name must be unique, so when it is not, Maya will automatically add a number suffix:

curve -d 1 -name "myCurve" -p 1 0 0 -p 0 1 0;
// Result: myCurve //
curve -d 1 -name "myCurve" -p 2 0 0 -p 0 2 0;
// Result: myCurve1 //

Result of a command

For almost every command, Maya returns a result (number, text, etc):

curve -degree 1 -p 0 0 0 -p 5 0 0;
// Result: curve1 //

This result can be assigned to a variable as a value:

$result = `command ...`;
// or
$result2 = command();
Note the special ` quotes, called backticks. You can find them on the ~ key.

Application using backticks:

$result = `curve -d 1 -p 0 0 0 -p 0 0 6`;
// Result: curve1 //

Application using round brackets:

$result2 = sin(8/3);
// Result: 0.909297 //

Using the name of an object

As we've seen, Maya returns the name of an object when it's created. We can store this result in a variable. An object name is a string:

string $name;
$name = `curve -d 1 -p 0 0 0 -p 0 0 6`;
extrude [options...] "Profile" $name;

The example above shows a curve being created using the curve function. The name of the resulting object is stored in the $name variable (type: string) so we can use it for future application. The name is, for instance, used in the extrude function to specify a curve that should be used (in this example as a path). Instead of passing the name 'hard coded', you can let Maya read the value of the $name variable. Note that the example still uses a 'hard coded' name for the extrusion profile, "profile". Of course this could be specified using a variable as well.

Curve functions

Position on a curve

Curve parameter.jpg

You can define any point on a curve by using the parameter value. Parameters are the unique numeric values (like coordinates) of points on a curve or surface. Parameters let you refer to specific points along the length of a curve. The higher the parameter, the further is the point along the curve.

Note that there are two main parameter ranges:

0 - num spans
the startpoint of the curve has parameter value 0, the endpoint a number equal to the number of spans (number of editpoints minus 1)
0 - 1
the startpoint of the curve has parameter value 0, the endpoint 1
Note that parameter values aren't necessarily distributed evenly along a curve.
Example: the length of a curve between parameter 0 and 0.1 isn't necessarily the same as between 0.4 and 0.5!

Using the parameter value, you can obtain the X, Y and Z (world) positions of any point on a curve:

Function: pointOnCurve

pointOnCurve -position -pr 0.75 "curve1";
-position
world coordinate
-pr
parameter

The result of the function pointOnCurve is a float array:

// This script generates a vertical line (3 units tall) 
// on 6 points that are on curve1.
 
float $pos[];
float $p = 0;
while ( $p <= 1 ) {
  $pos = `pointOnCurve -position -pr $p "curve1"`;
  curve -d 1 -p $pos[0] $pos[1] $pos[2] -p $pos[0] 3 $pos[2];
  $p = $p + 0.2;
}


To generate a few lines between a point at parameter (U-value) $p on the first curve and point at parameter $p on a second curve, using parameter increments of 0.2 between 0 and 1:

float $pos1[]; //declare variable to save coordinates of the first curve
float $pos2[]; //declare variable to save coordinates of the second curve
float $p = 0; //declare variable for the parameter value
 
while ( $p <= 1 ) {
  $pos1 = `pointOnCurve -position -pr $p "ondersteBuis"`;
  $pos2 = `pointOnCurve -position -pr $p "bovensteBuis"`;
  // draw a curve that start at the position of the requested point
  curve -d 1 -p $pos1[0] $pos1[1] $pos1[2] -p $pos2[0] $pos2[1] $pos2[2];
 
  // increase $p with 0.2
  $p = $p + 0.2;
}

Curve length

It can be useful to measure the length of any curve in your script. This way you can determine the number of subdivisions you want to make, for example.

Function: arclen

float $length = arclen("curve1");
// Result: 58.589098 //

Procedures (functions)

We've used several commands so far. A command will perform certain operations, mostly determined by the flags (attributes) specified.

It's possible to create your own commands, called procedures. As this is more in-depth stuff, it's not covered in this page. See: MEL procedures.

Library with some procedures

  • Download lib_bsc2.mel (downloads BSc2)
  • Script Editor > Source Script > choose lib_bsc2.mel
  • The procedures specified in this file are now loaded and ready to be used.
  • On the page MEL BSc2 library is a short explanation of each procedure.



Overview of Maya topics

Maya main index

Personal tools
Actions
Navigation
Tools