If you don't have VRayScatter or MultiScatter and a massively huge scene, you probably won't get the same errors... But you may find the script useful if you use layers extensively.
It runs through the list of layers and gives a unique .gbufferchannel to all objects on each layer. Then generates one MultiMatte per three layers. Until I build a UI, it simply starts at ObjectID 300.
Layer01 objects are assigned gbufferchannel 301
Layer02 objects 302
Layer03 objects 303
Layer04 objects 304
Layer05 objects 305
Layer06 objects 306
etc
MultiMatte "Layer01Layer02Layer03" is 301 for Red, 302 for Green, 303 for Blue
etc, etc, through all layers.
It also truncates layers so that the MultiMatte name is <= 31 characters due to the EXR spec for channel names, but that's irrelevant.
It gets the nodes on each layer using refs.dependents for each layer and then filtering out only the GeometryClass nodes. This works fine on small scenes but for some reason on my current scene with nearly 11,000 objects, it is breaking.
Check the listener to get an idea of what it's doing.
Here is an example of the layerRefs vs the filtered nodes:
The problem is with the highlighted VRayScatter objects. The $VRS_... objects are VRayScatter class as well but show up properly in the node array...
It works fine a small test scene. It cycles through all layers even with VRayScatter objects and has no problem....
sigh
Any help would be primo,
Also posted on CGTalk I hope that's not a forum faux pas
It runs through the list of layers and gives a unique .gbufferchannel to all objects on each layer. Then generates one MultiMatte per three layers. Until I build a UI, it simply starts at ObjectID 300.
Layer01 objects are assigned gbufferchannel 301
Layer02 objects 302
Layer03 objects 303
Layer04 objects 304
Layer05 objects 305
Layer06 objects 306
etc
MultiMatte "Layer01Layer02Layer03" is 301 for Red, 302 for Green, 303 for Blue
etc, etc, through all layers.
It also truncates layers so that the MultiMatte name is <= 31 characters due to the EXR spec for channel names, but that's irrelevant.
It gets the nodes on each layer using refs.dependents for each layer and then filtering out only the GeometryClass nodes. This works fine on small scenes but for some reason on my current scene with nearly 11,000 objects, it is breaking.
Check the listener to get an idea of what it's doing.
Here is an example of the layerRefs vs the filtered nodes:
layerRefs: #($VRS_GreenRoof_OrnimentalGrass01, ReferenceTarget:NodeSelection, ReferenceTarget:ReferenceTarget, ReferenceTarget:ReferenceTarget, ReferenceTarget:NodeSelection, ReferenceTarget:ParamBlock2, RMVisSetArray2:RMVisSetArray2, Controller:Bezier_Float, ReferenceTarget:ParamBlock2, RMVisSetArray1:RMVisSetArray1, $VRS_GreenRoof_MiscanthusClump02, $VRS_GreenRoof_Fescue02, $VRS_SucculentGarden_Base, ReferenceTarget:NodeNamedSelSet, ReferenceTarget:NamedSelSetList, ReferenceTarget:Scene, ReferenceTarget:ParamBlock2, VRayScatter, ReferenceTarget:ParamBlock2, VRayScatter, ...)
layerNodes: #($VRS_GreenRoof_OrnimentalGrass01, $VRS_GreenRoof_MiscanthusClump02, $VRS_GreenRoof_Fescue02, $VRS_SucculentGarden_Base, VRayScatter, VRayScatter, VRayScatter)
layerNodes: #($VRS_GreenRoof_OrnimentalGrass01, $VRS_GreenRoof_MiscanthusClump02, $VRS_GreenRoof_Fescue02, $VRS_SucculentGarden_Base, VRayScatter, VRayScatter, VRayScatter)
It works fine a small test scene. It cycles through all layers even with VRayScatter objects and has no problem....
sigh
Code:
clearlistener() fn keepChars str pass: = ( local killChars = case pass of ( 1: "abcdefghijklmnopqrstuvwxyz0123456_" 2: "abcdefghijklmnopqrstuvwxyz" 3: "bcdfghjklmnpqrstvwxyz" ) 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 %\n\n" elName re.REmoveRenderElement x ) ) ) ( local re = maxOps.GetCurRenderElementMgr() local el = multimatteelement local groupsSoFar = 0 local startID = 300 removeElementByPrefix "LAY_" 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 obj = 1 to layerNodes.count do ( if layerNodes[obj] != "VRayScatter" do ( layerNodes[obj].gbufferChannel = x ) ) format "LayerRefs: %\n" layerRefs format "Layer: %\n" layerName format "Objects: %\n" layerNodes format "ObjectID: %\n" x ) if idGroup.count < 3 do ( append idGroup (idGroup[idGroup.count] + 1) if idGroup.count < 3 then ( append idGroup (idGroup[idGroup.count] + 1) ) else() ) layerGroup = "LAY_" + layerGroup format "MultiMatte name: % is % characters.\n" layerGroup layerGroup.count format "IDs in MM: %\n\n" idGroup format "--------------------\n\n" 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 ) )
Also posted on CGTalk I hope that's not a forum faux pas