@cornerstonejs/core 4.11.5 → 4.12.1

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.
@@ -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(width, height, depth, numberOfComponents, dataType, data, preferSizeOverAccuracy);
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 { VtkDataTypes } from '@kitware/vtk.js/Common/Core/DataArray/Constants';
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 vtkOpenGLTexture from '@kitware/vtk.js/Rendering/OpenGL/Texture';
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
- publicAPI.buildBufferObjects = (ren, actor) => {
14
- const image = model.currentInput;
15
- if (!image) {
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
- const vprop = actor.getProperty();
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 oTable = new Uint8Array(32 * 32);
99
+ const jitterArray = new Float32Array(32 * 32);
21
100
  for (let i = 0; i < 32 * 32; ++i) {
22
- oTable[i] = 255.0 * Math.random();
23
- }
24
- model.jitterTexture.setMinificationFilter(Filter.LINEAR);
25
- model.jitterTexture.setMagnificationFilter(Filter.LINEAR);
26
- model.jitterTexture.create2DFromRaw(32, 32, 1, VtkDataTypes.UNSIGNED_CHAR, oTable);
27
- }
28
- const { numberOfComponents: numIComps } = image.get('numberOfComponents');
29
- const useIndependentComps = publicAPI.useIndependentComponents(vprop);
30
- const scalarOpacityFunc = vprop.getScalarOpacity();
31
- const opTex = model._openGLRenderWindow.getGraphicsResourceForObject(scalarOpacityFunc);
32
- let toString = getTransferFunctionHash(scalarOpacityFunc, useIndependentComps, numIComps);
33
- const reBuildOp = !opTex?.oglObject || opTex.hash !== toString;
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
- model.opacityTexture = vtkOpenGLTexture.newInstance();
36
- model.opacityTexture.setOpenGLRenderWindow(model._openGLRenderWindow);
37
- const oWidth = 1024;
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 = vprop.getScalarOpacity(c);
138
+ const ofun = firstVolumeProperty.getScalarOpacity(c);
43
139
  const opacityFactor = publicAPI.getCurrentSampleDistance(ren) /
44
- vprop.getScalarOpacityUnitDistance(c);
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
- model.opacityTexture.resetFormatAndType();
54
- model.opacityTexture.setMinificationFilter(Filter.LINEAR);
55
- model.opacityTexture.setMagnificationFilter(Filter.LINEAR);
56
- if (model._openGLRenderWindow.getWebgl2() &&
57
- model.context.getExtension('OES_texture_float') &&
58
- model.context.getExtension('OES_texture_float_linear')) {
59
- model.opacityTexture.create2DFromRaw(oWidth, 2 * numIComps, 1, VtkDataTypes.FLOAT, ofTable);
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
- model.opacityTexture.create2DFromRaw(oWidth, 2 * numIComps, 1, VtkDataTypes.UNSIGNED_CHAR, oTable);
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 (scalarOpacityFunc) {
69
- model._openGLRenderWindow.setGraphicsResourceForObject(scalarOpacityFunc, model.opacityTexture, toString);
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
- const colorTransferFunc = vprop.getRGBTransferFunction();
81
- toString = getTransferFunctionHash(colorTransferFunc, useIndependentComps, numIComps);
82
- const cTex = model._openGLRenderWindow.getGraphicsResourceForObject(colorTransferFunc);
83
- const reBuildC = !cTex?.oglObject?.getHandle() || cTex?.hash !== toString;
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
- model.colorTexture = vtkOpenGLTexture.newInstance();
86
- model.colorTexture.setOpenGLRenderWindow(model._openGLRenderWindow);
87
- const cWidth = 1024;
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 = vprop.getRGBTransferFunction(c);
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
- model.colorTexture.resetFormatAndType();
101
- model.colorTexture.setMinificationFilter(Filter.LINEAR);
102
- model.colorTexture.setMagnificationFilter(Filter.LINEAR);
103
- model.colorTexture.create2DFromRaw(cWidth, 2 * numIComps, 3, VtkDataTypes.UNSIGNED_CHAR, cTable);
104
- if (colorTransferFunc) {
105
- model._openGLRenderWindow.setGraphicsResourceForObject(colorTransferFunc, model.colorTexture, toString);
106
- if (colorTransferFunc !== model._colorTransferFunc) {
107
- model._openGLRenderWindow.registerGraphicsResourceUser(colorTransferFunc, publicAPI);
108
- model._openGLRenderWindow.unregisterGraphicsResourceUser(model._colorTransferFunc, publicAPI);
109
- }
110
- model._colorTransferFunc = colorTransferFunc;
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
- publicAPI.updateLabelOutlineThicknessTexture(actor);
117
- toString = `${image.getMTime()}-${model.scalarTexture.getMTime()}`;
118
- if (model.scalarTextureString !== toString) {
119
- const dims = image.getDimensions();
120
- model.scalarTexture.setOpenGLRenderWindow(model._openGLRenderWindow);
121
- model.scalarTexture.enableUseHalfFloat(false);
122
- const previousTextureParameters = model.scalarTexture.getTextureParameters();
123
- const dataType = image.get('dataType').dataType;
124
- let shouldReset = true;
125
- if (previousTextureParameters?.dataType === dataType) {
126
- if (previousTextureParameters?.width === dims[0]) {
127
- if (previousTextureParameters?.height === dims[1]) {
128
- if (previousTextureParameters?.depth === dims[2]) {
129
- shouldReset = false;
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 (shouldReset) {
135
- const norm16Ext = model.context.getExtension('EXT_texture_norm16');
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
- else {
149
- model.scalarTexture.deactivate();
150
- model.scalarTexture.update3DFromRaw();
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
- model.scalarTextureString = toString;
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
- model.scalarTexture = initialValues.scalarTexture;
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
  }
@@ -1 +1 @@
1
- export declare const version = "4.11.5";
1
+ export declare const version = "4.12.1";
@@ -1 +1 @@
1
- export const version = '4.11.5';
1
+ export const version = '4.12.1';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cornerstonejs/core",
3
- "version": "4.11.5",
3
+ "version": "4.12.1",
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": "32.12.1",
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": "9dc8d3389f395190f13c42d583b09586053f50ee"
100
+ "gitHead": "ba9c1f6316761f852a6278a70b012d89241b9e54"
101
101
  }