import macro from 'vtk.js/Sources/macros';
import vtkDataArray from 'vtk.js/Sources/Common/Core/DataArray'; import vtkMath from 'vtk.js/Sources/Common/Core/Math/index'; import vtkPolyData from 'vtk.js/Sources/Common/DataModel/PolyData'; import vtkTriangle from 'vtk.js/Sources/Common/DataModel/Triangle';
function vtkPolyDataNormals(publicAPI, model) { model.classHierarchy.push('vtkPolyDataNormals');
publicAPI.vtkPolyDataNormalsExecute = ( numberOfPolys, polysData, pointsData ) => { if (!pointsData) { return null; }
const pointNormals = new Float32Array(pointsData.length); const cellNormals = new Float32Array(3 * numberOfPolys); let cellNormalComponent = 0;
let numberOfPoints = 0; const polysDataLength = polysData.length;
const cellPointIds = [0, 0, 0]; const cellNormal = [0, 0, 0];
for (let c = 0; c < polysDataLength; c += numberOfPoints + 1) { numberOfPoints = polysData[c];
if (numberOfPoints < 3) { continue; }
for (let i = 1; i <= 3; ++i) { cellPointIds[i - 1] = 3 * polysData[c + i]; }
vtkTriangle.computeNormal( pointsData.slice(cellPointIds[0], cellPointIds[0] + 3), pointsData.slice(cellPointIds[1], cellPointIds[1] + 3), pointsData.slice(cellPointIds[2], cellPointIds[2] + 3), cellNormal );
cellNormals[cellNormalComponent++] = cellNormal[0]; cellNormals[cellNormalComponent++] = cellNormal[1]; cellNormals[cellNormalComponent++] = cellNormal[2];
if (model.computePointNormals) { for (let i = 1; i <= numberOfPoints; ++i) { let pointId = 3 * polysData[c + i];
pointNormals[pointId] += cellNormal[0]; pointNormals[++pointId] += cellNormal[1]; pointNormals[++pointId] += cellNormal[2]; } } }
if (model.computePointNormals) { const pointNormal = [0, 0, 0]; for (let i = 0; i < pointsData.length; ) { pointNormal[0] = pointNormals[i]; pointNormal[1] = pointNormals[i + 1]; pointNormal[2] = pointNormals[i + 2];
vtkMath.normalize(pointNormal);
pointNormals[i++] = pointNormal[0]; pointNormals[i++] = pointNormal[1]; pointNormals[i++] = pointNormal[2]; } }
return [cellNormals, pointNormals]; };
publicAPI.requestData = (inData, outData) => { const numberOfInputs = publicAPI.getNumberOfInputPorts();
if (!numberOfInputs) { return; }
const input = inData[0];
if (!input) { return; }
const output = vtkPolyData.newInstance();
output.setPoints(input.getPoints()); output.setVerts(input.getVerts()); output.setLines(input.getLines()); output.setPolys(input.getPolys()); output.setStrips(input.getStrips());
output.getPointData().passData(input.getPointData()); output.getCellData().passData(input.getCellData()); output.getFieldData().passData(input.getFieldData());
const [cellNormals, pointNormals] = publicAPI.vtkPolyDataNormalsExecute( input.getNumberOfPolys(), input.getPolys().getData(), input.getPoints().getData() );
if (model.computePointNormals) { const outputPointNormals = vtkDataArray.newInstance({ numberOfComponents: 3, name: 'Normals', values: pointNormals, }); output.getPointData().setNormals(outputPointNormals); }
if (model.computeCellNormals) { const outputCellNormals = vtkDataArray.newInstance({ numberOfComponents: 3, name: 'Normals', values: cellNormals, }); output.getCellData().setNormals(outputCellNormals); }
outData[0] = output; }; }
function defaultValues(initialValues) { return { computeCellNormals: false, computePointNormals: true, ...initialValues, }; }
export function extend(publicAPI, model, initialValues = {}) { Object.assign(model, defaultValues(initialValues));
macro.obj(publicAPI, model);
macro.algo(publicAPI, model, 1, 1);
macro.setGet(publicAPI, model, ['computeCellNormals', 'computePointNormals']);
vtkPolyDataNormals(publicAPI, model); }
export const newInstance = macro.newInstance(extend, 'vtkPolyDataNormals');
export default { newInstance, extend };
|