VTK源码分析:Type System

news2024/11/27 16:51:39

作为一款开源跨平台的数据可视化代码库,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.coloradmin.cn/o/1938167.html

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

相关文章

visio保存一部分图/emf图片打开很模糊/emf插入到word或ppt中很模糊

本文主要解决三个问题 visio保存一部分图 需求描述&#xff1a;在一个visio文件中画了很多个图&#xff0c;但我只想把其中一部分保存成某种图片格式&#xff0c;比如jpg emf png之类的&#xff0c;以便做后续的处理。 方法&#xff1a;超级容易。 选中希望保存的这部分图&…

免费【2024】springboot 爱看漫画小程序的设计与实现

博主介绍&#xff1a;✌CSDN新星计划导师、Java领域优质创作者、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流✌ 技术范围&#xff1a;SpringBoot、Vue、SSM、HTML、Jsp、PHP、Nodejs、Python、爬虫、数据可视化…

分布式搜索之Elasticsearch入门

Elasticsearch 是什么 Elasticsearch 是一个分布式、RESTful 风格的搜索和数据分析引擎&#xff0c;能够解决不断涌现出的各种用例。作为 Elastic Stack 的核心&#xff0c;它集中存储您的数据&#xff0c;帮助您发现意料之中以及意料之外的情况。 Elastic Stack 又是什么呢&a…

使用docker swarm搭建ruoyi集群环境

整体目标 项目背景 领导给到了我一个客户&#xff0c;客户商业模式为成本制作&#xff0c;成本核算。其中涉及到大量涉密数据&#xff0c;且与我们现有产品几乎没有兼容点&#xff08;我们是一套低代码的框架&#xff0c;客户有很多业务二开&#xff09; 测试环境给到了我6台…

黑马微服务拆分2 (路由 登录 配置)

会利用微服务网关做请求路由 会利用微服务网关做登录身份校验 会利用Nacos实现统一配置管理 会利用Nacos实现配置热更新 今天粗略的完成了黑马笔记里边的代码实现 其实本身黑马商城的源码就写的逻辑有漏洞&#xff0c;加上对业务没有仔细分析 导致出现的bug调试了很久 这…

如何判断自己的数据格式适合使用json还是Excel的形式存入neo4j数据库

判断自己的数据格式适合使用JSON还是Excel的形式存入Neo4j数据库&#xff0c;主要取决于数据的复杂性、规模、结构、以及你或你的团队对这两种格式的熟悉程度。以下是一些关键因素&#xff0c;可以帮助你做出决策&#xff1a; 数据的复杂性&#xff1a; 如果你的数据包含大量的…

【Zynq UltraScale+ RFSoC】~~~

Zynq UltraScale RFSoC 系列为 5G 无线和射频级模拟应用引入了颠覆性的集成和架构突破&#xff0c;可直接支持整个 5G sub-6GHz 频段。这个创新系列现已开始批量生产。此设计演示展示了多通道&#xff08;8T8R 或 16T16R&#xff09;Zynq UltraScale RFSoC 评估工具工具工具&am…

ICMP 和 IGMP 的区别

ICMP 和 IGMP 协议 IP 层分支图 ICMP&#xff08;Internet Control Message Protocol&#xff0c;因特网控制信息协议&#xff09; 用于补充 IP 传输数据报的过程中&#xff0c;发送主机无法确定数据报是否到达目标主机。 ICMP 报文分为出错报告报文和查询报文两种。 若数据…

C语言 | Leetcode C语言题解之第263题丑数

题目&#xff1a; 题解&#xff1a; bool isUgly(int n) {if (n < 0) {return false;}int factors[] {2, 3, 5};for (int i 0; i < 3; i) {while (n % factors[i] 0) {n / factors[i];}}return n 1; }

python:本机摄像头目标检测实时推理(使用YOLOv8n模型)

本文将介绍如何使用本机摄像头进行目标检测实时推理的python代码。 文章目录 一、下载YOLO权重文件二、环境配置三、完整代码 一、下载YOLO权重文件 https://github.com/ultralytics/ultralytics?tabreadme-ov-file 拉到网页最下面&#xff0c;选择适合的模型&#xff0c;下…

Armv8/Armv9架构的学习大纲-学习方法-自学路线-付费学习路线

本文给大家列出了Arm架构的学习大纲、学习方法、自学路线、付费学习路线。有兴趣的可以关注&#xff0c;希望对您有帮助。 如果大家有需要的&#xff0c;欢迎关注我的CSDN课程&#xff1a;https://edu.csdn.net/lecturer/6964 ARM 64位架构介绍 ARM 64位架构介绍 ARM架构概况…

56、本地数据库迁移到阿里云

现有需求&#xff0c;本地数据库迁移到阿里云上。 库名xy102表 test01test02test01 test023条数据。1、登录阿里云界面创建免费试用ECS实列。 阿里云登录页 (aliyun.com)](https://account.aliyun.com/login/login.htm?oauth_callbackhttps%3A%2F%2Fusercenter2.aliyun.com%…

Spring -- 三层架构

T04BF &#x1f44b;专栏: 算法|JAVA|MySQL|C语言 &#x1faf5; 今天你敲代码了吗 应用分层 介绍 在阿里的开发手册里,关于工程结构部分,定义的常见工程的应用分层结构 那么什么是应用分层呢? 应用分层是一种软件开发设计思想,他将应用程序分层N个层次.这N个层次分别负责各…

JVM:JavaAgent技术

文章目录 一、Java工具的介绍二、Java Agent技术1、介绍2、静态加载模式3、动态加载模式 三、搭建java agent静态加载模式环境1、创建maven项目2、编写类和premain方法3、编写MANIFEST.MF文件4、使用maven-assembly-plugin进行打包5、创建Spring Boot应用 一、Java工具的介绍 …

Vscode离线下载对应版本的ms-python.vsix

一、查看vscode的版本号和发行时间 vscode界面中Help-About查看版本号和发行时间&#xff0c;ms-python的发行时间需要和这个时间相近&#xff1a; 二、在github仓库中查看ms-python有什么版本&#xff0c;以及发行时间 github仓库路径 https://github.com/microsoft/vsco…

算法学习笔记(Hello算法)—— 时间复杂度

1.1 统计时间增长趋势 时间复杂度分析统计的不是算法运行时间&#xff0c;而是算法运行时间随着数据量变大时的增长趋势。 // 算法 A 的时间复杂度&#xff1a;常数阶 void algorithm_A(int n) {System.out.println(0); }// 算法 B 的时间复杂度&#xff1a;线性阶 void algo…

计算机网络入门 -- TCP详解

计算机网络入门 – TCP详解 1.TCP协议 1.1 报文格式 1.32位序号&#xff1a;该条TCP数据携带的起始序号。 2.32位确认序号&#xff1a;期望对方发送数据从那个序号开始发送。 3.4位首部长度&#xff1a;最大为0xF(15)&#xff0c;指的是TCP头部长度。 首部长度 4 位首部长…

huawei USG6001v1学习---防火墙高可靠性(双机热备)

1.什么是双机热备 如图&#xff1a;当左图的防火墙发生故障时&#xff0c;整个系统都会收到影响&#xff0c;而右图即使有防火墙发生故障&#xff0c;但是还有一台防火墙做备份&#xff0c;相对于只有一台防火墙&#xff0c;要可靠些。 由于防火墙上不仅需要同步配置信息&…

Jenkins+Maven+Gitlab+Tomcat自动化构建打包+部署

目录 环境准备 导入项目包 配置jenkins 构建项目 配置项目上线 修改项目代码测试 环境准备 本实操项目环境基于https://blog.csdn.net/Lzcsfg/article/details/140359830 首先在node01主机中操作&#xff0c;本次操作需要java8的版本&#xff0c;将之前安装的java17卸…

大模型学习笔记 - LLM模型架构

LLM 模型架构 LLM 模型架构 1. LLM 核心模型 Transformer2. 详细配置 2.1 归一化方法2.2 归一化模块位置2.3 激活函数2.4 位置编码 2.4.1 绝对位置编码2.4.2 相对位置编码2.4.3 旋转位置编码 RoPE2.4.4 ALiBi位置编码 2.5 注意力机制 2.5.1 完整自注意力机制2.5.2 稀疏注意力机…