[Closed] Problem with Dynamic UI in Macro Script
I’m working on a “Light Lister” type script for materials. I’ve got a basic version working perfectly as a stand-along script but as soon as it enclosed in a macroscript brackets, it starts having problems adding SubRollouts. I am new to this but have been beating my head against a wall for 2-days now and out of ideas to try.
Here is the code:
try destroydialog ::rollLister catch()
fn getSceneMaterials =
(
global aVrayMaterials = getclassinstances vraymtl
global NoVrayMaterials = aVrayMaterials.count
)
fn CreateSubRollouts=
(
global SubRollout1 = rolloutCreator "SubRO1" "Name"
SubRollout1.begin()
if aVrayMaterials != 0 then
(
for i = 1 to NoVrayMaterials do
(
SubRollout1.addcontrol #label ("lName" + i as string) (substituteString (aVrayMaterials[i] as string) ":VRayMtl" "" ) paramStr:("pos:[20," + ( (i-1) * 30 + 5) as string +"]")
SubRollout1.addcontrol #edittext ("etName" + i as string) "" paramStr: ("text:\"\" width:225 pos:[100," + ( (i-1) * 30 + 5) as string +"]")
SubRollout1.addcontrol #spinner ("spRefl" + i as string) #Reflection_Gloss_subdivs paramStr:("type: #integer range:[1,1000,8] fieldwidth:50 scale:1 pos:[350," + ( (i-1) * 30 +5) as string +"]")
)
)
SubRollout1.end()
return (SubRO1)
)
fn soft_refresh =
(
if NoVrayMaterials != 0 then
(
for i = 1 to NoVrayMaterials do
(
--tempname1=(aVrayMaterials[i] as string)
global tempname=(substituteString (aVrayMaterials[i] as string) ":VRayMtl" "" )
--global tempname3="test123"
--print tempname1
--print tempname2
execute ("rollLister.Mat.SubRO1.etName" + i as string +".text = tempname")
execute ("rollLister.Mat.SubRO1.spRefl" + i as string +".value = aVrayMaterials[" + i as string + "].reflection_subdivs")
)
)
)
fn hard_refresh =
(
--need to redefine those variables --
SubRO1 = rollLister.Mat.SubRO1
removeSubRollout rollLister.Mat SubRO1
getSceneMaterials()
CreateSubRollouts()
AddSubRollout rollLister.Mat SubRO1
soft_refresh()
)
getSceneMaterials()
-------main rollout creation---------
global RCmain = rolloutCreator "rollLister" "VRay Materials"
RCmain.begin()
RCmain.addcontrol #subrollout #Mat #Name paramStr:"width:680 height:560"
RCmain.addcontrol #button #btnRefresh "Refresh" paramStr:"width:200"
RCmain.width = 700
RCmain.height = 600
--refresh button-
RCmain.addHandler #btnRefresh #pressed CodeStr: "hard_refresh()"
CreateSubRollouts()
createDialog (RCmain.end())
AddSubRollout rollLister.Mat SubRO1
soft_refresh()
That works fine. As soon as it becomes:
macroScript MatLister
category:“Tools”
buttontext:“ML”
toolTip:“Material Lister”
silentErrors:false
autoUndoEnabled:true
(
–START
previous code
–END
)
…It starts throwing errors at the AddSubRollout rollLister.Mat SubRO1 two lines from the bottom. Once it errors, if you re-evaluate it and relaunch it, it will work then so it is very difficult to trouble shoot because you have to restart MAX each time. I suspect it is a scope issue for the subrollouts but I don’t know how to fix it and after two days of guessing, I’m beginning to run out of options. Please help
are you sure that sub-rollouts is a good user interface solution? what is if the number of materials ‘hundreds’? no search, no sort, no easy scroll…
i would use listview, treelist (devx), or gridview. there are many examples on this forum
Well to be honest, no – I’m not sure. I’m an old artist but new at scripting and I’ve found the best way for me to learn is to just dive right in to a particular workflow problem and try to solve it.
My studio relies heavily on multi-mattes in post-production and going into dozens or more materials individually to organize and set Effect IDs is extremely time consuming. What I’m working on is a tool that will allow you to set them for all the materials, rename materials, set glossy subdivisions, etc. all in one spot. Being new to scripting, I’m not familiar with any of the interface tools you mention and am just relying on the standard UI tools documented in the MaxScript help.
I do have a version that manually creates a sort of tree view by looping through multi-sub object materials and then, depending on the child materials, it adds various controls with different position offsets to visually recreate a sort of tree view. It is crude though.
i have a lot of experience of making tools so…
how i would do it:
#1 make a list view control where show in row: name, glossiness, any other parameter …
#2 edit text control – for setting a material name for all selected materials in the list
#3 spinner – for setting glossiness (or any) for selected materials
#4-… any other controls for another parameters
#0 above the listview i would add search line
Thank Again Denis. When you mention “list view”, are you referring to the “List Box”?
http://docs.autodesk.com/3DSMAX/15/ENU/MAXScript-Help/index.html?url=files/GUID-4BB713FC-4380-4EDF-8155-E48EA5380E32.htm,topicNumber=d30e621026
Here is the full version of the script I have so far. I actually really like the layout as do my artist. I may do what you’ve suggested as a version 2 of this but since I’ve gotten this far and am beginning to understand this dynamic UI stuff, I want to follow through on it. I’m just running into problems converting it into a macro script due to insufficient depth of understanding with how the rollouts and dialogs work in Max and variable scope. Take a look and I must say I am cannibalizing other scripts I have found online, the main one from a guy named Florent Arnould.
global Version = "v0.1"
global c1 = 260
global c2 = 310
global c3 = c2+60
global c4 = c3+60
fn GetSceneMaterials =
(
--Blanks/Resets Arrays
global aVrayInstances = #() -- Holds all Vray Material Instances
global aMultiSubMaterials = #() -- Holds all Multi/Sub-Object Parent Materials
global aSubMaterials = #() --Holds Multi/Sub-Object Child Materials
global NoVrayInstances = 0
global NoMultiSubMaterials = 0
global NoSubMaterials = 0
-- Builds Array with All Vray Mats regardless of parent material
aVrayInstances = getclassinstances vraymtl
NoVrayInstances = aVrayInstances.count
aMultiSubMaterials = getclassinstances Multimaterial
NoMultiSubMaterials = aMultiSubMaterials.count
--turns on OverRide Material ID
for Mat in aVrayInstances do Mat.override_effect_id = true
)
fn CreateRolls =
(
global rcRollout1 = rolloutCreator "SubRollout1" "Unique V-Ray Instances"
rcRollout1.begin()
if NoVrayInstances != 0 then
(
--Unique Vray Instances Headers
rcRollout1.addcontrol #label "HeaderName" "Material Name" paramStr:("pos:[35,5]")
rcRollout1.addcontrol #label "HeaderType" "Type" paramStr:("pos:[c1,5]")
rcRollout1.addcontrol #label "Header1" "Effect ID" paramStr:("pos:[c2,5]")
rcRollout1.addcontrol #label "Header2" "Refl Subs" paramStr:("pos:[c3,5]")
rcRollout1.addcontrol #label "Header3" "Refr Subs" paramStr:("pos:[c4,5]")
for i = 1 to NoVrayInstances do
(
--Unique Vray Instances
rcRollout1.addcontrol #button ("bLoad" + i as string) "V" paramStr: ("width:15 height: 15 pos:[10," + ( (i) * 20 + 6) as string +"]")
rcRollout1.addcontrol #edittext ("mtlName" + i as string) "" paramStr: ("text:\"\" width:225 pos:[30," + ( (i) * 20 + 5) as string +"]")
rcRollout1.addcontrol #label ("MtlType" + i as string) (classof aVrayInstances[i] as string) paramStr:("pos:[c1," + ( (i) * 20 + 5) as string +"]")
rcRollout1.addcontrol #spinner ("EffectID" + i as string) "" paramStr:("type: #integer range:[0,1000,0] fieldwidth:35 scale:1 pos:[c2," + ( (i) * 20 +5) as string +"]")
rcRollout1.addcontrol #spinner ("spnRefl" + i as string) "" paramStr:("type: #integer range:[1,1000,8] fieldwidth:35 scale:1 pos:[c3," + ( (i) * 20 +5) as string +"]")
rcRollout1.addcontrol #spinner ("spnRefr" + i as string) "" paramStr:("type: #integer range:[1,1000,8] fieldwidth:35 scale:1 pos:[c4 ," + ( (i) * 20 +5 ) as string +"]")
rcRollout1.addHandler ("mtlName" + i as string) #changed paramStr:"arg" codeStr: ("aVrayInstances[" + i as string + "].name = arg")
rcRollout1.addHandler ("EffectID" + i as string) #changed paramStr:"arg" codeStr: ("aVrayInstances[" + i as string + "].effect_id = arg")
rcRollout1.addHandler ("spnRefl" + i as string) #changed paramStr:"arg" codeStr: ("aVrayInstances[" + i as string + "].reflection_subdivs = arg")
rcRollout1.addHandler ("spnRefr" + i as string) #changed paramStr:"arg" codeStr: ("aVrayInstances[" + i as string + "].refraction_subdivs = arg")
)
)
rcRollout1.end()
return (SubRollout1)
)
-- Pulls info for interface from Arrays
fn soft_refresh =
(
if aVrayInstances != 0 then
(
for i = 1 to NoVrayInstances do
(
global tempname=(substituteString (aVrayInstances[i] as string) ":VRayMtl" "" )
execute ("rollLister.Mat.SubRollout1.mtlName" + i as string +".text = tempname")
execute ("rollLister.Mat.SubRollout1.EffectID" + i as string +".value = aVrayInstances[" + i as string + "].effect_id")
execute ("rollLister.Mat.SubRollout1.spnRefl" + i as string +".value = aVrayInstances[" + i as string + "].reflection_subdivs")
execute ("rollLister.Mat.SubRollout1.spnRefr" + i as string +".value = aVrayInstances[" + i as string + "].refraction_subdivs")
)
)
)
fn hard_refresh =
(
--need to redefine those variables --
SubRollout1 = rollLister.Mat.SubRollout1
removeSubRollout rollLister.Mat SubRollout1
getSceneMaterials()
CreateRolls()
AddSubRollout rollLister.Mat SubRollout1
soft_refresh()
)
clearlistener()
GetSceneMaterials()
title = "Material Lister_"+version
global RCImain = rolloutCreator "rollLister" title
RCImain.begin()
RCImain.addcontrol #subrollout #Mat #Name paramStr:"width:500 height:600"
RCImain.addcontrol #label "lUniqueVrays" ("Unique VRay Material Instances:"+(NoVrayInstances as string)) paramStr:"align:#left offset:[0,10]"
RCImain.addcontrol #button #btnRefresh "Refresh" paramStr:"width:200 offset:[0,50]"
RCImain.width = 525
RCImain.height = 800
RCImain.addHandler #btnRefresh #pressed CodeStr: "hard_refresh()"
CreateRolls()
createDialog (RCImain.end()) pos:[1920,0]
AddSubRollout rollLister.Mat SubRollout1
soft_refresh()
i’m talking about listview .net form control. as i said there are many examples of its using. here is one of them:
http://forums.cgsociety.org/showpost.php?p=7798219&postcount=2
when you post a code please put it between ‘code’ tags (wrap CODE). the easiest way to do it is just select the code and press # button in message toolbar
Thank you Denis, I’ll take a look.
EDIT: Ahhh, that’s nice. I assumed implementing the .net controls would be more difficult and I was reluctant to tackle it before I had a better grasp of the standard controls. It doesn’t look too bad though, thanks.