oxigaf_flame/lib.rs
1//! # oxigaf-flame
2//!
3//! FLAME parametric head model implementation in Pure Rust.
4//!
5//! This crate implements the [FLAME (Faces Learned with an Articulated Model and Expressions)](https://flame.is.tue.mpg.de/)
6//! parametric 3D head model in pure Rust, with no dependencies on Python or C/C++ libraries.
7//!
8//! ## Features
9//!
10//! - **FLAME model loading** from `.npy` files (converted from the original `.pkl`)
11//! - **Linear Blend Skinning (LBS)** forward pass: parameters → posed mesh
12//! - **CPU normal map rendering** for diffusion model conditioning
13//! - **Mesh surface point sampling** for Gaussian initialization
14//! - **Zero-cost abstractions** with extensive use of `#[inline]` for performance
15//!
16//! ### Cargo Features
17//!
18//! This crate supports the following feature flags:
19//!
20//! - **`simd`** (optional, requires nightly Rust with `portable_simd`):
21//! Enables SIMD-accelerated vector operations for:
22//! - Normal map rendering (3-4× faster)
23//! - Rodrigues rotation computation
24//! - Blend shape evaluation
25//!
26//! - **`parallel`** (optional):
27//! Enables parallel batch processing with `rayon`:
28//! - `forward_batch_par()` - parallel mesh generation
29//! - `compute_normals_batch_par()` - parallel normal computation
30//! - Near-linear speedup with CPU core count
31//!
32//! - **`full`** (convenience): Enables both `simd` and `parallel` for maximum performance
33//!
34//! Example usage:
35//! ```toml
36//! # In Cargo.toml
37//! oxigaf-flame = { version = "0.1", features = ["parallel"] }
38//! ```
39//!
40//! ## Quick Start
41//!
42//! ```rust,no_run
43//! use oxigaf_flame::{FlameModel, FlameParams};
44//!
45//! // Load FLAME model from directory containing .npy files
46//! let model = FlameModel::load("path/to/flame/model")?;
47//!
48//! // Create neutral parameters (zero shape, expression, pose)
49//! let params = FlameParams::neutral();
50//!
51//! // Run forward pass to get posed mesh
52//! let mesh = model.forward(¶ms);
53//!
54//! println!("Generated mesh with {} vertices", mesh.vertices.len());
55//! # Ok::<(), oxigaf_flame::FlameError>(())
56//! ```
57//!
58//! ## FLAME Parameters
59//!
60//! The FLAME model is controlled by several parameter types:
61//!
62//! - **Shape parameters** (β): Control identity-specific features (typically 100-300 coefficients)
63//! - **Expression parameters** (ψ): Control facial expressions (typically 50-100 coefficients)
64//! - **Pose parameters** (θ): Control joint rotations (5 joints × 3 = 15 values)
65//! - Root rotation (global head orientation)
66//! - Neck rotation
67//! - Jaw rotation
68//! - Left eye rotation
69//! - Right eye rotation
70//! - **Translation**: Global 3D translation applied after posing
71//!
72//! ## Coordinate System
73//!
74//! FLAME uses a **right-handed coordinate system**:
75//! - +X: Right (from the subject's perspective)
76//! - +Y: Up
77//! - +Z: Forward (out of the face)
78//!
79//! Rotations are specified as **axis-angle** vectors and converted to rotation
80//! matrices using [Rodrigues' formula](https://en.wikipedia.org/wiki/Rodrigues%27_rotation_formula).
81//!
82//! ## Performance
83//!
84//! The LBS forward pass is optimized for real-time performance:
85//! - ~1-2ms for standard FLAME mesh (5023 vertices) on modern CPUs
86//! - Critical path functions are marked with `#[inline]`
87//! - Uses `ndarray` for efficient BLAS-accelerated operations
88//!
89//! Run benchmarks with: `cargo bench -p oxigaf-flame`
90//!
91//! ## References
92//!
93//! - [FLAME Paper](https://ps.is.tuebingen.mpg.de/uploads_file/attachment/attachment/400/paper.pdf)
94//! - [FLAME Model](https://flame.is.tue.mpg.de/)
95
96// Strict no-unwrap policy
97#![deny(clippy::unwrap_used)]
98// Allow expect in test code but deny in library code
99#![cfg_attr(not(test), deny(clippy::expect_used))]
100// Additional quality lints
101#![warn(clippy::all, clippy::pedantic)]
102#![allow(clippy::module_name_repetitions)]
103#![allow(clippy::cast_possible_truncation)]
104#![allow(clippy::cast_precision_loss)]
105#![allow(clippy::cast_sign_loss)]
106#![allow(clippy::similar_names)]
107// Nightly feature for portable SIMD (requires both 'simd' feature AND nightly Rust)
108#![cfg_attr(all(feature = "simd", nightly), feature(portable_simd))]
109
110pub mod conversion;
111pub mod error;
112pub mod io;
113pub mod io_safetensors;
114pub mod mesh;
115pub mod model;
116pub mod normal_map;
117pub mod params;
118mod params_builder;
119pub mod sampler;
120pub mod sequence;
121
122// SIMD module (requires nightly + simd feature)
123#[cfg(all(feature = "simd", nightly))]
124pub mod simd;
125
126pub use error::FlameError;
127pub use mesh::Mesh;
128pub use model::{
129 compute_normals_batch, compute_normals_into, recompute_batch_normals, rodrigues,
130 BatchBufferPool, BatchedFlameOutput, FlameModel,
131};
132#[cfg(feature = "parallel")]
133pub use model::{compute_normals_batch_par, recompute_batch_normals_par};
134pub use normal_map::{Camera, NormalMapRenderer};
135pub use params::FlameParams;
136pub use params_builder::FlameParamsBuilder;
137pub use sampler::{sample_mesh_surface, SurfacePoint};