• 1/3

25 things you probably didn't know about the 3ds Max SDK

Posted by Christopher Diggins, 8 June 2012 6:06 pm

25 things you probably didn't know about the 3ds Max SDK

I've adventured deep into the darkest corners of the 3ds Max SDK to bring you a set of largely unknown but useful tips and tricks.

  1. Use the 3ds Max SDK from MAXScript by loading the Autodesk.Max.dll. Add the following MAXScript to your start-up scripts and you can use the MaxGlobal variable to access the 3ds Max SDK.

    fn loadAutodeskMax = (
      local Assembly = dotNetClass "System.Reflection.Assembly"
      local maxroot = pathConfig.GetDir #maxroot
      Assembly.LoadFile (maxroot + "\Autodesk.Max.dll")
      local GlobalInterface = dotNetClass "Autodesk.Max.GlobalInterface"  
      global MaxGlobal = GlobalInterface.Instance
    )
    loadAutodeskMax ()
    
  2. Execute arbitrary MAXScript code using the ExecuteMAXScriptScript() global function (see the maxscriptmaxscript.h header).
  3. Execute code safely in the main thread in 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 as soon as 3ds Max is idle next.
    #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 ); }
  4. Work with different types of meshes ( Mesh, MNMesh and PatchMesh) using the ObjectWrapper class. This can simplify writing plug-in that have to deal with arbitrary mesh types such as modifiers.
  5. Collect notifications about all nodes in the scene in an efficient way using the ISceneEventManager class. It's ideal to use for UI refresh, when you need to monitor the scene for events to trigger a refresh.
  6. Output text to the 3ds Max MAXScript listener window (see the maxscriptmaxscript.h header) as follows:
      the_listener->edit_stream->wputs("Hello") 
      the_listener->edit_stream->flush()
    
  7. Execute a Python script from a .NET assembly with a few lines of code after downloading and installing IronPython
    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);
      }
    }
    
  8. Extend 3ds Max with new drag and drop functionality by deriving from the DragAndDropHandler class.
  9. Download a file from an arbitrary URL to disk using: IDragAndDropMgr::DownloadUrlToDisk().
  10. Compress data using the zlip compression library. Check out the zlibdll.h header file in the 3ds Max SDK.
  11. Log messages to the 3ds Max log file and even print out messages to Visual Studio console using LogSys class.
  12. Evaluate mathematical expressions stored as strings using the Expr class.
  13. Generate repeatable sequences of random numbers using the Random class.
  14. Store objects in one of the following container template types:
  15. Read and write Unicode files easily and correctly using the FileReaderWriter class.
  16. Compute the time it takes to complete a task using the Timer class.
  17. Automatically delete objects when you are done with them using the AutoPtr template.
  18. Output unobtrusive status messages to the user using the Interface::PushPrompt() function.
  19. Retrieve the user define UI colors using IColorManager.
  20. Launch a web browser using IBrowserMgr.
  21. Retrieve .MAX file properties using Interface11::OpenMaxStorageFile().
  22. Format a time value as a string using Interface10::FormatRenderTime()
  23. Open the windows explorer using Interface8::RevealInExplorer().
  24. Perform a quick render to a bitmap using Interface8::QuickRender()
  25. Execute code when 3ds Max is fully initialized in C#:
    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 
        } 
      } 
    } 
    

Special thanks to Michaelson Britt, Stephen Taylor, and David Cunningham for several of theses cool tips. Please share in the comments your favorite undocumented or frequently overlooked tips and tricks for using the 3ds Max SDK!

14 Comments

JokerMartini

Posted 9 June 2012 7:08 pm

I'm jumping into sdk stuff for max right now. What intro tutorials would you recommend me starting with to get a good grasp on c++ w/ max? I've become very familiar with maxscript as I've been doing it for over 5 years now.

On a side note I've recently come across the issue where my maxscript listener no longer records anything I do. Is there a fix to that?

Great blog, keep up the work. Thanks Christopher.

- John
- www.JokerMartini.com

lo_

Posted 10 June 2012 6:49 am

Really helpful list, thanks. One correction on the casing: it's ExecuteMAXScriptScript()
(uppercase MAX)

Christopher Diggins

Posted 11 June 2012 6:47 pm

@John Thanks for the kinds words. Can you please report the bug at: http://usa.autodesk.com/adsk/servlet/item?siteID=123112&id=12331406? For learning the 3ds Max SDK I recommend looking at 3ds Max SDK - The Learning Path.

@lo_ Thanks for the support and the correction. I made the change.

spacefrog

Posted 11 June 2012 7:30 pm

Hey John:
not really tutorials or such but a great resource of collected Max SDK knowledge. Just in case you did' know this forum ...

http://dl3d.free.fr/phpBB2/viewforum.php?f=3

And of course not to miss Dacid Lanier's free Book/PDF about Max SDK programming. Parts of it might be obsolete by now, but nvertheless a great read ..
http://dl3d.free.fr/resources/3DSMAX_SDK_DavidLanier.pdf

Jake Jeziorski

Posted 12 June 2012 8:36 am

Indeed very helpful. Hope there will be more to come.
Thank you very much.

JokerMartini

Posted 12 June 2012 8:58 pm

Thanks guys for the comments and guidance. I want to write a simple tool (for learning purposes) which would just reorder the selected objects based on the users "order method".

I want to write it in c++ and then make it a plugin for 3ds max.
I'll check out the SDK section which was mentioned above.
Where is the best community to post snippets and get feedback on developing these types of tools for max?

Klunk

Posted 18 June 2012 8:52 pm

number 6 doesn't compile as is, if you're going to post this sort of stuff do it properly. Glib little non compiling snippets are no good to anyone.

this however

#include "maxscrpt/maxscrpt.h"
#include "maxscrpt/Listener.h"

the_listener->edit_stream->wputs("Hello" ) ;
the_listener->edit_stream->flush();

should compile

Christopher Diggins

Posted 19 June 2012 5:31 pm

I've fixed the typo in number 6.

Klunk

Posted 20 June 2012 12:35 pm

cool, Sorry if i sounded a little short in the previous comment, trying to make a python script to check to see if max is running was doing my head in

Shawn Olson

Posted 3 October 2012 3:17 am

It would be great if we could get a series of articles/tutorials called The MAXScripter's Guide to the MAX SDK ... to help those of us (myself, John above, many many others) make the transition from MAXScript into the SDK. I'm finding there is very little to guide one in such a transition.

All info seems to assume knowledge of C++/C# ... and many of us have no real background in that. At the same time, a good transitional guide would help us get going faster and probably make it easier for us to absorb C++/C#.

Klunk

Posted 12 January 2013 9:45 pm

Number 6 doesn't work within dlx mxs exposure plugin, adding the include listener.h causes max to think the plugin should have the following exports LibNumberClasses and LibClassDesc.

Klunk

Posted 13 January 2013 7:23 am

sorry my bad, dlx plugins are quite sensitive to #include file order.

powernemo

Posted 24 April 2013 9:41 pm

Very nice stuff!
I have a question about ExecuteMAXScriptScript() if you don`t mind.
The third parameter is an IFPValue but is not clear how to obtain this from C#, I would like to get a return value from this :

var tp = IGlobal.ExecuteMAXScriptScript("Teapot()", true, «???»);

but all the usages I`ve seen in the SDK and your MaxSharp use "null" instead.
Thank you

MZ

Posted 8 March 2014 5:41 pm

Number 3 : "Execute code safely in the main thread in 3ds Max by either creating a Windows timer object using the main 3ds Max window as the window handle"

Can anyone show me an example of how we can use those functions to execute a maxscript?

Add Your Comment

You must be logged in to post a comment.

Please only report comments that are spam or abusive.