VTK 平面裁剪
Posted Sam Fang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了VTK 平面裁剪相关的知识,希望对你有一定的参考价值。
有些时候需要显示零件内部情况,所有会对零件显示进行平面裁剪,这里用到了vtkPlane和vtkClipPolyData。
vtkPlane是定义一个平面,vtkClipPolyData使用vtkPlane定义的平面进行裁剪。
下面列出主要的代码,其他Qt框架代码参考前面文章。
QSurfaceFormat::setDefaultFormat(QVTKOpenGLNativeWidget::defaultFormat()); vtkNew<vtkRenderer> renderer; vtkNew<vtkNamedColors> colors; //定义球 vtkNew<vtkSphereSource> sphereSource; sphereSource->SetRadius(10); sphereSource->SetCenter(0, 0, 0); //定义平面 vtkNew<vtkPlane> plane; plane->SetOrigin(3,0,0); plane->SetNormal(-1, 0, 0); //定义裁剪 vtkNew<vtkClipPolyData> clipper; clipper->SetInputConnection(sphereSource->GetOutputPort()); clipper->SetClipFunction(plane); vtkNew<vtkDataSetMapper> clipMapper; clipMapper->SetInputConnection(clipper->GetOutputPort()); vtkNew<vtkActor> clipActor; clipActor->SetMapper(clipMapper); clipActor->GetProperty()->SetDiffuseColor(colors->GetColor4d("Tomato").GetData()); clipActor->GetProperty()->EdgeVisibilityOn(); //显示线框 renderer->AddActor(clipActor); renderer->SetBackground(colors->GetColor3d("SteelBlue").GetData()); vtkNew<vtkGenericOpenGLRenderWindow> renderWindow; renderWindow->AddRenderer(renderer); renderWindow->SetWindowName("RenderWindowNoUIFile"); ui.vtk_main->setRenderWindow(renderWindow);
显示如下:
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()
立体网格:
参考:
VTKExamples/Cxx/Graphs/ShortestPath
VTKExamples/Cxx/PolyData/DijkstraGraphGeodesicPath
以上是关于VTK 平面裁剪的主要内容,如果未能解决你的问题,请参考以下文章