copper3d 3.0.2 → 3.1.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.
- package/README.md +183 -1028
- package/dist/Utils/segmentation/CanvasState.d.ts +31 -0
- package/dist/Utils/segmentation/CanvasState.js +168 -0
- package/dist/Utils/segmentation/CanvasState.js.map +1 -0
- package/dist/Utils/segmentation/DragOperator.d.ts +1 -1
- package/dist/Utils/segmentation/DragOperator.js +2 -4
- package/dist/Utils/segmentation/DragOperator.js.map +1 -1
- package/dist/Utils/segmentation/DrawToolCore.d.ts +49 -27
- package/dist/Utils/segmentation/DrawToolCore.js +275 -344
- package/dist/Utils/segmentation/DrawToolCore.js.map +1 -1
- package/dist/Utils/segmentation/NrrdTools.d.ts +92 -467
- package/dist/Utils/segmentation/NrrdTools.js +499 -1341
- package/dist/Utils/segmentation/NrrdTools.js.map +1 -1
- package/dist/Utils/segmentation/RenderingUtils.d.ts +73 -0
- package/dist/Utils/segmentation/RenderingUtils.js +186 -0
- package/dist/Utils/segmentation/RenderingUtils.js.map +1 -0
- package/dist/Utils/segmentation/core/MaskVolume.d.ts +1 -1
- package/dist/Utils/segmentation/core/MaskVolume.js +1 -1
- package/dist/Utils/segmentation/core/index.d.ts +1 -1
- package/dist/Utils/segmentation/core/index.js.map +1 -1
- package/dist/Utils/segmentation/core/types.d.ts +386 -0
- package/dist/Utils/segmentation/core/types.js +1 -0
- package/dist/Utils/segmentation/core/types.js.map +1 -1
- package/dist/Utils/segmentation/coreTools/GuiState.d.ts +1 -1
- package/dist/Utils/segmentation/coreTools/GuiState.js +1 -0
- package/dist/Utils/segmentation/coreTools/GuiState.js.map +1 -1
- package/dist/Utils/segmentation/coreTools/NrrdState.d.ts +1 -1
- package/dist/Utils/segmentation/coreTools/divControlTools.d.ts +1 -1
- package/dist/Utils/segmentation/coreTools/gui.d.ts +1 -1
- package/dist/Utils/segmentation/tools/BaseTool.d.ts +1 -1
- package/dist/Utils/segmentation/tools/ContrastTool.d.ts +3 -6
- package/dist/Utils/segmentation/tools/ContrastTool.js.map +1 -1
- package/dist/Utils/segmentation/tools/CrosshairTool.d.ts +11 -1
- package/dist/Utils/segmentation/tools/CrosshairTool.js +25 -0
- package/dist/Utils/segmentation/tools/CrosshairTool.js.map +1 -1
- package/dist/Utils/segmentation/tools/DataLoader.d.ts +33 -0
- package/dist/Utils/segmentation/tools/DataLoader.js +159 -0
- package/dist/Utils/segmentation/tools/DataLoader.js.map +1 -0
- package/dist/Utils/segmentation/tools/DragSliceTool.d.ts +3 -12
- package/dist/Utils/segmentation/tools/DragSliceTool.js.map +1 -1
- package/dist/Utils/segmentation/tools/DrawingTool.d.ts +18 -26
- package/dist/Utils/segmentation/tools/DrawingTool.js +48 -0
- package/dist/Utils/segmentation/tools/DrawingTool.js.map +1 -1
- package/dist/Utils/segmentation/tools/ImageStoreHelper.d.ts +2 -5
- package/dist/Utils/segmentation/tools/ImageStoreHelper.js.map +1 -1
- package/dist/Utils/segmentation/tools/LayerChannelManager.d.ts +56 -0
- package/dist/Utils/segmentation/tools/LayerChannelManager.js +188 -0
- package/dist/Utils/segmentation/tools/LayerChannelManager.js.map +1 -0
- package/dist/Utils/segmentation/tools/PanTool.d.ts +2 -8
- package/dist/Utils/segmentation/tools/PanTool.js.map +1 -1
- package/dist/Utils/segmentation/tools/SliceRenderPipeline.d.ts +80 -0
- package/dist/Utils/segmentation/tools/SliceRenderPipeline.js +355 -0
- package/dist/Utils/segmentation/tools/SliceRenderPipeline.js.map +1 -0
- package/dist/Utils/segmentation/tools/SphereTool.d.ts +25 -19
- package/dist/Utils/segmentation/tools/SphereTool.js +61 -7
- package/dist/Utils/segmentation/tools/SphereTool.js.map +1 -1
- package/dist/Utils/segmentation/tools/ToolHost.d.ts +74 -0
- package/dist/Utils/segmentation/tools/ToolHost.js +10 -0
- package/dist/Utils/segmentation/tools/ToolHost.js.map +1 -0
- package/dist/Utils/segmentation/tools/ZoomTool.d.ts +2 -6
- package/dist/Utils/segmentation/tools/ZoomTool.js.map +1 -1
- package/dist/Utils/segmentation/tools/index.d.ts +5 -7
- package/dist/Utils/segmentation/tools/index.js +6 -0
- package/dist/Utils/segmentation/tools/index.js.map +1 -1
- package/dist/Utils/workers/reformatSaveDataWorker.d.ts +1 -1
- package/dist/bundle.esm.js +2146 -2359
- package/dist/bundle.umd.js +2146 -2359
- package/dist/index.d.ts +3 -3
- package/dist/index.js +1 -1
- package/dist/types/Utils/segmentation/CanvasState.d.ts +31 -0
- package/dist/types/Utils/segmentation/DragOperator.d.ts +1 -1
- package/dist/types/Utils/segmentation/DrawToolCore.d.ts +49 -27
- package/dist/types/Utils/segmentation/NrrdTools.d.ts +92 -467
- package/dist/types/Utils/segmentation/RenderingUtils.d.ts +73 -0
- package/dist/types/Utils/segmentation/core/MaskVolume.d.ts +1 -1
- package/dist/types/Utils/segmentation/core/index.d.ts +1 -1
- package/dist/types/Utils/segmentation/core/types.d.ts +386 -0
- package/dist/types/Utils/segmentation/coreTools/GuiState.d.ts +1 -1
- package/dist/types/Utils/segmentation/coreTools/NrrdState.d.ts +1 -1
- package/dist/types/Utils/segmentation/coreTools/divControlTools.d.ts +1 -1
- package/dist/types/Utils/segmentation/coreTools/gui.d.ts +1 -1
- package/dist/types/Utils/segmentation/tools/BaseTool.d.ts +1 -1
- package/dist/types/Utils/segmentation/tools/ContrastTool.d.ts +3 -6
- package/dist/types/Utils/segmentation/tools/CrosshairTool.d.ts +11 -1
- package/dist/types/Utils/segmentation/tools/DataLoader.d.ts +33 -0
- package/dist/types/Utils/segmentation/tools/DragSliceTool.d.ts +3 -12
- package/dist/types/Utils/segmentation/tools/DrawingTool.d.ts +18 -26
- package/dist/types/Utils/segmentation/tools/ImageStoreHelper.d.ts +2 -5
- package/dist/types/Utils/segmentation/tools/LayerChannelManager.d.ts +56 -0
- package/dist/types/Utils/segmentation/tools/PanTool.d.ts +2 -8
- package/dist/types/Utils/segmentation/tools/SliceRenderPipeline.d.ts +80 -0
- package/dist/types/Utils/segmentation/tools/SphereTool.d.ts +25 -19
- package/dist/types/Utils/segmentation/tools/ToolHost.d.ts +74 -0
- package/dist/types/Utils/segmentation/tools/ZoomTool.d.ts +2 -6
- package/dist/types/Utils/segmentation/tools/index.d.ts +5 -7
- package/dist/types/Utils/workers/reformatSaveDataWorker.d.ts +1 -1
- package/dist/types/index.d.ts +3 -3
- package/package.json +1 -1
- package/dist/Utils/segmentation/CommToolsData.d.ts +0 -192
- package/dist/Utils/segmentation/CommToolsData.js +0 -474
- package/dist/Utils/segmentation/CommToolsData.js.map +0 -1
- package/dist/Utils/segmentation/coreTools/coreType.d.ts +0 -389
- package/dist/Utils/segmentation/coreTools/coreType.js +0 -3
- package/dist/Utils/segmentation/coreTools/coreType.js.map +0 -1
- package/dist/types/Utils/segmentation/CommToolsData.d.ts +0 -192
- package/dist/types/Utils/segmentation/coreTools/coreType.d.ts +0 -389
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { RenderingUtils } from "./RenderingUtils";
|
|
2
2
|
import { switchPencilIcon } from "../utils";
|
|
3
3
|
import { EventRouter } from "./eventRouter";
|
|
4
4
|
import { SphereTool } from "./tools/SphereTool";
|
|
@@ -10,10 +10,17 @@ import { PanTool } from "./tools/PanTool";
|
|
|
10
10
|
import { DrawingTool } from "./tools/DrawingTool";
|
|
11
11
|
import { ImageStoreHelper } from "./tools/ImageStoreHelper";
|
|
12
12
|
import { UndoManager } from "./core";
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
/**
|
|
14
|
+
* DrawToolCore — Tool orchestration and event routing.
|
|
15
|
+
*
|
|
16
|
+
* Previously extended CommToolsData; now uses composition:
|
|
17
|
+
* - `state: CanvasState` — pure state container
|
|
18
|
+
* - `renderer: RenderingUtils` — rendering / slice-buffer helpers
|
|
19
|
+
*
|
|
20
|
+
* Created by NrrdTools which passes in a shared CanvasState.
|
|
21
|
+
*/
|
|
22
|
+
export class DrawToolCore {
|
|
23
|
+
constructor(container, state) {
|
|
17
24
|
this.drawingPrameters = {
|
|
18
25
|
handleOnDrawingMouseDown: (ev) => { },
|
|
19
26
|
handleOnDrawingMouseMove: (ev) => { },
|
|
@@ -39,20 +46,12 @@ export class DrawToolCore extends CommToolsData {
|
|
|
39
46
|
this.eraserUrls = [];
|
|
40
47
|
this.pencilUrls = [];
|
|
41
48
|
this.undoManager = new UndoManager();
|
|
42
|
-
// Centralized event router
|
|
43
|
-
this.eventRouter = null;
|
|
44
49
|
/** Slice index recorded when paintOnCanvas() starts, guards stale-click */
|
|
45
50
|
this.paintSliceIndex = 0;
|
|
51
|
+
/** Wheel event dispatch mode — replaces manual wheel add/remove (Phase 2) */
|
|
52
|
+
this.activeWheelMode = 'zoom';
|
|
46
53
|
// need to return to parent
|
|
47
54
|
this.start = () => { };
|
|
48
|
-
/*************************************May consider to move outside *******************************************/
|
|
49
|
-
this.drawLine = (x1, y1, x2, y2) => {
|
|
50
|
-
this.protectedData.ctxes.drawingCtx.beginPath();
|
|
51
|
-
this.protectedData.ctxes.drawingCtx.moveTo(x1, y1);
|
|
52
|
-
this.protectedData.ctxes.drawingCtx.lineTo(x2, y2);
|
|
53
|
-
this.protectedData.ctxes.drawingCtx.strokeStyle = this.gui_states.drawing.color;
|
|
54
|
-
this.protectedData.ctxes.drawingCtx.stroke();
|
|
55
|
-
};
|
|
56
55
|
this.configContrastDragMode = () => {
|
|
57
56
|
this.contrastTool.configContrastDragMode();
|
|
58
57
|
};
|
|
@@ -66,17 +65,19 @@ export class DrawToolCore extends CommToolsData {
|
|
|
66
65
|
this.contrastTool.repraintCurrentContrastSlice();
|
|
67
66
|
};
|
|
68
67
|
this.container = container;
|
|
69
|
-
this.mainAreaContainer = mainAreaContainer;
|
|
68
|
+
this.mainAreaContainer = state.protectedData.mainAreaContainer;
|
|
69
|
+
this.state = state;
|
|
70
|
+
this.renderer = new RenderingUtils(state);
|
|
70
71
|
this.initTools();
|
|
71
72
|
this.initDrawToolCore();
|
|
72
73
|
}
|
|
73
74
|
initTools() {
|
|
74
75
|
const toolCtx = {
|
|
75
|
-
nrrd_states: this.nrrd_states,
|
|
76
|
-
gui_states: this.gui_states,
|
|
77
|
-
protectedData: this.protectedData,
|
|
78
|
-
cursorPage: this.cursorPage,
|
|
79
|
-
callbacks: this.annotationCallbacks,
|
|
76
|
+
nrrd_states: this.state.nrrd_states,
|
|
77
|
+
gui_states: this.state.gui_states,
|
|
78
|
+
protectedData: this.state.protectedData,
|
|
79
|
+
cursorPage: this.state.cursorPage,
|
|
80
|
+
callbacks: this.state.annotationCallbacks,
|
|
80
81
|
};
|
|
81
82
|
this.imageStoreHelper = new ImageStoreHelper(toolCtx, {
|
|
82
83
|
setEmptyCanvasSize: (axis) => this.setEmptyCanvasSize(axis),
|
|
@@ -85,6 +86,8 @@ export class DrawToolCore extends CommToolsData {
|
|
|
85
86
|
this.sphereTool = new SphereTool(toolCtx, {
|
|
86
87
|
setEmptyCanvasSize: (axis) => this.setEmptyCanvasSize(axis),
|
|
87
88
|
drawImageOnEmptyImage: (canvas) => this.drawImageOnEmptyImage(canvas),
|
|
89
|
+
enableCrosshair: () => this.enableCrosshair(),
|
|
90
|
+
setUpSphereOrigins: (x, y, s) => this.setUpSphereOrigins(x, y, s),
|
|
88
91
|
});
|
|
89
92
|
this.crosshairTool = new CrosshairTool(toolCtx);
|
|
90
93
|
this.contrastTool = new ContrastTool(toolCtx, this.container, this.contrastEventPrameters, {
|
|
@@ -102,10 +105,10 @@ export class DrawToolCore extends CommToolsData {
|
|
|
102
105
|
});
|
|
103
106
|
this.drawingTool = new DrawingTool(toolCtx, {
|
|
104
107
|
setCurrentLayer: () => this.setCurrentLayer(),
|
|
105
|
-
compositeAllLayers: () => this.compositeAllLayers(),
|
|
108
|
+
compositeAllLayers: () => this.renderer.compositeAllLayers(),
|
|
106
109
|
syncLayerSliceData: (index, layer) => this.syncLayerSliceData(index, layer),
|
|
107
|
-
filterDrawedImage: (axis, index) => this.filterDrawedImage(axis, index),
|
|
108
|
-
getVolumeForLayer: (layer) => this.getVolumeForLayer(layer),
|
|
110
|
+
filterDrawedImage: (axis, index) => this.renderer.filterDrawedImage(axis, index),
|
|
111
|
+
getVolumeForLayer: (layer) => this.renderer.getVolumeForLayer(layer),
|
|
109
112
|
pushUndoDelta: (delta) => this.undoManager.push(delta),
|
|
110
113
|
getEraserUrls: () => this.eraserUrls,
|
|
111
114
|
});
|
|
@@ -114,7 +117,7 @@ export class DrawToolCore extends CommToolsData {
|
|
|
114
117
|
// Initialize EventRouter for centralized event handling
|
|
115
118
|
this.eventRouter = new EventRouter({
|
|
116
119
|
container: this.container,
|
|
117
|
-
canvas: this.protectedData.canvases.drawingCanvas,
|
|
120
|
+
canvas: this.state.protectedData.canvases.drawingCanvas,
|
|
118
121
|
onModeChange: (prevMode, newMode) => {
|
|
119
122
|
// Use string comparison to avoid TypeScript narrowing issues
|
|
120
123
|
const prev = prevMode;
|
|
@@ -124,56 +127,53 @@ export class DrawToolCore extends CommToolsData {
|
|
|
124
127
|
}
|
|
125
128
|
else if (prev === 'contrast') {
|
|
126
129
|
this.removeContrastDragMode();
|
|
127
|
-
this.gui_states.viewConfig.readyToUpdate = true;
|
|
130
|
+
this.state.gui_states.viewConfig.readyToUpdate = true;
|
|
128
131
|
}
|
|
129
132
|
if (next === 'crosshair') {
|
|
130
|
-
this.protectedData.isDrawing = false;
|
|
133
|
+
this.state.protectedData.isDrawing = false;
|
|
131
134
|
}
|
|
132
135
|
}
|
|
133
136
|
});
|
|
134
137
|
// Inject eventRouter into ToolContext so tools can query mode/state
|
|
135
138
|
const toolCtx = this.sphereTool['ctx'];
|
|
136
139
|
toolCtx.eventRouter = this.eventRouter;
|
|
137
|
-
// Configure keyboard settings from
|
|
138
|
-
this.eventRouter.setKeyboardSettings(this.
|
|
140
|
+
// Configure keyboard settings from state
|
|
141
|
+
this.eventRouter.setKeyboardSettings(this.state.keyboardSettings);
|
|
139
142
|
// Track undo flag for Ctrl+Z handling
|
|
140
143
|
let undoFlag = false;
|
|
141
144
|
// Register keyboard handlers with EventRouter
|
|
142
145
|
this.eventRouter.setKeydownHandler((ev) => {
|
|
143
|
-
|
|
144
|
-
if (this._configKeyBoard)
|
|
146
|
+
if (this.state.configKeyBoard)
|
|
145
147
|
return;
|
|
146
148
|
// Handle undo (Ctrl+Z)
|
|
147
|
-
if ((ev.ctrlKey || ev.metaKey) && ev.key === this.
|
|
149
|
+
if ((ev.ctrlKey || ev.metaKey) && ev.key === this.state.keyboardSettings.undo) {
|
|
148
150
|
undoFlag = true;
|
|
149
151
|
this.undoLastPainting();
|
|
150
152
|
}
|
|
151
153
|
// Handle redo (Ctrl+<redo key> or Ctrl+Shift+<undo key>)
|
|
152
|
-
const redoKey = this.
|
|
153
|
-
const undoKeyUpper = this.
|
|
154
|
+
const redoKey = this.state.keyboardSettings.redo;
|
|
155
|
+
const undoKeyUpper = this.state.keyboardSettings.undo.toUpperCase();
|
|
154
156
|
if ((ev.ctrlKey || ev.metaKey) && (ev.key === redoKey || (ev.shiftKey && ev.key === undoKeyUpper))) {
|
|
155
157
|
this.redoLastPainting();
|
|
156
158
|
}
|
|
157
159
|
// Handle crosshair toggle (allowed in drawing tools AND sphere mode)
|
|
158
|
-
if (ev.key === this.
|
|
159
|
-
|
|
160
|
+
if (ev.key === this.state.keyboardSettings.crosshair) {
|
|
161
|
+
this.eventRouter.toggleCrosshair();
|
|
160
162
|
}
|
|
161
163
|
// Handle draw mode (Shift key) - EventRouter already tracks this
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
if ((_b = this.eventRouter) === null || _b === void 0 ? void 0 : _b.isCtrlHeld()) {
|
|
164
|
+
if (ev.key === this.state.keyboardSettings.draw && !this.state.gui_states.mode.sphere) {
|
|
165
|
+
if (this.eventRouter.isCtrlHeld()) {
|
|
165
166
|
return; // Ctrl takes priority
|
|
166
167
|
}
|
|
167
|
-
// EventRouter will set mode to 'draw' via internal handler
|
|
168
168
|
}
|
|
169
169
|
// Handle sphere mode toggle
|
|
170
|
-
if (ev.key === this.
|
|
170
|
+
if (ev.key === this.state.keyboardSettings.sphere) {
|
|
171
171
|
// Block during draw mode or contrast mode
|
|
172
|
-
if (
|
|
172
|
+
if (this.eventRouter.isShiftHeld() || this.eventRouter.isCtrlHeld()) {
|
|
173
173
|
return;
|
|
174
174
|
}
|
|
175
|
-
this.gui_states.mode.sphere = !this.gui_states.mode.sphere;
|
|
176
|
-
if (this.gui_states.mode.sphere) {
|
|
175
|
+
this.state.gui_states.mode.sphere = !this.state.gui_states.mode.sphere;
|
|
176
|
+
if (this.state.gui_states.mode.sphere) {
|
|
177
177
|
this.enterSphereMode();
|
|
178
178
|
}
|
|
179
179
|
else {
|
|
@@ -182,33 +182,57 @@ export class DrawToolCore extends CommToolsData {
|
|
|
182
182
|
}
|
|
183
183
|
});
|
|
184
184
|
this.eventRouter.setKeyupHandler((ev) => {
|
|
185
|
-
|
|
186
|
-
if (this._configKeyBoard)
|
|
185
|
+
if (this.state.configKeyBoard)
|
|
187
186
|
return;
|
|
188
187
|
// Handle Ctrl key release (contrast mode toggle)
|
|
189
|
-
if (this.
|
|
188
|
+
if (this.state.keyboardSettings.contrast.includes(ev.key)) {
|
|
190
189
|
if (undoFlag) {
|
|
191
|
-
this.gui_states.viewConfig.readyToUpdate = true;
|
|
190
|
+
this.state.gui_states.viewConfig.readyToUpdate = true;
|
|
192
191
|
undoFlag = false;
|
|
193
192
|
return;
|
|
194
193
|
}
|
|
195
194
|
// Skip mode toggle when contrast shortcut is disabled
|
|
196
|
-
if (!
|
|
195
|
+
if (!this.eventRouter.isContrastEnabled())
|
|
197
196
|
return;
|
|
198
197
|
// Block contrast toggle during crosshair, draw, or sphere (mutual exclusion)
|
|
199
|
-
if (
|
|
198
|
+
if (this.eventRouter.isCrosshairEnabled() || this.eventRouter.getMode() === 'draw')
|
|
200
199
|
return;
|
|
201
|
-
if (this.gui_states.mode.sphere)
|
|
200
|
+
if (this.state.gui_states.mode.sphere)
|
|
202
201
|
return;
|
|
203
202
|
// Toggle contrast mode manually since it's on keyup
|
|
204
|
-
if (
|
|
205
|
-
|
|
203
|
+
if (this.eventRouter.getMode() !== 'contrast') {
|
|
204
|
+
this.eventRouter.setMode('contrast');
|
|
206
205
|
}
|
|
207
206
|
else {
|
|
208
|
-
|
|
207
|
+
this.eventRouter.setMode('idle');
|
|
209
208
|
}
|
|
210
209
|
}
|
|
211
210
|
});
|
|
211
|
+
// Register pointer handlers with EventRouter
|
|
212
|
+
this.eventRouter.setPointerMoveHandler((e) => {
|
|
213
|
+
if (this.drawingTool.isActive || this.panTool.isActive) {
|
|
214
|
+
this.drawingPrameters.handleOnDrawingMouseMove(e);
|
|
215
|
+
}
|
|
216
|
+
});
|
|
217
|
+
this.eventRouter.setPointerUpHandler((e) => {
|
|
218
|
+
if (this.drawingTool.isActive || this.drawingTool.painting
|
|
219
|
+
|| this.panTool.isActive
|
|
220
|
+
|| (this.state.gui_states.mode.sphere && this.eventRouter.getMode() !== 'crosshair')) {
|
|
221
|
+
this.drawingPrameters.handleOnDrawingMouseUp(e);
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
this.eventRouter.setPointerLeaveHandler((e) => {
|
|
225
|
+
this.handlePointerLeave();
|
|
226
|
+
});
|
|
227
|
+
// Register wheel handler with EventRouter
|
|
228
|
+
this.eventRouter.setWheelHandler((e) => {
|
|
229
|
+
if (this.activeWheelMode === 'zoom') {
|
|
230
|
+
this.drawingPrameters.handleMouseZoomSliceWheel(e);
|
|
231
|
+
}
|
|
232
|
+
else if (this.activeWheelMode === 'sphere') {
|
|
233
|
+
this.drawingPrameters.handleSphereWheel(e);
|
|
234
|
+
}
|
|
235
|
+
});
|
|
212
236
|
// Bind all event listeners
|
|
213
237
|
this.eventRouter.bindAll();
|
|
214
238
|
}
|
|
@@ -217,245 +241,157 @@ export class DrawToolCore extends CommToolsData {
|
|
|
217
241
|
}
|
|
218
242
|
setPencilIconUrls(urls) {
|
|
219
243
|
this.pencilUrls = urls;
|
|
220
|
-
this.gui_states.viewConfig.defaultPaintCursor = switchPencilIcon("dot", this.pencilUrls);
|
|
221
|
-
this.protectedData.canvases.drawingCanvas.style.cursor =
|
|
222
|
-
this.gui_states.viewConfig.defaultPaintCursor;
|
|
244
|
+
this.state.gui_states.viewConfig.defaultPaintCursor = switchPencilIcon("dot", this.pencilUrls);
|
|
245
|
+
this.state.protectedData.canvases.drawingCanvas.style.cursor =
|
|
246
|
+
this.state.gui_states.viewConfig.defaultPaintCursor;
|
|
223
247
|
}
|
|
224
248
|
setCurrentLayer() {
|
|
225
|
-
const layer = this.gui_states.layerChannel.layer;
|
|
226
|
-
let target = this.protectedData.layerTargets.get(layer);
|
|
249
|
+
const layer = this.state.gui_states.layerChannel.layer;
|
|
250
|
+
let target = this.state.protectedData.layerTargets.get(layer);
|
|
227
251
|
if (!target) {
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
target = this.protectedData.layerTargets.get(firstId);
|
|
252
|
+
const firstId = this.state.nrrd_states.image.layers[0];
|
|
253
|
+
target = this.state.protectedData.layerTargets.get(firstId);
|
|
231
254
|
}
|
|
232
255
|
return { ctx: target.ctx, canvas: target.canvas };
|
|
233
256
|
}
|
|
234
257
|
draw(opts) {
|
|
235
258
|
if (!!opts) {
|
|
236
|
-
// Phase 2: Store callbacks in annotationCallbacks instead of nrrd_states
|
|
237
259
|
if (opts.getMaskData) {
|
|
238
|
-
this.annotationCallbacks.onMaskChanged = opts.getMaskData;
|
|
260
|
+
this.state.annotationCallbacks.onMaskChanged = opts.getMaskData;
|
|
239
261
|
}
|
|
240
262
|
if (opts.onClearLayerVolume) {
|
|
241
|
-
this.annotationCallbacks.onLayerVolumeCleared = opts.onClearLayerVolume;
|
|
263
|
+
this.state.annotationCallbacks.onLayerVolumeCleared = opts.onClearLayerVolume;
|
|
242
264
|
}
|
|
243
265
|
if (opts.getSphereData) {
|
|
244
|
-
this.annotationCallbacks.onSphereChanged = opts.getSphereData;
|
|
266
|
+
this.state.annotationCallbacks.onSphereChanged = opts.getSphereData;
|
|
245
267
|
}
|
|
246
268
|
if (opts.getCalculateSpherePositionsData) {
|
|
247
|
-
this.annotationCallbacks.onCalculatorPositionsChanged = opts.getCalculateSpherePositionsData;
|
|
269
|
+
this.state.annotationCallbacks.onCalculatorPositionsChanged = opts.getCalculateSpherePositionsData;
|
|
248
270
|
}
|
|
249
271
|
}
|
|
250
272
|
this.paintOnCanvas();
|
|
251
273
|
}
|
|
252
274
|
zoomActionAfterDrawSphere() {
|
|
253
|
-
this.
|
|
254
|
-
}
|
|
255
|
-
clearSpherePrintStoreImages() {
|
|
256
|
-
this.sphereTool.clearSpherePrintStoreImages();
|
|
275
|
+
this.activeWheelMode = 'zoom';
|
|
257
276
|
}
|
|
258
277
|
paintOnCanvas() {
|
|
259
278
|
var _a, _b, _c;
|
|
260
279
|
// Initialize tools for this paint cycle
|
|
261
280
|
this.drawingTool.reset(this.useEraser());
|
|
262
281
|
this.panTool.reset();
|
|
263
|
-
this.paintSliceIndex = this.protectedData.mainPreSlices.index;
|
|
282
|
+
this.paintSliceIndex = this.state.protectedData.mainPreSlices.index;
|
|
264
283
|
this.updateOriginAndChangedWH();
|
|
265
284
|
this.initAllCanvas();
|
|
266
|
-
(_a = this.protectedData.ctxes.displayCtx) === null || _a === void 0 ? void 0 : _a.save();
|
|
285
|
+
(_a = this.state.protectedData.ctxes.displayCtx) === null || _a === void 0 ? void 0 : _a.save();
|
|
267
286
|
this.flipDisplayImageByAxis();
|
|
268
|
-
(_b = this.protectedData.ctxes.displayCtx) === null || _b === void 0 ? void 0 : _b.drawImage(this.protectedData.canvases.originCanvas, 0, 0, this.nrrd_states.view.changedWidth, this.nrrd_states.view.changedHeight);
|
|
269
|
-
(_c = this.protectedData.ctxes.displayCtx) === null || _c === void 0 ? void 0 : _c.restore();
|
|
270
|
-
//
|
|
271
|
-
|
|
272
|
-
this.protectedData.canvases.drawingCanvas.removeEventListener("wheel", this.drawingPrameters.handleMouseZoomSliceWheel);
|
|
273
|
-
if (this._keyboardSettings.mouseWheel === "Scroll:Zoom") {
|
|
287
|
+
(_b = this.state.protectedData.ctxes.displayCtx) === null || _b === void 0 ? void 0 : _b.drawImage(this.state.protectedData.canvases.originCanvas, 0, 0, this.state.nrrd_states.view.changedWidth, this.state.nrrd_states.view.changedHeight);
|
|
288
|
+
(_c = this.state.protectedData.ctxes.displayCtx) === null || _c === void 0 ? void 0 : _c.restore();
|
|
289
|
+
// Configure wheel handler functions
|
|
290
|
+
if (this.state.keyboardSettings.mouseWheel === "Scroll:Zoom") {
|
|
274
291
|
this.drawingPrameters.handleMouseZoomSliceWheel = this.configMouseZoomWheel();
|
|
275
292
|
}
|
|
276
293
|
else {
|
|
277
294
|
this.drawingPrameters.handleMouseZoomSliceWheel = this.configMouseSliceWheel();
|
|
278
295
|
}
|
|
279
|
-
// Keep wheel as direct addEventListener due to dynamic add/remove patterns in handleOnDrawingMouseUp
|
|
280
|
-
// EventRouter routing would conflict with the dynamic wheel switching (zoom vs sphere wheel)
|
|
281
|
-
this.protectedData.canvases.drawingCanvas.addEventListener("wheel", this.drawingPrameters.handleMouseZoomSliceWheel, {
|
|
282
|
-
passive: false,
|
|
283
|
-
});
|
|
284
296
|
// sphere Wheel
|
|
285
297
|
this.drawingPrameters.handleSphereWheel = this.configMouseSphereWheel();
|
|
286
|
-
//
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
e.preventDefault();
|
|
290
|
-
this.nrrd_states.interaction.mouseOverX = e.offsetX;
|
|
291
|
-
this.nrrd_states.interaction.mouseOverY = e.offsetY;
|
|
292
|
-
if (this.nrrd_states.interaction.mouseOverX === undefined) {
|
|
293
|
-
this.nrrd_states.interaction.mouseOverX = e.clientX;
|
|
294
|
-
this.nrrd_states.interaction.mouseOverY = e.clientY;
|
|
295
|
-
}
|
|
296
|
-
if (e.type === "mouseout") {
|
|
297
|
-
this.nrrd_states.interaction.mouseOver = false;
|
|
298
|
-
this.protectedData.canvases.drawingCanvas.removeEventListener("mousemove", this.drawingPrameters.handleOnDrawingBrushCricleMove);
|
|
299
|
-
}
|
|
300
|
-
else if (e.type === "mouseover") {
|
|
301
|
-
this.nrrd_states.interaction.mouseOver = true;
|
|
302
|
-
this.protectedData.canvases.drawingCanvas.addEventListener("mousemove", this.drawingPrameters.handleOnDrawingBrushCricleMove);
|
|
303
|
-
}
|
|
304
|
-
};
|
|
298
|
+
// brush circle move — delegated to DrawingTool
|
|
299
|
+
this.drawingPrameters.handleOnDrawingBrushCricleMove =
|
|
300
|
+
this.drawingTool.createBrushTrackingHandler();
|
|
305
301
|
// drawing move — delegated to DrawingTool
|
|
306
302
|
this.drawingPrameters.handleOnDrawingMouseMove = (e) => {
|
|
307
303
|
this.drawingTool.onPointerMove(e);
|
|
308
304
|
};
|
|
309
305
|
this.drawingPrameters.handleOnDrawingMouseDown = (e) => {
|
|
310
|
-
var _a, _b, _c;
|
|
311
306
|
if (this.drawingTool.isActive || this.panTool.isActive) {
|
|
312
|
-
this.protectedData.
|
|
313
|
-
this.protectedData.ctxes.drawingLayerMasterCtx.closePath();
|
|
307
|
+
this.state.protectedData.ctxes.drawingLayerMasterCtx.closePath();
|
|
314
308
|
return;
|
|
315
309
|
}
|
|
316
|
-
if (this.paintSliceIndex !== this.protectedData.mainPreSlices.index) {
|
|
317
|
-
this.paintSliceIndex = this.protectedData.mainPreSlices.index;
|
|
310
|
+
if (this.paintSliceIndex !== this.state.protectedData.mainPreSlices.index) {
|
|
311
|
+
this.paintSliceIndex = this.state.protectedData.mainPreSlices.index;
|
|
312
|
+
}
|
|
313
|
+
// Suppress wheel only when starting a draw operation
|
|
314
|
+
if (this.eventRouter.getMode() === 'draw') {
|
|
315
|
+
this.activeWheelMode = 'none';
|
|
318
316
|
}
|
|
319
|
-
// remove it when mouse click down
|
|
320
|
-
this.protectedData.canvases.drawingCanvas.removeEventListener("wheel", this.drawingPrameters.handleMouseZoomSliceWheel);
|
|
321
317
|
if (e.button === 0) {
|
|
322
|
-
if (
|
|
318
|
+
if (this.eventRouter.getMode() === 'draw') {
|
|
323
319
|
this.drawingTool.onPointerDown(e);
|
|
324
|
-
this.protectedData.canvases.drawingCanvas.addEventListener("pointerup", this.drawingPrameters.handleOnDrawingMouseUp);
|
|
325
|
-
this.protectedData.canvases.drawingCanvas.addEventListener("pointermove", this.drawingPrameters.handleOnDrawingMouseMove);
|
|
326
320
|
}
|
|
327
|
-
else if (
|
|
328
|
-
this.nrrd_states.interaction.cursorPageX =
|
|
329
|
-
e.offsetX / this.nrrd_states.view.sizeFactor;
|
|
330
|
-
this.nrrd_states.interaction.cursorPageY =
|
|
331
|
-
e.offsetY / this.nrrd_states.view.sizeFactor;
|
|
321
|
+
else if (this.eventRouter.isCrosshairEnabled()) {
|
|
322
|
+
this.state.nrrd_states.interaction.cursorPageX =
|
|
323
|
+
e.offsetX / this.state.nrrd_states.view.sizeFactor;
|
|
324
|
+
this.state.nrrd_states.interaction.cursorPageY =
|
|
325
|
+
e.offsetY / this.state.nrrd_states.view.sizeFactor;
|
|
332
326
|
this.enableCrosshair();
|
|
333
|
-
this.protectedData.canvases.drawingCanvas.addEventListener("pointerup", this.drawingPrameters.handleOnDrawingMouseUp);
|
|
334
327
|
}
|
|
335
|
-
else if (this.gui_states.mode.sphere && !
|
|
328
|
+
else if (this.state.gui_states.mode.sphere && !this.eventRouter.isCrosshairEnabled()) {
|
|
336
329
|
this.handleSphereClick(e);
|
|
337
330
|
}
|
|
338
331
|
}
|
|
339
332
|
else if (e.button === 2) {
|
|
340
333
|
this.panTool.onPointerDown(e);
|
|
341
|
-
this.protectedData.canvases.drawingCanvas.addEventListener("pointerup", this.drawingPrameters.handleOnDrawingMouseUp);
|
|
342
334
|
}
|
|
343
335
|
else {
|
|
344
336
|
return;
|
|
345
337
|
}
|
|
346
338
|
};
|
|
347
|
-
// Route pointerdown through EventRouter
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
this.drawingPrameters.handleOnDrawingMouseDown(e);
|
|
352
|
-
});
|
|
353
|
-
}
|
|
354
|
-
else {
|
|
355
|
-
// Fallback for legacy mode without EventRouter
|
|
356
|
-
this.protectedData.canvases.drawingCanvas.addEventListener("pointerdown", this.drawingPrameters.handleOnDrawingMouseDown, true);
|
|
357
|
-
}
|
|
339
|
+
// Route pointerdown through EventRouter
|
|
340
|
+
this.eventRouter.setPointerDownHandler((e) => {
|
|
341
|
+
this.drawingPrameters.handleOnDrawingMouseDown(e);
|
|
342
|
+
});
|
|
358
343
|
this.drawingPrameters.handleOnDrawingMouseUp = (e) => {
|
|
359
|
-
var _a, _b, _c;
|
|
360
344
|
if (e.button === 0) {
|
|
361
|
-
if (
|
|
345
|
+
if (this.eventRouter.getMode() === 'draw' || this.drawingTool.painting) {
|
|
362
346
|
this.drawingTool.onPointerUp(e);
|
|
363
|
-
this.
|
|
364
|
-
// add wheel after pointer up
|
|
365
|
-
this.protectedData.canvases.drawingCanvas.addEventListener("wheel", this.drawingPrameters.handleMouseZoomSliceWheel, {
|
|
366
|
-
passive: false,
|
|
367
|
-
});
|
|
347
|
+
this.activeWheelMode = 'zoom';
|
|
368
348
|
}
|
|
369
|
-
else if (this.gui_states.mode.sphere &&
|
|
370
|
-
!
|
|
371
|
-
|
|
372
|
-
this.
|
|
373
|
-
// Render current slice from volume to sphere canvas
|
|
374
|
-
this.sphereTool.refreshSphereCanvas();
|
|
375
|
-
this.annotationCallbacks.onSphereChanged(this.nrrd_states.sphere.sphereOrigin.z, this.nrrd_states.sphere.sphereRadius / this.nrrd_states.view.sizeFactor);
|
|
376
|
-
this.annotationCallbacks.onCalculatorPositionsChanged(this.nrrd_states.sphere.tumourSphereOrigin, this.nrrd_states.sphere.skinSphereOrigin, this.nrrd_states.sphere.ribSphereOrigin, this.nrrd_states.sphere.nippleSphereOrigin, this.protectedData.axis);
|
|
377
|
-
this.protectedData.canvases.drawingCanvas.removeEventListener("wheel", this.drawingPrameters.handleSphereWheel, true);
|
|
378
|
-
this.protectedData.canvases.drawingCanvas.addEventListener("wheel", this.drawingPrameters.handleMouseZoomSliceWheel);
|
|
379
|
-
this.protectedData.canvases.drawingCanvas.removeEventListener("pointerup", this.drawingPrameters.handleOnDrawingMouseUp);
|
|
349
|
+
else if (this.state.gui_states.mode.sphere &&
|
|
350
|
+
!this.eventRouter.isCrosshairEnabled()) {
|
|
351
|
+
this.sphereTool.onSpherePointerUp();
|
|
352
|
+
this.activeWheelMode = 'zoom';
|
|
380
353
|
this.zoomActionAfterDrawSphere();
|
|
381
354
|
}
|
|
382
|
-
else if (this.gui_states.mode.sphere &&
|
|
383
|
-
|
|
384
|
-
this.
|
|
385
|
-
this.protectedData.canvases.drawingCanvas.removeEventListener("pointerup", this.drawingPrameters.handleOnDrawingMouseUp);
|
|
355
|
+
else if (this.state.gui_states.mode.sphere &&
|
|
356
|
+
this.eventRouter.isCrosshairEnabled()) {
|
|
357
|
+
this.activeWheelMode = 'zoom';
|
|
386
358
|
}
|
|
387
359
|
}
|
|
388
360
|
else if (e.button === 2) {
|
|
389
|
-
this.panTool.onPointerUp(e, this.gui_states.viewConfig.defaultPaintCursor);
|
|
361
|
+
this.panTool.onPointerUp(e, this.state.gui_states.viewConfig.defaultPaintCursor);
|
|
390
362
|
}
|
|
391
363
|
else {
|
|
392
364
|
return;
|
|
393
365
|
}
|
|
394
|
-
if (!this.gui_states.mode.pencil) {
|
|
366
|
+
if (!this.state.gui_states.mode.pencil) {
|
|
395
367
|
this.setIsDrawFalse(100);
|
|
396
368
|
}
|
|
397
369
|
};
|
|
398
|
-
this.protectedData.canvases.drawingCanvas.addEventListener("pointerleave", () => {
|
|
399
|
-
const wasDrawing = this.drawingTool.onPointerLeave();
|
|
400
|
-
if (wasDrawing) {
|
|
401
|
-
this.protectedData.canvases.drawingCanvas.removeEventListener("pointermove", this.drawingPrameters.handleOnDrawingMouseMove);
|
|
402
|
-
this.protectedData.canvases.drawingCanvas.removeEventListener("wheel", this.drawingPrameters.handleSphereWheel, true);
|
|
403
|
-
}
|
|
404
|
-
this.panTool.onPointerLeave();
|
|
405
|
-
this.setIsDrawFalse(100);
|
|
406
|
-
if (this.gui_states.mode.pencil) {
|
|
407
|
-
this.setIsDrawFalse(1000);
|
|
408
|
-
}
|
|
409
|
-
});
|
|
410
370
|
this.start = () => {
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
this.protectedData.ctxes.drawingCtx.
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
this.protectedData.ctxes.drawingLayerMasterCtx.
|
|
418
|
-
this.protectedData.
|
|
419
|
-
for (const [, target] of this.protectedData.layerTargets) {
|
|
371
|
+
if (this.state.gui_states.viewConfig.readyToUpdate) {
|
|
372
|
+
this.state.protectedData.ctxes.drawingCtx.clearRect(0, 0, this.state.nrrd_states.view.changedWidth, this.state.nrrd_states.view.changedHeight);
|
|
373
|
+
this.state.protectedData.ctxes.drawingCtx.globalAlpha =
|
|
374
|
+
this.state.gui_states.drawing.globalAlpha;
|
|
375
|
+
if (this.state.protectedData.isDrawing) {
|
|
376
|
+
this.state.protectedData.ctxes.drawingLayerMasterCtx.lineCap = "round";
|
|
377
|
+
this.state.protectedData.ctxes.drawingLayerMasterCtx.globalAlpha = 1;
|
|
378
|
+
for (const [, target] of this.state.protectedData.layerTargets) {
|
|
420
379
|
target.ctx.lineCap = "round";
|
|
421
380
|
target.ctx.globalAlpha = 1;
|
|
422
381
|
}
|
|
423
382
|
}
|
|
424
383
|
else {
|
|
425
|
-
|
|
426
|
-
const currentMode = (_a = this.eventRouter) === null || _a === void 0 ? void 0 : _a.getMode();
|
|
384
|
+
const currentMode = this.eventRouter.getMode();
|
|
427
385
|
if (currentMode === 'draw') {
|
|
428
|
-
|
|
429
|
-
if (!this.gui_states.mode.pencil &&
|
|
430
|
-
!this.gui_states.mode.eraser &&
|
|
431
|
-
this.nrrd_states.interaction.mouseOver) {
|
|
432
|
-
this.protectedData.ctxes.drawingCtx.clearRect(0, 0, this.nrrd_states.view.changedWidth, this.nrrd_states.view.changedHeight);
|
|
433
|
-
this.protectedData.ctxes.drawingCtx.fillStyle =
|
|
434
|
-
this.gui_states.drawing.brushColor;
|
|
435
|
-
this.protectedData.ctxes.drawingCtx.beginPath();
|
|
436
|
-
this.protectedData.ctxes.drawingCtx.arc(this.nrrd_states.interaction.mouseOverX, this.nrrd_states.interaction.mouseOverY, this.gui_states.drawing.brushAndEraserSize / 2 + 1, 0, Math.PI * 2);
|
|
437
|
-
this.protectedData.ctxes.drawingCtx.strokeStyle =
|
|
438
|
-
this.gui_states.drawing.brushColor;
|
|
439
|
-
this.protectedData.ctxes.drawingCtx.stroke();
|
|
440
|
-
}
|
|
386
|
+
this.drawingTool.renderBrushPreview(this.state.protectedData.ctxes.drawingCtx, this.state.nrrd_states.view.changedWidth, this.state.nrrd_states.view.changedHeight);
|
|
441
387
|
}
|
|
442
|
-
else if (currentMode === 'crosshair' ||
|
|
443
|
-
|
|
444
|
-
this.protectedData.ctxes.drawingCtx.clearRect(0, 0, this.nrrd_states.view.changedWidth, this.nrrd_states.view.changedHeight);
|
|
445
|
-
const ex = this.nrrd_states.interaction.cursorPageX * this.nrrd_states.view.sizeFactor;
|
|
446
|
-
const ey = this.nrrd_states.interaction.cursorPageY * this.nrrd_states.view.sizeFactor;
|
|
447
|
-
this.drawLine(ex, 0, ex, this.nrrd_states.view.changedWidth);
|
|
448
|
-
this.drawLine(0, ey, this.nrrd_states.view.changedHeight, ey);
|
|
388
|
+
else if (currentMode === 'crosshair' || this.eventRouter.isCrosshairEnabled()) {
|
|
389
|
+
this.crosshairTool.renderCrosshair(this.state.protectedData.ctxes.drawingCtx, this.state.nrrd_states.view.changedWidth, this.state.nrrd_states.view.changedHeight);
|
|
449
390
|
}
|
|
450
391
|
}
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
// Draw sphere overlay from cached sphere canvas (separate from master).
|
|
455
|
-
// During preview: drawSphere/drawCalculatorSphere update the sphere canvas.
|
|
456
|
-
// After placement: refreshSphereCanvas renders from sphereMaskVolume.
|
|
457
|
-
if (this.gui_states.mode.sphere) {
|
|
458
|
-
this.protectedData.ctxes.drawingCtx.drawImage(this.protectedData.canvases.drawingSphereCanvas, 0, 0, this.nrrd_states.view.changedWidth, this.nrrd_states.view.changedHeight);
|
|
392
|
+
this.state.protectedData.ctxes.drawingCtx.drawImage(this.state.protectedData.canvases.drawingCanvasLayerMaster, 0, 0);
|
|
393
|
+
if (this.state.gui_states.mode.sphere) {
|
|
394
|
+
this.state.protectedData.ctxes.drawingCtx.drawImage(this.state.protectedData.canvases.drawingSphereCanvas, 0, 0, this.state.nrrd_states.view.changedWidth, this.state.nrrd_states.view.changedHeight);
|
|
459
395
|
}
|
|
460
396
|
}
|
|
461
397
|
else {
|
|
@@ -463,87 +399,67 @@ export class DrawToolCore extends CommToolsData {
|
|
|
463
399
|
}
|
|
464
400
|
};
|
|
465
401
|
}
|
|
402
|
+
/**
|
|
403
|
+
* Extracted from paintOnCanvas() pointerleave handler.
|
|
404
|
+
*/
|
|
405
|
+
handlePointerLeave() {
|
|
406
|
+
const wasDrawing = this.drawingTool.onPointerLeave();
|
|
407
|
+
if (wasDrawing) {
|
|
408
|
+
this.activeWheelMode = 'zoom';
|
|
409
|
+
}
|
|
410
|
+
this.panTool.onPointerLeave();
|
|
411
|
+
this.setIsDrawFalse(100);
|
|
412
|
+
if (this.state.gui_states.mode.pencil) {
|
|
413
|
+
this.setIsDrawFalse(1000);
|
|
414
|
+
}
|
|
415
|
+
}
|
|
466
416
|
/** Extracted from paintOnCanvas() — handles sphere placement on left-click */
|
|
467
417
|
handleSphereClick(e) {
|
|
468
|
-
this.
|
|
469
|
-
|
|
470
|
-
let mouseY = e.offsetY / this.nrrd_states.view.sizeFactor;
|
|
471
|
-
// record mouseX,Y, and enable crosshair function
|
|
472
|
-
this.nrrd_states.sphere.sphereOrigin[this.protectedData.axis] = [
|
|
473
|
-
mouseX,
|
|
474
|
-
mouseY,
|
|
475
|
-
this.nrrd_states.view.currentSliceIndex,
|
|
476
|
-
];
|
|
477
|
-
this.setUpSphereOrigins(mouseX, mouseY, this.nrrd_states.view.currentSliceIndex);
|
|
478
|
-
// Store origin for the active sphere type
|
|
479
|
-
const calPos = this.gui_states.mode.activeSphereType;
|
|
480
|
-
switch (calPos) {
|
|
481
|
-
case "tumour":
|
|
482
|
-
this.nrrd_states.sphere.tumourSphereOrigin = JSON.parse(JSON.stringify(this.nrrd_states.sphere.sphereOrigin));
|
|
483
|
-
break;
|
|
484
|
-
case "skin":
|
|
485
|
-
this.nrrd_states.sphere.skinSphereOrigin = JSON.parse(JSON.stringify(this.nrrd_states.sphere.sphereOrigin));
|
|
486
|
-
break;
|
|
487
|
-
case "nipple":
|
|
488
|
-
this.nrrd_states.sphere.nippleSphereOrigin = JSON.parse(JSON.stringify(this.nrrd_states.sphere.sphereOrigin));
|
|
489
|
-
break;
|
|
490
|
-
case "ribcage":
|
|
491
|
-
this.nrrd_states.sphere.ribSphereOrigin = JSON.parse(JSON.stringify(this.nrrd_states.sphere.sphereOrigin));
|
|
492
|
-
break;
|
|
493
|
-
}
|
|
494
|
-
this.nrrd_states.interaction.cursorPageX = mouseX;
|
|
495
|
-
this.nrrd_states.interaction.cursorPageY = mouseY;
|
|
496
|
-
this.enableCrosshair();
|
|
497
|
-
// draw circle setup width/height for sphere canvas
|
|
498
|
-
this.drawCalculatorSphere(this.nrrd_states.sphere.sphereRadius);
|
|
499
|
-
this.protectedData.canvases.drawingCanvas.addEventListener("wheel", this.drawingPrameters.handleSphereWheel, true);
|
|
500
|
-
this.protectedData.canvases.drawingCanvas.addEventListener("pointerup", this.drawingPrameters.handleOnDrawingMouseUp);
|
|
418
|
+
this.activeWheelMode = 'sphere';
|
|
419
|
+
this.sphereTool.onSphereClick(e);
|
|
501
420
|
}
|
|
502
421
|
initAllCanvas() {
|
|
503
422
|
/**
|
|
504
423
|
* display canvas
|
|
505
424
|
*/
|
|
506
|
-
this.protectedData.canvases.displayCanvas.style.position = "absolute";
|
|
507
|
-
this.protectedData.canvases.displayCanvas.style.zIndex = "9";
|
|
508
|
-
this.protectedData.canvases.displayCanvas.width =
|
|
509
|
-
this.nrrd_states.view.changedWidth;
|
|
510
|
-
this.protectedData.canvases.displayCanvas.height =
|
|
511
|
-
this.nrrd_states.view.changedHeight;
|
|
425
|
+
this.state.protectedData.canvases.displayCanvas.style.position = "absolute";
|
|
426
|
+
this.state.protectedData.canvases.displayCanvas.style.zIndex = "9";
|
|
427
|
+
this.state.protectedData.canvases.displayCanvas.width =
|
|
428
|
+
this.state.nrrd_states.view.changedWidth;
|
|
429
|
+
this.state.protectedData.canvases.displayCanvas.height =
|
|
430
|
+
this.state.nrrd_states.view.changedHeight;
|
|
512
431
|
/**
|
|
513
432
|
* drawing canvas
|
|
514
433
|
*/
|
|
515
|
-
this.protectedData.canvases.drawingCanvas.style.zIndex = "10";
|
|
516
|
-
this.protectedData.canvases.drawingCanvas.style.position = "absolute";
|
|
517
|
-
this.protectedData.canvases.drawingCanvas.width =
|
|
518
|
-
this.nrrd_states.view.changedWidth;
|
|
519
|
-
this.protectedData.canvases.drawingCanvas.height =
|
|
520
|
-
this.nrrd_states.view.changedHeight;
|
|
521
|
-
this.protectedData.canvases.drawingCanvas.style.cursor =
|
|
522
|
-
this.gui_states.viewConfig.defaultPaintCursor;
|
|
523
|
-
this.protectedData.canvases.drawingCanvas.oncontextmenu = () => false;
|
|
434
|
+
this.state.protectedData.canvases.drawingCanvas.style.zIndex = "10";
|
|
435
|
+
this.state.protectedData.canvases.drawingCanvas.style.position = "absolute";
|
|
436
|
+
this.state.protectedData.canvases.drawingCanvas.width =
|
|
437
|
+
this.state.nrrd_states.view.changedWidth;
|
|
438
|
+
this.state.protectedData.canvases.drawingCanvas.height =
|
|
439
|
+
this.state.nrrd_states.view.changedHeight;
|
|
440
|
+
this.state.protectedData.canvases.drawingCanvas.style.cursor =
|
|
441
|
+
this.state.gui_states.viewConfig.defaultPaintCursor;
|
|
442
|
+
this.state.protectedData.canvases.drawingCanvas.oncontextmenu = () => false;
|
|
524
443
|
/**
|
|
525
|
-
*
|
|
526
|
-
* it should be hide, so we don't need to add it to mainAreaContainer
|
|
444
|
+
* layer canvases
|
|
527
445
|
*/
|
|
528
|
-
this.protectedData.canvases.drawingCanvasLayerMaster.width =
|
|
529
|
-
this.nrrd_states.view.changedWidth;
|
|
530
|
-
this.protectedData.canvases.drawingCanvasLayerMaster.height =
|
|
531
|
-
this.nrrd_states.view.changedHeight;
|
|
532
|
-
for (const [, target] of this.protectedData.layerTargets) {
|
|
533
|
-
target.canvas.width = this.nrrd_states.view.changedWidth;
|
|
534
|
-
target.canvas.height = this.nrrd_states.view.changedHeight;
|
|
446
|
+
this.state.protectedData.canvases.drawingCanvasLayerMaster.width =
|
|
447
|
+
this.state.nrrd_states.view.changedWidth;
|
|
448
|
+
this.state.protectedData.canvases.drawingCanvasLayerMaster.height =
|
|
449
|
+
this.state.nrrd_states.view.changedHeight;
|
|
450
|
+
for (const [, target] of this.state.protectedData.layerTargets) {
|
|
451
|
+
target.canvas.width = this.state.nrrd_states.view.changedWidth;
|
|
452
|
+
target.canvas.height = this.state.nrrd_states.view.changedHeight;
|
|
535
453
|
}
|
|
536
454
|
/**
|
|
537
455
|
* display and drawing canvas container
|
|
538
456
|
*/
|
|
539
|
-
// this.mainAreaContainer.style.width = this.nrrd_states.view.changedWidth + "px";
|
|
540
|
-
// this.mainAreaContainer.style.height = this.nrrd_states.view.changedHeight + "px";
|
|
541
457
|
this.mainAreaContainer.style.width =
|
|
542
|
-
this.nrrd_states.image.originWidth * 8 + "px";
|
|
458
|
+
this.state.nrrd_states.image.originWidth * 8 + "px";
|
|
543
459
|
this.mainAreaContainer.style.height =
|
|
544
|
-
this.nrrd_states.image.originHeight * 8 + "px";
|
|
545
|
-
this.mainAreaContainer.appendChild(this.protectedData.canvases.displayCanvas);
|
|
546
|
-
this.mainAreaContainer.appendChild(this.protectedData.canvases.drawingCanvas);
|
|
460
|
+
this.state.nrrd_states.image.originHeight * 8 + "px";
|
|
461
|
+
this.mainAreaContainer.appendChild(this.state.protectedData.canvases.displayCanvas);
|
|
462
|
+
this.mainAreaContainer.appendChild(this.state.protectedData.canvases.drawingCanvas);
|
|
547
463
|
}
|
|
548
464
|
useEraser() {
|
|
549
465
|
return this.eraserTool.createClearArc();
|
|
@@ -563,13 +479,9 @@ export class DrawToolCore extends CommToolsData {
|
|
|
563
479
|
this.crosshairTool.enableCrosshair();
|
|
564
480
|
}
|
|
565
481
|
drawImageOnEmptyImage(canvas) {
|
|
566
|
-
const ctx = this.protectedData.ctxes.emptyCtx;
|
|
567
|
-
const w = this.protectedData.canvases.emptyCanvas.width;
|
|
568
|
-
const h = this.protectedData.canvases.emptyCanvas.height;
|
|
569
|
-
// No flip needed: the layer canvas screen coordinates already match the
|
|
570
|
-
// Three.js source coordinate system used by MaskVolume. Applying a flip
|
|
571
|
-
// here would invert cross-axis slice indices (e.g. coronal slice 220
|
|
572
|
-
// becoming 228 when total=448).
|
|
482
|
+
const ctx = this.state.protectedData.ctxes.emptyCtx;
|
|
483
|
+
const w = this.state.protectedData.canvases.emptyCanvas.width;
|
|
484
|
+
const h = this.state.protectedData.canvases.emptyCanvas.height;
|
|
573
485
|
ctx.imageSmoothingEnabled = false;
|
|
574
486
|
ctx.drawImage(canvas, 0, 0, w, h);
|
|
575
487
|
}
|
|
@@ -577,9 +489,6 @@ export class DrawToolCore extends CommToolsData {
|
|
|
577
489
|
drawCalculatorSphereOnEachViews(axis) {
|
|
578
490
|
this.sphereTool.drawCalculatorSphereOnEachViews(axis);
|
|
579
491
|
}
|
|
580
|
-
drawSphereOnEachViews(decay, axis) {
|
|
581
|
-
this.sphereTool.drawSphereOnEachViews(decay, axis);
|
|
582
|
-
}
|
|
583
492
|
configMouseSphereWheel() {
|
|
584
493
|
return this.sphereTool.configMouseSphereWheel();
|
|
585
494
|
}
|
|
@@ -591,10 +500,9 @@ export class DrawToolCore extends CommToolsData {
|
|
|
591
500
|
}
|
|
592
501
|
/**
|
|
593
502
|
* Refresh sphere canvas from sphereMaskVolume for the current slice/axis.
|
|
594
|
-
* Called after view changes (slice switch, zoom, contrast, axis switch).
|
|
595
503
|
*/
|
|
596
504
|
refreshSphereOverlay() {
|
|
597
|
-
if (this.gui_states.mode.sphere) {
|
|
505
|
+
if (this.state.gui_states.mode.sphere) {
|
|
598
506
|
this.sphereTool.refreshSphereCanvas();
|
|
599
507
|
}
|
|
600
508
|
}
|
|
@@ -610,42 +518,30 @@ export class DrawToolCore extends CommToolsData {
|
|
|
610
518
|
}
|
|
611
519
|
/****************************layer div controls****************************************************/
|
|
612
520
|
getRestLayer() {
|
|
613
|
-
const layers = this.nrrd_states.image.layers;
|
|
521
|
+
const layers = this.state.nrrd_states.image.layers;
|
|
614
522
|
const restLayer = layers.filter((item) => {
|
|
615
|
-
return item !== this.gui_states.layerChannel.layer;
|
|
523
|
+
return item !== this.state.gui_states.layerChannel.layer;
|
|
616
524
|
});
|
|
617
525
|
return restLayer;
|
|
618
526
|
}
|
|
619
527
|
/**************************** Undo/Redo functions (Phase 6 — Delta-based) ****************************/
|
|
620
528
|
/**
|
|
621
529
|
* Clear the mask on the current slice canvas for the active layer ONLY.
|
|
622
|
-
*
|
|
623
|
-
* This method only clears the active layer's MaskVolume slice data for the
|
|
624
|
-
* currently viewed slice index. Other slices in the same layer remain intact.
|
|
625
|
-
* Other background layers are also left untouched.
|
|
626
|
-
* After clearing, all layer canvases are re-rendered from the `MaskVolume`
|
|
627
|
-
* to keep the visuals in sync.
|
|
628
|
-
*
|
|
629
|
-
* The operation is recorded to the UndoManager to allow for user rollback.
|
|
630
530
|
*/
|
|
631
531
|
clearActiveSlice() {
|
|
632
|
-
this.protectedData.isDrawing = true;
|
|
633
|
-
this.protectedData.canvases.originCanvas.width =
|
|
634
|
-
this.protectedData.canvases.originCanvas.width;
|
|
635
|
-
this.protectedData.mainPreSlices.repaint.call(this.protectedData.mainPreSlices);
|
|
532
|
+
this.state.protectedData.isDrawing = true;
|
|
533
|
+
this.state.protectedData.canvases.originCanvas.width =
|
|
534
|
+
this.state.protectedData.canvases.originCanvas.width;
|
|
535
|
+
this.state.protectedData.mainPreSlices.repaint.call(this.state.protectedData.mainPreSlices);
|
|
636
536
|
// Clear only the active layer's MaskVolume slice and record undo delta
|
|
637
537
|
try {
|
|
638
|
-
const axis = this.protectedData.axis;
|
|
639
|
-
const idx = this.nrrd_states.view.currentSliceIndex;
|
|
640
|
-
const activeLayer = this.gui_states.layerChannel.layer;
|
|
641
|
-
const vol = this.getVolumeForLayer(activeLayer);
|
|
642
|
-
// Capture old slice for undo before clearing
|
|
538
|
+
const axis = this.state.protectedData.axis;
|
|
539
|
+
const idx = this.state.nrrd_states.view.currentSliceIndex;
|
|
540
|
+
const activeLayer = this.state.gui_states.layerChannel.layer;
|
|
541
|
+
const vol = this.renderer.getVolumeForLayer(activeLayer);
|
|
643
542
|
const oldSlice = vol.getSliceUint8(idx, axis).data.slice();
|
|
644
|
-
// Clear only the active layer's MaskVolume slice
|
|
645
543
|
vol.clearSlice(idx, axis);
|
|
646
|
-
// New (all-zero) slice for undo newSlice
|
|
647
544
|
const { data: newSlice, width, height } = vol.getSliceUint8(idx, axis);
|
|
648
|
-
// Push clearActiveSlice delta to UndoManager (supports undo)
|
|
649
545
|
this.undoManager.push({
|
|
650
546
|
layerId: activeLayer,
|
|
651
547
|
axis,
|
|
@@ -653,106 +549,96 @@ export class DrawToolCore extends CommToolsData {
|
|
|
653
549
|
oldSlice,
|
|
654
550
|
newSlice: newSlice.slice(),
|
|
655
551
|
});
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
this.annotationCallbacks.onMaskChanged(newSlice, activeLayer, activeChannel, idx, axis, width, height, true // clearFlag = true
|
|
660
|
-
);
|
|
552
|
+
if (!this.state.nrrd_states.flags.loadingMaskData && !this.state.gui_states.mode.sphere) {
|
|
553
|
+
const activeChannel = this.state.gui_states.layerChannel.activeChannel || 1;
|
|
554
|
+
this.state.annotationCallbacks.onMaskChanged(newSlice, activeLayer, activeChannel, idx, axis, width, height, true);
|
|
661
555
|
}
|
|
662
556
|
}
|
|
663
557
|
catch (_a) {
|
|
664
558
|
// Volume not ready (1×1×1 placeholder)
|
|
665
559
|
}
|
|
666
|
-
// Re-render ALL layers from MaskVolume to canvas (rebuilds visuals from source of truth)
|
|
667
560
|
this.resetLayerCanvas();
|
|
668
|
-
const buffer = this.getOrCreateSliceBuffer(this.protectedData.axis);
|
|
561
|
+
const buffer = this.renderer.getOrCreateSliceBuffer(this.state.protectedData.axis);
|
|
669
562
|
if (buffer) {
|
|
670
|
-
const w = this.nrrd_states.view.changedWidth;
|
|
671
|
-
const h = this.nrrd_states.view.changedHeight;
|
|
672
|
-
for (const layerId of this.nrrd_states.image.layers) {
|
|
673
|
-
const target = this.protectedData.layerTargets.get(layerId);
|
|
563
|
+
const w = this.state.nrrd_states.view.changedWidth;
|
|
564
|
+
const h = this.state.nrrd_states.view.changedHeight;
|
|
565
|
+
for (const layerId of this.state.nrrd_states.image.layers) {
|
|
566
|
+
const target = this.state.protectedData.layerTargets.get(layerId);
|
|
674
567
|
if (!target)
|
|
675
568
|
continue;
|
|
676
569
|
target.ctx.clearRect(0, 0, w, h);
|
|
677
|
-
this.renderSliceToCanvas(layerId, this.protectedData.axis, this.nrrd_states.view.currentSliceIndex, buffer, target.ctx, w, h);
|
|
570
|
+
this.renderer.renderSliceToCanvas(layerId, this.state.protectedData.axis, this.state.nrrd_states.view.currentSliceIndex, buffer, target.ctx, w, h);
|
|
678
571
|
}
|
|
679
572
|
}
|
|
680
|
-
this.compositeAllLayers();
|
|
573
|
+
this.renderer.compositeAllLayers();
|
|
681
574
|
this.setIsDrawFalse(1000);
|
|
682
575
|
}
|
|
683
576
|
/**
|
|
684
577
|
* Undo the last drawing operation on the active layer.
|
|
685
|
-
* Restores the MaskVolume slice to its pre-draw state, re-renders
|
|
686
|
-
* the canvas, and notifies the backend.
|
|
687
578
|
*/
|
|
688
579
|
undoLastPainting() {
|
|
689
580
|
const delta = this.undoManager.undo();
|
|
690
581
|
if (!delta)
|
|
691
582
|
return;
|
|
692
583
|
try {
|
|
693
|
-
const vol = this.getVolumeForLayer(delta.layerId);
|
|
584
|
+
const vol = this.renderer.getVolumeForLayer(delta.layerId);
|
|
694
585
|
vol.setSliceUint8(delta.sliceIndex, delta.oldSlice, delta.axis);
|
|
695
586
|
}
|
|
696
587
|
catch (_a) {
|
|
697
|
-
return;
|
|
588
|
+
return;
|
|
698
589
|
}
|
|
699
|
-
this.protectedData.isDrawing = true;
|
|
700
|
-
if (delta.axis === this.protectedData.axis && delta.sliceIndex === this.nrrd_states.view.currentSliceIndex) {
|
|
590
|
+
this.state.protectedData.isDrawing = true;
|
|
591
|
+
if (delta.axis === this.state.protectedData.axis && delta.sliceIndex === this.state.nrrd_states.view.currentSliceIndex) {
|
|
701
592
|
this.applyUndoRedoToCanvas(delta.layerId);
|
|
702
593
|
}
|
|
703
|
-
if (!this.nrrd_states.flags.loadingMaskData) {
|
|
704
|
-
const { data: sliceData, width, height } = this.getVolumeForLayer(delta.layerId)
|
|
594
|
+
if (!this.state.nrrd_states.flags.loadingMaskData) {
|
|
595
|
+
const { data: sliceData, width, height } = this.renderer.getVolumeForLayer(delta.layerId)
|
|
705
596
|
.getSliceUint8(delta.sliceIndex, delta.axis);
|
|
706
|
-
this.annotationCallbacks.onMaskChanged(sliceData, delta.layerId, this.gui_states.layerChannel.activeChannel || 1, delta.sliceIndex, delta.axis, width, height, false);
|
|
597
|
+
this.state.annotationCallbacks.onMaskChanged(sliceData, delta.layerId, this.state.gui_states.layerChannel.activeChannel || 1, delta.sliceIndex, delta.axis, width, height, false);
|
|
707
598
|
}
|
|
708
599
|
this.setIsDrawFalse(1000);
|
|
709
600
|
}
|
|
710
601
|
/**
|
|
711
602
|
* Redo the last undone operation on the active layer.
|
|
712
|
-
* Reapplies the MaskVolume slice to its post-draw state, re-renders
|
|
713
|
-
* the canvas, and notifies the backend.
|
|
714
603
|
*/
|
|
715
604
|
redoLastPainting() {
|
|
716
605
|
const delta = this.undoManager.redo();
|
|
717
606
|
if (!delta)
|
|
718
607
|
return;
|
|
719
608
|
try {
|
|
720
|
-
const vol = this.getVolumeForLayer(delta.layerId);
|
|
609
|
+
const vol = this.renderer.getVolumeForLayer(delta.layerId);
|
|
721
610
|
vol.setSliceUint8(delta.sliceIndex, delta.newSlice, delta.axis);
|
|
722
611
|
}
|
|
723
612
|
catch (_a) {
|
|
724
|
-
return;
|
|
613
|
+
return;
|
|
725
614
|
}
|
|
726
|
-
this.protectedData.isDrawing = true;
|
|
727
|
-
if (delta.axis === this.protectedData.axis && delta.sliceIndex === this.nrrd_states.view.currentSliceIndex) {
|
|
615
|
+
this.state.protectedData.isDrawing = true;
|
|
616
|
+
if (delta.axis === this.state.protectedData.axis && delta.sliceIndex === this.state.nrrd_states.view.currentSliceIndex) {
|
|
728
617
|
this.applyUndoRedoToCanvas(delta.layerId);
|
|
729
618
|
}
|
|
730
|
-
if (!this.nrrd_states.flags.loadingMaskData) {
|
|
731
|
-
const { data: sliceData, width, height } = this.getVolumeForLayer(delta.layerId)
|
|
619
|
+
if (!this.state.nrrd_states.flags.loadingMaskData) {
|
|
620
|
+
const { data: sliceData, width, height } = this.renderer.getVolumeForLayer(delta.layerId)
|
|
732
621
|
.getSliceUint8(delta.sliceIndex, delta.axis);
|
|
733
|
-
this.annotationCallbacks.onMaskChanged(sliceData, delta.layerId, this.gui_states.layerChannel.activeChannel || 1, delta.sliceIndex, delta.axis, width, height, false);
|
|
622
|
+
this.state.annotationCallbacks.onMaskChanged(sliceData, delta.layerId, this.state.gui_states.layerChannel.activeChannel || 1, delta.sliceIndex, delta.axis, width, height, false);
|
|
734
623
|
}
|
|
735
624
|
this.setIsDrawFalse(1000);
|
|
736
625
|
}
|
|
737
626
|
/**
|
|
738
627
|
* Re-render a layer canvas from MaskVolume and composite to master.
|
|
739
|
-
* Called after writing oldSlice/newSlice back to the volume during undo/redo.
|
|
740
628
|
*/
|
|
741
629
|
applyUndoRedoToCanvas(layerId) {
|
|
742
|
-
let target = this.protectedData.layerTargets.get(layerId);
|
|
630
|
+
let target = this.state.protectedData.layerTargets.get(layerId);
|
|
743
631
|
if (!target) {
|
|
744
|
-
const firstId = this.nrrd_states.image.layers[0];
|
|
745
|
-
target = this.protectedData.layerTargets.get(firstId);
|
|
632
|
+
const firstId = this.state.nrrd_states.image.layers[0];
|
|
633
|
+
target = this.state.protectedData.layerTargets.get(firstId);
|
|
746
634
|
}
|
|
747
635
|
const { ctx, canvas } = target;
|
|
748
|
-
// Clear and re-render the affected layer canvas from MaskVolume
|
|
749
636
|
canvas.width = canvas.width;
|
|
750
|
-
const buffer = this.getOrCreateSliceBuffer(this.protectedData.axis);
|
|
637
|
+
const buffer = this.renderer.getOrCreateSliceBuffer(this.state.protectedData.axis);
|
|
751
638
|
if (buffer) {
|
|
752
|
-
this.renderSliceToCanvas(layerId, this.protectedData.axis, this.nrrd_states.view.currentSliceIndex, buffer, ctx, this.nrrd_states.view.changedWidth, this.nrrd_states.view.changedHeight);
|
|
639
|
+
this.renderer.renderSliceToCanvas(layerId, this.state.protectedData.axis, this.state.nrrd_states.view.currentSliceIndex, buffer, ctx, this.state.nrrd_states.view.changedWidth, this.state.nrrd_states.view.changedHeight);
|
|
753
640
|
}
|
|
754
|
-
|
|
755
|
-
this.compositeAllLayers();
|
|
641
|
+
this.renderer.compositeAllLayers();
|
|
756
642
|
}
|
|
757
643
|
/****************************Store images (delegated to ImageStoreHelper)****************************************************/
|
|
758
644
|
syncLayerSliceData(index, layer) {
|
|
@@ -762,5 +648,50 @@ export class DrawToolCore extends CommToolsData {
|
|
|
762
648
|
setupConrastEvents(callback) {
|
|
763
649
|
this.contrastTool.setupConrastEvents(callback);
|
|
764
650
|
}
|
|
651
|
+
// ── Pseudo-abstract methods (overridden by NrrdTools via callback injection) ──
|
|
652
|
+
/** Override in NrrdTools */
|
|
653
|
+
setIsDrawFalse(target) {
|
|
654
|
+
throw new Error("setIsDrawFalse must be provided by NrrdTools");
|
|
655
|
+
}
|
|
656
|
+
/** Override in NrrdTools */
|
|
657
|
+
setSyncsliceNum() {
|
|
658
|
+
throw new Error("setSyncsliceNum must be provided by NrrdTools");
|
|
659
|
+
}
|
|
660
|
+
/** Override in NrrdTools */
|
|
661
|
+
resetPaintAreaUIPosition(l, t) {
|
|
662
|
+
throw new Error("resetPaintAreaUIPosition must be provided by NrrdTools");
|
|
663
|
+
}
|
|
664
|
+
/** Override in NrrdTools */
|
|
665
|
+
resizePaintArea(factor) {
|
|
666
|
+
throw new Error("resizePaintArea must be provided by NrrdTools");
|
|
667
|
+
}
|
|
668
|
+
/** Override in NrrdTools */
|
|
669
|
+
setEmptyCanvasSize(axis) {
|
|
670
|
+
throw new Error("setEmptyCanvasSize must be provided by NrrdTools");
|
|
671
|
+
}
|
|
672
|
+
/** Override in NrrdTools */
|
|
673
|
+
flipDisplayImageByAxis() {
|
|
674
|
+
throw new Error("flipDisplayImageByAxis must be provided by NrrdTools");
|
|
675
|
+
}
|
|
676
|
+
/** Override in NrrdTools */
|
|
677
|
+
updateOriginAndChangedWH() {
|
|
678
|
+
throw new Error("updateOriginAndChangedWH must be provided by NrrdTools");
|
|
679
|
+
}
|
|
680
|
+
/** Override in NrrdTools */
|
|
681
|
+
resetLayerCanvas() {
|
|
682
|
+
throw new Error("resetLayerCanvas must be provided by NrrdTools");
|
|
683
|
+
}
|
|
684
|
+
/** Override in NrrdTools */
|
|
685
|
+
redrawDisplayCanvas() {
|
|
686
|
+
throw new Error("redrawDisplayCanvas must be provided by NrrdTools");
|
|
687
|
+
}
|
|
688
|
+
/** Override in NrrdTools */
|
|
689
|
+
enterSphereMode() {
|
|
690
|
+
throw new Error("enterSphereMode must be provided by NrrdTools");
|
|
691
|
+
}
|
|
692
|
+
/** Override in NrrdTools */
|
|
693
|
+
exitSphereMode() {
|
|
694
|
+
throw new Error("exitSphereMode must be provided by NrrdTools");
|
|
695
|
+
}
|
|
765
696
|
}
|
|
766
697
|
//# sourceMappingURL=DrawToolCore.js.map
|