The Wonderful World of Classes and Class Instances

new.gif MAXScript Frequently Asked Questions

A user asked:

I want to be able to turn RenderEffects on and off, but I haven't been able to figure out if this is even possible.

I'm trying to decipher exactly how the Maxscript Help file syntax works... what does it mean when something is in the < > symbols as in:

setActive <renderEffect> <boolean>

I understand that setActive is the command, and boolean is an either true or false flag but what is required with renderEffect? and how does that command actually get written?

I tried

setActive blur true

setActive blur false

and that did not seem to be acceptable as the error states:

-- Runtime error: Invalid object, needed Atmospheric or Effect, got: blur

So what am I to provide in terms of an OOP object?

Answer:

According to Syntax Definitions in This Document

<rule> -- you can insert what is defined by the named rule

So when you see <boolean> , it tells you that you need an expression which evaluates to a boolean value. This also means that it doesn't only expect the symbol True or False itself, but any expression leading to the value represented by the symbols True and False would be legal. So in place of <boolean> you can have a variable containing a boolean value, or an expression like myValue >= 10.5, or a MAXScript method which returns a boolean value (like selection[1].isHidden).

In the case of <renderEffect>, obviously it expects a renderEffect object value. Since 3ds Max is an Object-Oriented program, most of its building blocks are objects in the OOP meaning of the word. Similarly, MAXScript lets you construct instances of object classes.

For example, b=box() creates an instance of the class Box and returns a value that is then stored in the variable b which then can be used anywhere where a <Node> is expected according to the MAXScript Help.

If you create an instance of the lens_effects class which is of renderEffect superClass, you get back an object which is not a scene node, but an object in the OOP meaning of the word and fits the rule mentioned above because its superClass matches the type of object expected by the setActive method.

Let's try to see this from a human perspective:

The CLASS of an object can be seen as the Nationality of a human.

The SUPERCLASS could be seen as the species, in this case, HumanBeing.

So when you give birth to a human being in Bulgaria, for example, you are creating an instance of the class Bulgarian, of superclass HumanBeing.

So class and superclass are general descriptions of types of objects, but not the objects themselves. If you want to apply the method "Kiss" to a human being, you cannot use "Kiss Bulgarian" as it is slightly difficult to kiss a nation. You need an INSTANCE of the class, a single human being, to call the method, so, in MAXScript pseudo-code:

Pseudo-Script:

theHuman = Bulgarian() --create an instance of the class Bulgarian

theHuman.name = "Bobo" --give it a funny name

print (superclassof theHuman)

--> HumanBeing

if theHuman.location == "Winnipeg" do

theHuman.isFrozen = true --set some properties based on object's location

 

-- Now you have a single instance you can call a method

-- that expects an object of the superclass HumanBeing:

Kiss theHuman

 

If you would try to use "Kiss Bulgarian", in Pseudo-MAXScript you would get an error like

-- Runtime error: Invalid object, needed HumanBeing or Dog, got: Bulgarian

because Bulgarian is not an object itself, it is a class describing a category of objects!

The idea of Object Oriented Programming is to have common classes of objects which inherit from more general classes, and let you create any number of instances of a class which inherits all typical properties and capabilities of the class hierarchy above.

So you could have a class hierarchy like

LifeForm>EarthInhabitant>Mammal>HumanBeing>IndoEuropean>Bulgarian

The more general classes in the beginning define common capabilities of a life form, the fact it probably breathes air or swims in water, the fact it drinks lots of milk, the fact it is a strange two-legged creature spending most of its time wearing digital watches, the origin and some common skin, hair and eye color properties, the language it speaks and the region it comes from, etc.

Still, you have to create an instance of the class you are interested in to use methods applicable to objects, as shown above.

In the special case of the RenderEffects, you need an instance of the Blur effect, not the class Blur itself. Usually, if the object exists in the scene, you would try to get the existing one into a variable, by calling

For Example

myEffect = getEffect 1 --returns the first effect on the RenderEffects list

setActive myEffect false --disables it

Or shorter, without the intermediate variable,

For Example

setActive (getEffect 1) false

Obviously, to disable all effects in the scene, you could do something like

For Example

for i = 1 to NumEffects do setActive (getEffect i) false

 

See also

Frequently Asked Questions