@kitware/vtk.js
Version:
Visualization Toolkit for the Web
408 lines (393 loc) • 15.7 kB
JavaScript
import { m as macro } from '../../macros2.js';
import vtkPolyData from '../../Common/DataModel/PolyData.js';
import vtkCellArray from '../../Common/Core/CellArray.js';
import vtkPoints from '../../Common/Core/Points.js';
// ----------------------------------------------------------------------------
// vtkCursor3D methods
// ----------------------------------------------------------------------------
function vtkCursor3D(publicAPI, model) {
// Set our className
model.classHierarchy.push('vtkCursor3D');
// Public API methods
publicAPI.setModelBounds = bounds => {
if (!Array.isArray(bounds) || bounds.length < 6) {
return;
}
if (model.modelBounds[0] === bounds[0] && model.modelBounds[1] === bounds[1] && model.modelBounds[2] === bounds[2] && model.modelBounds[3] === bounds[3] && model.modelBounds[4] === bounds[4] && model.modelBounds[5] === bounds[5]) {
return;
}
publicAPI.modified();
// Doing type convert, make sure it is a number array.
// Without correct coversion, the array may contains string which cause
// the wrapping and clampping works incorrectly.
model.modelBounds = bounds.map(v => Number(v));
for (let i = 0; i < 3; ++i) {
model.modelBounds[2 * i] = Math.min(model.modelBounds[2 * i], model.modelBounds[2 * i + 1]);
}
};
publicAPI.setFocalPoint = points => {
if (!Array.isArray(points) || points.length < 3) {
return;
}
if (points[0] === model.focalPoint[0] && points[1] === model.focalPoint[1] && points[2] === model.focalPoint[2]) {
return;
}
publicAPI.modified();
const v = [];
for (let i = 0; i < 3; i++) {
v[i] = points[i] - model.focalPoint[i];
model.focalPoint[i] = Number(points[i]);
if (model.translationMode) {
model.modelBounds[2 * i] += v[i];
model.modelBounds[2 * i + 1] += v[i];
}
// wrap
else if (model.wrap) {
model.focalPoint[i] = model.modelBounds[2 * i] + (model.focalPoint[i] - model.modelBounds[2 * i]) * 1.0 % ((model.modelBounds[2 * i + 1] - model.modelBounds[2 * i]) * 1.0);
}
// clamp
else {
if (points[i] < model.modelBounds[2 * i]) {
model.focalPoint[i] = model.modelBounds[2 * i];
}
if (points[i] > model.modelBounds[2 * i + 1]) {
model.focalPoint[i] = model.modelBounds[2 * i + 1];
}
}
}
};
publicAPI.setAll = flag => {
publicAPI.setOutline(flag);
publicAPI.setAxes(flag);
publicAPI.setXShadows(flag);
publicAPI.setYShadows(flag);
publicAPI.setZShadows(flag);
};
publicAPI.allOn = () => {
publicAPI.setAll(true);
};
publicAPI.allOff = () => {
publicAPI.setAll(false);
};
publicAPI.requestData = (inData, outData) => {
let numPts = 0;
let numLines = 0;
// Check bounding box and origin
if (model.wrap) {
for (let i = 0; i < model.focalPoint.length; ++i) {
model.focalPoint[i] = model.modelBounds[2 * i] + (model.focalPoint[i] - model.modelBounds[2 * i]) * 1.0 % (model.modelBounds[2 * i + 1] - model.modelBounds[2 * i]);
}
} else {
for (let i = 0; i < model.focalPoint.length; ++i) {
model.focalPoint[i] = Math.max(model.focalPoint[i], model.modelBounds[2 * i]);
model.focalPoint[i] = Math.min(model.focalPoint[i], model.modelBounds[2 * i + 1]);
}
}
// allocate storage
if (model.axes) {
numPts += 6;
numLines += 3;
}
if (model.outline) {
numPts += 8;
numLines += 12;
}
if (model.xShadows) {
numPts += 8;
numLines += 4;
}
if (model.yShadows) {
numPts += 8;
numLines += 4;
}
if (model.zShadows) {
numPts += 8;
numLines += 4;
}
if (numPts === 0) {
return;
}
const polyData = outData[0]?.initialize() || vtkPolyData.newInstance();
const newPts = vtkPoints.newInstance({
size: numPts * 3
});
// vtkCellArray is a supporting object that explicitly represents cell
// connectivity. The cell array structure is a raw integer list
// of the form: (n,id1,id2,...,idn, n,id1,id2,...,idn, ...)
// where n is the number of points in the cell, and id is a zero-offset index
// into an associated point list.
const newLines = vtkCellArray.newInstance({
size: numLines * (2 + 1)
});
let pid = 0;
let cid = 0;
// Create axes
if (model.axes) {
newPts.getData()[pid * 3 + 0] = model.modelBounds[0];
newPts.getData()[pid * 3 + 1] = model.focalPoint[1];
newPts.getData()[pid * 3 + 2] = model.focalPoint[2];
++pid;
newPts.getData()[pid * 3 + 0] = model.modelBounds[1];
newPts.getData()[pid * 3 + 1] = model.focalPoint[1];
newPts.getData()[pid * 3 + 2] = model.focalPoint[2];
++pid;
newLines.getData()[cid * 3 + 0] = 2;
newLines.getData()[cid * 3 + 1] = pid - 2;
newLines.getData()[cid * 3 + 2] = pid - 1;
++cid;
newPts.getData()[pid * 3 + 0] = model.focalPoint[0];
newPts.getData()[pid * 3 + 1] = model.modelBounds[2];
newPts.getData()[pid * 3 + 2] = model.focalPoint[2];
++pid;
newPts.getData()[pid * 3 + 0] = model.focalPoint[0];
newPts.getData()[pid * 3 + 1] = model.modelBounds[3];
newPts.getData()[pid * 3 + 2] = model.focalPoint[2];
++pid;
newLines.getData()[cid * 3 + 0] = 2;
newLines.getData()[cid * 3 + 1] = pid - 2;
newLines.getData()[cid * 3 + 2] = pid - 1;
++cid;
newPts.getData()[pid * 3 + 0] = model.focalPoint[0];
newPts.getData()[pid * 3 + 1] = model.focalPoint[1];
newPts.getData()[pid * 3 + 2] = model.modelBounds[4];
++pid;
newPts.getData()[pid * 3 + 0] = model.focalPoint[0];
newPts.getData()[pid * 3 + 1] = model.focalPoint[1];
newPts.getData()[pid * 3 + 2] = model.modelBounds[5];
++pid;
newLines.getData()[cid * 3 + 0] = 2;
newLines.getData()[cid * 3 + 1] = pid - 2;
newLines.getData()[cid * 3 + 2] = pid - 1;
++cid;
}
// create outline
if (model.outline) {
// first traid
newPts.getData()[pid * 3 + 0] = model.modelBounds[0];
newPts.getData()[pid * 3 + 1] = model.modelBounds[2];
newPts.getData()[pid * 3 + 2] = model.modelBounds[4];
const corner024 = pid;
++pid;
newPts.getData()[pid * 3 + 0] = model.modelBounds[1];
newPts.getData()[pid * 3 + 1] = model.modelBounds[2];
newPts.getData()[pid * 3 + 2] = model.modelBounds[4];
const corner124 = pid;
++pid;
newPts.getData()[pid * 3 + 0] = model.modelBounds[0];
newPts.getData()[pid * 3 + 1] = model.modelBounds[3];
newPts.getData()[pid * 3 + 2] = model.modelBounds[4];
const corner034 = pid;
++pid;
newPts.getData()[pid * 3 + 0] = model.modelBounds[0];
newPts.getData()[pid * 3 + 1] = model.modelBounds[2];
newPts.getData()[pid * 3 + 2] = model.modelBounds[5];
const corner025 = pid;
++pid;
newLines.getData()[(cid + 0) * 3 + 0] = 2;
newLines.getData()[(cid + 0) * 3 + 1] = corner024;
newLines.getData()[(cid + 0) * 3 + 2] = corner124;
newLines.getData()[(cid + 1) * 3 + 0] = 2;
newLines.getData()[(cid + 1) * 3 + 1] = corner024;
newLines.getData()[(cid + 1) * 3 + 2] = corner034;
newLines.getData()[(cid + 2) * 3 + 0] = 2;
newLines.getData()[(cid + 2) * 3 + 1] = corner024;
newLines.getData()[(cid + 2) * 3 + 2] = corner025;
cid += 3;
// second triad
newPts.getData()[pid * 3 + 0] = model.modelBounds[1];
newPts.getData()[pid * 3 + 1] = model.modelBounds[3];
newPts.getData()[pid * 3 + 2] = model.modelBounds[5];
const corner135 = pid;
++pid;
newPts.getData()[pid * 3 + 0] = model.modelBounds[0];
newPts.getData()[pid * 3 + 1] = model.modelBounds[3];
newPts.getData()[pid * 3 + 2] = model.modelBounds[5];
const corner035 = pid;
++pid;
newPts.getData()[pid * 3 + 0] = model.modelBounds[1];
newPts.getData()[pid * 3 + 1] = model.modelBounds[2];
newPts.getData()[pid * 3 + 2] = model.modelBounds[5];
const corner125 = pid;
++pid;
newPts.getData()[pid * 3 + 0] = model.modelBounds[1];
newPts.getData()[pid * 3 + 1] = model.modelBounds[3];
newPts.getData()[pid * 3 + 2] = model.modelBounds[4];
const corner134 = pid;
++pid;
newLines.getData()[(cid + 0) * 3 + 0] = 2;
newLines.getData()[(cid + 0) * 3 + 1] = corner135;
newLines.getData()[(cid + 0) * 3 + 2] = corner035;
newLines.getData()[(cid + 1) * 3 + 0] = 2;
newLines.getData()[(cid + 1) * 3 + 1] = corner135;
newLines.getData()[(cid + 1) * 3 + 2] = corner125;
newLines.getData()[(cid + 2) * 3 + 0] = 2;
newLines.getData()[(cid + 2) * 3 + 1] = corner135;
newLines.getData()[(cid + 2) * 3 + 2] = corner134;
cid += 3;
// Fill in remaining lines
// vtk.js do not support checking repeating insertion
newLines.getData()[(cid + 0) * 3 + 0] = 2;
newLines.getData()[(cid + 0) * 3 + 1] = corner124;
newLines.getData()[(cid + 0) * 3 + 2] = corner134;
newLines.getData()[(cid + 1) * 3 + 0] = 2;
newLines.getData()[(cid + 1) * 3 + 1] = corner124;
newLines.getData()[(cid + 1) * 3 + 2] = corner125;
cid += 2;
newLines.getData()[(cid + 0) * 3 + 0] = 2;
newLines.getData()[(cid + 0) * 3 + 1] = corner034;
newLines.getData()[(cid + 0) * 3 + 2] = corner134;
newLines.getData()[(cid + 1) * 3 + 0] = 2;
newLines.getData()[(cid + 1) * 3 + 1] = corner034;
newLines.getData()[(cid + 1) * 3 + 2] = corner035;
cid += 2;
newLines.getData()[(cid + 0) * 3 + 0] = 2;
newLines.getData()[(cid + 0) * 3 + 1] = corner025;
newLines.getData()[(cid + 0) * 3 + 2] = corner125;
newLines.getData()[(cid + 1) * 3 + 0] = 2;
newLines.getData()[(cid + 1) * 3 + 1] = corner025;
newLines.getData()[(cid + 1) * 3 + 2] = corner035;
cid += 2;
}
// create x-shadows
if (model.xShadows) {
for (let i = 0; i < 2; ++i) {
newPts.getData()[pid * 3 + 0] = model.modelBounds[i];
newPts.getData()[pid * 3 + 1] = model.modelBounds[2];
newPts.getData()[pid * 3 + 2] = model.focalPoint[2];
++pid;
newPts.getData()[pid * 3 + 0] = model.modelBounds[i];
newPts.getData()[pid * 3 + 1] = model.modelBounds[3];
newPts.getData()[pid * 3 + 2] = model.focalPoint[2];
++pid;
newLines.getData()[cid * 3 + 0] = 2;
newLines.getData()[cid * 3 + 1] = pid - 2;
newLines.getData()[cid * 3 + 2] = pid - 1;
++cid;
newPts.getData()[pid * 3 + 0] = model.modelBounds[i];
newPts.getData()[pid * 3 + 1] = model.focalPoint[1];
newPts.getData()[pid * 3 + 2] = model.modelBounds[4];
++pid;
newPts.getData()[pid * 3 + 0] = model.modelBounds[i];
newPts.getData()[pid * 3 + 1] = model.focalPoint[1];
newPts.getData()[pid * 3 + 2] = model.modelBounds[5];
++pid;
newLines.getData()[cid * 3 + 0] = 2;
newLines.getData()[cid * 3 + 1] = pid - 2;
newLines.getData()[cid * 3 + 2] = pid - 1;
++cid;
}
}
// create y-shadows
if (model.yShadows) {
for (let i = 0; i < 2; ++i) {
newPts.getData()[pid * 3 + 0] = model.modelBounds[0];
newPts.getData()[pid * 3 + 1] = model.modelBounds[i + 2];
newPts.getData()[pid * 3 + 2] = model.focalPoint[2];
++pid;
newPts.getData()[pid * 3 + 0] = model.modelBounds[1];
newPts.getData()[pid * 3 + 1] = model.modelBounds[i + 2];
newPts.getData()[pid * 3 + 2] = model.focalPoint[2];
++pid;
newLines.getData()[cid * 3 + 0] = 2;
newLines.getData()[cid * 3 + 1] = pid - 2;
newLines.getData()[cid * 3 + 2] = pid - 1;
++cid;
newPts.getData()[pid * 3 + 0] = model.focalPoint[0];
newPts.getData()[pid * 3 + 1] = model.modelBounds[i + 2];
newPts.getData()[pid * 3 + 2] = model.modelBounds[4];
++pid;
newPts.getData()[pid * 3 + 0] = model.focalPoint[0];
newPts.getData()[pid * 3 + 1] = model.modelBounds[i + 2];
newPts.getData()[pid * 3 + 2] = model.modelBounds[5];
++pid;
newLines.getData()[cid * 3 + 0] = 2;
newLines.getData()[cid * 3 + 1] = pid - 2;
newLines.getData()[cid * 3 + 2] = pid - 1;
++cid;
}
}
// create z-shadows
if (model.zShadows) {
for (let i = 0; i < 2; ++i) {
newPts.getData()[pid * 3 + 0] = model.modelBounds[0];
newPts.getData()[pid * 3 + 1] = model.focalPoint[1];
newPts.getData()[pid * 3 + 2] = model.modelBounds[i + 4];
++pid;
newPts.getData()[pid * 3 + 0] = model.modelBounds[1];
newPts.getData()[pid * 3 + 1] = model.focalPoint[1];
newPts.getData()[pid * 3 + 2] = model.modelBounds[i + 4];
++pid;
newLines.getData()[cid * 3 + 0] = 2;
newLines.getData()[cid * 3 + 1] = pid - 2;
newLines.getData()[cid * 3 + 2] = pid - 1;
++cid;
newPts.getData()[pid * 3 + 0] = model.focalPoint[0];
newPts.getData()[pid * 3 + 1] = model.modelBounds[2];
newPts.getData()[pid * 3 + 2] = model.modelBounds[i + 4];
++pid;
newPts.getData()[pid * 3 + 0] = model.focalPoint[0];
newPts.getData()[pid * 3 + 1] = model.modelBounds[3];
newPts.getData()[pid * 3 + 2] = model.modelBounds[i + 4];
++pid;
newLines.getData()[cid * 3 + 0] = 2;
newLines.getData()[cid * 3 + 1] = pid - 2;
newLines.getData()[cid * 3 + 2] = pid - 1;
++cid;
}
}
const pts = vtkPoints.newInstance({
size: 3
});
pts.getData()[0] = model.focalPoint[0];
pts.getData()[1] = model.focalPoint[1];
pts.getData()[2] = model.focalPoint[2];
// update ourseleves
model.focus = vtkPolyData.newInstance();
model.focus.setPoints(pts);
polyData.setPoints(newPts);
polyData.setLines(newLines);
outData[0] = polyData;
};
}
// ----------------------------------------------------------------------------
// Object factory
// ----------------------------------------------------------------------------
const DEFAULT_VALUES = {
focus: null,
modelBounds: [-1.0, 1.0, -1.0, 1.0, -1.0, 1.0],
focalPoint: [0.0, 0.0, 0.0],
outline: true,
axes: true,
xShadows: true,
yShadows: true,
zShadows: true,
wrap: false,
translationMode: false
};
// ----------------------------------------------------------------------------
function extend(publicAPI, model, initialValues = {}) {
Object.assign(model, DEFAULT_VALUES, initialValues);
// Build VTK API
// Cursor3D
macro.obj(publicAPI, model);
macro.get(publicAPI, model, ['focus']);
macro.getArray(publicAPI, model, ['modelBounds'], 6);
macro.getArray(publicAPI, model, ['focalPoint'], 3);
macro.setGet(publicAPI, model, ['outline']);
macro.setGet(publicAPI, model, ['axes']);
macro.setGet(publicAPI, model, ['xShadows']);
macro.setGet(publicAPI, model, ['yShadows']);
macro.setGet(publicAPI, model, ['zShadows']);
macro.setGet(publicAPI, model, ['wrap']);
macro.setGet(publicAPI, model, ['translationMode']);
macro.algo(publicAPI, model, 0, 1);
vtkCursor3D(publicAPI, model);
}
// ----------------------------------------------------------------------------
const newInstance = macro.newInstance(extend, 'vtkCursor3D');
// ----------------------------------------------------------------------------
var vtkCursor3D$1 = {
newInstance,
extend
};
export { vtkCursor3D$1 as default, extend, newInstance };