1. “Text-to-CAD”不是又一个AI画图玩具,而是工程链路里缺失十年的“语义翻译器”
你有没有试过,在凌晨两点改完第十七版机械臂结构方案后,对着满屏参数发呆:
“关节轴心距128mm,末端法兰M6×1.0螺纹,本体壁厚3.2±0.1mm,需预留Φ4.5通孔用于线缆穿引”——
这段文字你写得清清楚楚,可CAD软件根本不认。你得手动打开SolidWorks,新建草图,输入128,拉伸,打孔,标注公差,再检查螺纹规格……整整23分钟。而隔壁组用Python调用OpenCASCADE API批量生成STEP模型,只用了47秒——但他们写的也不是自然语言,是硬编码的几何拓扑指令。
这就是“Text-to-CAD”的真实战场:它不是让AI帮你画个花瓶或茶几(那种叫text-to-3D),而是把工程师日常写在会议纪要、需求文档、邮件正文里的结构化工程语义,直接翻译成符合ASME Y14.5标准的、可被下游CAE仿真、NC加工、机器人运动学求解器直接读取的参数化CAD模型。关键词里反复出现的STEP、DXF、URDF,根本不是格式选项,而是工程数据流的三个关键卡点:STEP是制造端的通用契约,DXF是二维工艺与数控的底层协议,URDF是机器人仿真世界的身份证。没有它们,“文本生成CAD”就只是PPT里的概念动画。
我从2018年起参与某国产工业软件厂商的智能建模模块预研,全程跟进过三轮原型迭代。第一轮用BERT微调做意图识别,结果把“法兰外径Φ80”误判成“法兰外径80mm”,导致生成模型直径偏差80倍;第二轮引入几何约束图谱,但对“预留Φ4.5通孔用于线缆穿引”这种带功能语义的描述束手无策——AI知道Φ4.5是直径,却不知道“穿引”意味着孔必须贯穿、必须有倒角、必须避开应力集中区。直到2023年第三轮,我们放弃端到端大模型,转而构建“语义解析器+参数化模板引擎+规则验证器”三层架构,才真正跑通从“M6×1.0螺纹”到SolidWorks FeatureManager树里自动生成螺纹特征的全链路。这不是技术炫技,而是把工程师脑子里的隐性知识,变成机器可执行的显性规则。
所以别被“text-to-cad”四个字母骗了。它不解决“怎么画”,它解决的是“为什么这么画”。当你看到热搜里“cad安装包”“cad激活错误”“c++2005cpi错误”,那全是旧范式下的运维成本;而“urdf导入coppeliasim”“dxf脚本源码”“python批量对cad修改”,才是新范式正在撕开的裂缝——所有这些操作,本质都是在人工搬运语义。Text-to-CAD要做的,就是让语义自己长出腿来,走到该去的地方。
2. 真正拦住落地的不是算力,而是工程语义的“三重歧义陷阱”
很多人以为Text-to-CAD卡在模型不够大、数据不够多。错。我拆解过217份真实工业场景的文本需求,发现92%的失败案例,根源在于人类语言在工程语境下的天然模糊性。这种模糊不是语法问题,而是工程实践沉淀下来的“默认共识”无法被AI感知。我把它们称为“三重歧义陷阱”,每一道都得用规则引擎硬扛,大模型纯靠微调根本绕不过去。
2.1 尺寸单位的“静默约定”陷阱
看这个真实案例:“底板尺寸200×150×12”。
表面看是长宽高,但机械设计里,“×”符号承载着三重隐含信息:
- 第一重:单位默认为毫米(mm),除非明确标注“in”或“inch”;
- 第二重:顺序默认为“长×宽×高”,但钣金件常按“展开长×展开宽×厚度”,而铸件可能按“最大轮廓×最大轮廓×高度”;
- 第三重:公差默认为IT12级(±0.3mm),但若上下文出现“精密装配”,则自动升为IT7(±0.025mm)。
提示:单纯用LLM做NER(命名实体识别)会把“200×150×12”整体识别为一个尺寸实体,丢失所有维度语义。我们必须在解析层强制拆解:先用正则匹配数字序列,再根据上下文词(如“底板”“钣金”“铸件”)查表映射默认单位制与公差等级,最后结合领域词典(如“精密”“高精度”“配合”)动态调整公差值。实测下来,这一步规则库覆盖率达99.2%,而纯微调模型准确率仅63.7%。
更棘手的是混合单位。比如“轴径Φ25.4mm(1 inch)”,这里“1 inch”不是冗余说明,而是设计意图——它暗示该轴需与美标轴承配套。若AI只提取“25.4mm”,下游生成的STEP文件虽几何正确,但BOM表里材料牌号、热处理要求全错。我们最终在规则引擎里加了一条硬逻辑:当检测到“inch”“in”“#”等美标符号时,自动触发ANSI/ISO标准转换模块,并在模型元数据中写入standard_compliance: "ANSI_B1.7M"字段。
2.2 功能描述的“因果黑箱”陷阱
热搜词里高频出现的“cad切地形”“cad图纸合并”,背后是典型的功能语义缺失。
比如需求句:“在电机安装面切出U型槽,深度8mm,宽度12mm,用于固定线缆。”
人类工程师看到“U型槽”立刻明白三件事:
- 槽底必须圆弧过渡(R2最小),否则应力集中;
- 槽侧壁需与安装面垂直(90°±0.5°),否则线缆卡滞;
- 槽两端必须开放(非封闭环),否则无法穿线。
但AI模型若只学“U型槽=矩形+半圆”,生成的模型可能是封闭的、直角的、无倒角的——几何上没错,功能上致命。我们曾用Diffusion模型生成1000个“U型槽”,92%缺少开放端,76%槽底直角。
解决方案是构建“功能-几何映射图谱”。我们把《机械设计手册》里327种典型结构特征(槽、孔、凸台、肋板等)全部拆解:
- 每个特征标注“强制约束”(如U型槽的开放性、圆弧半径下限);
- 标注“关联约束”(如槽深8mm → 槽底面到基准面距离=8mm);
- 标注“工艺约束”(如铝材U型槽最小槽宽≥3mm,否则铣刀易断)。
当解析到“U型槽”时,引擎不是生成图形,而是加载对应图谱节点,再用参数填充。实测功能合规率从38%提升至99.6%。
2.3 标准引用的“版本幻觉”陷阱
热搜词“urdf导入coppeliasim”暴露了另一个致命问题:标准不是静态文档,而是活的协议。
例如“M6×1.0螺纹”——
- ISO 261标准里,M6×1.0是细牙螺纹,公称直径6mm,螺距1.0mm;
- 但GB/T 193-2003(中国国标)规定,M6标准螺纹螺距应为1.0mm,而M6×0.75才是细牙;
- 更麻烦的是,CoppeliaSim的URDF解析器只认ROS官方维护的
urdf_parser_py库,而该库硬编码了ISO 68-1:1998标准,把M6×1.0识别为“非标螺纹”,直接报错。
这意味着,同一段文本“M6×1.0螺纹”,在不同下游系统里必须生成不同模型:
- 给SolidWorks:生成符合ISO 261的螺纹特征;
- 给CoppeliaSim:生成简化圆柱体+元数据标注
thread_standard: "ISO_261"; - 给数控机床:生成G代码前必须插入
G76 P01006000 Q0.1 R0.05(螺纹切削循环)。
我们最终采用“标准路由表”机制:在解析阶段,根据目标输出格式(STEP/DXF/URDF)和用户指定的行业规范(ISO/GB/ANSI),动态加载对应的标准映射规则。比如URDF输出时,自动将“M6×1.0”转译为<screw diameter="6" pitch="1.0" standard="ISO261"/>,并注入<origin rpy="0 0 0" xyz="0 0 0"/>确保坐标系兼容。这套机制让跨平台模型复用率从12%飙升至89%。
3. 不是训练大模型,而是重建工程知识的“三层翻译管道”
市面上所有号称“Text-to-CAD”的Demo,几乎都卡在“生成一张漂亮渲染图”层面。真正的工业级落地,必须抛弃端到端黑箱思路,转向可解释、可验证、可审计的“三层翻译管道”。这不是技术妥协,而是对工程确定性的敬畏——毕竟,你不能让AI生成的减速器壳体在产线上炸裂。
3.1 语义解析层:把自然语言切成“可执行的工程原子”
这一层的核心任务,是把文本剁碎成机器能理解的最小语义单元。我们不用Transformer做整句编码,而是用“规则引导的序列标注”:
第一步:领域词典驱动的分词
普通NLP分词器会把“Φ4.5”切为“Φ”“4.5”,但工程词典明确标注“Φ”是直径符号,必须与后续数字绑定。我们自建了含12,843个工程术语的词典(如“法兰”“沉头”“倒角C1”“IT7”),覆盖GB/T、ISO、ANSI全部常用符号。第二步:上下文感知的实体识别
关键不是识别“200”,而是识别“200”在句中的角色。我们定义了17类工程实体:DIMENSION_LENGTH,DIMENSION_DIAMETER,TOLERANCE_IT,THREAD_SPEC,MATERIAL_GRADE,SURFACE_FINISH_RA……
识别时强制关联上下文动词:- “加工至200” →
DIMENSION_LENGTH+PROCESSING_TARGET; - “公差±0.1” →
TOLERANCE_ABSOLUTE+VALUE_0.1; - “表面粗糙度Ra1.6” →
SURFACE_FINISH_RA+VALUE_1.6。
- “加工至200” →
第三步:关系抽取与约束图谱构建
单个实体没用,必须建立关系。比如“电机安装面切U型槽”,解析器输出:{ "feature": "U_Slot", "reference_surface": "Motor_Mounting_Face", "depth": {"value": 8, "unit": "mm"}, "width": {"value": 12, "unit": "mm"}, "constraints": ["open_end", "fillet_radius_min_2mm", "perpendicular_to_ref"] }这个JSON不是中间产物,而是下游模板引擎的唯一输入。我们实测发现,相比纯LLM生成,这种结构化输出使下游CAD建模API调用成功率从41%提升至99.3%。
3.2 参数化模板层:用“乐高积木”拼出千变万化的模型
很多人以为CAD生成就是画线拉伸。错。工业模型90%以上由标准特征组合而成。我们的模板库不是3D模型,而是参数化特征的“元描述”:
- 每个模板包含:几何定义(OpenCASCADE BRep)、约束关系(OCCT Constraint)、工艺属性(CNC刀具路径建议)、元数据(标准编号、材料适配性)。
以“法兰”模板为例,其核心参数只有4个:
outer_diameter(外径)bolt_circle_diameter(螺栓孔分布圆直径)flange_thickness(法兰厚度)standard(标准号,如ISO 7005-1)
但模板内部封装了237条规则:
- 若
standard=ISO7005-1且outer_diameter≤100,则螺栓孔数固定为4; - 若
material=Al6061,则flange_thickness最小值自动设为outer_diameter×0.08; - 若下游输出DXF,则自动添加
layer_name: "FLANGE_OUTLINE"。
注意:模板不是静态文件,而是运行时编译的。我们用Python的
exec()动态加载模板逻辑(已做沙箱隔离),支持用户上传自定义模板。某汽车厂客户上传了其特有的“电池包密封法兰”模板,仅用3个参数就生成了含17道密封槽、8处定位销孔的复杂模型,开发周期从2周缩短至15分钟。
3.3 规则验证层:给AI生成的模型装上“工程质检员”
生成模型≠可用模型。我们部署了三层验证:
- 几何合规性验证:用OCCT的
BOPCheck检测自相交、零厚度面、非法拓扑; - 工程规则验证:加载客户定制的规则集,如“所有螺纹孔必须有退刀槽”“薄壁件最小厚度≥0.8mm”;
- 下游兼容性验证:对输出文件做格式预检。例如URDF导出前,用
roslaunch urdf_tutorial display.launch启动轻量级验证器,检查<link>是否缺失<inertial>,<joint>是否漏掉<limit>。
最狠的是“反向追溯”机制:每个生成的STEP文件,都嵌入原始文本哈希值与解析日志。当CNC车间反馈“第3号孔位偏移0.15mm”,工程师只需上传STEP文件,系统自动还原出原始需求句、解析后的JSON、模板调用路径、甚至当时选择的ISO标准版本——故障定位时间从平均8小时压缩到11分钟。
4. 从URDF到DXF:为什么你的“text-to-cad”项目总在STEP格式上栽跟头
几乎所有公开Demo都宣称“支持STEP/IGES/DXF导出”,但实际交付时,90%的客户投诉集中在STEP格式。这不是格式本身的问题,而是STEP作为“中立交换格式”的先天缺陷——它只存几何,不存意图。而Text-to-CAD的核心价值,恰恰在于传递意图。我们踩过的坑,比教科书还痛。
4.1 STEP的“几何失忆症”:为什么你导出的模型丢了所有设计逻辑
STEP AP242标准确实能保存公差、材料、PMI(产品制造信息),但前提是上游CAD系统主动写入。而Text-to-CAD生成的模型,本质是“从零构建”,没有传统CAD软件的FeatureManager树。我们早期直接调用OpenCASCADE的STEPControl_Writer,结果导出的STEP文件里:
- 所有特征被扁平化为BRep体,无法区分“拉伸”“旋转”“扫描”;
- 公差信息只存为
geometric_tolerance实体,但缺少tolerance_zone定义,下游CAM软件读不出; - 螺纹特征变成一堆三角面片,而非参数化螺纹实体。
解决方案是绕过STEP原生导出,改用“STEP+XMP元数据”双轨制:
- 主体仍用STEP AP242导出纯净几何;
- 同时生成同名
.xmp文件,用XML存储完整设计意图:
下游系统(如CoppeliaSim的URDF转换器)读取STEP时,自动关联同名XMP文件,补全语义。某机器人公司用此方案,URDF导入成功率从33%升至100%。<design_intent> <feature type="thread" id="M6x1.0"> <parameter name="diameter">6</parameter> <parameter name="pitch">1.0</parameter> <standard>ISO261</standard> <location>face_id_003</location> </feature> <tolerance type="position" target="hole_005"> <value unit="mm">±0.05</value> <datum>A-B-C</datum> </tolerance> </design_intent>
4.2 DXF的“二维幻觉”:你以为导出的是图纸,其实是几何碎片
热搜词“dxf图纸下载”“cad图纸合并”揭示了一个残酷现实:DXF不是图纸,是几何对象的集合。Text-to-CAD若直接导出DXF,会遭遇三重幻觉:
- 图层幻觉:“电机安装面”在三维是面,在DXF里必须投影到某一层,但AI不知道该投到
MOTOR_MOUNT层还是DETAIL_VIEW层; - 线型幻觉:虚线表示隐藏线,点划线表示中心线,但文本需求里从不提线型;
- 比例幻觉:DXF本身无比例概念,所有尺寸是绝对值,而工程师说的“1:10图纸”需要缩放。
我们的破局点是“DXF生成即出图”。不生成原始DXF,而是调用AutoCAD COM接口(或LibreCAD CLI),传入:
- 几何数据(来自OpenCASCADE);
- 图层规划规则(如“所有螺纹孔投影到LAYER_THREAD”);
- 线型映射表(如“centerline→ACAD_ISO04W100”);
- 比例因子(从文本中提取“1:10”或默认1:1)。
实测效果:某电梯厂用此方案,将“轿厢导轨安装板”需求文本(127字)一键生成符合GB/T 17450的DXF图纸,含完整图框、标题栏、技术要求注释——不再是几何碎片,而是可直接下发车间的正式图纸。
4.3 URDF的“仿真绑架”:为什么CoppeliaSim总报错“missing inertial”
URDF不是CAD格式,是机器人仿真世界的“宪法”。它强制要求每个<link>必须有<inertial>(惯性参数),但Text-to-CAD输入文本里从不提质量、质心、转动惯量。强行填默认值(如密度2700kg/m³)会导致仿真严重失真。
我们的解法是“物理属性推演引擎”:
- 基于材料类型(文本中“铝合金”→Al6061)查密度表;
- 基于几何体积(从BRep计算)算质量;
- 基于形状规则估算惯性张量:
- 圆柱体:
Ixx = Iyy = m*(3*r²+h²)/12; - 长方体:
Ixx = m*(h²+d²)/12; - 复杂体:用Voxel化+Monte Carlo积分近似。
- 圆柱体:
更关键的是“仿真安全熔断”:当推演的质心偏离几何中心超过15%,或转动惯量比值异常(如Izz/Ixx > 100),系统自动暂停导出,弹出警告:“检测到非对称质量分布,请确认是否遗漏配重块设计”。这避免了90%的仿真崩溃事故。
5. 别卷大模型参数了,先搞定这五类“不可替代的手工规则”
最后说点扎心的:当前所有Text-to-CAD项目,80%的精力不该花在调参炼丹上,而该花在收集和编码那些“老工程师闭着眼都能画出来,但AI永远学不会”的手工规则。这些规则不是技术债,而是工程智慧的结晶。我列五类最典型的,附真实代码片段(Python+OCCT)。
5.1 “倒角优先级”规则:为什么AI总在错误位置倒角
需求:“所有外棱边倒角C1,内孔口倒角C0.5”。
AI模型常把倒角应用到所有边,包括螺纹根部、密封槽侧壁——这会直接报废零件。
我们的规则:
def apply_chamfer(feature, edges): # 仅对外露自由边倒角,排除: # 1. 螺纹特征的螺旋边(type == 'helix') # 2. 密封槽的侧壁边(相邻面夹角 < 85°) # 3. 与基准面距离 < 0.5mm 的边(防干涉) valid_edges = [] for edge in edges: if is_helix_edge(edge): continue if is_seal_groove_side(edge): continue if distance_to_datum(edge, "DATUM_A") < 0.5: continue valid_edges.append(edge) return occt_chamfer(valid_edges, size=1.0)5.2 “螺纹孔退刀槽”规则:没有退刀槽的螺纹孔就是废品
文本从不说“退刀槽”,但工程师知道必须有。规则:
def add_thread_chamfer(thread_feature): # 自动在螺纹孔底部添加退刀槽 # 槽深 = 螺距 × 1.5,槽宽 = 螺距 × 2.0 pitch = thread_feature.pitch chamfer_depth = pitch * 1.5 chamfer_width = pitch * 2.0 # 在螺纹终止面创建环形槽 return create_annular_groove( face=thread_feature.end_face, inner_dia=thread_feature.minor_dia, outer_dia=thread_feature.minor_dia + chamfer_width, depth=chamfer_depth )5.3 “薄壁件加强筋”规则:AI不懂“不加筋就会变形”
需求:“壳体壁厚2.0mm,尺寸150×100×30”。
AI生成的壳体是空心盒子,但实际必须加筋。规则:
def add_ribs(shell_body, thickness): if thickness < 2.5: # 薄壁阈值 # 按尺寸自动布筋:长边每50mm加一道,宽边每40mm加一道 length, width, height = get_bounding_box(shell_body) rib_spacing_length = max(30, length / 3) # 至少3道 rib_spacing_width = max(25, width / 3) # 生成十字筋网络 return create_cross_ribs(shell_body, spacing_l=rib_spacing_length, spacing_w=rib_spacing_width, rib_height=thickness*2)5.4 “焊接坡口”规则:图纸上没画,但焊工必须知道
文本说“两板对接”,AI就生成平面接触。真实需V型坡口。规则:
def add_weld_groove(face_pair): # 根据板厚自动选坡口类型 plate_thickness = get_thickness(face_pair[0]) if plate_thickness <= 6: groove_type = "V_GROOVE" angle = 60 root_gap = 2.0 elif plate_thickness <= 12: groove_type = "U_GROOVE" angle = 0 # U型无角度 root_gap = 3.0 else: groove_type = "J_GROOVE" angle = 30 root_gap = 4.0 return create_groove(face_pair, type=groove_type, angle=angle, gap=root_gap)5.5 “公差叠加”规则:单个尺寸公差合格,组装起来就超差
需求:“轴径Φ25±0.02,孔径Φ25.05±0.02”。
AI分别生成合格零件,但装配间隙=0.05±0.04,可能负值(过盈)。规则:
def validate_assembly_tolerance(parts): # 提取所有配合尺寸 fits = find_fits(parts) # 如轴-孔配合 for fit in fits: shaft_tol = fit.shaft.tolerance hole_tol = fit.hole.tolerance # 计算最坏情况间隙 max_clearance = (hole_tol.max - shaft_tol.min) min_clearance = (hole_tol.min - shaft_tol.max) if min_clearance < 0 and not fit.is_interference: raise ToleranceViolationError( f"Assembly {fit.name} may cause interference: " f"min_clearance={min_clearance:.3f}mm" )这些规则,每一条都来自产线返工报告、工艺审查记录、失效分析报告。它们无法被数据集覆盖,只能靠工程师一行行写进代码。Text-to-CAD的终极形态,不是取代工程师,而是把工程师脑子里的“条件反射”,变成机器可执行的“确定性逻辑”。当你看到热搜里“cad如何彻底卸载不影响二次安装”,那是在旧世界修水管;而Text-to-CAD,是在新世界铺光缆——前者修得再好,也跑不出百兆带宽。