Python 中使用 ezdxf:轻松读写 DXF 文件的完整指南
在工程制图、建筑、机械设计等领域,DXF(Drawing Exchange Format) 是一种广泛使用的矢量图形文件格式,由 Autodesk 开发,用于在不同 CAD 软件之间交换数据。如果你需要在 Python 中自动化处理 CAD 图纸------比如提取几何信息、批量修改图层、生成简单图纸或与 BIM 系统集成------那么 ezdxf 就是你不可或缺的利器。
ezdxf 是一个功能强大且易于上手的开源 Python 库,支持读取、创建和修改 DXF 文件(兼容 R12 到 R2018 等多个版本)。本文将带你从安装到实战,全面掌握 ezdxf 的核心用法。
一、安装 ezdxf
ezdxf 可通过 pip 直接安装:
pip install ezdxf
💡 建议同时安装
matplotlib或opencv-python,便于可视化调试(非必需)。
二、基础概念:DXF 文件结构简述
在使用 ezdxf 前,了解 DXF 的基本组成有助于理解 API 设计:
- Entities(实体):如 LINE(直线)、CIRCLE(圆)、TEXT(文字)、POLYLINE(多段线)等。
- Layers(图层):用于组织和控制实体的显示/打印属性。
- Blocks(块):可重复使用的图形组合(类似"符号")。
- Modelspace / Paperspace:模型空间(实际设计区域)和布局空间(打印排版区域)。
ezdxf 将这些概念封装为直观的 Python 对象。
三、创建一个新的 DXF 文件
下面是一个创建包含直线和圆的简单 DXF 文件的示例:
import ezdxf
# 创建一个新的 DXF 文档(默认 R2010 格式)
doc = ezdxf.new(dxfversion='R2010')
# 获取模型空间
msp = doc.modelspace()
# 添加一条直线:起点 (0, 0),终点 (10, 10)
msp.add_line((0, 0), (10, 10))
# 添加一个圆:圆心 (5, 5),半径 3
msp.add_circle(center=(5, 5), radius=3)
# 保存文件
doc.saveas("example.dxf")
print("DXF 文件已生成:example.dxf")
运行后,你将得到一个可在 AutoCAD、DraftSight、FreeCAD 等软件中打开的 .dxf 文件。
四、读取现有 DXF 文件并遍历实体
假设你有一个现成的 drawing.dxf,想提取其中所有直线坐标:
import ezdxf
# 读取 DXF 文件
doc = ezdxf.readfile("drawing.dxf")
msp = doc.modelspace()
# 遍历所有实体
for entity in msp:
if entity.dxftype() == 'LINE':
start = entity.dxf.start
end = entity.dxf.end
print(f"直线:{start} → {end}")
elif entity.dxftype() == 'CIRCLE':
center = entity.dxf.center
radius = entity.dxf.radius
print(f"圆:中心 {center},半径 {radius}")
✅
entity.dxftype()返回实体类型字符串,是判断实体种类的关键方法。
五、操作图层(Layers)
图层是 CAD 组织图形的核心机制。ezdxf 允许你创建、修改和分配图层:
# 创建新图层
doc.layers.new(name="WALLS", dxfattribs={'color': 1}) # 颜色1=红色
# 在指定图层上添加实体
msp.add_line((0, 0), (100, 0), dxfattribs={'layer': 'WALLS'})
# 修改图层属性
layer = doc.layers.get("WALLS")
layer.color = 3 # 改为绿色
六、添加文字与标注
# 添加单行文字
msp.add_text(
"Hello, CAD!",
dxfattribs={
'insert': (10, 20), # 插入点
'height': 2.5, # 字高
'layer': 'ANNOTATION'
}
)
# 添加多行文字(MTEXT)
msp.add_mtext("这是\n多行文本", dxfattribs={'insert': (10, 30), 'char_height': 2})
七、使用块(Blocks)提高复用性
块类似于"模板",适合重复图形(如门窗符号、设备图标):
# 创建一个名为 "DOOR" 的块
block = doc.blocks.new(name='DOOR')
block.add_line((0, 0), (0, 2)) # 门框
block.add_arc(center=(0, 0), radius=2, start_angle=0, end_angle=90) # 门扇弧线
# 在模型空间插入该块(可多次插入,位置/缩放/旋转可变)
msp.add_blockref(
name='DOOR',
insert=(5, 5), # 插入位置
dxfattribs={'xscale': 1, 'yscale': 1, 'rotation': 0}
)
八、实用技巧与注意事项
1. 版本兼容性
- 使用
ezdxf.new(dxfversion='R12')可生成更老的 DXF 版本(兼容性更好)。 - 但 R12 不支持某些高级实体(如 LWPOLYLINE),建议优先使用 R2000 或 R2010。
2. 坐标系统
- DXF 使用笛卡尔坐标系(X 向右,Y 向上),与屏幕坐标一致。
- 所有坐标均为
(x, y)或(x, y, z)元组。
3. 性能优化
- 处理大型 DXF 文件时,避免频繁调用
save(),应在最后一次性保存。 - 可使用
doc.entitydb.purge()清理未引用的实体(谨慎使用)。
4. 可视化调试(可选)
虽然 ezdxf 本身不提供绘图功能,但可结合 matplotlib 快速预览:
from ezdxf.addons.drawing import RenderContext, Frontend
from ezdxf.addons.drawing.matplotlib import MatplotlibBackend
doc = ezdxf.readfile("example.dxf")
msp = doc.modelspace()
fig = plt.figure()
ax = fig.add_axes([0, 0, 1, 1])
ctx = RenderContext(doc)
out = MatplotlibBackend(ax)
Frontend(ctx, out).draw_layout(msp)
plt.show()
需安装
matplotlib和ezdxf[draw](pip install ezdxf[draw])。
九、典型应用场景
- 自动化出图:根据数据库生成标准 CAD 图纸。
- BIM 数据提取:从建筑模型导出的 DXF 中解析墙体、门窗位置。
- 激光切割/数控编程:生成符合设备要求的 DXF 路径。
- GIS 数据转换:将 Shapefile 或 GeoJSON 转为 DXF 供 CAD 使用。
结语
ezdxf 以简洁的 API 和强大的功能,让 Python 成为处理 DXF 文件的高效工具。无论你是工程师、开发者还是科研人员,只要涉及 CAD 数据自动化,ezdxf 都值得纳入你的技术栈。