MelQuick Reference II

Index

getAttr

 ```string \$node[] = `sphere -r 2`; print("shape node name = "+\$node[1]+"\n"); float \$angle = `getAttr (\$node[1]+".esw")`; print("end sweep angle = "+\$angle+"\n");``` Create a sphere and capture the names of its nodes. Print the name of the shape node. Get the value of an attribute. Print the value.

setAttr

 ```string \$node[] = `sphere -r 2`; setAttr (\$node[1] + ".radius") 3.5;``` Create a sphere and capture the names of its nodes set a radius value of 3.5 units.

 ```addAttr -ln "foo" -sn "foo" -at float3 -usedAsColor -k 1 "nurbsSphereShape1"; addAttr -ln "r" -at "float" -k 1 -p "foo" "nurbsSphereShape1"; addAttr -ln "g" -at "float" -k 1 -p "foo" "nurbsSphereShape1"; addAttr -ln "b" -at "float" -k 1 -p "foo" "nurbsSphereShape1"; setAttr "nurbsSphereShape1.foo" -type "float3" 1 1 1;```

Getting a Number from a Node Name

 ```string \$name[] = `pSphere1`; int \$num = `match "[0-9]+" \$name[0]`; print("The numeric part of " + \$name[0] + " is " + \$num + "\n");``` Create a sphere and capture the names of its nodes Use the match command to find ALL the numerals. In this example the name of the transform node only has a single digit but if it had more the + symbol tells match to find them all.

Group

 ```sphere -name sph -r 1; cylinder -name cyl -r 0.5 -hr 20; group -name part1 sph cyl; string \$s[] = `sphere -r 1`; string \$c[] = `cylinder -r 0.5 -hr 20`; string \$g = `group \$s[0] \$c[0]`;``` create a named sphere create a named cylinder create a named group Let Maya assign the names most object creation commands return the names of the transform & shape nodes - hence the string array. However, the group command returns a single name.

Duplicate & Smart Transform

 ```string \$s[] = `sphere -r 1`; string \$c[] = `cylinder -r 0.5 -hr 20`; string \$g1 = `group \$s[0] \$c[0]`; string \$d1[] = `duplicate`; // or \$d[] = `duplicate \$g1`; xform -os -piv 0 0 0 -t 0 1 0 -ro 0 45 0; string \$d2[] = `duplicate -st`; string \$d3[] = `duplicate -st`; string \$all = `group \$g1 \$d1 \$d2 \$d3`;``` Create a group to be duplicated. Make a copy of the original object nodes, there are now two sets of objects in the same location. Rotate and translate the first duplicate 45 degrees. Make a second copy with smart transform applied. Make a third copy with smart transform applied. Group them into a single composite object. The duplicated objects are independent of each other and of the original group from which they were copied. Changing the size of one object will not effect the sizes of the other objects.

Instance & Smart Transform

 ```string \$s[] = `sphere -r 1`; string \$c[] = `cylinder -r 0.5 -hr 20`; string \$g1 = `group \$s[0] \$c[0]`; string \$n1[] = `instance`; // or \$d[] = `instance \$g1`; xform -os -piv 0 0 0 -t 0 1 0 -ro 0 30 0; string \$n2[] = `instance -st`; string \$n3[] = `instance -st`; string \$all = `group \$g1 \$n1 \$n2 \$n3`;``` Create a group to be instanced. Make a reference to the original object nodes. The original group is now drawn twice (in the same location). Rotate and translate the first duplicate 30 degrees. Make a second instance with smart transform applied. Make a third instance with smart transform applied. Group them into a single composite object. The instanced objects reference the objects in the original group. Changing the size of either the original sphere or cylinder will effect the sizes of the instances.

Extrude

 ```string \$path = `curve -degree 3 -p 0 0 0 -p 2 1 0 -p -2 2 0 -p 0 3 0`; string \$c[] = `circle -nr 0 1 0 -r 0.25`; string \$ext[] = `extrude -polygon 0 \$c[0] \$path`;``` Create a path for the extrusion. Create a profile for the extrusion. Extrude the profile along the path.

Setting a Keyframe

 ```string \$sph[] = `sphere`; currentTime 1; setKeyframe (\$sph[0] + ".translate"); currentTime 30; move -r -moveY 2; setKeyframe (\$sph[0] + ".translate"); playbackOptions -min 1 -max 30; play;``` Create the target object. Go to the first frame. Set the initial value for the translation attribute. Go to the last frame. Apply a change to the translation. Set the final value for the translation attribute. Set the duration of the animation. Begin looping.

Setting an Expression

 ```string \$exp = ""; string \$obj[]; for(\$i = 0; \$i < 3; \$i++) { \$obj = `sphere`; move (rand(-3,3)) (rand(-3,3)) (rand(-3,3)); \$exp += "select -r " + \$obj[0] + ";\n" + "move -moveY (rand(0,2));\n"; } \$exp += "select -clear;\n"; expression -s \$exp -ae 1; playbackOptions -min 1 -max 30; play;``` Declare an empty string that will store the entire expression. Declare a string array for the names of a sphere transform and shape nodes. Create three spheres and add the (expression) text that references each sphere. The move statements on this line merely separates each of the spheres. The expression randomly moves each sphere in Y. This line is optional, but its sometimes useful to ensure that no object remains selected after the expression has been run. Add the expression to the scene graph. Setup a short animation. Begin looping the animation.

Finding Shape Nodes Inputs

 ```global proc string getShapeInput(string \$node) { // get the shape node string \$shp[] = `listRelatives -shapes \$node`; // get the connections of the shape node string \$plugs[] = `listConnections \$shp[0]`; // plugs[0] is the "initialShadingGroup" // plugs[1] is "makeNurbSphere_SOME_NUMBER" return \$plugs[1]; } string \$s1[] = `sphere -r 1`; string \$s2[] = `sphere -r 1`; string \$s3[] = `sphere -r 1`; string \$group = `group \$s1 \$s2 \$s3`; string \$geoNodes[] = `listRelatives -children -path \$group`; for(\$n = 0; \$n < size(\$geoNodes); \$n++) { string \$input = getShapeInput(\$geoNodes[\$n]); // Perhaps assign a value to one of the // attributes, say, the radius - assuming // the geometry is a sphere. setAttr (\$input + ".radius", 2.0); }``` This proc assumes the node it is given has a single shape node. If you have a group node the following code will enable you to access each item of geometry in the group. For example, suppose we have 3 spheres in a group.

Delete all Geometry

 ```\$geoList = `ls -geometry`; select \$geoList; delete;``` When re-running a script that places geometry into a scene its useful to be able to remove the existing geometry - see next script.

Randomly Placed Planes

 ```\$geoList = `ls -geometry`; select \$geoList; delete; for (\$n = 0; \$n < 1000; \$n++) { polyPlane -sx 1 -sy 1; float \$x = rand(-10, 10); float \$y = rand(-10, 10); float \$z = rand(-10, 10); move \$x \$y \$z; } select "pPlane*"; group;``` This script inserts a number of randomly placed poly planes into a scene.

Writing a Data File

 ```\$path = getenv("HOME"); \$path += "/test.txt"; int \$fileid = fopen(\$path, "w"); fprint(\$fileid, "hello\n"); fclose(\$fileid);``` This script creates/opens a file and writes text to it.

Getting the Indices of Selected Vertices

 ```global proc int[] getSelectedIndices() { int \$indices[]; int \$count = 0; int \$n, \$j; string \$items[]; string \$vertexStrs[] = `ls -sl`; // Check for a valid selection if(size(\$vertexStrs) == 0) return \$indices; for(\$n = 0; \$n < size(\$vertexStrs); \$n++) { // The regular expression says, "find one or more digits // followed by a colon followed by one or more digits". string \$range = `match "[0-9]+:[0-9]+" \$vertexStrs[\$n]`; // We've found a pair of numbers, for example, "15:19" if(\$range != "") { // Split the pair into two strings tokenize(\$range, ":", \$items); // Convert the strings to the first and last index // in the range ie. integer 15 and 19 int \$beginIndex = \$items[0]; int \$endIndex = \$items[1]; // Check we have valid index values if(\$endIndex > \$beginIndex) { for(\$j = 0; \$j <= (\$endIndex - \$beginIndex); \$j++) { // Add the index to the output list \$indices[\$count] = \$beginIndex + \$j; \$count++; } } } else // ...its just a single integer { // The next regular expression says, "find an open // square bracket followed by one or more digits followed // by a closing square bracket". string \$indexStr = `match "\[[0-9]+\]" \$vertexStrs[\$n]`; // extract the digits ie. ignore "[" and "]" \$index = `substring \$indexStr 2 (size(\$indexStr)-1)`; \$indices[\$count] = \$index; \$count++; } } return \$indices; }``` After selecting a few vertices of a poly sphere the command,     `ls -sl` might return the following information.     pSphere1.vtx[265]     pSphere1.vtx[284:285]     pSphere1.vtx[302:304] Notice the last two items provide a range of indices separated by colons. Using the proc shown opposite, for example,     int \$result[] = getSelectedIndices(); we obtain an array of "extracted" index values ie,     265 284 285 302 303 304

 ```global proc addIndicesAttribute(string \$tnode, string \$attr) { // Add an attribute that will contain a list // of the indices of the selected vertices addAttr -longName \$attr -shortName \$attr -dt Int32Array \$tnode; // Get the list of indices int \$indices[] = getSelectedIndices(); // The first value is the number of values to be set. string \$dataStr = size(\$indices) + " "; // Append the indices for(\$n = 0; \$n < size(\$indices); \$n++) { \$dataStr = \$dataStr + \$indices[\$n] + " "; } //print \$dataStr; // Make a string containing the full text of setAttr command string \$str = \$tnode + "." + \$attr; string \$setAttrCmd = "setAttr " + \$tnode + "." + \$attr + " -type Int32Array " + \$dataStr; // Run the command eval(\$setAttrCmd); }``` This proc adds an attribute to a polymesh that will reference an array containing the indices of selected vertices. For example, create a poly sphere, select a few vertices and then run the following command,     addIndicesAttribute("pSphere1", "selected"); This will add an attribute named "selected" to the transform node of the sphere. Use getAttr to confirm a list of indices has been assigned to the attribute,     getAttr pSphere1.selected; The proc "getSelectedIndices()" must be loaded before running "addIndicesAttribute()".

get renderer

 ```string \$gname = `rmanGetGlobals`; string \$result = match("RIS", \$gname); if(\$result == "RIS") print("RIS is active\n"); else print("Reyes is active\n"); // Getting a specific attribute string \$motionAttr = \$gname + ".rman__torattr___motionBlur"; if(getAttr(\$motionAttr) == 1) print("Motion blur is on\n"); else print("Motion blur is off\n"); ``` Pixar's proc rmanGetGlobals() returns the name of preferred RMS renderer even if the actual renderer specified in Render Settings is a non-Pixar system, such as the Maya software renderer. The name returned by rmanGetGlobals() might be, "renderManRISGlobals" (only applicable to RMS version 19 and higher) or "renderManGlobals" (traditional Reyes renderer).