Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 🎸 Allows configuration of a the segmentation properties #77

Merged
merged 11 commits into from
Nov 15, 2019
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);
}