Topology and Geometry in OpenCascade-Edge

简介: Topology and Geometry in OpenCascade-Edge eryar@163.com 摘要Abstract:本文简要介绍了几何造型中的边界表示法(BRep),并结合程序说明OpenCascade中的边界表示的具体实现,即拓朴与几何的联系。

Topology and Geometry in OpenCascade-Edge

eryar@163.com

摘要Abstract:本文简要介绍了几何造型中的边界表示法(BRep),并结合程序说明OpenCascade中的边界表示的具体实现,即拓朴与几何的联系。对具有几何信息的拓朴结构顶点(vertex)、边(edge)、面(face)进行了详细说明。本文只对拓朴边数据进行说明,着重介绍了OpenCascade中两个种特别的边缝合边(seam edge)和退化边(degenerated edge)。

关键字Key Words:OpenCascade、BRep、Topology、Edge、Geometry

一、引言 Introduction

边(Edge)是两个邻面(对正则形体而言)或多个邻面(对非正则形体而言)的交集。边有方向,它由起始顶点和终止顶点来界定;边的形状由边的几何信息来表示,可以是直线,也可以是曲线,曲线边可用一系列控制点或型值点来描述,也可以用显示、隐式或参数方程来描述。

边(Edge)是边界表示法中的重要结构,因为边界表示法(BRep)是用形体的边界来描述形体的一种方法。BRep认为形体是由有限数量的边界表面(平面或曲面)构成,而每个表面又由若干边界边与顶点构成,所有的单元面构成了形体的边界,形体的边界将形体和周围的环境分隔开来。

边界表示法不仅详细记录了构成形体的面、边方程的系数和顶点坐标值的几何信息,而且描述了这些几何元素之间的拓朴信息,即体、面、边、顶点的组成关系等。在保证对形体面的定义确定并且无二义性的前提下,它允许根据形体的拓朴结构、面表示的方便性等因素确定一个面是以一个整体表示,还是以几个部分之和进行表示。

在OpenCascade中边包含了一系列的曲线,其结构如下图所示:

wps_clip_image-4387

Figure 1.1 BRep_TEdge members

其中,包含一系列的曲线由下面几种:

wps_clip_image-601

Figure 1.2 BRep_CurveRepresentation class diagram

二、边 Edge

边(edge)是对应于一维对象-曲线的拓朴实体。边可以是面的边界(如长方体的12条边之一);也可以只是一条不属于任何面的“悬空”边(floating edge),想像一下在构建锥形体或扫掠体之前的轮廓线;面的边可以被两个或更多面共享,或者只属于一个面。如下图所示:

wps_clip_image-23008

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

边中的标志位有三种:

1  static   const  Standard_Integer ParameterMask        =   1
2  static   const  Standard_Integer RangeMask            =   2
3  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)是其三维曲线和其他任何表示方式之间的最大偏差。其几何意义就是以容差为半径沿边的一个包含边的三维曲线及其他任何形式表示的管子。如下图所示:

wps_clip_image-28483

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。因为球面的参数方程为:

wps_clip_image-17127

当参数u取0和2*PI时,球面的参数方程计算如下:

wps_clip_image-5507

从计算结果可以看出,缝合边是位于Dx和Dz所在平面上的半圆弧。

当参数v取-PI/2和PI/2时,球面的参数方程计算如下:

wps_clip_image-23112

从计算结果可以看出,曲面上的两个边分别退化为两个点。即v取-PI/2和PI/2时球面的两个退化边分别位于南北极点上。如下图所示:

wps_clip_image-9886

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表示的球面为例,说明其边的类型。程序代码如下所示:

  1  /*
  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  }


程序运行结果如下所示:

 1  ======  Edge Info  =======
 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  . . .


从运行结果可以看,当球的边为退化边时,边的两个顶点的坐标值相同。退化边位于球的南北极点上。缝合边为连接两个退化边的曲线。

根据遍历顺序,

第一条边为退化边(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.

 

目录
相关文章
265Echarts - GL 矢量场图(Flow on the cartesian)
265Echarts - GL 矢量场图(Flow on the cartesian)
81 0
|
C++ 算法
OpenCASCADE BRep Projection
OpenCASCADE BRep Projection eryar@163.com 一网友发邮件问我下图所示的效果如何在OpenCASCADE中实现,我的想法是先构造出螺旋线,再将螺旋线投影到面上。
1757 0
OpenCASCADE Make Primitives-Sphere
OpenCASCADE Make Primitives-Sphere eryar@163.com Abstract. The sphere is the simplest topology shape of the BRep structure.
1168 0
|
iOS开发 Ruby
OpenGL ES From the Ground Up, Part 3: Viewports in Perspective
SATURDAY, APRIL 25, 2009 OpenGL ES From the Ground Up, Part 3: Viewports in Perspective Now that you got a taste of how to draw...
1210 0
|
算法 数据可视化 Shell
Mesh Algorithm in OpenCascade
Mesh Algorithm in OpenCascade eryar@163.com Abstract. Rendering a generic surface is a two steps process: first, computing the points that will ...
1728 0
OpenCascade Primitives BRep - Sphere
OpenCascade Primitives BRep - Sphere eryar@163.com Abstract. BRep is short for Boundary Representation.
1119 0
|
Shell
OpenCascade Primitives BRep - Box
OpenCascade Primitives BRep - Box eryar@163.com Abstract. BRep is short for Boundary Representation.
1664 0
|
算法 图形学
Surface Normal Vector in OpenCascade
Surface Normal Vector in OpenCascade eryar@163.com 摘要Abstract:表面上某一点的法向量(Normal Vector)指的是在该点处与表面垂直的方向。
1382 0
|
算法 图形学 C++
Topology Shapes of OpenCascade BRep
Topology Shapes of OpenCascade BRep eryar@163.com 摘要Abstract:通过对OpenCascade中的BRep数据的读写,理解边界表示法的概念及实现。
1893 0
|
数据建模 BI
Geometry Surface of OpenCascade BRep
Geometry Surface of OpenCascade BRep eryar@163.com 摘要Abstract:几何曲面是参数表示的曲面 ,在边界表示中其数据存在于BRep_TFace中,BRep_TFace中不仅包括了几何曲线,还包含用于显示的离散几何信息,如三角剖分数据。
1309 0

热门文章

最新文章