Visualizing vertex positions and normals
This code example shows the following things:
- How to iterate over all objects in the scene
- How to iterate over mesh vertices and faces
- How to access primitive variables such as normals
- How to process the two storage types "varying" vs
"user"/"uniform int XYZfaces[3]"
- How to draw 3D marker and lines
The following script loads a scene and shows the vertices and normals of
every mesh in the scene. The vertices are displayed as blue markers
and the normals as lines.
Here is the script and a demo file (bunny.3ds) containing the
Stanford Bunny.
def showVertices(mesh):
"""Draw markers at the vertex positions of a triangle mesh.
"""
L = mesh.worldtransform
for v in mesh.verts:
drawMarker(L*v, size=0.07, color=(0,0,1))
def showNormals(mesh):
"""Draw the normals as lines.
A normal is drawn at every vertex position. The normals may either be
specified as "varying normal N" or as "user normal N"/"uniform int Nfaces[3]".
The actual drawing code is in showVaryingNormals() and showUserNormals().
"""
desc = mesh.findVariable("N")
if desc==None:
print 'Mesh "%s" has no normals set.'%mesh.name
return
name, storage_class, type, mult = desc
if storage_class==VARYING and type==NORMAL and mult==1:
showVaryingNormals(mesh)
elif storage_class==USER and type==NORMAL and mult==1:
desc = mesh.findVariable("Nfaces")
if desc==None:
print 'Mesh "%s" has no normal faces set.'%mesh.name
else:
name, storage_class, type, mult = desc
if storage_class==UNIFORM and type==INT and mult==3:
showUserNormals(mesh)
else:
print 'Mesh "%s": Invalid declaration of "Nfaces"'%mesh.name
else:
print 'Mesh "%s": Invalid declaration of variable "N".'%mesh.name
def showVaryingNormals(mesh):
"""Draw normals given as "varying normal N".
"""
L = mesh.worldtransform
L0 = L*vec3(0)
N = mesh.geom.slot("N")
for i,j,k in mesh.faces:
a = L*mesh.verts[i]
b = L*mesh.verts[j]
c = L*mesh.verts[k]
na = L*N[i]-L0
nb = L*N[j]-L0
nc = L*N[k]-L0
drawLine(a, a+na)
drawLine(b, b+nb)
drawLine(c, c+nc)
def showUserNormals(mesh):
"""Draw normals given as "user normal N"/"uniform int Nfaces[3]".
"""
L = mesh.worldtransform
L0 = L*vec3(0)
N = mesh.geom.slot("N")
Nfaces = mesh.geom.slot("Nfaces")
for face, Nface in zip(mesh.faces, Nfaces):
i,j,k = face
ni,nj,nk = Nface
a = L*mesh.verts[i]
b = L*mesh.verts[j]
c = L*mesh.verts[k]
na = L*N[ni]-L0
nb = L*N[nj]-L0
nc = L*N[nk]-L0
drawLine(a, a+na)
drawLine(b, b+nb)
drawLine(c, c+nc)
load("bunny.3ds")
listWorld()
for obj in scene.walkWorld():
if isinstance(obj.geom, TriMeshGeom):
print 'Creating vertex markers for "%s"...'%obj.name
showVertices(obj)
print 'Creating normal lines for "%s"...'%obj.name
showNormals(obj)
Back to the tutorial index