在三维数字资产生成领域,近年来的技术探索大多集中在以多边形网格(Polygon Mesh)、神经辐射场(NeRF)或高斯泼溅(3D Gaussian Splatting)为核心的表示方法上。这些方法在游戏影视资产与外观概念设计中表现出众,但难以直接迁移至严谨的精密机械与实体制造场景。
工业工程对几何模型有着截然不同的标准:零件需要具备严格的边界表示(B-Rep, Boundary Representation)、确定的解析曲面与精确尺寸公差,并能输出为 STEP、DXF 等标准交换格式。在装配与自动化阶段,往往还需要进一步产出机器人结构描述(URDF/SRDF)并对接切片工具(Slicer)生成可加工的 G-code。
开源项目 earthtojake/text-to-cad 及其底层核心引擎 cadgen 选择了另一条技术路线:不依赖端到端的黑盒网格扩散,而是让大语言模型(如 Claude Code、Codex 等)编写符合工程约束的 Python 参数化建模代码,再由底层的构建引擎与 OpenCascade 几何内核完成实体编译、内容寻址缓存、仿真模型生成以及制造质检。
从多边形网格到参数化实体:CAD 的数字化演进
在讨论代码生成 CAD 之前,首先需要明确几何表示方式的根本差异。
当前主流的 3D 生成模型多以离散三角形构建空间结构。这种模型在视口渲染中效果良好,但无法提供平面的严密几何平整度、轴孔的同轴度约束以及清晰的特征边界。若尝试将其导入主流 CAD 软件进行打孔、攻丝或应力仿真,往往需要进行繁重的逆向重构,且容易出现拓扑缝隙。
相比之下,工业 CAD 体系建立在边界表示(B-Rep)之上。B-Rep 通过拓扑关系(顶点、边、环、面、壳、体)以及底层的解析数学方程(平面、圆柱、圆锥、NURBS 曲面)精确界定物体的内部与外部。这种表示方式是机械装配、CNC 机床加工以及注塑模具开发的通用语言。
text-to-cad 的核心定位,便是为大语言模型打造一套以 B-Rep 为基石的 CAD/CAE/CAM 技能体系。它让模型专注于逻辑理解与代码生成,通过严密的 Python 几何脚本(基于 build123d 框架)表达尺寸与公差,再借助成熟的几何编译器完成拓扑计算。这种职责划分规避了神经网络在解析几何精度上的随机性,确保了输出物具备可靠的工程制造价值。
分层体系与 cadgen 构建中枢
整个 text-to-cad 生态采用了清晰的模块化分层设计,涵盖从用户交互、任务调度、几何解算到数据持久化的完整链条。
@startuml
!theme plain
skinparam backgroundColor transparent
skinparam defaultFontName "Inter, PingFang SC, sans-serif"
skinparam roundcorner 8
skinparam shadowing false
skinparam packageStyle rectangle
skinparam package {
BackgroundColor #F8FAFC
BorderColor #CBD5E1
FontColor #0F172A
FontStyle bold
}
skinparam component {
BackgroundColor #FFFFFF
BorderColor #94A3B8
FontColor #1E293B
}
package "1. Agent Skills 交互与协议矩阵" as LayerSkills {
[CAD 建模核心 (cad)] as SkillCAD
[本地 WebGL 预览 (cad-viewer)] as SkillViewer
[标准五金件检索 (step-parts)] as SkillParts
[2D 工程出图 (dxf)] as SkillDXF
[机器人连杆与运动学 (urdf / srdf)] as SkillRobot
[物理仿真世界 (sdf)] as SkillSim
[增材可制造性分析 (dfam-check)] as SkillDfAM
[切片与打印机控制 (gcode / bambu)] as SkillCAM
}
package "2. cadgen 双语核心引擎与常驻进程池" as LayerEngine {
[Warm Daemon 守护构建池] as DaemonPool
[@memo 操作码纯度检查] as MemoGuard
[cadgen-js 嵌入式运行时] as JSRuntime
[Job Ledger 槽位调度器] as JobLedger
}
package "3. 工业级几何内核与拓扑模型" as LayerKernel {
[OpenCascade (OCP 绑定)] as OCPKernel
[build123d 声明式拓扑] as Build123d
[STEP / BREP 工业格式转换] as Exporter
}
package "4. CAS 内容寻址持久层与物理终端" as LayerStore {
database "objects/ (不可变内容哈希)" as StoreObjects
database "index/ (输入哈希映射)" as StoreIndex
[自包含工件 (<name>.step + sidecar)] as Artifacts
[制造终端 (Bambu / SendCutSend)] as PhysicalMachines
}
LayerSkills --> LayerEngine
LayerEngine --> LayerKernel
LayerKernel --> LayerStore
@enduml
系统主要由以下四个核心层级协同运转:
- 智能体技能协议层(Skills Matrix):
通过标准化的技能接口,向 AI 智能体暴露 11 个职责内聚的操作指令。其中,
cad负责基于自然语言与草图生成几何模型;cad-viewer提供免额外依赖的轻量 WebGL 交互预览;step-parts允许模型直接检索标准螺栓、轴承等通用标准件并装配入库;urdf、srdf与sdf则负责输出机器人运动学链与仿真环境配置。 - cadgen 核心构建中枢:
该组件作为执行调度中枢,将 Python 逻辑与预编译的
cadgen-js运行时封装为单一发布包。为了避免 Python 环境每次冷启动加载 C++ 几何动态库带来的明显延迟,引擎内置了 Warm Daemon 常驻构建池,配合 Job Ledger 统一调度并发作业。 - 几何内核与拓扑抽象层:
基于 OpenCascade 的 Python 绑定(OCP)构建精确的拓扑实体,上层采用声明式的
build123d框架。这一层遵循严格的惰性导入规范,只在执行实体布尔运算时加载重型模块,保证了上层 CLI 与辅助工具的高响应速度。 - CAS 内容寻址存储层:
位于本地目录
~/.cache/cadgen,采用类似 Git 的内容寻址存储机制,精确管理中间计算产物与最终工件,实现跨模型的高速缓存复用。
核心设计约束与 CAS 存储模型
在 cadgen 的系统说明中,设计团队确立了几项严格的设计约束,以保障整个工具链的稳定性。
工件自洽与源码解耦
一个关键的设计约束是:生成的文件必须脱离源代码独立存在。
当模型编译输出 model.step 实体时,会同步生成对应的 model.step.json 侧车文件(Sidecar)。该文件不仅记录了装配层级、材质色彩与约束标签,还直接内嵌了用于动画展示的纯 JavaScript 逻辑。无论是本地查看器还是外部质检工具,都只需读取生成的工件本身,无需依赖任何 Python 解释环境。即便将源码脚本全部移除,已生成的 3D 工件依然可以完整浏览并驱动运动学模拟。
存储两面结构 (The Two-Sides Pattern)
本地存储库 ~/.cache/cadgen 遵循清晰的两面模式划分:
- 工件侧 (
objects/):基于内容哈希(Content-Addressed)管理不可变的几何数据与结果树,只要几何实体的拓扑一致,其哈希值便保持相同; - 记录侧 (
index/):基于输入哈希(Input-Addressed)建立索引,记录“代码脚本 + 依赖版本”与“结果几何树”之间的映射关系。
当输入相同的参数化脚本时,调度器只需比对输入哈希即可在毫秒级完成缓存匹配;而对于装配体中重复引用的公共构件,内容寻址机制能实现天然的单实例存储,大幅节省磁盘空间与 IO 开销。
架构权衡取舍 (Trade-offs)
系统在设计时做出了清晰的取舍:
- 放弃黑盒直接生成,选择可读代码作为媒介:尽管代码生成增加了一个编译步骤,但赋予了工程师完全的参数修改自由度与版本控制能力,契约清晰;
- 限制动态特性的自由度,保障中间结果纯度:在几何缓存层限制了外部任意动态调用的能力,换取了无副作用的并行构建与可靠的缓存重现性。
内核机制与操作码级纯度检查
工业装配模型往往由大量重复特征组合而成,例如机械外壳上的数十个散热孔或均布螺栓孔。如果每次微调都对所有孔位执行完整的布尔布尔求交(Boolean Cut/Fuse),计算耗时将成倍增长。
为了实现中间几何运算的细粒度复用,cadgen 提供了 @memo 记忆化机制。与常规的 Python 内存缓存不同,几何缓存必须保证绝对的数学纯度——即不能依赖未追踪的全局变量、随机数或外部文件系统变更。为此,packages/cadgen/src/cadgen/memoization.py 实现了一套基于 Python 字节码操作码(Opcode)白名单 的校验方案:
# 摘自 packages/cadgen/src/cadgen/memoization.py
_ALLOWED_OPCODES = frozenset("""
CACHE RESUME LOAD_CONST LOAD_FAST LOAD_GLOBAL LOAD_ATTR
STORE_FAST STORE_ATTR STORE_SUBSCR DELETE_FAST
BINARY_OP STORE_SLICE
CALL CALL_FUNCTION_EX CALL_KW
BUILD_TUPLE BUILD_LIST BUILD_SET BUILD_MAP BUILD_CONST_KEY_MAP
LIST_APPEND LIST_EXTEND SET_ADD SET_UPDATE MAP_ADD DICT_UPDATE
UNPACK_SEQUENCE GET_ITER FOR_ITER END_FOR
JUMP_FORWARD JUMP_BACKWARD POP_JUMP_IF_TRUE POP_JUMP_IF_FALSE
COMPARE_OP CONTAINS_OP RETURN_VALUE
""".split())
def _digest_code(code: types.CodeType) -> tuple:
"""递归检查 Python CodeType 字节码纯度并提取特征哈希"""
if code in _code_cache:
return _code_cache[code]
# 遍历字节码指令,若包含非白名单操作码则拒绝缓存 (Decline)
for instruction in dis.get_instructions(code):
if instruction.opname not in _ALLOWED_OPCODES:
raise _Decline(f"disallowed opcode: {instruction.opname}")
digest = (
code.co_code,
code.co_consts,
code.co_names,
tuple(_digest_code(c) for c in code.co_consts if isinstance(c, types.CodeType))
)
return digest
关键技术点剖析:
- 静态操作码白名单:代码扫描严格限制在数据加载、算术运算与局部变量操作上,任何涉及动态模块导入(如
IMPORT_NAME)的操作码均不在白名单内; - 平滑降级防御:若开发者在
@memo装饰的函数内使用了外部读写等复杂逻辑,系统通过捕获_Decline异常自动回退到无缓存计算模式,保证程序不中断; - 自包含前端运动学:在构建带有运动关节的模型时,导出的
.step.json内嵌了由cadgen-js预编译的逆运动学(IK)解算逻辑。前端 WebGL 查看器无需后端支撑即可完成机械臂末端执行器的坐标求解与拖拽联动。
从自然语言到物理成型:端到端流水线解析
在实际工业应用中,从需求输入到硬件成型通常包含五个关键阶段。
@startuml
autonumber
actor "开发者 / 工程师" as User
participant "AI Agent (Claude / Codex)" as Agent
participant "cadgen 构建池" as Daemon
participant "OpenCascade (OCP 内核)" as OCP
database "CAS 存储中心 (~/.cache)" as CAS
participant "CAD Viewer (WebGL)" as Viewer
participant "制造设备 (3D 打印机)" as Hardware
User -> Agent: 输入提示词:"设计一个带 4 个 M3 孔的固定支架"
Agent -> Agent: 调用 /cad 技能,编写参数化 build123d 脚本 (bracket.py)
Agent -> Daemon: 提交构建作业 (bracket.py::bracket)
activate Daemon
Daemon -> CAS: 查询输入索引 index/
alt 缓存命中 (Cache Hit)
CAS --> Daemon: 返回已编译 Result Tree 哈希
else 缓存未命中 (Cache Miss)
Daemon -> OCP: 调度 Worker,执行几何建模与布尔运算
OCP --> Daemon: 返回精确 B-Rep Solid 实体
Daemon -> CAS: 原子写入 objects/ 与 index/
end
Daemon --> Agent: 输出 bracket.step 与 bracket.step.json (Sidecar)
deactivate Daemon
Agent -> Viewer: 启动本地查看服务 (cadgen viewer)
Viewer --> User: 浏览器呈现 3D 实体与材质控制
User -> Agent: "检查可打印性并打印"
Agent -> Daemon: 执行 /dfam-check 分析壁厚、悬垂角与体积
Daemon --> Agent: 检查通过
Agent -> Daemon: 调用 /gcode,启动本地切片器生成 G-code
Agent -> Hardware: 局域网传输并启动 3D 打印
Hardware --> User: 打印机开始物理出件
@enduml
- 工程意图解析与参数化脚本生成:
用户向接入了该技能库的 Agent 发送尺寸或装配要求。Agent 调用
cad技能,根据几何拓扑关系编写符合build123d规范的 Python 代码。 - 指纹校验与增量缓存匹配:
构建请求投递至常驻守护进程。系统提取源码 AST 与依赖版本生成指纹并查询
index/;若存在历史命中,以极小开销直接返回已构建树。 - 几何计算与实体输出:
若未命中缓存,Worker 进程利用 OpenCascade 内核执行布尔运算与特征倒角,导出工业级 STEP 实体并打包
.step.json侧车文件。 - 轻量交互与多格式导出:
调用
cadgen viewer启动本地轻量 Web 服务,在浏览器中交互式查看模型细节;根据后续环节需要,同步导出 STL、3MF 或 2D 工程图 DXF。 - 增材制造质检与硬件闭环:
- 触发
dfam-check技能,针对目标加工工艺计算悬垂角度、危险薄壁与支撑体积; - 校验通过后,调用
gcode驱动底层切片引擎(如 PrusaSlicer 或 OrcaSlicer CLI)完成路径规划; - 最终通过
bambu-labs技能,经由局域网协议将切片文件分发至 3D 打印机启动物理制作。
- 触发
工程实战:从最小可运行示例到 CI/CD 集成
快速上手实践
通过 Skills CLI 安装该技能库,并配置基础运行环境:
# 安装 Agent 技能
npx skills add earthtojake/text-to-cad
# 安装核心编译引擎与几何框架
pip install cadgen build123d
编写一个包含参数化沉头固定孔的法兰盘示例 flange_sample.py:
"""参数化法兰盘建模示例"""
from build123d import *
from cadgen import step
@step
def flange():
# 定义直径 60mm、厚度 10mm 的圆柱基底
with BuildPart() as part:
Cylinder(radius=30, height=10)
# 对底面外边缘添加 2mm 平滑倒角
fillet(part.edges().filter_by(Axis.Z, reverse=True), radius=2)
# 中心开设 12mm 通孔
Hole(radius=6)
# 在直径 40mm 的分度圆上均布 4 个 M4 沉头螺钉孔
with PolarLocations(radius=20, count=4):
CounterSinkHole(radius=2.2, counter_sink_radius=4.5)
return part.part
执行编译并拉起本地预览界面:
# 编译并生成 STEP 实体及 Sidecar
cadgen compile flange_sample.py
# 启动本地 CAD 查看器
cadgen viewer flange_sample.step
终端执行日志展示:
[cadgen::daemon] Connected to warm daemon at PID 84210
[cadgen::build] Compiling flange_sample.py::flange ...
[cadgen::store] Object write: objects/sha256/a8f2c3... (Solid BREP, 42 KB)
[cadgen::export] Exported STEP: flange_sample.step (AP214 format, 108 KB)
[cadgen::export] Generated sidecar: flange_sample.step.json (Kinematics & metadata)
[cadgen::viewer] Local viewer listening at http://127.0.0.1:4200/
[cadgen::viewer] Serving flange_sample.step. Press Ctrl+C to stop.
生产环境配置与 Windows 平台注意事项
[!WARNING] Windows 11 Smart App Control (SAC) 拦截机制
cadgen底层的OCP(OpenCascade 绑定)包含开源社区构建的二进制原生 DLL 文件。在默认启用 Smart App Control 的 Windows 11 环境中,未包含商业数字签名的原生库会被系统拦截,进而导致ImportError: DLL load failed while importing OCP(系统事件 ID 3077)。
应对方案:在生产部署或自动化服务器中,推荐使用 WSL 2(Ubuntu 22.04+)运行环境,或在系统设置中做好对应的信任策略配置。
常用运维指令
# 运行环境诊断(检查 OCP、切片工具与系统安全策略状态)
cadgen doctor
# 查看特定模型的构建依赖与缓存失效原因
cadgen store why flange_sample.py::flange
# 无头模式生成指定分辨率的高清渲染截图
cadgen snapshot flange_sample.step --output ./preview.png --width 1920 --height 1080
# 清理超过 7 天的陈旧缓存对象
cadgen store gc --older-than 7d
自动化流水线实践 (GitHub Actions 示例)
在硬件团队的代码仓库中,可配置持续集成流水线,在提交代码时自动编译工件并校验可制造性:
name: CAD Validation Pipeline
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
build-and-verify:
runs-on: ubuntu-latest
steps:
- name: Checkout Source Code
uses: actions/checkout@v4
- name: Setup Python Runtime
uses: actions/setup-python@v5
with:
python-version: "3.11"
cache: "pip"
- name: Install System Libraries
run: |
sudo apt-get update
sudo apt-get install -y libgl1-mesa-glx libglu1-mesa
- name: Install Dependencies
run: |
pip install --upgrade pip
pip install cadgen build123d trimesh numpy
- name: Run Toolchain Health Check
run: cadgen doctor
- name: Compile Models to STEP and STL
run: |
cadgen compile models/ --format step,stl
- name: Verify Printability (DfAM)
run: |
python -c "
from cadgen.analysis import check_dfam
report = check_dfam('models/*.stl', min_wall_thickness=0.8)
if not report.is_printable:
print(f'::error::DfAM verification failed: {report.issues}')
exit(1)
"
- name: Archive Validated Artifacts
uses: actions/upload-artifact@v4
with:
name: compiled-cad-artifacts
path: |
models/**/*.step
models/**/*.step.json
models/**/*.stl
技术路线对比与工程落地边界
为了更客观地理解 text-to-cad 的设计权衡,我们将其与同类三维自动化方案进行横向对标:
全维度对比矩阵
| 评估维度 | text-to-cad (cadgen) | 3D 网格扩散模型 (Meshy / Tripo) | Zoo (KittyCAD) API | 传统脚本 CAD (OpenSCAD / FreeCAD) |
|---|---|---|---|---|
| 底层几何模型 | 精确 B-Rep 实体 (OpenCascade) | 多边形三角网格 (Mesh) / NeRF | 精确 B-Rep 实体 (自研引擎) | CSG 网格 (OpenSCAD) / B-Rep (FreeCAD) |
| 工业级 STEP 导出 | 原生支持 (AP214 / AP242 规范) | 不支持(逆向重构存在拓扑缺陷) | 原生支持 | 支持(FreeCAD 导出偶现缝隙) |
| 代码建模表达 | Python (build123d 现代参数化语法) | 无代码(黑盒提示词直接生成) | 专有 KCL 语言 | 专有 DSL (OpenSCAD) / 复杂 C API |
| 部署与隐私边界 | 100% 本地离线执行,无接口计费 | 依赖云端 GPU 订阅服务 | 依赖商业云端 API | 100% 本地运行 |
| 机器人与仿真链条 | 内置 URDF / SRDF / SDF 转换 | 无 | 无 | 需繁琐的第三方宏与外部脚本 |
| 制造环节集成 | 打通 DfAM、切片与局域网打印 | 无(网格非水密易切片失败) | 需手动导出并对接外部软件 | 需手动导出中间格式进行后处理 |
| Agent 技能体系 | 提供 11 个标准化 Agent Skills | 仅提供标准 Web 界面或基础 API | 仅提供常规 REST API | 缺少针对大模型 Agent 优化的协议层 |
推荐适用场景
- 硬件研发敏捷打样:针对传感器安装座、设备外壳、转接法兰等机械构件,利用自然语言或草图快速生成尺寸精确的模型,并直接完成增材制造闭环;
- 机器人结构与仿真开发:为多关节机械臂或移动机器人快速配置 URDF 连杆质量、惯性张量,并导出 MoveIt2 规划组(SRDF)与物理仿真世界(SDF);
- 参数化零件库批量派生:根据规格表批量输出多尺寸衍生构件,利用 CAS 内容寻址特性获得高效的构建复用。
不适用的场景边界
- 自由有机曲面艺术雕刻:对于角色模型、复杂布料皱褶或影视动画资产,基于网格渲染的 Blender 或扩散生成工具在表现力上远优于基于约束的参数化 CAD;
- 高级 A 级汽车曲面造型:尽管 OpenCascade 底层具备 NURBS 计算能力,但该项目目前的封装重点在功能性机械零件,尚未提供面向高级流线美学的高阶曲率(G2/G3)连续性控制工具。
生产实践避坑提示
[!IMPORTANT] 提示 1:防范拓扑命名漂移(Topological Naming Problem)
在参数化建模过程中,前序特征的尺寸微调可能导致几何面或边的内部索引发生变化。在编写build123d代码时,建议始终使用基于几何空间关系的语义过滤器(例如edges().filter_by(Axis.Z)),避免硬编码固定的数组索引下标。
[!CAUTION] 提示 2:长周期编译中的内存管理
在长时间批量编译大型装配体时,底层 C++ 几何计算分配的内存可能无法及时交还操作系统。在常驻 Worker 或持续集成环境中,建议为执行进程配置合理的内存限制与定期自愈回收机制。
结语
在工程数字化演进的过程中,AI 工具要真正融入实体研发,必须建立在严谨的数学几何、物理公差与标准数据协议之上。
earthtojake/text-to-cad 展现了一种清晰的技术思路:通过参数化 B-Rep 实体内核、细粒度的内容寻址缓存以及针对制造业的完整流程打通,使大语言模型能够胜任严谨的机械设计与制造协同工作。这种从代码到实体的确定性工程实践,为智能体走向物理制造提供了扎实的参考范式。