SPZ is a compressed file format for 3D Gaussian Splats, designed by Niantic. It provides efficient storage of Gaussian Splat data with configurable spherical harmonics degrees and coordinate system support.
See docs/SPZ.md for more information.
$ # install:
$ cargo install spz
$ # or
$ flatpak install io.github.jackneill.spz
$ # or
$ snap install spz
$
$ # run:
$ path/to/spz info assets/racoonfamily.spz
GaussianSplat={num_points=932560, sh_degree=3, antialiased=true, median_ellipsoid_volume=0.0000000046213082, bbox=[x=-281.779541 to 258.382568, y=-240.000000 to 240.000000, z=-240.000000 to 240.000000]}[dependencies]
spz = { version = "0.0.7", default-features = false, features = [] }use spz::prelude::*;cargo run --example load_spz// SPDX-License-Identifier: Apache-2.0 OR MIT
use std::path::{Path, PathBuf};
use anyhow::{Context, Result};
use spz::{coord::CoordinateSystem, gaussian_splat::GaussianSplat, unpacked::UnpackOptions};
fn main() -> Result<()> {
let mut sample_spz = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
sample_spz.push("../../assets/racoonfamily.spz");
let _gs1 = GaussianSplat::builder()
.filepath(&sample_spz)
.packed(true)?
.unpack_options(
UnpackOptions::builder()
.to_coord_system(CoordinateSystem::UNSPECIFIED)
.build(),
)
.load()
.with_context(|| format!("unable to load file: {:?}", sample_spz))?;
let _gs0 = GaussianSplat::builder().filepath(&sample_spz).load()?;
Ok(())
}
#[allow(unused)]
async fn load_spz_async<P>(spz_file: P) -> Result<GaussianSplat>
where
P: AsRef<Path>,
{
GaussianSplat::builder()
.filepath(spz_file.as_ref())
.packed(true)?
.unpack_options(
UnpackOptions::builder()
.to_coord_system(CoordinateSystem::UNSPECIFIED)
.build(),
)
.load_async()
.await
.with_context(|| format!("unable to load file: {:?}", spz_file.as_ref()))
}#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
pub struct GaussianSplat {
pub num_points: i32,
pub spherical_harmonics_degree: i32,
pub antialiased: bool,
pub positions: Vec<f32>,
pub scales: Vec<f32>,
pub rotations: Vec<f32>,
pub alphas: Vec<f32>,
pub colors: Vec<f32>,
pub spherical_harmonics: Vec<f32>,
}- Install
nextestrunner. - For fuzz testing:
cargo install cargo-fuzz- Further documentation is available in fuzz/README.md.
- Install cargo-mutants for test insights.
cargo install cargo-mutants
just test
just fuzz
just mutantscargo install cargo-criterion- Install
gnuplotfor html reports.
just bench- The html report of the benchmark can be found under
./target/criterion/report/index.html. - View Benchmark and Profiling data on CodSpeed, (from CI runs).
- Install the
moldlinker: https://github.com/rui314/mold
uvx pip install spz# pyproject.toml
[project]
dependencies = [
"spz",
]import spz
# Load from file
splat = spz.load("scene.spz") # -> GaussianSplat
# or
splat = spz.GaussianSplat.load(
"scene.spz", coordinate_system=spz.CoordinateSystem.RUB
) # -> GaussianSplat
# or
with spz.SplatReader("scene.spz") as ctx:
splat2 = ctx.splat # -> GaussianSplat
with spz.temp_save(splat) as tmp_path:
import subprocess
subprocess.run(["viewer", str(tmp_path)])
# Access properties
print(f"{splat.num_points:,} points")
print(f"center: {splat.bbox.center}")
print(f"size: {splat.bbox.size}")
# Access data (flat arrays, list[float])
positions = splat.positions # [x1, y1, z1, x2, y2, z2, ...]
scales = splat.scales
rotations = splat.rotations
alphas = splat.alphas
colors = splat.colors
sh = splat.spherical_harmonics
# Serialize
data = splat.to_bytes() # -> bytes
splat2 = spz.GaussianSplat.from_bytes(data) # -> GaussianSplat
# Create from data
new_splat = spz.GaussianSplat(
positions=[0.0, 0.0, 0.0, 1.0, 2.0, 3.0], # flat array
scales=[-5.0] * 6,
rotations=[1.0, 0.0, 0.0, 0.0] * 2,
alphas=[0.5, 0.8],
colors=[255.0, 0.0, 0.0, 0.0, 255.0, 0.0],
) # -> GaussianSplat
# Save to file
new_splat.save("output.spz")
with spz.SplatWriter("output2.spz") as writer:
writer.splat = splat2
with spz.modified_splat("scene.spz", "scene_rotated.spz") as splat:
splat.rotate_180_deg_about_x()Further documentation is available under ./docs.
Licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
SPDX-License-Identifier: Apache-2.0
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
SPDX-License-Identifier: MIT
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.