ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

text-to-cad 实战:从自然语言到三维 CAD 模型的完整链路

text-to-cad 实战:从自然语言到三维 CAD 模型的完整链路 1. 从一句话到三维实体text-to-cad 到底在解决什么问题第一次听到 text-to-cad 这个词很多做机械设计或者工业软件的朋友第一反应是又是个蹭大模型热度的概念。但如果你真的在产线上待过或者帮客户做过非标自动化项目就会明白这个方向背后压着多大的痛点。传统 CAD 建模的流程是需求方给一段文字描述或者一张草图工程师打开 SolidWorks、UG、中望CAD 这类工具从草图约束开始一笔一笔画拉伸、旋转、倒角、打孔最后导出 STEP 或者 STL 交给下游。这个过程里最耗时的往往不是建模本身而是理解需求—确认尺寸—反复修改的循环。一个简单的法兰盘从沟通到出图可能要半天一个带装配关系的支架来回改三五版是常态。text-to-cad 想做的事情就是把这套流程的前半段自动化你输入一段自然语言比如一个外径 80mm、内径 40mm、厚度 10mm 的法兰均布 6 个直径 8mm 的螺栓孔孔心圆直径 60mm系统直接输出可用的三维模型文件格式可以是 STEP、STL甚至是带运动学定义的 URDF。这不是要取代工程师而是把工程师从重复性的参数化建模里解放出来让他们把精力放在真正需要判断力的地方——结构强度、装配干涉、工艺可行性。这个方向之所以现在能落地靠的是三件事凑齐了一是大语言模型对自然语言的理解能力足够强能把模糊描述拆解成结构化的几何参数二是参数化建模的内核比如 OpenCASCADE、CadQuery 这类库已经足够成熟可以通过代码精确控制几何体三是 STEP、URDF、G-code 这些中间格式的生态完善生成的模型能直接对接下游的仿真、3D 打印或者数控加工。关键词里出现的 STEP、URDF、G-code其实正好对应了 text-to-cad 的三条主要出口STEP 给通用 CAD 交换和加工URDF 给机器人仿真G-code 给增材制造和减材制造。这篇文章适合谁看如果你是想了解这个方向的技术选型的产品经理或者是想自己动手搭一套原型的开发者又或者是被重复建模折磨够了的机械工程师都能从下面这些内容里找到能直接用的东西。我会把整个链路拆开讲从文本怎么变成参数参数怎么变成几何几何怎么导出成各种格式以及我在实际搭这套东西时踩过的坑。不堆概念只讲能跑起来的逻辑。2. 文本解析层把人话翻译成机器能懂的几何参数2.1 为什么不能直接让大模型输出 CAD 代码很多人第一反应是既然大模型能写 Python那我直接让它生成 CadQuery 或者 OpenSCAD 的代码不就行了我一开始也是这么想的实测下来问题很大。大模型生成的建模代码语法上可能没问题但几何上经常是错的。比如它会把均布 6 个孔理解成在一条直线上排 6 个孔或者把孔心圆直径 60mm和外径 80mm搞混导致孔打到实体外面去。更麻烦的是它生成的代码往往没有参数化尺寸是硬编码的你改一个数就得重新生成整段代码失去了参数化建模的意义。正确的做法是把任务拆成两步第一步让大模型做它擅长的事——从自然语言里抽取结构化的参数输出一个 JSON 或者类似的中间表示第二步用确定性的代码模板把这些参数填进预定义好的几何构造流程里。这样几何的正确性由模板保证大模型只负责理解语义。这个思路在业界叫LLM as a parser而不是LLM as a coder。2.2 参数抽取的 schema 设计中间表示的 schema 设计是整个链路的地基。设计得好后面几何生成就顺设计得烂后面全是补丁。我建议按特征树的思路来组织而不是平铺一堆尺寸。一个法兰的 schema 大概长这样{ part_type: flange, base_geometry: { type: cylinder, outer_diameter: 80.0, thickness: 10.0 }, features: [ { type: through_hole, diameter: 40.0, position: center }, { type: hole_pattern, hole_diameter: 8.0, count: 6, pattern: circular, pitch_circle_diameter: 60.0 } ], units: mm }这个 schema 的关键在于每个特征都是独立的、可组合的而且带了类型信息。大模型只需要把均布 6 个直径 8mm 的螺栓孔孔心圆直径 60mm映射成hole_pattern这个特征剩下的计算——每个孔的具体坐标——由几何引擎去算。这样即使大模型对空间关系的理解有偏差只要它识别对了特征类型和关键尺寸最终结果就是对的。单位是个容易被忽略的点。我见过太多因为单位搞错导致模型放大 25.4 倍的案例。schema 里必须显式带units字段而且在 prompt 里要明确要求大模型输出单位。如果用户没说默认用毫米但要在返回结果里标注假设单位为毫米让用户有机会纠正。2.3 处理模糊描述和缺省值真实场景里用户很少会把所有尺寸说全。做个支架这种描述大模型再强也变不出具体尺寸。这时候有两个策略一是追问二是用合理的默认值填充并标注。追问适合交互式场景但如果是批量处理或者 API 调用追问就不现实了。我的做法是维护一套缺省值规则比如板类零件的默认厚度 5mm默认倒角 1mm默认材料是铝合金。这些默认值不是拍脑袋定的而是从历史项目里统计出来的常见值。还有一个坑是相对描述。孔比外径小 20mm这种需要大模型做一次算术。实测下来让大模型直接算数出错率不低尤其是数字大的时候。更稳的做法是让大模型输出表达式比如outer_diameter - 20然后在几何生成阶段用代码去求值。这样算术的准确性由代码保证大模型只负责建立关系。2.4 用 few-shot 示例稳住输出格式大模型输出 JSON 的时候偶尔会加一些解释性文字或者把 JSON 包在 markdown 代码块里导致解析失败。解决办法是在 prompt 里给两三个 few-shot 示例明确展示输入文本—输出 JSON的对应关系并且在系统提示里强调只输出 JSON不要任何其他文字。如果用的是支持 JSON mode 的 API直接开启能省掉很多后处理。即便如此解析层还是要加一层容错先尝试直接解析失败就提取第一个{到最后一个}之间的内容再解析再失败就返回错误让用户重试。3. 几何生成层参数怎么变成真正的三维实体3.1 几何内核选型OpenCASCADE 还是别的参数变成几何靠的是几何内核。目前开源方案里OpenCASCADE简称 OCCT是绕不开的选择它支持 B-rep 表示能精确表达圆柱、圆锥、倒角这些工程上常用的几何导出的 STEP 文件也是标准的 B-rep 格式能被主流 CAD 软件正确读取。CadQuery 就是基于 OCCT 的 Python 封装用起来比较顺手。另一个选择是 OpenSCAD它用的是 CSG构造实体几何的思路代码简洁但导出的模型是网格化的精度受限于细分程度而且不支持真正的倒角和圆角做出来的东西偏概念模型不太适合直接加工。如果你要做的是机械零件我强烈建议走 OCCT/CadQuery 这条路。虽然学习曲线陡一点但几何质量是网格方案比不了的。举个具体的例子用 OpenSCAD 做一个带倒角的法兰倒角实际上是很多小平面拼出来的近似而 CadQuery 做出来的倒角是真正的曲面导出的 STEP 在 CAM 软件里能直接生成正确的刀路。3.2 从 schema 到 CadQuery 代码的映射有了 schema生成几何就是写一个解释器把每个特征翻译成 CadQuery 的操作。核心逻辑是一个特征一个特征地做布尔运算。以法兰为例流程是先做一个外径 80、厚 10 的圆柱作为基体然后挖掉中心直径 40 的通孔最后在孔心圆上均布 6 个直径 8 的孔。CadQuery 的代码大概是这样import cadquery as cq import math # 基体 result cq.Workplane(XY).circle(80/2).extrude(10) # 中心通孔 result result.faces(Z).workplane().hole(40) # 均布孔 pcd 60 hole_d 8 count 6 points [ (pcd/2 * math.cos(2*math.pi*i/count), pcd/2 * math.sin(2*math.pi*i/count)) for i in range(count) ] result result.faces(Z).workplane().pushPoints(points).hole(hole_d) # 导出 cq.exporters.export(result, flange.step)这段代码里pushPoints接收的就是几何引擎算出来的孔位坐标大模型不需要参与。这就是前面说的确定性模板的价值——只要 schema 对几何一定对。3.3 特征顺序和布尔运算的坑特征的应用顺序会影响最终结果尤其是涉及布尔运算的时候。比如你先打孔再倒角和先倒角再打孔结果可能不一样。一般来说应该按照先加后减的原则先做所有的材料添加拉伸、旋转、扫掠再做材料去除打孔、挖槽最后做修饰性特征倒角、圆角。这个顺序要写死在解释器里不能依赖大模型的输出顺序。另一个坑是布尔运算的容差。OCCT 在做布尔运算时如果两个面几乎重合但不完全重合可能会产生细小的碎面或者失败。比如两个圆柱同轴但半径差 0.001mm布尔减运算可能报错。解决办法是在生成几何前做一次参数清洗把明显不合理的尺寸关系过滤掉比如孔径大于外径、孔心圆直径小于孔径等。这些校验规则要作为 schema 验证的一部分在几何生成之前就拦住。3.4 参数化与可编辑性text-to-cad 生成的不应该是一个死模型而应该是一个带参数的模型。这意味着解释器要支持改一个参数重新生成的能力。实现方式是把 schema 存下来几何生成函数接收 schema 作为输入输出模型。用户想改尺寸改 schema 里的数值重新跑一遍就行。如果对接的是前端可以把 schema 暴露成表单用户拖滑块就能实时看到模型变化。这里有个性能考量每次改参数都重新跑一遍完整的几何生成对于复杂零件可能比较慢。优化思路是只重新生成受影响的部分但这需要更复杂的依赖追踪一般原型阶段不值得做。我的经验是对于特征数在 20 个以内的零件全量重新生成通常在几百毫秒到一两秒交互体验可以接受。4. 格式导出STEP、URDF、G-code 各自的门道4.1 STEP 导出通用交换的底线STEP 是 text-to-cad 最基础的出口。它是 ISO 10303 标准下的格式主流 CAD 软件SolidWorks、UG、中望CAD、FreeCAD都能读。CadQuery 导出 STEP 就一行代码但有几个细节要注意。第一是单位STEP 文件内部默认用毫米如果你的 schema 用的是英寸导出前要转换。第二是精度OCCT 导出时可以设置write_pcurves和精度参数默认值一般够用但如果模型有很小的特征比如 0.1mm 的槽可能需要调高精度否则读进来会丢特征。实测中遇到过一个典型问题导出的 STEP 在 SolidWorks 里打开显示输入的文件包含无效的几何体。排查下来是模型里有自相交的面原因是倒角半径大于了相邻边的长度。这类问题在几何生成阶段就要校验比如倒角半径不能超过相邻最短边的一半。导出前的最后一道校验可以用 OCCT 的BRepCheck_Analyzer跑一遍确认几何有效再写文件。4.2 URDF 导出给机器人仿真用的模型URDF 是机器人领域描述模型的标准格式它不关心几何的精确 B-rep而是关心连杆的质量、惯性矩、关节类型和运动范围。text-to-cad 要输出 URDF意味着输入描述里得包含运动学信息比如一个两连杆机械臂第一段长 200mm第二段长 150mm关节都是旋转关节范围正负 90 度。这比纯几何描述复杂因为要建立连杆之间的父子关系和坐标系变换。URDF 的几何部分通常用 STL 或者 DAE 网格而不是 STEP。所以流程是先用 CadQuery 生成每个连杆的几何导出 STL然后写 URDF 的 XML把 STL 引用进去同时定义 joint 的 origin、axis、limit。惯性矩的计算是个麻烦事简单形状可以套公式复杂形状得用网格积分。如果精度要求不高可以用包围盒近似但仿真结果会有偏差。我一般建议在 URDF 里把 inertial 留空或者用简化值让用户在仿真软件里自己补因为惯性参数跟材料密度强相关而 text-to-cad 阶段往往不知道材料。4.3 G-code 生成从模型到刀路G-code 是数控加工和 3D 打印的指令格式。从 text-to-cad 直接生成 G-code中间其实还差一步切片或者CAM 规划。对于 3D 打印可以用 CuraEngine 或者 PrusaSlicer 的命令行接口把 STL 喂进去输出 G-code。对于 CNC 加工情况复杂得多需要定义毛坯、刀具、切削策略一般用 FreeCAD 的 Path 工作台或者专门的 CAM 软件。text-to-cad 在这个环节能做的是生成 STL 并调用切片器把打印参数层高、填充率、支撑作为额外输入。这里有个现实问题G-code 跟具体的机器强相关不同打印机的床身尺寸、喷嘴直径、回抽参数都不一样。所以 text-to-cad 输出的 G-code 只能是参考刀路真正上机前必须用目标机器的配置重新切片。我在项目里的做法是G-code 作为可选出口默认不生成用户明确需要时才调用切片器并且提示请用您的机器配置重新切片。4.4 三种格式的适用场景对照格式核心用途几何表示关键注意点STEPCAD 交换、CNC 加工B-rep 精确几何单位、精度、几何有效性校验URDF机器人仿真、运动学网格 运动学树惯性参数、关节坐标系、父子关系G-code3D 打印、CNC 加工刀路指令机器相关、需重新切片、参数配置选哪个格式取决于下游要干什么。做结构设计交 STEP做机器人算法验证交 URDF做快速原型交 G-code。一个成熟的 text-to-cad 系统应该支持多出口让用户按需选择。5. 实战踩坑我在搭原型时遇到的五个真实问题5.1 大模型把直径和半径搞混这是最高频的错误。用户说直径 80大模型有时候输出radius: 80结果模型放大一倍。解决办法是在 schema 里统一用直径字段名明确写diameter并且在 prompt 里强调所有圆形尺寸一律用直径表示。即便如此还是要在几何生成前加一道校验如果某个直径值明显偏大比如超过零件包围盒的两倍就报警让用户确认。这个校验规则救过我很多次。5.2 孔位计算用了角度制还是弧度制Python 的math.cos接收弧度但用户描述里说每隔 60 度大模型可能输出angle: 60。如果解释器直接把这个 60 喂给math.cos算出来的孔位就全错了。我的处理方式是在 schema 里明确角度字段用度为单位解释器内部统一转弧度。这个转换只在一处做避免散落在各处导致不一致。另外均布孔的第一个孔从哪个角度开始也要约定好我一般默认从 0 度正 X 轴方向开始逆时针排列。5.3 布尔运算失败但没有报错OCCT 的布尔运算有时候会静默失败——不抛异常但结果是个空实体或者只有一部分。这种情况特别隐蔽因为代码跑完了文件也导出了但打开一看模型是残缺的。排查方法是每次布尔运算后检查结果的体积或者面数如果体积接近零或者面数异常少就说明出问题了。我在解释器里加了一个validate_solid函数每个特征应用后都跑一遍一旦发现异常就回滚到上一个有效状态并记录日志。这样至少能保证输出的模型是完整的哪怕少了个别特征。5.4 导出的 STEP 在目标软件里读不出来不同 CAD 软件对 STEP 的兼容性有差异。我遇到过 CadQuery 导出的 STEP 在 FreeCAD 里正常在中望CAD 里打开却提示不支持的实体类型。后来发现是模型里用了 OCCT 的某些高级曲面类型中望的解析器不支持。解决办法是导出前把模型简化一下把高级曲面转成 NURBS 或者平面近似。OCCT 提供了ShapeUpgrade_UnifySameDomain和BRepBuilderAPI_Copy这类工具可以把模型规范化。虽然会损失一点精度但兼容性大大提升。如果目标软件明确最好在导出后实际用目标软件打开验证一遍别假设标准格式就一定通用。5.5 用户输入里混了非几何信息真实用户的描述里经常混着非几何信息比如这个零件要能承受 500N 的力表面要阳极氧化成本控制在 50 块以内。这些信息对几何生成没用但大模型可能会试图把它们塞进 schema导致解析失败。解决办法是在 prompt 里明确区分几何参数和非几何要求让大模型只抽取几何相关的非几何的放到一个notes字段里原样保留。这样既不丢信息又不干扰几何生成。notes字段可以在最终输出时附在模型旁边提醒用户这些要求需要人工处理。6. 把 text-to-cad 接进现有工作流的几种姿势6.1 作为 CAD 软件的插件最容易被工程师接受的形态是插件。用户在 SolidWorks 或者中望CAD 里装一个插件输入文字描述插件在后台调用 text-to-cad 服务生成的模型直接插入当前装配体。这种方式的优点是用户不用切换工具学习成本低。难点在于不同 CAD 软件的插件 API 差异很大SolidWorks 用 COM中望用 ZRXFreeCAD 用 Python要分别适配。如果资源有限可以先做 FreeCAD 插件因为它是开源的API 文档也全做完能覆盖一部分用户。6.2 作为独立的 Web 服务另一种形态是 Web 应用前端一个输入框用户输入描述后端生成模型前端用 Three.js 或者 model-viewer 做三维预览用户满意了再下载 STEP。这种形态适合非专业用户比如创客或者学生。技术栈上后端用 FastAPI 包一层 CadQuery前端用 React 加 Three.js。预览用的网格可以从 STEP 转成 GLTFThree.js 直接加载。这个方案我在内部工具里用过从输入到看到预览大概 3 到 5 秒体验可以接受。6.3 作为批量处理的脚本如果是做参数化零件库text-to-cad 可以做成批量脚本读一个 CSV每行是一段描述批量生成 STEP 文件。这种场景下稳定性比交互速度重要。我的做法是加一个重试机制解析失败或者几何生成失败就重试一次还失败就记录到错误日志继续处理下一行。批量跑完之后人工检查错误日志针对性地调整 prompt 或者 schema。这个模式适合做标准件库比如螺栓、轴承、型材的连接件。6.4 和现有 PDM/PLM 系统的对接企业环境里生成的模型最终要进 PDM 或者 PLM 系统。这时候除了模型文件本身还要生成配套的元数据零件号、版本、材料、作者、生成时间。这些信息可以在 text-to-cad 的输出里一并带上导出时写进 STEP 的自定义属性或者单独生成一个 JSON 伴随文件。STEP 的PRODUCT实体支持自定义属性CadQuery 导出时可以传metadata参数。这样模型进 PDM 的时候属性自动带过去省得人工录入。7. 几个提升生成成功率的实用技巧7.1 给用户一个描述模板与其让用户自由发挥不如给一个结构化的输入模板引导他们按零件类型—基体尺寸—特征列表—单位的顺序描述。比如零件类型法兰 基体圆柱外径 80mm厚 10mm 特征中心通孔直径 40mm均布 6 个直径 8mm 的孔孔心圆直径 60mm 单位毫米这种模板化的输入大模型解析的成功率比自由文本高很多。实测下来结构化输入的首次解析成功率能到 90% 以上而自由文本只有 60% 到 70%。如果产品面向的是非专业用户模板几乎是必须的。7.2 建立常见零件的 schema 库法兰、支架、齿轮、轴、板金件这些常见零件可以预先定义好 schema 模板。用户描述里只要匹配到零件类型就直接套用模板大模型只需要填参数不需要从零构建 schema。这样既快又稳。schema 库可以随着使用不断扩充遇到新的零件类型就加一个模板。这个思路类似于检索增强生成用预定义的模板约束大模型的输出空间。7.3 用几何校验做最后一道防线不管前面做得多好最后一定要有一道几何校验。校验内容包括模型是否非空、体积是否为正、是否有自相交、包围盒尺寸是否与描述一致、孔的数量和位置是否正确。这些校验可以用 CadQuery 和 OCCT 的 API 实现。校验不通过就返回错误并给出具体的失败原因比如检测到 5 个孔但描述要求 6 个。用户看到具体原因就知道怎么改描述。这道防线能拦住大部分低级错误避免把明显有问题的模型交给下游。7.4 记录失败案例持续优化 prompttext-to-cad 的准确率不是一次调好的而是靠持续迭代。每次解析失败或者几何生成失败都要把输入文本、大模型输出、失败原因记下来。积累几十个案例之后就能看出规律哪类描述容易出错哪个字段经常被搞混。然后针对性地改 prompt、加 few-shot 示例、补校验规则。我在项目里维护了一个failures.md每周review一次把高频问题转化成 prompt 里的约束。这个习惯让解析成功率在两个月里从 65% 提到了 88%。8. 关于精度、性能和扩展性的一些个人体会精度方面text-to-cad 生成的模型精度取决于几何内核OCCT 的精度是微米级的对于绝大多数机械零件够用。但要注意如果描述里的尺寸本身是模糊的比如大概 80mm那精度就无从谈起。所以我在 schema 里对尺寸字段加了确定性标记明确是精确值还是估计值。估计值在输出时会标注提醒用户复核。性能方面瓶颈通常不在几何生成而在大模型调用。一次 API 调用几百毫秒到几秒不等如果做交互式应用这个延迟是能感知的。优化手段包括用更小的模型做解析如果准确率够、缓存常见描述的解析结果、把几何生成放在本地避免网络往返。几何生成本身对于中等复杂度的零件CadQuery 跑一遍通常在 100 到 500 毫秒不是瓶颈。扩展性方面这套架构的扩展点主要在 schema 和特征库。每支持一种新特征比如扫掠、放样、阵列就在解释器里加一个处理函数。schema 的设计要留有余地比如features是个数组可以无限追加。我建议一开始就把 schema 设计得稍微通用一点别为了一个法兰把字段写死否则后面加新零件类型要重构。最后说个我自己的判断text-to-cad 短期内不会取代 CAD 工程师但它会改变工程师的工作方式。以前是从零画图以后是描述需求—审核生成结果—微调。工程师的价值会更多体现在判断生成结果是否合理、是否可制造而不是操作软件的熟练度。这个转变对愿意拥抱新工具的人是机会对固守旧流程的人是挑战。我自己的做法是把手头重复性最高的那部分建模工作先交给 text-to-cad省下来的时间用来学仿真和工艺这才是这个工具真正的价值所在。
返回列表