Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
[threejs][html5]STL File Viewer with HTML5 File API
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>STL File Viewer</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r68/three.min.js"
></script>
<script src="https://rawgit.com/mrdoob/three.js/master/examples/js/controls/TrackballControls.js"
></script>
<script src="loader.js"></script>
<script src="stl.js"></script>
</head>
<body>
<div>
select stl file: <input type="file" id="file" /> or drop stl file
</div>
<div id="view"></div>
</body>
</html>
window.addEventListener("load", function () {
"use strict";
var w = 800, h = 800;
var renderer = new THREE.WebGLRenderer();
renderer.setSize(w, h);
var view = document.getElementById("view");
view.appendChild(renderer.domElement);
var camera = new THREE.PerspectiveCamera(45, w / h, 1, 1000);
camera.position.set(0, 0, 50);
var controls = new THREE.TrackballControls(camera, view);
var scene = new THREE.Scene();
scene.add(new THREE.AmbientLight(0x666666));
var light1 = new THREE.DirectionalLight(0xffffff);
light1.position.set(0, 100, 100);
scene.add(light1);
var light2 = new THREE.DirectionalLight(0xffffff);
light2.position.set(0, -100, -100);
scene.add(light2);
var mat = new THREE.MeshPhongMaterial({
color: 0x339900, ambient: 0x339900, specular: 0x030303,
});
var obj = new THREE.Mesh(new THREE.Geometry(), mat);
scene.add(obj);
var loop = function loop() {
requestAnimationFrame(loop);
//obj.rotation.z += 0.05;
controls.update();
renderer.clear();
renderer.render(scene, camera);
};
loop();
// file load
var openFile = function (file) {
var reader = new FileReader();
reader.addEventListener("load", function (ev) {
var buffer = ev.target.result;
var geom = loadStl(buffer);
scene.remove(obj);
obj = new THREE.Mesh(geom, mat);
scene.add(obj);
}, false);
reader.readAsArrayBuffer(file);
};
// file input button
var input = document.getElementById("file");
input.addEventListener("change", function (ev) {
var file = ev.target.files[0];
openFile(file);
}, false);
// dnd
view.addEventListener("dragover", function (ev) {
ev.stopPropagation();
ev.preventDefault();
ev.dataTransfer.dropEffect = "copy";
}, false);
view.addEventListener("drop", function (ev) {
ev.stopPropagation();
ev.preventDefault();
var file = ev.dataTransfer.files[0];
openFile(file);
}, false);
}, false);
var loadStl = (function () {
var binaryVector3 = function (view, offset) {
var v = new THREE.Vector3();
v.x = view.getFloat32(offset + 0, true);
v.y = view.getFloat32(offset + 4, true);
v.z = view.getFloat32(offset + 8, true);
return v;
};
var loadBinaryStl = function (buffer) {
// binary STL
var view = new DataView(buffer);
var size = view.getUint32(80, true);
var geom = new THREE.Geometry();
var offset = 84;
for (var i = 0; i < size; i++) {
var normal = binaryVector3(view, offset);
geom.vertices.push(binaryVector3(view, offset + 12));
geom.vertices.push(binaryVector3(view, offset + 24));
geom.vertices.push(binaryVector3(view, offset + 36));
geom.faces.push(
new THREE.Face3(i * 3, i * 3 + 1, i * 3 + 2, normal));
offset += 4 * 3 * 4 + 2;
}
return geom;
};
var m2vec3 = function (match) {
var v = new THREE.Vector3();
v.x = parseFloat(match[1]);
v.y = parseFloat(match[2]);
v.z = parseFloat(match[3]);
return v;
};
var toLines = function (array) {
var lines = [];
var h = 0;
for (var i = 0; i < array.length; i++) {
if (array[i] === 10) {
var line = String.fromCharCode.apply(
null, array.subarray(h, i));
lines.push(line);
h = i + 1;
}
}
lines.push(String.fromCharCode.apply(null, array.subarray(h)));
return lines;
}
var loadTextStl = function (buffer) {
var lines = toLines(new Uint8Array(buffer));
var index = 0;
var scan = function (regexp) {
while (lines[index].match(/^\s*$/)) index++;
var r = lines[index].match(regexp);
return r;
};
var scanOk = function (regexp) {
var r = scan(regexp);
if (!r) throw new Error(
"not text stl: " + regexp.toString() +
"=> (line " + (index - 1) + ")" +
"[" + lines[index-1] + "]");
index++;
return r;
}
var facetReg = /^\s*facet\s+normal\s+([^\s]+)\s+([^\s]+)\s+([^\s]+)/;
var vertexReg = /^\s*vertex\s+([^s]+)\s+([^\s]+)\s+([^\s]+)/;
var geom = new THREE.Geometry();
scanOk(/^\s*solid\s(.*)/);
while (!scan(/^\s*endsolid/)) {
var normal = scanOk(facetReg);
scanOk(/^\s*outer\s+loop/);
var v1 = scanOk(vertexReg);
var v2 = scanOk(vertexReg);
var v3 = scanOk(vertexReg);
scanOk(/\s*endloop/);
scanOk(/\s*endfacet/);
var base = geom.vertices.length;
geom.vertices.push(m2vec3(v1));
geom.vertices.push(m2vec3(v2));
geom.vertices.push(m2vec3(v3));
geom.faces.push(
new THREE.Face3(base, base + 1, base + 2, m2vec3(normal)));
}
return geom;
};
return function (buffer) {
try {
console.log("load as text stl");
return loadTextStl(buffer);
} catch (ex) {
console.log(ex);
console.log("load as binary stl");
return loadBinaryStl(buffer);
}
};
})();
@bellbind

This comment has been minimized.

@siidorann

This comment has been minimized.

Copy link

commented Jan 10, 2016

How can I set a .stl scene before uploading file?
I wanna set stl scene that is in may server.

@SalmanEmenacsoft

This comment has been minimized.

Copy link

commented Nov 24, 2016

Nice code, but i have one question, in the above code we have to select the .STL file for the system, but in my case i have the file on my server and i have the link to show that, can you please help me how can i show that please

Thanks

@fenderguitar

This comment has been minimized.

Copy link

commented Apr 29, 2017

Any updates on adding our own .stl file? I have one on my server but can't figure out how to modify the code to point to that stl.

@yayas10

This comment has been minimized.

Copy link

commented Nov 16, 2017

For loading an scene from server side, you have to load the file with THREE.STLloader module provided in three.js website specifing your static path to the file from server, instead of loading the local file with function:(
var openFile = function (file) {
var reader = new FileReader();
reader.addEventListener("load", function (ev) {
var buffer = ev.target.result;
var geom = loadStl(buffer);
scene.remove(obj);
obj = new THREE.Mesh(geom, mat);
scene.add(obj);
}, false);
reader.readAsArrayBuffer(file);
};
)

There is an example on three.js website.

@pkemarco

This comment has been minimized.

Copy link

commented Jul 19, 2019

Hi ! It is very beautiful and helpful. But I want to know please what I have to do to change the background color ? Thank tou.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.