@kitware/vtk.js
Version:
Visualization Toolkit for the Web
1,639 lines (1,314 loc) • 59.9 kB
JavaScript
import _slicedToArray from '@babel/runtime/helpers/slicedToArray';
import _typeof from '@babel/runtime/helpers/typeof';
import _defineProperty from '@babel/runtime/helpers/defineProperty';
import _toConsumableArray from '@babel/runtime/helpers/toConsumableArray';
import _construct from '@babel/runtime/helpers/construct';
import DeepEqual from 'fast-deep-equal';
import vtk, { vtkGlobal } from './vtk.js';
import ClassHierarchy from './Common/Core/ClassHierarchy.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 globalMTime = 0;
var VOID = Symbol('void');
function getCurrentGlobalMTime() {
return globalMTime;
} // ----------------------------------------------------------------------------
// Logging function calls
// ----------------------------------------------------------------------------
/* eslint-disable no-prototype-builtins */
var fakeConsole = {};
function noOp() {}
var consoleMethods = ['log', 'debug', 'info', 'warn', 'error', 'time', 'timeEnd', 'group', 'groupEnd'];
consoleMethods.forEach(function (methodName) {
fakeConsole[methodName] = noOp;
});
vtkGlobal.console = console.hasOwnProperty('log') ? console : fakeConsole;
var loggerFunctions = {
debug: noOp,
// Don't print debug by default
error: vtkGlobal.console.error || noOp,
info: vtkGlobal.console.info || noOp,
log: vtkGlobal.console.log || noOp,
warn: vtkGlobal.console.warn || noOp
};
function setLoggerFunction(name, fn) {
if (loggerFunctions[name]) {
loggerFunctions[name] = fn || noOp;
}
}
function vtkLogMacro() {
loggerFunctions.log.apply(loggerFunctions, arguments);
}
function vtkInfoMacro() {
loggerFunctions.info.apply(loggerFunctions, arguments);
}
function vtkDebugMacro() {
loggerFunctions.debug.apply(loggerFunctions, arguments);
}
function vtkErrorMacro() {
loggerFunctions.error.apply(loggerFunctions, arguments);
}
function vtkWarningMacro() {
loggerFunctions.warn.apply(loggerFunctions, arguments);
}
var ERROR_ONCE_MAP = {};
function vtkOnceErrorMacro(str) {
if (!ERROR_ONCE_MAP[str]) {
loggerFunctions.error(str);
ERROR_ONCE_MAP[str] = true;
}
} // ----------------------------------------------------------------------------
// TypedArray
// ----------------------------------------------------------------------------
var TYPED_ARRAYS = Object.create(null);
TYPED_ARRAYS.Float32Array = Float32Array;
TYPED_ARRAYS.Float64Array = Float64Array;
TYPED_ARRAYS.Uint8Array = Uint8Array;
TYPED_ARRAYS.Int8Array = Int8Array;
TYPED_ARRAYS.Uint16Array = Uint16Array;
TYPED_ARRAYS.Int16Array = Int16Array;
TYPED_ARRAYS.Uint32Array = Uint32Array;
TYPED_ARRAYS.Int32Array = Int32Array;
TYPED_ARRAYS.Uint8ClampedArray = Uint8ClampedArray;
try {
TYPED_ARRAYS.BigInt64Array = BigInt64Array;
TYPED_ARRAYS.BigUint64Array = BigUint64Array;
} catch (_unused) {// ignore
}
function newTypedArray(type) {
for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
args[_key - 1] = arguments[_key];
}
return _construct(TYPED_ARRAYS[type] || Float64Array, args);
}
function newTypedArrayFrom(type) {
var _ref;
for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
args[_key2 - 1] = arguments[_key2];
}
return (_ref = TYPED_ARRAYS[type] || Float64Array).from.apply(_ref, args);
} // ----------------------------------------------------------------------------
// capitilize provided string
// ----------------------------------------------------------------------------
function capitalize(str) {
return str.charAt(0).toUpperCase() + str.slice(1);
}
function _capitalize(str) {
return capitalize(str[0] === '_' ? str.slice(1) : str);
}
function uncapitalize(str) {
return str.charAt(0).toLowerCase() + str.slice(1);
} // ----------------------------------------------------------------------------
// Convert byte size into a well formatted string
// ----------------------------------------------------------------------------
function formatBytesToProperUnit(size) {
var precision = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 2;
var chunkSize = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1000;
var units = ['TB', 'GB', 'MB', 'KB'];
var value = Number(size);
var currentUnit = 'B';
while (value > chunkSize) {
value /= chunkSize;
currentUnit = units.pop();
}
return "".concat(value.toFixed(precision), " ").concat(currentUnit);
} // ----------------------------------------------------------------------------
// Convert thousand number with proper separator
// ----------------------------------------------------------------------------
function formatNumbersWithThousandSeparator(n) {
var separator = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ' ';
var sections = [];
var size = n;
while (size > 1000) {
sections.push("000".concat(size % 1000).slice(-3));
size = Math.floor(size / 1000);
}
if (size > 0) {
sections.push(size);
}
sections.reverse();
return sections.join(separator);
} // ----------------------------------------------------------------------------
// Array helper
// ----------------------------------------------------------------------------
function safeArrays(model) {
Object.keys(model).forEach(function (key) {
if (Array.isArray(model[key])) {
model[key] = [].concat(model[key]);
}
});
} // ----------------------------------------------------------------------------
// shallow equals
// ----------------------------------------------------------------------------
function shallowEquals(a, b) {
if (a === b) {
return true;
}
if (Array.isArray(a) && Array.isArray(b)) {
if (a.length !== b.length) {
return false;
}
for (var i = 0; i < a.length; i++) {
if (a[i] !== b[i]) {
return false;
}
}
return true;
}
return false;
} // ----------------------------------------------------------------------------
function enumToString(e, value) {
return Object.keys(e).find(function (key) {
return e[key] === value;
});
}
function getStateArrayMapFunc(item) {
if (item && item.isA) {
return item.getState();
}
return item;
} // ----------------------------------------------------------------------------
// setImmediate
// ----------------------------------------------------------------------------
function setImmediateVTK(fn) {
setTimeout(fn, 0);
} // ----------------------------------------------------------------------------
// measurePromiseExecution
//
// Measures the time it takes for a promise to finish from
// the time this function is invoked.
// The callback receives the time it took for the promise to resolve or reject.
// ----------------------------------------------------------------------------
function measurePromiseExecution(promise, callback) {
var start = performance.now();
promise.finally(function () {
var delta = performance.now() - start;
callback(delta);
});
} // ----------------------------------------------------------------------------
// vtkObject: modified(), onModified(callback), delete()
// ----------------------------------------------------------------------------
function obj() {
var publicAPI = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var model = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
// Ensure each instance as a unique ref of array
safeArrays(model);
var callbacks = [];
if (!Number.isInteger(model.mtime)) {
model.mtime = ++globalMTime;
}
if (!('classHierarchy' in model)) {
model.classHierarchy = new ClassHierarchy('vtkObject');
} else if (!(model.classHierarchy instanceof ClassHierarchy)) {
var hierarchy = new ClassHierarchy();
for (var i = 0; i < model.classHierarchy.length; i++) {
hierarchy.push(model.classHierarchy[i]);
}
model.classHierarchy = hierarchy;
}
function off(index) {
callbacks[index] = null;
}
function on(index) {
function unsubscribe() {
off(index);
}
return Object.freeze({
unsubscribe: unsubscribe
});
}
publicAPI.isDeleted = function () {
return !!model.deleted;
};
publicAPI.modified = function (otherMTime) {
if (model.deleted) {
vtkErrorMacro('instance deleted - cannot call any method');
return;
}
if (otherMTime && otherMTime < publicAPI.getMTime()) {
return;
}
model.mtime = ++globalMTime;
callbacks.forEach(function (callback) {
return callback && callback(publicAPI);
});
};
publicAPI.onModified = function (callback) {
if (model.deleted) {
vtkErrorMacro('instance deleted - cannot call any method');
return null;
}
var index = callbacks.length;
callbacks.push(callback);
return on(index);
};
publicAPI.getMTime = function () {
return model.mtime;
};
publicAPI.isA = function (className) {
var count = model.classHierarchy.length; // we go backwards as that is more likely for
// early termination
while (count--) {
if (model.classHierarchy[count] === className) {
return true;
}
}
return false;
};
publicAPI.getClassName = function () {
var depth = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
return model.classHierarchy[model.classHierarchy.length - 1 - depth];
};
publicAPI.set = function () {
var map = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var noWarning = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
var noFunction = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
var ret = false;
Object.keys(map).forEach(function (name) {
var fn = noFunction ? null : publicAPI["set".concat(capitalize(name))];
if (fn && Array.isArray(map[name]) && fn.length > 1) {
ret = fn.apply(void 0, _toConsumableArray(map[name])) || ret;
} else if (fn) {
ret = fn(map[name]) || ret;
} else {
// Set data on model directly
if (['mtime'].indexOf(name) === -1 && !noWarning) {
vtkWarningMacro("Warning: Set value to model directly ".concat(name, ", ").concat(map[name]));
}
ret = model[name] !== map[name] || ret;
model[name] = map[name];
}
});
return ret;
};
publicAPI.get = function () {
for (var _len3 = arguments.length, list = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
list[_key3] = arguments[_key3];
}
if (!list.length) {
return model;
}
var subset = {};
list.forEach(function (name) {
subset[name] = model[name];
});
return subset;
};
publicAPI.getReferenceByName = function (val) {
return model[val];
};
publicAPI.delete = function () {
Object.keys(model).forEach(function (field) {
return delete model[field];
});
callbacks.forEach(function (el, index) {
return off(index);
}); // Flag the instance being deleted
model.deleted = true;
}; // Add serialization support
publicAPI.getState = function () {
if (model.deleted) {
return null;
}
var jsonArchive = _objectSpread(_objectSpread({}, model), {}, {
vtkClass: publicAPI.getClassName()
}); // Convert every vtkObject to its serializable form
Object.keys(jsonArchive).forEach(function (keyName) {
if (jsonArchive[keyName] === null || jsonArchive[keyName] === undefined || keyName[0] === '_' // protected members start with _
) {
delete jsonArchive[keyName];
} else if (jsonArchive[keyName].isA) {
jsonArchive[keyName] = jsonArchive[keyName].getState();
} else if (Array.isArray(jsonArchive[keyName])) {
jsonArchive[keyName] = jsonArchive[keyName].map(getStateArrayMapFunc);
}
}); // Sort resulting object by key name
var sortedObj = {};
Object.keys(jsonArchive).sort().forEach(function (name) {
sortedObj[name] = jsonArchive[name];
}); // Remove mtime
if (sortedObj.mtime) {
delete sortedObj.mtime;
}
return sortedObj;
}; // Add shallowCopy(otherInstance) support
publicAPI.shallowCopy = function (other) {
var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
if (other.getClassName() !== publicAPI.getClassName()) {
throw new Error("Cannot ShallowCopy ".concat(other.getClassName(), " into ").concat(publicAPI.getClassName()));
}
var otherModel = other.get();
var keyList = Object.keys(model).sort();
var otherKeyList = Object.keys(otherModel).sort();
otherKeyList.forEach(function (key) {
var keyIdx = keyList.indexOf(key);
if (keyIdx === -1) {
if (debug) {
vtkDebugMacro("add ".concat(key, " in shallowCopy"));
}
} else {
keyList.splice(keyIdx, 1);
}
model[key] = otherModel[key];
});
if (keyList.length && debug) {
vtkDebugMacro("Untouched keys: ".concat(keyList.join(', ')));
}
publicAPI.modified();
}; // This function will get called when one invoke JSON.stringify(vtkObject)
// JSON.stringify will only stringify the return value of this function
publicAPI.toJSON = function vtkObjToJSON() {
return publicAPI.getState();
}; // Allow usage as decorator
return publicAPI;
} // ----------------------------------------------------------------------------
// getXXX: add getters
// ----------------------------------------------------------------------------
var objectGetterMap = {
object: function object(publicAPI, model, field) {
return function getter() {
return _objectSpread({}, model[field.name]);
};
}
};
function get(publicAPI, model, fieldNames) {
fieldNames.forEach(function (field) {
if (_typeof(field) === 'object') {
var getter = objectGetterMap[field.type];
if (getter) {
publicAPI["get".concat(_capitalize(field.name))] = getter(publicAPI, model, field);
} else {
publicAPI["get".concat(_capitalize(field.name))] = function () {
return model[field.name];
};
}
} else {
publicAPI["get".concat(_capitalize(field))] = function () {
return model[field];
};
}
});
} // ----------------------------------------------------------------------------
// setXXX: add setters
// ----------------------------------------------------------------------------
var objectSetterMap = {
enum: function _enum(publicAPI, model, field) {
var onChanged = "_on".concat(_capitalize(field.name), "Changed");
return function (value) {
if (typeof value === 'string') {
if (field.enum[value] !== undefined) {
if (model[field.name] !== field.enum[value]) {
model[field.name] = field.enum[value];
publicAPI.modified();
return true;
}
return false;
}
vtkErrorMacro("Set Enum with invalid argument ".concat(field, ", ").concat(value));
throw new RangeError('Set Enum with invalid string argument');
}
if (typeof value === 'number') {
if (model[field.name] !== value) {
if (Object.keys(field.enum).map(function (key) {
return field.enum[key];
}).indexOf(value) !== -1) {
var _model$onChanged;
var previousValue = model[field.name];
model[field.name] = value;
(_model$onChanged = model[onChanged]) === null || _model$onChanged === void 0 ? void 0 : _model$onChanged.call(model, publicAPI, model, value, previousValue);
publicAPI.modified();
return true;
}
vtkErrorMacro("Set Enum outside numeric range ".concat(field, ", ").concat(value));
throw new RangeError('Set Enum outside numeric range');
}
return false;
}
vtkErrorMacro("Set Enum with invalid argument (String/Number) ".concat(field, ", ").concat(value));
throw new TypeError('Set Enum with invalid argument (String/Number)');
};
},
object: function object(publicAPI, model, field) {
var onChanged = "_on".concat(_capitalize(field.name), "Changed");
return function (value) {
if (!DeepEqual(model[field.name], value)) {
var _model$onChanged2;
var previousValue = model[field.name];
model[field.name] = value;
(_model$onChanged2 = model[onChanged]) === null || _model$onChanged2 === void 0 ? void 0 : _model$onChanged2.call(model, publicAPI, model, value, previousValue);
publicAPI.modified();
return true;
}
return false;
};
}
};
function findSetter(field) {
if (_typeof(field) === 'object') {
var fn = objectSetterMap[field.type];
if (fn) {
return function (publicAPI, model) {
return fn(publicAPI, model, field);
};
}
vtkErrorMacro("No setter for field ".concat(field));
throw new TypeError('No setter for field');
}
return function getSetter(publicAPI, model) {
var onChanged = "_on".concat(_capitalize(field), "Changed");
return function setter(value) {
if (model.deleted) {
vtkErrorMacro('instance deleted - cannot call any method');
return false;
}
if (model[field] !== value) {
var _model$onChanged3;
var previousValue = model[field.name];
model[field] = value;
(_model$onChanged3 = model[onChanged]) === null || _model$onChanged3 === void 0 ? void 0 : _model$onChanged3.call(model, publicAPI, model, value, previousValue);
publicAPI.modified();
return true;
}
return false;
};
};
}
function set(publicAPI, model, fields) {
fields.forEach(function (field) {
if (_typeof(field) === 'object') {
publicAPI["set".concat(_capitalize(field.name))] = findSetter(field)(publicAPI, model);
} else {
publicAPI["set".concat(_capitalize(field))] = findSetter(field)(publicAPI, model);
}
});
} // ----------------------------------------------------------------------------
// set/get XXX: add both setters and getters
// ----------------------------------------------------------------------------
function setGet(publicAPI, model, fieldNames) {
get(publicAPI, model, fieldNames);
set(publicAPI, model, fieldNames);
} // ----------------------------------------------------------------------------
// getXXX: add getters for object of type array with copy to be safe
// getXXXByReference: add getters for object of type array without copy
// ----------------------------------------------------------------------------
function getArray(publicAPI, model, fieldNames) {
fieldNames.forEach(function (field) {
publicAPI["get".concat(_capitalize(field))] = function () {
return model[field] ? Array.from(model[field]) : model[field];
};
publicAPI["get".concat(_capitalize(field), "ByReference")] = function () {
return model[field];
};
});
} // ----------------------------------------------------------------------------
// setXXX: add setter for object of type array
// if 'defaultVal' is supplied, shorter arrays will be padded to 'size' with 'defaultVal'
// set...From: fast path to copy the content of an array to the current one without call to modified.
// ----------------------------------------------------------------------------
function setArray(publicAPI, model, fieldNames, size) {
var defaultVal = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : undefined;
fieldNames.forEach(function (field) {
if (model[field] && size && model[field].length !== size) {
throw new RangeError("Invalid initial number of values for array (".concat(field, ")"));
}
var onChanged = "_on".concat(_capitalize(field), "Changed");
publicAPI["set".concat(_capitalize(field))] = function () {
if (model.deleted) {
vtkErrorMacro('instance deleted - cannot call any method');
return false;
}
for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
args[_key4] = arguments[_key4];
}
var array = args;
var changeDetected;
var needCopy = false; // allow null or an array to be passed as a single arg.
if (array.length === 1 && (array[0] == null || array[0].length >= 0)) {
/* eslint-disable prefer-destructuring */
array = array[0];
/* eslint-enable prefer-destructuring */
needCopy = true;
}
if (array == null) {
changeDetected = model[field] !== array;
} else {
if (size && array.length !== size) {
if (array.length < size && defaultVal !== undefined) {
array = Array.from(array);
needCopy = false;
while (array.length < size) {
array.push(defaultVal);
}
} else {
throw new RangeError("Invalid number of values for array setter (".concat(field, ")"));
}
}
changeDetected = model[field] == null || model[field].length !== array.length;
for (var i = 0; !changeDetected && i < array.length; ++i) {
changeDetected = model[field][i] !== array[i];
}
if (changeDetected && needCopy) {
array = Array.from(array);
}
}
if (changeDetected) {
var _model$onChanged4;
var previousValue = model[field.name];
model[field] = array;
(_model$onChanged4 = model[onChanged]) === null || _model$onChanged4 === void 0 ? void 0 : _model$onChanged4.call(model, publicAPI, model, array, previousValue);
publicAPI.modified();
}
return changeDetected;
};
publicAPI["set".concat(_capitalize(field), "From")] = function (otherArray) {
var target = model[field];
otherArray.forEach(function (v, i) {
target[i] = v;
});
};
});
} // ----------------------------------------------------------------------------
// set/get XXX: add setter and getter for object of type array
// ----------------------------------------------------------------------------
function setGetArray(publicAPI, model, fieldNames, size) {
var defaultVal = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : undefined;
getArray(publicAPI, model, fieldNames);
setArray(publicAPI, model, fieldNames, size, defaultVal);
}
function moveToProtected(publicAPI, model, fieldNames) {
for (var i = 0; i < fieldNames.length; i++) {
var fieldName = fieldNames[i];
if (model[fieldName] !== undefined) {
model["_".concat(fieldName)] = model[fieldName];
delete model[fieldName];
}
}
} // ----------------------------------------------------------------------------
// vtkAlgorithm: setInputData(), setInputConnection(), getOutputData(), getOutputPort()
// ----------------------------------------------------------------------------
function algo(publicAPI, model, numberOfInputs, numberOfOutputs) {
if (model.inputData) {
model.inputData = model.inputData.map(vtk);
} else {
model.inputData = [];
}
if (model.inputConnection) {
model.inputConnection = model.inputConnection.map(vtk);
} else {
model.inputConnection = [];
}
if (model.output) {
model.output = model.output.map(vtk);
} else {
model.output = [];
}
if (model.inputArrayToProcess) {
model.inputArrayToProcess = model.inputArrayToProcess.map(vtk);
} else {
model.inputArrayToProcess = [];
} // Cache the argument for later manipulation
model.numberOfInputs = numberOfInputs; // Methods
function setInputData(dataset) {
var port = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
if (model.deleted) {
vtkErrorMacro('instance deleted - cannot call any method');
return;
}
if (port >= model.numberOfInputs) {
vtkErrorMacro("algorithm ".concat(publicAPI.getClassName(), " only has ").concat(model.numberOfInputs, " input ports. To add more input ports, use addInputData()"));
return;
}
if (model.inputData[port] !== dataset || model.inputConnection[port]) {
model.inputData[port] = dataset;
model.inputConnection[port] = null;
if (publicAPI.modified) {
publicAPI.modified();
}
}
}
function getInputData() {
var port = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
if (model.inputConnection[port]) {
model.inputData[port] = model.inputConnection[port]();
}
return model.inputData[port];
}
function setInputConnection(outputPort) {
var port = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
if (model.deleted) {
vtkErrorMacro('instance deleted - cannot call any method');
return;
}
if (port >= model.numberOfInputs) {
var msg = "algorithm ".concat(publicAPI.getClassName(), " only has ");
msg += "".concat(model.numberOfInputs);
msg += ' input ports. To add more input ports, use addInputConnection()';
vtkErrorMacro(msg);
return;
}
model.inputData[port] = null;
model.inputConnection[port] = outputPort;
}
function getInputConnection() {
var port = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
return model.inputConnection[port];
}
function getPortToFill() {
var portToFill = model.numberOfInputs;
while (portToFill && !model.inputData[portToFill - 1] && !model.inputConnection[portToFill - 1]) {
portToFill--;
}
if (portToFill === model.numberOfInputs) {
model.numberOfInputs++;
}
return portToFill;
}
function addInputConnection(outputPort) {
if (model.deleted) {
vtkErrorMacro('instance deleted - cannot call any method');
return;
}
setInputConnection(outputPort, getPortToFill());
}
function addInputData(dataset) {
if (model.deleted) {
vtkErrorMacro('instance deleted - cannot call any method');
return;
}
setInputData(dataset, getPortToFill());
}
function getOutputData() {
var port = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
if (model.deleted) {
vtkErrorMacro('instance deleted - cannot call any method');
return null;
}
if (publicAPI.shouldUpdate()) {
publicAPI.update();
}
return model.output[port];
}
publicAPI.shouldUpdate = function () {
var localMTime = publicAPI.getMTime();
var minOutputMTime = Infinity;
var count = numberOfOutputs;
while (count--) {
if (!model.output[count] || model.output[count].isDeleted()) {
return true;
}
var mt = model.output[count].getMTime();
if (mt < localMTime) {
return true;
}
if (mt < minOutputMTime) {
minOutputMTime = mt;
}
}
count = model.numberOfInputs;
while (count--) {
var _model$inputConnectio, _publicAPI$getInputDa;
if ((_model$inputConnectio = model.inputConnection[count]) !== null && _model$inputConnectio !== void 0 && _model$inputConnectio.filter.shouldUpdate() || ((_publicAPI$getInputDa = publicAPI.getInputData(count)) === null || _publicAPI$getInputDa === void 0 ? void 0 : _publicAPI$getInputDa.getMTime()) > minOutputMTime) {
return true;
}
}
return false;
};
function getOutputPort() {
var port = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
var outputPortAccess = function outputPortAccess() {
return getOutputData(port);
}; // Add reference to filter
outputPortAccess.filter = publicAPI;
return outputPortAccess;
} // Handle input if needed
if (model.numberOfInputs) {
// Reserve inputs
var count = model.numberOfInputs;
while (count--) {
model.inputData.push(null);
model.inputConnection.push(null);
} // Expose public methods
publicAPI.setInputData = setInputData;
publicAPI.setInputConnection = setInputConnection;
publicAPI.addInputData = addInputData;
publicAPI.addInputConnection = addInputConnection;
publicAPI.getInputData = getInputData;
publicAPI.getInputConnection = getInputConnection;
}
if (numberOfOutputs) {
publicAPI.getOutputData = getOutputData;
publicAPI.getOutputPort = getOutputPort;
}
publicAPI.update = function () {
var ins = [];
if (model.numberOfInputs) {
var _count = 0;
while (_count < model.numberOfInputs) {
ins[_count] = publicAPI.getInputData(_count);
_count++;
}
}
if (publicAPI.shouldUpdate() && publicAPI.requestData) {
publicAPI.requestData(ins, model.output);
}
};
publicAPI.getNumberOfInputPorts = function () {
return model.numberOfInputs;
};
publicAPI.getNumberOfOutputPorts = function () {
return numberOfOutputs || model.output.length;
};
publicAPI.getInputArrayToProcess = function (inputPort) {
var arrayDesc = model.inputArrayToProcess[inputPort];
var ds = model.inputData[inputPort];
if (arrayDesc && ds) {
return ds["get".concat(arrayDesc.fieldAssociation)]().getArray(arrayDesc.arrayName);
}
return null;
};
publicAPI.setInputArrayToProcess = function (inputPort, arrayName, fieldAssociation) {
var attributeType = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 'Scalars';
while (model.inputArrayToProcess.length < inputPort) {
model.inputArrayToProcess.push(null);
}
model.inputArrayToProcess[inputPort] = {
arrayName: arrayName,
fieldAssociation: fieldAssociation,
attributeType: attributeType
};
};
} // ----------------------------------------------------------------------------
// Event handling: onXXX(callback), invokeXXX(args...)
// ----------------------------------------------------------------------------
var EVENT_ABORT = Symbol('Event abort');
function event(publicAPI, model, eventName) {
var callbacks = [];
var previousDelete = publicAPI.delete;
var curCallbackID = 1;
function off(callbackID) {
for (var i = 0; i < callbacks.length; ++i) {
var _callbacks$i = _slicedToArray(callbacks[i], 1),
cbID = _callbacks$i[0];
if (cbID === callbackID) {
callbacks.splice(i, 1);
return;
}
}
}
function on(callbackID) {
function unsubscribe() {
off(callbackID);
}
return Object.freeze({
unsubscribe: unsubscribe
});
}
function invoke() {
var _arguments = arguments;
if (model.deleted) {
vtkErrorMacro('instance deleted - cannot call any method');
return;
}
/* eslint-disable prefer-rest-params */
// Go through a copy of the callbacks array in case new callbacks
// get prepended within previous callbacks
var currentCallbacks = callbacks.slice();
var _loop = function _loop(index) {
var _currentCallbacks$ind = _slicedToArray(currentCallbacks[index], 3),
cb = _currentCallbacks$ind[1],
priority = _currentCallbacks$ind[2];
if (!cb) {
return "continue"; // eslint-disable-line
}
if (priority < 0) {
setTimeout(function () {
return cb.apply(publicAPI, _arguments);
}, 1 - priority);
} else {
// Abort only if the callback explicitly returns false
var continueNext = cb.apply(publicAPI, _arguments);
if (continueNext === EVENT_ABORT) {
return "break";
}
}
};
for (var index = 0; index < currentCallbacks.length; ++index) {
var _ret = _loop(index);
if (_ret === "continue") continue;
if (_ret === "break") break;
}
/* eslint-enable prefer-rest-params */
}
publicAPI["invoke".concat(_capitalize(eventName))] = invoke;
publicAPI["on".concat(_capitalize(eventName))] = function (callback) {
var priority = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0.0;
if (!callback.apply) {
console.error("Invalid callback for event ".concat(eventName));
return null;
}
if (model.deleted) {
vtkErrorMacro('instance deleted - cannot call any method');
return null;
}
var callbackID = curCallbackID++;
callbacks.push([callbackID, callback, priority]);
callbacks.sort(function (cb1, cb2) {
return cb2[2] - cb1[2];
});
return on(callbackID);
};
publicAPI.delete = function () {
previousDelete();
callbacks.forEach(function (_ref2) {
var _ref3 = _slicedToArray(_ref2, 1),
cbID = _ref3[0];
return off(cbID);
});
};
} // ----------------------------------------------------------------------------
// newInstance
// ----------------------------------------------------------------------------
function newInstance(extend, className) {
var constructor = function constructor() {
var initialValues = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var model = {};
var publicAPI = {};
extend(publicAPI, model, initialValues);
return Object.freeze(publicAPI);
}; // Register constructor to factory
if (className) {
vtk.register(className, constructor);
}
return constructor;
} // ----------------------------------------------------------------------------
// Chain function calls
// ----------------------------------------------------------------------------
function chain() {
for (var _len5 = arguments.length, fn = new Array(_len5), _key5 = 0; _key5 < _len5; _key5++) {
fn[_key5] = arguments[_key5];
}
return function () {
for (var _len6 = arguments.length, args = new Array(_len6), _key6 = 0; _key6 < _len6; _key6++) {
args[_key6] = arguments[_key6];
}
return fn.filter(function (i) {
return !!i;
}).map(function (i) {
return i.apply(void 0, args);
});
};
} // ----------------------------------------------------------------------------
// Some utility methods for vtk objects
// ----------------------------------------------------------------------------
function isVtkObject(instance) {
return instance && instance.isA && instance.isA('vtkObject');
}
function traverseInstanceTree(instance, extractFunction) {
var accumulator = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
var visitedInstances = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : [];
if (isVtkObject(instance)) {
if (visitedInstances.indexOf(instance) >= 0) {
// avoid cycles
return accumulator;
}
visitedInstances.push(instance);
var result = extractFunction(instance);
if (result !== undefined) {
accumulator.push(result);
} // Now go through this instance's model
var model = instance.get();
Object.keys(model).forEach(function (key) {
var modelObj = model[key];
if (Array.isArray(modelObj)) {
modelObj.forEach(function (subObj) {
traverseInstanceTree(subObj, extractFunction, accumulator, visitedInstances);
});
} else {
traverseInstanceTree(modelObj, extractFunction, accumulator, visitedInstances);
}
});
}
return accumulator;
} // ----------------------------------------------------------------------------
// Returns a function, that, as long as it continues to be invoked, will not
// be triggered. The function will be called after it stops being called for
// N milliseconds. If `immediate` is passed, trigger the function on the
// leading edge, instead of the trailing.
function debounce(func, wait, immediate) {
var _this = this;
var timeout;
var debounced = function debounced() {
for (var _len7 = arguments.length, args = new Array(_len7), _key7 = 0; _key7 < _len7; _key7++) {
args[_key7] = arguments[_key7];
}
var context = _this;
var later = function later() {
timeout = null;
if (!immediate) {
func.apply(context, args);
}
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) {
func.apply(context, args);
}
};
debounced.cancel = function () {
return clearTimeout(timeout);
};
return debounced;
} // ----------------------------------------------------------------------------
// Creates a throttled function that only invokes `func` at most once per
// every `wait` milliseconds.
function throttle(callback, delay) {
var isThrottled = false;
var argsToUse = null;
function next() {
isThrottled = false;
if (argsToUse !== null) {
wrapper.apply(void 0, _toConsumableArray(argsToUse)); // eslint-disable-line
argsToUse = null;
}
}
function wrapper() {
for (var _len8 = arguments.length, args = new Array(_len8), _key8 = 0; _key8 < _len8; _key8++) {
args[_key8] = arguments[_key8];
}
if (isThrottled) {
argsToUse = args;
return;
}
isThrottled = true;
callback.apply(void 0, args);
setTimeout(next, delay);
}
return wrapper;
} // ----------------------------------------------------------------------------
// keystore(publicAPI, model, initialKeystore)
//
// - initialKeystore: Initial keystore. This can be either a Map or an
// object.
//
// Generated API
// setKey(key, value) : mixed (returns value)
// getKey(key) : mixed
// getAllKeys() : [mixed]
// deleteKey(key) : Boolean
// ----------------------------------------------------------------------------
function keystore(publicAPI, model) {
var initialKeystore = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
model.keystore = Object.assign(model.keystore || {}, initialKeystore);
publicAPI.setKey = function (key, value) {
model.keystore[key] = value;
};
publicAPI.getKey = function (key) {
return model.keystore[key];
};
publicAPI.getAllKeys = function () {
return Object.keys(model.keystore);
};
publicAPI.deleteKey = function (key) {
return delete model.keystore[key];
};
publicAPI.clearKeystore = function () {
return publicAPI.getAllKeys().forEach(function (key) {
return delete model.keystore[key];
});
};
} // ----------------------------------------------------------------------------
// proxy(publicAPI, model, sectionName, propertyUI)
//
// - sectionName: Name of the section for UI
// - propertyUI: List of props with their UI description
//
// Generated API
// getProxyId() : String
// listProxyProperties() : [string]
// updateProxyProperty(name, prop)
// getProxySection() => List of properties for UI generation
// ----------------------------------------------------------------------------
var nextProxyId = 1;
var ROOT_GROUP_NAME = '__root__';
function proxy(publicAPI, model) {
// Proxies are keystores
keystore(publicAPI, model);
var parentDelete = publicAPI.delete; // getProxyId
model.proxyId = "".concat(nextProxyId++); // ui handling
model.ui = JSON.parse(JSON.stringify(model.ui || [])); // deep copy
get(publicAPI, model, ['proxyId', 'proxyGroup', 'proxyName']);
setGet(publicAPI, model, ['proxyManager']); // group properties
var propertyMap = {};
var groupChildrenNames = {};
function registerProperties(descriptionList, currentGroupName) {
if (!groupChildrenNames[currentGroupName]) {
groupChildrenNames[currentGroupName] = [];
}
var childrenNames = groupChildrenNames[currentGroupName];
for (var i = 0; i < descriptionList.length; i++) {
childrenNames.push(descriptionList[i].name);
propertyMap[descriptionList[i].name] = descriptionList[i];
if (descriptionList[i].children && descriptionList[i].children.length) {
registerProperties(descriptionList[i].children, descriptionList[i].name);
}
}
}
registerProperties(model.ui, ROOT_GROUP_NAME);
publicAPI.updateUI = function (ui) {
model.ui = JSON.parse(JSON.stringify(ui || [])); // deep copy
Object.keys(propertyMap).forEach(function (k) {
return delete propertyMap[k];
});
Object.keys(groupChildrenNames).forEach(function (k) {
return delete groupChildrenNames[k];
});
registerProperties(model.ui, ROOT_GROUP_NAME);
publicAPI.modified();
};
function listProxyProperties() {
var gName = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ROOT_GROUP_NAME;
return groupChildrenNames[gName];
}
publicAPI.updateProxyProperty = function (propertyName, propUI) {
var prop = propertyMap[propertyName];
if (prop) {
Object.assign(prop, propUI);
} else {
propertyMap[propertyName] = _objectSpread({}, propUI);
}
};
publicAPI.activate = function () {
if (model.proxyManager) {
var setActiveMethod = "setActive".concat(_capitalize(publicAPI.getProxyGroup().slice(0, -1)));
if (model.proxyManager[setActiveMethod]) {
model.proxyManager[setActiveMethod](publicAPI);
}
}
}; // property link
model.propertyLinkSubscribers = {};
publicAPI.registerPropertyLinkForGC = function (otherLink, type) {
if (!(type in model.propertyLinkSubscribers)) {
model.propertyLinkSubscribers[type] = [];
}
model.propertyLinkSubscribers[type].push(otherLink);
};
publicAPI.gcPropertyLinks = function (type) {
var subscribers = model.propertyLinkSubscribers[type] || [];
while (subscribers.length) {
subscribers.pop().unbind(publicAPI);
}
};
model.propertyLinkMap = {};
publicAPI.getPropertyLink = function (id) {
var persistent = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
if (model.propertyLinkMap[id]) {
return model.propertyLinkMap[id];
}
var value = null;
var links = [];
var count = 0;
var updateInProgress = false;
function update(source) {
var force = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
if (updateInProgress) {
return null;
}
var needUpdate = [];
var sourceLink = null;
count = links.length;
while (count--) {
var link = links[count];
if (link.instance === source) {
sourceLink = link;
} else {
needUpdate.push(link);
}
}
if (!sourceLink) {
return null;
}
var newValue = sourceLink.instance["get".concat(_capitalize(sourceLink.propertyName))]();
if (!shallowEquals(newValue, value) || force) {
value = newValue;
updateInProgress = true;
while (needUpdate.length) {
var linkToUpdate = needUpdate.pop();
linkToUpdate.instance.set(_defineProperty({}, linkToUpdate.propertyName, value));
}
updateInProgress = false;
}
if (model.propertyLinkMap[id].persistent) {
model.propertyLinkMap[id].value = newValue;
}
return newValue;
}
function unbind(instance, propertyName) {
var indexToDelete = [];
count = links.length;
while (count--) {
var link = links[count];
if (link.instance === instance && (link.propertyName === propertyName || propertyName === undefined)) {
link.subscription.unsubscribe();
indexToDelete.push(count);
}
}
while (indexToDelete.length) {
links.splice(indexToDelete.pop(), 1);
}
}
function bind(instance, propertyName) {
var updateMe = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
var subscription = instance.onModified(update);
var other = links[0];
links.push({
instance: instance,
propertyName: propertyName,
subscription: subscription
});
if (updateMe) {
if (model.propertyLinkMap[id].persistent && model.propertyLinkMap[id].value !== undefined) {
instance.set(_defineProperty({}, propertyName, model.propertyLinkMap[id].value));
} else if (other) {
update(other.instance, true);
}
}
return {
unsubscribe: function unsubscribe() {
return unbind(instance, propertyName);
}
};
}
function unsubscribe() {
while (links.length) {
links.pop().subscription.unsubscribe();
}
}
var linkHandler = {
bind: bind,
unbind: unbind,
unsubscribe: unsubscribe,
persistent: persistent
};
model.propertyLinkMap[id] = linkHandler;
return linkHandler;
}; // extract values
function getProperties() {
var groupName = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ROOT_GROUP_NAME;
var values = [];
var id = model.proxyId;
var propertyNames = listProxyProperties(groupName) || [];
for (var i = 0; i < propertyNames.length; i++) {
var name = propertyNames[i];
var method = publicAPI["get".concat(_capitalize(name))];
var value = method ? method() : undefined;
var prop = {
id: id,
name: name,
value: value
};
var children = getProperties(name);
if (children.length) {
prop.children = children;
}
values.push(prop);
}
return values;
}
publicAPI.listPropertyNames = function () {
return getProperties().map(function (p) {
return p.name;
});
};
publicAPI.getPropertyByName = function (name) {
return getProperties().find(function (p) {
return p.name === name;
});
};
publicAPI.getPropertyDomainByName = function (name) {
return (propertyMap[name] || {}).domain;
}; // ui section
publicAPI.getProxySection = function () {
return {
id: model.proxyId,
name: model.proxyGroup,
ui: model.ui,
properties: getProperties()
};
}; // free resources
publicAPI.delete = function () {
var list = Object.keys(model.propertyLinkMap);
var count = list.length;
while (count--) {
model.propertyLinkMap[list[count]].unsubscribe();
}
Object.keys(model.propertyLinkSubscribers).forEach(publicAPI.gcPropertyLinks);
parentDelete();
}; // @todo fix infinite recursion due to active source
publicAPI.getState = function () {
return null;
};
function registerLinks() {
// Allow dynamic registration of links at the application level
if (model.links) {
for (var i = 0; i < model.links.length; i++) {
var _model$links$i = model.links[i],
link = _model$links$i.link,
property = _model$links$i.property,
persistent = _model$links$i.persistent,
updateOnBind = _model$links$i.updateOnBind,
type = _model$links$i.type;
if (type === 'application') {
var sLink = model.proxyManager.getPropertyLink(link, persistent);
publicAPI.registerPropertyLinkForGC(sLink, 'application');
sLink.bind(publicAPI, property, updateOnBind);
}
}
}
}
setImmediateVTK(registerLinks);
} // ----------------------------------------------------------------------------
// proxyPropertyMapping(publicAPI, model, map)
//
// map = {
// opacity: { modelKey: 'property', property: 'opacity' },
// }
//
// Generated API:
// Elevate set/get methods from internal object stored in the model to current one
// ----------------------------------------------------------------------------
function proxyPropertyMapping(publicAPI, model, map) {
var parentDelete = publicAPI.delete;
var subscriptions = [];
var propertyNames = Object.keys(map);
var count = propertyNames.length;
while (count--) {
var propertyName = propertyNames[count];
var _map$propertyName = map[propertyName],
modelKey = _map$propertyName.modelKey,
property = _map$propertyName.property,
_map$propertyName$mod = _map$propertyName.modified,
modified = _map$propertyName$mod === void 0 ? true : _map$propertyName$mod;
var methodSrc = _capitalize(property);
var methodDst = _capitalize(propertyName);
publicAPI["get".concat(methodDst)] = model[modelKey]["get".concat(methodSrc)];
publicAPI["set".concat(methodDst)] = model[modelKey]["set".concat(methodSrc)];
if (modified) {
subscriptions.push(model[modelKey].onModified(publicAPI.modified));
}
}
publicAPI.delete = function () {
while (subscriptions.length) {
subscriptions.pop().unsubscribe();
}
parentDelete();
};
} // ----------------------------------------------------------------------------
// proxyPropertyState(publicAPI, model, state, defaults)
//
// state = {
// representation: {
// 'Surface with edges': { property: { edgeVisibility: true, representation: 2 } },
// Surface: { property: { edgeVisibility: false, representation: 2 } },
// Wireframe: { property: { edgeVisibility: false, representation: 1 } },
// Points: { pr