zoukankan      html  css  js  c++  java
  • VTK 交互与拾取_点拾取

    1.拾取

    选择拾取是人机交互过程的一个重要功能。
    一个最经典的例子就是,在玩3D游戏时,场景中可能会存在多个角色,有时需要用鼠标来选择所要控制的角色,这就要用到拾取功能。
    另外,在某些三维图形的编辑软件中,经常需要编辑其中的一个点、一个面片或者一个局部区域,这也需要通过拾取功能来完成。
    VTK中定义了多个拾取功能的类,具体的继承关系如下:
    VTK中所有的拾取类都继承自vtkAbstractPicker类,在这些类的基础之上可以实现非常复杂的功能。

    2.点拾取

    从上图中能够知晓,完成点拾取功能的类是vtkPointPicker。
    vtk中的消息是通过vtkRenderWindowInteractor类处理的,在类vtkRenderWindowInteractor中,定义如下函数:
    virtual void SetPicker(vtkAbstractPicker*  );
    该函数用来设置具体的VTKAbstractPicker对象,并执行相应的拾取操作。因此对于点拾取,实际就是设置VTKPointPicker的过程。
    之前,曾经细致的研究过,vtkRenderWindowInteractor内部定义了一个vtkInteractorStyle对象。vtkInteractorStyle类是一个虚基类,其子类定义了多种鼠标和键盘消息的处理方法,在实现拾取操作是,需要定制相应的鼠标消息处理函数。比如拾取某个点时,应该响应鼠标的左键按下消息,并在响应该消息的函数中根据鼠标的当前窗口坐标来完成拾取操作。
    点拾取的示例代码如下:
      1 #include <vtkAutoInit.h>
      2 VTK_MODULE_INIT(vtkRenderingOpenGL)
      3 VTK_MODULE_INIT(vtkRenderingFreeType)
      4 VTK_MODULE_INIT(vtkInteractionStyle)
      5  
      6 #include <vtkSmartPointer.h>
      7 #include <vtkSphereSource.h>
      8 #include <vtkPolyDataMapper.h>
      9 #include <vtkActor.h>
     10 #include <vtkRenderer.h>
     11 #include <vtkRenderWindow.h>
     12 #include <vtkRenderWindowInteractor.h>
     13  
     14 #include <vtkPointPicker.h>
     15 //this->Interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer()
     16 #include <vtkRendererCollection.h> 
     17 #include <vtkInteractorStyleTrackballCamera.h>
     18 #include <vtkObjectFactory.h>  //vtkStandardNewMacro();
     19 #include <vtkProperty.h>
     20  
     21 #include <vtkAxesActor.h>
     22 #include <vtkOrientationMarkerWidget.h>
     23 /**************************************************************************************************/
     24 class PointPickerInteractorStyle : public vtkInteractorStyleTrackballCamera
     25 {
     26 public:
     27     static PointPickerInteractorStyle* New();
     28     vtkTypeMacro(PointPickerInteractorStyle, vtkInteractorStyleTrackballCamera);
     29  
     30     virtual void OnLeftButtonDown()
     31     {
     32         //打印鼠标左键像素位置
     33         std::cout << "Picking pixel: " << this->Interactor->GetEventPosition()[0] 
     34             << " " << this->Interactor->GetEventPosition()[1] << std::endl;
     35         //注册拾取点函数
     36         this->Interactor->GetPicker()->Pick(
     37             this->Interactor->GetEventPosition()[0],
     38             this->Interactor->GetEventPosition()[1], 0,  // always zero.
     39             this->Interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer()
     40             );
     41         //打印拾取点空间位置
     42         double picked[3];
     43         this->Interactor->GetPicker()->GetPickPosition(picked);
     44         std::cout << "Picked value: " << picked[0] << " " << picked[1] << " " << picked[2] << std::endl;
     45         //对拾取点进行标记
     46         vtkSmartPointer<vtkSphereSource> sphereSource =
     47             vtkSmartPointer<vtkSphereSource>::New();
     48         sphereSource->Update();
     49  
     50         vtkSmartPointer<vtkPolyDataMapper> mapper =
     51             vtkSmartPointer<vtkPolyDataMapper>::New();
     52         mapper->SetInputConnection(sphereSource->GetOutputPort());
     53  
     54         vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
     55         actor->SetMapper(mapper);
     56         actor->SetPosition(picked);
     57         actor->SetScale(0.05);
     58         actor->GetProperty()->SetColor(1.0, 0.0, 0.0);
     59         this->Interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer()->AddActor(actor);
     60  
     61         vtkInteractorStyleTrackballCamera::OnLeftButtonDown();
     62     }
     63 };
     64 /**************************************************************************************************/
     65  
     66 vtkStandardNewMacro(PointPickerInteractorStyle);
     67  
     68 int main()
     69 {
     70     vtkSmartPointer<vtkSphereSource> sphereSource =
     71         vtkSmartPointer<vtkSphereSource>::New();
     72     sphereSource->Update();
     73  
     74     vtkSmartPointer<vtkPolyDataMapper> mapper =
     75         vtkSmartPointer<vtkPolyDataMapper>::New();
     76     mapper->SetInputConnection(sphereSource->GetOutputPort());
     77     vtkSmartPointer<vtkActor> actor =
     78         vtkSmartPointer<vtkActor>::New();
     79     actor->SetMapper(mapper);
     80  
     81     vtkSmartPointer<vtkRenderer> renderer =
     82         vtkSmartPointer<vtkRenderer>::New();
     83     renderer->AddActor(actor);
     84     renderer->SetBackground(1, 1, 1);
     85  
     86     vtkSmartPointer<vtkRenderWindow> renderWindow =
     87         vtkSmartPointer<vtkRenderWindow>::New();
     88     renderWindow->Render();
     89     renderWindow->SetWindowName("PointPicker");
     90     renderWindow->AddRenderer(renderer);
     91  
     92     vtkSmartPointer<vtkPointPicker> pointPicker =
     93         vtkSmartPointer<vtkPointPicker>::New();
     94  
     95     vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
     96         vtkSmartPointer<vtkRenderWindowInteractor>::New();
     97     renderWindowInteractor->SetPicker(pointPicker);
     98     renderWindowInteractor->SetRenderWindow(renderWindow);
     99  
    100     vtkSmartPointer<PointPickerInteractorStyle> style =
    101         vtkSmartPointer<PointPickerInteractorStyle>::New();
    102     renderWindowInteractor->SetInteractorStyle(style);
    103     /
    104     vtkSmartPointer<vtkAxesActor>  Axes = vtkSmartPointer<vtkAxesActor>::New();
    105     vtkSmartPointer<vtkOrientationMarkerWidget>  widget =
    106         vtkSmartPointer<vtkOrientationMarkerWidget>::New();
    107     widget->SetInteractor(renderWindowInteractor);
    108     widget->SetOrientationMarker(Axes);
    109     widget->SetOutlineColor(1, 1, 1);
    110     widget->SetViewport(0, 0, 0.2, 0.2);
    111     widget->SetEnabled(1);
    112     widget->InteractiveOn();
    113     
    114     renderWindow->Render();
    115     renderWindowInteractor->Start();
    116  
    117     return 0;
    118 }
    实际操作细节分析:
    • vtkInteractorStyleTrackballCemera派生类设计
    PointPickerInteractorStyle类从vtkInteractorStyleTrackballCemera派生,并覆盖了该类OnLeftButtonDown()函数。在该函数中,调用了vtkRenderWindowInteractor的GetEventPosition()函数输出鼠标点击的屏幕坐标。
    • 拾取函数Pick()设计
    int Pick(double selectionX, double selectionY, double selectionZ, vtkRender* renderer);
    该函数需要接受四个参数,前三个为(selectionX,selectionY,selectionZ),即鼠标的当前窗口坐标,其中selectionZ通常为零。最后一个是vtkRenderer对象。
    • GetPackPosition()是指世界坐标系下拾取点的坐标
    • mian()函数中设计拾取调用流程
     1 vtkSmartPointer<vtkPointPicker> pointPicker =
     2     vtkSmartPointer<vtkPointPicker>::New();
     3  
     4 vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
     5     vtkSmartPointer<vtkRenderWindowInteractor>::New();
     6 renderWindowInteractor->SetPicker(pointPicker);
     7 renderWindowInteractor->SetRenderWindow(renderWindow);
     8  
     9 vtkSmartPointer<PointPickerInteractorStyle> style =
    10     vtkSmartPointer<PointPickerInteractorStyle>::New();
    11 renderWindowInteractor->SetInteractorStyle(style);
    实例化vtkPointPicker对象以后,调用vtkRenderWindowInteractor::SetPicker()函数将其设置到渲染窗口交互器中。PointPickerInteractorStyle类与vtkInteractorStyleImage等交互器样式使用方法一致。
  • 相关阅读:
    phpinfo mac 和 php -moudle里的不一致(mongodb篇)
    0、服务启动前之日志字段和格式
    P3740 贴海报
    树状数组区间修改and查询和
    P1823 Patrik 音乐会的等待
    西安段素扫描线
    P1903 数颜色
    P1220 关路灯
    [p1559] 运动员最佳匹配问题
    treap数组版
  • 原文地址:https://www.cnblogs.com/ybqjymy/p/14244545.html
Copyright © 2011-2022 走看看