use std::io::Cursor;
use acadrust::entities::underlay::{Underlay, UnderlayDisplayFlags, UnderlayType};
use acadrust::entities::EntityType;
use acadrust::objects::{ObjectType, UnderlayDefinition};
use acadrust::types::{DxfVersion, Handle, Vector2, Vector3};
use acadrust::{CadDocument, DwgReader, DwgWriter, DxfReader, DxfWriter};
fn dwg_roundtrip(doc: &CadDocument) -> CadDocument {
let bytes = DwgWriter::write_to_vec(doc).expect("DWG write failed");
DwgReader::from_stream(Cursor::new(bytes))
.read()
.expect("DWG read failed")
}
fn dxf_roundtrip(doc: &CadDocument) -> CadDocument {
let bytes = DxfWriter::new(doc).write_to_vec().expect("DXF write failed");
DxfReader::from_reader(Cursor::new(bytes))
.expect("DXF reader init failed")
.read()
.expect("DXF read failed")
}
fn sample_underlay(kind: UnderlayType) -> Underlay {
let mut u = Underlay::new(kind);
u.normal = Vector3::new(0.0, 0.0, 1.0);
u.insertion_point = Vector3::new(10.0, 20.0, 5.0);
u.rotation = 0.5;
u.x_scale = 2.0;
u.y_scale = 3.0;
u.z_scale = 1.5;
u.flags = UnderlayDisplayFlags::CLIPPING | UnderlayDisplayFlags::ON;
u.contrast = 75;
u.fade = 20;
u.definition_handle = Handle::new(0x2A);
u.clip_boundary_vertices = vec![
Vector2::new(0.0, 0.0),
Vector2::new(100.0, 0.0),
Vector2::new(100.0, 50.0),
];
u
}
fn roundtrip_underlay(version: DxfVersion, kind: UnderlayType) -> Underlay {
let mut doc = CadDocument::with_version(version);
doc.add_entity(EntityType::Underlay(sample_underlay(kind)))
.unwrap();
let rt = dwg_roundtrip(&doc);
let found = rt.entities().find_map(|e| match e {
EntityType::Underlay(u) => Some(u.clone()),
_ => None,
});
found.expect("UNDERLAY missing after DWG roundtrip")
}
fn assert_fields(u: &Underlay, kind: UnderlayType, label: &str) {
assert_eq!(u.underlay_type, kind, "{label}: underlay type");
assert_eq!(
u.insertion_point,
Vector3::new(10.0, 20.0, 5.0),
"{label}: insertion point"
);
assert_eq!(u.rotation, 0.5, "{label}: rotation");
assert_eq!(u.x_scale, 2.0, "{label}: x scale");
assert_eq!(u.y_scale, 3.0, "{label}: y scale");
assert_eq!(u.z_scale, 1.5, "{label}: z scale");
assert_eq!(
u.flags,
UnderlayDisplayFlags::CLIPPING | UnderlayDisplayFlags::ON,
"{label}: display flags"
);
assert_eq!(u.contrast, 75, "{label}: contrast");
assert_eq!(u.fade, 20, "{label}: fade");
assert_eq!(u.definition_handle, Handle::new(0x2A), "{label}: def handle");
assert_eq!(
u.clip_boundary_vertices.len(),
3,
"{label}: clip vertex count"
);
assert_eq!(
u.clip_boundary_vertices[2],
Vector2::new(100.0, 50.0),
"{label}: last clip vertex"
);
}
#[test]
fn underlay_pdf_dwg_roundtrip_all_versions() {
for version in [
DxfVersion::AC1015,
DxfVersion::AC1018,
DxfVersion::AC1024,
DxfVersion::AC1032,
] {
let u = roundtrip_underlay(version, UnderlayType::Pdf);
assert_fields(&u, UnderlayType::Pdf, &format!("PDF {version:?}"));
}
}
fn definition_document(version: DxfVersion, kind: UnderlayType) -> CadDocument {
let mut doc = CadDocument::with_version(version);
let mut def = UnderlayDefinition::new(kind);
def.handle = Handle::new(0x400);
def.owner_handle = Handle::new(0x0C); def.file_path = "C:/refs/site-plan.pdf".to_string();
def.page_name = "Sheet1".to_string();
doc.objects
.insert(def.handle, ObjectType::UnderlayDefinition(def));
doc
}
fn extract_definition(doc: &CadDocument) -> UnderlayDefinition {
doc.objects
.values()
.find_map(|o| match o {
ObjectType::UnderlayDefinition(d) => Some(d.clone()),
_ => None,
})
.expect("underlay definition missing after roundtrip")
}
fn assert_def(d: &UnderlayDefinition, kind: UnderlayType, label: &str) {
assert_eq!(d.underlay_type, kind, "{label}: def underlay type");
assert_eq!(d.file_path, "C:/refs/site-plan.pdf", "{label}: def file path");
assert_eq!(d.page_name, "Sheet1", "{label}: def page name");
assert_eq!(d.handle, Handle::new(0x400), "{label}: def handle");
}
#[test]
fn underlay_definition_dwg_roundtrip() {
for kind in [UnderlayType::Pdf, UnderlayType::Dwf, UnderlayType::Dgn] {
let doc = definition_document(DxfVersion::AC1032, kind);
let d = extract_definition(&dwg_roundtrip(&doc));
assert_def(&d, kind, &format!("DWG {kind:?}"));
}
}
#[test]
fn underlay_definition_dxf_roundtrip() {
for kind in [UnderlayType::Pdf, UnderlayType::Dwf, UnderlayType::Dgn] {
let doc = definition_document(DxfVersion::AC1032, kind);
let d = extract_definition(&dxf_roundtrip(&doc));
assert_def(&d, kind, &format!("DXF {kind:?}"));
}
}
#[test]
fn underlay_flavours_preserved() {
for kind in [UnderlayType::Pdf, UnderlayType::Dwf, UnderlayType::Dgn] {
let u = roundtrip_underlay(DxfVersion::AC1032, kind);
assert_fields(&u, kind, &format!("{kind:?}"));
}
}