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:
IParamBlock2* GetParamBlock(ReferenceMaker* obj) {
int nRefs = obj->NumRefs();
for ( int i = 0; i < nRefs; ++i ) {
ReferenceTarget* ref = obj->GetReference(j);
if ( ref && ref->SuperClassID() == PARAMETER_BLOCK2_CLASS_ID ) {
returndynamic_cast<IParamBlock2*>( ref );
}
}
return NULL;
}
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.
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 Useful MAXScript Tips.
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:
This will generate a header (.h) file that you can copy or include into the source of your plug-in.