Skip to content

feat(paint): add Fill Holes segmentation process#898

Open
PaulHax wants to merge 3 commits into
Kitware:mainfrom
PaulHax:fill-holes
Open

feat(paint): add Fill Holes segmentation process#898
PaulHax wants to merge 3 commits into
Kitware:mainfrom
PaulHax:fill-holes

Conversation

@PaulHax

@PaulHax PaulHax commented Jun 27, 2026

Copy link
Copy Markdown
Collaborator

Summary

Adds Fill Holes, a third paint "process" alongside Fill Between and Smooth. It
finds background regions fully enclosed by segmentation on a 2D slice and fills them
in — a common cleanup after painting leaves interior gaps. Fill Holes is the first
option in the process list and the default selection.

Behavior

  • Per-slice flood fill on the plane of the active 2D view: anything not reachable from
    the slice border is a hole.
  • Only background (0) voxels are ever filled. Existing segments are never overwritten,
    even when fully enclosed.
  • Two independent options:
    • Slices — Current slice (default), or All slices (every slice along the active
      view's axis).
    • Segments — All segments (default), or Selected segment.
  • All segments: each hole is filled with the majority bordering label (ties broken
    by the lowest label for determinism). Locked segments are never grown.
  • Selected segment: only the active segment's holes are filled.

UX

The Preview step's Original/Processed control toggles in place — clicking either
button flips the view, so you can compare without moving the pointer. The active button
still indicates which view you're on.

Implementation

  • core/tools/paint/fillHoles.ts — pure, dependency-free flood fill (unit-testable,
    worker-ready), run in a web worker (fillHoles.worker.ts) so whole-volume fills don't
    block the UI, matching Gaussian Smooth.
  • store/tools/fillHoles.ts — resolves the IJK slice axis from the active 2D view and
    the segment group's parent image, and the current slice from the view's slice
    config; requires an active 2D view.
  • Conforms to the existing ProcessAlgorithm contract; no changes to the process
    framework's preview/apply/cancel flow.
  • Process wiring (label, icon, controls, algorithm) is centralized in a small
    processes.ts registry, so the selector and controls render from one table instead of
    per-type copy-paste.

Shared fixes (benefit all paint processes)

Review surfaced bugs in the shared process flow, fixed here so Fill Between and Smooth
benefit too:

  • Apply no longer discards the result when the user is viewing the Original preview
    (previously confirmProcess committed the original scalars).
  • The active-segment requirement is now opt-out, so an all-segments process isn't
    blocked by (or limited to) a single active segment.

Testing

  • 11 unit tests for the core algorithm: single/all-segment fills, border handling,
    no-mutation, deterministic tie-break, locked-segment protection, whole-volume on a
    non-default axis, single-slice.
  • 3 DOM-only e2e specs (default run, whole-volume + selected-segment, in-place preview
    toggle), verified against a production build in Chrome.

Manual QA

Load a dataset, create a segment group, paint a shape with an interior gap, then
Paint → Process → Fill Holes. Try each Slices/Segments combination, Preview, then
Apply or Cancel.

Out of scope

  • True 3D cavity filling and multi-axis fills (whole-volume is per-slice along the
    active view's axis only).

PaulHax added 2 commits June 27, 2026 14:38
Fill Holes fills enclosed background regions in a segment group on a slice.

Options select current-slice vs whole-volume and all-segments vs the selected segment.

Only background voxels are filled, so existing segments are never overwritten.

Fill Holes is the default process.
…ta loss

Commit processed scalars on Apply even when the original preview is shown, so
the result is no longer silently discarded (shared by all paint processes).
Make the active-segment requirement opt-out so all-segments Fill Holes runs.
Centralize process wiring (label, icon, controls, algorithm) in a registry.
Fill Holes: require an active 2D view and resolve the slice axis from the
segment group's parent image instead of the global current image.
Fill Holes: skip locked segments in all-segments fill and break majority
ties by lowest label; run the flood fill in a web worker.
Tests: add a preview-toggle e2e, fix the whole-volume selector, share setup.
@netlify

netlify Bot commented Jun 27, 2026

Copy link
Copy Markdown

Deploy Preview for volview-dev ready!

Name Link
🔨 Latest commit a7ec8a0
🔍 Latest deploy log https://app.netlify.com/projects/volview-dev/deploys/6a4154dea8f4450008005127
😎 Deploy Preview https://deploy-preview-898--volview-dev.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

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