stl reader and url loader

This commit is contained in:
Val Erastov 2016-11-23 19:20:33 -08:00
parent 97abd14f0e
commit 3213728337
4 changed files with 63 additions and 29 deletions

23
web/app/3d/io.js Normal file
View file

@ -0,0 +1,23 @@
import {ParseStl} from './stl/stl-reader'
export function LoadSTLFromURL(url, solidsConsumer) {
const xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if (this.readyState == 4){
//console.log(this.response, typeof this.response);
if (this.status == 200) {
const reader = new FileReader();
reader.addEventListener("loadend", () => {
let solids = ParseStl(reader.result);
solidsConsumer(solids)
});
reader.readAsArrayBuffer(this.response);
} else {
solidsConsumer(null, this.status);
}
}
};
xhr.open('GET', url);
xhr.responseType = 'blob';
xhr.send();
}

View file

@ -1,15 +1,15 @@
import {StlSolid, StlFace} from './stl-data-structure'
export function parse(buf) {
var solid = {
name: null,
faces: []
};
var solids = [];
var triangle = [];
var normal = null;
var reader = new LinesReader(buf);
let solid = new StlSolid('');
let face = new StlFace(null);
let solids = [];
let reader = new LinesReader(buf);
let lineNumber = 0;
while (reader.hasNextLine()) {
let line = reader.nextLine();
let line = reader.nextLine();
lineNumber ++;
var parts = line
.trim()
.split(' ')
@ -18,10 +18,7 @@ export function parse(buf) {
});
switch(parts[0]) {
case 'solid':
solid = {
name: parts.slice(1).join(' '),
faces: []
};
solid = new StlSolid(parts.slice(1).join(' '));
break;
case 'endsolid':
solids.push(solid);
@ -29,22 +26,22 @@ export function parse(buf) {
case 'facet':
var noramlParts = parts.slice(2);
if (noramlParts.length == 3) {
normal = noramlParts.map(Number);
face.normal = noramlParts.map(Number);
} else {
console.warn('bad normal definition at line ' + lineNumber);
}
break;
case 'vertex':
var position = parts.slice(1).map(Number);
triangle.push(position);
const position = parts.slice(1).map(Number);
face.vertices.push(position);
break;
case 'endfacet':
if (triangle.length == 3) {
solid.faces.push({
vertices: triangle,
normal: normal
});
if (face.normal != null && face.vertices.length == 3) {
solid.faces.push(face);
} else {
console.warn('bad stl face at line ' + lineNumber);
}
triangle = [];
normal = null;
face = new StlFace(null);
default:
// skip
}

View file

@ -0,0 +1,9 @@
export function StlSolid(name) {
this.name = name;
this.faces = [];
}
export function StlFace(normal) {
this.normal = normal;
this.vertices = [];
}

View file

@ -5,13 +5,18 @@ export function ParseStl(buf) {
if(typeof buf === 'string') {
return ParseASCII(buf);
}
// The other way is to check if file starts with 'solid' then it's ascii
// WIKI: A binary STL file has an 80-character header (which is generally ignored, but should never begin with "solid"
// because that will lead most software to assume that this is an ASCII STL file
//var triangleCount = buf.readUInt32LE(80);
//var expectedSize = 80 + 4 + triangleCount * ((4 * 3) * 4 + 2);
//
//if(expectedSize === buf.length) {
// return parseBinary(buf);
//}
const dataView = new DataView(buf);
const triangleCount = dataView.getUint32(80, true);
const expectedSize = 80 + 4 + triangleCount * ((4 * 3) * 4 + 2);
if(expectedSize === buf.byteLength) {
return [ParseBinary(dataView)];
}
return ParseASCII(buf);
}