陳軍任,王艷紅
(1.沈陽工業(yè)大學(xué)信息科學(xué)與工程學(xué)院,沈陽 110870;2.沈陽工業(yè)大學(xué)管理學(xué)院,沈陽 110870)
隨著科技發(fā)展,人們對(duì)加工速度以及加工質(zhì)量有了更高的要求,STL 的可視化技術(shù)在應(yīng)用中占據(jù)了很大的比重。STL 的可視化技術(shù)就是將3D 掃描的STL 文件快速轉(zhuǎn)化為可視化的三維模型,便利于人們對(duì)其進(jìn)行人機(jī)交互等操作,提高加工速率及精確度。研究者對(duì)于STL 的可視化進(jìn)行了大量的研究,占志敏[1]等結(jié)合OpenGL 圖形編程技術(shù),成功實(shí)現(xiàn)STL 三維模型的可視化,其算法簡(jiǎn)單,只是經(jīng)過簡(jiǎn)單的冗余處理及拓?fù)潢P(guān)系。鄭毅[2]使用C++標(biāo)準(zhǔn)模板庫(kù)和迭代器技術(shù)進(jìn)行編程,借助紅黑樹結(jié)構(gòu),加快了拓?fù)渲亟ㄈ蝿?wù),但沒有實(shí)現(xiàn)三維顯示及人機(jī)交互。鄒學(xué)涌[3]等采用基于哈希表的拓?fù)渲亟ㄋ惴ǎ⒔柚薕penGL 顯示技術(shù),實(shí)現(xiàn)顯示效果及信息獲取,該算法中哈希函數(shù)的設(shè)定對(duì)算法效率影響較大,設(shè)置不當(dāng)會(huì)使效率大幅降低。尚旭明[4]利用WPF 及XAML技術(shù)實(shí)現(xiàn)了對(duì)3ds Max 模型的顯示及簡(jiǎn)單人機(jī)交互。Tata[5]等人提出了一種自適應(yīng)分層算法,可以根據(jù)局部幾何形狀改變層厚,算法基于三個(gè)基本概念:選擇適應(yīng)曲面復(fù)雜性的準(zhǔn)則、識(shí)別對(duì)象的關(guān)鍵特征和物體特征,以及開發(fā)用于表示對(duì)象的facet 的分組方法。Choi[6]等人提出了一種用于分層制造的切片輪廓處理的容錯(cuò)切片算法,該算法旨在克服計(jì)算機(jī)內(nèi)存的限制和傳統(tǒng)切片方法所固有的計(jì)算不穩(wěn)定性。Brown[7]等人運(yùn)用切片算法實(shí)現(xiàn)了能夠處理和切割一個(gè)或多個(gè)STL 文件。
在此,針對(duì)上述研究成果的不足及可行之處,并結(jié)合某機(jī)械加工企業(yè)的實(shí)際需求,提出一種基于WPF 的STL 系統(tǒng)可視化設(shè)計(jì)方案,通過建立WPF模型數(shù)據(jù),對(duì)直接導(dǎo)入的STL 文件模型進(jìn)行轉(zhuǎn)化,對(duì)模型頂點(diǎn)、邊、以及三角片面進(jìn)行拓?fù)潢P(guān)系建立,生成三維模型,從而確定模型特征,在此基礎(chǔ)上,利用WPF 的3D 顯示模塊將三維模型顯示出來,進(jìn)而實(shí)現(xiàn)STL 文件對(duì)應(yīng)模型的旋轉(zhuǎn)、縮放、平移等人機(jī)交互功能。
系統(tǒng)主要由STL 文件分析處理、算法研究實(shí)現(xiàn)、人機(jī)交互三個(gè)主要功能組成。
研究STL 文件格式,分析不同格式間的共同性,對(duì)STL 文件進(jìn)行結(jié)構(gòu)分析,探究其更合適的拓?fù)潢P(guān)系。
針對(duì)對(duì)STL 文件的分析,設(shè)計(jì)STL 文件的讀取儲(chǔ)存方式,給出STL 文件可視化實(shí)現(xiàn)算法流程圖。
首先利用WPF 的3D 模塊搭建可顯示3D 效果的場(chǎng)景,然后利用給出的算法處理STL 文件,在3D場(chǎng)景中顯示,最后針對(duì)可視化的模型進(jìn)行可操作化設(shè)計(jì)。
系統(tǒng)整體結(jié)構(gòu)圖如圖1所示。
圖1 系統(tǒng)整體結(jié)構(gòu)圖
STL 格式文件以三角形面為單位記錄了每個(gè)三角形的簡(jiǎn)單幾何信息,每個(gè)三角形面都包含該三角形所在平面的法向矢量以及三角形的三個(gè)頂點(diǎn)坐標(biāo)。目前為止,STL 文件有文本(ASCII)和二進(jìn)制(BINARY)兩種格式[8]。
ASCII 格式的STL 文件逐行給出三角形面片的幾何信息,每一行由1 個(gè)或2 個(gè)關(guān)鍵字開頭。在STL文件中一個(gè)帶矢量方向的三角形面片是由三角形面片的信息單元facet 來表述的,每一個(gè)facet 由7 行數(shù)據(jù)組成。
關(guān)鍵字facet normal 后面給出三個(gè)數(shù)是三角面指向?qū)嶓w外部的法向矢量坐標(biāo);
outer loop 隨后的3 行數(shù)據(jù)分別是三角面的3個(gè)頂點(diǎn)坐標(biāo);
end loop 表示完成三角形面片的3 個(gè)頂點(diǎn)坐標(biāo)定義;
end facet 表示完成一個(gè)三角形面片定義;
end solid 表示整個(gè)STL 文件定義結(jié)束,由若干個(gè)三角形面片的信息單元facet 構(gòu)成整個(gè)STL 文件格式模型,3 個(gè)頂點(diǎn)沿指向?qū)嶓w外部的法矢方向逆時(shí)針排列。
二進(jìn)制STL 文件用固定的字節(jié)數(shù)來給出三角面片的幾何信息。
文件起始的80 個(gè)字節(jié)是文件頭,用于存貯文件名,緊接著用4 個(gè)字節(jié)的整數(shù)來描述模型的三角面片總數(shù),后面逐個(gè)給出每個(gè)三角面片的幾何信息。每個(gè)三角形面片占用固定的50 個(gè)字節(jié),依次是:
3 個(gè)4 字節(jié)浮點(diǎn)數(shù),表示三角面法矢量;
3 個(gè)4 字節(jié)浮點(diǎn)數(shù),表示三角面片第一個(gè)頂點(diǎn)坐標(biāo);
3 個(gè)4 字節(jié)浮點(diǎn)數(shù),表示三角面片第二個(gè)頂點(diǎn)坐標(biāo);
3 個(gè)4 字節(jié)浮點(diǎn)數(shù),表示三角面片第三個(gè)頂點(diǎn)坐標(biāo);
最后2 個(gè)字節(jié)為預(yù)留字,一般表示屬性特征。
一個(gè)完整的二進(jìn)制STL 文件的大小為三角面的個(gè)數(shù)乘以50 再加上84 個(gè)字節(jié)。
其實(shí)不管何種的格式的STL 文件,一個(gè)基本的三角片中,都包括了三角片的法向量normal 以及三個(gè)頂點(diǎn)的三維坐標(biāo)vertex 等信息。憑借這些信息都可以唯一確定一個(gè)三角片,進(jìn)而確定完整的三維曲面模型。為更好分析STL 文件結(jié)構(gòu),以下給出部分STL 文件結(jié)構(gòu)圖,如圖2所示。
圖2 STL 文件局部結(jié)構(gòu)示意圖
根據(jù)圖2所示,假設(shè)頂點(diǎn)所對(duì)應(yīng)的邊以及邊的兩個(gè)相鄰的邊為鄰接邊,那么在三角形ABC 中,點(diǎn)A 的鄰接邊是a,邊a 在該三角形中的鄰接邊分別為邊b 和邊c。但是這只是一個(gè)三角形的頂點(diǎn)以及鄰接邊信息,STL 文件所表示的是n 個(gè)三角片的信息,其中會(huì)有很多相同的頂點(diǎn)以及鄰接邊。經(jīng)過觀察可以得到一個(gè)頂點(diǎn)最多可以達(dá)到6 個(gè)鄰接邊,最少有4 個(gè)。而邊的鄰接邊最多可以有4 個(gè)鄰接邊,最少2 個(gè)。由此可見,若只是簡(jiǎn)單地減少冗余量提升打開文件的速度,直接處理點(diǎn)的冗余就可以實(shí)現(xiàn),但是如果要進(jìn)行后續(xù)的操作,邊的信息也是非常重要的一部分,例如后續(xù)在線建模和NC 代碼自動(dòng)生成等。故此不能只處理點(diǎn)的冗余,也須處理邊的冗余,然后建立點(diǎn)與鄰接邊、邊與鄰接邊的拓?fù)潢P(guān)系。
儲(chǔ)存STL 文件信息時(shí),并不能簡(jiǎn)單地儲(chǔ)存點(diǎn)、邊以及三角片的信息,還需要儲(chǔ)存它們各自的鄰接邊信息。通過研究還可發(fā)現(xiàn),雖然每三個(gè)頂點(diǎn)可以確定唯一的三角片,但是不同的三角片有可能用到相同的頂點(diǎn)以及相同的鄰接邊,這樣就極大地浪費(fèi)了儲(chǔ)存空間以及處理速度。所以為了存取方便,避免點(diǎn)和邊的重復(fù)存取,設(shè)計(jì)給每個(gè)點(diǎn)和邊一個(gè)專用的ID號(hào),依據(jù)讀取的順序,設(shè)計(jì)點(diǎn)和邊的ID 號(hào)從0 開始依次遞增。這樣就便于在存取的過程中同時(shí)也可以剔除重復(fù)的頂點(diǎn)和邊信息,進(jìn)而能夠大幅度提高存取效率,節(jié)省儲(chǔ)存空間及讀取時(shí)間。
為此,需要建立三個(gè)容器分別來儲(chǔ)存頂點(diǎn)、邊和三角片的數(shù)據(jù)集合。三維頂點(diǎn)的屬性包含頂點(diǎn)的三維坐標(biāo),以及頂點(diǎn)的鄰接邊和頂點(diǎn)的專用ID;邊的屬性包含邊的位置信息(兩個(gè)頂點(diǎn))、邊的鄰接邊的序號(hào)的集合以及邊的ID 號(hào);三角片容器屬性包含三角形的頂點(diǎn)、邊和法矢量信息。容器結(jié)構(gòu)示意圖如圖3所示。
圖3 容器結(jié)構(gòu)示意圖
憑借頂點(diǎn)和邊的鄰接關(guān)系,完全可以確定網(wǎng)格模型各三角面片之間的連接關(guān)系。由一個(gè)頂點(diǎn)出發(fā),可根據(jù)其鄰接邊獲取包含該頂點(diǎn)的所有三角形;由產(chǎn)生的鄰接邊,可分別獲取它們自身的鄰接邊組合。如此循環(huán)擴(kuò)展,直到擴(kuò)展到整個(gè)網(wǎng)格模型為止。然后把STL 文件中的三角片的法矢量信息儲(chǔ)存到建立的三角片容器中,這樣由以上三個(gè)容器的建立就可以獲取STL 文件中的所有信息并建立起基本圖元之間的鄰接關(guān)系。簡(jiǎn)易的演示過程如圖4所示。
圖4 三角片拓展關(guān)系演示圖
參考圖2的設(shè)定,具體算法流程可如圖5所示。
圖5 STL 可視化算法流程圖
如圖,假設(shè)先讀取三角片ABC,首先讀取三角片三個(gè)頂點(diǎn)的信息,然后按照上述建立的鄰接邊關(guān)系,分別將三角片ABC 的頂點(diǎn)信息儲(chǔ)存到頂點(diǎn)容器中,設(shè)置點(diǎn)信息ID 號(hào)以及點(diǎn)對(duì)應(yīng)的鄰接邊ID 號(hào);然后把邊的信息儲(chǔ)存到邊容器中,設(shè)置邊信息ID 號(hào)以及邊所對(duì)應(yīng)的鄰接邊ID 號(hào);最后在三角片容器中儲(chǔ)存三角片三個(gè)頂點(diǎn)ID 以及法矢量信息。接下來讀取三角片BDC,首先判斷三角片BDC 的三個(gè)頂點(diǎn)以及邊是否被處理(判斷依據(jù)是用頂點(diǎn)的三維坐標(biāo)值與已儲(chǔ)存在容器中的三維坐標(biāo)值相比較),若被處理,將不再處理此信息不同的保留作為下一個(gè)處理頂點(diǎn),然后將欲處理的點(diǎn)邊信息分別儲(chǔ)存到對(duì)應(yīng)的容器中,且添加鄰接邊關(guān)系。往后的三角片按照上述方法處理,直到達(dá)到文件的末尾位置為止。
對(duì)可視化模型進(jìn)行操作化設(shè)計(jì),可直觀地看出所打開的STL 文件是否有缺陷,并為實(shí)現(xiàn)后續(xù)在線建模提供操作基礎(chǔ)。目前大多數(shù)研究者利用C++語言跟OpenGL 或者3ds Max 結(jié)合實(shí)現(xiàn)3D 模型顯示功能,但此方法實(shí)際操作性復(fù)雜。在此利用XAML技術(shù)WPF 框架來實(shí)現(xiàn)系統(tǒng)3D 模型顯示功能。XAML 技術(shù)提供了一種便于擴(kuò)展和定位的語法來定義與程序邏輯相分離的用戶界面,XAML 中界面表現(xiàn)和邏輯功能的分離使得界面開發(fā)和功能開發(fā)代碼分離,有利于開發(fā)團(tuán)隊(duì)的合理分工,提高了開發(fā)效率。WPF 技術(shù)主要是用來實(shí)現(xiàn)3D 效果,使用WPF實(shí)現(xiàn)3D 顯示只需要設(shè)置好3D 場(chǎng)景,然后將需要打開的STL 文件經(jīng)過算法處理就可以直接顯示。利用C#語言除了因?yàn)槠渑cWPF 可以組合實(shí)現(xiàn)外,還可以避免C++語言中存在的bug。
3D 環(huán)境搭建首先需要在XAML 板塊中編寫一個(gè)Viewport3D 模塊,用來顯示打開處理的STL 文件,然后在后臺(tái)程序當(dāng)中初始化顯示3D 模型的必要元素:攝像機(jī)(Camera)、光源(Light)、模型(Model)。
設(shè)置好這些3D 環(huán)境所需要的固定屬性,就可以去處理STL 文件來顯示STL 文件里面所儲(chǔ)存的3D 模型。主要步驟如下:
1)在編寫的系統(tǒng)3D 模塊中加入3DTools 工具;
2)建立世界坐標(biāo);
3)利用上文算法處理STL 文件:
①構(gòu)建頂點(diǎn)容器,儲(chǔ)存頂點(diǎn)的三維坐標(biāo)x、y、z,以及頂點(diǎn)的鄰接邊和頂點(diǎn)的專用ID;
②構(gòu)建鄰接邊容器,儲(chǔ)存邊的位置信息(兩個(gè)頂點(diǎn))、邊的鄰接邊的序號(hào)的集合以及邊的ID 號(hào);
③構(gòu)建三角片容器,儲(chǔ)存三角形的頂點(diǎn)、邊和法矢量信息;
④利用鄰接邊信息進(jìn)行三維模型拓展;
⑤定義表面材質(zhì)(設(shè)置Material 屬性);
最終,通過調(diào)用處理后的STL 文件,就可在系統(tǒng)中的3D 顯示區(qū)域?qū)崿F(xiàn)STL 模型的可視化??梢暬Ч故救鐖D6所示。
圖6 STL 文件可視化展示圖
主要設(shè)計(jì)旋轉(zhuǎn)、縮放、平移等三大功能。這些可通過操作模型的變化來實(shí)現(xiàn),也可通過操作Camera來實(shí)現(xiàn)。操作模型時(shí)需要變化模型的全部坐標(biāo)以及更新,而操作Camera 時(shí)只需要變化Camera 的坐標(biāo)信息,故實(shí)現(xiàn)三大功能全部用操作Camera 來實(shí)現(xiàn)。
當(dāng)操作Camera 時(shí),首先需要獲得Camera 的初始位置以及模型的中心位置,然后需要設(shè)置每個(gè)功能的計(jì)算公式以及獲取的變化變量,這樣就可以得到新的Camera 坐標(biāo)位置,以此實(shí)現(xiàn)操作功能。
1)模型中心位置獲取
在WPF 的MeshGeometry3D 中,有一個(gè) Bounds屬性,該屬性的功能是返回MesheGeometry3D 的邊界Rect3D。Rect3D 表示一個(gè)三維矩形,也就是模型的外切矩形。由此信息可以得到外切矩形的三條邊長(zhǎng)分別為SizeX、SizeY、SizeZ,并且可以得到模型的中心位置(SizeX,SizeY,SizeZ),同時(shí)可以計(jì)算外切圓半徑,計(jì)算公式為:
通過初始設(shè)置時(shí)可以得到Camera 最初的坐標(biāo)位置為(x0,y0,z0),這樣可以得到Camera 到模型中心距離為a,其計(jì)算公式為:
2)旋轉(zhuǎn)功能設(shè)計(jì)
旋轉(zhuǎn)功能除了中心位置的獲取,還需要旋轉(zhuǎn)半徑及旋轉(zhuǎn)角度。旋轉(zhuǎn)角度可通過鼠標(biāo)的控制來獲取。旋轉(zhuǎn)半徑首先比較a 與r 的大小,當(dāng)a 大于r 時(shí)選取a 為旋轉(zhuǎn)半徑,否則選r。此舉主要是為防止Camera 旋轉(zhuǎn)時(shí)進(jìn)入模型內(nèi)部出錯(cuò)。
3)縮放功能設(shè)計(jì)
采取向量比例的算法來實(shí)現(xiàn)模型縮放功能,根據(jù)鼠標(biāo)轉(zhuǎn)輪采集的縮放信息進(jìn)行縮放。設(shè)縮放大小為d,縮放后新的Camera 位置可如下式計(jì)算得到:
4)平移功能設(shè)計(jì)
通過計(jì)算模型中心位置與期望移動(dòng)位置的偏差,來確定新的Camera 位置坐標(biāo),實(shí)現(xiàn)模型的平移功能。
為測(cè)試上述構(gòu)建的方法及所開發(fā)系統(tǒng)的有效性,選用某企業(yè)實(shí)際加工中的一些STL 文件,分別對(duì)期文本和二進(jìn)制兩種格式的STL 文件進(jìn)行測(cè)試。結(jié)果表明,系統(tǒng)實(shí)現(xiàn)了兩種STL 格式的可視化,并且可以通過人機(jī)交互實(shí)現(xiàn)模型的旋轉(zhuǎn)、縮放、平移。系統(tǒng)操作簡(jiǎn)單、反應(yīng)速度快。具體測(cè)試效果如圖7。
圖7 實(shí)際測(cè)試效果展示圖
采用WPF 框架以及XAML 技術(shù)的設(shè)計(jì)方案,優(yōu)化了系統(tǒng)實(shí)現(xiàn)的簡(jiǎn)約性,實(shí)現(xiàn)了對(duì)STL 文件的可視化,也實(shí)現(xiàn)了對(duì)可視化STL 文件進(jìn)行操作的功能。用鄰接邊作為STL 文件快速拓展的依據(jù),極大減少了STL 信息的冗余量,提高了可視化速度,為后續(xù)研究中進(jìn)一步處理可視化的STL 模型提供了信息基礎(chǔ)。