@cornerstonejs/core 4.11.4 → 4.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/RenderingEngine/StackViewport.js +0 -4
- package/dist/esm/RenderingEngine/helpers/createVolumeActor.js +4 -0
- package/dist/esm/RenderingEngine/helpers/createVolumeMapper.js +0 -3
- package/dist/esm/RenderingEngine/vtkClasses/vtkStreamingOpenGLTexture.js +10 -2
- package/dist/esm/RenderingEngine/vtkClasses/vtkStreamingOpenGLVolumeMapper.js +298 -97
- package/dist/esm/version.d.ts +1 -1
- package/dist/esm/version.js +1 -1
- package/package.json +3 -3
|
@@ -111,10 +111,6 @@ class StackViewport extends Viewport {
|
|
|
111
111
|
mapper.setInputData(imageData);
|
|
112
112
|
const actor = vtkImageSlice.newInstance();
|
|
113
113
|
actor.setMapper(mapper);
|
|
114
|
-
const { preferSizeOverAccuracy } = getConfiguration().rendering;
|
|
115
|
-
if (preferSizeOverAccuracy) {
|
|
116
|
-
mapper.setPreferSizeOverAccuracy(true);
|
|
117
|
-
}
|
|
118
114
|
if (imageData.getPointData().getScalars().getNumberOfComponents() > 1) {
|
|
119
115
|
actor.getProperty().setIndependentComponents(false);
|
|
120
116
|
}
|
|
@@ -4,6 +4,7 @@ import createVolumeMapper from './createVolumeMapper';
|
|
|
4
4
|
import triggerEvent from '../../utilities/triggerEvent';
|
|
5
5
|
import { Events } from '../../enums';
|
|
6
6
|
import setDefaultVolumeVOI from './setDefaultVolumeVOI';
|
|
7
|
+
import { getConfiguration } from '../../init';
|
|
7
8
|
async function createVolumeActor(props, element, viewportId, suppressEvents = false) {
|
|
8
9
|
const { volumeId, callback, blendMode } = props;
|
|
9
10
|
const imageVolume = await loadVolume(volumeId);
|
|
@@ -20,6 +21,9 @@ async function createVolumeActor(props, element, viewportId, suppressEvents = fa
|
|
|
20
21
|
const { numberOfComponents } = imageData.get('numberOfComponents');
|
|
21
22
|
const volumeProperty = volumeActor.getProperty();
|
|
22
23
|
volumeProperty.set({ viewportId: viewportId }, true);
|
|
24
|
+
if (getConfiguration().rendering.preferSizeOverAccuracy) {
|
|
25
|
+
volumeProperty.setPreferSizeOverAccuracy(true);
|
|
26
|
+
}
|
|
23
27
|
if (numberOfComponents === 3) {
|
|
24
28
|
volumeActor.getProperty().setIndependentComponents(false);
|
|
25
29
|
}
|
|
@@ -4,9 +4,6 @@ import vtkVolumeMapper from '@kitware/vtk.js/Rendering/Core/VolumeMapper';
|
|
|
4
4
|
import vtkDataArray from '@kitware/vtk.js/Common/Core/DataArray';
|
|
5
5
|
export default function createVolumeMapper(imageData, vtkOpenGLTexture) {
|
|
6
6
|
const volumeMapper = vtkSharedVolumeMapper.newInstance();
|
|
7
|
-
if (getConfiguration().rendering.preferSizeOverAccuracy) {
|
|
8
|
-
volumeMapper.setPreferSizeOverAccuracy(true);
|
|
9
|
-
}
|
|
10
7
|
volumeMapper.setInputData(imageData);
|
|
11
8
|
const spacing = imageData.getSpacing();
|
|
12
9
|
const sampleDistanceMultiplier = getConfiguration().rendering?.volumeRendering?.sampleDistanceMultiplier ||
|
|
@@ -13,10 +13,18 @@ function vtkStreamingOpenGLTexture(publicAPI, model) {
|
|
|
13
13
|
model.updatedFrames = [];
|
|
14
14
|
model.volumeId = null;
|
|
15
15
|
const superCreate3DFilterableFromRaw = publicAPI.create3DFilterableFromRaw;
|
|
16
|
-
publicAPI.create3DFilterableFromRaw = (width, height, depth, numberOfComponents, dataType, data, preferSizeOverAccuracy) => {
|
|
16
|
+
publicAPI.create3DFilterableFromRaw = ({ width, height, depth, numberOfComponents, dataType, data, preferSizeOverAccuracy, }) => {
|
|
17
17
|
model.inputDataType = dataType;
|
|
18
18
|
model.inputNumComps = numberOfComponents;
|
|
19
|
-
superCreate3DFilterableFromRaw(
|
|
19
|
+
superCreate3DFilterableFromRaw({
|
|
20
|
+
width,
|
|
21
|
+
height,
|
|
22
|
+
depth,
|
|
23
|
+
numberOfComponents,
|
|
24
|
+
dataType,
|
|
25
|
+
data,
|
|
26
|
+
preferSizeOverAccuracy,
|
|
27
|
+
});
|
|
20
28
|
};
|
|
21
29
|
const superUpdate = publicAPI.updateVolumeInfoForGL;
|
|
22
30
|
publicAPI.updateVolumeInfoForGL = (dataType, numComps) => {
|
|
@@ -1,47 +1,143 @@
|
|
|
1
1
|
import macro from '@kitware/vtk.js/macros';
|
|
2
|
+
import vtkDataArray from '@kitware/vtk.js/Common/Core/DataArray';
|
|
3
|
+
import { VtkDataTypes } from '@kitware/vtk.js/Common/Core/DataArray/Constants';
|
|
2
4
|
import vtkOpenGLVolumeMapper from '@kitware/vtk.js/Rendering/OpenGL/VolumeMapper';
|
|
5
|
+
import vtkOpenGLTexture from '@kitware/vtk.js/Rendering/OpenGL/Texture';
|
|
3
6
|
import { Filter } from '@kitware/vtk.js/Rendering/OpenGL/Texture/Constants';
|
|
4
|
-
import {
|
|
5
|
-
import { getTransferFunctionHash } from '@kitware/vtk.js/Rendering/OpenGL/RenderWindow/resourceSharingHelper';
|
|
6
|
-
import vtkDataArray from '@kitware/vtk.js/Common/Core/DataArray';
|
|
7
|
+
import { getTransferFunctionsHash } from '@kitware/vtk.js/Rendering/OpenGL/RenderWindow/resourceSharingHelper';
|
|
7
8
|
import { Representation } from '@kitware/vtk.js/Rendering/Core/Property/Constants';
|
|
8
|
-
import
|
|
9
|
-
import { getConstructorFromType } from '../../utilities/getBufferConfiguration';
|
|
9
|
+
import { BlendMode } from '@kitware/vtk.js/Rendering/Core/VolumeMapper/Constants';
|
|
10
10
|
import { getCanUseNorm16Texture } from '../../init';
|
|
11
11
|
function vtkStreamingOpenGLVolumeMapper(publicAPI, model) {
|
|
12
12
|
model.classHierarchy.push('vtkStreamingOpenGLVolumeMapper');
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
if (!
|
|
13
|
+
const graphicsResourceReferenceCount = new Map();
|
|
14
|
+
function decreaseGraphicsResourceCount(openGLRenderWindow, coreObject) {
|
|
15
|
+
if (!coreObject) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
const oldCount = graphicsResourceReferenceCount.get(coreObject) ?? 0;
|
|
19
|
+
const newCount = oldCount - 1;
|
|
20
|
+
if (newCount <= 0) {
|
|
21
|
+
openGLRenderWindow.unregisterGraphicsResourceUser(coreObject, publicAPI);
|
|
22
|
+
graphicsResourceReferenceCount.delete(coreObject);
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
graphicsResourceReferenceCount.set(coreObject, newCount);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function increaseGraphicsResourceCount(openGLRenderWindow, coreObject) {
|
|
29
|
+
if (!coreObject) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
const oldCount = graphicsResourceReferenceCount.get(coreObject) ?? 0;
|
|
33
|
+
const newCount = oldCount + 1;
|
|
34
|
+
graphicsResourceReferenceCount.set(coreObject, newCount);
|
|
35
|
+
if (oldCount <= 0) {
|
|
36
|
+
openGLRenderWindow.registerGraphicsResourceUser(coreObject, publicAPI);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
function replaceGraphicsResource(openGLRenderWindow, oldResourceCoreObject, newResourceCoreObject) {
|
|
40
|
+
if (oldResourceCoreObject === newResourceCoreObject) {
|
|
16
41
|
return;
|
|
17
42
|
}
|
|
18
|
-
|
|
43
|
+
decreaseGraphicsResourceCount(openGLRenderWindow, oldResourceCoreObject);
|
|
44
|
+
increaseGraphicsResourceCount(openGLRenderWindow, newResourceCoreObject);
|
|
45
|
+
}
|
|
46
|
+
publicAPI.renderPiece = (ren, actor) => {
|
|
47
|
+
publicAPI.invokeEvent({ type: 'StartEvent' });
|
|
48
|
+
model.renderable.update();
|
|
49
|
+
const numberOfInputs = model.renderable.getNumberOfInputPorts();
|
|
50
|
+
model.currentValidInputs = [];
|
|
51
|
+
for (let inputIndex = 0; inputIndex < numberOfInputs; ++inputIndex) {
|
|
52
|
+
const imageData = model.renderable.getInputData(inputIndex);
|
|
53
|
+
if (imageData && !imageData.isDeleted()) {
|
|
54
|
+
model.currentValidInputs.push({ imageData, inputIndex });
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
let newNumberOfLights = 0;
|
|
58
|
+
if (model.currentValidInputs.length > 0) {
|
|
59
|
+
const volumeProperties = actor.getProperties();
|
|
60
|
+
const firstValidInput = model.currentValidInputs[0];
|
|
61
|
+
const firstImageData = firstValidInput.imageData;
|
|
62
|
+
const firstVolumeProperty = volumeProperties[firstValidInput.inputIndex];
|
|
63
|
+
if (firstVolumeProperty.getShade() &&
|
|
64
|
+
model.renderable.getBlendMode() === BlendMode.COMPOSITE_BLEND) {
|
|
65
|
+
ren.getLights().forEach((light) => {
|
|
66
|
+
if (light.getSwitch() > 0) {
|
|
67
|
+
newNumberOfLights++;
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
const numberOfValidInputs = model.currentValidInputs.length;
|
|
72
|
+
const multiTexturePerVolumeEnabled = numberOfValidInputs > 1;
|
|
73
|
+
const { numberOfComponents } = firstImageData.get('numberOfComponents');
|
|
74
|
+
model.numberOfComponents = multiTexturePerVolumeEnabled
|
|
75
|
+
? numberOfValidInputs
|
|
76
|
+
: numberOfComponents;
|
|
77
|
+
if (model.numberOfComponents > 1) {
|
|
78
|
+
model.useIndependentComponents =
|
|
79
|
+
firstVolumeProperty.getIndependentComponents();
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
model.useIndependentComponents = false;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
if (newNumberOfLights !== model.numberOfLights) {
|
|
86
|
+
model.numberOfLights = newNumberOfLights;
|
|
87
|
+
publicAPI.modified();
|
|
88
|
+
}
|
|
89
|
+
publicAPI.invokeEvent({ type: 'EndEvent' });
|
|
90
|
+
if (model.currentValidInputs.length === 0) {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
publicAPI.renderPieceStart(ren, actor);
|
|
94
|
+
publicAPI.renderPieceDraw(ren, actor);
|
|
95
|
+
publicAPI.renderPieceFinish(ren, actor);
|
|
96
|
+
};
|
|
97
|
+
publicAPI.buildBufferObjects = (ren, actor) => {
|
|
19
98
|
if (!model.jitterTexture.getHandle()) {
|
|
20
|
-
const
|
|
99
|
+
const jitterArray = new Float32Array(32 * 32);
|
|
21
100
|
for (let i = 0; i < 32 * 32; ++i) {
|
|
22
|
-
|
|
23
|
-
}
|
|
24
|
-
model.jitterTexture.setMinificationFilter(Filter.
|
|
25
|
-
model.jitterTexture.setMagnificationFilter(Filter.
|
|
26
|
-
model.jitterTexture.create2DFromRaw(
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
101
|
+
jitterArray[i] = Math.random();
|
|
102
|
+
}
|
|
103
|
+
model.jitterTexture.setMinificationFilter(Filter.NEAREST);
|
|
104
|
+
model.jitterTexture.setMagnificationFilter(Filter.NEAREST);
|
|
105
|
+
model.jitterTexture.create2DFromRaw({
|
|
106
|
+
width: 32,
|
|
107
|
+
height: 32,
|
|
108
|
+
numComps: 1,
|
|
109
|
+
dataType: VtkDataTypes.FLOAT,
|
|
110
|
+
data: jitterArray,
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
const volumeProperties = actor.getProperties();
|
|
114
|
+
const firstValidInput = model.currentValidInputs[0];
|
|
115
|
+
const firstVolumeProperty = volumeProperties[firstValidInput.inputIndex];
|
|
116
|
+
const numberOfComponents = model.numberOfComponents;
|
|
117
|
+
const useIndependentComps = model.useIndependentComponents;
|
|
118
|
+
const numIComps = useIndependentComps ? numberOfComponents : 1;
|
|
119
|
+
const opacityFunctions = [];
|
|
120
|
+
for (let component = 0; component < numIComps; ++component) {
|
|
121
|
+
opacityFunctions.push(firstVolumeProperty.getScalarOpacity(component));
|
|
122
|
+
}
|
|
123
|
+
const opacityFuncHash = getTransferFunctionsHash(opacityFunctions, useIndependentComps, numIComps);
|
|
124
|
+
const firstScalarOpacityFunc = firstVolumeProperty.getScalarOpacity();
|
|
125
|
+
const opTex = model._openGLRenderWindow.getGraphicsResourceForObject(firstScalarOpacityFunc);
|
|
126
|
+
const reBuildOp = !opTex?.oglObject?.getHandle() || opTex.hash !== opacityFuncHash;
|
|
34
127
|
if (reBuildOp) {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
128
|
+
const newOpacityTexture = vtkOpenGLTexture.newInstance();
|
|
129
|
+
newOpacityTexture.setOpenGLRenderWindow(model._openGLRenderWindow);
|
|
130
|
+
let oWidth = model.renderable.getOpacityTextureWidth();
|
|
131
|
+
if (oWidth <= 0) {
|
|
132
|
+
oWidth = model.context.getParameter(model.context.MAX_TEXTURE_SIZE);
|
|
133
|
+
}
|
|
38
134
|
const oSize = oWidth * 2 * numIComps;
|
|
39
135
|
const ofTable = new Float32Array(oSize);
|
|
40
136
|
const tmpTable = new Float32Array(oWidth);
|
|
41
137
|
for (let c = 0; c < numIComps; ++c) {
|
|
42
|
-
const ofun =
|
|
138
|
+
const ofun = firstVolumeProperty.getScalarOpacity(c);
|
|
43
139
|
const opacityFactor = publicAPI.getCurrentSampleDistance(ren) /
|
|
44
|
-
|
|
140
|
+
firstVolumeProperty.getScalarOpacityUnitDistance(c);
|
|
45
141
|
const oRange = ofun.getRange();
|
|
46
142
|
ofun.getTable(oRange[0], oRange[1], oWidth, tmpTable, 1);
|
|
47
143
|
for (let i = 0; i < oWidth; ++i) {
|
|
@@ -50,46 +146,63 @@ function vtkStreamingOpenGLVolumeMapper(publicAPI, model) {
|
|
|
50
146
|
ofTable[c * oWidth * 2 + i + oWidth] = ofTable[c * oWidth * 2 + i];
|
|
51
147
|
}
|
|
52
148
|
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
if (model._openGLRenderWindow.getWebgl2()
|
|
57
|
-
model.context.getExtension('OES_texture_float') &&
|
|
58
|
-
|
|
59
|
-
|
|
149
|
+
newOpacityTexture.resetFormatAndType();
|
|
150
|
+
newOpacityTexture.setMinificationFilter(Filter.LINEAR);
|
|
151
|
+
newOpacityTexture.setMagnificationFilter(Filter.LINEAR);
|
|
152
|
+
if (model._openGLRenderWindow.getWebgl2() ||
|
|
153
|
+
(model.context.getExtension('OES_texture_float') &&
|
|
154
|
+
model.context.getExtension('OES_texture_float_linear'))) {
|
|
155
|
+
newOpacityTexture.create2DFromRaw({
|
|
156
|
+
width: oWidth,
|
|
157
|
+
height: 2 * numIComps,
|
|
158
|
+
numComps: 1,
|
|
159
|
+
dataType: VtkDataTypes.FLOAT,
|
|
160
|
+
data: ofTable,
|
|
161
|
+
});
|
|
60
162
|
}
|
|
61
163
|
else {
|
|
62
164
|
const oTable = new Uint8ClampedArray(oSize);
|
|
63
165
|
for (let i = 0; i < oSize; ++i) {
|
|
64
166
|
oTable[i] = 255.0 * ofTable[i];
|
|
65
167
|
}
|
|
66
|
-
|
|
168
|
+
newOpacityTexture.create2DFromRaw({
|
|
169
|
+
width: oWidth,
|
|
170
|
+
height: 2 * numIComps,
|
|
171
|
+
numComps: 1,
|
|
172
|
+
dataType: VtkDataTypes.UNSIGNED_CHAR,
|
|
173
|
+
data: oTable,
|
|
174
|
+
});
|
|
67
175
|
}
|
|
68
|
-
if (
|
|
69
|
-
model._openGLRenderWindow.setGraphicsResourceForObject(
|
|
70
|
-
if (scalarOpacityFunc !== model._scalarOpacityFunc) {
|
|
71
|
-
model._openGLRenderWindow.registerGraphicsResourceUser(scalarOpacityFunc, publicAPI);
|
|
72
|
-
model._openGLRenderWindow.unregisterGraphicsResourceUser(model._scalarOpacityFunc, publicAPI);
|
|
73
|
-
}
|
|
74
|
-
model._scalarOpacityFunc = scalarOpacityFunc;
|
|
176
|
+
if (firstScalarOpacityFunc) {
|
|
177
|
+
model._openGLRenderWindow.setGraphicsResourceForObject(firstScalarOpacityFunc, newOpacityTexture, opacityFuncHash);
|
|
75
178
|
}
|
|
179
|
+
model.opacityTexture = newOpacityTexture;
|
|
76
180
|
}
|
|
77
181
|
else {
|
|
78
182
|
model.opacityTexture = opTex.oglObject;
|
|
79
183
|
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
const
|
|
83
|
-
|
|
184
|
+
replaceGraphicsResource(model._openGLRenderWindow, model._opacityTextureCore, firstScalarOpacityFunc);
|
|
185
|
+
model._opacityTextureCore = firstScalarOpacityFunc;
|
|
186
|
+
const colorTransferFunctions = [];
|
|
187
|
+
for (let component = 0; component < numIComps; ++component) {
|
|
188
|
+
colorTransferFunctions.push(firstVolumeProperty.getRGBTransferFunction(component));
|
|
189
|
+
}
|
|
190
|
+
const colorFuncHash = getTransferFunctionsHash(colorTransferFunctions, useIndependentComps, numIComps);
|
|
191
|
+
const firstColorTransferFunc = firstVolumeProperty.getRGBTransferFunction();
|
|
192
|
+
const cTex = model._openGLRenderWindow.getGraphicsResourceForObject(firstColorTransferFunc);
|
|
193
|
+
const reBuildC = !cTex?.oglObject?.getHandle() || cTex?.hash !== colorFuncHash;
|
|
84
194
|
if (reBuildC) {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
195
|
+
const newColorTexture = vtkOpenGLTexture.newInstance();
|
|
196
|
+
newColorTexture.setOpenGLRenderWindow(model._openGLRenderWindow);
|
|
197
|
+
let cWidth = model.renderable.getColorTextureWidth();
|
|
198
|
+
if (cWidth <= 0) {
|
|
199
|
+
cWidth = model.context.getParameter(model.context.MAX_TEXTURE_SIZE);
|
|
200
|
+
}
|
|
88
201
|
const cSize = cWidth * 2 * numIComps * 3;
|
|
89
202
|
const cTable = new Uint8ClampedArray(cSize);
|
|
90
203
|
const tmpTable = new Float32Array(cWidth * 3);
|
|
91
204
|
for (let c = 0; c < numIComps; ++c) {
|
|
92
|
-
const cfun =
|
|
205
|
+
const cfun = firstVolumeProperty.getRGBTransferFunction(c);
|
|
93
206
|
const cRange = cfun.getRange();
|
|
94
207
|
cfun.getTable(cRange[0], cRange[1], cWidth, tmpTable, 1);
|
|
95
208
|
for (let i = 0; i < cWidth * 3; ++i) {
|
|
@@ -97,60 +210,124 @@ function vtkStreamingOpenGLVolumeMapper(publicAPI, model) {
|
|
|
97
210
|
cTable[c * cWidth * 6 + i + cWidth * 3] = 255.0 * tmpTable[i];
|
|
98
211
|
}
|
|
99
212
|
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
213
|
+
newColorTexture.resetFormatAndType();
|
|
214
|
+
newColorTexture.setMinificationFilter(Filter.LINEAR);
|
|
215
|
+
newColorTexture.setMagnificationFilter(Filter.LINEAR);
|
|
216
|
+
newColorTexture.create2DFromRaw({
|
|
217
|
+
width: cWidth,
|
|
218
|
+
height: 2 * numIComps,
|
|
219
|
+
numComps: 3,
|
|
220
|
+
dataType: VtkDataTypes.UNSIGNED_CHAR,
|
|
221
|
+
data: cTable,
|
|
222
|
+
});
|
|
223
|
+
model._openGLRenderWindow.setGraphicsResourceForObject(firstColorTransferFunc, newColorTexture, colorFuncHash);
|
|
224
|
+
model.colorTexture = newColorTexture;
|
|
112
225
|
}
|
|
113
226
|
else {
|
|
114
227
|
model.colorTexture = cTex.oglObject;
|
|
115
228
|
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
229
|
+
replaceGraphicsResource(model._openGLRenderWindow, model._colorTextureCore, firstColorTransferFunc);
|
|
230
|
+
model._colorTextureCore = firstColorTransferFunc;
|
|
231
|
+
model.currentValidInputs.forEach(({ imageData, inputIndex: _inputIndex }, component) => {
|
|
232
|
+
if (!model.scalarTextures) {
|
|
233
|
+
model.scalarTextures = [];
|
|
234
|
+
}
|
|
235
|
+
if (!model.scalarTextures[component]) {
|
|
236
|
+
console.warn(`ScalarTexture for component ${component} not initialized, skipping.`);
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
const currentTexture = model.scalarTextures[component];
|
|
240
|
+
const toString = `${imageData.getMTime()}-${currentTexture.getMTime()}`;
|
|
241
|
+
if (!model.scalarTextureStrings) {
|
|
242
|
+
model.scalarTextureStrings = [];
|
|
243
|
+
}
|
|
244
|
+
if (model.scalarTextureStrings[component] !== toString) {
|
|
245
|
+
const dims = imageData.getDimensions();
|
|
246
|
+
currentTexture.setOpenGLRenderWindow(model._openGLRenderWindow);
|
|
247
|
+
currentTexture.enableUseHalfFloat(false);
|
|
248
|
+
const previousTextureParameters = currentTexture.getTextureParameters();
|
|
249
|
+
const dataType = imageData.get('dataType').dataType;
|
|
250
|
+
let shouldReset = true;
|
|
251
|
+
if (previousTextureParameters?.dataType === dataType) {
|
|
252
|
+
if (previousTextureParameters?.width === dims[0]) {
|
|
253
|
+
if (previousTextureParameters?.height === dims[1]) {
|
|
254
|
+
if (previousTextureParameters?.depth === dims[2]) {
|
|
255
|
+
shouldReset = false;
|
|
256
|
+
}
|
|
130
257
|
}
|
|
131
258
|
}
|
|
132
259
|
}
|
|
260
|
+
if (shouldReset) {
|
|
261
|
+
const norm16Ext = model.context.getExtension('EXT_texture_norm16');
|
|
262
|
+
currentTexture.setOglNorm16Ext(getCanUseNorm16Texture() ? norm16Ext : null);
|
|
263
|
+
currentTexture.resetFormatAndType();
|
|
264
|
+
currentTexture.setTextureParameters({
|
|
265
|
+
width: dims[0],
|
|
266
|
+
height: dims[1],
|
|
267
|
+
depth: dims[2],
|
|
268
|
+
numberOfComponents: numIComps,
|
|
269
|
+
dataType,
|
|
270
|
+
});
|
|
271
|
+
currentTexture.create3DFromRaw({
|
|
272
|
+
width: dims[0],
|
|
273
|
+
height: dims[1],
|
|
274
|
+
depth: dims[2],
|
|
275
|
+
numComps: numIComps,
|
|
276
|
+
dataType,
|
|
277
|
+
data: null,
|
|
278
|
+
});
|
|
279
|
+
currentTexture.update3DFromRaw();
|
|
280
|
+
}
|
|
281
|
+
else {
|
|
282
|
+
currentTexture.deactivate();
|
|
283
|
+
currentTexture.update3DFromRaw();
|
|
284
|
+
}
|
|
285
|
+
model.scalarTextureStrings[component] = toString;
|
|
133
286
|
}
|
|
134
|
-
if (
|
|
135
|
-
|
|
136
|
-
model.scalarTexture.setOglNorm16Ext(getCanUseNorm16Texture() ? norm16Ext : null);
|
|
137
|
-
model.scalarTexture.resetFormatAndType();
|
|
138
|
-
model.scalarTexture.setTextureParameters({
|
|
139
|
-
width: dims[0],
|
|
140
|
-
height: dims[1],
|
|
141
|
-
depth: dims[2],
|
|
142
|
-
numberOfComponents: numIComps,
|
|
143
|
-
dataType,
|
|
144
|
-
});
|
|
145
|
-
model.scalarTexture.create3DFromRaw(dims[0], dims[1], dims[2], numIComps, dataType, null);
|
|
146
|
-
model.scalarTexture.update3DFromRaw();
|
|
287
|
+
if (!model._scalarTexturesCore) {
|
|
288
|
+
model._scalarTexturesCore = [];
|
|
147
289
|
}
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
290
|
+
});
|
|
291
|
+
const labelOutlineThicknessArray = firstVolumeProperty.getLabelOutlineThickness();
|
|
292
|
+
const lTex = model._openGLRenderWindow.getGraphicsResourceForObject(labelOutlineThicknessArray);
|
|
293
|
+
const labelOutlineThicknessHash = labelOutlineThicknessArray.join('-');
|
|
294
|
+
const reBuildL = !lTex?.oglObject?.getHandle() || lTex?.hash !== labelOutlineThicknessHash;
|
|
295
|
+
if (reBuildL) {
|
|
296
|
+
const newLabelOutlineThicknessTexture = vtkOpenGLTexture.newInstance();
|
|
297
|
+
newLabelOutlineThicknessTexture.setOpenGLRenderWindow(model._openGLRenderWindow);
|
|
298
|
+
let lWidth = model.renderable.getLabelOutlineTextureWidth();
|
|
299
|
+
if (lWidth <= 0) {
|
|
300
|
+
lWidth = model.context.getParameter(model.context.MAX_TEXTURE_SIZE);
|
|
151
301
|
}
|
|
152
|
-
|
|
302
|
+
const lHeight = 1;
|
|
303
|
+
const lSize = lWidth * lHeight;
|
|
304
|
+
const lTable = new Uint8Array(lSize);
|
|
305
|
+
for (let i = 0; i < lWidth; ++i) {
|
|
306
|
+
const thickness = typeof labelOutlineThicknessArray[i] !== 'undefined'
|
|
307
|
+
? labelOutlineThicknessArray[i]
|
|
308
|
+
: labelOutlineThicknessArray[0];
|
|
309
|
+
lTable[i] = thickness;
|
|
310
|
+
}
|
|
311
|
+
newLabelOutlineThicknessTexture.resetFormatAndType();
|
|
312
|
+
newLabelOutlineThicknessTexture.setMinificationFilter(Filter.NEAREST);
|
|
313
|
+
newLabelOutlineThicknessTexture.setMagnificationFilter(Filter.NEAREST);
|
|
314
|
+
newLabelOutlineThicknessTexture.create2DFromRaw({
|
|
315
|
+
width: lWidth,
|
|
316
|
+
height: lHeight,
|
|
317
|
+
numComps: 1,
|
|
318
|
+
dataType: VtkDataTypes.UNSIGNED_CHAR,
|
|
319
|
+
data: lTable,
|
|
320
|
+
});
|
|
321
|
+
if (labelOutlineThicknessArray) {
|
|
322
|
+
model._openGLRenderWindow.setGraphicsResourceForObject(labelOutlineThicknessArray, newLabelOutlineThicknessTexture, labelOutlineThicknessHash);
|
|
323
|
+
}
|
|
324
|
+
model.labelOutlineThicknessTexture = newLabelOutlineThicknessTexture;
|
|
153
325
|
}
|
|
326
|
+
else {
|
|
327
|
+
model.labelOutlineThicknessTexture = lTex.oglObject;
|
|
328
|
+
}
|
|
329
|
+
replaceGraphicsResource(model._openGLRenderWindow, model._labelOutlineThicknessTextureCore, labelOutlineThicknessArray);
|
|
330
|
+
model._labelOutlineThicknessTextureCore = labelOutlineThicknessArray;
|
|
154
331
|
if (!model.tris.getCABO().getElementCount()) {
|
|
155
332
|
const ptsArray = new Float32Array(12);
|
|
156
333
|
for (let i = 0; i < 4; i++) {
|
|
@@ -188,16 +365,33 @@ function vtkStreamingOpenGLVolumeMapper(publicAPI, model) {
|
|
|
188
365
|
model.VBOBuildTime.getMTime() < actor.getMTime() ||
|
|
189
366
|
model.VBOBuildTime.getMTime() < model.renderable.getMTime() ||
|
|
190
367
|
model.VBOBuildTime.getMTime() < actor.getProperty().getMTime() ||
|
|
191
|
-
model.VBOBuildTime.getMTime() < model.currentInput.getMTime() ||
|
|
192
|
-
model.VBOBuildTime.getMTime() < model.scalarTexture?.getMTime() ||
|
|
193
368
|
model.VBOBuildTime.getMTime() < model.colorTexture?.getMTime() ||
|
|
194
369
|
model.VBOBuildTime.getMTime() <
|
|
195
370
|
model.labelOutlineThicknessTexture?.getMTime() ||
|
|
196
|
-
!model.scalarTexture?.getHandle() ||
|
|
197
371
|
!model.colorTexture?.getHandle() ||
|
|
198
372
|
!model.labelOutlineThicknessTexture?.getHandle()) {
|
|
199
373
|
return true;
|
|
200
374
|
}
|
|
375
|
+
if (model.scalarTextures && model.scalarTextures.length > 0) {
|
|
376
|
+
for (let i = 0; i < model.scalarTextures.length; i++) {
|
|
377
|
+
const texture = model.scalarTextures[i];
|
|
378
|
+
if (texture &&
|
|
379
|
+
(model.VBOBuildTime.getMTime() < texture.getMTime() ||
|
|
380
|
+
!texture.getHandle())) {
|
|
381
|
+
return true;
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
if (model.currentValidInputs && model.currentValidInputs.length > 0) {
|
|
386
|
+
for (let i = 0; i < model.currentValidInputs.length; i++) {
|
|
387
|
+
const input = model.currentValidInputs[i];
|
|
388
|
+
if (input &&
|
|
389
|
+
input.imageData &&
|
|
390
|
+
model.VBOBuildTime.getMTime() < input.imageData.getMTime()) {
|
|
391
|
+
return true;
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
}
|
|
201
395
|
return false;
|
|
202
396
|
};
|
|
203
397
|
}
|
|
@@ -205,7 +399,14 @@ const DEFAULT_VALUES = {};
|
|
|
205
399
|
export function extend(publicAPI, model, initialValues = {}) {
|
|
206
400
|
Object.assign(model, DEFAULT_VALUES, initialValues);
|
|
207
401
|
vtkOpenGLVolumeMapper.extend(publicAPI, model, initialValues);
|
|
208
|
-
|
|
402
|
+
if (initialValues.scalarTexture) {
|
|
403
|
+
model.scalarTextures = [initialValues.scalarTexture];
|
|
404
|
+
}
|
|
405
|
+
else {
|
|
406
|
+
model.scalarTextures = [];
|
|
407
|
+
}
|
|
408
|
+
model.scalarTextureStrings = [];
|
|
409
|
+
model._scalarTexturesCore = [];
|
|
209
410
|
model.previousState = {};
|
|
210
411
|
vtkStreamingOpenGLVolumeMapper(publicAPI, model);
|
|
211
412
|
}
|
package/dist/esm/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const version = "4.
|
|
1
|
+
export declare const version = "4.12.0";
|
package/dist/esm/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '4.
|
|
1
|
+
export const version = '4.12.0';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cornerstonejs/core",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.12.0",
|
|
4
4
|
"description": "Cornerstone3D Core",
|
|
5
5
|
"module": "./dist/esm/index.js",
|
|
6
6
|
"types": "./dist/esm/index.d.ts",
|
|
@@ -81,7 +81,7 @@
|
|
|
81
81
|
"prepublishOnly": "yarn run build"
|
|
82
82
|
},
|
|
83
83
|
"dependencies": {
|
|
84
|
-
"@kitware/vtk.js": "
|
|
84
|
+
"@kitware/vtk.js": "34.15.1",
|
|
85
85
|
"comlink": "4.4.2",
|
|
86
86
|
"gl-matrix": "3.4.3",
|
|
87
87
|
"loglevel": "1.9.2"
|
|
@@ -97,5 +97,5 @@
|
|
|
97
97
|
"type": "individual",
|
|
98
98
|
"url": "https://ohif.org/donate"
|
|
99
99
|
},
|
|
100
|
-
"gitHead": "
|
|
100
|
+
"gitHead": "15c5cd644cfe703ce053c006ac911d3b4965ab97"
|
|
101
101
|
}
|