@cornerstonejs/tools 3.0.0-beta.2 → 3.0.0-beta.3
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/config.d.ts +29 -0
- package/dist/esm/config.js +23 -0
- package/dist/esm/enums/StrategyCallbacks.d.ts +3 -1
- package/dist/esm/enums/StrategyCallbacks.js +2 -0
- package/dist/esm/enums/WorkerTypes.d.ts +3 -1
- package/dist/esm/enums/WorkerTypes.js +2 -0
- package/dist/esm/init.d.ts +2 -1
- package/dist/esm/init.js +2 -0
- package/dist/esm/stateManagement/segmentation/helpers/normalizeSegmentationInput.js +1 -1
- package/dist/esm/stateManagement/segmentation/helpers/validateSegmentationInput.js +1 -1
- package/dist/esm/stateManagement/segmentation/index.d.ts +3 -2
- package/dist/esm/stateManagement/segmentation/index.js +3 -2
- package/dist/esm/tools/displayTools/Contour/contourDisplay.js +8 -6
- package/dist/esm/tools/displayTools/Labelmap/index.d.ts +1 -1
- package/dist/esm/tools/displayTools/Labelmap/index.js +1 -1
- package/dist/esm/tools/displayTools/Labelmap/labelmapDisplay.js +14 -5
- package/dist/esm/tools/displayTools/Surface/surfaceDisplay.js +13 -8
- package/dist/esm/tools/segmentation/BrushTool.js +1 -9
- package/dist/esm/tools/segmentation/CircleScissorsTool.js +0 -1
- package/dist/esm/tools/segmentation/LabelmapBaseTool.d.ts +1 -2
- package/dist/esm/tools/segmentation/LabelmapBaseTool.js +10 -49
- package/dist/esm/tools/segmentation/RectangleScissorsTool.js +0 -1
- package/dist/esm/tools/segmentation/SphereScissorsTool.js +0 -1
- package/dist/esm/tools/segmentation/strategies/BrushStrategy.d.ts +21 -10
- package/dist/esm/tools/segmentation/strategies/BrushStrategy.js +8 -8
- package/dist/esm/tools/segmentation/strategies/compositions/determineSegmentIndex.js +7 -10
- package/dist/esm/tools/segmentation/strategies/compositions/dynamicThreshold.js +15 -14
- package/dist/esm/tools/segmentation/strategies/compositions/ensureImageVolume.d.ts +4 -0
- package/dist/esm/tools/segmentation/strategies/compositions/ensureImageVolume.js +35 -0
- package/dist/esm/tools/segmentation/strategies/compositions/ensureSegmentationVolume.d.ts +4 -0
- package/dist/esm/tools/segmentation/strategies/compositions/ensureSegmentationVolume.js +20 -0
- package/dist/esm/tools/segmentation/strategies/compositions/index.d.ts +7 -10
- package/dist/esm/tools/segmentation/strategies/compositions/index.js +4 -2
- package/dist/esm/tools/segmentation/strategies/compositions/islandRemovalComposition.js +3 -2
- package/dist/esm/tools/segmentation/strategies/compositions/labelmapStatistics.d.ts +1 -1
- package/dist/esm/tools/segmentation/strategies/compositions/labelmapStatistics.js +6 -97
- package/dist/esm/tools/segmentation/strategies/compositions/preview.js +3 -3
- package/dist/esm/tools/segmentation/strategies/compositions/threshold.js +5 -6
- package/dist/esm/tools/segmentation/strategies/fillCircle.js +2 -2
- package/dist/esm/tools/segmentation/strategies/fillSphere.js +3 -3
- package/dist/esm/tools/segmentation/strategies/utils/getStrategyData.d.ts +7 -3
- package/dist/esm/tools/segmentation/strategies/utils/getStrategyData.js +78 -34
- package/dist/esm/tools/segmentation/strategies/utils/isWithinThreshold.d.ts +2 -7
- package/dist/esm/tools/segmentation/strategies/utils/isWithinThreshold.js +5 -4
- package/dist/esm/types/CalculatorTypes.d.ts +2 -0
- package/dist/esm/types/LabelmapToolOperationData.d.ts +1 -1
- package/dist/esm/types/index.d.ts +3 -4
- package/dist/esm/utilities/getPixelValueUnits.d.ts +2 -1
- package/dist/esm/utilities/getPixelValueUnits.js +5 -1
- package/dist/esm/utilities/index.d.ts +3 -2
- package/dist/esm/utilities/index.js +3 -2
- package/dist/esm/utilities/math/basic/BasicStatsCalculator.d.ts +6 -1
- package/dist/esm/utilities/math/basic/BasicStatsCalculator.js +27 -2
- package/dist/esm/utilities/math/vec2/liangBarksyClip.d.ts +1 -1
- package/dist/esm/utilities/registerComputeWorker.d.ts +1 -0
- package/dist/esm/{stateManagement/segmentation/polySeg/registerPolySegWorker.js → utilities/registerComputeWorker.js} +4 -4
- package/dist/esm/utilities/segmentation/brushThresholdForToolGroup.d.ts +5 -1
- package/dist/esm/utilities/segmentation/brushThresholdForToolGroup.js +12 -13
- package/dist/esm/{stateManagement/segmentation/polySeg → utilities/segmentation}/computeAndAddRepresentation.d.ts +1 -1
- package/dist/esm/{stateManagement/segmentation/polySeg → utilities/segmentation}/computeAndAddRepresentation.js +4 -6
- package/dist/esm/utilities/segmentation/getOrCreateSegmentationVolume.d.ts +2 -0
- package/dist/esm/utilities/segmentation/getOrCreateSegmentationVolume.js +21 -0
- package/dist/esm/utilities/segmentation/getStatistics.d.ts +5 -0
- package/dist/esm/utilities/segmentation/getStatistics.js +210 -0
- package/dist/esm/utilities/segmentation/index.d.ts +6 -1
- package/dist/esm/utilities/segmentation/index.js +6 -1
- package/dist/esm/{tools/displayTools/Labelmap → utilities/segmentation}/validateLabelmap.d.ts +2 -2
- package/dist/esm/workers/computeWorker.js +78 -0
- package/package.json +3 -3
- package/dist/esm/stateManagement/segmentation/helpers/clipAndCacheSurfacesForViewport.d.ts +0 -16
- package/dist/esm/stateManagement/segmentation/helpers/clipAndCacheSurfacesForViewport.js +0 -88
- package/dist/esm/stateManagement/segmentation/polySeg/Contour/computeAndAddContourRepresentation.d.ts +0 -4
- package/dist/esm/stateManagement/segmentation/polySeg/Contour/computeAndAddContourRepresentation.js +0 -6
- package/dist/esm/stateManagement/segmentation/polySeg/Contour/contourComputationStrategies.d.ts +0 -8
- package/dist/esm/stateManagement/segmentation/polySeg/Contour/contourComputationStrategies.js +0 -103
- package/dist/esm/stateManagement/segmentation/polySeg/Contour/utils/createAndAddContourSegmentationsFromClippedSurfaces.d.ts +0 -3
- package/dist/esm/stateManagement/segmentation/polySeg/Contour/utils/createAndAddContourSegmentationsFromClippedSurfaces.js +0 -71
- package/dist/esm/stateManagement/segmentation/polySeg/Contour/utils/extractContourData.d.ts +0 -3
- package/dist/esm/stateManagement/segmentation/polySeg/Contour/utils/extractContourData.js +0 -16
- package/dist/esm/stateManagement/segmentation/polySeg/Contour/utils/updateContoursOnCameraModified.d.ts +0 -1
- package/dist/esm/stateManagement/segmentation/polySeg/Contour/utils/updateContoursOnCameraModified.js +0 -25
- package/dist/esm/stateManagement/segmentation/polySeg/Labelmap/computeAndAddLabelmapRepresentation.d.ts +0 -2
- package/dist/esm/stateManagement/segmentation/polySeg/Labelmap/computeAndAddLabelmapRepresentation.js +0 -13
- package/dist/esm/stateManagement/segmentation/polySeg/Labelmap/convertContourToLabelmap.d.ts +0 -7
- package/dist/esm/stateManagement/segmentation/polySeg/Labelmap/convertContourToLabelmap.js +0 -143
- package/dist/esm/stateManagement/segmentation/polySeg/Labelmap/convertSurfaceToLabelmap.d.ts +0 -6
- package/dist/esm/stateManagement/segmentation/polySeg/Labelmap/convertSurfaceToLabelmap.js +0 -49
- package/dist/esm/stateManagement/segmentation/polySeg/Labelmap/labelmapComputationStrategies.d.ts +0 -6
- package/dist/esm/stateManagement/segmentation/polySeg/Labelmap/labelmapComputationStrategies.js +0 -96
- package/dist/esm/stateManagement/segmentation/polySeg/Surface/computeAndAddSurfaceRepresentation.d.ts +0 -4
- package/dist/esm/stateManagement/segmentation/polySeg/Surface/computeAndAddSurfaceRepresentation.js +0 -7
- package/dist/esm/stateManagement/segmentation/polySeg/Surface/convertContourToSurface.d.ts +0 -3
- package/dist/esm/stateManagement/segmentation/polySeg/Surface/convertContourToSurface.js +0 -37
- package/dist/esm/stateManagement/segmentation/polySeg/Surface/convertLabelmapToSurface.d.ts +0 -3
- package/dist/esm/stateManagement/segmentation/polySeg/Surface/convertLabelmapToSurface.js +0 -44
- package/dist/esm/stateManagement/segmentation/polySeg/Surface/createAndCacheSurfacesFromRaw.d.ts +0 -5
- package/dist/esm/stateManagement/segmentation/polySeg/Surface/createAndCacheSurfacesFromRaw.js +0 -33
- package/dist/esm/stateManagement/segmentation/polySeg/Surface/surfaceComputationStrategies.d.ts +0 -12
- package/dist/esm/stateManagement/segmentation/polySeg/Surface/surfaceComputationStrategies.js +0 -75
- package/dist/esm/stateManagement/segmentation/polySeg/Surface/updateSurfaceData.d.ts +0 -1
- package/dist/esm/stateManagement/segmentation/polySeg/Surface/updateSurfaceData.js +0 -59
- package/dist/esm/stateManagement/segmentation/polySeg/canComputeRequestedRepresentation.d.ts +0 -3
- package/dist/esm/stateManagement/segmentation/polySeg/canComputeRequestedRepresentation.js +0 -58
- package/dist/esm/stateManagement/segmentation/polySeg/index.d.ts +0 -5
- package/dist/esm/stateManagement/segmentation/polySeg/index.js +0 -5
- package/dist/esm/stateManagement/segmentation/polySeg/registerPolySegWorker.d.ts +0 -1
- package/dist/esm/tools/segmentation/strategies/compositions/labelmapInterpolation.d.ts +0 -12
- package/dist/esm/tools/segmentation/strategies/compositions/labelmapInterpolation.js +0 -60
- package/dist/esm/tools/segmentation/strategies/utils/getItkImage.d.ts +0 -1
- package/dist/esm/tools/segmentation/strategies/utils/getItkImage.js +0 -49
- package/dist/esm/types/PolySeg.d.ts +0 -6
- package/dist/esm/types/PolySeg.js +0 -0
- package/dist/esm/workers/polySegConverters.js +0 -382
- /package/dist/esm/{geometricSurfaceUtils.d.ts → utilities/geometricSurfaceUtils.d.ts} +0 -0
- /package/dist/esm/{geometricSurfaceUtils.js → utilities/geometricSurfaceUtils.js} +0 -0
- /package/dist/esm/{tools/displayTools/Labelmap → utilities/segmentation}/validateLabelmap.js +0 -0
- /package/dist/esm/workers/{polySegConverters.d.ts → computeWorker.d.ts} +0 -0
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
import { Enums, getWebWorkerManager, eventTarget, triggerEvent, } from '@cornerstonejs/core';
|
|
2
|
-
import { WorkerTypes } from '../../../enums';
|
|
3
|
-
import { pointToString } from '../../../utilities/pointToString';
|
|
4
|
-
import { registerPolySegWorker } from '../polySeg/registerPolySegWorker';
|
|
5
|
-
import { getSurfaceActorEntry } from './getSegmentationActor';
|
|
6
|
-
const workerManager = getWebWorkerManager();
|
|
7
|
-
const polyDataCache = new Map();
|
|
8
|
-
const surfacesAABBCache = new Map();
|
|
9
|
-
const triggerWorkerProgress = (eventTarget, progress) => {
|
|
10
|
-
triggerEvent(eventTarget, Enums.Events.WEB_WORKER_PROGRESS, {
|
|
11
|
-
progress,
|
|
12
|
-
type: WorkerTypes.SURFACE_CLIPPING,
|
|
13
|
-
});
|
|
14
|
-
};
|
|
15
|
-
export async function clipAndCacheSurfacesForViewport(surfacesInfo, viewport) {
|
|
16
|
-
registerPolySegWorker();
|
|
17
|
-
const planesInfo = viewport.getSlicesClippingPlanes?.();
|
|
18
|
-
if (!planesInfo) {
|
|
19
|
-
return;
|
|
20
|
-
}
|
|
21
|
-
const currentSliceIndex = viewport.getSliceIndex();
|
|
22
|
-
planesInfo.sort((a, b) => {
|
|
23
|
-
const diffA = Math.abs(a.sliceIndex - currentSliceIndex);
|
|
24
|
-
const diffB = Math.abs(b.sliceIndex - currentSliceIndex);
|
|
25
|
-
return diffA - diffB;
|
|
26
|
-
});
|
|
27
|
-
triggerWorkerProgress(eventTarget, 0);
|
|
28
|
-
await updateSurfacesAABBCache(surfacesInfo);
|
|
29
|
-
const surfacesAABB = new Map();
|
|
30
|
-
surfacesInfo.forEach((surface) => {
|
|
31
|
-
surfacesAABB.set(surface.id, surfacesAABBCache.get(surface.id));
|
|
32
|
-
});
|
|
33
|
-
const camera = viewport.getCamera();
|
|
34
|
-
await workerManager
|
|
35
|
-
.executeTask('polySeg', 'cutSurfacesIntoPlanes', {
|
|
36
|
-
surfacesInfo,
|
|
37
|
-
planesInfo,
|
|
38
|
-
surfacesAABB,
|
|
39
|
-
}, {
|
|
40
|
-
callbacks: [
|
|
41
|
-
({ progress }) => {
|
|
42
|
-
triggerWorkerProgress(eventTarget, progress);
|
|
43
|
-
},
|
|
44
|
-
({ sliceIndex, polyDataResults }) => {
|
|
45
|
-
polyDataResults.forEach((polyDataResult, segmentIndex) => {
|
|
46
|
-
const segmentIndexNumber = Number(segmentIndex);
|
|
47
|
-
const cacheId = generateCacheId(viewport, camera.viewPlaneNormal, sliceIndex);
|
|
48
|
-
updatePolyDataCache(segmentIndexNumber, cacheId, polyDataResult);
|
|
49
|
-
});
|
|
50
|
-
},
|
|
51
|
-
],
|
|
52
|
-
})
|
|
53
|
-
.catch((error) => {
|
|
54
|
-
console.error(error);
|
|
55
|
-
});
|
|
56
|
-
triggerWorkerProgress(eventTarget, 100);
|
|
57
|
-
return polyDataCache;
|
|
58
|
-
}
|
|
59
|
-
async function updateSurfacesAABBCache(surfacesInfo) {
|
|
60
|
-
const surfacesWithoutAABB = surfacesInfo.filter((surface) => !surfacesAABBCache.has(surface.id));
|
|
61
|
-
if (!surfacesWithoutAABB.length) {
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
const surfacesAABB = await workerManager.executeTask('polySeg', 'getSurfacesAABBs', {
|
|
65
|
-
surfacesInfo: surfacesWithoutAABB,
|
|
66
|
-
}, {
|
|
67
|
-
callbacks: [
|
|
68
|
-
({ progress }) => {
|
|
69
|
-
triggerWorkerProgress(eventTarget, progress);
|
|
70
|
-
},
|
|
71
|
-
],
|
|
72
|
-
});
|
|
73
|
-
surfacesAABB.forEach((aabb, id) => {
|
|
74
|
-
surfacesAABBCache.set(id, aabb);
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
|
-
export function generateCacheId(viewport, viewPlaneNormal, sliceIndex) {
|
|
78
|
-
return `${viewport.id}-${pointToString(viewPlaneNormal)}-${sliceIndex}`;
|
|
79
|
-
}
|
|
80
|
-
export function updatePolyDataCache(segmentIndex, cacheId, polyDataResult) {
|
|
81
|
-
const { points, lines, numberOfCells } = polyDataResult;
|
|
82
|
-
let segmentCache = polyDataCache.get(segmentIndex);
|
|
83
|
-
if (!segmentCache) {
|
|
84
|
-
segmentCache = new Map();
|
|
85
|
-
polyDataCache.set(segmentIndex, segmentCache);
|
|
86
|
-
}
|
|
87
|
-
segmentCache.set(cacheId, { points, lines, numberOfCells });
|
|
88
|
-
}
|
package/dist/esm/stateManagement/segmentation/polySeg/Contour/computeAndAddContourRepresentation.js
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import { SegmentationRepresentations } from '../../../../enums';
|
|
2
|
-
import { computeAndAddRepresentation } from '../computeAndAddRepresentation';
|
|
3
|
-
import { computeContourData } from './contourComputationStrategies';
|
|
4
|
-
export function computeAndAddContourRepresentation(segmentationId, options = {}) {
|
|
5
|
-
return computeAndAddRepresentation(segmentationId, SegmentationRepresentations.Contour, () => computeContourData(segmentationId, options), () => undefined);
|
|
6
|
-
}
|
package/dist/esm/stateManagement/segmentation/polySeg/Contour/contourComputationStrategies.d.ts
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import type { PolySegConversionOptions } from '../../../../types';
|
|
2
|
-
import type { SurfaceClipResult } from '../../helpers/clipAndCacheSurfacesForViewport';
|
|
3
|
-
export type RawContourData = Map<number, SurfaceClipResult[]>;
|
|
4
|
-
export declare function computeContourData(segmentationId: string, options?: PolySegConversionOptions): Promise<{
|
|
5
|
-
annotationUIDsMap: Map<number, Set<string>>;
|
|
6
|
-
}>;
|
|
7
|
-
declare function computeContourFromLabelmapSegmentation(segmentationId: any, options?: PolySegConversionOptions): Promise<RawContourData>;
|
|
8
|
-
export { computeContourFromLabelmapSegmentation };
|
package/dist/esm/stateManagement/segmentation/polySeg/Contour/contourComputationStrategies.js
DELETED
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
import { cache } from '@cornerstonejs/core';
|
|
2
|
-
import { getUniqueSegmentIndices } from '../../../../utilities/segmentation/getUniqueSegmentIndices';
|
|
3
|
-
import { computeSurfaceFromLabelmapSegmentation } from '../Surface/surfaceComputationStrategies';
|
|
4
|
-
import { clipAndCacheSurfacesForViewport } from '../../helpers/clipAndCacheSurfacesForViewport';
|
|
5
|
-
import { extractContourData } from './utils/extractContourData';
|
|
6
|
-
import { createAndAddContourSegmentationsFromClippedSurfaces } from './utils/createAndAddContourSegmentationsFromClippedSurfaces';
|
|
7
|
-
import { getSegmentation } from '../../getSegmentation';
|
|
8
|
-
import { segmentationStyle } from '../../SegmentationStyle';
|
|
9
|
-
import { SegmentationRepresentations } from '../../../../enums';
|
|
10
|
-
export async function computeContourData(segmentationId, options = {}) {
|
|
11
|
-
const segmentIndices = options.segmentIndices?.length
|
|
12
|
-
? options.segmentIndices
|
|
13
|
-
: getUniqueSegmentIndices(segmentationId);
|
|
14
|
-
let rawContourData;
|
|
15
|
-
const segmentation = getSegmentation(segmentationId);
|
|
16
|
-
const representationData = segmentation.representationData;
|
|
17
|
-
try {
|
|
18
|
-
if (representationData.Surface) {
|
|
19
|
-
rawContourData = await computeContourFromSurfaceSegmentation(segmentationId, {
|
|
20
|
-
segmentIndices,
|
|
21
|
-
...options,
|
|
22
|
-
});
|
|
23
|
-
}
|
|
24
|
-
else if (representationData.Labelmap) {
|
|
25
|
-
rawContourData = await computeContourFromLabelmapSegmentation(segmentationId, {
|
|
26
|
-
segmentIndices,
|
|
27
|
-
...options,
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
catch (error) {
|
|
32
|
-
console.error(error);
|
|
33
|
-
throw error;
|
|
34
|
-
}
|
|
35
|
-
if (!rawContourData) {
|
|
36
|
-
throw new Error('Not enough data to convert to contour, currently only support converting volume labelmap to contour if available');
|
|
37
|
-
}
|
|
38
|
-
const { viewport } = options;
|
|
39
|
-
const annotationUIDsMap = createAndAddContourSegmentationsFromClippedSurfaces(rawContourData, viewport, segmentationId);
|
|
40
|
-
segmentationStyle.setStyle({ segmentationId, type: SegmentationRepresentations.Contour }, {
|
|
41
|
-
fillAlpha: 0,
|
|
42
|
-
});
|
|
43
|
-
return {
|
|
44
|
-
annotationUIDsMap,
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
async function computeContourFromLabelmapSegmentation(segmentationId, options = {}) {
|
|
48
|
-
if (!options.viewport) {
|
|
49
|
-
throw new Error('Viewport is required to compute contour from labelmap');
|
|
50
|
-
}
|
|
51
|
-
const results = await computeSurfaceFromLabelmapSegmentation(segmentationId, options);
|
|
52
|
-
if (!results?.length) {
|
|
53
|
-
console.error('Failed to convert labelmap to surface or labelmap is empty');
|
|
54
|
-
return;
|
|
55
|
-
}
|
|
56
|
-
const { viewport } = options;
|
|
57
|
-
const pointsAndPolys = results.map((surface) => {
|
|
58
|
-
return {
|
|
59
|
-
id: surface.segmentIndex.toString(),
|
|
60
|
-
points: surface.data.points,
|
|
61
|
-
polys: surface.data.polys,
|
|
62
|
-
segmentIndex: surface.segmentIndex,
|
|
63
|
-
};
|
|
64
|
-
});
|
|
65
|
-
const polyDataCache = await clipAndCacheSurfacesForViewport(pointsAndPolys, viewport);
|
|
66
|
-
const rawResults = extractContourData(polyDataCache);
|
|
67
|
-
return rawResults;
|
|
68
|
-
}
|
|
69
|
-
async function computeContourFromSurfaceSegmentation(segmentationId, options = {}) {
|
|
70
|
-
if (!options.viewport) {
|
|
71
|
-
throw new Error('Viewport is required to compute contour from surface');
|
|
72
|
-
}
|
|
73
|
-
const { viewport } = options;
|
|
74
|
-
const segmentIndices = options.segmentIndices?.length
|
|
75
|
-
? options.segmentIndices
|
|
76
|
-
: getUniqueSegmentIndices(segmentationId);
|
|
77
|
-
const segmentIndexToSurfaceId = new Map();
|
|
78
|
-
const surfaceIdToSegmentIndex = new Map();
|
|
79
|
-
const segmentation = getSegmentation(segmentationId);
|
|
80
|
-
const representationData = segmentation.representationData.Surface;
|
|
81
|
-
const surfacesInfo = [];
|
|
82
|
-
representationData.geometryIds.forEach((geometryId, segmentIndex) => {
|
|
83
|
-
if (segmentIndices.includes(segmentIndex)) {
|
|
84
|
-
segmentIndexToSurfaceId.set(segmentIndex, geometryId);
|
|
85
|
-
const surface = cache.getGeometry(geometryId)?.data;
|
|
86
|
-
if (surface) {
|
|
87
|
-
surfacesInfo.push({
|
|
88
|
-
id: geometryId,
|
|
89
|
-
points: surface.points,
|
|
90
|
-
polys: surface.polys,
|
|
91
|
-
segmentIndex,
|
|
92
|
-
});
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
});
|
|
96
|
-
segmentIndexToSurfaceId.forEach((surfaceId, segmentIndex) => {
|
|
97
|
-
surfaceIdToSegmentIndex.set(surfaceId, segmentIndex);
|
|
98
|
-
});
|
|
99
|
-
const polyDataCache = await clipAndCacheSurfacesForViewport(surfacesInfo, viewport);
|
|
100
|
-
const rawResults = extractContourData(polyDataCache);
|
|
101
|
-
return rawResults;
|
|
102
|
-
}
|
|
103
|
-
export { computeContourFromLabelmapSegmentation };
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import type { RawContourData } from '../contourComputationStrategies';
|
|
2
|
-
import { type Types } from '@cornerstonejs/core';
|
|
3
|
-
export declare function createAndAddContourSegmentationsFromClippedSurfaces(rawContourData: RawContourData, viewport: Types.IViewport, segmentationId: string): Map<number, Set<string>>;
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import PlanarFreehandContourSegmentationTool from '../../../../../tools/annotation/PlanarFreehandContourSegmentationTool';
|
|
2
|
-
import { addAnnotation } from '../../../../annotation/annotationState';
|
|
3
|
-
import { utilities } from '@cornerstonejs/core';
|
|
4
|
-
export function createAndAddContourSegmentationsFromClippedSurfaces(rawContourData, viewport, segmentationId) {
|
|
5
|
-
const annotationUIDsMap = new Map();
|
|
6
|
-
for (const [segmentIndex, contoursData] of rawContourData) {
|
|
7
|
-
for (const contourData of contoursData) {
|
|
8
|
-
const { points } = contourData;
|
|
9
|
-
const { lineSegments, linesNumberOfPoints } = _extractLineSegments(contourData);
|
|
10
|
-
for (let i = 0; i < lineSegments.length; i++) {
|
|
11
|
-
const line = lineSegments[i];
|
|
12
|
-
const polyline = [];
|
|
13
|
-
for (let j = 0; j < linesNumberOfPoints[i]; j++) {
|
|
14
|
-
const pointIndex = line[j];
|
|
15
|
-
polyline.push([
|
|
16
|
-
points[3 * pointIndex],
|
|
17
|
-
points[3 * pointIndex + 1],
|
|
18
|
-
points[3 * pointIndex + 2],
|
|
19
|
-
]);
|
|
20
|
-
}
|
|
21
|
-
if (polyline.length < 3) {
|
|
22
|
-
continue;
|
|
23
|
-
}
|
|
24
|
-
const contourSegmentationAnnotation = {
|
|
25
|
-
annotationUID: utilities.uuidv4(),
|
|
26
|
-
data: {
|
|
27
|
-
contour: {
|
|
28
|
-
closed: true,
|
|
29
|
-
polyline,
|
|
30
|
-
},
|
|
31
|
-
segmentation: {
|
|
32
|
-
segmentationId,
|
|
33
|
-
segmentIndex,
|
|
34
|
-
},
|
|
35
|
-
handles: {},
|
|
36
|
-
},
|
|
37
|
-
handles: {},
|
|
38
|
-
highlighted: false,
|
|
39
|
-
autoGenerated: false,
|
|
40
|
-
invalidated: false,
|
|
41
|
-
isLocked: false,
|
|
42
|
-
isVisible: true,
|
|
43
|
-
metadata: {
|
|
44
|
-
toolName: PlanarFreehandContourSegmentationTool.toolName,
|
|
45
|
-
...viewport.getViewReference(),
|
|
46
|
-
},
|
|
47
|
-
};
|
|
48
|
-
addAnnotation(contourSegmentationAnnotation, viewport.element);
|
|
49
|
-
const currentSet = annotationUIDsMap?.get(segmentIndex) || new Set();
|
|
50
|
-
currentSet.add(contourSegmentationAnnotation.annotationUID);
|
|
51
|
-
annotationUIDsMap.set(segmentIndex, currentSet);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
return annotationUIDsMap;
|
|
56
|
-
}
|
|
57
|
-
const _extractLineSegments = (contourData) => {
|
|
58
|
-
const { numberOfCells, lines } = contourData;
|
|
59
|
-
const lineSegments = [];
|
|
60
|
-
const linesNumberOfPoints = [];
|
|
61
|
-
for (let i = 0; i < lines.length;) {
|
|
62
|
-
const pointsInLine = lines[i];
|
|
63
|
-
linesNumberOfPoints.push(pointsInLine);
|
|
64
|
-
lineSegments.push(lines.slice(i + 1, i + pointsInLine + 1));
|
|
65
|
-
i += pointsInLine + 1;
|
|
66
|
-
if (lineSegments.length === numberOfCells) {
|
|
67
|
-
break;
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
return { lineSegments, linesNumberOfPoints };
|
|
71
|
-
};
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
export function extractContourData(polyDataCache) {
|
|
2
|
-
const rawResults = new Map();
|
|
3
|
-
for (const [segmentIndex, intersectionInfo] of polyDataCache) {
|
|
4
|
-
const segmentIndexNumber = Number(segmentIndex);
|
|
5
|
-
for (const [_, result] of intersectionInfo) {
|
|
6
|
-
if (!result) {
|
|
7
|
-
continue;
|
|
8
|
-
}
|
|
9
|
-
if (!rawResults.has(segmentIndexNumber)) {
|
|
10
|
-
rawResults.set(segmentIndexNumber, []);
|
|
11
|
-
}
|
|
12
|
-
rawResults.get(segmentIndexNumber).push(result);
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
return rawResults;
|
|
16
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function updateContoursOnCameraModified(surfacesInfo: any, viewport: any, segmentationRepresentationUID: any): void;
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { utilities, Enums } from '@cornerstonejs/core';
|
|
2
|
-
import { extractContourData } from './extractContourData';
|
|
3
|
-
import { clipAndCacheSurfacesForViewport } from '../../../helpers/clipAndCacheSurfacesForViewport';
|
|
4
|
-
import { createAndAddContourSegmentationsFromClippedSurfaces } from './createAndAddContourSegmentationsFromClippedSurfaces';
|
|
5
|
-
const currentViewportNormal = new Map();
|
|
6
|
-
export function updateContoursOnCameraModified(surfacesInfo, viewport, segmentationRepresentationUID) {
|
|
7
|
-
async function cameraModifiedCallback(evt) {
|
|
8
|
-
const { camera } = evt.detail;
|
|
9
|
-
const { viewPlaneNormal } = camera;
|
|
10
|
-
const surface1 = surfacesInfo[0];
|
|
11
|
-
const currentNormal = currentViewportNormal.get(surface1.id);
|
|
12
|
-
if (utilities.isEqual(viewPlaneNormal, currentNormal)) {
|
|
13
|
-
return;
|
|
14
|
-
}
|
|
15
|
-
currentViewportNormal.set(surface1.id, viewPlaneNormal);
|
|
16
|
-
const polyDataCache = await clipAndCacheSurfacesForViewport(surfacesInfo, viewport);
|
|
17
|
-
const results = extractContourData(polyDataCache);
|
|
18
|
-
createAndAddContourSegmentationsFromClippedSurfaces(results, viewport, segmentationRepresentationUID);
|
|
19
|
-
viewport.render();
|
|
20
|
-
}
|
|
21
|
-
const camera = viewport.getCamera();
|
|
22
|
-
currentViewportNormal.set(surfacesInfo[0].id, camera.viewPlaneNormal);
|
|
23
|
-
viewport.element.removeEventListener(Enums.Events.CAMERA_MODIFIED, cameraModifiedCallback);
|
|
24
|
-
viewport.element.addEventListener(Enums.Events.CAMERA_MODIFIED);
|
|
25
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { SegmentationRepresentations } from '../../../../enums';
|
|
2
|
-
import { computeAndAddRepresentation } from '../computeAndAddRepresentation';
|
|
3
|
-
import { computeLabelmapData } from './labelmapComputationStrategies';
|
|
4
|
-
import { defaultSegmentationStateManager } from '../../SegmentationStateManager';
|
|
5
|
-
import { triggerSegmentationDataModified } from '../../triggerSegmentationEvents';
|
|
6
|
-
export async function computeAndAddLabelmapRepresentation(segmentationId, options = {}) {
|
|
7
|
-
return computeAndAddRepresentation(segmentationId, SegmentationRepresentations.Labelmap, () => computeLabelmapData(segmentationId, options), () => null, () => {
|
|
8
|
-
defaultSegmentationStateManager.processLabelmapRepresentationAddition(options.viewport.id, segmentationId);
|
|
9
|
-
setTimeout(() => {
|
|
10
|
-
triggerSegmentationDataModified(segmentationId);
|
|
11
|
-
}, 0);
|
|
12
|
-
});
|
|
13
|
-
}
|
package/dist/esm/stateManagement/segmentation/polySeg/Labelmap/convertContourToLabelmap.d.ts
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import type { ContourSegmentationData, PolySegConversionOptions } from '../../../../types';
|
|
2
|
-
export declare function convertContourToVolumeLabelmap(contourRepresentationData: ContourSegmentationData, options?: PolySegConversionOptions): Promise<{
|
|
3
|
-
volumeId: string;
|
|
4
|
-
}>;
|
|
5
|
-
export declare function convertContourToStackLabelmap(contourRepresentationData: ContourSegmentationData, options?: PolySegConversionOptions): Promise<{
|
|
6
|
-
imageIds: any[];
|
|
7
|
-
}>;
|
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
import { vec3 } from 'gl-matrix';
|
|
2
|
-
import { cache, utilities, getWebWorkerManager, volumeLoader, imageLoader, metaData, Enums, triggerEvent, eventTarget, } from '@cornerstonejs/core';
|
|
3
|
-
import { getAnnotation } from '../../../annotation/annotationState';
|
|
4
|
-
import { WorkerTypes } from '../../../../enums';
|
|
5
|
-
const workerManager = getWebWorkerManager();
|
|
6
|
-
const triggerWorkerProgress = (eventTarget, progress) => {
|
|
7
|
-
triggerEvent(eventTarget, Enums.Events.WEB_WORKER_PROGRESS, {
|
|
8
|
-
progress,
|
|
9
|
-
type: WorkerTypes.POLYSEG_CONTOUR_TO_LABELMAP,
|
|
10
|
-
});
|
|
11
|
-
};
|
|
12
|
-
export async function convertContourToVolumeLabelmap(contourRepresentationData, options = {}) {
|
|
13
|
-
const viewport = options.viewport;
|
|
14
|
-
const volumeId = viewport.getVolumeId();
|
|
15
|
-
const imageIds = utilities.getViewportImageIds(viewport);
|
|
16
|
-
if (!imageIds) {
|
|
17
|
-
throw new Error('No imageIds found, labelmap computation from contour requires viewports with imageIds');
|
|
18
|
-
}
|
|
19
|
-
const segmentationVolumeId = utilities.uuidv4();
|
|
20
|
-
const segmentationVolume = volumeLoader.createAndCacheDerivedLabelmapVolume(volumeId, {
|
|
21
|
-
volumeId: segmentationVolumeId,
|
|
22
|
-
});
|
|
23
|
-
const { dimensions, origin, direction, spacing, voxelManager } = segmentationVolume;
|
|
24
|
-
const { segmentIndices, annotationUIDsInSegmentMap } = _getAnnotationMapFromSegmentation(contourRepresentationData, options);
|
|
25
|
-
triggerWorkerProgress(eventTarget, 0);
|
|
26
|
-
const newScalarData = await workerManager.executeTask('polySeg', 'convertContourToVolumeLabelmap', {
|
|
27
|
-
segmentIndices,
|
|
28
|
-
dimensions,
|
|
29
|
-
scalarData: voxelManager.getCompleteScalarDataArray?.(),
|
|
30
|
-
origin,
|
|
31
|
-
direction,
|
|
32
|
-
spacing,
|
|
33
|
-
annotationUIDsInSegmentMap,
|
|
34
|
-
}, {
|
|
35
|
-
callbacks: [
|
|
36
|
-
(progress) => {
|
|
37
|
-
triggerWorkerProgress(eventTarget, progress);
|
|
38
|
-
},
|
|
39
|
-
],
|
|
40
|
-
});
|
|
41
|
-
triggerWorkerProgress(eventTarget, 100);
|
|
42
|
-
voxelManager.setCompleteScalarDataArray(newScalarData);
|
|
43
|
-
segmentationVolume.modified();
|
|
44
|
-
return {
|
|
45
|
-
volumeId: segmentationVolume.volumeId,
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
export async function convertContourToStackLabelmap(contourRepresentationData, options = {}) {
|
|
49
|
-
if (!options.viewport) {
|
|
50
|
-
throw new Error('No viewport provided, labelmap computation from contour requires viewports');
|
|
51
|
-
}
|
|
52
|
-
const viewport = options.viewport;
|
|
53
|
-
const imageIds = viewport.getImageIds();
|
|
54
|
-
if (!imageIds) {
|
|
55
|
-
throw new Error('No imageIds found, labelmap computation from contour requires viewports with imageIds');
|
|
56
|
-
}
|
|
57
|
-
imageIds.forEach((imageId) => {
|
|
58
|
-
if (!cache.getImageLoadObject(imageId)) {
|
|
59
|
-
throw new Error('ImageIds must be cached before converting contour to labelmap');
|
|
60
|
-
}
|
|
61
|
-
});
|
|
62
|
-
const segImages = await imageLoader.createAndCacheDerivedLabelmapImages(imageIds);
|
|
63
|
-
const segmentationImageIds = segImages.map((it) => it.imageId);
|
|
64
|
-
const { segmentIndices, annotationUIDsInSegmentMap } = _getAnnotationMapFromSegmentation(contourRepresentationData, options);
|
|
65
|
-
const segmentationsInfo = new Map();
|
|
66
|
-
segmentationImageIds.forEach((segImageId, index) => {
|
|
67
|
-
const segImage = cache.getImage(segImageId);
|
|
68
|
-
const imagePlaneModule = metaData.get(Enums.MetadataModules.IMAGE_PLANE, segImageId);
|
|
69
|
-
let { columnCosines, rowCosines, rowPixelSpacing, columnPixelSpacing, imagePositionPatient, } = imagePlaneModule;
|
|
70
|
-
columnCosines = columnCosines ?? [0, 1, 0];
|
|
71
|
-
rowCosines = rowCosines ?? [1, 0, 0];
|
|
72
|
-
rowPixelSpacing = rowPixelSpacing ?? 1;
|
|
73
|
-
columnPixelSpacing = columnPixelSpacing ?? 1;
|
|
74
|
-
imagePositionPatient = imagePositionPatient ?? [0, 0, 0];
|
|
75
|
-
const rowCosineVec = vec3.fromValues(rowCosines[0], rowCosines[1], rowCosines[2]);
|
|
76
|
-
const colCosineVec = vec3.fromValues(columnCosines[0], columnCosines[1], columnCosines[2]);
|
|
77
|
-
const scanAxisNormal = vec3.create();
|
|
78
|
-
vec3.cross(scanAxisNormal, rowCosineVec, colCosineVec);
|
|
79
|
-
const direction = [...rowCosineVec, ...colCosineVec, ...scanAxisNormal];
|
|
80
|
-
const spacing = [rowPixelSpacing, columnPixelSpacing, 1];
|
|
81
|
-
const origin = imagePositionPatient;
|
|
82
|
-
segmentationsInfo.set(imageIds[index], {
|
|
83
|
-
direction,
|
|
84
|
-
spacing,
|
|
85
|
-
origin,
|
|
86
|
-
scalarData: segImage.voxelManager.getScalarData(),
|
|
87
|
-
imageId: segImageId,
|
|
88
|
-
dimensions: [segImage.width, segImage.height, 1],
|
|
89
|
-
});
|
|
90
|
-
});
|
|
91
|
-
triggerWorkerProgress(eventTarget, 0);
|
|
92
|
-
const newSegmentationsScalarData = await workerManager.executeTask('polySeg', 'convertContourToStackLabelmap', {
|
|
93
|
-
segmentationsInfo,
|
|
94
|
-
annotationUIDsInSegmentMap,
|
|
95
|
-
segmentIndices,
|
|
96
|
-
}, {
|
|
97
|
-
callbacks: [
|
|
98
|
-
(progress) => {
|
|
99
|
-
triggerWorkerProgress(eventTarget, progress);
|
|
100
|
-
},
|
|
101
|
-
],
|
|
102
|
-
});
|
|
103
|
-
triggerWorkerProgress(eventTarget, 100);
|
|
104
|
-
const segImageIds = [];
|
|
105
|
-
newSegmentationsScalarData.forEach(({ scalarData }, referencedImageId) => {
|
|
106
|
-
const segmentationInfo = segmentationsInfo.get(referencedImageId);
|
|
107
|
-
const { imageId: segImageId } = segmentationInfo;
|
|
108
|
-
const segImage = cache.getImage(segImageId);
|
|
109
|
-
segImage.voxelManager.getScalarData().set(scalarData);
|
|
110
|
-
segImage.imageFrame?.pixelData?.set(scalarData);
|
|
111
|
-
segImageIds.push(segImageId);
|
|
112
|
-
});
|
|
113
|
-
return {
|
|
114
|
-
imageIds: segImageIds,
|
|
115
|
-
};
|
|
116
|
-
}
|
|
117
|
-
function _getAnnotationMapFromSegmentation(contourRepresentationData, options = {}) {
|
|
118
|
-
const annotationMap = contourRepresentationData.annotationUIDsMap;
|
|
119
|
-
const segmentIndices = options.segmentIndices?.length
|
|
120
|
-
? options.segmentIndices
|
|
121
|
-
: Array.from(annotationMap.keys());
|
|
122
|
-
const annotationUIDsInSegmentMap = new Map();
|
|
123
|
-
segmentIndices.forEach((index) => {
|
|
124
|
-
const annotationUIDsInSegment = annotationMap.get(index);
|
|
125
|
-
let uids = Array.from(annotationUIDsInSegment);
|
|
126
|
-
uids = uids.filter((uid) => !getAnnotation(uid).parentAnnotationUID);
|
|
127
|
-
const annotations = uids.map((uid) => {
|
|
128
|
-
const annotation = getAnnotation(uid);
|
|
129
|
-
const hasChildAnnotations = annotation.childAnnotationUIDs?.length;
|
|
130
|
-
return {
|
|
131
|
-
polyline: annotation.data.contour.polyline,
|
|
132
|
-
referencedImageId: annotation.metadata.referencedImageId,
|
|
133
|
-
holesPolyline: hasChildAnnotations &&
|
|
134
|
-
annotation.childAnnotationUIDs.map((childUID) => {
|
|
135
|
-
const childAnnotation = getAnnotation(childUID);
|
|
136
|
-
return childAnnotation.data.contour.polyline;
|
|
137
|
-
}),
|
|
138
|
-
};
|
|
139
|
-
});
|
|
140
|
-
annotationUIDsInSegmentMap.set(index, annotations);
|
|
141
|
-
});
|
|
142
|
-
return { segmentIndices, annotationUIDsInSegmentMap };
|
|
143
|
-
}
|
package/dist/esm/stateManagement/segmentation/polySeg/Labelmap/convertSurfaceToLabelmap.d.ts
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import type { Types } from '@cornerstonejs/core';
|
|
2
|
-
import type { SurfaceSegmentationData } from '../../../../types/SurfaceTypes';
|
|
3
|
-
export declare function convertSurfaceToVolumeLabelmap(surfaceRepresentationData: SurfaceSegmentationData, segmentationVolume: Types.IImageVolume): Promise<{
|
|
4
|
-
volumeId: string;
|
|
5
|
-
}>;
|
|
6
|
-
export declare function convertSurfaceToStackLabelmap(): Promise<void>;
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import { Enums, cache, eventTarget, getWebWorkerManager, triggerEvent, } from '@cornerstonejs/core';
|
|
2
|
-
import { WorkerTypes } from '../../../../enums';
|
|
3
|
-
const workerManager = getWebWorkerManager();
|
|
4
|
-
const triggerWorkerProgress = (eventTarget, progress) => {
|
|
5
|
-
triggerEvent(eventTarget, Enums.Events.WEB_WORKER_PROGRESS, {
|
|
6
|
-
progress,
|
|
7
|
-
type: WorkerTypes.POLYSEG_SURFACE_TO_LABELMAP,
|
|
8
|
-
});
|
|
9
|
-
};
|
|
10
|
-
export async function convertSurfaceToVolumeLabelmap(surfaceRepresentationData, segmentationVolume) {
|
|
11
|
-
const { geometryIds } = surfaceRepresentationData;
|
|
12
|
-
if (!geometryIds?.size) {
|
|
13
|
-
throw new Error('No geometry IDs found for surface representation');
|
|
14
|
-
}
|
|
15
|
-
const segmentsInfo = new Map();
|
|
16
|
-
geometryIds.forEach((geometryId, segmentIndex) => {
|
|
17
|
-
const geometry = cache.getGeometry(geometryId);
|
|
18
|
-
const geometryData = geometry.data;
|
|
19
|
-
const points = geometryData.points;
|
|
20
|
-
const polys = geometryData.polys;
|
|
21
|
-
segmentsInfo.set(segmentIndex, {
|
|
22
|
-
points,
|
|
23
|
-
polys,
|
|
24
|
-
});
|
|
25
|
-
});
|
|
26
|
-
const { dimensions, direction, origin, spacing, voxelManager } = segmentationVolume;
|
|
27
|
-
triggerWorkerProgress(eventTarget, 0);
|
|
28
|
-
const newScalarData = await workerManager.executeTask('polySeg', 'convertSurfacesToVolumeLabelmap', {
|
|
29
|
-
segmentsInfo,
|
|
30
|
-
dimensions,
|
|
31
|
-
spacing,
|
|
32
|
-
direction,
|
|
33
|
-
origin,
|
|
34
|
-
}, {
|
|
35
|
-
callbacks: [
|
|
36
|
-
(progress) => {
|
|
37
|
-
triggerWorkerProgress(eventTarget, progress);
|
|
38
|
-
},
|
|
39
|
-
],
|
|
40
|
-
});
|
|
41
|
-
triggerWorkerProgress(eventTarget, 100);
|
|
42
|
-
voxelManager.setCompleteScalarDataArray(newScalarData);
|
|
43
|
-
segmentationVolume.modified();
|
|
44
|
-
return {
|
|
45
|
-
volumeId: segmentationVolume.volumeId,
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
export async function convertSurfaceToStackLabelmap() {
|
|
49
|
-
}
|
package/dist/esm/stateManagement/segmentation/polySeg/Labelmap/labelmapComputationStrategies.d.ts
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import type { LabelmapSegmentationDataStack, LabelmapSegmentationDataVolume } from '../../../../types/LabelmapTypes';
|
|
2
|
-
import type { PolySegConversionOptions } from '../../../../types';
|
|
3
|
-
export type RawLabelmapData = LabelmapSegmentationDataVolume | LabelmapSegmentationDataStack;
|
|
4
|
-
export declare function computeLabelmapData(segmentationId: string, options?: PolySegConversionOptions): Promise<RawLabelmapData>;
|
|
5
|
-
declare function computeLabelmapFromContourSegmentation(segmentationId: any, options?: PolySegConversionOptions): Promise<LabelmapSegmentationDataVolume | LabelmapSegmentationDataStack>;
|
|
6
|
-
export { computeLabelmapFromContourSegmentation };
|