festifun/scripts/splat_via_modelbeast.sh
m3ultra f12b6e0847 Splat upgrade (ideas.md #1) + MODELBEAST crossover
- GET /api/splat serves data/work/splat.ply; manifest reports has_splat
- scene3d: lazy-load @mkkellogg/gaussian-splats-3d DropInViewer when a splat
  exists (rigs/anchors/paths overlay as before); point-cloud fallback intact
- scripts/splat_via_modelbeast.sh: train the splat on the MODELBEAST fleet
  (colmap_poses -> brush_train via the mb queue) and drop it in place
- docs/modelbeast-crossover.md: full crossover map (fleet compute, volumetric
  capture w/ CorridorKey + audio sync, per-moment splats)
Verified in-browser: 32MB room splat rendered via /api/splat with overlays live.
2026-07-16 22:32:01 +10:00

41 lines
2.0 KiB
Bash
Executable File

#!/usr/bin/env bash
# Train a 3DGS splat of this project's scene on the MODELBEAST fleet, and drop
# it where the viewer looks for it (data/work/splat.ply).
#
# Uses the sampled SfM frames (data/work/frames) as input: uploads them to
# MODELBEAST, runs colmap_poses + brush_train on the render farm's queue, and
# downloads the trained splat back. Requires the `mb` CLI env:
# export MB_HOST=http://100.89.131.57:8777 # M3 primary
# export MB_TOKEN=... # from MODELBEAST Settings → Users
#
# (v1 re-runs COLMAP on the farm rather than shipping our local reconstruction —
# simpler and uses the farm's known-good chain; direct dataset handoff is a
# future optimization. See docs/modelbeast-crossover.md.)
set -euo pipefail
cd "$(dirname "$0")/.."
MB=${MB:-/Users/m3ultra/Documents/MODELBEAST/mb}
FRAMES_DIR=${FESTIVAL4D_DATA_DIR:-data}/work/frames
OUT=${FESTIVAL4D_DATA_DIR:-data}/work
[ -d "$FRAMES_DIR" ] || { echo "no frames at $FRAMES_DIR — run the reconstruct step first"; exit 1; }
command -v "$MB" >/dev/null || { echo "mb CLI not found (set MB=/path/to/mb)"; exit 1; }
echo "[splat] uploading frames..."
mapfile -t frames < <(find "$FRAMES_DIR" -name '*.jpg' -o -name '*.png' | sort)
echo "[splat] ${#frames[@]} frames"
ids=$("$MB" upload "${frames[@]}" | awk '{print $1}')
first=$(echo "$ids" | head -1)
echo "[splat] running colmap_poses on the farm..."
cj=$("$MB" run colmap_poses --asset "$first" $(echo "$ids" | tail -n +2 | sed 's/^/--asset /') | grep -oE '[0-9a-f]{10,}' | head -1)
"$MB" wait "$cj"
ds=$("$MB" assets | awk '/colmap_dataset/ {print $1; exit}')
echo "[splat] dataset: $ds — training splat (brush)..."
bj=$("$MB" run brush_train --asset "$ds" | grep -oE '[0-9a-f]{10,}' | head -1)
"$MB" wait "$bj" --download "$OUT/_splat_dl"
ply=$(find "$OUT/_splat_dl" -name '*.ply' | head -1)
[ -n "$ply" ] || { echo "no .ply came back"; exit 1; }
mv "$ply" "$OUT/splat.ply" && rm -rf "$OUT/_splat_dl"
echo "[splat] done → $OUT/splat.ply (restart/reload the app; the 3D view now renders the splat)"