@cornerstonejs/tools 3.7.4 → 3.7.5
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/eventListeners/segmentation/labelmap/onLabelmapSegmentationDataModified.js +7 -55
- package/dist/esm/eventListeners/segmentation/labelmap/performStackLabelmapUpdate.d.ts +4 -0
- package/dist/esm/eventListeners/segmentation/labelmap/performStackLabelmapUpdate.js +37 -0
- package/dist/esm/eventListeners/segmentation/labelmap/performVolumeLabelmapUpdate.d.ts +6 -0
- package/dist/esm/eventListeners/segmentation/labelmap/performVolumeLabelmapUpdate.js +21 -0
- package/dist/esm/tools/displayTools/Labelmap/addVolumesAsIndependentComponents.js +11 -8
- package/package.json +3 -3
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import * as SegmentationState from '../../../stateManagement/segmentation/segmentationState';
|
|
1
|
+
import { VolumeViewport, getEnabledElementByViewportId, StackViewport, } from '@cornerstonejs/core';
|
|
3
2
|
import { SegmentationRepresentations } from '../../../enums';
|
|
4
|
-
import {
|
|
3
|
+
import { performVolumeLabelmapUpdate } from './performVolumeLabelmapUpdate';
|
|
4
|
+
import { performStackLabelmapUpdate } from './performStackLabelmapUpdate';
|
|
5
|
+
import { getSegmentation } from '../../../stateManagement/segmentation/getSegmentation';
|
|
6
|
+
import { getViewportIdsWithSegmentation } from '../../../stateManagement/segmentation/getViewportIdsWithSegmentation';
|
|
5
7
|
const onLabelmapSegmentationDataModified = function (evt) {
|
|
6
8
|
const { segmentationId, modifiedSlicesToUse } = evt.detail;
|
|
7
|
-
const { representationData } =
|
|
8
|
-
const viewportIds =
|
|
9
|
+
const { representationData } = getSegmentation(segmentationId);
|
|
10
|
+
const viewportIds = getViewportIdsWithSegmentation(segmentationId);
|
|
9
11
|
const hasVolumeViewport = viewportIds.some((viewportId) => {
|
|
10
12
|
const { viewport } = getEnabledElementByViewportId(viewportId);
|
|
11
13
|
return viewport instanceof VolumeViewport;
|
|
@@ -32,54 +34,4 @@ const onLabelmapSegmentationDataModified = function (evt) {
|
|
|
32
34
|
}
|
|
33
35
|
});
|
|
34
36
|
};
|
|
35
|
-
function performVolumeLabelmapUpdate({ modifiedSlicesToUse, representationData, type, }) {
|
|
36
|
-
const segmentationVolume = cache.getVolume(representationData[type].volumeId);
|
|
37
|
-
if (!segmentationVolume) {
|
|
38
|
-
console.warn('segmentation not found in cache');
|
|
39
|
-
return;
|
|
40
|
-
}
|
|
41
|
-
const { imageData, vtkOpenGLTexture } = segmentationVolume;
|
|
42
|
-
let slicesToUpdate;
|
|
43
|
-
if (modifiedSlicesToUse?.length > 0) {
|
|
44
|
-
slicesToUpdate = modifiedSlicesToUse;
|
|
45
|
-
}
|
|
46
|
-
else {
|
|
47
|
-
const numSlices = imageData.getDimensions()[2];
|
|
48
|
-
slicesToUpdate = [...Array(numSlices).keys()];
|
|
49
|
-
}
|
|
50
|
-
slicesToUpdate.forEach((i) => {
|
|
51
|
-
vtkOpenGLTexture.setUpdatedFrame(i);
|
|
52
|
-
});
|
|
53
|
-
imageData.modified();
|
|
54
|
-
}
|
|
55
|
-
function performStackLabelmapUpdate({ viewportIds, segmentationId }) {
|
|
56
|
-
viewportIds.forEach((viewportId) => {
|
|
57
|
-
let representations = SegmentationState.getSegmentationRepresentations(viewportId, { segmentationId });
|
|
58
|
-
representations = representations.filter((representation) => representation.type === SegmentationRepresentations.Labelmap);
|
|
59
|
-
representations.forEach((representation) => {
|
|
60
|
-
if (representation.segmentationId !== segmentationId) {
|
|
61
|
-
return;
|
|
62
|
-
}
|
|
63
|
-
const enabledElement = getEnabledElementByViewportId(viewportId);
|
|
64
|
-
if (!enabledElement) {
|
|
65
|
-
return;
|
|
66
|
-
}
|
|
67
|
-
const { viewport } = enabledElement;
|
|
68
|
-
if (viewport instanceof VolumeViewport) {
|
|
69
|
-
return;
|
|
70
|
-
}
|
|
71
|
-
const actorEntries = getLabelmapActorEntries(viewportId, segmentationId);
|
|
72
|
-
if (!actorEntries?.length) {
|
|
73
|
-
return;
|
|
74
|
-
}
|
|
75
|
-
actorEntries.forEach((actorEntry, i) => {
|
|
76
|
-
const segImageData = actorEntry.actor.getMapper().getInputData();
|
|
77
|
-
const currentSegmentationImageIds = SegmentationState.getCurrentLabelmapImageIdsForViewport(viewportId, segmentationId);
|
|
78
|
-
const segmentationImage = cache.getImage(currentSegmentationImageIds[i]);
|
|
79
|
-
segImageData.modified();
|
|
80
|
-
csUtils.updateVTKImageDataWithCornerstoneImage(segImageData, segmentationImage);
|
|
81
|
-
});
|
|
82
|
-
});
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
37
|
export default onLabelmapSegmentationDataModified;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { cache, utilities as csUtils, VolumeViewport, getEnabledElementByViewportId, } from '@cornerstonejs/core';
|
|
2
|
+
import { SegmentationRepresentations } from '../../../enums';
|
|
3
|
+
import { getLabelmapActorEntries } from '../../../stateManagement/segmentation/helpers/getSegmentationActor';
|
|
4
|
+
import { getSegmentationRepresentations } from '../../../stateManagement/segmentation/getSegmentationRepresentation';
|
|
5
|
+
import { getCurrentLabelmapImageIdsForViewport } from '../../../stateManagement/segmentation/getCurrentLabelmapImageIdForViewport';
|
|
6
|
+
export function performStackLabelmapUpdate({ viewportIds, segmentationId, }) {
|
|
7
|
+
viewportIds.forEach((viewportId) => {
|
|
8
|
+
let representations = getSegmentationRepresentations(viewportId, {
|
|
9
|
+
segmentationId,
|
|
10
|
+
});
|
|
11
|
+
representations = representations.filter((representation) => representation.type === SegmentationRepresentations.Labelmap);
|
|
12
|
+
representations.forEach((representation) => {
|
|
13
|
+
if (representation.segmentationId !== segmentationId) {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
const enabledElement = getEnabledElementByViewportId(viewportId);
|
|
17
|
+
if (!enabledElement) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
const { viewport } = enabledElement;
|
|
21
|
+
if (viewport instanceof VolumeViewport) {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
const actorEntries = getLabelmapActorEntries(viewportId, segmentationId);
|
|
25
|
+
if (!actorEntries?.length) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
actorEntries.forEach((actorEntry, i) => {
|
|
29
|
+
const segImageData = actorEntry.actor.getMapper().getInputData();
|
|
30
|
+
const currentSegmentationImageIds = getCurrentLabelmapImageIdsForViewport(viewportId, segmentationId);
|
|
31
|
+
const segmentationImage = cache.getImage(currentSegmentationImageIds[i]);
|
|
32
|
+
segImageData.modified();
|
|
33
|
+
csUtils.updateVTKImageDataWithCornerstoneImage(segImageData, segmentationImage);
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { SegmentationRepresentations } from '../../../enums';
|
|
2
|
+
export declare function performVolumeLabelmapUpdate({ modifiedSlicesToUse, representationData, type, }: {
|
|
3
|
+
modifiedSlicesToUse: number[];
|
|
4
|
+
representationData: Record<string, unknown>;
|
|
5
|
+
type: SegmentationRepresentations;
|
|
6
|
+
}): void;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { cache } from '@cornerstonejs/core';
|
|
2
|
+
export function performVolumeLabelmapUpdate({ modifiedSlicesToUse, representationData, type, }) {
|
|
3
|
+
const segmentationVolume = cache.getVolume(representationData[type].volumeId);
|
|
4
|
+
if (!segmentationVolume) {
|
|
5
|
+
console.warn('segmentation not found in cache');
|
|
6
|
+
return;
|
|
7
|
+
}
|
|
8
|
+
const { imageData, vtkOpenGLTexture } = segmentationVolume;
|
|
9
|
+
let slicesToUpdate;
|
|
10
|
+
if (modifiedSlicesToUse?.length > 0) {
|
|
11
|
+
slicesToUpdate = modifiedSlicesToUse;
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
const numSlices = imageData.getDimensions()[2];
|
|
15
|
+
slicesToUpdate = [...Array(numSlices).keys()];
|
|
16
|
+
}
|
|
17
|
+
slicesToUpdate.forEach((i) => {
|
|
18
|
+
vtkOpenGLTexture.setUpdatedFrame(i);
|
|
19
|
+
});
|
|
20
|
+
imageData.modified();
|
|
21
|
+
}
|
|
@@ -28,9 +28,11 @@ export async function addVolumesAsIndependentComponents({ viewport, volumeInputs
|
|
|
28
28
|
throw new Error(`segImageVolume with id: ${segImageVolume.volumeId} does not exist`);
|
|
29
29
|
}
|
|
30
30
|
const segVoxelManager = segImageVolume.voxelManager;
|
|
31
|
+
const segData = segVoxelManager.getCompleteScalarDataArray();
|
|
31
32
|
const { imageData: segImageData } = segImageVolume;
|
|
32
33
|
const baseVolume = cache.getVolume(referenceVolumeId);
|
|
33
34
|
const baseVoxelManager = baseVolume.voxelManager;
|
|
35
|
+
const baseData = baseVoxelManager.getCompleteScalarDataArray();
|
|
34
36
|
const newComp = 2;
|
|
35
37
|
const cubeData = new Float32Array(newComp * baseVolume.voxelManager.getScalarDataLength());
|
|
36
38
|
const dims = segImageData.getDimensions();
|
|
@@ -38,8 +40,8 @@ export async function addVolumesAsIndependentComponents({ viewport, volumeInputs
|
|
|
38
40
|
for (let y = 0; y < dims[1]; ++y) {
|
|
39
41
|
for (let x = 0; x < dims[0]; ++x) {
|
|
40
42
|
const iTuple = x + dims[0] * (y + dims[1] * z);
|
|
41
|
-
cubeData[iTuple * newComp + 0] =
|
|
42
|
-
cubeData[iTuple * newComp + 1] =
|
|
43
|
+
cubeData[iTuple * newComp + 0] = baseData[iTuple];
|
|
44
|
+
cubeData[iTuple * newComp + 1] = segData[iTuple];
|
|
43
45
|
}
|
|
44
46
|
}
|
|
45
47
|
}
|
|
@@ -70,7 +72,7 @@ export async function addVolumesAsIndependentComponents({ viewport, volumeInputs
|
|
|
70
72
|
preLoad: load,
|
|
71
73
|
});
|
|
72
74
|
function onSegmentationDataModified(evt) {
|
|
73
|
-
const { segmentationId
|
|
75
|
+
const { segmentationId } = evt.detail;
|
|
74
76
|
const { representationData } = getSegmentation(segmentationId);
|
|
75
77
|
const { volumeId: segVolumeId } = representationData.Labelmap;
|
|
76
78
|
if (segVolumeId !== segImageVolume.volumeId) {
|
|
@@ -78,13 +80,12 @@ export async function addVolumesAsIndependentComponents({ viewport, volumeInputs
|
|
|
78
80
|
}
|
|
79
81
|
const segmentationVolume = cache.getVolume(segVolumeId);
|
|
80
82
|
const segVoxelManager = segmentationVolume.voxelManager;
|
|
81
|
-
const
|
|
83
|
+
const imageData = mapper.getInputData();
|
|
84
|
+
const array = imageData.getPointData().getArray(0);
|
|
82
85
|
const baseData = array.getData();
|
|
83
86
|
const newComp = 2;
|
|
84
87
|
const dims = segImageData.getDimensions();
|
|
85
|
-
const slices =
|
|
86
|
-
? modifiedSlicesToUse
|
|
87
|
-
: Array.from({ length: dims[2] }, (_, i) => i);
|
|
88
|
+
const slices = Array.from({ length: dims[2] }, (_, i) => i);
|
|
88
89
|
for (const z of slices) {
|
|
89
90
|
for (let y = 0; y < dims[1]; ++y) {
|
|
90
91
|
for (let x = 0; x < dims[0]; ++x) {
|
|
@@ -94,8 +95,10 @@ export async function addVolumesAsIndependentComponents({ viewport, volumeInputs
|
|
|
94
95
|
}
|
|
95
96
|
}
|
|
96
97
|
array.setData(baseData);
|
|
98
|
+
imageData.modified();
|
|
99
|
+
viewport.render();
|
|
97
100
|
}
|
|
98
|
-
eventTarget.
|
|
101
|
+
eventTarget.addEventListenerDebounced(Events.SEGMENTATION_DATA_MODIFIED, onSegmentationDataModified, 200);
|
|
99
102
|
eventTarget.addEventListener(Events.SEGMENTATION_REPRESENTATION_REMOVED, async (evt) => {
|
|
100
103
|
eventTarget.removeEventListener(Events.SEGMENTATION_DATA_MODIFIED, onSegmentationDataModified);
|
|
101
104
|
const actorEntry = viewport.getActor(uid);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cornerstonejs/tools",
|
|
3
|
-
"version": "3.7.
|
|
3
|
+
"version": "3.7.5",
|
|
4
4
|
"description": "Cornerstone3D Tools",
|
|
5
5
|
"types": "./dist/esm/index.d.ts",
|
|
6
6
|
"module": "./dist/esm/index.js",
|
|
@@ -103,7 +103,7 @@
|
|
|
103
103
|
"canvas": "^2.11.2"
|
|
104
104
|
},
|
|
105
105
|
"peerDependencies": {
|
|
106
|
-
"@cornerstonejs/core": "^3.7.
|
|
106
|
+
"@cornerstonejs/core": "^3.7.5",
|
|
107
107
|
"@kitware/vtk.js": "32.12.1",
|
|
108
108
|
"@types/d3-array": "^3.0.4",
|
|
109
109
|
"@types/d3-interpolate": "^3.0.1",
|
|
@@ -122,5 +122,5 @@
|
|
|
122
122
|
"type": "individual",
|
|
123
123
|
"url": "https://ohif.org/donate"
|
|
124
124
|
},
|
|
125
|
-
"gitHead": "
|
|
125
|
+
"gitHead": "81632a9aae1c17f5de5d3a6c59d448960c4f7804"
|
|
126
126
|
}
|