[Closed] Material Lister Script
/edit
Download the latest version of this script here :-
http://www.reformstudios.com/03-resources/MatLister/VRayMatList_0_42.ms
/edit
I’m trying to write a material lister macroscript at the moment. Its my first serious venture into the world of maxscript… so it may be beyond my skills.
Anyway, I’ve managed to rip out alot of code from the light lister script, and have got as far as getting the basic structure together. I’ve reached a bit of a brick wall trying to fix a bug that stops the labels from getting added to the rollout.
Can anyone have a look and see if they can see what the problem is?
Whats weird is that the lightlister script calls the function ‘writeTitle’… when I do the same in my script it doesnt work… but adding () to the function call works… but creates another problem when it attempts to add the labels/controllers.
Any help appreciated ! :)
---------------------------------------------------------------------------
--MATERIAL LISTER
--VRayMatList_0_5.ms--Beta 0.10
--Started 21.02.06
--Code By Patrick Macdonald
--mail@reformstudios.com
---------------------------------------------------------------------------
--SHORT DESCRIPTION:
--Listing of all scene materials with control over all material properties.
---------------------------------------------------------------------------
---------------------------------------------------------------------------
--Notes
--------
--0.3 Limited to VrayMtl class materials.
macroScript Material_List
enabledIn:#("max", "viz", "vizr") --pfb: 2003.12.12 added product switch
category:"Medit"
internalcategory:"Lights and Cameras"
ButtonText:"Material Lister..."
tooltip:"Material Lister..."
Icon:#("Lights",7)
-- SilentErrors:(Debug != True)
(
struct MatListerStruct (vrayMatRC, vrayMatList, MatInspectorSetup, \
CreateMatRollout, MatInspectorFloater, MatInspectorListRollout, \
materialsList, DeleCallback, MLUndoStr, DeleteCallback, \
count, lbcount, matIndex, totalMatCount, getMatProp, setMatProp, enableRefreshBtn, \
LineOffset, disableUIElements, UIControlList, enableUIElements, CreateMatRollout, \
yOffset, LineOffset )
global MLister, MListerYOffset
MLister = MatListerStruct()
-- Strings for localisation
MLister.MLUndoStr = "MaterialLister"
local dialogUp = false
-- End Strings
-- Position to help localisation
MListerYOffset = 0
MLister.yOffset = MListerYOffset
MLister.LineOffset = 0
------------------------------
-------- Globals -------------
------------------------------
------------------------------
----- useful functions -------
------------------------------
fn subtractFromArray myArray mySub =
(
tmpArray = #()
for i in myArray do append tmpArray i
for i in mySub do
(
itemNo = finditem tmpArray i
local newArray = #()
if itemNo != 0 do
(
for j in 1 to (itemNo-1) do append newArray tmpArray[j]
for j in (itemNo+1) to tmpArray.count do append newArray tmpArray[j]
tmpArray = newArray
)
)
tmpArray
)
fn copyArray array1 = for i in array1 collect i
fn SortNodeArrayByName myArray =
(
qsort myArray (fn myname v1 v2 = (if v1.name < v2.name then 0 else 1))
myArray
)
fn disableUIElements array1 = for i in array1 do execute ("maxLightsRollout." + i as string + ".enabled = false")
MLister.disableUIElements = disableUIElements
fn enableRefreshBtn materialobj =
(
if (MLister.GetMatProp materialObj #useGlobalShadowSettings) == true do
(
MLister.MatInspectorSetup.BtnReload.Checked = true
)
)
MLister.enableRefreshBtn = enableRefreshBtn
fn getMatProp obj prop =
(
if (isProperty obj prop) and not (isProperty obj #delegate) then
getProperty obj prop
else
if isProperty obj #delegate then
if isProperty obj.delegate prop then
getProperty obj.delegate prop
else undefined
else undefined
)
MLister.getMatProp = getMatProp
fn setMatProp obj prop val =
(
if (isProperty obj prop) and not (isProperty obj #delegate) then
setProperty obj prop val
else
if isProperty obj #delegate then
if isProperty obj.delegate prop then
setProperty obj.delegate prop val
else undefined
else undefined
)
MLister.setMatProp = setMatProp
------------------------------
----- Local variables --------
------------------------------
--topspace = 0
--spacer = 45
vrayMats = getclassinstances VrayMtl
MLister.vraymatlist = getclassinstances VrayMtl
--cnt = vrayMats.count
------------------------------
----- main function ---------
------------------------------
fn CreateMatRollout myCollection selection:false =
(
local CreateMatRollout
-------------------------------------------------------
--------------------- Class Definitions----------------
-------------------------------------------------------
-------------------------------------------------------
--------------------- Scene Parser --------------------
-------------------------------------------------------
SceneMats = MyCollection as array
SceneVrayMats = #()
-------------------------------------------------------
--------------------- Scene Parser --------------------
-------------------------------------------------------
tmpParser = #( \
tmpsceneVrayMats = copyArray sceneMats \
)
ListParser = #( \
MLister.vrayMatList = vraymats \
)
for i in 1 to tmpParser.count do
(
/* while tmpParser[i].count > 0 do
(
) */ --end While loop
) --end i loop
MLister.totalMatCount = MLister.vrayMatList
-------------------------------------------------------
---------- BuildControls and rollouts------------------
-------------------------------------------------------
MLister.totalMatCount = getclassinstances VrayMtl
MLister.vrayMatRC = rolloutCreator "vrayMatsRollout" "Materials"
MLister.vrayMatRC.begin()
MLister.vrayMatRC.addText "fn clearCheckButtons = for i in MLister.MatInspectorListRollout.controls do if classof i == checkButtonControl do if i.checked do i.checked = false
"
MLister.count = 1
MLister.lbCount = 1
MLister.MatIndex = #()
MLister.UIControlList = #(#(), #())
-------------------------------------------------------
---------- Routine to add Column Headings -------------
-------------------------------------------------------
fn WriteTitle =
(
local lbName
fn lbName =
(
if MLister.lbcount == undefined do MLister.lbCount = 1
MLister.lbcount += 1
("LB" + MLister.lbCount as string) as name
) -- end function lbName
local labelOffset = -3
--MLister.vrayMatRC.addControl #label (lbname()) "Name" paramStr:(" align:#left offset:[28," + (-3 + MLister.yOffset + MLister.LineOffset) as string + "]")
--MLister.vrayMatRC.addControl #label (lbname()) "Dif." paramStr:(" align:#left offset:[182,"+ (-18 + LLister.yOffset) as string + "]")
--MLister.vrayMatRC.addControl #label (lbName()) "Reflect." paramStr:(" align:#left offset:[240,"+ (-18 + LLister.yOffset) as string + "]")
--------- Why do these not appear ? -----------------
MLister.vrayMatRC.addControl #checkButton (lbName()) "" paramStr:(" pos:[5,25] width:10 height:10")
MLister.vrayMatRC.addControl #label (lbName()) "Name:" paramStr:(" pos:[29,5] width:40 height:15")
MLister.vrayMatRC.addControl #label (lbName()) "Dif." paramStr:(" pos:[111,5] width:40 height:15")
MLister.vrayMatRC.addControl #label (lblName()) "Refl." paramStr:(" pos:[153,5] width:40 height:15")
MLister.vrayMatRC.addControl #editText (lbName()) "" paramStr:(" text:\"text\" pos:[16,22] width:80 height:15")
MLister.vrayMatRC.addControl #colorPicker (lbName()) "" paramStr:(" pos:[104,24] width:15 height:15 fieldWidth:15")
)
------------ end fn writetitle -----------------
-------------------------------------------------------
---------- routine to add material controls -----------
-------------------------------------------------------
fn CreateControls =
(
MLister.vrayMatRC.addControl #button #myButton "My Button"
append MLister.UIControlList[2][LLister.Count] (("LightSel" + MLister.count as string) as name)
MLister.UIControlList[1][MLister.count] = MLister.LightIndex[MLister.count][1]
)
if Mlister.vrayMatList.count > 0 do
(
writetitle
for x in 1 to Mlister.vrayMatList.count do
(
append MLister.MatIndex Mlister.vrayMatList[x]
createControls
MLister.count += 1
)
)
----------- end fn create controls --------------
local CanAddControls = true
local MatCountLimit = 150
-- Callback handlers
MLister.vrayMatRC.addHandler "vraymatsrollout" #'open' filter:off codeStr:("MLister.DeleteCallback = when MLister.UIControlList[1] deleted obj do" + \
"
(
local foundme = findItem MLister.UIControllist[1] obj
" + \
"if foundMe > 0 do
(
" + \
"MLister.disableUIElements MLister.UIControlList[2][foundMe]
)
)")
MLister.vrayMatRC.addHandler "vrayMatsRollout" #'close' filter:off \
codeStr:"DeleteChangeHandler MLister.DeleteCallback"
MLister.vrayMatRC.end()
)-- end function CreateMatRollout
MLister.CreateMatRollout = CreateMatRollout
local matFilterTypes
matFilterTypes = #("All", "Vray", "VrayLightMtl", "VrayMtlWrapper", "Standard", "Composite", "MultiMaterial")
------- MAT INSPECTOR SETUP ------------
MLister.MatInspectorSetup =
(
local MatInspectorSetup
rollout MatInspectorSetup "Configuration" -- Localize
(
label lab1 "Filter:" pos:[5,0]
dropdownlist matFilter items:matFilterTypes width:80 pos:[0,13]
on matInspectorSetup close do
(
callbacks.removeScripts id:#MListerRollout
dialogUp = false
updateToolbarButtons()
)
on MatInspectorSetup open do
(
try(removerollout MLister.MatInspectorListRollout MLister.MatInspectorFloater) catch()
-------- MAT INSPECTOR LIST ROLLOUT
MLister.MatInspectorListRollout = MLister.CreateMatRollout (vrayMats as array)
if MLister.MatInspectorListRollout != undefined do
addRollout MLister.MatInspectorListRollout MLister.MatInspectorFloater
MLister.vrayMatRC = undefined
-- Callbacks to remove Floater
callBacks.AddScript #systemPreReset "CloseRolloutFloater MLister.MatInspectorFloater" id:#MListerRollout -- do not localize
callBacks.AddScript #systemPreNew "CloseRolloutFloater MLister.MatInspectorFloater" id:#MListerRollout -- do not localize
callBacks.AddScript #filePreOpen "CloseRolloutFloater MLister.MatInspectorFloater" id:#MListerRollout -- do not localize
dialogUp = true
updateToolbarButtons()
)
) --end of matinspector rollout
) -- end of mat inspector setup
on execute do
(
local dialogPos, dialogSize
dialogPos = [200,300]
dialogSize = [800,300]
try(closeRolloutFloater MLister.MatInspectorFloater) catch()
MLister.MatInspectorFloater = newRolloutFloater "Material Lister" 500 500 100 100
addRollout MLister.MatInspectorSetup MLister.MatInspectorFloater
dialogUp = true
)
on closeDialogs do
(
try(closeRolloutFloater MLister.MatInspectorFloater) catch( print "error in Material Lister" )
dialogUp = False
)
on isChecked return
(
dialogUp
)
)--end macroscript
When a function is called with no arguments you must write the ()
example:
– fn with no arguments definition:
fn Myprint1=(print “something”)
– fn call:
MyPrint1()
– fn with arguments definition
fn MyPrint2 str = (print str)
– fn call:
Myprint2 “Something” – no ()
so you should write :
writeTitle()
also there is a typo :(lblName()) should be (lbName())
for the rest I leave it up to you !
thanks dude. Ah… jesus… that spello has been messing my up for ages! Amazing what a fresh pair of eyes can spot. Thanks!
As for the functions. I thought you only got away without () if you were returning values…
I’ll need to pass some values to the function anyway, so I’ll add them in and see if it sorts it out.
At last, progress is being made… the rollout seems to be working ok now, and I’ve got the diffuse channel link working. Now to get all the properties into the interface and linked up.
I was wondering about the best way to filter which parameters are visible. If anyone has any suggestion as to how the parameters are displayed, please let me know. (ie mode-1 would be the standard colours and spinners, mode-2 would be the map channels)
One other quick question. In the Light lister macro, calls to light parameters are done using :-
LLister.LightIndex[LLister.count][1].property
but for some reason this doesn’t work with the MLister variables I have. What is the [1] refering to? I have adjusted the code to MLister.MatIndex[MLister.count].name which seems to work… but perhaps this will lead to problems further down the line (maybe when animating parameters? )
Thanks again for any help!
Latest code:-
---------------------------------------------------------------------------
--MATERIAL LISTER
--VRayMatList_0_5.ms--Beta 0.12
--Started 21.02.06
--Code By Patrick Macdonald
--mail@reformstudios.com
---------------------------------------------------------------------------
--SHORT DESCRIPTION:
--Listing of all scene materials with control over all material properties.
---------------------------------------------------------------------------
---------------------------------------------------------------------------
--Notes
--------
--0.3 Limited to VrayMtl class materials.
macroScript Material_List
enabledIn:#("max", "viz", "vizr") --pfb: 2003.12.12 added product switch
category:"Medit"
internalcategory:"Lights and Cameras"
ButtonText:"Material Lister..."
tooltip:"Material Lister..."
Icon:#("Lights",7)
-- SilentErrors:(Debug != True)
(
clearListener()
struct MatListerStruct (vrayMatRC, vrayMatList, MatInspectorSetup, \
CreateMatRollout, MatInspectorFloater, MatInspectorListRollout, \
materialsList, DeleCallback, MLUndoStr, DeleteCallback, \
count, lbCount, matIndex, totalMatCount, getMatProp, setMatProp, enableRefreshBtn, \
LineOffset, disableUIElements, UIControlList, enableUIElements, \
yOffset, LineOffset )
global MLister, MListerYOffset
MLister = MatListerStruct()
-- Strings for localisation
MLister.MLUndoStr = "MaterialLister"
local dialogUp = false
-- End Strings
-- Position to help localisation
MListerYOffset = 0
MLister.yOffset = MListerYOffset
MLister.LineOffset = 0
------------------------------
-------- Globals -------------
------------------------------
------------------------------
----- useful functions -------
------------------------------
fn subtractFromArray myArray mySub =
(
tmpArray = #()
for i in myArray do append tmpArray i
for i in mySub do
(
itemNo = finditem tmpArray i
local newArray = #()
if itemNo != 0 do
(
for j in 1 to (itemNo-1) do append newArray tmpArray[j]
for j in (itemNo+1) to tmpArray.count do append newArray tmpArray[j]
tmpArray = newArray
)
)
tmpArray
)
fn copyArray array1 = for i in array1 collect i
fn SortNodeArrayByName myArray =
(
qsort myArray (fn myname v1 v2 = (if v1.name < v2.name then 0 else 1))
myArray
)
fn disableUIElements array1 = for i in array1 do execute ("maxLightsRollout." + i as string + ".enabled = false")
MLister.disableUIElements = disableUIElements
fn enableRefreshBtn materialobj =
(
if (MLister.GetMatProp materialObj #useGlobalShadowSettings) == true do
(
MLister.MatInspectorSetup.BtnReload.Checked = true
)
)
MLister.enableRefreshBtn = enableRefreshBtn
fn getMatProp obj prop =
(
if (isProperty obj prop) and not (isProperty obj #delegate) then
getProperty obj prop
else
if isProperty obj #delegate then
if isProperty obj.delegate prop then
getProperty obj.delegate prop
else undefined
else undefined
)
MLister.getMatProp = getMatProp
fn setMatProp obj prop val =
(
if (isProperty obj prop) and not (isProperty obj #delegate) then
setProperty obj prop val
else
if isProperty obj #delegate then
if isProperty obj.delegate prop then
setProperty obj.delegate prop val
else undefined
else undefined
)
MLister.setMatProp = setMatProp
------------------------------
----- Local variables --------
------------------------------
--topspace = 0
--spacer = 45
vrayMats = getclassinstances VrayMtl
MLister.vraymatlist = getclassinstances VrayMtl
--cnt = vrayMats.count
------------------------------
----- main function ---------
------------------------------
local CreateMatRollout
fn CreateMatRollout myCollection =
(
-------------------------------------------------------
--------------------- Class Definitions----------------
-------------------------------------------------------
-------------------------------------------------------
--------------------- Scene Parser --------------------
-------------------------------------------------------
SceneMats = MyCollection as array
SceneVrayMats = #()
-------------------------------------------------------
--------------------- Scene Parser --------------------
-------------------------------------------------------
tmpParser = #( \
tmpsceneVrayMats = copyArray sceneMats \
)
ListParser = #( \
MLister.vrayMatList = vraymats \
)
for i in 1 to tmpParser.count do
(
) --end i loop
MLister.totalMatCount = MLister.vrayMatList
-------------------------------------------------------
---------- BuildControls and rollouts------------------
-------------------------------------------------------
MLister.totalMatCount = getclassinstances VrayMtl
MLister.vrayMatRC = rolloutCreator "vrayMatsRollout" "Materials"
MLister.vrayMatRC.begin()
-- MLister.vrayMatRC.addText "fn clearCheckButtons = for i in MLister.MatInspectorListRollout.controls do if classof i == checkButtonControl do if i.checked do i.checked = false
"
MLister.count = 1
MLister.lbCount = 1
MLister.MatIndex = #()
MLister.UIControlList = #(#(), #())
-------------------------------------------------------
---------- Routine to add Column Headings -------------
-------------------------------------------------------
fn WriteTitle =
(
local lbName
fn lbName =
(
if MLister.lbCount == undefined do MLister.lbCount = 1
MLister.lbCount += 1
("LB" + MLister.lbCount as string) as name
) -- end function lbName
local labelOffset = -3
--MLister.vrayMatRC.addControl #label (lbname()) "Name" paramStr:(" align:#left offset:[28," + (-3 + MLister.yOffset + MLister.LineOffset) as string + "]")
--MLister.vrayMatRC.addControl #label (lbname()) "Dif." paramStr:(" align:#left offset:[182,"+ (-18 + LLister.yOffset) as string + "]")
--MLister.vrayMatRC.addControl #label (lbName()) "Reflect." paramStr:(" align:#left offset:[240,"+ (-18 + LLister.yOffset) as string + "]")
--------- Why do these not appear ? -----------------
MLister.vrayMatRC.addControl #label (lbName()) "Name:" paramStr:(" pos:[29," + (0 + MLister.yOffset + MLister.LineOffset) as string + "] width:40 height:15")
MLister.vrayMatRC.addControl #label (lbName()) "Dif." paramStr:(" pos:[111," + (0 + MLister.yOffset + MLister.LineOffset) as string + "] width:40 height:15")
MLister.vrayMatRC.addControl #label (lbName()) "Refl." paramStr:(" pos:[153," + (0 + MLister.yOffset + MLister.LineOffset) as string + "] width:40 height:15")
)
------------ end fn writetitle -----------------
-------------------------------------------------------
---------- routine to add material controls -----------
-------------------------------------------------------
fn CreateControls =
(
local lbName
fn lbName =
(
if MLister.lbCount == undefined do MLister.lbCount = 1
MLister.lbCount += 1
("LB" + MLister.lbCount as string) as name
) -- end function lbName
local isMatSelected = false
--for i in Mlister.MatIndex[MLister.count] where (not isMatSelected) do isMatSelected = i.isSelected
MLister.UIControlList[1][MLister.count] = MLister.MatIndex[MLister.count][1]
MLister.UIControlList[2][MLister.count] = #()
MLister.vrayMatRC.addControl #checkButton (("MatSel" + MLister.count as string) as name) "" \
paramStr:("checked:" +(isMatSelected as string) + " offset:[-5,"+ (-2+ MLister.yOffset + MLister.LineOffset) as string + "] align:#left" + \
" width:10 height:20 ")
MLister.vrayMatRC.addControl #editText (("MatName" + MLister.count as string) as name) "" \
paramStr:(" text:\"" + MLister.matindex[MLister.count].name as string + "\" offset:[5," \
+ (-25 + MLister.yOffset + MLister.LineOffset) as string + "] align:#left width:90 height:20 ")
MLister.vrayMatRC.addControl #colorPicker (("MatDiffCol" + MLister.count as string) as name) "" \
paramStr:(" offset:[95," + (-23 + MLister.yOffset + MLister.LineOffset) as string + \
"] color:" + (MLister.getMatProp MLister.MatIndex[MLister.count] #diffuse) as string + \
" width:15 height:15 fieldWidth:15")
MLister.vrayMatRC.addHandler (("MatDiffCol" + MLister.count as string) as name) #'changed val' filter:on \
codeStr:("MLister.setMatProp MLister.MatIndex[" + MLister.count as string + "] #diffuse val")
--MLister.vrayMatRC.addControl #button #myButton "My Button"
append MLister.UIControlList[2][MLister.Count] (("MatSel" + MLister.count as string) as name)
MLister.UIControlList[1][MLister.count] = MLister.MatIndex[MLister.count][1]
)
if Mlister.vrayMatList.count > 0 do
(
writetitle ()
for x in 1 to Mlister.vrayMatList.count do
(
append MLister.MatIndex Mlister.vrayMatList[x]
createControls ()
MLister.count += 1
)
)
----------- end fn create controls --------------
local CanAddControls = true
local MatCountLimit = 150
-- Callback handlers
MLister.vrayMatRC.addHandler "vraymatsrollout" #'open' filter:off codeStr:("MLister.DeleteCallback = when MLister.UIControlList[1] deleted obj do" + \
"
(
local foundme = findItem MLister.UIControllist[1] obj
" + \
"if foundMe > 0 do
(
" + \
"MLister.disableUIElements MLister.UIControlList[2][foundMe]
)
)")
MLister.vrayMatRC.addHandler "vrayMatsRollout" #'close' filter:off \
codeStr:"DeleteChangeHandler MLister.DeleteCallback"
MLister.vrayMatRC.end()
)-- end function CreateMatRollout
MLister.CreateMatRollout = CreateMatRollout
local matFilterTypes
matFilterTypes = #("All", "Vray", "VrayLightMtl", "VrayMtlWrapper", "Standard", "Composite", "MultiMaterial")
------- MAT INSPECTOR SETUP ------------
MLister.MatInspectorSetup =
(
local MatInspectorSetup
rollout MatInspectorSetup "Configuration" -- Localize
(
label lab1 "Filter:" pos:[5,0]
dropdownlist matFilter items:matFilterTypes width:80 pos:[0,13]
on btnReload changed state do
(
roloutSelector.changed rolloutSelector.state
btnReload.checked = false
)
on matInspectorSetup close do
(
callbacks.removeScripts id:#MListerRollout
dialogUp = false
updateToolbarButtons()
)
on MatInspectorSetup open do
(
local laststate = 5
if laststate < 4 do rolloutSelector.changed = laststate
try (removerollout MLister.MatInspectorListRollout MLister.MatInspectorFloater) catch()
MLister.MatInspectorListRollout = MLister.CreateMatRollout (vrayMats as array)
if MLister.MatInspectorListRollout != undefined do
addRollout MLister.MatInspectorListRollout MLister.MatInspectorFloater
MLister.vrayMatRC = undefined
--MLister.vrayMatRC = undefined
--Callbacks to remove Floater
--callBacks.AddScript #systemPreReset "CloseRolloutFloater MLister.MatInspectorFloater" id:#MListerRollout -- do not localize
--callBacks.AddScript #systemPreNew "CloseRolloutFloater MLister.MatInspectorFloater" id:#MListerRollout -- do not localize
--callBacks.AddScript #filePreOpen "CloseRolloutFloater MLister.MatInspectorFloater" id:#MListerRollout -- do not localize
dialogUp = true
--updateToolbarButtons()
)
) --end of matinspector rollout
) -- end of mat inspector setup
on execute do
(
local dialogPos, dialogSize
dialogPos = [200,300]
dialogSize = [800,300]
try(closeRolloutFloater MLister.MatInspectorFloater) catch()
MLister.MatInspectorFloater = newRolloutFloater "Material Lister" 500 500 100 100
addRollout MLister.MatInspectorSetup MLister.MatInspectorFloater
dialogUp = true
)
on closeDialogs do
(
try(closeRolloutFloater MLister.MatInspectorFloater) catch( print "error in Material Lister" )
dialogUp = False
)
on isChecked return
(
dialogUp
)
)--end macroscript
another update…
Controls to make the maps visible added.
---------------------------------------------------------------------------
--MATERIAL LISTER
--VRayMatList_0_5.ms--Beta 0.13
--Started 21.02.06
--Code By Patrick Macdonald
--mail@reformstudios.com
---------------------------------------------------------------------------
--SHORT DESCRIPTION:
--Listing of all scene materials with control over all material properties.
---------------------------------------------------------------------------
---------------------------------------------------------------------------
--Notes
--------
--0.3 Limited to VrayMtl class materials.
macroScript Material_List
enabledIn:#("max", "viz", "vizr") --pfb: 2003.12.12 added product switch
category:"Medit"
internalcategory:"Lights and Cameras"
ButtonText:"Material Lister..."
tooltip:"Material Lister..."
Icon:#("Lights",7)
-- SilentErrors:(Debug != True)
(
clearListener()
struct MatListerStruct (vrayMatRC, vrayMatList, MatInspectorSetup, \
CreateMatRollout, MatInspectorFloater, MatInspectorListRollout, \
materialsList, DeleCallback, MLUndoStr, DeleteCallback, \
count, lbCount, matIndex, totalMatCount, getMatProp, setMatProp, enableRefreshBtn, \
LineOffset, disableUIElements, UIControlList, enableUIElements, \
yOffset, LineOffset, showTexMap, showSpin )
global MLister, MListerYOffset
MLister = MatListerStruct()
-- Strings for localisation
MLister.MLUndoStr = "MaterialLister"
local dialogUp = false
-- End Strings
-- Position to help localisation
MListerYOffset = 2
MLister.yOffset = MListerYOffset
MLister.LineOffset = 0
MLister.showTexMap = 0
------------------------------
-------- Globals -------------
------------------------------
------------------------------
----- useful functions -------
------------------------------
fn subtractFromArray myArray mySub =
(
tmpArray = #()
for i in myArray do append tmpArray i
for i in mySub do
(
itemNo = finditem tmpArray i
local newArray = #()
if itemNo != 0 do
(
for j in 1 to (itemNo-1) do append newArray tmpArray[j]
for j in (itemNo+1) to tmpArray.count do append newArray tmpArray[j]
tmpArray = newArray
)
)
tmpArray
)
fn copyArray array1 = for i in array1 collect i
fn SortNodeArrayByName myArray =
(
qsort myArray (fn myname v1 v2 = (if v1.name < v2.name then 0 else 1))
myArray
)
fn disableUIElements array1 = for i in array1 do execute ("maxLightsRollout." + i as string + ".enabled = false")
MLister.disableUIElements = disableUIElements
fn enableRefreshBtn materialobj =
(
if (MLister.GetMatProp materialObj #useGlobalShadowSettings) == true do
(
MLister.MatInspectorSetup.BtnReload.Checked = true
)
)
MLister.enableRefreshBtn = enableRefreshBtn
fn getMatProp obj prop =
(
if (isProperty obj prop) and not (isProperty obj #delegate) then
getProperty obj prop
else
if isProperty obj #delegate then
if isProperty obj.delegate prop then
getProperty obj.delegate prop
else undefined
else undefined
)
MLister.getMatProp = getMatProp
fn setMatProp obj prop val =
(
if (isProperty obj prop) and not (isProperty obj #delegate) then
setProperty obj prop val
else
if isProperty obj #delegate then
if isProperty obj.delegate prop then
setProperty obj.delegate prop val
else undefined
else undefined
)
MLister.setMatProp = setMatProp
------------------------------
----- Local variables --------
------------------------------
--topspace = 0
--spacer = 45
vrayMats = getclassinstances VrayMtl
MLister.vraymatlist = getclassinstances VrayMtl
--cnt = vrayMats.count
------------------------------
----- main function ---------
------------------------------
local CreateMatRollout
fn CreateMatRollout myCollection =
(
-------------------------------------------------------
--------------------- Class Definitions----------------
-------------------------------------------------------
-------------------------------------------------------
--------------------- Scene Parser --------------------
-------------------------------------------------------
SceneMats = MyCollection as array
SceneVrayMats = #()
-------------------------------------------------------
--------------------- Scene Parser --------------------
-------------------------------------------------------
tmpParser = #( \
tmpsceneVrayMats = copyArray sceneMats \
)
ListParser = #( \
MLister.vrayMatList = vraymats \
)
for i in 1 to tmpParser.count do
(
) --end i loop
MLister.totalMatCount = MLister.vrayMatList
-------------------------------------------------------
---------- BuildControls and rollouts------------------
-------------------------------------------------------
MLister.totalMatCount = getclassinstances VrayMtl
MLister.vrayMatRC = rolloutCreator "vrayMatsRollout" "Materials"
MLister.vrayMatRC.begin()
-- MLister.vrayMatRC.addText "fn clearCheckButtons = for i in MLister.MatInspectorListRollout.controls do if classof i == checkButtonControl do if i.checked do i.checked = false
"
MLister.count = 1
MLister.lbCount = 1
MLister.MatIndex = #()
MLister.UIControlList = #(#(), #())
-------------------------------------------------------
---------- Routine to add Column Headings -------------
-------------------------------------------------------
fn WriteTitle =
(
local lbName
fn lbName =
(
if MLister.lbCount == undefined do MLister.lbCount = 1
MLister.lbCount += 1
("LB" + MLister.lbCount as string) as name
) -- end function lbName
local labelOffset = -3
--MLister.vrayMatRC.addControl #label (lbname()) "Name" paramStr:(" align:#left offset:[28," + (-3 + MLister.yOffset + MLister.LineOffset) as string + "]")
--MLister.vrayMatRC.addControl #label (lbname()) "Dif." paramStr:(" align:#left offset:[182,"+ (-18 + LLister.yOffset) as string + "]")
--MLister.vrayMatRC.addControl #label (lbName()) "Reflect." paramStr:(" align:#left offset:[240,"+ (-18 + LLister.yOffset) as string + "]")
--------- Why do these not appear ? -----------------
MLister.vrayMatRC.addControl #label (lbName()) "Name:" paramStr:(" pos:[29," + (0 + MLister.yOffset + MLister.LineOffset) as string + "] width:40 height:15")
MLister.vrayMatRC.addControl #label (lbName()) "Dif." paramStr:(" pos:[111," + (0 + MLister.yOffset + MLister.LineOffset) as string + "] width:40 height:15")
MLister.vrayMatRC.addControl #label (lbName()) "Refl." paramStr:(" pos:[143," + (0 + MLister.yOffset + MLister.LineOffset) as string + "] width:40 height:15")
)
------------ end fn writetitle -----------------
-------------------------------------------------------
---------- routine to add material controls -----------
-------------------------------------------------------
fn CreateControls showTexMap:false =
(
local lbName
fn lbName =
(
if MLister.lbCount == undefined do MLister.lbCount = 1
MLister.lbCount += 1
("LB" + MLister.lbCount as string) as name
) -- end function lbName
local isUsingEdittextOffset = 0, editTextSize = 75
local isMatSelected = false
--for i in Mlister.MatIndex[MLister.count] where (not isMatSelected) do isMatSelected = i.isSelected
MLister.UIControlList[1][MLister.count] = MLister.MatIndex[MLister.count][1]
MLister.UIControlList[2][MLister.count] = #()
-- Select Material Toggle
MLister.vrayMatRC.addControl #checkButton (("MatSel" + MLister.count as string) as name) "" \
paramStr:("checked:" +(isMatSelected as string) + " offset:[-5,"+ (-2+ MLister.yOffset + MLister.LineOffset) as string + "] align:#left" + \
" width:10 height:20 ")
-- Material Name Text field
MLister.vrayMatRC.addControl #editText (("MatName" + MLister.count as string) as name) "" \
paramStr:(" text:\"" + MLister.matindex[MLister.count].name + "\" offset:[5," \
+ (-25 + MLister.yOffset + MLister.LineOffset) as string + "] align:#left width:90 height:16 ")
MLister.vrayMatRC.addHandler (("MatName" + MLister.count as string) as name) #'changed txt' filter:on \
codeStr:("MLister.MatIndex[" + MLister.count as string + "].name = txt")
-- Diffuse Colour Picker
MLister.vrayMatRC.addControl #colorPicker (("MatDiffCol" + MLister.count as string) as name) "" \
paramStr:(" offset:[95," + (-22 + MLister.yOffset + MLister.LineOffset) as string + \
"] color:" + (MLister.getMatProp MLister.MatIndex[MLister.count] #diffuse) as string + \
" width:15 height:15 fieldWidth:15")
MLister.vrayMatRC.addHandler (("MatDiffCol" + MLister.count as string) as name) #'changed val' filter:on \
codeStr:("MLister.setMatProp MLister.MatIndex[" + MLister.count as string + "] #diffuse val")
-- Diffuse Colour Material
if showTexMap then
(
MLister.vrayMatRC.addControl #mapbutton (("MatDiffMap" + MLister.count as string) as name) ((MLister.MatIndex[MLister.count].texmap_diffuse) as string) \
paramStr:("tooltip:\"Select Diffuse Map\" align:#left height:15 width:80 offset:[112," + (-22 + MLister.yOffset + MLister.LineOffset) as string + \
"]")
MLister.vrayMatRC.addHandler (("MatDiffMap" + MLister.count as string) as name) #'picked texmap' filter:on \
codeStr:("MLister.MatIndex[" + MLister.count as string + "].texmap_diffuse texmap
" + ("MatDiffMap" + MLister.count as string) + ".text = classof texmap as string ")
)
else
(
MLister.vrayMatRC.addControl #mapbutton (("MatDiffMap" + MLister.count as string) as name) "" \
paramStr:("tooltip:\"Select Diffuse Map\" align:#left height:15 width:10 offset:[112," + (-22 + MLister.yOffset + MLister.LineOffset) as string + \
"]")
MLister.vrayMatRC.addHandler (("MatDiffMap" + MLister.count as string) as name) #'picked texmap' filter:on \
codeStr:("MLister.MatIndex[" + MLister.count as string + "].texmap_diffuse texmap
" + ("MatDiffMap" + MLister.count as string) + ".text = classof texmap as string ")
)
-- Reflection Colour Picker
MLister.vrayMatRC.addControl #colorPicker (("MatReflCol" + MLister.count as string) as name) "" \
paramStr:(" offset:[" + (125+(80*MLister.showtexmap)) as string + "," + (-22 + MLister.yOffset + MLister.LineOffset) as string + \
"] color:" + (MLister.getMatProp MLister.MatIndex[MLister.count] #reflection) as string + \
" width:15 height:15 fieldWidth:15")
MLister.vrayMatRC.addHandler (("MatReflCol" + MLister.count as string) as name) #'changed val' filter:on \
codeStr:("MLister.setMatProp MLister.MatIndex[" + MLister.count as string + "] #reflection val")
-- Reflection Colour Material
if showTexMap then
(
MLister.vrayMatRC.addControl #mapbutton (("MatReflMap" + MLister.count as string) as name) ((MLister.MatIndex[MLister.count].texmap_reflection) as string) \
paramStr:("tooltip:\"Select Reflection Map\" align:#left height:15 width:80 offset:[" + (142+(80*MLister.showtexmap)) as string + "," + (-22 + MLister.yOffset + MLister.LineOffset) as string + \
"]")
MLister.vrayMatRC.addHandler (("MatReflMap" + MLister.count as string) as name) #'picked texmap' filter:on \
codeStr:("MLister.MatIndex[" + MLister.count as string + "].texmap_reflection texmap
" + ("MatReflMap" + MLister.count as string) + ".text = classof texmap as string ")
)
else
(
MLister.vrayMatRC.addControl #mapbutton (("MatReflMap" + MLister.count as string) as name) "" \
paramStr:("tooltip:\"Select Reflection Map\" align:#left height:15 width:10 offset:[142," + (-22 + MLister.yOffset + MLister.LineOffset) as string + \
"]")
MLister.vrayMatRC.addHandler (("MatReflMap" + MLister.count as string) as name) #'picked texmap' filter:on \
codeStr:("MLister.MatIndex[" + MLister.count as string + "].texmap_reflection texmap
" + ("MatReflMap" + MLister.count as string) + ".text = classof texmap as string ")
)
append MLister.UIControlList[2][MLister.Count] (("MatSel" + MLister.count as string) as name)
MLister.UIControlList[1][MLister.count] = MLister.MatIndex[MLister.count][1]
)
if Mlister.vrayMatList.count > 0 do
(
writetitle ()
for x in 1 to Mlister.vrayMatList.count do
(
append MLister.MatIndex Mlister.vrayMatList[x]
if MLister.showTexMap == 1 then createControls showTexMap:true
else createControls showTexMap:false
MLister.count += 1
)
)
----------- end fn create controls --------------
local CanAddControls = true
local MatCountLimit = 150
-- Callback handlers
MLister.vrayMatRC.addHandler "vraymatsrollout" #'open' filter:off codeStr:("MLister.DeleteCallback = when MLister.UIControlList[1] deleted obj do" + \
"
(
local foundme = findItem MLister.UIControllist[1] obj
" + \
"if foundMe > 0 do
(
" + \
"MLister.disableUIElements MLister.UIControlList[2][foundMe]
)
)")
MLister.vrayMatRC.addHandler "vrayMatsRollout" #'close' filter:off \
codeStr:"DeleteChangeHandler MLister.DeleteCallback"
MLister.vrayMatRC.end()
)-- end function CreateMatRollout
MLister.CreateMatRollout = CreateMatRollout
local matFilterTypes
matFilterTypes = #("All", "Vray", "VrayLightMtl", "VrayMtlWrapper", "Standard", "Composite", "MultiMaterial")
------- MAT INSPECTOR SETUP ------------
MLister.MatInspectorSetup =
(
local MatInspectorSetup
rollout MatInspectorSetup "Configuration" -- Localize
(
label lab1 "Filter:" pos:[5,0]
dropdownlist matFilter items:matFilterTypes width:80 pos:[0,13]
label lab2 "View parameters"
checkbutton checkShowMaps "Maps" offset:[-10,0] align:#left
checkbutton checkShowspin "Spinners" offset:[40,-25] align:#left
on checkShowMaps changed state do
(
if state == on
then MLister.showTexMap = 1
else MLister.showTexMap = 0
try (removerollout MLister.MatInspectorListRollout MLister.MatInspectorFloater) catch()
MLister.MatInspectorListRollout = MLister.CreateMatRollout (vrayMats as array)
if MLister.MatInspectorListRollout != undefined do
addRollout MLister.MatInspectorListRollout MLister.MatInspectorFloater
MLister.vrayMatRC = undefined
)
on checkShowSpin changed state do
(
if state == on
then MLister.showSpin = 1
else MLister.showSpin = 0
try (removerollout MLister.MatInspectorListRollout MLister.MatInspectorFloater) catch()
MLister.MatInspectorListRollout = MLister.CreateMatRollout (vrayMats as array)
if MLister.MatInspectorListRollout != undefined do
addRollout MLister.MatInspectorListRollout MLister.MatInspectorFloater
MLister.vrayMatRC = undefined
)
on matInspectorSetup close do
(
callbacks.removeScripts id:#MListerRollout
dialogUp = false
updateToolbarButtons()
)
on MatInspectorSetup open do
(
local laststate = 5
if laststate < 4 do rolloutSelector.changed = laststate
try (removerollout MLister.MatInspectorListRollout MLister.MatInspectorFloater) catch()
MLister.MatInspectorListRollout = MLister.CreateMatRollout (vrayMats as array)
if MLister.MatInspectorListRollout != undefined do
addRollout MLister.MatInspectorListRollout MLister.MatInspectorFloater
MLister.vrayMatRC = undefined
--MLister.vrayMatRC = undefined
--Callbacks to remove Floater
--callBacks.AddScript #systemPreReset "CloseRolloutFloater MLister.MatInspectorFloater" id:#MListerRollout -- do not localize
--callBacks.AddScript #systemPreNew "CloseRolloutFloater MLister.MatInspectorFloater" id:#MListerRollout -- do not localize
--callBacks.AddScript #filePreOpen "CloseRolloutFloater MLister.MatInspectorFloater" id:#MListerRollout -- do not localize
dialogUp = true
--updateToolbarButtons()
)
) --end of matinspector rollout
) -- end of mat inspector setup
on execute do
(
local dialogPos, dialogSize
dialogPos = [200,300]
dialogSize = [800,300]
try(closeRolloutFloater MLister.MatInspectorFloater) catch()
MLister.MatInspectorFloater = newRolloutFloater "Material Lister" 500 500 100 100
addRollout MLister.MatInspectorSetup MLister.MatInspectorFloater
dialogUp = true
)
on closeDialogs do
(
try(closeRolloutFloater MLister.MatInspectorFloater) catch( print "error in Material Lister" )
dialogUp = False
)
on isChecked return
(
dialogUp
)
)--end macroscript
Ok…I have a small question for you maxscript gurus. How do I get my filter function to successfuly select objects with the currently selected material?
Here’s what I have so far.
fn objFilter ob =
(
if (classof ob == GeometryClass) do
(
if (ob.material.name != undefined) do (ob.material.name == MLister.matIndex[MLister.count].name)
)
)
The interface for the material lister is taking shape…
And the full script can be downloaded here.
http://www.reformstudios.com/03-resources/MatLister/VRayMatList_0_15.ms
Another update.
I’ve got the filters working now, so you can pick and choose which material types to list. (although I have’t implimented the display of any materials other than vray mats).
I’ve added buttons beneath each material:
S = Select objects with this material applied (not working… any help appreciated)
A = Apply material to selected objects (not implimented)
E = Edit material in material editor in selected slot.
and for the map slots…
V = View map in viewports.
E = Edit map in material editor in selected slot.
This already feels quite nice to use, even with such limited functionality.
So… no-one has any suggestions ? 🙄
Here’s the latest interface:
I have another slight problem I hope someone can help me with. I have a button to switch off all materials in the viewport of the current material.
MLister.vrayMatRC.addHandler (("ViewMatOff" + MLister.count as string) as name) #'pressed' codeStr:("mat = MLister.vraymatlist[" + MLister.count as string + "]
names = getpropnames mat
for i in names do (
if superclassof mat." + i as string + " == texturemap do showtexturemap mat mat." + i as string + " false)")
which roughly translates as:-
on pressed do
( mat = MLister.vraymatlist[1]
names = getpropnames mat
for i in names do
(
if superclassof mat.i == texturemap do showTextureMap mat mat.i false
)
)
which should… I think… make sure that no materials have their visibility switched on in the viewport…
Unfortunately, it doesn’t work.
They key code is “if superclassof mat.texmap_diffuse == texturemap do showtexturemap mat mat.texmap_diffuse false” … which works when I enter it into the listener… but for some reason, it doesn’t work when in the handler.
Can anyone help me out here?
🙁
Ok… another update.
I’m looking at how best to control the filtration of information. I think I need to provide two options,
Simple :
Commonly used parameters for each material type (as shown in the ‘materials’ rollout in the screengrab) arranged in a fixed layout.
Advanced :
The user can choose to view a specific parameter from a dropdown list for each material type. The user can also choose which material types to view.
I’m sure there’s probably a more straight-forward way to arrange things, but this is the best I have come up with so far. If you have any suggestions… lets hear them!
is there anyway to show the final blend result of the material in the viewport. right now i dont know how to do that. you can display either of the three materials like Diffuse0, Diffuse1 or the alpha but not the end result. It only shows in the render. is it possible to show the final blend in viewport.