Author Topic: Corona Mask Manager (2020)  (Read 2031 times)

2020-04-17, 08:48:53

cjwidd

  • Active Users
  • **
  • Posts: 1077
    • View Profile
    • Artstation
I'm looking for a method to modify an existing script from the Corona forums that automatically generates mono masks (CMasking_Mask) for every material in a scene. 

The script works very well, but requires some modifications to address edge cases:

watch x1.5 speed

2020-04-17, 23:36:10
Reply #1

niljut

  • Active Users
  • **
  • Posts: 16
    • View Profile
Looking at this briefly, adding this to line 172
Code: [Select]
if obj_list.count == 0 do continueIs enough to fix this issue, I think, making it skip the materials that are not directly assigned to any object.


Complete script:
Code: [Select]
/*
------------------------------------------------------------------------------------------------------
--> by Gabriel Sumner & durandal_1707 (big ThX for the original script structure and wireColor code)
--> timestamp: 23/05/15
-->Version 1.0 Alpha
-------------------------------------------------------------------------------------------------------
*/
/*Credits for code snippets (sorry if someone has been forgotten, his / her name shall be added here asap:
 > Dave Wortleys tutorial for the basis idea of adding renderElements: https://davewortley.wordpress.com/2012/06/22/making-render-element-masks/
 > Bobo "select object my material" : http://forums.cgsociety.org/archive/index.php/t-183739.html
 >
*/

/* known issues:
- only Corona materials are renamed to shorten the naming of the saved renderElement
- only poly geometry is supported: lines need to have an editPoly on top of the stack to be recognized; Groups are not supported
- if the "create mono masks" button is pressed several times the script keeps adding new render elements, no check for existing elements at the moment
- open / close script window is somewhat buggy, needs optimizin'...
*/

/* TODO: planed functions (everyone is welcome to change the script in any way / participate in the development ;) )
- check for existing elements and warn the user to create additional or replace the existing once
- delete all mono mask elements
- set different path for render elements
- set different file format for render elements
*/


(
--try(destroydialog wireColorByMatRollout)catch()   >> toDo dialog creation

re = maxOps.GetCurRenderElementMgr()

local theMaterials = for m in SceneMaterials collect m

/* Material Names List */
local theNames = for n in theMaterials collect n.name
/*Remove the word "Material" for easier file naming */
for i=1 to theNames.count do
(
try(
if i != undefined then
theNames[i] = replace theNames[i] (findstring theNames[i] "Material ") 10 ""
)catch()
)


local fixedPaletteColors = #
(
(color 255 0 0), /* 1 - RED */
(color 0 255 0), /* 2 - GREEN */
(color 0 0 255), /* 3 - BLUE */
(color 255 0 255), /* 4 - MAGENTA */
(color 255 255 0), /* 5 - YELLOW */
(color 0 255 255), /* 6 - CYAN */
(color 120 0 0), /* 7- DARK RED */
(color 0 120 0), /* 8 - DARK GREEN */
(color 0 0 120), /* 9 - DARK BLUE */
(color 120 0 120), /* 10 - DARK MAGENTA */
(color 120 120 0), /* 11 - DARK YELLOW */
(color 0 120 120), /* 12 - DARK CYAN */
(color 60 60 60), /* 13 - DARK GRAY */
(color 120 120 120), /* 14 - GRAY */
(color 255 255 255) /* 15 - WHITE */
)

struct materialWireColor
(
matRef, matName, wireColor
)

/* unique scene materials */
local sceneMats = #()
local sceneMatTags = #()

for sceneObject in (objects) do
(
if sceneObject.material != undefined then
appendIfUnique sceneMats sceneObject.material
)

/* pre-select wire colors from a fixed palette defined above */
for matIdx = 1 to  sceneMats.count do
(
local wireColor = (color 128 128 128)
if(matIdx <= fixedPaletteColors.count) then
wireColor = fixedPaletteColors[matIdx]

local matName = undefined
if sceneMats[matIdx].name != undefined then
matName = sceneMats[matIdx].name
else
matName = "unnamed_material_" + matIdx

append sceneMatTags (materialWireColor sceneMats[matIdx] matName wireColor)
)

/* Main UI */
global rofWireColors
rollout wireColorByMatRollout "Assign wire colors by material" width:340 height:320
(
listbox materialListBox "Scene materials" pos:[16,16] width:179 height:9 items:(for matTag in (sceneMatTags) collect matTag.matRef.name)
button assignColorsButton "Assign wire colors" pos:[50,160] width:235 height:40
--button createMonoMasksButton "Create mono masks" pos:[50,240] width:235 height:40
colorPicker wireColorPicker "" pos:[208,40] width:112 height:112
label lbl1 "Pick wire color" pos:[216,16] width:72 height:24

on wireColorByMatRollout open do
(
try
(
materialListBox.selection = 1
wireColorPicker.color = sceneMatTags[1].wireColor
)catch()
)

on materialListBox selected mlbSelIndex do
(
try
(
wireColorPicker.color = sceneMatTags[mlbSelIndex].wireColor
)catch()
)

on wireColorPicker changed newColor do
(
selMatIndex = materialListBox.selection
if selMatIndex != undefined then
sceneMatTags[selMatIndex].wireColor = newColor
)

on assignColorsButton pressed do
(
/*assign wire colors to objects based on their material */
for sceneObject in (objects) do
(
for sceneMatTag in (sceneMatTags) do
(
if sceneObject.material == sceneMatTag.matRef then
sceneObject.wireColor = sceneMatTag.wireColor
)
)
/* close UI */
try
(
closeRolloutFloater rofWireColors
) catch()
)
)
rollout monoMasksRollout "Generate Mono Masks for assigned sceneMats" width:340 height:260
(
button createMonoMasksButton "Create mono masks" pos:[5,10] width:150 height:40
button deleteAllMonoMasksButton "Delete all mono mask passes" pos:[180,10] width:150 height:40 enabled: false
on createMonoMasksButton pressed do
(
/*
--Materials List
theMaterials = for m in SceneMaterials collect m
--Material Names List
theNames = for n in theMaterials collect n.name
--Remove the word "Material" for easier file naming
for i=1 to theNames.count do
(
theNames[i] = replace theNames[i] (findstring theNames[i] "Material ") 10 ""
)
*/


for i=1 to theMaterials.count do
(
obj_list = (for o in Geometry where o.material == theMaterials[i] collect o)
if obj_list.count == 0 do continue
re.addrenderelement (CMasking_Mask())
theelement = re.getrenderelement (re.numrenderelements() - 1 )
theelement.elementName = ("Matte_" + theNames[i] as string)
theelement.nodesMonoOn = true
theelement.nodesMonoIncludeMod= true
theelement.nodesMono = obj_list;
obj_list=#()
--maskEls = append maskEls theelement.elementName
)

/*update  Render Setup Window */
if renderSceneDialog.isOpen()==true do
(
renderSceneDialog.close()
renderSceneDialog.open()
)

/*show  Render Setup Window */
renderSceneDialog.open()

/* close UI */
try
(
closeRolloutFloater rofWireColors
) catch()

)
/*
on deleteAllMonoMasksButton pressed do
(
)*/

)
/* prevent the user from opening more than one dialog at a time */
rollout miscRollout "Toolbox" width:340 height:260
(
label lbl1 "Select objects by mat" pos:[15,5] width:200 height:16
dropDownList matsDropDownList items:theNames
on matsDropDownList selected itm do
     select (for o in Geometry where o.material == theMaterials[itm] collect o)

label lbl2 "Set different path for render elements" pos:[15,55] width:200 height:16 enabled:false
editText edt1 "" pos:[10,75] width:200 height:25 enabled:false
button btn1 "Change path" pos:[220,75] width:85 height:25
enabled:false

label lbl3 "Set different file format for render elements" pos:[15,110] width:250 height:16 enabled:false
    dropdownList ddl_file_ext "" pos:[12,125] width:110 height:40 items:#(".avi", ".bmp", ".cin", ".eps", ".ps", ".exr", ".fxr", ".hdr", ".pic", ".jpg", ".png", ".rgb", ".rla", ".rpf", ".tga", ".tif", ".dds")enabled:false
)

rofWireColors = newRolloutFloater "Corona Mask Manager" 350 500
addRollout wireColorByMatRollout rofWireColors
addRollout monoMasksRollout rofWireColors
addRollout miscRollout rofWireColors


)

2020-04-18, 01:21:51
Reply #2

cjwidd

  • Active Users
  • **
  • Posts: 1077
    • View Profile
    • Artstation
@niljut this seems to address the issue exactly, thanks for your help!

Can I add another condition to prevent materials of hidden objects from being collected, something like:

Code: [Select]
for obj in objects where obj.isHidden do
« Last Edit: 2020-04-18, 06:03:34 by cjwidd »

2020-04-18, 09:32:08
Reply #3

cjwidd

  • Active Users
  • **
  • Posts: 1077
    • View Profile
    • Artstation
I added a couple more lines (172, 174) that seem to produce the desired result; I have no idea whether it is optimal, sensible, efficient, scalable, etc.

Code: [Select]
for i=1 to theMaterials.count do
(
obj_list = (for o in Geometry where o.material == theMaterials[i] collect o)
obj_list_vis = (for o in obj_list where not o.isHidden collect o)
if obj_list.count == 0 do continue
if obj_list_vis.count == 0 do continue
re.addrenderelement (CMasking_Mask())
theelement = re.getrenderelement (re.numrenderelements() - 1 )
theelement.elementName = ("alpha_" + theNames[i] as string)
theelement.nodesMonoOn = true
theelement.nodesMonoIncludeMod= true
theelement.nodesMono = obj_list;
obj_list=#()
--maskEls = append maskEls theelement.elementName
)

Complete script:

Code: [Select]

/*
------------------------------------------------------------------------------------------------------
--> by Gabriel Sumner & durandal_1707 (big ThX for the original script structure and wireColor code)
--> timestamp: 23/05/15
-->Version 1.0 Alpha
-------------------------------------------------------------------------------------------------------
*/
/*Credits for code snippets (sorry if someone has been forgotten, his / her name shall be added here asap:
 > Dave Wortleys tutorial for the basis idea of adding renderElements: https://davewortley.wordpress.com/2012/06/22/making-render-element-masks/
 > Bobo "select object my material" : http://forums.cgsociety.org/archive/index.php/t-183739.html
 >
*/

/* known issues:
- only Corona materials are renamed to shorten the naming of the saved renderElement
- only poly geometry is supported: lines need to have an editPoly on top of the stack to be recognized; Groups are not supported
- if the "create mono masks" button is pressed several times the script keeps adding new render elements, no check for existing elements at the moment
- open / close script window is somewhat buggy, needs optimizin'...
*/

/* TODO: planed functions (everyone is welcome to change the script in any way / participate in the development ;) )
- check for existing elements and warn the user to create additional or replace the existing once
- delete all mono mask elements
- set different path for render elements
- set different file format for render elements
*/


(
--try(destroydialog wireColorByMatRollout)catch()   >> toDo dialog creation

re = maxOps.GetCurRenderElementMgr()

local theMaterials = for m in SceneMaterials collect m

/* Material Names List */
local theNames = for n in theMaterials collect n.name
/*Remove the word "Material" for easier file naming */
for i=1 to theNames.count do
(
try(
if i != undefined then
theNames[i] = replace theNames[i] (findstring theNames[i] "Material ") 10 ""
)catch()
)


local fixedPaletteColors = #
(
(color 255 0 0), /* 1 - RED */
(color 0 255 0), /* 2 - GREEN */
(color 0 0 255), /* 3 - BLUE */
(color 255 0 255), /* 4 - MAGENTA */
(color 255 255 0), /* 5 - YELLOW */
(color 0 255 255), /* 6 - CYAN */
(color 120 0 0), /* 7- DARK RED */
(color 0 120 0), /* 8 - DARK GREEN */
(color 0 0 120), /* 9 - DARK BLUE */
(color 120 0 120), /* 10 - DARK MAGENTA */
(color 120 120 0), /* 11 - DARK YELLOW */
(color 0 120 120), /* 12 - DARK CYAN */
(color 60 60 60), /* 13 - DARK GRAY */
(color 120 120 120), /* 14 - GRAY */
(color 255 255 255) /* 15 - WHITE */
)

struct materialWireColor
(
matRef, matName, wireColor
)

/* unique scene materials */
local sceneMats = #()
local sceneMatTags = #()

for sceneObject in (objects) do
(
if sceneObject.material != undefined then
appendIfUnique sceneMats sceneObject.material
)

/* pre-select wire colors from a fixed palette defined above */
for matIdx = 1 to  sceneMats.count do
(
local wireColor = (color 128 128 128)
if(matIdx <= fixedPaletteColors.count) then
wireColor = fixedPaletteColors[matIdx]

local matName = undefined
if sceneMats[matIdx].name != undefined then
matName = sceneMats[matIdx].name
else
matName = "unnamed_material_" + matIdx

append sceneMatTags (materialWireColor sceneMats[matIdx] matName wireColor)
)

/* Main UI */
global rofWireColors
rollout wireColorByMatRollout "Assign wire colors by material" width:340 height:320
(
listbox materialListBox "Scene materials" pos:[16,16] width:179 height:9 items:(for matTag in (sceneMatTags) collect matTag.matRef.name)
button assignColorsButton "Assign wire colors" pos:[50,160] width:235 height:40
--button createMonoMasksButton "Create mono masks" pos:[50,240] width:235 height:40
colorPicker wireColorPicker "" pos:[208,40] width:112 height:112
label lbl1 "Pick wire color" pos:[216,16] width:72 height:24

on wireColorByMatRollout open do
(
try
(
materialListBox.selection = 1
wireColorPicker.color = sceneMatTags[1].wireColor
)catch()
)

on materialListBox selected mlbSelIndex do
(
try
(
wireColorPicker.color = sceneMatTags[mlbSelIndex].wireColor
)catch()
)

on wireColorPicker changed newColor do
(
selMatIndex = materialListBox.selection
if selMatIndex != undefined then
sceneMatTags[selMatIndex].wireColor = newColor
)

on assignColorsButton pressed do
(
/*assign wire colors to objects based on their material */
for sceneObject in (objects) do
(
for sceneMatTag in (sceneMatTags) do
(
if sceneObject.material == sceneMatTag.matRef then
sceneObject.wireColor = sceneMatTag.wireColor
)
)
/* close UI */
try
(
closeRolloutFloater rofWireColors
) catch()
)
)
rollout monoMasksRollout "Generate Mono Masks for assigned sceneMats" width:340 height:260
(
button createMonoMasksButton "Create mono masks" pos:[5,10] width:150 height:40
button deleteAllMonoMasksButton "Delete all mono mask passes" pos:[180,10] width:150 height:40 enabled: false
on createMonoMasksButton pressed do
(
/*
--Materials List
theMaterials = for m in SceneMaterials collect m
--Material Names List
theNames = for n in theMaterials collect n.name
--Remove the word "Material" for easier file naming
for i=1 to theNames.count do
(
theNames[i] = replace theNames[i] (findstring theNames[i] "Material ") 10 ""
)
*/


for i=1 to theMaterials.count do
(
obj_list = (for o in Geometry where o.material == theMaterials[i] collect o)
obj_list_vis = (for o in obj_list where not o.isHidden collect o)
if obj_list.count == 0 do continue
if obj_list_vis.count == 0 do continue
re.addrenderelement (CMasking_Mask())
theelement = re.getrenderelement (re.numrenderelements() - 1 )
theelement.elementName = ("alpha_" + theNames[i] as string)
theelement.nodesMonoOn = true
theelement.nodesMonoIncludeMod= true
theelement.nodesMono = obj_list;
obj_list=#()
--maskEls = append maskEls theelement.elementName
)

/*update  Render Setup Window */
if renderSceneDialog.isOpen()==true do
(
renderSceneDialog.close()
renderSceneDialog.open()
)

/*show  Render Setup Window */
renderSceneDialog.open()

/* close UI */
try
(
closeRolloutFloater rofWireColors
) catch()

)
/*
on deleteAllMonoMasksButton pressed do
(
)*/

)
/* prevent the user from opening more than one dialog at a time */
rollout miscRollout "Toolbox" width:340 height:260
(
label lbl1 "Select objects by mat" pos:[15,5] width:200 height:16
dropDownList matsDropDownList items:theNames
on matsDropDownList selected itm do
     select (for o in Geometry where o.material == theMaterials[itm] collect o)

label lbl2 "Set different path for render elements" pos:[15,55] width:200 height:16 enabled:false
editText edt1 "" pos:[10,75] width:200 height:25 enabled:false
button btn1 "Change path" pos:[220,75] width:85 height:25
enabled:false

label lbl3 "Set different file format for render elements" pos:[15,110] width:250 height:16 enabled:false
    dropdownList ddl_file_ext "" pos:[12,125] width:110 height:40 items:#(".avi", ".bmp", ".cin", ".eps", ".ps", ".exr", ".fxr", ".hdr", ".pic", ".jpg", ".png", ".rgb", ".rla", ".rpf", ".tga", ".tif", ".dds")enabled:false
)

rofWireColors = newRolloutFloater "Corona Mask Manager" 350 500
addRollout wireColorByMatRollout rofWireColors
addRollout monoMasksRollout rofWireColors
addRollout miscRollout rofWireColors


)

« Last Edit: 2020-04-18, 13:17:39 by cjwidd »

2020-04-18, 13:33:32
Reply #4

tallbox

  • Active Users
  • **
  • Posts: 139
  • George Nicola
    • View Profile
    • Architectural Visualizations | TALLBOX
And what is the result?
Architectural Visualizations / Deep work practitioner
https://www.tallboxdesign.com

2020-04-18, 15:03:03
Reply #5

niljut

  • Active Users
  • **
  • Posts: 16
    • View Profile
There are almost always numerous ways to improve scripts, but as long as it works as intended and is not unreasonably slow it's usually best to let it be. I was almost tempted to rewrite the entire script, but it wouldn't actually accomplish anything meaningful. :-)

If you're curious about optimizing the part you added, all you really need to check for is if there is at least one non hidden item with the material. Something like this:

Code: [Select]
for i=1 to theMaterials.count do
(
obj_list = (for o in Geometry where o.material == theMaterials[i] collect o)

if obj_list.count == 0 do continue

local hidden = true
for obj in obj_list while hidden == true do hidden = obj.isHidden
if hidden == true do continue

re.addrenderelement (CMasking_Mask())
theelement = re.getrenderelement (re.numrenderelements() - 1 )
theelement.elementName = ("alpha_" + theNames[i] as string)
theelement.nodesMonoOn = true
theelement.nodesMonoIncludeMod= true
theelement.nodesMono = obj_list;
obj_list=#()
--maskEls = append maskEls theelement.elementName
)

causes it to break out of the for loop the moment it finds a visible item with the material.