text-to-cad 原理与工程落地:从自然语言到可编辑参数化模型
1. text-to-cad到底解决什么问题1.1 先把“能生成3D模型”和“能生成零件”分清楚先说个结论text-to-cad 不是让 AI 随手吐一个三维模型出来而是要输出能进加工、装配、仿真流程的“正经 CAD 模型”。很多第一次接触这个概念的人以为只要对着电脑说一句“帮我画一个圆角矩形盒子”就能得到和 SolidWorks 里一模一样可编辑的零件——这个期待是对的但离技术现状还有一段距离。我见过不少项目在这个点上栽跟头。团队拿一个文本生成点云或网格的开源模型跑通了 demo兴奋地拿去给机械工程师看结果对方打开模型第一句话就是“这个孔是贯通的吗圆角能不能改 R3壁厚均匀吗”工程师关心的不是渲染效果而是这个模型能不能放进加工环境、能不能改尺寸、能不能做有限元。text-to-cad 的核心价值恰恰就藏在这些“能不能”里。这里要区分两个概念一个是“生成 3D 形状”另一个是“生成 CAD 模型”。前者可以是一团点云、一个 mesh、一张深度图只要视觉上像就行后者必须包含参数、特征、约束、历史树。CAD 模型的本质不是形状而是一串“制造意图”的连续记录。比如一个法兰盘在 CAD 系统里不是一个圆柱加六个孔而是由“拉伸基体、切除材料、阵列孔”这些特征组成的操作序列。text-to-cad 要解决的就是这个问题把自然语言描述转换成工程师能继续编辑的特征序列。我常用一个类比来解释传统建模就像口述做菜给一个厨师厨师会按你的步骤切菜、配菜、下锅但你要是只给“我要一道好吃的菜”厨师只能自由发挥而 text-to-cad 的目标是让 AI 变成那个能听懂“少盐、多醋、不要香菜”的帮厨而不是直接把外卖端上桌。1.2 直接生成网格为什么难落地市面上很多“文本转 3D”项目比如文本生成点云、文本生成神经辐射场其实走的是另一条路线。它们擅长生成视觉上惊艳的有机体一只猫、一把椅子、一个角色概念。但这类结果到了 CAD 场景里几乎不可用原因很现实。网格模型没有工程语义。一个由几十万三角面片组成的 mesh里面根本没有“圆柱”“通孔”“圆角”这些概念。你想把孔直径从 8mm 改成 9mm网格模型只能整体重生成或手动雕刻没法像参数化模型那样改一个数字。同时网格模型的拓扑质量很难保证经常出现破面、重叠三角形、法线翻转、非流形边。拿去切片打印切片软件可能会直接报错拿去 CAM 编程刀路更是没法算。还有精度问题。工业 CAD 的尺寸精度通常是微米级一个机械零件如果台阶厚度差了 0.1mm装配就可能出问题。而生成式网格模型天然是近似表示它的顶点坐标、面片密度都服务于“看起来像”而不是“量起来准”。这就像用像素画去指导数控机床加工本质上不是同一个信息载体。所以 text-to-cad 的技术路线从一开始就注定不能走“生成网格”这条捷径而是要让模型学会输出参数化操作。哪怕最终也要导出成 mesh 用于渲染或打印但在中间环节必须有可编辑、可约束、可重算的 CAD 数据结构。谁能在这一层做得稳谁才能真正落地。1.3 谁适合用text-to-cad先说最直接的用户非专业建模者。很多 3D 打印玩家有明确需求我要一个能卡住摄像头的小支架、一个路由器挂架、一个补缺的塑料垫片。他们不想学一整套 CAD 软件只想用自然语言描述尺寸和功能。text-to-cad 可以成为“设计助手”帮他们生成第一版模型再进软件微调。另一类是设计师和结构工程师的草图阶段。工程师经常开会时口头描述一个零件宽度大概 60长度 100厚度 3四周开四个沉头孔。过去要回工位慢慢画如果有一个 text-to-cad 工具能先画出基础特征再到 CadQuery 或 SolidWorks 里补细节效率会高不少。注意这里说的是“辅助”不是“替代”目前替代还不现实。还有自动化批量生成场景。比如电商平台要按不同参数生成成千上万款定制铭牌、外壳、齿轮。用传统模板参数化当然也能做但如果有自然语言入口业务人员就能直接描述需求不需要开发改代码。教学场景也很有意思让学生用自然语言描述设计意图再对照生成的 CAD 特征树学建模逻辑比从零学命令快得多。我个人的判断是text-to-cad 短期不是要取代 CAD 软件而是把人和三维建模之间的“输入门槛”降低一大截。它能做的事是让“画一个东西”变得更像“说一个东西”。2. 主流技术路径从文本到参数化模型2.1 核心是把语言翻译成构造步骤目前比较靠谱的 text-to-cad 实现几乎都是同一个思路让大型语言模型把文本翻译成一份 CAD 构造脚本。所谓 CAD 构造脚本就是一系列可执行的建模操作例如“创建一个平面草图画一个矩形拉伸到 10mm在中心打一个直径 5mm 的孔”。这类脚本语言包括 OpenSCAD、CadQuery、SolidPython、FreeCAD 的 Python API 等。为什么要用代码作为中间表示因为文本是离散的代码也是离散的语言模型处理连续的点云反而不擅长。文本描述“凸台边长 20高 5”可以直接映射到代码里的cube([20, 20, 5])这种 token 级别的映射关系是语言模型天然可以学习的。反过来如果让模型直接回归三维坐标误差控制非常难而且很难引入“约束”信息。这里有个关键点CAD 脚本不是简单的一句代码而是一棵树。OpenSCAD 的布尔运算本身就是一个 CSG 树CadQuery 则是面向对象的特征序列。我们要让 AI 学会的是如何从自然语言中提取实体、属性、空间关系并组织成合法的操作树。比如“在圆盘中央打一个通孔”模型不仅要识别出“圆盘”和“孔”两个实体还要知道“中央”是位置约束、“通孔”是贯穿特征。所以在实际项目里我不建议直接用大模型输出纯 OpenSCAD 代码。更稳的方案是设计一个受限的中间 DSL领域专用语言比如 JSON 格式的特征列表{ features: [ {type: cylinder, radius: 20, height: 10, origin: [0, 0, 0]}, {type: hole, radius: 4, origin: [0, 0, 0], through: true} ], units: mm }然后写一个解释器把这个 JSON 转成 OpenSCAD 或 CadQuery 脚本。这样做的原因是让大模型直接生成自由代码语法错误率太高但如果让它生成结构化 JSON再交给固定解释器渲染就把“语义理解”和“语法生成”分离了。前者是大模型擅长的后者是传统代码可以兜底的。2.2 三种常见表示空间怎么选text-to-cad 的技术路径中中间表示的选择决定了整个系统的上限。我总结下来主流方案有三类。第一类是程序化代码表示代表工具是 OpenSCAD、CadQuery。它生成的模型自带参数和特征可编辑性最强也最容易验证。缺点是表达能力受限于脚本语言复杂的自由曲面很难表达需要依赖放样、扫掠、曲面建模等高级操作。第二类是隐式场表示比如 SDF符号距离场、占用场。这类表示适合生成有机形状比如阀体、外壳、人体工程学手柄。模型输出一个函数空间中每个点返回“到表面的距离”或“是否在体内”再从函数里提取等值面生成网格。优点是表达能力强能生成任意拓扑缺点是提取网格后仍然是 mesh无法直接进入 CAD 特征树需要再做逆向。AutoSDF、Point-E 这类方法都在这个方向上。第三类是点云或体素表示通常作为中间输出再配合后续的曲面重建进入 CAD。点云本身不带任何工程语义需要额外步骤因此目前更多用于“文本生成形状”的研究不太适合直接做机械零件。我给一个不太严谨但很实用的选择建议如果目标是加工件、标准件、装配体优先选代码生成因为特征、尺寸、约束都在如果目标是概念外形、外观件可以考虑隐式场如果只是做设计灵感预览那就无所谓了点云、网格都行。也就是说越接近制造环节越要偏向可编辑的程序化表示。2.3 端到端生成与传统两步走的取舍有些研究论文追求一个模型从文本直接输出 CAD 操作序列也就是端到端。这种方案听起来很爽实际训练起来却非常吃数据和算力。CAD 操作序列本身是一种带层级结构的程序语言模型要同时学会语义理解、几何推理、语法约束和参数回归任何一个环节出错都会崩盘。我见过的端到端 demo大多是训练数据里见过的类似句式能跑通换一个说法就完全失灵。相比而言两步走方案在工程上更稳妥。第一步先用语言模型做信息抽取识别文本中的实体、数量、单位、位置关系。第二步再用规则或模板规划生成 CAD 操作。比如“一个 40mm × 30mm × 5mm 的底座四角带 M3 沉头孔”第一步先抽取出“底座、四个孔、M3、矩形阵列”第二步查标准件库得到 M3 沉头孔的尺寸然后生成 CadQuery 代码。两步走的好处是可以引入外部知识库和规则约束。沉头孔的标准尺寸不该靠模型“想象”而是查表。倒角该倒多大、螺纹底孔该钻多大都应由工艺规范决定。这些信息用外部规则注入比让模型硬记可靠得多。所以我的判断是当前阶段工程应用应优先做可控的分步系统而不是迷信一个“黑盒”端到端模型。3. 落地实操从一句描述到可打印的STL文件3.1 先搭一个最小可用的环境拿一个最简单的场景举例从自然语言生成 OpenSCAD 模型再导出 STL 用于 3D 打印。这个流程足够小却覆盖了 text-to-cad 的几个关键节点语义解析、代码生成、渲染校验、导出制造格式。环境准备只需要三样东西Python 环境用于调用大模型和编写解析逻辑OpenSCAD 命令行工具用于把脚本渲染成 PNG 或导出 STL以及一个文本编辑器或 Jupyter Notebook。如果你希望生成更现代的脚本式模型也可以装 CadQuery它的 Python API 比 OpenSCAD 更接近传统 CAD 的特征思维但最小示例用 OpenSCAD 就够了。安装 OpenSCAD 之后记得确认命令openscad在 PATH 里。在 Linux 下可以用apt install openscadmacOS 下用 Homebrew 安装Windows 下安装后手动把可执行文件路径加进 PATH。这个步骤看起来简单但很多人卡在脚本调用时找不到可执行文件后面所有自动化都会报错。3.2 一个从文本到OpenSCAD脚本的完整示例假设用户输入这样一句话“一个直径 40mm、高 10mm 的圆柱中心打一个直径 8mm 的通孔。”这是一个非常典型的入门级描述。先让大模型做结构化抽取输出 JSON{ base: {type: cylinder, radius: 20, height: 10}, hole: {type: hole, radius: 4, through: true} }然后由一个解释器生成 OpenSCAD 脚本$fn 64; difference() { cylinder(r 20, h 10); cylinder(r 4, h 10); }这里有两个细节常被新手忽略。第一文本说“直径 40mm”半径是 20mm文本说“直径 8mm”半径是 4mm。模型如果不理解“直径”和“半径”的转换生成结果会大错特错。所以在结构化表达中我建议直接统一使用半径并把“直径/半径”的转换放在语义解析阶段完成不要让解释器再去猜。第二OpenSCAD 的$fn参数控制圆的逼近精度。实际打印时如果$fn设置成 64圆柱侧面看起来已经足够光滑但如果用于精密零件建议用更高的$fn或改用$fa、$fs控制角度和尺寸误差。还有一点通孔的建模用cylinder加上difference布尔减法是常规做法但如果你希望孔在工程上更真实考虑锥角、沉头等特征时就不能只用一个简单的圆柱了那属于后处理阶段需要补充的工艺细节。生成脚本后立刻进行渲染预览在命令行执行openscad -o preview.png -D $fn64 part.scad如果命令没有报错并生成了一张正常图片说明基本语法没问题。但别高兴太早这只是第一步。3.3 不能只看渲染图自动校验的四个环节文本生成代码最大的风险是“看起来对实际不能用”。很多 AI 生成的 OpenSCAD 模型渲染预览能通过切片时却出问题。我自定义了一套四步校验流程每次批量生成都跑一遍。第一步是语法校验。用 OpenSCAD 的--check-parameters这类参数检查或直接用 Python 的 AST 解析脚本看看有没有未定义变量、括号不匹配、函数名拼错。代码层面的错误要最先干掉。第二步是几何校验。导出 STL 之后用admesh、MeshLab或 Python 的trimesh库检查 STL 是不是闭合的流形有没有朝向错误的面、破洞、自相交。对于打印来说非流形模型等于废件。第三步是尺寸校验。把脚本里的关键参数抽出来和用户输入的要求做比对直径对不对、高度对不对、孔位间距对不对。这一步不是看渲染图而是做数值断言。比如用户要求“中心孔距底面 30mm”生成的代码里translate([0, 0, 30])就必须真有一个30。第四步是工程校验。是否有拔模角度壁厚是否小于打印机能承受的极限孔是否有过盈配合需要这类规则没法靠单一模型解决需要一套规则库。我的做法是把校验规则写成 Python 检查器在生成流水线里逐个执行检查不通过就触发“重新生成”或“标记人工审核”。3.4 批量生成时的工程化提示当你开始批量处理几十条描述时就不能一条条手动跑命令了。我会把所有流程包装成一个函数def text_to_stl(description: str, out_path: str): spec llm_extract(description) script build_openscad(spec) if not validate_syntax(script): raise ValueError(syntax check failed) tmp_scad write_temp(script) preview render_preview(tmp_scad) stl_path export_stl(tmp_scad, out_path) if not validate_mesh(stl_path): raise RuntimeError(mesh not manifold) return stl_path这个函数里我刻意把每一步拆开原因是方便定位问题。如果生成的 STL 流形不通错误信息可以直接告诉你是语法、几何还是尺寸阶段失败而不是让你面对一团乱麻的报错日志。还有一个工程化细节大模型的 temperature 参数要调低。text-to-cad 和聊天不同这里要的是稳定输出不是创意发挥。temperature 设置在 0.1 到 0.2 之间能显著减少随机生成的“胡话参数”。另外system prompt 里必须写明“只输出 JSON不要解释”否则模型把思考过程也输出出来解释器直接崩溃。4. 常见问题与排查技巧实录4.1 文本歧义AI把“薄壁”理解成模型的一个薄片自然语言天生有歧义这在 text-to-cad 里会被放大。比如“两孔之间的薄壁厚度是 2mm”AI 可能把这个“薄壁”理解成单独一个薄片实体而不是两个孔之间的距离约束。我遇到最典型的例子是用户说“做一个小外壳壁厚 1.5mm”结果生成的模型是“一个壁厚 1.5mm 的实体板”而不是一个空心的薄壁容器。解法有两种。第一种是在提示词工程里做约束要求模型把“壁厚”识别为“壳操作”或“布尔减去的内部偏移”并且在中间表示里明确字段wall_thickness。第二种是后规则校验如果检测到文本里出现“外壳”“盒体”“壁厚”等词汇而生成的模型没有布尔挖空操作就判定为语义解析失败触发重新生成。遇到歧义时我倾向于让模型输出多个候选解释再让用户选择。比如“做一个长 50 的盒子”到底是内长还是外长先让模型生成两个版本标注“内尺寸版本”和“外尺寸版本”这种交互比强行让 AI 猜一个要可靠得多。4.2 尺寸单位与半径直径混淆单位问题是 text-to-cad 的隐形杀手。CAD 领域默认用毫米但普通用户可能说“4 厘米”“3 英寸”。如果系统没有单位换算后面所有尺寸都会对不上。我的建议是在语义解析阶段直接统一到毫米并在 JSON 里记录原始单位和原始数值方便追溯。另一个高频错误是“直径/半径”不分的幻觉。用户说“直径 10 的孔”模型却生成r 10。这个问题看起来很蠢但语言模型非常容易混淆因为“10”出现在描述里模型就倾向于直接作为参数。补救方法是建立关键词归一化表与“直径”对应的 key 是diameter然后在解释器里做radius diameter / 2而不是让模型自己换算。4.3 布尔运算与拓扑错误OpenSCAD 的difference、union、intersection是 CSG 布尔运算对输入几何体的要求很严格。当两个圆柱共面、一个立方体正好贴住另一个立方体的面时OpenSCAD 可能产生退化面、零厚度边最后导出的 STL 流形不闭合。最典型的场景是“在方形底板的中心挖一个刚好与板厚度相等的贯通槽”。由于槽高度和板厚度完全相等布尔求差时两个体在 Z 方向“恰好相切”软件无法稳定判断边界渲染图上可能显示正确导出 STL 后却出现裂缝。排查策略是对每个布尔操作“留一点点余量”。比如挖槽的高度比底板厚度多 0.001mm或者把分割平面做一次微小偏移让布尔操作“穿过”而不是“擦过”。经验规则是参与布尔运算的体尽量让它们有明确的相交区域避免共面接触。4.4 LLM幻觉代码与参数失控大模型生成代码时会一本正经地编造不存在的函数或参数。比如 OpenSCAD 里根本没有chamfer圆角命令它却可能生成chamfer(...)。这种问题特别的隐蔽因为脚本报错后初学者第一反应是去查 OpenSCAD 文档没想到是模型在“一本正经地胡说八道”。解决办法是不要让它直接输出“自由文本代码”而是让它生成受限的 JSON 特征指令再由本地的“可执行函数库”映射到 OpenSCAD 或 CadQuery。如果某个特性比如倒角当前还不支持JSON 解释器就直接报“不支持该特征”而不是让模型临场发挥。另一个幻觉点是参数范围。模型可能生成半径 1e8 的巨大圆柱或者负高度的立方体。所以每个参数都要做范围检查radius 必须大于 0 且小于 1000height 必须大于 0 且小于 1000。数值校验是成本最低、收益最高的防线。4.5 数据依赖与泛化边界text-to-cad 模型的泛化能力目前受限于训练数据。开源社区在做 Text2CAD 这类数据集把 CAD 模型的操作序列和文本描述配对。这类数据合成思路是对的但覆盖范围还比较窄大多是机械零件、规则几何体。一旦遇到汽车曲面、复杂装配体、需要自由曲面建模的造型模型的表现就会断崖式下跌。所以我的建议是把它当“规则零件的辅助设计器”用别拿它当“万能建模师”。在业务落地时先盘点自己的需求是否落在训练数据覆盖范围内。如果都是板件、轴、套、孔系结构那 text-to-cad 能发挥很大价值如果涉及外观创意设计建议找另一个技术路线。5. 工具选型与学习建议5.1 不同需求对应不同技术栈需求场景推荐中间表示推荐工具理由机械零件、标准件特征序列CadQuery / SolidPython贴近 CAD 特征思维参数改动方便3D 打印外壳、支架CSG 树OpenSCAD语法简单AI 容易生成验证快概念外观、自由曲面隐式场SDF / 神经隐式模型表达能力更强适合有机形态装配体、多零件设计参数约束网络FreeCAD Python API支持装配关系但技术门槛更高纯设计灵感预览点云或网格现成文本生成 3D 模型快但不适合工程化这段表格不是绝对标准但可以作为技术选型的第一层过滤器。机械场景里我强烈建议优先掌握 CadQuery。它的思想是“先建平面草图、再拉伸旋转、再打孔”和主流 CAD 软件的操作逻辑一致所以模型生成的代码也更接近真实设计步骤。5.2 开源项目怎么读才不走弯路很多人读 text-to-cad 相关的论文或开源仓库一上来就盯模型架构、loss 函数结果越看越晕。我建议先看数据再看中间表示最后看模型结构。因为这类任务最大的难点往往不是模型而是数据如何构造。先看训练数据长什么样一条文本描述对应几个操作步骤操作步骤是用序列化的 JSON 表示还是一段 CadQuery 代码如果数据本身质量不高模型再先进也白搭。再看中间表示是否支持“可逆执行”。也就是从表示能不能直接重建出模型并且能不能方便地做局部修改。如果中间表示是固定长度的向量那基本不具备工程价值顶多发论文。最后才是模型。我个人的经验是当前阶段与其去训练一个新模型不如先在大模型预训练基础上做少量微调或直接做 in-context learning。LSTM 时代那种从零训练序列模型的方式已经被大模型取代了别走回头路。5.3 几条写在最后的大实话如果让我总结 text-to-cad 真正重要的东西我会说不是模型从文本生成能力而是“约束系统”。一个能让 AI 自由发挥的文本生成器和一个能把结果约束在制造规则之内的生成器是完全不同的产品。普通用户只看到渲染图工程师却会检查尺寸、公差、螺纹孔、壁厚、材料收缩率。这些约束越早进入系统落地的概率越大。在实际操作中我把大模型当“翻译官”而不是“设计师”。它负责把用户的话翻译成结构化诉求剩下的几何生成和校验交给规则系统。这样可以充分发挥大模型的语义理解能力同时避免它的幻觉和不确定性。你可以在提示词里加上一句话“如果你的描述有歧义请输出你能想到的默认假设并单独列出假设条件。”这比让模型闷头生成更可控。还有一个小技巧每个生成的模型都保留当时的“输入文本、中间 JSON、最终脚本”三件套存成一个可追溯的 case。下次模型表现不对时翻出历史 case 对比能更快定位是语义抽取问题还是解释器问题。我就靠这个办法把模型的单次成功率从八成提到了九成以上。最后再分享一个我常用的验证思路拿到一个 text-to-cad 生成结果别先急着看正面渲染图先剖开看内部。把模型切一半看壁厚是否均匀、孔道是否贯通、倒角是否如预期。文本生成模型的很多错误藏在内部比藏在表面多得多。做设计工具的人一定要有“切开模型”的习惯。