Skip to main content

Browser-side body model evaluation for viser

Project description

body-models-viser

body-models-viser is a browser-oriented implementation of selected body-models models. The goal is to evaluate body models directly in a web viewer, without being limited by viser skinning constraints such as a fixed maximum number of bones per vertex.

The package currently supports unbatched/default SMPL, SMPLH, SMPLX, MHR, ANNY, and SOMA models. The Rust implementation is checked against Python body-models output using JSON fixtures, and the Python wheel ships the JavaScript bundle that can be injected into a viser frontend.

Layout

  • src/ contains the Rust model implementation and JSON CLI.
  • fixtures/ contains small input cases for each model.
  • scripts/generate_reference.py exports model weights and Python reference outputs into generated/.
  • tests/parity.rs compares Rust output against the generated Python outputs.
  • client/ contains the small browser-side skinning helper.

generated/, target/, client/dist/, and client/node_modules/ are local build artifacts and are ignored.

How It Works

Reference data is generated from a local body-models checkout. The script saves two kinds of JSON:

  • generated/model_data/<model>.json: model weights needed by Rust.
  • generated/reference/<model>/<case>.json: expected skeleton and mesh outputs for each fixture.

Rust loads the same fixture JSON as Python, evaluates the model, and emits:

{
  "model": "smpl",
  "case": "rest",
  "skeleton": [],
  "mesh": []
}

The Python package exposes the viser-facing API and injects the bundled browser runtime into viser. Python sends custom body-model messages with unskinned vertices, sparse weights, joint indices, and bone transforms. The browser runtime intercepts those messages, applies skinning with every supplied weight, and forwards a regular viser mesh message to the viewer.

User Usage

Install the Python package:

uv add body-models-viser

Get the bundled browser module from Python:

from body_models_viser import client_path

print(client_path())

Add a model to a viser scene:

import body_models_viser as bmv
from body_models.smpl.numpy import SMPL

handle = bmv.add_body_model(scene, "/body", SMPL(gender="neutral"))
handle.body_pose = next_body_pose

add_body_model() injects the browser runtime automatically. It does not call scene.add_mesh_simple() or scene.add_mesh_skinned(); the mesh sent to viser is produced by the runtime after browser-side skinning.

client_path() returns the packaged body-models-viser.js runtime used for viser injection. Advanced browser integrations can import the same low-level skinning API from the ESM bundle built by the TypeScript package:

import { skinVertices } from "./body-models-viser.module.js";

const vertices = skinVertices({
  vertices: bindVertices,
  skinWeights,
  skinJoints,
  boneTransforms,
});

For development against the TypeScript source, import from client/src/index.ts and run npm test from client/. Do not commit client/dist/; CI builds the JavaScript bundle for releases.

Commands

Generate Python references:

uv run --project ../body-models --no-sync scripts/generate_reference.py

Run Rust parity tests:

cargo test --release

Run the forward benchmark:

cargo run --release --bin bench_forward

Run one fixture through the Rust CLI:

cargo run --release -- \
  --model-data generated/model_data \
  --input fixtures/smpl/rest.json

Build and test the TypeScript package:

cd client
npm test

CI And Releases

GitHub Actions runs three checks:

  • Rust formatting, clippy, and crate/bin tests.
  • TypeScript build and tests from client/src.
  • Python package build after generating the JavaScript bundle in CI.

The JavaScript bundle in client/dist/ is not tracked by git. Releases build it in GitHub Actions, package it into the Python wheel under body_models_viser/client/body-models-viser.js, and publish with uv publish from .github/workflows/release.yml using PyPI trusted publishing.

Notes

The Rust implementation keeps the JSON format simple and builds sparse runtime caches for large sparse model matrices on first use. SOMA identity preparation is intentionally done in Python during reference/model-data export; Rust consumes the prepared identity state and handles pose evaluation, correctives, skinning, and global translation. This keeps the generated data easy to inspect while making repeated forwards fast enough for interactive viewer work.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

body_models_viser-0.0.2.tar.gz (15.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

body_models_viser-0.0.2-py3-none-any.whl (11.0 kB view details)

Uploaded Python 3

File details

Details for the file body_models_viser-0.0.2.tar.gz.

File metadata

  • Download URL: body_models_viser-0.0.2.tar.gz
  • Upload date:
  • Size: 15.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.15 {"installer":{"name":"uv","version":"0.11.15","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for body_models_viser-0.0.2.tar.gz
Algorithm Hash digest
SHA256 68d4718cb14b8091535174e3110dba2fd372763050fb3cc14fe8681208f8624a
MD5 37870377ded4e3d190da5758c1fb9b25
BLAKE2b-256 5b97e057f4abb1de735d701332a281a23b91a2863def846a3dacf014b3238493

See more details on using hashes here.

File details

Details for the file body_models_viser-0.0.2-py3-none-any.whl.

File metadata

  • Download URL: body_models_viser-0.0.2-py3-none-any.whl
  • Upload date:
  • Size: 11.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.15 {"installer":{"name":"uv","version":"0.11.15","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for body_models_viser-0.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 bc349e89a1656617d7cbfc1cd4d367080c812dceec8a8205aa46772ea718b87d
MD5 1dcd21a3485b086591abef536c4e04f3
BLAKE2b-256 b8e606bf244352212a2a08eaac0ccb805ebb12e51f36459beadde05d5a38b312

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page