copper3d 3.0.2 → 3.1.0

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 (104) hide show
  1. package/README.md +183 -1028
  2. package/dist/Utils/segmentation/CanvasState.d.ts +31 -0
  3. package/dist/Utils/segmentation/CanvasState.js +167 -0
  4. package/dist/Utils/segmentation/CanvasState.js.map +1 -0
  5. package/dist/Utils/segmentation/DragOperator.d.ts +1 -1
  6. package/dist/Utils/segmentation/DragOperator.js +2 -4
  7. package/dist/Utils/segmentation/DragOperator.js.map +1 -1
  8. package/dist/Utils/segmentation/DrawToolCore.d.ts +49 -27
  9. package/dist/Utils/segmentation/DrawToolCore.js +275 -344
  10. package/dist/Utils/segmentation/DrawToolCore.js.map +1 -1
  11. package/dist/Utils/segmentation/NrrdTools.d.ts +89 -467
  12. package/dist/Utils/segmentation/NrrdTools.js +479 -1335
  13. package/dist/Utils/segmentation/NrrdTools.js.map +1 -1
  14. package/dist/Utils/segmentation/RenderingUtils.d.ts +73 -0
  15. package/dist/Utils/segmentation/RenderingUtils.js +180 -0
  16. package/dist/Utils/segmentation/RenderingUtils.js.map +1 -0
  17. package/dist/Utils/segmentation/core/MaskVolume.d.ts +1 -1
  18. package/dist/Utils/segmentation/core/MaskVolume.js +1 -1
  19. package/dist/Utils/segmentation/core/index.d.ts +1 -1
  20. package/dist/Utils/segmentation/core/index.js.map +1 -1
  21. package/dist/Utils/segmentation/core/types.d.ts +384 -0
  22. package/dist/Utils/segmentation/core/types.js +1 -0
  23. package/dist/Utils/segmentation/core/types.js.map +1 -1
  24. package/dist/Utils/segmentation/coreTools/GuiState.d.ts +1 -1
  25. package/dist/Utils/segmentation/coreTools/NrrdState.d.ts +1 -1
  26. package/dist/Utils/segmentation/coreTools/divControlTools.d.ts +1 -1
  27. package/dist/Utils/segmentation/coreTools/gui.d.ts +1 -1
  28. package/dist/Utils/segmentation/tools/BaseTool.d.ts +1 -1
  29. package/dist/Utils/segmentation/tools/ContrastTool.d.ts +3 -6
  30. package/dist/Utils/segmentation/tools/ContrastTool.js.map +1 -1
  31. package/dist/Utils/segmentation/tools/CrosshairTool.d.ts +11 -1
  32. package/dist/Utils/segmentation/tools/CrosshairTool.js +25 -0
  33. package/dist/Utils/segmentation/tools/CrosshairTool.js.map +1 -1
  34. package/dist/Utils/segmentation/tools/DataLoader.d.ts +33 -0
  35. package/dist/Utils/segmentation/tools/DataLoader.js +159 -0
  36. package/dist/Utils/segmentation/tools/DataLoader.js.map +1 -0
  37. package/dist/Utils/segmentation/tools/DragSliceTool.d.ts +3 -12
  38. package/dist/Utils/segmentation/tools/DragSliceTool.js.map +1 -1
  39. package/dist/Utils/segmentation/tools/DrawingTool.d.ts +18 -26
  40. package/dist/Utils/segmentation/tools/DrawingTool.js +48 -0
  41. package/dist/Utils/segmentation/tools/DrawingTool.js.map +1 -1
  42. package/dist/Utils/segmentation/tools/ImageStoreHelper.d.ts +2 -5
  43. package/dist/Utils/segmentation/tools/ImageStoreHelper.js.map +1 -1
  44. package/dist/Utils/segmentation/tools/LayerChannelManager.d.ts +52 -0
  45. package/dist/Utils/segmentation/tools/LayerChannelManager.js +175 -0
  46. package/dist/Utils/segmentation/tools/LayerChannelManager.js.map +1 -0
  47. package/dist/Utils/segmentation/tools/PanTool.d.ts +2 -8
  48. package/dist/Utils/segmentation/tools/PanTool.js.map +1 -1
  49. package/dist/Utils/segmentation/tools/SliceRenderPipeline.d.ts +80 -0
  50. package/dist/Utils/segmentation/tools/SliceRenderPipeline.js +355 -0
  51. package/dist/Utils/segmentation/tools/SliceRenderPipeline.js.map +1 -0
  52. package/dist/Utils/segmentation/tools/SphereTool.d.ts +25 -19
  53. package/dist/Utils/segmentation/tools/SphereTool.js +61 -7
  54. package/dist/Utils/segmentation/tools/SphereTool.js.map +1 -1
  55. package/dist/Utils/segmentation/tools/ToolHost.d.ts +74 -0
  56. package/dist/Utils/segmentation/tools/ToolHost.js +10 -0
  57. package/dist/Utils/segmentation/tools/ToolHost.js.map +1 -0
  58. package/dist/Utils/segmentation/tools/ZoomTool.d.ts +2 -6
  59. package/dist/Utils/segmentation/tools/ZoomTool.js.map +1 -1
  60. package/dist/Utils/segmentation/tools/index.d.ts +5 -7
  61. package/dist/Utils/segmentation/tools/index.js +6 -0
  62. package/dist/Utils/segmentation/tools/index.js.map +1 -1
  63. package/dist/Utils/workers/reformatSaveDataWorker.d.ts +1 -1
  64. package/dist/bundle.esm.js +2109 -2357
  65. package/dist/bundle.umd.js +2109 -2357
  66. package/dist/index.d.ts +3 -3
  67. package/dist/index.js +1 -1
  68. package/dist/types/Utils/segmentation/CanvasState.d.ts +31 -0
  69. package/dist/types/Utils/segmentation/DragOperator.d.ts +1 -1
  70. package/dist/types/Utils/segmentation/DrawToolCore.d.ts +49 -27
  71. package/dist/types/Utils/segmentation/NrrdTools.d.ts +89 -467
  72. package/dist/types/Utils/segmentation/RenderingUtils.d.ts +73 -0
  73. package/dist/types/Utils/segmentation/core/MaskVolume.d.ts +1 -1
  74. package/dist/types/Utils/segmentation/core/index.d.ts +1 -1
  75. package/dist/types/Utils/segmentation/core/types.d.ts +384 -0
  76. package/dist/types/Utils/segmentation/coreTools/GuiState.d.ts +1 -1
  77. package/dist/types/Utils/segmentation/coreTools/NrrdState.d.ts +1 -1
  78. package/dist/types/Utils/segmentation/coreTools/divControlTools.d.ts +1 -1
  79. package/dist/types/Utils/segmentation/coreTools/gui.d.ts +1 -1
  80. package/dist/types/Utils/segmentation/tools/BaseTool.d.ts +1 -1
  81. package/dist/types/Utils/segmentation/tools/ContrastTool.d.ts +3 -6
  82. package/dist/types/Utils/segmentation/tools/CrosshairTool.d.ts +11 -1
  83. package/dist/types/Utils/segmentation/tools/DataLoader.d.ts +33 -0
  84. package/dist/types/Utils/segmentation/tools/DragSliceTool.d.ts +3 -12
  85. package/dist/types/Utils/segmentation/tools/DrawingTool.d.ts +18 -26
  86. package/dist/types/Utils/segmentation/tools/ImageStoreHelper.d.ts +2 -5
  87. package/dist/types/Utils/segmentation/tools/LayerChannelManager.d.ts +52 -0
  88. package/dist/types/Utils/segmentation/tools/PanTool.d.ts +2 -8
  89. package/dist/types/Utils/segmentation/tools/SliceRenderPipeline.d.ts +80 -0
  90. package/dist/types/Utils/segmentation/tools/SphereTool.d.ts +25 -19
  91. package/dist/types/Utils/segmentation/tools/ToolHost.d.ts +74 -0
  92. package/dist/types/Utils/segmentation/tools/ZoomTool.d.ts +2 -6
  93. package/dist/types/Utils/segmentation/tools/index.d.ts +5 -7
  94. package/dist/types/Utils/workers/reformatSaveDataWorker.d.ts +1 -1
  95. package/dist/types/index.d.ts +3 -3
  96. package/package.json +1 -1
  97. package/dist/Utils/segmentation/CommToolsData.d.ts +0 -192
  98. package/dist/Utils/segmentation/CommToolsData.js +0 -474
  99. package/dist/Utils/segmentation/CommToolsData.js.map +0 -1
  100. package/dist/Utils/segmentation/coreTools/coreType.d.ts +0 -389
  101. package/dist/Utils/segmentation/coreTools/coreType.js +0 -3
  102. package/dist/Utils/segmentation/coreTools/coreType.js.map +0 -1
  103. package/dist/types/Utils/segmentation/CommToolsData.d.ts +0 -192
  104. package/dist/types/Utils/segmentation/coreTools/coreType.d.ts +0 -389
@@ -7,31 +7,7 @@
7
7
  */
8
8
  import { BaseTool } from "./BaseTool";
9
9
  import type { ToolContext } from "./BaseTool";
10
- import type { MaskDelta } from "../core";
11
- /**
12
- * Callbacks DrawingTool needs from its host (DrawToolCore).
13
- */
14
- export interface DrawingCallbacks {
15
- /** Get current layer's canvas and 2D context */
16
- setCurrentLayer: () => {
17
- ctx: CanvasRenderingContext2D;
18
- canvas: HTMLCanvasElement;
19
- };
20
- /** Composite all layers to master canvas */
21
- compositeAllLayers: () => void;
22
- /** Sync layer slice data to MaskVolume */
23
- syncLayerSliceData: (index: number, layer: string) => void;
24
- /** Get stored image data for previous image redraw */
25
- filterDrawedImage: (axis: "x" | "y" | "z", index: number) => {
26
- image: ImageData;
27
- } | undefined;
28
- /** Get MaskVolume for a layer (undo snapshots) */
29
- getVolumeForLayer: (layer: string) => any;
30
- /** Push delta to UndoManager */
31
- pushUndoDelta: (delta: MaskDelta) => void;
32
- /** Get eraser icon URLs */
33
- getEraserUrls: () => string[];
34
- }
10
+ import type { DrawingHostDeps } from "./ToolHost";
35
11
  export declare class DrawingTool extends BaseTool {
36
12
  /** Left mouse button currently held (draw mode) */
37
13
  private leftClicked;
@@ -46,7 +22,7 @@ export declare class DrawingTool extends BaseTool {
46
22
  private preDrawAxis;
47
23
  private preDrawSliceIndex;
48
24
  private callbacks;
49
- constructor(ctx: ToolContext, callbacks: DrawingCallbacks);
25
+ constructor(ctx: ToolContext, callbacks: DrawingHostDeps);
50
26
  /** Whether a draw operation is currently active */
51
27
  get isActive(): boolean;
52
28
  /** Whether paint strokes are being recorded */
@@ -77,6 +53,22 @@ export declare class DrawingTool extends BaseTool {
77
53
  * @returns true if drawing was in progress when leave occurred
78
54
  */
79
55
  onPointerLeave(): boolean;
56
+ /**
57
+ * Create a self-managing mouseover/mouseout/mousemove handler
58
+ * that tracks brush hover position for the preview circle.
59
+ *
60
+ * The returned function should be registered on drawingCanvas for
61
+ * "mouseover" and "mouseout" events. It adds/removes a "mousemove"
62
+ * listener on itself to keep mouseOverX/Y up-to-date while the
63
+ * cursor is inside the canvas.
64
+ */
65
+ createBrushTrackingHandler(): (e: MouseEvent) => void;
66
+ /**
67
+ * Render brush circle preview on the drawing context.
68
+ * Called from the start() render loop when in draw mode and not
69
+ * actively painting. Skipped in pencil/eraser mode.
70
+ */
71
+ renderBrushPreview(ctx: CanvasRenderingContext2D, width: number, height: number): void;
80
72
  /** Capture pre-draw slice snapshot for undo */
81
73
  private capturePreDrawSnapshot;
82
74
  /** Push delta to UndoManager after drawing completes */
@@ -8,13 +8,10 @@
8
8
  */
9
9
  import { BaseTool } from "./BaseTool";
10
10
  import type { ToolContext } from "./BaseTool";
11
- export interface ImageStoreCallbacks {
12
- setEmptyCanvasSize: (axis?: "x" | "y" | "z") => void;
13
- drawImageOnEmptyImage: (canvas: HTMLCanvasElement) => void;
14
- }
11
+ import type { ImageStoreHostDeps } from "./ToolHost";
15
12
  export declare class ImageStoreHelper extends BaseTool {
16
13
  private callbacks;
17
- constructor(ctx: ToolContext, callbacks: ImageStoreCallbacks);
14
+ constructor(ctx: ToolContext, callbacks: ImageStoreHostDeps);
18
15
  /**
19
16
  * Get MaskVolume for a specific layer.
20
17
  * Delegates to the volumes stored in protectedData.maskData.
@@ -0,0 +1,52 @@
1
+ import { BaseTool } from "./BaseTool";
2
+ import type { ToolContext } from "./BaseTool";
3
+ import type { ChannelValue, RGBAColor, ChannelColorMap } from "../core";
4
+ import type { SphereType } from "./SphereTool";
5
+ import type { LayerChannelHostDeps } from "./ToolHost";
6
+ /**
7
+ * Manages layer/channel state: active selection, visibility, and channel colors.
8
+ *
9
+ * Extracted from NrrdTools.ts to reduce its size.
10
+ * Follows the same BaseTool + ToolContext + Callbacks pattern as other tools.
11
+ */
12
+ export declare class LayerChannelManager extends BaseTool {
13
+ private callbacks;
14
+ constructor(ctx: ToolContext, callbacks: LayerChannelHostDeps);
15
+ /****************************Active Layer/Channel****************************************************/
16
+ setActiveLayer(layerId: string): void;
17
+ getActiveLayer(): string;
18
+ setActiveChannel(channel: ChannelValue): void;
19
+ getActiveChannel(): number;
20
+ /**
21
+ * Set the active sphere type and sync brush/fill color.
22
+ *
23
+ * @example
24
+ * ```ts
25
+ * nrrdTools.setActiveSphereType('nipple');
26
+ * ```
27
+ */
28
+ setActiveSphereType(type: SphereType): void;
29
+ getActiveSphereType(): SphereType;
30
+ /****************************Visibility****************************************************/
31
+ setLayerVisible(layerId: string, visible: boolean): void;
32
+ isLayerVisible(layerId: string): boolean;
33
+ setChannelVisible(layerId: string, channel: ChannelValue, visible: boolean): void;
34
+ isChannelVisible(layerId: string, channel: ChannelValue): boolean;
35
+ getLayerVisibility(): Record<string, boolean>;
36
+ getChannelVisibility(): Record<string, Record<number, boolean>>;
37
+ hasLayerData(layerId: string): boolean;
38
+ /****************************Channel Colors****************************************************/
39
+ setChannelColor(layerId: string, channel: number, color: RGBAColor): void;
40
+ getChannelColor(layerId: string, channel: number): RGBAColor;
41
+ getChannelHexColor(layerId: string, channel: number): string;
42
+ getChannelCssColor(layerId: string, channel: number): string;
43
+ setChannelColors(layerId: string, colorMap: Partial<ChannelColorMap>): void;
44
+ setAllLayersChannelColor(channel: number, color: RGBAColor): void;
45
+ resetChannelColors(layerId?: string, channel?: number): void;
46
+ /****************************Private Helpers****************************************************/
47
+ /**
48
+ * Sync brush/fill color from the active layer's volume channel color.
49
+ * Falls back to global CHANNEL_HEX_COLORS if volume not available.
50
+ */
51
+ private syncBrushColor;
52
+ }
@@ -6,13 +6,7 @@
6
6
  */
7
7
  import { BaseTool } from "./BaseTool";
8
8
  import type { ToolContext } from "./BaseTool";
9
- /**
10
- * Callbacks PanTool needs from its host (DrawToolCore).
11
- */
12
- export interface PanCallbacks {
13
- /** Re-enable zoom wheel after pan ends in sphere mode */
14
- zoomActionAfterDrawSphere: () => void;
15
- }
9
+ import type { PanHostDeps } from "./ToolHost";
16
10
  export declare class PanTool extends BaseTool {
17
11
  /** Right mouse button currently held */
18
12
  private rightClicked;
@@ -26,7 +20,7 @@ export declare class PanTool extends BaseTool {
26
20
  * Arrow function preserves `this` binding.
27
21
  */
28
22
  private readonly boundPointerMove;
29
- constructor(ctx: ToolContext, callbacks: PanCallbacks);
23
+ constructor(ctx: ToolContext, callbacks: PanHostDeps);
30
24
  /** Whether a pan drag is currently active */
31
25
  get isActive(): boolean;
32
26
  /**
@@ -0,0 +1,80 @@
1
+ import { BaseTool } from "./BaseTool";
2
+ import type { ToolContext } from "./BaseTool";
3
+ import type { SliceRenderHostDeps } from "./ToolHost";
4
+ /**
5
+ * Manages slice rendering pipeline: slice setup, canvas rendering, and view helpers.
6
+ *
7
+ * Extracted from NrrdTools.ts to reduce its size.
8
+ * Follows the same BaseTool + ToolContext + Callbacks pattern as other tools.
9
+ */
10
+ export declare class SliceRenderPipeline extends BaseTool {
11
+ private callbacks;
12
+ private initState;
13
+ constructor(ctx: ToolContext, callbacks: SliceRenderHostDeps);
14
+ /**
15
+ * Reset initState to true (called from NrrdTools.reset() when switching datasets).
16
+ */
17
+ resetInitState(): void;
18
+ /****************************Slice Setup****************************************************/
19
+ setDisplaySlicesBaseOnAxis(): void;
20
+ private loadDisplaySlicesArray;
21
+ resetDisplaySlicesStatus(): void;
22
+ private setupConfigs;
23
+ private setMainPreSlice;
24
+ private setOriginCanvasAndPre;
25
+ afterLoadSlice(): void;
26
+ private updateMaxIndex;
27
+ /****************************Rendering****************************************************/
28
+ /**
29
+ * Phase 3: Reload all mask layers from MaskVolume using buffer reuse
30
+ * Replaces the old reloadMaskToLayer approach
31
+ */
32
+ reloadMasksFromVolume(): void;
33
+ /******************************** redraw display canvas ***************************************/
34
+ /**
35
+ * Redraw current contrast image to display canvas.
36
+ * It is more related to change the contrast slice image's window width or center.
37
+ */
38
+ redrawDisplayCanvas(): void;
39
+ redrawMianPreOnDisplayCanvas(): void;
40
+ /**
41
+ * flip the canvas to a correct position.
42
+ * This is because the slice canvas from threejs is not in a correct 2D postion.
43
+ * Thus, everytime when we redraw the display canvas, we need to flip to draw the origin canvas from threejs.
44
+ * Under different axis(sagittal, Axial, Coronal), the flip orientation is different.
45
+ */
46
+ flipDisplayImageByAxis(): void;
47
+ /**
48
+ * Set the empty canvas width and height based on the axis (pixel distance not the mm), to reduce duplicate codes.
49
+ *
50
+ * @param axis
51
+ */
52
+ setEmptyCanvasSize(axis?: "x" | "y" | "z"): void;
53
+ /**
54
+ * Clear masks on drawingCanvas layers.
55
+ */
56
+ resetLayerCanvas(): void;
57
+ /****************************View/Canvas Helpers****************************************************/
58
+ /**
59
+ * Resize the draw and display canvas size based on the input size factor number.
60
+ * @param factor number
61
+ */
62
+ resizePaintArea(factor: number): void;
63
+ /**
64
+ * Reset the draw and display canvases layout after mouse pan.
65
+ * If no params in, then center the draw and display canvases.
66
+ * @param l number, Offset to the left
67
+ * @param t number, Offset to the top
68
+ */
69
+ resetPaintAreaUIPosition(l?: number, t?: number): void;
70
+ /**
71
+ * Update the original canvas size, allow set to threejs load one (pixel distance not the mm).
72
+ * Then update the changedWidth and changedHeight based on the sizeFactor.
73
+ */
74
+ updateOriginAndChangedWH(): void;
75
+ /**
76
+ * Keep all contrast slice index to same.
77
+ * Synchronize the slice indexes of all the contrasts so that they are consistent with the main slice's index.
78
+ */
79
+ setSyncsliceNum(): void;
80
+ }
@@ -43,10 +43,11 @@
43
43
  * - drawSphereOnEachViews / drawCalculatorSphereOnEachViews
44
44
  * - storeSphereImages / setSphereCanvasSize
45
45
  * - drawCalculatorSphere / configMouseSphereWheel
46
- * - getSpherePosition / clearSpherePrintStoreImages
46
+ * - getSpherePosition
47
47
  */
48
48
  import { BaseTool } from "./BaseTool";
49
49
  import type { ToolContext } from "./BaseTool";
50
+ import type { SphereHostDeps } from "./ToolHost";
50
51
  /** The 4 supported sphere marker types. */
51
52
  export type SphereType = 'tumour' | 'skin' | 'nipple' | 'ribcage';
52
53
  /**
@@ -72,22 +73,10 @@ export declare const SPHERE_CHANNEL_MAP: Record<SphereType, {
72
73
  * Calculator mode uses type-specific labels (1-4).
73
74
  */
74
75
  export declare const SPHERE_LABELS: Record<SphereType | 'default', number>;
75
- /**
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
82
- */
83
- export interface SphereCallbacks {
84
- setEmptyCanvasSize: (axis?: "x" | "y" | "z") => void;
85
- drawImageOnEmptyImage: (canvas: HTMLCanvasElement) => void;
86
- }
87
76
  export declare class SphereTool extends BaseTool {
88
77
  private callbacks;
89
- constructor(ctx: ToolContext, callbacks: SphereCallbacks);
90
- setCallbacks(callbacks: SphereCallbacks): void;
78
+ constructor(ctx: ToolContext, callbacks: SphereHostDeps);
79
+ setCallbacks(callbacks: SphereHostDeps): void;
91
80
  /**
92
81
  * Get the channel number for a sphere type.
93
82
  *
@@ -189,12 +178,29 @@ export declare class SphereTool extends BaseTool {
189
178
  */
190
179
  drawCalculatorSphere(radius: number): void;
191
180
  /**
192
- * Clear sphere overlay images.
181
+ * Handle left-click in sphere mode — record origin, draw preview.
182
+ *
183
+ * Performs all data operations for sphere placement:
184
+ * 1. Record sphere origin for current axis
185
+ * 2. Convert origin to all three axes via setUpSphereOrigins
186
+ * 3. Store origin for the active sphere type
187
+ * 4. Enable crosshair at click position
188
+ * 5. Draw calculator sphere preview
189
+ *
190
+ * Event binding (wheel, pointerup) stays in DrawToolCore as orchestration.
191
+ */
192
+ onSphereClick(e: MouseEvent): void;
193
+ /**
194
+ * Handle pointer-up in sphere mode — write to volume, fire callbacks.
195
+ *
196
+ * Performs:
197
+ * 1. Write all placed calculator spheres to sphereMaskVolume
198
+ * 2. Refresh sphere canvas overlay from volume
199
+ * 3. Fire onSphereChanged and onCalculatorPositionsChanged callbacks
193
200
  *
194
- * No-op in current implementation sphere data is rendered as overlay
195
- * and stored in the dedicated sphereMaskVolume (not in layer volumes).
201
+ * Event cleanup (wheel, pointerup listener removal) stays in DrawToolCore.
196
202
  */
197
- clearSpherePrintStoreImages(): void;
203
+ onSpherePointerUp(): void;
198
204
  /**
199
205
  * Convert canvas (mm-space) coordinates to 3D voxel coordinates.
200
206
  *
@@ -0,0 +1,74 @@
1
+ /**
2
+ * ToolHost — Unified host interface for all tools.
3
+ *
4
+ * Replaces the 10 individual *Callbacks interfaces with a single definition.
5
+ * Each tool picks only the methods it needs via `Pick<ToolHost, ...>`.
6
+ *
7
+ * @see issue3_unify_callbacks_plan.md
8
+ */
9
+ import type { MaskVolume, MaskDelta } from "../core";
10
+ import type { RGBAColor } from "../core";
11
+ /**
12
+ * Unified host interface — all methods that tools may call back into.
13
+ *
14
+ * Each tool picks only the methods it needs via `Pick<ToolHost, ...>`.
15
+ */
16
+ export interface ToolHost {
17
+ setEmptyCanvasSize(axis?: "x" | "y" | "z"): void;
18
+ drawImageOnEmptyImage(canvas: HTMLCanvasElement): void;
19
+ compositeAllLayers(): void;
20
+ renderSliceToCanvas(layer: string, axis: "x" | "y" | "z", sliceIndex: number, buffer: ImageData, targetCtx: CanvasRenderingContext2D, scaledWidth: number, scaledHeight: number): void;
21
+ getOrCreateSliceBuffer(axis: "x" | "y" | "z"): ImageData | null;
22
+ flipDisplayImageByAxis(): void;
23
+ redrawDisplayCanvas(): void;
24
+ refreshSphereOverlay(): void;
25
+ reloadMasksFromVolume(): void;
26
+ getVolumeForLayer(layer: string): MaskVolume;
27
+ setIsDrawFalse(target: number): void;
28
+ setSyncsliceNum(): void;
29
+ resetPaintAreaUIPosition(l?: number, t?: number): void;
30
+ resizePaintArea(moveDistance: number): void;
31
+ resetZoom(): void;
32
+ invalidateSliceBuffer(): void;
33
+ clearUndoHistory(): void;
34
+ setCurrentLayer(): {
35
+ ctx: CanvasRenderingContext2D;
36
+ canvas: HTMLCanvasElement;
37
+ };
38
+ syncLayerSliceData(index: number, layer: string): void;
39
+ filterDrawedImage(axis: "x" | "y" | "z", index: number): {
40
+ image: ImageData;
41
+ } | undefined;
42
+ pushUndoDelta(delta: MaskDelta): void;
43
+ getEraserUrls(): string[];
44
+ enableCrosshair(): void;
45
+ setUpSphereOrigins(mouseX: number, mouseY: number, sliceIndex: number): void;
46
+ zoomActionAfterDrawSphere(): void;
47
+ setDisplaySlicesBaseOnAxis(): void;
48
+ afterLoadSlice(): void;
49
+ syncGuiParameterSettings(): void;
50
+ repraintCurrentContrastSlice(): void;
51
+ updateShowNumDiv(contrastNum: number): void;
52
+ updateCurrentContrastSlice(): void;
53
+ onChannelColorChanged(layerId: string, channel: number, color: RGBAColor): void;
54
+ }
55
+ /** ImageStoreHelper host dependencies */
56
+ export type ImageStoreHostDeps = Pick<ToolHost, 'setEmptyCanvasSize' | 'drawImageOnEmptyImage'>;
57
+ /** PanTool host dependencies */
58
+ export type PanHostDeps = Pick<ToolHost, 'zoomActionAfterDrawSphere'>;
59
+ /** ContrastTool host dependencies */
60
+ export type ContrastHostDeps = Pick<ToolHost, 'setIsDrawFalse' | 'setSyncsliceNum'>;
61
+ /** ZoomTool host dependencies */
62
+ export type ZoomHostDeps = Pick<ToolHost, 'resetPaintAreaUIPosition' | 'resizePaintArea' | 'setIsDrawFalse'>;
63
+ /** SphereTool host dependencies */
64
+ export type SphereHostDeps = Pick<ToolHost, 'setEmptyCanvasSize' | 'drawImageOnEmptyImage' | 'enableCrosshair' | 'setUpSphereOrigins'>;
65
+ /** DrawingTool host dependencies */
66
+ export type DrawingHostDeps = Pick<ToolHost, 'setCurrentLayer' | 'compositeAllLayers' | 'syncLayerSliceData' | 'filterDrawedImage' | 'getVolumeForLayer' | 'pushUndoDelta' | 'getEraserUrls'>;
67
+ /** DragSliceTool host dependencies */
68
+ export type DragSliceHostDeps = Pick<ToolHost, 'setSyncsliceNum' | 'setIsDrawFalse' | 'flipDisplayImageByAxis' | 'setEmptyCanvasSize' | 'getOrCreateSliceBuffer' | 'renderSliceToCanvas' | 'refreshSphereOverlay'>;
69
+ /** LayerChannelManager host dependencies */
70
+ export type LayerChannelHostDeps = Pick<ToolHost, 'reloadMasksFromVolume' | 'getVolumeForLayer' | 'onChannelColorChanged'>;
71
+ /** SliceRenderPipeline host dependencies */
72
+ export type SliceRenderHostDeps = Pick<ToolHost, 'compositeAllLayers' | 'getOrCreateSliceBuffer' | 'renderSliceToCanvas' | 'getVolumeForLayer' | 'refreshSphereOverlay' | 'syncGuiParameterSettings' | 'repraintCurrentContrastSlice' | 'clearUndoHistory' | 'updateShowNumDiv' | 'updateCurrentContrastSlice'>;
73
+ /** DataLoader host dependencies */
74
+ export type DataLoaderHostDeps = Pick<ToolHost, 'invalidateSliceBuffer' | 'setDisplaySlicesBaseOnAxis' | 'afterLoadSlice' | 'setEmptyCanvasSize' | 'syncLayerSliceData' | 'reloadMasksFromVolume' | 'resetZoom'>;
@@ -6,15 +6,11 @@
6
6
  */
7
7
  import { BaseTool } from "./BaseTool";
8
8
  import type { ToolContext } from "./BaseTool";
9
- export interface ZoomCallbacks {
10
- resetPaintAreaUIPosition: (l?: number, t?: number) => void;
11
- resizePaintArea: (moveDistance: number) => void;
12
- setIsDrawFalse: (target: number) => void;
13
- }
9
+ import type { ZoomHostDeps } from "./ToolHost";
14
10
  export declare class ZoomTool extends BaseTool {
15
11
  private container;
16
12
  private mainAreaContainer;
17
13
  private callbacks;
18
- constructor(ctx: ToolContext, container: HTMLElement, mainAreaContainer: HTMLDivElement, callbacks: ZoomCallbacks);
14
+ constructor(ctx: ToolContext, container: HTMLElement, mainAreaContainer: HTMLDivElement, callbacks: ZoomHostDeps);
19
15
  configMouseZoomWheel(): (e: WheelEvent) => void;
20
16
  }
@@ -8,19 +8,17 @@
8
8
  */
9
9
  export { BaseTool } from "./BaseTool";
10
10
  export type { ToolContext } from "./BaseTool";
11
+ export type { ToolHost, ImageStoreHostDeps, PanHostDeps, ContrastHostDeps, ZoomHostDeps, SphereHostDeps, DrawingHostDeps, DragSliceHostDeps, LayerChannelHostDeps, SliceRenderHostDeps, DataLoaderHostDeps, } from "./ToolHost";
11
12
  export { EraserTool } from "./EraserTool";
12
13
  export { DrawingTool } from "./DrawingTool";
13
- export type { DrawingCallbacks } from "./DrawingTool";
14
14
  export { PanTool } from "./PanTool";
15
- export type { PanCallbacks } from "./PanTool";
16
15
  export { ZoomTool } from "./ZoomTool";
17
- export type { ZoomCallbacks } from "./ZoomTool";
18
16
  export { SphereTool, SPHERE_CHANNEL_MAP } from "./SphereTool";
19
- export type { SphereCallbacks, SphereType } from "./SphereTool";
17
+ export type { SphereType } from "./SphereTool";
20
18
  export { CrosshairTool } from "./CrosshairTool";
21
19
  export { ContrastTool } from "./ContrastTool";
22
- export type { ContrastCallbacks } from "./ContrastTool";
23
20
  export { ImageStoreHelper } from "./ImageStoreHelper";
24
- export type { ImageStoreCallbacks } from "./ImageStoreHelper";
25
21
  export { DragSliceTool } from "./DragSliceTool";
26
- export type { DragSliceCallbacks } from "./DragSliceTool";
22
+ export { LayerChannelManager } from "./LayerChannelManager";
23
+ export { SliceRenderPipeline } from "./SliceRenderPipeline";
24
+ export { DataLoader } from "./DataLoader";
@@ -1,4 +1,4 @@
1
- import { IPaintImage } from "../segmentation/coreTools/coreType";
1
+ import { IPaintImage } from "../segmentation/core/types";
2
2
  declare function pruningData(originArr: IPaintImage[]): Uint8ClampedArray[];
3
3
  declare function restructData(originArr: IPaintImage[], len: number, width: number, height: number): {
4
4
  sliceIndex: number;
@@ -17,13 +17,13 @@ import { Copper3dTrackballControls } from "./Controls/Copper3dTrackballControls"
17
17
  import { MeshNodeTool } from "./Utils/MeshNodeTool";
18
18
  import { removeGuiFolderChilden } from "./Utils/segmentation/coreTools/gui";
19
19
  import { nrrdMeshesType, nrrdSliceType, SensorDecodedValue_kiwrious, SensorReadResult_kiwrious, HeartRateResult_kiwrious, loadingBarType, exportPaintImageType, IOptVTKLoader } from "./types/types";
20
- import { IPaintImage, ICommXYZ, IGUIStates, IGuiParameterSettings, INrrdStates, IGuiMeta } from "./Utils/segmentation/coreTools/coreType";
20
+ import { IPaintImage, ICommXYZ, IGUIStates, IGuiParameterSettings, INrrdStates, IGuiMeta } from "./Utils/segmentation/core/types";
21
21
  import { NrrdState } from "./Utils/segmentation/coreTools/NrrdState";
22
22
  import { GuiState } from "./Utils/segmentation/coreTools/GuiState";
23
- import type { ToolMode, IAnnotationCallbacks } from "./Utils/segmentation/coreTools/coreType";
23
+ import type { ToolMode, IAnnotationCallbacks } from "./Utils/segmentation/core/types";
24
24
  import { CHANNEL_COLORS, CHANNEL_HEX_COLORS, rgbaToHex, rgbaToCss } from "./Utils/segmentation/core/index";
25
25
  import type { LayerId, ChannelValue } from "./Utils/segmentation/core/index";
26
26
  import "./css/style.css";
27
- export declare const REVISION = "v3.0.2-beta";
27
+ export declare const REVISION = "v3.1.0-beta";
28
28
  export { copperRenderer, copperRendererOnDemond, copperMSceneRenderer, setHDRFilePath, addLabelToScene, convert3DPostoScreenPos, convertScreenPosto3DPos, addBoxHelper, fullScreenListenner, configKiwriousHeart, copperScene, copperSceneOnDemond, copperMScene, CameraViewPoint, kiwrious, NrrdTools, loading, Copper3dTrackballControls, createTexture2D_NRRD, MeshNodeTool, throttle, removeGuiFolderChilden, CHANNEL_COLORS, CHANNEL_HEX_COLORS, rgbaToHex, rgbaToCss, };
29
29
  export type { positionType, screenPosType, optsType, nrrdMeshesType, nrrdSliceType, SensorDecodedValue_kiwrious, SensorReadResult_kiwrious, HeartRateResult_kiwrious, loadingBarType, IPaintImage, exportPaintImageType, IOptVTKLoader, ICommXYZ, IGUIStates, IGuiParameterSettings, INrrdStates, NrrdState, GuiState, IGuiMeta, ToolMode, IAnnotationCallbacks, LayerId, ChannelValue, };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "copper3d",
3
3
  "description": "A 3d visualisation package base on threejs provides multiple scenes and Nrrd image load funtion.",
4
- "version": "3.0.2",
4
+ "version": "3.1.0",
5
5
  "main": "dist/bundle.umd.js",
6
6
  "moudle": "dist/bundle.esm.js",
7
7
  "types": "dist/types/index.d.ts",
@@ -1,192 +0,0 @@
1
- import { IProtected, ICursorPage, IConvertObjType, INewMaskData, IKeyBoardSettings, IAnnotationCallbacks } from "./coreTools/coreType";
2
- import { NrrdState } from "./coreTools/NrrdState";
3
- import { GuiState } from "./coreTools/GuiState";
4
- import { MaskVolume } from "./core/index";
5
- export declare class CommToolsData {
6
- baseCanvasesSize: number;
7
- private _reusableSliceBuffer;
8
- private _reusableBufferWidth;
9
- private _reusableBufferHeight;
10
- /** External annotation callbacks — set via draw() options */
11
- protected annotationCallbacks: IAnnotationCallbacks;
12
- /** Whether the keyboard-config dialog is open (suppresses all shortcuts). */
13
- protected _configKeyBoard: boolean;
14
- /** Active keyboard shortcut bindings. */
15
- protected _keyboardSettings: IKeyBoardSettings;
16
- protected nrrd_states: NrrdState;
17
- protected cursorPage: ICursorPage;
18
- protected gui_states: GuiState;
19
- protected protectedData: IProtected;
20
- constructor(container: HTMLElement, mainAreaContainer: HTMLElement, options?: {
21
- layers?: string[];
22
- });
23
- /**
24
- * Get MaskVolume for a specific layer
25
- *
26
- * @param layer - Layer name: "layer1", "layer2", or "layer3"
27
- * @returns MaskVolume instance for the specified layer
28
- *
29
- * @example
30
- * ```ts
31
- * const volume = this.getVolumeForLayer("layer1");
32
- * volume.setVoxel(x, y, z, 255);
33
- * ```
34
- */
35
- getVolumeForLayer(layer: string): MaskVolume;
36
- /**
37
- * Get MaskVolume for the currently active layer
38
- *
39
- * @returns MaskVolume instance for the current layer
40
- *
41
- * @example
42
- * ```ts
43
- * const volume = this.getCurrentVolume();
44
- * const slice = volume.getSliceImageData(50, 'z');
45
- * ```
46
- */
47
- getCurrentVolume(): MaskVolume;
48
- /**
49
- * Get all three MaskVolume instances
50
- *
51
- * @returns Object containing all three layer volumes
52
- *
53
- * @example
54
- * ```ts
55
- * const { layer1, layer2, layer3 } = this.getAllVolumes();
56
- * layer1.clear();
57
- * ```
58
- */
59
- getAllVolumes(): INewMaskData;
60
- private generateSystemCanvases;
61
- private generateLayerTargets;
62
- /**
63
- * Rewrite this {clearActiveSlice} function under DrawToolCore
64
- */
65
- clearActiveSlice(): void;
66
- /**
67
- * Rewrite this {undoLastPainting} function under DrawToolCore
68
- */
69
- undoLastPainting(): void;
70
- /**
71
- * Rewrite this {redoLastPainting} function under DrawToolCore
72
- */
73
- redoLastPainting(): void;
74
- /**
75
- * Rewrite this {clearActiveLayer} function under NrrdTools
76
- */
77
- clearActiveLayer(): void;
78
- /**
79
- * Rewrite this {resizePaintArea} function under NrrdTools
80
- */
81
- resizePaintArea(factor: number): void;
82
- /**
83
- * Rewrite this {setIsDrawFalse} function under NrrdTools
84
- */
85
- setIsDrawFalse(target: number): void;
86
- /**
87
- * Rewrite this {updateOriginAndChangedWH} function under NrrdTools
88
- */
89
- updateOriginAndChangedWH(): void;
90
- /**
91
- * Rewrite this {flipDisplayImageByAxis} function under NrrdTools
92
- */
93
- flipDisplayImageByAxis(): void;
94
- /**
95
- * Rewrite this {resetPaintAreaUIPosition} function under NrrdTools
96
- */
97
- resetPaintAreaUIPosition(l?: number, t?: number): void;
98
- /**
99
- * Rewrite this {resetPaintAreaUIPosition} function under NrrdTools
100
- */
101
- setEmptyCanvasSize(axis?: "x" | "y" | "z"): void;
102
- /**
103
- * Rewrite this {convertCursorPoint} function under NrrdTools
104
- */
105
- convertCursorPoint(from: "x" | "y" | "z", to: "x" | "y" | "z", cursorNumX: number, cursorNumY: number, currentSliceIndex: number): IConvertObjType | undefined;
106
- /**
107
- * Rewrite this {resetLayerCanvas} function under NrrdTools
108
- */
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;
121
- /**
122
- * Rewrite this {setSyncsliceNum} function under NrrdTools
123
- */
124
- setSyncsliceNum(): void;
125
- /**
126
- * Rewrite this {redrawDisplayCanvas} function under NrrdTools
127
- */
128
- redrawDisplayCanvas(): void;
129
- /**
130
- * Get a painted mask image based on current axis and input slice index.
131
- *
132
- * Phase 3: Reads directly from MaskVolume.
133
- *
134
- * @param axis "x" | "y" | "z"
135
- * @param sliceIndex number
136
- * @returns Object with index and image, or undefined
137
- */
138
- filterDrawedImage(axis: "x" | "y" | "z", sliceIndex: number): {
139
- index: number;
140
- image: ImageData;
141
- } | undefined;
142
- /**
143
- * Get or create a reusable ImageData buffer for the given axis.
144
- *
145
- * Reuses the same buffer across multiple slice renders to avoid
146
- * allocating a new ImageData per layer per slice switch.
147
- * The buffer is only reallocated when slice dimensions change (axis switch).
148
- *
149
- * @param axis - Axis: "x", "y", or "z"
150
- * @returns Reusable ImageData buffer with correct dimensions
151
- */
152
- getOrCreateSliceBuffer(axis: "x" | "y" | "z"): ImageData | null;
153
- /**
154
- * Render a layer's slice into a reusable buffer and draw to the target canvas.
155
- *
156
- * Uses MaskVolume.renderLabelSliceInto() for zero-allocation rendering.
157
- * The caller should obtain the buffer via getOrCreateSliceBuffer() and reuse
158
- * it across multiple layer renders.
159
- *
160
- * @param layer - Layer name: "layer1", "layer2", or "layer3"
161
- * @param axis - Axis: "x", "y", or "z"
162
- * @param sliceIndex - Slice index
163
- * @param buffer - Reusable ImageData buffer (from getOrCreateSliceBuffer)
164
- * @param targetCtx - Canvas context to draw the result onto
165
- * @param scaledWidth - Target display width
166
- * @param scaledHeight - Target display height
167
- */
168
- renderSliceToCanvas(layer: string, axis: "x" | "y" | "z", sliceIndex: number, buffer: ImageData, targetCtx: CanvasRenderingContext2D, scaledWidth: number, scaledHeight: number): void;
169
- /**
170
- * Invalidate the reusable buffer (e.g. when switching datasets).
171
- * The buffer will be lazily recreated on next use.
172
- */
173
- invalidateSliceBuffer(): void;
174
- /**
175
- * Apply the same flip transform used by flipDisplayImageByAxis() to any
176
- * canvas context. This ensures mask overlays align with the flipped CT image.
177
- *
178
- * The flip is its own inverse (applying twice = identity), so it works for
179
- * both directions: volume→display (rendering) and display→volume (storing).
180
- *
181
- * @param ctx Target 2D context (must be wrapped in save/restore by caller).
182
- * @param width Canvas width in pixels.
183
- * @param height Canvas height in pixels.
184
- * @param axis Current viewing axis.
185
- */
186
- applyMaskFlipForAxis(ctx: CanvasRenderingContext2D, width: number, height: number, axis: "x" | "y" | "z"): void;
187
- /**
188
- * Composite all layer canvases to the master display canvas.
189
- * Only draws layers whose visibility is enabled.
190
- */
191
- compositeAllLayers(): void;
192
- }