Fix/annotation ribbon and mesh regressions - #202
Merged
Conversation
The 'single owner for the primary mouse button' effect had grown two branches meant to fix edge cases (lasso/level-tracing forcing the crosshair off instead of falling through to crosshairToolActive, and smartfill/point/box-segment calling releasePrimaryMouseTools() instead of a plain toggleCrosshairTool(false)). Neither fix actually worked in practice, and the box-segment/pointSegment change in particular left the crosshair tool not registering as a controllable interaction target, so clicking anywhere in the 2D panes stopped moving the crosshair at all. Reverts both branches back to the simpler pre-fix behavior: - lasso/levelTracing now falls through to the plain else branch again - smartfill/pointSegment/boxSegment now just does toggleCrosshairTool(false)
…per-viewport checks These were hardcoded to always return false to suppress a redundant rotate-handle icon on the crosshair, but CrosshairsTool apparently uses these same callbacks to decide which viewports are interactive navigation targets — hardcoding false broke click-to-move crosshair navigation entirely. Reverted to the original per-viewport [viewportId1, viewportId2, viewportId3].indexOf(viewportId) !== -1 checks. handleRadius left at its original value/formatting.
Strips the isRendering/isDeletingSegment plumbing end-to-end:
- AnnotationToolbar: removed RenderingIndicator component, the
renderingDot*/deletingDot* state + effects, and their props
- VisualizationPage: removed isEditRendering/isDeletingSegment state,
every onBusyChange={setIsEditRendering} call site (Margin, Islands,
LogicalOperators, GrowFromSeeds, FillBetweenSlices, Smoothing), the
setIsEditRendering(true/false) calls in the pointer-guard effect
(kept beginBrushMaskGuard/endBrushMaskGuard, which are functional,
not just indicator), and onDeletingChange from SegmentsPopup.
promptToolBusy is left alone — it still gates re-entrant point/box
segment calls, it just no longer feeds a visual indicator.
…le to SegmentsPopup - AnnotationToolbar now renders as a small centered popout (.atb-shell, no more clip-path 'branch off the button' reveal) with a small square pointer notch (.atb--horizontal__pointer) tracked via getBoundingClientRect() against the pencil button, instead of the old dark rotated-square connector capped at the shell's z-index. - Removed the ribbon's own 'Show only target class' checkbox and the global MaskingSelect scope control — showOnlyTargetMask/ onShowOnlyTargetMaskChange/hasActiveTarget now passed to SegmentsPopup instead, and maskingArea/onMaskingAreaChange/ hasAnySegments/scopeLocked props dropped entirely. - Removed pointSegment/boxSegment from TOOL_DEFS and their related IconPointer/IconFrame imports. - CSS: .atb--horizontal is now position:relative/width:auto/centered instead of a full-width static bar; brightened border opacity 0.28 -> 0.55; new .atb--horizontal__pointer rules; removed the old .atb-shell__connector/.atb-shell__pointer rules.
…gering stroke markSegmentEdited only fires AFTER Cornerstone's SEGMENTATION_DATA_MODIFIED event, i.e. after the first stroke has already mutated the labelmap — so the mesh that used to get built the moment a segment 'became edited' already included that first stroke. - CornerstoneNifti2: new _preEditMaskSnapshots map, captured in setActiveEditSegment (before any stroke can land) via _capturePreEditSnapshotIfAbsent; consumePreEditSegmentSnapshot is a one-shot getter/clear; clearPreEditSegmentSnapshot for manual invalidation; extractSegmentSurface takes an optional precomputedMask to build from a frozen snapshot instead of the live volume; clearEditedSegments now also clears snapshots. - LiveSegmentMesh: rewritten to extract once (cached per segmentIndex, keyed only on segmentIndex/manifestCenter — never on paint activity) using the pre-edit snapshot when available, instead of the old debounced rebuild-on-every-edit (subscribeToSegmentationEdits) which caused visible 2D-pane stutter.
The 3D pane switched a static catalog organ from its baked GLB to a live marching-cubes mesh (LiveSegmentMesh) the instant it picked up its first edit. That switch — not painting itself — was the source of a lag spike on the first brush stroke, and the 3D pane is only meant to show the original mesh anyway, never a live reconstruction of in-progress annotations. Static organs now always render via OrganMesh regardless of edit state. Removed the now-unused editVersion state, its subscribeToSegmentationEdits subscription, and getEditedSegments()/editedSegments.has() branch. Custom classes (no baked GLB) still go through LiveSegmentMesh — that's unavoidable and unrelated to this bug.
Previously the Annotate button was simply disabled until the HD upgrade finished elsewhere. Now clicking it always does something: if HD is already ready it just toggles the ribbon as before; if not, it kicks off runEnhance() (reusing an in-flight one) and shows a full-screen blurred loading overlay (.vp-annotate-hd-overlay) until the upgrade resolves, only then opening the annotation toolbar/SegmentsPopup — so there's never a window where the ribbon is up but painting would hit the still-low-res segmentation grid. Adds annotateHdLoading state + the watcher effect, handleAnnotateClick, and the overlay CSS/keyframes in VisualizationPage.css.
…th ribbon DOCK_CLEARANCE was still reserving --atb-ribbon-h/--atb-panel-h as if the ribbon were a full-width bar in-flow under the topbar. Now that it's a small centered floating popout, that space is no longer occupied, so the panel can dock right under --vp-topbar-h.
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.
Summary
A cluster of fixes and reverts addresses issues with the annotation ribbon and 3D mesh viewer.
The Applying…/Deleting… busy indicators have been removed end-to-end. The related UI and logic in
AnnotationToolbar.tsxandVisualizationPage.tsxwere dead code that added complexity without providing meaningful value.The annotation ribbon has been redesigned. It is now a small, centered popout with a pointer arrow back to the pencil button instead of a full-width bar. The mask-visibility toggle and masking-scope selector have also been moved out of the ribbon and into
SegmentsPopup.The first-brush-stroke lag in the 3D pane has been fixed. Static organs no longer switch to a live marching-cubes mesh on their first edit; they always render the pre-baked GLB. Custom classes still build a live mesh, but they now build it from a pre-edit snapshot captured when
setActiveEditSegmentis called, before the triggering stroke lands. The snapshot is cached per segment rather than rebuilt on every edit.The Annotate button now triggers its own HD upgrade. When HD is not yet loaded, clicking Annotate displays a full-screen loading overlay instead of simply leaving the button disabled. Once the upgrade resolves, the annotation ribbon opens.
SegmentsPopup now docks directly under the main topbar. This is possible because the redesigned ribbon no longer reserves space as a full-width bar.
Testing
SegmentsPopupand confirm it now docks closer to the topbar.