HW 2: MEL scripting and Procedural Terrain Generation
In this project you will create a custom tool inside Maya for automatically generating a terrain.
Fire up Maya and open the script editor window. Create a polySphere in the scene
and move it using the manipulator. Observe the commands which stream by in the
History window. Now experiment with copying and pasting those commands into the
script window and executing them. You can use CTRL+ENTER to execute the commands
(or the execute button in the toolbar at the top of the script window).
Look through a couple online tutorials about MEL in order to get an idea of
what a MEL script looks like.
I suggest starting with this one:
Intro by Lindsay Grace
While reading this, please use the script editor window to interactively test
out the commands being discussed and see how they work.
To test your comprehension, try writing a simple procedure which places a couple
spheres in the scene.
global proc drawMySpheres() {
...yourcodegoeshere...
}
Save the script as a text file in the Maya scripts directory as
"drawMySpheres.mel". To run your procedure in the script window, you can
first make Maya load your script by typing "source drawMySpheres.mel;".
This loads your procedure into memory. You can then run your procedure
by executing the line "drawMySpheres();".
At some point you will probably find the need to refer to the documentation from Autodesk which you can find here:
[MEL Command Reference]. You
may also find this wiki a useful reference [MEL wiki]
One thing to keep in mind when looking online for references for Maya scripting
is that there are at least 3 different ways to interact with Maya: MEL (which
we will use), Python scripting, and C++ so don't confuse yourself looking at a
Python scripting example.
Write a MEL procedure named createTerrain which creates a 3D terrain
mesh in the current scene. Since Maya already has procedures for performing
subdivision, we won't need to implement the square-diamond algorithm described
in class. Instead, your procedure should work as follows:
Create a polyPlane
For some number of specified iterations...
Loop through all the vertices of the mesh and move each one up/down by a random amount in the range [-d,d]
Subdivide the mesh using the polySmooth command
Decrease the displacement range d by a factor of s
Your procedure should take as input variables the number of iterations, the initial scale d and the scale factor s.
HINTS:
You should be able to implement this script using the following MEL basic commands and functions:
polyPlane, for, select, polyEvaluate, rand(), move, polySmooth, print, if
Look up these commands in the MEL reference as necessary to learn about their
different parameters and flags. In particular, you will want to experiment
with setting the continuity parameter for polySmooth.
When calling polyPlane, it is convenient specify a name for the mesh (e.g.
"terrain") so you can refer to it later. However, if the user runs your script
multiple times, the name will conflict with that of the previous mesh. Maya's
solution is to add a number to the end of the name (e.g. "terrain22") to make
it unique. Thus, the best option is that whenever you create some new object,
grab the return value so that you know the name. In our case, use
string $names[] = `polyPlane -n terrain ....`
and then later on when you need to refer to the name you can use the string stored
in the variable $names[0].
In your MEL script you will want to perform operations on nodes in the Maya scene.
For example, suppose you have a mesh "terrain" and want to modify a vertex,
whose name will be something like "terrain.vtx[19]". In your script you will
have a string variable $names[0] which stores the name of the mesh and
another integer variable $i which specifies the vertex number you want to work
on. If you try to use $names[0].vtx[$i] you will get an error
(why?). Instead you need to assemble the pieces into a string which is the
name of the vertex. For example: $myvertexname =
$names[0]+".vtx["+$i$+"]"
It is not hard to write a script which causes Maya to freeze up so make sure and
save your script often. In this example, if we subdivide the mesh too many
times, things will grind to a halt. Make sure your procedure checks the input
parameters to see that the number of levels (iterations) is reasonable (e.g. a
max of 5 or 6) to keep this from happening. Use the error command
as appropriate.
Make your terrain generator user friendly by creating a GUI. Write a MEL
proceedure called terrainGUI which creates a window with
textFields to enter the terrain parameters and a button labeled
"generate" which calls your createTerrain proceedure with the parameters given
in the textFields.
Here is an example script with some commands to get you started:
Note how the button works. When it is clicked, Maya evaluates the string
$whenclicked. In this case we are querying the contents of the text
field (using textField -q) and the printing out the result.
Add your terrain generator to the shelf. Once you have your proceedure saved
to a file "terrainGUI.mel", the final step is to add a button to the Maya user
interface. To do this, first enter commands necessary to load up your code and
start your gui in the script window. For example:
Now, select the "custom" shelf in the Maya user interface, highlight the code
and drag it to the shelf and indicate that it is a MEL script. This will
create a shelf button that invokes your script any time you need it.
Extend the simple terrain generation function to implement some more interesting
features. Here are three possibilities:
Implement plateaus and plains by allowing the user to specify a maximum and
minimum displacement for the terrain map and modifying your code to enforce these
constraints.
Implement an option of producing sharp ridges discussed in class by
generating the terrain and then changing the height of each vertex to be
-abs(height).
Implement terrain coloring by assigning colors to each vertex using
polyColorPerVertex or by assigning UV-texture coordinates to each vertex
based on the vertex height. If you use the per-vertex coloring technique, make sure to
go to the menu (Color > Toggle Display Colors) in order to get them displayed
in the scene view.
Please implement at least one of these three. You will get up to 10%
extra-credit for implementing all three or some other creative ideas of your
own choosing.
To distinguish this version from the basic version you already implemented,
please call your new terrain generator scripts
createTerrain2.mel and terrainGUI2.mel.