王曉斌, 寧 濤, 王 可
(1. 北京航空航天大學機械工程及自動化學院,北京 100191; 2. 北京新洲協同軟件技術有限公司,北京 100062)
三維模型不僅是設計和制造過程中表達產品信息的重要媒介,在產品發布,產品銷售,維護等過程中,同樣扮演著重要的角色。通過在網絡上瀏覽產品的三維模型,將三維模型整合到技術文檔、維護手冊、宣傳冊、郵件中,用戶可以更直接的了解產品的相關信息,更加迅速地掌握產品的使用,降低產品的維護成本。
但是傳統的CAD 文件中包含重要的設計信息,而且文件較大,不便于網絡傳輸和企業之間的數據交流。針對這些問題,需要一種輕量化的三維模型數據格式,保留產品的三維模型顯示信息,過濾掉重要的設計信息,同時文件的尺寸更小。
通過CAD 軟件內置的工具,可以將三維模型轉換成VRML,STL,PLY 等文件,這些文件采用三角片來表示模型,過濾了模型的設計信息,但是沒有裝配信息,不能表達零件之間的關系,同時文件較大,不便于網絡傳輸和存儲。
為此,Dassault Systemes 公司推出了3DXML文件格式[1]。3DXML 是一種基于XML 的輕量化的3D 數據格式,它體積更小,壓縮比高,能使用戶快速、簡單地獲得和共享精確的3D 數據。
本文針對3DXML 文件格式進行解析,給出解析的主要步驟和基于3DXML 文件的輕量化三維模型瀏覽方案及應用實例。
3DXML 是一種完全開放的數據格式,不同于一般的CAD 文件,3DXML 文件中不含有幾何信息,只包含模型實體信息,同時保有裝配信息。這使3DXML 的文件尺寸遠遠小于一般的CAD文件,同時3DXML 對文件近一步壓縮,使其能夠提供更快的文件傳輸速度和更短的儲存時間。
3DXML 完全遵循XML 語法,使用任何的標準XML 解析器都可以對其進行解析,提取需要的信息。
Dassault System 在其所有的產品中如CATIA,Virtools 等,都加入了對3DXML 的支持,可以將CAD 文件轉換成相應的3DXML 文件,同時Dassault Systemes 提供了3DXML 瀏覽器,但是只能進行最基本的顯示操作,而用戶在使用模型的過程中,往往要進行如拖拽,生成爆炸圖,設置屬性,添加注釋等操作,這就需要提取圖形信息,重新進行組織,完成所需的功能。為此,本文對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 文件,獲取裝配信息文件名。讀取裝配信息,生成產品結構樹,同時獲取所有的圖形數據文件名,最后依次解析圖形文件。
在裝配文件中保存的信息較多,但產品的裝配結構是人們最關心的,因此主要針對裝配信息進行解析。
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結點做為樹結點添加到樹結構中。
在裝配文件中,每個<ReferenceRep>元素結點對應一個3drep 文件,即圖形文件。
3DXML 的一個圖形文件中可能包含多個零件的圖形數據,這些零件在裝配體結構中,可以看作是一個完整的零件,而不會影響裝配結構的表達。其文件數據結構如圖3 所示。

圖3 圖形文件結構
每個零件的圖形數據由 XML 元素<Rep xsi:type="PolygonalRepType">標識其開始,由面片集合<Faces>,邊集合<Edges>和頂點信息<VertexBuffer>組成。頂點緩存中保存該零件所有頂點的坐標和法線,在面片信息中只保存組成面的三角形(條帶,扇)的索引,可以大大減少了圖形文件的尺寸。在邊集合中的點則直接保存為點的坐標值。為了加快圖形繪制的速度,面片信息中使用了LOD(多細節層次)模型,每個零件最多有8 個LOD 模型,由元素<PolygonalLOD>標識。在圖形繪制過程中,計算該零件到視點的距離,然后根據文件中每個細節層次所提供的臨界選取值,即<PolygonalLOD>的屬性accuracy,選擇相應的LOD 模型繪制,可以大大提高渲染的效率。
圖形文件中沒有存儲各基礎圖元的數量,為了加快解析速度,減少內存使用,可預先分配一塊足夠大的緩存,每次將某種圖元數據全部讀取到緩存并計算出圖元數量[5]。在讀取到該圖元結點結束的位置時,為相應的圖形結點分配內存,將緩存中的數據拷貝至其中,并將緩存清空,為下個圖元結點數據加載做準備。
3DXML 文件是采用ZIP 壓縮算法進行壓縮的。通過文本編輯器打開3DXML 文件,可以看到文本的前兩個字符為PK,所有采用ZIP 算法壓縮后的文件,其前兩個字符都以PK 作為標識。
在本文的解析器中,采用了Zlib 庫進行解壓,Zlib 庫是一個開源的免費的商用程序庫,主要用來解壓/壓縮字符串。本文解析器在其基礎上進行了封裝,使其可以解壓文件,這里不再贅述。
在VC6.0 平臺上,作者開發了基于3DXML文件的輕量化瀏覽器,采用 OpenGL 和Direct3D9.0 完成渲染操作。同時,開發了其控件版本,可以嵌入文檔或網頁中,便于產品信息的發布和共享。
瀏覽器界面如圖4 所示。在模型的左邊用樹形結構表示產品的裝配層次關系。系統提供了基本的交互操作,可以設置零件的顏色,實現了零件的顯示和隱藏。
圖4 中的裝配體由超過200 個零件組成,文件大小僅為1.38M,為原始CAD 文件大小的5%,文件解析時間大約5 秒,其幀率可達到30 幀/秒以上,完全可以滿足交互操作的效率要求。

圖4 基于3DXML 的輕量化瀏覽器
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.