The Wonderful World of Classes and Class Instances

MAXScript FAQ > The Wonderful World of Classes and Class Instances

A user asked:

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

I am 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 either a true or false flag, but what is required with renderEffect? How does that command actually get written?

I tried

setActive blur true
setActive blur false

This 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>, you need an expression which evaluates to a boolean value. This also means that it does not only expect the symbol True or False, but any expression leading to the value represented by the symbols True and False. So, in place of <boolean>, you can have a variable containing a boolean value, an expression like myValue >= 10.5, or a MAXScript method that returns a boolean value (like selection[1].isHidden).

In the case of <renderEffect>, it expects a renderEffect object value. As 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 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 that 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.

For example, try to see this from a human perspective:

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

The SUPERCLASS can 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 not possible 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 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 try to use "Kiss Bulgarian" in Pseudo -MAXScript, you will get an error like:

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

This is because Bulgarian is not an object. It is a class describing a category of objects.

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

So, you can have a class hierarchy like:

LifeForm > EarthInhabitant > Mammal > HumanBeing > Caucasian > Bulgarian

The more general classes in the beginning define common capabilities of a life form like it breathes air or swims in water, drinks milk, is a two-legged creature, the origin and some common skin, hair, and eye color properties, the language it speaks, the region it comes from, and so on.

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 can 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

To disable all effects in the scene, you can do something like:

FOR EXAMPLE

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

See Also