i also tried this, to get things per triangle, but it didnt seem to work, as im getting hte exact same resutls as i was before in getting information for 4 verts of hte quad not info for the triangles in the quad. it also prints out info for 14 faces and gives me this error as it tries to do more “Error: RuntimeError: (kInvalidParameter): No element at given index” test is a cube so it should olny give me 12.
It looks like you’re using the 2nd return value of getTriangles as a list of polygon ids when it’s actually a list of vertex ids for each triangle.
Parameters:
[out] triangleCounts The number of triangles for each polygon face
[out] triangleVertices The triangle vertex Ids for each triangle
So for a cube you’ll end up with something like:
triangleCounts: [2, 2, 2, 2, 2, 2]
triangleVertices: [0, 1, 2, 2, 1, 3, 2, 3, 4, 4, 3, 5, 4, 5, 6, 6, 5, 7, 6, 7, 0, 0, 7, 1, 1, 7, 3, 3, 7, 5, 6, 0, 4, 4, 0, 2]
Where each element in triangleCounts is the number of triangles in the polygon with the same index*. So [[0, 1, 2], [2, 1, 3]] are the vertex ids of the two triangles in the first polygon.
If you need to know which polygon and triangle the vert is from, you could group them into a nested list of vertex ids per-triangle, per-polygon with something like:
vertTriplets = zip(*[iter(triVerts)]*3)
start = 0
vertids = []
for num in triCount:
next = start + num
vertids.append(vertTriplets[start:next])
start = next
print vertids
# [[(0, 1, 2), (2, 1, 3)], [(2, 3, 4), (4, 3, 5)], [(4, 5, 6), (6, 5, 7)], [(6, 7, 0), (0, 7, 1)], [(1, 7, 3), (3, 7, 5)], [(6, 0, 4), (4, 0, 2)]]
So if I’m understanding what you’re after, something like this prints out Poly id, Triangle id, Vertex id, and the position and normal of each vertex.
import maya.OpenMaya as om
#get mSelection List
sel = om.MSelectionList()
om.MGlobal.getActiveSelectionList(sel)
#MItSelectionList iteritor for meshes
#filter with mfn class
iterMesh = om.MItSelectionList(sel, om.MFn.kGeometric)
triCount = om.MIntArray()
triVerts = om.MIntArray()
# selection iterator
while not iterMesh.isDone():
dagPath = om.MDagPath()
iterMesh.getDagPath(dagPath)
fnMesh = om.MFnMesh(dagPath)
fnMesh.getTriangles(triCount, triVerts)
# Zips the list of verts into triplets: [[0, 1, 2], [2, 1, 3],...]
vertzip = zip(*[iter(triVerts)]*3)
# Groups the triplets into n-length lists based on the number of tris per-poly from triCount
start = 0
vertids = []
for num in triCount:
next = start + num
vertids.append(vertzip[start:next])
start = next
for polyId, tris in enumerate(vertids):
print 'Poly id: %d' % polyId
for triNum, vertIds in enumerate(tris):
print 'Triangle: %d' % triNum
for vertId in vertIds:
print 'Vert id: %d ::' % vertId,
# make point var for pos, and get pos
vertPos = om.MPoint()
fnMesh.getPoint(vertId, vertPos)
# make vector var for normal and get normal
vertNrm = om.MVector()
fnMesh.getFaceVertexNormal(polyId, vertId, vertNrm)
# print out data
print 'POSITION:', vertPos.x, vertPos.y, vertPos.z,
print 'NORMAL:', vertNrm.x, vertNrm.y, vertNrm.z
iterMesh.next()
Maybe there’s a better way to do this… Haha, but it’s a start at least.
Also, if speed is an issue, don’t call MfnMesh.getPoint() on every vertex (it’s actually being called multiple times for the same vertices because triangles share verts), call MFnMesh.getPoints() and look up each vertex id by index in the returned MPointArray.
- The docs say that it “Returns the number of triangles for every polygon face”, so I’m making the assumption that it returns them in ID order, so that triCount[2] is the number of triangles for the polygon with an index of 2.