ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

text-to-cad:一句话生成可编辑CAD模型的原理与实践

text-to-cad:一句话生成可编辑CAD模型的原理与实践

text-to-cad 这个名字,很多人第一次看到会以为它又是文生图那套东西换了个马甲。但真正干过三维设计的人都清楚,一张好看的渲染图和一颗能加工、能装配、能改参数的实际零件之间,隔的可能是一整个白天。text-to-cad 要做的,就是让用户用一句自然语言,直接得到可编辑的 CAD 模型——不是像素,不是贴图,而是实实在在的实体特征。过去两年这个方向在工业软件圈和 AI 圈同时升温,学术论文、开源仓库、商业软件的实验性功能都开始出现。这篇内容我从技术路线、核心细节、复现流程和踩坑经验四个角度把它盘一遍,适合正在评估这个方向的建模工程师、产品经理,以及想自己动手实验的开发者。

1. 先分清 text-to-cad 和文生图,到底差在哪里

很多人第一次接触这台词,第一反应是“这不就是文字转3D吗,跟Midjourney一样”。真不是一回事。文生图输出的是像素矩阵,本质上是一堆颜色值的概率分布采样,它好看就够了,不需要符合物理规律,更不用考虑能不能被数控机床加工。text-to-cad 如果只生成一张“看起来像零件”的图片,那对工程师来说一点价值都没有。CAD 模型的核心不是外观,而是可编辑、可测量、可装配的参数化实体。

1.1 输出物的本质差异:像素 vs 实体几何

CAD 模型在计算机里的表达方式,和图像完全不同。图像是一个二维数组,每个元素是RGB值;而CAD模型最主流的表达是边界表示,也就是用面、边、顶点以及它们之间的拓扑关系来描述一个封闭实体。一个长方体不是“六个像素块”,而是六个平面、十二条边、八个顶点,还要带上每个面的法向、邻接关系,甚至草图上还留着尺寸约束和几何约束。

这就是为什么很多做图形学的人转到 CAD 方向会很不适应。在图形学里,两个三角形拼起来就是一个模型;在 CAD 里,两条边若没有正确的共线关系,后续的拉伸、倒角全部会崩。text-to-cad 真正要生成的,是这一整套带拓扑约束的几何结构,而不是一张深度图或一个网格文件。只要能明白这一层差异,后面所有技术选型都好理解了。

1.2 两大技术路线:直接生成几何 vs 生成建模命令

目前公开的 text-to-cad 工作,大致分成两派。

第一派是端到端生成几何体,模型直接输出体素、点云、三角网格或者神经隐式场,经过后处理变成可导入的模型文件。这条路速度快,几分钟内能出结果,用扩散模型或者自回归模型都能做。但问题也很致命:输出的大多是网格模型,没有参数化特征树,没有草图和约束历史,改一个孔直径等于把整个网格重新雕刻一遍。这在工程流程里基本不可接受。

第二派是生成建模命令序列,模型先输出一段结构化的指令流,比如“在XY平面画一个长120宽60的矩形,拉伸10毫米,在上表面打一个直径8的通孔”,然后由一个解释器把这些命令逐条喂给CAD内核,最终在软件里重建出完整的特征树。这样生成的模型完全可编辑,改尺寸就是改一个参数的事,和设计师手工建模的产物没有本质区别。

我个人的判断是,第二派才是真正意义上的 text-to-cad。生成网格那叫 text-to-mesh,工业软件不认。当然,第二派也有它的难处:命令空间巨大、顺序强依赖、一步错步步错,对模型的推理能力要求高得多。但这恰恰是这两年大语言模型兴起后最被看好的突破口——LLM 天然擅长生成有序列结构的文本,而CAD命令流本质上就是一种“带格式的程序语言”。

2. text-to-cad 的核心环节:一句话怎么变成一棵特征树

说清楚路线之后,得往深里拆一层:用户输入“一个带通孔的法兰盘,外径80,内径35,厚度12,周围六个对称分布的M6螺纹孔”,这句自然语言是怎么变成CAD软件里一棵可编辑的特征树的?

2.1 自然语言到结构化参数的桥梁

最笨的办法是写意图识别规则,比如正则匹配“直径”“厚度”“孔数”,然后填模板。这种方案在限定场景里能跑,但用户一旦换个说法就废了,比如“外径80”和“直径80的外圈”是同义表达,规则类方法根本覆盖不完。

大语言模型出现后,这个问题的解法变成:先把自然语言翻译成一份结构化的JSON schema,再把这份schema交给CAD命令解释器。比如:

{ "operations": [ {"type": "sketch", "plane": "XY", "profile": "circle", "params": {"diameter": 80}}, {"type": "extrude", "distance": 12, "boolean": "new"}, {"type": "hole", "position": "centered", "diameter": 35, "through": true}, {"type": "pattern", "type": "circular", "count": 6, "features": ["threaded_hole_M6"]} ] }

这里的关键不是“模型认不认得‘法兰盘’这个词”,而是模型能不能把“六个对称分布”这种模糊的空间描述,转换成circular pattern, count=6这种精确的参数指令。坐标怎么算、孔径多大、孔是通孔还是盲孔,全部要在这一步确定下来。传统NLP工具链做不到这种程度的转换,只有经过大量CAD数据训练的LLM能勉强胜任。

2.2 训练数据是最难绕开的壁垒

text-to-cad 最大的瓶颈,不在模型结构,而在数据。图像有 LAION,文本有 Common Crawl,但“自然语言描述 + CAD特征树”这种成对数据,互联网上几乎没有现成的。

我看到的公开方案大致有三类思路。

第一类是程序化合成。先定义一批参数化模板,比如“带法兰的轴套”“L型支架”“底板加筋板”,然后随机采样参数、随机组合特征操作,生成大量带设计树的模型;再用一个文本生成模型,为每个模型生成若干条自然语言描述。这类数据规模大、标签纯净,但缺点是模板覆盖度有限,模型很容易只学会“见过的形状”。

第二类是从已有的三维模型库反推。像 ABC Dataset、Fusion 360 Gallery 这类公开数据集,里面有几百万个B-rep模型,但很多只有最终几何,没有中间特征历史。想要拿到特征树,需要用逆建模算法反推,这是一件极其费力的事,而且反推结果经常和人工建模逻辑对不上。

第三类是半自动标注,让设计师在建模软件里录屏、记录操作日志,再把这些日志和语音/文字描述对齐。数据质量最高,但采集成本也最贵,目前只有少数商业团队能做。

所以如果你打算自己在这个方向做实验,别一上来就想搞大规模数据集。更现实的路径是:找一个小众行业场景,比如“非标自动化设备的底板设计”,手工整理两三百条样本,用LoRA微调一个开源模型,重点验证流程能跑通、效果够用,再逐步扩数据。

2.3 评估指标:为什么只看渲染图没用

text-to-cad 方向的论文多了以后,很多实验结果的“效果”根本没法比——因为用的评估口径完全不一样,有的贴渲染图,有的算点云距离,有的让设计师主观打分。

要做科学评估,业内现在逐渐形成了一套多维度指标组合:

  • 几何相似度:把生成模型和真值模型都采样成点云,算 Chamfer Distance 或 IoU。这个指标能衡量“整体像不像”,但测不出拓扑错误和孔位误差。
  • 命令序列一致性:比较生成命令和标准命令的编辑距离,或者按操作类型、参数值逐项对比。这个指标最接近“设计意图是否被还原”,但对齐命令时会遇到同一目标不同建模路径的问题。
  • 可编辑性检查:看生成模型的参数化特征树是否完整、能否直接修改某个尺寸后重新生成。这是工程实用性最硬的一条标准,也是很多纯生成模型过不去的坎。

我提醒一句:论文里光展示渲染图的,十有八九没做实体检查。真正靠谱的评估,至少要有实体公差分析和特征树可编辑性验证。如果你在选型或者读论文,看到一个方法在工业场景落地,先问一句“模型是网格还是B-rep”,再问一句“能不能改尺寸”,十个问题能筛掉八个。

3. 本地复现一个 text-to-cad 流程,关键步骤记录

技术原理说得再多,不如自己跑一遍。这个方向的开源仓库这两年逐渐变多,不同仓库细节差异很大,但整体流程基本是一套,我按最常见的主线梳理一遍,你可以拿这套思路去套具体仓库。我这里不绑定某个特定仓库的API,只把通用环节拆开讲。

3.1 环境准备与基座模型选择

硬件门槛是第一个现实问题。text-to-cad 的模型基本都是“LLM + 专用命令解码器”的结构,对显存比较敏感。我实测下来,7B级别的开源模型做推理,使用量化后大概需要12~16GB显存,也就是一张RTX 4080或3090能跑;如果要做LoRA微调,建议至少24GB显存起步,今天的主流消费级顶卡也能扛。

依赖方面,Python 3.10以上,PyTorch 2.x,再加上HuggingFace Transformers就能跑大部分流程:

pip install torch transformers datasets trimesh numpy

如果你会用CADQuery这个Python库来验证命令流,可以一并装上:

pip install cadquery

基座模型的选择我建议优先考虑代码能力强的模型,比如开源社区的 CodeLlama、DeepSeek-Coder 这类。CAD命令序列本质上是一种DSL,代码模型对这类结构化输出的把握能力,比通用对话模型强不少。当然,近半年很多新的通用模型在结构化输出上进步很大,你也可以直接用你熟悉的中文开源模型,关键看它对长指令的跟随能力。

3.2 文本到指令流的生成与校验

拿到自然语言描述后,第一步是用prompt模板把它格式化成模型输入。我用过的一套比较稳定的模板大概长这样:明确告知模型要输出JSON格式命令序列、所有参数必须是数字、禁止添加额外解释文字。然后配合采样参数控制输出稳定性。

from transformers import AutoModelForCausalLM, AutoTokenizer model_name = "your-base-model-path" tokenizer = AutoTokenizer.from_pretrained(model_name) model = AutoModelForCausalLM.from_pretrained( model_name, device_map="auto", torch_dtype="auto" ) user_input = "M8螺栓用的通孔垫片,外径16,内径8.4,厚度1.6" prompt = f"""已知CAD命令包括: - sketch_circle(plane, x, y, diameter) - extrude(distance, direction) - sketch_hole(x, y, diameter, depth) 根据用户需求,生成完整CAD命令序列,仅输出JSON格式命令序列,不要任何额外文字。 需求:{user_input} 命令序列:""" inputs = tokenizer(prompt, return_tensors="pt").to(model.device) gen = model.generate( **inputs, max_new_tokens=512, do_sample=True, temperature=0.2, top_p=0.9, ) commands = tokenizer.decode(gen[0][inputs.input_ids.shape[1]:], skip_special_tokens=True) print(commands)

温度参数这里值得展开说。我在试跑时一开始用temperature=0.8,输出经常出现花活——比例创意有余、精确不足,甚至生成了extrude(-1.6)这种反向拉伸。降到0.2之后,输出的命令序列明显更保守、更工程化,虽然少了些意外惊喜,但对CAD生成场景来说,稳定性比创造性值钱得多。如果你想让同一个模型出多方案对比,可以适当回调到0.4左右,但不要超过0.6,否则命令合法性会急剧下降。

3.3 从指令流到实体模型的构建与可视化

生成命令序列之后,需要用一个能执行命令的CAD内核把模型真正建出来。我在本地常用CADQuery来做这件事,因为它可以直接在Python里跑,又支持导出STEP格式。

比如说,模型输出了“画一个外径16的圆,拉伸1.6,再在中心打一个直径8.4的通孔”的命令,可以用类似下面的方式构建:

import cadquery as cq result = ( cq.Workplane("XY") .circle(16 / 2) .extrude(1.6) .faces(">Z") .hole(8.4) ) cq.exporters.export(result, "washer.step")

这一步看着简单,但它是整条链路里最容易暴露问题的地方。命令参数查不到面怎么办?倒角选择了不存在的边怎么办?布尔运算的体量太小导致精度报错?这些问题都只在“真正执行命令”时才会跳出来,所以命令校验环节一定不能省。

我的建议是在执行前先加一道静态检查:所有尺寸必须大于0、特征名称必须在已知列表里、拉伸方向必须是合法向量。哪怕只是这样一层简单的规则过滤,都能减少一半以上的运行时崩溃。

3.4 参数后处理:尺寸规整与约束修复

模型生成的数字有时候会很怪:用户要1.6毫米厚度,它输出1.599999994;要8.4直径,它输出8.400000572。这种误差在模型眼里“差不多”,但在CAD里会导致配合公差计算出问题。

所以我在流程里加了一个后处理步骤:按工程常识规整数字。小于1毫米的尺寸保留到小数点后三位,螺纹孔径对齐公制标准系列,圆整到0.05的倍数。纯几何生成模型不需要做这一步,因为它输出的是网格坐标;但 text-to-cad 的目标是进入工程链路,尺寸必须读起来像人写的参数,而不是模型采样出来的随机小数。

def normalize_dimension(value: float) -> float: value = round(value, 3) # 先统一到毫米级精度 if value < 1: return round(value, 3) if value < 100: return round(value, 1) return round(value)

这一步没什么技术含量,但在实际管线上能省下大量人工清理时间。另外,几何约束修复也在这里做:比如孔位坐标需要对齐到整数栅格、圆形阵列角度需要严格等分。很多时候模型生成的命令逻辑没错,就是参数不够“工程化”,后处理一加持,成品质量立刻上一个台阶。

4. 典型翻车现场与问题排查速查

复现流程容易,跑得稳不容易。以下这些坑我基本都踩过,有些是模型问题,有些是数据问题,还有些是工程管线问题。我把它们整理出来,你要是做这个方向,大概率能省下几周排查时间。

4.1 语义歧义:同一个尺寸被读出三个数字

用户描述“一个直径大约100的圆盘”,模型输出circle(d=99.99)、circle(d=100)、circle(d=100.02)三种结果,这算正常,但不稳定。真正的坑在于用户描述里的空间参照系:“在右边打孔”——“右边”是哪边?如果文本里没指定平面,模型会默认在XY平面,但用户心里想的是主视图的右侧。

我用的一个笨办法是在prompt里固定描述规范:凡是空间位置,必须先指定“在XY平面/在顶面/在侧面”,再写坐标或方位词。如果是自由输入文本,则让模型先在内部补全为完整空间描述,再转JSON命令。简单来说,就是给模型加一道“语义规范化”的中间层,不要让它直接跳转命令。

4.2 命令序列中途崩溃:非法操作与自相交

模型生成的命令序列经常会“逻辑正确但操作非法”:想在一个已经闭合的面上再画草图,或者倒角的半径大于边本身的长度。这类错误用CADQuery执行时直接抛异常,日志定位到具体命令还相对好办。

难的是自相交问题——命令全执行成功,但最终实体几何有裂缝或面片交叉,肉眼在渲染图里根本看不出来。我的排查方法是做实体检查:计算体积是否为负、检查面边界是否闭合、用布尔运算求一下自交。这步可以用trimesh库加载后检查:

import trimesh mesh = trimesh.load("washer.step") print(mesh.is_watertight) print(mesh.is_winding_consistent)

如果输出显示is_watertight=False,基本可以断定布尔运算出了问题。此时先检查草图平面是否选对,再检查拉伸方向是否有反向。这个排查顺序,我每次都是用草图平面优先定位,因为百分之七十的自相交都源自草图定位错误。

4.3 看着像,尺寸差一截:精度问题

还有一个很隐蔽的坑,来自字节级的精度损失。模型参数量化到4bit之后,输出的数字经常出现“差不多但就是不对”的情况。我之前遇到过一次,用户要外径80的圆盘,模型输出79.999991,被内核接受,但装配到配套轴套时干涉检查直接报警。这类问题不会被视觉检查发现,只能在导出前做尺寸规整。

所以我现在在管线里强制加一道关卡:所有最终尺寸必须落回标准工程精度——大尺寸保留一位小数,小尺寸保留三位小数,圆整规则按机械设计手册的公差表走。你宁可让模型结果“看起来不像AI生成的”,也要确保每个参数能进装配图。

4.4 只会生成见过的形状:数据分布陷阱

我最早跑实验的时候,觉得模型效果惊艳,垫片、法兰、支架样样能出。后来给它一个“非标焊接底座”的需求,输出直接崩了——命令序列合法,但几何形状完全没有工程合理性。原因很直白:训练数据里没见过这类特征组合。

这不是模型能力问题,是数据覆盖问题。解决思路有两条:要么扩数据集,让模板覆盖这个类型;要么缩场景,把模型限定在某个窄领域里。后者对实际工程团队其实更现实。你做一个“标准件选型工具”,就只让模型处理垫片、卡簧、轴承座这几类,训练数据容易整理,输出质量也可控。想把模型做成什么都懂的通用CAD助手,以目前公开数据和算力条件来看,还有很长的路。

症状可能原因排查建议
输出命令序列非法温度设置过高、prompt缺少格式约束降温度到0.2,强约束输出schema
几何自相交 / 裂缝草图平面选错、拉伸方向反向优先检查草图平面,再做水密性检查
尺寸与要求差一点量化精度损失、浮点采样误差加参数规整模块,按工程公差圆整
特征树缺失、不可编辑模型输出的是网格而非B-rep确认输出格式,走命令序列路线
特定类型形状崩坏训练数据覆盖不足限定应用场景或补充该类样本

最后分享一点实际经验

做这个方向最大的感触是:text-to-cad 当前最合适的定位不是取代建模师,而是当建模师的“第一稿生成器”。设计师花三秒说一句要求,它用三十秒出一个带特征树的基础模型,人再花三分钟精修细节,效率提升非常明显。我实际使用下来,最有价值的是它生成参数化特征树的思路对人有启发——同样一个零件,我习惯用拉伸加倒角,模型可能会用旋转体加阵列,有时候这种视角能帮设计师打开新的建模路径。如果你正在考虑给自己的团队引入类似能力,我的建议是别追求“通用”,先锁定一类你最常做的零件,把数据、后处理、校验这套闭环跑通,体验会完全不一样。

返回列表