@kitware/vtk.js 32.0.1 → 32.1.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/Common/DataModel/Box.d.ts +2 -1
- package/Common/DataModel/Box.js +2 -1
- package/Common/DataModel/Cone.d.ts +2 -6
- package/Common/DataModel/Cone.js +2 -1
- package/Common/DataModel/Cylinder.d.ts +3 -2
- package/Common/DataModel/Cylinder.js +2 -1
- package/Common/DataModel/ImageData.d.ts +0 -1
- package/Common/DataModel/ImageData.js +2 -2
- package/Common/DataModel/ImplicitBoolean.js +5 -4
- package/Common/DataModel/ImplicitFunction.d.ts +68 -0
- package/Common/DataModel/ImplicitFunction.js +60 -0
- package/Common/DataModel/Plane.d.ts +2 -1
- package/Common/DataModel/Plane.js +2 -1
- package/Common/DataModel/Sphere.d.ts +10 -17
- package/Common/DataModel/Sphere.js +11 -19
- package/Rendering/OpenGL/ImageCPRMapper.js +90 -66
- package/Rendering/OpenGL/ImageMapper.js +3 -9
- package/Rendering/OpenGL/ImageResliceMapper.js +9 -17
- package/Rendering/OpenGL/RenderWindow/resourceSharingHelper.d.ts +34 -0
- package/Rendering/OpenGL/RenderWindow/resourceSharingHelper.js +14 -0
- package/Rendering/OpenGL/Texture.d.ts +26 -0
- package/Rendering/OpenGL/Texture.js +124 -68
- package/Rendering/OpenGL/VolumeMapper.js +21 -18
- package/index.d.ts +2 -0
- package/package.json +1 -1
|
@@ -285,7 +285,7 @@ function vtkOpenGLTexture(publicAPI, model) {
|
|
|
285
285
|
publicAPI.getDefaultInternalFormat = (vtktype, numComps) => {
|
|
286
286
|
let result = 0;
|
|
287
287
|
// try default next
|
|
288
|
-
result = model._openGLRenderWindow.getDefaultTextureInternalFormat(vtktype, numComps, model.oglNorm16Ext,
|
|
288
|
+
result = model._openGLRenderWindow.getDefaultTextureInternalFormat(vtktype, numComps, model.oglNorm16Ext, publicAPI.useHalfFloat());
|
|
289
289
|
if (result) {
|
|
290
290
|
return result;
|
|
291
291
|
}
|
|
@@ -295,6 +295,7 @@ function vtkOpenGLTexture(publicAPI, model) {
|
|
|
295
295
|
}
|
|
296
296
|
return result;
|
|
297
297
|
};
|
|
298
|
+
publicAPI.useHalfFloat = () => model.enableHalfFloat && model.canUseHalfFloat;
|
|
298
299
|
|
|
299
300
|
//----------------------------------------------------------------------------
|
|
300
301
|
publicAPI.setInternalFormat = iFormat => {
|
|
@@ -353,6 +354,7 @@ function vtkOpenGLTexture(publicAPI, model) {
|
|
|
353
354
|
|
|
354
355
|
//----------------------------------------------------------------------------
|
|
355
356
|
publicAPI.getDefaultDataType = vtkScalarType => {
|
|
357
|
+
const useHalfFloat = publicAPI.useHalfFloat();
|
|
356
358
|
// DON'T DEAL with VTK_CHAR as this is platform dependent.
|
|
357
359
|
if (model._openGLRenderWindow.getWebgl2()) {
|
|
358
360
|
switch (vtkScalarType) {
|
|
@@ -362,14 +364,14 @@ function vtkOpenGLTexture(publicAPI, model) {
|
|
|
362
364
|
return model.context.UNSIGNED_BYTE;
|
|
363
365
|
// prefer norm16 since that is accurate compared to
|
|
364
366
|
// half float which is not
|
|
365
|
-
case model.oglNorm16Ext && !
|
|
367
|
+
case model.oglNorm16Ext && !useHalfFloat && VtkDataTypes.SHORT:
|
|
366
368
|
return model.context.SHORT;
|
|
367
|
-
case model.oglNorm16Ext && !
|
|
369
|
+
case model.oglNorm16Ext && !useHalfFloat && VtkDataTypes.UNSIGNED_SHORT:
|
|
368
370
|
return model.context.UNSIGNED_SHORT;
|
|
369
371
|
// use half float type
|
|
370
|
-
case
|
|
372
|
+
case useHalfFloat && VtkDataTypes.SHORT:
|
|
371
373
|
return model.context.HALF_FLOAT;
|
|
372
|
-
case
|
|
374
|
+
case useHalfFloat && VtkDataTypes.UNSIGNED_SHORT:
|
|
373
375
|
return model.context.HALF_FLOAT;
|
|
374
376
|
// case VtkDataTypes.INT:
|
|
375
377
|
// return model.context.INT;
|
|
@@ -490,8 +492,18 @@ function vtkOpenGLTexture(publicAPI, model) {
|
|
|
490
492
|
}
|
|
491
493
|
};
|
|
492
494
|
|
|
493
|
-
|
|
494
|
-
|
|
495
|
+
/**
|
|
496
|
+
* Updates the data array to match the required data type for OpenGL.
|
|
497
|
+
*
|
|
498
|
+
* This function takes the input data and converts it to the appropriate
|
|
499
|
+
* format required by the OpenGL texture, based on the specified data type.
|
|
500
|
+
*
|
|
501
|
+
* @param {string} dataType - The original data type of the input data.
|
|
502
|
+
* @param {Array} data - The input data array that needs to be updated.
|
|
503
|
+
* @param {boolean} [depth=false] - Indicates whether the data is a 3D array.
|
|
504
|
+
* @returns {Array} The updated data array that matches the OpenGL data type.
|
|
505
|
+
*/
|
|
506
|
+
publicAPI.updateArrayDataTypeForGL = function (dataType, data) {
|
|
495
507
|
let depth = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
496
508
|
const pixData = [];
|
|
497
509
|
let pixCount = model.width * model.height * model.components;
|
|
@@ -556,7 +568,7 @@ function vtkOpenGLTexture(publicAPI, model) {
|
|
|
556
568
|
}
|
|
557
569
|
}
|
|
558
570
|
return pixData;
|
|
559
|
-
}
|
|
571
|
+
};
|
|
560
572
|
|
|
561
573
|
//----------------------------------------------------------------------------
|
|
562
574
|
function scaleTextureToHighestPowerOfTwo(data) {
|
|
@@ -683,7 +695,7 @@ function vtkOpenGLTexture(publicAPI, model) {
|
|
|
683
695
|
|
|
684
696
|
// Create an array of texture with one texture
|
|
685
697
|
const dataArray = [data];
|
|
686
|
-
const pixData =
|
|
698
|
+
const pixData = publicAPI.updateArrayDataTypeForGL(dataType, dataArray);
|
|
687
699
|
const scaledData = scaleTextureToHighestPowerOfTwo(pixData);
|
|
688
700
|
|
|
689
701
|
// Source texture data from the PBO.
|
|
@@ -705,7 +717,7 @@ function vtkOpenGLTexture(publicAPI, model) {
|
|
|
705
717
|
if (flip) {
|
|
706
718
|
model.context.pixelStorei(model.context.UNPACK_FLIP_Y_WEBGL, false);
|
|
707
719
|
}
|
|
708
|
-
model.allocatedGPUMemoryInBytes = model.width * model.height * model.depth * numComps * model._openGLRenderWindow.getDefaultTextureByteSize(dataType, model.oglNorm16Ext,
|
|
720
|
+
model.allocatedGPUMemoryInBytes = model.width * model.height * model.depth * numComps * model._openGLRenderWindow.getDefaultTextureByteSize(dataType, model.oglNorm16Ext, publicAPI.useHalfFloat());
|
|
709
721
|
publicAPI.deactivate();
|
|
710
722
|
return true;
|
|
711
723
|
};
|
|
@@ -730,7 +742,7 @@ function vtkOpenGLTexture(publicAPI, model) {
|
|
|
730
742
|
model.maxLevel = data.length / 6 - 1;
|
|
731
743
|
publicAPI.createTexture();
|
|
732
744
|
publicAPI.bind();
|
|
733
|
-
const pixData =
|
|
745
|
+
const pixData = publicAPI.updateArrayDataTypeForGL(dataType, data);
|
|
734
746
|
const scaledData = scaleTextureToHighestPowerOfTwo(pixData);
|
|
735
747
|
|
|
736
748
|
// invert the data because opengl is messed up with cube maps
|
|
@@ -783,7 +795,7 @@ function vtkOpenGLTexture(publicAPI, model) {
|
|
|
783
795
|
h /= 2;
|
|
784
796
|
}
|
|
785
797
|
}
|
|
786
|
-
model.allocatedGPUMemoryInBytes = model.width * model.height * model.depth * numComps * model._openGLRenderWindow.getDefaultTextureByteSize(dataType, model.oglNorm16Ext,
|
|
798
|
+
model.allocatedGPUMemoryInBytes = model.width * model.height * model.depth * numComps * model._openGLRenderWindow.getDefaultTextureByteSize(dataType, model.oglNorm16Ext, publicAPI.useHalfFloat());
|
|
787
799
|
// generateMipmap must not be called here because we manually upload all levels
|
|
788
800
|
// if it is called, all levels will be overwritten
|
|
789
801
|
|
|
@@ -833,7 +845,7 @@ function vtkOpenGLTexture(publicAPI, model) {
|
|
|
833
845
|
if (model.generateMipmap) {
|
|
834
846
|
model.context.generateMipmap(model.target);
|
|
835
847
|
}
|
|
836
|
-
model.allocatedGPUMemoryInBytes = model.width * model.height * model.depth * model.components * model._openGLRenderWindow.getDefaultTextureByteSize(dataType, model.oglNorm16Ext,
|
|
848
|
+
model.allocatedGPUMemoryInBytes = model.width * model.height * model.depth * model.components * model._openGLRenderWindow.getDefaultTextureByteSize(dataType, model.oglNorm16Ext, publicAPI.useHalfFloat());
|
|
837
849
|
publicAPI.deactivate();
|
|
838
850
|
return true;
|
|
839
851
|
};
|
|
@@ -883,7 +895,7 @@ function vtkOpenGLTexture(publicAPI, model) {
|
|
|
883
895
|
if (model.generateMipmap) {
|
|
884
896
|
model.context.generateMipmap(model.target);
|
|
885
897
|
}
|
|
886
|
-
model.allocatedGPUMemoryInBytes = model.width * model.height * model.depth * model.components * model._openGLRenderWindow.getDefaultTextureByteSize(VtkDataTypes.UNSIGNED_CHAR, model.oglNorm16Ext,
|
|
898
|
+
model.allocatedGPUMemoryInBytes = model.width * model.height * model.depth * model.components * model._openGLRenderWindow.getDefaultTextureByteSize(VtkDataTypes.UNSIGNED_CHAR, model.oglNorm16Ext, publicAPI.useHalfFloat());
|
|
887
899
|
publicAPI.deactivate();
|
|
888
900
|
return true;
|
|
889
901
|
};
|
|
@@ -915,7 +927,7 @@ function vtkOpenGLTexture(publicAPI, model) {
|
|
|
915
927
|
}
|
|
916
928
|
return true;
|
|
917
929
|
}
|
|
918
|
-
function
|
|
930
|
+
function setCanUseHalfFloat(dataType, offset, scale, preferSizeOverAccuracy) {
|
|
919
931
|
publicAPI.getOpenGLDataType(dataType);
|
|
920
932
|
let useHalfFloat = false;
|
|
921
933
|
if (model._openGLRenderWindow.getWebgl2()) {
|
|
@@ -928,7 +940,7 @@ function vtkOpenGLTexture(publicAPI, model) {
|
|
|
928
940
|
// Don't consider halfFloat and convert back to Float when the range of data does not generate an accurate halfFloat
|
|
929
941
|
// AND it is not preferable to have a smaller texture than an exact texture.
|
|
930
942
|
const isHalfFloat = useHalfFloat && (hasExactHalfFloat(offset, scale) || preferSizeOverAccuracy);
|
|
931
|
-
model.
|
|
943
|
+
model.canUseHalfFloat = isHalfFloat;
|
|
932
944
|
}
|
|
933
945
|
function processDataArray(dataArray, preferSizeOverAccuracy) {
|
|
934
946
|
const numComps = dataArray.getNumberOfComponents();
|
|
@@ -948,11 +960,11 @@ function vtkOpenGLTexture(publicAPI, model) {
|
|
|
948
960
|
|
|
949
961
|
// preferSizeOverAccuracy will override norm16 due to bug with norm16 implementation
|
|
950
962
|
// https://bugs.chromium.org/p/chromium/issues/detail?id=1408247
|
|
951
|
-
|
|
963
|
+
setCanUseHalfFloat(dataType, scaleOffsets.offset, scaleOffsets.scale, preferSizeOverAccuracy);
|
|
952
964
|
|
|
953
965
|
// since our default is to use half float, in case that we can't use it
|
|
954
966
|
// we need to use another type
|
|
955
|
-
if (!
|
|
967
|
+
if (!publicAPI.useHalfFloat()) {
|
|
956
968
|
publicAPI.getOpenGLDataType(dataType, true);
|
|
957
969
|
}
|
|
958
970
|
return {
|
|
@@ -979,14 +991,88 @@ function vtkOpenGLTexture(publicAPI, model) {
|
|
|
979
991
|
} = processDataArray(dataArray, preferSizeOverAccuracy);
|
|
980
992
|
publicAPI.create2DFromRaw(width, height, numComps, dataType, data);
|
|
981
993
|
};
|
|
994
|
+
publicAPI.updateVolumeInfoForGL = (dataType, numComps) => {
|
|
995
|
+
let isScalingApplied = false;
|
|
996
|
+
const useHalfFloat = publicAPI.useHalfFloat();
|
|
997
|
+
|
|
998
|
+
// Initialize volume info if it doesn't exist
|
|
999
|
+
if (!model.volumeInfo?.scale || !model.volumeInfo?.offset) {
|
|
1000
|
+
model.volumeInfo = {
|
|
1001
|
+
scale: new Array(numComps),
|
|
1002
|
+
offset: new Array(numComps)
|
|
1003
|
+
};
|
|
1004
|
+
}
|
|
1005
|
+
|
|
1006
|
+
// Default scaling and offset
|
|
1007
|
+
for (let c = 0; c < numComps; ++c) {
|
|
1008
|
+
model.volumeInfo.scale[c] = 1.0;
|
|
1009
|
+
model.volumeInfo.offset[c] = 0.0;
|
|
1010
|
+
}
|
|
1011
|
+
|
|
1012
|
+
// Handle SHORT data type with EXT_texture_norm16 extension
|
|
1013
|
+
if (model.oglNorm16Ext && !useHalfFloat && dataType === VtkDataTypes.SHORT) {
|
|
1014
|
+
for (let c = 0; c < numComps; ++c) {
|
|
1015
|
+
model.volumeInfo.scale[c] = 32767.0; // Scale to [-1, 1] range
|
|
1016
|
+
}
|
|
1017
|
+
|
|
1018
|
+
isScalingApplied = true;
|
|
1019
|
+
}
|
|
1020
|
+
|
|
1021
|
+
// Handle UNSIGNED_SHORT data type with EXT_texture_norm16 extension
|
|
1022
|
+
if (model.oglNorm16Ext && !useHalfFloat && dataType === VtkDataTypes.UNSIGNED_SHORT) {
|
|
1023
|
+
for (let c = 0; c < numComps; ++c) {
|
|
1024
|
+
model.volumeInfo.scale[c] = 65535.0; // Scale to [0, 1] range
|
|
1025
|
+
}
|
|
1026
|
+
|
|
1027
|
+
isScalingApplied = true;
|
|
1028
|
+
}
|
|
1029
|
+
|
|
1030
|
+
// Handle UNSIGNED_CHAR data type
|
|
1031
|
+
if (dataType === VtkDataTypes.UNSIGNED_CHAR) {
|
|
1032
|
+
for (let c = 0; c < numComps; ++c) {
|
|
1033
|
+
model.volumeInfo.scale[c] = 255.0; // Scale to [0, 1] range
|
|
1034
|
+
}
|
|
1035
|
+
|
|
1036
|
+
isScalingApplied = true;
|
|
1037
|
+
}
|
|
1038
|
+
|
|
1039
|
+
// No scaling needed for FLOAT or HalfFloat (SHORT/UNSIGNED_SHORT)
|
|
1040
|
+
if (dataType === VtkDataTypes.FLOAT || useHalfFloat && (dataType === VtkDataTypes.SHORT || dataType === VtkDataTypes.UNSIGNED_SHORT)) {
|
|
1041
|
+
isScalingApplied = true;
|
|
1042
|
+
}
|
|
1043
|
+
return isScalingApplied;
|
|
1044
|
+
};
|
|
1045
|
+
|
|
982
1046
|
//----------------------------------------------------------------------------
|
|
983
1047
|
publicAPI.create3DFromRaw = (width, height, depth, numComps, dataType, data) => {
|
|
1048
|
+
let dataTypeToUse = dataType;
|
|
1049
|
+
let dataToUse = data;
|
|
1050
|
+
if (!publicAPI.updateVolumeInfoForGL(dataTypeToUse, numComps) && dataToUse) {
|
|
1051
|
+
const numPixelsIn = width * height * depth;
|
|
1052
|
+
const scaleOffsetsCopy = structuredClone(model.volumeInfo);
|
|
1053
|
+
// otherwise convert to float
|
|
1054
|
+
const newArray = new Float32Array(numPixelsIn * numComps);
|
|
1055
|
+
// use computed scale and offset
|
|
1056
|
+
model.volumeInfo.offset = scaleOffsetsCopy.offset;
|
|
1057
|
+
model.volumeInfo.scale = scaleOffsetsCopy.scale;
|
|
1058
|
+
let count = 0;
|
|
1059
|
+
const scaleInverse = scaleOffsetsCopy.scale.map(s => 1 / s);
|
|
1060
|
+
for (let i = 0; i < numPixelsIn; i++) {
|
|
1061
|
+
for (let nc = 0; nc < numComps; nc++) {
|
|
1062
|
+
newArray[count] = (dataToUse[count] - scaleOffsetsCopy.offset[nc]) * scaleInverse[nc];
|
|
1063
|
+
count++;
|
|
1064
|
+
}
|
|
1065
|
+
}
|
|
1066
|
+
dataTypeToUse = VtkDataTypes.FLOAT;
|
|
1067
|
+
dataToUse = newArray;
|
|
1068
|
+
}
|
|
1069
|
+
|
|
984
1070
|
// Permit OpenGLDataType to be half float, if applicable, for 3D
|
|
985
|
-
publicAPI.getOpenGLDataType(
|
|
1071
|
+
publicAPI.getOpenGLDataType(dataTypeToUse);
|
|
986
1072
|
|
|
987
1073
|
// Now determine the texture parameters using the arguments.
|
|
988
|
-
publicAPI.getInternalFormat(
|
|
989
|
-
publicAPI.getFormat(
|
|
1074
|
+
publicAPI.getInternalFormat(dataTypeToUse, numComps);
|
|
1075
|
+
publicAPI.getFormat(dataTypeToUse, numComps);
|
|
990
1076
|
if (!model.internalFormat || !model.format || !model.openGLDataType) {
|
|
991
1077
|
vtkErrorMacro('Failed to determine texture parameters.');
|
|
992
1078
|
return false;
|
|
@@ -1001,9 +1087,9 @@ function vtkOpenGLTexture(publicAPI, model) {
|
|
|
1001
1087
|
publicAPI.createTexture();
|
|
1002
1088
|
publicAPI.bind();
|
|
1003
1089
|
// Create an array of texture with one texture
|
|
1004
|
-
const dataArray = [
|
|
1090
|
+
const dataArray = [dataToUse];
|
|
1005
1091
|
const is3DArray = true;
|
|
1006
|
-
const pixData =
|
|
1092
|
+
const pixData = publicAPI.updateArrayDataTypeForGL(dataTypeToUse, dataArray, is3DArray);
|
|
1007
1093
|
const scaledData = scaleTextureToHighestPowerOfTwo(pixData);
|
|
1008
1094
|
|
|
1009
1095
|
// Source texture data from the PBO.
|
|
@@ -1012,7 +1098,7 @@ function vtkOpenGLTexture(publicAPI, model) {
|
|
|
1012
1098
|
|
|
1013
1099
|
// openGLDataType
|
|
1014
1100
|
|
|
1015
|
-
if (useTexStorage(
|
|
1101
|
+
if (useTexStorage(dataTypeToUse)) {
|
|
1016
1102
|
model.context.texStorage3D(model.target, 1, model.internalFormat, model.width, model.height, model.depth);
|
|
1017
1103
|
if (scaledData[0] != null) {
|
|
1018
1104
|
model.context.texSubImage3D(model.target, 0, 0, 0, 0, model.width, model.height, model.depth, model.format, model.openGLDataType, scaledData[0]);
|
|
@@ -1023,7 +1109,7 @@ function vtkOpenGLTexture(publicAPI, model) {
|
|
|
1023
1109
|
if (model.generateMipmap) {
|
|
1024
1110
|
model.context.generateMipmap(model.target);
|
|
1025
1111
|
}
|
|
1026
|
-
model.allocatedGPUMemoryInBytes = model.width * model.height * model.depth * model.components * model._openGLRenderWindow.getDefaultTextureByteSize(
|
|
1112
|
+
model.allocatedGPUMemoryInBytes = model.width * model.height * model.depth * model.components * model._openGLRenderWindow.getDefaultTextureByteSize(dataTypeToUse, model.oglNorm16Ext, publicAPI.useHalfFloat());
|
|
1027
1113
|
publicAPI.deactivate();
|
|
1028
1114
|
return true;
|
|
1029
1115
|
};
|
|
@@ -1050,7 +1136,6 @@ function vtkOpenGLTexture(publicAPI, model) {
|
|
|
1050
1136
|
data,
|
|
1051
1137
|
scaleOffsets
|
|
1052
1138
|
} = processDataArray(dataArray, preferSizeOverAccuracy);
|
|
1053
|
-
const numPixelsIn = width * height * depth;
|
|
1054
1139
|
const offset = [];
|
|
1055
1140
|
const scale = [];
|
|
1056
1141
|
for (let c = 0; c < numComps; ++c) {
|
|
@@ -1076,46 +1161,13 @@ function vtkOpenGLTexture(publicAPI, model) {
|
|
|
1076
1161
|
// Create a copy of scale and offset to avoid aliasing issues
|
|
1077
1162
|
// Original is read only, copy is read/write
|
|
1078
1163
|
// Use the copy as volumeInfo.scale and volumeInfo.offset
|
|
1079
|
-
const scaleOffsetsCopy = structuredClone(scaleOffsets);
|
|
1080
1164
|
|
|
1081
1165
|
// WebGL2 path, we have 3d textures etc
|
|
1082
1166
|
if (model._openGLRenderWindow.getWebgl2()) {
|
|
1083
|
-
|
|
1084
|
-
for (let c = 0; c < numComps; ++c) {
|
|
1085
|
-
model.volumeInfo.scale[c] = 32767.0;
|
|
1086
|
-
}
|
|
1087
|
-
return publicAPI.create3DFromRaw(width, height, depth, numComps, dataType, data);
|
|
1088
|
-
}
|
|
1089
|
-
if (model.oglNorm16Ext && !model.useHalfFloat && dataType === VtkDataTypes.UNSIGNED_SHORT) {
|
|
1090
|
-
for (let c = 0; c < numComps; ++c) {
|
|
1091
|
-
model.volumeInfo.scale[c] = 65535.0;
|
|
1092
|
-
}
|
|
1093
|
-
return publicAPI.create3DFromRaw(width, height, depth, numComps, dataType, data);
|
|
1094
|
-
}
|
|
1095
|
-
if (dataType === VtkDataTypes.FLOAT || model.useHalfFloat && (dataType === VtkDataTypes.SHORT || dataType === VtkDataTypes.UNSIGNED_SHORT)) {
|
|
1096
|
-
return publicAPI.create3DFromRaw(width, height, depth, numComps, dataType, data);
|
|
1097
|
-
}
|
|
1098
|
-
if (dataType === VtkDataTypes.UNSIGNED_CHAR) {
|
|
1099
|
-
for (let c = 0; c < numComps; ++c) {
|
|
1100
|
-
model.volumeInfo.scale[c] = 255.0;
|
|
1101
|
-
}
|
|
1102
|
-
return publicAPI.create3DFromRaw(width, height, depth, numComps, dataType, data);
|
|
1103
|
-
}
|
|
1104
|
-
// otherwise convert to float
|
|
1105
|
-
const newArray = new Float32Array(numPixelsIn * numComps);
|
|
1106
|
-
// use computed scale and offset
|
|
1107
|
-
model.volumeInfo.offset = scaleOffsetsCopy.offset;
|
|
1108
|
-
model.volumeInfo.scale = scaleOffsetsCopy.scale;
|
|
1109
|
-
let count = 0;
|
|
1110
|
-
const scaleInverse = scaleOffsetsCopy.scale.map(s => 1 / s);
|
|
1111
|
-
for (let i = 0; i < numPixelsIn; i++) {
|
|
1112
|
-
for (let nc = 0; nc < numComps; nc++) {
|
|
1113
|
-
newArray[count] = (data[count] - scaleOffsetsCopy.offset[nc]) * scaleInverse[nc];
|
|
1114
|
-
count++;
|
|
1115
|
-
}
|
|
1116
|
-
}
|
|
1117
|
-
return publicAPI.create3DFromRaw(width, height, depth, numComps, VtkDataTypes.FLOAT, newArray);
|
|
1167
|
+
return publicAPI.create3DFromRaw(width, height, depth, numComps, dataType, data);
|
|
1118
1168
|
}
|
|
1169
|
+
const numPixelsIn = width * height * depth;
|
|
1170
|
+
const scaleOffsetsCopy = structuredClone(scaleOffsets);
|
|
1119
1171
|
|
|
1120
1172
|
// not webgl2, deal with webgl1, no 3d textures
|
|
1121
1173
|
// and maybe no float textures
|
|
@@ -1267,6 +1319,11 @@ function vtkOpenGLTexture(publicAPI, model) {
|
|
|
1267
1319
|
}
|
|
1268
1320
|
return -1;
|
|
1269
1321
|
};
|
|
1322
|
+
|
|
1323
|
+
// set use half float
|
|
1324
|
+
publicAPI.enableUseHalfFloat = use => {
|
|
1325
|
+
model.enableUseHalfFloat = use;
|
|
1326
|
+
};
|
|
1270
1327
|
}
|
|
1271
1328
|
|
|
1272
1329
|
// ----------------------------------------------------------------------------
|
|
@@ -1299,13 +1356,12 @@ const DEFAULT_VALUES = {
|
|
|
1299
1356
|
baseLevel: 0,
|
|
1300
1357
|
maxLevel: 1000,
|
|
1301
1358
|
generateMipmap: false,
|
|
1302
|
-
// use half float by default, but it will get set
|
|
1303
|
-
// to false if the context does not support it or
|
|
1304
|
-
// the voxel intensity range is out of the accurate
|
|
1305
|
-
// range of half float
|
|
1306
|
-
useHalfFloat: true,
|
|
1307
1359
|
oglNorm16Ext: null,
|
|
1308
|
-
allocatedGPUMemoryInBytes: 0
|
|
1360
|
+
allocatedGPUMemoryInBytes: 0,
|
|
1361
|
+
// by default it is enabled
|
|
1362
|
+
enableUseHalfFloat: true,
|
|
1363
|
+
// but by default we don't know if we can use half float base on the data range
|
|
1364
|
+
canUseHalfFloat: false
|
|
1309
1365
|
};
|
|
1310
1366
|
|
|
1311
1367
|
// ----------------------------------------------------------------------------
|
|
@@ -15,6 +15,7 @@ import { Representation } from '../Core/Property/Constants.js';
|
|
|
15
15
|
import { Wrap, Filter } from './Texture/Constants.js';
|
|
16
16
|
import { InterpolationType, OpacityMode, ColorMixPreset } from '../Core/VolumeProperty/Constants.js';
|
|
17
17
|
import { BlendMode } from '../Core/VolumeMapper/Constants.js';
|
|
18
|
+
import { getTransferFunctionHash, getImageDataHash } from './RenderWindow/resourceSharingHelper.js';
|
|
18
19
|
import { v as vtkVolumeVS } from './glsl/vtkVolumeVS.glsl.js';
|
|
19
20
|
import { v as vtkVolumeFS } from './glsl/vtkVolumeFS.glsl.js';
|
|
20
21
|
import { registerOverride } from './ViewNodeFactory.js';
|
|
@@ -28,9 +29,6 @@ const {
|
|
|
28
29
|
// helper methods
|
|
29
30
|
// ----------------------------------------------------------------------------
|
|
30
31
|
|
|
31
|
-
function computeFnToString(pwfun, useIComps, numberOfComponents) {
|
|
32
|
-
return pwfun ? `${pwfun.getMTime()}-${useIComps}-${numberOfComponents}` : '0';
|
|
33
|
-
}
|
|
34
32
|
function getColorCodeFromPreset(colorMixPreset) {
|
|
35
33
|
switch (colorMixPreset) {
|
|
36
34
|
case ColorMixPreset.CUSTOM:
|
|
@@ -417,18 +415,23 @@ function vtkOpenGLVolumeMapper(publicAPI, model) {
|
|
|
417
415
|
program.setUniformf('sampleDistance', publicAPI.getCurrentSampleDistance(ren));
|
|
418
416
|
const volInfo = model.scalarTexture.getVolumeInfo();
|
|
419
417
|
const ipScalarRange = model.renderable.getIpScalarRange();
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
for
|
|
423
|
-
|
|
424
|
-
minVals
|
|
425
|
-
maxVals
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
418
|
+
|
|
419
|
+
// In some situations, we might not have computed the scale and offset
|
|
420
|
+
// for the data range, or it might not be needed.
|
|
421
|
+
if (volInfo?.dataComputedScale?.length) {
|
|
422
|
+
const minVals = [];
|
|
423
|
+
const maxVals = [];
|
|
424
|
+
for (let i = 0; i < 4; i++) {
|
|
425
|
+
// convert iprange from 0-1 into data range values
|
|
426
|
+
minVals[i] = ipScalarRange[0] * volInfo.dataComputedScale[i] + volInfo.dataComputedOffset[i];
|
|
427
|
+
maxVals[i] = ipScalarRange[1] * volInfo.dataComputedScale[i] + volInfo.dataComputedOffset[i];
|
|
428
|
+
// convert data ranges into texture values
|
|
429
|
+
minVals[i] = (minVals[i] - volInfo.offset[i]) / volInfo.scale[i];
|
|
430
|
+
maxVals[i] = (maxVals[i] - volInfo.offset[i]) / volInfo.scale[i];
|
|
431
|
+
}
|
|
432
|
+
program.setUniform4f('ipScalarRangeMin', minVals[0], minVals[1], minVals[2], minVals[3]);
|
|
433
|
+
program.setUniform4f('ipScalarRangeMax', maxVals[0], maxVals[1], maxVals[2], maxVals[3]);
|
|
434
|
+
}
|
|
432
435
|
|
|
433
436
|
// if we have a zbuffer texture then set it
|
|
434
437
|
if (model.zBufferTexture !== null) {
|
|
@@ -1044,7 +1047,7 @@ function vtkOpenGLVolumeMapper(publicAPI, model) {
|
|
|
1044
1047
|
const numIComps = useIndependentComps ? numComp : 1;
|
|
1045
1048
|
const scalarOpacityFunc = vprop.getScalarOpacity();
|
|
1046
1049
|
const opTex = model._openGLRenderWindow.getGraphicsResourceForObject(scalarOpacityFunc);
|
|
1047
|
-
let toString =
|
|
1050
|
+
let toString = getTransferFunctionHash(scalarOpacityFunc, useIndependentComps, numIComps);
|
|
1048
1051
|
const reBuildOp = !opTex?.oglObject || opTex.hash !== toString;
|
|
1049
1052
|
if (reBuildOp) {
|
|
1050
1053
|
model.opacityTexture = vtkOpenGLTexture.newInstance();
|
|
@@ -1096,7 +1099,7 @@ function vtkOpenGLVolumeMapper(publicAPI, model) {
|
|
|
1096
1099
|
|
|
1097
1100
|
// rebuild color tfun?
|
|
1098
1101
|
const colorTransferFunc = vprop.getRGBTransferFunction();
|
|
1099
|
-
toString =
|
|
1102
|
+
toString = getTransferFunctionHash(colorTransferFunc, useIndependentComps, numIComps);
|
|
1100
1103
|
const cTex = model._openGLRenderWindow.getGraphicsResourceForObject(colorTransferFunc);
|
|
1101
1104
|
const reBuildC = !cTex?.oglObject?.getHandle() || cTex?.hash !== toString;
|
|
1102
1105
|
if (reBuildC) {
|
|
@@ -1133,7 +1136,7 @@ function vtkOpenGLVolumeMapper(publicAPI, model) {
|
|
|
1133
1136
|
publicAPI.updateLabelOutlineThicknessTexture(actor);
|
|
1134
1137
|
const tex = model._openGLRenderWindow.getGraphicsResourceForObject(scalars);
|
|
1135
1138
|
// rebuild the scalarTexture if the data has changed
|
|
1136
|
-
toString =
|
|
1139
|
+
toString = getImageDataHash(image, scalars);
|
|
1137
1140
|
const reBuildTex = !tex?.oglObject?.getHandle() || tex?.hash !== toString;
|
|
1138
1141
|
if (reBuildTex) {
|
|
1139
1142
|
model.scalarTexture = vtkOpenGLTexture.newInstance();
|
package/index.d.ts
CHANGED
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
/// <reference path="./Common/DataModel/EdgeLocator.d.ts" />
|
|
32
32
|
/// <reference path="./Common/DataModel/ITKHelper.d.ts" />
|
|
33
33
|
/// <reference path="./Common/DataModel/ImageData.d.ts" />
|
|
34
|
+
/// <reference path="./Common/DataModel/ImplicitFunction.d.ts" />
|
|
34
35
|
/// <reference path="./Common/DataModel/IncrementalOctreeNode.d.ts" />
|
|
35
36
|
/// <reference path="./Common/DataModel/IncrementalOctreePointLocator.d.ts" />
|
|
36
37
|
/// <reference path="./Common/DataModel/KochanekSpline1D.d.ts" />
|
|
@@ -216,6 +217,7 @@
|
|
|
216
217
|
/// <reference path="./Rendering/OpenGL/HardwareSelector/Constants.d.ts" />
|
|
217
218
|
/// <reference path="./Rendering/OpenGL/HardwareSelector.d.ts" />
|
|
218
219
|
/// <reference path="./Rendering/OpenGL/RenderWindow.d.ts" />
|
|
220
|
+
/// <reference path="./Rendering/OpenGL/RenderWindow/resourceSharingHelper.d.ts" />
|
|
219
221
|
/// <reference path="./Rendering/OpenGL/Texture/Constants.d.ts" />
|
|
220
222
|
/// <reference path="./Rendering/OpenGL/Texture.d.ts" />
|
|
221
223
|
/// <reference path="./Rendering/SceneGraph/RenderPass.d.ts" />
|