不需要主标题直接从二级标题开始正文如下。开工前我先说几句实在话。text-to-cad这个话题我在社区里关注了挺久最近终于抽时间把一条完整链路跑通了。说白了它就是让计算机听懂人话把“帮我画一个直径50的法兰盘四个均布孔”这种自然语言描述直接变成一张能交付、能下料、能归档的CAD图纸。这听起来有点科幻但落到AutoCAD的二次开发里其实是一套很清晰的技术栈自然语言解析加上参数化绘图命令再加上规则引擎。这篇文章把我自己的实现思路、踩坑记录和完整代码示例都放出来给想搞CAD自动化、批量改图、图纸规范化的人做个参考。不管你是刚入门的CAD制图新手还是天天跟图纸打交道的工程师这套思路都能帮你省下不少重复劳动。1. 先想明白text-to-cad 到底在解决什么问题1.1 别再拿设计师当“人肉翻译器”我见过太多团队里这样的场景工艺工程师拿着一个零件需求跑到设计部说“我要一个直径63的圆盘上面六个孔孔距52倒角C2”设计师听完在CAD里一通操作十分钟后图纸出来了。听起来没什么问题可如果把同样的话换成一百个零件十种规格甚至每周都要来一遍呢设计师就成了人肉翻译器把文字需求翻译成图形指令这活儿本质上是最没技术含量、却最消耗时间的部分。text-to-cad想干掉的就是这个翻译环节。它的目标不是让设计师失业而是把那些“听得懂人话、画得出图纸”的重复劳动提取出来变成一套可复用的程序。对于标准件、常用件、系列化设计来说这件事的价值非常大。我实际测下来一个熟练的设计师手工画一张法兰盘图纸从新建文件到标注完成少说也要七八分钟。而text-to-cad脚本跑一遍从解析文字到图形生成耗时基本在1秒以内算上参数校验和图层整理也不会超过2秒。效率差距是数量级的。1.2 技术路线选择的几个关键考量在真正动手之前我认真比较了几条技术路线这里把我的思考过程写出来免得你们走弯路。第一条路是纯CAD内置的脚本语言比如AutoCAD的AutoLISP或者VBA。优点是直接集成在CAD环境里不需要外部依赖启动快。但缺点是文本解析能力太弱处理“自然语言”这种非结构化输入很费劲而且AutoLISP的字符串处理写起来特别容易出错。我试过一个简单的中文命令解析用LISP写了一百多行结果遇到各种标点符号、空格变体就崩溃。第二条路是用Python做外部控制通过pywin32或者pyautocad调用AutoCAD的COM接口。这条路我最终选了。为什么因为Python在文本处理、正则匹配、规则解析上的生态太强了而且写起来直观后续想接入更复杂的自然语言处理模型也有现成库可以用。缺点是需要额外安装Python环境和库但考虑到自动化流程本来就要跑脚本这个成本可以接受。第三条路是现在比较火的大语言模型接口直接让AI生成图纸脚本。这个我研究过效果确实惊艳但有个很现实的问题在工业设计场景里稳定性比聪明程度更重要。大模型偶尔会产生错误的参数计算而你不可能每次跑图都去人肉核对一遍。所以我最终的方案是规则引擎为主用精确的解析逻辑保证每个尺寸都可预测如果以后想接大模型也只需要把解析结果作为上下文传给模型做补充理解核心绘图逻辑还是走规则引擎。这条架构思路我现在用下来是最稳的。1.3 这套方案能覆盖哪些实际场景text-to-cad不止是画个圆、画条线那么简单。我给它规划了四个层面的应用场景从浅到深分别是第一层是基础图元生成比如“画一条从(0,0)到(100,50)的直线”“画一个圆心在(50,50)半径20的圆”。这是最底层的功能几乎所有其他指令都建立在这一层之上。第二层是参数化标准件生成这是最有实用价值的一层。比如“法兰盘外径120内径60孔数8孔径12孔心距90”这种复合指令程序根据这些参数自动完成所有几何计算一次性生成完整的平面图。标准件库越大这套系统的价值就越高。第三层是图纸规范化处理。一个图纸文件夹里几十张CAD文件图层命名五花八门、线型颜色混乱如果靠人工去整理一张图可能就要半小时。text-to-cad可以把“将当前图纸所有虚线图层重命名为HIDDEN颜色改为黄色线型比例统一改成0.5”这种指令批量下发自动完成。这一点和“python批量对cad修改”那个热搜词天然契合。第四层是辅助设计校验。比如“检查选区内所有圆找出直径小于3的孔并高亮标注”这类规则化检查用程序跑起来比人眼可靠得多。图层没关、重复线没清理、孔径小于工艺要求这些问题都有固定的判断逻辑完全可以程序化。2. 核心细节拆解从一句话到一条多段线2.1 文本指令的语法设计——让系统听得懂人话这是整个项目里最需要打磨的地方。一个text-to-cad系统的智商首先体现在它能不能准确理解用户到底想要什么。我把指令语法分成两种严格语法和自然语法。严格语法是给熟练用户用的格式固定、利于程序解析。我设计了一套简单的关键词模板指令结构就三部分动作词、对象词、参数组。比如画圆圆心(50,50) 半径20“画圆”是动作词“圆心”和“半径”是参数标签括号里的数字是对应的参数值。用正则表达式来提取几乎不会出错。类似的还有“画线起点(0,0) 终点(100,50)”“画矩形角点A(10,10) 角点B(80,60)”“文字位置(30,30) 内容零件图 高度5”。自然语法是我后来补充的宽松模式允许用户用更接近口语的方式描述。举个例子“以坐标50,50为圆心画一个半径30的圆”这句话系统需要从中提取出圆心坐标(50,50)和半径30。实现方式就是预设多个匹配模式比如通过关键词“圆心”抓坐标通过“半径”抓数值再通过语序判断哪个是圆心、哪个是半径。这套规则写得越多系统能听懂的表达就越丰富。我强烈建议做这类项目的人一定把语法设计当成核心工作来做不要小看它。每一步解析规则都要考虑兼容性比如逗号可能是中文的也可能是英文的坐标外面可能有括号也可能没有数值后面可能出现单位厘米或者毫米。我最终在解析前加了一个预处理函数把所有全角字符统一转成半角把所有“”和“”转成英文逗号和分号这样解析规则只需要处理一种字符形态复杂度瞬间降了一半。2.2 实体映射表指令到图形对象的翻译逻辑解析完文本之后系统拿到了完整的参数接下来就要把这些参数变成CAD里真正的图形实体。这里的原则是程序内部定义统一的实体接口再通过映射表把指令词对应到具体的绘图函数。我设计了一张实体映射表类似这样指令词映射类底层函数必要参数画圆/圆/圆形CircleAddCircle圆心、半径画线/直线LineAddLine起点、终点画矩形/矩形RectangleAddRectangle角点A、角点B画多段线/多段线PolylineAddPolyline顶点列表文字/标注文字TextAddText位置、内容、高度画圆弧/弧ArcAddArc圆心、半径、起始角、终止角这个映射表看起来简单但好处是显而易见的用户只需要表达“我要什么”完全不需要关心底层是怎么实现的。未来如果要从AutoCAD切换到中望CAD或者从COM接口换到dotnet API只需要改映射表中的底层函数上层解析逻辑完全不用动。2.3 参数计算与坐标系处理大部分用户第一次用text-to-cad时最容易忽视的问题就是坐标系。AutoCAD的世界坐标系是WCS但图纸内部还可能有用户坐标系UCS。我一开始没处理这个结果用户在图里切换了坐标系以后我的程序还在按WCS坐标画图所有图形全部偏移了。后来解决方案很简单在执行任何绘图操作前先获取当前UCS的原点和旋转角度然后把用户输入的坐标统一做一次坐标变换变成WCS坐标再传给绘图函数。另一个和坐标系相关的坑是极坐标。很多图纸会用距离加角度的方式来定位比如“从点(10,20)出发角度30度距离50”这种描述。在解析阶段我增加了一个指令类型相对极坐标用户可以直接写“极坐标起点(10,20) 角度30 距离50”程序内部立即换算成笛卡尔坐标再交绘图层处理。这个功能做出来后画斜线和定位孔时效率提高非常明显。2.4 图层、线型、标注的自动管理画图只是第一步画完图还能按照规范管理起来才算真正解决工程问题。我在这套系统里内置了一套图层规范每次生成图形实体时会根据实体类型自动分配到对应图层。举个例子如果用户输入的是“画圆圆心(50,50)半径20图层中心线”程序会先去检查图纸中有没有“CENTER”这个图层没有就自动创建然后设置线型为CENTER、颜色为红色、线宽为0.25mm最后把这个圆放到这个图层上。如果用户没指定图层就走默认映射尺寸标注放DIM图层轮廓线放OUTLINE图层文字放TEXT图层。这一步其实特别有价值。我发现很多图纸之所以乱就是因为每个人画图时都习惯在自己当前图层上直接画根本没有切换图层的意识。现在text-to-cad把所有实体自动分配图层图纸的规范程度直接上了一个台阶。配合前面说的批量处理指令老图纸也能在一分钟之内完成图层规范化的整理。3. 实操过程在 AutoCAD 里跑通第一个 text-to-cad 闭环3.1 环境准备Python 3.10 pywin32 AutoCAD 2020我先说明一下我用到的环境Windows 10系统AutoCAD 2020版本Python 3.10第三方库只用了pywin32用来通过COM接口和AutoCAD通信。如果你们用的是AutoCAD 2022以后的新版本COM接口依然保留这套代码逻辑不用变。老规矩先装库pip install pywin32然后需要一个能打开AutoCAD的前提条件。COM方式有两种连接模式一种是AutoCAD已经在运行脚本直接连接当前进程另一种是脚本主动启动一个AutoCAD进程。我实际开发时两种都用了调试用连接当前进程更方便最后部署时用启动模式更稳定。连接代码长这样import win32com.client import pythoncom def connect_to_acad(): pythoncom.CoInitialize() try: acad win32com.client.Dispatch(AutoCAD.Application) except Exception: acad win32com.client.DispatchEx(AutoCAD.Application) acad.Visible True return acad doc connect_to_acad().ActiveDocument ms doc.ModelSpace这里有个细节特别容易踩坑Dispatch和DispatchEx的区别。DispatchEx每次都会创建一个新的AutoCAD实例而Dispatch倾向于连接已经存在的实例。如果你测试时打开了多个CAD窗口Dispatch可能会莫名其妙连接到一个你没留意的实例上然后所有图形都画到那个窗口里了。排查这个问题我用了一下午最后发现是窗口选错了。建议生产环境中明确指定连接目标的文档名或者句柄。3.2 解析引擎正则与规则匹配解析引擎是整个系统的大脑。我用了Python的正则库re写了一个指令解析器。下面这个函数处理“画圆”指令看起来很简单但它体现了整体解析思路import re def parse_command(text): text text.strip().replace(, ,).replace(, ().replace(, )) # 圆 m re.search(r画圆.*?圆心[\(]?\s*([-\d.])\s*[,]\s*([-\d.])\s*[\)]?\s*半径\s*([-\d.]), text) if m: cx, cy, r map(float, m.groups()) return (circle, cx, cy, r) # 直线 m re.search(r画线.*?起点[\(]?\s*([-\d.])\s*[,]\s*([-\d.])\s*[\)]?\s*终点[\(]?\s*([-\d.])\s*[,]\s*([-\d.])\s*[\)]?, text) if m: x1, y1, x2, y2 map(float, m.groups()) return (line, x1, y1, x2, y2) return None这个函数的处理流程是先把全角符号统一转半角再用正则去匹配“圆心(x,y) 半径r”这种模式提取出数值转成浮点数最后返回一个包含指令类型和参数的元组。是不是很简单但你别小看这个结构我后续所有指令都是按照这个模式扩展的。每增加一种新指令只需要加一行正则、一个返回类型完全不用改动其他代码。3.3 绘制引擎COM调用与图形生成解析引擎拿到参数之后绘图引擎负责把这些参数真正画到图纸里。以圆为例绘制函数的实现是这样的def draw_circle(ms, cx, cy, r, layerNone): circle ms.AddCircle(win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_R8, (cx, cy, 0)), r) if layer: circle.Layer layer circle.Update() return circle这里有一个关键点AutoCAD的COM接口坐标参数需要以VARIANT数组的形式传递。我第一次写的时候直接把Python的元组(cx, cy, 0)传进去结果报类型错误后来才发现必须显式构造VARIANT。这个坑几乎所有做CAD COM自动化的人都会遇到所以我把这段代码原样贴出来。对于直线、多段线这类需要多个点的实体处理方式也更复杂一些需要构造一个包含所有顶点坐标的数组再调用对应接口。但核心逻辑和画圆完全一致。3.4 运行效果从命令行到图纸我把解析引擎和绘图引擎串起来封装成一个简单入口函数def run_command(text): parsed parse_command(text) if parsed is None: print(f无法解析指令: {text}) return False cmd_type parsed[0] if cmd_type circle: _, cx, cy, r parsed draw_circle(ms, cx, cy, r, layer轮廓线) # 其他指令类型... return True写个测试直接在Python交互环境里输入run_command(画圆圆心(50,50) 半径20)然后切回AutoCAD窗口你就会看到一个圆心在(50,50)、半径20的圆已经躺在模型空间里了图层是“轮廓线”颜色是默认的黑色。那一刻你会觉得之前所有的踩坑都值了。我又加了一个批量测试函数一次执行十来个指令画圆圆心(10,10) 半径5 画圆圆心(20,20) 半径8 画线起点(0,0) 终点(100,50) 画矩形角点A(5,5) 角点B(60,40)全部执行完CAD里整整齐齐出现了对应的图形。整个过程耗时不到1秒而如果用人工操作这些指令至少需要两分钟。效率上的冲击力是非常直观的。3.5 进阶把图纸批量修改也纳入指令体系基础绘图跑通之后我又把之前说的批量修改思路集成进来。这是所有指令里最简单但最实用的功能。def change_layer_all_text(doc, layer_name): counter 0 for ent in doc.ModelSpace: if ent.ObjectName AcDbText: ent.Layer layer_name counter 1 return counter这个函数做的事很简单遍历模型空间里所有实体找出所有文字对象统一改到指定图层。听起来不复杂但放到一个几百张图纸的文件夹里批量跑效果就非常可怕。我再配一个遍历文件夹的脚本所有图纸里文字乱图层的毛病十分钟内全部改完。你可以随便扩展这个模式批量把所有标注样式改成标准样式、批量把所有图块炸开、批量把所有不可见图层彻底删除。这些以前需要手动操作半天的整理工作现在都是一行指令的事。4. 常见问题与排查技巧实录4.1 COM接口连不上AutoCAD这是新手最常见的报错错误信息通常是“Invalid class string”或者“库未注册”。原因一般是AutoCAD没有正确安装或者COM组件没有注册。排查步骤我建议这样走第一步确认AutoCAD能正常打开先手动启动一次看看是否报错。第二步在Python里执行win32com.client.Dispatch(AutoCAD.Application)如果仍然失败检查AutoCAD安装目录下是否有acad.exe再用命令行运行regsvr32手动注册一下accore.dll和acdb.dll。第三步如果注册完还不行可以考虑用DispatchEx强制创建新实例。我遇到过一台机器上注册表权限被精简软件清理过导致组件丢失的情况重新安装AutoCAD是最彻底的解决方案。4.2 坐标混乱、单位不一致画出来的图位置不对这是我被问得最多的问题。除了之前提到的UCS坐标变换问题外还有一个常见原因是图纸单位没有统一。有些人用毫米有些人用厘米如果解析引擎不做单位换算直接按原始数值画图那图面尺寸会差十倍。我的建议是在所有指令参数解析完之后统一调用一次单位换算函数把用户输入值转成当前图纸的主单位。doc.GetVariable(INSUNITS)可以获取图纸的单位设置然后做对应的比例换算。这个环节看起来不起眼但如果没有它跨团队协作时图纸会乱成一锅粥。4.3 图层和颜色不受控制我在实际测试中发现即使用脚本指定了图层有些情况下实体还是会画到当前图层上。排查了很久发现是自己写的绘制函数里少了真实的图层判断虽然调用了circle.Layer layer但某些AutoCAD版本在实体刚创建但还没Update时调用Layer属性可能被忽略。解决方案是在调用属性赋值之后、显式调用一次circle.Update()这样可以确保属性更改被正确应用。代码里我上面已经写了这一句你们别漏了。图层设置常烂的另一个原因是用户输入了不存在的图层名程序没有做好容错。我的策略是设定一套规范的图层名映射表比如用户输入“中心线”程序自动映射到“CENTER”输入“虚线”映射到“HIDDEN”。同时在创建图层前先检查是否存在不存在则用doc.Layers.Add(CENTER)创建并按规范设置线型和颜色。4.4 批量指令执行了一半报错批量跑一百条指令跑到第五十条报错了怎么处理绝对不能让它从头再来一遍已经执行过的指令那会画出一堆重复实体。我的做法是引入指令队列和事务机制把待执行的指令排进队列每条指令执行前先记录当前实体数量执行后检查数量是否增加且无异常如果某条指令失败把它的原始文本和错误信息单独记录到一个日志文件里然后跳过继续执行后面的指令。执行完之后把失败清单打印出来人工处理。这种做法在生产环境里非常重要它可以保证批量任务不会因为某一条指令的偶发错误而整体中断。运行日志我这里用的是简单的logging库每条指令的执行结果都带时间戳记录后续排查问题特别方便。4.5 关于“cad下载、安装、卸载”这类问题的插话这段时间后台收到不少关于CAD下载、激活报错、卸载后重新安装失败的问题。严格说这些不属于text-to-cad的内容但既然相关度这么高我就简短说两句自己的经验。第一安装包务必从官方渠道或者可信的授权渠道获取不要图方便去下载来路不明的“精简版”很多注册表项被改坏以后COM接口就再也起不来了所有二次开发脚本跟着遭殃。第二如果遇到卸载后二次安装失败重点检查是不是有残留的AutoCAD进程或服务任务管理器里结束所有acad.exe进程再手动删除安装目录残留文件。第三安装过程中频繁出现C运行库错误尤其是“2005cpi”这类说明系统缺少对应版本的VC运行库先卸载干净再重新安装运行库最后再跑一次AutoCAD安装程序。这些基础问题如果解决不了后面的自动化流程根本没机会跑起来。5. 写在最后一点个人体会从零开始把text-to-cad跑通前前后后花了我差不多三周时间其中至少有一半时间花在解析规则调试和COM接口排错上。但真正用起来之后我感觉自己已经回不去了。以前画图是“我手动操作CAD”现在画图变成了“我给程序下一段描述”CAD反而成了后台默默执行任务的工具。这种体验上的变化不单是效率问题更是工作方式的重构。最后再分享一个小技巧如果你想让这套系统在团队里真正用起来不要指望每个人都去写Python脚本。我把常用指令封装成了几条极简的短文本格式整理成一张速查表贴在共享文档里。新同事上手十分钟就能学会老同事用顺手之后甚至能直接打字画图比在CAD里翻菜单快得多。至于未来怎么接大模型、怎么让系统理解更复杂的图纸语义那就是后面的扩展方向了目前这套规则引擎的底子足够稳先跑起来再迭代。