copper3d 3.0.1 → 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 +24 -9
- package/dist/Utils/segmentation/CommToolsData.js +65 -139
- package/dist/Utils/segmentation/CommToolsData.js.map +1 -1
- package/dist/Utils/segmentation/DragOperator.d.ts +10 -2
- package/dist/Utils/segmentation/DragOperator.js +14 -4
- package/dist/Utils/segmentation/DragOperator.js.map +1 -1
- package/dist/Utils/segmentation/DrawToolCore.d.ts +23 -16
- package/dist/Utils/segmentation/DrawToolCore.js +218 -401
- package/dist/Utils/segmentation/DrawToolCore.js.map +1 -1
- package/dist/Utils/segmentation/NrrdTools.d.ts +152 -10
- package/dist/Utils/segmentation/NrrdTools.js +599 -202
- package/dist/Utils/segmentation/NrrdTools.js.map +1 -1
- package/dist/Utils/segmentation/core/MaskVolume.d.ts +1 -1
- package/dist/Utils/segmentation/core/MaskVolume.js +24 -3
- 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 -62
- 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 -12
- 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 -1
- package/dist/Utils/segmentation/eventRouter/EventRouter.js +15 -10
- 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 +8 -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 +11 -28
- package/dist/Utils/segmentation/tools/ImageStoreHelper.js +39 -82
- 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 -1
- 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 +3 -3
- 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 +2452 -1492
- package/dist/bundle.umd.js +2452 -1492
- 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 +24 -9
- package/dist/types/Utils/segmentation/DragOperator.d.ts +10 -2
- package/dist/types/Utils/segmentation/DrawToolCore.d.ts +23 -16
- package/dist/types/Utils/segmentation/NrrdTools.d.ts +152 -10
- package/dist/types/Utils/segmentation/core/MaskVolume.d.ts +1 -1
- 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 -62
- package/dist/types/Utils/segmentation/coreTools/gui.d.ts +12 -12
- package/dist/types/Utils/segmentation/eventRouter/EventRouter.d.ts +2 -1
- package/dist/types/Utils/segmentation/eventRouter/types.d.ts +3 -3
- package/dist/types/Utils/segmentation/tools/BaseTool.d.ts +8 -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 +11 -28
- package/dist/types/Utils/segmentation/tools/PanTool.d.ts +53 -0
- package/dist/types/Utils/segmentation/tools/SphereTool.d.ts +208 -1
- 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
package/README.md
CHANGED
|
@@ -128,7 +128,7 @@ const container = document.getElementById('viewer') as HTMLDivElement;
|
|
|
128
128
|
const nrrdTools = new Copper.NrrdTools(container);
|
|
129
129
|
|
|
130
130
|
// 2. After NRRD images are loaded via Copper scene:
|
|
131
|
-
nrrdTools.
|
|
131
|
+
nrrdTools.reset();
|
|
132
132
|
nrrdTools.setAllSlices(allSlices); // allSlices from Copper scene loader
|
|
133
133
|
|
|
134
134
|
// 3. Hook drawing callbacks
|
|
@@ -211,7 +211,7 @@ Must be called **after** Copper has loaded and decoded the NRRD files.
|
|
|
211
211
|
|
|
212
212
|
```typescript
|
|
213
213
|
// Reset state from previous case
|
|
214
|
-
nrrdTools.
|
|
214
|
+
nrrdTools.reset();
|
|
215
215
|
|
|
216
216
|
// allSlices is the array of decoded NRRD slice objects returned by Copper's loader
|
|
217
217
|
nrrdTools.setAllSlices(allSlices);
|
|
@@ -336,12 +336,29 @@ nrrdTools.draw({
|
|
|
336
336
|
notifyBackendLayerCleared(layerId);
|
|
337
337
|
},
|
|
338
338
|
|
|
339
|
-
// Called when the 3D sphere annotation tool places a sphere
|
|
339
|
+
// Called when the 3D sphere annotation tool places a sphere (sphere mode)
|
|
340
|
+
//
|
|
341
|
+
// sphereOrigin: [mouseX, mouseY, sliceIndex] — center on z-axis view
|
|
342
|
+
// sphereRadius: radius in pixels (1-50)
|
|
343
|
+
//
|
|
344
|
+
// Note: Sphere data does NOT write to layer MaskVolume.
|
|
345
|
+
// It is rendered as a visual overlay via the dedicated sphereMaskVolume.
|
|
340
346
|
getSphereData: (sphereOrigin: number[], sphereRadius: number) => {
|
|
341
347
|
console.log('Sphere placed at', sphereOrigin, 'radius', sphereRadius);
|
|
348
|
+
sendSphereToBackend({ sphereOrigin, sphereRadius });
|
|
342
349
|
},
|
|
343
350
|
|
|
344
|
-
// Called when the
|
|
351
|
+
// Called when the calculator sphere positions are updated (calculator mode)
|
|
352
|
+
//
|
|
353
|
+
// Each sphere type maps to a specific channel on layer1:
|
|
354
|
+
// tumour → channel 1
|
|
355
|
+
// ribcage → channel 3
|
|
356
|
+
// skin → channel 4
|
|
357
|
+
// nipple → channel 2
|
|
358
|
+
//
|
|
359
|
+
// Origins are ICommXYZ: { x: [mx, my, slice], y: [...], z: [...] }
|
|
360
|
+
// representing sphere center coordinates on all 3 axis views.
|
|
361
|
+
// null if that sphere type has not been placed yet.
|
|
345
362
|
getCalculateSpherePositionsData: (
|
|
346
363
|
tumourOrigin, skinOrigin, ribOrigin, nippleOrigin, axis
|
|
347
364
|
) => {
|
|
@@ -350,7 +367,116 @@ nrrdTools.draw({
|
|
|
350
367
|
});
|
|
351
368
|
```
|
|
352
369
|
|
|
353
|
-
#### 5.3
|
|
370
|
+
#### 5.3 SphereTool — 3D Sphere Placement & Distance Calculator
|
|
371
|
+
|
|
372
|
+
The SphereTool provides unified sphere placement with 4 sphere types controlled by `gui_states.mode.activeSphereType`. The active type determines which origin and color are used. The old separate "Calculator" mode has been merged into SphereTool.
|
|
373
|
+
|
|
374
|
+
##### Sphere Types & Channel Mapping
|
|
375
|
+
|
|
376
|
+
Each sphere type maps to a specific channel on layer1. Switch between types using `gui_states.mode.activeSphereType`:
|
|
377
|
+
|
|
378
|
+
| Sphere Type | Channel | Default Color | `activeSphereType` value |
|
|
379
|
+
|-------------|---------|---------------|---------------------|
|
|
380
|
+
| tumour | 1 | `#10b981` (Emerald) | `"tumour"` (default) |
|
|
381
|
+
| nipple | 2 | `#f43f5e` (Rose) | `"nipple"` |
|
|
382
|
+
| ribcage | 3 | `#3b82f6` (Blue) | `"ribcage"` |
|
|
383
|
+
| skin | 4 | `#fbbf24` (Amber) | `"skin"` |
|
|
384
|
+
|
|
385
|
+
These mappings are exported as `SPHERE_CHANNEL_MAP` and `SPHERE_LABELS` from `tools/SphereTool.ts`. (`SPHERE_COLORS` was removed — colors are now derived dynamically from each volume's `colorMap`.)
|
|
386
|
+
|
|
387
|
+
##### Switching Sphere Type
|
|
388
|
+
|
|
389
|
+
Use the public API — do NOT mutate `gui_states.mode.activeSphereType` directly, as `setActiveSphereType()` also updates brush/fill color as a side-effect:
|
|
390
|
+
|
|
391
|
+
```typescript
|
|
392
|
+
// Set active sphere type (also updates fillColor / brushColor)
|
|
393
|
+
nrrdTools.setActiveSphereType('nipple'); // channel 2, Rose #f43f5e
|
|
394
|
+
nrrdTools.setActiveSphereType('tumour'); // channel 1, Emerald #10b981
|
|
395
|
+
nrrdTools.setActiveSphereType('skin'); // channel 4, Amber #fbbf24
|
|
396
|
+
nrrdTools.setActiveSphereType('ribcage'); // channel 3, Blue #3b82f6
|
|
397
|
+
|
|
398
|
+
// Read current type
|
|
399
|
+
const type = nrrdTools.getActiveSphereType();
|
|
400
|
+
// → 'tumour' | 'skin' | 'nipple' | 'ribcage'
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
##### Interaction Flow
|
|
404
|
+
|
|
405
|
+
```
|
|
406
|
+
Sphere mode activated (gui_states.mode.sphere = true, keyboard shortcut: 'q'):
|
|
407
|
+
├─ Shift key DISABLED (no draw mode)
|
|
408
|
+
├─ Crosshair toggle allowed (S key)
|
|
409
|
+
│
|
|
410
|
+
├─ Left-click DOWN → record origin for current activeSphereType type,
|
|
411
|
+
│ show preview, bind sphere wheel
|
|
412
|
+
├─ Scroll wheel (while holding) → adjust radius [1, 50]
|
|
413
|
+
└─ Left-click UP → write all placed spheres to volume,
|
|
414
|
+
fire getSphere + getCalculateSpherePositions callbacks,
|
|
415
|
+
restore zoom/slice wheel
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
##### SphereMaskVolume
|
|
419
|
+
|
|
420
|
+
Sphere 3D data is stored in a dedicated `MaskVolume` (`nrrd_states.sphereMaskVolume`), separate from the layer draw mask volumes. This prevents sphere overlay data from polluting layer1's annotations.
|
|
421
|
+
|
|
422
|
+
- **Created** in `setAllSlices()` (same dimensions as CT volume)
|
|
423
|
+
- **Cleared** in `reset()` (when switching cases)
|
|
424
|
+
|
|
425
|
+
> **Note**: Currently sphere data does NOT write to layer1's MaskVolume. The channel mapping and `sphereMaskVolume` are reserved for future integration.
|
|
426
|
+
|
|
427
|
+
##### Scenario: Sphere mode with AI backend (distance calculation)
|
|
428
|
+
|
|
429
|
+
```typescript
|
|
430
|
+
nrrdTools.draw({
|
|
431
|
+
// Called on every sphere placement — receives all 4 sphere origins
|
|
432
|
+
getCalculateSpherePositionsData: (tumour, skin, rib, nipple, axis) => {
|
|
433
|
+
// Each origin is { x: [mx, my, slice], y: [...], z: [...] } or null
|
|
434
|
+
if (tumour && skin && rib && nipple) {
|
|
435
|
+
aiBackend.runSegmentation({ tumour, skin, rib, nipple, axis });
|
|
436
|
+
}
|
|
437
|
+
},
|
|
438
|
+
// Also called — receives the current sphere's origin and radius
|
|
439
|
+
getSphereData: (origin, radius) => {
|
|
440
|
+
console.log('Sphere placed at', origin, 'radius', radius);
|
|
441
|
+
},
|
|
442
|
+
});
|
|
443
|
+
```
|
|
444
|
+
|
|
445
|
+
##### Programmatic Sphere Placement (Backend → Frontend)
|
|
446
|
+
|
|
447
|
+
When the backend returns sphere coordinates (e.g., from AI detection), use `setCalculateDistanceSphere()` to place them without user interaction. This method replicates the full mouse-down → mouse-up flow internally:
|
|
448
|
+
|
|
449
|
+
```typescript
|
|
450
|
+
// Backend returns sphere data for a case
|
|
451
|
+
interface BackendSphereData {
|
|
452
|
+
type: 'tumour' | 'skin' | 'nipple' | 'ribcage';
|
|
453
|
+
x: number; // X in unscaled image space
|
|
454
|
+
y: number; // Y in unscaled image space
|
|
455
|
+
sliceIndex: number; // Target slice index
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
// Place each sphere programmatically
|
|
459
|
+
function applySphereFromBackend(nrrdTools: Copper.NrrdTools, spheres: BackendSphereData[]) {
|
|
460
|
+
for (const s of spheres) {
|
|
461
|
+
nrrdTools.setCalculateDistanceSphere(s.x, s.y, s.sliceIndex, s.type);
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
// Example: place a tumour sphere at (120, 95) on slice 42
|
|
466
|
+
nrrdTools.setCalculateDistanceSphere(120, 95, 42, 'tumour');
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
Internally, `setCalculateDistanceSphere` performs:
|
|
470
|
+
1. Sets `sphereRadius = 5` and navigates to the target slice
|
|
471
|
+
2. Records `sphereOrigin` on all 3 axes (via `crosshairTool.setUpSphereOrigins`)
|
|
472
|
+
3. Deep-copies the origin into the type-specific field (e.g., `tumourSphereOrigin`)
|
|
473
|
+
4. Draws the sphere preview on canvas (`drawCalculatorSphere`)
|
|
474
|
+
5. Writes all placed spheres to `sphereMaskVolume` (`writeAllCalculatorSpheresToVolume`)
|
|
475
|
+
6. Re-renders the sphere overlay (`refreshSphereCanvas`)
|
|
476
|
+
|
|
477
|
+
> **Note**: Coordinates (`x`, `y`) are in **unscaled** image space. The method automatically applies `sizeFactor` scaling internally.
|
|
478
|
+
|
|
479
|
+
#### 5.4 `enableContrastDragEvents()` — Windowing
|
|
354
480
|
|
|
355
481
|
Enable Ctrl+drag to adjust window/level (brightness/contrast):
|
|
356
482
|
|
|
@@ -466,14 +592,14 @@ Each layer has its own independent color map. Changing channel 3's color in `lay
|
|
|
466
592
|
|
|
467
593
|
| Channel | Color | Hex |
|
|
468
594
|
|---------|-------|-----|
|
|
469
|
-
| 1 |
|
|
470
|
-
| 2 |
|
|
471
|
-
| 3 | Blue (Necrosis) | `#
|
|
472
|
-
| 4 |
|
|
473
|
-
| 5 |
|
|
474
|
-
| 6 | Cyan (Additional) | `#
|
|
475
|
-
| 7 | Orange (Auxiliary) | `#
|
|
476
|
-
| 8 |
|
|
595
|
+
| 1 | Emerald (Tumour) | `#10b981` |
|
|
596
|
+
| 2 | Rose (Edema) | `#f43f5e` |
|
|
597
|
+
| 3 | Blue (Necrosis) | `#3b82f6` |
|
|
598
|
+
| 4 | Amber (Enhancement) | `#fbbf24` |
|
|
599
|
+
| 5 | Fuchsia (Vessel) | `#d946ef` |
|
|
600
|
+
| 6 | Cyan (Additional) | `#06b6d4` |
|
|
601
|
+
| 7 | Orange (Auxiliary) | `#f97316` |
|
|
602
|
+
| 8 | Violet (Extended) | `#8b5cf6` |
|
|
477
603
|
|
|
478
604
|
#### 7.1 Set a single channel color
|
|
479
605
|
|
|
@@ -606,6 +732,7 @@ window.addEventListener('keydown', (e) => {
|
|
|
606
732
|
| Redo | `y` |
|
|
607
733
|
| Contrast adjust | `Ctrl` / `Meta` (hold) |
|
|
608
734
|
| Crosshair | `s` |
|
|
735
|
+
| Sphere mode | `q` |
|
|
609
736
|
| Mouse wheel | Zoom |
|
|
610
737
|
|
|
611
738
|
#### Reading current settings
|
|
@@ -691,7 +818,7 @@ const maxSlices = nrrdTools.getMaxSliceNum();
|
|
|
691
818
|
// → [512, 512, 256] (one per axis)
|
|
692
819
|
|
|
693
820
|
// Current viewing state
|
|
694
|
-
const {
|
|
821
|
+
const { currentSliceIndex, contrastIndex } = nrrdTools.getCurrentSlicesNumAndContrastNum();
|
|
695
822
|
```
|
|
696
823
|
|
|
697
824
|
#### Accessing internal canvases
|
|
@@ -700,13 +827,13 @@ const { currentIndex, contrastIndex } = nrrdTools.getCurrentSlicesNumAndContrast
|
|
|
700
827
|
// The topmost interactive canvas (mouse/pen events target here)
|
|
701
828
|
const drawingCanvas = nrrdTools.getDrawingCanvas();
|
|
702
829
|
|
|
703
|
-
// The container
|
|
830
|
+
// The inner main-area container div (dynamically created by NrrdTools, NOT the original container passed to constructor)
|
|
704
831
|
const container = nrrdTools.getContainer();
|
|
705
832
|
|
|
706
|
-
// Raw
|
|
833
|
+
// Raw NrrdState (all internal state fields, grouped by semantic sub-objects)
|
|
707
834
|
const states = nrrdTools.getNrrdToolsSettings();
|
|
708
|
-
console.log(states.layers); // ["layer1", "layer2", ...]
|
|
709
|
-
console.log(states.dimensions); // [512, 512, 256]
|
|
835
|
+
console.log(states.image.layers); // ["layer1", "layer2", ...]
|
|
836
|
+
console.log(states.image.dimensions); // [512, 512, 256]
|
|
710
837
|
```
|
|
711
838
|
|
|
712
839
|
#### Accessing full mask data
|
|
@@ -737,7 +864,7 @@ const channelVis = nrrdTools.getChannelVisibility();
|
|
|
737
864
|
const hasTumour = nrrdTools.hasLayerData('layer1');
|
|
738
865
|
|
|
739
866
|
// Get current channel color as hex
|
|
740
|
-
const hex = nrrdTools.getChannelHexColor('layer1', 1); // → "#
|
|
867
|
+
const hex = nrrdTools.getChannelHexColor('layer1', 1); // → "#10b981"
|
|
741
868
|
|
|
742
869
|
// Keyboard settings
|
|
743
870
|
const keys = nrrdTools.getKeyboardSettings();
|
|
@@ -765,7 +892,7 @@ async function initAnnotationTool(container: HTMLDivElement, allSlices: any[]) {
|
|
|
765
892
|
});
|
|
766
893
|
|
|
767
894
|
// Load image volume
|
|
768
|
-
nrrdTools.
|
|
895
|
+
nrrdTools.reset();
|
|
769
896
|
nrrdTools.setAllSlices(allSlices);
|
|
770
897
|
|
|
771
898
|
// Register callbacks
|
|
@@ -820,7 +947,7 @@ async function loadAndColorCase(nrrdTools: Copper.NrrdTools, caseId: string) {
|
|
|
820
947
|
```typescript
|
|
821
948
|
async function switchCase(nrrdTools: Copper.NrrdTools, newCaseData: ICaseData) {
|
|
822
949
|
// Reset annotation volumes
|
|
823
|
-
nrrdTools.
|
|
950
|
+
nrrdTools.reset();
|
|
824
951
|
|
|
825
952
|
// Load new image slices (from Copper's scene loader result)
|
|
826
953
|
nrrdTools.setAllSlices(newCaseData.slices);
|
|
@@ -927,12 +1054,32 @@ function buildColorLegend(nrrdTools: Copper.NrrdTools, layerId: string) {
|
|
|
927
1054
|
}
|
|
928
1055
|
|
|
929
1056
|
// → [
|
|
930
|
-
// { channel: 1, cssColor: 'rgba(
|
|
931
|
-
// { channel: 2, cssColor: 'rgba(
|
|
1057
|
+
// { channel: 1, cssColor: 'rgba(16,185,129,1.00)', hexColor: '#10b981', rgba: { r:16, g:185, b:129, a:255 } },
|
|
1058
|
+
// { channel: 2, cssColor: 'rgba(244,63,94,1.00)', hexColor: '#f43f5e', rgba: { r:244, g:63, b:94, a:255 } },
|
|
932
1059
|
// ...
|
|
933
1060
|
// ]
|
|
934
1061
|
```
|
|
935
1062
|
|
|
1063
|
+
#### Scenario H: Clearing annotations
|
|
1064
|
+
|
|
1065
|
+
There are different levels of clearing data depending on the use case:
|
|
1066
|
+
|
|
1067
|
+
```typescript
|
|
1068
|
+
// 1. Clear ALL data across ALL layers comprehensively (typically used when switching cases)
|
|
1069
|
+
// This clears all volumes, undo histories, UI canvases, index parameters, and sphere data globally.
|
|
1070
|
+
nrrdTools.reset();
|
|
1071
|
+
|
|
1072
|
+
// 2. Clear all annotations on the currently active layer across its entire 3D volume
|
|
1073
|
+
// This clears the active layer's MaskVolume, clears its undo/redo history, and re-renders the canvas.
|
|
1074
|
+
// It also triggers the `onClearLayerVolume` callback so you can notify the backend.
|
|
1075
|
+
nrrdTools.clearActiveLayer();
|
|
1076
|
+
|
|
1077
|
+
// 3. Clear the mask ONLY on the currently viewed 2D slice for the active layer
|
|
1078
|
+
// This removes annotations specifically on the current slice index and orientation.
|
|
1079
|
+
// It records an undo operation to allow rollback.
|
|
1080
|
+
nrrdTools.clearActiveSlice();
|
|
1081
|
+
```
|
|
1082
|
+
|
|
936
1083
|
---
|
|
937
1084
|
|
|
938
1085
|
### 13. Vue 3 Integration Pattern
|
|
@@ -956,7 +1103,7 @@ onMounted(() => {
|
|
|
956
1103
|
|
|
957
1104
|
// After all NRRD files are loaded by the Copper scene:
|
|
958
1105
|
function onAllImagesLoaded(allSlices: any[]) {
|
|
959
|
-
nrrdTools!.
|
|
1106
|
+
nrrdTools!.reset();
|
|
960
1107
|
nrrdTools!.setAllSlices(allSlices);
|
|
961
1108
|
|
|
962
1109
|
nrrdTools!.drag({ getSliceNum: (idx) => emit('sliceChanged', idx) });
|
|
@@ -1066,8 +1213,9 @@ interface IKeyBoardSettings {
|
|
|
1066
1213
|
draw: string;
|
|
1067
1214
|
undo: string;
|
|
1068
1215
|
redo: string;
|
|
1069
|
-
contrast: string
|
|
1216
|
+
contrast: string[]; // always an array, e.g. ["Control", "Meta"]
|
|
1070
1217
|
crosshair: string;
|
|
1218
|
+
sphere: string;
|
|
1071
1219
|
mouseWheel: 'Scroll:Zoom' | 'Scroll:Slice';
|
|
1072
1220
|
}
|
|
1073
1221
|
|
|
@@ -1099,7 +1247,9 @@ type ChannelValue = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8;
|
|
|
1099
1247
|
| | `enableContrastDragEvents(cb)` | Enable Ctrl+drag windowing |
|
|
1100
1248
|
| | `setDisplaySliceIndexPanel(el)` | Show slice index in a panel |
|
|
1101
1249
|
| | `setBaseDrawDisplayCanvasesSize(n)` | Set canvas resolution multiplier (1-8) |
|
|
1102
|
-
| **Data** | `
|
|
1250
|
+
| **Data** | `reset()` | Reset all volumes, undo histories, canvases, and sphere data |
|
|
1251
|
+
| | `clearActiveLayer()` | Clear annotations and undo history for the *currently active layer* |
|
|
1252
|
+
| | `clearActiveSlice()` | Clear annotations exclusively on the *currently viewed slice* of the active layer |
|
|
1103
1253
|
| | `setAllSlices(slices)` | Load NRRD slices, init MaskVolumes |
|
|
1104
1254
|
| | `setMasksFromNIfTI(map)` | Load saved NIfTI voxel data |
|
|
1105
1255
|
| **Render** | `start` | Frame callback — pass to render loop |
|
|
@@ -1109,6 +1259,8 @@ type ChannelValue = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8;
|
|
|
1109
1259
|
| | `isLayerVisible(id)` | Query layer visibility |
|
|
1110
1260
|
| | `getLayerVisibility()` | All layer visibility map |
|
|
1111
1261
|
| | `hasLayerData(id)` | Check if layer has non-zero voxels |
|
|
1262
|
+
| **Sphere** | `setActiveSphereType(type)` | Set active sphere type (`'tumour'`/`'skin'`/`'nipple'`/`'ribcage'`), updates brush color |
|
|
1263
|
+
| | `getActiveSphereType()` | Read current sphere type |
|
|
1112
1264
|
| **Channel** | `setActiveChannel(ch)` | Switch drawing target channel |
|
|
1113
1265
|
| | `getActiveChannel()` | Read current channel |
|
|
1114
1266
|
| | `setChannelVisible(id, ch, bool)` | Toggle channel visibility in a layer |
|
|
@@ -1121,6 +1273,22 @@ type ChannelValue = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8;
|
|
|
1121
1273
|
| | `getChannelHexColor(id, ch)` | Read Hex string |
|
|
1122
1274
|
| | `getChannelCssColor(id, ch)` | Read CSS rgba() string |
|
|
1123
1275
|
| | `resetChannelColors(id?, ch?)` | Reset to defaults |
|
|
1276
|
+
| **Tool Mode** | `setMode(mode)` | Switch tool mode: `"pencil"` / `"brush"` / `"eraser"` / `"sphere"` / `"calculator"` |
|
|
1277
|
+
| | `getMode()` | Read current tool mode |
|
|
1278
|
+
| | `isCalculatorActive()` | Check if calculator (distance) mode is active |
|
|
1279
|
+
| **Drawing** | `setOpacity(value)` | Set mask overlay opacity [0.1, 1] |
|
|
1280
|
+
| | `getOpacity()` | Read current opacity |
|
|
1281
|
+
| | `setBrushSize(size)` | Set brush/eraser size [5, 50], updates cursor |
|
|
1282
|
+
| | `getBrushSize()` | Read current brush size |
|
|
1283
|
+
| | `setPencilColor(hex)` | Set pencil stroke color (hex string) |
|
|
1284
|
+
| | `getPencilColor()` | Read current pencil color |
|
|
1285
|
+
| **Contrast** | `setWindowHigh(value)` | Set window high (image contrast), call `finishWindowAdjustment()` after drag |
|
|
1286
|
+
| | `setWindowLow(value)` | Set window low (image center) |
|
|
1287
|
+
| | `finishWindowAdjustment()` | Repaint all contrast slices after drag ends |
|
|
1288
|
+
| | `getSliderMeta(key)` | Get slider min/max/step/value for UI config (`"globalAlpha"`, `"brushAndEraserSize"`, etc.) |
|
|
1289
|
+
| **Actions** | `executeAction(action)` | Run named action: `"undo"`, `"redo"`, `"clearActiveSliceMask"`, `"clearActiveLayerMask"`, `"resetZoom"`, `"downloadCurrentMask"` |
|
|
1290
|
+
| **Navigation** | `setSliceOrientation(axis)` | Switch viewing axis `"x"` / `"y"` / `"z"` |
|
|
1291
|
+
| | `setCalculateDistanceSphere(x, y, slice, type)` | Programmatically place a calculator sphere (simulates full click flow: record origin → draw → write to volume) |
|
|
1124
1292
|
| **History** | `undo()` | Undo last stroke |
|
|
1125
1293
|
| | `redo()` | Redo last undone stroke |
|
|
1126
1294
|
| **Keyboard** | `setKeyboardSettings(partial)` | Remap shortcuts |
|
|
@@ -1135,11 +1303,10 @@ type ChannelValue = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8;
|
|
|
1135
1303
|
| | `getMaxSliceNum()` | Max slice index per axis |
|
|
1136
1304
|
| | `getCurrentSlicesNumAndContrastNum()` | Current slice & contrast index |
|
|
1137
1305
|
| | `getMaskData()` | Raw `IMaskData` object |
|
|
1138
|
-
| | `getNrrdToolsSettings()` | Full `
|
|
1306
|
+
| | `getNrrdToolsSettings()` | Full `NrrdState` snapshot (grouped sub-objects: image, view, interaction, sphere, flags) |
|
|
1139
1307
|
| | `getContainer()` | Host `HTMLElement` |
|
|
1140
1308
|
| | `getDrawingCanvas()` | Top-layer `HTMLCanvasElement` |
|
|
1141
1309
|
|
|
1142
|
-
---
|
|
1143
1310
|
|
|
1144
1311
|
## Acknowledgements
|
|
1145
1312
|
|
|
@@ -1,18 +1,22 @@
|
|
|
1
|
-
import { IProtected,
|
|
1
|
+
import { IProtected, ICursorPage, IConvertObjType, INewMaskData, IKeyBoardSettings, IAnnotationCallbacks } from "./coreTools/coreType";
|
|
2
|
+
import { NrrdState } from "./coreTools/NrrdState";
|
|
3
|
+
import { GuiState } from "./coreTools/GuiState";
|
|
2
4
|
import { MaskVolume } from "./core/index";
|
|
3
5
|
export declare class CommToolsData {
|
|
4
6
|
baseCanvasesSize: number;
|
|
5
7
|
private _reusableSliceBuffer;
|
|
6
8
|
private _reusableBufferWidth;
|
|
7
9
|
private _reusableBufferHeight;
|
|
10
|
+
/** External annotation callbacks — set via draw() options */
|
|
11
|
+
protected annotationCallbacks: IAnnotationCallbacks;
|
|
8
12
|
/** Whether the keyboard-config dialog is open (suppresses all shortcuts). */
|
|
9
13
|
protected _configKeyBoard: boolean;
|
|
10
14
|
/** Active keyboard shortcut bindings. */
|
|
11
15
|
protected _keyboardSettings: IKeyBoardSettings;
|
|
12
|
-
nrrd_states:
|
|
13
|
-
cursorPage: ICursorPage;
|
|
14
|
-
gui_states:
|
|
15
|
-
protectedData: IProtected;
|
|
16
|
+
protected nrrd_states: NrrdState;
|
|
17
|
+
protected cursorPage: ICursorPage;
|
|
18
|
+
protected gui_states: GuiState;
|
|
19
|
+
protected protectedData: IProtected;
|
|
16
20
|
constructor(container: HTMLElement, mainAreaContainer: HTMLElement, options?: {
|
|
17
21
|
layers?: string[];
|
|
18
22
|
});
|
|
@@ -56,9 +60,9 @@ export declare class CommToolsData {
|
|
|
56
60
|
private generateSystemCanvases;
|
|
57
61
|
private generateLayerTargets;
|
|
58
62
|
/**
|
|
59
|
-
* Rewrite this {
|
|
63
|
+
* Rewrite this {clearActiveSlice} function under DrawToolCore
|
|
60
64
|
*/
|
|
61
|
-
|
|
65
|
+
clearActiveSlice(): void;
|
|
62
66
|
/**
|
|
63
67
|
* Rewrite this {undoLastPainting} function under DrawToolCore
|
|
64
68
|
*/
|
|
@@ -68,9 +72,9 @@ export declare class CommToolsData {
|
|
|
68
72
|
*/
|
|
69
73
|
redoLastPainting(): void;
|
|
70
74
|
/**
|
|
71
|
-
* Rewrite this {
|
|
75
|
+
* Rewrite this {clearActiveLayer} function under NrrdTools
|
|
72
76
|
*/
|
|
73
|
-
|
|
77
|
+
clearActiveLayer(): void;
|
|
74
78
|
/**
|
|
75
79
|
* Rewrite this {resizePaintArea} function under NrrdTools
|
|
76
80
|
*/
|
|
@@ -103,6 +107,17 @@ export declare class CommToolsData {
|
|
|
103
107
|
* Rewrite this {resetLayerCanvas} function under NrrdTools
|
|
104
108
|
*/
|
|
105
109
|
resetLayerCanvas(): void;
|
|
110
|
+
/**
|
|
111
|
+
* Enter sphere mode: clear all layer canvases (not MaskVolume),
|
|
112
|
+
* hide all mask data so sphere overlay is the only visible annotation.
|
|
113
|
+
* Rewrite this under NrrdTools.
|
|
114
|
+
*/
|
|
115
|
+
enterSphereMode(): void;
|
|
116
|
+
/**
|
|
117
|
+
* Exit sphere mode: clear sphere canvas overlay, reload all layer
|
|
118
|
+
* MaskVolume data back onto canvases. Rewrite this under NrrdTools.
|
|
119
|
+
*/
|
|
120
|
+
exitSphereMode(): void;
|
|
106
121
|
/**
|
|
107
122
|
* Rewrite this {setSyncsliceNum} function under NrrdTools
|
|
108
123
|
*/
|