• VTK计算网格模型上的最短路径


      Dijkstra algorithm to compute the graph geodesic.Takes as input a polygonal mesh and performs a single source shortest path calculation. Dijkstra's algorithm is used. 

      用鼠标右键拾取平面网格上的点,观察输出路径:

    #!usrbinenv python
    
    import vtk
    
    
    def loadSTL(filenameSTL):
        readerSTL = vtk.vtkSTLReader()
        readerSTL.SetFileName(filenameSTL)
        # 'update' the reader i.e. read the .stl file
        readerSTL.Update()
    
        polydata = readerSTL.GetOutput()
        
        print "Number of Cells:",  polydata.GetNumberOfCells()
        print "Number of Points:", polydata.GetNumberOfPoints()
        
        # If there are no points in 'vtkPolyData' something went wrong
        if polydata.GetNumberOfPoints() == 0:
            raise ValueError("No point data could be loaded from " + filenameSTL)
            return None
            
        return polydata
        
    
    
    # Customize vtkInteractorStyleTrackballCamera 
    class MyInteractor(vtk.vtkInteractorStyleTrackballCamera):
    
        def __init__(self,parent=None):
            self.AddObserver("RightButtonPressEvent", self.RightButtonPressEvent)
            
        def RightButtonPressEvent(self,obj,event):
            clickPos = self.GetInteractor().GetEventPosition()
            print "Picking pixel: " , clickPos
            
            # Pick from this location
            picker = self.GetInteractor().GetPicker()
            picker.Pick(clickPos[0], clickPos[1], 0, self.GetDefaultRenderer())
            
            # If CellId = -1, nothing was picked
            if(picker.GetCellId() != -1): 
                print "Pick position is: " , picker.GetPickPosition()
                print "Cell id is:",  picker.GetCellId()
                print "Point id is:", picker.GetPointId()
                
                pathList.append(picker.GetPointId())
                point_position = mesh.GetPoint(picker.GetPointId())
                
                # Create a sphere
                sphereSource = vtk.vtkSphereSource()
                sphereSource.SetCenter(point_position)
                #sphereSource.SetRadius(0.2)
                sphereSource.SetRadius(0.02)
                
                # Create a mapper and actor
                sphereMapper = vtk.vtkPolyDataMapper()
                sphereMapper.SetInputConnection(sphereSource.GetOutputPort())            
                sphereActor = vtk.vtkActor()
                sphereActor.SetMapper(sphereMapper)
                sphereActor.GetProperty().SetColor(1.0, 0.0, 0.0)    
                self.GetDefaultRenderer().AddActor(sphereActor)
                
                # find the shortest path
                if len(pathList) > 1:
                    dijkstra.SetStartVertex(pathList[-2])
                    dijkstra.SetEndVertex(pathList[-1])
                    dijkstra.Update()
                    
                    # Get the vertex ids (of the input polydata) on the shortest path
                    IdList = dijkstra.GetIdList()
                
                    # store in pathList
                    for i in range(IdList.GetNumberOfIds()-1, 0, -1):
                        pathList.insert(-1, IdList.GetId(i))
                        
                    self.drawPath()
    
            # Forward events
            self.OnRightButtonDown()
            return
            
        def drawPath(self):
            points = vtk.vtkPoints()
            for i in range(0, len(pathList)):
                points.InsertNextPoint(mesh.GetPoint(pathList[i])) 
    
            # draw intermediate points    
            # pointsPolydata = vtk.vtkPolyData()
            # pointsPolydata.SetPoints(points)             
             
            # vertexFilter  = vtk.vtkVertexGlyphFilter()
            # vertexFilter.SetInputData(pointsPolydata)
            # vertexFilter.Update()
    
            # polydata = vtk.vtkPolyData()
            # polydata.ShallowCopy(vertexFilter.GetOutput())
            
            # mapper = vtk.vtkPolyDataMapper()
            # mapper.SetInputData(polydata)
    
            # polydataActor = vtk.vtkActor()
            # polydataActor.SetMapper(mapper)
            # polydataActor.GetProperty().SetPointSize(5)
            
            # self.GetDefaultRenderer().AddActor(polydataActor)
                    
            # draw path 
            polyLine = vtk.vtkPolyLine()
            polyLine.GetPointIds().SetNumberOfIds(len(pathList))
            for i in range(0, len(pathList)):
                polyLine.GetPointIds().SetId(i,i)
    
            #Create a cell array to store the lines in and add the lines to it
            cells = vtk.vtkCellArray()
            cells.InsertNextCell(polyLine)
            
            # Create a polydata to store everything in    
            polyLine = vtk.vtkPolyData()
            polyLine.SetPoints(points) # Add the points to the dataset
            polyLine.SetLines(cells)   # Add the lines to the dataset
            
            # Setup mapper
            polyLineMapper = vtk.vtkPolyDataMapper()
            polyLineMapper.SetInputData(polyLine)
            
            # Create an actor to represent the polyline
            polyLineActor = vtk.vtkActor()
            polyLineActor.SetMapper(polyLineMapper)
            polyLineActor.GetProperty().SetColor(0,0,1)
            polyLineActor.GetProperty().SetLineWidth(2)
            
            self.GetDefaultRenderer().AddActor(polyLineActor)
            
            
    def CreateScene():
        # Create a rendering window and renderer
        renWin = vtk.vtkRenderWindow()
        # Set window size
        renWin.SetSize(600, 600)
        ren = vtk.vtkRenderer()
        # Set background color
        ren.GradientBackgroundOn()
        ren.SetBackground(.1, .1, .1)
        ren.SetBackground2(0.8,0.8,0.8)
        
        renWin.AddRenderer(ren)
         
        # Create a renderwindowinteractor
        iren = vtk.vtkRenderWindowInteractor()
        iren.SetRenderWindow(renWin)
        
        style = MyInteractor()
        style.SetDefaultRenderer(ren)
        iren.SetInteractorStyle(style)
        
        # vtkCellPicker will shoot a ray into a 3D scene and return information about
        # the first object that the ray hits.
        cellPicker = vtk.vtkCellPicker()  
        iren.SetPicker(cellPicker)
        
        # load STL file 
        global mesh
        mesh = loadSTL("untitled.stl")
        
        global dijkstra
        global pathList
        pathList = []
        dijkstra = vtk.vtkDijkstraGraphGeodesicPath()
        dijkstra.SetInputData(mesh)
                
        mapper = vtk.vtkPolyDataMapper() 
        mapper.SetInputData(mesh)         # maps polygonal data to graphics primitives
        actor = vtk.vtkLODActor() 
        actor.SetMapper(mapper)
        actor.GetProperty().EdgeVisibilityOn()
        actor.GetProperty().SetColor(0.0,0.9,0.9)
        actor.GetProperty().SetLineWidth(0.3)
        ren.AddActor(actor)
    
        # Enable user interface interactor
        iren.Initialize()
        iren.Start()
        
    
    if __name__ == "__main__":
        CreateScene()
    View Code

       立体网格:

    参考:

    Dijkstra算法(一)之 C语言详解

    VTKExamples/Cxx/Graphs/ShortestPath

    VTKExamples/Cxx/PolyData/DijkstraGraphGeodesicPath

    VTK: vtkDijkstraGraphGeodesicPath Class Reference

    vtkDijkstraGraphGeodesicPath在曲面上寻找最短路径的应用

  • 相关阅读:
    Flink核心技术
    Flink学习问题和答案
    Spark知识点总结
    Scala知识点总结
    Spark测试题
    Hadoop概念试题
    IntelliJ IDEA 2019 快捷键终极大全
    Linux入门
    javaSe知识点总结
    Data
  • 原文地址:https://www.cnblogs.com/21207-iHome/p/9127171.html
Copyright © 2020-2023  润新知