Hi everyone! Right now for fun (and to learn more about MEL) I’ve started to make a rig generator for UDK vehicles where you place controllers at the points you want axles to be and it generates a bone structure from that.
Not as much a problem as just a question, is there a way to add objects to an array as they are created so that instead of having the user select all the control curves it will just select all the created curves.
An example of this being that when it creates a Control_Axel it adds it to an array that I can access later. Thanks in advance.
window -title "Vehicle Rig" -widthHeight 200 100 myWindow;
//Button Layout
columnLayout -adjustableColumn true;
button -label "Make Root" -command createRoot;
button -label "Make Axel" -command createAxle;
button -label "Make Bones" -command createBone;
//Creates controller named Control_Root
proc createRoot() {
circle -n Root_Controller -ch on -nr 0 1 0 -r 10;
}
//Creates controller named Control_Axle
proc createAxle() {
circle -n Control_Axel -ch on -nr 0 1 0 -r 10;
}
//Gets position of controllers selected and adds joints
proc createBone() {
$Controls = `ls -sl`;
select -cl;
for ( $item in $Controls ) {
$POS = `xform -q -t $item`;
$NJ = `joint -p $POS[0] $POS[1] $POS[2]`;
pickWalk -d up;
}
}
showWindow myWindow;
If I remember correctly there is no push/pop for array’s in Mel, you’ll need to reconstruct the array each time using the old array and your new value. Someone may have a better way but that’s how I would do it if I had to. A simpler way might be to use “very” unique names for the creation of controllers, and just parse you entire scene for that name later.
i agree with Kolgrima to define unique names and search for them later…
anyway… as you want to learn something… here the workaroud if you want to use an array. you have to use a global variable (but be carfull! make sure to take a very specific name for that variable because otherwise you could accidentally overwrite internal variables of maya)
i just updated your code a bit… now if you push the “make axel” button it creates the handles and selects all of them afterwards.
hope i could help you a bit!
//init of global variable allHandles
global string $allHandles[];
//set it to zero
$allHandles = {};
window -title "Vehicle Rig" -widthHeight 200 100 myWindow;
//Button Layout
columnLayout -adjustableColumn true;
button -label "Make Root" -command createRoot;
button -label "Make Axel" -command createAxle;
button -label "Make Bones" -command createBone;
//Creates controller named Control_Root
proc createRoot() {
circle -n Root_Controller -ch on -nr 0 1 0 -r 10;
}
//Creates controller named Control_Axle
proc createAxle() {
//init of global varialbe inside of proc
global string $allHandles[];
//crate handle and store value in variable
string $controlhanlde[] = `circle -n Control_Axel -ch on -nr 0 1 0 -r 10`;
// add created handle to global variable
$allHandles[size($allHandles)] = $controlhanlde[0];
// select all handles stored in global variable
select $allHandles;
}
//Gets position of controllers selected and adds joints
proc createBone() {
$Controls = `ls -sl`;
select -cl;
for ( $item in $Controls ) {
$POS = `xform -q -t $item`;
$NJ = `joint -p $POS[0] $POS[1] $POS[2]`;
pickWalk -d up;
}
}
showWindow myWindow;
Or you could just use python? I have no idea why you’d want to learn MEL.
one way to push something into a MEL array is doing this:
$array[size($array)] = $itemToAdd
But as rob says, go with python… much easier. Usually what I will do is to have the tools within a one class (or more if you need). That way you’ll have access to different variables throughout the tool without doing global variables.
EDIT: Didn’t see that mattschwarz had put that push method in her code
yeah, thumbs up for python…
[QUOTE=mattschwarz;12834]yeah, thumbs up for python… :)[/QUOTE]
oh c’mon … MEL is great… … … if you wanna claw your eyes out in frustration! =)
Thanks mattschwarz and everyone for the replies, been a bit bogged down in schoolwork and finally got to check this.
Ya I thought itd be fun to learn some MEL…slowly realizing, as primal_r said, that I want to claw my eyes out because of it haha. So ill end up taking this to python.
MEL isn’t that bad as long as you only need to stay inside Maya. But Python opens up a lot more door though.
There isn’t a need to learn mel but you will be learning it indirectly when using python for Maya because it really isn’t a whole lot different than mel at first glance other than syntax. For stuff like solving this little exercise, python makes it incredibly easy. I remember when first learning mel and finding out this little tidbit of info on how to pop items into an array, I was surprised at how mel is extremely limited (right out of the box). It’s only as powerful as all the code you have to write to make it more robust, but why would you want to waste so much time when all you really wanted to do is create a tool to get the job done quicker, right? It is an exercise in futility. I quickly turned to Python after learning a few things and I never want to look back but occasionally I find myself having to go back to fix things that are pre-existing as mel, mostly to port them to python, or so I’d like to think. When I do have to go back to mel, it’s sort of like, geeky fun, I know an obscure language and I can go back and make things work in strange and confusing ways. But THIS (via Tistatos): $array[size($array)] = $itemToAdd; you will see that you use in pretty much every script and you’re gonna want to put it in a global proc () of its own. Unbelievable, when I first learned this, how useful it is.
[QUOTE=primal_r;12845]oh c’mon … MEL is great… … … if you wanna claw your eyes out in frustration! =)[/QUOTE]
and yeah… that happens a lot!
as i started MEL i didn´t know any programming language… so i got used to all that “clawing my eyes out”. and i didn´t even know, that i could leave my eyes untouched while writing scripts (well, more or less…) until i started switching over to python. so i guess MEL helps you appreciating all the nice things python does for you…
however, i do use MEL from time to time… for quick and dirty stuff, just inside maya, it does its job quite well.
Part I. General Thoughts (skip this if you don’t want to read me ranting, if you just want a proposed solution, skip to Part II)
-
On Learning MEL - Some people argue learning MEL is a good skill because it teaches you how Maya works internally. While this is true, you’re not going to gain any incredibly useful additional knowledge that you won’t learn using maya.cmds. Sure, there are some MEL specific syntax points you might learn, but again, qualifier being “incredibly useful”. The only reason to know MEL is that for a bit, there’s still alot of codebases around the industry that uses, so there’s a real chance that you’ll be using it on job, but hopefully you’ll have to know enough to port to Python.
-
On Globals - No. Rob made a great post about them on his blog and on adbd, so i’m not going to rehash, but just, No. There are a few cases in MEL you have to use them, sure, and even if you look at Maya’s system code, there are globals all over the place. But No.
-
On Names - Again, No. You should never write anything assuming the presence of a name, especially given the volatility of names in Maya. At the very least, use a custom attribute specific to your tool, which might not be a bad idea anyway if you want persistence between sessions or scenes. If you’re in the habit of relying on names, break that habit immediately.
Part II. Possible solution
Alright, so first, i’m not going to pose any MEL solutions, other than stop and run your code through mel2py right now. Then you might be in a good spot to continue. This problem is actually a great example of why Python is better than MEL, in that you see right away how Python’s features allow you to implement smarter patterns than you could in MEL, which in this case turns into a pretty simple solution. The quick, dirty answer is implement your tool as a class, store your array on the instance and have your UI callbacks access that. Now you have an array that’ll persist through the life of a given instance of your tool. Couple that with some simple metadata like an attribute setting which you could use to populate your arrays on startup and you’re probably off to a good start. Hopefully folks are familiar with that pattern, it’s simple, it’s readable, it works…
a simple script i’ve sorted for this is
global proc string[] addStringToArray(string $item,string $array[],int $index)
{
if($index==1)
$array=stringToStringArray($item+", "+stringArrayToString($array,", "),", ") ;
else if($index==-1)
$array[size($array)]=$item ;
else
error "Non-compatable index number" ;
return $array ;
}
it does leave alot to be desired and i recommend python over this, but it isnt much hassle in mel until you want to insert at index’s other than the start (1) or end (-1) (which just needs to recreate the array into a temp, inserting the item at given index, bumping each item above the index by 1 and re-writing the array)
Here is a way to append strings to a string array as a one-liner in mel:
string $queue[];
string $newString;
... initialize variables here! ...
stringArrayInsertAtIndex(size($queue), $queue, $newString);