def __init__( self, sides, size, color, position = (0.0, 0.0, 0.0) ): self.sides = sides self.color = color self.size = size self.position = np.array(position) height = LEGO_BIG_HEIGHT if self.size else LEGO_SMALL_HEIGHT length = self.bottom - self.top combine = lambda _points, _vertices, _weights: _points self.__tess = GLU.gluNewTess() GLU.gluTessCallback(self.__tess, GLU.GLU_TESS_BEGIN, GL.glBegin) GLU.gluTessCallback(self.__tess,GLU.GLU_TESS_VERTEX,GL.glVertex3fv) GLU.gluTessCallback(self.__tess,GLU.GLU_TESS_COMBINE,combine) GLU.gluTessCallback(self.__tess, GLU.GLU_TESS_END, GL.glEnd) GLU.gluTessProperty(self.__tess, GLU.GLU_TESS_WINDING_RULE, GLU.GLU_TESS_WINDING_ODD) self.__gllist = GL.glGenLists(1) GL.glNewList(self.__gllist,GL.GL_COMPILE) GL.glColor3fv(self.color) GL.glBindTexture(GL.GL_TEXTURE_2D,0) GLU.gluTessNormal(self.__tess, 0.0, 1.0, 0.0) GL.glNormal3f(0.0, 1.0, 0.0) GLU.gluTessBeginPolygon(self.__tess,None) GLU.gluTessBeginContour(self.__tess) for i in range(0,len(self.coords)): vertex = (self.coords[i][0]*LEGO_GRID, height, self.coords[i-1][1]*LEGO_GRID) GLU.gluTessVertex(self.__tess, vertex, vertex) vertex = (self.coords[i][0]*LEGO_GRID, height, self.coords[i][1]*LEGO_GRID) GLU.gluTessVertex(self.__tess, vertex, vertex) GLU.gluTessEndContour(self.__tess) GLU.gluTessEndPolygon(self.__tess) for i in range(0,len(self.coords)): GL.glBegin(GL.GL_QUADS) sign = float(np.sign(self.sides[2*i-1])) GL.glNormal3f( sign, 0.0, 0.0 ) GL.glVertex3f( self.coords[i][0] * LEGO_GRID, height, self.coords[i-1][1] * LEGO_GRID) GL.glVertex3f( self.coords[i][0] * LEGO_GRID, height, self.coords[i] [1] * LEGO_GRID) GL.glVertex3f( self.coords[i][0] * LEGO_GRID, 0.0, self.coords[i] [1] * LEGO_GRID) GL.glVertex3f( self.coords[i][0] * LEGO_GRID, 0.0, self.coords[i-1][1] * LEGO_GRID) sign = float(np.sign(self.sides[2*i-2])) GL.glNormal3f( 0.0, 0.0, -sign ) GL.glVertex3f( self.coords[i-1][0] * LEGO_GRID, height, self.coords[i-1][1] * LEGO_GRID ) GL.glVertex3f( self.coords[i] [0] * LEGO_GRID, height, self.coords[i-1][1] * LEGO_GRID ) GL.glVertex3f( self.coords[i] [0] * LEGO_GRID, 0.0, self.coords[i-1][1] * LEGO_GRID ) GL.glVertex3f( self.coords[i-1][0] * LEGO_GRID, 0.0, self.coords[i-1][1] * LEGO_GRID ) GL.glEnd() GL.glTranslatef( self.left*LEGO_GRID + LEGO_GRID/2.0, (LEGO_BUMP_HEIGHT+height)/2.0 , self.bottom*LEGO_GRID - LEGO_GRID/2.0 ) for i in range( self.left, self.right ): for j in range( self.bottom, self.top ): GL.glTranslatef( 0.0, 0.0, LEGO_GRID ) if self.is_hit( (i+0.5,j+0.5) ): _caped_cylinder( LEGO_BUMP_RADIUS, height+LEGO_BUMP_HEIGHT, 32 ) GL.glTranslatef( 0.0, 0.0, length*LEGO_GRID ) GL.glTranslatef( LEGO_GRID, 0.0, 0.0 ) GL.glEndList()
def triangulate(loops: List[List[Vec]]) -> List[List[Vec]]: tessalator = glu.gluNewTess() vertices = [] def new_vertex(pos): vertices.append(pos[:2]) glu.gluTessProperty(tessalator, glu.GLU_TESS_WINDING_RULE, glu.GLU_TESS_WINDING_ODD) glu.gluTessCallback(tessalator, glu.GLU_TESS_EDGE_FLAG_DATA, lambda *args: None) glu.gluTessCallback(tessalator, glu.GLU_TESS_BEGIN, lambda *args: None) glu.gluTessCallback(tessalator, glu.GLU_TESS_VERTEX, new_vertex) glu.gluTessCallback(tessalator, glu.GLU_TESS_COMBINE, lambda *args: args[0]) glu.gluTessCallback(tessalator, glu.GLU_TESS_END, lambda: None) glu.gluTessBeginPolygon(tessalator, 0) for loop in loops: glu.gluTessBeginContour(tessalator) for point in loop: point = point[0],point[1], 0 glu.gluTessVertex(tessalator, point, point) glu.gluTessEndContour(tessalator) glu.gluTessEndPolygon(tessalator) glu.gluDeleteTess(tessalator) return [vertices[i:i+3] for i in range(0,len(vertices),3)]
def runGluTesselator(nodes): from OpenGL import GL from OpenGL import GLU shapes = [] vertexes = [] def begin(shape): assert shape == GL.GL_LINE_LOOP shapes.append([]) def vertex(vertex): if vertex is None: vertex = vertexes.pop() shapes[-1].append(vertex) def error(args): print "error", args def combine(coords, vertex_data, weight, theTuple): vertexes.append(coords) return coords #def end(*args, **kwargs): # pass tess = GLU.gluNewTess() GLU.gluTessCallback(tess, GLU.GLU_TESS_BEGIN, begin) GLU.gluTessCallback(tess, GLU.GLU_TESS_VERTEX, vertex) GLU.gluTessCallback(tess, GLU.GLU_TESS_COMBINE_DATA, combine) GLU.gluTessCallback(tess, GLU.GLU_TESS_ERROR_DATA, error) #GLU.gluTessCallback(tess, GLU.GLU_TESS_END_DATA, end) GLU.gluTessProperty(tess, GLU.GLU_TESS_WINDING_RULE, GLU.GLU_TESS_WINDING_NEGATIVE) #GLU.gluTessProperty(tess, GLU.GLU_TESS_WINDING_RULE, GLU.GLU_TESS_WINDING_NONZERO) GLU.gluTessProperty(tess, GLU.GLU_TESS_BOUNDARY_ONLY, GLU.GLU_TRUE) GLU.gluTessProperty(tess, GLU.GLU_TESS_TOLERANCE, 1.0 / 2048.0) GLU.gluTessNormal(tess, 0.0, 0.0, 1.0) GLU.gluBeginPolygon(tess, None) def tweaked(p): return (int(p.x() * 1024) / 1024.0, int(p.y() * 1024) / 1024.0, 0) for n in nodes: GLU.gluTessVertex(tess, (tweaked(n.start)), (n.start.x(), n.start.y())) GLU.gluEndPolygon(tess) res = [] for s in shapes: nodes = [] for i in range(len(s)): p1 = s[i] p2 = s[(i + 1) % len(s)] nodes.append( DrawingLine(QPointF(p1[0], p1[1]), QPointF(p2[0], p2[1]))) res.append(DrawingPolyline(nodes)) return res
def _triangulate(self, looplist, fill_rule): if self.shape in ['line']: return None t_list = [] self.ctx_curr_shape = [] spare_verts = [] tess = glu.gluNewTess() glu.gluTessNormal(tess, 0, 0, 1) glu.gluTessProperty(tess, glu.GLU_TESS_WINDING_RULE, glu.GLU_TESS_WINDING_NONZERO) def set_tess_callback(which): def set_call(func): glu.gluTessCallback(tess, which, func) return set_call @set_tess_callback(glu.GLU_TESS_VERTEX) def vertex_callback(vertex): self.ctx_curr_shape.append(list(vertex[0:2])) @set_tess_callback(glu.GLU_TESS_BEGIN) def begin_callback(which): self.ctx_tess_style = which @set_tess_callback(glu.GLU_TESS_END) def end_callback(): if self.ctx_tess_style == gl.GL_TRIANGLE_FAN: c = self.ctx_curr_shape.pop(0) p1 = self.ctx_curr_shape.pop(0) while self.ctx_curr_shape: p2 = self.ctx_curr_shape.pop(0) t_list.extend([c, p1, p2]) p1 = p2 elif self.ctx_tess_style == gl.GL_TRIANGLE_STRIP: p1 = self.ctx_curr_shape.pop(0) p2 = self.ctx_curr_shape.pop(0) while self.ctx_curr_shape: p3 = self.ctx_curr_shape.pop(0) t_list.extend([p1, p2, p3]) p1 = p2 p2 = p3 elif self.ctx_tess_style == gl.GL_TRIANGLES: t_list.extend(self.ctx_curr_shape) else: self._warn("Unrecognised tesselation style: %d" % (self.ctx_tess_style,)) self.ctx_tess_style = None self.ctx_curr_shape = [] @set_tess_callback(glu.GLU_TESS_ERROR) def error_callback(code): ptr = glu.gluErrorString(code) err = '' idx = 0 while ptr[idx]: err += chr(ptr[idx]) idx += 1 self._warn("GLU Tesselation Error: " + err) @set_tess_callback(glu.GLU_TESS_COMBINE) def combine_callback(coords, vertex_data, weights): x, y, z = coords[0:3] dataOut = (x,y,z) spare_verts.append((x,y,z)) return dataOut data_lists = [] for vlist in looplist: d_list = [] for x, y in vlist: v_data = (x, y, 0) d_list.append(v_data) data_lists.append(d_list) if fill_rule == 'nonzero': glu.gluTessProperty(tess, glu.GLU_TESS_WINDING_RULE, glu.GLU_TESS_WINDING_NONZERO) elif fill_rule == 'evenodd': glu.gluTessProperty(tess, glu.GLU_TESS_WINDING_RULE, glu.GLU_TESS_WINDING_ODD) glu.gluTessBeginPolygon(tess, None) for d_list in data_lists: glu.gluTessBeginContour(tess) for v_data in d_list: glu.gluTessVertex(tess, v_data, v_data) glu.gluTessEndContour(tess) glu.gluTessEndPolygon(tess) return t_list