?
OpenCASCADE Make Primitives-Box
Abstract. By making a simple box to demonstrate the BRep data structure of the OpenCASCADE. The construction method is different from BRepPrimAPI_MakeBox. In the paper construct the box from vertex, edge to solid, while in BRepPrimAPI_MakeBox from solid, shell to vertex. From the construction, the BRep data structure in OpenCASCADE also can be called the Winged-Edge data structure.
Key Words. OpenCASCADE, BRep, Box, The Winged-Edge Structure
1. Introduction
OpenCASCADE的Toolit TKPrim中提供了基本圖元的創(chuàng)建功能,像Box, Cylinder, Sphere等等。直接使用Package BRepPrimAPI中的功能,可以方便地創(chuàng)建出基本圖元,而不用關(guān)心其內(nèi)部的數(shù)據(jù)結(jié)構(gòu)。
Figure 1. BRepPrimAPI Package classes
為 了理解ModelingData模塊中OpenCASCADE的邊界表示法BRep數(shù)據(jù)結(jié)構(gòu),決定參考其實(shí)現(xiàn),自己來創(chuàng)建出基本圖元,進(jìn)而理解其中的 BRep數(shù)據(jù)結(jié)構(gòu)。本文以最簡單的長方體Box入手,從點(diǎn)、邊到體的創(chuàng)建出一個(gè)形狀。并將構(gòu)造的形狀在Draw Test Harness中進(jìn)行顯示,且進(jìn)行布爾運(yùn)算,來驗(yàn)證構(gòu)造結(jié)果的正確性。
2. Make a Face of the Box
在OpenCASCADE的包BRepPrim中,構(gòu)造長方體的方式是形狀的根結(jié)點(diǎn)出發(fā)到葉子結(jié)點(diǎn),即從Shell到Face到Wire最后到Vertex,如下圖所示:
Figure 2.1 Data structure of a Shape
為了程序演示的清晰,本文中采用與OpenCASCADE中相反的方式,即先從葉子結(jié)點(diǎn)出發(fā),逐步回到根結(jié)點(diǎn),即先構(gòu)造出頂點(diǎn)、邊最后到實(shí)體。長方體由六個(gè)面構(gòu)成,所以先從一個(gè)面開始來構(gòu)造。將一個(gè)面構(gòu)造成功后,其他六個(gè)面的構(gòu)造方法就相同了。
構(gòu)造使用了BRep_Builder,在創(chuàng)建相應(yīng)的拓樸的同時(shí)可以將其相關(guān)的幾何信息設(shè)置進(jìn)去。如創(chuàng)建頂點(diǎn)Vertex時(shí),可以將點(diǎn)的坐標(biāo)信息及容差值設(shè)置進(jìn)去,代碼如下所示:
BRep_Builder aBuilder; // make vertex of the box. aBuilder.MakeVertex(aVertices[ 0 ], aPoints[ 0 ], Precision::Confusion()); aBuilder.MakeVertex(aVertices[ 1 ], aPoints[ 1 ], Precision::Confusion()); aBuilder.MakeVertex(aVertices[ 2 ], aPoints[ 2 ], Precision::Confusion()); aBuilder.MakeVertex(aVertices[ 3 ], aPoints[ 3 ], Precision::Confusion()); aBuilder.MakeVertex(aVertices[ 4 ], aPoints[ 4 ], Precision::Confusion()); aBuilder.MakeVertex(aVertices[ 5 ], aPoints[ 5 ], Precision::Confusion()); aBuilder.MakeVertex(aVertices[ 6 ], aPoints[ 6 ], Precision::Confusion()); aBuilder.MakeVertex(aVertices[ 7 ], aPoints[ 7 ], Precision::Confusion());
創(chuàng)建邊的同時(shí),將其邊中的三維曲線信息也設(shè)置進(jìn)去,代碼如下所示:
// make edges of the box. aBuilder.MakeEdge(aEdges[ 0 ], new Geom_Line(aLines[ 0 ]), Precision::Confusion()); aBuilder.MakeEdge(aEdges[ 1 ], new Geom_Line(aLines[ 1 ]), Precision::Confusion()); aBuilder.MakeEdge(aEdges[ 2 ], new Geom_Line(aLines[ 2 ]), Precision::Confusion()); aBuilder.MakeEdge(aEdges[ 3 ], new Geom_Line(aLines[ 3 ]), Precision::Confusion()); aBuilder.MakeEdge(aEdges[ 4 ], new Geom_Line(aLines[ 4 ]), Precision::Confusion()); aBuilder.MakeEdge(aEdges[ 5 ], new Geom_Line(aLines[ 5 ]), Precision::Confusion()); aBuilder.MakeEdge(aEdges[ 6 ], new Geom_Line(aLines[ 6 ]), Precision::Confusion()); aBuilder.MakeEdge(aEdges[ 7 ], new Geom_Line(aLines[ 7 ]), Precision::Confusion()); aBuilder.MakeEdge(aEdges[ 8 ], new Geom_Line(aLines[ 8 ]), Precision::Confusion()); aBuilder.MakeEdge(aEdges[ 9 ], new Geom_Line(aLines[ 9 ]), Precision::Confusion()); aBuilder.MakeEdge(aEdges[ 10 ], new Geom_Line(aLines[ 10 ]),Precision::Confusion()); aBuilder.MakeEdge(aEdges[ 11 ], new Geom_Line(aLines[ 11 ]),Precision::Confusion());
創(chuàng)建的邊Edge還需要與頂點(diǎn)Vertex關(guān)聯(lián)上,且需要注意頂點(diǎn)的反向,示例代碼如下所示:
// set the vertex info of the edges. // edge 0: { TopoDS_Vertex V1 = aVertices[ 0 ]; TopoDS_Vertex V2 = aVertices[ 1 ]; V2.Reverse(); aBuilder.Add(aEdges[ 0 ], V1); aBuilder.Add(aEdges[ 0 ], V2); aBuilder.UpdateVertex(V1, ElCLib::Parameter(aLines[ 0 ], aPoints[ 0 ]), aEdges[ 0 ], Precision::Confusion()); aBuilder.UpdateVertex(V2, ElCLib::Parameter(aLines[ 0 ], aPoints[ 1 ]), aEdges[ 0 ], Precision::Confusion()); BRepTools::Update(aEdges[ 0 ]); }
接著創(chuàng)建Wire,創(chuàng)建Wire時(shí)需要注意邊的反向,從而構(gòu)造成一個(gè)閉合的Wire,代碼如下所示:
// make wires of the box. aBuilder.MakeWire(aWires[ 0 ]); // wire 1: bottom { TopoDS_Edge E1 = aEdges[ 0 ]; TopoDS_Edge E2 = aEdges[ 1 ]; TopoDS_Edge E3 = aEdges[ 2 ]; TopoDS_Edge E4 = aEdges[ 3 ]; E3.Reverse(); E4.Reverse(); aBuilder.Add(aWires[ 0 ], E1); aBuilder.Add(aWires[ 0 ], E2); aBuilder.Add(aWires[ 0 ], E3); aBuilder.Add(aWires[ 0 ], E4); BRepTools::Update(aWires[ 0 ]); }
關(guān)鍵是面的創(chuàng)建及面創(chuàng)建后,設(shè)置邊與面的關(guān)聯(lián)信息,即PCurve的信息。如果沒有PCurve的信息,可視化顯示就不能正確顯示出面,即網(wǎng)格化算法會(huì)失敗。長方體底面的創(chuàng)建及PCurve設(shè)置代碼如下所示:
// make faces of the box. aBuilder.MakeFace(aFaces[ 0 ], new Geom_Plane(aPlanes[ 0 ]),Precision::Confusion()); aBuilder.Add(aFaces[ 0 ], aWires[ 0 ]); // set bottom pcurve info of between the edge and surface. { // pcurve 0: double u = 0.0 ; double v = 0.0 ; double du = 0.0 ; double dv = 0.0 ; gp_Dir DX = aPlanes[ 0 ].XAxis().Direction(); gp_Dir DY = aPlanes[ 0 ].YAxis().Direction(); ElSLib::Parameters(aPlanes[ 0 ], aLines[ 0 ].Location(), u, v); du = aLines[ 0 ].Direction() * DX; dv = aLines[ 0 ].Direction() * DY; aBuilder.UpdateEdge(aEdges[ 0 ], new Geom2d_Line(gp_Lin2d(gp_Pnt2d(u, v), gp_Dir2d(du, dv))), aFaces[ 0 ], Precision::Confusion()); // pcurve 1: ElSLib::Parameters(aPlanes[ 0 ], aLines[ 1 ].Location(), u, v); du = aLines[ 1 ].Direction() * DX; dv = aLines[ 1 ].Direction() * DY; aBuilder.UpdateEdge(aEdges[ 1 ], new Geom2d_Line(gp_Lin2d(gp_Pnt2d(u, v), gp_Dir2d(du, dv))), aFaces[ 0 ], Precision::Confusion()); // pcurve 2: ElSLib::Parameters(aPlanes[ 0 ], aLines[ 2 ].Location(), u, v); du = aLines[ 2 ].Direction() * DX; dv = aLines[ 2 ].Direction() * DY; aBuilder.UpdateEdge(aEdges[ 2 ], new Geom2d_Line(gp_Lin2d(gp_Pnt2d(u, v), gp_Dir2d(du, dv))), aFaces[ 0 ], Precision::Confusion()); // pcurve 3: ElSLib::Parameters(aPlanes[ 0 ], aLines[ 3 ].Location(), u, v); du = aLines[ 3 ].Direction() * DX; dv = aLines[ 3 ].Direction() * DY; aBuilder.UpdateEdge(aEdges[ 3 ], new Geom2d_Line(gp_Lin2d(gp_Pnt2d(u, v), gp_Dir2d(du, dv))), aFaces[ 0 ], Precision::Confusion()); }
歷經(jīng)艱辛,最后終于將一個(gè)面創(chuàng)建出來了,且可以在Draw Test Harness中顯示,如下圖所示:
Figure 2.2 A Face of the Box in Draw Test Harness
如上圖所示,在Darw Test Harness中,邊的顏色是有講究的,說明如下:
In Draw Test Harness, shapes are displayed using isoparametric curves. There is color coding for the Edges:
v A red edge is an isolated edge, which belongs to no faces;
v A green edge is a free boundary edge, which belongs to one face;
v A yello edge is shared edge, which belongs to at least two faces;
Figure 2.3 Color Coding for Edges in Draw Test Harness
如上圖所示,紅色的邊表示此邊不屬于任何一個(gè)面;綠色的邊表示此邊只屬于一個(gè)面;黃色的面表示此面至少屬于兩個(gè)面。
Figure 2.4 Shared Edges of the Box
如上圖所示,當(dāng)創(chuàng)建出長方體的三個(gè)面時(shí),側(cè)面與上下兩個(gè)底面相連的邊顯示成了黃色。其他邊都是綠色。
3. Finish the Box
將長方體的六個(gè)面按上述方式創(chuàng)建完畢后,需要驗(yàn)證其正確性。于是將生成的數(shù)據(jù)導(dǎo)出為Brep格式,并與其他基本體進(jìn)行布爾運(yùn)算。
當(dāng)導(dǎo)出的長方體為Shell時(shí)進(jìn)行布爾運(yùn)算會(huì)得到的也是殼體,如下圖所示的結(jié)果:
Figure 3.1 Box Shell Cut a Cylinder
當(dāng)導(dǎo)出的長方體為Solid時(shí),若面的方式未正確設(shè)置,則布爾運(yùn)算會(huì)失敗,如下圖所示:
Figure 3.2 Box Solid Cut a Cylinder
如上圖所示,長方體與圓柱體的交線都已經(jīng)計(jì)算出來了,但由于面的方向不對(duì),不知道去除哪些面,保留哪些面。
將面的方向正確設(shè)置后,導(dǎo)出為Solid,進(jìn)行布爾運(yùn)算,結(jié)果正確,如下圖所示:
Figure 3.3 Box Cut Cylinder
測試用的Tcl腳本代碼如下所示:
# # Tcl script to test the box BRep data. # eryar@163.com # 2014-11-16 21:55 # OpenCASCADE6.8.0 # pload ALL restore d :/box. brep b pcylinder c 1.5 2 bop b c bopcut r vdisplay r
?
4. Conclusion
通過創(chuàng)建基本圖元,從而進(jìn)一步來理解OpenCASCADE中的邊界表示BRep的數(shù)據(jù)結(jié)構(gòu)。需要注意的事項(xiàng)有:
v 創(chuàng)建邊時(shí),需要設(shè)置邊中幾何曲線的范圍;
v 創(chuàng)建邊時(shí),需要設(shè)置正確與邊相關(guān)頂點(diǎn)的方向;
v 創(chuàng)建環(huán)時(shí),需要確保環(huán)中邊的參數(shù)曲線PCurve能在參數(shù)空間中閉合;
v 創(chuàng)建面后,需要在邊中設(shè)置與面相關(guān)的幾何信息;
v 創(chuàng)建體時(shí),需要所有面的方向正確;
注: 最后發(fā)現(xiàn)前不久寫的一篇文章有誤,說OpenCASCADE的BRep不是翼邊結(jié)構(gòu)。其實(shí)從邊出發(fā)是可以找到與點(diǎn)、面相關(guān)的信息的。因?yàn)?OpenCASCADE中拓樸結(jié)構(gòu)中有包含關(guān)系,所以頂點(diǎn)信息已經(jīng)包含在邊中了,直接遍歷邊即可得到與此邊相關(guān)的頂點(diǎn)信息。所以,這樣看來 OpenCASCADE中的BRep表示法也是翼邊的數(shù)據(jù)結(jié)構(gòu)。
原文如下:
邊界表示方式比較。因?yàn)橐话愕臅隙荚敿?xì)重 點(diǎn)描述了邊界表示中以為邊為核心的翼邊數(shù)據(jù)結(jié)構(gòu),所以有人想從這方面來給OpenCASCADE中的Brep表示法來給個(gè)說法。結(jié)合上面的類圖可知,從邊 出發(fā)并不能訪問到與這條邊相關(guān)的其他信息,如頂點(diǎn)的信息。如果硬是想在這里給個(gè)名分,倒是從點(diǎn)出發(fā)可以找到邊及面的幾何信息,所以O(shè)penCASCADE 中的Brep表示法應(yīng)該更像是以點(diǎn)為基礎(chǔ)的表示方法。OpenNURBS中通過ON_BrepTrim,可以訪問其他的信息,而ON_BrepTrim與 邊ON_BrepEdge的意義有些相似,所以應(yīng)該是以邊為核心的翼邊結(jié)構(gòu)了。
5. References
1. OpenCASCADE BRep vs. OpenNURBS Brep. OpenCASCADE BRep vs. OpenNURBS BRep
?
PDF Version and Source Code: OpenCASCADE Make Primitives-Box
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元
