概述
本教程将教您如何使用 Open CASCADE Technology 服务对 3D 对象进行建模。本教程的目的不是描述所有 Open CASCADE Technology 课程,而是帮助您开始将 Open CASCADE Technology 作为一种工具进行思考。
先决条件
本教程假设您有使用和设置 C++ 的经验。从编程的角度来看,Open CASCADE 技术旨在通过 3D 建模类、方法和函数来增强您的 C++ 工具。所有这些资源的组合将允许您创建大量的应用程序。
该模型
为了说明 3D 几何建模工具包中提供的类的使用,您将创建一个瓶子,如下所示:
在本教程中,我们将逐步创建一个对瓶子进行建模的函数,如上所示。您将找到本教程的完整源代码,包括Open CASCADE Technology 分发包中的MakeBottle函数。函数体在文件 samples/qt/Tutorial/src/MakeBottle.cxx 中提供。
型号规格
我们首先定义瓶子规格如下:
对象参数 | 参数名称 | 参数值 |
---|---|---|
瓶子高度 | 我的身高 | 70mm |
瓶宽 | 我的宽度 | 50mm |
瓶子厚度 | 我的厚度 | 30mm |
此外,我们决定瓶子的轮廓(底部)将以全局笛卡尔坐标系的原点为中心。
此建模需要四个步骤:
- 建立瓶子的个人资料
- 建立瓶子的身体
- 在瓶子的脖子上建立螺纹
- 构建结果化合物
构建配置文件
定义支撑点
要创建瓶子的轮廓,您首先需要在 (XOY) 平面中创建特征点及其坐标,如下所示。这些点将是定义轮廓几何形状的支撑。
在 Open CASCADE 技术中,有两个类可以从其 X、Y 和 Z 坐标描述 3D 笛卡尔点:
- 原始几何gp_Pnt类
- 由句柄操作的瞬态Geom_CartesianPoint类
句柄是一种提供自动内存管理的智能指针。要为此应用选择最佳等级,请考虑以下因素:
- gp_Pnt由值操纵。像所有同类物体一样,它的寿命有限。
- Geom_CartesianPoint由句柄操作,可能有多个引用和较长的生命周期。
由于您将定义的所有点仅用于创建轮廓的曲线,因此具有有限生命周期的对象就可以了。选择gp_Pnt类。要实例化一个gp_Pnt对象,只需指定全局笛卡尔坐标系中点的 X、Y 和 Z 坐标:
一旦你的对象被实例化,你就可以使用类提供的方法来访问和修改它的数据。例如,要获取一个点的 X 坐标:
配置文件:定义几何
借助先前定义的点,您可以计算出瓶子轮廓几何的一部分。如下图所示,它将由两条线段和一条弧线组成。
要创建这样的实体,您需要一个实现 3D 几何对象的特定数据结构。这可以在 Open CASCADE Technology 的 Geom 包中找到。在 Open CASCADE 技术中,包是一组提供相关功能的类。这些类的名称以它们所属的包的名称开头。例如,Geom_Line和Geom_Circle类属于Geom包。Geom包实现 3D 几何对象:提供基本曲线和曲面以及更复杂的(例如Bezier和BSpline)。然而,几何包只提供几何实体的数据结构。您可以直接实例化属于Geom的类,但使用GC包更容易计算基本曲线和曲面。这是因为GC提供了两个算法类,这正是我们的配置文件所需要的:
- 类GC_MakeSegment创建一个段。它的一个构造函数允许您通过两个端点 P1 和 P2 定义一个段
- GC_MakeArcOfCircle类创建圆弧。一个有用的构造函数从两个端点 P1 和 P3 并通过 P2 创建一个弧。
这两个类都返回一个由句柄操作的Geom_TrimmedCurve。这个实体代表一个基本曲线(在我们的例子中是直线或圆),限制在它的两个参数值之间。例如,圆 C 参数化在 0 和 2PI 之间。如果您需要创建四分之一圆,则在 C 上创建一个Geom_TrimmedCurve,限制在 0 和 M_PI/2 之间。
所有GC类都提供了一种强制转换方法,可以通过类似函数的调用自动获取结果。请注意,如果构造失败,此方法将引发异常。要更明确地Handle可能的错误,您可以使用IsDone和Value方法。例如:
简介:定义拓扑
您已经创建了轮廓一部分的支撑几何体,但这些曲线是独立的,彼此之间没有任何关系。为了简化建模,将这三个曲线作为一个实体进行操作是正确的。这可以通过使用TopoDS包中定义的 Open CASCADE Technology 的拓扑数据结构来完成:它定义了可以链接在一起以表示复杂形状的几何实体之间的关系。从TopoDS_Shape类继承的TopoDS包的每个对象都描述了一个拓扑形状,如下所述:
形状 | 开设CASCADE技术课 | 描述 |
---|---|---|
顶点 | TopoDS_Vertex | 与几何中的点相对应的零维形状。 |
边 | TopoDS_Edge | 一维形状对应于一条曲线,并以每个端点的顶点为界。 |
线 | TopoDS_Wire | 由顶点连接的边序列。 |
面 | TopoDS_Face | 由闭合线包围的表面的一部分。 |
壳 | TopoDS_Shell | 由边连接的一组面。 |
实体 | TopoDS_Solid | 以壳为界的 3D 空间的一部分。 |
复合固体 | TopoDS_CompSolid | 一组通过面连接的实体。 |
化合物 | TopoDS_Compound | 上述任何其他形状的集合。 |
参考上表,要构建配置文件,您将创建:
- 先前计算的曲线中的三个边。
- 一根带有这些边的线。
但是,TopoDS包仅提供拓扑实体的数据结构。可用于计算标准拓扑对象的算法类可以在BRepBuilderAPI包中找到。要创建一条边,您可以将BRepBuilderAPI_MakeEdge类与先前计算的曲线一起使用:
在 Open CASCADE Technology 中,您可以通过多种方式创建边。一种可能性是直接从两个点创建一条边,在这种情况下,这条边的底层几何图形是一条线,由从两个输入点自动计算的两个顶点界定。例如,anEdge1 和 anEdge3 可以用更简单的方式计算:
要连接边,您需要使用BRepBuilderAPI_MakeWire类创建连线。有两种方法可以用这个类构建一条线:
- 直接从一到四个边
- 通过将其他线或边添加到现有线(本教程后面将对此进行说明)
当从少于四个边构建导线时,如本例所示,您可以直接使用构造函数,如下所示:
个人资料:完成个人资料
创建导线的第一部分后,您需要计算完整的配置文件。一个简单的方法是:
- 通过反映现有的线来计算新的线。
- 将反射线添加到初始线。
要对形状(包括线)应用变换,首先需要使用gp_Trsf类定义 3D 几何变换的属性。这种变换可以是平移、旋转、缩放、反射或这些的组合。在我们的例子中,我们需要定义一个相对于全局坐标系 X 轴的反射。使用gp_Ax1类定义的轴由一个点构建并具有一个方向(3D 酉向量)。有两种方法来定义这个轴。第一种方法是从头开始定义它,使用它的几何定义:
第二种也是最简单的方法是使用 gp 包中定义的几何常数(全局坐标系的原点、主要方向和轴)。要获取 X 轴,只需调用gp::OX方法:
如前所述,3D 几何变换是使用gp_Trsf类定义的。有两种不同的方式来使用这个类:
- 通过所有值定义一个变换矩阵
- 通过使用与所需转换相对应的适当方法(用于平移的 SetTranslation、用于反射的 SetMirror 等):自动计算矩阵。
由于最简单的方法总是最好的方法,因此您应该使用以轴为对称中心的 SetMirror 方法。
您现在拥有所有必要的数据,可以通过指定使用BRepBuilderAPI_Transform类应用转换:
- 必须应用变换的形状。
- 几何变换
BRepBuilderAPI_Transform不会修改形状的性质:反射线的结果仍然是线。但是类似函数的调用或BRepBuilderAPI_Transform::Shape方法返回一个TopoDS_Shape对象:
您需要一种将产生的反射形状视为线的方法。TopoDS全局函数通过将形状转换为真实类型来提供这种服务。要投射转换后的线,请使用TopoDS::Wire方法。
瓶子的轮廓几乎完成了。您已经创建了两条线:aWire和aMirroredWire。您需要连接它们以计算单个形状。为此,您可以使用BRepBuilderAPI_MakeWire类,如下所示:
- 创建BRepBuilderAPI_MakeWire的实例。
- 使用此对象的Add方法添加两条线的所有边。
建立身体
拉伸轮廓
要计算瓶子的主体,您需要创建一个实体形状。最简单的方法是使用之前创建的轮廓并沿一个方向扫过它。Open CASCADE Technology的Prism功能最适合该任务。它接受一个形状和一个方向作为输入,并根据以下规则生成一个新形状:
形状 | 生成 |
---|---|
点 | 边 |
边 | 面 |
线 | 壳 |
面 | 实体 |
壳 | 固体化合物 |
您当前的个人资料是线。参考 Shape/Generates 表,您需要根据其线计算面以生成实体。要创建面,请使用BRepBuilderAPI_MakeFace类。如前所述,面是由闭合线包围的表面的一部分。通常,BRepBuilderAPI_MakeFace从表面和一根或多根线计算出一个面。当导线位于平面上时,将自动计算曲面。
BRepPrimAPI包提供了创建拓扑基元构造的所有类:长方体、圆锥体、圆柱体、球体等。其中包括BRepPrimAPI_MakePrism类。如上所述,拉伸定义为:
- 要扫描的基础形状;
- 有限拉伸的矢量或有限和无限拉伸的方向。
您希望实体是有限的,沿 Z 轴扫过并且高度为 myHeight。使用gp_Vec类在其 X、Y 和 Z 坐标上定义的向量是:
现在可以使用创建瓶子主体所需的所有数据。只需应用BRepPrimAPI_MakePrism类来计算实体:
应用圆角
瓶身边非常锋利。要使用圆角面替换它们,您可以使用 Open CASCADE 技术的圆角功能。出于我们的目的,我们将指定圆角必须是:
- 应用于形状的所有边
- 半径为myThickness / 12
要在形状的边应用圆角,请使用BRepFilletAPI_MakeFillet类。该类通常使用如下:
- 在BRepFilletAPI_MakeFillet构造函数中指定要圆角的形状。
- 使用Add方法添加圆角描述(边和半径)(您可以根据需要添加任意数量的边)。
- 使用Shape方法请求生成的圆角形状。
要添加圆角描述,您需要知道属于您的形状的边。最好的解决方案是探索您的实体以检索其边。这种功能由TopExp_Explorer类提供,该类探索TopoDS_Shape中描述的数据结构并提取您特别需要的子形状。通常,通过提供以下信息来创建此资源管理器:
- 探索的形状
- 要找到的子形状的类型。此信息由TopAbs_ShapeEnum枚举提供。
资源管理器通常通过使用其三种主要方法在循环中应用:
- More()以了解是否有更多子形状需要探索。
- Current()知道哪个是当前探索的子形状(仅在More()方法返回 true 时使用)。
- Next()移动到下一个要探索的子形状。
在资源管理器循环中,您已经找到了瓶子形状的所有边。然后必须使用Add()方法将每一个添加到BRepFilletAPI_MakeFillet实例中。不要忘记指定圆角的半径。
完成此操作后,您可以通过询问圆角形状来执行该过程的最后一步。
添加颈部
要为瓶子添加颈部,您将创建一个圆柱体并将其融合到身体上。圆柱体将定位在主体的顶面上,半径为myThickness / 4。高度为myHeight / 10。
要定位圆柱体,您需要使用gp_Ax2类定义一个坐标系,该类定义一个点和两个方向的右手坐标系 – 主 (Z) 轴方向和 X 方向(Y 方向是从这两个方向计算得出的) )。要将颈部与顶面的中心对齐,在全局坐标系 (0, 0, myHeight ) 中,其法线在全局 Z 轴上,您的局部坐标系可以定义如下:
要创建圆柱体,请使用原语构造包中的另一个类:BRepPrimAPI_MakeCylinder类。您必须提供的信息是:
- 圆柱所在的坐标系;
- 半径和高度。
你现在有两个独立的部分:一个主体和一个需要融合在一起的颈部。BRepAlgoAPI包提供了在形状之间执行布尔运算的服务,尤其是:common (布尔交集)、cut(布尔减法)和fuse(布尔并集)。使用BRepAlgoAPI_Fuse融合两个形状:
创建空心实体
由于真正的瓶子用于盛装液体材料,您现在应该从瓶子的顶面创建一个中空的实体。在 Open CASCADE 技术中,空心实体称为厚 实体,其内部计算如下:
- 从初始实体中移除一个或多个面,以获得空心实体的第一壁 W1。
- 在距离 D 处从 W1 创建平行墙 W2。如果 D 为正,则 W2 将位于初始实体的外部,否则它将位于内部。
- 从两个墙 W1 和 W2 计算一个实体。
要计算厚实体,您可以通过提供以下信息来创建BRepOffsetAPI_MakeThickSolid类的实例:
- 形状,必须是镂空的。
- 用于计算的公差(生成形状重合的公差标准)。
- 两壁 W1 和 W2 之间的厚度(距离 D)。
- 要从原始实体中移除以计算第一面墙 W1 的面。
此过程中具有挑战性的部分是找到要从您的形状中移除的面部 – 颈部的顶面,它:
- 有一个平面(平面表面)作为基础几何;
- 是瓶子的最高面(在 Z 坐标中)。
要找到具有这些特征的面孔,您将再次使用资源管理器迭代所有瓶子的面孔以找到合适的面孔。
对于每个检测到的面,您需要访问形状的几何属性:为此使用BRep_Tool类。这个类最常用的方法有:
- Surface访问面的表面;
- 曲线访问边的 3D 曲线;
- Point访问顶点的 3D 点。
如您所见,BRep_Tool::Surface方法返回一个由句柄操作的Geom_Surface类的实例。但是,Geom_Surface类不提供有关对象aSurface的真实类型的信息,它可能是Geom_Plane、Geom_CylindricalSurface等的实例。所有由句柄操作的对象,如Geom_Surface,都继承自Standard_Transient类,该类提供了两个非常有用的方法关于类型:
- DynamicType知道对象的真实类型
- IsKind知道对象是否继承自一种特定类型
DynamicType 返回对象的真实类型,但您需要将其与现有的已知类型进行比较,以确定aSurface是平面、圆柱面还是其他类型。要将给定类型与您寻找的类型进行比较,请使用STANDARD_TYPE宏,该宏返回类的类型:
如果此比较为真,则您知道aSurface真实类型是Geom_Plane。然后,您可以使用每个继承Standard_Transient的类提供的DownCast()方法将其从Geom_Surface转换为Geom_Plane。顾名思义,此静态方法用于使用以下语法将对象向下转换为给定类型:
请记住,所有这些转换的目标是找到位于平面上的瓶子的最高面。假设您有这两个全局变量:
知道平面的位置是用Geom_Plane::Location方法给出的,您可以很容易地找到原点在 Z 中最大的平面。例如:
您现在已经找到了颈部的顶面。创建空心实体之前的最后一步是将此面放入列表中。由于可以从初始实体中移除多个面,因此BRepOffsetAPI_MakeThickSolid构造函数将面列表作为参数。Open CASCADE Technology 为不同类型的对象提供了许多集合:参见TColGeom包以获取Geom包中的对象集合,TColgp包获取 gp 包中的对象集合等。形状集合可以在TopTools包中找到。由于BRepOffsetAPI_MakeThickSolid需要一个列表,因此请使用TopTools_ListOfShape类。
现在所有必要的数据都可用了,因此您可以通过调用BRepOffsetAPI_MakeThickSolid MakeThickSolidByJoin 方法来创建空心实体:
构建线程
创建曲面
到目前为止,您已经学习了如何从 3D 曲线中创建边。您现在将学习如何从 2D 曲线和曲面创建边。要了解 Open CASCADE 技术的这一方面,您将使用圆柱表面上的 2D 曲线构建螺旋轮廓。该理论比前面的步骤更复杂,但应用它非常简单。作为第一步,您计算这些圆柱表面。您已经熟悉Geom包的曲线。现在,您可以使用以下方法创建圆柱表面 ( Geom_CylindricalSurface ):
- 坐标系;
- 一个半径。
使用用于定位颈部的相同坐标系eckAx2 ,您可以创建两个具有以下半径的圆柱曲面Geom_CylindricalSurface :
请注意,其中一个圆柱面小于颈部。这样做有一个很好的理由:创建线程后,您会将其与颈部融合。所以,我们必须确保这两个形状保持接触。
定义二维曲线
为了创建瓶子的颈部,您基于圆柱表面制作了一个实心圆柱体。您将通过在这样的表面上创建 2D 曲线来创建螺纹轮廓。Geom包中定义的所有几何图形都已参数化。这意味着来自 Geom 的每条曲线或曲面都是使用参数方程计算的。Geom_CylindricalSurface曲面使用以下参数方程定义:
P(U, V) = O + R * (cos(U) * xDir + sin(U) * yDir) + V * zDir,其中:
- P 是由参数 (U, V) 定义的点。
- O、*Dir、yDir、zDir分别为圆柱面局部坐标系的原点、X方向、Y方向、Z方向。
- R 是圆柱表面的半径。
- U 范围是 [0, 2PI],V 是无限的。
具有这种参数化几何形状的优点是您可以计算表面的任何 (U, V) 参数:
- 3D点;
- 此时的 1、2 到 N 阶导数向量。
这些参数方程还有另一个优点:您可以将曲面视为使用 (U, V) 坐标系定义的 2D 参数空间。例如,考虑颈部表面的参数范围:
假设您在此参数(U、V)空间上创建一条 2D 线并计算其 3D 参数曲线。根据行定义,结果如下:
案子 | 参数方程 | 参数曲线 |
---|---|---|
U = 0 | P(V) = O + V * zDir | 平行于 Z 方向的线 |
V = 0 | P(U) = O + R * (cos(U) * xDir + sin(U) * yDir) | 平行于 (O, X, Y) 平面的圆 |
U != 0 V != 0 | P(U, V) = O + R * (cos(U) * xDir + sin(U) * yDir) + V * zDir | 描述圆柱体高度和角度演变的螺旋曲线 |
螺旋曲线类型正是您所需要的。在颈部表面,这条曲线的演化规律将是:
- 在 V 参数中:0 和 myHeighNeck 之间的高度描述
- 在 U 参数中:角度描述在 0 到 2PI 之间。但是,由于圆柱表面是 U 周期的,您可以决定将此角度演化扩展到 4PI,如下图所示:
在这个 (U, V) 参数空间中,您将创建一个局部 (X, Y) 坐标系来定位要创建的曲线。该坐标系将定义为:
- 位于颈部圆柱体参数空间中间的中心,位于 U、V 坐标中 (2*PI, myNeckHeight / 2)。
- AX 方向由 U、V 坐标中的 (2*PI, myNeckHeight/4) 向量定义,以便曲线占据颈部表面的一半。
要使用 Open CASCADE 技术的 2D 原始几何类型来定义点和坐标系,您将再次从 gp 实例化类:
- 要从其 X 和 Y 坐标定义 2D 点,请使用gp_Pnt2d类。
- 要从其 X 和 Y 坐标定义 2D 方向(单位向量),请使用gp_Dir2d类。坐标将自动归一化。
- 要定义 2D 右手坐标系,请使用gp_Ax2d类,该类是根据一个点(坐标系的原点)和一个方向(坐标系的 X 方向)计算得出的。将自动计算 Y 方向。
您现在将定义曲线。如前所述,这些螺纹轮廓是在两个圆柱表面上计算的。在下图中,左侧的曲线定义了底面(在aCyl1表面上),右侧的曲线定义了螺纹形状的顶部(在aCyl2表面上)。
您已经使用Geom包定义了 3D 几何实体。对于 2D,您将使用Geom2d包。至于Geom,所有几何图形都是参数化的。例如,一个Geom2d_Ellipse椭圆定义自:
- 以椭圆中心为原点的坐标系;
- 由坐标系的 X 方向定义的主轴上的主半径;
- 由坐标系的 Y 方向定义的短轴上的小半径。
假设:
- 两个椭圆的主半径相同,均为 2*PI,
- 第一个椭圆的小半径是 myNeckHeight / 10,
- 第二个椭圆的小半径值是第一个椭圆的四分之一,
您的椭圆定义如下:
为了描述上面绘制的弧线的曲线部分,您从创建的椭圆中定义Geom2d_TrimmedCurve修剪曲线和两个参数来限制它们。由于椭圆的参数方程为 P(U) = O + (MajorRadius * cos(U) * XDirection) + (MinorRadius * sin(U) * YDirection),因此椭圆需要限制在 0 和 M_PI 之间。
最后一步包括定义线段,这对于两个轮廓是相同的:一条由一个弧的第一个点和最后一个点限制的线。要访问与曲线或曲面的参数对应的点,可以使用 Value 或 D0 方法(表示 0 次导数),D1 方法用于一阶导数,D2 用于二阶导数。
创建瓶子的轮廓时,您使用了GC包中的类,提供了创建基本几何图形的算法。在二维几何中,这种算法可以在GCE2d包中找到。类名和行为与GC中的类似。例如,要从两点创建 2D 线段:
建筑边和线
正如您在创建瓶子的基本配置文件时所做的那样,您现在可以:
- 计算颈部螺纹的边。
- 从这些边计算两条线。
以前,您已经构建了:
- 螺纹的两个圆柱面
- 定义螺纹的基本几何形状的三个 2D 曲线
要计算这些曲线的边,请再次使用BRepBuilderAPI_MakeEdge类。它的构造函数之一允许您从曲面的 2D 参数空间中描述的曲线构建边。
现在,您可以创建位于每个表面上的两个螺纹轮廓。
请记住,这些线是由曲面和 2D 曲线构建的。就这些线而言,缺少一个重要的数据项:没有关于 3D 曲线的信息。幸运的是,您不需要自己计算,这可能是一项艰巨的任务,因为数学可能非常复杂。当一个形状包含除 3D 曲线之外的所有必要信息时,Open CASCADE Technology 提供了一种自动构建它们的工具。在BRepLib工具包中,您可以使用BuildCurves3d方法计算形状所有边的 3D 曲线。
创建线程
您已经计算了线程的线数。螺纹将是一个实体形状,因此您现在必须计算线的面,允许您连接线的面,这些面的壳,然后是实体本身。这可能是一个冗长的操作。定义基本拓扑后,总是有更快的方法来构建实体。您想用两条线创建一个实体。Open CASCADE 技术提供了一种通过构建阁楼的快速方法来做到这一点:一个壳或一个实体以给定的顺序穿过一组线。
loft 函数在BRepOffsetAPI_ThruSections类中实现,您可以按如下方式使用该类:
- 通过创建类的实例来初始化算法。如果要创建实体,则必须指定此构造函数的第一个参数。默认情况下,BRepOffsetAPI_ThruSections构建一个外壳。
- 使用 AddWire 方法添加连续的连线。
- 使用CheckCompatibility方法激活(或停用)检查线是否具有相同数量的边的选项。在这种情况下,每条线都有两条边,因此您可以禁用此选项。
- 使用 Shape 方法请求生成的放样形状。
构建生成的化合物
你几乎完成了瓶子的制作。使用TopoDS_Compound和BRep_Builder类从myBody和myThreading构建单个形状:
恭喜!你的瓶子是完整的。这是教程应用程序的结果快照:
我们希望本教程能让您感受到 Open CASCADE 技术的工业实力。如果您想了解更多信息并使用 Open CASCADE 技术开发重大项目,我们邀请您在我们的网站https://www.opencascade.com/content/technology-support上学习我们的培训、支持和咨询服务。我们的专业服务可以最大限度地发挥您的 Open CASCADE 技术应用程序的功能。
附录
MakeBottle 函数的完整定义(在教程的 src/MakeBottle.cxx 文件中定义):
暂无评论内容