@kitware/vtk.js
Version:
Visualization Toolkit for the Web
177 lines (155 loc) • 6.08 kB
JavaScript
import { n as newInstance$1, o as obj, g as get, e as setGet, f as event } from '../../macros2.js';
import DataAccessHelper from '../Core/DataAccessHelper.js';
import vtkTexture from '../../Rendering/Core/Texture.js';
import '../Core/DataAccessHelper/LiteHttpDataAccessHelper.js';
// import 'vtk.js/Sources/IO/Core/DataAccessHelper/HttpDataAccessHelper'; // HTTP + gz
// import 'vtk.js/Sources/IO/Core/DataAccessHelper/HtmlDataAccessHelper'; // html + base64 + zip
// import 'vtk.js/Sources/IO/Core/DataAccessHelper/JSZipDataAccessHelper'; // zip
// ----------------------------------------------------------------------------
// vtkMTLReader methods
// ----------------------------------------------------------------------------
function vtkMTLReader(publicAPI, model) {
// Set our className
model.classHierarchy.push('vtkMTLReader');
function imageReady() {
model.requestCount--;
if (model.requestCount === 0) {
publicAPI.invokeBusy(false);
}
}
function parseLine(line) {
if (line[0] === '#' || line.length === 0) {
return;
}
const tokens = line.split(/[ \t]+/).map(s => s.trim()).filter(s => s.length);
if (tokens[0] === 'newmtl') {
tokens.shift();
model.currentMaterial = tokens.join(' ').trim();
} else if (model.currentMaterial) {
if (tokens.length < 2) {
return;
}
if (!model.materials[model.currentMaterial]) {
model.materials[model.currentMaterial] = {};
}
model.materials[model.currentMaterial][tokens[0]] = tokens.slice(1);
if (tokens[0] === 'map_Kd') {
const image = new Image();
image.onload = () => setTimeout(imageReady, 0);
image.src = [model.baseURL, tokens[1]].join('/');
model.materials[model.currentMaterial].image = image;
model.requestCount++;
}
}
}
// Create default dataAccessHelper if not available
if (!model.dataAccessHelper) {
model.dataAccessHelper = DataAccessHelper.get('http');
}
// Internal method to fetch Array
function fetchData(url, options) {
return model.dataAccessHelper.fetchText(publicAPI, url, options);
}
// Set DataSet url
publicAPI.setUrl = function (url) {
let option = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
if (url.indexOf('.mtl') === -1 && !option.fullpath) {
model.baseURL = url;
model.url = `${url}/index.mtl`;
} else {
model.url = url;
// Remove the file in the URL
const path = url.split('/');
path.pop();
model.baseURL = path.join('/');
}
// Fetch metadata
return publicAPI.loadData(option);
};
// Fetch the actual data arrays
publicAPI.loadData = option => new Promise((resolve, reject) => {
fetchData(model.url, option).then(content => {
publicAPI.parseAsText(content);
resolve();
}, err => {
reject();
});
});
publicAPI.parseAsText = content => {
publicAPI.modified();
model.materials = {};
content.split('\n').forEach(parseLine);
};
// return Busy state
publicAPI.isBusy = () => !!model.requestCount;
publicAPI.getMaterialNames = () => Object.keys(model.materials);
publicAPI.getMaterial = name => model.materials[name];
publicAPI.listImages = () => Object.keys(model.materials).map(name => model.materials[name].map_Kd).filter(fileName => !!fileName).map(s => s[0].trim());
publicAPI.setImageSrc = (imagePath, src) => new Promise((resolve, reject) => {
const selectedName = Object.keys(model.materials).find(name => model.materials[name].map_Kd && model.materials[name].map_Kd[0].trim() === imagePath.trim());
const material = model.materials[selectedName];
if (material && material.image) {
material.image.src = src;
material.image.onload = () => setTimeout(resolve, 0);
} else {
resolve();
}
});
publicAPI.applyMaterialToActor = (name, actor) => {
const material = model.materials[name];
if (material && actor) {
const white = [1, 1, 1];
const actorProp = {
ambientColor: material.Ka ? material.Ka.map(i => Number(i)) : white,
specularColor: material.Ks ? material.Ks.map(i => Number(i)) : white,
diffuseColor: material.Kd ? material.Kd.map(i => Number(i)) : white,
opacity: material.d ? Number(material.d) : 1,
specularPower: material.Ns ? Number(material.Ns) : 1
};
const illum = Number(material.illum || 2);
['ambient', 'diffuse', 'specular'].forEach((k, idx) => {
actorProp[k] = idx <= illum ? 1.0 : 0.0;
});
if (material.image) {
const texture = vtkTexture.newInstance({
interpolate: model.interpolateTextures
});
texture.setImage(material.image);
actor.addTexture(texture);
}
actor.getProperty().set(actorProp);
}
};
}
// ----------------------------------------------------------------------------
// Object factory
// ----------------------------------------------------------------------------
const DEFAULT_VALUES = {
numberOfOutputs: 1,
requestCount: 0,
materials: {},
interpolateTextures: true
// baseURL: null,
// dataAccessHelper: null,
// url: null,
};
// ----------------------------------------------------------------------------
function extend(publicAPI, model) {
let initialValues = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
Object.assign(model, DEFAULT_VALUES, initialValues);
// Build VTK API
obj(publicAPI, model);
get(publicAPI, model, ['url', 'baseURL']);
setGet(publicAPI, model, ['dataAccessHelper', 'interpolateTextures', 'splitGroup']);
event(publicAPI, model, 'busy');
// Object methods
vtkMTLReader(publicAPI, model);
}
// ----------------------------------------------------------------------------
const newInstance = newInstance$1(extend, 'vtkMTLReader');
// ----------------------------------------------------------------------------
var vtkMTLReader$1 = {
newInstance,
extend
};
export { vtkMTLReader$1 as default, extend, newInstance };