Skip to content

Changes since version 2.10.0 (2.11.0-rc1)

New Features

  • Image transport codecs — binary image frames carry a versioned codec byte, auto-selecting JPEG for 8-bit 1/3-channel images and lossless zlib otherwise, overridable per image via ImageData(codec=EImageCodec.…, jpeg_quality=…) (None = auto).
  • Tiled images — Visualizer.register_image_pyramid serves very large images as an on-demand /image/{id}/{level}/{x}/{y} tile pyramid with a server-side LRU, so the frontend fetches only the visible region.
  • Image streams — Visualizer.register_camera_stream streams 15–30 Hz camera feeds as MJPEG over /stream/{id}.
  • JPEG-by-default HTML export — the export asset store embeds eligible 8-bit images as JPEG data URLs instead of raw base64, with a lossless fallback for 16-bit/float/4-channel data.
  • Layout reconciliation (no full teardown on re-push) — the frontend now reconciles the whole view_layout tree by stable view id against a single live-view orphan registry (_viewRegistry), reusing unchanged scene panes and controls and only creating/removing the diff, so reordering a layout re-attaches the expensive WebGL panes instead of tearing the whole UI down.
  • Granular background-image update — Visualizer.set_background_image(view, image) streams a new CameraView.background_image (a binary pixel frame plus a view_background_image message) without re-pushing the layout, leaving other panes untouched.
  • Streaming camera-view example — pinhole_calibrated_streaming.py streams random noise at 4 fps into a calibrated 2D pane and swaps the left/right panes at runtime via a toolbar button.
  • Enable/disable/hide for entities and controls — entities can be hidden or shown at runtime (Visualizer.set_visible/hide, VizSceneHandle.set_visible/ hide, VizObjectRef.visible), action objects can be enabled/disabled (ActSceneObject.set_enabled/enable/disable), and UI controls can be hidden, shown, or greyed out (ControlView.set_enabled/set_visible and Visualizer.set_control_enabled/set_control_visible) — each pushed as a granular message (a visible aspect patch, an interaction re-push, or a control_state message) with no layout re-push. See hide_sphere.py.

Bug Fixes

  • SdfObject(Cylinder(...)) now honours align_center=0.0 — the SDF cylinder is based at origin (not centred), matching the mesh renderer and the documented align_center semantics.
  • Multiple panes of the same scene — a view_layout re-push now reuses every scene pane by its stable id (previously keyed by scene name), so two panes of the same scene no longer tear down and rebuild an unrelated pane on every re-push.

Refactor

  • Cached blade-name parsing — Algebra._resolve_key_signed caches the string → blade-id resolution per algebra, removing the per-access parse cost of mv["e14"] / mv["e12"] = x.
  • Branch-free MV operator dispatch — the six GA operators are bound once to plain/modular implementations, and the MV dunders route through them, skipping the per-call modulus re-check.
  • JS dev toolchain under js/dev/ — package.json (esbuild + playwright), node --test unit tests for the reconciliation/orphan-map core (extracted into the pure views/reconcile.js), a node syntax gate, and a headless Playwright smoke; wired into pre-commit and the PR checklist. JS tests/esbuild/playwright do not run in GitHub Actions.