基于VTK的八叉树可视化
VTK是一个非常强大的3D可视化库,其中就有可视化八叉树的类和函数。
效果图:
下面的代码是使用VTK构建的对PLY网格模型的八叉树空间划分
import vtk
class SliderObserver(object):
def __init__(self, Octree, polyData, renderer):
self.Octree = Octree
self.level = 0
self.polyData = polyData
self.renderer = renderer
def __call__(self, caller, event):
self.level = vtk.vtkMath.Round(caller.GetRepresentation().GetValue())
self.Octree.GenerateRepresentation(self.level, self.polyData)
self.renderer.Render()
def OctreeVisualize(fileName):
'''
fileName:文件路径
该函数显示PLY模型的空间八叉树划分
'''
# PLY模型的读取
colors = vtk.vtkNamedColors()
plyReader = vtk.vtkPLYReader()
'''
如果要读取STL模型的话,将plyReader = vtkPLYReader() 替换成
plyReader = vtk.vtkSTLReader()
'''
plyReader.SetFileName(fileName)
plyMapper = vtk.vtkPolyDataMapper()
plyMapper.SetInputConnection(plyReader.GetOutputPort())
plyReader.Update()
plyActor = vtk.vtkActor()
plyActor.SetMapper(plyMapper)
plyActor.GetProperty().SetInterpolationToFlat()
plyActor.GetProperty().SetRepresentationToPoints()
plyActor.GetProperty().SetColor(colors.GetColor3d("Yellow"))
# 构建八叉树
octree = vtk.vtkOctreePointLocator()
octree.SetMaximumPointsPerRegion(5)
octree.SetDataSet(plyReader.GetOutput())
octree.BuildLocator()
polydata = vtk.vtkPolyData()
octree.GenerateRepresentation(0, polydata)
octreeMapper = vtk.vtkPolyDataMapper()
octreeMapper.SetInputData(polydata)
octreeActor = vtk.vtkActor()
octreeActor.SetMapper(octreeMapper)
octreeActor.GetProperty().SetInterpolationToFlat()
octreeActor.GetProperty().SetRepresentationToWireframe()
octreeActor.GetProperty().SetColor(colors.GetColor3d("SpringGreen"))
# 渲染器和窗口
renderer = vtk.vtkRenderer()
renderWindow = vtk.vtkRenderWindow()
renderWindow.AddRenderer(renderer)
# 交互器
renderWindowInteractor = vtk.vtkRenderWindowInteractor()
renderWindowInteractor.SetRenderWindow(renderWindow)
# 将模型加入场景中
renderer.AddActor(plyActor)
renderer.AddActor(octreeActor)
renderer.SetBackground(colors.GetColor3d("MidnightBlue"))
# 渲染一副图像(光照和相机自动创建)
renderWindow.SetWindowName("OctreeVisualize")
renderWindow.SetSize(600, 600)
renderWindow.Render()
# 创建设定八叉树划分细度的滑动条
sliderRep = vtk.vtkSliderRepresentation2D()
sliderRep.SetMinimumValue(0)
sliderRep.SetMaximumValue(octree.GetLevel())
sliderRep.SetValue(0)
sliderRep.SetTitleText("Level")
sliderRep.GetPoint1Coordinate().SetCoordinateSystemToNormalizedDisplay()
sliderRep.GetPoint1Coordinate().SetValue(.2, .2)
sliderRep.GetPoint2Coordinate().SetCoordinateSystemToNormalizedDisplay()
sliderRep.GetPoint2Coordinate().SetValue(.8, .2)
sliderRep.SetSliderLength(0.075)
sliderRep.SetSliderWidth(0.05)
sliderRep.SetEndCapLength(0.05)
sliderRep.GetTitleProperty().SetColor(colors.GetColor3d("Beige"))
sliderRep.GetCapProperty().SetColor(colors.GetColor3d("MistyRose"))
sliderRep.GetSliderProperty().SetColor(colors.GetColor3d("LightBlue"))
sliderRep.GetSelectedProperty().SetColor(colors.GetColor3d("Violet"))
sliderWidget = vtk.vtkSliderWidget()
sliderWidget.SetInteractor(renderWindowInteractor)
sliderWidget.SetRepresentation(sliderRep)
sliderWidget.SetAnimationModeToAnimate()
sliderWidget.EnabledOn()
# 给滑动条添加观察者
callback = SliderObserver(octree, polydata, renderer)
callback.Octree = octree
callback.PolyData = polydata
callback.Renderer = renderer
sliderWidget.AddObserver('InteractionEvent', callback)
renderWindowInteractor.Initialize()
renderWindow.Render()
renderWindowInteractor.Start()
if __name__=='__main__':
fileName = "Armadillo.ply"
OctreeVisualize(fileName)
上述代码为Python代码,修改自VTK官网的C++例子,添加了可以显示PLY模型的代码
C++代码的网址:https://kitware.github.io/vtk-examples/site/Cxx/DataStructures/OctreeVisualize/