feat(cst): Add new command to get nearby annotation tools (#3327)
* feat(cst): Add new command to get nearby annotation tools This commit adds a new command `getNearbyAnnotation` to the `commandsModule.ts` file that identifies nearby annotation tools excluding Crosshairs and ReferenceLines. It also removes an unused mapping to `Crosshairs` in `initMeasurementService.js` and changes the command run in `findNearbyToolData.ts` to `getNearbyAnnotation`. * perf(cornerstone): Improve performance by optimizing tools Removes unnecessary imports to improve app's performance. Changes how annotations are detected on the `commandsModule.js` file by fetching the `isAnnotation` property of the tool instance if available. Updates `CrosshairsTool` and `ReferenceLinesTool` to not be annotations anymore. Adjusts the `localhost` URL ports for the `dcm4chee-arc` service interface on `local_dcm4chee.js` to allow for more efficient server communication. * feat(cornerstone): Add CornerstoneServices type and ToolGroupService.getToolGroup to get tool group by ID or active viewport This commit introduces the new CornerstoneServices interface to the code and adds the ToolGroupService.getToolGroup method, which can retrieve a specific tool group by ID or from the active viewport. The older _getToolGroup method has also been removed from commandsModule. When no tool group ID is provided, this method now retrieves the tool group from the currently active viewport with the help of getActiveViewportEnabledElement. Additionally, the required reference to @ohif/core has been removed.
This commit is contained in:
parent
fe7fa6e5bf
commit
c9d3c08cb6
@ -10,7 +10,6 @@ import {
|
|||||||
utilities as cstUtils,
|
utilities as cstUtils,
|
||||||
ReferenceLinesTool,
|
ReferenceLinesTool,
|
||||||
} from '@cornerstonejs/tools';
|
} from '@cornerstonejs/tools';
|
||||||
import { ServicesManager } from '@ohif/core';
|
|
||||||
|
|
||||||
import CornerstoneViewportDownloadForm from './utils/CornerstoneViewportDownloadForm';
|
import CornerstoneViewportDownloadForm from './utils/CornerstoneViewportDownloadForm';
|
||||||
import callInputDialog from './utils/callInputDialog';
|
import callInputDialog from './utils/callInputDialog';
|
||||||
@ -18,6 +17,7 @@ import { setColormap } from './utils/colormap/transferFunctionHelpers';
|
|||||||
import toggleStackImageSync from './utils/stackSync/toggleStackImageSync';
|
import toggleStackImageSync from './utils/stackSync/toggleStackImageSync';
|
||||||
import { getFirstAnnotationSelected } from './utils/measurementServiceMappings/utils/selection';
|
import { getFirstAnnotationSelected } from './utils/measurementServiceMappings/utils/selection';
|
||||||
import getActiveViewportEnabledElement from './utils/getActiveViewportEnabledElement';
|
import getActiveViewportEnabledElement from './utils/getActiveViewportEnabledElement';
|
||||||
|
import { CornerstoneServices } from './types';
|
||||||
|
|
||||||
function commandsModule({ servicesManager, commandsManager }) {
|
function commandsModule({ servicesManager, commandsManager }) {
|
||||||
const {
|
const {
|
||||||
@ -28,51 +28,14 @@ function commandsModule({ servicesManager, commandsManager }) {
|
|||||||
uiDialogService,
|
uiDialogService,
|
||||||
cornerstoneViewportService,
|
cornerstoneViewportService,
|
||||||
uiNotificationService,
|
uiNotificationService,
|
||||||
customizationService,
|
|
||||||
measurementService,
|
measurementService,
|
||||||
hangingProtocolService,
|
} = servicesManager.services as CornerstoneServices;
|
||||||
} = (servicesManager as ServicesManager).services;
|
|
||||||
|
|
||||||
const { measurementServiceSource } = this;
|
const { measurementServiceSource } = this;
|
||||||
|
|
||||||
function _getActiveViewportEnabledElement() {
|
function _getActiveViewportEnabledElement() {
|
||||||
return getActiveViewportEnabledElement(viewportGridService);
|
return getActiveViewportEnabledElement(viewportGridService);
|
||||||
}
|
}
|
||||||
|
|
||||||
function _getToolGroup(toolGroupId) {
|
|
||||||
let toolGroupIdToUse = toolGroupId;
|
|
||||||
|
|
||||||
if (!toolGroupIdToUse) {
|
|
||||||
// Use the active viewport's tool group if no tool group id is provided
|
|
||||||
const enabledElement = _getActiveViewportEnabledElement();
|
|
||||||
|
|
||||||
if (!enabledElement) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { renderingEngineId, viewportId } = enabledElement;
|
|
||||||
const toolGroup = ToolGroupManager.getToolGroupForViewport(
|
|
||||||
viewportId,
|
|
||||||
renderingEngineId
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!toolGroup) {
|
|
||||||
console.warn(
|
|
||||||
'No tool group found for viewportId:',
|
|
||||||
viewportId,
|
|
||||||
'and renderingEngineId:',
|
|
||||||
renderingEngineId
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
toolGroupIdToUse = toolGroup.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
const toolGroup = toolGroupService.getToolGroup(toolGroupIdToUse);
|
|
||||||
return toolGroup;
|
|
||||||
}
|
|
||||||
|
|
||||||
const actions = {
|
const actions = {
|
||||||
/**
|
/**
|
||||||
* Generates the selector props for the context menu, specific to
|
* Generates the selector props for the context menu, specific to
|
||||||
@ -127,6 +90,36 @@ function commandsModule({ servicesManager, commandsManager }) {
|
|||||||
cstUtils.getAnnotationNearPoint(element, canvasCoordinates)
|
cstUtils.getAnnotationNearPoint(element, canvasCoordinates)
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
getNearbyAnnotation({ element, canvasCoordinates }) {
|
||||||
|
const nearbyToolData = actions.getNearbyToolData({
|
||||||
|
nearbyToolData: null,
|
||||||
|
element,
|
||||||
|
canvasCoordinates,
|
||||||
|
});
|
||||||
|
|
||||||
|
const isAnnotation = toolName => {
|
||||||
|
const enabledElement = getEnabledElement(element);
|
||||||
|
|
||||||
|
if (!enabledElement) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { renderingEngineId, viewportId } = enabledElement;
|
||||||
|
const toolGroup = ToolGroupManager.getToolGroupForViewport(
|
||||||
|
viewportId,
|
||||||
|
renderingEngineId
|
||||||
|
);
|
||||||
|
|
||||||
|
const toolInstance = toolGroup.getToolInstance(toolName);
|
||||||
|
|
||||||
|
return toolInstance?.constructor?.isAnnotation ?? true;
|
||||||
|
};
|
||||||
|
|
||||||
|
return nearbyToolData?.metadata?.toolName &&
|
||||||
|
isAnnotation(nearbyToolData.metadata.toolName)
|
||||||
|
? nearbyToolData
|
||||||
|
: null;
|
||||||
|
},
|
||||||
|
|
||||||
// Measurement tool commands:
|
// Measurement tool commands:
|
||||||
|
|
||||||
@ -298,7 +291,7 @@ function commandsModule({ servicesManager, commandsManager }) {
|
|||||||
|
|
||||||
setToolActive: ({ toolName, toolGroupId = null }) => {
|
setToolActive: ({ toolName, toolGroupId = null }) => {
|
||||||
if (toolName === 'Crosshairs') {
|
if (toolName === 'Crosshairs') {
|
||||||
const activeViewportToolGroup = _getToolGroup(null);
|
const activeViewportToolGroup = toolGroupService.getToolGroup(null);
|
||||||
|
|
||||||
if (!activeViewportToolGroup._toolInstances.Crosshairs) {
|
if (!activeViewportToolGroup._toolInstances.Crosshairs) {
|
||||||
uiNotificationService.show({
|
uiNotificationService.show({
|
||||||
@ -317,7 +310,7 @@ function commandsModule({ servicesManager, commandsManager }) {
|
|||||||
viewports: [],
|
viewports: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
const toolGroup = _getToolGroup(toolGroupId);
|
const toolGroup = toolGroupService.getToolGroup(toolGroupId);
|
||||||
const toolGroupViewportIds = toolGroup?.getViewportIds?.();
|
const toolGroupViewportIds = toolGroup?.getViewportIds?.();
|
||||||
|
|
||||||
// if toolGroup has been destroyed, or its viewports have been removed
|
// if toolGroup has been destroyed, or its viewports have been removed
|
||||||
@ -635,6 +628,11 @@ function commandsModule({ servicesManager, commandsManager }) {
|
|||||||
storeContexts: [],
|
storeContexts: [],
|
||||||
options: {},
|
options: {},
|
||||||
},
|
},
|
||||||
|
getNearbyAnnotation: {
|
||||||
|
commandFn: actions.getNearbyAnnotation,
|
||||||
|
storeContexts: [],
|
||||||
|
options: {},
|
||||||
|
},
|
||||||
|
|
||||||
deleteMeasurement: {
|
deleteMeasurement: {
|
||||||
commandFn: actions.deleteMeasurement,
|
commandFn: actions.deleteMeasurement,
|
||||||
|
|||||||
@ -30,6 +30,9 @@ import {
|
|||||||
import CalibrationLineTool from './tools/CalibrationLineTool';
|
import CalibrationLineTool from './tools/CalibrationLineTool';
|
||||||
|
|
||||||
export default function initCornerstoneTools(configuration = {}) {
|
export default function initCornerstoneTools(configuration = {}) {
|
||||||
|
CrosshairsTool.isAnnotation = false;
|
||||||
|
ReferenceLinesTool.isAnnotation = false;
|
||||||
|
|
||||||
init(configuration);
|
init(configuration);
|
||||||
addTool(PanTool);
|
addTool(PanTool);
|
||||||
addTool(WindowLevelTool);
|
addTool(WindowLevelTool);
|
||||||
|
|||||||
@ -49,20 +49,6 @@ const initMeasurementService = (
|
|||||||
Length.toMeasurement
|
Length.toMeasurement
|
||||||
);
|
);
|
||||||
|
|
||||||
measurementService.addMapping(
|
|
||||||
csTools3DVer1MeasurementSource,
|
|
||||||
'Crosshairs',
|
|
||||||
Length.matchingCriteria,
|
|
||||||
() => {
|
|
||||||
console.warn('Crosshairs mapping not implemented.');
|
|
||||||
return {};
|
|
||||||
},
|
|
||||||
() => {
|
|
||||||
console.warn('Crosshairs mapping not implemented.');
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
measurementService.addMapping(
|
measurementService.addMapping(
|
||||||
csTools3DVer1MeasurementSource,
|
csTools3DVer1MeasurementSource,
|
||||||
'Bidirectional',
|
'Bidirectional',
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import { ToolGroupManager, Enums, Types } from '@cornerstonejs/tools';
|
import { ToolGroupManager, Enums, Types } from '@cornerstonejs/tools';
|
||||||
|
|
||||||
import { Types as OhifTypes, pubSubServiceInterface } from '@ohif/core';
|
import { Types as OhifTypes, pubSubServiceInterface } from '@ohif/core';
|
||||||
|
import getActiveViewportEnabledElement from '../../utils/getActiveViewportEnabledElement';
|
||||||
|
|
||||||
const EVENTS = {
|
const EVENTS = {
|
||||||
VIEWPORT_ADDED: 'event::cornerstone::toolgroupservice:viewportadded',
|
VIEWPORT_ADDED: 'event::cornerstone::toolgroupservice:viewportadded',
|
||||||
@ -39,20 +40,56 @@ export default class ToolGroupService {
|
|||||||
EVENTS: { [key: string]: string };
|
EVENTS: { [key: string]: string };
|
||||||
|
|
||||||
constructor(serviceManager) {
|
constructor(serviceManager) {
|
||||||
const { cornerstoneViewportService } = serviceManager.services;
|
const {
|
||||||
|
cornerstoneViewportService,
|
||||||
|
viewportGridService,
|
||||||
|
} = serviceManager.services;
|
||||||
this.cornerstoneViewportService = cornerstoneViewportService;
|
this.cornerstoneViewportService = cornerstoneViewportService;
|
||||||
|
this.viewportGridService = viewportGridService;
|
||||||
this.listeners = {};
|
this.listeners = {};
|
||||||
this.EVENTS = EVENTS;
|
this.EVENTS = EVENTS;
|
||||||
Object.assign(this, pubSubServiceInterface);
|
Object.assign(this, pubSubServiceInterface);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the cornerstone ToolGroup for a given toolGroup UID
|
* Retrieves a tool group from the ToolGroupManager by tool group ID.
|
||||||
* @param {string} toolGroupId - The toolGroup uid
|
* If no tool group ID is provided, it retrieves the tool group of the active viewport.
|
||||||
* @returns {IToolGroup} - The toolGroup
|
* @param toolGroupId - Optional ID of the tool group to retrieve.
|
||||||
|
* @returns The tool group or undefined if it is not found.
|
||||||
*/
|
*/
|
||||||
public getToolGroup(toolGroupId: string): Types.IToolGroup | void {
|
public getToolGroup(toolGroupId?: string): Types.IToolGroup | void {
|
||||||
const toolGroup = ToolGroupManager.getToolGroup(toolGroupId);
|
let toolGroupIdToUse = toolGroupId;
|
||||||
|
|
||||||
|
if (!toolGroupIdToUse) {
|
||||||
|
// Use the active viewport's tool group if no tool group id is provided
|
||||||
|
const enabledElement = getActiveViewportEnabledElement(
|
||||||
|
this.viewportGridService
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!enabledElement) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { renderingEngineId, viewportId } = enabledElement;
|
||||||
|
const toolGroup = ToolGroupManager.getToolGroupForViewport(
|
||||||
|
viewportId,
|
||||||
|
renderingEngineId
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!toolGroup) {
|
||||||
|
console.warn(
|
||||||
|
'No tool group found for viewportId:',
|
||||||
|
viewportId,
|
||||||
|
'and renderingEngineId:',
|
||||||
|
renderingEngineId
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
toolGroupIdToUse = toolGroup.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
const toolGroup = ToolGroupManager.getToolGroup(toolGroupIdToUse);
|
||||||
return toolGroup;
|
return toolGroup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -11,7 +11,7 @@ export const findNearbyToolData = (commandsManager, evt) => {
|
|||||||
}
|
}
|
||||||
const { element, currentPoints } = evt.detail;
|
const { element, currentPoints } = evt.detail;
|
||||||
return commandsManager.runCommand(
|
return commandsManager.runCommand(
|
||||||
'getNearbyToolData',
|
'getNearbyAnnotation',
|
||||||
{
|
{
|
||||||
element,
|
element,
|
||||||
canvasCoordinates: currentPoints?.canvas,
|
canvasCoordinates: currentPoints?.canvas,
|
||||||
|
|||||||
@ -508,7 +508,6 @@ class MeasurementService extends PubSubService {
|
|||||||
if (!this._isValidSource(source)) {
|
if (!this._isValidSource(source)) {
|
||||||
throw new Error('Invalid source.');
|
throw new Error('Invalid source.');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!annotationType) {
|
if (!annotationType) {
|
||||||
throw new Error('No source annotationType provided.');
|
throw new Error('No source annotationType provided.');
|
||||||
}
|
}
|
||||||
@ -572,7 +571,7 @@ class MeasurementService extends PubSubService {
|
|||||||
// For now, it is just added in OHIF here and in setMeasurementSelected.
|
// For now, it is just added in OHIF here and in setMeasurementSelected.
|
||||||
this.measurements[internalUID] = newMeasurement;
|
this.measurements[internalUID] = newMeasurement;
|
||||||
if (isUpdate) {
|
if (isUpdate) {
|
||||||
this._broadcastEvent(this.EVENTS.MEASUREMENT_UPDATED, {
|
this._broadcastEvent(this.EVENTS.MEASUREMENT_UPDATED, {
|
||||||
source,
|
source,
|
||||||
measurement: newMeasurement,
|
measurement: newMeasurement,
|
||||||
notYetUpdatedAtSource: false,
|
notYetUpdatedAtSource: false,
|
||||||
|
|||||||
@ -16,14 +16,13 @@ window.config = {
|
|||||||
sourceName: 'dicomweb',
|
sourceName: 'dicomweb',
|
||||||
configuration: {
|
configuration: {
|
||||||
name: 'DCM4CHEE',
|
name: 'DCM4CHEE',
|
||||||
wadoUriRoot: 'http://localhost/dcm4chee-arc/aets/DCM4CHEE/wado',
|
wadoUriRoot: 'http://localhost:8080/dcm4chee-arc/aets/DCM4CHEE/wado',
|
||||||
qidoRoot: 'http://localhost/dcm4chee-arc/aets/DCM4CHEE/rs',
|
qidoRoot: 'http://localhost:8080/dcm4chee-arc/aets/DCM4CHEE/rs',
|
||||||
wadoRoot: 'http://localhost/dcm4chee-arc/aets/DCM4CHEE/rs',
|
wadoRoot: 'http://localhost:8080/dcm4chee-arc/aets/DCM4CHEE/rs',
|
||||||
qidoSupportsIncludeField: true,
|
qidoSupportsIncludeField: true,
|
||||||
imageRendering: 'wadors',
|
imageRendering: 'wadors',
|
||||||
enableStudyLazyLoad: true,
|
enableStudyLazyLoad: true,
|
||||||
thumbnailRendering: 'wadors',
|
thumbnailRendering: 'wadors',
|
||||||
useBulkDataURI: false,
|
|
||||||
requestOptions: {
|
requestOptions: {
|
||||||
auth: 'admin:admin',
|
auth: 'admin:admin',
|
||||||
},
|
},
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user