Skip to content

Commit 4df655c

Browse files
committed
fix(Cornerstone): Add module to handle cornerstone interoperability
1 parent ff59f7a commit 4df655c

File tree

3 files changed

+127
-0
lines changed

3 files changed

+127
-0
lines changed
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
import macro from 'vtk.js/Sources/macro';
2+
3+
const { vtkErrorMacro } = macro;
4+
5+
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
6+
// TODO:
7+
// - Support image stack
8+
// - Support slice orientation (see stack?)
9+
// - may need some data conversion
10+
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
11+
12+
// ----------------------------------------------------------------------------
13+
// vtkImageDataToCornerstoneImage methods
14+
// ----------------------------------------------------------------------------
15+
16+
function vtkImageDataToCornerstoneImage(publicAPI, model) {
17+
// Set our className
18+
model.classHierarchy.push('vtkImageDataToCornerstoneImage');
19+
20+
publicAPI.requestData = (inData, outData) => {
21+
// implement requestData
22+
const input = inData[0];
23+
24+
if (!input) {
25+
vtkErrorMacro('Invalid or missing input');
26+
return;
27+
}
28+
29+
// Retrieve output and volume data
30+
// const origin = input.getOrigin();
31+
const spacing = input.getSpacing();
32+
const dims = input.getDimensions();
33+
const scalars = input.getPointData().getScalars();
34+
const dataRange = scalars.getRange(0);
35+
const rawData = scalars.getData();
36+
37+
// FIXME probably need to expand to RGBA
38+
let pixelData = null;
39+
if (dims[2] === 1) {
40+
pixelData = scalars.data;
41+
} else {
42+
const offset =
43+
model.sliceIndex * dims[0] * dims[1] * rawData.BYTES_PER_ELEMENT;
44+
pixelData = new macro.TYPED_ARRAYS[(scalars.getDataType())](
45+
rawData.buffer,
46+
offset,
47+
dims[0] * dims[1]
48+
);
49+
}
50+
51+
const cornerstoneImage = {
52+
imageId: model.imageId,
53+
color: scalars.getNumberOfComponents() > 1,
54+
55+
columnPixelSpacing: spacing[1],
56+
columns: dims[1],
57+
width: dims[1],
58+
59+
rowPixelSpacing: spacing[0],
60+
rows: dims[0],
61+
height: dims[0],
62+
63+
intercept: 0,
64+
invert: false,
65+
minPixelValue: dataRange[0],
66+
maxPixelValue: dataRange[1],
67+
68+
sizeInBytes: pixelData.length * pixelData.BYTES_PER_ELEMENT,
69+
slope: 1,
70+
71+
windowCenter: Math.round((dataRange[0] + dataRange[1]) / 2),
72+
windowWidth: dataRange[1] - dataRange[0],
73+
decodeTimeInMS: 0,
74+
75+
getPixelData() {
76+
return pixelData;
77+
},
78+
};
79+
80+
outData[0] = cornerstoneImage;
81+
};
82+
}
83+
84+
// ----------------------------------------------------------------------------
85+
// Object factory
86+
// ----------------------------------------------------------------------------
87+
88+
const DEFAULT_VALUES = {
89+
imageId: 'default-image-id',
90+
sliceIndex: 0,
91+
};
92+
93+
// ----------------------------------------------------------------------------
94+
95+
export function extend(publicAPI, model, initialValues = {}) {
96+
Object.assign(model, DEFAULT_VALUES, initialValues);
97+
98+
// Make this a VTK object
99+
macro.obj(publicAPI, model);
100+
101+
// Also make it an algorithm with one input and one output
102+
macro.algo(publicAPI, model, 1, 1);
103+
104+
macro.setGet(publicAPI, model, ['imageId', 'sliceIndex']);
105+
106+
// Object specific methods
107+
macro.algo(publicAPI, model, 1, 1);
108+
vtkImageDataToCornerstoneImage(publicAPI, model);
109+
}
110+
111+
// ----------------------------------------------------------------------------
112+
113+
export const newInstance = macro.newInstance(
114+
extend,
115+
'vtkImageDataToCornerstoneImage'
116+
);
117+
118+
// ----------------------------------------------------------------------------
119+
120+
export default { newInstance, extend };

Sources/Filters/Cornerstone/index.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import vtkImageDataToCornerstoneImage from './ImageDataToCornerstoneImage';
2+
3+
export default {
4+
vtkImageDataToCornerstoneImage,
5+
};

Sources/Filters/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
import Cornerstone from './Cornerstone';
12
import General from './General';
23
import Sources from './Sources';
34
import Texture from './Texture';
45

56
export default {
7+
Cornerstone,
68
General,
79
Sources,
810
Texture,

0 commit comments

Comments
 (0)