eryar

PipeCAD - Plant Piping Design Software.
RvmTranslator - Translate AVEVA RVM to OBJ, glTF, etc.
posts - 603, comments - 590, trackbacks - 0, articles - 0

Open CASCADE Foundation Classes – Basics

Posted on 2012-08-23 20:28 eryar 阅读(4184) 评论(2)  编辑 收藏 引用 所属分类: 2.OpenCASCADE

Open CASCADE Foundation ClassesBasics

Open CASCADE 基础库之基本功能

eryar@163.com

本章主要介绍Open CASCADE的基本功能,如内存管理(memory management)、手柄编程(programming with handles)、基本类型(primitive types)、异常处理(exception handling)、泛型编程(genericity by downcasting)、Plug-in的创建等……

一、数据类型 Data Types

1.1 基本类型 Primitive Types

基本类型是由语言定义的且他们是由值控制的。有些基本类型从类Storable继承而来。这就意味着他们可以在持久性对象中使用,或者被包含在对象的方法中,或者作为对象内部的一部分。由类Standard_Storable派生的类有:

l Boolean: 用来表示逻辑数据。只有两种状态:Standard_TrueStandard_False;

l Character: 用来表示任意ASCII字符;

l ExtCharacter: 用来表示字符的扩展;

l Integer: 用来表示整数;

l Real: 用来表示实数;

l ShortReal: 用来表示实数的另一种选择,精度要低;

也有非存储类型,如:

l CString:

l ExtString:

l Address:

下表所示为Open CASCADE中基本类型与C++中基本类型对应表:

C++ Types

Open CASCADE Types

int

Standard_Integer

double

Standard_Real

float

Standard_ShortReal

unsigned int

Standard_Boolean

Standard_False = 0;

Standard_True = 1;

char

Standard_Character

short

Standard_ExtCharacter

char*

Standard_CString

void*

Standard_Address

short*

Standard_ExtString

clip_image002 使用上述基本类型的注意事项:

具体请参考《Open CASCADE Foundation Classes User's Guide》;

1.2 由值控制的类型

由值控制的变量类型分为三类:

l 基本类型;

l 枚举类型;

l 不是由类Standard_Persistent直接或间接派生的类;

由值控制的变量比由手柄控制的变量更直接,更快,就是不能保存到文件。

clip_image004

1.3 由引用控制的类型

由手柄控制的变量分为两类:

l 由类Persistent派生的类,这种类可以保存到文件;

l 由类Transient派生的类;

clip_image006

1.4 属性的结论

clip_image008

二、手柄编程 Programming with Handles

2.1 手柄定义 Handle Definition

手柄与C++的指针(pointer)类似。几个手柄可以引用同一个对象,同样地,一个手柄也可以引用了几个对象,但是一次只能是一个对象。为了访问引用的对象,必须先解除引用(de-referenced),就像使用C++的指针一样。临时变量和持久变量既可以是由值控制的也可以是由手柄控制的。引用非持久性对象的手柄称为不可存储手柄。因此,持久性对象不能包含不可存储手柄。

类的组织:使用手柄的类的对象可以是持久的也可是临时的。从类Standard_Transient继承的类的实例是临时的,而从类Standard_Persistent继承的类的实例是持久的。本章只讨论临时类及其相关的手柄。持久类及其相关的手柄的组织与此类似。

Standard_TransientOpen CASCADE中由手柄控制的类层次结构中的基类。它有引用计数部分,所有的子类都继承此部分。当使用Handle()类时,就可知引手柄引用实例的数量。

直接或间接由类Transient派生的类,CDL extractor将创建类的相应的手柄Handle(),类名是相同的,只是在类名前加上了“Handle_*”。Open CASCADE提供预处理器的宏定义Handle(),用来产生相应类的带手柄的类。

使用手柄:在对临时对象执行任何操作之前,你必须声明手柄。如:若点(Point)和线(Line)是从包Geom中定义的两个临时对象,代码如下:

clip_image010

声明手柄创建了一个未指向任何对象的空手柄。手柄可以通过其方法IsNull()来验证。使用手柄无效,可使用方法Nullify()。

只要类型兼容,既可以从创建新的对象或通过赋值来初始化手柄。手柄仅用于共享的对象。对于所有的本地操作,建议使用由值控制的类。

2.2 类型管理 Type Management

Open CASCADE提供一种描述数据类型层次的通用方式,并且可以运行时检查对象类型,与C++的RTTI类似。对于从类Standard_Transient继承的每个类,CDL extractor从类Standard_Type创建代码。由类Standard_Transient派生的类的虚函数DynamicType()返回一个实例。通过虚函数IsKind()来检查给定的对象是不是指定的类型。

2.3 使用手柄创建对象 Using Handles to Create Objects

创建由手柄控制的对象,声明手柄并使用标准C++的new操作符,紧随其后调用构造函数。

clip_image012

与指针不同的是,手柄不需要delete。因为当手柄引用的对象为零时,对象将会被自动释放。

2.4 方法调用 Invoking Methods

当你使用手柄的时候,就跟使用C++的指针一样。调用手柄引用对象的方法使用操作符->。检查或修改手柄的状态,通过操作符点.来实现。下例所示为访问一个点对象的坐标:

clip_image014

下例所示为如何检查笛卡尔坐标点的类型:

clip_image016

当调用一个空Null手柄时,NullObject异常将会产生。

调用类方法:类方法就是C++类中的静态函数。即用类名加上“::”和方法名来调用。

clip_image018

2.5 手柄释放 Handle De-allocation

在删除一个对象之前,必须其没有被引用。为了减少管理对象生命周期的编程工作量,Open CASCADE中对象的删除函数是由手柄控制类的引用计数(reference counter)来确保。手柄就是用来管理引用计数,当对象不再引用时将会调用delete将其删除。当是Standard_Transient的子类时,通常不需要直接使用delete操作符。当对相同的对象使用new时,引用计数将会增加。当手柄被销毁、置为空或重新赋值,引用计数将会减少。当引用计数为0时对象将会自动调用delete操作符。内存分配的原理如下所示:

clip_image020

Cycles

本段内容不清楚,具体内容请参考原文。

2.6 不使用CDL创建类 Creating Transient Classes without CDL

尽管可用CDL extractor生成手柄类及其相关C++代码,然而也可不用CDL管理手柄。为此,在文件Standard_DefineHandle.hxx中提供了几个宏定义:

DECLARE_STANDARD_HANDLE(class_name, ancestor_name) 这个宏定义了以class_name为类名并继承类ancestor_name的手柄类。这个宏必须放在头文件中,且基类必须是可用的。

IMPLEMENT_STANDARD_HANDLE(class_name, ancestor_name) 这个宏实现了转换方法DownCast(),应该在C++文件中使用。

DEFINE_STANDARD_RTTI(class_name) 这个宏声明方法需要RTTI支持,应该在类的public中使用。

IMPLEMENT_STANDARD_RTTIEXT(class_name, ancestor_name) 实现上面的方法。

注:在使用这些宏的时候,必须确保参数的正确性,特别是父类的名字。否则定义将会不正确,且编译也不会报错。

clip_image022

clip_image024

三、内存管理 Memory Management in Open CASCADE

在几何建模的过程中,程序创建和删除相当数量的C++对象在动态内存中,也就是堆中(heap)。在这种情况下,标准函数管理内存的性能可能不足够。所以,Open CASCADE在标准包中实现了内存的管理。

3.1 用法 Usage

使用Open CASCADE内存管理只需要在C中使用malloc()的地方使用Standard::Allocate();在使用free()的地方使用Standard::Free();在使用realloc()的地方使用Standard::Reallocate()。

C++中,类的操作符new()和delete()已经定义了在申请内存时使用Standard::Allocate()并在释放时使用Standard::Free()。所以,类所有的对象的内存都将由Open CASCADE的内存管理器来管理。

CDL extractor为所有的类定义了new()和delete()。所以,所有的Open CASCADE的类(小部分除外)都使用Open CASCADE的内存管理器。

由于操作符new()和delete()被继承,所以,所有从Open CASCADE派生的类,所有从Standard_Transient类派生的类都是由内存管理器管理。

注:若重载了部分从Standard_Transient类派生类的new()和delete(),尽管不推荐这样做,方法Delete()必须重定义,以便对这样的指针使用delete操作。这将确保合适的delete()函数将会被调用,即使是由手柄控制的对象。

3.2 配置内存管理器 Configuring Memory Manager

Open CASCADE内存管理器可以被配置以便对不同的内存区域使用不同的优化技术,或者根本不使用任何优化而直接使用Cmalloc()和free()函数。配置方法为修改环境变量的值:

l MMGT_OPT

l MMGT_CLEAR

l MMGT_CELLSIZE:

l MMGT_NBPAGES:

l MMGT_THRESHOLD:

l MMGT_REENTRANT:

3.3 实现细节 Implementation details

本段内容请参考原文。

四、异常处理 Exception Handling

异常处理提供了一种从指定点转换到其他点的一种方法。一个方法可能会产生一个异常,将程序从正常执行处转换到捕捉异常处。Open CASCADE提供了异常类的层次,其基类是包Standard中的Standard_FailureCDL extractor使用标准接口生成异常类。

Open CASCADE也提供将系统信号的转换成异常的支持,如数除0这样所有的情况都可以用安全、统一的方法来处理了。但是为了支持不同的平台,也使用了一些特殊的方法。

如下内容为在Open CASCADE中使用异常处理的推荐方法。

4.1 产生异常 Raising an Exception

C++的语法:产生适当的异常将需要调用指定类型的Raise()方法。

clip_image026

产生了一个DomainError类型的异常并可附上相关信息“Cannot cope with this condition”,信息字符串是可选的。这个异常可以被捕捉DomainError类型的Handler捕捉到:

clip_image028

正常使用异常处理:异常不能被当作编程技巧来替代“goto”,但可作为防止方法被误用的一种方法。

五、Plug-In管理

本段内容请参考原文。

六、结论

本章内容介绍了一些C++编程的知识及Open CASCADEC++的包装。其中,手柄编程是C++中常见的方法,这种引用计数的方式使内存的管理更方便。

 

eryar@163.com

Pudongxin Shanghai China

2012-8-23

Feedback

# re: Open CASCADE Foundation Classes – Basics  回复  更多评论   

2012-08-24 13:18 by 力为
用这个的越来越多了,好事情!

# re: Open CASCADE Foundation Classes – Basics  回复  更多评论   

2012-08-26 09:17 by eryar
学习学习, 希望能做点东西出来@力为

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理