#! /usr/bin/env python """demonstration code for loading a collection of meshes from a vrml file, merging them into a single mesh, and displaying this mesh """ from OpenGLContext import glutinteractivecontext BaseContext = glutinteractivecontext.GLUTInteractiveContext from OpenGLContext.scenegraph.basenodes import * from OpenGLContext import visitor from vrml.vrml97 import nodetypes from numpy import * import scipy from scipy import random try: from OpenGLContext.loaders import vrml97 except ImportError, err: print """This demo requires the VRML97 loader""" in_sg = vrml97.load( "cornell_box.wrl") # derived class of the glutcontext, containing our scene # and timer callbacks class TestContext( BaseContext ): flip = 1 def OnInit( self ): """Initialize the scene, start the timer""" self.sg = out_sg def findShapes(sg): """ find all shape nodes, return the list of shape nodes and commulative transforms associated with these nodes""" paths_to_shapes = visitor.find(sg, (Shape,) ) # last elements of all paths are shapes = map( lambda x: x[-1], paths_to_shapes) transforms = map( lambda x: x.transformMatrix(), paths_to_shapes) return shapes, transforms def extractPolys(shapes, transforms): """ finds all indexed face sets in the list of shapes returns an Nx3 array of vertex coordinates and a list of integer arrays for faces extracting color information can be added here """ vertices = array([[0,0,0]]) faces = [] vertind_offset = 1 for (s,T) in zip(shapes,transforms): if isinstance(s.geometry,IndexedFaceSet): g = s.geometry # apply transformations to vertices to reduce everything to # a single coord. system # convert vertices to homogeneous coords (add 1 at the end), apply matrix # convert back (divide by the 4th component) # matrix is applied on the right, vectors are regarded as rows transf_vert = [ dot(concatenate( (x,[1]) ),T) for x in g.coord.point] transf_vert = [ x[:3]/x[3] for x in transf_vert] # add vertices to the global list, increment the offset in the # global vertex list by the # of vertices added vertices = concatenate((vertices,transf_vert)) fv_inds = arange(0,len(g.coordIndex)) # array of indices of -1's in coordIndex face_terminators = fv_inds[g.coordIndex == -1] # split the array after each -1 shape_faces = split( g.coordIndex, face_terminators+1) # if there is a terminating -1 some faces may be 0 length shape_faces = [x for x in shape_faces if len(x) > 0 ] # chop off -1's and add faces to the global list # add offset to all vertex indices faces = faces + map( lambda x: x[0:-1]+vertind_offset,shape_faces) vertind_offset += len(g.coord.point) return vertices,faces def testSceneGraph(V,F): """ for testing purposes, put together a single faceset """ coordidx = concatenate(map( lambda x: concatenate((x,[-1])),F)) sg = sceneGraph( children = [ Shape( geometry = IndexedFaceSet( coord = Coordinate( point = V, ), coordIndex = coordidx, color =Color( color = scipy.random.random( (len(V),3)) ), ), ), PointLight( location = (0,0,8), ), ], ) return sg if __name__ == "__main__": """Mainloop for the GLUT testing context""" from OpenGL.GLUT import glutInit, glutMainLoop # initialize GLUT windowing system import sys try: glutInit( sys.argv) except TypeError: import string glutInit( string.join(sys.argv, ' ')) # find all shapes shapes,transforms = findShapes(in_sg) # extract vertex and face arrays V,F = extractPolys(shapes,transforms) # reassemble them into a new scene graph out_sg = testSceneGraph(V,F) render = TestContext() # GLUT main loop does not return, so there seems to be no # way to exit back to the interpreter properly glutMainLoop()