• <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

            Topology and Geometry in OpenCascade-Topology

            Posted on 2013-09-21 14:59 eryar 閱讀(5840) 評(píng)論(2)  編輯 收藏 引用 所屬分類(lèi): 2.OpenCASCADE

            Topology and Geometry in OpenCascade-Topology

            eryar@163.com

            摘要Abstract:本文簡(jiǎn)要介紹了幾何造型中的邊界表示法(BRep),并結(jié)合程序說(shuō)明OpenCascade中的邊界表示的具體實(shí)現(xiàn),即拓樸與幾何的聯(lián)系。對(duì)具有幾何信息的拓樸結(jié)構(gòu)頂點(diǎn)(vertex)、邊(edge)、面(face)進(jìn)行了詳細(xì)說(shuō)明。本文通過(guò)ACIS與OpenCascade進(jìn)行對(duì)比來(lái)對(duì)拓樸(Topology)的概念進(jìn)行說(shuō)明。并通過(guò)示例程序,說(shuō)明如何在OpenCascade中取得與一個(gè)拓樸對(duì)象相連的其他拓樸對(duì)象,包括父對(duì)象和子對(duì)象。

            關(guān)鍵字Key Words:OpenCascade、ACIS、BRep、Topology、Geometry

            一、引言 Introduction

            邊界表示(Boundary Representation)也稱為BRep表示,它是幾何造型中最成熟、無(wú)二義的表示法。實(shí)體的邊界通常是由面的并集來(lái)表示,而每個(gè)面又由它所在的曲面的定義加上其邊界來(lái)表示,面的邊界是邊的并集,而邊又是由點(diǎn)來(lái)表示的。

            邊界表示的一個(gè)重要特征是描述形體的信息包括幾何信息(Geometry)和拓樸信息(Topology)兩個(gè)方面。拓樸信息描述形體上的頂點(diǎn)、邊、面的連接關(guān)系,它形成物體邊界表示的“骨架”。形體的幾何信息猶如附著在“骨架”上的肌肉。例如,形體的某個(gè)面位于某一個(gè)曲面上,定義這一曲面方程的數(shù)據(jù)就是幾何信息。此外,邊的形狀、頂點(diǎn)在三維空間中的位置(點(diǎn)的坐標(biāo))等都是幾何信息,一般來(lái)說(shuō),幾何信息描述形體的大小、尺寸、位置和形狀等。

            在邊界表示法中,邊界表示就按照體-面-環(huán)-邊-點(diǎn)的層次,詳細(xì)記錄構(gòu)成形體的所有幾何元素的幾何信息及其相互連接的拓樸關(guān)系。這樣,在進(jìn)行各種運(yùn)算和操作中,就可以直接取得這些信息。

            拓樸是指一個(gè)模型中的不同實(shí)體之間的關(guān)系,它描述了幾何實(shí)體之間的連接方式。拓樸定義了一個(gè)空間位置不固定的浮動(dòng)模型。當(dāng)拓樸實(shí)體與幾何信息關(guān)聯(lián)在一起時(shí),它的空間位置才確定。

            拓樸可以是有邊界的、沒(méi)邊界的和半封閉的,它允許實(shí)體是完全實(shí)體,也可以是不完全實(shí)體。例如,實(shí)體可以沒(méi)有面,面可以沒(méi)有邊,實(shí)體也可以從內(nèi)部將它分割成殼的內(nèi)部面。這種實(shí)體在物理世界中是不存在的,但在幾何造型內(nèi)核中可以表現(xiàn)出來(lái)。

            二、ACIS中的拓樸結(jié)構(gòu) Topology of ACIS

            ACIS模型的邊界表示(B-Rep)是將模型的拓樸結(jié)構(gòu)按層次分解成下述對(duì)象:

            1. 體(Body):是實(shí)體對(duì)象的最高層次,是塊(lump)的集合。體可以是線、面、或?qū)嵭捏w;

            2. 塊(Lump):空間一維、二維或三維點(diǎn)連接而成的集合,與其他塊(lump)不關(guān)聯(lián),其邊界由殼(shell)組成;

            3. 殼(Shell):互聯(lián)的線或面的集合,它可以界定實(shí)體的外部或內(nèi)部區(qū)域;

            4. 子殼(Subshell):殼的進(jìn)一步分解,用于處理內(nèi)部處理算法的效率;

            5. 面(Face):被一個(gè)或多個(gè)邊(edge)組成的環(huán)(loop)界定的曲面中的連通域。面可以是“雙向”的,這時(shí)它的厚度趨于無(wú)窮小。面也可以是“單向”的,這時(shí)面的法線指向面的外部,另一邊側(cè)是面的內(nèi)部;

            6. 環(huán)(Loop):面(face)的邊界中互相連接的部分,它由一系列的有向邊(coedge)組成。通常環(huán)是封閉的,沒(méi)有實(shí)際的開(kāi)始和結(jié)束點(diǎn),但是ACIS中的環(huán)可以是開(kāi)環(huán);

            7. 線(Wire):沒(méi)有附著在面上的,連接在一起的有向邊(coedge);

            8. 有向邊(Coedge):表示面(face)或線(wire)中對(duì)某個(gè)邊的引用;

            9. 邊(Edge):與曲線關(guān)聯(lián)的拓樸,由頂點(diǎn)(vertex)界定。

            10. 頂點(diǎn)(Vertex):點(diǎn)是幾何造型中的最基本元素。用計(jì)算機(jī)存儲(chǔ)、管理、輸出形體的實(shí)質(zhì)就是對(duì)點(diǎn)集及其連接關(guān)系的處理。

            wps_clip_image-6000

            Figure 2.1 Topology of ACIS

            上圖說(shuō)明了概念上的拓樸對(duì)象之間的關(guān)系,這些對(duì)象組成了ACIS邊界表示方法的基礎(chǔ)。它們?cè)贏CIS中分別用類(lèi)BODY、LUMP、SHELL、SUBSHELL、FACE、LOOP、WIRE、COEDGE、EDGE和VERTEX實(shí)現(xiàn),這些類(lèi)派生于類(lèi)ENTITY。

            ACIS通過(guò)在它的數(shù)據(jù)結(jié)構(gòu)中整合了線框、曲面和實(shí)體這三種表示方法,將這三種不同的幾何體聯(lián)系在一起。線框?qū)嶓w可以和實(shí)體(solid)與面實(shí)體共享,它們可以是共享邊、有向邊與頂點(diǎn)。由于這種共存的實(shí)現(xiàn),使ACIS具有了表示混合維度模型與各種各樣不封閉模型的能力,如一個(gè)平面可以只在3個(gè)方向上有邊界邊,另外一方向沒(méi)有邊界。

            wps_clip_image-11877

            Figure 2.2 Class Diagram of ACIS Topology

            ACIS的對(duì)象都有包圍盒(Bound),這在求交運(yùn)算中很有用,可以提高效率。如果兩個(gè)對(duì)象的包圍盒相交,那么這兩個(gè)對(duì)象則可能相交,然后再執(zhí)行更精確的求交運(yùn)算。如果兩個(gè)對(duì)象的包圍盒不相交,則這兩個(gè)對(duì)象一定不相交,這樣進(jìn)一步的精確求交運(yùn)算就不需要了。

            既然拓樸表示了各對(duì)象之間的連接關(guān)系,那么給定一個(gè)對(duì)象時(shí),可以容易得到其相連接其它對(duì)象。圖3說(shuō)明了ACIS中組成實(shí)體、面、線和混合體的所有實(shí)體類(lèi),這些類(lèi)及其方法提供了一個(gè)邊界表示造型器所必需的數(shù)據(jù)和方法。層次關(guān)系中向上和向下的指示說(shuō)明這些類(lèi)之間允許數(shù)據(jù)的快速切換,利用這種功能就可以確定兩個(gè)實(shí)體是否共享邊或頂點(diǎn)。從圖中可以看出拓樸類(lèi)都有指向?qū)?yīng)的幾何體類(lèi)的指針。

            wps_clip_image-8073

            Figure 2.3 Topology structure of ACIS

            從上圖可以看出,任意給定一個(gè)對(duì)象,可以快速獲得與其相連的其它對(duì)象,不管是向下還是向上。如給定一個(gè)FACE對(duì)象,可以通過(guò)loop()向下獲得LOOP對(duì)象;可以通過(guò)shell()向上獲得SHELL對(duì)象。

            除了頂點(diǎn)以外,其他拓樸對(duì)象都有bound(),可以取得其包圍盒。

            下面是統(tǒng)計(jì)一個(gè)模型中所有面的數(shù)量的程序,該程序就是利用拓樸類(lèi)的公共成員函數(shù)來(lái)完成面的統(tǒng)計(jì)功能。通過(guò)這個(gè)程序來(lái)說(shuō)明函數(shù)的使用方法。

            wps_clip_image-11521

             

            三、OpenCascade中的拓樸結(jié)構(gòu) Topology of OpenCascade

            3.1 OpenCascade拓樸簡(jiǎn)介 Introduction of OpenCascade Topology

            OpenCascade中的拓樸(topology)是根據(jù)STEP標(biāo)準(zhǔn)ISO-10303-42設(shè)計(jì)的。也許讀一下這個(gè)標(biāo)準(zhǔn)中的有關(guān)概念還是很有幫助的。STEP ISO-10303-42的相關(guān)資源:

            http://www.steptools.com/support/stdev_docs/express/step_irs/index.html

            wps_clip_image-6429

            Figure 3.1 Topology data structure in OpenCascade

            wps_clip_image-12719

            TopoDS_Shape由值控制,包含三個(gè)成員變量:myLocation、myOrient、myTShape。

            wps_clip_image-16890

            Figure 3.2 TopoDS_Shape member fields

            其中TopoDS_TShape中包含與此對(duì)象相連接的子對(duì)象。

            下圖所示為由一條邊連接的兩個(gè)面組成的殼(shell):

            wps_clip_image-28930

            Figure 3.3 Structure of a shell formed from two faces

            上圖所示的形狀表示為T(mén)S, 面TF1和TF2,有七條邊TE1~TE7和六個(gè)頂點(diǎn)TV1~TV6。

            環(huán)TW1引用邊TE1~TE4;環(huán)TW2引用TE4~TE7 。邊引用的頂點(diǎn)如下:TE1(TV1,TV4),TE2(TV1,TV2),TE3(TV2,TV3),TE4(TV3,TV4),TE5(TV4,TV5),TE6(TV5,TV6),TE7(TV3,TV6)。

            wps_clip_image-14945

            Figure 3.4 Data structure of the shell formed from two faces connected at an edge

            注:OpenCascade中的這個(gè)數(shù)據(jù)結(jié)構(gòu)中不包含“反向引用(back references)”,即所有的引用只從復(fù)雜形狀到簡(jiǎn)單形狀。(Note that this data structure does not contain any “back references”. All references go from more comples underlying shapes to less complex ones.)有點(diǎn)有向圖的意思。

            這個(gè)根據(jù)OpenCascade的拓樸結(jié)構(gòu)的類(lèi)圖可知,訪問(wèn)形狀的子對(duì)象是很容易的。為了獲得一個(gè)對(duì)象的拓樸,不管是向上還是向下,OpenCascade提供了專門(mén)類(lèi)和函數(shù)來(lái)實(shí)現(xiàn)。當(dāng)向下訪問(wèn)拓樸對(duì)象時(shí),OpenCascacde提供了兩種方法來(lái)遍歷子對(duì)象。向上遍歷時(shí),OpenCascade提供了一個(gè)靜態(tài)函數(shù)TopExp::MapShapesAndAncestors()來(lái)實(shí)現(xiàn)。以下分別對(duì)其進(jìn)行說(shuō)明。

            3.2 遍歷子對(duì)象 Iteration over Children

            遍歷子對(duì)象是向下來(lái)訪問(wèn)拓樸關(guān)系。OpenCascade中遍歷一個(gè)形狀的子對(duì)象的兩個(gè)方法分別為:

            l 直接使用類(lèi)TopoDS_Iterator來(lái)遍歷:

            Direct children can be retrieved using TopoDS_Iterator,如下函數(shù)可以訪問(wèn)當(dāng)前對(duì)象所有的子對(duì)象,不管子對(duì)象的類(lèi)型。通過(guò)遞歸的方式來(lái)實(shí)現(xiàn)。

            1 void TraverseShape(const TopoDS_Shape& theShape) 
            2 
            3     TopoDS_Iterator anIt(theShape); 
            4     for ( ; anIt.More(); anIt.Next() ) 
            5     { 
            6         const TopoDS_Shape& aChild = anIt.Value(); 
            7         TraverseShape(aChild); 
            8     } 
            9 

             

            TopoDS_Iterator有兩個(gè)標(biāo)志位,用于控制在查詢子對(duì)象時(shí)設(shè)定是否考慮父對(duì)象的位置和朝向(location and orientation)。若位置(location)標(biāo)志設(shè)置為開(kāi),那么所有子對(duì)象返回的值就像它們是獨(dú)立的對(duì)象一樣,而且位置是在具有全局坐標(biāo)系的三維空間中的位置。(例如用戶將看到單獨(dú)取出來(lái)的邊edge與其父對(duì)象環(huán)wire中顯示的位置是一樣的。)若朝向(orientation)標(biāo)設(shè)置為開(kāi),則返回的子對(duì)象的朝向?qū)?huì)變成父對(duì)象的朝向與子對(duì)象朝向的乘積(例如,子對(duì)象和父對(duì)象兩者都是反向reversed或是向前forward,則結(jié)果仍然向前。向前與反向的任意組合結(jié)果都將為反向)。

            若標(biāo)志位為關(guān),則子對(duì)象就只返回其自身保存的位置和朝向。默認(rèn)情況下,兩個(gè)標(biāo)志位都設(shè)置為開(kāi)。

            l 使用類(lèi)TopExp_Explorer來(lái)遍歷指定類(lèi)型的子對(duì)象:

            若只想訪問(wèn)形狀指定類(lèi)型的子對(duì)象,可以使用類(lèi)TopExp_Explorer來(lái)實(shí)現(xiàn)。如下程序所示為訪問(wèn)對(duì)象的邊的功能。

            1 TopExp_Explorer anExp(theShape, TopAbs_EDGE); 
            2 
            3 for (; anExp.More(); anExp.Next() ) 
            4 
            5     const TopoDS_Edge& anEdge = TopoDS::Edge(anExp.Current()); 
            6     // do something with anEdge 
            7 
            8 

            類(lèi)TopExp_Explorer還有一個(gè)附加參數(shù),可以用來(lái)指定要跳過(guò)的父對(duì)象類(lèi)型。這個(gè)參數(shù)在下面的情況下很有用。例如只想取得“懸空”邊(floating edge, 即不屬于面的邊),就可用下面代碼來(lái)實(shí)現(xiàn):

            1 TopExp_Explorer aFloatingEdgeExp(theShape, TopAbs_EDGE, TopAbs_FACE); 

             

            3.3 反向引用 Back references

            在使用OpenCascade時(shí),你可能也注意到了,或者根據(jù)類(lèi)圖分析到拓樸對(duì)象包含其子對(duì)象,而不是相反的方式。這是可以理解的,同一個(gè)對(duì)象或者子對(duì)象可以屬于不同的對(duì)象。例如任意共享邊可以屬于至少兩個(gè)面。然而有時(shí)也需要從子對(duì)象追蹤到與其相連的父對(duì)象。在OpenCascade中提供了靜態(tài)函數(shù)TopExp::MapShapesAndAncestors()來(lái)實(shí)現(xiàn)這個(gè)功能。

            1 TopTools_IndexedDataMapOfShapeListOfShape anEFsMap; 
            2 TopExp::MapShapesAndAncestors (myShape, TopAbs_EDGE, TopAbs_FACE, anEFsMap); 

            上面的代碼生成了myShape中面和邊之間的映射。若myShape是長(zhǎng)方體,每一條邊會(huì)映射到兩個(gè)面上。若遍歷同樣的長(zhǎng)方體,并在每一個(gè)面中盡力找到邊的父對(duì)象,那么明顯的該映射中一條邊只有一個(gè)面,也就是當(dāng)前正在搜索的面。

             

            四、示例程序 Example Code

            1. 統(tǒng)計(jì)一個(gè)長(zhǎng)方體面的數(shù)量

             1 /* 
             2 *    Copyright (c) 2013 eryar All Rights Reserved. 
             3 
             4 *        File    : Main.cpp 
             5 *        Author  : eryar@163.com 
             6 *        Date    : 2013-09-21 11:58 
             7 *        Version : 1.0v 
             8 
             9 *    Description : Count faces of a box.  
            10 *                   
            11 */ 
            12 
            13 // OpenCascade library. 
            14 #define WNT 
            15 #include <BRepPrimAPI_MakeBox.hxx> 
            16 #include <TopExp_Explorer.hxx> 
            17 #pragma comment(lib, "TKernel.lib"
            18 #pragma comment(lib, "TKMath.lib"
            19 #pragma comment(lib, "TKBRep.lib"
            20 #pragma comment(lib, "TKTopAlgo.lib"
            21 #pragma comment(lib, "TKPrim.lib"
            22 
            23 int main(void
            24 
            25     Standard_Integer nFaceCount = 0
            26     TopoDS_Shape aBox = BRepPrimAPI_MakeBox(100150200); 
            27 
            28     for (TopExp_Explorer faceExp(aBox, TopAbs_FACE); faceExp.More(); faceExp.Next()) 
            29     { 
            30         nFaceCount++
            31     } 
            32 
            33     std::cout << "The box has " << nFaceCount << " faces." << std::endl; 
            34 
            35     return 0
            36 

            程序輸出結(jié)果為:

            1 The box has 6 faces. 

             

            2. 反向訪問(wèn)

             1 /*
             2 *    Copyright (c) 2013 eryar All Rights Reserved.
             3 *
             4 *        File    : Main.cpp
             5 *        Author  : eryar@163.com
             6 *        Date    : 2013-09-21 11:58
             7 *        Version : 1.0v
             8 *
             9 *    Description : Demonstrate how to access parent and child topology data
            10 *       for a given topology shape.
            11 *                  
            12 */
            13 
            14 // OpenCascade library.
            15 #define WNT
            16 #include <BRepPrimAPI_MakeBox.hxx>
            17 #include <TopExp_Explorer.hxx>
            18 #include <TopoDS.hxx>
            19 #include <TopExp.hxx>
            20 #include <TopTools_ListOfShape.hxx>
            21 #include <TopTools_ListIteratorOfListOfShape.hxx>
            22 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
            23 
            24 #pragma comment(lib, "TKernel.lib")
            25 #pragma comment(lib, "TKMath.lib")
            26 #pragma comment(lib, "TKBRep.lib")
            27 #pragma comment(lib, "TKTopAlgo.lib")
            28 #pragma comment(lib, "TKPrim.lib")
            29 
            30 void dumpVertex(const TopoDS_Vertex& vertex)
            31 {
            32     gp_Pnt pnt = BRep_Tool::Pnt(vertex);
            33 
            34     std::cout << "(" << pnt.X() << "" << pnt.Y() << "" << pnt.Z() << ")" << std::endl;
            35 }
            36 
            37 int main(void)
            38 {
            39     Standard_Integer nCount = 0;
            40     TopoDS_Shape aBox = BRepPrimAPI_MakeBox(100150200);
            41 
            42     TopTools_IndexedDataMapOfShapeListOfShape shapeMap;
            43     TopTools_ListOfShape edges;
            44     TopTools_ListIteratorOfListOfShape edgeItr;
            45 
            46     // Use TopExp_Explorer to access subshapes.
            47     TopExp_Explorer vertexExp(aBox, TopAbs_VERTEX);
            48 
            49     const TopoDS_Vertex& aVertex = TopoDS::Vertex(vertexExp.Current());
            50 
            51     // Use TopExp::MapShapesAndAncestors() to access parent shapes.
            52     TopExp::MapShapesAndAncestors(aBox, TopAbs_VERTEX, TopAbs_EDGE, shapeMap);
            53     
            54     edges = shapeMap.FindFromKey(aVertex);
            55 
            56     dumpVertex(aVertex);
            57 
            58     for (edgeItr.Initialize(edges); edgeItr.More(); edgeItr.Next() )
            59     {
            60         const TopoDS_Edge& anEdge = TopoDS::Edge(edgeItr.Value());
            61 
            62         std::cout << "Vertex belong to the Edge: " << std::endl;
            63         dumpVertex(TopExp::FirstVertex(anEdge));
            64         dumpVertex(TopExp::LastVertex(anEdge));
            65         std::cout << "---------------------------" << std::endl;
            66     }
            67 
            68     return 0;
            69 }

            程序輸出結(jié)果:

             1 (00200)
             2 Vertex belong to the Edge:
             3 (000)
             4 (00200)
             5 ---------------------------
             6 Vertex belong to the Edge:
             7 (00200)
             8 (0150200)
             9 ---------------------------
            10 Vertex belong to the Edge:
            11 (00200)
            12 (1000200)
            13 ---------------------------
            14 Vertex belong to the Edge:
            15 (000)
            16 (00200)
            17 ---------------------------
            18 Vertex belong to the Edge:
            19 (00200)
            20 (0150200)
            21 ---------------------------
            22 Vertex belong to the Edge:
            23 (00200)
            24 (1000200)
            25 ---------------------------
            26 Press any key to continue . . .

             

            五、結(jié)論 Conclusion

            OpenCascade中的拓樸關(guān)系不像ACIS中那樣直接,但是也提供了向下訪問(wèn)子形狀、向上訪問(wèn)父形狀的類(lèi)和函數(shù),使用起來(lái)要涉及到好幾個(gè)類(lèi),不是很方便。

            當(dāng)向上訪問(wèn)與頂點(diǎn)相連接的邊時(shí),有重復(fù)數(shù)據(jù)。

             

            六、參考資料 References

            1. Roman Lygin, OpenCascade notes, opencascade.blogspot.com

            2. 詹海生等, 基于ACIS的幾何造型技術(shù)與系統(tǒng)開(kāi)發(fā), 清華大學(xué)出版社, 2002

            3. 孫家廣等. 計(jì)算機(jī)圖形學(xué). 清華大學(xué)出版社

            4. OpenCascade source code.

             

            Feedback

            # re: Topology and Geometry in OpenCascade-Topology  回復(fù)  更多評(píng)論   

            2013-09-22 18:18 by eryar
            共同學(xué)習(xí),,@大島小柚子

            # re: Topology and Geometry in OpenCascade-Topology  回復(fù)  更多評(píng)論   

            2013-09-22 15:52 by 大島小柚子
            感謝分享。
            一本大道久久香蕉成人网| 亚洲精品97久久中文字幕无码| 欧美黑人激情性久久| 久久综合丁香激情久久| 久久亚洲sm情趣捆绑调教| 亚洲国产二区三区久久| 国产精品99久久久久久www| 乱亲女H秽乱长久久久| 亚洲国产成人久久精品99| 久久99精品国产自在现线小黄鸭| 亚洲国产精品18久久久久久| 久久青青草原精品国产软件| 色综合久久中文综合网| 亚洲精品乱码久久久久66| 人妻丰满?V无码久久不卡| 亚洲熟妇无码另类久久久| 99久久婷婷免费国产综合精品| 精品免费tv久久久久久久| 91久久精品无码一区二区毛片| 亚洲精品高清国产一线久久 | 99久久99久久久精品齐齐| 色播久久人人爽人人爽人人片AV| 久久人人爽人人精品视频| 99热都是精品久久久久久| 国产女人aaa级久久久级| 国产精品久久国产精品99盘 | 亚洲AV日韩精品久久久久久| 国产高潮久久免费观看| 日本免费久久久久久久网站| 日韩精品久久无码人妻中文字幕| 久久免费的精品国产V∧| 久久精品视频网| 久久综合久久性久99毛片| 亚洲а∨天堂久久精品| 欧美麻豆久久久久久中文| 青青草原综合久久大伊人| 久久亚洲AV成人出白浆无码国产| 国产婷婷成人久久Av免费高清| 国产一区二区三区久久| 人妻系列无码专区久久五月天| 亚洲AV伊人久久青青草原|