[Closed] Cleaning up Architectural Materials
MXS-ers,
Got a quick question for you. I am trying to replace architectural materials with standard ones. Here is the basic idea:
fn cleanMaterials theType = (
local theMats = getClassInstances theType
for m in theMats do (
m = standardMaterial ()
)
)
rollout rlt_Main "replace" (
button btn_Replace "Replace Arch Materials with Standard ones"
on btn_Replace pressed do (
cleanMaterials Architectural
)
)
However, probably because m is referring to the instance of that material it will not change. Things within the
for m in theMats
block do work like
m.name = "new" \\ m.diffuse = [255,0,0] \\ etc
I could do something inefficient and run through all the objects in the scene and find the ones that have architectural materials applied and update them to the new material, but there must be another way that’s faster. I’m clearly missing something easy, what is it?
-Thanks,
Colin
Here is my code for cleaning up architectural materials
fn cleanMaterials theType = (
local theMats = getClassInstances theType
local newMat = standardMaterial name:"Arch->Standard" diffuseColor:[127,127,127]
local txtUndo = "Replace " + (theType as string) + " Materials"
local cleaned = 0
undo txtUndo on (
for o in objects do (
for m in theMats do (
if o.material == m then (
o.material = newMat
cleaned += 1
)
)
)
)
cleaned
)
rollout rlt_Main "Clean Materials" (
button btn_Arch "Architectural"
button btn_RT "Raytrace"
label lbl_Arch "Cleaned: "
label lbl_RT "Cleaned: "
on btn_Arch pressed do (
local cleaned = cleanMaterials Architectural
lbl_Arch.caption = "Cleaned: " + (cleaned as string)
)
on btn_RT pressed do (
local cleaned = cleanMaterials RaytraceMaterial
lbl_RT.caption = "Cleaned: " + (cleaned as string)
)
)
createDialog rlt_Main 300 200
This is the code I’m using to replace all Architectural and Raytrace Materials in the scene with Standard ones because VRay really doesn’t like either of these. If someone could chime in on a better way of doing this instead of looping through all the scene’s objects (which is tedious as far as time is concerned for large scenes).
Any better ideas?
-Colin
you could loop through SceneMaterials instead of each object, would be much quicker methinks
EDIT: scratch that
try this:
dirtyMatObjs = (for o in objects where classof o.material == Architectural OR classof o.material == RaytraceMaterial collect o)
for m in dirtyMatObjs do
(
m.material = (Standard())
--or you could just remove the material
--from those objects with: m.material = undefined
)
I also find it useful do use the following lines when there might be a large amount of items to loop through:
tMode = getCommandPanelTaskMode() --saves current command panel state
max create mode --switches to the create panel for faster script execution
--then when your looping is done
SetCommandPanelTaskMode tMode --returns command panel to original state
you could loop through SceneMaterials instead of each object, would be much quicker methinks
EDIT: scratch that
Why scratch that just curious, looping through sceneMaterials would be faster than looping through the objects when there’s 1000s of objects no?
Thanks a ton, didn’t know scripts executed faster in max create mode! I will certainly be utilitizing this snippet plenty in the future. +++
-Colin
i said scratch that because i gave it a test (a very quick test mind you) and for some reason even though there was no error, the architectural mat i was testing on still remainded in my material editor and appeared as though it was still applied to my test object. I’m sure if you did some more tests you would be able to sort it out though.
another good piece of code i just remembered is:
with redraw off
(
--do some stuff
)
this stops max trying to redraw the viewports as the script is being executed
enjoi!
excellent, I was having the very same problem earlier, I will do some more tests when I get a break today. Thanks for bouncing some ideas with me Gravey.
-Colin