2个类可以用来描述3D坐标点:
• gp_Pnt 类
• Geom_CartesianPoint 类(句柄操作)
gp_Pnt aPnt1(-myWidth / 2. , 0 , 0);
gp_Pnt aPnt2(-myWidth / 2. , -myThickness / 4. , 0);
gp_Pnt aPnt3(0 , -myThickness / 2. , 0);
gp_Pnt aPnt4(myWidth / 2. , -myThickness / 4. , 0);
gp_Pnt aPnt5(myWidth / 2. , 0 , 0);
Handle(Geom_CartesianPoint) aPnt1 = new Geom_CartesianPoint(-myWidth / 2. , 0 , 0);
gp_Pnt aPnt1(0,0,0);
Handle(Geom_CartesianPoint) aPnt2 = new Geom_CartesianPoint(0 , 0 , 0);
Standard_Real xValue1 = aPnt1.X();
Standard_Real xValue2 = aPnt2->X();
Geom_Line,Geom_Circle 这2个类属于Geom开发包。这个开发包实现3D几何对象:基本曲线和曲面(比如Bezier和BSpline)。
但是,Geom开发包仅仅提供几何对象的数据结构。你可以直接使用这些数据结构定义几何体。因此GC开发包提供了更简单的生成这些基本几何对象的方法。
GC开发包提供了2个算法类,它对通过参数计算得到几何对象更容易:
• 类 GC_MakeSegment 创建线段。它的其中一个构造函数支持使用2个点P1,P2来构造线段。
• 类 GC_MakeArcOfCircle 创建圆弧和圆。一个常用的方法是通过圆弧的2个端点和圆弧所通过的一个点来生成圆弧。
这些类返回一个Geom_TrimmedCurve 句柄。
Handle(Geom_TrimmedCurve) aArcOfCircle = GC_MakeArcOfCircle(aPnt2,aPnt3 ,aPnt4);
Handle(Geom_TrimmedCurve) aSegment1 = GC_MakeSegment(aPnt1 , aPnt2);
Handle(Geom_TrimmedCurve) aSegment2 = GC_MakeSegment(aPnt4 , aPnt5);
通过IsDone和Value方法来保证更安全的使用这些类:
GC_MakeSegment mkSeg (aPnt1 , aPnt2);
Handle(Geom_TrimmedCurve) aSegment1;
if(mkSegment.IsDone())
{ aSegment1 = mkSeg.Value(); ... }
TopoDS开发包:这个开发包可以将几何对象关联在一起,让它们生成一个复合对象。
TopoDS开发包的所有对象都是由TopoDS_Shape 类派生而来。
图形 Open CASCADE Class 描述
Vertex (顶点) TopoDS_Vertex 表示几何体上的一个点
Edge (边) TopoDS_Edge 表示一个曲线和一个有边界的向量
Wire (网格) TopoDS_Wire 由顶点连起来的一系列边
Face (面) TopoDS_Face 由闭合的网格组成的边界平面
Shell (壳) TopoDS_Shell 通过边连接起起来一组面
Solid (体) TopoDS_Solid 由壳组成的有边界的三维空间
CompSolid (复合体) TopoDS_CompSolid 通过面连接的一组体
Compound (复合对象) TopoDS_Compound 由上面各种图形形成的一个集合
TopoDS包中只提供了拓扑实体的数据结构。在BRepBuilderAPI包中,可以找到计算标准拓朴对象的算法类。
为了创建一个边,通过前面得出曲线,使用BRepBuilderAPI_MakeEdge类来完成:
TopoDS_Edge aEdge1 = BRepBuilderAPI_MakeEdge(aSegment1);
TopoDS_Edge aEdge2 = BRepBuilderAPI_MakeEdge(aArcOfCircle);
TopoDS_Edge aEdge3 = BRepBuilderAPI_MakeEdge(aSegment2);
TopoDS_Edge aEdge1 = BRepBuilderAPI_MakeEdge(aPnt1 , aPnt3);
TopoDS_Edge aEdge2 = BRepBuilderAPI_MakeEdge(aPnt4 , aPnt5);
为了将边链接起来,需要通过 BRepBuilderAPI_MakeWire 创建网格。
TopoDS_Wire aWire = BRepBuilderAPI_MakeWire(aEdge1 , aEdge2 , aEdge3);
4,轮廓:完成轮廓
• 通过镜像原有的网格生成一个新的网格 。
• 添加镜像出来的新网格到原有的网格中。
要完成上面的操作,需要一个gp_Trsf 类。它可以在3D图形上应用变换。变换方式包含 移动,旋转,缩放,镜像,或者几种的组合。
需要先用一个点和一个法向创建一个轴(gp_Ax1)。
定义轴的第一种方法:
•X 轴的原点在(0,0,0) 使用 gp_Pnt。
• X 轴的方向为(1,0,0) 使用gp_Dir。
gp_Pnt aOrigin(0 , 0 , 0);
gp_Dir xDir(1 , 0 , 0);
gp_Ax1 xAxis(aOrigin , xDir);
定义轴的第二种方法:
可以直接使用gp 开发包中的几何常量来初始化轴。
gp_Ax1 xAxis = gp::OX();
下面看看 gp_Trsf 类的2种不同的使用方法:
•直接设置变换矩阵。
• 使用合适的方法计算生成所需的变换(移动使用 SetTranslation ,镜像使用 SetMirror 等等)。
gp_Trsf aTrsf;
aTrsf.SetMirror(xAxis);
现在数据已经准备完毕,下面将使用BRepBuilderAPI_Transform 进行变换:
BRepBuilderAPI_Transform aBRepTrsf(aWire , aTrsf);
BRepBuilderAPI_Transform 并不会修改aWire中的原始形状,镜像的结果仍然是一个网格。这个结果需要调用BRepBuilderAPI_Transform::Shape 方法返回一个TopoDS_Shape 对象:
TopoDS_Shape aMirroredShape = aBRepTrsf.Shape();
还可以通过下面的方法将返回的TopoDS_Shape类转换为TopoDS_Wire(这是因为TopoDS_Shape是所有拓扑类的基类):
TopoDS_Wire aMirroredWire = TopoDS::Wire(aMirroredShape);
我们已经创建了2个网格: aWire 和 aMirroredWire。现在需要将它们连接成一个单一的图形。
BRepBuilderAPI_MakeWire 这个类可以帮助我们完成这个任务:
• 创建一个 BRepBuilderAPI_MakeWire 实例 。
• 使用 Add 方法将2个网格的所有的边添加到这个实体上。
BRepBuilderAPI_MakeWire mkWire;
mkWire.Add(aWire);
mkWire.Add(aMirroredWire);
TopoDS_Wire myWireProfile = mkWire.Wire();
OCC可以根据一个形状和一个方向生成实体:
形状 生成
Vertex 顶点 Edge 边
Edge 边 Face 表面
Wire 网格 Shell 壳
Face 表面 Solid 体
Shell 壳 Compound of Solids 组合体
当前的轮廓是一个wire,根据上面的表,应该通过wire获得face,再通过face生成solid。
用 BRepBuilderAPI_MakeFace 类创建face。如前面所说, face是一个由闭合wire组成的表面轮廓的一部分。通常,BRepBuilderAPI_MakeFace类可以将一个或多个wire生成face。
如果wire在一个平面上,则surface将自动生成。
TopoDS_Face myFaceProfile = BRepBuilderAPI_MakeFace(myWireProfile);
BRepPrimAPI 开发包提供了很多类来创建拓扑图元:boxes, cones, cylinders, spheres, 等等。 其中 BRepPrimAPI_MakePrism 类。 上面的柱体可以这个创建:
gp_Vec aPrismVec(0 , 0 , myHeight);
TopoDS_Shape myBody = BRepPrimAPI_MakePrism(myFaceProfile , aPrismVec);
圆角的方法有很多,比如沿着一条线,或者棱线,我们这里采用比较简单的方法:
• 圆角所有的边。
• 圆角半径 myThickness / 12 。
在尖锐的边上圆角使用 BRepFilletAPI_MakeFillet 类。使用方法:
• 使用 BRepFilletAPI_MakeFillet 类的构造函数传入需要圆角的图形。
• 使用Add函数添加要圆角的边和半径。
• 用Shape函数返回圆角结果。
BRepFilletAPI_MakeFillet mkFillet(myBody);
为了添加圆角的参数边,必须知道图形都有哪些边。最好的解决方法是通过遍历获得形体的所有边。这里面用到TopExp_Explorer类提供的功能和TopoDS_Shape类提供的数据结构,下面我们通过程序来看一下通过遍历,将边作为参数传入圆角类的过程:
TopExp_Explorer aEdgeExplorer(myBody , TopAbs_EDGE);
while(aEdgeExplorer.More())
{
TopoDS_Edge aEdge = TopoDS::Edge(aEdgeExplorer.Current()); //Add edge to fillet algorithm
...
aEdgeExplorer.Next();
}
mkFillet.Add(myThickness / 12. , aEdge);
myBody = mkFillet.Shape();
要添加瓶颈,需生成一个园柱并把它焊到瓶体上;园柱的位置在瓶体的顶面,半径设定myThickness/4,高度设定myHeight/10。
为了定位园柱,要用gp_Ax2类来定义一个右手坐标系,这个坐标系可以由一个点和两个方向来定义,这两个方向分别是法线方向和X轴方向,Y轴方向可以由这两个方向计算得出。
瓶子体上面的中心,在世界坐标系中的坐标是(0,0,myHeight),法线是Z轴。所以,局部坐标系可以这们定义:
gp_Pnt neckLocation(0 , 0 , myHeight);
gp_Dir neckNormal = gp::DZ();
gp_Ax2 neckAx2(neckLocation , neckNormal);
生成圆柱可以使用图元构造开发包中的BRepPrimAPI_MakeCylinder 类。 需要以下信息:
• 圆柱所在的坐标系
• 半径和高度
Standard_Real myNeckRadius = myThickness / 4.;
Standard_Real myNeckHeight = myHeight / 10;
TopoDS_Shape myNeck = BRepPrimAPI_MakeCylinder(neckAx2 , myNeckRadius , myNeckHeight);
BRepAlgoAPI 开发包中提供了图元间的布尔运算。包括交,并,差 三种运算。
用 BRepAlgoAPI_Fuse 可以将2个图元焊接在一起:
myBody = BRepAlgoAPI_Fuse(myBody , myNeck);