bytev-charts
Version:
基于echarts和JavaScript及ES6封装的一个可以直接调用的图表组件库,内置主题设计,简单快捷,且支持用户自定义配置; npm 安装方式: npm install bytev-charts 若启动提示还需额外install插件,则运行 npm install @babel/runtime-corejs2 即可;
916 lines (735 loc) • 32.7 kB
JavaScript
import "core-js/modules/es.regexp.exec.js";
import "core-js/modules/es.string.split.js";
import "core-js/modules/es.string.trim.js";
import "core-js/modules/es.array.index-of.js";
import "core-js/modules/es.array.iterator.js";
import "core-js/modules/es.array-buffer.slice.js";
import "core-js/modules/es.object.to-string.js";
import "core-js/modules/es.typed-array.uint8-array.js";
import "core-js/modules/es.typed-array.copy-within.js";
import "core-js/modules/es.typed-array.every.js";
import "core-js/modules/es.typed-array.fill.js";
import "core-js/modules/es.typed-array.filter.js";
import "core-js/modules/es.typed-array.find.js";
import "core-js/modules/es.typed-array.find-index.js";
import "core-js/modules/es.typed-array.for-each.js";
import "core-js/modules/es.typed-array.includes.js";
import "core-js/modules/es.typed-array.index-of.js";
import "core-js/modules/es.typed-array.iterator.js";
import "core-js/modules/es.typed-array.join.js";
import "core-js/modules/es.typed-array.last-index-of.js";
import "core-js/modules/es.typed-array.map.js";
import "core-js/modules/es.typed-array.reduce.js";
import "core-js/modules/es.typed-array.reduce-right.js";
import "core-js/modules/es.typed-array.reverse.js";
import "core-js/modules/es.typed-array.set.js";
import "core-js/modules/es.typed-array.slice.js";
import "core-js/modules/es.typed-array.some.js";
import "core-js/modules/es.typed-array.sort.js";
import "core-js/modules/es.typed-array.subarray.js";
import "core-js/modules/es.typed-array.to-locale-string.js";
import "core-js/modules/es.typed-array.to-string.js";
import "core-js/modules/es.data-view.js";
import "core-js/modules/es.array.join.js";
import "core-js/modules/es.typed-array.float32-array.js";
import "core-js/modules/es.typed-array.uint32-array.js";
import "core-js/modules/es.typed-array.int32-array.js";
import "core-js/modules/es.array.slice.js";
import "core-js/modules/es.array.filter.js";
import "core-js/modules/es.array.includes.js";
import "core-js/modules/es.string.includes.js";
import _Object$assign from "@babel/runtime-corejs2/core-js/object/assign";
import _Object$create from "@babel/runtime-corejs2/core-js/object/create";
import _parseFloat from "@babel/runtime-corejs2/core-js/parse-float";
import _parseInt from "@babel/runtime-corejs2/core-js/parse-int";
console.warn("THREE.VTKLoader: As part of the transition to ES6 Modules, the files in 'examples/js' were deprecated in May 2020 (r117) and will be deleted in December 2020 (r124). You can find more information about developing using ES6 Modules in https://threejs.org/docs/#manual/en/introduction/Installation.");
THREE.VTKLoader = function (manager) {
THREE.Loader.call(this, manager);
};
THREE.VTKLoader.prototype = _Object$assign(_Object$create(THREE.Loader.prototype), {
constructor: THREE.VTKLoader,
load: function load(url, onLoad, onProgress, onError) {
var scope = this;
var loader = new THREE.FileLoader(scope.manager);
loader.setPath(scope.path);
loader.setResponseType('arraybuffer');
loader.setRequestHeader(scope.requestHeader);
loader.load(url, function (text) {
try {
onLoad(scope.parse(text));
} catch (e) {
if (onError) {
onError(e);
} else {
console.error(e);
}
scope.manager.itemError(url);
}
}, onProgress, onError);
},
parse: function parse(data) {
function parseASCII(data) {
// connectivity of the triangles
var indices = []; // triangles vertices
var positions = []; // red, green, blue colors in the range 0 to 1
var colors = []; // normal vector, one per vertex
var normals = [];
var result; // pattern for detecting the end of a number sequence
var patWord = /^[^\d.\s-]+/; // pattern for reading vertices, 3 floats or integers
var pat3Floats = /(\-?\d+\.?[\d\-\+e]*)\s+(\-?\d+\.?[\d\-\+e]*)\s+(\-?\d+\.?[\d\-\+e]*)/g; // pattern for connectivity, an integer followed by any number of ints
// the first integer is the number of polygon nodes
var patConnectivity = /^(\d+)\s+([\s\d]*)/; // indicates start of vertex data section
var patPOINTS = /^POINTS /; // indicates start of polygon connectivity section
var patPOLYGONS = /^POLYGONS /; // indicates start of triangle strips section
var patTRIANGLE_STRIPS = /^TRIANGLE_STRIPS /; // POINT_DATA number_of_values
var patPOINT_DATA = /^POINT_DATA[ ]+(\d+)/; // CELL_DATA number_of_polys
var patCELL_DATA = /^CELL_DATA[ ]+(\d+)/; // Start of color section
var patCOLOR_SCALARS = /^COLOR_SCALARS[ ]+(\w+)[ ]+3/; // NORMALS Normals float
var patNORMALS = /^NORMALS[ ]+(\w+)[ ]+(\w+)/;
var inPointsSection = false;
var inPolygonsSection = false;
var inTriangleStripSection = false;
var inPointDataSection = false;
var inCellDataSection = false;
var inColorSection = false;
var inNormalsSection = false;
var lines = data.split('\n');
for (var i in lines) {
var line = lines[i].trim();
if (line.indexOf('DATASET') === 0) {
var dataset = line.split(' ')[1];
if (dataset !== 'POLYDATA') throw new Error('Unsupported DATASET type: ' + dataset);
} else if (inPointsSection) {
// get the vertices
while ((result = pat3Floats.exec(line)) !== null) {
if (patWord.exec(line) !== null) break;
var x = _parseFloat(result[1]);
var y = _parseFloat(result[2]);
var z = _parseFloat(result[3]);
positions.push(x, y, z);
}
} else if (inPolygonsSection) {
if ((result = patConnectivity.exec(line)) !== null) {
// numVertices i0 i1 i2 ...
var numVertices = _parseInt(result[1]);
var inds = result[2].split(/\s+/);
if (numVertices >= 3) {
var i0 = _parseInt(inds[0]);
var i1, i2;
var k = 1; // split the polygon in numVertices - 2 triangles
for (var j = 0; j < numVertices - 2; ++j) {
i1 = _parseInt(inds[k]);
i2 = _parseInt(inds[k + 1]);
indices.push(i0, i1, i2);
k++;
}
}
}
} else if (inTriangleStripSection) {
if ((result = patConnectivity.exec(line)) !== null) {
// numVertices i0 i1 i2 ...
var numVertices = _parseInt(result[1]);
var inds = result[2].split(/\s+/);
if (numVertices >= 3) {
var i0, i1, i2; // split the polygon in numVertices - 2 triangles
for (var j = 0; j < numVertices - 2; j++) {
if (j % 2 === 1) {
i0 = _parseInt(inds[j]);
i1 = _parseInt(inds[j + 2]);
i2 = _parseInt(inds[j + 1]);
indices.push(i0, i1, i2);
} else {
i0 = _parseInt(inds[j]);
i1 = _parseInt(inds[j + 1]);
i2 = _parseInt(inds[j + 2]);
indices.push(i0, i1, i2);
}
}
}
}
} else if (inPointDataSection || inCellDataSection) {
if (inColorSection) {
// Get the colors
while ((result = pat3Floats.exec(line)) !== null) {
if (patWord.exec(line) !== null) break;
var r = _parseFloat(result[1]);
var g = _parseFloat(result[2]);
var b = _parseFloat(result[3]);
colors.push(r, g, b);
}
} else if (inNormalsSection) {
// Get the normal vectors
while ((result = pat3Floats.exec(line)) !== null) {
if (patWord.exec(line) !== null) break;
var nx = _parseFloat(result[1]);
var ny = _parseFloat(result[2]);
var nz = _parseFloat(result[3]);
normals.push(nx, ny, nz);
}
}
}
if (patPOLYGONS.exec(line) !== null) {
inPolygonsSection = true;
inPointsSection = false;
inTriangleStripSection = false;
} else if (patPOINTS.exec(line) !== null) {
inPolygonsSection = false;
inPointsSection = true;
inTriangleStripSection = false;
} else if (patTRIANGLE_STRIPS.exec(line) !== null) {
inPolygonsSection = false;
inPointsSection = false;
inTriangleStripSection = true;
} else if (patPOINT_DATA.exec(line) !== null) {
inPointDataSection = true;
inPointsSection = false;
inPolygonsSection = false;
inTriangleStripSection = false;
} else if (patCELL_DATA.exec(line) !== null) {
inCellDataSection = true;
inPointsSection = false;
inPolygonsSection = false;
inTriangleStripSection = false;
} else if (patCOLOR_SCALARS.exec(line) !== null) {
inColorSection = true;
inNormalsSection = false;
inPointsSection = false;
inPolygonsSection = false;
inTriangleStripSection = false;
} else if (patNORMALS.exec(line) !== null) {
inNormalsSection = true;
inColorSection = false;
inPointsSection = false;
inPolygonsSection = false;
inTriangleStripSection = false;
}
}
var geometry = new THREE.BufferGeometry();
geometry.setIndex(indices);
geometry.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3));
if (normals.length === positions.length) {
geometry.setAttribute('normal', new THREE.Float32BufferAttribute(normals, 3));
}
if (colors.length !== indices.length) {
// stagger
if (colors.length === positions.length) {
geometry.setAttribute('color', new THREE.Float32BufferAttribute(colors, 3));
}
} else {
// cell
geometry = geometry.toNonIndexed();
var numTriangles = geometry.attributes.position.count / 3;
if (colors.length === numTriangles * 3) {
var newColors = [];
for (var i = 0; i < numTriangles; i++) {
var r = colors[3 * i + 0];
var g = colors[3 * i + 1];
var b = colors[3 * i + 2];
newColors.push(r, g, b);
newColors.push(r, g, b);
newColors.push(r, g, b);
}
geometry.setAttribute('color', new THREE.Float32BufferAttribute(newColors, 3));
}
}
return geometry;
}
function parseBinary(data) {
var count, pointIndex, i, numberOfPoints, s;
var buffer = new Uint8Array(data);
var dataView = new DataView(data); // Points and normals, by default, are empty
var points = [];
var normals = [];
var indices = []; // Going to make a big array of strings
var vtk = [];
var index = 0;
function findString(buffer, start) {
var index = start;
var c = buffer[index];
var s = [];
while (c !== 10) {
s.push(String.fromCharCode(c));
index++;
c = buffer[index];
}
return {
start: start,
end: index,
next: index + 1,
parsedString: s.join('')
};
}
var state, line;
while (true) {
// Get a string
state = findString(buffer, index);
line = state.parsedString;
if (line.indexOf('DATASET') === 0) {
var dataset = line.split(' ')[1];
if (dataset !== 'POLYDATA') throw new Error('Unsupported DATASET type: ' + dataset);
} else if (line.indexOf('POINTS') === 0) {
vtk.push(line); // Add the points
numberOfPoints = _parseInt(line.split(' ')[1], 10); // Each point is 3 4-byte floats
count = numberOfPoints * 4 * 3;
points = new Float32Array(numberOfPoints * 3);
pointIndex = state.next;
for (i = 0; i < numberOfPoints; i++) {
points[3 * i] = dataView.getFloat32(pointIndex, false);
points[3 * i + 1] = dataView.getFloat32(pointIndex + 4, false);
points[3 * i + 2] = dataView.getFloat32(pointIndex + 8, false);
pointIndex = pointIndex + 12;
} // increment our next pointer
state.next = state.next + count + 1;
} else if (line.indexOf('TRIANGLE_STRIPS') === 0) {
var numberOfStrips = _parseInt(line.split(' ')[1], 10);
var size = _parseInt(line.split(' ')[2], 10); // 4 byte integers
count = size * 4;
indices = new Uint32Array(3 * size - 9 * numberOfStrips);
var indicesIndex = 0;
pointIndex = state.next;
for (i = 0; i < numberOfStrips; i++) {
// For each strip, read the first value, then record that many more points
var indexCount = dataView.getInt32(pointIndex, false);
var strip = [];
pointIndex += 4;
for (s = 0; s < indexCount; s++) {
strip.push(dataView.getInt32(pointIndex, false));
pointIndex += 4;
} // retrieves the n-2 triangles from the triangle strip
for (var j = 0; j < indexCount - 2; j++) {
if (j % 2) {
indices[indicesIndex++] = strip[j];
indices[indicesIndex++] = strip[j + 2];
indices[indicesIndex++] = strip[j + 1];
} else {
indices[indicesIndex++] = strip[j];
indices[indicesIndex++] = strip[j + 1];
indices[indicesIndex++] = strip[j + 2];
}
}
} // increment our next pointer
state.next = state.next + count + 1;
} else if (line.indexOf('POLYGONS') === 0) {
var numberOfStrips = _parseInt(line.split(' ')[1], 10);
var size = _parseInt(line.split(' ')[2], 10); // 4 byte integers
count = size * 4;
indices = new Uint32Array(3 * size - 9 * numberOfStrips);
var indicesIndex = 0;
pointIndex = state.next;
for (i = 0; i < numberOfStrips; i++) {
// For each strip, read the first value, then record that many more points
var indexCount = dataView.getInt32(pointIndex, false);
var strip = [];
pointIndex += 4;
for (s = 0; s < indexCount; s++) {
strip.push(dataView.getInt32(pointIndex, false));
pointIndex += 4;
} // divide the polygon in n-2 triangle
for (var j = 1; j < indexCount - 1; j++) {
indices[indicesIndex++] = strip[0];
indices[indicesIndex++] = strip[j];
indices[indicesIndex++] = strip[j + 1];
}
} // increment our next pointer
state.next = state.next + count + 1;
} else if (line.indexOf('POINT_DATA') === 0) {
numberOfPoints = _parseInt(line.split(' ')[1], 10); // Grab the next line
state = findString(buffer, state.next); // Now grab the binary data
count = numberOfPoints * 4 * 3;
normals = new Float32Array(numberOfPoints * 3);
pointIndex = state.next;
for (i = 0; i < numberOfPoints; i++) {
normals[3 * i] = dataView.getFloat32(pointIndex, false);
normals[3 * i + 1] = dataView.getFloat32(pointIndex + 4, false);
normals[3 * i + 2] = dataView.getFloat32(pointIndex + 8, false);
pointIndex += 12;
} // Increment past our data
state.next = state.next + count;
} // Increment index
index = state.next;
if (index >= buffer.byteLength) {
break;
}
}
var geometry = new THREE.BufferGeometry();
geometry.setIndex(new THREE.BufferAttribute(indices, 1));
geometry.setAttribute('position', new THREE.BufferAttribute(points, 3));
if (normals.length === points.length) {
geometry.setAttribute('normal', new THREE.BufferAttribute(normals, 3));
}
return geometry;
}
function Float32Concat(first, second) {
var firstLength = first.length,
result = new Float32Array(firstLength + second.length);
result.set(first);
result.set(second, firstLength);
return result;
}
function Int32Concat(first, second) {
var firstLength = first.length,
result = new Int32Array(firstLength + second.length);
result.set(first);
result.set(second, firstLength);
return result;
}
function parseXML(stringFile) {
// Changes XML to JSON, based on https://davidwalsh.name/convert-xml-json
function xmlToJson(xml) {
// Create the return object
var obj = {};
if (xml.nodeType === 1) {
// element
// do attributes
if (xml.attributes) {
if (xml.attributes.length > 0) {
obj['attributes'] = {};
for (var j = 0; j < xml.attributes.length; j++) {
var attribute = xml.attributes.item(j);
obj['attributes'][attribute.nodeName] = attribute.nodeValue.trim();
}
}
}
} else if (xml.nodeType === 3) {
// text
obj = xml.nodeValue.trim();
} // do children
if (xml.hasChildNodes()) {
for (var i = 0; i < xml.childNodes.length; i++) {
var item = xml.childNodes.item(i);
var nodeName = item.nodeName;
if (typeof obj[nodeName] === 'undefined') {
var tmp = xmlToJson(item);
if (tmp !== '') obj[nodeName] = tmp;
} else {
if (typeof obj[nodeName].push === 'undefined') {
var old = obj[nodeName];
obj[nodeName] = [old];
}
var tmp = xmlToJson(item);
if (tmp !== '') obj[nodeName].push(tmp);
}
}
}
return obj;
} // Taken from Base64-js
function Base64toByteArray(b64) {
var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array;
var i;
var lookup = [];
var revLookup = [];
var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
var len = code.length;
for (i = 0; i < len; i++) {
lookup[i] = code[i];
}
for (i = 0; i < len; ++i) {
revLookup[code.charCodeAt(i)] = i;
}
revLookup['-'.charCodeAt(0)] = 62;
revLookup['_'.charCodeAt(0)] = 63;
var j, l, tmp, placeHolders, arr;
var len = b64.length;
if (len % 4 > 0) {
throw new Error('Invalid string. Length must be a multiple of 4');
}
placeHolders = b64[len - 2] === '=' ? 2 : b64[len - 1] === '=' ? 1 : 0;
arr = new Arr(len * 3 / 4 - placeHolders);
l = placeHolders > 0 ? len - 4 : len;
var L = 0;
for (i = 0, j = 0; i < l; i += 4, j += 3) {
tmp = revLookup[b64.charCodeAt(i)] << 18 | revLookup[b64.charCodeAt(i + 1)] << 12 | revLookup[b64.charCodeAt(i + 2)] << 6 | revLookup[b64.charCodeAt(i + 3)];
arr[L++] = (tmp & 0xFF0000) >> 16;
arr[L++] = (tmp & 0xFF00) >> 8;
arr[L++] = tmp & 0xFF;
}
if (placeHolders === 2) {
tmp = revLookup[b64.charCodeAt(i)] << 2 | revLookup[b64.charCodeAt(i + 1)] >> 4;
arr[L++] = tmp & 0xFF;
} else if (placeHolders === 1) {
tmp = revLookup[b64.charCodeAt(i)] << 10 | revLookup[b64.charCodeAt(i + 1)] << 4 | revLookup[b64.charCodeAt(i + 2)] >> 2;
arr[L++] = tmp >> 8 & 0xFF;
arr[L++] = tmp & 0xFF;
}
return arr;
}
function parseDataArray(ele, compressed) {
var numBytes = 0;
if (json.attributes.header_type === 'UInt64') {
numBytes = 8;
} else if (json.attributes.header_type === 'UInt32') {
numBytes = 4;
} // Check the format
if (ele.attributes.format === 'binary' && compressed) {
var rawData, content, byteData, blocks, cSizeStart, headerSize, padding, dataOffsets, currentOffset;
if (ele.attributes.type === 'Float32') {
var txt = new Float32Array();
} else if (ele.attributes.type === 'Int64') {
var txt = new Int32Array();
} // VTP data with the header has the following structure:
// [#blocks][#u-size][#p-size][#c-size-1][#c-size-2]...[#c-size-#blocks][DATA]
//
// Each token is an integer value whose type is specified by "header_type" at the top of the file (UInt32 if no type specified). The token meanings are:
// [#blocks] = Number of blocks
// [#u-size] = Block size before compression
// [#p-size] = Size of last partial block (zero if it not needed)
// [#c-size-i] = Size in bytes of block i after compression
//
// The [DATA] portion stores contiguously every block appended together. The offset from the beginning of the data section to the beginning of a block is
// computed by summing the compressed block sizes from preceding blocks according to the header.
rawData = ele['#text'];
byteData = Base64toByteArray(rawData);
blocks = byteData[0];
for (var i = 1; i < numBytes - 1; i++) {
blocks = blocks | byteData[i] << i * numBytes;
}
headerSize = (blocks + 3) * numBytes;
padding = headerSize % 3 > 0 ? 3 - headerSize % 3 : 0;
headerSize = headerSize + padding;
dataOffsets = [];
currentOffset = headerSize;
dataOffsets.push(currentOffset); // Get the blocks sizes after the compression.
// There are three blocks before c-size-i, so we skip 3*numBytes
cSizeStart = 3 * numBytes;
for (var i = 0; i < blocks; i++) {
var currentBlockSize = byteData[i * numBytes + cSizeStart];
for (var j = 1; j < numBytes - 1; j++) {
// Each data point consists of 8 bytes regardless of the header type
currentBlockSize = currentBlockSize | byteData[i * numBytes + cSizeStart + j] << j * 8;
}
currentOffset = currentOffset + currentBlockSize;
dataOffsets.push(currentOffset);
}
for (var i = 0; i < dataOffsets.length - 1; i++) {
var inflate = new Inflate(byteData.slice(dataOffsets[i], dataOffsets[i + 1]), {
resize: true,
verify: true
}); // eslint-disable-line no-undef
content = inflate.decompress();
content = content.buffer;
if (ele.attributes.type === 'Float32') {
content = new Float32Array(content);
txt = Float32Concat(txt, content);
} else if (ele.attributes.type === 'Int64') {
content = new Int32Array(content);
txt = Int32Concat(txt, content);
}
}
delete ele['#text'];
if (ele.attributes.type === 'Int64') {
if (ele.attributes.format === 'binary') {
txt = txt.filter(function (el, idx) {
if (idx % 2 !== 1) return true;
});
}
}
} else {
if (ele.attributes.format === 'binary' && !compressed) {
var content = Base64toByteArray(ele['#text']); // VTP data for the uncompressed case has the following structure:
// [#bytes][DATA]
// where "[#bytes]" is an integer value specifying the number of bytes in the block of data following it.
content = content.slice(numBytes).buffer;
} else {
if (ele['#text']) {
var content = ele['#text'].split(/\s+/).filter(function (el) {
if (el !== '') return el;
});
} else {
var content = new Int32Array(0).buffer;
}
}
delete ele['#text']; // Get the content and optimize it
if (ele.attributes.type === 'Float32') {
var txt = new Float32Array(content);
} else if (ele.attributes.type === 'Int32') {
var txt = new Int32Array(content);
} else if (ele.attributes.type === 'Int64') {
var txt = new Int32Array(content);
if (ele.attributes.format === 'binary') {
txt = txt.filter(function (el, idx) {
if (idx % 2 !== 1) return true;
});
}
}
} // endif ( ele.attributes.format === 'binary' && compressed )
return txt;
} // Main part
// Get Dom
var dom = null;
if (window.DOMParser) {
try {
dom = new DOMParser().parseFromString(stringFile, 'text/xml');
} catch (e) {
dom = null;
}
} else if (window.ActiveXObject) {
try {
dom = new ActiveXObject('Microsoft.XMLDOM'); // eslint-disable-line no-undef
dom.async = false;
if (!dom.loadXML()) {
throw new Error(dom.parseError.reason + dom.parseError.srcText);
}
} catch (e) {
dom = null;
}
} else {
throw new Error('Cannot parse xml string!');
} // Get the doc
var doc = dom.documentElement; // Convert to json
var json = xmlToJson(doc);
var points = [];
var normals = [];
var indices = [];
if (json.PolyData) {
var piece = json.PolyData.Piece;
var compressed = json.attributes.hasOwnProperty('compressor'); // Can be optimized
// Loop through the sections
var sections = ['PointData', 'Points', 'Strips', 'Polys']; // +['CellData', 'Verts', 'Lines'];
var sectionIndex = 0,
numberOfSections = sections.length;
while (sectionIndex < numberOfSections) {
var section = piece[sections[sectionIndex]]; // If it has a DataArray in it
if (section && section.DataArray) {
// Depending on the number of DataArrays
if (Object.prototype.toString.call(section.DataArray) === '[object Array]') {
var arr = section.DataArray;
} else {
var arr = [section.DataArray];
}
var dataArrayIndex = 0,
numberOfDataArrays = arr.length;
while (dataArrayIndex < numberOfDataArrays) {
// Parse the DataArray
if ('#text' in arr[dataArrayIndex] && arr[dataArrayIndex]['#text'].length > 0) {
arr[dataArrayIndex].text = parseDataArray(arr[dataArrayIndex], compressed);
}
dataArrayIndex++;
}
switch (sections[sectionIndex]) {
// if iti is point data
case 'PointData':
var numberOfPoints = _parseInt(piece.attributes.NumberOfPoints);
var normalsName = section.attributes.Normals;
if (numberOfPoints > 0) {
for (var i = 0, len = arr.length; i < len; i++) {
if (normalsName === arr[i].attributes.Name) {
var components = arr[i].attributes.NumberOfComponents;
normals = new Float32Array(numberOfPoints * components);
normals.set(arr[i].text, 0);
}
}
}
break;
// if it is points
case 'Points':
var numberOfPoints = _parseInt(piece.attributes.NumberOfPoints);
if (numberOfPoints > 0) {
var components = section.DataArray.attributes.NumberOfComponents;
points = new Float32Array(numberOfPoints * components);
points.set(section.DataArray.text, 0);
}
break;
// if it is strips
case 'Strips':
var numberOfStrips = _parseInt(piece.attributes.NumberOfStrips);
if (numberOfStrips > 0) {
var connectivity = new Int32Array(section.DataArray[0].text.length);
var offset = new Int32Array(section.DataArray[1].text.length);
connectivity.set(section.DataArray[0].text, 0);
offset.set(section.DataArray[1].text, 0);
var size = numberOfStrips + connectivity.length;
indices = new Uint32Array(3 * size - 9 * numberOfStrips);
var indicesIndex = 0;
for (var i = 0, len = numberOfStrips; i < len; i++) {
var strip = [];
for (var s = 0, len1 = offset[i], len0 = 0; s < len1 - len0; s++) {
strip.push(connectivity[s]);
if (i > 0) len0 = offset[i - 1];
}
for (var j = 0, len1 = offset[i], len0 = 0; j < len1 - len0 - 2; j++) {
if (j % 2) {
indices[indicesIndex++] = strip[j];
indices[indicesIndex++] = strip[j + 2];
indices[indicesIndex++] = strip[j + 1];
} else {
indices[indicesIndex++] = strip[j];
indices[indicesIndex++] = strip[j + 1];
indices[indicesIndex++] = strip[j + 2];
}
if (i > 0) len0 = offset[i - 1];
}
}
}
break;
// if it is polys
case 'Polys':
var numberOfPolys = _parseInt(piece.attributes.NumberOfPolys);
if (numberOfPolys > 0) {
var connectivity = new Int32Array(section.DataArray[0].text.length);
var offset = new Int32Array(section.DataArray[1].text.length);
connectivity.set(section.DataArray[0].text, 0);
offset.set(section.DataArray[1].text, 0);
var size = numberOfPolys + connectivity.length;
indices = new Uint32Array(3 * size - 9 * numberOfPolys);
var indicesIndex = 0,
connectivityIndex = 0;
var i = 0,
len = numberOfPolys,
len0 = 0;
while (i < len) {
var poly = [];
var s = 0,
len1 = offset[i];
while (s < len1 - len0) {
poly.push(connectivity[connectivityIndex++]);
s++;
}
var j = 1;
while (j < len1 - len0 - 1) {
indices[indicesIndex++] = poly[0];
indices[indicesIndex++] = poly[j];
indices[indicesIndex++] = poly[j + 1];
j++;
}
i++;
len0 = offset[i - 1];
}
}
break;
default:
break;
}
}
sectionIndex++;
}
var geometry = new THREE.BufferGeometry();
geometry.setIndex(new THREE.BufferAttribute(indices, 1));
geometry.setAttribute('position', new THREE.BufferAttribute(points, 3));
if (normals.length === points.length) {
geometry.setAttribute('normal', new THREE.BufferAttribute(normals, 3));
}
return geometry;
} else {
throw new Error('Unsupported DATASET type');
}
}
function getStringFile(data) {
var stringFile = '';
var charArray = new Uint8Array(data);
var i = 0;
var len = charArray.length;
while (len--) {
stringFile += String.fromCharCode(charArray[i++]);
}
return stringFile;
} // get the 5 first lines of the files to check if there is the key word binary
var meta = THREE.LoaderUtils.decodeText(new Uint8Array(data, 0, 250)).split('\n');
if (meta[0].indexOf('xml') !== -1) {
return parseXML(getStringFile(data));
} else if (meta[2].includes('ASCII')) {
return parseASCII(getStringFile(data));
} else {
return parseBinary(data);
}
}
});