duberPython features demonstration!

loocas | 3ds Max,maxscript,Python,software,technical | Thursday, March 4th, 2010

duberPython banner

I’m trhilled to be able to finally showcase, at least, some of our very own Python implementation into 3ds Max!

First off, our primary reason for writing our own, proprietary, Python connection to 3ds Max is Tactic by Southpaw Technology. An awesome asset management system entirely written in Python that I decided to invest in and integrate our tools and software packages into. Another reason for this connection, later came up, was the need for writing much more complex scripts with complex GUIs, since, as you probably know, a few functional lines of code are hardly enough in a modern, efficient, VFX production of today. ;)

The heart of our Python integration is dotNET from Microsoft. I can’t express myself enough how much I appretiate this framework! The brain of our Python integration is IronPython. Also a product from Microsoft, completely open source and free, which are two very important aspects for any pipeline tool in any production facility of any size. Not the price as much as the availability of the software. And with IronPython and Microsoft, I am certain that this piece of software will be around for years!

So, what have we done?

  • We’ve developed a bridge that connects MAXScript and Python via dotNET.
  • The bridge converts most of native Python and MAXScript data types to and from one another.
  • We’ve implemented several, custom, methods in Python that allow us to directly communicate with 3ds Max via MAXScript.
  • We’ve also implemented error reporting so that when an error is thrown in Python, it’ll return the exception in MAXScript for debuging.
  • Everything is based on dotNET and written in C#.
  • The best part? Our Python bridge is completely platform and 3ds Max version independent!

Let me talk about the custom Python methods first. We’ve incorporated a class called mxsCon, that stores several methods for direct communication with 3ds Max as well as a variable
that stores passed arguments from MAXScript to Python for greater flexibility, especially when executing short code snippets.

The initial design meant to provide a way of directly running Python code from within MAXScript. However, with more complex tools needed nowdays, this proved to be insufficient and thus we’ve developed a way of executing more complex Python scripts written externally using IronPython. This works perfectly well if you plan on using 3ds Max’s interpreter and just want to pass values around MAXScript and Python. This is perfectly efficitent and enough for writing really complex tools based on Python. In our case, it’s the connection to Tactic.

However, later, it occured to me that since we have most of the hard work done, why not bring everything over to the Python side. Since Python is such a great and powerful language, why bother with MAXScript! So we developed another method for executing MAXScript code directly within Python scripts and have the result, evaluated in MAXScript, be passed back to Python. IronPython that is. Since all the value conversions had already been done, this proved to be an extremely powerful and efficient way of writing very complex tools, now even, with very complex GUIs. Since everything is based on dotNET, we can utilise IronPython and some of the IDEs available for super quick GUI development. I used SharpDevelop, an open source IDE for writing dotNET applications, for all my GUI and code stuff. Then I just hook up MAXScript commands that I pass Python values to in order to perform some actions in 3ds Max, like opening a file from our server stored in Tactic. Or, create objects and list them in a ListView. Or even write a direct 3ds Max – Maya translator! Why not? :)

Anyways, here are the methods and their purpose in 3ds Max:

  • Python.run( <string> ) — will execute a Python script wrapped in double quotes (effectively a string).

Example:

Python.run
(
	"import sys
	mxsCon.setResult( sys.version )"
)



In this case, Python.run() will return whatever the mxsCon.setResult() will pass to it (more on that later).

  • Python.runFromFile( <string> ) [ args:#() ] — will execute a Python script stored in an external file and alternatively pass it custom arguments.

Example:

Python.runFromFile @"C:\myPythonScript.py" args:#( 10., true, #(1,2,3), "some string" )



In Python, you’ll have to catch the passed arguments in order to use them, however the conversion of the data types will be done automatically for you.

  • Python.inspect( <data type> ) — this method will inspect what data type you passed to it and how it will convert it to Python.
  • Python.getError() — this method returns the last unhandled exception in Python code.
  • Python.setVerbosity( <int> ) — allows you to set the level of verbosity for error reporting.
  • Python.getVerbosity() — retreives the level of verbosity you currently use.
  • Python.resetPy() — a very useful method for resetting our bridge residing in memory in case you’ve changed something radical in the source code etc…

And here are the custom methods developed in C# for IronPython use in the scripts. These only exist when run via our Pythoner.dll module. If you run the Python scripts without Pythoner, you’ll have to handle their lack of presence. I’ve done this via a custom class that I import in the scripts I use. This is extremely flexible since when I run the code outside of 3ds Max, I can still use its functionality without having to deal with error handlers all over the place.

  • mxsCon.setResult( <data> ) # this method will return whatever it encapsulates directly to 3ds Max as well as in Python should you need to work with it later in the script.

Example:

import math

def myFunc( arg ):
	sum = arg + 100.
	return mxsCon.setResult( [arg, sum] )

if __name__ == '<module>':
	myFunc( math.pi )



The myFunc function will not only return a List of whatever you pass to it as well as the result of addition, but it’ll also pass this List directly to MAXScript for later use in 3ds Max.

  • mxsCon.getResult() # this method will only return the last value stored in memory using the .setResult() method. Useful for later usage in Python.
  • mxsCon.convert( <data> ) # this method will convert the input data types from Python to MAXScript compatible data types, but will return then wrapped as a string. This
    may be useful for other usage reasons. I used it for debugging or printing values in Python in MAXScript format.
  • mxsCon.execute( <data> ) # here’s where the magic happens. This method is quite complex. It not only evaluates whatever is passed to it in a String format, but it’ll also wait for the result from MAXScript and return it within Python. Another, very cool, feature of this method is similar to String formatting capabilities known from Python.

Some examples of the mxsCon.execute() method:

# assume here's a ton of complex Python code that invokes this method
returnedVal = mxsCon.execute( r'Box()' )
# will create a box in 3ds Max and return OK (converted to True) back to Python.

returnedVal = mxsCon.execute( r'getDir {0}', r'#scripts' )

The .execute method will first evaluate its input into a single string,
in this case: r’getDir #scripts’, in a similar fashion the .format method works in Python.
Then it’ll execute the command in MAXScript and retun its output back to Python.
The output, in this case, will be a string: ‘C:\Program Files\Autodesk\3ds Max 2009\scripts’

duberPython Features Demo

But, enought with the talk, see it for yourself in action in this short Windows.Forms demo. (clicking the image will take you to the video)

21 Comments »

  1. Hi,
    It looks really promising.
    I’m also looking into a way of making Max communicate with Python but deciding on a method thats relativly simple to implement ans easy to maintain is difficult.
    The .NET way seems to be a good solution to this.

    Will you be releasing the code to the public?
    i would love to play around with it.

    Best regards
    Rasmus

    Comment by Rasmus — May 3, 2010 @ 11:33

  2. Heya Rasmus,

    thanks for the heads up! :)
    As for a code release, well, I’m not really considering making our plugin an opensource project available to anyone, however, I am considering releasing the plugin as “closed-source” since it “just works” with any version of Max and any version of .NET, thus it doesn’t require us to maintain and update it as often as a regular Max plugin would. It’s more of a .NET plugin really, than a Max plugin.

    But, it seems to be working really awesome. I’m currently working on my first WPF project using IronPython, latest .NET libs, all developped in Visual Studio 2010 using the awesome GUI designer and bringing it all to 3ds Max!

    I love this technology! :D

    Comment by loocas — May 3, 2010 @ 12:43

  3. Sounds great :)

    Can you tell me what are the advantages and disadvantages of using .Net instead of a COM server for instance?

    Best
    Rasmus

    Comment by Rasmus — May 12, 2010 @ 11:30

  4. The difference between COM and .NET is HUGE! .NET is a whole framework. You can use the classes, objects and what not to build your feature rich applications in record time. While COM servers serve only as transport layers, not much into them, although very useful at times. These two technologies cannot be directly compared, actually. They serve a different purpose.

    Comment by loocas — May 12, 2010 @ 13:11

  5. Ok.
    I am currently trying desperately to get Max to retrieve data from an online project management system, using Maxscript > COM server > Python API > Webserver > Python API > COM server > Maxscript. But not succeeding. I think something along the COM server to Maxscript is acting up.
    Is this possible to solve more easily, elegantly or just to be solvable at all with Maxscript > .NET ?

    best
    Rasmus

    Comment by Rasmus — May 19, 2010 @ 08:07

  6. Rasmus,

    I’m not 100% sure, but I think you can do this via networking classes in .NET. I haven’t done this myself, so I’m not sure, but I’ve seen some pretty amazing stuff being done via this connection.

    Comment by loocas — May 19, 2010 @ 10:10

  7. The video link seems to be broken :(

    Comment by Matt Ostgard — July 14, 2010 @ 01:33

  8. Ah, shit!

    Thanks for pointing that out, Matt. I’m afraid my last FTP cleanup deleted more than I’d wished. :/

    I’ll do another video soon… stay tuned.

    Comment by loocas — July 14, 2010 @ 09:57

  9. An updated video has just been uploaded, Matt. Much shorter, but perhaps a bit more interesting ;)

    Comment by loocas — July 14, 2010 @ 11:54

  10. whaou, from a pure CG point of view, I can tell you that such a plugin, if any created object can be load into max from just a click, that would be first class plugin. I know nothing about programming but i’m really impress.

    Comment by lolo — August 27, 2010 @ 14:48

  11. Thanks,

    yeah, Pythoner is causing quite some buzz in the tech circles… so, who knows, we might even release the plugin to the public, soon… ;)

    Comment by loocas — August 28, 2010 @ 16:26

  12. uff, nice progress – looking forward about next informations

    Comment by martincg — September 17, 2010 @ 22:17

  13. Hi Duber,
    I tried to follow your example, then I could run external python file from maxscript. But when I click a button, I got a error message: global name ‘mxsCon’ is not defined
    It look like that I missed any dll file.
    I use max 2012 64bit, IronPython 2.7
    Please give me advice

    Comment by Batigol — May 2, 2011 @ 06:20

  14. Yes, you’re missing our Python plugin. :)

    Comment by loocas — May 2, 2011 @ 10:33

  15. if so, could you teach me which is missing?
    I also sent email to you yesterday. Please kindly help me.
    Thanks

    Comment by Batigol — May 3, 2011 @ 02:04

  16. Again, Batigol, you are missing our, proprietary, Python plugin, we developed specifically for my studio. It is not publicly available.

    Comment by loocas — May 3, 2011 @ 08:25

  17. oh :)
    That’s why I cannot find on anywhere. I also tried with blur-python. But it look like doesn’t support opensource anymore. Hope you will publish it soon.
    I will try it with socket :D
    Thanks

    Comment by Batigol — May 3, 2011 @ 11:39

  18. why brag about this shit when you don’t release it. how fucking lame.

    Comment by heh — May 15, 2013 @ 22:28

  19. I did release it, just not publicly. Yet. Pixomondo uses it, for example.

    Comment by loocas — May 23, 2013 @ 17:24

  20. Hello ,

    I have just started at a new studio that is forced to use Max2012 , Is there any chance I can use this software?

    Cheers

    Comment by Marco Vidaurre — February 4, 2015 @ 23:12

  21. Hi, yes, there is. But you’ll have to write me directly to my address: loocas@duber.cz

    Comment by loocas — February 11, 2015 @ 16:53

RSS feed for comments on this post. TrackBack URI

Leave a comment

Powered by WordPress | Theme by Roy Tanck