ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

text-to-cad 实战:用自然语言直接生成可编辑参数化 CAD 模型

2026/10/8 12:22:21 拓冰建站 浏览量
text-to-cad 实战:用自然语言直接生成可编辑参数化 CAD 模型 text-to-cad 这个词乍一听像是某个软件菜单里的隐藏功能实际上它代表的是近两年 CAD 领域最让人兴奋的一个方向用自然语言直接生成 CAD 模型。简单说你输入“一个带四个腰形孔的矩形安装板长 200 宽 100 厚 8”软件自动帮你把草图画出来、特征加上甚至生成好可编辑的参数化模型而不是传统的一步步点击命令。这篇内容我会把我在这个方向上的实际摸索、踩坑和目前能跑通的方案完整记录下来给想入坑的工程师和爱好者一条相对顺趟的路径。我最早关注它是因为做非标自动化设计时每天大量重复在画安装板、支架、法兰这类标准件一个零件少说十几分钟多则半小时。后来尝试把一部分工作交给文本生成工具虽然还没到“一句话搞定整套产线”的夸张程度但针对规则零件效率提升是肉眼可见的。这篇博客适合的人群很明确搞机械设计、结构设计、建筑设计或者只是对 CAD 二次开发和 AI 辅助设计有兴趣的人。新手也能看懂我会把原理、工具、坑点都交代清楚。1. 整体设计思路拆解为什么 text-to-cad 能颠覆传统建模方式1.1 传统 CAD 建模的痛点与文本生成的本质差异传统 CAD 建模的核心是人盯着屏幕一步步点选命令、输入坐标、选择约束关系。这个过程的问题在于模型是“被操作”出来的不是“被描述”出来的。比如要做一个法兰你脑子里已经有了法兰的完整定义但你还得通过拉伸、旋转、打孔、阵列等一系列操作把它表达出来。高频重复时这种“翻译”过程非常消耗精力。text-to-cad 走的是一条完全不同路线把建模过程抽象成“描述-解析-执行”三个环节。用户提供的文本本身就是对模型的完整定义系统要做的是理解文本中的几何信息、尺寸信息、特征信息然后通过参数化建模引擎把这些信息转换成可编辑的模型。这里的核心不是“自动点击按键”而是建立一套从语言到几何的映射模型。刚开始我觉得这个东西很玄学但当我拆开看后发现真正落地可行的方案通常不是端到端的黑盒而是基于规则加模板的半自动系统或者基于大语言模型进行关键信息抽取后再驱动参数化脚本。这套思路的好处是每一步都可控、可调试、结果可预期不会出现“只可远观不可编辑”的僵尸模型。1.2 为什么选参数化脚本作为后端而不是直接改内核很多人一谈到 text-to-cad就想到让 AI 直接操作 AutoCAD 或 SolidWorks 的界面。这个路径在 demo 里经常出现但生产环境里极度脆弱。因为图形界面操作依赖鼠标坐标、菜单状态、屏幕分辨率任何一点变化都会导致流程中断。更致命的是生成的模型是没有参数历史的后续改一个尺寸可能要全盘重来。我目前的方案是用自然语言解析结果去驱动参数化建模脚本。CadQuery、Build123d 这类 Python 库非常合适它们把建模变成代码表达几何特征清晰参数可调整模型历史完整。简单说就是把 AI 当翻译官把文本翻译成一棵“建模语法树”然后由脚本执行。这样做的好处有三层第一模型天然可编辑。你想把厚度从 8 改成 10改一行参数就行不用重新生成。 第二可控性好。每条规则、每个特征映射都是显式代码出了问题可以单步调试。 第三容易积攒模板。不同行业的零件表达方式差异大但建立一套基础特征库后新零件的适配成本会越来越低。1.3 整体架构中的三个核心模块一个能用的 text-to-cad 系统我认为至少要拆成三块语义解析器、模型映射器、参数化执行器。语义解析器的任务是把自然语言拆解成结构化信息比如类型、尺寸、位置、特征。这里我建议不要一上来就训练自己的模型先用现成的大语言模型做意图识别和槽位填充。后面我会细说怎么做。模型映射器处理的是“结构化信息”到“建模 API”的对应关系。比如识别到“腰形孔”这个特征就要映射到 CadQuery 里slot方法的参数。这块是整个系统里最麻烦的部分因为自然语言里同一个特征有无数种说法比如腰形孔也可以叫“长圆孔”“跑道形孔”“腰孔”模型映射器必须做归一化。参数化执行器相对简单它接收映射器的输出参数调用建模库生成模型文件同时输出工程图可用的视图。这部分只需要处理好坐标系约定、单位约定、命名约定就够了。我最初做的时候把大量精力放在解析器上以为只要模型聪明就能听懂人话。后来发现大部分问题出在“听懂了但做不了”——也就是映射器不够灵活。语言的多样性在 CAD 领域里尤为夸张同样是“板上有几个孔”孔位可以按阵列、按坐标、按均布、按中心距描述映射器没做好模型就会七零八落。2. 核心细节解析与实操要点从自然语言到 CAD 特征的完整映射2.1 建立领域专用指令集不是所有话模型都要懂text-to-cad 系统不需要理解人类的全部语言只需要理解你所在行业的常用指令。拿机械设计来说最常用的几何描述不超过几十种拉伸、旋转、孔、槽、倒角、阵列、镜像、抽壳。因此建立一份“领域指令集”非常关键。我这边的做法是列出了高频指令模板每个模板跟一个特征生成函数对应。例如“长 l 宽 w 高 h 的板” → 拉伸长方体“直径 d 的圆” → 草图圆加拉伸“厚 h 的法兰” → 旋转体“中心距 d1 的孔阵列” → 线性阵列/圆形阵列这些模板不需要覆盖所有情况但至少覆盖 80% 的日常需求。我用的是“模板优先 LLM 兜底”策略解析器先尝试匹配模板匹配失败才调用大语言模型做智能识别。这样既快又稳也避免了纯模板系统的僵硬。2.2 尺寸信息的抽取与冲突处理单位、参考系和显式缺省尺寸信息是 CAD 生成里最容易出问题的环节。自然语言里说“长 200 宽 100”但没说单位。国内工程师默认毫米但遇到部分行业用的英寸或者 m系统必须做出约定。我现在的策略是所有输入默认毫米如果有显式单位前缀如“2.5 inch”则自动换算并在日志里标注换算过程。另一个关键坑是参考系。同一句“右边开个槽”右边的概念取决于基准方向。我要求在指令里尽量使用绝对坐标或相对基准面描述比如“以原点为左下角向右开槽”。如果是相对描述比如“后侧中心”就需要系统先确定模型的当前方位再做向量换算。这块我吃过不少亏建议在解析层就输出规范化坐标不要临时计算。尺寸冲突问题更隐蔽。用户说“板长 200”又加一句“左边留 50 右边留 50”这就跟某次阵列间距产生矛盾。我的做法是让每个特征记录约束来源生成前做一致性检查冲突时给出警告并让用户确认优先级而不是擅自改尺寸。2.3 特征识别的归一化策略同一种特征百种说法领域内同一个特征的说法千奇百怪。腰形孔、长圆孔、跑道孔、slot其实都是一类特征。螺纹孔可以叫“牙孔”“丝孔”“tap hole”。倒角能说成“去毛刺”“倒 C 角”“chamfer”。我的处理方式是建立一份同义词表并不断从真实输入中喂养扩展。注意同义词表不是单纯字符串替换而是在语义解析层做归一化比如“倒 C 角”和“chamfer”都映射到统一的“倒角特征”然后再对参数做细分。这么做的好处是后续参数提取会非常干净不会出现同一个特征走了两条代码分支。2.4 语言模型作为解析器提示词工程的关键经验如果你也想用大语言模型来做语义解析我给你三个建议。第一给模型结构化输出格式不要让它自由发挥。我会让它输出 JSON里面固定字段包括feature_type、params、constraints、origin_desc。这样下游映射器可以直接解析不用反复猜测。第二把领域指令集和同义词表作为上下文塞给模型。模型自己会联想出很多新说法但你通过 few-shot 示例把典型输入输出喂进去能明显提升准确率。我常用 5 个示例覆盖不同说法效果比单纯说“你是 CAD 助手”强很多。第三对模型输出做 post-processing 校验。模型可能给出超出范围的长度、负值半径、或者不存在的特征类型必须加一层规则过滤。目前我的系统里有一个validation_layer专门做数值范围和类型检查识别失败时回退到模板匹配再不行就让用户补充。这套组合拳打下来常用零件的解析成功率能达到 85% 以上剩下的要么是描述过于模糊要么是用户自己都没想清楚。3. 实操过程与核心环节实现从“钢板带孔”到可编辑模型3.1 工具选型与环境准备我目前的实现是基于 Python 3.10 CadQuerymaster 分支 OCPOpenCASCADE Python 绑定。CadQuery 是建模型的主力它比 OpenSCAD 更适合机械类零件因为支持圆角倒角、布尔运算、扫掠和放样。OpenSCAD 也能用但它布尔操作太“硬”圆角经常要绕路做 fillet实在不如 CadQuery 顺手。环境搭建有几个注意点。CadQuery 目前强依赖 conda直接用 pip 容易在 OCP 环节出兼容问题。我用的是 conda 创建独立环境conda create -n cadgen python3.10 conda activate cadgen conda install -c conda-forge cadquerymaster如果是 Windows 环境不要用系统自带 PowerShell 直接pip install cadquery我试过几次OCP 二进制经常加载失败。用 conda-forge 的预编译包稳得多。3.2 一个可落地的范例由文本生成安装板加孔特征为了让你直观看到完整链路我挑一个最简单的例子描述是“200mm × 120mm × 8mm 的安装板四角开 6mm 通孔左上角倒 C3 角”。第一步语义解析。模板匹配触发了 4 个特征板{type: extrude, width:200, length:120, height:8, origin: [0,0,0]}4 个通孔{type: hole, diameter:6, positions: 以四角为圆心距边 10mm}倒角{type: chamfer, at_edge: 左上角两条棱边, size:3}第二步映射器把特征转换成 CadQuery 代码。代码如下import cadquery as cq # 创建安装板 result ( cq.Workplane(XY) .box(200, 120, 8, centered(True, True, False)) .faces(Z) # 选中上表面 .workplane() .rect(200 - 20, 120 - 20) # 距边10mm的孔位矩形 .vertices() # 取矩形四个角点 .hole(6) .edges(|Z) # 选中所有竖直边 ) # 单独的倒角需要额外处理这里用顶点选择会更精确 result result.faces(Z).vertices(Z).chamfer(3, verticesresult.faces(Z).vertices(Z).val().center().toTuple())实际上我上面代码里的chamfer部分写得比较草率CadQuery 的倒角通常选边而不是选点。更可靠的办法是先把左上角两条竖直边单独选出来chamfer_target result.faces(Z).edges(Z).filter_by(lambda e: e.start_point().x 0 and e.start_point().y 0) result result.chamfer(chamfer_target, 3)这地方你会发现真正实现的时候文本描述里“左上角倒角”要转换成选择特定边的逻辑。如果你的系统在映射层不做逻辑判断代码就会写死成只能处理“所有边倒角”。这也是我为什么强调映射器要保留语义信息不只是把字符串变成函数名。第三步导出文件。CadQuery 可以直接导出 STEP、STL 和 DXFcq.exporters.export(result, mounting_plate.step) cq.exporters.export(result, mounting_plate.stl)STEP 是给 CAD 软件用的保留实体STL 是给 3D 打印或快速预览用的。如果还要输出工程图CadQuery 可以用cq.exporters.dxf导出草图但工程图标注我还是习惯导入 FreeCAD 再做。3.3 建模规则里最容易忽视的坐标系约定text-to-cad 系统里坐标系约定决定了描述里的“上、下、左、右、前、后”是否有意义。我内部统一规定X 向右Y 向上Z 朝屏幕外。板类零件的底面默认在 Z0 平面拉伸方向为 Z。这样系统在解析“厚度”时就可以直接映射成 Z 方向高度。用centered(True, True, False)做板体时第三项 False 表示在 Z 方向不居中让底面贴住 Z0。这样后续在板上加孔时workplane定位会非常自然。很多新手建模喜欢全部居中后续定位孔位时就会发现坐标系飘忽不定。3.4 生成结果的校验不只检查几何还要检查“语义”模型生成完不是看一眼形状像就行。我会跑三组自动校验物理校验体积、质心是否在合理范围是否有干涉这用 CadQuery 的Volume,Center属性能轻松拿到。尺寸校验实际生成的模型边界尺寸是否与文本要求一致。比如要求 200mm实际是 201mm那就说明映射器的基准位写错了。特征校验孔数、倒角数是否匹配。这个通过查result.faces()数量和边数量能快速过滤一部分错误。我经常遇到的一种情况模型生成出来看起来非常正常但尺寸一测发现孔距错了。问题出在文本描述里“距边 10mm”的映射我最初把rect(200-20, 120-20)理解成了中心距为 180×100 的矩形但实际上孔位矩形的原点应该在(10,10)不是中心。这个坑很典型说明表面形状正确不等于语义正确。4. 常见问题与排查技巧实录文本生成 CAD 路上的那些坑4.1 解析器识别成功但执行器报错多半是参数类型问题我在开发中最高频的问题是模型信心满满地输出了feature_type: hole参数里给了position: [100, 60]但执行器报TypeError: expected a 3D point。因为 CadQuery 里定位孔一般用的是二维 workplane 上的坐标但我的代码在传给hole()之前忘记把二维点转换成三维点。排查这种问题我的习惯是在映射器输出后加一层to_cad_type转换把所有尺寸统一转成 float坐标统一加 Z 值。凡是遇到类型异常绝不直接在 CadQuery 调用栈里猜先在映射器日志里看参数格式。4.2 文字里说“对侧”但模型生成在错误方位这类问题主要是相对方向解析做得不够。文本说“右侧开孔”系统应该先判断模型的轴向方向再决定x还是x-。但如果前面生成的板体用了不同的工作平面X 轴方向可能是反的。我的解决方案是在生成每个零件前先定义一个“基准方位”结构体把前、后、左、右跟坐标轴的关系固定下来。比如板体生成时我把长边沿 X、短边沿 Y 作为默认方向并给用户提供覆盖入口。这样“右侧”永远指 X 侧不会因为建模顺序漂移。这套约定很笨但极有效。4.3 模型可编辑性差如果你直接生成网格后面就哭了有一点我必须提醒不要为了演示效果去生成网格文件当交付物。网格模型无法承载孔、倒角、特征树后续要改尺寸就得回到文本重新生成。而参数化模型导出 STEP 后在任何主流 CAD 软件里都能打开看历史特征改起来方便得多。我的建议是交付给团队时同时给出 STEP 和参数化脚本别只给一个 STL。如果对方只想要可视化再额外导一个轻量化 glTF 格式。4.4 与常用 CAD 流程的衔接文本生成只是前半场生成完模型不等于任务结束。实际工作中还需要把模型放进装配、出图、标注甚至做有限元简化。text-to-cad 的产出如何与现有 CAD 流程打通是整个方案能否落地的关键。STEP 格式是与 SolidWorks、中望 CAD、AutoCAD 之间交互最稳定的格式。我测试过在 SolidWorks 里打开 CadQuery 导出的 STEP特征树能识别成“拉伸”、“切除-拉伸”等基本可用。中断面曲线导出到 DXF 给 CAD 制图时文字标注可能需要手动补充这就不细说了属于 CAD 出图基本功。另外针对“cad图纸合并”、“cad导入layout步骤详解”这些热词我提一个相关体会如果你用 text-to-cad 生成的是单个零件最后还是要进入传统 CAD 环境做装配。我会把装配约束信息也纳入文本描述体系比如“该板与另一块板的长边贴合”然后在生成后利用 FreeCAD 的装配工作台做约束。虽然多花一点时间但装配体改动同步起来比零散导出再手工装配要省心。4.5 文本描述模糊到一个程度系统该拒绝而不是猜这是我踩了很多次坑才总结出来的原则。当输入描述缺少关键尺寸或者方向指向不明确时宁可让系统提示“缺少 X 尺寸”也不要默认一个值继续跑。因为默认值一旦出错用户要花在排查模型错误上的时间远多于手动补全一句话的时间。我最初为了追求“一句话出模型”的效果默认了很多隐式参数结果经常生成出一个莫名其妙的造型用户还要花时间解释为什么不是他要的样子。后来我在系统里加了feedback回路缺参数时主动提问模型反而更受团队认可。这也说明一款工具的使用体验并不完全由“自动程度”决定而是由“可控程度”决定。4.6 中文描述下的特殊坑单位词和量词如果你做的是中文文本生成 CAD 模型还要额外处理量词和单位词的灵活性。“一个 200 毫米的板”和“一块 200mm×100mm×8mm 的安装板”以及“尺寸 200 的方形板”三种说法对应的语义是完全不同的。第一种歧义大第二种最完整第三种要结合上下文判断是边长还是直径。我给解析器设计了一套“补全策略”先识别出所有维度的量词位置再根据特征类型推断缺失维度。比如“方形板”意味着长宽相同“圆形板”需要直径而不是长宽。这套策略效果不错但依然无法解决输入本身含混的情况此时只能靠反馈回路线下补充。5. 后续扩展方向从文本到装配体、从单零件到布局当前这套 text-to-cad 实践已经能稳定生成大量规则零件但距离“自然语言设计整个产品”还有明显距离。我接下来的探索有两块一是把文本解析扩展到装配层级支持“A 板放在 B 板的右侧用 4 个 M6 螺栓固定”这类跨零件约束二是把布局布线纳入文本描述比如“三个腰形孔沿中心线等距分布”让布局规则也能被显式抽取。另外我在考虑把 CAD 模型细分类别跟行业模板做深绑定。比如钣金、法兰、机架、装饰条各有专属的特征集。未来一个非标工程师只需要描述装配意图底层模板库自动匹配最合适的结构形式模型的生成速度还能再上一个台阶。在这个方向上我认为最值得投入精力的是“约束表达”而不是“特征识别”。因为特征识别已经比较成熟了反而是装配约束、尺寸链约束这些更难用文本表达。这也是为什么我把大量时间花在语义解析和约束校验上而不是继续加新特征。回到最初的问题text-to-cad 到底是不是未来从我这段时间的实际体验来说它至少在重复性建模领域已经具备生产力价值。它不会取代设计师但它会取代大量无效的重复点击操作。我更愿意把它理解成一个“能听懂你说话的高级建模助手”你描述需求它完成建模然后你依然可以做深度的编辑和判断。这套流程落地之后我做非标壳体设计的时间从原来的一小时压缩到十几分钟其中有十分钟还是在确认孔位和螺纹规格。这个效率提升已经足够让我坚定地继续往下走。最后分享一个实用小技巧当你调试映射器时不要只测试正面案例多收集那些“说得不太标准”的负面案例。比如用户说“板上打几个孔”这句到底几个孔你能识别出孔特征但数量缺失。把这类模糊案例单独建立一个测试集每轮模型迭代都跑一遍你会发现系统在“识别模糊意图”上进步得比“识别标准句子”上快得多。这是我目前觉得最值得投入的优化方向。