预备基础:1.概览
什么是Open CASCADE Technology?
Open CASCADE Technology (OCCT) 是一个功能强大的开源 C++ 库,由数千个类组
成,并提供以下领域的解决方案:
- 表面和实体建模:对任何对象进行建模。
- 3D 和 2D 可视化:显示对象并为其设置动画。
- 数据交换:导入和导出标准 CAD 格式。
- 快速应用程序开发:操作自定义应用程序数据。
OCCT 还适用于 CAD/CAM/CAE 的许多其他领域,包括 AEC、GIS 和 PDM。OCCT 专为需要良好质量、可靠性和强大工具集的 3D 建模和可视化应用程序的工业开发而设计。
OCCT 库在 GNU 宽通用公共许可证 (LGPL) 版本 2.1 下以开源方式分发给多个平台。
怎么获取OCCT?
您可以通过以下方式获取 Open CASCADE Technology:
- 从官方网站下载版本:
- 在OPEN CASCADE公司官方网站上创建帐户。
- 注册后,您将可以访问下载页面。
- 从源码(Git 存储库)构建 OCCT。
要从官方 Git 存储库获取 OCCT 源码,应该: - 在协作开发门户上创建一个帐户。
- 克隆 OCCT Git 存储库(使用您的 ssh 密钥)。
- 下载必要的第3方库。
下载 OCCT 源代码后,可以使用 CMake 为 IDE 生成项目文件。
从源码构建
从源码构建 OCCT 涉及几个步骤:
- 下载OCCT源码;
- 下载必要的第三方库(TCL 和 FreeType 是标准构建的最低要求);
- 配置CMake:
- 点击“configure”按钮;
- 设置 3RDPARTY_DIR 变量指向解压的第三方文件夹;
- 将 INSTALL_DIR 更改为所需的目录;
- 启用必要的功能;
- 如果不需要OCCT开发环境,则启用 BUILD_USE_PCH 以使用预编译头加速计算;
- 再次点击“configure”按钮;
- 点击“generate”按钮。
源码包中的内容是什么?
对象库
对象库分为模块:
- Foundation classes
- Modeling data
- Modeling algorithms
- Visualization
- Data exchange
- Shape healing
- Applicattion framework(OCAF)
每个模块包含多个库,每个库包含分组到包中的类:
文档
- 从 Doxygen 注释自动生成;
- 手动编写的用户和开发人员指南。
编程示例
使用不同 GUI 的编程示例:
- MFC
- C#
- Qt
- Java
测试套件应用
- 基于 TCL 的命令解释器
- 一组预定义的命令
- 大多数 OCCT API 都可以在测试套件( Test Harness )中使用
- Test Harness 是 OCCT的原型框架
- 该应用程序用于测试 OCCT本身
应该提前了解的内容
必修知识:
- C++面向对象语言
- 编程技术
- 常见数学、代数、几何
可选知识: - 计算机辅助设计基础
文献书籍
性能提示
并行模式
一些算法具有并行模式:
- BRepAlgoAPI
- BRepMesh_IncrementalMesh
- BVH Tree construction
Part-related
使用简单的对象可以获得更好的性能:
- C2连续性;
- 低阶样条;
- 小结点矢量
尽可能使用规范几何: - 许多算法的有效实现
使用拓扑信息代替几何数据: - 数据共享、连接等
数据模型
利用数据共享。这种技术称为实例化:
- 多次使用同一形状部分,对它们进行不同的变换
- 此外,这个概念可以在可视化级别上重复使用(AIS Connected Interactives)
可视化
尽量保持渲染批次的数量尽可能少:
- 每批次都涉及相应的 OpenGL 操作集 (glDrawArrays /gIDrawElements)。这些调用的计算成本很高。
- 大量的渲染批次会影响CPU性能。每个组应在 CPU 端单独处理。对于 OpenGL,该过程以单线程模式工作。
编写程序
- 对于大阶矩阵,不要使用 OCCT 线性代数,因为它是为低阶输入设计的;
- 使用 OCCT 分配器来避免动态内存分配;
- 使用 BVH 等加速数据结构;
- 尽可能使用局部操作;
- 在布尔算法之后使用面(face)最大化;
- 避免使用 NCollection_Sequence。请改用 NCollection_Vector 或NCollection_List。
预备基础:2.Draw
什么是Draw?
Draw 是OCCT的基本测试工具。它提供:
- 基于TCL语言的命令解释器;
- 一组预定义的命令;
- 添加自定义命令的可能性
可以创建和操作、保存和恢复实体,在视图中显示它们等。Draw 可以是用于自动化测试等的自定义场景的原型。OCCT发行版是名为 DRAWEXE 的 Draw 可执行文件的即用型实现。按如下方式启动:
DRAWEXE 提供了一个用于从插件库加载新命令的接口。技术模块中定义的绘
制命令被组织到此类插件中,并且可以通过运行 pload 命令加载到 DRAWEXE。
pload [-PluginResourceFile] [Key1] [key2] …
Draw 插件的默认资源文件是 %CASROOT%/src/DrawResources/DrawPlugin,它
收集所有标准插件的定义。为了加载所有标准绘图命令,请运行:
Draw[1]> pload ALL
Draw命令语言
命令由一个或多个单词组成:第一个单词是命令的名称,其他单词是参数。单词之间用空格或制表符分隔。以下命令构造一个盒子:
Draw[1]> box b 10 10 10
命令由换行符或分号分隔:
Draw[1]> box b 10 10 10; fit
可以使用 source命令从文件中读取命令:
Draw[1]> source myscript.txt
基础命令
help 命令提供有关命令的帮助:
Draw[1]> help [command]
exit命令终止程序执行:
Draw[1]> exit
source 命令从文件中读取命令:
Draw[1]> source box
directory 命令用于返回与模式匹配的所有绘制全局变量的列表:
Draw[1]> directory [command]
Whatis 命令获取有关Draw变量的信息:
Draw[1]> whatis <varname>
dump 命令获取有关Draw变量的长信息:
Draw[1]> dump <varname>
save 将Draw变量的值放入文件中
Draw[1]> save <varname> <filename>
restore 将文件的内容放入Draw变量中:
Draw[1]> restore <filename> <varname>
视图命令
Draw 提供了一组标准的屏幕布局命令:
Draw[1]> axo; pers; top; bottom; left; right; front; back; mu4; v2d; av2d
wzoom 命令允许用鼠标选择要缩放的区域:
Draw[1]> wzoom
平移视图的命令:
Draw[1]> pu; pd; pr; pl; 2pdu; 2dpd; 2dpr; 2dpl
向上、向下、向右、向左旋转视图的命令:
Draw[1]> u; d; l; r;
display 命令使对象可见:
Draw[1]> display <varname> [ … ]
donly 命令使对象可见并删除所有其他对象:
Draw[1]> donly <varname> [ … ]
erase 命令从所有视图中擦除对象:
Draw[1]> erase <varname> [ … ]
从视图中清除对象的命令:
Draw[1]> clear; 2dclear
3D视图命令
vinit 命令初始化 3D 视图:
Draw[1]> vinit
vdisplay 命令使对象可见:
Draw[1]> vdisplay <varname> [ … ]
从视图中清除对象的命令:
Draw[1]> vclear [varname] [ … ]
设置背景颜色:
Draw[1]> vsetcolorrbg <r> <b> <g>
设置相机选项:
Draw[1]> vcamera [options]
设置视图参数
Draw[1]> vviewparams [options]
设置光照参数:
Draw[1]> vlight [options]
DrawTrSurf package
DrawTrSurf 包用于连接 C++ 几何实体与 Draw 实例。该包的方法允许:
-
将对象设置为具有给定名称的 Draw 几何变量
-
从具有给定名称的 Draw 几何变量获取对象
DBRep package
DBRep包用于连接C++拓扑实体与Draw实例。该包的方法允许:
-
将 TopoDS_Shape 设置为具有给定名称的绘制拓扑变量!
-
从具有给定名称的 Draw 拓扑变量获取 TopoDS_Shape!
基于Draw的应用
要编写 Draw 程序,必须遵守以下结构:
-
从 main 函数启动并初始化 Draw:
-
或者,可以使用宏来启动:
新命令的定义
当运行Draw时,系统调用函数Draw_InitAppli。该函数必须定义在可执行文件,并且必须在该函数内的 Draw 命令解释器中添加(注册)命令。
Draw插件机制
或者,新的 Draw 命令可以组合到一些动态库中并加载到 DRAWEXE 中具有插件接口的可执行文件。插件的入口点应实现为静态方法某个类的 Factory() 应该用宏 DPLUGIN 声明,例如:
OCCT 与位于 $CASROOT/src/DrawResources 目录中的 DrawPlugin 资源文件一起提供。该文件的格式符合标准 OCCT 资源文件(有关详细信息,请参阅Resource_Manager.hxx 文件)。每个键定义了一系列其他(嵌套)键或动态库的名
称。键可以嵌套到任意级别。但是,不会检查键之间的循环依赖关系。例子:
命令定义
新绘制命令的定义示例如下:
预备基础:3.OCCT基础
标准类型
OCCT 定义了一组基本数据类型的别名,在整个库中使用中这些别名替代纯 C++ 数据类型名称:
Standard_Boolean 可以采用以下两个值之一:
Handle机制
handle是整个 OCCT 中使用的智能指针。一般来说,handle机制基于两种要素:
- 存储对内存中对象的引用次数的计数器
- 指向内存中对象的指针
每次创建对象的新handle时,该对象的引用计数器都会递增。
每次删除对象的handle时,该对象的引用计数器就会递减。一旦引用计数器达到 0,该对象就会被自动删除。
这样,引用计数器就保证了删除功能。handle不能像通常的指针那样引用任何东西。
Handle 和智能指针
从C++11标准开始就有内置的智能指针。 OCСТ handle和智能指针有什么区别?
很容易看出 OCCT 的handle与 C++11 中的共享指针完全等效。 OCCT 可以不包含其他智能指针类型的等效项。
Handle实现
本节介绍如何实现由 OCCT handle机制包装的新类。新类应该继承自 Standard_Transient 类或其后代:
应在类定义中声明特殊宏,以便创建handle:
完整的示例可以在 OCCT 源代码中找到 \src\BRepAdaptor\BRepAdaptor_HCurve.hxx
操作系统抽象层
OCCT 为 OSD 包中的低级操作系统设施提供独立于平台的接口。该包类似“python”编程语言中的“os”模块。提供以下功能:
- 方法 OSD::SetSignal() 设置一个 C 信号处理程序,用于转换软件信号(例如浮点错误、访问冲突等)到常见的 C++ 异常。
- OSD_File、OSD_Path、OSD_Directory 类为文件系统提供了统一的接口。
- OSD_Mutex 和 OSD_Thread 类为互斥锁和线程的系统相关实现提供了统一的接口。
- OSD_Timer 类实现了一个方便的计时器对象。
- 类 OSD_Host、OSD_Process 提供对当前计算机上的信息的访问过程。
容器
从历史上看,OCCT 中有两个容器集。
TCollection 包在 1998 年标准化之前用于模拟模板。从 OССТ 开始7.0 中,它被相应的 NCollection 实例取代。
NCollection 包是一个较新的基于模板的包,提供现代容器。应该使用它尽可能代替 TCollection 类。
OCCT 中索引从 1 开始,NCollection_Vector 除外(其中索引从 0 开始)。这样做是为了与基于 STL 的算法兼容。
容器类通过值进行操作;还为大多数实例提供了由 Handle 操作的版本,请参见 TCollection_HArray1。
容器和STL
OCCT中有很多容器;将它们与 STL 集合进行比较是富有成效的,因为它们是 C++ 语言的通用参考点。与往常一样,与 STL 相比,有几个优点和缺点。
优点:
-
接口,OCCT 容器的设计和实现是为了人类可读。以下代码段演示了 OCCT 的 Seek() map方法的 STL 等效项:
-
内存效率,OCCT 容器旨在提高内存效率。例如,当一个新元素添加到NCollection_Vector 并需要重新打包时;将分配固定大小的新块,而不是完全重新分配内存。新的元素将被添加到新的块中,而不是内存复制和元素移动。
缺点
- 随机索引访问比 STL 容器慢。可测量的差异可以观察到一些极端的情况。在低级内存优化期间可能会遇到这个问题在间接寻址场景。
容器比较
异常
按照惯例,Open CASCADE 库中使用的所有异常类均继承自Standard_Failure 类。从它派生的异常类的层次结构在 Standard 包中定义。
为了在数值不稳定的情况下 OCCT 算法稳健工作,有必要调用该方OSD::SetSignal() 在应用程序中的某处(一次;在 Windows 上 - 每个执行线程一次)。
之后,标准C++异常和软件信号都可以在通常的C++中以统一的方式处理方式:
消息
Message Package 为 OCCT 和应用程序级算法提供了以抽象且可定制的方式与用户沟通:
- Message_Messenger 类是字符串消息输出的接口。它可以根据应用程序的需要,通过将输出定向到一个或多个流、GUI 窗口或其他任何内容来进行定制。
- Message_Msg 类提供消息本地化的方法。它由消息密钥初始化,参数并构造相应的消息作为文本字符串。消息的定义与键关联的字符串是从资源文件中加载的。
- Message_Algorithm 类为类提供了一种实现复杂算法的便捷方法返回执行的扩展状态,包括有关遇到问题的面向用户的消息和情况。
进度指示器
进度指示器是一个实体,允许跟踪下游算法的进度并报告它。Message_ProgressIndicator 类为复杂算法提供了一个接口,以告知其在运行时的当前执行状态,并有可能根据用户命令中断。目前(OCCT7.4.0),不支持在多线程应用程序中使用并发进度指示器。进度指示器的典型封装如下所示: