ScriptSpot

Forum topic · General Scripting

Create Render Element for each layer

By Huehv · 2018-10-30

Description

Hi all,

I would like to create a script which add automaticaly a C_Masking render Element for each layer composed of this objects.
I already succed to create a render element for on layer but i don't know how create a loop which scan all layers in a scene.

Can you help me ? :)

Thank you in advance

Comments (13)

Hi! I want some help to do the same thing.

Bluby · 2020-07-14

I manage to add render elments for all the layers with Gbuffer Id name for all the layers but i don't know how to add layer name to the render element. I will put below the code with what i manage to do so far.

   ---------------------------------------------

    (
rollout CoronaMask_roll "Corona Mask"

(

fn getObjectsIDArray sel =
(   
    local GBufferArray = #()
   
    for o in (if sel == false then objects else selection) where o.gbufferchannel != 0 do
    (
    if (findItem GBufferArray (o.gbufferchannel as string)) == 0 then append GBufferArray (o.gbufferchannel as string)
    )
    return GBufferArray


)


group "Render Elements"
(

button btn_go "Create Corona Mask" align:#right
on btn_go pressed do
(
        -- this will add Gbuffer ID on layers
        (
            fn setLayerObjID ignoreEmpy:on =
            (
            local getlayer = LayerManager.getlayer, layer, idx = 0
            if not ignoreEmpy then (for i = 0 to layerManager.count-1 where ((layer = getlayer i).nodes &objs ; objs).count > 0 do objs.gbufferChannel = (i+1)) else
            (
            for i = 0 to layerManager.count-1 where ((layer = getlayer i).nodes &objs ; objs).count > 0 do objs.gbufferChannel = (idx+=1)
            )
            )
            setLayerObjID()-- this will ignore empty layer (id order 1,2,3,4,5 ...)
            setLayerObjID ignoreEmpy:off -- this will ignore empty layer (id order 1,2,4,6 ...)
        )
   
   
   
    -------This lines will add CMasking_Mask render elements and Gbuffer id name to element
    (
   
        if matchpattern (renderers.current as string) pattern:"Corona*" == true then (
        re = maxOps.GetCurRenderElementMgr()

        maskElms = for i=0 to re.NumRenderElements() where classof (re.GetRenderElement i) == CMasking_Mask collect re.GetRenderElement i
        for i in (getObjectsIDArray false) do (
        exclude = false
           

           
        for m in maskElms where m.objectMono == (i as integer) do exclude = true
        if not exclude then re.AddRenderElement (CMasking_Mask elementname:("Name of layer here_"+i)mode:0 objectMonoOn:true objectMono:( i as integer))
        )
        )
        else messagebox "Use Corona Render"
        )
        )
)
   
   
   
   
) -- dialog
createdialog CoronaMask_roll width:150 height:160 style:#(#style_sysmenu, #style_toolwindow)
)

.

jahman · 2020-07-14

check the answer on cgs

Thank you for the replay!

Bluby · 2020-07-14

I checkd the CGS and think that the problem is that im a super beginner and i use just simple maxscript lines and make some minor modifications on other scripts,i will need to learn more to make this modification by my self . Simply said, the only answer for me is that if you can help me to make him work. Thank you very much in advance!

.

jahman · 2020-07-14

I didn't test it in max. Hope it works


(
	rollout CoronaMask_roll "Corona Mask"
	(

		fn GetUsedGBufferChannels sel =
		(   		
			MakeUniqueArray (for o in (if sel == false then objects else selection) where o.gbufferchannel != 0 collect o.gbufferchannel)
		)
		
		fn GetLayerNameByGBufferChannel index =
		(
			local layer_name
			for o in objects while layer_name == undefined where o.gbufferChannel == index do layer_name = o.layer.name
			layer_name
		)
		
		fn setLayerObjID ignoreEmptyLayers:on =
		(
			local getlayer = LayerManager.getlayer, layer, idx = 0
			
			if not ignoreEmptyLayers then
			(
				for i = 0 to layerManager.count-1 where ((layer = getlayer i).nodes &objs; objs).count > 0 do objs.gbufferChannel = i+1
				
			)
			else
			(
				for i = 0 to layerManager.count-1 where ((layer = getlayer i).nodes &objs; objs).count > 0 do objs.gbufferChannel = (idx+=1)
			)
		)

		group "Render Elements"
		(

			button btn_go "Create Corona Mask" align:#right
			on btn_go pressed do
			(

				setLayerObjID() -- this will ignore empty layer (id order 1,2,3,4,5 ...)
			   
				if matchpattern (renderers.current as string) pattern:"Corona*" == true then
				(
					re = maxOps.GetCurRenderElementMgr()

					corona_mask_elements = for i=0 to re.NumRenderElements() where classof (re.GetRenderElement i) == CMasking_Mask collect re.GetRenderElement i
					
					for gbuffer_index in GetUsedGBufferChannels false do
					(
						exclude = false
						for m in corona_mask_elements where m.objectMono == gbuffer_index do exclude = true
						
						if not exclude then
						(				
							layer_name = GetLayerNameByGBufferChannel gbuffer_index
							re.AddRenderElement ( CMasking_Mask elementname:layer_name mode:0 objectMonoOn:true objectMono:gbuffer_index )			
						)
					)	
				) else messagebox "Use Corona Render"
				
			   
			)
		)
	)
	
	createdialog CoronaMask_roll width:150 height:160 style:#(#style_sysmenu, #style_toolwindow)
)

Thank you very much, its working perfectly!

Bluby · 2020-07-14

You saved me a lot of time from adding manually all that layers on the CMasking render elements. The problem was that i work with large scenes with many layers and i have to be very organize with all the assets.
Thank you one more time for your time and patience to help me and other people.

scottparris · 2020-09-08

Could you make this work with V-Ray MultiMattes? It works great with Corona but I can't find the problem writing it for V-Ray.

Attachments

.

jahman · 2020-09-09

Check your matchpattern pattern


renderers.current as string -> "V_Ray_Adv_3_60_03:V_Ray_Adv_3_60_03"

scottparris · 2020-09-09

It works! Much appreciated.

scottparris · 2020-09-09

Sorry, one more. Instead of ignoring empty layers, would it be possible to ignore layers that are turned off or frozen?

phicata · 2019-01-28

Why not share this script?, it could be very useful! Thank

.

miauu · 2018-11-06


(
	for i = 0 to layerManager.count - 1 do
	(
		layer = layerManager.getlayer i
		format "layer name: % \n" layer.name
		-- add the code that creates Render Element here:

	)
)

Delete Render Element

Huehv · 2018-11-22

Thanks ! It works perfectly
Other question, I look for how to delete a specific render element ...
I find the expression : RemoveRenderElement, but i don't understand how to use it
I succeed delete all render elements but i don't care ...