I often get asked to help making mass adjustments to scenes, or to provide tools to do that.
While all too happy to help, i'd be much happier knowing i passed something along other than one solution to a single, specific problem.
In that spirit, let me share with you what is possibly the awesomest one-liner of them all: let's change something in a bunch of things only if a condition is satisfied.
For example, let's say that you would like to change all the V-Ray standard materials in your scene, which currently have a very un-physical reflection glossiness of 1.0 to a slightly lower value, say 0.995, so to enable a more comprehensive sampling and help avoid fireflies.
The script would run like so, nearly in natural English language (brackets added for clarity only.):
*) So, the script would collect all the vrayMtl class materials (getClassInstances vraymtl) into a list (an Array, to be precise), and then run through that to assign them one after the other to the variable "myMaterial" for further processing.
*)The keyword "where" works like in natural language: it needs a condition to be satisfied, and if it is, then it will proceed.
In this case, we ask Max to check each material reflection glossiness level: if it is 1.0 then the material needs to be acted upon.
*)You will want to pay particular attention to the DOUBLE EQUAL SIGN: that is, in coding lingo, a QUESTION.
In other words, myMaterial.reflection_glossiness == 1.0, would read "is myMaterial reflection_glossiness equal to 1.0?".
*)If the answer to that question is "yes" (True, or 1) then the script will proceed DOing something.
It will, precisely, execute anything present in the brackets after the keyword "do", one line at a time.
The original goal was to change reflection glossiness amount, and so we proceed setting it.
*)Notice the SINGLE EQUAL SIGN: that's an ASSIGNMENT in coding.
In other words, now we tell max to SET the value of the property to 0.995
And this is the lay of the land. What's so special about this is that with the help of the maxscript listener, and its Macro Recorder, you can easily mass modify pretty much anything: lights, objects, maps, you name it.
For example, let's say i want to scale down all lights which are wider than 10 units:
first, select one light.
then type
in the listener, followed by the keypad enter.
$ in maxscript means "what is currently selected", and the command "classOf" queries the class of nodes.
it will print "vrayLight", which is the class of objects we want to operate on.
with the light still selected and the listener open, turn on the macro recorder (macro recorder menu -> enable), and change with the standard UI the light width.
The listener will print "$.size1 = 1.234".
The name after the dot is the property we're interested in: "size1"
Or let's turn all vrayHDRI loader maps filtering to elliptical, if they do not have it currently:
Or let's select all proxies for which no file is loaded
I believe this is enough to start a conversation.
I purposefully simplified things, and left a few tricky parts unsaid, along with some redundant code, but they may be better suited to a more in-depth debate, should it arise at all.
happy mass changes!
While all too happy to help, i'd be much happier knowing i passed something along other than one solution to a single, specific problem.
In that spirit, let me share with you what is possibly the awesomest one-liner of them all: let's change something in a bunch of things only if a condition is satisfied.
For example, let's say that you would like to change all the V-Ray standard materials in your scene, which currently have a very un-physical reflection glossiness of 1.0 to a slightly lower value, say 0.995, so to enable a more comprehensive sampling and help avoid fireflies.
The script would run like so, nearly in natural English language (brackets added for clarity only.):
Code:
[B]for[/B] [I]myMaterial [/I][B]in[/B] ([B]getClassInstances vraymtl[/B]) [B]where[/B] ([I]myMaterial[/I].[B]reflection_glossiness == [/B]1.0)[B] do[/B] ([I]myMaterial[/I].[B]reflection_glossiness =[/B] 0.995)
*)The keyword "where" works like in natural language: it needs a condition to be satisfied, and if it is, then it will proceed.
In this case, we ask Max to check each material reflection glossiness level: if it is 1.0 then the material needs to be acted upon.
*)You will want to pay particular attention to the DOUBLE EQUAL SIGN: that is, in coding lingo, a QUESTION.
In other words, myMaterial.reflection_glossiness == 1.0, would read "is myMaterial reflection_glossiness equal to 1.0?".
*)If the answer to that question is "yes" (True, or 1) then the script will proceed DOing something.
It will, precisely, execute anything present in the brackets after the keyword "do", one line at a time.
The original goal was to change reflection glossiness amount, and so we proceed setting it.
*)Notice the SINGLE EQUAL SIGN: that's an ASSIGNMENT in coding.
In other words, now we tell max to SET the value of the property to 0.995
And this is the lay of the land. What's so special about this is that with the help of the maxscript listener, and its Macro Recorder, you can easily mass modify pretty much anything: lights, objects, maps, you name it.
For example, let's say i want to scale down all lights which are wider than 10 units:
first, select one light.
then type
Code:
classOf $
$ in maxscript means "what is currently selected", and the command "classOf" queries the class of nodes.
it will print "vrayLight", which is the class of objects we want to operate on.
with the light still selected and the listener open, turn on the macro recorder (macro recorder menu -> enable), and change with the standard UI the light width.
The listener will print "$.size1 = 1.234".
The name after the dot is the property we're interested in: "size1"
Code:
for myLight in (getClassInstances vrayLight) where (myLight.size1 > 10.0) do (myLight.size1 = 10.0)
Code:
for myMap in (getClassInstances vrayHDRI) where (myMap.filterMode == 0) do (myMap.filtermode = 1)
Code:
for myProxy in (getClassInstances vrayProxy) where (myProxy.filename == "") do (selectMore myProxy)
I purposefully simplified things, and left a few tricky parts unsaid, along with some redundant code, but they may be better suited to a more in-depth debate, should it arise at all.
happy mass changes!
Comment