cad-editor/examples/inspect_polyline.rs

174 lines
6.5 KiB
Rust
Raw Normal View History

// One-off inspector for diagnosing a DWG: dumps every LwPolyline/Polyline2D/
// Polyline3D with its elevation, normal vector, and per-vertex coordinates.
// Run with: cargo run --example inspect_polyline -- <path-to-dwg>
use acadrust::entities::EntityType;
use acadrust::io::dwg::DwgReader;
use acadrust::DxfReader;
use std::env;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let path = env::args().nth(1).ok_or("usage: inspect_polyline <file>")?;
let mut doc = if path.to_lowercase().ends_with(".dxf") {
DxfReader::from_file(&path)?.read()?
} else {
DwgReader::from_file(&path)?.read()?
};
// Cheap inline corruption check — mirrors the rules in src/io/mod.rs so the
// example reports the same drop count without needing a library crate.
let total = doc.entities().count();
let bad = doc
.entities()
.filter(|e| {
use acadrust::entities::EntityType as E;
const MAX: usize = 100_000;
let bad_normal = |n: &acadrust::types::Vector3| {
!n.x.is_finite()
|| !n.y.is_finite()
|| !n.z.is_finite()
|| ((n.x * n.x + n.y * n.y + n.z * n.z) - 1.0).abs() >= 0.21
};
match e {
E::LwPolyline(p) => {
bad_normal(&p.normal)
|| p.vertices.len() > MAX
|| !p.elevation.is_finite()
|| p.elevation.abs() > 1e10
}
E::Polyline2D(p) => {
bad_normal(&p.normal)
|| p.vertices.len() > MAX
|| !p.elevation.is_finite()
|| p.elevation.abs() > 1e10
}
_ => false,
}
})
.count();
println!("Entities: total={} corrupt={}", total, bad);
println!();
let _ = &mut doc; // silence unused-mut warning if we don't mutate below
let h = &doc.header;
println!(
"Header extents: min=({:.3},{:.3},{:.3}) max=({:.3},{:.3},{:.3})",
h.model_space_extents_min.x,
h.model_space_extents_min.y,
h.model_space_extents_min.z,
h.model_space_extents_max.x,
h.model_space_extents_max.y,
h.model_space_extents_max.z,
);
println!();
let mut lwp = 0usize;
let mut p2d = 0usize;
let mut p3d = 0usize;
let mut pl = 0usize;
for (i, e) in doc.entities().enumerate() {
match e {
EntityType::LwPolyline(p) => {
lwp += 1;
if p.common.layer != "PLN_Sev" {
continue;
}
let nx_abs = p.normal.x.abs();
let ny_abs = p.normal.y.abs();
let corrupt = !nx_abs.is_finite()
|| nx_abs > 1.0
|| ny_abs > 1.0
|| p.vertices.len() > 1000;
if corrupt {
println!(
"[{}] CORRUPT handle={:?} verts={} elev={:.3e} normal=({:.2e},{:.2e},{:.2e})",
i,
p.common.handle,
p.vertices.len(),
p.elevation,
p.normal.x,
p.normal.y,
p.normal.z,
);
} else {
println!(
"[{}] OK handle={:?} verts={} elev={:.3} normal=({:.4},{:.4},{:.4})",
i,
p.common.handle,
p.vertices.len(),
p.elevation,
p.normal.x,
p.normal.y,
p.normal.z,
);
for (vi, v) in p.vertices.iter().take(3).enumerate() {
println!(" v{}: ({:.3}, {:.3}) bulge={}", vi, v.location.x, v.location.y, v.bulge);
}
}
}
EntityType::Polyline2D(p) => {
p2d += 1;
if p2d <= 5 {
println!(
"[{}] Polyline2D handle={:?} layer={:?}",
i, p.common.handle, p.common.layer
);
println!(
" elevation={} thickness={} normal=({},{},{})",
p.elevation, p.thickness, p.normal.x, p.normal.y, p.normal.z
);
println!(" closed={} verts={}", p.is_closed(), p.vertices.len());
for (vi, v) in p.vertices.iter().enumerate() {
println!(
" v{}: ({}, {}, {}) bulge={}",
vi, v.location.x, v.location.y, v.location.z, v.bulge
);
}
println!();
}
}
EntityType::Polyline3D(p) => {
p3d += 1;
if p3d <= 5 {
println!(
"[{}] Polyline3D handle={:?} layer={:?}",
i, p.common.handle, p.common.layer
);
println!(" closed={} verts={}", p.is_closed(), p.vertices.len());
for (vi, v) in p.vertices.iter().enumerate() {
println!(
" v{}: ({}, {}, {})",
vi, v.position.x, v.position.y, v.position.z
);
}
println!();
}
}
EntityType::Polyline(p) => {
pl += 1;
if pl <= 5 {
println!(
"[{}] Polyline (heavy 3D) handle={:?} layer={:?}",
i, p.common.handle, p.common.layer
);
println!(" closed={} verts={}", p.flags.is_closed(), p.vertices.len());
for (vi, v) in p.vertices.iter().enumerate() {
println!(
" v{}: ({}, {}, {})",
vi, v.location.x, v.location.y, v.location.z
);
}
println!();
}
}
_ => {}
}
}
println!(
"Totals: LwPolyline={} Polyline2D={} Polyline3D={} Polyline={}",
lwp, p2d, p3d, pl
);
Ok(())
}