VTK修炼之道72:交互与Widget_交互器样式

来源:互联网 发布:淘宝大码学生女装店 编辑:程序博客网 时间:2024/05/19 17:03

1.vtkRenderWindowInteractor

该类就是渲染窗口交互器,它提供一种平台独立的响应鼠标/按键/时钟事件的交互机制,可将平台相关的鼠标/按键/时钟等消息传至vtkInteractorObservser或其子类。
也就是说,vtkRenderWindowInteractor作为一个基类,其具体的功能是由平台相关的子类(如vtkWin32RenderWindowInteractor)来完成的。当从窗口系统中监听到感兴趣的事件/消息时,通过调用InvokeEvent()函数将平台相关的事件翻译成VTK事件。而这些VTK事件是平台独立的,然后在传至VTKInteractorObserver或其子类,再由已经对该事件进行注册的VTKInteractorObservser或其子类相应具体操作。
VTK列表中封装了94个VTK事件。
这里最关心的就是VTK是如何捕捉这些消息并实现交互功能的?
示例代码如下:
#include <vtkAutoInit.h>VTK_MODULE_INIT(vtkRenderingOpenGL);VTK_MODULE_INIT(vtkInteractionStyle);#include <vtkSmartPointer.h>#include <vtkJPEGReader.h>#include <vtkImageActor.h>#include <vtkRenderer.h>#include <vtkRenderWindow.h>#include <vtkRenderWindowInteractor.h>#include <vtkInteractorStyleImage.h>int main(int argc, char* argv[]){vtkSmartPointer<vtkJPEGReader> reader =vtkSmartPointer<vtkJPEGReader>::New();reader->SetFileName("vtk.jpg");reader->Update();//////////////////////////////////////////////vtkSmartPointer<vtkImageActor> imageActor =vtkSmartPointer<vtkImageActor>::New();imageActor->SetInputData(reader->GetOutput());vtkSmartPointer<vtkRenderer> renderer =vtkSmartPointer<vtkRenderer>::New();renderer->AddActor(imageActor);renderer->SetBackground(0, 0, 0);vtkSmartPointer<vtkRenderWindow> renWin =vtkSmartPointer<vtkRenderWindow>::New();renWin->AddRenderer(renderer);renWin->SetSize(640, 480);renWin->Render();renWin->SetWindowName("InteractionStyle by vtkRenderWindowInteractor");vtkSmartPointer<vtkRenderWindowInteractor> iren =vtkSmartPointer<vtkRenderWindowInteractor>::New();iren->SetRenderWindow(renWin);vtkSmartPointer<vtkInteractorStyleImage> style =vtkSmartPointer<vtkInteractorStyleImage>::New();iren->SetInteractorStyle(style);iren->Initialize();iren->Start();return 0;}
该程序先读入一幅JPG图像,然后用vtkImageActor、vtkRenderer、vtkRenderWindow等建立可视化管线。
值得注意的是,在以上实例中,使用类VTKInteractorStyle作为交互器样式。该交互器样式预设了针对二维图像的交互功能,比如:
  • 同时按下<Ctrl>键和鼠标左键可以实现图像的旋转;
  • 同时按下<Shift>键和鼠标左键可以实现图像平移;
  • 按下鼠标左键并移动鼠标可以调节图像的窗宽和窗位;
  • 按下<R>键可以实现图像的窗宽和窗位的重置;
  • 滑动鼠标滚轮可以实现图像的放缩。
根据前述内容可以知晓,vtkRenderWindowInteractor是一个基类,具体的操作,是由平台相关的子类实现。因为,该程序是在win32平台下的,因此,该平台下的消息先有vtkWin32RenderWindowInteractor类捕获。
下面以窗宽和窗位的重置为例,跟踪当用户按下<R>键时,消息是如何传递的。

2.vtkInteractorStyle


交互模式的内部执行流程如下:
  • Windows消息被vtkWin32RenderWindowInteractor捕获,捕获到消息之后,先由vtkWin32RenderWindowInteractor类的回调函数vtkHandleMessage2()分发到各个消息的响应函数。
  • 每个消息响应函数的最后,通过调用vtkObject::InvokeEvent()再将Windows消息翻译成VTK事件。
  • vtkObject::InvokeEvent()函数里,通过类vtkSubjectHelper::InvokeEvent()函数再将各个VTK事件分发到不同的观察者中。
  • 观察者通过回调函数vtkInteractorStyle::ProcessEvents()处理不同的VTK事件。
  • 最后,再将这些VTK事件分发至vtkInteractorStyle或其子类的消息响应函数中,从而完成整个消息的传递过程。

3.参看资料

1.《C++ primer》
2.《The VTK User’s Guide – 11thEdition》
3.  张晓东, 罗火灵. VTK图形图像开发进阶[M]. 机械工业出版社, 2015.
0 0
原创粉丝点击