
1. 从一句话到三维实体text-to-cad 到底在解决什么问题第一次听到 text-to-cad 这个词很多人脑子里浮现的画面大概是对着电脑说一句给我画个法兰盘屏幕上就自动长出一个带螺栓孔的三维模型。这个想象不算离谱但真正落地的时候它解决的问题比语音画图要具体得多也有意思得多。text-to-cad 的核心是把自然语言描述转换成计算机辅助设计CAD能够识别的几何数据。这里的CAD不是指某个具体软件而是指整个几何建模与工程制图的技术体系而text也不只是随口一句话它可以是结构化的参数描述、一段规格说明甚至是一份从需求文档里摘出来的尺寸表。最终产物通常是一个可被下游工具消费的文件——可能是STEP通用的三维交换格式、URDF机器人领域描述连杆与关节的格式也可能是G-code数控加工或 3D 打印的执行指令。为什么这件事值得单独拿出来做因为传统 CAD 工作流里从想法到模型这一段高度依赖人工。工程师打开软件画草图、拉伸、打孔、倒角一个中等复杂度的零件动辄半小时起步。如果需求是批量生成——比如一百个尺寸略有差异的支架或者一批参数化的机械臂连杆——纯手工建模的时间成本会迅速失控。text-to-cad 的价值就在于把这段重复劳动自动化用文本描述参数用程序生成几何人只负责定义规则和校验结果。它适合谁三类人最直接受益。第一类是做参数化设计的工程师手里有大量结构相似、尺寸不同的零件第二类是机器人方向的开发者需要频繁生成 URDF 模型来搭建仿真环境第三类是做增材制造或数控加工的从业者希望从参数直接跳到 G-code跳过中间的手工建模环节。哪怕你只是刚接触 CAD 制图入门的新手理解这套思路也能帮你建立几何即数据的认知而不是把 CAD 当成一个只能手点鼠标的黑盒。需要先泼一盆冷水text-to-cad 不是AI 帮你画图的魔法。它更像一套参数化建模的自动化管线文本只是入口真正的功夫在于你怎么把语言里的模糊描述翻译成精确的、无歧义的几何参数。这一点想不清楚后面全是坑。2. 文本到几何的翻译链路参数、约束与格式选择2.1 自然语言里的尺寸为什么不能直接用人说话是模糊的。一个大概 50 毫米长的支架——这句话里大概是致命的。CAD 内核不接受大概它要的是确定的数值和明确的拓扑关系。所以 text-to-cad 的第一步永远是把自然语言归一化成结构化参数。我通常的做法是定义一个参数字典把描述里能提取的数值全部落到键值对上。比如长 50、宽 30、厚 5、四角各一个直径 4 的通孔孔中心距边缘 6 毫米翻译成结构大概是这样params { length: 50.0, width: 30.0, thickness: 5.0, hole_dia: 4.0, hole_offset: 6.0, hole_count: 4, }注意这里我把四角这种空间描述转成了hole_count加hole_offset的组合。为什么因为几何生成代码需要的是可计算的坐标而不是角这种人类概念。四个孔的中心坐标可以这样推出来half_l params[length] / 2 - params[hole_offset] half_w params[width] / 2 - params[hole_offset] centers [ (-half_l, -half_w), ( half_l, -half_w), (-half_l, half_w), ( half_l, half_w), ]这段推导看着简单但它体现了 text-to-cad 的核心思维把语言里的相对描述转成绝对坐标。凡是描述里出现边缘中心对称等距这类词都要在代码里找到对应的数学表达。这一步做扎实了后面生成什么格式都只是换输出层的事。2.2 约束比尺寸更重要新手最容易忽略的一点光有尺寸模型可能是飘的。什么意思你告诉程序画一个 50 长的板但没告诉它这块板在坐标系里的位置、朝向、和相邻零件的关系。结果就是每次生成的模型位置都不一样装配的时候全乱套。所以在参数化建模里约束constraint和尺寸同等重要。常见的约束有几类几何约束平行、垂直、相切、同心。比如这个孔和那个轴同心决定了两个特征必须共享轴线。尺寸约束长度、角度、半径。这是最直观的一类。位置约束相对于原点或某个基准面的偏移。决定了零件在全局坐标系里的落点。在文本描述里这些约束往往藏在形容词和介词里。与底面垂直的立柱沿 X 轴对称分布的两个耳片——每一句都在施加约束。做 text-to-cad 的时候我习惯先把描述拆成实体 约束两张清单实体负责形状约束负责关系两边都齐了再动手写生成逻辑。2.3 STEP、URDF、G-code三种输出各管一段同一个几何体输出成什么格式取决于下游要拿它干什么。这三者经常被混为一谈其实分工很清楚。格式主要用途关键特点典型下游工具STEP通用三维交换保留精确 B-rep 几何跨软件兼容各类 CAD 软件、CAM 软件URDF机器人建模描述连杆、关节、惯性、碰撞体机器人仿真环境G-code加工执行刀具路径指令面向机床/打印机数控机床、3D 打印机STEP 是几何的通用语言。你在这个软件里建的模型导出 STEP 后换个软件打开形状基本不会变。它记录的是精确的边界表示B-rep不是网格近似所以做后续的 CAM 加工或者精确装配都靠它。URDF 则是机器人的骨架说明书。它不关心你零件表面多光滑它关心的是这个连杆的质量是多少、惯性张量怎么算、和下一个连杆通过什么关节连接、关节的旋转轴在哪。所以从 CAD 几何转 URDF 的时候质量属性和关节定义是必须补上的信息光有形状不够用。G-code 是给机器的命令。它把几何切成一层层的路径或者一条条的刀具轨迹输出成机器能逐行执行的指令。从几何到 G-code 中间通常还要经过切片或刀路规划text-to-cad 如果直接输出 G-code等于把建模和加工规划一起包了复杂度会高不少。我的建议是默认输出 STEP需要仿真再加 URDF需要加工再走 G-code。不要一上来就追求端到端先把几何生成这一层做稳。3. 搭一条能跑的参数化生成管线3.1 工具选型为什么我优先考虑脚本化建模要自动化生成几何第一步是选一个能用代码驱动的建模工具。纯 GUI 的 CAD 软件虽然功能强但很难批量调用。我这些年试下来比较顺手的路线有这么几条CadQuery基于 Python 的参数化建模库语法接近描述几何而不是操作鼠标写起来直观导出 STEP 很方便。OpenSCAD用脚本描述实体适合做规则化的机械结构社区模型多但复杂曲面偏弱。FreeCAD 的 Python 接口功能全能覆盖从建模到导出的完整链路学习曲线稍陡。直接调用几何内核比如通过 OCCT 的绑定做底层操作灵活但门槛高。选哪个取决于你的模型复杂度和你对编程的熟悉度。如果只是规则零件批量生成CadQuery 或 OpenSCAD 足够如果要做复杂装配和工程图FreeCAD 的接口更合适。我个人的默认选择是 CadQuery因为它的 API 设计让参数到几何的映射非常直接调试起来也快。3.2 一个最小可用的生成脚本下面这段是我常用的骨架用 CadQuery 生成一块带四角孔的板然后导出 STEP。你可以直接拿去改参数。import cadquery as cq def make_plate(length, width, thickness, hole_dia, hole_offset): # 先建基础板 plate cq.Workplane(XY).box(length, width, thickness) # 计算四个孔的中心位置 half_l length / 2 - hole_offset half_w width / 2 - hole_offset centers [ (-half_l, -half_w), ( half_l, -half_w), (-half_l, half_w), ( half_l, half_w), ] # 在顶面打孔 plate ( plate.faces(Z) .workplane() .pushPoints(centers) .hole(hole_dia) ) return plate if __name__ __main__: part make_plate(50, 30, 5, 4, 6) cq.exporters.export(part, plate.step) print(导出完成plate.step)这段代码有几个细节值得说。faces(Z)是选中朝上的那个面作为工作平面pushPoints把之前算好的坐标批量投上去hole一次性打穿。这种先算坐标、再批量操作的写法比一个个孔单独画要稳得多也更容易参数化。3.3 参数校验别让错误参数悄悄生成废模型脚本能跑通不代表结果是对的。我踩过最典型的坑是参数之间互相矛盾程序照样生成了一个看起来正常的模型但尺寸完全不对。比如孔偏移量比板的一半还大孔就跑到板外面去了程序不报错模型却是废的。所以生成之前一定要加校验。我一般会写一个validate函数把物理上不合理的组合挡在前面def validate(params): assert params[hole_offset] params[length] / 2, 孔偏移超出板长 assert params[hole_offset] params[width] / 2, 孔偏移超出板宽 assert params[hole_dia] params[thickness] * 4, 孔径相对板厚过大 assert params[thickness] 0, 板厚必须为正这些断言看着啰嗦但能省下大量生成了才发现不对的时间。尤其是批量生成的时候一个坏参数混进去可能污染整批输出。把校验做在生成之前是参数化管线的基本纪律。3.4 批量生成与命名规范批量生成时命名混乱是另一个高频问题。我见过有人生成一百个 STEP 文件全叫part.step、part(1).step最后根本分不清哪个对应哪组参数。正确的做法是把关键参数编进文件名比如def build_filename(params): return fplate_L{params[length]}_W{params[width]}_T{params[thickness]}.step这样文件名本身就是一份参数记录回溯的时候一目了然。如果参数很多可以只取几个关键维度或者额外导出一份 CSV 记录每组参数和对应文件名。这个习惯在项目后期会救你很多次。4. 从几何到 URDF机器人场景下的额外功课4.1 URDF 要的不只是形状如果你做的是机器人方向text-to-cad 的终点往往不是 STEP而是 URDF。这里有个认知差CAD 关心的是零件长什么样URDF 关心的是机器人怎么动。所以从几何转 URDF必须补上三类信息。第一类是连杆划分。一个机器人由若干连杆link和关节joint组成你得决定哪些几何属于同一个连杆。这个划分不是几何问题而是运动学问题——同一个连杆上的零件之间没有相对运动不同连杆之间通过关节连接。第二类是关节定义。关节类型旋转、平移、固定、旋转轴方向、运动范围这些都要明确。URDF 里一个旋转关节大概长这样joint namejoint1 typerevolute parent linkbase_link/ child linkarm_link/ origin xyz0 0 0.1 rpy0 0 0/ axis xyz0 0 1/ limit lower-1.57 upper1.57 effort10 velocity1.0/ /jointorigin决定关节在父连杆坐标系里的位置axis决定绕哪个轴转limit决定运动范围。这些参数在纯几何模型里是没有的必须人工或按规则补上。第三类是质量与惯性。URDF 的每个 link 都要有inertial块包含质量和惯性张量。质量可以从几何体积乘密度估算惯性张量则和形状、质量分布有关。很多从 CAD 直接导出的 URDF 之所以仿真时表现诡异就是因为惯性参数是瞎填的。4.2 导入仿真环境时的常见问题URDF 做好之后通常要导入机器人仿真环境验证。这一步的坑主要集中在坐标系和单位上。CAD 里常用的单位是毫米而 URDF 和多数仿真环境默认用米。如果你直接把毫米数值填进 URDF机器人会瞬间变成一千倍大小看起来像一座山。我的做法是在导出前统一做单位换算把所有长度除以 1000。另外CAD 里零件的坐标系原点和 URDF 里 link 的坐标系原点往往不一致需要显式设置origin的偏移。这个偏移量算错机器人装配起来就会错位关节转起来像脱臼。还有一个容易被忽略的点碰撞体collision和视觉体visual可以分开定义。视觉体用精细网格碰撞体用简化几何比如包围盒或圆柱这样仿真计算量会小很多。如果两者都用高精度网格仿真会卡到怀疑人生。4.3 一个实用的转换流程我现在的流程大致是这样先用参数化脚本生成每个连杆的 STEP再写一个转换脚本把 STEP 读进来、算质量属性、按预定义的关节关系拼成 URDF。质量属性这块CadQuery 和 FreeCAD 都能直接算体积和重心乘上密度就是质量惯性张量也能一并导出。# 伪代码示意从几何算质量属性 volume shape.Volume() # 单位取决于建模单位 mass volume * density # 密度按材料给 com shape.Center() # 重心 # 惯性张量通过几何内核的惯性计算接口获取这里要提醒一句密度单位要和长度单位匹配。如果你建模用毫米密度就得用吨每立方毫米这种别扭的单位否则质量会差好几个数量级。我一般干脆在建模阶段就用米省得来回换算。5. 踩过的坑那些文档里不会写的教训5.1 单位不统一是万恶之源前面提过单位问题但它的严重程度值得单独拎出来说。我做过一个项目几何用毫米建模导出 STEP 没问题但转 URDF 时忘了换算结果仿真里机器人有几百米高调了半天才发现是单位。更隐蔽的是混合单位有的零件用毫米有的用米拼在一起表面看不出来一装配就错位。我的应对办法是在管线入口就锁定单位所有参数、所有中间计算、所有输出统一用一种单位并在代码里写死注释。宁可多写一行注释也不要靠记忆。5.2 浮点误差导致的面不闭合参数化生成复杂几何时偶尔会遇到导出的 STEP 在某些软件里打不开提示面不闭合或实体无效。这通常是浮点误差累积导致的——两个本该重合的顶点差了 1e-9几何内核就认为它们不是同一个点。解决办法有两个方向一是在生成时留出合理的容差不要让特征之间刚好相切或刚好重合到极限二是导出前做一次几何修复很多内核都提供fix或heal接口。我一般会在导出前跑一遍有效性检查把有问题的模型挑出来单独处理而不是等下游报错。5.3 参数化不等于什么都能参数化刚接触这套方法时我一度想把所有东西都参数化结果发现有些几何特征天生不适合。比如自由曲面、复杂的过渡圆角、依赖大量人工审美的造型硬要参数化反而会让脚本变得极其臃肿维护成本超过手工建模。后来我想明白了参数化适合规则化、重复性高的结构比如板、轴、支架、法兰、标准件。对于这些脚本生成又快又稳。对于高度不规则的东西老老实实手工建模或者用脚本生成基础形状再手工微调反而更高效。认清边界比强行全能更重要。5.4 版本与依赖管理参数化脚本依赖几何库而几何库的版本更新有时会改变 API 行为。我遇到过升级库之后原本能跑的脚本报错或者生成的几何微妙地变了。所以锁定依赖版本很重要用虚拟环境或者依赖清单把版本固定下来。另外脚本本身也要做版本管理因为参数化模型的可复现性完全依赖脚本——脚本丢了或者改了同样的参数就再也生成不出同样的模型。6. 把 text-to-cad 用顺手的几个实践建议6.1 从半自动开始别追求全自动很多人一上来就想做输入一句话输出完整模型的全自动系统结果卡在自然语言理解的模糊性上。我的建议是先做半自动人负责把需求整理成结构化参数程序负责从参数生成几何。这个阶段先把几何生成的稳定性和准确性做扎实等这套跑顺了再考虑往上加自然语言解析。半自动的好处是可控。参数是人给的出了问题能快速定位是参数错还是生成逻辑错。全自动的话一句话进来中间黑盒一大段出错都不知道从哪查。6.2 建立参数模板库做久了你会发现很多需求是重复的。今天要一块带孔板明天要一块带槽板结构大同小异。这时候建一个参数模板库就很有价值把常见结构写成可复用的函数新需求来了直接调只改参数不改逻辑。# 模板库示意 def plate_with_holes(length, width, thickness, holes): ... def shaft_with_steps(steps): ... def flange(outer_dia, inner_dia, bolt_count, bolt_circle_dia): ...模板库积累起来之后生成新零件的速度会快一个量级。而且模板经过多次使用和验证稳定性也比临时写的脚本高。6.3 输出前一定要可视化检查程序说导出成功不等于模型是对的。我养成的习惯是每批生成之后随机抽几个模型在查看器里打开看一眼。有时候参数算错了模型形状会很奇怪肉眼一看就知道。这一步花不了几分钟但能挡住很多低级错误。如果批量很大可以写个脚本自动生成缩略图或者投影视图快速扫一遍。自动化生成 人工抽检是目前我觉得最稳的组合。6.4 关于格式转换的取舍STEP、URDF、G-code 之间的转换不是无损的。STEP 转 URDF 会丢精度、要补质量属性STEP 转 G-code 要经过切片或刀路规划几何会被离散化。所以尽量在源头就把目标格式想清楚需要什么就生成什么减少中间转换环节。转换次数越多出错和失真的机会越大。如果确实需要多格式输出建议以 STEP 作为母版其他格式都从 STEP 派生而不是在派生格式之间互相转。这样至少保证几何源头是统一的。6.5 文档和注释别省参数化脚本最怕的是三个月后自己都看不懂。每个函数干什么、每个参数什么含义、单位是什么、有什么约束都值得写清楚。我现在写这类脚本函数头注释和参数说明是标配关键计算步骤也会加注释。当时多写两行后面省下的时间是以小时计的。说到底text-to-cad 这套东西的门槛不在某个高深算法而在于把模糊需求翻译成精确参数、把精确参数稳定地变成几何、再把几何准确地交给下游这一整条链路的工程化。每一环都不难难的是每一环都不出错、可复现、能维护。我自己的体会是先把一个简单零件从文本参数到 STEP 的链路跑通再逐步加复杂度比一上来就搭大框架要靠谱得多。等你把这条链路走顺了回头再看那些AI 自动画图的宣传心里就有数了——真正值钱的从来不是那句描述而是描述背后那套严谨的几何逻辑。