Expand description
Streaming, callback-based Wavefront OBJ reader and writer with matched read/write traits.
§Why
Most OBJ crates on crates.io eagerly load a file into a Mesh struct.
That works great when the input fits in memory and you don’t care about
preserving exact byte layout. This crate fills the opposite niche:
- Streaming.
read_obj_filewalks the file once and dispatches to trait callbacks - no intermediate allocation per element. You can process arbitrarily large meshes by writing your ownObjReaderthat pushes data straight into the buffer of your choice. - Round-trip fidelity.
ObjReaderandObjWriterare matched trait pairs: every directive a reader can produce, a writer can emit. That makes byte-equal round trips of OBJ files trivial. - Configurable float precision. Read and write
f32orf64via theObjFloatgeneric parameter. - Strict-by-default with explicit opt-in for lenient parsing.
ObjReader::read_unknownreturns an error by default; override it to silently skip directives you don’t care about (e.g. NURBS).
If what you want is let mesh = obj::load(path)?, use
tobj instead - that is the right tool
for that job.
§Supported directives
Core geometry: v, vt, vn, f, o, # comments.
Standard auxiliary directives have first-class trait methods on both
ObjReader and ObjWriter: mtllib, usemtl, g, s (with
SmoothingGroup), l, p.
Anything else (NURBS / free-form geometry, display attributes, vendor
extensions) routes to ObjReader::read_unknown - reject or ignore as
you see fit.
§Quick start
use wavefront_obj_io::{ObjReader, read_obj_file};
use std::io::Cursor;
#[derive(Default)]
struct CountVertices(usize);
impl ObjReader<f32> for CountVertices {
fn read_comment(&mut self, _: &str) {}
fn read_object_name(&mut self, _: &str) {}
fn read_vertex(&mut self, _: f32, _: f32, _: f32, _: Option<f32>) {
self.0 += 1;
}
fn read_texture_coordinate(&mut self, _: f32, _: Option<f32>, _: Option<f32>) {}
fn read_normal(&mut self, _: f32, _: f32, _: f32) {}
fn read_face(&mut self, _: &[(usize, Option<usize>, Option<usize>)]) {}
}
let obj = "v 0 0 0\nv 1 0 0\nv 0 1 0\n";
let mut counter = CountVertices::default();
read_obj_file(Cursor::new(obj), &mut counter).unwrap();
assert_eq!(counter.0, 3);Indices follow the Wavefront convention and are kept 1-based throughout the API.
Structs§
Enums§
- ObjError
- Error type returned by
read_obj_file. - Parse
Error Kind - Structured description of an OBJ syntax problem.
- Smoothing
Group - Smoothing group selector for the
sdirective.
Traits§
- ObjFloat
- Trait for floating point types that can be used in OBJ files. This allows the library to work with both f32 and f64 precision.
- ObjReader
- Trait for reading OBJ file data with configurable float precision.
- ObjWriter
- Trait for writing OBJ file data with configurable float precision.