mirror of
https://github.com/xibyte/jsketcher
synced 2025-12-28 11:22:59 +01:00
stl reader and url loader
This commit is contained in:
parent
97abd14f0e
commit
3213728337
4 changed files with 63 additions and 29 deletions
23
web/app/3d/io.js
Normal file
23
web/app/3d/io.js
Normal 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();
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
9
web/app/3d/stl/stl-data-structure.js
Normal file
9
web/app/3d/stl/stl-data-structure.js
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
export function StlSolid(name) {
|
||||
this.name = name;
|
||||
this.faces = [];
|
||||
}
|
||||
|
||||
export function StlFace(normal) {
|
||||
this.normal = normal;
|
||||
this.vertices = [];
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue