介绍
布尔运算用于从两组形状的组合中创建新形状。本文档全面描述了布尔运算组件中的算法,因为它是在 Open CASCADE 技术中实现的。布尔组件包含:
- 通用联合操作器(GFA),
- 布尔运算符 (BOA),
- 部分操作员 (SA),
- 分离器操作员 (SPA)。
GFA 是 BOA、SPA、SA 的基础算法。
GFA 具有基于历史的架构,旨在允许使用 OCAF 命名功能。GFA 的架构是可扩展的,允许基于它创建新的算法。
概述
运营商
布尔运算符
布尔运算符在两组Objects和Tools之间提供以下操作:
- FUSE – 两组的联合;
- COMMON – 两组的交集;
- CUT – 两组之间的差异。
每个组由任意数量的TopoDS_Shape参数组成。
运算符可以表示为:
R B =B j (G 1 , G 2 ),
在哪里:
- *R B * – 运算结果;
- *B j * – 类型j的操作(通用、联合、切断);
- *G 1 ={S 11 , S 12 … S 1n1 }* 参数组(对象);
- *G 2 ={S 21 , S 22 … S 2n2 }* 参数组(工具);
- *n 1 * –对象组中的参数数量;
- *n 2 * –工具组中的参数数量。
注意有一个操作Cut21,它是前切操作的扩展,即Cut21=Cut(G2, G1)。
有关更多详细信息,请参阅布尔运算算法部分。
通用联合操作员
根据TopoDS_Shape,通用熔断器运算符可以应用于任意数量的参数。
GFA算子可以表示为:
R GF = GF (S 1 , S 2 … S n ),
在哪里
- *R GF * – 运算结果,
- *S 1 , S 2 … S n * – 操作的参数,
- n – 参数的数量。
布尔运算符 *R B * 的结果可以从 *R GF * 获得。
例如,对于两个参数 *S 1 * 和 *S 2 *,结果 *R GF * 是
R GF = GF (S 1 , S 2 ) = S p1 + S p2 + S p12
该图表明
- B共同(S 1 , S 2 ) = S p12 ;
- B cut12 (S 1 , S 2 ) = S p1 ;
- B cut21 (S 1 , S 2 ) = S p2 ;
- B熔断器(S 1 , S 2 ) = S p1 +S p2 +S p12
R GF =GF (S 1 , S 2 ) = B熔断器= B common + B cut12 + B cut21。
*R GF * 包含 *R B * 的组件这一事实允许将 GFA 视为 BOA 的一般情况。因此,可以将 BOA 实现为 GFA 的子类。
有关更多详细信息,请参阅通用联合算法部分。
分离器运算符
Splitter 运算符可以根据TopoDS_Shape应用于任意数量的参数。参数分为两组:Objects和Tools。SPA的结果包含属于Objects的所有部分,但不包含属于Tools的部分。
SPA算子可以表示如下:
R SPA =SPA (G 1 , G 2 ),其中:
- R SPA——是运算的结果;
- *G 1 ={S 11 , S 12 … S 1n1 }* 参数组(对象);
- *G 2 ={S 21 , S 22 … S 2n2 }* 参数组(工具);
- *n 1 * –对象组中的参数数量;
- *n 2 * –工具组中的参数数量。
结果 *R SPA * 可以从 *R GF * 获得。
例如,对于两个参数 *S 1 * 和 *S 2 *,结果 *R SPA * 是
R SPA =SPA(S 1 ,S 2 )=S p1 +S p12。
如果SPA的所有参数都是Objects并且没有Tools,则SPA的结果等同于GFA的结果。
例如,当 *G 1 * 由形状 *S 1 * 和 *S 2 * 组成时, SPA的结果是
R SPA =SPA(S 1 , S 2 ) = S p1 + S p2 + S p12 = GF (S 1 , S 2 )
*R GF * 包含 *R SPA * 的组件这一事实允许将GFA视为SPA的一般情况。因此,可以将SPA实现为GFA的子类。
有关更多详细信息,请参阅拆分器算法部分。
部分运算符
截面运算符SA可以根据TopoDS_Shape应用于任意数量的参数。SA的结果根据参数之间的干扰包含顶点和边。 SA 算子可以表示如下:R SA =SA(S1, S2… Sn),其中
- R SA——运算结果;
- S1, S2 … Sn – 操作参数;
- n – 参数的数量。
有关更多详细信息,请参阅部分算法部分。
部分算法
GFA、BOA、SPA 和 SA 具有相同的数据结构 (DS)。数据结构的主要目标是存储输入数据和中间结果的所有必要信息。
运算符由两个主要部分组成:
- 交叉部分 (IP)。IP 的主要目标是计算参数子形状之间的干扰。IP 使用 DS 检索输入数据并存储交叉点的结果。
- 建筑部分 (BP)。BP 的主要目标是构建所需的操作结果。这部分还使用 DS 来检索数据并存储结果。
从算子结果的定义来看,GFA、BOA、SPA和SA的主要区别在于建筑部分。算法的交叉部分是相同的。
术语和定义
本章提供了理解算法如何工作所必需的背景术语和定义。
干扰
有两组干扰。
首先,每个具有边界表示(顶点、边、面)的形状都有一个内部几何公差值。这些形状在公差方面相互干扰。当 3D 空间的一部分中,形状的基础几何形状之间的距离小于或等于形状公差的总和时,具有边界表示的形状会产生干扰。三种类型的形状:顶点、边和面——产生六种类型的BRep 干涉:
- 顶点/顶点,
- 顶点/边,
- 顶点/面,
- 边/边,
- 边/面和
- 面对面。
其次,当Z1和S2没有 BRep 干涉但S2完全在 Z1 内部时,实体Z1和形状S2之间会发生干涉。这些干扰是非 BRep 干扰。有四种可能的情况:
- 顶点/实体,
- 边/实心,
- 面/实心和
- 固体/固体。
顶点/顶点干涉
对于两个顶点Vi和Vj,它们对应的 3D 点之间的距离小于它们的公差Tol(Vi)和Tol(Vj)之和。
结果是具有 3D 点Pn和公差值Tol(Vn)的新顶点Vn。
Pn的坐标和值Tol(Vn)被计算为包含源顶点(V1, V2)的公差球体的球体的中心和半径。
顶点/边干涉
对于顶点Vi和边Ej ,顶点的 3D 点与其在边Ej的 3D 曲线上的投影之间的距离D小于或等于顶点Tol(Vi)和边Tol(Ej)的公差之和。
结果是顶点Vi对应的公差值Tol(Vi)=Max(Tol(Vi), D+Tol(Ej)),其中D = 距离 (Pi, PPi);
以及边Ej的3D 曲线Cj上的投影点PPi的参数 *t i * 。
顶点/面干涉
对于顶点Vi和面Fj ,顶点的 3D 点与其在面表面上的投影之间的距离D小于或等于顶点Tol(Vi)和面Tol(Fj)的公差之和。
结果是具有相应公差值Tol(Vi)=Max(Tol(Vi), D+Tol(Fj))的顶点Vi,其中D = 距离 (Pi, PPi)
和参数u i , vi是面Fj的面Sj上投影点PPi的参数。
边/边干涉
对于两条边Ei和Ej(具有相应的 3D 曲线Ci和Cj),在某些地方,曲线之间的距离小于(或等于)边的公差之和。
让我们检查两个案例:
在第一种情况下,两条边在公差方面具有 3D 曲线的一个或多个公共部分。
边/边干涉:常见零件
结果是:
- 边Ei的 3D 曲线Ci的参数范围[t i1 , t i2 ]。
- 边Ej的 3D 曲线Cj的参数范围[t j1 , t j2 ]。
在第二种情况下,两条边在公差方面有一个或几个共同点。
结果是具有 3D 点Pn和公差值Tol(Vn)的新顶点Vn。
Pn的坐标和值Tol(Vn)被计算为包围源边Ei、Ej的 3D 曲线Ci、Cj的对应最近点Pi、Pj的公差球体的球体的中心和半径。
- Pi的参数 *t i *用于 3D 曲线Ci。
- 3D 曲线Cj的Pj的参数 *t j * 。
边/面干涉
对于边Ei(具有相应的 3D 曲线Ci)和面Fj(具有相应的 3D 曲面Sj),在 3D 空间中存在一些地方,其中Ci和曲面Sj之间的距离小于(或等于)总和边Ei和面Fj的公差。
让我们检查两个案例:
在第一种情况下,边Ei和面Fj在公差方面有一个或几个共同部分。
结果是边Ei的 3D 曲线Ci的参数范围[t i1 , t i2 ]。
在第二种情况下,边Ei和面Fj在公差方面有一个或几个共同点。
结果是具有 3D 点Pn和公差值Tol(Vn)的新顶点Vn。
Pn的坐标和值Tol(Vn)被计算为包含3D 曲线Ci的对应最近点Pi、Pj和源边Ei、Fj的表面Sj的公差球的球的中心和半径。
- Pi的参数 *t i *用于 3D 曲线Ci。
- 面Fj的表面Sj上的投影点PPi的参数 *u i * 和 *v i * 。
面/面干涉
对于面Fi和面Fj(具有对应的面Si和Sj),在 3D 空间中存在一些地方,其中面之间的距离小于(或等于)面的公差之和。
在第一种情况下,结果包含相交曲线 *C ijk (k = 0, 1, 2…k N ,* 其中 *k N * 是具有对应公差值 *Tol(C ijk )*的相交曲线的数量。
面/面干扰:共同点
在第二种情况下,面Fi和面Fj有一个或几个新顶点*V ijm *,其中m=0,1,2, … mN,mN是交点的数量。
3D 点的坐标 *P ijm * 和值 *Tol(V ijm )* 被计算为包含表面Si、Sj的相应最近点Pi、Pj的公差球的球的中心和半径源形状Fi , Fj。
- 参数 *u j *, *v j * 属于点PPj投影在面Fj的表面Sj上。
- 参数 *u i * 和 *v i * 属于投影在面Fi的表面Si上的点PPi。
顶点/实体干涉
对于顶点Vi和实体Zj ,如果顶点Vi与Zj的任何子形状没有 BRep 干扰,并且Vi完全在实体Zj内,则存在顶点/实体干扰。
边/固体干涉
对于边Ei和实体Zj,如果边Ei及其子形状与Zj的任何子形状没有 BRep 干涉,并且Ei完全在实体Zj内,则存在边/实体干涉。
面/实体干涉
对于面Fi和实体Zj ,如果面Fi及其子形状与Zj的任何子形状没有 BRep 干涉,并且Fi完全在实体Zj内,则存在面/实体干涉。
固体/固体干扰
对于实体Zi和实体Zj,如果实体Zi及其子形状与Zj的任何子形状没有 BRep 干扰,并且Zi完全在实体Zj内,则存在实体/实体干涉。
计算顺序
形状之间的干涉是在形状尺寸值增加的基础上按以下顺序计算的:
- 顶点/顶点,
- 顶点/边,
- 边/边,
- 顶点/面,
- 边/面,
- 面对面,
- 顶点/实体,
- 边/实心,
- 面/实心,
- 固体/固体。
当较低的子形状Sik和Sjm之间存在干扰时,该顺序允许避免计算上层形状Si和Sj之间的冗余干扰。
结果
- 干涉的结果是一个形状,它可以是被干涉的形状本身(或其部分),也可以是一个新的形状。
- 干涉的结果是尺寸值小于或等于干涉形状的最小尺寸值的形状。例如,Vertex/Edge 干涉的结果是一个顶点,而不是一条边。
- 干涉的结果每次都会分裂零件上的源形状,因为它可以做到这一点。
铺路石
在大多数情况下,Vertex/Edge、Edge/Edge 和 Edge/Face 类型的干涉的结果是位于边上的顶点(新的或旧的)。
在大多数情况下,Face/Face 类型的干涉的结果是相交曲线,它穿过位于面上的一些顶点。
顶点Vi在曲线C上的位置可以通过曲线上顶点的3D点的参数t i的值来定义。Pave PVi on curve C是一个结构,包含顶点Vi和曲线上顶点的 3D 点的参数t i的对应值。曲线C可以是 3D 或 2D 曲线。
同一曲线C上的两条铺装PV1和PV2可以使用参数值进行比较
铺装的使用允许将顶点绑定到曲线(或任何包含曲线的结构:边、相交曲线)。
铺砌块
一组铺路 PVi (i=1, 2…nPV),其中nPV是曲线 C 的铺路数]可以使用曲线C上的参数t的值按升序排序。
铺路块PBi是相邻铺路之间的对象(边、相交曲线)的一部分。
任何有限源边E至少有一个包含两个铺路PVb和PVe的铺路块:
- 铺装 PVb对应于边曲线上具有最小参数t b的顶点Vb 。
- 铺装 PVe对应于边曲线上具有最大参数t e的顶点Ve 。
缩小范围
曲线C的铺装块PV以具有公差值Tol(V1)和Tol(V2)的顶点V1和V2为界。曲线C有自己的公差值Tol(C):
- 在边的情况下,公差值是边的公差。
- 在相交曲线的情况下,公差值是从相交算法中获得的。
铺砌块的理论参数范围为[t1C, t2C]。
铺装块的顶点V1和V2的位置可以不同。位置由以下条件确定:
该图表明,顶点的每个公差球都可以将铺装块的参数范围缩小到范围[t1S, t2S]。范围[t1S, t2S]是铺装块的收缩范围。
摊铺块的收缩范围是 3D 曲线的一部分,可能会干扰其他形状。
通用块
Edge/Edge、Edge/Face 类型的干涉产生的结果是公共零件。
在边/边干涉的情况下,公共部分是具有不同基边的铺装块。
如果铺砌块PB 1 , PB 2 …PB NbPB,其中NbPB是具有相同边界顶点并且几何重合的铺砌块的数量,则铺砌块形成公共块CB。
在边/面干涉的情况下,公共部分是位于一个或多个面上的铺路块。
如果铺砌块PBi在几何上与面Fj重合,则铺砌块形成公共块CB。
在一般情况下,公共块CB包含:
- 铺砌块PBi (i=0,1,2, 3…NbPB)。
- 一组面Fj (j=0,1…NbF),NbF – 面数。
面信息
结构FaceInfo包含以下信息:
- 为面铺设状态为In的块;
- 面的状态为In的顶点;
- 为面铺上状态为On的块;
- 面的状态为On的顶点;
- 从面的相交曲线铺砌块;
- 从面的交点建立的顶点。
面信息
在图中,对于面F1:
- 铺砌面的状态为In的块:*PB in1 *。
- 面的状态为In的顶点:*V in1 *。
- 摊铺面的状态为On的块:*PB on11 *、*PB on12 *、*PB on2 *、*PB on31 *、*PB on32 *、*PB on4 *。
- 面的状态为On的顶点:V1, V2, V3, V4, V5, V6。
- 从面的交叉曲线构建的铺砌块:*PB sc1 *。
- 从面的交点建立的顶点:无
数据结构
数据结构 (DS) 用于:
- 存储有关输入数据和中间结果的信息;
- 提供对信息的访问;
- 提供信息块之间的链接。
这些信息包括:
- 论据;
- 形状;
- 干扰;
- 铺砌块;
- 通用块。
数据结构在BOPDS_DS类中实现。
论据
参数是形状(根据TopoDS_Shape):
- 参数的数量是无限的。
- 每个参数都是一个有效的形状(就BRepCheck_Analyzer 而言)。
- 每个参数可以是以下类型之一(见表):
不 | 类型 | 类型索引 |
---|---|---|
1 | 化合物 | 0 |
2 | 复合体 | 1 |
3 | 实体 | 2 |
4 | 壳 | 3 |
5 | 面 | 4 |
6 | 线 | 5 |
7 | 边 | 6 |
8 | 顶点 | 7 |
- 类型0 (COMPOUND)的参数可以包括任意数量的任意类型 (0, 1…7) 的形状。
- 参数不应该是自干涉的,即通过任何拓扑实体(顶点、边、面)具有几何重合的参数的所有子形状必须共享这些实体。
- 对形状的基础几何类型没有限制。参数 *S i *的面或边可以具有 Open CASCADE Technology 建模算法支持的任何类型的基础几何(就GeomAbs_CurveType和GeomAbs_SurfaceType 而言)。
- 参数的面或边应具有连续性不小于 C1 的基础几何。
形状
有关 Shapes 的信息存储在结构BOPDS_ShapeInfo中。BOPDS_ShapeInfo类型的对象存储在数组类型的容器中。该数组允许通过索引(DS 索引)访问信息。结构BOPDS_ShapeInfo具有以下内容:
名称 | 内容 |
---|---|
我的形状 | 塑造自己 |
我的风格 | 形状类型 |
我的盒子 | 形状的 3D 边界框 |
我的子形状 | 子形状的 DS 索引列表 |
我的参考 | 一些辅助信息的 存储 |
我的标志 | 一些辅助信息的 存储 |
干扰
有关干扰的信息存储在从类BOPDS_Interf继承的类的实例中。
名称 | 内容 |
---|---|
BOPDS_Interf | 干扰根类 |
索引1 | 形状 1 的 DS 索引 |
索引2 | 形状 2 的 DS 索引 |
BOPDS_InterfVV | 存储顶点/顶点干涉 |
BOPDS_InterfVE | 存储顶点/边干涉 |
我的参数 | 边的曲线上顶点的点的参数值 |
BOPDS_InterfVF | 存储顶点/面干涉 |
我的,我的 | 面的表面上顶点的点的参数值 |
BOPDS_InterfEE | 边/边干扰的 存储 |
我的共同部分 | 公共部分(根据IntTools_CommonPart) |
BOPDS_InterfEF | 边/面干扰 存储 |
我的共同部分 | 公共部分(根据IntTools_CommonPart) |
BOPDS_InterfFF | 面/面干扰 存储 |
myTolR3D, myTolR2D | 在 3D 和 2D 中达到的曲线(点)的公差值 |
我的曲线 | 相交曲线(根据BOPDS_Curve) |
我的积分 | 交点(根据BOPDS_Point) |
BOPDS_InterfVZ | 存储顶点/实体干涉 |
BOPDS_InterfEZ | 边/固体干扰 存储 |
BOPDS_InterfFZ | 面/实体干涉 存储 |
BOPDS_InterfZZ | 存储固体/固体干涉 |
该图显示了BOPDS_Interf类的继承图。
铺装、铺装块和普通块
有关铺路的信息存储在BOPDS_Pave类型的对象中。
名称 | 内容 |
---|---|
BOPDS_铺路 | |
我的索引 | 顶点的 DS 索引 |
我的参数 | 曲线上顶点的 3D 点参数值。 |
有关铺路块的信息存储在BOPDS_PaveBlock类型的对象中。
名称 | 内容 |
---|---|
BOPDS_PaveBlock | |
我的边 | 铺装块产生的边的 DS 指数 |
我的原始边 | 源边的 DS 索引 |
我的铺路1 | 铺装1(根据BOPDS_Pave) |
我的铺路2 | 铺装2(就BOPDS_Pave 而言) |
myExtPaves | 用于在交叉过程中存储位于铺装块内的铺装 的铺装列表(以BOPDS_Pave 表示) |
我的通用块 | 如果铺砌块是公共块,则 对公共块的引用(根据BOPDS_CommonBlock ) |
我的收缩数据 | 铺装块的收缩范围 |
- 为了绑定到一条边(或相交曲线),BOPDS_PaveBlock类型的结构存储在一个列表类型(BOPDS_ListOfPaveBlock)的容器中。
- 在边的情况下,上面的所有铺砌块列表都存储在一个数组类型的容器中。该数组允许通过边铺砌块列表的索引来访问信息。该索引(如果存在)存储在字段myReference中。
公共块的信息存储在BOPDS_CommonBlock类型的对象中。
名称 | 内容 |
---|---|
BOPDS_CommonBlock | |
我的铺路砖 | 就通用块而言常见的铺装块列表 |
我的面 | 铺装块所在面的 DS 索引列表。 |
点和曲线
有关交点的信息存储在BOPDS_Point类型的对象中。
名称 | 内容 |
---|---|
BOPDS_Point | |
我的Pnt | 3D点 |
我的Pnt2D1 | 面上的二维点1 |
我的Pnt2D2 | 面上的二维点2 |
有关相交曲线的信息存储在BOPDS_Curve类型的对象中。
名称 | 内容 |
---|---|
BOPDS_Curve | |
我的曲线 | 相交曲线(根据IntTools_Curve) |
我的铺路砖 | 属于曲线的铺装块列表 |
我的盒子 | 曲线的边界框(以Bnd_Box 表示) |
面信息
有关FaceInfo的信息存储在结构BOPDS_FaceInfo中。结构BOPDS_FaceInfo具有以下内容。
名称 | 内容 |
---|---|
BOPDS_FaceInfo | |
myPaveBlocksIn | 为面铺装状态为 In 的块 |
我的顶点输入 | 面的状态为 In 的顶点 |
myPaveBlocksOn | 铺砌面的状态为 On 的块 |
我的顶点打开 | 面的状态为 On 的顶点 |
myPaveBlocksSc | 从面的相交曲线铺设块 |
我的顶点Sc | 从面的交点建立的顶点 + |
BOPDS_FaceInfo类型的对象存储在一个数组类型的容器中。该数组允许通过索引访问信息。该索引(如果存在)存储在字段myReference中。
根类
BOPAlgo_Options 类
BOPAlgo_Options类为算法提供以下选项:
- 设置合适的内存分配器;
- 检查错误和警告的存在;
- 打开/关闭并行处理;
- 设置操作的附加公差;
- 按用户请求中断操作;
- 在操作中使用定向边界框。
BOPAlgo_Algo 类
BOPAlgo_Algo类为所有算法提供了基本接口:
- 执行操作;
- 检查输入数据;
- 检查结果。
交叉部分
交叉部分 (IP) 用于
- 初始化数据结构;
- 计算参数(或其子形状)之间的干扰;
- 计算相同的域顶点、边;
- 建立分裂边;
- 构建截面边;
- 建立 p 曲线;
- 将所有获得的信息存储在 DS 中。
IP 在BOPAlgo_PaveFiller类中实现。
下一段中提供的描述与方法BOPAlgo_PaveFiller::Perform()的实现是一致的。
初始化
该步骤的输入数据是参数。初始化步骤的描述如表所示。
不 | 内容 | 执行 |
---|---|---|
1 | 初始化形状数组(根据Shapes)。填充形状数组。 | BOPDS_DS::Init() |
2 | 初始化阵列铺路块(在Pave、PaveBlock、CommonBlock 方面) | BOPDS_DS::Init() |
3 | 交集迭代器的初始化。交集迭代器是根据边界框计算参数的子形状之间的交集的对象。交集迭代器提供给定类型的干扰的近似数量(根据干扰) | BOPDS_Iterator |
4 | 交叉点上下文的初始化。交集上下文是一个包含几何和拓扑工具包(分类器、投影仪等)的对象。交集上下文用于缓存工具以提高算法性能。 | IntTools_Context |
计算顶点/顶点干涉
此步骤的输入数据是Initialization之后的 DS 。该步骤的描述如表所示:
不 | 内容 | 执行 |
---|---|---|
1 | 初始化顶点/顶点干涉数组。 | BOPAlgo_PaveFiller::PerformVV() |
2 | 访问干扰形状对(nVi, nVj)k, k=0, 1…nk,其中nVi和nVj是顶点Vi和Vj的 DS 索引,而nk是对的数量。 | BOPDS_Iterator |
3 | 计算受干扰顶点的连接链nV1C, nV2C… nVnC)k, C=0, 1…nCs,其中nCs是连接链的数量 | BOPAlgo_Tools::MakeBlocksCnx() |
4 | 从链VNc 构建新顶点。C=0, 1…nCs。 | BOPAlgo_PaveFiller::PerformVV() |
5 | 在 DS 中追加新顶点。 | BOPDS_DS::追加() |
6 | 在 DS 中附加相同的域顶点。 | BOPDS_DS::AddShapeSD() |
7 | 在 DS 中附加顶点/顶点干涉。 | BOPDS_DS::AddInterf() |
- 被干扰的顶点对是:(nV11, nV12), (nV11, nV13), (nV12, nV13), (nV13, nV15), (nV13, nV14), (nV14, nV15), (nV21, nV22), ( nV21, nV23), (nV22, nV23);
- 这些对产生两条链:(nV11, nV12, nV13, nV14, nV15)和(nV21, nV22, nV23);
- 每条链都用于相应地创建一个新顶点VN1和VN2。
图像中给出了受干扰顶点的连接链示例:
计算顶点/边干涉
此步骤的输入数据是计算顶点/顶点干扰后的 DS。
不 | 内容 | 执行 |
---|---|---|
1 | 初始化顶点/边干涉数组 | BOPAlgo_PaveFiller::PerformVE() |
2 | 访问干扰形状对(nVi, nEj)kk=0, 1…nk,其中nVi是顶点Vi的 DS 索引,nEj是边Ej的 DS 索引,nk是对的数量。 | BOPDS_Iterator |
3 | 计算铺垫。请参见顶点/边干涉 | BOPInt_Context::ComputeVE() |
4 | 为干涉中涉及 的边Ej初始化铺装块 | BOPDS_DS :: ChangePaveBlocks() |
5 | 根据Pave、PaveBlock 和 CommonBlock将铺装附加到铺装块中 | BOPDS_PaveBlock :: AppendExtPave() |
6 | 在 DS 中附加顶点/边干涉 | BOPDS_DS::AddInterf() |
更新铺装块
此步骤的输入数据是计算顶点/边干涉后的 DS。
不 | 内容 | 执行 |
---|---|---|
1 | 每个包含内部铺装的铺装块 PB 被内部铺装分割成新的铺装块PBN1、PBN2…PBNn。PB 被 DS 中的新铺路块PBN1、PBN2…PBNn取代。 | BOPDS_DS :: UpdatePaveBlocks() |
计算边/边干扰
此步骤的输入数据是更新铺砌块后的 DS。
不 | 内容 | 执行 |
---|---|---|
1 | 初始化边/边干涉数组 | BOPAlgo_PaveFiller::PerformEE() |
2 | 访问干扰形状对(nEi, nEj)k, k=0, 1…nk,其中nEi是边Ei的 DS 索引,nEj是边Ej的 DS 索引,nk是对的数量。 | BOPDS_Iterator |
3 | 如有必要,为干涉中涉及的边初始化铺装块。 | BOPDS_DS :: ChangePaveBlocks() |
4 | 访问干扰形状的铺装块:(PBi1, PBi2…PBiNi)用于边Ei和(PBj1, PBj2…PBjNj)用于边Ej | BOPAlgo_PaveFiller::PerformEE() |
5 | 如有必要, 根据Pave、PaveBlock 和 CommonBlock 计算摊铺块的收缩数据。 | BOPAlgo_PaveFiller::FillShrunkData() |
6 | 计算铺装块PBix和PBiy的边/边干涉。计算的结果是一组IntTools_CommonPart类型的对象 | IntTools_EdgeEdge |
7.1 | 对于每个VERTEX类型的CommonPart :创建新顶点VNi (i =1, 2…,NbVN),其中NbVN是新顶点的数量。使用步骤初始化和计算顶点/顶点干涉与顶点VNi相交,如下所示: a) 创建一个具有自己的 DS的BOPAlgo_PaveFiller类型的新对象PFn ;b) 使用新顶点VNi (i=1, 2…,NbVN), NbVN作为PFn的参数(根据TopoDs_Shape);c)为PFn调用方法Perform()。生成的顶点VNXi (i=1, 2…,NbVNX),其中NbVNX是顶点的数量,是通过VNi和PVn的结果之间的映射获得的。 | BOPTools_Tools::MakeNewVertex() |
7.2 | 对于 EDGE类型的每个CommonPart :计算铺装块的重合连接链(PB1C, PB2C…PNnC)k, C=0, 1…nCs,其中nCs是连接链的数量。从链中创建公共块(CBc. C=0, 1…nCs)。将普通块连接到铺路块上。 | BOPAlgo_Tools::PerformCommonBlocks() |
8 | 后期处理。在Pave、PaveBlock 和 CommonBlock方面将VNXi的铺装附加到相应的铺装块中 | BOPDS_PaveBlock :: AppendExtPave() |
9 | 用铺路分割公共块 CBc。 | BOPDS_DS :: UpdateCommonBlock() |
10 | 在 DS 中附加边/边干扰。 | BOPDS_DS::AddInterf() |
图中给出了铺路块重合链的示例:
- 重合的铺砌块对为:(PB11, PB12), (PB11, PB13), (PB12, PB13), (PB21, PB22), (PB21, PB23), (PB22, PB23)。
- 这些对产生两条链:(PB11、PB12、PB13)和(PB21、PB22、PB23)。
计算顶点/面干涉
此步骤的输入数据是计算边/边干扰后的 DS。
不 | 内容 | 执行 |
---|---|---|
1 | 初始化顶点/面干涉数组 | BOPAlgo_PaveFiller::PerformVF() |
2 | 访问干扰形状对(nVi, nFj)k, k=0, 1…nk,其中nVi是顶点Vi的 DS 索引,nFj是边Fj的 DS 索引,nk是对的数量。 | BOPDS_Iterator |
3 | 计算干涉参见顶点/面干涉 | BOPInt_Context::ComputeVF() |
4 | 在 DS 中附加顶点/面干涉 | BOPDS_DS::AddInterf() |
5 | 对每个新顶点VNXi (i=1, 2…,NbVNX) 重复步骤 2-4,其中NbVNX是顶点数。 | BOPAlgo_PaveFiller::TreatVerticesEE() |
计算边/面干涉
此步骤的输入数据是计算 Vertex/Face Interferences 后的 DS。
不 | 内容 | 执行 |
---|---|---|
1 | 初始化边/面干涉数组 | BOPAlgo_PaveFiller::PerformEF() |
2 | 访问干扰形状对(nEi, nFj)k, k=0, 1…nk,其中nEi是边Ei的 DS 索引,nFj是面Fj的 DS 索引,nk是对的数量。 | BOPDS_Iterator |
3 | 如有必要,为干涉中涉及的边初始化铺装块。 | BOPDS_DS::ChangePaveBlocks() |
4 | 访问边Ei的受干扰边(PBi1, PBi2…PBiNi)的铺装块 | BOPAlgo_PaveFiller::PerformEF() |
5 | 如有必要 ,计算铺装块的收缩数据(根据Pave、PaveBlock 和 CommonBlock )。 | BOPAlgo_PaveFiller::FillShrunkData() |
6 | 计算铺装块PBix和面nFj的边/面干涉。计算的结果是一组IntTools_CommonPart类型的对象 | IntTools_EdgeFace |
7.1 | 对于每个VERTEX类型的CommonPart :创建新顶点VNi (i=1, 2…,NbVN),其中NbVN是新顶点的数量。合并顶点VNi如下: a)使用自己的 DS创建BOPAlgo_PaveFiller类型的新对象PFn ;b) 使用新顶点VNi (i=1, 2…,NbVN), NbVN作为PFn的参数(根据TopoDs_Shape);c)为PFn调用方法Perform()。生成的顶点VNXi (i=1, 2…,NbVNX),其中NbVNX是顶点的数量,是通过VNi之间的映射获得的和PVn的结果。 | BOPTools_Tools::MakeNewVertex()和BOPAlgo_PaveFiller::PerformVertices1() |
7.2 | 对于EDGE类型的每个CommonPart :从位于面上的铺砌块创建公共块(CBc. C=0, 1…nCs) 。将普通块连接到铺路块上。 | BOPAlgo_Tools::PerformCommonBlocks() |
8 | 后期处理。根据Pave、PaveBlock 和 CommonBlock将VNXi的铺砌附加到相应的铺砌块中。 | BOPDS_PaveBlock :: AppendExtPave() |
9 | 将铺装块和普通块CBc按铺装块分开。 | BOPAlgo_PaveFiller::PerformVertices1(),BOPDS_DS :: UpdatePaveBlock()和BOPDS_DS :: UpdateCommonBlock() |
10 | 在 DS 中附加边/面干涉 | BOPDS_DS::AddInterf() |
11 | 为所有具有 EF 公共部分的面 更新FaceInfo 。 | BOPDS_DS :: UpdateFaceInfoIn() |
构建分割边
此步骤的输入数据是计算边/面干扰后的 DS。
对于每个铺路块PB,请执行以下步骤:
不 | 内容 | 执行 |
---|---|---|
1 | 获取实际铺装块PBR ,如果PB不是公共块,则等于PB ;如果PB是公共块,则等于 *PB 1 * 。*PB 1 * 是公共块的铺砌块列表中的第一个铺砌块。请参阅铺装、铺装块和通用块。 | BOPAlgo_PaveFiller::MakeSplitEdges() |
2 | 使用来自DS和PBR的信息构建分裂边Esp。 | BOPTools_Tools::MakeSplitEdge() |
3 | 计算Esp 的BOPDS_ShapeInfo内容 | BOPAlgo_PaveFiller::MakeSplitEdges() |
4 | 将BOPDS_ShapeInfo内容附加到 DS | BOPDS_DS::追加() |
计算面/面干涉
此步骤的输入数据是构建分割边后的 DS。
不 | 内容 | 执行 |
---|---|---|
1 | 初始化面/面干涉数组 | BOPAlgo_PaveFiller::PerformFF() |
2 | 访问干扰形状对(nFi, nFj)k, k=0, 1…nk,其中nFi是边Fi的 DS 索引,nFj是面Fj的 DS 索引,nk是对的数量。 | BOPDS_Iterator |
3 | 计算面/面干涉 | IntTools_FaceFace |
4 | 在 DS 中附加面/面干涉。 | BOPDS_DS::AddInterf() |
构建剖面边
此步骤的输入数据是计算面/面干扰后的 DS。
不 | 内容 | 执行 |
---|---|---|
1 | 对于每个面/面干扰nFi, nFj,检索FaceInfo。从交点VPk (k=1, 2…, NbVP)创建拔模顶点,其中NbVP是新顶点的数量,如果VPk ≠ Vm (m = 0, 1, 2 ),则从交点创建拔模顶点VPk … NbVm),其中Vm是面nFi和nF,j的现有顶点(根据TopoDs_Shape的On或In),NbVm是面nFi和nF,j上存在的顶点数≠ – 表示在顶点/顶点干涉方面不重合。 | BOPAlgo_PaveFiller::MakeBlocks() |
2 | 对于每条相交曲线Cijk | |
2.1 | 使用现有顶点为曲线创建铺装 PVc,即面nFi和nFj的顶点 On 或 In(根据FaceInfo ) 。附加铺装PVc | BOPAlgo_PaveFiller::PutPaveOnCurve()和BOPDS_PaveBlock::AppendExtPave() |
2.2 | 创建技术顶点Vt,它们是相交曲线的边界点(具有公差Tol(Cijk)的值)。曲线Cijk上具有参数Tt的每个顶点Vt在曲线Cijk上形成铺装PVt。追加技术铺垫。 | BOPAlgo_PaveFiller::PutBoundPaveOnCurve() |
2.3 | 使用pave (k=1, 2…, NbPB)为曲线创建铺装块PBk,其中NbPB是铺装块的数量 | BOPAlgo_PaveFiller::MakeBlocks() |
2.4 | 使用铺装块(k=1, 2…, NbES)构建拔模截面边ESk,其中NbES是拔模截面边的数量如果PBk的两个面的状态为In或On ,则从摊铺块PBk创建拔模截面边nFi和nF,j和PBk ≠ PBm (m=0, 1, 2… NbPBm),其中PBm是面nFi和nF,j的现有铺砌块(在FaceInfo方面为On或In),NbVm是面nFi和nF,j和 ≠ 的现有铺装块的数量 – 表示不重合(就顶点/面干扰而言)。 | BOPTools_Tools::MakeEdge() |
3 | 与拔模顶点VPk (k=1, 2…, NbVP)和拔模截面边ESk (k=1, 2…, NbES) 相交。为此: a)使用自己的 DS创建BOPAlgo_PaveFiller类型的新对象PFn ;b) 使用顶点VPk和边ESk作为PFn的参数(根据Arguments);c)为PFn调用方法Perform()。生成的顶点VPXk (k=1, 2… NbVPX)和边ESXk (k=1, 2… NbESX)通过VPk, ESk和PVn的结果之间的映射获得。 | BOPAlgo_PaveFiller::PostTreatFF() |
4 | 更新面信息(关于铺装块和顶点的部分) | BOPAlgo_PaveFiller::PerformFF() |
建立 P 曲线
此步骤的输入数据是构建截面边后的 DS。
不 | 内容 | 执行 |
---|---|---|
1 | 对于每个面/面干扰, nFi和nFj在nFi和nFj上为每个截面边ESXk构建 p 曲线。 | BOPAlgo_PaveFiller::MakePCurves() |
2 | 对于面nFi和nFj常见的每个铺装块,在nFi和nFj上构建 p 曲线。 | BOPAlgo_PaveFiller::MakePCurves() |
处理退化边
此步骤的输入数据是构建 P 曲线后的 DS。
不 | 内容 | 执行 |
---|---|---|
对于每个具有顶点VD的退化边ED | BOPAlgo_PaveFiller::ProcessDE() | |
1 | 找到铺砌块PBi (i=1,2… NbPB),其中NbPB是通过顶点VD的铺砌块的数量。 | BOPAlgo_PaveFiller::FindPaveBlocks() |
2 | 使用ED的 2D 曲线和PBi的 2D 曲线计算退化边ED的铺面。形成铺装块PBDi (i=1,2…NbPBD),其中NbPBD是退化边ED的铺装块数 | BOPAlgo_PaveFiller::FillPaves() |
3 | 构建分裂边ESDi (i=1,2…NbESD),其中ESD是分裂边的数量,使用铺装块PBDi | BOPAlgo_PaveFiller :: MakeSplitEdge() |
建筑部分的一般描述
建筑部件 (BP) 用于
- 构建操作结果
- 提供历史信息(根据::Generated()、 ::Modified()和::IsDeleted()) BP 使用第 5 章中描述的BOPAlgo_PaveFiller准备的 DS作为输入数据。BP 在以下类中实现:
- BOPAlgo_Builder – 用于通用熔断器运算符 (GFA)。
- BOPAlgo_BOP – 用于布尔运算运算符 (BOA)。
- BOPAlgo_Section – 用于 Section 运算符 (SA)。
- BOPAlgo_MakerVolume – 用于 Volume Maker 运算符。
- BOPAlgo_Splitter – 用于拆分器运算符。
- BOPAlgo_CellsBuilder – 用于 Cells Builder 运算符。
BOPAlgo_BuilderShape类为具有以下特性的算法提供接口:
- 结果是一个形状;
- 历史信息(根据::Generated()、::Modified()和::IsDeleted())。
通用联合算法
论据
该算法的参数是形状(根据TopoDS_Shape)。参数的主要要求在数据结构一章中描述。
结果
在运算过程中,参数Si可以分为几个部分Si1, Si2… Si1NbSp,其中NbSp是部分的数量。集合(Si1, Si2… Si1NbSp)是参数Si的图像。
- General Fuse 操作的结果是一个复合。复合的每个子形状对应于某个参数形状S1,S2…Sn,并且根据参数之间的干扰具有共享子形状。
- 对于 EDGE、FACE、SOLID 类型的参数,结果包含参数的拆分部分。
- 对于 WIRE、SHELL、COMPSOLID、COMPOUND 类型的参数,结果包含相应类型(即 WIRE、SHELL、COMPSOLID 或 COMPOUND)的形状的图像。结果形状的类型取决于参与操作的相应参数的类型。见下表:
不 | 论据类型 | 结果形状的类型 | 注释 |
---|---|---|---|
1 | 化合物 | 化合物 | 生成的 COMPOUND 由 COMPOUND COMPSOLID、SHELL、WIRE 和 VERTEX 类型的子形状的图像构建。SOLID、FACE、EDGE 类型的分割子形状集。 |
2 | 复合体 | 复合体 | 生成的 COMPSOLID 是从拆分的 SOLID 构建的。 |
3 | 实体 | 一组拆分 SOLID | |
4 | 壳 | 壳 | 生成的 SHELL 由拆分的 FACE 构建而成 |
5 | 面 | 一组拆分面 | |
6 | 线 | 线 | 生成的 WIRE 是由分裂的 EDGE 构建的 |
7 | 边 | 一组分裂边 | |
8 | 顶点 | 顶点 |
选项
General Fuse 算法有一组选项,可以加快运算速度并提高结果质量:
- 并行处理选项允许以并行模式运行算法;
- 模糊选项允许为操作设置额外的容差;
- 安全输入形状选项允许防止修改输入形状;
- 粘合选项允许加快参数的交集;
- 可以禁用对输入形状中倒置实体的检查;
- 在操作中使用定向边界框;
- 历史支持。
有关这些选项的更多详细信息,请参阅高级选项部分。
用法
以下示例说明了如何使用 GF 算法:
在 C++ 级别上使用 GF 算法
例子
查看示例以更好地理解定义。
案例1:三个边相交于一点
让我们考虑三个边:E1、E2和E3,它们在一个 3D 点中相交。
GFA 操作的结果是包含 6 个新边的复合:E11、E12、E21、E22、E31和E32。这些边有一个共享顶点Vn1。
在这种情况下:
- 参数边E1具有结果分裂边E11和E12(E1的图像)。
- 参数边E2具有结果分裂边E21和E22(E2的图像)。
- 参数边E3具有结果分裂边E31和E32(E3的图像)。
案例 2:两条线和一条边
让我们考虑两条线W1 (Ew11, Ew12, Ew13)和W2 (Ew21, Ew22, Ew23)和边E1。
两条线和一条边
GF 运算的结果是由 2 条线组成的复合线:Wn1(Ew11,En1,En2,En3,Ew13)和Wn2(Ew21,En2,En3,En4,Ew23)和两条边:E11和E12。
在这种情况下 :
- 自变量W1具有图像Wn1。
- 参数W2具有图像Wn2。
- 自变量边E1具有分裂边E11和E12。(E1的图像)。边En1、En2、En3、En4和顶点Vn1是在操作过程中创建的新形状。边Ew12具有分裂边En1、En2和En3,边Ew22具有分裂边En2、En3和En4。
案例 3:与面相交的边
让我们考虑边E1和面F2:
GF 操作的结果是由 3 个形状组成的复合:
- 分割边部分E11和E12(E1的图像)。
- 具有内边E12的新面F21(F2的图像)。
案例 4:位于面上的边
让我们考虑边E1和面F2:
GF 操作的结果是由 5 个形状组成的复合:
- 分割边部分E11、E12和E13(E1的图像)。
- 分割面部F21和F22(F2的图像)。
案例5:边和壳
让我们考虑由 2 个面组成的边E1和壳Sh2:F21和F22
GF 操作的结果是由 5 个形状组成的复合:
- 分割边部分E11、E12、E13和E14(E1的图像)。
- 图像外壳Sh21(包含分割面零件F211、F212、F221和F222)。
案例6:一根线和一个外壳
让我们考虑线W1 (E1, E2, E3, E4)和外壳Sh2 (F21, F22)。
GF 操作的结果是由 2 个形状组成的复合:
- 图像线W11由线W1 的分裂边部分组成:E11、E12、E13和E14。
- 包含分割面部件的图像外壳Sh21 : F211、F212、F213、F221、F222和F223。
案例 7:三张面
让我们考虑 3 个面:F1、F2和F3。
GF 操作的结果是由 7 个形状组成的复合:
- 分割面零件:Fn1、Fn2、Fn3、Fn4、Fn5、Fn6和Fn7。
案例8:一张面和一个贝壳
让我们考虑外壳Sh1 (F11, F12, F13)和面F2。
GF 操作的结果是由 4 个形状组成的复合:
- 图像外壳Sh11由外壳Sh1 的拆分面部分组成:Fn1、Fn2、Fn3、Fn4、Fn5和Fn6。
- 分割面F2 的部分:Fn3、Fn6和Fn7。
案例 9:壳和实体
让我们考虑外壳Sh1 (F11, F12…F16)和固体So2。
GF 操作的结果是由 2 个形状组成的复合:
- 图像外壳Sh11由Sh1 的分割面部分组成:Fn1、Fn2 … Fn8。
- 带内壳的固体So21 。(So2的图像)。
案例 10:化合物和固体
让我们考虑由 2 个固体So11和So12 ) 和固体So2组成的化合物Cm1。
GF 操作的结果是由 4 个形状组成的复合:
- 图像化合物Cm11由来自So11和So12的分裂固体部分(Sn1、Sn2、Sn3、Sn4)组成。
- 拆分固体So2 (Sn2, Sn3, Sn5)的部分。
BOPAlgo_Builder 类
GFA 在BOPAlgo_Builder类中实现。
字段
类的主要字段如表所示:
名称 | 内容 |
---|---|
我的铺路填料 | 指向BOPAlgo_PaveFiller对象 的指针 |
我的DS | 指向BOPDS_DS对象 的指针 |
我的上下文 | 指向交叉点上下文的指针 |
我的图片 | 源形状与其图像之间的映射 |
我的形状SD | 由于相同的域属性,源形状(或源形状的分割部分)与将在结果中使用的形状(或形状的一部分)之间的映射。 |
初始化
此步骤的输入数据是一个BOPAlgo_PaveFiller对象(根据Intersection),在处理退化边与相应的 DS 之后的状态。
不 | 内容 | 执行 |
---|---|---|
1 | 检查 DS 和BOPAlgo_PaveFiller的准备情况。 | BOPAlgo_Builder::CheckData() |
2 | 构建一个 Compound 类型的空结果。 | BOPAlgo_Builder::Prepare() |
为顶点构建图像
此步骤的输入数据是初始化后的BOPAlgo_Builder对象。
不 | 内容 | 执行 |
---|---|---|
1 | 使用来自 DS 的信息按 SD 顶点 填充myShapesSD 。 | BOPAlgo_Builder::FillImagesVertices() |
Vertex 类型的构建结果
此步骤的输入数据是为顶点和Type构建图像后的BOPAlgo_Builder对象,即形状类型(TopAbs_VERTEX)。
不 | 内容 | 执行 |
---|---|---|
1 | 对于Type 类型的参数。如果参数有图像:将图像添加到结果中。如果参数没有图像:将参数添加到结果中。 | BOPAlgo_Builder::BuildResult() |
为边构建图像
此步骤的输入数据是构建顶点类型结果后的BOPAlgo_Builder对象。
不 | 内容 | 执行 |
---|---|---|
1 | 对于 DS 中的所有铺砌块。通过从铺砌块分割边ESPi填充原始边E的myImages 。如果是边上的常见块,请使用与前导铺路块相对应的边ESPSDj ,并通过ESPi/ESPSDj对填充myShapesSD。 | BOPAlgo_Builder::FillImagesEdges() |
类型 Edge 的构建结果
此步骤与类型 Vertex 的 Building Result相同,但适用于Edge类型。
为线构建图像
此步骤的输入数据为:
- 构建Edge类型结果后的BOPAlgo_Builder对象;
- 原始形状 – 线材
- 类型– 形状类型(TopAbs_WIRE)。
不 | 内容 | 执行 |
---|---|---|
1 | 对于Type 类型的所有参数。创建一个Type 类型的容器 C 。 | BOPAlgo_Builder::FillImagesContainers() |
2 | 将原始形状的图像或未拆分部分添加到 C 中,同时考虑其方向。 | BOPAlgo_Builder::FillImagesContainers() BOPTools_Tools::IsSplitToReverse() |
3 | 使用上述信息填充原始形状的myImages。 | BOPAlgo_Builder::FillImagesContainers() |
Wire 类型的构建结果
此步骤与类型 Vertex 的 Building Result相同,但适用于Wire类型。
为面构建图像
此步骤的输入数据是构建Wire类型结果后的BOPAlgo_Builder对象。
不 | 内容 | 执行 |
---|---|---|
1 | 为FACE类型的所有干涉 DS 形状Fi构建分割面。 | |
1.1 | 收集Fi(ESPij)的所有边或其图像。 | BOPAlgo_Builder::BuildSplitFaces() |
1.2 | 向 ESPij 赋予与原始方向一致的方向。 | BOPAlgo_Builder::BuildSplitFaces() |
1.3 | 为Fi收集所有截面边SEk。 | BOPAlgo_Builder::BuildSplitFaces() |
1.4 | 为Fi (Fi1, Fi2…FiNbSp)构建分割面,其中NbSp是分割部分的数量(有关详细信息 ,请参阅从一组边构建面)。 | BOPAlgo_BuilderFace |
1.5 | 赋予(Fi1, Fi2…FiNbSp)与原始面Fi一致的方向。 | BOPAlgo_Builder::BuildSplitFaces() |
1.6 | 用Fi/(Fi1, Fi2…FiNbSp)填充地图 mySplits | BOPAlgo_Builder::BuildSplitFaces() |
2 | 填充相同的域面 | BOPAlgo_Builder::FillSameDomainFaces |
2.1 | 在mySplits的内容中查找并收集相同域分割面的对(Fij, Fkl)m,其中m是对的数量。 | BOPAlgo_Builder::FillSameDomainFaces BOPTools_Tools::AreFacesSameDomain() |
2.2 | 计算相同域面(F1C, F2C…FnC)k, C=0, 1…nCs 的连接链 1),其中nCs是连接链的数量。 | BOPAlgo_Builder::FillSameDomainFaces() |
2.3 | 使用链填充myShapesSD (F1C, F2C… FnC)k | BOPAlgo_Builder::FillSameDomainFaces() |
2.4 | 将内部顶点添加到分割面。 | BOPAlgo_Builder::FillSameDomainFaces() |
2.5 | 使用myShapesSD和mySplits填充myImages。 | BOPAlgo_Builder::FillSameDomainFaces() |
图像中给出了相同域面链的示例:
- 相同域面对是:(F11, F21), (F22, F31), (F41, F51) , (F41, F6)和(F51, F6)。
- 这些对产生三个链:(F11, F21), (F22, F31)和(F41, F51, F6)。
字体的构建结果
此步骤与类型 Vertex 的 Building Result相同,但适用于Face类型。
为 Shell 构建映像
此步骤的输入数据为:
- BOPAlgo_Builder对象在构建类型 face 的结果后;
- 原始形状– 贝壳;
- 类型– 形状的类型(TopAbs_SHELL)。
该过程与为线构建图像的过程相同。
Shell 类型的构建结果
此步骤与类型 Vertex 的 Building Result相同,但适用于Shell类型。
为实体构建图像
此步骤的输入数据是构建Shell类型结果后的BOPAlgo_Builder对象。
对所有类型为SOLID的干扰 DS 形状Si执行以下程序。
不 | 内容 | 执行 |
---|---|---|
1 | 收集具有 3D 状态In Si的所有面(FSPij)的所有图像或非分割部分。 | BOPAlgo_Builder::FillIn3DParts () |
2 | 收集Si的所有面的所有图像或非分割部分 | BOPAlgo_Builder::BuildSplitSolids() |
3 | 为Si -> (Si1, Si2…SiNbSp)构建分割实体,其中NbSp是分割部分的数量(有关详细信息 ,请参阅从一组边构建面) | BOPAlgo_BuilderSolid |
4 | 填充地图 同域实体myShapesSD | BOPAlgo_Builder::BuildSplitSolids() |
5 | 填写地图myImages | BOPAlgo_Builder::BuildSplitSolids() |
6 | 添加内部顶点以分割实体 | BOPAlgo_Builder::FillInternalShapes() |
Solid 类型的构建结果
此步骤与类型 Vertex 的 Building Result相同,但适用于 Solid 类型。
为 CompSolid 类型构建映像
此步骤的输入数据为:
- 构建实体类型结果后的BOPAlgo_Builder对象;
- 原始形状– Compsolid;
- 类型– 形状的类型(TopAbs_COMPSOLID)。
该过程与为线构建图像的过程相同。
Compsolid 类型的构建结果
此步骤与类型 Vertex 的 Building Result相同,但适用于 Compsolid 类型。
为化合物构建图像
此步骤的输入数据如下:
- 构建compsolid类型的结果后的BOPAlgo_Builder对象;
- 原始形状– 复合;
- 类型– 形状的类型(TopAbs_COMPOUND)。
该过程与为线构建图像的过程相同。
类型化合物的构建结果
此步骤与类型 Vertex 的 Building Result相同,但适用于 Compound 类型。
后期处理
该步骤的目的是更正结果的容差,以根据BRepCheck_Analyzer提供其有效性。
此步骤的输入数据是构建复合类型结果后的BOPAlgo_Builder对象。
不 | 内容 | 执行 |
---|---|---|
1 | 曲线上顶点的正确公差 | BOPTools_Tools::CorrectPointOnCurve() |
2 | 修正面上边的公差 | BOPTools_Tools::CorrectCurveOnSurface() |
分离器算法
Splitter 算法允许将一组任意形状拆分为另一组任意形状。
它基于通用熔断器算法,因此通用熔断器的所有选项(参见GF 选项)也可用于该算法。
论据
- Splitter 算法的参数分为两组 –对象(将被分割的形状)和工具(形状,对象将被分割);
- 参数的要求(对象和工具)与通用熔断算法相同 – 每个组中可以有任意数量的任何类型的参数,但每个参数应该是有效的并且不会自干扰。
结果
- Splitter 算法的结果只包含对象组中包含的形状的分割部分;
- 仅包含在工具组中的形状的分割部分从结果中排除;
- 如果工具组中没有形状,则操作的结果将等同于 General Fuse 操作的结果;
- 这些形状可以被同一组中的其他形状分割(如果这些形状相互干扰)。
用法
API
在底层,Splitter 算法在BOPAlgo_Splitter类中实现。该算法的用法如下:
例子
示例 1
通过一组边分割一个面:
|
|
示例 2
通过一组圆柱体分割一个板:
|
|
示例 3
按平面分割壳壳:
|
|
布尔运算算法
论据
- BOA 的参数是根据TopoDS_Shape的形状。参数的主要要求在数据结构中描述
- BOA 中有两组参数:
- 对象(S1=S11, S12, …) ;
- 工具(S2=S21,S22,…)。
- 下表包含不同类型参数的维度值:
不 | 论据类型 | 类型索引 | 方面 |
---|---|---|---|
1 | 化合物 | 0 | 0、1、2、3 之一 |
2 | 复合体 | 1 | 3 |
3 | 实体 | 2 | 3 |
4 | 壳 | 3 | 2 |
5 | 面 | 4 | 2 |
6 | 线 | 5 | 1 |
7 | 边 | 6 | 1 |
8 | 顶点 | 7 | 0 |
- 对于布尔运算 Fuse,所有参数都应具有相同的维度。
- 对于布尔运算 Cut,S2的最小尺寸不应小于S1的最大尺寸。
- 对于布尔运算 Common,参数可以有任何维度。
结果。通用规则
- 布尔运算的结果是一个复合(如果已定义)。根据论元之间的干扰,复合的每个子形状都有共享的子形状。
- 结果的内容取决于操作的类型(Common、Fuse、Cut12、Cut21)和参数的维度。
- 操作 Fuse 的结果是为具有相同维度值的参数S1和S2定义的: Dim(S1)=Dim(S2)。如果参数具有不同的维度值,则未定义操作 Fuse 的结果。结果的维度等于参数的维度。例如,无法融合边和面。
- 参数S1和S2的 Fuse 操作的结果包含相对于相反参数具有状态OUT的参数部分。
- 通过移除所有可能的内部面以提供最少数量的实体,对尺寸值为 3(实体)的参数S1和S2的操作 Fuse 的结果进行了细化。
- 参数S1和S2的操作 Common 的结果是为参数维度的所有值定义的。结果可以包含不同维度的形状,但结果的最小维度将等于参数的最小维度。例如,边之间的Common运算的结果不能是顶点。
- 参数S1和S2的 Common 操作的结果包含相对于相反参数具有状态IN和ON的参数部分。
- 操作 Cut 的结果是为参数S1和S2定义的,其维度Dim(S2)的值不应小于Dim(S1)。结果可以包含不同尺寸的形状,但结果的最小尺寸将等于对象Dim(S1)的最小尺寸。Cut12运算的结果未针对其他情况定义。例如,不可能从实体中切出一条边,因为没有定义没有边的实体。
- 参数S1和S2的操作Cut12的结果包含参数S1中相对于相反参数S2具有状态OUT的部分。
- 参数S1和S2的操作Cut21的结果包含参数S2中相对于相反参数S1具有状态OUT的部分。
- 对于集合类型(WIRE、SHELL、COMPSOLID)的参数,类型将在结果中传递。例如,Shell 和 Wire 之间的 Common 操作的结果将是一个包含 Wire 的化合物。
- 对于包含重叠部分的集合类型(WIRE、SHELL、COMPSOLID)的参数,传递给结果的重叠部分将从包含这些部分的输入形状中为每个容器重复。结果中将避免完全包含在其他容器中的容器。
- 对于集合类型(WIRE、SHELL、COMPSOLID)的参数,包含在结果中的容器将与来自参数的原始容器具有相同的方向。在重复的情况下,其方向将由参数中第一个容器的方向定义。结果中包含的每个容器都将具有其子形状的一致方向。
- 集合类型 (WIRE, SHELL) 的参数的操作 Fuse 的结果将由相同集合类型的形状组成。重叠部分(EDGES/FACES)将在容器之间共享,但结果中将避免重复容器。例如,两条完全重合的线之间的 Fuse 操作的结果将是一根线,但两条部分重合的线之间的 Fuse 操作的结果将是共享重合边的两条线。
- COMPSOLID 类型参数的 Fuse 操作的结果将由包含 COMPSOLID 的化合物组成,该 COMPSOLID 由熔融固体的连接块创建。
- 集合类型(WIRE、SHELL、COMPSOLID)参数的 Common 操作的结果将由包含重叠部分的唯一容器组成。例如,两条完全重叠的线之间的通用操作的结果将是一条包含所有边分割的线。两条部分重叠的线之间的公共操作结果中的线数将等于重叠边的连接块数。
例子
案例一:两个顶点
让我们考虑两个干扰顶点V1和V2:
- Fuse操作的结果是包含新顶点V的复合。
- Common运算的结果是包含新顶点V的复合。
- Cut12操作的结果是一个空的化合物。
- Cut21操作的结果是一个空的化合物。
案例 2:顶点和边
让我们考虑在 3D 点中相交的顶点V1和边E2:
- Fuse操作的结果是 result is not defined,因为顶点的维度(0)不等于边的维度(1)。
- Common运算的结果是包含顶点 *V 1 * 作为参数 *V 1 * 与边E2具有公共部分的复合。
- Cut12操作的结果是一个空的化合物。
- Cut21操作的结果未定义,因为顶点的维度 (0) 小于边的维度 (1)。
案例 3:一个顶点和一个面
让我们考虑在 3D 点中相交的顶点V1和面F2:
- 由于顶点(0)的尺寸不等于面(2)的尺寸,因此未定义Fuse操作的结果。
- Common运算的结果是包含顶点 *V 1 * 作为自变量 *V 1 * 与面F2具有公共部分的复合。
- Cut12操作的结果是一个空的化合物。
- 未定义 Cut21操作的结果,因为顶点 (0) 的尺寸小于面 (2) 的尺寸。
案例 4:一个顶点和一个实体
让我们考虑在 3D 点中相交的顶点V1和实体S2:
- 未定义Fuse操作的结果,因为顶点 (0) 的尺寸不等于实体 (3) 的尺寸。
- Common运算的结果是包含顶点 *V 1 * 作为自变量 *V 1 * 与实体S2具有公共部分的复合。
- Cut12操作的结果是一个空的化合物。
- 未定义 Cut21操作的结果,因为顶点 (0) 的尺寸小于实体 (3) 的尺寸。
案例5:两条边相交于一点
让我们考虑在 3D 点中相交的边E1和E2:
- Fuse操作的结果是包含参数拆分部分的复合,即 4 个新边E11、E12、E21和E22。这些边有一个共享顶点Vn1。在这种情况下:
- 参数边E1具有结果分裂边E11和E12(E1的图像);
- 参数边E2具有结果分裂边E21和E22(E2的图像)。
- Common运算的结果是一个空复合,因为边(顶点)之间的公共部分的维度(0)小于参数的维度(1)。
- Cut12操作的结果是包含参数E1的拆分部分的复合,即 2 条新边E11和E12。这些边有一个共享顶点Vn1。
在这种情况下,参数边E1具有结果分裂边E11和E12(E1的图像)。
- Cut21操作的结果是包含参数E2的拆分部分的复合,即 2 条新边E21和E12。这些边有一个共享顶点Vn1。
在这种情况下,参数边E2具有结果分裂边E21和E22(E2的图像)。
案例 6:两条边有一个公共块
让我们考虑具有公共块的边E1和E2 :
- Fuse操作的结果是包含参数拆分部分的复合,即 3 个新边E11、E12和E22。这些边有两个共享顶点。在这种情况下:
- 参数边E1具有结果分裂边E11和E12(E1的图像);
- 参数边E2具有结果分裂边E21和E22(E2的图像);
- 边E12对于E1和E2的图像是常见的。
- Common操作的结果是包含参数拆分部分的复合,即 1 个新边E12。在这种情况下,边E12对于E1和E2的图像是共同的。边 (edge) 之间的公共部分具有与参数 (1) 的维数相同的维数 (1)。
- Cut12操作的结果是包含参数E1的拆分部分的复合,即新边E11。
- Cut21操作的结果是包含参数E2的拆分部分的复合,即新边E22。
案例 7:边和面在一点相交
让我们考虑在 3D 点相交的边E1和面F2:
- 未定义Fuse操作的结果,因为边 (1) 的尺寸不等于面 (2) 的尺寸。
- Common运算的结果是一个空复合,因为边和面(顶点)之间的公共部分的维度 (0) 小于参数 (1) 的维度。
- Cut12操作的结果是包含参数E1的拆分部分的复合,即 2 条新边E11和E12。
在这种情况下,参数边E1与面F2没有公共部分,因此E1的整个图像都在结果中。
- 未定义 Cut21操作的结果,因为边 (1) 的尺寸小于面 (2) 的尺寸。
案例 8:具有公共块的面和边
让我们考虑具有公共块的边E1和面F2 :
- 未定义Fuse操作的结果,因为边 (1) 的尺寸不等于面 (2) 的尺寸。
- Common运算的结果是包含参数E1的拆分部分的复合,即新边E12。
在这种情况下,参数边E1与面F2具有共同部分,因此E1图像的相应部分在结果中。黄色方块不是结果的一部分。它只显示F2的位置。
- Cut12操作的结果是包含参数E1的拆分部分的复合,即新边E11。
在这种情况下,参数边E1与面F2有一个公共部分,因此相应的部分不包含在结果中。黄色方块不是结果的一部分。它只显示F2的位置。
- 未定义 Cut21操作的结果,因为边 (1) 的尺寸小于面 (2) 的尺寸。
案例 9:边和实体在一点相交
让我们考虑在一点相交的边E1和实体S2 :
- 未定义Fuse操作的结果,因为边 (1) 的尺寸不等于实体 (3) 的尺寸。
- Common运算的结果是包含参数E1的拆分部分的复合,即新边E12。
在这种情况下,参数边E1与实体S2具有共同部分,因此E1图像的相应部分在结果中。黄色方块不是结果的一部分。它只显示S2的位置。
- Cut12操作的结果是包含参数E1的拆分部分的复合,即新边E11。
在这种情况下,参数边E1与实体S2有一个公共部分,因此相应的部分不包含在结果中。黄色方块不是结果的一部分。它只显示S2的位置。
- 未定义 Cut21操作的结果,因为边 (1) 的尺寸小于实体 (3) 的尺寸。
案例 10:具有公共块的边和实体
让我们考虑具有公共块的边E1和实体S2 :
- 未定义Fuse操作的结果,因为边 (1) 的尺寸不等于实体 (3) 的尺寸。
- Common运算的结果是包含参数E1的拆分部分的复合,即新边E12。
在这种情况下,参数边E1与实体S2具有共同部分,因此E1图像的相应部分在结果中。黄色方块不是结果的一部分。它只显示S2的位置。
- Cut12操作的结果是包含参数E1的拆分部分的复合,即新边E11。
在这种情况下,参数边E1与实体S2有一个公共部分,因此相应的部分不包含在结果中。黄色方块不是结果的一部分。它只显示S2的位置。
- 未定义 Cut21操作的结果,因为边 (1) 的尺寸小于实体 (3) 的尺寸。
案例 11:两个相交的面
让我们考虑两个相交的面F1和F2:
- Fuse操作的结果是包含参数拆分部分的复合,即 2 个新面F11和F21。这些面有一个共享边En1。
- Common运算的结果是一个空复合,因为F1和F2之间的公共部分(边)的维数 (1) 小于参数 (2) 的维数。
- Cut12操作的结果是包含自变量F1的分割部分的复合,即新面F11。
- Cut21操作的结果是包含自变量F2的分割部分的复合,即 1 个新面F21。
案例 12:具有公共部分的两个面
让我们考虑两个具有共同部分的面F1和F2 :
- Fuse操作的结果是包含分割部分参数的复合,即 3 个新面:F11、F12和F22。这些面通过边共享在这种情况下:
- 参数边F1具有结果分割面F11和F12(F1的图像)
- 参数 face F2产生分裂面F12和F22(F2的图像)
- 面F12对于F1和F2的图像是常见的。
- Common操作的结果是一个包含拆分部分参数的复合,即 1 个新面孔F12。在这种情况下:面F12对于F1和F2的图像是常见的。面 (face) 之间的公共部分具有与参数 (2) 的维度相同的维度 (2)。
- Cut12操作的结果是包含自变量F1的分割部分的复合,即新面F11。
- Cut21操作的结果是包含自变量F2的分割部分的复合,即 1 个新面F21。
案例 13:具有公共边的两个面
让我们考虑两个具有共同边的面F1和F2 :
- Fuse操作的结果是包含拆分部分参数的复合,即 2 个新面:F11和F21。这些面有一个共享边En1。
- Common运算的结果是一个空复合,因为F1和F2之间的公共部分(边)的维数 (1) 小于参数 (2) 的维数
- Cut12操作的结果是包含自变量F1的分割部分的复合,即新面F11。显示顶点只是为了澄清边被吐出的事实。
- Cut21操作的结果是包含自变量F2的分割部分的复合,即 1 个新面F21。显示顶点只是为了澄清边被吐出的事实。
案例 14:两个具有共同顶点的面
让我们考虑两个具有共同顶点的面F1和F2 :
- Fuse操作的结果是包含拆分部分参数的复合,即 2 个新面:F11和F21。这些面有一个共享顶点Vn1。
- Common运算的结果是一个空复合,因为F1和F2 (顶点)之间的公共部分的维数 (0)小于参数 (2) 的维数
- Cut12操作的结果是包含自变量F1的分割部分的复合,即新面F11。
- Cut21操作的结果是包含自变量F2的分割部分的复合,即 1 个新面F21。
案例 15:具有相交曲线的面和实体。
让我们考虑具有相交曲线的面F1和实体S2 :
- 未定义Fuse操作的结果,因为面 (2) 的尺寸不等于实体 (3) 的尺寸。
- Common运算的结果是包含自变量F1的拆分部分的复合。在这种情况下,参数面F1与实体S2具有共同部分,因此F1图像的对应部分在结果中。黄色轮廓不是结果的一部分。它只显示S2的位置。
- Cut12操作的结果是包含参数F1的拆分部分的复合。在这种情况下,参数面F1具有与实体S2相同的部分,因此相应的部分不包含在结果中。黄色轮廓不是结果的一部分。它只显示S2的位置。
- 未定义 Cut21操作的结果,因为面 (2) 的尺寸小于实体 (3) 的尺寸。
案例 16:具有重叠面的面和实体。
让我们考虑具有重叠面的面F1和实体S2:
- 未定义Fuse操作的结果,因为面 (2) 的尺寸不等于实体 (3) 的尺寸。
- Common运算的结果是包含自变量F1的拆分部分的复合。在这种情况下,参数面F1与实体S2具有共同的部分,因此F1的图像的相应部分包含在结果中。黄色轮廓不是结果的一部分。它只显示S2的位置。
- Cut12操作的结果是包含参数F1的拆分部分的复合。在这种情况下,参数面F1具有与实体S2相同的部分,因此相应的部分不包含在结果中。黄色轮廓不是结果的一部分。它只显示S2的位置。
- 未定义 Cut21操作的结果,因为面 (2) 的尺寸小于实体 (3) 的尺寸。
案例 17:具有重叠边的面和实体。
让我们考虑具有重叠边的面F1和实体S2:
- 未定义Fuse操作的结果,因为面 (2) 的尺寸不等于实体 (3) 的尺寸。
- Common运算的结果是一个空复合,因为F1和S2 (边)之间的公共部分的维度 (1)小于参数 (2) 的较低维度。
- Cut12操作的结果是包含参数F1的拆分部分的复合。在这种情况下,参数面F1具有与实体S2相同的部分,因此相应的部分不包含在结果中。黄色轮廓不是结果的一部分。它只显示S2的位置。
- 未定义 Cut21操作的结果,因为面 (2) 的尺寸小于实体 (3) 的尺寸。
案例 18:具有重叠顶点的面和实体。
让我们考虑具有重叠顶点的面F1和实体S2:
- 未定义Fuse操作的结果,因为面 (2) 的尺寸不等于实体 (3) 的尺寸。
- Common运算的结果是一个空复合,因为F1和S2 (顶点)之间的公共部分的维度 (1)小于参数 (2) 的较低维度。
- Cut12操作的结果是包含参数F1的拆分部分的复合。在这种情况下,参数面F1具有与实体S2相同的部分,因此相应的部分不包含在结果中。黄色轮廓不是结果的一部分。它只显示S2的位置。
- 未定义 Cut21操作的结果,因为面 (2) 的尺寸小于实体 (3) 的尺寸。
案例 19:两个相交的实体。
让我们考虑两个相交的实体S1和S2:
- Fuse操作的结果是由参数S11、S12和S22 (Cut12, Common, Cut21)的拆分部分组成的复合。所有内网都被移除,因此结果是一个新的实体R。
- Common运算的结果是一个包含拆分部分参数的复合,即一个新的实体S12。在这种情况下,实心S12对于S1和S2的图像是常见的。实体 (solid) 之间的公共部分具有与参数 (3) 的维度相同的维度 (3)。黄色轮廓不是结果的一部分。它只显示S1的位置。
- Cut12操作的结果是包含参数S1的拆分部分的复合,即 1 个新实体S11。
- Cut21操作的结果是包含参数S2的拆分部分的复合,即 1 个新实体S21。
案例 20:两个具有重叠面的实体。
让我们考虑两个在面上具有公共部分的实体S1和S2 :
- Fuse操作的结果是由参数S11、S12和S22 (Cut12, Common, Cut21)的拆分部分组成的复合。所有内网都被移除,因此结果是一个新的实体R。
- Common运算的结果是一个空复合,因为S1和S2 (面)之间的公共部分的维度 (2)小于参数 (3) 的较低维度。
- Cut12操作的结果是包含参数S1的拆分部分的复合,即 1 个新实体S11。
- Cut21操作的结果是包含参数S2的拆分部分的复合,即 1 个新实体S21。
案例 21:两个具有重叠边的实体。
让我们考虑两个具有重叠边的实体S1和S2:
- Fuse操作的结果是由参数的拆分部分组成的复合,即 2 个新实体S11和S21。这些实体有一个共享边En1。
- Common运算的结果是一个空复合,因为S1和S2 (边)之间的公共部分的维度 (1)小于参数 (3) 的较低维度。
- Cut12操作的结果是包含参数S1的拆分部分的复合。在这种情况下,参数S1具有与实体S2相同的部分,因此相应的部分不包含在结果中。
- Cut21操作的结果是包含参数S2的拆分部分的复合。在这种情况下,参数S2具有与实体S1相同的部分,因此相应的部分不包含在结果中。
案例 22:两个具有重叠顶点的实体。
让我们考虑两个具有重叠顶点的实体S1和S2:
- Fuse操作的结果是由参数的拆分部分组成的复合,即 2 个新实体S11和S21。这些固体共享Vn1。
- Common运算的结果是一个空复合,因为S1和S2 (顶点)之间的公共部分的维数 (0)小于参数 (3) 的下维数。
- Cut12操作的结果是包含参数S1的拆分部分的复合。
- Cut21操作的结果是包含参数S2的拆分部分的复合。
案例 23:一个壳和一个被实体切割的线。
让我们将 Shell Sh和 Wire W视为对象,将 Solid S视为工具:
- Fuse操作的结果没有定义,因为参数的维度不一样。
- Common操作的结果是一个复合,其中包含 Solid 的初始 Shell 和 Wire 公共部分。新的 Shell 和 Wire 是从对象创建的。
- Cut12操作的结果是包含从参数Sh和W拆分的新 Shell 和 Wire 的复合。在这种情况下,它们具有与实体S相同的部分,因此相应的部分不包含在结果中。
- Cut21操作的结果未定义为对象的尺寸低于工具。
案例 24:两条具有重叠边的导线。
让我们考虑两条边重叠的线,W1是对象,W2是工具:
- Fuse操作的结果是包含两条 Wire 的复合,它们共享一条重叠的边。新的 Wire 是从对象创建的:
- Common操作的结果是包含一条由重叠边组成的 Wire 的复合。新的 Wire 是从对象创建的:
- Cut12操作的结果是包含从对象W1拆分的线的复合。它与W2的共同部分不包括在结果中。
- Cut21操作的结果是包含从W2拆分的线的复合。它与W1的共同部分不包括在结果中。
BOPAlgo_BOP 类
BOA 在BOPAlgo_BOP类中实现。该类的主要字段如表所示:
名称 | 内容 |
---|---|
我的操作 | 布尔运算的类型(Common、Fuse、Cut) |
我的工具 | 工具 |
我的点[2] | 参数维度的值 |
我的RC | 草稿结果(形状) |
BOPAlgo_BOP的主要步骤与BOPAlgo_Builder相同,除了下一段中描述的某些方面。
构建草稿结果
此步骤的输入数据如下:
- 构建Compound类型的结果后的BOPAlgo_BOP对象;
- 布尔运算的类型。
不 | 内容 | 执行 |
---|---|---|
1 | 对于布尔操作Fuse将所有参数图像添加到myRC。 | BOPAlgo_BOP::BuildRC() |
2 | 对于布尔运算Common或Cut将参数S1的所有图像添加到myRC ,这些图像对于 Common 操作是 Common 并且对于Cut操作 不是 Common | BOPAlgo_BOP::BuildRC() |
构建结果
此步骤的输入数据如下:
- BOPAlgo_BOP对象构建草稿结果后的状态。
不 | 内容 | 执行 |
---|---|---|
1 | 对于布尔运算的类型 Common, Cut with any dimension and operation Fuse with myDim[0] < 3 | |
1.1 | 在参数中查找容器(WIRE、SHELL、COMPSOLID) | BOPAlgo_BOP :: BuildShape() |
1.2 | 从myRC中的每个容器的拆分中创建连接块 | BOPTools_Tools::MakeConnexityBlocks() |
1.3 | 从连接块制成的形状构建结果 | BOPAlgo_BOP :: BuildShape() |
1.4 | 将myRC中的剩余形状添加到结果中 | BOPAlgo_BOP :: BuildShape() |
2 | 对于布尔运算 Fuse 的类型,myDim[0] = 3 | |
2.1 | 在myRC中查找内部面(FWi) | BOPAlgo_BOP::BuildSolid() |
2.2 | 收集myRC的所有面,除了内部面(FWi) -> SFS | BOPAlgo_BOP::BuildSolid () |
2.3 | 从SFS构建实体(SDi)。 | BOPAlgo_BuilderSolid |
2.4 | 将固体(SDi)添加到结果中 |
开放实体的布尔运算
开放实体上的布尔运算非常棘手,以至于基于实体分割构建结果的布尔运算的标准方法不起作用。发生这种情况是因为分割实体的算法(BOPAlgo_BuilderSolid)总是试图创建闭环(壳)并从中生成实体。但是,如果输入实体没有关闭,那么可以从它的拆分中得到什么?为了对开放实体执行布尔运算,使用了另一种方法,它不依赖于实体的分割是否正确,而是尝试选择面的分割,这对于给定的操作类型是必需的。这里的重点是布尔运算的类型清楚地定义了要被纳入结果的面的状态:
- 对于COMMON操作,必须采用位于相反组的任何实体内的参数的所有面;
- 对于FUSE操作,必须采用位于对组所有实体之外的参数的所有面;
- 对于CUT操作,位于工具的所有实体之外的对象的所有面和位于对象的任何实体内的工具的所有面都必须被获取;
- 对于CUT21操作,必须获取位于工具的任何实体内的对象的所有面以及位于对象的所有实体之外的工具的所有面。从选定的面构建结果实体。请注意,结果可能包含与开放实体一样的正常(封闭)实体。
即使采用这种方法,也不能始终保证对开放实体进行布尔运算的正确结果。这可以通过开放实体的非流形性质来解释:在某些情况下,面的分类取决于选择用于分类的面的点。
截面算法
论据
BOA 的参数是根据TopoDS_Shape的形状。算法中描述了参数的主要要求。
结果和一般规则
- Section 运算的结果是一个复合。根据论元之间的干扰,复合的每个子形状都有共享的子形状。
- 截面操作的结果包含尺寸小于 2 的形状,即顶点和边。
- 如果这些顶点不属于结果的边,则 Section 操作的结果包含独立的顶点。
- Section 运算的结果包含属于至少两个参数(或两个参数图像)的参数(或参数图像)的顶点和边。
- 截面操作的结果包含从面/面干涉获得的截面顶点和边。
- 截面操作的结果包含顶点,这些顶点是顶点和面之间干涉的结果。
- 截面操作的结果包含边和面(公共块)之间的干涉结果,
例子
案例一:两个顶点
让我们考虑两个干扰顶点:V1和V2。
Section操作的结果是包含一个新顶点V的复合。
案例 1:案例 2:顶点和边
让我们考虑在 3D 点中相交的顶点V1和边E2:
Section操作的结果是包含顶点V1的复合。
案例 1:案例 2:一个顶点和一个面
让我们考虑在 3D 点中相交的顶点V1和面F2:
Section操作的结果是包含顶点V1的复合。
案例 4:一个顶点和一个实体
让我们考虑顶点V1和实体Z2。顶点V1在实体Z2内。
Section操作的结果是一个空的化合物。
案例5:两条边相交于一点
让我们考虑在 3D 点中相交的边E1和E2:
Section操作的结果是包含一个新顶点Vnew的复合。
案例 6:两条边有一个公共块
让我们考虑具有公共块的边E1和E2:
Section操作的结果是包含新边Enew的复合。
案例 7:边和面在一点相交
让我们考虑在 3D 点处相交的边E1和面F2:
Section操作的结果是包含一个新顶点Vnew的复合。
案例 8:具有公共块的面和边
让我们考虑具有共同块的边E1和面F2 :
Section操作的结果是包含新边Enew的化合物。
案例 9:边和实体在一点相交
让我们考虑在一点相交的边E1和实体Z2 :
Section操作的结果是包含一个新顶点Vnew的复合。
案例 10:具有公共块的边和实体
让我们考虑边E1和实体Z2,它们在一个面上有一个公共块:
Section操作的结果是包含新边Enew的复合。
案例 11:两个相交的面
让我们考虑两个相交的面F1和F2:
Section操作的结果是包含新边Enew的复合。
案例 12:具有公共部分的两个面
让我们考虑两个具有共同部分的面F1和F2 :
Section运算的结果是包含 4 条新边的复合。
案例 13:具有重叠边的两个面
让我们考虑两个具有重叠边的面F1和F2 :
Section操作的结果是包含新边Enew的复合。
案例 14:两个顶点重叠的面
让我们考虑两个具有重叠顶点的面F1和F2:
Section操作的结果是包含一个新顶点Vnew的复合。
案例 15:具有相交曲线的面和实体
让我们考虑具有相交曲线的面F1和实体Z2 :
Section运算的结果是包含新边的复合。
案例 16:具有重叠面的面和实体。
让我们考虑具有重叠面的面F1和实体Z2:
Section运算的结果是包含新边的复合
案例 17:具有重叠边的面和实体。
让我们考虑在边上有共同部分的面F1和实体Z2:
Section操作的结果是包含新边Enew的复合。
案例 18:具有重叠顶点的面和实体。
让我们考虑具有重叠顶点的面F1和实体Z2:
Section操作的结果是包含一个新顶点Vnew的复合。
案例 19:两个相交的实体
让我们考虑两个相交的实体Z1和Z2:
Section运算的结果是包含新边的复合。
案例 20:两个具有重叠面的实体
让我们考虑两个在面上具有公共部分的实体Z1和Z2 :
Section运算的结果是包含新边的复合。
案例 21:两个具有重叠边的实体
让我们考虑两个具有重叠边的实体Z1和Z2:
Section操作的结果是包含新边Enew的复合。
案例 22:两个具有重叠顶点的实体
让我们考虑两个具有重叠顶点的实体Z1和Z2:
Section操作的结果是包含一个新顶点Vnew的复合。
BOPAlgo_Section 类
SA 在BOPAlgo_Section类中实现。该类没有特定字段。BOPAlgo_Section的主要步骤与BOPAlgo_Builder相同,但以下步骤除外:
- 为线构建图像;
- 类型线的构建结果;
- 为面构建图像;
- 字体的构建结果;
- 为壳构建图像;
- Shell 类型的构建结果;
- 为实体构建图像;
- 实体类型的构建结果;
- 为 CompSolid 类型构建图像;
- CompSolid 类型的构建结果;
- 为化合物构建图像;下一段将描述构建结果的某些方面
构建结果
不 | 内容 | 执行 |
---|---|---|
1 | 使用FaceInfo、Common Block、参数的共享实体等中 包含的所有信息构建操作结果。 | BOPAlgo_Section :: BuildSection() |
Volume Maker 算法
Volume Maker 算法设计用于从一组连接的、相交的或嵌套的形状构建基本体积(实体)。该算法还可用于将实体拆分为多个部分,或从一组相交或连接的面或壳构造新实体。该算法仅创建闭合实体。在一般情况下,结果实体是非流形的:位于实体内部的输入形状(线、面)的片段作为内部子形状添加到这些实体中。但是该算法允许防止将固体零件的内部添加到结果中。在这种情况下,结果实体将是多方面的,并且不包含任何内部零件。但是,此选项不会阻止面中出现内部边或顶点。
位于任何实体之外的非闭合面、自由线等始终被排除在结果之外。
Volume Maker 算法在BOPAlgo_MakerVolume类中实现。它基于通用联合(GF)算法。GF 算法的所有选项(请参阅GF 选项)在此算法中也可用。
参数的要求与 GF 算法的参数相同——它们可以是任何类型,但每个参数都应该是有效的并且不能自干扰。
该算法允许禁用参数之间的交集计算。在这种情况下,算法会运行得更快,但用户应保证参数不会相互干扰,否则结果将无效(例如包含意外部分)或为空。例如,此选项对于从一个壳的面或已相交的形状构建实体很有用。
用法
C++ 级别
API级别算法的使用:
例子
示例 1
从球体和 63 个平面集创建 9832 个实体:
|
|
示例 2
在由船壳和一组平面定义的船上创建隔间。该船由五个横向舱壁和一个甲板划分为多个隔间 – 创建了六个隔间:
|
|
细胞生成器算法
Cells Builder 算法是 General Fuse 算法的扩展。General Fuse 算法的结果包含参数的所有拆分部分。Cells Builder 算法提供了指定参数的任何给定拆分部分(称为 Cell)是否可以在结果中采用或避免的方法。
选择任何 Cell 的可能性允许组合任何可能的结果,并使 Cells Builder 算法具有非常广泛的应用范围 – 从构建任何布尔运算的结果到构建任何特定于应用程序的运算的结果。
该算法只构建一次 Cells,然后将它们重新用于组合结果。这使该算法具有优于布尔运算的性能优势,布尔运算总是重建拆分以获得理想的结果。
因此,Cells Builder 算法对于模拟布尔表达式特别有用,即对相同参数的一系列布尔运算。它允许在单个操作中获得最终结果,而不是执行许多布尔运算。Cells Builder 还有助于在相同参数上获得不同布尔运算的结果 – 例如,Cut 和 Common。
Cells Builder 算法还提供了移除相同类型拆分之间的任何内部边界的可能性,即融合添加到结果中的任何相同维度的部分并保持任何其他部分分开。这种可能性是通过 Cells 材质方法实现的:要移除两个 Cell 之间的边界,应该为两个 Cell 分配相同的材质 ID。但是,如果相同的材质 ID 已分配给不同维度的单元,则不会执行该材质的内部边界的移除。目前,这种情况被认为是算法的限制。
该算法还可以从添加到结果中的连接单元创建容器 – WIRES 来自 Edges,SHELLS 来自 Faces 和 COMPSOLIDS 来自 Solids。
用法
该算法已在BOPAlgo_CellsBuilder类中实现。
Cells Builder 基于 General Fuse 算法。因此,General Fuse 算法的所有选项(请参阅GF 选项)在此算法中也可用。
输入形状的要求与通用联合的要求相同 – 每个参数在BRepCheck_Analyzer和BOPAlgo_ArgumentAnalyzer方面应该是有效的。
算法的结果是包含基本类型(顶点、边、面或实体)的选定部分的复合。默认结果是空化合物。可以使用AddToRessult()和AddAllToResult()方法添加任何单元格。也可以使用RemoveFromResult()和RemoveAllFromResult()方法从结果中删除任何部分。RemoveAllFromResult()方法也适用于清除结果。
应该在结果中添加/删除的单元格是通过包含应该采取的部分 *(ShapesToTake)* 和包含应该避免的部分 (ShapesToAvoid) 的输入形状来定义的。要纳入结果,该部分必须是来自ShapesToTake 的所有形状和来自ShapesToAvoid的所有形状的OUT。
要移除内部边界,需要为 Cells 设置相同的材质,在它们之间移除边界,并调用方法RemoveInternalBoundaries()。材质不应等于 0,因为这是默认材质 ID。具有此材质 ID 的单元之间的边界不会被移除。同一个 Cell 不能添加不同的材料。也可以在合并结果时去除边界。为此,需要为零件设置材料(不等于 0)并将标志bUpdate设置为 TRUE。如果为不同尺寸的零件设置了相同的材质 ID,则不会执行该材质的内部边界的移除。
可以使用MakeContainers()方法从添加到结果中的部分创建类型化的容器。容器的类型取决于输入形状的类型:WIRES 用于 EDGE,SHELLS 用于 FACES,COMPSOLIDS 用于 SOLIDS。结果将是一个包含容器的化合物。
API 使用情况
以下是在 API 级别上使用的算法示例:
DRAW 用法
已实现以下一组新命令以在 DRAW 测试工具中运行算法:
以下是在 DRAW 级别上使用的算法示例:
例子
以下简单示例说明了算法在圆柱体和与平面相交的球体上工作的可能性:
1. 所有论点的共同点
2、圆柱面与面共通
3.圆柱体和球体的共同点
4.圆柱体和球体的熔断器
5. 实体内部的面部分 – FUSE(COMMON(f, c), COMMON(f, s))
6. 部分面外实体
7. 熔断器操作(使用标准布尔熔断器操作是不可能的)
这些例子可能会永远持续下去。要定义任何新操作,只需定义应采用哪些单元格以及应避免哪些单元格。
算法限制
本章描述了被认为是算法限制的问题。在大多数情况下,算法失败是由各种因素的组合引起的,例如自干扰参数、参数容差的不适当或无根据的值、参数的不利相互位置、相切等。
GFA 算法的很多失败可能是由低级算法中的错误引起的:交集算法、投影算法、逼近算法、分类算法等。
- 交集、投影和逼近算法主要用于交集步骤。他们的错误直接导致错误的截面结果(即不正确的截面边、截面点、缺失的截面边或微边)。如果部分结果错误,则无法获得正确的 GFA 最终结果。
- 投影算法用于交叉步骤。投影算法的目的是计算曲面上的二维曲线。此处错误的结果会导致最终 GFA 结果中的面不正确或缺失。
- 分类算法用于构建步骤。分类算法中的错误会导致选择形状部分(边、面、实体)时出错,并最终导致错误的最终 GFA 结果。
下面的描述说明了一些已知的 GFA 限制。它没有详尽地列举实践中可能出现的所有问题。请向 OCCT 维护服务解决算法故障的情况。
论据
常见要求
每个参数都应该是有效的(就BRepCheck_Analyzer 而言),或者相反,如果该参数被认为是无效的(就BRepCheck_Analyzer 而言),则它不能用作算法的参数。
BRepCheck_Analyzer类用于检查形状的整体有效性。在 OCCT 中,形状(或其子形状)如果满足特定标准则被认为是有效的。如果发现形状无效,可以通过ShapeAnalysis、ShapeUpgrade和ShapeFix包中的工具进行修复。
但是,需要注意的是,BRepCheck_Analyzer类只是一个工具,它可能有自己的问题;这意味着由于特定因素,此工具有时会提供错误的结果。
让我们考虑以下示例:
分析器检查面F上边E的一对3D 检查点(Pi, PSi)之间的距离。点Pi是从边的 3D 曲线(在参数ti处)获得的。PSi是从面F的表面S上的边的2D 曲线(在参数ti处)获得的。为了有效,所有检查点对的距离应小于Tol(E) 。这些检查点的数量是一个预定义的值(例如 23)。
让我们考虑边E被识别为有效的情况(根据BRepCheck_Analyzer)。
此外,经过一些操作,边E被分成两条边E1和E2。每条分割边与原始边E具有相同的 3D 曲线和 2D 曲线。
让我们检查E1(或 E2)。分析器再次检查检查点对(Pi, PSi)之间的距离。这些检查点的数量是相同的常数值 (23),但不能保证距离会小于Tol(E),因为为E1选择的点与E不同。
因此,如果分析器将E1识别为无效,则边E也应该是无效的。但是E已被认为是有效的。因此,分析器为E给出了错误的结果。
参数是有效形状的事实(根据BRepCheck_Analyzer)是产生算法有效结果的必要但不充分的要求。
纯自干扰
参数不应该是自干涉的,即通过任何拓扑实体(顶点、边、面)具有几何重合的参数的所有子形状都应该共享这些实体。
示例 1:两条边的复合
两条边E1和E2的复合是自干涉形状,不能作为算法的参数。
示例 2:自干涉边
边E是自干涉形状,不能用作算法的参数。
示例 3:自干扰面
面F是自干涉形状,不能用作算法的参数。
示例 4:革命的面貌
面F是由边E绕线L旋转得到的。
尽管面F是有效的(就BRepCheck_Analyzer 而言),但它是一个自干扰形状,不能用作算法的参数。
公差引起的自干扰
示例 1:非闭合边
让我们考虑基于非闭合圆的边E。
E的顶点之间的距离是D=0.69799。公差值Tol(V1)=Tol(V2)=0.5。
尽管边E在BRepCheck_Analyzer方面是有效的,但它是一个自干扰形状,因为它的顶点受到干扰。因此,边E不能用作算法的参数。
示例 2:包含干涉顶点的实体
让我们考虑包含顶点 V 的实体S。
公差值 Tol(V)= 50.000075982061。
尽管实体S在BRepCheck_Analyzer方面是有效的,但它是一个自干涉形状,因为顶点V与S中的许多子形状干涉,而与它们没有任何拓扑连接。因此,实体S不能用作算法的参数。
参数表示
某些曲面(圆柱、圆锥、旋转曲面)的参数化可能是限制的原因。
示例 1:圆柱面
圆柱面的参数化范围为:
U坐标的范围总是有限制的,而V坐标的范围是不受限制的。
让我们考虑一个半径为 R=3和H=6的基于圆柱的面 1。
让我们还考虑一个基于圆柱体的面 2,其半径R=3000和H=6000 (由比例因子ScF=1000缩放面 1 的结果)。
注意图形的缩放值。
很明显,从某个ScF值开始,例如ScF>1000000 ,面 2上的所有倾斜 p 曲线将几乎垂直。至少,由标准 C 运行时库函数(例如double acos(double x) )计算的角度值之间没有区别。角度计算精度的损失可能会导致一些 BP 子算法失败,例如从一组边构建面或从一组面构建实体。
使用顶点的公差来修复间隙
可以创建使用低阶子形状的形状,以避免基于公差的数据模型中的间隙。
让我们考虑以下示例:
- 面F有两条边E1和E2以及两个顶点,基平面为{0,0,0, 0,0,1};
- 边E1基于线{0,0,0, 1,0,0},Tol(E1) = 1.e-7;
- 边E2基于线{0,1,0, 1,0,0},Tol(E2) = 1.e-7;
- 顶点V1,点{0,0.5,0},Tol(V1) = 1;
- 顶点V2,点{10,0.5,0},Tol(V2) = 1;
- 面F是有效的(就BRepCheck_Analyzer 而言)。
公差Tol(V1)和Tol(V2)的值足够大,可以固定边的末端之间的间隙,但是顶点V1和V2不包含任何关于连接边对应末端的轨迹的信息。因此,轨迹是不确定的。这会导致 BP 的一些子算法失效。例如,用于从一组边构建面的子算法使用有关在一个顶点中连接的所有边的信息。一个顶点有几对边的情况将无法正确解决。
交叉口问题
纯交叉口和公共区域
示例:相交边
让我们考虑两条边之间的交点:
- E1基于一行:{0,-10,0, 1,0,0},Tol(E1)=2。
- E2基于一个圆:{0,0,0,0,0,1},R=10,Tol(E2)=2。
E1和E2之间纯相交的结果是顶点Vx {0,-10,0}。
考虑到公差的相交结果是公共区域CZ(3D 空间的一部分,其中曲线之间的距离小于或等于边公差的总和。
算法的交集部分使用纯交集Vx而不是CZ的结果,原因如下:
- 算法不会基于明显不同类型的底层曲线(例如线/圆)在边之间产生公共块。如果曲线有不同的类型,经验法则是产生的结果是类型vertex。此规则不适用于非解析曲线(Bezier、B-Spline)及其与解析曲线的组合。
- 两个曲面之间的相交算法IntPatch_Intersection不计算曲线和点之间相交的CZ。所以即使CZ是通过 Edge/Edge 相交算法计算出来的,它的结果也不能被 Face/Face 相交算法处理。
公差和误差
以下限制是由建模错误或不准确造成的。
示例:平面的相交
让我们考虑两个平面矩形面F1和F2。
平面之间的相交曲线是曲线C12。该曲线产生一个新的相交边EC12。由于顶点Tol(V1)和Tol(V2)的大公差值,边通过顶点V1和V2。因此,两条直边E12和EC12穿过两个顶点,在这种情况下这是不可能的。
这个问题一般不能解决,因为E12的长度可以是无限的,Tol(V1)和Tol(V2)的值理论上也可以是无限的。
在特定情况下,可以通过多种方式解决问题:
- 如果可能,减少Tol(V1)和Tol(V2)的值( F1的细化)。
- 分析 Tol(EC12) 的值并增加Tol(EC12)以获得边EC12和E12之间的公共部分。然后公共部分将被拒绝,因为面F1已经存在边E12。
很容易看出,如果C12略高于V1和V2的公差范围,则不会出现问题。
示例:两条边的交点
让我们考虑两条边E1和E2,它们具有公共顶点V1和V2。边E1和E2具有 3D 曲线C1和 *C2。Tol(E1)=1.e -7 , Tol(E2)=1.e -7 .*
C1实际上在 3D 中与C2重合。偏转值是Dmax(例如 *Dmax=1.e -6 *)。
明显和预期的结果应该是E1和E2之间的公共块。但是,相交的结果不同。
结果包含三个新顶点Vx1、Vx2和Vx3,8 条新边(V1、Vx1、Vx2、Vx3、V2)并且没有公共块。由于源数据,这是正确的: *Tol(E1)=1.e -7, Tol(E2)=1.e -7 * 和Dmax=1.e -6。
在这种特殊情况下,可以通过多种方式解决问题:
- 如果可能,增加值Tol(E1)和Tol(E2)以在公差方面获得E1和E2之间的 3D 重合。
- 用更精确的模型替换E1 。
该示例可以从 1D(边)扩展到 2D(面)。
评论和建议与上述一维案例相同。
获得性自干扰
示例 1:顶点和边
让我们考虑顶点V1和边E2。
顶点V1与顶点V12和V22发生干涉。所以顶点V21应该干涉顶点V22,这是不可能的,因为顶点V21和V22是边E2的顶点,因此V21不等于V22。
该问题一般无法解决,因为长度可以尽可能小以提供E2的有效性(在极端情况下:长度 (E2) = Tol(V21) + Tol(V22) + e,其中e-> 0)。
在特定情况下,可以通过改进参数来解决问题,即通过减小Tol(V21)、Tol(V22)和Tol(V1)的值。
示例 2:顶点和线
让我们考虑顶点V2和由边E11和E12组成的线。
论点本身不是自相交的。顶点V2与边E11和E12发生干涉。因此,边E11应该与边E22发生干涉,但这是不可能的,因为边E11和E12不受条件干涉。
非自干扰参数(或其子形状)由于与其他参数(或其子形状)的交叉而受到干扰的情况被认为是算法的限制。
高级选项
前面的章节描述了所谓的基本操作。大多数任务都可以使用基本操作来解决。尽管如此,有些情况并不能通过基本操作直接解决。这些任务被视为基本操作的限制。
本章专门介绍高级选项。在某些情况下,使用高级选项可以克服限制,提高操作结果的质量、操作员本身的稳健性和性能。
模糊布尔运算
Fuzzy Boolean operation 是基本操作的选项,例如 General Fuse、Splitting、Boolean、Section、Maker Volume 和 Cells 构建操作,其中使用了额外的用户指定的容差。此选项允许操作员稳健地处理参数的接触和近乎重合、未对齐的实体的情况。
模糊选项对于在这些形状的实体之间具有间隙或嵌入的形状很有用,这些实体的公差值未涵盖这些形状。这种形状可能是建模错误、翻译过程、从其他系统导入而导致精度损失或某些算法错误的结果。
最有可能的是,基本操作将在此类模型上给出不令人满意的结果。结果可能包含意外和不需要的小实体、有缺陷的实体(就BRepCheck_Analyzer 而言),或者根本没有结果。
使用模糊选项可以获得预期的结果——只需为操作定义适当的模糊容差值。要定义该值,有必要测量模型实体之间的间隙值(或嵌入深度值),稍微增加它(以使偏移的实体在其公差加上额外的公差方面一致)和将其传递给算法。
模糊选项包含在交叉部分的接口(类BOPAlgo_PaveFiller)和应用程序编程接口(类BRepAlgoAPI_BooleanOperation)中
例子
以下示例演示了在典型情况下使用模糊选项操作相对于基本操作的优势。
情况1
在此示例中,圆柱体(以黄色和透明显示)从框(以红色显示)中减去。圆柱体沿其轴线相对于盒子移动5e -5(盒子背面与圆柱体之间的距离为5e -5)。
使用基本操作和模糊值为 5e -5的模糊操作获得以下结果:
在此示例中,模糊选项允许消除由于长方体和圆柱体的背面未对齐而由基本算法产生的结果形状中非常薄的部分。
案例2
在这个例子中,两个盒子被融合了。其中一个尺寸为 10*10*10,另一个尺寸为 10*10.000001*10.000001,与第一个相邻。在这种情况下没有间隙,因为相邻面的表面重合,但一个框略大于另一个框。
使用基本操作和模糊值为 1e -6的模糊操作获得以下结果:
在此示例中,模糊选项允许在基本操作产生的结果中消除极窄的面。
案例3
在此示例中,从大平面(以黄色显示)中减去了小平面(以橙色显示)。这些面的边之间有一个间隙 1e -5 。
使用基本操作和模糊值为 1e -5的模糊操作获得以下结果:
在此示例中,模糊选项消除了由参数面边之间的间隙导致的针状突起。
案例4
在本例中,从大边中减去小边。边不精确地重叠,它们之间的最大偏差等于 5.28004e -5。我们将为模糊选项使用 6e -5值。
使用基本操作和模糊值为 6e -5的模糊操作获得以下结果:
这个例子不仅强调了有效性,还强调了性能问题。使用具有适当值的模糊选项可以比使用纯基本操作更快地处理案例。该机箱的性能增益为 45(处理器:Intel(R) Core(TM) i5-3450 CPU @ 3.10 GHz)。
涂胶操作
Gluing 操作是基本操作的选项,例如 General Fuse、Splitting、Boolean、Section、Maker Volume 和 Cells 构建操作。它旨在加速计算特殊情况下操作的参数之间的干扰,其中参数可能重叠,但它们的子形状之间没有真正的交集。
此选项不能用于具有真正相交的形状,例如边之间的相交顶点,或边与面之间的相交顶点或面之间的相交线:
重叠形状有两种可能性:
- 形状可以部分重合 – 面没有相交曲线,而是重叠。此类参数的面将在操作过程中被分割。下图说明了这些形状:
- 形状可以完全重合 – 面不应该有部分重叠,因此根本没有 EDGE/FACE 类型的交集。在这种情况下,操作过程中不会分割面。
因此,有两种可能的选择——形状的完全重合和部分重合。
即使在没有 Gluing 选项的情况下没有真正的交集,该算法仍会将参数的子形状与干扰边界框相交。
粘合模式下的性能改进是通过排除最耗时的计算来实现的,在某些情况下可以达到 90%:
- 排除部分重合的 FACE/FACE 交叉点的计算;
- 排除 VERTEX/FACE、EDGE/FACE 和 FACE/FACE 交叉点的计算以实现完全重合。
通过为操作设置 Gluing 选项,用户应该保证参数确实一致。该算法本身并不检查这一点。为操作设置不合适的选项很可能导致不正确的结果。
用法
Gluing选项是在BOPAlgo_GlueEnum.hxx中实现的枚举:
- BOPAlgo_GlueOff – 算法的默认值,胶合关闭;
- BOPAlgo_GlueShift – 部分重合形状的胶水选项;
- BOPAlgo_GlueFull – 完全重合形状的胶水选项。
API 级别
为了设置算法的粘合选项,只需调用具有适当值的 SetGlue(const BOPAlgo_Glue) 方法:
例子
Case1 – 将 64 个 bspline 框融合为一个实体
在这种情况下,使用 GlueShift 选项的性能改进约为 70%。
案例 2 – 从 IGES 读取后缝合形状的面
在这种情况下,性能也提高了 70% 左右。
安全处理模式
安全处理模式是布尔运算组件中的高级选项。该模式适用于所有基本操作,如General Fuse、Splitting、Boolean、Section、Maker Volume、Cells building。此选项允许保持输入参数不变。换句话说,打开此选项可防止输入参数进行任何修改,例如公差增加、在边上添加 P 曲线等。
该选项对于在应用程序中实现撤消/重做机制非常有用,并且允许在不更改输入的情况下多次执行操作。
默认情况下,算法的安全处理选项是关闭的。启用此选项可能会略微降低操作的性能,因为不需要修改某些实体,而是需要创建该实体的副本并对其进行修改。然而,这种降级应该非常小,因为仅在必要的情况下才执行复制。
该选项在交叉点算法 – BOPAlgo_PaveFiller中也可用。要对相同的参数执行多个不同的操作,可以在 PaveFiller 中启用安全处理模式,只准备一次,然后在操作中使用。仅将此选项设置为 PaveFiller 就足够了,所有采用此 PaveFiller 的算法也将在安全模式下工作。
用法
API 级别
要启用/禁用算法的安全处理模式,需要调用具有适当值的SetNonDestructive()方法:
如何禁用检查输入固体的反转状态
默认情况下,检查所有输入实体的反转状态,即对实体进行分类以了解它们是空间中的孔(负体积)还是正常实体(正体积)。禁用检查输入实体的反转状态的可能性是布尔运算组件中的高级选项。此选项可应用于所有基本操作,例如通用熔断、拆分、布尔、截面、制造商体积和单元格构建。此选项允许避免耗时的输入固体分类,并以与正体积相同的方式处理它们,在输入固体数量很大的情况下最多可节省 10% 的时间。
仅当用户确定输入实体中没有负体积时才应禁用分类,否则结果可能无效。
用法
API 级别
要启用/禁用输入实体的分类,需要使用适当的值调用SetCheckInverted()方法:
定向边界框的使用
由于定向边界框通常比轴对齐边界框更紧密(有关 OBB 的更多信息,请参阅建模数据用户指南的边界框章节),它的使用可以通过减少干扰对象的数量来显着加快操作的交叉阶段.
用法
API 级别
要在操作中启用/禁用 OBB 的使用,需要使用适当的值调用SetUseOBB()方法:
错误和警告报告系统
本章描述了布尔组件中算法的错误/警告报告系统。
错误和警告收集在Message_Report类的实例中,由布尔运算算法BOPAlgo_Options的公共基类作为字段维护。
对于无法处理并导致算法失败的问题,将报告该错误。在这种情况下,操作的结果将不正确或不完整,或者根本没有结果。
针对可能被处理或忽略的问题报告警告,因此不会导致算法停止工作(但可能会影响结果)。
该算法可以设置的所有可能的错误和警告都列在其头文件中。布尔运算可以生成的错误和警告的完整列表在BOPAlgo_Alerts.hxx中定义。
使用HasErrors()方法检查是否存在错误;方法HasError()可用于检查特定错误。方法DumpErrors()将收集到的错误的文本描述输出到流中。为警告提供了类似的方法HasWarnings()、HasWarning()和DumpWarnings() 。
请注意,与错误和警告对应的消息在资源文件BOPAlgo.msg中定义。这些消息可以本地化;将翻译后的版本放到单独的文件中,并通过调用Message_MsgFile::Load()将其加载到应用程序中。
以下是如何使用该系统的示例:
执行布尔运算的 DRAW 命令以文本形式输出由这些运算生成的错误和警告。附加选项允许将已生成警告的形状保存为 DRAW 变量。要激活此选项,请使用参数 1 运行命令bdrawwarnshapes(或使用 0 停用):
设置此选项并运行算法后,结果将如下所示:
历史信息
布尔组件中的所有操作都支持历史信息。本章介绍如何为这些操作填充历史记录。
除了顶点、边和面之外,实体的历史记录也可用。
填充已删除和已修改形状的历史信息的规则与 API 算法相同。
只有生成形状的规则需要澄清。就布尔组件中的算法而言,只有当这些新形状是由于该形状与来自参数的任何其他形状的纯交集(不重叠)而获得时,参数中的形状才能具有生成的形状。因此,生成的形状总是:
- 从交点创建的顶点,只能从边和面生成;
- EDGES 从相交边创建,并且只能从面生成。
因此,只有 EDGES 和 FACES 可以拥有有关 Generated 形状的信息。对于所有其他类型的形状,生成的形状列表将为空。
例子
以下是一些说明历史信息的示例。
已删除的形状
两个重叠平面的 CUT 操作结果(参见下面的示例)不包含来自工具面的任何零件。因此,工具面被视为已删除。如果面不完全重合,则结果必须包含对象面的某些部分。在这种情况下,对象面将被视为未删除。但如果面完全重合,则结果必须为空,两个面都将被视为已删除。
重叠面的示例:
修改后的形状
在两条边相交于一点的 FUSE 操作中(见下例),两条边都会被交点分开。所有这些拆分都将包含在结果中。因此,每个输入边都将被修改为它的两个分割。但是在相同边上的 CUT 操作中,工具边将从结果中删除,因此不会有任何修改的形状。
相交边的示例:
生成的形状
两条相交的边都将具有从它们生成的相交顶点。
对于相交面的操作,请考虑以下示例:
BOP 结果简化
实现布尔运算的 API 算法提供了通过统一连接的切边和面来简化结果形状的可能性。这种简化是通过在类BRepAlgoAPI_BuilderAlgo(通用熔断操作)中实现的方法SimplifyResult执行的。它使BRepAlgoAPI_BooleanOperation(所有布尔操作)和BRepAlgoAPI_Splitter(拆分操作)类的用户可用。
通过ShapeUpgrade_UnifySameDom算法进行简化。运算结果被简化结果覆盖。
简化是在不创建内部形状的情况下执行的,即永远不会破坏形状连接。它在整个结果形状上执行。因此,如果输入形状包含连接的切边或在操作期间未修改的面,它们也将被统一。
简化的历史被合并到主要的操作历史中,因此在询问修改、生成和删除的形状时将被计算在内。
主要操作的一些选项被传递到 Unifier 中:
- 操作的模糊容差作为线性容差赋予统一器。
- 这里的无损模式控制着 Unifier 中的安全输入模式。
为了在 DRAW 中控制这种可能性,已经实现了命令bsimplify 。请参阅绘图用户指南中的布尔运算选项章节。
例子
下面是简化两个框的 Fuse 操作结果的简单示例:
|
|
用法
本章包含 OCCT 布尔组件用法的一些示例。可以在两个级别上使用:C++ 和 Tcl。
包 BRepAlgoAPI
BRepAlgoAPI包提供布尔组件的应用程序编程接口。
该包由以下类组成:
- BRepAlgoAPI_Algo – 为算法提供接口的根类。
- BRepAlgoAPI_BuilderAlgo – General Fuse 算法的类 API 级别。
- BRepAlgoAPI_Splitter – Splitter 算法的类 API 级别。
- BRepAlgoAPI_BooleanOperation – BRepAlgoAPI_Fuse类的根类。BRepAlgoAPI_Common、 BRepAlgoAPI_Cut和BRepAlgoAPI_Section。
- BRepAlgoAPI_Fuse – 该类提供布尔融合操作。
- BRepAlgoAPI_Common – 该类提供布尔通用操作。
- BRepAlgoAPI_Cut – 该类提供布尔切割操作。
- BRepAlgoAPI_Section – 该类提供布尔部分操作。
类的详细描述可以在相应的 .hxx 文件中找到。本章的示例如下。
封装 BOPTest
包BOPTest提供了在 Tcl 级别上使用布尔组件。BOPTest::APICommands方法包含相应的 Tcl 命令:
- bapibuild – 用于通用联合操作员;
- bapisplit – 用于拆分器运算符;
- bapibop – 用于布尔运算符和部分运算符。
本章下面将举例说明如何使用这些命令。
案例 1. Fuse操作
以下示例说明了如何使用 Fuse 运算符:
C++ 级别
案例二、拆分操作
以下示例说明了如何使用 Splitter 运算符:
C++ 级别
案例三、Common操作
以下示例说明了如何使用 Common 操作:
C++ 级别
案例 4. Fuse操作
以下示例说明了如何使用 Fuse 操作:
C++ 级别
案例五、cut操作
以下示例说明了如何使用剪切操作:
C++ 级别
案例六、分段操作
以下示例说明了如何使用 Section 操作:
暂无评论内容