Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions packages/core/src/RenderingEngine/StackViewport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -995,6 +995,15 @@ class StackViewport extends Viewport {

if (typeof colormap !== 'undefined') {
this.setColormap(colormap);
// setColormap rebuilds the RGB transfer function in its default,
// non-inverted state, so `this.invert` no longer reflects the actor's
// actual LUT. Clear the tracked flag so the setInvertColor below actually
// re-applies the inversion instead of being skipped by its no-op guard
// (setInvertColorGPU only flips the TF when the requested value differs
// from this.invert). Without this, invert is lost when scrolling after a
// reset: reset applies a colormap, which is then re-applied on every
// scroll and clobbers the inversion.
this.invert = false;
}

this.setInterpolationType(interpolationType);
Expand Down
52 changes: 51 additions & 1 deletion packages/core/test/stackViewport_gpu_render_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ const { cache, RenderingEngine, utilities, imageLoader, metaData, Enums } =
cornerstone3D;

const { Events, ViewportType, InterpolationType } = Enums;
const { calibratedPixelSpacingMetadataProvider } = utilities;
const { calibratedPixelSpacingMetadataProvider, transferFunctionUtils } =
utilities;

const { fakeImageLoader, fakeMetaDataProvider, compareImages } = testUtils;

Expand Down Expand Up @@ -916,6 +917,55 @@ describe('renderingCore -- Stack', () => {
.catch(done.fail);
});

it('Should preserve inversion when scrolling after resetProperties', function (done) {
testUtils.createViewports(renderingEngine, {
viewportId,
orientation: Enums.OrientationAxis.AXIAL,
});

const imageInfo = {
loader: 'fakeImageLoader',
name: 'imageURI',
rows: 64,
columns: 64,
barStart: 20,
barWidth: 5,
xSpacing: 1,
ySpacing: 1,
sliceIndex: 0,
};
const imageId1 = testUtils.encodeImageIdInfo(imageInfo);
const imageId2 = testUtils.encodeImageIdInfo({
...imageInfo,
sliceIndex: 1,
});

const vp = renderingEngine.getViewport(viewportId);
const getTransferFunctionColors = () => {
const actor = vp.getDefaultActor().actor;
const transferFunction = actor.getProperty().getRGBTransferFunction(0);

return transferFunctionUtils
.getTransferFunctionNodes(transferFunction)
.map(([, red, green, blue]) => [red, green, blue]);
};

vp.setStack([imageId1, imageId2], 0)
.then(() => {
vp.resetProperties();
vp.setProperties({ invert: true });

const invertedColors = getTransferFunctionColors();

return vp.setImageIdIndex(1).then(() => {
expect(vp.getProperties().invert).toBe(true);
expect(getTransferFunctionColors()).toEqual(invertedColors);
});
})
.then(done)
.catch(done.fail);
});

it('Should be able to resetProperties API', function (done) {
const element = testUtils.createViewports(renderingEngine, {
viewportId,
Expand Down
Loading