USD BRep五层架构深度解析:SMLib、SM_API、SM_API_USD与SmPyLib各管什么
USD BRep五层架构深度解析:SMLib、SM_API、SM_API_USD与SmPyLib各管什么
USD BRep 是一个独立的 C++ 与 Python 实体建模库,基于 NURBS 边界表示(BRep)做精确的三维实体建模,并原生读写 OpenUSD。它按职责清晰拆分为五层:SMLib 内核、SM_API 稳定封装、SM_API_USD 转换层、内部 USD 数据层和 SmPyLib Python 绑定。本文带你一次看懂每一层各管什么、该从哪层入手。
🧱 五层架构总览:一张表看懂分工
USD BRep 的分层思路是“内核做算法、封装做接口、桥接做格式、绑定做易用”。官方架构说明见 AGENTS.md,各层一览:
| 层级 | 模块 | 目录 | 职责 | 典型使用者 |
|---|---|---|---|---|
| ① 内核 | SMLib | source/SMLib/ | 几何/拓扑类与全部建模算法 | 底层 C++ 集成者 |
| ② 封装 | SM_API | source/SM_API/ | 稳定的 C 风格 SmApi* 接口 |
主流 C++ 用户 |
| ③ 桥接 | SM_API_USD | source/SM_API_USD/ | USD 文件导入/导出、修复、网格化 | C++ USD 互操作 |
| ④ 数据 | BREP_SM_USD / BREP_USD_DATA | source/BREP_SM_USD/、source/BREP_USD_DATA/ | BRep ↔ USD BrepArray 数据转换 | 内部实现细节 |
| ⑤ 绑定 | SmPyLib | source/SmPyLib/ | Python 模块 _omni_solid / 包 usd_brep |
绝大多数新手用户 |
数据流向可以简单理解为:
usd_brep (Python) → SM_API → SMLib,以及 BrepArray (.usda/.usdc) ⇄ SM_API_USD ⇄ BREP_USD_DATA/BREP_SM_USD ⇄ SmBrep。
① SMLib:NURBS 几何内核,一切的基石
SMLib 是最底层的 C++ 内核,拥有全部几何与拓扑类:SmBrep → SmShell → SmFace → SmEdge → SmVertex 的层次结构,配合 NURBS 曲线曲面、解析基元(球、柱、锥、环面等)以及布尔、圆角、扫掠、偏移、修复等算法。它的头文件多达 238 个,例如:
- source/SMLib/inc/SmBrep.h — 实体模型主体
- source/SMLib/inc/SmSurface.h — 曲面求值契约
- source/SMLib/inc/SmBSplineCurve.h — B 样条曲线
- source/SMLib/inc/SmFilletExecutive.h — 圆角求解执行器
💡 内核记忆由内部的 SmContext 统一管理;这一层 API 丰富但不承诺稳定,官方建议普通开发者不要直接调用内核类,而是走上面两层的稳定封装。
② SM_API:稳定 C 风格封装,日常建模主力
SM_API 是给 C++ 用户的主要接口,函数统一采用 SmApi* 命名,按功能拆成一组头文件,分工一目了然:
| 头文件 | 管什么 |
|---|---|
| SmApiPrimitives.h | 创建盒、球、锥、柱、环面等基元 |
| SmApiBrep.h | 布尔、扫掠、切割、缝合、圆角、壳体、网格化 |
| SmApiFillets.h | 倒角、圆角、去除圆角 |
| SmApiQueries.h | 体积、面积、包围盒、流形检查等只读查询 |
| SmApiHeal.h | BRep 修复(healing) |
| SmApiTessellationParams.h | 网格化精度参数 |
配套的可运行示例放在 Examples/SM_API/,其中的 boolean_bounds.cpp 演示了“板件减 16 个圆柱”的布尔运算,并对比了不同包围盒查询策略对性能的影响。
③ SM_API_USD:USD 导入导出,让 BRep 进出 OpenUSD
这一层负责 .usda / .usdc / .usd 文件与内存中 SmBrep 之间的往返转换,入口在 source/SM_API_USD/inc/SmApiUsd.h:
- 导入:
SmApiUsdImportBreps扫描 USD 文件里所有带 BrepArray 模式的 prim,逐一转换为SmBrep,支持“严格”与“部分成功”两种策略; - 导出:把
SmBrep/SmPolyBrep写回 USD 文件; - 修复:SmApiUsdHeal.cpp 提供文件级
heal能力,可批量修复 BrepArray 数据; - 网格化:SmApiUsdTessellate.h 可把 USD 里的 BRep 直接转成
UsdGeomMesh。
USD 侧的数据格式是 UsdSolidBrepArray(BrepArray)模式——一个 prim 即可打包多个 BRep 的拓扑、曲线与曲面数据。官方设计提案与模式定义见 proposals/UsdSolid/README.md 和 proposals/UsdSolid/schema.usda。下图就是一个 BrepArray 场景中的两个 BRep 实体(黑/绿色立方体):
④ BREP_SM_USD / BREP_USD_DATA:藏在幕后的数据转换层
这两个模块是 SM_API_USD 的“内务部门”,做纯数据转换,不直接面向用户:
- BREP_SM_USD(source/BREP_SM_USD/inc/SmuConvert.h):在 SMLib 对象与 USD 数据之间做属性映射、token 解析;
- BREP_USD_DATA(source/BREP_USD_DATA/inc/UsdBrepRead.h、UsdBrepWrite.h):面向 BrepArray 模式数组的读取器、写入器与诊断信息。
💡 了解它们有助于阅读源码和排查数据问题;日常使用无需直接接触。若你要接入其他 CAD 数据源,source/BREP_STAGING/ 还定义了源中立的“staging 记录”约定,规定了 UV 曲线存储顺序、缺失 UV 的处理等适配规则。
⑤ SmPyLib:Python 绑定,新手最友好的入口
SmPyLib 基于 pybind11 把 SM_API 与 SM_API_USD 暴露给 Python,核心源码在 source/SmPyLib/src/SmPyMain.cpp,类型标注在 source/SmPyLib/stubs/usd_brep/init.pyi。
它有两个使用形态:
- 源码构建:
import _omni_solid as sm,适合参与内核开发; - PyPI 安装:
pip install usd-brep后import usd_brep,打包版内置 OpenUSD 运行时,开箱即用,说明见 tools/pyproject/README.md。
打包版把操作按语义分组为子模块:primitives(基元)、booleans(布尔)、sweeps(扫掠)、fillets(圆角)、tessellate(网格化)、usd(USD 读写)等。几行代码完成一次建模 + 导出:
import usd_brep
box = usd_brep.primitives.create_box((0, 0, 0), 10, 10, 10)
sph = usd_brep.primitives.create_sphere((0, 0, 0), 5)
cut = usd_brep.booleans.subtract(box, sph)
usd_brep.usd.export_brep(cut, "cut.usda")
⚠️ 用 Python API 时请记住三种“变异约定”(详见 AGENTS.md):
| 约定 | 含义 | 例子 |
|---|---|---|
| Pure | 返回新对象,输入不变 | create_box、tessellate |
| Consumes | 输入所有权被操作消费 | boolean_union |
| Mutates | 修改第一个参数并返回同一句柄,可链式调用 | fillet_edges、cut |
想保留原始对象时,先 brep.copy() 再传入。完整 Python 入门示例可参考 Examples/PyAPI/round_corner_pipe.py(用平面扫掠、布尔与球面转角拼出带圆角的管道)和 docs/python.rst。
🛠️ 周边组件速览:渲染、校验与 GUI
除五层核心外,仓库还提供了配套的生态组件:
- hdUsdBrep 渲染插件(source/HYDRA_USD_BREP/):把 USD BrepArray 实时网格化后交给 Hydra 渲染,可直接在 usdview 中查看 BRep 实体,支持线框/表面线框显示模式;
- brep_validator 系列(tools/brep_validator_cli/):对 BrepArray 模式做 schema 级校验,TestFiles/brep_validator/ 下有上百个覆盖各种缺陷的测试资产;
- OCCT 互转(source/OCCT_BREP_IMPORT/):OpenCASCADE
.brep文件的导入导出,TestFiles/occt_breps/ 提供了大量测试模型; - smlib_gui(tools/smlib_gui/):基于 Python 的 GUI 工作台,可视化查看、挑选与操作 BRep 对象。
📌 新手如何选择入手层?
- 只想用 Python 建模、读写 USD → 直接
pip install usd-brep,走 SmPyLib; - 写 C++ 工具做布尔/圆角/网格化 → 用 SM_API 的
SmApi*函数; - 需要在 C++ 程序里加载
.usda里的 BRep → 用 SM_API_USD 的导入导出; - 研究精确几何算法或内核行为 → 深入 SMLib,并配合 Examples/SMLib/ 中的内核示例理解调用约定。
按层使用、越界不越权,就是理解并用好 USD BRep 五层架构的关键。
