[Closed] vray MultiMatteElement from Layer
Hi,
I have found a script, it creates a MultiMatteElement pass from your layers, and applies object id’s to the geometry.
The problem i have with this is, when i have a scene, with particles and forest pack objects it errors out.
Is there away to have the script to apply only to geometry objects and shapes? in the scene?
heres the script:
clearlistener()
fn keepChars str pass: = (
local killChars = case pass of
(
1: "abcdefghijklmnopqrstuvwxyz0123456789_ABCDEFGHIJKLMNOPQRSTUVWXYZ!()*- /@"
2: "abcdefghijklmnopqrstuvwxyz0123456789_ABCDEFGHIJKLMNOPQRSTUVWXYZ!()*- /@"
3: "abcdefghijklmnopqrstuvwxyz0123456789_ABCDEFGHIJKLMNOPQRSTUVWXYZ!()*- /@"
)
for i = str.count to 1 by -1 where (local index = findString killChars str[i]) == undefined do str = replace str i 1 ""
str
)
fn cropString str charMax = (
if str.count > charMax then
(
str = keepChars str pass:1
if str.count >charMax then
(
str = keepChars str pass:2
if str.count > charMax then
(
str = keepChars str pass:3
if str.count > charMax then
(
str = substring str 1 charMax
)
else str
)
else str
)
else str
)
str
)
fn removeElementByPrefix pref = (
clearlistener()
local re = maxOps.GetCurRenderElementMgr()
for i = re.numrenderelements()-1 to 0 by -1 do
(
x = (re.GetRenderElement i)
elName = x.elementName
prefix = substring elName 1 pref.count
if prefix == pref do
(
format "Removing element %
" elName
re.REmoveRenderElement x
)
)
)
(
local re = maxOps.GetCurRenderElementMgr()
local el = multimatteelement
local groupsSoFar = 0
--starting ID's number
local startID = 00
--MultiMatteElement name remove
removeElementByPrefix "matte_"
for el = 1 to re.numrenderelements() do
(
re.GetRenderElement el
)
while groupsSoFar*3 < layerManager.count-1 do
(
layerGroup = ""
idGroup = #()
for i = 1 to 3 while (x = i+groupsSoFar*3) <= layerManager.count-1 do
(
layer = ILayerManager.getLayerObject x
layerRefs = refs.dependents layer
layerName = (cropString ((layerManager.getLayer x).name) 9)
layerNodes = #()
layerGroup += layerName
append idGroup (startID + x)
for o in layerRefs where classof (superClassOf o) == node and superclassof o == GeometryClass do
(
append layerNodes o
)
----help????
for obj = 1 to layerNodes.count do
(
if layerNodes[obj] != "shapes" do
(
layerNodes[obj].gbufferChannel = x
)
)
format "LayerRefs: %
" layerRefs
format "Layer: %
" layerName
format "Objects: %
" layerNodes
format "ObjectID: %
" x
)
if idGroup.count < 3 do
(
append idGroup (idGroup[idGroup.count] + 1)
if idGroup.count < 3 then
(
append idGroup (idGroup[idGroup.count] + 1)
)
else()
)
---Name_Pass
layerGroup = "matte_" + layerGroup
format "MultiMatte name: % is % characters.
" layerGroup layerGroup.count
format "IDs in MM: %
" idGroup
format "--------------------
"
if groupsSoFar*3 < layerManager.count-1 do
(
re.addrenderelement (el elementname:layerGroup R_gbufID:idGroup[1] R_gbufIDOn:(on) G_gbufID:idGroup[2] G_gbufIDOn:(on) B_gbufID:idGroup[3] B_gbufIDOn:(on) )
)
groupsSoFar +=1 --increment the groups counter
)
)
Thanks
If several Classes falls into the same Superclass and you need to filter them, one way I can think of is to have either a “whitelist” or a “blacklist” of Classes, the shortest or the safest one, depending on what information of the scene you have. It might not be elegant but could work.
This function uses a blacklist to filter out the default Particles Systems:
(
fn GetSceneNodes =
(
blacklist =
#(
pf_source,
particlegroup,
snow,
blizzard,
pcloud,
spray,
superspray,
parray
)
layernodes = #()
for o in objects where iskindof o node do
(
if superclassof o == geometryclass do
(
if finditem blacklist (classof o) == 0 do append layernodes o
)
)
return layernodes
)
nodes = GetSceneNodes()
)
This other function uses a whitelist to collect some of the Geometry Classes and Shapes:
(
fn GetSceneNodes =
(
whitelist =
#(
polymeshobject,
editable_mesh,
editable_poly
)
layernodes = #()
for o in objects where iskindof o node do
(
if finditem whitelist (classof o) != 0 or superclassof o == shape do append layernodes o
)
return layernodes
)
nodes = GetSceneNodes()
)
Or simply
fn GetSceneNodes =
(
fn filterGeo node = ((node.category != #Itoo_Software or node.category != #Particle_Systems) and canconvertto node Editable_Mesh)
for o in objects where filterGeo o collect o
)
nodes = GetSceneNodes ()
Couldn’t it happen that certain Particle System plugins don’t use the #Particle_Systems category and use a different one?
I don’t know. Maybe but I did’nt use such P-System. Anyway… We can always put one more item in the “exclude” lisr. Right?
Thank you PolyTools3D,
just abit stuck as, were to put that into the script?
Im not very proficient with maxscripting
Good question!
I am not entirely sure of how the function works nor do I have a proper scene to fully test it, but I guess that for Meshes, Polys and Shapes the following code should work:
clearlistener()
fn keepChars str pass: = (
local killChars = case pass of
(
1: "abcdefghijklmnopqrstuvwxyz0123456789_ABCDEFGHIJKLM NOPQRSTUVWXYZ!()*- /@"
2: "abcdefghijklmnopqrstuvwxyz0123456789_ABCDEFGHIJKLM NOPQRSTUVWXYZ!()*- /@"
3: "abcdefghijklmnopqrstuvwxyz0123456789_ABCDEFGHIJKLM NOPQRSTUVWXYZ!()*- /@"
)
for i = str.count to 1 by -1 where (local index = findString killChars str[i]) == undefined do str = replace str i 1 ""
str
)
fn cropString str charMax = (
if str.count > charMax then
(
str = keepChars str pass:1
if str.count >charMax then
(
str = keepChars str pass:2
if str.count > charMax then
(
str = keepChars str pass:3
if str.count > charMax then
(
str = substring str 1 charMax
)
else str
)
else str
)
else str
)
str
)
fn removeElementByPrefix pref = (
clearlistener()
local re = maxOps.GetCurRenderElementMgr()
for i = re.numrenderelements()-1 to 0 by -1 do
(
x = (re.GetRenderElement i)
elName = x.elementName
prefix = substring elName 1 pref.count
if prefix == pref do
(
format "Removing element %
" elName
re.REmoveRenderElement x
)
)
)
(
local re = maxOps.GetCurRenderElementMgr()
local el = multimatteelement
local groupsSoFar = 0
--starting ID's number
local startID = 00
--MultiMatteElement name remove
local whitelist =
#(
polymeshobject,
editable_mesh,
editable_poly
)
removeElementByPrefix "matte_"
for el = 1 to re.numrenderelements() do
(
re.GetRenderElement el
)
while groupsSoFar*3 < layerManager.count-1 do
(
layerGroup = ""
idGroup = #()
for i = 1 to 3 while (x = i+groupsSoFar*3) <= layerManager.count-1 do
(
layer = ILayerManager.getLayerObject x
layerRefs = refs.dependents layer
layerName = (cropString ((layerManager.getLayer x).name) 9)
layerNodes = #()
layerGroup += layerName
append idGroup (startID + x)
-- for o in layerRefs where classof (superClassOf o) == node and superclassof o == GeometryClass do
-- (
-- append layerNodes o
-- )
for o in layerRefs where iskindof o node do
(
if finditem whitelist (classof o) != 0 or superclassof o == shape do append layerNodes o
)
----help????
for obj = 1 to layerNodes.count do
(
if layerNodes[obj] != "shapes" do
(
layerNodes[obj].gbufferChannel = x
)
)
format "LayerRefs: %
" layerRefs
format "Layer: %
" layerName
format "Objects: %
" layerNodes
format "ObjectID: %
" x
)
if idGroup.count < 3 do
(
append idGroup (idGroup[idGroup.count] + 1)
if idGroup.count < 3 then
(
append idGroup (idGroup[idGroup.count] + 1)
)
else()
)
---Name_Pass
layerGroup = "matte_" + layerGroup
format "MultiMatte name: % is % characters.
" layerGroup layerGroup.count
format "IDs in MM: %
" idGroup
format "--------------------
"
if groupsSoFar*3 < layerManager.count-1 do
(
re.addrenderelement (el elementname:layerGroup R_gbufID:idGroup[1] R_gbufIDOn:(on) G_gbufID:idGroup[2] G_gbufIDOn:(on) B_gbufID:idGroup[3] B_gbufIDOn:(on) )
)
groupsSoFar +=1 --increment the groups counter
)
)
Thanks PolyTools3D, works perfectly, tired testing in various scenes and hasn’t broken yet
Of course. The OP can add as many things as needed, depending on what the scenes contains and what needs to be excluded. That’s why my suggestion of blacklisting or whitelisting. I would believe that most scenes would use polys or meshes, but that’s far away from been accurate, as I have no idea of what other artists/developers have in their scenes.
They could use a load of custom or commercial plugins that I we are not aware of. For example, as I don’t have Forest Pack to test it, I have no idea of what you can build with it or if everything you can build with it will fall into the #Itoo_Software category.
I agree.
Also every user which use 3d party plugs that causing similar problems can also learn a simple line of mxs code ($.category) to find object category and simply isolate it from the process.
Personally I wouldn’t rely that much just in the “Category” of a node. See the following very simple example:
(
delete objects
pf_source logo_size:25 emitter_length:50 emitter_width:50
for node in objects do
(
format "class:% category:%
" (classof node) node.category
)
)