日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

VTK修炼之道81:VTK开发基础_vtkObject类深入分析

發布時間:2025/3/15 编程问答 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 VTK修炼之道81:VTK开发基础_vtkObject类深入分析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

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()函數實現具體的功能
  • 實現Execute()函數的兩種方式
第一種方式是生成vtkCommand子類,并覆蓋Execute()函數,在該函數中實現相應的功能。virtual void Execute(vtkObject* caller, unsigned long eventId, void* callData) = 0;該函數有三個參數,caller為觸發消息對象;eventId為消息Id;callData為消息觸發時需要傳遞的數據。 第二種方式是使用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.

總結

以上是生活随笔為你收集整理的VTK修炼之道81:VTK开发基础_vtkObject类深入分析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。