Expand description
Streaming, callback-based Wavefront OBJ and MTL 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.
MTL (material library) files are handled by the matched
MtlReader / MtlWriter pair via read_mtl_file. Supported
directives: newmtl, Ka, Kd, Ks, Ke, Ns, Ni, d, Tr,
illum, and the texture-map family (map_Ka, map_Kd, map_Ks,
map_Ke, map_Ns, map_d, bump / map_bump, disp, decal,
refl). Map options (-bm, -clamp, -o, -s, …) are passed
through verbatim to keep round trips byte-equal.
§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§
- IoMtl
Writer - File-backed
MtlWriter. MirrorsIoObjWriter. - IoObj
Writer
Enums§
- MapKind
- Texture-map directive kind.
- MtlError
- Error type returned by
read_mtl_file. - MtlParse
Error Kind - Structured description of an MTL syntax problem.
- 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§
- MtlReader
- Trait for reading MTL (material library) data.
- MtlWriter
- Trait for writing MTL data. Mirror of
MtlReader. - 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.