人月是Parasolid的重度使用者,他基于Parasolid开发大型CAD软件近20年,这次请他基于Parasoid给大家再进一步的探究下几何引擎。本文内容主要供大家参考学习,并不是推广Parasolid或者其他几何引擎。
计算机中表示三维形体的模型,按照几何特点进行分类,大体上可以分为三种:线框模型、表面模型和实体模型。其中,实体建模指的是一组用于三维形状(实体)的数学和计算机建模的概念。实体建模与一般的几何建模和计算机图形学的相关领域(例如 3D 建模)的主要区别在于它强调物理保真度。几何和实体建模的原则共同构成了 3D 计算机辅助设计的基础,并且通常支持物理对象数字模型的创建、变换、可视化、查询和记录等功能。
如果按照表示物体的方法进行分类,实体模型基本上可以分为构造表示CSG(Constructive Solid Geometry)和边界表示BREP(Boundary Representation)两大类。
图1. CSG表示法
图2. B-rep表示法
因此,实体建模内核实际上是指能够为CAD软件提供上述核心建模功能的一个组件,它是整个CAD软件的核心和基础。具体来说它可以提供:
经过了40多年的发展,目前市场上的主流建模内核主要有西门子公司开发的Parasolid,达索公司的ACIS和开源的OpenCascade.
ACIS是美国spatial technology公司的产品,后被达索公司收购。它提供从简单实体到复杂实体的造型功能,以及实体的布尔运算、曲面裁减、曲面过渡等多种编辑功能,还提供了实体的数据存储功能和SAT文件的输入、输出功能。ACIS的特点是采用面向对象的数据结构,用C++编程,使得线架造型、曲面造型、实体造型任意灵活组合使用。线架造型仅用边和顶点定义物体;曲面造型类似线框造型,只不过多定义了物体的可视面;实体造型用物体的大小、形状、密度和属性(重量、容积、重心)来表示。ACIS产品使用软件组件技术,用户可使用所需的部件,也可以用自己开发的部件来替代ACIS的部件。ACIS产品包括一系列的ACIS 3D Toolkit几何造型和多种可选择的软件包,一个软件包类似于一个或多个部件,提供一些高级专业函数,可以单独出售给需要特定功能的用户。ACIS产品可向外出售接口源程序,同时鼓励各家软件公司在ACIS核心开发系统的基础上发展与STEP标准相兼容的集成制造系统。
Open CASCADE (简称OCC)是一款开源的几何造型引擎。基于该建模引擎发展了若干CAD/CAE/CAM软件,如国外的FreeCAD、HeeksCAD,国内的AnyCAD。Open CASCADE(简称OCC)为开源社区比较成熟的基于BREP结构的建模引擎,能够满足二维三维实体造型和曲面造型,国内研究和使用它的单位也越来越多.OCC可以分为建模、可视化和数据管理(OCAF)三大模块。其中建模为核心组件;可视化组件基于OpenGL,相对其他的三维可视化OpenGL平台(如Coin3d,OpenInventor,Ogre3d,OSG,VTK等),功能简单,并且显示效果比较差,不能充分利用GPU硬件加速;OCAF采用树的方式管理数据,使用比较复杂,效率比较低,并且不适合自定义扩展。
首先,什么是Parasolid呢?Parasolid是世界上领先的、经过生产证明的三维几何建模组件软件。利用该软件提供的核心功能,基于Parasolid产品的用户能够快速、稳定地对行业最复杂的产品建模。由于基于高精度的边界表示技术(B-rep), Parasolid支持在一个集成框架中进行实体建模、广义单元建模以及自由曲面建模。
图3. Parasolid接口函数架构
Parasolid是一个三维建模内核,所以任何基于三维模型数据的应用软件都应该将Parasolid作为架构的基础或者核心。Parasolid提供了非常丰富的接口函数,如图3所示,这些接口函数主要分成两种:
需要注意的是,在启动内核之前应用程序需要注册自己提供的Frustrum接口函数,否则Parasolid不能启动。
根据Parasolid定义,可以在内核和用户的应用程序之间传递的数据项统统称为对象(Object)。每个对象都属于一个定义通用类型对象的类。Parasolid 中的类符合层次树的结构,如下图所示,最顶层的类是CLASS, 它是所有其它类型的父类。
图4. Parasolid类的层次结构
在黄色的方框中的都是拥有Tag值的类, 包含了最经常使用的到的一些类型。其中,PARTITION, PMARK和MARK这几种类主要是用于帮助应用程序进行回滚;ATTDEF,ATTRIB, GROUP主要是用来帮助应用程序把特定的信息记录到模型中;最重要也是类型最多的是几何(GEOM)和拓扑(TOPOL)两个类型。
在Parasolid里,按照使用目的一般把数据分为两类:几何(Geometry)和拓扑(Topology)。其中,“几何”描述的是具体 位置和形状,“拓扑”描述的是邻接关系。
“几何”比较容易理解,就是我们通常所说的点,线,面,体。线又可以分为直线,线段,圆,圆弧,NURBS曲线,贝赛尔曲线等各种线,面也类似可以分为平面,非参数曲面,参数方程定义的曲面等。而体则定义了各种实体,长方体,圆柱,球,圆环,组合体等。下图是Parasolid中的所有几何类型。
图5. Parasolid的几何类型
什么是“拓扑”呢?它是研究几何图形或空间在连续改变形状后还能保持不变的一些性质的一个概念, 它只考虑物体间的位置关系而不考虑它们的形状和大小。
图6. Parasolid的拓扑类型
所以在Parasolid中,所有的拓扑类型按照边界表示法共构成了模型的骨架。
图7. Parasolid的拓扑类型和几何类型的联系
附着在某一特定拓扑上的几何类型(Surface, Curve, Point)构成了模型具体的形状和位置,Parasolid把这一类几何称为Principle Geometry。与之相对的,只附着在体(Body)上的几何,Parasolid称之为Construction Geometry。例如,用户需要用一个点来表示体的质心,那么就可以创建这个点然后附着在Body上。
附着在某一特定拓扑上的几何类型(Surface, Curve, Point)构成了模型具体的形状和位置,Parasolid把这一类几何称为Principle Geometry。与之相对的,只附着在体(Body)上的几何,Parasolid称之为Construction Geometry。例如,用户需要用一个点来表示体的质心,那么就可以创建这个点然后附着在Body上。
为什么要有“拓扑”的概念?其实很好理解,举个例子,一条线段有两个顶点,当我们只知道其中一点的坐标数据时,希望得到该点在哪条线段上。如果没有拓扑信息,简单的办法就是全局计算遍历一遍,缺点显而易见;如果有拓扑信息,记录了该点的拓扑信息,即该点的上层拓扑直线,我们直接拿点的拓扑信息就可以了。
图8. Parasolid的拓扑结构示例
从上图的示例中我们可以去更直观的感受到拓扑其实只是模型的骨架。图中圆柱和圆台虽然形状不一样,但是他们有相同的拓扑结构,只是拓扑对象上所附着的几何对象不同,使得模型拥有不同的形状。FA代表拓扑的face, SU代表几何的Surface。我们可以看到,两个模型都有3个面,但是所附着的曲面,在圆柱体上是两个平面和一个圆柱面,在圆台上是两个平面和一个圆锥面,这就是他们为什么有相同的拓扑却形状不一样的原因了。
Parasolid实际上是一组C语言函数库,不仅可以被C/C++应用程序调用,同时还提供了能够被.net应用程序调用的绑定库,可以帮助使用C#的用户也可以正常的调用Parasolid API函数。
图9 .Net程序调用 Parasolid示例
本章示例代码均为C++代码。
要想使用Parasolid进行建模,首先要启动ParasolidSession。根据Parasolid的定义,一个session就是指的在开始和结束之间的所有的操作和函数调用。启动和停止是通过调用PK_SESSION_start, PK_SESSION_stop。
需要注意的是,在启动session之前应用程序要注册Frustrum函数,否则无法启动,这一点在前面有所介绍。
启动Session之后,用户就可以使用Parasolid进行建模操作了。Parasolid提供了多达几百个用于建模操作的接口函数,用户可以根据需求从文档中查询需要用到的函数介绍。
下面我们来展示一下如何用Parasolid创建一个圆柱体。
// Declare body and initialize.
PK_BODY_t primitive = PK_ENTITY_null;
// Declare position and orientation
PK_AXIS2_sf_t basis_set;
// Assign position and orientation value
basis_set.location.coord[0] = 15;
basis_set.location.coord[1] = -5;
basis_set.location.coord[2] = 5;
basis_set.axis.coord[0] = 0;
basis_set.axis.coord[1] = 1;
basis_set.axis.coord[2] = 0;
basis_set.ref_direction.coord[0] = 1;
basis_set.ref_direction.coord[1] = 0;
basis_set.ref_direction.coord[2] = 0;
// Call PK API to create a cylinder body.
PK_BODY_create_solid_cyl( 2.5, 20.0, &basis_set, &primitive );
读写数据
Parasolid可以把创建好的模型数据存到磁盘中,也可以从磁盘中读取存储的模型数据。读写数据是通过调用PK_PART_transmit, PK_PART_receive来实现的。
int n_parts = 0;
PK_PART_t *parts = nullptr;
// Obtain all the parts in the session
PK_SESSION_ask_parts( &n_parts, &parts );
// Declare transmit option
PK_PART_transmit_o_t transmit_opts;
PK_PART_transmit_o_m( transmit_opts );
// Set the format as text
transmit_opts.transmit_format = PK_transmit_format_text_c;
char *key = "..\\Example Parts\\block";
// Call PK API to save the bodies into a file
PK_PART_transmit( n_parts, parts, key, &transmit_opts );
图11. 存储文件的代码示例
int n_parts = 0;
PK_PART_t *parts = nullptr;
// Declare receive option
PK_PART_receive_o_treceive_opts;
PK_PART_receive_o_m( receive_opts );
// Set the format as text
receive_opts.receive_format = PK_receive_format_text_c;
char *key = "..\\Example Parts\\block";
// Call PK API to load the file data into the session
PK_PART_receive( key, &receive_opts, &n_parts, &parts );
图12. 读取文件的代码示例
本文首先简要介绍了三维实体建模以及内核的概念,然后分析了当前建模内核的发展现状,接着详细介绍了Parasolid的功能和一些基本概念并在提供了一些简单的Parasolid示例代码,最后总结了在Parasolid应用过程中遇到的三个实践问题以及解决方案。
通过此次本文我们了解了Parasolid的基本概念,并结合编程习题全面学习了Parasolid的文档的查询方法,掌握了Parasolid建模接口函数的基本功能,使大家具备了在Windows/Linux平台下配置、开发和调试Parasolid应用程序的能力,为进一步开发基于Parasolid建模内核的大型商业化工业软件奠定了坚实的基础。
Parasolid Functional Description