VTK编程指南<三>:基于VTK入门程序解析来理解VTK基础知识

1、VTK入门程序

  下面是一个完整的Vtk入门程序,我们基于这个程序来对VTK的基本知识进行一个初步了解。
在这里插入图片描述

在这里插入图片描述

#include <iostream>#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL2);// VTK was built with vtkRenderingOpenGL2
VTK_MODULE_INIT(vtkInteractionStyle);#include <vtkSmartPointer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkCylinderSource.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkProperty.h>int main()
{vtkSmartPointer <vtkCylinderSource> cylinder =vtkSmartPointer<vtkCylinderSource>::New();cylinder->SetHeight(3.0);cylinder->SetRadius(1.0);cylinder->SetResolution(10);vtkSmartPointer<vtkPolyDataMapper> cylinderMapper =vtkSmartPointer<vtkPolyDataMapper>::New();cylinderMapper->SetInputConnection(cylinder->GetOutputPort());vtkSmartPointer<vtkActor> cylinderActor =vtkSmartPointer<vtkActor>::New();cylinderActor->SetMapper(cylinderMapper);cylinderActor->GetProperty()->SetColor(1.0, 0.0, 0.0);vtkSmartPointer<vtkRenderer> renderer =vtkSmartPointer<vtkRenderer>::New();renderer->AddActor(cylinderActor);renderer->SetBackground(0.4, 0.4, 1.0);vtkSmartPointer<vtkRenderWindow> renWin =vtkSmartPointer<vtkRenderWindow>::New();renWin->AddRenderer(renderer);renWin->SetSize(640, 480);renWin->Render();renWin->SetWindowName("RenderCylinder");vtkSmartPointer<vtkRenderWindowInteractor> iren =vtkSmartPointer<vtkRenderWindowInteractor>::New();iren->SetRenderWindow(renWin);vtkSmartPointer<vtkInteractorStyleTrackballCamera> style =vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New();iren->SetInteractorStyle(style);iren->Initialize();iren->Start();return EXIT_SUCCESS;
}

2、交互快捷键及错误处理

2.1、运行错误处理

#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL2);// VTK was built with vtkRenderingOpenGL2
VTK_MODULE_INIT(vtkInteractionStyle);

  上面这三行代码是为了解决VTK运行openGL报错而添加的,现在的新的电脑大部分编译VTK默认采用的都是vtkRenderingOpenGL2,因此加上这3行,避免报如下错误:

vtkInteractorStyleSwitc:37    WARN| vtkInteractorStyleSwitchBase (00000165F8951AD0): 
Warning: Link to vtkInteractionStyle for default style selection.
Warning: In E:\VTK_9.0.1\src\Rendering\Core\vtkInteractorStyleSwitchBase.cxx, line 37
vtkInteractorStyleSwitchBase (00000165F8951AD0): 
Warning: Link to vtkInteractionStyle for default style selection.

2.2、交互快捷键

  在上图程序运行的窗口中,可以使用鼠标与柱体进行交互,比如用鼠标滚轮可以对柱体放大、缩小;按下鼠标左键不放,然后移动鼠标,可以转动柱体;按下鼠标左键,同时按下Shift
键,移动鼠标,可以移动整个柱体等。读者也可以尝试一下其他的功能,比如按下〈Ctrl〉键
时再按鼠标左键;鼠标停留在柱体上,然后按下〈P〉键;试着按一下〈E〉键呢?关于交互的内容,后续文章会进行介绍。

按键W --------------------- 网格显示模型按键S --------------------- 曲面显示模型按键P --------------------- 显示模型包围框按键F --------------------- 放大到选取点按键R --------------------- 重置相机视图按键A ---------------------- 切换演员模式按键C ---------------------- 切换相机模式按键T ---------------------- 切换轨迹球模式按键J ----------------------- 切换操纵杆模式

3、代码分析

  接下来详细解释一下示例里每行代码的含义以及所用到的VTK类。

3.1、vtkCylinderSource

  该类派生自vtkPolyDataAlgorithm。顾名思义,vtkCylinderSource 生成的数据类型就是vtkPolyData,它主要是生成一个中心在渲染场景原点的柱体,柱体的长轴沿着Y轴,柱体的
高度、截面半径等都可以任意指定。

  vtkCylinderSource::SetHeight():设置柱体的高。
  vtkCylinderSource::SetRadius():设置柱体横截面的半径。
  vtkCylinderSource::SetResolution():设置柱体横截面的等边多边形的边数。转动一下柱体然后数一数柱体横截面有多少条边,应该就能明白这个参数所表示的意思。

3.2、vtkPolyDataMapper

  该类用于渲染多边形儿何数据(vtkPolyData),派生自类vtkMapper,将输入的数据转换
为几何图元(点、线、多边形)进行渲染。
  vtkPolyDataMapper::SetInputConnection():VTK可视化管线的输入数据接口,对应的可视化管线的输出数据接口为 GetOutputPort;VTK5.0 之前的版本使用 SetInput()和 GetOutput()作为输入输出接口,后续版本继续保留。

3.3、vtkActor

  该类派生自vtkProp类,渲染场景中数据的可视化表达通过vtkProp 的子类负责。比如该示例要渲染一个柱体,柱体的数据类型是vtkPolyData,数据要在场景中渲染时,不是直接把数据加入渲染场景,而是以vtkProp的形式存在于渲染场景中。三维空间中渲染对象最常用的vtkProp子类有vtkActor(表达场景中的儿何数据)和 vtkVolume(表达场景中的体数据)。

  二维空间中的数据则是用vtkActor2D 表达:vtkProp 子类负责确定渲染场景中对象的位置、大小和方向等信息;Prop依赖于两个对象:一个是Mapper(vtkMapper)对象,负责存放数据和渲染信息;另一个是属性(vtkProperty)对象,负责控制颜色、不透明度等参数。另外,vtkActor 中还可以设置纹理(vtkTexture)对象,用于纹理贴图。

  VTK定义了大量的 Prop 类,如 vtkImageActor(负责图像显示)和 vtkPieChartActor(用于创建数组数据的饼图可视化表达形式)。其中有些 Prop内部直接包括了控制显示的参数和待渲染数据的索引,因此并不需要额外的 Property 和 Mapper 对象,例如vtkAxisActor。

  vtkActor 的子类vtkFollower 可以自动更新方向信息使其始终面向一个特定的相机,这样无论怎样旋转该对象都是可见的,例如三维场景中的广告板或者文本。vtkActor的子类vtkLODActor 可以自动改变自身的几何表达形式来实现所需的交互帧率。

  vtkAssembly建立了各个Actor 的层次结构以便在整个结构平移、旋转或缩放等变换时能够更合理地进行控制。

  vtkActor::SetMapper():该方法用于设置生成几何图元的 Mapper,即连接一个 Actor 到可视化管线的末端(Mapper是可视化管线的末端)。

3.4、vtkRenderWindow

  将操作系统与VTK渲染引擎连接到一起。不同平台下的vtkRenderWindow 子类负责管理本地计算机系统中窗口创建和渲染过程。当使用VTK开发应用程序时,只需要使用平台无关的 vtkRendererWindow 类,运行时系统会自动替换为平台相关的 vtkRendererWindow 子类。

  比如,Windows下运行上述的VTK程序,实际创建的vtkWin32OpenGLRenderWindow
(vtkRenderWindow的子类)对象。vtkRenderWindow中包含了vtkRenderer集合、渲染参数,如立体显示(Stereo)、反走样、运动模糊(Motion Blur)和焦点深度(Focal Depth)等。

  vtkRenderWindow::AddRenderer():该方法用于加入 vtkRenderer 对象。
  vtkRenderWindow::SetSize():该方法是从vtkRenderWindow的父类vtkWindow 继承过来的,用于设置窗口的大小,以像素为单位。

3.5、vtkRenderer

  负责管理场景的渲染过程。组成场景的对象包括Prop,照相机(vtkCamera)和光照
(vtkLight)都被整合到一个vtkRenderer 对象中。一个vtkRenderWindow 中可以有多个vtkRenderer对象,而这些vtkRenderer 可以渲染在窗口不同的矩形区域中(即视口)或者覆盖整个窗口区域。

  vtkRenderer::AddActor():该方法用于将 vtkProp 类型的对象添加到渲染场景中。

  vtkRenderer::SetBackground):该方法是从 vtkRenderer 的父类 vtkViewport继承的,用于设置渲染场景的背景颜色,用R、G、B的格式设置,三个分量的取值为0.0~1.0。(0.0,0.0,0.0)为黑色,(1.0,1.0,1.0)为白色。

除了可以设置单一的背景颜色之外,还可以设置渐变的背景颜色,vtkViewport::SetBackground2)用于设置渐变的另外一种颜色,但是要使背景颜色渐变生效或者关闭,必须调用以下的方法。

vtkViewport::SetGradientBackground(bool):参数为 0 时,关闭,反之,打开。
vtkViewport::GradientBackgroundOn():
该方法用于打开背景颜色渐变效果,相当于调用方法SetGradientBackground(1)。
vtkViewport::GradientBackgroundOff():
该方法用于关闭背景颜色渐变效果。相当于调用方法SetGradientBackground(0)

3.6、 vtkRenderWindowInteractor

  提供平台独立的响应鼠标、键盘和时钟事件的交互机制,通过VTK的观察者/命令模式将监听到的特定平台的鼠标、键盘和时钟事件交由vtkInteractorObserver 或其子类,如 vtkInteractorStyle 进行处理。vtkInteractorStyle 等监听这些消息并进行处理以完成旋转、拉伸和缩放等运动控制。

  vtkRenderWindowInteractor 会自动建立一个默认的3D场景交互器样式(Interactor Style):

  vtkInteractorStyleSwitch,当然也可以选择其他交互器样式或者创建自己的交互器样式,如本例中使用的 vtkInteractorStyleTrackballCamera。

  vtkRenderWindowInteractor::SetRenderWindow():该方法用于设置渲染窗口,消息是通过渲染窗口捕获到的,所以必须给交互器对象设置渲染窗口。

  vtkRenderWindowInteractor::SetInteractorStyle():该方法用于定义交互器样式,默认的交互器样式为 vtkInteractorStyleSwitch。

  vtkRenderWindowInteractor::Initialize():该方法表示为处理窗口事件做准备,交互器工作之前必须先调用这个方法进行初始化。

  vtkRenderWindowInteractor::Start。该方法表示开始进入事件响应循环,交互器处于等待状态,等待用户交互事件的发生。进入事件响应循环之前必须先调用Initialize方法。

3.7、 vtkInteractorStyleTrackballCamera

  vtkInteractorStyleTrackballCamera是交互器样式的一种。该样式下,用户通过控制相机对物体作旋转、放大、缩小等操作。打个比方,在照相时如果要想物体拍起来显得大一些,可以采取两种做法:
  第一种做法是相机不动,让要拍的物体靠近相机;第二种做法是物体不动,让相机靠近物体。第二种做法就是vtkInteractorStyleTrackballCamera 的风格,其父类为 vtkInteractorStyle。

  除了vtkInteractorStyleTrackballCamera 之外,VTK还定义了其他多种交互器样式,如vtkInteractorStyleImage,主要用于显示二维图像时的交互。

4、总结

  下面通过一个类比,从宏观角度重新审视该示例,它对理解示例的代码将会有所帮助。

  可以将以上示例看作一个舞台剧演出。观看舞台剧时,观众坐在台下,展现在观众面前的是一个舞台,舞台上有各式的灯光和各样的演员。演员出场时肯定是会先化妆,观众有时还会与台上的演员有一定的互动。

  整个剧院就好比VTK程序的渲染窗口(vtkRenderWindow);舞台就相当于渲染场景(vtkRenderer);而那些演员就是程序中的Actor,台上演员与台下观众的互动可以看作与应用程序的交互(vtkRenderWindowInteractor);

  演员与观众的互动方式有很多种,现场的观众可以直接上台跟演员们握手拥抱,电视机前的可以发短信,计算机前的可以微博关注等,这就好比程序中的交互器样式(vtkInteractorStyle)。

  对于舞台上的演员,观众都可以一一分辨出来,不会弄混,是因为他们穿着打扮、容貌都不一样,这就相当于程序中vtkActor的不同属性(vtkProperty)。

  台下观众的眼睛可以看作vtkCamera,前排的观众因为离得近,在观看台上演员时会觉得他们比较高大,而后排的观众因为离得远,所以那些演员看起来就会显得小些,每位观众看到的东西在他/她的世界里都是唯一的,所以渲染场景Renderer里的vtkCamera对象也是只有一个。

  舞台上的灯光可以有多个,所以渲染场景里的vtkLight也存在多个。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/485313.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

React基础知识四 Hooks

什么是hooks&#xff1f; (coderwhy) hooks是react 16.8&#xff08;2019年&#xff09;出的新特性。 react有两种形式来创建组件——类式和函数式。在hooks之前类式组件就是react最主流的编程方式。 这个时候&#xff0c;函数式组件是非常鸡肋的&#xff0c;几乎没什么用。因…

TYUT计算机操作系统简答题

简述分组交换的优点。 高效灵活、迅速可靠&#xff0c;且各分组小&#xff0c;路由灵活&#xff0c;网络生存性能好。 解决 IPv4 地址紧缺有哪些方案&#xff1f; ① 使用代理服务器&#xff1b;② 使用地址转换&#xff1b;③ 升级到 IPv6。 网络适配器的作用是什么&#…

tomcat+jdbc报错怎么办?

1. 虽然mysql8.0以上的不用手动添加driver类&#xff0c;但是一旦加上driver类&#xff0c;就要手动添加了 不然会报找不到driver类的错误 2. java.lang.RuntimeException: java.sql.SQLException: No suitable driver found for jdbc:mysql://localhost:xXX?serverTimezoneU…

Qt6.8 QGraphicsView鼠标坐标点偏差

ui文件拖放QGraphicsView&#xff0c;src文件定义QGraphicsScene赋值给图形视图。 this->scene new QGraphicsScene();ui.graph->setScene(this->scene);对graphicview过滤事件&#xff0c;只能在其viewport之后安装&#xff0c;否则不响应。 ui.graph->viewport…

减少30%人工处理时间,AI OCR与表格识别助力医疗化验单快速处理

在医疗行业&#xff0c;化验单作为重要的诊断依据和数据来源&#xff0c;涉及大量的文字和表格信息&#xff0c;传统的手工输入和数据处理方式不仅繁琐&#xff0c;而且容易出错&#xff0c;给医院的运营效率和数据准确性带来较大挑战。随着人工智能技术的快速发展&#xff0c;…

工厂流水线上位机开发--USB转串口收不到数据,485通信时好时坏 不稳定问题

做过众多项目中&#xff0c;出现过很多次USB转485的返回值异常问题&#xff0c;自动化跑的好好的&#xff0c;一段时间后突然就查询不到返回值。 第一次出现时&#xff0c;上位机软件说是下位机问题&#xff0c;下位机说监控到返回数据了&#xff0c;是上位机问题&#xff0c;吵…

Mac曲线救国实现Bandizip右键一级菜单

一、前言 个人认为&#xff1a;Bandizip是Mac上最好用的压缩软件&#xff0c;没有之一。 在Mac系统上&#xff0c;学习版的Bandizip由于签名检验问题无法在访达右键的一级菜单显示 解压相关菜单。 有能力的&#xff0c;希望还是支持正版&#xff0c;找找优惠渠道应该100左右。…

矢量数据库

随着人工智能技术的深入发展&#xff0c;从图像识别到自然语言处理&#xff0c;从智能推荐到自动驾驶&#xff0c;AI的应用场景日益广泛。 而在这背后&#xff0c; 这种变革技术的核心数据概念是矢量。通过矢量化和大型语言模型(LLM) 的强大功能&#xff0c;生成式 AI 实现了其…

大模型学习有什么发展前景?

前景人工智能大模型是指拥有超大规模参数&#xff08;通常在十亿个以上&#xff09;、复杂计算结构的机器学习模型。它通常能够处理海量数据&#xff0c;完成各种复杂任务&#xff0c;如自然语言处理、图像识别等。 2024年政府工作报告提出“发展新质生产力”&#xff0c;并将…

2025澄迈漓岛音乐节品牌招商大会成功举行

——共谋音乐盛事&#xff0c;携手推动文化经济发展 12月6日&#xff0c;“2025澄迈漓岛音乐节品牌招商大会”&#xff08;以下简称“招商大会”&#xff09;在澄迈举行。本次大会由澄迈福山发展有限公司、福山咖啡文化风情镇旅游区联合主办&#xff0c;海南绿发投资有限公司承…

鲲鹏麒麟部署MongoDB4

本次部署采用Docker方式进行部署&#xff0c;服务器为鲲鹏服务器&#xff0c;CPU架构为ARM64&#xff0c;操作系统版本信息为 # cat /etc/kylin-release Kylin Linux Advanced Server release V10 (Tercel)找镜像 首先在https://hub.docker.com/网站上找到相关的额镜像&…

数据结构 (29)基于树的查找法

前言 数据结构中的基于树的查找法是一种高效的查找方法&#xff0c;它利用树形结构组织数据&#xff0c;使得查找过程能够迅速定位到目标元素。 一、树的基本概念 树是一种非线性结构&#xff0c;主要用来描述客观的层次结构关系。在树结构中&#xff0c;一个元素&#xff08;称…

前端框架的选择与反思:在简约与复杂之间寻找平衡

在当今互联网时代&#xff0c;前端开发已经成为web应用构建中不可或缺的一环。从最初的静态HTML页面&#xff0c;到如今复杂的单页应用&#xff08;SPA&#xff09;&#xff0c;前端技术的发展让我们见证了Web应用的蓬勃发展。然而&#xff0c;伴随着技术的进步&#xff0c;一个…

前端速通Blob、File、FileReader、ArrayBuffer、Base64...

提示:记录工作中遇到的需求及解决办法 文章目录 前言Blob基本使用使用场景File基本使用支持 Blob 和 File 对象的 APIFileReaderFileReader 实例属性FileReader 实例方法事件Base64术语解释Base64 编码原理示例Base64 的应用场景总结URL.createObjectURL()基本使用使用场景示例…

深入理解网络安全等级保护:保障信息安全的关键策略与实践

随着信息技术的飞速发展&#xff0c;网络安全问题日益凸显。为了应对这一挑战&#xff0c;网络安全等级保护制度应运而生&#xff0c;旨在确保不同等级的信息和信息系统的安全。本文将探讨网络安全等级保护的基本概念、重要性及其实践方法。 一、信息安全等级保护的基本概念 1…

Angular由一个bug说起之十一:排序之后无法展开 Row

问题现象 在使用 Material Table 时&#xff0c;排序功能触发了一个奇怪的 Bug&#xff1a;表格的 Row 无法展开。最终排查发现&#xff0c;问题的根源在于 trackBy 的错误使用。trackBy 方法接受两个参数&#xff1a;index&#xff08;数据索引&#xff09;和 row&#xff08;…

MySQL语句学习第三篇_数据库

MySQL语句学习第三篇_数据库 专栏记录MySQL的学习&#xff0c;感谢大家观看。 本章的专栏&#x1f4da;➡️MySQL语法学习 本博客前一章节指向➡️MySQL语句学习第二篇 本人的博客➡️:如烟花般绚烂却又稍纵即逝的主页 文章目录 MySQL的基础操作&#xff08;改与查&#xff0…

代码随想录Day35 本周小结动态规划,动态规划:01背包理论基础,动态规划:01背包理论基础(滚动数组),416. 分割等和子集。

1.本周小结动态规划 周一 动态规划&#xff1a;不同路径 (opens new window)中求从出发点到终点有几种路径&#xff0c;只能向下或者向右移动一步。 我们提供了三种方法&#xff0c;但重点讲解的还是动规&#xff0c;也是需要重点掌握的。 dp[i][j]定义 &#xff1a;表示从…

ceph存储池

1、存储池 1、存储池的概念 存储池就是ceph的逻辑分区&#xff0c;专门用来存储对象的 特点 将文件切片成对象&#xff0c;通过hash算法&#xff0c;找到存储池中的pg&#xff0c;池中的pg根据crush算法找到osd节点 存储中的PG数量对性能有重要的影响&#xff0c;过多和过少…

知从科技闪耀汽车智能底盘大会:共探软件安全新篇章

在汽车科技蓬勃发展的浪潮中&#xff0c;智能底盘技术正成为引领行业变革的关键力量。11月27日-28日&#xff0c;盖世汽车 2024 第四届汽车智能底盘大会盛大召开&#xff0c;上海知从科技有限公司受邀出席此次盛会&#xff0c;与众多汽车领域的精英齐聚一堂&#xff0c;共话智能…