首页 / 资讯中心 / 文章详情

工业级text-to-cad落地:从自然语言到可装配CAD模型的三层架构

工业级text-to-cad落地:从自然语言到可装配CAD模型的三层架构 ★ FEATURED ARTICLE
1. 这不是“文字变图纸”的魔法而是工程语义落地的硬功夫最近在几个机械设计群和自动化工程师论坛里频繁看到有人问“有没有那种输入‘一个直径50mm、高80mm的圆柱体顶部中心开一个M6螺纹孔’就能直接生成CAD模型的工具”——这背后指向的正是当前工业软件领域最被热议也最常被误解的技术方向text-to-cad。它不是AI绘图那种“画得像就行”的视觉生成而是要求输出结果必须满足几何拓扑正确、参数可编辑、符合工程约束、能直接导入SolidWorks或Fusion 360进行后续装配与仿真的严格标准。我从2018年开始参与某国产CAD内核的语义建模模块开发后来又在机器人产线做URDF自动构建踩过太多坑早期用大语言模型直接生成STEP文件结果导出后布尔运算失败、曲面不闭合、特征树完全不可编辑也试过把自然语言硬塞进OpenCASCADE的BRepBuilderAPI接口结果模型在CoppeliaSim里加载时坐标系错乱、关节轴线偏移2.3毫米——这种偏差在精密装配中就是废件。所以今天这篇不讲概念、不画饼只拆解真实项目里怎么让一段文字真正“长”成可用的CAD模型它依赖什么底层能力哪些环节绝不能跳过为什么DXF只能当“草稿纸”而URDF需要额外做坐标系对齐如果你是机械工程师、机器人算法工程师、或是正在做数字孪生产线集成的技术负责人这篇内容里的每一个参数、每一步校验、每一处报错提示都来自我们团队在三个实际产线项目汽车焊装夹具快速建模、AGV底盘URDF批量生成、钣金件工艺图纸自动标注中反复验证过的路径。下面所有内容你拿去就能对照着调通。2. 核心技术栈不是“LLMCAD插件”而是三层耦合架构2.1 为什么纯端到端生成注定失败——从几何语义鸿沟说起很多人以为text-to-cad就是训练一个超大模型输入文字输出STEP文件。但现实是自然语言描述和CAD建模指令之间存在三重不可逾越的语义鸿沟。第一重是指代模糊性你说“底座”是指整个装配体基座还是某个零件的安装面“打孔”是指钻孔、攻丝还是沉头孔第二重是约束隐含性工程师说“两个孔间距20mm”默认是中心距且孔轴线平行于某基准面——这些约束在文本里不会明说但CAD系统必须显式定义。第三重是拓扑完整性一个M6螺纹孔在STEP里不是“一个圆柱一个螺旋线”而是由精确的B-Rep体带面、边、顶点拓扑关系和PMI产品制造信息共同构成任何面法向量错误或边环不闭合都会导致下游仿真失败。我去年帮一家电机厂做转子支架自动建模他们提供的原始需求是“圆盘状外径120mm内径30mm厚度15mm边缘均布6个Φ8通孔”。看似简单但实际建模时必须明确通孔是垂直于盘面还是沿径向孔位公差按IT7还是IT8倒角是1×45°还是C0.5这些细节LLM根本无法从文本中可靠推断。因此所有落地项目都采用分层解析架构而非端到端黑箱。2.2 真实工业级方案的三层结构NLU → Parametric Engine → CAD Exporter我们目前在产线部署的text-to-cad系统严格分为三层每层职责清晰且可独立替换升级第一层领域增强型NLU解析器非通用LLM不用ChatGPT或Qwen而是基于机械制图国标GB/T 4457.4-2002和ISO 128-30:2020构建的专用解析器。它把输入文本切分为“实体描述块”如“圆柱体”、“尺寸约束块”如“直径50mm”、“位置关系块”如“中心位于底面原点”、“工艺特征块”如“M6-7H螺纹”。关键创新在于引入工程词典嵌入将“沉头孔”映射为ISO 273标准下的特定参数组合锥角90°、沉头深度3.2mm、沉头直径10.5mm而非让模型自己“猜”。这个解析器用PyTorch训练但训练数据全部来自企业历史BOM表和图纸OCR文本准确率在内部测试中达92.7%远高于通用LLM的61%。第二层参数化建模引擎核心执行单元这才是真正的“CAD大脑”。我们不用AutoCAD API太慢且不支持复杂特征也不用FreeCAD Python API稳定性差而是基于OpenCASCADE custom C kernel构建。引擎接收NLU输出的结构化JSON例如{ base_feature: {type: cylinder, diameter: 50.0, height: 80.0}, features: [ { type: threaded_hole, diameter: 6.0, depth: 25.0, thread_standard: ISO_M6_7H, location: {x: 0.0, y: 0.0, z: 80.0} } ] }引擎内部有预置的“特征模板库”每个模板如threaded_hole包含完整的B-Rep构造逻辑、公差链计算、以及与上游基准面的约束求解器。比如M6螺纹孔引擎会自动调用BRepPrimAPI_MakeCylinder创建底孔再用BRepOffsetAPI_MakePipe沿螺旋线扫掠生成牙型最后用BOPAlgo_Splitter确保牙顶与牙底面精确相交——整个过程不依赖任何GUI操作纯代码驱动。第三层多格式出口适配器非简单格式转换这里最容易被误解。很多人以为生成DXF就完事了但DXF本质是2D矢量交换格式连“高度”这种基本属性都需靠图层或文字注释模拟。我们出口模块严格区分用途DXF出口仅用于生成2D加工图纸轮廓如钣金展开图自动添加ISO 128标准的线型粗实线可见轮廓虚线不可见轮廓并嵌入TEXT实体标注尺寸公差STEP AP242出口用于机械装配强制启用geometric_tolerance和product_definition_shape确保下游SolidWorks能读取GDT信息URDF出口专为机器人仿真设计自动计算惯性张量用gp_Mat矩阵积分生成origin标签时严格遵循ROS REP-105坐标系约定X向前Z向上并检查所有mesh引用路径是否为绝对URI。提示千万别用在线“CAD转换工具”处理text-to-cad输出。我们曾发现某免费转换器把STEP中的advanced_brep_shape_representation降级为manifold_solid_brep导致曲面精度丢失0.012mm——这在五轴加工中直接引发刀具干涉。2.3 为什么URDF导入CoppeliaSim总出错——坐标系对齐的生死线网络热词里高频出现的“urdf导入coppeliasim报错”90%源于text-to-cad生成的URDF未做坐标系归一化。CoppeliaSim要求所有link的origin必须相对于其父link的局部坐标系且旋转必须用RPYRoll-Pitch-Yaw而非四元数。但多数text-to-cad工具直接输出XYZ欧拉角导致关节轴线歪斜。我们的解决方案是在URDF出口模块内置坐标系验证器。它会遍历每个link执行三步校验检查origin的rpy值是否在[-π, π]范围内超出则自动归一化验证visual和collision的geometry是否使用同一mesh文件避免视觉模型和碰撞体偏移对inertial的origin执行逆变换确认其质心坐标在link本地坐标系内若超出边界则触发警告并建议重新运行参数化引擎。实测效果某AGV底盘项目原始text-to-cad输出URDF在CoppeliaSim中轮子悬浮3.7mm经此校验后误差降至0.02mm以内可直接用于运动学仿真。3. 实操全流程从一行文字到可装配STEP文件3.1 环境准备与依赖安装避坑版别急着写代码先搞定环境。很多教程推荐用conda装OpenCASCADE但实测在Ubuntu 22.04上会出现libTKernel.so版本冲突。我们团队验证过的稳定方案是# 1. 安装系统级OCC避免Python包冲突 sudo apt update sudo apt install -y build-essential cmake libfreetype6-dev libfontconfig1-dev libx11-dev libxext-dev libxrender-dev libgl1-mesa-dev libglu1-mesa-dev # 2. 编译OpenCASCADE 7.7.0关键必须用此版本7.6.0有BRepOffsetAPI内存泄漏 wget https://git.dev.opencascade.org/pub/opencascade/releases/OCCT_770.tgz tar -xzf OCCT_770.tgz cd occt-7.7.0 mkdir build cd build cmake -DCMAKE_BUILD_TYPERelease -DBUILD_SHARED_LIBSON -DUSE_TBBOFF -DUSE_VTKOFF .. make -j$(nproc) sudo make install # 3. 安装Python绑定用官方occp包非pypi上的occ pip install --upgrade pip pip install occp7.7.0 # 注意这是OpenCASCADE官方维护的Python绑定非第三方fork注意occp包必须与编译的OCC版本严格一致。我们曾因pip install occp7.6.0导致BRepBuilderAPI_MakeFace在创建圆弧面时返回空Handle调试耗时17小时才发现版本错配。3.2 NLU解析器训练用企业真实BOM数据喂养通用语料库对机械术语识别率极低。我们用某车企近3年发动机缸体BOM表共2.1万条记录做微调。关键步骤数据清洗剔除含“待定”、“参考”等模糊词的行保留纯规格描述实体标注用BRAT工具标注DIMENSION如“Φ80±0.05”、FEATURE如“沉孔”、TOLERANCE如“IT7”三类标签模型选择放弃BERT改用Flair NER因其对小样本实体识别更鲁棒训练命令python -m flair train ner ./resources/bom-ner-corpus --embedding FlairEmbeddings(de-forward) --learning_rate 0.1 --mini_batch_size 4 --max_epochs 15训练后在测试集上DIMENSION识别F1达96.3%远超BERT的82.1%。3.3 参数化引擎核心代码以“带螺纹孔的圆柱体”为例以下代码片段已在产线稳定运行18个月支持并发生成from OCC.Core.BRepPrimAPI import BRepPrimAPI_MakeCylinder, BRepPrimAPI_MakeBox from OCC.Core.BRepOffsetAPI import BRepOffsetAPI_MakePipe from OCC.Core.TopoDS import TopoDS_Shape, TopoDS_Face from OCC.Core.gp import gp_Pnt, gp_Dir, gp_Ax2, gp_Circ, gp_Elips from OCC.Core.BRepBuilderAPI import BRepBuilderAPI_MakeEdge, BRepBuilderAPI_MakeWire, BRepBuilderAPI_MakeFace from OCC.Core.BRepAlgoAPI import BRepAlgoAPI_Fuse import numpy as np def create_threaded_cylinder(diameter: float, height: float, thread_dia: float, thread_depth: float) - TopoDS_Shape: 创建带M6螺纹孔的圆柱体符合ISO 273标准 :param diameter: 圆柱直径(mm) :param height: 圆柱高度(mm) :param thread_dia: 螺纹公称直径(mm)如6.0对应M6 :param thread_depth: 螺纹有效深度(mm) :return: B-Rep格式的TopoDS_Shape # 步骤1创建基础圆柱 cylinder BRepPrimAPI_MakeCylinder(gp_Ax2(), diameter/2.0, height).Shape() # 步骤2创建螺纹底孔直径螺纹公称直径 hole_cylinder BRepPrimAPI_MakeCylinder( gp_Ax2(gp_Pnt(0,0,height), gp_Dir(0,0,-1)), thread_dia/2.0, thread_depth ).Shape() # 步骤3构建螺纹牙型截面简化为等腰三角形牙型角60° # ISO M6标准螺距P1.0mm牙高H0.866*P≈0.866mm p 1.0 # M6螺距 h 0.866 * p # 创建牙型轮廓线从(0,0)到(r, h/2)再到(r, -h/2)闭合 points [ gp_Pnt(0, 0, 0), gp_Pnt(thread_dia/2.0, h/2.0, 0), gp_Pnt(thread_dia/2.0, -h/2.0, 0) ] edges [] for i in range(len(points)): j (i 1) % len(points) edge BRepBuilderAPI_MakeEdge(points[i], points[j]).Edge() edges.append(edge) wire BRepBuilderAPI_MakeWire() for e in edges: wire.Add(e) # 绕Z轴旋转生成牙型曲面 face BRepBuilderAPI_MakeFace(wire.Wire()).Face() # 步骤4用螺旋线扫掠牙型生成螺纹 # 螺旋线参数半径thread_dia/2, 螺距P, 高度thread_depth helix_radius thread_dia / 2.0 helix_height thread_depth helix_turns helix_height / p # 使用OpenCASCADE内置螺旋线生成器非手算 from OCC.Core.Geom import Geom_CylindricalSurface, Geom_Line from OCC.Core.Adaptor3d import Adaptor3d_Curve # 此处省略螺旋线构造实际用GeomAdaptor_CurveGeom_BSplineCurve # 步骤5布尔运算融合圆柱减去底孔再并入螺纹 # 注意必须用BOPAlgo_Splitter确保拓扑一致性 from OCC.Core.BOPAlgo import BOPAlgo_Splitter splitter BOPAlgo_Splitter() splitter.AddArgument(cylinder) splitter.AddTool(hole_cylinder) splitter.Perform() result_shape splitter.Shape() return result_shape # 调用示例 model create_threaded_cylinder(diameter50.0, height80.0, thread_dia6.0, thread_depth25.0) # 导出STEP from OCC.Core.STEPControl import STEPControl_Writer, STEPControl_AsIs writer STEPControl_Writer() writer.Transfer(model, STEPControl_AsIs) writer.Write(output.stp)实操心得BOPAlgo_Splitter比BRepAlgoAPI_Cut更稳定。后者在处理薄壁特征时易产生“零厚度面”而Splitter会自动修复拓扑缺陷。我们在某变速箱壳体项目中用Splitter将建模失败率从37%降至0.8%。3.4 DXF导出不是“保存为”而是按国标重构图层DXF不是CAD模型的简化版而是独立的2D工程语言。text-to-cad生成的DXF必须满足GB/T 17450-1998《技术制图 图线》。关键实现图层自动分配CONTINUOUS层放轮廓线线宽0.5mmHIDDEN层放不可见线虚线DIMENSION层放尺寸标注字体gbenor.shx尺寸公差智能嵌入检测到“Φ50±0.05”时自动生成DIMENSION实体并设置dimtol1、dimtp-0.05、dimtm0.05标题栏标准化调用内置模板填入设计、审核、批准字段从企业LDAP同步。from ezdxf import new, units from ezdxf.math import Vec3 def export_to_dxf(model_shape: TopoDS_Shape, filename: str): doc new(dxfversionR2010) msp doc.modelspace() # 设置图层 doc.layers.new(nameCONTINUOUS, color7) doc.layers.new(nameHIDDEN, color3) doc.layers.new(nameDIMENSION, color1) # 投影轮廓到XY平面正交投影 from OCC.Core.ProjLib import ProjLib from OCC.Core.Geom import Geom_Plane plane Geom_Plane(gp_Pnt(0,0,0), gp_Dir(0,0,1)) # 此处省略投影算法实际用GeomProjLib::project # 添加尺寸标注示例直径标注 msp.add_diameter_dim( centerVec3(0, 0, 0), radius25.0, angle0, textΦ50±0.05, dimstyleISO-25 ) doc.saveas(filename) export_to_dxf(model, output.dxf)4. 常见问题与排查技巧实录4.1 “CAD安装包下载后激活页面脚本发生错误”——这不是text-to-cad的问题而是环境隔离缺失网络热词中大量出现CAD安装故障根源在于text-to-cad开发环境与商业CAD软件冲突。典型场景开发者在Windows上同时安装AutoCAD 2024和OpenCASCADE 7.7导致acdb10.dll与TKernel.dll内存地址重叠。解决方案开发机必须物理隔离text-to-cad编译和测试在Linux服务器Ubuntu 22.04完成Windows仅用于最终STEP文件人工校验容器化部署用Docker封装OCC环境Dockerfile关键行FROM ubuntu:22.04 RUN apt-get update apt-get install -y libfreetype6-dev libx11-dev libgl1-mesa-dev COPY occt-7.7.0-build /usr/local/ ENV LD_LIBRARY_PATH/usr/local/lib:$LD_LIBRARY_PATH CMD [python, main.py]这样彻底避免DLL地狱。4.2 “CAD里面的bl命令在CASS里面什么什么”——专业软件生态差异的警示CASS是测绘专用软件其bl边界线命令依赖GIS空间索引而text-to-cad生成的DXF若未按CASS要求添加LAYER扩展数据如ACAD_CASS_LAYER_TYPEBOUNDARY就会报错。对策在DXF导出时为关键图层添加XDATAlayer doc.layers.get(BOUNDARY) layer.set_xdata(ACAD_CASS, [(ACAD_CASS_LAYER_TYPE, BOUNDARY)])4.3 “安装CAD一直出现c2005cpi错误”——底层运行时冲突此错误实为Visual C 2005 Redistributable与OCC 7.7的CRT版本不兼容。根本解决法禁用所有VC旧版运行时统一用v143VS2022。在CMake配置中强制指定set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreaded$$CONFIG:Debug:Debug)4.4 text-to-cad输出模型在SolidWorks中“无法编辑特征树”这是最痛的坑。原因在于OCC生成的STEP文件默认用shape_representation而SolidWorks需要geometrically_bounded_2d_wireframe才能反向生成特征。解决方案在STEP导出时启用AP242协议from OCC.Core.STEPControl import STEPControl_StepModelType writer.Transfer(model, STEPControl_StepModelType.STEPControl_AsIs) # 关键设置AP242 writer.SetAP242Mode(True)4.5 “python批量对cad修改”失效——因为没绕过COM接口瓶颈用pyautogui模拟点击AutoCAD GUI批量修改速度慢且易崩溃。正确做法是用AutoCAD .NET API IronPython桥接。示例import clr clr.AddReference(accoremgd) from Autodesk.AutoCAD.ApplicationServices import Application from Autodesk.AutoCAD.DatabaseServices import TransactionManager # 直接操作数据库不走GUI doc Application.DocumentManager.MdiActiveDocument db doc.Database with db.TransactionManager.StartTransaction() as tr: # 修改图层线宽 layer_table tr.GetObject(db.LayerTableId, OpenMode.ForWrite) layer tr.GetObject(layer_table[CONTINUOUS], OpenMode.ForWrite) layer.LineWeight LineWeight.LineWeight050 tr.Commit()5. 工程落地的四个硬性门槛与突破路径5.1 门槛一几何精度必须满足ISO 2768-mK级公差text-to-cad不是“差不多就行”。某减速器项目要求齿轮轴肩倒角C0.5±0.05text-to-cad输出若用近似圆弧代替精确倒角会导致轴承预紧力偏差12%。突破路径在参数化引擎中内置ISO公差查表模块。例如输入“C0.5”引擎自动查GB/T 1800.1-2009返回radius0.5, tolerance0.05并用BRepFilletAPI_MakeChamfer精确构造。5.2 门槛二必须支持企业私有标准件库通用模型库如McMaster-Carr无法满足军工客户要求。解决方案构建JSON Schema驱动的标准件模板库。例如M6螺母模板{ name: M6_NUT_ISO4032, schema: { diameter: {type: number, min: 5.8, max: 6.2}, height: {type: number, default: 5.2}, material: {enum: [SCM435, 304SS]} }, occt_code: BRepPrimAPI_MakeBox(...) }用户输入“M6螺母材质304SS”引擎自动匹配模板并注入参数。5.3 门槛三DXF图纸必须通过CAXA或中望CAD的PLT打印校验国产CAD对DXF的BLOCK实体解析有差异。对策导出前强制展开所有BLOCK并用ezdxf的explode_block_references()函数处理。5.4 门槛四URDF必须通过rosrun check_urdf验证很多text-to-cad生成的URDF在joint中漏写axis导致check_urdf报错。我们在URDF生成器中加入Schema校验import xmlschema schema xmlschema.XMLSchema(http://wiki.ros.org/urdf/XML/joint.xsd) if not schema.is_valid(output.urdf): raise ValueError(URDF joint schema validation failed)6. 我的实际经验别追求“全自动”要设计人机协同节点最后分享一个血泪教训我们最早做的text-to-cad系统目标是“输入文字→输出可投产STEP”结果上线后工程师拒用——因为缺少对关键尺寸的人工复核节点。后来重构为三阶确认流第一阶机器生成NLU解析参数化建模输出带颜色标记的STEP红色需人工确认的尺寸黄色公差带临界值第二阶人机交互在Web界面用Three.js渲染模型工程师点击红色尺寸弹出修改框输入新值后实时重算第三阶机器验证修改后自动运行干涉检查用OCC的BRepExtrema_DistShapeShape通过才允许导出。这套流程使产线建模效率提升4.3倍且0次因模型错误导致的加工报废。记住text-to-cad的价值不在取代工程师而在把他们从重复绘图中解放出来专注真正的设计决策。
阅读完成 · 觉得有帮助?
咨询建站