//! # Example: File Import (OBJ) //! //! Demonstrates loading a Wavefront OBJ file with `wsg_lib::mesh::load_obj`. //! Parses the file and prints geometry statistics. //! //! ## Build & Run //! ```sh //! cargo run -p wsg-lib --example import --features import-obj -- /path/to/model.obj //! ``` //! //! Without a file argument, parses a built-in sample triangle. use wsg_lib::mesh::import::parse_obj; use wsg_lib::mesh::load_obj; fn main() { let args: Vec = std::env::args().collect(); let content = if args.len() > 1 { let path = &args[1]; eprintln!("Loading: {path}"); match load_obj(path) { Ok(geom) => { print_stats(&geom); return; } Err(e) => { eprintln!("Error: {e}"); std::process::exit(1); } } } else { eprintln!("No file argument — parsing a built-in sample."); eprintln!("Usage: import "); // Built-in sample: a simple triangle with UVs and normals "v 0.0 0.0 0.0\nv 1.0 0.0 0.0\nv 0.5 1.0 0.0\nvn 0 0 1\nvt 0.0 0.0\nvt 1.0 0.0\nvt 0.5 1.0\nf 1/1/1 2/2/1 3/3/1\n" }; let geom = parse_obj(content).expect("sample should parse"); print_stats(&geom); } fn print_stats(geom: &wsg_lib::Geometry) { println!("\n=== Geometry Statistics ==="); println!(" Vertices: {}", geom.positions.len()); if let Some(n) = &geom.normals { println!(" Normals: {}", n.len()); } if let Some(uv) = &geom.uvs { println!(" UVs: {}", uv.len()); } if let Some(idx) = &geom.indices { println!(" Indices: {} ({} triangles)", idx.len(), idx.len() / 3); } if let Err(e) = geom.validate() { println!(" Validation FAILED: {e}"); } else { println!(" Validation: OK"); } // Bounding box if let Some(bbox) = geom.bbox() { println!(" BBox min: {:?}", bbox.min); println!(" BBox max: {:?}", bbox.max); } println!(); }