import macro from 'vtk.js/Sources/macros'; import vtkPolyData from 'vtk.js/Sources/Common/DataModel/PolyData'; import vtkMatrixBuilder from 'vtk.js/Sources/Common/Core/MatrixBuilder'; import vtkDataArray from 'vtk.js/Sources/Common/Core/DataArray';
function vtkConcentricCylinderSource(publicAPI, model) { model.classHierarchy.push('vtkConcentricCylinderSource');
function validateCellFields() { while (model.cellFields.length < model.radius.length) { model.cellFields.push(model.cellFields.length); } }
publicAPI.clearRadius = () => { model.radius = []; model.cellFields = []; publicAPI.modified(); };
publicAPI.addRadius = (radius, cellField) => { model.radius.push(radius); if (cellField !== undefined) { model.cellFields.push(cellField); } validateCellFields(); publicAPI.modified(); };
publicAPI.getNumberOfRadius = () => model.radius.length; publicAPI.getRadius = (index = 0) => model.radius[index]; publicAPI.setRadius = (index, radius) => { model.radius[index] = radius; publicAPI.modified(); }; publicAPI.setCellField = (index, field) => { model.cellFields[index] = field; publicAPI.modified(); };
publicAPI.removeMask = () => { model.mask = null; publicAPI.modified(); };
publicAPI.setMaskLayer = (index, hidden) => { let changeDetected = false;
if (!model.mask && hidden) { changeDetected = true; model.mask = []; }
if (model.mask) { if (!model.mask[index] !== !hidden) { changeDetected = true; } model.mask[index] = hidden; }
if (changeDetected) { publicAPI.modified(); } };
publicAPI.getMaskLayer = (index) => index === undefined ? model.mask : model.mask[index];
function requestData(inData, outData) { if (model.deleted || !model.radius.length) { return; }
validateCellFields();
let dataset = outData[0];
const numLayers = model.radius.length; const zRef = model.height / 2.0;
let cellArraySize = 0; let numCells = 0;
let startTheta = model.startTheta < model.endTheta ? model.startTheta : model.endTheta; startTheta *= Math.PI / 180.0; let endTheta = model.endTheta > model.startTheta ? model.endTheta : model.startTheta; endTheta *= Math.PI / 180.0; let thetaResolution = model.resolution; let partialDisk = false; if (endTheta >= startTheta + 2 * Math.PI) { endTheta = startTheta + 2 * Math.PI; } else { ++thetaResolution; partialDisk = true; } const deltaTheta = (endTheta - startTheta) / model.resolution;
const numberOfPoints = thetaResolution * numLayers * 2 + 2;
if (!model.skipInnerFaces && !model.mask) { cellArraySize = 2 * (thetaResolution + 1) + 5 * thetaResolution + (numLayers - 1) * thetaResolution * 20 + (partialDisk ? 10 * numLayers : 0); numCells = 2 + thetaResolution + (numLayers - 1) * 4 * thetaResolution + (partialDisk ? 2 * numLayers : 0); } else if (!model.skipInnerFaces && model.mask) { if (!model.mask[0]) { cellArraySize += 2 * (thetaResolution + 1) + 5 * thetaResolution + (partialDisk ? 10 : 0); numCells += 2 + thetaResolution + (partialDisk ? 2 : 0); } for (let layer = 1; layer < numLayers; layer++) { if (!model.mask[layer]) { cellArraySize += thetaResolution * 20 + (partialDisk ? 10 : 0); numCells += 4 * thetaResolution + (partialDisk ? 2 : 0); } } } else { if (!model.skipInnerFaces || !model.mask || !model.mask[0]) { cellArraySize += 2 * (thetaResolution + 1) + (partialDisk ? 10 : 0); numCells += 2 + (partialDisk ? 2 : 0); if ( model.radius.length === 1 || !model.skipInnerFaces || (model.mask && model.mask[1]) ) { cellArraySize += 5 * thetaResolution; numCells += thetaResolution; } }
for (let layer = 1; layer < numLayers; layer++) { if (!model.skipInnerFaces || !model.mask || !model.mask[layer]) { const lastLayer = numLayers - 1 === layer;
cellArraySize += thetaResolution * 10 + (partialDisk ? 10 : 0); numCells += thetaResolution * 2 + (partialDisk ? 2 : 0);
if (!model.skipInnerFaces || (model.mask && model.mask[layer - 1])) { cellArraySize += thetaResolution * 5; numCells += thetaResolution; }
if ( lastLayer || !model.skipInnerFaces || (model.mask && model.mask[layer + 1]) ) { cellArraySize += thetaResolution * 5; numCells += thetaResolution; } } } }
let pointIdx = 0; const points = macro.newTypedArray(model.pointType, numberOfPoints * 3);
let cellLocation = 0; const polys = new Uint32Array(cellArraySize);
let fieldLocation = 0; const field = new Float32Array(numCells);
points[pointIdx * 3 + 0] = 0; points[pointIdx * 3 + 1] = 0; points[pointIdx * 3 + 2] = zRef; pointIdx++; points[pointIdx * 3 + 0] = 0; points[pointIdx * 3 + 1] = 0; points[pointIdx * 3 + 2] = -zRef; pointIdx++; for (let layer = 0; layer < numLayers; layer++) { const radius = model.radius[layer]; for (let i = 0; i < thetaResolution; i++) { const theta = startTheta + i * deltaTheta; points[pointIdx * 3 + 0] = radius * Math.cos(theta); points[pointIdx * 3 + 1] = radius * Math.sin(theta); points[pointIdx * 3 + 2] = zRef; pointIdx++; }
for (let i = 0; i < thetaResolution; i++) { const theta = startTheta + i * deltaTheta; points[pointIdx * 3 + 0] = radius * Math.cos(theta); points[pointIdx * 3 + 1] = radius * Math.sin(theta); points[pointIdx * 3 + 2] = -zRef; pointIdx++; } }
let currentField = model.cellFields[0];
if (!model.mask || !model.mask[0]) { field[fieldLocation++] = currentField; polys[cellLocation++] = thetaResolution + (partialDisk ? 1 : 0); if (partialDisk) polys[cellLocation++] = 0; for (let i = 0; i < thetaResolution; i++) { polys[cellLocation++] = i + 2; }
field[fieldLocation++] = currentField; polys[cellLocation++] = thetaResolution + (partialDisk ? 1 : 0); if (partialDisk) polys[cellLocation++] = 1; for (let i = 0; i < thetaResolution; i++) { polys[cellLocation++] = 2 * thetaResolution - i - 1 + 2; }
if ( !model.skipInnerFaces || (model.mask && model.mask[1]) || numLayers === 1 ) { for (let i = 0; i < model.resolution; i++) { polys[cellLocation++] = 4; polys[cellLocation++] = ((i + 1) % thetaResolution) + 2; polys[cellLocation++] = i + 2; polys[cellLocation++] = i + thetaResolution + 2; polys[cellLocation++] = ((i + 1) % thetaResolution) + thetaResolution + 2;
field[fieldLocation++] = currentField; } } if (partialDisk) { polys[cellLocation++] = 4; polys[cellLocation++] = 2; polys[cellLocation++] = 0; polys[cellLocation++] = 1; polys[cellLocation++] = thetaResolution + 2;
field[fieldLocation++] = currentField;
polys[cellLocation++] = 4; polys[cellLocation++] = 0; polys[cellLocation++] = thetaResolution + 1; polys[cellLocation++] = 2 * thetaResolution + 1; polys[cellLocation++] = 1;
field[fieldLocation++] = currentField; } }
for (let layer = 1; layer < numLayers; layer++) { if (model.mask && model.mask[layer]) { continue; }
const offset = thetaResolution * 2 * (layer - 1) + 2; const a = offset + 2 * thetaResolution; const lastLayer = numLayers - 1 === layer; currentField = model.cellFields[layer];
for (let i = 0; i < model.resolution; i++) { polys[cellLocation++] = 4; polys[cellLocation++] = i + offset; polys[cellLocation++] = ((i + 1) % thetaResolution) + offset; polys[cellLocation++] = ((i + 1) % thetaResolution) + a; polys[cellLocation++] = i + a;
field[fieldLocation++] = currentField; }
for (let i = 0; i < model.resolution; i++) { polys[cellLocation++] = 4; polys[cellLocation++] = ((i + 1) % thetaResolution) + offset + thetaResolution; polys[cellLocation++] = i + offset + thetaResolution; polys[cellLocation++] = i + a + thetaResolution; polys[cellLocation++] = ((i + 1) % thetaResolution) + a + thetaResolution;
field[fieldLocation++] = currentField; }
if (!model.skipInnerFaces || (model.mask && model.mask[layer - 1])) { for (let i = 0; i < model.resolution; i++) { polys[cellLocation++] = 4; polys[cellLocation++] = i + offset; polys[cellLocation++] = ((i + 1) % thetaResolution) + offset; polys[cellLocation++] = ((i + 1) % thetaResolution) + thetaResolution + offset; polys[cellLocation++] = i + thetaResolution + offset;
field[fieldLocation++] = currentField; } }
if ( !model.skipInnerFaces || lastLayer || (model.mask && (model.mask[layer + 1] || lastLayer)) ) { for (let i = 0; i < model.resolution; i++) { polys[cellLocation++] = 4; polys[cellLocation++] = ((i + 1) % thetaResolution) + a; polys[cellLocation++] = i + a; polys[cellLocation++] = i + thetaResolution + a; polys[cellLocation++] = ((i + 1) % thetaResolution) + thetaResolution + a;
field[fieldLocation++] = currentField; } } if (partialDisk) { polys[cellLocation++] = 4; polys[cellLocation++] = a; polys[cellLocation++] = offset; polys[cellLocation++] = thetaResolution + offset; polys[cellLocation++] = thetaResolution + a;
field[fieldLocation++] = currentField;
polys[cellLocation++] = 4; polys[cellLocation++] = model.resolution + a; polys[cellLocation++] = model.resolution + offset; polys[cellLocation++] = model.resolution + thetaResolution + offset; polys[cellLocation++] = model.resolution + thetaResolution + a;
field[fieldLocation++] = currentField; } }
vtkMatrixBuilder .buildFromRadian() .translate(...model.center) .rotateFromDirections([0, 0, 1], model.direction) .apply(points);
dataset = vtkPolyData.newInstance(); dataset.getPoints().setData(points, 3); dataset.getPolys().setData(polys, 1); dataset .getCellData() .setScalars(vtkDataArray.newInstance({ name: 'layer', values: field }));
outData[0] = dataset; }
publicAPI.requestData = requestData; }
const DEFAULT_VALUES = { height: 1.0, radius: [0.5], cellFields: [1], resolution: 6, startTheta: 0.0, endTheta: 360.0, center: [0, 0, 0], direction: [0.0, 0.0, 1.0], skipInnerFaces: true, mask: null, pointType: 'Float64Array', };
export function extend(publicAPI, model, initialValues = {}) { Object.assign(model, DEFAULT_VALUES, initialValues);
macro.obj(publicAPI, model); macro.setGet(publicAPI, model, [ 'height', 'resolution', 'startTheta', 'endTheta', 'skipInnerFaces', ]); macro.setGetArray(publicAPI, model, ['center', 'direction'], 3); macro.getArray(publicAPI, model, ['cellFields']); macro.algo(publicAPI, model, 0, 1); vtkConcentricCylinderSource(publicAPI, model); }
export const newInstance = macro.newInstance( extend, 'vtkConcentricCylinderSource' );
export default { newInstance, extend };
|