copper3d 2.2.3 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1056 -5
- package/dist/Scene/copperScene.d.ts +3 -0
- package/dist/Scene/copperScene.js +13 -0
- package/dist/Scene/copperScene.js.map +1 -1
- package/dist/Utils/segmentation/CommToolsData.d.ts +109 -6
- package/dist/Utils/segmentation/CommToolsData.js +314 -50
- package/dist/Utils/segmentation/CommToolsData.js.map +1 -1
- package/dist/Utils/segmentation/DragOperator.d.ts +13 -7
- package/dist/Utils/segmentation/DragOperator.js +51 -165
- package/dist/Utils/segmentation/DragOperator.js.map +1 -1
- package/dist/Utils/segmentation/DrawToolCore.d.ts +57 -76
- package/dist/Utils/segmentation/DrawToolCore.js +368 -878
- package/dist/Utils/segmentation/DrawToolCore.js.map +1 -1
- package/dist/Utils/segmentation/NrrdTools.d.ts +277 -15
- package/dist/Utils/segmentation/NrrdTools.js +594 -232
- package/dist/Utils/segmentation/NrrdTools.js.map +1 -1
- package/dist/Utils/segmentation/core/MaskVolume.d.ts +477 -0
- package/dist/Utils/segmentation/core/MaskVolume.js +1238 -0
- package/dist/Utils/segmentation/core/MaskVolume.js.map +1 -0
- package/dist/Utils/segmentation/core/MigrationUtils.d.ts +97 -0
- package/dist/Utils/segmentation/core/MigrationUtils.js +163 -0
- package/dist/Utils/segmentation/core/MigrationUtils.js.map +1 -0
- package/dist/Utils/segmentation/core/UndoManager.d.ts +47 -0
- package/dist/Utils/segmentation/core/UndoManager.js +86 -0
- package/dist/Utils/segmentation/core/UndoManager.js.map +1 -0
- package/dist/Utils/segmentation/core/index.d.ts +76 -0
- package/dist/Utils/segmentation/core/index.js +75 -0
- package/dist/Utils/segmentation/core/index.js.map +1 -0
- package/dist/Utils/segmentation/core/types.d.ts +106 -0
- package/dist/Utils/segmentation/core/types.js +98 -0
- package/dist/Utils/segmentation/core/types.js.map +1 -0
- package/dist/Utils/segmentation/coreTools/coreType.d.ts +55 -36
- package/dist/Utils/segmentation/coreTools/coreType.js.map +1 -1
- package/dist/Utils/segmentation/coreTools/gui.d.ts +6 -16
- package/dist/Utils/segmentation/coreTools/gui.js +23 -27
- package/dist/Utils/segmentation/coreTools/gui.js.map +1 -1
- package/dist/Utils/segmentation/eventRouter/EventRouter.d.ts +144 -0
- package/dist/Utils/segmentation/eventRouter/EventRouter.js +369 -0
- package/dist/Utils/segmentation/eventRouter/EventRouter.js.map +1 -0
- package/dist/Utils/segmentation/eventRouter/index.d.ts +7 -0
- package/dist/Utils/segmentation/eventRouter/index.js +7 -0
- package/dist/Utils/segmentation/eventRouter/index.js.map +1 -0
- package/dist/Utils/segmentation/eventRouter/types.d.ts +70 -0
- package/dist/Utils/segmentation/eventRouter/types.js +7 -0
- package/dist/Utils/segmentation/eventRouter/types.js.map +1 -0
- package/dist/Utils/segmentation/tools/BaseTool.d.ts +25 -0
- package/dist/Utils/segmentation/tools/BaseTool.js +18 -0
- package/dist/Utils/segmentation/tools/BaseTool.js.map +1 -0
- package/dist/Utils/segmentation/tools/ContrastTool.d.ts +26 -0
- package/dist/Utils/segmentation/tools/ContrastTool.js +118 -0
- package/dist/Utils/segmentation/tools/ContrastTool.js.map +1 -0
- package/dist/Utils/segmentation/tools/CrosshairTool.d.ts +30 -0
- package/dist/Utils/segmentation/tools/CrosshairTool.js +157 -0
- package/dist/Utils/segmentation/tools/CrosshairTool.js.map +1 -0
- package/dist/Utils/segmentation/tools/DragSliceTool.d.ts +44 -0
- package/dist/Utils/segmentation/tools/DragSliceTool.js +170 -0
- package/dist/Utils/segmentation/tools/DragSliceTool.js.map +1 -0
- package/dist/Utils/segmentation/tools/EraserTool.d.ts +16 -0
- package/dist/Utils/segmentation/tools/EraserTool.js +92 -0
- package/dist/Utils/segmentation/tools/EraserTool.js.map +1 -0
- package/dist/Utils/segmentation/tools/ImageStoreHelper.d.ts +65 -0
- package/dist/Utils/segmentation/tools/ImageStoreHelper.js +174 -0
- package/dist/Utils/segmentation/tools/ImageStoreHelper.js.map +1 -0
- package/dist/Utils/segmentation/tools/SphereTool.d.ts +38 -0
- package/dist/Utils/segmentation/tools/SphereTool.js +193 -0
- package/dist/Utils/segmentation/tools/SphereTool.js.map +1 -0
- package/dist/Utils/segmentation/tools/ZoomTool.d.ts +20 -0
- package/dist/Utils/segmentation/tools/ZoomTool.js +59 -0
- package/dist/Utils/segmentation/tools/ZoomTool.js.map +1 -0
- package/dist/Utils/segmentation/tools/index.d.ts +22 -0
- package/dist/Utils/segmentation/tools/index.js +23 -0
- package/dist/Utils/segmentation/tools/index.js.map +1 -0
- package/dist/bundle.esm.js +4740 -1979
- package/dist/bundle.umd.js +4743 -1978
- package/dist/index.d.ts +5 -3
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/types/Renderer/copperRenderer.d.ts +1 -1
- package/dist/types/Renderer/copperRendererOnDemond.d.ts +1 -1
- package/dist/types/Scene/copperScene.d.ts +3 -0
- package/dist/types/Utils/segmentation/CommToolsData.d.ts +109 -6
- package/dist/types/Utils/segmentation/DragOperator.d.ts +13 -7
- package/dist/types/Utils/segmentation/DrawToolCore.d.ts +57 -76
- package/dist/types/Utils/segmentation/NrrdTools.d.ts +277 -15
- package/dist/types/Utils/segmentation/core/MaskVolume.d.ts +477 -0
- package/dist/types/Utils/segmentation/core/MigrationUtils.d.ts +97 -0
- package/dist/types/Utils/segmentation/core/UndoManager.d.ts +47 -0
- package/dist/types/Utils/segmentation/core/index.d.ts +76 -0
- package/dist/types/Utils/segmentation/core/types.d.ts +106 -0
- package/dist/types/Utils/segmentation/coreTools/coreType.d.ts +55 -36
- package/dist/types/Utils/segmentation/coreTools/gui.d.ts +6 -16
- package/dist/types/Utils/segmentation/eventRouter/EventRouter.d.ts +144 -0
- package/dist/types/Utils/segmentation/eventRouter/index.d.ts +7 -0
- package/dist/types/Utils/segmentation/eventRouter/types.d.ts +70 -0
- package/dist/types/Utils/segmentation/tools/BaseTool.d.ts +25 -0
- package/dist/types/Utils/segmentation/tools/ContrastTool.d.ts +26 -0
- package/dist/types/Utils/segmentation/tools/CrosshairTool.d.ts +30 -0
- package/dist/types/Utils/segmentation/tools/DragSliceTool.d.ts +44 -0
- package/dist/types/Utils/segmentation/tools/EraserTool.d.ts +16 -0
- package/dist/types/Utils/segmentation/tools/ImageStoreHelper.d.ts +65 -0
- package/dist/types/Utils/segmentation/tools/SphereTool.d.ts +38 -0
- package/dist/types/Utils/segmentation/tools/ZoomTool.d.ts +20 -0
- package/dist/types/Utils/segmentation/tools/index.d.ts +22 -0
- package/dist/types/index.d.ts +5 -3
- package/dist/types/types/types.d.ts +3 -3
- package/dist/types/types.d.ts +3 -3
- package/package.json +1 -1
- package/dist/Utils/segmentation/coreTools/archive.d.ts +0 -1
- package/dist/Utils/segmentation/coreTools/archive.js +0 -23
- package/dist/Utils/segmentation/coreTools/archive.js.map +0 -1
- package/dist/types/Utils/segmentation/coreTools/archive.d.ts +0 -1
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ContrastTool - Contrast adjustment event handlers
|
|
3
|
+
*
|
|
4
|
+
* Extracted from DrawToolCore.ts:
|
|
5
|
+
* - setupConrastEvents
|
|
6
|
+
* - configContrastDragMode / removeContrastDragMode
|
|
7
|
+
* - updateSlicesContrast / repraintCurrentContrastSlice
|
|
8
|
+
*/
|
|
9
|
+
import { BaseTool } from "./BaseTool";
|
|
10
|
+
import type { ToolContext } from "./BaseTool";
|
|
11
|
+
import type { IContrastEvents } from "../coreTools/coreType";
|
|
12
|
+
export interface ContrastCallbacks {
|
|
13
|
+
setIsDrawFalse: (target: number) => void;
|
|
14
|
+
setSyncsliceNum: () => void;
|
|
15
|
+
}
|
|
16
|
+
export declare class ContrastTool extends BaseTool {
|
|
17
|
+
private contrastEventPrameters;
|
|
18
|
+
private container;
|
|
19
|
+
private callbacks;
|
|
20
|
+
constructor(ctx: ToolContext, container: HTMLElement, contrastEventPrameters: IContrastEvents, callbacks: ContrastCallbacks);
|
|
21
|
+
setupConrastEvents(callback: (step: number, towards: "horizental" | "vertical") => void): void;
|
|
22
|
+
configContrastDragMode(): void;
|
|
23
|
+
removeContrastDragMode(): void;
|
|
24
|
+
updateSlicesContrast(value: number, flag: string): void;
|
|
25
|
+
repraintCurrentContrastSlice(): void;
|
|
26
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ContrastTool - Contrast adjustment event handlers
|
|
3
|
+
*
|
|
4
|
+
* Extracted from DrawToolCore.ts:
|
|
5
|
+
* - setupConrastEvents
|
|
6
|
+
* - configContrastDragMode / removeContrastDragMode
|
|
7
|
+
* - updateSlicesContrast / repraintCurrentContrastSlice
|
|
8
|
+
*/
|
|
9
|
+
import { BaseTool } from "./BaseTool";
|
|
10
|
+
import { throttle } from "../../utils";
|
|
11
|
+
export class ContrastTool extends BaseTool {
|
|
12
|
+
constructor(ctx, container, contrastEventPrameters, callbacks) {
|
|
13
|
+
super(ctx);
|
|
14
|
+
this.container = container;
|
|
15
|
+
this.contrastEventPrameters = contrastEventPrameters;
|
|
16
|
+
this.callbacks = callbacks;
|
|
17
|
+
}
|
|
18
|
+
// ===== Contrast Event Setup =====
|
|
19
|
+
setupConrastEvents(callback) {
|
|
20
|
+
this.contrastEventPrameters.w = this.container.offsetWidth;
|
|
21
|
+
this.contrastEventPrameters.h = this.container.offsetHeight;
|
|
22
|
+
this.contrastEventPrameters.handleOnContrastMouseDown = (ev) => {
|
|
23
|
+
if (ev.button === 0) {
|
|
24
|
+
this.contrastEventPrameters.x = ev.offsetX / this.contrastEventPrameters.x;
|
|
25
|
+
this.contrastEventPrameters.y = ev.offsetY / this.contrastEventPrameters.h;
|
|
26
|
+
this.container.addEventListener("pointermove", this.contrastEventPrameters.handleOnContrastMouseMove);
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
this.contrastEventPrameters.handleOnContrastMouseUp = (ev) => {
|
|
30
|
+
this.container.removeEventListener("pointermove", this.contrastEventPrameters.handleOnContrastMouseMove);
|
|
31
|
+
};
|
|
32
|
+
this.contrastEventPrameters.handleOnContrastMouseMove = throttle((ev) => {
|
|
33
|
+
if (this.contrastEventPrameters.y -
|
|
34
|
+
ev.offsetY / this.contrastEventPrameters.h >=
|
|
35
|
+
0) {
|
|
36
|
+
this.contrastEventPrameters.move_y = -Math.ceil((this.contrastEventPrameters.y -
|
|
37
|
+
ev.offsetY / this.contrastEventPrameters.h) *
|
|
38
|
+
10);
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
this.contrastEventPrameters.move_y = -Math.floor((this.contrastEventPrameters.y -
|
|
42
|
+
ev.offsetY / this.contrastEventPrameters.h) *
|
|
43
|
+
10);
|
|
44
|
+
}
|
|
45
|
+
if (this.contrastEventPrameters.move_y !== 0 &&
|
|
46
|
+
Math.abs(this.contrastEventPrameters.move_y) === 1) {
|
|
47
|
+
callback(this.contrastEventPrameters.move_y, "vertical");
|
|
48
|
+
}
|
|
49
|
+
if (this.contrastEventPrameters.x -
|
|
50
|
+
ev.offsetX / this.contrastEventPrameters.w >=
|
|
51
|
+
0) {
|
|
52
|
+
this.contrastEventPrameters.move_x = -Math.ceil((this.contrastEventPrameters.x -
|
|
53
|
+
ev.offsetX / this.contrastEventPrameters.w) *
|
|
54
|
+
10);
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
this.contrastEventPrameters.move_x = -Math.floor((this.contrastEventPrameters.x -
|
|
58
|
+
ev.offsetX / this.contrastEventPrameters.w) *
|
|
59
|
+
10);
|
|
60
|
+
}
|
|
61
|
+
if (this.contrastEventPrameters.move_x !== 0 &&
|
|
62
|
+
Math.abs(this.contrastEventPrameters.move_x) === 1) {
|
|
63
|
+
callback(this.contrastEventPrameters.move_x, "horizental");
|
|
64
|
+
}
|
|
65
|
+
this.contrastEventPrameters.x =
|
|
66
|
+
ev.offsetX / this.contrastEventPrameters.w;
|
|
67
|
+
this.contrastEventPrameters.y =
|
|
68
|
+
ev.offsetY / this.contrastEventPrameters.h;
|
|
69
|
+
}, 100);
|
|
70
|
+
}
|
|
71
|
+
// ===== Contrast Drag Mode =====
|
|
72
|
+
configContrastDragMode() {
|
|
73
|
+
this.container.style.cursor = "pointer";
|
|
74
|
+
this.container.addEventListener("pointerdown", this.contrastEventPrameters.handleOnContrastMouseDown, true);
|
|
75
|
+
this.container.addEventListener("pointerup", this.contrastEventPrameters.handleOnContrastMouseUp, true);
|
|
76
|
+
}
|
|
77
|
+
removeContrastDragMode() {
|
|
78
|
+
this.container.style.cursor = "";
|
|
79
|
+
this.container.removeEventListener("pointerdown", this.contrastEventPrameters.handleOnContrastMouseDown, true);
|
|
80
|
+
this.container.removeEventListener("pointermove", this.contrastEventPrameters.handleOnContrastMouseMove, true);
|
|
81
|
+
this.container.removeEventListener("pointerup", this.contrastEventPrameters.handleOnContrastMouseUp, true);
|
|
82
|
+
this.container.removeEventListener("pointerleave", this.contrastEventPrameters.handleOnContrastMouseLeave, true);
|
|
83
|
+
this.callbacks.setIsDrawFalse(1000);
|
|
84
|
+
}
|
|
85
|
+
// ===== Contrast Sliders =====
|
|
86
|
+
updateSlicesContrast(value, flag) {
|
|
87
|
+
switch (flag) {
|
|
88
|
+
case "lowerThreshold":
|
|
89
|
+
this.ctx.protectedData.displaySlices.forEach((slice) => {
|
|
90
|
+
slice.volume.lowerThreshold = value;
|
|
91
|
+
});
|
|
92
|
+
break;
|
|
93
|
+
case "upperThreshold":
|
|
94
|
+
this.ctx.protectedData.displaySlices.forEach((slice) => {
|
|
95
|
+
slice.volume.upperThreshold = value;
|
|
96
|
+
});
|
|
97
|
+
break;
|
|
98
|
+
case "windowLow":
|
|
99
|
+
this.ctx.protectedData.displaySlices.forEach((slice) => {
|
|
100
|
+
slice.volume.windowLow = value;
|
|
101
|
+
});
|
|
102
|
+
break;
|
|
103
|
+
case "windowHigh":
|
|
104
|
+
this.ctx.protectedData.displaySlices.forEach((slice) => {
|
|
105
|
+
slice.volume.windowHigh = value;
|
|
106
|
+
});
|
|
107
|
+
break;
|
|
108
|
+
}
|
|
109
|
+
this.repraintCurrentContrastSlice();
|
|
110
|
+
}
|
|
111
|
+
repraintCurrentContrastSlice() {
|
|
112
|
+
this.callbacks.setSyncsliceNum();
|
|
113
|
+
this.ctx.protectedData.displaySlices.forEach((slice) => {
|
|
114
|
+
slice.repaint.call(slice);
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=ContrastTool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ContrastTool.js","sourceRoot":"","sources":["../../../../src/Utils/segmentation/tools/ContrastTool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CrosshairTool - Crosshair positioning and cursor point conversion
|
|
3
|
+
*
|
|
4
|
+
* Extracted from DrawToolCore.ts:
|
|
5
|
+
* - enableCrosshair
|
|
6
|
+
* - convertCursorPoint
|
|
7
|
+
* - setUpSphereOrigins
|
|
8
|
+
*/
|
|
9
|
+
import { BaseTool } from "./BaseTool";
|
|
10
|
+
import type { IConvertObjType } from "../coreTools/coreType";
|
|
11
|
+
export declare class CrosshairTool extends BaseTool {
|
|
12
|
+
enableCrosshair(): void;
|
|
13
|
+
/**
|
|
14
|
+
* Convert cursor point between axis views.
|
|
15
|
+
*
|
|
16
|
+
* MRI slices are generated from threejs based on mm, but displayed based on pixel distance.
|
|
17
|
+
* The index number on each axis is the slice's depth in mm distance.
|
|
18
|
+
* Width/height on screen is in pixel distance.
|
|
19
|
+
*
|
|
20
|
+
* When switching views, we convert depth to pixel distance and vice versa.
|
|
21
|
+
*
|
|
22
|
+
* @param from Current view axis
|
|
23
|
+
* @param to Target view axis
|
|
24
|
+
* @param cursorNumX Cursor X on current axis (pixel distance)
|
|
25
|
+
* @param cursorNumY Cursor Y on current axis (pixel distance)
|
|
26
|
+
* @param currentSliceIndex Current slice depth (mm distance)
|
|
27
|
+
*/
|
|
28
|
+
convertCursorPoint(from: "x" | "y" | "z", to: "x" | "y" | "z", cursorNumX: number, cursorNumY: number, currentSliceIndex: number): IConvertObjType | undefined;
|
|
29
|
+
setUpSphereOrigins(mouseX: number, mouseY: number, sliceIndex: number): void;
|
|
30
|
+
}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CrosshairTool - Crosshair positioning and cursor point conversion
|
|
3
|
+
*
|
|
4
|
+
* Extracted from DrawToolCore.ts:
|
|
5
|
+
* - enableCrosshair
|
|
6
|
+
* - convertCursorPoint
|
|
7
|
+
* - setUpSphereOrigins
|
|
8
|
+
*/
|
|
9
|
+
import { BaseTool } from "./BaseTool";
|
|
10
|
+
export class CrosshairTool extends BaseTool {
|
|
11
|
+
// ===== Crosshair Enable =====
|
|
12
|
+
enableCrosshair() {
|
|
13
|
+
this.ctx.nrrd_states.isCursorSelect = true;
|
|
14
|
+
switch (this.ctx.protectedData.axis) {
|
|
15
|
+
case "x":
|
|
16
|
+
this.ctx.cursorPage.x.updated = true;
|
|
17
|
+
this.ctx.cursorPage.y.updated = false;
|
|
18
|
+
this.ctx.cursorPage.z.updated = false;
|
|
19
|
+
break;
|
|
20
|
+
case "y":
|
|
21
|
+
this.ctx.cursorPage.x.updated = false;
|
|
22
|
+
this.ctx.cursorPage.y.updated = true;
|
|
23
|
+
this.ctx.cursorPage.z.updated = false;
|
|
24
|
+
break;
|
|
25
|
+
case "z":
|
|
26
|
+
this.ctx.cursorPage.x.updated = false;
|
|
27
|
+
this.ctx.cursorPage.y.updated = false;
|
|
28
|
+
this.ctx.cursorPage.z.updated = true;
|
|
29
|
+
break;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
// ===== Cursor Point Conversion =====
|
|
33
|
+
/**
|
|
34
|
+
* Convert cursor point between axis views.
|
|
35
|
+
*
|
|
36
|
+
* MRI slices are generated from threejs based on mm, but displayed based on pixel distance.
|
|
37
|
+
* The index number on each axis is the slice's depth in mm distance.
|
|
38
|
+
* Width/height on screen is in pixel distance.
|
|
39
|
+
*
|
|
40
|
+
* When switching views, we convert depth to pixel distance and vice versa.
|
|
41
|
+
*
|
|
42
|
+
* @param from Current view axis
|
|
43
|
+
* @param to Target view axis
|
|
44
|
+
* @param cursorNumX Cursor X on current axis (pixel distance)
|
|
45
|
+
* @param cursorNumY Cursor Y on current axis (pixel distance)
|
|
46
|
+
* @param currentSliceIndex Current slice depth (mm distance)
|
|
47
|
+
*/
|
|
48
|
+
convertCursorPoint(from, to, cursorNumX, cursorNumY, currentSliceIndex) {
|
|
49
|
+
const nrrd = this.ctx.nrrd_states;
|
|
50
|
+
const dimensions = nrrd.dimensions;
|
|
51
|
+
const ratios = nrrd.ratios;
|
|
52
|
+
const { nrrd_x_mm, nrrd_y_mm, nrrd_z_mm } = nrrd;
|
|
53
|
+
let currentIndex = 0;
|
|
54
|
+
let oldIndex = 0;
|
|
55
|
+
let convertCursorNumX = 0;
|
|
56
|
+
let convertCursorNumY = 0;
|
|
57
|
+
const convertIndex = {
|
|
58
|
+
x: {
|
|
59
|
+
y: (val) => Math.ceil((val / nrrd_x_mm) * dimensions[0]),
|
|
60
|
+
z: (val) => Math.ceil((val / nrrd_z_mm) * dimensions[2]),
|
|
61
|
+
},
|
|
62
|
+
y: {
|
|
63
|
+
x: (val) => Math.ceil((val / nrrd_y_mm) * dimensions[1]),
|
|
64
|
+
z: (val) => Math.ceil((1 - val / nrrd_z_mm) * dimensions[2]),
|
|
65
|
+
},
|
|
66
|
+
z: {
|
|
67
|
+
x: (val) => Math.ceil((val / nrrd_x_mm) * dimensions[0]),
|
|
68
|
+
y: (val) => Math.ceil((val / nrrd_y_mm) * dimensions[1]),
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
const convertCursor = {
|
|
72
|
+
x: {
|
|
73
|
+
y: (sliceIndex) => Math.ceil((sliceIndex / dimensions[0]) * nrrd_x_mm),
|
|
74
|
+
z: (sliceIndex) => Math.ceil((sliceIndex / dimensions[0]) * nrrd_x_mm),
|
|
75
|
+
},
|
|
76
|
+
y: {
|
|
77
|
+
x: (sliceIndex) => Math.ceil((sliceIndex / dimensions[1]) * nrrd_y_mm),
|
|
78
|
+
z: (sliceIndex) => Math.ceil((sliceIndex / dimensions[1]) * nrrd_y_mm),
|
|
79
|
+
},
|
|
80
|
+
z: {
|
|
81
|
+
x: (sliceIndex) => Math.ceil((sliceIndex / dimensions[2]) * nrrd_z_mm),
|
|
82
|
+
y: (sliceIndex) => Math.ceil((1 - sliceIndex / dimensions[2]) * nrrd_z_mm),
|
|
83
|
+
},
|
|
84
|
+
};
|
|
85
|
+
if (from === to) {
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
if (from === "z" && to === "x") {
|
|
89
|
+
currentIndex = convertIndex[from][to](cursorNumX);
|
|
90
|
+
oldIndex = currentIndex * ratios[to];
|
|
91
|
+
convertCursorNumX = convertCursor[from][to](currentSliceIndex);
|
|
92
|
+
convertCursorNumY = cursorNumY;
|
|
93
|
+
}
|
|
94
|
+
else if (from === "y" && to === "x") {
|
|
95
|
+
currentIndex = convertIndex[from][to](cursorNumX);
|
|
96
|
+
oldIndex = currentIndex * ratios.x;
|
|
97
|
+
convertCursorNumY = convertCursor[from][to](currentSliceIndex);
|
|
98
|
+
convertCursorNumX = dimensions[2] * ratios.z - cursorNumY;
|
|
99
|
+
}
|
|
100
|
+
else if (from === "z" && to === "y") {
|
|
101
|
+
currentIndex = convertIndex[from][to](cursorNumY);
|
|
102
|
+
oldIndex = currentIndex * ratios[to];
|
|
103
|
+
convertCursorNumY = convertCursor[from][to](currentSliceIndex);
|
|
104
|
+
convertCursorNumX = cursorNumX;
|
|
105
|
+
}
|
|
106
|
+
else if (from === "x" && to === "y") {
|
|
107
|
+
currentIndex = convertIndex[from][to](cursorNumY);
|
|
108
|
+
oldIndex = currentIndex * ratios[to];
|
|
109
|
+
convertCursorNumX = convertCursor[from][to](currentSliceIndex);
|
|
110
|
+
convertCursorNumY = dimensions[2] * ratios.z - cursorNumX;
|
|
111
|
+
}
|
|
112
|
+
else if (from === "x" && to === "z") {
|
|
113
|
+
currentIndex = convertIndex[from][to](cursorNumX);
|
|
114
|
+
oldIndex = currentIndex * ratios[to];
|
|
115
|
+
convertCursorNumX = convertCursor[from][to](currentSliceIndex);
|
|
116
|
+
convertCursorNumY = cursorNumY;
|
|
117
|
+
}
|
|
118
|
+
else if (from === "y" && to === "z") {
|
|
119
|
+
currentIndex = convertIndex[from][to](cursorNumY);
|
|
120
|
+
oldIndex = currentIndex * ratios.z;
|
|
121
|
+
convertCursorNumY = convertCursor[from][to](currentSliceIndex);
|
|
122
|
+
convertCursorNumX = cursorNumX;
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
return { currentIndex, oldIndex, convertCursorNumX, convertCursorNumY };
|
|
128
|
+
}
|
|
129
|
+
// ===== Sphere Origins Setup =====
|
|
130
|
+
setUpSphereOrigins(mouseX, mouseY, sliceIndex) {
|
|
131
|
+
const convertCursor = (from, to) => {
|
|
132
|
+
const convertObj = this.convertCursorPoint(from, to, mouseX, mouseY, sliceIndex);
|
|
133
|
+
return {
|
|
134
|
+
convertCursorNumX: convertObj === null || convertObj === void 0 ? void 0 : convertObj.convertCursorNumX,
|
|
135
|
+
convertCursorNumY: convertObj === null || convertObj === void 0 ? void 0 : convertObj.convertCursorNumY,
|
|
136
|
+
currentIndex: convertObj === null || convertObj === void 0 ? void 0 : convertObj.currentIndex,
|
|
137
|
+
};
|
|
138
|
+
};
|
|
139
|
+
const axisConversions = {
|
|
140
|
+
x: { axisTo1: "y", axisTo2: "z" },
|
|
141
|
+
y: { axisTo1: "z", axisTo2: "x" },
|
|
142
|
+
z: { axisTo1: "x", axisTo2: "y" },
|
|
143
|
+
};
|
|
144
|
+
const { axisTo1, axisTo2 } = axisConversions[this.ctx.protectedData.axis];
|
|
145
|
+
this.ctx.nrrd_states.sphereOrigin[axisTo1] = [
|
|
146
|
+
convertCursor(this.ctx.protectedData.axis, axisTo1).convertCursorNumX,
|
|
147
|
+
convertCursor(this.ctx.protectedData.axis, axisTo1).convertCursorNumY,
|
|
148
|
+
convertCursor(this.ctx.protectedData.axis, axisTo1).currentIndex,
|
|
149
|
+
];
|
|
150
|
+
this.ctx.nrrd_states.sphereOrigin[axisTo2] = [
|
|
151
|
+
convertCursor(this.ctx.protectedData.axis, axisTo2).convertCursorNumX,
|
|
152
|
+
convertCursor(this.ctx.protectedData.axis, axisTo2).convertCursorNumY,
|
|
153
|
+
convertCursor(this.ctx.protectedData.axis, axisTo2).currentIndex,
|
|
154
|
+
];
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
//# sourceMappingURL=CrosshairTool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CrosshairTool.js","sourceRoot":"","sources":["../../../../src/Utils/segmentation/tools/CrosshairTool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DragSliceTool - Drag-based slice navigation
|
|
3
|
+
*
|
|
4
|
+
* Extracted from DragOperator.ts:
|
|
5
|
+
* - updateIndex
|
|
6
|
+
* - drawDragSlice
|
|
7
|
+
* - drawMaskToLayerCtx
|
|
8
|
+
* - cleanCanvases
|
|
9
|
+
* - updateShowNumDiv / updateCurrentContrastSlice
|
|
10
|
+
*/
|
|
11
|
+
import { BaseTool } from "./BaseTool";
|
|
12
|
+
import type { ToolContext } from "./BaseTool";
|
|
13
|
+
import type { ILayerRenderTarget } from "../coreTools/coreType";
|
|
14
|
+
export interface DragSliceCallbacks {
|
|
15
|
+
setSyncsliceNum: () => void;
|
|
16
|
+
setIsDrawFalse: (target: number) => void;
|
|
17
|
+
flipDisplayImageByAxis: () => void;
|
|
18
|
+
setEmptyCanvasSize: (axis?: "x" | "y" | "z") => void;
|
|
19
|
+
getOrCreateSliceBuffer: (axis: "x" | "y" | "z") => ImageData | null;
|
|
20
|
+
renderSliceToCanvas: (layer: string, axis: "x" | "y" | "z", sliceIndex: number, buffer: ImageData, targetCtx: CanvasRenderingContext2D, scaledWidth: number, scaledHeight: number) => void;
|
|
21
|
+
}
|
|
22
|
+
interface IDragEffectCanvases {
|
|
23
|
+
drawingCanvasLayerMaster: HTMLCanvasElement;
|
|
24
|
+
displayCanvas: HTMLCanvasElement;
|
|
25
|
+
layerTargets: Map<string, ILayerRenderTarget>;
|
|
26
|
+
[key: string]: HTMLCanvasElement | Map<string, ILayerRenderTarget>;
|
|
27
|
+
}
|
|
28
|
+
export declare class DragSliceTool extends BaseTool {
|
|
29
|
+
private callbacks;
|
|
30
|
+
private showDragNumberDiv;
|
|
31
|
+
private dragEffectCanvases;
|
|
32
|
+
constructor(ctx: ToolContext, callbacks: DragSliceCallbacks, showDragNumberDiv: HTMLDivElement, dragEffectCanvases: IDragEffectCanvases);
|
|
33
|
+
setShowDragNumberDiv(div: HTMLDivElement): void;
|
|
34
|
+
updateIndex(move: number): void;
|
|
35
|
+
private drawDragSlice;
|
|
36
|
+
/**
|
|
37
|
+
* Composite all visible layer canvases to the master display canvas.
|
|
38
|
+
*/
|
|
39
|
+
private compositeAllLayers;
|
|
40
|
+
private cleanCanvases;
|
|
41
|
+
updateShowNumDiv(contrastNum: number): void;
|
|
42
|
+
updateCurrentContrastSlice(): any;
|
|
43
|
+
}
|
|
44
|
+
export {};
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DragSliceTool - Drag-based slice navigation
|
|
3
|
+
*
|
|
4
|
+
* Extracted from DragOperator.ts:
|
|
5
|
+
* - updateIndex
|
|
6
|
+
* - drawDragSlice
|
|
7
|
+
* - drawMaskToLayerCtx
|
|
8
|
+
* - cleanCanvases
|
|
9
|
+
* - updateShowNumDiv / updateCurrentContrastSlice
|
|
10
|
+
*/
|
|
11
|
+
import { BaseTool } from "./BaseTool";
|
|
12
|
+
export class DragSliceTool extends BaseTool {
|
|
13
|
+
constructor(ctx, callbacks, showDragNumberDiv, dragEffectCanvases) {
|
|
14
|
+
super(ctx);
|
|
15
|
+
this.callbacks = callbacks;
|
|
16
|
+
this.showDragNumberDiv = showDragNumberDiv;
|
|
17
|
+
this.dragEffectCanvases = dragEffectCanvases;
|
|
18
|
+
}
|
|
19
|
+
setShowDragNumberDiv(div) {
|
|
20
|
+
this.showDragNumberDiv = div;
|
|
21
|
+
}
|
|
22
|
+
// ===== Update Index =====
|
|
23
|
+
updateIndex(move) {
|
|
24
|
+
let sliceModifyNum = 0;
|
|
25
|
+
let contrastModifyNum = 0;
|
|
26
|
+
const nrrd = this.ctx.nrrd_states;
|
|
27
|
+
if (nrrd.showContrast) {
|
|
28
|
+
contrastModifyNum = move % this.ctx.protectedData.displaySlices.length;
|
|
29
|
+
nrrd.contrastNum += contrastModifyNum;
|
|
30
|
+
if (move > 0) {
|
|
31
|
+
if (nrrd.currentIndex <= nrrd.maxIndex) {
|
|
32
|
+
sliceModifyNum = Math.floor(move / this.ctx.protectedData.displaySlices.length);
|
|
33
|
+
if (nrrd.contrastNum > this.ctx.protectedData.displaySlices.length - 1) {
|
|
34
|
+
sliceModifyNum += 1;
|
|
35
|
+
nrrd.contrastNum -= this.ctx.protectedData.displaySlices.length;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
sliceModifyNum = 0;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
sliceModifyNum = Math.ceil(move / this.ctx.protectedData.displaySlices.length);
|
|
44
|
+
if (nrrd.contrastNum < 0) {
|
|
45
|
+
nrrd.contrastNum += this.ctx.protectedData.displaySlices.length;
|
|
46
|
+
sliceModifyNum -= 1;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
sliceModifyNum = move;
|
|
52
|
+
}
|
|
53
|
+
let newIndex = nrrd.currentIndex + sliceModifyNum;
|
|
54
|
+
if (newIndex != nrrd.currentIndex || nrrd.showContrast) {
|
|
55
|
+
if (newIndex > nrrd.maxIndex) {
|
|
56
|
+
newIndex = nrrd.maxIndex;
|
|
57
|
+
nrrd.contrastNum = this.ctx.protectedData.displaySlices.length - 1;
|
|
58
|
+
}
|
|
59
|
+
else if (newIndex < nrrd.minIndex) {
|
|
60
|
+
newIndex = nrrd.minIndex;
|
|
61
|
+
nrrd.contrastNum = 0;
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
this.ctx.protectedData.mainPreSlices.index = newIndex * nrrd.RSARatio;
|
|
65
|
+
this.callbacks.setSyncsliceNum();
|
|
66
|
+
let isSameIndex = true;
|
|
67
|
+
if (newIndex != nrrd.currentIndex) {
|
|
68
|
+
nrrd.switchSliceFlag = true;
|
|
69
|
+
isSameIndex = false;
|
|
70
|
+
}
|
|
71
|
+
this.cleanCanvases(isSameIndex);
|
|
72
|
+
if (nrrd.changedWidth === 0) {
|
|
73
|
+
nrrd.changedWidth = nrrd.originWidth;
|
|
74
|
+
nrrd.changedHeight = nrrd.originHeight;
|
|
75
|
+
}
|
|
76
|
+
const needToUpdateSlice = this.updateCurrentContrastSlice();
|
|
77
|
+
needToUpdateSlice.repaint.call(needToUpdateSlice);
|
|
78
|
+
nrrd.currentIndex = newIndex;
|
|
79
|
+
this.drawDragSlice(needToUpdateSlice.canvas);
|
|
80
|
+
}
|
|
81
|
+
nrrd.oldIndex = newIndex * nrrd.RSARatio;
|
|
82
|
+
this.updateShowNumDiv(nrrd.contrastNum);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
// ===== Draw Drag Slice =====
|
|
86
|
+
drawDragSlice(canvas) {
|
|
87
|
+
const nrrd = this.ctx.nrrd_states;
|
|
88
|
+
// Draw base image (CT/MRI scan)
|
|
89
|
+
this.ctx.protectedData.ctxes.displayCtx.save();
|
|
90
|
+
this.callbacks.flipDisplayImageByAxis();
|
|
91
|
+
this.ctx.protectedData.ctxes.displayCtx.drawImage(canvas, 0, 0, nrrd.changedWidth, nrrd.changedHeight);
|
|
92
|
+
this.ctx.protectedData.ctxes.displayCtx.restore();
|
|
93
|
+
// Phase 3: Draw ALL layers from MaskVolume (multi-layer compositing)
|
|
94
|
+
if (nrrd.switchSliceFlag) {
|
|
95
|
+
const axis = this.ctx.protectedData.axis;
|
|
96
|
+
const sliceIndex = nrrd.currentIndex;
|
|
97
|
+
// Get a single reusable buffer — shared across all layer renders
|
|
98
|
+
const buffer = this.callbacks.getOrCreateSliceBuffer(axis);
|
|
99
|
+
if (buffer) {
|
|
100
|
+
const w = nrrd.changedWidth;
|
|
101
|
+
const h = nrrd.changedHeight;
|
|
102
|
+
for (const layerId of this.ctx.nrrd_states.layers) {
|
|
103
|
+
const target = this.ctx.protectedData.layerTargets.get(layerId);
|
|
104
|
+
if (target) {
|
|
105
|
+
this.callbacks.renderSliceToCanvas(layerId, axis, sliceIndex, buffer, target.ctx, w, h);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
// Composite all layers to master canvas
|
|
110
|
+
this.compositeAllLayers();
|
|
111
|
+
nrrd.switchSliceFlag = false;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Composite all visible layer canvases to the master display canvas.
|
|
116
|
+
*/
|
|
117
|
+
compositeAllLayers() {
|
|
118
|
+
const masterCtx = this.ctx.protectedData.ctxes.drawingLayerMasterCtx;
|
|
119
|
+
const width = this.ctx.nrrd_states.changedWidth;
|
|
120
|
+
const height = this.ctx.nrrd_states.changedHeight;
|
|
121
|
+
masterCtx.clearRect(0, 0, width, height);
|
|
122
|
+
// Master stores full-alpha composite; globalAlpha applied in start() render loop.
|
|
123
|
+
for (const layerId of this.ctx.nrrd_states.layers) {
|
|
124
|
+
if (!this.ctx.gui_states.layerVisibility[layerId])
|
|
125
|
+
continue;
|
|
126
|
+
const target = this.ctx.protectedData.layerTargets.get(layerId);
|
|
127
|
+
if (target)
|
|
128
|
+
masterCtx.drawImage(target.canvas, 0, 0, width, height);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
// ===== Canvas Cleanup =====
|
|
132
|
+
cleanCanvases(flag) {
|
|
133
|
+
if (flag) {
|
|
134
|
+
// Same-index: only clear the display canvas
|
|
135
|
+
this.dragEffectCanvases.displayCanvas.width =
|
|
136
|
+
this.dragEffectCanvases.displayCanvas.width;
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
// Different slice: clear master, display, and all layer canvases
|
|
140
|
+
this.dragEffectCanvases.drawingCanvasLayerMaster.width =
|
|
141
|
+
this.dragEffectCanvases.drawingCanvasLayerMaster.width;
|
|
142
|
+
this.dragEffectCanvases.displayCanvas.width =
|
|
143
|
+
this.dragEffectCanvases.displayCanvas.width;
|
|
144
|
+
for (const [, target] of this.dragEffectCanvases.layerTargets) {
|
|
145
|
+
target.canvas.width = target.canvas.width;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
// ===== UI Updates =====
|
|
150
|
+
updateShowNumDiv(contrastNum) {
|
|
151
|
+
if (this.ctx.protectedData.mainPreSlices) {
|
|
152
|
+
const nrrd = this.ctx.nrrd_states;
|
|
153
|
+
if (nrrd.currentIndex > nrrd.maxIndex) {
|
|
154
|
+
nrrd.currentIndex = nrrd.maxIndex;
|
|
155
|
+
}
|
|
156
|
+
if (nrrd.showContrast) {
|
|
157
|
+
this.showDragNumberDiv.innerHTML = `ContrastNum: ${contrastNum}/${this.ctx.protectedData.displaySlices.length - 1} SliceNum: ${nrrd.currentIndex}/${nrrd.maxIndex}`;
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
this.showDragNumberDiv.innerHTML = `SliceNum: ${nrrd.currentIndex}/${nrrd.maxIndex}`;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
updateCurrentContrastSlice() {
|
|
165
|
+
this.ctx.protectedData.currentShowingSlice =
|
|
166
|
+
this.ctx.protectedData.displaySlices[this.ctx.nrrd_states.contrastNum];
|
|
167
|
+
return this.ctx.protectedData.currentShowingSlice;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
//# sourceMappingURL=DragSliceTool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DragSliceTool.js","sourceRoot":"","sources":["../../../../src/Utils/segmentation/tools/DragSliceTool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EraserTool - Channel-aware circular eraser implementation
|
|
3
|
+
*
|
|
4
|
+
* Phase 3.5: Updated to only erase pixels matching the active channel color
|
|
5
|
+
* on the current layer canvas. Other channels/layers are untouched.
|
|
6
|
+
*/
|
|
7
|
+
import { BaseTool } from "./BaseTool";
|
|
8
|
+
export declare class EraserTool extends BaseTool {
|
|
9
|
+
/**
|
|
10
|
+
* Create the circular eraser function.
|
|
11
|
+
*
|
|
12
|
+
* Channel-aware: only erases pixels whose RGB matches the active channel's color.
|
|
13
|
+
* Only operates on the current layer canvas + master canvas.
|
|
14
|
+
*/
|
|
15
|
+
createClearArc(): (x: number, y: number, radius: number) => void;
|
|
16
|
+
}
|