I am working on a couple projects that require me to query vertex position data, which got me curious to what might be the fastest approach. I set up a little test and went through all the different python approaches to querying vertex data in Maya. The approaches consists off:
- Maya Python API 1.0
- Maya Python API 2.0
- Maya Cmds
The test results where more or less as expected, nothing new arose. But it is quite interesting to see how the different approaches are integrated with Maya and what this could imply for their usability. The test case is a polySphere smoothed 5 times which gives it:
- vertices’s: 399370
- edges: 798732
- faces: 399366
I also thought it would be sensible to make every approach structure the data in the same manner, which would possibly give it a bit more “real world” importance. Anyways, the data is structured so the first indices’s represents the vertex ID and the second level of indices’s represent the x, y,z of the vertex. If all the functions outputted to a variable called “vertexList” I could go:
to look at the position of the first vertex of the object queried. And go:
to retrieve the x value of the first vertex.
Maya Python API 1.0
Maya Python API 2.0
In the results for each approach you can see how many calls each method uses to finish the task. From the data you can see that Maya Cmds is written tightly to Maya’s command engine, but not as fast as API methods. And it’s clear that Pymel was never written for speed in mind, but for writing Maya scripts in an Object Oriented Programming fashion. Which makes it interesting with the introduction of Maya Python API 2.0, which is made more tightly integrated with the C++ API, using even less calls than the Maya Cmds module. And is used in a more true Pythonic way similar to Pymel just faster and the ability to write plugins with!
Here’s the code used for the test. It might not be the fastest way for each approach, in which I would’t mind a comment letting me know!
import maya.OpenMaya as om import maya.api.OpenMaya as om2 import maya.cmds as cmds import pymel.core as pm import cProfile """ A comparison of the different methods of retrieving vertex positions in Maya. Assuming that all approaches should behave in similar manner, which is: 1. You select your object 2. Run the function 3. receive a list where: - the index corresponds to vertex ID - within each index there's a list of the x,y,z coordinates of that vertex i.e. returnedList = [[x,y,z],[x,y,z],[x,y,z],...] test case: A standard polygon sphere, smoothed 4 times resulting in: verts: 399370 edges: 798732 faces: 399366 data collection: Using cProfile to run the different functions and receive their results. i.e cProfile.run('vertexCmds()') ############################# reproduce the test case: import maya.cmds as cmds cmds.polySphere() for i in range(5): exec "cmds.polySmooth()" """ def vertexOm1(): """ Using Maya Python API 1.0 """ #___________Selection___________ # 1 # initialize a selectionList holder selectionLs = om.MSelectionList() # 2 # get the selected object in the viewport and put it in the selection list om.MGlobal.getActiveSelectionList(selectionLs) # 3 # initialize a dagpath object dagPath = om.MDagPath() # 4 # populate the dag path object with the first object in the selection list selectionLs.getDagPath(0,dagPath) #___________Query vertex position ___________ # initialize a Point array holder vertPoints = om.MPointArray() # create a Mesh functionset from our dag object mfnObject = om.MFnMesh(dagPath) # call the function "getPoints" and feed the data into our pointArray mfnObject.getPoints(vertPoints) return vertPoints def vertexOm2(): """ Using Maya Python API 2.0 """ #___________Selection___________ # 1 # Query the selection list selectionLs = om2.MGlobal.getActiveSelectionList() # 2 # Get the dag path of the first item in the selection list selObj = selectionLs.getDagPath(0) #___________Query vertex position ___________ # create a Mesh functionset from our dag object mfnObject = om2.MFnMesh(selObj) return mfnObject.getPoints() def vertexCmds(): """ Using Maya Cmds """ #___________Selection___________ # query the currently selected object selTemp = str(cmds.ls(selection=True)) # edit retrieved string so we can feed it into commands sel = selTemp.split("'") #___________Query vertex position ___________ # use the xform command with the ".vtx[*]" to retireve all vertex positions at once vertPosTemp = cmds.xform(sel + '.vtx[*]', q=True, ws=True, t=True) # split the resulting list into sets of 3 vertPos = zip(*[iter(vertPosTemp)]*3) return vertPos def vertexPm(): """ Using Pymel """ #___________Selection___________ # use the ls command and "" to make sure we are using the first object sel = pm.ls(selection=True) #___________Query vertex position ___________ # use the .getPoints also found in openMaya, but here run through the pymel bindings return sel.getPoints(space='object') cProfile.run('vertexOm1()') cProfile.run('vertexOm2()') cProfile.run('vertexCmds()') cProfile.run('vertexPm()')