feat: Add CS3D WSI and Video Viewports and add annotation navigation for MPR (#4182)

This commit is contained in:
Bill Wallace authored and GitHub committed 2024-08-15 14:36:53 -04:00
1 parent b12e0211d4
commit 7599ec9421
65 files changed
+781 -513

No files matched your search

+2
View File
@@ -35,6 +35,8 @@ const setHeaders = (res, path) => {
}
if (path.indexOf('.pdf') !== -1) {
res.setHeader('Content-Type', 'application/pdf');
} else if (path.indexOf('mp4') !== -1) {
res.setHeader('Content-Type', 'video/mp4');
} else if (path.indexOf('frames') !== -1) {
res.setHeader('Content-Type', 'multipart/related');
} else {
@@ -42,6 +42,10 @@ describe('OHIF Measurement Panel', function () {
});
it('checks if image would jump when clicked on a measurement item', function () {
cy.get('[data-cy="study-browser-thumbnail"][data-series="1"]').dblclick();
cy.wait(250);
cy.scrollToIndex(0);
// Add length measurement
cy.addLengthMeasurement().wait(250);
cy.get('[data-cy="prompt-begin-tracking-yes-btn"]').as('yesBtn').click();
+5 -4
View File
@@ -36,9 +36,9 @@ Cypress.Commands.add('openStudy', PatientName => {
cy.openStudyList();
cy.get('#filter-patientNameOrId').type(PatientName);
// cy.get('@getStudies').then(() => {
cy.waitQueryList();
// cy.waitQueryList();
cy.get('[data-cy="study-list-results"]', { timeout: 5000 })
cy.get('[data-cy="study-list-results"]', { timeout: 15000 })
.contains(PatientName)
.first()
.click({ force: true });
@@ -79,8 +79,9 @@ Cypress.Commands.add(
);
Cypress.Commands.add('waitQueryList', () => {
cy.get('[data-querying="false"]');
cy.get('[data-querying="false"]', { timeout: 15000 });
});
/**
* Command to search for a Modality and open the study.
*
@@ -109,7 +110,7 @@ Cypress.Commands.add('openStudyList', () => {
cy.visit('/', { timeout: 15000 });
// For some reason cypress 12.x does not like to stub the network request
// so we just wait here for 1 second
// so we just wait here for querying to be done.
// cy.wait('@getStudies');
cy.waitQueryList();
});
+1
View File
@@ -59,6 +59,7 @@ window.config = {
bulkDataURI: {
enabled: true,
relativeResolution: 'studies',
transform: url => url.replace('/pixeldata.mp4', '/rendered'),
},
omitQuotationForMultipartRequest: true,
},
+2
View File
@@ -44,6 +44,7 @@ window.config = {
bulkDataURI: {
enabled: true,
relativeResolution: 'studies',
transform: url => url.replace('/pixeldata.mp4', '/index.mp4'),
},
},
},
@@ -115,6 +116,7 @@ window.config = {
bulkDataURI: {
enabled: true,
relativeResolution: 'studies',
transform: url => url.replace('/pixeldata.mp4', '/rendered'),
},
},
},
+1
View File
@@ -38,6 +38,7 @@ window.config = {
bulkDataURI: {
enabled: true,
relativeResolution: 'studies',
transform: url => url.replace('/pixeldata.mp4', '/rendered'),
},
omitQuotationForMultipartRequest: true,
},
+17 -24
View File
@@ -168,33 +168,31 @@ function ViewerViewportGrid(props: withAppTypes) {
const { displaySetInstanceUID: referencedDisplaySetInstanceUID } = measurement;
const updatedViewports = _getUpdatedViewports(viewportId, referencedDisplaySetInstanceUID);
// Arbitrarily assign the viewport to element 0
const viewport = updatedViewports?.[0];
if (!viewport) {
if (!updatedViewports[0]) {
console.warn(
'ViewportGrid::Unable to navigate to viewport containing',
referencedDisplaySetInstanceUID
);
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;
viewport.viewportOptions ||= {};
viewport.viewportOptions.orientation = 'acquisition';
// Copy the viewport options to prevent modifying the internal data
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
// or zoom level required to display an annotation. The metadata attribute
// of the measurement is a viewReference, so use it to show the measurement.
// Longer term this should clear the view reference data
viewReference: measurement.metadata,
viewportType: measurement.metadata.volumeId ? 'volume' : null,
};
const displaySet = displaySetService.getDisplaySetByUID(referencedDisplaySetInstanceUID);
// jump straight to the initial image index if we can
if (displaySet.images && measurement.SOPInstanceUID) {
for (let index = 0; index < displaySet.images.length; index++) {
const image = displaySet.images[index];
if (image.SOPInstanceUID === measurement.SOPInstanceUID) {
viewport.viewportOptions.initialImageOptions = {
index,
};
break;
}
}
}
viewportGridService.setDisplaySetsForViewports(updatedViewports);
}
);
@@ -338,11 +336,6 @@ function ViewerViewportGrid(props: withAppTypes) {
);
}
ViewerViewportGrid.propTypes = {
viewportComponents: PropTypes.array.isRequired,
servicesManager: PropTypes.instanceOf(Object).isRequired,
};
function _getViewportComponent(displaySets, viewportComponents, uiNotificationService) {
if (!displaySets || !displaySets.length) {
return EmptyViewport;