3
votes

I want to copy a shape in Open GL with Maya Api, including normals. Let's take a cube as source shape.

Maya's MFnMesh::getPoints will return 8 points.
Maya's MFnMesh::getNormals will return 24 normals (3 normals per vertex, or 1 normal per vertex per face).

glDrawElements requires the list of vertices and the list of normals to correspond, which is not the case here. How can I align both lists so that glDrawElement is properly assigning normals to vertices ?

I believe that the vertices in the vertices list needs to be duplicated in order to become 24 points and the MFnMesh::getPolygonVertices need to point to the duplicated vertices. Any way to do this ?

1

1 Answers

5
votes

Vertex normals are not 1:1 with vertices: they are only 1:1 with vertex face vertices. Showing a hard edge requires maya to have two normal values for each of the vertices that define the edge. The more hard edges you have coming in to a given vertex, the more normals that vertex might support: it will always have at least one but can have as many as 1 normal per incoming edge. Your 24 normals reflect the fact they each cube vertex has 3 hard edges coming in

To get the normal correctly you should use vertex faces vertices, not plain vertices.

from maya.api.OpenMaya import MFnMesh, MGlobal, MSpace, MVector
mobj = MGlobal.getSelectionListByName('pCubeShape1').getDagPath(0)
mesh = MFnMesh(mobj)
space = MSpace.kWorld

def vertices_and_normals(mesh_fn, face, space):
    '''
    mesh_fn = an MFnMesh, face = an integer, space = an MSpace enum valu
    '''
    normals = [MVector(m) for m in mesh_fn.getFaceVertexNormals(face, space=space)]
    verts = [mesh_fn.getPoint(f, space=space) for f in mesh_fn.getPolygonVertices(face)]
    return zip(verts, normals)

for f in range(6):    
    for v, n in  vertices_and_normals(mesh,f, space):
        print "v", v, "n", n


v (-0.5, -0.5, 0.5, 1) n (0, 0, 1)
v (0.5, -0.5, 0.5, 1) n (0, 0, 1)
v (0.5, 0.5, 0.5, 1) n (0, 0, 1)
v (-0.5, 0.5, 0.5, 1) n (0, 0, 1)
v (-0.5, 0.5, 0.5, 1) n (0, 1, 0)
v (0.5, 0.5, 0.5, 1) n (0, 1, 0)
v (0.5, 0.5, -0.5, 1) n (0, 1, 0)
v (-0.5, 0.5, -0.5, 1) n (0, 1, 0)
v (-0.5, 0.5, -0.5, 1) n (0, 0, -1)
v (0.5, 0.5, -0.5, 1) n (0, 0, -1)
v (0.5, -0.5, -0.5, 1) n (0, 0, -1)
v (-0.5, -0.5, -0.5, 1) n (0, 0, -1)
v (-0.5, -0.5, -0.5, 1) n (0, -1, 0)
v (0.5, -0.5, -0.5, 1) n (0, -1, 0)
v (0.5, -0.5, 0.5, 1) n (0, -1, 0)
v (-0.5, -0.5, 0.5, 1) n (0, -1, 0)
v (0.5, -0.5, 0.5, 1) n (1, 0, 0)
v (0.5, -0.5, -0.5, 1) n (1, 0, 0)
v (0.5, 0.5, -0.5, 1) n (1, 0, 0)
v (0.5, 0.5, 0.5, 1) n (1, 0, 0)
v (-0.5, -0.5, -0.5, 1) n (-1, 0, 0)
v (-0.5, -0.5, 0.5, 1) n (-1, 0, 0)
v (-0.5, 0.5, 0.5, 1) n (-1, 0, 0)
v (-0.5, 0.5, -0.5, 1) n (-1, 0, 0)