[Maya API C++] Convert Maya array to std::vector and back (e.g. MIntArray)


#1

Hey Guys,

I’m trying to convert an MIntArray as fast as possible to std::vector<int> and back.

Apparently the MIntArray has a get method so I can get the int array that is in the class. I should be able to use that to build the vector.

I was thinking something along the lines of:

Convert to std::vector


MIntArray mayaArray; // assume this was a filled MIntArray
int *intArray;
instancePolyConnections.get(intArray); 
   std::vector<int> myVec(intArray, intArray+(sizeof(int) * instancePolyConnections.length()));

Convert to MIntArray


std::vector<int> myVec; // assume this was a filled vector
MIntArray mayaArray(&myVec[0], myVec.size());

Yet both crash Maya and I have no clue on how to proceed and get this working.


#2

If you have a look at the documentation for MIntArray::get(int[]), it is performing a copy. Consequently it expects that the int[] c-style array is already initialized with ample space. In your code snippet, it is not initialized at all. You need to allocate that space first, then call get.

I’m not able to spot any problems with your second case apart from thinking the array is not actually filled as you think?


#3

Thanks for the quick reply.

The whole concept of pointers and how they allocate space for arrays in C++ is a bit of a hard concept for me. I guess I always staid far away from pointers, yet now is the time I should delve some deeper.

So, my brain is saying this should do the trick:

MIntArray mayaArray; // assume this was a filled MIntArray
 int *intArray = new int[mayaArray.length()];
 instancePolyConnections.get(intArray); 
 std::vector<int> myVec(intArray, intArray+(sizeof(int) * instancePolyConnections.length()));

And the back conversion should stay the same.

std::vector<int> myVec; // assume this was a filled vector
 MIntArray mayaArray(&myVec[0], myVec.size());

Can’t test this at the moment, should look into it now. :slight_smile: Would love to hear if someone has some extra pointers (or already notices that something is way off here.)

Edit: Would it actually be faster to extend C++ vectors instead of extending Maya Arrays? I have a loop where I get arrays all the time and need to append all the values (extending) to the one big array.


#4

Yes you can do it that way, but then you would also need to manage your memory usage and deallocate the intArray pointer that you created. Btw your notation is correct.

A better way to do this perhaps is to use the std::vector to allocate it for you. So you could do something like this:

MIntArray mayaArray; // assume this is filled
 std::vector<int> intArray;
 intArray.resize(mayaArray.length());
 mayaArray.get(&intArray[0]);

I haven’t tested this, but I think it should work. Basically it’s using the std::vector to allocate the space and then getting Maya to copy it directly into that C-style array, which is accessed by getting the address of the intArray’s first element.

Going back should be just as you have it:

std::vector<int> intArray; // assume this is filled
 MIntArray mayaArray(&intArray[0], intArray.size());

I don’t think there’s a huge performance gain to be had by performing your array extends on MIntArray or std::vector, but I haven’t profiled the two arrays themselves, so I can’t say for sure. I think it’s best to get the code working first. Test if the performance is actually a concern. Then if so, profile it to figure the exact bottleneck. My guess is that extending arrays is not your issue given the way these arrays dynamically allocate.


#5

Profiling the stuff in Maya is always a b*tch. :slight_smile:

Thanks for the tip, I think getting the pointer by using the vector is an extremely clever solution.

Just a quick follow-up, managing the memory myself would come down to:

delete [] myInt;

Right?

Really appreciate the help.

-Roy


#6

Profiling in Maya is no worse or better than profiling in most other API environments.
Build yourself boost chrono already and time your work if you have performance concerns (given Maya’s love for ancient compilers that have no C++11 stl).

In this specific case you look like you’re going after what you think would be an optimization on a gut feeling but without having actually profiled, timed or tested the case. It is very likely not going to net you much, if anything, or worse will result in a loss.

Vectors are extremely fast, when presized the difference between one and an array is practically insignificant.

In this case, just because MIntArray offers a C style array return you are assuming that copying the entire content of MIntArray to a C style array and then copying it again into a vector (no move semantics) will be a fast option. It likely won’t be, and it will cost a fair chunk of additional memory as you’d be copying a lot there.

I haven’t profiled MIntArray, but I have used it a fair bit, and I haven’t found it particularly slow, plus it has an [] accessor, so it doesn’t even hamper you syntactically.
Presize your vector and copy directly into it iterating MIntArray fetching through the accessor, and only then, if performance was unsatisfactory, then time it properly, and then try using an intermediate C style array.
I would be surprised though if it turned out to be any faster.

Don’t optimize early on a gut feeling and without having timed unless you have a borderline stellar knowledge of the domain. It’s pointless and hampers learning.


#7

Yes, that’s right. And I fully agree with everything Jaco wrote.


#8

Recently, I had to switch from MIntArray to vector<int> because I had such a huge array that the MIntArray crashed Maya. vector<int> just had no probem with that size.
Of course that data did not come from Maya, I simply used MIntArray for my own needs.


#9

Can I ask what qualifies as huge?
I’m currently tossing around some multi-million entries ones that shuttle back and forth to single and double indexed elements and I’ve had no crashes related to MIntArray.

It’s, not unexpectedly, fiddly the way any non boundary checked, non size checked arrays that offer direct mapping to a C-Style array are, but that’s 100% user dependent when it goes wrong.

Don’t get me wrong, I’m firmly in the camp of those favoring STL containers indiscriminately any and every time they fit nicely, but I can’t say MIntArray is broken. It’s a fairly primitive and long standing component.


#10

Sure, but I did not have look for its size. I talked about that with Haggi in the german maya-mentalRay forum. He mentioned his MintArray crashed at about 150 mio elements and I am sure my array had at least that size.
I had to give weights to locations on a mesh based on triangle size and vertex coloring.

So, why dont you just try the limit of MIntArray yourself.. However, funny to see theres a limit for the Maya int array :shrug:


#11

Sorry, I wasn’t challenging your observation, I was genuinely interested in hearing what it would have been where the object itself crashed and burned for you.

Hundreds of mills is an order I haven’t needed MIntArray in myself, so fair enough, and good to know actually (which is why I was asking).
I think the biggest I’m tossing around right now don’t make it to 15 mill entries.


#12

Uh, sorry myself. I did’t want to sound that way…
Thanks for your interest!


#13

This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.