It’s really important when you’re writing scripts to understand what class nodes are in 3dsmax. You can use classes to quickly select things, like for instances
Will select all the cameras in your scene.
If you create a Target Camera select it, and type in ($ is a shortcut for our node selected, can only be one node at a time)
You’ll get ‘TargetCamera’ returned, so hang on Dave I thought you just said that Cameras was the class… well a TargetCamera class is derived from the Camera Class, so to find out what the class of TargetCamera is we can do
..which returns ‘camera’. Now a simpler way to find out what the base class is actually is to user SuperClassOf…. on our selected TargetCamera
… returns… ‘camera’.
You can get all the classes of camera by typing
Similar with other things like lights and materials
So why, I hear you ask, is it important to know all this… well lets say you wanted to run a script on all the Vray lights in the scene. You can’t just type in ‘VRayLights’ and expect to get an array of the lights unfortunately. You need to filter your selection, or the scene objects.
for o in objects where classof o == VRayLight do print o
So basically in this loop, we’re saying for every ‘object’ in the objects in our scene where it’s class is equal to VRayLight then print it.
Now, how did I know the class name we were looking for was VRayLight? Easiest way is to select a VRayLight and then you can just type into the listener, Classof $ and it’ll return ‘VRayLight’. Very useful as you don’t have to remember every single class.
So lets do something practical with this, let’s say we wanted to write a script which would double or half the intensity of our VRayLights, which is effectively ‘stopping-up’ or ‘stepping-down’ in camera terms.
Lets make a quick interface as outlined in lesson 1, with two buttons.
try(DestroyDialog RL_LightAdjuster)catch() Rollout RL_LightAdjuster "VRay Light Adjuster" ( button btn_increase "Increase Light" button btn_decrease "Decrease Light" on btn_increase pressed do ( ) on btn_decrease pressed do ( ) ) CreateDialog RL_LightAdjuster
Now we have a basic interface we can make the buttons do something… We want to run it on all the VRayLights in our scene, but we can’t guarantee that the lights are going to be called $VRayLight001, $VRayLight002 or we could use $VRayLight* as outlined in the previous post, instead we need to collect the array based on class.
We want to adjust the strength of the VRayLight, so we need to find out what that property is called in maxscript, we can’t always rely on the name in the interface to be the same as the maxscript property so to find out we can use the Showproperties() function. There are two ways to use this, first, select a VrayLight and run it like this…
Either will return a long list….
.on : boolean .type : integer .castShadows : boolean .size0 : worldUnits .size1 : worldUnits .size2 : worldUnits .subdivs : integer .color_mode : integer .color_temperature : float .color : RGB color .multiplier : float ....
This gives us the properties available to this class and what type of value they expect.
Briefly on types of values…
boolean: True or False
integer: a whole number 1,2,3,4,etc
float: a non-whole number 1.233, 1.454, 0.234
RGB color: a color consisting of 3 numbers. color 255 255 255
worldUnit: a measurement value that depends on you system units. eg 1.0m
string: a bit of text normally in quotations, “this is a string”
array: a list of values.. can be mixed types.
node: an object in the scene.
These are the main ones you’ll come across, so from our list we can see that there’s multiplier which is a float, nice and obviously this is what we want, so lets write a bit of code to double the multiplier of the light. We can test this in isolation from our script interface as it’s a one-liner. Select a VrayLight and try this.
$.multiplier = $.multiplier * 2
Which will double the multiplier 🙂 There’s an even shorter way to write this sort of basic maths… instead of saying… something = something * 2 or something = something + 1 we can use *= or +=.
$.multiplier *= 2
Even simpler to use, so lets put this into a loop to run on all the lights in our scene.
for o in objects where ClassOf o == VrayLight do o.multiplier *= 2
We could actually make this script faster (although on most scenes not noticeably) by limiting our array to just the Lights…
for o in Lights where Classof o == VrayLight do o.multiplier *= 2
So lets put this code into our interface and make the decrease light button too.
try(DestroyDialog RL_LightAdjuster)catch() Rollout RL_LightAdjuster "VRay Light Adjuster" ( button btn_increase "Increase Light" button btn_decrease "Decrease Light" on btn_increase pressed do ( for o in Lights where Classof o == VrayLight do o.multiplier *= 2 ) on btn_decrease pressed do ( for o in Lights where Classof o == VrayLight do o.multiplier /= 2 ) ) CreateDialog RL_LightAdjuster
Now, just to throw a spanner in the mix, there’s another way to class to get an array of what we want to work on. GetClassInstances() , this function will get all the instances of a given class and collect as an array. For example.
for o in getclassinstances VrayLight do o.multiplier *= 2
So here’s our final optimized script.
try(DestroyDialog RL_LightAdjuster)catch() Rollout RL_LightAdjuster "VRay Light Adjuster" ( button btn_increase "Increase Light" button btn_decrease "Decrease Light" on btn_increase pressed do ( for o in getclassinstances VrayLight do o.multiplier *= 2 ) on btn_decrease pressed do ( for o in getclassinstances VrayLight do o.multiplier /= 2 ) ) CreateDialog RL_LightAdjuster