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

时间:2023-03-09 15:27:44
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()

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

  立体网格:

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

参考:

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

VTKExamples/Cxx/Graphs/ShortestPath

VTKExamples/Cxx/PolyData/DijkstraGraphGeodesicPath

VTK: vtkDijkstraGraphGeodesicPath Class Reference

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