您的位置:首页 > 娱乐 > 明星 > VTK源码分析:Type System

VTK源码分析:Type System

2024/12/24 8:18:45 来源:https://blog.csdn.net/qq_26221775/article/details/140569305  浏览:    关键词: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

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com