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.rhkb.cn/news/382826.html

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

相关文章

从安装Node到TypeScript到VsCode的配置教程

从安装Node到TypeScript到VsCode的配置教程 1.下载Node安装包&#xff0c; 链接 2.双击安装包&#xff0c;选择安装路径&#xff0c;如下&#xff1a; 3.一直点击下一步&#xff0c;直至安装结束即可&#xff1a; 这个时候&#xff0c;node会默认配置好环境变量&#xff0c;并且…

抖音客户端一面

C | 字节抖音客户端一面 Http握手过程 1. 客户端问候(Client Hello) 客户端向服务器发送一个“问候”消息&#xff0c;其中包含客户端支持的SSL/TLS版本、加密算法、压缩方法以及一个随机数。 version 版本号,https也有版本号哦TLS 1.0、TLS 1.1、TLS 1.2等等 random 随机数…

(11)Python引领金融前沿:投资组合优化实战案例

1. 前言 本篇文章为 Python 对金融的投资组合优化的示例。投资组合优化是从一组可用的投资组合中选择最佳投资组合的过程&#xff0c;目的是最大限度地提高回报和降低风险。 投资组合优化是从一组可用的投资组合中选择最佳投资组合的过程&#xff0c;目的是最大限度地提高回报…

JUnit 单元测试

JUnit 测试是程序员测试&#xff0c;就是白盒测试&#xff0c;可以让程序员知道被测试的软件如何 &#xff08;How&#xff09;完成功能和完成什么样&#xff08;What&#xff09;的功能。 下载junit-4.12和hamcrest-core-1.3依赖包 相关链接 junit-4.12&#xff1a;Central …

【Qt】窗口

文章目录 QMainWindow菜单栏工具栏状态栏浮动窗口对话框自定义对话框Qt内置对话框QMessageBox QMainWindow Qt中的主窗口以QMainWindow表示&#xff0c;其总体结构如下&#xff1a; 菜单栏 菜单栏MenuBar&#xff0c;可包含多个菜单Menu&#xff0c;每个菜单也可以包含多个菜…

Godot游戏制作 03世界构建1.0版

在game场景&#xff0c;删除StaticBody2D节点&#xff0c;添加TileMap节点 添加TileSet图块集 添加TileSet源 拖动图片到图块&#xff0c;自动创建图块 使用橡皮擦擦除。取消橡皮擦后按住Shift创建大型图块。 进入选择模式&#xff0c;TileMap选择绘制&#xff0c;选中图块后在…

Java——————接口(interface) <详解>

1.1 接口的概念 在现实生活中&#xff0c;接口的例子比比皆是&#xff0c;比如&#xff1a;笔记本电脑上的USB接口&#xff0c;电源插座等。 电脑的USB口上&#xff0c;可以插&#xff1a;U盘、鼠标、键盘...所有符合USB协议的设备 电源插座插孔上&#xff0c;可以插&#xff…

若依Vue前后端分离版如何部署(windows)(超详细)

一、项目环境准备 下面是项目所需要准备的环境 Node.js redis 1、Node.js下载 下面进入官网可以下载Node.js — 在任何地方运行 JavaScript (nodejs.org)https://nodejs.org/zh-cn 下载完成安装后&#xff0c;需要配置环境变量&#xff0c;首先复制以下nodejs的安…

springboot系列十一:Thymeleaf

文章目录 官方文档基本介绍Thymeleaf机制说明Thymeleaf语法表达式运算符th属性迭代条件运算使用Thymeleaf th属性需要注意点 Thymeleaf综合案例需求说明思路分析代码实现 作业布置 官方文档 在线文档: https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html 离线…

css黑色二级下拉导航菜单

黑色二级下拉导航菜单https://www.bootstrapmb.com/item/14816 body { font-family: Arial, sans-serif; margin: 0; padding: 0; }nav { background-color: #000; /* 导航背景色为黑色 */ }.menu { list-style-type: none; margin: 0; padding: 0; overflow: hidden; }.menu l…

ARP欺骗——华为ensp

首先&#xff0c;搭建好网络拓扑。网络设备包含客户端Client1和服务端Server1&#xff0c;交换机 以及 云。 图中的 Client和Server 配置IP地址&#xff0c;要和 vm8 在相同的网段。故设置客户端ip为192.168.11.10 &#xff0c;服务端ip为&#xff1a;192.168.11.20&#xff0…

uni-app AppStore Connect上传拒绝汇总

1.Guideline 2.3.3 - Performance - Accurate Metadata 问题是图片不对&#xff0c;最好是自己截图&#xff0c;然后用香蕉云编 上传图片合成图片 2.Guideline 5.1.2 - Legal - Privacy - Data Use and Sharing 解决办法&#xff1a;在uniapp manifest.json找到 APP常用其他…

【Ubuntu】Ubuntu系统镜像

清华镜像源 Index of /ubuntu-releases/ | 清华大学开源软件镜像站 | Tsinghua Open Source MirrorIndex of /ubuntu-releases/ | 清华大学开源软件镜像站&#xff0c;致力于为国内和校内用户提供高质量的开源软件镜像、Linux 镜像源服务&#xff0c;帮助用户更方便地获取开源软…

Llama 3.1要来啦?!测试性能战胜GPT-4o

哎呀&#xff0c;Meta声称将于今晚发布的Llama 3.1&#xff0c;数小时前就在Hugging Face上泄露出来了&#xff1f;泄露的人很有可能是Meta员工&#xff1f; 还是先来看泄露出来的llama3.1吧。新的Llama 3.1模型包括8B、70B、405B三个版本。 而经过网友测试&#xff0c;该base…

Langchain核心模块与实战[8]:RAG检索增强生成[loader机制、文本切割方法、长文本信息处理技巧]

Langchain核心模块与实战[8]:RAG(Retrieval Augmented Generation,检索增强生成) RAG(Retrieval-Augmented Generation)技术是一种结合检索和生成功能的自然语言处理(NLP)技术。该技术通过从大型外部数据库中检索与输入问题相关的信息,来辅助生成模型回答问题。其核心…

gitee的怎么上传项目

前提 1.先下载Git Bash (如果没有下载的宝子们下载连接如下: 链接: link ) 项目上传到Gitee步骤 1.在Gitee上建立远程仓库 2.填写相关信息 3.进入本地你想要上传的文件目录下&#xff0c;右键单击空白处&#xff0c;点击Git Bash Here 4.配置你的用户名和邮箱 git con…

使用Ollama和OpenWebUI,轻松探索Meta Llama3–8B

大家好&#xff0c;2024年4月&#xff0c;Meta公司开源了Llama 3 AI模型&#xff0c;迅速在AI社区引起轰动。紧接着&#xff0c;Ollama工具宣布支持Llama 3&#xff0c;为本地部署大型模型提供了极大的便利。 本文将介绍如何利用Ollama工具&#xff0c;实现Llama 3–8B模型的本…

Android APP CameraX应用(02)预览流程

说明&#xff1a;camera子系统 系列文章针对Android12.0系统&#xff0c;主要针对 camerax API框架进行解读。 1 CameraX简介 1.1 CameraX 预览流程简要解读 CameraX 是 Android 上的一个 Jetpack 支持库&#xff0c;它提供了一套统一的 API 来处理相机功能&#xff0c;无论 …

爬虫学习3:爬虫的深度爬取

爬虫的深度爬取和爬取视频的方式 深度爬取豆瓣读书 import time import fake_useragent import requests from lxml import etree head {"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 …

双向链表(C语言版)

1. 双向链表的结构 注意&#xff1a;这里的“带头”跟单链表的“头结点”是两个概念&#xff0c;实际上在单链表阶段称呼不太严谨&#xff0c;但是为了更好地理解就直接称为单链表的头结点。带头链表里的头结点&#xff0c;实际为“哨兵位”&#xff0c;哨兵位结点不存储任何有…