Skip to content

Instantly share code, notes, and snippets.

@plugnburn
Last active October 11, 2019 19:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save plugnburn/5371798326cb894e3ef17e33f1646c65 to your computer and use it in GitHub Desktop.
Save plugnburn/5371798326cb894e3ef17e33f1646c65 to your computer and use it in GitHub Desktop.
STL2SCAD.js - Optimizing decompiler of a binary STL into the OpenSCAD source
/**
* Optimizing decompiler of a binary STL into the OpenSCAD polyhedron module
* @license Unlicense
*
* @param {ArrayBuffer} stl STL file contents (binary flavor)
* @param {string} optional custom name for OpenSCAD object (if none passed then 'object{NumTriangles}' will be used)
* @returns {string} ready OpenSCAD script
*/
function STL2SCAD(stl, optModName = null) {
var totalTriangles = new Uint32Array(stl.slice(80, 84))[0], //triangle amount is LE uint at byte 80
cVD = new Uint8Array(stl.slice(84)), //points should start from byte 84
i, k, l = cVD.length, p, pKey, vertices = [], triangles = [],
modName = optModName || ('object' + totalTriangles),
embrace = a => '[' + a.join(', ') + ']',
reslice = (i, k) => new Float32Array(cVD.slice(i+k+12, i+k+16).buffer)[0].toFixed(5) + 0,
vertexCache = {}, triangle
//trim the garbage
if(l > totalTriangles * 50)
l = totalTriangles * 50
for(i=0;i<l;i+=50) { //two loops to skip all unused bytes
triangle = []
for(k=0;k<3;k++) {
p = {
x: reslice(i, 12*k),
y: reslice(i, 12*k + 4),
z: reslice(i, 12*k + 8)
}
pKey = [p.x, p.y, p.z].join(':')
if(!vertexCache[pKey]) {
vertices.push(embrace([p.x,p.y,p.z]))
vertexCache[pKey] = vertices.length - 1
}
triangle.push(vertexCache[pKey])
}
triangles.push(embrace([triangle[0], triangle[2], triangle[1]]))
}
return 'module ' + modName + ' () {\n\tpolyhedron(\n\t\tpoints='
+ embrace(vertices) + ',\n\t\tfaces='
+ embrace(triangles) + '\n\t);\n}\n' + modName + '();'
}
if(module) {
module.exports = STL2SCAD
if(typeof require !== 'undefined' && require.main === module) {
const fs = require('fs')
let stlContents = fs.readFileSync(process.argv[2])
console.log(STL2SCAD(stlContents.buffer))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment