VTK學習記錄9-Observer/command設計模式
阿新 • • 發佈:2021-07-17
用New()建立的,最後記得要用delete釋放掉,不然時間久了會內容洩露。不用現在基本用智慧指標了,那就另說了。
Observer模式:是一種行為模式,這一模式主要針對兩個物件:Object和Observer。
一個Object可以有多個Observer,它定義物件間的一種一對多的依賴關係。
當一個Object的狀態發生改變時,所有依賴於它的Observer物件都得到通知並被自動更新。
Command模式:屬於物件行為模式,Command模式將一個請求封裝成一個物件,並提供一致性請求的介面。
事件呼叫者只是和介面打交道。不和具體實現互動。
-------------------------------------------------------------------------------------------------------------------------
vtkObject通過註冊感興趣的事件把Command和事件聯絡在一起,然後編寫回調函式響應事件的發生。
比如vtkRenderer當訊息StartEvent發生時,開始對資料進行渲染,而當訊息EndEvent發生時停止渲染。
任意一個vtkObject的例項可以通過呼叫AddObserver()方法來新增對事件的觀察。
只需將事件的id和自定義的回撥函式進行關聯,VTK就能方便地實現訊息處理。
程式碼:
1 //tips:如果不是用cmake編譯,而是用vs編譯的,需要加這三行。 2 #include "vtkAutoInit.h" 3 VTK_MODULE_INIT(vtkRenderingOpenGL2); //VTK was built with vtkRenderingOpenGL2 4 VTK_MODULE_INIT(vtkInteractionStyle); 5 6 #include <vtkConeSource.h> 7 #include <vtkRenderer.h> 8 #include <vtkPolyDataMapper.h> 9 #include <vtkRenderWindow.h> 10 #include <vtkActor.h> 11 #include <vtkCamera.h> 12 #include <vtkRenderWindowInteractor.h> 13#include <vtkCommand.h> 14 #include <vtkProperty.h> 15 16 class vtkMyCallback : public vtkCommand //列印相機位置 17 { 18 public: 19 static vtkMyCallback *New() 20 { 21 return new vtkMyCallback; 22 } 23 virtual void Execute(vtkObject *caller, unsigned long, void*) 24 { 25 vtkRenderer *renderer = reinterpret_cast<vtkRenderer*>(caller); 26 cout << renderer->GetActiveCamera()->GetPosition()[0] << " " 27 << renderer->GetActiveCamera()->GetPosition()[1] << " " 28 << renderer->GetActiveCamera()->GetPosition()[2] << "\n"; 29 } 30 }; 31 class vtkMyCallback2 : public vtkCommand //點選p拾取變紅色 32 { 33 public: 34 static vtkMyCallback2 *New() 35 { 36 return new vtkMyCallback2; 37 } 38 virtual void Execute(vtkObject *caller, unsigned long eventID, void * callData) 39 {//以下是自定義內容,上面幾行是固有寫法? 40 vtkActor *actor2 = reinterpret_cast<vtkActor*>(caller); 41 actor2->GetProperty()->SetColor(1.0, 0.0, 0.0); //設定actor顏色為紅色 42 } 43 44 }; 45 int main() 46 { 47 vtkConeSource *cone = vtkConeSource::New(); 48 cone->SetResolution(8); 49 cone->SetHeight(5); 50 cone->SetRadius(2); 51 52 vtkPolyDataMapper *coneMapper = vtkPolyDataMapper::New(); 53 coneMapper->SetInputData(cone->GetOutput()); 54 coneMapper->SetInputConnection(cone->GetOutputPort()); 55 56 vtkActor *vtkactor = vtkActor::New(); 57 vtkactor->SetMapper(coneMapper); 58 //加入自定義回撥函式2,點選變紅 59 vtkMyCallback2 *mol2 = vtkMyCallback2::New(); 60 vtkactor->AddObserver(vtkCommand::PickEvent, mol2); 61 mol2->Delete(); //這裡一旦監聽到拾取動作,就呼叫回撥函式2,觸發自定義的內容(即變紅色) 62 63 vtkRenderer *render = vtkRenderer::New(); 64 render->AddActor(vtkactor); 65 render->SetBackground(0.1, 0.2, 0.3); 66 67 //加入自己寫的回撥函式 68 vtkMyCallback *mol = vtkMyCallback::New(); 69 render->AddObserver(vtkCommand::StartEvent, mol); 70 71 72 vtkRenderWindow *window = vtkRenderWindow::New(); 73 window->SetSize(500, 500); 74 window->AddRenderer(render); 75 76 vtkRenderWindowInteractor *inter = vtkRenderWindowInteractor::New(); 77 inter->SetRenderWindow(window); 78 79 window->Render(); 80 81 inter->Initialize(); 82 inter->Start(); 83 84 //釋放掉,其他的懶得寫了。自己新增吧 85 cone->Delete(); 86 coneMapper->Delete(); 87 vtkactor->Delete(); 88 render->Delete(); 89 window->Delete(); 90 return 0; 91 }
效果圖: