Skip to main content

oxideav_obj/
lib.rs

1//! Pure-Rust Wavefront OBJ + MTL 3D mesh codec.
2//!
3//! Implements [`oxideav_mesh3d::Mesh3DDecoder`] and
4//! [`oxideav_mesh3d::Mesh3DEncoder`] for the polygonal subset of the
5//! OBJ format published by Wavefront Technologies in the early 1990s
6//! (Appendix B of the *Advanced Visualizer* manual). Companion MTL
7//! material files are parsed/serialised by the same crate so a
8//! decoded [`Scene3D`](oxideav_mesh3d::Scene3D) carries its full
9//! material set.
10//!
11//! # Modules
12//!
13//! * [`obj`] — line-oriented parser and serialiser for the geometry
14//!   format itself (`v` / `vt` / `vn` / `f` / `l` / `p` / `o` / `g` /
15//!   `s` / `mg` / `usemtl` / `mtllib`).
16//! * [`mtl`] — line-oriented parser and serialiser for the material
17//!   library (`newmtl` / `Ka` / `Kd` / `Ks` / `Ke` / `Ns` / `Ni` /
18//!   `d` / `Tr` / `Tf` / `sharpness` / `illum` / `map_*` and the
19//!   Wavefront-PBR extension `Pr` / `Pm` / `Pc` / `Ps` / `map_Pr` /
20//!   `map_Pm`).
21//! * [`decoder`] — [`ObjDecoder`] type wired to the
22//!   [`Mesh3DDecoder`](oxideav_mesh3d::Mesh3DDecoder) trait.
23//! * [`encoder`] — [`ObjEncoder`] type wired to the
24//!   [`Mesh3DEncoder`](oxideav_mesh3d::Mesh3DEncoder) trait.
25//!
26//! # Standalone build
27//!
28//! Drop the `registry` feature for a free-standing build:
29//!
30//! ```toml
31//! oxideav-obj = { version = "0.0", default-features = false }
32//! ```
33//!
34//! This compiles out the [`register`] helper and the `oxideav-core`
35//! dependency; the [`ObjDecoder`] and [`ObjEncoder`] types remain
36//! usable directly through the standalone
37//! [`Mesh3DDecoder`](oxideav_mesh3d::Mesh3DDecoder) /
38//! [`Mesh3DEncoder`](oxideav_mesh3d::Mesh3DEncoder) traits.
39
40#![forbid(unsafe_code)]
41#![warn(missing_debug_implementations)]
42
43pub mod decoder;
44pub mod encoder;
45pub mod mtl;
46pub mod obj;
47
48pub use decoder::ObjDecoder;
49pub use encoder::ObjEncoder;
50
51/// Register OBJ + MTL decoders and encoders with a
52/// [`Mesh3DRegistry`](oxideav_mesh3d::Mesh3DRegistry).
53///
54/// Two format ids land:
55///
56/// * `"obj"` — extension `.obj`. Decoder produces a fully-populated
57///   `Scene3D`; encoder emits a single OBJ document and accepts a
58///   companion MTL via [`ObjEncoder::with_mtl_basename`].
59/// * `"mtl"` — extension `.mtl`. Decoder produces a `Scene3D` with
60///   only the materials populated (no meshes / nodes); encoder emits
61///   the MTL document for the scene's materials.
62///
63/// The OBJ encoder does **not** automatically write the companion MTL
64/// — that's the caller's job (since they own the file-system context).
65/// See [`mtl::serialize_mtl`] / [`obj::serialize_obj`] if you need to
66/// drive both halves manually.
67#[cfg(feature = "registry")]
68pub fn register(registry: &mut oxideav_mesh3d::Mesh3DRegistry) {
69    registry.register_decoder("obj", &["obj"], Box::new(|| Box::new(ObjDecoder::new())));
70    registry.register_encoder("obj", &["obj"], Box::new(|| Box::new(ObjEncoder::new())));
71    registry.register_decoder(
72        "mtl",
73        &["mtl"],
74        Box::new(|| Box::new(decoder::MtlDecoder::new())),
75    );
76    registry.register_encoder(
77        "mtl",
78        &["mtl"],
79        Box::new(|| Box::new(encoder::MtlEncoder::new())),
80    );
81}