UNPKG

@kitware/vtk.js

Version:

Visualization Toolkit for the Web

154 lines (130 loc) 5.34 kB
import { m as macro } from '../../macros2.js'; import vtkImageData from '../../Common/DataModel/ImageData.js'; import vtkDataArray from '../../Common/Core/DataArray.js'; const { vtkErrorMacro } = macro; // ---------------------------------------------------------------------------- // vtkImageCropFilter methods // ---------------------------------------------------------------------------- function vtkImageCropFilter(publicAPI, model) { // Set our className model.classHierarchy.push('vtkImageCropFilter'); // -------------------------------------------------------------------------- publicAPI.reset = () => { const data = publicAPI.getInputData(); if (data) { publicAPI.setCroppingPlanes(...data.getExtent()); } }; // -------------------------------------------------------------------------- publicAPI.requestData = (inData, outData) => { // implement requestData const input = inData[0]; if (!input) { vtkErrorMacro('Invalid or missing input'); return; } const outImage = outData[0]?.initialize() || vtkImageData.newInstance(); outData[0] = outImage; const scalars = input.getPointData().getScalars(); if (!scalars) { vtkErrorMacro('No scalars from input'); return; } const extent = input.getExtent(); const cropped = model.croppingPlanes && model.croppingPlanes.length === 6 ? extent.map((e, i) => { if (i % 2 === 0) { // min plane return Math.max(e, Math.round(model.croppingPlanes[i])); } // max plane return Math.min(e, Math.round(model.croppingPlanes[i])); }) : extent.slice(); if (cropped[0] === extent[0] && cropped[1] === extent[1] && cropped[2] === extent[2] && cropped[3] === extent[3] && cropped[4] === extent[4] && cropped[5] === extent[5]) { outImage.shallowCopy(input); // Force new mtime return; } // reorder if needed for (let i = 0; i < 3; ++i) { if (cropped[i * 2] > cropped[i * 2 + 1]) { [cropped[i * 2], cropped[i * 2 + 1]] = [cropped[i * 2 + 1], cropped[i * 2]]; } } // restrict crop bounds based on extent bounds for (let i = 0; i < 6; i += 2) { // min case cropped[i] = Math.max(cropped[i], extent[i]); // max case cropped[i + 1] = Math.min(cropped[i + 1], extent[i + 1]); } const numberOfComponents = scalars.getNumberOfComponents(); const componentSize = (cropped[1] - cropped[0] + 1) * (cropped[3] - cropped[2] + 1) * (cropped[5] - cropped[4] + 1) * numberOfComponents; const scalarsData = scalars.getData(); const dims = input.getDimensions(); const jStride = numberOfComponents * dims[0]; const kStride = numberOfComponents * dims[0] * dims[1]; const beginOffset = (cropped[0] - extent[0]) * numberOfComponents; const stripSize = (cropped[1] - cropped[0] + 1) * numberOfComponents; // +1 because subarray end is exclusive // crop image const croppedArray = new scalarsData.constructor(componentSize); let index = 0; for (let k = cropped[4]; k <= cropped[5]; ++k) { for (let j = cropped[2]; j <= cropped[3]; ++j) { const begin = beginOffset + (j - extent[2]) * jStride + (k - extent[4]) * kStride; const end = begin + stripSize; const slice = scalarsData.subarray(begin, end); croppedArray.set(slice, index); index += slice.length; } } outImage.setExtent(cropped); outImage.setOrigin(input.getOrigin()); outImage.setSpacing(input.getSpacing()); outImage.setDirection(input.getDirection()); const croppedScalars = vtkDataArray.newInstance({ name: scalars.getName(), numberOfComponents, values: croppedArray }); outImage.getPointData().setScalars(croppedScalars); }; publicAPI.isResetAvailable = () => { if (model.croppingPlanes == null || model.croppingPlanes.length === 0) { return false; } const data = publicAPI.getInputData(); if (data) { const originalExtent = data.getExtent(); const findDifference = originalExtent.find((v, i) => Math.abs(model.croppingPlanes[i] - v) > Number.EPSILON); return findDifference !== undefined; } return false; }; } // ---------------------------------------------------------------------------- // Object factory // ---------------------------------------------------------------------------- const DEFAULT_VALUES = { // croppingPlanes: null, }; // ---------------------------------------------------------------------------- function extend(publicAPI, model, initialValues = {}) { Object.assign(model, DEFAULT_VALUES, initialValues); // Make this a VTK object macro.obj(publicAPI, model); // Also make it an algorithm with one input and one output macro.algo(publicAPI, model, 1, 1); // no orientation support yet macro.setGetArray(publicAPI, model, ['croppingPlanes'], 6); // Object specific methods vtkImageCropFilter(publicAPI, model); } // ---------------------------------------------------------------------------- const newInstance = macro.newInstance(extend, 'vtkImageCropFilter'); // ---------------------------------------------------------------------------- var vtkImageCropFilter$1 = { newInstance, extend }; export { vtkImageCropFilter$1 as default, extend, newInstance };