@kitware/vtk.js
Version:
Visualization Toolkit for the Web
205 lines (166 loc) • 7.58 kB
JavaScript
import macro from '../../macros.js';
import vtkPolyData from '../../Common/DataModel/PolyData.js';
import vtkDataArray from '../../Common/Core/DataArray.js';
// vtkSphereSource methods
// ----------------------------------------------------------------------------
function vtkSphereSource(publicAPI, model) {
// Set our className
model.classHierarchy.push('vtkSphereSource');
publicAPI.requestData = function (inData, outData) {
if (model.deleted) {
return;
}
var dataset = outData[0];
var pointDataType = dataset ? dataset.getPoints().getDataType() : model.pointType;
dataset = vtkPolyData.newInstance(); // ----------------------------------------------------------------------
var numPoles = 0; // Check data, determine increments, and convert to radians
var thetaResolution = model.thetaResolution;
var startTheta = model.startTheta < model.endTheta ? model.startTheta : model.endTheta;
startTheta *= Math.PI / 180.0;
var endTheta = model.endTheta > model.startTheta ? model.endTheta : model.startTheta;
endTheta *= Math.PI / 180.0;
var startPhi = model.startPhi < model.endPhi ? model.startPhi : model.endPhi;
startPhi *= Math.PI / 180.0;
var endPhi = model.endPhi > model.startPhi ? model.endPhi : model.startPhi;
endPhi *= Math.PI / 180.0;
if (Math.abs(startTheta - endTheta) < 2.0 * Math.PI) {
++thetaResolution;
}
var deltaTheta = (endTheta - startTheta) / model.thetaResolution;
var jStart = model.startPhi <= 0.0 ? 1 : 0;
var jEnd = model.phiResolution + (model.endPhi >= 180.0 ? -1 : 0);
var numPts = model.phiResolution * thetaResolution + 2;
var numPolys = model.phiResolution * 2 * model.thetaResolution; // Points
var pointIdx = 0;
var points = macro.newTypedArray(pointDataType, numPts * 3); // Normals
var normals = new Float32Array(numPts * 3); // Cells
var cellLocation = 0;
var polys = new Uint32Array(numPolys * 5); // Create north pole if needed
if (model.startPhi <= 0.0) {
points[pointIdx * 3 + 0] = model.center[0];
points[pointIdx * 3 + 1] = model.center[1];
points[pointIdx * 3 + 2] = model.center[2] + model.radius;
normals[pointIdx * 3 + 0] = 0;
normals[pointIdx * 3 + 1] = 0;
normals[pointIdx * 3 + 2] = 1;
pointIdx++;
numPoles++;
} // Create south pole if needed
if (model.endPhi >= 180.0) {
points[pointIdx * 3 + 0] = model.center[0];
points[pointIdx * 3 + 1] = model.center[1];
points[pointIdx * 3 + 2] = model.center[2] - model.radius;
normals[pointIdx * 3 + 0] = 0;
normals[pointIdx * 3 + 1] = 0;
normals[pointIdx * 3 + 2] = -1;
pointIdx++;
numPoles++;
}
var phiResolution = model.phiResolution - numPoles;
var deltaPhi = (endPhi - startPhi) / (model.phiResolution - 1); // Create intermediate points
for (var i = 0; i < thetaResolution; i++) {
var theta = startTheta + i * deltaTheta;
for (var j = jStart; j < jEnd; j++) {
var phi = startPhi + j * deltaPhi;
var radius = model.radius * Math.sin(phi);
normals[pointIdx * 3 + 0] = radius * Math.cos(theta);
normals[pointIdx * 3 + 1] = radius * Math.sin(theta);
normals[pointIdx * 3 + 2] = model.radius * Math.cos(phi);
points[pointIdx * 3 + 0] = normals[pointIdx * 3 + 0] + model.center[0];
points[pointIdx * 3 + 1] = normals[pointIdx * 3 + 1] + model.center[1];
points[pointIdx * 3 + 2] = normals[pointIdx * 3 + 2] + model.center[2];
var norm = Math.sqrt(normals[pointIdx * 3 + 0] * normals[pointIdx * 3 + 0] + normals[pointIdx * 3 + 1] * normals[pointIdx * 3 + 1] + normals[pointIdx * 3 + 2] * normals[pointIdx * 3 + 2]);
norm = norm === 0 ? 1 : norm;
normals[pointIdx * 3 + 0] /= norm;
normals[pointIdx * 3 + 1] /= norm;
normals[pointIdx * 3 + 2] /= norm;
pointIdx++;
}
} // Generate mesh connectivity
var base = phiResolution * thetaResolution;
if (Math.abs(startTheta - endTheta) < 2.0 * Math.PI) {
--thetaResolution;
} // around north pole
if (model.startPhi <= 0.0) {
for (var _i = 0; _i < thetaResolution; _i++) {
polys[cellLocation++] = 3;
polys[cellLocation++] = phiResolution * _i + numPoles;
polys[cellLocation++] = phiResolution * (_i + 1) % base + numPoles;
polys[cellLocation++] = 0;
}
} // around south pole
if (model.endPhi >= 180.0) {
var numOffset = phiResolution - 1 + numPoles;
for (var _i2 = 0; _i2 < thetaResolution; _i2++) {
polys[cellLocation++] = 3;
polys[cellLocation++] = phiResolution * _i2 + numOffset;
polys[cellLocation++] = numPoles - 1;
polys[cellLocation++] = phiResolution * (_i2 + 1) % base + numOffset;
}
} // bands in-between poles
for (var _i3 = 0; _i3 < thetaResolution; _i3++) {
for (var _j = 0; _j < phiResolution - 1; _j++) {
var a = phiResolution * _i3 + _j + numPoles;
var b = a + 1;
var c = (phiResolution * (_i3 + 1) + _j) % base + numPoles + 1;
if (!model.latLongTessellation) {
polys[cellLocation++] = 3;
polys[cellLocation++] = a;
polys[cellLocation++] = b;
polys[cellLocation++] = c;
polys[cellLocation++] = 3;
polys[cellLocation++] = a;
polys[cellLocation++] = c;
polys[cellLocation++] = c - 1;
} else {
polys[cellLocation++] = 4;
polys[cellLocation++] = a;
polys[cellLocation++] = b;
polys[cellLocation++] = c;
polys[cellLocation++] = c - 1;
}
}
} // Squeeze
points = points.subarray(0, pointIdx * 3);
dataset.getPoints().setData(points, 3);
normals = normals.subarray(0, pointIdx * 3);
var normalArray = vtkDataArray.newInstance({
name: 'Normals',
values: normals,
numberOfComponents: 3
});
dataset.getPointData().setNormals(normalArray);
polys = polys.subarray(0, cellLocation);
dataset.getPolys().setData(polys, 1); // Update output
outData[0] = dataset;
};
} // ----------------------------------------------------------------------------
// Object factory
// ----------------------------------------------------------------------------
var DEFAULT_VALUES = {
radius: 0.5,
latLongTessellation: false,
thetaResolution: 8,
startTheta: 0.0,
endTheta: 360.0,
phiResolution: 8,
startPhi: 0.0,
endPhi: 180.0,
center: [0, 0, 0],
pointType: 'Float64Array'
}; // ----------------------------------------------------------------------------
function extend(publicAPI, model) {
var initialValues = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
Object.assign(model, DEFAULT_VALUES, initialValues); // Build VTK API
macro.obj(publicAPI, model);
macro.setGet(publicAPI, model, ['radius', 'latLongTessellation', 'thetaResolution', 'startTheta', 'endTheta', 'phiResolution', 'startPhi', 'endPhi']);
macro.setGetArray(publicAPI, model, ['center'], 3);
macro.algo(publicAPI, model, 0, 1);
vtkSphereSource(publicAPI, model);
} // ----------------------------------------------------------------------------
var newInstance = macro.newInstance(extend, 'vtkSphereSource'); // ----------------------------------------------------------------------------
var vtkSphereSource$1 = {
newInstance: newInstance,
extend: extend
};
export { vtkSphereSource$1 as default, extend, newInstance };