Skip to content

[WIP] feat/decimated loading#6034

Open
mbellehumeur wants to merge 61 commits into
OHIF:masterfrom
mbellehumeur:test-merge-decimateLoading
Open

[WIP] feat/decimated loading#6034
mbellehumeur wants to merge 61 commits into
OHIF:masterfrom
mbellehumeur:test-merge-decimateLoading

Conversation

@mbellehumeur
Copy link
Copy Markdown
Contributor

@mbellehumeur mbellehumeur commented May 22, 2026

Context

Changes & Results

Testing

Checklist

PR

  • [] My Pull Request title is descriptive, accurate and follows the
    semantic-release format and guidelines.

Code

  • [] My code has been well-documented (function documentation, inline comments,
    etc.)

Public Documentation Updates

  • [] The documentation page has been updated as necessary for any public API
    additions or removals.

Tested Environment

  • [] OS:
  • [] Node version:
  • [] Browser:

Greptile Summary

This WIP PR introduces decimated volume loading for 3D rendering in OHIF: volumes exceeding a configurable voxel threshold are automatically downsampled via a new decimatedVolumeLoader, a GPU benchmark runs at startup to calibrate sample-distance defaults, and a new SmartScrollbar tracks per-slice load/viewed state with a visual progress fill.

  • Auto-decimation pipeline: applyAutoDecimationIfNecessary estimates voxel count from display-set metadata and selects an IJK decimation tuple; CornerstoneCacheService constructs a decimatedVolumeLoader:…:I_J_K volume ID and passes it to Cornerstone's volume cache; an AutoDecimationOverlay badge notifies the user when a volume has been reduced.
  • GPU benchmark (gpuPerformanceTest): measures triangle throughput, texture upload, and buffer operations via a temporary off-screen WebGL canvas; stores a generalPerformanceScore in localStorage to set rotateSampleDistanceFactor and sampleDistanceMultiplier once per browser session; Cypress/CPU-rendering paths skip the live test.
  • SmartScrollbar + ViewportSliceProgressScrollbar: replaces the legacy scrollbar by default; renders loaded-bytes and viewed-bytes fills via useByteArray batched updates; introduces ViewedDataService to persist per-imageId viewed state across viewports.

Confidence Score: 3/5

Not ready to merge — the PR is explicitly marked [WIP] and several unresolved issues from prior review rounds remain in the code.

Multiple issues flagged in earlier review rounds are still present: numImageFrames is overwritten for decimated volumes in volumeLoadedHandler, decimated volume cache entries are not purged during display-set invalidation, and the GPU result assigns level 'failed' outside the declared union type. New findings in this round are lower-impact but add to the overall debt.

init.tsx (volumeLoadedHandler still corrupts numImageFrames), CornerstoneCacheService.ts (stale decimated volumes survive invalidation, no-op delete calls), gpuPerformanceTest.ts (type-union mismatch on level, debug window assignment).

Important Files Changed

Filename Overview
extensions/cornerstone/src/utils/decimation/applyAutoDecimationIfNecessary.ts New utility for auto-decimation of large volumes; fallback loop produces anisotropic K-only decimation for very large datasets; otherwise logic is sound for typical cases.
extensions/cornerstone/src/services/CornerstoneCacheService/CornerstoneCacheService.ts Volume loading extended with decimated-loader support; volumeImageIds.delete calls inside the invalidation loop use volume IDs instead of display set UIDs (no-ops); decimated volumes still not purged on invalidation (flagged in prior review).
extensions/cornerstone/src/utils/gpuPerformanceTest.ts New GPU benchmark utility; stores full result on window.gpuPerformanceResult in both paths (debug leak); 'failed' level not in the GPUPerformanceResult.level union (flagged in prior review).
extensions/cornerstone/src/init.tsx Registers decimated volume loader, runs GPU benchmark on init, adds volumeLoadedHandler; handler still corrupts numImageFrames for decimated volumes (flagged in prior review).
platform/ui-next/src/components/SmartScrollbar/SmartScrollbar.tsx New compound scrollbar component with ResizeObserver, drag, keyboard nav, and expandable indicator; well-structured with clear context separation and runtime child validation.
extensions/cornerstone/src/Viewport/Overlays/ViewportSliceProgressScrollbar/hooks.ts New hooks for load/viewed progress tracking; useViewedSliceBytes correctly guards viewedDataService as nullable at runtime despite non-optional type annotation; event cleanup is properly handled.
extensions/cornerstone/src/utils/decimation/constants.ts Exports decimation constants; AUTO_DECIMATION_VIEWPORT_TYPES includes 'volume' which is not a valid Cornerstone3D ViewportType and will never match.
extensions/cornerstone/src/commandsModule.ts Adds volume cropping, decimation reload, and quality commands; fixes setVolumeRenderingQulaity typo; reloadVolumeWithDecimation handles camera/preset restoration and concurrent viewport updates.

Comments Outside Diff (1)

  1. extensions/cornerstone/src/services/CornerstoneCacheService/CornerstoneCacheService.ts, line 110-145 (link)

    P1 Decimated volumes are never purged from cache during invalidation

    invalidateVolume iterates candidateVolumeIds (baseVolumeId, …:volume3d, …:orthographic) but decimated volumes are stored under the key decimatedVolumeLoader:${baseVolumeIdWithSuffix}:${i}_${j}_${k}. When a display set is invalidated (e.g. after a series reload), the stale decimated volume remains in cs3DCache and will be served on the next viewport render instead of the freshly-loaded data. A scan of cs3DCache._volumeCache for keys that start with decimatedVolumeLoader: and contain the display set UID needs to be added to the purge loop.

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: extensions/cornerstone/src/services/CornerstoneCacheService/CornerstoneCacheService.ts
    Line: 110-145
    
    Comment:
    **Decimated volumes are never purged from cache during invalidation**
    
    `invalidateVolume` iterates `candidateVolumeIds` (`baseVolumeId`, `…:volume3d`, `…:orthographic`) but decimated volumes are stored under the key `decimatedVolumeLoader:${baseVolumeIdWithSuffix}:${i}_${j}_${k}`. When a display set is invalidated (e.g. after a series reload), the stale decimated volume remains in `cs3DCache` and will be served on the next viewport render instead of the freshly-loaded data. A scan of `cs3DCache._volumeCache` for keys that start with `decimatedVolumeLoader:` and contain the display set UID needs to be added to the purge loop.
    
    How can I resolve this? If you propose a fix, please make it concise.
Prompt To Fix All With AI
Fix the following 4 code review issues. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 4
extensions/cornerstone/src/utils/decimation/applyAutoDecimationIfNecessary.ts:229-246
**Fallback decimation loop only increments K axis**

When no pre-built candidate achieves the `requiredFactor` (i.e., the volume exceeds `8 × threshold`), the fallback loop keeps I and J fixed at `2` and increments K indefinitely. For a 900×512×512 volume at a 10M-voxel threshold the required factor is ≈ 47 → `[2, 2, 12]`, yielding a volume 6× more coarse in the slice direction than in-plane, making 3D renders look severely anisotropic. The fix would be to balance increments across all three axes in the fallback loop (e.g., cycle through incrementing i, j, and k in turn).

### Issue 2 of 4
extensions/cornerstone/src/utils/decimation/constants.ts:3
`'volume'` is not a valid Cornerstone3D `ViewportType` value — the enum only defines `'volume3d'`, `'orthographic'`, `'stack'`, etc. This entry will never be matched by `resolveViewportType` and is dead code that creates a false impression that plain `'volume'`-typed viewports are auto-decimated.

```suggestion
export const AUTO_DECIMATION_VIEWPORT_TYPES = new Set(['volume3d']);
```

### Issue 3 of 4
extensions/cornerstone/src/utils/gpuPerformanceTest.ts:603-606
**Debug result leaked onto `window` in production**

`window.gpuPerformanceResult` is set in both the success and failure paths of `gpuPerformanceTest`. The full `GPUPerformanceResult` object (including renderer info, texture sizes, and heap metrics) is permanently accessible from the browser console or any injected script. If this is a development-only aid, it should be guarded by a dev/debug flag or removed from production builds.

### Issue 4 of 4
extensions/cornerstone/src/services/CornerstoneCacheService/CornerstoneCacheService.ts:115-125
**`volumeImageIds.delete` calls inside the loop are no-ops**

`this.volumeImageIds` is keyed by `displaySet.displaySetInstanceUID` (see `this.volumeImageIds.set(displaySet.displaySetInstanceUID, volumeImageIds)` in `_getVolumeViewportData`). The loop deletes by `candidateVolumeId` (a fully-qualified volume ID like `cornerstoneStreamingImageVolume:DSUID:volume3d`), which will never match a display-set-UID key. Only the final `this.volumeImageIds.delete(invalidatedDisplaySetInstanceUID)` after the loop is effective. The per-candidate deletes inside the loop should be removed to avoid confusion.

Reviews (4): Last reviewed commit: "Add files to merge CornerstoneOverlays." | Re-trigger Greptile

…ds for sample distance multiplier and volume reload with decimation
…on logic for improved performance and memory management
…h parsing from volumeId for improved clarity and maintainability
…nfig threshold and refactoring related functions
…nt to use AllInOneMenu for improved layout and organization
…nality and update related components for improved clarity
… in display sets and enhance event broadcasting
…umeLoader format and update IJK decimation parsing to handle baseVolumeId with colons
…e volume ID generation logic for improved clarity and performance
…ommented code and unnecessary whitespace for improved readability. Add doc.
… and remove unused import for improved clarity
…RenderingPresets components by integrating props instead of hooks for improved flexibility and clarity
…ecimation messages in the viewport, enhancing user feedback on volume rendering changes
…omizationService for volume decimation settings, improving configuration flexibility and clarity
…bling volume-specific options and enhancing user interaction with volume rendering settings
…CompassMenu component for enhanced 3D viewport orientation control
…port3DCompassMenu with spin controls for improved 3D viewport interaction
…r center sphere and adjust layout for spin controls
…nto VolumeOptionsMenu for enhanced volume manipulation features
… and integrate GPU performance testing utility for improved volume rendering settings
…stone tools and integrate it into volume3D tool group with configuration options
mbellehumeur and others added 21 commits March 17, 2026 13:17
…n, and yarn.lock for improved stability and performance
…playSetFromVolume for improved clarity and functionality
… settings and broadcast updated viewport data
…js to netlify.js for improved configuration management
Co-authored-by: Dan Rukas <dan.rukas@gmail.com>
…ys.tsx

Co-authored-by: Dan Rukas <dan.rukas@gmail.com>
…ys.tsx

Co-authored-by: Dan Rukas <dan.rukas@gmail.com>
Copy link
Copy Markdown

@claude claude Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude Code Review

This pull request is from a fork — automated review is disabled. A repository maintainer can comment @claude review to run a one-time review.

@netlify
Copy link
Copy Markdown

netlify Bot commented May 22, 2026

Deploy Preview for ohif-dev failed. Why did it fail? →

Name Link
🔨 Latest commit dcedf30
🔍 Latest deploy log https://app.netlify.com/projects/ohif-dev/deploys/6a103ac87478dd000874a46d

Comment thread extensions/cornerstone/src/utils/gpuPerformanceTest.ts Outdated
Comment thread platform/core/src/utils/volumeOptionsStorage.ts
Comment thread extensions/cornerstone/src/init.tsx
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