diff --git a/Sources/Common/Core/LookupTable/test/testSetTable.js b/Sources/Common/Core/LookupTable/test/testSetTable.js index ad6a81de41b..d66f7cf326f 100644 --- a/Sources/Common/Core/LookupTable/test/testSetTable.js +++ b/Sources/Common/Core/LookupTable/test/testSetTable.js @@ -12,7 +12,7 @@ import vtkPolyData from 'vtk.js/Sources/Common/DataModel/PolyData'; import baseline from './testSetTable.png'; -it.skip('Test LookupTable setTable', () => { +it.skipIf(__VTK_TEST_NO_WEBGL__)('Test LookupTable setTable', () => { const gc = testUtils.createGarbageCollector(); expect('rendering', 'vtkLookupTable TestSetTable').toBeTruthy(); // testUtils.keepDOM(); diff --git a/Sources/Rendering/Core/Mapper/test/testEdgeVisibility.js b/Sources/Rendering/Core/Mapper/test/testEdgeVisibility.js index c1bccfe3a4e..4a12f15fa38 100644 --- a/Sources/Rendering/Core/Mapper/test/testEdgeVisibility.js +++ b/Sources/Rendering/Core/Mapper/test/testEdgeVisibility.js @@ -10,7 +10,7 @@ import vtkMapper from 'vtk.js/Sources/Rendering/Core/Mapper'; import baseline from './testEdgeVisibility.png'; -it.skip('Test Edge Visibility', () => { +it.skipIf(__VTK_TEST_NO_WEBGL__)('Test Edge Visibility', () => { const gc = testUtils.createGarbageCollector(); expect('rendering', 'vtkMapper EdgeVisibility').toBeTruthy(); @@ -50,7 +50,7 @@ it.skip('Test Edge Visibility', () => { testUtils.compareImages( image, [baseline], - 'Rendering/Core/Mapper/testEdgeVisibility.js', + 'Rendering/Core/Mapper/testEdgeVisibility', 1 ) ) diff --git a/Sources/Rendering/Core/Mapper/test/testEdgeVisibility.png b/Sources/Rendering/Core/Mapper/test/testEdgeVisibility.png index b165b2f1e17..01403f8d4e4 100644 Binary files a/Sources/Rendering/Core/Mapper/test/testEdgeVisibility.png and b/Sources/Rendering/Core/Mapper/test/testEdgeVisibility.png differ diff --git a/Sources/Rendering/Core/VolumeMapper/test/testAverageIntensityProjection.js b/Sources/Rendering/Core/VolumeMapper/test/testAverageIntensityProjection.js index a078a65f9ea..c142b254ab1 100644 --- a/Sources/Rendering/Core/VolumeMapper/test/testAverageIntensityProjection.js +++ b/Sources/Rendering/Core/VolumeMapper/test/testAverageIntensityProjection.js @@ -14,87 +14,92 @@ import Constants from 'vtk.js/Sources/Rendering/Core/VolumeMapper/Constants'; import baseline from './testAverageIntensityProjection.png'; -it.skip('Test Average Intensity Projection Volume Rendering', async () => { - const gc = testUtils.createGarbageCollector(); - expect('rendering', 'vtkVolumeMapper AverageIP').toBeTruthy(); - // testUtils.keepDOM(); - - // Create some control UI - const container = document.querySelector('body'); - const renderWindowContainer = gc.registerDOMElement( - document.createElement('div') - ); - container.appendChild(renderWindowContainer); - - // create what we will view - const renderWindow = gc.registerResource(vtkRenderWindow.newInstance()); - const renderer = gc.registerResource(vtkRenderer.newInstance()); - renderWindow.addRenderer(renderer); - renderer.setBackground(0.32, 0.34, 0.43); - - const actor = gc.registerResource(vtkVolume.newInstance()); - - const mapper = gc.registerResource(vtkVolumeMapper.newInstance()); - mapper.setSampleDistance(0.7); - mapper.setBlendMode(Constants.BlendMode.AVERAGE_INTENSITY_BLEND); - - actor.setMapper(mapper); - - const reader = vtkHttpDataSetReader.newInstance({ fetchGzip: true }); - - // create color and opacity transfer functions - const ctfun = vtkColorTransferFunction.newInstance(); - ctfun.addRGBPoint(-3024, 0, 0, 0); - ctfun.addRGBPoint(-637.62, 1, 1, 1); - ctfun.addRGBPoint(700, 1, 1, 1); - ctfun.addRGBPoint(3071, 1, 1, 1); - ctfun.setMappingRange(500, 3000); - - const ofun = vtkPiecewiseFunction.newInstance(); - ofun.addPoint(-3024, 0); - ofun.addPoint(-637.62, 0); - ofun.addPoint(700, 0.5); - ofun.addPoint(3071, 0.9); - - actor.getProperty().setRGBTransferFunction(0, ctfun); - actor.getProperty().setScalarOpacity(0, ofun); - actor.getProperty().setScalarOpacityUnitDistance(0, 4.5); - actor.getProperty().setInterpolationTypeToFastLinear(); - - mapper.setInputConnection(reader.getOutputPort()); - - // now create something to view it - const glwindow = gc.registerResource(renderWindow.newAPISpecificView()); - glwindow.setContainer(renderWindowContainer); - renderWindow.addView(glwindow); - glwindow.setSize(400, 400); - - // Interactor - const interactor = vtkRenderWindowInteractor.newInstance(); - interactor.setStillUpdateRate(0.01); - interactor.setView(glwindow); - interactor.initialize(); - interactor.bindEvents(renderWindowContainer); - - await reader.setUrl(`${__BASE_PATH__}/Data/volume/headsq.vti`); - await reader.loadData(); - - renderer.addVolume(actor); - renderer.resetCamera(); - - const promise = glwindow.captureNextImage().then((image) => - testUtils.compareImages( - image, - [baseline], - 'Rendering/Core/VolumeMapper/testAverageIntensityProjection', - { - // be stricter here - pixelThreshold: 0.01, - mismatchTolerance: 1.0, - }, - gc.releaseResources - ) - ); - renderWindow.render(); - return promise; -}); +it.skipIf(__VTK_TEST_NO_WEBGL__)( + 'Test Average Intensity Projection Volume Rendering', + async () => { + const gc = testUtils.createGarbageCollector(); + expect('rendering', 'vtkVolumeMapper AverageIP').toBeTruthy(); + // testUtils.keepDOM(); + + // Create some control UI + const container = document.querySelector('body'); + const renderWindowContainer = gc.registerDOMElement( + document.createElement('div') + ); + container.appendChild(renderWindowContainer); + + // create what we will view + const renderWindow = gc.registerResource(vtkRenderWindow.newInstance()); + const renderer = gc.registerResource(vtkRenderer.newInstance()); + renderWindow.addRenderer(renderer); + renderer.setBackground(0.32, 0.34, 0.43); + + const actor = gc.registerResource(vtkVolume.newInstance()); + + const mapper = gc.registerResource(vtkVolumeMapper.newInstance()); + mapper.setSampleDistance(0.7); + mapper.setBlendMode(Constants.BlendMode.AVERAGE_INTENSITY_BLEND); + + actor.setMapper(mapper); + + const reader = vtkHttpDataSetReader.newInstance({ fetchGzip: true }); + + // create color and opacity transfer functions + const ctfun = vtkColorTransferFunction.newInstance(); + ctfun.addRGBPoint(-3024, 0, 0, 0); + ctfun.addRGBPoint(-637.62, 1, 1, 1); + ctfun.addRGBPoint(700, 1, 1, 1); + ctfun.addRGBPoint(3071, 1, 1, 1); + ctfun.setMappingRange(500, 3000); + + const ofun = vtkPiecewiseFunction.newInstance(); + ofun.addPoint(-3024, 0); + ofun.addPoint(-637.62, 0); + ofun.addPoint(700, 0.5); + ofun.addPoint(3071, 0.9); + + actor.getProperty().setRGBTransferFunction(0, ctfun); + actor.getProperty().setScalarOpacity(0, ofun); + actor.getProperty().setScalarOpacityUnitDistance(0, 4.5); + actor.getProperty().setInterpolationTypeToFastLinear(); + + mapper.setInputConnection(reader.getOutputPort()); + + // now create something to view it + const glwindow = gc.registerResource(renderWindow.newAPISpecificView()); + glwindow.setContainer(renderWindowContainer); + renderWindow.addView(glwindow); + glwindow.setSize(400, 400); + + // Interactor + const interactor = vtkRenderWindowInteractor.newInstance(); + interactor.setStillUpdateRate(0.01); + interactor.setView(glwindow); + interactor.initialize(); + interactor.bindEvents(renderWindowContainer); + + await reader.setUrl(`${__BASE_PATH__}/Data/volume/headsq.vti`); + await reader.loadData(); + + renderer.addVolume(actor); + renderer.resetCamera(); + + const promise = glwindow + .captureNextImage() + .then((image) => + testUtils.compareImages( + image, + [baseline], + 'Rendering/Core/VolumeMapper/testAverageIntensityProjection', + { + // be stricter here + pixelThreshold: 0.01, + mismatchTolerance: 1.0, + } + ) + ) + .finally(gc.releaseResources); + renderWindow.render(); + return promise; + } +); diff --git a/Sources/Rendering/Core/VolumeMapper/test/testAverageIntensityProjection.png b/Sources/Rendering/Core/VolumeMapper/test/testAverageIntensityProjection.png index fe9fe011e06..a691c7502ce 100644 Binary files a/Sources/Rendering/Core/VolumeMapper/test/testAverageIntensityProjection.png and b/Sources/Rendering/Core/VolumeMapper/test/testAverageIntensityProjection.png differ diff --git a/Sources/Rendering/OpenGL/VolumeMapper/test/testLabelmapOutlineManyRenderer.js b/Sources/Rendering/OpenGL/VolumeMapper/test/testLabelmapOutlineManyRenderer.js index 1839e0a2025..4e372476d37 100644 --- a/Sources/Rendering/OpenGL/VolumeMapper/test/testLabelmapOutlineManyRenderer.js +++ b/Sources/Rendering/OpenGL/VolumeMapper/test/testLabelmapOutlineManyRenderer.js @@ -74,7 +74,7 @@ function createLabelPipeline(backgroundImageData, gc) { ); labelMapData.getPointData().setScalars(dataArray); - labelMapData.setDimensions(backgroundImageData.getDimensionsByReference()); + labelMapData.setDimensions(backgroundImageData.getDimensions()); labelMapData.setSpacing(backgroundImageData.getSpacingByReference()); labelMapData.setOrigin(backgroundImageData.getOriginByReference()); labelMapData.setDirection(backgroundImageData.getDirectionByReference()); @@ -145,162 +145,165 @@ function fillBlobForThreshold(imageData, backgroundImageData) { imageData.getPointData().getScalars().setData(values); } -it.skip('Test Labelmap Outline with many renderers', async () => { - const gc = testUtils.createGarbageCollector(); - expect('rendering', 'LabelmapOutline manyRenderers').toBeTruthy(); +it.skipIf(__VTK_TEST_NO_WEBGL__)( + 'Test Labelmap Outline with many renderers', + async () => { + const gc = testUtils.createGarbageCollector(); + expect('rendering', 'LabelmapOutline manyRenderers').toBeTruthy(); - const renderWindow = gc.registerResource(vtkRenderWindow.newInstance()); - const glwindow = gc.registerResource(vtkOpenGLRenderWindow.newInstance()); - renderWindow.addView(glwindow); + const renderWindow = gc.registerResource(vtkRenderWindow.newInstance()); + const glwindow = gc.registerResource(vtkOpenGLRenderWindow.newInstance()); + renderWindow.addView(glwindow); - // Create some control UI - const bodyElement = document.querySelector('body'); - bodyElement.style.margin = 0; + // Create some control UI + const bodyElement = document.querySelector('body'); + bodyElement.style.margin = 0; - const rootContainer = gc.registerDOMElement(document.createElement('div')); - rootContainer.style.position = 'fixed'; - rootContainer.style.zIndex = -1; - rootContainer.style.left = 0; - rootContainer.style.top = 0; - rootContainer.style.pointerEvents = 'none'; + const rootContainer = gc.registerDOMElement(document.createElement('div')); + rootContainer.style.position = 'fixed'; + rootContainer.style.zIndex = -1; + rootContainer.style.left = 0; + rootContainer.style.top = 0; + rootContainer.style.pointerEvents = 'none'; - bodyElement.appendChild(rootContainer); - glwindow.setContainer(rootContainer); + bodyElement.appendChild(rootContainer); + glwindow.setContainer(rootContainer); - const interactor = gc.registerResource( - vtkRenderWindowInteractor.newInstance() - ); - interactor.setView(glwindow); - interactor.initialize(); - - resize(renderWindow, glwindow); - - // ---------------------------------------------------------------------------- - // Renderers - // ---------------------------------------------------------------------------- - let rendererId = 1; - - const reader = vtkHttpDataSetReader.newInstance({ - fetchGzip: true, - }); - - await reader.setUrl(`${__BASE_PATH__}/Data/volume/headsq.vti`, { - loadData: true, - }); - - const data = reader.getOutputData(); - const labelMap = createLabelPipeline(data, gc); - fillBlobForThreshold(labelMap.imageData, data); - - for (let i = 0; i < 2; i++) { - const mapper = gc.registerResource(vtkVolumeMapper.newInstance()); - mapper.setInputData(data); - const el = gc.registerDOMElement(document.createElement('div')); - el.classList.add('renderer'); - el.style.width = '400px'; - el.style.height = '400px'; - - el.id = rendererId++; - bodyElement.appendChild(el); - - const actor = gc.registerResource(vtkVolume.newInstance()); - actor.getProperty().setInterpolationTypeToNearest(); - - actor.setMapper(mapper); - - const ofun = vtkPiecewiseFunction.newInstance(); - ofun.addPoint(0, 0); - ofun.addPoint(1, 1.0); - actor.getProperty().setScalarOpacity(0, ofun); - - const sourceDataRGBTransferFunction = actor - .getProperty() - .getRGBTransferFunction(0); - sourceDataRGBTransferFunction.setMappingRange(324, 2324); - - const renderer = gc.registerResource(vtkRenderer.newInstance()); - renderer.addVolume(actor); - renderer.addVolume(labelMap.actor); - - renderWindow.addRenderer(renderer); - renderer.resetCamera(); - - // MPR slice custom, for some reason doesn't work if we set it as interactorStyle - const camera = renderer.getActiveCamera(); - const normal = camera.getDirectionOfProjection(); - // prevent zoom manipulator from messing with our focal point - camera.setFreezeFocalPoint(true); - vtkMath.normalize(normal); - - const bounds = mapper.getBounds(); - - // diagonal will be used as "width" of camera scene - const diagonal = Math.sqrt( - vtkMath.distance2BetweenPoints( - [bounds[0], bounds[2], bounds[4]], - [bounds[1], bounds[3], bounds[5]] - ) + const interactor = gc.registerResource( + vtkRenderWindowInteractor.newInstance() ); + interactor.setView(glwindow); + interactor.initialize(); + + resize(renderWindow, glwindow); + + // ---------------------------------------------------------------------------- + // Renderers + // ---------------------------------------------------------------------------- + let rendererId = 1; + + const reader = vtkHttpDataSetReader.newInstance({ + fetchGzip: true, + }); + + await reader.setUrl(`${__BASE_PATH__}/Data/volume/headsq.vti`, { + loadData: true, + }); + + const data = reader.getOutputData(); + const labelMap = createLabelPipeline(data, gc); + fillBlobForThreshold(labelMap.imageData, data); + + for (let i = 0; i < 2; i++) { + const mapper = gc.registerResource(vtkVolumeMapper.newInstance()); + mapper.setInputData(data); + const el = gc.registerDOMElement(document.createElement('div')); + el.classList.add('renderer'); + el.style.width = '400px'; + el.style.height = '400px'; + + el.id = rendererId++; + bodyElement.appendChild(el); + + const actor = gc.registerResource(vtkVolume.newInstance()); + actor.getProperty().setInterpolationTypeToNearest(); + + actor.setMapper(mapper); + + const ofun = vtkPiecewiseFunction.newInstance(); + ofun.addPoint(0, 0); + ofun.addPoint(1, 1.0); + actor.getProperty().setScalarOpacity(0, ofun); + + const sourceDataRGBTransferFunction = actor + .getProperty() + .getRGBTransferFunction(0); + sourceDataRGBTransferFunction.setMappingRange(324, 2324); + + const renderer = gc.registerResource(vtkRenderer.newInstance()); + renderer.addVolume(actor); + renderer.addVolume(labelMap.actor); + + renderWindow.addRenderer(renderer); + renderer.resetCamera(); + + // MPR slice custom, for some reason doesn't work if we set it as interactorStyle + const camera = renderer.getActiveCamera(); + const normal = camera.getDirectionOfProjection(); + // prevent zoom manipulator from messing with our focal point + camera.setFreezeFocalPoint(true); + vtkMath.normalize(normal); + + const bounds = mapper.getBounds(); + + // diagonal will be used as "width" of camera scene + const diagonal = Math.sqrt( + vtkMath.distance2BetweenPoints( + [bounds[0], bounds[2], bounds[4]], + [bounds[1], bounds[3], bounds[5]] + ) + ); + + // center will be used as initial focal point + const center = [ + (bounds[0] + bounds[1]) / 2.0, + (bounds[2] + bounds[3]) / 2.0, + (bounds[4] + bounds[5]) / 2.0, + ]; + + const angle = 90; + // distance from camera to focal point + const dist = diagonal / (2 * Math.tan((angle / 360) * Math.PI)); + + const cameraPos = [ + center[0] - normal[0] * dist, + center[1] - normal[1] * dist, + center[2] - normal[2] * dist, + ]; + + // set viewUp based on DOP rotation + const oldDop = camera.getDirectionOfProjection(); + const transform = vtkMatrixBuilder + .buildFromDegree() + .identity() + .rotateFromDirections(oldDop, normal); + + const viewUp = [0, 1, 0]; + transform.apply(viewUp); + + camera.setParallelProjection(true); + + camera.setPosition(...cameraPos); + camera.setDistance(dist); + // camera.setFocalPoint(center) + // should be set after pos and distance + camera.setDirectionOfProjection(...normal); + camera.setViewUp(...viewUp); + camera.setViewAngle(angle); + camera.setClippingRange(dist, dist + 0.1); + camera.setParallelScale(20); + + updateViewPort(el, renderer); + renderer.getActiveCamera().setViewUp(1, 0, 0); + renderWindow.render(); + + // Keep track of renderer + RENDERERS[el.id] = renderer; + } - // center will be used as initial focal point - const center = [ - (bounds[0] + bounds[1]) / 2.0, - (bounds[2] + bounds[3]) / 2.0, - (bounds[4] + bounds[5]) / 2.0, - ]; - - const angle = 90; - // distance from camera to focal point - const dist = diagonal / (2 * Math.tan((angle / 360) * Math.PI)); - - const cameraPos = [ - center[0] - normal[0] * dist, - center[1] - normal[1] * dist, - center[2] - normal[2] * dist, - ]; - - // set viewUp based on DOP rotation - const oldDop = camera.getDirectionOfProjection(); - const transform = vtkMatrixBuilder - .buildFromDegree() - .identity() - .rotateFromDirections(oldDop, normal); - - const viewUp = [0, 1, 0]; - transform.apply(viewUp); - - camera.setParallelProjection(true); - - camera.setPosition(...cameraPos); - camera.setDistance(dist); - // camera.setFocalPoint(center) - // should be set after pos and distance - camera.setDirectionOfProjection(...normal); - camera.setViewUp(...viewUp); - camera.setViewAngle(angle); - camera.setClippingRange(dist, dist + 0.1); - camera.setParallelScale(20); - - updateViewPort(el, renderer); - renderer.getActiveCamera().setViewUp(1, 0, 0); - renderWindow.render(); - - // Keep track of renderer - RENDERERS[el.id] = renderer; + const promise = glwindow + .captureNextImage() + .then((image) => + testUtils.compareImages( + image, + [baseline1], + 'Rendering/OpenGL/VolumeMapper/testLabelmapOutlineManyRenderer', + 1.5, + gc.releaseResources + ) + ); + + recomputeViewports(renderWindow); + return promise; } - - const promise = glwindow - .captureNextImage() - .then((image) => - testUtils.compareImages( - image, - [baseline1], - 'Rendering/OpenGL/VolumeMapper/testLabelmapOutlineManyRenderer', - 1.5, - gc.releaseResources - ) - ); - - recomputeViewports(renderWindow); - return promise; -}); +);