Custom Node Properties and App Data

3DS Max Plug-In SDK

Custom Node Properties and App Data

See Also: Class Interface, Class INode, Class ClassDesc, AppData, AppDataChunk.

Overview

A plug-in developer may need to hang arbitrary data off nodes in the scene. 3ds max provides two ways to accomplish this, AppData and User Properties. This section discusses both these approaches. Also discussed is the way a developer can save data associated with their plug-in class to the 3ds max file.

AppData

AppData is application-specific data that may be attached to any Animatable in the scene. With these APIs any 3ds max object (controller, object, node, modifier, material, etc.) can have custom data attached by other objects. These chunks are saved in the .MAX file and can be accessed through the object they are attached to.

The methods used to create AppData are from class Animatable. The data is accessed using three owner identifiers: The SuperClassID and the Class_ID of the owner, and a sub-index.

void AddAppDataChunk(Class_ID cid, SClass_ID sid,

 DWORD sbid, DWORD len, void *d);

This method is used to add an AppDataChunk to this Animatable. The chunk is identified using the Class_ID, and SuperClassID of the owner, and an ID for sub-chunks.

AppDataChunk *GetAppDataChunk(Class_ID cid, SClass_ID sid, DWORD sbid);

This method is used to retrieve a pointer to an AppDataChunk.

BOOL RemoveAppDataChunk(Class_ID cid, SClass_ID sid, DWORD sbid);

This method is used to delete an AppDataChunk.

Sample code using these APIs can be found in \MAXSDK\SAMPLES\UTILITIES\APPDATA.CPP.

Developers who have 3D Studio / DOS IPAS AppData associated with nodes being imported into 3ds max have APIs available in 3ds max to help process this imported data. AppData was used by IPAS plug-ins to store special data with nodes. This was used for example by IK and spline patches. These APIs allow a 3ds max plug-in to request incoming app data from an IPAS plug-in and use it. Plug-ins can register a callback that gets called when app data is loaded. The callback can then interpret the data and create a new object that will be used instead of the usual triangle mesh. For more details see Class ObjectDataReaderCallback.

Note: Although it is possible to hang AppData off the scene or the root node, that data won't be saved in the 3ds max file since the scene and the root node are not actually saved.

Custom Node Properties

Another type of data that may be attached to a node is referred to as a Custom Node Property. This data can be ASCII text, an integer value, a float value, or a BOOLean value. These values are stored and retrieved using a 'key' string. This is a string of any length -- the only limitation is the key string must not contains spaces, tabs or the equal sign (=) character.

To get and set specific data values developers may use the following methods of INode. These get and set values for ASCII strings, ints, floats, and booleans:

GetUserPropString(), SetUserPropString()

GetUserPropInt(), SetUserPropInt()

GetUserPropFloat(), SetUserPropFloat()

GetUserPropBool(), SetUserPropBool()

An end user may enter this data as well (in the 3ds max user interface it is referred to as a "User Defined Property"). Using the Object Properties dialog a user may enter text in the following format:

PropertyName=Property Value

The property name cannot have spaces within it, although a user can use spaces (and any other characters) anywhere outside the property name. The property name must appear at the start of the line (although it can be indented with spaces or tabs) and there can be only one property per line.

A developer may access the entire user-defined property text buffer if they wish to parse it themselves. The methods to do this are GetUserPropBuffer() and SetUserPropBuffer().

For reference information on these methods, see Class INode.

Saving Class Data

The following three methods of class ClassDesc may be used to save data associated with a class in a 3ds max file. This is appropriate for preference data and other similar information associated with a class. If you want to save data associated with the class have NeedsToSave() return TRUE and implement the Save() and Load() methods. See the Advanced Topics section on Loading and Saving for more details on the way data is written to and read from 3ds max files.

virtual BOOL NeedsToSave();

Returns TRUE if there is data associated with the class that needs to be saved in the 3ds max file. If this is so, implement the Save() and Load() methods below. If there is no class data to save, return FALSE.

virtual IOResult Save(ISave *s);

If NeedsToSave() returns TRUE then this method should be implemented to save the data associated with the class.

virtual IOResult Load(ILoad *l);

If NeedsToSave() returns TRUE then this method should be implemented to load the data associated with the class.

Note: One peculiarity with the loading and saving of the class data is that if the user does a File New or File Reset then the class data is not cleared.