This workshop is geared towards individuals wanting to learn how to extend and customize Maya with the Maya API. Individuals should have existing C++ and/or Python experience as well as an intermediate to advanced level of knowledge of Maya. A good understanding of Object Oriented Programming (OOP) is extremely helpful as the Maya API makes heavy use of OOP. You will not learn everything about the Maya API from this workshop. The purpose of this workshop is not to make you expert Maya programmers, but to give you a solid foundation from which to further your Maya API studies.
The techniques and code included in this workflow may not be perfect or accepted by elite Maya API programmers as the best way to utilize the API. The code and knowledge presented here is based off of my experience in creating dozens of nodes, deformers, and tool sets using the Maya API in both C++ and Python in the production of animated and effects heavy feature films a large studios. If you think something is incorrect, let me know. Maya API learning resources are limited so hopefully these notes will help you add to your tool set.
What is the Maya API?
The Maya API is a C++/Python API that lets programmers and scripters access the internal libraries of Maya. With the Maya API, programmers can customize Maya with new technology and create tools to help integrate the software into a studios production pipeline. Tasks written with the Maya API execute several times faster than the same tasks written in MEL.
What Can Be Implemented with the Maya API?
The Maya API is traditionally used to make plug-ins, which are dynamic libraries loaded by Maya at runtime. Plug-ins contain implementations of many different types of objects you want to add to Maya. When I refer to “objects” here, I am referring to objects in the Object Oriented Programming sense. The Maya API provides several base classes that programmers will inherit from and fill in the desired implementations. Some possible object types are:
- Rendering viewports.
- Texture baking engines.
- Particle and fluid emitters
- IK solvers
- Dependency nodes
- OpenGL locators
- File exporters
Starting with Maya 8.5, the Maya API became accessible via Python. With Python, not only can we make plug-ins as described above, but we can also access API commands in scripts, which adds a significant performance gain to existing toolsets.
C++ vs. Python
Plug-ins can be made with both C++ and Python. So which one should you use? Both are useful but there are situations where one should be used over the other.
Anything complex or that works with larger data sets like deformers should probably be made with C++ for speeds sake. For simple nodes that are not performance critical, Python works fine. Anything dealing with OpenGL such as viewports and locators should be made with C++ as I have seen significant slowdowns with Python implementations.
Also, some API calls in Python are a total pain syntax-wise because the API expects a lot of C++ pointers and references, which is wrapped with a very cryptic module in Python (MScriptUtil) which is not documented very well.
I have used both C++ and Python when developing plug-ins. When I am writing a new node, I sometimes start with Python to work out algorithm details. Since Python isn’t compiled like C++, the iteration time is faster. There’s also less of a chance to crash Maya with array index and memory errors.
Most of the time, I stick with C++ just because that is what the end product is going to be. However, I use the API a lot with Python in scripts so it is still worth learning. All the API calls are the same; it is just a difference in syntax.
Setting Up Your Development Environment
The first step in learning the API is setting up your build environment. The Maya API is packaged as a set of libraries that you will need to access. From the documentation, these libraries are:
- OpenMaya – Contains fundamental classes for defining nodes and commands and for assembling them into a plug-in.
- OpenMayaUI – Contains classes necessary for creating new user interface elements such as manipulators, contexts, and locators.
- OpenMayaAnim – Contains classes for animation, including deformers and inverse kinematics.
- OpenMayaFX – Contains classes for Autodesk Dynamics.
- OpenMayaRender – Contains classes for performing rendering functions.
If you are using Python, accessing these libraries is as simple as importing them into your code:
import maya.OpenMaya import maya.OpenMayaUI import maya.OpenMayaAnim import maya.OpenMayaFX import maya.OpenMayaRender
On Windows, the most common development environment for Maya plug-ins is Visual Studio. Setting up a development project is easy with the Maya Plug-in Wizard that ships with Maya. Installation and usage instructions for the wizard can be found in:MayaInstallDirectory\devkit\pluginwizard
The Wizard is limited to creating skeleton code for nodes and commands. However, you can use it to set up the proper library and directory settings. Without the Wizard, you will need to configure your project manually. The project should be a .dll project. You will need to specify where Visual Studio can access the libraries and header files. In the project properties, example settings are:
C/C++ > General > Additional Include Directories: C:\Program Files\Autodesk\Maya2010\include;
C/C++ > Preprocessor > Preprocessor Definitions: WIN32;NDEBUG;_WINDOWS;NT_PLUGIN;REQUIRE_IOSTREAM;
Linker > General > Output File: $(OutDir)\$(ProjectName).mll
Linker > General > Additional Library Directories: C:\Program Files\Autodesk\Maya2010\lib;
Linker > Input > Additional Dependencies: Foundation.lib OpenMaya.lib OpenMayaUI.lib OpenMayaAnim.lib OpenMayaFX.lib OpenMayaRender.lib Image.lib opengl32.lib
Additional settings may need to be tweaked depending on if you are developing for 32 or 64 bit Maya and if you are on a 32 or 64 bit machine.
Programmers using Linux are most likely experienced with setting up build environments. I would recommend using CMake to setup your build environment. Depending on your build environment, you will to ensure the linker can find the Maya include and lib directories.