Skip to content

Commit a626193

Browse files
authored
Merge branch 'master' into more-ts-defs
2 parents 27f4b25 + 2e43a9a commit a626193

File tree

15 files changed

+185
-85
lines changed

15 files changed

+185
-85
lines changed

Sources/Rendering/Core/ImageMapper/index.d.ts

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,11 @@ export interface IImageMapperInitialValues extends IAbstractMapperInitialValues
3434

3535
export interface vtkImageMapper extends vtkAbstractMapper {
3636

37-
/**
38-
*
39-
* @param {Number} pos The position value.
40-
*/
41-
getSliceAtPosition(pos: number): number;
42-
43-
/**
44-
*
45-
* @param {Vector3} pos The position value.
46-
*/
47-
getSliceAtPosition(pos: Vector3): number;
37+
/**
38+
* Returns the IJK slice value from a world position or XYZ slice value
39+
* @param {Vector3 | number} [pos] World point or XYZ slice value
40+
*/
41+
getSliceAtPosition(pos: Vector3 | number): number;
4842

4943
/**
5044
* Get the closest IJK axis

Sources/Rendering/Core/ImageMapper/index.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,19 +51,17 @@ function vtkImageMapper(publicAPI, model) {
5151
switch (ijkMode) {
5252
case SlicingMode.I:
5353
slice = vtkMath.clampValue(ijk[0], ex[0], ex[1]);
54-
slice = Math.round(slice);
5554
break;
5655
case SlicingMode.J:
5756
slice = vtkMath.clampValue(ijk[1], ex[2], ex[3]);
58-
slice = Math.round(slice);
5957
break;
6058
case SlicingMode.K:
6159
slice = vtkMath.clampValue(ijk[2], ex[4], ex[5]);
62-
slice = Math.round(slice);
6360
break;
6461
default:
6562
return 0;
6663
}
64+
6765
return slice;
6866
};
6967

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import test from 'tape-catch';
2+
3+
import vtkImageMapper from 'vtk.js/Sources/Rendering/Core/ImageMapper';
4+
import { SlicingMode } from 'vtk.js/Sources/Rendering/Core/ImageMapper/Constants';
5+
import vtkImageSlice from 'vtk.js/Sources/Rendering/Core/ImageSlice';
6+
import vtkRTAnalyticSource from 'vtk.js/Sources/Filters/Sources/RTAnalyticSource';
7+
8+
test('Test slice position differences between XYZ and IJK modes', (t) => {
9+
const source = vtkRTAnalyticSource.newInstance({
10+
wholeExtent: [0, 10, 0, 10, 0, 10],
11+
});
12+
source.update();
13+
const image = source.getOutputData();
14+
image.setSpacing([10, 10, 10]);
15+
global.image = image;
16+
const mapper = vtkImageMapper.newInstance();
17+
const slice = vtkImageSlice.newInstance();
18+
mapper.setInputData(image);
19+
20+
slice.setMapper(mapper);
21+
22+
mapper.setSlicingMode(SlicingMode.Z);
23+
24+
t.equal(3, mapper.getSliceAtPosition(30));
25+
t.equal(3.5, mapper.getSliceAtPosition(35));
26+
27+
t.equal(5, mapper.getSliceAtPosition([0, 0, 50]));
28+
t.equal(5.5, mapper.getSliceAtPosition([0, 0, 55]));
29+
30+
t.equal(0, mapper.getSliceAtPosition(-1));
31+
t.equal(10, mapper.getSliceAtPosition(110));
32+
33+
t.end();
34+
});

Sources/Rendering/OpenGL/Actor/index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ function vtkOpenGLActor(publicAPI, model) {
132132

133133
publicAPI.opaquePass = (prepass, renderPass) => {
134134
if (prepass) {
135-
model.openGLRenderWindow.enableDepthMask();
135+
model.context.depthMask(true);
136136
publicAPI.activateTextures();
137137
} else if (model.activeTextures) {
138138
for (let index = 0; index < model.activeTextures.length; index++) {
@@ -144,7 +144,7 @@ function vtkOpenGLActor(publicAPI, model) {
144144
// Renders myself
145145
publicAPI.translucentPass = (prepass, renderPass) => {
146146
if (prepass) {
147-
model.openGLRenderWindow.disableDepthMask();
147+
model.context.depthMask(false);
148148
publicAPI.activateTextures();
149149
} else if (model.activeTextures) {
150150
for (let index = 0; index < model.activeTextures.length; index++) {

Sources/Rendering/OpenGL/Actor2D/index.js

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,12 @@ function vtkOpenGLActor2D(publicAPI, model) {
1717
if (!model.renderable) {
1818
return;
1919
}
20+
model.openGLRenderWindow = publicAPI.getFirstAncestorOfType(
21+
'vtkOpenGLRenderWindow'
22+
);
2023
model.openGLRenderer =
2124
publicAPI.getFirstAncestorOfType('vtkOpenGLRenderer');
25+
model.context = model.openGLRenderWindow.getContext();
2226
publicAPI.prepareNodes();
2327
publicAPI.addMissingNodes(model.renderable.getTextures());
2428
publicAPI.addMissingNode(model.renderable.getMapper());
@@ -84,9 +88,6 @@ function vtkOpenGLActor2D(publicAPI, model) {
8488
// Renders myself
8589
publicAPI.opaquePass = (prepass, renderPass) => {
8690
if (prepass) {
87-
model.context = publicAPI
88-
.getFirstAncestorOfType('vtkOpenGLRenderWindow')
89-
.getContext();
9091
model.context.depthMask(true);
9192
publicAPI.activateTextures();
9293
} else {
@@ -100,9 +101,6 @@ function vtkOpenGLActor2D(publicAPI, model) {
100101
// Renders myself
101102
publicAPI.translucentPass = (prepass, renderPass) => {
102103
if (prepass) {
103-
model.context = publicAPI
104-
.getFirstAncestorOfType('vtkOpenGLRenderWindow')
105-
.getContext();
106104
model.context.depthMask(false);
107105
publicAPI.activateTextures();
108106
} else {

Sources/Rendering/OpenGL/ImageMapper/index.js

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -850,12 +850,14 @@ function vtkOpenGLImageMapper(publicAPI, model) {
850850
const { ijkMode } = model.renderable.getClosestIJKAxis();
851851

852852
// Find the IJK slice
853-
let nSlice = model.renderable.getSlice();
853+
let slice = model.renderable.getSlice();
854854
if (ijkMode !== model.renderable.getSlicingMode()) {
855855
// If not IJK slicing, get the IJK slice from the XYZ position/slice
856-
nSlice = model.renderable.getSliceAtPosition(nSlice);
856+
slice = model.renderable.getSliceAtPosition(slice);
857857
}
858858

859+
const nSlice = Math.round(slice);
860+
859861
// Find sliceOffset
860862
const ext = image.getExtent();
861863
let sliceOffset;
@@ -870,7 +872,7 @@ function vtkOpenGLImageMapper(publicAPI, model) {
870872
}
871873

872874
// rebuild the VBO if the data has changed
873-
const toString = `${nSlice}A${image.getMTime()}A${imgScalars.getMTime()}B${publicAPI.getMTime()}C${model.renderable.getSlicingMode()}D${actor
875+
const toString = `${slice}A${image.getMTime()}A${imgScalars.getMTime()}B${publicAPI.getMTime()}C${model.renderable.getSlicingMode()}D${actor
874876
.getProperty()
875877
.getMTime()}`;
876878
if (model.VBOBuildString !== toString) {
@@ -922,16 +924,16 @@ function vtkOpenGLImageMapper(publicAPI, model) {
922924
}
923925
dims[0] = dims[1];
924926
dims[1] = dims[2];
925-
ptsArray[0] = nSlice;
927+
ptsArray[0] = slice;
926928
ptsArray[1] = ext[2];
927929
ptsArray[2] = ext[4];
928-
ptsArray[3] = nSlice;
930+
ptsArray[3] = slice;
929931
ptsArray[4] = ext[3];
930932
ptsArray[5] = ext[4];
931-
ptsArray[6] = nSlice;
933+
ptsArray[6] = slice;
932934
ptsArray[7] = ext[2];
933935
ptsArray[8] = ext[5];
934-
ptsArray[9] = nSlice;
936+
ptsArray[9] = slice;
935937
ptsArray[10] = ext[3];
936938
ptsArray[11] = ext[5];
937939
} else if (ijkMode === SlicingMode.J) {
@@ -947,16 +949,16 @@ function vtkOpenGLImageMapper(publicAPI, model) {
947949
}
948950
dims[1] = dims[2];
949951
ptsArray[0] = ext[0];
950-
ptsArray[1] = nSlice;
952+
ptsArray[1] = slice;
951953
ptsArray[2] = ext[4];
952954
ptsArray[3] = ext[1];
953-
ptsArray[4] = nSlice;
955+
ptsArray[4] = slice;
954956
ptsArray[5] = ext[4];
955957
ptsArray[6] = ext[0];
956-
ptsArray[7] = nSlice;
958+
ptsArray[7] = slice;
957959
ptsArray[8] = ext[5];
958960
ptsArray[9] = ext[1];
959-
ptsArray[10] = nSlice;
961+
ptsArray[10] = slice;
960962
ptsArray[11] = ext[5];
961963
} else if (ijkMode === SlicingMode.K || ijkMode === SlicingMode.NONE) {
962964
scalars = basicScalars.subarray(
@@ -965,16 +967,16 @@ function vtkOpenGLImageMapper(publicAPI, model) {
965967
);
966968
ptsArray[0] = ext[0];
967969
ptsArray[1] = ext[2];
968-
ptsArray[2] = nSlice;
970+
ptsArray[2] = slice;
969971
ptsArray[3] = ext[1];
970972
ptsArray[4] = ext[2];
971-
ptsArray[5] = nSlice;
973+
ptsArray[5] = slice;
972974
ptsArray[6] = ext[0];
973975
ptsArray[7] = ext[3];
974-
ptsArray[8] = nSlice;
976+
ptsArray[8] = slice;
975977
ptsArray[9] = ext[1];
976978
ptsArray[10] = ext[3];
977-
ptsArray[11] = nSlice;
979+
ptsArray[11] = slice;
978980
} else {
979981
vtkErrorMacro('Reformat slicing not yet supported.');
980982
}
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
import test from 'tape-catch';
2+
import testUtils from 'vtk.js/Sources/Testing/testUtils';
3+
4+
import vtkImageGridSource from 'vtk.js/Sources/Filters/Sources/ImageGridSource';
5+
import vtkImageMapper from 'vtk.js/Sources/Rendering/Core/ImageMapper';
6+
import vtkImageSlice from 'vtk.js/Sources/Rendering/Core/ImageSlice';
7+
import vtkOpenGLRenderWindow from 'vtk.js/Sources/Rendering/OpenGL/RenderWindow';
8+
import vtkRenderer from 'vtk.js/Sources/Rendering/Core/Renderer';
9+
import vtkRenderWindow from 'vtk.js/Sources/Rendering/Core/RenderWindow';
10+
import vtkColorTransferFunction from 'vtk.js/Sources/Rendering/Core/ColorTransferFunction';
11+
12+
import baseline from './testImageIntermediateZSlice.png';
13+
import { SlicingMode } from '../../../Core/ImageMapper/Constants';
14+
15+
test.onlyIfWebGL('Test ImageMapper intermediate slices', (t) => {
16+
const gc = testUtils.createGarbageCollector(t);
17+
t.ok('rendering', 'vtkOpenGLImageMapper testImage');
18+
19+
// Create some control UI
20+
const container = document.querySelector('body');
21+
const renderWindowContainer = gc.registerDOMElement(
22+
document.createElement('div')
23+
);
24+
container.appendChild(renderWindowContainer);
25+
26+
// create what we will view
27+
const renderWindow = gc.registerResource(vtkRenderWindow.newInstance());
28+
const renderer = gc.registerResource(vtkRenderer.newInstance());
29+
renderWindow.addRenderer(renderer);
30+
renderer.setBackground(0.32, 0.34, 0.43);
31+
32+
// ----------------------------------------------------------------------------
33+
// Test code
34+
// ----------------------------------------------------------------------------
35+
36+
const gridSource = gc.registerResource(vtkImageGridSource.newInstance());
37+
const extent = 200;
38+
const gridSpacing = 32;
39+
const dataSpacing = 4;
40+
const origin = 16;
41+
gridSource.setDataExtent(0, extent, 0, extent, 0, 4);
42+
gridSource.setDataSpacing(dataSpacing, dataSpacing, dataSpacing);
43+
gridSource.setGridSpacing(gridSpacing, gridSpacing, gridSpacing);
44+
gridSource.setGridOrigin(origin, origin, 1);
45+
const direction = [0.866, 0.5, 0, -0.5, 0.866, 0, 0, 0, 1];
46+
gridSource.setDataDirection(...direction);
47+
48+
const slice = 0;
49+
const offset = 1.5;
50+
51+
// mapperAbove should show above mapperBelow
52+
// scalars, however, should be correct
53+
const mapperBelow = gc.registerResource(vtkImageMapper.newInstance());
54+
mapperBelow.setInputConnection(gridSource.getOutputPort());
55+
mapperBelow.setSlicingMode(SlicingMode.Z);
56+
mapperBelow.setSlice(slice * dataSpacing);
57+
58+
const mapperAbove = gc.registerResource(vtkImageMapper.newInstance());
59+
mapperAbove.setInputConnection(gridSource.getOutputPort());
60+
mapperAbove.setSlicingMode(SlicingMode.Z);
61+
mapperAbove.setSlice(slice * dataSpacing + offset);
62+
63+
// make sure that if both mappers were coincident,
64+
// mapperBelow would show above mapperAbove, breaking the test
65+
mapperBelow.setResolveCoincidentTopologyToPolygonOffset();
66+
mapperAbove.setResolveCoincidentTopologyToPolygonOffset();
67+
mapperBelow.setRelativeCoincidentTopologyPolygonOffsetParameters(0, -1);
68+
mapperAbove.setRelativeCoincidentTopologyPolygonOffsetParameters(0, 1);
69+
70+
const actorBelow = gc.registerResource(vtkImageSlice.newInstance());
71+
const rgb = vtkColorTransferFunction.newInstance();
72+
rgb.addRGBPoint(0, 0, 0, 0);
73+
rgb.addRGBPoint(255, 0, 0, 0);
74+
actorBelow.getProperty().setRGBTransferFunction(rgb);
75+
actorBelow.setMapper(mapperBelow);
76+
actorBelow.setPosition(100, 100, 0);
77+
78+
const actorAbove = gc.registerResource(vtkImageSlice.newInstance());
79+
actorAbove.setMapper(mapperAbove);
80+
actorAbove.setPosition(-100, 0, 0);
81+
82+
renderer.addActor(actorBelow);
83+
renderer.addActor(actorAbove);
84+
renderer.resetCamera();
85+
86+
// -----------------------------------------------------------
87+
// Make some variables global so that you can inspect and
88+
// modify objects in your browser's developer console:
89+
// -----------------------------------------------------------
90+
91+
// create something to view it, in this case webgl
92+
const glwindow = gc.registerResource(vtkOpenGLRenderWindow.newInstance());
93+
glwindow.setContainer(renderWindowContainer);
94+
renderWindow.addView(glwindow);
95+
glwindow.setSize(400, 400);
96+
97+
glwindow.captureNextImage().then((image) => {
98+
testUtils.compareImages(
99+
image,
100+
[baseline],
101+
'Rendering/OpenGL/ImageMapper',
102+
t,
103+
0.5,
104+
gc.releaseResources
105+
);
106+
});
107+
renderWindow.render();
108+
});
21.9 KB
Loading

Sources/Rendering/OpenGL/ImageSlice/index.js

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,12 @@ function vtkOpenGLImageSlice(publicAPI, model) {
2222
if (!model.renderable) {
2323
return;
2424
}
25-
25+
model.openGLRenderWindow = publicAPI.getFirstAncestorOfType(
26+
'vtkOpenGLRenderWindow'
27+
);
2628
model.openGLRenderer =
2729
publicAPI.getFirstAncestorOfType('vtkOpenGLRenderer');
30+
model.context = model.openGLRenderWindow.getContext();
2831
publicAPI.prepareNodes();
2932
publicAPI.addMissingNode(model.renderable.getMapper());
3033
publicAPI.removeUnusedNodes();
@@ -92,23 +95,13 @@ function vtkOpenGLImageSlice(publicAPI, model) {
9295
// Renders myself
9396
publicAPI.opaquePass = (prepass, renderPass) => {
9497
if (prepass) {
95-
model.context = publicAPI
96-
.getFirstAncestorOfType('vtkOpenGLRenderWindow')
97-
.getContext();
9898
model.context.depthMask(true);
9999
}
100100
};
101101

102102
// Renders myself
103103
publicAPI.translucentPass = (prepass, renderPass) => {
104-
if (prepass) {
105-
model.context = publicAPI
106-
.getFirstAncestorOfType('vtkOpenGLRenderWindow')
107-
.getContext();
108-
model.context.depthMask(false);
109-
} else {
110-
model.context.depthMask(true);
111-
}
104+
model.context.depthMask(!prepass);
112105
};
113106

114107
publicAPI.getKeyMatrices = () => {

Sources/Rendering/OpenGL/RenderWindow/index.d.ts

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -284,16 +284,6 @@ export interface vtkOpenGLRenderWindow extends vtkOpenGLRenderWindowBase {
284284
*/
285285
traverseAllPasses(): void;
286286

287-
/**
288-
*
289-
*/
290-
disableDepthMask(): void;
291-
292-
/**
293-
*
294-
*/
295-
enableDepthMask(): void;
296-
297287
/**
298288
*
299289
*/

0 commit comments

Comments
 (0)