用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 }
效果图: