Archive for May, 2010

Maya Scripting – Working with vectors in Python

Tuesday, May 4th, 2010

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