Text-to-CAD实战:自然语言生成可编辑CAD模型的全流程解析
2026/9/20 0:54:06 网站建设 项目流程

做CAD设计的人应该都有过这种瞬间:脑子里面已经构思好了一个零件的形状,但手放到鼠标上之后,对着草图界面发了十分钟呆。画个法兰盘要先算圆心、切线、阵列角度,建个支架得琢磨拉伸方向、拔模斜度、圆角顺序。这些操作本身不难,难的是把脑海里的语言化描述,一点点翻译成几何约束和特征树。前几年大家觉得这事只能靠熟练度硬扛,但从2023年开始,一个叫text-to-cad的方向冒了出来,意思是直接用自然语言描述,让AI生成可编辑的CAD模型。

我今年在好几个项目里深度试玩了这条技术路线,从最早基于OpenSCAD脚本拼接的方案,到后来用大模型直接生成特征历史序列的pipeline,踩了不少坑,也摸出了一些门道。这篇文章不打算铺开讲论文公式,而是想从一个使用者和二次开发者角度,聊聊text-to-cad到底能做什么、不能做什么、上手时要避开哪些雷,以及如果你想在自己的工作流里接入这套东西,最合理的姿势是什么。

1. 整体设计与思路拆解

1.1 text-to-cad到底在解决什么问题

先说一个容易混淆的概念。很多人把text-to-cad和text-to-3D当成一回事,但实际上它们的目标完全不同。text-to-3D(比如常见的扩散模型生成Mesh或NeRF)追求的是视觉上好看、渲染出来唬人的几何体,适合游戏资产、影视视效、概念可视化。text-to-cad追求的是工程上可用、结构上合理、能进参数化建模流程的实体模型,典型特征是有明确的草图轮廓、拉伸旋转特征、倒角圆角、孔位阵列,并且特征树干净、可编辑。

打个比方,text-to-3D做出来的是"雕塑",你只能远观;text-to-cad做出来的是"工程图纸",你得能改、能装配、能出加工路径。这中间隔着一条巨大的鸿沟——CAD模型本质上是特征历史序列(feature history sequence),而不是一堆三角面片。一个法兰盘在Mesh里可能是一万个三角形,但在CAD的特征树里就是"草图+拉伸+六个孔+倒角"这么几句话。

所以text-to-cad真正要解决的问题,是让模型学会从自然语言中抽取几何意图,然后转换成CAD软件能识别的特征操作序列。这比单纯生成一个形状要难得多,因为它要求模型理解语言里的隐含约束,比如"对称""等距""贯穿""沉头"这些词,在CAD里都有明确的工程语义。

1.2 为什么是"生成特征序列"而不是"直接生成模型"

早期尝试过直接让神经网络输出体素或者点云来表征CAD模型,效果都不理想。原因很直接:CAD模型的编辑性、参数化关联和拓扑关系在离散的体素表示里会全部丢失。你生成一个法兰盘的体素模型,得到了一个看起来像法兰盘的东西,但它没法改孔径,没法阵列,没法导入SolidWorks继续往下设计。

后来业内逐渐形成共识:应该把CAD建模过程看作一个程序合成问题。一个模型就是一段程序——特征操作序列,每个特征有类型、草图参数、布尔运算方式。这样生成出来的东西天然具有CAD的层次结构,可以回溯、可以修改、可以重新参数化。这个思路在DeepCAD数据集和相关论文里被验证得比较充分,也成了后来Text2CAD等工作的基础。

选择特征序列路线还有一个工程上的好处:训练数据的获取相对容易。CAD软件里现成的模型都有特征树,把特征树转成token序列,再把对应的自然语言描述配对,就能构造大规模训练集。相比之下,Mesh类的生成需要大量人工标注语义,成本高得多。

1.3 核心技术栈拆解

从实现角度,一个完整的text-to-cad系统通常由几个层次构成。首先是语言理解层,负责把自然语言中的尺寸、形状、位置关系、特征类型提取成结构化的槽位;其次是几何推理层,负责把槽位信息映射成具体的草图坐标、约束关系和特征参数;最后是代码生成层,负责把参数组合成合法的特征序列或脚本代码。

底层模型方面,目前主流路线有两类。一类是端到端的Transformer模型,输入语言token序列,输出CAD特征token序列,代表性工作有Text2CAD和CAD-GPT系列;另一类是借助大语言模型(LLM)的推理能力,让LLM写OpenSCAD或FreeCAD的Python脚本,再由脚本引擎执行生成模型。两条路线各有优劣:端到端模型速度快、输出稳定,但可解释性差、对复杂约束的理解有限;LLM+脚本路线灵活、能做推理和规划,但速度慢、输出不稳定,经常需要多次采样才能得到可用结果。

我自己实际测试下来,比较折中的做法是两条路线结合:用端到端模型做初稿生成,再用LLM做后处理脚本修正。这样的好处是兼顾速度和精度,坏处是工程复杂度上升了不止一个量级。

2. 核心细节解析与实操要点

2.1 语言描述是怎么变成几何参数的

这里面最核心的环节是"槽位填充"(slot filling)。用户说"生成一个直径50mm、厚度10mm的圆形法兰盘,中心有一个直径20mm的安装孔,周围均匀分布6个直径8mm的螺栓孔",这段描述里其实包含了好几个层次的几何信息。

第一层是特征类型:"圆形法兰盘"意味着基础特征是旋转体或拉伸体,"安装孔""螺栓孔"意味着后续要打孔特征。第二层是尺寸参数:50mm、10mm、20mm、8mm这些数字必须被准确识别并绑定到正确的特征上。第三层是空间关系:"中心""周围""均匀分布"决定了草图坐标和阵列参数。第四层是隐含约束:"6个"暗示了圆周阵列的个数,"均匀"暗示了360度等分。

端到端模型没有显式地做槽位填充,但它的注意力机制实际上隐式地在做这个任务。你在实际使用时要注意,语言表达越结构化,模型的理解准确率越高。我测试过同样一个法兰盘,用"直径50的圆盘打6个孔"和"做一个圆形的法兰,上面有六个螺栓孔绕着圆心均匀分布"两种描述,后者生成的模型在孔位精度上明显更好。

实操上的技巧是,给模型喂描述时尽量按"主体形状—关键尺寸—特征操作—空间关系—附加要求"的顺序组织句子。这个顺序跟大多数CAD建模的逻辑顺序是一致的,模型更容易对齐语言和几何语义。

2.2 草图与特征序列的token化逻辑

要把CAD特征历史序列变成模型能处理的token,需要定义一套编码规则。以DeepCAD和Text2CAD采用的方式为例,每个特征被拆解成几个部分:特征类型(拉伸、旋转、倒角、孔等)、草图参数(直线、圆弧、圆心坐标、半径)、拉伸深度、布尔运算方式。

举个具体的例子,一个简单的L形支架的特征序列可能长这样:

REVOLVE | sketch: [LINE(x0,y0,x1,y1), LINE(x1,y1,x2,y2), ARC(...)] | angle: 90 | boolean: NEW EXTRUDE | sketch: [CIRCLE(x,y,r)] | depth: 5 | boolean: SUBTRACT FILLET | edges: [1,2,3] | radius: 2

模型要做的事情就是把自然语言序列映射到这组token序列。这里有个很关键的设计问题:草图中线的端点坐标是绝对坐标还是相对坐标?实际训练中普遍采用相对坐标或者归一化坐标,因为这样能让模型对不同尺度的模型有更好的泛化能力。你如果自己动手做数据集,一定要把坐标归一化这一步处理好,否则模型会对训练集里的尺寸范围过拟合。

2.3 约束求解:让生成结果从"像"到"能用"

光有形状还不够。CAD模型最重要的特性是参数化驱动——你改了孔的位置,周边的倒角和阵列应该自动跟着变。这就要求生成的模型必须带有约束关系。

这一步在实操中是最容易翻车的。端到端模型生成的模型,很多只是"看起来对",打开草图一看,线的端点没有重合约束,圆孔没有同心约束,阵列没有关联到中心轴。这种模型一旦进去编辑,稍微动一个参数,整个模型就散架了。

想要解决这个问题,有几个方向可以尝试。第一个方向是在生成后处理阶段,用约束求解器(如PlanG、Sympy几何约束模块)对草图做自动约束补全,把缺失的共点、共线、垂直、同心等关系补上去。第二个方向是在模型训练时,在损失函数里加入约束一致性约束,但这需要比较强的算法背景才能实现。第三个方向是走LLM+脚本路线,让生成的脚本直接包含约束定义,比如OpenSCAD的语句天然就是参数化的。

从我个人的实践看,中小团队最务实的方案是第一个方向:生成模型跑一个初稿,然后用约束求解脚本做后处理。不要试图在生成阶段解决所有问题,那是大厂研究团队才有精力做的优化方向。

2.4 实操环节的关键注意事项

数据准备阶段要特别注意标注一致性。同一个模型,不同的人写语言描述可能差异很大,有人写"带孔的板子",有人写"矩形底座上打一个通孔"。模型见过越多样的描述,泛化能力越强,但这也意味着你需要做一轮描述规范化,把常见CAD术语统一。我自己会在预处理时做一步术语替换,把"钻孔""打孔""开孔""通孔"统一成同一个token,这样模型学起来负担小很多。

训练阶段要控制特征序列长度。CAD模型的特征序列可以很长,尤其是有大量阵列和倒角操作的时候。序列太长会导致Transformer的注意力计算量飙升,推理速度大幅下降。实际工程里可以把模型截断处理,先保证前几个关键特征准确,后面的倒角圆角留到后处理阶段补。

推理阶段最关键的是采样策略。我用过greedy decoding和beam search,效果都不太理想,beam search容易生成重复特征。反而是用带温度和top-p采样的随机解码效果最好,多采样几次然后从中选一个几何合法的结果。这跟文本生成里的做法是反直觉的,因为CAD特征序列的"正确"标准是几何合法性,而不是概率最大。

3. 实操过程与核心环节实现

3.1 快速上手的工具链选型

如果你只是想先体验一下text-to-cad的能力,不需要自己训练模型,可以直接用现成的在线服务或开源推理接口。Text2CAD有公开的推理demo,输入一句描述就能看到生成的模型。想本地跑的试一下CAD-GPT、CAD-MLLM这些项目,它们在HuggingFace上都有权重和推理脚本。

如果是想认认真真接进自己的工作流,我建议从以下这套工具链起步:

  • 语言模型:先从开源的中小型模型开始,比如Llama-3-8B或者Qwen2.5-7B的指令微调版本,跑通流程之后再考虑换更大的模型。
  • CAD脚本引擎:OpenSCAD是首选,因为它语法简单、文本化程度高,非常适合作为LLM生成的目标语言。FreeCAD的Python API功能更全,但学习和调试成本更高。
  • 数据标注:用现成数据集(如Text2CAD数据集、DeepCAD数据集)做起步训练,不要自己造数据,成本极高。
  • 约束后处理:用Python的sympy库或者OpenCascade的约束求解模块做基础约束补全。

3.2 实操三步走:生成、解析、成模

整个流程可以拆成三个模块,我分别说一下每个模块里最容易出问题的地方。

第一步是生成阶段。以LLM生成OpenSCAD脚本为例,你给模型一个系统提示词,说明输出格式必须是一个完整的OpenSCAD文件,然后再给用户的需求描述。这里最关键的坑是模型经常"自作聪明"地添加解释性的文字,输出一些不在代码块里的内容。解决办法是在提示词里强制要求只输出代码,不要有任何解释,同时在解析阶段做代码块提取和语法校验。

第二步是解析阶段。拿到生成的OpenSCAD代码后,不能直接丢进渲染器,要先做语法检查。OpenSCAD提供了命令行接口,可以用openscad --check-parameters之类的选项做验证。我习惯的做法是在这一步同时跑一个体积包围盒检测——如果生成的模型体积为0或者最大尺寸超过设定阈值,直接判定为失败,重新采样。

第三步是成模阶段。把通过校验的OpenSCAD代码渲染成三维模型,导出为STL或STEP格式。如果要进SolidWorks、Fusion 360等主流CAD软件继续编辑,最好导出STEP格式,因为STL是离散网格,无法保留参数化特征。从OpenSCAD导出STEP需要用到FreeCAD的转换工具,流程上稍微绕一点,但效果是值得的。

3.3 一个实际案例的参数配置过程

我用一个实际需求来演示参数怎么配。需求描述是:"生成一个U型支架,底部有两个安装孔,侧壁各有一个腰型孔。"

这个需求里有一个值得注意的点:"腰型孔"在CAD里又叫长圆孔或跑马槽,它不是一个单一的拉伸特征,而是"两条平行线+两个半圆"的草图轮廓,或者用两个圆孔+中间矩形槽的组合来近似。模型能不能正确处理这种特征,很大程度上取决于训练数据里有没有类似样本。

如果走LLM+OpenSCAD路线,我预期模型生成的代码大致会长这样:

module u_bracket() { difference() { // 主体U型 union() { cube([100, 50, 5]); translate([0, 0, 5]) cube([5, 50, 40]); translate([95, 0, 5]) cube([5, 50, 40]); } // 底部安装孔 translate([25, 25, -1]) cylinder(h=7, d=6, $fn=24); translate([75, 25, -1]) cylinder(h=7, d=6, $fn=24); // 侧壁腰型孔 translate([2, 25, 25]) rotate([0, 90, 0]) linear_extrude(height=3) offset(r=3) square([20, 10], center=true); } }

这段代码的主体是合理了,但实际生成中模型容易在腰型孔这个位置出问题:要么忘了offset(圆角过渡),要么linear_extrude的拉伸方向不对,导致孔被拉穿到了错误的方向。我后来在后处理脚本里加了一个规则:凡是检测到"translate+rotate+linear_extrude"的组合,就会自动检查旋转轴和拉伸方向的一致性,不一致就打回重生成。

这个例子想说明的是,text-to-cad的实操不是一个"输入描述—直接出成品"的魔法管道,而是一个需要不断调参、加规则、做校验的迭代工程。模型负责解决"把语言变成代码"这步,但"代码是否正确、是否能加工"这类工程判断,还是需要人来兜底。

3.4 评估指标与效果验证

怎么判断一个text-to-cad系统好不好用?不能光看生成成功率,还要看生成质量、编辑性和下游可用性。我常用的几个指标:

几何有效性(Validity),指生成的模型在几何上自洽,不出现自相交面、退化边、零厚度薄壁等问题。底盘和孔洞相交是否正确、孔是否完全贯穿,都要靠这个指标把关。

工程可编辑性(Editability),指生成的模型进入CAD软件后,特征树是否干净、参数是否可改、约束是否完善。这个指标主观性强,但恰恰是实际使用中最重要的。生成一个没法改参数的模型,跟生成一张图片没本质区别。

生成速度(Latency),端到端模型通常几百毫秒出一版,LLM+脚本路线可能要5到20秒不等。速度取决于模型大小、硬件配置和采样次数。如果你的使用场景是交互式设计辅助,速度要求就很高;如果是离线批量生成,则可以容忍几十秒的延迟。

我在测试中还习惯加一个人工评估维度:让有5年以上经验的机械设计师给生成结果打分,主要看是否符合加工工艺常识。很多模型生成的模型在几何上没问题,但在工艺上很愚蠢——比如在需要避空的位置设计了实心凸台,或者孔的布置完全没法用标准钻头加工。这种"看起来对、实际上废"的问题,只有真正干过加工的人才能看出来。

4. 常见问题与排查技巧实录

4.1 生成结果位置偏移错乱

典型表现是零件主体正确,但孔位、倒角位置明显偏了,比如描述说的是"底部四个角各一个孔",生成结果却把孔打在侧壁或者悬空在零件外面。

这个问题的根源大概率在草图坐标的归一化处理上。我在开源代码里见过不少这样的案例:训练时采用了中心归一化(把坐标缩放到-1到1之间),但推理时忘记做反归一化,或者输入的单位和训练时的单位不一致,导致坐标缩放比例错误。

排查思路是先检查生成的特征序列里的坐标值范围,如果明显超出合理边界(比如零件尺寸是100,坐标却出现了500),基本就是归一化环节出了问题。再检查输入的尺寸描述是否被模型正确抽取——很多时候模型把"50mm"这个数字理解成了英寸或者其他单位,导致整体比例失调。

4.2 特征序列截断导致零件不完整

早期的Transformer模型有最大序列长度限制,一个复杂零件如果特征数量太多,生成到一半就被截断了,结果是零件缺了一半特征。

这个问题从工程角度有三个应对方式。第一个是分段生成:把复杂零件拆成多个子部件,分别生成再拼装,但这对装配约束提出了新要求。第二个是优先特征排序:在数据预处理时,按特征重要性重新排序,把主轮廓和主要结构特征放在最前面,把细节特征排在后面,这样即使被截断,主体结构也完整。第三个是配合CAD软件的宏录制功能做增量建模——模型先生成主体,然后再生成打孔、倒角等细节特征,以增量的方式加进去。

我最推荐的是第二种和第三种组合使用。优先特征排序能让模型在有限的序列长度内尽可能输出完整的零件结构,增量建模则能在主体生成成功的基础上逐步补全细节,两者的容错率都远高于"一口气生成整个零件"。

4.3 生成的圆角倒角过于密集

在实际测试中,模型特别喜欢生成圆角特征,因为训练数据里倒角很常见。但生成的圆角往往过度——每个边缘都倒了角,倒角半径还特别大,这在加工中是很大的忌讳。

这个问题本质上是模型的分布学习出了问题:模型学到了"多数零件有倒角"这个统计规律,但没有学会"倒角应该用在正确的边缘上"。我在后处理阶段加了两个规则:一是限制倒角特征的总数,超过设定阈值就把多余的倒角删掉;二是对倒角的半径做合理性检查——如果倒角半径跟相邻特征尺寸的比例超过1:10,就自动缩小或移除。

需要注意的是,这类规则在端到端模型里很难通过调参解决,它的本质是数据和模型的固有限制。要做长期优化,还是得回到训练数据配比上:增加无倒角或少倒角的负样本,让模型学会更克制的圆角使用习惯。

4.4 典型问题速查表

现象常见原因排查思路解决建议
生成零件整体比例失调单位混淆或坐标归一化处理错误检查坐标值范围与训练时尺度是否一致统一单位,推理前增加输入尺寸校验
孔位偏移悬空草图坐标失真或空间关系理解错误对比特征序列中坐标与语言描述的几何关系后处理增加坐标合法性校验,不合法则重新采样
零件缺少主体结构序列截断或注意力分散检查生成序列长度是否接近上限采用优先特征排序,主体特征前置
所有边缘都被倒角训练样本分布偏差统计生成结果中倒角特征占比后处理限制倒角数量,调整训练样本配比
语言描述越复杂生成越差槽位信息丢失逐项检查尺寸、特征、关系是否都被抽取用结构化提示词模板,降低描述复杂度

4.5 两个独家避坑心得

第一,别迷信"一个模型解决所有问题"。在text-to-cad这个方向上,通用模型和垂直模型的能力差距非常大。一个在通用数据集上训练的模型,可能连"带法兰的90度弯管"这种最基本的管道件都生成不好,因为管道件在数据集里占比太低。但如果你自己收集一批管道件数据做微调,哪怕是基座模型小一个数量级的模型,效果也远好于通用大模型。所以做实际项目时,先把你的业务场景梳理清楚,针对性地采集数据做微调,比换一个更大的模型更有效。

第二,人机协作的边界要划清楚。目前text-to-cad最适合的场景是"概念方案生成——设计师修改——再生成——再修改"的循环,而不是"一句话直接出成品"。我用下来最顺的节奏是:用AI生成3到5个粗略的方案变体,然后我在CAD里选一个最接近需求的,手动修细节,修不动的地方再回去改描述重新生成。这个协作模式比完全手画快,也比完全信任AI可靠。合作的前提是双方各让一步:AI负责发散和骨架,设计师负责收敛和细节。

5. 写在最后的实操建议

从最早的DeepCAD数据集到现在的Text2CAD、CAD-MLLM,text-to-cad技术迭代的速度比很多人想得要快。我今年年初测试时,模型连基本的法兰盘都经常生成失败,到了年中,已经能稳定生成带阵列、带镜像的中等复杂钣金件了。这个进步速度说明方向是对的,但也得清醒认识到,距离"人人会用自然语言做设计"还有不小的距离。

对于想在这个方向尝试的朋友,我的建议是不要一开始就想着训练自己的模型。先用现成的开源权重跑几条demo,感受一下生成质量和失败模式;然后买一个便宜的GPU实例,部署一个小的推理服务;最后再考虑数据微调。这个顺序能让你少走很多弯路,也能帮你更早判断这个技术到底适不适合自己的业务场景。

我还有一个经验是,实时上手比看论文有效得多。读十篇text-to-cad的论文,不如亲手生成十个零件,再用SolidWorks打开看看特征树到底长什么样。只有亲手改过AI生成的模型,你才知道约束有多重要、特征命名有多重要、草图是否完全定义有多重要。这些体会,坐在屏幕前面看论文是永远得不到的。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询