twitter youtube facebook linkedin email
Connect with:

Design Animation Stories

Creating Plug-ins That Work, Part 1

Drew
17 December, 2015

From the beginning, 3ds Max was designed to be extendable by users and developers outside of Autodesk.   One of the most popular ways to extend Max’s functionality is with plug-ins. Just about every facet of Max can be extended with plug-ins, from creating new modifiers and geometric primitives, to import and export formats, to the appearance of the viewport. This story will cover what you need to know to get set up and writing plug-ins. It is intended for C++ developers with no previous experience developing Max plug-ins. It assumes you have 3ds Max and the separate 3ds Max C++ SDK installed.

What is a plug-in?

But first, what exactly is a plug-in? A plug-in is code and data that provide additional functionality to 3ds Max. In fact, many of the existing features, such as geometric objects, animation controllers, texture maps and materials in 3ds Max are actually plug-ins. The source for many of these built-in features is available in the 3ds Max C++ SDK, under maxsdk/samples.

How Max recognizes your plug-ins

Plug-ins are compiled into dynamic link libraries (DLLs). At startup, 3ds Max attempts to load all DLLs located in specific directories (specifically, the <MaxInstall>\plugins directory). A DLL will only load successfully if it exports the functions mentioned below. These functions tell Max how many plug-ins are implemented in the DLL, and return objects that describe the plug-ins and allow Max to instantiate them.

What 3ds Max expects from your plug-in

In order for Max to load your plug-in, it has to export these functions:

  • DLLMain() – the entry point function
  • LibNumberClasses() – indicates the number of plug-ins the DLL contains
  • LibVersion() – indicates the version of the Max SDK with which the plug-in has been compiled
  • LibDescription() – returns a short string describing the plug-in
  • A plug-in creation function
  • LibInitialize() and LibShutdown() – functions to perform initialization and uninitialization (optional, but highly recommended)
  • LibClassDesc() – returns a class descriptor object for the plug-in class(es) exported by the DLL.

Your DLL project can include a module definition (.DEF) file that describes the names and order of functions exposed in the DLL. There are methods of loading plug-ins without using a .DEF file, but it is the recommended approach.

Now for the good news

For your first plug-in, you don’t need to worry about this, because the 3ds Plug-in Wizard will create a skeleton plug-in project in Visual Studio that already has all these functions defined and creates a .DEF file. In fact, for the majority of projects, you will want to start with an empty project created by the Plug-in Wizard. So let’s get started with that first.

Installing the Plug-in Wizard

Open the maxsdk\howto\3dsmaxPluginWizard\3dsMaxPluginWizard.vsz file with your favorite text editor.

Edit the ABSOLUTE_PATH parameter to reflect the actual location of the 3dsmaxPluginWizard root directory. Don’t add a backslash after the directory name.

Update the Wizard version to match the compiler you are using:

  • Visual Studio 2012 – 11.0
  • Visual Studio 2015 – 14.0

Note: check the system requirements help for the version of 3ds Max and the SDK you are using to see the appropriate compiler version to use.

 

Right-click the maxsdk/howto/3dsmaxPluginWizard directory, and make it writeable (clear the “Read Only” checkbox, and apply the change to all files and subdirectories).

Copy the following files from the 3dsmaxPluginWizard root to the “VC\vcprojects” (Visual Studio 2012) or “VC\vcprojectitems” (Visual Studio 2015) directory under your Visual Studio installation:

  • ico
  • vsdir
  • vsz

When you re-start Visual Studio and select File > New Projects > Visual C++ Projects, you should see the 3ds Max Plug-in Wizard project as an option.

image002

Hello World…

The first type of plug-in we’re going to build is a “Utility” plug-in. These plug-ins show up in the utility panel:

image004

This utility will print “Hello World” to the Max prompt bar.

To start, create a new 3ds Max Plugin Wizard project, and name it “HelloMax”.

In the next step, set the plug-in type to “Utility”. Effectively, this means the plug-in base class will be UtilityObj.

image006

In the next step, enter the name, category and description for your plug-in. These are arbitrary strings, you can enter whatever you like.

image008

The last page of the wizard asks for the path to three different folders. Enter the paths to the Max SDK, the output path (usually the plugins directory for your 3ds Max installation), and the location of 3dsmax.exe.

Click ok, and the wizard will create your project.

You’ll see several generated files, but we’re only concerned with HelloMax.cpp.

image010

We want to modify the HelloMax::BeginEditParams() function. This function is called when the plug-in is started, and usually adds the UI panel defined in the .rc file to the 3ds Max Utility panel as a rollout. When 3ds Max calls this function, it passes a pointer to the 3ds Max main interface, which we can use to call the Interface::PushPrompt() function on. Add the highlighted line to your BeginEditParams():

void HelloMax::BeginEditParams(Interface* ip,IUtil* iu)

{

this->iu = iu;

hPanel = ip->AddRollupPage(

hInstance,

MAKEINTRESOURCE(IDD_PANEL),

DlgProc,

GetString(IDS_PARAMS),

0);

 

ip->PushPrompt(_M("Hello World from a utility-plugin! Called from BeginEditParams()"));

}

However, this message will stay in the prompt area, even if another plug-in is selected. We need to pop the message from the prompt stack when the plug-in is not active anymore. We can use the UtilObj::EndEditParams() function for this purpose. This function is called by 3ds Max when the plug-in is deactivating. Add this code:

void HelloMax::EndEditParams(Interface* ip,IUtil*)
{
this->iu = nullptr;
ip->DeleteRollupPage(hPanel);
hPanel = nullptr;
ip->PopPrompt();
}

Build the project. Did you get a link error?

image012

Only release libraries are shipped in the 3ds Max SDK, so if you built the debug configuration (the default) you will get this error. Change the configuration to Hybrid and try building again.

Let’s see this thing work.

Start Max, and on the Utility panel, Click More… You should see HelloMax in the available utility list:

Click OK, and see the results of your first plug-in:

image016

Congratulations on creating your first plug-in.

In the next part of this series, we’ll create a plug-in that uses the 3ds Max reference system to get information about the scene graph.

Drew

Drew is a Learning Content Developer at Autodesk.

0 Comments

'