-
Notifications
You must be signed in to change notification settings - Fork 327
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Planar freehand roi tool (#89)
* WIP, made SVG render + starting draw interaction. * WIP cross on create to trigger stop and later edit * Drawing complete + resamping and breaking on cross. * Implement open contour drawing * WIP open contour + adding editing paths * Edit open end loop * WIP contour editing * Find line to snap to * Snap + register second cross + cropping of edit line so that we have clear criteria for the preview contour * Rendering preview bug fixed. * Finish closed contour edit and implement most of open contour edit logic * WIP open contour editing drag over end * Fix open contour edit placement of handles and write open edit line drag to draw transition. * Stable for demo * Implement edit on cross. * WIP find other snap index if first will break crossing rules * Fix more edge cases. * Reconcile changes with upstream. * Event emission * Fix start of edits when you draw along the line * Cleanup unused variables + simplify some segments to just the important index for calculations * Implement missing spacing calculation for volume viewports. * WIP update all tsdoc + refactor * Cleanup + doc + type * try to fix type issues * WIP review comments. * WIP more comments * Cleanup rendering logic. * Fix issues * fix build issues Co-authored-by: Erik Ziegler <[email protected]> Co-authored-by: Alireza <[email protected]>
- Loading branch information
1 parent
d743a45
commit 0067339
Showing
25 changed files
with
3,309 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,160 @@ | ||
import { RenderingEngine, Types, Enums } from '@cornerstonejs/core'; | ||
import { | ||
initDemo, | ||
createImageIdsAndCacheMetaData, | ||
setTitleAndDescription, | ||
} from '../../../../utils/demo/helpers'; | ||
import * as cornerstoneTools from '@cornerstonejs/tools'; | ||
|
||
// This is for debugging purposes | ||
console.warn( | ||
'Click on index.ts to open source code for this example --------->' | ||
); | ||
|
||
const { | ||
PlanarFreehandROITool, | ||
PanTool, | ||
StackScrollMouseWheelTool, | ||
ZoomTool, | ||
ToolGroupManager, | ||
Enums: csToolsEnums, | ||
} = cornerstoneTools; | ||
|
||
const { ViewportType } = Enums; | ||
const { MouseBindings } = csToolsEnums; | ||
|
||
// ======== Set up page ======== // | ||
setTitleAndDescription( | ||
'Planar Freehand Annotation Tool', | ||
'Here we demonstrate how to use the Planar Freehand Annotation Tool to draw 2D open and closed ROIs' | ||
); | ||
|
||
const content = document.getElementById('content'); | ||
const element = document.createElement('div'); | ||
|
||
// Disable right click context menu so we can have right click tools | ||
element.oncontextmenu = (e) => e.preventDefault(); | ||
|
||
element.id = 'cornerstone-element'; | ||
element.style.width = '500px'; | ||
element.style.height = '500px'; | ||
|
||
content.appendChild(element); | ||
|
||
const instructions = document.createElement('p'); | ||
instructions.innerText = ` | ||
Drawing: | ||
- Left click and drag to draw a contour. | ||
-- If you join the contour together it will be closed, otherwise releasing the mouse will create an open contour (freehand line) | ||
Editing: | ||
- Left click and drag on the line of an existing contour to edit it: | ||
-- Closed Contours: | ||
--- Drag the line and a preview of the edit will be displayed. Release the mouse to complete the edit. You can cross the original contour multiple times in one drag to do a complicated edit in one movement. | ||
-- Open Contours: | ||
--- Hover over an end and you will see a handle appear, drag this handle to pull out the polyline further. You can join this handle back round to the other end if you wish to close the contour (say you made a mistake making an open contour). | ||
--- Drag the line and a preview of the edit will be displayed. Release the mouse to complete the edit. You can cross the original contour multiple times in one drag to do a complicated edit in one movement. | ||
--- If You drag the line past the end of the of the open contour, the edit will snap to make your edit the new end, and allow you to continue drawing. | ||
`; | ||
|
||
content.append(instructions); | ||
// ============================= // | ||
|
||
const toolGroupId = 'STACK_TOOL_GROUP_ID'; | ||
|
||
/** | ||
* Runs the demo | ||
*/ | ||
async function run() { | ||
// Init Cornerstone and related libraries | ||
await initDemo(); | ||
|
||
// Add tools to Cornerstone3D | ||
cornerstoneTools.addTool(PlanarFreehandROITool); | ||
cornerstoneTools.addTool(PanTool); | ||
cornerstoneTools.addTool(StackScrollMouseWheelTool); | ||
cornerstoneTools.addTool(ZoomTool); | ||
|
||
// Define a tool group, which defines how mouse events map to tool commands for | ||
// Any viewport using the group | ||
const toolGroup = ToolGroupManager.createToolGroup(toolGroupId); | ||
|
||
// Add the tools to the tool group | ||
toolGroup.addTool(PlanarFreehandROITool.toolName); | ||
toolGroup.addTool(PanTool.toolName); | ||
toolGroup.addTool(StackScrollMouseWheelTool.toolName); | ||
toolGroup.addTool(ZoomTool.toolName); | ||
|
||
// Set the initial state of the tools. | ||
toolGroup.setToolActive(PlanarFreehandROITool.toolName, { | ||
bindings: [ | ||
{ | ||
mouseButton: MouseBindings.Primary, // Left Click | ||
}, | ||
], | ||
}); | ||
toolGroup.setToolActive(PanTool.toolName, { | ||
bindings: [ | ||
{ | ||
mouseButton: MouseBindings.Auxiliary, // Middle Click | ||
}, | ||
], | ||
}); | ||
toolGroup.setToolActive(ZoomTool.toolName, { | ||
bindings: [ | ||
{ | ||
mouseButton: MouseBindings.Secondary, // Right Click | ||
}, | ||
], | ||
}); | ||
// As the Stack Scroll mouse wheel is a tool using the `mouseWheelCallback` | ||
// hook instead of mouse buttons, it does not need to assign any mouse button. | ||
toolGroup.setToolActive(StackScrollMouseWheelTool.toolName); | ||
|
||
// Get Cornerstone imageIds and fetch metadata into RAM | ||
const imageIds = await createImageIdsAndCacheMetaData({ | ||
StudyInstanceUID: | ||
'1.3.6.1.4.1.14519.5.2.1.7009.2403.334240657131972136850343327463', | ||
SeriesInstanceUID: | ||
'1.3.6.1.4.1.14519.5.2.1.7009.2403.226151125820845824875394858561', | ||
wadoRsRoot: 'https://d1qmxk7r72ysft.cloudfront.net/dicomweb', | ||
type: 'STACK', | ||
}); | ||
|
||
// Instantiate a rendering engine | ||
const renderingEngineId = 'myRenderingEngine'; | ||
const renderingEngine = new RenderingEngine(renderingEngineId); | ||
|
||
// Create a stack viewport | ||
const viewportId = 'CT_STACK'; | ||
const viewportInput = { | ||
viewportId, | ||
type: ViewportType.STACK, | ||
element, | ||
defaultOptions: { | ||
background: <Types.Point3>[0.2, 0, 0.2], | ||
}, | ||
}; | ||
|
||
renderingEngine.enableElement(viewportInput); | ||
|
||
// Set the tool group on the viewport | ||
toolGroup.addViewport(viewportId, renderingEngineId); | ||
|
||
// Get the stack viewport that was created | ||
const viewport = <Types.IStackViewport>( | ||
renderingEngine.getViewport(viewportId) | ||
); | ||
|
||
// Define a stack containing a single image | ||
const stack = [imageIds[0], imageIds[1]]; | ||
|
||
// Set the stack on the viewport | ||
viewport.setStack(stack); | ||
|
||
// Render the image | ||
viewport.render(); | ||
} | ||
|
||
run(); |
Oops, something went wrong.