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

相关文章

Vue中动态权限到按钮的完整实现方案详解

《Vue中动态权限到按钮的完整实现方案详解》这篇文章主要为大家详细介绍了Vue如何在现有方案的基础上加入对路由的增、删、改、查权限控制,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、数据库设计扩展1.1 修改路由表(routes)1.2 修改角色与路由权限表(role_routes)二、后端接口设计

C#集成DeepSeek模型实现AI私有化的流程步骤(本地部署与API调用教程)

《C#集成DeepSeek模型实现AI私有化的流程步骤(本地部署与API调用教程)》本文主要介绍了C#集成DeepSeek模型实现AI私有化的方法,包括搭建基础环境,如安装Ollama和下载DeepS... 目录前言搭建基础环境1、安装 Ollama2、下载 DeepSeek R1 模型客户端 ChatBo

Qt实现发送HTTP请求的示例详解

《Qt实现发送HTTP请求的示例详解》这篇文章主要为大家详细介绍了如何通过Qt实现发送HTTP请求,文中的示例代码讲解详细,具有一定的借鉴价值,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1、添加network模块2、包含改头文件3、创建网络访问管理器4、创建接口5、创建网络请求对象6、创建一个回复对

C++实现回文串判断的两种高效方法

《C++实现回文串判断的两种高效方法》文章介绍了两种判断回文串的方法:解法一通过创建新字符串来处理,解法二在原字符串上直接筛选判断,两种方法都使用了双指针法,文中通过代码示例讲解的非常详细,需要的朋友... 目录一、问题描述示例二、解法一:将字母数字连接到新的 string思路代码实现代码解释复杂度分析三、

grom设置全局日志实现执行并打印sql语句

《grom设置全局日志实现执行并打印sql语句》本文主要介绍了grom设置全局日志实现执行并打印sql语句,包括设置日志级别、实现自定义Logger接口以及如何使用GORM的默认logger,通过这些... 目录gorm中的自定义日志gorm中日志的其他操作日志级别Debug自定义 Loggergorm中的

Spring Boot整合消息队列RabbitMQ的实现示例

《SpringBoot整合消息队列RabbitMQ的实现示例》本文主要介绍了SpringBoot整合消息队列RabbitMQ的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的... 目录RabbitMQ 简介与安装1. RabbitMQ 简介2. RabbitMQ 安装Spring

Gin框架中的GET和POST表单处理的实现

《Gin框架中的GET和POST表单处理的实现》Gin框架提供了简单而强大的机制来处理GET和POST表单提交的数据,通过c.Query、c.PostForm、c.Bind和c.Request.For... 目录一、GET表单处理二、POST表单处理1. 使用c.PostForm获取表单字段:2. 绑定到结

springMVC返回Http响应的实现

《springMVC返回Http响应的实现》本文主要介绍了在SpringBoot中使用@Controller、@ResponseBody和@RestController注解进行HTTP响应返回的方法,... 目录一、返回页面二、@Controller和@ResponseBody与RestController

nginx中重定向的实现

《nginx中重定向的实现》本文主要介绍了Nginx中location匹配和rewrite重定向的规则与应用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下... 目录一、location1、 location匹配2、 location匹配的分类2.1 精确匹配2

Nginx之upstream被动式重试机制的实现

《Nginx之upstream被动式重试机制的实现》本文主要介绍了Nginx之upstream被动式重试机制的实现,可以通过proxy_next_upstream来自定义配置,具有一定的参考价值,感兴... 目录默认错误选择定义错误指令配置proxy_next_upstreamproxy_next_upst