Class MacroRecorder

3DS Max Plug-In SDK

Class MacroRecorder

See Also: Class ClassDesc, Class INode, Class IParamBlock, Class IParamBlock2, Class Matrix3, Class ReferenceTarget.

class MacroRecorder : public BaseInterfaceServer

Description:

This class is available in release 3.0 and later only.

This class provides various methods to emit pieces of script to the Macro Recorder. There are also methods to specify the nature of the scripts generated by the user operating 3ds max. Additionally there are methods to enable or disable the recording of scripts.

This class may be used by plug-ins but is also used internally as part of the 3ds max Macro Recorder. Inside key areas of 3ds max macro scripts are emitted corresponding to the operation being performed. For example when a call goes to a parameter block to set a value 3ds max internally call this classes method ParamBlock2SetValue(...) to emit script to record the change. Thus, many operations a plug-in performs are recorded automatically. There are however operations a plug-in can perform which won't be recorded automatically. In these cases methods of this class may be used to emit script to record these operations.

Several of the functions in this class use an ellipsis argument (...). This ellipsis is the var-args style of passing information to a method. This allows a developer to pass a variable number of values to the method. These are typically a set of tag values followed by some C++ types. The sample code shown with many of the methods shows how this is done. For a starting point for more general information on variable argument lists see va_arg in the Window help file.

Developers use the following global instance of this class to call these methods:

MacroRecorder *macroRecorder;

Methods:

public:

Prototype:

virtual void SetProperty(ReferenceTarget* targ, TCHAR* prop_name, BYTE type, ...)=0;

Remarks:

This provides a simple way to emit a properly assignment script. An example of this type of script is shown below:

$sphere01.radius = 50

Parameters:

ReferenceTarget* targ

Points to the object whose property is changing.

TCHAR* prop_name

The string which is the name of the property. This is the fixed machine-parsable name.

BYTE type

One of the type tags from List of Macro Recorder Value Types.

...

This ellipsis is the var-args style of passing information to a method. This allows a developer to pass a variable number of values to a method. These are typically a set of 'tags' followed by some C++ data types.

Prototype:

virtual void SetSelProperty(TCHAR* prop_name, BYTE type, ...)=0;

Remarks:

This provides a simple way to emit a properly assignment script for the current selection set.

Parameters:

TCHAR* prop_name

The name of the property to set.

BYTE type

One of the type tags from List of Macro Recorder Value Types.

...

This ellipsis is the var-args style of passing information to a method. This allows a developer to pass a variable number of values to a method. These are typically a set of 'tags' followed by some C++ types.

Sample Code:

macroRecorder->SetSelProperty(_T("material"), mr_reftarg, (Mtl*)dropThis);

Prototype:

virtual void FunctionCall(TCHAR* op_name, int arg_count, int keyarg_count, ...)=0;

Remarks:

This method is used to build a MAXScript function call. In the general case, such a call may have positional arguments followed by keyword arguments.

Parameters:

TCHAR* op_name

The name of the function to call.

int arg_count

The number of positional arguments in the varargs section.

int keyarg_count

The number of keyword arguments in the varargs section.

...

This ellipsis is the var-args style of passing information to a method. This allows a developer to pass a variable number of values to a method. These are typically a set of 'tags' followed by some C++ types.

See List of Macro Recorder Value Types for a list of potential tags and arguments.

Sample Code:

macroRecorder->FunctionCall(_T("addModifier"), 2, 1, mr_reftarg, this, mr_create, mod->ClassID(), mod->SuperClassID(), 0, _T("before"), mr_int, before);

This generates an addModifier() function call, such as:

addModifier $foo (bend()) before:3

The call has 2 positional arguments and 1 keyword argument (hence the 2, 1). The first positional is given as mr_reftarg, this which refers to the current node, the second positional is given as mr_create, mod->ClassID(), mod->SuperClassID(), 0 which causes a 0-argument constructor to be emitted for the modifier, and finally the single keyword argument is given as _T("before"), mr_int, before which is the keyword name followed by the arg value.

Prototype:

virtual void ScriptString(TCHAR* s)=0;

Remarks:

Emits a piece of macro script as a literal string. To understand when this is used consider the following example. Say you have a button in your user interface which does a certain thing but there is no way using the other macro recorder calls of constructing the piece of script that you need emitted. For instance the button may invoke a for loop. In such a case you can use this method to emit a macro script string which does a for loop. This is a string, just as you would type it into the MAXScript Listener.

Parameters:

TCHAR* s

The string to emit.

Prototype:

virtual void Assign(TCHAR* var_name, BYTE type, ...)=0;

Remarks:

This method is called to emit script to record the assignment to a MAXScript variable.

Parameters:

TCHAR* var_name

The variable name.

BYTE type

One of the type tags from List of Macro Recorder Value Types.

...

This ellipsis is the var-args style of passing information to a method. This allows a developer to pass a variable number of values to a method. These are typically a set of 'tags' followed by some C++ types.

Prototype:

virtual void SetCopy(ReferenceTarget* to_copy)=0;

Remarks:

This method is used to signal that an mr_reftarg argument in the currently accumulating script should be emitted as a copy. For example, when maps or materials are dragged onto sub-map/mtl buttons in the material editor, an instance/copy requester dialog is presented and depending on the choice, either a direct assignment or assignment of a copy is appropriate:

meditMaterials[4].materialList[2] = meditMaterials[11] -- instance

meditMaterials[4].materialList[2] = copy meditMaterials[11] -- copy

The actual assignment script is set up using a macroRecorder->SetProperty() call with the dropped map/material supplied as an mr_reftarg argument. In situations where the copy/instance status is known, you can emit directly an mr_funcall argument for the copy, but there may be situations in which this choice is decided in some piece of remote code or control flow and so you can use this method to condition the emitted script to apply a 'copy ' call.

Parameters:

ReferenceTarget* to_copy

The ReferenceTarget* object which should be copied.

Prototype:

virtual void Cancel()=0;

Remarks:

This cancels and clears the currently accumulating script. This would be used for example, if the operation that is being accumulated can be canceled by the user, such as right-clicking out of a transform or a geometry node create. There are calls to macroRecorder()->Cancel() in the MOUSE_ABORT processing in the default creation manager.

Prototype:

virtual void EmitScript()=0;

Remarks:

This signals the completion of an accumulating script, causing it to be frozen in the recorder pane and any new calls that might have been folded into the current script will cause a new one to be started. For example, when you drag the time slider, the sliderTime assignment script accumulates the changes, but when you let go of the mouse button, an EmitScript() is called, so that subsequent drags will start a separate script fragment. Same with interactive transforms and node creation.

Prototype:

virtual TSTR GetSubMtlPropName(Mtl* m, int i)=0;

Remarks:

Returns the property name of the 'i-th' sub-material of the specified material.

Parameters:

Mtl* m

The material whose 'i-th' sub-material property name is returned.

int i

The zero based index of the sub-material.

Prototype:

virtual TSTR GetSubTexmapPropName(MtlBase* m, int i)=0;

Remarks:

Returns the property name of the 'i-th' sub-texmap of the specified material.

Parameters:

MtlBase* m

The material or texmap whose 'i-th' sub-texmap property name is returned.

int i

The zero based index of the sub-texmap.

Prototype:

virtual void Enable()=0;

Remarks:

Enables the Macro Recorder. This call is 'nestable', i.e. it uses a use counter internally so recursive or nested code can manage local enables and disable states.

Prototype:

virtual void Disable()=0;

Remarks:

Disables the Macro Recorder. This allows the developer to disable the automatic macro recording.

Prototype:

virtual BOOL Enabled()=0;

Remarks:

Returns TRUE if the Macro Recroder is enabled (via Enable() above); otherwise FALSE.

Prototype:

virtual BOOL MasterEnable()=0;

Remarks:

In the MAXScript Listener Window Macro Recorder pulldown menu choice is an option to enable or disable the Macro Recorder. This method corresponds to that state. It returns TRUE if enabled; FALSE if disabled.

Prototype:

virtual void MasterEnable(BOOL onOff)=0;

Remarks:

In the MAXScript Listener Window Macro Recorder pulldown menu choice is an option to enable or disable the Macro Recorder. This method sets this state.

Parameters:

BOOL onOff

TRUE for enabled; FALSE for disabled.

Prototype:

virtual BOOL ShowCommandPanelSwitch()=0;

Remarks:

Returns TRUE if code is emitted when command panels are changed; FALSE if code is not emitted.

Prototype:

virtual void ShowCommandPanelSwitch(BOOL onOff)=0;

Remarks:

Determines if the macro recorder will emit script for command panel mode changes.

Parameters:

BOOL onOff

TRUE to record command panel changes; FALSE to ignore them.

Prototype:

virtual BOOL ShowToolSelections()=0;

Remarks:

Returns TRUE if the macro recorder will emit script for 3ds max toolbar tool selections; otherwise FALSE.

Prototype:

virtual void ShowToolSelections(BOOL onOff)=0;

Remarks:

Determines if the macro recorder will emit script for 3ds max toolbar selections.

Parameters:

BOOL onOff

TRUE to record toolbar selections; FALSE to ignore them.

Prototype:

virtual BOOL ShowMenuSelections()=0;

Remarks:

Returns TRUE if the macro recorder will emit script for 3ds max menu selecitons; otherwise FALSE.

Prototype:

virtual void ShowMenuSelections(BOOL onOff)=0;

Remarks:

Determines if the macro recorder will emit script for 3ds max menu selections.

Parameters:

BOOL onOff

TRUE to record menu selections; FALSE to ignore them.

Prototype:

virtual BOOL EmitAbsoluteSceneNames()=0;

Remarks:

Returns TRUE if specific node names are used in the generated code; FALSE if the current selection is used.

Prototype:

virtual void EmitAbsoluteSceneNames(BOOL onOff)=0;

Remarks:

This controls whether the code generated refers to the exact node names being operated or or simply the current selection.

Parameters:

BOOL onOff

TRUE to record absolute scene names; FALSE to use the selection set.

Prototype:

virtual BOOL EmitAbsoluteSubObjects()=0;

Remarks:

Returns TRUE if recording absolute sub-object numbers; FALSE if using the selection set.

Prototype:

virtual void EmitAbsoluteSubObjects(BOOL onOff)=0;

Remarks:

Determines if code generated is relative to the current sub-object selection state or if explicit sub-object numbers are generated.

Parameters:

BOOL onOff

TRUE to record explicit, absolute sub-object numbers; FALSE to use the selection set.

Prototype:

virtual BOOL EmitAbsoluteTransforms()=0;

Remarks:

Returns TRUE if code is generated using absolute transform assignments; FALSE if relative transforms operations are generated.

Prototype:

virtual void EmitAbsoluteTransforms(BOOL onOff)=0;

Remarks:

Sets if code is generated using absolute transform assignments.

Parameters:

BOOL onOff

TRUE for on; FALSE for off.

Prototype:

virtual BOOL EmitExplicitCoordinates()=0;

Remarks:

Returns TRUE if the macro recorder emits explicit coordinate contexts; otherwise FALSE. This determines whether explicit coordinate contexts are emitted in the generated script. For example, when you do a move() call or a .pos assign in MAXScript, the coordinates are interpreted with respect to the current active coordinate system, in a way similar to interactive transforms in the 3ds max UI. You set up the current system using a coordsys context, like this:

coordsys parent move $foo [10,0,0]

which would move the object 'foo' [10,0,0] in its parent's coordinate system. If you just say

move $foo [10,0,0]

it will work relative to the current active coordinate system. So, when this method returns TRUE 3ds max always sticks the coordsys context prefix onto a generated transform script, as set by the user in the coordinate system drop-down.

Prototype:

virtual void EmitExplicitCoordinates(BOOL onOff)=0;

Remarks:

Sets if the code is generated using explicit coordinate contexts. See EmitExplicitCoordinates() above.

Parameters:

BOOL onOff

TRUE for on; FALSE for off.

Prototype:

virtual BOOL BeginCreate(ClassDesc* cd, int flags=0)=0;

Remarks:

You would use this method if implementing a custom creation manager. This method starts a special accumulation 'mode' in which certain other Macro Recorder calls are treated specially until the next EmitScript(). BeginCreate() effectively signals the start of a scene node creation and enters a mode in which calls to SetNodeTM(), SetProperty(), ParamBlockXSetValue() and SetSelProperty() all generate keyword parameters to the current constructor, rather than emitting stand-alone property assignment scripts. Outside the 'create' mode, a call to SetNodeTM() would generate something like:

move $foo [10,0,0]

but when in the mode would add a pos: argument to the constructor:

sphere radius:20 pos:[10,0,0]

Parameters:

ClassDesc* cd

Points to the class descriptor for the plug-in.

Return Value:

This tells you whether MAXScript successfully entered the BeginCreate mode. It will fail if MAXScript can't create the object described by the ClassDesc, so you might use it in some generic situations to decided whether to call the closing EmitScript().

Prototype:

virtual void SetNodeTM(INode* n, Matrix3 m)=0;

Remarks:

This method is for internal use only.

Prototype:

virtual void ParamBlockSetValue(ParamBlock* pb, int i, BYTE type, ...)=0;

Remarks:

This method is for internal use only.

Prototype:

virtual void ParamBlock2SetValue(ParamBlock2* pb, int i, int tabIndex, ...)=0;

Remarks:

This method is for internal use only.

Prototype:

virtual void ParamBlock2SetCount(IParamBlock2* pb, int i, int n)=0;

Remarks:

This method is for internal use only.

Prototype:

virtual BOOL BeginSelectNode()=0;

Remarks:

This method is for internal use only.

Prototype:

virtual void Select(INode*)=0;

Remarks:

This method is for internal use only.

Prototype:

virtual void DeSelect(INode*)=0;

Remarks:

This method is for internal use only.

Prototype:

virtual void MAXCommand(int com)=0;

Remarks:

This method is for internal use only.

The following global function is not a part of this class:

Function:

void InitMacroRecorder();

Remarks:

This global function is used internally to inialize the macro recorder and should not be called by plug-in developers.