@cornerstonejs/tools 5.1.0 → 5.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/stateManagement/segmentation/helpers/labelmapImageMapperSupport.js +1 -1
- package/dist/esm/stateManagement/segmentation/labelmapModel/normalizeLabelmapSegmentationData.js +1 -1
- package/dist/esm/stateManagement/segmentation/labelmapModel/privateLabelmap.js +2 -2
- package/dist/esm/stateManagement/segmentation/utilities/getViewportAssociatedToSegmentation.js +2 -1
- package/dist/esm/synchronizers/callbacks/cameraSyncCallback.js +19 -2
- package/dist/esm/synchronizers/callbacks/imageSliceSyncCallback.js +3 -0
- package/dist/esm/synchronizers/callbacks/voiSyncCallback.js +13 -1
- package/dist/esm/tools/AdvancedMagnifyTool.js +36 -10
- package/dist/esm/tools/CrosshairsTool.js +100 -49
- package/dist/esm/tools/MagnifyTool.d.ts +1 -1
- package/dist/esm/tools/MagnifyTool.js +27 -6
- package/dist/esm/tools/OrientationControllerTool.js +3 -2
- package/dist/esm/tools/OrientationMarkerTool.js +3 -0
- package/dist/esm/tools/OverlayGridTool.js +2 -1
- package/dist/esm/tools/ReferenceCursors.d.ts +1 -1
- package/dist/esm/tools/ReferenceCursors.js +24 -3
- package/dist/esm/tools/ReferenceLinesTool.js +5 -4
- package/dist/esm/tools/ScaleOverlayTool.js +2 -1
- package/dist/esm/tools/TrackballRotateTool.js +6 -4
- package/dist/esm/tools/VolumeCroppingControlTool.js +11 -6
- package/dist/esm/tools/VolumeCroppingTool.js +6 -4
- package/dist/esm/tools/VolumeRotateTool.js +4 -2
- package/dist/esm/tools/WindowLevelRegionTool.js +27 -3
- package/dist/esm/tools/WindowLevelTool.js +4 -8
- package/dist/esm/tools/annotation/DragProbeTool.js +2 -1
- package/dist/esm/tools/annotation/ETDRSGridTool.js +3 -2
- package/dist/esm/tools/annotation/EllipticalROITool.js +2 -1
- package/dist/esm/tools/annotation/LabelTool.js +2 -1
- package/dist/esm/tools/annotation/LivewireContourTool.js +12 -1
- package/dist/esm/tools/annotation/RectangleROITool.js +2 -1
- package/dist/esm/tools/annotation/UltrasoundPleuraBLineTool/UltrasoundPleuraBLineTool.js +2 -1
- package/dist/esm/tools/annotation/WholeBodySegmentTool.js +3 -2
- package/dist/esm/tools/annotation/planarFreehandROITool/drawLoop.js +1 -1
- package/dist/esm/tools/base/AnnotationTool.js +6 -0
- package/dist/esm/tools/base/GrowCutBaseTool.js +3 -2
- package/dist/esm/tools/displayTools/Contour/contourDisplay.js +2 -1
- package/dist/esm/tools/displayTools/Contour/contourHandler/handleContourSegmentation.js +3 -2
- package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/legacyVolumePlan.js +21 -9
- package/dist/esm/tools/displayTools/Labelmap/syncStackLabelmapActors.js +36 -0
- package/dist/esm/tools/segmentation/CircleScissorsTool.js +2 -1
- package/dist/esm/tools/segmentation/RectangleScissorsTool.js +2 -1
- package/dist/esm/tools/segmentation/SegmentBidirectionalTool.js +2 -1
- package/dist/esm/tools/segmentation/strategies/fillRectangle.js +2 -1
- package/dist/esm/types/LabelmapTypes.d.ts +1 -1
- package/dist/esm/utilities/cine/playClip.js +28 -0
- package/dist/esm/utilities/genericViewportToolHelpers.d.ts +11 -0
- package/dist/esm/utilities/genericViewportToolHelpers.js +37 -0
- package/dist/esm/utilities/getVOIMultipliers.js +1 -3
- package/dist/esm/utilities/getViewportICamera.js +3 -2
- package/dist/esm/utilities/index.d.ts +2 -1
- package/dist/esm/utilities/index.js +2 -1
- package/dist/esm/utilities/math/polyline/getSubPixelSpacingAndXYDirections.js +7 -3
- package/dist/esm/utilities/planar/filterAnnotationsForDisplay.js +7 -2
- package/dist/esm/utilities/segmentation/getSegmentIndexAtWorldPoint.js +2 -1
- package/dist/esm/utilities/segmentation/growCut/runGrowCutForSphere.js +3 -2
- package/dist/esm/utilities/setViewportCamera.d.ts +3 -0
- package/dist/esm/utilities/setViewportCamera.js +58 -0
- package/dist/esm/utilities/stackPrefetch/stackPrefetchUtils.js +6 -2
- package/dist/esm/utilities/viewport/isViewportPreScaled.js +2 -13
- package/dist/esm/utilities/voi/colorbar/ViewportColorbar.js +17 -5
- package/dist/esm/utilities/voi/windowlevel/extractWindowLevelRegionToolData.d.ts +1 -1
- package/dist/esm/utilities/voi/windowlevel/extractWindowLevelRegionToolData.js +28 -1
- package/dist/esm/version.d.ts +1 -1
- package/dist/esm/version.js +1 -1
- package/package.json +4 -4
|
@@ -4,6 +4,7 @@ import { drawPolyline as drawPolylineSvg } from '../../drawingSvg';
|
|
|
4
4
|
import { resetElementCursor, hideElementCursor, } from '../../cursors/elementCursor';
|
|
5
5
|
import { Events } from '../../enums';
|
|
6
6
|
import triggerAnnotationRenderForViewportUIDs from '../../utilities/triggerAnnotationRenderForViewportIds';
|
|
7
|
+
import getViewportICamera from '../../utilities/getViewportICamera';
|
|
7
8
|
import { growCut } from '../../utilities/segmentation';
|
|
8
9
|
import GrowCutBaseTool from '../base/GrowCutBaseTool';
|
|
9
10
|
const NEGATIVE_PIXEL_RANGE = [-Infinity, -995];
|
|
@@ -167,7 +168,7 @@ class WholeBodySegmentTool extends GrowCutBaseTool {
|
|
|
167
168
|
return [ijkLineP1, ijkLineP2];
|
|
168
169
|
}
|
|
169
170
|
_getCuboidIJKEdgePointsFromProjectedWorldPoint(viewport, worldEdgePoint) {
|
|
170
|
-
const { viewPlaneNormal } = viewport
|
|
171
|
+
const { viewPlaneNormal } = getViewportICamera(viewport);
|
|
171
172
|
return this._projectWorldPointAcrossSlices(viewport, worldEdgePoint, viewPlaneNormal);
|
|
172
173
|
}
|
|
173
174
|
_getWorldCuboidCornerPoints(viewport, worldSquarePoints) {
|
|
@@ -202,7 +203,7 @@ class WholeBodySegmentTool extends GrowCutBaseTool {
|
|
|
202
203
|
const volume = this._getViewportVolume(viewport);
|
|
203
204
|
const { dimensions } = volume;
|
|
204
205
|
const ijkPoint = transformWorldToIndex(volume.imageData, worldPoint);
|
|
205
|
-
const { viewUp, viewPlaneNormal } = viewport
|
|
206
|
+
const { viewUp, viewPlaneNormal } = getViewportICamera(viewport);
|
|
206
207
|
const vecRow = vec3.cross(vec3.create(), viewUp, viewPlaneNormal);
|
|
207
208
|
const axis = vecRow.findIndex((n) => csUtils.isEqual(Math.abs(n), 1));
|
|
208
209
|
const ijkLineP1 = [...ijkPoint];
|
|
@@ -13,7 +13,6 @@ import { removeAnnotation } from '../../../stateManagement/annotation/annotation
|
|
|
13
13
|
import { ContourWindingDirection } from '../../../types/ContourAnnotation';
|
|
14
14
|
const { addCanvasPointsToArray, pointsAreWithinCloseContourProximity, getFirstLineSegmentIntersectionIndexes, getSubPixelSpacingAndXYDirections, } = polyline;
|
|
15
15
|
function activateDraw(evt, annotation, viewportIdsToRender) {
|
|
16
|
-
this.isDrawing = true;
|
|
17
16
|
const eventDetail = evt.detail;
|
|
18
17
|
const { currentPoints, element } = eventDetail;
|
|
19
18
|
const canvasPos = currentPoints.canvas;
|
|
@@ -25,6 +24,7 @@ function activateDraw(evt, annotation, viewportIdsToRender) {
|
|
|
25
24
|
if (!spacing || !xDir || !yDir) {
|
|
26
25
|
return;
|
|
27
26
|
}
|
|
27
|
+
this.isDrawing = true;
|
|
28
28
|
this.drawData = {
|
|
29
29
|
canvasPoints: [canvasPos],
|
|
30
30
|
polylineIndex: 0,
|
|
@@ -314,6 +314,12 @@ class AnnotationTool extends AnnotationDisplayTool {
|
|
|
314
314
|
else if (viewport instanceof BaseVolumeViewport) {
|
|
315
315
|
referencedImageId = instance.getReferencedImageId(viewport, points[0], viewPlaneNormal, viewUp);
|
|
316
316
|
}
|
|
317
|
+
else if (csUtils.isGenericViewport(viewport)) {
|
|
318
|
+
const genericViewport = viewport;
|
|
319
|
+
referencedImageId = genericViewport.getViewReference?.({
|
|
320
|
+
points: [points[0]],
|
|
321
|
+
})?.referencedImageId;
|
|
322
|
+
}
|
|
317
323
|
else {
|
|
318
324
|
throw new Error('Unsupported viewport type');
|
|
319
325
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { getEnabledElement, utilities as csUtils, cache, getRenderingEngine, volumeLoader, imageLoader, ImageVolume, } from '@cornerstonejs/core';
|
|
2
2
|
import { BaseTool } from '../base';
|
|
3
|
+
import getViewportICamera from '../../utilities/getViewportICamera';
|
|
3
4
|
import { SegmentationRepresentations } from '../../enums';
|
|
4
5
|
import { segmentIndex as segmentIndexController, state as segmentationState, activeSegmentation, } from '../../stateManagement/segmentation';
|
|
5
6
|
import { triggerSegmentationDataModified } from '../../stateManagement/segmentation/triggerSegmentationEvents';
|
|
@@ -28,7 +29,7 @@ class GrowCutBaseTool extends BaseTool {
|
|
|
28
29
|
const { world: worldPoint } = currentPoints;
|
|
29
30
|
const enabledElement = getEnabledElement(element);
|
|
30
31
|
const { viewport, renderingEngine } = enabledElement;
|
|
31
|
-
const { viewUp } = viewport
|
|
32
|
+
const { viewUp } = getViewportICamera(viewport);
|
|
32
33
|
const { segmentationId, segmentIndex, labelmapVolumeId, referencedVolumeId, } = await this.getLabelmapSegmentationData(viewport);
|
|
33
34
|
if (!this._isOrthogonalView(viewport, referencedVolumeId)) {
|
|
34
35
|
throw new Error('Oblique view is not supported yet');
|
|
@@ -223,7 +224,7 @@ class GrowCutBaseTool extends BaseTool {
|
|
|
223
224
|
_isOrthogonalView(viewport, referencedVolumeId) {
|
|
224
225
|
const volume = cache.getVolume(referencedVolumeId);
|
|
225
226
|
const volumeImageData = volume.imageData;
|
|
226
|
-
const camera = viewport
|
|
227
|
+
const camera = getViewportICamera(viewport);
|
|
227
228
|
const { ijkVecColDir, ijkVecSliceDir } = csUtils.getVolumeDirectionVectors(volumeImageData, camera);
|
|
228
229
|
return [ijkVecColDir, ijkVecSliceDir].every((vec) => csUtils.isEqual(Math.abs(vec[0]), 1) ||
|
|
229
230
|
csUtils.isEqual(Math.abs(vec[1]), 1) ||
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { cache, getEnabledElementByViewportId, Enums, utilities, } from '@cornerstonejs/core';
|
|
2
2
|
import Representations from '../../../enums/SegmentationRepresentations';
|
|
3
3
|
import { handleContourSegmentation } from './contourHandler/handleContourSegmentation';
|
|
4
|
+
import getViewportICamera from '../../../utilities/getViewportICamera';
|
|
4
5
|
import { getSegmentation } from '../../../stateManagement/segmentation/getSegmentation';
|
|
5
6
|
import removeContourFromElement from './removeContourFromElement';
|
|
6
7
|
import { getPolySeg } from '../../../config';
|
|
@@ -51,7 +52,7 @@ async function render(viewport, contourRepresentation) {
|
|
|
51
52
|
return;
|
|
52
53
|
}
|
|
53
54
|
let hasContourDataButNotMatchingViewport = false;
|
|
54
|
-
const viewportNormal = viewport
|
|
55
|
+
const viewportNormal = getViewportICamera(viewport).viewPlaneNormal;
|
|
55
56
|
if (contourData.annotationUIDsMap) {
|
|
56
57
|
hasContourDataButNotMatchingViewport = !_checkContourNormalsMatchViewport(contourData.annotationUIDsMap, viewportNormal);
|
|
57
58
|
}
|
|
@@ -2,6 +2,7 @@ import { addAnnotation } from '../../../../stateManagement/annotation/annotation
|
|
|
2
2
|
import { cache, utilities } from '@cornerstonejs/core';
|
|
3
3
|
import { getClosestImageIdForStackViewport } from '../../../../utilities/annotationHydration';
|
|
4
4
|
import { addContourSegmentationAnnotation } from '../../../../utilities/contourSegmentation';
|
|
5
|
+
import getViewportICamera from '../../../../utilities/getViewportICamera';
|
|
5
6
|
import { validateGeometry } from './utils';
|
|
6
7
|
import { SegmentationRepresentations } from '../../../../enums';
|
|
7
8
|
import { segmentationStyle } from '../../../../stateManagement/segmentation/SegmentationStyle';
|
|
@@ -31,7 +32,7 @@ function addContourSetsToElement(viewport, geometryIds, contourRepresentation) {
|
|
|
31
32
|
segmentIndex,
|
|
32
33
|
});
|
|
33
34
|
const contourSet = geometry.data;
|
|
34
|
-
const viewPlaneNormal = viewport
|
|
35
|
+
const viewPlaneNormal = getViewportICamera(viewport).viewPlaneNormal;
|
|
35
36
|
contourSet.contours.forEach((contour) => {
|
|
36
37
|
const { points, color, id } = contour;
|
|
37
38
|
const referencedImageId = getClosestImageIdForStackViewport(viewport, points[0], viewPlaneNormal);
|
|
@@ -60,7 +61,7 @@ function addContourSetsToElement(viewport, geometryIds, contourRepresentation) {
|
|
|
60
61
|
referencedImageId,
|
|
61
62
|
toolName: 'PlanarFreehandContourSegmentationTool',
|
|
62
63
|
FrameOfReferenceUID: viewport.getFrameOfReferenceUID(),
|
|
63
|
-
viewPlaneNormal
|
|
64
|
+
viewPlaneNormal,
|
|
64
65
|
},
|
|
65
66
|
};
|
|
66
67
|
const annotationGroupSelector = viewport.element;
|
|
@@ -47,7 +47,7 @@ async function mountLegacyVolumeLabelmap({ config, labelMapData, segmentation, s
|
|
|
47
47
|
}
|
|
48
48
|
labelmapLayers.push({
|
|
49
49
|
labelmapId: volumeId,
|
|
50
|
-
|
|
50
|
+
storageKind: 'volume',
|
|
51
51
|
volumeId,
|
|
52
52
|
imageIds: cache.getVolume(volumeId)?.imageIds,
|
|
53
53
|
});
|
|
@@ -56,16 +56,28 @@ async function mountLegacyVolumeLabelmap({ config, labelMapData, segmentation, s
|
|
|
56
56
|
let useIndependentComponents = blendMode === Enums.BlendModes.LABELMAP_EDGE_PROJECTION_BLEND;
|
|
57
57
|
if (useIndependentComponents) {
|
|
58
58
|
const referenceVolumeId = volumeCompatibleViewport.getVolumeId?.();
|
|
59
|
-
const
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
59
|
+
const segLabelmapVolumeId = labelmapLayers[0]?.volumeId;
|
|
60
|
+
const baseVolume = referenceVolumeId
|
|
61
|
+
? cache.getVolume(referenceVolumeId)
|
|
62
|
+
: undefined;
|
|
63
|
+
const segVolume = segLabelmapVolumeId
|
|
64
|
+
? cache.getVolume(segLabelmapVolumeId)
|
|
65
|
+
: undefined;
|
|
66
|
+
if (!baseVolume || !segVolume) {
|
|
66
67
|
useIndependentComponents = false;
|
|
67
68
|
blendMode = Enums.BlendModes.MAXIMUM_INTENSITY_BLEND;
|
|
68
|
-
console.debug('
|
|
69
|
+
console.debug('Independent components unavailable (missing reference or segmentation volume) - falling back to regular volume addition');
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
const segDims = segVolume.dimensions;
|
|
73
|
+
const refDims = baseVolume.dimensions;
|
|
74
|
+
if (segDims[0] !== refDims[0] ||
|
|
75
|
+
segDims[1] !== refDims[1] ||
|
|
76
|
+
segDims[2] !== refDims[2]) {
|
|
77
|
+
useIndependentComponents = false;
|
|
78
|
+
blendMode = Enums.BlendModes.MAXIMUM_INTENSITY_BLEND;
|
|
79
|
+
console.debug('Dimensions mismatch - falling back to regular volume addition');
|
|
80
|
+
}
|
|
69
81
|
}
|
|
70
82
|
}
|
|
71
83
|
const volumeInputs = labelmapLayers.map((layer) => ({
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import vtkDataArray from '@kitware/vtk.js/Common/Core/DataArray';
|
|
2
2
|
import vtkImageData from '@kitware/vtk.js/Common/DataModel/ImageData';
|
|
3
|
+
import vtkPiecewiseFunction from '@kitware/vtk.js/Common/DataModel/PiecewiseFunction';
|
|
3
4
|
import { ActorRenderMode, cache, utilities, } from '@cornerstonejs/core';
|
|
4
5
|
import { triggerSegmentationRender } from '../../../stateManagement/segmentation/SegmentationRenderingEngine';
|
|
5
6
|
import { updateLabelmapSegmentationImageReferences } from '../../../stateManagement/segmentation/updateLabelmapSegmentationImageReferences';
|
|
@@ -22,6 +23,7 @@ export function syncStackLabelmapActors(viewport, segmentationId) {
|
|
|
22
23
|
const derivedImageIdSet = new Set(derivedImageIds);
|
|
23
24
|
const labelmapActorEntries = getLabelmapActorEntries(viewport.id, segmentationId) ?? [];
|
|
24
25
|
const staleActorEntries = labelmapActorEntries.filter((actorEntry) => !derivedImageIdSet.has(actorEntry.referencedId));
|
|
26
|
+
const inheritedLabelmapStyle = captureLabelmapActorStyle(staleActorEntries[0]?.actor);
|
|
25
27
|
let shouldTriggerSegmentationRender = false;
|
|
26
28
|
let shouldRenderViewport = staleActorEntries.length > 0;
|
|
27
29
|
if (staleActorEntries.length) {
|
|
@@ -104,6 +106,7 @@ export function syncStackLabelmapActors(viewport, segmentationId) {
|
|
|
104
106
|
representationUID,
|
|
105
107
|
callback: ({ imageActor }) => {
|
|
106
108
|
imageActor.getMapper().setInputData(imageData);
|
|
109
|
+
applyInheritedLabelmapStyle(imageActor, inheritedLabelmapStyle);
|
|
107
110
|
},
|
|
108
111
|
},
|
|
109
112
|
]);
|
|
@@ -133,3 +136,36 @@ export function syncStackLabelmapActors(viewport, segmentationId) {
|
|
|
133
136
|
viewport.render();
|
|
134
137
|
}
|
|
135
138
|
}
|
|
139
|
+
function captureLabelmapActorStyle(actor) {
|
|
140
|
+
const prop = actor?.getProperty?.();
|
|
141
|
+
if (!prop) {
|
|
142
|
+
return undefined;
|
|
143
|
+
}
|
|
144
|
+
return {
|
|
145
|
+
cfun: prop.getRGBTransferFunction?.(0),
|
|
146
|
+
ofun: prop.getScalarOpacity?.(0),
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
function applyInheritedLabelmapStyle(actor, style) {
|
|
150
|
+
const prop = actor?.getProperty?.();
|
|
151
|
+
if (!prop) {
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
if (style?.cfun && prop.setRGBTransferFunction) {
|
|
155
|
+
prop.setRGBTransferFunction(0, style.cfun);
|
|
156
|
+
}
|
|
157
|
+
if (style?.ofun && prop.setScalarOpacity) {
|
|
158
|
+
prop.setScalarOpacity(0, style.ofun);
|
|
159
|
+
}
|
|
160
|
+
else if (prop.setScalarOpacity) {
|
|
161
|
+
const ofun = vtkPiecewiseFunction.newInstance();
|
|
162
|
+
ofun.addPoint(0, 0);
|
|
163
|
+
ofun.addPoint(1, 1);
|
|
164
|
+
ofun.setClamping(false);
|
|
165
|
+
prop.setScalarOpacity(0, ofun);
|
|
166
|
+
}
|
|
167
|
+
prop.setUseLookupTableScalarRange?.(true);
|
|
168
|
+
prop.setInterpolationTypeToNearest?.();
|
|
169
|
+
actor?.setForceTranslucent?.(true);
|
|
170
|
+
actor?.setForceOpaque?.(false);
|
|
171
|
+
}
|
|
@@ -6,6 +6,7 @@ import { Events } from '../../enums';
|
|
|
6
6
|
import { drawCircle as drawCircleSvg } from '../../drawingSvg';
|
|
7
7
|
import { resetElementCursor, hideElementCursor, } from '../../cursors/elementCursor';
|
|
8
8
|
import triggerAnnotationRenderForViewportIds from '../../utilities/triggerAnnotationRenderForViewportIds';
|
|
9
|
+
import getViewportICamera from '../../utilities/getViewportICamera';
|
|
9
10
|
import { segmentLocking, activeSegmentation, segmentIndex as segmentIndexController, config as segmentationConfig, } from '../../stateManagement/segmentation';
|
|
10
11
|
import { getCurrentLabelmapImageIdForViewport, getSegmentation, } from '../../stateManagement/segmentation/segmentationState';
|
|
11
12
|
import getViewportLabelmapRenderMode from '../../stateManagement/segmentation/helpers/getViewportLabelmapRenderMode';
|
|
@@ -37,7 +38,7 @@ class CircleScissorsTool extends LabelmapBaseTool {
|
|
|
37
38
|
const enabledElement = getEnabledElement(element);
|
|
38
39
|
const { viewport } = enabledElement;
|
|
39
40
|
this.isDrawing = true;
|
|
40
|
-
const camera = viewport
|
|
41
|
+
const camera = getViewportICamera(viewport);
|
|
41
42
|
const { viewPlaneNormal, viewUp } = camera;
|
|
42
43
|
const activeLabelmapSegmentation = activeSegmentation.getActiveSegmentation(viewport.id);
|
|
43
44
|
if (!activeLabelmapSegmentation) {
|
|
@@ -7,6 +7,7 @@ import { Events, SegmentationRepresentations } from '../../enums';
|
|
|
7
7
|
import { drawRect as drawRectSvg } from '../../drawingSvg';
|
|
8
8
|
import { resetElementCursor, hideElementCursor, } from '../../cursors/elementCursor';
|
|
9
9
|
import triggerAnnotationRenderForViewportIds from '../../utilities/triggerAnnotationRenderForViewportIds';
|
|
10
|
+
import getViewportICamera from '../../utilities/getViewportICamera';
|
|
10
11
|
import { config as segmentationConfig, segmentLocking, segmentIndex as segmentIndexController, activeSegmentation, } from '../../stateManagement/segmentation';
|
|
11
12
|
import { getCurrentLabelmapImageIdForViewport, getSegmentation, } from '../../stateManagement/segmentation/segmentationState';
|
|
12
13
|
import getViewportLabelmapRenderMode from '../../stateManagement/segmentation/helpers/getViewportLabelmapRenderMode';
|
|
@@ -35,7 +36,7 @@ class RectangleScissorsTool extends LabelmapBaseTool {
|
|
|
35
36
|
const enabledElement = getEnabledElement(element);
|
|
36
37
|
const { viewport } = enabledElement;
|
|
37
38
|
this.isDrawing = true;
|
|
38
|
-
const camera = viewport
|
|
39
|
+
const camera = getViewportICamera(viewport);
|
|
39
40
|
const { viewPlaneNormal, viewUp } = camera;
|
|
40
41
|
const activeLabelmapSegmentation = activeSegmentation.getActiveSegmentation(viewport.id);
|
|
41
42
|
if (!activeLabelmapSegmentation) {
|
|
@@ -7,6 +7,7 @@ import { drawLine as drawLineSvg, drawHandles as drawHandlesSvg, } from '../../d
|
|
|
7
7
|
import { getViewportIdsWithToolToRender } from '../../utilities/viewportFilters';
|
|
8
8
|
import { hideElementCursor } from '../../cursors/elementCursor';
|
|
9
9
|
import triggerAnnotationRenderForViewportIds from '../../utilities/triggerAnnotationRenderForViewportIds';
|
|
10
|
+
import getViewportICamera from '../../utilities/getViewportICamera';
|
|
10
11
|
import BidirectionalTool from '../annotation/BidirectionalTool';
|
|
11
12
|
import { getSegmentIndexColor } from '../../stateManagement/segmentation/config/segmentationColor';
|
|
12
13
|
class SegmentBidirectionalTool extends BidirectionalTool {
|
|
@@ -118,7 +119,7 @@ class SegmentBidirectionalTool extends BidirectionalTool {
|
|
|
118
119
|
const enabledElement = getEnabledElement(element);
|
|
119
120
|
const { viewport } = enabledElement;
|
|
120
121
|
this.isDrawing = true;
|
|
121
|
-
const camera = viewport
|
|
122
|
+
const camera = getViewportICamera(viewport);
|
|
122
123
|
const { viewPlaneNormal, viewUp } = camera;
|
|
123
124
|
const referencedImageId = this.getReferencedImageId(viewport, worldPos, viewPlaneNormal, viewUp);
|
|
124
125
|
const FrameOfReferenceUID = viewport.getFrameOfReferenceUID();
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { vec3 } from 'gl-matrix';
|
|
2
2
|
import { utilities as csUtils, StackViewport } from '@cornerstonejs/core';
|
|
3
3
|
import { getBoundingBoxAroundShapeIJK } from '../../../utilities/boundingBox';
|
|
4
|
+
import getViewportICamera from '../../../utilities/getViewportICamera';
|
|
4
5
|
import BrushStrategy from './BrushStrategy';
|
|
5
6
|
import { StrategyCallbacks } from '../../../enums';
|
|
6
7
|
import compositions from './compositions';
|
|
@@ -47,7 +48,7 @@ function createPointInRectangle(viewport, points, segmentationImageData) {
|
|
|
47
48
|
vec3.normalize(normal, normal);
|
|
48
49
|
const direction = segmentationImageData.getDirection();
|
|
49
50
|
const spacing = segmentationImageData.getSpacing();
|
|
50
|
-
const { viewPlaneNormal } = viewport
|
|
51
|
+
const { viewPlaneNormal } = getViewportICamera(viewport);
|
|
51
52
|
const EPS = csUtils.getSpacingInNormalDirection({
|
|
52
53
|
direction,
|
|
53
54
|
spacing,
|
|
@@ -17,7 +17,7 @@ export type LabelmapStyle = BaseLabelmapStyle & InactiveLabelmapStyle;
|
|
|
17
17
|
export type LabelmapLayerType = 'volume' | 'stack';
|
|
18
18
|
export type LabelmapLayer = {
|
|
19
19
|
labelmapId: string;
|
|
20
|
-
|
|
20
|
+
storageKind: LabelmapLayerType;
|
|
21
21
|
volumeId?: string;
|
|
22
22
|
geometryVolumeId?: string;
|
|
23
23
|
referencedVolumeId?: string;
|
|
@@ -339,6 +339,31 @@ function _createDynamicVolumeViewportCinePlayContext(volume) {
|
|
|
339
339
|
},
|
|
340
340
|
};
|
|
341
341
|
}
|
|
342
|
+
function _createGenericViewportCinePlayContext(viewport, waitForRendered) {
|
|
343
|
+
return {
|
|
344
|
+
get numScrollSteps() {
|
|
345
|
+
return viewport.getNumberOfSlices();
|
|
346
|
+
},
|
|
347
|
+
get currentStepIndex() {
|
|
348
|
+
return viewport.getSliceIndex();
|
|
349
|
+
},
|
|
350
|
+
get frameTimeVectorEnabled() {
|
|
351
|
+
return viewport.getCurrentMode() === 'stack';
|
|
352
|
+
},
|
|
353
|
+
waitForRenderedCount: 0,
|
|
354
|
+
scroll(delta) {
|
|
355
|
+
const status = viewport.viewportStatus;
|
|
356
|
+
if (this.waitForRenderedCount <= waitForRendered &&
|
|
357
|
+
status !== undefined &&
|
|
358
|
+
status !== ViewportStatus.RENDERED) {
|
|
359
|
+
this.waitForRenderedCount++;
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
362
|
+
this.waitForRenderedCount = 0;
|
|
363
|
+
csUtils.scroll(viewport, { delta, debounceLoading: debounced });
|
|
364
|
+
},
|
|
365
|
+
};
|
|
366
|
+
}
|
|
342
367
|
function _createCinePlayContext(viewport, playClipOptions) {
|
|
343
368
|
if (viewport instanceof StackViewport) {
|
|
344
369
|
return _createStackViewportCinePlayContext(viewport, playClipOptions.waitForRendered ?? 30);
|
|
@@ -353,6 +378,9 @@ function _createCinePlayContext(viewport, playClipOptions) {
|
|
|
353
378
|
if (viewport instanceof VideoViewport) {
|
|
354
379
|
return _createVideoViewportCinePlayContext(viewport, playClipOptions.waitForRendered ?? 30);
|
|
355
380
|
}
|
|
381
|
+
if (csUtils.isGenericViewport(viewport)) {
|
|
382
|
+
return _createGenericViewportCinePlayContext(viewport, playClipOptions.waitForRendered ?? 30);
|
|
383
|
+
}
|
|
356
384
|
throw new Error('Unknown viewport type');
|
|
357
385
|
}
|
|
358
386
|
export { playClip, stopClip };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type Types } from '@cornerstonejs/core';
|
|
2
|
+
export declare function getSlabThicknessOrDefault(viewport: Types.IViewport): number;
|
|
3
|
+
export declare function jumpToFocalPoint(viewport: Types.IViewport, cameraFocalPoint: Types.Point3): void;
|
|
4
|
+
export interface NativeSourceProperties {
|
|
5
|
+
properties: Record<string, unknown>;
|
|
6
|
+
rotation?: number;
|
|
7
|
+
flipHorizontal?: boolean;
|
|
8
|
+
flipVertical?: boolean;
|
|
9
|
+
currentImageId?: string;
|
|
10
|
+
}
|
|
11
|
+
export declare function getNativeSourceProperties(viewport: Types.IViewport): NativeSourceProperties;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { CONSTANTS, utilities as csUtils, } from '@cornerstonejs/core';
|
|
2
|
+
import { getViewportPresentation } from './viewportPresentation';
|
|
3
|
+
const { RENDERING_DEFAULTS } = CONSTANTS;
|
|
4
|
+
export function getSlabThicknessOrDefault(viewport) {
|
|
5
|
+
if (csUtils.isGenericViewport(viewport)) {
|
|
6
|
+
return RENDERING_DEFAULTS.MINIMUM_SLAB_THICKNESS;
|
|
7
|
+
}
|
|
8
|
+
return viewport.getSlabThickness();
|
|
9
|
+
}
|
|
10
|
+
export function jumpToFocalPoint(viewport, cameraFocalPoint) {
|
|
11
|
+
if (csUtils.isGenericViewport(viewport)) {
|
|
12
|
+
viewport.setViewReference({ cameraFocalPoint });
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
export function getNativeSourceProperties(viewport) {
|
|
16
|
+
if (!csUtils.viewportSupportsDisplaySetPresentation(viewport)) {
|
|
17
|
+
return { properties: {} };
|
|
18
|
+
}
|
|
19
|
+
const sourceDataId = viewport.getSourceDataId();
|
|
20
|
+
const properties = {
|
|
21
|
+
...((sourceDataId
|
|
22
|
+
? viewport.getDisplaySetPresentation(sourceDataId)
|
|
23
|
+
: {}) ?? {}),
|
|
24
|
+
};
|
|
25
|
+
const voiLUTFunction = properties.VOILUTFunction ?? properties.voiLUTFunction;
|
|
26
|
+
if (voiLUTFunction !== undefined) {
|
|
27
|
+
properties.VOILUTFunction = voiLUTFunction;
|
|
28
|
+
}
|
|
29
|
+
const presentation = (getViewportPresentation(viewport) ?? {});
|
|
30
|
+
return {
|
|
31
|
+
properties,
|
|
32
|
+
rotation: presentation.rotation,
|
|
33
|
+
flipHorizontal: presentation.flipHorizontal,
|
|
34
|
+
flipVertical: presentation.flipVertical,
|
|
35
|
+
currentImageId: viewport.getCurrentImageId(),
|
|
36
|
+
};
|
|
37
|
+
}
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import { utilities as csUtils } from '@cornerstonejs/core';
|
|
2
|
-
import { isViewportPreScaled } from './viewport';
|
|
3
2
|
const DEFAULT_MULTIPLIER = 4;
|
|
4
3
|
function getVOIMultipliers(viewport, volumeId, options) {
|
|
5
|
-
const modality = csUtils.
|
|
4
|
+
const { modality, isPreScaled } = csUtils.getScalingDescriptor(viewport, volumeId) ?? {};
|
|
6
5
|
if (modality === 'PT') {
|
|
7
6
|
const { clientWidth, clientHeight } = viewport.element;
|
|
8
7
|
const ptMultiplier = 5 / Math.max(clientWidth, clientHeight);
|
|
9
|
-
const isPreScaled = isViewportPreScaled(viewport, volumeId);
|
|
10
8
|
const { fixedPTWindowWidth = true } = options ?? {};
|
|
11
9
|
const xMultiplier = fixedPTWindowWidth ? 0 : ptMultiplier;
|
|
12
10
|
return isPreScaled
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { utilities } from '@cornerstonejs/core';
|
|
2
2
|
export default function getViewportICamera(viewport, viewReference = viewport.getViewReference()) {
|
|
3
|
-
const
|
|
4
|
-
|
|
3
|
+
const camera = ((utilities.isGenericViewport(viewport)
|
|
4
|
+
? viewport.getResolvedView()?.toICamera()
|
|
5
|
+
: undefined) ||
|
|
5
6
|
viewport.getCamera?.() ||
|
|
6
7
|
{});
|
|
7
8
|
const focalPoint = utilities.clonePoint3(viewReference?.cameraFocalPoint || camera.focalPoint);
|
|
@@ -43,4 +43,5 @@ import { moveAnnotationToViewPlane } from './moveAnnotationToViewPlane';
|
|
|
43
43
|
import { safeStructuredClone } from './safeStructuredClone';
|
|
44
44
|
import getOrCreateImageVolume from './segmentation/getOrCreateImageVolume';
|
|
45
45
|
import * as usFanExtraction from '../tools/annotation/UltrasoundPleuraBLineTool/utils/fanExtraction';
|
|
46
|
-
|
|
46
|
+
import { jumpToFocalPoint } from './genericViewportToolHelpers';
|
|
47
|
+
export { math, planar, viewportFilters, drawing, debounce, dynamicVolume, throttle, orientation, isObject, touch, triggerEvent, calibrateImageSpacing, getCalibratedLengthUnitsAndScale, getCalibratedProbeUnitsAndValue, getCalibratedAspect, getPixelValueUnits, getPixelValueUnitsImageId, segmentation, contours, triggerAnnotationRenderForViewportIds, triggerAnnotationRenderForToolGroupIds, triggerAnnotationRender, getSphereBoundsInfo, getAnnotationNearPoint, getViewportForAnnotation, getAnnotationNearPointOnEnabledElement, viewport, cine, boundingBox, draw3D, rectangleROITool, planarFreehandROITool, stackPrefetch, stackContextPrefetch, roundNumber, pointToString, polyDataUtils, voi, AnnotationMultiSlice, contourSegmentation, annotationHydration, getClosestImageIdForStackViewport, pointInSurroundingSphereCallback, normalizeViewportPlane, IslandRemoval, geometricSurfaceUtils, usFanExtraction, setAnnotationLabel, moveAnnotationToViewPlane, safeStructuredClone, getOrCreateImageVolume, jumpToFocalPoint, };
|
|
@@ -43,4 +43,5 @@ import { moveAnnotationToViewPlane } from './moveAnnotationToViewPlane';
|
|
|
43
43
|
import { safeStructuredClone } from './safeStructuredClone';
|
|
44
44
|
import getOrCreateImageVolume from './segmentation/getOrCreateImageVolume';
|
|
45
45
|
import * as usFanExtraction from '../tools/annotation/UltrasoundPleuraBLineTool/utils/fanExtraction';
|
|
46
|
-
|
|
46
|
+
import { jumpToFocalPoint } from './genericViewportToolHelpers';
|
|
47
|
+
export { math, planar, viewportFilters, drawing, debounce, dynamicVolume, throttle, orientation, isObject, touch, triggerEvent, calibrateImageSpacing, getCalibratedLengthUnitsAndScale, getCalibratedProbeUnitsAndValue, getCalibratedAspect, getPixelValueUnits, getPixelValueUnitsImageId, segmentation, contours, triggerAnnotationRenderForViewportIds, triggerAnnotationRenderForToolGroupIds, triggerAnnotationRender, getSphereBoundsInfo, getAnnotationNearPoint, getViewportForAnnotation, getAnnotationNearPointOnEnabledElement, viewport, cine, boundingBox, draw3D, rectangleROITool, planarFreehandROITool, stackPrefetch, stackContextPrefetch, roundNumber, pointToString, polyDataUtils, voi, AnnotationMultiSlice, contourSegmentation, annotationHydration, getClosestImageIdForStackViewport, pointInSurroundingSphereCallback, normalizeViewportPlane, IslandRemoval, geometricSurfaceUtils, usFanExtraction, setAnnotationLabel, moveAnnotationToViewPlane, safeStructuredClone, getOrCreateImageVolume, jumpToFocalPoint, };
|
|
@@ -1,11 +1,15 @@
|
|
|
1
|
-
import { StackViewport } from '@cornerstonejs/core';
|
|
1
|
+
import { StackViewport, utilities as csUtils } from '@cornerstonejs/core';
|
|
2
2
|
import { vec3 } from 'gl-matrix';
|
|
3
|
+
import getViewportICamera from '../../getViewportICamera';
|
|
3
4
|
const EPSILON = 1e-3;
|
|
4
5
|
const getSubPixelSpacingAndXYDirections = (viewport, subPixelResolution) => {
|
|
5
6
|
let spacing;
|
|
6
7
|
let xDir;
|
|
7
8
|
let yDir;
|
|
8
|
-
|
|
9
|
+
const isGeneric = csUtils.isGenericViewport(viewport);
|
|
10
|
+
const isImageSlice = viewport instanceof StackViewport ||
|
|
11
|
+
(isGeneric && csUtils.getViewportContentMode(viewport) === 'stack');
|
|
12
|
+
if (isImageSlice) {
|
|
9
13
|
const imageData = viewport.getImageData();
|
|
10
14
|
if (!imageData) {
|
|
11
15
|
return;
|
|
@@ -17,7 +21,7 @@ const getSubPixelSpacingAndXYDirections = (viewport, subPixelResolution) => {
|
|
|
17
21
|
else {
|
|
18
22
|
const imageData = viewport.getImageData();
|
|
19
23
|
const { direction, spacing: volumeSpacing } = imageData;
|
|
20
|
-
const { viewPlaneNormal, viewUp } = viewport.getCamera();
|
|
24
|
+
const { viewPlaneNormal, viewUp } = (isGeneric ? getViewportICamera(viewport) : viewport.getCamera());
|
|
21
25
|
const iVector = direction.slice(0, 3);
|
|
22
26
|
const jVector = direction.slice(3, 6);
|
|
23
27
|
const kVector = direction.slice(6, 9);
|
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
import { StackViewport, VolumeViewport, utilities as csUtils, } from '@cornerstonejs/core';
|
|
2
2
|
import filterAnnotationsWithinSlice from './filterAnnotationsWithinSlice';
|
|
3
|
+
import getViewportICamera from '../getViewportICamera';
|
|
3
4
|
export default function filterAnnotationsForDisplay(viewport, annotations, filterOptions = {}) {
|
|
4
|
-
|
|
5
|
-
|
|
5
|
+
const isLegacyVolume = viewport instanceof VolumeViewport;
|
|
6
|
+
const isNativeVolume = csUtils.getViewportContentMode(viewport) === 'volume';
|
|
7
|
+
if (isLegacyVolume || isNativeVolume) {
|
|
8
|
+
const camera = isLegacyVolume
|
|
9
|
+
? viewport.getCamera()
|
|
10
|
+
: getViewportICamera(viewport);
|
|
6
11
|
const { spacingInNormalDirection } = csUtils.getTargetVolumeAndSpacingInNormalDir(viewport, camera);
|
|
7
12
|
return filterAnnotationsWithinSlice(annotations, camera, spacingInNormalDirection);
|
|
8
13
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { BaseVolumeViewport, cache, utilities } from '@cornerstonejs/core';
|
|
2
|
+
import getViewportICamera from '../getViewportICamera';
|
|
2
3
|
import { SegmentationRepresentations } from '../../enums';
|
|
3
4
|
import { getSegmentation, getCurrentLabelmapImageIdsForViewport, } from '../../stateManagement/segmentation/segmentationState';
|
|
4
5
|
import { getAnnotation } from '../../stateManagement';
|
|
@@ -75,7 +76,7 @@ export function getSegmentIndexAtWorldForLabelmap(segmentation, worldPoint, { vi
|
|
|
75
76
|
export function getSegmentIndexAtWorldForContour(segmentation, worldPoint, { viewport }) {
|
|
76
77
|
const contourData = segmentation.representationData.Contour;
|
|
77
78
|
const segmentIndices = Array.from(contourData.annotationUIDsMap.keys());
|
|
78
|
-
const { viewPlaneNormal } = viewport
|
|
79
|
+
const { viewPlaneNormal } = getViewportICamera(viewport);
|
|
79
80
|
for (const segmentIndex of segmentIndices) {
|
|
80
81
|
const annotationsSet = contourData.annotationUIDsMap.get(segmentIndex);
|
|
81
82
|
if (!annotationsSet) {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { quat, vec3 } from 'gl-matrix';
|
|
2
2
|
import { utilities as csUtils, cache, volumeLoader } from '@cornerstonejs/core';
|
|
3
|
+
import getViewportICamera from '../../getViewportICamera';
|
|
3
4
|
import { run } from './runGrowCut';
|
|
4
5
|
import { getSphereBoundsInfo } from '../../getSphereBoundsInfo';
|
|
5
6
|
const { transformWorldToIndex } = csUtils;
|
|
@@ -29,7 +30,7 @@ function _getSphereBoundsInfo(referencedVolume, sphereInfo) {
|
|
|
29
30
|
}
|
|
30
31
|
function _createSubVolumeFromSphere(referencedVolume, sphereInfo, viewport) {
|
|
31
32
|
const refVolImageData = referencedVolume.imageData;
|
|
32
|
-
const camera = viewport
|
|
33
|
+
const camera = getViewportICamera(viewport);
|
|
33
34
|
const { ijkVecRowDir, ijkVecColDir } = csUtils.getVolumeDirectionVectors(refVolImageData, camera);
|
|
34
35
|
const obliqueView = [ijkVecRowDir, ijkVecColDir].some((vec) => !csUtils.isEqual(Math.abs(vec[0]), 1) &&
|
|
35
36
|
!csUtils.isEqual(Math.abs(vec[1]), 1) &&
|
|
@@ -113,7 +114,7 @@ function _setNegativeSeedValues(subVolume, labelmap, sphereInfo, viewport, optio
|
|
|
113
114
|
const subVolPixelData = subVolume.voxelManager.getCompleteScalarDataArray();
|
|
114
115
|
const [columns, rows, numSlices] = labelmap.dimensions;
|
|
115
116
|
const numPixelsPerSlice = columns * rows;
|
|
116
|
-
const { worldVecRowDir, worldVecSliceDir } = csUtils.getVolumeDirectionVectors(labelmap.imageData, viewport
|
|
117
|
+
const { worldVecRowDir, worldVecSliceDir } = csUtils.getVolumeDirectionVectors(labelmap.imageData, getViewportICamera(viewport));
|
|
117
118
|
const ijkSphereCenter = transformWorldToIndex(subVolume.imageData, sphereInfo.center);
|
|
118
119
|
const referencePixelValue = subVolPixelData[ijkSphereCenter[2] * columns * rows +
|
|
119
120
|
ijkSphereCenter[1] * columns +
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { utilities, Enums } from '@cornerstonejs/core';
|
|
2
|
+
function normalizeVec3(v) {
|
|
3
|
+
const length = Math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
|
|
4
|
+
return length > 0 ? [v[0] / length, v[1] / length, v[2] / length] : v;
|
|
5
|
+
}
|
|
6
|
+
export default function setViewportCamera(viewport, camera) {
|
|
7
|
+
const vp = viewport;
|
|
8
|
+
if (utilities.isGenericViewport(viewport)) {
|
|
9
|
+
if (viewport.type === Enums.ViewportType.PLANAR_NEXT &&
|
|
10
|
+
typeof vp.setViewReference === 'function') {
|
|
11
|
+
const ref = viewport.getViewReference();
|
|
12
|
+
const focalPoint = camera.focalPoint ?? ref?.cameraFocalPoint;
|
|
13
|
+
const viewUp = camera.viewUp ?? ref?.viewUp;
|
|
14
|
+
let viewPlaneNormal = camera.viewPlaneNormal;
|
|
15
|
+
if (!viewPlaneNormal && camera.position && focalPoint) {
|
|
16
|
+
viewPlaneNormal = normalizeVec3([
|
|
17
|
+
camera.position[0] - focalPoint[0],
|
|
18
|
+
camera.position[1] - focalPoint[1],
|
|
19
|
+
camera.position[2] - focalPoint[2],
|
|
20
|
+
]);
|
|
21
|
+
}
|
|
22
|
+
const rotatingVp = viewport;
|
|
23
|
+
const readResolvedScale = () => rotatingVp.getResolvedView?.()?.toICamera?.()?.parallelScale;
|
|
24
|
+
const beforeScale = readResolvedScale();
|
|
25
|
+
const beforeZoom = rotatingVp.getZoom?.();
|
|
26
|
+
vp.setViewReference({
|
|
27
|
+
...ref,
|
|
28
|
+
cameraFocalPoint: focalPoint,
|
|
29
|
+
viewPlaneNormal,
|
|
30
|
+
viewUp,
|
|
31
|
+
});
|
|
32
|
+
rotatingVp.invalidateResolvedView?.();
|
|
33
|
+
const afterScale = readResolvedScale();
|
|
34
|
+
if (beforeScale &&
|
|
35
|
+
afterScale &&
|
|
36
|
+
typeof beforeZoom === 'number' &&
|
|
37
|
+
typeof rotatingVp.setZoom === 'function') {
|
|
38
|
+
const newZoom = (afterScale * beforeZoom) / beforeScale;
|
|
39
|
+
if (Number.isFinite(newZoom) && newZoom > 0) {
|
|
40
|
+
rotatingVp.setZoom(newZoom);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
viewport.render();
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
vp.setViewState?.(camera);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
vp.setCamera?.(camera);
|
|
50
|
+
}
|
|
51
|
+
export function resetViewportCamera(viewport, options) {
|
|
52
|
+
const vp = viewport;
|
|
53
|
+
if (utilities.isGenericViewport(viewport)) {
|
|
54
|
+
vp.resetViewState?.(options);
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
vp.resetCamera?.(options);
|
|
58
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { getEnabledElement,
|
|
1
|
+
import { getEnabledElement, Enums, utilities } from '@cornerstonejs/core';
|
|
2
2
|
import { getToolState } from './state';
|
|
3
|
+
import { viewportSupportsImageSlices } from '../viewportCapabilities';
|
|
3
4
|
export const requestType = Enums.RequestType.Prefetch;
|
|
4
5
|
export const priority = 0;
|
|
5
6
|
export function range(lowEnd, highEnd) {
|
|
@@ -34,7 +35,10 @@ export function getStackData(element) {
|
|
|
34
35
|
return null;
|
|
35
36
|
}
|
|
36
37
|
const { viewport } = enabledElement;
|
|
37
|
-
if (!(viewport
|
|
38
|
+
if (!viewportSupportsImageSlices(viewport) ||
|
|
39
|
+
utilities.viewportIsInVolumeMode(viewport) ||
|
|
40
|
+
(utilities.viewportSupportsVolumeCompatibility(viewport) &&
|
|
41
|
+
!utilities.isGenericViewport(viewport))) {
|
|
38
42
|
return null;
|
|
39
43
|
}
|
|
40
44
|
return {
|