draco-io
A Rust library for reading and writing 3D mesh file formats with Draco compression support. Built on top of draco-core, this crate provides a unified API for working with OBJ, PLY, FBX, and glTF/GLB formats.
For the project overview, compatibility notes, and benchmarks, see the Draco Rust workspace README.
Features
- Unified API: Common
ReaderandWritertraits across all formats - In-Memory I/O: Common
ReadFromBytesandWriteToBytestraits - Draco Compression: Full support for
KHR_draco_mesh_compressionin glTF/GLB - Document-Preserving Compression: Draco-compress an existing glTF/GLB in
place, keeping materials, textures, animations, and other content (
compress_gltf_bytes) - Multiple Formats: OBJ, PLY, FBX (ASCII/Binary), glTF (JSON/Binary/Embedded)
- Scene Graph Support: Read and write scene hierarchies with transforms
- Point Cloud Support: Read/write point clouds (OBJ, PLY)
- Feature Flags: Per-format reader and writer features
Supported Formats
| Format | Read | Write | Draco Compression | Notes |
|---|---|---|---|---|
| OBJ | ✓ | ✓ | - | Positions, normals, texcoords, named groups, point clouds |
| PLY | ✓ | ✓ | - | ASCII/binary, normals, colors, per-vertex texcoords |
| FBX | ✓ | ✓ | - | Binary 7.x, positions and triangle faces only |
| glTF | ✓ | ✓ | ✓ | JSON + separate .bin |
| GLB | ✓ | ✓ | ✓ | Binary container |
Geometry Contract
draco-io is a geometry bridge for the draco-core data model, not a
general-purpose asset importer. The stable contract is:
- Meshes use triangle faces; readers triangulate polygon faces when the source format provides polygons, and reject unsupported primitive modes explicitly.
Positionis the required mesh attribute.Normal,Color,TexCoord, andGenericare preserved when the format can represent them as Draco attributes.- Scene support is intentionally small: names, hierarchy, transforms, and mesh parts. Materials, textures, cameras, lights, animation, skinning, and arbitrary format extras are out of scope for now.
- Writers should not silently claim to preserve attributes that the target format cannot encode. FBX writing currently accepts position-only meshes.
Installation
Add to your Cargo.toml:
[]
= "0.1"
Feature Flags
| Feature | Default | Description |
|---|---|---|
all-readers |
✓ | Reading support for all formats |
all-writers |
✓ | Writing support for all formats |
obj-reader |
✓ | OBJ reading support |
obj-writer |
✓ | OBJ writing support |
ply-reader |
✓ | PLY reading support |
ply-writer |
✓ | PLY writing support |
fbx-reader |
✓ | FBX reading support |
fbx-writer |
✓ | FBX writing support |
gltf-reader |
✓ | glTF/GLB reading support |
gltf-writer |
✓ | glTF/GLB writing support |
scene |
✓ | Scene graph API for hierarchical formats |
compression |
✓ | zlib compression for FBX |
To use only one format direction (smaller binary):
[]
= { = "0.1", = false, = ["gltf-reader"] }
Quick Start
Reading a Mesh
use ;
use io;
Writing a Mesh
use ;
use Mesh;
use io;
Generic Functions (Polymorphism)
Write format-agnostic code using the trait interface:
use ;
use Mesh;
use io;
// Works with any reader implementation
// Works with any writer implementation
GLB with Draco Compression
use GltfWriter;
use Mesh;
Reading Draco-Compressed glTF
use GltfReader;
Unified Trait API
All readers and writers implement common traits for a consistent interface:
Writer Trait
Reader Trait
In-Memory I/O Traits
Scene Traits
For scene graph support with transforms and hierarchies. Scene APIs are in
draco_io::scene and re-exported from draco_io when the scene feature is
enabled. glTF and FBX readers expose native scene graphs; flat OBJ/PLY readers
can be wrapped explicitly with flatten_to_scene.
Format-Specific Features
OBJ Writer
use ;
let mut obj = new;
// Named object groups
obj.add_mesh?;
// Point clouds
obj.add_points;
obj.write?;
PLY Writer
use PlyWriter;
let mut ply = new;
ply.set_binary_little_endian; // optional, ASCII is the default
// Add mesh
ply.add_mesh?;
// Or point cloud with colors
ply.add_points_with_colors;
ply.write?;
FBX Writer
use FbxWriter;
let mut fbx = new
.with_compression // Enable zlib output (default feature)
.with_compression_threshold; // Min size to compress
fbx.add_mesh?;
fbx.write?;
glTF Writer
use ;
let mut gltf = new;
// Custom quantization settings
let quant = QuantizationBits ;
gltf.add_draco_mesh?;
// Multiple output formats:
gltf.write_glb?; // Binary GLB (single file)
gltf.write_gltf?; // JSON + separate binary
gltf.write_gltf_embedded?; // Pure text with base64
glTF Reader with Scene Graph
use ;
let mut reader = open?;
let scene = reader.read_scene?;
// Traverse scene hierarchy
for node in &scene.root_nodes
Examples
The crate includes several examples:
# Run unified API demo
# Run polymorphic usage demo
# Run glTF demo
# Run FBX demo
Module Structure
draco-io
├── Traits
│ ├── traits::Writer - Common writer interface
│ ├── traits::Reader - Common reader interface
│ ├── traits::WriteToBytes - In-memory writer output
│ ├── traits::ReadFromBytes - In-memory reader input
│ ├── traits::PointCloudWriter - Point cloud writing
│ └── traits::PointCloudReader - Point cloud reading
│
├── Scene (feature = "scene")
│ ├── scene::SceneWriter - Scene graph writing
│ ├── scene::SceneReader - Scene graph reading
│ ├── scene::Scene - Scene container
│ └── scene::flatten_to_scene - Flat mesh adapter
│
├── Readers (feature = "all-readers")
│ ├── obj_reader - Wavefront OBJ
│ ├── ply_reader - Stanford PLY
│ ├── fbx_reader - Autodesk FBX
│ └── gltf_reader - glTF/GLB with Draco support
│
├── Writers (feature = "all-writers")
│ ├── obj_writer - Wavefront OBJ
│ ├── ply_writer - Stanford PLY (ASCII/binary)
│ ├── fbx_writer - Autodesk binary FBX
│ └── gltf_writer - glTF/GLB with Draco compression
│
└── glTF geometry + Draco compression
├── gltf_geometry - Reader-agnostic geometry decode + shared glTF error type
│ (compiled with gltf-reader OR gltf-writer)
└── gltf_compress - Document-preserving Draco compression. The in-memory
compress_gltf_value needs only gltf-writer; the byte API
compress_gltf_bytes also needs gltf-reader
The gltf_geometry split lets callers that already have a parsed glTF document
(for example via draco-gltf on gltf-rs)
reuse the same geometry decoder and drive compress_gltf_value with only the
writer — never linking the glTF reader.
Dependencies
draco-core- Core compression/decompressionthiserror- Error handlingbyteorder- Binary I/Oserde,serde_json- glTF JSON parsingminiz_oxide(optional) - zlib compression for FBX
License
Apache-2.0 (same as the original Draco library)
See Also
- draco-core - Core compression library
- API Reference - Detailed API documentation
- Google Draco - Original C++ implementation