- 作者说:
最好用.DXF格式的文件!.DWF格式的文件可能会出现缩放不正确的问题!!!
把 AutoCAD 画的 DXF / DWF / DWFx 文件(多段线 / 直线 / 圆弧 / 圆 / 样条曲线 / 文字) 转换成 CNC 雕刻机能用的 G 代码。 输出严格限定为
G00 / G01 / G02 / G03四种指令,无宏程序、无固定循环。
d:\Desktop\1\
│
├── 核心代码 ─────────────────────────
│ └── core\
│ ├── dxf2gcode.py ← 核心转换脚本
│ └── preview_gcode.py ← G 代码预览脚本(Pillow 画 PNG)
│
├── 用户入口(拖文件就能跑)───────────
│ ├── convert.bat ← 单个文件:拖一个 DXF/DWF/DWFx 进去
│ ├── convert_all.bat ← 批量:扫描 input\ 下全部文件
│ └── preview.bat ← 单独预览已有 .txt / .nc
│
├── 输入输出目录(自动创建)────────────
│ ├── input\ ← 批量模式放 CAD 源文件
│ ├── gcode\ ← 转换输出(.txt)
│ └── preview\ ← 预览图输出(_full.png + _cutting.png)
│
└── README.md
支持三种格式(脚本自动识别扩展名):
| 格式 | 扩展名 | 所需依赖 |
|---|---|---|
| DXF | .dxf |
ezdxf(必装) |
| DWF | .dwf |
ezdwf(可选,DWF 才需要) |
| DWFx | .dwfx |
ezdwf(可选,DWFx 才需要) |
内容要求:
- 线条类型:
LWPOLYLINE / POLYLINE / LINE / ARC / CIRCLE / SPLINE - 文字对象:
TEXT / MTEXT(会用字体把字描成闭合轮廓一起刻,见下文「文字怎么刻」) - 坐标原点在图纸右下角(X 向左负方向,Y 向上正方向)
- 可以画一个最大外框矩形,工具会自动跳过它
# 必装:ezdxf + Pillow
"C:\Users\ASUS\AppData\Local\Programs\Python\Python310\python.exe" -m pip install ezdxf pillow
# 可选:如果要读 DWF / DWFx 文件再加这个
"C:\Users\ASUS\AppData\Local\Programs\Python\Python310\python.exe" -m pip install ezdwf
# 可选:图纸里写了文字(TEXT / MTEXT)才需要,用来把文字描成刀路轮廓
"C:\Users\ASUS\AppData\Local\Programs\Python\Python310\python.exe" -m pip install matplotlib单个文件: 把文件拖到 convert.bat 上 → 自动转换 + 自动预览
批量(推荐): 把多个 CAD 文件丢进 input\ 文件夹,然后双击 convert_all.bat
| 场景 | 操作 |
|---|---|
| 单个文件 | 拖 01.dxf → convert.bat → gcode\01.txt + preview\ 两张图 |
| 批量多个 | 把 N 个文件丢 input\ → 双击 convert_all.bat → 全部处理完 |
批量转换的程序号会自动递增:
input\里的第 1 个文件写成O0001;, 第 2 个写成O0002;,以此类推(按文件名排序)。 转换失败的文件不占用程序号,所以成功转换出来的文件永远是连续的O0001、O0002… 单个文件转换固定用O1099;,想换号加-n参数即可。
批量输出:
========================================
批量转换
扫描 input\ 下所有 DXF / DWF / DWFx
========================================
----------------------------------------
[1] 01.dxf
----------------------------------------
...转换中...
[成功] 01.dxf -> gcode\01.txt
----------------------------------------
[2] 02.dwf
----------------------------------------
...转换中...
[成功] 02.dwf -> gcode\02.txt
========================================
完成:2 成功,0 失败,共 2 个
========================================
如果你已经有 .txt,拖到 preview.bat 或:
.\preview.bat gcode\01.txt会在 preview\ 下生成两张图:
| 文件 | 内容 |
|---|---|
preview\01_full.png |
完整轨迹:蓝色切削 + 灰色快速 G00 + 浅灰抬刀空跑 |
preview\01_cutting.png |
纯切削轨迹:只有蓝色雕刻形状,一眼看清最终效果 |
O1099; ← 程序号(单文件默认 O1099;批量转换按顺序 O0001、O0002…)
M03S3000; ← 主轴正转 3000 RPM
G54G90; ← 工件坐标系 + 绝对坐标
G00Z15; ← 快速抬刀到安全高度
G00X0Y0; ← 快速回原点
抬刀指令只在真正需要时才出现,不会连着写两遍。 第一次下刀前,程序头的
G00Z15;已经把刀抬好了(初始化抬刀),所以第一条链前面没有多余抬刀。
G00 X-33.803 Y17.737 ← 快速移动到起点上方
G01 Z-0.200 F200 ← 下刀切入,整条链唯一一次写 F
G01 X-22.649 Y17.737 ← 切削直线(不再重复写 F200)
G01 X-22.649 Y8.826
...
G00 Z15.000 ← 抬刀(整条链只抬这一次,然后去下一条链)
F也是模态指令,只在每条链的下刀那一行写一次,后面的切削行全部不带 F。 所以整份程序里F出现的次数 = 切削链的条数。
M30 ← 程序结束,回到开头
最后一条链切完时已经抬过刀了,结尾不再重复写
G00 Z15。 所以整份程序里G00 Z15.000出现的次数 = 切削链的条数。
| 字段 | 格式 | 说明 |
|---|---|---|
| X / Y | 保留 3 位小数 | 绝对坐标(G90 模态) |
| Z | 保留 3 位小数 | 安全高 +15,下刀 -0.2 |
| R | 保留 3 位小数 | G02/G03 专用,圆弧半径。首选格式——非整圆全部用 R,不依赖机床的 I/J 解释方式 |
| I / J | 保留 3 位小数 | 圆心相对起点的偏移。只有整圆(起点=终点)才用 I/J,因为整圆的 R 格式有歧义;加 --arc-ij 可强制所有弧都用 I/J |
| F | 整数 | 每分钟进给,只在每条链的下刀行写一次(模态保持),默认 200 |
| 指令 | 用途 | 说明 |
|---|---|---|
| G00 | 快速定位 | 抬刀状态下用 |
| G01 | 直线插补 | 切削 / 空跑 |
| G02 | 顺时针圆弧 | 带 I、J 圆心偏移 |
| G03 | 逆时针圆弧 | 带 I、J 圆心偏移 |
不会出现: G41(刀补)、G80-G89(固定循环)、G98/G99、M98/M99(子程序)、宏程序变量等。
| 参数 | 全称 | 默认值 | 含义 |
|---|---|---|---|
-i |
--input |
必填 | 输入文件路径(.dxf / .dwf / .dwfx) |
-o |
--output |
必填 | 输出 G 代码文件路径(建议 .txt) |
-s |
--safe-z |
15.0 |
安全高度 Z(抬刀高度,mm) |
-d |
--cut-depth |
-0.2 |
下刀深度(负值,mm) |
-f |
--feed |
200 |
进给速度 F(mm/min) |
-p |
--origin |
br |
加工原点位置:bl左下 / br右下 / tl左上 / tr右上 |
--snap-tol |
0 |
端点吸附容差(mm)。0 = 要求端点严格重合;填 0.05 表示相距 0.05mm 以内的端点也算接上,可以少抬几次刀 |
|
--no-optimize |
不开启 | 加上这个开关会关掉链间路径优化(默认开启) | |
-n |
--prog-num |
1099 |
程序号 O 后面的数字,范围 1~9999。批量转换时由 convert_all.bat 自动传入 1、2、3…,生成 O0001、O0002、O0003…;手动指定写 -n 5 就是 O0005 |
--arc-ij |
不开启 | 强制所有圆弧都用 I/J 格式(圆心相对起点的偏移)。默认规则:非整圆用 R,整圆用 I/J。机床上若圆弧跑到很远的地方,说明机床把 I/J 当成绝对坐标,保持默认即可;但整圆目前只能走 I/J,如果整圆也飞了请反馈,有备选方案 | |
--font |
C:\Windows\Fonts\simhei.ttf |
图纸里的文字用哪个 TTF 字体描成轮廓,默认黑体;换字体例如 --font C:\Windows\Fonts\simkai.ttf(楷体) |
# 最简(全部默认参数)
python core\dxf2gcode.py -i input\考试.dwf -o gcode\考试.txt
# 自定义原点 + 下刀更深 + 更快
python core\dxf2gcode.py -i input\考试.dwf -o gcode\考试.txt -p bl -d -0.5 -f 300
# 原点在左上 + 安全高 20mm
python core\dxf2gcode.py -i input\考试.dwf -o gcode\考试.txt -p tl -s 20
# CAD 里线段没接严,差一点点就断开 → 用 0.05mm 吸附容差接起来
python core\dxf2gcode.py -i input\考试.dxf -o gcode\考试.txt --snap-tol 0.05
# 图纸里的字换成楷体刻
python core\dxf2gcode.py -i input\考试.dxf -o gcode\考试.txt --font C:\Windows\Fonts\simkai.ttf转换时做了三层优化,不需要你做任何设置,默认全开。
把所有图形的端点归到"同一个位置",同一位置上的线段就串成一条链, 一条链只下刀一次、抬刀一次,中间不断刀。
起链的位置从端点数只有 1 根线的地方开始找(也就是笔画的两个头), 这样一条能连通的折线永远只切一次,不会因为它在 DXF 里的排列顺序被拆成好几刀。
链和链之间本来要抬刀飞过去,飞多远取决于加工顺序。程序用两个经典算法把它压到最短:
| 算法 | 作用 |
|---|---|
| 最近邻 | 从当前位置出发,每次挑离得最近的下一段去切,顺便决定这一段从哪头进刀 |
| 2-opt | 反复尝试"把中间某几段整体倒过来加工",只要总路程变短就接受,直到再也改不动 |
这两个是旅行商问题(TSP)里最经典的算法,开源项目 dxf2gcode、pyTSP、skyink 都用它来减少空程。
在 CAD 里画线时,两根线端点看着接上了,实际可能差了 0.001~0.01mm,
严格比对会认为"没接上",于是白白多抬一次刀。
加 --snap-tol 0.05 就能把这种"差一点点"的端点当成接上。
图纸里的线条确认是精确对齐的,就不用加这个参数(默认 0)。
每次转换完,控制台都会打印一行对比,例如:
【端点链接】60 个实体 → 27 条连续切削链
【路径优化】空行程 290.4 mm → 112.4 mm(减少 61.3%)
【完成】共处理 60 个图元 → 27 条连续切削链(抬刀/下刀 27 次)
- 抬刀/下刀 27 次 = 图形里有 27 组互不相连的线条(这个数量由图纸本身决定, 想再减少只能去 CAD 里把断开的线接成一条)
- 空行程减少了 xx% = 抬刀状态下白白飞过的距离,越小越省时间
工具会自动识别并跳过覆盖整个图形最大范围的外框线:
- LINE 水平覆盖全宽 或 垂直覆盖全高 → 外框边
- POLYLINE 包围盒恰好等于整体包围盒 → 闭合外框
你可以放心在 CAD 里画外框,转换时会自动消失。
图纸里用 TEXT(单行文字)或 MTEXT(多行文字)写的字,不用打散、不用转成线条,
转换时会自动按字体把每个字描成空心轮廓,然后跟线条一样出刀路。
空心描边:一个字的外轮廓和内孔都会刻。例如:
- 「口」→ 外面一个方框 + 里面一个方孔
- 「回」→ 三层轮廓
- 「A」→ 三角形外框 + 中间那个小三角
所以刻出来是"线条勾出字的形状",不是挖空的实心字。
CAD 里的"字高"指的是字形本身多高,转换时就按这个尺寸刻:
| 图纸里写的字高 | 刻出来的实际高度 |
|---|---|
| 8 mm | 8.2 ~ 8.4 mm(正常误差,不同笔画高度略有差别) |
程序会自动区分中英文再换算:中文字按汉字方块的高算,英文字母数字按大写字母的高算。
| 属性 | 是否支持 | 说明 |
|---|---|---|
| 插入点 | ✅ | |
| 字高 | ✅ | |
| 旋转 | ✅ | 任意角度 |
| 对齐(左/中/右) | ✅ | TEXT 的 halign,MTEXT 的 attachment |
| 多行文字 | ✅ | 自动换行,行距 = 字高 × 1.5 |
| 字体 | ✅ | 用 --font 指定,默认黑体 |
| 倾斜 / 字宽比例 | ❌ | 斜体、压扁拉长不支持,按正体刻 |
默认用黑体(C:\Windows\Fonts\simhei.ttf),中英文都能出。
换字体的例子:
# 楷体
python core\dxf2gcode.py -i input\字.dxf -o gcode\字.txt --font C:\Windows\Fonts\simkai.ttf
# 宋体
python core\dxf2gcode.py -i input\字.dxf -o gcode\字.txt --font C:\Windows\Fonts\simsun.ttc
# 微软雅黑
python core\dxf2gcode.py -i input\字.dxf -o gcode\字.txt --font C:\Windows\Fonts\msyh.ttc字体文件必须是
.ttf/.ttc格式,不能用.shx(AutoCAD 专用笔画字体)。
- 字的每个笔画轮廓互不相连,所以每个轮廓要单独下刀一次。
一个字通常 3
10 条轮廓,也就是 310 次抬刀,这是正常的。 - 文字轮廓是把字体的曲线打成小直线段(每段曲线分 12 刀),所以图纸里字多时 G 代码会比较长。
- 如果漏装了 matplotlib,图纸里的文字会被跳过并给出提示,线条部分照常转换。
A: 默认 Python 路径不对。用 bat 或显式指定 Python 3.10 路径。
手动装:python3.10 -m pip install ezdxf pillow
A: DWF 格式需要额外装 ezdwf:python3.10 -m pip install ezdwf
A: 输入里没有 ARC 或带 bulge 的多段线。DWG 转换时曲线被打散成小直线了。 解决:用 AutoCAD 直接保存为高版本 DWF 或 DXF(不要用第三方转换器)。
A: 检查边框是不是恰好覆盖整个图形的 X 或 Y 范围。有圆角/偏移则识别不出。 临时解决:在 CAD 里把边框改回严格矩形再保存。
A: 三种可能:
- 没装 matplotlib(转换时控制台会有【警告】提示)
→ 装一下:
python3.10 -m pip install matplotlib --font指定的字体文件不存在 → 换成一个确实存在的.ttf/.ttc- CAD 里文字用的是
.shx笔画字体,且内容是中文 →.shx不是标准字体文件,程序读不了,请换用系统 TTF 字体再转
A: 正常。字体的字形本身比"标称字高"略大(不同笔画高度不一样), 一般大 2%~5%。要精确尺寸就以转换出来的预览图为准,或在 CAD 里微调字高。
A: 刀直径 0.3mm,走刀中心轨迹自然会偏小。要么加 G41 半径补偿, 要么在 CAD 里提前把轮廓向外偏移 0.15mm。
A: 绝大多数 CNC 控制器(FANUC / 广数 / 华中)不关心后缀名, 只认文件里的 G 代码内容。如果你的机床要求特定后缀,改回去即可。
- Python 3.10(路径:
C:\Users\ASUS\AppData\Local\Programs\Python\Python310\) - ezdxf 1.4+ (DXF 解析,必装)
- ezdwf 0.0.6+ (DWF / DWFx 解析,可选)
- Pillow (PNG 预览绘图)
- matplotlib (把文字描成矢量轮廓,图纸里有文字才需要,可选)
- Windows 10 / 11
本项目仅用于个人 CNC 雕刻场景,可自由修改和分发。