@cornerstonejs/tools 2.8.6 → 2.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/dist/esm/eventDispatchers/shared/getToolsWithActionsForKeyboardEvents.js +1 -1
  2. package/dist/esm/eventDispatchers/shared/getToolsWithActionsForMouseEvent.js +1 -1
  3. package/dist/esm/index.d.ts +2 -2
  4. package/dist/esm/index.js +2 -2
  5. package/dist/esm/stateManagement/segmentation/activeSegmentation.d.ts +1 -1
  6. package/dist/esm/stateManagement/segmentation/activeSegmentation.js +1 -1
  7. package/dist/esm/stateManagement/segmentation/index.d.ts +3 -1
  8. package/dist/esm/stateManagement/segmentation/index.js +3 -1
  9. package/dist/esm/stateManagement/segmentation/internalAddSegmentationRepresentation.js +1 -0
  10. package/dist/esm/stateManagement/segmentation/polySeg/Contour/utils/createAndAddContourSegmentationsFromClippedSurfaces.js +1 -1
  11. package/dist/esm/stateManagement/segmentation/polySeg/Labelmap/labelmapComputationStrategies.js +4 -2
  12. package/dist/esm/tools/annotation/RegionSegmentPlusTool.d.ts +3 -2
  13. package/dist/esm/tools/annotation/RegionSegmentPlusTool.js +27 -12
  14. package/dist/esm/tools/annotation/RegionSegmentTool.d.ts +1 -1
  15. package/dist/esm/tools/annotation/RegionSegmentTool.js +7 -8
  16. package/dist/esm/tools/annotation/SplineROITool.js +7 -1
  17. package/dist/esm/tools/annotation/WholeBodySegmentTool.d.ts +3 -2
  18. package/dist/esm/tools/annotation/WholeBodySegmentTool.js +40 -5
  19. package/dist/esm/tools/base/AnnotationTool.d.ts +2 -1
  20. package/dist/esm/tools/base/AnnotationTool.js +6 -3
  21. package/dist/esm/tools/base/ContourSegmentationBaseTool.d.ts +1 -0
  22. package/dist/esm/tools/base/ContourSegmentationBaseTool.js +1 -0
  23. package/dist/esm/tools/base/GrowCutBaseTool.d.ts +25 -10
  24. package/dist/esm/tools/base/GrowCutBaseTool.js +124 -21
  25. package/dist/esm/tools/displayTools/Labelmap/addLabelmapToElement.d.ts +5 -1
  26. package/dist/esm/tools/displayTools/Labelmap/addLabelmapToElement.js +17 -3
  27. package/dist/esm/tools/displayTools/Labelmap/addVolumesAsIndependentComponents.d.ts +10 -0
  28. package/dist/esm/tools/displayTools/Labelmap/addVolumesAsIndependentComponents.js +123 -0
  29. package/dist/esm/tools/displayTools/Labelmap/labelmapDisplay.d.ts +1 -0
  30. package/dist/esm/tools/displayTools/Labelmap/labelmapDisplay.js +17 -10
  31. package/dist/esm/tools/index.d.ts +3 -1
  32. package/dist/esm/tools/index.js +3 -1
  33. package/dist/esm/tools/segmentation/BrushTool.d.ts +0 -1
  34. package/dist/esm/tools/segmentation/LabelmapBaseTool.d.ts +5 -1
  35. package/dist/esm/tools/segmentation/LabelmapBaseTool.js +107 -12
  36. package/dist/esm/tools/segmentation/SegmentSelectTool.js +0 -1
  37. package/dist/esm/tools/segmentation/strategies/compositions/index.js +1 -1
  38. package/dist/esm/tools/segmentation/strategies/compositions/islandRemovalComposition.d.ts +5 -0
  39. package/dist/esm/tools/segmentation/strategies/compositions/islandRemovalComposition.js +27 -0
  40. package/dist/esm/tools/segmentation/strategies/compositions/labelmapStatistics.js +69 -2
  41. package/dist/esm/types/CalculatorTypes.d.ts +4 -0
  42. package/dist/esm/types/SegmentationStateTypes.d.ts +3 -1
  43. package/dist/esm/utilities/contourSegmentation/addContourSegmentationAnnotation.js +5 -2
  44. package/dist/esm/utilities/index.d.ts +3 -1
  45. package/dist/esm/utilities/index.js +3 -1
  46. package/dist/esm/utilities/planar/filterAnnotationsWithinSlice.js +2 -2
  47. package/dist/esm/utilities/planar/getPointInLineOfSightWithCriteria.d.ts +5 -1
  48. package/dist/esm/utilities/planar/getPointInLineOfSightWithCriteria.js +40 -29
  49. package/dist/esm/utilities/planar/index.d.ts +3 -2
  50. package/dist/esm/utilities/planar/index.js +3 -2
  51. package/dist/esm/utilities/segmentation/VolumetricCalculator.d.ts +7 -0
  52. package/dist/esm/utilities/segmentation/VolumetricCalculator.js +28 -0
  53. package/dist/esm/utilities/segmentation/growCut/runGrowCutForBoundingBox.d.ts +0 -2
  54. package/dist/esm/utilities/segmentation/growCut/runOneClickGrowCut.d.ts +0 -4
  55. package/dist/esm/utilities/segmentation/index.d.ts +2 -1
  56. package/dist/esm/utilities/segmentation/index.js +2 -1
  57. package/dist/esm/utilities/segmentation/islandRemoval.d.ts +28 -0
  58. package/dist/esm/utilities/segmentation/islandRemoval.js +181 -0
  59. package/package.json +3 -3
  60. package/dist/esm/tools/segmentation/strategies/compositions/islandRemoval.d.ts +0 -16
  61. package/dist/esm/tools/segmentation/strategies/compositions/islandRemoval.js +0 -159
  62. /package/dist/esm/{tools/segmentation/strategies/utils → utilities}/normalizeViewportPlane.d.ts +0 -0
  63. /package/dist/esm/{tools/segmentation/strategies/utils → utilities}/normalizeViewportPlane.js +0 -0
@@ -0,0 +1,181 @@
1
+ import { utilities } from '@cornerstonejs/core';
2
+ import normalizeViewportPlane from '../normalizeViewportPlane';
3
+ const { RLEVoxelMap, VoxelManager } = utilities;
4
+ const MAX_IMAGE_SIZE = 65535;
5
+ export var SegmentationEnum;
6
+ (function (SegmentationEnum) {
7
+ SegmentationEnum[SegmentationEnum["SEGMENT"] = -1] = "SEGMENT";
8
+ SegmentationEnum[SegmentationEnum["ISLAND"] = -2] = "ISLAND";
9
+ SegmentationEnum[SegmentationEnum["INTERIOR"] = -3] = "INTERIOR";
10
+ SegmentationEnum[SegmentationEnum["EXTERIOR"] = -4] = "EXTERIOR";
11
+ SegmentationEnum[SegmentationEnum["INTERIOR_SMALL"] = -5] = "INTERIOR_SMALL";
12
+ SegmentationEnum[SegmentationEnum["INTERIOR_TEST"] = -6] = "INTERIOR_TEST";
13
+ })(SegmentationEnum || (SegmentationEnum = {}));
14
+ export default class IslandRemoval {
15
+ constructor(options) {
16
+ this.fillInternalEdge = false;
17
+ this.maxInternalRemove = 128;
18
+ this.maxInternalRemove =
19
+ options?.maxInternalRemove ?? this.maxInternalRemove;
20
+ this.fillInternalEdge = options?.fillInternalEdge ?? this.fillInternalEdge;
21
+ }
22
+ initialize(viewport, segmentationVoxels, options) {
23
+ const hasSource = !!segmentationVoxels.sourceVoxelManager;
24
+ const segmentationVoxelManager = hasSource
25
+ ? segmentationVoxels.sourceVoxelManager
26
+ : segmentationVoxels;
27
+ const previewVoxelManager = hasSource
28
+ ? segmentationVoxels
29
+ : VoxelManager.createRLEHistoryVoxelManager(segmentationVoxelManager);
30
+ const { segmentIndex = 1, previewSegmentIndex = 1 } = options;
31
+ const clickedPoints = options.points || previewVoxelManager.getPoints();
32
+ if (!clickedPoints?.length) {
33
+ return;
34
+ }
35
+ const boundsIJK = previewVoxelManager
36
+ .getBoundsIJK()
37
+ .map((bound, i) => [
38
+ Math.min(bound[0], ...clickedPoints.map((point) => point[i])),
39
+ Math.max(bound[1], ...clickedPoints.map((point) => point[i])),
40
+ ]);
41
+ if (boundsIJK.find((it) => it[0] < 0 || it[1] > MAX_IMAGE_SIZE)) {
42
+ return;
43
+ }
44
+ const { toIJK, fromIJK, boundsIJKPrime, error } = normalizeViewportPlane(viewport, boundsIJK);
45
+ if (error) {
46
+ console.warn('Not performing island removal for planes not orthogonal to acquisition plane', error);
47
+ return;
48
+ }
49
+ const [width, height, depth] = fromIJK(segmentationVoxelManager.dimensions);
50
+ const segmentSet = new RLEVoxelMap(width, height, depth);
51
+ const getter = (i, j, k) => {
52
+ const index = segmentationVoxelManager.toIndex(toIJK([i, j, k]));
53
+ const oldVal = segmentationVoxelManager.getAtIndex(index);
54
+ if (oldVal === previewSegmentIndex || oldVal === segmentIndex) {
55
+ return SegmentationEnum.SEGMENT;
56
+ }
57
+ };
58
+ segmentSet.fillFrom(getter, boundsIJKPrime);
59
+ segmentSet.normalizer = { toIJK, fromIJK, boundsIJKPrime };
60
+ this.segmentSet = segmentSet;
61
+ this.previewVoxelManager = previewVoxelManager;
62
+ this.segmentIndex = segmentIndex;
63
+ this.previewSegmentIndex = previewSegmentIndex ?? segmentIndex;
64
+ this.selectedPoints = clickedPoints;
65
+ return true;
66
+ }
67
+ floodFillSegmentIsland() {
68
+ const { selectedPoints: clickedPoints, segmentSet } = this;
69
+ let floodedCount = 0;
70
+ const { fromIJK } = segmentSet.normalizer;
71
+ clickedPoints.forEach((clickedPoint) => {
72
+ const ijkPrime = fromIJK(clickedPoint);
73
+ const index = segmentSet.toIndex(ijkPrime);
74
+ const [iPrime, jPrime, kPrime] = ijkPrime;
75
+ if (segmentSet.get(index) === SegmentationEnum.SEGMENT) {
76
+ floodedCount += segmentSet.floodFill(iPrime, jPrime, kPrime, SegmentationEnum.ISLAND);
77
+ }
78
+ });
79
+ return floodedCount;
80
+ }
81
+ removeExternalIslands() {
82
+ const { previewVoxelManager, segmentSet } = this;
83
+ const { toIJK } = segmentSet.normalizer;
84
+ const callback = (index, rle) => {
85
+ const [, jPrime, kPrime] = segmentSet.toIJK(index);
86
+ if (rle.value !== SegmentationEnum.ISLAND) {
87
+ for (let iPrime = rle.start; iPrime < rle.end; iPrime++) {
88
+ const clearPoint = toIJK([iPrime, jPrime, kPrime]);
89
+ const v = previewVoxelManager.getAtIJKPoint(clearPoint);
90
+ previewVoxelManager.setAtIJKPoint(clearPoint, v === undefined ? 0 : null);
91
+ }
92
+ }
93
+ };
94
+ segmentSet.forEach(callback, { rowModified: true });
95
+ }
96
+ removeInternalIslands() {
97
+ const { segmentSet, previewVoxelManager, previewSegmentIndex } = this;
98
+ const { height, normalizer, width } = segmentSet;
99
+ const { toIJK } = normalizer;
100
+ segmentSet.forEachRow((baseIndex, row) => {
101
+ let lastRle;
102
+ for (const rle of [...row]) {
103
+ if (rle.value !== SegmentationEnum.ISLAND) {
104
+ continue;
105
+ }
106
+ if (!lastRle) {
107
+ if (this.fillInternalEdge && rle.start > 0) {
108
+ for (let iPrime = 0; iPrime < rle.start; iPrime++) {
109
+ segmentSet.set(baseIndex + iPrime, SegmentationEnum.INTERIOR);
110
+ }
111
+ }
112
+ lastRle = rle;
113
+ continue;
114
+ }
115
+ for (let iPrime = lastRle.end; iPrime < rle.start; iPrime++) {
116
+ segmentSet.set(baseIndex + iPrime, SegmentationEnum.INTERIOR);
117
+ }
118
+ lastRle = rle;
119
+ }
120
+ if (this.fillInternalEdge && lastRle?.end < width) {
121
+ for (let iPrime = lastRle.end; iPrime < width; iPrime++) {
122
+ segmentSet.set(baseIndex + iPrime, SegmentationEnum.INTERIOR);
123
+ }
124
+ }
125
+ });
126
+ segmentSet.forEach((baseIndex, rle) => {
127
+ if (rle.value !== SegmentationEnum.INTERIOR) {
128
+ return;
129
+ }
130
+ const [, jPrime, kPrime] = segmentSet.toIJK(baseIndex);
131
+ const rowPrev = jPrime > 0 ? segmentSet.getRun(jPrime - 1, kPrime) : null;
132
+ const rowNext = jPrime + 1 < height ? segmentSet.getRun(jPrime + 1, kPrime) : null;
133
+ const isLast = jPrime === height - 1;
134
+ const isFirst = jPrime === 0;
135
+ const prevCovers = IslandRemoval.covers(rle, rowPrev) ||
136
+ (isFirst && this.fillInternalEdge);
137
+ const nextCovers = IslandRemoval.covers(rle, rowNext) || (isLast && this.fillInternalEdge);
138
+ if (rle.end - rle.start > 2 && (!prevCovers || !nextCovers)) {
139
+ segmentSet.floodFill(rle.start, jPrime, kPrime, SegmentationEnum.EXTERIOR, { singlePlane: true });
140
+ }
141
+ });
142
+ segmentSet.forEach((baseIndex, rle) => {
143
+ if (rle.value !== SegmentationEnum.INTERIOR) {
144
+ return;
145
+ }
146
+ const [, jPrime, kPrime] = segmentSet.toIJK(baseIndex);
147
+ const size = segmentSet.floodFill(rle.start, jPrime, kPrime, SegmentationEnum.INTERIOR_TEST);
148
+ const isBig = size > this.maxInternalRemove;
149
+ const newType = isBig
150
+ ? SegmentationEnum.EXTERIOR
151
+ : SegmentationEnum.INTERIOR_SMALL;
152
+ segmentSet.floodFill(rle.start, jPrime, kPrime, newType);
153
+ });
154
+ segmentSet.forEach((baseIndex, rle) => {
155
+ if (rle.value !== SegmentationEnum.INTERIOR_SMALL) {
156
+ return;
157
+ }
158
+ for (let iPrime = rle.start; iPrime < rle.end; iPrime++) {
159
+ const clearPoint = toIJK(segmentSet.toIJK(baseIndex + iPrime));
160
+ previewVoxelManager.setAtIJKPoint(clearPoint, previewSegmentIndex);
161
+ }
162
+ });
163
+ return previewVoxelManager.getArrayOfModifiedSlices();
164
+ }
165
+ static covers(rle, row) {
166
+ if (!row) {
167
+ return false;
168
+ }
169
+ let { start } = rle;
170
+ const { end } = rle;
171
+ for (const rowRle of row) {
172
+ if (start >= rowRle.start && start < rowRle.end) {
173
+ start = rowRle.end;
174
+ if (start >= end) {
175
+ return true;
176
+ }
177
+ }
178
+ }
179
+ return false;
180
+ }
181
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cornerstonejs/tools",
3
- "version": "2.8.6",
3
+ "version": "2.10.0",
4
4
  "description": "Cornerstone3D Tools",
5
5
  "types": "./dist/esm/index.d.ts",
6
6
  "module": "./dist/esm/index.js",
@@ -104,7 +104,7 @@
104
104
  "canvas": "^2.11.2"
105
105
  },
106
106
  "peerDependencies": {
107
- "@cornerstonejs/core": "^2.8.6",
107
+ "@cornerstonejs/core": "^2.10.0",
108
108
  "@kitware/vtk.js": "32.1.1",
109
109
  "@types/d3-array": "^3.0.4",
110
110
  "@types/d3-interpolate": "^3.0.1",
@@ -123,5 +123,5 @@
123
123
  "type": "individual",
124
124
  "url": "https://ohif.org/donate"
125
125
  },
126
- "gitHead": "f2c65f17bdd9d55f34c384e2665b1414257f22c9"
126
+ "gitHead": "aab86e3f13a86bcd2d975a4cfbdf7eee7fa1627a"
127
127
  }
@@ -1,16 +0,0 @@
1
- import { utilities } from '@cornerstonejs/core';
2
- import type { InitializedOperationData } from '../BrushStrategy';
3
- export declare enum SegmentationEnum {
4
- SEGMENT = 1,
5
- ISLAND = 2,
6
- INTERIOR = 3,
7
- EXTERIOR = 4,
8
- INTERIOR_SMALL = -5,
9
- INTERIOR_TEST = -6
10
- }
11
- declare const _default: {
12
- onInteractionEnd: (operationData: InitializedOperationData) => void;
13
- };
14
- export default _default;
15
- export declare function createSegmentSet(operationData: InitializedOperationData): utilities.RLEVoxelMap<SegmentationEnum>;
16
- export declare function covers(rle: any, row: any): boolean;
@@ -1,159 +0,0 @@
1
- import { utilities } from '@cornerstonejs/core';
2
- import { triggerSegmentationDataModified } from '../../../../stateManagement/segmentation/triggerSegmentationEvents';
3
- import StrategyCallbacks from '../../../../enums/StrategyCallbacks';
4
- import normalizeViewportPlane from '../utils/normalizeViewportPlane';
5
- const { RLEVoxelMap } = utilities;
6
- const MAX_IMAGE_SIZE = 65535;
7
- export var SegmentationEnum;
8
- (function (SegmentationEnum) {
9
- SegmentationEnum[SegmentationEnum["SEGMENT"] = 1] = "SEGMENT";
10
- SegmentationEnum[SegmentationEnum["ISLAND"] = 2] = "ISLAND";
11
- SegmentationEnum[SegmentationEnum["INTERIOR"] = 3] = "INTERIOR";
12
- SegmentationEnum[SegmentationEnum["EXTERIOR"] = 4] = "EXTERIOR";
13
- SegmentationEnum[SegmentationEnum["INTERIOR_SMALL"] = -5] = "INTERIOR_SMALL";
14
- SegmentationEnum[SegmentationEnum["INTERIOR_TEST"] = -6] = "INTERIOR_TEST";
15
- })(SegmentationEnum || (SegmentationEnum = {}));
16
- export default {
17
- [StrategyCallbacks.OnInteractionEnd]: (operationData) => {
18
- const { strategySpecificConfiguration, previewSegmentIndex, segmentIndex } = operationData;
19
- if (!strategySpecificConfiguration.THRESHOLD ||
20
- segmentIndex === null ||
21
- previewSegmentIndex === undefined) {
22
- return;
23
- }
24
- const segmentSet = createSegmentSet(operationData);
25
- if (!segmentSet) {
26
- return;
27
- }
28
- const externalRemoved = removeExternalIslands(operationData, segmentSet);
29
- if (externalRemoved === undefined) {
30
- return;
31
- }
32
- const arrayOfSlices = removeInternalIslands(operationData, segmentSet);
33
- if (!arrayOfSlices) {
34
- return;
35
- }
36
- triggerSegmentationDataModified(operationData.segmentationId, arrayOfSlices, previewSegmentIndex);
37
- },
38
- };
39
- export function createSegmentSet(operationData) {
40
- const { segmentationVoxelManager, previewSegmentIndex, previewVoxelManager, segmentIndex, viewport, } = operationData;
41
- const clickedPoints = previewVoxelManager.getPoints();
42
- if (!clickedPoints?.length) {
43
- return;
44
- }
45
- const boundsIJK = previewVoxelManager
46
- .getBoundsIJK()
47
- .map((bound, i) => [
48
- Math.min(bound[0], ...clickedPoints.map((point) => point[i])),
49
- Math.max(bound[1], ...clickedPoints.map((point) => point[i])),
50
- ]);
51
- if (boundsIJK.find((it) => it[0] < 0 || it[1] > MAX_IMAGE_SIZE)) {
52
- return;
53
- }
54
- const { toIJK, fromIJK, boundsIJKPrime, error } = normalizeViewportPlane(viewport, boundsIJK);
55
- if (error) {
56
- console.warn('Not performing island removal for planes not orthogonal to acquisition plane', error);
57
- return;
58
- }
59
- const [width, height, depth] = fromIJK(segmentationVoxelManager.dimensions);
60
- const floodedSet = new RLEVoxelMap(width, height, depth);
61
- const getter = (i, j, k) => {
62
- const index = segmentationVoxelManager.toIndex(toIJK([i, j, k]));
63
- const oldVal = segmentationVoxelManager.getAtIndex(index);
64
- if (oldVal === previewSegmentIndex || oldVal === segmentIndex) {
65
- return SegmentationEnum.SEGMENT;
66
- }
67
- };
68
- floodedSet.fillFrom(getter, boundsIJKPrime);
69
- floodedSet.normalizer = { toIJK, fromIJK, boundsIJKPrime };
70
- return floodedSet;
71
- }
72
- function removeInternalIslands(operationData, floodedSet) {
73
- const { height, normalizer } = floodedSet;
74
- const { toIJK } = normalizer;
75
- const { previewVoxelManager, previewSegmentIndex } = operationData;
76
- floodedSet.forEachRow((baseIndex, row) => {
77
- let lastRle;
78
- for (const rle of [...row]) {
79
- if (rle.value !== SegmentationEnum.ISLAND) {
80
- continue;
81
- }
82
- if (!lastRle) {
83
- lastRle = rle;
84
- continue;
85
- }
86
- for (let iPrime = lastRle.end; iPrime < rle.start; iPrime++) {
87
- floodedSet.set(baseIndex + iPrime, SegmentationEnum.INTERIOR);
88
- }
89
- lastRle = rle;
90
- }
91
- });
92
- floodedSet.forEach((baseIndex, rle) => {
93
- if (rle.value !== SegmentationEnum.INTERIOR) {
94
- return;
95
- }
96
- const [, jPrime, kPrime] = floodedSet.toIJK(baseIndex);
97
- const rowPrev = jPrime > 0 ? floodedSet.getRun(jPrime - 1, kPrime) : null;
98
- const rowNext = jPrime + 1 < height ? floodedSet.getRun(jPrime + 1, kPrime) : null;
99
- const prevCovers = covers(rle, rowPrev);
100
- const nextCovers = covers(rle, rowNext);
101
- if (rle.end - rle.start > 2 && (!prevCovers || !nextCovers)) {
102
- floodedSet.floodFill(rle.start, jPrime, kPrime, SegmentationEnum.EXTERIOR, { singlePlane: true });
103
- }
104
- });
105
- floodedSet.forEach((baseIndex, rle) => {
106
- if (rle.value !== SegmentationEnum.INTERIOR) {
107
- return;
108
- }
109
- for (let iPrime = rle.start; iPrime < rle.end; iPrime++) {
110
- const clearPoint = toIJK(floodedSet.toIJK(baseIndex + iPrime));
111
- previewVoxelManager.setAtIJKPoint(clearPoint, previewSegmentIndex);
112
- }
113
- });
114
- return previewVoxelManager.getArrayOfModifiedSlices();
115
- }
116
- function removeExternalIslands(operationData, floodedSet) {
117
- const { previewVoxelManager } = operationData;
118
- const { toIJK, fromIJK } = floodedSet.normalizer;
119
- const clickedPoints = previewVoxelManager.getPoints();
120
- let floodedCount = 0;
121
- clickedPoints.forEach((clickedPoint) => {
122
- const ijkPrime = fromIJK(clickedPoint);
123
- const index = floodedSet.toIndex(ijkPrime);
124
- const [iPrime, jPrime, kPrime] = ijkPrime;
125
- if (floodedSet.get(index) === SegmentationEnum.SEGMENT) {
126
- floodedCount += floodedSet.floodFill(iPrime, jPrime, kPrime, SegmentationEnum.ISLAND);
127
- }
128
- });
129
- if (floodedCount === 0) {
130
- return;
131
- }
132
- const callback = (index, rle) => {
133
- const [, jPrime, kPrime] = floodedSet.toIJK(index);
134
- if (rle.value !== SegmentationEnum.ISLAND) {
135
- for (let iPrime = rle.start; iPrime < rle.end; iPrime++) {
136
- const clearPoint = toIJK([iPrime, jPrime, kPrime]);
137
- previewVoxelManager.setAtIJKPoint(clearPoint, null);
138
- }
139
- }
140
- };
141
- floodedSet.forEach(callback, { rowModified: true });
142
- return floodedCount;
143
- }
144
- export function covers(rle, row) {
145
- if (!row) {
146
- return false;
147
- }
148
- let { start } = rle;
149
- const { end } = rle;
150
- for (const rowRle of row) {
151
- if (start >= rowRle.start && start < rowRle.end) {
152
- start = rowRle.end;
153
- if (start >= end) {
154
- return true;
155
- }
156
- }
157
- }
158
- return false;
159
- }