Revert "fix(measurement): fix for measurement jump is not switching series in 2DMPR (#4779)" (#4898)

This commit is contained in:
Alireza 2025-03-28 10:17:33 -04:00 committed by GitHub
parent 3f06c966eb
commit eafa2efda5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 26 additions and 100 deletions

View File

@ -264,10 +264,11 @@ const OHIFCornerstoneViewport = React.memo(
const presentations = getViewportPresentations(viewportId, viewportOptions);
let measurement;
if (cacheJumpToMeasurementEvent?.cornerstoneViewport === viewportId) {
if (cacheJumpToMeasurementEvent?.viewportId === viewportId) {
measurement = cacheJumpToMeasurementEvent.measurement;
// Delete the position presentation so that viewport navigates direct
presentations.positionPresentation = null;
cacheJumpToMeasurementEvent = null;
}
// 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;
}
await cornerstoneViewportService.setViewportData(
cornerstoneViewportService.setViewportData(
viewportId,
viewportData,
viewportOptions,
@ -289,13 +290,7 @@ const OHIFCornerstoneViewport = React.memo(
);
if (measurement) {
_checkForCachedJumpToMeasurementEvents(
elementRef,
viewportId,
displaySets,
servicesManager
);
cacheJumpToMeasurementEvent = null;
cs3DTools.annotation.selection.setAnnotationSelected(measurement.uid);
}
};
@ -323,6 +318,8 @@ const OHIFCornerstoneViewport = React.memo(
servicesManager
);
_checkForCachedJumpToMeasurementEvents(elementRef, viewportId, displaySets, servicesManager);
return () => {
unsubscribeFromJumpToMeasurementEvents();
};
@ -454,16 +451,6 @@ function _subscribeToJumpToMeasurementEvents(elementRef, viewportId, servicesMan
if (cacheJumpToMeasurementEvent.cornerstoneViewport !== viewportId) {
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);
}
);

View File

@ -372,7 +372,7 @@ class CornerstoneViewportService extends PubSubService implements IViewportServi
* @param publicDisplaySetOptions - The public display set options.
* @param presentations - The presentations to set.
*/
public async setViewportData(
public setViewportData(
viewportId: string,
viewportData: StackViewportData | VolumeViewportData,
publicViewportOptions: PublicViewportOptions,
@ -458,14 +458,21 @@ class CornerstoneViewportService extends PubSubService implements IViewportServi
this.viewportsById.set(viewportId, viewportInfo);
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
// viewport to access. Doing it too early can result in exceptions or
// invalid data.
this._broadcastEvent(this.EVENTS.VIEWPORT_DATA_CHANGED, {
viewportData,
viewportId,
displaySetPromise.then(() => {
this._broadcastEvent(this.EVENTS.VIEWPORT_DATA_CHANGED, {
viewportData,
viewportId,
});
});
}

View File

@ -6,7 +6,6 @@ import { useViewportGrid } from '@ohif/ui-next';
import EmptyViewport from './EmptyViewport';
import classNames from 'classnames';
import { useAppConfig } from '@state';
import getClosestOrientationFromIOP from '../utils/getClosestOrientationFromIOP';
function ViewerViewportGrid(props: withAppTypes) {
const { servicesManager, viewportComponents = [], dataSource } = props;
@ -178,20 +177,7 @@ function ViewerViewportGrid(props: withAppTypes) {
const { displaySetInstanceUID: referencedDisplaySetInstanceUID } = measurement;
const updatedViewports = _getUpdatedViewports(viewportId, referencedDisplaySetInstanceUID);
let viewportToUpdate;
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) {
if (!updatedViewports[0]) {
console.warn(
'ViewportGrid::Unable to navigate to viewport containing',
referencedDisplaySetInstanceUID
@ -199,9 +185,14 @@ function ViewerViewportGrid(props: withAppTypes) {
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
viewportToUpdate.viewportOptions = {
...viewportToUpdate.viewportOptions,
viewport.viewportOptions = {
...viewport.viewportOptions,
orientation: 'acquisition',
// 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 File

@ -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;
}