VTK实现三视图显示及交互STL模型

2024-05-29 17:12

本文主要是介绍VTK实现三视图显示及交互STL模型,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

VTK实现STL模型的三视图显示及交互

最近收到需求,要实现多视图显示同一个STL模型,并且控制主窗口要其他试图窗口也跟着交互,花了点时间去尝试一下,把这个效果给实现出来了,而且实现也挺简单。


效果演示

在这里插入图片描述


要点

  1. 用同一个vtkRenderer传三次给vtkRenderWindow是不行的,要创建三个vtkRenderer来显示用一个vtkActor,分别传给vtkRenderWindow才行。
  2. 用同一个vtkCamera同时控制三个vtkRenderer是不行的,因为vtkCamera的参数发生改变,会同步影响,要实现不同的视角,还是需要准备三个vtkCamera分别传给三个vtkRenderer。
  3. 既然要实现控制一个主vtkCamera,影响另外两个辅vtkCamera也要同步更新,那最直接的方法就是用回调函数。

代码实现

#include <iostream>
#include <vtkAutoInit.h>
#include <vtkSTLReader.h>
#include <vtkPLYReader.h>
#include <vtkPolyDataMapper.h>
#include <vtkSmartPointer.h>
#include <vtkActor.h>
#include <vtkCamera.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkTransform.h>#include <vtkGenericOpenGLRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkCommand.h>
VTK_MODULE_INIT(vtkRenderingOpenGL2)
VTK_MODULE_INIT(vtkInteractionStyle);
VTK_MODULE_INIT(vtkRenderingFreeType);class vtkUpdateCamera : public vtkCommand
{
public:static vtkUpdateCamera* New(){return new vtkUpdateCamera;}void Execute(vtkObject* caller, unsigned long vtkNotUsed(event), void* callData){//获取主cameravtkRenderer* renderer = dynamic_cast<vtkRenderer*>(caller);auto camera = renderer->GetActiveCamera();//更新两个辅助camera的参数camera1->SetPosition(camera->GetPosition());camera1->SetFocalPoint(camera->GetFocalPoint());camera1->SetViewUp(camera->GetViewUp());camera1->Azimuth(90);camera1->Modified();//通过调整摄像头的viewup的旋转角度,为辅助摄像头实现上试图,左视图的朝向camera2->SetPosition(camera->GetPosition());camera2->SetFocalPoint(camera->GetFocalPoint());double* viewUp = camera->GetViewUp();double* direction = camera->GetDirectionOfProjection();double view[3];vtkMath::Cross(direction, viewUp, view);camera2->SetViewUp(view);camera2->Azimuth(-90);camera2->Modified();}void SetCamera1(vtkCamera* c){camera1 = c;}void SetCamera2(vtkCamera* c){camera2 = c;}private:vtkCamera* camera1;vtkCamera* camera2;
};int main()
{vtkSmartPointer<vtkSTLReader> reader = vtkSmartPointer<vtkSTLReader>::New();reader->SetFileName("D://Bunny.stl");reader->Update();vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();mapper->SetInputData(reader->GetOutput());vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();actor->SetMapper(mapper);double* bounds = reader->GetOutput()->GetBounds();vtkSmartPointer<vtkCamera> camera = vtkSmartPointer<vtkCamera>::New();camera->SetPosition(0, bounds[2]- 200, 0);camera->SetFocalPoint(reader->GetOutput()->GetCenter());camera->SetViewUp(0, 0, 1);vtkSmartPointer<vtkCamera> camera1 = vtkSmartPointer<vtkCamera>::New();vtkSmartPointer<vtkCamera> camera2 = vtkSmartPointer<vtkCamera>::New();//为主渲染器准备更新摄像头的回调函数vtkSmartPointer<vtkUpdateCamera> callback = vtkSmartPointer<vtkUpdateCamera>::New();callback->SetCamera1(camera1);callback->SetCamera2(camera2);//---------设置主渲染器----------vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();renderer->AddActor(actor);renderer->SetActiveCamera(camera);renderer->SetBackground(1, 1, 1);renderer->SetViewport(0, 0, 0.33, 1);//为主渲染器绑定回调函数,使用AnyEvent为了使任何交互都影响两个辅助摄像头renderer->AddObserver(vtkCommand::AnyEvent, callback);//---------设置第一个辅助渲染器----------vtkSmartPointer<vtkRenderer> renderer1 = vtkSmartPointer<vtkRenderer>::New();auto actors = renderer->GetActors();actors->InitTraversal();for (int i = 0; i < actors->GetNumberOfItems(); i++){renderer1->AddActor(actors->GetNextActor());}renderer1->SetActiveCamera(camera1);renderer1->SetViewport(0.33, 0, 0.66, 1);renderer1->SetBackground(1, 1, 1);//---------设置第二个辅助渲染器----------vtkSmartPointer<vtkRenderer> renderer2 = vtkSmartPointer<vtkRenderer>::New();renderer2->SetActiveCamera(camera2);renderer2->SetViewport(0.66, 0, 1, 1);renderer2->SetBackground(1, 1, 1);actors->InitTraversal();for (int i = 0; i < actors->GetNumberOfItems(); i++){renderer2->AddActor(actors->GetNextActor());}vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();renderWindow->AddRenderer(renderer);renderWindow->AddRenderer(renderer1);renderWindow->AddRenderer(renderer2);renderWindow->SetSize(1200, 400);vtkSmartPointer<vtkInteractorStyleTrackballCamera> style = vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New();vtkSmartPointer<vtkRenderWindowInteractor> rwi = vtkSmartPointer<vtkRenderWindowInteractor>::New();rwi->SetRenderWindow(renderWindow);rwi->SetInteractorStyle(style);rwi->Start();
}

这篇关于VTK实现三视图显示及交互STL模型的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1014138

相关文章

大模型研发全揭秘:客服工单数据标注的完整攻略

在人工智能(AI)领域,数据标注是模型训练过程中至关重要的一步。无论你是新手还是有经验的从业者,掌握数据标注的技术细节和常见问题的解决方案都能为你的AI项目增添不少价值。在电信运营商的客服系统中,工单数据是客户问题和解决方案的重要记录。通过对这些工单数据进行有效标注,不仅能够帮助提升客服自动化系统的智能化水平,还能优化客户服务流程,提高客户满意度。本文将详细介绍如何在电信运营商客服工单的背景下进行

hdu1043(八数码问题,广搜 + hash(实现状态压缩) )

利用康拓展开将一个排列映射成一个自然数,然后就变成了普通的广搜题。 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#inclu

第10章 中断和动态时钟显示

第10章 中断和动态时钟显示 从本章开始,按照书籍的划分,第10章开始就进入保护模式(Protected Mode)部分了,感觉从这里开始难度突然就增加了。 书中介绍了为什么有中断(Interrupt)的设计,中断的几种方式:外部硬件中断、内部中断和软中断。通过中断做了一个会走的时钟和屏幕上输入字符的程序。 我自己理解中断的一些作用: 为了更好的利用处理器的性能。协同快速和慢速设备一起工作

Andrej Karpathy最新采访:认知核心模型10亿参数就够了,AI会打破教育不公的僵局

夕小瑶科技说 原创  作者 | 海野 AI圈子的红人,AI大神Andrej Karpathy,曾是OpenAI联合创始人之一,特斯拉AI总监。上一次的动态是官宣创办一家名为 Eureka Labs 的人工智能+教育公司 ,宣布将长期致力于AI原生教育。 近日,Andrej Karpathy接受了No Priors(投资博客)的采访,与硅谷知名投资人 Sara Guo 和 Elad G

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

让树莓派智能语音助手实现定时提醒功能

最初的时候是想直接在rasa 的chatbot上实现,因为rasa本身是带有remindschedule模块的。不过经过一番折腾后,忽然发现,chatbot上实现的定时,语音助手不一定会有响应。因为,我目前语音助手的代码设置了长时间无应答会结束对话,这样一来,chatbot定时提醒的触发就不会被语音助手获悉。那怎么让语音助手也具有定时提醒功能呢? 我最后选择的方法是用threading.Time

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

安卓链接正常显示,ios#符被转义%23导致链接访问404

原因分析: url中含有特殊字符 中文未编码 都有可能导致URL转换失败,所以需要对url编码处理  如下: guard let allowUrl = webUrl.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) else {return} 后面发现当url中有#号时,会被误伤转义为%23,导致链接无法访问

C#实战|大乐透选号器[6]:实现实时显示已选择的红蓝球数量

哈喽,你好啊,我是雷工。 关于大乐透选号器在前面已经记录了5篇笔记,这是第6篇; 接下来实现实时显示当前选中红球数量,蓝球数量; 以下为练习笔记。 01 效果演示 当选择和取消选择红球或蓝球时,在对应的位置显示实时已选择的红球、蓝球的数量; 02 标签名称 分别设置Label标签名称为:lblRedCount、lblBlueCount