diff --git a/packages/core/src/RenderingEngine/StackViewport.ts b/packages/core/src/RenderingEngine/StackViewport.ts index c9f1c8ca8..cb58ff1d4 100644 --- a/packages/core/src/RenderingEngine/StackViewport.ts +++ b/packages/core/src/RenderingEngine/StackViewport.ts @@ -1309,8 +1309,8 @@ class StackViewport extends Viewport implements IStackViewport { const dataType = imageData.getPointData().getScalars().getDataType(); // using epsilon comparison for float numbers comparison. - const isSameXSpacing = isEqual(xSpacing, image.rowPixelSpacing); - const isSameYSpacing = isEqual(ySpacing, image.columnPixelSpacing); + const isSameXSpacing = isEqual(xSpacing, image.columnPixelSpacing); + const isSameYSpacing = isEqual(ySpacing, image.rowPixelSpacing); // using spacing, size, and direction only for now return ( diff --git a/packages/tools/test/StackScrollToolMouseWheelTool_test.js b/packages/tools/test/StackScrollToolMouseWheelTool_test.js index 427d5eac6..d101c979f 100644 --- a/packages/tools/test/StackScrollToolMouseWheelTool_test.js +++ b/packages/tools/test/StackScrollToolMouseWheelTool_test.js @@ -4,6 +4,7 @@ import * as testUtils from '../../../utils/test/testUtils'; import * as volumeURI_100_100_10_1_1_1_0_scrolled from './groundTruth/volumeURI_100_100_10_1_1_1_0_scrolled.png'; import * as imageURI_64_64_0_20_1_1_0_scrolled from './groundTruth/imageURI_64_64_0_20_1_1_0_scrolled.png'; +import * as imageURI_64_64_10_5_3_2_0 from './groundTruth/imageURI_64_64_10_5_3_2_0.png'; const { cache, @@ -18,7 +19,12 @@ const { const { Events, ViewportType, InterpolationType } = Enums; const { registerVolumeLoader } = volumeLoader; -const { StackScrollMouseWheelTool, ToolGroupManager } = csTools3d; +const { + StackScrollMouseWheelTool, + ZoomTool, + ToolGroupManager, + Enums: { MouseBindings }, +} = csTools3d; const { fakeImageLoader, @@ -65,6 +71,8 @@ describe('Cornerstone Tools Scroll Wheel: ', () => { beforeEach(function () { csTools3d.init(); csTools3d.addTool(StackScrollMouseWheelTool); + csTools3d.addTool(ZoomTool); + cache.purgeCache(); this.DOMElements = []; @@ -72,7 +80,17 @@ describe('Cornerstone Tools Scroll Wheel: ', () => { this.stackToolGroup.addTool(StackScrollMouseWheelTool.toolName, { debounceIfNotLoaded: false, }); + this.stackToolGroup.addTool(ZoomTool.toolName, { + debounceIfNotLoaded: false, + }); this.stackToolGroup.setToolActive(StackScrollMouseWheelTool.toolName); + this.stackToolGroup.setToolActive(ZoomTool.toolName, { + bindings: [ + { + mouseButton: MouseBindings.Secondary, // Right Click + }, + ], + }); this.renderingEngine = new RenderingEngine(renderingEngineId); imageLoader.registerImageLoader('fakeImageLoader', fakeImageLoader); @@ -254,4 +272,119 @@ describe('Cornerstone Tools Scroll Wheel: ', () => { done.fail(e); } }); + + it('Should successfully scroll through stack of images of non square spacing', function (done) { + const element = createViewport( + this.renderingEngine, + ViewportType.STACK, + 256, + 256 + ); + this.DOMElements.push(element); + + const imageId1 = 'fakeImageLoader:imageURI_64_64_10_5_3_2_0'; + const imageId2 = 'fakeImageLoader:imageURI_64_64_15_5_3_2_0'; + const vp = this.renderingEngine.getViewport(viewportId); + + let handlerRun = false; + function renderEventHandler() { + if (handlerRun) return; + handlerRun = true; + + // First render is the actual image render + const index1 = [0, 0, 4]; + const index2 = [10, 10, 4]; + + const { imageData } = vp.getImageData(); + + const { + pageX: pageX1, + pageY: pageY1, + clientX: clientX1, + clientY: clientY1, + } = createNormalizedMouseEvent(imageData, index1, element, vp); + + const { + pageX: pageX2, + pageY: pageY2, + clientX: clientX2, + clientY: clientY2, + } = createNormalizedMouseEvent(imageData, index2, element, vp); + + let evt = new MouseEvent('mousedown', { + target: element, + buttons: 2, + clientX: clientX1, + clientY: clientY1, + pageX: pageX1, + pageY: pageY1, + }); + element.dispatchEvent(evt); + + // Mouse move to put the end somewhere else + evt = new MouseEvent('mousemove', { + target: element, + buttons: 2, + clientX: clientX2, + clientY: clientY2, + pageX: pageX2, + pageY: pageY2, + }); + document.dispatchEvent(evt); + + setTimeout(() => { + evt = new WheelEvent('wheel', { + target: element, + pageX: pageX1, + pageY: pageY1, + deltaX: 0, + deltaY: 12, + deltaMode: 0, + wheelDelta: -36, + wheelDeltaX: 0, + wheelDeltaY: -36, + }); + + attachEventHandler(); + + element.removeEventListener(Events.IMAGE_RENDERED, renderEventHandler); + element.dispatchEvent(evt); + }, 500); + } + + function attachEventHandler() { + const canvas = vp.getCanvas(); + + element.addEventListener( + Events.IMAGE_RENDERED, + function secondImageRendered() { + // Second render is as a result of scrolling + const image = canvas.toDataURL('image/png'); + element.removeEventListener( + Events.IMAGE_RENDERED, + secondImageRendered + ); + + compareImages( + image, + imageURI_64_64_10_5_3_2_0, + 'imageURI_64_64_10_5_3_2_0' + ).then(done, done.fail); + } + ); + } + + element.addEventListener(Events.IMAGE_RENDERED, renderEventHandler); + + this.stackToolGroup.addViewport(vp.id, this.renderingEngine.id); + + try { + vp.setStack([imageId1, imageId2], 0).then(() => { + vp.setProperties({ interpolationType: InterpolationType.NEAREST }); + vp.render(); + }); + } catch (e) { + done.fail(e); + } + }); }); diff --git a/packages/tools/test/groundTruth/imageURI_64_64_10_5_3_2_0.png b/packages/tools/test/groundTruth/imageURI_64_64_10_5_3_2_0.png new file mode 100644 index 000000000..40af80b2f Binary files /dev/null and b/packages/tools/test/groundTruth/imageURI_64_64_10_5_3_2_0.png differ diff --git a/utils/test/testUtilsImageLoader.js b/utils/test/testUtilsImageLoader.js index ce4d93f54..61a056180 100644 --- a/utils/test/testUtilsImageLoader.js +++ b/utils/test/testUtilsImageLoader.js @@ -49,8 +49,8 @@ const fakeImageLoader = (imageId) => { windowWidth: 400, maxPixelValue: 255, minPixelValue: 0, - rowPixelSpacing: 1, - columnPixelSpacing: 1, + rowPixelSpacing: y_spacing, + columnPixelSpacing: x_spacing, getPixelData: () => pixelData, sizeInBytes: rows * columns * 1, // 1 byte for now FrameOfReferenceUID: 'Stack_Frame_Of_Reference', @@ -119,8 +119,8 @@ function fakeMetaDataProvider(type, imageId) { columnCosines: [0, 1, 0], imagePositionPatient: [0, 0, 0], pixelSpacing: [x_spacing, y_spacing], - rowPixelSpacing: x_spacing, - columnPixelSpacing: y_spacing, + rowPixelSpacing: y_spacing, + columnPixelSpacing: x_spacing, }; return imagePlaneModule;