""" 3D mesh viewer for GLB/glTF. Returns HTML for use with st.components.v1.html(). Uses Google's 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""" """