1. 为什么“AI + CAD”的 Demo 看起来都很美
过去两年,我陆陆续续接触过十几个号称“AI 自动画图”“AI 读图改图”的项目,有创业团队做的 SaaS,也有大厂内部孵化的小工具,还有开源社区里用 Python 拼出来的原型。几乎每一个在演示阶段都能让人眼前一亮:上传一张户型图,几秒钟后吐出带墙线、门窗、标注的 DXF;或者丢进去一张机械零件照片,AI 自动识别轮廓并生成可编辑的草图。但真正拿到工程场景里跑一遍,十有八九会卡在某个环节,最后不了了之。
这个现象背后其实有一个很朴素的道理:CAD 不是画图工具,它是工程语义的载体。一张 DWG 图纸里,一条线不只是线,它可能是墙、可能是梁、可能是管道中心线,还可能是标注引线。图层、块、属性、扩展数据、布局空间、外部参照,这些东西共同构成了一套工程语言。AI 在图像层面看到的像素和矢量,跟工程师脑子里的“构件”之间,隔着一整套语义映射。Demo 之所以好看,是因为它只处理了最表层的那一步——把像素变成线,或者把线变成另一堆线。而工程走不通,是因为后面还有九十九步没人愿意在演示里讲。
我写这篇东西,不是要唱衰 AI 在 CAD 领域的应用,恰恰相反,我认为这个方向迟早会跑通,只是现在大量团队把顺序搞反了。他们先做一个炫酷的端到端模型,再回头找场景,结果发现每个真实场景都有一堆“脏活”需要处理。正确的路径应该是先把工程数据链路打通,再把 AI 塞进合适的环节。下面我就按自己踩过的坑和见过的案例,把这件事拆开讲清楚。
2. 拆解“AI + CAD”的真实技术链路
2.1 从一张图纸到可计算数据,中间隔了什么
很多人以为读 DWG 就是调个库的事。实际上,光是“把图纸读进来”这一步,就足够劝退一半的团队。DWG 是闭源二进制格式,官方 SDK 授权费用不低,开源方案里 LibreDWG 的兼容性一直是个玄学问题,ODA(Open Design Alliance)的 Teigha 相对稳,但也不是免费午餐。更麻烦的是,即使你成功读出了实体,得到的也只是一堆 LINE、LWPOLYLINE、INSERT、TEXT 的集合,没有任何工程含义。
我拿一个实际例子说明。某次我尝试用 Python 的 ezdxf 库读取一张建筑平面图,想统计墙体长度。读进来之后发现,墙线分布在三个图层上,有的用 LINE 画,有的用 LWPOLYLINE 画,还有一部分被做成了块参照,块里面又嵌套了块。更离谱的是,有些墙线在布局空间里,模型空间只放了一个视口。如果你只是遍历模型空间的实体,统计出来的长度连一半都不到。这就是典型的“Demo 能跑,工程跑不通”——演示时用的图纸是精心清理过的,真实图纸是十年积累下来的屎山。
所以第一步的核心不是 AI,而是图纸规范化。你得先有一套规则,把不同来源、不同习惯的图纸统一成一种可计算的结构。这套规则包括:图层命名约定、实体类型优先级、块展开策略、布局与模型空间的取舍、标注与几何的分离等等。这些东西听起来很土,但它们是后面所有 AI 环节的地基。
2.2 DXF、DWG、FreeCAD 各自扮演什么角色
在讨论技术选型时,经常有人问:我到底该用 DXF 还是 DWG?FreeCAD 能不能替代 AutoCAD?我的回答通常是:看你在链路的哪一段。
DXF 是文本格式,解析起来友好得多,适合做数据交换和算法验证。但 DXF 有个致命问题——它承载不了 DWG 里的很多高级特性,比如动态块、约束、部分扩展数据。如果你用 DXF 做中间格式,信息丢失是必然的。我一般建议在原型阶段用 DXF 快速跑通流程,但一旦进入工程化,必须直面 DWG。
FreeCAD 的定位不太一样。它是一个开源参数化建模工具,有自己的文档对象模型。很多人想用 FreeCAD 做“AI 生成 CAD”的底座,因为它的 Python API 足够开放。这个思路有道理,但要注意:FreeCAD 的几何内核是 OpenCASCADE,而主流 CAD 的几何内核是 Parasolid 或 ACIS,两者在曲面精度和布尔运算的鲁棒性上有差距。如果你做的是建筑平面这种二维为主的东西,FreeCAD 够用;如果是复杂机械装配,迁移成本会很高。
下面这张表是我个人对几个关键环节的选型建议,仅供参考:
| 环节 | 推荐方案 | 备选方案 | 主要坑点 |
|---|---|---|---|
| DWG 读取 | ODA SDK | LibreDWG | 授权费用、版本兼容 |
| DXF 解析 | ezdxf | dxfgrabber | 块嵌套、扩展数据丢失 |
| 几何内核 | OpenCASCADE | Parasolid | 曲面精度、布尔稳定性 |
| 参数化建模 | FreeCAD | RhinoCommon | 生态成熟度、API 稳定性 |
| AI 推理 | 本地 ONNX | 云端 API | 数据安全、延迟 |
2.3 AI 在链路里到底该放在哪
这是最核心的问题。我见过太多团队把 AI 放在最前面——输入一张图片,直接输出 DWG。这个方案在学术论文里很常见,在工程里几乎不可行。原因很简单:图像到矢量的转换误差,在后续的尺寸标注、图层归类、块替换环节会被无限放大。你生成一条线偏了 2 个像素,到了施工图阶段可能就是 20 毫米的偏差。
我的观点是,AI 应该放在语义理解和决策环节,而不是几何生成环节。具体来说,有几个位置是 AI 真正能发挥价值的:
第一个位置是图纸分类与信息抽取。给定一张扫描版或 PDF 图纸,AI 可以识别标题栏、图号、比例、材料表,把这些结构化信息抽出来。这个任务对精度要求相对宽松,错了可以人工复核,但能省掉大量录入工作。
第二个位置是构件识别与图层归类。把几何实体喂给一个分类模型,判断它是墙、柱、梁、门窗还是标注。这个任务的关键是特征工程——除了几何位置,还要把图层名、线型、颜色、块名作为特征输入。纯靠几何的模型准确率很难超过 70%,加上工程特征后能到 90% 以上。
第三个位置是参数推荐与合规检查。比如根据房间功能推荐门窗尺寸,或者检查图纸是否符合制图标准。这类任务本质上是规则引擎加 AI 辅助,AI 负责处理模糊边界,规则负责兜底。
至于“AI 一键生成施工图”这种目标,我认为在可见的未来都不现实。不是模型能力不够,而是工程责任无法归属。一张图纸是要盖楼的,出了问题谁负责?这个问题不解决,AI 就只能做辅助。
3. 实操:从 DWG 到可计算数据的完整流程
3.1 环境准备与工具链搭建
我以 Python 技术栈为例,讲一套我自己用过的流程。这套流程不依赖商业软件,适合做原型验证。
首先装依赖。ezdxf 是必须的,用来处理 DXF;如果要做几何运算,shapely 和 numpy 是标配;如果要可视化调试,matplotlib 或者 pyvista 都行。如果你有 ODA 的授权,可以用它的 Python binding 直接读 DWG,否则先用 ODA File Converter 把 DWG 转成 DXF 再处理。
pip install ezdxf shapely numpy matplotlib这里有个细节:ezdxf 的版本更新比较快,不同版本对块和布局的处理有差异。我建议锁定一个稳定版本,比如 1.1.x,不要盲目追新。另外,如果你处理的是中文图纸,注意 DXF 的编码问题,有些老图纸用的是 GBK 或者 ANSI,读进来会乱码,需要手动指定编码。
3.2 读取与规范化图纸数据
下面这段代码是我常用的一个模板,用来把 DXF 里的实体统一提取成带图层信息的几何对象。注意我做了几件事:展开块参照、处理布局空间、过滤非几何实体。
import ezdxf from ezdxf import bbox def extract_entities(dxf_path): doc = ezdxf.readfile(dxf_path) msp = doc.modelspace() entities = [] for entity in msp: dxftype = entity.dxftype() layer = entity.dxf.layer if dxftype == 'LINE': start = entity.dxf.start end = entity.dxf.end entities.append({ 'type': 'line', 'layer': layer, 'coords': [(start.x, start.y), (end.x, end.y)] }) elif dxftype == 'LWPOLYLINE': points = [(p[0], p[1]) for p in entity.get_points()] entities.append({ 'type': 'polyline', 'layer': layer, 'coords': points, 'closed': entity.closed }) elif dxftype == 'INSERT': # 展开块参照 for virtual in entity.virtual_entities(): # 递归处理,这里简化处理 pass return entities这段代码只是骨架,实际用的时候要处理很多边界情况。比如块参照的缩放和旋转、嵌套块的递归展开、属性块的属性提取、多段线的凸度(bulge)等等。我踩过最大的坑是块参照的坐标系变换——块定义里的坐标是相对于块插入点的,展开时必须应用插入点的平移、旋转和缩放。如果漏了旋转,整个图纸会歪掉。
3.3 图层语义映射与构件识别
拿到几何数据后,下一步是给每个实体打上工程标签。这一步我建议先用规则做一版,再用 AI 补充。
规则部分很简单:建一个图层名到构件类型的映射表。比如图层名包含“WALL”或“墙”的,标记为墙体;包含“DOOR”或“门”的,标记为门;包含“DIM”或“标注”的,标记为标注。这个映射表需要针对不同设计院的习惯做调整,没有通用解。
AI 部分我试过用随机森林和轻量级神经网络。特征包括:实体类型、图层名、线宽、颜色、长度、闭合性、相邻实体数量、所在位置(用网格编码)。训练数据需要人工标注几千个实体,工作量不小,但一旦训好,对新图纸的泛化能力比纯规则强很多。
这里有个经验:不要试图用一个模型识别所有构件。墙、门、窗、标注的几何特征差异很大,分开建模效果更好。我一般会训三个模型:一个识别线性构件(墙、梁、管道),一个识别闭合构件(房间、柱、设备),一个识别注释类实体(标注、文字、符号)。
3.4 从识别结果到可计算模型
识别完之后,要把这些带标签的几何转成可计算的工程模型。比如墙体,需要把中心线加厚度转成多边形;门窗需要定位到墙上的开口;房间需要从墙线围合出闭合区域。
这一步的难点是拓扑关系重建。图纸里的线是断开的,你需要判断哪些线该连起来,哪些线是交叉但不相连。我用的方法是先做线段合并(端点距离小于阈值的合并),再做多边形化(用 shapely 的 polygonize)。但 polygonize 对自相交和悬挂边很敏感,需要先做清理。
from shapely.ops import polygonize, unary_union from shapely.geometry import LineString def build_rooms(wall_lines, tolerance=0.01): # 合并端点相近的线 merged = unary_union([LineString(line) for line in wall_lines]) # 多边形化 polygons = list(polygonize(merged)) # 过滤面积过小的 rooms = [p for p in polygons if p.area > 1.0] return rooms这段代码看起来简单,实际跑起来问题很多。比如墙线有厚度,中心线和边线混在一起,polygonize 会生成一堆碎片。我的做法是先用中心线做房间划分,再把厚度作为属性附加到房间边界上。这样既保证了拓扑正确,又保留了工程信息。
4. 工程落地中最容易踩的五个坑
4.1 图纸质量参差不齐,预处理比算法更重要
我做过一个统计,在一个中型设计院的历史图纸库里,能直接用于算法处理的图纸不到 20%。剩下的 80% 有各种问题:图层混乱、块参照爆炸、标注和几何混在一起、布局空间和模型空间不一致、外部参照丢失、字体缺失导致文字变成问号。
这意味着什么?意味着你花三个月训的模型,可能因为输入图纸的图层名跟训练集不一样,准确率直接掉一半。所以我现在做项目,第一件事不是搭模型,而是搭图纸质量评估和预处理流水线。这条流水线包括:图层规范化、块展开、外部参照绑定、文字编码修复、重复实体去重、孤立实体清理。这些东西没有技术含量,但决定了项目能不能走下去。
提示:预处理阶段一定要保留原始图纸的备份,所有操作在副本上进行。我见过有人直接改源文件,结果改坏了没法回滚。
4.2 数据标注成本被严重低估
做 AI 的人习惯性地低估标注成本。在图像领域,标一张图可能几分钟;在 CAD 领域,标一张图纸可能需要几个小时。因为你要标的不是“这是不是墙”,而是“这条线是墙的中心线还是边线”“这个块是门还是窗”“这个标注属于哪个构件”。
我试过用众包标注,效果很差,因为标注员没有工程背景,根本分不清剪力墙和填充墙。后来改成让设计院实习生标,成本上去了,但质量有保障。我的建议是:标注工作必须由懂工程的人做,而且要在项目早期就启动。不要等模型搭好了再找数据,那时候时间已经不够了。
4.3 几何精度与 AI 容错的矛盾
AI 模型天然有误差,分类可能错,回归可能有偏差。但 CAD 对精度是零容忍的。一条墙线偏了 5 毫米,在图纸上可能看不出来,但到了算量阶段就是真金白银的差异。
解决这个矛盾的办法是把 AI 的输出限制在离散决策上,而不是连续值。比如让 AI 判断“这条线属于哪个图层”,而不是“这条线的精确坐标是多少”。坐标由原始几何保证,AI 只负责语义标签。这样即使 AI 错了,几何精度也不受影响,人工复核也容易发现。
4.4 工具链的版本地狱
CAD 生态的版本兼容性是个噩梦。AutoCAD 每年一个新版本,DWG 格式每年微调,第三方库跟进速度参差不齐。我遇到过 ezdxf 读某个版本的 DXF 时,多段线的凸度解析错误,导致圆弧变成直线。也遇到过 ODA 转换器把动态块转成静态块后,属性丢失。
我的应对策略是:锁定工具链版本,建立回归测试集。选一套经过验证的版本组合,不要轻易升级。同时准备一批覆盖各种情况的测试图纸,每次升级前跑一遍,确认没有回归问题再上。
4.5 工程责任与 AI 可解释性
最后一个坑不是技术问题,是责任问题。设计院用 AI 辅助出图,出了问题谁负责?如果 AI 建议的标注错了,审核人没看出来,责任算谁的?这个问题不解决,AI 就很难进入核心生产环节。
我见过的可行做法是:AI 只做建议,不做决定。所有 AI 输出都以“待确认”状态呈现,由工程师逐条确认后才写入图纸。这样责任链条清晰,AI 的角色是提效工具,不是决策主体。同时,AI 的每个建议都要附带依据,比如“根据图层名 WALL 和线宽 0.3,判断为剪力墙”,这样工程师才能快速判断对错。
5. 常见问题速查与排查思路
5.1 图纸读取类问题
| 现象 | 可能原因 | 排查方法 | 解决思路 |
|---|---|---|---|
| 读进来实体数量为零 | 文件是 DWG 不是 DXF | 检查文件头 | 先用转换器转 DXF |
| 中文图层名乱码 | 编码不匹配 | 查看原始编码 | 指定 GBK 或 CP936 |
| 块参照位置偏移 | 坐标系变换错误 | 对比插入点 | 检查旋转和缩放矩阵 |
| 布局空间实体丢失 | 只遍历了模型空间 | 检查 layouts | 遍历所有布局或绑定视口 |
| 多段线圆弧变直线 | 凸度未处理 | 检查 bulge 值 | 用 ezdxf 的 bulge 转换 |
5.2 构件识别类问题
识别准确率上不去,先别急着换模型。我一般按这个顺序排查:第一,看训练集和测试集的图层分布是否一致,如果不一致,说明模型在过拟合特定图层名;第二,看特征里有没有包含位置信息,纯几何特征对相似形状的构件区分度不够;第三,看标注质量,如果标注本身有歧义,模型学出来也是乱的。
还有一个容易被忽略的点:类别不平衡。图纸里墙线可能占 60%,门只占 5%。如果不做重采样或加权,模型会倾向于把所有东西都预测成墙。我通常用 focal loss 或者简单的类别权重来缓解这个问题。
5.3 几何处理类问题
多边形化失败是最常见的问题。原因通常是线没有闭合,或者有自相交。我的排查步骤是:先用 shapely 的is_valid检查每条线,找出无效几何;然后看端点距离,如果两个端点距离小于容差但没合并,说明合并阈值设大了或小了;最后看是否有悬挂边,悬挂边会导致 polygonize 生成不了闭合区域。
另一个坑是精度问题。浮点数运算在 CAD 里很容易出问题,尤其是坐标值很大的时候。我一般会把图纸坐标平移到原点附近再做运算,处理完再平移回去。这样能避免很多精度导致的拓扑错误。
6. 我对这个方向的一些个人判断
做了这么多尝试,我现在的判断是:AI 在 CAD 领域的落地,短期内不会以“替代设计师”的形式出现,而是以“图纸数据化引擎”的形式存在。也就是说,AI 的价值不在于生成图纸,而在于把存量图纸变成结构化数据,让这些数据能被检索、被计算、被复用。
这个方向的市场其实很大。设计院、施工单位、运维单位手里都有海量图纸,这些图纸目前基本是死数据,只能靠人看。如果能用 AI 把它们变成可查询的数据库,价值是巨大的。而且这个任务对精度的要求相对宽松,错了可以人工修正,不像自动出图那样零容错。
技术路线上,我倾向于“小模型 + 强规则 + 人工复核”的组合,而不是追求端到端的大模型。工程领域的数据量不足以训练一个通用大模型,但针对特定构件类型的小模型,几千个样本就能达到可用水平。规则负责兜底和保证一致性,人工负责处理边界情况。这个组合听起来不性感,但能落地。
最后说一个我自己的体会:在这个领域,懂 CAD 比懂 AI 更重要。我见过太多 AI 背景的团队,模型调得很漂亮,但连图层和块的关系都搞不清楚,做出来的东西自然没法用。反过来,懂 CAD 的人如果愿意花时间学一点 AI,往往能做出更实用的工具。如果你正在考虑进入这个方向,我建议先把 DWG 格式规范读一遍,把 ODA 的文档翻一翻,再动手写代码。磨刀不误砍柴工,这句话在工程软件领域尤其成立。