VTK源码分析:Type System

作为一款开源跨平台的数据可视化代码库,VTK以其清晰的流水线工作方式、丰富的后处理算法、异种渲染/交互方式,而被众多CAx软件选作后处理实施方案。而异种渲染/交互方式的实现,主要是倚重于VTK的类型系统,因此,有必要对这个问题予以研究分析。

另外,结合前面对FreeCAD类型系统的分析,本文旨在导出类型系统在设计与实现等方面的(非)技术约束

本文涉及的主要知识点包括,

  • Factory Method Pattern
  • Type Registration

注1:限于研究水平,分析难免不当,欢迎批评指正。

注2:文章内容会不定期更新。

一、相关组件

1.1 vtkObjectBase

vtkObjectBase定义了类型信息、引用计数等相关接口,而类型信息主要是基于其内部维护的类型名称字符串。

1.2 vtkObject

vtkObject派生于vtkObjectBase,增加了对象动态创建接口。

// Macro to use when you are a direct child class of vtkObjectBase, instead
// of vtkTypeMacro. This is required to properly specify NewInstanceInternal
// as a virtual method.
// It is used to determine whether a class is the same class or a subclass
// of the named class.#define vtkBaseTypeMacro(thisClass, superclass)                                                    \vtkAbstractTypeMacro(thisClass, superclass);                                                     \\
protected:                                                                                         \virtual vtkObjectBase* NewInstanceInternal() const { return thisClass::New(); }                  \\
public:
// Same as vtkTypeMacro, but adapted for cases where thisClass is abstract.
#define vtkAbstractTypeMacro(thisClass, superclass)                                                \vtkAbstractTypeMacroWithNewInstanceType(thisClass, superclass, thisClass, #thisClass);           \\
public:
// Allows definition of vtkObject API such that NewInstance may return a
// superclass of thisClass.
#define vtkAbstractTypeMacroWithNewInstanceType(                                                   \thisClass, superclass, instanceType, thisClassName)                                              \
protected:                                                                                         \const char* GetClassNameInternal() const override { return thisClassName; }                      \\
public:                                                                                            \typedef superclass Superclass;                                                                   \static vtkTypeBool IsTypeOf(const char* type)                                                    \{                                                                                                \if (!strcmp(thisClassName, type))                                                              \{                                                                                              \return 1;                                                                                    \}                                                                                              \return superclass::IsTypeOf(type);                                                             \}                                                                                                \vtkTypeBool IsA(const char* type) override { return this->thisClass::IsTypeOf(type); }           \static thisClass* SafeDownCast(vtkObjectBase* o)                                                 \{                                                                                                \if (o && o->IsA(thisClassName))                                                                \{                                                                                              \return static_cast<thisClass*>(o);                                                           \}                                                                                              \return nullptr;                                                                                \}                                                                                                \VTK_NEWINSTANCE instanceType* NewInstance() const                                                \{                                                                                                \return instanceType::SafeDownCast(this->NewInstanceInternal());                                \}                                                                                                \static vtkIdType GetNumberOfGenerationsFromBaseType(const char* type)                            \{                                                                                                \if (!strcmp(thisClassName, type))                                                              \{                                                                                              \return 0;                                                                                    \}                                                                                              \return 1 + superclass::GetNumberOfGenerationsFromBaseType(type);                               \}                                                                                                \vtkIdType GetNumberOfGenerationsFromBase(const char* type) override                              \{                                                                                                \return this->thisClass::GetNumberOfGenerationsFromBaseType(type);                              \}

1.2 vtkObjectFactory

vtkObjectFactory定义了对象实例化的接口,同时将所有的对象工厂存储到静态成员变量RegisteredFactories。

二、关键流程

2.1 类型注册

在VTK中,CMake/vtkObjectFactory.cmake 定义了 vtk_object_factory_configure用于自动生成对应的vtkObjectFactory,

// CMake/vtkObjectFactory.cxx.in@_vtk_object_factory_configure_EXPORT_MACRO@ void @_vtk_object_factory_library_name@_AutoInit_Construct()
{if(++@_vtk_object_factory_library_name@Count == 1){
@_vtk_object_factory_configure_INITIAL_CODE@@_vtk_object_factory_library_name@ObjectFactory* factory = @_vtk_object_factory_library_name@ObjectFactory::New();if (factory){// vtkObjectFactory keeps a reference to the "factory",vtkObjectFactory::RegisterFactory(factory);factory->Delete();}}
}

然后,借助于VTK_MODULE_INIT宏完成vtkObjectFactory的注册。

// Common/Core/vtkAutoInit.h// Description:
// Initialize the named module, ensuring its object factory is correctly
// registered. This call must be made in global scope in the
// translation unit of your executable (which can include a shared library, but
// will not work as expected in a static library).
//
// @code{.cpp}
// #include "vtkAutoInit.h"
// VTK_MODULE_INIT(vtkRenderingOpenGL2);
// @endcode
//
// The above snippet if included in the global scope will ensure the object
// factories for vtkRenderingOpenGL2 are correctly registered and unregistered.
#define VTK_MODULE_INIT(M)                                                                         \VTK_AUTOINIT_DECLARE(M) namespace                                                                \{                                                                                                \static struct M##_ModuleInit                                                                   \{                                                                                              \/* Call <mod>_AutoInit_Construct during initialization.  */                                  \M##_ModuleInit() { VTK_AUTOINIT_CONSTRUCT(M) }                                               \} M##_ModuleInit_Instance;                                                                     \}

2.2 对象创建

vtkObject* vtkObjectFactory::CreateInstance(const char* vtkclassname, bool)
{if (!vtkObjectFactory::RegisteredFactories){vtkObjectFactory::Init();}vtkObjectFactory* factory;vtkCollectionSimpleIterator osit;for (vtkObjectFactory::RegisteredFactories->InitTraversal(osit);(factory = vtkObjectFactory::RegisteredFactories->GetNextObjectFactory(osit));){vtkObject* newobject = factory->CreateObject(vtkclassname);if (newobject){return newobject;}}return nullptr;
}

三、总结

由上述对VTK类型系统的分析,同时结合<FreeCAD源码分析:Type System>一文,可以总结出类型系统实现的要点,

  • 定义对象基类
  • 定义构造器及其接口
  • 将构造器(手动/自动)注册到类型注册表
  • 根据类型名字获取构造器,然后实例化对象
VTKFreeCAD
基类vtkObjectBaseBase::BaseClass
构造器vtkObjectFactoryBase::Type
类型注册表vtkObjectFactory::RegisteredFactoriesBase::Type::typedata

参考文献

  • Erich Gamma. Design Patterns:elements of reusable object-oriented software. Addison Wesley, 1994.

网络资料

VTKicon-default.png?t=N7T8https://vtk.org/

大型CAx(CAD/CAE/CAM)软件研发中的职责编排icon-default.png?t=N7T8https://blog.csdn.net/qq_26221775/article/details/136975550?spm=1001.2014.3001.5502

FreeCAD源码分析:Type Systemicon-default.png?t=N7T8https://blog.csdn.net/qq_26221775/article/details/140468677?spm=1001.2014.3001.5502

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

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

相关文章

最新 Docker 下载镜像超时解决方案:Docker proxy

现在Docker换源也下载失败太常见了&#xff0c;至于原因&#xff0c;大家懂得都懂。本文提供一种简洁的方案&#xff0c; 利用 Docker 的http-proxy&#xff0c;代理至本机的 proxy。 文章目录 前言Docker proxy 前言 这里默认你会安装 clash&#xff0c;然后有配置和数据库。…

排序算法

排序算法 内部排序&#xff1a;指将需要处理的所有数据都加载到内部存储器中进行排序 外部排序&#xff1a;数据量过大&#xff0c;无法全部加载到内存中&#xff0c;需要借助外部存储进行排序 算法的时间复杂度 一个算法花费的时间与算法中语句的执行次数成正比&#xff0c;…

Unity XR Interaction Toolkit(VR、AR交互工具包)记录安装到开发的流程,以及遇到的常见问题(一)!

提示&#xff1a;文章有错误的地方&#xff0c;还望诸位大神不吝指教&#xff01; 文章目录 前言一、XR Interaction Toolkit是什么&#xff1f;二、跨平台交互三、 AR 功能四、XR Interaction Toolkit的特点五、XR Interaction Toolkit 示例总结 前言 随着VR行业的发展&#…

7.21 复习数据结构相关知识【主链表】

顺序表 链表 栈 队列之间的关系 顺序表&#xff1a;array list---->基于数组实现的线性表&#xff0c;元素在内存中是连续存储的。链表&#xff1a;linked list ---->通过指针将一系列节点连接起来的线性表 单链表&#xff1a;next指针双链表&#xff1a;priornext指针 …

JS中的File(五):node.js中的file模块使用

详情阅读官方文档&#xff1a; File system | Node.js v22.5.1 Documentation Node.js fs.write() Method - GeeksforGeeks 这里暂时仅提供一些简单的梳理和阅读小tips&#xff08;偷懒一下 0.基本认知 对文件系统的操作可以主要分为几个主要部分&#xff1a;打开文件、新建文…

一文搞懂 Java 基础:新手入门必备

目录 &#x1f4dd; Java基础Java起源第一个Java程序基础语法Java标识符Java变量Java注释Java数据类型Java运算符Java流程控制语句 &#x1f4dd; Java基础 Java起源 Java programming language具有大部分编程语言所共有的一些特征&#xff0c;被特意设计用于互联网的分布式环…

《算法笔记》总结No.10——链表

从第10期破例插叙一期单链表的实现&#xff0c;这个东东相当重要&#xff01;考研的同学也可以看&#xff1a;相较于王道考研的伪码不太相同&#xff0c;专注于可以运行。如果是笔试中的伪码&#xff0c;意思正确即可~ 注&#xff1a;博主之前写过一个版本的顺序表和单链表的C实…

Jolt路线图

1. 引言 a16z crypto团队2024年7月更新了其Jolt路线图&#xff1a; 主要分为3大维度&#xff1a; 1&#xff09;链上验证维度&#xff1a; 1.1&#xff09;Zeromorph&#xff1a;见Aztec Labs团队2023年论文 Zeromorph: Zero-Knowledge Multilinear-Evaluation Proofs from…

视觉巡线小车——STM32+OpenMV

系列文章目录 第一章&#xff1a;视觉巡线小车——STM32OpenMV&#xff08;一&#xff09; 第二章&#xff1a;视觉巡线小车——STM32OpenMV&#xff08;二&#xff09; 第三章&#xff1a;视觉巡线小车——STM32OpenMV&#xff08;三&#xff09; 第四章&#xff1a;视觉巡…

【过题记录】 7.21

Mad MAD Sum 算法&#xff1a;思维&#xff0c;前缀最大值 模拟一下他的运行过程就会发现&#xff0c;两次之后整个数组就固定了&#xff0c;之后每次都是每个数往后移动一位&#xff0c;可以模拟两次之后计算每个数的存活轮数&#xff0c;计算贡献。 #include<bits/stdc.h…

JavaSE 知识梳理(下)

1.继承 继承是面向对象程序设计使代码可以复用的最重要的手段&#xff0c;它允许程序员在保持原有类特 性 的基础上进行扩展&#xff0c;增加新功能&#xff0c;这样产生新的类&#xff0c;称派生类。 继承主要解决的问题是&#xff1a;共性的抽取&#xff0c;实现代码复用&a…

【D3.js in Action 3 精译_018】2.4 向选择集添加元素

当前内容所在位置 第一部分 D3.js 基础知识 第一章 D3.js 简介&#xff08;已完结&#xff09; 1.1 何为 D3.js&#xff1f;1.2 D3 生态系统——入门须知1.3 数据可视化最佳实践&#xff08;上&#xff09;1.3 数据可视化最佳实践&#xff08;下&#xff09;1.4 本章小结 第二章…

【PyTorch】图像二分类项目-部署

【PyTorch】图像二分类项目 【PyTorch】图像二分类项目-部署 在独立于训练脚本的新脚本中部署用于推理的模型&#xff0c;需要构造一个模型类的对象&#xff0c;并将权重加载到模型中。操作流程为&#xff1a;定义模型--加载权重--在验证和测试数据集上部署模型。 import torch…

基于PSO算法优化PID参数的一些问题

目录 前言 Q1&#xff1a;惯性权重ω如何设置比较好&#xff1f;学习因子C1和C2如何设置&#xff1f; Q2&#xff1a;迭代速度边界设定一定能够遍历&#xff08;/覆盖&#xff09;整个PID参数二维空间范围吗&#xff1f;还是说需要与迭代次数相关&#xff1f;迭代次数越高&a…

MATLAB图像处理分析基础(一)

一、引言 MATLAB软件得到许多数字图像处理学生、老师和科研工作者的喜爱&#xff0c;成为数字图像处理领域不可或缺的工具之一&#xff0c;其与其他软件相比有以下诸多显著优点。首先&#xff0c;MATLAB 拥有强大的内置函数库&#xff0c;涵盖了图像读取、显示、处理及分析的全…

【学习笔记】无人机系统(UAS)的连接、识别和跟踪(九)-无人机区域地面探测与避让(DAA)

引言 3GPP TS 23.256 技术规范&#xff0c;主要定义了3GPP系统对无人机&#xff08;UAV&#xff09;的连接性、身份识别、跟踪及A2X&#xff08;Aircraft-to-Everything&#xff09;服务的支持。 3GPP TS 23.256 技术规范&#xff1a; 【免费】3GPPTS23.256技术报告-无人机系…

星火模型大体验简单实现一个LLM Chat平台

星火文档 利用axios封装 星火模型 API 请求 为了管理好的key,需要把对应的环境放置env.json文件中。 源码 const axios = require(axios); const ENV = require(../env.json); /*** * @param {*} messages 数组* @returns */ function request(messages) {return new Pro…

Unity UI 开发:代码与示例全解析

在 Unity 游戏开发中&#xff0c;用户界面&#xff08;UI&#xff09;的设计和实现是至关重要的一部分。一个直观、美观且功能完善的 UI 能够极大地提升玩家的游戏体验。本文将为您介绍一些 Unity UI 相关的代码和示例&#xff0c;帮助您更好地掌握 UI 开发。 一、创建基本 UI…

《昇思 25 天学习打卡营第 14 天 | 基于MindSpore的红酒分类实验 》

《昇思 25 天学习打卡营第 14 天 | 基于MindSpore的红酒分类实验 》 活动地址&#xff1a;https://xihe.mindspore.cn/events/mindspore-training-camp 签名&#xff1a;Sam9029 使用MindSpore实现K近邻&#xff08;KNN&#xff09;红酒聚类 实验目的和KNN算法概述 本次实验的…

gfsk调制相对于FSK调制优点

GFSK调制相对于FSK调制主要有以下优点&#xff1a; 抗噪声性能&#xff1a;GFSK调制采用高斯滤波器&#xff0c;这使得其抗噪声性能较好。在同样的信噪比下&#xff0c;GFSK调制能够实现更高的误码率性能。 频带利用率&#xff1a;GFSK调制的频带利用率相对较高。由于其带外衰…