模型数据提供数据结构,用于在 3D 模式下实现对象的边界表示 (BRep)。在 BRep 中,形状表示为拓扑中几何图形的聚合。几何形状被理解为形状的数学描述,例如曲线和曲面(简单或规范,贝塞尔,NURBS等)。拓扑是将几何对象绑定在一起的数据结构。
几何类型和实用程序为以下方面提供几何数据结构和服务:
拓扑定义简单几何实体之间的关系。形状是基本的拓扑实体,可以分为组件(子形状):
复杂形状可以定义为简单实体的组件(复合)。3D 几何模型可以以 OCCT 原生 BREP 格式存储。
Geom
几何实用程序提供以下服务:
在建模中,通常需要将点拟合或插值为曲线和曲面。在插值中,当曲线或曲面通过所有点时,该过程完成;近似值,当它尽可能接近这些点时。
曲线和曲面拟合将 2D 和 3D 几何中使用的各种功能组合在一起,用于:
您可以通过两种方式对拟合值进行编程:
GProp 包中的 PEquation 类允许分析点的集合或云,并验证它们在给定精度内是重合、共线还是共面。如果是,则算法计算点的平均点、平均线或点的平均平面。如果不是,则算法将计算包含所有点的最小框。
Geom2dAPI 和 GeomAPI 软件包提供了简单的近似和插值方法,只需最少的编程
Geom2dAPI 包中的类插值允许构建受约束的 2D BSpline 曲线,该曲线由曲线通过的点表定义。如果需要,可以为表中的每个点给出切线的参数值和向量。
GeomAPI 的类插值包允许构建受约束的 3D BSpline 曲线,该曲线由曲线通过的点表定义。如果需要,可以为表中的每个点给出切线的参数值和向量。如图,从散点拟合 BSpline
此类可以按如下方式实例化:
GeomAPI_Interpolate Interp(Points);
从这个对象,可以请求如下的BSpline曲线:
Handle(Geom_BSplineCurve) C = Interp.Curve();
来自Geom2dAPI包的类PointsToBSpline允许构建2DBSpline曲线,该曲线近似于一组点。您必须定义曲线的最低和最高度数、其连续性和公差值。容差值用于检查点是否彼此不太接近,或者切向量是否不太小。生成的 BSpline 曲线将是 C2 或二度连续的,除非在曲线通过的点上定义了相切约束。在这种情况下,它将只是 C1 连续的。
来自GeomAPI包的类PointsToBSpline允许构建3D BSpline曲线,该曲线近似于一组点。有必要定义曲线的最低和最高度,其连续性和公差。容差值用于检查点是否彼此不太接近,或者切向量是否太小。
生成的 BSpline 曲线将是 C2 或二阶连续的,除非在曲线通过的点上定义了相切约束。在这种情况下,它将只是 C1 连续的。此类实例化如下:
GeomAPI_PointsToBSpline
Approx(Points,DegMin,DegMax,Continuity, Tol);
从这个对象,可以请求如下的BSpline曲线:
Handle(Geom_BSplineCurve) K = Approx.Curve();
GeomAPI包中的类 PointsToBSplineSurface 允许构建一个 BSpline 曲面,该曲面近似或插值一组点。
AppDef 和 AppParCurves 包提供低级函数,允许对拟合值进行更多控制。
低级函数提供2个 API,其中包含以下功能:
您还可以找到要计算的函数:
AppDef 软件包提供了低级工具,允许使用多个点约束将点组平行近似为贝塞尔曲线或 B 样条曲线。
提供以下低级服务:
点约束数组的定义:
MultiLine 类允许定义给定数量的多点约束,以便构建多线,多条线通过有序多点约束。如图
在此图像中:
Pi,Qi,Ri…Si 可以是 2D 或 3D 点。
定义为一个组:Pn、Qn、Rn、…Sn 形成多点约束。它们具有相同的通道、相切和曲率约束。
P1, P2, …Pn,或Q,R,…或 S 系列表示要拟合的线。
一组点约束的定义:
类 MultiPointConstraint 允许定义多点约束并计算点集到多条曲线的近似值。
从一组点计算贝塞尔曲线的近似值:
类 Compute 允许将一组点近似到贝塞尔曲线
从一组点计算BSpline曲线的近似值:
类BSplineCompute允许将一组点近似到BSpline曲线。
变分标准的定义:
类 TheVariational 允许使用最小二乘法结合变分准则(通常是每个约束点的权重)将近似曲线整流到给定数量的点。
AppParCurves 软件包提供了低级工具,允许将点组平行近似为具有参数或几何约束的贝塞尔曲线或 B 样条曲线,例如要求曲线通过给定点,或在特定点具有给定的相切或曲率。
使用的算法包括:
提供以下低级服务:
类 ConstraintCouple 允许您将索引关联到对象以使用 AppDef_TheVariational 计算流行曲线。
多曲线类允许定义由多条贝塞尔曲线组成的多线的近似值。
MultiBSpCurve类允许定义由多条BSpline曲线组成的多线的近似值。
多点类允许定义构成多线的 2D 或 3D 点组。
若要拟合曲线的切向,请执行以下步骤:
GCE、GC 和 GCE2d 软件包中的直接构造方法提供了简化的算法来构建基本几何实体,例如直线、圆和曲线。它们补充了 gp、Geom 和 Geom2d 软件包提供的参考定义。
gce、 GCE2d 和 GC 包实现的算法很简单:无需创建由高级位置约束定义的对象
例如,要使用 gp 包从点和半径构造圆,必须在创建圆之前构造轴 Ax2d。如果使用gce包,并且以Ox作为轴,则可以直接从点和半径创建圆。
另一个例子是类gce_MakeCirc提供了一个框架,用于定义圆的几何构造中遇到的八个问题并实现八个相关的构造算法。
创建(或实现)的对象是一种算法,可以参考以找出答案,特别是:
如果不成功,状态会给出失败的原因。
gp_Pnt P1 (0.,0.,0.);
gp_Pnt P2 (0.,10.,0.);
gp_Pnt P3 (10.,0.,0.);
gce_MakeCirc MC (P1,P2,P3);
if (MC.IsDone()) {
const gp_Circ& C = MC.Value();
}
此外, gce, GCE2d和GC各有一个根类。此类是包中所有类的根,这些类返回状态。返回的状态(成功构造或构造错误)由枚举gce_ErrorType描述。
请注意,构造几何变换的类不返回状态,因此不会从 Root 继承。
以下用于从 gp 包构建实体的算法由 gce 包提供。
gp 包中的每个类,如 Circ、Circ2d、Mirror、Mirror2d 等,都有对应的 MakeCirc、MakeCirc2d、MakeMirror、MakeMirror2d 等。GCE 包中的类。
可以使用 gce 包类创建一个点,然后质询它以恢复相应的 gp 对象。
gp_Pnt2d Point1,Point2;
...
//Initialization of Point1 and Point2
gce_MakeLin2d L = gce_MakeLin2d(Point1,Point2);
if (L.Status() == gce_Done() ){
gp_Lin2d l = L.Value();
}
如果您不确定参数是否可以在不引发异常的情况下创建 gp 对象,这将非常有用。在上述情况下,如果 Point1 和 Point2 更接近 MakeLin2d 要求的容差值,则函数 Status 将返回枚举gce_ConfusedPoint。这告诉您为什么无法创建 gp 对象。如果您知道点 1 和点 2 之间的点由超过容差值的值分隔,则可以直接创建 gp 对象,如下所示:
gp_Lin2d l = gce_MakeLin2d(Point1,Point2);
GC 和 GCE2d 包提供了用于从 Geom 和 Geom2D 包构建实体的算法实现。它们实现与 gce 包相同的算法,并且还包含修剪曲面和曲线的算法。可以使用以下算法:
GCE2d包中的每个类,如Circle,Ellipse,Mirror等,都有相应的MakeCircle,MakeEllipse,MakeMirror等来自 Geom2d 包的类。此外,类 MakeArcOfCircle 从 Geom2d 返回一个类型为 TrimmedCurve 的对象。
GC 包中的每个类,如 Circle、Ellipse、Mirror 等,都有对应的 MakeCircle、MakeEllipse、MakeMirror 等来自 Geom* 包的类。以下类从 Geom 返回类型为 TrimmedCurve 的对象:
与BSplines之间的转换组件有两个不同的目的:
“与BSplines之间的转换”组件由三个包组成。
转换包提供了将以下内容转换为 BSpline 曲线或曲面的算法:
这些算法计算定义生成的BSpline曲线或曲面所需的数据。然后,可以直接在算法中使用这些基本数据(度数、周期特征、极点和权重、节点和多重性),或者可以通过调用类Geom2d_BSplineCurve、Geom_BSplineCurve 或 Geom_BSplineSurface 提供的适当构造函数来构造曲线或曲面。
Geom2dConvert软件包提供以下内容:
GeomConvert软件包还提供以下内容:
曲线上的点组件包含高级函数,为计算 2D 或 3D 曲线上的点的复杂算法提供 API。
以下特征点存在于 3D 空间中的参数化曲线上:
GCPnts 包提供了计算这些点的算法:
让我们采用一个自适应曲线 C,即一个对象,它是包 Geom2d(在Adaptor_Curve2d曲线的情况下)或包 Geom 的 3D 曲线(在Adaptor_Curve曲线的情况下)提供的服务与计算算法在曲线上所需的服务之间的接口。调整曲线按以下方式创建:
2D案例 :
Handle(Geom2d_Curve) mycurve = ... ;
Geom2dAdaptor_Curve C (mycurve) ;
3D案例 :
Handle(Geom_Curve) mycurve = ... ;
GeomAdaptor_Curve C (mycurve) ;
然后使用以下对象构造算法:
GCPnts_UniformDeflection myAlgo () ;
Standard_Real Deflection = ... ;
myAlgo.Initialize ( C , Deflection ) ;
if ( myAlgo.IsDone() )
{
Standard_Integer nbr = myAlgo.NbPoints() ;
Standard_Real param ;
for ( Standard_Integer i = 1 ; i <= nbr ; i++ )
{
param = myAlgo.Parameter (i) ;
...
}
}
用于计算 2D 和 3D 中点、曲线和表面之间最小距离的类由 GeomAPI 和 Geom2dAPI 包提供。
这些包计算以下各项之间的距离极值:
GeomAPI_ProjectPointOnCurve类允许计算点和曲线之间的所有极值。极值是与曲线正交的线段的长度。GeomAPI_ProjectPointOnSurface类允许计算点和表面之间的所有极值。极值是与表面正交的线段的长度。这些类使用“投影”标准进行优化。
Geom2dAPI_ExtremaCurveCurve类允许计算两条二维几何曲线之间的所有最小距离。GeomAPI_ExtremaCurveCurve类允许计算两条 3D 几何曲线之间的所有最小距离。这些类使用欧几里得距离作为优化标准。
GeomAPI_ExtremaCurveSurface类允许计算 3D 曲线和曲面之间的一个极值。极值是与曲线和曲面正交的线段的长度。此类使用“投影”条件进行优化。
GeomAPI_ExtremaSurfaceSurface 类允许计算两个表面之间的一个最小距离和一个最大距离。此类使用欧几里得距离计算最小值,并使用“投影”条件计算最大值。
Geom2d 包定义 2dspace 中的几何对象。所有几何图元都经过 STEP 处理。对象通过引用进行处理。
特别是,Geom2d包提供了以下类:
以下对象可用:
在创建几何对象之前,有必要确定如何处理对象。Geom2d 包提供的对象按引用而不是按值处理。复制实例会复制句柄,而不是对象,以便对一个实例的更改反映在每次出现时。如果需要一组对象实例而不是单个对象实例,则可以使用 TColGeom2d 包。该软件包为Geom2d软件包中的曲线提供了一维数组和序列的标准和常用实例化。所有对象都有两个版本:
Geom2d曲线的关键特征是它们是参数化的。每个类都提供函数来处理曲线的参数方程,特别是计算曲线上参数 u 的点和此时 1、2…、N 阶的导数向量。
作为参数化的结果,Geom2d曲线是自然定向的。
参数化和方向将基本Geom2d曲线与gp包提供的等效曲线区分开来。Geom2d包提供了转换功能,可以将Geom2d对象转换为gp对象,反之亦然。
此外, Geom2d包提供了更复杂的曲线,包括贝塞尔曲线,BSpline曲线,修剪曲线和偏移曲线。
Geom2d 对象根据多个级别的继承结构进行组织。
因此,椭圆(特定类Geom2d_Ellipse)也是圆锥曲线,继承自抽象类Geom2d_Conic,而贝塞尔曲线(具体类Geom2d_BezierCurve)也是有界曲线,继承自抽象类Geom2d_BoundedCurve;这两个例子也是曲线(抽象类Geom2d_Curve)。曲线、点和矢量继承自抽象类 Geom2d_Geometry该类描述了 Geom2d 包中任何几何对象的通用属性。
这种继承结构是开放的,可以描述从Geom2d包中提供的对象继承的新对象,前提是它们尊重要从中继承的类的行为。
最后, Geom2d对象可以在更复杂的数据结构中共享。例如,这就是为什么它们在拓扑数据结构中使用的原因。
Geom2d软件包使用GP软件包的服务来:
但是,Geom2d包本质上提供数据结构而不是算法。您可以参考GCE2d软件包来查找更多针对Geom2d对象的进化构造算法。
Geom 包定义 3D 空间中的几何对象,并包含所有基本的几何转换,例如标识、旋转、平移、镜像、缩放转换、转换组合等。以及取决于几何对象的参考定义的特殊功能(例如,在 B 样条曲线上添加控制点、修改曲线等)。所有几何图元都经过 STEP 处理。
特别是,它为以下对象提供了类:
以下对象可用:
几何曲线和曲面的关键特征是它们是参数化的。每个类都提供函数来处理曲线或曲面的参数方程,特别是计算:
由于这种参数化,几何曲线或曲面是自然定向的。
参数化和方向将基本几何曲线和曲面与 gp 包中具有相同(或相似)名称的类区分开来。Geom 包还提供了转换函数,用于将 Geom 对象转换为 gp 对象,反之亦然,如果可以进行这种转换。
此外, Geom 软件包提供更复杂的曲线和曲面,包括:
几何对象根据继承结构在多个级别上进行组织。因此,球体(具体类 Geom_SphericalSurface)也是基本曲面,继承自抽象类Geom_ElementarySurface,而贝塞尔曲面(具体类 Geom_BezierSurface)也是有界曲面,继承自抽象类Geom_BoundedSurface;这两个示例也是曲面(抽象类 Geom_Surface)。曲线、点和矢量继承自抽象类 Geom_Geometry该类描述了 Geom 包中任何几何对象的通用属性。
这种继承结构是开放的,可以描述从 Geom 包中提供的对象继承的新对象,前提是它们尊重要从中继承的类的行为。
最后,Geom 对象可以在更复杂的数据结构中共享。例如,这就是为什么它们在拓扑数据结构中使用的原因。
如果需要一组对象实例而不是单个对象实例,则可以使用 TColGeom 包。此包提供 Geom 包中曲线的一维和二维数组和序列的实例化。所有对象都有两个版本:
Geom 软件包使用 gp 软件包的服务来:
但是,Geom 包本质上提供数据结构,而不是算法。
您可以参考 GC 包来查找 Geom 对象的更多改进构造算法。
OCCT拓扑允许访问和操作对象的数据,而无需处理其2D或3D表示。OCCT 几何根据坐标或参数值提供对象的描述,而拓扑则描述参数空间中对象的数据结构。这些描述使用此空间中的位置和部分限制。
拓扑库允许您构建纯拓扑数据结构。拓扑定义简单几何实体之间的关系。通过这种方式,您可以将复杂形状建模为简单实体的程序集。由于内置的非流形(或混合维)功能,您可以混合构建模型:
例如,可以表示由多个不同实体组成的单个对象,其中包含连接到或未连接到外部边界的嵌入曲线和曲面。
抽象拓扑数据结构描述了一个基本实体——形状,它可以分为以下组件拓扑:
导线和实体可以是无限的,也可以是封闭的。
具有 3D 基础几何图形的面也可以指近似于下层曲面的连接三角形的集合。曲面可以未定义,只留下由三角形表示的面。如果是这样,则模型是纯多面体的。
拓扑定义了简单几何实体之间的关系,因此可以将这些几何实体链接在一起以表示复杂的形状。
摘要拓扑由六个包提供。前三个包描述了开放级联技术中使用的拓扑数据结构:
三个附加包提供了访问和操作此抽象拓扑的工具:
TopAbs 包提供了描述拓扑的基本概念和处理这些枚举的方法的一般枚举。它不包含任何类。此包已与拓扑的其余部分分开,因为它包含的概念足够通用,可供所有拓扑工具使用。这样可以避免通过保持独立于建模资源来重新定义枚举。***TopAbs***软件包定义了三个概念:
TopAbs包含TopAbs_ShapeEnum枚举,其中列出了不同的拓扑类型:
拓扑模型可以被视为具有邻接关系的对象图。在 2D 或 3D 空间中对零件进行建模时,它必须属于 ShapeEnum 枚举中列出的类别之一。TopAbspackage列出了所有对象,可以在任何模型中找到。它不能扩展,但可以使用子集。例如,实体的概念在2D中是无用的。
枚举项按从最复杂到最简单的顺序显示,因为对象在其描述中可以包含更简单的对象。例如,面参照其导线、边和顶点。
方向的概念由TopAbs_Orientation枚举表示。方向是在各种建模者中发现的方向感的广义概念。当形状限制几何域时,将使用此方法;并且与边界概念密切相关。这三种情况如下:
在每种情况下,用作更高维几何域边界的拓扑形式定义了两个局部区域,其中一个被任意视为默认区域。
对于受顶点限制的曲线,默认区域是参数大于顶点的点集。也就是说,它是顶点之后的曲线部分,沿着曲线的自然方向。
对于受边限制的曲面,缺省区域位于边的左侧,遵循其自然方向。更准确地说,它是法向向量到曲面的向量积和与曲线相切的向量所指向的区域。
对于受面限制的空间,默认区域位于曲面法线的负侧。
基于此默认区域,方向允许定义要保留的区域,称为内部或材料。内部有四个方向。
取向 | 描述 |
---|---|
向前 | 内部是默认区域。 |
反 | 内部是与默认区域互补的区域。 |
内部 | 内部包括两个地区。边界位于材料内部。例如,实体内的曲面。 |
外部 | 内陆不包括这两个地区。边界位于材料之外。例如,线框模型中的边。 |
四个方向如图:
方向的概念是一个非常笼统的概念,它可以用于出现区域或边界的任何上下文。因此,例如,在描述边和轮廓的交点时,不仅可以描述相交的顶点,还可以描述边如何与轮廓相交,将其视为边界。因此,边将分为两个区域:外部和内部,交点将是边界。因此,方向可以与交点顶点相关联,如下图所示:
取向 | 协会 |
---|---|
向前 | 进入 |
反 | 退出 |
内部 | 从内部触摸 |
外部 | 从外面触摸 |
交点的四个方向:
除了方向枚举外,TopAbs 包还定义了四种方法:
TopAbs_State枚举描述了一个顶点或一组顶点相对于某个区域的位置。有四个术语:
位置 | 描述 |
---|---|
在 | 重点是内部。 |
外 | 重点是外部。 |
上 | 该点位于边界上(在公差范围内)。 |
未知 | 该点的状态是不确定的。 |
引入了 UNKNOWN 术语,因为此枚举通常用于表示计算的结果,计算结果可能会失败。当无法知道一个点是在内部还是外部时,可以使用此术语,例如明线或面。
State 枚举还可用于指定对象的各个部分。下图显示了与面相交的边部分。如图所示,状态指定边与面相交的部分
局部坐标系可视为以下任一选项:
TopLoc 软件包区分了两个概念:
如果两个参考坐标由相同顺序的相同基本坐标组成,则它们相等。没有数值比较。因此,如果两个坐标不是从相同的基本坐标构建的,则它们可以对应于相同的变换,而不会相等。
例如,考虑三个基本坐标:R1、R2、R3 复合坐标为: C1 = R1 * R2, C2 = R2 * R3,C3 = C1 * R3,C4 = R1 * C2
注意:C3 和 C4 相等,因为它们都是 R1 * R2 * R3。
TopLoc 包主要针对拓扑数据结构,但它可以用于其他目的。
TopLoc_Datum3D类表示基本坐标的变化。必须共享此类更改,以便此类继承自Standard_Transient。坐标由变换gp_Trsfpackage表示。此转换没有比例因子。
TopoDS软件包描述了具有以下特征的拓扑数据结构:
如上所述,OCCT 拓扑描述了参数空间中对象的数据结构。这些描述使用此空间的某些部分的本地化和限制。可以用这些术语描述的形状类型是顶点、面和形状。顶点是根据参数空间中的定位来定义的,面和形状是根据该空间的限制来定义的。
OCCT拓扑描述还允许将这些术语中定义的简单形状组合成集合。例如,一组边形成一根导线;一组面形成一个壳,一组实体形成复合实体(开放式级联技术中的 CompSolid)。您还可以将任一类型的形状组合成化合物。最后,您可以为形状指定方向和位置。
按从顶点到复合实体的复杂程度顺序列出形状,导致我们将数据结构的概念作为如何将形状分解为一组更简单形状的知识。这实际上是 TopoDS 软件包的目的。
形状的模型是可共享的数据结构,因为它可以由其他形状使用。(一条边可以由实体的多个面使用)。可共享的数据结构通过引用处理。当简单参照不足时,将添加两条信息:方向和局部坐标参照。
***TopoDS_TShape***类是所有形状说明的根。它包含一个形状列表。如有必要,继承***TopoDS_TShape***的类可以携带几何域的描述(例如,与 TVertex 关联的几何点)。***TopoDS_TShape***是形状在其定义参考框架中的描述。此类由引用操作。
***TopoDS_Shape***类描述对形状的引用。它包含对底层抽象形状、方向和局部参考坐标的引用。此类由值操作,因此无法共享。
表示基础抽象形状的类永远不会直接引用。TopoDS_Shape类始终用于引用它。
特定于每个形状的信息(几何支持)始终通过继承添加到从***TopoDS_TShape***派生的类中。下图显示了由边连接的两个面形成的壳的示例。
在上图中,外壳由底层形状 TS 描述,面由 TF1 和 TF2 描述。从 TE1 到 TE7 有 7 条边,从 TV1 到 TV6 有 6 条顶点。
导线 TW1 参照从 TE1 到 TE4 的边;TW2 引用从 TE4 到 TE7。
边按如下方式引用顶点:
T E 1 ( T V 1 , T V 4 ) 、 T E 2 ( T V 1 , T V 2 ) 、 T E 3 ( T V 2 , T V 3 ) 、 T E 4 ( T V 3 , T V 4 ) 、 T E 5 ( T V 4 , T V 5 ) 、 T E 6 ( T 5 , T V 6 ) 、 T E 7 ( T V 3 , T V 6 ) TE1(TV1,TV4)、TE2(TV1,TV2)、TE3(TV2,TV3)、\\TE4(TV3,TV4)、TE5(TV4,TV5)、TE6(T5,TV6)、TE7(TV3,TV6) TE1(TV1,TV4)、TE2(TV1,TV2)、TE3(TV2,TV3)、TE4(TV3,TV4)、TE5(TV4,TV5)、TE6(T5,TV6)、TE7(TV3,TV6)
请注意,此数据结构不包含任何反向引用。所有引用都从更复杂的基础形状转到不太复杂的形状。稍后将介绍用于访问信息的技术。数据结构尽可能紧凑。子对象可以在不同对象之间共享。
两个非常相似的对象(可能是同一对象的两个版本)可能共享相同的子对象。在数据结构中使用本地坐标允许共享重复子结构的描述。
紧凑的数据结构避免了与复制操作相关的信息的丢失,复制操作通常用于创建对象的新版本或应用坐标更改。
下图显示了包含两个版本的实体的数据结构。第二个版本展示了一系列在不同位置钻孔的相同孔。数据结构紧凑,但保留了有关子元素的所有信息。
从 TSh2 到底层面 TFcyl 的三个参照具有关联的局部坐标系,这些坐标系对应于孔的连续位置。
TopoDS 基于类*TopoDS_Shape*和定义其底层形状的类。这有一定的优点,但主要缺点是这些类太笼统了。它们可以表示的不同形状不会键入它们(顶点、边缘等),因此不可能引入检查以避免不连贯,例如在边缘中插入面。
TopoDS 包提供两组类,一组继承基础形状,既没有方向也没有位置,另一组继承*TopoDS_Shape*,它们表示 TopAbs 包中列举的标准拓扑形状。
以下类继承形状:TopoDS_Vertex、TopoDS_Edge、TopoDS_Wire、TopoDS_Face、TopoDS_Shell、TopoDS_Solid、TopoDS_CompSolid 和*TopoDS_Compound*。尽管名称与继承自**TopoDS_TShape**的名称相似,但它们的使用方式却存在很大差异。
*TopoDS_Shape类和从它继承的类是操作拓扑对象的自然手段。TopoDS_TShape类是隐藏的。TopoDS_TShape描述没有方向的原始局部坐标系中的类。TopoDS_Shape是对具有方向和局部引用的TopoDS_TShape*的引用。
*TopoDS_TShape类被推迟;TopoDS_Shape*类不是。使用 TopoDS_Shape 类允许在不知道拓扑对象类型的情况下操作拓扑对象。它是一种通用形式。纯拓扑算法通常使用 TopoDS_Shape 类。
TopoDS_TShape类是通过引用操作的;按值TopoDS_Shape类。TopoDS_Shape只不过是用方向和局部坐标增强的参考。分享TopoDS_Shapes是没有意义的。重要的是共享基础TopoDS_TShapes。参数中的赋值或段落不会复制数据结构:这只会创建引用相同*TopoDS_TShape的新TopoDS_Shapes*。
尽管继承*TopoDS_TShape的类用于添加额外信息,但不应在从TopoDS_Shape继承的类中添加额外的字段。从TopoDS_Shape继承的类仅用于专用化引用,以便从静态类型控制(由编译器执行)中受益。例如,对于编译器来说,接收参数TopoDS_Face的例程比接收TopoDS_Shape*的例程更精确。派生除 TopoDS 中的类之外的其他类是没有意义的。对拓扑数据结构的所有引用都是使用 TopoDS 中定义的 Shape 类及其继承者进行的。
从 TopoDS_Shape 类继承的类没有构造函数,否则类型控件将通过隐式强制转换消失(C++ 的特征)。TopoDS 包提供了用于在这些子类之一中强制转换 *TopoDS_Shape*类对象的包方法,并具有类型验证。
下面的示例演示一个例程,该例程接收 TopoDS_Shape 类型的参数,然后将其放入变量 V 中(如果它是顶点)或调用方法 ProcessEdge(如果它是边)。
#include
#include
#include
void ProcessEdge(const TopoDS_Edge&);
void Process(const TopoDS_Shape& aShape) {
if (aShape.Shapetype() == TopAbs_VERTEX) {
TopoDS_Vertex V;
V = TopoDS::Vertex(aShape); // Also correct
TopoDS_Vertex V2 = aShape; // Rejected by the compiler
TopoDS_Vertex V3 = TopoDS::Vertex(aShape); // Correct
}
else if (aShape.ShapeType() == TopAbs_EDGE){
ProcessEdge(aShape) ; // This is rejected
ProcessEdge(TopoDS::Edge(aShape)) ; // Correct
}
else {
cout <<"Neither a vertex nor an edge ?";
ProcessEdge(TopoDS::Edge(aShape)) ;
// OK for compiler but an exception will be raised at run-time
}
}
*TopExp软件包提供了用于探索TopoDS*软件包描述的数据结构的工具。探索拓扑结构意味着查找给定类型的所有子对象,例如,查找实体的所有面。
TopExp 包提供了类*TopExp_Explorer*来查找给定类型的所有子对象。资源管理器是用以下内容构建的:
资源管理器访问整个结构,以便查找所请求类型的形状未包含在要避免的类型中。下面的示例显示了如何查找形状 S 中的所有面:
void test() {
TopoDS_Shape S;
TopExp_Explorer Ex;
for (Ex.Init(S,TopAbs_FACE); Ex.More(); Ex.Next()) {
ProcessFace(Ex.Current());
}
}
查找所有不在边中的顶点
for (Ex.Init(S,TopAbs_VERTEX,TopAbs_EDGE); ...)
查找 SHELL 中的所有面,然后查找不在 SHELL 中的所有面:
void test() {
TopExp_Explorer Ex1, Ex2;
TopoDS_Shape S;
for (Ex1.Init(S,TopAbs_SHELL);Ex1.More(); Ex1.Next()){
// visit all shells
for (Ex2.Init(Ex1.Current(),TopAbs_FACE);Ex2.More();
Ex2.Next()){
//visit all the faces of the current shell
ProcessFaceinAshell(Ex2.Current());
...
}
}
for(Ex1.Init(S,TopAbs_FACE,TopAbs_SHELL);Ex1.More(); Ex1.Next()){
// visit all faces not ina shell.
ProcessFace(Ex1.Current());
}
}
资源管理器假定对象仅包含相同或较低类型的对象。例如,如果搜索面,则不会查看导线、边或顶点以查看它们是否包含面。
TopExp包中的MapShapes方法允许填充映射。如果多次引用某个对象,则使用 Explorer 类的探索可以多次访问该对象。例如,实体的边通常由两个面参照。要只处理一次对象,必须将它们放置在 Map 中。
例
void TopExp::MapShapes (const TopoDS_Shape& S,
const TopAbs_ShapeEnum T,
TopTools_IndexedMapOfShape& M)
{
TopExp_Explorer Ex(S,T);
while (Ex.More()) {
M.Add(Ex.Current());
Ex.Next();
}
}
在下面的示例中,对象的所有面和所有边都是按照以下规则绘制的:
执行以下步骤:
void DrawShape ( const TopoDS_Shape& aShape,
const Standard_Integer nbIsos,
const Color FaceIsocolor,
const Color FreeEdgeColor,
const Color BorderEdgeColor,
const Color SharedEdgeColor)
{
// Store the edges in aMap.
TopTools_IndexedMapOfShape edgemap;
TopExp::MapShapes(aShape,TopAbs_EDGE,edgeMap);
// Create an array set to zero.
TColStd_Array1OfInteger faceCount(1,edgeMap.Extent());
faceCount.Init (0);
// Explore the faces.
TopExp_Explorer expFace(aShape,TopAbs_FACE);
while (expFace.More()) {
//Draw the current face.
DrawFaceIsos(TopoDS::Face(expFace.Current()),nbIsos,FaceIsoColor);
// Explore the edges of the face.
TopExp_Explorer expEdge(expFace.Current(),TopAbs_EDGE);
while (expEdge.More()) {
//Increment the face count for this edge.
faceCount(edgemap.FindIndex(expEdge.Current()))++;
expEdge.Next();
}
expFace.Next();
}
//Draw the edges of theMap
Standard_Integer i;
for (i=1;i<=edgemap.Extent();i++) {
switch (faceCount(i)) {
case 0 :
DrawEdge(TopoDS::Edge(edgemap(i)),FreeEdgeColor);
break;
case 1 :
DrawEdge(TopoDS::Edge(edgemap(i)),BorderEdgeColor);
break;
default :
DrawEdge(TopoDS::Edge(edgemap(i)),SharedEdgeColor);
break;
}
}
}
TopTools 软件包包含用于利用 TopoDS 数据结构的工具。它是 TCollection 包中工具的实例化,其中包含 TopoDS 的 Shape 类。
使用TopTools_Map,可以保留一组对形状的引用而不会重复。以下示例将数据结构的大小计为多个 TShapes。
#include
Standard_Integer Size(const TopoDS_Shape& aShape)
{
// This is a recursive method.
// The size of a shape is1 + the sizes of the subshapes.
TopoDS_Iterator It;
Standard_Integer size = 1;
for (It.Initialize(aShape);It.More();It.Next()) {
size += Size(It.Value());
}
return size;
}
如果数据结构中有共享,则此程序不正确。
因此,对于四条边的轮廓,它应该计算 1 根导线 + 4 条边 +4 个顶点,结果为 9,但由于每个顶点由两条边共享,该程序将返回 13。一种解决方案是将所有形状放在映射中,以避免对它们进行两次计数,如以下示例所示:
#include
#include
void MapShapes(const TopoDS_Shape& aShape,
TopTools_MapOfShape& aMap)
{
//This is a recursive auxiliary method. It stores all subShapes of aShape in a Map.
if (aMap.Add(aShape)) {
//Add returns True if aShape was not already in the Map.
TopoDS_Iterator It;
for (It.Initialize(aShape);It.More();It.Next()){
MapShapes(It.Value(),aMap);
}
}
}
Standard_Integer Size(const TopoDS_Shape& aShape)
{
// Store Shapes in a Mapand return the size.
TopTools_MapOfShape M;
MapShapes(aShape,M);
return M.Extent();
}
注意有关映射的更多详细信息,请参阅 TCollection 文档(基础类参考手册)。
下面的示例更加雄心勃勃,并编写了一个使用 IndexedMap 复制数据结构的程序。副本的结构相同,但与原件没有任何共同之处。主要算法如下:
#include
#include
#include
#include
#include
TopoDS_Shape Copy(const TopoDS_Shape& aShape,
const TopoDS_Builder& aBuilder)
{
// Copies the wholestructure of aShape using aBuilder.
// Stores all thesub-Shapes in an IndexedMap.
TopTools_IndexedMapOfShape theMap;
TopoDS_Iterator It;
Standard_Integer i;
TopoDS_Shape S;
TopLoc_Location Identity;
S = aShape;
S.Location(Identity);
S.Orientation(TopAbs_FORWARD);
theMap.Add(S);
for (i=1; i<= theMap.Extent(); i++) {
for(It.Initialize(theMap(i)); It.More(); It.Next()) {
S=It.Value();
S.Location(Identity);
S.Orientation(TopAbs_FORWARD);
theMap.Add(S);
}
}
}
在上面的示例中,索引 i 是 Map 中未处理的第一个对象的索引。当i达到与映射相同的大小时,这意味着一切都已处理。处理包括在 Map 中插入所有子对象,如果它们尚未在 Map 中,则以大于 i 的索引插入它们。
请注意,插入的对象带有设置为标识的本地引用和 FORWARD 方向。只有底层的 TShape 才引起极大的兴趣。
//Create an array to store the copies.
TopTools_Array1OfShapetheCopies(1,theMap.Extent());
// Use a recursivefunction to copy the first element.
void AuxiliaryCopy (Standard_Integer,
const TopTools_IndexedMapOfShape &,
TopTools_Array1OfShape &,
const TopoDS_Builder&);
AuxiliaryCopy(1,theMap,theCopies,aBuilder);
// Get the result with thecorrect local reference and orientation.
S = theCopies(1);
S.Location(aShape.Location());
S.Orientation(aShape.Orientation());
return S;
下面是辅助函数,它将秩 i 的元素从映射复制到表中。此方法检查对象是否已复制;如果未复制,则在表中执行空副本,并通过在映射中找到其排名来插入所有子元素的副本。
void AuxiliaryCopy(Standard_Integer index,
const TopTools_IndexedMapOfShapes& sources,
TopTools_Array1OfShape& copies,
const TopoDS_Builder& aBuilder)
{
//If the copy is a null Shape the copy is not done.
if (copies(index).IsNull()) {
copies(index) =sources(index).EmptyCopied();
//Insert copies of the sub-shapes.
TopoDS_Iterator It;
TopoDS_Shape S;
TopLoc_Location Identity;
for(It.Initialize(sources(index)),It.More(), It.Next ()) {
S = It.Value();
S.Location(Identity);
S.Orientation(TopAbs_FORWARD);
AuxiliaryCopy(sources.FindIndex(S),sources,copies,aBuilder);
S.Location(It.Value().Location());S.Orientation(It.Value().Orientation()); aBuilder.Add(copies(index),S);
}
}
}
线浏览器
*BRepTools_WireExplorer*类可以按其连接顺序访问导线的边缘。
例如,在图像中的导线中,我们希望按 {e1, e2, e3,e4, e5} 的顺序恢复边缘:
但是,*TopExp_Explorer*以任何顺序恢复线路。
TopoDS_Wire W = ...;
BRepTools_WireExplorer Ex;
for(Ex.Init(W); Ex.More(); Ex.Next()) {
ProcessTheCurrentEdge(Ex.Current());
ProcessTheVertexConnectingTheCurrentEdgeToThePrevious
One(Ex.CurrentVertex());
}
BRepLProp 包提供形状的局部属性组件,该组件包含计算 BRep 模型中边和面上的各种局部属性的算法。
可以查询的本地属性包括:
分析的边和面被描述为 BRepAdaptor 曲线和曲面,它们为形状提供用于描述其几何支撑的界面。局部属性的基点由曲线上的 u 参数值或曲面上的 (u, v) 参数值定义。
“曲线和曲面的局部属性”组件提供了用于计算几何曲线(在 2D 或 3D 空间中)或曲面上的各种局部属性的算法。它由以下部分组成:
曲线可以是*Geom_Curve曲线(在 3D 空间中)或Geom2d_Curve曲线(在平面中)。曲面是Geom_Surface*曲面。计算局部属性的点由曲线上的 u 参数值和曲面上的 (u,v) 参数值定义。
可以查询上述点的相同局部属性,还可以查询 2D 曲线:
要检查曲面的凹度,请执行以下操作:
GeomAbs_Shape枚举中介绍了曲线和曲面支持的连续性类型。
在曲线方面,支持以下类型的连续性(见下图):
*注意:*几何连续性(G1、G2)意味着曲线可以重新参数化以具有参数化(C1、C2)连续性。
支持以下类型的表面连续性:
对于单个曲面,两个曲面的连接(见上图)仅定义其在每个交点中的连续性。连接的平滑度是相交曲线上连续性的最小值。
边的规则性是共享此边的两个面连接的平滑度。换句话说,规则性是边上每个点的连接面之间的最小连续性。
边缘的规律性可以通过BRep_Builder::Continuity方法设置。要获得规律性,请使用BRep_Tool::Continuity方法。
像Fillet 这样的一些算法通过自己的算法设置生成的边的规律性。另一方面,其他一些算法(如布尔运算、形状修复等)不设置规律性。如果需要在形状上正确设置规则性,则可以使用方法BRepLib::EncodeRegularity。它计算并为形状的所有边缘设置正确的值。
规则性标志被以下高级算法广泛使用:倒角、拔模角度、隐藏线去除、糊盒机。
形状的全局属性组件提供用于计算 3D 空间中复合几何系统的全局属性的算法,以及用于查询计算结果的框架。
为系统计算的全局属性是:
几何系统通常定义为形状。根据分析它们的方式,这些形状将提供以下属性:
可以将几个系统的全局属性组合在一起,以给出由所有单个系统的总和组成的系统的全局属性。
“形状的全局属性”组件由以下部分组成:
GeomLProp 和 Geom2dLProp 软件包提供计算曲线和曲面局部属性的算法
曲线(对于一个参数)具有以下局部属性:
曲面(对于两个参数 U 和 V)具有以下局部属性:
可以使用以下方法:
请注意,B样条曲线和曲面是可以接受的,但它们不会被切割成所需连续性的碎片。这是全球连续性,这是可见的。
一些开放级联技术通用算法理论上可以适用于多种类型的曲线或曲面。
为此,他们只需通过接口获取分析曲线或曲面所需的服务,以便获得单个 API,无论曲线或曲面的类型如何。这些接口称为适配器。
例如, Adaptor3d_Curve是一个抽象类,它通过使用任何 3D 曲线的算法提供所需的服务。
GeomAdaptor软件包提供接口:
Geom2dAdaptor软件包提供接口:
BRep适配器封装提供接口:
编写对几何对象进行操作的算法时,请使用 Adaptor3d(或 Adaptor2d)对象。
因此,如果您为该对象提供派生自 Adaptor3d 或 Adaptor2d 的接口,则可以将该算法用于任何类型的对象。这些接口易于使用:只需从Geom2d曲线创建自适应曲线或曲面,然后将此自适应曲线用作算法的参数。这需要它。
边界框用于许多 OCCT 算法。最常见的用途是作为过滤器,避免检查形状对之间的过多干涉(检查边界框之间的干涉比形状之间的干涉要简单得多,如果它们不干涉,那么搜索相应形状之间的干涉就没有意义)。通常,边界框可以分为两种主要类型:
下图说明了使用OBB比AABB更好的示例。
此图中的 AABB 受到干扰。因此,许多OCCT算法会花费大量时间来干扰形状。然而, 如果我们检查没有干扰的 OBB, 那么就不需要搜索形状之间的干涉.此时,创建和分析 OBB 比使用 AABB 的类比运算花费的时间要多得多.
此图中的 AABB 受到干扰。因此,许多OCCT算法会花费大量时间来干扰形状。然而, 如果我们检查没有干扰的 OBB, 那么就不需要搜索形状之间的干涉.此时,创建和分析 OBB 比使用 AABB 的类比运算花费的时间要多得多.
BRepBndLib 类包含从形状创建边界框(AABB和 OBB)的方法。
该算法在Thomas Larsson和Linus Källberg(FastOBBs.pdf)的“紧拟合导向边界框的快速计算”中进行了描述。它包括以下步骤:
(待更新…)
为了从点集创建最佳OBB使用与上述相同的算法,但对逻辑进行了一些简化并增加了计算时间.为了获得最佳的OBB, 有必要检查所有可能的轴, 这些轴可以由极点创建.由于极值点仅对初始轴有效,因此有必要在每个轴上投影整组点。这种方法通常提供更紧密的OBB但性能较低.该算法的复杂性仍然是线性的,并且使用BVH作为点集,它是 O ( N + C ∗ l o g ( N ) ) O(N + C * log(N)) O(N+C∗log(N))。
以下是使用125K节点集的模型的最佳和非最佳OBB示例:
在这种情况下,非最佳 OBB 的计算需要 0.007 秒, 最佳 - 0.1 秒, 这大约慢了 14 倍.这样的性能与通过PCA方法为这种形状创建OBB相当 (见下文) 大约需要 0.17 秒.
最优OBB的计算由BRepBndLib::AddOBB方法中与PCA算法相同的IsOptimal标志控制。
这些算法在 Bnd_OBB::ReBuild(…) 方法中实现。
该算法包含以下步骤:
根据“定向边界框的分离轴定理” ,需要检查15个分隔轴:框的6个轴和9个是它们的交叉乘积。
分析轴的算法l如下:
(待更新…)
如果OBB在至少一个轴(15)方面没有受到干扰,那么它们根本不会受到干扰.
创建一个新的 OBB基于源点和给定边界框的所有顶点.
方法 *BRepBndLib::AddOBB( … )*允许从复杂对象 TopoDS_Shape 创建边界框。此方法使用从点集创建OBB和基于惯性轴创建OBB部分中描述的算法。
如果形状的外壳可以由其中包含的一组点表示,则使用第一种算法。也就是说,只有以下元素是点集的来源:
如果无法提取所需的点集,则基于惯性轴创建OBB部分中的算法用于OBB创建.
包* BRepBndLib* 包含用于创建形状的 AABB 的方法 BRepBndLib::Add(…)、BRepBndLib::AddClose(…) 和 BRepBndLib::AddOptimal(…)*。