Notifications
Clear all

[Closed] Alternative method to execute()?

Hi,

Just wondering whether the following is possible without the use of the execute() method:

Say I have a variable

local objectType = "geometry"

-- Now I want to loop through all the geometry in the scene
for i in objectType do ( ) -- doesn't work for obvious reasons

-- but the following works
for i in (execute objectType) do ( ) 

So is the only way through using execute() or is there another alternative method?

Thanks

8 Replies

Hi,

I guess you are typing the class name as a string. Try this:

for i in geometry do print i.name

Light

Hi Light,

Thanks for the reply. I actually want to loop through the different ObjectSets as determined by a variable.

So if I have a variable which is set to ‘geometry’, i’ll loop through the geometry in the scene. If I change the variable to ‘shapes’, it’ll loop through the shapes in the scene.

It’s evaluating the variable that I’m wondering about, as I want it to evaluate the variable so then it’ll read as

for i in geometry do

-- or 

for i in shapes do

etc…

Calling execute once is not a big deal, the docs only warn against using it to do time-critical operations. So if your current method is valid and working, why change it?

Of course you can use the variable in a case statement to get the actual object set to loop through, but your code would be much longer and would require a new entry for any new class you add. On the positive side, if you are performing destructive or hierarchy-changing operations, this method would allow you to snapshot the objects into an array first (as the geometry set would be dynamically changing if objects are being reparented, added or deleted and it could cause the loop to miss some of them or hit some twice).
If the objectType variable is for example coming from the item of a drop-down list or listbox, it would give you the freedom to name the item freely without caring for the MAXScript syntax, or to use the index of the list instead of the string displayed in the list. On top of that, you could collect objects that do not exist as a built-in object set, for example “Spheres” or “Point Helpers”

theCollection = case objectType of
   (
   "geometry": geometry as array
   "shapes": shapes as array
   "spheres": for o in objects where classof o.baseobject == Sphere collect o
   )
   for o in theCollection do ...

Even better, you could take the type as a name to ensure case-insensitivity:

theCollection = case objectType as name of
   (
   #geometry: geometry as array
   #shapes: shapes as array
 #spheres: for o in objects where classof o.baseobject == Sphere collect o
   )
   for o in theCollection do ...

So the question is – why are you asking and what do you expect to get?

Try this:

fn printObjectNames theClass = for i in theClass do print i.name

printObjectNames geometry
printObjectNames lights

Light

Hi Bobo,

Thanks for the reply. I asked as I’m still fairly new to Maxscript and have heard to avoid execute if possible. Therefore I was wondering if there are better alternatives whilst still achieving the same effect without a drastic change to the code.

I guess as you have pointed out already that calling it once or twice isn’t a big deal and works quite well as opposed to avoiding it but making the code much longer.

Thanks for alternative method anyhow!

Thanks for the alternative method Light!

You could take a screenshot of your ui and check all pixels if they together form the letters “geometry”…or you can go with what Bobo suggested. Put the collection into a variable first and then loop through that variable…like: theobjs = execute thestring. For i in theobjs do…

Thanks Rivendale, but I think the other methods look more attractive !