《電子技術(shù)應(yīng)用》
您所在的位置:首頁 > 嵌入式技術(shù) > 設(shè)計應(yīng)用 > 基于半邊結(jié)構(gòu)的STL文件快速拓?fù)渌惴?/span>
基于半邊結(jié)構(gòu)的STL文件快速拓?fù)渌惴?
2020年電子技術(shù)應(yīng)用第1期
武小超,陳 鴻
中北大學(xué) 儀器與電子學(xué)院,山西 太原030051
摘要: 針對三維模型轉(zhuǎn)換為STL文件后會丟失三角面間的拓?fù)潢P(guān)系,在對STL格式文件進(jìn)行讀取和分析時,提出了一種基于半邊結(jié)構(gòu)和哈希表的快速拓?fù)渲貥?gòu)算法。在讀取數(shù)據(jù)過程中,通過哈希表建立無重復(fù)位置信息的點表,并在其中維護(hù)一個未添加鄰接面的半邊集合。依據(jù)該集合和拓?fù)渌惴ㄍ晟泼娴耐負(fù)潢P(guān)系,實現(xiàn)在讀取數(shù)據(jù)的過程中快速建立面的拓?fù)潢P(guān)系。
中圖分類號: TN06;P301.6
文獻(xiàn)標(biāo)識碼: A
DOI:10.16157/j.issn.0258-7998.190962
中文引用格式: 武小超,陳鴻. 基于半邊結(jié)構(gòu)的STL文件快速拓?fù)渌惴╗J].電子技術(shù)應(yīng)用,2020,46(1):92-95,99.
英文引用格式: Wu Xiaochao,Chen Hong. Fast topology algorithm for STL files based on half-edges structure[J]. Application of Electronic Technique,2020,46(1):92-95,99.
Fast topology algorithm for STL files based on half-edges structure
Wu Xiaochao,Chen Hong
School of Instrument and Electronics,North University of China,Taiyuan 030051,China
Abstract: In order to solve the problem that the topological relationship between the triangular facets is lost when the 3D model is converted to STL files,in the process of reading and analyzing STL files, a fast topology reconstruction algorithm based on half-edges structure and hash table is proposed. In the process of reading data, a point table without repeat position information is established through a hash table, and a collection containing half-edges in which no adjacency facets are added is maintained therein. According to the set and topology algorithm, the topological relationship of the facets is improved, and the topological relationship of the facets is quickly established in the process of reading data.
Key words : STL file;half-edges structure;hash table;topology algorithm

0 引言

    自3D打印技術(shù)問世之后,憑借其復(fù)雜性低、成本低廉、軟件開源、易于推廣等特點在國內(nèi)外得到了迅速的發(fā)展[1]。STL(Stereo Lithography)文件是由美國3D System公司于1987年制定的接口協(xié)議,由于其格式簡單、讀寫便利,成為3D打印過程中最常用的數(shù)據(jù)存儲格式[2]。STL文件由離散的三角面片組成,存放了模型的點云的位置信息和三角面片的法向量,但其丟失了面與面之間的拓?fù)潢P(guān)系,同時,單個點被多次記錄,造成了大量的數(shù)據(jù)冗余[3]。在快速成型過程中,待支撐位置查詢、模型分層切片等操作均需要三角面間的拓?fù)潢P(guān)系[4],因此,建立合理的數(shù)據(jù)結(jié)構(gòu)剔除冗余信息,采用高效的算法建立拓?fù)潢P(guān)系就顯得尤為重要。

    針對STL文件讀寫的局限,國內(nèi)外專家提出多種解決方案。侯聰聰?shù)?sup>[5]提出基于鏈表的數(shù)據(jù)存儲和拓?fù)浣Y(jié)構(gòu),建立點、邊、面表進(jìn)行數(shù)據(jù)存儲,雖剔除了STL文件中的重復(fù)點,但每次建立拓?fù)潢P(guān)系時,均對整個邊表進(jìn)行遍歷,算法性能較低;王增波[6]采用哈希表作為基礎(chǔ)結(jié)構(gòu),將有效數(shù)據(jù)僅保存一次,提升了數(shù)據(jù)的添加和查找速度,幾乎可以在常數(shù)時間內(nèi)快速完成,但建立拓?fù)潢P(guān)系時,依舊是對已存數(shù)據(jù)進(jìn)行遍歷,不僅效率較低,還存在部分?jǐn)?shù)據(jù)查找遺漏的現(xiàn)象;王彥云等[7]優(yōu)化了哈希表的沖突解決方案,采用二分查找的方法對相同key值的鏈表進(jìn)行查找,提升了查表速度,但拓?fù)渌惴?/a>效率依舊較低;錢乘等[8]也采用哈希表進(jìn)行數(shù)據(jù)存儲,存儲數(shù)據(jù)的同時對每個點記錄其所屬三角面片,全部存儲完畢后,再對所有面片進(jìn)行遍歷,建立拓?fù)潢P(guān)系,不存在遺漏,但讀取完成后,需要再次遍歷面表尋找鄰接面;張應(yīng)中等[9]利用半邊結(jié)構(gòu)進(jìn)行拓?fù)潢P(guān)系建立,巧妙地將點與面的信息存入邊,利用三角面中頂點的存放順序來保存邊的信息,精簡了存儲結(jié)構(gòu),但拓?fù)渌惴◤?fù)雜,并且需要在讀入全部頂點的情況下建立拓?fù)潢P(guān)系。

    基于以上算法的研究,本文提出一種基于哈希表的、利用半邊結(jié)構(gòu)的數(shù)據(jù)存儲和三角面拓?fù)渌惴?,在讀取數(shù)據(jù)過程中,一方面剔除冗余數(shù)據(jù),一方面快速建立面的拓?fù)潢P(guān)系,每讀入一個三角面信息,進(jìn)行數(shù)據(jù)存放的同時,在點表中維護(hù)一個未添加鄰接面的半邊集合。當(dāng)數(shù)據(jù)讀取完成后,建立無重復(fù)數(shù)據(jù)的點表和面表,完善三角面間的拓?fù)潢P(guān)系。

1 STL文件

    STL格式文件分為ASCII碼和二進(jìn)制兩種,其中,二進(jìn)制格式的文件數(shù)據(jù)結(jié)構(gòu)如圖1所示,與ASCII相比存儲更加緊湊,占用空間較小,會在文件起始位置記錄三角面片總數(shù)Num,在后續(xù)建立哈希表時也能依據(jù)此選擇更加合適的表長。

jsj1-t1.gif

    由歐拉公式可知,存儲正確的三角網(wǎng)格文件,三角面的數(shù)量約為頂點的2倍[10],而在STL文件中,每存儲一次面片信息,都會重復(fù)存儲3個點的位置坐標(biāo),使得存的儲頂點數(shù)量是面片數(shù)量的3倍[11]。由此可得,每個頂點在STL文件中平均記錄了6次,所以在進(jìn)行拓?fù)潢P(guān)系建立前,需要先對冗余信息進(jìn)行辨別和剔除,使每個頂點僅存儲一次,減少數(shù)據(jù)存儲量,提升算法效率。

2 采用半邊結(jié)構(gòu)的拓?fù)鋽?shù)據(jù)結(jié)構(gòu)

2.1 半邊的二元組表示

    本文采用文獻(xiàn)[9]提出的精簡半邊結(jié)構(gòu)作為基礎(chǔ),使用三角面的標(biāo)志和半邊在面中的序號來表示半邊。如圖2所示,頂點A、B、C、A按照逆時針順序連線構(gòu)成面M1;頂點D、A、C、D連線構(gòu)成面M2,半邊L2可以表示為[M1,2],即M1面中的第2條半邊,半邊L6可以表示為[M2,3],即M2面中的第3條半邊。

jsj1-t2.gif

    當(dāng)兩個半邊頂點相同且邊的起點與終點相互調(diào)換時,兩半邊互為反向半邊,這時,兩半邊所屬三角面互為鄰接面。如圖2所示,L3和L5為反向半邊,M1與M2為鄰接三角面。使用二元法表示半邊可以精簡高效地建立點、邊、面的關(guān)系,當(dāng)兩半邊為反向半邊時,可立即得到該半邊所在面,從而建立面的拓?fù)潢P(guān)系。

2.2 拓?fù)鋽?shù)據(jù)結(jié)構(gòu)

    基于STL文件的特點和半邊二元組的表示,綜合考慮空間和效率需求,本文提出如下的基于半邊結(jié)構(gòu)的三角面拓?fù)鋽?shù)據(jù)結(jié)構(gòu)。如圖3所示,STL文件的幾何信息通過頂點和三角面描述,半邊信息定義在頂點類中,使用鍵值對存入Map容器中;臨接面信息通過在三角面類中定義一個包含3個元素的數(shù)組對其進(jìn)行存儲。

jsj1-t3.gif

    (1)頂點類(Class Vertex)。頂點數(shù)據(jù)包括頂點位置坐標(biāo)和一個用來存儲半邊信息的Map容器。該Map容器以紅黑樹為底層,存放以該頂點為起點的半邊,半邊信息通過將上文中的二元組轉(zhuǎn)化為鍵值對進(jìn)行存儲。使用紅黑樹作為底層數(shù)據(jù)結(jié)構(gòu),可以避免使用連續(xù)內(nèi)存,并將以該點為起點的半邊信息全部保存,其搜索時間復(fù)雜度為O(lgn),在增加刪除半邊時,不會對頂點存放的Hash表產(chǎn)生額外影響,同時仍具有較快的速度。

    (2)三角面類(Class Mesh)。面數(shù)據(jù)包含3個指向頂點的指針, 采用一維數(shù)組存放,指針存儲順序同時隱性包含了半邊順序,即:頂點V1與V2形成序號為1的半邊,頂點V2與V3形成序號為2的半邊,頂點V3與V1形成序號為3的半邊;此外,將法向量坐標(biāo)存入normal_vector數(shù)組,面片的3個臨接面存入border_meshs數(shù)組。

2.3 點表和面表

    存儲頂點數(shù)據(jù)時,需要快速判斷該頂點是否已經(jīng)保存,鑒于哈希表查找時較低的時間復(fù)雜度,采用哈希表對頂點數(shù)據(jù)進(jìn)行保存。本文哈希函數(shù)如下:

     jsj1-gs1-2.gif

其中,x、y、z為頂點坐標(biāo)的3個分量值,m為哈希表的長度,h(k)為計算出的哈希地址。由于STL文件數(shù)據(jù)精度較高,使得各點的值較為接近,因此對k進(jìn)行一定程度放大。STL文件滿足歐拉關(guān)系,即三角網(wǎng)格模型的頂點總數(shù)是其總?cè)敲嫫瑪?shù)的1/2,所以m取值為與Num/2最接近的素數(shù),以減少散列地址的沖突。存儲頂點的哈希表如圖4所示。

jsj1-t4.gif

    因為面數(shù)據(jù)不存在重復(fù),所以直接使用面對象數(shù)組作為面表,一方面可以在O(1)的時間復(fù)雜度內(nèi)找到對應(yīng)面片,修改面片信息;另一方面,將數(shù)組的下標(biāo)加1,便可作為面片的標(biāo)志,可以快速定位半邊位置。

3 STL文件拓?fù)湫畔⒅亟鞒?/strong>

3.1 冗余信息剔除

    當(dāng)開始進(jìn)行STL文件讀取后,會依次讀入所有三角面片的頂點和法向量信息,法向量信息待3個點均讀入后存入面對象,將頂點的3個坐標(biāo)帶入式(1)、式(2),計算得到哈希地址,即該點存入點表的位置,而后分為以下兩種情況:

    (1)若該地址內(nèi)沒有數(shù)據(jù),說明該點首次出現(xiàn),依據(jù)該點所在的三角面片的序號和點在面中的位置構(gòu)建半邊,并將其以鍵值對的形式存入點的half-edges,便完成新點添加。例如,依次讀入第4個面片的3個頂點V1、V2、V3,由于V2是第2個讀入的點,則構(gòu)建二元組為[4,2],即第4個面片中的第2個半邊,半邊方向由V2指向V3。

    (2)若該地址存在數(shù)據(jù),由于不相同的兩點也可能計算出相同的哈希地址,因此需要對比新添加的頂點坐標(biāo)和已存頂點的坐標(biāo)是否相同。若相同,則說明該點為重復(fù)的舊點,不需要進(jìn)行添加,進(jìn)行下一個點的處理;若不同,則該點為新點,同樣構(gòu)建并添加半邊信息后,鏈?zhǔn)教砑狱c解決沖突。例如:讀入新點V1,計算得到哈希地址為2,但發(fā)現(xiàn)該地址已經(jīng)存在頂點數(shù)據(jù)且與V1不同,則需要在該地址處添加指向新點的指針,形成鏈表來解決哈希地址沖突。

3.2 添加三角面并生成拓?fù)湫畔?/strong>

    依次讀取并存儲3個頂點信息后,依據(jù)讀取的三角面的序號,更新面表內(nèi)所對應(yīng)面的頂點和法向量信息,即vertex數(shù)組和 normal_vector數(shù)組。第一個面片讀取完成后,點表中的半邊信息如圖5所示,點A、B、C所存半邊信息依次為[1,1]、[1,2]、[1,3],即AB、BC、CA半邊,此時border_meshs數(shù)組內(nèi)暫無鄰接面信息。

jsj1-t5.gif

    后續(xù)繼續(xù)添加面片信息時存在多種情況,以下分別討論:

    (1)新面片的3個頂點與現(xiàn)存頂點均不相同。即3頂點均為第一次讀取,構(gòu)建面數(shù)據(jù)并將其加入面表后,半邊信息如圖6所示,其中(A,B,C)為已存面,(D,E,F(xiàn))為新添加面,所有點目前僅保存一個半邊,所有面不存在鄰接面。

jsj1-t6.gif

    (2)新面片的3個頂點與現(xiàn)存頂點有一個相同,構(gòu)建面數(shù)據(jù)并將其加入面表后,半邊信息如圖7(a)所示,其中(A,B,C)為已存面,(D,C,E)為新添加面,由于點C不是首次讀取,因此點中已經(jīng)存有指向點A的半邊,需將C指向點E的半邊也存入其中,即構(gòu)建[2,2]半邊存入點C的half-edges,此時點C中存有兩個半邊信息,添加后的半邊信息如圖7(b)所示。此時點C中存有兩個半邊信息,兩個已存面均無鄰接面信息。

jsj1-t7.gif

    (3)新面片的3個頂點與現(xiàn)存頂點有兩個相同,此時又可分為兩種情況,新添加面均為(D,A,C)。①情況1如圖8(a)所示,A、C兩點為已存點,由于C點已存半邊CE與AC半邊不是反向半邊,因此兩面不是鄰接面,構(gòu)建AC、CD兩半邊分別存入點A、C中即可,此時A、C、E 3點均存有兩個半邊信息;②情況2如圖8(b)所示,A、C兩點為已存點,由于C點包含指向A點的半邊CA,與新添加面中的AC半邊互為反向半邊,說明兩三角面互為鄰接面,向面(A,B,C)的border_meshs數(shù)組中添加序號2,向面(D,A,C)的border_meshs數(shù)組中添加半邊CA所在面序號1,而后刪除點C中的半邊CA并添加半邊CD,即half-edges刪除[1,3],添加[2,3],便完成了新面的添加和拓?fù)潢P(guān)系的建立,此時兩面均存在一個鄰接面,所有點均包含一個半邊。

jsj1-t8.gif

    (4)新面片的3個頂點與現(xiàn)存頂點均相同,此時又可以又可分為4種情況,新加入的面均為(D,A,C)。①情況1如圖9(a)所示,不存在新的鄰接邊,將D、A、C 3點均添加新的半邊即可;②情況2如圖9(b)所示,有一條新的鄰接邊,添加DA、CD半邊,刪除CA半邊,并在兩面中添加鄰接面即可;③情況3如圖9(c)所示,有兩條新的鄰接邊,添加DA半邊,將CA、DC半邊刪除,并完善鄰接面信息;④情況4如圖9(d)所示,3條邊均為新的鄰接邊,將AD、DC、CA半邊刪除,完善面的鄰接信息后即完成面的添加和鄰接拓?fù)湫畔?gòu)建。

jsj1-t9.gif

    綜上,面片的添加與拓補過程與重合點數(shù)量相關(guān)需分情況討論。若不存在舊點,則默認(rèn)構(gòu)建即可;若存在一個,給該點添加新的半邊;若存在兩個以上,3點按讀入順序,每兩點組成一個新半邊,依次判斷3個半邊的半邊,即是否存在新的鄰接面。若不存在,則為半邊的起點添加新半邊;若存在,則在面表內(nèi)添加新的鄰接面,并刪除起點的原有半邊。注意,若3點中僅有兩點為已存點,則需要為刪除半邊的點添加新的、基于新添加面片的半邊(如圖8(b)所示)。整個拓?fù)淞鞒倘鐖D10所示。

jsj1-t10.gif

4 測試實例及性能分析

    將上述數(shù)據(jù)結(jié)構(gòu)和快速拓?fù)渌惴ㄍㄟ^OpenGL和Qt Creator編程實現(xiàn),同時,使用文獻(xiàn)[8]中的拓?fù)渌惴ㄅc本文的算法對5個STL模型進(jìn)行拓?fù)渲亟▽嶒?,實驗環(huán)境為Windows 10操作系統(tǒng),處理器主頻為2.6 GHz,4.0 GB內(nèi)存,獲得同一個STL模型在兩種算法下的拓?fù)潢P(guān)系構(gòu)建時間。表1為兩種算法運行時間對比。

jsj1-b1.gif

    由于本文算法在進(jìn)行STL文件存儲的同時便完成了面片拓?fù)潢P(guān)系的建立,相比于文獻(xiàn)[8]的算法,不需要存儲數(shù)據(jù)后再對面表遍歷并進(jìn)行大量比對尋找鄰接面,節(jié)省了大量的時間,從測試結(jié)果中也可看出本算法具有更高的效率。

5 結(jié)論

    本文提出半邊結(jié)構(gòu)的快速拓?fù)渌惴ǎ瑢脒呅畔⒁枣I值對的形式存入點中,每讀入一個面片,存儲數(shù)據(jù)的同時,以較快的效率更新未添加鄰接面的半邊集合和面表中的鄰接面數(shù)組,STL模型讀取完畢后,面的拓?fù)湫畔⒁餐瑫r完善,有效縮短了面片拓?fù)潢P(guān)系建立的時間,為模型后續(xù)的支撐添加和切片處理帶來了極大的便利。

參考文獻(xiàn)

[1] 宋廷強,邢照合.一種彩色FDM型3D打印機的設(shè)計與實現(xiàn)[J].電子技術(shù)應(yīng)用,2017,43(4):69-71,75.

[2] 楊晟院,陳瑤,易飛,等.基于2維流形的STL曲面網(wǎng)格重建算法[J].軟件學(xué)報,2017,28(12):3358-3366.

[3] 王彥云,陳鴻,謝明師,等.FDM快速成型支撐結(jié)構(gòu)自動生成算法的研究[J].電子技術(shù)應(yīng)用,2015,41(8):146-148.

[4] 徐敬華,盛紅升,張樹有,等.基于鄰接拓?fù)涞牧餍尉W(wǎng)格模型層切多連通域構(gòu)建方法[J].計算機輔助設(shè)計與圖形學(xué)學(xué)報,2018,30(1):180-190.

[5] 侯聰聰,南琳,張磊.基于分組的STL模型快速切片算法[J].制造業(yè)自動化,2014,36(9):12-15.

[6] 王增波.STL格式文件的快速拓?fù)渲亟ㄋ惴╗J].計算機應(yīng)用,2014,34(9):2720-2724.

[7] 王彥云,陳鴻,謝明師,等.基于哈希表的STL格式文件拓?fù)渲亟ǖ乃惴╗J].現(xiàn)代制造工程,2015(12):61-64.

[8] 錢乘,李震,江本赤,等.基于哈希表的STL文件拓?fù)潢P(guān)系快速重建算法[J].新鄉(xiāng)學(xué)院學(xué)報,2018,35(6):36-39,51.

[9] 張應(yīng)中,謝馥香,羅曉芳,等.采用半邊編碼的三角網(wǎng)格拓?fù)鋽?shù)據(jù)結(jié)構(gòu)[J].計算機輔助設(shè)計與圖形學(xué)學(xué)報,2016,28(2):328-334.

[10] BOTSCH M,KOBBELT L,PAULY M,et al.Polygon mesh processing[M].Natick:A K Peters,2010:1-2.

[11] 謝馥香.面向三角網(wǎng)格分割體的設(shè)計特征重構(gòu)[D].大連:大連理工大學(xué),2015.




作者信息:

武小超,陳  鴻

(中北大學(xué) 儀器與電子學(xué)院,山西 太原030051)

此內(nèi)容為AET網(wǎng)站原創(chuàng),未經(jīng)授權(quán)禁止轉(zhuǎn)載。