Class descriptors provide 3ds Max with information about each plug-ins that is implemented in a DLL, and allows 3ds Max to instantiate them. A plug-in will implement its own class descriptor by deriving from ClassDesc2 which in turn derives from ClassDesc.
3ds Max queries the DLL for the number of class descriptors contained in the plug-in using LibNumberClasses() and will retrieve them using LibClassDesc(). For more information see Required DLL Functions.
Here is an example of a plug-ins class descriptor:
class WidgetClassDesc : public ClassDesc2 { public: int IsPublic() { returnTRUE; } void* Create(BOOL loading = FALSE) { return new Widget(); } const TCHAR* ClassName() { return GetResourceString(IDS_CLASS_NAME); } SClass_ID SuperClassID() { return GEOMOBJECT_CLASS_ID; } Class_ID ClassID() { return Widget_CLASS_ID; } const TCHAR* Category() { return GetResourceString(IDS_CATEGORY); } // returns fixed parsable name (scripter-visible name) const TCHAR* InternalName() { return_T("Widget"); } // returns owning module handle HINSTANCE HInstance() { return hInstance; } };
The ClassDesc::IsPublic() member function returns a boolean value to indicate whether the plug-in should be exposed to the user through the 3ds Max user interface. If the plug-in can be selected by the user, as is usually the case, return TRUE otherwise return FALSE. The following code example demonstrates how a plug-in that is only intended for 3ds Max Design might prevent itself from being display in non-Design versions of 3ds Max.
int IsPublic() { return GetProductID() == k3dsMaxDesign ? 1 : 0; }
3ds Max calls the ClassDesc::Create() member function when it needs a pointer to a new instance of the plug-in class. For example, if 3ds Max is loading a file from disk containing a previously used plug-in (procedural object, modifier, controller, etc.), it will call the plug-in's ClassDesc::Create() member function. The plug-in responds by allocating a new instance of its plug-in class. Typically this would be done using the new operator.
The optional parameter passed to ClassDesc::Create() is a flag indicating if the class being created is going to be loaded from a disk file. If the flag is TRUE, the plug-in may not have to perform any initialization of the object because the loading process will take care of it. See the section on Loading and Saving for more information.
Some plug-ins allow the system to manage the creation process so their implementation of this member function simply returns NULL. This indicates to the system that it should invoke the default object creation process.
The ClassDesc::ClassName() member function returns the name of the class. This name appears in the button for the plug-in in the 3ds Max user interface.
The ClassDesc::SuperClassID() member function returns a system-defined constant describing the class that this plug-in class was derived from. For example, the Bend modifier returns OSM_CLASS_ID. This super class ID is used by all object space modifiers. Some other example super class IDs are: CAMERA_CLASS_ID, LIGHT_CLASS_ID, SHAPE_CLASS_ID, HELPER_CLASS_ID, and SYSTEM_CLASS_ID. See List of Super Class IDs for the entire list of available super class IDs.
The ClassDesc::ClassID() member function must return the unique ID for the plug-in object. A program is provided with the SDK called Gencid.exe to generate these IDs, to avoid conflicts with existing plug-ins. It is very important you use this program to create the class ids for your plug-ins.
Note: If you use one of the source code examples to create your plug-in, you MUST change the existing Class_ID. If you don't, you'll get a conflict. If two class IDs conflict, the system will only load the first one it finds (and will post a message when it attempts to load the second one noting that there is a Class_ID conflict).
A Class_ID consists of two unsigned 32-bit quantities. The constructor assigns a value to each of these, for example Class_ID( 0xA1C864D1, 0xE7AA2BE5). See theClass_ID documentation for reference information.
Note: sample code plug-ins used in 3ds Max use 0 as the second 32-bit quantity of the Class_ID. Only the built-in classes (those that ship with 3ds Max) should have the second 32 bits equal to 0 . All plug-in developers should use both 32 bit quantities.
The ClassDesc::Category() category is selected in the bottom-most drop down list in the create branch of the command panel. If this is set to be an existing category (i.e. "Standard Primitives", "Particle Systems", etc.) then the plug-in will appear in that category. Developers should not add to the categories provided by 3ds Max (see the note below). If the category doesn't yet exist then it is created. If the plug-in does not need to appear in the list, it may simply return an empty string as in _T(""). ClassDesc::Category() is also used for modifiers to classify them in the button sets dialog.
Note: The 3ds Max architecture has a limit of 12 plug-ins per category in the Create branch. To prevent a problem with too many plug-ins per category, developers should ALWAYS create a new Category for their plug-ins, rather than using one of the existing ones used by the standard 3ds Max plug-ins.