VTK交互-观察者/命令模式
来源:互联网 发布:淘宝授权书psd模板 编辑:程序博客网 时间:2024/06/03 12:30
观察者/命令模式
vtk中用到大量的面向对象设计模式,如工厂模式、观察者/命令模式、另外还用到引用计数与智能指针等高级内存管理知识。
前面的博客讲过观察者/命令模式这个模式了 这里就不细说了。
观察者/命令模式(Observer/Command)是vtk里用的较多的设计模式。vtk中 绝大多数的类都派生自vtkobject。查看类vtkobject的接口可以找到AddObserver()、RemoveObserver()、GetCommand()等函数,从函数的字面意思可以看出,这些函数是与观察者/命令模式相关的。
观察者/命令模式是指一个Object可以有多个Observer,它定义了对象间的一种多对多的依赖关系,当一个Object对象的状态发生改变时,所有依赖于它的Observer对象都得到通知而被自动更新。命令模式属于对象的行为模式,它将一个请求封装为一个对象,并提供一致性发送请求的接口,当一个事件发生时,它不直接把事件传递给事件调用者,而是在命令和调用者之间增加一个中间者,讲这种关系直接切断,同时将两者都隔离。事件调用者只是和接口打交道,不和具体时间实现交互,在vtk中,可以通过这两种方式来实现观察者/命令模式,它们分别是使用事件回调函数以及从VTK派生出来具体的子类。
事件回调函数
在vtkOBject中,有如下函数:
unsigned long AddObserver(unsigned long event,vtkCommand *,float priority=0.0f);unsigned long AddObserver(unsigned char* event,vtkCommand *,float priority=0.0f);
AddObserver()函数的作用就是针对某个事件添加观察者到某个VTK对象中,当该对象发生观察者感兴趣的事件时,就会调用回调函数,执行相关的操作。
#include <vtkSmartPointer.h>#include <vtkImageReader2.h>#include <vtkMatrix4x4.h>#include <vtkImageReslice.h>#include <vtkLookupTable.h>#include <vtkImageMapToColors.h>#include <vtkImageActor.h>#include <vtkRenderer.h>#include <vtkRenderWindow.h>#include <vtkRenderWindowInteractor.h>#include <vtkInteractorStyleImage.h>#include <vtkCommand.h>#include <vtkImageData.h>#include <vtkMetaImageReader.h>#include <vtkImageCast.h>#include"vtkPNGReader.h"#include"vtkAutoInit.h"#include"vtkImageViewer2.h"#include"vtkProperty.h"#include"vtkCallbackCommand.h"VTK_MODULE_INIT(vtkRenderingOpenGL);VTK_MODULE_INIT(vtkInteractionStyle);VTK_MODULE_INIT(vtkRenderingFreeType);VTK_MODULE_INIT(vtkRenderingVolumeOpenGL);long pressCounts = 0;void MyCallbackFunc(vtkObject *,unsigned long eid,void *clientdata,void *calldata){ std::cout << "You have clicked: " << ++pressCounts << " Times." << endl;}int main(int argc,char *argv[]){ std::string filename = "VTK-logo.png"; vtkSmartPointer<vtkPNGReader> reader = vtkSmartPointer<vtkPNGReader>::New(); reader->SetFileName(filename.c_str()); vtkSmartPointer<vtkImageViewer2> viewer = vtkSmartPointer<vtkImageViewer2>::New(); viewer->SetInputData(reader->GetOutput()); vtkSmartPointer<vtkRenderWindowInteractor> interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New(); viewer->SetupInteractor(interactor); viewer->Render(); vtkSmartPointer<vtkCallbackCommand> mouseCallback = vtkSmartPointer<vtkCallbackCommand>::New(); mouseCallback->SetCallback(MyCallbackFunc); interactor->SetRenderWindow(viewer->GetRenderWindow()); interactor->AddObserver(vtkCommand::LeftButtonPressEvent,mouseCallback); interactor->Initialize(); interactor->Start(); return 0;}
vtkCommand子类
观察者/命令模式除了使用事件回调函数外,还可以直接从vtkCommand类中派生出子类来实现。
#include <vtkSmartPointer.h>#include <vtkImageReader2.h>#include <vtkMatrix4x4.h>#include <vtkImageReslice.h>#include <vtkLookupTable.h>#include <vtkImageMapToColors.h>#include <vtkImageActor.h>#include <vtkRenderer.h>#include <vtkRenderWindow.h>#include <vtkRenderWindowInteractor.h>#include <vtkInteractorStyleImage.h>#include <vtkCommand.h>#include <vtkImageData.h>#include <vtkMetaImageReader.h>#include <vtkImageCast.h>#include"vtkPNGReader.h"#include"vtkAutoInit.h"#include"vtkImageViewer2.h"#include"vtkProperty.h"#include"vtkCallbackCommand.h"#include"vtkPolyDataMapper.h"VTK_MODULE_INIT(vtkRenderingOpenGL);VTK_MODULE_INIT(vtkInteractionStyle);VTK_MODULE_INIT(vtkRenderingFreeType);VTK_MODULE_INIT(vtkRenderingVolumeOpenGL);#include"vtkConeSource.h"class vtkMyCallback : public vtkCommand{public: static vtkMyCallback *New() { return new vtkMyCallback; } void SetObject(vtkConeSource *cone) { m_Cone = cone; } virtual void Execute(vtkObject *caller,unsigned long eventId,void *callData) { std::cout << "Left button pressed.\n" << "The Height:" << m_Cone->GetHeight() << "\n" << "The Radius:" << m_Cone->GetRadius() << std::endl; }private: vtkConeSource *m_Cone;};int main(){ vtkSmartPointer<vtkConeSource> cone = vtkSmartPointer<vtkConeSource>::New(); cone->SetHeight(3.0); cone->SetRadius(1.0); cone->SetResolution(1.0); vtkSmartPointer<vtkPolyDataMapper> coneMapper = vtkSmartPointer<vtkPolyDataMapper>::New(); coneMapper->SetInputConnection(cone->GetOutputPort()); vtkSmartPointer<vtkActor> coneActor = vtkSmartPointer<vtkActor>::New(); coneActor->SetMapper(coneMapper); vtkSmartPointer<vtkRenderer> ren1 = vtkSmartPointer<vtkRenderer>::New(); ren1->AddActor(coneActor); ren1->SetBackground(0.1,0.2,0.4); vtkSmartPointer<vtkRenderWindow> renwin = vtkSmartPointer<vtkRenderWindow>::New(); renwin->AddRenderer(ren1); renwin->SetSize(300, 300); vtkSmartPointer<vtkRenderWindowInteractor> iren = vtkSmartPointer<vtkRenderWindowInteractor>::New(); iren->SetRenderWindow(renwin); vtkSmartPointer<vtkInteractorStyleTrackballCamera> style = vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New(); iren->SetInteractorStyle(style); vtkSmartPointer<vtkMyCallback> callback = vtkSmartPointer<vtkMyCallback>::New(); callback->SetObject(cone); iren->AddObserver(vtkCommand::LeftButtonPressEvent,callback); iren->Initialize(); iren->Start(); return EXIT_SUCCESS;}
上面的程序同样演示的是鼠标左键单击消息,如果监听到单击消息,就在控制台中打出主程序所设置的椎体的高和底面积等信息。vtkMyCallback是从vtkCommand类中派生的,SetObject()函数用于设置椎体对象。利用这种方式使用VTK的观察者/命令模式也应该遵循如下三个步骤。
**(1) 从vtkCommand类派生子类,并实现vtkCommand::Execute()虚函数,该函数的原型为:
**virtual void Execute(vtkObject *caller,unsigned long evemtId,void *callData)=0;
(3) 调用AddObserver()函数监听感兴趣的事件。如果所监听的事件会发生,会调用vtkCommand子类中的Execute()函数,针对所监听的事件,程序需要实现的功能一般都放在Execute()函数中。
- VTK交互-观察者/命令模式
- VTK修炼之道71:交互与Widget_观察者/命令模式
- vtk切换交互模式
- VTK修炼之道27:图像基本操作_三维图像切片交互提取(回调函数、观察者-命令模式)
- vtk基础02观察者/命令机制
- 利用VTK观察者模式Pick拾取
- vtk交互
- VTK交互
- vtk交互
- VTK: VTK实体交互widget
- VTK交互之交互样式
- VTK交互机制
- VTK鼠标交互方式
- vtk交互(2)
- VTK交互之vtkCommand
- VTK交互之Widget
- VTK交互之拾取
- VTK学习笔记:使用VTK交互功能
- 【CF】Codeforces Round #423(Div.1)
- Resource interpreted as Stylesheet but transferred with MIME type application/octet-stream
- Lamda表达式,从抵制到喜欢
- 关于协方差矩阵
- 中国IT风险投资机构
- VTK交互-观察者/命令模式
- Git合并分支(下)
- 牛客练习赛8,给个n,求1到n的所有数的约数个数的和~
- 人到了32岁就有自己的工作方法了吗
- 2296: 【POJ Challenge】随机种子
- 决策树学习笔记整理
- IE浏览器bug 原因 haslayout
- 一次诡异的NIO和IO性能测试
- qt configure