General Event Callback Mechanism

MAXScript allows you to register callback scripts for all of the notification events supported by 3ds Max, such as pre/post scene file open, new, reset, scene file save, pre/post render, selection change, etc. You can specify any number of callback scripts per notification event. Callback scripts can be bundled into ID'd sets, and can be deleted individually or all callback scripts in and ID’d set can be deleted. Callback scripts can be specified as persistent so that they are saved and loaded with the currently open file.

The callbacks are maintained by the following set of functions:

callbacks.addScript <callback_type_name> ( <script_string> | <script_stringstream> | \ fileName:<filename_string> ) [id:<name>] [ persistent:<boolean> ]

This method is used to register a new callback script. Requires as the first argument a name that specifies which type of notify event this script is associated with. The list of valid callback_type_name values is listed below.

The script is supplied either as a direct String or StringStream value containing the text of the script to run, or as a fileName: keyword argument, in which case the named file is loaded and run whenever the event notification callback occurs. You can specify either a direct string or a fileName:, but not both.

The optional id: parameter lets you tag one or a group of callbacks with a unique name so that you can remove them all as a group without interfering with other callbacks, perhaps registered by other scripted tools.

The optional persistent: parameter lets you control whether the script is saved permanently in the currently open scene file or is a global callback script that remains in place no matter what file opening and closing is performed. A true value for the parameter specifies that the script should be stored in the current file and loaded and registered for callback whenever that file is opened again. Persistent callback scripts are always removed when a new file is loaded or a reset is performed so that persistent scripts in one file don't accidentally get copied to a later file. The default for this parameter is false, indicating the script is a global script and is not persistent.

For Example:

callbacks.addScript #preRender "setUpRenderGeom()" id:#jbwRender

registers a new callback script that will be called just before a render is performed. The script invokes a function (that has presumably already been set up). An unique ID has been assigned to the script for later selective removal.

callbacks.removeScripts [ <callback_type_name> ] [ id:<name> ]

This method is used to unregister and remove one or more callback scripts. Specifying just a callback event type name removes all the callback scripts for that event. Specifying just an id:<name> removes all callback scripts in all events with that ID. Specifying both limits the ID-based removal to the specified event type.

callbacks.show ()

This method lists out the current callback scripts in the Listener window.

callbacks.broadcastCallback <callback_type_name>

This method provides a way for you to simulate one of the events and have all the callback scripts for it executed. Within 3ds Max, the #preRenderFrame and #preRenderFrame callbacks can only be called by the renderer. These callbacks can not be called by using this method.

Additional notification information on the callback:

callbacks.notificationParam()

This method can be called in a callback script to provide additional information on the callback. The value returned by this method varies based on the callback type. If no additional information was present for the callback, a value of 'undefined' is returned.

Example:

--Remove any existing callbacks with this ID.

callbacks.removeScripts id:#MXSHelp

--Add a new callback script which will call

--callbacks.notificationParam() before selected nodes are deleted

--and thus will print the deleted objects to the Listener:

callbacks.addScript #selectedNodesPreDelete "print (callbacks.notificationParam())" id:#MXSHelp

Callback Event Names and notificationParam Return Values:

Below are all supported Callback Event Names and the callbacks.notificationParam() values typically returned. Depending on how the broadcast is generated, a value of 'undefined' may be returned by this method instead of the value shown.

Quick Navigation:

Animation Notifications

Render Dialog and Render Plugin Notifications

Rendering Notifications

File Notifications

Xrefs Notifications

Layer System Notifications

Manipulate Mode Notifications

new.gif Modifier Panel Notifications

Modifier Notifications

Material Library Notifications

Material Notifications

Node Related Notifications

System Notifications

Radiosity Notifications

Undo System Notifications

Schematic View Notifications

Asset Browser Notifications

new.gif Named Selection Set Notifications

new.gif Direct3D Notifications

Other Notifications

Animation Notifications:

#animateOff: undefined

Sent when the Animate button is turned off.

#animateOn: undefined

Sent when the Animate button is turned on.

#animationRangeChange: undefined

Render Dialog and Renderer Plugin Notifications:

#tabbedDialogCreated: #(integer, integer)

Sent after the tabbed render dialog has been created.

#tabbedDialogDeleted: #(integer, integer)

Sent after the tabbed render dialog has been deleted.

#renderParamsChanged: undefined

Sent whenever the common renderer parameters have changed.

#preRendererChange: undefined

Sent before the current renderer is changed, or the type of one of the renderers is changed.

#postRendererChange: undefined

Sent after the current renderer is changed, or the type of one of the renderers is changed.

Rendering Notifications:

#preRender: Array

Sent before rendering is started. This notification is sent out before the renderer creates the render instance objects, which means that you can create nodes and other objects as a response to this event. When rendering multiple frames, this event is sent only once at the beginning of the rendering phase, and not on a per-frame basis. In the #preRender callback, you can't change any of the render parameters (height, width, aliasing, etc) and affect the current render sessions. Those parameters have already been set up internally in 3ds Max, and so changes to them won't occur until the next render session occurs.

Returns a 28 element array - see the SDK help file, class RendParams, for more information on the parameter definitions.

1 - Name - rpar->rendType

2 - Boolean - rpar->isNetRender

3 - Boolean - rpar->fieldRender

4 - Integer - rpar->fieldOrder

5 - Time - rpar->frameDur

6 - Boolean - rpar->colorCheck

7 - Integer - rpar->vidCorrectMethod

8 - Integer - rpar->ntscPAL

9 - Boolean - rpar->superBlack

10 - Integer - rpar->sbThresh

11 - Boolean - rpar->rendHidden

12 - Boolean - rpar->force2Side

13 - Boolean - rpar->inMtlEdit

14 - Float - rpar->mtlEditTile

15 - Boolean - rpar->mtlEditAA

16 - Boolean - rpar->multiThread

17 - Boolean - rpar->useEnvironAlpha

18 - Boolean - rpar->dontAntialiasBG

19 - Boolean - rpar->useDisplacement

20 - Boolean - rpar->useRadiosity

21 - Boolean - rpar->computeRadiosity

22 - TextureMap - rpar->envMap

23 - Time - rpar->firstFrame

24 - Integer - rpar->scanBandHeight

25 - Integer - rpar->extraFlags

26 - Point2 - rpar->width, rpar->height

27 - Boolean - rpar->filterBG

28 - Boolean - rpar->alphaOutOnAdditive

#postRender: undefined

Sent after rendering has finished. This notification is sent out after the renderer destroys the render instance objects, which means that you can create nodes and other objects as a response to this event. When rendering multiple frames, this event is sent only once at the end of the rendering phase, and not on a per-frame basis.

#preRenderEval: time

Sent just before the renderer starts evaluating objects.

Returns the time being rendered

#preRenderFrame: Array

Sent just before each frame is rendered by the renderer. This notification is sent out after the renderer has taken a snapshot of the scene geometry. At the time of this call the scene cannot be modified. The renderer has already called GetRenderMesh() on all the object instances, and the materials and lights are already updated. If you don't modify anything that is rendered, then it is okay to use this callback. The current frame being rendered is set into the MAXScript currentTime context and system global, so any references to other scene object properties will automatically be resolved at the currently rendering frame's time. This notification is not sent out when the renderer is called to update the Material Editor sample spheres, only during output rendering.

#postRenderFrame: Array

Sent just after each frame is rendered by the renderer. The current frame being rendered is set into the MAXScript currentTime context and system global, so any references to other scene object properties will automatically be resolved at the currently rendering frame's time. This notification is not sent out when the renderer is called to update the Material Editor sample spheres, only during output rendering.

Returns a 22 element array - see the SDK help file, class RenderGlobalContext, for more information on the parameter definitions.

1 - Integer - rendParams->projType

2 - Point2 - rendParams->devWidth, rendParams->devHeight

3 - Point2 - rendParams->xscale, rendParams->yscale

4 - Point2 - rendParams->xc, rendParams->yc

5 - Boolean rendParams->antialias

6 - Matrix3 - rendParams->camToWorld

7 - Matrix3 - rendParams->worldToCam

8 - Point2 - rendParams->nearRange, rendParams->farRange

9 - Float - rendParams->devAspect

10 - Float - rendParams->frameDur

11 - TextureMap - rendParams->envMap

12 - Color - rendParams->globalLightLevel

13 - Time - rendParams->time

14 - Boolean rendParams->wireMode

15 - Float - rendParams->wire_thick

16 - Boolean - rendParams->force2Side

17 - Boolean - rendParams->inMtlEdit

18 - Boolean - rendParams->fieldRender

19 - Boolean - rendParams->first_field

20 - Boolean - rendParams->field_order

21 - Boolean - rendParams->objMotBlur

22 - Integer - rendParams->nBlurFrames

#beginRenderingReflectRefractMap: undefined

Sent before preparing Reflect and Refract Maps for rendering

#beginRenderingActualFrame: undefined

Sent after render setup and immediately before the actual render begins

#beginRenderingTonemappingImage: undefined

Sent before rendering Tonemapping image

WARNING:

You cannot change an object's mesh in a #preRenderFrame, #postRenderFrame, or any of the #beginRendering* callbacks, particularly if the mesh isn't animated. The renderer has already evaluated the original mesh and holds a pointer to that mesh. Changing the object's mesh will delete the old mesh, but the renderer doesn't know this, and when trying to render the now deleted mesh will crash.

For an example of using the #preRender and #postRender callbacks, see

How To ... Change Objects At Render Time

 

FileLink Notifications:

#fileLinkPreAttach: undefined

Sent just before a file link attach.

#fileLinkPostAttach: undefined

Sent just after a file link attach.

#fileLinkPreBind: undefined

Sent just before a file link bind.

#fileLinkPostBind: undefined

Sent just after a file link bind.

#fileLinkPreDetatch: undefined

Sent just before a file link detach.

#fileLinkPostDetatch: undefined

Sent just after a file link detach.

#fileLinkPreReload: undefined

Sent just before a file link reload.

#fileLinkPostReload: undefined

Sent just after a file link reload.

#filelinkPostReloadPrePrune: undefined

Sent after all of the new objects for a reload have been created, but before any objects have been deleted.

File Notifications:

#filePreOpen: (integer | undefined)

Sent before a new file is opened.

Calling callbacks.notificationParam() returns an integer value of 2 if a render preset file is being opened, undefined otherwise.

#filePostOpen: (integer | undefined)

Sent after a new file is opened successfully.

Calling callbacks.notificationParam() returns an integer value of 2 if a render preset file is being opened, undefined otherwise.

#filePostOpenProcess: undefined

Sent after the file open process has finished.

#filePreSave: string

Sent before a file is saved.

Calling callbacks.notificationParam() returns a String containing the file name.

#filePostSave: string

Sent after a file is saved.

Calling callbacks.notificationParam() returns a String containing the file name.

#filePreSaveOld: undefined

Sent before an old version file is saved.

#filePostSaveOld: undefined

Sent after an old version file is saved.

#filePreMerge: integer

Sent before a file is merged.

Calling callbacks.notificationParam() returns an integer value of 1 if object or scene Xref merged, undefined otherwise

#filePostMerge: integer

Sent after a file is merged successfully.

Calling callbacks.notificationParam() returns an integer value of 1 if object or scene Xref merged, undefined otherwise

#filePostMergeProcess: undefined

Sent after the merge process has finished.

#preImport: undefined

Sent before a file is imported.

#postImport: undefined

Sent after a file is imported successfully.

#importFailed: undefined

Sent if import fails.

#preExport: undefined

Sent before a file is exported.

#postExport: undefined

Sent after a file is exported successfully.

#exportFailed: undefined

Sent if export fails.

Xrefs Notifications:

#objectXrefPreMerge: undefined

Loading XRef (typically surrounding Merge notices)

#objectXrefPostMerge: undefined

Loading XRef (typically surrounding Merge notices)

#sceneXrefPreMerge: undefined

Loading XRef (typically surrounding Merge notices)

#sceneXrefPostMerge: undefined

Loading XRef (typically surrounding Merge notices)

Layer System Notifications:

#layerCreated: BaseLayer (reftarg)

Sent after layer created.

Calling callbacks.notificationParam() returns a layer ReferenceTarget.

Note:

There is a known problem with #layerCreated - a layer may be created if an object is merged or an object XRef is performed, but these actions do not broadcast a #layerCreated event.

#layerDeleted: BaseLayer (reftarg)

Sent before layer deleted, callbacks.notificationParam() returns the layer

#nodeLayerChanged: #(node, BaseLayer, BaseLayer)

Sent after node placed on new layer, callbacks.notificationParam() returns an array containing 3 elements - the node, the old layer and the new layer

Manipulate Mode Notifications:

#manipulateModeOn: undefined

Sent when entering manipulate mode.

#manipulateModeOff: undefined

Sent when exiting manipulate mode

Modifier Panel Notifications:

#modPanelObjPreChange: undefined

Sent just before the current edit object is about to change in Modify panel.

#modPanelObjPostChange: undefined

Sent just after the current edit object changes in Modify panel

#modPanelSelChanged: undefined

Sent whenever the Modify panel opens on a new selection, either because the Modify panel was just selected or because a new selection is made in the scene. The notify occurs at a point just prior to panel redraw but after the selection has been established, so that callback functions can modify the panel state without it being overwritten.

#ModPanelSubObjectLevelChanged: #(newSOlevelIndex, oldSOlevelIndex)

new.gif NEW in 3ds Max 9: Sent whenever the Modify panel changes the sub-object level. Calling callbacks.notificationParam() returns an array containing the new SO level number and the old SO level number.

Modifier Notifications:

#preModifierAdded: #(node, modifier)

Sent before a modifier is added to a node.

Calling callbacks.notificationParam() within the callback function will return a 2 element array containing the node and the modifier which was added.

#postModifierAdded: #(node, modifier)

Sent after a modifier is added to a node.

Calling callbacks.notificationParam() within the callback function will return a 2 element array containing the node and the modifier which was added.

#preModifierDeleted: #(node, modifier)

Sent before a modifier is deleted from a node.

Calling callbacks.notificationParam() within the callback function will return a 2 element array containing the node and the modifier which was deleted.

#postModifierDeleted: #(node, modifier)

Sent after a modifier is deleted from a node.

Calling callbacks.notificationParam() within the callback function will return a 2 element array containing the node and the modifier which was deleted.

Material Library Notifications:

#mtlLibPreOpen: undefined

Sent just before loading a material library.

#mtlLibPostOpen: materiallib

Sent just after loading a material library.

Calling callbacks.notificationParam() within the callback function will return the MaterialLibrary loaded.

#mtlLibPreSave: undefined

Sent just before saving a material library.

#mtlLibPostSave: undefined

Sent just after saving a material library.

#mtlLibPreMerge: undefined

Sent just before merging a material library.

#mtlLibPostMerge: undefined

Sent just after merging a material library.

Material Notifications:

#mtlRefAdded: material

Called when a material reference is added.

Calling callbacks.notificationParam() within the callback function returns the Material

#mtlRefDeleted: material

Called when a material reference is deleted.

Calling callbacks.notificationParam() within the callback function returns the Material

Node Related Notifications:

#nodeCreated: node

Sent when a node is created.

Calling callbacks.notificationParam() within the callback function returns the node.

#nodeCloned: node

Sent after a node is cloned but before theHold.Accept(..).

Calling callbacks.notificationParam() within the callback function returns the node.

#sceneNodeAdded: node

Sent just after a node is added to the scene.

Calling callbacks.notificationParam() within the callback function returns the node.

#nodeFreeze: node

Sent when a node is frozen.

Calling callbacks.notificationParam() within the callback function returns the node.

#nodeUnfreeze: Node

Sent when a node is unfrozen.

Calling callbacks.notificationParam() within the callback function returns the node.

#nodeHide: node

Sent when a node is hidden.

Calling callbacks.notificationParam() within the callback function returns the node.

#nodeUnhide: Node

Sent when a node is unhidden.

Calling callbacks.notificationParam() within the callback function returns the node.

#nodeLinked: Node

Sent when a new parent-child link is made. Calling callbacks.notificationParam() within the callback function returns the node.

#nodeUnlinked: Node

Sent when a parent-child link is broken.

Calling callbacks.notificationParam() within the callback function returns the node.

#nodePreDelete: Node

Sent before a node is deleted.

Calling callbacks.notificationParam() within the callback function returns the node.

#nodePostDelete: undefined

Sent after a node is deleted.

#nodePreMaterial: Node

Sent just before a node gets a new material.

Calling callbacks.notificationParam() within the callback function returns the node.

#nodePostMaterial: Node

Sent just after a node gets a new material.

Calling callbacks.notificationParam() within the callback function returns the node.

#nodeRenamed: #(name, name)

Sent if a scene node is renamed.

Calling callbacks.notificationParam() within the callback function returns a 2 element array containing the old and new node name as strings

Note:

It is more reliable to use the #nodeNameSet callback introduced in 3ds Max 7! See below.

#nodeNameSet: #(name, name, node)

Sent when a scene node name is set or changed.

Note:

It is more reliable to use this callback type than the #nodeRenamed callback.

Calling callbacks.notificationParam() within the callback function returns a 3 element array containing the old name, the new name, and the node.

#preNodeBonePropChanged: Array of nodes

Pre bone property change.

Calling callbacks.notificationParam() within the callback function returns the array of nodes.

#postNodeBonePropChanged: Array of nodes

Post bone property change.

Calling callbacks.notificationParam() within the callback function returns the array of nodes.

#preNodeGeneralPropChanged: Array of nodes

Pre general property change.

Calling callbacks.notificationParam() within the callback function returns the array of nodes

#postNodeGeneralPropChanged: Array of nodes

Post general property change.

Calling callbacks.notificationParam() within the callback function returns the array of nodes whose properties have been changed.

#preNodeGiPropChanged: Array of nodes

Sent before Advanced Lighting property changes.

Calling callbacks.notificationParam() within the callback function returns the array of nodes whose properties will be changed.

#postNodeGiPropChanged: Array of nodes

Sent after Advanced Lighting property changes.

Calling callbacks.notificationParam() within the callback function returns the array of nodes whose properties have been changed.

#preNodeMentalrayPropChanged: Array of nodes

Sent before mental ray property changes.

Calling callbacks.notificationParam() within the callback function returns the array of nodes whose mental ray properties will be changed.

#postNodeMentalrayPropChanged: Array of nodes

Sent after mental ray property changes.

Calling callbacks.notificationParam() within the callback function returns the array of nodes whose mental ray properties have been changed.

#preNodesCloned: Array of nodes

Sent before node clone.

Calling callbacks.notificationParam() within the callback function returns the array of nodes.

#postNodesCloned: #(array of nodes, array of nodes, name)

Sent after nodes are cloned.

Calling callbacks.notificationParam() within the callback function will return a 3 element array where the first element is an array of the original nodes, the second element is an array of the cloned nodes, and the third element is a name value of #copy, #instance, or #reference, reflecting the clone type.

#preNodeUserPropChanged: Array of nodes

Pre user property change.

Calling callbacks.notificationParam() within the callback function returns the array of nodes.

#postNodeUserPropChanged: Array of nodes

Post user property change.

Calling callbacks.notificationParam() within the callback function returns the array of nodes.

#preMirrorNodes: Array of nodes

Beginning of the mirror operation.

Calling callbacks.notificationParam() within the callback function returns the array of nodes

#postMirrorNodes: Array of nodes

End of the mirror operation.

Calling callbacks.notificationParam() within the callback function returns the array of nodes.

#selectedNodesPreDelete: Array of nodes

Sent just before selected nodes are deleted.

Calling callbacks.notificationParam() within the callback function returns the Array of nodes about to be deleted

#selectedNodesPostDelete: undefined

Sent just after selected nodes are deleted.

#selectionSetChanged: undefined

Sent after the selection set has changed.

 

System Notifications:

#postSystemStartup: undefined

Sent when the software goes live.

#systemPreNew: integer

Sent just before 3ds Max is reset.

Calling callbacks.notificationParam() within the callback function will return an integer value corresponding to the option selected in the New Scene dialog:

1 - New All

2 - Keep Objects

3 - Keep Objects and Hierarchy

#systemPostNew: undefined

Sent just after 3ds Max is reset.

#systemPreReset: undefined

Sent before 3ds Max is reset.

#systemPostReset: undefined

Sent after 3ds Max is reset.

#systemPreDirChange: undefined

System path has changed - Catalogs dir modified from the Configure Path dialogue

#systemPostDirChange: undefined

System path has changed - Catalogs dir modified from the Configure Path dialogue

#preSystemShutdown: undefined

Sent just before the software enters the shutdown process.

#postSystemShutdown: undefined

Sent just before the software finishes the shutdown process.

#pluginLoaded: string

Sent whenever a plug-in is loaded.

Calling callbacks.notificationParam() within the callback function will return the String containing the name of the dll loaded

Radiosity Notifications:

#radiosityPluginChanged: undefined

Radiosity plugin is changed

#radiosityProcessDone: undefined

Called when the Radiosity process has finished.

#radiosityProcessReset: undefined

Called when the Radiosity process has been reset.

#radiosityProcessStart: undefined

Called when the Radiosity process has been started.

#radiosityProcessStopped: undefined

Called when the Radiosity process has been stopped.

Undo System Notifications:

#sceneUndo: string

Sent after a scene undo is performed.
callbacks.notificationParam() returns the name of the undo entry in 3ds Max 8 and higher.

#sceneRedo: string

Sent after a scene redo is performed.
callbacks.notificationParam() returns the name of the undo entry 3ds Max 8 and higher.

Example script:

callbacks.removeScripts id:#test

callbacks.addScript #sceneRedo "format \"Redo: %\\n\" (callbacks.notificationParam())" id:#test

callbacks.addScript #sceneUndo "format \"Undo: %\\n\" (callbacks.notificationParam())" id:#test

Schematic View Notifications:

#svSelectionSetChanged: integer

Sent when the Schematic View selection set has changed. callbacks.notificationParam() returns the Schematic View index.

#svDoubleClickGraphNode: undefined

Sent when the user double-clicked a Schematic View node.

#svPreLayoutChange: integer

Sent before Schematic View applies its layout algorithm.

Calling callbacks.notificationParam() within the callback function returns the Schematic View index.

#svPostLayoutChange: integer

Sent after Schematic View applies its layout algorithm.

Calling callbacks.notificationParam() within the callback function returns the Schematic View index.

Asset Browser Notification:

#assetBrowserPreNavigate: string

Sent whenever a URL is loaded into the Asset Browser.

Calling callbacks.notificationParam() within the callback function returns the String containing the URL to browse to.

Named Selection Set Notification:

#NamedSelSetCreated: string

new.gif NEW in 3ds Max 9: Sent after a named selection set is created.

Calling callbacks.notificationParam() will return the new selection set name.

#NamedSelSetDeleted: string

new.gif NEW in 3ds Max 9: Sent after a named selection set is deleted.

Calling callbacks.notificationParam() will return the name of the deleted named selections set.

#NamedSelSetRenamed: string

new.gif NEW in 3ds Max 9: Sent after a named selection set is renamed.

Calling callbacks.notificationParam() will return an array containing the old name and new name of the renamed selection set.

Direct3D Device Notification:

#D3DPreDeviceReset: undefined

new.gif NEW in 3ds Max 9: Sent before the DirectX device is being reset.

#D3DPostDeviceReset: undefined

new.gif NEW in 3ds Max 9: Sent after the DirectX device has been reset.

Other Notifications:

#bitmapChanged: string

Sent after a bitmap is reloaded.

Calling callbacks.notificationParam() within the callback function returns the String containing bitmaptexture bitmap file name.

#byCategoryDisplayFilterChanged: undefined

Sent AFTER object categories marked to be hidden\unhidden

#colorChanged: undefined

Sent when the system is updating it’s custom colors.

#customDisplayFilterChanged: undefined

Sent AFTER custom display filters have been activated\deactivated

#lightingUnitDisplaySystemChange: undefined

Sent when lighting unit display system is changed

#spacemodeChange: undefined

Sent if the user changes the reference coordinate system.

#timeunitsChange: undefined

Sent if the user changes the time format setting.

#unitsChange: undefined

Sent if the user changes the unit setting.

#viewportChange: undefined

Sent if the user changes the viewport layout.

#mainWindowEnabled: boolean

Sent when the main application window gets enabled.

Calling callbacks.notificationParam() within the callback function returns a Boolean value - true if main 3ds Max window is being enabled, false if another window is being enabled.

#heightMenuChanged: undefined

Sent when a user operated the height menu.

#preProgress: undefined

Sent before the progress bar is displayed

#postProgress: undefined

Sent after the progress bar is finished

See also

How To ... Change Objects At Render Time

Change Handlers and Callbacks

Change Handlers and When Constructs

Time Change Callback Mechanism

Viewport Redraw Callback Mechanism