copper3d 1.15.22 → 2.0.1

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 (94) hide show
  1. package/README.md +2 -2
  2. package/dist/Loader/copperNrrdLoader.d.ts +1 -1
  3. package/dist/Renderer/baseRenderer.d.ts +2 -2
  4. package/dist/Renderer/baseRenderer.js +2 -2
  5. package/dist/Renderer/baseRenderer.js.map +1 -1
  6. package/dist/Renderer/copperMSceneRenderer.d.ts +2 -2
  7. package/dist/Renderer/copperMSceneRenderer.js +2 -2
  8. package/dist/Renderer/copperMSceneRenderer.js.map +1 -1
  9. package/dist/Renderer/copperRenderer.d.ts +4 -4
  10. package/dist/Renderer/copperRenderer.js +3 -3
  11. package/dist/Renderer/copperRenderer.js.map +1 -1
  12. package/dist/Renderer/copperRendererOnDemond.d.ts +4 -5
  13. package/dist/Renderer/copperRendererOnDemond.js +3 -3
  14. package/dist/Renderer/copperRendererOnDemond.js.map +1 -1
  15. package/dist/Scene/baseScene.d.ts +2 -2
  16. package/dist/Scene/baseScene.js +2 -2
  17. package/dist/Scene/baseScene.js.map +1 -1
  18. package/dist/Scene/commonSceneMethod.d.ts +1 -1
  19. package/dist/Scene/commonSceneMethod.js +1 -1
  20. package/dist/Scene/commonSceneMethod.js.map +1 -1
  21. package/dist/Scene/copperMScene.d.ts +2 -2
  22. package/dist/Scene/copperMScene.js +2 -2
  23. package/dist/Scene/copperMScene.js.map +1 -1
  24. package/dist/Scene/copperScene.d.ts +2 -2
  25. package/dist/Scene/copperScene.js +2 -2
  26. package/dist/Scene/copperScene.js.map +1 -1
  27. package/dist/Scene/copperSceneOnDemond.d.ts +2 -2
  28. package/dist/Scene/copperSceneOnDemond.js +2 -2
  29. package/dist/Scene/copperSceneOnDemond.js.map +1 -1
  30. package/dist/Utils/add3DLabel.d.ts +2 -2
  31. package/dist/Utils/segmentation/CommToolsData.d.ts +71 -0
  32. package/dist/Utils/segmentation/CommToolsData.js +267 -0
  33. package/dist/Utils/segmentation/CommToolsData.js.map +1 -0
  34. package/dist/Utils/segmentation/DragOperator.d.ts +30 -0
  35. package/dist/Utils/segmentation/DragOperator.js +243 -0
  36. package/dist/Utils/segmentation/DragOperator.js.map +1 -0
  37. package/dist/Utils/segmentation/DrawToolCore.d.ts +78 -0
  38. package/dist/Utils/segmentation/DrawToolCore.js +1083 -0
  39. package/dist/Utils/segmentation/DrawToolCore.js.map +1 -0
  40. package/dist/Utils/segmentation/NrrdTools.d.ts +178 -0
  41. package/dist/Utils/segmentation/NrrdTools.js +965 -0
  42. package/dist/Utils/segmentation/NrrdTools.js.map +1 -0
  43. package/dist/Utils/segmentation/coreTools/archive.d.ts +1 -0
  44. package/dist/Utils/segmentation/coreTools/archive.js +23 -0
  45. package/dist/Utils/segmentation/coreTools/archive.js.map +1 -0
  46. package/dist/Utils/segmentation/coreTools/coreType.d.ts +206 -0
  47. package/dist/Utils/segmentation/coreTools/coreType.js +2 -0
  48. package/dist/Utils/segmentation/coreTools/coreType.js.map +1 -0
  49. package/dist/Utils/segmentation/coreTools/divControlTools.d.ts +19 -0
  50. package/dist/Utils/segmentation/coreTools/divControlTools.js +48 -0
  51. package/dist/Utils/segmentation/coreTools/divControlTools.js.map +1 -0
  52. package/dist/Utils/segmentation/coreTools/gui.d.ts +123 -0
  53. package/dist/Utils/segmentation/coreTools/gui.js +306 -0
  54. package/dist/Utils/segmentation/coreTools/gui.js.map +1 -0
  55. package/dist/Utils/utils.d.ts +1 -1
  56. package/dist/Utils/utils.js +27 -12
  57. package/dist/Utils/utils.js.map +1 -1
  58. package/dist/Utils/workers/reformatSaveDataWorker.d.ts +3 -3
  59. package/dist/Utils/workers/reformatSaveDataWorker.js.map +1 -1
  60. package/dist/bundle.esm.js +2578 -2230
  61. package/dist/bundle.umd.js +2579 -2230
  62. package/dist/css/style.css +2 -18
  63. package/dist/index.d.ts +13 -11
  64. package/dist/index.js +11 -10
  65. package/dist/index.js.map +1 -1
  66. package/dist/types/Loader/copperNrrdLoader.d.ts +1 -1
  67. package/dist/types/Renderer/baseRenderer.d.ts +2 -2
  68. package/dist/types/Renderer/copperMSceneRenderer.d.ts +2 -2
  69. package/dist/types/Renderer/copperRenderer.d.ts +4 -4
  70. package/dist/types/Renderer/copperRendererOnDemond.d.ts +4 -5
  71. package/dist/types/Scene/baseScene.d.ts +2 -2
  72. package/dist/types/Scene/commonSceneMethod.d.ts +1 -1
  73. package/dist/types/Scene/copperMScene.d.ts +2 -2
  74. package/dist/types/Scene/copperScene.d.ts +2 -2
  75. package/dist/types/Scene/copperSceneOnDemond.d.ts +2 -2
  76. package/dist/types/Utils/add3DLabel.d.ts +2 -2
  77. package/dist/types/Utils/segmentation/CommToolsData.d.ts +71 -0
  78. package/dist/types/Utils/segmentation/DragOperator.d.ts +30 -0
  79. package/dist/types/Utils/segmentation/DrawToolCore.d.ts +78 -0
  80. package/dist/types/Utils/segmentation/NrrdTools.d.ts +178 -0
  81. package/dist/types/Utils/segmentation/coreTools/archive.d.ts +1 -0
  82. package/dist/types/Utils/segmentation/coreTools/coreType.d.ts +206 -0
  83. package/dist/types/Utils/segmentation/coreTools/divControlTools.d.ts +19 -0
  84. package/dist/types/Utils/segmentation/coreTools/gui.d.ts +123 -0
  85. package/dist/types/Utils/utils.d.ts +1 -1
  86. package/dist/types/Utils/workers/reformatSaveDataWorker.d.ts +3 -3
  87. package/dist/types/index.d.ts +13 -11
  88. package/dist/types/types/types.d.ts +4 -38
  89. package/dist/types/types.d.ts +4 -38
  90. package/package.json +1 -1
  91. package/dist/Utils/nrrd_tool.d.ts +0 -269
  92. package/dist/Utils/nrrd_tool.js +0 -2480
  93. package/dist/Utils/nrrd_tool.js.map +0 -1
  94. package/dist/types/Utils/nrrd_tool.d.ts +0 -269
@@ -0,0 +1,965 @@
1
+ import { setupGui } from "./coreTools/gui";
2
+ import { autoFocusDiv } from "./coreTools/divControlTools";
3
+ import { DragOperator } from "./DragOperator";
4
+ import { DrawToolCore } from "./DrawToolCore";
5
+ export class NrrdTools extends DrawToolCore {
6
+ constructor(container) {
7
+ super(container);
8
+ this.initState = true;
9
+ this.container = container;
10
+ this.storedPaintImages = {
11
+ label1: this.protectedData.maskData.paintImagesLabel1,
12
+ label2: this.protectedData.maskData.paintImagesLabel2,
13
+ label3: this.protectedData.maskData.paintImagesLabel3,
14
+ };
15
+ this.protectedData.previousDrawingImage =
16
+ this.protectedData.ctxes.emptyCtx.createImageData(1, 1);
17
+ this.init();
18
+ this.dragOperator = new DragOperator(this.container, this.nrrd_states, this.gui_states, this.protectedData, this.drawingPrameters, this.setSyncsliceNum, this.setIsDrawFalse, this.flipDisplayImageByAxis, this.setEmptyCanvasSize, this.filterDrawedImage);
19
+ }
20
+ /**
21
+ * core function for drag slices
22
+ * @param opts
23
+ */
24
+ drag(opts) {
25
+ this.dragOperator.drag(opts);
26
+ }
27
+ // draw(opts?: IDrawOpts) {
28
+ // this.drawOperator.draw(opts);
29
+ // }
30
+ // start() {
31
+ // console.log(this.drawOperator.start);
32
+ // return this.drawOperator.start;
33
+ // }
34
+ /**
35
+ * Set the Draw Display Canvas base size
36
+ * @param size number
37
+ */
38
+ setBaseDrawDisplayCanvasesSize(size) {
39
+ if (size > 8) {
40
+ this.baseCanvasesSize = 8;
41
+ }
42
+ else if (size < 1 || typeof size !== "number") {
43
+ this.baseCanvasesSize = 1;
44
+ }
45
+ else {
46
+ this.baseCanvasesSize = size;
47
+ }
48
+ }
49
+ setDisplaySliceIndexPanel(panel) {
50
+ this.dragOperator.setShowDragNumberDiv(panel);
51
+ }
52
+ /**
53
+ * Set up GUI for drawing panel
54
+ * @param gui GUI
55
+ */
56
+ setupGUI(gui) {
57
+ let modeFolder;
58
+ modeFolder = gui.addFolder("Mode Parameters");
59
+ const guiOptions = {
60
+ modeFolder,
61
+ dragOperator: this.dragOperator,
62
+ gui_states: this.gui_states,
63
+ nrrd_states: this.nrrd_states,
64
+ drawingCanvas: this.protectedData.canvases.drawingCanvas,
65
+ drawingPrameters: this.drawingPrameters,
66
+ eraserUrls: this.eraserUrls,
67
+ pencilUrls: this.pencilUrls,
68
+ mainPreSlices: this.protectedData.mainPreSlices,
69
+ protectedData: this.protectedData,
70
+ removeDragMode: this.dragOperator.removeDragMode,
71
+ configDragMode: this.dragOperator.configDragMode,
72
+ clearPaint: this.clearPaint,
73
+ clearStoreImages: this.clearStoreImages,
74
+ updateSlicesContrast: this.updateSlicesContrast,
75
+ setMainAreaSize: this.setMainAreaSize,
76
+ resetPaintAreaUIPosition: this.resetPaintAreaUIPosition,
77
+ resizePaintArea: this.resizePaintArea,
78
+ repraintCurrentContrastSlice: this.repraintCurrentContrastSlice,
79
+ setSyncsliceNum: this.setSyncsliceNum,
80
+ resetLayerCanvas: this.resetLayerCanvas,
81
+ redrawDisplayCanvas: this.redrawDisplayCanvas,
82
+ reloadMaskToLabel: this.reloadMaskToLabel,
83
+ flipDisplayImageByAxis: this.flipDisplayImageByAxis,
84
+ filterDrawedImage: this.filterDrawedImage,
85
+ setEmptyCanvasSize: this.setEmptyCanvasSize,
86
+ };
87
+ this.guiParameterSettings = setupGui(guiOptions);
88
+ }
89
+ getGuiSettings() {
90
+ return {
91
+ guiState: this.gui_states,
92
+ guiSetting: this.guiParameterSettings,
93
+ };
94
+ }
95
+ /**
96
+ * A initialise function for nrrd_tools
97
+ */
98
+ init() {
99
+ this.protectedData.mainAreaContainer.classList.add("copper3D_drawingCanvasContainer");
100
+ this.container.appendChild(this.protectedData.mainAreaContainer);
101
+ autoFocusDiv(this.container);
102
+ this.setShowInMainArea();
103
+ }
104
+ /**
105
+ *
106
+ * entry function
107
+ * * {
108
+ * x:slice,
109
+ * y:slice,
110
+ * z:slice
111
+ * }
112
+ *
113
+ * @param allSlices - all nrrd contrast slices
114
+
115
+ */
116
+ setAllSlices(allSlices) {
117
+ this.protectedData.allSlicesArray = [...allSlices];
118
+ const randomSlice = this.protectedData.allSlicesArray[0];
119
+ this.nrrd_states.nrrd_x_mm = randomSlice.z.canvas.width;
120
+ this.nrrd_states.nrrd_y_mm = randomSlice.z.canvas.height;
121
+ this.nrrd_states.nrrd_z_mm = randomSlice.x.canvas.width;
122
+ this.nrrd_states.nrrd_x_pixel = randomSlice.x.volume.dimensions[0];
123
+ this.nrrd_states.nrrd_y_pixel = randomSlice.x.volume.dimensions[1];
124
+ this.nrrd_states.nrrd_z_pixel = randomSlice.x.volume.dimensions[2];
125
+ this.nrrd_states.voxelSpacing = randomSlice.x.volume.spacing;
126
+ this.nrrd_states.ratios.x = randomSlice.x.volume.spacing[0];
127
+ this.nrrd_states.ratios.y = randomSlice.x.volume.spacing[1];
128
+ this.nrrd_states.ratios.z = randomSlice.x.volume.spacing[2];
129
+ this.nrrd_states.dimensions = randomSlice.x.volume.dimensions;
130
+ this.nrrd_states.spaceOrigin = randomSlice.x.volume.header.space_origin.map((item) => {
131
+ return item * 1;
132
+ });
133
+ this.protectedData.allSlicesArray.forEach((item, index) => {
134
+ item.x.contrastOrder = index;
135
+ item.y.contrastOrder = index;
136
+ item.z.contrastOrder = index;
137
+ });
138
+ this.nrrd_states.sharedPlace.x = this.getSharedPlace(this.nrrd_states.dimensions[0], this.nrrd_states.ratios.x);
139
+ this.nrrd_states.sharedPlace.y = this.getSharedPlace(this.nrrd_states.dimensions[1], this.nrrd_states.ratios.y);
140
+ this.nrrd_states.sharedPlace.z = this.getSharedPlace(this.nrrd_states.dimensions[2], this.nrrd_states.ratios.z);
141
+ // init paintImages array
142
+ this.initPaintImages(this.nrrd_states.dimensions);
143
+ // init displayslices array, the axis default is "z"
144
+ this.setDisplaySlicesBaseOnAxis();
145
+ this.afterLoadSlice();
146
+ }
147
+ loadingMaskByLabel(masks, index, imageData) {
148
+ let imageDataLable = this.protectedData.ctxes.emptyCtx.createImageData(this.nrrd_states.nrrd_x_pixel, this.nrrd_states.nrrd_y_pixel);
149
+ this.setEmptyCanvasSize();
150
+ for (let j = 0; j < masks[index].data.length; j++) {
151
+ imageDataLable.data[j] = masks[index].data[j];
152
+ imageData.data[j] += masks[index].data[j];
153
+ }
154
+ return imageDataLable;
155
+ }
156
+ setMasksData(masksData, loadingBar) {
157
+ if (!!masksData) {
158
+ this.nrrd_states.loadMaskJson = true;
159
+ if (loadingBar) {
160
+ let { loadingContainer, progress } = loadingBar;
161
+ loadingContainer.style.display = "flex";
162
+ progress.innerText = "Loading masks data......";
163
+ }
164
+ this.setEmptyCanvasSize();
165
+ const len = masksData["label1"].length;
166
+ for (let i = 0; i < len; i++) {
167
+ let imageData = this.protectedData.ctxes.emptyCtx.createImageData(this.nrrd_states.nrrd_x_pixel, this.nrrd_states.nrrd_y_pixel);
168
+ let imageDataLabel1, imageDataLabel2, imageDataLabel3;
169
+ if (masksData["label1"][i].data.length > 0) {
170
+ this.setEmptyCanvasSize();
171
+ imageDataLabel1 = this.loadingMaskByLabel(masksData["label1"], i, imageData);
172
+ this.protectedData.ctxes.emptyCtx.putImageData(imageDataLabel1, 0, 0);
173
+ this.storeEachLayerImage(i, "label1");
174
+ }
175
+ if (masksData["label2"][i].data.length > 0) {
176
+ this.setEmptyCanvasSize();
177
+ imageDataLabel2 = this.loadingMaskByLabel(masksData["label2"], i, imageData);
178
+ this.protectedData.ctxes.emptyCtx.putImageData(imageDataLabel2, 0, 0);
179
+ this.storeEachLayerImage(i, "label2");
180
+ }
181
+ if (masksData["label3"][i].data.length > 0) {
182
+ this.setEmptyCanvasSize();
183
+ imageDataLabel3 = this.loadingMaskByLabel(masksData["label3"], i, imageData);
184
+ this.protectedData.ctxes.emptyCtx.putImageData(imageDataLabel3, 0, 0);
185
+ this.storeEachLayerImage(i, "label3");
186
+ }
187
+ this.setEmptyCanvasSize();
188
+ this.protectedData.ctxes.emptyCtx.putImageData(imageData, 0, 0);
189
+ this.storeAllImages(i, "default");
190
+ }
191
+ this.nrrd_states.loadMaskJson = false;
192
+ this.gui_states.resetZoom();
193
+ if (loadingBar) {
194
+ loadingBar.loadingContainer.style.display = "none";
195
+ }
196
+ }
197
+ }
198
+ setShowInMainArea() {
199
+ this.nrrd_states.showContrast = true;
200
+ }
201
+ getCurrentImageDimension() {
202
+ return this.nrrd_states.dimensions;
203
+ }
204
+ getVoxelSpacing() {
205
+ return this.nrrd_states.voxelSpacing;
206
+ }
207
+ getSpaceOrigin() {
208
+ return this.nrrd_states.spaceOrigin;
209
+ }
210
+ getMaskData() {
211
+ return this.protectedData.maskData;
212
+ }
213
+ getSharedPlace(len, ratio) {
214
+ let old = -1;
215
+ let same = [];
216
+ let temp = new Set();
217
+ for (let i = 0; i < len; i++) {
218
+ const index = Math.floor(i * ratio);
219
+ if (index === old) {
220
+ temp.add(i - 1);
221
+ temp.add(i);
222
+ }
223
+ else {
224
+ old = index;
225
+ }
226
+ }
227
+ temp.forEach((value) => {
228
+ same.push(value);
229
+ });
230
+ return same;
231
+ }
232
+ /**
233
+ * init all painted images for store images
234
+ * @param dimensions
235
+ */
236
+ initPaintImages(dimensions) {
237
+ this.createEmptyPaintImage(dimensions, this.protectedData.maskData.paintImages);
238
+ this.createEmptyPaintImage(dimensions, this.protectedData.maskData.paintImagesLabel1);
239
+ this.createEmptyPaintImage(dimensions, this.protectedData.maskData.paintImagesLabel2);
240
+ this.createEmptyPaintImage(dimensions, this.protectedData.maskData.paintImagesLabel3);
241
+ }
242
+ createEmptyPaintImage(dimensions, paintImages) {
243
+ for (let i = 0; i < dimensions[0]; i++) {
244
+ const markImage_x = this.protectedData.ctxes.emptyCtx.createImageData(this.nrrd_states.nrrd_z_pixel, this.nrrd_states.nrrd_y_pixel);
245
+ const initMark_x = {
246
+ index: i,
247
+ image: markImage_x,
248
+ };
249
+ paintImages.x.push(initMark_x);
250
+ }
251
+ // for y slices' marks
252
+ for (let i = 0; i < dimensions[1]; i++) {
253
+ const markImage_y = this.protectedData.ctxes.emptyCtx.createImageData(this.nrrd_states.nrrd_x_pixel, this.nrrd_states.nrrd_z_pixel);
254
+ const initMark_y = {
255
+ index: i,
256
+ image: markImage_y,
257
+ };
258
+ paintImages.y.push(initMark_y);
259
+ }
260
+ // for z slices' marks
261
+ for (let i = 0; i < dimensions[2]; i++) {
262
+ const markImage_z = this.protectedData.ctxes.emptyCtx.createImageData(this.nrrd_states.nrrd_x_pixel, this.nrrd_states.nrrd_y_pixel);
263
+ const initMark_z = {
264
+ index: i,
265
+ image: markImage_z,
266
+ };
267
+ paintImages.z.push(initMark_z);
268
+ }
269
+ }
270
+ /**
271
+ * We generate the MRI slice from threejs based on mm, but when we display it is based on pixel size/distance.
272
+ * So, the index munber on each axis (sagittal, axial, coronal) is the slice's depth in mm distance. And the width and height displayed on screen is the slice's width and height in pixel distance.
273
+ *
274
+ * When we switch into different axis' views, we need to convert current view's the depth to the pixel distance in other views width or height, and convert the current view's width or height from pixel distance to mm distance as other views' depth (slice index) in general.
275
+ *
276
+ * Then as for the crosshair (Cursor Inspector), we also need to convert the cursor point (x, y, z) to other views' (x, y, z).
277
+ *
278
+ * @param from "x" | "y" | "z", current view axis, "x: sagittle, y: coronal, z: axial".
279
+ * @param to "x" | "y" | "z", target view axis (where you want jump to), "x: sagittle, y: coronal, z: axial".
280
+ * @param cursorNumX number, cursor point x on current axis's slice. (pixel distance)
281
+ * @param cursorNumY number, cursor point y on current axis's slice. (pixel distance)
282
+ * @param currentSliceIndex number, current axis's slice's index/depth. (mm distance)
283
+ * @returns
284
+ */
285
+ convertCursorPoint(from, to, cursorNumX, cursorNumY, currentSliceIndex) {
286
+ const nrrd = this.nrrd_states;
287
+ const dimensions = nrrd.dimensions;
288
+ const ratios = nrrd.ratios;
289
+ const { nrrd_x_mm, nrrd_y_mm, nrrd_z_mm } = nrrd;
290
+ let currentIndex = 0;
291
+ let oldIndex = 0;
292
+ let convertCursorNumX = 0;
293
+ let convertCursorNumY = 0;
294
+ const convertIndex = {
295
+ x: {
296
+ y: (val) => Math.ceil((val / nrrd_x_mm) * dimensions[0]),
297
+ z: (val) => Math.ceil((val / nrrd_z_mm) * dimensions[2]),
298
+ },
299
+ y: {
300
+ x: (val) => Math.ceil((val / nrrd_y_mm) * dimensions[1]),
301
+ z: (val) => Math.ceil((val / nrrd_z_mm) * dimensions[2]),
302
+ },
303
+ z: {
304
+ x: (val) => Math.ceil((val / nrrd_x_mm) * dimensions[0]),
305
+ y: (val) => Math.ceil((val / nrrd_y_mm) * dimensions[1]),
306
+ },
307
+ };
308
+ const convertCursor = {
309
+ x: {
310
+ y: (sliceIndex) => Math.ceil((sliceIndex / dimensions[0]) * nrrd_x_mm),
311
+ z: (sliceIndex) => Math.ceil((sliceIndex / dimensions[0]) * nrrd_x_mm),
312
+ },
313
+ y: {
314
+ x: (sliceIndex) => Math.ceil((sliceIndex / dimensions[1]) * nrrd_y_mm),
315
+ z: (sliceIndex) => Math.ceil((sliceIndex / dimensions[1]) * nrrd_y_mm),
316
+ },
317
+ z: {
318
+ x: (sliceIndex) => Math.ceil((sliceIndex / dimensions[2]) * nrrd_z_mm),
319
+ y: (sliceIndex) => Math.ceil((sliceIndex / dimensions[2]) * nrrd_z_mm),
320
+ },
321
+ };
322
+ if (from === to) {
323
+ return;
324
+ }
325
+ if (from === "z" && to === "x") {
326
+ currentIndex = convertIndex[from][to](cursorNumX);
327
+ oldIndex = currentIndex * ratios[to];
328
+ convertCursorNumX = convertCursor[from][to](currentSliceIndex);
329
+ convertCursorNumY = cursorNumY;
330
+ }
331
+ else if (from === "y" && to === "x") {
332
+ currentIndex = convertIndex[from][to](cursorNumX);
333
+ oldIndex = currentIndex * ratios.x;
334
+ convertCursorNumY = convertCursor[from][to](currentSliceIndex);
335
+ convertCursorNumX = cursorNumY;
336
+ }
337
+ else if (from === "z" && to === "y") {
338
+ currentIndex = convertIndex[from][to](cursorNumY);
339
+ oldIndex = currentIndex * ratios[to];
340
+ convertCursorNumY = convertCursor[from][to](currentSliceIndex);
341
+ convertCursorNumX = cursorNumX;
342
+ }
343
+ else if (from === "x" && to === "y") {
344
+ currentIndex = convertIndex[from][to](cursorNumY);
345
+ oldIndex = currentIndex * ratios[to];
346
+ convertCursorNumX = convertCursor[from][to](currentSliceIndex);
347
+ convertCursorNumY = cursorNumX;
348
+ }
349
+ else if (from === "x" && to === "z") {
350
+ currentIndex = convertIndex[from][to](cursorNumX);
351
+ oldIndex = currentIndex * ratios[to];
352
+ convertCursorNumX = convertCursor[from][to](currentSliceIndex);
353
+ convertCursorNumY = cursorNumY;
354
+ }
355
+ else if (from === "y" && to === "z") {
356
+ currentIndex = convertIndex[from][to](cursorNumY);
357
+ oldIndex = currentIndex * ratios.z;
358
+ convertCursorNumY = convertCursor[from][to](currentSliceIndex);
359
+ convertCursorNumX = cursorNumX;
360
+ }
361
+ else {
362
+ return;
363
+ }
364
+ return { currentIndex, oldIndex, convertCursorNumX, convertCursorNumY };
365
+ }
366
+ /**
367
+ * Switch all contrast slices' orientation
368
+ * @param {string} aixs:"x" | "y" | "z"
369
+ * */
370
+ setSliceOrientation(axisTo) {
371
+ let convetObj;
372
+ if (this.nrrd_states.enableCursorChoose || this.gui_states.sphere) {
373
+ if (this.protectedData.axis === "z") {
374
+ this.cursorPage.z.index = this.nrrd_states.currentIndex;
375
+ this.cursorPage.z.cursorPageX = this.nrrd_states.cursorPageX;
376
+ this.cursorPage.z.cursorPageY = this.nrrd_states.cursorPageY;
377
+ }
378
+ else if (this.protectedData.axis === "x") {
379
+ this.cursorPage.x.index = this.nrrd_states.currentIndex;
380
+ this.cursorPage.x.cursorPageX = this.nrrd_states.cursorPageX;
381
+ this.cursorPage.x.cursorPageY = this.nrrd_states.cursorPageY;
382
+ }
383
+ else if (this.protectedData.axis === "y") {
384
+ this.cursorPage.y.index = this.nrrd_states.currentIndex;
385
+ this.cursorPage.y.cursorPageX = this.nrrd_states.cursorPageX;
386
+ this.cursorPage.y.cursorPageY = this.nrrd_states.cursorPageY;
387
+ }
388
+ if (axisTo === "z") {
389
+ if (this.nrrd_states.isCursorSelect && !this.cursorPage.z.updated) {
390
+ if (this.protectedData.axis === "x") {
391
+ // convert x to z
392
+ convetObj = this.convertCursorPoint("x", "z", this.cursorPage.x.cursorPageX, this.cursorPage.x.cursorPageY, this.cursorPage.x.index);
393
+ }
394
+ if (this.protectedData.axis === "y") {
395
+ // convert y to z
396
+ convetObj = this.convertCursorPoint("y", "z", this.cursorPage.y.cursorPageX, this.cursorPage.y.cursorPageY, this.cursorPage.y.index);
397
+ }
398
+ }
399
+ else {
400
+ // not cursor select, freedom to switch x -> z or y -> z and z -> x or z -> y
401
+ this.nrrd_states.currentIndex = this.cursorPage.z.index;
402
+ this.nrrd_states.oldIndex =
403
+ this.cursorPage.z.index * this.nrrd_states.ratios.z;
404
+ this.nrrd_states.cursorPageX = this.cursorPage.z.cursorPageX;
405
+ this.nrrd_states.cursorPageY = this.cursorPage.z.cursorPageY;
406
+ }
407
+ }
408
+ else if (axisTo === "x") {
409
+ if (this.nrrd_states.isCursorSelect && !this.cursorPage.x.updated) {
410
+ if (this.protectedData.axis === "z") {
411
+ // convert z to x
412
+ convetObj = this.convertCursorPoint("z", "x", this.cursorPage.z.cursorPageX, this.cursorPage.z.cursorPageY, this.cursorPage.z.index);
413
+ }
414
+ if (this.protectedData.axis === "y") {
415
+ // convert y to x
416
+ convetObj = this.convertCursorPoint("y", "x", this.cursorPage.y.cursorPageX, this.cursorPage.y.cursorPageY, this.cursorPage.y.index);
417
+ }
418
+ }
419
+ else {
420
+ // not cursor select, freedom to switch z -> x or y -> x and x -> z or x -> y
421
+ this.nrrd_states.currentIndex = this.cursorPage.x.index;
422
+ this.nrrd_states.oldIndex =
423
+ this.cursorPage.x.index * this.nrrd_states.ratios.x;
424
+ this.nrrd_states.cursorPageX = this.cursorPage.x.cursorPageX;
425
+ this.nrrd_states.cursorPageY = this.cursorPage.x.cursorPageY;
426
+ }
427
+ }
428
+ else if (axisTo === "y") {
429
+ if (this.nrrd_states.isCursorSelect && !this.cursorPage.y.updated) {
430
+ if (this.protectedData.axis === "z") {
431
+ // convert z to y
432
+ convetObj = this.convertCursorPoint("z", "y", this.cursorPage.z.cursorPageX, this.cursorPage.z.cursorPageY, this.cursorPage.z.index);
433
+ }
434
+ if (this.protectedData.axis === "x") {
435
+ // convert x to y
436
+ convetObj = this.convertCursorPoint("x", "y", this.cursorPage.x.cursorPageX, this.cursorPage.x.cursorPageY, this.cursorPage.x.index);
437
+ }
438
+ }
439
+ else {
440
+ // not cursor select, freedom to switch z -> y or x -> y and y -> z or y -> x
441
+ this.nrrd_states.currentIndex = this.cursorPage.y.index;
442
+ this.nrrd_states.oldIndex =
443
+ this.cursorPage.y.index * this.nrrd_states.ratios.y;
444
+ this.nrrd_states.cursorPageX = this.cursorPage.y.cursorPageX;
445
+ this.nrrd_states.cursorPageY = this.cursorPage.y.cursorPageY;
446
+ }
447
+ }
448
+ if (convetObj) {
449
+ // update convert cursor point, when cursor select
450
+ this.nrrd_states.currentIndex = convetObj.currentIndex;
451
+ this.nrrd_states.oldIndex = convetObj.oldIndex;
452
+ this.nrrd_states.cursorPageX = convetObj.convertCursorNumX;
453
+ this.nrrd_states.cursorPageY = convetObj.convertCursorNumY;
454
+ convetObj = undefined;
455
+ switch (axisTo) {
456
+ case "x":
457
+ this.cursorPage.x.updated = true;
458
+ break;
459
+ case "y":
460
+ this.cursorPage.y.updated = true;
461
+ break;
462
+ case "z":
463
+ this.cursorPage.z.updated = true;
464
+ break;
465
+ }
466
+ }
467
+ if (this.cursorPage.x.updated &&
468
+ this.cursorPage.y.updated &&
469
+ this.cursorPage.z.updated) {
470
+ // one point convert to all axis, reset all updated status
471
+ this.nrrd_states.isCursorSelect = false;
472
+ }
473
+ }
474
+ this.protectedData.axis = axisTo;
475
+ this.resetDisplaySlicesStatus();
476
+ // for sphere plan a
477
+ if (this.gui_states.sphere && !this.nrrd_states.spherePlanB) {
478
+ this.drawSphere(this.nrrd_states.sphereOrigin[axisTo][0], this.nrrd_states.sphereOrigin[axisTo][1], this.nrrd_states.sphereRadius);
479
+ }
480
+ }
481
+ addSkip(index) {
482
+ this.protectedData.skipSlicesDic[index] =
483
+ this.protectedData.backUpDisplaySlices[index];
484
+ if (index >= this.protectedData.displaySlices.length) {
485
+ this.nrrd_states.contrastNum = this.protectedData.displaySlices.length;
486
+ }
487
+ else {
488
+ this.nrrd_states.contrastNum = index;
489
+ }
490
+ this.resetDisplaySlicesStatus();
491
+ }
492
+ removeSkip(index) {
493
+ this.protectedData.skipSlicesDic[index] = undefined;
494
+ this.nrrd_states.contrastNum = 0;
495
+ this.resetDisplaySlicesStatus();
496
+ }
497
+ clear() {
498
+ // To effectively reduce the js memory garbage
499
+ this.protectedData.allSlicesArray.length = 0;
500
+ this.protectedData.displaySlices.length = 0;
501
+ this.undoArray.length = 0;
502
+ this.protectedData.maskData.paintImages.x.length = 0;
503
+ this.protectedData.maskData.paintImages.y.length = 0;
504
+ this.protectedData.maskData.paintImages.z.length = 0;
505
+ this.protectedData.maskData.paintImagesLabel1.x.length = 0;
506
+ this.protectedData.maskData.paintImagesLabel1.y.length = 0;
507
+ this.protectedData.maskData.paintImagesLabel1.z.length = 0;
508
+ this.protectedData.maskData.paintImagesLabel2.x.length = 0;
509
+ this.protectedData.maskData.paintImagesLabel2.y.length = 0;
510
+ this.protectedData.maskData.paintImagesLabel2.z.length = 0;
511
+ this.protectedData.maskData.paintImagesLabel3.x.length = 0;
512
+ this.protectedData.maskData.paintImagesLabel3.y.length = 0;
513
+ this.protectedData.maskData.paintImagesLabel3.z.length = 0;
514
+ this.clearDictionary(this.protectedData.skipSlicesDic);
515
+ // this.nrrd_states.previousPanelL = this.nrrd_states.previousPanelT = -99999;
516
+ this.protectedData.canvases.displayCanvas.style.left =
517
+ this.protectedData.canvases.drawingCanvas.style.left = "";
518
+ this.protectedData.canvases.displayCanvas.style.top =
519
+ this.protectedData.canvases.drawingCanvas.style.top = "";
520
+ this.protectedData.backUpDisplaySlices.length = 0;
521
+ this.protectedData.mainPreSlices = undefined;
522
+ this.protectedData.currentShowingSlice = undefined;
523
+ this.protectedData.previousDrawingImage =
524
+ this.protectedData.ctxes.emptyCtx.createImageData(1, 1);
525
+ this.initState = true;
526
+ this.protectedData.axis = "z";
527
+ this.nrrd_states.sizeFoctor = this.baseCanvasesSize;
528
+ this.gui_states.mainAreaSize = this.baseCanvasesSize;
529
+ this.resetLayerCanvas();
530
+ this.protectedData.canvases.drawingCanvas.width =
531
+ this.protectedData.canvases.drawingCanvas.width;
532
+ this.protectedData.canvases.displayCanvas.width =
533
+ this.protectedData.canvases.displayCanvas.width;
534
+ }
535
+ setSliceMoving(step) {
536
+ if (this.protectedData.mainPreSlices) {
537
+ this.protectedData.Is_Draw = true;
538
+ this.setSyncsliceNum();
539
+ this.dragOperator.updateIndex(step);
540
+ this.setIsDrawFalse(1000);
541
+ }
542
+ }
543
+ setMainAreaSize(factor) {
544
+ this.nrrd_states.sizeFoctor = factor;
545
+ if (this.nrrd_states.sizeFoctor >= 8) {
546
+ this.nrrd_states.sizeFoctor = 8;
547
+ }
548
+ else if (this.nrrd_states.sizeFoctor <= 1) {
549
+ this.nrrd_states.sizeFoctor = 1;
550
+ }
551
+ this.resizePaintArea(this.nrrd_states.sizeFoctor);
552
+ this.resetPaintAreaUIPosition();
553
+ // this.setIsDrawFalse(1000);
554
+ }
555
+ getContainer() {
556
+ return this.protectedData.mainAreaContainer;
557
+ }
558
+ getDrawingCanvas() {
559
+ return this.protectedData.canvases.drawingCanvas;
560
+ }
561
+ getNrrdToolsSettings() {
562
+ return this.nrrd_states;
563
+ }
564
+ getMaxSliceNum() {
565
+ if (this.nrrd_states.showContrast) {
566
+ return [
567
+ this.nrrd_states.maxIndex,
568
+ this.nrrd_states.maxIndex * this.protectedData.displaySlices.length,
569
+ ];
570
+ }
571
+ else {
572
+ return [this.nrrd_states.maxIndex];
573
+ }
574
+ }
575
+ getCurrentSlicesNumAndContrastNum() {
576
+ return {
577
+ currentIndex: this.nrrd_states.currentIndex,
578
+ contrastIndex: this.nrrd_states.contrastNum,
579
+ };
580
+ }
581
+ getCurrentSliceIndex() {
582
+ return Math.ceil(this.protectedData.mainPreSlices.index / this.nrrd_states.RSARatio);
583
+ }
584
+ getIsShowContrastState() {
585
+ return this.nrrd_states.showContrast;
586
+ }
587
+ /**
588
+ * Give a delay time to finish the last drawing before upcoming interrupt opreations.
589
+ * Give a delay time number (ms) to disable the draw function,
590
+ * After your interrupt opeartion, you should enable the draw fucntion.
591
+ * @param target number
592
+ */
593
+ setIsDrawFalse(target) {
594
+ this.preTimer = setTimeout(() => {
595
+ this.protectedData.Is_Draw = false;
596
+ if (this.preTimer) {
597
+ window.clearTimeout(this.preTimer);
598
+ this.preTimer = undefined;
599
+ }
600
+ }, target);
601
+ }
602
+ setDisplaySlicesBaseOnAxis() {
603
+ this.protectedData.displaySlices.length = 0;
604
+ this.protectedData.backUpDisplaySlices.length = 0;
605
+ this.protectedData.allSlicesArray.forEach((slices) => {
606
+ this.protectedData.backUpDisplaySlices.push(slices[this.protectedData.axis]);
607
+ });
608
+ this.loadDisplaySlicesArray();
609
+ }
610
+ loadDisplaySlicesArray() {
611
+ const remainSlices = Object.values(this.protectedData.skipSlicesDic);
612
+ if (remainSlices.length === 0) {
613
+ // load all display slices
614
+ this.protectedData.backUpDisplaySlices.forEach((slice, index) => {
615
+ this.protectedData.skipSlicesDic[index] = slice;
616
+ this.protectedData.displaySlices.push(slice);
617
+ });
618
+ }
619
+ else {
620
+ remainSlices.forEach((slice, index) => {
621
+ if (!!slice) {
622
+ this.protectedData.displaySlices.push(this.protectedData.backUpDisplaySlices[index]);
623
+ this.protectedData.skipSlicesDic[index] =
624
+ this.protectedData.backUpDisplaySlices[index];
625
+ }
626
+ });
627
+ }
628
+ }
629
+ switchAllSlicesArrayData(allSlices) {
630
+ this.protectedData.allSlicesArray.length = 0;
631
+ this.protectedData.allSlicesArray = [...allSlices];
632
+ this.resetDisplaySlicesStatus();
633
+ }
634
+ resetDisplaySlicesStatus() {
635
+ // reload slice data
636
+ this.setDisplaySlicesBaseOnAxis();
637
+ // reset canvas attribute for drag and draw
638
+ this.setupConfigs();
639
+ }
640
+ setupConfigs() {
641
+ // reset main slice
642
+ this.setMainPreSlice();
643
+ // update the max index for drag and slider
644
+ this.updateMaxIndex();
645
+ // reset origin canvas and the nrrd_states origin Width/height
646
+ // reset the current index
647
+ this.setOriginCanvasAndPre();
648
+ // update the show number div on top area
649
+ this.dragOperator.updateShowNumDiv(this.nrrd_states.contrastNum);
650
+ // repaint all contrast images
651
+ this.repraintCurrentContrastSlice();
652
+ // resize the draw/drawOutLayer/display canvas size
653
+ this.resizePaintArea(this.nrrd_states.sizeFoctor);
654
+ this.resetPaintAreaUIPosition();
655
+ }
656
+ setMainPreSlice() {
657
+ this.protectedData.mainPreSlices = this.protectedData.displaySlices[0];
658
+ if (this.protectedData.mainPreSlices) {
659
+ this.nrrd_states.RSARatio = this.protectedData.mainPreSlices.RSARatio;
660
+ }
661
+ }
662
+ setOriginCanvasAndPre() {
663
+ if (this.protectedData.mainPreSlices) {
664
+ if (this.nrrd_states.oldIndex > this.nrrd_states.maxIndex)
665
+ this.nrrd_states.oldIndex = this.nrrd_states.maxIndex;
666
+ if (this.initState) {
667
+ this.nrrd_states.oldIndex =
668
+ this.protectedData.mainPreSlices.initIndex *
669
+ this.nrrd_states.RSARatio;
670
+ this.nrrd_states.currentIndex =
671
+ this.protectedData.mainPreSlices.initIndex;
672
+ }
673
+ else {
674
+ // !need to change
675
+ // todo
676
+ this.protectedData.mainPreSlices.index = this.nrrd_states.oldIndex;
677
+ }
678
+ this.protectedData.canvases.originCanvas =
679
+ this.protectedData.mainPreSlices.canvas;
680
+ this.updateOriginAndChangedWH();
681
+ }
682
+ }
683
+ afterLoadSlice() {
684
+ this.setMainPreSlice();
685
+ this.setOriginCanvasAndPre();
686
+ this.protectedData.currentShowingSlice = this.protectedData.mainPreSlices;
687
+ this.nrrd_states.oldIndex =
688
+ this.protectedData.mainPreSlices.initIndex * this.nrrd_states.RSARatio;
689
+ this.nrrd_states.currentIndex = this.protectedData.mainPreSlices.initIndex;
690
+ this.undoArray = [
691
+ {
692
+ sliceIndex: this.nrrd_states.currentIndex,
693
+ layers: { label1: [], label2: [], label3: [] },
694
+ },
695
+ ];
696
+ // compute max index
697
+ this.updateMaxIndex();
698
+ this.dragOperator.updateShowNumDiv(this.nrrd_states.contrastNum);
699
+ this.initState = false;
700
+ }
701
+ updateMaxIndex() {
702
+ if (this.protectedData.mainPreSlices) {
703
+ this.nrrd_states.maxIndex = this.protectedData.mainPreSlices.MaxIndex;
704
+ }
705
+ }
706
+ /**
707
+ * Update the original canvas size, allow set to threejs load one (pixel distance not the mm).
708
+ * Then update the changedWidth and changedHeight based on the sizeFoctor.
709
+ */
710
+ updateOriginAndChangedWH() {
711
+ this.nrrd_states.originWidth =
712
+ this.protectedData.canvases.originCanvas.width;
713
+ this.nrrd_states.originHeight =
714
+ this.protectedData.canvases.originCanvas.height;
715
+ this.nrrd_states.changedWidth =
716
+ this.nrrd_states.originWidth * Number(this.nrrd_states.sizeFoctor);
717
+ this.nrrd_states.changedHeight =
718
+ this.nrrd_states.originWidth * Number(this.nrrd_states.sizeFoctor);
719
+ this.resizePaintArea(this.nrrd_states.sizeFoctor);
720
+ this.resetPaintAreaUIPosition();
721
+ }
722
+ /**
723
+ * Keep all contrast slice index to same.
724
+ * Synchronize the slice indexes of all the contrasts so that they are consistent with the main slice's index.
725
+ */
726
+ setSyncsliceNum() {
727
+ this.protectedData.displaySlices.forEach((slice, index) => {
728
+ if (index !== 0) {
729
+ slice.index = this.protectedData.mainPreSlices.index;
730
+ }
731
+ });
732
+ }
733
+ appendLoadingbar(loadingbar) {
734
+ this.protectedData.mainAreaContainer.appendChild(loadingbar);
735
+ }
736
+ clearStoreImages() {
737
+ this.protectedData.maskData.paintImages.x.length = 0;
738
+ this.protectedData.maskData.paintImages.y.length = 0;
739
+ this.protectedData.maskData.paintImages.z.length = 0;
740
+ this.protectedData.maskData.paintImagesLabel1.x.length = 0;
741
+ this.protectedData.maskData.paintImagesLabel1.y.length = 0;
742
+ this.protectedData.maskData.paintImagesLabel1.z.length = 0;
743
+ this.protectedData.maskData.paintImagesLabel2.x.length = 0;
744
+ this.protectedData.maskData.paintImagesLabel2.y.length = 0;
745
+ this.protectedData.maskData.paintImagesLabel2.z.length = 0;
746
+ this.protectedData.maskData.paintImagesLabel3.x.length = 0;
747
+ this.protectedData.maskData.paintImagesLabel3.y.length = 0;
748
+ this.protectedData.maskData.paintImagesLabel3.z.length = 0;
749
+ this.initPaintImages(this.nrrd_states.dimensions);
750
+ }
751
+ /**
752
+ * Reset the draw and display canvases layout after mouse pan.
753
+ * If no params in, then center the draw and display canvases.
754
+ * @param l number, Offset to the left
755
+ * @param t number, Offset to the top
756
+ */
757
+ resetPaintAreaUIPosition(l, t) {
758
+ if (l && t) {
759
+ this.protectedData.canvases.displayCanvas.style.left =
760
+ this.protectedData.canvases.drawingCanvas.style.left = l + "px";
761
+ this.protectedData.canvases.displayCanvas.style.top =
762
+ this.protectedData.canvases.drawingCanvas.style.top = t + "px";
763
+ }
764
+ else {
765
+ this.protectedData.canvases.displayCanvas.style.left =
766
+ this.protectedData.canvases.drawingCanvas.style.left = "";
767
+ this.protectedData.canvases.displayCanvas.style.top =
768
+ this.protectedData.canvases.drawingCanvas.style.top = "";
769
+ this.protectedData.mainAreaContainer.style.justifyContent = "center";
770
+ this.protectedData.mainAreaContainer.style.alignItems = "center";
771
+ }
772
+ }
773
+ /**
774
+ * Clear masks on drawingCanvas layers.
775
+ */
776
+ resetLayerCanvas() {
777
+ this.protectedData.canvases.drawingCanvasLayerMaster.width =
778
+ this.protectedData.canvases.drawingCanvasLayerMaster.width;
779
+ this.protectedData.canvases.drawingCanvasLayerOne.width =
780
+ this.protectedData.canvases.drawingCanvasLayerOne.width;
781
+ this.protectedData.canvases.drawingCanvasLayerTwo.width =
782
+ this.protectedData.canvases.drawingCanvasLayerTwo.width;
783
+ this.protectedData.canvases.drawingCanvasLayerThree.width =
784
+ this.protectedData.canvases.drawingCanvasLayerThree.width;
785
+ }
786
+ redrawMianPreOnDisplayCanvas() {
787
+ var _a;
788
+ this.protectedData.canvases.displayCanvas.width =
789
+ this.protectedData.canvases.displayCanvas.width;
790
+ this.protectedData.canvases.displayCanvas.height =
791
+ this.protectedData.canvases.displayCanvas.height;
792
+ this.protectedData.canvases.originCanvas.width =
793
+ this.protectedData.canvases.originCanvas.width;
794
+ if (this.protectedData.mainPreSlices) {
795
+ this.protectedData.mainPreSlices.repaint.call(this.protectedData.mainPreSlices);
796
+ this.flipDisplayImageByAxis();
797
+ (_a = this.protectedData.ctxes.displayCtx) === null || _a === void 0 ? void 0 : _a.drawImage(this.protectedData.canvases.originCanvas, 0, 0, this.nrrd_states.changedWidth, this.nrrd_states.changedHeight);
798
+ this.resizePaintArea(this.nrrd_states.sizeFoctor);
799
+ }
800
+ }
801
+ /**
802
+ * Resize the draw and display canvas size based on the input size factor number.
803
+ * @param factor number
804
+ */
805
+ resizePaintArea(factor) {
806
+ /**
807
+ * clear canvas
808
+ */
809
+ this.protectedData.canvases.originCanvas.width =
810
+ this.protectedData.canvases.originCanvas.width;
811
+ this.protectedData.canvases.displayCanvas.width =
812
+ this.protectedData.canvases.displayCanvas.width;
813
+ this.protectedData.canvases.drawingCanvas.width =
814
+ this.protectedData.canvases.drawingCanvas.width;
815
+ this.resetLayerCanvas();
816
+ this.nrrd_states.changedWidth = this.nrrd_states.originWidth * factor;
817
+ this.nrrd_states.changedHeight = this.nrrd_states.originHeight * factor;
818
+ /**
819
+ * resize canvas
820
+ */
821
+ this.protectedData.canvases.displayCanvas.width =
822
+ this.nrrd_states.changedWidth;
823
+ this.protectedData.canvases.displayCanvas.height =
824
+ this.nrrd_states.changedHeight;
825
+ this.protectedData.canvases.drawingCanvas.width =
826
+ this.nrrd_states.changedWidth;
827
+ this.protectedData.canvases.drawingCanvas.height =
828
+ this.nrrd_states.changedHeight;
829
+ this.protectedData.canvases.drawingCanvasLayerMaster.width =
830
+ this.nrrd_states.changedWidth;
831
+ this.protectedData.canvases.drawingCanvasLayerMaster.height =
832
+ this.nrrd_states.changedHeight;
833
+ this.protectedData.canvases.drawingCanvasLayerOne.width =
834
+ this.nrrd_states.changedWidth;
835
+ this.protectedData.canvases.drawingCanvasLayerOne.height =
836
+ this.nrrd_states.changedHeight;
837
+ this.protectedData.canvases.drawingCanvasLayerTwo.width =
838
+ this.nrrd_states.changedWidth;
839
+ this.protectedData.canvases.drawingCanvasLayerTwo.height =
840
+ this.nrrd_states.changedHeight;
841
+ this.protectedData.canvases.drawingCanvasLayerThree.width =
842
+ this.nrrd_states.changedWidth;
843
+ this.protectedData.canvases.drawingCanvasLayerThree.height =
844
+ this.nrrd_states.changedHeight;
845
+ this.redrawDisplayCanvas();
846
+ this.reloadMaskToLabel(this.protectedData.maskData.paintImages, this.protectedData.ctxes.drawingLayerMasterCtx);
847
+ this.reloadMaskToLabel(this.protectedData.maskData.paintImagesLabel1, this.protectedData.ctxes.drawingLayerOneCtx);
848
+ this.reloadMaskToLabel(this.protectedData.maskData.paintImagesLabel2, this.protectedData.ctxes.drawingLayerTwoCtx);
849
+ // need to check here again: why use ctx two not three. now modify to three
850
+ // this.reloadMaskToLabel(this.protectedData.maskData.paintImagesLabel3, this.protectedData.ctxes.drawingLayerTwoCtx);
851
+ this.reloadMaskToLabel(this.protectedData.maskData.paintImagesLabel3, this.protectedData.ctxes.drawingLayerThreeCtx);
852
+ }
853
+ /**
854
+ * Used to init the mask on each label and reload
855
+ * @param paintImages
856
+ * @param ctx
857
+ */
858
+ reloadMaskToLabel(paintImages, ctx) {
859
+ let paintedImage;
860
+ switch (this.protectedData.axis) {
861
+ case "x":
862
+ if (paintImages.x.length > 0) {
863
+ paintedImage = this.filterDrawedImage("x", this.nrrd_states.currentIndex, paintImages);
864
+ }
865
+ else {
866
+ paintedImage = undefined;
867
+ }
868
+ break;
869
+ case "y":
870
+ if (paintImages.y.length > 0) {
871
+ paintedImage = this.filterDrawedImage("y", this.nrrd_states.currentIndex, paintImages);
872
+ }
873
+ else {
874
+ paintedImage = undefined;
875
+ }
876
+ break;
877
+ case "z":
878
+ if (paintImages.z.length > 0) {
879
+ paintedImage = this.filterDrawedImage("z", this.nrrd_states.currentIndex, paintImages);
880
+ }
881
+ else {
882
+ paintedImage = undefined;
883
+ }
884
+ break;
885
+ }
886
+ if (paintedImage === null || paintedImage === void 0 ? void 0 : paintedImage.image) {
887
+ // redraw the stored data to empty point 1
888
+ this.setEmptyCanvasSize();
889
+ this.protectedData.ctxes.emptyCtx.putImageData(paintedImage.image, 0, 0);
890
+ ctx === null || ctx === void 0 ? void 0 : ctx.drawImage(this.protectedData.canvases.emptyCanvas, 0, 0, this.nrrd_states.changedWidth, this.nrrd_states.changedHeight);
891
+ }
892
+ }
893
+ /**
894
+ * flip the canvas to a correct position.
895
+ * This is because the slice canvas from threejs is not in a correct 2D postion.
896
+ * Thus, everytime when we redraw the display canvas, we need to flip to draw the origin canvas from threejs.
897
+ * Under different axis(sagittal, Axial, Coronal), the flip orientation is different.
898
+ */
899
+ flipDisplayImageByAxis() {
900
+ var _a, _b, _c, _d;
901
+ if (this.protectedData.axis === "x") {
902
+ (_a = this.protectedData.ctxes.displayCtx) === null || _a === void 0 ? void 0 : _a.scale(-1, -1);
903
+ (_b = this.protectedData.ctxes.displayCtx) === null || _b === void 0 ? void 0 : _b.translate(-this.nrrd_states.changedWidth, -this.nrrd_states.changedHeight);
904
+ }
905
+ else if (this.protectedData.axis === "z") {
906
+ (_c = this.protectedData.ctxes.displayCtx) === null || _c === void 0 ? void 0 : _c.scale(1, -1);
907
+ (_d = this.protectedData.ctxes.displayCtx) === null || _d === void 0 ? void 0 : _d.translate(0, -this.nrrd_states.changedHeight);
908
+ }
909
+ }
910
+ clearDictionary(dic) {
911
+ for (var key in dic) {
912
+ delete dic[key];
913
+ }
914
+ }
915
+ /**
916
+ * Set the empty canvas width and height based on the axis (pixel distance not the mm), to reduce duplicate codes.
917
+ *
918
+ * @param axis
919
+ */
920
+ setEmptyCanvasSize(axis) {
921
+ switch (!!axis ? axis : this.protectedData.axis) {
922
+ case "x":
923
+ this.protectedData.canvases.emptyCanvas.width =
924
+ this.nrrd_states.nrrd_z_pixel;
925
+ this.protectedData.canvases.emptyCanvas.height =
926
+ this.nrrd_states.nrrd_y_pixel;
927
+ break;
928
+ case "y":
929
+ this.protectedData.canvases.emptyCanvas.width =
930
+ this.nrrd_states.nrrd_x_pixel;
931
+ this.protectedData.canvases.emptyCanvas.height =
932
+ this.nrrd_states.nrrd_z_pixel;
933
+ break;
934
+ case "z":
935
+ this.protectedData.canvases.emptyCanvas.width =
936
+ this.nrrd_states.nrrd_x_pixel;
937
+ this.protectedData.canvases.emptyCanvas.height =
938
+ this.nrrd_states.nrrd_y_pixel;
939
+ break;
940
+ }
941
+ }
942
+ /******************************** redraw display canvas ***************************************/
943
+ /**
944
+ * Redraw current contrast image to display canvas.
945
+ * It is more related to change the contrast slice image's window width or center.
946
+ */
947
+ redrawDisplayCanvas() {
948
+ var _a, _b, _c;
949
+ this.dragOperator.updateCurrentContrastSlice();
950
+ this.protectedData.canvases.displayCanvas.width =
951
+ this.protectedData.canvases.displayCanvas.width;
952
+ this.protectedData.canvases.displayCanvas.height =
953
+ this.protectedData.canvases.displayCanvas.height;
954
+ this.protectedData.canvases.originCanvas.width =
955
+ this.protectedData.canvases.originCanvas.width;
956
+ if (this.protectedData.currentShowingSlice) {
957
+ this.protectedData.currentShowingSlice.repaint.call(this.protectedData.currentShowingSlice);
958
+ (_a = this.protectedData.ctxes.displayCtx) === null || _a === void 0 ? void 0 : _a.save();
959
+ this.flipDisplayImageByAxis();
960
+ (_b = this.protectedData.ctxes.displayCtx) === null || _b === void 0 ? void 0 : _b.drawImage(this.protectedData.currentShowingSlice.canvas, 0, 0, this.nrrd_states.changedWidth, this.nrrd_states.changedHeight);
961
+ (_c = this.protectedData.ctxes.displayCtx) === null || _c === void 0 ? void 0 : _c.restore();
962
+ }
963
+ }
964
+ }
965
+ //# sourceMappingURL=NrrdTools.js.map