3DXML 文件格式解析及应用
2010-01-01王晓斌
王晓斌, 宁 涛, 王 可
(1. 北京航空航天大学机械工程及自动化学院,北京 100191; 2. 北京新洲协同软件技术有限公司,北京 100062)
三维模型不仅是设计和制造过程中表达产品信息的重要媒介,在产品发布,产品销售,维护等过程中,同样扮演着重要的角色。通过在网络上浏览产品的三维模型,将三维模型整合到技术文档、维护手册、宣传册、邮件中,用户可以更直接的了解产品的相关信息,更加迅速地掌握产品的使用,降低产品的维护成本。
但是传统的CAD 文件中包含重要的设计信息,而且文件较大,不便于网络传输和企业之间的数据交流。针对这些问题,需要一种轻量化的三维模型数据格式,保留产品的三维模型显示信息,过滤掉重要的设计信息,同时文件的尺寸更小。
通过CAD 软件内置的工具,可以将三维模型转换成VRML,STL,PLY 等文件,这些文件采用三角片来表示模型,过滤了模型的设计信息,但是没有装配信息,不能表达零件之间的关系,同时文件较大,不便于网络传输和存储。
为此,Dassault Systemes 公司推出了3DXML文件格式[1]。3DXML 是一种基于XML 的轻量化的3D 数据格式,它体积更小,压缩比高,能使用户快速、简单地获得和共享精确的3D 数据。
本文针对3DXML 文件格式进行解析,给出解析的主要步骤和基于3DXML 文件的轻量化三维模型浏览方案及应用实例。
1 3DXML 简介
3DXML 是一种完全开放的数据格式,不同于一般的CAD 文件,3DXML 文件中不含有几何信息,只包含模型实体信息,同时保有装配信息。这使3DXML 的文件尺寸远远小于一般的CAD文件,同时3DXML 对文件近一步压缩,使其能够提供更快的文件传输速度和更短的储存时间。
3DXML 完全遵循XML 语法,使用任何的标准XML 解析器都可以对其进行解析,提取需要的信息。
Dassault System 在其所有的产品中如CATIA,Virtools 等,都加入了对3DXML 的支持,可以将CAD 文件转换成相应的3DXML 文件,同时Dassault Systemes 提供了3DXML 浏览器,但是只能进行最基本的显示操作,而用户在使用模型的过程中,往往要进行如拖拽,生成爆炸图,设置属性,添加注释等操作,这就需要提取图形信息,重新进行组织,完成所需的功能。为此,本文对3DXML 文件格式进行解析,提取必要的信息,建立适当的数据结构,对文件数据重新进行组织,以实现对三维模型的浏览和编辑。
2 3DXML 解析器设计及实现
本文所采用的3DXML 文件格式为最新的4.0 版本,其解压后的所有文件都可以使用文本编辑器进行浏览和修改。
解析器使用MSXML4.0 进行XML 文件的解析[2],使用SAX(A Simple API for XML)方式进行解析,该解析方式适合解析大型的XML 文件,可以快速提取大型装配体的相关信息。SAX 是一个事件驱动接口,采用顺序的方式读取XML 文件,在读到XML 元素的开始标记,结尾标记和内容标记时将产生一系列的事件,返回元素名,属性值,元素内容字符串等信息供用户使用。对MSXML 所提供的接口ISAXContentHandler,派生出新的类,并重载该接口的3 个虚函数,如表1 所示。
表1 SAX 解析主要重载函数
startElement 响应XML 元素结点开始事件,endElement 响应结点结束事件,character 处理所有的非结点字符,包括元素值,空格和换行符。
当解析器读取到文件相应内容时,将自动回调上表中相应函数,并将文件信息作为参数传入函数供使用者调用。
3DXML 文件的基本构成如图1 所示。
图1 3DXML 多文件组织结构
3DXML 文件是一种多文档格式,并采用ZIP算法压缩成一个文件。Manifest 文件中的<Root>元素结点值为装配信息文件名,即扩展名为3dxml 的文件。扩展名为3drep 的文件保存图形数据及属性信息。在本文的解析器中,有两个主要的类,都派生自接口ISAXContentHandler,分别用来解析装配和图形文件。
在解析的过程中,首先对文件进行解压缩,然后读取Manifest 文件,获取装配信息文件名。读取装配信息,生成产品结构树,同时获取所有的图形数据文件名,最后依次解析图形文件。
2.1 装配信息解析
在装配文件中保存的信息较多,但产品的装配结构是人们最关心的,因此主要针对装配信息进行解析。
3DXML 文件中零件之间的装配关系采用有向非循环图结构进行组织[3]。其文件数据结构如图2 所示。
3DXML 采用引用/实例(Reference/Instance)的方式描述产品结构,引用表示一个可以被重复使用的物体,实例则表示该引用的一个实例化物体,而一个引用常常又是由多个实例组成。
图2 装配文件结构
产品结构信息由XML元素<ProductStructure >标识其开始,该结点有 4 类子结点,<Reference3D>,<Instance3D>,<ReferenceRep>,<InstanceRep>。每个结点具有唯一的ID 值。<Instance3D>结点有3个子结点,<IsAggregatedBy>,<IsInstanceOf>,<RelativeMatrix>,前两个子结点中分别保存了一个ID 值,表示该实例结点是哪个引用结点的组成部分,该实例结点是哪个引用结点的一个实例,最后一个子节点存储了该实例结点相对其上层引用结点的相对位置矩阵。<ReferenceRep>结点保存了图形数据的文件名,<InstanceRep>结点作为连接图形结点和零件引用结点的中间结点。其两个子结点保存的信息与<Instance3D>的前两个子节点的信息相同。在本文的解析器中,有向非循环图中的结点为<Reference3D>和<Instance3D>两个元素结点。其数据结构如下:
解析过程主要针对上图中的4 类结点进行解析,重点解析Reference3D 和Instance3D 结点。为了便于结点的查询,创建一张结点指针表,保存结点指针,即Reference3D*和Instance3D*。在读取到引用结点开始元素时,检测指针表中对应ID 的结点是否创建,若指针为空,则创建,然后读取相应的属性信息。在读取到实例结点时,同样检测对应指针是否为空并读取属性信息,对于实例结点的前两个子节点,只判断对应ID 的结点是否为空,为空则只分配内存,不为其填入属性信息。
有向非循环图结构可以大大减少文件的尺寸,但不便于图形的绘制和属性的传递。为此,需要将图形结构装换成常用的树形结构。采用深度优先原则遍历图,遍历过程中,将每条路径中出现的Instance3D结点做为树结点添加到树结构中。
2.2 图形数据解析
在装配文件中,每个<ReferenceRep>元素结点对应一个3drep 文件,即图形文件。
3DXML 的一个图形文件中可能包含多个零件的图形数据,这些零件在装配体结构中,可以看作是一个完整的零件,而不会影响装配结构的表达。其文件数据结构如图3 所示。
图3 图形文件结构
每个零件的图形数据由 XML 元素<Rep xsi:type="PolygonalRepType">标识其开始,由面片集合<Faces>,边集合<Edges>和顶点信息<VertexBuffer>组成。顶点缓存中保存该零件所有顶点的坐标和法线,在面片信息中只保存组成面的三角形(条带,扇)的索引,可以大大减少了图形文件的尺寸。在边集合中的点则直接保存为点的坐标值。为了加快图形绘制的速度,面片信息中使用了LOD(多细节层次)模型,每个零件最多有8 个LOD 模型,由元素<PolygonalLOD>标识。在图形绘制过程中,计算该零件到视点的距离,然后根据文件中每个细节层次所提供的临界选取值,即<PolygonalLOD>的属性accuracy,选择相应的LOD 模型绘制,可以大大提高渲染的效率。
图形文件中没有存储各基础图元的数量,为了加快解析速度,减少内存使用,可预先分配一块足够大的缓存,每次将某种图元数据全部读取到缓存并计算出图元数量[5]。在读取到该图元结点结束的位置时,为相应的图形结点分配内存,将缓存中的数据拷贝至其中,并将缓存清空,为下个图元结点数据加载做准备。
2.3 解压缩
3DXML 文件是采用ZIP 压缩算法进行压缩的。通过文本编辑器打开3DXML 文件,可以看到文本的前两个字符为PK,所有采用ZIP 算法压缩后的文件,其前两个字符都以PK 作为标识。
在本文的解析器中,采用了Zlib 库进行解压,Zlib 库是一个开源的免费的商用程序库,主要用来解压/压缩字符串。本文解析器在其基础上进行了封装,使其可以解压文件,这里不再赘述。
3 3DXML 数据格式的应用
在VC6.0 平台上,作者开发了基于3DXML文件的轻量化浏览器,采用 OpenGL 和Direct3D9.0 完成渲染操作。同时,开发了其控件版本,可以嵌入文档或网页中,便于产品信息的发布和共享。
浏览器界面如图4 所示。在模型的左边用树形结构表示产品的装配层次关系。系统提供了基本的交互操作,可以设置零件的颜色,实现了零件的显示和隐藏。
图4 中的装配体由超过200 个零件组成,文件大小仅为1.38M,为原始CAD 文件大小的5%,文件解析时间大约5 秒,其帧率可达到30 帧/秒以上,完全可以满足交互操作的效率要求。
图4 基于3DXML 的轻量化浏览器
4 结 束 语
3DXML 文件格式体积小,便于扩展和传输,可以大大加快产品信息的发布和企业之间资源的共享。本文针对3DXML 文件格式进行解析,提取重要的装配信息和图形数据。供用户在此基础上进行进一步的开发。
[1] Dassault System. 3D XML User’s Guide[EB/OL]. http://www.3ds.com, 2007.
[2] Fabio Arciniegas. Advanced programming guide with C++XML [M]. 北京: 中国希望电子出版社, 2002. 102-357.
[3] 曹 翔. 3DXML 标准在协同装配中的研究与应用[D]. 南京: 南京航空航天大学, 2007.
[4] 孙 静, 宋 杨, 胡金星, 等. 大型XML 文件的分割和动态加载研究[J]. 计算机工程与应用, 2003, 16(6): 107-125.
[5] 刘云华, 刘 俊, 陈立平. 产品三维数据模型轻量化表示实现[J]. 计算机辅助设计与图形学学报, 2006, 18(4): 602-607.
[6] 谢君英. 微软XML技术指南[M]. 北京: 中国电力出版社, 2003. 126-460.