@thewtex/vtk.js-esm
Version:
Visualization Toolkit for the Web
306 lines (255 loc) • 10.4 kB
JavaScript
import '../../Common/DataModel/ImageData.js';
import '../../Common/DataModel/PolyData.js';
import vtk from '../../vtk.js';
import macro from '../../macro.js';
import DataAccessHelper from './DataAccessHelper.js';
import vtkDataArray from '../../Common/Core/DataArray.js';
import vtkStringArray from '../../Common/Core/StringArray.js';
import './DataAccessHelper/LiteHttpDataAccessHelper.js';
// For vtk factory
// import 'vtk.js/Sources/IO/Core/DataAccessHelper/HttpDataAccessHelper'; // HTTP + zip
// import 'vtk.js/Sources/IO/Core/DataAccessHelper/HtmlDataAccessHelper'; // html + base64 + zip
// import 'vtk.js/Sources/IO/Core/DataAccessHelper/JSZipDataAccessHelper'; // zip
var fieldDataLocations = ['pointData', 'cellData', 'fieldData'];
var ARRAY_BUILDERS = {
vtkDataArray: vtkDataArray,
vtkStringArray: vtkStringArray
}; // ----------------------------------------------------------------------------
// Global methods
// ----------------------------------------------------------------------------
var cachedArrays = {};
var GEOMETRY_ARRAYS = {
vtkPolyData: function vtkPolyData(dataset) {
var arrayToDownload = [];
arrayToDownload.push(dataset.points);
['verts', 'lines', 'polys', 'strips'].forEach(function (cellName) {
if (dataset[cellName]) {
arrayToDownload.push(dataset[cellName]);
}
});
return arrayToDownload;
},
vtkImageData: function vtkImageData(dataset) {
return [];
},
vtkUnstructuredGrid: function vtkUnstructuredGrid(dataset) {
var arrayToDownload = [];
arrayToDownload.push(dataset.points);
arrayToDownload.push(dataset.cells);
arrayToDownload.push(dataset.cellTypes);
return arrayToDownload;
},
vtkRectilinearGrid: function vtkRectilinearGrid(dataset) {
var arrayToDownload = [];
arrayToDownload.push(dataset.xCoordinates);
arrayToDownload.push(dataset.yCoordinates);
arrayToDownload.push(dataset.zCoordinates);
return arrayToDownload;
}
};
function processDataSet(publicAPI, model, dataset, fetchArray, resolve, reject, loadData) {
var enable = model.enableArray; // Generate array list
model.arrays = [];
fieldDataLocations.forEach(function (location) {
if (dataset[location]) {
dataset[location].arrays.map(function (i) {
return i.data;
}).forEach(function (array) {
model.arrays.push({
name: array.name,
enable: enable,
location: location,
array: array,
registration: array.ref.registration || 'addArray'
});
}); // Reset data arrays
dataset[location].arrays = [];
}
}); // Fetch geometry arrays
var pendingPromises = [];
var progressCallback = model.progressCallback;
var compression = model.fetchGzip ? 'gz' : null;
GEOMETRY_ARRAYS[dataset.vtkClass](dataset).forEach(function (array) {
pendingPromises.push(fetchArray(array, {
compression: compression,
progressCallback: progressCallback
}));
});
function success() {
model.dataset = vtk(dataset);
if (!loadData) {
model.output[0] = model.dataset;
resolve(publicAPI, model.output[0]);
} else {
publicAPI.loadData().then(function () {
model.output[0] = model.dataset;
resolve(publicAPI, model.output[0]);
});
}
} // Wait for all geometry array to be fetched
if (pendingPromises.length) {
Promise.all(pendingPromises).then(success, function (err) {
reject(err);
});
} else {
success();
}
} // ----------------------------------------------------------------------------
// vtkHttpDataSetReader methods
// ----------------------------------------------------------------------------
function vtkHttpDataSetReader(publicAPI, model) {
// Set our className
model.classHierarchy.push('vtkHttpDataSetReader'); // Empty output by default
model.output[0] = vtk({
vtkClass: 'vtkPolyData'
}); // Create default dataAccessHelper if not available
if (!model.dataAccessHelper) {
model.dataAccessHelper = DataAccessHelper.get('http');
} // Internal method to fetch Array
function fetchArray(array) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var arrayId = "".concat(array.ref.id, "|").concat(array.vtkClass);
if (!cachedArrays[arrayId]) {
// Cache the promise while fetching
cachedArrays[arrayId] = model.dataAccessHelper.fetchArray(publicAPI, model.baseURL, array, options).then(function (newArray) {
// Replace the promise with the array in cache once downloaded
cachedArrays[arrayId] = newArray;
return newArray;
});
} else {
// cacheArrays[arrayId] can be a promise or value
Promise.resolve(cachedArrays[arrayId]).then(function (cachedArray) {
if (array !== cachedArray) {
Object.assign(array, cachedArray);
delete array.ref;
}
});
}
return Promise.resolve(cachedArrays[arrayId]);
} // Fetch dataset (metadata)
publicAPI.updateMetadata = function () {
var loadData = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
if (model.compression === 'zip') {
return new Promise(function (resolve, reject) {
DataAccessHelper.get('http').fetchBinary(model.url).then(function (zipContent) {
model.dataAccessHelper = DataAccessHelper.get('zip', {
zipContent: zipContent,
callback: function callback(zip) {
model.baseURL = '';
model.dataAccessHelper.fetchJSON(publicAPI, 'index.json').then(function (dataset) {
processDataSet(publicAPI, model, dataset, fetchArray, resolve, reject, loadData);
}, function (error) {
reject(error);
});
}
});
}, function (error) {
reject(error);
});
});
}
return new Promise(function (resolve, reject) {
model.dataAccessHelper.fetchJSON(publicAPI, model.url).then(function (dataset) {
processDataSet(publicAPI, model, dataset, fetchArray, resolve, reject, loadData);
}, function (error) {
reject(error);
});
});
}; // Set DataSet url
publicAPI.setUrl = function (url) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
if (url.indexOf('index.json') === -1 && !options.fullpath) {
model.baseURL = url;
model.url = "".concat(url, "/index.json");
} else {
model.url = url; // Remove the file in the URL
var path = url.split('/');
path.pop();
model.baseURL = path.join('/');
}
model.compression = options.compression; // Fetch metadata
return publicAPI.updateMetadata(!!options.loadData);
}; // Fetch the actual data arrays
publicAPI.loadData = function () {
var datasetObj = model.dataset;
var arrayToFecth = model.arrays.filter(function (array) {
return array.enable;
}).filter(function (array) {
return array.array.ref;
}).map(function (array) {
return array.array;
});
return new Promise(function (resolve, reject) {
var error = function error(e) {
reject(e);
};
var processNext = function processNext() {
if (arrayToFecth.length) {
var progressCallback = model.progressCallback;
var compression = model.fetchGzip ? 'gz' : null;
fetchArray(arrayToFecth.pop(), {
compression: compression,
progressCallback: progressCallback
}).then(processNext, error);
} else if (datasetObj) {
// Perform array registration on new arrays
model.arrays.filter(function (metaArray) {
return metaArray.registration && !metaArray.array.ref;
}).forEach(function (metaArray) {
var newArray = ARRAY_BUILDERS[metaArray.array.vtkClass].newInstance(metaArray.array);
datasetObj["get".concat(macro.capitalize(metaArray.location))]()[metaArray.registration](newArray);
delete metaArray.registration;
});
datasetObj.modified();
resolve(publicAPI, datasetObj);
}
}; // Start processing queue
processNext();
});
};
publicAPI.requestData = function (inData, outData) {// do nothing loadData will eventually load up the data
}; // Toggle arrays to load
publicAPI.enableArray = function (location, name) {
var enable = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
var activeArray = model.arrays.filter(function (array) {
return array.name === name && array.location === location;
});
if (activeArray.length === 1) {
activeArray[0].enable = enable;
}
}; // return Busy state
publicAPI.isBusy = function () {
return !!model.requestCount;
};
} // ----------------------------------------------------------------------------
// Object factory
// ----------------------------------------------------------------------------
var DEFAULT_VALUES = {
enableArray: true,
fetchGzip: false,
arrays: [],
url: null,
baseURL: null,
requestCount: 0 // dataAccessHelper: null,
}; // ----------------------------------------------------------------------------
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.get(publicAPI, model, ['enableArray', 'fetchGzip', 'url', 'baseURL', 'dataAccessHelper']);
macro.set(publicAPI, model, ['dataAccessHelper', 'progressCallback']);
macro.getArray(publicAPI, model, ['arrays']);
macro.algo(publicAPI, model, 0, 1);
macro.event(publicAPI, model, 'busy'); // Object methods
vtkHttpDataSetReader(publicAPI, model); // Make sure we can destructuring progressCallback from model
if (model.progressCallback === undefined) {
model.progressCallback = null;
}
} // ----------------------------------------------------------------------------
var newInstance = macro.newInstance(extend, 'vtkHttpDataSetReader'); // ----------------------------------------------------------------------------
var vtkHttpDataSetReader$1 = {
newInstance: newInstance,
extend: extend
};
export default vtkHttpDataSetReader$1;
export { extend, newInstance };