Skip to content

feat: expose canvas integration and camera APIs - #285

Open
kephale wants to merge 12 commits into
pyapp-kit:mainfrom
kephale:lodstone-integration
Open

feat: expose canvas integration and camera APIs#285
kephale wants to merge 12 commits into
pyapp-kit:mainfrom
kephale:lodstone-integration

Conversation

@kephale

@kephale kephale commented Aug 23, 2026

Copy link
Copy Markdown

Human Kyle: I got here while building a viewer-agnostic progressive-loading module. This keeps the integration surface renderer-neutral and does not add a dependency on Lodstone.

Summary

  • expose an ArrayViewer.canvas integration surface and application-thread dispatch hook
  • publish backend-neutral camera viewport/matrix state and camera change events
  • support independent scale/origin transforms on image and volume handles
  • keep VisPy and PyGFX behavior aligned, including volume downsampling and transforms
  • preserve projective VisPy camera state correctly
  • cancel pending renderer work and close canvas resources before GUI frontend teardown
  • make Qt and wx destruction deterministic across bindings and operating systems
  • compare Qt leak checks by widget identity, while allowing only the anonymous wrapper frames left by rendercanvas after native-parent destruction
  • fix the wx typing issues reported by pre-commit

Validation

  • current GitHub matrix is fully green across Linux, macOS, and Windows; VisPy and PyGFX; Qt, wx, and Jupyter
  • both array-library jobs pass on Python 3.10 and 3.13
  • coverage upload, Codecov project, and Codecov patch checks pass
  • exact local array-library environment: 170 passed, 11 skipped
  • full local branch suite: 191 passed, 14 skipped
  • pre-commit, Ruff, mypy, and Pyright pass
  • manual VisPy and PyGFX visual tests pass

Teardown resolution

The earlier post-test failures were fixed rather than waived:

  • PyGFX now clears pending downloader work before closing rendercanvas
  • embedded Qt native children are left to their parent while root widgets are hidden, scheduled for deletion, and drained through deferred-delete events
  • wx top-level windows, shared devices, and app state are released in order
  • leak checks remain strict for root viewers/dialogs and compare object identities instead of unstable counts

@kephale

kephale commented Aug 23, 2026

Copy link
Copy Markdown
Author

The matrix found and helped fix two portability regressions in eb2aa51: initial PyGFX scale synchronization against an empty scene and a Qt-specific viewport assertion under Jupyter. The refreshed matrix passes the affected min-deps, PyGFX, VisPy, Jupyter, Pyright, docs, manifest, and cross-platform jobs.

Two teardown-only jobs remain red and need a maintainer rerun (GitHub does not allow the fork author to rerun upstream jobs):

  • test-array-libs (3.13): 168 passed / 12 skipped, then the existing top-level-widget leak detector reported Qt widgets retained from earlier viewer tests while tearing down test_canvas_to_world_scale_aware_offset.
  • windows-latest py3.13 wxpython pygfx: 157 passed / 13 skipped, then the Python process exited nonzero after repeated wx DestroyWindow invalid-handle messages.

Neither reports an assertion failure in the integration APIs. Locally the complete suite is 190 passed / 14 skipped, including the new empty-scene regression test.

@codecov

codecov Bot commented Aug 23, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 97.22222% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 85.39%. Comparing base (1c887ad) to head (8d1f6e7).

Files with missing lines Patch % Lines
src/ndv/controllers/_array_viewer.py 87.50% 2 Missing ⚠️
src/ndv/views/_wx/_array_view.py 50.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #285      +/-   ##
==========================================
+ Coverage   85.20%   85.39%   +0.19%     
==========================================
  Files          53       53              
  Lines        7192     7279      +87     
==========================================
+ Hits         6128     6216      +88     
+ Misses       1064     1063       -1     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@tlambert03

Copy link
Copy Markdown
Member

thank you for this @kephale! I'm glad to see you're still playing around with ndv. I apologize for the delayed response. I'm buried under a backlog of things to respond to after my move. I can say up front that exposing camera APIs is a known high priority... and it touches stuff that @gselzer has been doing it abstracting away the heart of ndv into scenex... so i know there will be some overlap with #276

i apologize that i likely won't be able to give concrete feedback on this very soon. maybe @gselzer, who has been looking at these things more recently, might have thoughts on how to get you what you need (or perhaps even just merge this idea as is) without waiting for the whole refactor to land

@kephale

kephale commented Aug 27, 2026

Copy link
Copy Markdown
Author

yay, hey @tlambert03! no worries on my side, this is a slower push from me so I can wait on @gselzer and adapt my implementation accordingly. my intention is just to get progressive loading support into the world. that said, i did find ndv to be one of the snappiest viewers with this implementation so it might become my main testing vehicle while investigating the chunk sampling/prioritization strategies.

@kephale
kephale marked this pull request as ready for review August 31, 2026 00:14
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.

2 participants