Notifications
Clear all

[Closed] concatenate in Max?

how would I execute this in Max?
execute (objs[i].modifiers[#MeshSmooth].iterations = smoothVal);

in Maya it would be:
eval(objs[i] + “.modifiers[#MeshSmooth].iterations = ” + smoothVal);

Thank You

6 Replies

Originally posted by Technofreak
[B]how would I execute this in Max?
execute (objs[i].modifiers[#MeshSmooth].iterations = smoothVal);

in Maya it would be:
eval(objs[i] + “.modifiers[#MeshSmooth].iterations = ” + smoothVal);

Thank You [/B]

Well, it depends on what is inside the objs array :o)

If it is an array of nodes, you don’t have to do anything fancy, the above line without the execute will do it.

objs[i].modifiers[#MeshSmooth].iterations = smoothVal

If the array contains the NAMES of the objects, then I would suggest retrieving the object by name, then applying the above code instead of using execute. Execute is A) slightly slower, B) works with strings so it is not very convenient and C) works only in the global context.

So if objs is an array like

objs = #(“Box01”,“Sphere01”,“Cylinder02”)

then the code would be like

for i in objs do
(
theObject = getNodeByName i
if theObject != undefined do
try(theObject.modifiers[#MeshSmooth].iterations = smoothVal)catch()
)

The try()catch() is also rather slow, but makes sure the code will work even if there is no MeshSmooth modifier on the stack, or the objects are completely missing…

Btw, you can also use

theObject.MeshSmooth.iterations = smoothVal

assuming that there is only one meshSmooth modifier on the stack. If there are more, the lowest one will be affected.

So this could be made shorter, like
for i in objs do
(
if (theObject = getNodeByName i) != undefined do
try(theObject.meshsmooth.iterations = smoothVal)catch()
)

As you know, you could use an index counter, but as long as you don’t need a number anywhere else in the code, you should better loop through the array as above.

for i = 1 to objs.count do
(
if (theObject = getNodeByName objs[i] ) != undefined do
try(theObject.meshsmooth.iterations = smoothVal)catch()
)

JFYI, the code using execute would look like

execute (“$”+objs[i]+”.modifiers[#MeshSmooth].iterations = smoothVal”)

It is a good idea to place the name in single quotes if it contains spaces or specialc characters, so the better code would be

execute (“$’”+objs[i]+”’.modifiers[#MeshSmooth].iterations = smoothVal”)

The optimized version with a try()catch() safety net would be then

for i in objs do
execute (“try($’”+i+”’.MeshSmooth.iterations = smoothVal)catch()”)

Hope this helps.

Just curious, how many different ways are there in MEL to do this? ;o)

Cheers,

Bobo

Just wanted to add to my previous post that when I am talking about a function being “slow”, it is in general terms, with heavy code executing thousands of operations.

All examples I posted above executed on my machine (Athlon MP 2800+) in between 110 and 125 milliseconds, no matter what changes I made. So the try()catch() and execute effect cannot be measured in a short code like this.

Executing the two code versions (getNodeByName vs. Execute) 100000 times shows that the execute code is slightly slower,
29.312 seconds vs 25.890 with GetNodeByName…

Obviously, when doing stuff with millions of vertices for example. applying a scripted operation to each vertex would be faster if no execute or try()catch() would be around…

JFYI

Bobo

you the man BOBO!

Thanks man…

Originally posted by Technofreak
[B]you the man BOBO!

Thanks man… [/B]

Thanks, but…

To correct myself:

for i in objs do
(
if (theObject = getNodeByName i) != undefined do
try(theObject.meshsmooth.iterations = smoothVal)catch()
)

can be reduced to

for i in objs do
(
theObject = getNodeByName i
try(theObject.meshsmooth.iterations = smoothVal)catch()
)

since try()catch() will take care in the case the node does not exist in the scene. Checking for undefined is obviously redundant!

No idea what I was thinking

Bobo

Originally posted by Bobo
[
for i in objs do
execute (“try($’”+i+”’.MeshSmooth.iterations = smoothVal)catch()”)

[/B]

Some more notes while we are on it:

The above code assumes that smoothVal is a GLOBAL variable!
If it is not, the code will not work with execute.

To avoid this, you could add the value of the variable to the string:

for i in objs do
execute (“try($’”+i+”’.MeshSmooth.iterations = ” + smoothVal as string + “)catch()”)

Note that you have to explicitly convert the variable to string to be able to concatenate. In this case, smoothVal can be a local variable.

This is one of the reasons I was against using the execute method (unless absolutely necessary)

Cheers.
Bobo

you the man BOBO!

Thanks man…