@kitware/vtk.js 26.8.2 → 26.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/BREAKING_CHANGES.md +6 -1
  2. package/Common/Core/DataArray.js +9 -10
  3. package/Common/Core/ScalarsToColors.d.ts +9 -1
  4. package/Common/Core/ScalarsToColors.js +22 -0
  5. package/Filters/General/ImageMarchingCubes.js +2 -1
  6. package/Rendering/Core/Mapper.js +10 -1
  7. package/Rendering/OpenGL/Actor.js +12 -2
  8. package/Rendering/OpenGL/Camera.js +1 -0
  9. package/Rendering/OpenGL/ForwardPass.js +6 -3
  10. package/Rendering/OpenGL/ImageMapper.js +5 -1
  11. package/Rendering/OpenGL/ImageSlice.js +17 -1
  12. package/Rendering/OpenGL/OrderIndependentTranslucentPass.js +1 -0
  13. package/Rendering/OpenGL/PolyDataMapper.js +5 -1
  14. package/Rendering/OpenGL/RenderWindow.js +24 -8
  15. package/Rendering/OpenGL/Renderer.js +5 -1
  16. package/Rendering/OpenGL/VolumeMapper.js +5 -1
  17. package/Widgets/Core/AbstractWidget.js +1 -5
  18. package/Widgets/Core/AbstractWidgetFactory.d.ts +5 -0
  19. package/Widgets/Core/AbstractWidgetFactory.js +4 -0
  20. package/Widgets/Core/StateBuilder/color3Mixin.js +3 -1
  21. package/Widgets/Core/StateBuilder/originMixin.js +34 -3
  22. package/Widgets/Core/WidgetManager.d.ts +8 -0
  23. package/Widgets/Core/WidgetManager.js +27 -5
  24. package/Widgets/Representations/CroppingOutlineRepresentation.js +1 -1
  25. package/Widgets/Representations/GlyphRepresentation.js +10 -5
  26. package/Widgets/Representations/ImplicitPlaneRepresentation.js +2 -1
  27. package/Widgets/Representations/PolyLineRepresentation.js +2 -1
  28. package/Widgets/Representations/WidgetRepresentation.js +3 -26
  29. package/Widgets/Widgets3D/ResliceCursorWidget/behavior.js +19 -7
  30. package/Widgets/Widgets3D/ResliceCursorWidget/helpers.js +9 -20
  31. package/Widgets/Widgets3D/ResliceCursorWidget/state.js +2 -23
  32. package/Widgets/Widgets3D/ResliceCursorWidget.js +40 -39
  33. package/package.json +3 -1
@@ -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
@@ -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
  // ----------------------------------------------------------------------------
@@ -268,8 +268,9 @@ function vtkImageMarchingCubes(publicAPI, model) {
268
268
  publicAPI.produceTriangles(model.contourValue, i, j, k, extent, slice, dims, origin, spacing, s, pBuffer, tBuffer, nBuffer);
269
269
  }
270
270
  }
271
- } // Update output
271
+ }
272
272
 
273
+ edgeLocator.initialize(); // Update output
273
274
 
274
275
  var polydata = vtkPolyData.newInstance();
275
276
  polydata.getPoints().setData(new Float32Array(pBuffer), 3);
@@ -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.isOpaque();
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
- publicAPI.traverseOpaqueZBufferPass = function (renderPass) {
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
  };
@@ -29,6 +29,7 @@ function vtkOpenGLCamera(publicAPI, model) {
29
29
  };
30
30
 
31
31
  publicAPI.translucentPass = publicAPI.opaquePass;
32
+ publicAPI.zBufferPass = publicAPI.opaquePass;
32
33
  publicAPI.opaqueZBufferPass = publicAPI.opaquePass;
33
34
  publicAPI.volumePass = publicAPI.opaquePass;
34
35
 
@@ -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
- publicAPI.setCurrentOperation('opaqueZBufferPass');
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.opaqueZBufferPass = function (prepass) {
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.opaqueZBufferPass = function (prepass) {
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', // might want to make this not call modified as
984
- // we change the active framebuffer a lot. Or maybe
985
- // only mark modified if the size or depth
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.opaqueZBufferPass = function (prepass) {
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.opaqueZBufferPass = function (prepass, renderPass) {
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.getViewIds().map(function (viewId) {
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 { r as radiansFromDegrees } from '../../Common/Core/Math/index.js';
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.onModified(updateDisplayScaleParams));
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 vtkWidgetRepresentation, { allocateArray, getPixelWorldHeightAtCoord } from './WidgetRepresentation.js';
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 colors = allocateArray(polyData, 'color', states.length, 'Uint8Array', // RGB
43
- 3).getData();
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 vtkWidgetRepresentation, { getPixelWorldHeightAtCoord } from './WidgetRepresentation.js';
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 vtkWidgetRepresentation, { allocateArray, getPixelWorldHeightAtCoord } from './WidgetRepresentation.js';
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, getPixelWorldHeightAtCoord, mergeStyles };
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; // FIXME: label information should be accessible from activeState instead of parent state.
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.getDisplayScaleParams(), model._factory.getRotationHandlePosition());
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.getDisplayScaleParams(), model._factory.getRotationHandlePosition());
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.getDisplayScaleParams(), model._factory.getRotationHandlePosition());
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() === 'point0') {
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 (model.widgetState.getKeepOrthogonality()) {
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.getDisplayScaleParams(), model._factory.getRotationHandlePosition());
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
- } // Update the extremities and the rotation point coordinate of the line
159
+ } // Compute the offset of the rotation handle origin
161
160
 
162
- function computeRotationHandleOrigin(center, axis, rotationHandlePosition, volumeDiagonalLength, displayScaleParams) {
161
+ function computeRotationHandleOriginOffset(axis, rotationHandlePosition, volumeDiagonalLength, scaleInPixels) {
163
162
  // FIXME: p1 and p2 could be placed on the exact boundaries of the volume.
164
- var distanceToCenter = volumeDiagonalLength; // displayScaleParams is not null when representation.getScaleInPixels() is true
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, displayScaleParams, rotationHandlePosition) {
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 rotationPoint0 = computeRotationHandleOrigin(center, axes["".concat(planeName).concat(inPlaneName)], rotationHandlePosition, pdLength, displayScaleParams[planeNameToViewType[inPlaneName]]);
200
- widgetState["getRotationHandle".concat(lineName, "0")]().setOrigin(rotationPoint0);
201
- var rotationPoint1 = computeRotationHandleOrigin(center, multiplyScalar(axes["".concat(planeName).concat(inPlaneName)], -1), rotationHandlePosition, pdLength, displayScaleParams[planeNameToViewType[inPlaneName]]);
202
- widgetState["getRotationHandle".concat(lineName, "1")]().setOrigin(rotationPoint1);
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 ResliceCursorRepresentation for a given viewType
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 findRepresentationsForViewType(viewType) {
148
- var widgetForViewType = publicAPI.getViewIds().map(function (viewId) {
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
- return widgetForViewType.getRepresentations();
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: ['lineInY'],
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: ['rotationInY', 'center'],
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: ['rotationInX', 'center'],
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, publicAPI.getDisplayScaleParams(), model.rotationHandlePosition);
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, publicAPI.getDisplayScaleParams(), model.rotationHandlePosition);
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 = (_findRepresentationsF2 = findRepresentationsForViewType(viewType)[0]).getDisplayScaleParams) === null || _findRepresentationsF === void 0 ? void 0 : _findRepresentationsF.call(_findRepresentationsF2);
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.25
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
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kitware/vtk.js",
3
- "version": "26.8.2",
3
+ "version": "26.9.1",
4
4
  "description": "Visualization Toolkit for the Web",
5
5
  "keywords": [
6
6
  "3d",
@@ -129,6 +129,8 @@
129
129
  "xml2js": "0.4.23"
130
130
  },
131
131
  "peerDependencies": {
132
+ "@babel/preset-env": "^7.17.10",
133
+ "autoprefixer": "^10.4.7",
132
134
  "wslink": "^1.1.0"
133
135
  },
134
136
  "scripts": {