http://kursk.dyvniy.ru:81/develop/mrdoob-three.js/my/webgl_loader_stl.html
http://kursk.dyvniy.ru/html5/mrdoob-three.js/examples/webgl_loader_stl.html
Сохранение stl
http://buildaweso.me/project/2014/10/26/writing-binary-stl-files-from-threejs-objects
- Спойлер
- Expanding on this blog post I wrote a while back on writing ASCII STL files from THREE.js objects from the browser, I wanted to show how easy it is to write binary STL files also.
The binary STL format is very straightforward. From Wikipedia:
UINT8[80] – Header
UINT32 – Number of triangles
foreach triangle
REAL32[3] – Normal vector
REAL32[3] – Vertex 1
REAL32[3] – Vertex 2
REAL32[3] – Vertex 3
UINT16 – Attribute byte count
end
Be extra careful to write the floating point numbers as little-endian, as the wikipedia article warns:
“Floating-point numbers are... assumed to be little-endian, although this is not stated in documentation.”
Once we get the mechanics of writing binary data out of the way, it really becomes trivial, so lets tackle that first. To write binary data in javascript we'll need two objects:
A container to put the raw data in: an ArrayBuffer
A helper to write heterogeneous binary datatypes: a DataView
Since this is binary data, we need to know how many bytes the file will be before we are able to start writing it. Its pretty straightforward to compute from the layout above:
// sizeInBytes =
// 80 * sizeof(UINT8)
// + 1 * sizeof(UINT32)
// + (12 * sizeof(REAL32) + 1 * sizeof(UINT16)) * N triangles
var buffer = new ArrayBuffer(84 + (50 * nTriangles));
That takes care of the ArrayBuffer container for the data, but how do we write data to it?
Because we are dealing with many different binary types (uint8, uint32, float32, etc.), we need an abstraction that allows us to write these types into the raw data buffer. That is what a DataView does. After creating a DataView using the raw ArrayBuffer it will write data into, you can easily write individual bytes of data in their corresponding types. You only have to keep track of the byte offset:
Код: Выделить всё
var dataview = new DataView(buffer);
var offset = 0;
// To skip data, no need to write zeros, just increase the offset
offset += 80 // For the STL header
// To write a vector like the face normal, or a vertex
// need to pass in isLittleEndian=true / false as last param
dataview.setFloat32(offset, v.x, isLittleEndian);
offset += 4; // 4 = number of bytes in a float 32
dataview.setFloat32(offset, v.y, isLittleEndian);
offset += 4;
dataview.setFloat32(offset, v.z, isLittleEndian);
offset += 4;
Putting those together, here is the full binary stl writer.
// Written by Paul Kaplan
var BinaryStlWriter = (function() {
var that = {};
var writeVector = function(dataview, offset, vector, isLittleEndian) {
offset = writeFloat(dataview, offset, vector.x, isLittleEndian);
offset = writeFloat(dataview, offset, vector.y, isLittleEndian);
return writeFloat(dataview, offset, vector.z, isLittleEndian);
};
var writeFloat = function(dataview, offset, float, isLittleEndian) {
dataview.setFloat32(offset, float, isLittleEndian);
return offset + 4;
};
var geometryToDataView = function(geometry) {
var tris = geometry.faces;
var verts = geometry.vertices;
var isLittleEndian = true; // STL files assume little endian, see wikipedia page
var bufferSize = 84 + (50 * tris.length);
var buffer = new ArrayBuffer(bufferSize);
var dv = new DataView(buffer);
var offset = 0;
offset += 80; // Header is empty
dv.setUint32(offset, tris.lengtb, isLittleEndian);
offset += 4;
for(var n = 0; n < tris.length; n++) {
offset = writeVector(dv, offset, tris[n].normal, isLittleEndian);
offset = writeVector(dv, offset, verts[tris[n].a], isLittleEndian);
offset = writeVector(dv, offset, verts[tris[n].b], isLittleEndian);
offset = writeVector(dv, offset, verts[tris[n].c], isLittleEndian);
offset += 2; // unused 'attribute byte count' is a Uint16
}
return dv;
};
var save = function(geometry, filename) {
var dv = geometryToDataView(geometry);
var blob = new Blob([dv], {type: 'application/octet-binary'});
// FileSaver.js defines `saveAs` for saving files out of the browser
saveAs(blob, filename);
};
that.save = save;
return that;
}());
view rawbinary_stl_writer.js hosted with ❤ by GitHub