FreeCAD源码分析:Type System

40 篇文章 134 订阅

虽然C++11引入了RTTI、Metaprogramming 等技术,但C++在Reflection方面依旧功能有限。作为反射机制的组成部分,类型系统(Type System)提供运行时类型信息(RTTI)、依据类名创建对象等功能。

FreeCAD中,类型系统插件式开发框架分层架构等核心实现的基础,因此,有必要对这个基础问题予以研究分析。

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

  • Meta Object
  • RTTI
  • Factory Method Pattern
  • Model-View-Presenter 
  • Layered Architecture
  • Modular Development Framework

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

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

一、主要组件

1.1 Base::Type

Base::Type实际上是一般类型系统中的类型注册表,通过其静态成员变量存储了类型名称、对象构造器、类型继承关系等类型信息。

可以看到,FreeCAD实际上是通过TypeData来描述类型名称、父类名称、对象构造器等类型信息,并将所有的类型信息注册到Base::Type::typedata静态变量,而每个Type对象仅维护一个类型索引index。

1.2 Base::BaseClass

Base::BaseClass是一般类型系统中的接口类,定义了对象构造器,同时维护了类型信息索引,也就是提供了对元对象的访问。

二、关键流程

2.1 类型注册

相较于QtRTTR等反射机制,FreeCAD并没有提供类型自动注册的实现,因此,需要结合需要手动编写代码以完成类型注册。

在FreeCAD中,大体上有两种类型注册方式:

一是在FreeCADApp、FreeCADGui等软件主体启动时,便会调用App::Application::initTypes()完成一些类型的注册。

void Application::initTypes()
{
    // Base types
    Base::Type                      ::init();
    Base::BaseClass                 ::init();
    Base::Exception                 ::init();
    Base::AbortException            ::init();
    Base::Persistence               ::init();

    // Complex data classes
    Data::ComplexGeoData            ::init();
    Data::Segment                   ::init();

    // ... ...
}

另外一种方式就是在加载各种Module时,比如对于Part模块,

PyMOD_INIT_FUNC(Part)
{
    Base::Console().Log("Module: Part\n");

    // ... ...

    Part::TopoShape             ::init();
    Part::PropertyPartShape     ::init();
    Part::PropertyGeometryList  ::init();
    Part::PropertyShapeHistory  ::init();
    Part::PropertyFilletEdges   ::init();
    Part::PropertyTopoShapeList ::init();

    // ... ...
}

2.2 对象创建

当完成类型注册之后,便可以依据类型名称调用对应构造器来创建对象。

在FreeCAD中,类型系统的一个主要应用就是分层系统的实现。

  • App::DocumentObject/Gui::ViewProviderDocumentObject

void Document::slotNewObject(const App::DocumentObject& Obj)
{
    // ... ...
        //Base::Console().Log("Document::slotNewObject() called\n");
        std::string cName = Obj.getViewProviderNameStored();
        for(;;) {
            if (cName.empty()) {
                // handle document object with no view provider specified
                FC_LOG(Obj.getFullName() << " has no view provider specified");
                return;
            }
            Base::Type type = Base::Type::getTypeIfDerivedFrom(cName.c_str(), ViewProviderDocumentObject::getClassTypeId(), true);
            pcProvider = static_cast<ViewProviderDocumentObject*>(type.createInstance());
            // createInstance could return a null pointer
            if (!pcProvider) {
                // type not derived from ViewProviderDocumentObject!!!
                FC_ERR("Invalid view provider type '" << cName << "' for " << Obj.getFullName());
                return;
            }
            else if (cName!=Obj.getViewProviderName() && !pcProvider->allowOverride(Obj)) {
                FC_WARN("View provider type '" << cName << "' does not support " << Obj.getFullName());
                delete pcProvider;
                pcProvider = nullptr;
                cName = Obj.getViewProviderName();
            }
            else {
                break;
            }
        }
    // ... ...
}

三、演练: ACISE中的反射机制

参考文献

  • Erich Gamma. Design Patterns:elements of reusable object-oriented software. Addison Wesley, 1994.
  • Joseph Ingeno. Software Architect's Handbook. Packt Publishing, 2018.

网络资料

An Introduction to Reflection in C++icon-default.png?t=N7T8https://blog.csdn.net/qq_26221775/article/details/138768568?spm=1001.2014.3001.5501

FreeCADicon-default.png?t=N7T8https://www.freecad.org/

RTTRicon-default.png?t=N7T8https://www.rttr.org/

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

SALOME源码分析:MDF框架icon-default.png?t=N7T8https://blog.csdn.net/qq_26221775/article/details/139268234?spm=1001.2014.3001.5501

FreeCAD源码分析:Property Systemicon-default.png?t=N7T8https://blog.csdn.net/qq_26221775/article/details/140326663?spm=1001.2014.3001.5501

  • 27
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Module developer’s guide to FreeCAD source code by Qingfeng Xia http://www.iesensor.com • 2015-09-18 version 0.1 for FreeCAD version 0.16-dev • 2016-09-18 version 0.2 for FreeCAD version 0.17-dev License of this book This ebook is licensed the same as FreeCAD document license CC-BY 3.0 http://creativecommons.org/licenses/by/3.0/Contents 1 FreeCAD overview and architecture 7 1.1 Introduction to FreeCAD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 1.2 Key features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 1.3 Software architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 1.3.1 Key software libraries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 1.3.2 Mixed python and c++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 1.3.3 GPL code will not be included into installer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 1.4 How 3D model are renderred . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 1.4.1 Selection of 3D visualization libarary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 1.4.2 Discussion of 3D rendering library selection on FreeCAD Forum . . . . . . . . . . . . . . . . . . . . . 8 1.5 Roadmap of FreeCAD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 1.5.1 Keep updated with main components: . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 1.5.2 C++11 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 1.5.3 Pyside 2 project for Qt 5.x . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 2 Organisation of FreeCAD source code 11 2.1 Build system for FreeCAD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 2.1.1 Analysis of src/cMake/SMesh.cMake . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 2.2 List of files and folders in FreeCAD source folder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 2.3 List of modules in FreeCAD Mod folder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 2.4 Learning path . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 2.5 Learning OpenInventor/Coin3D . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 2.5.1 OpenInventor in FreeCAD’s ViewProvider . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 2.5.2 Important classes in OpenInventor/Coin3D . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 2.5.3 Window System integration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 2.5.4 Pivy: Coin3D ’s Python wrapping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 3 Base, App and Main module 19 3.1 List of header files in Base folder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 3.1.1 Frequently included headers files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 3.1.2 Correct way of using Sequencer in try-catch block . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 3.1.3 String enconding utf8 and conversion into wchar_t QString . . . . . . . . . . . . . . . . . . . . . . . . 22 3.2 Type, BaseClass, PyObjectBase . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 3.2.1 Type system . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 3.2.2 src/Base/BaseClass.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 3.2.3 src/Base/PyObjectBase.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 3.2.4 src/Base/Persistence.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 3.2.5 GeoFeature: Base class of all geometric document objects . . . . . . . . . . . . . . . . . . . . . . . . . 26 3.3 Unit scheme for physial quantity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 3.3.1 src/Base/Unit.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 3.3.2 src/Base/Quantity.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 3.4 List of header files in App folder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 3.5 Property framewrok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 3.5.1 Naming of property and PropertyEditor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 3.5.2 src/App/PropertyStandard.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 3.5.3 PropertyEnumeration, see src/App/Enumeration.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 3.5.4 Geometry related property . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 3.5.5 File related property . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 1
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值