http://code.google.com/p/glumpy/source/detail?r=6527672b4b73
Modified:
/demos/obj-viewer.py
=======================================
--- /demos/obj-viewer.py Thu Sep 15 06:33:36 2011
+++ /demos/obj-viewer.py Mon Oct 3 00:21:23 2011
@@ -33,40 +33,65 @@
import glumpy as gp
import OpenGL.GL as gl
-
def load_obj(filename):
- ''' Load vertices and face indices from a wavefront .obj file '''
-
- dt = np.dtype([('type', np.character, 1),('points', np.float32, 3)])
- data = np.genfromtxt(filename, dtype=dt)
-
- # Get vertices
- V = data['points'][data['type'] == 'v']
+ '''
+ Load vertices and faces from a wavefront .obj file and generate
normals.
+ '''
+ data = np.genfromtxt(filename, dtype=[('type', np.character, 1),
+ ('points', np.float32, 3)])
+
+ # Get vertices and faces
+ vertices = data['points'][data['type'] == 'v']
+ faces = (data['points'][data['type'] == 'f']-1).astype(np.uint32)
+
+ # Build normals
+ T = vertices[faces]
+ N = np.cross(T[::,1 ]-T[::,0], T[::,2]-T[::,0])
+ L = np.sqrt(N[:,0]**2+N[:,1]**2+N[:,2]**2)
+ N /= L[:, np.newaxis]
+ normals = np.zeros(vertices.shape)
+ normals[faces[:,0]] += N
+ normals[faces[:,1]] += N
+ normals[faces[:,2]] += N
+ L = np.sqrt(normals[:,0]**2+normals[:,1]**2+normals[:,2]**2)
+ normals /= L[:, np.newaxis]
# Scale vertices such that object is contained in [-1:+1,-1:+1,-1:+1]
- vmin, vmax = V.min(), V.max()
- V = 2*(V-vmin)/(vmax-vmin) - 1
-
- # Get indices
- I = data['points'][data['type'] == 'f']
- # Indices starts at one in .obj files but we want them to start at 0
- I -= 1
-
- return V.view([('position', np.float32, 3)]), I.astype(np.uint32)
+ vmin, vmax = vertices.min(), vertices.max()
+ vertices = 2*(vertices-vmin)/(vmax-vmin) - 1
+
+ return vertices, normals, faces
+
if __name__ == '__main__':
import sys
+
if len(sys.argv) < 2:
- print 'Usage: obj-viewer.py objfile'
- sys.exit()
-
- fig = gp.figure((512,512))
+ print 'Usage: obj-viewer.py objfile'
+ sys.exit()
+ vertices, normals, faces = load_obj(sys.argv[1])
+ V = np.zeros(len(vertices), [('position', np.float32, 3),
+ ('color', np.float32, 3),
+ ('normal', np.float32, 3)])
+ V['position'] = vertices
+ V['color'] = (vertices+1)/2.0
+ V['normal'] = normals
+
+ fig = gp.figure((300,300))
frame = fig.add_frame()
- vertices, indices = load_obj( sys.argv[1] )
- mesh = gp.graphics.VertexBuffer( vertices, indices )
- trackball = gp.Trackball( 65, 135, 1.0, 3.5 )
+ mesh = gp.graphics.VertexBuffer( V, faces )
+ trackball = gp.Trackball( 65, 135, 1.0, 2.5 )
+
+ @fig.event
+ def on_init():
+ gl.glLightfv (gl.GL_LIGHT0, gl.GL_DIFFUSE, (1.0, 1.0, 1.0, 1.0))
+ gl.glLightfv (gl.GL_LIGHT0, gl.GL_AMBIENT, (0.3, 0.3, 0.3, 1.0))
+ gl.glLightfv (gl.GL_LIGHT0, gl.GL_SPECULAR,(0.0, 0.0, 0.0, 0.0))
+ gl.glLightfv (gl.GL_LIGHT0, gl.GL_POSITION,(2.0, 2.0, 2.0, 0.0))
+ gl.glEnable (gl.GL_LIGHTING)
+ gl.glEnable (gl.GL_LIGHT0)
@fig.event
def on_mouse_drag(x,y,dx,dy,button):
@@ -85,12 +110,15 @@
gl.glEnable( gl.GL_POLYGON_OFFSET_FILL )
gl.glPolygonOffset (1, 1)
gl.glPolygonMode( gl.GL_FRONT_AND_BACK, gl.GL_FILL )
- gl.glColor( 1.0, 1.0, 1.0, 1.0 )
- mesh.draw( gl.GL_TRIANGLES )
+ mesh.draw( gl.GL_TRIANGLES, "pnc" )
gl.glDisable( gl.GL_POLYGON_OFFSET_FILL )
gl.glPolygonMode( gl.GL_FRONT_AND_BACK, gl.GL_LINE )
- gl.glColor( 0.0, 0.0, 0.0, 1.0 )
- mesh.draw( gl.GL_TRIANGLES )
+ gl.glEnable( gl.GL_BLEND )
+ gl.glEnable( gl.GL_LINE_SMOOTH )
+ gl.glColor( 0.0, 0.0, 0.0, 0.5 )
+ mesh.draw( gl.GL_TRIANGLES, "p" )
+ gl.glDisable( gl.GL_BLEND )
+ gl.glDisable( gl.GL_LINE_SMOOTH )
trackball.pop()
frame.unlock()