@kitware/vtk.js 27.4.6 → 28.0.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.
Files changed (44) hide show
  1. package/BREAKING_CHANGES.md +4 -0
  2. package/Common/DataModel/Line.d.ts +24 -2
  3. package/Common/DataModel/Line.js +17 -1
  4. package/Common/DataModel/PolyLine.d.ts +36 -2
  5. package/Common/DataModel/PolyLine.js +80 -10
  6. package/Common/Transform/Transform.d.ts +177 -0
  7. package/Common/Transform/Transform.js +81 -3
  8. package/Proxy/Core/View2DProxy.js +22 -12
  9. package/Rendering/Core/AbstractMapper3D.d.ts +1 -3
  10. package/Rendering/Core/AbstractMapper3D.js +21 -45
  11. package/Rendering/Core/ImageCPRMapper.d.ts +380 -0
  12. package/Rendering/Core/ImageCPRMapper.js +361 -0
  13. package/Rendering/OpenGL/ImageCPRMapper.js +919 -0
  14. package/Rendering/OpenGL/Profiles/All.js +1 -0
  15. package/Rendering/OpenGL/Profiles/Volume.js +1 -0
  16. package/Rendering/OpenGL/RenderWindow/Constants.js +3 -2
  17. package/Rendering/OpenGL/RenderWindow.js +38 -45
  18. package/Rendering/Profiles/All.js +1 -0
  19. package/Rendering/Profiles/Volume.js +1 -0
  20. package/Widgets/Core/WidgetManager.js +1 -1
  21. package/Widgets/Manipulators/AbstractManipulator.d.ts +2 -2
  22. package/Widgets/Manipulators/CPRManipulator.js +138 -0
  23. package/Widgets/Manipulators/LineManipulator.js +3 -1
  24. package/Widgets/Manipulators/PlaneManipulator.js +3 -1
  25. package/Widgets/Manipulators/TrackballManipulator.js +3 -1
  26. package/Widgets/Widgets3D/AngleWidget/behavior.js +5 -2
  27. package/Widgets/Widgets3D/DistanceWidget/behavior.js +5 -2
  28. package/Widgets/Widgets3D/ImageCroppingWidget/behavior.js +3 -3
  29. package/Widgets/Widgets3D/ImplicitPlaneWidget.js +3 -1
  30. package/Widgets/Widgets3D/LabelWidget/behavior.js +5 -2
  31. package/Widgets/Widgets3D/LineWidget/behavior.js +4 -2
  32. package/Widgets/Widgets3D/PaintWidget/behavior.js +2 -1
  33. package/Widgets/Widgets3D/PolyLineWidget/behavior.js +2 -1
  34. package/Widgets/Widgets3D/ResliceCursorWidget/Constants.js +2 -1
  35. package/Widgets/Widgets3D/ResliceCursorWidget/behavior.js +72 -34
  36. package/Widgets/Widgets3D/ResliceCursorWidget/cprBehavior.js +92 -0
  37. package/Widgets/Widgets3D/ResliceCursorWidget/helpers.js +64 -18
  38. package/Widgets/Widgets3D/ResliceCursorWidget/state.js +30 -16
  39. package/Widgets/Widgets3D/ResliceCursorWidget.js +43 -20
  40. package/Widgets/Widgets3D/ShapeWidget/behavior.js +4 -2
  41. package/Widgets/Widgets3D/SphereWidget/behavior.js +1 -1
  42. package/Widgets/Widgets3D/SplineWidget/behavior.js +3 -1
  43. package/index.d.ts +2 -0
  44. package/package.json +3 -2
@@ -2,10 +2,9 @@ import _toConsumableArray from '@babel/runtime/helpers/toConsumableArray';
2
2
  import macro from '../../../macros.js';
3
3
  import vtkBoundingBox from '../../../Common/DataModel/BoundingBox.js';
4
4
  import vtkLine from '../../../Common/DataModel/Line.js';
5
- import vtkPlanePointManipulator from '../../Manipulators/PlaneManipulator.js';
6
- import { k as add, l as normalize, d as dot, j as cross, s as subtract, m as multiplyAccumulate, w as multiplyScalar, S as signedAngleBetweenVectors } from '../../../Common/Core/Math/index.js';
7
- import { getOtherLineName, updateState, boundPointOnPlane, getLinePlaneName, getLineInPlaneName, rotateVector } from './helpers.js';
8
- import { InteractionMethodsName, lineNames, ScrollingMethods, planeNameToViewType } from './Constants.js';
5
+ import { k as add, l as normalize, s as subtract, d as dot, j as cross, m as multiplyAccumulate, w as multiplyScalar, S as signedAngleBetweenVectors } from '../../../Common/Core/Math/index.js';
6
+ import { getLineNames, getOtherLineName, updateState, boundPointOnPlane, getLinePlaneName, getLineInPlaneName, rotateVector } from './helpers.js';
7
+ import { InteractionMethodsName, ScrollingMethods, planeNameToViewType } from './Constants.js';
9
8
 
10
9
  function widgetBehavior(publicAPI, model) {
11
10
  model._isDragging = false;
@@ -46,7 +45,7 @@ function widgetBehavior(publicAPI, model) {
46
45
 
47
46
 
48
47
  publicAPI.getActiveLineName = function () {
49
- return lineNames.find(function (lineName) {
48
+ return getLineNames(model.widgetState).find(function (lineName) {
50
49
  return model.widgetState.getStatesWithLabel(lineName).includes(model.activeState);
51
50
  });
52
51
  }; // FIXME: label information should be accessible from activeState instead of parent state.
@@ -67,19 +66,27 @@ function widgetBehavior(publicAPI, model) {
67
66
  publicAPI.getOtherLineHandle = function (lineName) {
68
67
  var _model$widgetState$2, _model$widgetState2;
69
68
 
70
- return (_model$widgetState$2 = (_model$widgetState2 = model.widgetState)["getAxis".concat(getOtherLineName(lineName))]) === null || _model$widgetState$2 === void 0 ? void 0 : _model$widgetState$2.call(_model$widgetState2);
69
+ return (_model$widgetState$2 = (_model$widgetState2 = model.widgetState)["getAxis".concat(getOtherLineName(model.widgetState, lineName))]) === null || _model$widgetState$2 === void 0 ? void 0 : _model$widgetState$2.call(_model$widgetState2);
71
70
  }; // FIXME: label information should be accessible from activeState instead of parent state.
72
71
 
73
72
  /**
74
73
  * There are 2 rotation handles per axis: 'point0' and 'point1'.
75
74
  * This function returns which rotation handle (point0 or point1) is currently active.
76
75
  * ActiveState must be a RotationHandle.
77
- * @returns 'point0' or 'point1'
76
+ * @returns 'point0', 'point1' or null if no point is active (e.g. line is being rotated)
78
77
  */
79
78
 
80
79
 
81
80
  publicAPI.getActiveRotationPointName = function () {
82
- return model.widgetState.getStatesWithLabel('point0').includes(model.activeState) ? 'point0' : 'point1';
81
+ if (model.widgetState.getStatesWithLabel('point0').includes(model.activeState)) {
82
+ return 'point0';
83
+ }
84
+
85
+ if (model.widgetState.getStatesWithLabel('point1').includes(model.activeState)) {
86
+ return 'point1';
87
+ }
88
+
89
+ return null;
83
90
  };
84
91
 
85
92
  publicAPI.startScrolling = function (newPosition) {
@@ -122,12 +129,18 @@ function widgetBehavior(publicAPI, model) {
122
129
 
123
130
  publicAPI.handleLeftButtonPress = function (callData) {
124
131
  if (model.activeState && model.activeState.getActive()) {
132
+ var _model$activeState$ge, _model$activeState, _model$activeState$ge2;
133
+
125
134
  model._isDragging = true;
126
135
  var viewType = model.viewType;
127
136
  var currentPlaneNormal = model.widgetState.getPlanes()[viewType].normal;
128
- model.planeManipulator.setWidgetOrigin(model.widgetState.getCenter());
129
- model.planeManipulator.setWidgetNormal(currentPlaneNormal);
130
- var worldCoords = model.planeManipulator.handleEvent(callData, model._apiSpecificRenderWindow);
137
+ var manipulator = (_model$activeState$ge = (_model$activeState = model.activeState) === null || _model$activeState === void 0 ? void 0 : (_model$activeState$ge2 = _model$activeState.getManipulator) === null || _model$activeState$ge2 === void 0 ? void 0 : _model$activeState$ge2.call(_model$activeState)) !== null && _model$activeState$ge !== void 0 ? _model$activeState$ge : model.manipulator;
138
+ manipulator.setWidgetOrigin(model.widgetState.getCenter());
139
+ manipulator.setWidgetNormal(currentPlaneNormal);
140
+
141
+ var _manipulator$handleEv = manipulator.handleEvent(callData, model._apiSpecificRenderWindow),
142
+ worldCoords = _manipulator$handleEv.worldCoords;
143
+
131
144
  previousPosition = worldCoords;
132
145
  publicAPI.startInteraction();
133
146
  } else if (model.widgetState.getScrollingMethod() === ScrollingMethods.LEFT_MOUSE_BUTTON) {
@@ -261,6 +274,8 @@ function widgetBehavior(publicAPI, model) {
261
274
  };
262
275
 
263
276
  publicAPI[InteractionMethodsName.TranslateAxis] = function (calldata) {
277
+ var _model$activeState$ge3, _model$activeState2, _model$activeState2$g, _model$activeState3, _model$activeState3$g;
278
+
264
279
  var lineHandle = publicAPI.getActiveLineHandle();
265
280
  var lineName = publicAPI.getActiveLineName();
266
281
  var pointOnLine = add(lineHandle.getOrigin(), lineHandle.getDirection(), []);
@@ -268,25 +283,37 @@ function widgetBehavior(publicAPI, model) {
268
283
  normalize(currentLineVector); // Translate the current line along the other line
269
284
 
270
285
  var otherLineHandle = publicAPI.getOtherLineHandle(lineName);
271
- var otherLineVector = otherLineHandle.getDirection();
272
- normalize(otherLineVector);
273
- var axisTranslation = otherLineVector;
274
- var dot$1 = dot(currentLineVector, otherLineVector); // lines are colinear, translate along perpendicular axis from current line
286
+ var center = model.widgetState.getCenter();
287
+ var manipulator = (_model$activeState$ge3 = (_model$activeState2 = model.activeState) === null || _model$activeState2 === void 0 ? void 0 : (_model$activeState2$g = _model$activeState2.getManipulator) === null || _model$activeState2$g === void 0 ? void 0 : _model$activeState2$g.call(_model$activeState2)) !== null && _model$activeState$ge3 !== void 0 ? _model$activeState$ge3 : model.manipulator;
288
+ var worldCoords = null;
289
+ var newOrigin = [];
290
+
291
+ if ((_model$activeState3 = model.activeState) !== null && _model$activeState3 !== void 0 && (_model$activeState3$g = _model$activeState3.getManipulator) !== null && _model$activeState3$g !== void 0 && _model$activeState3$g.call(_model$activeState3)) {
292
+ worldCoords = manipulator.handleEvent(calldata, model._apiSpecificRenderWindow).worldCoords;
293
+ var translation = subtract(worldCoords, previousPosition, []);
294
+ add(center, translation, newOrigin);
295
+ } else if (otherLineHandle) {
296
+ var otherLineVector = otherLineHandle.getDirection();
297
+ normalize(otherLineVector);
298
+ var axisTranslation = otherLineVector;
299
+ var dot$1 = dot(currentLineVector, otherLineVector); // lines are colinear, translate along perpendicular axis from current line
300
+
301
+ if (dot$1 === 1 || dot$1 === -1) {
302
+ cross(currentLineVector, manipulator.getWidgetNormal(), axisTranslation);
303
+ }
275
304
 
276
- if (dot$1 === 1 || dot$1 === -1) {
277
- cross(currentLineVector, model.planeManipulator.getWidgetNormal(), axisTranslation);
305
+ var closestPoint = [];
306
+ worldCoords = manipulator.handleEvent(calldata, model._apiSpecificRenderWindow).worldCoords;
307
+ vtkLine.distanceToLine(worldCoords, lineHandle.getOrigin(), pointOnLine, closestPoint);
308
+ var translationVector = subtract(worldCoords, closestPoint, []);
309
+ var translationDistance = dot(translationVector, axisTranslation);
310
+ newOrigin = multiplyAccumulate(center, axisTranslation, translationDistance, newOrigin);
278
311
  }
279
312
 
280
- var closestPoint = [];
281
- var worldCoords = model.planeManipulator.handleEvent(calldata, model._apiSpecificRenderWindow);
282
- vtkLine.distanceToLine(worldCoords, lineHandle.getOrigin(), pointOnLine, closestPoint);
283
- var translationVector = subtract(worldCoords, closestPoint, []);
284
- var translationDistance = dot(translationVector, axisTranslation);
285
- var center = model.widgetState.getCenter();
286
- var newOrigin = multiplyAccumulate(center, axisTranslation, translationDistance, [0, 0, 0]);
287
313
  newOrigin = publicAPI.getBoundedCenter(newOrigin);
288
314
  model.widgetState.setCenter(newOrigin);
289
315
  updateState(model.widgetState, model._factory.getScaleInPixels(), model._factory.getRotationHandlePosition());
316
+ previousPosition = worldCoords;
290
317
  };
291
318
 
292
319
  publicAPI.getBoundedCenter = function (newCenter) {
@@ -301,7 +328,13 @@ function widgetBehavior(publicAPI, model) {
301
328
  };
302
329
 
303
330
  publicAPI[InteractionMethodsName.TranslateCenter] = function (calldata) {
304
- var worldCoords = model.planeManipulator.handleEvent(calldata, model._apiSpecificRenderWindow);
331
+ var _model$activeState$ge4, _model$activeState4, _model$activeState4$g;
332
+
333
+ var manipulator = (_model$activeState$ge4 = (_model$activeState4 = model.activeState) === null || _model$activeState4 === void 0 ? void 0 : (_model$activeState4$g = _model$activeState4.getManipulator) === null || _model$activeState4$g === void 0 ? void 0 : _model$activeState4$g.call(_model$activeState4)) !== null && _model$activeState$ge4 !== void 0 ? _model$activeState$ge4 : model.manipulator;
334
+
335
+ var _manipulator$handleEv2 = manipulator.handleEvent(calldata, model._apiSpecificRenderWindow),
336
+ worldCoords = _manipulator$handleEv2.worldCoords;
337
+
305
338
  var translation = subtract(worldCoords, previousPosition, []);
306
339
  previousPosition = worldCoords;
307
340
  var newCenter = add(model.widgetState.getCenter(), translation, []);
@@ -311,20 +344,27 @@ function widgetBehavior(publicAPI, model) {
311
344
  };
312
345
 
313
346
  publicAPI[InteractionMethodsName.RotateLine] = function (calldata) {
347
+ var _model$activeState$ge5, _model$activeState5, _model$activeState5$g;
348
+
314
349
  var activeLineHandle = publicAPI.getActiveLineHandle();
315
- var planeNormal = model.planeManipulator.getWidgetNormal();
316
- var worldCoords = model.planeManipulator.handleEvent(calldata, model._apiSpecificRenderWindow);
350
+ var manipulator = (_model$activeState$ge5 = (_model$activeState5 = model.activeState) === null || _model$activeState5 === void 0 ? void 0 : (_model$activeState5$g = _model$activeState5.getManipulator) === null || _model$activeState5$g === void 0 ? void 0 : _model$activeState5$g.call(_model$activeState5)) !== null && _model$activeState$ge5 !== void 0 ? _model$activeState$ge5 : model.manipulator;
351
+ var planeNormal = manipulator.getWidgetNormal();
352
+
353
+ var _manipulator$handleEv3 = manipulator.handleEvent(calldata, model._apiSpecificRenderWindow),
354
+ worldCoords = _manipulator$handleEv3.worldCoords;
355
+
317
356
  var center = model.widgetState.getCenter();
357
+ var currentVectorToOrigin = [0, 0, 0];
358
+ subtract(worldCoords, center, currentVectorToOrigin);
359
+ normalize(currentVectorToOrigin);
318
360
  var previousLineDirection = activeLineHandle.getDirection();
319
361
  normalize(previousLineDirection);
362
+ var activePointName = publicAPI.getActiveRotationPointName();
320
363
 
321
- if (publicAPI.getActiveRotationPointName() === 'point1') {
364
+ if (activePointName === 'point1' || !activePointName && dot(currentVectorToOrigin, previousLineDirection) < 0) {
322
365
  multiplyScalar(previousLineDirection, -1);
323
366
  }
324
367
 
325
- var currentVectorToOrigin = [0, 0, 0];
326
- subtract(worldCoords, center, currentVectorToOrigin);
327
- normalize(currentVectorToOrigin);
328
368
  var radianAngle = signedAngleBetweenVectors(previousLineDirection, currentVectorToOrigin, planeNormal);
329
369
  publicAPI.rotateLineInView(publicAPI.getActiveLineName(), radianAngle);
330
370
  };
@@ -342,7 +382,7 @@ function widgetBehavior(publicAPI, model) {
342
382
  publicAPI.rotatePlane(viewType, radianAngle, planeNormal);
343
383
 
344
384
  if (publicAPI.getKeepOrthogonality()) {
345
- var otherLineName = getOtherLineName(lineName);
385
+ var otherLineName = getOtherLineName(model.widgetState, lineName);
346
386
  var otherPlaneName = getLinePlaneName(otherLineName);
347
387
  publicAPI.rotatePlane(planeNameToViewType[otherPlaneName], radianAngle, planeNormal);
348
388
  }
@@ -371,8 +411,6 @@ function widgetBehavior(publicAPI, model) {
371
411
  // initialization
372
412
  // --------------------------------------------------------------------------
373
413
 
374
-
375
- model.planeManipulator = vtkPlanePointManipulator.newInstance();
376
414
  }
377
415
 
378
416
  export { widgetBehavior as default };
@@ -0,0 +1,92 @@
1
+ import widgetBehavior$1 from './behavior.js';
2
+ import { InteractionMethodsName } from './Constants.js';
3
+ import { updateState } from './helpers.js';
4
+ import { ViewTypes } from '../../Core/WidgetManager/Constants.js';
5
+ import { vec3 } from 'gl-matrix';
6
+
7
+ function widgetBehavior(publicAPI, model) {
8
+ // We inherit resliceCursorBehavior
9
+ widgetBehavior$1(publicAPI, model);
10
+ var stretchPlaneName = 'Y';
11
+ var crossPlaneName = 'Z';
12
+
13
+ publicAPI.getActiveInteraction = function () {
14
+ if (model.widgetState.getStatesWithLabel("lineIn".concat(stretchPlaneName)).includes(model.activeState)) {
15
+ return InteractionMethodsName.TranslateCenterAndUpdatePlanes;
16
+ }
17
+
18
+ if (model.widgetState.getStatesWithLabel("lineIn".concat(crossPlaneName)).includes(model.activeState) || model.widgetState.getStatesWithLabel("rotationIn".concat(crossPlaneName)).includes(model.activeState)) {
19
+ return InteractionMethodsName.RotateLine;
20
+ }
21
+
22
+ return null;
23
+ };
24
+
25
+ publicAPI[InteractionMethodsName.TranslateCenterAndUpdatePlanes] = function (calldata) {
26
+ var _model$activeState$ge, _model$activeState, _model$activeState$ge2;
27
+
28
+ var manipulator = (_model$activeState$ge = (_model$activeState = model.activeState) === null || _model$activeState === void 0 ? void 0 : (_model$activeState$ge2 = _model$activeState.getManipulator) === null || _model$activeState$ge2 === void 0 ? void 0 : _model$activeState$ge2.call(_model$activeState)) !== null && _model$activeState$ge !== void 0 ? _model$activeState$ge : model.manipulator;
29
+
30
+ var _manipulator$handleEv = manipulator.handleEvent(calldata, model._apiSpecificRenderWindow),
31
+ worldCoords = _manipulator$handleEv.worldCoords,
32
+ worldDirection = _manipulator$handleEv.worldDirection;
33
+
34
+ publicAPI.updateCenterAndPlanes(worldCoords, worldDirection);
35
+ };
36
+
37
+ publicAPI.updateCenterAndPlanes = function (worldCoords, worldDirection) {
38
+ // Update center
39
+ var newBoundedCenter = publicAPI.getBoundedCenter(worldCoords);
40
+ model.widgetState.setCenter(newBoundedCenter); // Update planes if axes are given
41
+
42
+ if (worldDirection) {
43
+ var getAxis = function getAxis(idx) {
44
+ return vec3.normalize([], worldDirection.slice(3 * idx, 3 * idx + 3));
45
+ };
46
+
47
+ var planes = model.widgetState.getPlanes();
48
+ Object.keys(planes).forEach(function (viewType) {
49
+ switch (Number.parseInt(viewType, 10)) {
50
+ case ViewTypes.YZ_PLANE:
51
+ planes[viewType] = {
52
+ normal: getAxis(0),
53
+ viewUp: getAxis(2)
54
+ };
55
+ break;
56
+
57
+ case ViewTypes.XZ_PLANE:
58
+ planes[viewType] = {
59
+ normal: getAxis(1),
60
+ viewUp: getAxis(2)
61
+ };
62
+ break;
63
+
64
+ case ViewTypes.XY_PLANE:
65
+ planes[viewType] = {
66
+ normal: getAxis(2),
67
+ viewUp: getAxis(1)
68
+ };
69
+ break;
70
+ }
71
+ });
72
+ }
73
+
74
+ updateState(model.widgetState, model._factory.getScaleInPixels(), model._factory.getRotationHandlePosition());
75
+ };
76
+
77
+ publicAPI.translateCenterOnPlaneDirection = function (nbSteps) {
78
+ var _model$_factory$getMa;
79
+
80
+ var handleScroll = (_model$_factory$getMa = model._factory.getManipulator()) === null || _model$_factory$getMa === void 0 ? void 0 : _model$_factory$getMa.handleScroll;
81
+
82
+ if (handleScroll) {
83
+ var _handleScroll = handleScroll(nbSteps),
84
+ worldCoords = _handleScroll.worldCoords,
85
+ worldDirection = _handleScroll.worldDirection;
86
+
87
+ publicAPI.updateCenterAndPlanes(worldCoords, worldDirection);
88
+ }
89
+ };
90
+ }
91
+
92
+ export { widgetBehavior as default };
@@ -5,8 +5,7 @@ import vtkCutter from '../../../Filters/Core/Cutter.js';
5
5
  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
- import { ViewTypes } from '../../Core/WidgetManager/Constants.js';
9
- import { planeNames, lineNames, planeNameToViewType } from './Constants.js';
8
+ import { viewTypeToPlaneName, planeNameToViewType, planeNames } from './Constants.js';
10
9
 
11
10
  var EPSILON = 10e-7;
12
11
  /**
@@ -128,6 +127,18 @@ function rotateVector(vectorToBeRotated, axis, angle) {
128
127
  vtkMatrixBuilder.buildFromRadian().rotate(angle, axis).apply(rotatedVector);
129
128
  return rotatedVector;
130
129
  }
130
+ /**
131
+ * Return ['X', 'Y'] if there are only 2 planes defined in the widget state.
132
+ * Return ['X', 'Y', 'Z'] if there are 3 planes defined in the widget state.
133
+ * @param {object} widgetState the state of the widget
134
+ * @returns An array of plane names
135
+ */
136
+
137
+ function getPlaneNames(widgetState) {
138
+ return Object.keys(widgetState.getPlanes()).map(function (viewType) {
139
+ return viewTypeToPlaneName[viewType];
140
+ });
141
+ }
131
142
  /**
132
143
  * Return X if lineName == XinY|XinZ, Y if lineName == YinX|YinZ and Z otherwise
133
144
  * @param {string} lineName name of the line (YinX, ZinX, XinY, ZinY, XinZ, YinZ)
@@ -144,15 +155,39 @@ function getLinePlaneName(lineName) {
144
155
  function getLineInPlaneName(lineName) {
145
156
  return lineName[3];
146
157
  }
158
+ /**
159
+ * Returns ['XinY', 'YinX'] if planes == ['X', 'Y']
160
+ * ['XinY', 'XinZ', 'YinX', 'YinZ', 'ZinX', 'ZinY'] if planes == ['X', 'Y', 'Z']
161
+ * @param {string} planes name of the planes (e.g. ['X', 'Y'])
162
+ */
163
+
164
+ function getPlanesLineNames() {
165
+ var planes = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : planeNames;
166
+ var lines = [];
167
+ planes.forEach(function (plane) {
168
+ planes.forEach(function (inPlane) {
169
+ if (plane !== inPlane) {
170
+ lines.push("".concat(plane, "in").concat(inPlane));
171
+ }
172
+ });
173
+ });
174
+ return lines;
175
+ }
176
+ function getLineNames(widgetState) {
177
+ var planes = Object.keys(widgetState.getPlanes()).map(function (viewType) {
178
+ return viewTypeToPlaneName[viewType];
179
+ });
180
+ return getPlanesLineNames(planes);
181
+ }
147
182
  /**
148
183
  * Return ZinX if lineName == YinX, YinX if lineName == ZinX, ZinY if lineName == XinY...
149
184
  * @param {string} lineName name of the line (YinX, ZinX, XinY, ZinY, XinZ, YinZ)
150
185
  */
151
186
 
152
- function getOtherLineName(lineName) {
187
+ function getOtherLineName(widgetState, lineName) {
153
188
  var linePlaneName = getLinePlaneName(lineName);
154
189
  var lineInPlaneName = getLineInPlaneName(lineName);
155
- var otherLineName = planeNames.find(function (planeName) {
190
+ var otherLineName = getPlaneNames(widgetState).find(function (planeName) {
156
191
  return planeName !== linePlaneName && planeName !== lineInPlaneName;
157
192
  });
158
193
  return "".concat(otherLineName, "in").concat(lineInPlaneName);
@@ -165,33 +200,44 @@ function computeRotationHandleOriginOffset(axis, rotationHandlePosition, volumeD
165
200
 
166
201
 
167
202
  function updateState(widgetState, scaleInPixels, rotationHandlePosition) {
168
- // Compute line axis
169
- var xNormal = widgetState.getPlanes()[ViewTypes.YZ_PLANE].normal;
170
- var yNormal = widgetState.getPlanes()[ViewTypes.XZ_PLANE].normal;
171
- var zNormal = widgetState.getPlanes()[ViewTypes.XY_PLANE].normal;
172
- var axes = {
173
- XY: cross(xNormal, yNormal, []),
174
- YZ: cross(yNormal, zNormal, []),
175
- XZ: cross(zNormal, xNormal, [])
176
- };
177
- axes.YX = axes.XY;
178
- axes.ZY = axes.YZ;
179
- axes.ZX = axes.XZ;
203
+ var planes = Object.keys(widgetState.getPlanes()).map(function (viewType) {
204
+ return viewTypeToPlaneName[viewType];
205
+ }); // Generates an object as such:
206
+ // axes = {'XY': cross(X, Y), 'YX': cross(X, Y), 'YZ': cross(Y, Z)...}
207
+
208
+ var axes = planes.reduce(function (res, plane) {
209
+ planes.filter(function (otherPlane) {
210
+ return plane !== otherPlane;
211
+ }).forEach(function (otherPlane) {
212
+ var cross$1 = cross(widgetState.getPlanes()[planeNameToViewType[plane]].normal, widgetState.getPlanes()[planeNameToViewType[otherPlane]].normal, []);
213
+ res["".concat(plane).concat(otherPlane)] = cross$1;
214
+ res["".concat(otherPlane).concat(plane)] = cross$1;
215
+ });
216
+ return res;
217
+ }, {});
180
218
  var bounds = widgetState.getImage().getBounds();
181
219
  var center = widgetState.getCenter(); // Length of the principal diagonal.
182
220
 
183
221
  var pdLength = vtkBoundingBox.getDiagonalLength(bounds);
184
222
  widgetState.getCenterHandle().setOrigin(center);
185
- lineNames.forEach(function (lineName) {
223
+ getPlanesLineNames(planes).forEach(function (lineName) {
224
+ var _widgetState$$getMani, _widgetState$$getMani2, _widgetState$$getMani3, _widgetState$$getMani4, _lineHandle$getManipu, _lineHandle$getManipu2;
225
+
186
226
  var planeName = getLinePlaneName(lineName);
187
227
  var inPlaneName = getLineInPlaneName(lineName);
188
228
  var direction = axes["".concat(planeName).concat(inPlaneName)];
189
229
  widgetState["getRotationHandle".concat(lineName, "0")]().setOrigin(center);
230
+ (_widgetState$$getMani = widgetState["getRotationHandle".concat(lineName, "0")]().getManipulator()) === null || _widgetState$$getMani === void 0 ? void 0 : _widgetState$$getMani.setHandleOrigin(center);
231
+ (_widgetState$$getMani2 = widgetState["getRotationHandle".concat(lineName, "0")]().getManipulator()) === null || _widgetState$$getMani2 === void 0 ? void 0 : _widgetState$$getMani2.setHandleNormal(widgetState.getPlanes()[planeNameToViewType[planeName]].normal);
190
232
  widgetState["getRotationHandle".concat(lineName, "0")]().setOffset(computeRotationHandleOriginOffset(direction, rotationHandlePosition, pdLength, scaleInPixels));
191
233
  widgetState["getRotationHandle".concat(lineName, "1")]().setOrigin(center);
234
+ (_widgetState$$getMani3 = widgetState["getRotationHandle".concat(lineName, "1")]().getManipulator()) === null || _widgetState$$getMani3 === void 0 ? void 0 : _widgetState$$getMani3.setHandleOrigin(center);
235
+ (_widgetState$$getMani4 = widgetState["getRotationHandle".concat(lineName, "1")]().getManipulator()) === null || _widgetState$$getMani4 === void 0 ? void 0 : _widgetState$$getMani4.setHandleNormal(widgetState.getPlanes()[planeNameToViewType[planeName]].normal);
192
236
  widgetState["getRotationHandle".concat(lineName, "1")]().setOffset(computeRotationHandleOriginOffset(direction, -rotationHandlePosition, pdLength, scaleInPixels));
193
237
  var lineHandle = widgetState["getAxis".concat(lineName)]();
194
238
  lineHandle.setOrigin(center);
239
+ (_lineHandle$getManipu = lineHandle.getManipulator()) === null || _lineHandle$getManipu === void 0 ? void 0 : _lineHandle$getManipu.setHandleOrigin(center);
240
+ (_lineHandle$getManipu2 = lineHandle.getManipulator()) === null || _lineHandle$getManipu2 === void 0 ? void 0 : _lineHandle$getManipu2.setHandleNormal(widgetState.getPlanes()[planeNameToViewType[planeName]].normal);
195
241
  var scale = normalize(direction);
196
242
  var scale3 = lineHandle.getScale3();
197
243
  scale3[2] = 2 * scale;
@@ -222,4 +268,4 @@ function transformPlane(planeToTransform, targetCenter, targetNormal, targetView
222
268
  planeToTransform.setCenter(targetCenter);
223
269
  }
224
270
 
225
- export { boundPlane, boundPoint, boundPointOnPlane, getLineInPlaneName, getLinePlaneName, getOtherLineName, rotateVector, transformPlane, updateState };
271
+ export { boundPlane, boundPoint, boundPointOnPlane, getLineInPlaneName, getLineNames, getLinePlaneName, getOtherLineName, getPlaneNames, getPlanesLineNames, rotateVector, transformPlane, updateState };
@@ -1,8 +1,27 @@
1
1
  import _defineProperty from '@babel/runtime/helpers/defineProperty';
2
2
  import vtkStateBuilder from '../../Core/StateBuilder.js';
3
- import { ScrollingMethods, planeNames } from './Constants.js';
4
- import { ViewTypes } from '../../Core/WidgetManager/Constants.js';
3
+ import { planeNameToViewType, ScrollingMethods, planeNames } from './Constants.js';
5
4
 
5
+ 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; }
6
+
7
+ 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; }
8
+ var defaultPlanes = {
9
+ X: {
10
+ normal: [1, 0, 0],
11
+ viewUp: [0, 0, 1],
12
+ color3: [255, 0, 0]
13
+ },
14
+ Y: {
15
+ normal: [0, -1, 0],
16
+ viewUp: [0, 0, 1],
17
+ color3: [0, 255, 0]
18
+ },
19
+ Z: {
20
+ normal: [0, 0, -1],
21
+ viewUp: [0, -1, 0],
22
+ color3: [0, 0, 255]
23
+ }
24
+ };
6
25
  var viewsColor3 = {
7
26
  X: [255, 0, 0],
8
27
  // red
@@ -12,8 +31,7 @@ var viewsColor3 = {
12
31
 
13
32
  };
14
33
  function generateState() {
15
- var _initialValue;
16
-
34
+ var planes = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : planeNames;
17
35
  var state = vtkStateBuilder.createBuilder().addField({
18
36
  name: 'center',
19
37
  initialValue: [0, 0, 0]
@@ -25,16 +43,12 @@ function generateState() {
25
43
  initialValue: null
26
44
  }).addField({
27
45
  name: 'planes',
28
- initialValue: (_initialValue = {}, _defineProperty(_initialValue, ViewTypes.YZ_PLANE, {
29
- normal: [1, 0, 0],
30
- viewUp: [0, 0, 1]
31
- }), _defineProperty(_initialValue, ViewTypes.XZ_PLANE, {
32
- normal: [0, -1, 0],
33
- viewUp: [0, 0, 1]
34
- }), _defineProperty(_initialValue, ViewTypes.XY_PLANE, {
35
- normal: [0, 0, -1],
36
- viewUp: [0, -1, 0]
37
- }), _initialValue)
46
+ initialValue: planes.reduce(function (res, planeName) {
47
+ return _objectSpread(_objectSpread({}, res), {}, _defineProperty({}, planeNameToViewType[planeName], {
48
+ normal: defaultPlanes[planeName].normal,
49
+ viewUp: defaultPlanes[planeName].viewUp
50
+ }));
51
+ }, {})
38
52
  }).addField({
39
53
  name: 'scrollingMethod',
40
54
  initialValue: ScrollingMethods.MIDDLE_MOUSE_BUTTON
@@ -53,8 +67,8 @@ function generateState() {
53
67
  color3: [255, 255, 255]
54
68
  }
55
69
  });
56
- planeNames.reduce(function (viewState, view) {
57
- return planeNames.filter(function (v) {
70
+ planes.reduce(function (viewState, view) {
71
+ return planes.filter(function (v) {
58
72
  return v !== view;
59
73
  }).reduce(function (axisState, axis) {
60
74
  // Line handle
@@ -4,6 +4,7 @@ import macro from '../../macros.js';
4
4
  import vtkAbstractWidgetFactory from '../Core/AbstractWidgetFactory.js';
5
5
  import vtkPlane from '../../Common/DataModel/Plane.js';
6
6
  import vtkPlaneSource from '../../Filters/Sources/PlaneSource.js';
7
+ import vtkPlanePointManipulator from '../Manipulators/PlaneManipulator.js';
7
8
  import vtkLineHandleRepresentation from '../Representations/LineHandleRepresentation.js';
8
9
  import vtkSphereHandleRepresentation from '../Representations/SphereHandleRepresentation.js';
9
10
  import { e as distance2BetweenPoints, m as multiplyAccumulate, s as subtract, l as normalize, w as multiplyScalar, k as add } from '../../Common/Core/Math/index.js';
@@ -263,11 +264,9 @@ function vtkResliceCursorWidget(publicAPI, model) {
263
264
  updateCamera(renderer, normal, viewType, resetFocalPoint, keepCenterFocalDistance);
264
265
  };
265
266
 
266
- publicAPI.updateReslicePlane = function (imageReslice, viewType) {
267
- // Calculate appropriate pixel spacing for the reslicing
268
- var spacing = model.widgetState.getImage().getSpacing(); // Compute original (i.e. before rotation) plane (i.e. origin, p1, p2)
267
+ publicAPI.getPlaneSource = function (viewType) {
268
+ // Compute original (i.e. before rotation) plane (i.e. origin, p1, p2)
269
269
  // centered on cursor center.
270
-
271
270
  var planeSource = computeReslicePlaneOrigin(viewType);
272
271
  var _model$widgetState$ge = model.widgetState.getPlanes()[viewType],
273
272
  normal = _model$widgetState$ge.normal,
@@ -286,18 +285,25 @@ function vtkResliceCursorWidget(publicAPI, model) {
286
285
  planeSource.setOrigin.apply(planeSource, _toConsumableArray(boundedOrigin));
287
286
  planeSource.setPoint1.apply(planeSource, _toConsumableArray(boundedP1));
288
287
  planeSource.setPoint2.apply(planeSource, _toConsumableArray(boundedP2));
289
- var o = planeSource.getOrigin();
288
+ return planeSource;
289
+ };
290
+
291
+ publicAPI.getResliceAxes = function (viewType) {
292
+ // Compute original (i.e. before rotation) plane (i.e. origin, p1, p2)
293
+ // centered on cursor center.
294
+ var planeSource = publicAPI.getPlaneSource(viewType); // TBD: use normal from planeSource ?
295
+
296
+ var normal = model.widgetState.getPlanes()[viewType].normal;
297
+ var planeOrigin = planeSource.getOrigin();
290
298
  var p1 = planeSource.getPoint1();
291
299
  var planeAxis1 = [];
292
- subtract(p1, o, planeAxis1);
300
+ subtract(p1, planeOrigin, planeAxis1);
301
+ normalize(planeAxis1);
293
302
  var p2 = planeSource.getPoint2();
294
303
  var planeAxis2 = [];
295
- subtract(p2, o, planeAxis2); // The x,y dimensions of the plane
296
-
297
- var planeSizeX = normalize(planeAxis1);
298
- var planeSizeY = normalize(planeAxis2);
304
+ subtract(p2, planeOrigin, planeAxis2);
305
+ normalize(planeAxis2);
299
306
  var newResliceAxes = mat4.identity(new Float64Array(16));
300
- var planeOrigin = planeSource.getOrigin();
301
307
 
302
308
  for (var i = 0; i < 3; i++) {
303
309
  newResliceAxes[i] = planeAxis1[i];
@@ -306,6 +312,21 @@ function vtkResliceCursorWidget(publicAPI, model) {
306
312
  newResliceAxes[12 + i] = planeOrigin[i];
307
313
  }
308
314
 
315
+ return newResliceAxes;
316
+ };
317
+
318
+ publicAPI.updateReslicePlane = function (imageReslice, viewType) {
319
+ // Calculate appropriate pixel spacing for the reslicing
320
+ var spacing = model.widgetState.getImage().getSpacing();
321
+ var planeSource = publicAPI.getPlaneSource(viewType);
322
+ var newResliceAxes = publicAPI.getResliceAxes(viewType);
323
+ var planeOrigin = planeSource.getOrigin();
324
+ var p1 = planeSource.getPoint1();
325
+ var planeAxis1 = subtract(p1, planeOrigin, []);
326
+ var planeSizeX = normalize(planeAxis1);
327
+ var p2 = planeSource.getPoint2();
328
+ var planeAxis2 = subtract(p2, planeOrigin, []);
329
+ var planeSizeY = normalize(planeAxis2);
309
330
  var spacingX = Math.abs(planeAxis1[0] * spacing[0]) + Math.abs(planeAxis1[1] * spacing[1]) + Math.abs(planeAxis1[2] * spacing[2]);
310
331
  var spacingY = Math.abs(planeAxis2[0] * spacing[0]) + Math.abs(planeAxis2[1] * spacing[1]) + Math.abs(planeAxis2[2] * spacing[2]); // Compute a new set of resliced extents
311
332
 
@@ -350,12 +371,7 @@ function vtkResliceCursorWidget(publicAPI, model) {
350
371
  modified = imageReslice.setOutputSpacing([outputSpacingX, outputSpacingY, 1]) || modified;
351
372
  modified = imageReslice.setOutputOrigin([0.5 * outputSpacingX, 0.5 * outputSpacingY, 0]) || modified;
352
373
  modified = imageReslice.setOutputExtent([0, extentX - 1, 0, extentY - 1, 0, 0]) || modified;
353
- return {
354
- modified: modified,
355
- origin: o,
356
- point1: p1,
357
- point2: p2
358
- };
374
+ return modified;
359
375
  };
360
376
  /**
361
377
  * Returns a plane source with origin at cursor center and
@@ -429,13 +445,20 @@ function vtkResliceCursorWidget(publicAPI, model) {
429
445
  });
430
446
  } // ----------------------------------------------------------------------------
431
447
 
448
+ /**
449
+ * Initializes the model.
450
+ * @param {*} initialValues optional object of member variables. initialValues.planes is an optional list of axis names (e.g. ['X', 'Y'])
451
+ * @returns the initial model object
452
+ */
453
+
432
454
 
433
455
  var defaultValues = function defaultValues(initialValues) {
434
456
  return _objectSpread({
435
457
  behavior: widgetBehavior,
436
- widgetState: generateState(),
458
+ widgetState: generateState(initialValues.planes),
437
459
  rotationHandlePosition: 0.5,
438
- scaleInPixels: true
460
+ scaleInPixels: true,
461
+ manipulator: vtkPlanePointManipulator.newInstance()
439
462
  }, initialValues);
440
463
  }; // ----------------------------------------------------------------------------
441
464
 
@@ -444,7 +467,7 @@ function extend(publicAPI, model) {
444
467
  var initialValues = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
445
468
  Object.assign(model, defaultValues(initialValues));
446
469
  vtkAbstractWidgetFactory.extend(publicAPI, model, initialValues);
447
- macro.setGet(publicAPI, model, ['scaleInPixels', 'rotationHandlePosition']);
470
+ macro.setGet(publicAPI, model, ['scaleInPixels', 'rotationHandlePosition', 'manipulator']);
448
471
  vtkResliceCursorWidget(publicAPI, model);
449
472
  } // ----------------------------------------------------------------------------
450
473
 
@@ -369,7 +369,8 @@ function widgetBehavior(publicAPI, model) {
369
369
  model.shapeHandle.setDirection(normal);
370
370
  }
371
371
 
372
- var worldCoords = manipulator.handleEvent(callData, model._apiSpecificRenderWindow);
372
+ var _manipulator$handleEv = manipulator.handleEvent(callData, model._apiSpecificRenderWindow),
373
+ worldCoords = _manipulator$handleEv.worldCoords;
373
374
 
374
375
  if (!worldCoords.length) {
375
376
  return macro.VOID;
@@ -413,7 +414,8 @@ function widgetBehavior(publicAPI, model) {
413
414
  }
414
415
 
415
416
  if (model.hasFocus) {
416
- var worldCoords = manipulator.handleEvent(e, model._apiSpecificRenderWindow);
417
+ var _manipulator$handleEv2 = manipulator.handleEvent(e, model._apiSpecificRenderWindow),
418
+ worldCoords = _manipulator$handleEv2.worldCoords;
417
419
 
418
420
  if (!model.point1) {
419
421
  model.point1Handle.setOrigin(worldCoords);
@@ -56,7 +56,7 @@ function widgetBehavior(publicAPI, model) {
56
56
  var _model$activeState$ge, _model$activeState, _model$activeState$ge2;
57
57
 
58
58
  var manipulator = (_model$activeState$ge = (_model$activeState = model.activeState) === null || _model$activeState === void 0 ? void 0 : (_model$activeState$ge2 = _model$activeState.getManipulator) === null || _model$activeState$ge2 === void 0 ? void 0 : _model$activeState$ge2.call(_model$activeState)) !== null && _model$activeState$ge !== void 0 ? _model$activeState$ge : model.manipulator;
59
- return manipulator.handleEvent(e, model._apiSpecificRenderWindow);
59
+ return manipulator.handleEvent(e, model._apiSpecificRenderWindow).worldCoords;
60
60
  } // Update the sphere's center and radius. Example:
61
61
  // handle.setCenterAndRadius([1,2,3], 10);
62
62