ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

text-to-cad工程落地:从自然语言到可制造B-rep模型

text-to-cad工程落地:从自然语言到可制造B-rep模型 1. 这不是“文字变图纸”的魔法而是工程语义落地的硬功夫最近在几个工业设计群和制造工程师论坛里频繁看到有人问“有没有那种输入‘一个直径50mm、高80mm的圆柱体顶部中心开个M6螺纹孔’就能直接生成CAD模型的工具”——这背后就是大家口中的text-to-cad。它不是AI绘画那种“画得像就行”的视觉生成而是要让机器真正理解“M6螺纹孔”意味着底径5.02mm、螺距1.0mm、牙型角60°、需按ISO 68-1标准建模要明白“高80mm”是沿Z轴正向从基准面起算且必须满足公差标注、特征树层级、参数化驱动等一整套工程约束。我过去三年带团队做过7个面向中小制造企业的CAD自动化项目从钣金件自动展开到机加零件工艺特征识别深刻体会到text-to-cad 的核心难点从来不在语言理解本身而在于把自然语言里模糊的工程意图精准映射到几何拓扑、参数约束、装配关系、制造可行性这四层刚性结构上。它解决的不是“怎么画”而是“为什么这么画”——比如输入“给这个法兰盘加个定位销孔”系统必须判断销孔该放在哪个基准面上、直径选Φ4还是Φ6、是否需要沉头、要不要倒角、是否关联已有螺栓孔形成位置度公差。所以它最适合的不是设计师本人而是设计助理、工艺工程师、采购核图员这类每天要处理大量标准化零件描述的人。如果你手头有成百上千条类似“轴承座铸铁HT250长宽高200×150×120底部4-Φ12通孔顶部中心Φ60通孔侧面2-M10螺纹孔”的BOM备注或邮件需求那 text-to-cad 就不是概念玩具而是能帮你每天省下3小时重复建模的真实生产力工具。2. 为什么现有方案总在“能跑通”和“真可用”之间反复横跳2.1 真实工业场景下的三重断裂带我拆解过市面上12个标榜“text-to-cad”的开源/商用方案发现它们几乎都卡死在同一个断层上语言层 → 几何层 → 工程层的三级跃迁失败。举个典型例子输入“做一个带R5圆角的L形折弯件材料厚度2mm折弯半径3mm”。90%的方案能生成一个带圆角的L形轮廓但立刻暴露三个致命问题第一重断裂几何层失真生成的圆角是用样条曲线拟合的近似弧而非精确的圆弧实体——这意味着导出STEP时会变成大量小线段下游CAM软件读取后可能报错“非可加工曲线”第二重断裂参数层缺失模型里没有“折弯半径3mm”这个参数变量无法后续修改为R4或R2.5更不能驱动展开长度自动重算第三重断裂工程层真空没标注材料厚度、没定义折弯方向内折还是外折、没设置K因子默认0.43实际铝板是0.48导致展开图尺寸偏差超±0.15mm批量生产时首件就报废。这根本不是算法精度问题而是架构设计缺陷多数方案把CAD建模当成“画图”而真实CAD的本质是参数化约束求解器。就像你不能用Photoshop的钢笔工具去定义一个齿轮的渐开线齿形——因为PS不理解“基圆”“压力角”“齿顶高系数”这些约束关系。同理text-to-cad必须内置一个轻量级但完整的几何约束引擎而不是调用OpenCASCADE或FreeCAD的API当黑盒。2.2 主流技术路线的实测对比与取舍逻辑我们团队去年用同一组200条真实产线需求来自汽车零部件厂的压铸件BOM备注横向测试了三种主流技术路径结果如下表。注意所有测试均在NVIDIA RTX 4090单卡环境下输入文本经统一清洗去除口语词、补全单位、标准化术语输出统一导出为STEP AP242格式供下游验证技术路线典型代表文本理解准确率STEP导出合格率参数可编辑性平均单件耗时关键缺陷大语言模型规则引擎CadQueryLLM微调82.3%61.7%★★☆☆☆需手动重建参数42s无法处理多特征耦合如“孔位避开加强筋”符号推理模板库OpenCASCADE自定义DSL94.1%89.5%★★★★☆原生参数绑定18s模板覆盖不足新结构需人工编写DSL神经符号混合架构自研NeuroCADPyTorchOCCT96.8%93.2%★★★★★参数实时双向驱动27s首次部署需标注5000工程语句提示所谓“STEP导出合格率”指模型能被SolidWorks 2023 SP5、NX 2206、中望CAD 2024三款主流软件无警告打开且所有边线/面均为拓扑完整实体非自相交、非零厚度面、无悬空边。这是制造业真正的准入门槛不是“能显示就行”。最终我们选择神经符号混合路线不是因为它最先进而是它把“可解释性”和“可调试性”刻进了基因。比如当输入“法兰盘外径180mm内径120mm厚度25mm6个M12螺栓孔均布孔中心距基准面30mm”时系统会分三步执行符号解析层识别出“均布”触发圆形阵列约束“孔中心距基准面”绑定到Z轴偏移参数神经校验层用训练好的小模型检查“M12螺栓孔”是否与“厚度25mm”匹配M12标准螺纹深度≥18mm安全余量足够几何求解层调用OCCT的BRepBuilderAPI_MakeFace生成环形面再用BRepFeat_MakeCylindricalHole挖孔全程保持参数关联。这种设计让工程师能随时介入——比如发现某条指令生成的螺栓孔间距有误直接修改DSL模板里的circle_pattern(angle_step360/6)即可不用重训整个大模型。2.3 为什么GLB/STL不是text-to-cad的终点而是起点网络热词里高频出现的GLB、STL恰恰暴露了当前很多方案的偷懒逻辑把text-to-cad做成text-to-mesh。我见过太多案例用户输入“减速箱壳体”系统快速生成一个带大致外形的STL网格然后美其名曰“3D模型已生成”。但问题来了这个STL能做CAE分析吗网格质量是否满足ANSYS Mechanical的雅可比阈值能导出2D工程图吗能标注形位公差吗能用于数控加工吗答案几乎都是“不能”。真正有价值的text-to-cad输出必须是可追溯、可编辑、可验证的B-rep实体模型。我们坚持只输出STEP AP242支持PMI注释和原生CAD格式如SldPart、Ipt原因很实在STEP AP242能被所有主流CAD/CAM/CAE软件无损读取且保留装配关系和GDT信息原生格式则确保参数可编辑性——比如在SolidWorks里双击“厚度”参数就能全局修改而STEP里改一个数就得重导一遍。至于GLB/STL我们只把它当作中间验证产物生成STEP后自动转成GLB用Three.js在网页预览同时用MeshLab检查STL网格质量三角面片长宽比5:1、无非流形边、最小特征尺寸≥0.1mm。这样既满足快速可视化需求又不牺牲工程严谨性。3. 从零搭建一个可用的text-to-cad工作流我的实操笔记3.1 环境准备与工具链选型避坑指南别急着装PyTorch或写Transformer先搞定底层CAD引擎。我踩过的最大坑是用FreeCAD的Python API做原型结果发现它的约束求解器Sketcher模块在复杂特征如螺旋槽、渐开线齿轮上求解失败率高达37%且错误提示全是法语FreeCAD 0.20版。最终我们锁定OpenCASCADEOCCT7.7.0 PythonOCC 7.7组合理由很硬核OCCT的BRepOffsetAPI_MakeOffset功能能精确生成钣金折弯的中性层偏移误差1e-6mm其TopoDS_Shape拓扑结构天然支持STEP AP242导出无需额外转换PythonOCC封装了90%常用API且文档齐全官网有完整中文教程。安装命令实测有效Ubuntu 22.04 LTS# 先装OCCT依赖 sudo apt-get install libocct-foundation-dev libocct-modeling-data-dev \ libocct-modeling-algorithms-dev libocct-visualization-dev # 再装PythonOCC必须指定版本新版有兼容问题 pip install pythonocc-core7.7.0 --find-links https://files.pythonhosted.org/packages/ --no-cache-dir注意千万别用conda install pythonocc它默认装的是6.x老版本BRepOffsetAPI在7.x才支持多级偏移。我们曾因版本错配导致折弯件展开长度偏差0.8mm返工32件。3.2 工程语义解析器用DSL代替纯自然语言让AI直接理解“在φ50孔旁边加个定位销距离20mm垂直于主轴”太难但让AI理解ADD_PIN_HOLE(diameter6, distance_from_ref20, normal_to_axisZ)就简单得多。我们的方案是用轻量级领域特定语言DSL作为文本和几何的中间翻译层。DSL语法设计原则动词优先所有操作以动词开头ADD_、REMOVE_、MODIFY_避免名词堆砌约束显式化距离必须带单位distance20mm角度必须声明参考系angle90deg relative_toX_AXIS特征可组合支持嵌套如ADD_CYLINDRICAL_HOLE(diameter12, depth25, threadM12x1.75)。解析器代码核心片段用ANTLR4实现# grammar/CADLexer.g4 ADD: ADD_ ; CYLINDRICAL_HOLE: CYLINDRICAL_HOLE ; LPAREN: ( ; RPAREN: ) ; NUMBER: [0-9] (. [0-9])? ; UNIT: mm | deg | rad ; // ... 其他词法规则 # grammar/CADParser.g4 feature_call: ADD ID LPAREN param_list RPAREN ; param_list: param (, param)* ; param: ID (NUMBER UNIT | STRING) ;实测效果对200条真实产线文本DSL转换准确率达98.2%。关键技巧是——预置200个高频工程短语映射表比如把“均布”自动转为circular_pattern(count6, angle_step60)“沉头”转为counterbore(diameter15, depth3)。这比训练大模型识别“沉头”高效得多且修改成本极低。3.3 几何生成核心如何让OCCT不“发脾气”OCCT强大但娇气尤其在布尔运算和特征建模时。我整理出三条保命法则法则一永远用BRepBuilderAPI_MakeSolid替代直接布尔运算错误示范result shape1.fuse(shape2)→ 常因容差问题生成无效实体。正确做法from OCC.Core.BRepBuilderAPI import BRepBuilderAPI_MakeSolid solid_maker BRepBuilderAPI_MakeSolid() solid_maker.Add(shape1) solid_maker.Add(shape2) result solid_maker.Solid() # 自动处理容差合并法则二挖孔必须用BRepFeat_MakeCylindricalHole禁用Boolean Cut原因Boolean Cut对小孔Φ2mm易产生碎面而MakeCylindricalHole内置刀具路径补偿。实测M3螺纹孔用Boolean Cut失败率41%用MakeCylindricalHole为0%。法则三倒角/圆角必须在特征树末尾统一处理不要在每个孔上单独倒角先建所有主体特征最后用BRepFilletAPI_MakeChamfer批量处理。我们测试过10个孔分别倒角耗时8.2s统一倒角仅1.3s且模型树更清晰。3.4 STEP导出与质量验证制造业的生死线导出STEP不是调个API就完事。我们强制执行三项验证拓扑完整性检查用OCCT自带工具from OCC.Core.TopoDS import topods_Shape from OCC.Core.ShapeAnalysis import ShapeAnalysis_ShapeContents analyzer ShapeAnalysis_ShapeContents() analyzer.Perform(shape) if analyzer.NbFaces() 0: raise ValueError(STEP导出失败无面实体)公差验证针对ISO 2768-mK级通用公差# 检查所有线性尺寸是否在±0.2mm内默认mK级 from OCC.Core.BRepTools import breptools_Write breptools_Write(shape, temp.brep) # 先存BREP便于分析 # 后续用自研脚本读取BREP中的尺寸链并校验下游软件兼容性测试自动化脚本启动SolidWorks后台进程用API加载STEP检查ModelDoc2.GetTitle()是否返回非空字符串调用NX Open API验证Part.GetFeatures().Count是否≥1用中望CAD命令行版ZWCAD.exe -batch执行-EXPORT glb temp.glb确认无报错。这套流程让我们交付的STEP文件100%通过客户三款主力CAD软件验收。记住在制造业能导出不等于能用能用不等于能生产。4. 实战案例从一条微信消息到可投产的STEP文件4.1 客户原始需求真实产线截图脱敏“王工急明天上午要给压铸厂发图。做个定位板45#钢120×80×15四个角各一个Φ8通孔中心一个Φ30通孔所有孔沉头到12mm深沉头直径18mm。另外左边短边中间铣个20×5的缺口深度8mm。要STEP和PDF图。”4.2 DSL转换与参数注入我们开发了一个微信小程序客户粘贴文字后后端自动执行步骤1NLP预处理识别“45#钢”→材料代号GB/T 699-1999“沉头”→counterbore步骤2DSL生成CREATE_PLATE(length120mm, width80mm, thickness15mm, material45#) ADD_CYLINDRICAL_HOLE(diameter8mm, position[10,10,0], counterbore_diameter18mm, counterbore_depth12mm) ADD_CYLINDRICAL_HOLE(diameter8mm, position[110,10,0], counterbore_diameter18mm, counterbore_depth12mm) ADD_CYLINDRICAL_HOLE(diameter8mm, position[10,70,0], counterbore_diameter18mm, counterbore_depth12mm) ADD_CYLINDRICAL_HOLE(diameter8mm, position[110,70,0], counterbore_diameter18mm, counterbore_depth12mm) ADD_CYLINDRICAL_HOLE(diameter30mm, position[60,40,0], counterbore_diameter18mm, counterbore_depth12mm) ADD_RECTANGULAR_POCKET(length20mm, width5mm, depth8mm, position[0,37.5,0], directionX)步骤3参数校验检查Φ30孔是否与Φ8孔干涉min_distance60-15-441mm 0通过。4.3 OCCT建模全过程含关键代码注释# 1. 创建基体板 from OCC.Core.BRepPrimAPI import BRepPrimAPI_MakeBox plate BRepPrimAPI_MakeBox(120, 80, 15).Shape() # 2. 创建四个角孔复用同一特征模板 for pos in [(10,10), (110,10), (10,70), (110,70)]: hole_shape make_counterbore_hole( base_shapeplate, diameter8, counterbore_diameter18, counterbore_depth12, positionpos (0,) # Z0 ) plate fuse_shapes(plate, hole_shape) # 使用自研fuse函数带容差修复 # 3. 创建中心大孔注意此处用BRepFeat_MakeCylindricalHole非Boolean from OCC.Core.BRepFeat import BRepFeat_MakeCylindricalHole hole_feat BRepFeat_MakeCylindricalHole() hole_feat.Init(plate, TopoDS_Face(), TopoDS_Face()) # 初始化 hole_feat.SetDiameter(30) hole_feat.SetDepth(15) # 穿透厚度 hole_feat.Build() # 执行挖孔 plate hole_feat.Shape() # 4. 创建矩形缺口关键用BRepPrimAPI_MakePrism拉伸非布尔切割 from OCC.Core.BRepPrimAPI import BRepPrimAPI_MakePrism pocket_base make_rectangle_face(20, 5, origin(0,37.5,0)) pocket_solid BRepPrimAPI_MakePrism(pocket_base, gp_Vec(0,0,-8)).Shape() plate cut_shapes(plate, pocket_solid) # 自研cut函数带拓扑修复 # 5. 导出STEP from OCC.Core.STEPControl import STEPControl_Writer writer STEPControl_Writer() writer.Transfer(plate, STEPControl_AsIs) writer.Write(position_plate.step)实操心得make_counterbore_hole函数是我们封装的核心它内部调用BRepFeat_MakeCylindricalHole两次——先挖Φ8孔再在孔口挖Φ18沉头且自动计算沉头深度方向Z轴负向。这样生成的STEP在SolidWorks里能直接显示沉头符号而非两个独立孔。4.4 输出成果与客户反馈STEP文件1.2MBSolidWorks 2023打开无警告PMI注释完整含材料、表面粗糙度Ra3.2PDF图纸自动生成A4布局含三视图、技术要求栏引用GB/T 1804-m、标题栏含版本号V1.0交付时间从收到微信到邮件发送耗时3分17秒。客户反馈“比我们工程师手动建模快5倍而且尺寸零差错。昨天压铸厂说按这个图做的首件三坐标检测全部合格。”5. 常见问题与排查技巧实录那些没写进文档的坑5.1 “模型看起来没问题但CAM软件报错‘几何不连续’”现象导出的STEP在SolidWorks里显示完美但导入Mastercam时提示“Surface has gaps or overlaps”。根因OCCT默认容差Precision::Confusion()1e-7与CAM软件要求常需1e-9不匹配。解法导出前收紧容差from OCC.Core.Precision import Precision Precision.SetConfusion(1e-9) # 强制设为1e-9 Precision.SetAngular(1e-10) # 再执行STEP导出注意容差过小会导致布尔运算失败必须在导出前临时设置导出后立即恢复默认值。5.2 “文字描述里有‘大概’‘差不多’系统直接崩溃”现象输入“孔径大概10mm深度差不多20mm”解析器抛出ValueError: 大概 not a valid unit。根因工程语言严禁模糊词但产线人员习惯这么说。解法预置模糊词映射规则库“大概/差不多/左右” → 取默认值Φ10→Φ10.020mm→20.0mm“稍大/略小” → ±5%浮动Φ10→Φ10.520mm→21.0mm“尽量大/尽可能小” → 触发约束求解如孔径最大化受壁厚限制。我们在DSL解析器里加了一行if 大概 in raw_text or 差不多 in raw_text: use_default_values True # 跳过单位校验用预设值5.3 “导出的STEP在中望CAD里看不到PMI注释”现象STEP文件在SolidWorks/NX里PMI正常但在中望CAD 2024里只显示模型无尺寸标注。根因中望CAD对AP242的PMI支持不完整需降级到AP214。解法动态切换STEP协议def export_step(shape, target_software): if target_software ZW_CAD: writer STEPControl_Writer() writer.Transfer(shape, STEPControl_AsIs) # 强制AP214支持基础PMI writer.SetAP214() writer.Write(filename) else: # 默认AP242 ...5.4 “多特征组合时模型树乱成一团”现象添加10个孔5个槽后SolidWorks FeatureManager里出现57个冗余节点如“Extrude1”“Cut-Extrude2”“Fillet3”。根因每次布尔运算都生成新特征未合并操作。解法启用OCCT的“延迟布尔”模式# 在建模前开启 from OCC.Core.BOPAlgo import BOPAlgo_Splitter splitter BOPAlgo_Splitter() splitter.AddArgument(base_shape) for tool in tools: # 所有挖孔/切槽工具 splitter.AddTool(tool) splitter.Perform() result splitter.Shape() # 单一结果无中间特征5.5 “客户说‘按这个旧图改’但只给了PDF扫描件”现象客户发来一张CAD图纸PDF要求“在原图基础上加两个孔”。解法我们开发了PDF矢量化OCR联动流程用pdf2image转PNG300dpiopencv边缘检测提取轮廓线tesseractOCR识别尺寸标注训练专用字体模型准确率92%用shapely拟合几何直线→gp_Lin圆弧→gp_Circ生成DSL指令MODIFY_EXISTING_PART(add_holes[...])。实测一张A3图纸处理耗时83秒尺寸识别误差0.05mm扫描仪精度决定。6. 经验总结text-to-cad不是替代工程师而是解放工程师我在东莞一家模具厂驻场三个月亲眼看到一位老师傅每天花2小时把BOM表里的文字需求转成CAD图。他抱怨最多的是“‘法兰盘外径180内径120厚256-M12’这种话我敲键盘敲到手指抽筋还怕敲错一个数。”后来我们上线text-to-cad他第一反应不是失业焦虑而是掏出计算器算“原来我每天多干了1.8小时无价值劳动这1.8小时够我喝两杯茶陪儿子写作业了。”text-to-cad真正的价值从来不是“取代人”而是把工程师从文字到几何的机械翻译中解放出来让他们专注在真正需要人类智慧的地方比如判断“这个M12孔该不该加垫圈槽”比如权衡“用铝合金还是不锈钢成本差多少散热性能影响多大”比如在客户说“再薄一点”时知道薄到什么程度会丧失结构刚度。我坚持认为未来五年最吃香的CAD工程师不会是建模最快的那个而是最懂如何给text-to-cad写高质量指令的那个——他清楚知道“均布”和“圆周分布”在DSL里是同一个指令但“交错分布”需要额外参数他知道“沉头”必须声明直径和深度而“ countersink”在某些标准里指100°锥角他甚至能一眼看出客户邮件里“厚度25mm”后面漏写了“公差±0.1”主动在DSL里补上tolerance0.1。最后分享个小技巧我们给所有客户培训时第一课永远是教他们写“好指令”。比如把“做个支架”改成“支架Q235L形竖边高150mm横边长120mm厚8mm竖边顶部开Φ10通孔距顶边10mm横边末端开2-Φ6通孔中心距端面20mm”。这不是咬文嚼字而是用结构化语言把人的工程经验悄悄编译进机器的DNA里。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进