Hey guys so i finished my first proper script a while back and thought i'd finally post it up here to see what people thought of it :) it's a randomizer, takes all your objects and randomizes translate, rotate and/or scale on the axis of your choosing between limits of your choosing. i'm still very new to scripting and i have no doubt there's a better way of doing this :P this way of doing it seems kinda slow but it works and it serves it's purpose :) there was a problem with window sizing but you can just resize it and it keeps it's sizing whenever you run it. let me know what you think!

too much copy paste;
for that much code, only one procedure;
it's written in MEL.

goleafsgo

02-15-2011, 03:20 AM

A few things:

I'm guessing that you worked on this in the script editor mostly? What you should do is put all this in a mel file, then make a global proc that has the same name as your script and put your UI code in that proc. And your "execute" proc should be global as well.

e.g. Dump all this in a file named MyRandomizer.mel, move all your UI code at the top into a "global proc MyRandomizer" and make your execute proc global too.

Then from your shelf button or wherever you can just call "MyRandomizer".

In terms of the actual code....

Making one formLayout and then hardcoding all the positions is a typical thing for someone to try when they are first starting out, but it can be a bit of a nightmare to maintain. Instead of using "attachForm" everywhere you should try "attachControl" in a lot of the places. That lets you place a UI control relative to another one. So instead of saying one control is 20 units away from the forms edges...then the next control is 35 units away...then the next one is 55 units away... you can say that the next control should be a certain number of units away from the control beside it.

And instead of every control being a separate thing to be attached in the formLayout you can add parts of the UI into other layouts, e.g. maybe everything for Translate is in one rowLayout, then everything for Rotate and Scale are in their own rowLayouts, and then you just add in those rowLayouts to the formLayout. Does that make sense?

For your execute function, anything that isn't changing in your for loop should be obtained before you start the loop. So all that querying of checkBoxes that you have running for each object could probably be done once before the loop starts I think? Right now if you have 100 objects then you're asking those checkBox's 100 times if they are on or not.

Those chunks of code at the bottom could probably be shortened quite a bit. Right now you query the floatField and do two getAttr's for X, Y and Z separately. You could probably change your logic so that you either query the floatField or do a getAttr for each of them and then just have to do one xform call. Does that make sense?

Freshfromthegrave

02-15-2011, 09:56 AM

hey Tim thanks for the input :) i actually do have it in a mel file i just didn't think to try and upload that to the forums xD what is the advantage to using global procs over local ones? my understanding was that if you could get by with local then you should use that?

i found making the interface like that to be time consuming but actually quite easy to control, but i'll definitely try the other options too. i didn't realise you could use more than one layout in a window o.O

that was a total facepalm on my part for putting the checkbox queries in the loop xD thanks for pointing that out, it seems to be a bit faster now too.

would you be able to explain your last paragraph though? i don't quite understand =\

thanks for you time Tim i appreciate it :) :beer:

NaughtyNathan

02-15-2011, 10:35 AM

Steven, a proc that is declared "local" to the world scope is global. It's only local when it's inside a MEL script file. Also, UI controls cannot refer directly to local procs, only to globals.

you really do need to proceduralise your code a lot more, if ever you find yourself copy/pasting the same lines of code more than once in a script (even with a slight variance in their parameters) you need to consider making it a separate proc (local! ;) ).

:nathaN

Freshfromthegrave

02-15-2011, 10:43 AM

thanks Nathan, insightful as always ^^ i actually wanted to use more procs (in fact one for each of those copy pasted bits) but i was unsure as to how =\ it's something i should probably experiment with/research more :)

goleafsgo

02-15-2011, 01:30 PM

would you be able to explain your last paragraph though? i don't quite understand =\

I didn't actually run this, so it might have typo's, but this is the kind of thing I was talking about:

// Get the current value of translate x/y/z all at once...
float $trans[] = `getAttr ($objects+".translate")`;

// Then update any of the 3 values if the check box was on.
// The min/max values here are another one that could probably be
// queried before starting the loop.
if ($TranslateXCheckboxOnOff == 1)
{
$trans[0] = rand ($InputTransXMin,$InputTransXMax);
}
if ($TranslateYCheckboxOnOff == 1)
{
$trans[1] = rand ($InputTransYMin,$InputTransYMax);
}
if ($TranslateZCheckboxOnOff == 1)
{
$trans[2] = rand ($InputTransZMin,$InputTransZMax);
}

// Now set all the values at the same time. Some of these values
// might just be the current values...some the random values.
xform -a -t $trans[0] $trans[1] $trans[2] $objects;

So this chunk of code should replace 3 of yours where you did translateX, translateY and translateZ separately. And if you really wanted to, you could make another (local) proc that takes in a string for the attribute you are setting and you could make that one proc set translate, rotate and scale.

Freshfromthegrave

02-15-2011, 02:36 PM

oh that's pretty clever dude :D (well to me lol) thanks for that i'm gonna try that out sometime and see if i can optimize it more :) still confused as to how to implement more procs though =\ is there a way to have the different checkboxes somehow point to different procs?

this is probably something super simple that i'm missing xD

Freshfromthegrave

02-15-2011, 03:06 PM

can you just use a simple if loop saying if the checkbox is ticked go to that proc? actually it probably is just that xD

Freshfromthegrave

02-16-2011, 01:54 PM

right, how do you guys like this version then? :D ok i can't attach a .mel file on the forums...

just to see what it would take to not call similar lines of code with slight differences, I took the same base code that goleafsgo told you to rewrite and wrote it without any reuse... its a bit more complicated and I don't actually think I'd do this for pure readability.. but I figured I'd post it since it could be informative to some.. and it was a fun little exercise to try..

here is your translateProc, it can be modified too to incorporate rotation and scale as well. also the variables and checkbox names are different.. but it should make sense as to what they are.. I can explain further if this doesn't make sense..

hellz rich i could never have thought of that at this stage xD i can kinda follow it :) but i think i'm gonna leave it as is for the moment i think i'm pretty happy with how the script works and how fast it is, as well as what i've learnt making it ;)

Freshfromthegrave

02-17-2011, 10:06 AM

oh hang on... all the procs need to be global otherwise it doesn't work when you source it?

Freshfromthegrave

02-17-2011, 01:39 PM

ok it works with all procs being global but is it really necessary to have them all global?

All procs that are called from outside the mel file have to be global.

So If you create a UI in the script, you created an external caller too!
But a proc thats executed from a button can call other local procs of course! Because its inside the script again. (yep: IF they are above the call location in the script. I usuall put the main ui proc top, then locals and then the other stuff)

Sourcing and hashing MEL is quite a mystic thing anyway...
Executing from the Script Editor, Sourcing bla.mel and having the file hashed (loaded up automatically on startup without an explicit source call) are 3 diffent things.

:rolleyes: am I right? ;D correct me if its bs.

CGTalk Moderation

02-18-2011, 12:56 PM

This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.

Follow Us On:

The CGSociety

The CGSociety is the most respected and accessible global organization for creative digital artists. The CGS supports artists at every level by offering a range of services to connect, inform, educate and promote digital artists worldwide. More about us on TheArtSociety.com