从外部 CAD 系统导入的模型,几乎总会带着小毛病:顶点不重合、面有退化边、缝合处缝隙、容差超标......这些缺陷会让后续的布尔、网格化、渲染出问题。
SMLib 提供两套修复机制:heal_brep (几何修复)和 usd.heal_file(USD 文件结构修复)。这篇把两者讲清楚,并给出实战代码。
一、先搞清楚两个 API 的分工
| API | 修什么 | 输入/输出 |
|---|---|---|
sm.heal_brep(brep) |
修复 BRep 的几何/拓扑缺陷(顶点、边、面、容差、缝) | 传入 Brep,原地修改 |
usd_brep.usd.heal_file(src, dst) |
修复 USD 文件里的 BrepArray 定义(结构层面) | 输入/输出 USD 文件路径 |
记忆:
heal_brep修"几何",heal_file修"文件结构"。两者可以配合使用。
二、heal_brep:几何修复
2.1 基本用法
python
import usd_brep as sm
# 从 USD 导入外部模型(heal 参数可自动修复,见 §3)
breps = sm.usd.import_breps("input.usdc", heal=False)
brep = breps[0]
# 手动修复
sm.heal_brep(brep) # 原地修复
# 修复后必须验证!
print(sm.is_manifold_solid(brep)) # 是否为流形实体
print(sm.compute_volume(brep)) # 体积是否合理
2.2 官方实现能修的(SmApiHeal.h)
| 修复项 | 说明 |
|---|---|
| 重合顶点合并 | 把位置重合的顶点合并 |
| 退化面/边移除 | 删除零面积/零长度的退化拓扑 |
| 容差调整 | 按实测缝隙调整实体容差 |
| 周期缝移动 | 处理周期曲面的 seam 位置 |
| 壳/区域组织修复 | 部分 sheet 与 region 组织问题 |
2.3 官方明确修不了的(重要!)
- 通用几何缝隙闭合(general gap closure)
- 重合边修复(coincident-edge repair)
- 漏检的边相交修复
- 坏环修复(broken-loop repair,因分类/修复不可靠被禁用)
- 未包含边的处理只调整缓存状态
⚠️ 官方警告:"成功的返回不代表所有缺陷都已修复"------必须自己验证结果。
三、USD 导入时的自动修复(heal 参数)
SMLib 的 USD 导入接口提供 heal 参数:
| 接口 | 默认值 |
|---|---|
C:SmApiUsdImportBreps / SmApiUsdImportBrep |
默认开启 |
Python:usd.import_breps(..., heal=False) |
默认关闭 |
注意两个"坑":
- Python 默认不修复 :导入外部模型时需显式传
heal=True; - 修复作用于每个导入的 BRep:即使是你自己用 SMLib 生成的 USD 也会被修复------因为桥接层不保留 CAD 来源标记,healer 无法自动跳过。
python
# 导入外部来源的模型:开启自动修复
breps = sm.usd.import_breps("external_model.usdc", heal=True)
四、usd.heal_file:文件结构修复
4.1 用法
python
import usd_brep
# 修复 USD 文件中的 BrepArray 定义,输出到新文件
usd_brep.usd.heal_file("input.usdc", "input_healed.usdc")
4.2 它具体做什么
- 修复当前 USD 组合所用图层中的 BrepArray 定义;
- 保留图层、引用(references)、原生实例(native instances)、变换(transforms)与材质(materials)。
4.3 什么时候用
- 收到别人给的 USD 文件,BrepArray 定义不完整/不一致;
- 用其他工具(非 SMLib)生成/修改过 USD 里的 BRep 数据;
- 想在重新导入 SMLib 前,先把文件结构"洗干净"。
官方提示:纯资产生成场景不建议走 BRep↔USD 往返(有精度归一化损失),
heal_file更适合"接手外部文件"的场景。
五、实战流程:修复一个外部导入模型
python
import usd_brep as sm
# ① 修复文件结构(若文件来源可疑)
sm.usd.heal_file("raw/import.usdc", "work/import_healed.usdc")
# ② 导入并自动几何修复
breps = sm.usd.import_breps("work/import_healed.usdc", heal=True)
# ③ 逐个验证
for i, b in enumerate(breps):
ok = sm.is_manifold_solid(b)
vol = sm.compute_volume(b)
print(f"BRep[{i}]: manifold={ok}, volume={vol:.4f}")
# ④ 对仍有问题的 BRep 手动再修一次
for b in breps:
if not sm.is_manifold_solid(b):
sm.heal_brep(b) # 再试一次
print("二次修复后:", sm.is_manifold_solid(b))
六、已知问题(官方 KNOWN_ISSUES.md)
| 问题 | 说明 | 应对 |
|---|---|---|
heal_brep 可能"假成功" |
修复阶段失败时不报错(含 seam 插入) | 用 is_manifold_solid() 或 brep_geometry_validator 验证 |
| 闭合曲面缝修复错误 | 圆环/球/圆柱等周期曲面,缺缝/合缝时可能误修(多来自其他 CAD 系统) | 无现成 workaround,需人工验证 |
| 缝附近容差过紧 | 边-面缝隙可能测错侧,把容差收得过紧 | 验证后必要时手动调容差 |
| 极点穿越检测冲突 | 检测器与边拆分器在端点容差上不一致(会跳过该候选) | 缺陷会持续标记,待 NVIDIA 修复 |
七、修复决策表(官方建议)
| 来源 | 要不要修 | 原因 |
|---|---|---|
| 用 SM_API 自己生成 | 通常不用 | 内核生成的几何是干净的 |
| 外部导入(USD/其他 CAD) | 建议 heal=True |
尝试修复;但修复会改变拓扑与容差 |
| SMLib 自己生成的 USD | 通常不用 | 本来干净,且修复不会自动跳过 |
| 布尔运算结果 | 通常不用 | 布尔输出拓扑合法 |
| 手动改过拓扑之后 | 需要 | 人工编辑容易引入不一致 |
八、一句话总结
heal_brep修几何(但只修一部分,且会"假成功")、heal_file修文件结构;外部导入记得开heal=True,修完必须用is_manifold_solid/ 体积 / 几何验证器复核。
系列文章
SMLib 系列共 6 篇,本篇为第 6 篇,可互相跳转:
- 第 1 篇:《NVIDIA 开源 CAD 内核 SMLib:USD BRep 里有什么、能怎么用》
- 第 2 篇:《Agent 如何用 SMLib 做 CAD 创作:从 AGENTS.md 到 text-to-3D 流水线》
- 第 3 篇:《SMLib 五层架构深度解析》
- 第 4 篇:《SMLib Python API 实战:用 _omni_solid 建模的 10 个常用操作》
- 第 5 篇:《SMLib vs OpenCASCADE:2026 开源 CAD 内核怎么选?》
- 第 6 篇(本文):《SMLib 的 usd.heal_file:STEP/IGES 导入模型修复实战》
仓库:
https://github.com/NVIDIA-Omniverse/usd-brep(Apache 2.0,C++ / Python)