2.网格划分底层原理
网格划分(Tessellation曲面细分)底层原理
先分清两个名词,工业CAD里很容易混淆:
- Tessellation(曲面离散/网格化):把B‑Rep的解析曲面(球面、NURBS曲面)切成三角面片,给渲染显示用,就是OCCT给VTK喂三角数据的这个过程,我们现在讲的就是这个。
- 有限元网格划分(FEM Mesh):仿真求解用,生成四面体/六面体,给力学仿真算应力,这是另外一套算法,不要和渲染网格搞混。
你问的:为什么有的地方密、有的地方疏,能不能调,调的标准是什么,代码凭什么知道切多细,全部围绕渲染曲面离散Tessellation来讲。
1. 代码凭什么决定在哪里切、切多细?
B‑Rep里面每一张面,都是数学方程描述(NURBS曲面、圆柱面、球面),没有自带三角形。 算法核心思想:用三角形去逼近真实曲面,控制「三角面片和真实曲面之间的最大误差」。
核心判定指标:弦高误差(Chord Height Tolerance,弦高公差)
- 想象一段圆弧:用一条直线弦连接圆弧两个端点。圆弧和这条直线之间的最大距离,就叫弦高。
- 弦高越大:直线离真实曲面偏差越大,肉眼看就会有明显棱角。
- 算法规则:只要当前这片三角形,和原始曲面的弦高超过设定阈值,就必须继续切割;小于阈值,就停止切割。
举个直观例子:
-
平面:平面本身就是平直。三角面片贴上去之后,弦高永远=0,不需要切很多,少数几个大三角就搞定,网格稀疏。
-
曲率很大的圆角、曲面拐角:曲面弯得厉害。大三角贴上去弦高会超标,算法就会不断递归切小三角,网格变稠密。
✅这就是你看到现象的根源:曲率越高,网格越密;越平的面,网格越稀疏。
补充第二个约束:最大边长
光靠弦高还不够。比如一个巨大平缓的球面,整体曲率很小,弦高达标,但是单个三角会变得巨大,视图缩放之后观感很差。 所以算法一般是两套约束同时生效:
- 弦高公差(优先,控制曲面逼近误差)
- 三角面片最大边长(限制单个三角不能无限大) 只要任意一个条件触发,就继续细分。
2. 细分是怎么执行的(代码大致逻辑,递归思路)
以OCCT的BRepMesh_IncrementalMesh(OCCT做网格化的核心类)为例: 伪代码逻辑,方便理解:
输入:一张B‑Rep曲面,全局弦高公差max_chord_height,三角最大边长max_edge_len
函数subdivide(曲面,三角片):
1.计算这个三角面片,到原始解析曲面的【弦高误差】
2.计算三角三条边的长度
3.如果 弦高 > 允许公差 OR 边长 >最大边长:
将这个三角形切分成2个/4个更小三角形
对每一个新的小三角,递归调用subdivide()
4.否则:
停止细分,保留这个三角,输出到网格
不是均匀切!不是把曲面死板切成N×N格子。是自适应细分:弯的地方切碎,平坦地方少切。这就是“疏密不一样”。
⚠️注意:NURBS曲面还有参数空间,算法很多时候是在曲面uv参数域做细分,再映射回三维空间坐标,不是直接在3D空间切。
3. 能不能人为调控?怎么调?
完全可以调控,OCCT、VTK都开放参数。 OCCT中核心的两个参数:
LinearDeflection线性偏差,就是弦高公差,最重要参数AngularDeflection角度偏差:相邻三角法线夹角阈值;两个三角法线偏差超过这个角度,强制细分。专门处理圆角曲面。
行为表现:
- 把
LinearDeflection调小:允许的最大误差更小,整体网格变密,三角数量暴涨,曲面光滑,内存、GPU负载上升。 - 调大:三角少,速度快,但是圆角位置会出现明显“多边形棱角”。
工程坑:很多新人直接写死一个固定0.1的偏差。但是模型尺寸有大有小!一个1000mm的大零件和一个1mm小零件,同一个绝对公差,效果天差地别。 所以很多软件会使用相对偏差:公差 = 模型包围盒尺寸 × 比例系数,按模型大小自动缩放。
4. 调控标准:调到什么程度才算合适?
没有万能固定数值,分两类目标:可视化显示 vs 导出STL给3D打印/仿真
①目标:软件界面可视化(绝大多数工业软件场景)
目的:肉眼看不出棱角,同时三角数量不能爆炸,保证交互拖动不卡顿。
- 肉眼观察准则:正常视图下,人眼分辨不出曲面的锯齿棱角;把模型放大到局部细节,圆角也看不出多边形台阶。
- 代价约束:三角总数量不能过高。比如一个装配体,总三角超过几百万之后,拖拽旋转界面就会明显掉帧卡顿。
实践经验:不要追求数学上无限精确,人眼不可见的误差就是可以接受的误差。 如果误差小到人眼看不见,再继续加密网格只会白白消耗性能,没有收益。
②目标:导出STL用于3D打印 /仿真
需要更高网格精度,公差要结合实际物理尺寸。 比如打印0.05mm精度的零件,你的弦高公差就要远小于打印精度,不然打印出来圆角是多边形。
反面两种坏情况
- 公差太小:三角爆炸。一个普通零件直接生成上千万三角,内存暴涨,VTK渲染卡顿,鼠标拖拽延迟。
- 公差太大:圆角曲面变成多边形棱角,视觉失真;导出STL做仿真,几何形状失真,后续仿真结果出错。
5.重要的现实局限
-
自适应细分是每一张B‑Rep面独立运算 两个相邻面,一个平面、一个圆角面,各自细分,会出现:两个面交界处,两边三角顶点无法完全对齐。 👉于是就会出现:网格缝隙。
注意:这是网格层面的缝隙,不是底层B‑Rep拓扑缝隙。原始B‑Rep拓扑是完好的,仅仅网格化之后两套三角顶点没有对上。渲染时会出现一闪一闪的黑线,Z‑fighting闪烁。工业软件经常遇到这个bug。
-
自适应细分只针对渲染网格,不会修改底层B‑Rep。 调大/调小细分参数,只改变输出三角,原始曲面方程纹丝不动。
6.串联回你整条技术链路
B‑Rep精确曲面(OCCT CPU)
↓ 传入:弦高公差、角度公差、最大边长
自适应细分Tessellation(递归判断弦高误差,弯处密、平处疏)
↓输出疏密不等的三角面片
VTK接收网格 → OpenGL → GPU渲染
7.补充一个容易混淆点
前面讲的是OCCT的BRepMesh,B‑Rep曲面离散成三角用于显示。 有限元仿真软件的网格划分(ANSYS之类)是另一套算法:不仅考虑曲率,还要考虑应力梯度,应力集中区域网格进一步加密,输出四面体/六面体单元,用来数值求解,不是给显卡看的。不要把两者混在一起。

浙公网安备 33010602011771号