
1. 从一段文字到三维模型text-to-cad 到底在解决什么问题第一次听到 text-to-cad 这个词很多人脑子里浮现的是对着电脑说一句话屏幕上就蹦出一个零件。这个想象不算离谱但也不完全准确。text-to-cad 的本质是把自然语言描述转换成结构化的三维几何数据最终落地成 CAD 软件能打开、能编辑、能加工的文件格式比如 STEP、GLB、STL 这些。它解决的核心痛点很朴素传统建模太慢了。做过机械设计或者产品结构的人都有体会画一个带孔的法兰盘从草图、拉伸、打孔、倒角到出图熟手也得十几分钟。如果只是要一个概念验证用的粗略模型这个时间成本高得离谱。text-to-cad 想干的事情就是把这十几分钟压缩到几十秒——你用文字描述一个直径 80 毫米、厚 10 毫米、中心有 30 毫米通孔、边缘均布 6 个 8 毫米螺栓孔的圆盘系统直接吐出对应的三维模型文件。这里有个关键区分必须说清楚text-to-cad 生成的不是网格模型而是参数化实体模型。这两者的差别决定了它能不能真正进入工程流程。网格模型比如 STL本质上是一堆三角面片的集合你没法直接改它的尺寸参数而参数化实体比如 STEP保留了特征树和尺寸约束生成之后还能继续在 CAD 里编辑。这就是为什么 STEP 格式在 text-to-cad 领域被反复提及——它是工程可用性的分水岭。适合关注这个方向的人大致分三类。第一类是产品经理和工业设计师需要快速把想法变成可视化的三维草模用于沟通和评审。第二类是机械工程师想用文字驱动的方式批量生成标准件或者变型件省掉重复劳动。第三类是开发者和技术爱好者想搞清楚这背后的技术链路自己搭一套或者做二次开发。不管你是哪一类理解 text-to-cad 的能力边界和实现路径都比盲目追工具更有价值。2. 拆解 text-to-cad 的技术链路文字是怎么变成 STEP 文件的2.1 自然语言理解层把人话翻译成结构化参数text-to-cad 的第一步是把一段自由文本解析成机器能处理的参数集合。比如一个长 100、宽 50、高 20 的长方体顶面中心有个直径 10 的圆孔系统需要提取出基体类型是长方体尺寸是 100×50×20特征是顶面中心通孔孔径 10。这一步通常靠大语言模型LLM来完成因为它擅长从非结构化文本里抽取实体和关系。但这里有个坑LLM 输出的参数格式必须严格约束。如果你只是让模型理解这段话它可能给你一段自然语言回复但你需要的是 JSON 或者类似的结构化数据字段名、单位、坐标系定义都得固定。实践中常见的做法是设计一套 schema比如{ base_shape: box, dimensions: {length: 100, width: 50, height: 20}, features: [ {type: hole, face: top, position: center, diameter: 10, depth: through} ], unit: mm }这套 schema 的设计质量直接决定了后面几何生成的成败。字段太粗表达不了复杂特征字段太细LLM 容易填错。我的经验是先支持最基础的拉伸体、旋转体、孔、倒角这几类特征把 schema 打磨稳定再逐步扩展。一上来就想支持曲面放样、扫掠基本会陷入调试泥潭。2.2 几何内核层参数怎么变成真正的三维实体拿到结构化参数之后就需要几何内核来干活了。这一步是整个链路里技术门槛最高的部分。常见的开源几何内核有 OpenCASCADE简称 OCCT商业的有 Parasolid、ACIS。text-to-cad 项目绝大多数会选择 OpenCASCADE因为它开源、功能全、对 STEP 格式支持好。几何内核做的事情用大白话说就是根据你给的参数计算出这个实体的每一个面、每一条边、每一个顶点的精确数学表达。比如一个圆柱孔内核会生成一个圆柱面方程并计算出它和长方体顶面的交线。这些计算涉及大量的边界表示BRep操作精度要求极高——差 0.001 毫米在后续布尔运算里就可能报错。提示如果你自己搭 text-to-cad 原型强烈建议直接用 Python 的cadquery或者build123d库它们底层封装了 OpenCASCADE把常见的建模操作抽象成了链式调用能省掉大量底层调试时间。2.3 格式导出层STEP、GLB、STL 各自的分工模型在内存里建好之后要导出成文件。这时候不同格式的用途就体现出来了格式本质典型用途是否保留参数STEP边界表示实体工程交换、CAM 加工是保留 BRepSTL三角网格3D 打印、快速预览否GLB三角网格材质Web 展示、AR/VR否STEP 是工程领域的通用交换格式几乎所有 CAD 软件都能读。STL 是 3D 打印的事实标准但它只有网格没有特征信息。GLB 则是给网页和移动端展示用的带材质和光照信息适合做产品展示页。导出这一步看似简单其实有个常见问题网格精度设置。STL 导出时需要指定弦高偏差chord tolerance和角度偏差angular tolerance设得太粗圆孔变成多边形设得太细文件体积爆炸。一般 3D 打印场景弦高设 0.01 到 0.05 毫米比较合适具体看零件尺寸。3. 动手搭一个最小可用的 text-to-cad 流程3.1 环境准备Python 生态是当前最省事的选择如果你想快速验证 text-to-cad 的可行性Python 是目前最现实的起点。核心依赖就两个一个大语言模型的 API用来做文本解析一个几何建模库用来生成实体。几何库我推荐cadquery它的 API 设计比较直观文档也相对完整。安装很简单pip install cadquery pip install openaicadquery自带 OpenCASCADE 的绑定装完就能用。如果你在 Windows 上遇到编译问题可以考虑用 conda 安装conda install -c conda-forge cadquery通常更稳。3.2 文本解析给大模型一套严格的输出模板这一步的关键是 prompt 设计。你不能只说帮我解析这段话而要给出明确的输出格式要求。我常用的模板大致是这样import json from openai import OpenAI client OpenAI() SYSTEM_PROMPT 你是一个 CAD 参数解析器。用户会用自然语言描述一个三维零件 你需要输出严格的 JSON格式如下 { base_shape: box | cylinder, dimensions: {...}, features: [...], unit: mm } 只输出 JSON不要任何解释。 def parse_description(text): response client.chat.completions.create( modelgpt-4o, messages[ {role: system, content: SYSTEM_PROMPT}, {role: user, content: text} ], temperature0 ) return json.loads(response.choices[0].message.content)temperature0很重要它让输出尽量确定减少随机性。另外实际使用中一定要加异常处理因为模型偶尔会输出带 markdown 代码块的 JSON需要先清洗再解析。3.3 几何生成用 cadquery 把参数变成实体拿到 JSON 之后就可以调用 cadquery 建模了。下面是一个处理带孔长方体的示例import cadquery as cq def build_model(params): if params[base_shape] box: d params[dimensions] model cq.Workplane(XY).box(d[length], d[width], d[height]) for feat in params[features]: if feat[type] hole and feat[face] top: model (model.faces(Z).workplane() .hole(feat[diameter])) return model raise ValueError(Unsupported shape)这段代码的逻辑很直白先建一个长方体然后选中顶面在中心打一个通孔。faces(Z)是 cadquery 的选择器语法意思是选 Z 方向最靠上的面。这种链式写法比传统 CAD 的 API 友好很多。3.4 导出与验证STEP 和 STL 一起出模型建好之后导出两种格式model.val().exportStep(output.step) model.val().exportStl(output.stl, tolerance0.01)导出之后一定要用 CAD 软件或者在线查看器打开验证。我踩过的坑是模型在代码里没报错但导出的 STEP 在某些软件里显示为空原因是实体没有正确闭合non-manifold。这种情况通常出现在布尔运算之后解决办法是在导出前调用model.val().isValid()检查有效性。4. 实测中最容易翻车的几个环节4.1 单位混乱毫米和米混用导致模型大得离谱这是新手最常犯的错误。大语言模型在解析时如果你没说单位它可能默认按米来理解结果一个直径 80的圆盘变成了直径 80 米。解决办法有两个一是在 prompt 里强制要求输出单位字段二是在几何生成前做一次单位归一化统一转成毫米。注意STEP 文件本身不强制单位但大多数 CAD 软件默认按毫米读取。如果你的模型导出后在软件里尺寸差了 1000 倍八成就是单位问题。4.2 特征定位歧义中心到底是哪个中心顶面中心有个孔这句话人听起来没歧义但机器需要明确定义。是顶面的几何中心还是相对于某个基准点的中心如果零件本身不对称这两种理解会给出完全不同的结果。实践中我建议在 schema 里把位置定义成相对于面中心的偏移量默认 (0, 0)这样既简单又不容易出错。4.3 布尔运算失败孔打在了错误的位置当孔的位置超出了基体范围或者孔和已有的特征重叠布尔运算会失败。cadquery 在这种情况下可能不报错但生成的实体是无效的。我的做法是在每次布尔运算后检查实体有效性result model.cut(hole_solid) if not result.val().isValid(): raise RuntimeError(Boolean operation produced invalid solid)这个检查会增加一点运行时间但能帮你快速定位问题避免错误累积到导出阶段才发现。4.4 STL 网格精度圆孔变成六边形前面提过网格精度的问题这里再强调一次。默认的 STL 导出参数往往偏粗一个直径 10 毫米的孔可能只用了 8 个三角面片来近似看起来就是个多边形。对于需要 3D 打印的零件这个精度不够。把tolerance设到 0.01 毫米angularTolerance设到 0.1 弧度通常能得到比较光滑的曲面文件体积也在可接受范围内。5. 从原型到可用几个值得投入的优化方向5.1 建立常用零件模板库如果你的使用场景集中在某几类零件比如法兰、支架、齿轮坯与其每次都让大模型从零解析不如预先定义好模板让模型只负责填充参数。这样既提高了准确率又加快了生成速度。模板库可以用 YAML 或者 JSON 维护每个模板对应一段 cadquery 建模函数。5.2 加入尺寸合理性校验大模型有时候会给出物理上不合理的参数比如孔径大于零件本身。在生成几何之前加一层校验逻辑检查关键尺寸之间的关系。比如孔直径必须小于所在面的最小边长壁厚不能小于某个阈值。这层校验不需要很复杂但能挡掉大部分明显错误。5.3 支持多轮修改真正好用的 text-to-cad 工具应该支持在刚才那个模型基础上把孔改成 4 个这样的增量修改。实现方式是把上一轮的参数 JSON 保留下来让大模型基于它做修改而不是重新解析。这样用户体验会好很多也更接近真实的建模工作流。5.4 批量生成与参数扫描这是 text-to-cad 相比手工建模最大的优势场景。比如你需要生成 20 个不同长度的支架只需要准备一个参数表循环调用建模函数即可。配合 Python 的循环和文件命名规则几分钟就能出一整套模型。这种批量能力在标准件库建设、产品系列化设计中非常实用。6. 关于格式选择的一些实战体会回到 STEP、GLB、STL 这三个格式我在实际项目里的选择逻辑是这样的只要下游还要做工程处理一律出 STEP。STEP 保留了完整的边界表示可以被 SolidWorks、中望 CAD、Fusion 360 等软件读取和继续编辑。如果只是给客户看效果出 GLB文件小、加载快、带材质。如果要 3D 打印出 STL但记得调精度。有一个细节值得注意从 STL 转回 STEP 是很麻烦的因为网格转实体需要重建曲面这个过程叫逆向工程工具贵且效果不稳定。所以能出 STEP 的时候千万别只出 STL不然后面想改都改不了。这也是为什么 text-to-cad 项目里STEP 导出能力是核心竞争力之一。另外如果你生成的模型要导入到某些特定软件里比如中望 CAD 或者浩辰 CAD建议导出前确认一下 STEP 的版本。AP214 和 AP203 是两个常见版本前者支持颜色和图层后者更基础。大多数情况用 AP214 就行兼容性够好。7. 我在这条路上踩过的几个坑第一个坑是过度依赖大模型的几何理解能力。早期我试过让模型直接输出 cadquery 代码而不是结构化参数。结果模型经常写出语法正确但几何错误的代码比如把hole()用在了错误的工作平面上。后来改成模型只负责解析参数几何生成用固定代码稳定性大幅提升。这个分工原则很重要让大模型做它擅长的语义理解把几何计算交给确定性的代码。第二个坑是忽略了坐标系定义。不同 CAD 软件对上的方向定义不一样有的 Z 轴向上有的 Y 轴向上。如果你的模型要跨软件使用最好在导出前确认坐标系约定必要时做一次旋转。我遇到过一次模型导入后整个躺倒的情况排查了半天才发现是坐标系差异。第三个坑是没有做输入清洗。用户输入的文字里可能带各种奇怪字符、全角标点、甚至换行符直接丢给大模型会影响解析质量。加一个简单的文本预处理把全角转半角、去掉多余空白能明显提升解析成功率。第四个坑是文件命名和版本管理。批量生成模型的时候如果命名规则不清晰很快就会分不清哪个文件对应哪组参数。我的做法是把关键参数编码进文件名比如flange_D80_t10_hole30_6x8.step一眼就能看出规格。配合一个简单的 CSV 记录表追溯起来很方便。这套流程跑通之后生成一个中等复杂度的零件大概需要 10 到 30 秒其中大部分时间花在大模型 API 调用上。如果对速度有要求可以考虑本地部署小模型做解析或者把常用描述缓存起来。几何生成本身其实很快通常不到一秒。