stl.js v0.0.5
Simple STL utils
Currently, just an STL parser and writer. It handles the most popular ASCII and binary formats. It can read an entire buffer synchronously, or read a stream on-the-fly. It writes via a transform stream.
Reading
Synchronous immediate
var data = fs.readFileSync('gear.stl');
var stl = STLParser.parse(data [, options] );
stl = {
format: ...,
header: { ... },
triangles: [{ normal: vector, vertices: [vector, ...] }, ...]
};
Pseudo-asynchronous steam
fs.createReadStream('gear.stl')
.pipe(new STLParser.ParseStream( [options] ))
.on('format', function (format) {
})
.on('header', function (header) {
})
.on('data', function (triangle) {
})
.on('error', ...)
.on('finish', ...);
I called this "pseudo" asynchronous because the actual parsing is done by JS code, so is blocking and synchronous. The stream wrapper provides an asynchronous transform-stream interface around the parser, allowing sockets and files to be easily streamed through the parser.
If you're reading from a stream, but want the entire STL object, the transform
stream has a construct
method which will stream in the entire model and give
a single result in the same format as the non-streaming method:
fs.createReadStream('gear.stl')
.pipe(new STL.ParseStream())
.construct()
.on('data', function (chunk) {
/* Callback only called once */
/* chunk is entire STL model in same format that STLParser returns */
})
.on('finish', function () {
});
Result formats
format
is eitherbinary
orascii
.header
is either:ascii format:
{ name: 'solid name' }
binary format:
{ data: <80-byte buffer>, count: number }
triangles
is an array oftriangle
.triangle
is:{ normal: [nx, ny, nz], vertices: [ [v1x, v1y, v1z], [v2x, v2y, v2z], [v3x, v3y, v3z] ] }
For binary format, each triangle also contains an
attr
property containing a 16-bit integer value which has no standardized meaning.
Notes
The parser strictly enforces syntax, and disallows unfamiliar tokens. It does not however perform any validation on the geometry data, including:
Winding direction of vertices
Normal agreeing with direction implied by vertices
Some parse errors can be disabled by setting lax: true
in the parser options.
With lax
mode enabled, the following deviations from the standard are
permitted:
Non-positive values are permitted in vertex vectors
Tabs may also be used as whitespace in ASCII format
Garbage at end of lines is ignored
name
afterendsolid
does not have to match name aftersolid
Writing
Streaming
The writer is a transform stream. Initialize it with header data and triangle count, then stream the triangles in:
/* AsciiWriter requires solid name and triangle count */
var writer = new STL.AsciiWriter('name', numTriangles);
/* BinaryWriter requires header buffer/string and triangle count */
var writer = new STL.BinaryWriter(null, numTriangles);
/* Either/both of the following may be called multiple times */
writer.write(individualTriangle);
writer.write(arrayOfTriangles);
All at once
When initialized without header data, then writer will accept the entire STL
object (including headers) in one call to write
:
/* No parameters */
var writer = new STL.AsciiWriter();
/* One write call, with the entire STL object */
writer.write(parsedStlObject);
.pipe(...);