本發(fā)明屬于計算機圖形學領域,尤其涉及一種基于vtk處理obj文件的方法。
背景技術:
三維模型是物體的多邊形表示,通常用計算機或者其它視頻設備進行顯示。顯示的物體可以是現(xiàn)實世界的實體,也可以是虛構的物體。任何物理自然界存在的東西都可以用三維模型表示。
對于表情光滑的物體,所需要的多邊形數(shù)量就越多,如果數(shù)量不足就會使得構建處理的三維模型不夠平滑,此時就需要應用曲面細分算法來自動的增加面片數(shù)量,使得模型平滑,然而曲面細分算法所要求的輸入面面是連續(xù)的,離散面片構造的曲面直接應用細分算法將會產(chǎn)生很多空洞。對于多邊形的頂點,可能會對于多個紋理坐標,然而在vtk(視覺化工具函式庫,Visualization Toolkit)中一個頂點id(身份證,identification)只能與一個紋理坐標id相對應,這就使得一個頂點不夠用,需要增加新的位置一樣的。
技術實現(xiàn)要素:
發(fā)明目的:對于紋理坐標不一樣的頂點,為了應用曲面細分算法,還要保證面片之間的連通性,本發(fā)明提出了一個在不改變模型的基礎上,合理增加面片以保證所有面片是連通的方法。
針對vtk內置類vtkObjReader(vtk工具庫自帶的.obj格式文件處理類)存在不足的情況下,本發(fā)明提供了一種處理obj文件的方法。
本發(fā)明具體包括如下步驟:
步驟1:面片讀取。讀取obj文件三維模型里的面片,構造倒排索引表。
步驟2:尋找共享頂點:面片頂點的標識符為<頂點id,紋理坐標k>,id表示頂點的標識號,由于一個頂點對應著多個紋理坐標(三維模型頂點規(guī)定著模型的空間位置關系,頂點所對應的紋理坐標規(guī)定著模型表面的圖案,即貼圖)。所以這樣的頂點需要產(chǎn)生多個復制。讀取第n個面片頂點時,則該面片頂點的標識符為<頂點idn,紋理坐標kn>,idn表示第n個面片頂點的標識號,kn表示第n個面片頂點的紋理坐標,n取值為自然數(shù),若該面片頂點的復制中存在映射到紋理坐標kn的映射關系,且面片仍存在其它未讀取的頂點,轉步驟2;其它情況轉步驟3;
步驟3:產(chǎn)生新的頂點。如果尋找到了共享頂點,則更新構建面片頂點id,轉步驟5。如果沒有找到,則產(chǎn)生和頂點idn位置一樣的頂點,轉步驟4;
步驟4:增加面片:增加一個連接新舊頂點的面片,并將新頂點加入頂點集,所述頂點集為已讀取的所有面片頂點的集合;
步驟5:如果面片仍有后續(xù)頂點未處理,轉步驟2;如果三維模型還有后續(xù)面片,轉步驟1;其它情況轉步驟6;
步驟6:三角面片化,由于整個模型包含許多面片,面片的頂點數(shù)不一,為了簡化計算紋理坐標時的插值運算,以及后續(xù)在模型上能夠運行曲面細分算法,該步驟將所有面片拆分為三角面片組成。
步驟7:曲面平滑。運用loop曲面細分算法,平滑模型。
步驟1中,為了確定面片的處理順序,針對一整塊連通的三維面,規(guī)定,面的構造過程是連續(xù)的,即當前面為連續(xù)的,當添加新的面片后,所得的三維面依然是連通的,所有新選取的面一定和當前面有共享的變,所以構造倒排索引表,索引項為邊,值為面片。
步驟2中,對模型增加面片的過程中,已構成的面由許多多面片組成的,為了保持面的流形結構,面片內部的頂點不能用于共享。所以本發(fā)明中尋找的共享頂點應處于面邊緣,一個頂點是否處于面邊緣等價于這個頂點周圍是否都被面片所占據(jù),以該頂點為中心,將其鄰域360等分,一份表示一度,形成的空間稱為360度空間,(對模型增加面片的過程中,已構成的面由許多多面片組成的,為了保持面的流形結構。面片內部的頂點不能用于共享。所以尋找的共享頂點應處于面邊緣,三維模型的面是由許許多多的面片拼接而成,頂點分為兩類,一類在面內部,一類處于面邊緣)為了加快查找速度,將當前面的邊緣點都保存在一個隊列中,當新加了面片之后,實時更新這個隊列,更新規(guī)則如下:
針對該面片上的每一個頂點:
(1)尋找到的能夠共享的頂點從隊列中刪除(步驟4增加的面片會使得頂點處于面內部);
(2)對于不能共享的頂點處理如下:將在當前面片中的角增加到該點所對應的360度空間中,如果360度空間被填滿,則刪除該點,否則僅僅更新該點所對應的360度空間。例子:初始時,頂點(o)所對應的360度空間為空,a增加角aob(a,o,b均為頂點表示)360度空間中增加(a,b);b增加角(boc),360度空間中增加(b,c);
此時合并(a,b),(b,c)為(a,c);c增加角(coa),360度空間中增加(c,a),此時合并(a,c)(c,a)為(a,a)此時在隊列中刪除o點,此時o點變?yōu)閮炔抗?jié)點,而非邊緣節(jié)點。
尋找到共享頂點之后,如果能夠共享,繼續(xù)處理面片下一個頂點。否則,轉步驟3。
步驟3中,根據(jù)建立的倒排索引表,每次取得的是有相連邊的面片,該面片一定和當前生成的面有邊的連接,利用該信息可以獲悉步驟3中增加的面片屬于360度空間哪一快扇形空白區(qū)域,將這扇形空白區(qū)域的兩邊端點取出記作A,B,記共享頂點為X,為了保持面的流行特性和紋理的正確性。采用以下規(guī)則產(chǎn)生新的跟X位置一樣的頂點Y:
Y1=α*X1+β*A1+γ*B1,
其中,Y1表示頂點Y的坐標,A1和B1分別表示點A的坐標和點B的坐標,α+β+γ=1且α,β,γ>0,α,β,γ頂點比重系數(shù)(一般取值分別為0.9,0.05,0.05),頂點Y對應的紋理坐標Yt為:Yt=α*Xt+β*At+γ*Bt,
其中,At和Bt分別為點A對應的紋理坐標和點B對應的紋理坐標,然后交換X與Y,即將頂點id所對應的內容互換。
以下證明該種變換不改變紋理的表示(以直線AB為例)B’為B點按照上述產(chǎn)生的新頂點,以下證明AB’與B’B之間點的插值結果一樣(c,β)表示(AC/AB,AB’/AB):
B’=β*B+(1-β)*A,C=c*B+(1-c)*A;
(1)C為AB’之間(c<β)C=c/β*B’+(1-c/β)*A=c*B+(1-c)*A
(2)C為B’B之間(c>β)C=(c-β)/(1-β)*B+(1-c)/(1-β)*B’=c*B+(1-c)*A
步驟4中,為了保持面的流形特征,所增加的面片不與原有的面重疊,而且為了在后續(xù)曲面平滑步驟中,保持面原有的網(wǎng)狀結果。并且所增加面片的(AXBY),(BXAY)兩者法向量方向的選擇基于相鄰面片法向量基本一致的原則,面片法向量由右手定則確定。
所述后續(xù)頂點與后續(xù)面片步驟階段,起著階段轉移,控制程序執(zhí)行的作用。
所述三角面片化過程中,由于整個模型包含許多面片,面片的頂點數(shù)不一,為了簡化計算紋理坐標時的插值運算,以及后續(xù)在模型上能夠運行曲面細分算法,該步驟將所有面片拆分為三角面片組成。
所述曲面平滑中,面片的不平滑是由于面片過大導致的,該步通過loop曲面細分,增加面片數(shù),平滑模型。
有益效果:本發(fā)明解決了現(xiàn)有技術中的問題:1)針對頂點:如果兩個面片包含同一個頂點坐標而且頂點坐標所對應的紋理坐標一樣。此時這兩個面共享改頂點id,如果頂點坐標所對應的紋理坐標不同,該頂點才會創(chuàng)建自身的復制。減少了要所需要存儲的頂點對象;2)針對面片:當頂點產(chǎn)生自身復制時,需要增加過渡面片,以保證整個曲面的連續(xù)性。
附圖說明
下面結合附圖和具體實施方式對本發(fā)明做更進一步的具體說明,本發(fā)明的上述或其他方面的優(yōu)點將會變得更加清楚。
圖1a為當前O點360度空間被占有情況。
圖1b為插入新的角AOE后360度空間變化情況。
圖1c為當O點不被共享時O點及O’點360度空間示意圖。
圖2為vtk內置類vtkObjReader處理obj格式文件效果。
圖3為應用loop曲面細分算法效果。
圖4和圖5為應用本發(fā)明提出的方法的效果。
圖6是本發(fā)明流程圖。
具體實施方式
下面結合附圖及實施例對本發(fā)明做進一步說明。
本發(fā)明適用于當obj文件里面面片的數(shù)量不夠,不足以產(chǎn)生一個平滑模型的情形,此時內置類vtkObjReader獨立的處理每一個小面片。本發(fā)明提出了新的處理obj格式文件的方法。1)在處理面片時,考慮頂點的共享,使得能夠共享同一個頂點的面片確實共享的是頂點集中的同一個頂點(頂點能夠共享指的是頂點的坐標位置以及對于的紋理坐標位置相同),共享頂點至少可以將頂點集減少一半。2)在需要產(chǎn)生一個新的頂點時,新頂點與原始頂點雖然位置相同,但是在曲面細化階段,由于細化是一個近似算法,所以頂點的位置可能將會偏移,新頂點與原始頂點可能就會分開。使得三維模型產(chǎn)生很多空洞。提出了在新頂點與原始頂點之間過渡面片,保證連續(xù)性。3)在產(chǎn)生的連續(xù)面片上面運用loop曲面細分算法,平滑模型。如圖6所示,本發(fā)明包括如下步驟:
步驟1:面片讀取。讀取obj文件三維模型里的面片,構造倒排索引表。
步驟2:尋找共享頂點:由于一個頂點對應著多個紋理坐標(三維模型頂點規(guī)定著模型的空間位置關系,頂點所對應的紋理坐標規(guī)定著模型表面的圖案,即貼圖)。所以這樣的頂點需要產(chǎn)生多個復制。面片頂點的標識符為<頂點id,紋理坐標k>,id表示頂點的標識號,讀取第n個面片頂點時,則該面片頂點的標識符為<頂點idn,紋理坐標kn>,idn表示第n個面片頂點的標識號,kn表示第n個面片頂點的紋理坐標,n取值為自然數(shù),若該面片頂點的復制中存在映射到紋理坐標kn的映射關系,且面片仍存在其它未讀取的頂點,轉步驟2;其它情況轉步驟3;
步驟3:產(chǎn)生新的頂點。如果尋找到了共享頂點,則更新構建面片頂點id,轉步驟5。如果沒有找到,則產(chǎn)生和頂點idn位置一樣的頂點,轉步驟4;
步驟4:增加面片:增加一個連接新舊頂點的面片,并將新頂點加入頂點集,所述頂點集為已讀取的所有面片頂點的集合;
步驟5:如果面片仍有后續(xù)頂點未處理,轉步驟2;如果三維模型還有后續(xù)面片,轉步驟1;其它情況轉步驟6;
步驟6:三角面片化,由于整個模型包含許多面片,面片的頂點數(shù)不一,為了簡化計算紋理坐標時的插值運算,以及后續(xù)在模型上能夠運行曲面細分算法,該步驟將所有面片拆分為三角面片組成。
步驟7:曲面平滑。運用loop曲面細分算法,平滑模型。
步驟1中,為了確定面片的處理順序,針對一整塊連通的三維面,規(guī)定,面的構造過程是連續(xù)的,即當前面為連續(xù)的,當添加新的面片后,所得的三維面依然是連通的,所有新選取的面一定和當前面有共享的變,所以構造倒排索引表,索引項為邊,值為面片。
步驟2中,對模型增加面片的過程中,已構成的面由許多多面片組成的,為了保持面的流形結構,面片內部的頂點不能用于共享。所以本發(fā)明中尋找的共享頂點應處于面邊緣,一個頂點是否處于面邊緣等價于這個頂點360度是否被四周面片所占據(jù),為了加快查找速度,將當前面的邊緣點都保存在一個隊列中,當新加了面片之后,實時更新這個隊列,更新規(guī)則如下:
針對每一個受影響的頂點:
(1)尋找到的可以共享的頂點從隊列中刪除(步驟4增加的面片會使得頂點處于面內部);
(2)其他頂點處理如下:將在當前面片中的角增加到該點所對應的360度空間中,如果360度空間被填滿,則刪除該點,否則僅僅更新該點所對應的360度空間。例子:初始時,頂點(o)所對應的360度空間為空,a增加角aob(a,o,b均為頂點表示)360度空間中增加(a,b);b增加角(boc),360度空間中增加(b,c);
此時合并(a,b),(b,c)為(a,c);c增加角(coa),360度空間中增加(c,a),此時合并(a,c)(c,a)為(a,a)此時在隊列中刪除o點,此時o點變?yōu)閮炔抗?jié)點,而非邊緣節(jié)點。
尋找到共享頂點之后,如果可以共享,繼續(xù)處理面片下一個頂點。否則,轉步驟3。
步驟3中,根據(jù)建立的倒排索引表,每次取得的是有相連邊的面片,該面片一定和當前生成的面有邊的連接,利用該信息可以獲悉步驟3中增加的面片屬于360度空間哪一快空白區(qū)域,將這扇形空白區(qū)域的兩邊端點取出記作A,B,記共享頂點為X,為了保持面的流行特性和紋理的正確性。采用以下規(guī)則產(chǎn)生新的跟X位置一樣的頂點Y:
Y1=α*X1+β*A1+γ*B1,
其中,Y1表示頂點Y的坐標,A1和B1分別表示點A的坐標和點B的坐標,α+β+γ=1且α,β,γ>0,α,β,γ頂點比重系數(shù),頂點Y對應的紋理坐標Yt為:Yt=α*Xt+β*At+γ*Bt,
其中,At和Bt分別為點A對應的紋理坐標和點B對應的紋理坐標,然后交換X與Y,即將頂點id所對應的內容互換。
以下證明該種變換不改變紋理的表示(以直線AB為例)B’為B點按照上述產(chǎn)生的新頂點,以下證明AB’與B’B之間點的插值結果一樣(c,β)表示(AC/AB,AB’/AB):
B’=β*B+(1-β)*A,C=c*B+(1-c)*A
(1)C為AB’之間(c<β)C=c/β*B’+(1-c/β)*A=c*B+(1-c)*A
(2)C為B’B之間(c>β)C=(c-β)/(1-β)*B+(1-c)/(1-β)*B’=c*B+(1-c)*A
步驟4中,為了保持面的流形特征,所增加的面片不與原有的面重疊,而且為了在后續(xù)曲面平滑步驟中,保持面原有的網(wǎng)狀結果。所有選擇增加面片(AXBY),(BXAY)方向的選擇基于保持面片法向量基本一致的原則。面片法向量由右手定則確定。
所述后續(xù)頂點與后續(xù)面片步驟階段,起著階段轉移,控制程序執(zhí)行的作用。
所述三角面片化過程中,由于整個模型包含許多面片,面片的頂點數(shù)不一,為了簡化計算紋理坐標時的插值運算,以及后續(xù)在模型上能夠運行曲面細分算法,該步驟將所有面片拆分為三角面片組成。
所述曲面平滑中,面片的不平滑是由于面片過大導致的,該步通過loop曲面細分,增加面片數(shù),平滑模型。
實施例:
本發(fā)明采用上述方案,實現(xiàn)了在vtk中重現(xiàn)了由faceGen導出的人臉。
具體實現(xiàn)如下:Loop細分是一種三角形網(wǎng)格的細分法則,它按照1-4三角形分裂,每條邊計算生成一個新的頂點,同時每個原始頂點更新位置。
步驟1:建立倒排索引表,采用的數(shù)據(jù)結構為字典<key為邊,value為面片集合>;當讀取到一個面片時,將該面片加入到以該面片邊為key的value集合中。最終返回這個倒排索引表。
步驟2:對模型增加面片的過程中,已構成的面由許多多面片組成的,為了保持面的流形結構。面片內部的頂點不能用于共享。所以我們尋找的共享頂點應處于面邊緣,一個頂點是否處于面邊緣等價于這個頂點360度是否被四周面片所占據(jù)。并更新。本次采用的一個長度為360的線段循環(huán)數(shù)組。首先在下標項中查找A,B,如果找不到,任意選取兩索引值a,b代表A與B。并將A與B之間置1.選取的a到b之間應該全文0。當將長度為360的線段全都置一之后,對應的頂點從邊緣頂點表中移除,如圖1a~圖1c所示,圖1a為當已插入面片AOB與面片COD時點O對應的360度空間的占用情況(黑色表示已經(jīng)被占用,空白區(qū)域表示未占用),圖1b在圖1a的基礎上,插入面片AOE,此時AOE中頂點O與圖1a頂點O三維坐標一樣,而且對應的紋理坐標id一樣,此時頂點O兩者共享,O點360度空間占用情況(黑色表示被占用,空白區(qū)域表示未占用)如圖1b所示。圖1c在圖1a的基礎上,插入面片AOE,此時AOE中頂點O與圖1a頂點O三維坐標一樣,但是對應的紋理坐標id不一樣,此時頂點O兩者不能共享。原圖1a中頂點O位移到O’,并且增加平滑面AOCO’,此時O與O’點360度空間占用情況(黑色表示被占用,空白區(qū)域表示未占用)如圖1c所示。
步驟3:指定參數(shù)α=0.9,β=0.05,γ=0.05,在面片內部產(chǎn)生新的頂點Y,并將Y與舊頂點X內容呼喚。
步驟4:產(chǎn)生新的面片。從步驟2中面片過程中需要注意面片頂點之間排列的順序,如圖1所示,因為共享邊在相鄰面中排序不同,所有根據(jù)該信息確定增加面片頂點流向。
步驟5:起到轉移控制作用;
步驟6,7采用的是vtk內置類vtkTriangleFilter(vtk工具庫中自帶的將三維模型所有面片三角化的處理類)和vtkLoopSubdivisionFilter(vtk工具庫中l(wèi)oop曲面細分算法的實現(xiàn)類)實現(xiàn)。圖2為vtk(The Visualization Toolkit)內置處理類vtkObjReader處理三維人臉模型的效果圖,面片與面片之間的過度不平滑。圖3為在vtk(The Visualization Toolkit)內置處理類vtkObjReader處理三維人臉模型結果的基礎上運用曲面細分算法平滑模型的效果圖,面片平滑,但是面片之間不連續(xù)。圖4和圖5為應用本發(fā)明提出的增加過渡面片法,連接面片的三維人臉模型的平滑顯示效果圖。
本發(fā)明提供了一種基于vtk處理obj文件的方法,具體實現(xiàn)該技術方案的方法和途徑很多,以上所述僅是本發(fā)明的優(yōu)選實施方式,應當指出,對于本技術領域的普通技術人員來說,在不脫離本發(fā)明原理的前提下,還可以做出若干改進和潤飾,這些改進和潤飾也應視為本發(fā)明的保護范圍。本實施例中未明確的各組成部分均可用現(xiàn)有技術加以實現(xiàn)。