@cornerstonejs/core 4.15.32 → 4.16.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.
@@ -1,5 +1,6 @@
1
1
  import type { mat4 } from 'gl-matrix';
2
- import type { BlendModes, InterpolationType, OrientationAxis } from '../enums';
2
+ import type { BlendModes, InterpolationType } from '../enums';
3
+ import { OrientationAxis } from '../enums';
3
4
  import type { FlipDirection, IImageData, IVolumeInput, OrientationVectors, Point2, Point3, VolumeViewportProperties, ViewReferenceSpecifier, ReferenceCompatibleOptions, ViewReference, ICamera } from '../types';
4
5
  import type { VoiModifiedEventDetail } from '../types/EventTypes';
5
6
  import type { PlaneRestriction, ViewportInput } from '../types/IViewport';
@@ -4,7 +4,7 @@ import vtkPiecewiseFunction from '@kitware/vtk.js/Common/DataModel/PiecewiseFunc
4
4
  import { vec2, vec3 } from 'gl-matrix';
5
5
  import cache from '../cache/cache';
6
6
  import { MPR_CAMERA_VALUES, RENDERING_DEFAULTS, VIEWPORT_PRESETS, } from '../constants';
7
- import { Events, MetadataModules, ViewportStatus, VOILUTFunctionType, } from '../enums';
7
+ import { Events, MetadataModules, OrientationAxis, ViewportStatus, VOILUTFunctionType, } from '../enums';
8
8
  import ViewportType from '../enums/ViewportType';
9
9
  import eventTarget from '../eventTarget';
10
10
  import { getShouldUseCPURendering } from '../init';
@@ -1116,21 +1116,38 @@ class BaseVolumeViewport extends Viewport {
1116
1116
  }
1117
1117
  }
1118
1118
  else if (typeof orientation === 'string') {
1119
- if (orientation === 'acquisition') {
1119
+ if (orientation === OrientationAxis.ACQUISITION) {
1120
1120
  return this._getAcquisitionPlaneOrientation();
1121
1121
  }
1122
- else if (orientation === 'reformat' ||
1123
- orientation.includes('_reformat')) {
1122
+ else if (orientation === OrientationAxis.REFORMAT) {
1124
1123
  return getCameraVectors(this, {
1125
1124
  useViewportNormal: true,
1126
1125
  });
1127
1126
  }
1127
+ else if (orientation === OrientationAxis.AXIAL_REFORMAT ||
1128
+ orientation === OrientationAxis.SAGITTAL_REFORMAT ||
1129
+ orientation === OrientationAxis.CORONAL_REFORMAT) {
1130
+ let baseOrientation;
1131
+ if (orientation === OrientationAxis.AXIAL_REFORMAT) {
1132
+ baseOrientation = OrientationAxis.AXIAL;
1133
+ }
1134
+ else if (orientation === OrientationAxis.SAGITTAL_REFORMAT) {
1135
+ baseOrientation = OrientationAxis.SAGITTAL;
1136
+ }
1137
+ else {
1138
+ baseOrientation = OrientationAxis.CORONAL;
1139
+ }
1140
+ return getCameraVectors(this, {
1141
+ useViewportNormal: true,
1142
+ orientation: baseOrientation,
1143
+ });
1144
+ }
1128
1145
  else if (MPR_CAMERA_VALUES[orientation]) {
1129
1146
  this.viewportProperties.orientation = orientation;
1130
1147
  return MPR_CAMERA_VALUES[orientation];
1131
1148
  }
1132
1149
  }
1133
- throw new Error(`Invalid orientation: ${orientation}. Valid orientations are: ${Object.keys(MPR_CAMERA_VALUES).join(', ')}`);
1150
+ throw new Error(`Invalid orientation: ${orientation}. Valid orientations are: ${Object.keys(MPR_CAMERA_VALUES).join(', ')}, ${OrientationAxis.ACQUISITION}, ${OrientationAxis.REFORMAT}, ${OrientationAxis.AXIAL_REFORMAT}, ${OrientationAxis.SAGITTAL_REFORMAT}, ${OrientationAxis.CORONAL_REFORMAT}`);
1134
1151
  }
1135
1152
  _getAcquisitionPlaneOrientation() {
1136
1153
  const actorEntry = this.getDefaultActor();
@@ -161,12 +161,29 @@ class VolumeViewport extends BaseVolumeViewport {
161
161
  if (orientation === OrientationAxis.ACQUISITION) {
162
162
  ({ viewPlaneNormal, viewUp } = super._getAcquisitionPlaneOrientation());
163
163
  }
164
- else if (orientation === OrientationAxis.REFORMAT ||
165
- orientation.includes('_reformat')) {
164
+ else if (orientation === OrientationAxis.REFORMAT) {
166
165
  ({ viewPlaneNormal, viewUp } = getCameraVectors(this, {
167
166
  useViewportNormal: true,
168
167
  }));
169
168
  }
169
+ else if (orientation === OrientationAxis.AXIAL_REFORMAT ||
170
+ orientation === OrientationAxis.SAGITTAL_REFORMAT ||
171
+ orientation === OrientationAxis.CORONAL_REFORMAT) {
172
+ let baseOrientation;
173
+ if (orientation === OrientationAxis.AXIAL_REFORMAT) {
174
+ baseOrientation = OrientationAxis.AXIAL;
175
+ }
176
+ else if (orientation === OrientationAxis.SAGITTAL_REFORMAT) {
177
+ baseOrientation = OrientationAxis.SAGITTAL;
178
+ }
179
+ else {
180
+ baseOrientation = OrientationAxis.CORONAL;
181
+ }
182
+ ({ viewPlaneNormal, viewUp } = getCameraVectors(this, {
183
+ useViewportNormal: true,
184
+ orientation: baseOrientation,
185
+ }));
186
+ }
170
187
  else if (MPR_CAMERA_VALUES[orientation]) {
171
188
  ({ viewPlaneNormal, viewUp } = MPR_CAMERA_VALUES[orientation]);
172
189
  }
@@ -178,7 +195,7 @@ class VolumeViewport extends BaseVolumeViewport {
178
195
  viewUp,
179
196
  });
180
197
  this.viewportProperties.orientation = orientation;
181
- this.resetCamera();
198
+ this.resetCamera({ suppressEvents: true });
182
199
  }
183
200
  else {
184
201
  ({ viewPlaneNormal, viewUp } = orientation);
@@ -1,5 +1,6 @@
1
1
  import * as Enums from '../../enums';
2
2
  import type * as Types from '../../types';
3
+ import type OrientationVectors from '../../types/OrientationVectors';
3
4
  import { vec3 } from 'gl-matrix';
4
5
  export interface CameraPositionConfig {
5
6
  orientation?: Enums.OrientationAxis;
@@ -16,3 +17,4 @@ export declare function getCameraVectors(viewport: Types.IBaseVolumeViewport, co
16
17
  viewRight: [number, number, number];
17
18
  };
18
19
  export declare function getOrientationFromScanAxisNormal(scanAxisNormal: vec3): Enums.OrientationAxis;
20
+ export declare function getAcquisitionPlaneReformatOrientation(imageOrientationPatient: number[]): OrientationVectors | null;
@@ -19,6 +19,22 @@ export function calculateCameraPosition(rowCosineVec, colCosineVec, scanAxisNorm
19
19
  case OrientationAxis.CORONAL_REFORMAT:
20
20
  referenceCameraValues = MPR_CAMERA_VALUES.coronal;
21
21
  break;
22
+ case OrientationAxis.REFORMAT:
23
+ const autoDetected = getOrientationFromScanAxisNormal(scanAxisNormal);
24
+ switch (autoDetected) {
25
+ case OrientationAxis.AXIAL:
26
+ referenceCameraValues = MPR_CAMERA_VALUES.axial;
27
+ break;
28
+ case OrientationAxis.SAGITTAL:
29
+ referenceCameraValues = MPR_CAMERA_VALUES.sagittal;
30
+ break;
31
+ case OrientationAxis.CORONAL:
32
+ referenceCameraValues = MPR_CAMERA_VALUES.coronal;
33
+ break;
34
+ default:
35
+ referenceCameraValues = MPR_CAMERA_VALUES.axial;
36
+ }
37
+ break;
22
38
  default:
23
39
  referenceCameraValues = MPR_CAMERA_VALUES.axial;
24
40
  break;
@@ -97,7 +113,7 @@ export function getCameraVectors(viewport, config) {
97
113
  if (useViewportNormal) {
98
114
  normalPlaneForOrientation = viewport.getCamera().viewPlaneNormal;
99
115
  }
100
- if (!orientation) {
116
+ if (!orientation || orientation === OrientationAxis.REFORMAT) {
101
117
  orientation = getOrientationFromScanAxisNormal(normalPlaneForOrientation);
102
118
  }
103
119
  return calculateCameraPosition(rowCosineVec, colCosineVec, scanAxisNormal, orientation);
@@ -120,3 +136,100 @@ export function getOrientationFromScanAxisNormal(scanAxisNormal) {
120
136
  return OrientationAxis.CORONAL;
121
137
  }
122
138
  }
139
+ export function getAcquisitionPlaneReformatOrientation(imageOrientationPatient) {
140
+ if (!imageOrientationPatient || imageOrientationPatient.length !== 6) {
141
+ return null;
142
+ }
143
+ const rowVec = vec3.fromValues(imageOrientationPatient[0], imageOrientationPatient[1], imageOrientationPatient[2]);
144
+ const colVec = vec3.fromValues(imageOrientationPatient[3], imageOrientationPatient[4], imageOrientationPatient[5]);
145
+ const scanAxisNormal = vec3.create();
146
+ vec3.cross(scanAxisNormal, rowVec, colVec);
147
+ vec3.normalize(rowVec, rowVec);
148
+ vec3.normalize(colVec, colVec);
149
+ vec3.normalize(scanAxisNormal, scanAxisNormal);
150
+ const negRowVec = vec3.create();
151
+ vec3.negate(negRowVec, rowVec);
152
+ const negColVec = vec3.create();
153
+ vec3.negate(negColVec, colVec);
154
+ const negScanAxisNormal = vec3.create();
155
+ vec3.negate(negScanAxisNormal, scanAxisNormal);
156
+ const acquisitionVectors = [
157
+ { vec: rowVec, name: 'row' },
158
+ { vec: colVec, name: 'col' },
159
+ { vec: scanAxisNormal, name: 'scanAxis' },
160
+ { vec: negRowVec, name: '-row' },
161
+ { vec: negColVec, name: '-col' },
162
+ { vec: negScanAxisNormal, name: '-scanAxis' },
163
+ ];
164
+ const standardViews = [
165
+ {
166
+ name: 'axial',
167
+ viewPlaneNormal: vec3.fromValues(MPR_CAMERA_VALUES.axial.viewPlaneNormal[0], MPR_CAMERA_VALUES.axial.viewPlaneNormal[1], MPR_CAMERA_VALUES.axial.viewPlaneNormal[2]),
168
+ viewUp: vec3.fromValues(MPR_CAMERA_VALUES.axial.viewUp[0], MPR_CAMERA_VALUES.axial.viewUp[1], MPR_CAMERA_VALUES.axial.viewUp[2]),
169
+ },
170
+ {
171
+ name: 'sagittal',
172
+ viewPlaneNormal: vec3.fromValues(MPR_CAMERA_VALUES.sagittal.viewPlaneNormal[0], MPR_CAMERA_VALUES.sagittal.viewPlaneNormal[1], MPR_CAMERA_VALUES.sagittal.viewPlaneNormal[2]),
173
+ viewUp: vec3.fromValues(MPR_CAMERA_VALUES.sagittal.viewUp[0], MPR_CAMERA_VALUES.sagittal.viewUp[1], MPR_CAMERA_VALUES.sagittal.viewUp[2]),
174
+ },
175
+ {
176
+ name: 'coronal',
177
+ viewPlaneNormal: vec3.fromValues(MPR_CAMERA_VALUES.coronal.viewPlaneNormal[0], MPR_CAMERA_VALUES.coronal.viewPlaneNormal[1], MPR_CAMERA_VALUES.coronal.viewPlaneNormal[2]),
178
+ viewUp: vec3.fromValues(MPR_CAMERA_VALUES.coronal.viewUp[0], MPR_CAMERA_VALUES.coronal.viewUp[1], MPR_CAMERA_VALUES.coronal.viewUp[2]),
179
+ },
180
+ ];
181
+ let bestAlignment = -Infinity;
182
+ let bestViewPlaneNormal = null;
183
+ let bestViewUp = null;
184
+ for (const standardView of standardViews) {
185
+ let bestPairScore = -Infinity;
186
+ let bestPairViewPlaneNormal = null;
187
+ let bestPairViewUp = null;
188
+ for (let i = 0; i < acquisitionVectors.length; i++) {
189
+ for (let j = 0; j < acquisitionVectors.length; j++) {
190
+ if (i === j)
191
+ continue;
192
+ const v1 = acquisitionVectors[i].vec;
193
+ const v2 = acquisitionVectors[j].vec;
194
+ const dotProduct = Math.abs(vec3.dot(v1, v2));
195
+ if (dotProduct > 0.1)
196
+ continue;
197
+ const score1 = Math.abs(vec3.dot(v1, standardView.viewPlaneNormal));
198
+ const score2 = Math.abs(vec3.dot(v2, standardView.viewUp));
199
+ const totalScore = score1 + score2;
200
+ const score1Swapped = Math.abs(vec3.dot(v2, standardView.viewPlaneNormal));
201
+ const score2Swapped = Math.abs(vec3.dot(v1, standardView.viewUp));
202
+ const totalScoreSwapped = score1Swapped + score2Swapped;
203
+ if (totalScoreSwapped > totalScore &&
204
+ totalScoreSwapped > bestPairScore) {
205
+ bestPairScore = totalScoreSwapped;
206
+ bestPairViewPlaneNormal = v2;
207
+ bestPairViewUp = v1;
208
+ }
209
+ else if (totalScore > bestPairScore) {
210
+ bestPairScore = totalScore;
211
+ bestPairViewPlaneNormal = v1;
212
+ bestPairViewUp = v2;
213
+ }
214
+ }
215
+ }
216
+ if (bestPairScore > bestAlignment &&
217
+ bestPairViewPlaneNormal &&
218
+ bestPairViewUp) {
219
+ bestAlignment = bestPairScore;
220
+ bestViewPlaneNormal = bestPairViewPlaneNormal;
221
+ bestViewUp = bestPairViewUp;
222
+ }
223
+ }
224
+ if (!bestViewPlaneNormal || !bestViewUp) {
225
+ return null;
226
+ }
227
+ return {
228
+ viewPlaneNormal: [
229
+ bestViewPlaneNormal[0],
230
+ bestViewPlaneNormal[1],
231
+ bestViewPlaneNormal[2],
232
+ ],
233
+ viewUp: [bestViewUp[0], bestViewUp[1], bestViewUp[2]],
234
+ };
235
+ }
@@ -1 +1 @@
1
- export declare const version = "4.15.32";
1
+ export declare const version = "4.16.0";
@@ -1 +1 @@
1
- export const version = '4.15.32';
1
+ export const version = '4.16.0';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cornerstonejs/core",
3
- "version": "4.15.32",
3
+ "version": "4.16.0",
4
4
  "description": "Cornerstone3D Core",
5
5
  "module": "./dist/esm/index.js",
6
6
  "types": "./dist/esm/index.d.ts",
@@ -97,5 +97,5 @@
97
97
  "type": "individual",
98
98
  "url": "https://ohif.org/donate"
99
99
  },
100
- "gitHead": "05646c9490e54ad3841b1d6891d8cbdf73a2fd19"
100
+ "gitHead": "894fe3bebbbaae27c5aa58b758616988ba173ee3"
101
101
  }