webapp-ng: vtk.wasm field viewer — client-side FV pipeline (/vtk-wasm) - #1829
Open
jcschaff wants to merge 4 commits into
Open
webapp-ng: vtk.wasm field viewer — client-side FV pipeline (/vtk-wasm)#1829jcschaff wants to merge 4 commits into
jcschaff wants to merge 4 commits into
Conversation
…r foundation)
GitHub release assets can't be fetched cross-origin from the browser (no CORS
header), so the field viewer must load the bundle SAME-ORIGIN. Add a build-time
step that downloads the pinned virtualcell/vcell-vtk-wasm release and unpacks
vtkWebAssembly.{mjs,wasm} into src/assets/vtk-wasm/ (served at /assets/vtk-wasm/).
- scripts/fetch-vtk-wasm.mjs: idempotent fetch + unpack (VTK_WASM_TAG default
v1.0.0; VTK_WASM_BUNDLE=<local .tar.gz> overrides for offline/dev). Verified
locally against the built bundle.
- package.json: pin @kitware/vtk-wasm 2.1.8 (the loader); prepend
`npm run fetch:vtk-wasm` to the serve + build scripts so the bundle is present.
- .gitignore the 78 MB fetched bundle.
Foundation for the field-viewer component (loads /assets/vtk-wasm via the loader),
which follows once the v1.0.0 release is published. Until then, builds on this
branch need the v1.0.0 release reachable (or VTK_WASM_BUNDLE set).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CMxhE4gyPPRncpMPrRxnBW
Renders the custom VTK-compiled-to-WebAssembly bundle in the browser end-to-end:
build-time fetch of the vcell-vtk-wasm release -> same-origin /assets/vtk-wasm ->
UMD loader untars the .tar.gz in-browser -> standalone session renders via WebGL2.
Verified headless (a cone renders in ~3.9 s in the app shell).
- fetch-vtk-wasm.mjs: serve the .tar.gz as-is (the loader's loadAsync untars it
in-browser via DecompressionStream), instead of unpacking .mjs/.wasm.
- angular.json: copy @kitware/vtk-wasm's UMD loader (vtk.umd.js) into
assets/vtk-wasm at build time.
- VtkWasmViewerComponent + /vtk-wasm route + type shim. Uses the UMD loader via a
<script> tag: the ESM entry's runtime does a dynamic import(blobUrl) of the
untar'd glue that webpack rewrites and breaks ("Critical dependency ... is an
expression"); the UMD build isn't webpack-processed, so its native import works.
A cone is the smoke test; the FV pipeline (in-memory unstructured grid ->
vtkThreshold -> vtkGeometryFilter -> vtkWindowedSincPolyDataFilter, all
constructable via the marshal-coverage patch) is the next increment.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CMxhE4gyPPRncpMPrRxnBW
…brane) The vtk.wasm viewer now runs VCell's finite-volume surface-smoothing pipeline entirely in the browser (design doc §8B): build the raw whole-voxel unstructured grid in-memory from arrays → vtkGeometryFilter (boundary surface) → vtkWindowedSincPolyDataFilter (iters 12, feature angle 120°, pass-band 0.05) → render via WebGL2. All filters constructable in the standalone session via the marshal-coverage patch. Verified headless: a real VCell cell membrane (cytosol domain of SimID_946368938, 16306 pts / 12210 voxels) renders in ~1.85 s. The grid built in-session via vtkPoints + vtkCellArray + vtkUnstructuredGrid.setCells (single VTK_VOXEL type), proving the in-memory grid path (server sends raw arrays, client smooths + renders — no readers needed). - fv-sample-grid.json: sample FV grid fixture (exported from pyvcell) standing in for server-sent arrays. - vtk-wasm-viewer.component.ts: grid build + pipeline + render. Polish next: actor color/shading (property API), variable/time/slice/isovalue controls, and threshold for multi-region grids. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CMxhE4gyPPRncpMPrRxnBW
Assigning actor.property.color = [...] is a no-op in the standalone session; set color via actor.getProperty().setColor(...). Also add vtkPolyDataNormals after the smoothing filter so the mapper shades smoothly (Gouraud) instead of flat/faceted. The membrane now renders as a shaded green 3-D surface. Verified headless. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CMxhE4gyPPRncpMPrRxnBW
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
A
/vtk-wasmroute that renders VCell's finite-volume field geometry entirely client-side through the custom VTK-compiled-to-WebAssembly bundle — the payoff of the §8B design (docs/salad-3d-renderer-design.md). It proves the whole chain end-to-end inwebapp-ng.A real VCell cell membrane (cytosol domain, 16306 pts / 12210 voxels) renders as a shaded 3-D surface in ~1.3 s, computed in the browser — no server-side VTK, no readers.
The pipeline (all in-browser, via the wasm standalone session)
vtkPoints+vtkCellArray+vtkUnstructuredGrid.setCells) — a fixture stands in for server-sent arrays.vtkGeometryFilter→ boundary surface.vtkWindowedSincPolyDataFilter(iters 12, feature angle 120°, pass-band 0.05) → the faithful FV membrane smoothing.vtkPolyDataNormals→ smooth shading; render via WebGL2.All filters are constructable in the session thanks to the marshalling-coverage patch shipped in the bundle.
How the bundle is consumed
scripts/fetch-vtk-wasm.mjs, wired into serve/build): downloads the pinnedvirtualcell/vcell-vtk-wasmv1.0.0release and stages the.tar.gzundersrc/assets/vtk-wasm/(gitignored, ~12 MB). Served same-origin — GitHub release assets have no CORS header, so the browser can't fetch them cross-origin.import(blobUrl)of the in-browser-untar'd glue, which webpack rewrites and breaks. The UMD build (loaded via a<script>, copied to assets byangular.json) isn't webpack-processed, so its nativeimport()works.Notes
vtk-spikePhase 2 spike: vtk.js 3D rendering in webapp-ng (feasibility) #1799): fixture input, no wiring to real sim results yet.vcell-vtk-wasmv1.0.0release (fetched at build time). Complements vtk-wasm: move build to virtualcell/vcell-vtk-wasm; consume the release #1824 (monorepo build repoint) — independent files.Follow-ups
Variable/time/slice/isovalue controls;
vtkThresholdfor multi-region grids; unstructured volume rendering (vtkProjectedTetrahedra); replace the fixture with real server-sent arrays.🤖 Generated with Claude Code