Topology and Geometry in OpenCascade-Edge
摘要Abstract:本文簡要介紹了幾何造型中的邊界表示法(BRep),并結合程序說明OpenCascade中的邊界表示的具體實現,即拓樸與幾何的聯系。對具有幾何信息的拓樸結構頂點(vertex)、邊(edge)、面(face)進行了詳細說明。本文只對拓樸邊數據進行說明,著重介紹了OpenCascade中兩個種特別的邊縫合邊(seam edge)和退化邊(degenerated edge)。?
關鍵字Key Words:OpenCascade、BRep、Topology、Edge、Geometry
一、引言 Introduction
邊(Edge)是兩個鄰面(對正則形體而言)或多個鄰面(對非正則形體而言)的交集。邊有方向,它由起始頂點和終止頂點來界定;邊的形狀由邊的幾何信息來表示,可以是直線,也可以是曲線,曲線邊可用一系列控制點或型值點來描述,也可以用顯示、隱式或參數方程來描述。?
邊(Edge)是邊界表示法中的重要結構,因為邊界表示法(BRep)是用形體的邊界來描述形體的一種方法。BRep認為形體是由有限數量的邊界表面(平面或曲面)構成,而每個表面又由若干邊界邊與頂點構成,所有的單元面構成了形體的邊界,形體的邊界將形體和周圍的環境分隔開來。?
邊界表示法不僅詳細記錄了構成形體的面、邊方程的系數和頂點坐標值的幾何信息,而且描述了這些幾何元素之間的拓樸信息,即體、面、邊、頂點的組成關系等。在保證對形體面的定義確定并且無二義性的前提下,它允許根據形體的拓樸結構、面表示的方便性等因素確定一個面是以一個整體表示,還是以幾個部分之和進行表示。?
在OpenCascade中邊包含了一系列的曲線,其結構如下圖所示:?
Figure 1.1 BRep_TEdge members?
其中,包含一系列的曲線由下面幾種:?
Figure 1.2 BRep_CurveRepresentation class diagram?
二、邊 Edge
邊(edge)是對應于一維對象-曲線的拓樸實體。邊可以是面的邊界(如長方體的12條邊之一);也可以只是一條不屬于任何面的“懸空”邊(floating edge),想像一下在構建錐形體或掃掠體之前的輪廓線;面的邊可以被兩個或更多面共享,或者只屬于一個面。如下圖所示:?
Figure 2.1 Model used to illustrate Edge?
在上圖中用不同的顏色將不同類型的邊區別開來:?
l 紅色:不屬于任何面的懸空邊(floating edge);?
l 綠色:只屬于一個面的自由邊(free edge);?
l 黃色:屬于兩個或多個面的共享邊(shared edge);?
邊Edge包含幾種幾何表示:?
n 三維空間中的曲線C(t),由Geom_Curve實現。這是邊的基本表示方式;?
n 曲線P(t)為二維空間的參數曲線,用來表示屬于面的邊,通常被稱為pcurves,由類Geom2d_Curve實現;?
n 多段線(Polygonal)由一組三維點表示,且由類Poly_Polygon3D實現。?
n 多段線(Polygonal)也可由一組三角剖分面上點的索引來表示,且由類Poly_PolygonOnTriangulation實現。?
他們的表示都可以使用前面提到的類BRep_Tool來獲取。例如:?
Standard_Real aFirst, aLast, aPFirst, aPLast;
Handle(Geom_Curve) aCurve3d
=
BRep_Tool::Curve (anEdge, aFirst, aLast);
Handle(Geom2d_Curve) aPCurve
= BRep_Tool::CurveOnSurface (anEdge, aFace, aPFirst, aPLast);
邊必須有曲面上的參數曲線(pcurves),除了平面以外。邊中所有曲線必須一致,即朝向相同。這樣邊上的點可以使用任意表示方式計算得到,如曲線C(t),可以用[first, last]區間上的t來計算;也可根據u在區間[first1, last1]上取得曲面S1(P1x(u), P1y(u))上的點Pi,這里Pi是曲面Si上的參數曲線pcurve上的一點。?
1. 邊的標志位 Edge Flags?
邊中的標志位有三種:
static
const
Standard_Integer ParameterMask =
1
;
static
const
Standard_Integer RangeMask =
2
;
static
const
Standard_Integer DegeneratedMask =
4
;
這里對前兩種標志位進行說明:?
l RangeMask “same range”:(BRep_Tool::SameRange())取值區間相同,即幾何表示的曲線參數取值區間相同;?
l ParameterMask “same parameter”:(BRep_Tool::SameParameter())參數相同,即當C(t)=S1(P1x(t), P1y(t))時,對于同樣的參數t,C(t)和曲面S1上的點P1(t)相同。即任何邊上的點都對應參數曲線上相同的參數值。?
許多算法假定設置了這兩個標志位,因此建議你注意這種情況,一定要設置這些標志位。?
2. 邊的容差 Tolerance?
邊的容差(Tolerance)是其三維曲線和其他任何表示方式之間的最大偏差。其幾何意義就是以容差為半徑沿邊的一個包含邊的三維曲線及其他任何形式表示的管子。如下圖所示:?
Figure 2.2 Edge Tolerance?
3. 特殊類型的邊 Special edge types?
在OpenCascade有兩種特別類型的邊,他們是:?
l 縫合邊(seam edge):即在同一個面上出現兩次的邊(如:在同一個面上具有2個參數曲線);?
l 退化邊(degenerated edge):這種邊位于曲面的奇異點處,在三維空間中退化為一個點;?
球面中這兩種類型的邊都有。縫合邊位于經線(U iso-lines),參數為0和2*PI。退化邊位于南北極點,對應于緯線(V iso-lines),參數為-PI/2和PI/2。因為球面的參數方程為:?
當參數u取0和2*PI時,球面的參數方程計算如下:?
從計算結果可以看出,縫合邊是位于Dx和Dz所在平面上的半圓弧。
當參數v取-PI/2和PI/2時,球面的參數方程計算如下:?
從計算結果可以看出,曲面上的兩個邊分別退化為兩個點。即v取-PI/2和PI/2時球面的兩個退化邊分別位于南北極點上。如下圖所示:
Figure 2.3 seam edge and degenerated edge of sphere?
另外例子:環形體(torus)、圓柱體(cylinder)、圓錐體(cone)。環形體torus有兩條縫合邊(seam edge),對應于它的參數空間的邊界;圓柱體(cylinder)有一條縫合邊(seam edge)。圓錐(cone)頂點處為退化邊(degenerated edge)。?
檢查邊是否是縫化邊或退化邊,可以使用函數BRep_Tool::IsClosed()和BRep_Tool::Degenerated()。?
4. 邊的朝向?
邊的朝向為正向(forward edge orientation)意味著邊的邏輯方向與曲線的方向相同。反向(reversed)意味著邏輯方向與曲線方向相反。所以,縫合邊(seam-edge)在一個面中總是有兩個朝向:一個反向(reversed),一個正向(forward)。?
三、示例程序 Example Code?
以邊界表示BRep表示的球面為例,說明其邊的類型。程序代碼如下所示:
/*
* Copyright (c) 2013 eryar All Rights Reserved.
*
* File : Main.cpp
* Author : eryar@163.com
* Date : 2013-08-24 16:11
* Version : 1.0v
*
* Description : Demonstrate seam edge and degenerated edge of sphere.
*
*/
#include
<iostream>
//
OpenCascade Library.
#define
WNT
#include
<TopoDS.hxx>
#include
<TopoDS_Edge.hxx>
#include
<TopExp_Explorer.hxx>
#include
<BRepPrimAPI_MakeSphere.hxx>
#pragma
comment(lib, "TKernel.lib")
#pragma
comment(lib, "TKMath.lib")
#pragma
comment(lib, "TKBRep.lib")
#pragma
comment(lib, "TKPrim.lib")
#pragma
comment(lib, "TKTopAlgo.lib")
/*
*
* @breif Dump orientation types.
* Orientation definitaion:
* enum TopAbs_Orientation {
* TopAbs_FORWARD,
* TopAbs_REVERSED,
* TopAbs_INTERNAL,
* TopAbs_EXTERNAL
* };
*/
std::
string
dumpOrientation(
const
TopAbs_Orientation&
orient)
{
std::
string
strType;
switch
(orient)
{
case
TopAbs_FORWARD:
strType
=
"
TopAbs_FORWARD
"
;
break
;
case
TopAbs_REVERSED:
strType
=
"
TopAbs_REVERSED
"
;
break
;
case
TopAbs_INTERNAL:
strType
=
"
TopAbs_INTERNAL
"
;
break
;
case
TopAbs_EXTERNAL:
strType
=
"
TopAbs_EXTERNAL
"
;
break
;
}
return
strType;
}
/*
*
* @breif Dump edge information.
*/
void
processEdge(
const
TopoDS_Edge& edge,
const
TopoDS_Face&
face)
{
Standard_Real dTolerance
=
BRep_Tool::Tolerance(edge);
Standard_Boolean bIsGeometric
=
BRep_Tool::IsGeometric(edge);
Standard_Boolean bIsSameParameter
=
BRep_Tool::SameParameter(edge);
Standard_Boolean bIsSameRange
=
BRep_Tool::SameRange(edge);
Standard_Boolean bIsDegenerated
=
BRep_Tool::Degenerated(edge);
Standard_Boolean bIsClosed
=
BRep_Tool::IsClosed(edge, face);
TopAbs_Orientation nOrientation
=
edge.Orientation();
//
Dump edge info.
std::cout<<
"
====== Edge Info =======
"
<<
std::endl;
std::cout
<<
"
Tolerance:
"
<<dTolerance<<
std::endl;
std::cout
<<
"
Orientation:
"
<<dumpOrientation(nOrientation)<<
std::endl;
std::cout
<<
"
Geometric:
"
<<(bIsGeometric?
"
True
"
:
"
False
"
)<<
std::endl;
std::cout
<<
"
Same Parameter:
"
<<(bIsSameParameter?
"
True
"
:
"
False
"
)<<
std::endl;
std::cout
<<
"
Same Range:
"
<<(bIsSameRange?
"
True
"
:
"
False
"
)<<
std::endl;
std::cout
<<
"
Degenerated edge:
"
<<(bIsDegenerated?
"
True
"
:
"
False
"
)<<
std::endl;
std::cout
<<
"
Seam edge:
"
<<(bIsClosed?
"
True
"
:
"
False
"
)<<
std::endl;
//
Dump vertex of the edge.
for
(TopExp_Explorer vertexItr(edge, TopAbs_VERTEX);
vertexItr.More();
vertexItr.Next())
{
const
TopoDS_Vertex& aVertex =
TopoDS::Vertex(vertexItr.Current());
gp_Pnt pnt
=
BRep_Tool::Pnt(aVertex);
std::cout
<<
"
Vertex: (
"
<<pnt.X()<<
"
,
"
<<pnt.Y()<<
"
,
"
<<pnt.Z()<<
"
)
"
<<
std::endl;
}
}
int
main(
void
)
{
Standard_Integer nSphereFaceCount
=
0
;
Standard_Integer nSphereEdgeCount
=
0
;
TopoDS_Shape sphere
= BRepPrimAPI_MakeSphere(
1.0
);
for
(TopExp_Explorer faceItr(sphere, TopAbs_FACE);
faceItr.More();
faceItr.Next())
{
const
TopoDS_Face& aFace =
TopoDS::Face(faceItr.Current());
++
nSphereFaceCount;
for
(TopExp_Explorer edgeItr(aFace, TopAbs_EDGE);
edgeItr.More();
edgeItr.Next())
{
const
TopoDS_Edge& aEdge =
TopoDS::Edge(edgeItr.Current());
processEdge(aEdge, aFace);
++
nSphereEdgeCount;
}
}
std::cout
<<
"
Sphere face count:
"
<<nSphereFaceCount<<
std::endl;
std::cout
<<
"
Sphere edge count:
"
<<nSphereEdgeCount<<
std::endl;
return
0
;
}
程序運行結果如下所示:
====== Edge Info =======
Tolerance: 1e
-
007
Orientation: TopAbs_REVERSED
Geometric: True
Same Parameter: True
Same Range: True
Degenerated edge: True
Seam edge: False
Vertex: (
6.12323e-017
, -
1.49976e-032
,
1
)
Vertex: (
6.12323e-017
, -
1.49976e-032
,
1
)
====== Edge Info =======
Tolerance: 1e
-
007
Orientation: TopAbs_FORWARD
Geometric: True
Same Parameter: True
Same Range: True
Degenerated edge: False
Seam edge: True
Vertex: (
6.12323e-017
, -
1.49976e-032
,
1
)
Vertex: (
6.12323e-017
, -
1.49976e-032
, -
1
)
====== Edge Info =======
Tolerance: 1e
-
007
Orientation: TopAbs_FORWARD
Geometric: True
Same Parameter: True
Same Range: True
Degenerated edge: True
Seam edge: False
Vertex: (
6.12323e-017
, -
1.49976e-032
, -
1
)
Vertex: (
6.12323e-017
, -
1.49976e-032
, -
1
)
====== Edge Info =======
Tolerance: 1e
-
007
Orientation: TopAbs_REVERSED
Geometric: True
Same Parameter: True
Same Range: True
Degenerated edge: False
Seam edge: True
Vertex: (
6.12323e-017
, -
1.49976e-032
,
1
)
Vertex: (
6.12323e-017
, -
1.49976e-032
, -
1
)
Sphere face count:
1
Sphere edge count:
4
Press any key to
continue
. . .
從運行結果可以看,當球的邊為退化邊時,邊的兩個頂點的坐標值相同。退化邊位于球的南北極點上。縫合邊為連接兩個退化邊的曲線。?
根據遍歷順序,?
第一條邊為退化邊(degenerated edge),其朝向為反向(reversed);?
第二條邊為縫合邊(seam-edge),其朝向為正向(forward);?
第三條邊為退化邊,其朝向為正向(forward);?
第四條邊為縫合邊,其朝向為反向(reversed)。?
由上可見,縫合邊有兩個朝向,一個正向一個反向。?
四、結論 Conclusion?
對與幾何相關的拓樸邊(edge)的類的屬性數據進行詳細說明。并結合程序代碼詳細說明邊的標志位(myFlags)屬性的意義,從參數方程出發,理解縫合邊(seam-edge)和退化邊(degenerated edge),即標志位中DegeneratedMask的意義。?
五、參考資料?
1. Roman Lygin, OpenCascade notes, opencascade.blogspot.com?
2. 孫家廣等. 計算機圖形學. 清華大學出版社?
3. OpenCascade source code.?
?
PDF Version: Topology and Geometry in OpenCascade-Edge
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元

