Permalink
Cannot retrieve contributors at this time
Join GitHub today
GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.
Sign up
Fetching contributors…

// 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; | |
})(); |