上一篇讲了 SMLib 怎么用(《Agent 如何用 SMLib 做 CAD 创作》)。这篇往底层走:这个开源 CAD 内核到底是怎么组织的? 为什么它要拆成五层?每一层负责什么?
答案藏在仓库的 AGENTS.md 与 .agents/docs/usd_brep_libraries.md 里------官方文档对分层的描述非常清晰,本文把它们整理成一张完整的架构图。
一、五层架构总览
┌─────────────────────────────────────────────┐
│ SmPyLib(_omni_solid) │ Python 绑定(pybind11)
├─────────────────────────────────────────────┤
│ SM_API_USD │ BRep ↔ USD 导入导出
├─────────────────────────────────────────────┤
│ BREP_STAGING / BREP_USD_DATA / │ source-neutral 桥接库
│ USD_BREP_UTILS(内部转换) │ (不依赖任何 CAD 内核)
├─────────────────────────────────────────────┤
│ SM_API │ 稳定 C 风格 C++ API(SmApi*)
├─────────────────────────────────────────────┤
│ SMLib │ 核心 C++ 几何/拓扑内核
└─────────────────────────────────────────────┘
划分依据:
AGENTS.md的 Architecture 章节 +.agents/docs/usd_brep_libraries.md的桥接库说明。
二、逐层拆解
1️⃣ SMLib(核心 C++ 内核)
source/SMLib/------所有几何与拓扑类、以及操作算法都在这里。
| 关键类型 | 作用 |
|---|---|
SmBrep |
一个实体(BRep) |
SmShell / SmFace / SmEdge / SmVertex |
拓扑实体(壳/面/边/点) |
SmSurface / SmBSplineCurve |
几何定义(NURBS 曲面/曲线) |
SmContext |
内部内存管理上下文 |
特点:数学上精确、分辨率无关(不是多边形网格);拓扑自带邻接关系(哪个面共享哪条边)。
2️⃣ SM_API(稳定 C 风格 C++ API)
source/SM_API/------把常用操作包装成简单函数,函数命名统一为 SmApi*。这是 C++ 用户的首选入口,也是"稳定 API"边界(内核内部结构变化不影响这层)。
头文件即功能地图:
| 头文件 | 负责 |
|---|---|
SmApiPrimitives.h |
图元:Box / Sphere / Cone / Cylinder / Torus / Pyramid / 各种 partial 图元 / 皮肤/混合体 |
SmApiBrep.h |
布尔、扫掠、镶嵌、裁剪、缝合、圆角、偏移/抽壳 |
SmApiCurves.h |
曲线创建/偏移/求值/去节点 |
SmApiSurfaces.h |
曲面创建(拉伸/扫掠/直纹/旋转/皮肤/偏移) |
SmApiFillets.h |
圆角、倒角、移除圆角 |
SmApiPolygons.h |
多边形网格布尔、流形/体积 |
SmApiIntersectors.h |
曲线/曲面/面/BRep 相交 |
SmApiTrimmedSurfaces.h |
曲线裁剪、投影裁剪、平面面 |
SmApiQueries.h |
只读查询:最近点、拓扑查表、包围盒、体积... |
3️⃣ SM_API_USD(USD 导入导出)
source/SM_API_USD/------BRep 与 OpenUSD 文件(.usda/.usdc/.usd)互转。
- BRep 数据以自定义
BrepArrayschema 存储(beside 标准 USD prim) - 对应
omniSolidschema(source/schema/omniSolid/resources/,无代码 schema) - 提供
usd.heal_file(修复读入实体不一致)
4️⃣ BREP_STAGING / BREP_USD_DATA / USD_BREP_UTILS(source-neutral 桥接库)
这是架构里最容易被忽略、但设计最讲究的一层 ------三个不依赖任何建模内核的库:
| 库 | 职责 |
|---|---|
| BREP_STAGING | 源中立的 BREP 暂存模型 + 构建器 + USD 写入器(StagedBrepUsdWriter::WriteBrepArrayPrim)。关键类:BrepStagingState(按面的 UV 域、面/环/edgeuse、壳/区域、曲面/曲线/顶点)、BrepStagingBuilder(AddFace 等) |
| BREP_USD_DATA | 打包数组 + omniSolid schema 的读写(BrepWriteToUsdStage、BrepReadFromUsd*) |
| USD_BREP_UTILS | USD 侧分析:UsdBrepView 遍历、几何求值、拓扑查询 |
为什么重要 :任何 CAD 导入器(OCCT .brep、第三方 CAD)都通过各自的 adapter 把几何/拓扑喂进 source-neutral 记录,然后共享同一套 BrepArray 序列化。桥接库的公开 API 里不出现任何内核或 CAD 导入器类型(例如不含 OCCT 类型)。
5️⃣ SmPyLib(_omni_solid,Python 绑定)
source/SmPyLib/------通过 pybind11 把 SM_API 与 SM_API_USD 暴露给 Python,模块名 _omni_solid。
额外提供:
- 镶嵌到
PolyBrep(精确 BRep → 多边形网格) - 多边形网格布尔
对 Agent/脚本来说,这一层就是全部 :
import usd_brep as sm,几何操作都是sm.*调用。
三、BRep ↔ USD 的完整数据流
.agents/docs/usd_brep_libraries.md 给出了双向流程:
【写:BRep → USD】
源几何(OCCT .brep / 第三方 CAD)
│ (各自的 source adapter)
▼
source-neutral staging records
│ BREP_STAGING(BrepStagingState + builders)
▼
StagedBrepUsdWriter::WriteBrepArrayPrim()
│ 构建 UsdBrepArrayData
▼
BREP_USD_DATA(打包数组 + omniSolid schema)
│ BrepWriteToUsdStage()
▼
USD `BrepArray` prim
【读 + 分析:USD → 几何】
USD `BrepArray` prim
│ BREP_USD_DATA(BrepReadFromUsd*)
▼
USD_BREP_UTILS(UsdBrepView 遍历 / 几何求值 / 拓扑查询)
四、为什么要这样分层(设计考量)
| 设计 | 收益 |
|---|---|
| 内核与稳定 API 分离 | 内核可演进(内部重构),SM_API 保证用户代码不碎 |
| source-neutral 桥接层 | 换 CAD 导入器(OCCT/其他)不用改序列化;BRepArray 格式统一 |
| USD 作为交换层 | 与 Omniverse/OpenUSD 生态互通,资产在管线间流转 |
| Python 绑定覆盖全链路 | 脚本/Agent 无需编译 C++,开发效率高 |
| 精确几何 + 镶嵌分离 | 内核保持精确,渲染/展示时再按容差镶嵌(chord-height/角度) |
五、从架构看使用建议
| 你的角色 | 应该用哪层 |
|---|---|
| 写 Python 脚本 / Agent | _omni_solid (import usd_brep as sm) |
| 写 C++ 应用 | SM_API(SmApi* 函数,稳定边界) |
| 做 USD 资产生成 | _omni_solid + SM_API_USD(或直接用参考脚本 example_generate_asset.py) |
| 想给 SMLib 接新 CAD 格式 | 写 source adapter + BREP_STAGING 记录(不要碰桥接库内部) |
| 调试拓扑/内核问题 | _smlib_dev(调试 API,见 dev_topology 指南) |
六、一句话总结
SMLib 的架构 = 精确内核(SMLib)+ 稳定门面(SM_API)+ 交换格式(USD/BrepArray)+ 中立桥接(BREP_*)+ 脚本入口(SmPyLib)。 每一层解决一个边界问题,合起来才让"CAD 内核"能被 Agent、C++ 应用和 USD 管线同时使用。
系列文章
- 第 1 篇:《NVIDIA 开源 CAD 内核 SMLib:USD BRep 里有什么、能怎么用》
- 第 2 篇:《Agent 如何用 SMLib 做 CAD 创作:从 AGENTS.md 到 text-to-3D 流水线》
- 第 3 篇:本文(五层架构深度解析)
仓库:
https://github.com/NVIDIA-Omniverse/usd-brep(Apache 2.0,C++ / Python)