王曉斌, 寧 濤, 王 可
(1. 北京航空航天大學(xué)機械工程及自動化學(xué)院,北京 100191; 2. 北京新洲協(xié)同軟件技術(shù)有限公司,北京 100062)
三維模型不僅是設(shè)計和制造過程中表達產(chǎn)品信息的重要媒介,在產(chǎn)品發(fā)布,產(chǎn)品銷售,維護等過程中,同樣扮演著重要的角色。通過在網(wǎng)絡(luò)上瀏覽產(chǎn)品的三維模型,將三維模型整合到技術(shù)文檔、維護手冊、宣傳冊、郵件中,用戶可以更直接的了解產(chǎn)品的相關(guān)信息,更加迅速地掌握產(chǎn)品的使用,降低產(chǎn)品的維護成本。
但是傳統(tǒng)的CAD 文件中包含重要的設(shè)計信息,而且文件較大,不便于網(wǎng)絡(luò)傳輸和企業(yè)之間的數(shù)據(jù)交流。針對這些問題,需要一種輕量化的三維模型數(shù)據(jù)格式,保留產(chǎn)品的三維模型顯示信息,過濾掉重要的設(shè)計信息,同時文件的尺寸更小。
通過CAD 軟件內(nèi)置的工具,可以將三維模型轉(zhuǎn)換成VRML,STL,PLY 等文件,這些文件采用三角片來表示模型,過濾了模型的設(shè)計信息,但是沒有裝配信息,不能表達零件之間的關(guān)系,同時文件較大,不便于網(wǎng)絡(luò)傳輸和存儲。
為此,Dassault Systemes 公司推出了3DXML文件格式[1]。3DXML 是一種基于XML 的輕量化的3D 數(shù)據(jù)格式,它體積更小,壓縮比高,能使用戶快速、簡單地獲得和共享精確的3D 數(shù)據(jù)。
本文針對3DXML 文件格式進行解析,給出解析的主要步驟和基于3DXML 文件的輕量化三維模型瀏覽方案及應(yīng)用實例。
3DXML 是一種完全開放的數(shù)據(jù)格式,不同于一般的CAD 文件,3DXML 文件中不含有幾何信息,只包含模型實體信息,同時保有裝配信息。這使3DXML 的文件尺寸遠遠小于一般的CAD文件,同時3DXML 對文件近一步壓縮,使其能夠提供更快的文件傳輸速度和更短的儲存時間。
3DXML 完全遵循XML 語法,使用任何的標(biāo)準(zhǔn)XML 解析器都可以對其進行解析,提取需要的信息。
Dassault System 在其所有的產(chǎn)品中如CATIA,Virtools 等,都加入了對3DXML 的支持,可以將CAD 文件轉(zhuǎn)換成相應(yīng)的3DXML 文件,同時Dassault Systemes 提供了3DXML 瀏覽器,但是只能進行最基本的顯示操作,而用戶在使用模型的過程中,往往要進行如拖拽,生成爆炸圖,設(shè)置屬性,添加注釋等操作,這就需要提取圖形信息,重新進行組織,完成所需的功能。為此,本文對3DXML 文件格式進行解析,提取必要的信息,建立適當(dāng)?shù)臄?shù)據(jù)結(jié)構(gòu),對文件數(shù)據(jù)重新進行組織,以實現(xiàn)對三維模型的瀏覽和編輯。
本文所采用的3DXML 文件格式為最新的4.0 版本,其解壓后的所有文件都可以使用文本編輯器進行瀏覽和修改。
解析器使用MSXML4.0 進行XML 文件的解析[2],使用SAX(A Simple API for XML)方式進行解析,該解析方式適合解析大型的XML 文件,可以快速提取大型裝配體的相關(guān)信息。SAX 是一個事件驅(qū)動接口,采用順序的方式讀取XML 文件,在讀到XML 元素的開始標(biāo)記,結(jié)尾標(biāo)記和內(nèi)容標(biāo)記時將產(chǎn)生一系列的事件,返回元素名,屬性值,元素內(nèi)容字符串等信息供用戶使用。對MSXML 所提供的接口ISAXContentHandler,派生出新的類,并重載該接口的3 個虛函數(shù),如表1 所示。
表1 SAX 解析主要重載函數(shù)
startElement 響應(yīng)XML 元素結(jié)點開始事件,endElement 響應(yīng)結(jié)點結(jié)束事件,character 處理所有的非結(jié)點字符,包括元素值,空格和換行符。
當(dāng)解析器讀取到文件相應(yīng)內(nèi)容時,將自動回調(diào)上表中相應(yīng)函數(shù),并將文件信息作為參數(shù)傳入函數(shù)供使用者調(diào)用。
3DXML 文件的基本構(gòu)成如圖1 所示。
圖1 3DXML 多文件組織結(jié)構(gòu)
3DXML 文件是一種多文檔格式,并采用ZIP算法壓縮成一個文件。Manifest 文件中的<Root>元素結(jié)點值為裝配信息文件名,即擴展名為3dxml 的文件。擴展名為3drep 的文件保存圖形數(shù)據(jù)及屬性信息。在本文的解析器中,有兩個主要的類,都派生自接口ISAXContentHandler,分別用來解析裝配和圖形文件。
在解析的過程中,首先對文件進行解壓縮,然后讀取Manifest 文件,獲取裝配信息文件名。讀取裝配信息,生成產(chǎn)品結(jié)構(gòu)樹,同時獲取所有的圖形數(shù)據(jù)文件名,最后依次解析圖形文件。
在裝配文件中保存的信息較多,但產(chǎn)品的裝配結(jié)構(gòu)是人們最關(guān)心的,因此主要針對裝配信息進行解析。
3DXML 文件中零件之間的裝配關(guān)系采用有向非循環(huán)圖結(jié)構(gòu)進行組織[3]。其文件數(shù)據(jù)結(jié)構(gòu)如圖2 所示。
3DXML 采用引用/實例(Reference/Instance)的方式描述產(chǎn)品結(jié)構(gòu),引用表示一個可以被重復(fù)使用的物體,實例則表示該引用的一個實例化物體,而一個引用常常又是由多個實例組成。
圖2 裝配文件結(jié)構(gòu)
產(chǎn)品結(jié)構(gòu)信息由XML元素<ProductStructure >標(biāo)識其開始,該結(jié)點有 4 類子結(jié)點,<Reference3D>,<Instance3D>,<ReferenceRep>,<InstanceRep>。每個結(jié)點具有唯一的ID 值。<Instance3D>結(jié)點有3個子結(jié)點,<IsAggregatedBy>,<IsInstanceOf>,<RelativeMatrix>,前兩個子結(jié)點中分別保存了一個ID 值,表示該實例結(jié)點是哪個引用結(jié)點的組成部分,該實例結(jié)點是哪個引用結(jié)點的一個實例,最后一個子節(jié)點存儲了該實例結(jié)點相對其上層引用結(jié)點的相對位置矩陣。<ReferenceRep>結(jié)點保存了圖形數(shù)據(jù)的文件名,<InstanceRep>結(jié)點作為連接圖形結(jié)點和零件引用結(jié)點的中間結(jié)點。其兩個子結(jié)點保存的信息與<Instance3D>的前兩個子節(jié)點的信息相同。在本文的解析器中,有向非循環(huán)圖中的結(jié)點為<Reference3D>和<Instance3D>兩個元素結(jié)點。其數(shù)據(jù)結(jié)構(gòu)如下:
解析過程主要針對上圖中的4 類結(jié)點進行解析,重點解析Reference3D 和Instance3D 結(jié)點。為了便于結(jié)點的查詢,創(chuàng)建一張結(jié)點指針表,保存結(jié)點指針,即Reference3D*和Instance3D*。在讀取到引用結(jié)點開始元素時,檢測指針表中對應(yīng)ID 的結(jié)點是否創(chuàng)建,若指針為空,則創(chuàng)建,然后讀取相應(yīng)的屬性信息。在讀取到實例結(jié)點時,同樣檢測對應(yīng)指針是否為空并讀取屬性信息,對于實例結(jié)點的前兩個子節(jié)點,只判斷對應(yīng)ID 的結(jié)點是否為空,為空則只分配內(nèi)存,不為其填入屬性信息。
有向非循環(huán)圖結(jié)構(gòu)可以大大減少文件的尺寸,但不便于圖形的繪制和屬性的傳遞。為此,需要將圖形結(jié)構(gòu)裝換成常用的樹形結(jié)構(gòu)。采用深度優(yōu)先原則遍歷圖,遍歷過程中,將每條路徑中出現(xiàn)的Instance3D結(jié)點做為樹結(jié)點添加到樹結(jié)構(gòu)中。
在裝配文件中,每個<ReferenceRep>元素結(jié)點對應(yīng)一個3drep 文件,即圖形文件。
3DXML 的一個圖形文件中可能包含多個零件的圖形數(shù)據(jù),這些零件在裝配體結(jié)構(gòu)中,可以看作是一個完整的零件,而不會影響裝配結(jié)構(gòu)的表達。其文件數(shù)據(jù)結(jié)構(gòu)如圖3 所示。
圖3 圖形文件結(jié)構(gòu)
每個零件的圖形數(shù)據(jù)由 XML 元素<Rep xsi:type="PolygonalRepType">標(biāo)識其開始,由面片集合<Faces>,邊集合<Edges>和頂點信息<VertexBuffer>組成。頂點緩存中保存該零件所有頂點的坐標(biāo)和法線,在面片信息中只保存組成面的三角形(條帶,扇)的索引,可以大大減少了圖形文件的尺寸。在邊集合中的點則直接保存為點的坐標(biāo)值。為了加快圖形繪制的速度,面片信息中使用了LOD(多細節(jié)層次)模型,每個零件最多有8 個LOD 模型,由元素<PolygonalLOD>標(biāo)識。在圖形繪制過程中,計算該零件到視點的距離,然后根據(jù)文件中每個細節(jié)層次所提供的臨界選取值,即<PolygonalLOD>的屬性accuracy,選擇相應(yīng)的LOD 模型繪制,可以大大提高渲染的效率。
圖形文件中沒有存儲各基礎(chǔ)圖元的數(shù)量,為了加快解析速度,減少內(nèi)存使用,可預(yù)先分配一塊足夠大的緩存,每次將某種圖元數(shù)據(jù)全部讀取到緩存并計算出圖元數(shù)量[5]。在讀取到該圖元結(jié)點結(jié)束的位置時,為相應(yīng)的圖形結(jié)點分配內(nèi)存,將緩存中的數(shù)據(jù)拷貝至其中,并將緩存清空,為下個圖元結(jié)點數(shù)據(jù)加載做準(zhǔn)備。
3DXML 文件是采用ZIP 壓縮算法進行壓縮的。通過文本編輯器打開3DXML 文件,可以看到文本的前兩個字符為PK,所有采用ZIP 算法壓縮后的文件,其前兩個字符都以PK 作為標(biāo)識。
在本文的解析器中,采用了Zlib 庫進行解壓,Zlib 庫是一個開源的免費的商用程序庫,主要用來解壓/壓縮字符串。本文解析器在其基礎(chǔ)上進行了封裝,使其可以解壓文件,這里不再贅述。
在VC6.0 平臺上,作者開發(fā)了基于3DXML文件的輕量化瀏覽器,采用 OpenGL 和Direct3D9.0 完成渲染操作。同時,開發(fā)了其控件版本,可以嵌入文檔或網(wǎng)頁中,便于產(chǎn)品信息的發(fā)布和共享。
瀏覽器界面如圖4 所示。在模型的左邊用樹形結(jié)構(gòu)表示產(chǎn)品的裝配層次關(guān)系。系統(tǒng)提供了基本的交互操作,可以設(shè)置零件的顏色,實現(xiàn)了零件的顯示和隱藏。
圖4 中的裝配體由超過200 個零件組成,文件大小僅為1.38M,為原始CAD 文件大小的5%,文件解析時間大約5 秒,其幀率可達到30 幀/秒以上,完全可以滿足交互操作的效率要求。
圖4 基于3DXML 的輕量化瀏覽器
3DXML 文件格式體積小,便于擴展和傳輸,可以大大加快產(chǎn)品信息的發(fā)布和企業(yè)之間資源的共享。本文針對3DXML 文件格式進行解析,提取重要的裝配信息和圖形數(shù)據(jù)。供用戶在此基礎(chǔ)上進行進一步的開發(fā)。
[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 標(biāo)準(zhǔn)在協(xié)同裝配中的研究與應(yīng)用[D]. 南京: 南京航空航天大學(xué), 2007.
[4] 孫 靜, 宋 楊, 胡金星, 等. 大型XML 文件的分割和動態(tài)加載研究[J]. 計算機工程與應(yīng)用, 2003, 16(6): 107-125.
[5] 劉云華, 劉 俊, 陳立平. 產(chǎn)品三維數(shù)據(jù)模型輕量化表示實現(xiàn)[J]. 計算機輔助設(shè)計與圖形學(xué)學(xué)報, 2006, 18(4): 602-607.
[6] 謝君英. 微軟XML技術(shù)指南[M]. 北京: 中國電力出版社, 2003. 126-460.