def draw_face(self,f,f_color): #add normal format = GeomVertexFormat.getV3n3cp() vdata=GeomVertexData('vert', format, Geom.UHDynamic) vertex=GeomVertexWriter(vdata, 'vertex') color=GeomVertexWriter(vdata, 'color') normal=GeomVertexWriter(vdata, 'normal') vertex.addData3f(f.v1.pos) normal.addData3f(f.v1.norm.x, f.v1.norm.y, f.v1.norm.z) color.addData4f(f_color) vertex.addData3f(f.v2.pos) normal.addData3f(f.v2.norm.x, f.v2.norm.y, f.v2.norm.z) color.addData4f(f_color) vertex.addData3f(f.v3.pos) normal.addData3f(f.v3.norm.x, f.v3.norm.y, f.v3.norm.z) color.addData4f(f_color) mesh = Geom(vdata) tri = GeomTriangles(Geom.UHDynamic) tri.addVertex(0) tri.addVertex(1) tri.addVertex(2) tri.closePrimitive() mesh.addPrimitive(tri) face_node = GeomNode(self.mesh.name+'_face_'+str(f.ID)) face_node.addGeom(mesh) face_node.setTag('ID',str(f.ID)) rendered_face = self.render_root.attachNewNode(face_node) rendered_face.setTwoSided(True) self.render_nodes['face_'+str(f.ID)] = rendered_face
def draw_face(self, f, f_color): #add normal format = GeomVertexFormat.getV3n3cp() vdata = GeomVertexData('vert', format, Geom.UHDynamic) vertex = GeomVertexWriter(vdata, 'vertex') color = GeomVertexWriter(vdata, 'color') normal = GeomVertexWriter(vdata, 'normal') vertex.addData3f(f.v1.pos) normal.addData3f(f.v1.norm.x, f.v1.norm.y, f.v1.norm.z) color.addData4f(f_color) vertex.addData3f(f.v2.pos) normal.addData3f(f.v2.norm.x, f.v2.norm.y, f.v2.norm.z) color.addData4f(f_color) vertex.addData3f(f.v3.pos) normal.addData3f(f.v3.norm.x, f.v3.norm.y, f.v3.norm.z) color.addData4f(f_color) mesh = Geom(vdata) tri = GeomTriangles(Geom.UHDynamic) tri.addVertex(0) tri.addVertex(1) tri.addVertex(2) tri.closePrimitive() mesh.addPrimitive(tri) face_node = GeomNode(self.mesh.name + '_face_' + str(f.ID)) face_node.addGeom(mesh) face_node.setTag('ID', str(f.ID)) rendered_face = self.render_root.attachNewNode(face_node) rendered_face.setTwoSided(True) self.render_nodes['face_' + str(f.ID)] = rendered_face
def draw(self): if self.rendered_mesh != None: self.reset_draw() format=GeomVertexFormat.getV3n3cp() vdata=GeomVertexData('tri', format, Geom.UHDynamic) vertex=GeomVertexWriter(vdata, 'vertex') normal=GeomVertexWriter(vdata, 'normal') color=GeomVertexWriter(vdata, 'color') v_mapping = {} i=0 for v in self.verts.values(): vertex.addData3f(v.pos.x,v.pos.y,v.pos.z) normal.addData3f(v.norm.x, v.norm.y, v.norm.z) color.addData4f(v.color[0],v.color[1],v.color[2],v.color[3]) v_mapping[v.ID] = i i += 1 mesh = Geom(vdata) for f in self.faces.values(): tri = GeomTriangles(Geom.UHDynamic) tri.addVertex(v_mapping[f.v1.ID]) tri.addVertex(v_mapping[f.v2.ID]) tri.addVertex(v_mapping[f.v3.ID]) tri.closePrimitive() mesh.addPrimitive(tri) snode = GeomNode(self.name) snode.addGeom(mesh) self.rendered_mesh = render.attachNewNode(snode) self.rendered_mesh.setTwoSided(True)
def draw(self): if self.rendered_mesh != None: self.reset_draw() format = GeomVertexFormat.getV3n3cp() vdata = GeomVertexData('tri', format, Geom.UHDynamic) vertex = GeomVertexWriter(vdata, 'vertex') normal = GeomVertexWriter(vdata, 'normal') color = GeomVertexWriter(vdata, 'color') v_mapping = {} i = 0 for v in self.verts.values(): vertex.addData3f(v.pos.x, v.pos.y, v.pos.z) normal.addData3f(v.norm.x, v.norm.y, v.norm.z) color.addData4f(v.color[0], v.color[1], v.color[2], v.color[3]) v_mapping[v.ID] = i i += 1 mesh = Geom(vdata) for f in self.faces.values(): tri = GeomTriangles(Geom.UHDynamic) tri.addVertex(v_mapping[f.v1.ID]) tri.addVertex(v_mapping[f.v2.ID]) tri.addVertex(v_mapping[f.v3.ID]) tri.closePrimitive() mesh.addPrimitive(tri) snode = GeomNode(self.name) snode.addGeom(mesh) self.rendered_mesh = render.attachNewNode(snode) self.rendered_mesh.setTwoSided(True)
def __init__(self): ShowBase.__init__(self) PanditorDisableMouseFunc() camera.setPos(0.0, 0.0, 50.0) camera.lookAt(0.0) PanditorEnableMouseFunc() # 1) create GeomVertexData frmt = GeomVertexFormat.getV3n3cp() vdata = GeomVertexData('triangle', frmt, Geom.UHDynamic) # 2) create Writers/Rewriters (must all be created before any readers and readers are one-pass-temporary) vertex = GeomVertexRewriter(vdata, 'vertex') normal = GeomVertexRewriter(vdata, 'normal') color = GeomVertexRewriter(vdata, 'color') zUp = Vec3(0, 0, 1) wt = Vec4(1.0, 1.0, 1.0, 1.0) gr = Vec4(0.5, 0.5, 0.5, 1.0) # 3) write each column on the vertex data object (for speed, have a different writer for each column) def addPoint(x, y, z): vertex.addData3f(x, y, z) normal.addData3f(zUp) color.addData4f(wt) addPoint(0.0, 0.0, 0.0) addPoint(5.0, 0.0, 0.0) addPoint(0.0, 5.0, 0.0) addPoint(5.0, 5.0, 0.0) # 4) create a primitive and add the vertices via index (not truely associated with the actual vertex table, yet) tris = GeomTriangles(Geom.UHDynamic) tris.addVertices(0, 1, 2) tris.closePrimitive( ) # exception thrown if verts added != 3, other types inform Panda how many verts/primitive tris.addVertices(2, 1, 3) print "vdataPoints", vdata.getArrays()[0] # 5.1) (adding to scene) create a Geom and add primitives of like base-type i.e. triangles and triangle strips geom = Geom(vdata) geom.addPrimitive(tris) # 5.2) create a GeomNode to hold the Geom(s) and add the Geom(s) gn = GeomNode('gnode') gn.addGeom(geom) # 5.3) attache the node to the scene gnNodePath = render.attachNewNode(gn) geomPts = Geom(vdata) pts = GeomPoints(Geom.UHStatic) pts.addVertices(0, 1, 2) pts.closePrimitive() geomPts.addPrimitive(pts) pointsNode = GeomNode('points_node') pointsNode.addGeom(geomPts) pointsNP = render.attachNewNode(pointsNode) pointsNP.setZ(0.5) render.ls()
def __init__(self): ShowBase.__init__(self) PanditorDisableMouseFunc() camera.setPos(0.0, 0.0, 50.0) camera.lookAt(0.0) PanditorEnableMouseFunc() # 1) create GeomVertexData frmt = GeomVertexFormat.getV3n3cp() vdata = GeomVertexData('triangle', frmt, Geom.UHDynamic) # 2) create Writers/Rewriters (must all be created before any readers and readers are one-pass-temporary) vertex = GeomVertexRewriter(vdata, 'vertex') normal = GeomVertexRewriter(vdata, 'normal') color = GeomVertexRewriter(vdata, 'color') zUp = Vec3(0, 0, 1) wt = Vec4(1.0, 1.0, 1.0, 1.0) gr = Vec4(0.5, 0.5, 0.5, 1.0) # 3) write each column on the vertex data object (for speed, have a different writer for each column) def addPoint(x, y, z): vertex.addData3f(x, y, z) normal.addData3f(zUp) color.addData4f(wt) addPoint(0.0, 0.0, 0.0) addPoint(5.0, 0.0, 0.0) addPoint(0.0, 5.0, 0.0) addPoint(5.0, 5.0, 0.0) # 4) create a primitive and add the vertices via index (not truely associated with the actual vertex table, yet) tris = GeomTriangles(Geom.UHDynamic) tris.addVertices(0, 1, 2) tris.closePrimitive() # exception thrown if verts added != 3, other types inform Panda how many verts/primitive tris.addVertices(2, 1, 3) print "vdataPoints", vdata.getArrays()[0] # 5.1) (adding to scene) create a Geom and add primitives of like base-type i.e. triangles and triangle strips geom = Geom(vdata) geom.addPrimitive(tris) # 5.2) create a GeomNode to hold the Geom(s) and add the Geom(s) gn = GeomNode('gnode') gn.addGeom(geom) # 5.3) attache the node to the scene gnNodePath = render.attachNewNode(gn) geomPts = Geom(vdata) pts = GeomPoints(Geom.UHStatic) pts.addVertices(0, 1, 2) pts.closePrimitive() geomPts.addPrimitive(pts) pointsNode = GeomNode('points_node') pointsNode.addGeom(geomPts) pointsNP = render.attachNewNode(pointsNode) pointsNP.setZ(0.5) render.ls()
def createTriangle(v1, v2, v3, is_flat=False): x1 = v1.x y1 = v1.y z1 = v1.z x2 = v2.x y2 = v2.y z2 = v2.z x3 = v3.x y3 = v3.y z3 = v3.z format=GeomVertexFormat.getV3n3cp() vdata=GeomVertexData('tri', format, Geom.UHDynamic) vertex=GeomVertexWriter(vdata, 'vertex') normal=GeomVertexWriter(vdata, 'normal') color=GeomVertexWriter(vdata, 'color') vertex.addData3f(x1, y1, z1) vertex.addData3f(x2, y2, z2) vertex.addData3f(x3, y3, z3) if is_flat: normVector = norm(Vec3( (x1 + x2 + x3)/3.0, (y1 + y2 + y3)/3.0, (z1+ z2+ z3)/3.0)) normal.addData3f(normVector) normal.addData3f(normVector) normal.addData3f(normVector) else: normal.addData3f(norm(Vec3(x1,y1,z1))) normal.addData3f(norm(Vec3(x2,y2,z2))) normal.addData3f(norm(Vec3(x3,y3,z3))) #adding different colors to the vertex for visibility color.addData4f(0.5,0.5,0.5,1.0) color.addData4f(0.5,0.5,0.5,1.0) color.addData4f(0.5,0.5,0.5,1.0) tri = GeomTriangles(Geom.UHDynamic) tri.addVertex(0) tri.addVertex(1) tri.addVertex(2) tri.closePrimitive() output_tri = Geom(vdata) output_tri.addPrimitive(tri) return output_tri
def __init__(self): ShowBase.__init__(self) winProps = WindowProperties() winProps.setTitle("Triangle and SimpleCircle Unittest") # base.win.requestProperties(winProps) (same as below e.g. self == base) self.win.requestProperties(winProps) # 1) create GeomVertexData frmt = GeomVertexFormat.getV3n3cp() vdata = GeomVertexData('triangle_developer', frmt, Geom.UHDynamic) # 2) create Writers/Rewriters (must all be created before any readers and readers are one-pass-temporary) vertex = GeomVertexRewriter(vdata, 'vertex') normal = GeomVertexRewriter(vdata, 'normal') color = GeomVertexRewriter(vdata, 'color') zUp = Vec3(0, 0, 1) wt = Vec4(1.0, 1.0, 1.0, 1.0) gr = Vec4(0.5, 0.5, 0.5, 1.0) # 3) write each column on the vertex data object (for speed, have a different writer for each column) def addPoint(x, y, z): vertex.addData3f(x, y, z) normal.addData3f(zUp) color.addData4f(wt) addPoint(0.0, 0.0, 0.0) addPoint(5.0, 0.0, 0.0) addPoint(0.0, 5.0, 0.0) addPoint(15.0, 15.0, 0.0) # 4) create a primitive and add the vertices via index (not truely associated with the actual vertex table, yet) tris = GeomTriangles(Geom.UHDynamic) t1 = Triangle(0, 1, 2, vdata, tris, vertex) t2 = Triangle(2, 1, 3, vdata, tris, vertex) c1 = t1.getCircumcircle() t1AsEnum = t1.asPointsEnum() r0 = (t1AsEnum.point0 - c1.center).length() r1 = (t1AsEnum.point1 - c1.center).length() r2 = (t1AsEnum.point2 - c1.center).length() assert abs(r0 - r2) < utilities.EPSILON and abs(r0 - r1) < utilities.EPSILON t2AsEnum = t2.asPointsEnum() c2 = t2.getCircumcircle() r0 = (t2AsEnum.point0 - c2.center).length() r1 = (t2AsEnum.point1 - c2.center).length() r2 = (t2AsEnum.point2 - c2.center).length() assert abs(r0 - r2) < utilities.EPSILON and abs(r0 - r1) < utilities.EPSILON assert t1.getAngleDeg0() == 90.0 assert t1.getAngleDeg1() == t1.getAngleDeg2() oldInd0 = t1.pointIndex0 oldInd1 = t1.pointIndex1 oldInd2 = t1.pointIndex2 t1.pointIndex0 = t1.pointIndex1 t1.pointIndex1 = oldInd0 assert t1.pointIndex0 == oldInd1 assert t1.pointIndex1 == oldInd0 assert t1.pointIndex0 != t1.pointIndex1 t1.reverse() assert t1.pointIndex1 == oldInd2 # 5.1) (adding to scene) create a Geom and add primitives of like base-type i.e. triangles and triangle strips geom = Geom(vdata) geom.addPrimitive(tris) # 5.2) create a GeomNode to hold the Geom(s) and add the Geom(s) gn = GeomNode('gnode') gn.addGeom(geom) # 5.3) attache the node to the scene gnNodePath = render.attachNewNode(gn) # setup a wire frame wireNP = render.attachNewNode('wire') wireNP.setPos(0.0, 0.0, .1) wireNP.setColor(0.1, 0.1, 0.1, 1) wireNP.setRenderMode(RenderModeAttrib.MWireframe, .5, 0) gnNodePath.instanceTo(wireNP) # test and draw intersections and circles pt1 = Point3(0.0, 5.0, 0.0) pt2 = Point3(1.0, 5.0, 0.0) intersection = t2.getIntersectionsWithCircumcircle(pt1, pt2) circle = t2.getCircumcircle() cuts = 128 border = circle.getBorder(cuts, closed=True) assert len(border) == cuts or (len(border) == cuts + 1 and border[0] == border[len(border) - 1]) n = len(border) xMid = yMid = 0 for p in border: xMid += p.x yMid += p.y mid = Point3(xMid / n, yMid / n, border[0].z) assert mid.almostEqual(circle.center, 0.06) assert t2.isCcw() assert t1.containsPoint(c1.center) != t1.containsPoint(c1.center, includeEdges=False) circleSegs = LineSegs("circleLines") circleSegs.setColor(1.0, 0.0, 0.0, 1.0) for p in border: circleSegs.drawTo(*p) circleNode = circleSegs.create(False) circleNP = render.attachNewNode(circleNode) circleNP.setZ(-5) originSpot = LineSegs("intersection") originSpot.setColor(1.0, 0.0, 0.0, 1.0) originSpot.setThickness(10) for p in intersection: originSpot.drawTo(p) spotNode = originSpot.create(False) spotNP = render.attachNewNode(spotNode) circleNP.setZ(-0.75) # fix the camera rot/pos PHF.PanditorDisableMouseFunc() camera.setPos(0.0, 0.0, 50.0) camera.lookAt(c2.center) PHF.PanditorEnableMouseFunc()
def createCube(parent, index, cubeMembership, walls): vertexFormat = GeomVertexFormat.getV3n3cp() vertexData = GeomVertexData("cube_data", vertexFormat, Geom.UHStatic) tris = GeomTriangles(Geom.UHStatic) posWriter = GeomVertexWriter(vertexData, "vertex") colWriter = GeomVertexWriter(vertexData, "color") normalWriter = GeomVertexWriter(vertexData, "normal") vertexCount = 0 for direction in (-1, 1): for i in range(3): normal = VBase3() normal[i] = direction rgb = [0., 0., 0.] rgb[i] = 1. if direction == 1: rgb[i - 1] = 1. r, g, b = rgb color = (r, g, b, 0.) for a, b in ((-1., -1.), (-1., 1.), (1., 1.), (1., -1.)): pos = VBase3() pos[i] = direction pos[(i + direction) % 3] = a pos[(i + direction * 2) % 3] = b posWriter.addData3f(pos) colWriter.addData4f(color) normalWriter.addData3f(normal) vertexCount += 4 tris.addVertices(vertexCount - 2, vertexCount - 3, vertexCount - 4) tris.addVertices(vertexCount - 4, vertexCount - 1, vertexCount - 2) geom = Geom(vertexData) geom.addPrimitive(tris) node = GeomNode("cube_node") node.addGeom(geom) cube = parent.attachNewNode(node) x = index % 9 // 3 - 1 y = index // 9 - 1 z = index % 9 % 3 - 1 cube.setScale(.4) cube.setPos(x * 0.85, y * 0.85, z * 0.85) membership = set() # the walls this cube belongs to cubeMembership[cube] = membership if x == -1: walls["left"].append(cube) membership.add("left") elif x == 1: walls["right"].append(cube) membership.add("right") if y == -1: walls["front"].append(cube) membership.add("front") elif y == 1: walls["back"].append(cube) membership.add("back") if z == -1: walls["bottom"].append(cube) membership.add("bottom") elif z == 1: walls["top"].append(cube) membership.add("top") return cube
def makeTriMesh( verts, holeVerts=[[]]): pointmap = (lambda x, y: (x, y, 0)) if not hasattr(holeVerts[0], '__iter__'): holeVerts = [holeVerts] frmt = GeomVertexFormat.getV3n3cp() vdata = GeomVertexData('triangle', frmt, Geom.UHDynamic) vertex = GeomVertexWriter(vdata, 'vertex') normal = GeomVertexWriter(vdata, 'normal') color = GeomVertexWriter(vdata, 'color') bl = Vec4(50, 50, 50, 255) gr = Vec4(256/2 - 1, 256/2 - 1, 256/2 - 1, 255) trilator = Triangulator() zUp = Vec3(0, 0, 1) for i in verts: #print "verts", verts trilator.addPolygonVertex(trilator.addVertex(i.x, i.y)) vertex.addData3f(pointmap(i.x, i.y)) normal.addData3f(zUp) color.addData4f(bl) #if len(holeVerts) != 1 and holeVerts[0] != []: for w in holeVerts: trilator.beginHole() print "new hole" for j in w: # print(j) # ###################### PRINT ####################### trilator.addHoleVertex(trilator.addVertex(j.x, j.y)) vertex.addData3f(pointmap(j.x, j.y)) normal.addData3f(zUp) color.addData4f(gr) # try: trilator.triangulate() triVerts = trilator.getVertices() p = trilator.getTriangleV0(0) print "trilator return", p # except AssertionError: # pass # TODO:re-triangulate here and change AdjacencyList to expect a list of triangles rather than call Triangulator funcs trilator = makeDelaunayTriangulation(trilator) prim = GeomTriangles(Geom.UHStatic) if isinstance(trilator, Triangulator): # HACK just to switch back and forth from the non-Delaunay to the Delaunay for school for n in xrange(trilator.getNumTriangles()): prim.addVertices(trilator.getTriangleV0(n), trilator.getTriangleV1(n), trilator.getTriangleV2(n)) else: # it's an adjacency list for n in xrange(len(trilator.adjLst)): for v in range(0, len(triVerts)): print "\ncurr", triVerts[v], "\nv0", Point2D(trilator.adjLst[n].tri[0].x, trilator.adjLst[n].tri[0].y),\ "\nv1", Point2D(trilator.adjLst[n].tri[1].x, trilator.adjLst[n].tri[1].y),\ "\nv2", Point2D(trilator.adjLst[n].tri[2].x, trilator.adjLst[n].tri[2].y) # trilator.adjLst[n].tri[0].getXy(),\ # "\nv1", trilator.adjLst[n].tri[1].getXy(),\ # "\nv2", trilator.adjLst[n].tri[2].getXy() # v0 = v1 = v2 = -1 if Point2D(trilator.adjLst[n].tri[0].x, trilator.adjLst[n].tri[0].y) == triVerts[v]: v0 = v # we need indices into the vertex pool print "found v0", v0 if Point2D(trilator.adjLst[n].tri[1].x, trilator.adjLst[n].tri[1].y) == triVerts[v]: v1 = v print "found v1", v1 if Point2D(trilator.adjLst[n].tri[2].x, trilator.adjLst[n].tri[2].y) == triVerts[v]: v2 = v print "found v2", v2 # if v0 == -1 or v1 == -1 or v2 == -1: # print "pass", v0, v1, v2 # pass # else: # print "add" # i = triVerts[v0] # vertex.addData3f(pointmap(i.x, i.y)) # normal.addData3f(zUp) # color.addData4f(bl) # i = triVerts[v1] # vertex.addData3f(pointmap(i.x, i.y)) # normal.addData3f(zUp) # color.addData4f(bl) # i = triVerts[v2] # vertex.addData3f(pointmap(i.x, i.y)) # normal.addData3f(zUp) # color.addData4f(bl) print "v 1 2 3", v0, v1, v2 prim.addVertices(v0, v1, v2) prim.closePrimitive() geom = Geom(vdata) geom.addPrimitive(prim) node = GeomNode('gnode') node.addGeom(geom) # print trilator.isLeftWinding() # HACK just for school if hasattr(trilator, "adLst"): return tuple((node, trilator.adjLst)) else: return tuple((node, trilator))
def __init__(self): ShowBase.__init__(self) winProps = WindowProperties() winProps.setTitle("Triangle and SimpleCircle Unittest") # base.win.requestProperties(winProps) (same as below e.g. self == base) self.win.requestProperties(winProps) zUp = Vec3(0.0, 0.0, 1.0) wt = Vec4(1.0, 1.0, 1.0, 1.0) def addToVertex(x, y, z): normal.addData3f(zUp) color.addData4f(wt) # BLOG post about these bullet points then delete them # 1) create GeomVertexData (inside the triangulator's constructor) frmt = GeomVertexFormat.getV3n3cp() triangulator = ConstrainedDelaunayTriangulator(vertexFormat = frmt, onVertexCreationCallback = addToVertex) vdata = triangulator.getGeomVertexData() # 2) create Writers/Rewriters (must all be created before any readers and readers are one-pass-temporary) normal = GeomVertexRewriter(vdata, 'normal') # DOC 'vertex' is the only prohibited column for the user to use color = GeomVertexRewriter(vdata, 'color') # 3) write each column on the vertex data object (for speed, have a different writer for each column) # DOC 1.DT) create triangulator # DOC 2.DT) add vertices (before calling triangulate) # ############# NOT ANGLE OPTIMAL BELOW ##################### # triangulator.addVertexToPolygon(5.0, 0.0, 0.0) # triangulator.addVertexToPolygon(0.0, 0.0, 0.0) # triangulator.addVertexToPolygon(1.5, 2.5, 0.0) # triangulator.addVertexToPolygon(0.0, 5.0, 0.0) # triangulator.addVertexToPolygon(5.0, 5.0, 0.0) # ############# NOT ANGLE OPTIMAL ABOVE ##################### triangulator.addVertexToPolygon(5.0, 0.0, 0.0) triangulator.addVertexToPolygon(6.5, 6.5, 0.0) # triangulator.addVertexToPolygon(1.5, 2.5, 0.0) triangulator.addVertexToPolygon(0.0, 0.0, 0.0) triangulator.addVertexToPolygon(0.0, 5.0, 0.0) triangulator.addVertexToPolygon(5.0, 5.0, 0.0) # DOC 3.DT) add hole vertices (before calling triangulate) # DOC 4.DT) call triangulate triangulator.triangulate(makeDelaunay=True) # ######################## REMOVE ################################### # ######################## REMOVE ################################### assert triangulator.isTriangulated() adjLst = triangulator.getAdjacencyList() foundInvalidReference = [] foundMissingReference = [] # so I can explicitly state all index references are correct for t in adjLst: # check that references with no neighbor haven't missed an edge noneEdges = [] if t._neighbor0 is None: noneEdges.append(t.edgeIndices0) elif t._neighbor1 is None: noneEdges.append(t.edgeIndices1) elif t._neighbor2 is None: noneEdges.append(t.edgeIndices2) for tri_ in adjLst: for edge_ in noneEdges: # the edge that should hold the reference is on t. The one that should get referenced is on tri_ missedCount = 0 if edge_[0] in tri_.edgeIndices0 and edge_[1] in tri_.edgeIndices0 and tri_ != t: missedCount += 1 if edge_[0] in tri_.edgeIndices1 and edge_[1] in tri_.edgeIndices1 and tri_ != t: missedCount += 1 if edge_[0] in tri_.edgeIndices2 and edge_[1] in tri_.edgeIndices2 and tri_ != t: missedCount += 1 if missedCount == 1: foundMissingReference.extend((t, tri_)) notify.warning( "!MISSED REFERENCE TO NEIGHBOR\nreferrer: {} ptIndices: {} neighbors: {}\n".format( t.index, t.getPointIndices(), t.getNeighbors(), ) + "missed: {} ptIndices: {} neighbors: {}".format( tri_.index, tri_.getPointIndices(), tri_.getNeighbors(), )) elif missedCount > 1: foundMissingReference.extend((t, tri_)) notify.warning( "!EXTRANEOUS & MISSED SHARED EDGES\nreferrer: {} ptIndices: {} neighbors: {}\n".format( t.index, t.getPointIndices(), t.getNeighbors(), ) + "missed: {} ptIndices: {} neighbors: {}".format( tri_.index, tri_.getPointIndices(), tri_.getNeighbors(), )) # check that neighbor relations point to correct triangles for n in t.getNeighbors(includeEmpties=False): neighbor = adjLst[n] otherInds = neighbor.getPointIndices() if neighbor.index == t._neighbor0: edge = t.edgeIndices0 elif neighbor.index == t._neighbor1: edge = t.edgeIndices1 elif neighbor.index == t._neighbor2: edge = t.edgeIndices2 if edge[0] not in otherInds and edge[1] not in otherInds: foundInvalidReference.extend((t, neighbor)) notify.warning( "!INVALID REFERENCE TO NEIGHBOR\nreferrer: {} indices: {} neighbors: {}".format( t.index, t.getPointIndices(), t.getNeighbors(), ) + "\nreferee: {} indices: {} neighbors: {}".format( neighbor.index, neighbor.getPointIndices(), neighbor.getNeighbors() )) if not foundMissingReference: notify.warning("No error missing reference in neighbors.") else: notify.warning("!!!ERROR missing reference in neighbor references.") if not foundInvalidReference: notify.warning("No error found in neighbors that were referenced.") else: notify.warning("!!!ERROR found in neighbors that were referenced.") foundPointInsideCircle = False trianglesWithInvalidPoint = set() for t in adjLst: circle_ = t.getCircumcircle() # cycle through triangles checking each point against each circle.center for e in adjLst: p0, p1, p2 = e.getPoints() if circle_.radius - (p0 - circle_.center).length() > EPSILON: foundPointInsideCircle = True notify.warning( "!point in circumcircle point {0} circle {1}\ntriangle1: {2}\ntriangle2: {3}".format( p0, circle_, t, e )) trianglesWithInvalidPoint |= set((t.index, )) if circle_.radius - (p1 - circle_.center).length() > EPSILON: foundPointInsideCircle = True notify.warning( "!point in circumcircle point {0} circle {1}\ntriangle1: {2}\ntriangle2: {3}".format( p1, circle_, t, e )) trianglesWithInvalidPoint |= set((t.index, )) if circle_.radius - (p2 - circle_.center).length() > EPSILON: foundPointInsideCircle = True notify.warning( "!point in circumcircle point {0} circle {1}\ntriangle1: {2}\ntriangle2: {3}".format( p2, circle_, t, e )) trianglesWithInvalidPoint |= set((t.index, )) if not foundPointInsideCircle: notify.warning("No point found inside circumcircle.") else: notify.warning("!!!ERROR found point inside circumcircle. Triangles: {}".format(trianglesWithInvalidPoint)) # TODO test edges that reference no neighbor # triangles = triangulator.getGeomTriangles() # print "Triangulated:" # for tri in triangleList: # print "\t{0}".format(tri) # 4) create a primitive and add the vertices via index (not truly associated with the actual vertex table, yet) # tris = GeomTriangles(Geom.UHDynamic) # t1 = Triangle(0, 1, 2, vdata, tris, vertex) # t2 = Triangle(2, 1, 3, vdata, tris, vertex) # c1 = t1.getCircumcircle() # t1AsEnum = t1.asPointsEnum() # r0 = (t1AsEnum.point0 - c1.center).length() # r1 = (t1AsEnum.point1 - c1.center).length() # r2 = (t1AsEnum.point2 - c1.center).length() # assert abs(r0 - r2) < utilities.EPSILON and abs(r0 - r1) < utilities.EPSILON # t2AsEnum = t2.asPointsEnum() # c2 = t2.getCircumcircle() # r0 = (t2AsEnum.point0 - c2.center).length() # r1 = (t2AsEnum.point1 - c2.center).length() # r2 = (t2AsEnum.point2 - c2.center).length() # assert abs(r0 - r2) < utilities.EPSILON and abs(r0 - r1) < utilities.EPSILON # assert t1.getAngleDeg0() == 90.0 # assert t1.getAngleDeg1() == t1.getAngleDeg2() # # oldInd0 = t1.pointIndex0 # oldInd1 = t1.pointIndex1 # oldInd2 = t1.pointIndex2 # t1.pointIndex0 = t1.pointIndex1 # t1.pointIndex1 = oldInd0 # assert t1.pointIndex0 == oldInd1 # assert t1.pointIndex1 == oldInd0 # assert t1.pointIndex0 != t1.pointIndex1 # t1.reverse() # assert t1.pointIndex1 == oldInd2 # gn = triangulator.getGeomNode('triangles') gnNodePath = render.attachNewNode(gn) # setup a wire frame wireNP = render.attachNewNode('wire') wireNP.setPos(0.0, 0.0, .1) wireNP.setColor(0.1, 0.1, 0.1, 1) wireNP.setRenderMode(RenderModeAttrib.MWireframe, .5, 0) gnNodePath.instanceTo(wireNP) # # # test and draw intersections and circles # pt1 = Point3(0.0, 5.0, 0.0) # pt2 = Point3(1.0, 5.0, 0.0) # intersection = t2.getIntersectionsWithCircumcircle(pt1, pt2) # circle = t2.getCircumcircle() # cuts = 128 # border = circle.getBorder(cuts, closed=True) # assert len(border) == cuts or (len(border) == cuts + 1 and border[0] == border[len(border) - 1]) # n = len(border) # xMid = yMid = 0 # for p in border: # xMid += p.x # yMid += p.y # mid = Point3(xMid / n, yMid / n, border[0].z) # assert mid.almostEqual(circle.center, 0.06) # assert t2.isLeftWinding() # assert t1.containsPoint(c1.center) != t1.containsPoint(c1.center, includeEdges=False) # # circleSegs = LineSegs("circleLines") # circleSegs.setColor(1.0, 0.0, 0.0, 1.0) # for p in border: # circleSegs.drawTo(*p) # circleNode = circleSegs.create(False) # circleNP = render.attachNewNode(circleNode) # circleNP.setZ(-5) # # originSpot = LineSegs("intersection") # originSpot.setColor(1.0, 0.0, 0.0, 1.0) # originSpot.setThickness(10) # for p in intersection: # originSpot.drawTo(p) # spotNode = originSpot.create(False) # spotNP = render.attachNewNode(spotNode) # circleNP.setZ(-0.75) # fix the camera rot/pos PHF.PanditorDisableMouseFunc() camera.setPos(0.0, 0.0, 50.0) camera.lookAt(Point3(0.0)) # 2.5, 2.5, 0.0)) PHF.PanditorEnableMouseFunc() # print "isLeftWinding()", triangulator.isLeftWinding() # TODO port the triangle-indices node func drawTriangleIndices(...) indsNp = ConstrainedDelaunayTriangulator.drawTriangleIndices(triangulator.getTriangleList()) indsNp.setPos(0.0, 0.0, 0.3)
def makeTriMesh( verts, holeVerts=[[]]): pointmap = (lambda x, y: (x, y, 0)) if not holeVerts: holeVerts = [[]] if not hasattr(holeVerts[0], '__iter__'): holeVerts = [holeVerts] frmt = GeomVertexFormat.getV3n3cp() vdata = GeomVertexData('triangle', frmt, Geom.UHDynamic) vertex = GeomVertexWriter(vdata, 'vertex') normal = GeomVertexWriter(vdata, 'normal') color = GeomVertexWriter(vdata, 'color') bl = Vec4(50, 50, 50, 255) gr = Vec4(256/2 - 1, 256/2 - 1, 256/2 - 1, 255) trilator = Triangulator() zUp = Vec3(0, 0, 1) for i in verts: #print "verts", verts trilator.addPolygonVertex(trilator.addVertex(i.x, i.y)) vertex.addData3f(pointmap(i.x, i.y)) normal.addData3f(zUp) color.addData4f(bl) #if len(holeVerts) != 1 and holeVerts[0] != []: for w in holeVerts: trilator.beginHole() print "new hole" for j in w: # print(j) # ###################### PRINT ####################### trilator.addHoleVertex(trilator.addVertex(j.x, j.y)) vertex.addData3f(pointmap(j.x, j.y)) normal.addData3f(zUp) color.addData4f(gr) # try: trilator.triangulate() triVerts = trilator.getVertices() p = trilator.getTriangleV0(0) print "trilator return", p # except AssertionError: # pass # TODO:re-triangulate here and change AdjacencyList to expect a list of triangles rather than call Triangulator funcs trilator = makeDelaunayTriangulation(trilator) prim = GeomTriangles(Geom.UHStatic) if isinstance(trilator, Triangulator): # HACK just to switch back and forth from the non-Delaunay to the Delaunay for school for n in xrange(trilator.getNumTriangles()): prim.addVertices(trilator.getTriangleV0(n), trilator.getTriangleV1(n), trilator.getTriangleV2(n)) else: # it's an adjacency list for n in xrange(len(trilator.adjLst)): for v in range(0, len(triVerts)): print "\ncurr", triVerts[v], "\nv0", Point2D(trilator.adjLst[n].tri[0].x, trilator.adjLst[n].tri[0].y),\ "\nv1", Point2D(trilator.adjLst[n].tri[1].x, trilator.adjLst[n].tri[1].y),\ "\nv2", Point2D(trilator.adjLst[n].tri[2].x, trilator.adjLst[n].tri[2].y) # trilator.adjLst[n].tri[0].getXy(),\ # "\nv1", trilator.adjLst[n].tri[1].getXy(),\ # "\nv2", trilator.adjLst[n].tri[2].getXy() # v0 = v1 = v2 = -1 if Point2D(trilator.adjLst[n].tri[0].x, trilator.adjLst[n].tri[0].y) == triVerts[v]: v0 = v # we need indices into the vertex pool print "found v0", v0 if Point2D(trilator.adjLst[n].tri[1].x, trilator.adjLst[n].tri[1].y) == triVerts[v]: v1 = v print "found v1", v1 if Point2D(trilator.adjLst[n].tri[2].x, trilator.adjLst[n].tri[2].y) == triVerts[v]: v2 = v print "found v2", v2 # if v0 == -1 or v1 == -1 or v2 == -1: # print "pass", v0, v1, v2 # pass # else: # print "add" # i = triVerts[v0] # vertex.addData3f(pointmap(i.x, i.y)) # normal.addData3f(zUp) # color.addData4f(bl) # i = triVerts[v1] # vertex.addData3f(pointmap(i.x, i.y)) # normal.addData3f(zUp) # color.addData4f(bl) # i = triVerts[v2] # vertex.addData3f(pointmap(i.x, i.y)) # normal.addData3f(zUp) # color.addData4f(bl) print "v 1 2 3", v0, v1, v2 prim.addVertices(v0, v1, v2) prim.closePrimitive() geom = Geom(vdata) geom.addPrimitive(prim) node = GeomNode('gnode') node.addGeom(geom) # print trilator.isLeftWinding() # HACK just for school if hasattr(trilator, "adLst"): return tuple((node, trilator.adjLst)) else: return tuple((node, trilator))