[OpenMaya] :: MVector

I love math. Everything in life can change — your interests, your job, outside influences, but not math. Math never changes and I love about that very much.

Today, let’s go over why Maya’s MVector class object is so much fun: it’s a point in space (with a direction); we can add, subtract and multiply it against another MVector or a scalar value.

Right now, let’s deal with multiplying MVectors against scalar values.

Here we have two locators in space. Let’s have some fun with these two locators. First we will collect and manipulate information about these vectors using some Maya Python scripting. First, let’s show some code:

from maya.OpenMaya import MVector
from maya import cmds

class Vector(MVector):
    RESULT = ()

    def __init__(self, *args):
        super(Vector, self).__init__(*args)

    def do_division(self, amount=2.0):
        """
        divide the vector into sections.
        :param amount: <int> divide the vector by scalar amount.
        :return: <tuple> section vector.
        """
        self.RESULT = self.x / amount, self.y / amount, self.z / amount,
        return self.RESULT

    def do_multiply(self, amount=2.0):
        """
        multiply the vector by the amount.
        :param amount: <int> multiply the vector by scalar amount.
        :return: <tuple> section vector.
        """
        self.RESULT = self.x * amount, self.y * amount, self.z * amount,
        return self.RESULT

    def get_position(self):
        self.RESULT = self.x, self.y, self.z,
        return self.RESULT

    @property
    def result(self):
        return self.RESULT

    @property
    def position(self):
        return self.get_position()

def get_vector_position_2_points(position_1, position_2, divisions=2.0):
    """
    calculates the world space vector between the two positions.
    :param position_1: <tuple> list vector
    :param position_2: <tuple> list vector
    :param divisions: <int> calculate the vector by divisions.
    :return: <tuple> vector
    """
    positions = ()
    for i in xrange(1, divisions):
        vec_1 = Vector(*position_1)
        vec_2 = Vector(*position_2)
        new_vec = Vector(vec_1 - vec_2)
        div_vec = Vector(new_vec * (float(i) / float(divisions)))
        result_vec = Vector(*div_vec.position)
        positions += Vector(result_vec + vec_2).position,
    return positions

def get_vector_positon_2_objects(object_1, object_2, divisions=2):
    """
    calculates the world space vector between the two points.
    :return: <tuple> vector positions.
    """
    vector_1 = cmds.xform(object_1, ws=1, t=1)
    vector_2 = cmds.xform(object_2, ws=1, t=1) 
    return get_vector_position_2_points(vector_1, vector_2, divisions)

So this is a module I created for getting point positions between the two vectors. So let’s go through this step by step, in the get_vector_position_2_points function. Ignoring everything else but the math:

1.) we define the two vector positions.

2.) we subtract the first vector from the second to create a third vector at the origin.

3.) we loop through the number of divisions, dividing each number by the total number of divisions to give us the fraction that we can use to multiply with. (1/4, 2/4, 3/4, 4/4)

4.) we add the resultant origin vector by the second vector to place it relative to the second vector’s position.

5.) finally, we use this vector point to place our locators using the code below:

We are going to divide the space between the locators into 4 sections (divisions = 4). Let’s go into Maya and load up the script editor and paste this code there:

from maya_utils import math_utils
import maya.cmds as cmds
reload(math_utils)

positions = math_utils.get_vector_positon_2_objects('locator1', 'locator2', divisions=4)

for v_pos in positions:
    locator = cmds.createNode('locator')
    cmds.xform(object_utils.get_parent_name(locator), t=v_pos)

As we can see, between the locators, we have created four equal divisions, and have created the locators with the calculated positional vectors between the two original locators. This is useful in many of my rigging work, like creating springs, wires and folding wings.

It is important to be precise when creating any useful tool. So that we can eliminate any uncertainty in our work.

Leave a Reply

Your email address will not be published. Required fields are marked *