#!/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)"