Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 25 additions & 6 deletions packages/core/examples/tmtv/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ const {
RectangleROITool,
CircleROIStartEndThresholdTool,
RectangleROIStartEndThresholdTool,
PlanarFreehandROITool,
segmentation,
} = cornerstoneTools;

Expand Down Expand Up @@ -171,14 +172,14 @@ const optionsValues = [
RectangleROITool.toolName,
CircleROIStartEndThresholdTool.toolName,
RectangleROIStartEndThresholdTool.toolName,
PlanarFreehandROITool.toolName,
];

addButtonToToolbar({
title: 'Run Segmentation',
onClick: () => {
const annotations = cornerstoneTools.annotation.state.getAllAnnotations();
const labelmapVolume = cache.getVolume(segmentationId);
console.debug(annotations);
annotations.map((annotation, i) => {
// @ts-ignore
const pointsInVolume = annotation.data.cachedStats.pointsInVolume;
Expand Down Expand Up @@ -215,7 +216,6 @@ addDropdownToToolbar({
studyToolGroupIds.fusion,
].forEach((toolGroupId) => {
const toolGroup = ToolGroupManager.getToolGroup(toolGroupId);

if (toolName === ZoomTool.toolName) {
// Check if viewports are initialized before setting tools
if (renderingEngine && renderingEngine.getViewports().length > 0) {
Expand All @@ -240,6 +240,9 @@ addDropdownToToolbar({
toolGroup.setToolDisabled(ZoomTool.toolName);
toolGroup.setToolDisabled(WindowLevelTool.toolName);
toolGroup.setToolDisabled(RectangleROITool.toolName);
toolGroup.setToolDisabled(PlanarFreehandROITool.toolName);
toolGroup.setToolDisabled(CircleROIStartEndThresholdTool.toolName);
toolGroup.setToolDisabled(RectangleROIStartEndThresholdTool.toolName);
toolGroup.setToolActive(CrosshairsTool.toolName, {
bindings: [{ mouseButton: MouseBindings.Primary }],
});
Expand All @@ -248,6 +251,8 @@ addDropdownToToolbar({
toolGroup.setToolDisabled(WindowLevelTool.toolName);
toolGroup.setToolDisabled(CrosshairsTool.toolName);
toolGroup.setToolDisabled(RectangleROITool.toolName);
toolGroup.setToolDisabled(PlanarFreehandROITool.toolName);
toolGroup.setToolDisabled(RectangleROIStartEndThresholdTool.toolName);
toolGroup.setToolActive(CircleROIStartEndThresholdTool.toolName, {
bindings: [{ mouseButton: MouseBindings.Primary }],
});
Expand All @@ -257,9 +262,20 @@ addDropdownToToolbar({
toolGroup.setToolDisabled(CrosshairsTool.toolName);
toolGroup.setToolDisabled(RectangleROITool.toolName);
toolGroup.setToolDisabled(CircleROIStartEndThresholdTool.toolName);
toolGroup.setToolDisabled(PlanarFreehandROITool.toolName);
toolGroup.setToolActive(RectangleROIStartEndThresholdTool.toolName, {
bindings: [{ mouseButton: MouseBindings.Primary }],
});
} else if (toolName === PlanarFreehandROITool.toolName) {
toolGroup.setToolDisabled(ZoomTool.toolName);
toolGroup.setToolDisabled(WindowLevelTool.toolName);
toolGroup.setToolDisabled(CrosshairsTool.toolName);
toolGroup.setToolDisabled(RectangleROITool.toolName);
toolGroup.setToolDisabled(CircleROIStartEndThresholdTool.toolName);
toolGroup.setToolDisabled(RectangleROIStartEndThresholdTool.toolName);
toolGroup.setToolActive(PlanarFreehandROITool.toolName, {
bindings: [{ mouseButton: MouseBindings.Primary }],
});
} else {
toolGroup.setToolDisabled(ZoomTool.toolName);
toolGroup.setToolDisabled(WindowLevelTool.toolName);
Expand Down Expand Up @@ -392,7 +408,6 @@ function setUpToolGroupsForStudy(studyKey) {
studyViewportIds.FUSION.CORONAL,
renderingEngineId
);

// Add tools to CT and PT groups
[ctToolGroup, ptToolGroup].forEach((toolGroup) => {
toolGroup.addTool(WindowLevelTool.toolName);
Expand All @@ -418,14 +433,14 @@ function setUpToolGroupsForStudy(studyKey) {
});
toolGroup.addTool(RectangleROIStartEndThresholdTool.toolName, {
calculatePointsInsideVolume: true,
showTextBox: false,
showTextBox: true,
storePointData: true,
/* Set a custom wait time */
throttleTimeout: 100,
/* Simplified handles */
simplified: false,
});
// }
toolGroup.addTool(PlanarFreehandROITool.toolName, { cachedStats: true });
});

// Add tools to fusion group
Expand All @@ -452,13 +467,16 @@ function setUpToolGroupsForStudy(studyKey) {
});
fusionToolGroup.addTool(RectangleROIStartEndThresholdTool.toolName, {
calculatePointsInsideVolume: true,
showTextBox: false,
showTextBox: true,
storePointData: true,
/* Set a custom wait time */
throttleTimeout: 100,
/* Simplified handles */
simplified: false,
});
fusionToolGroup.addTool(PlanarFreehandROITool.toolName, {
cachedStats: true,
});

// Set active tools
[ctToolGroup, ptToolGroup, fusionToolGroup].forEach((toolGroup) => {
Expand Down Expand Up @@ -890,6 +908,7 @@ async function run() {
cornerstoneTools.addTool(RectangleROITool);
cornerstoneTools.addTool(CircleROIStartEndThresholdTool);
cornerstoneTools.addTool(RectangleROIStartEndThresholdTool);
cornerstoneTools.addTool(PlanarFreehandROITool);

// Instantiate a rendering engine
renderingEngine = new RenderingEngine(renderingEngineId);
Expand Down
68 changes: 55 additions & 13 deletions packages/tools/src/tools/annotation/PlanarFreehandROITool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -593,6 +593,9 @@ class PlanarFreehandROITool extends ContourSegmentationBaseTool {
const worldPos = evt.detail.currentPoints.world;
const contourAnnotation = super.createAnnotation(evt);

const { element } = evt.detail;
const { viewport } = getEnabledElement(element);

const onInterpolationComplete = (annotation) => {
// Clear out the handles because they aren't used for straight freeform
annotation.data.handles.points.length = 0;
Expand All @@ -607,6 +610,8 @@ class PlanarFreehandROITool extends ContourSegmentationBaseTool {
},
label: '',
cachedStats: {},
drawingVolumeId: this.getTargetId(viewport),
drawingViewportId: viewport.id,
},
onInterpolationComplete,
}
Expand All @@ -621,6 +626,42 @@ class PlanarFreehandROITool extends ContourSegmentationBaseTool {
return super.getAnnotationStyle(context);
}

/**
* Override to prevent interaction with the textbox handle
* if we are not on the same viewport as the one it was drawn on.
*/
public getHandleNearImagePoint(
element: HTMLDivElement,
annotation: PlanarFreehandROIAnnotation,
canvasCoords: Types.Point2,
proximity: number
): ToolHandle | undefined {
const handle = super.getHandleNearImagePoint(
element,
annotation,
canvasCoords,
proximity
);

if (!handle) {
return undefined;
}

if (handle === annotation.data.handles.textBox) {
const { viewport } = getEnabledElement(element);
const targetId = this.getTargetId(viewport);
//if the drawingVolumeId is defined and different from the current viewport targetId
if (
annotation.data.drawingVolumeId &&
annotation.data.drawingVolumeId !== targetId
) {
return undefined;
}
}

return handle;
}

protected renderAnnotationInstance(
renderContext: AnnotationRenderContext
): boolean {
Expand Down Expand Up @@ -703,13 +744,7 @@ class PlanarFreehandROITool extends ContourSegmentationBaseTool {
}

if (annotation.invalidated) {
this._calculateStatsIfActive(
annotation,
targetId,
viewport,
renderingEngine,
enabledElement
);
this._calculateStatsIfActive(annotation, renderingEngine);
}

this._renderStats(annotation, viewport, enabledElement, svgDrawingHelper);
Expand All @@ -719,12 +754,14 @@ class PlanarFreehandROITool extends ContourSegmentationBaseTool {

_calculateStatsIfActive(
annotation: PlanarFreehandROIAnnotation,
targetId: string,
viewport,
renderingEngine,
enabledElement
renderingEngine
) {
const activeAnnotationUID = this.commonData?.annotation.annotationUID;
const targetId = annotation.data.drawingVolumeId;
const viewport = renderingEngine.getViewport(
annotation.data.drawingViewportId
);
const enableElementForStats = getEnabledElement(viewport.element);

if (
annotation.annotationUID === activeAnnotationUID &&
Expand All @@ -750,14 +787,14 @@ class PlanarFreehandROITool extends ContourSegmentationBaseTool {
annotation,
viewport,
renderingEngine,
enabledElement
enableElementForStats
);
} else if (annotation.invalidated) {
this._throttledCalculateCachedStats(
annotation,
viewport,
renderingEngine,
enabledElement
enableElementForStats
);
}
}
Expand Down Expand Up @@ -1102,6 +1139,11 @@ class PlanarFreehandROITool extends ContourSegmentationBaseTool {
const canvasCoordinates = data.contour.polyline.map((p) =>
viewport.worldToCanvas(p)
);

if (canvasCoordinates.length < 2) {
return;
}

if (!data.handles.textBox.hasMoved) {
const canvasTextBoxCoords = getTextBoxCoordsCanvas(canvasCoordinates);

Expand Down
2 changes: 2 additions & 0 deletions packages/tools/src/types/ToolSpecificAnnotationTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,8 @@ export type PlanarFreehandROIAnnotation = ContourAnnotation & {
// Present if isOpenUShapeContour is true:
openUShapeContourVectorToPeak?: Types.Point3[];
cachedStats?: ROICachedStats;
drawingVolumeId?: string;
drawingViewportId?: string;
};
};
export type PlanarFreehandContourSegmentationAnnotation =
Expand Down
Loading