feat(4D): Add 4D dynamic volume rendering and new pre-clinical 4d pt/ct mode (#3664)
Co-authored-by: Alireza <ar.sedghi@gmail.com> Co-authored-by: Neil <neil.a.macphee@gmail.com>
This commit is contained in:
200 files changed
+9589
-2178
No files matched your search
+2
-1
@@ -200,6 +200,7 @@ class CornerstoneCacheService {
|
||||
volume,
|
||||
volumeId,
|
||||
imageIds: volumeImageIds,
|
||||
isDynamicVolume: displaySet.isDynamicVolume,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -228,7 +229,7 @@ class CornerstoneCacheService {
|
||||
|
||||
const shouldDisplaySeg = segmentationService.shouldRenderSegmentation(
|
||||
viewportDisplaySetInstanceUIDs,
|
||||
instance.FrameOfReferenceUID
|
||||
instance?.FrameOfReferenceUID || segDisplaySet.FrameOfReferenceUID
|
||||
);
|
||||
|
||||
if (shouldDisplaySeg) {
|
||||
|
||||
@@ -1289,7 +1289,7 @@ class SegmentationService extends PubSubService {
|
||||
}
|
||||
|
||||
const { colorLUTIndex } = segmentation;
|
||||
this._removeSegmentationFromCornerstone(segmentationId);
|
||||
const { updatedToolGroupIds } = this._removeSegmentationFromCornerstone(segmentationId);
|
||||
|
||||
// Delete associated colormap
|
||||
// Todo: bring this back
|
||||
@@ -1309,7 +1309,9 @@ class SegmentationService extends PubSubService {
|
||||
if (remainingHydratedSegmentations.length) {
|
||||
const { id } = remainingHydratedSegmentations[0];
|
||||
|
||||
this._setActiveSegmentationForToolGroup(id, this._getApplicableToolGroupId(), false);
|
||||
updatedToolGroupIds.forEach(toolGroupId => {
|
||||
this._setActiveSegmentationForToolGroup(id, toolGroupId, false);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1966,6 +1968,7 @@ class SegmentationService extends PubSubService {
|
||||
const removeFromCache = true;
|
||||
const segmentationState = cstSegmentation.state;
|
||||
const sourceSegState = segmentationState.getSegmentation(segmentationId);
|
||||
const updatedToolGroupIds: Set<string> = new Set();
|
||||
|
||||
if (!sourceSegState) {
|
||||
return;
|
||||
@@ -1981,6 +1984,7 @@ class SegmentationService extends PubSubService {
|
||||
segmentationRepresentations.forEach(representation => {
|
||||
if (representation.segmentationId === segmentationId) {
|
||||
UIDsToRemove.push(representation.segmentationRepresentationUID);
|
||||
updatedToolGroupIds.add(toolGroupId);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1998,6 +2002,8 @@ class SegmentationService extends PubSubService {
|
||||
if (removeFromCache && cache.getVolumeLoadObject(segmentationId)) {
|
||||
cache.removeVolumeLoadObject(segmentationId);
|
||||
}
|
||||
|
||||
return { updatedToolGroupIds: Array.from(updatedToolGroupIds) };
|
||||
}
|
||||
|
||||
private _updateCornerstoneSegmentations({ segmentationId, notYetUpdatedAtSource }) {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { ToolGroupManager, Enums, Types } from '@cornerstonejs/tools';
|
||||
import { eventTarget } from '@cornerstonejs/core';
|
||||
|
||||
import { Types as OhifTypes, pubSubServiceInterface } from '@ohif/core';
|
||||
import getActiveViewportEnabledElement from '../../utils/getActiveViewportEnabledElement';
|
||||
@@ -6,6 +7,8 @@ import getActiveViewportEnabledElement from '../../utils/getActiveViewportEnable
|
||||
const EVENTS = {
|
||||
VIEWPORT_ADDED: 'event::cornerstone::toolgroupservice:viewportadded',
|
||||
TOOLGROUP_CREATED: 'event::cornerstone::toolgroupservice:toolgroupcreated',
|
||||
TOOL_ACTIVATED: 'event::cornerstone::toolgroupservice:toolactivated',
|
||||
PRIMARY_TOOL_ACTIVATED: 'event::cornerstone::toolgroupservice:primarytoolactivated',
|
||||
};
|
||||
|
||||
type Tool = {
|
||||
@@ -38,18 +41,26 @@ export default class ToolGroupService {
|
||||
EVENTS: { [key: string]: string };
|
||||
|
||||
constructor(serviceManager) {
|
||||
const { cornerstoneViewportService, viewportGridService } = serviceManager.services;
|
||||
const { cornerstoneViewportService, viewportGridService, uiNotificationService } =
|
||||
serviceManager.services;
|
||||
this.cornerstoneViewportService = cornerstoneViewportService;
|
||||
this.viewportGridService = viewportGridService;
|
||||
this.uiNotificationService = uiNotificationService;
|
||||
this.listeners = {};
|
||||
this.EVENTS = EVENTS;
|
||||
Object.assign(this, pubSubServiceInterface);
|
||||
|
||||
this._init();
|
||||
}
|
||||
|
||||
onModeExit() {
|
||||
this.destroy();
|
||||
}
|
||||
|
||||
private _init() {
|
||||
eventTarget.addEventListener(Enums.Events.TOOL_ACTIVATED, this._onToolActivated);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a tool group from the ToolGroupManager by tool group ID.
|
||||
* If no tool group ID is provided, it retrieves the tool group of the active viewport.
|
||||
@@ -105,12 +116,14 @@ export default class ToolGroupService {
|
||||
return toolGroup.getActivePrimaryMouseButtonTool();
|
||||
}
|
||||
|
||||
public destroy() {
|
||||
public destroy(): void {
|
||||
ToolGroupManager.destroy();
|
||||
this.toolGroupIds = new Set();
|
||||
|
||||
eventTarget.removeEventListener(Enums.Events.TOOL_ACTIVATED, this._onToolActivated);
|
||||
}
|
||||
|
||||
public destroyToolGroup(toolGroupId: string) {
|
||||
public destroyToolGroup(toolGroupId: string): void {
|
||||
ToolGroupManager.destroyToolGroup(toolGroupId);
|
||||
this.toolGroupIds.delete(toolGroupId);
|
||||
}
|
||||
@@ -222,6 +235,10 @@ export default class ToolGroupService {
|
||||
toolInstance.configuration = config;
|
||||
}
|
||||
|
||||
public getActivePrimaryMouseButtonTool(toolGroupId?: string): string {
|
||||
return this.getToolGroup(toolGroupId)?.getActivePrimaryMouseButtonTool();
|
||||
}
|
||||
|
||||
private _setToolsMode(toolGroup, tools) {
|
||||
const { active, passive, enabled, disabled } = tools;
|
||||
|
||||
@@ -279,4 +296,23 @@ export default class ToolGroupService {
|
||||
addTools(tools.disabled);
|
||||
}
|
||||
}
|
||||
|
||||
private _onToolActivated = (evt: Types.EventTypes.ToolActivatedEventType) => {
|
||||
const { toolGroupId, toolName, toolBindingsOptions } = evt.detail;
|
||||
const isPrimaryTool = toolBindingsOptions.bindings?.some(
|
||||
binding => binding.mouseButton === Enums.MouseBindings.Primary
|
||||
);
|
||||
|
||||
const callbackProps = {
|
||||
toolGroupId,
|
||||
toolName,
|
||||
toolBindingsOptions,
|
||||
};
|
||||
|
||||
this._broadcastEvent(EVENTS.TOOL_ACTIVATED, callbackProps);
|
||||
|
||||
if (isPrimaryTool) {
|
||||
this._broadcastEvent(EVENTS.PRIMARY_TOOL_ACTIVATED, callbackProps);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -24,6 +24,7 @@ import JumpPresets from '../../utils/JumpPresets';
|
||||
|
||||
const EVENTS = {
|
||||
VIEWPORT_DATA_CHANGED: 'event::cornerstoneViewportService:viewportDataChanged',
|
||||
VIEWPORT_VOLUMES_CHANGED: 'event::cornerstoneViewportService:viewportVolumesChanged',
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -793,6 +794,10 @@ class CornerstoneViewportService extends PubSubService implements IViewportServi
|
||||
}
|
||||
|
||||
viewport.render();
|
||||
|
||||
this._broadcastEvent(this.EVENTS.VIEWPORT_VOLUMES_CHANGED, {
|
||||
viewportInfo,
|
||||
});
|
||||
}
|
||||
|
||||
private _addSegmentationRepresentationToToolGroupIfNecessary(
|
||||
|
||||
Reference in new issue
Block a user