VTK拾取网格模型上的可见点
消隐与Z-Buffer
使用缓冲器记录物体表面在屏幕上投影所覆盖范围内的全部像素的深度值,依次访问屏幕范围内物体表面所覆盖的每一像素,用深度小(深度用z值表示,z值小表示离视点近)的像素点颜色替代深度大的像素点颜色可以实现消隐,称为深度缓冲器算法。深度缓冲器算法也称为Z-Buffer算法,在物体空间内不对物体表面的可见性进行检测,在图像空间中根据每个像素的深度值确定最终绘制到屏幕的物体表面上各个像素的颜色。
下面的例子中从读入一个简单的8个顶点的立方体STL模型,用vtkSelectVisiblePoints类过滤可见点,并输出相关信息。
VTK: vtkSelectVisiblePoints Class Reference: extract points that are visible (based on z-buffer calculation). vtkSelectVisiblePoints is a filter that selects points based on whether they are visible or not. Visibility is determined by accessing the z-buffer of a rendering window. (The position of each input point is converted into display coordinates, and then the z-value at that point is obtained. If within the user-specified tolerance, the point is considered visible.) Points that are visible are passed to the output. Associated data attributes are passed to the output as well.
鼠标左键旋转到不同视角,点击右键观察输出的信息:
#!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() # 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 SetVisibleFilter(self, vis): self.VisibleFilter = vis def RightButtonPressEvent(self,obj,event): self.VisibleFilter.Update() print "number of visible points: ", self.VisibleFilter.GetOutput().GetNumberOfPoints() mapper = vtk.vtkPolyDataMapper() mapper.SetInputData(self.VisibleFilter.GetOutput()) actor =vtk.vtkActor() actor.SetMapper(mapper) actor.GetProperty().SetPointSize(15) self.GetDefaultRenderer().AddActor(actor) # Forward events self.OnRightButtonDown() return def CreateScene(): # Create a rendering window and renderer renWin = vtk.vtkRenderWindow() ren = vtk.vtkRenderer() # Set background color ren.GradientBackgroundOn() ren.SetBackground(.1, .1, .1) ren.SetBackground2(0.8,0.8,0.8) # Set window size renWin.SetSize(600, 600) renWin.AddRenderer(ren) # Create a renderwindowinteractor iren = vtk.vtkRenderWindowInteractor() iren.SetRenderWindow(renWin) style = MyInteractor() style.SetDefaultRenderer(ren) iren.SetInteractorStyle(style) # load STL file mesh = loadSTL("cube.stl") mapper = vtk.vtkPolyDataMapper() mapper.SetInputData(mesh) # maps polygonal data to graphics primitives actor = vtk.vtkLODActor() actor.SetMapper(mapper) ren.AddActor(actor) visPts = vtk.vtkSelectVisiblePoints() visPts.SetInputData(mesh) visPts.SetRenderer(ren) style.SetVisibleFilter(visPts) # Enable user interface interactor iren.Initialize() iren.Start() if __name__ == "__main__": CreateScene()
使用vtkCellPicker可以拾取模型上可见的面和点的信息(vtkCellPicker will shoot a ray into a 3D scene and return information about the first object that the ray hit),而用vtkPointPicker拾取点时会选择离射线距离最近的点,因此所选的点可能位于不可见的表面上。
#!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() 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 mapper = vtk.vtkPolyDataMapper() mapper.SetInputConnection(sphereSource.GetOutputPort()) actor = vtk.vtkActor() actor.SetMapper(mapper) actor.GetProperty().SetColor(1.0, 0.0, 0.0) self.GetDefaultRenderer().AddActor(actor) # Forward events self.OnRightButtonDown() return 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("Suzanne.stl") mapper = vtk.vtkPolyDataMapper() mapper.SetInputData(mesh) # maps polygonal data to graphics primitives actor = vtk.vtkLODActor() actor.SetMapper(mapper) actor.GetProperty().EdgeVisibilityOn() actor.GetProperty().SetLineWidth(0.3) ren.AddActor(actor) # Enable user interface interactor iren.Initialize() iren.Start() if __name__ == "__main__": CreateScene()
参考:
VTK - Users - point picking problem
VTK: vtkCellPicker Class Reference
VTK: vtkPointPicker Class Reference
VTK/Examples/Cxx/PolyData/SelectVisiblePoints
Ray Casting with Python and VTK: Intersecting lines/rays with surface meshes
相关文章
- 特征工程系列之非线性特征提取和模型堆叠
- 模型选择–网格搜索
- 10 关联模型《ThinkPHP6 入门到电商实战》
- 分享16个我总结的思维模型(程序员必读,受用终身)
- 结构建模设计——Solidworks软件之在已建模型的基础上进行特征修改及模型报错的解决方法实战
- OSI模型「建议收藏」
- E-R图向关系模型的转换_简述ER模型
- XGBoost+LightGBM+LSTM:一次机器学习比赛中的高分模型方案
- 数据挖掘机器学习[四]---汽车交易价格预测详细版本{嵌入式特征选择(XGBoots,LightGBM),模型调参(贪心、网格、贝叶斯调参)}
- PGL图学习之图游走类metapath2vec模型[系列五]
- python和netlogo软件模拟病毒传播仿真模型(一)
- TP6.0 一对多模型关联 hasMany
- 清华朱军团队开源首个基于Transformer的多模态扩散大模型,文图互生、改写全拿下
- IJCV 2022|逆转特征让re-id模型从88.54%到0.15%
- 云服务的抽象路由模型
- 理解Redis中的多线程模型(怎么理解redis多线程)
- C++中I/O模型之select模型实例