"""Runtime configuration (all overridable via env). Defaults target the `genrecon` LXC produced by issue i-opavuyaq; the MOCK path lets the whole app run/test on any machine without a GPU or the GenRecon install.""" import os from pathlib import Path BASE = Path(__file__).resolve().parent ROOT = BASE.parent def _flag(name: str, default: str = "0") -> bool: return str(os.environ.get(name, default)).lower() in ("1", "true", "yes", "on") # --- mode --- MOCK = _flag("GENRECON_MOCK") # skip GPU pipeline, emit the sample scene # --- paths --- JOBS_DIR = Path(os.environ.get("GENRECON_JOBS_DIR", "/srv/jobs")) FRONTEND_DIR = Path(os.environ.get("GENRECON_FRONTEND_DIR", str(ROOT / "frontend"))) SAMPLE_GLB = Path(os.environ.get("GENRECON_SAMPLE_GLB", str(ROOT / "sample" / "scene.glb"))) # --- GenRecon install (on the genrecon machine) --- GENRECON_SRC = Path(os.environ.get("GENRECON_SRC", "/opt/genrecon/src")) GENRECON_CKPTS = Path(os.environ.get("GENRECON_CKPTS", "/opt/genrecon/ckpts")) CONDA_ENV = os.environ.get("GENRECON_CONDA_ENV", "genrecon") CUDA_DEVICE = os.environ.get("GENRECON_CUDA_DEVICE", "5") # pin to a free GPU on hypervisor a # --- pipeline knobs --- FFMPEG_BIN = os.environ.get("GENRECON_FFMPEG_BIN", "ffmpeg") COLMAP_BIN = os.environ.get("GENRECON_COLMAP_BIN", "colmap") FRAMES_FPS = float(os.environ.get("GENRECON_FRAMES_FPS", "2")) FRAMES_MAX = int(os.environ.get("GENRECON_FRAMES_MAX", "300")) NUM_IMGS_PER_SCENE = int(os.environ.get("GENRECON_NUM_IMGS", "999")) PIPELINE_CONFIG = os.environ.get("GENRECON_PIPELINE_CONFIG", "configs/pipelines/texture.json") MAX_UPLOAD_MB = int(os.environ.get("GENRECON_MAX_UPLOAD_MB", "2048")) # reconstruct_scene.py Iphone-mode knobs. pipeline.py MUST pass these — when # omitted, the chunker falls back to more aggressive internal defaults # (stat_std_ratio 2.0) that can strip a sparse COLMAP cloud to 0 points and # crash the PLY export. These are the README-validated values; radius_m is a # metric radius, so on arbitrary-scale COLMAP clouds (plain video, no ARKit) # loosen it (raise radius_m / lower radius_nb_points) if cleaning wipes points. # Web-optimize the raw GenRecon glb (100s of MB) into a browser-loadable # walkthrough asset (simplify + webp). Best-effort; the raw mesh is kept as # scene_raw.glb. Needs a local gltf-transform install (see backend/optimize_glb.sh). WEB_OPTIMIZE = _flag("GENRECON_WEB_OPTIMIZE", "1") OPTIMIZE_GLB_SCRIPT = os.environ.get("GENRECON_OPTIMIZE_SCRIPT", str(BASE / "optimize_glb.sh")) CHUNK_SIZE_FACTOR = os.environ.get("GENRECON_CHUNK_SIZE_FACTOR", "1.08") STAT_STD_RATIO = os.environ.get("GENRECON_STAT_STD_RATIO", "3.0") RADIUS_NB_POINTS = os.environ.get("GENRECON_RADIUS_NB_POINTS", "7") # radius_m is a METRIC radius in GenRecon (tuned for ARKit-scale iPhone captures). # Our app reconstructs from a plain video → COLMAP, which is only up-to-scale, so a # fixed 0.2 wipes the cloud. "auto" (default) derives radius_m from the actual # point-cloud spacing per job (pipeline._resolve_radius_m); set a number to force it. RADIUS_M = os.environ.get("GENRECON_RADIUS_M", "auto") RADIUS_K = float(os.environ.get("GENRECON_RADIUS_K", "4.0")) # radius_m = median_nn_dist × RADIUS_K PROJ_BATCH_VOXELS = os.environ.get("GENRECON_PROJ_BATCH_VOXELS", "2048") JOBS_DIR.mkdir(parents=True, exist_ok=True) # Stage order + the progress band each stage fills (start, end). STAGES = [ ("frames", 5, 25), ("colmap", 25, 55), ("reconstruct", 55, 90), ("glb", 90, 100), ]