web component with base64-embedded GLB.
"""
import base64
from pathlib import Path
# Embedding very large GLBs can make the page slow; warn above this size (bytes)
MAX_EMBED_BYTES = 15 * 1024 * 1024 # 15 MB
def mesh_viewer_html(glb_path: str | Path | None = None, glb_bytes: bytes | None = None, height_px: int = 480) -> str:
"""
Build HTML for an interactive 3D mesh viewer (model-viewer).
Provide either glb_path (file path) or glb_bytes (raw GLB). Prefers path if both given.
Returns HTML string. If no valid input or file too large, returns a short error HTML.
"""
data_uri: str | None = None
if glb_path:
p = Path(glb_path)
if p.is_file() and p.suffix.lower() in (".glb", ".gltf"):
try:
raw = p.read_bytes()
except Exception:
raw = b""
else:
raw = b""
elif glb_bytes:
raw = glb_bytes
else:
raw = b""
if not raw or len(raw) < 4:
return (
"No GLB loaded. Upload a .glb file or choose one from outputs.
"
)
if len(raw) > MAX_EMBED_BYTES:
return (
f"Mesh is too large to embed in viewer ({len(raw) / 1024 / 1024:.1f} MB). "
"Use a local viewer or a smaller mesh.
"
)
b64 = base64.b64encode(raw).decode("utf-8")
data_uri = f"data:model/gltf-binary;base64,{b64}"
# model-viewer from unpkg; use module script
return f"""
"""