OpenCascade 边界表示法(BRep)
转自 http://www.cppblog.com/eryar/archive/2013/08/20/202678.html
Topology and Geometry in OpenCascade-Vertex
摘要Abstract:本文简要介绍了几何造型中的边界表示法(BRep),并结合程序说明OpenCascade中的边界表示的具体实现,即拓朴与几何的联系。对具有几何信息的拓朴结构顶点(vertex)、边(edge)、面(face)进行了详细说明。本文只对顶点数据进行说明。
关键字Key Words:OpenCascade、BRep、Topology、Geometry
一、引言 Introduction
边界表示(Boundary Representation)也称为BRep表示,它是几何造型中最成熟、无二义的表示法。实体的边界通常是由面的并集来表示,而每个面又由它所在的曲面的定义加上其边界来表示,面的边界是边的并集,而边又是由点来表示的。
边界表示的一个重要特征是描述形体的信息包括几何信息(Geometry)和拓朴信息(Topology)两个方面。拓朴信息描述形体上的顶点、边、面的连接关系,它形成物体边界表示的“骨架”。形体的几何信息犹如附着在“骨架”上的肌肉。例如,形体的某个面位于某一个曲面上,定义这一曲面方程的数据就是几何信息。此外,边的形状、顶点在三维空间中的位置(点的坐标)等都是几何信息,一般来说,几何信息描述形体的大小、尺寸、位置和形状等。
在边界表示法中,边界表示就按照体-面-环-边-点的层次,详细记录构成形体的所有几何元素的几何信息及其相互连接的拓朴关系。这样,在进行各种运算和操作中,就可以直接取得这些信息。
下图所示为由一条边连接的两个面组成的壳(shell):

Figure 1.1 Structure of a shell formed from two faces
上图所示的形状表示为TS, 面TF1和TF2,有七条边TE1~TE7和六个顶点TV1~TV6。
环TW1引用边TE1~TE4;环TW2引用TE4~TE7 。边引用的顶点如下:TE1(TV1,TV4),TE2(TV1,TV2),TE3(TV2,TV3),TE4(TV3,TV4),TE5(TV4,TV5),TE6(TV5,TV6),TE7(TV3,TV6)。

Figure 1.2 Data structure of the shell formed from two faces connected at an edge
注:OpenCascade中的这个数据结构中不包含“回溯引用(back references)”,即所有的引用只从复杂形状到简单形状。(Note that this data structure does not contain any “back references”. All references go from more comples underlying shapes to less complex ones.)有点有向图的意思。
二、OpenCascade中的边界表示 BRep in OpenCascade
2.1 拓朴结构 TopoDS_Shape data structure
OpenCascade中的拓朴(topology)是根据STEP标准ISO-10303-42设计的。也许读一下这个标准中的有关概念还是很有帮助的。STEP ISO-10303-42的相关资源:
http://www.steptools.com/support/stdev_docs/express/step_irs/index.html

Figure 2.1 Topology data structure in OpenCascade

TopoDS_Shape由值控制,包含三个成员变量:myLocation、myOrient、myTShape。

Figure 2.2 TopoDS_Shape member fields
2.2 拓朴与几何的联系 Connection with Geometry
现在我们来考虑一下拓朴结构与几何的关系。通过继承TopoDS包中的抽象的拓朴类实现了边界表示模型。如下图所示:

Figure 2.3 Topology data structure in OpenCascade
从上面的类图可以看出只有三种拓朴对象有几何表示数据:顶点(vertex)、边(edge)、面(face),分别为BRep_TVertex、BRep_TEdge、BRep_TFace。

Figure 2.4 TopoDS_TShape class diagram
三、顶点 Vertex
顶点(vertex)的位置用几何点(gp_Pnt)来表示。点是几何造型中的最基本元素,自由曲线、曲面或其他形体均可用有序的点集表示。用计算机存储、管理、输出形体的实质就是对点集及其连接关系的处理。在正则形体定义中,不允许孤立点存在。
顶点的另一个重要属性是容差(Tolerance),用来表示位置精度。顶点容差T的几何意义为以顶点为圆心半径为T的球。这个球必须包含所有与这个顶点相连的边的曲线的端点。

Figure 3.1 Vertex Tolerance
与其他几何库有全局精度(global precision)不同,OpenCascade把容差作为局部属性(local properties)。由图2.4可知,容差是顶点、边、面的属性。这种方法有助于用更一般的方式来描述高精度的模型。如下图所示:

Figure 3.2 Vertex with different tolerance
如果从底层来创建形状,最好的方法就是指定最小的允许误差。默认值Precision::Confusion()为1e-07。
下面讨论顶点的朝向(orientation)属性。它没有直接的几何意义,但是根据约定,若顶点的朝向属性值为TopAbs_FORWARD,它就必须与表示边的曲线的参数值小的端部匹配。相应地,TopAbs_REVERSED的顶点与参数值大的端部匹配。例如,有条边位于圆弧上,圆弧半径为1且在Z=0的平面上,起点为(1,0,0),向-Z轴向,曲线为逆时针方向。所以顶点(1,0,0)的朝向为TopAbs_FORWARD,顶点(0,1,0)的朝向为TopAbs_REVERSED。如下图所示:

Figure 3.3 Vertex Orientation attribute
实现上图所示的程序代码如下所示:
2 * Copyright (c) 2013 eryar All Rights Reserved.
3 *
4 * File : Main.cpp
5 * Author : eryar@163.com
6 * Date : 2013-08-17 21:46
7 * Version : 1.0v
8 *
9 * Description : Demonstrate how to build a edge bottom-up by BRepBuilderAPI_MakeEdge,
10 * and how to access vertex infomation by BRep_Tool.
11 *
12 */
13
14 // OpenCascade library.
15 #define WNT
16 #include <gp_Circ.hxx>
17 #include <GC_MakeArcOfCircle.hxx>
18
19 #include <TopoDS_Edge.hxx>
20 #include <BRep_Tool.hxx>
21 #include <BRepBuilderAPI_MakeEdge.hxx>
22 #include <BRepBuilderAPI_MakeVertex.hxx>
23
24 #pragma comment(lib, "TKernel.lib")
25 #pragma comment(lib, "TKMath.lib")
26 #pragma comment(lib, "TKBRep.lib")
27 #pragma comment(lib, "TKGeomBase.lib")
28 #pragma comment(lib, "TKTopAlgo.lib")
29
30 /**
31 * @breif Dump orientation types.
32 * Orientation definitaion:
33 * enum TopAbs_Orientation {
34
35 * TopAbs_FORWARD,
36
37 * TopAbs_REVERSED,
38
39 * TopAbs_INTERNAL,
40
41 * TopAbs_EXTERNAL
42
43 * };
44 */
45 std::string DumpOrientation(const TopAbs_Orientation& orient)
46 {
47 std::string strType;
48
49 switch (orient)
50 {
51 case TopAbs_FORWARD:
52 strType = "TopAbs_FORWARD";
53 break;
54
55 case TopAbs_REVERSED:
56 strType = "TopAbs_REVERSED";
57 break; 58 59 case TopAbs_INTERNAL: 60 strType = "TopAbs_INTERNAL"; 61 break; 62 63 case TopAbs_EXTERNAL: 64 strType = "TopAbs_EXTERNAL"; 65 break; 66 } 67 68 return strType; 69 } 70 71 /** 72 * @breif Dump attributes of the vertex. 73 */ 74 void DumpVertex(const TopoDS_Vertex& v) 75 { 76 gp_Pnt p = BRep_Tool::Pnt(v); 77 Standard_Real dTolerance = BRep_Tool::Tolerance(v); 78 79 std::cout<<"Vertex position: ("<<p.X()<<", "<<p.Y()<<", "<<p.Z()<<")"<<std::endl; 80 std::cout<<"Vertex Tolerance: "<<dTolerance<<std::endl; 81 std::cout<<"Vertex orientation: "<<DumpOrientation(v.Orientation())<<std::endl; 82 std::cout<<std::endl; 83 } 84 85 int main(int argc, char* argv[]) 86 { 87 gp_Circ circle; 88 TopoDS_Edge edge; 89 TopoDS_Vertex vertex1; 90 TopoDS_Vertex vertex2; 91 BRepBuilderAPI_MakeEdge edgeBuilder; 92 93 circle.SetRadius(1.0); 94 circle.SetAxis(gp::OZ()); 95 96 edgeBuilder.Init(GC_MakeArcOfCircle(circle, 0.0, M_PI/2.0, Standard_True)); 97 98 // Test single vertex. 99 /*vertex1 = BRepBuilderAPI_MakeVertex(gp_Pnt(100.0, 200.0, 300.0));100 vertex2 = BRepBuilderAPI_MakeVertex(gp_Pnt(500.0, 600.0, 700.0));101 102 std::cout<<"Single vetex test: "<<std::endl;103 104 std::cout<<"Vertex 1 attributes: "<<std::endl;105 DumpVertex(vertex1);106 107 std::cout<<"Vertex 2 attributes: "<<std::endl;108 DumpVertex(vertex2);*/109 110 edge = edgeBuilder.Edge();111 vertex1 = edgeBuilder.Vertex1();112 vertex2 = edgeBuilder.Vertex2();113 114 std::cout<<"Test vertex belong to edge:"<<std::endl;115 116 std::cout<<"Vertex 1 attributes: "<<std::endl;117 DumpVertex(vertex1);118 119 std::cout<<"Vertex 2 attributes: "<<std::endl;120 DumpVertex(vertex2);121 122 return 0;123 }
程序运行结果如下图所示:

Figure 3.4 Code example result
BRep_Builder是从底层创建拓朴结构的类。如下代码所示为从底层创建顶点的示例:
2
3 BRep_Builder aBuilder;
4
5 TopoDS_Vertex aVertex;
6
7 aBuilder.MakeVertex(aVertex, aPoint, Precision::Confusion());
8
9 aVertex.Orientation(TopAbs_REVERSED);
有一个方便的类也可用来创建顶点BRepBuilderAPI_MakeVertex,其内部也是使用了类BRep_Builder。所以,若想从底层创建拓朴结构,必须要熟悉BRep_Builder。
BRep_Tool是用来访问拓朴结构中几何信息的工具,他的大部分的函数是静态的。如下代码所示为获取顶点的容差和几何点的方法:
2
3 gp_Pnt aPoint = BRep_Tool::Pnt(aVertex);
4
四、BRep文件中Vertex的数据
结合《BRep Format Description White Paper》中对<vertex data>的描述,及程序代码中对顶点数据的读取,分析OpenCascade的BRep表示中的顶点。

Figure 4.1 NBF-like definition of Vertex
详细说明:
<vertex data representation u parameter>u的使用方法说明如下:
<vertex data representation data 1> 和参数u定义了三维曲线C上的点V的位置。参数u是曲线C上点V对应的参数:C(u)=V。
<vertex data representation data 2>和参数u定义了曲面上的二维曲线C上点V的位置。参数u是曲线C上点V对应的参数:C(u)=V。
<vertex data representation data 3>和参数u及<vertex data representation v parameter>v定义了曲面S上的点V:S(u,v)=V。
<vertex data tolerance>t定义如下所示:

读取Vertex部分的程序代码摘抄如下:
2 // vertex
3 //---------
4
5 case TopAbs_VERTEX :
6 {
7 TopoDS_Vertex& V = TopoDS::Vertex(S);
8
9 // Read the point geometry
10 IS >> tol;
11 IS >> X >> Y >> Z;
12 myBuilder.MakeVertex(V,gp_Pnt(X,Y,Z),tol);
13 Handle(BRep_TVertex) TV = Handle(BRep_TVertex)::DownCast(V.TShape());
14
15 BRep_ListOfPointRepresentation& lpr = TV->ChangePoints();
16 TopLoc_Location L;
17
18 do {
19 IS >> p1 >> val;
20
21 Handle(BRep_PointRepresentation) PR;
22 switch (val) {
23
24 case 1 :
25 {
26 IS >> c;
27
28 // Modified by Sergey KHROMOV - Wed Apr 24 13:59:09 2002 Begin
29 if (myCurves.Curve(c).IsNull())
30 break;
31 // Modified by Sergey KHROMOV - Wed Apr 24 13:59:13 2002 End
32
33 Handle(BRep_PointOnCurve) POC =
34 new BRep_PointOnCurve(p1,
35 myCurves.Curve(c),
36 L);
37 PR = POC;
38 }
39 break;
40
41 case 2 :
42 {
43 IS >> pc >> s;
44
45 // Modified by Sergey KHROMOV - Wed Apr 24 13:59:09 2002 Begin
46 if (myCurves2d.Curve2d(pc).IsNull() ||
47 mySurfaces.Surface(s).IsNull())
48 break;
49 // Modified by Sergey KHROMOV - Wed Apr 24 13:59:13 2002 End
50
51 Handle(BRep_PointOnCurveOnSurface) POC =
52 new BRep_PointOnCurveOnSurface(p1,
53 myCurves2d.Curve2d(pc),
54 mySurfaces.Surface(s),55 L);56 PR = POC;57 }58 break;59 60 case 3 :61 {62 IS >> p2 >> s;63 64 // Modified by Sergey KHROMOV - Wed Apr 24 13:59:09 2002 Begin65 if (mySurfaces.Surface(s).IsNull())66 break;67 // Modified by Sergey KHROMOV - Wed Apr 24 13:59:13 2002 End68 69 Handle(BRep_PointOnSurface) POC =70 new BRep_PointOnSurface(p1,p2,71 mySurfaces.Surface(s),72 L);73 PR = POC;74 }75 break;76 }77 78 if (val > 0) {79 IS >> l;80 if (!PR.IsNull()) {81 PR->Location(Locations().Location(l));82 lpr.Append(PR);83 }84 }85 } while (val > 0);86 }87 break;
从BRep文件中可知,大部分的Vertex只有如下数据:
2 *
3 Ve
4 1e-007
5 2 3 0
6 0 0
即只使用了BRep_Builder.MakeVertex()创建创建顶点(vertex),还可记录顶点的类型:
1. 若顶点在三维空间中的曲线上Geom_Curve,则记录三维曲线的索引号及参数u;
2. 若顶点在二维空间中的曲线上Geom2d_Curve,则记录二维曲线的索引号及参数u;
3. 若顶点在曲面上Geom_Surface,则记录曲面的索引号及参数(u,v);
五、结论 Conclusion
结合博客“OpenCascade notes”及《BRep format Description white
paper》对OpenCascade的拓朴结构中的顶点(vertex)的属性数据进行说明。结合程序说明了顶点的容差及朝向的意义及从底层创建顶点的方法。通过BRep_Tool的静态函数可以获取顶点的几何数据及其他属性。
发现在BRep文件中还对顶点进行了分类:三维曲线上的点、二维曲线上的点和曲面上的点。
六、参考资料
1. OpenCascade notes: opencascade.blogspot.com
2. 孙家广等. 计算机图形学. 清华大学出版社
OpenCascade 边界表示法(BRep)的更多相关文章
- OpenCASCADE PCurve of Topological Face
OpenCASCADE PCurve of Topological Face eryar@163.com Abstract. OpenCASCADE provides a class BRepBuil ...
- OpenCASCADE BRepTools
OpenCASCADE BRepTools eryar@163.com Abstract. OpenCASCADE BRepTools provides utilities for BRep data ...
- OpenCASCADE Make Primitives-Box
OpenCASCADE Make Primitives-Box eryar@163.com Abstract. By making a simple box to demonstrate the BR ...
- Topology and Geometry in OpenCascade-Face
Topology and Geometry in OpenCascade-Face eryar@163.com 摘要Abstract:本文简要介绍了几何造型中的边界表示法(BRep),并结合程序说明O ...
- OpenCASCADE BRep vs. OpenNURBS BRep
OpenCASCADE BRep vs. OpenNURBS BRep eryar@163.com Abstract. BRep short for Boundary Representation. ...
- OpenCascade Primitives BRep - Sphere
OpenCascade Primitives BRep - Sphere eryar@163.com Abstract. BRep is short for Boundary Representati ...
- OpenCascade Primitives BRep - Box
OpenCascade Primitives BRep - Box eryar@163.com Abstract. BRep is short for Boundary Representation. ...
- Topology Shapes of OpenCascade BRep
Topology Shapes of OpenCascade BRep eryar@163.com 摘要Abstract:通过对OpenCascade中的BRep数据的读写,理解边界表示法的概念及实现 ...
- Geometry Surface of OpenCascade BRep
Geometry Surface of OpenCascade BRep eryar@163.com 摘要Abstract:几何曲面是参数表示的曲面 ,在边界表示中其数据存在于BRep_TFace中, ...
随机推荐
- dubbo之启动时检查
启动时检查 Dubbo缺省会在启动时检查依赖的服务是否可用,不可用时会抛出异常,阻止Spring初始化完成,以便上线时,能及早发现问题,默认 check="true".所以可以通过 ...
- 三维重建5:场景中语义分析/语义SLAM/DCNN-大尺度SLAM
前言: 在实时/非实时大规模三维场景重建中,引入了语义SLAM这个概念,参考三维重建:SLAM的尺度和方法论问题和三维重建:SLAM的粒度和工程化问题 .大规模三维场景重建的尺度增大,因此相对于整个重 ...
- jquery的attr和prop
注意不同版本的attr和prop,attr适用于自定义dom值,prop适用于带有固有属性
- CorelDRAW图片导出变色,如何解决?
很多小伙伴反映说CDR颜色导出不准确,特别是CorelDRAW X4以及之前的版本,那么CDR导出变色的问题是怎么导致的,如何解决呢,本文小编分享一些自己的心得. 一:出现问题. 比如下面这个问题,明 ...
- 团体程序设计天梯赛-练习集-L1-045. 宇宙无敌大招呼
L1-045. 宇宙无敌大招呼 据说所有程序员学习的第一个程序都是在屏幕上输出一句“Hello World”,跟这个世界打个招呼.作为天梯赛中的程序员,你写的程序得高级一点,要能跟任意指定的星球打招呼 ...
- mongodb多实例部署
安装与管理MongoDB 1.安装解压源码包 [root@bogon ~]# tar xf mongodb-linux-x86_64-rhel70-4.0.6.tgz [root@bogon ~]# ...
- html 报告页面样式
修改了下HTML页面样式 页面代码 <!DOCTYPE html> <html lang="en"> <head> <meta chars ...
- appium滑动
在app应用日常使用过程中,会经常用到在屏幕滑动操作.如刷朋友圈上下滑操作.浏览图片左右滑动操作等.在自动化脚本该如何实现这些操作呢? 在Appium中模拟用户滑动操作需要使用swipe方法,该方法定 ...
- codeforces 466B Wonder Room(思维,暴力)
题目 参考了别人的博客,百度来的博客 #include<iostream> #include<string> #include<stdio.h> #include& ...
- C#第五节课
switch语句 using System;using System.Collections.Generic;using System.Linq;using System.Text;using Sys ...