Making Maya’s Arrays more like STL

If you have written any Maya plugins in C++, you probably have used Maya’s built in array classes such as MIntArray or MPointArray. These are very simple and convenient classes to work with Maya’s API. However, they do not provide much support for more modern C++ features, such as generic programming. For example, if you wanted to sort a MIntArray you could do something like this:

This makes the assumption that the values are stored in a continuous section of memory which is a risk when using some other owner’s library. It is best to keep to the API that was provided to you.

What I want to share is my code that takes a step at bridging this gap. I will just go over the basics on usage and explanation, the rest you can figure out yourself as it is not that difficult to follow. You can grab a copy of these header files here: https://github.com/scottenglert/MayaAPIUtils

The first thing I wanted to tackle was creating a standard library iterator type that would allow easy iteration over a range of values in a Maya array. Here is an example of this with the same sorting over an integer array:

 

Notice there is an extra line that creates a MayaArrayRange with an existing MIntArray. This does not create a copy of the values, but instead makes a reference to this array so any changes to “myArrayRange” actually affect “myUnsortedArray”. The “begin()” and “end()” member functions create iterators that wrap around Maya’s array class (in this case MIntArray) and provide a safer way to iterate through a range while also being more understandable to the programmer.

One nice advantage is you can now take advantage for the new C++ 11 for loops so we can go from this:

To this:

This is the first part of bridging the gap between Maya and the standard library, but there is one more thing we can do to make Maya arrays even more like standard libraries containers, such the “vector” class.

So I will introduce the next class called “MayaArray” that is inside the maya_array.h header file under the maya_array directory in the GitHub page. This templated class is a replacement to Maya’s M***Array classes but still uses them underneath to be still compatible with Maya’s API. This gives the user a more standard library interface but without the copying of data to and from a Maya array. I find I rarely need to use Maya’s array classes after I have filled it with data from API and in some situations end up copying the data to a standard library container like “vector” so I can use other libraries or use templating features.

Here is an example of using this class that gathers all the points from a mesh:

What is happening is I am creating a generic MayaArray class that will use a MPointArray as the underlying container. I then pass a reference to this container into the “getPoints” member function of MFnMesh which fills the container with points.  Then I can take advantage of the class and use it like other standard library container classes, like using iterators (from above) and other member functions that are more flexible that Maya’s. You can look at all the member functions of the MayaArray class to see what it has in common with std::vector.

The biggest advantage is now you can write code that can work with either Maya’s arrays or from the standard library without writing it for each data type:

This means you can use this function with either the MayaArray with either MIntArray, MFloatArray, or MDoubleArray, even a standard library container, like “vector” without any special handling for either either case. This is what make templates powerful and saves you headaches of maintaining duplicate functions that operate of different types of containers.

The main purpose of writing this array class is to bring the two sides of Maya and the standard library closer together and more compatible so there is less need to copy data from one container to another which is a waste of time and memory.

Perhaps in the future Maya’s array classes will adapt to be more similar to the standard library, but for now this is a fairly simple implementation that works. More C++ features will be added once there is an API equivalent to use (cough, move semantics,  cough).

These two classes will be the bases for other utilities I hope to write and release to the public, so I hope it is of use to others out there as well.

Any feedback or questions are welcome!

About the author: Scott

Leave a Reply

Your email address will not be published.Email address is required.