Tips and Tricks
This section contains a set of useful tips and tricks for working with the 3ds Max
SDK.
- Accessing the Parameter Block of Any Plug-in – If a plug-in does not explicitly provide access to its parameter blocks, you can
still access it by iterating over the references. The following returns a pointer
to the first parameter block of any plug-in:
- Referencing a Global Instance of a Non-plug-in Class – If a plug-in needs to contain some global instance that its member objects refer
to, but the plug-in itself is not of a specific type, then the super class ID of REF_TARGET_CLASS_ID can be used. The class of the global instance can be derived from ReferenceTarget.
- Executing Code in Main Thread – You can execute code safely in the main thread of 3ds Max by either creating a
Windows timer object using the main 3ds Max window as the window handle, or by using
the following function to trigger code when 3ds Max is next idle.
#define WM_TRIGGER_CALLBACK WM_USER+4764
void PostCallback( void (*funcPtr)(UINT_PTR), UINT_PTR param )
{
PostMessage( GetAppHWnd(), WM_TRIGGER_CALLBACK, (UINT_PTR)funcPtr, (UINT_PTR)param );
}
In .NET, the System.Windows.Dispatcher class can be used to achieve the same effect.
See MSDN ( ) for more information about this class.
- Executing a Python Script from a .NET Assembly – After downloading and installing IronPython, you can execute a Python script from
a .NET assembly with a few lines of code as follows:
using IronPython.Hosting;
using Microsoft.Scripting.Hosting;
public static void RunPythonFile(string filename) {
try {
var options = new Dictionary<string, object>();
options["Debug"] = true;
ScriptEngine se = Python.CreateEngine(options);
ScriptSource ss = se.CreateScriptSourceFromFile(filename);
CompiledCode cc = ss.Compile();
cc.Execute();
}
catch (Exception e){
MessageBox.Show("Error occurred: " + e.Message);
}
}
- Drag and Drop Functionality – You can extend 3ds Max with drag and drop functionality by deriving from the DragAndDropHandler class.
- Downloading from a URL – You can download a file referenced by a URL to disk using the IDragAndDropMgr::DownloadUrlToDisk() method.
- Compressing the Data – You can compress data using the zli compression library. See the zlibdll.h header file for more information.
- Logging Messages – You can log messages to a log file and print messages to the Visual Studio console
using the LogSys class. 3ds Max maintains a log file that contains the error, warning, information,
and debug messages generated by the system and plug-ins. The log file is placed in
the Network directory and is named Max.Log. The LogSys class is used for sending messages to the log.
- Evaluate Mathematical Expressions – You can evaluate mathematical expressions stored as strings using the Expr class. The expressions can consist of operators (+, -, *, /, and others), literal
constants (numbers like 180, 2.718, and others), variables (single floating point
values or vector (Point3) values), and functions (mathematical functions that take one or more arguments and
return a result). The return value from the expression might be a floating point value
or a vector. There are many built-in functions, operators and constants available
for use.
- Pseudo-random Number Generator – You can generate repeatable sequences of random numbers using the Random class. This class defines a pseudo-random number generator that precisely matches
the behavior of the MSVCRT 6.0 random routines.
- Container Templates – You can store objects in one of the following container template types: Stack, LinkedList, Array, and Tab.
- Reading and writing Unicode files – You can read and write Unicode files (see Unicode) easily and correctly using the FileReaderWriter class.
- Compute the Time to Complete a Task – You can compute the time taken to complete a task using the Timer class. The EndTimer method returns the time interval that has passed in milliseconds since the StartTimer method was used to start the timer.
- Automatically Delete the Allocated Objects when Done – Objects can be deleted automatically when you are done with them using the AutoPtr template. The object pointed to by the AutoPtr is deleted when the AutoPtr goes out of scope. AutoPtr helps prevent memory leaks and leads to exception safe code.
- Display Status Messages – You can display unobtrusive status messages to the user using the Interface::PushPrompt() function. See also Text Output to the MAXScript Listener Window.
- Custom Colors for UI Elements – You can add and retrieve user defined colors for the UI elements using the IColorManager class.
- Launch a Web Browser – You can use the IBrowserMgr class to launch a web browser.
- Access File Properties – You can retrieve the properties of a .MAX file using Interface11::OpenMaxStorageFile(). A max file is stored as a structured storage file and the property values can be
accessed through the standard structured storage property interfaces. See MSDN ( ) for more information about structured storage.
- Format a Time Value as a String – You can format a time value as a string using Interface10::FormatRenderTime().
- Open Windows Explorer – You can open the windows explorer to a specific folder or file path using Interface8::RevealInExplorer(). If the file path does not exist, a warning dialog appears and the Windows Explorer
is not opened. The Windows Explorer is independent of the calling application, which
means that it does not close when 3ds Max is closed.
- Quick Render – You can perform a quick render to a bitmap using Interface8::QuickRender().
- Execute Code in C# – You can execute code in C# after 3ds Max is fully initialized by registering a
callback with the notification listener as shown in the following example:
using ManagedServices;
public class My3dsMaxAssembly
{
public const int StartUpNotification = 0x50;
public static void AssemblyMain()
{
// This causes an event to be raised once the 3ds Max application has been started
var m = new MaxNotificationListener(StartUpNotification);
m.NotificationRaised += new EventHandler<MaxNotificationEventArgs>(AfterStartup);
}
public static void AfterStartup(object sender, MaxNotificationEventArgs e) {
if (e.NotificationCode == StartUpNotification) {
// Do whatever
}
}
}
-
Generate C++ Code from Mesh Data - If you create a mesh using 3ds Max and wish to capture the data as a sequence of
C++ instructions for manually constructing the mesh can be very time consuming if
the object contains a large number of vertices.
The MAXScript script found in the SDK under howto\objects\widget\mesh2cpp.ms can be used to write all the mesh generating instructing information to a header
(.h) file that you can include in your project. The script can be found Here is how
to use the script:
- Open the script and evaluate it. This will compile the script and create an action
entry in the 3dsmax action system.
- In the Customize > Customize User Interface ... dialog, look up the command Mesh2CPP
under the 'SDK Tools" category.
- Assign this command to a button or hotkey.
- Select your object in the viewport.
- Run the script. A Save As dialog will appear.
- Specify the header filename and select Save.
This will generate a header (.h) file that you can copy or include into the source
of your plug-in.