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_Plane, Geom_CylindricalSurface, Geom_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)三者协同工作
- 面(Face) 决定了它所属环的“正方向”(外环逆时针,内环顺时针)。
- 环(Wire) 里的边,必须按照这个正方向首尾相连。
- 边(Edge) 的方向决定了它在底层几何曲线(Curve)上是从 tmin 走到 tmax ,还是反过来。
- 几何曲线(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)直线
这是最基础的解析曲线。
- 数学表示:参数方程
。其中 P0P0 是起点,
是单位方向向量, 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 个控制点只在
区间内起作用。节点重复出现会降低该处连续性,重复度等于次数时曲线直接穿过对应控制点。
-
次数 (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_KNOTS与RATIONAL_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 曲线:
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 曲面:
(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
- 降维打击:在 2D 平面上做布尔运算(比如判断两条线是否相交、求交点),比在复杂的 3D 曲面上做计算要快得多、稳定得多。
- 纹理与网格:当你需要给模型贴图或生成网格时,GPU 和算法都是直接在 UV 平面上操作的,PCurve 提供了精确的边界。
- 缝合模型:两个相邻的面共用一条边。在 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_Circle | 圆 | Circ() 取底层圆数据 |
Geom_Ellipse | 椭圆 | — |
Geom_BSplineCurve | B 样条曲线 | 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_BSplineSurface | B 样条曲面 | Poles() 控制点网格;UKnots() VKnots() 节点;UDegree() VDegree() 次数;IsRational();Weights() |
3.桥接层 BRep_Tool / BRepAdaptor_*
拓扑↔几何的粘合剂。拓扑层自己存不了几何,要靠这层"从 TopoDS 实体里把 Geom 几何掏出来"。
| 类/函数 | 职责 | 关键函数 |
|---|---|---|
BRep_Tool | 静态函数集合,从拓扑取几何 | Surface(face) 取 Face 的底层 Geom_Surface;Curve(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_MakeEdge | 从 Geom_Curve 造 Edge | 构造(吃曲线/曲线+参数范围/两点)→ Edge() 返回造好的边;IsDone() 检查是否成功 |
BRepBuilderAPI_MakeWire | 从一组 Edge 造 Wire | Add(edge) 逐条加;Wire() 返回;Error() 查错误 |
BRepBuilderAPI_MakeFace | 从 Geom_Surface + 裁剪域造 Face | 构造(吃曲面/surface+wire)→ Face() 返回 |
BRepBuilderAPI_MakeShell | 从 Geom_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_Shape | ReadFile(path) 解析 STEP 文本为 STEP 实体;TransferRoots() 把 STEP 实体翻译成 BRep 拓扑;OneShape() 返回打包后的根形状;NbRootsForTransfer() 根实体数量 |
STEPControl_Writer | TopoDS_Shape → 写 STEP | Transfer(shape, mode) 把 BRep 翻译成 STEP 实体;Write(path) 写成 .step 文件 |
IGESControl_Reader/Writer | IGES 读写 | 接口同 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
| 来源 | 函数/常量 | 作用 |
|---|---|---|
Precision | Confusion() | 点重合容差,默认 1e-7(毫米单位下即 0.0001 微米)。两个点距离小于这个值就算同一个点 |
Precision | Angular() | 角度容差,默认 1e-12 弧度。两个方向夹角小于这个值就算平行 |
Precision | Intersection() | 求交容差,默认 1e-10,比 Confusion 更严 |
BRep_Tool | Tolerance(face) | 这个 Face 自己的容差,各实体可不同(STEP 文件里带进来) |
BRep_Tool | Tolerance(edge) | 这个 Edge 自己的容差 |
gp_Pnt | IsEqual(p, tol) | 判两点是否重合,用指定容差 |
关键认知
- 别用
==比较几何量。p1 == p2是逐分量精确比较,浮点误差下几乎永远 false。要用p1.IsEqual(p2, Precision::Confusion())。 - 容差是局部的。每个 Face/Edge 有自己的
Tolerance,STEP 文件带进来多少就是多少。STEP 的 AP242 要求所有实体的精度在某个范围内,但实际文件良莠不齐。 - 布尔运算对容差敏感。两个面本该相切,如果各自 Tolerance 太大或太小,布尔可能算不出结果或产生缝隙。
BRepAlgoAPI_*内部会用容差做贴合判断。 - 单位约定。OCCT 本身没有单位,但 STEP 文件通常带毫米。容差
1e-7在毫米单位下是极小值;如果你的模型是微米级特征,这个默认容差可能不够。
与七层关系:贯穿所有涉及几何比较和求交的层——桥接层取几何比较、算法层布尔运算、读写层读写时的精度转换都依赖容差。

540

被折叠的 条评论
为什么被折叠?



