Skip to content
Merged
39 changes: 36 additions & 3 deletions src/VTKViewport/View2D.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,11 @@ import vtkSVGWidgetManager from './vtkSVGWidgetManager';
import ViewportOverlay from '../ViewportOverlay/ViewportOverlay.js';
import { ViewTypes } from 'vtk.js/Sources/Widgets/Core/WidgetManager/Constants';
import { createSub } from '../lib/createSub.js';
import realsApproximatelyEqual from '../lib/math/realsApproximatelyEqual';
import createLabelPipeline from './createLabelPipeline';

const minSlabThickness = 0.1; // TODO -> Should this be configurable or not?

export default class View2D extends Component {
static propTypes = {
volumes: PropTypes.array.isRequired,
Expand All @@ -27,10 +30,14 @@ export default class View2D extends Component {
onCreated: PropTypes.func,
onDestroyed: PropTypes.func,
orientation: PropTypes.object,
labelmapRenderingOptions: PropTypes.object,
};

static defaultProps = {
painting: false,
labelmapRenderingOptions: {
visible: true,
},
};

constructor(props) {
Expand Down Expand Up @@ -258,8 +265,6 @@ export default class View2D extends Component {
if (currentIStyle.getSlabThickness) {
return currentIStyle.getSlabThickness();
}

//return this.currentSlabThickness;
}

setSlabThickness(slabThickness) {
Expand All @@ -268,6 +273,23 @@ export default class View2D extends Component {

if (istyle.setSlabThickness) {
istyle.setSlabThickness(slabThickness);

if (this.props.paintFilterLabelMapImageData) {
const labelmapActor = this.labelmap.actor;

if (realsApproximatelyEqual(slabThickness, minSlabThickness)) {
if (
labelmapActor.getVisibility() !==
this.props.labelmapRenderingOptions.visible
) {
labelmapActor.setVisibility(
this.props.labelmapRenderingOptions.visible
);
}
} else {
labelmapActor.setVisibility(false);
}
}
}

renderWindow.render();
Expand Down Expand Up @@ -392,7 +414,8 @@ export default class View2D extends Component {
const labelmapImageData = this.props.paintFilterLabelMapImageData;
const labelmap = createLabelPipeline(
this.props.paintFilterBackgroundImageData,
labelmapImageData
labelmapImageData,
this.props.labelmapRenderingOptions
);

this.labelmap = labelmap;
Expand All @@ -410,6 +433,16 @@ export default class View2D extends Component {
);
}

if (
prevProps.labelmapRenderingOptions &&
prevProps.labelmapRenderingOptions.visible !==
this.props.labelmapRenderingOptions.visible
) {
this.labelmap.actor.setVisibility(
prevProps.labelmapRenderingOptions.visible
);
}

if (prevProps.painting !== this.props.painting) {
if (this.props.painting) {
this.viewWidget = this.widgetManager.addWidget(
Expand Down
5 changes: 5 additions & 0 deletions src/VTKViewport/View3D.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,15 @@ export default class View3D extends Component {
dataDetails: PropTypes.object,
onCreated: PropTypes.func,
onDestroyed: PropTypes.func,
labelmapRenderingOptions: PropTypes.object,
};

static defaultProps = {
painting: false,
sliceNormal: [0, 0, 1],
labelmapRenderingOptions: {
visible: true,
},
};

constructor(props) {
Expand Down Expand Up @@ -189,6 +193,7 @@ export default class View3D extends Component {
const labelmap = createLabelPipeline(
this.props.paintFilterBackgroundImageData,
labelmapImageData,
this.props.labelmapRenderingOptions,
true
);

Expand Down
45 changes: 40 additions & 5 deletions src/VTKViewport/createLabelPipeline.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,21 @@ import vtkPiecewiseFunction from 'vtk.js/Sources/Common/DataModel/PiecewiseFunct
export default function createLabelPipeline(
backgroundImageData,
paintFilterLabelMapImageData,
options,
useSampleDistance = false
) {
let labelMapData;

let { colorLUT, globalOpacity, visible } = options;

if (visible === undefined) {
visible = false;
}

if (globalOpacity === undefined) {
globalOpacity = 1.0;
}

if (paintFilterLabelMapImageData) {
labelMapData = paintFilterLabelMapImageData;
} else {
Expand Down Expand Up @@ -53,17 +64,41 @@ export default function createLabelPipeline(

// labelmap pipeline
labelMap.actor.setMapper(labelMap.mapper);
labelMap.actor.setVisibility(visible);
labelMap.ofun.addPoint(0, 0);

// set up labelMap color and opacity mapping
labelMap.cfun.addRGBPoint(1, 1, 0, 0); // label '1' will be red
labelMap.cfun.addRGBPoint(2, 0, 1, 0); // label '2' will be green
labelMap.cfun.addRGBPoint(3, 0, 1, 1); // label '3' will be blue
labelMap.ofun.addPoint(0, 0);
labelMap.ofun.addPoint(1, 0.9);
if (colorLUT) {
// TODO -> It seems to crash if you set it higher than 256??
const numColors = Math.min(256, colorLUT.length);

for (let i = 0; i < numColors; i++) {
//for (let i = 0; i < colorLUT.length; i++) {
const color = colorLUT[i];
labelMap.cfun.addRGBPoint(
i,
color[0] / 255,
color[1] / 255,
color[2] / 255
);

const segmentOpacity = (color[3] / 255) * globalOpacity;
labelMap.ofun.addPointLong(i, segmentOpacity, 0.5, 1.0);
}
} else {
// Some default.
labelMap.cfun.addRGBPoint(1, 1, 0, 0); // label '1' will be red
labelMap.cfun.addRGBPoint(2, 0, 1, 0); // label '2' will be green
labelMap.cfun.addRGBPoint(3, 0, 1, 1); // label '3' will be blue
labelMap.ofun.addPoint(1, 0.5); // All labels full opacity
}

labelMap.actor.getProperty().setRGBTransferFunction(0, labelMap.cfun);
labelMap.actor.getProperty().setScalarOpacity(0, labelMap.ofun);

labelMap.actor.getProperty().setInterpolationTypeToNearest();
labelMap.actor.getProperty().setScalarOpacityUnitDistance(0, 0.1);
labelMap.actor.getProperty().setUseGradientOpacity(0, false);

return labelMap;
}
9 changes: 7 additions & 2 deletions src/helpers/formatDA.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@ export default function formatDA(date, strFormat = 'MMM D, YYYY') {
return;
}

const parsedDateTime = parse(date, 'YYYYMMDD');
try {
const parsedDateTime = parse(date, 'yyyyMMdd', new Date());
const formattedDateTime = format(parsedDateTime, strFormat);

return format(parsedDateTime, strFormat);
return formattedDateTime;
} catch (err) {
// swallow?
}
}
18 changes: 10 additions & 8 deletions src/helpers/formatTM.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,16 @@ export default function formatTM(time, strFormat = 'HH:mm:ss') {
return;
}

// DICOM Time is stored as HHmmss.SSS, where:
// HH 24 hour time:
// m mm 0..59 Minutes
// s ss 0..59 Seconds
// S SS SSS 0..999 Fractional seconds
//
// See MomentJS: http://momentjs.com/docs/#/parsing/string-format/
const parsedDateTime = parse(time, 'HHmmss.SSS');
try {
const inputFormat = 'HHmmss.SSS';
const strTime = time.toString().substring(0, inputFormat.length);
const parsedDateTime = parse(strTime, 'HHmmss.SSS', new Date(0));
const formattedDateTime = format(parsedDateTime, strFormat);

return formattedDateTime;
} catch (err) {
// swallow?
}

return format(parsedDateTime, strFormat);
}