def OnInit(self): """Do our testing here...""" weird_value = -701496917 data = arrays.zeros((256, ), "i") for name in dir(GL): value = getattr(GL, name) if isinstance(value, constant.Constant): original_ord = glget.GL_GET_SIZES.get(value) data[:] = weird_value try: glGetIntegerv(value, data) except error.GLError, err: if err.err == 1280: #print "# No: %s"%(value.name,) pass else: print("_simple.%s: (1,), # TODO: Check size!" % (value.name, )) else: ordinality = 256 - arrays.sum((data == weird_value)) if ordinality == 16: ordinality = (4, 4) else: ordinality = (ordinality, ) if original_ord != ordinality: print("_simple.%s: %s, # %s" % (value.name, ordinality, original_ord)) else: pass
def OnInit( self ): """Do our testing here...""" weird_value = -701496917 data = arrays.zeros( (256,),'i') for name in dir( GL ): value = getattr( GL, name ) if isinstance( value, constant.Constant ): if value in glget.GL_GET_SIZES: continue data[:] = weird_value try: GL.glGetIntegerv( value, data ) except error.GLError, err: if err.err == 1280: print '# No: %s'%( value.name, ) else: print 'simple.%s: (1,), # TODO: Check size!'%( value.name, ) else: ordinality = 256 - arrays.sum( (data == weird_value) ) if ordinality == 16: ordinality = (4,4) else: ordinality = (ordinality,) print 'simple.%s: %s,'%(value.name,ordinality)
def OnInit(self): """Do our testing here...""" weird_value = -701496917 data = arrays.zeros((256, ), 'i') for name in dir(GL): value = getattr(GL, name) if isinstance(value, constant.Constant): if value in glget.GL_GET_SIZES: continue data[:] = weird_value try: GL.glGetIntegerv(value, data) except error.GLError, err: if err.err == 1280: print '# No: %s' % (value.name, ) else: print 'simple.%s: (1,), # TODO: Check size!' % ( value.name, ) else: ordinality = 256 - arrays.sum((data == weird_value)) if ordinality == 16: ordinality = (4, 4) else: ordinality = (ordinality, ) print 'simple.%s: %s,' % (value.name, ordinality)
def compile(self, mode=None): """Compile material information into readily-rendered format""" holder = mode.cache.holder(self, None) for field in protofunctions.getFields(self): # change to any field requires a recompile holder.depend(self, field) # def dl(): dl = displaylist.DisplayList() dl.start() try: alpha = 1.0 - self.transparency renderingData = zeros((4, 4), 'f') renderingData[:, 3] = alpha diffuseColor = self.diffuseColor.astype('f') renderingData[0, :3] = diffuseColor renderingData[1, :3] = self.emissiveColor.astype('f') renderingData[2, :3] = self.specularColor.astype('f') renderingData[3, :3] = (diffuseColor * self.ambientIntensity).astype('f') map(glMaterialfv, self.faces, self.datamap, renderingData) glMaterialf(self.faces[0], GL_SHININESS, self.shininess * 128) finally: dl.end() holder.data = dl return holder.data
def render ( self, visible = 1, # can skip normals and textures if not lit = 1, # can skip normals if not textured = 1, # can skip textureCoordinates if not transparent = 0, # need to sort triangle geometry... mode = None, # the renderpass object ): """Render the curve as a geometry node""" if not len(self.knot) and not len(self.controlPoint): return 0 nurbObject = gluNewNurbsRenderer() try: gluBeginSurface( nurbObject ); # do tessellation configuration here try: #self.renderProperties( nurbObject ) if len(self.color): color = arrays.zeros((len(self.color),4),'d') color[:,:3] = self.color gluNurbsCurve( nurbObject, self.knot, color, GL_MAP1_COLOR_4 ) if len(self.weight): points = arrays.zeros( Numeric.shape(self.controlPoint)[:-1]+(4,), 'd') points[:,:3] = self.controlPoint points[:,3] = self.weight type = GL_MAP1_VERTEX_4 else: points = self.controlPoint type = GL_MAP1_VERTEX_3 gluNurbsCurve( nurbObject, self.knot, points, type ) finally: gluEndSurface( nurbObject ); finally: gluDeleteNurbsRenderer( nurbObject )
def mesh_indices(zstep, ystep, xstep=1): # now the indices, same as all quadratics indices = zeros((zstep - 1, ystep - 1, 6), dtype='H') # all indices now render the first rectangle... indices[:] = (0, 0 + ystep, 0 + ystep + xstep, 0, 0 + ystep + xstep, 0 + xstep) xoffsets = arange(0, ystep - 1, 1, dtype='H').reshape((-1, 1)) indices += xoffsets yoffsets = arange(0, zstep - 1, 1, dtype='H').reshape((-1, 1, 1)) indices += (yoffsets * ystep) return indices
def test_matrix(self): """Test that a texture matrix can produce a proper scale/offset""" map = self.atlasManager.add(NumpyAdapter(zeros((64, 64, 4), 'B'))) matrix = map.matrix() assert matrix is not None bottom_left = dot(array([0, 0, 0, 1], 'f'), matrix) assert allclose(bottom_left, [0, 0, 0, 1]), bottom_left top_right = dot(array([1, 1, 0, 1], 'f'), matrix) assert allclose(top_right, [.25, .25, 0, 1]), top_right map = self.atlasManager.add(NumpyAdapter(zeros((64, 64, 4), 'B'))) matrix = map.matrix() assert matrix is not None bottom_left = dot(array([0, 0, 0, 1], 'f'), matrix) assert allclose(bottom_left, [.25, 0, 0, 1]), (bottom_left, matrix) top_right = dot(array([1, 1, 0, 1], 'f'), matrix) assert allclose(top_right, [.5, .25, 0, 1]), (top_right, matrix) set = dot(array([[0, 0, 0, 1], [1, 1, 0, 1]], 'f'), matrix) assert allclose(set, [[.25, 0, 0, 1], [.5, .25, 0, 1]]), (set, matrix)
def test_assignment(self): """Test that assignments go to the correct strips""" map = self.atlasManager.add(NumpyAdapter(zeros((64, 64, 4), 'B'))) assert len(self.atlasManager.components) == 1 assert len(self.atlasManager.components[4]) == 1 atlas = self.atlasManager.components[4][0] assert map.atlas is atlas assert len(atlas.strips) == 1, len(atlas.strips) # this one should pack into the same strip map = self.atlasManager.add(NumpyAdapter(zeros((64, 64, 4), 'B'))) assert len(self.atlasManager.components) == 1 assert len(self.atlasManager.components[4]) == 1 atlas = self.atlasManager.components[4][0] assert map.atlas is atlas assert len(atlas.strips) == 1, len(atlas.strips) # this one should pack into another strip map = self.atlasManager.add(NumpyAdapter(zeros((32, 32, 4), 'B'))) assert len(self.atlasManager.components) == 1 assert len(self.atlasManager.components[4]) == 1 atlas = self.atlasManager.components[4][0] assert map.atlas is atlas assert len(atlas.strips) == 2, len(atlas.strips)
def render( self, visible=1, # can skip normals and textures if not lit=1, # can skip normals if not textured=1, # can skip textureCoordinates if not transparent=0, # need to sort triangle geometry... mode=None, # the renderpass object ): """Render the curve as a geometry node""" if not len(self.knot) and not len(self.controlPoint): return 0 nurbObject = gluNewNurbsRenderer() try: gluBeginSurface(nurbObject) # do tessellation configuration here try: #self.renderProperties( nurbObject ) if len(self.color): color = arrays.zeros((len(self.color), 4), 'd') color[:, :3] = self.color gluNurbsCurve(nurbObject, self.knot, color, GL_MAP1_COLOR_4) if len(self.weight): points = arrays.zeros( Numeric.shape(self.controlPoint)[:-1] + (4, ), 'd') points[:, :3] = self.controlPoint points[:, 3] = self.weight type = GL_MAP1_VERTEX_4 else: points = self.controlPoint type = GL_MAP1_VERTEX_3 gluNurbsCurve(nurbObject, self.knot, points, type) finally: gluEndSurface(nurbObject) finally: gluDeleteNurbsRenderer(nurbObject)
def renderSurface( self, nurbObject ): """Render this surface""" ## XXX need to add weights # do tessellation configuration here controlPoint = arrays.reshape( self.controlPoint, (self.vDimension, self.uDimension, 3) ) if self.ccw: glFrontFace( GL_CCW ) else: glFrontFace( GL_CW ) if self.solid: glEnable( GL_CULL_FACE ) else: glDisable( GL_CULL_FACE ) try: vKnot = self.vKnot.astype( 'f' ) uKnot = self.uKnot.astype( 'f' ) if len(self.color): glEnable( GL_COLOR_MATERIAL ) color = arrays.zeros( (len(self.controlPoint),4), 'f', ) color[:,:3] = self.color.astype( 'f' ) color = arrays.reshape( color, (self.vDimension, self.uDimension, 4), ) gluNurbsSurface( nurbObject, vKnot, uKnot, color, GL_MAP2_COLOR_4 ) gluNurbsSurface( nurbObject, vKnot, uKnot, controlPoint, GL_MAP2_VERTEX_3, ) finally: glEnable( GL_CULL_FACE ) glFrontFace( GL_CCW ) return 1
def renderSurface(self, nurbObject): """Render this surface""" ## XXX need to add weights # do tessellation configuration here controlPoint = arrays.reshape(self.controlPoint, (self.vDimension, self.uDimension, 3)) if self.ccw: glFrontFace(GL_CCW) else: glFrontFace(GL_CW) if self.solid: glEnable(GL_CULL_FACE) else: glDisable(GL_CULL_FACE) try: vKnot = self.vKnot.astype('f') uKnot = self.uKnot.astype('f') if len(self.color): glEnable(GL_COLOR_MATERIAL) color = arrays.zeros( (len(self.controlPoint), 4), 'f', ) color[:, :3] = self.color.astype('f') color = arrays.reshape( color, (self.vDimension, self.uDimension, 4), ) gluNurbsSurface(nurbObject, vKnot, uKnot, color, GL_MAP2_COLOR_4) gluNurbsSurface( nurbObject, vKnot, uKnot, controlPoint, GL_MAP2_VERTEX_3, ) finally: glEnable(GL_CULL_FACE) glFrontFace(GL_CCW) return 1
def _partialSphere(cls, latsteps, longsteps): """Create a partial-sphere data-set for latsteps and longsteps returns (coordarray, indexarray) """ ystep = len(longsteps) zstep = len(latsteps) xstep = 1 coords = zeros((zstep, ystep, 8), 'f') coords[:, :, 0] = sin(longsteps) coords[:, :, 1] = cos(latsteps).reshape((-1, 1)) coords[:, :, 2] = cos(longsteps) coords[:, :, 3] = longsteps / (2 * pi) coords[:, :, 4] = latsteps.reshape((-1, 1)) / pi # now scale by sin of y's scale = sin(latsteps).reshape((-1, 1)) coords[:, :, 0] *= scale coords[:, :, 2] *= scale coords[:, :, 5:8] = coords[:, :, 0:3] # normals indices = mesh_indices(zstep, ystep) # now optimize/simplify the data-set... new_indices = [] for (i, iSet) in enumerate(indices): angle = latsteps[i] nextAngle = latsteps[i + 1] if allclose(angle % (pi * 2), 0): iSet = iSet.reshape((-1, 3))[::2] elif allclose(nextAngle % (pi), 0): iSet = iSet.reshape((-1, 3))[1::2] else: iSet = iSet.reshape((-1, 3)) new_indices.append(iSet) indices = concatenate(new_indices) return coords.reshape((-1, 8)), indices.reshape((-1, ))
def compile( self, mode=None ): """Compile material information into readily-rendered format""" holder = mode.cache.holder(self, None) for field in protofunctions.getFields( self ): # change to any field requires a recompile holder.depend( self, field ) # def dl(): dl = displaylist.DisplayList( ) dl.start() try: alpha = 1.0 - self.transparency renderingData = zeros( (4,4),'f') renderingData[:,3] = alpha diffuseColor = self.diffuseColor.astype( 'f' ) renderingData[0,:3] = diffuseColor renderingData[1,:3] = self.emissiveColor.astype( 'f' ) renderingData[2,:3] = self.specularColor.astype( 'f' ) renderingData[3,:3] = (diffuseColor*self.ambientIntensity).astype('f') map ( glMaterialfv, self.faces, self.datamap, renderingData ) glMaterialf( self.faces[0], GL_SHININESS, self.shininess*128 ) finally: dl.end() holder.data = dl return holder.data
class TestContext(BaseContext): """There is one new customization point used here: OnInit OnInit is called by the Context class after initialization of the context has completed, and before any rendering is attempted. Within this method, you'll generally perform your global setup tasks. We also see the use of the python imaging library for loading images, something which is obviously not seen in the original tutorial. Finally, this interpretation reorganizes the code to resemble more idiomatic python than the original code. """ initialPosition = ( 0, 0, 0 ) # set initial camera position, tutorial does the re-positioning FILTER_SIZE = 4 convolutionKernel = arrays.zeros( (4, 4, 4), 'f') + (1.0 / (FILTER_SIZE * FILTER_SIZE)) currentImage = 0 def OnInit(self): """Load the image on initial load of the application""" print("""Uses glConvolutionFilter2D to process the NeHe6 based image This convolution filter should produce a "blurring" effect on the image. The effect is applied on image upload (i.e. glTexImage2D call), so different images can have different convolutions applied. """) if not glInitImagingARB(): sys.exit(testingcontext.REQUIRED_EXTENSION_MISSING) self.imageIDs = [ self.loadImage(), self.loadImage(convolve=False), ] self.imageIndex = 0 print( '''Press 'c' to toggle between convolved and non-convolved image''' ) self.addEventHandler("keypress", name="c", function=self.OnConvolve) def OnConvolve(self, event): """Convolve (choose the other image) or disable convolution""" self.imageIndex += 1 if self.imageIndex % 2: print('Un-convolved image') else: print('Convolved image') def loadImage(self, imageName='nehe_wall.bmp', convolve=True): """Load an image file as a 2D texture using PIL This method combines all of the functionality required to load the image with PIL, convert it to a format compatible with PyOpenGL, generate the texture ID, and store the image data under that texture ID. Note: only the ID is returned, no reference to the image object or the string data is stored in user space, the data is only present within the OpenGL engine after this call exits. """ im = open(imageName) try: ix, iy, image = im.size[0], im.size[1], im.tobytes( "raw", "RGBA", 0, -1) except SystemError: ix, iy, image = im.size[0], im.size[1], im.tobytes( "raw", "RGBX", 0, -1) # generate a texture ID ID = glGenTextures(1) # make it current glBindTexture(GL_TEXTURE_2D, ID) glPixelStorei(GL_UNPACK_ALIGNMENT, 1) # copy the texture into the current texture ID if convolve: glEnable(GL_CONVOLUTION_2D) glConvolutionParameteri(GL_CONVOLUTION_2D, GL_CONVOLUTION_BORDER_MODE, GL_CONSTANT_BORDER) assert glGetConvolutionParameteriv( GL_CONVOLUTION_2D, GL_CONVOLUTION_BORDER_MODE, ) == GL_CONSTANT_BORDER, glGetConvolutionParameteriv( GL_CONVOLUTION_2D, GL_CONVOLUTION_BORDER_MODE, ) glConvolutionFilter2D(GL_CONVOLUTION_2D, GL_RGBA, self.FILTER_SIZE, self.FILTER_SIZE, GL_RGBA, GL_FLOAT, self.convolutionKernel) setFilter = glGetConvolutionFilter(GL_CONVOLUTION_2D, GL_RGBA, GL_FLOAT) #assert setFilter.shape == (4,4) #assert setFilter.dtype == self.convolutionKernel.dtype glTexImage2D(GL_TEXTURE_2D, 0, 3, ix, iy, 0, GL_RGBA, GL_UNSIGNED_BYTE, image) glDisable(GL_CONVOLUTION_2D) # return the ID for use return ID def Render(self, mode=0): """Render scene geometry""" BaseContext.Render(self, mode) glDisable(GL_LIGHTING) # context lights by default glTranslatef(1.5, 0.0, -6.0) glRotated(time.time() % (8.0) / 8 * -360, 1, 0, 0) self.setupTexture() self.drawCube() def setupTexture(self): """Render-time texture environment setup This method encapsulates the functions required to set up for textured rendering. The original tutorial made these calls once for the entire program. This organization makes more sense if you are likely to have multiple textures. """ # texture-mode setup, was global in original glEnable(GL_TEXTURE_2D) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST) glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL) # re-select our texture, could use other generated textures # if we had generated them earlier... glBindTexture(GL_TEXTURE_2D, self.imageIDs[self.imageIndex % 2]) # 2d texture (x and y size) def drawCube(self): """Draw a cube with texture coordinates""" glBegin(GL_QUADS) glTexCoord2f(0.0, 0.0) glVertex3f(-1.0, -1.0, 1.0) glTexCoord2f(1.0, 0.0) glVertex3f(1.0, -1.0, 1.0) glTexCoord2f(1.0, 1.0) glVertex3f(1.0, 1.0, 1.0) glTexCoord2f(0.0, 1.0) glVertex3f(-1.0, 1.0, 1.0) glTexCoord2f(1.0, 0.0) glVertex3f(-1.0, -1.0, -1.0) glTexCoord2f(1.0, 1.0) glVertex3f(-1.0, 1.0, -1.0) glTexCoord2f(0.0, 1.0) glVertex3f(1.0, 1.0, -1.0) glTexCoord2f(0.0, 0.0) glVertex3f(1.0, -1.0, -1.0) glTexCoord2f(0.0, 1.0) glVertex3f(-1.0, 1.0, -1.0) glTexCoord2f(0.0, 0.0) glVertex3f(-1.0, 1.0, 1.0) glTexCoord2f(1.0, 0.0) glVertex3f(1.0, 1.0, 1.0) glTexCoord2f(1.0, 1.0) glVertex3f(1.0, 1.0, -1.0) glTexCoord2f(1.0, 1.0) glVertex3f(-1.0, -1.0, -1.0) glTexCoord2f(0.0, 1.0) glVertex3f(1.0, -1.0, -1.0) glTexCoord2f(0.0, 0.0) glVertex3f(1.0, -1.0, 1.0) glTexCoord2f(1.0, 0.0) glVertex3f(-1.0, -1.0, 1.0) glTexCoord2f(1.0, 0.0) glVertex3f(1.0, -1.0, -1.0) glTexCoord2f(1.0, 1.0) glVertex3f(1.0, 1.0, -1.0) glTexCoord2f(0.0, 1.0) glVertex3f(1.0, 1.0, 1.0) glTexCoord2f(0.0, 0.0) glVertex3f(1.0, -1.0, 1.0) glTexCoord2f(0.0, 0.0) glVertex3f(-1.0, -1.0, -1.0) glTexCoord2f(1.0, 0.0) glVertex3f(-1.0, -1.0, 1.0) glTexCoord2f(1.0, 1.0) glVertex3f(-1.0, 1.0, 1.0) glTexCoord2f(0.0, 1.0) glVertex3f(-1.0, 1.0, -1.0) glEnd() def OnIdle(self, ): """Request refresh of the context whenever idle""" self.triggerRedraw(1) return 1
def Render(self, mode=None): if mode.visible and not self._rendered: self._rendered = True for char in self.testText: if not char in self.maps: dataArray, metrics = self.font.createCharTexture(char, mode=mode) dataArray = array(dataArray[:, :, 1]) dataArray.shape = dataArray.shape + (1, ) map = self.tc.getTexture(dataArray, texture.Texture) self.maps[char] = (map, metrics) atlas = self.atlas = self.maps.values()[0][0].atlas atlas.render() self.img = ImageTexture.forTexture(atlas.texture, mode=mode) self.shape.appearance.texture = self.img points = zeros((len(self.testText) * 6, 4), 'f') ll = 0, 0 for i, char in enumerate(self.testText): map, metrics = self.maps[char] # six points for each character... coords = map.coords() x, y = ll w, h = metrics.width / 20., metrics.height / 20. texcoords = array([ [coords[0][0], coords[0][1]], [coords[1][0], coords[0][1]], [coords[1][0], coords[1][1]], [coords[0][0], coords[0][1]], [coords[1][0], coords[1][1]], [coords[0][0], coords[1][1]], ], 'f') vertices = array([ (x, y), (x + w, y), (x + w, y + h), (x, y), (x + w, y + h), (x, y + h), ], 'f') j = i * 6 points[j:j + 6, 2:] = texcoords points[j:j + 6, :2] = vertices ll = (x + w, 0) self.vbo = vbo.VBO(points) self.shape.Render(mode=mode) if self.vbo is not None: glUseProgram(self.shader) self.vbo.bind() glActiveTexture(GL_TEXTURE1) glEnable(GL_TEXTURE_2D) # atlas.render() doesn't work here, need to fix that! self.img.render(visible=True, mode=mode) glUniform1i(self.atlas_loc, 1) # texture *unit* 0 glUniform3f(self.color_loc, 1.0, 0.0, 0.0) # texture *unit* 0 glEnableVertexAttribArray(self.coord__loc) glVertexAttribPointer(self.coord__loc, 2, GL_FLOAT, False, 4 * 4, self.vbo) glEnableVertexAttribArray(self.tex__loc) glVertexAttribPointer(self.tex__loc, 2, GL_FLOAT, False, 4 * 4, self.vbo + (2 * 4)) glDrawArrays(GL_TRIANGLES, 0, 6 * len(self.testText)) self.vbo.unbind() glDisableVertexAttribArray(self.coord__loc) glDisableVertexAttribArray(self.tex__loc) glUseProgram(0) glDisable(GL_TEXTURE_2D) glActiveTexture(GL_TEXTURE0)
def Render( self, mode=None ): if mode.visible and not self._rendered: self._rendered = True for char in self.testText: if not char in self.maps: dataArray, metrics = self.font.createCharTexture( char, mode=mode ) dataArray = array( dataArray[:,:,1] ) dataArray.shape = dataArray.shape + (1,) map = self.tc.getTexture( dataArray, texture.Texture ) self.maps[char] = (map,metrics) atlas = self.atlas = self.maps.values()[0][0].atlas atlas.render() self.img = ImageTexture.forTexture( atlas.texture, mode=mode ) self.shape.appearance.texture = self.img points = zeros( (len(self.testText)*6,4),'f') ll = 0,0 for i,char in enumerate(self.testText): map,metrics = self.maps[char] # six points for each character... coords = map.coords() x,y = ll w,h = metrics.width/20.,metrics.height/20. texcoords = array([ [coords[0][0],coords[0][1]], [coords[1][0],coords[0][1]], [coords[1][0],coords[1][1]], [coords[0][0],coords[0][1]], [coords[1][0],coords[1][1]], [coords[0][0],coords[1][1]], ],'f') vertices = array([ (x,y), (x+w,y), (x+w,y+h), (x,y), (x+w,y+h), (x,y+h), ],'f') j = i*6 points[j:j+6,2:] = texcoords points[j:j+6,:2] = vertices ll = (x+w,0) self.vbo = vbo.VBO( points ) self.shape.Render( mode = mode ) if self.vbo is not None: glUseProgram( self.shader ) self.vbo.bind() glActiveTexture(GL_TEXTURE1) glEnable( GL_TEXTURE_2D ) # atlas.render() doesn't work here, need to fix that! self.img.render( visible=True, mode=mode ) glUniform1i( self.atlas_loc, 1 ) # texture *unit* 0 glUniform3f( self.color_loc, 1.0, 0.0, 0.0 ) # texture *unit* 0 glEnableVertexAttribArray( self.coord__loc ) glVertexAttribPointer( self.coord__loc, 2, GL_FLOAT,False, 4*4, self.vbo ) glEnableVertexAttribArray( self.tex__loc ) glVertexAttribPointer( self.tex__loc, 2, GL_FLOAT,False, 4*4, self.vbo+(2*4) ) glDrawArrays(GL_TRIANGLES, 0, 6*len(self.testText)) self.vbo.unbind() glDisableVertexAttribArray( self.coord__loc ) glDisableVertexAttribArray( self.tex__loc ) glUseProgram( 0 ) glDisable( GL_TEXTURE_2D ) glActiveTexture(GL_TEXTURE0)
def test_release(self): map = self.atlasManager.add(zeros((64, 64, 4), 'B')) del map map2 = self.atlasManager.add(zeros((64, 64, 4), 'B')) assert map2.offset == (0, 0), map2.offset
def cone(cls, height=2.0, radius=1.0, bottom=True, side=True, phi=pi / 16, longAngle=(pi * 2), top=False, cylinder=False): """Generate a VBO data-set to render a cone""" tip = (0, height / 2.0, 0) longsteps = arange(0, longAngle + 0.000003, phi) ystep = len(longsteps) zstep = 0 if top and cylinder: zstep += 2 if side: zstep += 2 if bottom: zstep += 2 # need top-ring coords and 2 sets for coords = zeros((zstep, ystep, 8), 'f') coords[:, :, 0] = sin(longsteps) * radius coords[:, :, 2] = cos(longsteps) * radius coords[:, :, 3] = longsteps / (2 * pi) def fill_disk(area, ycoord, normal=(0, -1, 0), degenerate=1): """fill in disk elements for given area""" other = not degenerate # disk texture coordinates area[:, :, 1] = ycoord # x and z are 0 at center area[degenerate, :, 0] = 0.0 area[degenerate, :, 2] = 0.0 area[other, :, 3] = (sin(longsteps) / 2.0 + .5)[:area.shape[2]] area[other, :, 4] = (cos(longsteps) / 2.0 + .5)[:area.shape[2]] area[degenerate, :, 3:5] = .5 # normal for the disk is all the same... area[:, :, 5:8] = normal def fill_sides(area): """Fill in side-of-cylinder/cone components""" if not cylinder: area[0, :, 0:3] = (0, height / 2.0, 0) else: area[0, :, 1] = height / 2.0 area[1, :, 1] = -height / 2.0 area[0, :, 4] = 0 area[1, :, 4] = 1.0 # normals for the sides... area[0:2, :-1, 5:8] = vectorutilities.normalise( vectorutilities.crossProduct( area[0, :-1, 0:3] - area[1, :-1, 0:3], area[1, :-1, 0:3] - area[1, 1:, 0:3])) area[0:2, -1, 5:8] = area[0:2, 0, 5:8] offset = 0 tocompress = {} if top and cylinder: fill_disk(coords[offset:offset + 2], height / 2.0, (0, 1, 0), degenerate=0) tocompress[offset] = 0 offset += 2 if side: fill_sides(coords[offset:offset + 2]) offset += 2 if bottom: # disk texture coordinates fill_disk(coords[offset:offset + 2], -height / 2.0, (0, -1, 0), degenerate=1) tocompress[offset] = 1 offset += 2 # now the indices, same as all quadratics indices = mesh_indices(zstep, ystep) new_indices = [] for (i, iSet) in enumerate(indices): iSet = iSet.reshape((-1, 3)) if i in tocompress: if not tocompress[i]: iSet = iSet[::2] else: iSet = iSet[1::2] new_indices.append(iSet) # compress out degenerate indices if present... indices = concatenate(new_indices) return coords.reshape((-1, 8)), indices.reshape((-1, ))