I avoided writing anything model-related in python for ages because I thought it didn’t have a native vector data type like MEL does. It doesn’t as it happens, but OpenMaya comes with one that is really simple to use and understand called: MVector.
Ryan Trowbridge has already gone over the basics of this on his blog, but I thought I’d cover it in a bit more detail, especially with some real-world examples.
The first thing you have to do is import the MVector class from the OpenMaya module:
from maya.OpenMaya import MVector
Once this is done you can start creating vectors like so:
X = MVector(1.0, 0.2, 0.3) Y = MVector(0, 1, 0)
The MVector simply takes 3 floats which represent the x, y and z components of the vector. You can’t, unfortunately, print out the MVector values by refering directly to it:
print X <maya.OpenMaya.MVector; proxy of <Swig Object of type 'MVector *' at 0x18b95ad0> >
but you can refer to the individual components:
print X.x # 1.0 print X.y # 0.2 print X.z # 0.3 print X.x, X.y, X.z # in one line # 1.0 0.2 0.3 mc.setAttr('pCube1.tx', X.x) # use as you would ordinary float variables
You can also do cool and useful stuff with the vectors very easily:
mag = X.length() # gets the vector magnitude(length) print mag # 1.06301458127 X = X.normal() # normalises the Vector Z = X^Y # the ^ character is a shortcut for the CrossProduct function d = X*Y # the * returns the dotProduct if both items are vectors Yb = Y*5.0 # but if one item is a single number it simply multiplies the vector print Yb.x,Yb.y,Yb.z # 0.0 5.0 0.0
If you want to capture command output into an MVector it’s just as easy as with MEL, you just have to add one minor addition, the * character:
V = MVector(*mc.pointPosition('pCube1.vtx[0]'))
The * character, in front of a list in python is kind of like shorthand for “unpack”. Because MVector expects 3 individual floats (doubles actually, but that’s splitting hairs!) you cannot legally pass it a list, even if the list is 3 elements long. The * tells the list to “unpack” itself into it’s constituent elements, so the MVector accepts it. This also holds true for anywhere in python where you need to pass a list in as individual params.
There’s a lot more you can do with MVectors, but I hope this basic stuff is enough to help you replicate what you can do with vectors in MEL. If you want to check out the more complex MVector methods and uses have a look in the Maya API – MVector docs
Great bit of info here, thanks!
That last example is particularly tasty 😀
Comment by Matt — May 18, 2010 @ 10:11 pm
Thanks :nathanN
I have just started making the switch to python so this will be very helpful.
Nice blog.
Comment by ronviers — June 13, 2010 @ 1:09 pm
Thanks very much for the tutorials that you’ve been showing at your site. Amazing content
…even newbie like me can understand your explanations! You you write a book I’ll buy it for sure!!!
Comment by Daniel — November 24, 2010 @ 1:40 am
hahah, thanks Daniel! I just wish I had the time and energy to put some more up here.
Comment by Naughty — November 24, 2010 @ 10:57 pm
Good post.
I was using numpy and pymel for this , but this is best solution.
Pymel is good but i’m really scared to using it , especially for some heavy computational stuff.
Numpy is good , but why use it when you have OpenMaya.
Btw i really need get myself familiar with api because there are some really nice stuff that are not exposed in mel.
Comment by ginoauri — May 7, 2011 @ 5:10 pm