# acadrust 0.2.8
[](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), 208/208 roundtrip-perfect
- **π§ 3D Solid Creation** β Read/Build ACIS-based simple 3DSOLID entities (box, wedge, pyramid, cylinder, and custom B-Rep) with SAT text (R2000βR2007) and SAB binary (R2013+) encoding
- **π 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 | β
| β
| β
| β
|
| 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 (read & **write** β SAT v7.0 text and SAB binary)
- **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.8"
```
Or install via cargo:
```bash
cargo add acadrust
```
### Optional Features
| `serde` | Enables `Serialize` / `Deserialize` on all document types for JSON, YAML, etc. |
```toml
[dependencies]
acadrust = { version = "0.2.8", features = ["serde"] }
```
---
## π 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(())
}
```
### Serialization (optional `serde` feature)
Serialize individual entities:
```rust
use acadrust::entities::Line;
let line = Line::from_coords(0.0, 0.0, 0.0, 100.0, 50.0, 0.0);
let json = serde_json::to_string_pretty(&line).unwrap();
println!("{json}");
```
Round-trip a full document:
```rust
use acadrust::{CadDocument, DxfReader};
fn main() -> acadrust::Result<()> {
let doc = DxfReader::from_file("drawing.dxf")?.read()?;
// Serialize the entire document to JSON
let json = serde_json::to_string_pretty(&doc).unwrap();
// Deserialize back
let doc2: CadDocument = serde_json::from_str(&json).unwrap();
println!("Entities: {}", doc2.entities().count());
Ok(())
}
```
Extract entities as a JSON array for a web API:
```rust
use acadrust::{CadDocument, DxfReader};
use acadrust::entities::EntityType;
fn main() -> acadrust::Result<()> {
let doc = DxfReader::from_file("drawing.dxf")?.read()?;
let entities: Vec<&EntityType> = doc.entities().collect();
let api_response = serde_json::to_string_pretty(&entities).unwrap();
println!("{api_response}");
Ok(())
}
```
All entities, tables, objects, and types implement `Serialize` and `Deserialize`
when the `serde` feature is enabled, making it easy to build web APIs, store
drawings in databases, or convert between formats.
See the full example: [`examples/serde_json.rs`](examples/serde_json.rs)
### Creating 3D Solids (ACIS)
acadrust includes a SAT/SAB builder for creating ACIS 3DSOLID entities from scratch.
The builder emits SAT v7.0 text for R2000βR2007 and SAB binary for R2013+.
```rust
use acadrust::{CadDocument, DwgWriter, DxfVersion, EntityType};
use acadrust::entities::Solid3D;
use acadrust::entities::acis::{SatDocument, SatPointer, Sense, Sidedness};
fn main() -> acadrust::Result<()> {
// Start a new ACIS body
let mut sat = SatDocument::new_body();
let body_idx = SatPointer::new(0);
// Geometry: 6 plane surfaces for a 10Γ10Γ10 box
let surf_top = sat.add_plane_surface([0.0, 0.0, 5.0], [0.0, 0.0, 1.0], [1.0, 0.0, 0.0]);
let surf_bottom = sat.add_plane_surface([0.0, 0.0, -5.0], [0.0, 0.0, -1.0], [1.0, 0.0, 0.0]);
// ... add remaining surfaces, curves, vertices, edges, coedges, loops, faces, shell, lump
// Wrap in a Solid3D and write to DWG
let mut solid = Solid3D::new();
solid.set_sat_document(&sat);
let mut doc = CadDocument::with_version(DxfVersion::AC1027); // R2013
doc.add_entity(EntityType::Solid3D(solid))?;
DwgWriter::write_to_file("box.dwg", &doc)?;
Ok(())
}
```
Available surface/curve builders:
| `add_plane_surface` | Infinite plane (origin, normal, u-axis) |
| `add_cone_surface` | Cone / cylinder (center, axis, major-axis, ratio, half-angle) |
| `add_sphere_surface` | Sphere (center, axis, radius) |
| `add_torus_surface` | Torus (center, axis, major/minor radii) |
| `add_straight_curve` | Infinite line (point, direction) |
| `add_ellipse_curve` | Ellipse / circle (center, normal, major-axis, ratio) |
See the full example: [`examples/write_3dsolid_dwg.rs`](examples/write_3dsolid_dwg.rs) β builds a box, wedge, pyramid, and cylinder.
### 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 |
| `serde` | Serialization/deserialization (optional) |
---
## π§ͺ 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.
### Roundtrip Data Integrity Test
Verify lossless writeβreadβwriteβread fidelity across all 26 entity types Γ 8 DWG versions (208 test cases):
```bash
cargo run --example test_roundtrip
```
All 208 roundtrips pass with **zero data drift** β 0 Trip1 field losses, 0 Trip2 divergence, 0 write failures.
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)
- [x] 208/208 roundtrip data integrity (0 field drift across all entity types Γ all versions)
- [x] Optional serde support (`Serialize` / `Deserialize` for all types)
- [x] ACIS 3DSOLID read/write β SAT text (R2000βR2007) and SAB binary (R2013+) with builder API
- [ ] 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>