UNPKG

@kitware/vtk.js

Version:

Visualization Toolkit for the Web

355 lines (283 loc) 12.8 kB
import _defineProperty from '@babel/runtime/helpers/defineProperty'; import _toConsumableArray from '@babel/runtime/helpers/toConsumableArray'; import { mat4, vec3, mat3 } from 'gl-matrix'; import Constants from './Glyph3DMapper/Constants.js'; import macro from '../../macros.js'; import vtkMapper from './Mapper.js'; import { N as createUninitializedBounds, n as norm } from '../../Common/Core/Math/index.js'; import vtkBoundingBox from '../../Common/DataModel/BoundingBox.js'; function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } var OrientationModes = Constants.OrientationModes, ScaleModes = Constants.ScaleModes; var vtkErrorMacro = macro.vtkErrorMacro; // ---------------------------------------------------------------------------- // class methods // ---------------------------------------------------------------------------- function vtkGlyph3DMapper(publicAPI, model) { // Set our className model.classHierarchy.push('vtkGlyph3DMapper'); /** * An orientation array is a vtkDataArray with 3 components. The first * component is the angle of rotation along the X axis. The second * component is the angle of rotation along the Y axis. The third * component is the angle of rotation along the Z axis. Orientation is * specified in X,Y,Z order but the rotations are performed in Z,X an Y. * This definition is compliant with SetOrientation method on vtkProp3D. * By using vector or normal there is a degree of freedom or rotation * left (underconstrained). With the orientation array, there is no degree of * freedom left. */ publicAPI.getOrientationModeAsString = function () { return macro.enumToString(OrientationModes, model.orientationMode); }; publicAPI.setOrientationModeToDirection = function () { return publicAPI.setOrientationMode(OrientationModes.DIRECTION); }; publicAPI.setOrientationModeToRotation = function () { return publicAPI.setOrientationMode(OrientationModes.ROTATION); }; publicAPI.setOrientationModeToMatrix = function () { return publicAPI.setOrientationMode(OrientationModes.MATRIX); }; publicAPI.getOrientationArrayData = function () { var idata = publicAPI.getInputData(0); if (!idata || !idata.getPointData()) { return null; } if (!model.orientationArray) { return idata.getPointData().getVectors(); } return idata.getPointData().getArray(model.orientationArray); }; publicAPI.getScaleModeAsString = function () { return macro.enumToString(ScaleModes, model.scaleMode); }; publicAPI.setScaleModeToScaleByMagnitude = function () { return publicAPI.setScaleMode(ScaleModes.SCALE_BY_MAGNITUDE); }; publicAPI.setScaleModeToScaleByComponents = function () { return publicAPI.setScaleMode(ScaleModes.SCALE_BY_COMPONENTS); }; publicAPI.setScaleModeToScaleByConstant = function () { return publicAPI.setScaleMode(ScaleModes.SCALE_BY_CONSTANT); }; publicAPI.getScaleArrayData = function () { var idata = publicAPI.getInputData(0); if (!idata || !idata.getPointData()) { return null; } if (!model.scaleArray) { return idata.getPointData().getScalars(); } return idata.getPointData().getArray(model.scaleArray); }; publicAPI.getBounds = function () { var idata = publicAPI.getInputData(0); var gdata = publicAPI.getInputData(1); if (!idata || !gdata) { return createUninitializedBounds(); } // first we build the arrays used for the glyphing publicAPI.buildArrays(); return model.bounds; }; publicAPI.buildArrays = function () { // if the mtgime requires it, rebuild var idata = publicAPI.getInputData(0); var gdata = publicAPI.getInputData(1); if (model.buildTime.getMTime() < gdata.getMTime() || model.buildTime.getMTime() < idata.getMTime() || model.buildTime.getMTime() < publicAPI.getMTime()) { var pts = idata.getPoints().getData(); var sArray = publicAPI.getScaleArrayData(); var sData = null; var numSComp = 0; if (sArray) { sData = sArray.getData(); numSComp = sArray.getNumberOfComponents(); } if (model.scaling && sArray && model.scaleMode === ScaleModes.SCALE_BY_COMPONENTS && sArray.getNumberOfComponents() !== 3) { vtkErrorMacro('Cannot scale by components since scale array does not have 3 components.'); sArray = null; } // get the glyph bounds var gbounds = gdata.getBounds(); // convert them to 8 points so we can compute the // overall bounds while building the arrays var corners = []; vtkBoundingBox.getCorners(gbounds, corners); model.bounds[0] = vtkBoundingBox.INIT_BOUNDS[0]; model.bounds[1] = vtkBoundingBox.INIT_BOUNDS[1]; model.bounds[2] = vtkBoundingBox.INIT_BOUNDS[2]; model.bounds[3] = vtkBoundingBox.INIT_BOUNDS[3]; model.bounds[4] = vtkBoundingBox.INIT_BOUNDS[4]; model.bounds[5] = vtkBoundingBox.INIT_BOUNDS[5]; var tcorner = new Float64Array(3); var oArray = publicAPI.getOrientationArrayData(); var identity = mat4.identity(new Float64Array(16)); var trans = []; var scale = []; var numPts = pts.length / 3; model.matrixArray = new Float32Array(16 * numPts); var mbuff = model.matrixArray.buffer; model.normalArray = new Float32Array(9 * numPts); var nbuff = model.normalArray.buffer; var tuple = []; for (var i = 0; i < numPts; ++i) { var z = new Float32Array(mbuff, i * 64, 16); trans[0] = pts[i * 3]; trans[1] = pts[i * 3 + 1]; trans[2] = pts[i * 3 + 2]; mat4.translate(z, identity, trans); if (oArray) { var orientation = []; oArray.getTuple(i, orientation); switch (model.orientationMode) { case OrientationModes.MATRIX: { // prettier-ignore var rotMat4 = [].concat(_toConsumableArray(orientation.slice(0, 3)), [0], _toConsumableArray(orientation.slice(3, 6)), [0], _toConsumableArray(orientation.slice(6, 9)), [0, 0, 0, 0, 1]); mat4.multiply(z, z, rotMat4); break; } case OrientationModes.ROTATION: mat4.rotateZ(z, z, orientation[2]); mat4.rotateX(z, z, orientation[0]); mat4.rotateY(z, z, orientation[1]); break; case OrientationModes.DIRECTION: if (orientation[1] === 0.0 && orientation[2] === 0.0) { if (orientation[0] < 0) { mat4.rotateY(z, z, 3.1415926); } } else { var vMag = norm(orientation); var vNew = []; vNew[0] = (orientation[0] + vMag) / 2.0; vNew[1] = orientation[1] / 2.0; vNew[2] = orientation[2] / 2.0; mat4.rotate(z, z, 3.1415926, vNew); } break; } } // scale data if appropriate if (model.scaling) { scale[0] = model.scaleFactor; scale[1] = model.scaleFactor; scale[2] = model.scaleFactor; // Get the scalar and vector data if (sArray) { switch (model.scaleMode) { case ScaleModes.SCALE_BY_MAGNITUDE: for (var t = 0; t < numSComp; ++t) { tuple[t] = sData[i * numSComp + t]; } scale[0] *= norm(tuple, numSComp); scale[1] = scale[0]; scale[2] = scale[0]; break; case ScaleModes.SCALE_BY_COMPONENTS: for (var _t = 0; _t < numSComp; ++_t) { tuple[_t] = sData[i * numSComp + _t]; } scale[0] *= tuple[0]; scale[1] *= tuple[1]; scale[2] *= tuple[2]; break; case ScaleModes.SCALE_BY_CONSTANT: } } if (scale[0] === 0.0) { scale[0] = 1.0e-10; } if (scale[1] === 0.0) { scale[1] = 1.0e-10; } if (scale[2] === 0.0) { scale[2] = 1.0e-10; } mat4.scale(z, z, scale); } // update bounds for (var p = 0; p < 8; ++p) { vec3.transformMat4(tcorner, corners[p], z); if (tcorner[0] < model.bounds[0]) { model.bounds[0] = tcorner[0]; } if (tcorner[1] < model.bounds[2]) { model.bounds[2] = tcorner[1]; } if (tcorner[2] < model.bounds[4]) { model.bounds[4] = tcorner[2]; } if (tcorner[0] > model.bounds[1]) { model.bounds[1] = tcorner[0]; } if (tcorner[1] > model.bounds[3]) { model.bounds[3] = tcorner[1]; } if (tcorner[2] > model.bounds[5]) { model.bounds[5] = tcorner[2]; } } var n = new Float32Array(nbuff, i * 36, 9); mat3.fromMat4(n, z); mat3.invert(n, n); mat3.transpose(n, n); } // map scalars as well var scalars = publicAPI.getAbstractScalars(idata, model.scalarMode, model.arrayAccessMode, model.arrayId, model.colorByArrayName).scalars; if (!model.useLookupTableScalarRange) { publicAPI.getLookupTable().setRange(model.scalarRange[0], model.scalarRange[1]); } model.colorArray = null; var lut = publicAPI.getLookupTable(); if (lut && scalars) { // Ensure that the lookup table is built lut.build(); model.colorArray = lut.mapScalars(scalars, model.colorMode, 0); } model.buildTime.modified(); } }; publicAPI.getPrimitiveCount = function () { var glyph = publicAPI.getInputData(1); var mult = publicAPI.getInputData().getPoints().getNumberOfValues() / 3; var pcount = { points: mult * glyph.getPoints().getNumberOfValues() / 3, verts: mult * (glyph.getVerts().getNumberOfValues() - glyph.getVerts().getNumberOfCells()), lines: mult * (glyph.getLines().getNumberOfValues() - 2 * glyph.getLines().getNumberOfCells()), triangles: mult * (glyph.getPolys().getNumberOfValues() - 3 * glyph.getLines().getNumberOfCells()) }; return pcount; }; } // ---------------------------------------------------------------------------- // Object factory // ---------------------------------------------------------------------------- var DEFAULT_VALUES = { orient: true, orientationMode: OrientationModes.DIRECTION, orientationArray: null, scaling: true, scaleFactor: 1.0, scaleMode: ScaleModes.SCALE_BY_MAGNITUDE, scaleArray: null, matrixArray: null, normalArray: null, colorArray: null }; // ---------------------------------------------------------------------------- function extend(publicAPI, model) { var initialValues = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; Object.assign(model, DEFAULT_VALUES, initialValues); // Inheritance vtkMapper.extend(publicAPI, model, initialValues); macro.algo(publicAPI, model, 2, 0); model.buildTime = {}; macro.obj(model.buildTime, { mtime: 0 }); model.boundsTime = {}; macro.obj(model.boundsTime, { mtime: 0 }); macro.setGet(publicAPI, model, ['orient', 'orientationMode', 'orientationArray', 'scaleArray', 'scaleFactor', 'scaleMode', 'scaling']); macro.get(publicAPI, model, ['colorArray', 'matrixArray', 'normalArray', 'buildTime']); // Object methods vtkGlyph3DMapper(publicAPI, model); } // ---------------------------------------------------------------------------- var newInstance = macro.newInstance(extend, 'vtkGlyph3DMapper'); // ---------------------------------------------------------------------------- var vtkGlyph3DMapper$1 = _objectSpread({ newInstance: newInstance, extend: extend }, Constants); export { vtkGlyph3DMapper$1 as default, extend, newInstance };