Dec 09

I answered a question about working with meshes using the python API on cgtalk and thought I would go more in depth on it.

First if you have not written anything using the API you need to know where the documentation is. If I tell you about a class and a function in that class you will only know about what I tell you and that is not very helpful. I looked on Autodesks website and found the latest documentation. This is for Maya 2009. Now there are changes between versions but the main reason for pointing you to this version is they reorganized the pages and added some new help. Also since this is how they will look from now on you should get familiar with it. The location of the docs are here:

Python Command
http://download.autodesk.com/us/maya/2009help/CommandsPython/index.html

Python API
http://download.autodesk.com/us/maya/2009help/API/main.html

Maya has two main ways to interact with it, using either Maya Commands or Maya API. Almost any time a MEL command is created it is also available to Python. There are some exceptions though. Autodesk did not make any of the string MEL commands available to Python because those are specifically made for MEL and do not apply to Python which already has a stronger suite of string functions. This also applies to the MEL commands that interact with your system like creating and reading files and printing to them.

Open up the Python API document and click on the Classes tab. This will show you all the classes available to you with C++ and Python. By default this tab shows the Alphabetical List. With this form of the documentation you also get the “Class List” tab which shows short descriptions of each class.

Today I will show how to get some information from a mesh. This Python script is using the API but a nice feature about Python is you do not need to create a Plugin to do this. It is fine to do so, but you dont have to like you do with C++. So even if you are writing a C++ plugin you could use Python just to quickly build up an idea of what your going to write just doing it in the script editor. No compiling!

Copy and paste this into a Python tab in your script editor and make sure to have a mesh selected so that it has something to work with:

# the OpenMaya module has many of the general Maya classes
# note that some Maya classes require extra modules to use which is noted in the API docs
import maya.OpenMaya as OpenMaya

# This shows how to use the MSelectionList and MGlobal class
# Get the selection and create a selection list of all the nodes meshes
selection = OpenMaya.MSelectionList()
OpenMaya.MGlobal.getActiveSelectionList( selection );

# Create an MItSelectionList class to iterate over the selection
# Use the MFn class to as a filter to filter node types
iter = OpenMaya.MItSelectionList ( selection, OpenMaya.MFn.kGeometric );

# This uses build in functions of the MItSelectionList class to loop through the list of objects
# Note this is not a basic array you must use its built in functions iterate on its objects
# Iterate through selection
while not iter.isDone():

	vertexList = []
	edgeList = []
	polytriVertsList = []
	polyList = []
	conpolyList = []

	# Get MDagPath from current iterated node
	dagPath = OpenMaya.MDagPath()
	iter.getDagPath( dagPath )

	# Get the selection as an MObject
	mObj = OpenMaya.MObject()
	iter.getDependNode( mObj )

	# This shows how to use the MItMeshPolygon class to work with meshes
	# Create an iterator for the polygons of the mesh
	iterPolys = OpenMaya.MItMeshPolygon( mObj )

	# Iterate through polys on current mesh
	while not iterPolys.isDone():

		# Get current polygons index
		polyList.append (iterPolys.index())	

		# Get current polygons vertices
		verts = OpenMaya.MIntArray()
		iterPolys.getVertices( verts )

		# Append the current polygons vertex indices
		for i in range( verts.length() ):
			vertexList.append (verts[i])

		# Get current polygons edges
		edges = OpenMaya.MIntArray()
		iterPolys.getEdges( edges )

		# Append the current polygons edge indices
		for i in range( edges.length() ):
			edgeList.append (edges[i])		

		# Get current polygons connected faces
		indexConFaces = OpenMaya.MIntArray()
		iterPolys.getConnectedFaces( indexConFaces )

		# Append the connected polygons indices
		for i in range( indexConFaces.length() ):
			conpolyList.append (indexConFaces[i])

		# Get current polygons triangles
		pntAry = OpenMaya.MPointArray()
		intAry = OpenMaya.MIntArray()
		space = OpenMaya.MSpace.kObject

		# Get the vertices and vertex positions of all the triangles in the current face's triangulation.
		iterPolys.getTriangles(pntAry, intAry, space)	

		# Append vertices that are part of the triangles
		for i in range( intAry.length() ):
			polytriVertsList.append (intAry[i])

		# Move to next polygon in the mesh list
		iterPolys.next()

	# print data for current node being iterated on
	print (dagPath.fullPathName()), '//////////////////////////////////'
	print 'Vertex list: ', vertexList
	print 'Edge list: ', edgeList
	print 'Poly Triangle Vertices: ', polytriVertsList
	print 'Polygon index list: ', polyList
	print 'Connected Polygons list: ', conpolyList

	# Move to the next selected node in the list
	iter.next()

Hope that helps,
-RyanT

9 Responses to “Maya Python API – Getting Mesh Data”

  1. Andy Seymour Says:

    Hi Ryan,

    Do you know why using OpenMaya.MSpace.kWorld instead of kObject would cause the script to fail?

  2. admin Says:

    Good question!

    I figured out the reason is you can initialize the MItMeshPolygon object with either a MObject or a MDagPath. If you want the OpenMaya.MSpace.kWorld you must give it a MDagPath and in my example I give it a MObject. Here is a code snippet that works for what you want:

    import maya.OpenMaya as OpenMaya

    selection = OpenMaya.MSelectionList()
    OpenMaya.MGlobal.getActiveSelectionList( selection );
    iter = OpenMaya.MItSelectionList ( selection, OpenMaya.MFn.kGeometric );

    while not iter.isDone():

    polytriVertsList = []

    dagPath = OpenMaya.MDagPath()
    iter.getDagPath( dagPath )

    mObj = OpenMaya.MObject()
    iter.getDependNode( mObj )

    iterPolys = OpenMaya.MItMeshPolygon( dagPath )

    while not iterPolys.isDone():

    pntAry = OpenMaya.MPointArray()
    intAry = OpenMaya.MIntArray()
    space = OpenMaya.MSpace.kWorld

    iterPolys.getTriangles(pntAry, intAry, space)

    # Append vertices that are part of the triangles
    for i in range( intAry.length() ):
    polytriVertsList.append (intAry[i])

    iterPolys.next()

    print ‘Poly Triangle Vertices: ‘, polytriVertsList
    iter.next()

  3. admin Says:

    Make sure to tab everything about the line:

    while not iter.isDone():

    Or you will get an error, and possibly lock up Maya. Posting code s a comment doesnt work very well I guess.

  4. bazuka Says:

    Hi Ryan,
    1st i’d like to say great tutorials for python

    and i/we would like to see more interesting tutorials for python (maya)

    so could u plz write some sample python plugin for mesh deformation? something like bend, sin deformation…

    cheers & thx

  5. tb Says:

    hi ,it’s very helpful!!,thank u so much .
    i have a question,how could i get dynField force at any given points position and how get field attributes value .cloud u show me the code?thanks

  6. admin Says:

    There is an example of how to work with a torusField by autodesk here:

    http://download.autodesk.com/us/maya/2009help/API/torus_field_8py-example.html

    I hope that helps.
    Ryan

  7. Matt Says:

    Some really great tutorials here, thanks for sharing. Hard to find resources for this, explained in a simple manner for beginners with the API.

    Can’t wait for the book!

  8. Joshua Says:

    I agree with Matt. When is the book coming out? Amazon says it will be available January 19 2011, but that day has come and gone. I can’t wait anymore!!

  9. admin Says:

    Amazon just has a placeholder release date, we will get it out as soon as possible.

Leave a Reply