| | Print | |
Conversational MEL Part 2www.NimbleStudiosInc.com This email address is being protected from spam bots, you need Javascript enabled to view it
IntroductionWhen we left off, we’d combined a pinch of cut-and-paste with a dash of basic UI to build a custom window for changing settings and automating short workflows. In this tutorial we’re going to break out of our monkey-see-monkey-do prison, and write a script from scratch. By the end of this article you will have written your very own mass-object-renaming-search-and-replace script! Once done this script will examine any selected objects looking for a word you specify. When found it will rename the object by replacing the specified word with something else. Are ya ready? In this article we will go over:
Object NamesWe’ll start our journey with the unassuming ‘ls’ command. ‘ls’ is short for ‘list’ (I know, not exactly the world’s longest word to begin with). So what exactly does this ‘list’ command do? According to our trusty Oxford Pocket Dictionary it either
Needless to say definition #3 is the one we’re interested in. The ‘ls’ command names, one by one, all of the objects in your scene. Getting this list of objects is almost always your first order of business in any script - before you can do something, you need something to do it on. Why don’t you give it a try. Start a new scene, create a few polygon objects, and type ‘ls’ in the Command Line: ![]() You should see something like the above. The text “// Result: ” followed by a list of names. These are the names of every object in your scene (who’d a thunk there could be so many in a nearly empty scene, eh?). If you scroll on over to the end of the list you should see the polygon objects that you just created. ![]() These names are just that: names. They are strings that refer to specific objects in Maya. If you remember from last month, a string is short for a ‘string of characters’ - basically one or more words or letters (numbers and punctuation are fine too). These strings are not objects themselves, they simply refer to some object in your scene. ![]() Knowing an object’s name is enough to interact with it. This is similar to the fictitious ‘sit’ command we went over last month: sit “Bowser”; The word “Bowser” is not the same thing as the living, drooling animal at your feet - but using his name is enough to get him to obey a command. The same is true for Maya objects. Let’s give this object name thing a go using the new command ‘select’. As you might expect the ‘select’ command selects objects - all of the objects referred to in its command arguments to be exact. Type ‘select’ in the Command Line, copy all of the output from ‘ls’ after “// Result: ” ... ![]() ... and paste it into the Command Line. ![]() Hit enter and see what happens: ![]() Bammo - everything in your scene is selected. If you’re thinking “That’s all well and good, but do I really have to go through all that cut and paste rigmarole every time I want to select something? C’mon man, there’s gotta be a better way!” - Fear not, a better way there is. Gather close and dim lights, because it’s time to talk about a little something I like to call “variables and data types”. VariablesA variable is basically a container, a bucket, which holds some bit of information.
You can think of a variable as the stained napkin with the phone number of the cutie you met last night, the “Today’s Special” line on the menu in front of Annie’s Kitchen, or even a literal bucket like those carried on the backs of quick-service motorcycles. It is important to note that a variable is distinct and separate from the information it contains.
A stained napkin is not a phone number, the words “Today’s Special” are not the same as “fried eggs”, and the quick-service dude is probably not delivering a blue bucket. Like the preceding examples, the information contained in a variable can be changed.
The quick-service gent will deliver the contents of his blue bucket and likely refill it with a new package elsewhere. Each morning Annie will erase yesterday’s special and write a new one. And the next time a hotty offers their number you can whip out that old napkin, cross out the previous number, and hand over the pen.
What does not change, though, is the meaning of the information. Your trusty napkin will always contain the number of your latest acquaintance, the “Today’s Special” line will always contain the name of the current special, and the quick-service guy will always be delivering the contents of his blue bucket. We’ll walk through the “Today’s Special” example in Maya-ese: string $todaysSpecial; This line declares a variable. In Maya variables don’t exist until they are declared. A parallel to real life might be manufacturing the napkin, sign board, or blue bucket. Only after a variable has been declared can it be used to store information. There are two parts to this line: string $todaysSpecial; $todaysSpecial is the variable name. All variable names start with a dollar-sign ‘$’, and can contain only letters, underscores ‘_’, and numbers (although a number can't follow the '$'). Ignoring these rules will end you up with a big plate o’ “Syntax error”: ![]() Like an object name, the variable name is the way that you refer to the variable and through it the information it contains. string $todaysSpecial; string, by now an old friend, is the data type of the variable. A variable can only store information of its declared data type. A restaurant would no more write their menu on the side of a quick-service bucket, than that delivery guy would try and wrap his package up in an old napkin. The Maya data types are notably less exciting than mystery packages and the phone numbers of attractive singles. There are only three: string, int, and float. (Actually there are more than three, but the others aren’t important yet.) A string, as we’ve touched on before, is a series of letters, words, numbers, and punctuation like: “beating a dead horse” “Enough already, I get what a string is.” “pCube1” An int, short for ‘integer’, is a whole number like: 3 -42 1337 A float, short for ‘floating-point’, is a number containing a decimal point like: -3.2 99.44 0.0001234567 The term ‘floating-point’ refers to the fact that the decimal point can appear anywhere in the number. It’s interesting to note that all ints can be represented as floats. int 3 can be written as float 3.0, int -42 can be written as float -42.0, etc... Okay, so maybe it’s not that interesting. Variable AssignmentBack to our example: string $todaysSpecial; This line declares a variable of type string called $todaysSpecial. Let’s say it’s Monday and Annie’s Kitchen has just opened. Annie’s first order of business is to write out the special of the day: ![]() $todaysSpecial = “fried eggs”; The ‘=’ in this line is called the assignment operator, it takes the value “fried eggs” and stuffs it into the variable $todaysSpecial. The assignment operator mimics the real life action of erasing the menu board and writing out by hand the current special of the day. If you were to read this line out loud you might say “The variable todaysSpecial is assigned the value ‘fried eggs’”. Or, for some real geek cred, you could say “todaysSpecial gets ‘fried eggs’”. It’s best not to read the ‘=’ symbol as ‘equals’, as in “todaysSpecial equals ‘fried eggs’”, because, as we’ll see later, the word ‘equals’ can be ambiguous - and besides all the geeks will laugh at you. At this point we believe the $todaysSpecial variable stores the value “fried eggs” - but how can be sure? Enter the ‘print’ command. This command simply prints its arguments to the Command Feedback and Script Editor. Give it a try: ![]() A little earlier I mentioned that you can access the information stored in a variable through its name. To illustrate this use the print command to print out the special of the day: ![]() As we can see Today’s Special is in fact “fried eggs” - if I were to walk into the restaurant on Monday and order Today’s Special, I would get some fried eggs. Earlier I mentioned that all variable names must start with a '$' sign. Just to see what happens why don't you try printing out 'todaysSpecial' without the dollar sign: ![]() The day passes and now it’s Tuesday. Again Annie walks out to the menu board, erases the old special of the day and writes out a new one: ![]() $todaysSpecial = “hotdog”; Assigning a new value to a variable will replace the previous one. Yesterday’s special is gone, replaced with the new special. If I order the special of the day on Tuesday, I won’t get fried eggs, instead I’ll get a hotdog. We can verify this using the print command again: ![]() It’s worth pointing out that although the value stored in the variable has changed, the meaning of the variable may stay the same. $todaysSpecial still holds the name of the special of the day, even if the exact dish has changed. The blue bucket on the bike always holds the current delivery regardless of the exact contents. And your napkin still holds the key to future romance, even if it’s now with Frank instead of Fred or Jessica instead of Julie. This last point about the meaning of a variable is not a rule - just good practice. Maya only requires the data type of the value match the declared data type of the variable. You are quite free to assign unrelated values to the same variable: $todaysSpecial = “hotdog”; $todaysSpecial = “Hi, I’m Joey.”; $todaysSpecial = “adsf.,m909%;(2.s”; Assigning a value of the wrong data type, however, may lead to trouble: int $myVariable = "hotdog"; // Warning: int $myVariable = "hotdog"; // // Warning: Line 1.28 : Converting string "hotdog" to an int value of 0. // // Result: 0 // When the wrong data type is assigned, Maya will try and convert it to the right data type. In the above example Maya converted “hotdog” to the integer value of 0 - probably not what the scripter had in mind. Not all conversions will be so unexpected, and in later articles we’ll show examples where you may want to convert values from one data type to another, but, for the time being, it’s best to make sure your variables are only assigned values of the appropriate data type. To recap:
ArraysIf you’ll remember back a bit, we embarked on all this talk about variables and data types in hopes that it would make our selection job a bit easier to do. Let’s see where we’re at. Before, we had to manually copy the output from the ‘ls’ command and paste it into the select command. ![]() Now, through the power of variables we can assign the name of each object in the scene to a variable and pass that to the ‘select’ command. string $firstObjectName; $firstObjectName = “time1”; string $secondObjectName; $secondObjectName = “renderPartition”; string $thirdObjectName; $thirdObjectName = “renderGlobalsList1”; string $fourthObjectName; $fourthObjectName = “defaultLightList1”; . . . select $firstObjectName $secondObjectName $thirdObjectName ....... Whoa! What happened?? That’s not easier at all! That’s like the opposite of easier! The problem is that the variables we’ve discussed are designed only to hold a single value at a time, and the output from the ‘ls’ command is, well, a list of values. In order to store a bunch of values at once we need something called an array. An array is a bunch of variables all put together - a complete menu at Annie’s Kitchen or a stack of napkins with phone numbers. But instead of referring to each bit of information by name, you refer to each one according to the order with which it is found in the array: ![]() As a real-life example let’s take look at Annie’s Kitchen’s menu: ![]() Here a bunch of different menu items are collected together as a single list - and in fact many of the patrons at Annie’s Kitchen probably order their dish by number: “Excuse me, miss, I would like one order of #3 and two orders of #5, please” - or, more likely: “Hey, waitress! One #3, two #5s.” Let’s see how this would look in MEL: string $fullMenu[]; $fullMenu[1] = “hotdog”; $fullMenu[2] = “hamburger”; $fullMenu[3] = “fried eggs”; $fullMenu[4] = “reuben sandwich”; $fullMenu[5] = “homefries”; Even without knowing what those little [] things mean it doesn’t look that different from the real life menu, does it? Let’s take a look at the first line: Arraystring $fullMenu[]; The [] at the end of the variable name tells Maya that you are declaring an array variable. Whereas Regularstring $todaysSpecial; declares a variable named $todaysSpecial which can store a single string variable, our first line declares a variable named $fullMenu which can store a list of string variables. Assigning to an array variable is almost the same as assigning to a regular variable: Regular$todaysSpecial = “fried eggs”; The only difference is that we have to indicate which element of the array we want to assign to: Array$fullMenu[3] = “fried eggs”; Here we’ve assigned the value “fried eggs” to element 3 of the $fullMenu array variable. Easy peasy, right? Unfortunately there’s one little curve ball: the numbers start from 0. Array indices, as they are formally called, start from 0 and count upwards. In our example above: string $fullMenu[]; $fullMenu[1] = “hotdog”; $fullMenu[2] = “hamburger”; $fullMenu[3] = “fried eggs”; $fullMenu[4] = “reuben sandwich”; $fullMenu[5] = “homefries”; There would be a gap at the beginning of the array: element 0 isn’t storing any information. You can verify this using the print command: ![]() This wouldn’t be that big a deal except for this whole “we start counting from 0” thing is embedded pretty deeply in MEL and programming culture. Many MEL commands and fellow scripters will assume your arrays have information at index 0 - so it’s best to try to get into the habit of always starting from 0. If we correct both our real-life and MEL-life versions we end up with: ![]() string $fullMenu[]; $fullMenu[0] = “hotdog”; $fullMenu[1] = “hamburger”; $fullMenu[2] = “fried eggs”; $fullMenu[3] = “reuben sandwich”; $fullMenu[4] = “homefries”; Return ValuesOkay, so now, armed with the power of variables, data types, and arrays, surely our selection job must be a lot easier. Let’s see: string $objects[]; $objects[0] = “time1”; $objects[1] = “renderPartition”; $objects[2] = “renderGlobalsList1”; $objects[3] = “defaultLightList1”; . . . select $objects[0] $objects[1] $objects[2] .......... Hmm... still not looking all that easy, eh? Earlier I said “the ‘select’ command will select all of the objects referred to in its command arguments”. Well we’ve already got all of our objects packaged up nice and neat in the $objects array, there’s really no reason we have to pull them out one-by-one to pass to the ‘select’ command. Just like you can access a regular variable’s value through the variable’s name, so can you access all of an array’s values through the array variable’s name. Quickly try printing out the entire menu from Annie’s Kitchen: ![]() print $fullMenu; hotdog hamburger fried eggs reuben sandwich homefries With this in mind we can update our code snippet again: string $objects[]; $objects[0] = “time1”; $objects[1] = “renderPartition”; $objects[2] = “renderGlobalsList1”; $objects[3] = “defaultLightList1”; . . . select $objects; Now we’re getting somewhere... but I’m still thinking it would be easier to just copy-and-paste the output from the ‘ls’ command. If you’ll remember last month we identified the main components of a MEL command as: commandName flagsAndArguments target I must apologize because I wasn’t entirely truthful: there’s one more component we haven’t talked about yet. A complete breakdown actually looks like this: returnValue commandName flagsAndArguments target Many, although not all, commands generate some information and give it (or “return it”) to you the scripter. This information, called the command’s return value, can be a value of any of MEL’s supported data types. For some commands the return value is used to provide information about changes the command may have made, and for some commands, like ‘ls’, the return value is the whole point of the command. Let's take a look at the real-life act of buying groceries. You're the proud parent of two teenage children and your refrigerator has gotten pretty bare. You turn to your loving progeny and issue the command 'buyGroceries'. As expected your adorable kids each turn to the other and say "You heard him, go get some groceries." Looks like 'buyGroceries' may be in need of the '-who' flag to indicate which of your offspring should do the chore. In this case there are two possibilities: buyGroceries -who "Joey"; buyGroceries -who "Sally"; .. and the return value will indicate what groceries were purchased. Lest you wonder which child to saddle with this burden, let's see what they would buy. Sally, your first born, responsible, A-student goes shopping and returns with a few bags of food: buyGroceries -who "Sally"; // Result: vegetables rice tofu fruit fresh-juice // Joey, your youngest, the class clown and alternative learner, goes shopping and returns with a single bag of "food": buyGroceries -who "Joey"; // Result: ho-hos ding-dongs twinkies // In addition to the quasi-real-life example above, you’ve seen several MEL return values over the past two articles: Here the return value (found immediately after the text “Result: ”) is a string storing the name of the scene - by default always “untitled”: file -f -new; // Result: ./untitled // Here the return value is a string array containing the names of the newly created polygon sphere nodes (we’ll get into more details about nodes, and why two names are returned, in later articles): polySphere -r 1 -sx 20 -sy 20 -ax 0 1 0 -tx 2 -ch 1; // Result: pSphere1 polySphere1 // And, as you’re no doubt very familiar with at this point, here the return value is a string array containing the names of all the objects in the scene: ls; // Result: time1 renderPartition renderGlobalsList1 ... Note the “// Result: ” text - this exists to differentiate return values from regular printed messages. To see what I mean try making a sphere and executing the ‘print’ command: ![]() See? No matter how sneaky I try to be, you will always be able to tell the difference between printed messages and return values. Why is this important? Because return values, like any other value, can be assigned to a variable. Printed messages, however, “are for display purposes only” - they are not values, and can not be assigned to variables. Give this a go by assigning the return value from the polySphere command to a string array variable: string $spheres[]; $spheres = polySphere -r 1 -sx 20 -sy 20 -ax 0 1 0 -tx 2 -ch 1; ![]() Nothing’s ever easy is it? You need one more, tricky, bit of syntax before you can assign the return value of a command to a variable: the backquote `. This frustrating piece of punctuation closely, oh so very closely, resembles the single quote ' - in fact it’s my personal belief that it serves no other purpose than to cause MEL scripters torment (which might explain why it dares not show its face in any sensible written languages and has been banished to the far left corner of the keyboard with only the equally useless ‘~’ for company.) ![]() Any time you want to assign the return value of a command to a variable you have to enclose the command in backquotes: string $spheres[]; $spheres = `polySphere -r 1 -sx 20 -sy 20 -ax 0 1 0 -tx 2 -ch 1`; To verify that the value was actually assigned, try printing out the $sphere variable: print $spheres; pSphere1 polySphere1 If you accidentally use single quotes instead of backquotes you’ll get an error message like this: string $spheres[]; $spheres = 'polySphere -r 1 -sx 20 -sy 20 -ax 0 1 0 -tx 2 -ch 1'; // Error: $spheres = 'polySphere -r 1 -sx 20 -sy 20 -ax 0 1 0 -tx 2 -ch 1'; // // Error: Line 2.12: Syntax error // Finally, we can get somewhere with our selection task: string $objects[]; $objects = `ls`; select $objects; Not half bad, eh? If you execute those three lines of MEL you should see something like: ![]() You’ll note that some objects aren’t selected. This is due to details about how Maya handles selection of certain types of objects (‘sets’ in this case). I won’t get into it now, but if you’re interested you can check out the “Sets and Partitions” section of the Maya Docs. We have one more concept to go over before diving into the renaming script. But first a quick summary:
for-in LoopWe’ve covered a lot of MEL in this article and the one before - but there’s still a lot to go. Two important concepts are “loops” and “conditionals” - together this dynamic duo is known by its alter ego “flow and control”. We’ll be covering this in detail in an upcoming article. For now, though, we’ll touch briefly on the simplest type of loop: the for-in loop. Let’s say you wanted to print out the names of all the objects in your scene. You could try: string $objects[]; $objects = `ls`; print $objects; Which would output something like: time1 renderPartition renderGlobalsList1 defaultLightList1 defaultShaderList1 . . . But let’s say you’re not really feeling that whole “vertical” thing - you’d rather have all of the names on the same line separated by commas. You could try: string $objects[]; $objects = `ls`; print $objects[0]; print “, ”; print $objects[1]; print “, ”; print $objects[2]; print “, ”; print $objects[3]; print “, ”; . . . This would work - but it probably wouldn’t take long before you decided that vertical isn’t that bad after all. Enter the ‘for-in’ loop. The for-in loop will walk through every element in an array and, one by one, assign the value of the element to a temporary variable that you can muck around with. Here’s our ‘print’ example written with a for-in loop: string $objects[]; $objects = `ls`;string $currentObject; for ( $currentObject in $objects ) { print $currentObject; print ", "; } If you give the script a quick scan you may notice the for and in words from which we get the name “for-in loop” - pretty clever, eh? string $objects[]; $objects = `ls`; string $currentObject; for ( $currentObject in $objects ) { print $currentObject; print ", "; } These lines you’ve seen before. They declare a string array and assign it the return value of the ‘ls’ command. string $objects[]; $objects = `ls`; string $currentObject; for ( $currentObject in $objects ) { print $currentObject; print ", "; } Here we declare the string variable that will be used in the for-in loop. This variable will get assigned each element in the $objects array one after the other. string $objects[]; $objects = `ls`; string $currentObject; for ( $currentObject in $objects ) { print $currentObject; print ", "; } This is the loop itself. As mentioned before: the for-in loop will walk through every element in an array and, one by one, assign the value of the element to a temporary variable that you can muck around with. In this chunk of code: $currentObject is the temporary variable $objects is the array we are walking through print $currentObject; is the mucking about we referred to - more formally known as the loop body. print ", "; The '{}' are called curly braces and their only purpose is to delimit the loop body. They'll pop up again in future articles - for now just remember to put a '{' before the loop body and a '}' after the loop body. The for-in loop causes the loop body to be executed several times in a row, each time with a different value in the temporary variable. Executing the loop is the same as executing: $currentObject = $objects[0]; print $currentObject; print “, ”; $currentObject = $objects[1]; print $currentObject; print “, ”; $currentObject = $objects[2]; print $currentObject; print “, ”; $currentObject = $objects[3]; print $currentObject; print “, ”; . . . Don’t worry if you’re not too comfortable with the for-in loop at this point. This was just a quick and dirty overview to get you up and running with the search-and-replace script. We’ll get into it nice and proper in a later article. Designing Search-And-ReplaceHere we are, over 4,000 words later and we haven’t even started to tackle the search-and-replace script promised way back at the beginning. Believe it or not, the hard part is over. With everything we’ve gone over here, plus two new commands, the script will practically write itself. From the intro: the search-and-replace script will examine every object in the scene looking for a word you specify. When found it will rename the object by replacing the specified word with something else. As the scripts you write get more complex, it may be a good idea to spend some time upfront thinking about how to structure the code. One way to do this is to take a plain-english description of the problem to solve and break it down into steps that match MEL language a little more closely. Doing this with the above description we might end up with:
This is still a far cry from actual MEL - but at least we’ve identified some key tasks. The next step might be to start thinking about how you might use MEL to accomplish each of these tasks. Again don’t worry about writing any real MEL code at this point.
Oops - turns out we got a couple problems. Luckily there are two handy MEL commands to help us out: substitute and rename. The substitute command will replace a portion of one string with another. For example: substitute "lias" "Alias" "utodesk"; ![]() ... will search through the target string “Alias” looking for the search string “lias”, if it finds it will replace it with the replace string “utodesk”. The final, substituted string, is passed back through the return value. If the string isn’t found, like in this attempt to turn “Howdy!” into “Y’all come back now, y’hear.” ... substitute “Hello!” “Howdy!” “Y’all come back now, y’hear.”; // Result: Howdy! // ... then the original string is returned unchanged. The rename command is used to rename nodes. It takes two command arguments: the name of the object to rename, and the name to rename it to. For example: rename “pSphere1” “Bob”; ![]() ![]() Okay, now we can fill in those missing bits:
As we can see the red notes don’t line up exactly with the descriptive lines - that’s okay. Normally you would go through this exercise just to get an idea for the structure of your script and the tools you’ll have to use. Coding Search-And-ReplaceLet’s write some code! Looking at our notes we see that the first item is “Use the ‘ls’ command and a for-in loop”. Let’s jot that down to give us a framework: string $objects[] = `ls`; string $currentObject; for ( $currentObject in $objects ) { } You’ll notice that the loop body is empty and in fact executing this script does nothing at all. ![]() If this weirds you out, you can fill in a temporary body: string $objects[] = `ls`; string $currentObject; for ( $currentObject in $objects ) { print $currentObject; } Adding the print command will also help us verify that everything we’ve written so far is working. Next we have “Use the ‘substitute’ command”. Okay this one’s a little tougher because we need to have three strings to pass it as command arguments. Let’s write the command anyways and fill it in as we go: string $objects[] = `ls`; string $currentObject; for ( $currentObject in $objects ) { print $currentObject; substitute; } Since we’re trying to replace a portion of the each object’s name, $currentObject is a good candidate for one of the substitute command arguments: string $objects[] = `ls`; string $currentObject; for ( $currentObject in $objects ) { print $currentObject; substitute $currentObject; } That leaves only the string that we’re searching for and the one that we’re replacing it with. These strings are what is knows as user input because they need to be provided by the user - as opposed to information like $currentObject which we can grab from the scene automatically without any user involvement. Lacking a real user you may have to play one yourself: once you come up with a search string and a replace string, slap them down into the substitute command (don’t forget its slightly awkward argument ordering): string $objects[] = `ls`; string $currentObject; for ( $currentObject in $objects ) { print $currentObject; substitute “pCube” $currentObject “Bob”; } I’ve chosen to replace all occurrences of “pCube” with the string “Bob”. It’s usually a good idea to execute your code periodically to try and catch any syntax errors earlier rather than later. ![]() Good, no errors. Our final note is “Use the ‘rename’ command”. Well that’s pretty easy, all we have to do is rename the $currentObject to the substituted string: string $objects[] = `ls`; string $currentObject; for ( $currentObject in $objects ) { print $currentObject; substitute “pCube” $currentObject “Bob”; rename $currentObject Uh Oh!! } What do we rename it to? Our outline got us pretty far, but usually there’ll be some blanks to fill in. From before we learned that the ‘substitute’ command passes back the substituted string as its return value. So all we need to do is store that value and then use it in the ‘rename’ command: string $objects[] = `ls`; string $currentObject; for ( $currentObject in $objects ) { print $currentObject; string $substitutedString = `substitute “pCube” $currentObject “Bob”`; rename $currentObject $substitutedString; } Holy moly! Is that it??! Are we done? Let’s create some objects ... ![]() ... and give it a try: ![]() Oik - what does that mean?? Luckily because of our ‘print’ command: print $currentObject; ... we know that we were trying to rename the ‘time1’ object when the error occurred. Even if you don’t know what an error message means, you may be able to make a judgment call about whether it even needs fixing. I don’t know about you, but I don’t give a flying hoo-ha about the ‘time1’ node. In fact I saw that huge list of object names returned by the ‘ls’ command and I honestly have no interest in renaming most of them. Rather than fix this error let’s see if we can’t skip over it. We opened this article with a discussion of the ‘ls’ command - one the most often used commands out there. Because of its well-worn position in the scripter’s toolbox, the ‘ls’ command has evolved several command flags over the years (41 as of Maya 7.0). Each of these 41 flags tweaks the ‘ls’ command a little bit, changes what types of objects are listed, what sort of information is included about each object, etc... There are so many flags, though, that you may be hard-pressed to remember them all. In a later article we’ll discuss how to read the MEL Command Reference and get all the juicy details of all of Maya’s MEL commands. For now, I’m just gonna wave my magic command flag wand and hope one appears: -selection The ‘-selection’ flag causes the ‘ls’ command to only list selected objects (its short form is ‘-sl’ - how’s that for a palindrome, madam!). Not only will this allow us to avoid that error message - but heck we could probably even spin it as a feature. Once we slip that new flag into place we end up with our script looking like: string $objects[] = `ls -sl`; string $currentObject; for ( $currentObject in $objects ) { print $currentObject; string $substitutedString = `substitute “pCube” $currentObject “Bob”`; rename $currentObject $substitutedString; } Remembering to select something first, let’s give this one final run: ![]() Rock on! ConclusionIn this article we covered a lot of hardcore programming concepts. We discussed variables and arrays, data types and loops, assignment and return values... And in the end we tried to tie it all together by writing a complex, and hopefully useful, script from scratch. (Did you know that there are currently 22 scripts on Highend 3D that deal with renaming nodes? Sure many of them have UI and other bells and whistles - but the script you just completed isn’t that far off!) Don’t worry if you’re still a little unsure on some of concepts introduced here. Variables, arrays, and loops are the building blocks of all scripts and as such will come up again and again as we delve deeper into MEL and explore more of the exciting Maya features it lays bare. As always if you have any comments or questions please feel free to email us at: This email address is being protected from spam bots, you need Javascript enabled to view it |
|||||||||||||
















![print $fullMenu[0];](images/stories/melIntro2/zeroIndex24.jpg)













