summaryrefslogtreecommitdiffabout
path: root/delta.jscad
Unidiff
Diffstat (limited to 'delta.jscad') (more/less context) (ignore whitespace changes)
-rw-r--r--delta.jscad1
1 files changed, 1 insertions, 0 deletions
diff --git a/delta.jscad b/delta.jscad
index e9fb773..b783913 100644
--- a/delta.jscad
+++ b/delta.jscad
@@ -1,1050 +1,1051 @@
1var PRINT = { 1var PRINT = {
2 layer_height: 0.2, 2 layer_height: 0.2,
3 extrusion_width: 0.4, 3 extrusion_width: 0.4,
4 4
5 fit_tolerance: .2, slide_tolerance: .4, play_tolerance: .6, screw_tolerance: .3 5 fit_tolerance: .2, slide_tolerance: .4, play_tolerance: .6, screw_tolerance: .3
6}; 6};
7 7
8var CONFIG = { 8var CONFIG = {
9 extrusion: { 9 extrusion: {
10 w: 20, slotdepth: 6 10 w: 20, slotdepth: 6
11 }, 11 },
12 base: { 12 base: {
13 el: 240, // side extrusion length 13 el: 240, // side extrusion length
14 sl: 240+2*70, // triangle side length 14 sl: 240+2*70, // triangle side length
15 gap: 9 // vertical gap between side extrusions 15 gap: 9 // vertical gap between side extrusions
16 }, 16 },
17 column: { 17 column: {
18 h: 600 // column height 18 h: 600 // column height
19 }, 19 },
20 heatbed: { 20 heatbed: {
21 r: 220/2, // heatbed radius 21 r: 220/2, // heatbed radius
22 sr: 220/2-4.5,// radius of the screwholes circle 22 sr: 220/2-4.5,// radius of the screwholes circle
23 h: 3+1.5 // thickness (including insulation) 23 h: 3+1.5 // thickness (including insulation)
24 }, 24 },
25 glass: { 25 glass: {
26 r: 195/2, // glass radius 26 r: 195/2, // glass radius
27 h: 3 // glass thickness 27 h: 3 // glass thickness
28 }, 28 },
29 duet: { 29 duet: {
30 pcb_size: { x: 124, y: 100, z: 1 }, 30 pcb_size: { x: 124, y: 100, z: 1 },
31 hole_spacing: { x: 115, y: 92 }, 31 hole_spacing: { x: 115, y: 92 },
32 h: 30 32 h: 30
33 }, 33 },
34 foot: { 34 foot: {
35 d: 20*Math.sqrt(2), h: 30, 35 d: 20*Math.sqrt(2), h: 30,
36 bolt: { d:5, l: 19, hd: 10 }, 36 bolt: { d:5, l: 19, hd: 10 },
37 margin: 2.5, 37 margin: 2.5,
38 nut: { d: 8.6 /* TODO: */, h: 3.5 }, 38 nut: { d: 8.6 /* TODO: */, h: 3.5 },
39 shell: 4, 39 shell: 4,
40 zscalefactor: 1.6, 40 zscalefactor: 1.6,
41 foot: { ho: 2.5, hi: 5 } 41 foot: { ho: 2.5, hi: 5 }
42 }, 42 },
43 duetholder: { 43 duetholder: {
44 bolt: { d: 3, l: 10, head: { d: 5.33, h: 3 } }, 44 bolt: { d: 3, l: 10, head: { d: 5.33, h: 3 } },
45 margin: 3, 45 margin: 3,
46 s: 2.5 46 s: 2.5
47 }, 47 },
48 bedholder: { 48 bedholder: {
49 h: 15, 49 h: 15,
50 margin: 3, 50 margin: 3,
51 nut: { w: 5.4, h: 2.5 }, 51 nut: { w: 5.4, h: 2.5 },
52 bolt: { d: 3, l: 10, head: { d: 5.33, h: 3 } } 52 bolt: { d: 3, l: 10, head: { d: 5.33, h: 3 } }
53 }, 53 },
54 hotend: { 54 hotend: {
55 h: 62.4, // full assembly height 55 h: 62.4, // full assembly height
56 groove: { d:12, h:6 }, // grove diameter and height 56 groove: { d:12, h:6 }, // grove diameter and height
57 ungroove: { d:16, above:3.7, below: 3+4 } 57 ungroove: { d:16, above:3.7, below: 3+4 }
58 }, 58 },
59 effector: { 59 effector: {
60 h: 6, 60 h: 6,
61 o: 20,// offset to the rod mounts line 61 o: 20,// offset to the rod mounts line
62 rods_apart: 40, 62 rods_apart: 40,
63 cone: { shell: 1, angle: Math.PI/6 }, 63 cone: { shell: 1, angle: Math.PI/6 },
64 rodend: { 64 rodend: {
65 joint_w: 7,// thickness of the joint 65 joint_w: 7,// thickness of the joint
66 screw_l: 20-1, // 20 with the head 66 screw_l: 20-1, // 20 with the head
67 screw_d: 3 67 screw_d: 3
68 }, 68 },
69 hotend: { margin: 2 }, 69 hotend: { margin: 2 },
70 hinge: { 70 hinge: {
71 d: 3, w: 5, margin: 2.5, 71 d: 3, w: 5, margin: 2.5,
72 h: 1+(6+3.7)/2, // elevation + grove + top 72 h: 1+(6+3.7)/2, // elevation + grove + top
73 e: 1 // elevation 73 e: 1 // elevation
74 }, 74 },
75 clamp: { 75 clamp: {
76 shell: 4.6, 76 shell: 4.6,
77 d: 3, 77 d: 3,
78 margin: 2.5, 78 margin: 2.5,
79 split: 0.6 79 split: 0.6
80 }, 80 },
81 mswitch: { 81 mswitch: {
82 size: [ 19.8, 6, 10 ], 82 size: [ 19.8, 6, 10 ],
83 screw: { 83 screw: {
84 d: 2, h: 10/2-2, 84 d: 2, h: 10/2-2,
85 s: 1.3, // screw shell 85 s: 1.3, // screw shell
86 o: [-9.5/2,9.5/2].map(function(x) { 86 o: [-9.5/2,9.5/2].map(function(x) {
87 return -19.8/2+x; 87 return -19.8/2+x;
88 }) 88 })
89 }, 89 },
90 switch_x: 2.5 90 switch_x: 2.5
91 }, 91 },
92 guide: { 92 guide: {
93 width: 3, height: 5+1, length: 6 93 width: 3, height: 5+1, length: 6
94 }, 94 },
95 fanholder: { 95 fanholder: {
96 r: 30, 96 r: 30,
97 screw: { d: 3, m: 2.5/*margin*/ }, 97 screw: { d: 3, m: 2.5/*margin*/ },
98 w: 3 98 w: 3
99 } 99 }
100 }, 100 },
101 nut: { h: 2.3, w: 5.5 }, 101 nut: { h: 2.3, w: 5.5 },
102 color: { 102 color: {
103 extrusion: [0.8, 0.8, 0.8, 0.8], 103 extrusion: [0.8, 0.8, 0.8, 0.8],
104 pcb: [ 0, 0.3, 0.2, 0.8 ], 104 pcb: [ 0, 0.3, 0.2, 0.8 ],
105 bulk: [ .9, .9, .9, .2 ], 105 bulk: [ .9, .9, .9, .2 ],
106 parts: [ 0, 0.8, 0, 0.9 ], 106 parts: [ 0, 0.8, 0, 0.9 ],
107 softparts: [ 0, 0, 0.8, 0.9 ], 107 softparts: [ 0, 0, 0.8, 0.9 ],
108 heatbed: [0.8, 0.8, 0.8, 0.8 ], 108 heatbed: [0.8, 0.8, 0.8, 0.8 ],
109 glass: [0.9, 0.9, 0.9, 0.7 ] 109 glass: [0.9, 0.9, 0.9, 0.7 ]
110 } 110 }
111}; 111};
112 112
113var CD = { 113var CD = {
114 base: (function(){ 114 base: (function(){
115 var rv = {}; 115 var rv = {};
116 rv.circumscription_r = 116 rv.circumscription_r =
117 CONFIG.base.sl/2/Math.cos(Math.PI/6); 117 CONFIG.base.sl/2/Math.cos(Math.PI/6);
118 rv.outer_inscription_r = 118 rv.outer_inscription_r =
119 Math.sqrt(Math.pow(rv.circumscription_r,2)- 119 Math.sqrt(Math.pow(rv.circumscription_r,2)-
120 Math.pow(CONFIG.base.sl/2,2)); 120 Math.pow(CONFIG.base.sl/2,2));
121 rv.mid_inscription_r = 121 rv.mid_inscription_r =
122 rv.outer_inscription_r-CONFIG.extrusion.w/2; 122 rv.outer_inscription_r-CONFIG.extrusion.w/2;
123 rv.inner_inscription_r = 123 rv.inner_inscription_r =
124 rv.outer_inscription_r-CONFIG.extrusion.w; 124 rv.outer_inscription_r-CONFIG.extrusion.w;
125 // TODO: properly calculate 125 // TODO: properly calculate
126 rv.column_r = rv.circumscription_r - 48.29; 126 rv.column_r = rv.circumscription_r - 48.29;
127 return rv; 127 return rv;
128 })(), 128 })(),
129 duetholder: (function() { 129 duetholder: (function() {
130 var rv = {}; 130 var rv = {};
131 var s = CONFIG.base.sl; 131 var s = CONFIG.base.sl;
132 var l = CONFIG.duet.hole_spacing.x; 132 var l = CONFIG.duet.hole_spacing.x;
133 var w = CONFIG.duet.hole_spacing.y; 133 var w = CONFIG.duet.hole_spacing.y;
134 var h = s*Math.cos(Math.PI/6); 134 var h = s*Math.cos(Math.PI/6);
135 var h1 = h*(1-l/s); 135 var h1 = h*(1-l/s);
136 rv.distance = (h1-w)/3; // hole to side 136 rv.distance = (h1-w)/3; // hole to side
137 return rv; 137 return rv;
138 })() 138 })()
139}; 139};
140console.log(CONFIG); console.log(CD); 140console.log(CONFIG); console.log(CD);
141 141
142var U = { 142var U = {
143 hypotenuse: function(a,b) { 143 hypotenuse: function(a,b) {
144 return Math.sqrt(Math.pow(a,2)+Math.pow(b,2)); 144 return Math.sqrt(Math.pow(a,2)+Math.pow(b,2));
145 }, 145 },
146 peek: function(x,m) { 146 peek: function(x,m) {
147 console.log(x,m); 147 console.log(x,m);
148 return x; 148 return x;
149 }, 149 },
150 axes: function U_axes(o) { 150 axes: function U_axes(o) {
151 if(!o) o = {}; 151 if(!o) o = {};
152 var l = o.l||20, g = o.g||0.7; 152 var l = o.l||20, g = o.g||0.7;
153 return union([ 153 return union([
154 CSG.roundedCylinder({start:[0,0,0],end:[l,0,0]}).setColor([1,0,0,g]), 154 CSG.roundedCylinder({start:[0,0,0],end:[l,0,0]}).setColor([1,0,0,g]),
155 CSG.roundedCylinder({start:[0,0,0],end:[0,l,0]}).setColor([0,1,0,g]), 155 CSG.roundedCylinder({start:[0,0,0],end:[0,l,0]}).setColor([0,1,0,g]),
156 CSG.roundedCylinder({start:[0,0,0],end:[0,0,l]}).setColor([0,0,1,g]) 156 CSG.roundedCylinder({start:[0,0,0],end:[0,0,l]}).setColor([0,0,1,g])
157 ]); 157 ]);
158 }, 158 },
159 pextract: function U_pextract(a,pn) { // TODO: monkeypatch Array 159 pextract: function U_pextract(a,pn) { // TODO: monkeypatch Array
160 return a.map(function(x){return x[pn]}); 160 return a.map(function(x){return x[pn]});
161 }, 161 },
162 hole: function U_hole(o) { 162 hole: function U_hole(o) {
163 var r = o.r||o.radius||(o.d/2)||(o.diameter/2); 163 var r = o.r||o.radius||(o.d/2)||(o.diameter/2);
164 var n = Math.max(Math.round(4*r),4); 164 var n = Math.max(Math.round(4*r),4);
165 return CSG.cylinder({ 165 return CSG.cylinder({
166 start: o.start, end: o.end, 166 start: o.start, end: o.end,
167 radius: r/Math.cos(Math.PI/n), 167 radius: r/Math.cos(Math.PI/n),
168 resultion: n 168 resultion: n
169 }); 169 });
170 }, 170 },
171 171
172 upright: function U_upright() { return new CSG.Connector([0,0,0],[0,0,1],[1,0,0]) }, 172 upright: function U_upright() { return new CSG.Connector([0,0,0],[0,0,1],[1,0,0]) },
173 downright: function U_downright() { return new CSG.Connector([0,0,0],[0,0,-1],[1,0,0]) }, 173 downright: function U_downright() { return new CSG.Connector([0,0,0],[0,0,-1],[1,0,0]) },
174 P: function U_P(x) { 174 P: function U_P(x) {
175 if(!x.properties.P) return x; 175 if(!x.properties.P) return x;
176 return x.connectTo(x.properties.P,U.upright(),false,0); 176 return x.connectTo(x.properties.P,U.upright(),false,0);
177 } 177 }
178 178
179}; 179};
180 180
181/* {h:,w:} */ 181/* {h:,w:} */
182function nut(o) { 182function nut(o) {
183 var rv = CSG.cylinder({ 183 var rv = CSG.cylinder({
184 start:[0,0,0],end:[0,0,o.h], 184 start:[0,0,0],end:[0,0,o.h],
185 radius: o.w/2/Math.cos(Math.PI/6), 185 radius: o.w/2/Math.cos(Math.PI/6),
186 resolution: 6 186 resolution: 6
187 }); 187 });
188 rv.properties.axis_connector = new CSG.Connector([0,0,0],[0,0,1],[0,1,0]); 188 rv.properties.axis_connector = new CSG.Connector([0,0,0],[0,0,1],[0,1,0]);
189 return rv; 189 return rv;
190} 190}
191 191
192var E3DV6 = { 192var E3DV6 = {
193 dimensions: { 193 dimensions: {
194 big_d: 22.3, 194 big_d: 22.3,
195 195
196 }, 196 },
197 heatsink: function() { 197 heatsink: function() {
198 var fn = 16; 198 var fn = 16;
199 var z=0; 199 var z=0;
200 var unite = [ {d:16,h:3.7},{d:12,h:6},{d:16,h:3} ].map(function(x) { 200 var unite = [ {d:16,h:3.7},{d:12,h:6},{d:16,h:3} ].map(function(x) {
201 return CSG.cylinder({ 201 return CSG.cylinder({
202 start: [0,0,z], end: [0,0,z-=x.h], 202 start: [0,0,z], end: [0,0,z-=x.h],
203 radius: x.d/2, resolution: fn 203 radius: x.d/2, resolution: fn
204 }); 204 });
205 }); 205 });
206 unite.push(CSG.cylinder({ 206 unite.push(CSG.cylinder({
207 start:[0,0,z-=1.5], end:[0,0,z-=1], 207 start:[0,0,z-=1.5], end:[0,0,z-=1],
208 radius: 16/2, resolution: fn 208 radius: 16/2, resolution: fn
209 })); 209 }));
210 for(var i=0;i<11;++i) unite.push(CSG.cylinder({ 210 for(var i=0;i<11;++i) unite.push(CSG.cylinder({
211 start:[0,0,z-=1.5], end:[0,0,z-=1], 211 start:[0,0,z-=1.5], end:[0,0,z-=1],
212 radius: this.dimensions.big_d/2, resolution: fn 212 radius: this.dimensions.big_d/2, resolution: fn
213 })); 213 }));
214 unite.push(CSG.cylinder({ 214 unite.push(CSG.cylinder({
215 start:[0,0,z], end: [0,0,-12.7], 215 start:[0,0,z], end: [0,0,-12.7],
216 radiusStart: 10/2, radiusEnd: 8.5/2, /* pretty arbitrary */ 216 radiusStart: 10/2, radiusEnd: 8.5/2, /* pretty arbitrary */
217 resolution: fn 217 resolution: fn
218 })); 218 }));
219 var rv = union(unite); 219 var rv = union(unite);
220 rv = rv.subtract([CSG.cylinder({ 220 rv = rv.subtract([CSG.cylinder({
221 start:[0,0,1], end: [0,0,z-1], 221 start:[0,0,1], end: [0,0,z-1],
222 radius: 4.2/2, resolution: fn 222 radius: 4.2/2, resolution: fn
223 }),CSG.cylinder({ 223 }),CSG.cylinder({
224 start:[0,0,1], end: [0,0,-6.7/*somewhat arbitrary*/], 224 start:[0,0,1], end: [0,0,-6.7/*somewhat arbitrary*/],
225 radius: 8/2, resolution: fn 225 radius: 8/2, resolution: fn
226 }),CSG.cylinder({ 226 }),CSG.cylinder({
227 start:[0,0,z-1], end: [0,0,z+14.8], 227 start:[0,0,z-1], end: [0,0,z+14.8],
228 radius: 6/2 /*M7*/, resolution: fn 228 radius: 6/2 /*M7*/, resolution: fn
229 })]); 229 })]);
230 rv.properties.pushfit_connector = new CSG.Connector([0,0,0],[0,0,-1],[1,0,0]); 230 rv.properties.pushfit_connector = new CSG.Connector([0,0,0],[0,0,-1],[1,0,0]);
231 rv.properties.heatbreak_connector = new CSG.Connector([0,0,z+14.8],[0,0,-1],[1,0,0]); 231 rv.properties.heatbreak_connector = new CSG.Connector([0,0,z+14.8],[0,0,-1],[1,0,0]);
232 rv.properties.grove_connector = new CSG.Connector([0,0,-3.7-3],[0,0,1],[1,0,0]); 232 rv.properties.grove_connector = new CSG.Connector([0,0,-3.7-3],[0,0,1],[1,0,0]);
233 return rv.setColor([0.8,0.8,0.8,0.9]); 233 return rv.setColor([0.8,0.8,0.8,0.9]);
234 } 234 }
235}; 235};
236 236
237var EFFECTOR = { 237var EFFECTOR = {
238 /* {sd: screw diameter, l: cone length, s: screw shell, a: angle from axis} */ 238 /* {sd: screw diameter, l: cone length, s: screw shell, a: angle from axis} */
239 cone: function effector_cone(o) { 239 cone: function effector_cone(o) {
240 var re = o.sd/2+o.s, rs = re+o.l*Math.tan(o.a||(Math.PI/4)); 240 var re = o.sd/2+o.s, rs = re+o.l*Math.tan(o.a||(Math.PI/4));
241 var rv = CSG.cylinder({ 241 var rv = CSG.cylinder({
242 start: [0,0,0], end: [0,0,o.l], 242 start: [0,0,0], end: [0,0,o.l],
243 radiusStart: rs, radiusEnd: re, 243 radiusStart: rs, radiusEnd: re,
244 resolution: Math.floor(rs*2*2) 244 resolution: Math.floor(rs*2*2)
245 }).subtract(CSG.cylinder({ 245 }).subtract(CSG.cylinder({
246 start:[0,0,-1], end:[0,0,o.l+1], radius: o.sd, 246 start:[0,0,-1], end:[0,0,o.l+1], radius: o.sd,
247 //resolution: Math.floor(o.sd*2*2) 247 //resolution: Math.floor(o.sd*2*2)
248 })); 248 }));
249 rv.properties.top_connector = new CSG.Connector([0,0,o.l],[0,0,-1],[1,0,0]); 249 rv.properties.top_connector = new CSG.Connector([0,0,o.l],[0,0,-1],[1,0,0]);
250 rv.properties.bottom_connector = new CSG.Connector([0,0,0],[0,0,1],[1,0,0]); 250 rv.properties.bottom_connector = new CSG.Connector([0,0,0],[0,0,1],[1,0,0]);
251 var nuthole = nut(CONFIG.nut); 251 var nuthole = nut(CONFIG.nut);
252 rv = rv.subtract(nuthole.connectTo( 252 rv = rv.subtract(nuthole.connectTo(
253 nuthole.properties.axis_connector, rv.properties.bottom_connector, 253 nuthole.properties.axis_connector, rv.properties.bottom_connector,
254 false, 0 254 false, 0
255 )); 255 ));
256 return rv.intersect(CSG.cylinder({start:[0,0,0],end:[0,0,o.l],radius:6/*TODO:calculate*/})); 256 return rv.intersect(CSG.cylinder({start:[0,0,0],end:[0,0,o.l],radius:6/*TODO:calculate*/}));
257 }, 257 },
258 platform_bb: function platform_bb() { 258 platform_bb: function platform_bb() {
259 var e = CONFIG.effector; 259 var e = CONFIG.effector;
260 var r = U.hypotenuse(e.rods_apart/2,e.o+e.rodend.screw_d/2+e.cone.shell); 260 var r = U.hypotenuse(e.rods_apart/2,e.o+e.rodend.screw_d/2+e.cone.shell);
261 var rv = CSG.sphere({ 261 var rv = CSG.sphere({
262 center: [0,0,e.h/2], radius: r, 262 center: [0,0,e.h/2], radius: r,
263 resolution: r*2*2 263 resolution: r*2*2
264 }).intersect(CSG.cube({ 264 }).intersect(CSG.cube({
265 corner1: [-r,-r,0], corner2: [r,r,e.h] 265 corner1: [-r,-r,0], corner2: [r,r,e.h]
266 })); 266 }));
267 rv.properties.base_connector = new CSG.Connector([0,0,0],[0,0,1],[1,0,0]); 267 rv.properties.base_connector = new CSG.Connector([0,0,0],[0,0,1],[1,0,0]);
268 return rv; 268 return rv;
269 }, 269 },
270 effector: function effector_effector() { 270 effector: function effector_effector() {
271 var e = CONFIG.effector; 271 var e = CONFIG.effector;
272 var conel = e.rodend.screw_l-e.rodend.joint_w; 272 var conel = e.rodend.screw_l-e.rodend.joint_w;
273 var nutr = CONFIG.nut.w/2/Math.cos(Math.PI/6); 273 var nutr = CONFIG.nut.w/2/Math.cos(Math.PI/6);
274 var cone = this.cone({sd:e.rodend.screw_d/2,l:conel,s:e.cone.shell,a:e.cone.angle}); 274 var cone = this.cone({sd:e.rodend.screw_d/2,l:conel,s:e.cone.shell,a:e.cone.angle});
275 var rcorner = U.hypotenuse(e.o-e.rodend.screw_d/2-e.cone.shell,e.rods_apart/2)-3.85; //XXX:config/calc 275 var rcorner = U.hypotenuse(e.o-e.rodend.screw_d/2-e.cone.shell,e.rods_apart/2)-3.85; //XXX:config/calc
276 var ropen = E3DV6.dimensions.big_d/2+e.hotend.margin; 276 var ropen = E3DV6.dimensions.big_d/2+e.hotend.margin;
277 var rmount = this.rmount = (rcorner+ropen)/2; 277 var rmount = this.rmount = (rcorner+ropen)/2;
278 var rv = []; 278 var rv = [];
279 for(var a=0;a<360;a+=120) { 279 for(var a=0;a<360;a+=120) {
280 rv.push(union([-1,1].map(function(s) { 280 rv.push(union([-1,1].map(function(s) {
281 return cone.connectTo(cone.properties.top_connector, 281 return cone.connectTo(cone.properties.top_connector,
282 new CSG.Connector([s*e.rods_apart/2,e.o,e.h/2],[-s,0,0],[0,0,1]), 282 new CSG.Connector([s*e.rods_apart/2,e.o,e.h/2],[-s,0,0],[0,0,1]),
283 false, 0); 283 false, 0);
284 })).union(CSG.cube({ 284 })).union(CSG.cube({
285 corner1:[e.rods_apart/2-conel+.1,e.o-nutr,0], 285 corner1:[e.rods_apart/2-conel+.1,e.o-nutr,0],
286 corner2:[-e.rods_apart/2+conel-.1, 286 corner2:[-e.rods_apart/2+conel-.1,
287 -rcorner, 287 -rcorner,
288 e.h] 288 e.h]
289 })).rotateZ(a)); 289 })).rotateZ(a));
290 } 290 }
291 rv.push(CSG.cylinder({ 291 rv.push(CSG.cylinder({
292 start:[0,0,0], end:[0,0,e.h], 292 start:[0,0,0], end:[0,0,e.h],
293 radius: U.hypotenuse(e.o-nutr,e.rods_apart/2-conel) 293 radius: U.hypotenuse(e.o-nutr,e.rods_apart/2-conel)
294 })); 294 }));
295 rv = union(rv).intersect(this.platform_bb()).subtract(CSG.cylinder({ 295 rv = union(rv).intersect(this.platform_bb()).subtract(CSG.cylinder({
296 start:[0,0,-1], end:[0,0,e.h+1], 296 start:[0,0,-1], end:[0,0,e.h+1],
297 radius: ropen, resolution: ropen*4 297 radius: ropen, resolution: ropen*4
298 })).subtract([/*0, probe here*/120,240].map(function(x) { /* nut pockets */ 298 })).subtract([/*0, probe here*/120,240].map(function(x) { /* nut pockets */
299 return CSG.cube({ 299 return CSG.cube({
300 corner1:[-CONFIG.nut.w/2,0,(e.h-CONFIG.nut.h)/2], 300 corner1:[-CONFIG.nut.w/2,0,(e.h-CONFIG.nut.h)/2],
301 corner2:[CONFIG.nut.w/2,-rcorner-1,(e.h+CONFIG.nut.h)/2] 301 corner2:[CONFIG.nut.w/2,-rcorner-1,(e.h+CONFIG.nut.h)/2]
302 }).union(CSG.cylinder({ 302 }).union(CSG.cylinder({
303 start:[0,-rmount,-1], end:[0,-rmount,e.h+1], 303 start:[0,-rmount,-1], end:[0,-rmount,e.h+1],
304 radius: 3/2 // XXX: 304 radius: 3/2 // XXX:
305 })).subtract(CSG.cylinder({ 305 })).subtract(CSG.cylinder({
306 start:[0,-rmount,(e.h+CONFIG.nut.h)/2], 306 start:[0,-rmount,(e.h+CONFIG.nut.h)/2],
307 end:[0,-rmount,(e.h+CONFIG.nut.h)/2+PRINT.layer_height*3/2], 307 end:[0,-rmount,(e.h+CONFIG.nut.h)/2+PRINT.layer_height*3/2],
308 radius: 3/2+.1 308 radius: 3/2+.1
309 })).rotateZ(x); 309 })).rotateZ(x);
310 })).subtract( CSG.cylinder({ // pulldown screw 310 })).subtract( CSG.cylinder({ // pulldown screw
311 start: [0,-rcorner+e.mswitch.size[1]+PRINT.extrusion_width+3/2/*XXX:conf*/,-1], 311 start: [0,-rcorner+e.mswitch.size[1]+PRINT.extrusion_width+3/2/*XXX:conf*/,-1],
312 end: [0,-rcorner+e.mswitch.size[1]+PRINT.extrusion_width+3/2/*XXX:conf*/,e.h+1], 312 end: [0,-rcorner+e.mswitch.size[1]+PRINT.extrusion_width+3/2/*XXX:conf*/,e.h+1],
313 radius: 3/2+1 /*XXX: config */ 313 radius: 3/2+1 /*XXX: config */
314 })).subtract( CSG.cylinder({ /* switch-screw */ 314 })).subtract( CSG.cylinder({ /* switch-screw */
315 start: [e.mswitch.switch_x,-rcorner+e.mswitch.size[1]/2,-1], 315 start: [e.mswitch.switch_x,-rcorner+e.mswitch.size[1]/2,-1],
316 end: [e.mswitch.switch_x,-rcorner+e.mswitch.size[1]/2,e.h+1], 316 end: [e.mswitch.switch_x,-rcorner+e.mswitch.size[1]/2,e.h+1],
317 radius: e.mswitch.screw.d/2 317 radius: e.mswitch.screw.d/2
318 })); 318 }));
319 // add hinges 319 // add hinges
320 rv.properties.hinge_connector=new CSG.Properties(); 320 rv.properties.hinge_connector=new CSG.Properties();
321 var hinges_apart=e.rods_apart/2-conel; 321 var hinges_apart=e.rods_apart/2-conel;
322 rv = rv.union([-1,1].map(function hinge(s) { 322 rv = rv.union([-1,1].map(function hinge(s) {
323 rv.properties.hinge_connector[s]=new CSG.Connector([s*hinges_apart,e.o,e.h+e.hinge.h],[s,0,0],[0,0,1]); 323 rv.properties.hinge_connector[s]=new CSG.Connector([s*hinges_apart,e.o,e.h+e.hinge.h],[s,0,0],[0,0,1]);
324 return CSG.cube({ 324 return CSG.cube({
325 corner1: [s*hinges_apart,e.o-e.hinge.margin-e.hinge.d/2,e.h], 325 corner1: [s*hinges_apart,e.o-e.hinge.margin-e.hinge.d/2,e.h],
326 corner2: [s*(hinges_apart+e.hinge.w),e.o+e.hinge.margin+e.hinge.d/2,e.h+e.hinge.h] 326 corner2: [s*(hinges_apart+e.hinge.w),e.o+e.hinge.margin+e.hinge.d/2,e.h+e.hinge.h]
327 }).union(CSG.cylinder({ 327 }).union(CSG.cylinder({
328 start: [s*hinges_apart,e.o,e.h+e.hinge.h], 328 start: [s*hinges_apart,e.o,e.h+e.hinge.h],
329 end: [s*(hinges_apart+e.hinge.w),e.o,e.h+e.hinge.h], 329 end: [s*(hinges_apart+e.hinge.w),e.o,e.h+e.hinge.h],
330 radius: e.hinge.d/2+e.hinge.margin 330 radius: e.hinge.d/2+e.hinge.margin
331 })).subtract(CSG.cylinder({ 331 })).subtract(CSG.cylinder({
332 start: [s*(hinges_apart-1),e.o,e.h+e.hinge.h], 332 start: [s*(hinges_apart-1),e.o,e.h+e.hinge.h],
333 end: [s*(hinges_apart+e.hinge.w+1),e.o,e.h+e.hinge.h], 333 end: [s*(hinges_apart+e.hinge.w+1),e.o,e.h+e.hinge.h],
334 radius: e.hinge.d/2 334 radius: e.hinge.d/2
335 })); 335 }));
336 })); 336 }));
337 // add clamp guides 337 // add clamp guides
338 var cgrr = e.guide.width/3; 338 var cgrr = e.guide.width/3;
339 rv = rv.union([-1,1].map(function guide(s) { 339 rv = rv.union([-1,1].map(function guide(s) {
340 return CSG.roundedCube({ 340 return CSG.roundedCube({
341 center: [s*(e.mswitch.size[0]+PRINT.slide_tolerance+e.guide.width)/2,-rcorner+e.guide.length/2,e.h+e.guide.height/2-cgrr], 341 center: [s*(e.mswitch.size[0]+PRINT.slide_tolerance+e.guide.width)/2,-rcorner+e.guide.length/2,e.h+e.guide.height/2-cgrr],
342 radius: [e.guide.width/2,e.guide.length/2,e.guide.height/2+cgrr], 342 radius: [e.guide.width/2,e.guide.length/2,e.guide.height/2+cgrr],
343 roundradius: cgrr 343 roundradius: cgrr
344 }).intersect(CSG.cube({ 344 }).intersect(CSG.cube({
345 center: [s*(e.mswitch.size[0]+PRINT.slide_tolerance+e.guide.width)/2,-rcorner+e.guide.length/2,e.h+e.guide.height/2], 345 center: [s*(e.mswitch.size[0]+PRINT.slide_tolerance+e.guide.width)/2,-rcorner+e.guide.length/2,e.h+e.guide.height/2],
346 radius: [e.guide.width/2,e.guide.length/2,e.guide.height/2+.1], 346 radius: [e.guide.width/2,e.guide.length/2,e.guide.height/2+.1],
347 roundradius: cgrr 347 roundradius: cgrr
348 })); 348 }));
349 })); 349 }));
350 rv.properties.grove_connector = new CSG.Connector([0,0,e.h+e.hinge.e+6/2],[0,0,1],[1,0,0]); 350 rv.properties.grove_connector = new CSG.Connector([0,0,e.h+e.hinge.e+6/2],[0,0,1],[1,0,0]);
351 rv.properties.rcorner = rcorner; 351 rv.properties.rcorner = rcorner;
352 return rv.setColor([0.4,0.8,0.4,0.9]); 352 return rv.setColor([0.4,0.8,0.4,0.9]);
353 }, 353 },
354 hinged: function effector_hinged(o) { 354 hinged: function effector_hinged(o) {
355 var e = CONFIG.effector; 355 var e = CONFIG.effector;
356 var conel = e.rodend.screw_l-e.rodend.joint_w; 356 var conel = e.rodend.screw_l-e.rodend.joint_w;
357 var hinges_apart = e.rods_apart/2-conel; 357 var hinges_apart = e.rods_apart/2-conel;
358 var hhr = e.o-e.hinge.d/2-e.hinge.margin; // hotend holder radius 358 var hhr = e.o-e.hinge.d/2-e.hinge.margin; // hotend holder radius
359 var hhh = CONFIG.hotend.groove.h+CONFIG.hotend.ungroove.above; 359 var hhh = CONFIG.hotend.groove.h+CONFIG.hotend.ungroove.above;
360 var rv = CSG.cylinder({ /* hinge */ 360 var rv = CSG.cylinder({ /* hinge */
361 start: [-hinges_apart+PRINT.slide_tolerance,e.o,e.h+e.hinge.h], 361 start: [-hinges_apart+PRINT.slide_tolerance,e.o,e.h+e.hinge.h],
362 end: [hinges_apart-PRINT.slide_tolerance,e.o,e.h+e.hinge.h], 362 end: [hinges_apart-PRINT.slide_tolerance,e.o,e.h+e.hinge.h],
363 radius: e.hinge.d/2+e.hinge.margin 363 radius: e.hinge.d/2+e.hinge.margin
364 }).union( /* lower hotend holder */ 364 }).union( /* lower hotend holder */
365 CSG.cylinder({ 365 CSG.cylinder({
366 start: [0,0,e.h+e.hinge.e], end: [0,0,e.h+e.hinge.e+CONFIG.hotend.groove.h], 366 start: [0,0,e.h+e.hinge.e], end: [0,0,e.h+e.hinge.e+CONFIG.hotend.groove.h],
367 radius: hhr 367 radius: hhr
368 }).subtract(CSG.cylinder({ 368 }).subtract(CSG.cylinder({
369 start: [0,0,e.h+e.hinge.e-1], end: [0,0,e.h+e.hinge.e+CONFIG.hotend.groove.h+1], 369 start: [0,0,e.h+e.hinge.e-1], end: [0,0,e.h+e.hinge.e+CONFIG.hotend.groove.h+1],
370 radius: CONFIG.hotend.groove.d/2 +PRINT.fit_tolerance 370 radius: CONFIG.hotend.groove.d/2 +PRINT.fit_tolerance
371 })) 371 }))
372 ).union( /* upper hotend holder */ 372 ).union( /* upper hotend holder */
373 CSG.cylinder({ 373 CSG.cylinder({
374 start: [0,0,e.h+e.hinge.e+CONFIG.hotend.groove.h], 374 start: [0,0,e.h+e.hinge.e+CONFIG.hotend.groove.h],
375 end: [0,0,e.h+e.hinge.e+CONFIG.hotend.groove.h+CONFIG.hotend.ungroove.above], 375 end: [0,0,e.h+e.hinge.e+CONFIG.hotend.groove.h+CONFIG.hotend.ungroove.above],
376 radius: hhr 376 radius: hhr
377 }).subtract(CSG.cylinder({ 377 }).subtract(CSG.cylinder({
378 start: [0,0,e.h+e.hinge.e+CONFIG.hotend.groove.h-1], 378 start: [0,0,e.h+e.hinge.e+CONFIG.hotend.groove.h-1],
379 end: [0,0,e.h+e.hinge.e+CONFIG.hotend.groove.h+CONFIG.hotend.ungroove.above+1], 379 end: [0,0,e.h+e.hinge.e+CONFIG.hotend.groove.h+CONFIG.hotend.ungroove.above+1],
380 radius: CONFIG.hotend.ungroove.d/2 +PRINT.fit_tolerance 380 radius: CONFIG.hotend.ungroove.d/2 +PRINT.fit_tolerance
381 })) 381 }))
382 ).union( /* connect mount with hinge */ 382 ).union( /* connect mount with hinge */
383 CSG.cube({ 383 CSG.cube({
384 corner1: [-hinges_apart+PRINT.slide_tolerance,CONFIG.hotend.ungroove.d/2+PRINT.fit_tolerance,e.h+e.hinge.e], 384 corner1: [-hinges_apart+PRINT.slide_tolerance,CONFIG.hotend.ungroove.d/2+PRINT.fit_tolerance,e.h+e.hinge.e],
385 corner2: [hinges_apart-PRINT.slide_tolerance,e.o,e.h+e.hinge.h+e.hinge.d/2+e.hinge.margin] 385 corner2: [hinges_apart-PRINT.slide_tolerance,e.o,e.h+e.hinge.h+e.hinge.d/2+e.hinge.margin]
386 }) 386 })
387 ).subtract( /* hinge screwhole */ 387 ).subtract( /* hinge screwhole */
388 CSG.cylinder({ 388 CSG.cylinder({
389 start: [-hinges_apart-1,e.o,e.h+e.hinge.h], 389 start: [-hinges_apart-1,e.o,e.h+e.hinge.h],
390 end: [hinges_apart+1,e.o,e.h+e.hinge.h], 390 end: [hinges_apart+1,e.o,e.h+e.hinge.h],
391 radius: e.hinge.d/2 391 radius: e.hinge.d/2
392 }) 392 })
393 ).union( /* hold clamp together */ 393 ).union( /* hold clamp together */
394 [-1,1].map(function(s) { 394 [-1,1].map(function(s) {
395 return CSG.roundedCube({ 395 return CSG.roundedCube({
396 corner1: [s*(-hhr-e.clamp.margin*2-e.clamp.d),-e.clamp.shell,e.h+e.hinge.e], 396 corner1: [s*(-hhr-e.clamp.margin*2-e.clamp.d),-e.clamp.shell,e.h+e.hinge.e],
397 corner2: [s*(-CONFIG.hotend.ungroove.d/2-PRINT.fit_tolerance),+e.clamp.shell,e.h+e.hinge.e+hhh], 397 corner2: [s*(-CONFIG.hotend.ungroove.d/2-PRINT.fit_tolerance),+e.clamp.shell,e.h+e.hinge.e+hhh],
398 roundradius: 1.5 398 roundradius: 1.5
399 }); 399 });
400 }) 400 })
401 ).subtract( /* screws for holding clamp */ 401 ).subtract( /* screws for holding clamp */
402 [-1,1].map(function(s) { 402 [-1,1].map(function(s) {
403 var nuthole = nut(CONFIG.nut); 403 var nuthole = nut(CONFIG.nut);
404 var x = s*(-hhr-e.clamp.margin-e.clamp.d/2); 404 var x = s*(-hhr-e.clamp.margin-e.clamp.d/2);
405 return CSG.cylinder({ 405 return CSG.cylinder({
406 start: [x,-e.clamp.shell-1,e.h+e.hinge.e+hhh/2], 406 start: [x,-e.clamp.shell-1,e.h+e.hinge.e+hhh/2],
407 end: [x,e.clamp.shell+1,e.h+e.hinge.e+hhh/2], 407 end: [x,e.clamp.shell+1,e.h+e.hinge.e+hhh/2],
408 radius: e.clamp.d/2 408 radius: e.clamp.d/2
409 }).union(nuthole.connectTo( 409 }).union(nuthole.connectTo(
410 nuthole.properties.axis_connector, 410 nuthole.properties.axis_connector,
411 new CSG.Connector([x,e.clamp.shell,e.h+e.hinge.e+hhh/2],[0,-1,0],[0,0,1]), 411 new CSG.Connector([x,e.clamp.shell,e.h+e.hinge.e+hhh/2],[0,-1,0],[0,0,1]),
412 false, 0 412 false, 0
413 )).union(CSG.cylinder({ 413 )).union(CSG.cylinder({
414 start: [x,-e.clamp.shell-1,e.h+e.hinge.e+hhh/2], 414 start: [x,-e.clamp.shell-1,e.h+e.hinge.e+hhh/2],
415 end: [x,0,e.h+e.hinge.e+hhh/2], 415 end: [x,0,e.h+e.hinge.e+hhh/2],
416 radius: e.clamp.d/2+PRINT.slide_tolerance 416 radius: e.clamp.d/2+PRINT.slide_tolerance
417 })); 417 }));
418 }) 418 })
419 ); 419 );
420 var ms = o.microswitch; 420 var ms = o.microswitch;
421 var msedge = o.effector.properties.rcorner; 421 var msedge = o.effector.properties.rcorner;
422 var msh = 9.5; // microswitch holes apart 422 var msh = 9.5; // microswitch holes apart
423 var mshh = Math.abs(ms.properties.switch_connector.point.z-ms.properties.screw_connector[0].point.z); // microswitch holes height 423 var mshh = Math.abs(ms.properties.switch_connector.point.z-ms.properties.screw_connector[0].point.z); // microswitch holes height
424 rv = rv.union(CSG.cube({ // connect clamp with microswitch 424 rv = rv.union(CSG.cube({ // connect clamp with microswitch
425 corner1: [-ms.properties.microswitch.size.x/2,-msedge+.1,e.h+e.hinge.e], 425 corner1: [-ms.properties.microswitch.size.x/2,-msedge+.1,e.h+e.hinge.e],
426 corner2: [+ms.properties.microswitch.size.x/2,-CONFIG.hotend.ungroove.d/2-PRINT.fit_tolerance,e.h+e.hinge.e+hhh] 426 corner2: [+ms.properties.microswitch.size.x/2,-CONFIG.hotend.ungroove.d/2-PRINT.fit_tolerance,e.h+e.hinge.e+hhh]
427 })).union([-msh/2,msh/2].map(function(x) { // shell for microswitch screws 427 })).union([-msh/2,msh/2].map(function(x) { // shell for microswitch screws
428 return CSG.roundedCylinder({ 428 return CSG.roundedCylinder({
429 start: [x,-CONFIG.hotend.ungroove.d/2-PRINT.fit_tolerance-(e.mswitch.screw.d/2+e.mswitch.screw.s),e.h+e.hinge.e+mshh], 429 start: [x,-CONFIG.hotend.ungroove.d/2-PRINT.fit_tolerance-(e.mswitch.screw.d/2+e.mswitch.screw.s),e.h+e.hinge.e+mshh],
430 end: [x,-msedge+ms.properties.microswitch.size.y,e.h+e.hinge.e+mshh], 430 end: [x,-msedge+ms.properties.microswitch.size.y,e.h+e.hinge.e+mshh],
431 radius: e.mswitch.screw.d/2+e.mswitch.screw.s 431 radius: e.mswitch.screw.d/2+e.mswitch.screw.s
432 }); 432 });
433 })).subtract(CSG.cube({ // cut off excess if any 433 })).subtract(CSG.cube({ // cut off excess if any
434 corner1:[-hhr,-msedge+ms.properties.microswitch.size.y,e.h+e.hinge.e-1], 434 corner1:[-hhr,-msedge+ms.properties.microswitch.size.y,e.h+e.hinge.e-1],
435 corner2:[hhr,-msedge-1,e.h+e.hinge.e+hhh+e.mswitch.screw.d+e.mswitch.screw.s+1] 435 corner2:[hhr,-msedge-1,e.h+e.hinge.e+hhh+e.mswitch.screw.d+e.mswitch.screw.s+1]
436 })).subtract([-msh/2,msh/2].map(function(x) { return CSG.roundedCylinder({ // screwholes 436 })).subtract([-msh/2,msh/2].map(function(x) { return CSG.roundedCylinder({ // screwholes
437 start: [x,-CONFIG.hotend.ungroove.d/2-PRINT.fit_tolerance-(e.mswitch.screw.d/2+e.mswitch.screw.s),e.h+e.hinge.e+mshh], 437 start: [x,-CONFIG.hotend.ungroove.d/2-PRINT.fit_tolerance-(e.mswitch.screw.d/2+e.mswitch.screw.s),e.h+e.hinge.e+mshh],
438 end: [x,-msedge+ms.properties.microswitch.size.y,e.h+e.hinge.e+mshh], 438 end: [x,-msedge+ms.properties.microswitch.size.y,e.h+e.hinge.e+mshh],
439 radius: e.mswitch.screw.d/2 439 radius: e.mswitch.screw.d/2
440 })})).subtract(CSG.cylinder({ // pulldown screw 440 })})).subtract(CSG.cylinder({ // pulldown screw
441 start:[0,-msedge+ms.properties.microswitch.size.y+3/2/*XXX:config*/+PRINT.extrusion_width,e.h+e.hinge.e-1], 441 start:[0,-msedge+ms.properties.microswitch.size.y+3/2/*XXX:config*/+PRINT.extrusion_width,e.h+e.hinge.e-1],
442 end:[0,-msedge+ms.properties.microswitch.size.y+3/2/*XXX:config*/+PRINT.extrusion_width,e.h+e.hinge.e+hhh+1], 442 end:[0,-msedge+ms.properties.microswitch.size.y+3/2/*XXX:config*/+PRINT.extrusion_width,e.h+e.hinge.e+hhh+1],
443 radius: 3/2/*XXX:config*/ 443 radius: 3/2/*XXX:config*/
444 })); 444 }));
445 rv.properties.microswitch_screw_connector = new CSG.Properties(); 445 rv.properties.microswitch_screw_connector = new CSG.Properties();
446 [-msh/2,msh/2].forEach(function(x,i) { 446 [-msh/2,msh/2].forEach(function(x,i) {
447 rv.properties.microswitch_screw_connector[i] = new CSG.Connector( 447 rv.properties.microswitch_screw_connector[i] = new CSG.Connector(
448 [x,-msedge,e.h+e.hinge.e+mshh], 448 [x,-msedge,e.h+e.hinge.e+mshh],
449 [0,1,0], [0,0,-1] 449 [0,1,0], [0,0,-1]
450 ); 450 );
451 }); 451 });
452 return rv.setColor([0.3,0.8,0.3,0.9]); 452 return rv.setColor([0.3,0.8,0.3,0.9]);
453 }, 453 },
454 split_hinged: function effector_split_hinged(hinged) { 454 split_hinged: function effector_split_hinged(hinged) {
455 var e = CONFIG.effector; 455 var e = CONFIG.effector;
456 var b = hinged.getBounds(); 456 var b = hinged.getBounds();
457 var ymax = Math.max(Math.abs(b[0].y),Math.abs(b[1].y)); 457 var ymax = Math.max(Math.abs(b[0].y),Math.abs(b[1].y));
458 var zmax = Math.max(b[0].z,b[1].z); 458 var zmax = Math.max(b[0].z,b[1].z);
459 return [-1,1].map(function(s) { 459 return [-1,1].map(function(s) {
460 return hinged.intersect(CSG.cube({ 460 return hinged.intersect(CSG.cube({
461 corner1: [Math.min(b[0].x,b[1].x)-1,s*e.clamp.split/2,-zmax-1], 461 corner1: [Math.min(b[0].x,b[1].x)-1,s*e.clamp.split/2,-zmax-1],
462 corner2: [Math.max(b[0].x,b[1].x)+1,s*(ymax+1),zmax+1] 462 corner2: [Math.max(b[0].x,b[1].x)+1,s*(ymax+1),zmax+1]
463 })); 463 }));
464 }); 464 });
465 }, 465 },
466 fanholder: function effector_fanholder() { 466 fanholder: function effector_fanholder() {
467 var fh = CONFIG.effector.fanholder; 467 var fh = CONFIG.effector.fanholder;
468 var od = fh.screw.d+2*fh.screw.m; 468 var od = fh.screw.d+2*fh.screw.m;
469 return linear_extrude({height:fh.w},hull( 469 return linear_extrude({height:fh.w},hull(
470 CAG.circle({center:[0,-this.rmount],radius:od/2}), 470 CAG.circle({center:[0,-this.rmount],radius:od/2}),
471 CAG.circle({center:[0,-fh.r+od/2+fh.w/2],radius:fh.w/2}) 471 CAG.circle({center:[0,-fh.r+od/2+fh.w/2],radius:fh.w/2})
472 )).translate([0,0,-fh.w]).union( 472 )).translate([0,0,-fh.w]).union(
473 linear_extrude({height:fh.w},hull( 473 linear_extrude({height:fh.w},hull(
474 CAG.circle({center:[fh.w/2,-this.rmount-od/2-fh.w/2],radius:fh.w/2}), 474 CAG.circle({center:[fh.w/2,-this.rmount-od/2-fh.w/2],radius:fh.w/2}),
475 CAG.circle({center:[od/2,-fh.r],radius:od/2}) 475 CAG.circle({center:[od/2,-fh.r],radius:od/2})
476 )).rotateY(90).translate([-fh.w/2,0,0]) 476 )).rotateY(90).translate([-fh.w/2,0,0])
477 ).subtract( CSG.cylinder({ 477 ).subtract( CSG.cylinder({
478 start: [-fh.w,-fh.r,-od/2], 478 start: [-fh.w,-fh.r,-od/2],
479 end: [fh.w,-fh.r,-od/2], 479 end: [fh.w,-fh.r,-od/2],
480 radius: fh.screw.d/2 480 radius: fh.screw.d/2
481 })).subtract( CSG.cylinder({ 481 })).subtract( CSG.cylinder({
482 start: [0,-this.rmount,1], 482 start: [0,-this.rmount,1],
483 end: [0,-this.rmount,-fh.w-1], 483 end: [0,-this.rmount,-fh.w-1],
484 radius: fh.screw.d/2 484 radius: fh.screw.d/2
485 })).setColor([0.3,0.8,0.3,0.9]).rotateZ(-120); 485 })).setColor([0.3,0.8,0.3,0.9]).rotateZ(-120);
486 } 486 }
487}; 487};
488 488
489function columns() { 489function columns() {
490 var rv = [0,1,2].map(function(x) { 490 var rv = [0,1,2].map(function(x) {
491 return union(vector_char(0,0,String.fromCharCode('A'.charCodeAt(0)+x)).segments.map(function(x) { 491 return union(vector_char(0,0,String.fromCharCode('A'.charCodeAt(0)+x)).segments.map(function(x) {
492 return rectangular_extrude(x,{w:2,h:1}); 492 return rectangular_extrude(x,{w:2,h:1});
493 })).center().rotateX(90).translate([0,50,0]).rotateZ(x*120+120); 493 })).center().rotateX(90).translate([0,50,0]).rotateZ(x*120+120);
494 }); 494 });
495 return union(rv); 495 return union(rv);
496} 496}
497 497
498function microswitch() { 498function microswitch() {
499 var screw_connector = new CSG.Properties(); 499 var screw_connector = new CSG.Properties();
500 var rv = CSG.cube({ center:[0,0,2.5],radius: [19.8/2,6/2,10/2] }).union( 500 var rv = CSG.cube({ center:[0,0,2.5],radius: [19.8/2,6/2,10/2] }).union(
501 CSG.cube({ center: [2.5,0.5,6], radius: [2/2,3.5/2,5/2] }) 501 CSG.cube({ center: [2.5,0.5,6], radius: [2/2,3.5/2,5/2] })
502 ).union( 502 ).union(
503 [-8,-1,8].map(function(x) { 503 [-8,-1,8].map(function(x) {
504 return CSG.cube({ center:[x,0,0], radius: [0.6/2,3.2/2,13/2] }) 504 return CSG.cube({ center:[x,0,0], radius: [0.6/2,3.2/2,13/2] })
505 }) 505 })
506 ).subtract( 506 ).subtract(
507 [-9.5/2,9.5/2].map(function(x,i) { 507 [-9.5/2,9.5/2].map(function(x,i) {
508 screw_connector[i] = new CSG.Connector([x,6/2,0],[0,-1,0],[0,0,1]); 508 screw_connector[i] = new CSG.Connector([x,6/2,0],[0,-1,0],[0,0,1]);
509 return CSG.cylinder({ 509 return CSG.cylinder({
510 start: [x,-4,0], end: [x,4,0], 510 start: [x,-4,0], end: [x,4,0],
511 radius: 2/2 511 radius: 2/2
512 }) 512 })
513 }) 513 })
514 ); 514 );
515 rv.properties.switch_connector = new CSG.Connector([2.5,0.5,6+5/2],[0,0,1],[0,-1,0]); 515 rv.properties.switch_connector = new CSG.Connector([2.5,0.5,6+5/2],[0,0,1],[0,-1,0]);
516 rv.properties.screw_connector = screw_connector; 516 rv.properties.screw_connector = screw_connector;
517 rv.properties.microswitch = new CSG.Properties(); 517 rv.properties.microswitch = new CSG.Properties();
518 rv.properties.microswitch.size = new CSG.Vector3D( 518 rv.properties.microswitch.size = new CSG.Vector3D(
519 19.8,6,10 519 19.8,6,10
520 ); 520 );
521 return rv; 521 return rv;
522} 522}
523 523
524var FOURWINDS = [0,90,180,270]; 524var FOURWINDS = [0,90,180,270];
525 525
526var E2020 = { 526var E2020 = {
527 outer: 20, thickness: 1.8, 527 outer: 20, thickness: 1.8,
528 roundius: 1, centerhole: 5, 528 roundius: 1, centerhole: 5,
529 slot_width: 6, 529 slot_width: 6,
530 T: { width: 10, thickness: 1.5, depth: 6.5 }, 530 T: { width: 10, thickness: 1.5, depth: 6.5 },
531 531
532 extrusion: function(o) { 532 extrusion: function(o) {
533 if(!o) o = {}; 533 if(!o) o = {};
534 var e = o.extrusion || this; 534 var e = o.extrusion || this;
535 var l = o.l||5; 535 var l = o.l||5;
536 var iy = e.outer/2-e.T.depth; 536 var iy = e.outer/2-e.T.depth;
537 var ix = e.T.width/2-(e.outer/2-iy-e.thickness-e.T.thickness); 537 var ix = e.T.width/2-(e.outer/2-iy-e.thickness-e.T.thickness);
538 var rv = CAG.roundedRectangle({ 538 var rv = CAG.roundedRectangle({
539 corner1: [-e.outer/2,-e.outer/2], corner2: [e.outer/2,e.outer/2], 539 corner1: [-e.outer/2,-e.outer/2], corner2: [e.outer/2,e.outer/2],
540 roundradius: e.roundius 540 roundradius: e.roundius
541 }).subtract( 541 }).subtract(
542 FOURWINDS.map(function(w) { 542 FOURWINDS.map(function(w) {
543 return CAG.fromPoints([ 543 return CAG.fromPoints([
544 [ e.slot_width/2,e.outer/2+1], 544 [ e.slot_width/2,e.outer/2+1],
545 [ e.slot_width/2,e.outer/2-e.thickness], 545 [ e.slot_width/2,e.outer/2-e.thickness],
546 [ e.T.width/2,e.outer/2-e.thickness], 546 [ e.T.width/2,e.outer/2-e.thickness],
547 [ e.T.width/2,e.outer/2-e.thickness-e.T.thickness], 547 [ e.T.width/2,e.outer/2-e.thickness-e.T.thickness],
548 [ ix, iy ], 548 [ ix, iy ],
549 [ -ix, iy ], 549 [ -ix, iy ],
550 [ -e.T.width/2,e.outer/2-e.thickness-e.T.thickness], 550 [ -e.T.width/2,e.outer/2-e.thickness-e.T.thickness],
551 [ -e.T.width/2,e.outer/2-e.thickness], 551 [ -e.T.width/2,e.outer/2-e.thickness],
552 [ -e.slot_width/2,e.outer/2-e.thickness], 552 [ -e.slot_width/2,e.outer/2-e.thickness],
553 [ -e.slot_width/2,e.outer/2+1], 553 [ -e.slot_width/2,e.outer/2+1],
554 ]).rotateZ(w); 554 ]).rotateZ(w);
555 }) 555 })
556 ).subtract(CAG.circle({ 556 ).subtract(CAG.circle({
557 center: [0,0], radius: e.centerhole/2 557 center: [0,0], radius: e.centerhole/2
558 })).extrude({offset:[0,0,l]}); 558 })).extrude({offset:[0,0,l]});
559 rv.properties.c_top=rv.properties.c_left 559 rv.properties.c_top=rv.properties.c_left
560 = new CSG.Connector([0,0,l],[0,0,-1],[1,0,0]); 560 = new CSG.Connector([0,0,l],[0,0,-1],[1,0,0]);
561 rv.properties.c_bottom=rv.properties.c_right 561 rv.properties.c_bottom=rv.properties.c_right
562 = new CSG.Connector([0,0,0],[0,0,1],[1,0,0]); 562 = new CSG.Connector([0,0,0],[0,0,1],[1,0,0]);
563 rv.properties.c_midway = new CSG.Connector([0,0,l/2],[0,0,1],[1,0,0]); 563 rv.properties.c_midway = new CSG.Connector([0,0,l/2],[0,0,1],[1,0,0]);
564 rv.properties.P = new CSG.Connector([0,0,0],[0,0,1],[1,0,0]); 564 rv.properties.P = new CSG.Connector([0,0,0],[0,0,1],[1,0,0]);
565 rv.properties.vitamin = true; 565 rv.properties.vitamin = true;
566 return rv; 566 return rv;
567 }, 567 },
568 568
569 cap: function extrusion_cap(o) { 569 cap: function extrusion_cap(o) {
570 if(!o) o = {}; 570 if(!o) o = {};
571 var e = o.extrusion || this; 571 var e = o.extrusion || this;
572 var thickness = o.thickness||2, l = o.l||5; 572 var thickness = o.thickness||2, l = o.l||5;
573 var rv = CSG.roundedCube({ 573 var rv = CSG.roundedCube({
574 corner1: [-e.outer/2,-e.outer/2,thickness], 574 corner1: [-e.outer/2,-e.outer/2,thickness],
575 corner2: [e.outer/2,e.outer/2,0], 575 corner2: [e.outer/2,e.outer/2,0],
576 roundradius: [e.roundius,e.roundius,0] 576 roundradius: [e.roundius,e.roundius,0]
577 }); 577 });
578 var fw = [0,90,180,270]; // four winds 578 var fw = [0,90,180,270]; // four winds
579 var iy = e.outer/2-e.T.depth; 579 var iy = e.outer/2-e.T.depth;
580 var ix = e.T.width/2-(e.outer/2-iy-e.thickness-e.T.thickness); 580 var ix = e.T.width/2-(e.outer/2-iy-e.thickness-e.T.thickness);
581 rv = rv.union(fw.map(function(w) { 581 rv = rv.union(fw.map(function(w) {
582 return CAG.fromPoints([ 582 return CAG.fromPoints([
583 [ e.slot_width/2,e.outer/2], 583 [ e.slot_width/2,e.outer/2],
584 [ e.slot_width/2,e.outer/2-e.thickness], 584 [ e.slot_width/2,e.outer/2-e.thickness],
585 [ e.T.width/2,e.outer/2-e.thickness], 585 [ e.T.width/2,e.outer/2-e.thickness],
586 [ e.T.width/2,e.outer/2-e.thickness-e.T.thickness], 586 [ e.T.width/2,e.outer/2-e.thickness-e.T.thickness],
587 [ ix, iy ], 587 [ ix, iy ],
588 [ -ix, iy ], 588 [ -ix, iy ],
589 [ -e.T.width/2,e.outer/2-e.thickness-e.T.thickness], 589 [ -e.T.width/2,e.outer/2-e.thickness-e.T.thickness],
590 [ -e.T.width/2,e.outer/2-e.thickness], 590 [ -e.T.width/2,e.outer/2-e.thickness],
591 [ -e.slot_width/2,e.outer/2-e.thickness], 591 [ -e.slot_width/2,e.outer/2-e.thickness],
592 [ -e.slot_width/2,e.outer/2], 592 [ -e.slot_width/2,e.outer/2],
593 ]).extrude({offset:[0,0,l+thickness]}).rotateZ(w); 593 ]).extrude({offset:[0,0,l+thickness]}).rotateZ(w);
594 })); 594 }));
595 rv.properties.P = new CSG.Connector([0,0,0],[0,0,1],[1,0,0]); 595 rv.properties.P = new CSG.Connector([0,0,0],[0,0,1],[1,0,0]);
596 return rv; 596 return rv;
597 } 597 }
598}; 598};
599 599
600var THREEWINDS = [0,120,240]; 600var THREEWINDS = [0,120,240];
601 601
602function base_sides() { 602function base_sides() {
603 return [0,1].map(function(l) { 603 return [0,1].map(function(l) {
604 return THREEWINDS.map(function(w) { 604 return THREEWINDS.map(function(w) {
605 var e = E2020.extrusion({l:CONFIG.base.el}); 605 var e = E2020.extrusion({l:CONFIG.base.el});
606 e = e.connectTo(e.properties.c_midway, 606 e = e.connectTo(e.properties.c_midway,
607 new CSG.Connector([0,-CD.base.mid_inscription_r,CONFIG.extrusion.w/2],[1,0,0],[0,0,1]), 607 new CSG.Connector([0,-CD.base.mid_inscription_r,CONFIG.extrusion.w/2],[1,0,0],[0,0,1]),
608 false, 0); 608 false, 0);
609 return ( e.translate([0,0,CONFIG.foot.h+l*(CONFIG.extrusion.w+CONFIG.base.gap)]) 609 return ( e.translate([0,0,CONFIG.foot.h+l*(CONFIG.extrusion.w+CONFIG.base.gap)])
610 .rotateZ(w) 610 .rotateZ(w)
611 .setColor(CONFIG.color.extrusion) ); 611 .setColor(CONFIG.color.extrusion) );
612 }); 612 });
613 }); 613 });
614} 614}
615function base_extrusions() { 615function base_extrusions() {
616 var rv = union( base_sides().map(function(x){return union(x)}) ); 616 var rv = union( base_sides().map(function(x){return union(x)}) );
617 rv.properties.P = new CSG.Connector([0,0,0],[0,0,1],[1,0,0]); 617 rv.properties.P = new CSG.Connector([0,0,0],[0,0,1],[1,0,0]);
618 return rv; 618 return rv;
619} 619}
620 620
621function columns() { 621function columns() {
622 return THREEWINDS.map(function(w) { 622 return THREEWINDS.map(function(w) {
623 return (E2020.extrusion({l:CONFIG.column.h}) 623 return (E2020.extrusion({l:CONFIG.column.h})
624 .translate([0,CD.base.column_r,CONFIG.foot.h]) 624 .translate([0,CD.base.column_r,CONFIG.foot.h])
625 .rotateZ(w).setColor(CONFIG.color.extrusion) 625 .rotateZ(w).setColor(CONFIG.color.extrusion)
626 ); 626 );
627 }); 627 });
628} 628}
629function column_extrusions() { 629function column_extrusions() {
630 var rv = union( columns() ); 630 var rv = union( columns() );
631 rv.properties.P = new CSG.Connector([0,0,0],[0,0,1],[1,0,0]); 631 rv.properties.P = new CSG.Connector([0,0,0],[0,0,1],[1,0,0]);
632 return rv; 632 return rv;
633} 633}
634 634
635function duet() { 635function duet() {
636 var C = CONFIG.duet; 636 var C = CONFIG.duet;
637 var pholes = new CSG.Properties(); 637 var pholes = new CSG.Properties();
638 var hx = C.hole_spacing.x/2; 638 var hx = C.hole_spacing.x/2;
639 var hy = C.hole_spacing.y/2; 639 var hy = C.hole_spacing.y/2;
640 var hh = { nw: [-1,1], ne: [1,1], se: [1,-1], sw: [-1,-1] }; 640 var hh = { nw: [-1,1], ne: [1,1], se: [1,-1], sw: [-1,-1] };
641 var holes = []; 641 var holes = [];
642 for(w in hh) { 642 for(w in hh) {
643 var h = hh[w],_x=h[0]*hx,_y=h[1]*hy; 643 var h = hh[w],_x=h[0]*hx,_y=h[1]*hy;
644 holes.push(CSG.cylinder({start:[_x,_y,-1],end:[_x,_y,C.pcb_size.z+1],radius:3/2})); 644 holes.push(CSG.cylinder({start:[_x,_y,-1],end:[_x,_y,C.pcb_size.z+1],radius:3/2}));
645 pholes['c_'+w] = new CSG.Connector([_x,_y,0],[0,0,1],[1,0,0]); 645 pholes['c_'+w] = new CSG.Connector([_x,_y,0],[0,0,1],[1,0,0]);
646 } 646 }
647 rv = CSG.cube({ 647 rv = CSG.cube({
648 corner1: [-C.pcb_size.x/2, -C.pcb_size.y/2, 0], 648 corner1: [-C.pcb_size.x/2, -C.pcb_size.y/2, 0],
649 corner2: [ C.pcb_size.x/2, C.pcb_size.y/2, C.pcb_size.z] 649 corner2: [ C.pcb_size.x/2, C.pcb_size.y/2, C.pcb_size.z]
650 }).subtract(holes).setColor(CONFIG.color.pcb).union( 650 }).subtract(holes).setColor(CONFIG.color.pcb).union(
651 CSG.cube({ 651 CSG.cube({
652 corner1: [-C.pcb_size.x/2,-C.hole_spacing.y/2+3,C.pcb_size.z], 652 corner1: [-C.pcb_size.x/2,-C.hole_spacing.y/2+3,C.pcb_size.z],
653 corner2: [ C.pcb_size.x/2, C.hole_spacing.y/2-3,C.h] 653 corner2: [ C.pcb_size.x/2, C.hole_spacing.y/2-3,C.h]
654 }).setColor(CONFIG.color.bulk) 654 }).setColor(CONFIG.color.bulk)
655 ); 655 );
656 rv.properties.holes = pholes; 656 rv.properties.holes = pholes;
657 rv.properties.P = new CSG.Connector([0,0,0],[0,0,1],[1,0,0]); 657 rv.properties.P = new CSG.Connector([0,0,0],[0,0,1],[1,0,0]);
658 rv.properties.vitamin = true; 658 rv.properties.vitamin = true;
659 return rv; 659 return rv;
660} 660}
661 661
662function foot() { 662function foot() {
663 var F = CONFIG.foot; 663 var F = CONFIG.foot;
664 var br = F.bolt.hd/2+F.margin; 664 var br = F.bolt.hd/2+F.margin;
665 var bh = F.zscalefactor*Math.sqrt(Math.pow(F.d/2,2)-Math.pow(br,2)); 665 var bh = F.zscalefactor*Math.sqrt(Math.pow(F.d/2,2)-Math.pow(br,2));
666 var th = F.h-bh; 666 var th = F.h-bh;
667 var r = 2*F.d; 667 var r = 2*F.d;
668 var rv = CSG.sphere({ // botom contorted sphere 668 var rv = CSG.sphere({ // botom contorted sphere
669 center: [0,0,0], radius: F.d/2, resolution: r 669 center: [0,0,0], radius: F.d/2, resolution: r
670 }).scale([1,1,F.zscalefactor]).translate([0,0,bh]).union(CSG.cylinder({ // top hat 670 }).scale([1,1,F.zscalefactor]).translate([0,0,bh]).union(CSG.cylinder({ // top hat
671 start: [0,0,bh], end: [0,0,F.h], radius: F.d/2, resolution: r 671 start: [0,0,bh], end: [0,0,F.h], radius: F.d/2, resolution: r
672 })).intersect(CSG.cylinder({ // cut off excess 672 })).intersect(CSG.cylinder({ // cut off excess
673 start: [0,0,0], end: [0,0,F.h], radius: F.d 673 start: [0,0,0], end: [0,0,F.h], radius: F.d
674 })).subtract([ 674 })).subtract([
675 CSG.cylinder({ // bolt hole 675 CSG.cylinder({ // bolt hole
676 start: [0,0,-1], end: [0,0,F.h+1], radius: F.bolt.d/2+PRINT.slide_tolerance 676 start: [0,0,-1], end: [0,0,F.h+1], radius: F.bolt.d/2+PRINT.slide_tolerance
677 }), CSG.cylinder({ // nut hole 677 }), CSG.cylinder({ // nut hole
678 start: [0,0,F.h-F.nut.h-PRINT.play_tolerance], 678 start: [0,0,F.h-F.nut.h-PRINT.play_tolerance],
679 end: [0,0,F.h], 679 end: [0,0,F.h],
680 radius: F.nut.d/2+PRINT.slide_tolerance, resolution: 6 680 radius: F.nut.d/2+PRINT.slide_tolerance, resolution: 6
681 }), CSG.cylinder({ // bolthead/washer hole 681 }), CSG.cylinder({ // bolthead/washer hole
682 start: [0,0,-1], end: [0,0,F.h-F.nut.h-PRINT.play_tolerance-F.shell], 682 start: [0,0,-1], end: [0,0,F.h-F.nut.h-PRINT.play_tolerance-F.shell],
683 radius: F.bolt.hd/2+PRINT.play_tolerance 683 radius: F.bolt.hd/2+PRINT.play_tolerance
684 }) 684 })
685 ]).union(CSG.cylinder({ // bridging patch 685 ]).union(CSG.cylinder({ // bridging patch
686 start: [0,0,F.h-F.nut.h-PRINT.play_tolerance-PRINT.layer_height], 686 start: [0,0,F.h-F.nut.h-PRINT.play_tolerance-PRINT.layer_height],
687 end: [0,0,F.h-F.nut.h-PRINT.play_tolerance], 687 end: [0,0,F.h-F.nut.h-PRINT.play_tolerance],
688 radius: F.nut.d/2 688 radius: F.nut.d/2
689 })); 689 }));
690 rv.properties.c_column = new CSG.Connector([0,0,F.h],[0,0,1],[1,0,0]); 690 rv.properties.c_column = new CSG.Connector([0,0,F.h],[0,0,1],[1,0,0]);
691 rv.properties.c_shoe = new CSG.Connector([0,0,0],[0,0,1],[1,0,0]); 691 rv.properties.c_shoe = new CSG.Connector([0,0,0],[0,0,1],[1,0,0]);
692 rv.properties.P = new CSG.Connector([0,0,F.h],[0,0,-1],[1,0,0]); 692 rv.properties.P = new CSG.Connector([0,0,F.h],[0,0,-1],[1,0,0]);
693 return rv.setColor(CONFIG.color.parts); 693 return rv.setColor(CONFIG.color.parts);
694} 694}
695function shoe() { 695function shoe() {
696 var F = CONFIG.foot; 696 var F = CONFIG.foot;
697 var rv = CSG.cylinder({ 697 var rv = CSG.cylinder({
698 start: [0,0,0], end: [0,0,F.foot.ho], 698 start: [0,0,0], end: [0,0,F.foot.ho],
699 radius: F.bolt.hd/2+F.margin 699 radius: F.bolt.hd/2+F.margin
700 }).union(CSG.cylinder({ 700 }).union(CSG.cylinder({
701 start: [0,0,0], end: [0,0,F.foot.ho+F.foot.hi], 701 start: [0,0,0], end: [0,0,F.foot.ho+F.foot.hi],
702 radius: F.bolt.hd/2+PRINT.play_tolerance-PRINT.fit_tolerance 702 radius: F.bolt.hd/2+PRINT.play_tolerance-PRINT.fit_tolerance
703 })); 703 }));
704 rv.properties.c_foot = new CSG.Connector([0,0,F.foot.ho],[0,0,1],[1,0,0]); 704 rv.properties.c_foot = new CSG.Connector([0,0,F.foot.ho],[0,0,1],[1,0,0]);
705 rv.properties.P = new CSG.Connector([0,0,0],[0,0,1],[1,0,0]); 705 rv.properties.P = new CSG.Connector([0,0,0],[0,0,1],[1,0,0]);
706 return rv.setColor(CONFIG.color.softparts); 706 return rv.setColor(CONFIG.color.softparts);
707} 707}
708 708
709function duetholder() { 709function duetholder() {
710 var DH = CONFIG.duetholder; 710 var DH = CONFIG.duetholder;
711 var DHD = CD.duetholder; 711 var DHD = CD.duetholder;
712 var hw = DH.bolt.head.d+2*DH.margin; 712 var hw = DH.bolt.head.d+2*DH.margin;
713 var s = DH.bolt.l-CONFIG.extrusion.slotdepth+PRINT.play_tolerance*2; 713 var s = DH.bolt.l-CONFIG.extrusion.slotdepth+PRINT.play_tolerance*2;
714 var lower = CONFIG.foot.h-2*DH.s; 714 var lower = CONFIG.foot.h-2*DH.s;
715 var hl = DHD.distance-CONFIG.extrusion.w; 715 var hl = DHD.distance-CONFIG.extrusion.w;
716 var rv = union([ 716 var rv = union([
717 CSG.cube({ // vertical 717 CSG.cube({ // vertical
718 corner1: [-hw/2,s,CONFIG.extrusion.w], 718 corner1: [-hw/2,s,CONFIG.extrusion.w],
719 corner2: [hw/2,0,-lower] 719 corner2: [hw/2,0,-lower]
720 }), 720 }),
721 CSG.cube({ // horizontal extrusion 721 CSG.cube({ // horizontal extrusion
722 corner1: [-hw/2,-CONFIG.extrusion.w,0], 722 corner1: [-hw/2,-CONFIG.extrusion.w,0],
723 corner2: [ hw/2,0,-s] 723 corner2: [ hw/2,0,-s]
724 }), 724 }),
725 CSG.cube({ // horizontal 725 CSG.cube({ // horizontal
726 corner1: [-hw/2,0,-lower], 726 corner1: [-hw/2,0,-lower],
727 corner2: [hw/2,hl,-lower+DH.s] 727 corner2: [hw/2,hl,-lower+DH.s]
728 }), 728 }),
729 CSG.cylinder({ // boltend of horizontal part 729 CSG.cylinder({ // boltend of horizontal part
730 start: [0,hl,-lower], end: [0,hl,-lower+DH.s], 730 start: [0,hl,-lower], end: [0,hl,-lower+DH.s],
731 radius: hw/2 731 radius: hw/2
732 }) 732 })
733 ]); 733 ]);
734 rv = rv.subtract([ 734 rv = rv.subtract([
735 CSG.cylinder({ // through vertical 735 CSG.cylinder({ // through vertical
736 start: [0,-1,CONFIG.extrusion.w/2], end: [0,s+1,CONFIG.extrusion.w/2], 736 start: [0,-1,CONFIG.extrusion.w/2], end: [0,s+1,CONFIG.extrusion.w/2],
737 radius: DH.bolt.d/2+PRINT.slide_tolerance 737 radius: DH.bolt.d/2+PRINT.slide_tolerance
738 }), 738 }),
739 CSG.cylinder({ // through horizontal to extrusion 739 CSG.cylinder({ // through horizontal to extrusion
740 start: [0,-CONFIG.extrusion.w/2,-s-1], 740 start: [0,-CONFIG.extrusion.w/2,-s-1],
741 end: [0,-CONFIG.extrusion.w/2,1], 741 end: [0,-CONFIG.extrusion.w/2,1],
742 radius: DH.bolt.d/2+PRINT.slide_tolerance 742 radius: DH.bolt.d/2+PRINT.slide_tolerance
743 }), 743 }),
744 CSG.cube({ // cut off 744 CSG.cube({ // cut off
745 corner1: [-hw/2-1,-2*s,0], 745 corner1: [-hw/2-1,-2*s,0],
746 corner2: [hw/2+1,0,-2*s] 746 corner2: [hw/2+1,0,-2*s]
747 }).rotateX(45).translate([0,-CONFIG.extrusion.w,0]), 747 }).rotateX(45).translate([0,-CONFIG.extrusion.w,0]),
748 CSG.cylinder({ // duet bolt 748 CSG.cylinder({ // duet bolt
749 start: [0,hl,-lower], end: [0,hl,-lower+DH.s], 749 start: [0,hl,-lower], end: [0,hl,-lower+DH.s],
750 radius: DH.bolt.d/2+PRINT.slide_tolerance 750 radius: DH.bolt.d/2+PRINT.slide_tolerance
751 }) 751 })
752 ]); 752 ]);
753 var cp = [0,hl,-lower+DH.s]; 753 var cp = [0,hl,-lower+DH.s];
754 rv.properties.duet = new CSG.Properties(); 754 rv.properties.duet = new CSG.Properties();
755 rv.properties.duet.c_sw = new CSG.Connector(cp,[0,0,1],[1,0,0]); 755 rv.properties.duet.c_sw = new CSG.Connector(cp,[0,0,1],[1,0,0]);
756 rv.properties.duet.c_se = new CSG.Connector(cp,[0,0,1],[1,0,0]); 756 rv.properties.duet.c_se = new CSG.Connector(cp,[0,0,1],[1,0,0]);
757 rv.properties.duet.c_ne = new CSG.Connector(cp,[0,0,1],[-Math.cos(Math.PI/3),-Math.sin(Math.PI/3),0]); 757 rv.properties.duet.c_ne = new CSG.Connector(cp,[0,0,1],[-Math.cos(Math.PI/3),-Math.sin(Math.PI/3),0]);
758 rv.properties.duet.c_nw = new CSG.Connector(cp,[0,0,1],[-Math.cos(Math.PI/3),Math.sin(Math.PI/3),0]); 758 rv.properties.duet.c_nw = new CSG.Connector(cp,[0,0,1],[-Math.cos(Math.PI/3),Math.sin(Math.PI/3),0]);
759 rv.properties.c_h = new CSG.Connector([0,-CONFIG.extrusion.w/2,0],[0,0,1],[1,0,0]); 759 rv.properties.c_h = new CSG.Connector([0,-CONFIG.extrusion.w/2,0],[0,0,1],[1,0,0]);
760 rv.properties.c_v = new CSG.Connector([0,0,CONFIG.extrusion.w/2],[0,-1,0],[0,0,1]); 760 rv.properties.c_v = new CSG.Connector([0,0,CONFIG.extrusion.w/2],[0,-1,0],[0,0,1]);
761 rv.properties.P = new CSG.Connector([-hw/2,0,0],[1,0,0],[0,1,0]); 761 rv.properties.P = new CSG.Connector([-hw/2,0,0],[1,0,0],[0,1,0]);
762 return rv.setColor(CONFIG.color.parts); 762 return rv.setColor(CONFIG.color.parts);
763} 763}
764 764
765function heatbed() { 765function heatbed() {
766 var rv = CSG.cylinder({ 766 var rv = CSG.cylinder({
767 start: [0,0,0], end: [0,0,CONFIG.heatbed.h], 767 start: [0,0,0], end: [0,0,CONFIG.heatbed.h],
768 radius: CONFIG.heatbed.r, resolution: 72 768 radius: CONFIG.heatbed.r, resolution: 72
769 }); 769 });
770 var screw = CSG.cylinder({ 770 var screw = CSG.cylinder({
771 start: [0,-CONFIG.heatbed.sr,-1], 771 start: [0,-CONFIG.heatbed.sr,-1],
772 end: [0,-CONFIG.heatbed.sr,CONFIG.heatbed.h+1], 772 end: [0,-CONFIG.heatbed.sr,CONFIG.heatbed.h+1],
773 radius: 3/2 773 radius: 3/2
774 }); 774 });
775 var screws = []; 775 var screws = [];
776 for(var a=0;a<360;a+=60) screws.push(screw.rotateZ(a)); // TODO: connectors 776 for(var a=0;a<360;a+=60) screws.push(screw.rotateZ(a)); // TODO: connectors
777 rv = rv.subtract(screws); 777 rv = rv.subtract(screws);
778 rv.properties.c_glass = new CSG.Connector([0,0,CONFIG.heatbed.h],[0,0,1],[1,0,0]); 778 rv.properties.c_glass = new CSG.Connector([0,0,CONFIG.heatbed.h],[0,0,1],[1,0,0]);
779 rv.properties.P = new CSG.Connector( 779 rv.properties.P = new CSG.Connector(
780 [0,0,-CONFIG.foot.h-CONFIG.extrusion.w*2-CONFIG.base.gap-CONFIG.bedholder.h], 780 [0,0,-CONFIG.foot.h-CONFIG.extrusion.w*2-CONFIG.base.gap-CONFIG.bedholder.h],
781 [0,0,1],[1,0,0]); 781 [0,0,1],[1,0,0]);
782 rv.properties.vitamin = true; 782 rv.properties.vitamin = true;
783 return rv.setColor(CONFIG.color.heatbed); 783 return rv.setColor(CONFIG.color.heatbed);
784} 784}
785function glass() { 785function glass() {
786 var rv = CSG.cylinder({ 786 var rv = CSG.cylinder({
787 start: [0,0,0], end: [0,0,CONFIG.glass.h], 787 start: [0,0,0], end: [0,0,CONFIG.glass.h],
788 radius: CONFIG.glass.r, resolution: 72 788 radius: CONFIG.glass.r, resolution: 72
789 }); 789 });
790 rv.properties.c_bed = new CSG.Connector([0,0,0],[0,0,1],[1,0,0]); 790 rv.properties.c_bed = new CSG.Connector([0,0,0],[0,0,1],[1,0,0]);
791 rv.properties.P = new CSG.Connector([0,0,-CONFIG.foot.h-CONFIG.heatbed.h],[0,0,1],[1,0,0]); 791 rv.properties.P = new CSG.Connector([0,0,-CONFIG.foot.h-CONFIG.heatbed.h],[0,0,1],[1,0,0]);
792 rv.properties.vitamin = true; 792 rv.properties.vitamin = true;
793 return rv.setColor(CONFIG.color.glass); 793 return rv.setColor(CONFIG.color.glass);
794} 794}
795function platform() { 795function platform() {
796 var b = heatbed(); 796 var b = heatbed();
797 var g = glass(); 797 var g = glass();
798 g = g.connectTo(g.properties.c_bed,b.properties.c_glass,false,0); 798 g = g.connectTo(g.properties.c_bed,b.properties.c_glass,false,0);
799 return b.union(g); 799 return b.union(g);
800} 800}
801 801
802function bedholder(params) { 802function bedholder(params) {
803 var h0 = CONFIG.foot.h+CONFIG.extrusion.w*2+CONFIG.base.gap; 803 var h0 = CONFIG.foot.h+CONFIG.extrusion.w*2+CONFIG.base.gap;
804 var e_h=E2020.T.thickness; // height of the bump for extrusion 804 var e_h=E2020.T.thickness; // height of the bump for extrusion
805 var e_w=E2020.slot_width-PRINT.fit_tolerance; // width of the bump for extrusion 805 var e_w=E2020.slot_width-PRINT.fit_tolerance; // width of the bump for extrusion
806 var e_o=E2020.slot_width+PRINT.fit_tolerance; // opening for the T-Nut width 806 var e_o=E2020.slot_width+PRINT.fit_tolerance; // opening for the T-Nut width
807 var rv = CSG.cylinder({ 807 var rv = CSG.cylinder({
808 start: [0,0,h0], end: [0,0,h0+CONFIG.bedholder.h], 808 start: [0,0,h0], end: [0,0,h0+CONFIG.bedholder.h],
809 radiusStart: CD.base.outer_inscription_r, 809 radiusStart: CD.base.outer_inscription_r,
810 radiusEnd: CD.base.outer_inscription_r+CONFIG.bedholder.h/2, 810 radiusEnd: CD.base.outer_inscription_r+CONFIG.bedholder.h/2,
811 resolution: 240 811 resolution: 240
812 }); 812 });
813 rv=rv.intersect(CSG.cube({ 813 rv=rv.intersect(CSG.cube({
814 corner1: [-CONFIG.extrusion.w/2,-CD.base.inner_inscription_r,h0], 814 corner1: [-CONFIG.extrusion.w/2,-CD.base.inner_inscription_r,h0],
815 corner2: [ CONFIG.extrusion.w/2,-CD.base.mid_inscription_r*2,h0+2*CONFIG.bedholder.h] 815 corner2: [ CONFIG.extrusion.w/2,-CD.base.mid_inscription_r*2,h0+2*CONFIG.bedholder.h]
816 })); 816 }));
817 817
818 rv=rv.union(CSG.cube({ // bump to fix on extrusion 818 rv=rv.union(CSG.cube({ // bump to fix on extrusion
819 corner1: [-CONFIG.extrusion.w/2,-CD.base.mid_inscription_r-e_w/2,h0], 819 corner1: [-CONFIG.extrusion.w/2,-CD.base.mid_inscription_r-e_w/2,h0],
820 corner2: [ CONFIG.extrusion.w/2,-CD.base.mid_inscription_r+e_w/2,h0-e_h] 820 corner2: [ CONFIG.extrusion.w/2,-CD.base.mid_inscription_r+e_w/2,h0-e_h]
821 }).subtract( 821 }).subtract(
822 CSG.cube({center:[0,0,0],radius:[(e_o+2*e_h)/(2*Math.sqrt(2)),e_w+2,(e_o+2*e_h)/(2*Math.sqrt(2))]}) 822 CSG.cube({center:[0,0,0],radius:[(e_o+2*e_h)/(2*Math.sqrt(2)),e_w+2,(e_o+2*e_h)/(2*Math.sqrt(2))]})
823 .rotateY(45) 823 .rotateY(45)
824 .translate([0,-CD.base.mid_inscription_r,h0-e_h]) 824 .translate([0,-CD.base.mid_inscription_r,h0-e_h])
825 )); 825 ));
826 826
827 var ebolt_s = CONFIG.bedholder.bolt.l-CONFIG.extrusion.slotdepth+PRINT.play_tolerance*2; 827 var ebolt_s = CONFIG.bedholder.bolt.l-CONFIG.extrusion.slotdepth+PRINT.play_tolerance*2;
828 rv=rv.subtract([ 828 rv=rv.subtract([
829 CSG.cylinder({ // base screw 829 CSG.cylinder({ // base screw
830 start: [0,-CD.base.mid_inscription_r,h0-1], 830 start: [0,-CD.base.mid_inscription_r,h0-1],
831 end: [0,-CD.base.mid_inscription_r,h0+CONFIG.bedholder.h+1], 831 end: [0,-CD.base.mid_inscription_r,h0+CONFIG.bedholder.h+1],
832 radius: CONFIG.bedholder.bolt.d/2+PRINT.screw_tolerance/2 832 radius: CONFIG.bedholder.bolt.d/2+PRINT.screw_tolerance/2
833 }), 833 }),
834 CSG.cylinder({ // base screw head 834 CSG.cylinder({ // base screw head
835 start: [0,-CD.base.mid_inscription_r,h0+ebolt_s], 835 start: [0,-CD.base.mid_inscription_r,h0+ebolt_s],
836 end: [0,-CD.base.mid_inscription_r,h0+CONFIG.bedholder.h+1], 836 end: [0,-CD.base.mid_inscription_r,h0+CONFIG.bedholder.h+1],
837 radius: CONFIG.bedholder.bolt.head.d/2+PRINT.play_tolerance 837 radius: CONFIG.bedholder.bolt.head.d/2+PRINT.play_tolerance
838 }) 838 })
839 ]); 839 ]);
840 840
841 var nuth=h0+CONFIG.bedholder.h*3/4; 841 var nuth=h0+CONFIG.bedholder.h*3/4;
842 rv=rv.subtract([ 842 rv=rv.subtract([
843 CSG.cylinder({ // bed screw 843 CSG.cylinder({ // bed screw
844 start: [0,-CONFIG.heatbed.sr,h0-1], 844 start: [0,-CONFIG.heatbed.sr,h0-1],
845 end: [0,-CONFIG.heatbed.sr,h0+CONFIG.bedholder.h+1], 845 end: [0,-CONFIG.heatbed.sr,h0+CONFIG.bedholder.h+1],
846 radius: CONFIG.bedholder.bolt.d/2+PRINT.screw_tolerance/2 846 radius: CONFIG.bedholder.bolt.d/2+PRINT.screw_tolerance/2
847 }), 847 }),
848 CSG.cube({ // nut pocket 848 CSG.cube({ // nut pocket
849 center: [0,-CONFIG.heatbed.sr,nuth], 849 center: [0,-CONFIG.heatbed.sr,nuth],
850 radius: [CONFIG.extrusion.w/2+1,CONFIG.bedholder.nut.w/2+PRINT.slide_tolerance/2,CONFIG.bedholder.nut.h/2+PRINT.slide_tolerance/2] 850 radius: [CONFIG.extrusion.w/2+1,CONFIG.bedholder.nut.w/2+PRINT.slide_tolerance/2,CONFIG.bedholder.nut.h/2+PRINT.slide_tolerance/2]
851 }) 851 })
852 ]); 852 ]);
853 853
854 rv.properties.P = new CSG.Connector([-CONFIG.extrusion.w/2,-CD.base.mid_inscription_r,h0+CONFIG.bedholder.h/2], 854 rv.properties.P = new CSG.Connector([-CONFIG.extrusion.w/2,-CD.base.mid_inscription_r,h0+CONFIG.bedholder.h/2],
855 [1,0,0],[0,0,1]); 855 [1,0,0],[0,0,1]);
856 return rv.setColor(CONFIG.color.parts); 856 return rv.setColor(CONFIG.color.parts);
857 var bolt_s = CONFIG.bedholder.bolt.l-CONFIG.extrusion.slotdepth+PRINT.play_tolerance*2; 857 var bolt_s = CONFIG.bedholder.bolt.l-CONFIG.extrusion.slotdepth+PRINT.play_tolerance*2;
858 var nuth=h0+CONFIG.bedholder.h*3/4; 858 var nuth=h0+CONFIG.bedholder.h*3/4;
859 var nutth = nuth+CONFIG.bedholder.nut.h/2+PRINT.slide_tolerance/2; 859 var nutth = nuth+CONFIG.bedholder.nut.h/2+PRINT.slide_tolerance/2;
860 var rv = CSG.roundedCube({ 860 var rv = CSG.roundedCube({
861 corner1: [-CONFIG.extrusion.w/2,-CD.base.inner_inscription_r,h0], 861 corner1: [-CONFIG.extrusion.w/2,-CD.base.inner_inscription_r,h0],
862 corner2: [ CONFIG.extrusion.w/2,-CONFIG.heatbed.sr-3/2-CONFIG.bedholder.margin,h0+CONFIG.bedholder.h], 862 corner2: [ CONFIG.extrusion.w/2,-CONFIG.heatbed.sr-3/2-CONFIG.bedholder.margin,h0+CONFIG.bedholder.h],
863 roundradius: CONFIG.bedholder.margin 863 roundradius: CONFIG.bedholder.margin
864 }); 864 });
865 rv = rv.subtract([ 865 rv = rv.subtract([
866 CSG.cylinder({ // base screw 866 CSG.cylinder({ // base screw
867 start: [0,-CD.base.mid_inscription_r,h0-1], 867 start: [0,-CD.base.mid_inscription_r,h0-1],
868 end: [0,-CD.base.mid_inscription_r,h0+CONFIG.bedholder.h+1], 868 end: [0,-CD.base.mid_inscription_r,h0+CONFIG.bedholder.h+1],
869 radius: CONFIG.bedholder.bolt.d/2+PRINT.screw_tolerance/2 869 radius: CONFIG.bedholder.bolt.d/2+PRINT.screw_tolerance/2
870 }), 870 }),
871 CSG.cylinder({ // bed screw 871 CSG.cylinder({ // bed screw
872 start: [0,-CONFIG.heatbed.sr,h0-1], 872 start: [0,-CONFIG.heatbed.sr,h0-1],
873 end: [0,-CONFIG.heatbed.sr,h0+CONFIG.bedholder.h+1], 873 end: [0,-CONFIG.heatbed.sr,h0+CONFIG.bedholder.h+1],
874 radius: CONFIG.bedholder.bolt.d/2+PRINT.screw_tolerance/2 874 radius: CONFIG.bedholder.bolt.d/2+PRINT.screw_tolerance/2
875 }), 875 }),
876 CSG.cube({ // nut pocket 876 CSG.cube({ // nut pocket
877 center: [0,-CONFIG.heatbed.sr,nuth], 877 center: [0,-CONFIG.heatbed.sr,nuth],
878 radius: [CONFIG.extrusion.w/2+1,(CONFIG.bedholder.nut.w+PRINT.slide_tolerance)/2,(CONFIG.bedholder.nut.h+PRINT.slide_tolerance)/2] 878 radius: [CONFIG.extrusion.w/2+1,(CONFIG.bedholder.nut.w+PRINT.slide_tolerance)/2,(CONFIG.bedholder.nut.h+PRINT.slide_tolerance)/2]
879 }), 879 }),
880 CSG.cylinder({ // sink base screw 880 CSG.cylinder({ // sink base screw
881 start: [0,-CD.base.mid_inscription_r,h0+bolt_s], 881 start: [0,-CD.base.mid_inscription_r,h0+bolt_s],
882 end: [0,-CD.base.mid_inscription_r,h0+CONFIG.bedholder.h+1], 882 end: [0,-CD.base.mid_inscription_r,h0+CONFIG.bedholder.h+1],
883 radius: CONFIG.bedholder.bolt.head.d/2+PRINT.play_tolerance 883 radius: CONFIG.bedholder.bolt.head.d/2+PRINT.play_tolerance
884 }) 884 })
885 ]); 885 ]);
886 rv = rv.union(CSG.cylinder({ // patch up for bridging 886 rv = rv.union(CSG.cylinder({ // patch up for bridging
887 start: [0,-CONFIG.heatbed.sr,nutth], end: [0,-CONFIG.heatbed.sr,nutth+PRINT.layer_height], 887 start: [0,-CONFIG.heatbed.sr,nutth], end: [0,-CONFIG.heatbed.sr,nutth+PRINT.layer_height],
888 radius: (CONFIG.bedholder.nut.w+PRINT.slide_tolerance)/2+PRINT.extrusion_width 888 radius: (CONFIG.bedholder.nut.w+PRINT.slide_tolerance)/2+PRINT.extrusion_width
889 })); 889 }));
890 rv = rv.intersect(CSG.cylinder({ // cut off excess 890 rv = rv.intersect(CSG.cylinder({ // cut off excess
891 start: [0,0,h0-1], end: [0,0,h0+CONFIG.bedholder.h+1], 891 start: [0,0,h0-1], end: [0,0,h0+CONFIG.bedholder.h+1],
892 radius: CONFIG.heatbed.r, resolution: 270 892 radius: CONFIG.heatbed.r, resolution: 270
893 })); 893 }));
894 rv.properties.P = new CSG.Connector([0,-CD.base.mid_inscription_r,h0],[0,0,1],[1,0,0]); 894 rv.properties.P = new CSG.Connector([0,-CD.base.mid_inscription_r,h0],[0,0,1],[1,0,0]);
895 return rv.setColor(CONFIG.color.parts); 895 return rv.setColor(CONFIG.color.parts);
896} 896}
897 897
898var PARTS = { 898var PARTS = {
899 wip: function(params) { 899 wip: function(params) {
900 return duetholder(params); 900 return duetholder(params);
901 return PARTS.alltogethernow(params); 901 return PARTS.alltogethernow(params);
902 return base_extrusions(); 902 return base_extrusions();
903 return foot(); 903 return foot();
904 return union(base_extrusions(),column_extrusions(),duet().translate([0,-20,0])); 904 return union(base_extrusions(),column_extrusions(),duet().translate([0,-20,0]));
905 }, 905 },
906 alltogethernow: function(params) { 906 alltogethernow: function(params) {
907 var cols = columns(); 907 var cols = columns();
908 var sides = base_sides(); 908 var sides = base_sides();
909 var feet = THREEWINDS.map(function(w,i) { 909 var feet = THREEWINDS.map(function(w,i) {
910 var rv = foot(); 910 var rv = foot();
911 rv = rv.connectTo(rv.properties.c_column,cols[i].properties.c_bottom,false,0); 911 rv = rv.connectTo(rv.properties.c_column,cols[i].properties.c_bottom,false,0);
912 var s = shoe(); 912 var s = shoe();
913 s = s.connectTo(s.properties.c_foot,rv.properties.c_shoe,false,0); 913 s = s.connectTo(s.properties.c_foot,rv.properties.c_shoe,false,0);
914 return rv.union(s); 914 return rv.union(s);
915 }); 915 });
916 var dh = duetholder(); 916 var dh = duetholder();
917 var dhsw = dh.connectTo(dh.properties.c_h, 917 var dhsw = dh.connectTo(dh.properties.c_h,
918 new CSG.Connector([-CONFIG.duet.hole_spacing.x/2,-CD.base.mid_inscription_r,CONFIG.foot.h],[0,0,1],[1,0,0]), 918 new CSG.Connector([-CONFIG.duet.hole_spacing.x/2,-CD.base.mid_inscription_r,CONFIG.foot.h],[0,0,1],[1,0,0]),
919 false,0); 919 false,0);
920 var d = duet(); 920 var d = duet();
921 d = d.connectTo(d.properties.holes.c_sw,dhsw.properties.duet.c_sw,false,0); 921 d = d.connectTo(d.properties.holes.c_sw,dhsw.properties.duet.c_sw,false,0);
922 var dhse = dh.connectTo(dh.properties.duet.c_se,d.properties.holes.c_se,false,0); 922 var dhse = dh.connectTo(dh.properties.duet.c_se,d.properties.holes.c_se,false,0);
923 var dhne = dh.connectTo(dh.properties.duet.c_ne,d.properties.holes.c_ne,false,0); 923 var dhne = dh.connectTo(dh.properties.duet.c_ne,d.properties.holes.c_ne,false,0);
924 var dhnw = dh.connectTo(dh.properties.duet.c_nw,d.properties.holes.c_nw,false,0); 924 var dhnw = dh.connectTo(dh.properties.duet.c_nw,d.properties.holes.c_nw,false,0);
925 var rv = union(cols).union(sides.map(union)).union(feet).union([ 925 var rv = union(cols).union(sides.map(union)).union(feet).union([
926 d,dhsw,dhse,dhne,dhnw 926 d,dhsw,dhse,dhne,dhnw
927 ]); 927 ]);
928 var p = U.P(platform()); 928 var p = U.P(platform());
929 rv = rv.union(p); 929 rv = rv.union(p);
930 rv.properties.P = new CSG.Connector([0,0,0],[0,0,1],[1,0,0]); 930 rv.properties.P = new CSG.Connector([0,0,0],[0,0,1],[1,0,0]);
931 return rv; 931 return rv;
932 }, 932 },
933 duetholder: function(params) { 933 duetholder: function(params) {
934 return duetholder(); 934 return duetholder();
935 }, 935 },
936 foot: foot, 936 foot: foot,
937 shoe: shoe, 937 shoe: shoe,
938 bedholder: bedholder, 938 bedholder: bedholder,
939 platform: function(params) { return U.P(EFFECTOR.effector()) }, 939 platform: function(params) { return U.P(EFFECTOR.effector()) },
940 hinged: function(params) { 940 hinged: function(params) {
941 // TODO: handle print mode 941 // TODO: handle print mode
942 var ms = microswitch(); 942 var ms = microswitch();
943 var e = EFFECTOR.effector(); 943 var e = EFFECTOR.effector();
944 var hd = EFFECTOR.hinged({ 944 var hd = EFFECTOR.hinged({
945 microswitch:ms,effector:e 945 microswitch:ms,effector:e
946 }); 946 });
947 ms = ms.connectTo( 947 ms = ms.connectTo(
948 ms.properties.screw_connector[0], 948 ms.properties.screw_connector[0],
949 hd.properties.microswitch_screw_connector[0], 949 hd.properties.microswitch_screw_connector[0],
950 false, 0); 950 false, 0);
951 var hdhd = EFFECTOR.split_hinged(hd); 951 var hdhd = EFFECTOR.split_hinged(hd);
952 return U.P(hdhd[1]); 952 return U.P(hdhd[1]);
953 }, 953 },
954 // TODO: eliminate common code above and below 954 // TODO: eliminate common code above and below
955 clamp: function(params) { 955 clamp: function(params) {
956 // TODO: handle print mode 956 // TODO: handle print mode
957 var ms = microswitch(); 957 var ms = microswitch();
958 var e = EFFECTOR.effector(); 958 var e = EFFECTOR.effector();
959 var hd = EFFECTOR.hinged({ 959 var hd = EFFECTOR.hinged({
960 microswitch:ms,effector:e 960 microswitch:ms,effector:e
961 }); 961 });
962 ms = ms.connectTo( 962 ms = ms.connectTo(
963 ms.properties.screw_connector[0], 963 ms.properties.screw_connector[0],
964 hd.properties.microswitch_screw_connector[0], 964 hd.properties.microswitch_screw_connector[0],
965 false, 0); 965 false, 0);
966 var hdhd = EFFECTOR.split_hinged(hd); 966 var hdhd = EFFECTOR.split_hinged(hd);
967 return U.P(hdhd[0]); 967 return U.P(hdhd[0]);
968 }, 968 },
969 fanholder: function(params) { 969 fanholder: function(params) {
970 EFFECTOR.effector(); // to set up rmount 970 EFFECTOR.effector(); // to set up rmount
971 return U.P(EFFECTOR.fanholder()); 971 return U.P(EFFECTOR.fanholder());
972 } 972 }
973}; 973};
974 974
975function main(params) { 975function main(params) {
976 var part = params.part && PARTS[params.part]; 976 var part = params.part && PARTS[params.part];
977 if(!part) return U.axes(); 977 if(!part) return U.axes();
978 var rv = U.P(part(params)); 978 var rv = U.P(part(params));
979 if(!params.print) rv = rv.union(U.axes()); 979 if(!params.print) rv = rv.union(U.axes());
980 return rv; 980 return rv;
981} 981}
982 982
983function _main(params) { 983function _main(params) {
984 var e = EFFECTOR.effector(); 984 var e = EFFECTOR.effector();
985 var hs = E3DV6.heatsink(); 985 var hs = E3DV6.heatsink();
986 hs = hs.connectTo(hs.properties.grove_connector,e.properties.grove_connector,false,0); 986 hs = hs.connectTo(hs.properties.grove_connector,e.properties.grove_connector,false,0);
987 var ms = microswitch(); 987 var ms = microswitch();
988 var hd = EFFECTOR.hinged({ 988 var hd = EFFECTOR.hinged({
989 microswitch:ms,effector:e 989 microswitch:ms,effector:e
990 }); 990 });
991 ms = ms.connectTo( 991 ms = ms.connectTo(
992 ms.properties.screw_connector[0], 992 ms.properties.screw_connector[0],
993 hd.properties.microswitch_screw_connector[0], 993 hd.properties.microswitch_screw_connector[0],
994 false, 0); 994 false, 0);
995 var hdhd = EFFECTOR.split_hinged(hd); 995 var hdhd = EFFECTOR.split_hinged(hd);
996 var fh = EFFECTOR.fanholder(); 996 var fh = EFFECTOR.fanholder();
997 return union({ 997 return union({
998 platform: e, 998 platform: e,
999 hinged: hdhd[1], 999 hinged: hdhd[1],
1000 clamp: hdhd[0], 1000 clamp: hdhd[0],
1001 fanholder: fh, 1001 fanholder: fh,
1002 alltogethernow: [e,hdhd[0],hdhd[1], columns(),hs,ms,fh] 1002 alltogethernow: [e,hdhd[0],hdhd[1], columns(),hs,ms,fh]
1003 }[params.part||'alltogethernow']) 1003 }[params.part||'alltogethernow'])
1004 var rv = union( 1004 var rv = union(
1005 e, 1005 e,
1006 hs, 1006 hs,
1007 columns(), 1007 columns(),
1008 ///hd, 1008 ///hd,
1009 hdhd[0], hdhd[1], 1009 hdhd[0], hdhd[1],
1010 ms); 1010 ms);
1011 return rv; 1011 return rv;
1012} 1012}
1013 1013
1014function getParameterDefinitions() { 1014function getParameterDefinitions() {
1015 return [{ 1015 return [{
1016 name: 'part', 1016 name: 'part',
1017 type: 'choice', 1017 type: 'choice',
1018 values: [ 1018 values: [
1019 'platform', 1019 'platform',
1020 'hinged', 1020 'hinged',
1021 'clamp', 1021 'clamp',
1022 'fanholder', 1022 'fanholder',
1023 'duetholder', 1023 'duetholder',
1024 'foot', 'shoe', 1024 'foot', 'shoe',
1025 'bedholder', 1025 'bedholder',
1026 'alltogethernow', 1026 'alltogethernow',
1027 'wip' 1027 'wip'
1028 ], 1028 ],
1029 captions: [ 1029 captions: [
1030 'Effector platform', 1030 'Effector platform',
1031 'Hinged part', 1031 'Hinged part',
1032 'Clamp', 1032 'Clamp',
1033 'Fan holder', 1033 'Fan holder',
1034 'Duet holder', 1034 'Duet holder',
1035 'Foot', 'Shoe', 1035 'Foot', 'Shoe',
1036 'Bed holder', 1036 'Bed holder',
1037 'All together now!', 1037 'All together now!',
1038 'Work in progress' 1038 'Work in progress'
1039 ], 1039 ],
1040 caption: 'Part', 1040 caption: 'Part',
1041 initial: 'wip' 1041 initial: 'wip'
1042 },{ 1042 },{
1043 name: 'print', 1043 name: 'print',
1044 type: 'checkbox', 1044 type: 'checkbox',
1045 checked: false,
1045 caption: 'For print, no nonsense', 1046 caption: 'For print, no nonsense',
1046 initial: false 1047 initial: false
1047 }]; 1048 }];
1048} 1049}
1049 1050
1050/* vim:set ft=javascript ai: */ 1051/* vim:set ft=javascript ai: */