How To ... Change Objects At Render Time

How To > Change Objects At Render Time

Using callback scripts, you can let MAXScript perform specific operations whenever certain system events occur. In the following example, we will increase the segment count of all spheres in the scene prior rendering, and decrease again after finishing. This will implement a kind of custom render resolution control for spheres. You can use similar approach to implement other pre-render preparations.

Related Topics:

Defining MacroScripts

General Event Callback Mechanism

NATURAL LANGUAGE

Package the code as macroScript to be able to use as a button, menu item or shortcut.

Remove any existing callbacks with our unique id.

Create a string containing the callback script for increasing the segment count of spheres.

In the script, loop through all geometry objects, check for sphere class of the base object and increase the segment count value 8 times.

Register a callback to be called before Rendering starts, give it a unique id.

Create a second string containing the callback script for decreasing the segment count of spheres.

In the script, loop through all geometry objects, check for sphere class of the base object and decrease the segment count value 8 times.

Register a callback to be called after Rendering finishes, give it the same unique id.

Create a second macroScript that removes our callbacks by id.

MAXSCRIPT

macroscript SphereSegsOn category: "HowTo"
(
callbacks.removescripts id:#sphere_segs
txt ="for o in geometry do(\n"
txt +="if classof o.baseObject == Sphere then \n"
txt +="o.baseObject.segments *= 8.0\n"
txt +=")\n"
 
callbacks.addscript #preRender txt id:#sphere_segs
txt ="for o in geometry do(\n"
txt +="if classof o.baseObject == Sphere then \n"
txt +="o.baseObject.segments /= 8.0\n"
txt +=")\n"
 
callbacks.addscript #postRender txt id:#sphere_segs
)
macroscript SphereSegsOff category: "HowTo"
(
callbacks.removescripts id:#sphere_segs
)

Step-By-Step

macroscript SphereSegsOn category:"HowTo"
(

The macroScript will be called SphereSegsOn . To use the script, you can go to Customize... and drag the script from the category "HowTo" to a toolbar, a menu, a quad menu or assign to a keyboard shortcut.

Defining Macro Scripts

callbacks.removescripts id:#sphere_segs

Before creating new callbacks, we try to remove any existing ones from a previous session. It is allowed to call callbacks.removescripts even if no callbacks with the specified id exist in the moment. If there are none, the call does nothing. If there are any, they will be removed.

We are going to use the same id #sphere_segs throughout the code. This way, we can affect only our callbacks without touching any others callbacks.

Callbacks.removeScripts

txt = "for o in geometry do(\n"
txt +="if classof o.baseObject == Sphere then \n"
txt +="o.baseObject.segments *= 8.0\n"
txt +=")\n"

In order to define a callback, we will need a string containing the code to be executed. We define a new user variable called txt and assign our code to it. The backslash n sequence denotes a new line. The script will loop through all geometry objects in the scene and ask each one for its base object (the object at the bottom of the modifier stack). If the class of the base object is Sphere, then we multiply the existing number of segments by 8. This means that the spheres will be changed even if there are modifiers like MeshSmooth, Bend etc. on the stack.

String Values

For Loop

Class and Object Inspector Functions

General Node Properties

Sphere : GeometryClass

callbacks.addscript #preRender txt id:#sphere_segs

Now we can assign the code as a callback script. . The keyword #preRender tells the callback that the script will be executed before rendering begins. The callback will have our unique id #sphere_segs so we can remove it by id anytime.

General Event Callback Mechanism

txt = "for o in geometry do(\n"
txt +="if classof o.baseObject == Sphere then \n"
txt +="o.baseObject.segments /= 8.0\n"
txt +=")\n"

This is basically the same code as before, but instead of multiplying, we divide the segments by 8. This should return all spheres to their original state.

callbacks.addscript #postRender txt id:#sphere_segs

We assign the new code as a callback script again. The keyword #postRender tells the callback that the script will be executed after the rendering finishes. The callback will have the same unique id.

)
macroscript SphereSegsOff category:"HowTo"
(

We define a second macroScript for turning off the effect of the callbacks. It will appear in the same category and will have the name SphereSegsOff

Defining Macro Scripts

callbacks.removescripts id:#sphere_segs

We remove any existing callbacks with our id. Rendering a scene with spheres should work as usual after calling this line.

Callbacks.removeScripts

)

Using the Script

Evaluate the code. To use the two scripts, you can use Customize... to drag the scripts from the category "HowTo" to a toolbar, a menu, a quad menu or to assign to a keyboard shortcut.

To use the script, create a scene with a couple of spheres and set their segments count quite low (as low as 4). Render the scene – all spheres should look exactly as they do in the viewports. (See first image). Then execute the SphereSegsOn script – nothing will change in the viewport, but if you render the scene again, all spheres will appear completely smooth. (see second image). Execute the SphereSegsOff script and the rendering should return to normal.

Back to

"How To" Tutorials Index Page