Brep格式

BRep 全称Boundary Representation(边界表示法),是工业 CAD 领域主流的三维实体建模标准。 BRep通过描述物体的边界来定义实体,一个物体由一组面围成,面由边围成,边由顶点定义。实体表示为连接的表面元素的集合,即实体和非实体之间的边界。

它的数据分为两大板块:拓扑信息(结构连接关系) + 几何信息(数学形态参数)

一、核心概念拆解

1. 拓扑 vs 几何

拓扑信息记录各个形状部件之间的连接、从属、共用关系,描述结构框架。只讲连接关系,不标注坐标、曲面曲率这类数值。

几何信息给拓扑节点赋予真实数学形状,填充具体坐标、曲线曲面参数。承载具体空间参数,决定模型实际尺寸样貌。

(1)拓扑层级结构

Body(独立零件)
└──Solid(实体整体)
        └── Shell(壳,封闭外壳,存在内外多层壳可以表达模型孔洞)
                 └── Face(面,一个个曲面面片)
                          └── Loop(环,面的闭合边界,外环顺时针、内环用来刻画面上的小孔)
                                    └── CoEdge(有向边,记录边在不同面的朝向)
                                               └── Edge(空间棱边)
                                                         └── Vertex(顶点,三维坐标端点)
Body 是 STEP 标准与 OpenCASCADE 中零件 / 装配的顶层管理单元,一个 STP 文件可包含一个或多个独立 Body。
 - 单实体零件:1 Body + 1 Solid;
 - 多实体零件:1 Body + N 个 Solid;
 - 装配体:多个无拓扑关联的 Body 组合。
 - 后续 STP 读取、Body 列表展示、几何体高亮、Body 拆分操作,全部以 Body 作为操作入口。

Solid(实体)
最高层级拓扑单元,代表一块封闭、具备体积的三维刚体。日常单个实心立方体就是 1 个 Solid;模型内部有空腔时,单个 Solid 可以拥有外层外壳 Shell + 内层空腔 Shell。

Shell(壳)
由大量 Face 拼接形成的闭合外壳。实心立方体仅有 1 个 Shell;如果方块内部挖出一个通孔,Solid 就拥有外层外壳、孔洞内壁壳两层 Shell。Shell 必须封闭,不然 Solid 体积无效。

Face(面)
Shell 的构成单元,对应实体的一个个表面。普通立方体正好有 6 张 Face,分别对应上下、前后、左右六个平面;Face 底层绑定几何曲面(平面、圆柱面、球面、NURBS 曲面等)。

Loop(环)
用来限定单张 Face 的边界轮廓,一张 Face 最少拥有 1 条外环,存在开孔时会额外增加多条内环:
外环:勾勒面整体的外轮廓;
内环:刻画面上镂空小孔的边界,孔洞就是依靠内环实现;
方向约定(右手定则):沿着环行进方向,实体内部处在行进方向左侧。立方体每个平整的面不存在开孔,因此每个 Face 仅配置 1 条外环。

CoEdge(共边 / 有向边)
Edge 会被相邻的两张 Face 共同使用,CoEdge 就是 Edge 依附于单个 Face 时的方向副本。同一条 Edge 绑定两个方向相反的 CoEdge,分别适配相邻两个面的环走向。拿立方体相邻的正面、右侧面这两个面举例:二者共用一条竖直棱 Edge;正面的 Loop 沿着这条棱向上行进(对应正向 CoEdge),右侧面的 Loop 沿着这条棱向下行进(反向 CoEdge),同一条 Edge 出现两个朝向。

Edge(边)
三维空间当中的棱线段,两端衔接 Vertex,底层绑定曲线几何(直线、圆弧、NURBS 曲线等)。立方体一共有 12 条 Edge。

Vertex(顶点)
拓扑树最底层节点,代表端点,绑定三维 (x,y,z) 坐标。立方体一共 8 个 Vertex。

(2)拓扑结构:两个面组成的壳

全部继承自底层TopoDS_TShape(最基础拓扑数据基类):

  • TS = T-Solid(底层实体拓扑)
  • TF = T-Face(底层面)
  • TW = T-Wire(底层线框)
  • TE = T-Edge(底层边)
  • TV = T-Vertex(底层顶点)

Underlying Shape底层固有拓扑形状(底层形状),这是 OCCT 内部原始、不可随意改动的拓扑内核数据,固定记录着立方体最根本的拓扑从属关系:Solid → Shell → Face → Wire → Edge → Vertex。

User shapes:面向用户的形状、用户层形状,不会拷贝底层拓扑骨架,而是通过引用复用 Underlying Shape,在此之上叠加用户侧需要的方位平移、旋转、正反朝向、自定义标记这类附加属性。

(3)几何实体

描述物体“长什么样”的数学基础,它与拓扑结构共同构成完整的三维模型。

Point (点): 对应Vertex。零维几何元素,由三维空间中的坐标 (x, y, z) 唯一确定在 OCCT 中,它由 gp_Pnt 类表示,是一个轻量级的数值对象,可直接在栈上创建,不涉及内存管理。

Curve (曲线): 对应Edge。一维几何元素,由参数方程 P(t) = (x(t), y(t), z(t)) 定义。在 OCCT 中,曲线由 Geom_Curve 及其子类(如 Geom_Line, Geom_Circle, Geom_BSplineCurve)表示。

  • 曲线是边(Edge)的几何基础。一个 Edge 本质上是对一条 Curve 的引用,并附加了参数范围 [t1, t2] 来限定其在空间中的实际长度。
  • 无限性:数学上的曲线通常是无限的(如直线、圆),但通过参数范围限制,可以表示有限长度的线段或弧段。
  • 类型多样:包括解析曲线(直线、圆、椭圆)和自由曲线(NURBS、Bézier)。NURBS 曲线因其灵活性和精确性,是现代 CAD 系统的核心。
  • 方向性:曲线有内在的方向(从 t1 到 t2),这决定了 Edge 的正向。

Surface (曲面): 对应Face。二维几何元素,由双参数方程 S(u, v) = (x(u,v), y(u,v), z(u,v)) 定义。在 OCCT 中,曲面由 Geom_Surface 及其子类(如 Geom_PlaneGeom_CylindricalSurfaceGeom_BSplineSurface)表示。

  • 曲面是面(Face)的几何基础。一个 Face 是对一个 Surface 的引用,并通过一个或多个 Wire(环)来定义其在 uv 参数平面上的有效区域。例如,一个圆柱面可以被一个矩形 Wire 裁剪成一个侧面。
  • 无限性:与曲线类似,数学曲面是无限的,但通过参数域 (u_min, u_max, v_min, v_max) 和 Wire 的限制,可以表示有限的物理表面。
  • 类型多样:包括解析曲面(平面、圆柱、圆锥、球、环面)和自由曲面(NURBS 曲面)。NURBS 曲面能精确表示复杂的自由形态,是汽车、航空等领域建模的关键。
  • 法向与方向曲面有法向量,用于定义面的“朝外”或“朝内”。这在布尔运算和渲染中至关重要。

(4)BRep 与其他建模方式横向对比

建模方案实现原理优势短板适配场景
BRep 边界表示依托边界拓扑 + 几何描述实体拓扑关联性强、曲面精度高、原生适配 STEP 标准拓扑层级复杂,遍历规则繁琐工业机械 CAD、后续你的 STP 读写、Body 拆分项目
CSG 构造实体几何借助立方体、圆柱等基础几何体布尔叠加拼接建模简单直观很难构建自由曲面,复杂零件存储冗余造型规整的简单机械件
STL 三角网格大量三角形面片拼接拟合外形渲染便捷,适配 3D 打印丢失拓扑连接信息,无法精准做后续拆分、拓扑编辑可视化预览、3D 打印

2. 方向与边界规则

(1)面的法向与实体的“内外”

在拓扑结构中,面(Face)本身只是一个没有厚度的二维区域。为了判断一个 Solid(体)的内部在哪里,必须规定面的法向。

  • 黄金法则(右手定则):四指弯曲,顺着面外环的逆时针方向,此时大拇指所指的方向就是这个面的法向。在 BRep 中,面的法向(Normal)永远指向实体的外部
  • 工程意义:在进行布尔运算(如求并集)时,内核会计算面的法向。如果两个相邻面的法向都朝外,内核就知道这两个面之间是“空的”;如果法向朝内,内核就知道那是实体的内部。

(2)Loop(环)的内外与方向约定

  • 外环(Outer Wire):定义面的最外层边界。
  • 内环(Inner Wire):定义面上的孔洞。
  • 方向约定(2D 参数空间)
    在面的局部 2D 参数坐标系(UV 平面)中,遵循以下约定:
    • 外环必须是逆时针(Counter-Clockwise, CCW)
    • 内环必须是顺时针(Clockwise, CW)
  • 为什么这么规定?
    想象你在 UV 平面上沿着外环逆时针走一圈,你的左手边始终是面的“实体区域”;当你沿着内环顺时针走一圈时,你的左手边依然指向面的“实体区域”。这保证了面的实体区域永远在环的“左侧”。

(3)边的方向(Edge Orientation)

边(Edge)是有向的,它从一个顶点指向另一个顶点。边的方向由两个因素共同决定:

  • 底层几何曲线的方向:底层的 Geom_Curve 有一个参数 t ,通常从 tmin​ 到 tmax​ 增加的方向是曲线的自然正向。
  • 拓扑边的方向标记:拓扑边(TopoDS_Edge)有一个 Orientation 属性,可以是 FORWARD(正向)或 REVERSED(反向)。
    • 如果标记为 FORWARD:边的方向与底层曲线的自然方向一致。
    • 如果标记为 REVERSED:边的方向与底层曲线的自然方向相反。

(4)三者协同工作

  1. 面(Face) 决定了它所属环的“正方向”(外环逆时针,内环顺时针)。
  2. 环(Wire) 里的边,必须按照这个正方向首尾相连。
  3. 边(Edge) 的方向决定了它在底层几何曲线(Curve)上是从 tmin 走到 tmax ,还是反过来。
  4. 几何曲线(Curve) 最终提供了空间中的精确坐标。

(5)半边结构 (Half-Edge) 

当开始写代码解析 STEP 文件时,需要选择一种数据结构来存储上述关系。最经典且常用的是 半边结构 (Half-Edge Data Structure) 或其变体 径向边结构 (Radial Edge Structure)。

它将每一条逻辑上的“边”拆分为两条方向相反的“半边”。 每条半边只属于一个面。

每条半边知道:

  • 它的起点是哪个顶点。

  • 它的下一条半边是谁(在同一个面上逆时针走)。

  • 它的对边(Twin/Pair)是谁(即相邻面上的那条反向边)。

  • 它所属的面是谁。

这种结构的优势:所有的查询操作都可以在常数时间 O(1) 内完成。

  • 遍历面: 顺着 Next 指针转一圈。

  • 找邻面: 找到对边 Twin,然后找 Twin 的面。

  • 找邻点: 顺着边走。

半边结构与BRep边方向的区别:

  • 半边结构(Half-Edge)是“地图(拓扑骨架)”
    • 半边结构是一种内存数据结构。它的核心任务是解决“谁连着谁”的问题。
    • 它把一条无向边拆成两个有向的半边(比如 HE_A 和 HE_B)。HE_A 属于面 1,HE_B 属于面 2。这种结构是固定的,它只负责在内存里把点和面串起来。
  • BRep 边的方向(Orientation)是“交通规则(几何约束)”

    • 方向(Forward/Reversed)是逻辑属性。它的核心任务是满足“右手法则”(外环逆时针、内环顺时针)。

    • 它决定了我们在遍历这个半边时,底层的数学曲线(Curve)是从 tmin​ 走到 tmax​ ,还是反过来。

(6)step文件

STEP文件是一种用于在不同CAD/CAM/CAE系统之间交换三维产品模型数据的国际标准格式,其全称为“产品模型数据交换标准”,遵循ISO 10303标准。

不仅包含三维几何形状(如曲面、实体),还涵盖拓扑结构(面、边、顶点)、装配关系、材料属性、公差、制造信息(PMI)等完整的产品生命周期数据。

3.几何曲线类型

在 BRep 的几何底层,曲线(Curve) 是定义所有边缘(Edge)形状的数学基石。在 STEP 文件解析和 CAD 内核(如 OCCT)中,曲线主要分为两大类:解析曲线(Analytical Curves) 和 自由曲线(Free-form Curves)。

(1)直线

这是最基础的解析曲线。

  • 数学表示:参数方程  P(t)=P_{0}+t\cdot \vec{V} 。其中 P0P0​ 是起点,\vec{V}  是单位方向向量, t 是参数。
  • 工程特点:计算极快,没有曲率。在 STEP 文件中通常对应实体 LINE
  • OCCT 类:Geom_Line。

(2) 圆弧 (Circular Arc)

在 CAD 中,圆弧几乎总是作为“圆”的一部分出现的。

  • 数学表示:基于圆心、半径、基准轴(X轴和Z轴)来定义一个完整的圆。
  • 参数范围:这是 BRep 的核心。一个完整的圆参数范围是 [0,2π][0,2π] 。但如果是一条 90 度的圆弧,它的底层几何依然是一个完整的圆,只是拓扑上的 Edge 限制了参数范围为 [0,π/2][0,π/2] 。
  • OCCT 类:Geom_Circle。

(3)椭圆弧 (Elliptical Arc)

比圆多了一个自由度(长短轴不等),常用于机械零件的倒角或特殊轮廓。

  • 数学表示:同样基于中心、主轴、副轴和旋转轴定义一个完整的椭圆。
  • 参数范围:完整椭圆参数范围也是 [0,2π] 。椭圆弧则是截取其中一段。
  • OCCT 类:Geom_Ellipse。

(4)B-Spline 曲线 (NURBS 的基础)

这是现代 CAD 的灵魂,用于描述复杂的自由形态(如汽车外壳、鼠标曲面)。NURBS(非均匀有理 B 样条)是 B-Spline 的通用超集。

  • 数学表示:它不是用一个简单的方程表示,而是由以下四个核心要素定义的:
    • 控制点 (Control Points):一组空间中的点,定义曲线的整体走向。每个控制点只在局部一段曲线上起作用(局部支撑性)——移动一个点只影响附近的几段,远处不变。曲线通常不穿过中间控制点,但钳端(clamped)节点向量下会穿过首尾点。

    • 节点向量 (Knot Vector):参数轴 u 上的断点表,单调不减。它做两件事:1.把参数区间切成若干段,决定曲线在哪拼接;2.界定每个控制点的影响范围——第 i  个控制点只在 $[u_i, u_{i+degree+1})$ 区间内起作用。节点重复出现会降低该处连续性,重复度等于次数时曲线直接穿过对应控制点。

    • 次数 (Degree):曲线单段的多项式阶数,决定平滑上限与局部影响跨度。degree=3(Cubic)工业最常用,内节点不重复时可保证 C² 曲率连续;每段曲线由 degree+1 个控制点共同决定。

    • 权重 (Weights):每个控制点带一个权重,是 NURBS 中"有理(Rational)"的来源。全为 1 时退化为普通 B-Spline;权重不等时能精确表示圆锥曲线(圆、椭圆、抛物线),这是普通 B-Spline 做不到的。权重越大,曲线越被该控制点"拉拢"。

  • 工程特点:极其灵活。通过增加控制点或调整节点,可以局部修改曲线形状而不影响整体。STEP 文件中的 B_SPLINE_CURVE_WITH_KNOTS 或 RATIONAL_B_SPLINE_CURVE 对应的就是它。
  • OCCT 类:Geom_BSplineCurve。

段"就是节点向量把曲线切成的一段一段,每段是参数域 [uᵢ, uᵢ₊₁) 之间的那截曲线。

次数 p=3,节点向量 [0,0,0,1,2,3,4,5,5,5]

节点:  0  0  0  1  2  3  4  5  5  5
区间:       [0,1)  [1,2)  [2,3)  [3,4)  [4,5)
段:          段1     段2    段3    段4    段5

每段受 p+1 个点影响,p=3,所以 p+1=4。意思是:

段1 [0,1):受 P0, P1, P2, P3 影响        ← 4 个点
段2 [1,2):受 P1, P2, P3, P4 影响        ← 4 个点(往后挪一个)
段3 [2,3):受 P2, P3, P4, P5 影响        ← 4 个点
段4 [3,4):受 P3, P4, P5, P6 影响        ← 4 个点
...

中间那些不重复的节点(1, 2, 3, 4, 5)把参数域切成 5 个区间,每个区间对应一段曲线。这 5 段拼在一起就是整条 B 样条曲线。

无限几何与有限拓扑

在学习这些曲线时,必须时刻牢记 BRep 的“几何与拓扑分离”思想:

  • 几何层(Curve)通常是无限的或闭合的:比如 Geom_Line 是一条无限长的直线,Geom_Circle 是一个永远闭合的圆。
  • 拓扑层(Edge)是有限的:Edge 通过记录 FirstParameter 和 LastParameter(例如 t=0t=0 到 t=10t=10 ),从无限的几何曲线上“截取”出实际模型需要的那一段。

在解析 STEP 文件时,代码逻辑通常是: 读到一条 EDGE。 找到它引用的 CURVE(比如一个 CIRCLE)。 读取该 EDGE 定义的参数范围(比如 0 0 到 1.57 1.57 )。 结合两者,在内存中构建出一条实际的 90 度圆弧。

4.几何曲面类型

在 BRep 的几何底层,曲面(Surface) 是定义所有面(Face)形状的数学基石。与曲线类似,曲面也分为解析曲面(Analytical Surfaces)自由曲面(Free-form Surfaces)

(1) 平面 (Plane)

最基础的解析曲面,绝大多数机械零件都由它构成。

  • 数学表示:通常由一个基准点(Location)和一个单位法向量(Normal)定义。也可以用一般方程 Ax+By+Cz+D=0 表示。
  • 工程特点:计算最快,UV 参数空间直接映射到三维空间。
  • OCCT 类:Geom_Plane。

(2)圆柱面 (Cylindrical Surface)

  • 数学表示:由一个轴线(Axis)、半径(Radius)和基准坐标系定义。
  • 参数空间 (UV)
    • U 参数:代表绕轴旋转的角度(0 到 2π2π )。
    • V 参数:代表沿轴线方向的直线距离。
  • 工程特点:在 STEP 文件中,即使是一个只有 90 度的圆柱侧面,其底层几何依然是一个完整的圆柱面,只是 Face 限制了 U 参数的范围。
  • OCCT 类:Geom_CylindricalSurface。

(3)圆锥面 (Conical Surface)

  • 数学表示:由轴线、顶点(Apex)、半角(Semi-angle)和基准坐标系定义。
  • 参数空间 (UV):与圆柱面类似,U 代表旋转角度,V 代表沿母线方向的距离。
  • 工程特点:常用于轴类零件的过渡、螺纹或定位销孔。如果半角为 0,圆锥面就退化成了圆柱面。
  • OCCT 类:Geom_ConicalSurface。

(4)球面 (Spherical Surface)

  • 数学表示:由球心(Center)、半径(Radius)和基准坐标系定义。
  • 参数空间 (UV)
    • U 参数:代表经度(Longitude),范围 00 到 2π2π 。
    • V 参数:代表纬度(Latitude),范围 −π/2−π/2 到 π/2π/2 。
  • 工程特点:注意在两极(V = ±π/2±π/2 )处存在参数奇点(所有经线汇聚于一点),在进行 UV 网格离散化时需要特殊处理。
  • OCCT 类:Geom_SphericalSurface。

(5)环面 (Toroidal Surface)

  • 数学表示:由旋转轴、主半径(Major Radius,圆心到旋转轴的距离)和次半径(Minor Radius,管道自身的半径)定义。
  • 参数空间 (UV):U 和 V 都代表旋转角度(都是 00 到 2π2π )。U 绕大圆转,V 绕小圆转。
  • 工程特点:常用于 O 型密封圈槽、轮胎或复杂的圆角过渡。
  • OCCT 类:Geom_ToroidalSurface。

(6)B-Spline 曲面 (NURBS 的基础)

这是现代 CAD 的灵魂,用于描述极其复杂的自由形态(如汽车车身、飞机机翼、鼠标外壳)。

  • 数学表示:它不是用一个简单方程表示,而是由以下核心要素定义的:
    • 控制点网格 (Control Points Grid):沿 U、V 两个方向排列的二维点阵,定义曲面整体形态。与曲线一样具有局部支撑性——移动一个控制点只影响附近一片区域,其余不变;曲面通常不穿过中间控制点,钳端下穿过边界点。

    • 节点向量 (Knot Vectors):U、V 各一组,独立管控各自方向的分段、连续性与控制点影响范围。两组节点向量把参数域 (u,v) 切成网格状的分片,每个分片是一张小曲面片,片与片之间按节点重复度决定连续性。

    • 次数 (Degree):U、V 方向各自独立,可不同(如 $3\times3$、$3\times1$)。每个方向各自决定该方向的平滑上限与局部影响跨度;两张曲面要在某方向 C² 连续,该方向次数至少为 3 且对应节点不重复。

    • 权重 (Weights):每个控制点带一个权重,组成与控制点网格同维的权重矩阵。全为 1 时退化为普通 B-Spline 曲面;权重不等时能精确表示球面、圆柱面、圆锥面等二次曲面——这也是 STEP 中 B_SPLINE_SURFACE_WITH_KNOTSRATIONAL_B_SPLINE_SURFACE 的分界。

  • 工程特点:极其灵活,支持局部修改。STEP 文件中的 B_SPLINE_SURFACE_WITH_KNOTS 或 RATIONAL_B_SPLINE_SURFACE 对应的就是它。
  • OCCT 类:Geom_BSplineSurface。

5.参数化表示

B-Rep 里,一个实体由它的边界描述——面(Face)、边(Edge)、顶点(Vertex)。关键在于:这些几何元素不是直接用 3D 坐标定义的,而是通过参数化映射间接定义。

核心思想:所有几何都挂在参数空间上,再映射到 3D。

(1)曲线的参数化

一条 3D 空间里的曲线 C,不是存成一堆点,而是存成一个参数函数:C(u) → (x, y, z)    其中 u ∈ [u_min, u_max]。

比如 B-Spline 曲线:C(u)=\sum_{i}N_{i,p}(u)\cdot P_{i}

  • u 是参数,范围通常归一化到 [0, 1]
  • Pᵢ 是控制点(3D 坐标)
  • Nᵢ,ₚ(u) 是 B-Spline 基函数
  • 给定一个 u 值,算出一个确定的 3D 点

边(Edge)本质上就是记录"这条边对应哪条曲线 C"以及"参数范围 [u₁, u₂]"。边的两个端点就是 C(u₁) 和 C(u₂)。

(2)曲面的参数化

一张 3D 曲面 S,用一个二元参数函数:S(u, v) → (x, y, z)    其中 u ∈ [u_min, u_max], v ∈ [v_min, v_max]。

B-Spline 曲面:S(u,v)=\sum_{i}\sum_{j}N_{i,p}(u)\cdot N_{j,q}(v)\cdot P_{ij}

  • (u, v) 是参数空间里的二维坐标
  • Pᵢⱼ 是控制点网格
  • 给定一组 (u, v),算出一个 3D 点

面(Face)记录"对应哪张曲面 S"以及"参数域范围"。面的边界(Trimming)就是在参数空间里定义的——一组 (u, v) 平面上的闭合环,把曲面"裁剪"出实际使用的区域。

(3)参数空间到 3D 空间的映射

这是 B-Rep 最核心的设计:参数空间里每个点 (u, v) 都通过函数 S(u,v) 对应到 3D 曲面上唯一一个点 (x, y, z)。 参数空间的网格线 → 映射成曲面上的等参线;参数空间的区域 → 映射成曲面上一块面片。

(4)参数化表示的优势

1. 几何和拓扑分离

  • 几何(Geometry):曲面 S(u,v) 本身——"数学定义"
  • 拓扑(Topology):面、边、顶点——"哪些部分被用到、怎么连起来"
  • 同一张曲面可以被多个面引用(比如一张圆柱面被切成两段),只是裁剪域不同

2. 精确表示
不用离散成三角网格,曲线曲面用数学函数精确定义。求交点就是解方程 S₁(u₁,v₁) = S₂(u₂,v₂),不是在网格上插值。

3. 等参线天然存在
固定 v = v₀,让 u 变化,得到一条 S(u, v₀) 曲线——这就是等参线(isoparametric line)。你之前 bspline-surface.html 里画的等参线就是这个概念。

6.裁剪与参数域

(1)裁剪

在纯数学世界里,直线是无限长的,圆柱面是无限延伸的。但在工程制造中,我们只需要其中的一小段。

几何层(Geometry)是“无限”的:一个 Geom_Circle 永远是一个完美的、闭合的整圆(参数 0 0 到 2 π 2π )。一个 Geom_Plane 永远是无限大的。

拓扑层(Topology)是“有限”的:为了得到一段 90 度的圆弧,BRep 不会去修改底层的数学方程,而是直接在拓扑的 Edge 上记录一个参数域(Parameter Range),比如 [ 0 , π / 2 ] [0,π/2] 。

这就是“裁剪”的本质: 几何提供无限的数学画布,拓扑拿着剪刀,在参数轴上剪下我们需要的那一段。

(2)PCurve(参数曲线)

想象你有一个圆柱面(3D 空间),你想在这个圆柱面上切出一个斜着的椭圆孔。这个孔的边缘(Edge)在 3D 空间里是一条复杂的椭圆弧。

  • 在 3D 空间里:这条边很难用简单的方程描述,它是一条复杂的 3D 空间曲线。
  • 在 2D 参数空间里:如果你把圆柱面像贴纸一样“撕开”铺平,它变成了一个矩形平面。在这个矩形平面上,那个椭圆孔的边缘,其实就是一条简单的直线或者正弦曲线

这条在面的 2D UV 参数平面上描述 Edge 走向的曲线,就是 PCurve,因此,PCurve 也叫 2D Curve on Surface。

(3)为什么需要PCurve

  1. 降维打击:在 2D 平面上做布尔运算(比如判断两条线是否相交、求交点),比在复杂的 3D 曲面上做计算要快得多、稳定得多。
  2. 纹理与网格:当你需要给模型贴图或生成网格时,GPU 和算法都是直接在 UV 平面上操作的,PCurve 提供了精确的边界。
  3. 缝合模型:两个相邻的面共用一条边。在 3D 空间里,由于浮点数误差,这两个面算出来的边可能差了 0.000001 毫米(导致模型破面)。但在各自的 2D UV 平面上,PCurve 可以完美重合。

(4)为什么同一个几何可以有多组 Trim

这是 BRep 数据共享机制的巅峰体现。
核心法则:几何(Curve/Surface)是“公共资源”,拓扑(Edge/Face)是“私人定制”。
让我们看一个经典的工程场景:一个圆柱体和一个平面相交,切掉了一部分。

  • 底层的几何(Geom_Surface):只有一个,它是一个无限延伸的完整圆柱面。
  • 拓扑的裁剪(Trim)
    • 圆柱体的侧面(Face A):它需要圆柱面的一部分。它在 UV 平面上画了一个矩形框(比如 U: 0~ $ \pi $ , V: 0~10)。这是第一组 Trim。
    • 被切掉后剩下的顶面(Face B):如果顶面也引用了这个圆柱面的边缘,它可能会在 UV 平面上画一个完全不同的形状。这是第二组 Trim。


更极端的例子(同一个 Edge 被两个面共用):
两个面(Face 1 和 Face 2)共用一条棱(Edge),每个面的UV展开方式是由它自己的曲面类型决定的

  • 底层的几何曲线(Geom_Curve)只有一份(比如一条直线)。
  • Face 1 在自己的 UV 平面上,用一条 PCurve 描述了这条边。
  • Face 2 在自己的 UV 平面上,也用一条 PCurve 描述了这条边。
  • 这两条 PCurve 在各自的 2D 空间里可能长得完全不一样(因为两个面的 UV 展开方式不同),但它们映射回 3D 空间后,必须完美重合在同一条棱上。

7.公差与精度

在纯数学世界里,两条线要么相交,要么平行,没有中间状态。但在计算机中,所有的几何计算都依赖于浮点数。浮点数在计算时必然会产生微小的舍入误差。 想象一个立方体,它的两个相邻面(Face)应该完美地共用一条棱(Edge)。但由于浮点运算的误差,面 A 算出来的棱的坐标可能是 1.000000000000001,而面 B 算出来的棱的坐标是 0.999999999999999。如果没有公差机制,计算机就会认为这两个面之间有一条极其微小的缝隙,导致模型破面,布尔运算直接崩溃。

-Rep 中的公差机制:
在 OpenCASCADE(OCCT)等内核中,公差(Tolerance)被定义为一种“模糊区域”,用来包容这些计算误差。拓扑元素必须在这个区域内才算作“连接在一起”:

  • 顶点(Vertex)的公差:定义了一个以该点为中心、以公差值为半径的球体。只要其他几何落在这个球体内,就认为它们相交于该点。
  • 边(Edge)的公差:定义了一个以曲线为中心、以公差值为半径的管道(Pipe)
  • 面(Face)的公差:定义了一个以曲面为中心、以公差值为厚度的板(Thickness)


黄金法则:在 B-Rep 结构中,公差必须满足层级关系:Tolerance(Vertex) >= Tolerance(Edge) >= Tolerance(Face)。这确保了更小的拓扑元素(点)的包容范围能够覆盖更大的拓扑元素(边和面)的误差。

8. 数据完整性规则:欧拉公式与拓扑验证

有了公差,计算机就能把模型“拼”起来。但拼起来的模型一定是一个合法的、水密的实体吗?这就需要数学上的拓扑一致性检验

欧拉公式(Euler's Formula)

对于任何一个没有孔洞的简单封闭多面体(Simple Polyhedron),其顶点数(V)、边数(E)和面数(F)必须满足以下铁律:V−E+F=2

欧拉-庞加莱公式(Euler-Poincaré Formula)

如果模型带有孔洞(例如一个甜甜圈形状的环面),公式就需要扩展。引入亏格(g,即穿透孔的数量),公式变为:V−E+F=2−2g

CAD 内核在进行布尔运算(如合并、切割)后,会利用这些公式来检验生成的 B-Rep 结构是否合法。如果公式不成立,内核就会抛出“非流形几何(Non-manifold geometry)”的错误。

欧拉操作(Euler Operations)

为了保证在修改模型时永远不破坏欧拉公式,CAD 内核使用一套原子操作(如 MEV - Make Edge Vertex, MFE - Make Face Edge 等)。这些操作在增加或减少点、线、面时,会成对地改变 V、E、F 的数量,从而在数学上保证 V−E+FV−E+F 的值始终保持恒定。

9.圆角、倒角的拓扑变化

(1)棱角

一个长方体的棱角,从侧面看截面就是一个直角。两个平面 Face_A 和 Face_B 在棱处相交

(2)圆角-拓扑插入

它是一个插入过程。它不会删除原有的边和顶点,而是在它们之间插入新的拓扑元素来创建平滑过渡。它保留原始的两条边和它们交汇的顶点,然后在它们之间“插入”一个新的圆角面。

(3)倒角-拓扑替换

它移除原始的两条边和一个顶点,然后用一条新的直线边来连接两个面。

二、OCCT BRep API 全景

┌─────────────────────────────────────────────────────────────┐
│  G. 读写层   STEPControl_Reader/Writer · BRepTools::Read/Write  │  ← 文件 ↔ BRep
├─────────────────────────────────────────────────────────────┤
│  F. 算法层   BRepAlgoAPI_* · BRepPrimAPI_* · BRepFilletAPI_*    │  ← 布尔/基元/倒角
├─────────────────────────────────────────────────────────────┤
│  E. 构造层   BRepBuilderAPI_MakeFace/Edge/Wire/Shell/Solid      │  ← 几何 → 拓扑
├─────────────────────────────────────────────────────────────┤
│  D. 遍历层   TopExp_Explorer · TopExp::MapShapes · BRepTools    │  ← 在拓扑里走动
├─────────────────────────────────────────────────────────────┤
│  C. 桥接层   BRep_Tool · BRepAdaptor_Surface · BRepAdaptor_Curve│  ← 拓扑 ↔ 几何
├─────────────────────────────────────────────────────────────┤
│  B. 几何层   gp_* · Geom_Curve* · Geom_Surface* · Geom_BSpline* │  ← 纯数学
├─────────────────────────────────────────────────────────────┤
│  A. 拓扑层   TopoDS_Shape → Compound/.../Solid/Shell/Face/      │  ← 只管连接关系
│             Wire/Edge/Vertex                                     │
└─────────────────────────────────────────────────────────────┘

1.拓扑层 TopoDS_*

只描述"形状由哪些子形状组成、怎么连接",完全不存几何数据。它是整个 BRep 的骨架。

类/函数职责关键函数
TopoDS_Shape所有拓扑实体的基类ShapeType() 返回拓扑类型枚举;Orientation() 返回方向枚举(FORWARD/REVERSED);Location() 返回位置变换;IsNull() 判空;IsSame(other) 判是否同一 TShape+Location(不管方向);IsEqual(other) 判是否同一 TShape+Location+Orientation(最严格)
TopoDS_Compound容器,装任意形状的杂烩
TopoDS_CompSolid一组共享面的 Solid
TopoDS_Solid一个封闭实体(有体积)
TopoDS_Shell一组连接的面
TopoDS_Face一个面片(裁剪后的曲面)
TopoDS_Wire一组连接的边(闭合或开放)
TopoDS_Edge一条边(裁剪后的曲线段)
TopoDS_Vertex一个顶点
TopoDS::Face(s)基类向下转换成具体子类型TopoDS::Solid/Face/Edge/Vertex(s)TopoDS_Shape 转回子类型,类型不符会抛异常

TopoDS_Shape 的三件套

TopoDS_Shape 看起来是一个对象,实际上它内部是三个东西的组合:

  • TopoDS_TShape*    (句柄,真正存"拓扑连接关系"的核心数据)
  • TopLoc_Location    (位置变换:这个形状被平移/旋转到了哪里)
  • TopAbs_Orientation (方向:FORWARD / REVERSED / INTERNAL / EXTERNAL)

为什么这么设计?为了"共享、不复制"。

同一个 TShape(比如一个圆柱面的拓扑结构)可以被多个 TopoDS_Shape 引用,各自配不同的 Location(一个放这里、一个平移到别处)和 Orientation(正向/反向)。数据只有一份,表现出来的形状却可以很多个。这是 OCCT 节省内存的关键设计。

2.几何层 gp_* / Geom_*

纯数学定义,和拓扑无关。一个 Geom_Cylinder 就是"无限延伸圆柱面"的方程,不知道自己属于哪个 Face。分两个子层。

(1)值类型 gp_*(轻量、栈上、拷贝传递)

职责关键函数
gp_Pnt三维点 (x,y,z)X() Y() Z() 取分量;Distance(p) 算到另一点的距离
gp_Vec三维向量Coord() 取分量;Crossed(v) 叉积;Dot(v) 点积;Normalized() 单位化
gp_Dir单位方向Coord() 取分量;Angle(d) 算夹角
gp_Ax1一根轴(点+方向)Location() 取轴上点;Direction() 取方向
gp_Ax2坐标系(点+主轴+副轴)Location() 取原点;Direction() 取主轴;XDirection() 取副轴
gp_Trsf仿射变换(平移/旋转/缩放)SetTranslation(vec) 设平移;SetRotation(ax, angle) 设旋转;Multiply(t) 级联变换

(2)参数化几何 Geom_*(堆上、句柄管理 Handle(Geom_*),有参数域)

类族职责关键函数
Geom_Curve参数曲线基类Value(t) 求值取点;D1(t) 一阶导;FirstParameter() LastParameter() 参数范围
Geom_Line直线
Geom_CircleCirc() 取底层圆数据
Geom_Ellipse椭圆
Geom_BSplineCurveB 样条曲线Poles() 控制点;Knots() 节点;Degree() 次数;IsRational() 是否有权重;Weights() 权重
Geom_TrimmedCurve裁剪曲线(把无限曲线截一段)BasisCurve() 取底层曲线;FirstParameter() LastParameter() 裁剪范围
Geom_Surface参数曲面基类Value(u,v) 求值取点;D1(u,v) 一阶偏导;Bounds(umin,umax,vmin,vmax) 参数域
Geom_Plane平面
Geom_Cylinder圆柱面Cylinder() 取底层圆柱数据
Geom_Cone锥面
Geom_Sphere球面
Geom_Torus环面
Geom_BSplineSurfaceB 样条曲面Poles() 控制点网格;UKnots() VKnots() 节点;UDegree() VDegree() 次数;IsRational()Weights()

3.桥接层 BRep_Tool / BRepAdaptor_*

拓扑↔几何的粘合剂。拓扑层自己存不了几何,要靠这层"从 TopoDS 实体里把 Geom 几何掏出来"。

类/函数职责关键函数
BRep_Tool静态函数集合,从拓扑取几何Surface(face) 取 Face 的底层 Geom_SurfaceCurve(edge, first, last) 取 Edge 的底层 Geom_Curve 和参数范围;CurveOnSurface(edge, face, first, last) 取 Edge 在某 Face 参数域里的 2D pcurve;Pnt(vertex) 取 Vertex 的 3D 点
BRepAdaptor_Surface把 Face 包装成可求值/求导/查类型的曲面适配器GetType() 返回曲面类型枚举(Plane/Cylinder/BSpline...);Value(u,v) 求值;FirstU() LastU() FirstV() LastV() 参数域;DN(u,v,n) 求 n 阶导
BRepAdaptor_Curve把 Edge 包装成可求值/求导/查类型的曲线适配器GetType() 返回曲线类型枚举(Line/Circle/BSpline...);Value(t) 求值;FirstParameter() LastParameter() 参数范围;DN(t,n) 求 n 阶导

BRep_Tool 是"静态工具函数",给一个 TopoDS_Face 返回底层 Handle(Geom_Surface)BRepAdaptor_* 是"包装器",构造时吃一个 Face/Edge,之后像用 Geom_* 一样求值,但自动处理了裁剪域和位置变换。

4.遍历与查询层 TopExp_* / BRepTools_*

在拓扑结构里"走动"和"查信息"。B-Rep 是嵌套结构,要拿到所有 Face/Edge 必须遍历。

类/函数职责关键函数
TopExp_Explorer按类型遍历子形状构造 (shape, type)More() Next() Current() 迭代三件套
TopExp::MapShapes把某类型所有子形状收集到一个 Map(去重)静态函数,遍历 Explorer 会重复,MapShapes 不会
TopExp::FirstVertex LastVertex取 Edge 的首/末顶点静态函数
TopExp::CommonVertex找两条 Edge 的公共顶点静态函数
BRepTools::WireExplorer按 Wire 的连接顺序遍历 Edge(比 Explorer 更"有序")按几何连接顺序逐条走,Explorer 不保证顺序
BRepTools::Dump把形状信息打印出来(调试用)输出拓扑结构到流

(TopExp_Explorer ex(shape, TopAbs_FACE); ex.More(); ex.Next())。它按类型一层层找,不去重、不保证顺序;要按几何连接顺序走 Wire 得用 BRepTools::WireExplorer;要全局去重用 TopExp::MapShapes

与上下层关系:操作拓扑层 A,配合桥接层 C 边遍历边取几何。

5.构造层 BRepBuilderAPI_*

反向操作——从几何"造出"拓扑。前面几层都是"读",这层开始"写"。

职责关键函数
BRepBuilderAPI_MakeEdgeGeom_Curve 造 Edge构造(吃曲线/曲线+参数范围/两点)→ Edge() 返回造好的边;IsDone() 检查是否成功
BRepBuilderAPI_MakeWire从一组 Edge 造 WireAdd(edge) 逐条加;Wire() 返回;Error() 查错误
BRepBuilderAPI_MakeFaceGeom_Surface + 裁剪域造 Face构造(吃曲面/surface+wire)→ Face() 返回
BRepBuilderAPI_MakeShellGeom_Surface + 参数域造 Shell构造 → Shell()
BRepBuilderAPI_MakeSolid从 Shell 造 Solid构造(吃 Shell)→ Solid()
BRepBuilderAPI_Transform对形状做变换(配合 gp_Trsf构造(吃 trsf+shape)→ Perform() 执行 → Shape() 返回变换后的形状

这层是"几何 → 拓扑"的转换器。比如 MakeFace 输入一个 Geom_Surface(无限数学曲面)和一个 Wire(UV 空间的裁剪边界),产出一个 TopoDS_Face(裁剪后的面片)。造的过程会自动建立拓扑连接关系。

与上下层关系:吃几何层 B 的对象,产出拓扑层 A 的对象;产出的拓扑可喂给算法层 F 或读写层 G。

6.算法层 BRepAlgoAPI_* / BRepPrimAPI_* / BRepFilletAPI_*

在拓扑形状上做"真正的 CAD 运算"——布尔、基元生成、倒角。只列类名和一句话作用。

作用
BRepPrimAPI_MakeBox造长方体
BRepPrimAPI_MakeCylinder造圆柱
BRepPrimAPI_MakeSphere造球
BRepPrimAPI_MakeCone造圆锥
BRepAlgoAPI_Cut布尔差(从 A 减去 B)
BRepAlgoAPI_Common布尔交(A 和 B 的公共部分)
BRepAlgoAPI_Fuse布尔并(A 和 B 合并)
BRepAlgoAPI_Section求截面(A 和 B 的交线)
BRepFilletAPI_MakeFillet倒圆角
BRepFilletAPI_MakeChamfer倒直角
BRepOffsetAPI_MakePipe沿路径扫掠成实体
BRepOffsetAPI_MakeThruSections放样(穿过若干截面造实体)

这层输入拓扑、输出拓扑,内部会重建拓扑连接关系。布尔运算是最重的操作,也是最容易出问题的(精度、非流形结果等)。

与上下层关系:输入拓扑层 A 的形状,输出新的拓扑层 A 形状;内部依赖桥接层 C 访问几何。

7.读写层 STEPControl_* / BRepTools

文件 ↔ BRep 的转换。STEP/IGES 是交换格式,BRep 是 OCCT 原生格式。

类/函数职责关键函数
STEPControl_Reader读 STEP → TopoDS_ShapeReadFile(path) 解析 STEP 文本为 STEP 实体;TransferRoots() 把 STEP 实体翻译成 BRep 拓扑;OneShape() 返回打包后的根形状;NbRootsForTransfer() 根实体数量
STEPControl_WriterTopoDS_Shape → 写 STEPTransfer(shape, mode) 把 BRep 翻译成 STEP 实体;Write(path) 写成 .step 文件
IGESControl_Reader/WriterIGES 读写接口同 STEPControl_*
BRepTools::Read读 OCCT 原生 BRep 文本格式Read(shape, istream, builder)
BRepTools::Write写 OCCT 原生 BRep 文本格式Write(shape, ostream) 输出可读的拓扑+几何文本,调试利器

ReadFile 只解析文本,TransferRoots 才真正产生 TopoDS_Shape——这两步是分离的。BRepTools::Write 输出的是 OCCT 私有的文本 BRep 格式(不是 STEP),但因为是纯文本且含完整拓扑+几何信息,调试时比 STEP 方便得多。

与上下层关系:读方向——文件 → 拓扑层 A(BRep);写方向——拓扑层 A → 文件。是整个工作链的入口和出口。

完整调用流:

读进来:
  linkrods.step
       │  STEPControl_Reader::ReadFile         ── G.读写层(解析文本为STEP实体)
       │  STEPControl_Reader::TransferRoots    ── G.读写层(STEP实体→BRep拓扑)
       ▼
  TopoDS_Shape                                ── A.拓扑层(拿到拓扑骨架)
       │  TopExp_Explorer(shape, TopAbs_SOLID) ── D.遍历层
       ▼
  TopoDS_Solid → Explorer(solid, TopAbs_FACE)  ── D.遍历层
       │  BRep_Tool::Surface(face)            ── C.桥接层(取底层几何)
       │  BRepAdaptor_Surface(face)           ── C.桥接层(包装成可求值)
       ▼
  Geom_Surface / Geom_Cylinder / ...         ── B.几何层(Value/DN 求值求导)

中间可插入算法层:
  TopoDS_Shape ──BRepAlgoAPI_Fuse──► 另一个 Shape ──► 新 TopoDS_Shape  ── F.算法层
              └─BRepAlgoAPI_Cut─┘
              └─BRepPrimAPI_MakeCylinder─┘(也可以从零造基元,不经读文件)

写出去(两条路):
  路线① 读改写:TopoDS_Shape(读来的或算法产出的)
       │  STEPControl_Writer::Transfer        ── G.读写层(BRep→STEP实体)
       │  STEPControl_Writer::Write           ── G.读写层(写成 .step)
       ▼
  output.step

  路线② 从零造再写出:先经几何层+构造层造拓扑,再写出去
  gp_Pnt / gp_Ax / gp_Trsf                   ── B.几何层(值类型,搭坐标和变换)
       │  Geom_Cylinder / Geom_BSplineSurface ── B.几何层(造参数化几何)
       ▼
  BRepBuilderAPI_MakeFace(surface, wire)     ── E.构造层(几何→拓扑Face)
  BRepBuilderAPI_MakeEdge(curve)             ── E.构造层(曲线→拓扑Edge)
  BRepBuilderAPI_MakeWire(edges)             ── E.构造层
  BRepBuilderAPI_MakeSolid(shell)            ── E.构造层
       ▼
  TopoDS_Solid                               ── A.拓扑层(造好的实体)
       │  BRepAlgoAPI_Cut / Fuse(可选)      ── F.算法层(可对造好的实体再布尔)
       │  STEPControl_Writer::Transfer/Write ── G.读写层(BRep→STEP实体→文件)
       ▼
  output.step

  旁支:纯文本调试输出(不经STEP)
  TopoDS_Shape ──BRepTools::Write──► shape.brep  ── G.读写层(OCCT原生文本格式,调试用)      

8.底层机制补充

(1)句柄机制 Handle(Geom_*)

OCCT 自己的智能指针,管理堆上几何对象的生存期。OCCT 的 Geom_* 对象不能直接放栈上,必须用 Handle 包着用。

写法含义
Handle(Geom_Surface)类型,"一个指向 Geom_Surface 的句柄"
Handle(Geom_Surface) surf = BRep_Tool::Surface(face)从 Face 取出底层曲面,返回值是 Handle
surf.IsNull()判空(底层对象不存在时为 true)
surf->Value(u, v)调底层对象的方法(用 -> 不是 .
Handle(Geom_Plane)::DownCast(surf)向下转型:从基类 Geom_Surface 转成 Geom_Plane,类型不符返回 Null

关键认知

  • 看到 Handle(...) 就是 OCCT 智能指针,不是裸指针,不用手动 delete。
  • 赋值是浅拷贝——两个 Handle 指向同一份对象,引用计数加一。
  • 几何对象和拓扑对象分开管:Geom_* 用 Handle,TopoDS_Shape 是值类型(内部才用 Handle 引用 TShape)。
  • 要从基类转子类(Geom_Surface → Geom_Plane)用 DownCast,不能直接 C 风格强转,不匹配返回 Null 不会崩。

与七层关系:贯穿 B(Geom_* 全是 Handle)、C(BRep_Tool 返回 Handle)、A(TopoDS_Shape 内部的 TShape 是 Handle)。

(2)TShape / Location / Orientation 三件套深入

成份存什么共享情况怎么影响几何
TShape拓扑连接关系 + 挂着的几何引用多个 Shape 常共享同一份决定"是什么形状"
Location位置变换(TopLoc_Location,内部是 gp_Trsf多个 Shape 可配不同 Location决定"放在哪里"
Orientation方向枚举(FORWARD/REVERSED/...)多个 Shape 可配不同 Orientation决定"正向还是反向用"

关键函数对比:

函数判断条件用途
a.IsEqual(b)同 TShape + 同 Location + 同 Orientation最严格,"完全同一个"
a.IsSame(b)同 TShape + 同 Location(不管 Orientation)判断"是不是同一个面/边",方向不重要时用
a.TShape() == b.TShape()只看 TShape 指针判断"是不是共享同一份底层数据"(最宽松)

关键认知:Location 非空时取几何要不要手动变换

这是最容易踩的坑。BRep_Tool::Surface(face) 返回的 Geom_Surface未应用 Location 的原始几何。如果 face.Location() 非空(形状被平移/旋转过),你拿到的曲面还在"原始位置",要得到实际位置的几何得自己应用变换:

Handle(Geom_Surface) surf = BRep_Tool::Surface(face);          // 原始几何(未变换)
TopLoc_Location loc = face.Location();
if (!loc.IsIdentity()) {
    surf = Handle(Geom_Surface)::DownCast(   // 复制一份再变换,不改原始数据
        surf->Transformed(loc.Transformation()));
}
// 现在 surf 才是"实际位置"的曲面

BRepAdaptor_Surface(face)自动处理 Location——这是包装器比直接取 Geom_* 省心的地方。

与七层关系:这是拓扑层 A 的内部机制,影响怎么取几何(C 层)和怎么比较形状。

(3)精度与容差 Precision::* / BRep_Tool::Tolerance

来源函数/常量作用
PrecisionConfusion()点重合容差,默认 1e-7(毫米单位下即 0.0001 微米)。两个点距离小于这个值就算同一个点
PrecisionAngular()角度容差,默认 1e-12 弧度。两个方向夹角小于这个值就算平行
PrecisionIntersection()求交容差,默认 1e-10,比 Confusion 更严
BRep_ToolTolerance(face)这个 Face 自己的容差,各实体可不同(STEP 文件里带进来)
BRep_ToolTolerance(edge)这个 Edge 自己的容差
gp_PntIsEqual(p, tol)判两点是否重合,用指定容差

关键认知

  • 别用 == 比较几何量p1 == p2 是逐分量精确比较,浮点误差下几乎永远 false。要用 p1.IsEqual(p2, Precision::Confusion())
  • 容差是局部的。每个 Face/Edge 有自己的 Tolerance,STEP 文件带进来多少就是多少。STEP 的 AP242 要求所有实体的精度在某个范围内,但实际文件良莠不齐。
  • 布尔运算对容差敏感。两个面本该相切,如果各自 Tolerance 太大或太小,布尔可能算不出结果或产生缝隙。BRepAlgoAPI_* 内部会用容差做贴合判断。
  • 单位约定。OCCT 本身没有单位,但 STEP 文件通常带毫米。容差 1e-7 在毫米单位下是极小值;如果你的模型是微米级特征,这个默认容差可能不够。

与七层关系:贯穿所有涉及几何比较和求交的层——桥接层取几何比较、算法层布尔运算、读写层读写时的精度转换都依赖容差。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值