opencascade 的建模数据与算法的代码架构简述

大概10年前,一位业内知名的教授在给我们上数据结构的课时,提到过一个重要概念。他说:“大道极简,其实世界上所有的程序只有两个东西,其一,是数据结构,其二,是运算过程”。opencascade是cad几何引擎库,那么对于一个几何引擎库而言,在几何层面它也只创建了两个东西,其一是几何数据结构,其二是几何数据的构建与操作的算法过程。

基本数据结构简介

当我们打开opencascade源代码,发现在它的src目录下面有非常多的子目录。从目录名称可以看出,其命名规则是有讲究的。对于现代cad来说,其数据结构包含3个层面,其一,几何层面描述几何元素;其二,描述拓扑结构中单位元素的边界描述法;其三,描述3D几何体的拓扑结构;这3个层面对应这opencascade源代码中重要的几个子目录:

  1. Geom 目录中的代码定义opencascade会用到的所有几何元素
  2. Geom2d 目录中的代码定义了opencascade会用到的所有2维几何元素
  3. gp 目录中定义了组成Geom或Geom2d的更基本的几何元素
  4. BRep目录中的代码定义了opencascade的边界描述法的数据结构
  5. TopoDS目录中的代码定义了opencascade的3D几何体的拓扑结构

TopoDS中的Shape与TShape

TopoDS包中定义了两套Shape,一套是常规的Shape,而另外一套是TShape。一般用户是不需要直接操作TShape的,Shape其实是对TShape的一次封装,它给TShape提供了方向和位姿属性。也就是说,TShape只管几何体的外形,而Shape还要负责描述几何体在空间的位置和方向。TopoDS包中的代码为我们构建了一层抽象的拓扑几何关系。它定义了点,线,面和体的关系。

BRep对TShape的进一步具体化

前面提到的TopoDS包只描述了抽象的顶点,边和面之间的关系。却没有描述点,线,面与实际几何对象的关系。在BRep包中,就具体的建立了顶点和点,边与曲线,面与曲面之间的关系。例如,在TopoDS中只表达了顶点这个概念,但却没有给顶点定义坐标。而在BRep包中,描述了面是由什么曲面生成的,面的误差是多少,用三角面片表达的数据又是什么样的?

值得单独拿出来一提的是,BRep中对边与曲线建立了一对多的关系。opencascade中引入了曲线表达的概念。同一个边,在实际应用中需要用到的多种表达方式。例如圆柱面与平面的交线,为了很好的应用,我们需要用至少3条曲线方法来表达这条边的几何外形。其一,是在3D空间内的几何表达;其二,是在平面空间内的几何表达;其三,是在圆柱空间内的几何表达。后两者虽然是2维曲面,但却很重要。尤其是在曲面之间做切割,三角化运算等操作时,都需要用到。对与同一条边的不同几何表达,在算法应用上大多有一个基本要求,那就是不同的参数表达里,参数的取之范围和参数值对应的实际点位置应该一致。这两个条件分别对应着边的SameRange和SameParameter两个标识位。如果边的三条曲线不满足此要求,则很多算法都会无效。从某种意义上来说,如果这两个条件不满足,此边将被认为是无效边。

缝合边与退化边

在正常的封闭实体中只存在3种类型的边,一种是普通边。正如,上文所提到的,普通边都有3个几何曲线的表达,一条是在3D空间的曲线表达,一条是在曲面A空间的曲线表达,还有一条是在曲面B空间上的曲线表达。而缝合边,比较特殊,它除了3D空间的曲线表达外,其余的两条表达曲线是在同一个曲面内(例如圆柱面的圆柱上的那条封闭边)。退化边的更特殊了,它表示在2维曲面空间内虽然存在有意义的曲线,但它在3维空间里不存在有意义的曲线(例如球面的南北极顶点)。退化边在创建的时候,opencascade会刻意的移除其3D空间的表达曲线,并将Degenerated标识为置为true。

基本的构建和操作方法

构建一个3D实体,实际上就称为了构建一个有效的TopoDS_Shape。上文提到了BRep是TShape的具体化,而TopoDS是对TShape增加位姿和方向的封装。构建一个3D实体从大体上,可以分为两步:1.通过几何元素构建基本的点,边,面。2.通过组合点,边,面,构建拓扑逻辑体。第1步的操作对应着BRep/BRep_Builder.x 文件中的代码,第2步对应着TopoDS/TopoDS_Builder.x文件中的代码。理论上通过这两个文件提供的api,我们已经能够构建任何3D实体。

然而,实时上却没有这么简单。TopoDS_Builder和BRep_Builder定义的方法都太底层了。如果创建任何实体都要先研究它每个面的曲面以及边界曲线的参数方程,这会要了那群设计师的老命的。所以,为了让这个世界更加美好,opencascade定义一系列的工具和算法来帮助设计师更好的建模。

BRepBuilder与BRepLib

在opencascade中,BRepBuilder和BRepLib是上下级的关系。BRepLib定义了比较方便的构建BRep元素的方法,而BRepBuilder定义了调用BRepLib的方法。通过BRepBuilder调用BRepLib可以更好的访问和控制创建BRep元素的过程与结果。

BRepPrim与BRepPrimAPI

前面提到的BRepBuilder和BRepLib都只能比较单一的一个个创建或改变某个BRep元素。这是非常低效的建模行为。BRepPrim则定义了通过拉伸,旋转等逻辑来批量的创建BRep元素。到了这一步,设计师们终于看到了曙光。通过一些直观的逻辑来批量的创建点,线,面使的设计师快速设计3维实体成为现实。实时上,opencascade中不只BRepPrim包是用来批量建立BRep,还有一些其他的包也是做同样的事情,只不过是应用逻辑不一样而已。BRepPrimAPI与BRepPrim也是上下级的关系,BRepPrimAPI对BRepPrim进一步封装,让建模过程和结果更加可控。

使用BRepCheck来检查实体

BRepCheck是opencascade中用来测试的库,这个库能检查我们创建的3D实体是否有效。这个库在软件开发过程中是非常重要的存在。理论上,通过高级方法创建实体是需要保证一定有效的。但一方面opencascade的高级建模方法在一些特殊情况下,可能本身存在缺陷,另一方面,opencascade的用户也不全是设计师,也许有人需要用occ底层来建模。在第二种情况下,BRepCheck就是神器,它能快速帮助开发人员定位问题。

发表评论

邮箱地址不会被公开。 必填项已用*标注