]>
Commit | Line | Data |
---|---|---|
1 | /* nt3d - Javascript library for doing some 3D stuff. | |
2 | * Copyright (C) 2012 Scott Worley <ScottWorley@ScottWorley.com> | |
3 | * | |
4 | * This program is free software: you can redistribute it and/or modify | |
5 | * it under the terms of the GNU Affero General Public License as | |
6 | * published by the Free Software Foundation, either version 3 of the | |
7 | * License, or (at your option) any later version. | |
8 | * | |
9 | * This program is distributed in the hope that it will be useful, | |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | * GNU Affero General Public License for more details. | |
13 | * | |
14 | * You should have received a copy of the GNU Affero General Public License | |
15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
16 | */ | |
17 | ||
18 | nt3d = { | |
19 | triangle: function(a, b, c) { | |
20 | return [a, b, c]; | |
21 | }, | |
22 | quad: function(a, b, c, d) { | |
23 | return this.triangle(a, b, c).concat( | |
24 | this.triangle(c, d, a)); | |
25 | }, | |
26 | trianglefan: function(fan) { | |
27 | var result = []; | |
28 | for (var i = 2; i < fan.length; i++) { | |
29 | result.push(fan[0], fan[i-1], fan[i]); | |
30 | } | |
31 | return result; | |
32 | }, | |
33 | quadstrip: function(strip) { | |
34 | if (strip.length % 2 != 0) { | |
35 | alert("quadstrip length not divisble by 2!"); | |
36 | } | |
37 | var result = []; | |
38 | for (var i = 2; i < strip.length; i += 2) { | |
39 | result = result.concat(nt3d.quad(strip[i-2], strip[i-1], strip[i+1], strip[i])); | |
40 | } | |
41 | return result; | |
42 | }, | |
43 | closed_quadstrip: function(strip) { | |
44 | return nt3d.quadstrip(strip).concat(nt3d.quad(strip[strip.length-2], strip[strip.length-1], strip[1], strip[0])); | |
45 | }, | |
46 | sub: function(a, b) { | |
47 | return [a[0] - b[0], | |
48 | a[1] - b[1], | |
49 | a[2] - b[2]]; | |
50 | }, | |
51 | cross: function(a, b) { | |
52 | return [a[1]*b[2] - a[2]*b[1], | |
53 | a[2]*b[0] - a[0]*b[2], | |
54 | a[0]*b[1] - a[1]*b[0]]; | |
55 | }, | |
56 | normal: function(a, b, c) { | |
57 | return this.cross(this.sub(a, b), this.sub(b, c)); | |
58 | }, | |
59 | go: function() { | |
60 | // Get params from form | |
61 | var params = []; | |
62 | for (var i = 0; i < this.user_params.length; i++) { | |
63 | params[i] = this.form.elements["param"+i].value; | |
64 | } | |
65 | ||
66 | // Run user_function | |
67 | this.points = this.user_function.apply(null, params); | |
68 | if (this.points.length % 3 != 0) { | |
69 | alert("Points list length not divisble by 3!"); | |
70 | } | |
71 | var n = this.points.length / 3; | |
72 | ||
73 | // Make STL | |
74 | this.stl = "solid " + this.user_function.name + "\n"; | |
75 | for (var i = 0; i < n; i++) { | |
76 | var a = this.points[i*3+0]; | |
77 | var b = this.points[i*3+1]; | |
78 | var c = this.points[i*3+2]; | |
79 | var normal = this.normal(a, b, c); | |
80 | this.stl += "facet normal " + normal[0] + " " + normal[1] + " " + normal[2] + "\n" + | |
81 | "outer loop\n" + | |
82 | "vertex " + a[0] + " " + a[1] + " " + a[2] + "\n"+ | |
83 | "vertex " + b[0] + " " + b[1] + " " + b[2] + "\n"+ | |
84 | "vertex " + c[0] + " " + c[1] + " " + c[2] + "\n"+ | |
85 | "endloop\n" + | |
86 | "endfacet\n"; | |
87 | } | |
88 | this.stl += "endsolid " + this.user_function.name + "\n"; | |
89 | ||
90 | // Remove any previous download links | |
91 | var old_download_link = document.getElementById("nt3d_download"); | |
92 | if (old_download_link) { | |
93 | old_download_link.parentNode.removeChild(old_download_link); | |
94 | } | |
95 | ||
96 | // Offer result as download | |
97 | var download_link = document.createElement("a"); | |
98 | download_link.appendChild(document.createTextNode("Download!")); | |
99 | download_link.setAttribute("id", "nt3d_download"); | |
100 | download_link.setAttribute("style", "background-color: blue"); | |
101 | download_link.setAttribute("download", this.user_function.name + ".stl"); | |
102 | download_link.setAttribute("href", "data:application/sla," + encodeURIComponent(this.stl)); | |
103 | this.ui.appendChild(download_link); | |
104 | 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); | |
105 | }, | |
106 | framework: function (f, params) { | |
107 | this.user_function = f; | |
108 | this.user_params = params; | |
109 | ||
110 | // Make the UI | |
111 | this.ui = document.getElementById("nt3dui"); | |
112 | if (!this.ui) { | |
113 | this.ui = document.createElement("div"); | |
114 | this.ui.setAttribute("id", "nt3dui"); | |
115 | document.body.appendChild(this.ui); | |
116 | } | |
117 | this.form = document.createElement("form"); | |
118 | this.form.setAttribute("onsubmit", "nt3d.go(); return false"); | |
119 | this.ui.appendChild(this.form); | |
120 | var table = document.createElement("table"); | |
121 | this.form.appendChild(table); | |
122 | var tr = document.createElement("tr"); | |
123 | table.appendChild(tr); | |
124 | var th = document.createElement("th"); | |
125 | th.appendChild(document.createTextNode("Variable")); | |
126 | tr.appendChild(th); | |
127 | th = document.createElement("th"); | |
128 | th.appendChild(document.createTextNode("Value")); | |
129 | tr.appendChild(th); | |
130 | for (var i = 0; i < params.length; i++) { | |
131 | tr = document.createElement("tr"); | |
132 | table.appendChild(tr); | |
133 | var td = document.createElement("td"); | |
134 | td.appendChild(document.createTextNode(params[i][0])); | |
135 | tr.appendChild(td); | |
136 | td = document.createElement("td"); | |
137 | var input = document.createElement("input"); | |
138 | input.setAttribute("name", "param" + i); | |
139 | input.setAttribute("value", params[i][1]); | |
140 | td.appendChild(input); | |
141 | tr.appendChild(td); | |
142 | } | |
143 | var go = document.createElement("input"); | |
144 | go.setAttribute("type", "button"); | |
145 | go.setAttribute("value", "Go!"); | |
146 | go.setAttribute("onclick", "nt3d.go()"); | |
147 | this.form.appendChild(go); | |
148 | } | |
149 | }; |