您的位置:首页 > 其它

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

2018-06-03 02:00 453 查看

  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语言详解

Python/GeometricObjects/PolyLine

VTKExamples/Cxx/Graphs/ShortestPath

VTKExamples/Cxx/PolyData/DijkstraGraphGeodesicPath

VTK: vtkDijkstraGraphGeodesicPath Class Reference

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

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: