Skip to content

Commit

Permalink
Merge pull request #835 from JamesAPetts/fix/brushDataAllocation
Browse files Browse the repository at this point in the history
Allocate labelmap memory on demand rather than on image load.
  • Loading branch information
JamesAPetts authored Feb 13, 2019
2 parents 1b38296 + 1b2d6fd commit 5e66375
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 92 deletions.
21 changes: 4 additions & 17 deletions src/eventListeners/onImageRenderedBrushEventHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,28 +61,15 @@ export default function(evt) {
const eventData = evt.detail;
const element = eventData.element;
const maxSegmentations = BaseBrushTool.getNumberOfColors();
let toolData = getToolState(
const activeSegIndex = store.modules.brush.state.drawColorId;

const toolData = getToolState(
element,
BaseBrushTool.getReferencedToolDataName()
);

if (!toolData) {
// Make toolData array as big as max number of segmentations.
for (let i = 0; i < maxSegmentations; i++) {
addToolState(element, BaseBrushTool.getReferencedToolDataName(), {});
}

toolData = getToolState(element, BaseBrushTool.getReferencedToolDataName());

// TEMP: HACK: Create first pixel data such that the tool has some data and the brush
// Cursor can be rendered. Can be replaced once we have a mechanism for SVG cursors.
const newPixelData = new Uint8ClampedArray(
eventData.image.width * eventData.image.height
);

toolData.data[0].pixelData = newPixelData;

toolData = getToolState(element, BaseBrushTool.getReferencedToolDataName());
return;
}

const enabledElement = external.cornerstone.getEnabledElement(element);
Expand Down
20 changes: 3 additions & 17 deletions src/eventListeners/onNewImageBrushEventHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,31 +14,17 @@ const { setters } = store.modules.brush;
export default function(evt) {
const eventData = evt.detail;
const element = eventData.element;
const activeSegIndex = store.modules.brush.state.drawColorId;
let toolData = getToolState(
element,
BaseBrushTool.getReferencedToolDataName()
);

if (!toolData) {
// Make toolData array as big as max number of segmentations.
const maxSegmentations = BaseBrushTool.getNumberOfColors();

for (let i = 0; i < maxSegmentations; i++) {
addToolState(element, BaseBrushTool.getReferencedToolDataName(), {});
}

toolData = getToolState(element, BaseBrushTool.getReferencedToolDataName());

// TEMP: HACK: Create first pixel data such that the tool has some data and the brush
// Cursor can be rendered. Can be replaced once we have a mechanism for SVG cursors.
const newPixelData = new Uint8ClampedArray(
eventData.image.width * eventData.image.height
);

toolData.data[0].pixelData = newPixelData;

addToolState(element, BaseBrushTool.getReferencedToolDataName(), {});
toolData = getToolState(element, BaseBrushTool.getReferencedToolDataName());
}

const enabledElement = external.cornerstone.getEnabledElement(element);
const maxSegmentations = BaseBrushTool.getNumberOfColors();

Expand Down
11 changes: 2 additions & 9 deletions src/tools/base/BaseBrushTool.js
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,7 @@ class BaseBrushTool extends BaseTool {
* @returns {null}
*/
static invalidateBrushOnEnabledElement(enabledElementUID) {
/** WIP **/
const element = store.getters.enabledElementByUID(enabledElementUID);

const stackToolState = getToolState(element, 'stack');
Expand All @@ -452,15 +453,6 @@ class BaseBrushTool extends BaseTool {

const toolState = globalImageIdSpecificToolStateManager.saveToolState();

// TODO -> Put this elsewhere
/*
const buffer = new ArrayBuffer(dim.xyz);
const unit8View = new Uint8Array(buffer);
console.log(unit8View.length);
*/

for (let i = 0; i < imageIds.length; i++) {
const imageId = imageIds[i];

Expand All @@ -484,6 +476,7 @@ class BaseBrushTool extends BaseTool {
* @return {type} description
*/
static getDataAsVolume(enabledElementUID) {
/** WIP **/
const element = store.getters.enabledElementByUID(enabledElementUID);

const stackToolState = getToolState(element, 'stack');
Expand Down
109 changes: 60 additions & 49 deletions src/tools/brush/BrushTool.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import external from './../../externalModules.js';
import BaseBrushTool from './../base/BaseBrushTool.js';
import { getToolState } from './../../stateManagement/toolState.js';
import {
getToolState,
addToolState,
} from './../../stateManagement/toolState.js';
import store from './../../store/index.js';
import brushUtils from './../../util/brush/index.js';
import EVENTS from '../../events';
Expand Down Expand Up @@ -118,87 +121,65 @@ function _overlappingStrategy(evt, configuration) {
const element = eventData.element;
const { rows, columns } = eventData.image;
const { x, y } = eventData.currentPoints.image;
const toolData = getToolState(element, configuration.referencedToolData);

let shouldErase = false;

// Check for key, could be a mouseDown or mouseDrag event.
if (_isCtrlDown(eventData)) {
console.log('ctrlDown');
shouldErase = true;
}

const segmentationIndex = state.drawColorId;

if (!toolData.data[segmentationIndex].pixelData) {
const newPixelData = new Uint8ClampedArray(
eventData.image.width * eventData.image.height
let toolState = getToolState(
element,
BaseBrushTool.getReferencedToolDataName()
);

if (!toolState) {
addToolState(element, BaseBrushTool.getReferencedToolDataName(), {});
toolState = getToolState(
element,
BaseBrushTool.getReferencedToolDataName()
);

toolData.data[segmentationIndex].pixelData = newPixelData;
}

const pixelData = toolData.data[segmentationIndex].pixelData;

const radius = state.radius;
const toolData = toolState.data;

if (x < 0 || x > columns || y < 0 || y > rows) {
return;
}

const radius = state.radius;
const pointerArray = getCircle(radius, rows, columns, x, y);

drawBrushPixels(pointerArray, pixelData, columns, shouldErase);

toolData.data[segmentationIndex].invalidated = true;
_drawMainColor(eventData, toolData, pointerArray);
}

function _nonOverlappingStrategy(evt, configuration) {
const eventData = evt.detail;
const element = eventData.element;
const { rows, columns } = eventData.image;
const { x, y } = eventData.currentPoints.image;
const toolState = getToolState(element, configuration.referencedToolData);
const toolData = toolState.data;

let shouldErase = false;

// Check for key, could be a mouseDown or mouseDrag event.
if (_isCtrlDown(eventData)) {
console.log('ctrlDown');
shouldErase = true;
}

const activeSegmentationIndex = state.drawColorId;
let toolState = getToolState(
element,
BaseBrushTool.getReferencedToolDataName()
);

if (!toolData[activeSegmentationIndex].pixelData) {
const newPixelData = new Uint8ClampedArray(
eventData.image.width * eventData.image.height
if (!toolState) {
addToolState(element, BaseBrushTool.getReferencedToolDataName(), {});
toolState = getToolState(
element,
BaseBrushTool.getReferencedToolDataName()
);

toolData[activeSegmentationIndex].pixelData = newPixelData;
}

const pixelData = toolData[activeSegmentationIndex].pixelData;

const radius = state.radius;
const toolData = toolState.data;
const segmentationIndex = state.drawColorId;

if (x < 0 || x > columns || y < 0 || y > rows) {
return;
}

const radius = state.radius;
const pointerArray = getCircle(radius, rows, columns, x, y);

// Draw / Erase the active color.
drawBrushPixels(pointerArray, pixelData, columns, shouldErase);

toolData[activeSegmentationIndex].invalidated = true;

const numberOfColors = BaseBrushTool.getNumberOfColors();

// If there is brush data in this region for other colors, delete it.
for (let i = 0; i < numberOfColors; i++) {
if (i === activeSegmentationIndex) {
if (i === segmentationIndex) {
continue;
}

Expand All @@ -207,6 +188,36 @@ function _nonOverlappingStrategy(evt, configuration) {
toolData[i].invalidated = true;
}
}

_drawMainColor(eventData, toolData, pointerArray);
}

function _drawMainColor(eventData, toolData, pointerArray) {
const shouldErase = _isCtrlDown(eventData);
const columns = eventData.image.columns;
const segmentationIndex = state.drawColorId;

if (shouldErase && !toolData[segmentationIndex]) {
// Erase command, yet no data yet, just return.
return;
}

if (!toolData[segmentationIndex]) {
toolData[segmentationIndex] = {};
}

if (!toolData[segmentationIndex].pixelData) {
toolData[segmentationIndex].pixelData = new Uint8ClampedArray(
eventData.image.width * eventData.image.height
);
}

const pixelData = toolData[segmentationIndex].pixelData;

// Draw / Erase the active color.
drawBrushPixels(pointerArray, pixelData, columns, shouldErase);

toolData[segmentationIndex].invalidated = true;
}

function _isCtrlDown(eventData) {
Expand Down

0 comments on commit 5e66375

Please sign in to comment.