Maya API How-To #20

Back · Previous · Next Maya

What are the advantages of using the API versus MEL?

The strongest motivation for using the API is speed. Alias suggests that, for the same work, a tool written using Maya's API will execute 10Ч faster than the equivalent instructions in MEL. This is not an exaggeration.

I recently wrote a tool to extract all of the per-polygon shading assignments for a scene and stream them to a text file. For a scene with 100000 polygons, the MEL script took over an hour to execute; the equivalent command performed by a plug-in took less than 10 seconds.

It took less time for me to write and execute a MPxCommand then for the MEL to finish!

Speed notwithstanding, MEL does have its restrictions, and some tasks you simply need to tackle from the API:

  1. Variable and optional command arguments. MEL procedures are dead simple to write, but are limited in the way they can handle arguments. If you declare a procedure to accept a string argument and an int argument, then that's what you need. No more, no less. The API's MSyntax class provides for conveniently defining an argument database, and allows both optional and multi-use flags.

  2. Defining a node. You cannot define a custom node type through MEL; you must use the MPxNode-derived classes in the API.

  3. Reading array attributes. A well-known limitation - you cannot query an array (e.g. '-dt "stringArray"') from MEL.

  4. Querying a componentListData attribute. It's possible (and common) to set an attribute of this type via MEL (Maya does this when you load a MayaAscii scene file, for instance), but it is not possible to query the component list on this plug. You must use the API's MFnComponentListData wrapper.

  5. Manipulators. If you wish to define your own manipulator for a tool or an attribute you must use the APIs MPxManipContainer. And it's not fun.

  6. Quaternion and matrix data types. It's possible to work with either of these in MEL, but you'll have to write your own math library in MEL to do it. The API conveniently provides MMatrix and MQuaternion classes. (Yes, I know MEL has a matrix datatype. I'm referring to actually doing something with the values once you have them stored.)

  7. Multi-dimensional arrays and data structures. Yes, MEL has array types and a triple-float vector type. Storing data in these types is convenient; however, managing data within these types quickly reveals limitations. For example, a task such as sorting two arrays and keeping the elements properly associated carries with it a lot of overhead in MEL. Pointers and containers available in C/C++ are much better suited to this task.

  8. Binary input and output. As an exercise I once tried to write a BMP image using MEL. In a word, painful. If you need to read or write binary data, save yourself the headache and go the plug-in route.

MEL To The Rescue

There are certain tasks for which you must use MEL, as there is no equivalent in the API:

  1. Any UI work. If you're building (or querying) windows, menus, layouts, buttons, shelves, what-have-you, MEL is the only mechanism available.

  2. User preferences. The optionVar interface is available only through MEL.

  3. Querying the current tool. There is no equivalent to 'currentCtx' within the API.

  4. Polygon operations. Thankfully they've finally added some of the more common polygon operations to Maya's API: subdivideFace and extrudeEdge, for example. Still, convenience operations such as polyMapCut, or polyMapMoveSew require that you call MEL (or write a helluva a lot of API code).

  5. Assigning/restoring the bind pose for a skeleton.

  6. Querying the default value for a dynamic attribute. The MEL query "addAttr -q -defaultValue $attr" carries no equivalent in the API.

  7. The API offers no convenient method for collapsing construction history, such as the "delete -ch" offered in MEL.

  8. The 'dgdirty' command. I haven't found an API equivalent for "dgdirty -all".

  9. Removing an unused array element from a multi attribute. Suppose, for instance, that you have multi attribute with connections on '.attr[0]', '.attr[1]' and '.attr[2]'. If you disconnect the input from '.attr[1]' you'll still have three elements in the array plug. The MEL command to clean up this unused index is "removeMultiInstance"; this action cannot be accomplished from the API. (A possible exception is for attributes on custom nodes which may be managed via disconnect behaviors or MArrayDataBuilder.)

  10. Duplicating a node. Maya's API offers no similar function to MEL's "duplicate", and the process for copying all attributes and data from one node to another would simply be an insane amount of work!

  11. Access to namespaces is not available in the API. You must use the two MEL commands "namespace" and "namespaceInfo".

  12. Access to project settings, as via the MEL "workspace" command, is not available in the API.

  13. Loading and unloading plug-ins. Ironically, the functionality available in the MEL commands "loadPlugin", "unloadPlugin" and "pluginInfo" are not available from the plug-in API.

  14. Sourcing MEL scripts. I've had little luck using MGlobal::sourceFile(), and have always resorted to calling MEL's "source" command via MGlobal::executeCommand().

Finally, there is one bonus for using MEL: Undo is free. The API allows you to manage your Undo, but it also requires that you manage your Undo.

Related How-To's

19 Dec 2004