Getting Started Writing Plug-ins

Introduction

This document reviews the structure of 3ds Max plug-ins and the interactions between 3ds Max software, the plug-ins and the user. The goal is to provide a clear image of the architecture of a plug-in in high level terms without getting into plug-in specific details. This document is written for C++ developers with no previous experience in writing 3ds Max plug-ins using the 3ds Max SDK. It is expected that the reader is already familiar with the basic features of 3ds Max.

What is a plug-in?

A plug-in is code and data that provide additional features or functionality to 3ds Max. There are many plug-ins shipped with 3ds Max whose functionality form the majority of the architecture and behavior of the final product. Examples of plug-ins are custom geometric objects, animation controllers, texture maps, materials and so on. We will explain here how a developer can create a plug-in to accomplish tasks by providing practical lessons on a few types of plug-ins and their features. You can refer to the topics Overview: Plug-ins and and Plug-in File Extensions in the Programmer's Guide for a complete review of 3ds Max plug-ins.

How 3ds Max recognizes your plug-ins

Programmers implement plug-ins in dynamic link libraries (DLLs). These DLLs include classes extended from one or more predefined base classes in the Max SDK, and override specific member functions according to their needs. At start up, 3ds Max attempts to load all DLL files located in certain 3ds Max installation subfolders (e.g. <3dsMaxInstallFolder>\plugins). A DLL will only load if it exports the required DLL functions mentioned below. These functions tell 3ds Max how many plug-ins are implemented in the DLL file, and return objects that both describe each of those plug-ins, and allow 3ds Max to instantiate from them.

What 3ds Max expects from your plug-in

Required DLL functions

In order for a DLL file to be loaded by 3ds Max it must implement certain functions. Common to any DLL, there must be a DLL entry point function (named DLLMain()). There are also at least four other functions required by 3ds Max. Three of them return basic information about the plug-in including: (1) the number of plug-in classes in the DLL, (2) the version of the 3ds Max SDK with which the plug-in has been compiled, and (3) a short string that gives the user an idea of what is contained in the DLL (e.g. what the included plug-in does).

The fourth function provides a mechanism with which the actual plug-in can be created (i.e. an object of our plug-in class can be instantiated) in 3ds Max. Once the plug-in is created using this function, 3ds Max will have specialized interfacing to the plug-in based on the plug-in type. This function is explained in more detail below in the Class Descriptors section.

Other than these four functions, without which your plug-in cannot be compiled, there are two other DLL functions needed for initializing and un-initializing the plugin. It is strongly recommended that you include these two functions in your DLL as well. The names and detailed descriptions of these functions are listed in the topic required DLL functions in the Programmer's Guide.

Class descriptors

Other than the main plug-in class, every plug-in project contains a class knows as the 'class descriptor'. The class descriptor has virtual member functions that provide information about the plug-in to 3ds Max. This information includes the class ID (explained below), category, and name. The class descriptor is usually derived from ClassDesc2, but can also be derived from ClassDesc.

An important task of the class descriptors is to implement a function (named Create()) that provides 3ds Max a pointer to an instance of the plug-in object. 3ds Max will use this pointer to access the plug-in’s properties and functionality. You can refer to its dedicated page in the programmer's guide for detailed information on the class descriptor.

Class ID

3ds Max recognizes plug-ins not by name but by ID. This means that two different plug-ins with the same name can co-exist as long as they have different IDs. On the other hand, if two plug-ins with different or the same name share the same ID, 3ds Max will load only one of them and will give a warning message regarding the conflict. This is because different developers might accidentally pick up the same names for their plug-ins, but it is practically impossible for them to pick up the same IDs since the ID consists of two random unsigned 32-bit numbers.

DEF Files

A .DEF file can be included in a DLL project to describe various attributes of the DLL such as the name and the order of the functions exposed in the DLL file. By listing the six mandatory plug-in functions in your .DEF file, you tell 3ds Max that the functions are implemented and are ready to be called. Although there are methods to load the plug-ins without including the .DEF file in the projects, we include it in the sample projects accompanying the lessons in this learning path to make them compatible with the plug-ins in the howto and samples sub-folders.

How to make your plug-ins do what you want

Based on their desired task, plug-ins can extend from many different base classes. The base class will outline the structure of your plug-in. Unlike a standalone application, your plug-in will not work by following a path from a start to end point in its code. Instead, it implements the member functions that are called by either 3ds Max, other plug-ins, or the plug-in itself at specific times or events. Each plug-in is extended from one or more 3ds Max predefined base classes. Each base class (and probably its parents) have a number of virtual methods that your plug-in must implement in order to become functional. Usually these are pure virtual functions. Additional optional virtual methods may be implemented depending on what your needs are, and these can improve the integration of your product with 3ds Max.