Skip to main content

Crate uvunwrap

Crate uvunwrap 

Source
Expand description

§uvunwrap

Pure-Rust automatic UV unwrapping, in the spirit of xatlas: generates unique, non-overlapping texture coordinates suitable for lightmaps, texture baking and painting.

The pipeline has three stages:

  1. Segmentation — faces are grouped into charts by region growing within a normal cone (Options::max_chart_angle).
  2. Parameterization — each chart is flattened with Least Squares Conformal Maps (or planar projection when flat). Results with flipped triangles, self-overlap or too much area distortion (Options::max_area_distortion) are split and retried, so the output is always valid.
  3. Packing — charts are rasterized and packed by shape into one or more atlas pages, nesting into each other’s concavities, or folded into rows for speed (Packing).
// A unit quad made of two triangles.
let positions = [[0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [1.0, 1.0, 0.0], [0.0, 1.0, 0.0]];
let indices = [0, 1, 2, 0, 2, 3];
let mesh = uvunwrap::MeshInput::new(&positions, &indices);

let atlas = uvunwrap::generate(&[mesh], &uvunwrap::Options::default()).unwrap();
let out = &atlas.meshes[0];
assert_eq!(out.indices.len(), indices.len());
for v in &out.vertices {
    // `xref` points back to the input vertex; copy its attributes.
    let _original_position = positions[v.xref as usize];
    assert!((0.0..=1.0).contains(&v.uv[0]) && (0.0..=1.0).contains(&v.uv[1]));
}

Output meshes have the same triangles in the same order, but vertices on chart seams are duplicated, so each output vertex carries an OutputVertex::xref to the input vertex it came from.

§Determinism

The same input, options and crate features give bit-identical output regardless of thread count. The platform math library is never used, so without the direct-solver feature the result depends only on IEEE-754 arithmetic and matches across platforms; CI compares output hashes on Linux (x86-64, ARM64), macOS (ARM64), Windows (x86-64), wasm32-wasip1 and wasm32-unknown-unknown. With direct-solver, faer picks SIMD kernels at runtime, so output may differ between CPU architectures (e.g. x86-64 vs ARM); disable it if you cache unwraps or bake lightmaps on one machine and use them on another.

Structs§

Atlas
The generated atlas.
InstanceRect
Where one instance of a mesh lives in the atlas. The instance’s texture coordinate for a vertex is min + uv * (max - min).
MeshInput
An indexed triangle mesh to unwrap.
Options
Unwrapping options. Fields added in future versions will always have defaults, so Options { padding: 4, ..Default::default() } keeps compiling.
OutputMesh
An unwrapped mesh.
OutputVertex
A vertex of an OutputMesh.
Progress
A progress report passed to the callback of generate_with_progress.

Enums§

Density
How texel density and page size are chosen.
Error
Errors returned by generate.
Packing
How charts are arranged in the atlas.
Stage
A pipeline stage, in the order they run.

Functions§

generate
Unwraps the meshes into a shared atlas.
generate_with_progress
generate, reporting progress to callback as it goes. Returning false from the callback cancels the unwrap: work in flight stops promptly and Error::Cancelled is returned.