Skip to content

fix(3d-viewport): preserve image color preset when resetting 3D viewport#5952

Open
GhadeerAlbattarni wants to merge 3 commits intoOHIF:masterfrom
GhadeerAlbattarni:fix/5922-3d-reset-skin-color
Open

fix(3d-viewport): preserve image color preset when resetting 3D viewport#5952
GhadeerAlbattarni wants to merge 3 commits intoOHIF:masterfrom
GhadeerAlbattarni:fix/5922-3d-reset-skin-color

Conversation

@GhadeerAlbattarni
Copy link
Copy Markdown
Collaborator

@GhadeerAlbattarni GhadeerAlbattarni commented Apr 8, 2026

Context

Fixes #5922

When a user opens a study in 3D layout, the viewport correctly renders with the configured color preset (e.g. CT-Skin showing skin colors). However, clicking Reset causes the 3D image to display in black and white.

Root cause

The root cause is a timing issue in Cornerstone3D: the "initial" state snapshot of the color transfer function is taken at volume load time, before OHIF applies the configured preset. So when Reset restores that snapshot, it restores a grayscale state that predates the color preset.

Changes & Results

In the resetViewport (commandsModule.ts), capture the current preset from viewport.getProperties() before calling resetProperties(), then re-apply it afterwards. This ensures the color preset survives the reset while all other properties (camera, zoom, etc ) are still reset as expected.

Before

3dReset-Before.mov

After

3dReset-After.mov

Testing

1- Open a study in the viewer mode (e.g., StudyInstanceUIDs=2.16.840.1.114362.1.11972228.22789312658.616067305.306.2)
2- Switch to 3D layout
3- Verify image color is shown
4- Zoom in
5- Click Reset
6- Verify the image color is preserved and only the camera/zoom/pan is reset

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: macOS 10.15.4
  • Node version: v22.13.0
  • Browser: Chrome 83.0.4103.116

Greptile Summary

This PR fixes a timing issue where resetViewport was restoring the 3D viewport's color transfer function to a grayscale snapshot taken at volume load time — before OHIF's configured preset was ever applied. The fix captures preset from getProperties() immediately before resetProperties() and re-applies it afterward. The guard if (preset) makes the change a no-op for 2D stack viewports where preset is not a property.

Confidence Score: 5/5

Safe to merge; the fix is minimal, well-guarded, and correct for both 3D and 2D viewports.

No P0 or P1 findings. The only remark is the generous screenshot diff tolerance (18%) in the new test, which is a P2 quality concern and does not block the fix from being correct or safe.

tests/3DOnly.spec.ts — consider tightening maxDiffPixelRatio from 0.18 to match the existing 3D test's 0.04.

Vulnerabilities

No security concerns identified.

Important Files Changed

Filename Overview
extensions/cornerstone/src/commandsModule.ts Captures the current preset from getProperties() before resetProperties() and re-applies it afterwards; safe for non-3D viewports because preset will be undefined and the guard prevents any re-application.
tests/3DOnly.spec.ts Adds screenshot regression test for the color-preset-after-reset fix; tolerance of 18% is considerably higher than other 3D tests (4%) and may not reliably catch the grayscale regression.
tests/utils/screenShotPaths.ts Adds reset3D.colorPresetPreservedAfterReset path entry, consistent with existing naming patterns.
Prompt To Fix All With AI
This is a comment left during a code review.
Path: tests/3DOnly.spec.ts
Line: 50

Comment:
**High pixel-diff tolerance may hide regressions**

`maxDiffPixelRatio: 0.18` (18%) is very permissive compared to the existing 3D screenshot test that uses `0.04` (4%). At 18%, a partially-grayscale render could still pass the comparison, which is the exact regression this test is meant to catch. Consider tightening the ratio; the existing 3D test at 4% already accounts for cross-environment color variation in 3D rendering.

How can I resolve this? If you propose a fix, please make it concise.

Reviews (1): Last reviewed commit: "Merge remote-tracking branch 'upstream/m..." | Re-trigger Greptile

Greptile also left 1 inline comment on this PR.

@netlify
Copy link
Copy Markdown

netlify bot commented Apr 8, 2026

Deploy Preview for ohif-dev ready!

Name Link
🔨 Latest commit 2bfc45e
🔍 Latest deploy log https://app.netlify.com/projects/ohif-dev/deploys/69d6d97451047b0008f9c62d
😎 Deploy Preview https://deploy-preview-5952--ohif-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.

Comment thread tests/3DOnly.spec.ts
page,
locator: activeViewport.pane,
screenshotPath: screenShotPaths.reset3D.colorPresetPreservedAfterReset,
maxDiffPixelRatio: 0.18,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 High pixel-diff tolerance may hide regressions

maxDiffPixelRatio: 0.18 (18%) is very permissive compared to the existing 3D screenshot test that uses 0.04 (4%). At 18%, a partially-grayscale render could still pass the comparison, which is the exact regression this test is meant to catch. Consider tightening the ratio; the existing 3D test at 4% already accounts for cross-environment color variation in 3D rendering.

Prompt To Fix With AI
This is a comment left during a code review.
Path: tests/3DOnly.spec.ts
Line: 50

Comment:
**High pixel-diff tolerance may hide regressions**

`maxDiffPixelRatio: 0.18` (18%) is very permissive compared to the existing 3D screenshot test that uses `0.04` (4%). At 18%, a partially-grayscale render could still pass the comparison, which is the exact regression this test is meant to catch. Consider tightening the ratio; the existing 3D test at 4% already accounts for cross-environment color variation in 3D rendering.

How can I resolve this? If you propose a fix, please make it concise.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

yeah it might be best to simply not have a test for this fix.

@GhadeerAlbattarni GhadeerAlbattarni requested a review from jbocce April 8, 2026 22:50
// appearance is preserved. This is because resetProperties() restores the
// transfer function to grayscale nodes captured at volume load time,
// which is before the initial preset (e.g. skin color) was ever applied.
const { preset } = viewport.getProperties?.() ?? {};
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I'm not sure this is the correct fix. I think the fix would be in cornerstone.

Copy link
Copy Markdown
Collaborator

@jbocce jbocce left a comment

Choose a reason for hiding this comment

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

We can live without the test. However, we should spend more time looking at fixing this in CS3D.

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.

[Bug] Color is reset on 3D image

2 participants