Skip to content

Public demo: the playground's viewport over the shipped scenes, with no Python - #101

Merged
andrinr merged 1 commit into
mainfrom
feat/public-demo
Oct 23, 2026
Merged

andrinr merged 1 commit into
mainfrom
feat/public-demo

Conversation

@andrinr

@andrinr andrinr commented Oct 23, 2026

Copy link
Copy Markdown
Owner

What

frontend/static.html grows from a scene dropdown into an editable static demo of cadjoint's playground that GitHub Pages can host. There's no Python server: the browser builds the WGSL from the scene graph, and jax-js does the meshing.

  • Look: the playground's own ViewerPane, object tree, render popover, view cube and design language, laid out in three fixed columns. There's no editor, and no Simulate or Optimize panels.
  • Parameters: a slider and number field for each free parameter, grouped by the object whose handle moves it. An edit writes the parameter buffer at once, then installs shaders rebuilt at the new values. The module text doesn't change, so this is a values-only upload with no pipeline rebuild.
  • Constraint-driven parameters are read-only. They show the constraint that holds them, are drawn as held squares, and refuse a drag with that reason.
  • Construction overlay from compile data exported at build time. Handles bound to a free parameter follow it, and dragging one (sketch points, or the gizmo in Objects mode) edits it.
  • Wireframe and feature edges from dual contouring on jax-js. Feature edges are a dihedral-angle crease test on the mesh. The Python lattice classifier isn't ported, because it needs every leaf's field and its Jacobian.
  • STL export of the current values, at 64–160 cells.
  • Fallback: a clear message without WebGPU; parameters and export still work on WebAssembly. The public-tier tags from Viewer: say which tier each feature runs on, instead of degrading silently #99 show.

Data

  • The bundle format is cadjoint/viewer/schema/demo.py (DemoScene, emitted into payloads.d.ts). python -m cadjoint.viewer.demo (or npm run bundle:static) writes it to frontend/src/static/bundle.
  • Each scene is run in a fresh process. Unnamed primitives are numbered by a per-process counter, so a second run in one process renames their parameters (cylinder_height vs cylinder_3_height).
  • tests/viewer/test_demo_bundle.py keeps the committed bundle current with the scenes. It compares floats to float32 round-off.

Shared changes

  • ViewerPane takes an optional lockedHandle prop. The playground doesn't pass it, so its behaviour is unchanged.
  • tier.ts's setter is renamed stateTier.
  • The committed playground bundle is rebuilt.
  • CI's frontend job also builds the static demo.

Deploy (not enabled)

.github/workflows/demo.yml only runs when started by hand, and only publishes (to gh-pages/demo/) with deploy ticked. docs.yml already owns gh-pages, and Quarto replaces the branch on each docs deploy, which would delete demo/. The durable option is to build the demo inside docs.yml into _site/demo. frontend/src/static/README.md has the details and local run instructions.

Tests

  • vitest: 741 passed, including new demoParameters and demoBundle tests.
  • npm run e2e:static: 3 passed. It loads a scene, moves a slider, checks the render changed with no pipeline rebuild, checks a constraint-driven parameter is read-only, and exports an STL.
  • Playground e2e (drag, interaction, shader, tierTags): 10 passed.
  • pytest (tests/backends/test_wgsl_frontend.py, tests/test_wgsl_scene_codegen.py, schema, API contract, core boundary, demo bundle): 142 passed, also with -n 4.
  • Not run: the full e2e suite and the ui-audit design linter.

Out of scope

  • Constraint solving in jax-js, so driving dimensions become editable.
  • During a gizmo drag, the parameter panel updates on release rather than live.

🤖 Generated with Claude Code

…no Python

static.html grows from a scene dropdown into an editable static demo that
GitHub Pages can host:

- The playground's ViewerPane, object tree, render panel, view cube and design
  language, fixed into a three-column desk. No editor, Simulate or Optimize.
- A parameter panel: slider and field per free parameter, grouped by the
  object whose handle moves it. An edit writes the parameter buffer at once,
  then installs shaders rebuilt at the new values, a values-only upload.
- The construction overlay from exported compile data. Handles bound to a
  free parameter follow it, and dragging one edits it. Constraint-driven
  parameters are read-only, drawn held, and name the constraint.
- Wireframe and feature edges from dual contouring on jax-js; the edges are a
  dihedral crease test, not the Python lattice classifier (not ported).
- STL export of the current values at a chosen resolution.
- WebGPU check with a message; jax-js on WebGPU or Wasm; public-tier tags.

Data: cadjoint/viewer/schema/demo.py (DemoScene, emitted to payloads.d.ts),
written by `python -m cadjoint.viewer.demo` into frontend/src/static/bundle,
each scene run in a fresh process because unnamed primitives are numbered
per process. tests/viewer/test_demo_bundle.py keeps the bundle current.

Shared changes: ViewerPane takes an optional lockedHandle (absent in the
playground, so behaviour there is unchanged); tier.ts's setter is stateTier.
.github/workflows/demo.yml builds the demo and publishes to gh-pages/demo
only when started by hand with deploy ticked.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@andrinr
andrinr merged commit 818de9e into main Oct 23, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant