@kitware/vtk.js 26.8.2 → 26.9.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/BREAKING_CHANGES.md +6 -1
- package/Common/Core/DataArray.js +9 -10
- package/Common/Core/ScalarsToColors.d.ts +9 -1
- package/Common/Core/ScalarsToColors.js +22 -0
- package/Rendering/Core/Mapper.js +10 -1
- package/Rendering/OpenGL/Actor.js +12 -2
- package/Rendering/OpenGL/Camera.js +1 -0
- package/Rendering/OpenGL/ForwardPass.js +6 -3
- package/Rendering/OpenGL/ImageMapper.js +5 -1
- package/Rendering/OpenGL/ImageSlice.js +17 -1
- package/Rendering/OpenGL/OrderIndependentTranslucentPass.js +1 -0
- package/Rendering/OpenGL/PolyDataMapper.js +5 -1
- package/Rendering/OpenGL/RenderWindow.js +24 -8
- package/Rendering/OpenGL/Renderer.js +5 -1
- package/Rendering/OpenGL/VolumeMapper.js +5 -1
- package/Widgets/Core/AbstractWidget.js +1 -5
- package/Widgets/Core/AbstractWidgetFactory.d.ts +5 -0
- package/Widgets/Core/AbstractWidgetFactory.js +4 -0
- package/Widgets/Core/StateBuilder/color3Mixin.js +3 -1
- package/Widgets/Core/StateBuilder/originMixin.js +34 -3
- package/Widgets/Core/WidgetManager.d.ts +8 -0
- package/Widgets/Core/WidgetManager.js +27 -5
- package/Widgets/Representations/CroppingOutlineRepresentation.js +1 -1
- package/Widgets/Representations/GlyphRepresentation.js +10 -5
- package/Widgets/Representations/ImplicitPlaneRepresentation.js +2 -1
- package/Widgets/Representations/PolyLineRepresentation.js +2 -1
- package/Widgets/Representations/WidgetRepresentation.js +3 -26
- package/Widgets/Widgets3D/ResliceCursorWidget/behavior.js +19 -7
- package/Widgets/Widgets3D/ResliceCursorWidget/helpers.js +9 -20
- package/Widgets/Widgets3D/ResliceCursorWidget/state.js +2 -23
- package/Widgets/Widgets3D/ResliceCursorWidget.js +40 -39
- package/package.json +1 -1
package/BREAKING_CHANGES.md
CHANGED
|
@@ -3,7 +3,12 @@
|
|
|
3
3
|
- **ResliceCursorWidget**: vtkResliceCursorContextRepresentation is deprecated and removed.
|
|
4
4
|
Instead, a `vtkSphereHandleRepresentation` is used for `rotation` and `center` handles,
|
|
5
5
|
and a `vtkLineHandleRepresenttion` is used for the axes. `rotateLineInView()` now
|
|
6
|
-
takes an axis name (string, e.g. 'XinY') instead of a substate.
|
|
6
|
+
takes an axis name (string, e.g. 'XinY') instead of a substate. `enableRotation`, `enableTranslation` and `keepOrthogonality` in widgetState are replaced by widget behavior accessors (e.g. `widgetInView.setEnableRotation(false)`). See RCW example.
|
|
7
|
+
- `widgetState.setShowCenter()` is replaced by `widgetState.getCenterHandle.setVisible()`
|
|
8
|
+
- `widgetState.setSphereRadius()` is replaced by `widgetState.getCenterHandle().setScale1()` and `widgetState.getStatesWithLabel('rotation').forEach((handle) => handle.setScale1())`
|
|
9
|
+
- `widgetState.setLineThickness(t)` is replaced by `widgetState.getStatesWithLabel('line').forEach((handle) => handle.setScale3(t,t,t))`
|
|
10
|
+
- `setScaleInPixels()` should now be set on the widget instead of the `widgetInView`.
|
|
11
|
+
- `widgetState.setOpacity()` is replaced by `widgetState.getStatesWithLabel('handles').forEach((handle) => handle.setOpacity())`
|
|
7
12
|
- SVGRepresentation and SVG widget support has been fully removed.
|
|
8
13
|
|
|
9
14
|
## From 24.x to 25
|
package/Common/Core/DataArray.js
CHANGED
|
@@ -161,18 +161,12 @@ var STATIC = {
|
|
|
161
161
|
function vtkDataArray(publicAPI, model) {
|
|
162
162
|
// Set our className
|
|
163
163
|
model.classHierarchy.push('vtkDataArray');
|
|
164
|
-
|
|
165
|
-
function dataChange() {
|
|
166
|
-
model.ranges = null;
|
|
167
|
-
publicAPI.modified();
|
|
168
|
-
}
|
|
169
164
|
/**
|
|
170
165
|
* Resize model.values and copy the old values to the new array.
|
|
171
166
|
* @param {Number} requestedNumTuples Final expected number of tuples; must be >= 0
|
|
172
167
|
* @returns {Boolean} True if a resize occured, false otherwise
|
|
173
168
|
*/
|
|
174
169
|
|
|
175
|
-
|
|
176
170
|
function resize(requestedNumTuples) {
|
|
177
171
|
if (requestedNumTuples < 0) {
|
|
178
172
|
return false;
|
|
@@ -198,19 +192,24 @@ function vtkDataArray(publicAPI, model) {
|
|
|
198
192
|
|
|
199
193
|
if (model.size > requestedNumTuples * numComps) {
|
|
200
194
|
model.size = requestedNumTuples * numComps;
|
|
201
|
-
dataChange();
|
|
195
|
+
publicAPI.dataChange();
|
|
202
196
|
}
|
|
203
197
|
|
|
204
198
|
return true;
|
|
205
199
|
}
|
|
206
200
|
|
|
201
|
+
publicAPI.dataChange = function () {
|
|
202
|
+
model.ranges = null;
|
|
203
|
+
publicAPI.modified();
|
|
204
|
+
};
|
|
205
|
+
|
|
207
206
|
publicAPI.resize = function (requestedNumTuples) {
|
|
208
207
|
resize(requestedNumTuples);
|
|
209
208
|
var newSize = requestedNumTuples * publicAPI.getNumberOfComponents();
|
|
210
209
|
|
|
211
210
|
if (model.size !== newSize) {
|
|
212
211
|
model.size = newSize;
|
|
213
|
-
dataChange();
|
|
212
|
+
publicAPI.dataChange();
|
|
214
213
|
return true;
|
|
215
214
|
}
|
|
216
215
|
|
|
@@ -243,7 +242,7 @@ function vtkDataArray(publicAPI, model) {
|
|
|
243
242
|
publicAPI.setComponent = function (tupleIdx, compIdx, value) {
|
|
244
243
|
if (value !== model.values[tupleIdx * model.numberOfComponents + compIdx]) {
|
|
245
244
|
model.values[tupleIdx * model.numberOfComponents + compIdx] = value;
|
|
246
|
-
dataChange();
|
|
245
|
+
publicAPI.dataChange();
|
|
247
246
|
}
|
|
248
247
|
};
|
|
249
248
|
|
|
@@ -448,7 +447,7 @@ function vtkDataArray(publicAPI, model) {
|
|
|
448
447
|
model.numberOfComponents = 1;
|
|
449
448
|
}
|
|
450
449
|
|
|
451
|
-
dataChange();
|
|
450
|
+
publicAPI.dataChange();
|
|
452
451
|
}; // Override serialization support
|
|
453
452
|
|
|
454
453
|
|
|
@@ -124,10 +124,18 @@ export interface vtkScalarsToColors extends vtkObject {
|
|
|
124
124
|
getVectorSize(): number;
|
|
125
125
|
|
|
126
126
|
/**
|
|
127
|
-
*
|
|
127
|
+
* @see areScalarsOpaque
|
|
128
128
|
*/
|
|
129
129
|
isOpaque(): boolean;
|
|
130
130
|
|
|
131
|
+
/**
|
|
132
|
+
* Returns false if scalars are Uint8 LA or RGBA with A < 255,
|
|
133
|
+
* otherwise rely on getAlpha() in case of direct mapping,
|
|
134
|
+
* otherwise return isOpaque()
|
|
135
|
+
* @see isOpaque, getAlpha
|
|
136
|
+
*/
|
|
137
|
+
areScalarsOpaque(scalars, colorMode, componentIn): boolean;
|
|
138
|
+
|
|
131
139
|
/**
|
|
132
140
|
*
|
|
133
141
|
* @param newColors
|
|
@@ -504,6 +504,28 @@ function vtkScalarsToColors(publicAPI, model) {
|
|
|
504
504
|
publicAPI.getRange = function () {
|
|
505
505
|
return publicAPI.getMappingRange();
|
|
506
506
|
};
|
|
507
|
+
|
|
508
|
+
publicAPI.areScalarsOpaque = function (scalars, colorMode, componentIn) {
|
|
509
|
+
if (!scalars) {
|
|
510
|
+
return publicAPI.isOpaque();
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
var numberOfComponents = scalars.getNumberOfComponents(); // map scalars through lookup table only if needed
|
|
514
|
+
|
|
515
|
+
if (colorMode === ColorMode.DEFAULT && scalars.getDataType() === VtkDataTypes.UNSIGNED_CHAR || colorMode === ColorMode.DIRECT_SCALARS) {
|
|
516
|
+
// we will be using the scalars directly, so look at the number of
|
|
517
|
+
// components and the range
|
|
518
|
+
if (numberOfComponents === 3 || numberOfComponents === 1) {
|
|
519
|
+
return model.alpha >= 1.0;
|
|
520
|
+
} // otherwise look at the range of the alpha channel
|
|
521
|
+
|
|
522
|
+
|
|
523
|
+
var range = scalars.getRange(numberOfComponents - 1);
|
|
524
|
+
return range[0] === 255;
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
return true;
|
|
528
|
+
};
|
|
507
529
|
} // ----------------------------------------------------------------------------
|
|
508
530
|
// Object factory
|
|
509
531
|
// ----------------------------------------------------------------------------
|
package/Rendering/Core/Mapper.js
CHANGED
|
@@ -375,12 +375,21 @@ function vtkMapper(publicAPI, model) {
|
|
|
375
375
|
};
|
|
376
376
|
|
|
377
377
|
publicAPI.getIsOpaque = function () {
|
|
378
|
+
var input = publicAPI.getInputData();
|
|
379
|
+
var gasResult = publicAPI.getAbstractScalars(input, model.scalarMode, model.arrayAccessMode, model.arrayId, model.colorByArrayName);
|
|
380
|
+
var scalars = gasResult.scalars;
|
|
381
|
+
|
|
382
|
+
if (!model.scalarVisibility || scalars == null) {
|
|
383
|
+
// No scalar colors.
|
|
384
|
+
return true;
|
|
385
|
+
}
|
|
386
|
+
|
|
378
387
|
var lut = publicAPI.getLookupTable();
|
|
379
388
|
|
|
380
389
|
if (lut) {
|
|
381
390
|
// Ensure that the lookup table is built
|
|
382
391
|
lut.build();
|
|
383
|
-
return lut.
|
|
392
|
+
return lut.areScalarsOpaque(scalars, model.colorMode, -1);
|
|
384
393
|
}
|
|
385
394
|
|
|
386
395
|
return true;
|
|
@@ -37,9 +37,10 @@ function vtkOpenGLActor(publicAPI, model) {
|
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
|
-
};
|
|
40
|
+
}; // render both opaque and translucent actors
|
|
41
41
|
|
|
42
|
-
|
|
42
|
+
|
|
43
|
+
publicAPI.traverseZBufferPass = function (renderPass) {
|
|
43
44
|
if (!model.renderable || !model.renderable.getNestedVisibility() || model._openGLRenderer.getSelector() && !model.renderable.getNestedPickable()) {
|
|
44
45
|
return;
|
|
45
46
|
}
|
|
@@ -47,6 +48,11 @@ function vtkOpenGLActor(publicAPI, model) {
|
|
|
47
48
|
publicAPI.apply(renderPass, true);
|
|
48
49
|
model.oglmapper.traverse(renderPass);
|
|
49
50
|
publicAPI.apply(renderPass, false);
|
|
51
|
+
}; // only render opaque actors
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
publicAPI.traverseOpaqueZBufferPass = function (renderPass) {
|
|
55
|
+
return publicAPI.traverseOpaquePass(renderPass);
|
|
50
56
|
}; // we draw textures, then mapper, then post pass textures
|
|
51
57
|
|
|
52
58
|
|
|
@@ -103,6 +109,10 @@ function vtkOpenGLActor(publicAPI, model) {
|
|
|
103
109
|
}
|
|
104
110
|
};
|
|
105
111
|
|
|
112
|
+
publicAPI.zBufferPass = function (prepass, renderPass) {
|
|
113
|
+
return publicAPI.opaquePass(prepass, renderPass);
|
|
114
|
+
};
|
|
115
|
+
|
|
106
116
|
publicAPI.opaqueZBufferPass = function (prepass, renderPass) {
|
|
107
117
|
return publicAPI.opaquePass(prepass, renderPass);
|
|
108
118
|
};
|
|
@@ -40,7 +40,7 @@ function vtkForwardPass(publicAPI, model) {
|
|
|
40
40
|
publicAPI.setCurrentOperation('queryPass');
|
|
41
41
|
renNode.traverse(publicAPI); // do we need to capture a zbuffer?
|
|
42
42
|
|
|
43
|
-
if (model.opaqueActorCount > 0 && model.volumeCount > 0 || model.depthRequested) {
|
|
43
|
+
if ((model.opaqueActorCount > 0 || model.translucentActorCount > 0) && model.volumeCount > 0 || model.depthRequested) {
|
|
44
44
|
var size = viewNode.getFramebufferSize(); // make sure the framebuffer is setup
|
|
45
45
|
|
|
46
46
|
if (model.framebuffer === null) {
|
|
@@ -56,8 +56,11 @@ function vtkForwardPass(publicAPI, model) {
|
|
|
56
56
|
model.framebuffer.populateFramebuffer();
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
-
model.framebuffer.bind();
|
|
60
|
-
|
|
59
|
+
model.framebuffer.bind(); // opaqueZBufferPass only renders opaque actors
|
|
60
|
+
// zBufferPass renders both translucent and opaque actors
|
|
61
|
+
// we want to be able to pick translucent actors
|
|
62
|
+
|
|
63
|
+
publicAPI.setCurrentOperation('zBufferPass');
|
|
61
64
|
renNode.traverse(publicAPI);
|
|
62
65
|
model.framebuffer.restorePreviousBindingsAndBuffers(); // reset now that we have done it
|
|
63
66
|
|
|
@@ -68,7 +68,7 @@ function vtkOpenGLImageMapper(publicAPI, model) {
|
|
|
68
68
|
}
|
|
69
69
|
};
|
|
70
70
|
|
|
71
|
-
publicAPI.
|
|
71
|
+
publicAPI.zBufferPass = function (prepass) {
|
|
72
72
|
if (prepass) {
|
|
73
73
|
model.haveSeenDepthRequest = true;
|
|
74
74
|
model.renderDepth = true;
|
|
@@ -77,6 +77,10 @@ function vtkOpenGLImageMapper(publicAPI, model) {
|
|
|
77
77
|
}
|
|
78
78
|
};
|
|
79
79
|
|
|
80
|
+
publicAPI.opaqueZBufferPass = function (prepass) {
|
|
81
|
+
return publicAPI.zBufferPass(prepass);
|
|
82
|
+
};
|
|
83
|
+
|
|
80
84
|
publicAPI.opaquePass = function (prepass) {
|
|
81
85
|
if (prepass) {
|
|
82
86
|
publicAPI.render();
|
|
@@ -29,8 +29,20 @@ function vtkOpenGLImageSlice(publicAPI, model) {
|
|
|
29
29
|
}
|
|
30
30
|
};
|
|
31
31
|
|
|
32
|
+
publicAPI.traverseZBufferPass = function (renderPass) {
|
|
33
|
+
if (!model.renderable || !model.renderable.getNestedVisibility() || model._openGLRenderer.getSelector() && !model.renderable.getNestedPickable()) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
publicAPI.apply(renderPass, true);
|
|
38
|
+
model.children.forEach(function (child) {
|
|
39
|
+
child.traverse(renderPass);
|
|
40
|
+
});
|
|
41
|
+
publicAPI.apply(renderPass, false);
|
|
42
|
+
};
|
|
43
|
+
|
|
32
44
|
publicAPI.traverseOpaqueZBufferPass = function (renderPass) {
|
|
33
|
-
publicAPI.traverseOpaquePass(renderPass);
|
|
45
|
+
return publicAPI.traverseOpaquePass(renderPass);
|
|
34
46
|
}; // we draw textures, then mapper, then post pass textures
|
|
35
47
|
|
|
36
48
|
|
|
@@ -73,6 +85,10 @@ function vtkOpenGLImageSlice(publicAPI, model) {
|
|
|
73
85
|
}
|
|
74
86
|
};
|
|
75
87
|
|
|
88
|
+
publicAPI.zBufferPass = function (prepass, renderPass) {
|
|
89
|
+
return publicAPI.opaquePass(prepass, renderPass);
|
|
90
|
+
};
|
|
91
|
+
|
|
76
92
|
publicAPI.opaqueZBufferPass = function (prepass, renderPass) {
|
|
77
93
|
return publicAPI.opaquePass(prepass, renderPass);
|
|
78
94
|
}; // Renders myself
|
|
@@ -151,6 +151,7 @@ function vtkOpenGLOrderIndependentTranslucentPass(publicAPI, model) {
|
|
|
151
151
|
// have the forward pass use a texture backed zbuffer
|
|
152
152
|
|
|
153
153
|
if (forwardPass.getOpaqueActorCount() > 0) {
|
|
154
|
+
// Don't use zBufferPass as it will also render the depth of translucent actors
|
|
154
155
|
forwardPass.setCurrentOperation('opaqueZBufferPass');
|
|
155
156
|
renNode.traverse(forwardPass);
|
|
156
157
|
}
|
|
@@ -72,7 +72,7 @@ function vtkOpenGLPolyDataMapper(publicAPI, model) {
|
|
|
72
72
|
}
|
|
73
73
|
};
|
|
74
74
|
|
|
75
|
-
publicAPI.
|
|
75
|
+
publicAPI.zBufferPass = function (prepass) {
|
|
76
76
|
if (prepass) {
|
|
77
77
|
model.haveSeenDepthRequest = true;
|
|
78
78
|
model.renderDepth = true;
|
|
@@ -81,6 +81,10 @@ function vtkOpenGLPolyDataMapper(publicAPI, model) {
|
|
|
81
81
|
}
|
|
82
82
|
};
|
|
83
83
|
|
|
84
|
+
publicAPI.opaqueZBufferPass = function (prepass) {
|
|
85
|
+
return publicAPI.zBufferPass(prepass);
|
|
86
|
+
};
|
|
87
|
+
|
|
84
88
|
publicAPI.opaquePass = function (prepass) {
|
|
85
89
|
if (prepass) {
|
|
86
90
|
publicAPI.render();
|
|
@@ -911,7 +911,26 @@ function vtkOpenGLRenderWindow(publicAPI, model) {
|
|
|
911
911
|
model.canvas.removeEventListener('webglcontextrestored', publicAPI.restoreContext);
|
|
912
912
|
}
|
|
913
913
|
|
|
914
|
-
publicAPI.delete = macro.chain(clearEvents, publicAPI.delete, publicAPI.setViewStream, deleteGLContext);
|
|
914
|
+
publicAPI.delete = macro.chain(clearEvents, publicAPI.delete, publicAPI.setViewStream, deleteGLContext); // Do not trigger modified for performance reasons
|
|
915
|
+
|
|
916
|
+
publicAPI.setActiveFramebuffer = function (newActiveFramebuffer) {
|
|
917
|
+
model.activeFramebuffer = newActiveFramebuffer;
|
|
918
|
+
};
|
|
919
|
+
|
|
920
|
+
var superSetSize = publicAPI.setSize;
|
|
921
|
+
|
|
922
|
+
publicAPI.setSize = function (width, height) {
|
|
923
|
+
var modified = superSetSize(width, height);
|
|
924
|
+
|
|
925
|
+
if (modified) {
|
|
926
|
+
publicAPI.invokeWindowResizeEvent({
|
|
927
|
+
width: width,
|
|
928
|
+
height: height
|
|
929
|
+
});
|
|
930
|
+
}
|
|
931
|
+
|
|
932
|
+
return modified;
|
|
933
|
+
};
|
|
915
934
|
} // ----------------------------------------------------------------------------
|
|
916
935
|
// Object factory
|
|
917
936
|
// ----------------------------------------------------------------------------
|
|
@@ -979,13 +998,10 @@ function extend(publicAPI, model) {
|
|
|
979
998
|
macro.event(publicAPI, model, 'imageReady');
|
|
980
999
|
macro.event(publicAPI, model, 'haveVRDisplay'); // Build VTK API
|
|
981
1000
|
|
|
982
|
-
macro.get(publicAPI, model, ['shaderCache', 'textureUnitManager', 'webgl2', 'vrDisplay', 'useBackgroundImage', 'xrSupported']);
|
|
983
|
-
macro.setGet(publicAPI, model, ['initialized', 'context', 'canvas', 'renderPasses', 'notifyStartCaptureImage', 'defaultToWebgl2', 'cursor', 'useOffScreen'
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
// of the buffer has changed
|
|
987
|
-
'activeFramebuffer']);
|
|
988
|
-
macro.setGetArray(publicAPI, model, ['size'], 2); // Object methods
|
|
1001
|
+
macro.get(publicAPI, model, ['shaderCache', 'textureUnitManager', 'webgl2', 'vrDisplay', 'useBackgroundImage', 'xrSupported', 'activeFramebuffer']);
|
|
1002
|
+
macro.setGet(publicAPI, model, ['initialized', 'context', 'canvas', 'renderPasses', 'notifyStartCaptureImage', 'defaultToWebgl2', 'cursor', 'useOffScreen']);
|
|
1003
|
+
macro.setGetArray(publicAPI, model, ['size'], 2);
|
|
1004
|
+
macro.event(publicAPI, model, 'windowResizeEvent'); // Object methods
|
|
989
1005
|
|
|
990
1006
|
vtkOpenGLRenderWindow(publicAPI, model);
|
|
991
1007
|
} // ----------------------------------------------------------------------------
|
|
@@ -44,7 +44,7 @@ function vtkOpenGLRenderer(publicAPI, model) {
|
|
|
44
44
|
return count;
|
|
45
45
|
};
|
|
46
46
|
|
|
47
|
-
publicAPI.
|
|
47
|
+
publicAPI.zBufferPass = function (prepass) {
|
|
48
48
|
if (prepass) {
|
|
49
49
|
var clearMask = 0;
|
|
50
50
|
var gl = model.context;
|
|
@@ -72,6 +72,10 @@ function vtkOpenGLRenderer(publicAPI, model) {
|
|
|
72
72
|
|
|
73
73
|
gl.enable(gl.DEPTH_TEST);
|
|
74
74
|
}
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
publicAPI.opaqueZBufferPass = function (prepass) {
|
|
78
|
+
return publicAPI.zBufferPass(prepass);
|
|
75
79
|
}; // Renders myself
|
|
76
80
|
|
|
77
81
|
|
|
@@ -52,7 +52,7 @@ function vtkOpenGLVolumeMapper(publicAPI, model) {
|
|
|
52
52
|
// intermixed volume rendering
|
|
53
53
|
|
|
54
54
|
|
|
55
|
-
publicAPI.
|
|
55
|
+
publicAPI.zBufferPass = function (prepass, renderPass) {
|
|
56
56
|
if (prepass) {
|
|
57
57
|
var zbt = renderPass.getZBufferTexture();
|
|
58
58
|
|
|
@@ -60,6 +60,10 @@ function vtkOpenGLVolumeMapper(publicAPI, model) {
|
|
|
60
60
|
model.zBufferTexture = zbt;
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
publicAPI.opaqueZBufferPass = function (prepass, renderPass) {
|
|
66
|
+
return publicAPI.zBufferPass(prepass, renderPass);
|
|
63
67
|
}; // Renders myself
|
|
64
68
|
|
|
65
69
|
|
|
@@ -87,11 +87,7 @@ function vtkAbstractWidget(publicAPI, model) {
|
|
|
87
87
|
};
|
|
88
88
|
|
|
89
89
|
publicAPI.getViewWidgets = function () {
|
|
90
|
-
return model._factory.
|
|
91
|
-
return model._factory.getWidgetForView({
|
|
92
|
-
viewId: viewId
|
|
93
|
-
});
|
|
94
|
-
});
|
|
90
|
+
return model._factory.getViewWidgets();
|
|
95
91
|
}; // --------------------------------------------------------------------------
|
|
96
92
|
// Initialization calls
|
|
97
93
|
// --------------------------------------------------------------------------
|
|
@@ -27,6 +27,11 @@ export interface vtkAbstractWidgetFactory {
|
|
|
27
27
|
*/
|
|
28
28
|
getViewIds(): string[];
|
|
29
29
|
|
|
30
|
+
/**
|
|
31
|
+
* Get a list of all the instances of the widget.
|
|
32
|
+
*/
|
|
33
|
+
getViewWidgets(): vtkAbstractWidget[];
|
|
34
|
+
|
|
30
35
|
/**
|
|
31
36
|
* Set the visiblity on each underlying view widget.
|
|
32
37
|
*
|
|
@@ -121,6 +121,10 @@ function vtkAbstractWidgetFactory(publicAPI, model) {
|
|
|
121
121
|
|
|
122
122
|
publicAPI.getViewIds = function () {
|
|
123
123
|
return Object.keys(viewToWidget);
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
publicAPI.getViewWidgets = function () {
|
|
127
|
+
return Object.values(viewToWidget);
|
|
124
128
|
}; // --------------------------------------------------------------------------
|
|
125
129
|
// Widget visibility / enable
|
|
126
130
|
// --------------------------------------------------------------------------
|
|
@@ -6,13 +6,15 @@ import macro from '../../../macros.js';
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
var DEFAULT_VALUES = {
|
|
9
|
-
color3: [255, 255, 255]
|
|
9
|
+
color3: [255, 255, 255],
|
|
10
|
+
opacity: 255
|
|
10
11
|
}; // ----------------------------------------------------------------------------
|
|
11
12
|
|
|
12
13
|
function extend(publicAPI, model) {
|
|
13
14
|
var initialValues = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
14
15
|
Object.assign(model, DEFAULT_VALUES, initialValues);
|
|
15
16
|
macro.setGetArray(publicAPI, model, ['color3'], 3, 255);
|
|
17
|
+
macro.setGet(publicAPI, model, ['opacity']);
|
|
16
18
|
} // ----------------------------------------------------------------------------
|
|
17
19
|
|
|
18
20
|
var color3 = {
|
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
import _slicedToArray from '@babel/runtime/helpers/slicedToArray';
|
|
2
|
+
import _defineProperty from '@babel/runtime/helpers/defineProperty';
|
|
2
3
|
import macro from '../../../macros.js';
|
|
4
|
+
import { f as vtkMath } from '../../../Common/Core/Math/index.js';
|
|
5
|
+
import { getPixelWorldHeightAtCoord } from '../WidgetManager.js';
|
|
6
|
+
|
|
7
|
+
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
8
|
+
|
|
9
|
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
3
10
|
|
|
4
11
|
function vtkOriginMixin(publicAPI, model) {
|
|
12
|
+
var superClass = _objectSpread({}, publicAPI);
|
|
13
|
+
|
|
5
14
|
publicAPI.translate = function (dx, dy, dz) {
|
|
6
15
|
var _publicAPI$getOriginB = publicAPI.getOriginByReference(),
|
|
7
16
|
_publicAPI$getOriginB2 = _slicedToArray(_publicAPI$getOriginB, 3),
|
|
@@ -11,18 +20,40 @@ function vtkOriginMixin(publicAPI, model) {
|
|
|
11
20
|
|
|
12
21
|
publicAPI.setOrigin(x + dx, y + dy, z + dz);
|
|
13
22
|
};
|
|
23
|
+
|
|
24
|
+
publicAPI.getOrigin = function (displayScaleParams) {
|
|
25
|
+
var origin = superClass.getOrigin();
|
|
26
|
+
|
|
27
|
+
if (!model.offset) {
|
|
28
|
+
return origin;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (!displayScaleParams) {
|
|
32
|
+
return vtkMath.add(origin, model.offset, origin);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
var pixelWorldHeight = getPixelWorldHeightAtCoord(origin, displayScaleParams);
|
|
36
|
+
var rendererPixelDims = displayScaleParams.rendererPixelDims;
|
|
37
|
+
var totalSize = Math.min(rendererPixelDims[0], rendererPixelDims[1]);
|
|
38
|
+
return vtkMath.multiplyAccumulate(origin, model.offset, totalSize * pixelWorldHeight, origin);
|
|
39
|
+
};
|
|
14
40
|
} // ----------------------------------------------------------------------------
|
|
15
41
|
|
|
42
|
+
/**
|
|
43
|
+
* offset: optional offset that can be scaled to pixel screen space.
|
|
44
|
+
*/
|
|
45
|
+
|
|
16
46
|
|
|
17
47
|
var DEFAULT_VALUES = {
|
|
18
|
-
origin: null
|
|
48
|
+
origin: null,
|
|
49
|
+
offset: null
|
|
19
50
|
}; // ----------------------------------------------------------------------------
|
|
20
51
|
|
|
21
52
|
function extend(publicAPI, model) {
|
|
22
53
|
var initialValues = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
23
54
|
Object.assign(model, DEFAULT_VALUES, initialValues);
|
|
24
|
-
macro.setGetArray(publicAPI, model, ['origin'], 3);
|
|
25
|
-
vtkOriginMixin(publicAPI);
|
|
55
|
+
macro.setGetArray(publicAPI, model, ['origin', 'offset'], 3);
|
|
56
|
+
vtkOriginMixin(publicAPI, model);
|
|
26
57
|
} // ----------------------------------------------------------------------------
|
|
27
58
|
|
|
28
59
|
var origin = {
|
|
@@ -37,6 +37,14 @@ export interface IRenderingComponents {
|
|
|
37
37
|
*/
|
|
38
38
|
export function extractRenderingComponents(renderer: vtkRenderer): IRenderingComponents;
|
|
39
39
|
|
|
40
|
+
/**
|
|
41
|
+
* This method returns the world distance that corresponds to the height of a
|
|
42
|
+
* single display pixel at a given coordinate. For example, to determine the
|
|
43
|
+
* (vertical) distance that matches a display distance of 30px for a coordinate
|
|
44
|
+
* `coord`, you would compute `30 * getPixelWorldHeightAtCoord(coord)`.
|
|
45
|
+
*/
|
|
46
|
+
export function getPixelWorldHeightAtCoord(coord: []): Number;
|
|
47
|
+
|
|
40
48
|
export interface vtkWidgetManager extends vtkObject {
|
|
41
49
|
/**
|
|
42
50
|
* The the captureOn value.
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import _asyncToGenerator from '@babel/runtime/helpers/asyncToGenerator';
|
|
2
2
|
import _slicedToArray from '@babel/runtime/helpers/slicedToArray';
|
|
3
|
+
import _toConsumableArray from '@babel/runtime/helpers/toConsumableArray';
|
|
3
4
|
import _regeneratorRuntime from '@babel/runtime/regenerator';
|
|
4
|
-
import {
|
|
5
|
+
import { f as vtkMath } from '../../Common/Core/Math/index.js';
|
|
5
6
|
import { FieldAssociations } from '../../Common/DataModel/DataSet/Constants.js';
|
|
6
7
|
import macro from '../../macros.js';
|
|
7
8
|
import WidgetManagerConst from './WidgetManager/Constants.js';
|
|
@@ -28,6 +29,26 @@ function extractRenderingComponents(renderer) {
|
|
|
28
29
|
apiSpecificRenderWindow: apiSpecificRenderWindow,
|
|
29
30
|
camera: camera
|
|
30
31
|
};
|
|
32
|
+
}
|
|
33
|
+
function getPixelWorldHeightAtCoord(worldCoord, displayScaleParams) {
|
|
34
|
+
var dispHeightFactor = displayScaleParams.dispHeightFactor,
|
|
35
|
+
cameraPosition = displayScaleParams.cameraPosition,
|
|
36
|
+
cameraDir = displayScaleParams.cameraDir,
|
|
37
|
+
isParallel = displayScaleParams.isParallel,
|
|
38
|
+
rendererPixelDims = displayScaleParams.rendererPixelDims;
|
|
39
|
+
var scale = 1;
|
|
40
|
+
|
|
41
|
+
if (isParallel) {
|
|
42
|
+
scale = dispHeightFactor;
|
|
43
|
+
} else {
|
|
44
|
+
var worldCoordToCamera = _toConsumableArray(worldCoord);
|
|
45
|
+
|
|
46
|
+
vtkMath.subtract(worldCoordToCamera, cameraPosition, worldCoordToCamera);
|
|
47
|
+
scale = vtkMath.dot(worldCoordToCamera, cameraDir) * dispHeightFactor;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
var rHeight = rendererPixelDims[1];
|
|
51
|
+
return scale / rHeight;
|
|
31
52
|
} // ----------------------------------------------------------------------------
|
|
32
53
|
// vtkWidgetManager methods
|
|
33
54
|
// ----------------------------------------------------------------------------
|
|
@@ -98,7 +119,7 @@ function vtkWidgetManager(publicAPI, model) {
|
|
|
98
119
|
|
|
99
120
|
var isParallel = _camera.getParallelProjection();
|
|
100
121
|
|
|
101
|
-
var dispHeightFactor = isParallel ? 2 * _camera.getParallelScale() : 2 * Math.tan(radiansFromDegrees(_camera.getViewAngle()) / 2);
|
|
122
|
+
var dispHeightFactor = isParallel ? 2 * _camera.getParallelScale() : 2 * Math.tan(vtkMath.radiansFromDegrees(_camera.getViewAngle()) / 2);
|
|
102
123
|
model.widgets.forEach(function (w) {
|
|
103
124
|
w.getNestedProps().forEach(function (r) {
|
|
104
125
|
if (r.getScaleInPixels()) {
|
|
@@ -327,7 +348,7 @@ function vtkWidgetManager(publicAPI, model) {
|
|
|
327
348
|
|
|
328
349
|
model._selector.setFieldAssociation(FieldAssociations.FIELD_ASSOCIATION_POINTS);
|
|
329
350
|
|
|
330
|
-
subscriptions.push(model._apiSpecificRenderWindow.
|
|
351
|
+
subscriptions.push(model._apiSpecificRenderWindow.onWindowResizeEvent(updateDisplayScaleParams));
|
|
331
352
|
subscriptions.push(model._camera.onModified(updateDisplayScaleParams));
|
|
332
353
|
updateDisplayScaleParams();
|
|
333
354
|
subscriptions.push(model._interactor.onStartAnimation(function () {
|
|
@@ -622,7 +643,8 @@ var newInstance = macro.newInstance(extend, 'vtkWidgetManager'); // ------------
|
|
|
622
643
|
var vtkWidgetManager$1 = {
|
|
623
644
|
newInstance: newInstance,
|
|
624
645
|
extend: extend,
|
|
625
|
-
Constants: WidgetManagerConst
|
|
646
|
+
Constants: WidgetManagerConst,
|
|
647
|
+
getPixelWorldHeightAtCoord: getPixelWorldHeightAtCoord
|
|
626
648
|
};
|
|
627
649
|
|
|
628
|
-
export { vtkWidgetManager$1 as default, extend, extractRenderingComponents, newInstance };
|
|
650
|
+
export { vtkWidgetManager$1 as default, extend, extractRenderingComponents, getPixelWorldHeightAtCoord, newInstance };
|
|
@@ -28,7 +28,7 @@ function vtkCroppingOutlineRepresentation(publicAPI, model) {
|
|
|
28
28
|
mtime: 0
|
|
29
29
|
});
|
|
30
30
|
allocateArray(model.internalPolyData, 'lines', OUTLINE_ARRAY.length).getData().set(OUTLINE_ARRAY);
|
|
31
|
-
var applyOrigin = origin(); // --------------------------------------------------------------------------
|
|
31
|
+
var applyOrigin = origin(publicAPI, model); // --------------------------------------------------------------------------
|
|
32
32
|
// Generic rendering pipeline
|
|
33
33
|
// --------------------------------------------------------------------------
|
|
34
34
|
|
|
@@ -7,7 +7,8 @@ import vtkContextRepresentation from './ContextRepresentation.js';
|
|
|
7
7
|
import vtkSphereSource from '../../Filters/Sources/SphereSource.js';
|
|
8
8
|
import vtkPolyData from '../../Common/DataModel/PolyData.js';
|
|
9
9
|
import { ScalarMode } from '../../Rendering/Core/Mapper/Constants.js';
|
|
10
|
-
import
|
|
10
|
+
import { getPixelWorldHeightAtCoord } from '../Core/WidgetManager.js';
|
|
11
|
+
import vtkWidgetRepresentation, { allocateArray } from './WidgetRepresentation.js';
|
|
11
12
|
import { Behavior } from './WidgetRepresentation/Constants.js';
|
|
12
13
|
import { OrientationModes } from '../../Rendering/Core/Glyph3DMapper/Constants.js';
|
|
13
14
|
|
|
@@ -23,7 +24,7 @@ function origin(publicAPI, model) {
|
|
|
23
24
|
var j = 0;
|
|
24
25
|
|
|
25
26
|
for (var i = 0; i < states.length; ++i) {
|
|
26
|
-
var coord = states[i].getOrigin();
|
|
27
|
+
var coord = states[i].getOrigin(model.scaleInPixels && model.displayScaleParams);
|
|
27
28
|
points[j++] = coord[0];
|
|
28
29
|
points[j++] = coord[1];
|
|
29
30
|
points[j++] = coord[2];
|
|
@@ -39,8 +40,9 @@ function color3(publicAPI, model) {
|
|
|
39
40
|
return function (polyData, states) {
|
|
40
41
|
model._pipeline.mapper.setColorByArrayName('color');
|
|
41
42
|
|
|
42
|
-
var
|
|
43
|
-
|
|
43
|
+
var colorArray = allocateArray(polyData, 'color', states.length, 'Uint8Array', // RGBA
|
|
44
|
+
4);
|
|
45
|
+
var colors = colorArray.getData();
|
|
44
46
|
var j = 0;
|
|
45
47
|
|
|
46
48
|
for (var i = 0; i < states.length; ++i) {
|
|
@@ -53,7 +55,10 @@ function color3(publicAPI, model) {
|
|
|
53
55
|
colors[j++] = c3[0];
|
|
54
56
|
colors[j++] = c3[1];
|
|
55
57
|
colors[j++] = c3[2];
|
|
58
|
+
colors[j++] = states[i].getOpacity();
|
|
56
59
|
}
|
|
60
|
+
|
|
61
|
+
colorArray.dataChange();
|
|
57
62
|
};
|
|
58
63
|
}
|
|
59
64
|
function color(publicAPI, model) {
|
|
@@ -278,7 +283,7 @@ function defaultValues(publicAPI, model, initialValues) {
|
|
|
278
283
|
})
|
|
279
284
|
}, initialValues._pipeline),
|
|
280
285
|
applyMixin: _objectSpread({
|
|
281
|
-
origin: (_initialValues$applyM = (_initialValues$applyM2 = initialValues.applyMixin) === null || _initialValues$applyM2 === void 0 ? void 0 : _initialValues$applyM2.origin) !== null && _initialValues$applyM !== void 0 ? _initialValues$applyM : origin(),
|
|
286
|
+
origin: (_initialValues$applyM = (_initialValues$applyM2 = initialValues.applyMixin) === null || _initialValues$applyM2 === void 0 ? void 0 : _initialValues$applyM2.origin) !== null && _initialValues$applyM !== void 0 ? _initialValues$applyM : origin(publicAPI, model),
|
|
282
287
|
noPosition: (_initialValues$applyM3 = (_initialValues$applyM4 = initialValues.applyMixin) === null || _initialValues$applyM4 === void 0 ? void 0 : _initialValues$applyM4.noPosition) !== null && _initialValues$applyM3 !== void 0 ? _initialValues$applyM3 : noPosition(),
|
|
283
288
|
color3: (_initialValues$applyM5 = (_initialValues$applyM6 = initialValues.applyMixin) === null || _initialValues$applyM6 === void 0 ? void 0 : _initialValues$applyM6.color3) !== null && _initialValues$applyM5 !== void 0 ? _initialValues$applyM5 : color3(publicAPI, model),
|
|
284
289
|
color: (_initialValues$applyM7 = (_initialValues$applyM8 = initialValues.applyMixin) === null || _initialValues$applyM8 === void 0 ? void 0 : _initialValues$applyM8.color) !== null && _initialValues$applyM7 !== void 0 ? _initialValues$applyM7 : color(publicAPI, model),
|
|
@@ -11,7 +11,8 @@ import vtkPlane from '../../Common/DataModel/Plane.js';
|
|
|
11
11
|
import vtkPolyData from '../../Common/DataModel/PolyData.js';
|
|
12
12
|
import vtkSphereSource from '../../Filters/Sources/SphereSource.js';
|
|
13
13
|
import vtkStateBuilder from '../Core/StateBuilder.js';
|
|
14
|
-
import
|
|
14
|
+
import { getPixelWorldHeightAtCoord } from '../Core/WidgetManager.js';
|
|
15
|
+
import vtkWidgetRepresentation from './WidgetRepresentation.js';
|
|
15
16
|
import WidgetManagerConst from '../Core/WidgetManager/Constants.js';
|
|
16
17
|
import PropertyConst from '../../Rendering/Core/Property/Constants.js';
|
|
17
18
|
|
|
@@ -5,7 +5,8 @@ import vtkMapper from '../../Rendering/Core/Mapper.js';
|
|
|
5
5
|
import { B as areEquals } from '../../Common/Core/Math/index.js';
|
|
6
6
|
import vtkBoundingBox from '../../Common/DataModel/BoundingBox.js';
|
|
7
7
|
import vtkTubeFilter from '../../Filters/General/TubeFilter.js';
|
|
8
|
-
import
|
|
8
|
+
import { getPixelWorldHeightAtCoord } from '../Core/WidgetManager.js';
|
|
9
|
+
import vtkWidgetRepresentation, { allocateArray } from './WidgetRepresentation.js';
|
|
9
10
|
import { RenderingTypes } from '../Core/WidgetManager/Constants.js';
|
|
10
11
|
import vtkPolyData from '../../Common/DataModel/PolyData.js';
|
|
11
12
|
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import _defineProperty from '@babel/runtime/helpers/defineProperty';
|
|
2
|
-
import _toConsumableArray from '@babel/runtime/helpers/toConsumableArray';
|
|
3
2
|
import macro from '../../macros.js';
|
|
4
3
|
import vtkProp from '../../Rendering/Core/Prop.js';
|
|
5
|
-
import { f as vtkMath } from '../../Common/Core/Math/index.js';
|
|
6
4
|
import vtkCellArray from '../../Common/Core/CellArray.js';
|
|
7
5
|
import vtkDataArray from '../../Common/Core/DataArray.js';
|
|
8
6
|
import vtkPoints from '../../Common/Core/Points.js';
|
|
@@ -96,26 +94,6 @@ function connectPipeline(pipeline) {
|
|
|
96
94
|
}
|
|
97
95
|
|
|
98
96
|
pipeline.actor.setMapper(pipeline.mapper);
|
|
99
|
-
}
|
|
100
|
-
function getPixelWorldHeightAtCoord(worldCoord, displayScaleParams) {
|
|
101
|
-
var dispHeightFactor = displayScaleParams.dispHeightFactor,
|
|
102
|
-
cameraPosition = displayScaleParams.cameraPosition,
|
|
103
|
-
cameraDir = displayScaleParams.cameraDir,
|
|
104
|
-
isParallel = displayScaleParams.isParallel,
|
|
105
|
-
rendererPixelDims = displayScaleParams.rendererPixelDims;
|
|
106
|
-
var scale = 1;
|
|
107
|
-
|
|
108
|
-
if (isParallel) {
|
|
109
|
-
scale = dispHeightFactor;
|
|
110
|
-
} else {
|
|
111
|
-
var worldCoordToCamera = _toConsumableArray(worldCoord);
|
|
112
|
-
|
|
113
|
-
vtkMath.subtract(worldCoordToCamera, cameraPosition, worldCoordToCamera);
|
|
114
|
-
scale = vtkMath.dot(worldCoordToCamera, cameraDir) * dispHeightFactor;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
var rHeight = rendererPixelDims[1];
|
|
118
|
-
return scale / rHeight;
|
|
119
97
|
} // Internal convenient function to create a data array:
|
|
120
98
|
|
|
121
99
|
function allocateArray(polyData, name, numberOfTuples, dataType, numberOfComponents) {
|
|
@@ -362,7 +340,7 @@ function extend(publicAPI, model) {
|
|
|
362
340
|
// Object methods
|
|
363
341
|
vtkProp.extend(publicAPI, model, defaultValues(initialValues));
|
|
364
342
|
macro.algo(publicAPI, model, 1, 1);
|
|
365
|
-
macro.get(publicAPI, model, ['labels']);
|
|
343
|
+
macro.get(publicAPI, model, ['labels', 'displayScaleParams', 'coincidentTopologyParameters']);
|
|
366
344
|
macro.set(publicAPI, model, [{
|
|
367
345
|
type: 'object',
|
|
368
346
|
name: 'displayScaleParams'
|
|
@@ -379,8 +357,7 @@ var vtkWidgetRepresentation$1 = {
|
|
|
379
357
|
extend: extend,
|
|
380
358
|
mergeStyles: mergeStyles,
|
|
381
359
|
applyStyles: applyStyles,
|
|
382
|
-
connectPipeline: connectPipeline
|
|
383
|
-
getPixelWorldHeightAtCoord: getPixelWorldHeightAtCoord
|
|
360
|
+
connectPipeline: connectPipeline
|
|
384
361
|
};
|
|
385
362
|
|
|
386
|
-
export { allocateArray, applyStyles, connectPipeline, vtkWidgetRepresentation$1 as default, extend,
|
|
363
|
+
export { allocateArray, applyStyles, connectPipeline, vtkWidgetRepresentation$1 as default, extend, mergeStyles };
|
|
@@ -10,7 +10,19 @@ import { InteractionMethodsName, lineNames, ScrollingMethods, planeNameToViewTyp
|
|
|
10
10
|
function widgetBehavior(publicAPI, model) {
|
|
11
11
|
model._isDragging = false;
|
|
12
12
|
var isScrolling = false;
|
|
13
|
-
var previousPosition;
|
|
13
|
+
var previousPosition;
|
|
14
|
+
macro.setGet(publicAPI, model, ['keepOrthogonality']);
|
|
15
|
+
|
|
16
|
+
publicAPI.setEnableTranslation = function (enable) {
|
|
17
|
+
model.representations[0].setPickable(enable); // line handle
|
|
18
|
+
|
|
19
|
+
model.representations[2].setPickable(enable); // center handle
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
publicAPI.setEnableRotation = function (enable) {
|
|
23
|
+
model.representations[1].setPickable(enable); // rotation handle
|
|
24
|
+
}; // FIXME: label information should be accessible from activeState instead of parent state.
|
|
25
|
+
|
|
14
26
|
|
|
15
27
|
publicAPI.getActiveInteraction = function () {
|
|
16
28
|
if (model.widgetState.getStatesWithLabel('rotation').includes(model.activeState)) {
|
|
@@ -245,7 +257,7 @@ function widgetBehavior(publicAPI, model) {
|
|
|
245
257
|
var newCenter = [oldCenter[0] + movingFactor * dirProj[0], oldCenter[1] + movingFactor * dirProj[1], oldCenter[2] + movingFactor * dirProj[2]];
|
|
246
258
|
newCenter = publicAPI.getBoundedCenter(newCenter);
|
|
247
259
|
model.widgetState.setCenter(newCenter);
|
|
248
|
-
updateState(model.widgetState, model._factory.
|
|
260
|
+
updateState(model.widgetState, model._factory.getScaleInPixels(), model._factory.getRotationHandlePosition());
|
|
249
261
|
};
|
|
250
262
|
|
|
251
263
|
publicAPI[InteractionMethodsName.TranslateAxis] = function (calldata) {
|
|
@@ -274,7 +286,7 @@ function widgetBehavior(publicAPI, model) {
|
|
|
274
286
|
var newOrigin = multiplyAccumulate(center, axisTranslation, translationDistance, [0, 0, 0]);
|
|
275
287
|
newOrigin = publicAPI.getBoundedCenter(newOrigin);
|
|
276
288
|
model.widgetState.setCenter(newOrigin);
|
|
277
|
-
updateState(model.widgetState, model._factory.
|
|
289
|
+
updateState(model.widgetState, model._factory.getScaleInPixels(), model._factory.getRotationHandlePosition());
|
|
278
290
|
};
|
|
279
291
|
|
|
280
292
|
publicAPI.getBoundedCenter = function (newCenter) {
|
|
@@ -295,7 +307,7 @@ function widgetBehavior(publicAPI, model) {
|
|
|
295
307
|
var newCenter = add(model.widgetState.getCenter(), translation, []);
|
|
296
308
|
newCenter = publicAPI.getBoundedCenter(newCenter);
|
|
297
309
|
model.widgetState.setCenter(newCenter);
|
|
298
|
-
updateState(model.widgetState, model._factory.
|
|
310
|
+
updateState(model.widgetState, model._factory.getScaleInPixels(), model._factory.getRotationHandlePosition());
|
|
299
311
|
};
|
|
300
312
|
|
|
301
313
|
publicAPI[InteractionMethodsName.RotateLine] = function (calldata) {
|
|
@@ -306,7 +318,7 @@ function widgetBehavior(publicAPI, model) {
|
|
|
306
318
|
var previousLineDirection = activeLineHandle.getDirection();
|
|
307
319
|
normalize(previousLineDirection);
|
|
308
320
|
|
|
309
|
-
if (publicAPI.getActiveRotationPointName() === '
|
|
321
|
+
if (publicAPI.getActiveRotationPointName() === 'point1') {
|
|
310
322
|
multiplyScalar(previousLineDirection, -1);
|
|
311
323
|
}
|
|
312
324
|
|
|
@@ -329,13 +341,13 @@ function widgetBehavior(publicAPI, model) {
|
|
|
329
341
|
var planeNormal = model.widgetState.getPlanes()[inViewType].normal;
|
|
330
342
|
publicAPI.rotatePlane(viewType, radianAngle, planeNormal);
|
|
331
343
|
|
|
332
|
-
if (
|
|
344
|
+
if (publicAPI.getKeepOrthogonality()) {
|
|
333
345
|
var otherLineName = getOtherLineName(lineName);
|
|
334
346
|
var otherPlaneName = getLinePlaneName(otherLineName);
|
|
335
347
|
publicAPI.rotatePlane(planeNameToViewType[otherPlaneName], radianAngle, planeNormal);
|
|
336
348
|
}
|
|
337
349
|
|
|
338
|
-
updateState(model.widgetState, model._factory.
|
|
350
|
+
updateState(model.widgetState, model._factory.getScaleInPixels(), model._factory.getRotationHandlePosition());
|
|
339
351
|
};
|
|
340
352
|
/**
|
|
341
353
|
* Rotate a specified plane around an other specified plane.
|
|
@@ -6,7 +6,6 @@ import vtkPlane from '../../../Common/DataModel/Plane.js';
|
|
|
6
6
|
import { s as subtract, l as normalize, j as cross, w as multiplyScalar, m as multiplyAccumulate, S as signedAngleBetweenVectors } from '../../../Common/Core/Math/index.js';
|
|
7
7
|
import vtkMatrixBuilder from '../../../Common/Core/MatrixBuilder.js';
|
|
8
8
|
import { ViewTypes } from '../../Core/WidgetManager/Constants.js';
|
|
9
|
-
import { getPixelWorldHeightAtCoord } from '../../Representations/WidgetRepresentation.js';
|
|
10
9
|
import { planeNames, lineNames, planeNameToViewType } from './Constants.js';
|
|
11
10
|
|
|
12
11
|
var EPSILON = 10e-7;
|
|
@@ -157,25 +156,15 @@ function getOtherLineName(lineName) {
|
|
|
157
156
|
return planeName !== linePlaneName && planeName !== lineInPlaneName;
|
|
158
157
|
});
|
|
159
158
|
return "".concat(otherLineName, "in").concat(lineInPlaneName);
|
|
160
|
-
} //
|
|
159
|
+
} // Compute the offset of the rotation handle origin
|
|
161
160
|
|
|
162
|
-
function
|
|
161
|
+
function computeRotationHandleOriginOffset(axis, rotationHandlePosition, volumeDiagonalLength, scaleInPixels) {
|
|
163
162
|
// FIXME: p1 and p2 could be placed on the exact boundaries of the volume.
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
if (displayScaleParams) {
|
|
167
|
-
var pixelWorldHeight = getPixelWorldHeightAtCoord(center, displayScaleParams);
|
|
168
|
-
var rendererPixelDims = displayScaleParams.rendererPixelDims;
|
|
169
|
-
var totalSize = Math.min(rendererPixelDims[0], rendererPixelDims[1]) / 2;
|
|
170
|
-
distanceToCenter = pixelWorldHeight * totalSize;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
distanceToCenter *= rotationHandlePosition;
|
|
174
|
-
return multiplyAccumulate(center, axis, distanceToCenter, []);
|
|
163
|
+
return multiplyScalar(_toConsumableArray(axis), rotationHandlePosition * (scaleInPixels ? 1 : volumeDiagonalLength) / 2);
|
|
175
164
|
} // Update the reslice cursor state according to the three planes normals and the origin
|
|
176
165
|
|
|
177
166
|
|
|
178
|
-
function updateState(widgetState,
|
|
167
|
+
function updateState(widgetState, scaleInPixels, rotationHandlePosition) {
|
|
179
168
|
// Compute line axis
|
|
180
169
|
var xNormal = widgetState.getPlanes()[ViewTypes.YZ_PLANE].normal;
|
|
181
170
|
var yNormal = widgetState.getPlanes()[ViewTypes.XZ_PLANE].normal;
|
|
@@ -196,13 +185,13 @@ function updateState(widgetState, displayScaleParams, rotationHandlePosition) {
|
|
|
196
185
|
lineNames.forEach(function (lineName) {
|
|
197
186
|
var planeName = getLinePlaneName(lineName);
|
|
198
187
|
var inPlaneName = getLineInPlaneName(lineName);
|
|
199
|
-
var
|
|
200
|
-
widgetState["getRotationHandle".concat(lineName, "0")]().setOrigin(
|
|
201
|
-
|
|
202
|
-
widgetState["getRotationHandle".concat(lineName, "1")]().setOrigin(
|
|
188
|
+
var direction = axes["".concat(planeName).concat(inPlaneName)];
|
|
189
|
+
widgetState["getRotationHandle".concat(lineName, "0")]().setOrigin(center);
|
|
190
|
+
widgetState["getRotationHandle".concat(lineName, "0")]().setOffset(computeRotationHandleOriginOffset(direction, rotationHandlePosition, pdLength, scaleInPixels));
|
|
191
|
+
widgetState["getRotationHandle".concat(lineName, "1")]().setOrigin(center);
|
|
192
|
+
widgetState["getRotationHandle".concat(lineName, "1")]().setOffset(computeRotationHandleOriginOffset(direction, -rotationHandlePosition, pdLength, scaleInPixels));
|
|
203
193
|
var lineHandle = widgetState["getAxis".concat(lineName)]();
|
|
204
194
|
lineHandle.setOrigin(center);
|
|
205
|
-
var direction = subtract(rotationPoint0, center, []);
|
|
206
195
|
var scale = normalize(direction);
|
|
207
196
|
var scale3 = lineHandle.getScale3();
|
|
208
197
|
scale3[2] = 2 * scale;
|
|
@@ -17,24 +17,12 @@ function generateState() {
|
|
|
17
17
|
var state = vtkStateBuilder.createBuilder().addField({
|
|
18
18
|
name: 'center',
|
|
19
19
|
initialValue: [0, 0, 0]
|
|
20
|
-
}).addField({
|
|
21
|
-
name: 'opacity',
|
|
22
|
-
initialValue: 1
|
|
23
20
|
}).addField({
|
|
24
21
|
name: 'image',
|
|
25
22
|
initialValue: null
|
|
26
23
|
}).addField({
|
|
27
24
|
name: 'activeViewType',
|
|
28
25
|
initialValue: null
|
|
29
|
-
}).addField({
|
|
30
|
-
name: 'lineThickness',
|
|
31
|
-
initialValue: 2
|
|
32
|
-
}).addField({
|
|
33
|
-
name: 'sphereRadius',
|
|
34
|
-
initialValue: 5
|
|
35
|
-
}).addField({
|
|
36
|
-
name: 'showCenter',
|
|
37
|
-
initialValue: true
|
|
38
26
|
}).addField({
|
|
39
27
|
name: 'planes',
|
|
40
28
|
initialValue: (_initialValue = {}, _defineProperty(_initialValue, ViewTypes.YZ_PLANE, {
|
|
@@ -47,15 +35,6 @@ function generateState() {
|
|
|
47
35
|
normal: [0, 0, -1],
|
|
48
36
|
viewUp: [0, -1, 0]
|
|
49
37
|
}), _initialValue)
|
|
50
|
-
}).addField({
|
|
51
|
-
name: 'enableRotation',
|
|
52
|
-
initialValue: true
|
|
53
|
-
}).addField({
|
|
54
|
-
name: 'enableTranslation',
|
|
55
|
-
initialValue: true
|
|
56
|
-
}).addField({
|
|
57
|
-
name: 'keepOrthogonality',
|
|
58
|
-
initialValue: false
|
|
59
38
|
}).addField({
|
|
60
39
|
name: 'scrollingMethod',
|
|
61
40
|
initialValue: ScrollingMethods.MIDDLE_MOUSE_BUTTON
|
|
@@ -66,7 +45,7 @@ function generateState() {
|
|
|
66
45
|
name: 'viewUpFromViewType',
|
|
67
46
|
initialValue: {}
|
|
68
47
|
}).addStateFromMixin({
|
|
69
|
-
labels: ['handles', 'center'],
|
|
48
|
+
labels: ['handles', 'sphere', 'center'],
|
|
70
49
|
mixins: ['origin', 'color3', 'scale1', 'visible', 'manipulator'],
|
|
71
50
|
name: 'centerHandle',
|
|
72
51
|
initialValues: {
|
|
@@ -92,7 +71,7 @@ function generateState() {
|
|
|
92
71
|
|
|
93
72
|
for (var rotationHandle = 0; rotationHandle < 2; ++rotationHandle) {
|
|
94
73
|
axisState.addStateFromMixin({
|
|
95
|
-
labels: ['handles', 'rotation', "rotationIn".concat(view), "".concat(axis, "in").concat(view), "point".concat(rotationHandle)],
|
|
74
|
+
labels: ['handles', 'sphere', 'rotation', "rotationIn".concat(view), "".concat(axis, "in").concat(view), "point".concat(rotationHandle)],
|
|
96
75
|
mixins: ['origin', 'color3', 'scale1', 'visible', 'manipulator'],
|
|
97
76
|
name: "rotationHandle".concat(axis, "in").concat(view).concat(rotationHandle),
|
|
98
77
|
initialValues: {
|
|
@@ -10,6 +10,7 @@ import { e as distance2BetweenPoints, m as multiplyAccumulate, s as subtract, l
|
|
|
10
10
|
import widgetBehavior from './ResliceCursorWidget/behavior.js';
|
|
11
11
|
import generateState from './ResliceCursorWidget/state.js';
|
|
12
12
|
import { updateState, transformPlane, boundPlane } from './ResliceCursorWidget/helpers.js';
|
|
13
|
+
import { viewTypeToPlaneName } from './ResliceCursorWidget/Constants.js';
|
|
13
14
|
import { ViewTypes } from '../Core/WidgetManager/Constants.js';
|
|
14
15
|
import { mat4 } from 'gl-matrix';
|
|
15
16
|
import vtkMatrixBuilder from '../../Common/Core/MatrixBuilder.js';
|
|
@@ -138,21 +139,32 @@ function vtkResliceCursorWidget(publicAPI, model) {
|
|
|
138
139
|
renderer.resetCameraClippingRange(bounds);
|
|
139
140
|
}
|
|
140
141
|
/**
|
|
141
|
-
* Convenient function to return the
|
|
142
|
+
* Convenient function to return the widget for a given viewType
|
|
142
143
|
* @param {string} viewType
|
|
143
|
-
* @returns
|
|
144
|
+
* @returns the widget instanced in the given viewType.
|
|
144
145
|
*/
|
|
145
146
|
|
|
146
147
|
|
|
147
|
-
function
|
|
148
|
-
|
|
148
|
+
function findWidgetForViewType(viewType) {
|
|
149
|
+
return publicAPI.getViewIds().map(function (viewId) {
|
|
149
150
|
return publicAPI.getWidgetForView({
|
|
150
151
|
viewId: viewId
|
|
151
152
|
});
|
|
152
153
|
}).find(function (widget) {
|
|
153
154
|
return widget.getViewType() === viewType;
|
|
154
155
|
});
|
|
155
|
-
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Convenient function to return the ResliceCursorRepresentation for a given viewType
|
|
159
|
+
* @param {string} viewType
|
|
160
|
+
* @returns an array of 3 representations (for line handles, rotation handles, center handle)
|
|
161
|
+
* or an empty array if the widget has not yet been added to the view type.
|
|
162
|
+
*/
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
function findRepresentationsForViewType(viewType) {
|
|
166
|
+
var widgetForViewType = findWidgetForViewType(viewType);
|
|
167
|
+
return widgetForViewType ? widgetForViewType.getRepresentations() : [];
|
|
156
168
|
} // --------------------------------------------------------------------------
|
|
157
169
|
// initialization
|
|
158
170
|
// --------------------------------------------------------------------------
|
|
@@ -161,47 +173,28 @@ function vtkResliceCursorWidget(publicAPI, model) {
|
|
|
161
173
|
publicAPI.getRepresentationsForViewType = function (viewType) {
|
|
162
174
|
switch (viewType) {
|
|
163
175
|
case ViewTypes.XY_PLANE:
|
|
164
|
-
return [{
|
|
165
|
-
builder: vtkLineHandleRepresentation,
|
|
166
|
-
labels: ['lineInZ'],
|
|
167
|
-
initialValues: {
|
|
168
|
-
useActiveColor: false
|
|
169
|
-
}
|
|
170
|
-
}, {
|
|
171
|
-
builder: vtkSphereHandleRepresentation,
|
|
172
|
-
labels: ['rotationInZ', 'center'],
|
|
173
|
-
initialValues: {
|
|
174
|
-
useActiveColor: false
|
|
175
|
-
}
|
|
176
|
-
}];
|
|
177
|
-
|
|
178
176
|
case ViewTypes.XZ_PLANE:
|
|
177
|
+
case ViewTypes.YZ_PLANE:
|
|
179
178
|
return [{
|
|
180
179
|
builder: vtkLineHandleRepresentation,
|
|
181
|
-
labels: [
|
|
180
|
+
labels: ["lineIn".concat(viewTypeToPlaneName[viewType])],
|
|
182
181
|
initialValues: {
|
|
183
|
-
useActiveColor: false
|
|
182
|
+
useActiveColor: false,
|
|
183
|
+
scaleInPixels: model.scaleInPixels
|
|
184
184
|
}
|
|
185
185
|
}, {
|
|
186
186
|
builder: vtkSphereHandleRepresentation,
|
|
187
|
-
labels: [
|
|
187
|
+
labels: ["rotationIn".concat(viewTypeToPlaneName[viewType])],
|
|
188
188
|
initialValues: {
|
|
189
|
-
useActiveColor: false
|
|
190
|
-
|
|
191
|
-
}];
|
|
192
|
-
|
|
193
|
-
case ViewTypes.YZ_PLANE:
|
|
194
|
-
return [{
|
|
195
|
-
builder: vtkLineHandleRepresentation,
|
|
196
|
-
labels: ['lineInX'],
|
|
197
|
-
initialValues: {
|
|
198
|
-
useActiveColor: false
|
|
189
|
+
useActiveColor: false,
|
|
190
|
+
scaleInPixels: model.scaleInPixels
|
|
199
191
|
}
|
|
200
192
|
}, {
|
|
201
193
|
builder: vtkSphereHandleRepresentation,
|
|
202
|
-
labels: ['
|
|
194
|
+
labels: ['center'],
|
|
203
195
|
initialValues: {
|
|
204
|
-
useActiveColor: false
|
|
196
|
+
useActiveColor: false,
|
|
197
|
+
scaleInPixels: model.scaleInPixels
|
|
205
198
|
}
|
|
206
199
|
}];
|
|
207
200
|
|
|
@@ -218,12 +211,12 @@ function vtkResliceCursorWidget(publicAPI, model) {
|
|
|
218
211
|
model.widgetState.setImage(image);
|
|
219
212
|
var center = image.getCenter();
|
|
220
213
|
model.widgetState.setCenter(center);
|
|
221
|
-
updateState(model.widgetState,
|
|
214
|
+
updateState(model.widgetState, model.scaleInPixels, model.rotationHandlePosition);
|
|
222
215
|
};
|
|
223
216
|
|
|
224
217
|
publicAPI.setCenter = function (center) {
|
|
225
218
|
model.widgetState.setCenter(center);
|
|
226
|
-
updateState(model.widgetState,
|
|
219
|
+
updateState(model.widgetState, model.scaleInPixels, model.rotationHandlePosition);
|
|
227
220
|
publicAPI.modified();
|
|
228
221
|
}; // --------------------------------------------------------------------------
|
|
229
222
|
// Methods
|
|
@@ -423,10 +416,17 @@ function vtkResliceCursorWidget(publicAPI, model) {
|
|
|
423
416
|
return [ViewTypes.YZ_PLANE, ViewTypes.XZ_PLANE, ViewTypes.XY_PLANE].reduce(function (res, viewType) {
|
|
424
417
|
var _findRepresentationsF, _findRepresentationsF2;
|
|
425
418
|
|
|
426
|
-
res[viewType] = (_findRepresentationsF =
|
|
419
|
+
res[viewType] = (_findRepresentationsF = findRepresentationsForViewType(viewType)[0]) === null || _findRepresentationsF === void 0 ? void 0 : (_findRepresentationsF2 = _findRepresentationsF.getDisplayScaleParams) === null || _findRepresentationsF2 === void 0 ? void 0 : _findRepresentationsF2.call(_findRepresentationsF);
|
|
427
420
|
return res;
|
|
428
421
|
}, {});
|
|
429
422
|
};
|
|
423
|
+
|
|
424
|
+
publicAPI.setScaleInPixels = macro.chain(publicAPI.setScaleInPixels, function (scale) {
|
|
425
|
+
publicAPI.getViewWidgets().forEach(function (w) {
|
|
426
|
+
return w.setScaleInPixels(scale);
|
|
427
|
+
});
|
|
428
|
+
updateState(model.widgetState, model.scaleInPixels, model.rotationHandlePosition);
|
|
429
|
+
});
|
|
430
430
|
} // ----------------------------------------------------------------------------
|
|
431
431
|
|
|
432
432
|
|
|
@@ -434,7 +434,8 @@ var defaultValues = function defaultValues(initialValues) {
|
|
|
434
434
|
return _objectSpread({
|
|
435
435
|
behavior: widgetBehavior,
|
|
436
436
|
widgetState: generateState(),
|
|
437
|
-
rotationHandlePosition: 0.
|
|
437
|
+
rotationHandlePosition: 0.5,
|
|
438
|
+
scaleInPixels: true
|
|
438
439
|
}, initialValues);
|
|
439
440
|
}; // ----------------------------------------------------------------------------
|
|
440
441
|
|
|
@@ -443,7 +444,7 @@ function extend(publicAPI, model) {
|
|
|
443
444
|
var initialValues = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
444
445
|
Object.assign(model, defaultValues(initialValues));
|
|
445
446
|
vtkAbstractWidgetFactory.extend(publicAPI, model, initialValues);
|
|
446
|
-
macro.setGet(publicAPI, model, ['rotationHandlePosition']);
|
|
447
|
+
macro.setGet(publicAPI, model, ['scaleInPixels', 'rotationHandlePosition']);
|
|
447
448
|
vtkResliceCursorWidget(publicAPI, model);
|
|
448
449
|
} // ----------------------------------------------------------------------------
|
|
449
450
|
|