• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            eryar

            PipeCAD - Plant Piping Design Software.
            RvmTranslator - Translate AVEVA RVM to OBJ, glTF, etc.
            posts - 603, comments - 590, trackbacks - 0, articles - 0

            OpenCASCADE Make Primitives-Box

            Posted on 2014-11-16 22:22 eryar 閱讀(4766) 評論(0)  編輯 收藏 引用 所屬分類: 2.OpenCASCADE

            OpenCASCADE Make Primitives-Box

            eryar@163.com

            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)。

            wps_clip_image-27189

            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,如下圖所示:

            wps_clip_image-5617

            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中顯示,如下圖所示:

            wps_clip_image-17990

            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;

            wps_clip_image-27097

            Figure 2.3 Color Coding for Edges in Draw Test Harness

            如上圖所示,紅色的邊表示此邊不屬于任何一個(gè)面;綠色的邊表示此邊只屬于一個(gè)面;黃色的面表示此面至少屬于兩個(gè)面。

            wps_clip_image-13274

            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é)果:

            wps_clip_image-88

            Figure 3.1 Box Shell Cut a Cylinder

            當(dāng)導(dǎo)出的長方體為Solid時(shí),若面的方式未正確設(shè)置,則布爾運(yùn)算會(huì)失敗,如下圖所示:

            wps_clip_image-331

            Figure 3.2 Box Solid Cut a Cylinder

            如上圖所示,長方體與圓柱體的交線都已經(jīng)計(jì)算出來了,但由于面的方向不對,不知道去除哪些面,保留哪些面。

            將面的方向正確設(shè)置后,導(dǎo)出為Solid,進(jìn)行布爾運(yùn)算,結(jié)果正確,如下圖所示:

            wps_clip_image-22873

            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)镺penCASCADE中拓樸結(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

            亚洲精品午夜国产VA久久成人| 青青青青久久精品国产| 一本色道久久88综合日韩精品| 亚洲国产成人精品久久久国产成人一区二区三区综| 久久国产精品99久久久久久老狼| 九九久久精品国产| 亚洲乱码精品久久久久..| 国产精品99久久久久久宅男| 久久久久久久精品成人热色戒| 99久久99久久久精品齐齐| 久久人人爽人人澡人人高潮AV | 国产精品9999久久久久| 国产精品欧美久久久天天影视| 日日狠狠久久偷偷色综合96蜜桃 | 99久久免费国产精品热| 人人狠狠综合88综合久久| 999久久久免费精品国产| 午夜精品久久久久| 久久99精品久久久久久水蜜桃| 午夜久久久久久禁播电影| 久久精品国产亚洲AV不卡| 久久本道伊人久久| 国内精品伊人久久久久AV影院| 99久久国产综合精品女同图片| 久久精品成人免费国产片小草| 狠狠色噜噜狠狠狠狠狠色综合久久| 久久久国产99久久国产一| 久久久久国产| 青青草原综合久久大伊人导航| 久久se精品一区精品二区国产| 成人资源影音先锋久久资源网| 久久精品国产亚洲AV麻豆网站| 97精品伊人久久久大香线蕉| 97香蕉久久夜色精品国产 | 久久香蕉超碰97国产精品| 久久久久久精品无码人妻| 伊人色综合久久天天网| 久久亚洲精品国产精品婷婷| 少妇被又大又粗又爽毛片久久黑人| 国产亚洲色婷婷久久99精品91 | 久久香蕉综合色一综合色88|