@cornerstonejs/core 0.40.0 → 0.41.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 (33) hide show
  1. package/dist/cjs/RenderingEngine/BaseVolumeViewport.js +18 -19
  2. package/dist/cjs/RenderingEngine/BaseVolumeViewport.js.map +1 -1
  3. package/dist/cjs/RenderingEngine/vtkClasses/vtkStreamingOpenGLVolumeMapper.js.map +1 -1
  4. package/dist/cjs/cache/cache.js +1 -1
  5. package/dist/cjs/cache/cache.js.map +1 -1
  6. package/dist/cjs/cache/classes/ContourSet.d.ts +5 -0
  7. package/dist/cjs/cache/classes/ContourSet.js +32 -0
  8. package/dist/cjs/cache/classes/ContourSet.js.map +1 -1
  9. package/dist/cjs/cache/classes/ImageVolume.d.ts +2 -1
  10. package/dist/cjs/cache/classes/ImageVolume.js +4 -0
  11. package/dist/cjs/cache/classes/ImageVolume.js.map +1 -1
  12. package/dist/cjs/types/IContourSet.d.ts +1 -0
  13. package/dist/esm/RenderingEngine/BaseVolumeViewport.js +18 -19
  14. package/dist/esm/RenderingEngine/BaseVolumeViewport.js.map +1 -1
  15. package/dist/esm/RenderingEngine/vtkClasses/vtkStreamingOpenGLVolumeMapper.js.map +1 -1
  16. package/dist/esm/cache/cache.js +1 -1
  17. package/dist/esm/cache/cache.js.map +1 -1
  18. package/dist/esm/cache/classes/ContourSet.d.ts +5 -0
  19. package/dist/esm/cache/classes/ContourSet.js +32 -0
  20. package/dist/esm/cache/classes/ContourSet.js.map +1 -1
  21. package/dist/esm/cache/classes/ImageVolume.d.ts +2 -1
  22. package/dist/esm/cache/classes/ImageVolume.js +4 -0
  23. package/dist/esm/cache/classes/ImageVolume.js.map +1 -1
  24. package/dist/esm/types/IContourSet.d.ts +1 -0
  25. package/dist/umd/index.js +1 -1
  26. package/dist/umd/index.js.map +1 -1
  27. package/package.json +2 -2
  28. package/src/RenderingEngine/BaseVolumeViewport.ts +23 -22
  29. package/src/RenderingEngine/vtkClasses/vtkStreamingOpenGLVolumeMapper.js +12 -0
  30. package/src/cache/cache.ts +1 -1
  31. package/src/cache/classes/ContourSet.ts +55 -1
  32. package/src/cache/classes/ImageVolume.ts +7 -1
  33. package/src/types/IContourSet.ts +2 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cornerstonejs/core",
3
- "version": "0.40.0",
3
+ "version": "0.41.0",
4
4
  "description": "",
5
5
  "main": "dist/umd/index.js",
6
6
  "types": "dist/esm/index.d.ts",
@@ -51,5 +51,5 @@
51
51
  "type": "individual",
52
52
  "url": "https://ohif.org/donate"
53
53
  },
54
- "gitHead": "b21acf448f3b24c4ff109da5208bc313c0289b81"
54
+ "gitHead": "91c274e60d136f3470eace8c04bf2216df0a06ed"
55
55
  }
@@ -309,27 +309,26 @@ abstract class BaseVolumeViewport extends Viewport implements IVolumeViewport {
309
309
  * @returns viewport properties including voi, interpolation type: TODO: slabThickness, invert, rotation, flip
310
310
  */
311
311
  public getProperties = (): VolumeViewportProperties => {
312
- const actorEntries = this.getActors();
313
- const voiRanges = actorEntries.map((actorEntry) => {
314
- const volumeActor = actorEntry.actor as vtkVolume;
315
- const volumeId = actorEntry.uid;
316
- const cfun = volumeActor.getProperty().getRGBTransferFunction(0);
317
- let lower, upper;
318
- if (this.VOILUTFunction === 'SIGMOID') {
319
- [lower, upper] = getVoiFromSigmoidRGBTransferFunction(cfun);
320
- } else {
321
- // @ts-ignore: vtk d ts problem
322
- [lower, upper] = cfun.getRange();
323
- }
324
- return {
325
- volumeId,
326
- voiRange: { lower, upper },
327
- };
328
- });
329
- return {
330
- voiRange: voiRanges[0].voiRange, // TODO: handle multiple actors instead of just first.
331
- VOILUTFunction: this.VOILUTFunction,
332
- };
312
+ const voiRanges = this.getActors()
313
+ .map((actorEntry) => {
314
+ const volumeActor = actorEntry.actor as vtkVolume;
315
+ const volumeId = actorEntry.uid;
316
+ const volume = cache.getVolume(volumeId);
317
+ if (!volume) return null;
318
+ const cfun = volumeActor.getProperty().getRGBTransferFunction(0);
319
+ const [lower, upper] =
320
+ this.VOILUTFunction === 'SIGMOID'
321
+ ? getVoiFromSigmoidRGBTransferFunction(cfun)
322
+ : // @ts-ignore
323
+ cfun.getRange();
324
+ return { volumeId, voiRange: { lower, upper } };
325
+ })
326
+ .filter(Boolean);
327
+
328
+ const voiRange = voiRanges.length ? voiRanges[0].voiRange : null;
329
+ const VOILUTFunction = this.VOILUTFunction;
330
+
331
+ return { voiRange, VOILUTFunction };
333
332
  };
334
333
 
335
334
  /**
@@ -599,7 +598,9 @@ abstract class BaseVolumeViewport extends Viewport implements IVolumeViewport {
599
598
  spacing: vtkImageData.getSpacing(),
600
599
  origin: vtkImageData.getOrigin(),
601
600
  direction: vtkImageData.getDirection(),
602
- scalarData: vtkImageData.getPointData().getScalars().getData(),
601
+ scalarData: vtkImageData.getPointData().getScalars().isDeleted()
602
+ ? null
603
+ : vtkImageData.getPointData().getScalars().getData(),
603
604
  imageData: actor.getMapper().getInputData(),
604
605
  metadata: {
605
606
  Modality: volume?.metadata?.Modality,
@@ -285,6 +285,18 @@ function vtkStreamingOpenGLVolumeMapper(publicAPI, model) {
285
285
 
286
286
  return [lowerLeftU, lowerLeftV];
287
287
  };
288
+
289
+ // TODO: it seems like this may be needed to reset the GPU memory associated
290
+ // with a volume
291
+ // publicAPI.hardReset = () => {
292
+ // model.opacityTexture.releaseGraphicsResources(model._openGLRenderWindow);
293
+ // model.colorTexture.releaseGraphicsResources(model._openGLRenderWindow);
294
+ // model.scalarTexture.setOglNorm16Ext(
295
+ // model.context.getExtension('EXT_texture_norm16')
296
+ // );
297
+ // model.scalarTexture.releaseGraphicsResources(model._openGLRenderWindow);
298
+ // model.scalarTexture.resetFormatAndType();
299
+ // };
288
300
  }
289
301
 
290
302
  // ----------------------------------------------------------------------------
@@ -133,7 +133,7 @@ class Cache implements ICache {
133
133
  }
134
134
 
135
135
  if (volume.imageData) {
136
- volume.imageData = null;
136
+ volume.imageData.delete();
137
137
  }
138
138
 
139
139
  if (volumeLoadObject.cancelFn) {
@@ -1,3 +1,4 @@
1
+ import vtkPolyData from '@kitware/vtk.js/Common/DataModel/PolyData';
1
2
  import { Point3, IContourSet, IContour, ContourData } from '../../types';
2
3
  import Contour from './Contour';
3
4
 
@@ -19,6 +20,8 @@ export class ContourSet implements IContourSet {
19
20
  readonly frameOfReferenceUID: string;
20
21
  private color: Point3 = [200, 0, 0]; // default color
21
22
  private segmentIndex: number;
23
+ private polyData: vtkPolyData;
24
+ private centroid: Point3;
22
25
  contours: IContour[];
23
26
 
24
27
  constructor(props: ContourSetProps) {
@@ -27,7 +30,6 @@ export class ContourSet implements IContourSet {
27
30
  this.color = props.color ?? this.color;
28
31
  this.frameOfReferenceUID = props.frameOfReferenceUID;
29
32
  this.segmentIndex = props.segmentIndex;
30
-
31
33
  this._createEachContour(props.data);
32
34
  this.sizeInBytes = this._getSizeInBytes();
33
35
  }
@@ -50,6 +52,47 @@ export class ContourSet implements IContourSet {
50
52
 
51
53
  this.contours.push(contour);
52
54
  });
55
+
56
+ this._updateContourSetCentroid();
57
+ }
58
+
59
+ // Todo: this centroid calculation has limitation in which
60
+ // it will not work for MPR, the reason is that we are finding
61
+ // the centroid of all points but at the end we are picking the
62
+ // closest point to the centroid, which will not work for MPR
63
+ // The reason for picking the closest is a rendering issue since
64
+ // the centroid can be not exactly in the middle of the slice
65
+ // and it might cause the contour to be rendered in the wrong slice
66
+ // or not rendered at all
67
+ _updateContourSetCentroid(): void {
68
+ const numberOfPoints = this.getTotalNumberOfPoints();
69
+ const flatPointsArray = this.getFlatPointsArray();
70
+
71
+ const sumOfPoints = flatPointsArray.reduce(
72
+ (acc, point) => {
73
+ return [acc[0] + point[0], acc[1] + point[1], acc[2] + point[2]];
74
+ },
75
+ [0, 0, 0]
76
+ );
77
+
78
+ const centroid = [
79
+ sumOfPoints[0] / numberOfPoints,
80
+ sumOfPoints[1] / numberOfPoints,
81
+ sumOfPoints[2] / numberOfPoints,
82
+ ];
83
+
84
+ const closestPoint = flatPointsArray.reduce((closestPoint, point) => {
85
+ const distanceToPoint = this._getDistance(centroid, point);
86
+ const distanceToClosestPoint = this._getDistance(centroid, closestPoint);
87
+
88
+ if (distanceToPoint < distanceToClosestPoint) {
89
+ return point;
90
+ } else {
91
+ return closestPoint;
92
+ }
93
+ }, flatPointsArray[0]);
94
+
95
+ this.centroid = closestPoint;
53
96
  }
54
97
 
55
98
  _getSizeInBytes(): number {
@@ -58,6 +101,10 @@ export class ContourSet implements IContourSet {
58
101
  }, 0);
59
102
  }
60
103
 
104
+ public getCentroid(): Point3 {
105
+ return this.centroid;
106
+ }
107
+
61
108
  public getSegmentIndex(): number {
62
109
  return this.segmentIndex;
63
110
  }
@@ -138,6 +185,13 @@ export class ContourSet implements IContourSet {
138
185
  return this.getPointsInContour(contourIndex).length;
139
186
  }
140
187
 
188
+ private _getDistance(pointA, pointB) {
189
+ return Math.sqrt(
190
+ (pointA[0] - pointB[0]) ** 2 +
191
+ (pointA[1] - pointB[1]) ** 2 +
192
+ (pointA[2] - pointB[2]) ** 2
193
+ );
194
+ }
141
195
  /**
142
196
  public convertToClosedSurface(): ClosedSurface {
143
197
  const flatPointsArray = this.getFlatPointsArray();
@@ -1,6 +1,7 @@
1
1
  import isTypedArray from '../../utilities/isTypedArray';
2
2
  import { imageIdToURI } from '../../utilities';
3
3
  import { vtkStreamingOpenGLTexture } from '../../RenderingEngine/vtkClasses';
4
+ import type { vtkImageData } from '@kitware/vtk.js/Common/DataModel/ImageData';
4
5
  import {
5
6
  IVolume,
6
7
  VolumeScalarData,
@@ -50,7 +51,7 @@ export class ImageVolume implements IImageVolume {
50
51
  /** volume number of voxels */
51
52
  numVoxels: number;
52
53
  /** volume image data */
53
- imageData?: any;
54
+ imageData?: vtkImageData;
54
55
  /** open gl texture for the volume */
55
56
  vtkOpenGLTexture: any; // No good way of referencing vtk classes as they aren't classes.
56
57
  /** load status object for the volume */
@@ -147,7 +148,12 @@ export class ImageVolume implements IImageVolume {
147
148
  * destroy the volume and make it unusable
148
149
  */
149
150
  destroy(): void {
151
+ // TODO: GPU memory associated with volume is not cleared.
152
+ this.vtkOpenGLTexture.releaseGraphicsResources();
153
+ this.vtkOpenGLTexture.destroyTexture();
150
154
  this.vtkOpenGLTexture.delete();
155
+ this.imageData.delete();
156
+ this.imageData = null;
151
157
  this.scalarData = null;
152
158
  }
153
159
  }
@@ -1,3 +1,4 @@
1
+ import vtkPolyData from '@kitware/vtk.js/Common/DataModel/PolyData';
1
2
  import { ContourData, IContour, Point3 } from './';
2
3
 
3
4
  /**
@@ -12,6 +13,7 @@ export interface IContourSet {
12
13
  _createEachContour(data: ContourData[]): void;
13
14
  getSizeInBytes(): number;
14
15
  getSegmentIndex(): number;
16
+ getCentroid(): Point3;
15
17
  getColor(): any;
16
18
  /**
17
19
  * This function returns the contours of the image