UNPKG

@thewtex/vtk.js-esm

Version:

Visualization Toolkit for the Web

306 lines (255 loc) 10.4 kB
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 };