@kitware/vtk.js
Version:
Visualization Toolkit for the Web
321 lines (255 loc) • 10.8 kB
JavaScript
import _defineProperty from '@babel/runtime/helpers/defineProperty';
import macro from '../../macros.js';
import vtkImageSlice from '../../Rendering/Core/ImageSlice.js';
import vtkImageMapper from '../../Rendering/Core/ImageMapper.js';
import vtkAbstractRepresentationProxy from '../Core/AbstractRepresentationProxy.js';
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
function sum(a, b) {
return a + b;
} // ----------------------------------------------------------------------------
function mean() {
for (var _len = arguments.length, array = new Array(_len), _key = 0; _key < _len; _key++) {
array[_key] = arguments[_key];
}
return array.reduce(sum, 0) / array.length;
} // ----------------------------------------------------------------------------
function updateDomains(dataset, dataArray, model, updateProp) {
var dataRange = dataArray.getRange();
var spacing = dataset.getSpacing();
var bounds = dataset.getBounds();
var extent = dataset.getExtent();
var sliceMin;
var sliceMax;
var stepVal;
var axisIndex;
var sliceMode = model.mapper.getSlicingMode();
var sliceModeLabel = 'IJKXYZ'[sliceMode];
switch (sliceMode) {
case vtkImageMapper.SlicingMode.I:
case vtkImageMapper.SlicingMode.J:
case vtkImageMapper.SlicingMode.K:
axisIndex = 'IJK'.indexOf(sliceModeLabel);
sliceMin = extent[axisIndex * 2];
sliceMax = extent[axisIndex * 2 + 1];
stepVal = 1;
break;
case vtkImageMapper.SlicingMode.X:
case vtkImageMapper.SlicingMode.Y:
case vtkImageMapper.SlicingMode.Z:
{
axisIndex = 'XYZ'.indexOf(sliceModeLabel);
sliceMin = bounds[axisIndex * 2];
sliceMax = bounds[axisIndex * 2 + 1];
var _model$mapper$getClos = model.mapper.getClosestIJKAxis(),
ijkMode = _model$mapper$getClos.ijkMode;
stepVal = spacing[ijkMode];
}
break;
}
var propToUpdate = {
slice: {
domain: {
min: sliceMin,
max: sliceMax,
step: stepVal
}
},
windowWidth: {
domain: {
min: 0,
max: dataRange[1] - dataRange[0],
step: 'any'
}
},
windowLevel: {
domain: {
min: dataRange[0],
max: dataRange[1],
step: 'any'
}
}
};
updateProp('slice', propToUpdate.slice);
updateProp('windowWidth', propToUpdate.windowWidth);
updateProp('windowLevel', propToUpdate.windowLevel);
return {
slice: mean(propToUpdate.slice.domain.min, propToUpdate.slice.domain.max),
windowWidth: propToUpdate.windowWidth.domain.max,
windowLevel: Math.floor(mean(propToUpdate.windowLevel.domain.min, propToUpdate.windowLevel.domain.max))
};
} // ----------------------------------------------------------------------------
// vtkSliceRepresentationProxy methods
// ----------------------------------------------------------------------------
function vtkSliceRepresentationProxy(publicAPI, model) {
// Set our className
model.classHierarchy.push('vtkSliceRepresentationProxy');
model.mapper = vtkImageMapper.newInstance();
model.actor = vtkImageSlice.newInstance();
model.property = model.actor.getProperty(); // connect rendering pipeline
model.actor.setMapper(model.mapper);
model.actors.push(model.actor);
function setInputData(inputDataset) {
var state = updateDomains(inputDataset, publicAPI.getDataArray(), model, publicAPI.updateProxyProperty);
publicAPI.set(state); // Init slice location
var bounds = inputDataset.getBounds();
var extent = inputDataset.getExtent();
switch (model.mapper.getSlicingMode()) {
case vtkImageMapper.SlicingMode.I:
publicAPI.setSlice(Math.floor(mean(extent[0], extent[1])));
break;
case vtkImageMapper.SlicingMode.J:
publicAPI.setSlice(Math.floor(mean(extent[2], extent[3])));
break;
case vtkImageMapper.SlicingMode.K:
publicAPI.setSlice(Math.floor(mean(extent[4], extent[5])));
break;
case vtkImageMapper.SlicingMode.X:
publicAPI.setSlice(mean(bounds[0], bounds[1]));
break;
case vtkImageMapper.SlicingMode.Y:
publicAPI.setSlice(mean(bounds[2], bounds[3]));
break;
case vtkImageMapper.SlicingMode.Z:
publicAPI.setSlice(mean(bounds[4], bounds[5]));
break;
}
} // Keep things updated
model.sourceDependencies.push(model.mapper);
model.sourceDependencies.push({
setInputData: setInputData
}); // keeps the slicing mode and domain info updated
function updateSlicingMode(mode) {
model.mapper.setSlicingMode(vtkImageMapper.SlicingMode[mode]); // Update to previously set position
var modelKey = "".concat(mode.toLowerCase(), "Slice");
if (modelKey in model && model[modelKey] !== undefined) {
model.mapper.setSlice(model[modelKey]);
}
if (model.input) {
// Update domains for UI...
var state = updateDomains(publicAPI.getInputDataSet(), publicAPI.getDataArray(), model, publicAPI.updateProxyProperty);
publicAPI.set(state);
}
publicAPI.modified();
} // API ----------------------------------------------------------------------
publicAPI.setSlicingMode = function (mode) {
if (!mode) {
return false;
}
if (model.slicingMode !== mode) {
// Update Mode
model.slicingMode = mode;
updateSlicingMode(mode);
return true;
}
return false;
};
publicAPI.getSliceIndex = function () {
if ('XYZ'.indexOf(model.slicingMode) !== -1) {
return model.mapper.getSliceAtPosition(model.mapper.getSlice());
}
return model.mapper.getSlice();
};
publicAPI.getAnnotations = function () {
var dynamicAddOn = {};
var sliceIndex = publicAPI.getSliceIndex();
var sliceBounds = model.mapper.getBoundsForSlice();
var sliceNormal = model.mapper.getSlicingModeNormal();
var _model$mapper$getClos2 = model.mapper.getClosestIJKAxis(),
ijkMode = _model$mapper$getClos2.ijkMode;
var sliceOrigin = [(sliceBounds[0] + sliceBounds[1]) * 0.5, (sliceBounds[2] + sliceBounds[3]) * 0.5, (sliceBounds[4] + sliceBounds[5]) * 0.5];
var slicePosition = 0;
if (sliceBounds[1] - sliceBounds[0] < Number.EPSILON) {
slicePosition = sliceBounds[0];
}
if (sliceBounds[3] - sliceBounds[2] < Number.EPSILON) {
slicePosition = sliceBounds[2];
}
if (sliceBounds[5] - sliceBounds[4] < Number.EPSILON) {
slicePosition = sliceBounds[4];
}
var imageData = model.mapper.getInputData();
if (imageData) {
dynamicAddOn.sliceSpacing = imageData.getSpacing()[ijkMode];
dynamicAddOn.dimensions = imageData.getDimensions();
dynamicAddOn.sliceCount = imageData.getDimensions()[ijkMode];
var ijkOrientation = [];
for (var i = 0; i < 3; i++) {
var extent = [0, 0, 0, 0, 0, 0];
extent[i * 2 + 1] = 1;
var tmpBounds = imageData.extentToBounds(extent);
if (tmpBounds[1] - tmpBounds[0] > Number.EPSILON) {
ijkOrientation[0] = 'IJK'[i];
}
if (tmpBounds[3] - tmpBounds[2] > Number.EPSILON) {
ijkOrientation[1] = 'IJK'[i];
}
if (tmpBounds[5] - tmpBounds[4] > Number.EPSILON) {
ijkOrientation[2] = 'IJK'[i];
}
}
dynamicAddOn.ijkOrientation = ijkOrientation.join('');
}
return _objectSpread({
ijkMode: ijkMode,
sliceBounds: sliceBounds,
sliceIndex: sliceIndex,
sliceNormal: sliceNormal,
sliceOrigin: sliceOrigin,
slicePosition: slicePosition
}, dynamicAddOn);
};
var parentSetColorBy = publicAPI.setColorBy;
publicAPI.setColorBy = function (arrayName, arrayLocation) {
var componentIndex = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : -1;
if (arrayName === null) {
model.property.setRGBTransferFunction(null);
model.property.setPiecewiseFunction(null);
} else {
parentSetColorBy(arrayName, arrayLocation, componentIndex);
var lutProxy = publicAPI.getLookupTableProxy(arrayName);
var pwfProxy = publicAPI.getPiecewiseFunctionProxy(arrayName);
model.property.setRGBTransferFunction(lutProxy.getLookupTable());
model.property.setPiecewiseFunction(pwfProxy.getPiecewiseFunction());
}
}; // Initialize slicing mode
updateSlicingMode(model.slicingMode || 'X');
} // ----------------------------------------------------------------------------
// Object factory
// ----------------------------------------------------------------------------
var DEFAULT_VALUES = {}; // ----------------------------------------------------------------------------
function extend(publicAPI, model) {
var initialValues = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
Object.assign(model, DEFAULT_VALUES, initialValues); // Object methods
vtkAbstractRepresentationProxy.extend(publicAPI, model, initialValues);
macro.get(publicAPI, model, ['slicingMode']); // Object specific methods
vtkSliceRepresentationProxy(publicAPI, model); // Proxyfy
macro.proxyPropertyMapping(publicAPI, model, {
visibility: {
modelKey: 'actor',
property: 'visibility'
},
windowWidth: {
modelKey: 'property',
property: 'colorWindow'
},
windowLevel: {
modelKey: 'property',
property: 'colorLevel'
},
interpolationType: {
modelKey: 'property',
property: 'interpolationType'
},
slice: {
modelKey: 'mapper',
property: 'slice'
}
});
} // ----------------------------------------------------------------------------
var newInstance = macro.newInstance(extend, 'vtkSliceRepresentationProxy'); // ----------------------------------------------------------------------------
var vtkSliceRepresentationProxy$1 = {
newInstance: newInstance,
extend: extend
};
export { vtkSliceRepresentationProxy$1 as default, extend, newInstance };