UNPKG

@kitware/vtk.js

Version:

Visualization Toolkit for the Web

973 lines (771 loc) 32.7 kB
import _defineProperty from '@babel/runtime/helpers/defineProperty'; import _toConsumableArray from '@babel/runtime/helpers/toConsumableArray'; import macro from '../../macros.js'; import { d as dot, e as distance2BetweenPoints } from '../../Common/Core/Math/index.js'; import vtkCellArray from '../../Common/Core/CellArray.js'; import vtkDataArray from '../../Common/Core/DataArray.js'; import { VtkDataTypes } from '../../Common/Core/DataArray/Constants.js'; import vtkPoints from '../../Common/Core/Points.js'; import vtkDataSetAttributes from '../../Common/DataModel/DataSetAttributes.js'; import vtkPolyData from '../../Common/DataModel/PolyData.js'; import vtkContourTriangulator from './ContourTriangulator.js'; import vtkEdgeLocator from '../../Common/DataModel/EdgeLocator.js'; import Constants from './ClipClosedSurface/Constants.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; } var vtkErrorMacro = macro.vtkErrorMacro, capitalize = macro.capitalize; var ScalarMode = Constants.ScalarMode; function vtkClipClosedSurface(publicAPI, model) { // Set our className model.classHierarchy.push('vtkClipClosedSurface'); publicAPI.getMTime = function () { return model.clippingPlanes.reduce(function (a, b) { return b.getMTime() > a ? b.getMTime() : a; }, model.mtime); }; /** * Take three colors as doubles, and convert to unsigned char. * * @param {Number} color1 * @param {Number} color2 * @param {Number} color3 * @param {Number[3][3]} colors */ function createColorValues(color1, color2, color3, colors) { var dcolors = [color1, color2, color3]; var clamp = function clamp(n, min, max) { return Math.min(Math.max(n, min), max); }; for (var i = 0; i < 3; i++) { for (var j = 0; j < 3; j++) { colors[i][j] = Math.round(clamp(dcolors[i][j], 0, 1) * 255); } } } /** * Point interpolation for clipping and contouring, given the scalar * values (v0, v1) for the two endpoints (p0, p1). The use of this * function guarantees perfect consistency in the results. * * @param {vtkPoints} points * @param {vtkDataArray} pointData * @param {CCSEdgeLocator} locator * @param {Number} tol * @param {Number} i0 * @param {Number} i1 * @param {Number} v0 * @param {Number} v1 * @param {Number} i * @returns {Number} */ function interpolateEdge(points, pointData, locator, tol, i0, i1, v0, v1) { // This swap guarantees that exactly the same point is computed // for both line directions, as long as the endpoints are the same. if (v1 > 0) { // eslint-disable-next-line no-param-reassign var _ref = [i1, i0]; i0 = _ref[0]; i1 = _ref[1]; var _ref2 = [v1, v0]; v0 = _ref2[0]; v1 = _ref2[1]; } // After the above swap, i0 will be kept, and i1 will be clipped // Check to see if this point has already been computed var edge = locator.insertUniqueEdge(i0, i1); if (edge.value != null) { return edge.value; } // Get the edge and interpolate the new point var p0 = points.getPoint(i0); var p1 = points.getPoint(i1); var f = v0 / (v0 - v1); var s = 1.0 - f; var t = 1.0 - s; var p = [s * p0[0] + t * p1[0], s * p0[1] + t * p1[1], s * p0[2] + t * p1[2]]; var tol2 = tol * tol; // Make sure that new point is far enough from kept point if (distance2BetweenPoints(p, p0) < tol2) { edge.value = i0; return i0; } if (distance2BetweenPoints(p, p1) < tol2) { edge.value = i1; return i1; } edge.value = points.insertNextTuple(p); pointData.interpolateData(pointData, i0, i1, edge.value, t); return edge.value; } /** * Method for clipping lines and copying the scalar data. * * @param {vtkPoints} points * @param {vtkDataArray} pointScalars * @param {vtkDataSetAttributesk} pointData * @param {vtkEdgeLocator} edgeLocator * @param {vtkCellArray} inputLines * @param {vtkCellArray} outputLines * @param {vtkDataSetAttributes} inLineData * @param {vtkDataSetAttributes} outLineData */ function clipLines(points, pointScalars, pointData, edgeLocator, inputLines, outputLines, inLineData, outLineData) { var numPts; var i0; var i1; var v0; var v1; var c0; var c1; var linePts = []; var values = inputLines.getData(); var cellId = 0; for (var i = 0; i < values.length; i += numPts + 1, cellId++) { numPts = values[i]; i1 = values[i + 1]; v1 = pointScalars.getData()[i1]; c1 = v1 > 0; for (var j = 2; j <= numPts; j++) { i0 = i1; v0 = v1; c0 = c1; i1 = values[i + j]; v1 = pointScalars.getData()[i1]; c1 = v1 > 0; // If at least one point wasn't clipped if (c0 || c1) { // If only one end was clipped, interpolate new point if (c0 ? !c1 : c1) { linePts[c0 ? 1 : 0] = interpolateEdge(points, pointData, edgeLocator, model.tolerance, i0, i1, v0, v1); } // If endpoints are different, insert the line segment if (i0 !== i1) { linePts[0] = i0; linePts[1] = i1; var newCellId = outputLines.insertNextCell(linePts); // outLineData.copyData(inLineData, cellId, newCellId); outLineData.passData(inLineData, cellId, newCellId); } } } } } /** * Break polylines into individual lines, copying scalar values from * inputScalars starting at firstLineScalar. If inputScalars is zero, * then scalars will be set to color. If scalars is zero, then no * scalars will be generated. * * @param {vtkCellArray} inputLines * @param {vtkCellArray} outputLines * @param {vtkDataArray} inputScalars * @param {Number} firstLineScalar * @param {vtkDataArray} scalars * @param {Vector3} color */ function breakPolylines(inputLines, outputLines, inputScalars, firstLineScalar, scalars, color) { var cellColor = _toConsumableArray(color); var cellId = 0; var values = inputLines.getData(); var numPts; for (var i = 0; i < values.length; i += numPts + 1) { numPts = values[i]; if (inputScalars) { inputScalars.getTuple(firstLineScalar + cellId++, cellColor); } for (var j = 1; j < numPts; j++) { outputLines.insertNextCell([values[i + j], values[i + j + 1]]); if (scalars) { scalars.insertNextTuple(cellColor); } } } } /** * Copy polygons and their associated scalars to a new array. * If inputScalars is set to zero, set polyScalars to color instead. * If polyScalars is set to zero, don't generate scalars. * * @param {vtkCellArray} inputPolys * @param {vtkCellArray} outputPolys * @param {vtkDataArray} inputScalars * @param {Number} firstPolyScalar * @param {vtkDataArray} polyScalars * @param {Vector3} color */ function copyPolygons(inputPolys, outputPolys, inputScalars, firstPolyScalar, polyScalars, color) { if (!inputPolys) { return; } outputPolys.deepCopy(inputPolys); if (polyScalars) { var scalarValue = _toConsumableArray(color); var n = outputPolys.getNumberOfCells(); polyScalars.insertTuple(n - 1, scalarValue); if (inputScalars) { for (var i = 0; i < n; i++) { inputScalars.getTuple(i + firstPolyScalar, scalarValue); polyScalars.setTuple(i, scalarValue); } } else { for (var _i = 0; _i < n; _i++) { polyScalars.setTuple(_i, scalarValue); } } } } function breakTriangleStrips(inputStrips, polys, inputScalars, firstStripScalar, polyScalars, color) { if (inputStrips.getNumberOfCells() === 0) { return; } var values = inputStrips.getData(); var cellId = firstStripScalar; var numPts; for (var i = 0; i < values.length; i += numPts + 1, cellId++) { numPts = values[i]; // vtkTriangleStrip.decomposeStrip(numPts, values, polys); var p1 = values[i + 1]; var p2 = values[i + 2]; for (var j = 0; j < numPts - 2; j++) { var p3 = values[i + j + 3]; if (j % 2) { polys.insertNextCell([p2, p1, p3]); } else { polys.insertNextCell([p1, p2, p3]); } p1 = p2; p2 = p3; } if (polyScalars) { var scalarValue = _toConsumableArray(color); if (inputScalars) { // If there are input scalars, use them instead of "color" inputScalars.getTuple(cellId, scalarValue); } var n = numPts - 3; var m = polyScalars.getNumberOfTuples(); if (n >= 0) { // First insert is just to allocate space polyScalars.insertTuple(m + n, scalarValue); for (var k = 0; k < n; k++) { polyScalars.setTuple(m + k, scalarValue); } } } } } /** * Given some closed contour lines, create a triangle mesh that * fills those lines. The input lines must be single-segment lines, * not polylines. The input lines do not have to be in order. * Only lines from firstLine to will be used. Specify the normal * of the clip plane, which will be opposite the normals * of the polys that will be produced. If outCD has scalars, then color * scalars will be added for each poly that is created. * * @param {vtkPolyData} polyData * @param {Number} firstLine * @param {Number} numLines * @param {vtkCellArray} outputPolys * @param {Vector3} normal */ function triangulateContours(polyData, firstLine, numLines, outputPolys, normal) { // If no cut lines were generated, there's nothing to do if (numLines <= 0) { return; } var triangulationError = !vtkContourTriangulator.triangulateContours(polyData, firstLine, numLines, outputPolys, [-normal[0], -normal[1], -normal[2]]); if (triangulationError && model.triangulationErrorDisplay) { vtkErrorMacro('Triangulation failed, polyData may not be watertight.'); } } /** * Break polylines into individual lines, copying scalar values from * inputScalars starting at firstLineScalar. If inputScalars is zero, * then scalars will be set to color. If scalars is zero, then no * scalars will be generated. * * @param {Number[]} polygon * @param {vtkPoints} points * @param {vtkCellArray} triangles * @returns {Boolean} */ function triangulatePolygon(polygon, points, triangles) { return vtkContourTriangulator.triangulatePolygon(polygon, points, triangles); } /** * Clip and contour polys in one step, in order to guarantee * that the contour lines exactly match the new free edges of * the clipped polygons. This exact correspondence is necessary * in order to guarantee that the surface remains closed. * * @param {vtkPoints} points * @param {vtkDataArray} pointScalars * @param {vtkDataSetAttributes} pointData * @param {vtkEdgeLocator} edgeLocator * @param {Number} triangulate * @param {vtkCellArray} inputPolys * @param {vtkCellArray} outputPolys * @param {vtkCellArray} outputLines * @param {vtkDataSetAttributes} inCellData * @param {vtkDataSetAttributes} outPolyData * @param {vtkDataSetAttributes} outLineData */ function clipAndContourPolys(points, pointScalars, pointData, edgeLocator, triangulate, inputPolys, outputPolys, outputLines, inCellData, outPolyData, outLineData) { var idList = model._idList; // How many sides for output polygons? var polyMax = Number.MAX_VALUE; if (triangulate) { if (triangulate < 4) { // triangles only polyMax = 3; } else if (triangulate === 4) { // allow triangles and quads polyMax = 4; } } // eslint-disable-next-line prefer-const var triangulationFailure = false; // Go through all cells and clip them var values = inputPolys.getData(); var linePts = []; var cellId = 0; var numPts; for (var i = 0; i < values.length; i += numPts + 1, cellId++) { numPts = values[i]; var i1 = values[i + numPts]; var v1 = pointScalars.getData()[i1]; var c1 = v1 > 0; // The ids for the current edge: init j0 to -1 if i1 will be clipped var j0 = c1 ? i1 : -1; var j1 = 0; // To store the ids of the contour line linePts[0] = 0; linePts[1] = 0; var idListIdx = 0; for (var j = 1; j <= numPts; j++) { // Save previous point info var i0 = i1; var v0 = v1; var c0 = c1; // Generate new point info i1 = values[i + j]; v1 = pointScalars.getData()[i1]; c1 = v1 > 0; // If at least one edge end point wasn't clipped if (c0 || c1) { // If only one end was clipped, interpolate new point if (c0 ? !c1 : c1) { j1 = interpolateEdge(points, pointData, edgeLocator, model.tolerance, i0, i1, v0, v1); if (j1 !== j0) { idList[idListIdx++] = j1; j0 = j1; } // Save as one end of the contour line linePts[c0 ? 1 : 0] = j1; } if (c1) { j1 = i1; if (j1 !== j0) { idList[idListIdx++] = j1; j0 = j1; } } } } // Insert the clipped poly var numPoints = idListIdx; idList.length = numPoints; if (model.triangulatePolys && numPoints > polyMax) { // TODO: Support triangulatePolygon var newCellId = outputPolys.getNumberOfCells(); // Triangulate the poly and insert triangles into output. var success = triangulatePolygon(idList, points, outputPolys); if (!success) { triangulationFailure = true; } // Copy the attribute data to the triangle cells var ncells = outputPolys.getNumberOfCells(); for (; newCellId < ncells; newCellId++) { outPolyData.passData(inCellData, cellId, newCellId); } } else if (numPoints > 2) { // Insert the polygon without triangulating it var _newCellId = outputPolys.insertNextCell(idList); outPolyData.passData(inCellData, cellId, _newCellId); } // Insert the contour line if one was created if (linePts[0] !== linePts[1]) { var _newCellId2 = outputLines.insertNextCell(linePts); outLineData.passData(inCellData, cellId, _newCellId2); } } if (triangulationFailure && model.triangulationErrorDisplay) { vtkErrorMacro('Triangulation failed, output may not be watertight'); } } /** * Squeeze the points and store them in the output. Only the points that * are used by the cells will be saved, and the pointIds of the cells will * be modified. * * @param {vtkPolyData} output * @param {vtkPoints} points * @param {vtkDataSetAttributes} pointData * @param {String} outputPointDataType */ function squeezeOutputPoints(output, points, pointData, outputPointDataType) { // Create a list of points used by cells var n = points.getNumberOfPoints(); var numNewPoints = 0; var outPointData = output.getPointData(); var pointMap = []; pointMap.length = n; var cellArrays = [output.getVerts(), output.getLines(), output.getPolys(), output.getStrips()]; // Find all the newPoints that are used by cells cellArrays.forEach(function (cellArray) { if (!cellArray) { return; } var values = cellArray.getData(); var numPts; var pointId; for (var i = 0; i < values.length; i += numPts + 1) { numPts = values[i]; for (var j = 1; j <= numPts; j++) { pointId = values[i + j]; if (pointMap[pointId] === undefined) { pointMap[pointId] = numNewPoints++; } } } }); // Create exactly the number of points that are required var newPoints = vtkPoints.newInstance({ size: numNewPoints * 3, dataType: outputPointDataType }); // outPointData.copyAllocate(pointData, numNewPoints, 0); var p = []; var newPointId; for (var pointId = 0; pointId < n; pointId++) { newPointId = pointMap[pointId]; if (newPointId !== undefined) { points.getPoint(pointId, p); newPoints.setTuple(newPointId, p); outPointData.passData(pointData, pointId, newPointId); // outPointData.copyData(pointData, pointId, newPointId); } } // Change the cell pointIds to reflect the new point array cellArrays.forEach(function (cellArray) { if (!cellArray) { return; } var values = cellArray.getData(); var numPts; var pointId; for (var i = 0; i < values.length; i += numPts + 1) { numPts = values[i]; for (var j = 1; j <= numPts; j++) { pointId = values[i + j]; values[i + j] = pointMap[pointId]; } } }); output.setPoints(newPoints); } publicAPI.requestData = function (inData, outData) { var _input$getVerts, _input$getStrips; // implement requestData var input = inData[0]; var output = vtkPolyData.newInstance(); outData[0] = output; if (!input) { vtkErrorMacro('Invalid or missing input'); return; } if (model._idList == null) { model._idList = []; } else { model._idList.length = 0; } // Get the input points var inputPoints = input.getPoints(); var numPts = 0; var inputPointsType = VtkDataTypes.FLOAT; if (inputPoints) { numPts = inputPoints.getNumberOfPoints(); inputPointsType = inputPoints.getDataType(); } // Force points to double precision, copy the point attributes var points = vtkPoints.newInstance({ size: numPts * 3, dataType: VtkDataTypes.DOUBLE }); var pointData = vtkDataSetAttributes.newInstance(); var inPointData = null; if (model.passPointData) { inPointData = input.getPointData(); // pointData.interpolateAllocate(inPointData, numPts, 0); } var point = []; for (var ptId = 0; ptId < numPts; ptId++) { inputPoints.getPoint(ptId, point); points.setTuple(ptId, point); if (inPointData) { // pointData.copyData(inPointData, ptId, ptId); pointData.passData(inPointData, ptId, ptId); } } // An edge locator to avoid point duplication while clipping var edgeLocator = vtkEdgeLocator.newInstance(); // A temporary polydata for the contour lines that are triangulated var tmpContourData = vtkPolyData.newInstance(); // The cell scalars var lineScalars; var polyScalars; var inputScalars; // For input scalars: the offsets to the various cell types var firstLineScalar = 0; var firstPolyScalar = 0; var firstStripScalar = 0; // Make the colors to be used on the data var numberOfScalarComponents = 1; var colors = [[0, 0, 0], [0, 0, 0], [0, 0, 0]]; if (model.scalarMode === ScalarMode.COLORS) { numberOfScalarComponents = 3; createColorValues(model.baseColor, model.clipColor, model.activePlaneColor, colors); } else if (model.scalarMode === ScalarMode.LABELS) { colors[0][0] = 0; colors[1][0] = 1; colors[2][0] = 2; } // This is set if we have to work with scalars. The input scalars // will be copied if they are unsigned char with 3 components, otherwise // new scalars will be generated. var numVerts = ((_input$getVerts = input.getVerts()) === null || _input$getVerts === void 0 ? void 0 : _input$getVerts.getNumberOfCells()) || 0; var inputLines = input.getLines(); var numLines = (inputLines === null || inputLines === void 0 ? void 0 : inputLines.getNumberOfCells()) || 0; var inputPolys = input.getPolys(); var numPolys = (inputPolys === null || inputPolys === void 0 ? void 0 : inputPolys.getNumberOfCells()) || 0; var numStrips = ((_input$getStrips = input.getStrips()) === null || _input$getStrips === void 0 ? void 0 : _input$getStrips.getNumberOfCells()) || 0; if (model.scalarMode !== ScalarMode.NONE) { lineScalars = vtkDataArray.newInstance({ dataType: VtkDataTypes.UNSIGNED_CHAR, empty: true, // size: 0, // values: new Uint8Array(numLines * 3), numberOfComponents: numberOfScalarComponents }); var tryInputScalars = input.getCellData().getScalars(); // Get input scalars if they are RGB color scalars if (tryInputScalars && tryInputScalars.getDataType() === VtkDataTypes.UNSIGNED_CHAR && numberOfScalarComponents === 3 && tryInputScalars.getNumberOfComponents() === 3) { inputScalars = input.getCellData().getScalars(); firstLineScalar = numVerts; firstPolyScalar = numVerts + numLines; firstStripScalar = numVerts + numLines + numPolys; } } // Break the input lines into segments, generate scalars for lines var lines; if (numLines > 0) { lines = vtkCellArray.newInstance({ dataType: inputLines.getDataType(), values: new Uint8Array(numLines * 3), // we will have at least that amount of lines size: 0 }); breakPolylines(inputLines, lines, inputScalars, firstLineScalar, lineScalars, colors[0]); } else { lines = vtkCellArray.newInstance({ empty: true }); } var polys = null; var polyMax = 3; if (numPolys > 0 || numStrips > 0) { // If there are line scalars, then poly scalars are needed too if (lineScalars) { polyScalars = vtkDataArray.newInstance({ dataType: VtkDataTypes.UNSIGNED_CHAR, empty: true, // size: 0, // values: new Uint8Array(inputPolys.getNumberOfCells(false) * 3), numberOfComponents: numberOfScalarComponents }); } polys = vtkCellArray.newInstance(); copyPolygons(inputPolys, polys, inputScalars, firstPolyScalar, polyScalars, colors[0]); // TODO: Support triangle strips breakTriangleStrips(input.getStrips(), polys, inputScalars, firstStripScalar, polyScalars, colors[0]); // Check if the input has polys and quads or just triangles polyMax = inputPolys.getCellSizes().reduce(function (a, b) { return a > b ? a : b; }, 0); } // Arrays for storing the clipped lines and polys var newLines = vtkCellArray.newInstance({ dataType: lines.getDataType(), empty: true }); var newPolys = null; if (polys) { newPolys = vtkCellArray.newInstance({ dataType: polys.getDataType(), empty: true }); } // The line scalars, for coloring the outline var inLineData = vtkDataSetAttributes.newInstance(); inLineData.copyScalarsOn(); inLineData.setScalars(lineScalars); // The poly scalars, for coloring the faces var inPolyData = vtkDataSetAttributes.newInstance(); inPolyData.copyScalarsOn(); inPolyData.setScalars(polyScalars); // Also create output attribute data var outLineData = vtkDataSetAttributes.newInstance(); outLineData.copyScalarsOn(); var outPolyData = vtkDataSetAttributes.newInstance(); outPolyData.copyScalarsOn(); var planes = model.clippingPlanes; // Go through the clipping planes and clip the input with each plane for (var planeId = 0; planeId < planes.length; planeId++) { var plane = planes[planeId]; var triangulate = 5; if (planeId === planes.length - 1) { triangulate = polyMax; } var active = planeId === model.activePlaneId; // Convert the plane into an easy-to-evaluate function var pc = plane.getNormal(); // OK to modify pc because vtkPlane.getNormal() returns a copy pc[3] = -dot(pc, plane.getOrigin()); // Create the clip scalars by evaluating the plane at each point var numPoints = points.getNumberOfPoints(); // The point scalars, needed for clipping (not for the output!) var pointScalars = vtkDataArray.newInstance({ dataType: VtkDataTypes.DOUBLE, size: numPoints }); var pointScalarsData = pointScalars.getData(); var pointsData = points.getData(); var i = 0; for (var pointId = 0; pointId < numPoints; pointId) { pointScalarsData[pointId++] = pointsData[i++] * pc[0] + pointsData[i++] * pc[1] + pointsData[i++] * pc[2] + pc[3]; } // Prepare the output scalars // outLineData.copyAllocate(inLineData, 0, 0); // outPolyData.copyAllocate(inPolyData, 0, 0); // Reset the locator edgeLocator.initialize(); // Clip the lines clipLines(points, pointScalars, pointData, edgeLocator, lines, newLines, inLineData, outLineData); // Clip the polys if (polys) { // Get the number of lines remaining after the clipping var numClipLines = newLines.getNumberOfCells(); // Cut the polys to generate more lines clipAndContourPolys(points, pointScalars, pointData, edgeLocator, triangulate, polys, newPolys, newLines, inPolyData, outPolyData, outLineData); // Add scalars for the newly-created contour lines var _scalars = outLineData.getScalars(); if (_scalars) { // Set the color to the active color if plane is active var color = colors[1 + (active ? 1 : 0)]; var activeColor = colors[2]; var numNewLines = newLines.getNumberOfCells(); var oldColor = []; for (var lineId = numClipLines; lineId < numNewLines; lineId++) { _scalars.getTuple(lineId, oldColor); if (numberOfScalarComponents !== 3 || oldColor[0] !== activeColor[0] || oldColor[1] !== activeColor[1] || oldColor[2] !== activeColor[2]) { _scalars.setTuple(lineId, color); } } } // Generate new polys from the cut lines var cellId = newPolys.getNumberOfCells(); var numClipAndContourLines = newLines.getNumberOfCells(); // Create a polydata for the lines tmpContourData.setPoints(points); tmpContourData.setLines(newLines); tmpContourData.buildCells(); triangulateContours(tmpContourData, numClipLines, numClipAndContourLines - numClipLines, newPolys, pc); // Add scalars for the newly-created polys _scalars = outPolyData.getScalars(); if (_scalars) { var _color = colors[1 + (active ? 1 : 0)]; var numCells = newPolys.getNumberOfCells(); if (numCells > cellId) { // The insert allocates space up to numCells - 1 _scalars.insertTuple(numCells - 1, _color); for (; cellId < numCells; cellId++) { _scalars.setTuple(cellId, _color); } } } // Add scalars to any diagnostic lines that added by // triangulateContours(). In usual operation, no lines are added. _scalars = outLineData.getScalars(); if (_scalars) { var _color2 = [0, 255, 255]; var _numCells = newLines.getNumberOfCells(); if (_numCells > numClipAndContourLines) { // The insert allocates space up to numCells - 1 _scalars.insertTuple(_numCells - 1, _color2); for (var lineCellId = numClipAndContourLines; lineCellId < _numCells; lineCellId++) { _scalars.setTuple(lineCellId, _color2); } } } } // Swap the lines, points, etcetera: old output becomes new input var _ref3 = [newLines, lines]; lines = _ref3[0]; newLines = _ref3[1]; newLines.initialize(); if (polys) { var _ref4 = [newPolys, polys]; polys = _ref4[0]; newPolys = _ref4[1]; newPolys.initialize(); } var _ref5 = [outLineData, inLineData]; inLineData = _ref5[0]; outLineData = _ref5[1]; outLineData.initialize(); var _ref6 = [outPolyData, inPolyData]; inPolyData = _ref6[0]; outPolyData = _ref6[1]; outPolyData.initialize(); } // Get the line scalars var scalars = inLineData.getScalars(); if (model.generateOutline) { output.setLines(lines); } else if (scalars) { scalars.initialize(); } if (model.generateFaces) { output.setPolys(polys); if (polys && scalars) { var pScalars = inPolyData.getScalars(); var m = scalars.getNumberOfTuples(); var n = pScalars.getNumberOfTuples(); if (n > 0) { var _color3 = [0, 0, 0]; // This is just to expand the array scalars.insertTuple(n + m - 1, _color3); // Fill in the poly scalars for (var _i2 = 0; _i2 < n; _i2++) { pScalars.getTuple(_i2, _color3); scalars.setTuple(_i2 + m, _color3); } } } } if (scalars && model.scalarMode === ScalarMode.COLORS) { scalars.setName('Colors'); output.getCellData().setScalars(scalars); } else if (model.scalarMode === ScalarMode.LABELS) { // Don't use VTK_UNSIGNED_CHAR or they will look like color scalars // const categories = vtkSignedCharArray.newInstance(); // categories.deepCopy(scalars); // categories.setName("Labels"); // output.getCellData().setScalars(categories); // categories.delete(); // TODO: Check var categories = scalars.newClone(); categories.setData(scalars.getData().slice()); categories.setName('Labels'); output.getCellData().setScalars(categories); } else { output.getCellData().setScalars(null); } // Finally, store the points in the output squeezeOutputPoints(output, points, pointData, inputPointsType); // TODO: Check // output.squeeze(); outData[0] = output; }; Object.keys(ScalarMode).forEach(function (key) { var name = capitalize(key.toLowerCase()); publicAPI["setScalarModeTo".concat(name)] = function () { model.scalarMode = ScalarMode[key]; }; }); } // ---------------------------------------------------------------------------- // Object factory // ---------------------------------------------------------------------------- var DEFAULT_VALUES = { clippingPlanes: null, tolerance: 1e-6, passPointData: false, triangulatePolys: false, scalarMode: ScalarMode.NONE, generateOutline: false, generateFaces: true, activePlaneId: -1, baseColor: [255 / 255, 99 / 255, 71 / 255], // Tomato clipColor: [244 / 255, 164 / 255, 96 / 255], // Sandy brown activePlaneColor: [227 / 255, 207 / 255, 87 / 255], // Banana triangulationErrorDisplay: false // _idList: null, }; // ---------------------------------------------------------------------------- function extend(publicAPI, model) { var initialValues = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; 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); macro.setGet(publicAPI, model, ['clippingPlanes', 'tolerance', 'passPointData', 'triangulatePolys', 'scalarMode', 'generateOutline', 'generateFaces', 'activePlaneId', 'triangulationErrorDisplay']); macro.setGetArray(publicAPI, model, ['baseColor', 'clipColor', 'activePlaneColor'], 3); // Object specific methods vtkClipClosedSurface(publicAPI, model); } // ---------------------------------------------------------------------------- var newInstance = macro.newInstance(extend, 'vtkClipClosedSurface'); // ---------------------------------------------------------------------------- var vtkClipClosedSurface$1 = _objectSpread({ newInstance: newInstance, extend: extend }, Constants); export { vtkClipClosedSurface$1 as default, extend, newInstance };