14 releases (5 breaking)
Uses new Rust 2024
| new 0.6.0 | Jan 6, 2026 |
|---|---|
| 0.5.2 | Nov 30, 2025 |
| 0.4.4 | Nov 28, 2025 |
| 0.3.1 | Nov 27, 2025 |
| 0.1.3 | Nov 25, 2025 |
#1449 in Command line utilities
29KB
377 lines
ply2splat
A Rust crate and CLI tool for converting Gaussian Splatting .ply files to the .splat format.
Available on crates.io for Rust, PyPI for Python, and npm for JavaScript/TypeScript (Node.js & Web).
🌐 Try the Web Converter - Convert files directly in your browser!
Workspace Architecture
This repository is organized as a Cargo workspace:
.
├── crates/
│ ├── ply2splat/ # Core library and CLI tool
│ ├── ply2splat-napi/ # Node.js/WASI bindings via NAPI-RS (@ply2splat/native)
│ ├── ply2splat-python/ # Python bindings via PyO3
│ └── ply2splat-wasm/ # Low-level WASM bindings (wasm-bindgen)
└── www/
└── ply2splat/ # Web application (React + WASM)
Features
- High Performance: Utilizes parallel processing (via
rayon) for conversion and sorting. - Fast I/O: Uses zero-copy serialization and large buffers for maximum throughput.
- Correctness: Implements the standard conversion logic including Spherical Harmonics (SH) to color conversion and geometric transformations.
- Python Bindings: Use the library directly from Python via PyO3.
- Node.js & Web Support: High-performance bindings for Node.js (Native) and Web (WASI) via
@ply2splat/native. - Browser-Based Converter: Convert files directly in your browser with the web app.
Installation
Web App (No Installation Required)
The easiest way to convert files is using the web application:
🌐 https://bastikohn.github.io/ply2splat/
Features:
- Runs entirely in your browser
- No file upload required - all processing is local
- Fast WebAssembly-powered conversion
- Simple drag-and-drop interface
Rust Crate
Add ply2splat to your Cargo.toml:
[dependencies]
ply2splat = "0.6"
CLI
Install the CLI tool directly from crates.io:
cargo install ply2splat
Or build from source:
git clone https://github.com/bastikohn/ply2splat.git
cd ply2splat
cargo build --release
The binary will be available at target/release/ply2splat.
Python Package
Install from PyPI using uv:
uv pip install ply2splat
Or install from source:
git clone https://github.com/bastikohn/ply2splat.git
cd ply2splat
uv pip install .
npm Package (Node.js & Web)
Install @ply2splat/native from npm:
npm install @ply2splat/native
This package provides high-performance native bindings for Node.js and falls back to WASM/WASI for supported environments.
Usage
CLI
Standard Installation (Rust)
ply2splat --input input.ply --output output.splat
Run via uvx (Python)
If you have uv installed, you can run the CLI directly without explicit installation:
uvx ply2splat --input input.ply --output output.splat
Run via Nix
If you have Nix installed:
nix run github:bastikohn/ply2splat -- --input input.ply --output output.splat
Native CLI via Node.js
You can also run the high-performance Rust CLI directly via Node.js without installing Rust or compiling the binary manually.
# Run directly via npx
npx @ply2splat/native --input input.ply --output output.splat
Python
import ply2splat
# Convert a PLY file to SPLAT format
count = ply2splat.convert("input.ply", "output.splat")
print(f"Converted {count} splats")
# Convert without sorting (faster, but may affect rendering quality)
count = ply2splat.convert("input.ply", "output.splat", sort=False)
# Load PLY file and access individual splats
data = ply2splat.load_ply_file("input.ply")
print(f"Loaded {len(data)} splats")
for splat in data:
print(f"Position: {splat.position}")
print(f"Scale: {splat.scale}")
print(f"Color (RGBA): {splat.color}")
print(f"Rotation: {splat.rotation}")
# Access splats by index
first_splat = data[0]
# Load existing SPLAT file
data = ply2splat.load_splat_file("output.splat")
print(f"Loaded {len(data)} splats from SPLAT file")
# Get raw bytes for custom processing
raw_bytes = data.to_bytes()
# Load and convert to bytes (for in-memory processing)
data, count = ply2splat.load_and_convert("input.ply")
print(f"Loaded {count} splats, {len(data)} bytes")
JavaScript/TypeScript (Node.js)
import { convert, getSplatCount } from "@ply2splat/native";
import { readFileSync } from "fs";
// Read PLY file into a buffer
const plyBuffer = readFileSync("input.ply");
// Convert to SPLAT format
// Returns { data: Buffer, count: number }
const result = convert(plyBuffer);
console.log(`Converted ${result.count} splats`);
console.log(`Output size: ${result.data.length} bytes`);
// Optionally disable sorting
// const result = convert(plyBuffer, false);
Development
Requirements
- Rust (latest stable)
- Node.js & pnpm (for JS bindings)
- Python & uv (for Python bindings)
Running Tests
# Test the entire workspace
cargo test --workspace
Fuzzing
The crate includes fuzzing targets to ensure stability against malformed inputs.
# Install cargo-fuzz
cargo install cargo-fuzz
# Run fuzzing target
cargo fuzz run fuzz_conversion
Development Environment
This project supports both Nix and Devcontainers for a reproducible development environment.
- Nix:
nix developwill enter a shell with Rust and dependencies configured. - Devcontainer: Open the folder in VS Code and accept the prompt to reopen in container.
License
MIT
Dependencies
~0.6–5MB
~92K SLoC