Topology and Geometry in OpenCascade-Edge
Posted on 2013-08-24 20:38 eryar 閱讀(4987) 評論(2) 編輯 收藏 引用 所屬分類: 2.OpenCASCADETopology and Geometry in OpenCascade-Edge
摘要Abstract:本文簡要介紹了幾何造型中的邊界表示法(BRep),并結(jié)合程序說明OpenCascade中的邊界表示的具體實(shí)現(xiàn),即拓樸與幾何的聯(lián)系。對具有幾何信息的拓樸結(jié)構(gòu)頂點(diǎn)(vertex)、邊(edge)、面(face)進(jìn)行了詳細(xì)說明。本文只對拓樸邊數(shù)據(jù)進(jìn)行說明,著重介紹了OpenCascade中兩個(gè)種特別的邊縫合邊(seam edge)和退化邊(degenerated edge)。
關(guān)鍵字Key Words:OpenCascade、BRep、Topology、Edge、Geometry
一、引言 Introduction
邊(Edge)是兩個(gè)鄰面(對正則形體而言)或多個(gè)鄰面(對非正則形體而言)的交集。邊有方向,它由起始頂點(diǎn)和終止頂點(diǎn)來界定;邊的形狀由邊的幾何信息來表示,可以是直線,也可以是曲線,曲線邊可用一系列控制點(diǎn)或型值點(diǎn)來描述,也可以用顯示、隱式或參數(shù)方程來描述。
邊(Edge)是邊界表示法中的重要結(jié)構(gòu),因?yàn)檫吔绫硎痉ǎ˙Rep)是用形體的邊界來描述形體的一種方法。BRep認(rèn)為形體是由有限數(shù)量的邊界表面(平面或曲面)構(gòu)成,而每個(gè)表面又由若干邊界邊與頂點(diǎn)構(gòu)成,所有的單元面構(gòu)成了形體的邊界,形體的邊界將形體和周圍的環(huán)境分隔開來。
邊界表示法不僅詳細(xì)記錄了構(gòu)成形體的面、邊方程的系數(shù)和頂點(diǎn)坐標(biāo)值的幾何信息,而且描述了這些幾何元素之間的拓樸信息,即體、面、邊、頂點(diǎn)的組成關(guān)系等。在保證對形體面的定義確定并且無二義性的前提下,它允許根據(jù)形體的拓樸結(jié)構(gòu)、面表示的方便性等因素確定一個(gè)面是以一個(gè)整體表示,還是以幾個(gè)部分之和進(jìn)行表示。
在OpenCascade中邊包含了一系列的曲線,其結(jié)構(gòu)如下圖所示:
Figure 1.1 BRep_TEdge members
其中,包含一系列的曲線由下面幾種:
Figure 1.2 BRep_CurveRepresentation class diagram
二、邊 Edge
邊(edge)是對應(yīng)于一維對象-曲線的拓樸實(shí)體。邊可以是面的邊界(如長方體的12條邊之一);也可以只是一條不屬于任何面的“懸空”邊(floating edge),想像一下在構(gòu)建錐形體或掃掠體之前的輪廓線;面的邊可以被兩個(gè)或更多面共享,或者只屬于一個(gè)面。如下圖所示:
Figure 2.1 Model used to illustrate Edge
在上圖中用不同的顏色將不同類型的邊區(qū)別開來:
l 紅色:不屬于任何面的懸空邊(floating edge);
l 綠色:只屬于一個(gè)面的自由邊(free edge);
l 黃色:屬于兩個(gè)或多個(gè)面的共享邊(shared edge);
邊Edge包含幾種幾何表示:
n 三維空間中的曲線C(t),由Geom_Curve實(shí)現(xiàn)。這是邊的基本表示方式;
n 曲線P(t)為二維空間的參數(shù)曲線,用來表示屬于面的邊,通常被稱為pcurves,由類Geom2d_Curve實(shí)現(xiàn);
n 多段線(Polygonal)由一組三維點(diǎn)表示,且由類Poly_Polygon3D實(shí)現(xiàn)。
n 多段線(Polygonal)也可由一組三角剖分面上點(diǎn)的索引來表示,且由類Poly_PolygonOnTriangulation實(shí)現(xiàn)。
他們的表示都可以使用前面提到的類BRep_Tool來獲取。例如:



邊必須有曲面上的參數(shù)曲線(pcurves),除了平面以外。邊中所有曲線必須一致,即朝向相同。這樣邊上的點(diǎn)可以使用任意表示方式計(jì)算得到,如曲線C(t),可以用[first, last]區(qū)間上的t來計(jì)算;也可根據(jù)u在區(qū)間[first1, last1]上取得曲面S1(P1x(u), P1y(u))上的點(diǎn)Pi,這里Pi是曲面Si上的參數(shù)曲線pcurve上的一點(diǎn)。
1. 邊的標(biāo)志位 Edge Flags
邊中的標(biāo)志位有三種:
2 static const Standard_Integer RangeMask = 2;
3 static const Standard_Integer DegeneratedMask = 4;
這里對前兩種標(biāo)志位進(jìn)行說明:
l RangeMask “same range”:(BRep_Tool::SameRange())取值區(qū)間相同,即幾何表示的曲線參數(shù)取值區(qū)間相同;
l ParameterMask “same parameter”:(BRep_Tool::SameParameter())參數(shù)相同,即當(dāng)C(t)=S1(P1x(t), P1y(t))時(shí),對于同樣的參數(shù)t,C(t)和曲面S1上的點(diǎn)P1(t)相同。即任何邊上的點(diǎn)都對應(yīng)參數(shù)曲線上相同的參數(shù)值。
許多算法假定設(shè)置了這兩個(gè)標(biāo)志位,因此建議你注意這種情況,一定要設(shè)置這些標(biāo)志位。
2. 邊的容差 Tolerance
邊的容差(Tolerance)是其三維曲線和其他任何表示方式之間的最大偏差。其幾何意義就是以容差為半徑沿邊的一個(gè)包含邊的三維曲線及其他任何形式表示的管子。如下圖所示:
Figure 2.2 Edge Tolerance
3. 特殊類型的邊 Special edge types
在OpenCascade有兩種特別類型的邊,他們是:
l 縫合邊(seam edge):即在同一個(gè)面上出現(xiàn)兩次的邊(如:在同一個(gè)面上具有2個(gè)參數(shù)曲線);
l 退化邊(degenerated edge):這種邊位于曲面的奇異點(diǎn)處,在三維空間中退化為一個(gè)點(diǎn);
球面中這兩種類型的邊都有??p合邊位于經(jīng)線(U iso-lines),參數(shù)為0和2*PI。退化邊位于南北極點(diǎn),對應(yīng)于緯線(V iso-lines),參數(shù)為-PI/2和PI/2。因?yàn)榍蛎娴膮?shù)方程為:
當(dāng)參數(shù)u取0和2*PI時(shí),球面的參數(shù)方程計(jì)算如下:
從計(jì)算結(jié)果可以看出,縫合邊是位于Dx和Dz所在平面上的半圓弧。
當(dāng)參數(shù)v取-PI/2和PI/2時(shí),球面的參數(shù)方程計(jì)算如下:
從計(jì)算結(jié)果可以看出,曲面上的兩個(gè)邊分別退化為兩個(gè)點(diǎn)。即v取-PI/2和PI/2時(shí)球面的兩個(gè)退化邊分別位于南北極點(diǎn)上。如下圖所示:
Figure 2.3 seam edge and degenerated edge of sphere
另外例子:環(huán)形體(torus)、圓柱體(cylinder)、圓錐體(cone)。環(huán)形體torus有兩條縫合邊(seam edge),對應(yīng)于它的參數(shù)空間的邊界;圓柱體(cylinder)有一條縫合邊(seam edge)。圓錐(cone)頂點(diǎn)處為退化邊(degenerated edge)。
檢查邊是否是縫化邊或退化邊,可以使用函數(shù)BRep_Tool::IsClosed()和BRep_Tool::Degenerated()。
4. 邊的朝向
邊的朝向?yàn)檎颍╢orward edge orientation)意味著邊的邏輯方向與曲線的方向相同。反向(reversed)意味著邏輯方向與曲線方向相反。所以,縫合邊(seam-edge)在一個(gè)面中總是有兩個(gè)朝向:一個(gè)反向(reversed),一個(gè)正向(forward)。
三、示例程序 Example Code
以邊界表示BRep表示的球面為例,說明其邊的類型。程序代碼如下所示:
2 * Copyright (c) 2013 eryar All Rights Reserved.
3 *
4 * File : Main.cpp
5 * Author : eryar@163.com
6 * Date : 2013-08-24 16:11
7 * Version : 1.0v
8 *
9 * Description : Demonstrate seam edge and degenerated edge of sphere.
10 *
11 */
12
13 #include <iostream>
14
15 // OpenCascade Library.
16 #define WNT
17 #include <TopoDS.hxx>
18 #include <TopoDS_Edge.hxx>
19 #include <TopExp_Explorer.hxx>
20 #include <BRepPrimAPI_MakeSphere.hxx>
21
22 #pragma comment(lib, "TKernel.lib")
23 #pragma comment(lib, "TKMath.lib")
24 #pragma comment(lib, "TKBRep.lib")
25 #pragma comment(lib, "TKPrim.lib")
26 #pragma comment(lib, "TKTopAlgo.lib")
27
28 /**
29 * @breif Dump orientation types.
30 * Orientation definitaion:
31 * enum TopAbs_Orientation {
32
33 * TopAbs_FORWARD,
34
35 * TopAbs_REVERSED,
36
37 * TopAbs_INTERNAL,
38
39 * TopAbs_EXTERNAL
40
41 * };
42 */
43 std::string dumpOrientation(const TopAbs_Orientation& orient)
44 {
45 std::string strType;
46
47 switch (orient)
48 {
49 case TopAbs_FORWARD:
50 strType = "TopAbs_FORWARD";
51 break;
52
53 case TopAbs_REVERSED:
54 strType = "TopAbs_REVERSED";
55 break;
56
57 case TopAbs_INTERNAL:
58 strType = "TopAbs_INTERNAL";
59 break;
60
61 case TopAbs_EXTERNAL:
62 strType = "TopAbs_EXTERNAL";
63 break;
64 }
65
66 return strType;
67 }
68
69 /**
70 * @breif Dump edge information.
71 */
72 void processEdge(const TopoDS_Edge& edge, const TopoDS_Face& face)
73 {
74 Standard_Real dTolerance = BRep_Tool::Tolerance(edge);
75
76 Standard_Boolean bIsGeometric = BRep_Tool::IsGeometric(edge);
77 Standard_Boolean bIsSameParameter = BRep_Tool::SameParameter(edge);
78 Standard_Boolean bIsSameRange = BRep_Tool::SameRange(edge);
79 Standard_Boolean bIsDegenerated = BRep_Tool::Degenerated(edge);
80 Standard_Boolean bIsClosed = BRep_Tool::IsClosed(edge, face);
81
82 TopAbs_Orientation nOrientation = edge.Orientation();
83
84 // Dump edge info.
85 std::cout<<"====== Edge Info ======="<<std::endl;
86 std::cout<<"Tolerance: "<<dTolerance<<std::endl;
87 std::cout<<"Orientation: "<<dumpOrientation(nOrientation)<<std::endl;
88 std::cout<<"Geometric: "<<(bIsGeometric?"True":"False")<<std::endl;
89 std::cout<<"Same Parameter: "<<(bIsSameParameter?"True":"False")<<std::endl;
90 std::cout<<"Same Range: "<<(bIsSameRange? "True":"False")<<std::endl;
91 std::cout<<"Degenerated edge: "<<(bIsDegenerated?"True":"False")<<std::endl;
92 std::cout<<"Seam edge: "<<(bIsClosed? "True":"False")<<std::endl;
93
94 // Dump vertex of the edge.
95 for (TopExp_Explorer vertexItr(edge, TopAbs_VERTEX);
96 vertexItr.More();
97 vertexItr.Next())
98 {
99 const TopoDS_Vertex& aVertex = TopoDS::Vertex(vertexItr.Current());
100 gp_Pnt pnt = BRep_Tool::Pnt(aVertex);
101
102 std::cout<<"Vertex: ("<<pnt.X()<<", "<<pnt.Y()<<", "<<pnt.Z()<<")"<<std::endl;
103 }
104 }
105
106 int main(void)
107 {
108 Standard_Integer nSphereFaceCount = 0;
109 Standard_Integer nSphereEdgeCount = 0;
110
111 TopoDS_Shape sphere = BRepPrimAPI_MakeSphere(1.0);
112
113 for (TopExp_Explorer faceItr(sphere, TopAbs_FACE);
114 faceItr.More();
115 faceItr.Next())
116 {
117 const TopoDS_Face& aFace = TopoDS::Face(faceItr.Current());
118
119 ++nSphereFaceCount;
120
121 for (TopExp_Explorer edgeItr(aFace, TopAbs_EDGE);
122 edgeItr.More();
123 edgeItr.Next())
124 {
125 const TopoDS_Edge& aEdge = TopoDS::Edge(edgeItr.Current());
126
127 processEdge(aEdge, aFace);
128
129 ++nSphereEdgeCount;
130 }
131 }
132
133 std::cout<<"Sphere face count: "<<nSphereFaceCount<<std::endl;
134 std::cout<<"Sphere edge count: "<<nSphereEdgeCount<<std::endl;
135
136 return 0;
137 }
程序運(yùn)行結(jié)果如下所示:
2 Tolerance: 1e-007
3 Orientation: TopAbs_REVERSED
4 Geometric: True
5 Same Parameter: True
6 Same Range: True
7 Degenerated edge: True
8 Seam edge: False
9 Vertex: (6.12323e-017, -1.49976e-032, 1)
10 Vertex: (6.12323e-017, -1.49976e-032, 1)
11 ====== Edge Info =======
12 Tolerance: 1e-007
13 Orientation: TopAbs_FORWARD
14 Geometric: True
15 Same Parameter: True
16 Same Range: True
17 Degenerated edge: False
18 Seam edge: True
19 Vertex: (6.12323e-017, -1.49976e-032, 1)
20 Vertex: (6.12323e-017, -1.49976e-032, -1)
21 ====== Edge Info =======
22 Tolerance: 1e-007
23 Orientation: TopAbs_FORWARD
24 Geometric: True
25 Same Parameter: True
26 Same Range: True
27 Degenerated edge: True
28 Seam edge: False
29 Vertex: (6.12323e-017, -1.49976e-032, -1)
30 Vertex: (6.12323e-017, -1.49976e-032, -1)
31 ====== Edge Info =======
32 Tolerance: 1e-007
33 Orientation: TopAbs_REVERSED
34 Geometric: True
35 Same Parameter: True
36 Same Range: True
37 Degenerated edge: False
38 Seam edge: True
39 Vertex: (6.12323e-017, -1.49976e-032, 1)
40 Vertex: (6.12323e-017, -1.49976e-032, -1)
41 Sphere face count: 1
42 Sphere edge count: 4
43 Press any key to continue . . .
從運(yùn)行結(jié)果可以看,當(dāng)球的邊為退化邊時(shí),邊的兩個(gè)頂點(diǎn)的坐標(biāo)值相同。退化邊位于球的南北極點(diǎn)上。縫合邊為連接兩個(gè)退化邊的曲線。
根據(jù)遍歷順序,
第一條邊為退化邊(degenerated edge),其朝向?yàn)榉聪颍╮eversed);
第二條邊為縫合邊(seam-edge),其朝向?yàn)檎颍╢orward);
第三條邊為退化邊,其朝向?yàn)檎颍╢orward);
第四條邊為縫合邊,其朝向?yàn)榉聪颍╮eversed)。
由上可見,縫合邊有兩個(gè)朝向,一個(gè)正向一個(gè)反向。
四、結(jié)論 Conclusion
對與幾何相關(guān)的拓樸邊(edge)的類的屬性數(shù)據(jù)進(jìn)行詳細(xì)說明。并結(jié)合程序代碼詳細(xì)說明邊的標(biāo)志位(myFlags)屬性的意義,從參數(shù)方程出發(fā),理解縫合邊(seam-edge)和退化邊(degenerated edge),即標(biāo)志位中DegeneratedMask的意義。
五、參考資料
1. Roman Lygin, OpenCascade notes, opencascade.blogspot.com
2. 孫家廣等. 計(jì)算機(jī)圖形學(xué). 清華大學(xué)出版社
3. OpenCascade source code.
PDF Version: Topology and Geometry in OpenCascade-Edge