门户网站建设 总结,求个网站没封的2021,个人网站作业,百度文库个人登录Vtk的了解学习途径跟随代码中的示例#xff0c;循序渐进。本篇详细解析Cone2.exe#xff0c;在Cone.exe基础上新增了观察者的概念#xff0c;在Qt中复现一样的观察者。Demo在这里插入图片描述观察者模式概述观察者模式#xff08;Observer Pattern#xff09;#xff0c;…Vtk的了解学习途径跟随代码中的示例循序渐进。本篇详细解析Cone2.exe在Cone.exe基础上新增了观察者的概念在Qt中复现一样的观察者。Demo在这里插入图片描述观察者模式概述观察者模式Observer Pattern允许一个对象观察者关注另一个对象被观察者的状态变化并在事件发生时自动执行预定操作。观察者回调Observer-Callback 是一种事件驱动的编程机制用于处理 VTK 对象状态变化或特定事件的响应。核心概念事件EventVTK 对象在特定操作或状态变化时会触发事件例如 数据更新如vtkCommand::ModifiedEvent 渲染完成如vtkCommand::EndEvent 鼠标交互如vtkCommand::LeftButtonPressEvent 每个事件都有唯一的标识符如枚举值或字符串。观察者Observer 注册到 VTK 对象上用于 “监听” 特定事件的对象。当被监听的事件触发时观察者会执行关联的回调函数。 回调函数Callback 事件触发时实际执行的代码逻辑通常是自定义函数或方法用于响应事件如更新 UI、处理数据、日志记录等。工作流程步骤一定义回调函数实现处理事件的逻辑需符合 VTK 的回调接口规范。步骤二获取被观察者确定需要监听的 VTK 对象如vtkRenderer、vtkActor等。步骤三注册观察者将回调函数与特定事件绑定到被观察者上。步骤四事件触发与响应当被观察者触发事件时VTK 自动调用对应的回调函数。简单示例在这里插入图片描述在这里插入图片描述观察者实现vtkCommandvtkCommand是观察器/命令设计模式的实现。在这种设计模式中可以“观察”vtkObject的任何实例以了解它可能调用的任何事件。例如vtkRenderer在开始渲染时调用StartEvent在完成渲染时调用EndEvent。过滤器vtkProcessObject的子类在过滤器处理数据时调用StartEvent、ProgressEvent和EndEvent。事件的观察者是通过vtkObject中的AddObserver()方法添加的。AddObserver()除了需要一个事件id或名称外还需要一个vtkCommand实例或子类。请注意vtkCommand旨在被子类化以便可以打包支持回调所需的信息。事件处理可以按优先级列表进行组织因此可以通过设置AbortFlag变量截断特定事件的处理。优先级是通过以下方式设定的AddObserver()方法。默认情况下优先级为0具有相同优先级的事件将按第一个处理顺序中的最后一个处理。事件的排序/中止对于像3D小部件这样的东西很重要如果选择了小部件它们会处理事件然后中止对该事件的进一步处理。否则。事件被传递以供进一步处理。当vtkObject的实例调用事件时它还会将可选的void指针传递给callData。这个callData在大多数时候都是空的。callData并不特定于某一类型的事件而是特定于调用特定事件的vtkObject类型。例如 vtkCommand::PickEvent由vtkProp使用空指针调用但由vtkInteractiorStyleImage使用指向 vtkInteractitorStyleImage对象本身的指针调用。以下是可以使用非nullptr callData调用的事件列表在这里插入图片描述在这里插入图片描述复现Demo有一个很重要的点这个示例代码是阻塞时的循环刷新与Qt的基于消息的编程处理方式不一样这是过程式的编程我们复刻示例保持一块Demo就一个函数否则的话可以使用Qt定时器来实现更新位置就可以了。步骤一创建圆锥体数据源在这里插入图片描述步骤二创建多边形映射器在这里插入图片描述在这里插入图片描述步骤三创建演员类类似osg模型结点在这里插入图片描述在这里插入图片描述步骤四创建渲染器在这里插入图片描述在这里插入图片描述步骤五设置渲染器到渲染窗口在这里插入图片描述步骤六设置观察者回调函数这里回调类放在函数里面定义方便归类demo在这里插入图片描述步骤七用Qt的方式实现不阻塞又是过程化旋转为了看到更加清晰我们设置过渡延迟一循环为1000ms在这里插入图片描述在这里插入图片描述运行效果在这里插入图片描述在这里插入图片描述Demo源码VTKWidget.cppvoid VTKWidget::test_demo4_createCone(){// 步骤一创建圆锥体数据源vtkSmartPointervtkConeSource pConeSource VTKManager::createConeSource(0, 0, 0, 10, 30, 10);// 步骤二创建多边形映射器#if 0vtkSmartPointervtkPolyDataMapper pPolyDataMapper VTKManager::createPolyDataMapper(pConeSource);#elsevtkSmartPointervtkPolyDataMapper pPolyDataMapper VTKManager::createPolyDataMapper(pConeSource-GetOutputPort());#endif// 步骤三创建演员vtkSmartPointervtkActor pActor VTKManager::createActor(pPolyDataMapper);// 步骤四创建渲染器vtkSmartPointervtkRenderer pRenderer VTKManager::createRenderer(pActor, 0.1, 0.2, 0.4);// 步骤五渲染器添加到QVTKWidget渲染_pQVTKWidget-GetRenderWindow()-AddRenderer(pRenderer);// 步骤六设置观察者触发回调函数交互回调class vtkMyCallback : public vtkCommand{public:static vtkMyCallback *New() {return new vtkMyCallback;}void Execute(vtkObject *caller, unsigned long, void*) override{// 注意这个类在函数里面定义其函数内部无法直接-或者.来得到成员函数vtkRenderer *pRenderer reinterpret_castvtkRenderer*(caller);LOG pRenderer-GetActiveCamera()-GetPosition()[0] pRenderer-GetActiveCamera()-GetPosition()[1] pRenderer-GetActiveCamera()-GetPosition()[2];}};vtkMyCallback *pVtkMyCallback vtkMyCallback::New();pRenderer-AddObserver(vtkCommand::StartEvent, pVtkMyCallback);pVtkMyCallback-Delete();// 步骤七过程循环的方式实现旋转QElapsedTimer elapsedTimer;for(int index 0; index 360; index){LOG index;if(!isVisible()){continue;}// 渲染一次_pQVTKWidget-GetRenderWindow()-Render();elapsedTimer.start();while(elapsedTimer.elapsed() 100){qApp-processEvents();}if(!isVisible()){continue;}// 渲染器相机绕焦点旋转VTKManager::rotateAzimuth(pRenderer, 1);}}VTKManager.cppvtkSmartPointervtkConeSource VTKManager::createConeSource(double x, double y, double z, double r, int h, int n){// 步骤一智能指针定义vtkSmartPointervtkConeSource pConeSource;// 步骤二智能指针实例化pConeSource vtkSmartPointervtkConeSource::New();// 步骤三设置中心坐标pConeSource-SetCenter(x, y, z);// 步骤三设置半径pConeSource-SetRadius(r);// 步骤四设置圆锥的高度pConeSource-SetHeight(h);// 步骤五设置圆锥球体的经度分辨率即横向的切片数量横向/水平精细度pConeSource-SetResolution(n);return pConeSource;}vtkSmartPointervtkPolyDataMapper VTKManager::createPolyDataMapper(vtkAlgorithmOutput *pAlgorithmOutput){// 步骤一智能指针定义vtkSmartPointervtkPolyDataMapper pPolyDataMapper;// 步骤二智能指针实例化pPolyDataMapper vtkSmartPointervtkPolyDataMapper::New();// 步骤三设置pPolyDataMapper-SetInputConnection(pAlgorithmOutput);return pPolyDataMapper;}vtkSmartPointervtkActor VTKManager::createActor(vtkPolyDataMapper *pPolyDataMapper){// 步骤一智能指针定义vtkSmartPointervtkActor pActor;// 步骤二智能指针实例化pActor vtkSmartPointervtkActor::New();// 步骤三设置映射器pActor-SetMapper(pPolyDataMapper);return pActor;}vtkSmartPointervtkRenderer VTKManager::createRenderer(std::vectorvtkActor * vectorPActor, double r, double g, double b){// 步骤一智能指针定义vtkSmartPointervtkRenderer pRenderer;// 步骤二智能指针实例化pRenderer vtkSmartPointervtkRenderer::New();// 步骤三设置映射器for(int index 0; index vectorPActor.size(); index){pRenderer-AddActor(vectorPActor.at(index));}// 步骤四设置背景色pRenderer-SetBackground(r, g, b);return pRenderer;}