Posted by Christopher Diggins, 9 June 2011 8:00 pm
Many 3ds Max customers have expressed an interest in writing Python scripts for 3ds Max that are compatible with CPython so that they can use some of the popular CPython specific extensions such as NumPy and SciPy, the Python Imaging Library, and cross-platform UI toolkits like PyQT.One solution that exists for running CPython scripts from 3ds Max that provides MAXScript interoperability is the Py3dsMax plug-in from Blur Studio. Currently only 3ds Max 2009 to 3ds Max 2011 are supported, but Blur say they are actively working on supporting 3ds Max 2012.
Py3dsMax is part of a large package of open-source tools and scripts from Blur available on Google project hosting that includes a redistribution of the PyQT cross-platform GUI library.
Installing Blur Tools and API
Before installing the blur tool set I strongly recommend that you carefully read the installation guide otherwise you risk installing twice (like I did). Even though the Blur tools comes with a self-installing package (MSI) the default locations provided by the installer will not work, and instructions provided during the installation process are minimal. Also not that despite giving you an option to provide paths the installer will still write a number of files to the hard-coded path “c:blur”.
Blur Dev Package Contents
The Blur package contains a lot of different tools and plug-ins used by Blur Studio. Some of the more noteworthy contents include:
The rest of this blog post focuses primarily on Py3dsMax and PyQT, but I recommend taking a hard look at the other tools to see if they are useful
Calling MAXScript from Python
Once installation is completed successfully the next time you start-up 3ds Max you should see a new menu-item called “Python” to the right of the “MAXScript” menu item. I suggest starting by choosing “Show logger…” which will open a nifty Python console with syntax coloring. From this point you can write commands to have executed by the Python interpreter. For example:
>>> 6 * 7
To interface with MAXScript you need to import the “mxs” class from the Py3dsMax module.
>>> from Py3dsMax import mxs
The “mxs” module provides access to all of the global functions and variables of MAXScript. For example to create a teapot in the scene try:
>>> teapot = mxs.Teapot()
To actually see the changes in the viewport you have to click anywhere on a viewport with your mouse or type:
Creating an object with named parameter is similar to MAXScript, for example:
>>> mybox = mxs.box( length = 20, width = 20, height = 20)
You can then change properties of the box easily:
>>> mybox.length = 70
Property values can be inspected using the Python logger as follows:
Changing the position of a box is more sophisticated: it requires that we create a new Point3 object and assign it to the position, as follows:
>>> mybox.position = mxs.Point3(20, 30, 50)
Rhe Py3dMax module does automatic conversion of Python primitive values to and from MAXScript values, but more complex MAXScript types like Point3, have to be explicitly created using the MAXScript global functions.
At first you may not realize it (I only discovered by accident) but the Python logger has two separate panes like the MAXScript listener. At the bottom of the logger window is a horizontal divider that can be dragged to expose a text editor to enter multiple lines of code without having them evaluated immediately. This is useful for defining functions or classes. You can run the code (or some selection of it) using the “Run” menu item.
There are a number of built-in functions defined in the Py3dsMax module:
Some caveats to using the Python logger:
mxs.getPropertyController( s.controller, "position" ).
Using the Generic Blur3d.API Module
Blur provides a module for working with some of the scripting API of both 3ds Max and Softimage in a generic way. While there are limitations, there are still some useful APIs exposed that emphasize pipeline specific tasks. This module was used to implement the generic Onion layer management tool provided by Blur (see the source code at C:blurdevofflinecodepythonlibblur3dguionion).
The following demonstrates how to access a generic scene object and set the name of an object in the scene, in a way that will work on both 3ds Max and Softimage.
>>> from blur3d.api import Scene
>>> scene = Scene.instance()
>>> objects = scene.objects()
>>> objects.setName( "Testing" )
The API comes with documentation accessible from the Blur IDE editor. When you open the Blur IDE Editor choose the “Help > SDK Help” menu item. This launches a tool called the SDK browser, which is similar to a compiled help module (CHM).The first time you run this tool you have to open the .SDK file found at: PYTHON_PATH/lib/site-packages/blurdev/resource/sdk/blurdev.sdk. After that you can browse documentation for many of the Python modules provided by Blur.
Using Python from MAXScript
In addition to allowing you to call MAXScript from Python Py3dsMax also allows Python to be called from MAXScript. From MAXScript a new global variable called “Python” gives access to Python modules. This variable in MAXScript provides four methods:
The following example MAXScript code show how you can retrieve Python documentation on a Python module using the Python inspect module:
inspect = python.import "inspect"
The following MAXScript code displays your system path using the Python sys module:
sys = python.import "sys"
How Py3dsMax Works
The Py3dsMax plug-in is a MAXScript extension plug-in (extension .DLX). It uses the MAXScript API of the 3ds Max SDK and the CPython extension API.
The blur package comes with all of the source code released under the GPL. In the source code is a file “wrapper.h” that provides a wrapper around the basic MAXScript value class (Value) to expose and a wrapper around the CPython object class (PyObject).
Building Common UIs with PyQt4
One problem faced by tool developers is creating UIs for multiple DCC tool. Ideally one could reuse the same UI code for each product. Blur has solved this problem by providing a single way to launch a GUI application independent of the host application. For example consider the following Python script:
from blurdev.gui import Dialog
def __init__( self, parent = None ):
Dialog.__init__( self, parent )
if ( __name__ == "__main__" ):
This same script can be run from within 3ds Max as an embedded application (using the Python > Run Script menu item) or as a standalone application (e.g. from the Python shell or by double clicking the file in Windows explorer). This assumes of course that you have Python and Blur properly installed.
PyQT is a third-party Python wrapper around the QT UI framework. Using PyQT and the blurdev.gui module allows tool writers to use the same QT interface regardless of the host application. Out of the box the Blur GUI framework works with 3ds Max and Softimage but has been used successfully with other applications (e.g. Maya).
Comparing Py3dsMax with MaxSharp and IronPython
Another approach to using Python with 3ds Max that I've discussed before is to use IronPython (the .NET implementation of Python) and a .NET wrapper around the 3ds Max SDK (such as MaxSharp). There are two main differences between Py3dsMax and using IronPython via MaxSharp.
Which one is better, depends on your needs and the expertise available in your studio. It is also worth noting that MaxSharp does not include an interactive Python console like is provided by blur studios with Py3dsMax.
Py3dsMax and the rest of the blur development package is a very useful set of tools for people interested in using Python (specifically CPython) from within 3ds Max. There are of course certain limitations (such as minimal documentation and some issues around usability and robustness) which one would naturally expect from a toolset developed primarily for in-house use. At the same time these tools have been used extensively in a production environment and are very sophisticated and useful.
I would appreciate hearing any feedback from other people who have used the Blur tools.
Please only report comments that are spam or abusive.