@cornerstonejs/tools 5.4.13 → 5.4.14

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.
@@ -1,4 +1,4 @@
1
- import { triggerSegmentationRenderBySegmentationId } from '../../stateManagement/segmentation/SegmentationRenderingEngine.js';
1
+ import { triggerSegmentationRenderForModified } from '../../stateManagement/segmentation/SegmentationRenderingEngine.js';
2
2
  import onLabelmapSegmentationDataModified from './labelmap/onLabelmapSegmentationDataModified.js';
3
3
  import { getSegmentation } from '../../stateManagement/segmentation/getSegmentation.js';
4
4
  const onSegmentationDataModified = function (evt) {
@@ -7,6 +7,6 @@ const onSegmentationDataModified = function (evt) {
7
7
  if (representationData.Labelmap) {
8
8
  onLabelmapSegmentationDataModified(evt);
9
9
  }
10
- triggerSegmentationRenderBySegmentationId(segmentationId);
10
+ triggerSegmentationRenderForModified(segmentationId);
11
11
  };
12
12
  export default onSegmentationDataModified;
@@ -17,5 +17,6 @@ declare class SegmentationRenderingEngine {
17
17
  }
18
18
  declare function triggerSegmentationRender(viewportId?: string): void;
19
19
  declare function triggerSegmentationRenderBySegmentationId(segmentationId?: string): void;
20
+ declare function triggerSegmentationRenderForModified(segmentationId?: string): void;
20
21
  declare const segmentationRenderingEngine: SegmentationRenderingEngine;
21
- export { triggerSegmentationRender, triggerSegmentationRenderBySegmentationId, segmentationRenderingEngine, };
22
+ export { triggerSegmentationRender, triggerSegmentationRenderBySegmentationId, triggerSegmentationRenderForModified, segmentationRenderingEngine, };
@@ -169,5 +169,49 @@ function triggerSegmentationRender(viewportId) {
169
169
  function triggerSegmentationRenderBySegmentationId(segmentationId) {
170
170
  segmentationRenderingEngine.renderSegmentation(segmentationId);
171
171
  }
172
+ const DEFERRED_SEGMENTATION_RENDER_DELAY_MS = 240;
173
+ const deferredSegmentationRenderTimers = new Map();
174
+ function isProjectionHeavySegmentationViewport(viewport) {
175
+ const blendMode = viewport.getBlendMode?.();
176
+ if (blendMode === Enums.BlendModes.LABELMAP_EDGE_PROJECTION_BLEND) {
177
+ return true;
178
+ }
179
+ const planarViewport = viewport;
180
+ if (typeof planarViewport.getDisplaySetPresentation !== 'function') {
181
+ return false;
182
+ }
183
+ const dataIds = [];
184
+ const sourceDataId = planarViewport.getSourceDataId?.();
185
+ if (sourceDataId) {
186
+ dataIds.push(sourceDataId);
187
+ }
188
+ planarViewport.getActors?.().forEach((actorEntry) => {
189
+ if (actorEntry.representationUID) {
190
+ dataIds.push(String(actorEntry.representationUID));
191
+ }
192
+ });
193
+ return dataIds.some((dataId) => (planarViewport.getDisplaySetPresentation(dataId)?.slabThickness ?? 0) > 0);
194
+ }
195
+ function triggerSegmentationRenderForModified(segmentationId) {
196
+ const viewportIds = segmentationRenderingEngine._getViewportIdsForSegmentation(segmentationId);
197
+ viewportIds.forEach((viewportId) => {
198
+ const { viewport } = getEnabledElementByViewportId(viewportId) || {};
199
+ if (!viewport) {
200
+ return;
201
+ }
202
+ if (!isProjectionHeavySegmentationViewport(viewport)) {
203
+ segmentationRenderingEngine.renderSegmentationsForViewport(viewportId);
204
+ return;
205
+ }
206
+ const existingTimer = deferredSegmentationRenderTimers.get(viewportId);
207
+ if (existingTimer !== undefined) {
208
+ clearTimeout(existingTimer);
209
+ }
210
+ deferredSegmentationRenderTimers.set(viewportId, setTimeout(() => {
211
+ deferredSegmentationRenderTimers.delete(viewportId);
212
+ segmentationRenderingEngine.renderSegmentationsForViewport(viewportId);
213
+ }, DEFERRED_SEGMENTATION_RENDER_DELAY_MS));
214
+ });
215
+ }
172
216
  const segmentationRenderingEngine = new SegmentationRenderingEngine();
173
- export { triggerSegmentationRender, triggerSegmentationRenderBySegmentationId, segmentationRenderingEngine, };
217
+ export { triggerSegmentationRender, triggerSegmentationRenderBySegmentationId, triggerSegmentationRenderForModified, segmentationRenderingEngine, };
@@ -1,4 +1,4 @@
1
- import { cache, Enums, convertMapperToNotSharedMapper, volumeLoader, eventTarget, createVolumeActor, } from '@cornerstonejs/core';
1
+ import { cache, Enums, convertMapperToNotSharedMapper, volumeLoader, eventTarget, } from '@cornerstonejs/core';
2
2
  import { Events, SegmentationRepresentations } from '../../../enums/index.js';
3
3
  import { getSegmentation } from '../../../stateManagement/segmentation/getSegmentation.js';
4
4
  const internalCache = new Map();
@@ -52,6 +52,8 @@ export async function addVolumesAsIndependentComponents({ viewport, volumeInputs
52
52
  }
53
53
  viewport.removeActors([uid]);
54
54
  const oldMapper = actor.getMapper();
55
+ const sharedImageData = oldMapper.getInputData();
56
+ const originalScalars = sharedImageData.getPointData().getScalars() ?? null;
55
57
  const mapper = convertMapperToNotSharedMapper(oldMapper);
56
58
  actor.setMapper(mapper);
57
59
  mapper.setBlendMode(Enums.BlendModes.LABELMAP_EDGE_PROJECTION_BLEND);
@@ -68,9 +70,16 @@ export async function addVolumesAsIndependentComponents({ viewport, volumeInputs
68
70
  .getProperty()
69
71
  .getIndependentComponents();
70
72
  actor.getProperty().setIndependentComponents(true);
73
+ const oldUseLabelOutline = actor.getProperty().getUseLabelOutline();
74
+ const oldLabelOutlineOpacity = actor.getProperty().getLabelOutlineOpacity();
75
+ const oldLabelOutlineThickness = actor
76
+ .getProperty()
77
+ .getLabelOutlineThickness();
78
+ const representationUID = volumeInputArray[0].representationUID ??
79
+ `${segmentationId}-${SegmentationRepresentations.Labelmap}`;
71
80
  viewport.addActor({
72
81
  ...defaultActor,
73
- representationUID: `${segmentationId}-${SegmentationRepresentations.Labelmap}`,
82
+ representationUID,
74
83
  });
75
84
  internalCache.set(uid, {
76
85
  added: true,
@@ -82,7 +91,7 @@ export async function addVolumesAsIndependentComponents({ viewport, volumeInputs
82
91
  preLoad: load,
83
92
  });
84
93
  function onSegmentationDataModified(evt) {
85
- const { segmentationId } = evt.detail;
94
+ const { segmentationId, modifiedSlicesToUse } = evt.detail;
86
95
  const { representationData } = getSegmentation(segmentationId);
87
96
  const { volumeId: segVolumeId } = representationData.Labelmap;
88
97
  if (segVolumeId !== segImageVolume.volumeId) {
@@ -92,19 +101,30 @@ export async function addVolumesAsIndependentComponents({ viewport, volumeInputs
92
101
  const segVoxelManager = segmentationVolume.voxelManager;
93
102
  const imageData = mapper.getInputData();
94
103
  const array = imageData.getPointData().getArray(0);
95
- const baseData = array.getData();
104
+ const combinedData = array.getData();
96
105
  const newComp = 2;
97
106
  const dims = segImageData.getDimensions();
98
- const slices = Array.from({ length: dims[2] }, (_, i) => i);
107
+ const sliceSize = dims[0] * dims[1];
108
+ const slices = modifiedSlicesToUse?.length
109
+ ? modifiedSlicesToUse
110
+ : Array.from({ length: dims[2] }, (_, i) => i);
99
111
  for (const z of slices) {
100
- for (let y = 0; y < dims[1]; ++y) {
101
- for (let x = 0; x < dims[0]; ++x) {
102
- const iTuple = x + dims[0] * (y + dims[1] * z);
103
- baseData[iTuple * newComp + 1] = segVoxelManager.getAtIndex(iTuple);
112
+ const sliceStart = z * sliceSize;
113
+ const sliceImage = cache.getImage(segmentationVolume.imageIds?.[z]);
114
+ const sliceData = sliceImage?.voxelManager?.getScalarData?.();
115
+ if (sliceData?.length === sliceSize) {
116
+ for (let i = 0; i < sliceSize; ++i) {
117
+ combinedData[(sliceStart + i) * newComp + 1] = sliceData[i];
118
+ }
119
+ }
120
+ else {
121
+ for (let i = 0; i < sliceSize; ++i) {
122
+ const iTuple = sliceStart + i;
123
+ combinedData[iTuple * newComp + 1] = segVoxelManager.getAtIndex(iTuple);
104
124
  }
105
125
  }
106
126
  }
107
- array.setData(baseData);
127
+ array.setData(combinedData);
108
128
  imageData.modified();
109
129
  viewport.render();
110
130
  }
@@ -113,7 +133,7 @@ export async function addVolumesAsIndependentComponents({ viewport, volumeInputs
113
133
  if (evt.detail.viewportId !== viewport.id) {
114
134
  return;
115
135
  }
116
- eventTarget.removeEventListener(Events.SEGMENTATION_DATA_MODIFIED, onSegmentationDataModified);
136
+ eventTarget.removeEventListenerDebounced(Events.SEGMENTATION_DATA_MODIFIED, onSegmentationDataModified);
117
137
  eventTarget.removeEventListener(Events.SEGMENTATION_REPRESENTATION_REMOVED, onSegmentationRepresentationRemoved);
118
138
  const actorEntry = viewport.getActor(uid);
119
139
  if (actorEntry) {
@@ -124,11 +144,22 @@ export async function addVolumesAsIndependentComponents({ viewport, volumeInputs
124
144
  return;
125
145
  }
126
146
  actor.setMapper(oldMapper);
147
+ const pointData = sharedImageData.getPointData();
148
+ if (originalScalars) {
149
+ pointData.setScalars(originalScalars);
150
+ }
151
+ else {
152
+ pointData.removeArray('Pixels');
153
+ }
154
+ sharedImageData.modified();
127
155
  actor.getProperty().setColorMixPreset(oldColorMixPreset);
128
156
  actor
129
157
  .getProperty()
130
158
  .setForceNearestInterpolation(1, oldForceNearestInterpolation);
131
159
  actor.getProperty().setIndependentComponents(oldIndependentComponents);
160
+ actor.getProperty().setUseLabelOutline(oldUseLabelOutline);
161
+ actor.getProperty().setLabelOutlineOpacity(oldLabelOutlineOpacity);
162
+ actor.getProperty().setLabelOutlineThickness(oldLabelOutlineThickness);
132
163
  viewport.addActor({
133
164
  ...defaultActor,
134
165
  });
@@ -1 +1 @@
1
- export declare const version = "5.4.13";
1
+ export declare const version = "5.4.14";
@@ -1 +1 @@
1
- export const version = '5.4.13';
1
+ export const version = '5.4.14';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cornerstonejs/tools",
3
- "version": "5.4.13",
3
+ "version": "5.4.14",
4
4
  "description": "Cornerstone3D Tools",
5
5
  "types": "./dist/esm/index.d.ts",
6
6
  "module": "./dist/esm/index.js",
@@ -126,11 +126,11 @@
126
126
  "lodash.get": "4.4.2"
127
127
  },
128
128
  "devDependencies": {
129
- "@cornerstonejs/core": "5.4.13",
129
+ "@cornerstonejs/core": "5.4.14",
130
130
  "canvas": "3.2.0"
131
131
  },
132
132
  "peerDependencies": {
133
- "@cornerstonejs/core": "5.4.13",
133
+ "@cornerstonejs/core": "5.4.14",
134
134
  "@kitware/vtk.js": "35.5.3",
135
135
  "@types/d3-array": "3.2.1",
136
136
  "@types/d3-interpolate": "3.0.4",
@@ -149,5 +149,5 @@
149
149
  "type": "individual",
150
150
  "url": "https://ohif.org/donate"
151
151
  },
152
- "gitHead": "9f0b0f4813368e68bc0c04f02132e06f15b6a0f8"
152
+ "gitHead": "44424ece1744c4ee1fdd4c6304abc9005bf3bd39"
153
153
  }