Revert "fix(measurement): fix for measurement jump is not switching series in 2DMPR (#4779)" (#4898)
This commit is contained in:
parent
3f06c966eb
commit
eafa2efda5
@ -264,10 +264,11 @@ const OHIFCornerstoneViewport = React.memo(
|
|||||||
const presentations = getViewportPresentations(viewportId, viewportOptions);
|
const presentations = getViewportPresentations(viewportId, viewportOptions);
|
||||||
|
|
||||||
let measurement;
|
let measurement;
|
||||||
if (cacheJumpToMeasurementEvent?.cornerstoneViewport === viewportId) {
|
if (cacheJumpToMeasurementEvent?.viewportId === viewportId) {
|
||||||
measurement = cacheJumpToMeasurementEvent.measurement;
|
measurement = cacheJumpToMeasurementEvent.measurement;
|
||||||
// Delete the position presentation so that viewport navigates direct
|
// Delete the position presentation so that viewport navigates direct
|
||||||
presentations.positionPresentation = null;
|
presentations.positionPresentation = null;
|
||||||
|
cacheJumpToMeasurementEvent = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note: This is a hack to get the grid to re-render the OHIFCornerstoneViewport component
|
// Note: This is a hack to get the grid to re-render the OHIFCornerstoneViewport component
|
||||||
@ -280,7 +281,7 @@ const OHIFCornerstoneViewport = React.memo(
|
|||||||
viewportOptions.needsRerendering = false;
|
viewportOptions.needsRerendering = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
await cornerstoneViewportService.setViewportData(
|
cornerstoneViewportService.setViewportData(
|
||||||
viewportId,
|
viewportId,
|
||||||
viewportData,
|
viewportData,
|
||||||
viewportOptions,
|
viewportOptions,
|
||||||
@ -289,13 +290,7 @@ const OHIFCornerstoneViewport = React.memo(
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (measurement) {
|
if (measurement) {
|
||||||
_checkForCachedJumpToMeasurementEvents(
|
cs3DTools.annotation.selection.setAnnotationSelected(measurement.uid);
|
||||||
elementRef,
|
|
||||||
viewportId,
|
|
||||||
displaySets,
|
|
||||||
servicesManager
|
|
||||||
);
|
|
||||||
cacheJumpToMeasurementEvent = null;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -323,6 +318,8 @@ const OHIFCornerstoneViewport = React.memo(
|
|||||||
servicesManager
|
servicesManager
|
||||||
);
|
);
|
||||||
|
|
||||||
|
_checkForCachedJumpToMeasurementEvents(elementRef, viewportId, displaySets, servicesManager);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
unsubscribeFromJumpToMeasurementEvents();
|
unsubscribeFromJumpToMeasurementEvents();
|
||||||
};
|
};
|
||||||
@ -454,16 +451,6 @@ function _subscribeToJumpToMeasurementEvents(elementRef, viewportId, servicesMan
|
|||||||
if (cacheJumpToMeasurementEvent.cornerstoneViewport !== viewportId) {
|
if (cacheJumpToMeasurementEvent.cornerstoneViewport !== viewportId) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const viewportInfo = cornerstoneViewportService.getViewportInfo(viewportId);
|
|
||||||
// Confirm viewportInfo matches measurement displaySetInstanceUID and referencedImageId
|
|
||||||
if (
|
|
||||||
!viewportInfo?.contains(
|
|
||||||
measurement.displaySetInstanceUID,
|
|
||||||
measurement.referencedImageId || measurement.metadata?.referencedImageId
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
_jumpToMeasurement(measurement, elementRef, viewportId, servicesManager);
|
_jumpToMeasurement(measurement, elementRef, viewportId, servicesManager);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|||||||
@ -372,7 +372,7 @@ class CornerstoneViewportService extends PubSubService implements IViewportServi
|
|||||||
* @param publicDisplaySetOptions - The public display set options.
|
* @param publicDisplaySetOptions - The public display set options.
|
||||||
* @param presentations - The presentations to set.
|
* @param presentations - The presentations to set.
|
||||||
*/
|
*/
|
||||||
public async setViewportData(
|
public setViewportData(
|
||||||
viewportId: string,
|
viewportId: string,
|
||||||
viewportData: StackViewportData | VolumeViewportData,
|
viewportData: StackViewportData | VolumeViewportData,
|
||||||
publicViewportOptions: PublicViewportOptions,
|
publicViewportOptions: PublicViewportOptions,
|
||||||
@ -458,15 +458,22 @@ class CornerstoneViewportService extends PubSubService implements IViewportServi
|
|||||||
this.viewportsById.set(viewportId, viewportInfo);
|
this.viewportsById.set(viewportId, viewportInfo);
|
||||||
|
|
||||||
const viewport = renderingEngine.getViewport(viewportId);
|
const viewport = renderingEngine.getViewport(viewportId);
|
||||||
await this._setDisplaySets(viewport, viewportData, viewportInfo, presentations);
|
const displaySetPromise = this._setDisplaySets(
|
||||||
|
viewport,
|
||||||
|
viewportData,
|
||||||
|
viewportInfo,
|
||||||
|
presentations
|
||||||
|
);
|
||||||
|
|
||||||
// The broadcast event here ensures that listeners have a valid, up to date
|
// The broadcast event here ensures that listeners have a valid, up to date
|
||||||
// viewport to access. Doing it too early can result in exceptions or
|
// viewport to access. Doing it too early can result in exceptions or
|
||||||
// invalid data.
|
// invalid data.
|
||||||
|
displaySetPromise.then(() => {
|
||||||
this._broadcastEvent(this.EVENTS.VIEWPORT_DATA_CHANGED, {
|
this._broadcastEvent(this.EVENTS.VIEWPORT_DATA_CHANGED, {
|
||||||
viewportData,
|
viewportData,
|
||||||
viewportId,
|
viewportId,
|
||||||
});
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -6,7 +6,6 @@ import { useViewportGrid } from '@ohif/ui-next';
|
|||||||
import EmptyViewport from './EmptyViewport';
|
import EmptyViewport from './EmptyViewport';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { useAppConfig } from '@state';
|
import { useAppConfig } from '@state';
|
||||||
import getClosestOrientationFromIOP from '../utils/getClosestOrientationFromIOP';
|
|
||||||
|
|
||||||
function ViewerViewportGrid(props: withAppTypes) {
|
function ViewerViewportGrid(props: withAppTypes) {
|
||||||
const { servicesManager, viewportComponents = [], dataSource } = props;
|
const { servicesManager, viewportComponents = [], dataSource } = props;
|
||||||
@ -178,20 +177,7 @@ function ViewerViewportGrid(props: withAppTypes) {
|
|||||||
const { displaySetInstanceUID: referencedDisplaySetInstanceUID } = measurement;
|
const { displaySetInstanceUID: referencedDisplaySetInstanceUID } = measurement;
|
||||||
|
|
||||||
const updatedViewports = _getUpdatedViewports(viewportId, referencedDisplaySetInstanceUID);
|
const updatedViewports = _getUpdatedViewports(viewportId, referencedDisplaySetInstanceUID);
|
||||||
let viewportToUpdate;
|
if (!updatedViewports[0]) {
|
||||||
if (updatedViewports.length > 1) {
|
|
||||||
// To get the viewport which orientation is closest to IOP
|
|
||||||
const closestOrientation = getClosestOrientationFromIOP(
|
|
||||||
displaySetService,
|
|
||||||
referencedDisplaySetInstanceUID
|
|
||||||
);
|
|
||||||
viewportToUpdate = updatedViewports.find(
|
|
||||||
viewport => viewport.viewportOptions?.orientation == closestOrientation
|
|
||||||
);
|
|
||||||
}
|
|
||||||
// If closest orientation viewport is not find then choose 0
|
|
||||||
viewportToUpdate = updatedViewports[0];
|
|
||||||
if (!viewportToUpdate) {
|
|
||||||
console.warn(
|
console.warn(
|
||||||
'ViewportGrid::Unable to navigate to viewport containing',
|
'ViewportGrid::Unable to navigate to viewport containing',
|
||||||
referencedDisplaySetInstanceUID
|
referencedDisplaySetInstanceUID
|
||||||
@ -199,9 +185,14 @@ function ViewerViewportGrid(props: withAppTypes) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Arbitrarily assign the viewport to element 0
|
||||||
|
// TODO - this should perform a search to find the most suitable viewport.
|
||||||
|
updatedViewports[0] = { ...updatedViewports[0] };
|
||||||
|
const [viewport] = updatedViewports;
|
||||||
|
|
||||||
// Copy the viewport options to prevent modifying the internal data
|
// Copy the viewport options to prevent modifying the internal data
|
||||||
viewportToUpdate.viewportOptions = {
|
viewport.viewportOptions = {
|
||||||
...viewportToUpdate.viewportOptions,
|
...viewport.viewportOptions,
|
||||||
orientation: 'acquisition',
|
orientation: 'acquisition',
|
||||||
// The preferred way to jump to the measurement view is to set the
|
// The preferred way to jump to the measurement view is to set the
|
||||||
// view reference, as this can hold information such as the orientation
|
// view reference, as this can hold information such as the orientation
|
||||||
|
|||||||
@ -1,59 +0,0 @@
|
|||||||
import { vec3 } from 'gl-matrix';
|
|
||||||
import { Enums } from '@cornerstonejs/core';
|
|
||||||
import OrientationAxis = Enums.OrientationAxis;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the plane (orientation) to which the ImageOrientationPatient is most closely aligned
|
|
||||||
*
|
|
||||||
* @param displaySetService
|
|
||||||
* @param displaySetInstanceUID
|
|
||||||
* @returns orientation
|
|
||||||
*/
|
|
||||||
export default function getClosestOrientationFromIOP(
|
|
||||||
displaySetService,
|
|
||||||
displaySetInstanceUID
|
|
||||||
): OrientationAxis {
|
|
||||||
const displaySet = displaySetService.getDisplaySetByUID(displaySetInstanceUID);
|
|
||||||
const imageOrientationPatient = displaySet.instances[0].ImageOrientationPatient as Array<number>;
|
|
||||||
// ImageOrientationPatient must be an array of length 6.
|
|
||||||
if (imageOrientationPatient?.length !== 6) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Take cross product to get vector coming "out" of image plane
|
|
||||||
const rowCosineVec = vec3.fromValues(
|
|
||||||
imageOrientationPatient[0],
|
|
||||||
imageOrientationPatient[1],
|
|
||||||
imageOrientationPatient[2]
|
|
||||||
);
|
|
||||||
const colCosineVec = vec3.fromValues(
|
|
||||||
imageOrientationPatient[3],
|
|
||||||
imageOrientationPatient[4],
|
|
||||||
imageOrientationPatient[5]
|
|
||||||
);
|
|
||||||
const scanAxisNormal = vec3.cross(vec3.create(), rowCosineVec, colCosineVec);
|
|
||||||
|
|
||||||
// Define the reference vectors for axial, coronal, and sagittal planes
|
|
||||||
const unitVectors = {
|
|
||||||
[OrientationAxis.AXIAL]: vec3.fromValues(0, 0, 1),
|
|
||||||
[OrientationAxis.CORONAL]: vec3.fromValues(0, 1, 0),
|
|
||||||
[OrientationAxis.SAGITTAL]: vec3.fromValues(1, 0, 0),
|
|
||||||
};
|
|
||||||
|
|
||||||
// Compute dot products for each reference plane
|
|
||||||
// Because all vectors are normalized, dot product is bounded between -1 and 1
|
|
||||||
let maxDot = 0;
|
|
||||||
let maxOrientation: string = '';
|
|
||||||
for (const [k, v] of Object.entries(unitVectors)) {
|
|
||||||
// Absolute value of dot product because we only care about alignment with the axis
|
|
||||||
// For example, dot product of -1 for a given axis means perfect alignment
|
|
||||||
// but the image is pointing in the "opposite" direction
|
|
||||||
const res = Math.abs(vec3.dot(scanAxisNormal, v));
|
|
||||||
if (res > maxDot) {
|
|
||||||
maxDot = res;
|
|
||||||
maxOrientation = k;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return maxOrientation as OrientationAxis;
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue
Block a user