• 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()
    View Code


       使用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()
    View Code

    参考:

    VTK拾取相关的类

    VTK - Users - point picking problem

    VTK: vtkCellPicker Class Reference

    VTK: vtkPointPicker Class Reference

    VTK修炼之道78:交互与拾取_点拾取

    VTK/Examples/Cxx/PolyData/SelectVisiblePoints

    Ray Casting with Python and VTK: Intersecting lines/rays with surface meshes

  • 相关阅读:
    获取所有栈的信息,只有最上面的和最下面的,但是不能获取栈中间的activity信息
    linux 接收udp流花屏的问题
    ffmpeg剪切视频
    Spring @RequestParam乱码问题
    ewebeditor ie8兼容问题
    [转] 只有十句话,我却看了十分钟,回味无穷
    [php]smtp.class.php
    [asp]jmail发送邮件
    md5加密,常用的几个值(16位和32位)
    JavaScript判断浏览器类型及版本
  • 原文地址:https://www.cnblogs.com/21207-iHome/p/9124024.html
Copyright © 2020-2023  润新知