Skip to content

Architecture

Vixar is split between a Python library (data ingestion + scene config) and a bundled JavaScript engine (viewer.js) that renders in WebGL2. They communicate through a single versioned JSON contract and a typed postMessage protocol.

Python (vixar)                         JS engine (viewer.js)
  read LAS/CSV/mesh  ──► scene JSON ──►  Scene Config Parser
  pyproj UTM rebase                       Data Pipeline (Workers)
  FastAPI / anywidget ◄─ events ◄──       IRenderer → ThreeJSRenderer
                                          Scene Manager (layers, slicer, LUT)

The renderer abstraction

All engine business logic is written against the IRenderer interface, never directly against Three.js. ThreeJSRenderer is the v1 implementation; a WebGPURenderer can be dropped in post-v1 without rewriting the engine.

UTM coordinate strategy

Large UTM coordinates (~500,000 m) lose precision in float32. At load time Python computes the scene-origin centroid across all layers, subtracts it to produce float32-safe local coordinates, and ships the origin in the config. The camera, measurements, and annotations all work in local coordinates; export adds the origin back to recover real-world UTM values.

Data pipeline & scale

  • Tiling (vixar tile) splits large LAS files into spatial binary tiles with a meta.json index.
  • An octree frustum-culls tiles each frame; an LOD controller picks coarse vs. full density by distance.
  • A byte-budgeted LRU cache bounds RAM; a WorkerPool parses tiles off the main thread using Transferable ArrayBuffers (no SharedArrayBuffer — keeps the viewer iframe-safe with no COOP/COEP headers). Crashed workers are restarted automatically and the offending tile is skipped.

Rust / WASM

vixar-wasm provides a Rust LAS parser and Marching Cubes, base64-inlined into the bundle so viewer.js stays a single self-contained asset. The engine prefers WASM and transparently falls back to the JS implementation when it is unavailable.

Resilience (Phase 5)

  • Progressive enhancement — without WebGL2 the viewer shows a clear message plus a 2-D summary table instead of crashing.
  • Shader pre-warm — all layer GLSL programs compile up-front after a scene loads, so the first frame doesn't stall.
  • Content-Security-Policy — emitted both as a <meta> tag (to_html) and a response header (server); frame-ancestors * keeps the viewer embeddable.