OpenCasCade 教程-瓶子 (3)

来源:互联网 发布:java语言数字金字塔 编辑:程序博客网 时间:2024/05/22 04:50

4. 创建螺纹

 

4.1. 创建表面

到目前为止,你已经学习了如何创建3D曲线的边界。

接下来要学习创建2D的边界和表面。

这里要看如何从圆柱表面的2D曲线来生成螺旋。这个原理要比先前的东西更复杂一些,但在OCC中也是相当简单的。

第一步先用下面这2个参数创建圆柱表面:

一个坐标系

一个半径

 

用坐标系 neckAx2 来创建2个圆柱半径如下(下图):

 

 

Handle(Geom_CylindricalSurface) aCyl1 = new Geom_CylindricalSurface(neckAx2 , myNeckRadius * 0.99);

Handle(Geom_CylindricalSurface) aCyl2 = new Geom_CylindricalSurface(neckAx2 , myNeckRadius * 1.05);

 

 

 

4.2. 定义2D曲线

创建瓶子的瓶颈时已经创建了圆柱体和表面,现在创建螺纹需要在那个圆柱表面上创建2D曲线。

Geom_CylindricalSurface 类所表述的面是用下面这个等式描述的:

P(U , V) = O + R * (cos(U) * xDir + sin(U) * yDir) + V * zDir

 

P 由参数 (U, V) 决定的点。

• O , xDir, yDir zDir 是原点和xyz坐标轴。

• R 是圆柱的半径

• U 范围是 [0 , 2PI] V 可任意取值。

 

将几何图形参数化的好处是你只要有 uv 参数就可以计算出具体位置:

参数化等式还有另一个好处:你可以将一个表面像2D平面一样看待,(UV)坐标系:)

比如瓶颈的圆柱则可以看作成以下的平面:

 

 

假设在这个uv参数空间创建2D线,那么这个2D线在3D空间对应了一个曲线。

 

 

实例

方程

参数曲线

U = 0

P(V) = O + V * zDir

平行于 Z 轴的线

V = 0

P(U) = O + R * (cos(U) * xDir + sin(U) * yDir)

平行于xoy平面的圆

U != 0 V != 0

P(U , V) = O + R * (cos(U) * xDir + sin(U) * yDir) + V * zDir

盘旋在圆柱上的螺旋曲线

 

螺旋曲线就是我们所需的严格按照以下限制在圆柱表面演化出的瓶颈螺纹:

 

• V 的取值: 0 myHeighNeck 用以描述高度

 

• U 的取值: 0 2PI 用以描述角度. 也可以扩展uv坐标周期这样可以取值到4PI

 

 

(U , V) 参数平面创建本地坐标系 (X , Y) ,将创建的曲线放在这个坐标系内:

 

坐标系原点在圆柱的参数平面的中心 (2*PI, myNeckHeight / 2)

 

• X 轴定义为向量 (2*PI, myNeckHeight/4) ,

 

这里我们将再次使用gp这个基础几何图元库:

 

• 2D点用 gp_Pnt2d

 

• 2D向量用 gp_Dir2d 类。

 

定义2D 右手坐标系用 gp_Ax2d , 它是由坐标原点和一个方向决定

 

gp_Pnt2d aPnt(2. * PI , myNeckHeight / 2.);

gp_Dir2d aDir(2. * PI , myNeckHeight / 4.);

gp_Ax2d aAx2d(aPnt , aDir);

 

You will now define the curves. As previously mentioned, these thread profiles are computed on two cylindrical surfaces. In the following figure, curves on the left define the base (on aCyl1 surface) and the curves on the right define the top of the thread’s shape (on aCyl2 surface).

 

 

You have already used the Geom package to define 3D geometric entities. For 2D, you will use the Geom2d package. As for Geom, all geometries are parameterized. For example, a Geom2d_Ellipse ellipse is defined from:

 

 

a coordinate system whose origin is the ellipse center

 

• a major radius on the major axis defined by the X direction of the coordinate system

 

• a minor radius on the minor axis defined by the Y direction of the coordinate system

Supposing that:

 

• Both ellipses have the same major radius of 2*PI.

 

• Minor radius of the first ellipse is myNeckHeight / 10

 

• And minor radius value of the second ellipse is a fourth of the first one Your ellipses are defined as follows:

 

 

Standard_Real aMajor = 2. * PI;

Standard_Real aMinor = myNeckHeight / 10;

Handle(Geom2d_Ellipse) anEllipse1 = new Geom2d_Ellipse(aAx2d , aMajor , aMinor);

Handle(Geom2d_Ellipse) anEllipse2 = new Geom2d_Ellipse(aAx2d , aMajor , aMinor / 4);

 

To describe portions of curves for the arcs drawn above, you define Geom2d_TrimmedCurve trimmed curves out of the created ellipses and two parameters to limit them.

As the parametric equation of an ellipse is P(U) = O + (MajorRadius * cos(U) * XDirection) + (MinorRadius * sin(U) * YDirection), the ellipses are limited between 0 and PI.

 

Handle(Geom2d_TrimmedCurve) aArc1 = new Geom2d_TrimmedCurve(anEllipse1 , 0 , PI); Handle(Geom2d_TrimmedCurve) aArc2 = new Geom2d_TrimmedCurve(anEllipse2 , 0 , PI);

 

The last step consists in defining the segment, which is the same for the two profiles: a line limited by the first and the last point of one of the arcs.

To access the point corresponding to the parameter of a curve or a surface, you use the Value or D0 method (meaning 0th derivative), D1 method is for first derivative, D2 for the second.

 

gp_Pnt2d anEllipsePnt1 = anEllipse1->Value(0); gp_Pnt2d anEllipsePnt2; anEllipse1->D0(PI , anEllipsePnt2);

 

When creating the bottle’s profile, you used classes from the GC package, providing algorithms to create elementary geometries.

In 2D geometry, this kind of algorithms is found in the GCE2d package. Class names and behaviors are almost the same as in GC. For example, to create a 2D segment out of two points:

 

Handle(Geom2d_TrimmedCurve) aSegment = GCE2d_MakeSegment(anEllipsePnt1 , anEllipsePnt2);

 

 

4.3. 创建边和网格

当你创建瓶颈的基本轮廓时,你可以这样做:

 

计算瓶颈螺纹的 edges

根据这些edges计算出2 wires

 

先前已经创建了以下的内容:

 

• 2个螺纹的圆柱表面

 

• 3个曲线定义的螺纹基本几何。

根据曲线计算出egdes,就可以用BRepBuilderAPI_MakeEdge 类。它的一个构造函数允许你根据曲线的描述来创建egde

 

TopoDS_Edge aEdge1OnSurf1 = BRepBuilderAPI_MakeEdge(aArc1 , aCyl1);

TopoDS_Edge aEdge2OnSurf1 = BRepBuilderAPI_MakeEdge(aSegment , aCyl1);

TopoDS_Edge aEdge1OnSurf2 = BRepBuilderAPI_MakeEdge(aArc2 , aCyl2);

TopoDS_Edge aEdge2OnSurf2 = BRepBuilderAPI_MakeEdge(aSegment , aCyl2);

 

现在可以创建2个螺纹的轮廓:.

 

TopoDS_Wire threadingWire1 = BRepBuilderAPI_MakeWire(aEdge1OnSurf1 , aEdge2OnSurf1); TopoDS_Wire threadingWire2 = BRepBuilderAPI_MakeWire(aEdge1OnSurf2 , aEdge2OnSurf2);

 

记住这些wires 是根据2D曲线和 suface创建出来的。

下面的代码用以完成复杂的计算,目的是计算出wire中的shape

 

BRepLib::BuildCurves3d(threadingWire1); BRepLib::BuildCurves3d(threadingWire2);

 

 

4.4. 创建螺纹

现在已经计算出了螺纹的网格. 它将被做成实心的实体, 所以还需要计算出网格的表面, 这些面将连接在网格之间,将网格封闭成一个封闭的实体。

当基本拓扑关系建立之后总是有更快的方法来创建封闭实体。Occ 提供了快速创建网格上表面的方法:

这个方法实现在类 BRepOffsetAPI_ThruSections 中:

 

 

 

 这个类的构造同时也就初始化了构建网格上表面的方法。 如果你想创建一个solid这个构造函数的第一个参数你必须指定,默认会创建shell

添加网格 AddWire 方法。

CheckCompatibility 方法用来设置是否激活检测网格是否有相同的边的选项。

查询结果使用 Shape 方法.

 

BRepOffsetAPI_ThruSections aTool(Standard_True); aTool.AddWire(threadingWire1);

aTool.AddWire(threadingWire2);

aTool.CheckCompatibility(Standard_False);

TopoDS_Shape myThreading = aTool.Shape();