#!/usr/bin/env bash # Wrapper for the Blender GLB post-processor. # # Usage: # postprocess [options] # postprocess .tmp/glb-gen/furniture/desks/scifi_desk.glb client-tmp/models/furniture/scifi_desk.glb # postprocess .tmp/glb-gen/furniture/desks/scifi_desk.glb # auto-output to .tmp/glb-gen/postproc/... # # Options are passed through to the Blender script: # --target-width FLOAT Target width in world units (default: 1.0) # --target-height FLOAT Target height in world units (default: auto) # --color-threshold FLOAT Dominant color detection threshold (default: 0.25) # --material-name NAME Material slot name (default: mat_primary) # # Output: # Post-processed model (texture preserved) # Recolor mask sidecar (if texture found) set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" BLENDER_SCRIPT="$SCRIPT_DIR/postprocess_glb.py" # Find project root via git PROJECT_ROOT="$(git -C "$SCRIPT_DIR" rev-parse --show-toplevel)" if [ $# -lt 1 ]; then echo "Usage: postprocess [output.glb] [--target-width N] [--color-threshold N]" echo "" echo "If output is omitted, writes to .tmp/glb-gen/postproc/ mirroring the input path." exit 1 fi INPUT_REL="$1" shift # Resolve to absolute if [[ "$INPUT_REL" = /* ]]; then INPUT_ABS="$INPUT_REL" else INPUT_ABS="$(cd "$PROJECT_ROOT" && pwd)/$INPUT_REL" fi if [ ! -f "$INPUT_ABS" ]; then echo "ERROR: Input file not found: $INPUT_ABS" >&2 exit 1 fi # Determine output path if [ $# -ge 1 ] && [[ "$1" != --* ]]; then OUTPUT_REL="$1" shift if [[ "$OUTPUT_REL" = /* ]]; then OUTPUT_ABS="$OUTPUT_REL" else OUTPUT_ABS="$(cd "$PROJECT_ROOT" && pwd)/$OUTPUT_REL" fi else # Auto-output: mirror input path under .tmp/glb-gen/postproc/ # e.g. .tmp/glb-gen/furniture/desks/foo.glb → .tmp/glb-gen/postproc/furniture/desks/foo.glb REL_TO_TMP="${INPUT_REL#.tmp/glb-gen/}" OUTPUT_ABS="$(cd "$PROJECT_ROOT" && pwd)/.tmp/glb-gen/postproc/$REL_TO_TMP" fi mkdir -p "$(dirname "$OUTPUT_ABS")" echo "Post-processing: $(basename "$INPUT_ABS")" echo " Input: $INPUT_REL" echo " Output: ${OUTPUT_ABS#$(cd "$PROJECT_ROOT" && pwd)/}" LOG="${OUTPUT_ABS%.glb}_blender.log" # Blender does not reliably set a non-zero exit code on an uncaught Python # exception (--python-exit-code is not set), so failures must be detected # from the log content and from whether the output file actually appeared — # not from Blender's own exit status alone. Capture the full log first # (temporarily disabling -e so a non-zero Blender exit doesn't abort before # we can inspect it), then filter for the console summary. set +e "$PROJECT_ROOT/tooling/blender" --background \ --python "$BLENDER_SCRIPT" \ -- "$INPUT_ABS" "$OUTPUT_ABS" "$@" > "$LOG" 2>&1 BLENDER_EXIT=$? set -e grep -iE "^ |^=|warning|error|traceback|dominant|mask" "$LOG" || true if [ "$BLENDER_EXIT" -ne 0 ] || [ ! -f "$OUTPUT_ABS" ]; then echo "ERROR: Blender post-process failed (exit $BLENDER_EXIT, output present: $([ -f "$OUTPUT_ABS" ] && echo yes || echo no))" >&2 echo " Full log: ${LOG#$(cd "$PROJECT_ROOT" && pwd)/}" >&2 exit 1 fi MASK="${OUTPUT_ABS%.glb}_mask.png" if [ -f "$MASK" ]; then echo " Mask: ${MASK#$(cd "$PROJECT_ROOT" && pwd)/}" fi echo "Done."