📋 概述
dxf-rs 是一个功能全面、纯 Rust 实现的库,专门用于读写 DXF (Drawing Exchange Format) 和 DXB 格式的 CAD 文件。它提供了安全、高效的方式来解析和生成 AutoCAD 交换文件,是 Rust 生态中处理 CAD 数据的主流选择。
✨ 核心特性
🔧 技术特性
- 100% 纯 Rust 实现:完全由 Rust 编写,依赖项也都是 Rust 库,无需链接 C/C++ 代码,跨平台编译轻松
- 类型安全:利用 Rust 强大的类型系统,将 DXF 中的各种图元映射为清晰的枚举和结构体
- 完整的图元支持:支持直线(Line)、圆(Circle)、多段线(Polyline)、三维面(3DFace)、样条曲线(Spline)等数十种图元类型
- 内存安全:Rust 的所有权系统确保文件解析过程中的内存安全
📁 文件格式支持
- DXF 格式:完整的 DXF 读写支持,兼容 ASCII 和二进制格式
- DXB 格式:支持二进制 DXB 文件的读写
- 版本兼容 :宣称支持到 AutoCAD R2018 版本的 DXF 规范,对更高版本能稳定读取基础几何信息
📦 版本信息
| 项目 | 详细信息 |
|---|---|
| 库名称 | dxf (在 crates.io 上注册的名称) |
| 当前版本 | 0.6.1 (2024年11月18日更新,5天前有版本更新) |
| 开源协议 | MIT (宽松协议,允许商业使用) |
| 源码仓库 | https://github.com/ixmilia/dxf-rs |
| 官方文档 | https://docs.rs/dxf/ |
| Rust 版本 | Edition 2021 |
| 作者 | Brett V. Forsgren |
🏗️ 架构设计
核心模块
text
dxf-rs
├── Drawing # 代表整个 DXF 图纸,包含所有数据
├── Header # 管理 DXF 文件头信息,如版本、变量设置
├── Entities # 所有图元类型的枚举和结构体定义
├── Tables # 处理层表、线型表、样式表等
├── Blocks # 支持块定义和块参照
├── Objects # 处理非图形对象,如字典、布局
└── CodePair # 底层 DXF 代码对解析器
主要数据结构
Drawing(图纸)
rust
Drawing {
header: Header, // 文件头信息
entities: Vec<Entity>, // 所有图元集合
blocks: Vec<Block>, // 所有块定义
tables: Tables, // 各种符号表
objects: Vec<Object>, // 非图形对象
}
Entity(图元)
通过 EntityType 枚举支持的所有图元类型:
Line- 直线Circle- 圆Arc- 圆弧Polyline- 多段线LwPolyline- 轻量多段线Spline- 样条曲线Ellipse- 椭圆Text- 文字MText- 多行文字Insert- 块参照Dimension- 标注Solid- 实体填充区Face3D- 三维面Point- 点- 等等...
🔧 安装与使用
添加依赖
在 Cargo.toml 中添加:
toml
[dependencies]
dxf = "0.6.1"
如需序列化支持:
toml
[dependencies]
dxf = { version = "0.6.1", features = ["serialize"] }
基础示例
读取 DXF 文件
rust
use dxf::Drawing;
use dxf::entities::EntityType;
fn main() -> Result<(), Box<dyn std::error::Error>> {
// 从文件加载 DXF
let drawing = Drawing::load_file("example.dxf")?;
println!("DXF 版本: {:?}", drawing.header.version());
println!("图元数量: {}", drawing.entities().count());
// 遍历所有图元
for entity in drawing.entities() {
println!("图层: {}", entity.common.layer);
match &entity.specific {
EntityType::Line(line) => {
println!(" 直线: ({:.2}, {:.2}) -> ({:.2}, {:.2})",
line.p1.x, line.p1.y, line.p2.x, line.p2.y);
}
EntityType::Circle(circle) => {
println!(" 圆: 圆心({:.2}, {:.2}), 半径{:.2}",
circle.center.x, circle.center.y, circle.radius);
}
EntityType::LwPolyline(poly) => {
println!(" 轻量多段线: {}个顶点", poly.vertices.len());
}
_ => {}
}
}
Ok(())
}
创建 DXF 文件
rust
use dxf::Drawing;
use dxf::entities::*;
use dxf::Point;
fn main() -> Result<(), Box<dyn std::error::Error>> {
// 创建新图纸
let mut drawing = Drawing::new();
// 创建直线
let line = Line {
p1: Point::new(0.0, 0.0, 0.0),
p2: Point::new(100.0, 100.0, 0.0),
..Default::default()
};
// 创建圆
let circle = Circle {
center: Point::new(50.0, 50.0, 0.0),
radius: 25.0,
..Default::default()
};
// 添加图元到图纸
drawing.add_entity(Entity::new(EntityType::Line(line)));
drawing.add_entity(Entity::new(EntityType::Circle(circle)));
// 保存文件
drawing.save_file("output.dxf")?;
println!("DXF 文件已保存");
Ok(())
}
处理块参照
rust
use dxf::Drawing;
use dxf::entities::{Insert, EntityType};
fn process_blocks(drawing: &Drawing) {
for entity in drawing.entities() {
if let EntityType::Insert(insert) = &entity.specific {
println!("发现块参照:");
println!(" 块名: {}", insert.name);
println!(" 位置: ({:.2}, {:.2})", insert.position.x, insert.position.y);
println!(" 缩放: ({:.2}, {:.2}, {:.2})",
insert.x_scale, insert.y_scale, insert.z_scale);
println!(" 旋转: {:.2}°", insert.rotation.to_degrees());
}
}
}
📚 DXF 参考资料
README.md 中提供了大量指向 Autodesk 官方 DXF 规范文档的链接,对理解文件底层结构非常有帮助:
- R2018 DXF 官方参考 - 在线阅读最新规范
- R2014 规范 - 适用于大多数场景的稳定版本
- R12/R13/R14 - 旧版兼容性参考
离线下载 R2018 文档
bash
wget -r -k -L -e robots=off http://help.autodesk.com/cloudhelp/2018/ENU/AutoCAD-DXF/files/GUID-235B22E0-A567-4CF6-92D3-38A2306D73F3.htm
🧪 测试与集成
集成测试
库中包含集成测试 (src/misc_tests/integration.rs),在 Windows 上可通过 ODA File Converter 工具运行:
- 下载地址:ODA File Converter
- 用于验证生成 DXF 文件的正确性
序列化支持
通过启用 serialize 功能,可以使用 serde 对 DXF 数据结构进行序列化和反序列化:
rust
use serde_json;
use dxf::Drawing;
let drawing = Drawing::load_file("input.dxf")?;
let json = serde_json::to_string_pretty(&drawing)?;
🔨 实际应用案例
已有多个项目基于 dxf-rs 开发:
- dxf2elmt:将 DXF 文件转换为特定格式 (.elmt) 的命令行工具
- kerf-adjuster:调整 DXF 文件以补偿激光切割切缝的 Web 应用
- Gerber-To-SolderMask-DXF:将 Gerber 文件转换为焊接掩模 DXF 格式
- csgrs :构造实体几何库,使用
dxf-rs实现 DXF 文件的导入导出
⚙️ 高级特性
自定义图元处理
rust
use dxf::{Drawing, CodePair};
use dxf::entities::*;
// 遍历并修改所有圆的半径
fn scale_circles(drawing: &mut Drawing, factor: f64) {
let circles: Vec<_> = drawing
.entities_mut()
.filter_map(|entity| {
if let EntityType::Circle(circle) = &mut entity.specific {
Some(circle)
} else {
None
}
})
.collect();
for circle in circles {
circle.radius *= factor;
}
}
处理扩展数据 (XData)
rust
use dxf::entities::{Entity, EntityType};
fn read_xdata(entity: &Entity) {
if let Some(xdata) = &entity.common.xdata {
println!("扩展数据应用: {}", xdata.application_name);
for code_pair in &xdata.items {
println!(" {}: {:?}", code_pair.code, code_pair.value);
}
}
}
📈 性能考虑
- 内存效率:采用流式解析策略,大文件处理时内存占用可控
- 零拷贝解析:某些场景下避免不必要的内存分配
- 并行处理:可以结合 Rayon 实现多线程图元处理
🚀 未来展望
根据仓库活跃度,预计未来会:
- 持续更新以支持更新的 DXF 版本特性
- 增强对复杂实体的支持(如动态块、约束)
- 优化解析性能
- 提供更多实用工具和示例
📖 总结
dxf-rs 是一个成熟、稳定且功能完整的 Rust CAD 库,特别适合需要处理 DXF 文件的 Rust 项目。它的纯 Rust 实现保证了跨平台兼容性和内存安全,丰富的 API 支持从简单的几何提取到复杂的 CAD 数据处理。无论您是构建 CAD 转换工具、CAM 软件、还是需要从 DXF 文件中提取设计信息的应用,dxf-rs 都是一个可靠的选择。
对于最新的 R2018+ 文件,它能可靠地处理基础几何信息;对于需要完整高级特性支持的场景,建议配合 ODA 工具链使用。