ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

text-to-cad 实战:从自然语言到三维模型的技术链路与落地指南

text-to-cad 实战:从自然语言到三维模型的技术链路与落地指南 1. 从一句话到三维实体text-to-cad 到底在解决什么问题第一次听到 text-to-cad 这个词很多做机械设计或者工业软件的朋友第一反应是又一个蹭大模型热度的概念。但如果你真的在产线或者研发部门待过就会明白这个方向背后压着多大的痛点。传统 CAD 建模的流程是这样的工程师脑子里有一个零件的形状然后打开 SolidWorks、中望 CAD 或者 FreeCAD用草图、拉伸、旋转、布尔运算一步步把脑子里的东西翻译成软件能理解的几何体。这个翻译过程极其耗时一个中等复杂度的支架零件熟练工程师也要画上大半天而且改一个尺寸往往要重新走一遍特征树。text-to-cad 想做的事情就是把这个人脑到软件的翻译环节换成自然语言到几何体的直接映射。你用中文或者英文描述一个长 80 毫米、宽 40 毫米、厚 5 毫米的矩形板四角各有一个直径 6 毫米的圆孔孔中心距边缘 10 毫米系统直接吐出一个可以导出为 STEP 或者 STL 的三维模型。这件事听起来简单做起来涉及自然语言理解、参数化几何生成、特征约束求解、格式转换等一整条链路任何一个环节掉链子出来的模型就是废的。我之所以对这个方向感兴趣是因为在实际工作中见过太多重复建模的浪费。很多中小型制造企业产品系列化程度很高A 型号和 B 型号的零件可能只差几个孔位或者一段长度但每次都要从头画。如果有一个可靠的 text-to-cad 工具把常用零件做成语言模板改几个参数就能生成新模型效率提升是肉眼可见的。这篇文章不打算空谈概念而是从实际可落地的角度把 text-to-cad 涉及的核心技术点、常见实现路径、STEP 与 URDF 等格式的转换细节、以及我在折腾过程中踩过的坑一条条拆开讲清楚。需要先说明的是text-to-cad 目前并不是一个开箱即用的成熟产品它更像是一个技术方向市面上有零散的开源项目和商业尝试但离工业级可靠还有距离。所以这篇文章的定位是给想自己动手做原型、或者想评估这个方向可行性的工程师提供一份基于实际实践的参考。如果你只是想找一个现成软件点两下就出图那可能会失望但如果你想搞清楚背后的原理并自己搭一个能跑的小系统下面的内容应该对你有用。2. 自然语言到几何体核心链路的技术拆解2.1 语言解析层把人话变成结构化参数text-to-cad 的第一道关卡是把用户输入的自然语言解析成机器能处理的参数结构。这一步的难点不在于理解中文而在于理解工程语义。举个例子一个直径 20 的圆盘中间开一个 8 的孔人类一看就懂但机器需要提取出基体是圆柱直径 20高度未指定需要默认值特征是中心通孔直径 8孔的位置是同心。这里涉及实体识别、尺寸抽取、空间关系推理三个子任务。实际实现中比较务实的做法是模板匹配 大模型兜底的混合方案。纯靠大模型做端到端解析在简单描述上表现不错但一旦描述里出现倒角沉头孔阵列这类专业术语或者出现在左侧面偏上位置这种模糊空间指代大模型就容易胡编。我试过用通用大模型直接解析工程描述十次里有三次会把沉头孔理解成普通圆孔把均布理解成随便放几个。所以更稳的思路是先定义一套覆盖常见特征的语法模板用规则或者小模型做第一层匹配匹配不上的再交给大模型并且对大模型的输出做严格的参数校验。参数校验这一步很多人会忽略但它极其重要。比如用户说一个半径 5 的圆解析出来半径是 5但单位是什么毫米还是厘米如果系统默认毫米而用户心里想的是厘米出来的模型尺寸差十倍。我的做法是在解析层强制要求单位归一化所有长度统一转成毫米并且在输出前做一次范围检查——如果一个螺丝孔解析出来直径是 500 毫米那肯定是哪里错了直接报错让用户确认而不是闷头生成一个荒谬的模型。2.2 几何生成层参数化建模与特征树重建拿到结构化参数之后下一步是生成几何体。这里有两种主流路线一种是直接生成边界表示B-rep另一种是生成参数化特征树再求值。前者速度快但难以修改后者灵活但实现复杂。对于 text-to-cad 场景我强烈建议走参数化特征树路线因为用户改需求是常态如果每次改一个尺寸都要重新生成整个 B-rep系统响应会很难看。参数化特征树的本质是把建模过程记录成一串有序的操作先画草图再拉伸再打孔再倒角。每个操作带一组参数参数之间可以有依赖关系。比如孔的位置依赖于板的边缘那么板的长宽一变孔的位置自动跟着变。这种依赖关系用有向无环图DAG来表达最自然每个特征是一个节点节点之间的连线表示参数引用。实际写代码的时候我推荐用 Python 的 CadQuery 或者 build123d 作为几何内核。CadQuery 基于 OpenCASCADEAPI 设计得比较符合工程师直觉而且天然支持参数化。比如生成一个带孔矩形板代码大概长这样import cadquery as cq length 80.0 width 40.0 thickness 5.0 hole_dia 6.0 edge_offset 10.0 result ( cq.Workplane(XY) .box(length, width, thickness) .faces(Z) .workplane() .rect(length - 2*edge_offset, width - 2*edge_offset, forConstructionTrue) .vertices() .hole(hole_dia) ) cq.exporters.export(result, plate.step)这段代码里forConstructionTrue的矩形不参与实体运算只用来定位四个顶点然后在顶点上打孔。这种构造几何的用法在参数化建模里非常常见比手动算四个孔的坐标要清晰得多而且板的长宽一变孔位自动跟着调整不需要改任何坐标数字。2.3 格式输出层STEP、STL、URDF 各自的使用场景模型生成出来之后要导出成什么格式取决于下游用途。这是很多人容易搞混的地方我见过有人拿 STL 去做装配仿真结果发现模型是一堆三角面片根本没法选中一个面来施加约束。所以这里把几种常见格式的适用场景说清楚。格式本质适用场景不适用场景STEPB-rep 精确几何跨软件交换、CAM 加工、装配网页轻量预览STL三角网格3D 打印、快速渲染精确尺寸标注、特征编辑URDFXML 描述的机器人模型机器人仿真、运动学通用机械零件交换G-code数控加工指令CNC 机床加工任何设计环节STEP 是 text-to-cad 最应该优先支持的输出格式因为它是工业界事实上的交换标准SolidWorks、中望 CAD、FreeCAD 都能读而且保留精确的曲面和边信息。STL 适合做快速预览或者 3D 打印但它是网格化的一个圆柱面会被离散成很多小三角片尺寸精度取决于离散精度设置。URDF 比较特殊它是给机器人仿真用的描述的是连杆和关节的连接关系不是单纯的零件几何。如果你做的是机械臂或者移动机器人相关的 text-to-cadURDF 输出就很重要因为仿真环境比如 CoppeliaSim需要 URDF 来构建运动学模型。G-code 则是另一个维度的事情它是加工指令不是设计模型。text-to-cad 生成模型之后理论上可以接一个 CAM 模块生成 G-code但这已经超出文本到 CAD的范畴了属于文本到制造的更大链路。实际项目中我建议把 G-code 生成作为独立的下游环节不要和几何生成耦合在一起否则系统会变得又大又难维护。3. 动手搭一个最小可用的 text-to-cad 原型3.1 环境准备与依赖选择要自己搭一个能跑的原型环境准备这一步就有讲究。核心依赖是几何内核我选 CadQuery因为它对 Python 友好文档也还算全。安装的时候有个坑CadQuery 依赖 OpenCASCADE 的 Python 绑定OCP这个包体积很大而且不同版本的 CadQuery 对 OCP 版本有严格要求。我建议直接用 conda 装比 pip 省心很多conda create -n text2cad python3.10 conda activate text2cad conda install -c conda-forge cadquery用 conda 的好处是它会自动解决 OCP 的二进制依赖pip 装的话在有些系统上会因为缺少系统库而编译失败。如果你非要用 pip记得先装好系统级的 OpenCASCADE 开发库具体包名因操作系统而异这里不展开。语言解析层我建议先用规则做不要一上来就上大模型。规则解析虽然笨但可控、可调试、出错能定位。等规则覆盖了八成常见描述之后再考虑用大模型处理剩下的长尾。规则解析可以用正则加关键词匹配比如识别直径后面跟的数字作为孔径识别长宽厚后面的数字作为尺寸。这种土办法在垂直场景下出奇地好用因为工程描述的语言其实相当规范不像日常聊天那么天马行空。3.2 从描述到参数结构的解析实现假设我们要支持一类最简单的零件带孔的矩形板。用户可能这样说一块 100 乘 50 的板厚 8四个角打 5 个的孔孔离边 12。我们需要从中提取长 100、宽 50、厚 8、孔径 5、边距 12、孔数 4。规则解析的思路是先做分词和数字抽取再做语义槽填充。数字抽取用正则\d(\.\d)?就能搞定难的是把数字和槽位对应起来。我的做法是定义一组锚点词比如长乘宽厚直径孔边然后看每个数字前后最近的锚点词是什么。上面那句话里100 前面是一块后面是乘所以它大概率是长度50 前面是乘后面是的板所以是宽度。这种基于上下文窗口的匹配在句式规整的情况下准确率很高。槽位填充完之后还要做一次完整性检查。如果用户没说厚度系统得有个默认值或者明确追问。我倾向于给一个保守的默认值比如 5 毫米并在输出里标注厚度未指定已使用默认值 5 毫米让用户知道哪里是系统猜的。这种透明性很重要否则用户拿到一个尺寸不对的模型会以为系统坏了其实是自己没说清楚。3.3 几何生成与 STEP 导出的完整代码把解析出来的参数喂给 CadQuery生成模型并导出 STEP这一步的代码前面已经给过片段这里补一个更完整的版本加上错误处理和参数校验import cadquery as cq from cadquery import exporters def build_plate(length, width, thickness, hole_dia, edge_offset): if length 2 * edge_offset or width 2 * edge_offset: raise ValueError(边距过大孔会超出板的范围) if hole_dia 0 or thickness 0: raise ValueError(孔径和厚度必须为正数) result ( cq.Workplane(XY) .box(length, width, thickness) .faces(Z) .workplane() .rect(length - 2*edge_offset, width - 2*edge_offset, forConstructionTrue) .vertices() .hole(hole_dia) ) return result def export_step(model, filepath): exporters.export(model, filepath) print(f已导出: {filepath}) if __name__ __main__: plate build_plate(100, 50, 8, 5, 12) export_step(plate, output_plate.step)这段代码里build_plate开头的校验很关键。我踩过一次坑用户说板 20 乘 20孔离边 15边距 15 意味着孔中心在距边 15 的位置但板半宽才 10孔直接跑到板外面去了。CadQuery 不会报错它会老老实实生成一个孔在实体外面的模型导出 STEP 之后打开一看孔是悬空的。所以几何参数之间的约束关系必须在生成前检查不能指望几何内核帮你兜底。3.4 实测中遇到的三个意外情况第一个意外是浮点数精度问题。CadQuery 内部用浮点数表示尺寸当两个面理论上应该重合时实际可能有 1e-10 级别的偏差导致布尔运算失败或者生成一个极薄的缝隙。解决办法是在关键运算前做一次吸附把接近零的坐标强制归零或者用 CadQuery 提供的clean()方法清理模型。这个问题在简单模型上不明显一旦模型复杂起来缝隙会导致后续装配约束全部失效。第二个意外是中文单位混用。用户有时候说5 个的孔意思是直径 5 毫米有时候说5 厘米的板那就是 50 毫米。规则解析如果只抓数字不抓单位就会把两者搞混。我的处理方式是维护一个单位词典识别到厘米公分就乘 10识别到米就乘 1000没识别到单位就默认毫米。这个逻辑虽然简单但能避免大量低级错误。第三个意外是导出 STEP 之后的兼容性。CadQuery 导出的 STEP 在 FreeCAD 里打开正常但在某些版本的 SolidWorks 里会提示曲面质量警告。原因是不同软件对 STEP 的容差设置不同。解决办法是在导出时显式指定容差参数或者导出后用中间软件转一道。这个问题没有银弹只能在实际目标软件上测试确认没问题再交付。4. URDF 与机器人仿真text-to-cad 的另一个战场4.1 URDF 描述的不是零件而是连接关系很多人第一次接触 URDF 会困惑为什么我导出的模型在 CoppeliaSim 里是一堆散件动不起来因为 URDF 描述的核心不是几何形状而是连杆link和关节joint的拓扑关系。一个机械臂的 URDF 文件里每个连杆有自己的几何和惯性参数每个关节定义了父子连杆之间的运动类型旋转、平移、固定和运动轴。如果你只把零件几何塞进 URDF 而不定义关节仿真环境就不知道这些零件之间怎么连接自然动不起来。text-to-cad 在这个场景下的价值是让用户用自然语言描述机器人的结构比如一个两连杆机械臂第一段长 200第二段长 150关节都是旋转关节绕 Z 轴转动系统自动生成对应的 URDF。这比手写 URDF 文件要直观得多因为 URDF 的 XML 语法相当啰嗦一个简单的两连杆臂写下来也要上百行。4.2 从 CAD 模型到 URDF 的转换要点如果你已经有 CAD 模型想转成 URDF有几个关键点要注意。首先是坐标系对齐CAD 软件里每个零件有自己的局部坐标系URDF 要求每个连杆的坐标系原点通常在关节处转换时需要做坐标变换。其次是惯性参数URDF 需要每个连杆的质量和惯性张量CAD 模型如果没指定材料密度这些参数是缺失的需要手动补或者用估算值。第三是碰撞体URDF 可以给每个连杆指定一个简化的碰撞几何通常是包围盒或圆柱用于物理仿真这个和视觉几何是分开的需要单独设置。实际转换时我建议先用 CAD 软件把每个连杆导出成独立的 STL 或 STEP然后在 URDF 里用visual标签引用视觉模型用collision标签引用简化碰撞体。CoppeliaSim 导入 URDF 的时候如果碰撞体设置得太复杂仿真会非常慢所以碰撞体一定要简化。我见过有人直接把高精度 STL 当碰撞体用结果仿真跑起来像幻灯片一帧要算好几秒。4.3 在 CoppeliaSim 中验证 URDF 的实操步骤CoppeliaSim 导入 URDF 的流程不算复杂但有几个细节容易出错。第一步是确保 URDF 文件里引用的网格文件路径正确CoppeliaSim 对相对路径的处理和某些工具不一样建议用绝对路径或者把网格文件和 URDF 放在同一目录下用相对路径。第二步是导入后检查关节的运动范围URDF 里如果没指定关节限位CoppeliaSim 默认可能是无限旋转实际机器人不可能无限转所以要手动加上下限。第三步是测试正运动学给每个关节一个已知角度看末端执行器的位置是否符合预期这一步能发现坐标系定义错误。我踩过的一个坑是关节轴向搞反了。URDF 里关节轴用axis xyz0 0 1/表示绕 Z 轴但 CAD 模型导出时如果坐标系旋转过实际轴向可能变成 Y 轴。结果就是仿真里关节转动的方向和预期垂直看起来像在扭麻花。解决办法是在 CAD 里导出前就把坐标系摆正或者在 URDF 里调整 axis 向量后者更灵活但需要反复试。5. 那些没人告诉你但一定会踩的坑5.1 单位、精度与容差的隐形陷阱单位问题前面提过但它的严重性值得单独再说一次。text-to-cad 系统里单位错误是最隐蔽也最致命的 bug。因为模型生成出来看起来形状是对的只是尺寸差了一个数量级如果不做尺寸校验很可能一路错到导出、到仿真、到加工才发现。我的做法是在系统里设置一个合理尺寸范围检查比如机械零件的尺寸通常在 0.1 毫米到 10 米之间超出这个范围的参数直接报警。这个检查虽然粗暴但能拦住九成以上的单位错误。精度问题则更微妙。CAD 内核用浮点数浮点数有精度极限。当模型尺寸很小比如微米级或者很大比如百米级时布尔运算的容差设置如果不当会出现面片丢失或者自相交。OpenCASCADE 默认容差是 1e-7 米也就是 0.1 微米对于大多数机械零件够用但对于精密光学零件可能不够。如果发现生成的模型有莫名其妙的破面可以尝试调整容差参数但调太小会导致运算变慢甚至失败需要权衡。5.2 大模型解析的幻觉与兜底策略用大模型做语言解析最大的风险是幻觉——它会自信地编造出用户根本没说的参数。比如用户说一个圆盘大模型可能自作主张补上直径 100 毫米因为它训练数据里圆盘经常是 100 毫米。这种补全在聊天场景下无伤大雅在 CAD 场景下就是灾难因为用户拿到一个尺寸不对的模型可能直接拿去加工了。我的兜底策略是宁可追问不可乱猜。解析结果里凡是用户没明确说的参数一律标记为未指定然后要么用保守默认值并明确标注要么直接追问用户。追问虽然多一轮交互但比生成错误模型要好。另外大模型的输出必须经过规则校验比如解析出的孔径如果是负数或者零直接拒绝不要试图修正因为那说明解析本身出了问题。5.3 导出格式的兼容性血泪史STEP 的兼容性问题我前面提过这里补充一个更具体的案例。CadQuery 导出的 STEP 文件在 FreeCAD 里打开正常在中望 CAD 里打开也正常但在某个版本的 SolidWorks 里圆柱面会变成多边形近似。排查后发现是 STEP 文件里的AP203和AP214协议差异导致的。AP214 对颜色和层的信息支持更好AP203 更纯粹但某些软件解析时会把曲面离散化。解决办法是导出时显式指定协议版本CadQuery 的 exporter 支持传参具体参数名查一下文档就行。STL 的问题则是精度和文件大小的权衡。STL 用三角面片逼近曲面逼近精度越高面片越多文件越大。一个直径 100 毫米的圆柱如果弦高容差设成 0.01 毫米可能要几千个三角面片设成 0.1 毫米几百个就够了但表面看起来会有明显棱角。3D 打印通常用 0.05 到 0.1 毫米的弦高容差视觉预览可以用更粗的。这个参数在导出时一定要暴露给用户不要写死。6. 这套东西到底能用在哪些实际场景6.1 系列化零件的快速变型设计这是 text-to-cad 最直接的价值场景。很多制造企业的产品是系列化的比如不同规格的法兰盘、不同长度的轴、不同孔位的安装板。这些零件的几何结构高度相似只是参数不同。传统做法是做一个模板文件每次改参数重新生成但模板文件的维护本身就很麻烦而且不是所有人都会用 CAD 的参数化功能。用 text-to-cad 的思路可以把每个系列做成一个语言模板用户只需要说法兰盘 DN50PN164 个螺栓孔系统就生成对应的模型。这里的DN50PN16是行业标准代号系统内部维护一个代号到参数的映射表。这种场景下语言解析的难度其实很低因为用户输入高度规范化真正的价值在于把标准参数库和几何生成打通。我见过一个做管道配件的团队用这套思路把常用件的建模时间从平均 20 分钟压缩到 30 秒以内。6.2 教学与快速原型验证在教学场景下text-to-cad 能让学生把注意力放在设计思维上而不是软件操作上。初学者学 CAD大量时间花在找菜单、记快捷键、处理报错上真正思考这个零件该怎么设计的时间反而很少。如果有一个 text-to-cad 工具学生描述自己的设计意图系统生成模型学生可以快速看到结果并迭代学习曲线会平缓很多。快速原型验证也是类似逻辑。硬件工程师在概念阶段经常需要快速出一个模型来评估尺寸和装配关系这时候不需要精确的工程图只需要一个能看能量的三维模型。text-to-cad 在这个阶段的速度优势很明显改一个描述就能重新生成比在 CAD 里改特征树快得多。当然到了详细设计阶段还是得回到专业 CAD 软件text-to-cad 目前还替代不了精细的工程标注和公差设计。6.3 机器人与自动化仿真的模型准备做机器人仿真的团队经常需要大量环境模型比如传送带、料框、夹具。这些模型不需要高精度但需要能快速生成并导入仿真环境。text-to-cad 可以批量生成这类模型比如一个 500 乘 300 的传送带高 200两端有直径 50 的滚筒几秒钟就能出一个 URDF 或者 STL直接拖进 CoppeliaSim 用。这比去模型库下载再调整尺寸要快得多而且尺寸完全可控。这个场景下输出格式的选择很关键。如果只是做视觉占位STL 就够了如果需要参与物理仿真就要考虑碰撞体和惯性参数。我的建议是给这类环境模型做一个简化模板碰撞体统一用包围盒惯性参数用均匀密度估算牺牲一点精度换仿真速度。实际项目里仿真速度往往比模型精度更重要一个跑不动的仿真再精确也没用。7. 我对这个方向的一些个人判断折腾 text-to-cad 这段时间我最大的体会是这个方向的技术难点不在生成几何而在理解意图。几何生成有成熟的内核可以用CadQuery、OpenCASCADE 都很稳但把一句模糊的自然语言准确映射成一组无歧义的几何参数这件事目前还没有特别优雅的解法。规则解析覆盖率高但不够灵活大模型灵活但不可控混合方案是目前最务实的但工程复杂度不低。另一个体会是text-to-cad 短期内不会取代传统 CAD它更像是 CAD 的一个前置入口。用户用自然语言快速表达意图系统生成一个粗糙的初始模型然后用户在传统 CAD 里做精细调整。这个定位比较现实也更容易落地。指望一句话生成一个可以直接加工的复杂零件目前还不现实因为加工需要考虑的东西公差、材料、工艺远超几何本身。最后分享一个实操小技巧如果你要评估一个 text-to-cad 方案好不好用不要拿简单零件测直接拿你工作中最常画的那个烦人零件去测。简单零件什么方案都能跑通真正能区分方案优劣的是那些有复杂特征、有参数依赖、有行业术语的零件。我当初就是用一个带沉头孔和阵列的安装板去测一下子就把几个方案的短板暴露出来了。这个测试方法虽然费点时间但比看任何宣传材料都管用。
返回列表