@kitware/vtk.js
Version:
Visualization Toolkit for the Web
197 lines (171 loc) • 6.65 kB
JavaScript
import { m as macro } from '../../macros2.js';
import vtkDataArray from '../../Common/Core/DataArray.js';
import vtkPolyData from '../../Common/DataModel/PolyData.js';
import vtkMatrixBuilder from '../../Common/Core/MatrixBuilder.js';
// ----------------------------------------------------------------------------
// vtkCylinderSource methods
// ----------------------------------------------------------------------------
function vtkCylinderSource(publicAPI, model) {
// Set our classname
model.classHierarchy.push('vtkCylinderSource');
publicAPI.requestData = (inData, outData) => {
const angle = 2.0 * Math.PI / model.resolution;
let numberOfPoints = 2 * model.resolution;
let numberOfPolys = 5 * model.resolution;
if (model.capping) {
numberOfPoints = 4 * model.resolution;
numberOfPolys = 7 * model.resolution + 2;
}
// Points
const points = macro.newTypedArray(model.pointType, numberOfPoints * 3);
// Cells
let cellLocation = 0;
const polys = new Uint32Array(numberOfPolys);
// Normals
const normalsData = new Float32Array(numberOfPoints * 3);
const normals = vtkDataArray.newInstance({
numberOfComponents: 3,
values: normalsData,
name: 'Normals'
});
// Texture coords
const tcData = new Float32Array(numberOfPoints * 2);
const tcoords = vtkDataArray.newInstance({
numberOfComponents: 2,
values: tcData,
name: 'TCoords'
});
// Generate points for all sides
const nbot = [0.0, 0.0, 0.0];
const ntop = [0.0, 0.0, 0.0];
const xbot = [0.0, 0.0, 0.0];
const xtop = [0.0, 0.0, 0.0];
const tcbot = [0.0, 0.0];
const tctop = [0.0, 0.0];
const otherRadius = model.otherRadius == null ? model.radius : model.otherRadius;
for (let i = 0; i < model.resolution; i++) {
// x coordinate
nbot[0] = Math.cos(i * angle + model.initAngle);
ntop[0] = nbot[0];
xbot[0] = model.radius * nbot[0] + model.center[0];
xtop[0] = xbot[0];
tcbot[0] = Math.abs(2.0 * i / model.resolution - 1.0);
tctop[0] = tcbot[0];
// y coordinate
xbot[1] = 0.5 * model.height + model.center[1];
xtop[1] = -0.5 * model.height + model.center[1];
tcbot[1] = 0.0;
tctop[1] = 1.0;
// z coordinate
nbot[2] = -Math.sin(i * angle + model.initAngle);
ntop[2] = nbot[2];
xbot[2] = otherRadius * nbot[2] + model.center[2];
xtop[2] = xbot[2];
const pointIdx = 2 * i;
for (let j = 0; j < 3; j++) {
normalsData[pointIdx * 3 + j] = nbot[j];
normalsData[(pointIdx + 1) * 3 + j] = ntop[j];
points[pointIdx * 3 + j] = xbot[j];
points[(pointIdx + 1) * 3 + j] = xtop[j];
if (j < 2) {
tcData[pointIdx * 2 + j] = tcbot[j];
tcData[(pointIdx + 1) * 2 + j] = tctop[j];
}
}
}
// Generate polygons for sides
for (let i = 0; i < model.resolution; i++) {
polys[cellLocation++] = 4;
polys[cellLocation++] = 2 * i;
polys[cellLocation++] = 2 * i + 1;
const pt = (2 * i + 3) % (2 * model.resolution);
polys[cellLocation++] = pt;
polys[cellLocation++] = pt - 1;
}
if (model.capping) {
// Generate points for top/bottom polygons
for (let i = 0; i < model.resolution; i++) {
// x coordinate
xbot[0] = model.radius * Math.cos(i * angle + model.initAngle);
xtop[0] = xbot[0];
tcbot[0] = xbot[0];
tctop[0] = xbot[0];
xbot[0] += model.center[0];
xtop[0] += model.center[0];
// y coordinate
nbot[1] = 1.0;
ntop[1] = -1.0;
xbot[1] = 0.5 * model.height + model.center[1];
xtop[1] = -0.5 * model.height + model.center[1];
// z coordinate
xbot[2] = -otherRadius * Math.sin(i * angle + model.initAngle);
xtop[2] = xbot[2];
tcbot[1] = xbot[2];
tctop[1] = xbot[2];
xbot[2] += model.center[2];
xtop[2] += model.center[2];
const botIdx = 2 * model.resolution + i;
const topIdx = 3 * model.resolution + model.resolution - i - 1;
for (let j = 0; j < 3; j++) {
normalsData[3 * botIdx + j] = nbot[j];
normalsData[3 * topIdx + j] = ntop[j];
points[3 * botIdx + j] = xbot[j];
points[3 * topIdx + j] = xtop[j];
if (j < 2) {
tcData[2 * botIdx + j] = tcbot[j];
tcData[2 * topIdx + j] = tctop[j];
}
}
}
// Generate polygons for top/bottom
polys[cellLocation++] = model.resolution;
for (let i = 0; i < model.resolution; i++) {
polys[cellLocation++] = 2 * model.resolution + i;
}
polys[cellLocation++] = model.resolution;
for (let i = 0; i < model.resolution; i++) {
polys[cellLocation++] = 3 * model.resolution + i;
}
}
// Apply transformation to the points coordinates
vtkMatrixBuilder.buildFromRadian().translate(...model.center).rotateFromDirections([0, 1, 0], model.direction).translate(...model.center.map(c => c * -1)).apply(points);
const dataset = outData[0]?.initialize() || vtkPolyData.newInstance();
dataset.getPoints().setData(points, 3);
dataset.getPolys().setData(polys, 1);
dataset.getPointData().setNormals(normals);
dataset.getPointData().setTCoords(tcoords);
// Update output
outData[0] = dataset;
};
}
// ----------------------------------------------------------------------------
// Object factory
// ----------------------------------------------------------------------------
const DEFAULT_VALUES = {
height: 1.0,
initAngle: 0,
radius: 1.0,
resolution: 6,
center: [0, 0, 0],
direction: [0.0, 1.0, 0.0],
capping: true,
pointType: 'Float64Array'
};
// ----------------------------------------------------------------------------
function extend(publicAPI, model, initialValues = {}) {
Object.assign(model, DEFAULT_VALUES, initialValues);
// Build VTK API
macro.obj(publicAPI, model);
macro.setGet(publicAPI, model, ['height', 'initAngle', 'otherRadius', 'radius', 'resolution', 'capping']);
macro.setGetArray(publicAPI, model, ['center', 'direction'], 3);
macro.algo(publicAPI, model, 0, 1);
vtkCylinderSource(publicAPI, model);
}
// ----------------------------------------------------------------------------
const newInstance = macro.newInstance(extend, 'vtkCylinderSource');
// ----------------------------------------------------------------------------
var vtkCylinderSource$1 = {
newInstance,
extend
};
export { vtkCylinderSource$1 as default, extend, newInstance };