text-to-cad 实战:从自然语言到 STEP/GLB/STL 的完整技术链路

发布时间:2026/10/8 10:08:34
text-to-cad 实战:从自然语言到 STEP/GLB/STL 的完整技术链路 1. 从一段文字到三维实体text-to-cad 到底在解决什么问题第一次听到 text-to-cad 这个词很多人脑子里浮现的画面大概是对着电脑敲一句给我画一个法兰盘然后屏幕上就自动长出一个三维模型。这个想象不算离谱但真正落地的时候它要解决的问题比自动画图要具体得多也琐碎得多。text-to-cad 的核心是把自然语言描述转换成结构化的 CAD 几何数据。这里的CAD 几何数据不是一张截图也不是一段渲染视频而是能被下游软件真正读取、编辑、加工的模型文件——常见的就是STEP、GLB、STL这几种格式。STEP 偏向精确的边界表示B-rep适合机械加工和工程交换GLB 是面向渲染和 Web 展示的轻量格式STL 则是三角网格3D 打印和快速预览用得最多。这三种格式基本覆盖了从能加工到能看的完整链路。为什么这件事值得单独拿出来做因为传统 CAD 建模的门槛卡在人身上。一个熟练的工程师画一个标准件可能只要几分钟但一个不懂 CAD 的产品经理、一个只想快速验证外观的设计师、一个需要批量生成零件库的开发者他们面对 CAD 软件里密密麻麻的草图约束、基准面、特征树往往第一步就卡住了。text-to-cad 想做的就是把描述需求和生成模型之间的那道墙拆掉让不会用 CAD 的人也能拿到可用的三维文件。这篇文章适合几类人看一是想自己搭一套 text-to-cad 流程的开发者二是想理解这类工具底层逻辑的产品和设计人员三是手里有一堆文字需求、想批量转成模型的工程从业者。我会从整体架构讲到具体实现把 STEP、GLB、STL 三种输出的取舍、自然语言到几何参数的映射、以及实际跑起来会踩的坑都摊开讲清楚。文中涉及的具体代码和参数是基于这类项目常见做法做的合理补全你可以直接拿去改。2. 拆解 text-to-cad 的技术链路从一句话到三种格式2.1 为什么不能一步到位语言和几何之间隔着三层很多人以为 text-to-cad 就是一个大模型的事输入文字输出模型中间没什么好讲的。真做起来会发现语言和几何之间至少隔着三层转换每一层都有各自的坑。第一层是语义理解。用户说一个直径 50 毫米、厚 10 毫米的圆盘中间开一个直径 10 毫米的孔模型需要从中抽出形状是圆柱、外径 50、高度 10、有一个同轴的通孔、孔径 10。这一步的难点不在识别名词而在处理隐含约束——中间意味着同轴通孔意味着贯穿圆盘默认是实心圆柱。这些词在人类看来理所当然但要让程序准确还原得有一套参数抽取和约束推断的逻辑。第二层是参数到几何的映射。抽出来的参数是数字和关系还需要转成真正的几何操作序列先拉伸一个圆柱再布尔减去一个小圆柱。这一步决定了模型是不是可编辑的。如果直接生成网格那模型就是一坨三角面改个孔径都得重来如果生成的是带特征的 B-rep那下游还能继续改。第三层是几何到文件格式的序列化。同一个几何体写成 STEP 要保留精确曲面和拓扑关系写成 STL 要三角化写成 GLB 要处理材质和坐标系。三种格式对精度的要求、对坐标系的约定都不一样这一步做不好模型在别的软件里打开就会变形、错位甚至报错。把这三层想清楚整个项目的架构就清晰了前端负责收集自然语言中间层做语义解析和参数抽取几何内核负责建模最后是格式导出。下面逐层展开。2.2 语义解析层把口语变成结构化参数语义解析这一层实际项目里通常有两种做法。一种是规则 模板针对特定品类比如标准件、法兰、齿轮预先写好解析规则另一种是大模型抽取让模型输出结构化的 JSON。两种做法各有适用场景我的经验是品类固定、精度要求高的场景用规则更稳品类开放、描述自由的场景用大模型更灵活但一定要加校验。举个具体的例子。用户输入做一个 80x60x5 的底板四角各一个 M4 的沉头孔理想情况下解析出来的结构大概是这样{ type: plate, size: {length: 80, width: 60, thickness: 5}, features: [ { type: countersunk_hole, thread: M4, count: 4, position: four_corners, edge_offset: 8 } ], unit: mm }这里有几个细节值得说。单位必须显式抽取因为 CAD 里毫米和米差一千倍一旦搞错整个模型就废了。边距edge_offset用户往往不会说但沉头孔不可能贴着边角得有个默认值通常取孔径的 1.5 到 2 倍。螺纹规格M4要能映射到具体的孔径和沉头尺寸这需要一张标准件对照表不能靠模型瞎猜。提示语义解析的输出一定要做范围校验。比如厚度不能为负、孔径不能大于板宽、孔间距不能小于孔径。这些校验放在解析层做比等到几何建模时报错要早得多也更容易给用户友好的提示。我踩过的一个坑是早期版本直接让大模型输出几何参数结果它经常把直径和半径搞混或者把厚 10理解成高 10。后来加了一层单位与语义归一化把所有尺寸统一成直径/半径/长/宽/高/厚这几个明确字段并在 prompt 里强制要求标注每个数字的含义错误率才降下来。这个经验很朴素但很关键不要让模型输出自由文本要让它填表。2.3 几何建模层为什么选 B-rep 而不是直接堆三角面几何建模层是整个项目的核心也是最能体现技术选型差异的地方。这里有个根本性的选择用 B-rep边界表示还是用网格mesh。网格建模简单直接所有形状最终都是一堆三角形生成快、渲染快、导出 STL 几乎零成本。但它的致命问题是不可参数化编辑。你生成一个带孔的圆盘想改孔径只能重新生成整个网格而且网格的孔边缘是锯齿状的精度取决于三角化密度。对于 3D 打印预览、游戏资产这类场景网格够用但对于要加工、要出工程图的场景网格不行。B-rep 则保留了精确的曲面定义和拓扑关系。一个圆柱面就是轴 半径 高度这几个参数孔就是一条布尔运算记录。改孔径只需要改一个数字重新求值即可。STEP 格式天然就是 B-rep 的载体所以做 text-to-cad 如果要输出 STEP几何内核基本绕不开 B-rep。实际项目里几何内核通常用现成的库比如OpenCASCADE开源、功能全、支持 STEP、CGAL偏计算几何、或者商业内核。选 OpenCASCADE 的理由很实际它同时支持 B-rep 建模、布尔运算、STEP/STL 导出还有 Python 绑定pythonocc对快速搭原型非常友好。下面是一段用 pythonocc 生成带孔圆盘并导出 STEP 的示意代码from OCC.Core.BRepPrimAPI import BRepPrimAPI_MakeCylinder from OCC.Core.BRepAlgoAPI import BRepAlgoAPI_Cut from OCC.Core.gp import gp_Ax2, gp_Pnt, gp_Dir from OCC.Core.STEPControl import STEPControl_Writer, STEPControl_AsIs # 外圆柱半径 25高 10 outer BRepPrimAPI_MakeCylinder(25.0, 10.0).Shape() # 内孔圆柱半径 5高 20故意做长保证贯穿 inner BRepPrimAPI_MakeCylinder(5.0, 20.0).Shape() # 布尔减得到带孔圆盘 disk BRepAlgoAPI_Cut(outer, inner).Shape() # 导出 STEP writer STEPControl_Writer() writer.Transfer(disk, STEPControl_AsIs) writer.Write(disk.step)这段代码看着简单但有几个实操细节。内孔圆柱的高度要大于外圆柱否则布尔运算可能因为共面问题失败这是 OpenCASCADE 里非常经典的坑。布尔运算的顺序也有讲究先做减再做别的特征比反过来稳定。还有布尔运算之后最好做一次形状修复ShapeFix清理掉微小的边和面否则导出的 STEP 在某些软件里会报拓扑错误。2.4 格式导出层STEP、GLB、STL 各自的脾气三种格式的导出看着只是换个函数调用实际上每个都有自己的脾气。STEP是工程交换的标准精度最高保留完整的 B-rep。导出时要注意单位和坐标系。STEP 文件头里会写明单位如果建模时用的是毫米导出时也要声明毫米否则下游软件可能按米来读模型直接缩小一千倍。另外 STEP 有 AP203、AP214、AP242 等不同协议版本AP242 支持颜色和 PMI产品制造信息如果下游需要这些信息导出时要选对版本。STL是三角网格导出时最关键的是弦高公差chordal tolerance和角度公差。公差越小三角面越密文件越大但越接近真实曲面公差越大文件小但曲面会有明显棱角。对于 3D 打印一般弦高取 0.01 到 0.05 毫米比较合适对于快速预览0.1 毫米也够。这里有个经验公式如果模型最大尺寸是 L弦高公差取 L 的千分之一到千分之五能在精度和文件大小之间取得不错的平衡。GLB是 glTF 的二进制版本面向渲染和 Web 展示。它支持材质、颜色、PBR 贴图但不关心精确几何。导出 GLB 时要注意坐标系转换——CAD 常用 Z 轴向上而 glTF 约定 Y 轴向上不做转换的话模型在网页里会躺着。另外 GLB 的网格也需要三角化但可以带法线和 UV视觉效果比 STL 好很多。格式几何类型典型用途关键导出参数常见坑STEPB-rep机械加工、工程交换单位、协议版本单位错、拓扑错误STL三角网格3D 打印、快速预览弦高公差、角度公差公差过大导致棱角GLB三角网格 材质Web 展示、渲染坐标系、材质Y/Z 轴不转换把这张表记住基本就能避开格式导出阶段八成的坑。3. 把自然语言映射到几何参数几个真实场景的拆解3.1 标准件场景规则比模型更靠谱标准件是 text-to-cad 最容易出成果的场景因为它的参数空间是封闭的。螺栓、螺母、垫圈、轴承、法兰这些都有国家标准或行业标准尺寸是查表得来的不需要模型去理解只需要模型去匹配。以法兰为例用户说DN50 的板式平焊法兰程序要做的不是去推理几何而是查表DN50 对应的外径、螺栓孔中心距、螺栓孔数量、螺栓孔直径、法兰厚度这些在标准里都是定值。程序只需要把DN50这个关键词映射到表里的一行然后按固定模板生成几何。这种场景下规则引擎比大模型可靠得多。大模型可能把 DN50 的螺栓孔数量记成 4 个实际通常是 4 个但 DN 不同数量不同而查表永远不会错。我的做法是大模型只负责识别品类和规格比如从DN50 板式平焊法兰里抽出{category: flange, standard: plate_flat_weld, nominal: DN50}剩下的尺寸全部查表。这样既利用了模型的语言理解能力又保证了尺寸的准确性。注意标准件的标准号一定要让用户能指定或程序能推断。同样是 DN50 法兰国标和化工部标准的尺寸可能不一样。如果用户没说程序要给出默认值并明确提示用的是哪个标准避免下游加工时对不上。3.2 自由形状场景模型负责创意几何内核负责落地自由形状就麻烦多了。用户说一个流线型的手机支架底部宽一点顶部有个弧度这种描述里几乎没有精确参数全是形容词。这时候大模型的作用是把形容词转成可量化的几何操作。比如底部宽一点可以转成底部截面宽度 80 毫米向上逐渐收窄到 60 毫米顶部有个弧度可以转成顶部用半径 30 毫米的圆弧过渡。这些转换没有唯一正确答案模型给的是一个合理的近似。程序要做的是把这个近似变成几何内核能执行的放样loft或扫掠sweep操作。这里的关键是给模型提供几何操作的词汇表。不要让模型自由发挥说做个流线型而是告诉它你可以用拉伸、旋转、放样、扫掠、圆角、倒角这几种操作每种操作的参数是什么。模型在这个受限空间里做选择输出的就是可执行的建模指令而不是一段无法落地的描述。我实测下来自由形状场景的满意度大概在六七成剩下的三四成需要人工微调。这不是模型不行而是自然语言本身就有歧义。所以这类工具的产品设计上一定要留参数微调面板让用户在生成结果上直接改尺寸而不是重新描述一遍。3.3 参数校验那些模型不会主动告诉你的约束无论哪种场景参数校验都是绕不开的一环。模型抽取出来的参数经常在几何上是不成立的比如孔径大于板宽孔直接开到板外面去了圆角半径大于相邻边长度圆角做不出来壁厚为负或者薄到无法加工两个特征在空间上重叠布尔运算会失败这些约束模型本身不知道几何内核在运算时才会报错但报错信息往往很晦涩。好的做法是在解析层和建模层之间加一道校验用一套规则提前拦截明显不合理的参数并给出人类能看懂的提示。def validate_plate(params): errors [] if params[thickness] 0: errors.append(厚度必须大于 0) if params[thickness] params[length] / 2: errors.append(厚度过大超过板长的一半请确认) for hole in params.get(holes, []): if hole[diameter] params[width]: errors.append(f孔径 {hole[diameter]} 超过板宽 {params[width]}) if hole[edge_offset] hole[diameter]: errors.append(孔边距小于孔径可能导致边缘破裂) return errors这段校验逻辑很朴素但能拦下大部分低级错误。我的经验是校验规则要随着实际使用不断补充每遇到一次几何内核报错就回头加一条前置校验慢慢就形成了一套贴合自己业务场景的规则库。4. 实测中绕不开的坑从环境搭建到批量生成4.1 几何内核的环境依赖装不上是常态做 text-to-cad第一个拦路虎往往不是算法而是几何内核装不上。OpenCASCADE 这类库依赖多、编译复杂在 Windows 上尤其容易出问题。pythonocc 虽然提供了 conda 包但版本和 Python 版本的对应关系很敏感装错版本就是一堆 import 错误。我的建议是用 conda 而不是 pip并且锁定版本。pythonocc 的 conda 渠道维护得比较及时conda install -c conda-forge pythonocc-core7.7.0这类命令比 pip 装源码靠谱得多。如果非要用 pip那就要做好编译依赖的准备Windows 上还需要对应的 Visual Studio 构建工具。另一个常见问题是中文字体和路径。几何内核在处理文件路径时对非 ASCII 字符的支持时好时坏导出的 STEP 文件如果路径里有中文某些下游软件会打不开。稳妥的做法是工作目录和输出文件名全部用英文和数字需要中文名的话在导出后再重命名。提示如果只是做原型验证不想折腾环境可以考虑先用网格库比如 trimesh跑通流程它能直接输出 STL 和 GLB装起来简单得多。等流程验证完再换成 OpenCASCADE 补上 STEP 输出。这样分阶段推进能少走很多弯路。4.2 布尔运算失败最常见的几何报错布尔运算失败是 B-rep 建模里出现频率最高的问题没有之一。表现是两个形状明明看着相交运算却返回空或者报错。原因通常有几类一是共面。两个形状的某个面完全重合内核在判断面内面外时会出现数值歧义。解决办法是让相交的形状稍微错开一点比如做孔的时候让圆柱比板厚长一点做凸台的时候让凸台稍微嵌入基体。二是微小边和面。模型经过多次运算后会积累很多长度接近零的边这些边在容差范围内会导致拓扑判断失败。解决办法是定期做形状修复用 ShapeFix 清理掉这些微小元素。三是容差设置不当。几何内核有个全局容差默认值对大多数场景够用但如果模型尺寸特别大或特别小就需要调整。比如做微米级的模型默认容差可能比模型特征还大运算必然失败。我处理布尔失败的流程一般是先看是不是共面错开一点再试不行就做形状修复再不行就检查容差和模型尺寸比例。这套流程能解决九成以上的布尔问题。4.3 批量生成的性能与稳定性单次生成跑通之后下一步往往是批量生成。这时候性能和稳定性就成了主要矛盾。几何运算本身是 CPU 密集型的单次生成一个中等复杂度的零件可能要几百毫秒到几秒批量几百个就是几分钟到几十分钟。优化的方向有几个。并行化是最直接的几何运算之间通常没有依赖可以用多进程并行。注意是多进程不是多线程因为几何内核的运算大多不受 GIL 释放多线程基本没收益。缓存也很重要相同的参数组合没必要重复计算把参数哈希作为 key 缓存结果能省下大量重复运算。稳定性方面批量生成最怕的是中途崩溃。一个零件运算失败不能让整个批次挂掉。做法是每个零件单独 try-catch失败的记录下来成功的正常输出最后给一份报告。这样即使有百分之几的失败率也不影响整体交付。import hashlib import json from concurrent.futures import ProcessPoolExecutor def cache_key(params): return hashlib.md5(json.dumps(params, sort_keysTrue).encode()).hexdigest() def generate_one(params): key cache_key(params) if key in cache: return cache[key] try: shape build_shape(params) export_all(shape, key) cache[key] key return key except Exception as e: return {error: str(e), params: params} with ProcessPoolExecutor(max_workers4) as pool: results list(pool.map(generate_one, all_params))这段代码里max_workers一般设成 CPU 核心数不要设太大否则进程切换开销反而拖慢速度。缓存用文件或数据库都行关键是 key 要能唯一标识参数组合。4.4 输出文件的验证别等下游打开才发现问题生成完文件一定要做自动验证不能假设几何内核导出的文件一定没问题。验证至少包括几项文件能不能被重新读取、几何是否有效有没有自交、有没有零面积面、包围盒尺寸是否符合预期、体积是否为正。STL 的验证相对简单读进来检查三角面数量和包围盒即可。STEP 的验证复杂一些需要重新读入并做有效性检查。GLB 可以用 glTF 校验工具过一遍。这些验证步骤看着繁琐但能避免生成了一堆文件下游一个都打不开的尴尬。我一般会在批量生成后跑一个验证脚本把不合格的文件单独列出来附上失败原因。这样交付的时候心里有底用户也能快速定位问题。5. 关于 text-to-cad 的一些个人判断和实用建议做了一段时间这类项目有几个体会比较深分享出来供参考。第一text-to-cad 不是要取代 CAD而是要填补描述和建模之间的空白。它能处理的是那些结构相对清晰、参数相对明确的需求对于高度复杂、需要反复推敲的设计还是得靠人在 CAD 里做。把它定位成一个快速出草模和批量出标准件的工具期望值会更合理。第二格式选择要看下游。如果下游是加工STEP 是首选精度和可编辑性都最好如果下游是 3D 打印STL 够用但要注意公差如果下游是网页展示GLB 最合适但记得转坐标系。不要指望一种格式打天下。第三参数校验和错误提示的价值往往比生成能力本身还高。用户能接受这个需求我暂时做不了但不能接受生成了一个错误的模型还不告诉我。把校验做扎实把错误信息写清楚用户体验会好很多。第四几何内核的坑是躲不掉的只能一个个踩过去。布尔失败、容差问题、单位错误、坐标系混乱这些是 B-rep 建模的必修课。建议在项目早期就建一个问题记录文档每遇到一个坑就记下来附上复现条件和解决办法时间长了就是一份很有价值的内部资料。最后说一个具体的技巧如果你要输出 STEP 给下游加工导出前一定要做一次单位确认和包围盒检查。我见过太多次因为单位搞错一个 50 毫米的零件变成 50 米下游软件打开直接卡死。加一行包围盒打印几秒钟的事能省下大量沟通成本。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询