Skip to content

Commit 50a4ead

Browse files
committed
feat(Viewer): Use ViewProxy and ProxyManager to create 3D view
1 parent a766bf5 commit 50a4ead

File tree

4 files changed

+149
-19
lines changed

4 files changed

+149
-19
lines changed

src/createViewer.js

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import vtkProxyManager from 'vtk.js/Sources/Proxy/Core/ProxyManager';
2+
3+
import proxyConfiguration from './proxyManagerConfiguration';
4+
import userInterface from './userInterface';
5+
6+
const STYLE_CONTAINER = {
7+
position: 'relative',
8+
width: '100%',
9+
height: '100%',
10+
minHeight: '200px',
11+
minWidth: '200px',
12+
margin: '0',
13+
padding: '0',
14+
top: '0',
15+
left: '0',
16+
overflow: 'hidden',
17+
};
18+
19+
function applyStyle(el, style) {
20+
Object.keys(style).forEach((key) => {
21+
el.style[key] = style[key];
22+
});
23+
}
24+
25+
const proxyManager = vtkProxyManager.newInstance({ proxyConfiguration });
26+
window.addEventListener('resize', proxyManager.resizeAllViews);
27+
28+
const createViewer = (rootContainer, { image, use2D, viewerState, config }) => {
29+
userInterface.emptyContainer(rootContainer);
30+
31+
const container = document.createElement('div');
32+
const defaultConfig = {
33+
background: [0, 0, 0],
34+
containerStyle: STYLE_CONTAINER,
35+
};
36+
const renderWindowConfiguration = config || defaultConfig;
37+
userInterface.emptyContainer(container);
38+
applyStyle(
39+
container,
40+
renderWindowConfiguration.containerStyle || STYLE_CONTAINER
41+
);
42+
rootContainer.appendChild(container);
43+
44+
const view = proxyManager.createProxy('Views', 'ItkVtkView');
45+
view.setContainer(container);
46+
view.resize();
47+
48+
const imageSource = proxyManager.createProxy('Sources', 'TrivialProducer');
49+
imageSource.setInputData(image);
50+
imageSource.setName('Image');
51+
52+
proxyManager.createRepresentationInAllViews(imageSource);
53+
54+
proxyManager.renderAllViews();
55+
56+
return { view, imageSource };
57+
};
58+
59+
export default createViewer;

src/index.js

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -46,23 +46,25 @@ export function initializeEmbeddedViewers() {
4646
el.style.height = Number.isFinite(Number(height))
4747
? `${height}px`
4848
: height;
49-
createViewerFromUrl(el, el.dataset.url, !!el.dataset.slice).then((viewer) => {
50-
// Background color handling
51-
if (el.dataset.backgroundColor && viewer.renderWindow) {
52-
const color = el.dataset.backgroundColor;
53-
const bgColor = [
54-
color.slice(0, 2),
55-
color.slice(2, 4),
56-
color.slice(4, 6),
57-
].map((v) => parseInt(v, 16) / 255);
58-
viewer.renderer.setBackground(bgColor);
59-
}
49+
createViewerFromUrl(el, el.dataset.url, !!el.dataset.slice).then(
50+
(viewer) => {
51+
// Background color handling
52+
if (el.dataset.backgroundColor && viewer.renderWindow) {
53+
const color = el.dataset.backgroundColor;
54+
const bgColor = [
55+
color.slice(0, 2),
56+
color.slice(2, 4),
57+
color.slice(4, 6),
58+
].map((v) => parseInt(v, 16) / 255);
59+
viewer.renderer.setBackground(bgColor);
60+
}
6061

61-
// Render
62-
if (viewer.renderWindow && viewer.renderWindow.render) {
63-
viewer.renderWindow.render();
62+
// Render
63+
if (viewer.renderWindow && viewer.renderWindow.render) {
64+
viewer.renderWindow.render();
65+
}
6466
}
65-
});
67+
);
6668
}
6769
}
6870
}
@@ -84,7 +86,11 @@ export function processParameters(
8486
}
8587

8688
if (userParams[keyName]) {
87-
return createViewerFromUrl(myContainer, userParams[keyName], !!userParams.use2D);
89+
return createViewerFromUrl(
90+
myContainer,
91+
userParams[keyName],
92+
!!userParams.use2D
93+
);
8894
}
8995
return null;
9096
}

src/processFiles.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import itkreadImageFile from 'itk/readImageFile';
22
import itkreadImageDICOMFileSeries from 'itk/readImageDICOMFileSeries';
33

4-
import viewers from './viewers';
54
import userInterface from './userInterface';
65
import convertItkImageToVtkImage from './convertItkImageToVtkImage';
6+
import createViewer from './createViewer';
77

88
const processFiles = (container, { files, use2D }) => {
99
userInterface.emptyContainer(container);
@@ -24,9 +24,9 @@ const processFiles = (container, { files, use2D }) => {
2424
const is3D = itkImage.imageType.dimension === 3 && !use2D;
2525

2626
resolve(
27-
viewers.createViewer(container, {
28-
type: is3D ? 'volumeRendering' : 'imageRendering',
27+
createViewer(container, {
2928
image: imageData,
29+
use2D: !is3D,
3030
})
3131
);
3232
});

src/proxyManagerConfiguration.js

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import vtkView from 'vtk.js/Sources/Proxy/Core/ViewProxy';
2+
import vtkProxySource from 'vtk.js/Sources/Proxy/Core/SourceProxy';
3+
import vtkGeometryRepresentationProxy from 'vtk.js/Sources/Proxy/Representations/GeometryRepresentationProxy';
4+
import vtkMoleculeRepresentationProxy from 'vtk.js/Sources/Proxy/Representations/MoleculeRepresentationProxy';
5+
import vtkVolumeRepresentationProxy from 'vtk.js/Sources/Proxy/Representations/VolumeRepresentationProxy';
6+
import vtkSliceRepresentationProxy from 'vtk.js/Sources/Proxy/Representations/SliceRepresentationProxy';
7+
import vtkPiecewiseFunctionProxy from 'vtk.js/Sources/Proxy/Core/PiecewiseFunctionProxy';
8+
import vtkLookupTableProxy from 'vtk.js/Sources/Proxy/Core/LookupTableProxy';
9+
10+
const proxyManagerConfiguration = {
11+
definitions: {
12+
Proxy: {
13+
LookupTable: {
14+
class: vtkLookupTableProxy,
15+
},
16+
PiecewiseFunction: {
17+
class: vtkPiecewiseFunctionProxy,
18+
},
19+
},
20+
Sources: {
21+
TrivialProducer: {
22+
class: vtkProxySource,
23+
options: {},
24+
},
25+
},
26+
Representations: {
27+
Geometry: {
28+
class: vtkGeometryRepresentationProxy,
29+
options: {},
30+
},
31+
Slice: {
32+
class: vtkSliceRepresentationProxy,
33+
options: {},
34+
},
35+
Volume: {
36+
class: vtkVolumeRepresentationProxy,
37+
options: {},
38+
},
39+
Molecule: {
40+
class: vtkMoleculeRepresentationProxy,
41+
options: {},
42+
},
43+
},
44+
Views: {
45+
ItkVtkView: {
46+
class: vtkView,
47+
options: {
48+
axis: 1, // Y
49+
orientation: -1, // Y- (A)
50+
viewUp: [0, 0, 1], // Z+ (S)
51+
useParallelRendering: false,
52+
},
53+
},
54+
},
55+
},
56+
representations: {
57+
ItkVtkView: {
58+
vtkPolyData: { name: 'Geometry' },
59+
vtkImageData: { name: 'Volume' },
60+
vtkMolecule: { name: 'Molecule' },
61+
},
62+
},
63+
};
64+
65+
export default proxyManagerConfiguration;

0 commit comments

Comments
 (0)