news 2026/10/27 16:31:21

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
text-to-CAD:从自然语言到可投产STEP的工程语义建模

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 10303(STEP 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的技术架构拆解:为什么不能用ChatGPT+AutoCAD插件凑合?

很多人第一反应是:“不就是调个大模型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-1)
  • 12→ 公称直径(单位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建模是“操作序列”(拉伸→倒角→打孔),而语义图是“约束网络”。以“带中心孔的铝块”为例:

  • 节点1:Block(类型:Solid, 材料:Al6061-T6)
  • 节点2:Hole(类型:Cylindrical, 直径:Φ8mm, 深度:贯穿)
  • 边1:CenteredOn(Hole→Block, 关系:Hole轴线通过Block质心)
  • 边2:AlignedWith(Hole轴线→Block Z轴)
  • 边3:Tolerance(Hole直径→ISO 286-2:2010 H7)

这个图不是静态的,它支持动态推理:当用户追加“孔需承受20kN轴向载荷”,系统自动添加LoadCondition节点,并触发FEA模块估算最小壁厚,若当前Block尺寸不满足,则反向修改Block节点尺寸——这才是真正的“设计闭环”。

2.3 第三层:CAD内核适配层(Kernel Adapter)——绕过GUI,直通几何引擎

市面上所有“text-to-CAD”Demo都卡在这里。AutoCAD的COM接口只能操作已打开的DWG文档,无法从零生成STEP;FreeCAD的Python API虽开放,但其Part模块对复杂约束求解不稳定。我们最终选择OpenCASCADE(OCC)作为底层内核,原因有三:

  1. OCC原生支持STEP AP242导出,且能精确控制geometric_tolerance、material_property等实体;
  2. 其BRepBuilderAPI_MakeShape系列API允许用纯数学描述构建实体(如BRepBuilderAPI_MakeCylinder(gp_Ax2(), radius, height)),避免GUI操作引入的精度损失;
  3. 开源协议友好,可深度定制约束求解器(我们替换了默认的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)。

我们采用双阶段清洗法:

  1. 规则引擎初筛:用正则匹配DN\d+→查GB/T 1047表,PN\d+→查GB/T 1048表,[A-Z][a-z]+\d*→查材料标准库(如“304”→ASTM A240-22中的S30400);
  2. LLM精修:将初筛结果喂给微调后的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( name="flange_body", shape="torus", # 环形体比拉伸更符合法兰力学特性 outer_diameter=168.3, # mm, from GB/T 1047 inner_diameter=50.0, # mm, DN50对应内径 thickness=16.0 # mm, from GB/T 9119 Table 3 ) # 添加螺栓孔(8个均布) bolt_holes = [] for i in range(8): angle = i * 45.0 # 360/8 hole = CylindricalHole( name=f"bolt_hole_{i}", diameter=18.0, # M16螺栓对应孔径,查GB/T 5782 depth=16.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( name="sealing_surface", shape="ring", outer_diameter=120.0, # 查GB/T 9119 Table 4 inner_diameter=60.0, thickness=2.0 ) # 约束:密封面与法兰端面共面 sealing_surface.add_constraint("coincident_with", flange_body.faces["top"])

注意:这里thickness=16.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后,必须执行:

  1. 语法验证:用stepcheck命令行工具(来自STEP Tools)检查:
    stepcheck -v flange_dn50_pn16.step # 输出必须含:'File schema: AP242' 和 'No errors found'
  2. 几何验证:用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(f"Outer diameter: {xmax-xmin:.3f}mm") # 应≈168.3mm
  3. 应用验证:在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 Socket(Linux)通信;
    • 所有STEP文件存本地缓存(SHA256哈希为文件名),相同输入秒级返回。
  • 实测数据:在i7-11800H上,DN50法兰建模时间从4.7秒降至0.8秒,CPU占用率从92%降至35%。

5. 常见问题排查手册:那些让你加班到凌晨的诡异Bug

text-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" upper="30"/>,但CoppeliaSim中实际转动±15°。
  • 根因:CoppeliaSim默认单位是弧度(radian),而URDF规范要求角度单位为度(degree),但其解析器未严格区分。
  • 解决方案:在URDF中显式声明单位:
    <limit lower="-30" upper="30" effort="100" velocity="1"/> <!-- 添加注释提醒 --> <!-- 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.5mm

5.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默认用系统locale(Windows为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才真正开始工作。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/27 16:31:05

TradeX.dll:DLL注入与共享内存实现行情交易协同

简介&#xff1a;本资源是一套面向量化交易开发者与金融IT工程师的通达信行情与交易接口集成方案&#xff0c;聚焦于Trade.dll与TradeX.dll的封装调用与二次开发支持。通过TdxTradeServer将本地DLL接口封装为HTTP REST API&#xff0c;显著降低C#、Python及C等语言接入通达信交…

作者头像 李华
网站建设 2026/10/27 16:31:01

OpenClaw多Agent协作系统:自动化任务处理与金融分析实战

1. OpenClaw项目概述OpenClaw是一个面向个人开发者和微型团队的AgentTeam引擎&#xff0c;它通过多Agent协作系统实现了"一人公司"的自动化运营理念。这个开源项目最近在开发者社区引发了广泛讨论&#xff0c;特别是在自动化任务处理和多Agent协同领域表现突出。我第…

作者头像 李华
网站建设 2026/10/27 16:29:46

Windows + WSL 双平台搭建Skynet游戏服务器开发环境

1. Skynet 初始化环境搭建&#xff1a;Windows WSL 双平台方案在游戏服务器开发领域&#xff0c;Skynet 作为轻量级的高性能框架备受开发者青睐。但很多 Windows 平台开发者首次接触 Skynet 时&#xff0c;往往会遇到环境配置的难题。本文将详细介绍如何在 Windows 10/11 系统…

作者头像 李华
网站建设 2026/10/27 16:29:46

Text-to-CAD本质:设计意图到几何实体的语义建模链路

1. 这不是“让AI画CAD图”——而是重建设计意图到几何实体的完整链路 “text-to-cad”这个词最近在工程圈和AI圈同时冒头&#xff0c;但很多人一看到就下意识理解成“输入一句话&#xff0c;自动生成一张CAD图纸”&#xff0c;这其实是个危险的误读。我带团队做过3个工业级text…

作者头像 李华
网站建设 2026/10/27 16:27:12

Java开发者必知的JVM核心原理与实践指南

1. 为什么每个Java开发者都应该懂JVM&#xff1f;2006年我刚入行Java开发时&#xff0c;组长让我优化一个报表导出功能。我花了三天时间调整SQL和循环逻辑&#xff0c;性能只提升了15%。后来一位架构师看了一眼就说&#xff1a;"把-Xmx参数从512M调到2G试试"。结果导…

作者头像 李华
网站建设 2026/10/27 16:27:04

大模型KV Cache优化:原理、挑战与工程实践

1. 项目概述&#xff1a;KV Cache为何成为LLM服务集群的关键瓶颈在部署百亿参数级别的大语言模型&#xff08;LLM&#xff09;服务集群时&#xff0c;KV Cache的内存占用问题正逐渐成为制约服务规模和响应速度的核心瓶颈。以实际生产环境中的175B参数模型为例&#xff0c;当并发…

作者头像 李华