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.
Files changed (98) hide show
  1. package/README.md +195 -28
  2. package/dist/Utils/segmentation/CommToolsData.d.ts +24 -9
  3. package/dist/Utils/segmentation/CommToolsData.js +65 -139
  4. package/dist/Utils/segmentation/CommToolsData.js.map +1 -1
  5. package/dist/Utils/segmentation/DragOperator.d.ts +10 -2
  6. package/dist/Utils/segmentation/DragOperator.js +14 -4
  7. package/dist/Utils/segmentation/DragOperator.js.map +1 -1
  8. package/dist/Utils/segmentation/DrawToolCore.d.ts +23 -16
  9. package/dist/Utils/segmentation/DrawToolCore.js +218 -401
  10. package/dist/Utils/segmentation/DrawToolCore.js.map +1 -1
  11. package/dist/Utils/segmentation/NrrdTools.d.ts +152 -10
  12. package/dist/Utils/segmentation/NrrdTools.js +599 -202
  13. package/dist/Utils/segmentation/NrrdTools.js.map +1 -1
  14. package/dist/Utils/segmentation/core/MaskVolume.d.ts +1 -1
  15. package/dist/Utils/segmentation/core/MaskVolume.js +24 -3
  16. package/dist/Utils/segmentation/core/MaskVolume.js.map +1 -1
  17. package/dist/Utils/segmentation/core/UndoManager.d.ts +1 -1
  18. package/dist/Utils/segmentation/core/UndoManager.js +1 -1
  19. package/dist/Utils/segmentation/core/index.d.ts +0 -2
  20. package/dist/Utils/segmentation/core/index.js +0 -1
  21. package/dist/Utils/segmentation/core/index.js.map +1 -1
  22. package/dist/Utils/segmentation/core/types.js +24 -24
  23. package/dist/Utils/segmentation/core/types.js.map +1 -1
  24. package/dist/Utils/segmentation/coreTools/GuiState.d.ts +22 -0
  25. package/dist/Utils/segmentation/coreTools/GuiState.js +48 -0
  26. package/dist/Utils/segmentation/coreTools/GuiState.js.map +1 -0
  27. package/dist/Utils/segmentation/coreTools/NrrdState.d.ts +25 -0
  28. package/dist/Utils/segmentation/coreTools/NrrdState.js +85 -0
  29. package/dist/Utils/segmentation/coreTools/NrrdState.js.map +1 -0
  30. package/dist/Utils/segmentation/coreTools/coreType.d.ts +88 -62
  31. package/dist/Utils/segmentation/coreTools/coreType.js.map +1 -1
  32. package/dist/Utils/segmentation/coreTools/divControlTools.js +1 -1
  33. package/dist/Utils/segmentation/coreTools/divControlTools.js.map +1 -1
  34. package/dist/Utils/segmentation/coreTools/gui.d.ts +12 -12
  35. package/dist/Utils/segmentation/coreTools/gui.js +81 -107
  36. package/dist/Utils/segmentation/coreTools/gui.js.map +1 -1
  37. package/dist/Utils/segmentation/eventRouter/EventRouter.d.ts +2 -1
  38. package/dist/Utils/segmentation/eventRouter/EventRouter.js +15 -10
  39. package/dist/Utils/segmentation/eventRouter/EventRouter.js.map +1 -1
  40. package/dist/Utils/segmentation/eventRouter/types.d.ts +3 -3
  41. package/dist/Utils/segmentation/tools/BaseTool.d.ts +8 -5
  42. package/dist/Utils/segmentation/tools/BaseTool.js +1 -2
  43. package/dist/Utils/segmentation/tools/BaseTool.js.map +1 -1
  44. package/dist/Utils/segmentation/tools/CrosshairTool.js +25 -25
  45. package/dist/Utils/segmentation/tools/CrosshairTool.js.map +1 -1
  46. package/dist/Utils/segmentation/tools/DragSliceTool.d.ts +2 -0
  47. package/dist/Utils/segmentation/tools/DragSliceTool.js +63 -53
  48. package/dist/Utils/segmentation/tools/DragSliceTool.js.map +1 -1
  49. package/dist/Utils/segmentation/tools/DrawingTool.d.ts +93 -0
  50. package/dist/Utils/segmentation/tools/DrawingTool.js +222 -0
  51. package/dist/Utils/segmentation/tools/DrawingTool.js.map +1 -0
  52. package/dist/Utils/segmentation/tools/EraserTool.js +8 -8
  53. package/dist/Utils/segmentation/tools/EraserTool.js.map +1 -1
  54. package/dist/Utils/segmentation/tools/ImageStoreHelper.d.ts +11 -28
  55. package/dist/Utils/segmentation/tools/ImageStoreHelper.js +39 -82
  56. package/dist/Utils/segmentation/tools/ImageStoreHelper.js.map +1 -1
  57. package/dist/Utils/segmentation/tools/PanTool.d.ts +53 -0
  58. package/dist/Utils/segmentation/tools/PanTool.js +90 -0
  59. package/dist/Utils/segmentation/tools/PanTool.js.map +1 -0
  60. package/dist/Utils/segmentation/tools/SphereTool.d.ts +208 -1
  61. package/dist/Utils/segmentation/tools/SphereTool.js +456 -45
  62. package/dist/Utils/segmentation/tools/SphereTool.js.map +1 -1
  63. package/dist/Utils/segmentation/tools/ZoomTool.js +3 -3
  64. package/dist/Utils/segmentation/tools/ZoomTool.js.map +1 -1
  65. package/dist/Utils/segmentation/tools/index.d.ts +6 -2
  66. package/dist/Utils/segmentation/tools/index.js +4 -1
  67. package/dist/Utils/segmentation/tools/index.js.map +1 -1
  68. package/dist/bundle.esm.js +2452 -1492
  69. package/dist/bundle.umd.js +2452 -1492
  70. package/dist/index.d.ts +6 -3
  71. package/dist/index.js +1 -1
  72. package/dist/index.js.map +1 -1
  73. package/dist/types/Utils/segmentation/CommToolsData.d.ts +24 -9
  74. package/dist/types/Utils/segmentation/DragOperator.d.ts +10 -2
  75. package/dist/types/Utils/segmentation/DrawToolCore.d.ts +23 -16
  76. package/dist/types/Utils/segmentation/NrrdTools.d.ts +152 -10
  77. package/dist/types/Utils/segmentation/core/MaskVolume.d.ts +1 -1
  78. package/dist/types/Utils/segmentation/core/UndoManager.d.ts +1 -1
  79. package/dist/types/Utils/segmentation/core/index.d.ts +0 -2
  80. package/dist/types/Utils/segmentation/coreTools/GuiState.d.ts +22 -0
  81. package/dist/types/Utils/segmentation/coreTools/NrrdState.d.ts +25 -0
  82. package/dist/types/Utils/segmentation/coreTools/coreType.d.ts +88 -62
  83. package/dist/types/Utils/segmentation/coreTools/gui.d.ts +12 -12
  84. package/dist/types/Utils/segmentation/eventRouter/EventRouter.d.ts +2 -1
  85. package/dist/types/Utils/segmentation/eventRouter/types.d.ts +3 -3
  86. package/dist/types/Utils/segmentation/tools/BaseTool.d.ts +8 -5
  87. package/dist/types/Utils/segmentation/tools/DragSliceTool.d.ts +2 -0
  88. package/dist/types/Utils/segmentation/tools/DrawingTool.d.ts +93 -0
  89. package/dist/types/Utils/segmentation/tools/ImageStoreHelper.d.ts +11 -28
  90. package/dist/types/Utils/segmentation/tools/PanTool.d.ts +53 -0
  91. package/dist/types/Utils/segmentation/tools/SphereTool.d.ts +208 -1
  92. package/dist/types/Utils/segmentation/tools/index.d.ts +6 -2
  93. package/dist/types/index.d.ts +6 -3
  94. package/package.json +1 -1
  95. package/dist/Utils/segmentation/core/MigrationUtils.d.ts +0 -97
  96. package/dist/Utils/segmentation/core/MigrationUtils.js +0 -163
  97. package/dist/Utils/segmentation/core/MigrationUtils.js.map +0 -1
  98. package/dist/types/Utils/segmentation/core/MigrationUtils.d.ts +0 -97
@@ -0,0 +1,90 @@
1
+ /**
2
+ * PanTool - Right-click pan/drag navigation
3
+ *
4
+ * Extracted from DrawToolCore.paintOnCanvas() closure.
5
+ * Handles right-click drag to reposition the canvas view.
6
+ */
7
+ import { BaseTool } from "./BaseTool";
8
+ export class PanTool extends BaseTool {
9
+ constructor(ctx, callbacks) {
10
+ super(ctx);
11
+ /** Right mouse button currently held */
12
+ this.rightClicked = false;
13
+ /** Pan drag offset X (clientX − canvas.offsetLeft at drag start) */
14
+ this.panMoveInnerX = 0;
15
+ /** Pan drag offset Y (clientY − canvas.offsetTop at drag start) */
16
+ this.panMoveInnerY = 0;
17
+ /**
18
+ * Bound handler reference for pointermove so we can add/remove it.
19
+ * Arrow function preserves `this` binding.
20
+ */
21
+ this.boundPointerMove = (e) => {
22
+ this.handlePointerMove(e);
23
+ };
24
+ this.callbacks = callbacks;
25
+ }
26
+ /** Whether a pan drag is currently active */
27
+ get isActive() {
28
+ return this.rightClicked;
29
+ }
30
+ /**
31
+ * Called on right-click pointerdown.
32
+ * Captures initial offsets and registers pointermove listener.
33
+ */
34
+ onPointerDown(e) {
35
+ this.rightClicked = true;
36
+ const offsetX = this.ctx.protectedData.canvases.drawingCanvas.offsetLeft;
37
+ const offsetY = this.ctx.protectedData.canvases.drawingCanvas.offsetTop;
38
+ this.panMoveInnerX = e.clientX - offsetX;
39
+ this.panMoveInnerY = e.clientY - offsetY;
40
+ this.ctx.protectedData.canvases.drawingCanvas.style.cursor = "grab";
41
+ this.ctx.protectedData.canvases.drawingCanvas.addEventListener("pointermove", this.boundPointerMove);
42
+ }
43
+ /**
44
+ * Called on pointerup (button === 2).
45
+ * Cleans up listeners and restores cursor.
46
+ */
47
+ onPointerUp(e, defaultCursor) {
48
+ this.rightClicked = false;
49
+ this.ctx.protectedData.canvases.drawingCanvas.style.cursor = "grab";
50
+ setTimeout(() => {
51
+ this.ctx.protectedData.canvases.drawingCanvas.style.cursor = defaultCursor;
52
+ }, 2000);
53
+ this.ctx.protectedData.canvases.drawingCanvas.removeEventListener("pointermove", this.boundPointerMove);
54
+ if (this.ctx.gui_states.mode.sphere) {
55
+ this.callbacks.zoomActionAfterDrawSphere();
56
+ }
57
+ }
58
+ /**
59
+ * Called on pointerleave while pan is active.
60
+ * Resets state and removes listener.
61
+ */
62
+ onPointerLeave() {
63
+ if (!this.rightClicked)
64
+ return;
65
+ this.rightClicked = false;
66
+ this.ctx.protectedData.canvases.drawingCanvas.style.cursor = "grab";
67
+ this.ctx.protectedData.canvases.drawingCanvas.removeEventListener("pointermove", this.boundPointerMove);
68
+ }
69
+ /** Reset pan state (called when paintOnCanvas re-initializes) */
70
+ reset() {
71
+ this.rightClicked = false;
72
+ this.panMoveInnerX = 0;
73
+ this.panMoveInnerY = 0;
74
+ }
75
+ /**
76
+ * Pointermove handler — updates canvas position during drag.
77
+ */
78
+ handlePointerMove(e) {
79
+ this.ctx.protectedData.canvases.drawingCanvas.style.cursor = "grabbing";
80
+ this.ctx.nrrd_states.view.previousPanelL = e.clientX - this.panMoveInnerX;
81
+ this.ctx.nrrd_states.view.previousPanelT = e.clientY - this.panMoveInnerY;
82
+ this.ctx.protectedData.canvases.displayCanvas.style.left =
83
+ this.ctx.protectedData.canvases.drawingCanvas.style.left =
84
+ this.ctx.nrrd_states.view.previousPanelL + "px";
85
+ this.ctx.protectedData.canvases.displayCanvas.style.top =
86
+ this.ctx.protectedData.canvases.drawingCanvas.style.top =
87
+ this.ctx.nrrd_states.view.previousPanelT + "px";
88
+ }
89
+ }
90
+ //# sourceMappingURL=PanTool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PanTool.js","sourceRoot":"","sources":["../../../../src/Utils/segmentation/tools/PanTool.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,43 @@
1
1
  /**
2
2
  * SphereTool - Sphere drawing and calculator sphere operations
3
3
  *
4
+ * Provides 3D sphere placement across multiple slice views.
5
+ * Supports 4 sphere types: tumour, skin, nipple, ribcage.
6
+ * Each type maps to a specific layer and channel for future MaskVolume integration.
7
+ *
8
+ * ## Interaction Flow
9
+ * 1. Sphere mode activated (gui_states.sphere = true)
10
+ * - Draw mode (Shift key) is disabled
11
+ * - Crosshair toggle is disabled
12
+ * 2. Left-click down: record sphere center (mouseX, mouseY, sliceIndex)
13
+ * - Remove zoom/slice wheel event
14
+ * - Bind sphere wheel event
15
+ * - Draw preview circle on sphereCanvas
16
+ * 3. While holding left-click, scroll wheel adjusts sphereRadius [1, 50]
17
+ * 4. Left-click up:
18
+ * - Fire getSphere / getCalculateSpherePositions callbacks
19
+ * - (Plan B) Draw 3D sphere across x/y/z axes into sphereMaskVolume
20
+ * - Remove sphere wheel event
21
+ * - Restore zoom/slice wheel event
22
+ *
23
+ * ## Channel Mapping
24
+ * Each sphere type defaults to layer1 with a specific channel:
25
+ * - tumour → layer1, channel 1
26
+ * - ribcage → layer1, channel 3
27
+ * - skin → layer1, channel 4
28
+ * - nipple → layer1, channel 5
29
+ *
30
+ * ## SphereMaskVolume
31
+ * Sphere 3D data is stored in a dedicated MaskVolume (nrrd_states.sphereMaskVolume)
32
+ * separate from the layer draw mask volumes, to avoid polluting layer1's draw data.
33
+ * This volume is created in setAllSlices() and cleared in reset().
34
+ *
35
+ * ## Future: Writing to Layer MaskVolume
36
+ * Currently sphere data does NOT write to layer1's MaskVolume.
37
+ * The channel mapping and interfaces are reserved for future integration.
38
+ * When enabled, use SPHERE_CHANNEL_MAP to determine the target layer & channel,
39
+ * then call volume.setVoxel() or similar to persist sphere data.
40
+ *
4
41
  * Extracted from DrawToolCore.ts:
5
42
  * - drawSphere / drawSphereCore / clearSphereCanvas
6
43
  * - drawSphereOnEachViews / drawCalculatorSphereOnEachViews
@@ -10,27 +47,197 @@
10
47
  */
11
48
  import { BaseTool } from "./BaseTool";
12
49
  import type { ToolContext } from "./BaseTool";
50
+ /** The 4 supported sphere marker types. */
51
+ export type SphereType = 'tumour' | 'skin' | 'nipple' | 'ribcage';
52
+ /**
53
+ * Default layer and channel for each sphere type.
54
+ *
55
+ * This mapping is used to:
56
+ * 1. Determine the color for sphere preview rendering
57
+ * 2. (Future) Write sphere data into the corresponding layer's MaskVolume channel
58
+ *
59
+ * @example
60
+ * ```ts
61
+ * const { layer, channel } = SPHERE_CHANNEL_MAP['tumour'];
62
+ * // layer = 'layer1', channel = 1
63
+ * ```
64
+ */
65
+ export declare const SPHERE_CHANNEL_MAP: Record<SphereType, {
66
+ layer: string;
67
+ channel: number;
68
+ }>;
69
+ /**
70
+ * Label values for sphere types stored in sphereMaskVolume.
71
+ * Regular sphere mode uses SPHERE_LABEL (1).
72
+ * Calculator mode uses type-specific labels (1-4).
73
+ */
74
+ export declare const SPHERE_LABELS: Record<SphereType | 'default', number>;
13
75
  /**
14
76
  * Callbacks that DrawToolCore must provide for sphere operations.
77
+ * These are internal canvas manipulation callbacks, NOT external data callbacks.
78
+ *
79
+ * External data output uses:
80
+ * - annotationCallbacks.onSphereChanged(origin, radius) — sphere mode
81
+ * - annotationCallbacks.onCalculatorPositionsChanged(...) — calculator mode
15
82
  */
16
83
  export interface SphereCallbacks {
17
84
  setEmptyCanvasSize: (axis?: "x" | "y" | "z") => void;
18
85
  drawImageOnEmptyImage: (canvas: HTMLCanvasElement) => void;
19
- storeImageToAxis: (index: number, imageData: ImageData, axis?: "x" | "y" | "z") => void;
20
86
  }
21
87
  export declare class SphereTool extends BaseTool {
22
88
  private callbacks;
23
89
  constructor(ctx: ToolContext, callbacks: SphereCallbacks);
24
90
  setCallbacks(callbacks: SphereCallbacks): void;
91
+ /**
92
+ * Get the channel number for a sphere type.
93
+ *
94
+ * @param type - Sphere type ('tumour', 'skin', 'ribcage', 'nipple')
95
+ * @returns Channel number (1-8) mapped to this sphere type
96
+ *
97
+ * @example
98
+ * ```ts
99
+ * sphereTool.getChannelForSphereType('tumour'); // → 1
100
+ * sphereTool.getChannelForSphereType('skin'); // → 4
101
+ * ```
102
+ */
103
+ getChannelForSphereType(type: SphereType): number;
104
+ /**
105
+ * Get the default layer for a sphere type.
106
+ *
107
+ * @param type - Sphere type
108
+ * @returns Layer ID (e.g. 'layer1')
109
+ */
110
+ getLayerForSphereType(type: SphereType): string;
111
+ /**
112
+ * Get the preview color for a sphere type.
113
+ *
114
+ * If a volume is available for the target layer, uses the volume's
115
+ * custom color map (respects per-layer color customization).
116
+ * Otherwise falls back to SPHERE_COLORS (derived from CHANNEL_HEX_COLORS).
117
+ *
118
+ * @param type - Sphere type
119
+ * @returns CSS color string (hex)
120
+ */
121
+ getColorForSphereType(type: SphereType): string;
25
122
  setSphereCanvasSize(axis?: "x" | "y" | "z"): void;
123
+ /**
124
+ * Draw a filled circle on the given context.
125
+ *
126
+ * @param ctx - Canvas 2D context
127
+ * @param x - Center X coordinate
128
+ * @param y - Center Y coordinate
129
+ * @param radius - Circle radius in pixels
130
+ * @param color - Fill color (CSS string)
131
+ */
26
132
  drawSphereCore(ctx: CanvasRenderingContext2D, x: number, y: number, radius: number, color: string): void;
27
133
  clearSphereCanvas(): [HTMLCanvasElement, CanvasRenderingContext2D];
134
+ /**
135
+ * Draw a sphere preview circle on the sphere canvas using the current
136
+ * gui_states.fillColor. Called during sphere mode pointer-down.
137
+ *
138
+ * NOTE: Does NOT composite to master canvas — the start() render loop
139
+ * draws the sphere canvas directly to drawingCtx for proper layering.
140
+ */
28
141
  drawSphere(mouseX: number, mouseY: number, radius: number): void;
142
+ /**
143
+ * Returns a wheel event handler that adjusts sphere radius while the user
144
+ * holds left-click in sphere mode.
145
+ *
146
+ * Radius is clamped to [1, 50].
147
+ */
29
148
  configMouseSphereWheel(): (e: WheelEvent) => void;
149
+ /**
150
+ * Store sphere slice image into SphereMaskVolume.
151
+ *
152
+ * Currently a no-op — sphere slice data is rendered as overlay only.
153
+ *
154
+ * TODO: Future — write sphere circle data into nrrd_states.sphereMaskVolume
155
+ * at the specified slice index and axis. Use SPHERE_CHANNEL_MAP to determine
156
+ * the target channel when integrating with layer MaskVolume.
157
+ */
30
158
  private storeSphereImages;
159
+ /**
160
+ * Draw a sphere cross-section at a given decay distance from center,
161
+ * for a specific axis view.
162
+ *
163
+ * Called for each decay value [0..sphereRadius] for all 3 axes,
164
+ * creating the 3D sphere effect.
165
+ *
166
+ * The sphere circle radius at each slice = sphereRadius - decay (linear decay).
167
+ *
168
+ * @param decay - Distance from sphere center slice
169
+ * @param axis - Axis to render on ('x', 'y', 'z')
170
+ */
31
171
  drawSphereOnEachViews(decay: number, axis: "x" | "y" | "z"): void;
32
172
  private getSpherePosition;
173
+ /**
174
+ * Draw all 4 calculator sphere types on each view axis.
175
+ *
176
+ * Groups sphere positions by their slice index so that spheres on the
177
+ * same slice are drawn together before storing.
178
+ *
179
+ * Uses SPHERE_COLORS for each sphere type instead of nrrd_states.*Color.
180
+ */
33
181
  drawCalculatorSphereOnEachViews(axis: "x" | "y" | "z"): void;
182
+ /**
183
+ * Draw all placed calculator spheres on the current slice.
184
+ *
185
+ * Called every frame to show existing sphere markers on the current view.
186
+ * Uses SPHERE_COLORS for consistent type-based coloring.
187
+ *
188
+ * @param radius - Sphere radius to draw
189
+ */
34
190
  drawCalculatorSphere(radius: number): void;
191
+ /**
192
+ * Clear sphere overlay images.
193
+ *
194
+ * No-op in current implementation — sphere data is rendered as overlay
195
+ * and stored in the dedicated sphereMaskVolume (not in layer volumes).
196
+ */
35
197
  clearSpherePrintStoreImages(): void;
198
+ /**
199
+ * Convert canvas (mm-space) coordinates to 3D voxel coordinates.
200
+ *
201
+ * @param canvasX - X position in canvas mm-space
202
+ * @param canvasY - Y position in canvas mm-space
203
+ * @param sliceIndex - Slice index along the viewing axis
204
+ * @param axis - Viewing axis where the sphere was placed
205
+ * @returns 3D voxel coordinates { x, y, z }
206
+ */
207
+ canvasToVoxelCenter(canvasX: number, canvasY: number, sliceIndex: number, axis: "x" | "y" | "z"): {
208
+ x: number;
209
+ y: number;
210
+ z: number;
211
+ };
212
+ /**
213
+ * Write a 3D solid sphere to sphereMaskVolume.
214
+ *
215
+ * Converts the sphere center from canvas mm-space to voxel coordinates,
216
+ * then iterates over a bounding box and sets voxels within the sphere.
217
+ * The sphere is an ellipsoid in voxel space to appear circular in
218
+ * physical (mm) space on all axis views.
219
+ *
220
+ * @param label - Label value to write (1-4, default 1)
221
+ */
222
+ write3DSphereToVolume(label?: number): void;
223
+ /**
224
+ * Write a calculator sphere type to sphereMaskVolume.
225
+ * Uses the stored origin for the specified sphere type.
226
+ *
227
+ * @param type - Sphere type ('tumour', 'skin', 'nipple', 'ribcage')
228
+ */
229
+ writeCalculatorSphereToVolume(type: SphereType): void;
230
+ /**
231
+ * Write all placed calculator spheres to the volume.
232
+ * Clears the volume first, then writes each placed sphere type.
233
+ */
234
+ writeAllCalculatorSpheresToVolume(): void;
235
+ /**
236
+ * Render the current slice of sphereMaskVolume to drawingSphereCanvas.
237
+ *
238
+ * Called after any operation that changes the view (slice, axis, zoom)
239
+ * to keep the sphere overlay visible. Uses the same render pipeline as
240
+ * layer masks (emptyCanvas → sphere canvas at display scale).
241
+ */
242
+ refreshSphereCanvas(): void;
36
243
  }