亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

OpenCASCADE Make Primitives-Box

系統(tǒng) 2547 0

?

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)建出基本圖元,而不用關心其內部的數(shù)據(jù)結構。

wps_clip_image-27189

Figure 1. BRepPrimAPI Package classes

為 了理解ModelingData模塊中OpenCASCADE的邊界表示法BRep數(shù)據(jù)結構,決定參考其實現(xiàn),自己來創(chuàng)建出基本圖元,進而理解其中的 BRep數(shù)據(jù)結構。本文以最簡單的長方體Box入手,從點、邊到體的創(chuàng)建出一個形狀。并將構造的形狀在Draw Test Harness中進行顯示,且進行布爾運算,來驗證構造結果的正確性。

2. Make a Face of the Box

在OpenCASCADE的包BRepPrim中,構造長方體的方式是形狀的根結點出發(fā)到葉子結點,即從Shell到Face到Wire最后到Vertex,如下圖所示:

wps_clip_image-5617

Figure 2.1 Data structure of a Shape

為了程序演示的清晰,本文中采用與OpenCASCADE中相反的方式,即先從葉子結點出發(fā),逐步回到根結點,即先構造出頂點、邊最后到實體。長方體由六個面構成,所以先從一個面開始來構造。將一個面構造成功后,其他六個面的構造方法就相同了。

構造使用了BRep_Builder,在創(chuàng)建相應的拓樸的同時可以將其相關的幾何信息設置進去。如創(chuàng)建頂點Vertex時,可以將點的坐標信息及容差值設置進去,代碼如下所示:

        
          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)建邊的同時,將其邊中的三維曲線信息也設置進去,代碼如下所示:

        
          //
        
        
           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還需要與頂點Vertex關聯(liá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時需要注意邊的反向,從而構造成一個閉合的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
        
        
          ]);

}
        
      

關鍵是面的創(chuàng)建及面創(chuàng)建后,設置邊與面的關聯(lián)信息,即PCurve的信息。如果沒有PCurve的信息,可視化顯示就不能正確顯示出面,即網格化算法會失敗。長方體底面的創(chuàng)建及PCurve設置代碼如下所示:

        
          //
        
        
           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());

}
        
      

歷經艱辛,最后終于將一個面創(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

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

wps_clip_image-13274

Figure 2.4 Shared Edges of the Box

如上圖所示,當創(chuàng)建出長方體的三個面時,側面與上下兩個底面相連的邊顯示成了黃色。其他邊都是綠色。

3. Finish the Box

將長方體的六個面按上述方式創(chuàng)建完畢后,需要驗證其正確性。于是將生成的數(shù)據(jù)導出為Brep格式,并與其他基本體進行布爾運算。

當導出的長方體為Shell時進行布爾運算會得到的也是殼體,如下圖所示的結果:

wps_clip_image-88

Figure 3.1 Box Shell Cut a Cylinder

當導出的長方體為Solid時,若面的方式未正確設置,則布爾運算會失敗,如下圖所示:

wps_clip_image-331

Figure 3.2 Box Solid Cut a Cylinder

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

將面的方向正確設置后,導出為Solid,進行布爾運算,結果正確,如下圖所示:

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)建基本圖元,從而進一步來理解OpenCASCADE中的邊界表示BRep的數(shù)據(jù)結構。需要注意的事項有:

v 創(chuàng)建邊時,需要設置邊中幾何曲線的范圍;

v 創(chuàng)建邊時,需要設置正確與邊相關頂點的方向;

v 創(chuàng)建環(huán)時,需要確保環(huán)中邊的參數(shù)曲線PCurve能在參數(shù)空間中閉合;

v 創(chuàng)建面后,需要在邊中設置與面相關的幾何信息;

v 創(chuàng)建體時,需要所有面的方向正確;

注: 最后發(fā)現(xiàn)前不久寫的一篇文章有誤,說OpenCASCADE的BRep不是翼邊結構。其實從邊出發(fā)是可以找到與點、面相關的信息的。因為 OpenCASCADE中拓樸結構中有包含關系,所以頂點信息已經包含在邊中了,直接遍歷邊即可得到與此邊相關的頂點信息。所以,這樣看來 OpenCASCADE中的BRep表示法也是翼邊的數(shù)據(jù)結構。

原文如下:

邊界表示方式比較。因為一般的書籍上都詳細重 點描述了邊界表示中以為邊為核心的翼邊數(shù)據(jù)結構,所以有人想從這方面來給OpenCASCADE中的Brep表示法來給個說法。結合上面的類圖可知,從邊 出發(fā)并不能訪問到與這條邊相關的其他信息,如頂點的信息。如果硬是想在這里給個名分,倒是從點出發(fā)可以找到邊及面的幾何信息,所以OpenCASCADE 中的Brep表示法應該更像是以點為基礎的表示方法。OpenNURBS中通過ON_BrepTrim,可以訪問其他的信息,而ON_BrepTrim與 邊ON_BrepEdge的意義有些相似,所以應該是以邊為核心的翼邊結構了。

5. References

1. OpenCASCADE BRep vs. OpenNURBS Brep. OpenCASCADE BRep vs. OpenNURBS BRep

?

PDF Version and Source Code: OpenCASCADE Make Primitives-Box

OpenCASCADE Make Primitives-Box


更多文章、技術交流、商務合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 久久国产精品99久久久久久老狼 | 免费看欧美一级特黄α大片 | www.亚洲视频 | 天天cao在线 | 久久亚洲高清观看 | 美女网站色视频 | 久久综合中文字幕一区二区三区 | 九九九九九热 | 亚洲视频中文字幕在线观看 | 九九亚洲综合精品自拍 | 草草免费观看视频在线 | 日本a毛片在线播放 | 国产日| 手机看片福利视频 | 亚洲欧美日韩高清一区二区三区 | 亚洲热久久| 精品久久一 | 四虎在线网站 | 免费观看成人羞羞视频网站观看 | 色天天综合 | 久久精品国产亚洲黑森林 | 国产福利不卡 | 久久se精品一区二区影院 | 四虎影视库永久在线地址 | 午夜激情男女 | 国产不卡视频 | 伊人精品影院一本到欧美 | 国产一级毛片夜一级毛片 | 亚洲欧美日韩国产综合专区 | 神马我不卡在线观看 | 亚洲成人xxx| 国产小视频免费观看 | 欧洲黄色网 | 女人寂寞偷人视频a级 | 日韩视频一区二区三区 | 亚洲欧美综合在线观看 | 国产视频久久久久 | 天天射天天搞 | 国产中文一区 | 成人欧美视频 | 天天弄 |