多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

从一句话到参数化CAD模型:text-to-cad实现方法与系统解析

从一句话到参数化CAD模型:text-to-cad实现方法与系统解析 这几年 AI 生成图片、生成代码早就不新鲜了但你要是跟搞机械、搞建筑、搞工业设计的朋友聊起来会发现大家都在盯一个更硬核的方向直接把一句大白话变成一张能用的 CAD 模型。这个方向社区里习惯叫它text-to-cad。听起来像是把给我画一个直径 20 的法兰盘扔进软件下一秒就自动建模了。实际做起来远没有这么浪漫但也正因为没那么简单这件事才真正值得认真拆一回。我花了大概三周时间从零搭了一个 text-to-cad 的模拟项目X目标特别朴素让用户输入一句话自动生成可编辑的参数化三维模型并导出为标准格式。整个过程踩了无数坑也搞明白了很多原来只是知道概念的东西这篇就完整记录一下我的实现思路、核心环节和排查心得。1. 整体设计为什么 text-to-cad 比想象中难以及怎么拆解它1.1 先想清楚text-to-cad到底在解决谁的什么问题先说定位。text-to-cad 不是一个凭空造出来的玩具方向它解决的是 CAD 建模里一个非常真实的效率痛点。传统 CAD 建模流程本质是人用鼠标和键盘把几何意图翻译成命令。你要画一个轴承座脑子里先有三维结构再拆成拉伸、切除、倒角、打孔这一系列特征操作每一步都要在软件界面里找命令、点坐标、填参数。这套流程最大的问题不是慢而是意图和表达之间的鸿沟——你想的是这里开四个均布的螺栓孔但软件听不懂这句话你只能一步步告诉它选面、建草图、画圆、定义阵列、指定数量、确定深度。text-to-cad 尝试把这层鸿沟填平一部分用户直接说四个均布的螺栓孔系统自动把它转成对应的建模操作。这对谁最有用两类人。第一类是 CAD 老手他们在方案设计阶段需要快速验证多个结构想法与其逐一建模不如先自然语言出几个粗略模型比选第二类是根本没系统学过 CAD 的工程师或产品经理他们懂需求、懂结构逻辑但卡在软件操作上如果一句话就能出基础体量后续再交给专业人员微调整体协作效率能提升不少。所以我在设计模拟项目X的时候没有贪多求大而是把目标收敛成三件事文本里出现明确的结构类型我能生成出现明确的关键尺寸我能正确使用生成的模型可以反回软件编辑而不是一堆不能参数化的死几何。这三点听起来不难实现起来各有各的坑。1.2 技术路线选型为什么最终选了文本到参数化特征树而非文本直接生成网格这里有个特别关键的路口决定整个项目的走向拿到文本之后是让 AI 直接输出一个网格模型mesh还是输出一个参数化建模的操作序列我先说直接生成网格的思路。好处是省事深度学习模型比如一些 3D 生成模型可以吃文本描述吐出体素或点云再转成网格。坏处非常致命生成结果不可编辑、不可参数化。CAD 行业的模型是要改的孔径要改、板厚要调、特征要删你给设计师一个定死的三角网格他只能叹气。用我同事的话说你这等于给我发了一张 JPG我要的是 PSD。这话糙理不糙CAD 模型的灵魂是特征树是参数不是表面形状。所以模拟项目X最终选了另一条路文本解析 参数化模板映射 几何内核重建。系统先把自然语言拆解成语义结构识别出法兰盘螺栓孔直径均布这类实体和属性然后映射到预先定义好的参数化模板上最后调用 CAD 内核的 API 完成建模。AI 在这里扮演的角色是解析器不是直接生成器。这样做有四个明显好处。第一输出的模型天然是参数化的用户拿到手可以改任何一个尺寸特征树干净可读。第二因为几何是由模板驱动的尺寸精度有保障不会出现20mm 的孔实际是 19.83mm这种魔幻问题。第三模板可以不断增加每新增一种结构类型系统能力就扩展一块可维护性比端到端黑盒强得多。第四也是我后来才体会到的这种架构让错误排查变得容易——文本解析错了、参数提取错了、建模失败各层都是独立的直接定位就行。这个选型思路我建议每个做类似项目的人都认真想一遍。端到端生成看着酷但在 CAD 这种对精度、可编辑性要求极高的领域可解释 可干预远比一次生成重要。1.3 系统架构概览一条从一句话到一个模型的生产线整个系统可以拆成五个模块链路非常清晰输入与预处理模块接收用户输入的自然语言文本做长度限制、语言检测、术语标准化。比如用户写直径20mm和直径20毫米在这里统一成内部标准单位表示。核心语义解析模块这是脑负责从文本里抽取结构化信息——对象类型、主尺寸、辅助特征、约束关系。我基于规则 轻量模型混合实现后面细讲。参数与约束构建模块把解析结果整理成参数列表并做完整性检查。比如均布孔没有给数量会在这里标记为待补默认值。建模执行模块调用几何内核 API按参数顺序执行建模操作生成带特征树的模型实体。导出与校验模块把模型导出为 STEP/DXF/STL 等格式同时做体积、尺寸等物理量校验确认生成结果和输入描述一致。这五个模块串起来就像一条流水线文本进来先洗再拆再装配最后质检出场。任何一个环节出问题终端用户看到的都是生成的模型不对但只有分模块排查才知道问题出在没听懂话还是建模时参数错了。这个分层思维贯穿了整个项目也是我最想分享的架构经验。2. 核心细节解析让机器听懂人话里的几何2.1 语义解析别急着上大模型先做好规则和词典我做语义解析时犯的最大错误就是一开始就想直接用大语言模型把文本转成 JSON。想法很直接让模型输出{type: flange, diameter: 50, holes: 4}不就行了试了以后才发现在工程场景下大模型输出的 JSON 结构不稳定字段命名经常漂移尺寸单位偶尔会把厘米当毫米更头疼的是它会把法兰和法兰盘当成两种东西。后来我把方案改成了词典 规则 轻量模型兜底的三层结构。第一层是术语词典。我把机械设计和建筑里常见的结构词、特征词、尺寸词全部手工整理了一遍分门别类形状名词法兰、轴承座、支架、箱体、特征动词拉伸、切除、倒角、打孔、修饰形容词均布、对称、通孔、盲孔、尺寸单位mm、cm、m、inch。解析时先做词表匹配这一步能覆盖大概六成常见句式。第二层是句法规则。比如识别到直径/直径是/直径大小这类触发词就会向后寻找数值量词识别到均布这个修饰词就会继续寻找它修饰的孔特征和数量。规则不是正则表达式硬匹配那种脆弱的东西而是基于依存关系做的轻量模式匹配具体工具不限制思路就是优先保证高频句式的稳定解析。第三层才是轻量模型兜底。当词典和规则都覆盖不了比如用户说一个带四角安装孔的方形底座这种自由度很高的表达就用模型来做意图分类和槽位填充。我拿了几百条真实用户话术做了标注微调了一个很小的序列标注模型效果可以接受。这里最想强调的是语义解析环节稳定压倒一切。宁可让系统老实承认这句话我没听懂也比猜一个错误参数生成一个错误模型好得多。所以我在解析层加了一个置信度阈值低于阈值的直接转人工兜底话术绝不让错误解析结果流到建模环节。2.2 参数提取单位、精度和默认值的魔鬼细节解析出结构类型只是第一步真正让人头疼的是参数提取。CAD 模型是精确的参数错一个小数点模型就废了。这个环节我总结出四个必须处理的魔鬼细节。第一是单位统一。用户可能说 20mm、两厘米、0.02m、甚至一寸系统内部必须全部转成标准单位我是统一转成毫米。单位搞错是灾难级的一个把厘米当毫米的孔直接让整个零件大了十倍安装时才发现就晚了。我的做法是解析时就把量词标准化并在最终校验阶段重新核对原始文本里的数字和生成模型里的尺寸是否一致。第二是数值稳定性。用户写30405表示长宽高或者直径∅25这些特殊表达都要覆盖。我用了一套专门的数值抽取逻辑不只是抓数字还会往前看有没有乘号、直径符号、孔径标识。第三是默认值处理。不是所有用户都会把参数说全。比如只说给我一个法兰盘没说直径没说孔数怎么办我的策略是每个模板都有工业上合理的默认参数表缺省字段用默认值填充同时在生成报告里明确标出哪些参数是默认值请确认。这比报错强也比瞎猜强。第四是参数合法性校验。直径不能是负数板厚不能大于外径孔数必须是整数。这一步放在建模之前做能拦截掉大量无意义的建模失败。我做了一张参数约束表每个模板都自带校验规则比如diameter 0、thickness diameter、hole_count in [0, 4, 6, 8]这种。2.3 参数化模板把几何知识变成可复用代码如果说语义解析是理解层参数化模板就是生成层的核心资产。我把它理解成把几何知识变成代码。什么是参数化模板拿法兰盘举例它的几何结构是一个中心圆柱体中心开孔圆周上均布若干螺栓孔。这个结构不会因为尺寸变化而改变变的只是数值。所以我可以把它写成一个函数输入是外径、内径、厚度、孔数、孔径输出是建模 API 的调用序列。模板建立的过程本质是解构一个专业零件的几何生成逻辑。我需要把一个法兰盘拆解成圆柱基体 - 中心打孔 - 圆周阵列螺栓孔三个操作步骤再给每个步骤定义好输入输出关系。这需要一点 CAD 建模经验但也算不上高深关键是拆解的粒度要合适——太粗整个法兰盘一步生成会导致灵活性下降太细每个微小倒角都是独立参数会让用户输入负担过重。我第一批做了五个模板法兰盘、带孔方形底板、U 型支架、阶梯轴、轴承座。选这些不是因为简单而是它们覆盖了几种最常见的建模操作类型——拉伸、旋转、打孔、阵列、布尔运算。五个模板跑通之后我对整个系统的信心就建立起来了因为建模执行层是通用的换模板只是换参数和操作序列不需要改框架。2.4 约束与几何逻辑为什么间距均布不能靠除法解决做参数化模板时有个概念必须认真对待几何约束。这不是 CAD 术语里那个复杂的约束求解器而是建模逻辑上的一些潜在关系。举个具体例子四个孔均布在直径 100 的圆周上。这句话拆解出来的信息是孔数量4、分度圆直径100、布局方式均布。要生成正确的模型需要调用阵列函数让系统自动计算 4 个孔在 360° 圆周上的间隔角度。如果你自己用除法算 360/490°然后逐个画孔问题来了如果用户后续把孔数改成 6你就得手动重新算角度模型就死了。正确做法是创建阵列特征把数量和圆周绑定为参数让 CAD 内核自己去算。这就是我强调可编辑参数化模型时的实现基础——该用特征就用特征绝不落到死坐标上。再比如中心孔这种描述隐含的约束是孔的轴线和圆柱基体的轴线重合。建模时要捕捉到这种轴线对齐关系而不是靠计算坐标硬摆上去。这种隐含几何逻辑的识别是 text-to-cad 和简单文本转数字最大的区别——文字里一个中心背后是一整套约束关系。我建了一个关系映射表把常见方位词、布局词映射到对应的几何约束类型解析出中心就绑定同轴约束解析出均布就绑定圆周阵列关系。3. 实操过程与核心环节实现跑通一个完整的一句话建模3.1 文本预处理把用户的话洗成规范输入在真正开始解析之前文本预处理的质量直接决定后续所有环节。我的预处理管线有四个步骤。第一统一大小写和全半角。用户可能在手机输入法里打了全角的这是真实会发生的事。第二处理多语言混杂。中文环境里用户经常中英混打diameter是30的flange我把常见英文术语映射到中文标准词典上。第三归一化数字表达。三十30.03e1统一转成浮点数。第四术语标准化。法兰法兰盘flange统一映射到同一个内部 ID 上。这一步看起来不产直接价值但它极大降低了后续解析的复杂度。我大概花了 20% 的精力写了这些预处理规则却避免了 80% 的解析器明明看到数字了却没有正确处理的 bug。在 NLP 项目里最贵的往往不是模型是数据清洗和归一化。3.2 从文本到结构化数据一个完整例子走一遍我用一个具体例子把解析流程串起来。输入文本生成一个法兰盘外径 50内径 25厚度 8均布 4 个直径 6 的螺栓孔。预处理之后文本被清洗成标准表达。进入词典匹配后命中对象法兰盘映射到模板flange_template命中特征外径、内径、厚度命中布局词均布命中数量4命中孔径6。规则接着做槽位填充。外径 50、内径 25、厚度 8 分别填进主参数表。这里有个值得注意的细节用户没说单位我们按默认单位有毫米处理这个默认单位策略需要提前定好并在界面上向用户展示默认单位为毫米。均布 4 个直径 6 的螺栓孔被解析成一个子特征表{feature: bolts, count: 4, diameter: 6, layout: circular, bolt_circle_diameter: null}。注意这里分度圆直径bolt circle diameter是缺失的。我们的规则做了智能推断在法兰盘模板里如果用户没说分度圆直径默认取主外径和中心孔径的中点即 37.5。这个值既符合常见工程比例也在合法性校验范围内。最后生成的结构化数据大概是这样的{ object: flange, params: {outer_diameter: 50.0, inner_diameter: 25.0, thickness: 8.0}, features: [ {type: circular_hole_array, count: 4, hole_diameter: 6.0, pcd: 37.5, layout: evenly} ] }这套数据传到建模执行层调用法兰模板函数20 毫秒内生成一个带完整特征树的参数化模型。整个链路在这里第一次跑通的时候说实话还挺有成就感的因为它证明了文本 - 结构化语义 - 参数化几何这条路是走得通的。3.3 几何内核建模按操作序列生成特征树结构化数据出来了建模本身反而相对枯燥因为它就是把几何操作一条条执行下去。以刚才的法兰盘为例操作序列是创建一个圆柱体基体直径外径 50高度厚度 8。在基体中心创建一个贯通孔直径内径 25并使用同轴约束。创建一个草图圆直径分度圆直径 37.5然后在该圆上定义 4 个孔的位置。执行圆周阵列数量4角度360/4均布生成 4 个直径 6 的通孔。把阵列结果从基体中布尔减除。每一步都调用内核 API并确保返回的特征对象被记录。值得强调的是第 2 步和第 4 步不要通过计算坐标的方式硬生成孔的位置而要通过阵列特征和约束来定义。这样用户后续双击模型能直接看到这个孔阵列的数量是 4角度是 90°修改数量为 8模型会自动重新生成。这就是参数化灵魂所在。用生活类比解释就是你给邻居指路可以直接告诉他走到第三个红绿灯右转也可以说沿着这条路的第 3.7 公里处右转。后者虽然也能到但路修了、重新标里程之后就废了。CAD 建模同理用特征和约束建模模型才活。3.4 导出与校验生成完不算完得过了质检才能交付很多初做这类系统的人生成一个模型就宣布成功。实际上校验环节才是我这类项目最花时间的部分之一。我做了两种校验。第一是参数回读验证从生成的模型特征树里读回关键尺寸与输入文本里的数值逐一对比。外径是不是 50内径是不是 25孔数是不是 4这一步能捕获到语义解析正确但建模执行错误的场景比如按钮孔阵列误用了直角阵列而不是圆周阵列。第二是几何属性验证计算模型体积、包围盒尺寸、质心位置和理论值对比。法兰盘体积可以由圆柱体积公式估算如果实际体积偏差超过 1%说明有几何重叠或残留体需要检查布尔操作是否干净。这个验证法很朴素但每次都能力挽狂澜曾经就靠它发现了一个阵列参数没更新的 bug——修改孔数后体积没变属性校验立刻报警。校验通过后模型统一导出为 STEP 和 STL 两种格式。STEP 用于高级 CAD 软件打开保留特征树和参数信息STL 用于 3D 打印和可视化预览。同时我还会生成一份 HTML 格式的建模摘要列出用户原文、解析出的所有参数、被默认填充的字段以及模型的物理属性。这份摘要特别受欢迎因为用户能直观看到系统到底理解了哪些内容哪部分理解错了也一目了然。4. 常见问题与排查技巧实录那些让我加班到深夜的坑4.1 语义误解比模型生成失败更隐蔽做这个项目我发现最可怕的错误不是建模失败而是系统以为理解对了、其实理解错了。举例用户说在板上打一个孔系统如果把孔解析成圆角矩形生成的模型外观差不多但参数完全错位。这种错误在建模阶段不会报错只有到后续装配环节才会暴露而那时排查的代价已经很高了。我的解决方案有两个。第一解析结果可视化。把结构化 JSON 转换成人能读懂的自然语言概要反馈给用户确认比如识别为法兰盘外径 50mm内径 25mm均布 4 孔直径 6mm。请确认。用户点确认再建模。这个环节看着多了一步交互但实际体验提升非常明显因为它把系统可能猜错这个不确定性显式暴露给用户了。第二设置歧义探测规则。像孔这种过于宽泛的表达如果后续没有足够上下文限定就主动向用户提问您要的是什么类型的孔通孔、盲孔还是螺纹孔绝不瞎猜。4.2 尺寸单位与量纲的幽灵问题单位错误是我排查过最多、也最容易反复出现的问题。有个特别典型的场景用户输入架子长 2m宽 1m高 0.5m系统如果当时没识别到m为单位全部按毫米处理生成的架子尺寸差了 1000 倍。模型倒是生成成功了但完全不能用。后来我在解析层增加了双重校验机制数字抽取器在返回数值的同时返回原始文本片段参数校验阶段重新用正则扫描原始片段确认单位换算因子被正确应用。两步对照从机制上防止了单位漏判。另外还在输出摘要里专门显示换算结果2m - 2000mm让用户一眼看到系统有没有理解对单位。4.3 默认参数的隐藏风险让用户为系统的不确定买单默认值是双刃剑。用好了能让输入门槛降低用不好会让用户拿到看似可用实则错误的模型。我踩过最狼狈的一次坑是用户想生成一个支架没说明是否是左右对称件系统默认生成了不对称结构。用户拿模型去加工做出来一对左右手件直接废了两个零件。这次之后我定了一条原则涉及方向、镜像、阵列数量和材料厚度这类影响重大的参数不设置默认值必须显式确认。用户没说系统就提问用户说了系统就忠实执行。虽然多了一步交互但避免了一个零件废掉的重成本。辅助性参数比如倒角半径、默认单位可以用默认值关键结构参数必须显式。这条经验的价值远超我教条式写的所有代码。4.4 建模失败的奇奇怪怪原因与排查路径建模阶段最常见的报错有这么几类布尔运算失败、阵列生成异常、草图约束冲突。布尔运算失败多发生在孔和基体边缘相切时比如螺栓孔分度圆直径等于法兰外径减去孔径一半导致孔突破了外边界。阵列生成异常则常见于数量为 0、负数或过大。草图约束冲突则是因为模板内存在冗余约束比如既手动定义了圆心坐标又定义了同心约束。排查这类问题我的习惯是给建模执行模块加一层断点日志。每步操作执行前记录输入参数执行后记录输出结果失败时把当前的参数上下文完整 dump 出来。这套日志帮我快速定位了至少 70% 的建模失败问题。具体排查路径是先看是哪一步操作失败再看失败时参数值是否合法最后确认模板内约束是否冲突。三步走完绝大多数问题都能找到根因。5. 常见问题速查表可以抄作业的清单为了让大家排查起来方便一点我把这段时间积累的典型问题整理成了一张表按环节归类、按严重度排序基本能覆盖 text-to-cad 项目里 80% 以上的常见故障。环节常见问题可能原因排查与解法预处理数字解析错乱全半角/中文字符干扰统一全半角、归一化数字表达预处理术语识别失败未收录新词/多语言混用扩充术语词典、增加同义词映射语义解析句式覆盖不全规则库覆盖不足记录失败样本持续迭代规则和标注数据语义解析歧义表达误判词义宽泛如孔主动提问确认关键参数参数提取单位弄错单位识别失败或漏判原始片段二次扫描 单位换算因子核对参数提取缺关键参数静默填充默认值策略过于激进区分辅助参数默认化和关键参数确认制建模执行布尔运算失败几何体相切/零厚度执行前做几何合法性检查调整特征顺序建模执行阵列数量异常数量非法值参数校验阶段限制数值范围建模执行约束冲突模板内重复约束简化模板约束定义避免冗余约束导出校验体积偏差过大布尔操作残留体几何属性比对及时报警导出校验参数读回不一致建模特征未正确更新重新生成并强制刷新特征树这张表建议大家直接抄走做成项目里的问题日志模板。新版出了问题先查表查不到再新增记录用一两周时间就能沉淀出属于自己的排查手册。6. 实操心得如果让我重新做一遍这三件事会先做项目做完以后回头总结有几条心得我觉得比任何技术细节都有价值。第一先把验收动作定义清楚再动工写代码。我们一开始花了太多时间在解析更准的模型上后来才发现用户真正在意的是生成的模型能不能直接进软件改尺寸。方向如果错了解析准确率再高也没用。正确的顺序是先确定你要交付哪种模型、哪种精度、哪种可编辑性再倒推需要什么解析能力。这就好比你做饭先想清楚要端出什么菜再决定调料比例而不是先纠结酱油用哪种。第二积累一个失败表达库远比优化模型参数重要。用户说话的方式千奇百怪打四个眼儿这种口语表达词典和规则都覆盖不到。后来我把所有未能正确解析的输入都记录下来整理成失败样本库每周迭代一次。这个库让系统的真实可用性每周都有肉眼可见的提升比调整内部词向量维度有效得多。第三交互设计绝不是锦上添花而是刚需。text-to-cad 天然有不确定性系统确认理解正确这个环节不能省。哪怕只是一个简单的摘要回显 确认按钮也能把最终交付的错误率降低一个数量级。我测过在解析后立即建模、不做确认和解析后先回显确认再建模这两种流程下用户对结果的满意度有很大差别。多做一次确认只是多点一下的事却换来完全不同的信任度。我自己最深的体会是text-to-cad 真正考验的不是 AI 能力而是对领域逻辑的拆解能力和对产品交互的把握。AI 负责理解语言但理解完语言之后如何组织参数、如何生成可编辑的几何、如何让用户信任系统的输出这些才是决定项目成败的地方。如果你也想做类似的方向我的建议是别急着找最花哨的模型。找一个你熟悉的零件把它拆成参数化模板用最朴素的解析方式跑通一条链路——从文本到参数到建模到校验——你从这个过程中收获的对自然语言与 CAD 结合的理解比任何现成方案都扎实。等这条链路跑通了再逐步扩充模板库、提升解析覆盖率你会发现这个系统的天花板一直在往上抬而你每抬一次都对 CAD 和 AI 的关系多一分理解。
返回列表