@kitware/vtk.js 33.0.0-beta.2 → 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.
- package/Common/Core/DataArray.d.ts +4 -0
- package/Common/Core/DataArray.js +3 -0
- package/Common/Core/Math/index.js +1 -1
- package/Common/Core/Math.js +1 -1
- package/Common/Core/URLExtract.js +2 -6
- package/Common/DataModel/Line.js +1 -0
- package/Common/DataModel/PolyLine.js +4 -0
- package/Filters/Core/ThresholdPoints.d.ts +72 -0
- package/Filters/Core/ThresholdPoints.js +219 -0
- package/Filters/General/ContourTriangulator/helper.js +1 -1
- package/IO/Core/DataAccessHelper/JSZipDataAccessHelper.js +1 -1
- package/IO/Geometry/DracoReader.d.ts +4 -4
- package/IO/Geometry/DracoReader.js +154 -105
- package/IO/Geometry/GLTFImporter/Animations.js +239 -0
- package/IO/Geometry/GLTFImporter/Constants.js +87 -0
- package/IO/Geometry/GLTFImporter/Decoder.js +69 -0
- package/IO/Geometry/GLTFImporter/Extensions.js +110 -0
- package/IO/Geometry/GLTFImporter/ORMTexture.worker.js +42 -0
- package/IO/Geometry/GLTFImporter/Parser.js +359 -0
- package/IO/Geometry/GLTFImporter/Reader.js +518 -0
- package/IO/Geometry/GLTFImporter/Utils.js +165 -0
- package/IO/Geometry/GLTFImporter.d.ts +266 -0
- package/IO/Geometry/GLTFImporter.js +245 -0
- package/IO/Geometry/IFCImporter.d.ts +163 -0
- package/IO/Geometry/IFCImporter.js +270 -0
- package/IO/Geometry/STLReader.d.ts +14 -0
- package/IO/Geometry/STLReader.js +57 -1
- package/IO/Geometry.js +5 -1
- package/IO/Image/HDRReader/Utils.js +1 -1
- package/IO/Image/HDRReader.js +1 -1
- package/IO/Image/TGAReader/Constants.js +28 -0
- package/IO/Image/TGAReader.d.ts +121 -0
- package/IO/Image/TGAReader.js +418 -0
- package/IO/Image/TIFFReader.d.ts +133 -0
- package/IO/Image/TIFFReader.js +144 -0
- package/IO/Image.js +5 -1
- package/IO/XML/XMLPolyDataWriter.js +1 -0
- package/Interaction/Manipulators/MouseCameraTrackballRollManipulator.js +1 -1
- package/Interaction/Style/InteractorStyleTrackballCamera.js +1 -1
- package/Rendering/Core/Glyph3DMapper.d.ts +45 -29
- package/Rendering/Core/ImageCPRMapper.js +1 -1
- package/Rendering/Core/ImageProperty.d.ts +22 -0
- package/Rendering/Core/PointPicker.js +10 -1
- package/Rendering/Core/Prop3D.js +1 -1
- package/Rendering/Core/RenderWindowInteractor.d.ts +1 -1
- package/Rendering/Core/RenderWindowInteractor.js +1 -1
- package/Rendering/Misc/CanvasView.js +4 -2
- package/Rendering/Misc/RemoteView.d.ts +9 -3
- package/Rendering/Misc/RemoteView.js +7 -3
- package/Rendering/Misc/SynchronizableRenderWindow/ObjectManager.d.ts +1 -1
- package/Rendering/OpenGL/ImageMapper.js +14 -7
- package/Rendering/OpenGL/Texture/supportsNorm16Linear.js +97 -0
- package/Rendering/OpenGL/Texture.js +18 -11
- package/Widgets/Widgets3D/AngleWidget/behavior.js +2 -0
- package/Widgets/Widgets3D/InteractiveOrientationWidget.js +1 -1
- package/Widgets/Widgets3D/ResliceCursorWidget/behavior.js +17 -0
- package/Widgets/Widgets3D/ResliceCursorWidget/helpers.js +1 -0
- package/Widgets/Widgets3D/ShapeWidget/behavior.js +3 -0
- package/_virtual/rollup-plugin-worker-loader__module_Sources/IO/Geometry/GLTFImporter/ORMTexture.worker.js +296 -0
- package/index.d.ts +5 -0
- 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);
|
|
@@ -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,
|
|
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 {
|
|
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?:
|
|
15
|
+
orientationArray?: string;
|
|
16
16
|
scaling?: boolean;
|
|
17
17
|
scaleFactor?: number;
|
|
18
18
|
scaleMode?: ScaleModes;
|
|
19
|
-
scaleArray?:
|
|
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
|
-
*
|
|
28
|
-
*
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
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
|
-
|
|
35
|
+
buildArrays(): void;
|
|
40
36
|
|
|
41
37
|
/**
|
|
42
|
-
*
|
|
38
|
+
*
|
|
43
39
|
*/
|
|
44
|
-
|
|
40
|
+
getPrimitiveCount(): IPrimitiveCount;
|
|
45
41
|
|
|
46
42
|
/**
|
|
47
|
-
* Get
|
|
43
|
+
* Get scale mode
|
|
44
|
+
* @default `SCALE_BY_MAGNITUDE`
|
|
48
45
|
*/
|
|
49
|
-
|
|
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
|
-
|
|
56
|
+
getScaleModeAsString(): string;
|
|
61
57
|
|
|
62
58
|
/**
|
|
63
|
-
*
|
|
59
|
+
* Sets the name of the array to use as scale values.
|
|
60
|
+
* @param {String} arrayName Name of the array
|
|
64
61
|
*/
|
|
65
|
-
|
|
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
|
-
*
|
|
74
|
-
*
|
|
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
|
-
|
|
87
|
+
getOrientationMode(): OrientationModes;
|
|
77
88
|
|
|
78
89
|
/**
|
|
79
|
-
*
|
|
90
|
+
* Get orientation as string
|
|
80
91
|
*/
|
|
81
|
-
|
|
92
|
+
getOrientationModeAsString(): string;
|
|
82
93
|
|
|
83
94
|
/**
|
|
84
|
-
*
|
|
95
|
+
* Get orientation as array
|
|
85
96
|
*/
|
|
86
|
-
|
|
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
|
|
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.
|
|
123
|
+
if (minPtId > -1 && tMin < model.globalTMin) {
|
|
124
|
+
model.globalTMin = tMin;
|
|
125
|
+
model.pointId = minPtId;
|
|
126
|
+
}
|
|
118
127
|
return tMin;
|
|
119
128
|
};
|
|
120
129
|
}
|
package/Rendering/Core/Prop3D.js
CHANGED
|
@@ -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 {
|
|
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;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { m as macro } from '../../macros2.js';
|
|
2
|
-
import {
|
|
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
|
|
138
|
-
|
|
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
|
|
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,
|
|
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
|
|
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
|
-
|
|
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().
|
|
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 };
|
|
@@ -5,6 +5,7 @@ import vtkDataArray from '../../Common/Core/DataArray.js';
|
|
|
5
5
|
import { V as isPowerOfTwo, R as nearestPowerOfTwo } from '../../Common/Core/Math/index.js';
|
|
6
6
|
import vtkViewNode from '../SceneGraph/ViewNode.js';
|
|
7
7
|
import { registerOverride } from './ViewNodeFactory.js';
|
|
8
|
+
import supportsNorm16LinearCached from './Texture/supportsNorm16Linear.js';
|
|
8
9
|
|
|
9
10
|
const {
|
|
10
11
|
Wrap,
|
|
@@ -133,6 +134,12 @@ function vtkOpenGLTexture(publicAPI, model) {
|
|
|
133
134
|
publicAPI.activate();
|
|
134
135
|
}
|
|
135
136
|
};
|
|
137
|
+
const getNorm16Ext = () => {
|
|
138
|
+
if ((model.minificationFilter === Filter.LINEAR || model.magnificationFilter === Filter.LINEAR) && !supportsNorm16LinearCached()) {
|
|
139
|
+
return undefined;
|
|
140
|
+
}
|
|
141
|
+
return model.oglNorm16Ext;
|
|
142
|
+
};
|
|
136
143
|
|
|
137
144
|
//----------------------------------------------------------------------------
|
|
138
145
|
publicAPI.destroyTexture = () => {
|
|
@@ -285,7 +292,7 @@ function vtkOpenGLTexture(publicAPI, model) {
|
|
|
285
292
|
publicAPI.getDefaultInternalFormat = (vtktype, numComps) => {
|
|
286
293
|
let result = 0;
|
|
287
294
|
// try default next
|
|
288
|
-
result = model._openGLRenderWindow.getDefaultTextureInternalFormat(vtktype, numComps,
|
|
295
|
+
result = model._openGLRenderWindow.getDefaultTextureInternalFormat(vtktype, numComps, getNorm16Ext(), publicAPI.useHalfFloat());
|
|
289
296
|
if (result) {
|
|
290
297
|
return result;
|
|
291
298
|
}
|
|
@@ -364,9 +371,9 @@ function vtkOpenGLTexture(publicAPI, model) {
|
|
|
364
371
|
return model.context.UNSIGNED_BYTE;
|
|
365
372
|
// prefer norm16 since that is accurate compared to
|
|
366
373
|
// half float which is not
|
|
367
|
-
case
|
|
374
|
+
case getNorm16Ext() && !useHalfFloat && VtkDataTypes.SHORT:
|
|
368
375
|
return model.context.SHORT;
|
|
369
|
-
case
|
|
376
|
+
case getNorm16Ext() && !useHalfFloat && VtkDataTypes.UNSIGNED_SHORT:
|
|
370
377
|
return model.context.UNSIGNED_SHORT;
|
|
371
378
|
// use half float type
|
|
372
379
|
case useHalfFloat && VtkDataTypes.SHORT:
|
|
@@ -659,7 +666,7 @@ function vtkOpenGLTexture(publicAPI, model) {
|
|
|
659
666
|
}
|
|
660
667
|
if (model._openGLRenderWindow.getWebgl2()) {
|
|
661
668
|
const webGLInfo = model._openGLRenderWindow.getGLInformations();
|
|
662
|
-
if (webGLInfo.RENDERER.value.match(/WebKit/gi) && navigator.platform.match(/Mac/gi) &&
|
|
669
|
+
if (webGLInfo.RENDERER.value.match(/WebKit/gi) && navigator.platform.match(/Mac/gi) && getNorm16Ext() && (dataType === VtkDataTypes.UNSIGNED_SHORT || dataType === VtkDataTypes.SHORT)) {
|
|
663
670
|
// Cannot use texStorage with EXT_texture_norm16 textures on Mac M1 GPU.
|
|
664
671
|
// No errors reported but the texture is unusable.
|
|
665
672
|
return false;
|
|
@@ -717,7 +724,7 @@ function vtkOpenGLTexture(publicAPI, model) {
|
|
|
717
724
|
if (flip) {
|
|
718
725
|
model.context.pixelStorei(model.context.UNPACK_FLIP_Y_WEBGL, false);
|
|
719
726
|
}
|
|
720
|
-
model.allocatedGPUMemoryInBytes = model.width * model.height * model.depth * numComps * model._openGLRenderWindow.getDefaultTextureByteSize(dataType,
|
|
727
|
+
model.allocatedGPUMemoryInBytes = model.width * model.height * model.depth * numComps * model._openGLRenderWindow.getDefaultTextureByteSize(dataType, getNorm16Ext(), publicAPI.useHalfFloat());
|
|
721
728
|
publicAPI.deactivate();
|
|
722
729
|
return true;
|
|
723
730
|
};
|
|
@@ -795,7 +802,7 @@ function vtkOpenGLTexture(publicAPI, model) {
|
|
|
795
802
|
h /= 2;
|
|
796
803
|
}
|
|
797
804
|
}
|
|
798
|
-
model.allocatedGPUMemoryInBytes = model.width * model.height * model.depth * numComps * model._openGLRenderWindow.getDefaultTextureByteSize(dataType,
|
|
805
|
+
model.allocatedGPUMemoryInBytes = model.width * model.height * model.depth * numComps * model._openGLRenderWindow.getDefaultTextureByteSize(dataType, getNorm16Ext(), publicAPI.useHalfFloat());
|
|
799
806
|
// generateMipmap must not be called here because we manually upload all levels
|
|
800
807
|
// if it is called, all levels will be overwritten
|
|
801
808
|
|
|
@@ -845,7 +852,7 @@ function vtkOpenGLTexture(publicAPI, model) {
|
|
|
845
852
|
if (model.generateMipmap) {
|
|
846
853
|
model.context.generateMipmap(model.target);
|
|
847
854
|
}
|
|
848
|
-
model.allocatedGPUMemoryInBytes = model.width * model.height * model.depth * model.components * model._openGLRenderWindow.getDefaultTextureByteSize(dataType,
|
|
855
|
+
model.allocatedGPUMemoryInBytes = model.width * model.height * model.depth * model.components * model._openGLRenderWindow.getDefaultTextureByteSize(dataType, getNorm16Ext(), publicAPI.useHalfFloat());
|
|
849
856
|
publicAPI.deactivate();
|
|
850
857
|
return true;
|
|
851
858
|
};
|
|
@@ -895,7 +902,7 @@ function vtkOpenGLTexture(publicAPI, model) {
|
|
|
895
902
|
if (model.generateMipmap) {
|
|
896
903
|
model.context.generateMipmap(model.target);
|
|
897
904
|
}
|
|
898
|
-
model.allocatedGPUMemoryInBytes = model.width * model.height * model.depth * model.components * model._openGLRenderWindow.getDefaultTextureByteSize(VtkDataTypes.UNSIGNED_CHAR,
|
|
905
|
+
model.allocatedGPUMemoryInBytes = model.width * model.height * model.depth * model.components * model._openGLRenderWindow.getDefaultTextureByteSize(VtkDataTypes.UNSIGNED_CHAR, getNorm16Ext(), publicAPI.useHalfFloat());
|
|
899
906
|
publicAPI.deactivate();
|
|
900
907
|
return true;
|
|
901
908
|
};
|
|
@@ -1013,7 +1020,7 @@ function vtkOpenGLTexture(publicAPI, model) {
|
|
|
1013
1020
|
}
|
|
1014
1021
|
|
|
1015
1022
|
// Handle SHORT data type with EXT_texture_norm16 extension
|
|
1016
|
-
if (
|
|
1023
|
+
if (getNorm16Ext() && !useHalfFloat && dataType === VtkDataTypes.SHORT) {
|
|
1017
1024
|
for (let c = 0; c < numComps; ++c) {
|
|
1018
1025
|
model.volumeInfo.scale[c] = 32767.0; // Scale to [-1, 1] range
|
|
1019
1026
|
}
|
|
@@ -1022,7 +1029,7 @@ function vtkOpenGLTexture(publicAPI, model) {
|
|
|
1022
1029
|
}
|
|
1023
1030
|
|
|
1024
1031
|
// Handle UNSIGNED_SHORT data type with EXT_texture_norm16 extension
|
|
1025
|
-
if (
|
|
1032
|
+
if (getNorm16Ext() && !useHalfFloat && dataType === VtkDataTypes.UNSIGNED_SHORT) {
|
|
1026
1033
|
for (let c = 0; c < numComps; ++c) {
|
|
1027
1034
|
model.volumeInfo.scale[c] = 65535.0; // Scale to [0, 1] range
|
|
1028
1035
|
}
|
|
@@ -1112,7 +1119,7 @@ function vtkOpenGLTexture(publicAPI, model) {
|
|
|
1112
1119
|
if (model.generateMipmap) {
|
|
1113
1120
|
model.context.generateMipmap(model.target);
|
|
1114
1121
|
}
|
|
1115
|
-
model.allocatedGPUMemoryInBytes = model.width * model.height * model.depth * model.components * model._openGLRenderWindow.getDefaultTextureByteSize(dataTypeToUse,
|
|
1122
|
+
model.allocatedGPUMemoryInBytes = model.width * model.height * model.depth * model.components * model._openGLRenderWindow.getDefaultTextureByteSize(dataTypeToUse, getNorm16Ext(), publicAPI.useHalfFloat());
|
|
1116
1123
|
publicAPI.deactivate();
|
|
1117
1124
|
return true;
|
|
1118
1125
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { m as macro } from '../../../macros2.js';
|
|
2
2
|
import { k as add } from '../../../Common/Core/Math/index.js';
|
|
3
|
+
import vtkBoundingBox from '../../../Common/DataModel/BoundingBox.js';
|
|
3
4
|
import vtkPointPicker from '../../../Rendering/Core/PointPicker.js';
|
|
4
5
|
|
|
5
6
|
const MAX_POINTS = 3;
|
|
@@ -8,6 +9,7 @@ function widgetBehavior(publicAPI, model) {
|
|
|
8
9
|
model._isDragging = false;
|
|
9
10
|
const picker = vtkPointPicker.newInstance();
|
|
10
11
|
picker.setPickFromList(1);
|
|
12
|
+
publicAPI.getBounds = () => model.widgetState.getHandleList().reduce((bounds, handle) => vtkBoundingBox.inflate(vtkBoundingBox.addPoint(bounds, ...handle.getOrigin()), publicAPI.getScaleInPixels() ? 0 : handle.getScale1() / 2), [...vtkBoundingBox.INIT_BOUNDS]);
|
|
11
13
|
|
|
12
14
|
// --------------------------------------------------------------------------
|
|
13
15
|
// Display 2D
|
|
@@ -2,7 +2,7 @@ import { m as macro } from '../../macros2.js';
|
|
|
2
2
|
import vtkAbstractWidgetFactory from '../Core/AbstractWidgetFactory.js';
|
|
3
3
|
import vtkConvexFaceContextRepresentation from '../Representations/ConvexFaceContextRepresentation.js';
|
|
4
4
|
import widgetBehavior from './InteractiveOrientationWidget/behavior.js';
|
|
5
|
-
import {
|
|
5
|
+
import { INITIAL_POINTS, generateState } from './InteractiveOrientationWidget/state.js';
|
|
6
6
|
import { Behavior } from '../Representations/WidgetRepresentation/Constants.js';
|
|
7
7
|
import { ViewTypes } from '../Core/WidgetManager/Constants.js';
|
|
8
8
|
|