@kitware/vtk.js 34.11.3 → 34.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Common/Core/CellArray.d.ts +5 -0
- package/Common/Core/CellArray.js +1 -0
- package/Common/Core/Math/index.js +1 -1
- package/Common/Core/Math.d.ts +2 -1
- package/Common/Core/Math.js +1 -1
- package/Common/Core/MatrixBuilder.d.ts +1 -0
- package/Common/DataModel/BoundingBox.js +1 -0
- package/Common/DataModel/DataSet.js +57 -32
- package/Common/DataModel/DataSetAttributes/FieldData.js +2 -2
- package/Common/DataModel/ImageData.js +1 -1
- package/Common/DataModel/IncrementalOctreeNode.js +1 -1
- package/Common/DataModel/IncrementalOctreePointLocator.js +1 -1
- package/Common/DataModel/Line.js +1 -1
- package/Common/DataModel/MergePoints.js +2 -2
- package/Common/DataModel/Planes.js +1 -1
- package/Common/DataModel/PointLocator.js +1 -1
- package/Common/DataModel/PolyData.d.ts +9 -3
- package/Common/DataModel/PolyData.js +10 -1
- package/Common/DataModel/Polygon.js +1 -1
- package/Common/DataModel/Quad.js +1 -1
- package/Common/DataModel/Triangle.js +1 -1
- package/Common/Transform/Transform.d.ts +1 -0
- package/Common/Transform/Transform.js +1 -1
- package/Filters/Core/CleanPolyData.d.ts +208 -0
- package/Filters/Core/CleanPolyData.js +399 -0
- package/Filters/Core/PolyDataNormals.js +1 -1
- package/Filters/Core/ThresholdPoints.js +2 -2
- package/Filters/Core.js +5 -1
- package/Filters/General/ClipClosedSurface.js +1 -1
- package/Filters/General/ContourTriangulator/helper.js +1 -1
- package/Filters/General/TubeFilter.js +1 -1
- package/Filters/General/WindowedSincPolyDataFilter.js +1 -1
- package/Filters/Sources/ArcSource.js +1 -1
- package/Filters/Sources/EllipseArcSource.js +1 -1
- package/Filters/Sources/FrustumSource.js +1 -1
- package/Filters/Sources/TorusSource.js +107 -0
- package/Filters/Sources.js +3 -1
- package/Filters/Texture/TextureMapToPlane.js +1 -1
- package/Filters/Texture/TextureMapToSphere.js +1 -1
- package/Imaging/Core/ImageReslice.d.ts +2 -1
- package/Imaging/Core/ImageReslice.js +1 -1
- package/Interaction/Manipulators/MouseCameraUnicamRotateManipulator.js +1 -1
- package/Interaction/Style/InteractorStyleMPRSlice.js +1 -1
- package/Interaction/Style/InteractorStyleManipulator.js +1 -0
- package/Proxy/Representations/GlyphRepresentationProxy.js +1 -0
- package/Rendering/Core/CellPicker.js +1 -1
- package/Rendering/Core/Picker.js +1 -1
- package/Rendering/Core/Prop3D.js +10 -0
- package/Rendering/Core/Renderer.js +13 -11
- package/Rendering/OpenGL/ImageResliceMapper.js +1 -1
- package/Rendering/WebGPU/VolumePass.js +1 -1
- package/Widgets/Core/StateBuilder/originMixin.js +1 -1
- package/Widgets/Core/WidgetManager.js +1 -1
- package/Widgets/Manipulators/PlaneManipulator.js +2 -2
- package/Widgets/Manipulators.js +2 -2
- package/Widgets/Representations/RotateTransformHandleRepresentation.js +46 -0
- package/Widgets/Representations/ScaleTransformHandleRepresentation.js +57 -0
- package/Widgets/Representations/TranslateTransformHandleRepresentation/TransformHandleSource.js +85 -0
- package/Widgets/Representations/TranslateTransformHandleRepresentation.js +57 -0
- package/Widgets/Representations.js +6 -0
- package/Widgets/Widgets3D/AngleWidget.js +2 -2
- package/Widgets/Widgets3D/EllipseWidget.js +2 -2
- package/Widgets/Widgets3D/ImageCroppingWidget.js +3 -3
- package/Widgets/Widgets3D/ImplicitPlaneWidget.js +2 -2
- package/Widgets/Widgets3D/LabelWidget.js +2 -2
- package/Widgets/Widgets3D/LineWidget.js +3 -3
- package/Widgets/Widgets3D/PaintWidget.js +2 -2
- package/Widgets/Widgets3D/PolyLineWidget.js +2 -2
- package/Widgets/Widgets3D/RectangleWidget.js +2 -2
- package/Widgets/Widgets3D/ResliceCursorWidget.js +3 -3
- package/Widgets/Widgets3D/ShapeWidget/behavior.js +1 -1
- package/Widgets/Widgets3D/SphereWidget.js +3 -3
- package/Widgets/Widgets3D/SplineWidget.js +2 -2
- package/Widgets/Widgets3D/TransformControlsWidget/behavior.js +180 -0
- package/Widgets/Widgets3D/TransformControlsWidget/constants.js +15 -0
- package/Widgets/Widgets3D/TransformControlsWidget/state.js +157 -0
- package/Widgets/Widgets3D/TransformControlsWidget.js +147 -0
- package/Widgets/Widgets3D.js +3 -1
- package/index.d.ts +1 -0
- package/package.json +4 -4
|
@@ -4,10 +4,10 @@ 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
|
|
7
|
+
import vtkPlaneManipulator from '../Manipulators/PlaneManipulator.js';
|
|
8
8
|
import vtkLineHandleRepresentation from '../Representations/LineHandleRepresentation.js';
|
|
9
9
|
import vtkSphereHandleRepresentation from '../Representations/SphereHandleRepresentation.js';
|
|
10
|
-
import {
|
|
10
|
+
import { f as distance2BetweenPoints, m as multiplyAccumulate, s as subtract, l as normalize, x as multiplyScalar, k as add } from '../../Common/Core/Math/index.js';
|
|
11
11
|
import widgetBehavior from './ResliceCursorWidget/behavior.js';
|
|
12
12
|
import generateState from './ResliceCursorWidget/state.js';
|
|
13
13
|
import { updateState, transformPlane, boundPlane } from './ResliceCursorWidget/helpers.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:
|
|
431
|
+
manipulator: vtkPlaneManipulator.newInstance(),
|
|
432
432
|
...initialValues
|
|
433
433
|
});
|
|
434
434
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { m as macro } from '../../../macros2.js';
|
|
2
|
-
import {
|
|
2
|
+
import { b as vtkMath } from '../../../Common/Core/Math/index.js';
|
|
3
3
|
import vtkBoundingBox from '../../../Common/DataModel/BoundingBox.js';
|
|
4
4
|
import vtkPlane from '../../../Common/DataModel/Plane.js';
|
|
5
5
|
import { ShapeBehavior, BehaviorCategory, TextPosition } from './Constants.js';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { f as distance2BetweenPoints } from '../../Common/Core/Math/index.js';
|
|
2
2
|
import vtkAbstractWidgetFactory from '../Core/AbstractWidgetFactory.js';
|
|
3
|
-
import
|
|
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 ||
|
|
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
|
|
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 ||
|
|
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 };
|
package/Widgets/Widgets3D.js
CHANGED
|
@@ -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 };
|
package/index.d.ts
CHANGED
|
@@ -58,6 +58,7 @@
|
|
|
58
58
|
/// <reference path="./Common/DataModel/TriangleStrip.d.ts" />
|
|
59
59
|
/// <reference path="./Common/Transform/LandmarkTransform.d.ts" />
|
|
60
60
|
/// <reference path="./Common/Transform/Transform.d.ts" />
|
|
61
|
+
/// <reference path="./Filters/Core/CleanPolyData.d.ts" />
|
|
61
62
|
/// <reference path="./Filters/Core/ThresholdPoints.d.ts" />
|
|
62
63
|
/// <reference path="./Filters/General/AppendPolyData.d.ts" />
|
|
63
64
|
/// <reference path="./Filters/General/ClipClosedSurface.d.ts" />
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kitware/vtk.js",
|
|
3
|
-
"version": "34.
|
|
3
|
+
"version": "34.13.0",
|
|
4
4
|
"description": "Visualization Toolkit for the Web",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"3d",
|
|
@@ -121,11 +121,11 @@
|
|
|
121
121
|
"style-loader": "3.3.1",
|
|
122
122
|
"tape": "5.5.3",
|
|
123
123
|
"typescript": "^5.8.3",
|
|
124
|
-
"webpack": "5.97.1",
|
|
124
|
+
"webpack": "^5.97.1",
|
|
125
125
|
"webpack-bundle-analyzer": "4.5.0",
|
|
126
|
-
"webpack-cli": "5.1.4",
|
|
126
|
+
"webpack-cli": "^5.1.4",
|
|
127
127
|
"webpack-dashboard": "3.3.7",
|
|
128
|
-
"webpack-dev-server": "^
|
|
128
|
+
"webpack-dev-server": "^4.9.0",
|
|
129
129
|
"webpack-merge": "5.8.0",
|
|
130
130
|
"webpack-notifier": "1.15.0",
|
|
131
131
|
"wslink": "1.12.4",
|