File size: 2,233 Bytes
a064299
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
"""Scene catalog for interactive browser demo."""

import json
import os
from typing import Any


def _repo_root() -> str:
    return os.path.dirname(os.path.dirname(os.path.abspath(__file__)))


def _abs(repo_root: str, rel_path: str) -> str:
    return os.path.normpath(os.path.join(repo_root, rel_path))


def load_interactive_scenes(config_path: str, repo_root: str | None = None) -> list[dict[str, Any]]:
    repo_root = repo_root or _repo_root()
    config_abs = config_path if os.path.isabs(config_path) else _abs(repo_root, config_path)
    with open(config_abs, encoding="utf-8") as f:
        data = json.load(f)

    scenes = []
    for raw in data.get("scenes", []):
        scene = dict(raw)
        scene["model_path"] = _abs(repo_root, scene["model_path"])
        scene["physics_config"] = _abs(repo_root, scene["physics_config"])
        if not validate_scene(scene, repo_root):
            print(f"[interactive] skip scene (missing files): {scene.get('id')}")
            continue
        scenes.append(scene)

    if not scenes:
        raise RuntimeError(f"No valid scenes in {config_abs}")
    return scenes


def validate_scene(scene: dict[str, Any], repo_root: str) -> bool:
    required = ("id", "name", "model_path", "physics_config", "dataset", "ply_name")
    if not all(scene.get(k) for k in required):
        return False
    if not os.path.isdir(scene["model_path"]):
        return False
    if not os.path.isfile(scene["physics_config"]):
        return False
    preview = scene.get("preview")
    if preview:
        preview_abs = preview if os.path.isabs(preview) else _abs(repo_root, preview)
        if not os.path.isfile(preview_abs):
            scene["preview"] = None
        else:
            scene["preview"] = preview_abs
    return True


def scene_by_id(scenes: list[dict[str, Any]], scene_id: str) -> dict[str, Any] | None:
    for scene in scenes:
        if scene["id"] == scene_id:
            return scene
    return None


def scene_public_view(scene: dict[str, Any]) -> dict[str, Any]:
    return {
        "id": scene["id"],
        "name": scene["name"],
        "description": scene.get("description", ""),
        "preview_url": f"/api/scene_preview?id={scene['id']}",
    }