# Geometry Surface of OpenCascade BRep

eryar@163.com

## 一、引言 Introduction

Figure 1.1 Topology data structure in OpenCascade

## 二、示例程序 Example Code

/*
*
*           File : Main.cpp
*         Author : eryar@163.com
*           Date : 2013-12-01 12:18
*        Version : 1.0v
*
*    Description : Demonstrate the geometry surface section
*                  of the BRep file of OpenCascade.
*       KeyWords : OpenCascade, BRep File, Geometry Surface
*
*/

#define WNT
#include <Geom_Plane.hxx>
#include <Geom_CylindricalSurface.hxx>
#include <Geom_ConicalSurface.hxx>
#include <Geom_SphericalSurface.hxx>
#include <Geom_ToroidalSurface.hxx>
#include <Geom_SurfaceOfLinearExtrusion.hxx>
#include <Geom_SurfaceOfRevolution.hxx>
#include <Geom_BezierSurface.hxx>
#include <Geom_BSplineSurface.hxx>
#include <Geom_RectangularTrimmedSurface.hxx>
#include <Geom_OffsetSurface.hxx>

#include <TColgp_Array2OfPnt.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <TColStd_Array2OfReal.hxx>
#include <TColStd_Array1OfInteger.hxx>

#include <GeomTools.hxx>
#include <Geom_Circle.hxx>

#pragma comment(lib, \"TKernel.lib\")
#pragma comment(lib, \"TKMath.lib\")
#pragma comment(lib, \"TKG3d.lib\")
#pragma comment(lib, \"TKGeomBase.lib\")

int main(void)
{
gp_Ax2 axis(gp_Pnt(1, 2, 3), gp::DZ());
std::ofstream dumpFile(\"geometrySurface.txt\");

// Surface record 1 - Plane.
// Example: 1 0 0 3 0 0 1 1 0 -0 -0 1 0
Handle_Geom_Plane thePlane = new Geom_Plane(gp_Pnt(0, 0, 3), gp_Dir(0, 0, 1));
GeomTools::Write(thePlane, dumpFile);
GeomTools::Dump(thePlane, dumpFile);
GeomTools::Write(thePlane, std::cout);
GeomTools::Dump(thePlane, std::cout);

// Surface record 2 - Cylinder.
// Example: 2 1 2 3 0 0 1 1 0 0 0 1 0 4
Handle_Geom_CylindricalSurface theCylinder = new Geom_CylindricalSurface(axis, 4.0);
GeomTools::Write(theCylinder, dumpFile);
GeomTools::Dump(theCylinder, dumpFile);
GeomTools::Write(theCylinder, std::cout);
GeomTools::Dump(theCylinder, std::cout);

// Surface record 3 - Cone.
// Example: 3 1 2 3 0 0 1 1 0 0 0 1 0 4
//          0.75
Handle_Geom_ConicalSurface theCone = new Geom_ConicalSurface(axis, 0.75, 4.0);
GeomTools::Write(theCone, dumpFile);
GeomTools::Dump(theCone, dumpFile);
GeomTools::Write(theCone, std::cout);
GeomTools::Dump(theCone, std::cout);

// Surface record 4 - Sphere.
// Example: 4 1 2 3 0 0 1 1 0 -0 -0 1 0 4
Handle_Geom_SphericalSurface theSphere = new Geom_SphericalSurface(axis, 4);
GeomTools::Write(theSphere, dumpFile);
GeomTools::Dump(theSphere, dumpFile);
GeomTools::Write(theSphere, std::cout);
GeomTools::Dump(theSphere, std::cout);

// Surface record 5 - Torus.
// Example: 5 1 2 3 0 0 1 1 0 -0 -0 1 0 8 4
Handle_Geom_ToroidalSurface theTorus = new Geom_ToroidalSurface(axis, 8, 4);
GeomTools::Write(theTorus, dumpFile);
GeomTools::Dump(theTorus, dumpFile);
GeomTools::Write(theTorus, std::cout);
GeomTools::Dump(theTorus, std::cout);

// Surface record 6 - Linear Extrusion.
// Example: 6 0 0.6 0.8
//          2 1 2 3 0 0 1 1 0 -0 -0 1 0 4
Handle_Geom_Circle baseCurve = new Geom_Circle(axis, 4.0);
Handle_Geom_SurfaceOfLinearExtrusion theExtrusion = new Geom_SurfaceOfLinearExtrusion(baseCurve, gp_Dir(0, 0.6, 0.8));
GeomTools::Write(theExtrusion, dumpFile);
GeomTools::Dump(theExtrusion, dumpFile);
GeomTools::Write(theExtrusion, std::cout);
GeomTools::Dump(theExtrusion, std::cout);

// Surface record 7 - Revolution Surface.
// Example: 7 -4 0 3 0 1 0
//          2 1 2 3 0 0 1 1 0 -0 -0 1 0 4
Handle_Geom_SurfaceOfRevolution theRevolution = new Geom_SurfaceOfRevolution(baseCurve, gp::OY());
theRevolution->SetLocation(gp_Pnt(-4, 0, 3));
GeomTools::Write(theRevolution, dumpFile);
GeomTools::Dump(theRevolution, dumpFile);
GeomTools::Write(theRevolution, std::cout);
GeomTools::Dump(theRevolution, std::cout);

// Surface record 8 - Bezier Surface.
// Example: 8 1 1 2 1 0 0 1  7 1 0 -4  10
//          0 1 -2  8 1 1 5  11
//          0 2 3  9 1 2 6  12
TColgp_Array2OfPnt poles(1, 3, 1, 2);
TColStd_Array2OfReal weights(1, 3, 1, 2);

poles.SetValue(1, 1, gp_Pnt(0, 0, 1));      weights.SetValue(1, 1, 7.0);
poles.SetValue(1, 2, gp_Pnt(1, 0, -4));     weights.SetValue(1, 2, 10.0);

poles.SetValue(2, 1, gp_Pnt(0, 1, -2));     weights.SetValue(2, 1, 8.0);
poles.SetValue(2, 2, gp_Pnt(1, 1, 5));      weights.SetValue(2, 2, 11.0);

poles.SetValue(3, 1, gp_Pnt(0, 2, 3));      weights.SetValue(3, 1, 9.0);
poles.SetValue(3, 2, gp_Pnt(1, 2, 6));      weights.SetValue(3, 2, 12.0);

Handle_Geom_BezierSurface theBezierSurface = new Geom_BezierSurface(poles, weights);
GeomTools::Write(theBezierSurface, dumpFile);
GeomTools::Dump(theBezierSurface, dumpFile);
GeomTools::Write(theBezierSurface, std::cout);
GeomTools::Dump(theBezierSurface, std::cout);

// Surface record 9 - B-spline Surface.
// Example: 9 1 1 0 0 1 1 3 2 5 4 0 0 1  7 1 0 -4  10
//          0 1 -2  8 1 1 5  11
//          0 2 3  9 1 2 6  12
//
//          0 1
//          0.25 1
//          0.5 1
//          0.75 1
//          1 1
//
//          0 1
//          0.3 1
//          0.7 1
//          1 1
Standard_Integer uDegree = 1;
Standard_Integer vDegree = 1;
Standard_Boolean uPeriodic = Standard_False;
Standard_Boolean vPeriodic = Standard_False;

TColStd_Array1OfReal uKnots(1, 5);
TColStd_Array1OfReal vKnots(1, 4);
TColStd_Array1OfInteger uMults(1, 5);
TColStd_Array1OfInteger vMults(1, 4);

uKnots.SetValue(1, 0);
uKnots.SetValue(2, 0.25);
uKnots.SetValue(3, 0.5);
uKnots.SetValue(4, 0.75);
uKnots.SetValue(5, 1.0);

vKnots.SetValue(1, 0);
vKnots.SetValue(2, 0.3);
vKnots.SetValue(3, 0.7);
vKnots.SetValue(4, 1.0);

// Multiplicity of u and v are 1.
uMults.Init(1);
vMults.Init(1);

Handle_Geom_BSplineSurface theBSplineSurface = new Geom_BSplineSurface(poles, weights, uKnots, vKnots, uMults, vMults, uDegree, vDegree, uPeriodic, vPeriodic);
GeomTools::Write(theBSplineSurface, dumpFile);
GeomTools::Dump(theBSplineSurface, dumpFile);
GeomTools::Write(theBSplineSurface, std::cout);
GeomTools::Dump(theBSplineSurface, std::cout);

// Surface record 10 - Rectangular Trim Surface.
// Example: 10 -1 2 -3 4
//          1 1 2 3 0 0 1 1 0 -0 -0 1 0
Handle_Geom_Plane baseSurface = new Geom_Plane(axis);
Handle_Geom_RectangularTrimmedSurface theTrimmedSurface = new Geom_RectangularTrimmedSurface(baseSurface, -1.0, 2.0, -3.0, 4.0);
GeomTools::Write(theTrimmedSurface, dumpFile);
GeomTools::Dump(theTrimmedSurface, dumpFile);
GeomTools::Write(theTrimmedSurface, std::cout);
GeomTools::Dump(theTrimmedSurface, std::cout);

// Surface record 11 - Offset Surface.
// Example: 11 -2
//          1 1 2 3 0 0 1 1 0 -0 -0 1 0
Handle_Geom_OffsetSurface theOffsetSurface = new Geom_OffsetSurface(baseSurface, -2.0);
GeomTools::Write(theOffsetSurface, dumpFile);
GeomTools::Dump(theOffsetSurface, dumpFile);
GeomTools::Write(theOffsetSurface, std::cout);
GeomTools::Dump(theOffsetSurface, std::cout);

return 0;
}

1 0 0 3 0 0 1 1 0 -0 -0 1 0
Plane
Origin :0, 0, 3
Axis   :0, 0, 1
XAxis  :1, 0, -0
YAxis  :-0, 1, 0

2 1 2 3 0 0 1 1 0 -0 -0 1 0 4
CylindricalSurface
Origin :1, 2, 3
Axis   :0, 0, 1
XAxis  :1, 0, -0
YAxis  :-0, 1, 0

3 1 2 3 0 0 1 1 0 -0 -0 1 0 4
0.75
ConicalSurface
Origin :1, 2, 3
Axis   :0, 0, 1
XAxis  :1, 0, -0
YAxis  :-0, 1, 0

Angle :0.75

4 1 2 3 0 0 1 1 0 -0 -0 1 0 4
SphericalSurface
Center :1, 2, 3
Axis   :0, 0, 1
XAxis  :1, 0, -0
YAxis  :-0, 1, 0

5 1 2 3 0 0 1 1 0 -0 -0 1 0 8 4
ToroidalSurface
Origin :1, 2, 3
Axis   :0, 0, 1
XAxis  :1, 0, -0
YAxis  :-0, 1, 0

6 0 0.6 0.8
2 1 2 3 0 0 1 1 0 -0 -0 1 0 4
SurfaceOfLinearExtrusion
Direction :0, 0.6, 0.8
Basis curve :
Circle
Center :1, 2, 3
Axis   :0, 0, 1
XAxis  :1, 0, -0
YAxis  :-0, 1, 0

7 -4 0 3 0 1 0
2 1 2 3 0 0 1 1 0 -0 -0 1 0 4
SurfaceOfRevolution
Origin    :-4, 0, 3
Direction :0, 1, 0
Basis curve :
Circle
Center :1, 2, 3
Axis   :0, 0, 1
XAxis  :1, 0, -0
YAxis  :-0, 1, 0

8 1 1 2 1 0 0 1  7 1 0 -4  10
0 1 -2  8 1 1 5  11
0 2 3  9 1 2 6  12

BezierSurface urational vrational
Degrees :2 1
1,  1 : 0, 0, 1  7
1,  2 : 1, 0, -4  10

2,  1 : 0, 1, -2  8
2,  2 : 1, 1, 5  11

3,  1 : 0, 2, 3  9
3,  2 : 1, 2, 6  12

9 1 1 0 0 1 1 3 2 5 4 0 0 1  7 1 0 -4  10
0 1 -2  8 1 1 5  11
0 2 3  9 1 2 6  12

0 1
0.25 1
0.5 1
0.75 1
1 1

0 1
0.3 1
0.7 1
1 1

BSplineSurface urational vrational
Degrees :1 1
NbPoles :3 2
NbKnots :5 4
Poles :

1,  1 : 0, 0, 1  7
1,  2 : 1, 0, -4  10

2,  1 : 0, 1, -2  8
2,  2 : 1, 1, 5  11

3,  1 : 0, 2, 3  9
3,  2 : 1, 2, 6  12

UKnots :

1 : 0 1

2 : 0.25 1

3 : 0.5 1

4 : 0.75 1

5 : 1 1

VKnots :

1 : 0 1

2 : 0.3 1

3 : 0.7 1

4 : 1 1

10 -1 2 -3 4
1 1 2 3 0 0 1 1 0 -0 -0 1 0
RectangularTrimmedSurface
Parameters : -1 2 -3 4
BasisSurface :
Plane
Origin :1, 2, 3
Axis   :0, 0, 1
XAxis  :1, 0, -0
YAxis  :-0, 1, 0

11 -2
1 1 2 3 0 0 1 1 0 -0 -0 1 0
OffsetSurface
Offset : -2
BasisSurface :
Plane
Origin :1, 2, 3
Axis   :0, 0, 1
XAxis  :1, 0, -0
YAxis  :-0, 1, 0

## 三、程序说明 Example Description

#### 3.1 平面 Plane

// Surface record 1 - Plane.
// Example: 1 0 0 3 0 0 1 1 0 -0 -0 1 0
Handle_Geom_Plane thePlane = new Geom_Plane(gp_Pnt(0, 0, 3), gp_Dir(0, 0, 1));
GeomTools::Write(thePlane, dumpFile);
GeomTools::Dump(thePlane, dumpFile);

<surface record 1>定义了平面。平面数据包含三维点P和三维正交坐标系N，Du，Dv。平面通过点P，且其法向量为N。其参数方程如下所示：

#### 3.2 圆柱面 Cylinder

// Surface record 2 - Cylinder.
// Example: 2 1 2 3 0 0 1 1 0 0 0 1 0 4
Handle_Geom_CylindricalSurface theCylinder = new Geom_CylindricalSurface(axis, 4.0);
GeomTools::Write(theCylinder, dumpFile);
GeomTools::Dump(theCylinder, dumpFile);

<surface record 2>定义了圆柱面。圆柱面的数据包含三维点P，三维正交坐标系Dv，Dx，Dy和一个非负实数r。圆柱面的轴通过点P，方向为Dv，圆柱面的半径为r，其参数方程如下所示：

#### 3.3 圆锥面 Cone

// Surface record 3 - Cone.
// Example: 3 1 2 3 0 0 1 1 0 0 0 1 0 4
//          0.75
Handle_Geom_ConicalSurface theCone = new Geom_ConicalSurface(axis, 0.75, 4.0);
GeomTools::Write(theCone, dumpFile);
GeomTools::Dump(theCone, dumpFile);

<surface record 3>定义了圆锥面。圆锥面的数据包含三维点P，正交坐标系Dz，Dx，Dy，非负实数r和实数ψ（范围为（-π/2, π/2））。圆锥面通过点P且轴的方向为Dz。过点P且与方向Dx，Dy平行的平面为圆锥面的参考平面（referenced plane）。参考平面截圆锥面为一个圆，其半径为r。其参数方程如下所示：

#### 3.4 球面 Sphere

// Surface record 4 - Sphere.
// Example: 4 1 2 3 0 0 1 1 0 -0 -0 1 0 4
Handle_Geom_SphericalSurface theSphere = new Geom_SphericalSurface(axis, 4);
GeomTools::Write(theSphere, dumpFile);
GeomTools::Dump(theSphere, dumpFile);

<surface record 4>定义了球面。球面的数据包含三维点P，三维正交坐标系Dz，Dx，Dy和非负实数r。即球面的球心为点P，半径为r，其参数方程如下所示：

#### 3.5 圆环面 Torus

// Surface record 5 - Torus.
// Example: 5 1 2 3 0 0 1 1 0 -0 -0 1 0 8 4
Handle_Geom_ToroidalSurface theTorus = new Geom_ToroidalSurface(axis, 8, 4);
GeomTools::Write(theTorus, dumpFile);
GeomTools::Dump(theTorus, dumpFile);

<surface record 5>定义了圆环面。圆环面的数据包含三维点P，三维正交坐标系Dz，Dx，Dy和非负实数r1，r2。圆环面的轴通过点P，方向为Dz，r1是从圆环面的圆的中心到点P的距离，圆环面的圆的半径为r2。圆环面的参数方程如下所示：

#### 3.6 线性拉伸面 Linear Extrusion

// Surface record 6 - Linear Extrusion.
// Example: 6 0 0.6 0.8
//          2 1 2 3 0 0 1 1 0 -0 -0 1 0 4
Handle_Geom_Circle baseCurve = new Geom_Circle(axis, 4.0);
Handle_Geom_SurfaceOfLinearExtrusion theExtrusion = new Geom_SurfaceOfLinearExtrusion(baseCurve, gp_Dir(0, 0.6, 0.8));
GeomTools::Write(theExtrusion, dumpFile);
GeomTools::Dump(theExtrusion, dumpFile);

<surface record 6>定义了线性拉伸面。线性拉伸面的数据包含三维方向Dv和三维曲线<3D curve record>。其参数方程如下所示：

#### 3.7 旋转面 Revolution Surface

// Surface record 7 - Revolution Surface.
// Example: 7 -4 0 3 0 1 0
//          2 1 2 3 0 0 1 1 0 -0 -0 1 0 4
Handle_Geom_SurfaceOfRevolution theRevolution = new Geom_SurfaceOfRevolution(baseCurve, gp::OY());
theRevolution->SetLocation(gp_Pnt(-4, 0, 3));
GeomTools::Write(theRevolution, dumpFile);
GeomTools::Dump(theRevolution, dumpFile);

<surface record 7>定义了旋转面。旋转面的数据包含三维点P，三维方向D和三维曲线。旋转曲面的轴通过点P且方向为D，旋转曲线为C与旋转轴共面。旋转曲面的参数方程如下所示：

#### 3.8 Bezier曲面 Bezier Surface

// Surface record 8 - Bezier Surface.
// Example: 8 1 1 2 1 0 0 1  7 1 0 -4  10
//          0 1 -2  8 1 1 5  11
//          0 2 3  9 1 2 6  12
TColgp_Array2OfPnt poles(1, 3, 1, 2);
TColStd_Array2OfReal weights(1, 3, 1, 2);

poles.SetValue(1, 1, gp_Pnt(0, 0, 1));      weights.SetValue(1, 1, 7.0);
poles.SetValue(1, 2, gp_Pnt(1, 0, -4));     weights.SetValue(1, 2, 10.0);

poles.SetValue(2, 1, gp_Pnt(0, 1, -2));     weights.SetValue(2, 1, 8.0);
poles.SetValue(2, 2, gp_Pnt(1, 1, 5));      weights.SetValue(2, 2, 11.0);

poles.SetValue(3, 1, gp_Pnt(0, 2, 3));      weights.SetValue(3, 1, 9.0);
poles.SetValue(3, 2, gp_Pnt(1, 2, 6));      weights.SetValue(3, 2, 12.0);

Handle_Geom_BezierSurface theBezierSurface = new Geom_BezierSurface(poles, weights);
GeomTools::Write(theBezierSurface, dumpFile);
GeomTools::Dump(theBezierSurface, dumpFile);

<surface record 8>定义了Bezier曲面。曲面的数据包含u有理标志位ru，v有理标志位rv，曲面次数mu, mv，和weight poles。u,v的次数都不能大于25。

Bezier曲面的参数方程如下所示：

#### 3.9 B样条曲面 B-spline Surface

// Surface record 9 - B-spline Surface.
// Example: 9 1 1 0 0 1 1 3 2 5 4 0 0 1  7 1 0 -4  10
//          0 1 -2  8 1 1 5  11
//          0 2 3  9 1 2 6  12
//
//          0 1
//          0.25 1
//          0.5 1
//          0.75 1
//          1 1
//
//          0 1
//          0.3 1
//          0.7 1
//          1 1
Standard_Integer uDegree = 1;
Standard_Integer vDegree = 1;
Standard_Boolean uPeriodic = Standard_False;
Standard_Boolean vPeriodic = Standard_False;

TColStd_Array1OfReal uKnots(1, 5);
TColStd_Array1OfReal vKnots(1, 4);
TColStd_Array1OfInteger uMults(1, 5);
TColStd_Array1OfInteger vMults(1, 4);

uKnots.SetValue(1, 0);
uKnots.SetValue(2, 0.25);
uKnots.SetValue(3, 0.5);
uKnots.SetValue(4, 0.75);
uKnots.SetValue(5, 1.0);

vKnots.SetValue(1, 0);
vKnots.SetValue(2, 0.3);
vKnots.SetValue(3, 0.7);
vKnots.SetValue(4, 1.0);

// Multiplicity of u and v are 1.
uMults.Init(1);
vMults.Init(1);

Handle_Geom_BSplineSurface theBSplineSurface = new Geom_BSplineSurface(poles, weights, uKnots, vKnots, uMults, vMults, uDegree, vDegree, uPeriodic, vPeriodic);
GeomTools::Write(theBSplineSurface, dumpFile);
GeomTools::Dump(theBSplineSurface, dumpFile);

<surface record 9>定义了B-Spline曲面。B样条曲面数据包含u有理标志位ru，v有理标志位rv，u次数mu<=25；v次数mv<=25，u控制点数nu>=2，v控制点数nv>=2，u重节点数ku，v重节点数kn，weight poles，u重节点，v重节点。

u重节点及其重数有ku对：u1,q1,…,uku,qku。这里ui是重数为qi>=1的节点：

v重节点及其重数有kv对：u1,q1,…,ukv,qkv。这里vi是重数为qi>=1的节点：

B-Spline曲面的参数方程如下所示：

#### 3.10 矩形裁剪曲面 Rectangular Trim Surface

// Surface record 10 - Rectangular Trim Surface.
// Example: 10 -1 2 -3 4
//          1 1 2 3 0 0 1 1 0 -0 -0 1 0
Handle_Geom_Plane baseSurface = new Geom_Plane(axis);
Handle_Geom_RectangularTrimmedSurface theTrimmedSurface = new Geom_RectangularTrimmedSurface(baseSurface, -1.0, 2.0, -3.0, 4.0);
GeomTools::Write(theTrimmedSurface, dumpFile);
GeomTools::Dump(theTrimmedSurface, dumpFile);

<surface record 10>定义了矩形裁剪曲面。矩形裁剪曲面的数据包含实数umin，umax，vmin，vmax和一个曲面。矩形裁剪曲面是将曲面限制在矩形区域[umin，umax]x[vmin，vmax]内得到的曲面。曲面的参数方程如下所示：

#### 3.11 偏移曲面 Offset Surface

// Surface record 11 - Offset Surface.
// Example: 11 -2
//          1 1 2 3 0 0 1 1 0 -0 -0 1 0
Handle_Geom_OffsetSurface theOffsetSurface = new Geom_OffsetSurface(baseSurface, -2.0);
GeomTools::Write(theOffsetSurface, dumpFile);
GeomTools::Dump(theOffsetSurface, dumpFile);

<surface record 11>定义了偏移曲面。偏移曲面的数据包含偏移距离d和曲面。偏移曲面的就将基准曲面B没曲面的法向N上偏移距离d得到的曲面。偏移曲面的参数方程如下所示：

## 四、程序分析 Refactoring the Code

Figure 4.1 Class diagram of Geom_Surface

//=======================================================================
//function : PrintSurface
//purpose  :
//=======================================================================
void GeomTools_SurfaceSet::PrintSurface(const Handle(Geom_Surface)& S,
Standard_OStream& OS,
const Standard_Boolean compact)
{
Handle(Standard_Type) TheType = S->DynamicType();

if ( TheType ==  STANDARD_TYPE(Geom_Plane)) {
Print(Handle(Geom_Plane)::DownCast(S),OS,compact);
}
else if ( TheType ==  STANDARD_TYPE(Geom_CylindricalSurface)) {
Print(Handle(Geom_CylindricalSurface)::DownCast(S),OS,compact);
}
else if ( TheType ==  STANDARD_TYPE(Geom_ConicalSurface)) {
Print(Handle(Geom_ConicalSurface)::DownCast(S),OS,compact);
}
else if ( TheType ==  STANDARD_TYPE(Geom_SphericalSurface)) {
Print(Handle(Geom_SphericalSurface)::DownCast(S),OS,compact);
}
else if ( TheType ==  STANDARD_TYPE(Geom_ToroidalSurface)) {
Print(Handle(Geom_ToroidalSurface)::DownCast(S),OS,compact);
}
else if ( TheType ==  STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion)) {
Print(Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(S),OS,compact);
}
else if ( TheType ==  STANDARD_TYPE(Geom_SurfaceOfRevolution)) {
Print(Handle(Geom_SurfaceOfRevolution)::DownCast(S),OS,compact);
}
else if ( TheType ==  STANDARD_TYPE(Geom_BezierSurface)) {
Print(Handle(Geom_BezierSurface)::DownCast(S),OS,compact);
}
else if ( TheType ==  STANDARD_TYPE(Geom_BSplineSurface)) {
Print(Handle(Geom_BSplineSurface)::DownCast(S),OS,compact);
}
else if ( TheType ==  STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
Print(Handle(Geom_RectangularTrimmedSurface)::DownCast(S),OS,compact);
}
else if ( TheType ==  STANDARD_TYPE(Geom_OffsetSurface)) {
Print(Handle(Geom_OffsetSurface)::DownCast(S),OS,compact);
}
else {
GeomTools::GetUndefinedTypeHandler()->PrintSurface(S,OS,compact);
//if (!compact)
//  OS << \"***** Unknown Surface ********\\n\";
//else
//  cout << \"***** Unknown Surface ********\"<<endl;
}
}

//=======================================================================
//purpose  :
//=======================================================================
Handle(Geom_Surface)& S)
{
Standard_Integer stype;

try {
OCC_CATCH_SIGNALS
IS >> stype;
switch (stype) {

case PLANE :
{
Handle(Geom_Plane) SS;
IS >> SS;
S = SS;
}
break;

case CYLINDER :
{
Handle(Geom_CylindricalSurface) SS;
IS >> SS;
S = SS;
}
break;

case CONE :
{
Handle(Geom_ConicalSurface) SS;
IS >> SS;
S = SS;
}
break;

case SPHERE :
{
Handle(Geom_SphericalSurface) SS;
IS >> SS;
S = SS;
}
break;

case TORUS :
{
Handle(Geom_ToroidalSurface) SS;
IS >> SS;
S = SS;
}
break;

case LINEAREXTRUSION :
{
Handle(Geom_SurfaceOfLinearExtrusion) SS;
IS >> SS;
S = SS;
}
break;

case REVOLUTION :
{
Handle(Geom_SurfaceOfRevolution) SS;
IS >> SS;
S = SS;
}
break;

case BEZIER :
{
Handle(Geom_BezierSurface) SS;
IS >> SS;
S = SS;
}
break;

case BSPLINE :
{
Handle(Geom_BSplineSurface) SS;
IS >> SS;
S = SS;
}
break;

case RECTANGULAR :
{
Handle(Geom_RectangularTrimmedSurface) SS;
IS >> SS;
S = SS;
}
break;

case OFFSET :
{
Handle(Geom_OffsetSurface) SS;
IS >> SS;
S = SS;
}
break;

default :
{
Handle(Geom_Surface) SS;
S = SS;
}
break;
}
}
catch(Standard_Failure) {
#ifdef DEB
Handle(Standard_Failure) anExc = Standard_Failure::Caught();
cout <<\"EXCEPTION in GeomTools_SurfaceSet::ReadSurface(..)!!!\" << endl;
cout << anExc << endl;
#endif
S = NULL;
}
return IS;
}

## 五、结论 Conclusion

#### 六、参考资料 References

1. OpenCascade. BRep Format Description White Paper

2. Martin Fowler. Refactoring:Improving the Design of Existing Code. Addison-Wesley

3. Les Piegl, Wayne Tiller. The NURBS Book. Springer-Verlag