wavefront-obj-io 0.1.0

Streaming, callback-based Wavefront OBJ reader and writer with matched read/write traits
Documentation

wavefront-obj-io

Crates.io Docs.rs

Streaming, callback-based Wavefront OBJ reader and writer in Rust. For round-trip pipelines and large files.

When to use this crate

  • You want to process OBJ files without allocating a Mesh struct - e.g. push vertices straight into a GPU buffer.
  • You want to round-trip an OBJ file (read then write back) without losing fidelity.
  • You're building an OBJ format converter / preprocessor / validator.
  • You need to handle files too large to comfortably fit in memory.

When not to use this crate

If you just want let mesh = load(path)?, use tobj. It is the right tool for that job and this crate intentionally does not compete with it.

Example

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);

Features

  • Streaming, SAX-style callback API on ObjReader / ObjWriter traits.
  • Configurable float precision (f32 or f64) via the ObjFloat generic.
  • Standard directive coverage: v, vt, vn, f, o, #, mtllib, usemtl, g, s, l, p.
  • Strict-by-default read_unknown callback - opt in to lenient parsing for NURBS / display / vendor directives.
  • Typed ObjError with structured ParseErrorKind for pattern-matching; bidirectional From between ObjError and io::Error.
  • WASM-compatible, no platform-specific dependencies.

Documentation

https://docs.rs/wavefront-obj-io

Development

This project uses Conventional Commits for commit messages, and rustfmt + clippy for formatting and linting.

cargo fmt
cargo clippy --all-targets -- -D warnings

Running the tests

cargo test

WASM tests for server-side WASM (wasmtime)

# Install the target and wasmtime (one-time setup)
rustup target add wasm32-wasip1
cargo install wasmtime-cli

cargo test --target wasm32-wasip1

WASM build for browser

rustup target add wasm32-unknown-unknown

cargo build --target wasm32-unknown-unknown

License

MIT