Skip to content

Commit

Permalink
fix: reference line exports and add cpu demo (#297)
Browse files Browse the repository at this point in the history
* fix: referece line exports and add cpu demo

* fix build
  • Loading branch information
sedghi authored Nov 14, 2022
1 parent 3dc4e36 commit e20d0b2
Show file tree
Hide file tree
Showing 5 changed files with 225 additions and 1 deletion.
4 changes: 3 additions & 1 deletion common/reviews/api/tools.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -3601,7 +3601,7 @@ interface ReferenceLineAnnotation extends Annotation {
}

// @public (undocumented)
export class ReferenceLinesTool extends AnnotationDisplayTool {
class ReferenceLines extends AnnotationDisplayTool {
constructor(toolProps?: PublicToolProps, defaultToolProps?: ToolProps);
// (undocumented)
editData: {
Expand Down Expand Up @@ -3634,6 +3634,8 @@ export class ReferenceLinesTool extends AnnotationDisplayTool {
// (undocumented)
touchDragCallback: any;
}
export { ReferenceLines }
export { ReferenceLines as ReferenceLinesTool }

// @public (undocumented)
function registerCursor(toolName: string, iconContent: string, viewBox: {
Expand Down
214 changes: 214 additions & 0 deletions packages/tools/examples/localCPU/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
import { RenderingEngine, Types, Enums, metaData } from '@cornerstonejs/core';
import cornerstoneWADOImageLoader from 'cornerstone-wado-image-loader';
import * as cornerstoneTools from '@cornerstonejs/tools';
import htmlSetup from '../local/htmlSetup';
import uids from '../local/uids';

import initProviders from '../../../../utils/demo/helpers/initProviders';
import initCornerstoneWADOImageLoader from '../../../../utils/demo/helpers/initCornerstoneWADOImageLoader';
import initVolumeLoader from './../../../../utils/demo/helpers/initVolumeLoader';
import { setUseCPURendering } from '@cornerstonejs/core';

const {
PanTool,
WindowLevelTool,
StackScrollMouseWheelTool,
ZoomTool,
ToolGroupManager,
Enums: csToolsEnums,
} = cornerstoneTools;

const { MouseBindings } = csToolsEnums;

import { setTitleAndDescription } from '../../../../utils/demo/helpers';

// This is for debugging purposes
console.warn(
'Click on index.ts to open source code for this example --------->'
);

const { ViewportType } = Enums;

// ======== Set up page ======== //
setTitleAndDescription(
'DICOM P10 from local file system (CPU)',
'Cornerstone3D uses WebGL for rendering by default (if available) and a fallback to CPU. This example force rendering on CPU for debugging purposes.'
);

// ============================= //

const { element } = htmlSetup(document);

const dropZone = document.getElementById('cornerstone-element');
dropZone.addEventListener('dragover', handleDragOver, false);
dropZone.addEventListener('drop', handleFileSelect, false);

let viewport;

const toolGroupId = 'myToolGroup';

document
.getElementById('selectFile')
.addEventListener('change', function (e: any) {
// Add the file to the cornerstoneFileImageLoader and get unique
// number for that file
const file = e.target.files[0];
const imageId = cornerstoneWADOImageLoader.wadouri.fileManager.add(file);
loadAndViewImage(imageId);
});

/**
* Runs the demo
*/
async function run() {
// Init Cornerstone and related libraries
await initCornerstoneWADOImageLoader();
await initVolumeLoader();
await initProviders();

setUseCPURendering(true);

cornerstoneTools.addTool(PanTool);
cornerstoneTools.addTool(WindowLevelTool);
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 tools to the tool group
toolGroup.addTool(WindowLevelTool.toolName);
toolGroup.addTool(PanTool.toolName);
toolGroup.addTool(ZoomTool.toolName);
toolGroup.addTool(StackScrollMouseWheelTool.toolName);

// Set the initial state of the tools, here all tools are active and bound to
// Different mouse inputs
toolGroup.setToolActive(WindowLevelTool.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

// 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);

// Get the stack viewport that was created
viewport = <Types.IStackViewport>renderingEngine.getViewport(viewportId);

toolGroup.addViewport(viewportId, renderingEngineId);
}

// this function gets called once the user drops the file onto the div
function handleFileSelect(evt) {
evt.stopPropagation();
evt.preventDefault();

// Get the FileList object that contains the list of files that were dropped
const files = evt.dataTransfer.files;

// this UI is only built for a single file so just dump the first one
const file = files[0];
const imageId = cornerstoneWADOImageLoader.wadouri.fileManager.add(file);
loadAndViewImage(imageId);
}

function handleDragOver(evt) {
evt.stopPropagation();
evt.preventDefault();
evt.dataTransfer.dropEffect = 'copy'; // Explicitly show this is a copy.
}

function loadAndViewImage(imageId) {
const stack = [imageId];
// Set the stack on the viewport
viewport.setStack(stack).then(() => {
// Set the VOI of the stack
// viewport.setProperties({ voiRange: ctVoiRange });
// Render the image
viewport.render();

const imageData = viewport.getImageData();

const {
pixelRepresentation,
bitsAllocated,
bitsStored,
highBit,
photometricInterpretation,
} = metaData.get('imagePixelModule', imageId);

const voiLutModule = metaData.get('voiLutModule', imageId);

const sopCommonModule = metaData.get('sopCommonModule', imageId);
const transferSyntax = metaData.get('transferSyntax', imageId);

document.getElementById('transfersyntax').innerHTML =
transferSyntax.transferSyntaxUID;
document.getElementById('sopclassuid').innerHTML = `${
sopCommonModule.sopClassUID
} [${uids[sopCommonModule.sopClassUID]}]`;
document.getElementById('sopinstanceuid').innerHTML =
sopCommonModule.sopInstanceUID;
document.getElementById('rows').innerHTML = imageData.dimensions[0];
document.getElementById('columns').innerHTML = imageData.dimensions[1];
document.getElementById('spacing').innerHTML = imageData.spacing.join('\\');
document.getElementById('direction').innerHTML = imageData.direction
.map((x) => Math.round(x * 100) / 100)
.join(',');

document.getElementById('origin').innerHTML = imageData.origin
.map((x) => Math.round(x * 100) / 100)
.join(',');
document.getElementById('modality').innerHTML = imageData.metadata.Modality;

document.getElementById('pixelrepresentation').innerHTML =
pixelRepresentation;
document.getElementById('bitsallocated').innerHTML = bitsAllocated;
document.getElementById('bitsstored').innerHTML = bitsStored;
document.getElementById('highbit').innerHTML = highBit;
document.getElementById('photometricinterpretation').innerHTML =
photometricInterpretation;
document.getElementById('windowcenter').innerHTML =
voiLutModule.windowCenter;
document.getElementById('windowwidth').innerHTML = voiLutModule.windowWidth;
});
}

run();
2 changes: 2 additions & 0 deletions packages/tools/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ import {
BrushTool,
AngleTool,
MagnifyTool,
ReferenceLines,
} from './tools';

import * as Enums from './enums';
Expand Down Expand Up @@ -86,6 +87,7 @@ export {
ArrowAnnotateTool,
AngleTool,
MagnifyTool,
ReferenceLines,
// Segmentation Display
SegmentationDisplayTool,
// Segmentation Editing Tools
Expand Down
2 changes: 2 additions & 0 deletions packages/tools/src/tools/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import EllipticalROITool from './annotation/EllipticalROITool';
import PlanarFreehandROITool from './annotation/PlanarFreehandROITool';
import ArrowAnnotateTool from './annotation/ArrowAnnotateTool';
import AngleTool from './annotation/AngleTool';
import ReferenceLines from './ReferenceLinesTool';

// Segmentation DisplayTool
import SegmentationDisplayTool from './displayTools/SegmentationDisplayTool';
Expand Down Expand Up @@ -67,4 +68,5 @@ export {
RectangleROIStartEndThresholdTool,
BrushTool,
MagnifyTool,
ReferenceLines,
};
4 changes: 4 additions & 0 deletions utils/ExampleRunner/example-info.json
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@
"name": "DICOM P10 from the local file system",
"description": "Provides an interface to load a DICOM P10 image from your local file system to the Cornerstone3D"
},
"local (CPU)": {
"name": "DICOM P10 from the local file system using CPU",
"description": "Cornerstone3D uses WebGL for rendering by default (if available) and a fallback to CPU. This example force rendering on CPU for debugging purposes."
},
"stackAnnotationTools": {
"name": "Stack Annotation Tools",
"description": "Demonstrates usage of various annotation tools (Probe, Rectangle ROI, Elliptical ROI, Bidirectional measurements) on a Stack Viewport."
Expand Down

0 comments on commit e20d0b2

Please sign in to comment.