PDA

View Full Version : Really simple script, select by name apply a modifier, if not, found skip it.


dpsygnet
09-19-2006, 12:55 PM
I'm trying to write a script that look for object with a certain name like *_LOD01 and apply a modifier like meshsmooth and set the itteration do 2. then look for a *_LOD02, apply a meshsmooth and set the iteration to 2. then do it for 3. but if no objet is named _LOD(number) then skip instead of displaying a script error.

I can write thing with the macro listener and web serach or mixing script together but i have no understanding of defining things.

Thank you and i hope i'm not bothering you with all my questions !

d3coy
09-19-2006, 03:54 PM
something like,


(
local theObjs = #()
select $*_LOD*

if selection.count != 0 do
(
local theMod = (meshsmooth())
theMod.iterations = 0
theMod.userenderiterations = true
theMod.renderiterations = 2

theObjs[selection.count] = undefined
for x = 1 to selection.count do theObjs[x] = selection[x]

for o in theObjs do
if validmodifier o (meshsmooth()) do addmodifier o theMod
)
)


should do the trick, unless you don't want the meshsmooths to be instanced, in which case you just take it out the pre-initialization and apply a different one during each iteration:


(
local theObjs = #()
select $*_LOD*

if selection.count != 0 do
(
theObjs[selection.count] = undefined
for x = 1 to selection.count do theObjs[x] = selection[x]

for o in theObjs do
if validmodifier o (meshsmooth()) do
(
addmodifier o (meshsmooth())
theMod = o.modifiers[1]
theMod.iterations = 0
theMod.userenderiterations = true
theMod.renderiterations = 2
)
)
)

dpsygnet
09-19-2006, 06:19 PM
thanx for the help but i tryed it and it does not work.

the modifier is not a meshsmooth it's a in-house modifier with a value that go from 1 to 3. It works exactly like a meshsmooth but it's an another name.

the thing i canT' get to work with your code is that i want the objet named *_LOD01 to have a value of 1 in the 'meshsmooth' the *_LOD02 to have a value of 2 and the *_LOD03 a value of 3. I canT' gwet it to work like taht with your code :(

OH and i need it to work ONLY on the selected object !
Like if i select the object something_LOD01 it will do other things taht i scripted and then at the end it will apply the modifier witth a value of 1. if i select a model with LOD02 it will apply a value of 2. if no *LOD* is found in the name, don't apply the modifier and go on

any ideas ?

d3coy
09-19-2006, 06:51 PM
Well you'll have to find out the name of your in-house modifier in Maxscript and swap out the (meshsmooth()) modifier in the code I wrote. Whoever wrote the modifier should know the maxscript function call for the modifier. The code I wrote sets all the iterations to 2, since that's what the original post said. It also uses render iterations instead of viewport visible iterations since when doing subdivisions on possibly many many objects in a loop you would experience significant slow-down.

So you want it to work on your selection, and go off the object's name to set the iterations. If your object's name ends with the number you want the iterations set to, you can easily extract that number by doing something like:


(
nameLength = theObj.name.count
theMod.iterations = theObj.name[nameLength] as integer
)


But if your number is nestled somewhere in the name, you're going to have to use a fancier method of extraction, probably using findString.

I've never scripted using a custom modifier, so I don't know if Maxscript would be totally kosher with validmodifier calls on a custom modifier, but the code below will work correctly assuming the number is the last part of the object's name, doesn't exceed 9, and your modifier is completely compatible with meshsmooth's properties. I've also just used normal iterations instead of renderiterations in this case. If your modifier isn't exposed to maxscript then you might be out of luck friend.


(
local theObjs = for o in selection do collect o

if theObjs.count != 0 do
for o in theObjs where (validmodifier o (yourModifier()) do
(
local nameLength = o.name.count
addmodifier o (yourModifier())
theMod = o.modifiers[1]
theMod.iterations = o.name[nameLength] as integer
)
)


*edit* Just saw your edit. You have to execute the script everytime you change your selection, unless you set up some callback stuff. The above script assumes you already have your LOD objects selected, it'll then go in and apply the modifier and set the iterations according to the number at the end of the object's name. So you select your LOD objects, execute the script and it sets up your modifiers. Executing it on objects with no number at the end of their name will throw an error.

dpsygnet
09-19-2006, 08:05 PM
I can'T get your script to work :/
The max listener is writing this error :
>> MAXScript MacroScript Error Exception: -- Syntax error: at collect, expected <factor>
-- In line: local theObjs = for o in selection do collect o <<

I got your last script to work with the modifier with something like

local theObjs = #()
select $*_LOD01

if selection.count != 0 do
(
theObjs[selection.count] = undefined
for x = 1 to selection.count do theObjs[x] = selection[x]

for o in theObjs do
if validmodifier o (GLOD ()) do
(
addmodifier o (GLOD ())
$.modifiers[#GLOD].displayNumber = 1
)
)
)
(
local theObjss = #()
select $*_LOD02

if selection.count != 0 do
(
theObjss[selection.count] = undefined
for x = 1 to selection.count do theObjss[x] = selection[x]

for o in theObjss do
if validmodifier o (GLOD ()) do
(
addmodifier o (GLOD ())
$.modifiers[#GLOD].displayNumber = 2
)
)
)
(
local theObjsss = #()
select $*_LOD03

if selection.count != 0 do
(
theObjsss[selection.count] = undefined
for x = 1 to selection.count do theObjsss[x] = selection[x]

for o in theObjsss do
if validmodifier o (GLOD ()) do
(
addmodifier o (GLOD ())
$.modifiers[#GLOD].displayNumber = 3
clearSelection()
)
)
)


But it only works if i have nothing selected and it do it for the scene and not the selected object :shrug:

d3coy
09-19-2006, 08:20 PM
sorry about that, I'm writing these from my head. There's a syntax error here:


local theObjs = for o in selection do collect o


should be:


local theObjs = for o in selection collect o

dpsygnet
09-20-2006, 12:11 PM
i still can't get it to work :sad:
i get a

-- Syntax error: at ), expected while
-- In line: )

Do you think you could modify my script so it can run only on selected object ?

d3coy
09-20-2006, 02:34 PM
There was an extra parenthesis :) Gotta love syntax errors, I really should have tested these before writing them out to you. Anyways, the below script works perfectly for me on selected objects. It (again) will look to the last character of the name of the object, if that last character is not a number then it will throw an error, otherwise it will use that number as the iterations (or displayNumber in your case). The code I wrote worked perfectly with meshsmooth and turbosmooth modifiers, but I modified it to match your GLOD modifier and displayNumber instead of iterations property.


(
local theObjs = for o in selection collect o

if theObjs.count != 0 do
for o in theObjs where (validmodifier o (GLOD())) do
(
local nameLength = o.name.count
addmodifier o (GLOD())
o.modifiers[#GLOD].displayNumber = o.name[nameLength] as integer
)
)

dpsygnet
09-20-2006, 03:24 PM
wow awesome !!

but i have one last request :)

If there is no number at the end of the model, instead of an error, can it simply go one with the rest of the code ?

this script is gonna be apply to models and IF the item is named with LOD01-02 or 03 then it will apply the GLOD. but still, it's great as it is !

d3coy
09-20-2006, 03:50 PM
Glad it worked :) Took long enough, haha


(
local theObjs = for o in selection collect o

if theObjs.count != 0 do
for o in theObjs where (validmodifier o (GLOD())) do
if findstring o.name "LOD" != undefined do
(
local nameLength = o.name.count
addmodifier o (GLOD())
if (o.name[nameLength] as integer) != undefined then
o.modifiers[#GLOD].displayNumber = o.name[nameLength] as integer
else print (o.name + " is an LOD object without a valid number")
)
)


This will only add the modifier to currently selected objects with "LOD" in their names. If "LOD" is in the name but the number isn't at the end of the name, or the name ends with a letter, it will print into the listener what object is incorrectly named, and you'll have to go in and set the iterations manually on that object. If you want to run the script on an entire scene instead of just your selection, change the first line to this:


local theObjs = for o in geometry where classof o != targetobject collect o


and it will act on every geometry object.

CGTalk Moderation
09-20-2006, 03:50 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.