@kitware/vtk.js 34.11.2 → 34.12.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 (32) hide show
  1. package/Common/DataModel/BoundingBox.js +8 -8
  2. package/Filters/Sources/TorusSource.js +107 -0
  3. package/Filters/Sources.js +3 -1
  4. package/Interaction/Style/InteractorStyleMPRSlice.js +15 -23
  5. package/Interaction/Style/InteractorStyleManipulator.js +1 -0
  6. package/Proxy/Representations/GlyphRepresentationProxy.js +1 -0
  7. package/Rendering/Core/Prop3D.js +16 -0
  8. package/Widgets/Manipulators/PlaneManipulator.js +2 -2
  9. package/Widgets/Manipulators.js +2 -2
  10. package/Widgets/Representations/RotateTransformHandleRepresentation.js +46 -0
  11. package/Widgets/Representations/ScaleTransformHandleRepresentation.js +57 -0
  12. package/Widgets/Representations/TranslateTransformHandleRepresentation/TransformHandleSource.js +85 -0
  13. package/Widgets/Representations/TranslateTransformHandleRepresentation.js +57 -0
  14. package/Widgets/Representations.js +6 -0
  15. package/Widgets/Widgets3D/AngleWidget.js +2 -2
  16. package/Widgets/Widgets3D/EllipseWidget.js +2 -2
  17. package/Widgets/Widgets3D/ImageCroppingWidget.js +3 -3
  18. package/Widgets/Widgets3D/ImplicitPlaneWidget.js +2 -2
  19. package/Widgets/Widgets3D/LabelWidget.js +2 -2
  20. package/Widgets/Widgets3D/LineWidget.js +2 -2
  21. package/Widgets/Widgets3D/PaintWidget.js +2 -2
  22. package/Widgets/Widgets3D/PolyLineWidget.js +2 -2
  23. package/Widgets/Widgets3D/RectangleWidget.js +2 -2
  24. package/Widgets/Widgets3D/ResliceCursorWidget.js +2 -2
  25. package/Widgets/Widgets3D/SphereWidget.js +2 -2
  26. package/Widgets/Widgets3D/SplineWidget.js +2 -2
  27. package/Widgets/Widgets3D/TransformControlsWidget/behavior.js +180 -0
  28. package/Widgets/Widgets3D/TransformControlsWidget/constants.js +15 -0
  29. package/Widgets/Widgets3D/TransformControlsWidget/state.js +157 -0
  30. package/Widgets/Widgets3D/TransformControlsWidget.js +147 -0
  31. package/Widgets/Widgets3D.js +3 -1
  32. package/package.json +4 -4
@@ -1,7 +1,7 @@
1
1
  import { m as macro } from '../../macros2.js';
2
2
  import vtkAbstractWidgetFactory from '../Core/AbstractWidgetFactory.js';
3
3
  import vtkSphereHandleRepresentation from '../Representations/SphereHandleRepresentation.js';
4
- import vtkPlanePointManipulator from '../Manipulators/PlaneManipulator.js';
4
+ import vtkPlaneManipulator from '../Manipulators/PlaneManipulator.js';
5
5
  import widgetBehavior from './LabelWidget/behavior.js';
6
6
  import generateState from './LabelWidget/state.js';
7
7
  import { ViewTypes } from '../Core/WidgetManager/Constants.js';
@@ -45,7 +45,7 @@ function vtkLabelWidget(publicAPI, model) {
45
45
  // --------------------------------------------------------------------------
46
46
 
47
47
  // Default manipulator
48
- publicAPI.setManipulator(model.manipulator || vtkPlanePointManipulator.newInstance({
48
+ publicAPI.setManipulator(model.manipulator || vtkPlaneManipulator.newInstance({
49
49
  useCameraNormal: true
50
50
  }));
51
51
  }
@@ -3,7 +3,7 @@ import { m as macro } from '../../macros2.js';
3
3
  import generateState from './LineWidget/state.js';
4
4
  import vtkAbstractWidgetFactory from '../Core/AbstractWidgetFactory.js';
5
5
  import vtkArrowHandleRepresentation from '../Representations/ArrowHandleRepresentation.js';
6
- import vtkPlanePointManipulator from '../Manipulators/PlaneManipulator.js';
6
+ import vtkPlaneManipulator from '../Manipulators/PlaneManipulator.js';
7
7
  import vtkPolyLineRepresentation from '../Representations/PolyLineRepresentation.js';
8
8
  import widgetBehavior from './LineWidget/behavior.js';
9
9
  import { Behavior } from '../Representations/WidgetRepresentation/Constants.js';
@@ -145,7 +145,7 @@ function vtkLineWidget(publicAPI, model) {
145
145
  });
146
146
 
147
147
  // Default manipulator
148
- publicAPI.setManipulator(model.manipulator || vtkPlanePointManipulator.newInstance({
148
+ publicAPI.setManipulator(model.manipulator || vtkPlaneManipulator.newInstance({
149
149
  useCameraNormal: true
150
150
  }));
151
151
  publicAPI.delete = macro.chain(publicAPI.delete, () => {
@@ -1,7 +1,7 @@
1
1
  import { m as macro } from '../../macros2.js';
2
2
  import vtkAbstractWidgetFactory from '../Core/AbstractWidgetFactory.js';
3
3
  import vtkCircleContextRepresentation from '../Representations/CircleContextRepresentation.js';
4
- import vtkPlanePointManipulator from '../Manipulators/PlaneManipulator.js';
4
+ import vtkPlaneManipulator from '../Manipulators/PlaneManipulator.js';
5
5
  import vtkSphereHandleRepresentation from '../Representations/SphereHandleRepresentation.js';
6
6
  import widgetBehavior from './PaintWidget/behavior.js';
7
7
  import generateState from './PaintWidget/state.js';
@@ -57,7 +57,7 @@ function vtkPaintWidget(publicAPI, model) {
57
57
  // --------------------------------------------------------------------------
58
58
 
59
59
  // Default manipulator
60
- publicAPI.setManipulator(model.manipulator || vtkPlanePointManipulator.newInstance({
60
+ publicAPI.setManipulator(model.manipulator || vtkPlaneManipulator.newInstance({
61
61
  useCameraNormal: true
62
62
  }));
63
63
  }
@@ -1,6 +1,6 @@
1
1
  import { m as macro } from '../../macros2.js';
2
2
  import vtkAbstractWidgetFactory from '../Core/AbstractWidgetFactory.js';
3
- import vtkPlanePointManipulator from '../Manipulators/PlaneManipulator.js';
3
+ import vtkPlaneManipulator from '../Manipulators/PlaneManipulator.js';
4
4
  import vtkPolyLineRepresentation from '../Representations/PolyLineRepresentation.js';
5
5
  import vtkSphereHandleRepresentation from '../Representations/SphereHandleRepresentation.js';
6
6
  import widgetBehavior from './PolyLineWidget/behavior.js';
@@ -54,7 +54,7 @@ function vtkPolyLineWidget(publicAPI, model) {
54
54
  // --------------------------------------------------------------------------
55
55
 
56
56
  // Default manipulator
57
- publicAPI.setManipulator(model.manipulator || vtkPlanePointManipulator.newInstance({
57
+ publicAPI.setManipulator(model.manipulator || vtkPlaneManipulator.newInstance({
58
58
  useCameraFocalPoint: true,
59
59
  useCameraNormal: true
60
60
  }));
@@ -1,5 +1,5 @@
1
1
  import { m as macro } from '../../macros2.js';
2
- import vtkPlanePointManipulator from '../Manipulators/PlaneManipulator.js';
2
+ import vtkPlaneManipulator from '../Manipulators/PlaneManipulator.js';
3
3
  import vtkShapeWidget from './ShapeWidget.js';
4
4
  import vtkSphereHandleRepresentation from '../Representations/SphereHandleRepresentation.js';
5
5
  import vtkRectangleContextRepresentation from '../Representations/RectangleContextRepresentation.js';
@@ -39,7 +39,7 @@ function vtkRectangleWidget(publicAPI, model) {
39
39
  // initialization
40
40
  // --------------------------------------------------------------------------
41
41
 
42
- model.manipulator = vtkPlanePointManipulator.newInstance({
42
+ model.manipulator = vtkPlaneManipulator.newInstance({
43
43
  useCameraNormal: true
44
44
  });
45
45
  }
@@ -4,7 +4,7 @@ import vtkBoundingBox from '../../Common/DataModel/BoundingBox.js';
4
4
  import vtkBox from '../../Common/DataModel/Box.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
+ import vtkPlaneManipulator from '../Manipulators/PlaneManipulator.js';
8
8
  import vtkLineHandleRepresentation from '../Representations/LineHandleRepresentation.js';
9
9
  import vtkSphereHandleRepresentation from '../Representations/SphereHandleRepresentation.js';
10
10
  import { e as distance2BetweenPoints, m as multiplyAccumulate, s as subtract, l as normalize, x as multiplyScalar, k as add } from '../../Common/Core/Math/index.js';
@@ -428,7 +428,7 @@ const defaultValues = initialValues => ({
428
428
  widgetState: generateState(initialValues.planes),
429
429
  rotationHandlePosition: 0.5,
430
430
  scaleInPixels: true,
431
- manipulator: vtkPlanePointManipulator.newInstance(),
431
+ manipulator: vtkPlaneManipulator.newInstance(),
432
432
  ...initialValues
433
433
  });
434
434
 
@@ -1,6 +1,6 @@
1
1
  import { e as distance2BetweenPoints } from '../../Common/Core/Math/index.js';
2
2
  import vtkAbstractWidgetFactory from '../Core/AbstractWidgetFactory.js';
3
- import vtkPlanePointManipulator from '../Manipulators/PlaneManipulator.js';
3
+ import vtkPlaneManipulator from '../Manipulators/PlaneManipulator.js';
4
4
  import vtkSphereHandleRepresentation from '../Representations/SphereHandleRepresentation.js';
5
5
  import vtkSphereContextRepresentation from '../Representations/SphereContextRepresentation.js';
6
6
  import { m as macro } from '../../macros2.js';
@@ -45,7 +45,7 @@ function vtkSphereWidget(publicAPI, model) {
45
45
  // initialization
46
46
  // --------------------------------------------------------------------------
47
47
 
48
- publicAPI.setManipulator(model.manipulator || vtkPlanePointManipulator.newInstance({
48
+ publicAPI.setManipulator(model.manipulator || vtkPlaneManipulator.newInstance({
49
49
  useCameraNormal: true
50
50
  }));
51
51
  }
@@ -1,6 +1,6 @@
1
1
  import { m as macro } from '../../macros2.js';
2
2
  import vtkAbstractWidgetFactory from '../Core/AbstractWidgetFactory.js';
3
- import vtkPlanePointManipulator from '../Manipulators/PlaneManipulator.js';
3
+ import vtkPlaneManipulator from '../Manipulators/PlaneManipulator.js';
4
4
  import vtkSplineContextRepresentation from '../Representations/SplineContextRepresentation.js';
5
5
  import vtkSphereHandleRepresentation from '../Representations/SphereHandleRepresentation.js';
6
6
  import widgetBehavior from './SplineWidget/behavior.js';
@@ -51,7 +51,7 @@ function vtkSplineWidget(publicAPI, model) {
51
51
  // --------------------------------------------------------------------------
52
52
 
53
53
  // Default manipulator
54
- publicAPI.setManipulator(model.manipulator || model.manipulator || vtkPlanePointManipulator.newInstance({
54
+ publicAPI.setManipulator(model.manipulator || model.manipulator || vtkPlaneManipulator.newInstance({
55
55
  useCameraNormal: true
56
56
  }));
57
57
  }
@@ -0,0 +1,180 @@
1
+ import { quat, vec3 } from 'gl-matrix';
2
+ import { m as macro } from '../../../macros2.js';
3
+ import vtkBoundingBox from '../../../Common/DataModel/BoundingBox.js';
4
+ import vtkPlaneManipulator from '../../Manipulators/PlaneManipulator.js';
5
+ import vtkLineManipulator from '../../Manipulators/LineManipulator.js';
6
+
7
+ function widgetBehavior(publicAPI, model) {
8
+ let isDragging = false;
9
+ model.rotationManipulator = vtkPlaneManipulator.newInstance();
10
+ model.lineManipulator = vtkLineManipulator.newInstance();
11
+ const rotateState = {
12
+ startQuat: quat.create(),
13
+ dragStartVec: [0, 0, 0]
14
+ };
15
+ const scaleState = {
16
+ startDistFromOrigin: 0,
17
+ startScale: 1
18
+ };
19
+ const translateState = {
20
+ startPos: 0,
21
+ dragStartCoord: [0, 0, 0]
22
+ };
23
+ publicAPI.getBounds = () => [...vtkBoundingBox.INIT_BOUNDS];
24
+ publicAPI.setDisplayCallback = callback => model.representations[0].setDisplayCallback(callback);
25
+ publicAPI.handleLeftButtonPress = callData => {
26
+ if (!model.activeState || !model.activeState.getActive() || !model.pickable) {
27
+ return macro.VOID;
28
+ }
29
+ const [type, axis] = model.activeState.getName().split(':');
30
+ const axisIndex = 'XYZ'.indexOf(axis);
31
+ if (type === 'translate') {
32
+ publicAPI.handleTranslateStartEvent(callData, axis, axisIndex);
33
+ } else if (type === 'scale') {
34
+ publicAPI.handleScaleStartEvent(callData, axis, axisIndex);
35
+ } else if (type === 'rotate') {
36
+ publicAPI.handleRotateStartEvent(callData, axis, axisIndex);
37
+ }
38
+ model._interactor.requestAnimation(publicAPI);
39
+ return macro.EVENT_ABORT;
40
+ };
41
+ publicAPI.handleTranslateStartEvent = (callData, axis, axisIndex) => {
42
+ model.lineManipulator.setHandleOrigin(model.activeState.getOrigin());
43
+ model.lineManipulator.setHandleNormal(model.activeState.getDirection());
44
+ const {
45
+ worldCoords
46
+ } = model.lineManipulator.handleEvent(callData, model._apiSpecificRenderWindow);
47
+ if (worldCoords.length) {
48
+ isDragging = true;
49
+ translateState.dragStartCoord = worldCoords;
50
+ translateState.startPos = model.widgetState.getTransform().getTranslation()[axisIndex];
51
+ }
52
+ };
53
+ publicAPI.handleScaleStartEvent = (callData, axis, axisIndex) => {
54
+ model.lineManipulator.setHandleOrigin(model.activeState.getOrigin());
55
+ model.lineManipulator.setHandleNormal(model.activeState.getDirection());
56
+ const {
57
+ worldCoords
58
+ } = model.lineManipulator.handleEvent(callData, model._apiSpecificRenderWindow);
59
+ if (worldCoords.length) {
60
+ isDragging = true;
61
+ scaleState.startScale = model.widgetState.getTransform().getScale()[axisIndex];
62
+ scaleState.startDistFromOrigin = vec3.dist(worldCoords, model.activeState.getOrigin()) || 0.0001;
63
+ }
64
+ };
65
+ publicAPI.handleRotateStartEvent = (callData, axis) => {
66
+ model.rotationManipulator.setHandleOrigin(model.activeState.getOrigin());
67
+ model.rotationManipulator.setHandleNormal(model.activeState.getDirection());
68
+
69
+ // compute unit vector from center of rotation
70
+ // to the click point on the plane defined by
71
+ // the center of rotation and the rotation normal.
72
+ const {
73
+ worldCoords
74
+ } = model.rotationManipulator.handleEvent(callData, model._apiSpecificRenderWindow);
75
+ if (worldCoords.length) {
76
+ isDragging = true;
77
+ vec3.sub(rotateState.dragStartVec, worldCoords, model.activeState.getOrigin());
78
+ vec3.normalize(rotateState.dragStartVec, rotateState.dragStartVec);
79
+ rotateState.startQuat = model.widgetState.getTransform().getRotation();
80
+ }
81
+ };
82
+ publicAPI.handleMouseMove = callData => {
83
+ if (isDragging && model.pickable) {
84
+ return publicAPI.handleEvent(callData);
85
+ }
86
+ return macro.VOID;
87
+ };
88
+ publicAPI.handleLeftButtonRelease = () => {
89
+ if (isDragging && model.pickable) {
90
+ model._interactor.cancelAnimation(publicAPI);
91
+ }
92
+ isDragging = false;
93
+ model.widgetState.deactivate();
94
+ };
95
+ publicAPI.handleEvent = callData => {
96
+ if (model.pickable && model.activeState && model.activeState.getActive()) {
97
+ const [type, axis] = model.activeState.getName().split(':');
98
+ const axisIndex = 'XYZ'.indexOf(axis);
99
+ if (type === 'translate') {
100
+ return publicAPI.handleTranslateEvent(callData, axis, axisIndex);
101
+ }
102
+ if (type === 'scale') {
103
+ return publicAPI.handleScaleEvent(callData, axis, axisIndex);
104
+ }
105
+ if (type === 'rotate') {
106
+ return publicAPI.handleRotateEvent(callData, axis, axisIndex);
107
+ }
108
+ }
109
+ return macro.VOID;
110
+ };
111
+ publicAPI.handleTranslateEvent = (callData, axis, axisIndex) => {
112
+ model.lineManipulator.setHandleOrigin(model.activeState.getOrigin());
113
+ model.lineManipulator.setHandleNormal(model.activeState.getDirection());
114
+ const {
115
+ worldCoords
116
+ } = model.lineManipulator.handleEvent(callData, model._apiSpecificRenderWindow);
117
+ if (worldCoords.length) {
118
+ const positiveDir = [0, 0, 0];
119
+ positiveDir[axisIndex] = 1;
120
+ const toWorldCoords = [0, 0, 0];
121
+ vec3.sub(toWorldCoords, worldCoords, translateState.dragStartCoord);
122
+ const dir = Math.sign(vec3.dot(positiveDir, toWorldCoords));
123
+ const dist = vec3.len(toWorldCoords);
124
+ const delta = dir * dist;
125
+ const translation = model.widgetState.getTransform().getTranslation();
126
+ translation[axisIndex] = translateState.startPos + delta;
127
+ model.widgetState.getTransform().setTranslation(translation);
128
+ }
129
+ };
130
+ publicAPI.handleScaleEvent = (callData, axis, axisIndex) => {
131
+ model.lineManipulator.setHandleOrigin(model.activeState.getOrigin());
132
+ model.lineManipulator.setHandleNormal(model.activeState.getDirection());
133
+ const {
134
+ worldCoords
135
+ } = model.lineManipulator.handleEvent(callData, model._apiSpecificRenderWindow);
136
+ if (worldCoords.length) {
137
+ const dist = vec3.dist(model.activeState.getOrigin(), worldCoords);
138
+ const scale = dist / scaleState.startDistFromOrigin * scaleState.startScale;
139
+ const scales = model.widgetState.getTransform().getScale();
140
+ scales[axisIndex] = scale;
141
+ model.widgetState.getTransform().setScale(scales);
142
+ }
143
+ };
144
+ publicAPI.handleRotateEvent = callData => {
145
+ model.rotationManipulator.setHandleOrigin(model.activeState.getOrigin());
146
+ model.rotationManipulator.setHandleNormal(model.activeState.getDirection());
147
+ const {
148
+ worldCoords
149
+ } = model.rotationManipulator.handleEvent(callData, model._apiSpecificRenderWindow);
150
+ const curPointerVec = [0, 0, 0];
151
+ if (worldCoords.length) {
152
+ vec3.sub(curPointerVec, worldCoords, model.activeState.getOrigin());
153
+ vec3.normalize(curPointerVec, curPointerVec);
154
+ const angle = vec3.angle(rotateState.dragStartVec, curPointerVec);
155
+ const signVec = [0, 0, 0];
156
+ vec3.cross(signVec, curPointerVec, rotateState.dragStartVec);
157
+ vec3.normalize(signVec, signVec);
158
+ const sign = vec3.dot(signVec, model.activeState.getDirection());
159
+ const q = quat.create();
160
+ quat.setAxisAngle(q, model.activeState.getDirection(), -sign * angle);
161
+ quat.mul(q, q, rotateState.startQuat);
162
+ quat.normalize(q, q);
163
+
164
+ // do not amplify fp errors when editing a particular direction
165
+ const direction = model.activeState.getDirection();
166
+ model.widgetState.getTransform().setRotation(q);
167
+ model.activeState.setDirection(direction);
168
+ }
169
+ return macro.EVENT_ABORT;
170
+ };
171
+
172
+ // --------------------------------------------------------------------------
173
+ // initialization
174
+ // --------------------------------------------------------------------------
175
+
176
+ model.camera = model._renderer.getActiveCamera();
177
+ model.classHierarchy.push('vtkTransformControlsWidgetProp');
178
+ }
179
+
180
+ export { widgetBehavior as default };
@@ -0,0 +1,15 @@
1
+ const ROTATE_HANDLE_PIXEL_SCALE = 240;
2
+ const TRANSLATE_HANDLE_RADIUS = 3;
3
+ const SCALE_HANDLE_RADIUS = 3;
4
+ const SCALE_HANDLE_CUBE_SIDE_LENGTH = 20;
5
+ const SCALE_HANDLE_PIXEL_SCALE = 320;
6
+ const TransformMode = {
7
+ TRANSLATE: 'translate',
8
+ SCALE: 'scale',
9
+ ROTATE: 'rotate'
10
+ };
11
+ var constants = {
12
+ TransformMode
13
+ };
14
+
15
+ export { ROTATE_HANDLE_PIXEL_SCALE, SCALE_HANDLE_CUBE_SIDE_LENGTH, SCALE_HANDLE_PIXEL_SCALE, SCALE_HANDLE_RADIUS, TRANSLATE_HANDLE_RADIUS, TransformMode, constants as default };
@@ -0,0 +1,157 @@
1
+ import vtkStateBuilder from '../../Core/StateBuilder.js';
2
+ import { SCALE_HANDLE_PIXEL_SCALE, ROTATE_HANDLE_PIXEL_SCALE } from './constants.js';
3
+
4
+ function stateGenerator() {
5
+ const transformState = vtkStateBuilder.createBuilder().addField({
6
+ name: 'translation',
7
+ initialValue: [0, 0, 0]
8
+ }).addField({
9
+ name: 'scale',
10
+ initialValue: [1, 1, 1]
11
+ }).addField({
12
+ name: 'rotation',
13
+ initialValue: [0, 0, 0, 1]
14
+ }).build();
15
+ return vtkStateBuilder.createBuilder().addStateFromInstance({
16
+ labels: [],
17
+ name: 'transform',
18
+ instance: transformState
19
+ })
20
+
21
+ // translate state
22
+ .addStateFromMixin({
23
+ labels: ['handles', 'translateHandles'],
24
+ mixins: ['name', 'origin', 'color3', 'scale3', 'orientation', 'visible'],
25
+ name: 'translateHandleZ',
26
+ initialValues: {
27
+ name: 'translate:Z',
28
+ scale3: [1, 1, SCALE_HANDLE_PIXEL_SCALE],
29
+ origin: [0, 0, 0],
30
+ color3: [0, 255, 0],
31
+ // these are fixed to the world axes
32
+ up: [0, 1, 0],
33
+ right: [1, 0, 0],
34
+ direction: [0, 0, 1]
35
+ }
36
+ }).addStateFromMixin({
37
+ labels: ['handles', 'translateHandles'],
38
+ mixins: ['name', 'origin', 'color3', 'scale3', 'orientation', 'visible'],
39
+ name: 'translateHandleX',
40
+ initialValues: {
41
+ name: 'translate:X',
42
+ scale3: [1, 1, SCALE_HANDLE_PIXEL_SCALE],
43
+ origin: [0, 0, 0],
44
+ color3: [0, 0, 255],
45
+ // these are fixed to the world axes
46
+ up: [0, 1, 0],
47
+ right: [0, 0, -1],
48
+ direction: [1, 0, 0]
49
+ }
50
+ }).addStateFromMixin({
51
+ labels: ['handles', 'translateHandles'],
52
+ mixins: ['name', 'origin', 'color3', 'scale3', 'orientation', 'visible'],
53
+ name: 'translateHandleY',
54
+ initialValues: {
55
+ name: 'translate:Y',
56
+ scale3: [1, 1, SCALE_HANDLE_PIXEL_SCALE],
57
+ origin: [0, 0, 0],
58
+ color3: [255, 0, 0],
59
+ // these are fixed to the world axes
60
+ up: [0, 0, 1],
61
+ right: [1, 0, 0],
62
+ direction: [0, 1, 0]
63
+ }
64
+ })
65
+
66
+ // scale state
67
+ .addStateFromMixin({
68
+ labels: ['handles', 'scaleHandles'],
69
+ mixins: ['name', 'origin', 'color3', 'scale3', 'orientation', 'visible'],
70
+ name: 'scaleHandleZ',
71
+ initialValues: {
72
+ name: 'scale:Z',
73
+ scale3: [1, 1, SCALE_HANDLE_PIXEL_SCALE],
74
+ origin: [0, 0, 0],
75
+ color3: [0, 255, 0],
76
+ // these are set via setHandleOrientationsFromQuat
77
+ up: [0, 0, 1],
78
+ right: [0, 1, 0],
79
+ direction: [1, 0, 0]
80
+ }
81
+ }).addStateFromMixin({
82
+ labels: ['handles', 'scaleHandles'],
83
+ mixins: ['name', 'origin', 'color3', 'scale3', 'orientation', 'visible'],
84
+ name: 'scaleHandleX',
85
+ initialValues: {
86
+ name: 'scale:X',
87
+ scale3: [1, 1, SCALE_HANDLE_PIXEL_SCALE],
88
+ origin: [0, 0, 0],
89
+ color3: [0, 0, 255],
90
+ // these are set via setHandleOrientationsFromQuat
91
+ up: [1, 0, 0],
92
+ right: [0, -1, 0],
93
+ direction: [0, 0, 1]
94
+ }
95
+ }).addStateFromMixin({
96
+ labels: ['handles', 'scaleHandles'],
97
+ mixins: ['name', 'origin', 'color3', 'scale3', 'orientation', 'visible'],
98
+ name: 'scaleHandleY',
99
+ initialValues: {
100
+ name: 'scale:Y',
101
+ scale3: [1, 1, SCALE_HANDLE_PIXEL_SCALE],
102
+ origin: [0, 0, 0],
103
+ color3: [255, 0, 0],
104
+ // these are set via setHandleOrientationsFromQuat
105
+ up: [0, 1, 0],
106
+ right: [1, 0, 0],
107
+ direction: [0, 0, 1]
108
+ }
109
+ })
110
+
111
+ // rotation state
112
+ .addStateFromMixin({
113
+ labels: ['handles', 'rotateHandles'],
114
+ mixins: ['name', 'origin', 'color3', 'scale1', 'orientation', 'visible'],
115
+ name: 'rotateHandleZ',
116
+ initialValues: {
117
+ name: 'rotate:Z',
118
+ scale1: ROTATE_HANDLE_PIXEL_SCALE,
119
+ origin: [0, 0, 0],
120
+ color3: [0, 255, 0],
121
+ // these are set via setHandleOrientationsFromQuat
122
+ up: [0, 1, 0],
123
+ right: [1, 0, 0],
124
+ direction: [0, 0, 1]
125
+ }
126
+ }).addStateFromMixin({
127
+ labels: ['handles', 'rotateHandles'],
128
+ mixins: ['name', 'origin', 'color3', 'scale1', 'orientation', 'visible'],
129
+ name: 'rotateHandleX',
130
+ initialValues: {
131
+ name: 'rotate:X',
132
+ scale1: ROTATE_HANDLE_PIXEL_SCALE,
133
+ origin: [0, 0, 0],
134
+ color3: [0, 0, 255],
135
+ // these are set via setHandleOrientationsFromQuat
136
+ up: [0, 1, 0],
137
+ right: [0, 0, -1],
138
+ direction: [1, 0, 0]
139
+ }
140
+ }).addStateFromMixin({
141
+ labels: ['handles', 'rotateHandles'],
142
+ mixins: ['name', 'origin', 'color3', 'scale1', 'orientation', 'visible'],
143
+ name: 'rotateHandleY',
144
+ initialValues: {
145
+ name: 'rotate:Y',
146
+ scale1: ROTATE_HANDLE_PIXEL_SCALE,
147
+ origin: [0, 0, 0],
148
+ color3: [255, 0, 0],
149
+ // these are set via setHandleOrientationsFromQuat
150
+ up: [0, 0, 1],
151
+ right: [1, 0, 0],
152
+ direction: [0, 1, 0]
153
+ }
154
+ }).build();
155
+ }
156
+
157
+ export { stateGenerator as default };
@@ -0,0 +1,147 @@
1
+ import { mat3 } from 'gl-matrix';
2
+ import { m as macro } from '../../macros2.js';
3
+ import vtkAbstractWidgetFactory from '../Core/AbstractWidgetFactory.js';
4
+ import vtkTranslateTransformHandleRepresentation from '../Representations/TranslateTransformHandleRepresentation.js';
5
+ import vtkScaleTransformHandleRepresentation from '../Representations/ScaleTransformHandleRepresentation.js';
6
+ import vtkRotateTransformHandleRepresentation from '../Representations/RotateTransformHandleRepresentation.js';
7
+ import { TransformMode, TRANSLATE_HANDLE_RADIUS, SCALE_HANDLE_RADIUS, SCALE_HANDLE_CUBE_SIDE_LENGTH, SCALE_HANDLE_PIXEL_SCALE } from './TransformControlsWidget/constants.js';
8
+ import widgetBehavior from './TransformControlsWidget/behavior.js';
9
+ import stateGenerator from './TransformControlsWidget/state.js';
10
+
11
+ function updateHandleTransforms(widgetState) {
12
+ const transformState = widgetState.getTransform();
13
+ const sx = widgetState.getScaleHandleX();
14
+ const sy = widgetState.getScaleHandleY();
15
+ const sz = widgetState.getScaleHandleZ();
16
+ const hx = widgetState.getRotateHandleX();
17
+ const hy = widgetState.getRotateHandleY();
18
+ const hz = widgetState.getRotateHandleZ();
19
+
20
+ // translation
21
+ widgetState.getStatesWithLabel('handles').forEach(state => {
22
+ state.setOrigin(transformState.getTranslation());
23
+ });
24
+
25
+ // rotation
26
+ const m3 = mat3.create();
27
+ mat3.fromQuat(m3, transformState.getRotation());
28
+ [sx, hx].forEach(state => {
29
+ state.setDirection(m3.slice(0, 3));
30
+ state.setUp(m3.slice(3, 6).map(c => -c));
31
+ state.setRight(m3.slice(6, 9));
32
+ });
33
+ [sy, hy].forEach(state => {
34
+ state.setDirection(m3.slice(3, 6));
35
+ state.setUp(m3.slice(6, 9));
36
+ state.setRight(m3.slice(0, 3));
37
+ });
38
+ [sz, hz].forEach(state => {
39
+ state.setDirection(m3.slice(6, 9));
40
+ state.setUp(m3.slice(3, 6));
41
+ state.setRight(m3.slice(0, 3));
42
+ });
43
+ }
44
+
45
+ // ----------------------------------------------------------------------------
46
+ // Factory
47
+ // ----------------------------------------------------------------------------
48
+
49
+ function vtkTransformControlsWidget(publicAPI, model) {
50
+ model.classHierarchy.push('vtkTransformControlsWidget');
51
+
52
+ // --- Widget Requirement ---------------------------------------------------
53
+
54
+ model.behavior = widgetBehavior;
55
+ model.widgetState = stateGenerator();
56
+ model.methodsToLink = ['scaleInPixels', 'activeScaleFactor', 'useActiveColor', 'activeColor'];
57
+ publicAPI.getRepresentationsForViewType = viewType => {
58
+ switch (viewType) {
59
+ default:
60
+ return [{
61
+ builder: vtkTranslateTransformHandleRepresentation,
62
+ labels: ['translateHandles'],
63
+ initialValues: {
64
+ radius: TRANSLATE_HANDLE_RADIUS,
65
+ glyphResolution: 12,
66
+ coneSource: {
67
+ radius: 8,
68
+ height: 0.05,
69
+ direction: [0, 1, 0]
70
+ }
71
+ }
72
+ }, {
73
+ builder: vtkScaleTransformHandleRepresentation,
74
+ labels: ['scaleHandles'],
75
+ initialValues: {
76
+ radius: SCALE_HANDLE_RADIUS,
77
+ glyphResolution: 12,
78
+ cubeSource: {
79
+ xLength: SCALE_HANDLE_CUBE_SIDE_LENGTH,
80
+ yLength: SCALE_HANDLE_CUBE_SIDE_LENGTH / SCALE_HANDLE_PIXEL_SCALE,
81
+ zLength: SCALE_HANDLE_CUBE_SIDE_LENGTH
82
+ }
83
+ }
84
+ }, {
85
+ builder: vtkRotateTransformHandleRepresentation,
86
+ labels: ['rotateHandles']
87
+ }];
88
+ }
89
+ };
90
+ publicAPI.updateHandleVisibility = () => {
91
+ model.widgetState.getStatesWithLabel('translateHandles').forEach(state => {
92
+ state.setVisible(model.mode === 'translate');
93
+ });
94
+ model.widgetState.getStatesWithLabel('scaleHandles').forEach(state => {
95
+ state.setVisible(model.mode === 'scale');
96
+ });
97
+ model.widgetState.getStatesWithLabel('rotateHandles').forEach(state => {
98
+ state.setVisible(model.mode === 'rotate');
99
+ });
100
+ };
101
+ model._onModeChanged = () => {
102
+ publicAPI.updateHandleVisibility();
103
+ };
104
+
105
+ // --- Widget Requirement ---------------------------------------------------
106
+
107
+ // sync translation/scale/rotation states to the handle states
108
+ const transformSubscription = model.widgetState.getTransform().onModified(state => {
109
+ updateHandleTransforms(model.widgetState);
110
+ });
111
+ publicAPI.delete = macro.chain(publicAPI.delete, () => {
112
+ transformSubscription.unsubscribe();
113
+ });
114
+ updateHandleTransforms(model.widgetState);
115
+ publicAPI.updateHandleVisibility();
116
+ }
117
+
118
+ // ----------------------------------------------------------------------------
119
+
120
+ const DEFAULT_VALUES = {
121
+ mode: TransformMode.TRANSLATE
122
+ };
123
+
124
+ // ----------------------------------------------------------------------------
125
+
126
+ function extend(publicAPI, model) {
127
+ let initialValues = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
128
+ Object.assign(model, DEFAULT_VALUES, initialValues);
129
+ vtkAbstractWidgetFactory.extend(publicAPI, model, initialValues);
130
+ macro.setGet(publicAPI, model, ['mode']);
131
+ macro.get(publicAPI, model, ['lineManipulator', 'rotateManipulator']);
132
+ vtkTransformControlsWidget(publicAPI, model);
133
+ }
134
+
135
+ // ----------------------------------------------------------------------------
136
+
137
+ const newInstance = macro.newInstance(extend, 'vtkTransformControlsWidget');
138
+
139
+ // ----------------------------------------------------------------------------
140
+
141
+ var vtkTransformControlsWidget$1 = {
142
+ newInstance,
143
+ extend,
144
+ TransformMode
145
+ };
146
+
147
+ export { vtkTransformControlsWidget$1 as default, extend, newInstance };
@@ -12,6 +12,7 @@ import vtkResliceCursorWidget from './Widgets3D/ResliceCursorWidget.js';
12
12
  import vtkShapeWidget from './Widgets3D/ShapeWidget.js';
13
13
  import vtkSphereWidget from './Widgets3D/SphereWidget.js';
14
14
  import vtkSplineWidget from './Widgets3D/SplineWidget.js';
15
+ import vtkTransformControlsWidget from './Widgets3D/TransformControlsWidget.js';
15
16
 
16
17
  var Widgets3D = {
17
18
  vtkAngleWidget,
@@ -27,7 +28,8 @@ var Widgets3D = {
27
28
  vtkResliceCursorWidget,
28
29
  vtkShapeWidget,
29
30
  vtkSphereWidget,
30
- vtkSplineWidget
31
+ vtkSplineWidget,
32
+ vtkTransformControlsWidget
31
33
  };
32
34
 
33
35
  export { Widgets3D as default };