VTK修炼之道81:VTK开发基础_vtkObject类深入分析
来源:互联网 发布:淘宝朵以专卖店 编辑:程序博客网 时间:2024/05/18 17:40
1.前言
相比于vtkObjectBase,我们接触更多的是vtkObject类。vtkObjectBase类主要实现了引用计数,因此vtkObject及其相关子类都继承了该特性。与此同时,vtkObject中实现了一个在VTK中是用非常广泛的观察者/命令模式,该机制可以方便地处理消息响应,例如处理鼠标消息、键盘消息、进度条消息等,VTK的Widget中大量地使用了该机制进行消息处理。
2.观察者/命令模式的工作流程
vtkObject中定义了一个vtkSubjectHelper对象来管理观察者。vtkSubjectHelper内部定义了一个观察者vtkObserver对象链表。vtkObserver表示一个观察者,其内部定义了一个vtkCommand指针、一个消息ID以及一个表示优先级的变量。直观的理解为:当观察者监听到一个消息时(如鼠标按下消息),就响应vtkCommand定义的回调函数。2.1 添加AddObserver()和删除观察者RemoveObserver()
vtkObject通过如下函数可以添加和删除观察者:unsigned long AddObserver(unsigned long event, vtkCommand* , float priority = 0.0f);void RemoveObserver(unsigned long tag);
- AddObserver用于添加一个观察者
当执行该函数时,vtkSublectHelper对象根据event、vtkCommand对象和priority参数封装为一个vtkObverser,并根据优先级priority顺序添加至观察者列表中。第二个参数为vtkCommand类型,vtkCommand中封装了消息处理函数,该类为一个虚基类,其中定义了一个纯虚函数:virtual void Execute(vtkObject* caller, unsigned long eventId, void* callData) = 0;当观察者检测到event消息时,会响应该函数来执行用户设定的操作。vtkCommand只是定义了一个接口,我们必须生成一个vtkCommand子类,并覆盖Execute()函数实现具体的功能。第一种方式是生成vtkCommand子类,并覆盖Execute()函数,在该函数中实现相应的功能。virtual void Execute(vtkObject* caller, unsigned long eventId, void* callData) = 0;该函数有三个参数,caller为触发消息对象;eventId为消息Id;callData为消息触发时需要传递的数据。
- 实现Execute()函数的两种方式
第二种方式是使用VTKCallbackCommand类。该类继承vtkCommand,其内部虽然覆盖了Execute()函数,但其实现是调用了一个内部函数,我们必须要自己定义这个函数。该函数为: void (*Callback) (vtkObject* , unsigned long , void* , void* );我们需要实现一个相同形式的回调函数,并通过SetCallback()函数来设置回调函数的指针:void SetCallback( void(*f) (vtkObject* caller, unsigned long eid, void* clientdata, void* calldata) );当我们定义了Callback()函数后,通过SetCallback()函数为VTKCallbackCommand设置回调函数。
- 对比实现Execute()函数的两种实现方法
通过对比Callback()函数的形式与Execute()函数,我们可以发现函数参数数目有所不同。不同之处在于Callback()函数多了一个clientdata参数。这是为回调函数中使用其他对象留的一个接口。2.2 VTK中消息触发
vtkObject中定义了触发消息的函数:int InvokeEvent(unsigned long event, void* callData);event为触发的消息ID,callData为触发消息后传递的数据。当使用一个对象的InvokeEvent()来触发一个消息后,对象则遍历其内部添加的vtkObserver对象,一旦发现与某个vtkObserver对象的消息ID一致,就会执行该vtkObserver对象中的vtkCommand回调函数执行相应得操作,将callData传递到vtkCommand对象的Excute()函数中,vtkObject及其子类都可以添加一个或者多个vtkObserver对象,从而实现对不同的消息做出不同的响应。2.3 观察者监听消息实例
#include <vtkVersion.h>#include <vtkSmartPointer.h>#include "vtkTestFilter.h"#include <vtkCallbackCommand.h>#include <vtkCommand.h>void CallbackFunction(vtkObject* caller, long unsigned int eventId, void* clientData, void* callData ){int* callDataCasted = reinterpret_cast<int*>(callData);std::cout << *callDataCasted << std::endl;}int main(){vtkSmartPointer<vtkTestFilter> filter =vtkSmartPointer<vtkTestFilter>::New();vtkSmartPointer<vtkCallbackCommand> callback =vtkSmartPointer<vtkCallbackCommand>::New();callback->SetCallback(CallbackFunction );filter->AddObserver(MyEvent, callback);filter->Update();system("pause");return EXIT_SUCCESS;}
3. 参看资料
1.《C++ primer》
2.《The VTK User’s Guide – 11thEdition》
3. 张晓东, 罗火灵. VTK图形图像开发进阶[M]. 机械工业出版社, 2015.
0 0
- VTK修炼之道81:VTK开发基础_vtkObject类深入分析
- VTK修炼之道80:VTK开发基础_智能指针与引用计数
- VTK修炼之道1_初识VTK
- VTK修炼之道82:VTK管线机制_信息对象类VTKInformation
- VTK修炼之道6_仔细分析一个复杂程序
- VTK修炼之道2_VTK体系结构1
- VTK修炼之道3_VTK体系结构2
- VTK修炼之道4_Win32控制台项目
- VTK修炼之道5_Procedural Source Object
- VTK修炼之道14:图像处理_创建
- VTK修炼之道31:图像二值化_阈值法
- VTK修炼之道32:边缘检测_梯度算子
- VTK修炼之道33:边缘检测_Sobel算子
- VTK修炼之道34:边缘检测_Canny算子
- VTK修炼之道35:边缘检测_Laplace算子
- VTK修炼之道36:图像平滑_均值滤波器
- VTK修炼之道38:图像平滑_中值滤波器
- VTK修炼之道39:图像平滑_各向异性滤波
- 创建 vxlan 并部署 instance
- 81. Search in Rotated Sorted Array II
- hibernate的查询方法
- Volley
- 【PAT】1097. Deduplication on a Linked List
- VTK修炼之道81:VTK开发基础_vtkObject类深入分析
- awk总结
- vim配置文件
- Retrofit2.0使用详解
- oracle一步一步学习(一)
- Java反射机制
- 每天一个linux命令:gzip命令
- FBX生成Prefab
- 初探Lambda表达式-Java多核编程【0】从外部迭代到内部迭代