Added memoization on VTKMPRToolbarButton component to avoid unnecesary rebuilds (#2274)

* Added memoization on VTKMPRToolbarButton component to avoid unnecessary rebuilds

* update isDisplaySetReconstructable for float precision

Co-authored-by: Rodrigo Cáceres Vicencio <rcaceres@nursoft.cl>
Co-authored-by: Davide Punzo <punzodavide@hotmail.it>
This commit is contained in:
Rodrigo Cáceres 2021-03-09 12:52:56 -03:00 committed by GitHub
parent bdecbfeee3
commit 97410e12b9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1,21 +1,18 @@
import React from 'react'; import React, { useMemo } from 'react';
import { useSelector } from 'react-redux'; import { useSelector } from 'react-redux';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { ToolbarButton } from '@ohif/ui'; import { ToolbarButton } from '@ohif/ui';
import { utils } from '@ohif/core'; import { utils } from '@ohif/core';
import { createSelector } from 'reselect';
const { studyMetadataManager } = utils; const { studyMetadataManager } = utils;
let isVisible = true; const _isDisplaySetReconstructable = (
displaySetInstanceUID = '',
const _isDisplaySetReconstructable = (viewportSpecificData = {}, activeViewportIndex) => { StudyInstanceUID = ''
if (!viewportSpecificData[activeViewportIndex]) { ) => {
if (displaySetInstanceUID == '' || StudyInstanceUID == '') {
return false; return false;
}; }
const { displaySetInstanceUID, StudyInstanceUID } = viewportSpecificData[
activeViewportIndex
];
const studies = studyMetadataManager.all(); const studies = studyMetadataManager.all();
@ -27,7 +24,9 @@ const _isDisplaySetReconstructable = (viewportSpecificData = {}, activeViewportI
return false; return false;
} }
const displaySet = study._displaySets.find(set => set.displaySetInstanceUID === displaySetInstanceUID); const displaySet = study._displaySets.find(
set => set.displaySetInstanceUID === displaySetInstanceUID
);
if (!displaySet) { if (!displaySet) {
return false; return false;
@ -45,33 +44,43 @@ const _isDisplaySetReconstructable = (viewportSpecificData = {}, activeViewportI
const image = displaySet.images[ii]; const image = displaySet.images[ii];
if (!image) continue; if (!image) continue;
const imageIdControl = image.getImageId() const imageIdControl = image.getImageId();
const instanceMetadataControl = cornerstone.metaData.get('instance', imageIdControl) const instanceMetadataControl = cornerstone.metaData.get(
'instance',
imageIdControl
);
if (!instanceMetadataControl || if (
!instanceMetadataControl ||
instanceMetadataControl === undefined || instanceMetadataControl === undefined ||
!instanceMetadataControl.ImagePositionPatient || !instanceMetadataControl.ImagePositionPatient ||
instanceMetadataControl.ImagePositionPatient === undefined) { instanceMetadataControl.ImagePositionPatient === undefined
) {
// if ImagePositionPatient is missing, skip the 4D datasets check. // if ImagePositionPatient is missing, skip the 4D datasets check.
// do not return false, because it could be a 3D dataset. // do not return false, because it could be a 3D dataset.
continue; continue;
} }
let xImagePositionPatientControl = instanceMetadataControl.ImagePositionPatient[0]; let xImagePositionPatientControl =
let yImagePositionPatientControl = instanceMetadataControl.ImagePositionPatient[1]; instanceMetadataControl.ImagePositionPatient[0];
let zImagePositionPatientControl = instanceMetadataControl.ImagePositionPatient[2]; let yImagePositionPatientControl =
instanceMetadataControl.ImagePositionPatient[1];
let zImagePositionPatientControl =
instanceMetadataControl.ImagePositionPatient[2];
for (let jj = ii + 1; jj < displaySet.numImageFrames; ++jj) { for (let jj = ii + 1; jj < displaySet.numImageFrames; ++jj) {
const image = displaySet.images[jj]; const image = displaySet.images[jj];
if (!image) continue; if (!image) continue;
const imageId = image.getImageId() const imageId = image.getImageId();
const instanceMetadata = cornerstone.metaData.get('instance', imageId) const instanceMetadata = cornerstone.metaData.get('instance', imageId);
if (!instanceMetadata || if (
!instanceMetadata ||
instanceMetadata === undefined || instanceMetadata === undefined ||
!instanceMetadata.ImagePositionPatient || !instanceMetadata.ImagePositionPatient ||
instanceMetadata.ImagePositionPatient === undefined) { instanceMetadata.ImagePositionPatient === undefined
) {
// if ImagePositionPatient is missing, skip the 4D datasets check. // if ImagePositionPatient is missing, skip the 4D datasets check.
// do not return false, because it could be a 3D dataset. // do not return false, because it could be a 3D dataset.
continue; continue;
@ -81,9 +90,12 @@ const _isDisplaySetReconstructable = (viewportSpecificData = {}, activeViewportI
let yImagePositionPatient = instanceMetadata.ImagePositionPatient[1]; let yImagePositionPatient = instanceMetadata.ImagePositionPatient[1];
let zImagePositionPatient = instanceMetadata.ImagePositionPatient[2]; let zImagePositionPatient = instanceMetadata.ImagePositionPatient[2];
if (xImagePositionPatientControl === xImagePositionPatient && // ImagePositionPatient is float
yImagePositionPatientControl === yImagePositionPatient && if (
zImagePositionPatientControl === zImagePositionPatient) { Math.abs( xImagePositionPatientControl - xImagePositionPatient ) < 1e-6 &&
Math.abs( yImagePositionPatientControl - yImagePositionPatient ) < 1e-6 &&
Math.abs( zImagePositionPatientControl - zImagePositionPatient ) < 1e-6
) {
return false; return false;
} }
} }
@ -92,30 +104,53 @@ const _isDisplaySetReconstructable = (viewportSpecificData = {}, activeViewportI
return displaySet.isReconstructable; return displaySet.isReconstructable;
}; };
function VTKMPRToolbarButton({ const selectDisplaySetInstanceUID = state => {
parentContext, if (
toolbarClickCallback, state.viewports.viewportSpecificData[state.viewports.activeViewportIndex]
button, ) {
activeButtons, return state.viewports.viewportSpecificData[
isActive, state.viewports.activeViewportIndex
className, ].displaySetInstanceUID;
}) { } else {
const { id, label, icon } = button; return '';
const { viewportSpecificData, activeViewportIndex } = useSelector(state => {
const { viewports = {} } = state;
const { viewportSpecificData, activeViewportIndex } = viewports;
return {
viewportSpecificData,
activeViewportIndex,
} }
}); };
isVisible = _isDisplaySetReconstructable( const selectStudyInstanceUID = state => {
viewportSpecificData, if (
activeViewportIndex, state.viewports.viewportSpecificData[state.viewports.activeViewportIndex]
) {
return state.viewports.viewportSpecificData[
state.viewports.activeViewportIndex
].StudyInstanceUID;
} else {
return '';
}
};
const stateSelector = createSelector(
[selectDisplaySetInstanceUID, selectStudyInstanceUID],
(displaySetInstanceUID, StudyInstanceUID) => {
return {
displaySetInstanceUID,
StudyInstanceUID,
};
}
);
function VTKMPRToolbarButton({ toolbarClickCallback, button, isActive }) {
const { id, label, icon } = button;
const { displaySetInstanceUID, StudyInstanceUID } = useSelector(
stateSelector
); );
const isVisible = useMemo(() => {
return _isDisplaySetReconstructable(
displaySetInstanceUID,
StudyInstanceUID
);
}, [displaySetInstanceUID, StudyInstanceUID]);
return ( return (
<React.Fragment> <React.Fragment>
{isVisible && ( {isVisible && (