@cornerstonejs/polymorphic-segmentation 3.0.0-beta.3 → 3.0.0-beta.4
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/Contour/contourComputationStrategies.d.ts +8 -0
- package/dist/esm/Contour/contourComputationStrategies.js +104 -0
- package/dist/esm/Contour/utils/createAndAddContourSegmentationsFromClippedSurfaces.d.ts +3 -0
- package/dist/esm/Contour/utils/createAndAddContourSegmentationsFromClippedSurfaces.js +71 -0
- package/dist/esm/Contour/utils/extractContourData.d.ts +3 -0
- package/dist/esm/Contour/utils/extractContourData.js +16 -0
- package/dist/esm/Contour/utils/updateContoursOnCameraModified.d.ts +1 -0
- package/dist/esm/Contour/utils/updateContoursOnCameraModified.js +25 -0
- package/dist/esm/Labelmap/convertContourToLabelmap.d.ts +8 -0
- package/dist/esm/Labelmap/convertContourToLabelmap.js +144 -0
- package/dist/esm/Labelmap/convertSurfaceToLabelmap.d.ts +6 -0
- package/dist/esm/Labelmap/convertSurfaceToLabelmap.js +50 -0
- package/dist/esm/Labelmap/labelmapComputationStrategies.d.ts +6 -0
- package/dist/esm/Labelmap/labelmapComputationStrategies.js +97 -0
- package/dist/esm/Surface/convertContourToSurface.d.ts +3 -0
- package/dist/esm/Surface/convertContourToSurface.js +37 -0
- package/dist/esm/Surface/convertLabelmapToSurface.d.ts +3 -0
- package/dist/esm/Surface/convertLabelmapToSurface.js +45 -0
- package/dist/esm/Surface/createAndCacheSurfacesFromRaw.d.ts +5 -0
- package/dist/esm/Surface/createAndCacheSurfacesFromRaw.js +34 -0
- package/dist/esm/Surface/surfaceComputationStrategies.d.ts +12 -0
- package/dist/esm/Surface/surfaceComputationStrategies.js +76 -0
- package/dist/esm/Surface/updateSurfaceData.d.ts +1 -0
- package/dist/esm/Surface/updateSurfaceData.js +55 -0
- package/dist/esm/canComputeRequestedRepresentation.d.ts +4 -0
- package/dist/esm/canComputeRequestedRepresentation.js +59 -0
- package/dist/esm/index.d.ts +7 -0
- package/dist/esm/index.js +10 -0
- package/dist/esm/registerPolySegWorker.d.ts +1 -0
- package/dist/esm/registerPolySegWorker.js +23 -0
- package/dist/esm/types/PolySegConversionOptions.d.ts +6 -0
- package/dist/esm/types/PolySegConversionOptions.js +0 -0
- package/dist/esm/types/index.d.ts +2 -0
- package/dist/esm/types/index.js +0 -0
- package/dist/esm/utilities/clipAndCacheSurfacesForViewport.d.ts +16 -0
- package/dist/esm/utilities/clipAndCacheSurfacesForViewport.js +88 -0
- package/dist/esm/utilities/index.d.ts +2 -0
- package/dist/esm/utilities/index.js +2 -0
- package/dist/esm/workers/polySegConverters.d.ts +1 -0
- package/dist/esm/workers/polySegConverters.js +391 -0
- package/package.json +9 -6
|
@@ -0,0 +1,391 @@
|
|
|
1
|
+
import { expose } from 'comlink';
|
|
2
|
+
import { utilities } from '@cornerstonejs/core';
|
|
3
|
+
import { utilities as ToolsUtilities } from '@cornerstonejs/tools';
|
|
4
|
+
import vtkImageData from '@kitware/vtk.js/Common/DataModel/ImageData';
|
|
5
|
+
import vtkDataArray from '@kitware/vtk.js/Common/Core/DataArray';
|
|
6
|
+
import vtkPlane from '@kitware/vtk.js/Common/DataModel/Plane';
|
|
7
|
+
import vtkPolyData from '@kitware/vtk.js/Common/DataModel/PolyData';
|
|
8
|
+
import vtkContourLoopExtraction from '@kitware/vtk.js/Filters/General/ContourLoopExtraction';
|
|
9
|
+
import vtkCutter from '@kitware/vtk.js/Filters/Core/Cutter';
|
|
10
|
+
const { math: { polyline: { containsPoint, getAABB, projectTo2D }, }, geometricSurfaceUtils: { checkStandardBasis, rotatePoints }, boundingBox: { getBoundingBoxAroundShapeWorld }, planar: { isPlaneIntersectingAABB }, } = ToolsUtilities;
|
|
11
|
+
async function peerImport(moduleId) {
|
|
12
|
+
try {
|
|
13
|
+
if (moduleId === '@icr/polyseg-wasm') {
|
|
14
|
+
return import('@icr/polyseg-wasm');
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
catch (error) {
|
|
18
|
+
console.warn('Error importing module:', error);
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
const polySegConverters = {
|
|
23
|
+
polySeg: null,
|
|
24
|
+
polySegInitializing: false,
|
|
25
|
+
polySegInitializingPromise: null,
|
|
26
|
+
async initializePolySeg(progressCallback) {
|
|
27
|
+
let ICRPolySeg;
|
|
28
|
+
try {
|
|
29
|
+
ICRPolySeg = (await peerImport('@icr/polyseg-wasm')).default;
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
console.error(error);
|
|
33
|
+
console.debug("Warning: '@icr/polyseg-wasm' module not found. Please install it separately.");
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
if (this.polySegInitializing) {
|
|
37
|
+
await this.polySegInitializingPromise;
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
if (this.polySeg?.instance) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
this.polySegInitializing = true;
|
|
44
|
+
this.polySegInitializingPromise = new Promise((resolve) => {
|
|
45
|
+
this.polySeg = new ICRPolySeg();
|
|
46
|
+
this.polySeg
|
|
47
|
+
.initialize({
|
|
48
|
+
updateProgress: progressCallback,
|
|
49
|
+
})
|
|
50
|
+
.then(() => {
|
|
51
|
+
this.polySegInitializing = false;
|
|
52
|
+
resolve();
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
await this.polySegInitializingPromise;
|
|
56
|
+
},
|
|
57
|
+
async convertContourToSurface(args, ...callbacks) {
|
|
58
|
+
const { polylines, numPointsArray } = args;
|
|
59
|
+
const [progressCallback] = callbacks;
|
|
60
|
+
await this.initializePolySeg(progressCallback);
|
|
61
|
+
const results = await this.polySeg.instance.convertContourRoiToSurface(polylines, numPointsArray);
|
|
62
|
+
return results;
|
|
63
|
+
},
|
|
64
|
+
async convertLabelmapToSurface(args, ...callbacks) {
|
|
65
|
+
const [progressCallback] = callbacks;
|
|
66
|
+
await this.initializePolySeg(progressCallback);
|
|
67
|
+
const results = this.polySeg.instance.convertLabelmapToSurface(args.scalarData, args.dimensions, args.spacing, args.direction, args.origin, [args.segmentIndex]);
|
|
68
|
+
const rotationInfo = checkStandardBasis(args.direction);
|
|
69
|
+
if (!rotationInfo.isStandard) {
|
|
70
|
+
const rotatedPoints = rotatePoints(rotationInfo.rotationMatrix, args.origin, results.points);
|
|
71
|
+
results.points = [...rotatedPoints];
|
|
72
|
+
}
|
|
73
|
+
return results;
|
|
74
|
+
},
|
|
75
|
+
async convertContourToVolumeLabelmap(args, ...callbacks) {
|
|
76
|
+
const [progressCallback] = callbacks;
|
|
77
|
+
await this.initializePolySeg(progressCallback);
|
|
78
|
+
const { segmentIndices, scalarData, annotationUIDsInSegmentMap, dimensions, origin, direction, spacing, } = args;
|
|
79
|
+
const segmentationVoxelManager = utilities.VoxelManager.createScalarVolumeVoxelManager({
|
|
80
|
+
dimensions,
|
|
81
|
+
scalarData,
|
|
82
|
+
});
|
|
83
|
+
const imageData = vtkImageData.newInstance();
|
|
84
|
+
imageData.setDimensions(dimensions);
|
|
85
|
+
imageData.setOrigin(origin);
|
|
86
|
+
imageData.setDirection(direction);
|
|
87
|
+
imageData.setSpacing(spacing);
|
|
88
|
+
const scalarArray = vtkDataArray.newInstance({
|
|
89
|
+
name: 'Pixels',
|
|
90
|
+
numberOfComponents: 1,
|
|
91
|
+
values: scalarData,
|
|
92
|
+
});
|
|
93
|
+
imageData.getPointData().setScalars(scalarArray);
|
|
94
|
+
imageData.modified();
|
|
95
|
+
for (const index of segmentIndices) {
|
|
96
|
+
const annotations = annotationUIDsInSegmentMap.get(index);
|
|
97
|
+
for (const annotation of annotations) {
|
|
98
|
+
if (!annotation.polyline) {
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
const { polyline, holesPolyline } = annotation;
|
|
102
|
+
const bounds = getBoundingBoxAroundShapeWorld(polyline);
|
|
103
|
+
const [iMin, jMin, kMin] = utilities.transformWorldToIndex(imageData, [
|
|
104
|
+
bounds[0][0],
|
|
105
|
+
bounds[1][0],
|
|
106
|
+
bounds[2][0],
|
|
107
|
+
]);
|
|
108
|
+
const [iMax, jMax, kMax] = utilities.transformWorldToIndex(imageData, [
|
|
109
|
+
bounds[0][1],
|
|
110
|
+
bounds[1][1],
|
|
111
|
+
bounds[2][1],
|
|
112
|
+
]);
|
|
113
|
+
const { projectedPolyline, sharedDimensionIndex } = projectTo2D(polyline);
|
|
114
|
+
const holes = holesPolyline?.map((hole) => {
|
|
115
|
+
const { projectedPolyline: projectedHole } = projectTo2D(hole);
|
|
116
|
+
return projectedHole;
|
|
117
|
+
});
|
|
118
|
+
const firstDim = (sharedDimensionIndex + 1) % 3;
|
|
119
|
+
const secondDim = (sharedDimensionIndex + 2) % 3;
|
|
120
|
+
const voxels = utilities.VoxelManager.createScalarVolumeVoxelManager({
|
|
121
|
+
dimensions,
|
|
122
|
+
scalarData,
|
|
123
|
+
});
|
|
124
|
+
voxels.forEach(({ pointIJK }) => {
|
|
125
|
+
segmentationVoxelManager.setAtIJKPoint(pointIJK, index);
|
|
126
|
+
}, {
|
|
127
|
+
imageData,
|
|
128
|
+
isInObject: (pointLPS) => {
|
|
129
|
+
const point2D = [pointLPS[firstDim], pointLPS[secondDim]];
|
|
130
|
+
const isInside = containsPoint(projectedPolyline, point2D, {
|
|
131
|
+
holes,
|
|
132
|
+
});
|
|
133
|
+
return isInside;
|
|
134
|
+
},
|
|
135
|
+
boundsIJK: [
|
|
136
|
+
[iMin, iMax],
|
|
137
|
+
[jMin, jMax],
|
|
138
|
+
[kMin, kMax],
|
|
139
|
+
],
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return segmentationVoxelManager.scalarData;
|
|
144
|
+
},
|
|
145
|
+
async convertContourToStackLabelmap(args, ...callbacks) {
|
|
146
|
+
const [progressCallback] = callbacks;
|
|
147
|
+
await this.initializePolySeg(progressCallback);
|
|
148
|
+
const { segmentationsInfo, annotationUIDsInSegmentMap, segmentIndices } = args;
|
|
149
|
+
const segmentationVoxelManagers = new Map();
|
|
150
|
+
segmentationsInfo.forEach((segmentationInfo, referencedImageId) => {
|
|
151
|
+
const { dimensions, scalarData, direction, spacing, origin } = segmentationInfo;
|
|
152
|
+
const manager = utilities.VoxelManager.createScalarVolumeVoxelManager({
|
|
153
|
+
dimensions,
|
|
154
|
+
scalarData,
|
|
155
|
+
});
|
|
156
|
+
const imageData = vtkImageData.newInstance();
|
|
157
|
+
imageData.setDimensions(dimensions);
|
|
158
|
+
imageData.setOrigin(origin);
|
|
159
|
+
imageData.setDirection(direction);
|
|
160
|
+
imageData.setSpacing(spacing);
|
|
161
|
+
const scalarArray = vtkDataArray.newInstance({
|
|
162
|
+
name: 'Pixels',
|
|
163
|
+
numberOfComponents: 1,
|
|
164
|
+
values: scalarData,
|
|
165
|
+
});
|
|
166
|
+
imageData.getPointData().setScalars(scalarArray);
|
|
167
|
+
imageData.modified();
|
|
168
|
+
segmentationVoxelManagers.set(referencedImageId, { manager, imageData });
|
|
169
|
+
});
|
|
170
|
+
for (const index of segmentIndices) {
|
|
171
|
+
const annotations = annotationUIDsInSegmentMap.get(index);
|
|
172
|
+
for (const annotation of annotations) {
|
|
173
|
+
if (!annotation.polyline) {
|
|
174
|
+
continue;
|
|
175
|
+
}
|
|
176
|
+
const { polyline, holesPolyline, referencedImageId } = annotation;
|
|
177
|
+
const bounds = getBoundingBoxAroundShapeWorld(polyline);
|
|
178
|
+
const { manager: segmentationVoxelManager, imageData } = segmentationVoxelManagers.get(referencedImageId);
|
|
179
|
+
const [iMin, jMin, kMin] = utilities.transformWorldToIndex(imageData, [
|
|
180
|
+
bounds[0][0],
|
|
181
|
+
bounds[1][0],
|
|
182
|
+
bounds[2][0],
|
|
183
|
+
]);
|
|
184
|
+
const [iMax, jMax, kMax] = utilities.transformWorldToIndex(imageData, [
|
|
185
|
+
bounds[0][1],
|
|
186
|
+
bounds[1][1],
|
|
187
|
+
bounds[2][1],
|
|
188
|
+
]);
|
|
189
|
+
const { projectedPolyline, sharedDimensionIndex } = projectTo2D(polyline);
|
|
190
|
+
const holes = holesPolyline?.map((hole) => {
|
|
191
|
+
const { projectedPolyline: projectedHole } = projectTo2D(hole);
|
|
192
|
+
return projectedHole;
|
|
193
|
+
});
|
|
194
|
+
const firstDim = (sharedDimensionIndex + 1) % 3;
|
|
195
|
+
const secondDim = (sharedDimensionIndex + 2) % 3;
|
|
196
|
+
const voxels = utilities.VoxelManager.createImageVoxelManager({
|
|
197
|
+
width: imageData.getDimensions()[0],
|
|
198
|
+
height: imageData.getDimensions()[1],
|
|
199
|
+
scalarData: imageData.getPointData().getScalars().getData(),
|
|
200
|
+
});
|
|
201
|
+
voxels.forEach(({ pointIJK }) => {
|
|
202
|
+
segmentationVoxelManager.setAtIJKPoint(pointIJK, index);
|
|
203
|
+
}, {
|
|
204
|
+
imageData,
|
|
205
|
+
isInObject: (pointLPS) => {
|
|
206
|
+
const point2D = [pointLPS[firstDim], pointLPS[secondDim]];
|
|
207
|
+
const isInside = containsPoint(projectedPolyline, point2D, {
|
|
208
|
+
holes,
|
|
209
|
+
});
|
|
210
|
+
return isInside;
|
|
211
|
+
},
|
|
212
|
+
boundsIJK: [
|
|
213
|
+
[iMin, iMax],
|
|
214
|
+
[jMin, jMax],
|
|
215
|
+
[kMin, kMax],
|
|
216
|
+
],
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
segmentationsInfo.forEach((segmentationInfo, referencedImageId) => {
|
|
221
|
+
const { manager: segmentationVoxelManager } = segmentationVoxelManagers.get(referencedImageId);
|
|
222
|
+
segmentationInfo.scalarData = segmentationVoxelManager.scalarData;
|
|
223
|
+
});
|
|
224
|
+
return segmentationsInfo;
|
|
225
|
+
},
|
|
226
|
+
async convertSurfaceToVolumeLabelmap(args, ...callbacks) {
|
|
227
|
+
const [progressCallback] = callbacks;
|
|
228
|
+
await this.initializePolySeg(progressCallback);
|
|
229
|
+
const results = this.polySeg.instance.convertSurfaceToLabelmap(args.points, args.polys, args.dimensions, args.spacing, args.direction, args.origin);
|
|
230
|
+
return results;
|
|
231
|
+
},
|
|
232
|
+
async convertSurfacesToVolumeLabelmap(args, ...callbacks) {
|
|
233
|
+
const [progressCallback] = callbacks;
|
|
234
|
+
await this.initializePolySeg(progressCallback);
|
|
235
|
+
const { segmentsInfo } = args;
|
|
236
|
+
const promises = Array.from(segmentsInfo.keys()).map((segmentIndex) => {
|
|
237
|
+
const { points, polys } = segmentsInfo.get(segmentIndex);
|
|
238
|
+
const result = this.polySeg.instance.convertSurfaceToLabelmap(points, polys, args.dimensions, args.spacing, args.direction, args.origin);
|
|
239
|
+
return {
|
|
240
|
+
...result,
|
|
241
|
+
segmentIndex,
|
|
242
|
+
};
|
|
243
|
+
});
|
|
244
|
+
const results = await Promise.all(promises);
|
|
245
|
+
const targetImageData = vtkImageData.newInstance();
|
|
246
|
+
targetImageData.setDimensions(args.dimensions);
|
|
247
|
+
targetImageData.setOrigin(args.origin);
|
|
248
|
+
targetImageData.setSpacing(args.spacing);
|
|
249
|
+
targetImageData.setDirection(args.direction);
|
|
250
|
+
const totalSize = args.dimensions[0] * args.dimensions[1] * args.dimensions[2];
|
|
251
|
+
const scalarArray = vtkDataArray.newInstance({
|
|
252
|
+
name: 'Pixels',
|
|
253
|
+
numberOfComponents: 1,
|
|
254
|
+
values: new Uint8Array(totalSize),
|
|
255
|
+
});
|
|
256
|
+
targetImageData.getPointData().setScalars(scalarArray);
|
|
257
|
+
targetImageData.modified();
|
|
258
|
+
const { dimensions } = args;
|
|
259
|
+
const scalarData = targetImageData.getPointData().getScalars().getData();
|
|
260
|
+
const segmentationVoxelManager = utilities.VoxelManager.createScalarVolumeVoxelManager({
|
|
261
|
+
dimensions,
|
|
262
|
+
scalarData,
|
|
263
|
+
});
|
|
264
|
+
const outputVolumesInfo = results.map((result) => {
|
|
265
|
+
const { data, dimensions, direction, origin, spacing } = result;
|
|
266
|
+
const volume = vtkImageData.newInstance();
|
|
267
|
+
volume.setDimensions(dimensions);
|
|
268
|
+
volume.setOrigin(origin);
|
|
269
|
+
volume.setSpacing(spacing);
|
|
270
|
+
volume.setDirection(direction);
|
|
271
|
+
const scalarArray = vtkDataArray.newInstance({
|
|
272
|
+
name: 'Pixels',
|
|
273
|
+
numberOfComponents: 1,
|
|
274
|
+
values: data,
|
|
275
|
+
});
|
|
276
|
+
volume.getPointData().setScalars(scalarArray);
|
|
277
|
+
volume.modified();
|
|
278
|
+
const voxelManager = utilities.VoxelManager.createScalarVolumeVoxelManager({
|
|
279
|
+
dimensions,
|
|
280
|
+
scalarData: data,
|
|
281
|
+
});
|
|
282
|
+
const extent = volume.getExtent();
|
|
283
|
+
return {
|
|
284
|
+
volume,
|
|
285
|
+
voxelManager,
|
|
286
|
+
extent,
|
|
287
|
+
scalarData: data,
|
|
288
|
+
segmentIndex: result.segmentIndex,
|
|
289
|
+
};
|
|
290
|
+
});
|
|
291
|
+
const voxels = utilities.VoxelManager.createScalarVolumeVoxelManager({
|
|
292
|
+
dimensions: targetImageData.getDimensions(),
|
|
293
|
+
scalarData: targetImageData.getPointData().getScalars().getData(),
|
|
294
|
+
});
|
|
295
|
+
voxels.forEach(({ pointIJK, pointLPS }) => {
|
|
296
|
+
try {
|
|
297
|
+
for (const volumeInfo of outputVolumesInfo) {
|
|
298
|
+
const { volume, extent, voxelManager, segmentIndex } = volumeInfo;
|
|
299
|
+
const index = volume.worldToIndex(pointLPS);
|
|
300
|
+
if (index[0] < extent[0] ||
|
|
301
|
+
index[0] > extent[1] ||
|
|
302
|
+
index[1] < extent[2] ||
|
|
303
|
+
index[1] > extent[3] ||
|
|
304
|
+
index[2] < extent[4] ||
|
|
305
|
+
index[2] > extent[5]) {
|
|
306
|
+
continue;
|
|
307
|
+
}
|
|
308
|
+
const roundedIndex = index.map(Math.round);
|
|
309
|
+
const value = voxelManager.getAtIJK(...roundedIndex);
|
|
310
|
+
if (value > 0) {
|
|
311
|
+
segmentationVoxelManager.setAtIJKPoint(pointIJK, segmentIndex);
|
|
312
|
+
break;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
catch (error) {
|
|
317
|
+
}
|
|
318
|
+
}, { imageData: targetImageData });
|
|
319
|
+
return segmentationVoxelManager.scalarData;
|
|
320
|
+
},
|
|
321
|
+
getSurfacesAABBs({ surfacesInfo }) {
|
|
322
|
+
const aabbs = new Map();
|
|
323
|
+
for (const { points, id } of surfacesInfo) {
|
|
324
|
+
const aabb = getAABB(points, { numDimensions: 3 });
|
|
325
|
+
aabbs.set(id, aabb);
|
|
326
|
+
}
|
|
327
|
+
return aabbs;
|
|
328
|
+
},
|
|
329
|
+
cutSurfacesIntoPlanes({ planesInfo, surfacesInfo, surfacesAABB = new Map() }, progressCallback, updateCacheCallback) {
|
|
330
|
+
const numberOfPlanes = planesInfo.length;
|
|
331
|
+
const cutter = vtkCutter.newInstance();
|
|
332
|
+
const plane1 = vtkPlane.newInstance();
|
|
333
|
+
cutter.setCutFunction(plane1);
|
|
334
|
+
const surfacePolyData = vtkPolyData.newInstance();
|
|
335
|
+
try {
|
|
336
|
+
for (const [index, planeInfo] of planesInfo.entries()) {
|
|
337
|
+
const { sliceIndex, planes } = planeInfo;
|
|
338
|
+
const polyDataResults = new Map();
|
|
339
|
+
for (const polyDataInfo of surfacesInfo) {
|
|
340
|
+
const { points, polys, id, segmentIndex } = polyDataInfo;
|
|
341
|
+
const aabb3 = surfacesAABB.get(id) || getAABB(points, { numDimensions: 3 });
|
|
342
|
+
if (!surfacesAABB.has(id)) {
|
|
343
|
+
surfacesAABB.set(id, aabb3);
|
|
344
|
+
}
|
|
345
|
+
const { minX, minY, minZ, maxX, maxY, maxZ } = aabb3;
|
|
346
|
+
const { origin, normal } = planes[0];
|
|
347
|
+
if (!isPlaneIntersectingAABB(origin, normal, minX, minY, minZ, maxX, maxY, maxZ)) {
|
|
348
|
+
continue;
|
|
349
|
+
}
|
|
350
|
+
surfacePolyData.getPoints().setData(points, 3);
|
|
351
|
+
surfacePolyData.getPolys().setData(polys, 3);
|
|
352
|
+
surfacePolyData.modified();
|
|
353
|
+
cutter.setInputData(surfacePolyData);
|
|
354
|
+
plane1.setOrigin(origin);
|
|
355
|
+
plane1.setNormal(normal);
|
|
356
|
+
try {
|
|
357
|
+
cutter.update();
|
|
358
|
+
}
|
|
359
|
+
catch (e) {
|
|
360
|
+
console.warn('Error during clipping', e);
|
|
361
|
+
continue;
|
|
362
|
+
}
|
|
363
|
+
const polyData = cutter.getOutputData();
|
|
364
|
+
const cutterOutput = polyData;
|
|
365
|
+
cutterOutput.buildLinks();
|
|
366
|
+
const loopExtraction = vtkContourLoopExtraction.newInstance();
|
|
367
|
+
loopExtraction.setInputData(cutterOutput);
|
|
368
|
+
const loopOutput = loopExtraction.getOutputData();
|
|
369
|
+
if (polyData) {
|
|
370
|
+
polyDataResults.set(segmentIndex, {
|
|
371
|
+
points: loopOutput.getPoints().getData(),
|
|
372
|
+
lines: loopOutput.getLines().getData(),
|
|
373
|
+
numberOfCells: loopOutput.getLines().getNumberOfCells(),
|
|
374
|
+
segmentIndex,
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
progressCallback({ progress: (index + 1) / numberOfPlanes });
|
|
379
|
+
updateCacheCallback({ sliceIndex, polyDataResults });
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
catch (e) {
|
|
383
|
+
console.warn('Error during processing', e);
|
|
384
|
+
}
|
|
385
|
+
finally {
|
|
386
|
+
surfacesInfo = null;
|
|
387
|
+
plane1.delete();
|
|
388
|
+
}
|
|
389
|
+
},
|
|
390
|
+
};
|
|
391
|
+
expose(polySegConverters);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cornerstonejs/polymorphic-segmentation",
|
|
3
|
-
"version": "3.0.0-beta.
|
|
3
|
+
"version": "3.0.0-beta.4",
|
|
4
4
|
"description": "Polymorphic Segmentation utility for Cornerstone3D",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist"
|
|
@@ -27,10 +27,13 @@
|
|
|
27
27
|
"build:esm:watch": "tsc --project ./tsconfig.json --watch",
|
|
28
28
|
"dev": "tsc --project ./tsconfig.json --watch",
|
|
29
29
|
"build:all": "yarn run build:esm",
|
|
30
|
-
"build:update-api": "yarn run build:esm && api-extractor run --local",
|
|
31
30
|
"start": "tsc --project ./tsconfig.json --watch",
|
|
32
31
|
"format": "prettier --write 'src/**/*.js' 'test/**/*.js'",
|
|
33
|
-
"lint": "eslint --fix ."
|
|
32
|
+
"lint": "eslint --fix .",
|
|
33
|
+
"format-check": "npx eslint ./src --quiet",
|
|
34
|
+
"api-check": "api-extractor --debug run ",
|
|
35
|
+
"build:update-api": "yarn run build:esm && api-extractor run --local",
|
|
36
|
+
"prepublishOnly": "yarn clean && yarn build"
|
|
34
37
|
},
|
|
35
38
|
"repository": {
|
|
36
39
|
"type": "git",
|
|
@@ -46,9 +49,9 @@
|
|
|
46
49
|
"@icr/polyseg-wasm": "0.4.0"
|
|
47
50
|
},
|
|
48
51
|
"peerDependencies": {
|
|
49
|
-
"@cornerstonejs/core": "^3.0.0-beta.
|
|
50
|
-
"@cornerstonejs/tools": "^3.0.0-beta.
|
|
52
|
+
"@cornerstonejs/core": "^3.0.0-beta.4",
|
|
53
|
+
"@cornerstonejs/tools": "^3.0.0-beta.4",
|
|
51
54
|
"@kitware/vtk.js": "^32.9.0"
|
|
52
55
|
},
|
|
53
|
-
"gitHead": "
|
|
56
|
+
"gitHead": "93464de8c8c6f01ca4ca35140c8f910b4a226582"
|
|
54
57
|
}
|