copper3d 3.0.0 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Utils/segmentation/CommToolsData.d.ts +9 -10
- package/dist/Utils/segmentation/CommToolsData.js +4 -13
- package/dist/Utils/segmentation/CommToolsData.js.map +1 -1
- package/dist/Utils/segmentation/DragOperator.js +4 -4
- package/dist/Utils/segmentation/DragOperator.js.map +1 -1
- package/dist/Utils/segmentation/DrawToolCore.d.ts +5 -6
- package/dist/Utils/segmentation/DrawToolCore.js +57 -55
- package/dist/Utils/segmentation/DrawToolCore.js.map +1 -1
- package/dist/Utils/segmentation/NrrdTools.js +6 -2
- package/dist/Utils/segmentation/NrrdTools.js.map +1 -1
- package/dist/Utils/segmentation/core/MaskVolume.d.ts +0 -33
- package/dist/Utils/segmentation/core/MaskVolume.js +0 -121
- package/dist/Utils/segmentation/core/MaskVolume.js.map +1 -1
- package/dist/Utils/segmentation/coreTools/coreType.d.ts +0 -3
- package/dist/Utils/segmentation/coreTools/coreType.js.map +1 -1
- package/dist/Utils/segmentation/coreTools/gui.d.ts +6 -3
- package/dist/Utils/segmentation/coreTools/gui.js.map +1 -1
- package/dist/Utils/segmentation/eventRouter/EventRouter.d.ts +1 -0
- package/dist/Utils/segmentation/eventRouter/EventRouter.js +9 -3
- package/dist/Utils/segmentation/eventRouter/EventRouter.js.map +1 -1
- package/dist/Utils/segmentation/tools/BaseTool.d.ts +3 -0
- package/dist/Utils/segmentation/tools/BaseTool.js.map +1 -1
- package/dist/Utils/segmentation/tools/ImageStoreHelper.d.ts +10 -13
- package/dist/Utils/segmentation/tools/ImageStoreHelper.js +13 -27
- package/dist/Utils/segmentation/tools/ImageStoreHelper.js.map +1 -1
- package/dist/Utils/segmentation/tools/SphereTool.d.ts +1 -3
- package/dist/Utils/segmentation/tools/SphereTool.js +1 -1
- package/dist/Utils/segmentation/tools/SphereTool.js.map +1 -1
- package/dist/Utils/segmentation/tools/ZoomTool.js +2 -1
- package/dist/Utils/segmentation/tools/ZoomTool.js.map +1 -1
- package/dist/bundle.esm.js +97 -228
- package/dist/bundle.umd.js +97 -228
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/types/Utils/segmentation/CommToolsData.d.ts +9 -10
- package/dist/types/Utils/segmentation/DrawToolCore.d.ts +5 -6
- package/dist/types/Utils/segmentation/core/MaskVolume.d.ts +0 -33
- package/dist/types/Utils/segmentation/coreTools/coreType.d.ts +0 -3
- package/dist/types/Utils/segmentation/coreTools/gui.d.ts +6 -3
- package/dist/types/Utils/segmentation/eventRouter/EventRouter.d.ts +1 -0
- package/dist/types/Utils/segmentation/tools/BaseTool.d.ts +3 -0
- package/dist/types/Utils/segmentation/tools/ImageStoreHelper.d.ts +10 -13
- package/dist/types/Utils/segmentation/tools/SphereTool.d.ts +1 -3
- package/dist/types/index.d.ts +1 -1
- package/package.json +1 -1
package/dist/bundle.esm.js
CHANGED
|
@@ -71138,127 +71138,6 @@ class MaskVolume {
|
|
|
71138
71138
|
}
|
|
71139
71139
|
}
|
|
71140
71140
|
}
|
|
71141
|
-
/**
|
|
71142
|
-
* Extract a 2D slice as raw RGBA ImageData (lossless round-trip).
|
|
71143
|
-
*
|
|
71144
|
-
* Requires the volume to have **≥ 4 channels** (ch0=R, ch1=G, ch2=B, ch3=A).
|
|
71145
|
-
* Returns the exact pixel data that was stored via `setSliceFromImageData`,
|
|
71146
|
-
* bypassing all render modes.
|
|
71147
|
-
*
|
|
71148
|
-
* @param sliceIndex Index along the specified axis.
|
|
71149
|
-
* @param axis `'x'`, `'y'`, or `'z'` (default `'z'`).
|
|
71150
|
-
* @returns ImageData with the stored RGBA values.
|
|
71151
|
-
*
|
|
71152
|
-
* @throws {RangeError} If sliceIndex is out of bounds.
|
|
71153
|
-
* @throws {Error} If the volume has fewer than 4 channels.
|
|
71154
|
-
*/
|
|
71155
|
-
getSliceRawImageData(sliceIndex, axis = 'z') {
|
|
71156
|
-
if (this.numChannels < 4) {
|
|
71157
|
-
throw new Error(`getSliceRawImageData requires ≥ 4 channels, volume has ${this.numChannels}`);
|
|
71158
|
-
}
|
|
71159
|
-
this.validateSliceIndex(sliceIndex, axis);
|
|
71160
|
-
const { width, height } = this.dims;
|
|
71161
|
-
const ch = this.numChannels;
|
|
71162
|
-
const [sliceWidth, sliceHeight] = this.getSliceDimensions(axis);
|
|
71163
|
-
const imageData = new ImageData(sliceWidth, sliceHeight);
|
|
71164
|
-
const pixels = imageData.data;
|
|
71165
|
-
const volData = this.data;
|
|
71166
|
-
if (axis === 'z') {
|
|
71167
|
-
// Z-axis (axial): slice data is contiguous in memory — direct bulk copy
|
|
71168
|
-
const offset = sliceIndex * this.bytesPerSlice;
|
|
71169
|
-
pixels.set(volData.subarray(offset, offset + this.bytesPerSlice));
|
|
71170
|
-
}
|
|
71171
|
-
else if (axis === 'y') {
|
|
71172
|
-
// Y-axis (coronal): each row (fixed z, fixed y, varying x) is contiguous
|
|
71173
|
-
// mapping: (i → x, sliceIndex → y, j → z)
|
|
71174
|
-
const rowBytes = width * ch;
|
|
71175
|
-
let px = 0;
|
|
71176
|
-
for (let j = 0; j < sliceHeight; j++) {
|
|
71177
|
-
const rowStart = j * height * width * ch + sliceIndex * width * ch;
|
|
71178
|
-
pixels.set(volData.subarray(rowStart, rowStart + rowBytes), px);
|
|
71179
|
-
px += rowBytes;
|
|
71180
|
-
}
|
|
71181
|
-
}
|
|
71182
|
-
else {
|
|
71183
|
-
// X-axis (sagittal): pixels not contiguous, but avoid function call overhead
|
|
71184
|
-
// After dimension fix: sliceWidth = depth (Z), sliceHeight = height (Y)
|
|
71185
|
-
// j → y (rows), i → z (columns)
|
|
71186
|
-
let px = 0;
|
|
71187
|
-
for (let j = 0; j < sliceHeight; j++) {
|
|
71188
|
-
const yOffset = j * width * ch;
|
|
71189
|
-
for (let i = 0; i < sliceWidth; i++) {
|
|
71190
|
-
const baseIdx = i * height * width * ch + yOffset + sliceIndex * ch;
|
|
71191
|
-
pixels[px] = volData[baseIdx];
|
|
71192
|
-
pixels[px + 1] = volData[baseIdx + 1];
|
|
71193
|
-
pixels[px + 2] = volData[baseIdx + 2];
|
|
71194
|
-
pixels[px + 3] = volData[baseIdx + 3];
|
|
71195
|
-
px += 4;
|
|
71196
|
-
}
|
|
71197
|
-
}
|
|
71198
|
-
}
|
|
71199
|
-
return imageData;
|
|
71200
|
-
}
|
|
71201
|
-
/**
|
|
71202
|
-
* Write slice data into an existing ImageData buffer (zero-allocation).
|
|
71203
|
-
*
|
|
71204
|
-
* Same semantics as {@link getSliceRawImageData} but avoids creating a new
|
|
71205
|
-
* ImageData object on every call. The caller is responsible for providing
|
|
71206
|
-
* a buffer whose dimensions match the expected slice size.
|
|
71207
|
-
*
|
|
71208
|
-
* All pixels are fully overwritten — no clearing is needed beforehand.
|
|
71209
|
-
*
|
|
71210
|
-
* @param sliceIndex Index along the specified axis.
|
|
71211
|
-
* @param axis `'x'`, `'y'`, or `'z'` (default `'z'`).
|
|
71212
|
-
* @param target Pre-allocated ImageData to write into.
|
|
71213
|
-
*
|
|
71214
|
-
* @throws {Error} If the volume has fewer than 4 channels.
|
|
71215
|
-
* @throws {RangeError} If sliceIndex is out of bounds.
|
|
71216
|
-
* @throws {Error} If target dimensions don't match the slice.
|
|
71217
|
-
*/
|
|
71218
|
-
getSliceRawImageDataInto(sliceIndex, axis = 'z', target) {
|
|
71219
|
-
if (this.numChannels < 4) {
|
|
71220
|
-
throw new Error(`getSliceRawImageDataInto requires ≥ 4 channels, volume has ${this.numChannels}`);
|
|
71221
|
-
}
|
|
71222
|
-
this.validateSliceIndex(sliceIndex, axis);
|
|
71223
|
-
const [sliceWidth, sliceHeight] = this.getSliceDimensions(axis);
|
|
71224
|
-
if (target.width !== sliceWidth || target.height !== sliceHeight) {
|
|
71225
|
-
throw new Error(`Buffer size mismatch: expected ${sliceWidth}×${sliceHeight}, ` +
|
|
71226
|
-
`got ${target.width}×${target.height}`);
|
|
71227
|
-
}
|
|
71228
|
-
const { width, height } = this.dims;
|
|
71229
|
-
const ch = this.numChannels;
|
|
71230
|
-
const pixels = target.data;
|
|
71231
|
-
const volData = this.data;
|
|
71232
|
-
if (axis === 'z') {
|
|
71233
|
-
const offset = sliceIndex * this.bytesPerSlice;
|
|
71234
|
-
pixels.set(volData.subarray(offset, offset + this.bytesPerSlice));
|
|
71235
|
-
}
|
|
71236
|
-
else if (axis === 'y') {
|
|
71237
|
-
const rowBytes = width * ch;
|
|
71238
|
-
let px = 0;
|
|
71239
|
-
for (let j = 0; j < sliceHeight; j++) {
|
|
71240
|
-
const rowStart = j * height * width * ch + sliceIndex * width * ch;
|
|
71241
|
-
pixels.set(volData.subarray(rowStart, rowStart + rowBytes), px);
|
|
71242
|
-
px += rowBytes;
|
|
71243
|
-
}
|
|
71244
|
-
}
|
|
71245
|
-
else {
|
|
71246
|
-
// X-axis (sagittal): sliceWidth = depth (Z), sliceHeight = height (Y)
|
|
71247
|
-
// j → y (rows), i → z (columns)
|
|
71248
|
-
let px = 0;
|
|
71249
|
-
for (let j = 0; j < sliceHeight; j++) {
|
|
71250
|
-
const yOffset = j * width * ch;
|
|
71251
|
-
for (let i = 0; i < sliceWidth; i++) {
|
|
71252
|
-
const baseIdx = i * height * width * ch + yOffset + sliceIndex * ch;
|
|
71253
|
-
pixels[px] = volData[baseIdx];
|
|
71254
|
-
pixels[px + 1] = volData[baseIdx + 1];
|
|
71255
|
-
pixels[px + 2] = volData[baseIdx + 2];
|
|
71256
|
-
pixels[px + 3] = volData[baseIdx + 3];
|
|
71257
|
-
px += 4;
|
|
71258
|
-
}
|
|
71259
|
-
}
|
|
71260
|
-
}
|
|
71261
|
-
}
|
|
71262
71141
|
// ── Label-based storage (1-channel volumes) ────────────────────────
|
|
71263
71142
|
/**
|
|
71264
71143
|
/**
|
|
@@ -72781,12 +72660,12 @@ class DragOperator {
|
|
|
72781
72660
|
this.eventRouter.subscribeModeChange((prevMode, newMode) => {
|
|
72782
72661
|
const prev = prevMode;
|
|
72783
72662
|
const next = newMode;
|
|
72784
|
-
// When entering draw or
|
|
72785
|
-
if (next === 'draw' || next === 'contrast') {
|
|
72663
|
+
// When entering draw, contrast, or crosshair mode, remove drag mode
|
|
72664
|
+
if (next === 'draw' || next === 'contrast' || next === 'crosshair') {
|
|
72786
72665
|
this.removeDragMode();
|
|
72787
72666
|
}
|
|
72788
|
-
// When leaving draw or
|
|
72789
|
-
if ((prev === 'draw' || prev === 'contrast') && next === 'idle') {
|
|
72667
|
+
// When leaving draw, contrast, or crosshair mode (returning to idle), restore drag mode
|
|
72668
|
+
if ((prev === 'draw' || prev === 'contrast' || prev === 'crosshair') && next === 'idle') {
|
|
72790
72669
|
if (!this.gui_states.sphere) {
|
|
72791
72670
|
this.configDragMode();
|
|
72792
72671
|
}
|
|
@@ -72889,7 +72768,6 @@ class CommToolsData {
|
|
|
72889
72768
|
ratios: { x: 1, y: 1, z: 1 },
|
|
72890
72769
|
contrastNum: 0,
|
|
72891
72770
|
showContrast: false,
|
|
72892
|
-
enableCursorChoose: false,
|
|
72893
72771
|
isCursorSelect: false,
|
|
72894
72772
|
cursorPageX: 0,
|
|
72895
72773
|
cursorPageY: 0,
|
|
@@ -73029,8 +72907,6 @@ class CommToolsData {
|
|
|
73029
72907
|
skipSlicesDic: {},
|
|
73030
72908
|
currentShowingSlice: undefined,
|
|
73031
72909
|
mainPreSlices: undefined,
|
|
73032
|
-
Is_Shift_Pressed: false,
|
|
73033
|
-
Is_Ctrl_Pressed: false,
|
|
73034
72910
|
Is_Draw: false,
|
|
73035
72911
|
axis: "z",
|
|
73036
72912
|
maskData: {
|
|
@@ -73180,12 +73056,6 @@ class CommToolsData {
|
|
|
73180
73056
|
clearStoreImages() {
|
|
73181
73057
|
throw new Error("Child class must implement abstract clearStoreImages, currently you can find it in NrrdTools.");
|
|
73182
73058
|
}
|
|
73183
|
-
/**
|
|
73184
|
-
* Rewrite this {createEmptyPaintImage} function under NrrdTools
|
|
73185
|
-
*/
|
|
73186
|
-
createEmptyPaintImage(dimensions, paintImages) {
|
|
73187
|
-
throw new Error("Child class must implement abstract clearStoreImages, currently you can find it in NrrdTools.");
|
|
73188
|
-
}
|
|
73189
73059
|
/**
|
|
73190
73060
|
* Rewrite this {resizePaintArea} function under NrrdTools
|
|
73191
73061
|
*/
|
|
@@ -73247,13 +73117,13 @@ class CommToolsData {
|
|
|
73247
73117
|
throw new Error("Child class must implement abstract redrawDisplayCanvas, currently you can find it in NrrdTools.");
|
|
73248
73118
|
}
|
|
73249
73119
|
/**
|
|
73250
|
-
* Get a painted mask image
|
|
73120
|
+
* Get a painted mask image based on current axis and input slice index.
|
|
73251
73121
|
*
|
|
73252
|
-
* Phase 3: Reads directly from MaskVolume
|
|
73122
|
+
* Phase 3: Reads directly from MaskVolume.
|
|
73253
73123
|
*
|
|
73254
73124
|
* @param axis "x" | "y" | "z"
|
|
73255
73125
|
* @param sliceIndex number
|
|
73256
|
-
* @returns
|
|
73126
|
+
* @returns Object with index and image, or undefined
|
|
73257
73127
|
*/
|
|
73258
73128
|
filterDrawedImage(axis, sliceIndex) {
|
|
73259
73129
|
try {
|
|
@@ -73310,7 +73180,7 @@ class CommToolsData {
|
|
|
73310
73180
|
/**
|
|
73311
73181
|
* Render a layer's slice into a reusable buffer and draw to the target canvas.
|
|
73312
73182
|
*
|
|
73313
|
-
* Uses MaskVolume.
|
|
73183
|
+
* Uses MaskVolume.renderLabelSliceInto() for zero-allocation rendering.
|
|
73314
73184
|
* The caller should obtain the buffer via getOrCreateSliceBuffer() and reuse
|
|
73315
73185
|
* it across multiple layer renders.
|
|
73316
73186
|
*
|
|
@@ -73566,11 +73436,13 @@ class EventRouter {
|
|
|
73566
73436
|
}
|
|
73567
73437
|
/**
|
|
73568
73438
|
* Toggle crosshair mode.
|
|
73439
|
+
* Blocked when draw or contrast mode is active (mutual exclusion).
|
|
73569
73440
|
*/
|
|
73570
73441
|
toggleCrosshair() {
|
|
73571
73442
|
if (!DRAWING_TOOLS.has(this.guiTool))
|
|
73572
73443
|
return;
|
|
73573
|
-
|
|
73444
|
+
// Block crosshair activation during draw or contrast
|
|
73445
|
+
if (this.state.shiftHeld || this.mode === 'draw' || this.mode === 'contrast')
|
|
73574
73446
|
return;
|
|
73575
73447
|
this.state.crosshairEnabled = !this.state.crosshairEnabled;
|
|
73576
73448
|
this.setMode(this.state.crosshairEnabled ? 'crosshair' : 'idle');
|
|
@@ -73689,12 +73561,16 @@ class EventRouter {
|
|
|
73689
73561
|
// Update state based on modifier keys
|
|
73690
73562
|
if (ev.key === this.keyboardSettings.draw) {
|
|
73691
73563
|
this.state.shiftHeld = true;
|
|
73692
|
-
|
|
73564
|
+
// Block draw mode when crosshair or contrast is active (mutual exclusion)
|
|
73565
|
+
if (DRAWING_TOOLS.has(this.guiTool) && !this.state.ctrlHeld && !this.state.crosshairEnabled) {
|
|
73693
73566
|
this.setMode('draw');
|
|
73694
73567
|
}
|
|
73695
73568
|
}
|
|
73696
73569
|
if (this.contrastEnabled && this.keyboardSettings.contrast.includes(ev.key)) {
|
|
73697
|
-
|
|
73570
|
+
// Block contrast state when crosshair or draw is active (mutual exclusion)
|
|
73571
|
+
if (!this.state.crosshairEnabled && this.mode !== 'draw') {
|
|
73572
|
+
this.state.ctrlHeld = true;
|
|
73573
|
+
}
|
|
73698
73574
|
}
|
|
73699
73575
|
// Route to external handler
|
|
73700
73576
|
if (this.keydownHandler) {
|
|
@@ -73854,7 +73730,7 @@ class SphereTool extends BaseTool {
|
|
|
73854
73730
|
this.callbacks.setEmptyCanvasSize(axis);
|
|
73855
73731
|
this.callbacks.drawImageOnEmptyImage(this.ctx.protectedData.canvases.drawingSphereCanvas);
|
|
73856
73732
|
const imageData = this.ctx.protectedData.ctxes.emptyCtx.getImageData(0, 0, this.ctx.protectedData.canvases.emptyCanvas.width, this.ctx.protectedData.canvases.emptyCanvas.height);
|
|
73857
|
-
this.callbacks.storeImageToAxis(index,
|
|
73733
|
+
this.callbacks.storeImageToAxis(index, imageData, axis);
|
|
73858
73734
|
}
|
|
73859
73735
|
// ===== Multi-View Sphere =====
|
|
73860
73736
|
drawSphereOnEachViews(decay, axis) {
|
|
@@ -74251,7 +74127,8 @@ class ZoomTool extends BaseTool {
|
|
|
74251
74127
|
configMouseZoomWheel() {
|
|
74252
74128
|
let moveDistance = 1;
|
|
74253
74129
|
return (e) => {
|
|
74254
|
-
|
|
74130
|
+
var _a;
|
|
74131
|
+
if ((_a = this.ctx.eventRouter) === null || _a === void 0 ? void 0 : _a.isShiftHeld()) {
|
|
74255
74132
|
return;
|
|
74256
74133
|
}
|
|
74257
74134
|
e.preventDefault();
|
|
@@ -74388,8 +74265,7 @@ class EraserTool extends BaseTool {
|
|
|
74388
74265
|
* Extracted from DrawToolCore.ts:
|
|
74389
74266
|
* - storeAllImages / storeImageToAxis / storeImageToLayer / storeEachLayerImage
|
|
74390
74267
|
*
|
|
74391
|
-
* Phase
|
|
74392
|
-
* Volume is the primary storage; IPaintImages kept for backward compatibility.
|
|
74268
|
+
* Phase 3: MaskVolume is the sole storage backend. All IPaintImages params removed.
|
|
74393
74269
|
*/
|
|
74394
74270
|
class ImageStoreHelper extends BaseTool {
|
|
74395
74271
|
constructor(ctx, callbacks) {
|
|
@@ -74406,12 +74282,12 @@ class ImageStoreHelper extends BaseTool {
|
|
|
74406
74282
|
*/
|
|
74407
74283
|
getVolumeForLayer(layer) {
|
|
74408
74284
|
const { volumes } = this.ctx.protectedData.maskData;
|
|
74409
|
-
|
|
74410
|
-
|
|
74411
|
-
|
|
74412
|
-
|
|
74413
|
-
|
|
74414
|
-
|
|
74285
|
+
const vol = volumes[layer];
|
|
74286
|
+
if (vol)
|
|
74287
|
+
return vol;
|
|
74288
|
+
const firstLayerId = this.ctx.nrrd_states.layers[0];
|
|
74289
|
+
console.warn(`ImageStoreHelper: unknown layer "${layer}", falling back to "${firstLayerId}"`);
|
|
74290
|
+
return volumes[firstLayerId];
|
|
74415
74291
|
}
|
|
74416
74292
|
/**
|
|
74417
74293
|
* Get MaskVolume for the currently active layer.
|
|
@@ -74430,19 +74306,17 @@ class ImageStoreHelper extends BaseTool {
|
|
|
74430
74306
|
}
|
|
74431
74307
|
// ===== Store Image To Axis =====
|
|
74432
74308
|
/**
|
|
74433
|
-
* Phase 3:
|
|
74434
|
-
* MaskVolume storage happens in storeAllImages via setSliceFromImageData.
|
|
74435
|
-
* This method kept for backward compatibility with existing call sites.
|
|
74309
|
+
* Phase 3: No-op — MaskVolume storage happens in storeAllImages.
|
|
74436
74310
|
*/
|
|
74437
|
-
storeImageToAxis(_index,
|
|
74311
|
+
storeImageToAxis(_index, _imageData, _axis) {
|
|
74438
74312
|
// No-op: MaskVolume is the primary storage, updated in storeAllImages
|
|
74439
74313
|
}
|
|
74440
74314
|
/**
|
|
74441
74315
|
* Retrieve the drawn image for a given axis and slice.
|
|
74442
74316
|
*
|
|
74443
|
-
* Phase 3: Reads exclusively from MaskVolume
|
|
74317
|
+
* Phase 3: Reads exclusively from MaskVolume.
|
|
74444
74318
|
*/
|
|
74445
|
-
filterDrawedImage(axis, sliceIndex
|
|
74319
|
+
filterDrawedImage(axis, sliceIndex) {
|
|
74446
74320
|
try {
|
|
74447
74321
|
const volume = this.getCurrentVolume();
|
|
74448
74322
|
if (volume) {
|
|
@@ -74531,10 +74405,9 @@ class ImageStoreHelper extends BaseTool {
|
|
|
74531
74405
|
}
|
|
74532
74406
|
}
|
|
74533
74407
|
/**
|
|
74534
|
-
*
|
|
74535
|
-
* Kept for backward compatibility with existing call sites.
|
|
74408
|
+
* Extract ImageData from canvas (MaskVolume storage is handled in storeAllImages).
|
|
74536
74409
|
*/
|
|
74537
|
-
storeImageToLayer(_index, canvas
|
|
74410
|
+
storeImageToLayer(_index, canvas) {
|
|
74538
74411
|
if (!this.ctx.nrrd_states.loadMaskJson) {
|
|
74539
74412
|
this.callbacks.setEmptyCanvasSize();
|
|
74540
74413
|
this.callbacks.drawImageOnEmptyImage(canvas);
|
|
@@ -74543,16 +74416,6 @@ class ImageStoreHelper extends BaseTool {
|
|
|
74543
74416
|
// No longer stores to paintedImages - MaskVolume is primary storage
|
|
74544
74417
|
return imageData;
|
|
74545
74418
|
}
|
|
74546
|
-
// ===== Helper Methods =====
|
|
74547
|
-
hasNonZeroPixels(imageData) {
|
|
74548
|
-
const data = imageData.data;
|
|
74549
|
-
for (let i = 0; i < data.length; i += 4) {
|
|
74550
|
-
if (data[i] !== 0 || data[i + 1] !== 0 || data[i + 2] !== 0 || data[i + 3] !== 0) {
|
|
74551
|
-
return true;
|
|
74552
|
-
}
|
|
74553
|
-
}
|
|
74554
|
-
return false;
|
|
74555
|
-
}
|
|
74556
74419
|
}
|
|
74557
74420
|
|
|
74558
74421
|
class DrawToolCore extends CommToolsData {
|
|
@@ -74631,8 +74494,7 @@ class DrawToolCore extends CommToolsData {
|
|
|
74631
74494
|
this.sphereTool = new SphereTool(toolCtx, {
|
|
74632
74495
|
setEmptyCanvasSize: (axis) => this.setEmptyCanvasSize(axis),
|
|
74633
74496
|
drawImageOnEmptyImage: (canvas) => this.drawImageOnEmptyImage(canvas),
|
|
74634
|
-
storeImageToAxis: (index,
|
|
74635
|
-
createEmptyPaintImage: (dimensions, paintImages) => this.createEmptyPaintImage(dimensions, paintImages),
|
|
74497
|
+
storeImageToAxis: (index, imageData, axis) => this.imageStoreHelper.storeImageToAxis(index, imageData, axis),
|
|
74636
74498
|
});
|
|
74637
74499
|
this.crosshairTool = new CrosshairTool(toolCtx);
|
|
74638
74500
|
this.contrastTool = new ContrastTool(toolCtx, this.container, this.contrastEventPrameters, {
|
|
@@ -74655,40 +74517,28 @@ class DrawToolCore extends CommToolsData {
|
|
|
74655
74517
|
// Use string comparison to avoid TypeScript narrowing issues
|
|
74656
74518
|
const prev = prevMode;
|
|
74657
74519
|
const next = newMode;
|
|
74658
|
-
// Sync EventRouter mode changes with existing state flags
|
|
74659
|
-
if (next === 'draw') {
|
|
74660
|
-
this.protectedData.Is_Shift_Pressed = true;
|
|
74661
|
-
this.nrrd_states.enableCursorChoose = false;
|
|
74662
|
-
}
|
|
74663
|
-
else if (prev === 'draw') {
|
|
74664
|
-
this.protectedData.Is_Shift_Pressed = false;
|
|
74665
|
-
}
|
|
74666
74520
|
if (next === 'contrast') {
|
|
74667
|
-
this.protectedData.Is_Ctrl_Pressed = true;
|
|
74668
|
-
this.protectedData.Is_Shift_Pressed = false;
|
|
74669
74521
|
this.configContrastDragMode();
|
|
74670
74522
|
}
|
|
74671
74523
|
else if (prev === 'contrast') {
|
|
74672
|
-
this.protectedData.Is_Ctrl_Pressed = false;
|
|
74673
74524
|
this.removeContrastDragMode();
|
|
74674
74525
|
this.gui_states.readyToUpdate = true;
|
|
74675
74526
|
}
|
|
74676
74527
|
if (next === 'crosshair') {
|
|
74677
|
-
this.nrrd_states.enableCursorChoose = true;
|
|
74678
74528
|
this.protectedData.Is_Draw = false;
|
|
74679
74529
|
}
|
|
74680
|
-
else if (prev === 'crosshair') {
|
|
74681
|
-
this.nrrd_states.enableCursorChoose = false;
|
|
74682
|
-
}
|
|
74683
74530
|
}
|
|
74684
74531
|
});
|
|
74532
|
+
// Inject eventRouter into ToolContext so tools can query mode/state
|
|
74533
|
+
const toolCtx = this.sphereTool['ctx'];
|
|
74534
|
+
toolCtx.eventRouter = this.eventRouter;
|
|
74685
74535
|
// Configure keyboard settings from class field
|
|
74686
74536
|
this.eventRouter.setKeyboardSettings(this._keyboardSettings);
|
|
74687
74537
|
// Track undo flag for Ctrl+Z handling
|
|
74688
74538
|
let undoFlag = false;
|
|
74689
74539
|
// Register keyboard handlers with EventRouter
|
|
74690
74540
|
this.eventRouter.setKeydownHandler((ev) => {
|
|
74691
|
-
var _a;
|
|
74541
|
+
var _a, _b;
|
|
74692
74542
|
if (this._configKeyBoard)
|
|
74693
74543
|
return;
|
|
74694
74544
|
// Handle undo (Ctrl+Z)
|
|
@@ -74709,15 +74559,16 @@ class DrawToolCore extends CommToolsData {
|
|
|
74709
74559
|
}
|
|
74710
74560
|
}
|
|
74711
74561
|
// Handle draw mode (Shift key) - EventRouter already tracks this
|
|
74562
|
+
// EventRouter's handleKeyDown will enforce mutual exclusion
|
|
74712
74563
|
if (ev.key === this._keyboardSettings.draw && !this.gui_states.sphere && !this.gui_states.calculator) {
|
|
74713
|
-
if (this.
|
|
74564
|
+
if ((_b = this.eventRouter) === null || _b === void 0 ? void 0 : _b.isCtrlHeld()) {
|
|
74714
74565
|
return; // Ctrl takes priority
|
|
74715
74566
|
}
|
|
74716
74567
|
// EventRouter will set mode to 'draw' via internal handler
|
|
74717
74568
|
}
|
|
74718
74569
|
});
|
|
74719
74570
|
this.eventRouter.setKeyupHandler((ev) => {
|
|
74720
|
-
var _a, _b, _c, _d;
|
|
74571
|
+
var _a, _b, _c, _d, _e, _f;
|
|
74721
74572
|
if (this._configKeyBoard)
|
|
74722
74573
|
return;
|
|
74723
74574
|
// Handle Ctrl key release (contrast mode toggle)
|
|
@@ -74730,12 +74581,15 @@ class DrawToolCore extends CommToolsData {
|
|
|
74730
74581
|
// Skip mode toggle when contrast shortcut is disabled
|
|
74731
74582
|
if (!((_a = this.eventRouter) === null || _a === void 0 ? void 0 : _a.isContrastEnabled()))
|
|
74732
74583
|
return;
|
|
74584
|
+
// Block contrast toggle during crosshair or draw (mutual exclusion)
|
|
74585
|
+
if (((_b = this.eventRouter) === null || _b === void 0 ? void 0 : _b.isCrosshairEnabled()) || ((_c = this.eventRouter) === null || _c === void 0 ? void 0 : _c.getMode()) === 'draw')
|
|
74586
|
+
return;
|
|
74733
74587
|
// Toggle contrast mode manually since it's on keyup
|
|
74734
|
-
if (((
|
|
74735
|
-
(
|
|
74588
|
+
if (((_d = this.eventRouter) === null || _d === void 0 ? void 0 : _d.getMode()) !== 'contrast') {
|
|
74589
|
+
(_e = this.eventRouter) === null || _e === void 0 ? void 0 : _e.setMode('contrast');
|
|
74736
74590
|
}
|
|
74737
74591
|
else {
|
|
74738
|
-
(
|
|
74592
|
+
(_f = this.eventRouter) === null || _f === void 0 ? void 0 : _f.setMode('idle');
|
|
74739
74593
|
}
|
|
74740
74594
|
}
|
|
74741
74595
|
});
|
|
@@ -74911,6 +74765,7 @@ class DrawToolCore extends CommToolsData {
|
|
|
74911
74765
|
}
|
|
74912
74766
|
};
|
|
74913
74767
|
this.drawingPrameters.handleOnDrawingMouseDown = (e) => {
|
|
74768
|
+
var _a, _b, _c, _d;
|
|
74914
74769
|
if (leftclicked || rightclicked) {
|
|
74915
74770
|
this.protectedData.canvases.drawingCanvas.removeEventListener("pointerup", this.drawingPrameters.handleOnDrawingMouseUp);
|
|
74916
74771
|
this.protectedData.ctxes.drawingLayerMasterCtx.closePath();
|
|
@@ -74926,7 +74781,7 @@ class DrawToolCore extends CommToolsData {
|
|
|
74926
74781
|
// remove it when mouse click down
|
|
74927
74782
|
this.protectedData.canvases.drawingCanvas.removeEventListener("wheel", this.drawingPrameters.handleMouseZoomSliceWheel);
|
|
74928
74783
|
if (e.button === 0) {
|
|
74929
|
-
if (this.
|
|
74784
|
+
if (((_a = this.eventRouter) === null || _a === void 0 ? void 0 : _a.getMode()) === 'draw') {
|
|
74930
74785
|
leftclicked = true;
|
|
74931
74786
|
lines = [];
|
|
74932
74787
|
Is_Painting = true;
|
|
@@ -74953,13 +74808,13 @@ class DrawToolCore extends CommToolsData {
|
|
|
74953
74808
|
const vol = this.getVolumeForLayer(this.gui_states.layer);
|
|
74954
74809
|
this.preDrawSlice = vol.getSliceUint8(this.preDrawSliceIndex, this.preDrawAxis).data.slice();
|
|
74955
74810
|
}
|
|
74956
|
-
catch (
|
|
74811
|
+
catch (_e) {
|
|
74957
74812
|
this.preDrawSlice = null;
|
|
74958
74813
|
}
|
|
74959
74814
|
this.protectedData.canvases.drawingCanvas.addEventListener("pointerup", this.drawingPrameters.handleOnDrawingMouseUp);
|
|
74960
74815
|
this.protectedData.canvases.drawingCanvas.addEventListener("pointermove", this.drawingPrameters.handleOnDrawingMouseMove);
|
|
74961
74816
|
}
|
|
74962
|
-
else if (this.
|
|
74817
|
+
else if ((_b = this.eventRouter) === null || _b === void 0 ? void 0 : _b.isCrosshairEnabled()) {
|
|
74963
74818
|
this.nrrd_states.cursorPageX =
|
|
74964
74819
|
e.offsetX / this.nrrd_states.sizeFoctor;
|
|
74965
74820
|
this.nrrd_states.cursorPageY =
|
|
@@ -74967,10 +74822,10 @@ class DrawToolCore extends CommToolsData {
|
|
|
74967
74822
|
this.enableCrosshair();
|
|
74968
74823
|
this.protectedData.canvases.drawingCanvas.addEventListener("pointerup", this.drawingPrameters.handleOnDrawingMouseUp);
|
|
74969
74824
|
}
|
|
74970
|
-
else if (this.gui_states.sphere && !this.
|
|
74825
|
+
else if (this.gui_states.sphere && !((_c = this.eventRouter) === null || _c === void 0 ? void 0 : _c.isCrosshairEnabled())) {
|
|
74971
74826
|
sphere(e);
|
|
74972
74827
|
}
|
|
74973
|
-
else if (this.gui_states.calculator && !this.
|
|
74828
|
+
else if (this.gui_states.calculator && !((_d = this.eventRouter) === null || _d === void 0 ? void 0 : _d.isCrosshairEnabled())) {
|
|
74974
74829
|
this.drawCalSphereDown(e.offsetX, e.offsetY, this.nrrd_states.currentIndex, this.gui_states.cal_distance);
|
|
74975
74830
|
}
|
|
74976
74831
|
}
|
|
@@ -75035,8 +74890,9 @@ class DrawToolCore extends CommToolsData {
|
|
|
75035
74890
|
ctx.drawImage(this.protectedData.canvases.emptyCanvas, 0, 0, this.nrrd_states.changedWidth, this.nrrd_states.changedHeight);
|
|
75036
74891
|
};
|
|
75037
74892
|
this.drawingPrameters.handleOnDrawingMouseUp = (e) => {
|
|
74893
|
+
var _a, _b, _c, _d;
|
|
75038
74894
|
if (e.button === 0) {
|
|
75039
|
-
if (this.
|
|
74895
|
+
if (((_a = this.eventRouter) === null || _a === void 0 ? void 0 : _a.getMode()) === 'draw' || Is_Painting) {
|
|
75040
74896
|
leftclicked = false;
|
|
75041
74897
|
let { ctx, canvas } = this.setCurrentLayer();
|
|
75042
74898
|
ctx.closePath();
|
|
@@ -75084,7 +74940,7 @@ class DrawToolCore extends CommToolsData {
|
|
|
75084
74940
|
};
|
|
75085
74941
|
this.undoManager.push(delta);
|
|
75086
74942
|
}
|
|
75087
|
-
catch (
|
|
74943
|
+
catch (_e) {
|
|
75088
74944
|
// Volume not ready — skip
|
|
75089
74945
|
}
|
|
75090
74946
|
this.preDrawSlice = null;
|
|
@@ -75095,7 +74951,7 @@ class DrawToolCore extends CommToolsData {
|
|
|
75095
74951
|
});
|
|
75096
74952
|
}
|
|
75097
74953
|
else if (this.gui_states.sphere &&
|
|
75098
|
-
!this.
|
|
74954
|
+
!((_b = this.eventRouter) === null || _b === void 0 ? void 0 : _b.isCrosshairEnabled())) {
|
|
75099
74955
|
// plan B
|
|
75100
74956
|
// findout all index in the sphere radius range in Axial view
|
|
75101
74957
|
if (this.nrrd_states.spherePlanB) {
|
|
@@ -75115,12 +74971,12 @@ class DrawToolCore extends CommToolsData {
|
|
|
75115
74971
|
this.protectedData.canvases.drawingCanvas.removeEventListener("pointerup", this.drawingPrameters.handleOnDrawingMouseUp);
|
|
75116
74972
|
}
|
|
75117
74973
|
else if ((this.gui_states.sphere || this.gui_states.calculator) &&
|
|
75118
|
-
this.
|
|
74974
|
+
((_c = this.eventRouter) === null || _c === void 0 ? void 0 : _c.isCrosshairEnabled())) {
|
|
75119
74975
|
this.protectedData.canvases.drawingCanvas.addEventListener("wheel", this.drawingPrameters.handleMouseZoomSliceWheel);
|
|
75120
74976
|
this.protectedData.canvases.drawingCanvas.removeEventListener("pointerup", this.drawingPrameters.handleOnDrawingMouseUp);
|
|
75121
74977
|
}
|
|
75122
74978
|
else if (this.gui_states.calculator &&
|
|
75123
|
-
!this.
|
|
74979
|
+
!((_d = this.eventRouter) === null || _d === void 0 ? void 0 : _d.isCrosshairEnabled())) {
|
|
75124
74980
|
// When mouse up
|
|
75125
74981
|
this.drawCalSphereUp();
|
|
75126
74982
|
}
|
|
@@ -75162,6 +75018,7 @@ class DrawToolCore extends CommToolsData {
|
|
|
75162
75018
|
}
|
|
75163
75019
|
});
|
|
75164
75020
|
this.start = () => {
|
|
75021
|
+
var _a, _b;
|
|
75165
75022
|
if (this.gui_states.readyToUpdate) {
|
|
75166
75023
|
this.protectedData.ctxes.drawingCtx.clearRect(0, 0, this.nrrd_states.changedWidth, this.nrrd_states.changedHeight);
|
|
75167
75024
|
this.protectedData.ctxes.drawingCtx.globalAlpha =
|
|
@@ -75175,7 +75032,10 @@ class DrawToolCore extends CommToolsData {
|
|
|
75175
75032
|
}
|
|
75176
75033
|
}
|
|
75177
75034
|
else {
|
|
75178
|
-
|
|
75035
|
+
// Use EventRouter mode for mutually exclusive crosshair vs draw rendering
|
|
75036
|
+
const currentMode = (_a = this.eventRouter) === null || _a === void 0 ? void 0 : _a.getMode();
|
|
75037
|
+
if (currentMode === 'draw') {
|
|
75038
|
+
// Draw mode: show brush circle preview
|
|
75179
75039
|
if (!this.gui_states.pencil &&
|
|
75180
75040
|
!this.gui_states.Eraser &&
|
|
75181
75041
|
this.nrrd_states.Mouse_Over) {
|
|
@@ -75189,7 +75049,8 @@ class DrawToolCore extends CommToolsData {
|
|
|
75189
75049
|
this.protectedData.ctxes.drawingCtx.stroke();
|
|
75190
75050
|
}
|
|
75191
75051
|
}
|
|
75192
|
-
if (this.
|
|
75052
|
+
else if (currentMode === 'crosshair' || ((_b = this.eventRouter) === null || _b === void 0 ? void 0 : _b.isCrosshairEnabled())) {
|
|
75053
|
+
// Crosshair mode: show red cross lines (mutually exclusive with draw)
|
|
75193
75054
|
this.protectedData.ctxes.drawingCtx.clearRect(0, 0, this.nrrd_states.changedWidth, this.nrrd_states.changedHeight);
|
|
75194
75055
|
const ex = this.nrrd_states.cursorPageX * this.nrrd_states.sizeFoctor;
|
|
75195
75056
|
const ey = this.nrrd_states.cursorPageY * this.nrrd_states.sizeFoctor;
|
|
@@ -75345,19 +75206,18 @@ class DrawToolCore extends CommToolsData {
|
|
|
75345
75206
|
/**
|
|
75346
75207
|
* Clear mask on current slice canvas.
|
|
75347
75208
|
*
|
|
75348
|
-
*
|
|
75349
|
-
*
|
|
75350
|
-
*
|
|
75209
|
+
* Only clears the active layer's MaskVolume slice data.
|
|
75210
|
+
* Other layers are left untouched. After clearing, all layer canvases
|
|
75211
|
+
* are re-rendered from MaskVolume to keep visuals in sync.
|
|
75351
75212
|
*/
|
|
75352
75213
|
clearPaint() {
|
|
75353
75214
|
this.protectedData.Is_Draw = true;
|
|
75354
|
-
this.resetLayerCanvas();
|
|
75355
75215
|
this.protectedData.canvases.originCanvas.width =
|
|
75356
75216
|
this.protectedData.canvases.originCanvas.width;
|
|
75357
75217
|
this.protectedData.mainPreSlices.repaint.call(this.protectedData.mainPreSlices);
|
|
75358
75218
|
this.protectedData.previousDrawingImage =
|
|
75359
75219
|
this.protectedData.ctxes.emptyCtx.createImageData(1, 1);
|
|
75360
|
-
//
|
|
75220
|
+
// Clear only the active layer's MaskVolume slice and record undo delta
|
|
75361
75221
|
try {
|
|
75362
75222
|
const axis = this.protectedData.axis;
|
|
75363
75223
|
const idx = this.nrrd_states.currentIndex;
|
|
@@ -75365,11 +75225,8 @@ class DrawToolCore extends CommToolsData {
|
|
|
75365
75225
|
const vol = this.getVolumeForLayer(activeLayer);
|
|
75366
75226
|
// Capture old slice for undo before clearing
|
|
75367
75227
|
const oldSlice = vol.getSliceUint8(idx, axis).data.slice();
|
|
75368
|
-
// Clear only the active layer
|
|
75369
|
-
|
|
75370
|
-
layer1.clearSlice(idx, axis);
|
|
75371
|
-
layer2.clearSlice(idx, axis);
|
|
75372
|
-
layer3.clearSlice(idx, axis);
|
|
75228
|
+
// Clear only the active layer's MaskVolume slice
|
|
75229
|
+
vol.clearSlice(idx, axis);
|
|
75373
75230
|
// New (all-zero) slice for undo newSlice
|
|
75374
75231
|
const { data: newSlice, width, height } = vol.getSliceUint8(idx, axis);
|
|
75375
75232
|
// Push clearPaint delta to UndoManager (supports undo)
|
|
@@ -75388,12 +75245,23 @@ class DrawToolCore extends CommToolsData {
|
|
|
75388
75245
|
}
|
|
75389
75246
|
}
|
|
75390
75247
|
catch (_a) {
|
|
75391
|
-
// Volume not ready (1×1×1 placeholder)
|
|
75248
|
+
// Volume not ready (1×1×1 placeholder)
|
|
75249
|
+
}
|
|
75250
|
+
// Re-render ALL layers from MaskVolume to canvas (rebuilds visuals from source of truth)
|
|
75251
|
+
this.resetLayerCanvas();
|
|
75252
|
+
const buffer = this.getOrCreateSliceBuffer(this.protectedData.axis);
|
|
75253
|
+
if (buffer) {
|
|
75254
|
+
const w = this.nrrd_states.changedWidth;
|
|
75255
|
+
const h = this.nrrd_states.changedHeight;
|
|
75256
|
+
for (const layerId of this.nrrd_states.layers) {
|
|
75257
|
+
const target = this.protectedData.layerTargets.get(layerId);
|
|
75258
|
+
if (!target)
|
|
75259
|
+
continue;
|
|
75260
|
+
target.ctx.clearRect(0, 0, w, h);
|
|
75261
|
+
this.renderSliceToCanvas(layerId, this.protectedData.axis, this.nrrd_states.currentIndex, buffer, target.ctx, w, h);
|
|
75262
|
+
}
|
|
75392
75263
|
}
|
|
75393
|
-
this.
|
|
75394
|
-
const restLayers = this.getRestLayer();
|
|
75395
|
-
this.storeEachLayerImage(this.nrrd_states.currentIndex, restLayers[0]);
|
|
75396
|
-
this.storeEachLayerImage(this.nrrd_states.currentIndex, restLayers[1]);
|
|
75264
|
+
this.compositeAllLayers();
|
|
75397
75265
|
this.setIsDrawFalse(1000);
|
|
75398
75266
|
}
|
|
75399
75267
|
/**
|
|
@@ -75474,14 +75342,11 @@ class DrawToolCore extends CommToolsData {
|
|
|
75474
75342
|
this.protectedData.ctxes.drawingLayerMasterCtx.getImageData(0, 0, this.protectedData.canvases.drawingCanvasLayerMaster.width, this.protectedData.canvases.drawingCanvasLayerMaster.height);
|
|
75475
75343
|
}
|
|
75476
75344
|
/****************************Store images (delegated to ImageStoreHelper)****************************************************/
|
|
75477
|
-
storeImageToAxis(index, paintedImages, imageData, axis) {
|
|
75478
|
-
this.imageStoreHelper.storeImageToAxis(index, paintedImages, imageData, axis);
|
|
75479
|
-
}
|
|
75480
75345
|
storeAllImages(index, layer) {
|
|
75481
75346
|
this.imageStoreHelper.storeAllImages(index, layer);
|
|
75482
75347
|
}
|
|
75483
|
-
storeImageToLayer(index, canvas
|
|
75484
|
-
return this.imageStoreHelper.storeImageToLayer(index, canvas
|
|
75348
|
+
storeImageToLayer(index, canvas) {
|
|
75349
|
+
return this.imageStoreHelper.storeImageToLayer(index, canvas);
|
|
75485
75350
|
}
|
|
75486
75351
|
storeEachLayerImage(index, layer) {
|
|
75487
75352
|
this.imageStoreHelper.storeEachLayerImage(index, layer);
|
|
@@ -76177,8 +76042,9 @@ class NrrdTools extends DrawToolCore {
|
|
|
76177
76042
|
* @param {string} aixs:"x" | "y" | "z"
|
|
76178
76043
|
* */
|
|
76179
76044
|
setSliceOrientation(axisTo) {
|
|
76045
|
+
var _a;
|
|
76180
76046
|
let convetObj;
|
|
76181
|
-
if (this.
|
|
76047
|
+
if (((_a = this.eventRouter) === null || _a === void 0 ? void 0 : _a.isCrosshairEnabled()) || this.gui_states.sphere) {
|
|
76182
76048
|
if (this.protectedData.axis === "z") {
|
|
76183
76049
|
this.cursorPage.z.index = this.nrrd_states.currentIndex;
|
|
76184
76050
|
this.cursorPage.z.cursorPageX = this.nrrd_states.cursorPageX;
|
|
@@ -76563,6 +76429,8 @@ class NrrdTools extends DrawToolCore {
|
|
|
76563
76429
|
}
|
|
76564
76430
|
// Invalidate reusable slice buffer
|
|
76565
76431
|
this.invalidateSliceBuffer();
|
|
76432
|
+
// Reload all layers to canvas (restores other layers' visuals)
|
|
76433
|
+
this.reloadMasksFromVolume();
|
|
76566
76434
|
}
|
|
76567
76435
|
/**
|
|
76568
76436
|
* Reset the draw and display canvases layout after mouse pan.
|
|
@@ -76773,7 +76641,8 @@ class NrrdTools extends DrawToolCore {
|
|
|
76773
76641
|
*/
|
|
76774
76642
|
configMouseSliceWheel() {
|
|
76775
76643
|
const handleMouseZoomSliceWheelMove = (e) => {
|
|
76776
|
-
|
|
76644
|
+
var _a;
|
|
76645
|
+
if ((_a = this.eventRouter) === null || _a === void 0 ? void 0 : _a.isShiftHeld()) {
|
|
76777
76646
|
return;
|
|
76778
76647
|
}
|
|
76779
76648
|
e.preventDefault();
|
|
@@ -77013,7 +76882,7 @@ function evaluateElement(element, weights) {
|
|
|
77013
76882
|
}
|
|
77014
76883
|
|
|
77015
76884
|
// import * as kiwrious from "copper3d_plugin_heart_k";
|
|
77016
|
-
const REVISION = "v3.0.
|
|
76885
|
+
const REVISION = "v3.0.1-beta";
|
|
77017
76886
|
console.log(`%cCopper3D Visualisation %cBeta:${REVISION}`, "padding: 3px;color:white; background:#023047", "padding: 3px;color:white; background:#f50a25");
|
|
77018
76887
|
|
|
77019
76888
|
export { CHANNEL_COLORS, CHANNEL_HEX_COLORS, CameraViewPoint, Copper3dTrackballControls, MeshNodeTool, NrrdTools, REVISION, addBoxHelper, addLabelToScene, configKiwriousHeart, convert3DPostoScreenPos, convertScreenPosto3DPos, copperMScene, copperMSceneRenderer, copperRenderer, copperRendererOnDemond, copperScene, copperSceneOnDemond, createTexture2D_NRRD, fullScreenListenner, kiwrious, loading, removeGuiFolderChilden, rgbaToCss, rgbaToHex, setHDRFilePath, throttle };
|