Permalink
Switch branches/tags
Nothing to show
Find file
Fetching contributors…
Cannot retrieve contributors at this time
188 lines (149 sloc) 6.05 KB
// namespace
var MeshesJS = MeshesJS || {};
;(function() {
// Constructor
function STLLoader(dropTarget) {
this.dropTarget = dropTarget || null;
this.addDropListener();
}
// methods
STLLoader.prototype.onDragLeave = function(e) {
e.stopPropagation();
e.preventDefault();
}
STLLoader.prototype.onDrop = function(e) {
this.onDragLeave(e);
this.loadFile((e.target.files || e.dataTransfer.files)[0]);
}
STLLoader.prototype.addDropListener = function(dropTarget) {
var dropTarget = dropTarget || this.dropTarget;
if (dropTarget) {
var self = this;
dropTarget.addEventListener('drop' , function(e) { self.onDrop(e); } , false);
dropTarget.addEventListener('dragover' , function(e) { self.onDragLeave(e); }, false);
dropTarget.addEventListener('dragleave', function(e) { self.onDragLeave(e); }, false);
}
};
STLLoader.prototype.removeDropListener = function(dropTarget) {
var dropTarget = dropTarget || this.dropTarget;
if (dropTarget) {
var self = this;
dropTarget.removeEventListener('drop' , function(e) { self.onDrop(e); } , false);
dropTarget.removeEventListener('dragover' , function(e) { self.onDragLeave(e); }, false);
dropTarget.removeEventListener('dragleave', function(e) { self.onDragLeave(e); }, false);
}
};
STLLoader.prototype.onGeometry = function(geometry) {};
STLLoader.prototype.onError = function(error) {};
STLLoader.prototype.loadFile = function(file) {
// self alias
var self = this;
// file reader instance
var reader = new FileReader();
// on file loaded
reader.onloadend = function(event) {
// if error/abort
if (this.error) {
self.onError(this.error);
return;
}
// Parse ASCII STL
if (typeof this.result === 'string' ) {
self.loadString(this.result);
return;
}
// buffer reader
var view = new DataView(this.result);
// get faces number
try {
var faces = view.getUint32(80, true);
}
catch(error) {
self.onError(error);
return;
}
// is binary ?
var binary = view.byteLength == (80 + 4 + 50 * faces);
if (! binary) {
// get the file contents as string
// (faster than convert array buffer)
reader.readAsText(file);
return;
}
// parse binary STL
self.loadBinaryData(view, faces);
};
// start reading file as array buffer
reader.readAsArrayBuffer(file);
};
STLLoader.prototype.loadString = function(data) {
var length, normal, patternNormal, patternVertex, result, text;
var geometry = new THREE.Geometry();
var patternFace = /facet([\s\S]*?)endfacet/g;
while((result = patternFace.exec(data)) !== null) {
text = result[0];
patternNormal = /normal[\s]+([\-+]?[0-9]+\.?[0-9]*([eE][\-+]?[0-9]+)?)+[\s]+([\-+]?[0-9]*\.?[0-9]+([eE][\-+]?[0-9]+)?)+[\s]+([\-+]?[0-9]*\.?[0-9]+([eE][\-+]?[0-9]+)?)+/g;
patternVertex = /vertex[\s]+([\-+]?[0-9]+\.?[0-9]*([eE][\-+]?[0-9]+)?)+[\s]+([\-+]?[0-9]*\.?[0-9]+([eE][\-+]?[0-9]+)?)+[\s]+([\-+]?[0-9]*\.?[0-9]+([eE][\-+]?[0-9]+)?)+/g;
while((result = patternNormal.exec(text)) !== null) {
normal = new THREE.Vector3(
parseFloat(result[1]),
parseFloat(result[3]),
parseFloat(result[5])
);
}
while((result = patternVertex.exec(text)) !== null) {
geometry.vertices.push(new THREE.Vector3(
parseFloat(result[1]),
parseFloat(result[3]),
parseFloat(result[5])
));
}
length = geometry.vertices.length;
geometry.faces.push(new THREE.Face3(length-3, length-2, length-1, normal));
}
geometry.computeBoundingBox();
geometry.computeBoundingSphere();
this.onGeometry(geometry);
};
STLLoader.prototype.loadBinaryData = function(view, faces) {
if (! view instanceof DataView) {
var view = new DataView(view);
}
if (! faces) {
try {
var faces = view.getUint32(80, true);
}
catch(error) {
this.onError(error);
return;
}
}
var dataOffset = 84;
var faceLength = 12 * 4 + 2;
var offset = 0;
var geometry = new THREE.BufferGeometry();
var vertices = new Float32Array( faces * 3 * 3 );
var normals = new Float32Array( faces * 3 * 3 );
for ( var face = 0; face < faces; face ++ ) {
var start = dataOffset + face * faceLength;
var normalX = view.getFloat32( start, true );
var normalY = view.getFloat32( start + 4, true );
var normalZ = view.getFloat32( start + 8, true );
for (var i = 1; i <= 3; i ++) {
var vertexstart = start + i * 12;
normals[ offset ] = normalX;
normals[ offset + 1 ] = normalY;
normals[ offset + 2 ] = normalZ;
vertices[ offset ] = view.getFloat32( vertexstart, true );
vertices[ offset + 1 ] = view.getFloat32( vertexstart + 4, true );
vertices[ offset + 2 ] = view.getFloat32( vertexstart + 8, true );
offset += 3;
}
}
geometry.addAttribute('position', new THREE.BufferAttribute(vertices, 3));
geometry.addAttribute('normal', new THREE.BufferAttribute(normals, 3));
this.onGeometry(geometry);
};
// export module
MeshesJS.STLLoader = STLLoader;
})();