
1. 从一段文字到三维模型text-to-cad 到底在解决什么问题第一次听到 text-to-cad 这个词很多人脑子里浮现的画面大概是对着电脑敲一句给我画一个法兰盘然后屏幕上就自动长出一个三维模型。这个想象不算离谱但真正落地的时候它解决的问题比自动画图要具体得多也有意思得多。text-to-cad 的核心链路是把自然语言描述转换成可用的 CAD 几何数据最终输出成 STEP、GLB、STL 这类标准格式。它瞄准的不是替代工程师做复杂装配设计而是解决那些重复、琐碎、但又必须精确的建模需求——比如批量生成标准件、根据参数快速出草图、把一段文字需求直接变成可以导入下游工具的三维文件。为什么这件事值得单独拿出来讲因为传统 CAD 工作流里从想法到模型之间隔着一道很高的墙。你得熟悉软件界面、记住建模命令、理解特征树逻辑还要处理坐标系、单位、约束这些细节。对于非专业建模人员或者需要快速验证概念的场景这道墙的代价太高了。text-to-cad 想做的就是把这道墙拆掉一部分让描述需求和得到模型之间的距离缩短。适合看这篇内容的人大概分三类一是想给自己的工具链加一个文字转模型能力的产品或研发同学二是做参数化设计、批量建模想找自动化出口的工程师三是对 CAD 数据格式和三维管线感兴趣想搞清楚 STEP、GLB、STL 到底怎么选的技术爱好者。不管你属于哪一类下面这些内容都会围绕一个核心问题展开怎么把一句话变成一份能真正被下游软件吃进去的几何文件。需要先说明一点text-to-cad 不是一个单一软件的名字而是一类能力的统称。它背后可能是一个大模型加几何内核的组合也可能是一套规则引擎加模板库的方案。理解它的关键不在于记住某个工具而在于搞清楚语言到几何这条链路上每一步在做什么、容易在哪里出问题。2. 语言到几何的转换链路每一步都在丢信息也都在补信息2.1 自然语言解析把人话拆成结构化参数当你说一个直径 50 毫米、厚度 10 毫米、中心带 20 毫米通孔的圆盘模型首先要做的不是画图而是把这句话拆成结构化的字段。这个过程叫意图识别与参数抽取输出通常是一个类似 JSON 的结构{ shape_type: cylinder_with_hole, outer_diameter: 50, thickness: 10, hole_diameter: 20, unit: mm }这一步看起来简单实际是最容易翻车的地方。自然语言里充满了省略、歧义和隐含假设。比如厚度 10没说单位模型得根据上下文猜是毫米还是厘米中心带孔没说孔是不是通孔默认按通孔处理还是需要追问圆盘到底是圆柱还是带倒角的圆盘不同人理解不一样。我在实际测试中发现参数抽取的准确率高度依赖描述的结构化程度。你写得越像工程图纸的标注语言抽取越稳你写得越像日常聊天歧义越多。一个实用的经验是在描述里主动带上单位、明确数量词、避免大概差不多这类模糊表达。这不是模型能力的问题而是语言本身的特性决定的。2.2 几何内核建模参数怎么变成真实的 B-rep 实体拿到结构化参数之后下一步是调用几何内核生成实体。这里涉及一个关键概念B-rep边界表示法。简单说一个三维实体在计算机里不是用体积描述的而是用它的表面来描述的——每个面由边界曲线围成每条曲线由控制点定义。这种表示方式精度高、支持布尔运算是 STEP 格式的基础。常见的几何内核有 OpenCASCADE、Parasolid、ACIS 等。text-to-cad 类工具通常会选 OpenCASCADE因为它是开源的社区资料多对 STEP 的支持也成熟。用 OpenCASCADE 生成一个带孔圆盘大致流程是先创建一个圆柱体再创建一个圆柱形的刀具用布尔减运算把孔挖出来最后做倒角或圆角处理。注意布尔运算的顺序会影响结果。先挖孔再倒角和先倒角再挖孔得到的几何可能不一样。在批量生成时这个顺序必须固定下来否则同一批模型会出现细微差异。2.3 格式导出STEP、GLB、STL 各自适合什么场景模型建好之后要导出成文件。这时候格式选择就变得关键了。很多人以为导出哪个都行实际上不同格式承载的信息完全不同用错了下游会直接报错或者丢精度。格式本质保留信息典型用途是否支持参数STEPB-rep 实体精确几何、拓扑、单位工程交换、CNC 加工支持GLB三角网格 材质网格、颜色、纹理可视化、Web 展示不支持STL三角网格仅表面三角面片3D 打印、快速预览不支持STEP 是工程语言它记录的是精确的数学曲面一个圆柱面就是一个圆柱面不是一堆三角形拼出来的。GLB 和 STL 是网格语言它们把曲面离散成大量小三角形精度取决于网格密度。这就引出一个很实际的问题如果你要拿去加工必须用 STEP如果只是网页上看一眼GLB 更合适如果要 3D 打印STL 最通用。我见过不少人把 STL 转成 STEP 之后发现模型变成了一堆碎面原因就在这里——STL 本身没有拓扑信息转成 STEP 只能得到一堆独立的三角面片无法还原成完整的实体。这个坑在后面还会详细讲。3. 格式选型不是小事STEP、GLB、STL 的取舍逻辑3.1 STEP 的精确性与重的代价STEPStandard for the Exchange of Product model data是工程领域的事实标准。它的优势在于精确一个直径 50 毫米的圆在 STEP 里就是数学意义上的圆任何软件打开都是精确的 50 毫米。它还保留了完整的拓扑关系——哪个面和哪个面相邻、哪条边属于哪个面这些信息对后续的倒角、抽壳、装配都至关重要。但 STEP 也有代价。文件体积通常比 STL 大解析速度慢对几何内核的依赖强。一个复杂的 STEP 文件在低配置机器上打开可能要几十秒。而且不同内核之间的 STEP 转换偶尔会出现破面——面与面之间的缝隙超出了容差导致实体不封闭。在实际项目中我的做法是只要下游涉及工程操作无条件优先 STEP只有在纯展示场景才考虑 GLB。这个原则能避免绝大多数格式兼容问题。3.2 GLB 在可视化管线里的位置GLB 是 glTF 的二进制版本专为实时渲染设计。它的优势是加载快、体积小、支持材质和动画浏览器和移动端都能直接解析。如果你做的是一个在线预览功能用户上传描述、后台生成模型、前端用 Three.js 展示那 GLB 是最顺的选择。但 GLB 的几何是三角网格精度受网格密度限制。一个曲面在 GLB 里永远是看起来像曲面的一堆三角形。对于视觉展示这没问题对于需要测量、加工的场景这就是致命的。所以 GLB 的定位很明确它是给人看的不是给机器加工的。3.3 STL 的只读属性与转换陷阱STL 是最古老的 3D 打印格式结构极其简单一堆三角面片的顶点坐标加法向量。它没有单位、没有颜色、没有拓扑、没有曲面信息。正因为简单它兼容性最好几乎所有 3D 软件都能读。但 STL 的简单也是它的陷阱。前面提到的STL 转 STEP 变碎面就是典型问题。因为 STL 里每个三角形都是独立的软件无法知道哪些三角形原本属于同一个曲面。转换时只能把每个三角形当成一个平面结果就是模型变成千疮百孔的碎面集合。提示如果拿到的是 STL又需要做工程处理正确做法不是直接转 STEP而是用逆向工程工具重新拟合曲面或者干脆根据尺寸重新建模。直接转换得到的 STEP 基本没有工程价值。热搜词里出现的sw中stl转stp就是这个场景。SolidWorks 确实提供了转换功能但转换质量取决于 STL 的网格质量和软件的曲面拟合能力。实测下来规则几何体如方块、圆柱转换效果尚可复杂曲面基本没法用。4. 把 text-to-cad 跑起来一条可复现的最小链路4.1 环境准备几何内核和依赖的安装要点要自己搭一条 text-to-cad 链路核心依赖是几何内核。以 OpenCASCADE 为例在 Linux 上可以通过包管理器安装在 Windows 上建议用 conda 或者预编译包。Python 环境下pythonocc-core是最常用的绑定。conda install -c conda-forge pythonocc-core安装过程中最容易出问题的是版本匹配。OpenCASCADE 的版本和 pythonocc-core 的版本必须对应否则会出现符号找不到的错误。我的建议是直接用 conda 安装让它自动解决依赖不要手动编译。手动编译 OpenCASCADE 是个体力活动辄一两个小时还容易缺库。另外如果你打算做语言解析还需要一个大模型接口或者本地的 NLP 工具。这部分可以用现成的 API也可以用开源模型本地跑。选择取决于你对延迟、成本和数据隐私的要求。4.2 从描述到 STEP 的完整代码路径下面是一段用 pythonocc-core 生成带孔圆盘并导出 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 from OCC.Core.Interface import Interface_Static_SetCVal from OCC.Core.IFSelect import IFSelect_RetDone # 参数 outer_d 50.0 thickness 10.0 hole_d 20.0 # 创建外圆柱 axis gp_Ax2(gp_Pnt(0, 0, 0), gp_Dir(0, 0, 1)) outer BRepPrimAPI_MakeCylinder(axis, outer_d / 2, thickness).Shape() # 创建孔稍微加长确保切透 hole_axis gp_Ax2(gp_Pnt(0, 0, -1), gp_Dir(0, 0, 1)) hole BRepPrimAPI_MakeCylinder(hole_axis, hole_d / 2, thickness 2).Shape() # 布尔减 result BRepAlgoAPI_Cut(outer, hole).Shape() # 导出 STEP Interface_Static_SetCVal(write.step.unit, MM) writer STEPControl_Writer() writer.Transfer(result, STEPControl_AsIs) status writer.Write(disk.step) print(导出状态:, status IFSelect_RetDone)这段代码的逻辑很直白建外圆柱、建孔、相减、导出。但有几个细节值得注意。第一孔的高度要比厚度大否则布尔运算可能留下薄薄一层残留。第二导出前设置单位否则 STEP 文件可能默认用米下游打开尺寸会差 1000 倍。第三布尔运算的结果要检查是否有效复杂模型上偶尔会失败。4.3 导出 GLB 和 STL 的额外处理如果要导出 GLB 或 STL需要先把 B-rep 离散成网格。pythonocc-core 提供了BRepMesh_IncrementalMesh来做这件事。from OCC.Core.BRepMesh import BRepMesh_IncrementalMesh from OCC.Core.StlAPI import StlAPI_Writer # 离散化0.1 是线性偏差0.5 是角度偏差 BRepMesh_IncrementalMesh(result, 0.1, False, 0.5, True) stl_writer StlAPI_Writer() stl_writer.Write(result, disk.stl)这里的0.1和0.5两个参数直接决定网格质量。线性偏差越小曲面越平滑但三角形数量越多文件越大。对于 3D 打印0.1 毫米的偏差通常够用对于网页展示可以放宽到 0.5 甚至 1.0。这个参数没有标准答案取决于你的精度需求和性能预算。GLB 的导出稍微麻烦一点pythonocc-core 本身不直接支持通常的做法是先导出 STL 或 OBJ再用 trimesh、pygltflib 这类库转成 GLB。多一步转换但工具链更灵活。5. 实测中暴露的问题从能跑到能用的距离5.1 单位混乱一个被低估的高频错误单位问题是 text-to-cad 里最隐蔽的坑。自然语言描述里用户可能说50也可能说50 毫米还可能说5 厘米。如果解析环节没有统一单位后面全乱。更麻烦的是不同格式对单位的处理方式不一样STEP 可以在文件头声明单位STL 根本没有单位概念GLB 默认按米处理。我踩过的一次坑是生成的 STEP 在 FreeCAD 里打开是 50 毫米导出 STL 后导入切片软件变成了 50 米。原因是 STL 导出时没有做单位缩放而切片软件默认按毫米解析结果差了 1000 倍。解决办法是在导出 STL 前明确把模型缩放到目标单位并在文件名或元数据里标注单位。5.2 布尔运算失败复杂模型的常见故障布尔运算在简单模型上很稳但模型一复杂失败率就上来了。常见原因包括面与面重合导致容差判断失败、曲面自交、微小特征导致数值不稳定。表现就是运算结果为空、或者得到一个破面实体。排查这类问题的思路是先把模型简化去掉倒角、圆角这些细节看布尔是否成功如果成功再逐步加回细节定位是哪个特征导致的。另一个技巧是稍微调整刀具的位置或尺寸避开重合面。比如挖孔时让刀具比实体高出 0.01 毫米往往能绕过容差问题。提示OpenCASCADE 提供了BRepAlgoAPI_Cut的SetFuzzyValue方法可以放宽容差。但这个值是双刃剑放得太宽会引入几何误差建议从 1e-5 开始试。5.3 网格质量与文件体积的平衡导出 STL 或 GLB 时网格密度直接决定文件大小。一个直径 50 毫米的圆盘用 0.1 毫米偏差离散可能产生几万个三角形文件几百 KB用 1.0 毫米偏差可能只有几千个三角形文件几十 KB。对于单个模型无所谓但如果是批量生成几百个模型体积差异就很可观了。我的经验是根据下游用途定网格密度而不是一刀切。3D 打印用 0.05 到 0.1 毫米视觉展示用 0.3 到 0.5 毫米快速预览用 1.0 毫米。如果下游不确定就导出两个版本让用户自己选。6. 批量生成与自动化text-to-cad 真正的价值场景6.1 参数化批量出图的实际做法单个模型生成只是演示text-to-cad 真正的价值在批量场景。比如你有一张 Excel 表里面是 200 个法兰的尺寸参数需要全部生成 STEP 文件。手动建模是不可能的但用脚本就是循环的事。做法是把第 4 节的代码封装成函数参数从表格读取循环调用每个模型导出成独立文件。关键点是文件名要有意义最好包含关键参数比如flange_d50_h20_t10.step这样后续查找和追溯都方便。另外要加异常处理某个模型生成失败不能中断整个批次要记录失败原因继续跑。import csv with open(params.csv) as f: reader csv.DictReader(f) for row in reader: try: generate_disk( outer_dfloat(row[outer_d]), thicknessfloat(row[thickness]), hole_dfloat(row[hole_d]), outputfflange_d{row[outer_d]}_h{row[hole_d]}_t{row[thickness]}.step ) except Exception as e: print(f失败: {row}, 原因: {e})6.2 和现有 CAD 工具的衔接方式生成的模型最终要进入现有工作流。常见的衔接方式有两种一是直接输出文件让工程师手动导入二是通过 API 或脚本自动导入。前者简单但效率低后者需要目标 CAD 软件支持自动化接口。以 FreeCAD 为例它提供了 Python 控制台可以直接读取 STEP 文件并做后续处理。SolidWorks 有 API但需要授权和开发环境。中望 CAD 这类国产软件也在逐步开放接口。选择哪种方式取决于你的团队用什么工具、自动化程度要求多高。热搜词里的python批量对cad修改就是这个方向。用 Python 驱动 CAD 做批量操作核心思路是把重复性操作脚本化把参数从代码里抽出来变成配置。这样即使不懂编程的工程师改改配置文件也能用。6.3 失败重试与日志记录的必要性批量任务一定要有日志。哪个模型成功了、哪个失败了、失败原因是什么这些信息在出问题时是唯一的排查依据。我习惯把日志写成 CSV包含时间戳、输入参数、输出路径、状态、错误信息。这样跑完一批之后直接筛选失败项重跑就行。重试策略也要考虑。有些失败是偶发的比如内存不足重试一次可能就过了有些失败是参数问题比如孔径大于外径重试多少次都没用。所以重试前要先判断错误类型参数错误直接跳过并标记环境错误才重试。7. 几个容易被忽略的工程细节7.1 坐标系与朝向下游软件的默认假设不同软件对坐标系和朝向的默认假设不一样。有的默认 Z 轴向上有的默认 Y 轴向上有的默认模型中心在原点有的默认底面在原点。text-to-cad 生成的模型如果朝向不对导入下游后可能需要手动旋转批量场景下这就是灾难。解决办法是在生成阶段就统一约定Z 轴向上、底面在 Z0 平面、模型中心在 XY 原点。这个约定符合大多数工程软件的习惯能减少大量调整工作。如果下游有特殊要求再在导出前做一次变换。7.2 文件名与元数据批量场景下的可追溯性批量生成几百个文件如果文件名都是output_001.step后面根本分不清谁是谁。文件名要包含关键参数元数据要记录生成时间、版本、输入描述。STEP 文件支持自定义属性可以把这些信息写进去但很多软件不显示。更实用的做法是同时生成一个 CSV 索引文件记录文件名和参数的对应关系。7.3 精度与性能的取舍什么时候该够用就行text-to-cad 不是越精确越好。精度越高计算越慢文件越大。对于概念验证、快速预览这类场景低精度完全够用。我通常的做法是先生成低精度版本用于确认确认无误后再生成高精度版本用于交付。这样既快又省资源。8. 关于 text-to-cad 的一些个人判断折腾 text-to-cad 这段时间最大的体会是语言到几何的难点不在生成而在约束。大模型很擅长理解意图但几何是精确的差 0.01 毫米就是不合格。所以真正可用的 text-to-cad 方案一定是语言解析 规则校验 几何内核的组合而不是单纯依赖模型生成。另一个体会是格式的重要性被严重低估。很多人把精力全放在怎么生成模型上结果卡在导出的文件下游打不开。STEP、GLB、STL 各有各的脾气搞清楚它们的边界比多调几个模型参数更有价值。最后分享一个小技巧如果你要测试一个 text-to-cad 工具的能力不要用画一个复杂的机械臂这种描述而是用直径 50、厚 10、中心孔 20 的圆盘这种精确描述。前者考验的是想象力后者考验的是工程能力。而工程能力才是这类工具真正要解决的问题。