[Closed] Instancing duplicate RPM Material Sub-Materials Script
Little script to re-instance RPMaterial sub-mats that have the same name and are the same class.
-- finds all like named materials in an RPMaterial and isntances them.
-- Gavin Greenwalt
-- Straightface Studios, Seattle, WA
-- 11/9/11
fn instanceLikeMats objMat =
(
if classof objMat == RPMMaterial do
(
matNames = makeUniqueArray (for o in objMat.materials where o != undefined collect o.name)
masterMats = for o in matNames collect ((for m in objMat.materials where m != undefined and m.name == o collect m)[1])
for o in masterMats do
(
for i = 1 to objMat.Materials.count do
(
if objMat.Materials[i] != undefeind and (objMat.Materials[i].name) == (o.name) and (classof objMat.Materials[i]) == (classof o) do
(
objMat.Materials[i] = o
)
)
)
)
)
print "Starting RPM sub-material istance hunt..."
for o in objects where o.material != undefined and classof o.material == RPMMaterial do
(
o.material.name = "RPMM "+o.material.materials[1].name
instanceLikeMats o.material
)
print "Finished instancing RPM sub-materials."
It’s a solution.
When you create an RPM Material it just copies it to all of the passes. So if you make a change to the material in one pass it doesn’t propagate by default. THis way you can always copy a specific render pass material but the rest stay in sync as instances.
Quite a few years ago I suggested to Grant that I thought the best default for the same sub-material in RPM materials would be auto-instance rather than copy. He changed it for a while, but I think people must have complained ’cause he changed it back. I can see reasons why either way could be preferable, but I personally prefer the instanced option so your script is very welcome.
Cg.
why did I ask about a problem? because the solution that you gave doesn’t work right… I modified your code to make it work with Composite Material (i don’t have RPM as many of us) but I left the same algorithm.
fn instanceLikeMats objMat =
(
if classof objMat == compositematerial do
(
matNames = makeUniqueArray (for o in objMat.materiallist where o != undefined collect o.name)
masterMats = for o in matNames collect ((for m in objMat.materiallist where m != undefined and m.name == o collect m)[1])
for o in masterMats do
(
for i = 1 to objMat.materiallist.count do
(
if objMat.materiallist[i] != undefeind and (objMat.materiallist[i].name) == (o.name) and (classof objMat.materiallist[i]) == (classof o) do
(
objMat.materiallist[i] = o
)
)
)
)
)
t1 = timestamp()
for o in objects where o.material != undefined and classof o.material == compositematerial do instanceLikeMats o.material
format "time:%
" (timestamp() - t1)
try this scene setup:
with undo off with redraw off
(
delete objects
seed 0
-- classes = #(Standard)
classes = #(Standard, Blend, Shellac)
-- names = #("A", "B", "C", "a", "b", "c")
names = #("A", "B", "C", "A", "B", "C")
for k=1 to 100 where (random 1 5) == 1 do
(
b = box name:(k as string)
b.mat = compositematerial()
for k=1 to b.mat.materiallist.count do b.mat.materiallist[k] = classes[random 1 classes.count] name:names[random 1 names.count]
)
gc()
)
after executing your code you will see for example that:
objects[1].mat.materiallist[2] != objects[1].mat.materiallist[3]
objects[2].mat.materiallist[5] != objects[2].mat.materiallist[10]
…
and it’s wrong
also it will be better to make the material names comparison not case sensitive.
here is my version:
fn instanceSimilarReplace mat =
(
local n = 1
local count = mat.materiallist.count
while n < count do
(
if iskindof (source = mat.materiallist[n]) Material do
(
for k=n+1 to count where iskindof (target = mat.materiallist[k]) Material and target != source do
(
if stricmp target.name source.name == 0 and (classof target == classof source) do replaceinstances target source
)
)
n += 1
)
)
t1 = timestamp()
for mat in (getclassinstances compositematerial target:rootnode) do instanceSimilarReplace mat
format "time:%
" (timestamp() - t1)
as you see the first algorithm “works” [/i]faster than main. but it’s just because it’s not complete.
anyone who sees the better solution is welcome.