box_thumbnail

Manipulating Objects , Part 1

I’ve decided to do a series of posts, probably 7-8, focused on using Maya’s API to manipulate objects. I’ll cover a broad range of topics starting with getting the components of a poly shape and ending with animation. My hope is that this helps other Technical artists understand Maya’s API a little better. Now on to part one!

Lets start by creating a polygon object. To keep things simple we’ll make a cube. Initially I’m using Maya’s CMDS module, but later on I’ll be using the API to build our meshes. So we make a cube named Box.

Working with the API requires a healthy understanding of MObjects and MDagPaths. Read the official documentation. It does a great job explaining these. Also give this guy a read. It covers objects and function sets which we’ll get into shortly.

In order to get Box’s shape node we’ll need to first get it’s MDagPath. The shape node is the one underlined with the big red arrow pointing at it in the image below.

Box Shape Node

There are a couple ways to do this, but the easiest is to use MSelectionList and its member function getDagPath(). First the object’s name is added to the selection list. This is a zero based list similar to the one found in Python. That means since there is only one object added to the list that object’s index will be zero. We’ll pass this to getDagPath() along with instances of MDagPath and MObject. GetDagPath() will update both of these instances to point at Box’s MDagPath and MObject.

With an MDagPath we have access to and object’s DAG – it’s transforms and geometry. To get Box’s shape node we use MDagPath’s member function extendToShapeDirectlyBelow().

There are a few important features of this function. First, it doesn’t have a return value. Instead it updates our MDagPath variable such that it points at the desired shape node. Second, it takes an index of the shape node to get. This is because a transform node can have any number of shape nodes. In the case of Box I know it has only one which allows me to safely pass in the value zero. Dealing with multiple shape nodes requires a for loop and the member function numberOfShapesDirectlyBelow().

Having extended the MDagPath to the shape we can start getting information about the mesh, starting with the API type. Each node in Maya has an API type – the Maya Object type of the node. This type defines what a node does within the API system. We’ll be using the API type to make sure the correct function set is used on the shape node.

Testing the API type of a node requires it’s MObject. We can get this easily from the MDagPath by using the member function node().

MObject has two useful member functions, apiType() and apiTypeStr(). The first returns an INT which can be compared to MFn. Useful in code, but not great if you’re trying to figure out where the different node types appear. Fortunately apiTypeStr() is great for debugging since it returns a string name. With it you can easily find out what type of node you’re dealing with and which MFn enum to test against.

In Box’s case I know it’s a polygon which is type MFn::kMesh. Had I not known that I would have used apiTypeStr() to find out.

Now that we know the shape node is type kMesh what good does that do us? A quick search of Maya’s documentation reveals that the function set MFnMesh supports objects of type kMesh. MFnMesh allows us to construct and manipulate polygon objects. Basically the function set is a tools chest just waiting for something to work on. We can either use it to create something completely new (I’ll cover that in a later post) or change something that already exists. In our case we want to get information about Box. To do this we construct a copy of MFnMesh using the MDagPath to Box’s shape node as a parameter. Once done we can use the various member functions of MFnMesh to learn about Box’s polygons.

Want to know the number of vertices? The number of polygons?

How about each vertex’s position in world space?

This post already covers a fair bit so I’ll save plumbing the depths of MFnMesh for the next time.

Here’s the complete code.