VTK 动画:框架、流程与实现

news2025/2/26 19:55:41

VTK 动画:框架、流程与实现

  • VTK 动画:框架、流程与实现
    • vtkAnimationCue 和 vtkAnimationScene 简介
    • vtkAnimationScene 类的重要方法
    • vtkAnimationCue 类的重要方法
    • VTK 动画的基本流程
    • 实例:一个简单的 VTK 动画演示程序

VTK是一个非常强大的图形处理库,它不仅可以用于科学计算和可视化,还可以用于创建各种有趣的动画。

VTK 动画:框架、流程与实现

参考:https://www.bilibili.com/video/BV1wM411K7wV

vtkAnimationCue 和 vtkAnimationScene 简介

VTK提供了一个由vtkAnimationCue和vtkAnimationScene等类所组成的框架,支持动画场景的创建和回放。

在这里插入图片描述

vtkAnimationScene表示一个场景或者是动画场景的建立。动画场景通常是通过渲染一系列的帧,在渲染每一帧时改变某些可视化参数来建立的。所渲染的每一帧都关联一个动画时间,这个时间用来确定动画中每一帧的位置。基于不同的播放模式,动画时间在动画播放过程中是一个计数不断添加的简单变量。

vtkAnimationCue代表一个随时间变化/动画的实体。vtkAnimationCue实例本身并不知道与动画相关的参数是假设改变的。因此,用户必须从vtkAnimationCue中派生出子类或者使用观察者模式监听事件。来改变动画过程中须要改变的参数。

动画场景中的Cue实体都有一个开始时间(start-time)和结束时间(end-time)。动画回放时,当场景的动画时间是处于所指定的开始时间与结束时间的范围内时,Cue实体就会被激活。Cue实体一旦激活后,它本身会发出vtkCommand::StartAnimationCueEvent事件。而对于动画系列中的每一帧。则发出vtkCommand::AnimationCueTickEvent事件,当动画时间递增至Cue实体的结束时间时,会发出vtkCommand::EndAnimationCueEvent事件。

vtkAnimationScene 类的重要方法

下面列出了类vtkAnimationScene中一些比较重要的方法:

  1. SetStartTime()/SetEndTime():设置动画场景的开始时间和结束时间,它们就是动画回放时的时间范围。
  2. SetPlayMode():用于控制动画回放的模式,也就是动画时间是怎样改变的。有两种模式能够设置:
    • SequenceMode(PLAYMODE_SEQUENCE):这样的模式下,每帧的动画时间添加(1/framerate)的间隔。直至达到所设置的EndTime。因此。所渲染的总帧数是固定的,与渲染每一帧时所用的时间的长短无关。
    • RealTimeMode(PLAYMODE_REALTIME):这样的模式下,整个动画的执行时间大约是(EndTime-StartTime)秒,当中第n帧的执行时间是:第n-1帧的执行时间+渲染第n-1帧所用的时间。因此。所渲染的总帧数随着渲染每一帧所用时间的不同而不同。
  3. SetFrameRate():帧率是指单位时间内渲染的帧数。主要用于Sequence模式。
  4. AddCue():将一个vtkAnimationCue实例加入到场景中。
  5. RemoveCue():从场景中移除vtkAnimationCue实例。
  6. RemoveAllCue():从场景中移除所有的vtkAnimationCue实例。
  7. SetAnimationTime():指定某一帧的动画时间。
  8. GetAnimationTime():动画回放时,获取动画的时钟时间。
  9. SetLoop():设为true,动画循环播放。
  10. Play()/Stop():开始/结束动画。

vtkAnimationCue 类的重要方法

下面是vtkAnimationCue类中一些比较重要的方法:

  1. SetTimeMode():TimeMode定义了Cue实体的起始时间和结束时间是怎样指定的,有两种模式可选。
    • Relative(TIMEMODE_RELATIVE):这样的模式下,动画场景中的Cue实体的时间是相对动画场景的开始时间来指定的。
    • Normalized(TIMEMODE_NORMALIZED):这样的模式下,Cue实体的开始时间和结束时间的取值范围为[0, 1],其中0对应动画场景的开始,1对应结束。
  2. SetStartTime()/SetEndTime():这两个方法主要是当Cue实体被激活时,标识动画时间的范围。
    • 当TimeMode取值为TIMEMODE_RELATIVE时,与动画场景的开始和结束时间有同样的单位。
    • 当TimeMode取值为TIMEMODE_NORMALIZED时,Cue实体的开始时间和结束时间的取值范围为[0, 1],其中0对应动画场景的开始,1对应结束。
  3. GetAnimationTime():用于vtkCommand::AnimationCueTickEvent事件的处理。处理事件时。可用来确定动画场景中的当前帧。其值依赖于TimeMode。
    • 当TimeMode取值为TIMEMODE_RELATIVE时,其值是Cue实体激活后的时间单位的倍数。
    • 当TimeMode取值为TIMEMODE_NORMALIZED时,Cue实体的开始时间和结束时间的取值范围为[0, 1],其中0对应动画场景的开始,1对应结束。
  4. GetClockTime():该方法与vtkAnimationScene::GetAnimationTime()中的动画时钟时间相似,仅当处理vtkCommand::AnimationCueTickEvent事件时才有效。
  5. TickInternal (double currenttime, double deltatime, double clocktime):正如前面所提的。我们能够派生一个vtkAnimationCue子类来取代编写处理动画事件的函数。子类派生时,必须要重载该函数。当中该函数的参数分别相应GetAnimationTime(),GetDeltaTime()和GetClockTime()的返回值。
  6. StartCueInternal()/EndCueInternal():这两个方法可在子类中重载,主要做一些创建、清除等工作以及动画回放时控制Cue实体的开始和结束。用户也能够加入事件观察者,通过监听vtkCommand::StartAnimationCueEvent和vtkCommand::EndAnimationCueEvent事件来实现相似的功能。

VTK 动画的基本流程

  1. 公有继承 vtkAnimationCue 实现一个自己的 vtkAnimationCue 子类,实现动画功能
  2. 创建一个 vtkAnimationScene 渲染场景
  3. 创建一个或多个 vtkAnimationCue 自定义子类实例,对于类中需要操作的对象进行赋值
  4. 添加动画实例到动画场景中:scene->AddCue(cue)
  5. 开始动画:scene->Play()
  6. 结束动画:scene->Stop()

实例:一个简单的 VTK 动画演示程序

VTK 对象都是通过内部定义静态函数 New() 来生成,用 Delete() 方法删除,因此构造函数、析构函数都要定义为 protected 类型,而对与赋值运算符和拷贝构造函数定义为 private 类型,只做声明不用实现。

两个宏:

vtkTypeMacro 是 VTK 的一个父子继承类型宏,用来追踪父子关系。借助该宏,不需要重新实现 vtkAnimationCue 的基本函数(虚函数)。

vtkStandardNewMacro 是 VTK 的一个宏,作用是定义一个通用的 New() 函数,使用时需要将实际的类名传递给它,确保你创建的对象是实际类的实例,而不是基类的实例。

完整程序:

#include <vtkSmartPointer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkSphereSource.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkProperty.h>

#include "vtkAutoInit.h"
VTK_MODULE_INIT(vtkRenderingOpenGL2);
VTK_MODULE_INIT(vtkInteractionStyle);

#include <vtkAnimationScene.h>
#include <vtkAnimationCue.h>

class vtkCustomAnimationCue : public vtkAnimationCue
{
protected:
	vtkCustomAnimationCue() : RenWin(nullptr), Sphere(nullptr) {}
	virtual void TickInternal(double currenttime, double deltatime, double clocktime)
	{
		double new_st = currenttime * 180;
		this->Sphere->SetStartTheta(new_st);
		this->RenWin->Render();
	}

public:
	static vtkCustomAnimationCue* New();
	vtkTypeMacro(vtkCustomAnimationCue, vtkAnimationCue);
	vtkRenderWindow* RenWin;
	vtkSphereSource* Sphere;
};
vtkStandardNewMacro(vtkCustomAnimationCue);

int main()
{
	// 新建一个 Source 数据源对象
	vtkSmartPointer<vtkSphereSource> sphere = nullptr;
	sphere = vtkSmartPointer<vtkSphereSource>::New();
	// 设置属性
	sphere->SetPhiResolution(30); // 设置纬度方向上的点数,默认值为 8
	sphere->SetThetaResolution(30); // 设置经度方向上的点数,默认值为 8
	// 新建一个 Mapper 映射器对象
	vtkSmartPointer<vtkPolyDataMapper> sphereMapper = nullptr;
	sphereMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
	// 接受 cylinder 的输出,将数据映射为几何元素
	sphereMapper->SetInputConnection(sphere->GetOutputPort());
	// 新建一个 Actor 演示对象
	vtkSmartPointer<vtkActor> sphereActor = nullptr;
	sphereActor = vtkSmartPointer<vtkActor>::New();
	// vtkActor 派生自 vtkProp 类,渲染场景中数据的可视化表达是通过 vtkProp 的子类负责的
	// vtkProp 子类负责确定渲染场景中对象的位置、大小和方向信息
	sphereActor->SetMapper(sphereMapper);
	sphereActor->GetProperty()->SetColor(0.0, 0.0, 1.0);
	// 创建一个 Renderer 渲染器对象,负责管理场景的渲染过程
	vtkSmartPointer<vtkRenderer> renderer = nullptr;
	renderer = vtkSmartPointer<vtkRenderer>::New();
	// 添加 vtkProp 类型的对象到渲染场景中
	renderer->AddActor(sphereActor);
	// 设置渲染场景的背景颜色
	renderer->SetBackground(1.0, 1.0, 1.0); // R、G、B,全 0 为黑色,全 1 为白色
	// 创建一个 Window 窗口对象,负责本地计算机系统中窗口创建和渲染过程管理
	vtkSmartPointer<vtkRenderWindow> window = nullptr;
	window = vtkSmartPointer<vtkRenderWindow>::New();
	window->AddRenderer(renderer);
	window->SetSize(640, 480); // 设置窗口大小
	window->Render();
	window->SetWindowName("Sphere");

	/*
	// 新建一个 Interactor 交互器对象,提供平台独立的响应鼠标、键盘和时钟事件的交互机制
	vtkSmartPointer<vtkRenderWindowInteractor> interactor = nullptr;
	interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
	// 设置渲染窗口,消息是通过渲染窗口捕获到的,所以必须要给交互器对象设置渲染窗口
	interactor->SetRenderWindow(window);
	// 新建一个交互器样式对象,该样式下,用户通过控制相机对物体作旋转、放大、缩小等操作
	vtkSmartPointer<vtkInteractorStyleTrackballCamera> style = nullptr;
	style = vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New();
	// 定义交互器样式,默认的交互样式为 vtkInteractorStyleSwitch
	interactor->SetInteractorStyle(style);

	interactor->Initialize();
	interactor->Start();
	*/

	vtkAnimationScene* scene = vtkAnimationScene::New(); // 创建动画场景
	//scene->SetModeToRealTime(); // 设置实时播放模式
	scene->SetModeToSequence(); // 设置顺序播放模式
	scene->SetFrameRate(30); // 设置帧率,单位时间内渲染的帧数
	scene->SetStartTime(0); // 动画开始时间
	scene->SetEndTime(60); // 动画结束时间

	vtkCustomAnimationCue* cue = vtkCustomAnimationCue::New(); // 创建动画实例
	// 对于类中需要操作的对象进行赋值
	cue->Sphere = sphere;
	cue->RenWin = window;
	cue->SetTimeModeToNormalized(); // 按照场景时间标准化实例的动画时间,0 对应动画场景的开始,1 对应结束
	cue->SetStartTime(.0);
	cue->SetEndTime(1.0);

	scene->AddCue(cue); // 添加动画实例到动画场景中
	//scene->SetLoop(1); // 设置循环播放模式
	scene->Play(); // 动画场景开始播放
	scene->Stop(); // 结束播放

	// 使用了智能指针,不需要手动释放内存
	//style->Delete();
	//interactor->Delete();
	//window->Delete();
	//renderer->Delete();
	//cylinderActor->Delete();
	//cylinderMapper->Delete();
	//cylinder->Delete();
	scene->Delete();
	cue->Delete();

	return EXIT_SUCCESS;
}

运行结果:

球的开口从0增大到180度,动画结束。

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

报表控件 Stimulsoft 常见问题:从代码启用缓存

Stimulsoft Ultimate &#xff08;原Stimulsoft Reports.Ultimate&#xff09;是用于创建报表和仪表板的通用工具集。该产品包括用于WinForms、ASP.NET、.NET Core、JavaScript、WPF、PHP、Java和其他环境的完整工具集。无需比较产品功能&#xff0c;Stimulsoft Ultimate包含了…

Day 20 654.最大二叉树 617.合并二叉树 700.二叉搜索树中的搜索 98.验证二叉搜索树

最大二叉树 给定一个不含重复元素的整数数组。一个以此数组构建的最大二叉树定义如下&#xff1a; 二叉树的根是数组中的最大元素。左子树是通过数组中最大值左边部分构造出的最大二叉树。右子树是通过数组中最大值右边部分构造出的最大二叉树。 通过给定的数组构建最大二叉…

django模板的继承

模板的继承 我们在访问一些访问的网站 这些网站页面整体都差不多 &#xff0c; 只是某一些局部在变化。 模板的继承&#xff0c; 就是自己先选好一个想要继承的模板页面 {% extends home.html %}​ 在继承之后子页面跟模板页面长的是一模一样的&#xff0c; 你需要在模板页面…

Burpsuite+MuMu模拟器12抓包

写在前面 高版本的安卓不能直接安装证书了&#xff0c;比较麻烦。步骤如下。 前置工作 安装adb https://blog.csdn.net/x2584179909/article/details/108319973 安装openssl https://blog.csdn.net/zyhse/article/details/108186278 下载证书 看一下自己的IP burp添加…

Linux Ubantu安装配置教程

Ubuntu是一个基于Linux的开源操作系统&#xff0c;它遵循GNU通用公共许可证&#xff0c;用户可以自由使用、复制、分发和修改。它提供直观易用的桌面环境&#xff0c;适合新手和有经验用户。Ubuntu有强大的软件中心&#xff0c;支持多硬件架构&#xff0c;注重安全和稳定&#…

AcWing 112. 雷达设备 解题思路及代码

先贴个题目&#xff1a; 以及原题链接&#xff1a; 112. 雷达设备 - AcWing题库https://www.acwing.com/problem/content/114/ 这题如果直接枚举点肯定是不行的&#xff0c;但可以把每个小岛的可能雷达设置点抽象成x轴上的线段进行贪心&#xff0c;我们的选点尽量选在线段的重合…

element vue 日期时间组件封装

一、背景 年、月、周、日的时间范围类型&#xff0c;选择对应的日期类型&#xff0c;会传参给后端一个dateType参数&#xff0c;用于后端判断&#xff0c;进行数据抽稀。 二、实现效果 三、代码 完整代码&#xff1a; //年月周日&#xff0c;组件封装 //vue3 setup <scrip…

element-ui中el-radio-group组件绑定点击事件触发多次的解决办法

1、需求 电商首页需求&#xff0c;需要做个单选框&#xff0c;然后点击选中切换图标方向及更换价格升倒序&#xff0c;如下图&#xff1a; 从官网文档看&#xff0c;单选框支持change event&#xff0c;使用click加载按钮处不会触发选中 但是使用 click.native 事件不做处理…

【XR806开发板试用】在 xr806 上移植 LVGL

本文参与极术社区的《基于安谋科技STAR-MC1的XR806开发板试用》活动。 不多废话&#xff0c;直接开搞&#xff0c;先上效果图 准备 开发环境啥的&#xff0c;已经有很多文章了&#xff0c;这里就不再提搭建开发环境的相关内容了。 一个屏幕(1.8’ 128x160) LVGL源码(v8.0.2…

ros 自定义package:在rviz中创建可显示markers的工具包(python)

在rviz中创建可显示markers的工具包 1. 创建using_makers工具包2. rviz部署和测试 1. 创建using_makers工具包 在catkin_ws工作空间下 cd ~/catkin_ws/srccatkin_create_pkg using_markers rospy visualization_msgsmkdir ~/catkin_ws/src/using_markers/scripts/添加basic_s…

D1084 5A低压差电压调整器应用方案,内含电流限制和热保护功能,防止任何过载时产生过高的结温

1、 概述&#xff1a; D1084是一款具有5A输出能力、低压差为1.5V的三端稳压器。输出电压可通过电位器调节或1.5V, 1.8V, 3.3V三个固定电压版。内含电流限制和热保护功能&#xff0c;防止任何过载时产生过高的结温。D1084系列电路有标准TO-220、TO-263和TO-252封装形式。 2、 典…

大话设计模式——21.中介者模式(Mediator Pattern)

简介 用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用&#xff0c;从而使其耦合松散&#xff0c;而且可以独立地改变它们之间的交互 UML图 应用场景 大量的连接使得一个对象不可能在没有其他对象的支持下工作&#xff0c;系统表现为一个不可分割的…

redis过期监听机制

转自&#xff1a;https://www.cnblogs.com/wangyunhong/articles/16505079.html 1.redis配置 1.打开conf/redis.conf 文件&#xff0c;取消注释&#xff1a;notify-keyspace-events Ex 2.重启redis 3.如果设置了密码需要重置密码&#xff1a;config set requirepass **** 3…

新鲜出炉!这一套二手平台管理系统,太牛了,直接领取【带源码】

​今天给大家分享一套基于SpringbootVue的二手平台管理系统源码&#xff0c;在实际项目中可以直接复用。(免费提供&#xff0c;文末自取) 一、系统运行图&#xff08;设计报告和接口文档&#xff09; 1、登陆页面 2、后台页面 3、设计报告包含接口文档 二、系统搭建视频教程 …

JVM常用参数一

jvm启动参数 JVM&#xff08;Java虚拟机&#xff09;的启动参数是在启动JVM时可以设置的一些命令行参数。这些参数用于指定JVM的运行环境、内存分配、垃圾回收器以及其他选项。以下是一些常见的JVM启动参数&#xff1a; -Xms&#xff1a;设置JVM的初始堆大小。 -Xmx&#xff1…

了解CSS中的BFC以及用法

目录 一 常见的定位方案 1. 普通流&#xff08;所有元素默认为普通流的定位&#xff09; 2. 浮动 3. 绝对定位 二 BFC 1. 定义 2. 触发条件 3. 作用 &#xff08;1&#xff09; 避免外边距重叠 ​&#xff08;2&#xff09;清除浮动 &#xff08;3&#xff09; 阻…

【知识扫盲】DHCP Server扫盲与作用

DHCP Server在实际应用中非常广泛&#xff0c;它适用于各种规模的网络环境&#xff0c;从小型办公室到大型企业网络&#xff0c;都能发挥重要作用。以下是一些具体的使用场景&#xff0c;用通俗易懂的语言进行解释。 1. 办公室网络环境 在一家公司的办公室里&#xff0c;通常会…

麒麟KOS删除鼠标右键新建菜单里不需要的选项

原文链接&#xff1a;麒麟KOS删除鼠标右键新建菜单里不需要的选项 Hello&#xff0c;大家好啊&#xff01;在日常使用麒麟KOS操作系统时&#xff0c;我们可能会发现鼠标右键新建菜单里包含了一些不常用或者不需要的选项。这不仅影响我们的使用效率&#xff0c;也让菜单显得杂乱…

基于MPC的自动驾驶泊车控制

基于MPC的自动驾驶泊车控制 H. Ye, H. Jiang, S. Ma, B. Tang, and L. Wahab, “Linear model predictive control of automatic parking path tracking with soft constraints,” International Journal of Advanced Robotic Systems, vol. 16, no. 3, p. 附赠自动驾驶学习资…

Qt之QSS样式表

QSS简介 QSS&#xff08;Qt Style Sheet&#xff09;样式表是一种用于描述图形用户界面&#xff08;GUI&#xff09;样式的语言。它允许开发者为应用程序的控件定义视觉外观&#xff0c;例如颜色、字体、尺寸和布局等。 QSS 样式表的主要目的是提供一种简洁而灵活的方式来美化…