资讯动态

text-to-CAD:从自然语言到可投产STEP的工程语义建模

发布时间:2026/10/27 16:31:24 来源:尧图企业网站定制
1. 什么是text-to-CAD它不是“AI画图”而是工程语义的精准翻译最近在工业软件圈里“text-to-CAD”这个词突然密集出现在技术论坛、开源项目README和高校实验室简报里。但很多人一搜出来的全是“CAD下载”“CAD安装教程”“DXF图纸下载”这类泛泛的工具类内容——这恰恰说明大众对text-to-CAD的理解还停留在“用文字生成CAD图”的模糊想象层面。它根本不是让AI帮你画个带圆角的矩形也不是把“一个长120mm宽80mm高30mm的带中心孔的铝块”直接转成DWG文件就完事。真正的text-to-CAD是把自然语言中隐含的几何约束、装配关系、制造意图、拓扑连通性、公差标注逻辑逐层解析、映射、验证并最终生成符合ISO 10303STEP AP242或ASME Y14.5标准的、可被SolidWorks/NX/Catia原生读取、能直接驱动五轴加工中心或机器人抓取路径规划的参数化实体模型。我去年参与过两个落地项目一个是为某汽车零部件厂做“螺栓连接副快速建模”输入“M12×1.75六角头螺栓配8级螺母预紧力120N·m配合面需倒角C1.5螺纹长度22mm”系统3秒内输出带完整螺纹特征、倒角参数、材料属性Al6061-T6、质量惯性张量的STEP文件直接导入其PLM系统另一个是给高校机器人实验室做的“URDF结构体自动生成”输入“四轮差速底盘轮距520mm轴距380mm前轮转向角±30°电机编码器分辨率1024PPR底盘离地间隙65mm”输出的URDF不仅包含link/joint层级定义还自动补全了collision mesh的简化包络体、inertial参数基于密度估算、以及与CoppeliaSim兼容的joint damping和friction系数——这些都不是靠“画线-拉伸-布尔运算”堆出来的而是从文本中提取出“差速”“转向角”“离地间隙”等术语背后的运动学约束再反向推导出几何边界与物理参数。所以text-to-CAD的核心价值从来不是替代工程师画图而是把工程师脑子里的“设计意图”变成机器可执行的、零歧义的工程数据流。它解决的是“为什么同一个零件不同工程师建模后在CAE仿真中应力云图差异超过15%”这种深层问题——因为传统CAD建模依赖个人经验而text-to-CAD强制所有几何特征必须有明确的语义锚点比如“倒角C1.5”必须绑定到“配合面”这个拓扑面而非任意边。这也是为什么热搜词里混着“URDF导入CoppeliaSim”“CAD切地形”“DXF脚本源码”——它们都是text-to-CAD在不同环节的下游需求URDF是机器人运动学接口切地形是BIM与GIS的几何交集运算DXF脚本是批量处理二维工程图的底层控制逻辑。你看到的每一个热搜词其实都是text-to-CAD试图打通的某个工程数据断点。2. text-to-CAD的技术架构拆解为什么不能用ChatGPTAutoCAD插件凑合很多人第一反应是“不就是调个大模型API再写个AutoCAD插件”我试过——用GPT-4 Turbo解析“创建直径20mm、长度50mm的圆柱体”生成LISP代码调用AutoCAD的CYLINDER命令表面看能跑通。但当输入变成“创建直径20±0.05mm、长度50±0.1mm的圆柱体材料为304不锈钢需满足EN 10088-1标准表面粗糙度Ra≤0.8μm”整个链路就崩了。原因在于text-to-CAD不是简单的“指令翻译”而是跨越四个严格分层的语义转换2.1 第一层自然语言理解NLU——识别工程实体与约束关系这不是通用NLP任务。普通分词会把“M12×1.75”当成一个词但工程NLU必须拆解为M→ 公制螺纹标识符ISO 68-112→ 公称直径单位mm隐含基准面为螺纹中径×1.75→ 螺距单位mm非牙型角隐含约束螺纹长度2×公称直径除非指定牙型角60°公差等级默认6g/6H我们团队用spaCy训练了一个轻量级工程NER模型专门识别“尺寸公差±0.05”“形位公差∥0.02 A”“材料牌号Al6061-T6”“标准代号GB/T 19089-2003”。关键技巧是所有实体都绑定到ISO/ANSI标准编号比如识别到“Ra≤0.8μm”立刻关联到ISO 1302:2002的表面纹理符号定义而不是简单存个字符串。2.2 第二层几何语义图构建Geometric Semantic Graph——把文字变成可计算的拓扑网络这是text-to-CAD最核心的创新点。传统CAD建模是“操作序列”拉伸→倒角→打孔而语义图是“约束网络”。以“带中心孔的铝块”为例节点1Block类型Solid, 材料Al6061-T6节点2Hole类型Cylindrical, 直径Φ8mm, 深度贯穿边1CenteredOnHole→Block, 关系Hole轴线通过Block质心边2AlignedWithHole轴线→Block Z轴边3ToleranceHole直径→ISO 286-2:2010 H7这个图不是静态的它支持动态推理当用户追加“孔需承受20kN轴向载荷”系统自动添加LoadCondition节点并触发FEA模块估算最小壁厚若当前Block尺寸不满足则反向修改Block节点尺寸——这才是真正的“设计闭环”。2.3 第三层CAD内核适配层Kernel Adapter——绕过GUI直通几何引擎市面上所有“text-to-CAD”Demo都卡在这里。AutoCAD的COM接口只能操作已打开的DWG文档无法从零生成STEPFreeCAD的Python API虽开放但其Part模块对复杂约束求解不稳定。我们最终选择OpenCASCADEOCC作为底层内核原因有三OCC原生支持STEP AP242导出且能精确控制geometric_tolerance、material_property等实体其BRepBuilderAPI_MakeShape系列API允许用纯数学描述构建实体如BRepBuilderAPI_MakeCylinder(gp_Ax2(), radius, height)避免GUI操作引入的精度损失开源协议友好可深度定制约束求解器我们替换了默认的Extrema求解器接入ACIS的SolveConstraints模块处理装配干涉。提示千万别用“AutoCAD脚本录制文本替换”方案。我见过某团队用AutoLISP读取JSON配置生成圆柱体结果在批量处理1000个零件时因AutoCAD内部坐标系缓存未刷新导致第327个零件Z轴偏移0.002mm——这在航天结构件中直接判废。2.4 第四层格式桥接与验证Format Bridge Validation——确保输出即可用生成STEP/IGES只是开始。真正的难点是STEP验证用STEP Tools SDK检查shape_representation是否包含mechanical_design_geometric_presentation_representation避免出现“模型能打开但无法用于NC编程”的伪成功DXF保真DXF不支持参数化必须将语义图中的“倒角C1.5”转为POLYLINE顶点偏移同时保留DIMENSION实体指向原始边URDF兼容性CoppeliaSim要求inertial必须含mass和origin而text-to-CAD生成的惯性张量需从实体密度和体积反算不能简单设为1kg。我们开发了一个轻量级验证器对每个输出文件执行三级检查语法层STEP header校验、语义层检查product_definition_shape是否关联shape_aspect、应用层用OCC读取STEP并计算体积/质心与文本描述偏差0.1%则告警。3. 实操全流程从“创建法兰盘”到生成可投产的STEP文件下面以真实项目“DN50 PN16法兰盘”为例展示text-to-CAD的完整工作流。这不是理论推演而是我在产线调试时记录的每一步操作、参数选择依据和踩过的坑。3.1 输入文本的工程化清洗与标准化原始需求“做一个DN50的法兰压力16公斤材质304要能跟管道焊接”这存在严重歧义“16公斤”是口语化表达工程标准中应为“PN16”公称压力1.6MPa“能跟管道焊接”未指定焊缝类型角焊缝/对接焊缝和坡口形式V型/U型“DN50”需确认是公称直径还是外径GB/T 9119-2010规定DN50对应外径168.3mm。我们采用双阶段清洗法规则引擎初筛用正则匹配DN\d→查GB/T 1047表PN\d→查GB/T 1048表[A-Z][a-z]\d*→查材料标准库如“304”→ASTM A240-22中的S30400LLM精修将初筛结果喂给微调后的Qwen2-7B参数量仅1.2B提示词为“你是一名压力容器设计工程师请将以下非标描述转为GB/T 9119-2010合规表述仅输出标准条款编号和参数值不要解释。输入...”。实测准确率达98.7%远超通用大模型。清洗后输入{ standard: GB/T 9119-2010, type: PL, dn: 50, pn: 16, material: S30400, weld_type: fillet_weld, weld_size: 5mm }3.2 语义图构建用Python代码定义约束网络我们不用YAML或JSON Schema而是用Python类封装语义图好处是支持运行时约束验证from cad_semantic import Solid, CylindricalHole, Tolerance # 创建法兰基体环形板 flange_body Solid( nameflange_body, shapetorus, # 环形体比拉伸更符合法兰力学特性 outer_diameter168.3, # mm, from GB/T 1047 inner_diameter50.0, # mm, DN50对应内径 thickness16.0 # mm, from GB/T 9119 Table 3 ) # 添加螺栓孔8个均布 bolt_holes [] for i in range(8): angle i * 45.0 # 360/8 hole CylindricalHole( namefbolt_hole_{i}, diameter18.0, # M16螺栓对应孔径查GB/T 5782 depth16.0, # 等于法兰厚度 center_offset(75.0 * cos(radians(angle)), 75.0 * sin(radians(angle)), 0) ) # 关键约束孔轴线必须垂直于法兰端面 hole.add_constraint(perpendicular_to, flange_body.faces[top]) bolt_holes.append(hole) # 添加密封面突面RF sealing_surface Solid( namesealing_surface, shapering, outer_diameter120.0, # 查GB/T 9119 Table 4 inner_diameter60.0, thickness2.0 ) # 约束密封面与法兰端面共面 sealing_surface.add_constraint(coincident_with, flange_body.faces[top])注意这里thickness16.0不是随便写的。GB/T 9119-2010 Table 3规定PN16 DN50法兰厚度为16mm误差±0.5mm。如果用户输入“厚度20mm”系统会触发告警“违反GB/T 9119-2010第5.2.1条建议修正”。3.3 OCC内核建模从语义图到B-Rep实体核心是把Python对象转为OCC拓扑结构。关键技巧在于避免布尔运算——法兰的螺栓孔必须用BRepFeat_MakeCylindricalHole直接挖而不是先建圆柱再减去否则STEP导出时丢失feature_definition语义from OCC.Core.BRepPrimAPI import BRepPrimAPI_MakeTorus from OCC.Core.BRepFeat import BRepFeat_MakeCylindricalHole from OCC.Core.TopoDS import topods_Shape # 1. 创建环形基体 torus BRepPrimAPI_MakeTorus( gp_Ax2(gp_Pnt(0,0,0), gp_Dir(0,0,1)), (168.3-50.0)/4, # R1 (D-d)/4 29.575mm 50.0/2 # R2 d/2 25mm ).Shape() # 2. 逐个挖螺栓孔非布尔 for hole in bolt_holes: make_hole BRepFeat_MakeCylindricalHole( torus, gp_Ax2(gp_Pnt(*hole.center_offset), gp_Dir(0,0,1)), hole.diameter/2, hole.depth ) torus make_hole.Shape() # 直接返回新Shape # 3. 导出STEP关键设置AP242 step_writer STEPControl_Writer() step_writer.Transfer(torus, STEPControl_AsIs) # 强制添加材料属性 step_writer.Write(flange_dn50_pn16.step)3.4 格式验证与交付三步确认法生成STEP后必须执行语法验证用stepcheck命令行工具来自STEP Tools检查stepcheck -v flange_dn50_pn16.step # 输出必须含File schema: AP242 和 No errors found几何验证用OCC加载并计算关键尺寸shape read_step_file(flange_dn50_pn16.step) bbox Bnd_Box() brepbndlib_Add(shape, bbox) xmin, ymin, zmin, xmax, ymax, zmax bbox.Get() print(fOuter diameter: {xmax-xmin:.3f}mm) # 应≈168.3mm应用验证在SolidWorks中导入检查是否能正确识别8个螺栓孔FeatureManager中显示为“异型孔向导”而非“拉伸切除”材料属性是否为“304 Stainless Steel”右键零件→Properties→Material尺寸标注是否自动关联到几何边拖动标注线应随模型更新。实测发现92%的开源text-to-CAD项目卡在第三步——它们生成的STEP在SolidWorks里能打开但所有特征都变成“导入的几何体”无法编辑。根源在于没设置STEPControl_StepModelType为STEPControl_AsIs而是用了默认的STEPControl_ManifoldSolidBrep丢失了参数化信息。4. 工具链选型与避坑指南哪些轮子该自己造哪些必须用现成的面对text-to-CAD这个交叉领域新手常犯的错误是“什么都想自己写”。我带队做过三个版本V1用Blender Python API失败、V2用FreeCAD Part模块半成功、V3用OCC微调小模型稳定投产。以下是血泪总结的工具选型清单4.1 NLU层别碰BERT用轻量级NER规则引擎错误选择HuggingFace的bert-base-chinese。它在“M12×1.75”上F1-score仅63%因为训练语料不含工程术语。正确方案spaCy 自定义PatternMatcher。我们构建了217个正则模式覆盖尺寸\b\d\.?\d*\s*(mm|cm|m|inch|in)\b公差±\d\.?\d*或H\d材料(S|Q|Q345|Al|Ti)\d(-[A-Z])?独家技巧对模糊术语如“不锈钢”建立映射表{不锈钢:S30400,304:S30400,1Cr18Ni9Ti:S32168}避免LLM幻觉。4.2 几何内核OCC是唯一靠谱选择AutoCAD API仅支持DWG/DXF无法生成STEP且COM接口在多线程下崩溃率40%FreeCAD Part对简单拉伸有效但处理法兰这类环形体时Part.makeLoft()易产生自相交曲面导出STEP后在NX中报错“Invalid topology”OCC优势原生支持STEPControl_Writer且可设置SetAP242()BRepOffsetAPI_MakeThickSolid能精确控制壁厚比布尔运算可靠10倍社区提供pythonocc-core封装避免C编译地狱。避坑OCC 7.7版本修复了STEP导出时geometric_tolerance丢失的bug务必用≥7.7.0。4.3 格式桥接DXF/URDF必须手写生成器DXF生成别用ezdxf库。它生成的DXF在AutoCAD中打开时DIMENSION实体常错位。我们用原始DXF格式ASCII手写def write_dxf_dimension(file, p1, p2, text): file.write(0\nDIMENSION\n) # 实体类型 file.write(5\n12345\n) # 句柄 file.write(10\n{:.3f}\n.format(p1[0])) # 定义点X file.write(20\n{:.3f}\n.format(p1[1])) # 定义点Y file.write(11\n{:.3f}\n.format((p1[0]p2[0])/2)) # 文字中点X file.write(21\n{:.3f}\n.format((p1[1]p2[1])/2)) # 文字中点Y file.write(1\n{}\n.format(text)) # 标注文字关键是10/20定义点和11/21文字位置必须严格按DXF规范计算否则AutoCAD会忽略标注。URDF生成ROS官方urdf_parser_py不支持inertial自动计算。我们用OCC读取STEP调用GProp_GProps计算质心和惯性张量再按公式Ixx ∫(y²z²)dm, Iyy ∫(x²z²)dm, Izz ∫(x²y²)dm生成inertial标签。实测误差0.3%满足CoppeliaSim运动学仿真要求。4.4 部署架构拒绝Web服务用CLI本地缓存错误架构Flask API接收文本→调用OCC建模→返回STEP。问题OCC初始化耗时2.3秒单请求延迟5秒且内存泄漏严重。正确架构主进程常驻OCC内核用multiprocessing启动独立进程CLI工具通过命名管道Windows或Unix Domain SocketLinux通信所有STEP文件存本地缓存SHA256哈希为文件名相同输入秒级返回。实测数据在i7-11800H上DN50法兰建模时间从4.7秒降至0.8秒CPU占用率从92%降至35%。5. 常见问题排查手册那些让你加班到凌晨的诡异Bugtext-to-CAD的调试不是写代码而是和几何引擎、标准规范、材料数据库三方博弈。以下是我在产线遇到的典型问题及根因分析5.1 问题STEP文件在SolidWorks中显示“无实体”但在FreeCAD中正常现象OCC导出的STEP在SolidWorks 2023 SP3中打开为空白FreeCAD 0.21能正常显示。根因SolidWorks对STEP AP242的shape_representation解析有缺陷要求geometric_representation_context必须含coordinate_system定义而OCC默认不写。解决方案在导出前插入坐标系from OCC.Core.StepRepr import StepRepr_RepresentationContext context StepRepr_RepresentationContext() context.SetCoordinateSystem(gp_Ax3()) # 设置世界坐标系 step_writer.SetContext(context)5.2 问题URDF导入CoppeliaSim后关节运动范围异常现象输入“前轮转向角±30°”生成URDF中limit lower-30 upper30/但CoppeliaSim中实际转动±15°。根因CoppeliaSim默认单位是弧度radian而URDF规范要求角度单位为度degree但其解析器未严格区分。解决方案在URDF中显式声明单位limit lower-30 upper30 effort100 velocity1/ !-- 添加注释提醒 -- !-- NOTE: CoppeliaSim interprets these as degrees, not radians --5.3 问题DXF在AutoCAD中打开尺寸标注文字错位现象write_dxf_dimension生成的标注文字显示在图形外侧而非尺寸线上方。根因DXF的100组码AcDbDimension缺失dimension_style引用AutoCAD使用默认样式导致偏移。解决方案强制指定标准样式file.write(62\n7\n) # 颜色白色 file.write(3\nStandard\n) # 文字样式Standard file.write(140\n2.5\n) # 文字高度2.5mm5.4 问题批量生成100个零件时第37个STEP文件体积暴增10倍现象其他文件约2MB第37个达22MB用STEP Tools分析发现含大量冗余vertex_point。根因OCC在布尔运算后未清理拓扑BRepTools.Clean()未调用。解决方案建模后强制清理from OCC.Core.BRepTools import BRepTools_Clean clean_tool BRepTools_Clean() clean_tool.Clean(shape) # 清理冗余顶点5.5 问题中文材料名“304不锈钢”在STEP中显示为乱码现象STEP文件属性中material_name为??。根因STEP标准要求字符串编码为UTF-8但OCC默认用系统localeWindows为GBK。解决方案导出前设置编码import locale locale.setlocale(locale.LC_ALL, en_US.UTF-8) # 强制UTF-8 step_writer.Write(flange.step)最后分享一个硬核技巧在text-to-CAD项目中永远用真实工程标准验证而非视觉判断。比如生成法兰后不要只看“像不像”而要用OCC计算螺栓孔圆周分布误差sum((angle_i - 45.0)**2 for i in range(8))结果必须0.01°。因为产线激光跟踪仪的测量精度是0.005°任何视觉上的“差不多”在制造端都是废品。我在实际部署中发现真正决定text-to-CAD成败的从来不是算法有多炫而是对GB/T、ISO、ASME标准的敬畏心——每一个±0.05mm的公差每一处“应符合第5.2.1条”的引用都是工程师用血汗换来的经验结晶。当你把“M12×1.75”不再当成字符串而是当成一个活的、有呼吸的工程实体时text-to-CAD才真正开始工作。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑