@kitware/vtk.js 33.0.0-beta.1 → 33.0.0-beta.3

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.
Files changed (62) hide show
  1. package/Common/Core/DataArray.d.ts +4 -0
  2. package/Common/Core/DataArray.js +3 -0
  3. package/Common/Core/Math/index.js +1 -1
  4. package/Common/Core/Math.js +1 -1
  5. package/Common/Core/URLExtract.js +2 -6
  6. package/Common/DataModel/Line.js +1 -0
  7. package/Common/DataModel/PolyLine.js +4 -0
  8. package/Filters/Core/ThresholdPoints.d.ts +72 -0
  9. package/Filters/Core/ThresholdPoints.js +219 -0
  10. package/Filters/General/ContourTriangulator/helper.js +1 -1
  11. package/IO/Core/DataAccessHelper/JSZipDataAccessHelper.js +1 -1
  12. package/IO/Geometry/DracoReader.d.ts +4 -4
  13. package/IO/Geometry/DracoReader.js +154 -105
  14. package/IO/Geometry/GLTFImporter/Animations.js +239 -0
  15. package/IO/Geometry/GLTFImporter/Constants.js +87 -0
  16. package/IO/Geometry/GLTFImporter/Decoder.js +69 -0
  17. package/IO/Geometry/GLTFImporter/Extensions.js +110 -0
  18. package/IO/Geometry/GLTFImporter/ORMTexture.worker.js +42 -0
  19. package/IO/Geometry/GLTFImporter/Parser.js +359 -0
  20. package/IO/Geometry/GLTFImporter/Reader.js +518 -0
  21. package/IO/Geometry/GLTFImporter/Utils.js +165 -0
  22. package/IO/Geometry/GLTFImporter.d.ts +266 -0
  23. package/IO/Geometry/GLTFImporter.js +245 -0
  24. package/IO/Geometry/IFCImporter.d.ts +163 -0
  25. package/IO/Geometry/IFCImporter.js +270 -0
  26. package/IO/Geometry/STLReader.d.ts +14 -0
  27. package/IO/Geometry/STLReader.js +57 -1
  28. package/IO/Geometry.js +5 -1
  29. package/IO/Image/HDRReader/Utils.js +1 -1
  30. package/IO/Image/HDRReader.js +1 -1
  31. package/IO/Image/TGAReader/Constants.js +28 -0
  32. package/IO/Image/TGAReader.d.ts +121 -0
  33. package/IO/Image/TGAReader.js +418 -0
  34. package/IO/Image/TIFFReader.d.ts +133 -0
  35. package/IO/Image/TIFFReader.js +144 -0
  36. package/IO/Image.js +5 -1
  37. package/IO/XML/XMLPolyDataWriter.js +1 -0
  38. package/Interaction/Manipulators/KeyboardCameraManipulator.d.ts +113 -0
  39. package/Interaction/Manipulators/MouseCameraTrackballRollManipulator.js +1 -1
  40. package/Interaction/Style/InteractorStyleTrackballCamera.js +1 -1
  41. package/Rendering/Core/Glyph3DMapper.d.ts +45 -29
  42. package/Rendering/Core/ImageCPRMapper.js +1 -1
  43. package/Rendering/Core/ImageProperty.d.ts +22 -0
  44. package/Rendering/Core/PointPicker.js +10 -1
  45. package/Rendering/Core/Prop3D.js +1 -1
  46. package/Rendering/Core/RenderWindowInteractor.d.ts +1 -1
  47. package/Rendering/Core/RenderWindowInteractor.js +1 -1
  48. package/Rendering/Misc/CanvasView.js +4 -2
  49. package/Rendering/Misc/RemoteView.d.ts +9 -3
  50. package/Rendering/Misc/RemoteView.js +7 -3
  51. package/Rendering/Misc/SynchronizableRenderWindow/ObjectManager.d.ts +1 -1
  52. package/Rendering/OpenGL/ImageMapper.js +14 -7
  53. package/Rendering/OpenGL/Texture/supportsNorm16Linear.js +97 -0
  54. package/Rendering/OpenGL/Texture.js +18 -11
  55. package/Widgets/Widgets3D/AngleWidget/behavior.js +2 -0
  56. package/Widgets/Widgets3D/InteractiveOrientationWidget.js +1 -1
  57. package/Widgets/Widgets3D/ResliceCursorWidget/behavior.js +17 -0
  58. package/Widgets/Widgets3D/ResliceCursorWidget/helpers.js +1 -0
  59. package/Widgets/Widgets3D/ShapeWidget/behavior.js +3 -0
  60. package/_virtual/rollup-plugin-worker-loader__module_Sources/IO/Geometry/GLTFImporter/ORMTexture.worker.js +296 -0
  61. package/index.d.ts +6 -0
  62. package/package.json +12 -10
@@ -36,6 +36,7 @@ function vtkXMLPolyDataWriter(publicAPI, model) {
36
36
  });
37
37
  publicAPI.processDataSetAttributes(piece, 'PointData', dataObject.getPointData());
38
38
  publicAPI.processDataSetAttributes(piece, 'CellData', dataObject.getCellData());
39
+ publicAPI.processDataSetAttributes(piece, 'FieldData', dataObject.getFieldData());
39
40
  publicAPI.processDataArray(piece.ele('Points'), dataObject.getPoints());
40
41
  POLYDATA_FIELDS.forEach(cellType => {
41
42
  const cellTypeName = camelize(cellType);
@@ -0,0 +1,113 @@
1
+ import { Vector3 } from './../../types';
2
+ import { vtkObject } from './../../interfaces';
3
+ import vtkCompositeKeyboardManipulator from './CompositeKeyboardManipulator';
4
+ import vtkRenderWindowInteractor from './../../Rendering/Core/RenderWindowInteractor';
5
+ import vtkCamera from './../../Rendering/Core/Camera';
6
+ import vtkRenderer from './../../Rendering/Core/Renderer';
7
+
8
+ export interface vtkKeyboardCameraManipulator
9
+ extends vtkObject,
10
+ vtkCompositeKeyboardManipulator {
11
+ /**
12
+ * Returns whether a movement is ongoing.
13
+ */
14
+ inMotion(): boolean;
15
+
16
+ /**
17
+ * Reset the movement speed to be proportional to the longest length of the renderer's bounds.
18
+ */
19
+ resetMovementSpeed(): void;
20
+
21
+ /**
22
+ * Initialize a movement of the current camera.
23
+ */
24
+ startMovement(): void;
25
+
26
+ /**
27
+ * Cancel any ongoing camera movement.
28
+ */
29
+ endMovement(): void;
30
+
31
+ /**
32
+ * Update active camera direction, depending on currently pressed keys.
33
+ */
34
+ calculateCurrentDirection(): void;
35
+
36
+ /**
37
+ * Returns the direction vector of the given camera for the given key.
38
+ * @param key the movedkey
39
+ * @param camera the camera
40
+ */
41
+ getDirectionFromKey(key: KeyboardEvent['key'], camera: vtkCamera): Vector3;
42
+
43
+ /**
44
+ * Moves the given camera, in the given direction, at the given speed.
45
+ * @param camera the moved camera
46
+ * @param direction the direction of the movemnt
47
+ * @param speed the speed
48
+ */
49
+ moveCamera(camera: vtkCamera, direction: Vector3, speed: number): void;
50
+
51
+ /**
52
+ * Handles a keypress event.
53
+ * @param interactor the interactor
54
+ * @param renderer the renderer
55
+ * @param key the key
56
+ */
57
+ onKeyPress(
58
+ interactor: vtkRenderWindowInteractor,
59
+ renderer: vtkRenderer,
60
+ key: KeyboardEvent['key']
61
+ ): void;
62
+
63
+ /**
64
+ * Handles a keydown event.
65
+ * @param interactor the interactor
66
+ * @param renderer the renderer
67
+ * @param key the key
68
+ */
69
+ onKeyDown(
70
+ interactor: vtkRenderWindowInteractor,
71
+ renderer: vtkRenderer,
72
+ key: KeyboardEvent['key']
73
+ ): void;
74
+
75
+ /**
76
+ * Handles a keyup event.
77
+ * @param interactor the interactor
78
+ * @param renderer the renderer
79
+ * @param key the key
80
+ */
81
+ onKeyUp(
82
+ interactor: vtkRenderWindowInteractor,
83
+ renderer: vtkRenderer,
84
+ key: KeyboardEvent['key']
85
+ ): void;
86
+ }
87
+
88
+ export interface IKeyboardCameraManipulatorInitialValues {
89
+ movementSpeed?: number;
90
+ moveForwardKeys?: KeyboardEvent['key'][];
91
+ moveLeftKeys?: KeyboardEvent['key'][];
92
+ moveBackwardKeys?: KeyboardEvent['key'][];
93
+ moveRightKeys?: KeyboardEvent['key'][];
94
+ moveUpKeys?: KeyboardEvent['key'][];
95
+ moveDownKeys?: KeyboardEvent['key'][];
96
+ }
97
+
98
+ export function newInstance(
99
+ initialValues?: IKeyboardCameraManipulatorInitialValues
100
+ ): vtkKeyboardCameraManipulator;
101
+
102
+ export function extend(
103
+ publicAPI: object,
104
+ model: object,
105
+ initialValues?: IKeyboardCameraManipulatorInitialValues
106
+ ): void;
107
+
108
+ export const vtkKeyboardCameraManipulator: {
109
+ newInstance: typeof newInstance;
110
+ extend: typeof extend;
111
+ };
112
+
113
+ export default vtkKeyboardCameraManipulator;
@@ -2,7 +2,7 @@ import { mat4, vec3 } from 'gl-matrix';
2
2
  import { m as macro } from '../../macros2.js';
3
3
  import vtkCompositeCameraManipulator from './CompositeCameraManipulator.js';
4
4
  import vtkCompositeMouseManipulator from './CompositeMouseManipulator.js';
5
- import { r as radiansFromDegrees, C as degreesFromRadians } from '../../Common/Core/Math/index.js';
5
+ import { r as radiansFromDegrees, A as degreesFromRadians } from '../../Common/Core/Math/index.js';
6
6
 
7
7
  // ----------------------------------------------------------------------------
8
8
  // vtkMouseCameraTrackballRollManipulator methods
@@ -1,7 +1,7 @@
1
1
  import { m as macro } from '../../macros2.js';
2
2
  import vtkInteractorStyle from '../../Rendering/Core/InteractorStyle.js';
3
3
  import vtkInteractorStyleConstants from '../../Rendering/Core/InteractorStyle/Constants.js';
4
- import { C as degreesFromRadians } from '../../Common/Core/Math/index.js';
4
+ import { A as degreesFromRadians } from '../../Common/Core/Math/index.js';
5
5
  import { Device, Input } from '../../Rendering/Core/RenderWindowInteractor/Constants.js';
6
6
 
7
7
  const {
@@ -12,11 +12,11 @@ interface IPrimitiveCount {
12
12
  export interface IGlyph3DMapperInitialValues extends IMapperInitialValues {
13
13
  orient?: boolean;
14
14
  orientationMode?: OrientationModes;
15
- orientationArray?: number[];
15
+ orientationArray?: string;
16
16
  scaling?: boolean;
17
17
  scaleFactor?: number;
18
18
  scaleMode?: ScaleModes;
19
- scaleArray?: number[];
19
+ scaleArray?: string;
20
20
  matrixArray?: number[];
21
21
  normalArray?: number[];
22
22
  colorArray?: number[];
@@ -24,29 +24,26 @@ export interface IGlyph3DMapperInitialValues extends IMapperInitialValues {
24
24
 
25
25
  export interface vtkGlyph3DMapper extends vtkMapper {
26
26
  /**
27
- * An orientation array is a vtkDataArray with 3 components. The first
28
- * component is the angle of rotation along the X axis. The second component
29
- * is the angle of rotation along the Y axis. The third component is the
30
- * angle of rotation along the Z axis. Orientation is specified in X,Y,Z
31
- * order but the rotations are performed in Z,X an Y.
32
- *
33
- * This definition is compliant with SetOrientation method on vtkProp3D.
27
+ * Get the bounds for this mapper as [xmin, xmax, ymin, ymax,zmin, zmax].
28
+ * @return {Bounds} The bounds for the mapper.
29
+ */
30
+ getBounds(): Bounds;
31
+
32
+ /**
34
33
  *
35
- * By using vector or normal there is a degree of freedom or rotation left
36
- * (underconstrained). With the orientation array, there is no degree of
37
- * freedom left.
38
34
  */
39
- getOrientationMode(): OrientationModes;
35
+ buildArrays(): void;
40
36
 
41
37
  /**
42
- * Get orientation as string
38
+ *
43
39
  */
44
- getOrientationModeAsString(): string;
40
+ getPrimitiveCount(): IPrimitiveCount;
45
41
 
46
42
  /**
47
- * Get orientation as array
43
+ * Get scale mode
44
+ * @default `SCALE_BY_MAGNITUDE`
48
45
  */
49
- getOrientationArrayData(): number[];
46
+ getScaleMode(): ScaleModes;
50
47
 
51
48
  /**
52
49
  * Get scale factor to scale object by.
@@ -54,15 +51,20 @@ export interface vtkGlyph3DMapper extends vtkMapper {
54
51
  getScaleFactor(): number;
55
52
 
56
53
  /**
57
- * Get scale mode
58
- * @default `SCALE_BY_MAGNITUDE`
54
+ * Get scale mode as string
59
55
  */
60
- getScaleMode(): ScaleModes;
56
+ getScaleModeAsString(): string;
61
57
 
62
58
  /**
63
- * Get scale mode as string
59
+ * Sets the name of the array to use as scale values.
60
+ * @param {String} arrayName Name of the array
64
61
  */
65
- getScaleModeAsString(): string;
62
+ setScaleArray(arrayName: Nullable<string>): boolean;
63
+
64
+ /**
65
+ * Gets the name of the array used as scale values.
66
+ */
67
+ getScaleArray(): string;
66
68
 
67
69
  /**
68
70
  * Get scale mode as array
@@ -70,20 +72,29 @@ export interface vtkGlyph3DMapper extends vtkMapper {
70
72
  getScaleArrayData(): number[];
71
73
 
72
74
  /**
73
- * Get the bounds for this mapper as [xmin, xmax, ymin, ymax,zmin, zmax].
74
- * @return {Bounds} The bounds for the mapper.
75
+ * An orientation array is a vtkDataArray with 3 components. The first
76
+ * component is the angle of rotation along the X axis. The second component
77
+ * is the angle of rotation along the Y axis. The third component is the
78
+ * angle of rotation along the Z axis. Orientation is specified in X,Y,Z
79
+ * order but the rotations are performed in Z,X an Y.
80
+ *
81
+ * This definition is compliant with SetOrientation method on vtkProp3D.
82
+ *
83
+ * By using vector or normal there is a degree of freedom or rotation left
84
+ * (underconstrained). With the orientation array, there is no degree of
85
+ * freedom left.
75
86
  */
76
- getBounds(): Bounds;
87
+ getOrientationMode(): OrientationModes;
77
88
 
78
89
  /**
79
- *
90
+ * Get orientation as string
80
91
  */
81
- buildArrays(): void;
92
+ getOrientationModeAsString(): string;
82
93
 
83
94
  /**
84
- *
95
+ * Get orientation as array
85
96
  */
86
- getPrimitiveCount(): IPrimitiveCount;
97
+ getOrientationArrayData(): number[];
87
98
 
88
99
  /**
89
100
  * Sets the name of the array to use as orientation.
@@ -91,6 +102,11 @@ export interface vtkGlyph3DMapper extends vtkMapper {
91
102
  */
92
103
  setOrientationArray(arrayName: Nullable<string>): boolean;
93
104
 
105
+ /**
106
+ * Gets the name of the array used as orientation values.
107
+ */
108
+ getOrientationArray(): string;
109
+
94
110
  /**
95
111
  * Orientation mode indicates if the OrientationArray provides the direction
96
112
  * vector for the orientation or the rotations around each axes.
@@ -1,4 +1,4 @@
1
- import { vec3, mat4, quat } from 'gl-matrix';
1
+ import { quat, vec3, mat4 } from 'gl-matrix';
2
2
  import CoincidentTopologyHelper from './Mapper/CoincidentTopologyHelper.js';
3
3
  import vtkAbstractImageMapper from './AbstractImageMapper.js';
4
4
  import { m as macro } from '../../macros2.js';
@@ -94,6 +94,28 @@ export interface vtkImageProperty extends vtkObject {
94
94
  */
95
95
  getScalarOpacity(idx?: number): vtkPiecewiseFunction;
96
96
 
97
+ /**
98
+ * Enable label outline rendering.
99
+ * @param {Boolean} useLabelOutline
100
+ */
101
+ setUseLabelOutline(useLabelOutline: boolean): boolean;
102
+
103
+ /**
104
+ * Check if label outline rendering.
105
+ */
106
+ getUseLabelOutline(): boolean;
107
+
108
+ /**
109
+ * Set the 0 to 1 opacity of the label outline.
110
+ * @param {Number} opacity
111
+ */
112
+ setLabelOutlineOpacity(opacity: number): boolean;
113
+
114
+ /**
115
+ * Get the 0 to 1 opacity of the label outline.
116
+ */
117
+ getLabelOutlineOpacity(): number;
118
+
97
119
  /**
98
120
  * gets the label outline thickness
99
121
  */
@@ -80,6 +80,9 @@ function vtkPointPicker(publicAPI, model) {
80
80
  if (maxDist <= tolerance && maxDist < minPtDist) {
81
81
  // within tolerance
82
82
  minPtId = ptId;
83
+ x[0];
84
+ x[1];
85
+ x[2];
83
86
  minPtDist = maxDist;
84
87
  tMin = t;
85
88
  }
@@ -108,13 +111,19 @@ function vtkPointPicker(publicAPI, model) {
108
111
  if (maxDist <= tolerance && maxDist < minPtDist) {
109
112
  // within tolerance
110
113
  minPtId = ptId;
114
+ x[0];
115
+ x[1];
116
+ x[2];
111
117
  minPtDist = maxDist;
112
118
  tMin = t;
113
119
  }
114
120
  }
115
121
  }
116
122
  }
117
- model.pointId = minPtId;
123
+ if (minPtId > -1 && tMin < model.globalTMin) {
124
+ model.globalTMin = tMin;
125
+ model.pointId = minPtId;
126
+ }
118
127
  return tMin;
119
128
  };
120
129
  }
@@ -1,7 +1,7 @@
1
1
  import { mat4, quat } from 'gl-matrix';
2
2
  import { m as macro } from '../../macros2.js';
3
3
  import vtkBoundingBox from '../../Common/DataModel/BoundingBox.js';
4
- import { C as degreesFromRadians, r as radiansFromDegrees, a as areMatricesEqual } from '../../Common/Core/Math/index.js';
4
+ import { A as degreesFromRadians, r as radiansFromDegrees, a as areMatricesEqual } from '../../Common/Core/Math/index.js';
5
5
  import vtkProp from './Prop.js';
6
6
 
7
7
  const VTK_EPSILON = 1e-6;
@@ -63,7 +63,7 @@ export interface IRenderWindowInteractorInitialValues {
63
63
  mouseScrollDebounceByPass?: boolean;
64
64
  }
65
65
 
66
- interface IPosition {
66
+ export interface IPosition {
67
67
  type: string;
68
68
  }
69
69
 
@@ -1,5 +1,5 @@
1
1
  import { m as macro } from '../../macros2.js';
2
- import { C as degreesFromRadians } from '../../Common/Core/Math/index.js';
2
+ import { A as degreesFromRadians } from '../../Common/Core/Math/index.js';
3
3
  import Constants from './RenderWindowInteractor/Constants.js';
4
4
 
5
5
  const {
@@ -134,8 +134,10 @@ function extend(publicAPI, model) {
134
134
  Object.assign(model, DEFAULT_VALUES, initialValues);
135
135
 
136
136
  // Create internal instances
137
- model.canvas = document.createElement('canvas');
138
- model.canvas.style.width = '100%';
137
+ if (!model.canvas) {
138
+ model.canvas = document.createElement('canvas');
139
+ model.canvas.style.width = '100%';
140
+ }
139
141
 
140
142
  // Create internal bgImage
141
143
  model.bgImage = new Image();
@@ -13,21 +13,27 @@ interface IRemoteViewInitialValues {
13
13
  rpcGestureEvent?: any;
14
14
  rpcWheelEvent?: any;
15
15
  viewStream?: vtkViewStream;
16
+ canvasElement?: HTMLCanvasElement;
16
17
  }
17
18
 
18
19
  export interface vtkRemoteView extends vtkObject {
19
20
  /**
20
- * Get container element
21
+ * Get container HTML element
21
22
  */
22
23
  getContainer(): HTMLElement;
23
24
 
24
25
  /**
25
- *
26
+ * Get vtkViewStream object
26
27
  */
27
28
  getViewStream(): vtkViewStream;
28
29
 
29
30
  /**
30
- *
31
+ * Get the canvas HTML element
32
+ */
33
+ getCanvasElement(): HTMLCanvasElement;
34
+
35
+ /**
36
+ * Get the vtkCanvasView object
31
37
  */
32
38
  getCanvasView(): vtkCanvasView;
33
39
 
@@ -17,7 +17,9 @@ function vtkRemoteView(publicAPI, model) {
17
17
  model.classHierarchy.push('vtkRemoteView');
18
18
 
19
19
  // Constructor
20
- model.canvasView = vtkCanvasView.newInstance();
20
+ model.canvasView = vtkCanvasView.newInstance({
21
+ canvas: model.canvasElement
22
+ });
21
23
  model.interactorStyle = vtkInteractorStyleRemoteMouse.newInstance();
22
24
  model.interactor = vtkRenderWindowInteractor.newInstance();
23
25
  model.interactor.setView(model.canvasView);
@@ -60,6 +62,7 @@ function vtkRemoteView(publicAPI, model) {
60
62
  model.viewStream.delete();
61
63
  }
62
64
  }, publicAPI.delete);
65
+ publicAPI.getCanvasElement = () => model.canvasView.getCanvas();
63
66
 
64
67
  // --------------------------------------------------------------------------
65
68
  // remote handing
@@ -194,7 +197,8 @@ const DEFAULT_VALUES = {
194
197
  stillRatio: 1,
195
198
  rpcMouseEvent: 'viewport.mouse.interaction',
196
199
  rpcGestureEvent: null,
197
- rpcWheelEvent: null
200
+ rpcWheelEvent: null,
201
+ canvasElement: null
198
202
  };
199
203
 
200
204
  // ----------------------------------------------------------------------------
@@ -203,7 +207,7 @@ function extend(publicAPI, model) {
203
207
  let initialValues = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
204
208
  Object.assign(model, DEFAULT_VALUES, initialValues);
205
209
  macro.obj(publicAPI, model, initialValues);
206
- macro.get(publicAPI, model, ['container', 'viewStream', 'canvasView', 'interactor', 'interactorStyle', 'interactiveQuality', 'interactiveRatio', 'stillQuality', 'stillRatio']);
210
+ macro.get(publicAPI, model, ['container', 'viewStream', 'canvasView', 'interactor', 'interactorStyle', 'interactiveQuality', 'interactiveRatio', 'stillQuality', 'stillRatio', 'canvasElement']);
207
211
  macro.setGet(publicAPI, model, ['session', 'rpcMouseEvent', 'rpcGestureEvent', 'rpcWheelEvent']);
208
212
 
209
213
  // Object methods
@@ -1,6 +1,6 @@
1
1
  import { vtkObject } from './../../../interfaces';
2
2
  import { Nullable } from './../../../types';
3
- import { ISynchronizerContext, IViewState } from '..';
3
+ import { ISynchronizerContext, IViewState } from '../SynchronizableRenderWindow';
4
4
 
5
5
  export type BuilderFunction = <T extends vtkObject>(
6
6
  type: string,
@@ -167,9 +167,9 @@ function vtkOpenGLImageMapper(publicAPI, model) {
167
167
  // check for the outline thickness and opacity
168
168
  const vtkImageLabelOutline = actor.getProperty().getUseLabelOutline();
169
169
  if (vtkImageLabelOutline === true) {
170
- FSSource = vtkShaderProgram.substitute(FSSource, '//VTK::LabelOutline::Dec', ['uniform int outlineThickness;', 'uniform float vpWidth;', 'uniform float vpHeight;', 'uniform float vpOffsetX;', 'uniform float vpOffsetY;', 'uniform mat4 PCWCMatrix;', 'uniform mat4 vWCtoIDX;', 'uniform ivec3 imageDimensions;']).result;
170
+ FSSource = vtkShaderProgram.substitute(FSSource, '//VTK::LabelOutline::Dec', ['uniform int outlineThickness;', 'uniform float vpWidth;', 'uniform float vpHeight;', 'uniform float vpOffsetX;', 'uniform float vpOffsetY;', 'uniform mat4 PCWCMatrix;', 'uniform mat4 vWCtoIDX;', 'uniform ivec3 imageDimensions;', 'uniform int sliceAxis;']).result;
171
171
  FSSource = vtkShaderProgram.substitute(FSSource, '//VTK::ImageLabelOutlineOn', '#define vtkImageLabelOutlineOn').result;
172
- FSSource = vtkShaderProgram.substitute(FSSource, '//VTK::LabelOutlineHelperFunction', ['#ifdef vtkImageLabelOutlineOn', 'vec3 fragCoordToIndexSpace(vec4 fragCoord) {', ' vec4 pcPos = vec4(', ' (fragCoord.x / vpWidth - vpOffsetX - 0.5) * 2.0,', ' (fragCoord.y / vpHeight - vpOffsetY - 0.5) * 2.0,', ' (fragCoord.z - 0.5) * 2.0,', ' 1.0);', '', ' vec4 worldCoord = PCWCMatrix * pcPos;', ' vec4 vertex = (worldCoord/worldCoord.w);', '', ' vec3 index = (vWCtoIDX * vertex).xyz;', '', ' // half voxel fix for labelmapOutline', ' return (index + vec3(0.5)) / vec3(imageDimensions);', '}', '#endif']).result;
172
+ FSSource = vtkShaderProgram.substitute(FSSource, '//VTK::LabelOutlineHelperFunction', ['#ifdef vtkImageLabelOutlineOn', 'vec3 fragCoordToIndexSpace(vec4 fragCoord) {', ' vec4 pcPos = vec4(', ' (fragCoord.x / vpWidth - vpOffsetX - 0.5) * 2.0,', ' (fragCoord.y / vpHeight - vpOffsetY - 0.5) * 2.0,', ' (fragCoord.z - 0.5) * 2.0,', ' 1.0);', '', ' vec4 worldCoord = PCWCMatrix * pcPos;', ' vec4 vertex = (worldCoord/worldCoord.w);', '', ' vec3 index = (vWCtoIDX * vertex).xyz;', '', ' // half voxel fix for labelmapOutline', ' return (index + vec3(0.5)) / vec3(imageDimensions);', '}', 'vec2 getSliceCoords(vec3 coord, int axis) {', ' if (axis == 0) return coord.yz;', ' if (axis == 1) return coord.xz;', ' if (axis == 2) return coord.xy;', '}', '#endif']).result;
173
173
  }
174
174
  if (iComps) {
175
175
  const rgba = ['r', 'g', 'b', 'a'];
@@ -201,7 +201,7 @@ function vtkOpenGLImageMapper(publicAPI, model) {
201
201
  FSSource = vtkShaderProgram.substitute(FSSource, '//VTK::TCoord::Impl', [...splitStringOnEnter(`
202
202
  #ifdef vtkImageLabelOutlineOn
203
203
  vec3 centerPosIS = fragCoordToIndexSpace(gl_FragCoord);
204
- float centerValue = texture2D(texture1, centerPosIS.xy).r;
204
+ float centerValue = texture2D(texture1, getSliceCoords(centerPosIS, sliceAxis)).r;
205
205
  bool pixelOnBorder = false;
206
206
  vec3 tColor = texture2D(colorTexture1, vec2(centerValue * cscale0 + cshift0, 0.5)).rgb;
207
207
  float scalarOpacity = texture2D(pwfTexture1, vec2(centerValue * pwfscale0 + pwfshift0, 0.5)).r;
@@ -212,7 +212,7 @@ function vtkOpenGLImageMapper(publicAPI, model) {
212
212
  int actualThickness = int(textureValue * 255.0);
213
213
 
214
214
  if (segmentIndex == 0){
215
- gl_FragData[0] = vec4(0.0, 1.0, 1.0, 0.0);
215
+ gl_FragData[0] = vec4(0.0, 0.0, 0.0, 0.0);
216
216
  return;
217
217
  }
218
218
 
@@ -225,7 +225,7 @@ function vtkOpenGLImageMapper(publicAPI, model) {
225
225
  gl_FragCoord.y + float(j),
226
226
  gl_FragCoord.z, gl_FragCoord.w);
227
227
  vec3 neighborPosIS = fragCoordToIndexSpace(neighborPixelCoord);
228
- float value = texture2D(texture1, neighborPosIS.xy).r;
228
+ float value = texture2D(texture1, getSliceCoords(neighborPosIS, sliceAxis)).r;
229
229
  if (value != centerValue) {
230
230
  pixelOnBorder = true;
231
231
  break;
@@ -474,7 +474,14 @@ function vtkOpenGLImageMapper(publicAPI, model) {
474
474
  if (vtkImageLabelOutline === true) {
475
475
  const worldToIndex = image.getWorldToIndex();
476
476
  const imageDimensions = image.getDimensions();
477
- program.setUniform3i('imageDimensions', imageDimensions[0], imageDimensions[1], 1);
477
+ let sliceAxis = model.renderable.getClosestIJKAxis().ijkMode;
478
+
479
+ // SlicingMode.NONE equates to SlicingMode.K
480
+ if (sliceAxis === SlicingMode.NONE) {
481
+ sliceAxis = SlicingMode.K;
482
+ }
483
+ program.setUniform3i('imageDimensions', imageDimensions[0], imageDimensions[1], imageDimensions[2]);
484
+ program.setUniformi('sliceAxis', sliceAxis);
478
485
  program.setUniformMatrix('vWCtoIDX', worldToIndex);
479
486
  const labelOutlineKeyMats = model.openGLCamera.getKeyMatrices(ren);
480
487
 
@@ -896,7 +903,7 @@ function vtkOpenGLImageMapper(publicAPI, model) {
896
903
  }
897
904
  };
898
905
  publicAPI.updatelabelOutlineThicknessTexture = image => {
899
- const labelOutlineThicknessArray = image.getProperty().getLabelOutlineThickness();
906
+ const labelOutlineThicknessArray = image.getProperty().getLabelOutlineThicknessByReference();
900
907
  const lTex = model._openGLRenderWindow.getGraphicsResourceForObject(labelOutlineThicknessArray);
901
908
 
902
909
  // compute the join of the labelOutlineThicknessArray so that
@@ -0,0 +1,97 @@
1
+ /**
2
+ * Even when the EXT_texture_norm16 extension is present, linear filtering
3
+ * might not be supported for normalized fixed point textures.
4
+ *
5
+ * This is a driver bug. See https://github.com/KhronosGroup/WebGL/issues/3706
6
+ * @return {boolean}
7
+ */
8
+ function supportsNorm16Linear() {
9
+ try {
10
+ const canvasSize = 4;
11
+ const texWidth = 2;
12
+ const texHeight = 1;
13
+ const texData = new Int16Array([0, 2 ** 15 - 1]);
14
+ const pixelToCheck = [1, 1];
15
+ const canvas = document.createElement('canvas');
16
+ canvas.width = canvasSize;
17
+ canvas.height = canvasSize;
18
+ const gl = canvas.getContext('webgl2');
19
+ if (!gl) {
20
+ return false;
21
+ }
22
+ const ext = gl.getExtension('EXT_texture_norm16');
23
+ if (!ext) {
24
+ return false;
25
+ }
26
+ const vs = `#version 300 es
27
+ void main() {
28
+ gl_PointSize = ${canvasSize.toFixed(1)};
29
+ gl_Position = vec4(0, 0, 0, 1);
30
+ }
31
+ `;
32
+ const fs = `#version 300 es
33
+ precision highp float;
34
+ precision highp int;
35
+ precision highp sampler2D;
36
+
37
+ uniform sampler2D u_image;
38
+
39
+ out vec4 color;
40
+
41
+ void main() {
42
+ vec4 intColor = texture(u_image, gl_PointCoord.xy);
43
+ color = vec4(vec3(intColor.rrr), 1);
44
+ }
45
+ `;
46
+ const vertexShader = gl.createShader(gl.VERTEX_SHADER);
47
+ gl.shaderSource(vertexShader, vs);
48
+ gl.compileShader(vertexShader);
49
+ if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {
50
+ return false;
51
+ }
52
+ const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
53
+ gl.shaderSource(fragmentShader, fs);
54
+ gl.compileShader(fragmentShader);
55
+ if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {
56
+ return false;
57
+ }
58
+ const program = gl.createProgram();
59
+ gl.attachShader(program, vertexShader);
60
+ gl.attachShader(program, fragmentShader);
61
+ gl.linkProgram(program);
62
+ if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
63
+ return false;
64
+ }
65
+ const tex = gl.createTexture();
66
+ gl.bindTexture(gl.TEXTURE_2D, tex);
67
+ gl.texImage2D(gl.TEXTURE_2D, 0, ext.R16_SNORM_EXT, texWidth, texHeight, 0, gl.RED, gl.SHORT, texData);
68
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
69
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
70
+ gl.useProgram(program);
71
+ gl.drawArrays(gl.POINTS, 0, 1);
72
+ const pixel = new Uint8Array(4);
73
+ gl.readPixels(pixelToCheck[0], pixelToCheck[1], 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixel);
74
+ const [r, g, b] = pixel;
75
+ const webglLoseContext = gl.getExtension('WEBGL_lose_context');
76
+ if (webglLoseContext) {
77
+ webglLoseContext.loseContext();
78
+ }
79
+ return r === g && g === b && r !== 0;
80
+ } catch (e) {
81
+ return false;
82
+ }
83
+ }
84
+
85
+ /**
86
+ * @type {boolean | undefined}
87
+ */
88
+ let supportsNorm16LinearCache;
89
+ function supportsNorm16LinearCached() {
90
+ // Only create a canvas+texture+shaders the first time
91
+ if (supportsNorm16LinearCache === undefined) {
92
+ supportsNorm16LinearCache = supportsNorm16Linear();
93
+ }
94
+ return supportsNorm16LinearCache;
95
+ }
96
+
97
+ export { supportsNorm16LinearCached as default };