ARTICLE DETAIL

资讯详情

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

text-to-cad实战:从自然语言到三维模型的工程化落地

text-to-cad实战:从自然语言到三维模型的工程化落地 1. 从一段文字到三维模型text-to-cad 到底在解决什么问题第一次听到 text-to-cad 这个词我脑子里蹦出来的画面是对着电脑敲一句“给我画一个长宽高 100×60×40 毫米、四角带 M4 沉头孔的法兰底座”然后屏幕上直接出现一个可以旋转、可以导出、可以拿去加工的三维模型。这个画面放在五年前还属于科幻范畴但放到今天它已经是一条能跑通的工程链路了。text-to-cad 本质上是一套把自然语言描述转换成 CAD 几何模型的技术方案它的输入是一段人话输出通常是 STEP、GLB、STL 这类标准三维格式文件。为什么这件事值得单独拿出来聊因为传统 CAD 建模的门槛实在不低。你得先学会草图约束、拉伸切除、基准面选择、装配配合这一整套操作逻辑还得对尺寸链、公差、特征顺序有概念。一个简单的支架零件熟手可能十分钟搞定新手折腾两小时还在纠结草图为什么过约束。text-to-cad 想做的事情就是把这套“人脑翻译成几何”的过程交给程序让描述需求的人不必同时是建模高手。它适合谁我梳理下来大概三类人最用得上。第一类是产品经理、工业设计师这类“有想法但不一定精通建模软件”的角色他们需要快速把概念可视化拿去跟团队或客户对齐。第二类是工程师手头有大量重复性、参数化的零件需求比如各种规格的垫片、支架、外壳用文字批量生成比一个个手画快得多。第三类是做 AI 应用开发的程序员想把三维生成能力集成到自己的工具链里比如做一个面向创客的在线零件生成器。这里要先说清楚一个预期管理的问题。text-to-cad 目前的能力边界跟很多人想象中“随便说句话就出一个复杂装配体”还有距离。它擅长的是参数明确、结构规整、有常见几何特征的零件比如带孔板、阶梯轴、简单壳体、标准连接件。你让它生成一个完整的汽车变速箱那是不现实的。但如果你的需求是“一块 200×200×10 的板中心一个直径 50 的通孔四角各一个直径 8 的孔孔边距 15”这种描述它能处理得相当靠谱。理解这个边界后面的所有实操才有意义。2. 核心技术链路拆解一句话是怎么变成 STEP 文件的2.1 整体流程的四个阶段把 text-to-cad 拆开看不管具体用什么模型、什么框架底层链路基本都逃不出这四个阶段语义解析、参数抽取、几何构建、格式导出。这四个阶段环环相扣任何一个环节出问题最后出来的模型就是废的。语义解析阶段要做的是理解你到底在说什么。这里面的难点在于自然语言里充满了省略、指代和行业黑话。你说“打个孔”程序得知道是通孔还是盲孔你说“倒个角”它得判断是圆角还是直角边。这一步通常依赖大语言模型来做意图识别和实体抽取把一段自由文本拆解成结构化的指令序列。参数抽取阶段是把语义里的关键数值和约束关系拎出来。尺寸、位置、数量、角度、公差这些都得变成程序能读的变量。这里有个坑自然语言里的尺寸经常是相对的比如“孔比板边往里缩 10 毫米”程序得先知道板边在哪才能算出孔的绝对坐标。所以参数抽取往往不是一次性的而是跟几何构建交替进行。几何构建阶段是真正干活的环节。它拿到结构化参数后调用几何内核来生成实体。这里的选择很关键是用 OpenCASCADE 这种重型 B-rep 内核还是用类似 CadQuery、Build123d 这种基于代码的建模库直接决定了后续能生成什么级别的模型、导出什么格式。格式导出阶段相对简单但也不能马虎。STEP 适合工程交付和后续编辑GLB 适合网页预览和渲染STL 适合 3D 打印。不同格式对几何精度的要求不一样导出参数设错了模型要么文件巨大要么表面破破烂烂。2.2 为什么几何内核的选择是分水岭我踩过最大的一个坑就是早期图省事用网格类方案去生成模型。网格方案比如直接操作三角面片上手快生成速度也快但它有个致命问题没有精确的几何语义。你生成一个圆柱它本质上是一堆三角形拼出来的近似体直径 50 的孔实际量出来可能是 49.97 到 50.03 之间浮动。这种模型拿去 3D 打印凑合能用但你要拿去做工程分析、出工程图、做装配配合那就完全不够格了。所以真正要做 text-to-cad几何内核必须选 B-rep边界表示类的。OpenCASCADE 是目前开源方案里最成熟的选择它能精确表示平面、圆柱面、圆锥面、样条曲面支持布尔运算、倒角、抽壳这些工程特征。CadQuery 和 Build123d 都是基于 OpenCASCADE 封装的 Python 库用起来比直接调 OCCT 的 C 接口舒服太多。选 CadQuery 还是 Build123d我的经验是如果你追求稳定和生态成熟CadQuery 更稳妥文档全、社区大、踩坑有人问。如果你喜欢更 Pythonic 的写法、想要更灵活的上下文管理Build123d 值得一试它的 API 设计更现代写复杂模型时心智负担小一些。两者底层都是 OCCT导出 STEP 和 STL 的能力没有本质差别。2.3 大语言模型在链路里的角色定位很多人以为 text-to-cad 就是“大模型直接画图”这个理解偏差挺大。大语言模型在这个链路里扮演的是翻译官不是绘图员。它负责把你的自然语言翻译成结构化的建模指令或者代码真正画图的是几何内核。这个定位很重要因为它决定了你的系统架构。如果你让大模型直接输出几何数据那基本不可控精度和稳定性都没法保证。正确的做法是让大模型输出一段 CadQuery 或 Build123d 的 Python 代码或者输出一个结构化的 JSON 参数字典然后由确定性的几何构建程序去执行。这样即使大模型偶尔抽风你也能通过代码审查和参数校验把问题拦住。我实测下来让大模型直接生成 CadQuery 代码的效果比让它生成 JSON 再自己解析要好。原因是 CadQuery 的 API 本身就很接近自然语言的描述逻辑比如box(100, 60, 40)就是“长宽高 100、60、40 的盒子”hole(8)就是“打一个直径 8 的孔”。大模型在训练数据里见过大量类似代码生成起来准确率相当高。而 JSON 方案需要你自己定义一套参数 schema大模型经常在字段名和嵌套结构上出错反而增加了调试成本。3. 实操环境搭建与核心代码实现3.1 环境准备Python 生态是首选这套东西跑起来环境其实不复杂。我推荐用 Python 3.10 或 3.11太新的版本有时候 OCCT 的 wheel 包还没跟上太老的版本又缺一些类型提示特性。虚拟环境用 venv 或者 conda 都行我个人习惯 conda因为 OCCT 在某些平台上对系统库有依赖conda 的环境隔离更干净。核心依赖就三个cadquery、build123d可选二选一或都装、openai或你用的任何大模型 SDK。如果你要做 Web 预览再加一个trimesh用来处理 GLB 和 STL 的加载与转换。conda create -n text2cad python3.11 conda activate text2cad pip install cadquery build123d trimesh openai装完之后先跑一个最小验证确认 OCCT 内核能正常工作import cadquery as cq result cq.Workplane(XY).box(100, 60, 40).faces(Z).workplane().hole(20) cq.exporters.export(result, test.step) print(STEP 导出成功)如果这行代码能跑通并且生成了 test.step说明环境没问题。如果报错说找不到 OCCT 相关库大概率是 conda 环境里缺了occt或者vtk的依赖用 conda 再装一下conda install -c conda-forge occt vtk通常能解决。3.2 提示词工程怎么跟大模型描述你的零件这一步是整个链路里最需要经验的地方。同样一个零件描述方式不同大模型生成的代码质量天差地别。我总结了几条实用的提示词原则。第一尺寸必须带单位位置必须给参照。不要说“打一个孔”要说“在板中心打一个直径 20 毫米的通孔”。不要说“四角打孔”要说“在板的四个角距离每条边 15 毫米的位置各打一个直径 8 毫米的通孔”。大模型对模糊描述的容忍度比你想象的低它不会帮你“猜”合理值猜错了你还得回头改。第二特征顺序要符合加工逻辑。先做主体形状再做切除特征最后做倒角和圆角。如果你说“先倒角再打孔”大模型可能真的按这个顺序生成代码结果倒角把孔边也倒了出来的模型就不是你要的。我一般会在提示词里明确写“先创建主体然后打孔最后对边缘做 2 毫米圆角”。第三给一个完整的示例。这是最有效的一招。在系统提示词里放一个“输入描述 → 输出代码”的范例大模型会模仿这个范例的代码风格和结构。比如用户描述创建一个 80x80x5 的方形板中心有一个直径 30 的通孔四角有直径 6 的通孔孔边距 10。 CadQuery 代码 import cadquery as cq result ( cq.Workplane(XY) .box(80, 80, 5) .faces(Z) .workplane() .hole(30) .faces(Z) .workplane() .rect(60, 60, forConstructionTrue) .vertices() .hole(6) )有了这个范例大模型生成的代码结构会稳定很多你后续做参数校验和错误处理也容易得多。3.3 完整实现从文本到 STEP 的端到端脚本下面是我实际在用的一个最小可用版本。它接收一段自然语言描述调用大模型生成 CadQuery 代码执行代码生成模型最后导出 STEP 和 STL。import cadquery as cq from openai import OpenAI import re client OpenAI(api_key你的密钥) SYSTEM_PROMPT 你是一个 CAD 建模助手。用户会用自然语言描述一个零件你需要生成对应的 CadQuery Python 代码。 规则 1. 只输出代码不要输出任何解释文字。 2. 代码必须以 import cadquery as cq 开头。 3. 最终模型必须赋值给变量 result。 4. 所有尺寸单位默认为毫米。 5. 先创建主体形状再添加切除特征最后处理倒角和圆角。 6. 如果描述中有歧义选择最保守、最符合工程常识的解释。 示例 用户创建一个 100x50x10 的板中心有一个直径 20 的通孔。 代码 import cadquery as cq result cq.Workplane(XY).box(100, 50, 10).faces(Z).workplane().hole(20) def text_to_cad(description: str, output_name: str output): response client.chat.completions.create( modelgpt-4o, messages[ {role: system, content: SYSTEM_PROMPT}, {role: user, content: description} ], temperature0.1 ) code response.choices[0].message.content code re.sub(rpython|, , code).strip() local_vars {} exec(code, {cq: cq}, local_vars) result local_vars[result] cq.exporters.export(result, f{output_name}.step) cq.exporters.export(result, f{output_name}.stl) return result if __name__ __main__: desc 创建一个 120x80x8 的矩形板中心有一个直径 40 的通孔四角各有一个直径 8 的通孔孔边距 12 毫米所有边缘做 1 毫米圆角。 model text_to_cad(desc, flange_plate) print(模型生成完成)这段代码有几个关键点值得说。temperature0.1是为了让大模型的输出尽量稳定减少随机性。exec执行生成的代码时我把cq传进了全局命名空间这样生成的代码里import cadquery as cq即使被省略也能跑。实际生产环境里exec是有安全风险的你应该把生成的代码放到沙箱里执行或者至少做一轮静态检查禁止import os、open()这类危险操作。3.4 参数校验拦住大模型的“胡说八道”大模型生成的代码不是每次都靠谱。我遇到过它把孔打到板外面去、把尺寸单位搞成厘米、甚至生成一个负尺寸的盒子。所以参数校验层是必须的。我的做法是在执行代码之前先用正则把代码里的关键数值抽出来跟原始描述里的数值做比对。如果描述里说“直径 20 的孔”代码里出现了hole(200)那就直接拦截让大模型重新生成。另外生成模型之后可以检查模型的包围盒尺寸是否跟描述一致体积是否为正数面数是否在合理范围内。def validate_model(result, expected_dims): bb result.val().BoundingBox() actual (bb.xlen, bb.ylen, bb.zlen) for a, e in zip(actual, expected_dims): if abs(a - e) 0.5: raise ValueError(f尺寸偏差过大期望 {expected_dims}实际 {actual}) return True这个校验逻辑不复杂但能拦住大部分低级错误。我建议把常见零件的尺寸范围也做成配置比如“板类零件厚度不超过 50 毫米”超出范围就报警防止大模型生成一个 10 米厚的“板”。4. 格式导出与下游对接STEP、GLB、STL 怎么选4.1 三种格式的本质区别很多人对这三种格式的区别只有一个模糊印象我用人话解释一下。STEP是工程界的“通用语言”。它记录的是精确的几何定义一个圆柱面就是数学意义上的圆柱面不是三角形拼的。所以 STEP 文件可以导入到任何主流 CAD 软件里继续编辑尺寸精确适合做工程交付、CNC 加工、装配设计。缺点是文件结构复杂解析起来重网页预览不太方便。STL是 3D 打印的“事实标准”。它只记录三角面片没有面、边、特征这些概念。优点是简单、通用几乎所有切片软件都认。缺点是精度有限一个曲面要靠大量三角形去逼近文件可能很大而且没法反向编辑。你拿 STL 回 CAD 软件里只能当网格参考不能当实体操作。GLB是网页和实时渲染的“宠儿”。它基于 glTF 标准支持材质、颜色、动画文件紧凑浏览器原生支持好。适合做在线预览、AR 展示、产品配置器。但它同样不是精确几何不能用于工程分析。我的建议是一次生成三种都导。STEP 存档和工程用STL 给 3D 打印GLB 给网页预览。导出参数上STL 的线性偏差linear deflection设成 0.1 毫米左右比较均衡太小文件爆炸太大表面粗糙。GLB 导出时注意单位有些查看器默认按米处理你按毫米生成的模型导进去会小得看不见。4.2 导出参数的实际影响我做过一组对比测试同一个直径 50 毫米的圆柱用不同的 STL 导出参数结果差异很明显。线性偏差 (mm)角度偏差 (rad)文件大小表面质量适用场景0.50.5约 80 KB明显棱面快速预览0.10.3约 450 KB较平滑一般 3D 打印0.020.1约 3.2 MB非常平滑精细打印/展示0.0050.05约 18 MB几乎完美高精度需求实际用的时候0.1 毫米的线性偏差对大多数 FDM 打印已经足够了因为喷嘴直径通常就是 0.4 毫米模型再精细也印不出来。但如果你做的是光固化打印或者需要配合的零件那就得往 0.02 甚至更小走。4.3 跟下游工具的对接经验STEP 文件导入 SolidWorks、Fusion 360、中望 CAD 这些软件一般都没问题。但有个细节要注意CadQuery 导出的 STEP 默认是 AP214 协议有些老版本软件可能只认 AP203。如果你遇到导入失败可以在导出时指定协议cq.exporters.export(result, output.step, opt{write_pcurves: False})STL 导入切片软件Cura、PrusaSlicer、Bambu Studio基本是即插即用。但如果你生成的模型有薄壁或者细小特征切片前最好在软件里用“修复模型”功能跑一遍防止出现非流形边导致切片异常。GLB 在网页端用 three.js 或者 model-viewer 加载都很顺。我常用model-viewer这个 Web Component几行 HTML 就能嵌一个可旋转缩放的三维预览对做产品展示页特别友好。5. 常见问题与排查技巧实录5.1 模型生成失败或结果不对这是最高频的问题我整理了一个速查表。现象可能原因排查方法解决方式代码执行报错大模型生成了不存在的 API看报错行号对照 CadQuery 文档在提示词里加 API 白名单模型是空的布尔运算把实体减没了检查切除特征尺寸是否大于主体加参数校验切除尺寸不能超过主体孔的位置不对坐标系理解偏差打印模型包围盒和孔中心坐标提示词里明确坐标系原点位置尺寸差 10 倍单位混淆mm/cm/m检查代码里的数值提示词强制声明“所有尺寸单位为毫米”表面破面STL 导出精度太低用网格检查工具看非流形边提高导出精度或先做几何修复圆角失败圆角半径大于相邻边长度检查圆角半径和最小边长的关系减小圆角半径或调整特征顺序5.2 大模型“自作主张”加特征这个问题很隐蔽。你明明只说了一个方板加一个孔它给你加了个倒角或者把通孔做成了盲孔。原因是训练数据里类似的零件经常带这些特征它“学”会了。我的应对策略是在系统提示词里加一条硬规则“只实现用户明确描述的特征不要添加任何未提及的倒角、圆角、孔或切除。”这条规则加上之后自作主张的情况少了八成。剩下两成靠参数校验兜底生成后对比特征数量多了就重新生成。5.3 复杂模型的生成策略当零件特征超过五六个之后大模型一次性生成正确代码的概率会明显下降。我的做法是分步生成、逐步组装。先让大模型生成主体形状的代码确认无误后再让它在这个基础上添加特征。每一步都做校验错了只回退一步不用从头再来。另一种策略是参数化模板。对于经常重复的零件类型比如法兰、支架、外壳我预先写好参数化的 CadQuery 模板大模型只需要输出参数值不用生成完整代码。这样稳定性和速度都大幅提升。模板方案适合产品线固定的场景灵活性换稳定性很划算。5.4 性能与并发如果你要做批量生成比如一次生成 100 个不同规格的垫片串行跑会很慢。CadQuery 的几何构建是 CPU 密集型的可以用多进程并行。但要注意 OCCT 内核不是线程安全的多线程会出问题必须用多进程。from multiprocessing import Pool def generate_one(params): # 每个进程独立构建模型 ... with Pool(processes4) as pool: results pool.map(generate_one, param_list)实测下来4 核并行能把批量生成时间压到串行的三分之一左右。再往上加进程收益递减因为 OCCT 本身也有内存和锁的开销。6. 几个我踩过的坑和对应的解法第一个坑是中文描述里的数字格式。大模型有时候会把“直径 20”理解成“半径 20”出来的孔大一倍。后来我在提示词里明确写“直径用 d 表示半径用 r 表示未标明时默认是直径”这个问题就基本消失了。第二个坑是圆角顺序。如果你先打孔再对整个面做圆角孔边也会被圆角出来的模型跟预期不符。正确的顺序是先对主体边缘做圆角再打孔。这个逻辑我在提示词里写死了不让大模型自己决定。第三个坑是STEP 导出的颜色丢失。CadQuery 默认导出的 STEP 不带颜色信息如果你在网页预览里给模型上了色导出 STEP 后颜色就没了。解决办法是在导出前给实体赋颜色属性或者接受 STEP 不带颜色这个事实颜色信息单独用 GLB 承载。第四个坑是STL 的坐标系。3D 打印切片软件通常默认 Z 轴向上但 CadQuery 默认的“XY 平面”工作平面生成的模型Z 轴是厚度方向这跟打印方向是一致的。如果你生成的模型是竖着的导入切片软件后可能需要旋转。我一般会在导出前检查一下包围盒确保最薄的方向是 Z 轴。7. 这套方案还能往哪些方向延展text-to-cad 目前我跑通的链路是“文本 → 代码 → 模型 → 导出”但这条链路可以往两头延展。往上游走可以接语音输入。用 Whisper 这类语音转文字模型把口述的零件需求直接转成文本再走后面的流程。对于车间现场或者不方便打字的场景这个体验提升很明显。往下游走可以接自动出工程图。CadQuery 本身支持生成二维投影视图结合一些标注库可以自动生成带尺寸标注的工程图 PDF。虽然精度和规范性还达不到人工出图的水准但用于内部沟通和快速评审已经够用了。再往深走可以接参数优化。给定一个目标比如“重量最轻”或“应力最小”让程序自动调整尺寸参数生成多个方案调用仿真工具评估迭代出最优解。这就从 text-to-cad 进化到了 text-to-optimized-design是另一个量级的事情了。我个人在实际操作中的体会是text-to-cad 的价值不在于完全替代人工建模而在于把重复性、参数化的建模工作自动化让人把精力放在真正需要创造力和工程判断的地方。它现在的定位更像是一个“建模加速器”而不是“建模替代者”。把预期放对位置用起来会很顺手预期错了就会觉得它哪哪都不行。
返回列表