/* nt3d - Javascript library for doing some 3D stuff. * Copyright (C) 2012 Scott Worley * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ nt3d = { triangle: function(a, b, c) { return [a, b, c]; }, quad: function(a, b, c, d) { return this.triangle(a, b, c).concat( this.triangle(c, d, a)); }, trianglefan: function(fan) { var result = []; for (var i = 2; i < fan.length; i++) { result.push(fan[0], fan[i-1], fan[i]); } return result; }, quadstrip: function(strip) { if (strip.length % 2 != 0) { alert("quadstrip length not divisble by 2!"); } var result = []; for (var i = 2; i < strip.length; i += 2) { result = result.concat(nt3d.quad(strip[i-2], strip[i-1], strip[i+1], strip[i])); } return result; }, closed_quadstrip: function(strip) { return nt3d.quadstrip(strip).concat(nt3d.quad(strip[strip.length-2], strip[strip.length-1], strip[1], strip[0])); }, sub: function(a, b) { return [a[0] - b[0], a[1] - b[1], a[2] - b[2]]; }, cross: function(a, b) { return [a[1]*b[2] - a[2]*b[1], a[2]*b[0] - a[0]*b[2], a[0]*b[1] - a[1]*b[0]]; }, normal: function(a, b, c) { return this.cross(this.sub(a, b), this.sub(b, c)); }, go: function() { // Get params from form var params = []; for (var i = 0; i < this.user_params.length; i++) { params[i] = this.form.elements["param"+i].value; } // Run user_function this.points = this.user_function.apply(null, params); if (this.points.length % 3 != 0) { alert("Points list length not divisble by 3!"); } var n = this.points.length / 3; // Make STL this.stl = "solid " + this.user_function.name + "\n"; for (var i = 0; i < n; i++) { var a = this.points[i*3+0]; var b = this.points[i*3+1]; var c = this.points[i*3+2]; var normal = this.normal(a, b, c); this.stl += "facet normal " + normal[0] + " " + normal[1] + " " + normal[2] + "\n" + "outer loop\n" + "vertex " + a[0] + " " + a[1] + " " + a[2] + "\n"+ "vertex " + b[0] + " " + b[1] + " " + b[2] + "\n"+ "vertex " + c[0] + " " + c[1] + " " + c[2] + "\n"+ "endloop\n" + "endfacet\n"; } this.stl += "endsolid " + this.user_function.name + "\n"; // Remove any previous download links var old_download_link = document.getElementById("nt3d_download"); if (old_download_link) { old_download_link.parentNode.removeChild(old_download_link); } // Offer result as download var download_link = document.createElement("a"); download_link.appendChild(document.createTextNode("Download!")); download_link.setAttribute("id", "nt3d_download"); download_link.setAttribute("style", "background-color: blue"); download_link.setAttribute("download", this.user_function.name + ".stl"); download_link.setAttribute("href", "data:application/sla," + encodeURIComponent(this.stl)); this.ui.appendChild(download_link); setTimeout(function() { download_link.setAttribute("style", "-webkit-transition: background-color 0.4s; -moz-transition: background-color 0.4s; -o-transition: background-color 0.4s; -ms-transition: background-color 0.4s; transition: background-color 0.4s; background-color: inherit"); }, 0); }, framework: function (f, params) { this.user_function = f; this.user_params = params; // Make the UI this.ui = document.getElementById("nt3dui"); if (!this.ui) { this.ui = document.createElement("div"); this.ui.setAttribute("id", "nt3dui"); document.body.appendChild(this.ui); } this.form = document.createElement("form"); this.form.setAttribute("onsubmit", "nt3d.go(); return false"); this.ui.appendChild(this.form); var table = document.createElement("table"); this.form.appendChild(table); var tr = document.createElement("tr"); table.appendChild(tr); var th = document.createElement("th"); th.appendChild(document.createTextNode("Variable")); tr.appendChild(th); th = document.createElement("th"); th.appendChild(document.createTextNode("Value")); tr.appendChild(th); for (var i = 0; i < params.length; i++) { tr = document.createElement("tr"); table.appendChild(tr); var td = document.createElement("td"); td.appendChild(document.createTextNode(params[i][0])); tr.appendChild(td); td = document.createElement("td"); var input = document.createElement("input"); input.setAttribute("name", "param" + i); input.setAttribute("value", params[i][1]); td.appendChild(input); tr.appendChild(td); } var go = document.createElement("input"); go.setAttribute("type", "button"); go.setAttribute("value", "Go!"); go.setAttribute("onclick", "nt3d.go()"); this.form.appendChild(go); } };