@kitware/vtk.js
Version:
Visualization Toolkit for the Web
973 lines (771 loc) • 32.7 kB
JavaScript
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 };