面向 AI 原生 3D 建模应用的 SDF、网格与 CAD 内核调研
调研日期:2026-08-28
目标:为一个基于 Three.js、可在浏览器与桌面端运行、从创建到使用都便于 AI 理解和操作的 3D 建模应用确定技术路线。
结论性质:本文把官方资料中可核实的事实与架构建议分开表述;涉及开源许可证的内容不是法律意见,上线前仍需法务复核。
易变事实快照:截至调研日期,已核实的正式版本包括 OCCT 8.0.1 与 Manifold v3.5.2。实现必须锁定具体版本、commit 与构建哈希,本文不会把 latest 当作可重放依赖。
0. 一页结论
Section titled “0. 一页结论”不要在 Manifold 与 OCCT 之间二选一,也不要把 Three.js 当建模内核。建议采用“统一语义层 + 多几何后端”:
| 层 | 建议 | 主要职责 |
|---|---|---|
| 产品与交互 | TypeScript + Three.js | 视口、选择、操控器、UI、渐进式预览 |
| AI/人类共同的模型源 | 自研 Aira Modeling Intermediate Representation(AMIR)与纯函数式表层语言 | 参数、特征图、约束、意图、稳定 ID、事务、审计 |
| 精确 CAD | OCCT;原型期经 Replicad / opencascade.js,产品期维护最小自定义 WASM 绑定 | B-Rep、NURBS、草图生成实体、倒角/圆角、壳体、STEP/IGES |
| 网格实体 | Manifold WASM | 可靠三角网格布尔、切割、批量 CSG、3MF/glTF、可打印网格 |
| 隐式建模 | 自研“有类型 SDF/Field 表达式图”;Manifold LevelSet 负责首版离散化 | 平滑并集、晶格、形变、生成式造型、GPU 预览、按误差烘焙 |
| 2D 约束 | 先抽象统一接口,再对 planegcs WASM 做技术验证 | 几何与尺寸约束、自由度、过约束诊断 |
| 编译与事务核心 | Rust,编译到 WASM 与原生;前期可用 TypeScript 先验证 IR | 解析、类型/单位检查、增量依赖图、补丁、缓存、确定性执行 |
核心判断:
- Manifold 是网格实体内核,不是完整 SDF 建模系统,也不是精确 CAD 内核。 它适合成为浏览器内默认的可靠网格布尔与 SDF 烘焙后端。
- OCCT 是精确机械 CAD 能力的主干。 它覆盖 B-Rep、解析曲面、NURBS、布尔、扫掠、放样、圆角/倒角、壳体、STEP/IGES 与 shape healing;代价是 API 复杂、WASM 较重、许可证与拓扑引用都必须认真设计。
- AI 原生的关键不是让模型直接写 TypeScript、Python 或 C++。 关键是一个短小、强类型、有单位、可增量修改、可查询、可验证、带稳定 ID 和来源映射的领域模型,以及一个事务式工具协议。
- 每个零件只能有明确的“权威表示”。 B-Rep、Manifold mesh、Field/SDF、Three.js mesh 之间的转换必须显式标注精度损失;禁止默默往返转换。
- 最值得自研的护城河是 Intent Graph + Stable Reference + Geometry Observatory。 即:设计意图图、跨重建的语义引用、以及供 AI 读取的结构化几何观测与诊断。
1. 先把四种“3D”分清
Section titled “1. 先把四种“3D”分清”很多架构错误来自把不同表示混成一种。
| 表示 | 擅长 | 不擅长 | 建议定位 |
|---|---|---|---|
| B-Rep / NURBS | 精确尺寸、解析面、工程特征、STEP、制造链路 | 自由平滑混合、体积笔刷、极复杂布尔的交互预览 | 权威精确 CAD |
| Manifold triangle mesh | 快速可靠的实体网格布尔、打印与渲染交付 | 精确 NURBS、无损 STEP、传统 CAD 特征语义 | 权威网格实体 |
| SDF / F-Rep / sparse level set | 平滑布尔、形变、晶格、体积造型、任意分辨率采样 | 显式边/面、精确圆角选择、传统尺寸标注 | 权威隐式实体 |
| Three.js BufferGeometry / glTF | GPU 显示、材质、交互、传输 | 设计历史、精确拓扑、参数与制造语义 | 派生视图与交付 |
Three.js 官方文档将 BufferGeometry 定义为位置、索引、法线、UV 等 GPU 缓冲的几何表示;Khronos 也明确说明 glTF 是运行时资产交付格式而非 authoring format。因此二者都不应成为模型的唯一源数据:Three.js BufferGeometry、glTF 2.0 规范。
2. 对两个标杆项目的判断
Section titled “2. 对两个标杆项目的判断”2.1 Manifold
Section titled “2.1 Manifold”项目定位与已核实能力:
- Manifold 的内部对象是带方向的 2-manifold 三角网格,是实体边界的简单 B-Rep;项目把“输出保持 manifold”作为首要目标,并提供 C++、C、Python 和官方 TS/JS/WASM 绑定。官方仓库
- 官方文档提供 primitive、extrude、revolve、boolean、batch boolean、split、trim、Minkowski、hull、simplify、smooth、体积/面积等 API。Manifold 类文档
- LevelSet 接受一个标量场函数、边界盒和目标边长,以 body-centered cubic grid 上的 Marching Tetrahedra 变体生成 manifold mesh;因此它是“SDF/标量场到网格”的烘焙器,而不是保留场表达式的 SDF 数据库。LevelSet 文档
- 官方 npm 包 manifold-3d 直接提供浏览器 WASM;ManifoldCAD 本身就是 Manifold + TypeScript + glTF 的参考实现。WASM README
- 许可证为 Apache-2.0。LICENSE
为什么值得采用:
- 浏览器适配是官方路径,不需要自行发明网格布尔 WASM。
- 对 AI 生成的组合模型,拓扑保证比“多数时候看起来正确”更重要;错误可以结构化为 NotManifold、InvalidConstruction 等状态。
- 输入面与输出三角形之间可保留 originalID / faceID 等来源关系,这能成为 AI 语义追踪的低层素材。
- 支持 glTF 的 EXT_mesh_manifold 扩展和 3MF,适合保留实体拓扑并进入打印/渲染链路。
必须明确的边界:
- 输入仍需是 manifold;Merge 只能修复部分轻微问题,不能代替通用 mesh repair。
- “manifold 输出”不等于“几何永远符合设计意图”。官方算法说明区分拓扑保证与 epsilon-valid 几何,并说明自重叠输入无法得到同样的几何可靠性承诺。算法说明
- 它不保存解析圆柱面、NURBS 面或传统 CAD 特征历史。网格再平滑也不等于精确 B-Rep。
- LevelSet 的性能和误差直接受边界盒、edgeLength 与 tolerance 影响;这些必须进入文档和缓存键,不能藏成全局默认值。
- JS
levelSet的符号约定是“正值在内部、负值在外部”,与许多 SDF / level-set 库常用的负内正外约定相反;Field adapter 必须显式声明并转换,不能靠调用方记忆。JS API - 首版可以把 Field 回调交给
levelSet,但复杂模型可能产生大量 JS↔WASM 回调;长期应把表达式图编译到 WASM 内部批量求值。这是需要用基准验证的工程推断,不是官方性能承诺。 - 官方提醒 Emscripten 并行构建存在潜在内存问题,浏览器首版应优先单线程 worker,再用基准验证线程版。构建说明
建议角色:立即采用,作为 MeshSolid 与 FieldBake 的默认后端,但绝不把它包装成“完整 CAD 内核”。
2.2 Open CASCADE Technology(OCCT)
Section titled “2.2 Open CASCADE Technology(OCCT)”项目定位与已核实能力:
- 当前官方正式版本为 OCCT 8.0.1;它是 C++ CAD/CAM/CAE 开发平台,模块包括 Modeling Data、Modeling Algorithms、Mesh、Data Exchange、Shape Healing 与 OCAF。8.0.1 Release 官方概览
- B-Rep 数据可表达点、曲线、解析面、Bezier、NURBS 与其拓扑组合;算法覆盖 primitives、extrude/revolve/pipe/loft、boolean、hollow/shell、draft、fillet/chamfer 与多种机械特征。Modeling Algorithms
- 数据交换覆盖 STEP AP203/AP214/AP242、IGES、glTF、OBJ、STL 等;XDE 可保留名称、颜色、层、材料等属性,Shape Healing 用于检查和修复交换模型。官方概览:Data Exchange / Shape Healing
- OCAF 提供文档、依赖、重算、撤销/重做、持久化以及 topological naming 基础设施。OCAF 指南
- 官方支持 Web / Emscripten 构建,但核心仍是大型 C++ 库。官方平台要求
- 许可证为 LGPL-2.1 加 OCCT 例外。官方文档特别指出静态链接或应用商店分发时仍需满足用户替换修改版 OCCT 的要求,或选择商业许可。官方许可证说明
为什么值得采用:
- 如果产品承诺“CAD”而不仅是“可打印网格编辑器”,STEP、解析曲面、可靠尺寸、圆角/壳体等能力很难绕开 B-Rep 内核。
- OCCT 的算法历史能报告 Deleted / Modified / Generated 子形状,并可合并历史;这是稳定引用的重要输入。History support
- OCAF 的 reference-key 模型与命名机制说明了正确方向:应用数据应该依附于比当前 shape 更稳定的引用结构,而不是当前数组下标。
必须明确的边界:
- 原始 OCCT API 对 AI 和普通应用开发者都过于庞大、命名晦涩、资源管理复杂;不应直接暴露给上层。
- 这里的“精确 CAD”指解析曲线/曲面与 B-Rep 语义,不等于精确有理算术。OCCT 仍以双精度浮点和 tolerance 驱动;例如
Precision::Confusion()的默认量级为1e-7个用户单位,所以单位尺度与 tolerance profile 必须进入文档语义。Precision reference - 拓扑命名不是“打开一个开关”就解决。官方说明要求建模算法历史、历史注册、选择与重算三部分严格协同;选择求解仍可能失败。OCAF Topological Naming
- OCCT 8.0 的
BRepGraph新增显式图拓扑、history、UID 与 mutation generation,是更好的 adapter 内部基础,但仍不是完整的参数重算语义命名;产品级 ID 不应直接等同于它的 UID。BRepGraph announcement - 圆角、布尔与 imported shape 会受容差、退化几何、面相交条件影响;产品必须返回可恢复的结构化诊断。
- OCCT 的子形状遍历顺序、地址相关 hash 和并行执行不适合作为跨平台 bit-identical 承诺;回归应比较有效性、拓扑摘要、质量属性和带界几何误差,而不是 BREP 字节或 face 枚举顺序。OCCT coding rules
- WebAssembly 体积、初始化、内存和异常语义都需要产品化。opencascade.js 官方资料也建议生产应用使用按符号裁剪的 custom build,而不是完整包。Custom Builds
- LGPL/WASM/商店分发需要在商业路线确定前完成合规方案,不应拖到发布阶段。
建议角色:采用,作为 ExactSolid 的权威后端;通过极窄、版本化、自动生成类型的 adapter 使用。
3. 浏览器中的 OCCT:怎样用,而不是是否用
Section titled “3. 浏览器中的 OCCT:怎样用,而不是是否用”3.1 opencascade.js
Section titled “3.1 opencascade.js”opencascade.js 是 OCCT 经 Emscripten/Embind 生成的 JS/WASM 绑定,带 TypeScript definitions,并支持以 YAML 描述需要暴露的类和编译参数生成 custom build。其官方入门仍使用 beta npm 标签,说明产品应固定提交/构建产物并自行做回归,而不是追随浮动版本。
建议:
- 研发探索时可用 full/beta build 查询能力。
- 产品包中只编译会用到的工具包和绑定;把构建清单、OCCT commit、Emscripten 版本写入 lock manifest。
- 在专用 Web Worker 内运行;接口只传结构化命令与 transferable typed arrays。
- 把 C++ 对象生命周期完全封装在 worker 内,绝不把 delete 责任泄露给 UI 或 AI。
3.2 Replicad
Section titled “3.2 Replicad”Replicad 是 MIT 许可的 TypeScript 高层封装,本质仍依赖 opencascade.js。它已经提供较易读的 code-CAD API、Three.js 辅助集成、STEP 导出等,可大幅缩短验证周期;官方也建议把 OCCT WASM 放进 worker。作为库使用
建议:
- MVP 与能力探索使用 Replicad。
- 把它放在自家 adapter 后面,不让 AMIR 直接依赖其类名与 selector 语法。
- 在模型语义、稳定引用、错误结构和确定性要求明确后,决定继续维护 fork,还是换成更窄的原生 OCCT adapter。
3.3 Cascade Studio
Section titled “3.3 Cascade Studio”Cascade Studio 已展示“OCCT WASM + Three.js + 浏览器脚本 CAD + history timeline + selector API”的完整纵向样例。它适合做交互和集成参考,不应直接被视为可替代产品语义内核的依赖。
4. SDF / 隐式建模库调研
Section titled “4. SDF / 隐式建模库调研”4.1 建议进入主路线
Section titled “4.1 建议进入主路线”Manifold LevelSet
Section titled “Manifold LevelSet”首版最实际:已有官方 WASM、与网格布尔同一数据结构、输出 manifold,并允许以误差参数控制烘焙。
适用:
- smooth union / subtraction;
- gyroid、lattice、泡沫、形变;
- 由 Field3D 生成预览或打印网格;
- 把离散结果继续交给 Manifold 做布尔、分解、测量与导出。
不适用:
- 作为可无限编辑的场数据库;
- 精确恢复 CAD 面和边;
- 把网格圆角冒充成工程圆角。
自研 Field IR + GPU 预览
Section titled “自研 Field IR + GPU 预览”这是建议自研的第一项核心技术。一个 Field3D 节点不是任意 JS 回调,而是节点数与执行成本可约束、可类型检查、可序列化的表达式图;其数学定义域本身可以是全空间:
- primitive:sphere、box、capsule、torus、plane、cylinder、cone;
- composition:union、intersection、difference、smoothUnion;
- transform:translate、rotate、uniformScale、twist、bend、repeat;
- domain/material:bounds、Lipschitz/距离保真标记、material/feature provenance;
- quality:preview steps、bake tolerance、max cells、normal method。
Field 类型必须至少区分 TrueSDF、ConservativeDistance 与 GeneralImplicit。非均匀缩放、warp 以及部分平滑组合会破坏严格距离性质;每个输出还应声明 inside-sign、mathematicalDomain、可知时的 surfaceBounds、Lipschitz 上界、梯度来源和可分辨的最小特征尺度。数学上无界的 Field 可以合法存在,但每次预览/测量必须给出有限 evaluationClip,每次 Field → Mesh 必须给出有限 meshingBounds。否则 AI 会把“零等值面可显示”误认为“可以安全 sphere trace、offset 或按固定误差烘焙”。
同一张图编译为:
- Three.js TSL/WGSL/GLSL 的 sphere-tracing 或切片预览;
- CPU/WASM 批量 evaluator;
- Manifold LevelSet 回调或后续更高级的自适应 mesher。
Three.js WebGPURenderer 已支持 TSL,并能根据后端转译到 WGSL 或 GLSL,适合做渐进增强的 Field 预览;但要固定 Three.js 版本并保留 WebGL2/mesh fallback。WebGPURenderer
4.2 值得保留为后续后端或研究参考
Section titled “4.2 值得保留为后续后端或研究参考”| 项目 | 已核实定位 | 价值 | 不进入首版主路径的原因 |
|---|---|---|---|
| Fidget | Rust 的实验性闭式隐式曲面基础设施,含表达式去重、tape、区间求值、梯度、JIT、Manifold Dual Contouring;MPL-2.0 | Field compiler、区间裁剪、自适应 meshing 的最佳研究参考之一 | 官方明确称其为个人规模实验项目;WASM 无 JIT,严肃使用可能需 fork |
| libfive | C++ F-Rep 内核,C API、Scheme/Python 绑定、feature-preserving watertight meshing;内核 MPL、Studio GPL | 成熟的函数表示设计与自适应求值参考 | 无官方浏览器优先路径;生态与近年的活跃度需要单独验证 |
| OpenVDB / NanoVDB | 稀疏体素/窄带 level set 与大量体积工具;Apache-2.0 | 桌面/服务端体积雕刻、mesh-to-volume、布尔、滤波、海量扫描数据 | 依赖、内存和构建复杂度不适合作为浏览器首屏内核;它是离散稀疏场,不是紧凑的可编辑符号表达式 |
| fogleman/sdf | 简洁 Python SDF API + Marching Cubes;MIT | API 易读性的参考、离线数据生成 | Python/NumPy 路线,不适合浏览器产品内核;README 也说明非精确 SDF/稀疏采样可能产生洞 |
重要概念限制:F-Rep 对 CSG 和连续变形非常自然,但缺少显式边与面,因此“对这条边倒角”会比 B-Rep 困难得多。libfive 作者对此有清楚说明:F-Rep 与 B-Rep 的取舍。
5. 其他 CAD / 几何库如何定位
Section titled “5. 其他 CAD / 几何库如何定位”| 项目 | 结论 | 适合做什么 |
|---|---|---|
| CadQuery | 不作为浏览器运行时;作为 AI 友好 API、训练数据和回归语料的重要参考 | 研究 Workplane、selector、parametric script 设计;导入现有 CadQuery 样例做对照 |
| build123d | 同上;API 比较现代,但仍是 Python + OCCT | 研究 Builder/Algebra 两种风格、Select.NEW/LAST 与拓扑查询 |
| JSCAD | 可快速做纯 JS code-CAD,但不应替代 Manifold/OCCT 组合 | 参考参数 UI、浏览器脚本生态和简洁 API |
| three-bvh-csg | 纯 Three.js、MIT、交互速度有吸引力,但项目仍标为 experimental,数值边界下可能得到非流形结果 | 仅作即时交互预览或 UX 原型;保存/导出前交给权威内核重算 |
| MCUT | 面向开放/封闭多边形表面的切割与布尔,LGPL-3.0 或商业许可;输入仍有绕序、流形和一般位置条件 | 未来需要“开放曲面切割”时作为专项后端评估,不替代通用实体内核 |
| OpenSCAD | 成功的文本 CSG 语言,但语义较旧、B-Rep 特征弱 | 兼容导入/迁移、语言与模块系统参考 |
| truck | 很有潜力的 Apache-2.0 Rust B-Rep/NURBS/WebGPU CAD kernel,带 JS crate 与 STEP 工具 | 建立持续 benchmark,作为未来降低 C++/LGPL 依赖的候选;目前不建议用它替换 OCCT 的生产覆盖 |
| openNURBS / rhino3dm | 主要是 3DM 读写、NURBS 求值和基础几何;rhino3dm 提供官方 WASM | 3DM 互操作、曲线/曲面数据读取;不要误认为完整 Rhino 几何/实体算法 |
| CGAL | 高质量计算几何算法集合,不是完整机械 CAD 应用框架;包许可证混合 | 特定算法离线后端或独立微服务,逐包评估许可证;不作为首版统一内核 |
最值得拆解的现有语言:KCL 与 FeatureScript
Section titled “最值得拆解的现有语言:KCL 与 FeatureScript”Zoo 的 KCL 是最值得认真拆解的行业参考:
- 文本是模型 source of truth;
- GUI 操作也修改同一份代码;
- 纯函数式取向;
- 参数、函数、pipeline、单位与 tags;
- Rust 实现的语言工具与 WASM LSP;
- 官方明确把文本/代码与 AI 可生成性联系起来。KCL 设计说明
值得直接吸收的原则:
- 每个数带单位;KCL 文档甚至规定数值不是“裸 42”,而是带长度、角度或无量纲类型。Units
- 代码、GUI、自动化走同一路径。
- 函数式/不可变模型便于依赖分析和来源映射。
- 给面、边和草图段命名,而不是让用户记序号。
需要向前再走一步的地方:
- 文本不应是 AI 工具调用的唯一接口;AI 更适合提交有 schema、precondition 与 base revision 的 AST patch。
- 仅靠 tag 仍不足以处理拆分、合并和重建。KCL 文档本身也描述了 tag scope/backward compatibility 的复杂性,并鼓励使用 body-scoped named faces。KCL Tags
- 多内核、多表示及有损转换应该进入类型系统,而不是隐藏在 engine 内。
- “生成成功”之外,系统要能结构化回答为什么失败、哪个引用歧义、误差是多少、可修复方案是什么。
Onshape 的 FeatureScript 是另一个必须研究的语义标杆。Part Studio 的重建本质是按特征重新执行 build;建模操作带层级 Id,失败可产生会撤销当前特征修改的结构化 regeneration error。更关键的是,它把拓扑引用表达为 query,而不是保存某次运行中的实体列表;官方区分 state-based query 与 historical query,后者能描述“由某次 extrude、从某个 sketch 实体生成的边”。Modeling / Queries
应吸收它的特征重建、单位/类型、operation ID、historical query 与结构化失败语义;不应照搬其与 Onshape 云运行时绑定的执行环境。Aira 还应更严格:查询必须声明 cardinality,匹配多个时不能沿用“取第一个”的便利行为,而要阻止提交并返回候选与原因。