import vtk import sys from math import sqrt from xml.sax.handler import ContentHandler from xml.sax.xmlreader import InputSource from xml.sax import make_parser def MakeDelaunConstr(mspts): onepolylines = vtk.vtkCellArray() onepolylines.InsertNextCell(mspts.GetNumberOfPoints()) # for i in range(mspts.GetNumberOfPoints()): # onepolylines.InsertCellPoint(i) # onepolylines.InsertCellPoint(0) for i in range(mspts.GetNumberOfPoints()): onepolylines.InsertCellPoint(mspts.GetNumberOfPoints() - 1 - i) # onepolylines.InsertCellPoint(mspts.GetNumberOfPoints() - 1) onepoly = vtk.vtkPolyData() onepoly.SetPoints(mspts) onepoly.SetPolys(onepolylines) delaun = vtk.vtkDelaunay2D() delaun.SetInput(onepoly) delaun.SetSource(onepoly) print mspts.GetNumberOfPoints() return delaun.GetOutput() class CHandler(ContentHandler): def __init__(self): pass def FindZ(self, x0, y0, z0, x1, y1, z1, x2, y2): diffx10 = x1 - x0 diffx20 = x2 - x0 diffy10 = y1 - y0 diffy20 = y2 - y0 n = diffx10 * diffx20 + diffy10 * diffy20 d = diffx10 * diffx10 + diffy10 * diffy10 d = sqrt(d) r = n / (d * d) return (1.0 - r) * z0 + r * z1 def startElement(self, name, attrs): output_function = getattr(self, "start_%s" % name, self.start_unkown_tag) output_function(name, attrs) def start_tunnelxpyvtk(self, name, attrs): self.pyvtkareaIndex = -1 self.appendF = vtk.vtkAppendPolyData() def start_pyvtkarea(self, name, attrs): self.pyvtkareaIndex += 1 if self.pyvtkareaIndex % 100 == 0: print "pyvtkareaIndex:%d" % self.pyvtkareaIndex self.ms = vtk.vtkFloatArray() self.mspts = vtk.vtkPoints() self.ms.SetNumberOfComponents(3) self.polygon = vtk.vtkPolygon() def start_path(self, name, attrs): self.Points = [] for attrName in attrs.keys(): if attrName == "zstart": self.z0 = float(attrs.get(attrName)) elif attrName == "zend": self.z1 = float(attrs.get(attrName)) elif attrName == "reversed": self.reversed = int(attrs.get(attrName)) def start_pt(self, name, attrs): for attrName in attrs.keys(): if attrName == "x": self.x = float(attrs.get(attrName)) elif attrName == "y": self.y = float(attrs.get(attrName)) self.Points.append([self.x,self.y]) def start_unkown_tag(self, name, attrs): if name == None: print "Warning:no name given for tag" else: print "start of unknown tag:%s" % name for attrName in attrs.keys(): print "Attribute -- Name: %s Value: %s" % (attrName, attrs.get(attrName)) def endElement(self, name): output_function = getattr(self, "end_%s" % name, self.end_unkown_tag) output_function(name) def end_pyvtkarea(self, name): self.appendF.AddInput(MakeDelaunConstr(self.mspts)) return polygon = self.polygon polygon.GetPoints().SetData(self.ms) n = polygon.GetPoints().GetNumberOfPoints() ids = polygon.GetPointIds() ids.SetNumberOfIds(n) for i in range(n): ids.SetId(i,i) ids = vtk.vtkIdList() polygon.Triangulate(ids) numberOfIds = ids.GetNumberOfIds() numberOfTriangles = numberOfIds / 3 if ids.GetNumberOfIds() != numberOfTriangles * 3: print "id list should contain a multipul of 3 points" cellArray = vtk.vtkCellArray() for triIndex in range(numberOfTriangles): a = ids.GetId(3 * triIndex) b = ids.GetId(3 * triIndex + 1) c = ids.GetId(3 * triIndex + 2) cellArray.InsertNextCell(3) cellArray.InsertCellPoint(a) cellArray.InsertCellPoint(b) cellArray.InsertCellPoint(c) pD = vtk.vtkPolyData() points = vtk.vtkPoints() points.SetData(self.ms) pD.SetPoints(points) #pD.SetPoints(self.polygon.GetPoints()) pD.SetPolys(cellArray) self.appendF.AddInput(pD) def end_tunnelxpyvtk(self, name): print "pyvtkareaIndex:%d" % self.pyvtkareaIndex def end_path(self, name): z0 = self.z0 z1 = self.z1 reversed = self.reversed points = self.Points if reversed == 1: points.reverse() tmp = z0 z0 = z1 z1 = z0 ptstart = points[0] ptend = points[-1] x0 = ptstart[0] y0 = ptstart[1] x1 = ptend[0] y1 = ptend[1] if x0 == x1 and y0 == y1 and z0 != z1: print "the data is a bit nasty, but I shouldnt crash!" for point in points[:-1]: x2 = point[0] y2 = point[1] if z0 == z1: z2 = z0 else: z2 = self.FindZ(x0, y0, z0, x1, y1, z1, x2, y2) self.ms.InsertNextTuple3(x2, y2, z2) self.mspts.InsertNextPoint(x2, y2, z2) #self.polygon.GetPoints().InsertNextPoint(x2, y2, z2) def end_pt(self, name): pass def end_unkown_tag(self, name): if name == None: print "Warning:end of tag:no name given for tag" else: print "end of unknown tag:%s" % name # the main part xmlfilename = len(sys.argv) >= 2 and sys.argv[1] or 'forsimon.xml' handler = CHandler() xmlParser = make_parser() xmlParser.setContentHandler(handler) xmlParser.setErrorHandler(handler); xmlParser.parse(InputSource(xmlfilename)) mapper = vtk.vtkPolyDataMapper() mapper.SetInput(handler.appendF.GetOutput()) ####### if False: ppp = [ (0, 0, 0), (0, 3, 0), (2, 3, 1), (3, 6, 1), (0, 6, 0), (0, 10, 0), (10, 10, 0), (10, 0, 0) ] ppp.reverse() #del ppp[1] polylines = vtk.vtkCellArray() pts = vtk.vtkPoints() polylines.InsertNextCell(len(ppp) + 1) i0 = -1 for p in ppp: i = pts.InsertNextPoint(p[0], p[1], p[2]) if i0 == -1: i0 = i polylines.InsertCellPoint(i) print i polylines.InsertCellPoint(i0) polyData = MakeDelaunConstr(pts) mapMesh = vtk.vtkPolyDataMapper() mapMesh.SetInput(MakeDelaunConstr(pts)) ######## actor = vtk.vtkActor() actor.SetMapper(mapper) ren = vtk.vtkRenderer() renWin = vtk.vtkRenderWindow() renWin.AddRenderer(ren) iren = vtk.vtkRenderWindowInteractor() iren.SetRenderWindow(renWin) ren.AddActor(actor) ren.SetBackground(0.1, 0.2, 0.4) renWin.SetSize(500, 500) cam1 = ren.GetActiveCamera() cam1.Elevation(-30) cam1.Roll(-20) ren.ResetCameraClippingRange() iren.Initialize() renWin.Render() iren.Start()