# acadrust 0.2.1
[](https://crates.io/crates/acadrust)
[](https://docs.rs/acadrust)
[](https://opensource.org/licenses/MPL-2.0)
[](https://www.rust-lang.org/)
**A pure Rust library for reading and writing CAD files (DXF and DWG).**
acadrust provides comprehensive support for the DXF and DWG file formats with a focus on correctness, type safety, and completeness. Inspired by [ACadSharp](https://github.com/DomCR/ACadSharp), this library brings full-featured CAD file manipulation to the Rust ecosystem.
---
## β¨ Features
### Core Capabilities
- **π Read & Write DXF** β Full support for both ASCII and Binary DXF formats
- **π Read & Write DWG** β Native DWG binary input/output for R13 through R2018 (8 versions)
- **π Type Safe** β Leverages Rust's type system with strongly-typed entities, tables, and objects
- **π Encoding Support** β Automatic code page detection and character encoding for pre-2007 files (~40 code pages via `encoding_rs`)
- **π‘οΈ Failsafe Mode** β Optional error-tolerant parsing that collects diagnostics instead of aborting
- **π Notifications** β Structured diagnostic system reporting unsupported elements, warnings, and errors
- **π Handle Resolution** β Automatic owner handle assignment and handle tracking after read
- **β Unknown Entity Preservation** β Unrecognized entity types are preserved as `UnknownEntity` with common fields intact
### File Version Support
| AC1009 | R12 | β
| β
| β | β |
| AC1012 | R13 | β
| β
| β
| β
|
| AC1014 | R14 | β
| β
| β
| β
|
| AC1015 | 2000 | β
| β
| β
| β
|
| AC1018 | 2004 | β
| β
| β
| β
|
| AC1021 | 2007 (UTF-8) | β
| β
| β
| β
|
| AC1024 | 2010 | β
| β
| β
| β
|
| AC1027 | 2013 | β
| β
| β
| β
|
| AC1032 | 2018+ | β
| β
| β
| β
|
### Supported Entity Types (41)
<details>
<summary>Click to expand full entity list</summary>
#### Basic Entities
- **Point** β Single point in 3D space
- **Line** β Line segment between two points
- **Circle** β Circle defined by center and radius
- **Arc** β Circular arc with start and end angles
- **Ellipse** β Ellipse or elliptical arc
#### Polylines
- **Polyline** β 2D polyline with optional bulge
- **Polyline2D** β Heavy 2D polyline with vertex entities
- **Polyline3D** β 3D polyline
- **LwPolyline** β Lightweight polyline (optimized 2D)
- **PolyfaceMesh** β 3D mesh defined by vertices and faces
- **PolygonMesh** β 3D polygon surface mesh (MΓN grid)
#### Text & Annotations
- **Text** β Single-line text
- **MText** β Multi-line formatted text
- **AttributeDefinition** β Block attribute template
- **AttributeEntity** β Block attribute instance
- **Tolerance** β Geometric tolerancing symbols
#### Dimensions & Leaders
- **Dimension** β Various dimension types (linear, angular, radial, etc.)
- **Leader** β Leader line with annotation
- **MultiLeader** β Modern multi-leader with advanced formatting
- **Table** β Table with cells, rows, and columns
#### Complex Entities
- **Spline** β NURBS curve
- **Hatch** β Filled region with pattern
- **Solid** β 2D filled polygon
- **Face3D** β 3D triangular/quadrilateral face
- **Mesh** β Subdivision mesh surface
#### Blocks & References
- **Block** / **BlockEnd** β Block definition markers
- **Insert** β Block reference (instance)
- **Seqend** β Sequence end marker for complex entities
#### Construction Geometry
- **Ray** β Semi-infinite line
- **XLine** β Infinite construction line
#### Advanced Entities
- **Viewport** β Paper space viewport
- **RasterImage** β Embedded or linked raster image
- **Solid3D** β 3D solid with ACIS data
- **Region** β 2D region with ACIS data
- **Body** β 3D body with ACIS data
- **MLine** β Multi-line with style
- **Wipeout** β Masking region
- **Shape** β Shape reference
- **Underlay** β PDF/DWF/DGN underlay reference
- **Ole2Frame** β OLE 2.0 embedded object
- **UnknownEntity** β Preserves common fields for unrecognized entity types
</details>
### Table System
Complete support for all standard tables:
| **Layer** | Drawing layers with color, linetype, and visibility |
| **LineType** | Line patterns and dash definitions |
| **TextStyle** | Font and text formatting settings |
| **DimStyle** | Dimension appearance and behavior |
| **BlockRecord** | Block definition registry |
| **AppId** | Application identifier registry |
| **View** | Named view configurations |
| **VPort** | Viewport configurations |
| **UCS** | User coordinate system definitions |
### Objects (Non-Graphical Elements)
- **Dictionary** / **DictionaryWithDefault** β Key-value storage for objects
- **DictionaryVariable** β Named variable in a dictionary
- **Group** β Named entity collections
- **Layout** β Model/paper space layout definitions
- **MLineStyle** β Multi-line style definitions
- **MultiLeaderStyle** β Multi-leader style definitions
- **TableStyle** β Table formatting styles
- **PlotSettings** β Print/plot configurations
- **Scale** β Annotation scale definitions
- **ImageDefinition** / **ImageDefinitionReactor** β Raster image definitions and reactors
- **XRecord** β Extended data records
- **SortEntitiesTable** β Entity draw order
- **VisualStyle** β 3D visual style definitions
- **Material** β Material definitions
- **GeoData** β Geolocation data
- **SpatialFilter** β Spatial clipping filter
- **RasterVariables** β Raster display settings
- **BookColor** β Color book (DBCOLOR) entries
- **PlaceHolder** β Placeholder objects
- **WipeoutVariables** β Wipeout display settings
### CLASSES Section
Full support for the CLASSES section β reading, storing, and writing DXF class definitions with all standard fields (class name, DXF name, application name, proxy flags, instance count).
### Extended Data (XData)
Full support for application-specific extended data:
- String, binary, and numeric values
- 3D points, directions, and displacements
- Layer references and database handles
- Nested data structures with control strings
### Reactors & Extension Dictionaries
Full support for entity/object reactor chains (group code 102 `{ACAD_REACTORS}`) and extension dictionaries (`{ACAD_XDICTIONARY}`), read and written for all entity and object types.
---
## π¦ Installation
Add acadrust to your `Cargo.toml`:
```toml
[dependencies]
acadrust = "0.2.1"
```
Or install via cargo:
```bash
cargo add acadrust
```
---
## π Quick Start
### Reading a DXF File
```rust
use acadrust::{CadDocument, DxfReader};
fn main() -> acadrust::Result<()> {
// Open and read a DXF file
let doc = DxfReader::from_file("drawing.dxf")?.read()?;
// Access document properties
println!("Version: {:?}", doc.header().version);
// Iterate over entities in model space
for entity in doc.entities() {
println!("Entity: {:?}", entity);
}
// Check parse notifications
for note in doc.notifications.iter() {
println!("[{:?}] {}", note.level, note.message);
}
Ok(())
}
```
### Reading with Failsafe Mode
```rust
use acadrust::{DxfReader};
use acadrust::io::dxf::DxfReaderConfiguration;
fn main() -> acadrust::Result<()> {
let config = DxfReaderConfiguration { failsafe: true };
let doc = DxfReader::from_file("drawing.dxf")?
.with_configuration(config)
.read()?;
// Even if some sections had errors, the document is partially populated
println!("Entities read: {}", doc.entities().len());
println!("Notifications: {}", doc.notifications.len());
Ok(())
}
```
### Writing a DXF File
```rust
use acadrust::{CadDocument, DxfWriter, Line, Layer, Vector3};
fn main() -> acadrust::Result<()> {
// Create a new document
let mut doc = CadDocument::new();
// Add a layer
let layer = Layer::new("MyLayer");
doc.layers_mut().add(layer)?;
// Create and add a line
let line = Line {
start: Vector3::new(0.0, 0.0, 0.0),
end: Vector3::new(100.0, 100.0, 0.0),
..Default::default()
};
doc.add_entity(line);
// Write to file
DxfWriter::new(&doc).write_to_file("output.dxf")?;
Ok(())
}
```
### Reading a DWG File
```rust
use acadrust::io::dwg::DwgReader;
fn main() -> acadrust::Result<()> {
let mut reader = DwgReader::from_file("drawing.dwg")?;
let doc = reader.read()?;
println!("Version: {:?}", doc.header().version);
println!("Entities: {}", doc.entities().len());
for entity in doc.entities() {
println!("Entity: {:?}", entity);
}
Ok(())
}
```
### Writing a DWG File
```rust
use acadrust::{CadDocument, DwgWriter};
use acadrust::entities::*;
use acadrust::types::{Color, DxfVersion, Vector3};
fn main() -> acadrust::Result<()> {
// Create a document (default: R2018)
let mut doc = CadDocument::new();
// Or target a specific version
// let mut doc = CadDocument::with_version(DxfVersion::AC1015); // R2000
// Add entities
let mut line = Line::from_coords(0.0, 0.0, 0.0, 100.0, 50.0, 0.0);
line.common.color = Color::RED;
doc.add_entity(EntityType::Line(line))?;
let mut circle = Circle::from_coords(50.0, 25.0, 0.0, 15.0);
circle.common.color = Color::BLUE;
doc.add_entity(EntityType::Circle(circle))?;
// Write to DWG
DwgWriter::write_to_file("output.dwg", &doc)?;
// Or write to a Vec<u8>
let bytes = DwgWriter::write_to_vec(&doc)?;
Ok(())
}
```
### Working with Layers
```rust
use acadrust::{CadDocument, Layer, Color};
fn main() -> acadrust::Result<()> {
let mut doc = CadDocument::new();
// Create a custom layer
let mut layer = Layer::new("Annotations");
layer.color = Color::from_index(1); // Red
layer.is_frozen = false;
layer.is_locked = false;
doc.layers_mut().add(layer)?;
// Access existing layers
if let Some(layer) = doc.layers().get("0") {
println!("Default layer color: {:?}", layer.color);
}
Ok(())
}
```
### Creating Complex Entities
```rust
use acadrust::{CadDocument, LwPolyline, LwVertex, Vector2, Circle, Arc};
fn main() -> acadrust::Result<()> {
let mut doc = CadDocument::new();
// Create a rectangle using LwPolyline
let mut polyline = LwPolyline::new();
polyline.vertices = vec![
LwVertex { position: Vector2::new(0.0, 0.0), ..Default::default() },
LwVertex { position: Vector2::new(100.0, 0.0), ..Default::default() },
LwVertex { position: Vector2::new(100.0, 50.0), ..Default::default() },
LwVertex { position: Vector2::new(0.0, 50.0), ..Default::default() },
];
polyline.is_closed = true;
doc.add_entity(polyline);
// Create a circle
let circle = Circle {
center: Vector3::new(50.0, 25.0, 0.0),
radius: 10.0,
..Default::default()
};
doc.add_entity(circle);
Ok(())
}
```
---
## ποΈ Architecture
acadrust uses a trait-based design for maximum flexibility and extensibility:
```
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β CadDocument β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β βββββββββββββββ ββββββββββββββββ βββββββββββββββββββββββ β
β β Header β β Tables β β Entities β β
β β Variables β β β β β β
β βββββββββββββββ β - Layers β β - Lines, Circles β β
β β - LineTypes β β - Polylines, Arcs β β
β βββββββββββββββ β - Styles β β - Text, Dimensions β β
β β Blocks β β - DimStyles β β - Hatches, Splines β β
β β β β - VPorts β β - 3D, Mesh, Images β β
β βββββββββββββββ ββββββββββββββββ βββββββββββββββββββββββ β
β β
β ββββββββββββββββββββββββββββββββββββ ββββββββββββββββββββ β
β β Objects β β Notifications β β
β β Dictionaries, Groups, Styles, β β Warnings, Errorsβ β
β β Layouts, XRecords, Materials β β Diagnostics β β
β ββββββββββββββββββββββββββββββββββββ ββββββββββββββββββββ β
β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β Classes ββ
β β DXF class definitions (name, app, proxy flags, count) ββ
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
```
### Core Traits
| `Entity` | Base trait for all graphical entities |
| `TableEntry` | Base trait for table entries (layers, styles, etc.) |
| `CadObject` | Common interface for all CAD objects |
### Key Types
| `CadDocument` | Central document container |
| `DxfReader` | DXF file reader (ASCII and binary) |
| `DxfWriter` | DXF file writer |
| `DwgReader` | DWG binary file reader |
| `DwgWriter` | DWG binary file writer |
| `DxfReaderConfiguration` | Reader options (failsafe mode) |
| `Handle` | Unique object identifier |
| `Vector2` / `Vector3` | 2D and 3D coordinate types |
| `Color` | CAD color (indexed or true color) |
| `LineWeight` | Line thickness enumeration |
| `Transform` | Transformation matrices |
| `NotificationCollection` | Parse diagnostics and warnings |
---
## βοΈ Dependencies
acadrust is built on a foundation of high-quality Rust crates:
| `thiserror` / `anyhow` | Error handling |
| `nom` | Parser combinators for binary parsing |
| `byteorder` | Cross-platform byte order handling |
| `flate2` | Compression/decompression |
| `nalgebra` | Linear algebra and transformations |
| `indexmap` | Ordered hash maps |
| `rayon` | Parallel iterators |
| `encoding_rs` | Character encoding support |
| `bitflags` | Type-safe bitflags |
| `once_cell` | Lazy static initialization |
| `ahash` | Fast hashing |
---
## π§ͺ Testing
Run the test suite:
```bash
# Run all tests
cargo test
# Run with output
cargo test -- --nocapture
# Run specific test
cargo test test_read_minimal_dxf
```
### Generate DWG Samples
Generate a comprehensive matrix of every entity type Γ every DWG version (R13βR2018) for verification in AutoCAD, IntelliCAD, or BricsCAD:
```bash
cargo run --example gen_all_entities_all_versions
```
This produces 216 DWG files in `target/entities_dwg/<VERSION>/` β 27 entity types across 8 versions.
Run benchmarks:
```bash
cargo bench
```
---
## οΈ Roadmap
- [x] ASCII DXF read/write
- [x] Binary DXF read/write
- [x] Full entity, table, and object coverage
- [x] CLASSES section support
- [x] Character encoding / code page support
- [x] Failsafe (error-tolerant) reading mode
- [x] Unknown entity preservation
- [x] DWG binary write (R13, R14, R2000, R2004, R2007, R2010, R2013, R2018)
- [x] DWG binary read (R13 through R2018)
- [ ] Geometric operations (offset, trim, extend)
- [ ] SVG/PDF export
- [ ] Spatial indexing for large drawings
---
## π License
This project is licensed under the Mozilla Public License 2.0 - see the [LICENSE](LICENSE) file for details.
---
## π Acknowledgments
- [ACadSharp](https://github.com/DomCR/ACadSharp) - The C# library that inspired this project
- The Rust community for excellent tooling and libraries
---
## π Support
- **Issues**: [GitHub Issues](https://github.com/hakanaktt/acadrust/issues)
- **Discussions**: [GitHub Discussions](https://github.com/hakanaktt/acadrust/discussions)
---
<p align="center">
Made with β€οΈ in Rust
</p>