OpenCasCade官方开发文档翻译(6)–occt形状修复

概述

介绍

本手册解释了如何使用形状修复。它提供了有关其操作的基本文档。有关形状修复及其应用的高级信息,请参阅我们的电子学习和培训产品。

形状修复工具包提供了一组工具来处理开放级联技术 ( OCCT ) 形状的几何形状和拓扑结构。形状修复调整形状,以使它们尽可能适合 Open CASCADE 技术使用。

使用示例

以下是一些典型问题的示例,并说明了 Shape Healing 如何处理这些问题:

  • 缺少接缝边缘的面
    • 问题:周期性表面上的表面受到绕表面完整行程的导线的限制。这些线在 3d 中闭合,但在曲面的参数空间中不闭合。这在 Open CASCADE 中无效。
    • 解决方案: Shape Healing 通过插入接缝边缘来修复这个面,该接缝边缘结合了两条明线,从而关闭了参数空间。请注意,内部线处理正确。
  • 线方向错误
    • 问题:面上的线方向不正确,导致面的内部和外部混合在一起。
    • 解决方案: Shape Healing 恢复正确的线方向。
  • 自相交线
    • 问题:面无效,因为它的边界线具有自相交(在两个相邻边上)。
    • 解决方案:形状修复在交叉点切割相交边缘,从而使边界有效。
  • 缺乏优势
    • 问题:线材的两个边缘之间有间隙,使线材没有闭合。
    • 解决方案: Shape Healing 通过插入缺少的边缘来填补间隙。

工具包结构

Shape Healing目前包括几个包,旨在帮助您:

  • 分析形状特征,特别是识别不符合 Open CASCADE 技术有效性规则的形状;
  • 修复形状可能存在的一些问题;
  • 升级用户需求的形状特征,例如可以升级C0支撑面,使其成为C1连续。

下图显示了 API 包的依赖关系:

图片[1]-OpenCasCade官方开发文档翻译(6)–occt形状修复-卡核形状修复包

每个子域都有自己的功能范围:

  • 分析——探索形状属性、计算形状特征、检测违反 OCCT 要求(形状本身未修改);
  • 固定 – 固定形状以满足 OCCT 要求(形状可能会改变其原始形式:修改、删除、构建子形状等);
  • 升级 – 形状改进,以便在 Open CASCADE 技术或其他算法中获得更好的可用性(形状被替换为新的,但在几何上它们是相同的);
  • 定制 – 修改形状表示以适应特定需求(不修改形状,仅修改其表示的形式);
  • 处理——通过用户可编辑的资源文件管理形状修改的机制。

消息管理用于创建消息,用各种参数填充它们并将它们存储在跟踪文件中。该工具提供了将消息附加到形状以延迟分析各种运行时事件的功能。在本文档中,将仅描述使用形状修复的一般原则。有关更多详细信息,请参阅相应的头文件。

负责分析、修复和升级形状的工具可以提供有关如何执行这些操作的信息。用户可以借助状态查询机制获得这些信息。

查询状态

每个修复和升级工具都有自己的状态,在调用它们的方法时会重置。状态可以包含几个标志,这些标志提供有关如何执行方法的信息。为了探索状态,提供了一组名为StatusXXX()的方法(ShapeFix_Wire::StatusReorder()例如)。这些方法接受枚举ShapeExtend_Status并在状态设置了相应的标志时返回 True。每种方法的标志的含义如下所述。

状态可能包含一组布尔标志(内部由位表示)。标志由枚举 ShapeExtend_Status 编码。此枚举提供以下状态系列:

  • ShapeExtend_OK – 情况正常,无需任何操作且尚未执行。
  • ShapeExtend_DONE – 操作已成功执行。
  • ShapeExtend_FAIL – 操作期间发生错误。

可以使用类提供的 StatusXXX() 方法来测试是否存在某些标志的状态:

if (object.StatusXXX (ShapeExtend_DONE))
{
// something was done
}

定义了 8 个“DONE”和 8 个“FAIL”标志,命名为 ShapeExtend_DONE1 … ShapeExtend_FAIL8,用于对遇到的情况进行详细分析。每个方法都为每个标志分配了自己的含义,记录在该方法的标题中。还有三个枚举值用于一次测试多个标志:

  • ShapeExtend_OK – 如果没有设置标志;
  • ShapeExtend_DONE – 如果至少设置了一个 ShapeExtend_DONEi;
  • ShapeExtend_FAIL – 如果至少设置了一个 ShapeExtend_FAILi。

修理

修复有问题(违反 OCCT 要求)形状的算法放置在包ShapeFix中。

ShapeFix包的每一类都处理一种特定类型的形状或一些问题。

在使用ShapeFix之前,您无需检测问题,因为ShapeFix包的所有组件在使用 ShapeAnalysis 包的相应工具修复它们之前对存在的问题进行分析,然后修复发现的问题。

ShapeFix包当前包含以下功能:

  • 添加缺少一条的 2D 曲线或 3D 曲线,
  • 当超过给定的公差值时,纠正 2D 曲线与 3D 曲线的偏差,
  • 将形状的公差值限制在给定范围内,
  • 为形状设置给定的公差值,
  • 修复导线相邻边缘之间的连接,
  • 正确的自相交线,
  • 添加接缝边缘,
  • 纠正 3D 和 2D 曲线之间的间隙,
  • 合并和删除小边缘,
  • 壳和实体的正确方向。

基本形状修复

固定形状的最简单方法是在具有默认参数的整个形状上使用类ShapeFix_ShapeShapeFix_Wireframe 。这些工具的组合可以解决形状可能存在的大多数问题。动作顺序如下:

  1. 创建工具ShapeFix_Shape并按形状对其进行初始化:
    处理( ShapeFix_Shape ) aFixShape = new ShapeFix_Shape ();
    aFixShape->Init (theShape);
  2. 设置基本精度、最大允许公差、最小允许公差:
    aFixShape->SetPrecision (thePrec);
    aFixShape->SetMaxTolerance (theMaxTol);
    aFixShape->SetMinTolerance (theMintol);

    在哪里:

    • thePrec——基本精度。
    • theMaxTol – 最大允许公差。当无效维度大于基本精度或检测到该问题的子形状公差时,将检测所有问题。最大容差值限制了修复问题的增加容差,例如修复未连接和自相交的线。如果需要一个大于最大允许容差的值来纠正检测到的问题,则无法修复该问题。在ShapeFix_SameParameter()方法和ShapeFix_Edge::FixVertexTolerance()方法中计算边的公差时没有考虑最大公差。有关详细信息,请参阅边缘修复工具
    • theMintol – 最小允许公差。它定义了允许的最小边长度。如果线修复工具中的ModifyTopologyMode设置为 true,则将删除长度小于指定最小公差的检测到的边。有关详细信息,请参阅线修理工具
  3. 启动修复:
    aFixShape->Perform();
  4. 得到结果:
    TopoDS_Shape aResult = aFixShape->Shape();

    在某些情况下,仅使用ShapeFix_Shape可能是不够的。可以使用工具来合并和移除小边以及修复 2D 和 3D 曲线之间的间隙。

  5. 创建ShapeFix_Wireframe工具并按形状对其进行初始化:
    处理( ShapeFix_Wireframe ) aFixWire = new ShapeFix_Wireframe (theShape);

    或者:

    aFixWire->Load (theShape);
  6. 设置基本精度和最大允许公差:
    aFixWire->SetPrecision (thePrec);
    aFixWire->SetMaxTolerance (theMaxTol);

    请参阅上面对 thePrectheMaxTol的描述。

  7. 合并和删除小边:
    aFixWire->DropSmallEdgesMode() = true ;
    aFixWire->FixSmallEdges();

    注意:默认模式下不会删除小边,但在许多情况下,删除小边对于固定形状非常有用。

  8. 修复 2D 和 3D 曲线的间隙
    aFixWire->FixWireGaps();
  9. 得到结果
    TopoDS_Shape aResult = aFixWire->Shape();

形状校正

如果您不想对整个形状进行修复或进行一组确定的修复,您可以为单独的修复情况设置标志(将它们标记为 ON 或 OFF),您还可以使用类来修复特定类型的子形状,例如实体、壳、面、线等。

对于每种类型的子形状,都有特定类型的固定工具,例如ShapeFix_SolidShapeFix_ShellShapeFix_FaceShapeFix_Wire

固定子形状

如果您想修复某个形状的一个子形状,可以采取以下步骤:

  • 为指定的子形状类型创建一个工具,并通过子形状初始化该工具;
  • 创建一个用于重建形状的工具并通过整个形状对其进行初始化(第 5.1 节);
  • 在子形状固定工具中设置形状重建工具;
  • 修复子形状;
  • 得到包含一个新的校正子形状的整个形状。

例如,通过以下方式可以修复形状 theShape1 的theFace1

// 创建修复面的工具
Handle( ShapeFix_Face ) aFixFace = new ShapeFix_Face ();
// 创建用于重建形状的工具并按形状对其进行初始化
Handle( ShapeBuild_ReShape ) aReshapeContext = new ShapeBuild_ReShape ();
aReshapeContext->Apply (theShape1);
// 在修复工具中设置重建形状的工具
aFixFace->SetContext (aReshapeContext);
// 用面初始化修复工具
aFixFace->Init (theFace1);
// 修复设置的面
aFixFace->Perform();
// 得到结果;生成的形状包含固定面
TopoDS_Shape aNewShape = aReshapeContext->Apply (theShape1);

借助负责分析形状有效性的工具(第 3.2 节),可以获得一组所需的修复和无效的子形状。

维修工具

每一类ShapeFix包都处理一种特定类型的形状或一系列问题。每个修复工具都借助包含一组最佳修复的Perform()方法对指定的形状及其子形状进行修复。可以在一组控制标志的帮助下管理 Perform 方法中这些修复的执行(修复可以是强制的或禁止的)。

一般工作流程

应应用以下操作序列来执行修复:

  1. 创建一个工具。
  2. 设置以下值:
    • 方法SetPrecision()的工作精度(默认 1.e-7);
    • 通过方法SetMaxTolerance()设置最大允许公差(默认等于工作精度);
    • 通过SetMinTolerance()方法设置最小公差(默认等于工作精度);
    • 通过方法SetContext()设置用于在修改后重建形状的工具(工具ShapeBuild_ReShape ) ;对于单独的面、线和边线,此工具是可选设置的;
    • 要强制或禁止某些修复,请将相应的标志设置为 0 或 1。
  3. 在方法的帮助下按形状初始化工具Init()Load()
  4. 使用方法Perform()或创建一组自定义修复。
  5. 通过通用方法Status或专用方法Status_(例如StatusSelfIntersection ( ShapeExtentd_DONE ))检查修复的状态。请参阅下面的状态描述。
  6. 通过两种方式获取结果:
    • 借助特殊方法Shape(), Face(), Wire(), Edge()
    • 通过方法Apply()从重建工具(访问重建工具使用方法Context()):
      TopoDS_Shape aResultShape = aFixTool->Context()->Apply (theInitialShape);

形状及其子形状的修改历史可以从形状重建工具 ( ShapeBuild_ReShape ) 中获得。

TopoDS_Shape aModifSubshape = aFixTool->Context()->Apply (theInitSubShape);

标志管理

标志Fix…Mode()用于控制来自 API 修复方法的修复过程的执行。默认情况下,这些标志的值等于 -1,这意味着相应的过程将被调用或不被调用,具体取决于情况。如果该标志设置为 1,则无论如何都会执行该过程;如果标志为 0,则不执行该过程。标志的名称对应于受控的修复过程。对于每个修复工具,都有自己的一组标志。要将标志设置为所需的值,请获取包含此标志的工具并将标志设置为所需的值。

例如,可以禁止执行修复以删除小边缘 – FixSmall

Handle( ShapeFix_Shape ) aFixShape = new ShapeFix_Shape (theShape);
aFixShape->FixWireTool()->FixSmallMode() = 0;
if (aFixShape->Perform())
{
TopoDS_Shape aResShape = aFixShape->Shape();
}

形状修复工具

ShapeFix_Shape允许对形状的所有子形状使用修复工具。它提供对所有修复工具的访问,以修复指定形状的子形状以及来自这些工具的所有控制标志。

例如,可以强制从面上移除无效的 2D 曲线:

TopoDS_Face theFace = …; // 面对无效的 2D 曲线。
// 创建工具并按形状初始化
处理( ShapeFix_Shape ) aFixShape = new ShapeFix_Shape (theFace);
// 设置工作精度和最大允许公差
aFixShape->SetPrecision (thePrec);
aFixShape->SetMaxTolerance (theMaxTol);
//设置flag的值以强制移除2D曲线
aFixShape->FixWireTool()->FixRemovePCurveMode() = 1;
// 改革修复
aFixShape->Perform();
// 得到结果
if (aFixShape->Status (ShapeExtend_DONE))
{
std::cout << “形状已修复\n” ;
TopoDS_Shape aResFace = aFixShape->Shape();
}
else if (aFixShape->Status (ShapeExtend_FAIL))
{
std::cout << “形状无法修复\n” ;
}
else if (aFixShape->Status (ShapeExtent_OK))
{
std::cout << “初始面在指定精度下有效 =” << thePrec << std::endl;
}

实体修复工具

ShapeFix_Solid允许固定实体并从壳构建实体以获得具有有限体积的有效实体。工具ShapeFix_Shell用于修正属于实体的壳。

此工具具有以下控制标志:

  • FixShellMode – 应用ShapeFix_Shell修复的模式,默认为 True。
  • CreateOpenShellMode – 如果等于 true,则从开放壳创建实体,否则仅从封闭壳创建实体,默认为 False。

壳修复工具

ShapeFix_Shell类允许修复壳中面的错误方向。它改变壳中面的方向,使壳中的所有面具有一致的方向。如果不可能定向壳中的所有面(例如在莫比乌斯带的情况下),则将根据指定的非流形模式创建一些流形或非流形壳。ShapeFix_Face工具用于校正外壳中的面此工具具有以下控制标志:

  • FixFaceMode – 应用ShapeFix_Face修复的模式,默认为True
  • FixOrientationMode – 对外壳中的面方向应用修复的模式。

面修复工具

ShapeFix_Face允许修复与面线相关的问题。它允许控制面的创建(添加线),并通过工具ShapeFix_Wire固定线。将线添加到面时,可以对其重新排序并且可以修复退化的边缘。这取决于用户定义的标志(默认情况下,False)是否执行。可以使用以下修复程序:

  • 固定在面上的线方向。如果面没有线,则计算自然边界。如果该面位于球面上并且上面有两条或更多条线描述孔,则添加自然边界。在单根线的情况下,它被制成外部线。如果面有几根线,它们的方向是一个在另一个外面(如果可能的话)。如果支撑表面是周期性的,则内部导线的 2D 曲线可以在整数个周期上移动,以将它们放在外部导线内部。
  • 修复闭合曲面上的面由一组闭合线定义且缺少接缝的情况(这在 OCCT 中无效)。在这种情况下,这些线通过接缝边缘连接到同一根线中。

此工具具有以下控制标志:

  • FixWireMode – 应用线修复的模式,默认为 True。
  • FixOrientationMode – 将导线定向到有限正方形边界的模式,默认为 True。
  • FixAddNaturalBoundMode – 向面添加自然边界的模式,默认为 False。
  • FixMissingSeamMode – 修复缺失接缝的模式,默认为 True。如果为 True,则尝试插入接缝。
  • FixSmallAreaWireMode – 修复小面积导线的模式,默认为 False。如果为 True,则丢弃限制小区域的线。
TopoDS_Face theFace = …;
TopoDS_Wire theWire = …;
// 创建一个工具并在面上添加一条线
ShapeFix_Face aFixShape (theFace);
aFixShape.Add (theWire);
// 使用方法 Perform 固定线和面
aFixShape.Perform();
// 或者单独修复面上线的方向
aFixShape.FixOrientation();
// 获取结果面
TopoDS_Face aNewFace = aFixShape.Face();

线修理工具

ShapeFix_Wire类允许固定线。除了几何填充间隙,它的方法Perform()执行所有可用的修复。可以借助用于固定形状ShapeFix_Wireframe的线框的工具来进行间隙的几何填充。

Perform()的修复顺序和默认行为如下:

  • 线中的边由FixReorder重新排序。大多数修复方法都希望线中的边缘是有序的,因此有必要在进行任何其他修复之前调用FixReorder() 。就算禁止了,也不管线是否有序的分析。
  • 小边被FixSmall移除。
  • 导线中的边缘通过FixConnected(如果已订购导线)连接(拓扑)。
  • 边缘(3D 曲线和 2D 曲线)由FixEdgeCurves固定(如果未订购线材,则不使用FixShifted)。
  • 退化边缘由FixDegenerated添加(如果订购了线)。
  • 自相交由FixSelfIntersection固定(如果线是有序的并且ClosedMode为 True)。
  • 缺少的边缘由FixLacking固定(如果订购了线)。

标志ClosedWireMode指定线是否(或应该)闭合。如果该标志为 True(默认情况下),则还针对最后一条边和第一条边执行需要或强制连接边的修复。

可以使用相应的控制标志打开/关闭修复方法:

  • FixReorderMode,
  • 修复小模式,
  • 固定连接模式,
  • FixEdgeCurvesMode,
  • 修复退化模式,
  • FixSelfIntersectionMode

可以通过三种方式进行一些修复:

  • 增加边或顶点的容差。
  • 更改拓扑(添加/删除/替换线中的边和/或替换边中的顶点、复制边等)。
  • 更改几何体(移动顶点或将边缘曲线的末端调整为顶点,或重新计算边缘的 3D 曲线或 2D 曲线)。

如果可以通过多种方式进行修复(例如,通过增加容差或移动顶点),则根据用户定义的标志进行选择:

  • ModifyTopologyMode – 允许修改拓扑。默认为假。
  • ModifyGeometryMode – 允许修改几何。现在此标志仅用于修复自相交边(允许修改 2D 曲线),默认为 True。

修复无序边缘

FixReorder对于大多数其他修复是必需的(但对于 Open CASCADE 技术不是必需的)。它检查导线中的边是否按顺序排列(前边的结束是下边的开始)。如果不是这样,则尝试重新排序边缘。

修复小边缘

FixSmall方法搜索长度小于给定值的边(退化的边被忽略)。如果找到这样的边缘,则只要满足以下条件之一,就将其删除:

  • 该边的两个端点都是同一个顶点,
  • 边的端点不同,但标志ModifyTopologyMode为 True;在后一种情况下,FixConnected方法应用于前面和后面的边以确保它们的连接。

修复断开的边缘

FixConnected方法强制两条相邻边共享相同的公共顶点(如果它们没有公共顶点)。它以给定的精度检查前边的结束顶点是否与后边的起始顶点重合,然后创建一个新顶点并将其设置为固定边的公共顶点。此时,边被复制,因此线拓扑被更改(无论ModifyTopologyMode标志如何)。如果顶点不重合,则此方法失败。

修复边曲线的一致性

FixEdgeCurves方法执行一组修复处理线中边缘的 3D 曲线和 2D 曲线。

这些修复将在名为ShapeFix_Edge的边缘修复工具中的一组修复的帮助下激活。通过将相应的标志设置为 True 或 False,可以强制或禁止这些修复中的每一个。

提到的修复及其执行条件是:

  • 通过调用ShapeFix_Edge::FixReversed2d来修复迷失方向的 2D 曲线——如果没有被标志FixReversed2dMode禁止;
  • 通过调用ShapeFix_Edge::FixRemovePCurve删除错误的 2D 曲线——仅当由标志FixRemovePCurveMode强制时;
  • 通过调用ShapeFix_Edge::FixAddPCurve来修复丢失的 2D 曲线——如果没有被标记FixAddPCurveMode禁止;
  • 通过调用ShapeFix_Edge::FixRemoveCurve3d删除错误的 3D 曲线——仅当由标志FixRemoveCurve3dMode强制时;
  • 通过调用ShapeFix_Edge::FixAddCurve3d来修复丢失的 3D 曲线——如果没有被标志FixAddCurve3dMode禁止;
  • 修复接缝边缘的 2D 曲线——如果没有被标志FixSeamMode禁止;
  • 通过调用ShapeFix_Edge::FixShifted 修复可以在闭合曲面上以整数周期移动的 2D 曲线——如果没有被标志FixShiftedMode禁止的话。

如果位于闭合曲面上的导线中某些边的 2D 曲线是从 3D 曲线重新计算的,则需要此修复。在这种情况下,沿曲面接缝行进的边缘的 2D 曲线可能会以整数个周期错误地移动。FixShifted方法检测到这种情况并将错误的 2D 曲线向后移动,确保导线中边缘的 2D 曲线是连接的。

修复退化的边缘

FixDegenerated方法检查导线中的边缘是否位于支撑表面的退化点上,或者边缘之间是否存在退化点。如果对任何边检测到其中一种情况,则会创建一个新的退化边,并在第一种情况下替换当前边,或者在第二种情况下将其添加到导线中。新创建的退化边有一条直线 2D 曲线,它从前边的 2D 曲线的末端到下一条边的起点。

固定边的 2D 曲线的交点

FixSelfIntersection方法检测并修复以下问题:

  • 各个边的 2D 曲线的自相交。如果标志ModifyGeometryMode()为 False,则将通过将端顶点之一的容差增加到小于MaxTolerance()的值来执行此修复。
  • 两条相邻边中每条边的 2D 曲线的交点(如果标志 ClosedWireMode 为 False,则第一条和最后一条边除外)。如果找到这样的交点,则修改公共顶点以包含交点。如果标志ModifyTopologyMode为 False,则将通过将顶点的容差增加到小于MaxTolerance()的值来执行此修复。
  • 非相邻边的二维曲线的交点。如果找到这样的交点,则增加最近顶点的容差以包含交点。如果无法使用小于MaxTolerance的容差进行此类增加,则不会执行此修复。

修复缺乏的边缘

FixLacking方法检查线是否在曲面的参数空间中没有闭合(虽然它可以在 3D 中闭合)。这是通过检查导线中两条相邻边中每条边的 2D 曲线之间的间隙是否小于相应顶点的公差来完成的。该算法计算边缘之间的间隙,分析这些边缘末端的位置关系,并(如果可能)尝试将新边缘插入间隙或增加公差。

通过几何填充修复 2D 和 3D 线中的间隙

以下方法检查相邻边的 2D 或 3D 曲线末端之间的间隙:

  • 方法FixGap2d将 2D 曲线的末端移动到中点。
  • 方法FixGaps3d将 3D 曲线的末端移动到一个公共顶点。

布尔标志FixGapsByRanges用于激活在转换为 B 样条线之前应用的附加模式。当此模式打开时,方法会尝试找到最精确的曲线交点,或目标点的最精确投影,或两条曲线之间的端点(以相应地修改它们的参数范围)。此模式默认关闭。独立于上述附加模式,如果存在间隙,这些方法将曲线转换为 B 样条形式,并在检测到间隙时移动其末端。

示例:一组自定义修复

让我们以创建一组自定义修复为例:

TopoDS_Face theFace = …;
TopoDS_Wire theWire = …;
Standard_Real aPrecision = 1e-04;
ShapeFix_Wire aFixWire (theWire, theFace, aPrecision);
// 创建一个工具并将对象加载到其中
aFixWire.FixReorder();
// 对连线中的边进行排序,以便每条边都从其前一条的末尾开始
aFixWire.FixConnected();
// 强制所有相邻边共享同一个顶点
bool toLockVertex = true ;
if (aFixWire.FixSmall (toLockVertex, aPrecision))
{
// 移除所有比给定精度短且两端顶点相同的边
}
if (aFixWire.FixSelfIntersection())
{
// 固定自相交边和相交相邻边
std::cout << “线有点自相交。已修复\n” ;
}
if (aFixWire.FixLacking (false))
{
// 插入边以连接相邻的非连续边
}
TopoDS_Wire aNewWire = aFixWire.Wire();
//返回正确的线

示例:校正线

让我们更正以下线路:

图片[2]-OpenCasCade官方开发文档翻译(6)–occt形状修复-卡核

初始形状

有必要使用分析线有效性的工具来检查:

  • 边缘方向正确;
  • 没有太短的边;
  • 没有相交的相邻边;然后立即应用固定工具。
TopoDS_Face theFace = …;
TopoDS_Wire theWire = …;
Standard_Real aPrecision = 1e-04;
ShapeAnalysis_Wire aCheckWire(theWire, theFace, aPrecision);
ShapeFix_Wire aFixWire (theWire, theFace, aPrecision);
if (aCheckWire.CheckOrder())
{
std::cout << “线路中的某些边需要重新排序\n” ;
// 两条边的方向不正确
aFixWire.FixReorder();
std::cout << “重新排序完成\n” ;
}
// 他们的方向被纠正了
if (aCheckWire.CheckSmall (aPrecision))
{
std::cout << “连线包含的边短于 “ << aPrecision << std::endl;
// 找到比给定容差短的边
if (aFixWire.FixSmall (LockVertex, aPrecision))
{
std::cout << “比 “ << aPrecision << ” 短的边已被删除\n” ;
// 边缘被移除
}
}
if (aCheckWire.CheckSelfIntersection())
{
std::cout << “线有自相交或相交的相邻边\n” ;
// 找到两条相交的相邻边
if (aFixWire.FixSelfIntersection())
{
std::cout << “线有点自相交。已修复\n” ;
// 在交点处切割边缘,使它们不再相交。
}
}

结果,所有故障都已修复。

图片[3]-OpenCasCade官方开发文档翻译(6)–occt形状修复-卡核

结果形状

修边工具

ShapeFix_Edge类提供了修复无效边缘的工具。检测并修复以下几何和/或拓扑不一致:

  • 缺少 3D 曲线或 2D 曲线,
  • 3D 曲线和 2D 曲线的方向不匹配,
  • 不正确的 SameParameter 标志(曲线偏差大于边缘公差)。

每个修复方法首先使用ShapeAnalysis_Edge类的方法检查问题是否存在。如果未检测到问题,则不执行任何操作。该工具没有Perform()方法。

要了解此工具的工作原理,可以采用边缘,其中 3D 曲线和 2D 曲线 P1 之间的最大偏差大于边缘公差。

图片[4]-OpenCasCade官方开发文档翻译(6)–occt形状修复-卡核

初始形状

首先需要应用边缘有效性检查工具来发现 pcurve 和 3D 曲线之间的最大偏差大于公差。然后我们可以使用修复工具来增加公差并使偏差可以接受。

TopoDS_Edge theEdge = …;
ShapeAnalysis_Edge aCheckEdge;
Standard_Real aMaxDev = 0.0;
if (aCheckEdge.CheckSameParameter ( theEdge, aMaxDev))
{
std::cout << “不正确的 SameParameter 标志\n”
<< “最大偏差” << aMaxDev << “, 容差” << BRep_Tool::Tolerance (theEdge) << std::endl;
ShapeFix_Edge aFixEdge;
aFixEdge.FixSameParameter ();
std::cout << “新公差” << BRep_Tool::Tolerance (theEdge) << std::endl;
}
图片[5]-OpenCasCade官方开发文档翻译(6)–occt形状修复-卡核

结果形状

结果,边缘公差增加了。

形状线框的修复工具

ShapeFix_Wireframe提供了几何固定间隙和合并形状中的小边缘的方法。此类执行以下操作:

  • 填充形状的 2D 和 3D 线框中的空白。
  • 合并和删除小边缘。

可以借助两个标志来管理小边缘的修复:

  • ModeDropSmallEdges() – 移除无法合并的小边的模式,默认等于 Standard_False。
  • LimitAngle – 合并两条相邻边的最大可能角度,默认情况下不应用限制角度 (-1)。

要执行修复,有必要:

  • 创建一个工具并按形状对其进行初始化,
  • 设置将检测到的工作精度问题和最大允许公差
  • 执行修复
// 创建一个工具
处理( ShapeFix_Wireframe ) aFixWireframe = new ShapeFix_Wireframe (theShape);
// 设置将检测到的工作精度问题和最大允许公差
aFixWireframe->SetPrecision (thePrec);
aFixWireframe->SetMaxTolerance (theMaxTol);
// 修复间隙
aFixWireframe->FixWireGaps();
// 固定小边
// 设置放置模式以固定小边缘和合并边缘之间的最大可能角度
aFixWireframe->ModeDropSmallEdges = true ;
aFixWireframe->SetLimliteAngle(theAngle);
// 执行修复
aFixWireframe->FixSmallEdges();
// 得到结果
TopoDS_Shape aResShape = aFixWireframe->Shape();

在应用此类的方法之前,希望形状在拓扑上是正确的。

从形状中删除小面的工具

类 ShapeFix_FixSmallFace 此工具用于从形状中删除小面。处理以下情况:

  • 斑点面:如果面的大小小于给定的精度;
  • 剥离面:如果面的一维尺寸小于给定精度。

执行修复的操作顺序与上述修复相同:

// 创建一个工具
处理( ShapeFix_FixSmallFace ) aFixSmallFace = new ShapeFix_FixSmallFace (theShape);
// 设置公差
aFixSmallFace->SetPrecision (thePrec);
aFixSmallFace->SetMaxTolerance (theMaxTol);
// 执行修复
aFixSmallFace.Perform();
// 得到结果
TopoDS_Shape aResShape = aFixSmallFace.FixShape();

修改形状公差的工具(类 ShapeFix_ShapeTolerance)

该工具提供了设置形状及其子形状公差的功能。在 Open CASCADE 技术中,只有顶点、边和面有公差。

该工具允许一次处理每种具体类型的子形状或所有类型。您可以按如下方式设置容差功能:

  • 通过方法 SetTolerance 设置子形状的公差,
  • 通过方法 LimitTolerance 限制给定范围的公差。
// 创建一个工具
// 设置形状及其所有子形状的指定容差
aFixToler.SetTolerance (theShape, theToler);
// 仅为顶点设置指定的容差
aFixToler.SetTolerance (theShape, theToler, TopAbs_VERTEX);
// 将形状及其子形状的公差限制在最小和最大公差之间
aFixToler.LimitTolerance (theShape, theTolerMin, theTolerMax);

分析

形状效度分析

ShapeAnalysis包提供了用于分析拓扑形状的工具。在执行修复工具之前不需要通过这些工具检查形状,因为这些工具用于在修复工具内部执行修复之前进行分析。但是,如果您愿意,这些工具可用于独立于修复工具检测一些形状问题。

可以通过以下方式完成:

  • 创建分析工具;
  • 通过形状初始化它并设置一个公差问题,如果有必要,将被检测到;
  • 检查您感兴趣的问题。
TopoDS_Face theFace = …;
// 创建一个分析边缘的工具
ShapeAnalysis_Edge aCheckEdge;
for ( TopExp_Explorer anExp (theFace, TopAbs_EDGE); anExp.More ( ); anExp.Next())
{
TopoDS_Edge anEdge = TopoDS::Edge (anExp.Current());
if (!aCheckEdge.HasCurve3d ( anEdge))
{
std::cout << “边缘没有 3D 曲线\n” ;
}
}

面上线的方向分析

可以借助ShapeAnalysis::IsOuterBound方法检查面是否有外边界。

TopoDS_Face theFace = …; // 分析面
{
std::cout << “面没有外边界\n” ;
}

线有效性分析

ShapeAnalysis_Wire类用于分析线。它提供了探索线特性和检查其是否符合 Open CASCADE 技术要求的功能。这些功能包括:

  • 检查线中边缘的顺序,
  • 检查是否存在小边(长度小于给定值),
  • 检查是否存在断开的边(具有不同顶点的相邻边),
  • 检查边缘曲线的一致性,
  • 检查退化边缘的存在或缺失,
  • 检查是否存在自相交边和相交边(边相交被理解为它们的二维曲线的相交),
  • 检查缺少的边缘以填充表面参数空间中的间隙,
  • 分析导线方向(以定义面上的外部或内部边界),
  • 分析添加到现有线的形状(边缘或线)的方向。

请注意,除第一个检查操作外,所有检查操作均基于导线中的边是有序的假设。因此,如果检测到线未排序,则有必要在调用其他检查操作之前对其进行排序。例如,这可以在ShapeFix_Wire::FixOrder()方法的帮助下完成。

此工具应使用线、面(或具有位置的表面)或精度进行初始化。一旦工具被初始化,就可以执行必要的检查操作。为了一次获取线上的所有信息,提供了全局方法Perform。它调用所有其他 API 检查操作来检查每个单独的案例。

API 方法仅检查相应的案例,可以分析它们返回的值和状态,以了解是否检测到案例。

这个类中的一些方法是:

  • CheckOrder检查导线中的边是否顺序正确;
  • CheckConnected检查边是否断开;
  • CheckSmall检查是否存在比给定值短的边;
  • CheckSelfIntersection检查是否存在自相交或相邻相交边。如果由于不相邻的边缘而发生交叉,则不会检测到它。

这个类维护状态管理。每个 API 方法都存储了其最后一次执行的状态,可以通过相应的Status..()方法进行查询。此外,每个 API 方法都会返回一个布尔值,当检测到正在分析的案例时(具有设置的ShapeExtend_DONE状态)为 True,否则为 False。

TopoDS_Face theFace = …;
TopoDS_Wire theWire = …;
Standard_Real aPrecision = 1e-04;
ShapeAnalysis_Wire aCheckWire(theWire, theFace, aPrecision);
// 创建一个工具并将对象加载到其中
if (aCheckWire.CheckOrder())
{
std::cout << “线路中的某些边需要重新排序\n”
<< “在进一步分析之前,请确保所有的边都正确排序\n” ;
返回
}
if (aCheckWire.CheckSmall (aPrecision))
{
std::cout << “连线包含的边短于 “ << aPrecision << std::endl;
}
if (aCheckWire.CheckConnected())
{
std::cout << “线断开\n” ;
}
if (aCheckWire.CheckSelfIntersection())
{
std::cout << “导线有自相交或相交的相邻边\n” ;
}

边缘效度分析

ShapeAnalysis_Edge旨在分析边缘。它提供以下功能来使用边缘:

  • 查询几何表示(给定面或曲面上的 3D 曲线和 pcurve),
  • 查询拓扑子形状(边界顶点),
  • 检查重叠边缘,
  • 分析曲线一致性:
    • 3D 曲线和 2D 曲线的相互方向(同向或相反方向),
    • 3D 和 2D 曲线与顶点的对应关系。

此类支持上述状态管理。

TopoDS_Face theFace = …;
// 创建一个分析边缘的工具
ShapeAnalysis_Edge aCheckEdge;
for ( TopExp_Explorer anExp (theFace, TopAbs_EDGE); anExp.More ( ); anExp.Next())
{
TopoDS_Edge anEdge = TopoDS::Edge (anExp.Current());
if (!aCheckEdge.HasCurve3d ( anEdge))
{
std::cout << “边缘没有 3D 曲线\n” ;
}
处理( Geom2d_Curve ) aPCurve;
Standard_Real aPFirst = 0.0,aPLast = 0.0;
if (aCheckEdge.PCurve ( anEdge, theFace, aPCurve, aPFirst, aPLast, Standard_False))
{
// 在给定的面上打印 pcurve 及其范围
std::cout << “Pcurve 范围 [“ << aPFirst << “, “ << aPLast << “]\n” ;
}
Standard_Real aMaxDev = 0.0;
if (aCheckEdge.CheckSameParameter ( anEdge, aMaxDev))
{
// 检查边缘中所有曲线的一致性
std::cout << “不正确的 SameParameter 标志\n” ;
}
std::cout << “最大偏差 “ << aMaxDev << “, 容差”
<< BRep_Tool::Tolerance (anEdge) << std::endl;
}
// 检查两条边的重叠
TopoDS_Edge theEdge1 = …;
TopoDS_Edge theEdge2 = …;
Standard_Real theDomainDist = 0.0;
ShapeAnalysis_Edge aCheckEdge;
Standard_Real aTolOverlap = 0.0;
if (aCheckEdge.CheckOverlapping ( theEdge1, theEdge2, aTolOverlap, theDomainDist))
{
std::cout << “边与公差重叠 = “ << aTolOverlap << std::endl;
std::cout << “重叠域=” << theDomainDist << std::endl;
}

小面的存在分析

ShapeAnalysis_CheckSmallFace类旨在使用以下方法从形状中分析小面:

  • CheckSpotFace()检查面的大小是否小于给定的精度;
  • CheckStripFace检查一维中面的大小是否小于给定的精度。
TopoDS_Shape theShape = …; // 检查形状
// 创建一个工具
// 探索面上的形状并检查每个面
Standard_Integer aNbSmallfaces = 0;
for ( TopExp_Explorer anExp (theShape, TopAbs_FACE); anExp.More ( ); anExp.Next())
{
TopoDS_Face aFace = TopoDS::Face (anExp.Current());
TopoDS_Edge anEdge1, anEdge2;
if (aCheckSmallFace.CheckSpotFace ( aFace, thePrec)
|| aCheckSmallFace。CheckStripFace (aFace, anEdge1, anEdge2, thePrec))
{
++aNbSmallfaces;
}
}
如果(aNbSmallfaces != 0)
{
std::cout << “形状中的小面数 = “ << aNbSmallfaces << std::endl;
}

壳效度和封闭性分析

ShapeAnalysis_Shell允许检查流形壳中边缘的方向。在这个工具的帮助下,可以找到自由边(边进入一个面)和坏边(边进入壳两次以相同的方向)。通过出现坏边和自由边,可以得出关于壳有效性和壳闭合的结论。

TopoDS_Shell theShell = …; // 检查形状
ShapeAnalysis_Shell aCheckShell (theShell);
// 外壳分析;第二个参数设置为 True 以获得自由边缘
aCheckShell.CheckOrientedShells (theShell, true );
// 获取分析结果
if (aCheckShell.HasBadEdges())
{
std::cout << “Shell 无效\n” ;
TopoDS_Compound badEdges = aCheckShell.BadEdges();
}
if (aCheckShell.HasFreeEdges())
{
std::cout << “Shell 已打开\n” ;
TopoDS_Compound freeEdges = aCheckShell.FreeEdges();
}

形状特性分析

形状公差分析

ShapeAnalysis_ShapeTolerance允许计算形状及其子形状的公差。在 Open CASCADE 技术中,只有顶点、边和面有公差:

该工具允许一次分析每种具体类型的子形状或所有类型。公差功能分析如下:

  • 计算子形状的最小、最大和平均公差,
  • 找到公差超过给定值的子形状,
  • 查找具有给定范围内公差的子形状。
TopoDS_Shape theShape = …;
Standard_Real anAverageOnShape = aCheckToler.Tolerance(theShape,0);
std::cout << “形状的平均公差为 “ << anAverageOnShape << std::endl;
Standard_Real aMinOnEdge = aCheckToler.Tolerance(theShape,-1,TopAbs_EDGE);
std::cout << “边缘的最小公差是 “ << aMinOnEdge << std::endl;
Standard_Real aMaxOnVertex = aCheckToler.Tolerance(theShape,1,TopAbs_VERTEX);
std::cout << “顶点的最大容差为 “ << aMaxOnVertex << std::endl;
Standard_Real theMaxAllowed = 0.1;
if (aMaxOnVertex > theMaxAllowed)
{
std::cout << “顶点的最大容差超过允许的最大值\n” ;
}

自由边界分析

ShapeAnalysis_FreeBounds旨在分析和输出形状的自由边界。自由边界是由形状中的一个面仅引用一次的边组成的线。在分析它们的自由边界时,此类适用于两种不同类型的形状:

  • 考虑到指定的容差,分析可能的自由边界。这种分析可以应用于面的复合。缝合算法的分析器用于预测这些面缝合后将获得哪些自由边界。应使用以下方法进行此分析:
    ShapeAnalysis_FreeBounds aCheckFreeBnd (theShape, theToler);
  • 分析已经存在的自由边界。在这种情况下,输出实际的自由边界(外壳中唯一面共享的边)。ShapeAnalysis_Shell用于此。
    ShapeAnalysis_FreeBounds aCheckFreeBnd (theShape);

当将边连接成线时,此算法尝试构建最大长度的线。为用户提供了两个选项以从闭合和/或开放轮廓中提取闭合子轮廓。自由边界作为两种化合物返回,一种用于封闭线,一种用于开放线。为了获得结果,有必要使用方法:

TopoDS_Compound aClosedWires = aCheckFreeBnd.GetClosedWires();
TopoDS_Compound anOpenWires = aCheckFreeBnd.GetOpenWires();

该类还提供了一些高级使用的静态方法:将边/线连接到线,从线中提取封闭的子线,将线分配到封闭和开放线的复合物中。

TopoDS_Shape theShape = …;
// 缝纫公差
Standard_Real theSewTolerance = 1.e-03;
bool theToSplitClosed = false ;
bool theToSplitOpen = true ;
// 在分析可能的自由边界的情况下
ShapeAnalysis_FreeBounds aCheckFreeBnd (theShape, theSewTolerance, theToSplitClosed, theToSplitOpen);
// 在分析现有自由边界的情况下
ShapeAnalysis_FreeBounds aCheckFreeBnd (theShape, theToSplitClosed, theToSplitOpen);
// 获取结果
TopoDS_Compound aClosedWires = aCheckFreeBnd.GetClosedWires();
// 返回封闭自由边界的复合
TopoDS_Compound anOpenWires = aCheckFreeBnd.GetClosedWires();
// 返回一个开放自由边界的复合

形状内容分析

ShapeAnalysis_ShapeContents提供了计算子形状数量并通过以下标准选择子形状的工具:

获取子形状数量的方法:

  • 实体数,
  • 壳数量,
  • 面数,
  • 边数,
  • 点数。

计算指定类型的几何对象或子形状数量的方法:

  • 自由面的数量,
  • 空闲线的数量,
  • 自由边的数量,
  • C0 表面的数量,
  • C0曲线的数量,
  • BSpline 曲面的数量等。

并根据各种标准选择子形状。

相应的标志应设置为 True 以按指定条件存储形状:

  • 基于间接表面的面 – aCheckContents.MofifyIndi​​rectMode() = Standard_True
  • 基于偏移表面的面 – aCheckContents.ModifyOffsetSurfaceMode() = Standard_True
  • 如果修剪了 3D 曲线,则边缘 – aCheckContents.ModifyTrimmed3dMode() = Standard_True
  • 边缘,如果它们的 3D 曲线和 2D 曲线是偏移曲线 – aCheckContents.ModifyOffsetCurveMode() = Standard_True
  • 如果修剪了 2D 曲线,则边缘 – aCheckContents.ModifyTrimmed2dMode() = Standard_True

例如,让我们根据偏移曲面选择面。

// 根据offsetsurfaces设置一个对应的flag用于存储面
aCheckContents.ModifyOffsetSurfaceMode() = true;
aCheckContents.Perform (theShape);
// 获取形状中偏移曲面的数量
Standard_Integer aNbOffsetSurfaces = aCheckContents。NbOffsetSurf ();
// 根据偏移曲面获取面序列
Handle(TopTools_HSequenceOfShape) aSeqFaces = aCheckContents.OffsetSurfaceSec();

形状下划线几何分析

ShapeAnalysis_CanonicalRecognition提供了分析形状几何和探索将几何转换为规范形式的可能性的工具。曲线的典型形式是直线、圆和椭圆。曲面的规范形式是平面、圆柱、圆锥和球面。

根据最大偏差准则执行识别和转换为规范形式:初始几何对象和规范几何对象之间的最大距离必须小于给定值。

允许对以下形状进行曲线分析:

  • edge – 算法检查边缘的 3d 曲线
  • 线 – 算法检查所有边缘的 3d 曲线,以便将它们转换为相同的解析曲线

允许对以下形状进行表面分析:

  • face – 算法检查表面
  • shell – 算法检查所有面的表面,以便将它们转换为相同的分析表面
  • 边缘 – 算法检查给定边缘共享的所有表面,以便将其中一个转换为最接近输入样本表面的分析表面。
  • 线 – 与边缘相同,但算法检查线的所有边缘以找到最接近输入样本表面的分析表面。

升级

升级工具旨在调整形状以便更好地使用 Open CASCADE 技术或根据特定需求进行定制,即导出到另一个系统。这意味着它不仅可以纠正和升级,还可以改变形状在几何、大小和其他方面的定义。方便的 API 允许您创建自己的工具来执行特定的升级。针对特定情况的附加工具提供了根据特定标准划分形状和表面的能力。

根据指定标准分割形状的工具

概述

当一个拓扑对象可以根据指定的标准划分或转换为多个拓扑对象时,这些工具提供了这样的修改。此外,还有针对特定情况的高级 API 工具:

  • 将形状的几何形状转换为给定的连续性,
  • 将旋转 U 拆分为小于给定值的段,
  • 转换为贝塞尔曲面和贝塞尔曲线,
  • 分割闭合面,
  • 将 C0 BSpline 曲线转换为一系列 C1 BSpline 曲线。

特定情况下的所有工具都基于用于形状分割的通用工具,但它们中的每一个都有自己的工具,用于根据指定的标准分割或转换几何图形。

形状分割的通用工具有:

  • 分割整个形状的工具,
  • 分割面的工具,
  • 用于拆分线的工具。

形状分割工具使用几何分割工具:

  • 用于分割表面的工具,
  • 用于分割 3D 曲线的工具,
  • 用于分割 2D 曲线的工具。

使用可用于形状拆分的工具

如果需要按指定的连续性分割形状,分割形状中的闭合面,按角度分割形状中的旋转曲面或将形状中的所有曲面、所有 3D 曲线、所有 2D 曲线转换为 Bezier,它是可以使用现有/可用的工具。

对于转换 C0 BSpline 曲线的工具,使用这些工具例外的通常方法如下:

  • 按形状创建和初始化工具;
  • 设定分割的工作精度和最大允许公差;
  • 设置分割准则的值(如有必要);
  • 进行拆分;
  • 获得分裂状态;
  • 得到结果;
  • 输出初始形状及其子形状的修改历史(此步骤是可选的)。

例如,让我们分割所有曲面以及所有具有小于 C2 的连续性的 3D 和 2D 曲线:

// 创建一个工具并通过形状对其进行初始化
ShapeUpgrade_ShapeDivideContinuity aShDivCont (theInitShape);
// 设置工作 3D 和 2D 精度和最大允许公差
aShDivCont.SetTolerance (thePrec);
aShDivCont.SetTolerance2D (thePrec2d);
aShDivCont.SetMaxTolerance (theMaxTol);
//设置曲面、3D曲线和2D曲线的标准值
aShDivCont.SetBoundaryCriterion(GeomAbs_C2);
aShDivCont.SetPCurveCriterion(GeomAbs_C2);
aShDivCont.SetSurfaceCriterion(GeomAbs_C2);
// 执行拆分
aShDivCont.Perform();
// 检查状态并获取结果
if (aShDivCont.Status (ShapeExtend_DONE)
{
TopoDS_Shape aResult = aShDivCont.GetResult();
}
// 获取面修改的历史
for ( TopExp_Explorer anExp (theInitShape, TopAbs_FACE); anExp.More ( ); anExp.Next())
{
TopoDS_Shape aModifShape = aShDivCont.GetContext()->Apply (anExp.Current());
}

创建用于分割形状的新工具

要创建新的分割工具,有必要根据所需的标准创建用于几何分割的工具。新工具应该继承自几何分割的基本工具。然后将新工具设置为相应的形状分割工具。

  • 应在面拆分工具中设置新的曲面拆分工具;
  • 用于分割 3D 和 2D 曲线的新工具应设置到线的分割工具中。

要更改形状分割标准的值,需要创建一个新的形状分割工具,该工具应继承于通用形状分割工具。

让我们根据指定的标准分割一个形状。

// 根据指定标准创建用于几何分割的新工具
Handle(MyTools_SplitSurfaceTool) MySplitSurfaceTool = new MyTools_SplitSurfaceTool();
Handle(MyTools_SplitCurve3DTool) MySplitCurve3Dtool = new MyTools_SplitCurve3DTool();
Handle(MyTools_SplitCurve2DTool) MySplitCurve2Dtool = new MyTools_SplitCurve2DTool();
// 创建用于分割形状的工具并按形状初始化该工具
TopoDS_Shape theInitShape = …;
MyTools_ShapeDivideTool aShapeDivide (theInitShape);
// 设置分割的工作精度和最大允许公差
aShapeDivide.SetPrecision (prec);
aShapeDivide.SetMaxTolerance (MaxTol);
// 在形状分割工具中设置新的分割几何工具
Handle( ShapeUpgrade_FaceDivide ) aFaceDivide = aShapeDivide->GetSplitFaceTool();
Handle( ShapeUpgrade_WireDivide ) aWireDivide = aFaceDivide->GetWireDivideTool();
aFaceDivide->SetSplitSurfaceTool (MySplitSurfaceTool);
aWireDivide->SetSplitCurve3dTool (MySplitCurve3DTool);
aWireDivide->SetSplitCurve2dTool (MySplitCurve2DTool);
// 设置值标准
aShapeDivide.SetValCriterion ( val );
// 形状分割
aShapeDivide.Perform();
// 得到结果
TopoDS_Shape aSplitShape = aShapeDivide.GetResult();
// 获取面修改的历史
for ( TopExp_Explorer anExp (theInitShape, TopAbs_FACE); anExp. More (0; anExp.Next())
{
TopoDS_Shape aModifShape = aShapeDivide.GetContext()->Apply (anExp.Current());
}

通用拆分工具

形状分割的通用工具

ShapeUpgrade_ShapeDivide根据给定的标准提供形状分割和转换。它使用给定的面分割工具(默认为ShapeUpgrade_FaceDivide)对每个面执行这些操作。

该工具通过SetSplitFaceTool和GetSpliFaceTool方法提供对用于分割面的工具的访问

面分割通用工具

ShapeUpgrade_FaceDivide根据给定的标准划分面(线中的边,通过拆分 3D 和 2D 曲线,以及面本身,通过拆分支撑表面)。

用于分割的面区域由面上线的 2D 曲线定义。应该定义所有二维曲线(在支撑表面的参数空间中)。结果在调用Perform方法后可用。它是一个包含所有生成面的壳。在拆分操作期间所做的所有修改都记录在外部上下文 ( ShapeBuild_ReShape ) 中。

该工具通过以下方法提供对线分割和表面分割工具的访问:

  • SetWireDivideTool ,
  • GetWireDivideTool ,
  • SetSurfaceSplitTool ,
  • GetSurfaceSplitTool.

分线通用工具

ShapeUpgrade_WireDivide使用给定的标准划分位于面上的线或自由线或自由边中的边。它将面部边缘的 3D 曲线和 2D 曲线分开。其他可能与边缘相关的二维曲线被简单地复制。如果 3D 曲线被分割,那么面部的 2D 曲线也会被分割,反之亦然。原始形状未修改。所做的修改会记录在上下文 ( ShapeBuild_ReShape ) 中。

该工具通过以下方法提供对用于分割和分割 3D 和 2D 曲线的工具的访问:

  • SetEdgeDivdeTool ,
  • GetEdgeDivideTool ,
  • SetSplitCurve3dTool ,
  • GetSplitCurve3dTool ,
  • SetSplitCurve2dTool ,
  • GetSplitCurve2dTool

它还通过SetEdgeModeGetEdgeMode方法提供对分割边模式的访问。

此模式设置是否仅分割自由边、仅共享边或所有边。

边缘分割的通用工具

ShapeUpgrade_EdgeDivide类根据指定的标准划分边及其几何。它用于分线工具。

该工具通过以下方法提供对用于分割和分割 3D 和 2D 曲线的工具的访问:

  • SetSplitCurve3dTool ,
  • GetSplitCurve3dTool ,
  • SetSplitCurve2dTool ,
  • GetSplitCurve2dTool

几何分割的通用工具

几何分割有三种通用工具。

所有这些工具都以相同的方式构建:它们具有方法:

  • 用于几何初始化(方法Init);
  • 用于拆分(方法Perform);
  • 用于获取拆分后的状态和结果:
    • 状态——用于获取结果状态;
    • ResSurface – 用于分割表面;
    • GetCurves – 用于分割 3D 和 2D 曲线。在方法执行分裂的过程中:
  • 根据指定的标准计算参数空间中的拆分值(方法Compute);
  • 根据为拆分计算的值进行拆分(方法Build)。

要创建用于几何分割的新工具,只需从用于分割相应类型几何的通用工具继承一个新工具,并根据其中的指定标准重新定义计算分割值的方法(方法Compute)。

通过连续性进行曲面分割的工具的头文件:

// 将标准和容差设置到拆分工具中的方法
void SetCriterion ( GeomAbs_Shape theCriterion);
void SetTolerance ( Standard_Real theTol);
// 重新定义方法 Compute
virtual void Compute ( const bool theSegment) override;
私人
GeomAbs_Shape myCriterion;
Standard_Real myTolerance;
};

具体拆分工具

将形状几何转换为目标连续性

ShapeUpgrade_ShapeDivideContinuity允许将连续性小于指定连续性的几何转换为具有目标连续性的几何。如果无法进行转换,则几何对象将被拆分为多个满足给定标准的对象。基于此几何的拓扑对象被基于新几何的多个对象替换。

ShapeUpgrade_ShapeDivideContinuity aShapeDivide (theShape);
aShapeDivide.SetTolerance (theTol3d);
aShapeDivide.SetTolerance3d (theTol2d); // 如果已知,则采用 1.e-09
aShapeDivide.SetBoundaryCriterion(GeomAbs_C2); // 对于曲线 3D
aShapeDivide.SetPCurveCriterion (GeomAbs_C2); // 对于 2D 曲线
aShapeDivide.SetSurfaceCriterion (GeomAbs_C2); // 对于表面
aShapeDivide.Perform();
TopoDS_Shape aResShape = aShapeDivide.Result();
//.. 也得到之前/之后的对应关系
Handle( ShapeBuild_ReShape ) aCtx = aShapeDivide.Context();
//.. 在给定的形状上
if (aCtx.IsRecorded (theSh))
{
TopoDS_Shape aNewSh = aCtx->Value (theSh);
// 如果有多个结果,则记录在一个 Compound 中
// .. 根据需要处理
}

按角度分割

ShapeUpgrade_ShapeDivideAngle允许拆分给定形状的所有旋转曲面、圆柱面、环形面、圆锥面、球面,以便每个生成的线段覆盖不超过定义的角度(以弧度为单位)。

将 2D、3D 曲线和曲面转换为 Bezier

ShapeUpgrade_ShapeConvertToBezier类是一个 API 工具,用于执行将 3D、2D 曲线转换为 Bezier 曲线和将曲面转换为基于 Bezier 的曲面(Bezier 曲面、基于 Bezier 曲线的旋转曲面、基于任何先前类型的偏移曲面)。

该工具提供对各种标志的访问,以便通过以下方法将不同类型的曲线和曲面转换为 Bezier:

  • 对于 3D 曲线:
    • Set3dConversion,
    • Get3dConversion,
    • Set3dLineConversion ,
    • Get3dLineConversion ,
    • Set3dCircleConversion ,
    • Get3dCircleConversion ,
    • Set3dConicConversion ,
    • Get3dConicConversion
  • 对于二维曲线:
    • Set2dConversion,
    • Get2dConversion.
  • 对于表面:
    • GetSurfaceConversion ,
    • SetPlaneMode,
    • GetPlaneMode,
    • SetRevolutionMode,
    • GetRevolutionMode,
    • SetExtrusionMode,
    • GetExtrusionMode,
    • SetBSplineMode,
    • GetBSplineMode.

让我们尝试将平面转换为贝塞尔曲面。

// 工具的创建和初始化
ShapeUpgrade_ShapeConvertToBezier aConvToBez (theShape);
// 设置公差
//设置平面转换模式
aConvToBez.SetSurfaceConversion ( true );
aConvToBez.SetPlaneMode (true);
aConvToBez.Perform();
if (aConvToBez.Status(ShapeExtend_DONE)
{
TopoDS_Shape aResult = aConvToBez.GetResult();
}

用于分割闭合面的工具

ShapeUpgrade_ShapeDivideClosed类通过 U 和 V 参数将形状中的闭合面拆分为定义数量的组件。它在拓扑和(部分)几何上处理闭合面并在类ShapeUpgrade_ClosedFaceDivide的帮助下执行分割。

TopoDS_Shape theShape = …;
Standard_Real theCloseTol = …;
aTool.SetPrecision (theCloseTol);
Standard_Real theMaxTol = …;
aTool.SetMaxTolerance (theMaxTol);
Standard_Integer theNbSplitPoints = …;
aTool.SetNbSplitPoints (theNbSplitPoints);
if (!aTool.Perform() && aTool.Status (ShapeExtend_FAIL))
{
std::cout << “闭合面分割失败\n” ;
}
TopoDS_Shape aResult = aTool.Result();

用于将 C0 BSpline 2D 或 3D 曲线拆分为序列 C1 BSpline 曲线的工具

此工具的 API 方法是一组方法ShapeUpgrade::C0BSplineToSequenceOfC1BsplineCurve,它将 C0 B-Spline 曲线转换为 C1 B-Spline 曲线序列。此方法在重数等于度的节点处拆分 B 样条,它不使用任何公差,因此不会改变 B 样条的几何形状。如果 C0 B-Spline 被成功分割,该方法返回 True,否则返回 False(如果 BS 是 C1 B-Spline)。

分割面的工具

ShapeUpgrade_ShapeDivideArea可以处理化合物、实体、壳和面。在工作期间,该工具检查指定形状的每个面,如果面面积超过指定的最大面积,则该面被分割面分割是在这个面的参数空间中进行的。U 和 V 方向的分割值是通过考虑边界框形式参数空间到 3D 空间的平移来计算的。

此类计算对于避免创建条形面是必要的。在分割初始面上的孔的过程中被考虑在内。分割后,所有新面再次按面积检查,对面积仍超过最大允许面积的面重复分割过程。形状中的面之间的共享被保留,并且生成的形状与源形状的类型相同。

下图显示了使用此工具的示例:

图片[6]-OpenCasCade官方开发文档翻译(6)–occt形状修复-卡核

源面
图片[7]-OpenCasCade官方开发文档翻译(6)–occt形状修复-卡核

结果形状

ShapeUpgrade_ShapeDivideArea继承自基类ShapeUpgrade_ShapeDivide,应按以下方式使用:

  • 此类应在基类的构造函数或方法Init()的帮助下在形状上初始化。
  • 最大允许区域应由方法MaxArea()指定。
  • 要从基类生成拆分使用方法 Perform。
  • 可以借助Result()方法获得结果形状。
ShapeUpgrade_ShapeDivideArea Tool (theInputShape);
aTool.MaxArea() = theMaxArea;
aTool.Perform();
if (aTool.Status (ShapeExtend_DONE))
{
TopoDS_Shape aResultShape = aTool.Result();
ShapeFix::SameParameter (aResultShape, false );
}

注意必须使用ShapeFix::SameParameter方法,否则分割后得到的参数edges可能不同。

其他方法

形状的定制

定制工具旨在根据客户需求调整形状几何形状。他们将几何对象修改为形状中的另一个对象。

要实现必要的形状修改,只需通过形状和所需参数初始化适当的工具并获得结果形状就足够了。例如,对于形状中的间接曲面的转换,请执行以下操作:

TopoDS_Shape theInitialShape = …;
TopoDS_Shape aResultShape = ShapeCustom::DirectFaces (theInitialShape);

间接表面的转换

static TopoDS_Shape DirectFaces (const TopoDS_Shape & theShape);

该方法提供了将形状中的间接基本表面(具有左手坐标系的基本表面)转换为直接基本表面的方法。新的 2d 曲线(为转换后的曲面重新计算)添加到由结果形状和原始形状S共享的相同边。

形状缩放

TopoDS_Shape ShapeCustom ::ScaleShape (const TopoDS_Shape & theShape, const Standard_Real theScale);

此方法返回一个新形状,它是一个缩放的原始形状,其系数等于指定的比例值。它使用工具ShapeCustom_TrsfModification

曲线和曲面到 BSpline 的转换

ShapeCustom_BSplineRestriction允许以指定的度数、最大段数、2d 公差和 3d 公差逼近曲面、曲线和 2D 曲线。如果不能以指定的连续性获得近似结果,则可以减少后者。

带有所有参数的方法如下所示:

ShapeCustom::BsplineRestriction()
TopoDS_Shape ShapeCustom ::BSplineRestriction (const TopoDS_Shape & theShape,
const Standard_Real theTol3d, const Standard_Real theTol2d,
const Standard_Integer theMaxDegree,
const Standard_Integer theMaxNbSegment,
const GeomAbs_Shape theContinuity3d,
const GeomAbs_Shape theContinuity2d,
const Standard_Boolean theDegree,
const Standard_Boolean theRational,
const Handle( ShapeCustom_RestrictionParameters )& theParameters);

它返回一个新形状,其中包含 BSpline/Bezier 类型或基于它们的所有曲面、曲线和 2D 曲线,根据优先级参数Degree以小于MaxDegree的度数或小于NbMaxSegment的跨度数进行转换。如果此参数等于 True,则Degree将增加到值GmaxDegree,否则NbMaxSegments将增加到值GmaxSegmentsGmaxDegreeGMaxSegments是最大可能的度数和相应的跨度数。这些值将在无法使用指定参数进行近似的情况下使用,并且要么根据优先级选择GmaxDegreeGMaxSegments 。

请注意,如果使用GMaxDegree无法进行近似,那么跨度数可能会超过指定的GMaxSegmentRational指定 Rational BSpline/Bezier 是否应转换为多项式 B-Spline。

另请注意,生成的形状中曲面的连续性可能小于给定值。

标志

要将其他类型的曲线和曲面转换为具有所需参数的 BSpline,必须使用类ShapeCustom_RestrictionParameters中的标志,它只是标志的容器。以下标志定义是否已将指定类型的几何图形转换为具有所需参数的 BSpline:

  • 转换平面
  • 转换贝塞尔冲浪
  • 转换革命冲浪
  • ConvertExtrusionSurf ,
  • 转换偏移冲浪
  • ConvertCurve3d – 用于转换所有类型的 3D 曲线,
  • ConvertOffsetCurv3d – 用于偏移 3D 曲线的转换,
  • ConvertCurve2d – 用于转换所有类型的 2D 曲线,
  • ConvertOffsetCurv2d – 用于偏移二维曲线的转换,
  • SegmentSurfaceMode – 定义表面是否近似于位于该表面上的面的边界内。

将基本曲面转换为旋转曲面

TopoDS_Shape ShapeCustom ::ConvertToRevolution (const TopoDS_Shape & theShape);

此方法返回一个新形状,其中所有基本周期曲面都转换为Geom_SurfaceOfRevolution。它使用工具ShapeCustom_ConvertToRevolution

将基本曲面转换为 Bspline 曲面

TopoDS_Shape ShapeCustom ::ConvertToBSpline (const TopoDS_Shape & theShape,
const Standard_Boolean theExtrMode,
const Standard_Boolean theRevolMode,
const Standard_Boolean theOffsetMode);

此方法返回一个新形状,其中线性挤压、旋转和偏移曲面的所有曲面根据标志转换为Geom_BSplineSurface(具有相同的参数化)。它使用工具ShapeCustom_ConvertToBSpline

获取子形状的修改历史。

如果除了生成的形状之外,您还想获取子形状的修改历史,则不应使用上述封装方法,而应使用您自己的代码:

  1. 创建一个负责必要修改的工具。
  2. 创建在形状中执行指定修改的工具BRepTools_Modifier 。
  3. 要获取历史记录并保持装配结构,请使用ShapeCustom::ApplyModifier方法。

缩放的通用调用语法是

TopoDS_Shape aScaledShape = ShapeCustom::ScaleShape (theShape, theScale);

请注意,规模是一个真实的价值。您可以通过使用额外的调用来细化您的映射过程,以逐个子形状地跟踪形状映射子形状。可以使用以下代码以及相关包含:

Standard_Real theScale = 100; // 例如!
gp_Trsf aTrsf;
aTrsf.SetScale ( gp_Pnt (0, 0, 0), theScale);
BRepTools_Modifier aBRepModif;
TopoDS_Shape aRes = ShapeCustom::ApplyModifier (theShape, aTrsfModif, aContext, aBRepModif);

在我们的示例中称为上下文的地图包含历史记录。替换是一一进行的,所有的形状都被转换了。要确定特定子形状会发生什么,可以使用:

TopoDS_Shape aOneRes = aContext.Find(theOneShape);
// 如果有疑问,还可以添加:
if (aContext.IsBound ( theOneShape))
{
aOneRes = aContext.Find(theOneShape);
}
// 也可以扫描整个数据图:
for ( TopTools_DataMapOfShapeShape::Iterator anIter (aContext); anIter.More(); anIter.Next())
{
TopoDS_Shape aOneShape = anIter.Key();
TopoDS_Shape aOneRes = anIter.Value();
}

拆除内部线

ShapeUpgrade_RemoveInternalWires工具移除轮廓面积小于指定最小面积的内部线。它可以处理化合物、实体、壳和面。

如果标记RemoveFaceMode设置为 TRUE,则将移除单独的面或具有外部线的一组面,这些面仅包含属于已移除内部线的边(不考虑接缝边)。只有缝合形状才能移除此类面。

内部线可以通过Perform方法移除。如果类没有被形状初始化,这两种方法Perform都不能执行。在这种情况下,Perform的状态设置为 FAIL。

不带参数的方法Perform从指定形状的所有面中移除面积小于最小面积的内部线。

另一种方法Perform具有一系列形状作为参数。此序列可以包含面或线。如果形状序列包含线,则仅删除内部线。

如果形状序列包含面,则仅删除这些面的内部线。

  • 执行操作的状态可以使用方法Status()获得;
  • 可以使用方法GetResult()获得生成的形状。

下图显示了使用此工具的示例:

图片[8]-OpenCasCade官方开发文档翻译(6)–occt形状修复-卡核

源面
图片[9]-OpenCasCade官方开发文档翻译(6)–occt形状修复-卡核

结果形状

处理后,轮廓面积小于指定最小面积的三根内部导线已被移除。一个内部面已被移除。该面的外线由属于已移除的内线的边缘和接缝边缘组成。另外两个内部面没有被移除,因为它们的外线不仅包含属于被移除的线的边。

图片[10]-OpenCasCade官方开发文档翻译(6)–occt形状修复-卡核

源面
图片[11]-OpenCasCade官方开发文档翻译(6)–occt形状修复-卡核

结果形状

处理后,轮廓面积小于指定最小面积的六根内部导线已被移除。六个内部面已被删除。这些面可以合并成面组。每组面都有一条外线,该外线仅由属于已移除的内部线的边组成。这样的面孔组也被删除。

下面也给出方法应用的例子:

// 按形状初始化类
// 设置参数
aTool->MinArea() = theMinArea;
aTool->RemoveFaceMode() = theModeRemoveFaces;
// 当对单独的形状执行方法 Perform 时
aTool->Perform (theSeqShapes);
// 当对整个形状执行方法 Perform 时
aTool->Perform();
// 检查方法执行后设置的状态
if (aTool->Status (ShapeExtend_FAIL)
{
std::cout << “操作失败\n” ;
返回;
}
if (aTool->Status (ShapeExtend_DONE1))
{
const TopTools_SequenceOfShape& aRemovedWires = aTool->RemovedWires();
std::cout << aRemovedWires.Length() << ” 内部线被移除\n” ;
}
if (aTool->Status (ShapeExtend_DONE2))
{
const TopTools_SequenceOfShape& aRemovedFaces =aTool->RemovedFaces();
std::cout << aRemovedFaces.Length() << ” 小面被移除\n” ;
}
// 获取结果形状
TopoDS_Shape aRes = aTool->GetResult();

曲面的转换

ShapeCustom_Surface类允许:

  • 将 BSpline 和 Bezier 曲面转换为解析形式(使用ConvertToAnalytical() 方法)
  • 将封闭的 B 样条曲面转换为周期性曲面。(使用方法ConvertToPeriodic)。

要将表面转换为分析形式,该类分析源表面的形式和闭合,并定义它是否可以通过以下类型之一的分析表面来近似:

仅当新(分析)表面与源的偏差不超过给定精度时,才进行转换。

Handle( Geom_Surface ) theInitSurf;
ShapeCustom_Surface aConvSurf (theInitSurf);
// 转换为解析形式
Handle( Geom_Surface ) aNewSurf = aConvSurf.ConvertToAnalytical (theAllowedTol, false );
// 或转换为周期性曲面
Handle( Geom_Surface ) aNewSurf = aConvSurf.ConvertToPeriodic ( false );
// 获取新曲面与初始曲面的最大偏差
Standard_Real aMaxDist = aConvSurf.Gap();

统一同域

ShapeUpgrade_UnifySameDomain工具允许统一一个形状的所有可能的面和边缘,它们位于同一几何体上。如果相邻的面/边位于重合的曲面/曲线上,则面/边被视为“同域”。这样的面/边可以统一为一个面/边。该工具采用输入形状并返回一个新形状。在操作过程中记录初始形状的所有修改。

可以使用以下选项:

  • 如果标志UnifyFaces设置为 TRUE,UnifySameDomain 会尝试统一所有可能的面;
  • 如果标志UnifyEdges设置为 TRUE,UnifySameDomain 会尝试统一所有可能的边;
  • 如果标志ConcatBSplines设置为 TRUE,则位于 BSpline 或 Bezier 曲线上的所有相邻边在其公共顶点上具有 C1 连续性将被合并为一个公共边。

默认情况下,UnifyFacesUnifyEdges设置为 TRUE;ConcatBSplines设置为 FALSE。

该工具的常用方法如下:

  • 方法Build()用于统一。
  • 方法Shape()用于获取结果形状。
  • 方法Generated()用于从旧形状中获取新的通用形状。如果一组边已统一为一个公共边,则在该组中的任何边上调用的Generated()方法将返回公共边。面孔也是如此。

使用示例如下:

// ‘theSh’ 是初始形状
// UnifyFaces 模式开启,UnifyEdges 模式开启,ConcatBSplines 模式开启
ShapeUpgrade_UnifySameDomain aTool (theSh, true , true , true );
aTool.Build();
// 得到结果
TopoDS_Shape aResult = aTool.Shape();
// 让 theSh1 作为 theSh 的一部分
// 从 theSh1 中获取新的(可能是统一的)形状
TopoDS_Shape aResSh1 = aTool.Generated (theSh1);

用于修复、分析和升级的辅助工具

用于重建形状的工具

ShapeBuild_ReShape类通过对其某些组件进行预定义的替换来重建形状。在第一阶段,它记录替换或删除某些单独形状的请求。对于每个形状,都会记录最后一个给定的请求。请求可以应用为定向(即仅适用于具有相同方向的项目)或不应用(替换形状的方向对应于原始形状的方向)。然后这些请求可以应用于任何形状,其中可能包含一个或多个这些单独的形状。

此工具有一个标志,用于考虑形状的位置(用于保持组件的结构)(ModeConsiderLocation)。如果此模式等于 Standard_True,则将保留具有位置的共享形状。如果此模式等于 Standard_False,则重建后将由具有不同位置的一个形状产生一些不同的形状。默认情况下,此模式等于 Standard_False。

要使用此工具重建形状,必须采取以下步骤:

  1. 创建此工具并使用Apply()方法通过初始形状对其进行初始化。参数until设置形状类型的级别,并且仅考虑到此级别的请求。超出参数 until 设置的线的类型的子形状将不会被重建,也不会进行进一步的探索。
  2. 替换或删除初始形状的子形状。每个子形状都可以替换为相同类型的形状或仅包含该类型形状的形状(例如,TopoDS_Edge可以替换为包含TopoDS_Edges的TopoDS_EdgeTopoDS_WireTopoDS_Compound)。如果遇到不兼容的形状类型,则会将其忽略并在状态中设置标志 FAIL1。对于子形状,建议在方法ReplaceRemove之前使用方法Apply,因为子形状目前已经被其先前的修改或修改其子形状(例如TopoDS_Edge可以通过修改其TopoDS_Vertex等来更改)。
  3. 使用方法再次申请初始形状,得到所有修改后的最终形状。
  4. 使用Apply方法获取子形状修改的历史。

附加方法IsNewShape可用于检查形状是否已被BRepTools_ReShape工具记录为值。

请注意,实际上类ShapeBuild_ReShape是类 BRepTools_ReShape 的别名。它们的区别仅在于ShapeBuild_ReShape类中的状态查询。

让我们使用工具来获得初始形状的子形状修改后的结果形状:

TopoDS_Shape theInitialShape = …;
// 创建一个重建工具
Handle( ShapeBuild_ReShape ) aContext = new ShapeBuild_ReShape ();
// 下一步是可选的;可用于保持装配结构
aContext->ModeConsiderLocation = true ;
// 通过初始形状初始化此工具
aContext->Apply (theInitialShape);
// 获取用修改后的 theNewSubshape1 替换 theSubshape1 的中间结果
TopoDS_Shape aTempSubshape1 = aContext->Apply (theSubshape1);
// 用 theNewSubshape1 替换从 theSubshape1 获得的中间形状
aContext->Replace (aTempSubshape1, theNewSubshape1);
// 用于移除子形状
TopoDS_Shape aTempSubshape2 = aContext->Apply (theSubshape2);
aContext->Remove (aTempSubshape2);
// 获取结果和修改历史
TopoDS_Shape aResultShape = aContext->Apply (theInitialShape);
// 从初始形状的 theSubshape1 获取生成的子形状
TopoDS_Shape aResultSubshape1 = aContext->Apply (theSubshape1);

状态定义

ShapeExtend_Status用于在执行某些可能失败、执行某些操作或什么都不执行的方法后报告状态。状态是一组标志DONEiFAILi。可以同时设置它们的任意组合。为了探索状态,使用枚举。

这些值具有以下含义:

意义
OK, 什么都没做,一切正常
DONE1, 事情已经完成,案例 1
DONE8, 事情已经完成,案例 8
DONE, 某事已完成(任何 DONE#)
FAIL1, 方法失败,案例1
FAIL8, 方法失败,案例8
FAIL 方法失败(发生任何 FAIL#)

代表线的工具

ShapeExtend_WireData提供了一种数据结构,可以像处理边的有序列表一样使用连线,这是许多算法所必需的。这个类的优点是它允许使用不正确的线。

ShapeExtend_WireData类的对象可以由TopoDS_Wire初始化并转换回TopoDS_Wire

线中的边由其等级数定义。提供了在给定秩数处访问、添加和删除边的操作。在整根导线上也提供了循环置换和反转操作(所有边缘的方向和边缘的顺序)。

此类还提供了一种方法来检查线中的边缘是否为接缝(如果线位于面上)。

让我们从线上移除边缘并定义它是否是接缝边缘:

TopoDS_Wire theInitWire = …;
Handle (ShapeExtend_Wire) anExtendWire = new ShapeExtend_Wire (theInitWire);
// 从线上移除边缘 theEdge1
Standard_Integer anEdge1Index = anExtendWire->Index (theEdge1);
anExtendWire.Remove(anEdge1Index);
//定义theEdge2是否为接缝边
Standard_Integer anEdge2Index = anExtendWire->Index (theEdge2);
anExtendWire->IsSeam (anEdge2Index);

探索形状的工具

ShapeExtend_Explorer旨在探索形状并转换复杂形状的不同表示(列表、序列、复合)。它提供了以下工具:

将消息附加到对象的工具

ShapeExtend_MsgRegistrator将消息附加到对象(通用瞬态或形状)。此类的对象被传输到形状修复算法,以便它们可以收集形状处理过程中发生的消息。消息被添加到地图(存储为字段)中,例如,数据交换处理器可以使用这些消息将这些消息附加到初始文件实体。

让我们发送并获取附加到对象的消息:

// 将消息附加到对象(形状或实体)
Message_Msg theMsg = …;
TopoDS_Shape theShape1 = …;
aMsgReg->Send (theShape1, theMsg, Message_WARNING);
Handle( Standard_Transient ) theEnt = …;
aMsgReg->Send (theEnt, theMsg, Message_WARNING);
// 获取附加到形状的消息
const ShapeExtend_DataMapOfShapeListOfMsg & aMsgMap = aMsgReg->MapShape();
if (aMsgMap.IsBound ( theShape1))
{
const Message_ListOfMsg & aMsgList = aMsgMap.Find(theShape1);
for ( Message_ListIteratorOfListOfMsg aMsgIter (aMsgList); aMsgIter. More (); aMsgIter.Next())
{
Message_Msg aMsg = aMsgIter.Value();
}
}

绩效衡量工具

MoniTool_Timer和MoniTool_TimerSentry用于测量当前操作或任何部分代码的性能,并提供必要的 API。定时器用于调试和性能优化目的。

让我们尝试使用XSDRAWIGES.cxxIGESBRep_Reader.cxx中的计时器来分析命令igesbrep的性能:

#include < MoniTool_Timer .hxx>
MoniTool_TimerSentry aTimeSentry ( “IGES_LoadFile” );
Standard_Integer aStatus = aReader.LoadFile (theFilePath.ToCString());
aTimeSentry.Stop();
return
IGESBRep_Reader.cxx
#include < MoniTool_TimerSentry .hxx>
Standard_Integer aNbEntries = theModel->NbEntities();
for ( Standard_Integer i = 1; i<= aNbEntries; ++i)
{
MoniTool_TimerSentry aTimeSentry ( “IGESToBRep_Transfer” );
try
{
TP.Transfer(anEntry);
shape = TransferBRep::ShapeResult (theProc, anEntry);
}
}

文件翻译后DumpTimer()的结果如下:

定时器 过去 CPU 用户 中央处理器系统 命中
IGES_LoadFile 1.0 秒 0.9 秒 0.0 秒 1
IGESToBRep_Transfer 14.5 秒 4.4 秒 0.1 秒 1311

形状加工

使用工作流程

形状处理模块允许将一般形状处理定义和应用为可定制的形状修复操作序列。自定义是通过用户可编辑的资源文件实现的,该文件定义了要执行的操作符的顺序及其参数。

形状处理功能是在XSAlgo接口的帮助下实现的。主函数XSAlgo_AlgoContainer::ProcessShape()使用指定的公差进行形状处理,并以Transient的形式返回结果形状和相关信息。

该功能的使用方式如下:

TopoDS_Shape theShape = …;
Standard_Real thePrec = …;
Standard_Real theMaxTol = …;
TopoDS_Shape aResult = XSAlgo::AlgoContainer()->ProcessShape (theShape, thePrec, theMaxTol,
“Name of ResourceFile”, “NameSequence”, anInfo);

让我们创建一个自定义的操作序列:

  1. 创建一个名为ResourceFile的资源文件,其中包括以下字符串:
    NameSequence.exec.op: MyOper

    其中MyOper是操作的名称。

  2. 在资源文件中为该操作输入自定义参数,例如:
    NameSequence.MyOper.Tolerance: 0.01

    其中Tolerance是参数的名称,0.01 是它的值。

  3. 将以下字符串添加到void ShapeProcess_OperLibrary::Init() 中

    其中myFunction是实现操作的函数。

  4. 在ShapeProcess_OperLibrary中创建此函数,如下所示:
    static bool myFunction ( const Handle ( ShapeProcess_Context )& theContext)
    {
    Handle( ShapeProcess_ShapeContext ) aCtx =Handle( ShapeProcess_ShapeContext )::DownCast (theContext);
    if (aCtx.IsNull()) { return false ; }
    TopoDS_Shape aShape = aCtx->Result();
    // 接收我们的参数:
    Standard_Real aToler = 0.0;
    aCtx->GetReal (Tolerance, aToler);
  5. 使用从资源文件中接收到的参数Tolerance值对aShape进行必要的操作。
    返回
    }
  6. 定义一些操作(及其参数)MyOper1、MyOper2、MyOper3等,并在ShapeProcess_OperLibrary中描述相应的函数。
  7. 使用资源文件中指定的操作名称和参数值执行所需的序列。

例如:输入以下字符串:

NameSequence.exec.op: MyOper1,MyOper3

表示 ShapeProcess_OperLibrary 中的相应函数使用资源文件中为MyOper1MyOper3定义的参数使用原始形状aShape执行。

需要注意的是,这些操作会逐步进行,执行第一次操作后得到的结果将作为第二次操作的初始形状。

运营商

直接面

此操作符基于间接曲面设置所有面,用左手坐标系定义为直接面。这涉及由轴放置(圆柱等)定义的表面。这种轴放置可能是间接的,这在 Cascade 中是允许的,但在某些其他系统中是不允许的。此运算符反转间接放置并相应地重新计算 PCurves。

同参数

根据它们所做的计算,在调用其他一些运算符后需要此运算符。它的调用是显式的,因此每个调用都可以根据运算符被删除,然后调用或不调用。这主要涉及可以分裂边缘的分裂算子。

操作员应用计算SameParameter确保每条边的各种表示(它的 3d 曲线,它所在的每个面上的 pcurve)在给定的容差内为相同的参数提供相同的 3D 点。

  • 对于编码为相同参数的每个边缘,计算曲线表示的偏差,如果边缘公差小于该偏差,则增加公差以满足偏差。无需修改几何形状,只能增加公差。
  • 对于编码为不同参数的每个边缘,偏差的计算方法与第一种情况相同。然后尝试通过修改二维曲线来实现与相同参数的边缘相等。如果此修改边的偏差小于原始偏差,则返回此边,否则返回原始边(具有未修改的 2d 曲线)并增加(如有必要)容差。通过调用标准算法BRepLib::SameParameter来完成计算。

可以使用以下参数调用此运算符:

  • Boolean : Force(可选)——如果为 True,则将所有边编码为不同的参数,然后运行计算。否则,仅对那些已编码为不同参数的边进行计算。
  • Real:Tolerance3d(可选)——如果未定义,则每条边的局部容差将用于其自己的计算。否则,此参数给出整个形状的全局公差。

BSplineRestriction

此运算符用于将曲面、曲线 2d 曲线转换为具有指定度数和指定跨度数的 BSpline 曲面。它对具有指定度数、最大段数、2d 容差、3d 容差的曲面、曲线和 2d 曲线进行逼近。如果与指定连续性的近似没有成功完成,则可以减少指定的连续性。

可以使用以下参数调用此运算符:

  • Boolean : SurfaceMode允许考虑表面;
  • Boolean : Curve3dMode允许考虑 3d 曲线;
  • Boolean : Curve2dMode允许考虑 2d 曲线;
  • Real : Tolerance3d定义用于计算的 3d 容差;
  • Real : Tolerance2d定义了计算 2d 曲线时要使用的 2d 容差;
  • GeomAbs_Shape (C0 G1 C1 G2 C2 CN) :Continuity3d是2d中要求的连续性;
  • GeomAbs_Shape (C0 G1 C1 G2 C2 CN) :Continuity2d是3d中需要的连续性;
  • Integer :RequiredDegree给出所需的学位;
  • Integer :RequiredNbSegments给出所需的段数;
  • Boolean : PreferDegree如果为真,RequiredDegree有优先级,否则RequiredNbSegments有优先级;
  • Boolean : RationalToPolynomial用于将 BSplines 转换为多项式形式;
  • Integer :MaxDegree给出允许的最大度数,如果无法达到RequiredDegree ;
  • Integer :如果无法达到RequiredNbSegments,MaxNbSegments 给出允许的最大 NbSegments 。

除了 BSpline 之外,以下标志允许管理特殊类型的曲线或曲面的转换。它们分别由SurfaceMode、Curve3dModeCurve2dMode控制;默认情况下,仅考虑 BSplines 和 Bezier 几何:

  • 布尔值:OffsetSurfaceMode
  • 布尔值:线性挤压模式
  • 布尔值:革命模式
  • 布尔值:OffsetCurve3dMode
  • 布尔值:OffsetCurve2dMode
  • 布尔值:平面模式
  • 布尔值:贝塞尔模式
  • 布尔值:ConvCurve3dMode
  • 布尔值:ConvCurve2dMode

对于上面列出的每个 Mode 参数,如果为 True,则将指定的几何图形转换为 BSpline,否则仅检查并转换其基本几何图形(如有必要),保持几何图形的原始类型(旋转、偏移等)。

  • Boolean :SegmentSurfaceMode仅对 Bsplines 和 Bezier 曲面有效。当为 False 时,曲面将被修剪曲面替换,否则将通过拆分原始 Bspline 或 Bezier 曲面来创建新几何。

初级到革命

此运算符将基本周期曲面转换为 SurfaceOfRevolution。

分割角

此运算符以给定的形状分割旋转、圆柱、环形、圆锥、球面的表面,以便每个生成的段覆盖不超过定义的度数。

可以使用以下参数调用它:

  • Real : Angle – 结果面的最大允许角度;
  • Real : MaxTolerance – 计算中使用的最大容差。

SurfaceToBSpline

该运算符将某些特定类型的 Surfaces 转换为 BSpline(根据参数)。可以使用以下参数调用它:

  • Boolean : LinearExtrusionMode允许转换 Linear Extrusion 的表面;
  • Boolean :RevolutionMode允许转换Revolution 的表面;
  • Boolean : OffsetMode允许转换偏移曲面。

托贝塞尔

该运算符仅用于支持 Bezier 的数据,并将各种类型的几何转换为 Bezier。可以使用以下用于计算转换的参数调用它:

  • 布尔值:表面模式
  • 布尔值:Curve3dMode
  • 布尔值:Curve2dMode
  • 真实:最大公差
  • Boolean : SegmentSurfaceMode(默认为 True)仅对 Bsplines 和 Bezier 曲面有效。当为 False 时,曲面将被修剪曲面替换,否则将通过拆分原始 Bspline 或 Bezier 曲面来创建新几何。

以下参数由SurfaceMode、Curve3dModeCurve2dMode控制(视情况而定):

  • 布尔值:Line3dMode
  • 布尔值:Circle3dMode
  • 布尔值:Conic3dMode
  • 布尔值:PlaneMode
  • 布尔值:RevolutionMode
  • 布尔值:ExtrusionMode
  • 布尔值:BSplineMode

分裂连续性

该运算符拆分形状,以使每个几何形状(曲面、曲线 3d、曲线 2d)对应于给定的连续性标准。可以使用以下参数调用它:

  • 真实:Tolerance3d
  • 整数(GeomAbs_Shape):CurveContinuity
  • 整数(GeomAbs_Shape):SurfaceContinuity
  • 真实:MaxTolerance

由于算子BSplineRestriction的算法限制(在某些特殊情况下,该算子会产生意外的 C0 几何),如果调用 SplitContinuity,建议在BSplineRestriction之后调用。除了直接整数值(分别为 0 1 2 3 4 5)外,连续性值将设置为GeomAbs_Shape(即 C0 G1 C1 G2 C2 CN)。

分裂闭合面

该操作符分割面,即使它们不是旋转的或圆柱、圆锥、球面、环形,这些面也是封闭的。这对应于可以闭合(无论是否周期性)的 BSpline 或 Bezier 曲面,因此它们具有接缝边缘。结果,不再有接缝边缘。点数允许控制每个输入闭合面产生的最小面数。

可以使用以下参数调用此运算符:

  • Integer : NbSplitPoints给出用于分割的点数(产生的间隔数是NbSplitPoints+1);
  • Real : CloseTolerance公差,用于确定一个面是否闭合;
  • Real : MaxTolerance用于分割计算。

修复间隙

调用FixFaceSize和/或DropSmallEdges时必须调用此运算符。使用 Surface Healing 可能需要额外调用BSplineRestriction以确保修改后的几何图形满足 BSpline 的要求。该运算符修复几何图形,这些几何图形包含导线中的边缘之间的间隙(始终执行)或面上的间隙,由参数SurfaceMode控制,面上的间隙通过使用表面修复算法修复。可以使用以下参数调用此运算符:

  • Real : Tolerance3d设置要在 3d 中达到的公差。如果一个gap小于这个值,就不是固定的;
  • Boolean : SurfaceMode设置边缘和面之间固定间隙的模式(是/否);
  • Integer :SurfaceAddSpans设置要添加到表面以修复间隙的跨度数;
  • GeomAbs_Shape (C0 G1 C1 G2 C2 CN) :SurfaceContinuity设置所得曲面的最小连续性;
  • Integer :NbIterations设置迭代次数;
  • Real : Beta设置修改表面的弹性系数 [1-1000];
  • Reals:Coeff1 到 Coeff6设置用于修改表面的能量系数 [0-10000];
  • Real : MaxDeflection设置表面从旧位置的最大偏转。

该运算符可以更改原始几何图形。此外,它会消耗 CPU,并且在某些情况下可能会失败。此外,FixGaps只有在由于删除可以通过DropSmallEdgesFixFaceSize删除的小边而获得间隙时才有帮助。

FixFaceSize

此操作符删除所有方向上的小面(斑点面)或一个方向上的小面(条形面)。可以使用参数Real : Tolerance调用它,该参数设置用于考虑面的最小尺寸,它小到可以被移除。

DropSmallEdges

当它们小于给定值 ( Tolerance3d ) 并且拓扑允许这种合并时(即,每个合并的边具有相同的相邻面),该操作符会丢弃导线中的边,并将它们与相邻边合并。如果它们共享相同的顶点参数,也可以删除自由(不被相邻面共享)的小边。

可以使用参数Real : Tolerance3d调用它,该参数设置用于确定边是否小的尺寸。

固定形状

可以添加此运算符以修复无效形状。它根据下面列出的模式执行各种检查和修复。一组修复的管理可以通过如下标志来执行:

  • 如果修复工具的标志设置为 0 ,则不执行;
  • 如果设置为 1 ,则在任何情况下都执行;
  • 如果未设置或设置为 -1 ,则对于要应用的每个形状,都会进行检查以评估是否需要修复。如果检查是肯定的,则执行修复。

默认情况下,未设置标志,检查每个单独的形状。

可以使用以下参数调用此运算符:

  • Real:Tolerance3d设置用于固定的基本公差;
  • Real : MaxTolerance3d设置结果公差的最大允许值;
  • Real : MinTolerance3d设置结果公差的最小允许值。
  • 布尔值:FixFreeShellMode
  • 布尔值:FixFreeFaceMode
  • 布尔值:FixFreeWireMode
  • 布尔值:FixSameParameterMode
  • 布尔值:FixSolidMode
  • 布尔值:FixShellMode
  • 布尔值:FixFaceMode
  • 布尔值:FixWireMode
  • 布尔值:FixOrientationMode
  • 布尔值:FixMissingSeamMode
  • 布尔值:FixSmallAreaWireMode
  • Boolean(未选中):ModifyTopologyMode指定修改拓扑的模式。对于有壳的形状应该是 False(默认),对于自由面可以是 True。
  • Boolean(未选中):ModifyGeometryMode指定修改几何的模式。如果要保留几何图形,则应为 False,如果可以修改,则应为 True。
  • Boolean(未选中):ClosedWireMode指定线的模式。对于面上的线,应该为 True,对于自由线,应该为 False。
  • Boolean(未选中):PreferencePCurveMode(未使用)指定边缘的 3d 或 2d 表示的偏好
  • 布尔值:FixReorderMode
  • 布尔值:FixSmallMode
  • 布尔值:FixConnectedMode
  • 布尔值:FixEdgeCurvesMode
  • 布尔值:FixDegenerationMode
  • 布尔值:FixLackingMode
  • 布尔值:FixSelfIntersectionMode
  • 布尔值:FixGaps3dMode
  • 布尔值:FixGaps2dMode
  • 布尔值:FixReversed2dMode
  • 布尔值:FixRemovePCurveMode
  • 布尔值:FixRemoveCurve3dMode
  • 布尔值:FixAddPCurveMode
  • 布尔值:FixAddCurve3dMode
  • 布尔值:FixSeamMode
  • 布尔值:FixShiftedMode
  • 布尔值:FixEdgeSameParameterMode
  • 布尔值:FixSelfIntersectingEdgeMode
  • 布尔值:FixIntersectingEdgesMode
  • 布尔值:FixNonAdjacentIntersectingEdgesMode

SplitClosedEdges

该运算符处理闭合边,即具有一个顶点的边。某些接收系统不支持此类边缘。该算子将拓扑闭合边(即具有一个顶点的边)拆分为两条边。不处理退化边缘和尺寸小于 Tolerance 的边缘。

消息机制

在形状修复或升级过程中会产生各种关于修改、警告和失败的消息。消息传递机制允许生成消息,这些消息将被发送到选定的目标媒体文件或屏幕。这些消息可以报告故障和/或警告,或提供有关事件的信息,例如形状的分析、修复或升级。

消息重力

枚举Message_Gravity用于定义消息重力。它提供以下消息状态:

  • Message_FAIL – 消息报告失败;
  • Message_WARNING – 消息报告警告;
  • Message_INFO – 消息提供信息。

将消息文件加载到内存中的工具

Message_MsgFile类允许通过将自定义消息文件加载到内存中来定义消息。在将其加载到内存之前,有必要创建一个自定义消息文件,因为它的路径将用作加载它的参数。消息文件中的每条消息都由一个键标识。用户可以通过指定消息键来获取消息的文本内容。

消息文件的格式

消息文件是一个 ASCII 文件,它定义了一组消息。文件的每一行的长度必须少于 255 个字符。文件中以感叹号开头的所有行(可能前面有空格和/或制表符)都被视为注释并被忽略。一个消息文件可能包含多条消息。每条消息都由其密钥(字符串)标识。文件中以字符(可能前面有空格和/或制表符)开头的每一行都定义了键。键是一个字符串,以点后的符号开始,以换行符\n 结尾之前的符号结束。文件中键之后和下一个关键字之前的所有行(并且不是注释)都定义了该键的消息。如果消息由多行组成,则消息字符串将在每行之间包含换行符\n(但不在末尾)。

以下示例说明了消息文件的结构:

!This is a sample message file
!——————————
!Messages for ShapeAnalysis package
!
.SampleKeyword
Your message string goes here
!
!…
!
!End of the message file

加载消息文件

可以使用Message_MsgFile::LoadFile方法将自定义文件加载到内存中,将文件路径作为参数,如下例所示:

Standard_CString aMsgFilePath = “(path)/sample.file” ;

用于管理填充消息的工具

Message_Msg类允许使用作为模板加载的消息文件。这个类提供了一个工具来准备消息,用参数填充它,存储和输出到默认的跟踪文件。消息由密钥创建:此密钥标识要在消息文件中创建的消息。消息的文本取自加载的消息文件(使用Message_MsgFile类)。消息的文本可以包含参数的位置,在准备消息时这些参数将由适当的值填充。这些参数可以是以下类型:

  • 字符串 – 在文本中编码为 %s,
  • 整数 – 在文本中编码为 %d,
  • real – 在文本中编码为 %f。

参数字段通过调用相应的方法AddInteger、AddRealAddString由消息文本填充。消息的原始文本和带有替换参数的输入文本都存储在对象中。准备和填充的消息可以输出到默认跟踪文件。还可以获得消息的文本(原始的或填充的)。

Message_Msg aMsg01 ( “SampleKeyword” );
// 创建消息 aMsg01,在文件中由关键字 SampleKeyword 标识
aMsg01.AddInteger (73);
aMsg01.AddString( “SampleFile” );
// 填写代码区域
© 版权声明
THE END
喜欢就支持一下吧
点赞1W+ 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容