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.
General Event Callback Mechanism
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.
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.
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.
Class and Object Inspector Functions
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.
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.
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
We remove any existing callbacks with our id. Rendering a scene with spheres should work as usual after calling this line.
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.