split example visualizaiton pipeline
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
|
||||
from ..unroll import (
|
||||
compute_uv_distortion_metrics,
|
||||
load_exported_data,
|
||||
recommend_edge_expand,
|
||||
scaled_map_cache_path,
|
||||
)
|
||||
|
||||
DEFAULT_FINGER_EXPORT_DIR = "assets/finger/30fps"
|
||||
DEFAULT_FINGER_MAP_CACHE = f"{DEFAULT_FINGER_EXPORT_DIR}/unroll_map_uv.npz"
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class FingerExportPaths:
|
||||
"""Resolved Blender export bundle paths for finger UV pipelines."""
|
||||
|
||||
export_dir: Path
|
||||
mesh: Path
|
||||
intrinsics: Path
|
||||
pose: Path
|
||||
|
||||
def as_tuple(self) -> tuple[str, str, str]:
|
||||
return (str(self.mesh), str(self.intrinsics), str(self.pose))
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class FingerExportBundle:
|
||||
"""Loaded Blender export data and UV map-cache settings."""
|
||||
|
||||
export_paths: FingerExportPaths
|
||||
data: dict
|
||||
map_cache: str
|
||||
edge_expand: float
|
||||
|
||||
|
||||
def _candidate_export_dirs(export_dir) -> list[Path]:
|
||||
raw = Path(export_dir).expanduser()
|
||||
if raw.is_absolute():
|
||||
return [raw]
|
||||
|
||||
here = Path(__file__).resolve()
|
||||
candidates = [
|
||||
Path.cwd() / raw, # repo root / user cwd
|
||||
here.parents[1] / raw, # packaged wheel: orisys/assets/...
|
||||
here.parents[3] / raw, # editable install: repo/assets/...
|
||||
]
|
||||
unique: list[Path] = []
|
||||
for candidate in candidates:
|
||||
resolved = candidate.resolve()
|
||||
if resolved not in unique:
|
||||
unique.append(resolved)
|
||||
return unique
|
||||
|
||||
|
||||
def resolve_export_paths(export_dir) -> FingerExportPaths:
|
||||
"""Return Blender export paths expected inside one folder."""
|
||||
checked: list[str] = []
|
||||
for root in _candidate_export_dirs(export_dir):
|
||||
paths = FingerExportPaths(
|
||||
export_dir=root,
|
||||
mesh=root / "mesh.npz",
|
||||
intrinsics=root / "camera_intrinsics.npz",
|
||||
pose=root / "world_to_cam.npy",
|
||||
)
|
||||
missing = [name for name, path in vars(paths).items() if name != "export_dir" and not path.is_file()]
|
||||
if not missing:
|
||||
return paths
|
||||
checked.append(f"{root} (missing: {', '.join(missing)})")
|
||||
|
||||
raise FileNotFoundError(
|
||||
f"Missing export file(s) for finger bundle '{export_dir}'. "
|
||||
f"Checked: {'; '.join(checked)}"
|
||||
)
|
||||
|
||||
|
||||
def load_finger_export_bundle(
|
||||
export_dir,
|
||||
*,
|
||||
map_cache=DEFAULT_FINGER_MAP_CACHE,
|
||||
source_scale=1.0,
|
||||
) -> FingerExportBundle:
|
||||
"""Resolve export paths, load bundle data, and pick the UV map cache path."""
|
||||
export_paths = resolve_export_paths(export_dir)
|
||||
if Path(map_cache) == Path(DEFAULT_FINGER_MAP_CACHE):
|
||||
map_cache = str(export_paths.export_dir / "unroll_map_uv.npz")
|
||||
map_cache = scaled_map_cache_path(map_cache, source_scale)
|
||||
mesh_path, intrinsics_path, pose_path = export_paths.as_tuple()
|
||||
data = load_exported_data(mesh_path, intrinsics_path, pose_path)
|
||||
distortion = compute_uv_distortion_metrics(data)
|
||||
edge_expand = recommend_edge_expand(distortion)
|
||||
return FingerExportBundle(
|
||||
export_paths=export_paths,
|
||||
data=data,
|
||||
map_cache=map_cache,
|
||||
edge_expand=float(edge_expand),
|
||||
)
|
||||
Reference in New Issue
Block a user