WIP reorganization

This commit is contained in:
Erik Ziegler committed 2018-12-12 09:10:39 +01:00
1 parent 6706dfe634
commit 054e37dfb7
266 files changed
+98 -620

No files matched your search

@@ -0,0 +1,22 @@
import { cornerstoneTools } from 'meteor/ohif:cornerstone';
// Add a proxy to cornerstoneTools.drawHandles function to change the handles' active state base on
// the hover, moving and selected states
export default function(context, eventData, handles, color, options) {
Object.keys(handles).forEach(handleKey => {
if (handleKey === 'textBox') return;
const handle = handles[handleKey];
handle.drawnIndependently = handle.moving;
if (handle.selected) {
handle.active = handle.hover;
} else {
if (handle.hover) {
handle.active = true;
} else {
handle.active = false;
}
}
});
cornerstoneTools.drawHandles(context, eventData, handles, color, options);
}
@@ -0,0 +1,16 @@
import { cornerstone } from 'meteor/ohif:cornerstone';
// draw perpendicular line
export default function(context, element, data, color, lineWidth) {
// Draw perpendicular line
const { perpendicularStart, perpendicularEnd } = data.handles;
const perpendicularStartCanvas = cornerstone.pixelToCanvas(element, perpendicularStart);
const perpendicularEndCanvas = cornerstone.pixelToCanvas(element, perpendicularEnd);
context.beginPath();
context.strokeStyle = color;
context.lineWidth = lineWidth;
context.moveTo(perpendicularStartCanvas.x, perpendicularStartCanvas.y);
context.lineTo(perpendicularEndCanvas.x, perpendicularEndCanvas.y);
context.stroke();
}
@@ -0,0 +1,39 @@
import { _ } from 'meteor/underscore';
import { OHIF } from 'meteor/ohif:core';
import { cornerstone, cornerstoneTools } from 'meteor/ohif:cornerstone';
// Draw a line marker over the selected arm
export default function(eventData, handles, color) {
const lib = OHIF.lesiontracker.bidirectional;
const { canvasContext, element } = eventData;
const handleKey = lib.getSelectedHandleKey(handles);
if (!handleKey) return;
const handle = handles[handleKey];
// Used a big distance (1km) to fill the entire line
const mmStep = -1000000;
// Get the line's start and end points
const fakeImage = {
columnPixelSpacing: eventData.viewport.scale,
rowPixelSpacing: eventData.viewport.scale
};
const pointA = lib.repositionBidirectionalArmHandle(fakeImage, handles, handleKey, mmStep, 0);
const pointB = _.pick(handle, ['x', 'y']);
// Stop here if pointA is not present
if (!pointA) return;
// Get the canvas coordinates for the line var perpendicularStartCanvas = cornerstone.pixelToCanvas(element, data.handles.perpendicularStart);
const canvasPointA = cornerstone.pixelToCanvas(element, pointA);
const canvasPointB = cornerstone.pixelToCanvas(element, pointB);
// Draw the line marker
canvasContext.beginPath();
canvasContext.strokeStyle = color;
canvasContext.lineWidth = cornerstoneTools.toolStyle.getToolWidth();
canvasContext.moveTo(canvasPointA.x, canvasPointA.y);
canvasContext.lineTo(canvasPointB.x, canvasPointB.y);
canvasContext.stroke();
}
@@ -0,0 +1,2 @@
import onImageRendered from './onImageRendered';
export default onImageRendered;
@@ -0,0 +1,204 @@
import { cornerstone, cornerstoneMath, cornerstoneTools } from 'meteor/ohif:cornerstone';
import { OHIF } from 'meteor/ohif:core';
import { toolType } from '../definitions';
import drawHandles from './drawHandles';
import calculateLongestAndShortestDiameters from '../calculateLongestAndShortestDiameters';
import updatePerpendicularLineHandles from '../updatePerpendicularLineHandles';
import drawPerpendicularLine from './drawPerpendicularLine';
import drawSelectedMarker from './drawSelectedMarker';
export default function onImageRendered(event) {
const eventData = event.detail;
const { element, canvasContext } = eventData;
// if we have no toolData for this element, return immediately as there is nothing to do
const toolData = cornerstoneTools.getToolState(element, toolType);
if (!toolData) return;
const imagePlane = cornerstone.metaData.get('imagePlaneModule', eventData.image.imageId);
let rowPixelSpacing;
let colPixelSpacing;
if (imagePlane) {
rowPixelSpacing = imagePlane.rowPixelSpacing || imagePlane.rowImagePixelSpacing;
colPixelSpacing = imagePlane.columnPixelSpacing || imagePlane.colImagePixelSpacing;
} else {
rowPixelSpacing = eventData.image.rowPixelSpacing;
colPixelSpacing = eventData.image.columnPixelSpacing;
}
// LT-29 Disable Target Measurements when pixel spacing is not available
if (!rowPixelSpacing || !colPixelSpacing) {
return;
}
// we have tool data for this element - iterate over each one and draw it
const context = canvasContext.canvas.getContext('2d');
context.setTransform(1, 0, 0, 1, 0, 0);
let color;
const lineWidth = cornerstoneTools.toolStyle.getToolWidth();
const config = cornerstoneTools[toolType].getConfiguration();
for (let i = 0; i < toolData.data.length; i++) {
const data = toolData.data[i];
if (data.visible === false) continue;
const { start, end, perpendicularStart, perpendicularEnd, textBox } = data.handles;
const strokeWidth = lineWidth;
context.save();
// configurable shadow from CornerstoneTools
const { shadow } = config;
if (shadow && shadow.shadow) {
context.shadowColor = shadow.shadowColor || '#000000';
context.shadowOffsetX = shadow.shadowOffsetX || 1;
context.shadowOffsetY = shadow.shadowOffsetY || 1;
}
const activeColor = cornerstoneTools.toolColors.getActiveColor();
if (data.active) {
color = activeColor;
} else {
color = cornerstoneTools.toolColors.getToolColor();
}
// Update the perpendicular handles to draw it correctly
updatePerpendicularLineHandles(eventData, data);
// Draw the line
const { pixelToCanvas } = cornerstone;
const handleStartCanvas = pixelToCanvas(element, start);
const handleEndCanvas = pixelToCanvas(element, end);
const handlePerpendicularStartCanvas = pixelToCanvas(element, perpendicularStart);
const handlePerpendicularEndCanvas = pixelToCanvas(element, perpendicularEnd);
const canvasTextLocation = pixelToCanvas(element, textBox);
context.beginPath();
context.strokeStyle = color;
context.lineWidth = strokeWidth;
context.moveTo(handleStartCanvas.x, handleStartCanvas.y);
context.lineTo(handleEndCanvas.x, handleEndCanvas.y);
context.stroke();
// Draw perpendicular line
drawPerpendicularLine(context, element, data, color, strokeWidth);
// Draw the handles
const handlesColor = color;
drawHandles(context, eventData, data.handles, handlesColor, { drawHandlesIfActive: true });
// Draw the selected marker
drawSelectedMarker(eventData, data.handles, '#FF9999');
// Calculate the longest and shortest diameters, storing it in the respective attributes
calculateLongestAndShortestDiameters(eventData, data);
if (data.measurementNumber) {
// Draw the textbox
let suffix = ' mm';
if (!rowPixelSpacing || !colPixelSpacing) {
suffix = ' pixels';
}
const lengthText = ' L ' + data.longestDiameter + suffix;
const widthText = ' W ' + data.shortestDiameter + suffix;
let textLines = [`Target ${data.measurementNumber}`, lengthText, widthText];
// Append extra text lines when applies
if (data.additionalData && Array.isArray(data.additionalData.extraTextLines)) {
textLines = textLines.concat(data.additionalData.extraTextLines);
}
const boundingBox = cornerstoneTools.drawTextBox(
context,
textLines,
canvasTextLocation.x,
canvasTextLocation.y,
color,
config.textBox
);
textBox.boundingBox = boundingBox;
OHIF.cornerstone.repositionTextBox(eventData, data, config.textBox);
// Draw linked line as dashed
const link = {
start: {},
end: {}
};
const longLine = {
start: handleStartCanvas,
end: handleEndCanvas
};
const perpendicularLine = {
start: handlePerpendicularStartCanvas,
end: handlePerpendicularEndCanvas
};
// Check if the perpendicular line has some length (start and end are not equal)
// Note: this check is needed to prevent NaN value on the intersection result
const { distance } = cornerstoneMath.point;
const lineHasLength = distance(perpendicularLine.start, perpendicularLine.end) > 0;
// Define the lines intersection point
let linesIntersection;
if (lineHasLength) {
// As the line has length, define it as the intersection between the lines
const { intersectLine } = cornerstoneMath.lineSegment;
linesIntersection = intersectLine(longLine, perpendicularLine);
} else {
// As the line has no length, the tool is in its start position
linesIntersection = longLine.start;
}
const points = [
handleStartCanvas,
handleEndCanvas,
handlePerpendicularStartCanvas,
handlePerpendicularEndCanvas,
linesIntersection
];
link.end.x = canvasTextLocation.x;
link.end.y = canvasTextLocation.y;
link.start = cornerstoneMath.point.findClosestPoint(points, link.end);
const boundingBoxPoints = [ {
// Top middle point of bounding box
x: boundingBox.left + boundingBox.width / 2,
y: boundingBox.top
}, {
// Left middle point of bounding box
x: boundingBox.left,
y: boundingBox.top + boundingBox.height / 2
}, {
// Bottom middle point of bounding box
x: boundingBox.left + boundingBox.width / 2,
y: boundingBox.top + boundingBox.height
}, {
// Right middle point of bounding box
x: boundingBox.left + boundingBox.width,
y: boundingBox.top + boundingBox.height / 2
},
];
link.end = cornerstoneMath.point.findClosestPoint(boundingBoxPoints, link.start);
context.beginPath();
context.strokeStyle = color;
context.lineWidth = lineWidth;
context.setLineDash([ 2, 3 ]);
context.moveTo(link.start.x, link.start.y);
context.lineTo(link.end.x, link.end.y);
context.stroke();
}
context.restore();
}
}