Fix/plane drag snapback#20
Merged
Merged
Conversation
Two issues made the voxel explorer's slice selector feel broken: 1. Snap-back (underlying code): Plot3D.to_state_dict() returned dict(_state) without refreshing overlay_widgets from the live widgets, so any view-only push that goes through the targeted-fields path (set_highlight / set_view) re-serialised a stale plane position and overwrote the in-progress drag in JS. The drag would jump back to the last Python-known integer position. Fix: to_state_dict() now always rebuilds overlay_widgets from the live _widgets, so every push path carries the current plane positions. 2. Faulty / jumpy highlight (example): the explorer snapped the highlight to integer voxel indices, so the marker jumped while the plane glided. Now it tracks smooth float positions (fx,fy,fz) for the highlight and the planes that follow, keeping integer indices only for slicing the 2D images. Adds 3 regression tests (TestPlaneDragNoSnapBack) asserting set_highlight / set_view preserve a live plane position. 3D suite + example execution green.
The voxel highlight appeared to land on random voxels in large (256³) volumes because the example rendered a sparse random subsample of the whole volume — the highlight projected to the correct (ix,iy,iz) but almost never coincided with a displayed cube, so it floated in empty space. Render the voxels lying ON the three slice planes instead, re-cut live on each drag. The marker is now always anchored on a real cube at the slice intersection, the volume shows actual slice contents, and the on-plane count is ~3·(N/step)² regardless of N, so it stays fast at 256³. - Plot3D.set_point_colors: accept voxels panels, not just scatter, so slabs can be recoloured live each drag. - Add the voxel grain explorer to the example smoke tests. - Add a set_point_colors-on-voxels regression test.
A 256³ grain explorer produced ~8112 slab voxels, which crossed the GPU_VOXEL_THRESHOLD (8000) and switched the panel to the Phase-1 WebGPU voxel path. That path is not hardware-verified in CI — headless Chromium exposes no WebGPU adapter, so the canvas fallback is what every test exercised — and on real GPUs it rendered a sparse, see-through volume (cubes appearing to float / vanish) instead of solid slice slabs. - Raise GPU_VOXEL_THRESHOLD 8000 -> 20000 so mid-size volumes stay on the depth-sorted, visual-regression-tested Canvas2D renderer. The grain explorer (~8k cubes) now renders its full slabs (verified at N=256). - GPU voxel pipeline: cullMode 'none'. The MVP swaps rows (r0,r2,r1) and negates depth, so cube winding can't be relied on for back-face culling; culling dropped the wrong faces. Translucent cubes need all faces anyway. - GPU geometry cache now keys on point_colors_b64 too, so set_point_colors recolours voxels live instead of reusing a stale colour buffer. - Add a browser regression test that a ~8k-voxel volume renders dense slabs on the canvas path (gpuCanvas hidden).
Correct the diagnosis from the previous commit. Large voxel volumes rendered 'empty' (only plane widgets + highlight, no cubes) in WebGPU-enabled browsers (PyCharm JCEF = Chrome 137). It was NOT the shader or back-face culling. Real cause: the 3D panel stacks gpuCanvas (z-index 0, WebGPU voxels) under plotCanvas (z-index 1, decorations). Activating the GPU path cleared the plotCanvas bitmap but left its opaque CSS background, so the element painted over every GPU-drawn voxel. - plotCanvas background -> transparent while GPU active; restored on fallback, device loss, and state-no-longer-wants-GPU. - Revert earlier workarounds now shown unnecessary: GPU_VOXEL_THRESHOLD back to 8000, cullMode back to 'back' for voxels. - Verified the voxel WGSL + _gpuMatrix on real hardware (NVIDIA TITAN X via native wgpu): three solid slabs; cull 'back' == 'none'. - Retarget regression test to the DOM layering invariant; the active-GPU transparent swap is hardware-verified separately (no WebGPU adapter in CI).
Safari's experimental WebGPU can activate, render correctly for a while, then throw mid-draw or lose the device. The GPU path makes the decoration plotCanvas transparent and takes GPU-only branches (proj==null etc.), so a mid-draw throw left the frame half-built: voxels AND axes vanished, and only a window resize (forcing a full redraw) brought them back. The catch block now disposes the GPU panel, restores the opaque plotCanvas background, and re-renders the whole panel once on the canvas path in the same frame (guarded against re-entry via p._gpuFellBack, reset per draw3d call). Verified by simulating an adapter+device that activates then throws on createCommandEncoder: no page errors, gpuCanvas hidden, plotCanvas opaque, voxels + axes rendered. Note: the kernel 'Task was destroyed but it is pending' warnings are ipykernel shutdown noise, unrelated to this.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #20 +/- ##
==========================================
+ Coverage 90.62% 90.63% +0.01%
==========================================
Files 33 33
Lines 2741 2744 +3
==========================================
+ Hits 2484 2487 +3
Misses 257 257 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
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.
This pull request introduces several improvements and bug fixes to the 3D voxel explorer and the underlying rendering engine, especially around the GPU/canvas rendering paths and interactive slice controls. The most important changes include a complete rewrite of how 3D voxels are selected and rendered in the explorer, robust handling and recovery from mid-draw GPU failures, fixes for canvas layering and background handling, and enhanced support for per-voxel colors. Additional tests are added to cover these behaviors.
These changes collectively make the 3D voxel explorer more robust, visually accurate, and user-friendly, while also addressing subtle rendering bugs and improving test coverage.