copper3d 3.0.0 → 3.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +195 -28
- package/dist/Utils/segmentation/CommToolsData.d.ts +32 -18
- package/dist/Utils/segmentation/CommToolsData.js +69 -152
- package/dist/Utils/segmentation/CommToolsData.js.map +1 -1
- package/dist/Utils/segmentation/DragOperator.d.ts +10 -2
- package/dist/Utils/segmentation/DragOperator.js +18 -8
- package/dist/Utils/segmentation/DragOperator.js.map +1 -1
- package/dist/Utils/segmentation/DrawToolCore.d.ts +24 -18
- package/dist/Utils/segmentation/DrawToolCore.js +255 -436
- package/dist/Utils/segmentation/DrawToolCore.js.map +1 -1
- package/dist/Utils/segmentation/NrrdTools.d.ts +152 -10
- package/dist/Utils/segmentation/NrrdTools.js +604 -203
- package/dist/Utils/segmentation/NrrdTools.js.map +1 -1
- package/dist/Utils/segmentation/core/MaskVolume.d.ts +1 -34
- package/dist/Utils/segmentation/core/MaskVolume.js +24 -124
- package/dist/Utils/segmentation/core/MaskVolume.js.map +1 -1
- package/dist/Utils/segmentation/core/UndoManager.d.ts +1 -1
- package/dist/Utils/segmentation/core/UndoManager.js +1 -1
- package/dist/Utils/segmentation/core/index.d.ts +0 -2
- package/dist/Utils/segmentation/core/index.js +0 -1
- package/dist/Utils/segmentation/core/index.js.map +1 -1
- package/dist/Utils/segmentation/core/types.js +24 -24
- package/dist/Utils/segmentation/core/types.js.map +1 -1
- package/dist/Utils/segmentation/coreTools/GuiState.d.ts +22 -0
- package/dist/Utils/segmentation/coreTools/GuiState.js +48 -0
- package/dist/Utils/segmentation/coreTools/GuiState.js.map +1 -0
- package/dist/Utils/segmentation/coreTools/NrrdState.d.ts +25 -0
- package/dist/Utils/segmentation/coreTools/NrrdState.js +85 -0
- package/dist/Utils/segmentation/coreTools/NrrdState.js.map +1 -0
- package/dist/Utils/segmentation/coreTools/coreType.d.ts +88 -65
- package/dist/Utils/segmentation/coreTools/coreType.js.map +1 -1
- package/dist/Utils/segmentation/coreTools/divControlTools.js +1 -1
- package/dist/Utils/segmentation/coreTools/divControlTools.js.map +1 -1
- package/dist/Utils/segmentation/coreTools/gui.d.ts +12 -9
- package/dist/Utils/segmentation/coreTools/gui.js +81 -107
- package/dist/Utils/segmentation/coreTools/gui.js.map +1 -1
- package/dist/Utils/segmentation/eventRouter/EventRouter.d.ts +2 -0
- package/dist/Utils/segmentation/eventRouter/EventRouter.js +19 -8
- package/dist/Utils/segmentation/eventRouter/EventRouter.js.map +1 -1
- package/dist/Utils/segmentation/eventRouter/types.d.ts +3 -3
- package/dist/Utils/segmentation/tools/BaseTool.d.ts +11 -5
- package/dist/Utils/segmentation/tools/BaseTool.js +1 -2
- package/dist/Utils/segmentation/tools/BaseTool.js.map +1 -1
- package/dist/Utils/segmentation/tools/CrosshairTool.js +25 -25
- package/dist/Utils/segmentation/tools/CrosshairTool.js.map +1 -1
- package/dist/Utils/segmentation/tools/DragSliceTool.d.ts +2 -0
- package/dist/Utils/segmentation/tools/DragSliceTool.js +63 -53
- package/dist/Utils/segmentation/tools/DragSliceTool.js.map +1 -1
- package/dist/Utils/segmentation/tools/DrawingTool.d.ts +93 -0
- package/dist/Utils/segmentation/tools/DrawingTool.js +222 -0
- package/dist/Utils/segmentation/tools/DrawingTool.js.map +1 -0
- package/dist/Utils/segmentation/tools/EraserTool.js +8 -8
- package/dist/Utils/segmentation/tools/EraserTool.js.map +1 -1
- package/dist/Utils/segmentation/tools/ImageStoreHelper.d.ts +12 -32
- package/dist/Utils/segmentation/tools/ImageStoreHelper.js +45 -102
- package/dist/Utils/segmentation/tools/ImageStoreHelper.js.map +1 -1
- package/dist/Utils/segmentation/tools/PanTool.d.ts +53 -0
- package/dist/Utils/segmentation/tools/PanTool.js +90 -0
- package/dist/Utils/segmentation/tools/PanTool.js.map +1 -0
- package/dist/Utils/segmentation/tools/SphereTool.d.ts +208 -3
- package/dist/Utils/segmentation/tools/SphereTool.js +456 -45
- package/dist/Utils/segmentation/tools/SphereTool.js.map +1 -1
- package/dist/Utils/segmentation/tools/ZoomTool.js +5 -4
- package/dist/Utils/segmentation/tools/ZoomTool.js.map +1 -1
- package/dist/Utils/segmentation/tools/index.d.ts +6 -2
- package/dist/Utils/segmentation/tools/index.js +4 -1
- package/dist/Utils/segmentation/tools/index.js.map +1 -1
- package/dist/bundle.esm.js +2451 -1622
- package/dist/bundle.umd.js +2451 -1622
- package/dist/index.d.ts +6 -3
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/types/Utils/segmentation/CommToolsData.d.ts +32 -18
- package/dist/types/Utils/segmentation/DragOperator.d.ts +10 -2
- package/dist/types/Utils/segmentation/DrawToolCore.d.ts +24 -18
- package/dist/types/Utils/segmentation/NrrdTools.d.ts +152 -10
- package/dist/types/Utils/segmentation/core/MaskVolume.d.ts +1 -34
- package/dist/types/Utils/segmentation/core/UndoManager.d.ts +1 -1
- package/dist/types/Utils/segmentation/core/index.d.ts +0 -2
- package/dist/types/Utils/segmentation/coreTools/GuiState.d.ts +22 -0
- package/dist/types/Utils/segmentation/coreTools/NrrdState.d.ts +25 -0
- package/dist/types/Utils/segmentation/coreTools/coreType.d.ts +88 -65
- package/dist/types/Utils/segmentation/coreTools/gui.d.ts +12 -9
- package/dist/types/Utils/segmentation/eventRouter/EventRouter.d.ts +2 -0
- package/dist/types/Utils/segmentation/eventRouter/types.d.ts +3 -3
- package/dist/types/Utils/segmentation/tools/BaseTool.d.ts +11 -5
- package/dist/types/Utils/segmentation/tools/DragSliceTool.d.ts +2 -0
- package/dist/types/Utils/segmentation/tools/DrawingTool.d.ts +93 -0
- package/dist/types/Utils/segmentation/tools/ImageStoreHelper.d.ts +12 -32
- package/dist/types/Utils/segmentation/tools/PanTool.d.ts +53 -0
- package/dist/types/Utils/segmentation/tools/SphereTool.d.ts +208 -3
- package/dist/types/Utils/segmentation/tools/index.d.ts +6 -2
- package/dist/types/index.d.ts +6 -3
- package/package.json +1 -1
- package/dist/Utils/segmentation/core/MigrationUtils.d.ts +0 -97
- package/dist/Utils/segmentation/core/MigrationUtils.js +0 -163
- package/dist/Utils/segmentation/core/MigrationUtils.js.map +0 -1
- package/dist/types/Utils/segmentation/core/MigrationUtils.d.ts +0 -97
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DrawingTool - Pencil/Brush/Eraser drawing on canvas layers
|
|
3
|
+
*
|
|
4
|
+
* Extracted from DrawToolCore.paintOnCanvas() closure (Phase 3).
|
|
5
|
+
* Handles left-click drawing operations: pencil stroke + fill, brush strokes,
|
|
6
|
+
* eraser, and undo snapshot capture/push.
|
|
7
|
+
*/
|
|
8
|
+
import { BaseTool } from "./BaseTool";
|
|
9
|
+
import { switchEraserSize } from "../../utils";
|
|
10
|
+
export class DrawingTool extends BaseTool {
|
|
11
|
+
constructor(ctx, callbacks) {
|
|
12
|
+
super(ctx);
|
|
13
|
+
/** Left mouse button currently held (draw mode) */
|
|
14
|
+
this.leftClicked = false;
|
|
15
|
+
/** True while actively painting (between pointerdown and pointerup) */
|
|
16
|
+
this.isPainting = false;
|
|
17
|
+
/** Accumulated pencil stroke points for fill-on-release */
|
|
18
|
+
this.drawingLines = [];
|
|
19
|
+
/** Eraser arc function, assigned once per paintOnCanvas() call */
|
|
20
|
+
this.clearArcFn = null;
|
|
21
|
+
/** Snapshot of the active layer's slice captured on mouse-down (before drawing) */
|
|
22
|
+
this.preDrawSlice = null;
|
|
23
|
+
this.preDrawAxis = "z";
|
|
24
|
+
this.preDrawSliceIndex = 0;
|
|
25
|
+
this.callbacks = callbacks;
|
|
26
|
+
}
|
|
27
|
+
/** Whether a draw operation is currently active */
|
|
28
|
+
get isActive() {
|
|
29
|
+
return this.leftClicked;
|
|
30
|
+
}
|
|
31
|
+
/** Whether paint strokes are being recorded */
|
|
32
|
+
get painting() {
|
|
33
|
+
return this.isPainting;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Reset drawing state. Called at start of each paintOnCanvas() cycle.
|
|
37
|
+
* @param clearArcFn - Eraser function for this paint cycle
|
|
38
|
+
*/
|
|
39
|
+
reset(clearArcFn) {
|
|
40
|
+
this.leftClicked = false;
|
|
41
|
+
this.isPainting = false;
|
|
42
|
+
this.drawingLines = [];
|
|
43
|
+
this.clearArcFn = clearArcFn;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Called on left-click pointerdown in draw mode.
|
|
47
|
+
* Sets up drawing state, cursor, undo snapshot, and start position.
|
|
48
|
+
*/
|
|
49
|
+
onPointerDown(e) {
|
|
50
|
+
this.leftClicked = true;
|
|
51
|
+
this.drawingLines = [];
|
|
52
|
+
this.isPainting = true;
|
|
53
|
+
this.ctx.protectedData.isDrawing = true;
|
|
54
|
+
// Set cursor based on mode
|
|
55
|
+
if (this.ctx.gui_states.mode.eraser) {
|
|
56
|
+
const urls = this.callbacks.getEraserUrls();
|
|
57
|
+
this.ctx.protectedData.canvases.drawingCanvas.style.cursor =
|
|
58
|
+
urls.length > 0
|
|
59
|
+
? switchEraserSize(this.ctx.gui_states.drawing.brushAndEraserSize, urls)
|
|
60
|
+
: switchEraserSize(this.ctx.gui_states.drawing.brushAndEraserSize);
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
this.ctx.protectedData.canvases.drawingCanvas.style.cursor =
|
|
64
|
+
this.ctx.gui_states.viewConfig.defaultPaintCursor;
|
|
65
|
+
}
|
|
66
|
+
// Record draw start position
|
|
67
|
+
this.ctx.nrrd_states.interaction.drawStartPos.x = e.offsetX;
|
|
68
|
+
this.ctx.nrrd_states.interaction.drawStartPos.y = e.offsetY;
|
|
69
|
+
// Capture pre-draw slice snapshot for undo
|
|
70
|
+
this.capturePreDrawSnapshot();
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Called on pointermove during an active drawing operation.
|
|
74
|
+
* Handles eraser clearing or brush/pencil stroke accumulation.
|
|
75
|
+
*/
|
|
76
|
+
onPointerMove(e) {
|
|
77
|
+
var _a;
|
|
78
|
+
this.ctx.protectedData.isDrawing = true;
|
|
79
|
+
if (this.isPainting) {
|
|
80
|
+
if (this.ctx.gui_states.mode.eraser) {
|
|
81
|
+
this.ctx.nrrd_states.flags.stepClear = 1;
|
|
82
|
+
(_a = this.clearArcFn) === null || _a === void 0 ? void 0 : _a.call(this, e.offsetX, e.offsetY, this.ctx.gui_states.drawing.brushAndEraserSize);
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
this.drawingLines.push({ x: e.offsetX, y: e.offsetY });
|
|
86
|
+
this.paintOnCanvasLayer(e.offsetX, e.offsetY);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Called on pointerup in draw mode.
|
|
92
|
+
* Completes stroke, fills pencil path, syncs volume, pushes undo delta.
|
|
93
|
+
*/
|
|
94
|
+
onPointerUp(_e) {
|
|
95
|
+
this.leftClicked = false;
|
|
96
|
+
const { ctx, canvas } = this.callbacks.setCurrentLayer();
|
|
97
|
+
ctx.closePath();
|
|
98
|
+
if (!this.ctx.gui_states.mode.eraser) {
|
|
99
|
+
if (this.ctx.gui_states.mode.pencil) {
|
|
100
|
+
// Clear only the current layer canvas (NOT master)
|
|
101
|
+
canvas.width = canvas.width;
|
|
102
|
+
// Redraw previous layer data from volume
|
|
103
|
+
this.redrawPreviousImageToLayerCtx(ctx);
|
|
104
|
+
// Draw new pencil strokes on current layer canvas
|
|
105
|
+
ctx.beginPath();
|
|
106
|
+
ctx.moveTo(this.drawingLines[0].x, this.drawingLines[0].y);
|
|
107
|
+
for (let i = 1; i < this.drawingLines.length; i++) {
|
|
108
|
+
ctx.lineTo(this.drawingLines[i].x, this.drawingLines[i].y);
|
|
109
|
+
}
|
|
110
|
+
ctx.closePath();
|
|
111
|
+
ctx.lineWidth = 1;
|
|
112
|
+
ctx.fillStyle = this.ctx.gui_states.drawing.fillColor;
|
|
113
|
+
ctx.fill();
|
|
114
|
+
// Composite ALL layers to master (not just current layer)
|
|
115
|
+
this.callbacks.compositeAllLayers();
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
this.callbacks.syncLayerSliceData(this.ctx.nrrd_states.view.currentSliceIndex, this.ctx.gui_states.layerChannel.layer);
|
|
119
|
+
this.isPainting = false;
|
|
120
|
+
// Push undo delta
|
|
121
|
+
this.pushUndoDelta();
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Called on pointerleave during drawing.
|
|
125
|
+
* Resets painting state and cleans up leftClicked.
|
|
126
|
+
* @returns true if drawing was in progress when leave occurred
|
|
127
|
+
*/
|
|
128
|
+
onPointerLeave() {
|
|
129
|
+
this.isPainting = false;
|
|
130
|
+
if (!this.leftClicked)
|
|
131
|
+
return false;
|
|
132
|
+
this.leftClicked = false;
|
|
133
|
+
this.ctx.protectedData.ctxes.drawingLayerMasterCtx.closePath();
|
|
134
|
+
return true;
|
|
135
|
+
}
|
|
136
|
+
// ── Private helpers ────────────────────────────────────────
|
|
137
|
+
/** Capture pre-draw slice snapshot for undo */
|
|
138
|
+
capturePreDrawSnapshot() {
|
|
139
|
+
try {
|
|
140
|
+
this.preDrawAxis = this.ctx.protectedData.axis;
|
|
141
|
+
this.preDrawSliceIndex = this.ctx.nrrd_states.view.currentSliceIndex;
|
|
142
|
+
const vol = this.callbacks.getVolumeForLayer(this.ctx.gui_states.layerChannel.layer);
|
|
143
|
+
this.preDrawSlice = vol.getSliceUint8(this.preDrawSliceIndex, this.preDrawAxis).data.slice();
|
|
144
|
+
}
|
|
145
|
+
catch (_a) {
|
|
146
|
+
this.preDrawSlice = null;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
/** Push delta to UndoManager after drawing completes */
|
|
150
|
+
pushUndoDelta() {
|
|
151
|
+
if (!this.preDrawSlice)
|
|
152
|
+
return;
|
|
153
|
+
try {
|
|
154
|
+
const vol = this.callbacks.getVolumeForLayer(this.ctx.gui_states.layerChannel.layer);
|
|
155
|
+
const { data: newSlice } = vol.getSliceUint8(this.preDrawSliceIndex, this.preDrawAxis);
|
|
156
|
+
const delta = {
|
|
157
|
+
layerId: this.ctx.gui_states.layerChannel.layer,
|
|
158
|
+
axis: this.preDrawAxis,
|
|
159
|
+
sliceIndex: this.preDrawSliceIndex,
|
|
160
|
+
oldSlice: this.preDrawSlice,
|
|
161
|
+
newSlice: newSlice.slice(),
|
|
162
|
+
};
|
|
163
|
+
this.callbacks.pushUndoDelta(delta);
|
|
164
|
+
}
|
|
165
|
+
catch (_a) {
|
|
166
|
+
// Volume not ready — skip
|
|
167
|
+
}
|
|
168
|
+
this.preDrawSlice = null;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Redraws persisted layer data onto ctx before new pencil fill.
|
|
172
|
+
* Extracted from DrawToolCore.
|
|
173
|
+
*/
|
|
174
|
+
redrawPreviousImageToLayerCtx(ctx) {
|
|
175
|
+
var _a;
|
|
176
|
+
const tempPreImg = (_a = this.callbacks.filterDrawedImage(this.ctx.protectedData.axis, this.ctx.nrrd_states.view.currentSliceIndex)) === null || _a === void 0 ? void 0 : _a.image;
|
|
177
|
+
this.ctx.protectedData.canvases.emptyCanvas.width =
|
|
178
|
+
this.ctx.protectedData.canvases.emptyCanvas.width;
|
|
179
|
+
this.ctx.protectedData.ctxes.emptyCtx.putImageData(tempPreImg, 0, 0);
|
|
180
|
+
ctx.imageSmoothingEnabled = false;
|
|
181
|
+
// Coronal (axis='y') Z-flip: same as renderSliceToCanvas.
|
|
182
|
+
if (this.ctx.protectedData.axis === 'y') {
|
|
183
|
+
ctx.save();
|
|
184
|
+
ctx.scale(1, -1);
|
|
185
|
+
ctx.translate(0, -this.ctx.nrrd_states.view.changedHeight);
|
|
186
|
+
}
|
|
187
|
+
ctx.drawImage(this.ctx.protectedData.canvases.emptyCanvas, 0, 0, this.ctx.nrrd_states.view.changedWidth, this.ctx.nrrd_states.view.changedHeight);
|
|
188
|
+
if (this.ctx.protectedData.axis === 'y') {
|
|
189
|
+
ctx.restore();
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
/** Draw a line segment on a layer canvas */
|
|
193
|
+
drawLinesOnLayer(ctx, x, y) {
|
|
194
|
+
ctx.beginPath();
|
|
195
|
+
ctx.moveTo(this.ctx.nrrd_states.interaction.drawStartPos.x, this.ctx.nrrd_states.interaction.drawStartPos.y);
|
|
196
|
+
if (this.ctx.gui_states.mode.pencil) {
|
|
197
|
+
ctx.strokeStyle = this.ctx.gui_states.drawing.color;
|
|
198
|
+
ctx.lineWidth = this.ctx.gui_states.drawing.lineWidth;
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
ctx.strokeStyle = this.ctx.gui_states.drawing.brushColor;
|
|
202
|
+
ctx.lineWidth = this.ctx.gui_states.drawing.brushAndEraserSize;
|
|
203
|
+
}
|
|
204
|
+
ctx.lineTo(x, y);
|
|
205
|
+
ctx.stroke();
|
|
206
|
+
ctx.closePath();
|
|
207
|
+
}
|
|
208
|
+
/** Paint a segment on the current layer canvas and composite to master */
|
|
209
|
+
paintOnCanvasLayer(x, y) {
|
|
210
|
+
const { ctx } = this.callbacks.setCurrentLayer();
|
|
211
|
+
// Draw only on the current layer canvas (not master directly)
|
|
212
|
+
this.drawLinesOnLayer(ctx, x, y);
|
|
213
|
+
// Composite all layers to master to preserve other layers' data
|
|
214
|
+
this.callbacks.compositeAllLayers();
|
|
215
|
+
// Reset drawing start position to current position
|
|
216
|
+
this.ctx.nrrd_states.interaction.drawStartPos.x = x;
|
|
217
|
+
this.ctx.nrrd_states.interaction.drawStartPos.y = y;
|
|
218
|
+
// Flag the map as needing updating
|
|
219
|
+
this.ctx.protectedData.mainPreSlices.mesh.material.map.needsUpdate = true;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
//# sourceMappingURL=DrawingTool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DrawingTool.js","sourceRoot":"","sources":["../../../../src/Utils/segmentation/tools/DrawingTool.ts"],"names":[],"mappings":"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"}
|
|
@@ -16,9 +16,9 @@ export class EraserTool extends BaseTool {
|
|
|
16
16
|
createClearArc() {
|
|
17
17
|
const clearArc = (x, y, radius) => {
|
|
18
18
|
var _a;
|
|
19
|
-
const activeChannel = this.ctx.gui_states.activeChannel || 1;
|
|
19
|
+
const activeChannel = this.ctx.gui_states.layerChannel.activeChannel || 1;
|
|
20
20
|
// Get color from current layer's volume (respects custom per-layer colors)
|
|
21
|
-
const layer = this.ctx.gui_states.layer;
|
|
21
|
+
const layer = this.ctx.gui_states.layerChannel.layer;
|
|
22
22
|
const volume = this.ctx.protectedData.maskData.volumes[layer];
|
|
23
23
|
const channelColor = volume
|
|
24
24
|
? volume.getChannelColor(activeChannel)
|
|
@@ -31,8 +31,8 @@ export class EraserTool extends BaseTool {
|
|
|
31
31
|
// Calculate bounding box of the eraser circle
|
|
32
32
|
const x0 = Math.max(0, Math.floor(x - radius));
|
|
33
33
|
const y0 = Math.max(0, Math.floor(y - radius));
|
|
34
|
-
const x1 = Math.min(this.ctx.nrrd_states.changedWidth, Math.ceil(x + radius));
|
|
35
|
-
const y1 = Math.min(this.ctx.nrrd_states.changedHeight, Math.ceil(y + radius));
|
|
34
|
+
const x1 = Math.min(this.ctx.nrrd_states.view.changedWidth, Math.ceil(x + radius));
|
|
35
|
+
const y1 = Math.min(this.ctx.nrrd_states.view.changedHeight, Math.ceil(y + radius));
|
|
36
36
|
const w = x1 - x0;
|
|
37
37
|
const h = y1 - y0;
|
|
38
38
|
if (w <= 0 || h <= 0)
|
|
@@ -75,11 +75,11 @@ export class EraserTool extends BaseTool {
|
|
|
75
75
|
// Recomposite master from all layer canvases (full alpha;
|
|
76
76
|
// globalAlpha applied in start() render loop).
|
|
77
77
|
const masterCtx = this.ctx.protectedData.ctxes.drawingLayerMasterCtx;
|
|
78
|
-
const fullW = this.ctx.nrrd_states.changedWidth;
|
|
79
|
-
const fullH = this.ctx.nrrd_states.changedHeight;
|
|
78
|
+
const fullW = this.ctx.nrrd_states.view.changedWidth;
|
|
79
|
+
const fullH = this.ctx.nrrd_states.view.changedHeight;
|
|
80
80
|
masterCtx.clearRect(0, 0, fullW, fullH);
|
|
81
|
-
for (const layerId of this.ctx.nrrd_states.layers) {
|
|
82
|
-
if (!this.ctx.gui_states.layerVisibility[layerId])
|
|
81
|
+
for (const layerId of this.ctx.nrrd_states.image.layers) {
|
|
82
|
+
if (!this.ctx.gui_states.layerChannel.layerVisibility[layerId])
|
|
83
83
|
continue;
|
|
84
84
|
const lt = this.ctx.protectedData.layerTargets.get(layerId);
|
|
85
85
|
if (lt)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EraserTool.js","sourceRoot":"","sources":["../../../../src/Utils/segmentation/tools/EraserTool.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAE9C,MAAM,OAAO,UAAW,SAAQ,QAAQ;IAEtC;;;;;OAKG;IACH,cAAc;QACZ,MAAM,QAAQ,GAAG,CAAC,CAAS,EAAE,CAAS,EAAE,MAAc,EAAE,EAAE;;YACxD,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,aAAa,IAAI,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"EraserTool.js","sourceRoot":"","sources":["../../../../src/Utils/segmentation/tools/EraserTool.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAE9C,MAAM,OAAO,UAAW,SAAQ,QAAQ;IAEtC;;;;;OAKG;IACH,cAAc;QACZ,MAAM,QAAQ,GAAG,CAAC,CAAS,EAAE,CAAS,EAAE,MAAc,EAAE,EAAE;;YACxD,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,YAAY,CAAC,aAAa,IAAI,CAAC,CAAC;YAC1E,2EAA2E;YAC3E,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,YAAY,CAAC,KAAK,CAAC;YACrD,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YAC9D,MAAM,YAAY,GAAG,MAAM;gBACzB,CAAC,CAAC,MAAM,CAAC,eAAe,CAAC,aAAa,CAAC;gBACvC,CAAC,CAAC,CAAC,MAAA,mBAAmB,CAAC,aAAa,CAAC,mCAAI,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC;YAEnE,uDAAuD;YACvD,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YAC9D,IAAI,CAAC,MAAM;gBAAE,OAAO,CAAC,2BAA2B;YAChD,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC;YAE5B,8CAA8C;YAC9C,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC;YAC/C,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC;YAC/C,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CACjB,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,YAAY,EACtC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,MAAM,CAAC,CACtB,CAAC;YACF,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CACjB,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,aAAa,EACvC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,MAAM,CAAC,CACtB,CAAC;YACF,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC;YAClB,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC;YAClB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;gBAAE,OAAO;YAE7B,gDAAgD;YAChD,MAAM,SAAS,GAAG,QAAQ,CAAC,YAAY,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;YACtD,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC;YAC9B,MAAM,EAAE,GAAG,MAAM,GAAG,MAAM,CAAC;YAE3B,oEAAoE;YACpE,gFAAgF;YAChF,MAAM,GAAG,GAAG,EAAE,CAAC;YACf,MAAM,EAAE,GAAG,YAAY,CAAC,CAAC,EAAE,EAAE,GAAG,YAAY,CAAC,CAAC,EAAE,EAAE,GAAG,YAAY,CAAC,CAAC,CAAC;YACpE,KAAK,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE;gBAC7B,KAAK,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE;oBAC7B,MAAM,EAAE,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC;oBACzB,MAAM,EAAE,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC;oBACzB,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE;wBAAE,SAAS,CAAC,iBAAiB;oBAEvD,MAAM,GAAG,GAAG,CAAC,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC;oBAC9B,MAAM,EAAE,GAAG,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;oBAE3B,0BAA0B;oBAC1B,IAAI,EAAE,KAAK,CAAC;wBAAE,SAAS;oBAEvB,+DAA+D;oBAC/D,MAAM,EAAE,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;oBACvB,MAAM,EAAE,GAAG,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;oBAC3B,MAAM,EAAE,GAAG,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;oBAC3B,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,IAAI,GAAG;wBACxB,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,IAAI,GAAG;wBACxB,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,IAAI,GAAG,EAAE;wBAC5B,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;wBAChB,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;wBACpB,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;wBACpB,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;qBACrB;iBACF;aACF;YAED,6CAA6C;YAC7C,QAAQ,CAAC,YAAY,CAAC,SAAS,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;YAEzC,0DAA0D;YAC1D,+CAA+C;YAC/C,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,KAAK,CAAC,qBAAqB,CAAC;YACrE,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,YAAY,CAAC;YACrD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,aAAa,CAAC;YACtD,SAAS,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;YAExC,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,KAAK,CAAC,MAAM,EAAE;gBACvD,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,YAAY,CAAC,eAAe,CAAC,OAAO,CAAC;oBAAE,SAAS;gBACzE,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;gBAC5D,IAAI,EAAE;oBAAE,SAAS,CAAC,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;aAC5D;QACH,CAAC,CAAC;QACF,OAAO,QAAQ,CAAC;IAClB,CAAC;CACF"}
|
|
@@ -2,14 +2,12 @@
|
|
|
2
2
|
* ImageStoreHelper - Cross-axis image storage
|
|
3
3
|
*
|
|
4
4
|
* Extracted from DrawToolCore.ts:
|
|
5
|
-
* -
|
|
5
|
+
* - syncLayerSliceData
|
|
6
6
|
*
|
|
7
|
-
* Phase
|
|
8
|
-
* Volume is the primary storage; IPaintImages kept for backward compatibility.
|
|
7
|
+
* Phase 3: MaskVolume is the sole storage backend. All IPaintImages params removed.
|
|
9
8
|
*/
|
|
10
9
|
import { BaseTool } from "./BaseTool";
|
|
11
10
|
import type { ToolContext } from "./BaseTool";
|
|
12
|
-
import type { IPaintImage, IPaintImages } from "../coreTools/coreType";
|
|
13
11
|
export interface ImageStoreCallbacks {
|
|
14
12
|
setEmptyCanvasSize: (axis?: "x" | "y" | "z") => void;
|
|
15
13
|
drawImageOnEmptyImage: (canvas: HTMLCanvasElement) => void;
|
|
@@ -25,41 +23,23 @@ export declare class ImageStoreHelper extends BaseTool {
|
|
|
25
23
|
* @returns MaskVolume for the given layer, or layer1 as fallback
|
|
26
24
|
*/
|
|
27
25
|
private getVolumeForLayer;
|
|
28
|
-
/**
|
|
29
|
-
* Get MaskVolume for the currently active layer.
|
|
30
|
-
*/
|
|
31
|
-
private getCurrentVolume;
|
|
32
26
|
/**
|
|
33
27
|
* Get the canvas element for a specific layer.
|
|
34
28
|
*/
|
|
35
29
|
private getCanvasForLayer;
|
|
36
30
|
/**
|
|
37
|
-
*
|
|
38
|
-
* MaskVolume storage happens in storeAllImages via setSliceFromImageData.
|
|
39
|
-
* This method kept for backward compatibility with existing call sites.
|
|
40
|
-
*/
|
|
41
|
-
storeImageToAxis(_index: number, _paintedImages: IPaintImages, _imageData: ImageData, _axis?: "x" | "y" | "z"): void;
|
|
42
|
-
/**
|
|
43
|
-
* Retrieve the drawn image for a given axis and slice.
|
|
31
|
+
* Vertically flip an ImageData buffer in-place (swap rows top↔bottom).
|
|
44
32
|
*
|
|
45
|
-
*
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
* Phase 2: Also writes into the current layer's MaskVolume.
|
|
52
|
-
*/
|
|
53
|
-
storeAllImages(index: number, layer: string): void;
|
|
54
|
-
/**
|
|
55
|
-
* Store a single layer's canvas data to its MaskVolume.
|
|
56
|
-
* Reads from the individual layer canvas (not master) and uses RGB→channel reverse lookup.
|
|
33
|
+
* Used to compensate for the Z-axis direction reversal between sagittal
|
|
34
|
+
* and coronal views. On coronal, Z runs along the canvas j-axis (vertical),
|
|
35
|
+
* and the display flip (scale(1,-1)) reverses Z relative to sagittal's
|
|
36
|
+
* horizontal Z mapping. This row-swap aligns the Z ordering so that
|
|
37
|
+
* MaskVolume stores data in a consistent coordinate system.
|
|
57
38
|
*/
|
|
58
|
-
|
|
39
|
+
private flipImageDataVertically;
|
|
59
40
|
/**
|
|
60
|
-
*
|
|
61
|
-
*
|
|
41
|
+
* Sync the current layer canvas to its MaskVolume slice and notify the parent
|
|
42
|
+
* via getMask. This is the primary write path after any draw/erase operation.
|
|
62
43
|
*/
|
|
63
|
-
|
|
64
|
-
private hasNonZeroPixels;
|
|
44
|
+
syncLayerSliceData(index: number, layer: string): void;
|
|
65
45
|
}
|
|
@@ -2,10 +2,9 @@
|
|
|
2
2
|
* ImageStoreHelper - Cross-axis image storage
|
|
3
3
|
*
|
|
4
4
|
* Extracted from DrawToolCore.ts:
|
|
5
|
-
* -
|
|
5
|
+
* - syncLayerSliceData
|
|
6
6
|
*
|
|
7
|
-
* Phase
|
|
8
|
-
* Volume is the primary storage; IPaintImages kept for backward compatibility.
|
|
7
|
+
* Phase 3: MaskVolume is the sole storage backend. All IPaintImages params removed.
|
|
9
8
|
*/
|
|
10
9
|
import { BaseTool } from "./BaseTool";
|
|
11
10
|
export class ImageStoreHelper extends BaseTool {
|
|
@@ -23,18 +22,12 @@ export class ImageStoreHelper extends BaseTool {
|
|
|
23
22
|
*/
|
|
24
23
|
getVolumeForLayer(layer) {
|
|
25
24
|
const { volumes } = this.ctx.protectedData.maskData;
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Get MaskVolume for the currently active layer.
|
|
35
|
-
*/
|
|
36
|
-
getCurrentVolume() {
|
|
37
|
-
return this.getVolumeForLayer(this.ctx.gui_states.layer);
|
|
25
|
+
const vol = volumes[layer];
|
|
26
|
+
if (vol)
|
|
27
|
+
return vol;
|
|
28
|
+
const firstLayerId = this.ctx.nrrd_states.image.layers[0];
|
|
29
|
+
console.warn(`ImageStoreHelper: unknown layer "${layer}", falling back to "${firstLayerId}"`);
|
|
30
|
+
return volumes[firstLayerId];
|
|
38
31
|
}
|
|
39
32
|
/**
|
|
40
33
|
* Get the canvas element for a specific layer.
|
|
@@ -45,78 +38,74 @@ export class ImageStoreHelper extends BaseTool {
|
|
|
45
38
|
return target.canvas;
|
|
46
39
|
return this.ctx.protectedData.canvases.drawingCanvasLayerMaster;
|
|
47
40
|
}
|
|
48
|
-
// =====
|
|
49
|
-
/**
|
|
50
|
-
* Phase 3: Simplified to be a no-op.
|
|
51
|
-
* MaskVolume storage happens in storeAllImages via setSliceFromImageData.
|
|
52
|
-
* This method kept for backward compatibility with existing call sites.
|
|
53
|
-
*/
|
|
54
|
-
storeImageToAxis(_index, _paintedImages, _imageData, _axis) {
|
|
55
|
-
// No-op: MaskVolume is the primary storage, updated in storeAllImages
|
|
56
|
-
}
|
|
41
|
+
// ===== ImageData Flip Helpers =====
|
|
57
42
|
/**
|
|
58
|
-
*
|
|
43
|
+
* Vertically flip an ImageData buffer in-place (swap rows top↔bottom).
|
|
59
44
|
*
|
|
60
|
-
*
|
|
45
|
+
* Used to compensate for the Z-axis direction reversal between sagittal
|
|
46
|
+
* and coronal views. On coronal, Z runs along the canvas j-axis (vertical),
|
|
47
|
+
* and the display flip (scale(1,-1)) reverses Z relative to sagittal's
|
|
48
|
+
* horizontal Z mapping. This row-swap aligns the Z ordering so that
|
|
49
|
+
* MaskVolume stores data in a consistent coordinate system.
|
|
61
50
|
*/
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
volume.renderLabelSliceInto(sliceIndex, axis, imageData, channelVis);
|
|
74
|
-
return { index: sliceIndex, image: imageData };
|
|
75
|
-
}
|
|
51
|
+
flipImageDataVertically(imageData) {
|
|
52
|
+
const { width, height, data } = imageData;
|
|
53
|
+
const rowSize = width * 4; // RGBA = 4 bytes per pixel
|
|
54
|
+
const temp = new Uint8ClampedArray(rowSize);
|
|
55
|
+
for (let y = 0; y < Math.floor(height / 2); y++) {
|
|
56
|
+
const topOffset = y * rowSize;
|
|
57
|
+
const bottomOffset = (height - 1 - y) * rowSize;
|
|
58
|
+
// Swap top row and bottom row
|
|
59
|
+
temp.set(data.subarray(topOffset, topOffset + rowSize));
|
|
60
|
+
data.copyWithin(topOffset, bottomOffset, bottomOffset + rowSize);
|
|
61
|
+
data.set(temp, bottomOffset);
|
|
76
62
|
}
|
|
77
|
-
catch (err) {
|
|
78
|
-
console.warn(`filterDrawedImage: Failed to read slice ${sliceIndex} on ${axis}:`, err);
|
|
79
|
-
}
|
|
80
|
-
return undefined;
|
|
81
63
|
}
|
|
82
|
-
// =====
|
|
64
|
+
// ===== Sync Layer Slice Data =====
|
|
83
65
|
/**
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
* Phase 2: Also writes into the current layer's MaskVolume.
|
|
66
|
+
* Sync the current layer canvas to its MaskVolume slice and notify the parent
|
|
67
|
+
* via getMask. This is the primary write path after any draw/erase operation.
|
|
87
68
|
*/
|
|
88
|
-
|
|
69
|
+
syncLayerSliceData(index, layer) {
|
|
89
70
|
const nrrd = this.ctx.nrrd_states;
|
|
90
71
|
// Read from the individual layer canvas (NOT master) to preserve layer isolation
|
|
91
72
|
const layerCanvas = this.getCanvasForLayer(layer);
|
|
92
|
-
if (!nrrd.
|
|
73
|
+
if (!nrrd.flags.loadingMaskData && !this.ctx.gui_states.mode.sphere) {
|
|
93
74
|
this.callbacks.setEmptyCanvasSize();
|
|
94
75
|
this.callbacks.drawImageOnEmptyImage(layerCanvas);
|
|
95
76
|
}
|
|
96
77
|
const imageData = this.ctx.protectedData.ctxes.emptyCtx.getImageData(0, 0, this.ctx.protectedData.canvases.emptyCanvas.width, this.ctx.protectedData.canvases.emptyCanvas.height);
|
|
78
|
+
// Coronal (axis='y') Z-flip: the Z dimension runs vertically on coronal
|
|
79
|
+
// but horizontally on sagittal, with opposite screen directions.
|
|
80
|
+
// Flip ImageData vertically before writing to MaskVolume so that
|
|
81
|
+
// cross-view rendering (sagittal↔coronal) is consistent.
|
|
82
|
+
// Same pattern as SphereTool.canvasToVoxelCenter('y') Z-flip.
|
|
83
|
+
if (this.ctx.protectedData.axis === 'y') {
|
|
84
|
+
this.flipImageDataVertically(imageData);
|
|
85
|
+
}
|
|
97
86
|
// Write label data into 1-channel MaskVolume with RGB→channel reverse lookup
|
|
98
87
|
try {
|
|
99
88
|
const volume = this.getVolumeForLayer(layer);
|
|
100
89
|
if (volume) {
|
|
101
|
-
const activeChannel = this.ctx.gui_states.activeChannel || 1;
|
|
90
|
+
const activeChannel = this.ctx.gui_states.layerChannel.activeChannel || 1;
|
|
102
91
|
// Phase 4 Fix: Pass channel visibility map to preserve hidden channels
|
|
103
|
-
const channelVis = this.ctx.gui_states.channelVisibility[layer];
|
|
92
|
+
const channelVis = this.ctx.gui_states.layerChannel.channelVisibility[layer];
|
|
104
93
|
volume.setSliceLabelsFromImageData(index, imageData, this.ctx.protectedData.axis, activeChannel, channelVis);
|
|
105
94
|
}
|
|
106
95
|
}
|
|
107
96
|
catch (err) {
|
|
108
97
|
// Volume not ready — skip
|
|
109
98
|
}
|
|
110
|
-
if (!nrrd.
|
|
99
|
+
if (!nrrd.flags.loadingMaskData && !this.ctx.gui_states.mode.sphere) {
|
|
111
100
|
// Extract raw slice data from MaskVolume and notify parent
|
|
112
101
|
try {
|
|
113
102
|
const volume = this.getVolumeForLayer(layer);
|
|
114
103
|
if (volume) {
|
|
115
104
|
const axis = this.ctx.protectedData.axis;
|
|
116
|
-
const sliceIndex = this.ctx.nrrd_states.
|
|
105
|
+
const sliceIndex = this.ctx.nrrd_states.view.currentSliceIndex;
|
|
117
106
|
const { data: sliceData, width, height } = volume.getSliceUint8(sliceIndex, axis);
|
|
118
|
-
const activeChannel = this.ctx.gui_states.activeChannel || 1;
|
|
119
|
-
this.ctx.
|
|
107
|
+
const activeChannel = this.ctx.gui_states.layerChannel.activeChannel || 1;
|
|
108
|
+
this.ctx.callbacks.onMaskChanged(sliceData, layer, activeChannel, sliceIndex, axis, width, height, this.ctx.nrrd_states.flags.clearAllFlag);
|
|
120
109
|
}
|
|
121
110
|
}
|
|
122
111
|
catch (_a) {
|
|
@@ -124,51 +113,5 @@ export class ImageStoreHelper extends BaseTool {
|
|
|
124
113
|
}
|
|
125
114
|
}
|
|
126
115
|
}
|
|
127
|
-
// ===== Store Per-Layer Images =====
|
|
128
|
-
/**
|
|
129
|
-
* Store a single layer's canvas data to its MaskVolume.
|
|
130
|
-
* Reads from the individual layer canvas (not master) and uses RGB→channel reverse lookup.
|
|
131
|
-
*/
|
|
132
|
-
storeEachLayerImage(index, layer) {
|
|
133
|
-
const layerCanvas = this.getCanvasForLayer(layer);
|
|
134
|
-
this.callbacks.setEmptyCanvasSize();
|
|
135
|
-
this.callbacks.drawImageOnEmptyImage(layerCanvas);
|
|
136
|
-
const imageData = this.ctx.protectedData.ctxes.emptyCtx.getImageData(0, 0, this.ctx.protectedData.canvases.emptyCanvas.width, this.ctx.protectedData.canvases.emptyCanvas.height);
|
|
137
|
-
try {
|
|
138
|
-
const volume = this.getVolumeForLayer(layer);
|
|
139
|
-
if (volume) {
|
|
140
|
-
const activeChannel = this.ctx.gui_states.activeChannel || 1;
|
|
141
|
-
// Phase 4 Fix: Pass channel visibility map to preserve hidden channels
|
|
142
|
-
const channelVis = this.ctx.gui_states.channelVisibility[layer];
|
|
143
|
-
volume.setSliceLabelsFromImageData(index, imageData, this.ctx.protectedData.axis, activeChannel, channelVis);
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
catch (_a) {
|
|
147
|
-
// Volume not ready — skip
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
/**
|
|
151
|
-
* Phase 3: Simplified - extracts ImageData from canvas but no longer stores to paintImages.
|
|
152
|
-
* Kept for backward compatibility with existing call sites.
|
|
153
|
-
*/
|
|
154
|
-
storeImageToLayer(_index, canvas, _paintedImages) {
|
|
155
|
-
if (!this.ctx.nrrd_states.loadMaskJson) {
|
|
156
|
-
this.callbacks.setEmptyCanvasSize();
|
|
157
|
-
this.callbacks.drawImageOnEmptyImage(canvas);
|
|
158
|
-
}
|
|
159
|
-
const imageData = this.ctx.protectedData.ctxes.emptyCtx.getImageData(0, 0, this.ctx.protectedData.canvases.emptyCanvas.width, this.ctx.protectedData.canvases.emptyCanvas.height);
|
|
160
|
-
// No longer stores to paintedImages - MaskVolume is primary storage
|
|
161
|
-
return imageData;
|
|
162
|
-
}
|
|
163
|
-
// ===== Helper Methods =====
|
|
164
|
-
hasNonZeroPixels(imageData) {
|
|
165
|
-
const data = imageData.data;
|
|
166
|
-
for (let i = 0; i < data.length; i += 4) {
|
|
167
|
-
if (data[i] !== 0 || data[i + 1] !== 0 || data[i + 2] !== 0 || data[i + 3] !== 0) {
|
|
168
|
-
return true;
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
return false;
|
|
172
|
-
}
|
|
173
116
|
}
|
|
174
117
|
//# sourceMappingURL=ImageStoreHelper.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ImageStoreHelper.js","sourceRoot":"","sources":["../../../../src/Utils/segmentation/tools/ImageStoreHelper.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"ImageStoreHelper.js","sourceRoot":"","sources":["../../../../src/Utils/segmentation/tools/ImageStoreHelper.ts"],"names":[],"mappings":"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"}
|