Skip to content

Commit 6c8e5c9

Browse files
committed
patches for chorus release
1 parent b0faf12 commit 6c8e5c9

6 files changed

Lines changed: 396 additions & 33 deletions

File tree

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,8 @@ siglip_features, dino_features, dinov2_features, image_features, visual_features
168168

169169
The first dimension must match the loaded splat count, the original splat count before masks/downsampling, or the `valid_feat_mask.npy` count.
170170

171+
If the feature file has a sibling `*_index.npy` sidecar, Mini Viewer treats it as source-row alignment metadata.
172+
171173
## Run the viewer
172174

173175
### PLY scene, automatic backend

core/renderer.py

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@
1919
import numpy as np
2020
import torch
2121

22+
try:
23+
from nerfview._renderer import InterruptRenderException as _NerfviewInterruptRenderException
24+
except Exception: # pragma: no cover - optional import outside viewer runtime.
25+
_NerfviewInterruptRenderException = None # type: ignore[assignment]
26+
2227
RenderBackend = Literal["auto", "gsplat", "torch"]
2328

2429
_FALLBACK_MESSAGES_SEEN: set[str] = set()
@@ -33,6 +38,38 @@ def _log_once(key: str, message: str, *, enabled: bool = True) -> None:
3338
print(message)
3439

3540

41+
def _clip_message(message: str, max_chars: int = 360) -> str:
42+
message = " ".join(message.strip().split())
43+
if len(message) <= max_chars:
44+
return message
45+
return f"{message[: max_chars - 3]}..."
46+
47+
48+
def _summarize_exception(exc: Exception) -> str:
49+
lines = [line.strip() for line in str(exc).splitlines() if line.strip()]
50+
if not lines:
51+
return exc.__class__.__name__
52+
53+
markers = (
54+
"fatal error:",
55+
"No CUDA toolkit found",
56+
"Error building extension",
57+
"RuntimeError:",
58+
"ImportError:",
59+
"AttributeError:",
60+
"error:",
61+
)
62+
for marker in markers:
63+
for line in lines:
64+
if marker in line:
65+
return _clip_message(line)
66+
return _clip_message(lines[0])
67+
68+
69+
def _is_render_interrupt(exc: Exception) -> bool:
70+
return _NerfviewInterruptRenderException is not None and isinstance(exc, _NerfviewInterruptRenderException)
71+
72+
3673
def _normalize_device(device: str | torch.device) -> str:
3774
device_str = str(device)
3875
if device_str.startswith("cuda") and not torch.cuda.is_available():
@@ -345,7 +382,9 @@ def _try_gsplat_rasterization(
345382
return depth[..., None].repeat(1, 1, 3)
346383
return image[..., :3].clamp(0.0, 1.0)
347384
except Exception as first_error:
348-
raise RuntimeError(f"gsplat rasterization failed: {first_error}") from first_error
385+
if _is_render_interrupt(first_error):
386+
raise
387+
raise RuntimeError(f"gsplat rasterization failed: {_summarize_exception(first_error)}") from first_error
349388

350389

351390
def viewer_render_fn(
@@ -410,12 +449,14 @@ def viewer_render_fn(
410449
)
411450
return image_to_uint8_numpy(image)
412451
except Exception as exc:
452+
if _is_render_interrupt(exc):
453+
raise
413454
if fallback_to_cpu:
414455
fallback_splats = cpu_fallback_splats if cpu_fallback_splats is not None else max_cpu_splats
415456
_log_once(
416457
"gsplat_to_cpu",
417458
"[renderer] gsplat failed; rerendering with CPU fallback "
418-
f"({fallback_splats:,} splats max): {exc}",
459+
f"({fallback_splats:,} splats max): {_summarize_exception(exc)}",
419460
enabled=log_fallbacks,
420461
)
421462
image = _torch_point_splat_rasterization(
@@ -433,7 +474,8 @@ def viewer_render_fn(
433474

434475
_log_once(
435476
"gsplat_to_same_device_torch",
436-
f"[renderer] gsplat failed; CPU fallback disabled, using torch renderer on {render_device}: {exc}",
477+
"[renderer] gsplat failed; CPU fallback disabled, using torch renderer "
478+
f"on {render_device}: {_summarize_exception(exc)}",
437479
enabled=log_fallbacks,
438480
)
439481

0 commit comments

Comments
 (0)