@kitware/vtk.js
Version:
Visualization Toolkit for the Web
280 lines (254 loc) • 7.79 kB
JavaScript
import { m as macro, T as TYPED_ARRAYS } from '../../macros2.js';
import vtkDataArray from '../Core/DataArray.js';
import vtkImplicitFunction from './ImplicitFunction.js';
import { b as vtkMath } from '../Core/Math/index.js';
import vtkPlane from './Plane.js';
import vtkPoints from '../Core/Points.js';
import { VtkDataTypes } from '../Core/DataArray/Constants.js';
const {
vtkErrorMacro,
vtkWarningMacro
} = macro;
// ----------------------------------------------------------------------------
// vtkPlanes methods
// ----------------------------------------------------------------------------
function vtkPlanes(publicAPI, model) {
// Set our className
model.classHierarchy.push('vtkPlanes');
// Initialize internal variables
model.planes = model.planes || macro.newTypedArray(TYPED_ARRAYS.Float64Array, 24);
model.bounds = model.bounds || macro.newTypedArray(TYPED_ARRAYS.Float64Array, 6);
model.plane = vtkPlane.newInstance();
// Public API methods
publicAPI.setNormals = normals => {
if (normals && normals.getNumberOfComponents() !== 3) {
vtkWarningMacro('This array does not have 3 components. Ignoring normals.');
}
model.normals = normals;
publicAPI.modified();
return true;
};
/**
* Evaluate the function at a point x
* @param {*} x The point at which to evaluate the function
* @returns The function value at the point x
*/
publicAPI.evaluateFunction = x => {
if (!model.points || !model.normals) {
vtkErrorMacro('Please define points and/or normals!');
return Number.MAX_VALUE;
}
const numPlanes = model.points.getNumberOfPoints();
if (numPlanes !== model.normals.getNumberOfTuples()) {
vtkErrorMacro('Number of normals/points inconsistent!');
return Number.MAX_VALUE;
}
let maxVal = -Number.MAX_VALUE;
const normal = [];
const point = [];
for (let i = 0; i < numPlanes; i++) {
model.normals.getTuple(i, normal);
model.points.getPoint(i, point);
const val = vtkPlane.evaluate(normal, point, x);
if (val > maxVal) {
maxVal = val;
}
}
return maxVal;
};
/**
* Evaluate the gradient at a point x
* @param {*} x The point at which to evaluate the gradient
* @returns The gradient at the point x
*/
publicAPI.evaluateGradient = x => {
const retVal = [0, 0, 0];
if (!model.points || !model.normals) {
vtkErrorMacro('Define points and/or normals first!');
return retVal;
}
const numPlanes = model.points.getNumberOfPoints();
if (numPlanes !== model.normals.getNumberOfTuples()) {
vtkErrorMacro('The number of normals/points is inconsistent!');
return retVal;
}
let maxVal = -Number.MAX_VALUE;
const nTemp = [];
const pTemp = [];
for (let i = 0; i < numPlanes; i++) {
model.normals.getTuple(i, nTemp);
model.points.getPoint(i, pTemp);
const val = vtkPlane.evaluate(nTemp, pTemp, x);
if (val > maxVal) {
maxVal = val;
retVal[0] = nTemp[0];
retVal[1] = nTemp[1];
retVal[2] = nTemp[2];
}
}
return retVal;
};
/**
* Set the frustum planes
* @param {Number[]} planes The planes to set
* @returns {Boolean} true if planes were set, false if they were already set
*/
publicAPI.setFrustumPlanes = planes => {
if (vtkMath.areEquals(model.planes, planes)) {
return false;
}
model.planes = [...planes];
const pts = vtkPoints.newInstance({
dataType: VtkDataTypes.DOUBLE
});
const normals = vtkDataArray.newInstance({
numberOfComponents: 3,
size: 6 * 3,
// 6 planes, each with a normal
dataType: VtkDataTypes.DOUBLE
});
pts.setNumberOfPoints(6);
publicAPI.setPoints(pts);
publicAPI.setNormals(normals);
const n = [];
const x = [];
for (let i = 0; i < 6; i++) {
const planeOffset = 4 * i;
n[0] = -planes[planeOffset];
n[1] = -planes[planeOffset + 1];
n[2] = -planes[planeOffset + 2];
x[0] = 0.0;
x[1] = 0.0;
x[2] = 0.0;
if (n[0] !== 0.0) {
x[0] = planes[planeOffset + 3] / n[0];
} else if (n[1] !== 0.0) {
x[1] = planes[planeOffset + 3] / n[1];
} else {
x[2] = planes[planeOffset + 3] / n[2];
}
pts.setPoint(i, ...x);
normals.setTuple(i, n);
}
publicAPI.modified();
return true;
};
/**
* Set the bounds of the planes
* @param {*} bounds The bounds to set
* @returns {Boolean} true if bounds were set, false if they were already set
*/
publicAPI.setBounds = bounds => {
if (vtkMath.areEquals(model.bounds, bounds)) {
return false;
}
model.bounds = [...bounds];
const pts = vtkPoints.newInstance();
const normals = vtkDataArray.newInstance({
numberOfComponents: 3,
size: 6 * 3,
// 6 planes, each with a normal
dataType: VtkDataTypes.DOUBLE
});
pts.setNumberOfPoints(6);
publicAPI.setPoints(pts);
publicAPI.setNormals(normals);
const n = [];
const x = [];
// The x planes
n[0] = -1.0;
n[1] = 0.0;
n[2] = 0.0;
x[0] = bounds[0];
x[1] = 0.0;
x[2] = 0.0;
pts.setPoint(0, ...x);
normals.setTuple(0, n);
n[0] = 1.0;
x[0] = bounds[1];
pts.setPoint(1, ...x);
normals.setTuple(1, n);
// The y planes
n[0] = 0.0;
n[1] = -1.0;
n[2] = 0.0;
x[0] = 0.0;
x[1] = bounds[2];
x[2] = 0.0;
pts.setPoint(2, ...x);
normals.setTuple(2, n);
n[1] = 1.0;
x[1] = bounds[3];
pts.setPoint(3, ...x);
normals.setTuple(3, n);
// The z planes
n[0] = 0.0;
n[1] = 0.0;
n[2] = -1.0;
x[0] = 0.0;
x[1] = 0.0;
x[2] = bounds[4];
pts.setPoint(4, ...x);
normals.setTuple(4, n);
n[2] = 1.0;
x[2] = bounds[5];
pts.setPoint(5, ...x);
normals.setTuple(5, n);
publicAPI.modified();
return true;
};
/**
* Get the number of planes
* @returns {Number} the number of planes
*/
publicAPI.getNumberOfPlanes = () => {
if (model.points && model.normals) {
const npts = model.points.getNumberOfPoints();
const nnormals = model.normals.getNumberOfTuples();
return Math.min(npts, nnormals);
}
return 0;
};
/**
* Get the i-th plane
* @param {*} i
* @param {vtkPlane} plane the vtkPlane instance to fill
* @returns {vtkPlane} the plane instance
*/
publicAPI.getPlane = (i, plane = model.plane) => {
if (i >= 0 && i < publicAPI.getNumberOfPlanes()) {
const normal = model.normals.getTuple(i);
const point = model.points.getPoint(i);
plane.setNormal(normal);
plane.setOrigin(point);
}
return plane;
};
}
// ----------------------------------------------------------------------------
// Object factory
// ----------------------------------------------------------------------------
const DEFAULT_VALUES = {
points: null,
normals: null,
planes: null,
bounds: null
};
// ----------------------------------------------------------------------------
function extend(publicAPI, model, initialValues = {}) {
Object.assign(model, DEFAULT_VALUES, initialValues);
// Build VTK API
vtkImplicitFunction.extend(publicAPI, model, initialValues);
macro.setGet(publicAPI, model, ['points', 'normals']);
macro.get(publicAPI, model, ['bounds', 'planes']);
// Object methods
vtkPlanes(publicAPI, model);
}
// ----------------------------------------------------------------------------
const newInstance = macro.newInstance(extend, 'vtkPlanes');
// ----------------------------------------------------------------------------
var vtkPlanes$1 = {
newInstance,
extend
};
export { vtkPlanes$1 as default, extend, newInstance };