OpenCasCade官方开发文档翻译(5)–occt网格

网格演示

除了支持 3D 对象的精确几何表示之外,Open CASCADE 技术还提供了以网格形式处理对象的镶嵌表示的功能。

开放式 CASCADE 技术网格功能提供:

  • 存储与形状相关的表面网格数据的数据结构,以及处理这些数据的一些基本算法
  • 从BRep对象(形状)构建表面三角形网格的数据结构和算法。
  • 用于扩展 Open CASCADE 技术的 3D 可视化功能的工具,显示网格以及相关的预处理器和后处理器数据。

Open CASCADE Technology 包括两个网格转换器:

  • VRML 转换器将 Open CASCADE 形状转换为 VRML 1.0 文件(虚拟现实建模语言)。开放的 CASCADE 形状可以转换为两种表示形式:阴影或线框。阴影表示将形状呈现为由网格算法计算的三角形集,而线框表示将形状呈现为曲线集。
  • STL 转换器将 Open CASCADE 形状转换为 STL 文件。STL(STtereoLithography)格式广泛用于快速原型制作。

Open CASCADE SAS 还提供高级网格产品:

此外,我们可以在曲面和体网格划分算法、网格优化算法等领域为您提供有效帮助。如果您需要有关网格划分算法的合格建议,请不要犹豫,从我们团队在该领域的专业知识中受益。

处理数值模拟的项目可以受益于使用 SALOME – 一个用于 CAE 的开源框架,具有 CAD 数据接口、通用的前后 FE 处理器和用于集成 FE 求解器的 API。

在https://www.salome-platform.org上了解有关 SALOME 平台的更多信息

网格划分算法

形状三角剖分算法由BRepMesh_IncrementalMesh类的功能提供,该类将形状三角剖分添加到其拓扑数据结构中。此三角测量用于在阴影模式下可视化形状。

Standard_Boolean meshing_explicit_parameters()
{
const Standard_Real aRadius = 10.0;
const Standard_Real aHeight = 25.0;
BRepPrimAPI_MakeCylinder aCylinder(aRadius, aHeight);
TopoDS_Shape aShape = aCylinder.Shape();
const Standard_Real aLinearDeflection = 0.01;
const Standard_Real anAngularDeflection = 0.5;
BRepMesh_IncrementalMesh aMesher (aShape, aLinearDeflection, Standard_False, anAngularDeflection, Standard_True);
const Standard_Integer aStatus = aMesher.GetStatusFlags();
return !aStatus;
}
Standard_Boolean meshing_imeshtools_parameters()
{
const Standard_Real aRadius = 10.0;
const Standard_Real aHeight = 25.0;
BRepPrimAPI_MakeCylinder aCylinder(aRadius, aHeight);
TopoDS_Shape aShape = aCylinder.Shape();
aMeshParams.Deflection = 0.01;
aMeshParams.Angle = 0.5;
aMeshParams.Relative = Standard_False;
aMeshParams.InParallel = Standard_True;
aMeshParams.MinSize = Precision::Confusion();
BRepMesh_IncrementalMesh aMesher (aShape, aMeshParams);
const Standard_Integer aStatus = aMesher.GetStatusFlags();
return !aStatus;
}

默认的网格划分算法BRepMesh_IncrementalMesh有两个主要的选项来定义三角剖分——线性和角度偏转。

第一步,根据指定的参数对面的所有边进行离散化。

第二步,对面进行细分。线性偏转限制了曲线与其镶嵌之间的距离,而角度偏转限制了折线中后续线段之间的角度。

图片[1]-OpenCasCade官方开发文档翻译(5)–occt网格-卡核

BRepMesh_IncrementalMesh算法的挠度参数

还有其他选项可以控制面内部的网格划分行为:DeflectionInteriorAngleInteriorDeflectionInterior限制了三角形和面内部之间的距离。AngleInterior(仅用于 B 样条面的细分)限制三角形每个链接节点中法线(图片中的 N1、N2 和 N3)之间的角度。沿面边界边缘的链接有一个例外,在边缘离散化期间对它们使用“角偏转”。

图片[2]-OpenCasCade官方开发文档翻译(5)–occt网格-卡核

线性和角度内部偏转

请注意,如果给定的线性变形值小于形状公差,则算法将跳过该值并考虑形状公差。

应用程序应提供偏转参数来计算令人满意的网格。角度偏转相对简单,允许使用默认值(12-20 度)。线性偏转具有绝对意义,应用程序应为其模型提供正确的值。给出较小的值可能会导致网格过大(消耗大量内存,从而导致计算时间长且渲染速度慢),而较大的值会导致网格变得丑陋。

对于在预先知道的尺寸中工作的应用程序,对所有模型使用绝对线性偏转是合理的。这会根据应用程序中使用的度量和精度提供网格(例如,已知模型将以米为单位存储,0.004 m 对于大多数任务来说就足够了)。

但是,导入在其他应用程序中创建的模型的应用程序可能不会对所有模型使用相同的偏转。请注意,这实际上是一种异常情况,此应用程序可能只是 CAD 模型的查看器,其尺寸变化了一个数量级。这个问题可以通过引入具有一些 LOD(细节层次)的相对线性偏转的概念来解决。详细程度是绝对变形的比例因子,应用于模型尺寸。

网格化使用三角形网格覆盖形状。除了去除隐藏线之外,您还可以使用网格划分将形状转移到另一个工具:制造工具、着色算法、有限元算法或碰撞算法。

您可以通过首先探索它来获取有关形状的信息。要稍后访问形状中的面的三角剖分,请使用BRepTool::Triangulation。要访问多边形,它是面部边缘的近似值,请使用BRepTool::PolygonOnTriangulation

BRepMesh 架构

目标

所选架构的主要目标是:

  • 消除数据结构、辅助工具和算法之间的紧密联系,创建可扩展的解决方案,易于维护和改进;
  • 为了简化调试和可读性,将代码分离在几个负责具体操作的功能单元中;
  • 引入新的数据结构,使操作特定实体(边缘、线、面)的离散模型成为可能,以便在本地执行计算,而不是处理整个模型;
  • 实施一种新的三角测量算法,以替换包含需要移至上层的过于复杂的解决方案的现有功能。此外,提供根据表面类型更改算法的可能性(最初是为了加快平面的网格划分)。

一般工作流程

图片[3]-OpenCasCade官方开发文档翻译(5)–occt网格-卡核

BRepMesh 组件的一般工作流程

一般来说,组件的工作流程可以分为六个部分:

  • 创建模型数据结构:分析传递给算法的源TopoDS_Shape并将其分解为面和边。在数据模型中创建对应于每个拓扑实体的反射。请注意,底层算法使用数据模型作为输入并通过通用接口访问它,该接口允许创建具有特定实体之间必要依赖关系的自定义数据模型(参见“数据模型接口”段落);
  • 离散化边缘 3D 和 2D 曲线:离散化 3D 曲线以及每个模型边缘的相关 2D 曲线集,以创建一个连贯的骨架,用作面网格剖分过程的基础。如果源形状的边缘已经包含适合指定参数的多边形数据,则从形状中提取它并按原样存储在模型中。每条边单独处理,不考虑邻接关系;
  • 修复离散模型:源TopoDS_Shape可能包含在设计、交换或修改模型时引入的问题,例如开线或自相交。此外,一些问题,如自相交,可以通过粗略离散的边引入。此阶段负责分析离散模型,以检测和修复问题,或在无法解决问题的情况下拒绝对模型部分进行进一步处理;
  • 预处理离散模型:定义特定于在面网格化之前执行的已实现方法的动作。默认情况下,此操作迭代模型面,检查现有三角剖分的一致性,并在不一致的情况下从多边形数据中清除拓扑面和相邻边,或将离散模型的面标记为计算不需要;
  • 离散面:表示基于二维离散数据为特定面执行网格生成的核心部分。此操作缓存与数据模型中的面边相关的多边形数据以供进一步处理,并将生成的网格存储到TopoDS_Face
  • 后处理离散模型:定义特定于在面网格化后执行的实施方法的动作。默认情况下,此操作将前一阶段获得的多边形数据存储到源模型的TopoDS_Edge对象中。

常用接口

组件结构包含两个单元:IMeshData(见数据模型接口)和IMeshTools,分别定义了数据模型和算法工具的通用接口。IMeshTools_Context类表示这些单元之间的连接器。上下文类缓存数据模型以及与上述工作流的六个阶段中的每个阶段对应的工具,并提供安全调用相应工具的方法(与IntTools_Context类似,以保持与 OCCT 核心工具的一致性)。除第一个阶段外,所有阶段都使用数据模型作为输入并对整个结构执行特定操作。因此,API 类IMeshTools_ModelAlgo是为了统一操作数据模型的工具的接口而定义的。每个应该处理数据模型的工具都应该继承这个接口,从而可以在上下文中缓存它。与其他不同的是,由于阶段的不同含义,模型构建器接口由另一个类IMeshTools_ModelBuilder定义。启动整个工作流程的入口点由IMeshTools_MeshBuilder表示。

IMeshTools_Context的默认实现在BRepMesh_Context类中给出,通过默认算法工具的实例初始化上下文。

工厂接口IMeshTools_MeshAlgoFactory提供了更改特定表面的三角测量算法的可能性。工厂通过IMeshTools_MeshAlgo接口返回三角测量算法的实例,具体取决于作为参数传递的曲面类型。它应该在面离散化阶段使用。

AlgoFactory 的默认实现在BRepMesh_MeshAlgoFactory返回根据传递的表面类型选择的不同复杂度的算法中给出。反过来,它被用作BRepMesh_FaceDiscret算法的初始化器,代表面离散化阶段的启动器。

图片[4]-OpenCasCade官方开发文档翻译(5)–occt网格-卡核

描述网格划分工作流程入口点的界面

其余接口描述辅助工具:

创建模型数据结构

用于保存底层算法所需的离散和临时数据的数据结构是在网格划分过程的第一阶段创建的。通常,该模型表示适用于目标任务的源拓扑形状的实体之间的依赖关系。

数据模型接口

Unit IMeshData提供通用接口,指定在整个工作流程的不同阶段使用的数据模型 API。设计的接口的依赖关系和引用如下图所示。特定的接口实现取决于目标应用程序,它允许开发人员实现不同的模型并使用自定义的低级数据结构,例如不同的集合,NCollection或 STL。IMeshData_Shape用作所有保持拓扑形状的数据结构和工具的基类,以避免可能的复制粘贴。

接口的默认实现在BRepMeshData单元中给出。默认数据模型的主要目的是提供以并行模式执行边缘离散化的特征。因此,curve、pcurve 和其他类基于 STL 容器和智能指针,只要NCollection在某些情况下不提供线程安全(例如NCollection_Sequence)。此外,它紧密地反映了源形状的拓扑结构,即数据模型中的边数等于源模型中的边数;每条边都包含一组与其相邻面相关联的 pcurve,这允许在单独的线程中为所有 pcurve 或特定边的 3D 曲线创建离散的多边形。

优点:在必要的情况下,数据模型(可能带有处理算法)可以很容易地被另一个支持另一种元素之间依赖关系的实现替代。

不同数据模型的另一个示例是不需要创建具有在相邻面之间同步的离散多边形的网格的情况,即在需要加速创建用于可视化或快速计算的粗糙的每面细分的情况下仅(在XDEDRAW_Props中使用的方法)。

图片[5]-OpenCasCade官方开发文档翻译(5)–occt网格-卡核

数据模型通用API

采集数据模型

在这个阶段,数据模型根据源形状的拓扑结构由实体填充。BRepMeshData中给出了数据模型的默认实现单位并将模型表示为两组:一组边和一组面。每个面都由一根或多根线组成,其中第一根总是代表外线,而其他的是内部线。反过来,每条线都描绘了定向边缘的有序序列。每条边的特征在于一条 3D 曲线和零(在自由边的情况下)或多个与该边相邻的面相关联的 2D 曲线。3D 和 2D 曲线都表示在参考面的 3D 和 2D 空间中定义的一组点参数对。曲线和 pcurve 之间的另一个区别是后者具有对其定义的面的引用。

模型填充算法由BRepMesh_ShapeVisitor类表示,在BRepMesh_ShapeExplorer对目标形状的边缘和面执行迭代的帮助下,将模型创建为拓扑形状的反射。请注意,该算法在数据模型的公共接口上运行,并在不了解实现细节和底层数据结构的情况下创建结构。收集功能的入口点是BRepMesh_ModelBuilder类。

离散化边缘 3D 和 2D 曲线

在这个阶段,只考虑数据模型的边缘。每条边都是单独处理的(可以在多个线程中运行处理)。检查边缘是否存在现有的多边形数据。如果至少存在一个表示并适合网格划分参数,则将其恢复并用作整个 pcurve 集以及分配给边缘的 3D 曲线的细分的参考数据(请参阅BRepMesh_EdgeTessellationExtractor)。否则,将创建一个新的细分算法并用于生成初始多边形(请参阅BRepMesh_CurveTessellator)并将边缘标记为过时。此外,模型边缘通过偏转以及重新计算的相同范围、相同参数和退化参数进行更新。请参见BRepMesh_EdgeDiscret实施细节。

IMeshData单元定义接口IMeshData_ParametersListArrayAdaptor,旨在将任意数据结构适配到NCollection_Array1容器 API。此解决方案使用NCollection_Array1IMeshData_Curve作为BRepMesh_EdgeParameterProvider工具的源,旨在生成一致的参数化,同时考虑相同的参数属性。

治愈离散模型

一般来说,这个阶段代表了对整个离散模型执行的一组操作,以解决由于设计、转换或粗离散化引起的问题而导致的不一致。可以根据目标三角剖分算法执行不同的操作序列,例如,有不同的方法来处理自相交——通过降低目标精度来放大边缘离散化或在相交点分割链接。在这个阶段,整体考虑了整组边,并考虑了它们的邻接性。BRepMesh_ModelHealer中给出了模型治疗器的默认实现,它执行以下操作:

  • 迭代模型面并检查它们的线是否一致,即线是否闭合且不包含自相交。数据结构设计为无冲突,因此可以以并行模式运行处理;
  • 强制连接参数空间中相邻边的末端,关闭可能断开的零件之间的间隙。该操作的目的是创建一个相对于目标面部的参数空间定义的正确离散模型,仅考虑 3D 空间的连通性和容差。这意味着无需进行特定计算来确定 U 和 V 容差;
  • 注册形成面部形状的边缘上的交叉点。为了解决自相交,有两种可能的解决方案:
    • 减少特定边缘的偏转并更新其离散模型。之后,工作流程“交叉点检查 – 放大”最多重复 5 次。结果,目标边包含更精细的细分,网格继续进行,或者面被IMeshData_SelfIntersectingWire状态标记并拒绝进一步处理;
    • 按交点分割目标边,并将更新的多边形与曲线和与每条边关联的剩余 pcurve 同步。与具有保证结果的放大过程相比,此操作提供了更稳健的解决方案,但从同步功能的角度来看,实现起来更加困难。

预处理离散模型

此阶段实现在面网格化之前要执行的操作。根据目标目标,它可以更改或省略。默认情况下,BRepMesh_ModelPreProcessor实现了检查拓扑面以确保现有三角剖分一致性的功能,即:与目标偏转参数的一致性;三角形引用的节点的索引不超过存储在三角剖分中的节点数。如果面未通过某些检查,则会从三角剖分中清除它,并从现有多边形中清除其相邻边缘。这不会影响离散模型,也不需要任何重新计算,因为尽管多边形的一致性,模型仍会为整个边缘集保留细分。

离散面

面的离散化是网格划分算法的一般部分。在这个阶段,在前面的步骤中获得和处理的边缘镶嵌数据用于形成目标面的轮廓,并作为输入传递给三角剖分算法。默认实现由BRepMesh_FaceDiscret类提供,该类表示三角测量算法的启动器。它遍历数据模型中可用的面,根据通过IMeshTools_MeshAlgoFactory与每个面关联的表面类型创建三角测量算法的实例并执行它。每个面都是单独处理的,因此可以以并行模式处理面。下图给出了面离散化的类图。

图片[6]-OpenCasCade官方开发文档翻译(5)–occt网格-卡核面离散阶段类图

一般来说,面网格划分算法具有以下结构:

  • BRepMesh_BaseMeshAlgo实现了 IMeshTools_MeshAlgo接口和继承算法的基本功能。此类的主要目标是初始化BRepMesh_DataStructureOfDelaun的实例以及适用于嵌套算法的辅助数据结构,使用作为输入参数传递的面模型数据。尽管实现了三角测量算法,但目前认为这种结构对于 OCCT 来说是常见的。但是,用户可以自由实现自定义算法和支持数据结构,可通过IMeshTools_MeshAlgo接口访问,例如连接不支持TopoDS_Shape的 3-rd 方网格划分工具开箱即用。为此,这种结构提供了以插件的形式将连接器分配给各种算法的可能性;
  • BRepMesh_DelaunayBaseMeshAlgoBRepMesh_SweepLineMeshAlgo类实现直接在BRepMesh_DataStructureOfDelaun实例上运行的核心网格划分功能。算法代表网格生成工具,将新点从数据结构添加到最终网格;
  • BRepMesh_NodeInsertionMeshAlgo类表示一个包装器,旨在扩展从BRepMesh_BaseMeshAlgo继承的算法,以启用生成表面节点并将其插入结构的功能。在这个级别上,创建了一个分类工具的实例,可用于接受-拒绝内部节点。此外,执行相对于为相应方向指定的范围缩放点的 UV 坐标所需的计算。就这两种三角剖分算法都处理结构提供的静态数据而言,在初始化阶段会添加新节点。曲面节点由称为范围拆分器的辅助工具生成,并作为模板参数传递(请参阅范围拆分器);
  • BRepMesh_DelaunayNodeInsertionMeshAlgo和BRepMesh_SweepLineNodeInsertionMeshAlgo类实现与添加内部节点相关的算法特定功能,以补充BRepMesh_NodeInsertionMeshAlgo提供的功能;
  • BRepMesh_DelaunayDeflectionControlMeshAlgo通过附加程序控制生成的三角形的偏转扩展了 BRepMesh_DelaunayNodeInsertionMeshAlgo 的功能

BRepMesh 为用户提供了一种将默认三角测量算法切换为自定义算法的方法,由用户实现或在全球范围内可用。目前可以使用三个基类来集成第 3 方算法:

  • BRepMesh_ConstrainedBaseMeshAlgo工具的基类,用于生成具有约束的三角剖分,不需要 BRepMesh 进行公共处理;
  • BRepMesh_CustomBaseMeshAlgo为不支持约束的通用算法提供入口点,并且仅用于生成基础网格。约束边使用组件本身提供的标准功能在由 3rd-party 求解器生成的背景网格上进行处理;
  • BRepMesh_CustomDelaunayBaseMeshAlgo包含 BRepMesh 使用的工具的初始化部分,用于使用 3rd 方算法的结果进行检查或优化。

可以通过使用相关接口实现IMeshTools_MeshAlgoFactory并将其传递给BRepMesh_Context::SetFaceDiscret()来提供网格划分算法。OCCT 带有两种基本的 2D 网格划分算法:BRepMesh_MeshAlgoFactory(默认使用)和BRepMesh_DelabellaMeshAlgoFactory

以下示例演示了如何在Draw环境中完成此操作:

球体 10
### 默认的东西###
incmesh s 0.0001 -算法默认值
### 德拉贝拉算法###
incmesh s 0.0001 -algo delabella

下面的代码片段显示了将自定义网格工厂传递给BRepMesh_IncrementalMesh

aContext->SetFaceDiscret (new BRepMesh_FaceDiscret (new BRepMesh_DelabellaMeshAlgoFactory()));
aMesher.SetShape (aShape);
aMesher.ChangeParameters() = aMeshParams;
aMesher.Perform (aContext);

范围分配器

范围拆分器工具提供了生成在使用离散模型数据计算的范围内定义的内部表面节点的功能。基本功能由BRepMesh_DefaultRangeSplitter提供,在平面表面的情况下无需修改即可使用。默认拆分器不生成任何内部节点。

BRepMesh_ConeRangeSplitter BRepMesh_CylinderRangeSplitterBRepMesh_SphereRangeSplitter是默认拆分器的特化,旨在为相应类型的分析表面快速生成内部节点。

BRepMesh_UVParamRangeSplitter实现基本功能,将面边界的离散点考虑在内以生成节点。它的后继BRepMesh_TorusRangeSplitterBRepMesh_NURBSRangeSplitter 相应地扩展了环形和 NURBS 曲面的基本功能。

后处理离散模型

这个阶段实现了面网格化后要执行的动作。根据目标目标,它可以更改或省略。默认情况下,BRepMesh_ModelPostProcessor将存储在数据模型中的多边形数据提交到TopoDS_Edge

© 版权声明
THE END
喜欢就支持一下吧
点赞8548 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容