UNPKG

@kitware/vtk.js

Version:

Visualization Toolkit for the Web

321 lines (291 loc) 11.3 kB
import { m as macro } from '../../macros2.js'; // ---------------------------------------------------------------------------- // Global methods // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // vtkImagePointDataIterator methods // ---------------------------------------------------------------------------- function vtkImagePointDataIterator(publicAPI, model) { // Set our className model.classHierarchy.push('vtkImagePointDataIterator'); publicAPI.initialize = (image, inExtent, stencil, algorithm) => { const dataExtent = image.getExtent(); let extent = inExtent; if (extent == null) { extent = dataExtent; } let emptyExtent = false; for (let i = 0; i < 6; i += 2) { model.extent[i] = Math.max(extent[i], dataExtent[i]); model.extent[i + 1] = Math.min(extent[i + 1], dataExtent[i + 1]); if (model.extent[i] > model.extent[i + 1]) { emptyExtent = true; } } model.rowIncrement = dataExtent[1] - dataExtent[0] + 1; model.sliceIncrement = model.rowIncrement * (dataExtent[3] - dataExtent[2] + 1); let rowSpan; let sliceSpan; let volumeSpan; if (!emptyExtent) { // Compute the span of the image region to be covered. rowSpan = model.extent[1] - model.extent[0] + 1; sliceSpan = model.extent[3] - model.extent[2] + 1; volumeSpan = model.extent[5] - model.extent[4] + 1; model.id = model.extent[0] - dataExtent[0] + (model.extent[2] - dataExtent[2]) * model.rowIncrement + (model.extent[4] - dataExtent[4]) * model.sliceIncrement; // Compute the end increments (continuous increments). model.rowEndIncrement = model.rowIncrement - rowSpan; model.sliceEndIncrement = model.rowEndIncrement + model.sliceIncrement - model.rowIncrement * sliceSpan; } else { // Extent is empty, isAtEnd() will immediately return "true" rowSpan = 0; sliceSpan = 0; volumeSpan = 0; model.id = 0; model.rowEndIncrement = 0; model.sliceEndIncrement = 0; for (let i = 0; i < 6; i += 2) { model.extent[i] = dataExtent[i]; model.extent[i + 1] = dataExtent[i] - 1; } } // Get the end pointers for row, slice, and volume. model.spanEnd = model.id + rowSpan; model.rowEnd = model.id + rowSpan; model.sliceEnd = model.id + (model.rowIncrement * sliceSpan - model.rowEndIncrement); model.end = model.id + (model.sliceIncrement * volumeSpan - model.sliceEndIncrement); // For keeping track of the current x,y,z index. model.index[0] = model.extent[0]; model.index[1] = model.extent[2]; model.index[2] = model.extent[4]; // For resetting the Y index after each slice. model.startY = model.index[1]; // Code for when a stencil is provided. if (stencil) { model.hasStencil = true; model.inStencil = false; model.spanIndex = 0; const stencilExtent = stencil.getExtent(); // The stencil has a YZ array of span lists, we need increments // to get to the next Z position in the YZ array. model.spanSliceIncrement = 0; model.spanSliceEndIncrement = 0; if (stencilExtent[3] >= stencilExtent[2] && stencilExtent[5] >= stencilExtent[4]) { model.spanSliceIncrement = stencilExtent[3] - stencilExtent[2] + 1; const botOffset = model.extent[2] - stencilExtent[2]; if (botOffset >= 0) { model.spanSliceEndIncrement += botOffset; } const topOffset = stencilExtent[3] - model.extent[3]; if (topOffset >= 0) { model.spanSliceEndIncrement += topOffset; } } // Find the offset to the start position within the YZ array. let startOffset = 0; const yOffset = model.extent[2] - stencilExtent[2]; if (yOffset < 0) { model.extent[2] = stencilExtent[2]; // starting before start of stencil: subtract the increment that // will be added in NextSpan() upon entry into stencil extent startOffset -= 1; } else { // starting partway into the stencil, so add an offset startOffset += yOffset; } if (stencilExtent[3] <= model.extent[3]) { model.extent[3] = stencilExtent[3]; } const zOffset = model.extent[4] - stencilExtent[4]; if (zOffset < 0) { model.extent[4] = stencilExtent[4]; // starting before start of stencil: subtract the increment that // will be added in NextSpan() upon entry into stencil extent if (yOffset >= 0) { startOffset -= 1 + model.spanSliceEndIncrement; } } else { // starting partway into the stencil, so add an offset startOffset += zOffset * model.spanSliceIncrement; } if (stencilExtent[5] <= model.extent[5]) { model.extent[5] = stencilExtent[5]; } if (model.extent[2] <= model.extent[3] && model.extent[4] <= model.extent[5]) { model.spanCountPointer = stencil.extentListLengths.subarray(startOffset); model.spanListPointer = stencil.extentLists.subarray(startOffset); // Get the current position within the span list for the current row if (yOffset >= 0 && zOffset >= 0) { // If starting within stencil extent, check stencil immediately model.inStencil = true; model.setSpanState(model.extent[0]); } } else { model.spanCountPointer = null; model.spanListPointer = null; model.inStencil = false; } } else { model.hasStencil = false; model.inStencil = true; model.spanSliceEndIncrement = 0; model.spanSliceIncrement = 0; model.spanIndex = 0; model.spanCountPointer = null; model.spanListPointer = null; } if (algorithm) { model.algorithm = algorithm; const maxCount = sliceSpan * volumeSpan; model.target = maxCount / 50 + 1; model.count = model.target * 50 - maxCount / model.target * model.target + 1; } else { model.algorithm = null; model.target = 0; model.count = 0; } }; publicAPI.setSpanState = idX => { // Find the span that includes idX let inStencil = false; const spans = model.spanListPointer; const n = model.spanCountPointer[0]; let i; for (i = 0; i < n; ++i) { if (spans[i] > idX) { break; } inStencil = !inStencil; } // Set the primary span state variables model.spanIndex = i; model.inStencil = inStencil; // Clamp the span end to MaxX+1 let endIdX = model.extent[1] + 1; if (i < n && spans[i] <= model.extent[1]) { endIdX = spans[i]; } // Compute the pointers for idX and endIdX const rowStart = model.rowEnd - (model.rowIncrement - model.rowEndIncrement); model.id = rowStart + (idX - model.extent[0]); model.spanEnd = rowStart + (endIdX - model.extent[0]); }; publicAPI.nextSpan = () => { if (model.spanEnd === model.rowEnd) { let spanIncr = 1; if (model.spanEnd !== model.sliceEnd) { // Move to the next row model.id = model.rowEnd + model.rowEndIncrement; model.rowEnd += model.rowIncrement; model.spanEnd = model.rowEnd; model.index[1]++; } else if (model.spanEnd !== model.end) { // Move to the next slice model.id = model.sliceEnd + model.sliceEndIncrement; model.sliceEnd += model.sliceIncrement; model.rowEnd = model.id + (model.rowIncrement - model.rowEndIncrement); model.spanEnd = model.rowEnd; model.index[1] = model.startY; model.index[2]++; spanIncr += model.spanSliceEndIncrement; } else { // reached End model.id = model.end; return; } // Start of next row model.index[0] = model.extent[0]; if (model.hasStencil) { if (model.index[1] >= model.extent[2] && model.index[1] <= model.extent[3] && model.index[2] >= model.extent[4] && model.index[2] <= model.extent[5]) { model.spanCountPointer = model.spanCountPointer.subarray(spanIncr); model.spanListPointer = model.spanListPointer.subarray(spanIncr); publicAPI.setSpanState(model.extent[0]); } else { model.inStencil = false; } } if (model.algorithm) { publicAPI.reportProgress(); } } else { // Move to the next span in the current row model.id = model.spanEnd; const spanCount = model.spanCountPointer[0]; let endIdX = model.extent[1] + 1; model.index[0] = endIdX; if (model.spanIndex < spanCount) { const tmpIdX = model.spanListPointer[model.spanIndex]; if (tmpIdX < endIdX) { model.index[0] = tmpIdX; } } // Get the index to the start of the span after the next model.spanIndex++; if (model.spanIndex < spanCount) { const tmpIdX = model.spanListPointer[model.spanIndex]; if (tmpIdX < endIdX) { endIdX = tmpIdX; } } // Compute the end of the span model.spanEnd = model.rowEnd - (model.rowIncrement - model.rowEndIncrement) + (endIdX - model.extent[0]); // Flip the state model.inStencil = !model.inStencil; } }; publicAPI.isAtEnd = () => model.id === model.end; publicAPI.isInStencil = () => model.inStencil; publicAPI.spanEndId = () => model.spanEnd; publicAPI.reportProgress = () => {}; publicAPI.getArray = (array, i) => array.getData().subarray(i * array.getNumberOfComponents()); publicAPI.getScalars = function (image) { let i = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; return publicAPI.getArray(image.getPointData().getScalars(), i); }; } // ---------------------------------------------------------------------------- // Object factory // ---------------------------------------------------------------------------- const DEFAULT_VALUES = { spanState: 0, extent: [0, -1, 0, -1, 0, -1], end: 0, spanEnd: 0, rowEnd: 0, sliceEnd: 0, rowIncrement: 0, rowEndIncrement: 0, sliceIncrement: 0, sliceEndIncrement: 0, id: 0, index: [0, 0, 0], startY: 0, hasStencil: false, inStencil: true, spanIndex: 0, spanSliceIncrement: 0, spanSliceEndIncrement: 0, spanCountPointer: null, spanListPointer: null, algorithm: null, target: 0, count: 0 }; // ---------------------------------------------------------------------------- function extend(publicAPI, model) { let initialValues = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; Object.assign(model, DEFAULT_VALUES, initialValues); // Object methods macro.obj(publicAPI, model); macro.get(publicAPI, model, ['id', 'index']); // Object specific methods vtkImagePointDataIterator(publicAPI, model); } // ---------------------------------------------------------------------------- const newInstance = macro.newInstance(extend, 'vtkImagePointDataIterator'); // ---------------------------------------------------------------------------- var vtkImagePointDataIterator$1 = { newInstance, extend }; export { vtkImagePointDataIterator$1 as default, extend, newInstance };