ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

text-to-cad:自然语言生成CAD模型的技术路线与工程实践

text-to-cad:自然语言生成CAD模型的技术路线与工程实践 做设计的人应该都经历过这样的时刻脑子里已经构建出完整的零件造型参数、结构、装配关系清清楚楚但打开CAD软件对着屏幕却无从下手。要么是草图约束反复报错要么是圆角倒角顺序搞错模型怎么都生不出来。我最近几个月一直在死磕一个方向就是text-to-cad用自然语言直接生成CAD模型。简单说你输入一句“设计一个内径20毫米、外径35毫米、高度15毫米的法兰盘带六个均布安装孔”它就能直接输出一个可编辑的STEP文件。这套工作流对机械设计、3D打印爱好者、自动化设计工具开发者的价值非常大今天把我自己的完整实操经验和踩过的坑都整理出来。text-to-cad的核心逻辑不是让AI凭感觉生成一团面片而是把大语言模型当作一个会写参数化代码的绘图员用自然语言描述设计意图由模型生成脚本再在本地编译成真正的CAD模型。这个思路和我一开始想的完全不同我最初以为会是某种端到端神经网络直接输出网格但深入了解之后发现沿着代码生成这条路走才能保证精度、可编辑性和可制造性。1. 为什么text-to-cad可行一句话说清技术逻辑很多人在第一次接触text-to-cad时会问这不就是把用户输入丢给大模型让它随便画吗其实完全不是。要理解这个方向为什么成立关键要明白CAD模型在计算机内部到底是怎么表达的。1.1 从“描述到模型”的本质是把设计意图翻译成参数化代码机械设计里的零件从来不是一堆无序三角面片堆出来的。一个真正的CAD模型内部存储的是特征树和参数约束拉伸、旋转、打孔、倒角、阵列每一步都有明确的几何参数。比如一个法兰盘在CAD软件里可能是“先在XY平面画外圆再画内圆草图拉伸15毫米再在圆周上阵列六个孔”。这种表达方式天然结构化每一步都是可参数化的操作。大语言模型最擅长的恰恰就是这种“结构化生成”。它不直接生成几何体而是生成一段描述这些操作的代码。目前主流的两条路线一是生成CadQuery的Python脚本二是生成OpenSCAD脚本。CadQuery更接近工业CAD的特征建模思路OpenSCAD更接近程序员做3D打印的CSG布尔建模。本质上都一样模型输出的是“怎么做”的逻辑而不是“长什么样”的像素。这个转变带来一个非常重要的优势模型不需要自己推理空间几何形状只需要把问题拆解成一系列可以执行的操作序列。空间计算交给几何内核来完成比如CadQuery下面跑的是OCCT内核和FreeCAD、Salome的几何内核同源精度和稳定性有保障。1.2 为什么是代码生成而不是直接生成网格我见过不少人尝试用AI直接生成STL网格效果都不理想。原因很直观大语言模型天生是文本模型你让它输出一个包含几万到几十万个三角形顶点坐标的二进制文件本质上是在要求它背诵一串它根本理解不了的长随机数序列。这个方向在数学上就不可能稳定。更致命的是网格文件的工程价值很低。STL只有表面三角形信息没有特征树、没有参数约束、没有设计历史。你拿回来一个STL改不了尺寸删不掉一个孔只能当成一块“石头”去加工。这对工业设计场景基本没有用。代码生成路线解决的正是这个问题。设计意图被固化为Python脚本脚本里每一行都有明确的工程语义。想改壁厚改一个数字就行。想增加阵列数量改一个参数就行。脚本本身还携带了注释和命名可以作为团队的知识资产沉淀下来。这也是为什么我在很多技术讨论里反复强调text-to-cad的正确落地路子是“LLM 参数化脚本 几何内核”而不是“LLM 三维网格”。2. 技术路线与工具选型两条主线如何选既然核心是代码生成接下来的问题就是选哪条技术路线来生成代码。我实际试过CadQuery、OpenSCAD和SolidPython三条路线各有优劣结合自己的使用场景来选别盲目跟风。2.1 基于OpenSCAD的路线语法简单、上手快、打印友好OpenSCAD是目前对LLM最友好的CAD脚本语言之一。它的语法极其简洁没有复杂的类继承和对象模型核心就是矩形、圆形、圆柱、立方体然后做差集、并集、交集。这种函数式的CSG建模方式和编程语言初学者写代码差不多LLM很难“写错”因为它需要的抽象层次很低。OpenSCAD生成的模型非常适合3D打印。我测试过很多次只要布尔运算逻辑没毛病输出的STL都非常干净水密性容易保证切片的成功率很高。但它的缺点同样明显生成的模型是纯多面体没有特征历史也没有B-rep边界表示的精确曲面信息。遇到需要圆弧精度极高的配合面时OpenSCAD的网格近似可能不满足要求。还有一个实际坑OpenSCAD对圆角的处理比较弱大量使用offset或minkowski会让模型生成速度急剧下降复杂模型动辄要算几十秒甚至几分钟。LLM如果被要求做很多圆角生成的代码性能会非常差。2.2 基于CadQuery的路线贴近工程制造、精确建模的关键CadQuery是我在工业级应用中的首选。它构建在OCCT几何内核之上支持精确的B-rep建模导出的STEP格式可以直接进入主流CAM软件做数控编程甚至可以进有限元分析的流程。这意味着真实制造业的精度需求是被完全满足的。CadQuery的API设计走的是“自顶向下”的特征建模思路创建二维草图、拉伸、开孔、布尔运算、倒角、阵列。这个思路和SolidWorks、Fusion 360里的特征树是同一个抽象层级的LLM生成的代码只要逻辑清晰几乎不会出现非流形实体或者拓扑错误。当然CadQuery的语法比OpenSCAD复杂得多。它的API有很多细节比如Workplane的坐标系变换、.faces(Z)的选取方式、cutBlind和throughAll的区别这些细节对LLM来说都是易错点。但好消息是只要提示词写得好多轮迭代几次模型能自我修正大部分问题。2.3 两条路线对比与选择建议对比维度OpenSCADCadQuery我的选择建议语法复杂度极低接近伪代码中等类似Python面向对象LLM生成的OpenSCAD更稳定几何精度网格近似有误差精确B-rep边界表示制造业必须用CadQuery输出格式STL/3MF/AMFSTEP/STL/SVG/DXF需要STEP选CadQuery可制造性适合3D打印适合CNC/打印/注塑按工艺选生成性能复杂圆角极慢中等依赖特征数量性能敏感选CadQuery文件大小网格大参数化脚本极小长期维护选CadQuery我现在的固定搭配是快速打样、验证想法时用OpenSCAD真正要做零件、出加工文件或者进装配体时用CadQuery。两者都需要和后端构建一套自动化的编译验证链路这一点没有区别。2.4 LLM模型怎么选开源还是闭源通用还是专用模型选择上不需要过度纠结通用大模型其实已经够用了。我实测过GPT-4o系列、Claude的Opus系列以及几款国内开源模型如DeepSeek-V3和Qwen系列它们在CadQuery和OpenSCAD两种语言的代码生成上都有不错的表现。关键差异在于代码推理能力而不在于参数规模。一个能稳定处理“先拉伸再打孔再阵列”这种多步推理链的模型比单纯参数大的模型要实用得多。多模态能力是加分项但非必需。如果输入的是手绘草图或者参考图那么多模态模型能把视觉信息转化为设计参数如果输入纯粹是文字描述文本模型足够。我在本地部署场景一般选Qwen系列的代码专用版本响应速度和离线能力更均衡。在线场景用闭源模型真要长上下文反复迭代时闭源模型的窗口管理更省心。3. 从零搭建text-to-cad工作流一套可以复用的工程实践讲完了选型逻辑下面是整个项目里价值密度最高的部分一套可复用的text-to-cad工程化工作流。这套流程我踩了很多坑才稳定下来现在拆开来讲可以直接照着搭。3.1 环境准备只装必要的东西别铺张工作流的核心依赖只有三项Python环境、CadQuery库可选、OpenSCAD命令行工具。CadQuery的安装要注意版本匹配我遇到过Python 3.12下旧版CadQuery装不上依赖的情况建议直接用官方推荐的Python 3.10或3.11然后执行pip install cadquery这个命令会连带装好OCCT内核绑定。安装完验证一下python -c import cadquery as cq; print(cq.__version__)能输出版本号就说明内核通了。OpenSCAD从官网下载安装包后需要把可执行文件加入系统PATH因为我们要在Python里调用它的命令行接口做编译。这一步很多人会忽略后面自动化脚本里调用openscad命令报错的时候才意识到。3.2 提示词模板设计把约束全部写进上下文我强烈建议不要直接甩一句“帮我画一个法兰盘”给模型那样生成的代码大概率不合意。正确做法是把设计约束、单位、输出格式、禁止事项全部写进提示词。我目前的提示词模板大致长这样你是一名资深机械设计工程师。请根据以下需求生成CadQuery Python脚本 - 单位毫米mm。 - 模型必须位于原点附近底面保持在Z0平面。 - 主要几何尺寸内径20外径45厚度8。 - 六角凸台六角外接圆半径18高度6位于顶面中心。 - 中心通孔直径8。 - 六个安装孔直径4.5均布在半径28的圆上。 - 代码必须使用cadquery库最终通过cq.exporters.export(result, output.step)导出STEP。 - 不要使用未定义的变量不要写多余的调试输出不要使用不存在的CadQuery API。关键点是把尺寸作为显式数字写清楚而不是让模型自己决定明确指定基准面和Z0底面给出导出语句禁止模型发挥不存在的API。这套约束下来代码的可用率能提高一大截。我在一次测试中带约束的提示词生成代码一次通过编译的概率接近七成而裸提示词只有两成左右。3.3 自动化验证闭环生成、编译、渲染、审查一条龙代码生成了不是终点必须建立一个自动化的验证闭环。我的流程分为四步模型生成代码后保存为model.py。Python编译检查python -c import ast; ast.parse(open(model.py).read())这一步做基础语法验证。执行脚本导出STEP和STL文件。如果执行过程抛出CadQuery异常把异常信息反馈给模型让它自己修复。用OpenSCAD命令行导出PNG预览图或者直接用CadQuery的exporters把模型转成SVG视图人工快速判断形状是否合理。自动化闭环的实质是把“编译、执行、反馈”做成一个循环。我写过一个简单的执行脚本import subprocess import sys import json def run_pipeline(code: str, output_prefix: str): with open(generated_model.py, w, encodingutf-8) as f: f.write(code) try: result subprocess.run( [sys.executable, generated_model.py], capture_outputTrue, textTrue, timeout30 ) if result.returncode ! 0: return {success: False, error: result.stderr[-2000:]} return {success: True, info: result.stdout[-1000:]} except subprocess.TimeoutExpired: return {success: False, error: timeout}推荐把整个流程封装成函数这样后面接入LLM的多轮迭代循环会非常方便。每轮模型生成代码脚本执行把错误信息回传模型修改再执行形成一个稳定的反馈回路。3.4 多轮迭代策略别一次求完美让模型自己改错text-to-cad和纯文本生成最大的区别在于代码是可以反复执行的。这意味着你完全可以采用“先出草图再迭代优化”的策略。我的迭代习惯是第一轮只求结构骨架对尺寸不准没关系。第二轮根据预览图修正尺寸和比例。第三轮做细节收尾倒角、圆角、螺纹孔、阵列。每轮都把上一轮的报错信息和渲染图传给模型模型自己会修正。这里有一个非常重要的经验不要把错误信息一股脑全塞给模型。CadQuery的报错信息有时非常长包含大量堆栈追踪信息占满上下文窗口反而会干扰模型判断。我通常只截取最后500到1000个字符的错误摘要回传同时附上一句指令“根据错误信息修复代码确保能一次通过编译”。效果比用完整报错提升明显。4. 常见问题与排查技巧实录坐标、单位、布尔运算的四个坑实操跑题多了发现text-to-cad看起来门槛不高但真正稳定输出能用的模型要翻过不少暗坑。我把最常见的几类问题整理出来按频率排序每条都附上排查思路。4.1 单位与尺寸不匹配毫米被当成英寸大模型的训练数据里英制单位出现的频率非常高。我一开始跑一个300毫米的长条零件模型生成出来只有7.62毫米。一看代码模型把输入的“300 mm”理解成了英寸内部转换了25.4倍。这个错误非常隐蔽因为编译不会报错模型也能正常生成但尺寸就是不对。排查办法是强制在提示词里声明“所有数值均为毫米不要转换单位”同时在自动验证脚本里加一个体积或体积包围盒检查如果生成的模型体积和预期差两个数量级以上直接判定尺寸异常让模型重生成。这个检查我用过很多次能拦住一大半离谱结果。4.2 坐标基准错误零件飞到空中或插进地面还有一次我要求模型“圆柱体站立在Z0平面上”它生成的圆柱中心在原点一半位于Z轴负方向。原因是CadQuery默认的圆柱构造方式是两端拉伸如果不指定起始平面模型就会跨越原点对称分布。输出STEP后导入其他CAD软件一看零件整体悬空。这类问题的根源在于CAD坐标系的“基准面”和“拉伸方向”概念LLM有时候会搞混。解决办法是在提示词里明确写一句“确保模型最低点位于Z0平面”然后生成后用形状包围盒检查shape result.val() bb shape.BoundingBox() print(zmin:, bb.zmin, zmax:, bb.zmax)如果zmin偏离0超过1毫米就反馈给模型“模型最低点不是Z0调整坐标使底面落回Z0平面”。4.3 布尔运算失败导致非流形实体布尔运算是CAD建模里最危险的操作也是最让LLM头疼的。当两个特征恰好在某个点上相切或者完全共面时OCCT内核会报“non-manifold”错误整个脚本直接崩溃。我遇到过一个非常经典的案例要求法兰盘的圆柱体和底座完全对齐两个面完全重合布尔求交时直接报错。工程实践上的解法有两个。第一个是避免精确共面把圆柱体底座稍微高出0.01毫米然后用“切掉多余部分”的方式修正。第二个是引导模型使用“从底面向上拉伸”的操作模式减少隐式布尔。CadQuery的Workplane操作之间本身有的就是链式特征累加有的则是布尔差集提示词里明确告诉模型“优先使用工作平面上的草图拉伸少用对象之间的并集布尔”代码稳定性会有质的提升。4.4 特征嵌套太深导致性能爆炸有一次我让模型生成一个布满散热鳍片的外壳它直接用for循环生成了一百多个重复特征。编译没有报错但导出STEP花了十几分钟文件大小超过200兆直接把内存吃满。这不是逻辑错误而是算法复杂度失控。排查方法在验证脚本里对导出的STEP文件大小做限制超过50MB直接判定失败同时检查生成的代码里是否有可疑的for循环嵌套。更优的解法是提示词里对这类情况做约束“阵列和重复特征请使用CadQuery的Array操作或者polar系列方法不要使用Python的for循环逐个建模”。这条约束能几倍地缩短生成时间也让模型更符合CAD软件的建模习惯。5. 质量评估怎么知道模型“造得好不好”很多人做text-to-cad只关注到“代码能不能跑通”就结束了但一个真正有价值的环节是质量评估。能不能筛选出高质量生成结果决定了这套工作流能否在日常设计中真正顶用。5.1 客观尺寸指标与参数检查最直接的评估手段是让生成模型和预期设计参数做对比。以法兰盘为例预期是外径60、内径20、高度15生成模型可以直接读取几何数据来检验import cadquery as cq result cq.importers.importStep(output.step) bb result.val().BoundingBox() outer_cyl result.faces(Z).val().Area()更合理的做法是检查模型的包围盒尺寸和关键特征的数量。比如安装孔的数量可以用面数统计来核对。这类指标可以自动化执行适合批量筛选模型。我给工作流加了一个简单规则尺寸误差超过5%直接判定失败不进入人工审核环节。5.2 可制造性与建模规范性检查生成模型是否“能造出来”比是否好看重要得多。3D打印场景要检查最小壁厚、悬垂角度CNC加工场景要检查最小圆角半径注塑场景要检查拔模斜度。这些检查在CadQuery里都能通过分析面的曲率和法线方向来做但工程上更省事的方法是直接导入切片软件或CAM软件里做一次仿真。还有一个规范性检查值得做确认模型是否全部是闭合实体没有自由边、没有薄壳结构。用shape.isValid()和shape.isWatertight()做布尔判断非常方便。我在实际项目里遇到过模型从表面看挺像样但其实是几个分离的薄壳拼在一起的情况这种模型到了切片阶段就废了。提前用自动检查拦住是这套流程最有价值的收益。5.3 典型质量评估表格检查项检查方法合格标准我的执行建议编译通过执行Python脚本返回码为0每次生成后必查几何有效Shape.isValid()返回True在导出STEP前检查水密实体Shape.isWatertight()返回True3D打印前必查尺寸正确对比包围盒与预期误差5%自动化对比特征完整统计孔数、阵列数量与预期一致人工抽检或写断言STEP可读性换软件导入验证无报错无破面至少选一款专业CAD验证这套表我直接固化在自动验证脚本里每次跑完自动打分。评分太低的自动触发重新生成评分中等的人工决定是否保留。这个评估意识会让text-to-cad真正变成可信赖的设计工具而不只是一个玩具级Demo。6. 我在实际项目里的一段完整样例前面讲了很多方法论可能有点抽象。这里给大家展示一个完整的典型样例用自然语言生成一个带凸台的电机安装座。从输入到最终STEP我把整个流转过程拆开来看。我给的描述是一个正方形底座边长100毫米高10毫米四个角各有直径8毫米的安装通孔中心有一个直径30毫米高20毫米的圆柱凸台凸台中心有一个直径12毫米贯穿的通孔。首轮生成的CadQuery代码大致长这样import cadquery as cq base ( cq.Workplane(XY) .rect(100, 100) .extrude(10) ) mounting_holes ( base.faces(Z).workplane() .rect(80, 80) .vertices() .hole(8) ) boss ( mounting_holes.faces(Z).workplane() .circle(15) .extrude(20) ) center_hole ( boss.faces(Z).workplane() .circle(6) .cutBlind(-20) ) cq.exporters.export(center_hole, motor_mount.step)这一版第一次跑就编译通过了但做包围盒检查时发现zmin是0而zmax是30底座10毫米加上凸台20毫米C是30这是符合预期的。不过盲检发现中心孔没有贯穿到底座只切了凸台的20毫米底座的10毫米还是实心。反馈给模型“中心通孔需要贯穿整个模型从凸台顶面一直穿出底座底面”模型很快修正为cutBlind(-30)或在底面上单独开孔。整个过程耗时不到两分钟其中大头是模型生成时间本地编译和检查基本秒级完成。这个效率对比传统手工建模优势非常明显尤其是在出方案初期“要快速确认这零件长什么样、能不能装”的场合价值极高。7. 最后再分享一个小经验text-to-cad这个方向我玩到现在最大的体会是别把它当成“AI自动画图”一定要把它当成“AI辅助下的参数化建模流程”。它不是为了替代设计师而是替代那些重复的、机械的、描述成本高于建模成本的操作——标准件建模、相似零件变体、对外协方案的快速验证。你描述得越清晰它输出得越准确。如果要做整套流程的产品化部署我建议优先把“提示词模板库”做起来。每次生成完一个成功的模型就把对应的描述和代码沉淀下来作为后续任务的标准用例。这套模板库积累得越多模型在特定领域里的表现就越稳定最终会形成你个人或团队专属的text-to-cad知识资产。这和当年大家对“提示词工程”的热情是一样的只是这里的回报更加可量化——直接体现在从需求到STEP文件的转化率上。
返回列表