larvitar 0.20.0 → 1.2.2

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 (45) hide show
  1. package/.github/workflows/build-docs.yml +1 -1
  2. package/.github/workflows/deploy.yml +2 -11
  3. package/MIGRATION.md +25 -0
  4. package/README.md +28 -27
  5. package/imaging/dataDictionary.json +21865 -21865
  6. package/imaging/{image_anonymization.js → imageAnonymization.js} +1 -1
  7. package/imaging/{image_colormaps.js → imageColormaps.js} +2 -2
  8. package/imaging/{image_contours.js → imageContours.js} +1 -2
  9. package/imaging/{image_io.js → imageIo.js} +18 -15
  10. package/imaging/{image_layers.js → imageLayers.js} +2 -2
  11. package/imaging/{image_loading.js → imageLoading.js} +9 -6
  12. package/imaging/imageParsing.js +301 -0
  13. package/imaging/{image_presets.js → imagePresets.js} +2 -2
  14. package/imaging/{image_rendering.js → imageRendering.js} +36 -32
  15. package/imaging/imageReslice.js +78 -0
  16. package/imaging/{image_store.js → imageStore.js} +24 -7
  17. package/imaging/{image_tools.js → imageTools.js} +15 -23
  18. package/imaging/{image_utils.js → imageUtils.js} +1 -1
  19. package/imaging/loaders/commonLoader.js +1 -1
  20. package/imaging/loaders/dicomLoader.js +1 -1
  21. package/imaging/loaders/fileLoader.js +2 -2
  22. package/imaging/loaders/multiframeLoader.js +6 -2
  23. package/imaging/loaders/nrrdLoader.js +11 -7
  24. package/imaging/tools/{contourTool.js → custom/contourTool.js} +25 -20
  25. package/imaging/tools/{diameterTool.js → custom/diameterTool.js} +9 -3
  26. package/imaging/tools/{editMaskTool.js → custom/editMaskTool.js} +7 -1
  27. package/imaging/tools/{polylineScissorsTool.js → custom/polylineScissorsTool.js} +12 -5
  28. package/imaging/tools/{seedTool.js → custom/seedTool.js} +3 -3
  29. package/imaging/tools/{thresholdsBrushTool.js → custom/thresholdsBrushTool.js} +7 -1
  30. package/imaging/tools/{tools.default.js → default.js} +9 -2
  31. package/imaging/tools/{tools.interaction.js → interaction.js} +13 -6
  32. package/imaging/tools/{tools.io.js → io.js} +15 -6
  33. package/imaging/tools/{tools.main.js → main.js} +14 -13
  34. package/imaging/tools/polygonSegmentationMixin.js +8 -4
  35. package/imaging/tools/{tools.segmentation.js → segmentation.js} +171 -58
  36. package/imaging/tools/segmentations.md +38 -0
  37. package/imaging/tools/setLabelMap3D.js +248 -0
  38. package/imaging/tools/{tools.state.js → state.js} +7 -1
  39. package/imaging/tools/strategies/eraseFreehand.js +8 -9
  40. package/imaging/tools/strategies/fillFreehand.js +8 -9
  41. package/index.js +41 -39
  42. package/modules/vuex/larvitar.js +2 -1
  43. package/package.json +11 -8
  44. package/imaging/image_parsing.js +0 -307
  45. package/imaging/image_reslice.js +0 -80
@@ -1,33 +1,23 @@
1
+ /** @module imaging/tools/segmentation
2
+ * @desc This file provides functionalities
3
+ * for handling masks and luts
4
+ */
5
+
1
6
  // external libraries
2
7
  import cornerstone from "cornerstone-core";
3
8
  import cornerstoneTools from "cornerstone-tools/dist/cornerstoneTools.js";
4
- // tools
5
- import { setToolActive, setToolDisabled } from "./tools.main";
6
- // utils
7
- import { cloneDeep, extend, values } from "lodash";
8
-
9
+ import { cloneDeep, extend, values, sum } from "lodash";
9
10
  const segModule = cornerstoneTools.getModule("segmentation");
10
- const setters = segModule.setters;
11
- const getters = segModule.getters;
11
+ const { getters, setters } = segModule;
12
12
 
13
- /**
14
- * THIS MODULE IS A WIP
15
- */
13
+ // internal libraries
14
+ import { setToolActive, setToolDisabled } from "./main";
15
+ import { isElement } from "../imageUtils";
16
16
 
17
- // DEV
18
- window.segModule = segModule;
19
- window.cornerstone = cornerstone;
20
- window.cornerstoneTools = cornerstoneTools;
21
-
22
- /**
23
- * NOTES ON CS TOOLS SEGMENTATION MODULE
24
- * The value in the mask (binary) define which color will be used from the LUT map
25
- * The different masks are 'labelmap', while different values in the same mask are 'segments'
26
- * Segments get the color from the lutmap (up to 2^16 segments) and can be shown/hidden one by one
27
- * > setters.toggleSegmentVisibility(htmlelement,segmentvalue,labelmapid)
28
- * > setters.colorForSegmentIndexOfColorLUT(colorLutIndex, segmentValue, colorRGBAarray)
29
- * Labelmaps are linked to a colormap and can be active / inactive
30
- * */
17
+ // custom code
18
+ import { setLabelmap3DForElement } from "./setLabelMap3D";
19
+ // override function
20
+ setters.labelmap3DForElement = setLabelmap3DForElement;
31
21
 
32
22
  // General segmentation cs tools module configuration
33
23
  const config = {
@@ -145,53 +135,153 @@ function generateUniformLUT(hex_color, opacity) {
145
135
  return lut;
146
136
  }
147
137
 
138
+ /**
139
+ * Set color for label
140
+ * @param {Number} labelId
141
+ * @param {String} color in hex format
142
+ */
143
+ export function setLabelColor(labelId, color) {
144
+ let volumeId = 0; // TODO MULTIVOLUME
145
+ let rgb = hexToRgb(color);
146
+ let rgba = [...rgb, 128];
147
+ setters.colorForSegmentIndexOfColorLUT(volumeId, labelId, rgba);
148
+ // force render ? depends on image visualization (render all ?)
149
+ }
150
+
151
+ /**
152
+ * Get color from label
153
+ * @param {Number} labelId
154
+ * @returns {String} Color in hex format
155
+ */
156
+ export function getLabelColor(labelId) {
157
+ let volumeId = 0; // TODO MULTIVOLUME
158
+ let rgba = getters.colorForSegmentIndexColorLUT(volumeId, labelId);
159
+ return rgbToHex(rgba);
160
+ }
161
+
148
162
  /**
149
163
  * A function to group all settings to load before masks
150
- * TODO add a param to override config
164
+ * @param {Object} customConfig - Object containing override values for segmentation module config
151
165
  */
152
- export function initSegmentationModule() {
166
+ export function initSegmentationModule(customConfig) {
153
167
  // set configuration
154
168
  segModule.configuration = cloneDeep(config);
169
+ extend(segModule.configuration, customConfig);
155
170
  }
156
171
 
157
172
  /**
158
173
  * Add segmentation mask to segmentation module
159
- * @param {Number} labelId - The label index (must be unique)
174
+ * @param {Object} maskProps - The mask properties (labelId, color and opacity)
160
175
  * @param {TypedArray} - The mask data array
176
+ * @param {String} elementId - The target html element Id or its DOM HTMLElement
177
+ * @returns {Promise} - Return a promise which will resolve when segmentation mask is added
161
178
  */
162
- export function addSegmentationMask(props, data, elementId, cb) {
163
- let element = document.getElementById(elementId);
164
- setters.labelmap3DForElement(element, data.buffer, props.labelId);
165
- // if user set a color property, use that color for all segments on the labelmap
166
- let lut = props.color
167
- ? generateUniformLUT(props.color, props.opacity)
168
- : generateLUT(props.opacity);
169
- setters.colorLUT(props.labelId, lut);
170
- // bind labelmap to colorLUT
171
- let labelmap3d = getters.labelmap3D(element, props.labelId);
172
- setters.colorLUTIndexForLabelmap3D(labelmap3d, props.labelId);
173
- if (cb) {
174
- cb();
179
+ export function addSegmentationMask(props, data, elementId) {
180
+ let promise = new Promise(async resolve => {
181
+ let element = isElement(elementId)
182
+ ? elementId
183
+ : document.getElementById(elementId);
184
+ if (!element) {
185
+ console.error("invalid html element: " + elementId);
186
+ return;
187
+ }
188
+
189
+ const res = await setters.labelmap3DForElement(
190
+ element,
191
+ data.buffer,
192
+ props.labelId
193
+ );
194
+ // if user set a color property, use that color for all segments on the labelmap
195
+ let lut = props.color
196
+ ? generateUniformLUT(props.color, props.opacity)
197
+ : generateLUT(props.opacity);
198
+ setters.colorLUT(props.labelId, lut);
199
+ // bind labelmap to colorLUT
200
+ let labelmap3d = getters.labelmap3D(element, props.labelId);
201
+ setters.colorLUTIndexForLabelmap3D(labelmap3d, props.labelId);
202
+ resolve();
203
+ });
204
+ return promise;
205
+ }
206
+
207
+ /**
208
+ * Set a new mask slice into the labelmap buffer
209
+ * @param {String} elementId - The target html element Id or its DOM HTMLElement
210
+ * @param {Number} sliceIndex - the index of the new mask slice
211
+ * @param {ArrayBuffer} pixelData - the pixelData array
212
+ */
213
+ export function loadMaskSlice(elementId, sliceIndex, pixelData) {
214
+ // optimization: if pixelData contains no labels, return
215
+ if (sum(pixelData) === 0) {
216
+ return;
217
+ }
218
+
219
+ let element = isElement(elementId)
220
+ ? elementId
221
+ : document.getElementById(elementId);
222
+ if (!element) {
223
+ console.error("invalid html element: " + elementId);
224
+ return;
175
225
  }
226
+ let volumeId = 0; // TODO for multivolume
227
+ // get labelmap buffer
228
+ let labelmaps2D = getters.labelmap3D(element, volumeId).labelmaps2D;
229
+
230
+ // add if not alresdy present
231
+ if (!labelmaps2D[sliceIndex]) {
232
+ labelmaps2D[sliceIndex] = {};
233
+ }
234
+
235
+ labelmaps2D[sliceIndex].pixelData = pixelData;
236
+ setters.updateSegmentsOnLabelmap2D(labelmaps2D[sliceIndex]);
237
+ cornerstone.updateImage(element);
176
238
  }
177
239
 
178
240
  /**
179
241
  * Activate a specific labelmap through its labelId
180
242
  * @param {Number} labelId - The labelmap id to activate
181
- * @param {String} elementId - The target html element id
243
+ * @param {String} elementId - The target html element Id or its DOM HTMLElement
182
244
  */
183
245
  export function setActiveLabelmap(labelId, elementId) {
184
- let element = document.getElementById(elementId);
246
+ let element = isElement(elementId)
247
+ ? elementId
248
+ : document.getElementById(elementId);
249
+ if (!element) {
250
+ console.error("invalid html element: " + elementId);
251
+ return;
252
+ }
185
253
  setters.activeLabelmapIndex(element, labelId);
186
254
  }
187
255
 
256
+ /**
257
+ * Get active labelmap for target element
258
+ * @param {String} elementId - The target html element Id or its DOM HTMLElement
259
+ * @returns {Object} The active labelmap object that contains the buffer
260
+ */
261
+ export function getActiveLabelmapBuffer(elementId) {
262
+ let element = isElement(elementId)
263
+ ? elementId
264
+ : document.getElementById(elementId);
265
+ if (!element) {
266
+ console.error("invalid html element: " + elementId);
267
+ return;
268
+ }
269
+ return getters.activeLabelmapBuffer(element);
270
+ }
271
+
188
272
  /**
189
273
  * Activate a specific segment through its index
190
274
  * @param {Number} segmentIndex - The segment index to activate
191
- * @param {String} elementId - The target html element id
275
+ * @param {String} elementId - The target html element Id or its DOM HTMLElement
192
276
  */
193
277
  export function setActiveSegment(segmentIndex, elementId) {
194
- let element = document.getElementById(elementId);
278
+ let element = isElement(elementId)
279
+ ? elementId
280
+ : document.getElementById(elementId);
281
+ if (!element) {
282
+ console.error("invalid html element: " + elementId);
283
+ return;
284
+ }
195
285
  setters.activeSegmentIndex(element, segmentIndex);
196
286
  }
197
287
 
@@ -213,6 +303,24 @@ export function setInactiveLabelOpacity(opacity) {
213
303
  forceRender();
214
304
  }
215
305
 
306
+ /**
307
+ * Toggle mask visibility
308
+ * @param {String} elementId - The target html element Id or its DOM HTMLElement
309
+ * @param {Number} labelId - The id of the mask label
310
+ */
311
+ export function toggleVisibility(elementId, labelId) {
312
+ let element = isElement(elementId)
313
+ ? elementId
314
+ : document.getElementById(elementId);
315
+ if (!element) {
316
+ console.error("invalid html element: " + elementId);
317
+ return;
318
+ }
319
+ let volumeId = 0; // TODO MULTIVOLUME
320
+ setters.toggleSegmentVisibility(element, labelId, volumeId);
321
+ cornerstone.updateImage(element);
322
+ }
323
+
216
324
  /**
217
325
  * Toggle between 'contours mode' and 'filled mode'
218
326
  * @param {Bool} toggle - Contour mode enabled if true
@@ -236,9 +344,7 @@ export function toggleContourMode(toggle) {
236
344
 
237
345
  /**
238
346
  * Set mask appearance props
239
- * @param {String} tag - The mask tag
240
- * @param {Integer} mode - [0=filled, 1=contour, 2=hidden]
241
- * @param {Float} alpha - Opacity value (if mode=0), between 0 and 1
347
+ * @param {Object} maskProps - The mask appearance props (labelId, visualization [0=filled, 1=contour, 2=hidden], opacity (if mode=0), between 0 and 1)
242
348
  */
243
349
  export function setMaskProps(props) {
244
350
  // Lut index and segment values are hardcoded because they will depend on design choices:
@@ -299,6 +405,7 @@ export function clearSegmentationState() {
299
405
  /**
300
406
  * Enable brushing
301
407
  * @param {Number} dimension - The initial brush radius
408
+ * @param {Array} thresholds - The threshold values (min and max)
302
409
  */
303
410
  export function enableBrushTool(dimension, thresholds) {
304
411
  segModule.configuration.radius = dimension;
@@ -324,35 +431,41 @@ export function setBrushProps(props) {
324
431
  forceRender();
325
432
  }
326
433
 
327
- /**
328
- * Retrieve the buffer that represents the current active mask
329
- */
330
- export function getActiveLabelmapBuffer() {
331
- let element = document.getElementById("axial");
332
- let object = segModule.getters.activeLabelmapBuffer(element);
333
- return object.buffer;
334
- }
335
-
336
434
  /**
337
435
  * Undo last brush operation (stroke)
436
+ * @param {String} elementId - The target html element Id or its DOM HTMLElement
338
437
  */
339
438
  export function undoLastStroke(elementId) {
340
- let element = document.getElementById(elementId);
439
+ let element = isElement(elementId)
440
+ ? elementId
441
+ : document.getElementById(elementId);
442
+ if (!element) {
443
+ console.error("invalid html element: " + elementId);
444
+ return;
445
+ }
341
446
  let activeLabelMapIndex = segModule.getters.activeLabelmapIndex(element);
342
447
  setters.undo(element, activeLabelMapIndex);
343
448
  }
344
449
 
345
450
  /**
346
451
  * Redo last brush operation (stroke)
452
+ * @param {String} elementId - The target html element Id or its DOM HTMLElement
347
453
  */
348
454
  export function redoLastStroke(elementId) {
349
- let element = document.getElementById(elementId);
455
+ let element = isElement(elementId)
456
+ ? elementId
457
+ : document.getElementById(elementId);
458
+ if (!element) {
459
+ console.error("invalid html element: " + elementId);
460
+ return;
461
+ }
350
462
  let activeLabelMapIndex = segModule.getters.activeLabelmapIndex(element);
351
463
  setters.redo(element, activeLabelMapIndex);
352
464
  }
353
465
 
354
466
  /**
355
467
  * Delete mask from state
468
+ * @param {Number} labelId - The labelmap id to activate
356
469
  */
357
470
  export function deleteMask(labelId) {
358
471
  let masks = values(segModule.state.series)[0].labelmaps3D;
@@ -0,0 +1,38 @@
1
+ # Introduction
2
+
3
+ This guide explains the key concepts of Larvitar **segmentation masks management**, based on cornerstone tools's **segmentation module**.
4
+
5
+ # Definitions
6
+
7
+ - _segmentation mask_ or just _mask_: the set of pixels that belongs to a specific structure
8
+ - _volume_: a buffer containing one or more segmentations
9
+ - _label_: the value inside a volume that identifies a specific segmentation
10
+
11
+ # CS tools
12
+
13
+ ## Segmentation module structure
14
+
15
+ In cs tools world, the different volumes are defined _labelmaps_, while the different labels in a volume are _segments_. Labelmaps can support up to 2^16 segments.
16
+ The values in the volume (ie, labels) define which color will be used from the LUT map: in fact, segments get the color from the lutmap and can be shown/hidden one by one.
17
+ Each labelmaps can be linked to a different colormap and has a active / inactive property that affects the rendering style (see configuration).
18
+
19
+ > setters.toggleSegmentVisibility(htmlelement,segmentvalue,labelmapid)
20
+ > setters.colorForSegmentIndexOfColorLUT(colorLutIndex, segmentValue, colorRGBAarray)
21
+
22
+ ## Configuration
23
+
24
+ TODO
25
+
26
+ # Larvitar segmentation management
27
+
28
+ TODO
29
+
30
+ # Larvitar segmentation API
31
+
32
+ TODO
33
+
34
+ # Customization
35
+
36
+ Some function in larvitar overrides the default behaviour of cornerstone tools, here is a list of them:
37
+
38
+ - `setters.labelmap3DForElement` is overridden to have a non-blocking behaviour, the custom code is in ./setLabelMap3D.js, same as original code in cs tools repo.
@@ -0,0 +1,248 @@
1
+ /**
2
+ * This is a custom version of setLabelMap3D from cs tools source code
3
+ * This let us implement a non-blocking version of the for loop that loads 3d labelmaps on a volume
4
+ * @ronzim
5
+ */
6
+
7
+ // import getElement from "./getElement";
8
+ // import { getToolState } from "../../../stateManagement/toolState.js";
9
+ // import state from "./state";
10
+ // import getSegmentsOnPixelData from "./getSegmentsOnPixeldata";
11
+ // import { triggerLabelmapModifiedEvent } from "../../../util/segmentation";
12
+ // import ARRAY_TYPES from "./arrayTypes";
13
+ // import { getModule } from "../../index.js";
14
+
15
+ const ARRAY_TYPES = {
16
+ UINT_16_ARRAY: 0,
17
+ FLOAT_32_ARRAY: 1
18
+ };
19
+ const { UINT_16_ARRAY, FLOAT_32_ARRAY } = ARRAY_TYPES;
20
+
21
+ import cornerstoneTools from "cornerstone-tools/dist/cornerstoneTools.js";
22
+ const { triggerLabelmapModifiedEvent } = cornerstoneTools.importInternal(
23
+ "util/segmentationUtils"
24
+ );
25
+ const getModule = cornerstoneTools.getModule;
26
+ const getToolState = cornerstoneTools.getToolState;
27
+ const storeGetters = cornerstoneTools.store.getters;
28
+ const state = getModule("segmentation").state;
29
+
30
+ /**
31
+ * These function are reported since they are not exposed by cs tools
32
+ *
33
+ */
34
+
35
+ // from getSegmentsOnPixelData.js
36
+ function getSegmentsOnPixelData(pixelData) {
37
+ return [...new Set(pixelData)];
38
+ }
39
+
40
+ // from getElement.js
41
+ function getElement(elementOrEnabledElementUID) {
42
+ if (elementOrEnabledElementUID instanceof HTMLElement) {
43
+ return elementOrEnabledElementUID;
44
+ }
45
+
46
+ return storeGetters.enabledElementByUID(elementOrEnabledElementUID);
47
+ }
48
+
49
+ /**
50
+ * Takes a 16-bit encoded `ArrayBuffer` and stores it as a `Labelmap3D` for the
51
+ * `BrushStackState` associated with the element.
52
+ *
53
+ * @param {HTMLElement|string} elementOrEnabledElementUID The cornerstone
54
+ * enabled element or its UUID.
55
+ * @param {ArrayBuffer} buffer
56
+ * @param {number} labelmapIndex The index to store the labelmap under.
57
+ * @param {Object[]} metadata = [] Any metadata about the segments.
58
+ * @param {number[][]} [segmentsOnLabelmapArray] An array of array of segments on each imageIdIndex.
59
+ * If not present, is calculated.
60
+ * @param {colorLUTIndex} [colorLUTIndex = 0] The index of the colorLUT to use to render the segmentation.
61
+ * @returns {null}
62
+ */
63
+ async function setLabelmap3DForElement(
64
+ elementOrEnabledElementUID,
65
+ buffer,
66
+ labelmapIndex,
67
+ metadata = [],
68
+ segmentsOnLabelmapArray,
69
+ colorLUTIndex = 0
70
+ ) {
71
+ const element = getElement(elementOrEnabledElementUID);
72
+
73
+ if (!element) {
74
+ return;
75
+ }
76
+
77
+ const stackState = getToolState(element, "stack");
78
+ const numberOfFrames = stackState.data[0].imageIds.length;
79
+ const firstImageId = stackState.data[0].imageIds[0];
80
+
81
+ const res = await setLabelmap3DByFirstImageId(
82
+ firstImageId,
83
+ buffer,
84
+ labelmapIndex,
85
+ metadata,
86
+ numberOfFrames,
87
+ segmentsOnLabelmapArray,
88
+ colorLUTIndex
89
+ );
90
+
91
+ triggerLabelmapModifiedEvent(element, labelmapIndex);
92
+
93
+ return res;
94
+ }
95
+
96
+ /**
97
+ * Takes an 16-bit encoded `ArrayBuffer` and stores it as a `Labelmap3D` for
98
+ * the `BrushStackState` associated with the firstImageId.
99
+ *
100
+ * @param {HTMLElement|string} firstImageId The firstImageId of the series to
101
+ * store the segmentation on.
102
+ * @param {ArrayBuffer} buffer
103
+ * @param {number} labelmapIndex The index to store the labelmap under.
104
+ * @param {Object[]} metadata = [] Any metadata about the segments.
105
+ * @param {number} numberOfFrames The number of frames, required to set up the
106
+ * relevant labelmap2D views.
107
+ * @param {number[][]} [segmentsOnLabelmapArray] An array of array of segments on each imageIdIndex.
108
+ * If not present, is calculated.
109
+ * @param {colorLUTIndex} [colorLUTIndex = 0] The index of the colorLUT to use to render the segmentation.
110
+ * @returns {null}
111
+ */
112
+ function setLabelmap3DByFirstImageId(
113
+ firstImageId,
114
+ buffer,
115
+ labelmapIndex,
116
+ metadata = [],
117
+ numberOfFrames,
118
+ segmentsOnLabelmapArray,
119
+ colorLUTIndex = 0
120
+ ) {
121
+ const { configuration } = getModule("segmentation");
122
+
123
+ let brushStackState = state.series[firstImageId];
124
+
125
+ if (!brushStackState) {
126
+ state.series[firstImageId] = {
127
+ activeLabelmapIndex: labelmapIndex,
128
+ labelmaps3D: []
129
+ };
130
+
131
+ brushStackState = state.series[firstImageId];
132
+ }
133
+
134
+ brushStackState.labelmaps3D[labelmapIndex] = {
135
+ buffer,
136
+ labelmaps2D: [],
137
+ metadata,
138
+ activeSegmentIndex: 1,
139
+ colorLUTIndex,
140
+ segmentsHidden: [],
141
+ undo: [],
142
+ redo: []
143
+ };
144
+
145
+ const labelmaps2D = brushStackState.labelmaps3D[labelmapIndex].labelmaps2D;
146
+ const slicelengthInBytes = buffer.byteLength / numberOfFrames;
147
+
148
+ /* non-blocking implementation by @ronzim */
149
+
150
+ return new Promise(resolve => {
151
+ function setSingleSlice(i, numberOfFrames) {
152
+ var pixelData = void 0;
153
+
154
+ switch (configuration.arrayType) {
155
+ case UINT_16_ARRAY:
156
+ pixelData = new Uint16Array(
157
+ buffer,
158
+ slicelengthInBytes * i, // 2 bytes/voxel
159
+ slicelengthInBytes / 2
160
+ );
161
+ break;
162
+
163
+ case FLOAT_32_ARRAY:
164
+ pixelData = new Float32Array(
165
+ buffer,
166
+ slicelengthInBytes * i,
167
+ slicelengthInBytes / 4
168
+ );
169
+ break;
170
+
171
+ default:
172
+ throw new Error(
173
+ "Unsupported Array Type ".concat(configuration.arrayType)
174
+ );
175
+ }
176
+
177
+ var segmentsOnLabelmap = segmentsOnLabelmapArray
178
+ ? segmentsOnLabelmapArray[i]
179
+ : getSegmentsOnPixelData(pixelData);
180
+
181
+ if (
182
+ segmentsOnLabelmap &&
183
+ segmentsOnLabelmap.some(function (segment) {
184
+ return segment;
185
+ })
186
+ ) {
187
+ labelmaps2D[i] = {
188
+ pixelData: pixelData,
189
+ segmentsOnLabelmap: segmentsOnLabelmap
190
+ };
191
+ }
192
+
193
+ ++i;
194
+
195
+ if (i < numberOfFrames) {
196
+ setTimeout(() => {
197
+ setSingleSlice(i, numberOfFrames);
198
+ }, 0);
199
+ } else {
200
+ resolve("OK");
201
+ }
202
+ }
203
+
204
+ setSingleSlice(0, numberOfFrames);
205
+ });
206
+
207
+ /* original implementation
208
+
209
+ for (let i = 0; i < numberOfFrames; i++) {
210
+ let pixelData;
211
+
212
+ switch (configuration.arrayType) {
213
+ case UINT_16_ARRAY:
214
+ pixelData = new Uint16Array(
215
+ buffer,
216
+ slicelengthInBytes * i, // 2 bytes/voxel
217
+ slicelengthInBytes / 2
218
+ );
219
+
220
+ break;
221
+
222
+ case FLOAT_32_ARRAY:
223
+ pixelData = new Float32Array(
224
+ buffer,
225
+ slicelengthInBytes * i,
226
+ slicelengthInBytes / 4
227
+ );
228
+ break;
229
+
230
+ default:
231
+ throw new Error(`Unsupported Array Type ${configuration.arrayType}`);
232
+ }
233
+
234
+ const segmentsOnLabelmap = segmentsOnLabelmapArray
235
+ ? segmentsOnLabelmapArray[i]
236
+ : getSegmentsOnPixelData(pixelData);
237
+
238
+ if (segmentsOnLabelmap && segmentsOnLabelmap.some(segment => segment)) {
239
+ labelmaps2D[i] = {
240
+ pixelData,
241
+ segmentsOnLabelmap
242
+ };
243
+ }
244
+ }
245
+ */
246
+ }
247
+
248
+ export { setLabelmap3DByFirstImageId, setLabelmap3DForElement };
@@ -1,8 +1,14 @@
1
+ /** @module imaging/tools/state
2
+ * @desc This file provides functionalities
3
+ * for handling tools' state
4
+ */
5
+
1
6
  // external libraries
2
7
  import cornerstone from "cornerstone-core";
3
8
  import cornerstoneTools from "cornerstone-tools";
4
-
5
9
  import { each } from "lodash";
10
+
11
+ // internal libraries
6
12
  import { state_example } from "./cstools_state_example.js";
7
13
 
8
14
  /**
@@ -1,17 +1,16 @@
1
- import cornerstoneTools from "cornerstone-tools";
2
-
3
- const {
4
- getBoundingBoxAroundPolygon,
5
- eraseInsideShape,
6
- eraseOutsideShape
7
- } = cornerstoneTools.importInternal("util/segmentationUtils");
1
+ /** @module imaging/strategies/eraseFreehand
2
+ * @desc This file provides functionalities for
3
+ * erasing pixels
4
+ */
8
5
 
6
+ // external libraries
7
+ import cornerstoneTools from "cornerstone-tools";
8
+ const { getBoundingBoxAroundPolygon, eraseInsideShape, eraseOutsideShape } =
9
+ cornerstoneTools.importInternal("util/segmentationUtils");
9
10
  const isPointInPolygon = cornerstoneTools.importInternal(
10
11
  "util/isPointInPolygon"
11
12
  );
12
-
13
13
  const getLogger = cornerstoneTools.importInternal("util/getLogger");
14
-
15
14
  const logger = getLogger("util:segmentation:operations:eraseInsideFreehand");
16
15
 
17
16
  /**
@@ -1,17 +1,16 @@
1
- import cornerstoneTools from "cornerstone-tools";
2
-
3
- const {
4
- getBoundingBoxAroundPolygon,
5
- fillInsideShape,
6
- fillOutsideShape
7
- } = cornerstoneTools.importInternal("util/segmentationUtils");
1
+ /** @module imaging/strategies/fillFreehand
2
+ * @desc This file provides functionalities for
3
+ * filling pixels
4
+ */
8
5
 
6
+ // external libraries
7
+ import cornerstoneTools from "cornerstone-tools";
8
+ const { getBoundingBoxAroundPolygon, fillInsideShape, fillOutsideShape } =
9
+ cornerstoneTools.importInternal("util/segmentationUtils");
9
10
  const isPointInPolygon = cornerstoneTools.importInternal(
10
11
  "util/isPointInPolygon"
11
12
  );
12
-
13
13
  const getLogger = cornerstoneTools.importInternal("util/getLogger");
14
-
15
14
  const logger = getLogger("util:segmentation:operations:fillInsideFreehand");
16
15
 
17
16
  /**