-rw-r--r-- | delta.jscad | 453 |
1 files changed, 453 insertions, 0 deletions
diff --git a/delta.jscad b/delta.jscad new file mode 100644 index 0000000..63eea6c --- a/dev/null +++ b/delta.jscad | |||
@@ -0,0 +1,453 @@ | |||
1 | var PRINT = { | ||
2 | layer_height: 0.2, | ||
3 | extrusion_width: 0.4, | ||
4 | |||
5 | fit_tolerance: 0.4, | ||
6 | slide_tolerance: 0.2 | ||
7 | }; | ||
8 | |||
9 | var CONFIG = { | ||
10 | hotend: { | ||
11 | h: 62.4, // full assembly height | ||
12 | groove: { d:12, h:6 }, // grove diameter and height | ||
13 | ungroove: { d:16, above:3.7, below: 3+4 } | ||
14 | }, | ||
15 | effector: { | ||
16 | h: 6, | ||
17 | o: 20,// offset to the rod mounts line | ||
18 | rods_apart: 40, | ||
19 | cone: { shell: 1, angle: Math.PI/6 }, | ||
20 | rodend: { | ||
21 | joint_w: 7,// thickness of the joint | ||
22 | screw_l: 20-1, // 20 with the head | ||
23 | screw_d: 3 | ||
24 | }, | ||
25 | hotend: { margin: 2 }, | ||
26 | hinge: { | ||
27 | d: 3, w: 5, margin: 2.5, | ||
28 | h: 1+(6+3.7)/2, // elevation + grove + top | ||
29 | e: 1 // elevation | ||
30 | }, | ||
31 | clamp: { | ||
32 | shell: 4.6, | ||
33 | d: 3, | ||
34 | margin: 2.5, | ||
35 | split: 0.6 | ||
36 | }, | ||
37 | mswitch: { | ||
38 | size: [ 19.8, 6, 10 ], | ||
39 | screw: { | ||
40 | d: 2, h: 10/2-2, | ||
41 | s: 1.3, // screw shell | ||
42 | o: [-9.5/2,9.5/2].map(function(x) { | ||
43 | return -19.8/2+x; | ||
44 | }) | ||
45 | }, | ||
46 | switch_x: 2.5 | ||
47 | }, | ||
48 | guide: { | ||
49 | width: 3, height: 5+1, length: 6 | ||
50 | }, | ||
51 | fanholder: { | ||
52 | r: 30, | ||
53 | screw: { d: 3, m: 2.5/*margin*/ }, | ||
54 | w: 3 | ||
55 | } | ||
56 | }, | ||
57 | nut: { h: 2.3, w: 5.5 } | ||
58 | }; | ||
59 | |||
60 | var U = { | ||
61 | hypotenuse: function(a,b) { | ||
62 | return Math.sqrt(Math.pow(a,2)+Math.pow(b,2)); | ||
63 | }, | ||
64 | peek: function(x,m) { | ||
65 | console.log(x,m); | ||
66 | return x; | ||
67 | } | ||
68 | }; | ||
69 | |||
70 | /* {h:,w:} */ | ||
71 | function nut(o) { | ||
72 | var rv = CSG.cylinder({ | ||
73 | start:[0,0,0],end:[0,0,o.h], | ||
74 | radius: o.w/2/Math.cos(Math.PI/6), | ||
75 | resolution: 6 | ||
76 | }); | ||
77 | rv.properties.axis_connector = new CSG.Connector([0,0,0],[0,0,1],[0,1,0]); | ||
78 | return rv; | ||
79 | } | ||
80 | |||
81 | var E3DV6 = { | ||
82 | dimensions: { | ||
83 | big_d: 22.3, | ||
84 | |||
85 | }, | ||
86 | heatsink: function() { | ||
87 | var fn = 16; | ||
88 | var z=0; | ||
89 | var unite = [ {d:16,h:3.7},{d:12,h:6},{d:16,h:3} ].map(function(x) { | ||
90 | return CSG.cylinder({ | ||
91 | start: [0,0,z], end: [0,0,z-=x.h], | ||
92 | radius: x.d/2, resolution: fn | ||
93 | }); | ||
94 | }); | ||
95 | unite.push(CSG.cylinder({ | ||
96 | start:[0,0,z-=1.5], end:[0,0,z-=1], | ||
97 | radius: 16/2, resolution: fn | ||
98 | })); | ||
99 | for(var i=0;i<11;++i) unite.push(CSG.cylinder({ | ||
100 | start:[0,0,z-=1.5], end:[0,0,z-=1], | ||
101 | radius: this.dimensions.big_d/2, resolution: fn | ||
102 | })); | ||
103 | unite.push(CSG.cylinder({ | ||
104 | start:[0,0,z], end: [0,0,-12.7], | ||
105 | radiusStart: 10/2, radiusEnd: 8.5/2, /* pretty arbitrary */ | ||
106 | resolution: fn | ||
107 | })); | ||
108 | var rv = union(unite); | ||
109 | rv = rv.subtract([CSG.cylinder({ | ||
110 | start:[0,0,1], end: [0,0,z-1], | ||
111 | radius: 4.2/2, resolution: fn | ||
112 | }),CSG.cylinder({ | ||
113 | start:[0,0,1], end: [0,0,-6.7/*somewhat arbitrary*/], | ||
114 | radius: 8/2, resolution: fn | ||
115 | }),CSG.cylinder({ | ||
116 | start:[0,0,z-1], end: [0,0,z+14.8], | ||
117 | radius: 6/2 /*M7*/, resolution: fn | ||
118 | })]); | ||
119 | rv.properties.pushfit_connector = new CSG.Connector([0,0,0],[0,0,-1],[1,0,0]); | ||
120 | rv.properties.heatbreak_connector = new CSG.Connector([0,0,z+14.8],[0,0,-1],[1,0,0]); | ||
121 | rv.properties.grove_connector = new CSG.Connector([0,0,-3.7-3],[0,0,1],[1,0,0]); | ||
122 | return rv.setColor([0.8,0.8,0.8,0.9]); | ||
123 | } | ||
124 | }; | ||
125 | |||
126 | var EFFECTOR = { | ||
127 | /* {sd: screw diameter, l: cone length, s: screw shell, a: angle from axis} */ | ||
128 | cone: function effector_cone(o) { | ||
129 | var re = o.sd/2+o.s, rs = re+o.l*Math.tan(o.a||(Math.PI/4)); | ||
130 | var rv = CSG.cylinder({ | ||
131 | start: [0,0,0], end: [0,0,o.l], | ||
132 | radiusStart: rs, radiusEnd: re, | ||
133 | resolution: Math.floor(rs*2*2) | ||
134 | }).subtract(CSG.cylinder({ | ||
135 | start:[0,0,-1], end:[0,0,o.l+1], radius: o.sd, | ||
136 | //resolution: Math.floor(o.sd*2*2) | ||
137 | })); | ||
138 | rv.properties.top_connector = new CSG.Connector([0,0,o.l],[0,0,-1],[1,0,0]); | ||
139 | rv.properties.bottom_connector = new CSG.Connector([0,0,0],[0,0,1],[1,0,0]); | ||
140 | var nuthole = nut(CONFIG.nut); | ||
141 | rv = rv.subtract(nuthole.connectTo( | ||
142 | nuthole.properties.axis_connector, rv.properties.bottom_connector, | ||
143 | false, 0 | ||
144 | )); | ||
145 | return rv.intersect(CSG.cylinder({start:[0,0,0],end:[0,0,o.l],radius:6/*TODO:calculate*/})); | ||
146 | }, | ||
147 | platform_bb: function platform_bb() { | ||
148 | var e = CONFIG.effector; | ||
149 | var r = U.hypotenuse(e.rods_apart/2,e.o+e.rodend.screw_d/2+e.cone.shell); | ||
150 | var rv = CSG.sphere({ | ||
151 | center: [0,0,e.h/2], radius: r, | ||
152 | resolution: r*2*2 | ||
153 | }).intersect(CSG.cube({ | ||
154 | corner1: [-r,-r,0], corner2: [r,r,e.h] | ||
155 | })); | ||
156 | rv.properties.base_connector = new CSG.Connector([0,0,0],[0,0,1],[1,0,0]); | ||
157 | return rv; | ||
158 | }, | ||
159 | effector: function effector_effector() { | ||
160 | var e = CONFIG.effector; | ||
161 | var conel = e.rodend.screw_l-e.rodend.joint_w; | ||
162 | var nutr = CONFIG.nut.w/2/Math.cos(Math.PI/6); | ||
163 | var cone = this.cone({sd:e.rodend.screw_d/2,l:conel,s:e.cone.shell,a:e.cone.angle}); | ||
164 | var rcorner = U.hypotenuse(e.o-e.rodend.screw_d/2-e.cone.shell,e.rods_apart/2)-3.85; //XXX:config/calc | ||
165 | var ropen = E3DV6.dimensions.big_d/2+e.hotend.margin; | ||
166 | var rmount = this.rmount = (rcorner+ropen)/2; | ||
167 | var rv = []; | ||
168 | for(var a=0;a<360;a+=120) { | ||
169 | rv.push(union([-1,1].map(function(s) { | ||
170 | return cone.connectTo(cone.properties.top_connector, | ||
171 | new CSG.Connector([s*e.rods_apart/2,e.o,e.h/2],[-s,0,0],[0,0,1]), | ||
172 | false, 0); | ||
173 | })).union(CSG.cube({ | ||
174 | corner1:[e.rods_apart/2-conel+.1,e.o-nutr,0], | ||
175 | corner2:[-e.rods_apart/2+conel-.1, | ||
176 | -rcorner, | ||
177 | e.h] | ||
178 | })).rotateZ(a)); | ||
179 | } | ||
180 | rv.push(CSG.cylinder({ | ||
181 | start:[0,0,0], end:[0,0,e.h], | ||
182 | radius: U.hypotenuse(e.o-nutr,e.rods_apart/2-conel) | ||
183 | })); | ||
184 | rv = union(rv).intersect(this.platform_bb()).subtract(CSG.cylinder({ | ||
185 | start:[0,0,-1], end:[0,0,e.h+1], | ||
186 | radius: ropen, resolution: ropen*4 | ||
187 | })).subtract([/*0, probe here*/120,240].map(function(x) { /* nut pockets */ | ||
188 | return CSG.cube({ | ||
189 | corner1:[-CONFIG.nut.w/2,0,(e.h-CONFIG.nut.h)/2], | ||
190 | corner2:[CONFIG.nut.w/2,-rcorner-1,(e.h+CONFIG.nut.h)/2] | ||
191 | }).union(CSG.cylinder({ | ||
192 | start:[0,-rmount,-1], end:[0,-rmount,e.h+1], | ||
193 | radius: 3/2 // XXX: | ||
194 | })).subtract(CSG.cylinder({ | ||
195 | start:[0,-rmount,(e.h+CONFIG.nut.h)/2], | ||
196 | end:[0,-rmount,(e.h+CONFIG.nut.h)/2+PRINT.layer_height*3/2], | ||
197 | radius: 3/2+.1 | ||
198 | })).rotateZ(x); | ||
199 | })).subtract( CSG.cylinder({ // pulldown screw | ||
200 | start: [0,-rcorner+e.mswitch.size[1]+PRINT.extrusion_width+3/2/*XXX:conf*/,-1], | ||
201 | end: [0,-rcorner+e.mswitch.size[1]+PRINT.extrusion_width+3/2/*XXX:conf*/,e.h+1], | ||
202 | radius: 3/2+1 /*XXX: config */ | ||
203 | })).subtract( CSG.cylinder({ /* switch-screw */ | ||
204 | start: [e.mswitch.switch_x,-rcorner+e.mswitch.size[1]/2,-1], | ||
205 | end: [e.mswitch.switch_x,-rcorner+e.mswitch.size[1]/2,e.h+1], | ||
206 | radius: e.mswitch.screw.d/2 | ||
207 | })); | ||
208 | // add hinges | ||
209 | rv.properties.hinge_connector=new CSG.Properties(); | ||
210 | var hinges_apart=e.rods_apart/2-conel; | ||
211 | rv = rv.union([-1,1].map(function hinge(s) { | ||
212 | rv.properties.hinge_connector[s]=new CSG.Connector([s*hinges_apart,e.o,e.h+e.hinge.h],[s,0,0],[0,0,1]); | ||
213 | return CSG.cube({ | ||
214 | corner1: [s*hinges_apart,e.o-e.hinge.margin-e.hinge.d/2,e.h], | ||
215 | corner2: [s*(hinges_apart+e.hinge.w),e.o+e.hinge.margin+e.hinge.d/2,e.h+e.hinge.h] | ||
216 | }).union(CSG.cylinder({ | ||
217 | start: [s*hinges_apart,e.o,e.h+e.hinge.h], | ||
218 | end: [s*(hinges_apart+e.hinge.w),e.o,e.h+e.hinge.h], | ||
219 | radius: e.hinge.d/2+e.hinge.margin | ||
220 | })).subtract(CSG.cylinder({ | ||
221 | start: [s*(hinges_apart-1),e.o,e.h+e.hinge.h], | ||
222 | end: [s*(hinges_apart+e.hinge.w+1),e.o,e.h+e.hinge.h], | ||
223 | radius: e.hinge.d/2 | ||
224 | })); | ||
225 | })); | ||
226 | // add clamp guides | ||
227 | var cgrr = e.guide.width/3; | ||
228 | rv = rv.union([-1,1].map(function guide(s) { | ||
229 | return CSG.roundedCube({ | ||
230 | 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], | ||
231 | radius: [e.guide.width/2,e.guide.length/2,e.guide.height/2+cgrr], | ||
232 | roundradius: cgrr | ||
233 | }).intersect(CSG.cube({ | ||
234 | center: [s*(e.mswitch.size[0]+PRINT.slide_tolerance+e.guide.width)/2,-rcorner+e.guide.length/2,e.h+e.guide.height/2], | ||
235 | radius: [e.guide.width/2,e.guide.length/2,e.guide.height/2+.1], | ||
236 | roundradius: cgrr | ||
237 | })); | ||
238 | })); | ||
239 | rv.properties.grove_connector = new CSG.Connector([0,0,e.h+e.hinge.e+6/2],[0,0,1],[1,0,0]); | ||
240 | rv.properties.rcorner = rcorner; | ||
241 | return rv.setColor([0.4,0.8,0.4,0.9]); | ||
242 | }, | ||
243 | hinged: function effector_hinged(o) { | ||
244 | var e = CONFIG.effector; | ||
245 | var conel = e.rodend.screw_l-e.rodend.joint_w; | ||
246 | var hinges_apart = e.rods_apart/2-conel; | ||
247 | var hhr = e.o-e.hinge.d/2-e.hinge.margin; // hotend holder radius | ||
248 | var hhh = CONFIG.hotend.groove.h+CONFIG.hotend.ungroove.above; | ||
249 | var rv = CSG.cylinder({ /* hinge */ | ||
250 | start: [-hinges_apart+PRINT.slide_tolerance,e.o,e.h+e.hinge.h], | ||
251 | end: [hinges_apart-PRINT.slide_tolerance,e.o,e.h+e.hinge.h], | ||
252 | radius: e.hinge.d/2+e.hinge.margin | ||
253 | }).union( /* lower hotend holder */ | ||
254 | CSG.cylinder({ | ||
255 | start: [0,0,e.h+e.hinge.e], end: [0,0,e.h+e.hinge.e+CONFIG.hotend.groove.h], | ||
256 | radius: hhr | ||
257 | }).subtract(CSG.cylinder({ | ||
258 | start: [0,0,e.h+e.hinge.e-1], end: [0,0,e.h+e.hinge.e+CONFIG.hotend.groove.h+1], | ||
259 | radius: CONFIG.hotend.groove.d/2 +PRINT.fit_tolerance | ||
260 | })) | ||
261 | ).union( /* upper hotend holder */ | ||
262 | CSG.cylinder({ | ||
263 | start: [0,0,e.h+e.hinge.e+CONFIG.hotend.groove.h], | ||
264 | end: [0,0,e.h+e.hinge.e+CONFIG.hotend.groove.h+CONFIG.hotend.ungroove.above], | ||
265 | radius: hhr | ||
266 | }).subtract(CSG.cylinder({ | ||
267 | start: [0,0,e.h+e.hinge.e+CONFIG.hotend.groove.h-1], | ||
268 | end: [0,0,e.h+e.hinge.e+CONFIG.hotend.groove.h+CONFIG.hotend.ungroove.above+1], | ||
269 | radius: CONFIG.hotend.ungroove.d/2 +PRINT.fit_tolerance | ||
270 | })) | ||
271 | ).union( /* connect mount with hinge */ | ||
272 | CSG.cube({ | ||
273 | corner1: [-hinges_apart+PRINT.slide_tolerance,CONFIG.hotend.ungroove.d/2+PRINT.fit_tolerance,e.h+e.hinge.e], | ||
274 | corner2: [hinges_apart-PRINT.slide_tolerance,e.o,e.h+e.hinge.h+e.hinge.d/2+e.hinge.margin] | ||
275 | }) | ||
276 | ).subtract( /* hinge screwhole */ | ||
277 | CSG.cylinder({ | ||
278 | start: [-hinges_apart-1,e.o,e.h+e.hinge.h], | ||
279 | end: [hinges_apart+1,e.o,e.h+e.hinge.h], | ||
280 | radius: e.hinge.d/2 | ||
281 | }) | ||
282 | ).union( /* hold clamp together */ | ||
283 | [-1,1].map(function(s) { | ||
284 | return CSG.roundedCube({ | ||
285 | corner1: [s*(-hhr-e.clamp.margin*2-e.clamp.d),-e.clamp.shell,e.h+e.hinge.e], | ||
286 | corner2: [s*(-CONFIG.hotend.ungroove.d/2-PRINT.fit_tolerance),+e.clamp.shell,e.h+e.hinge.e+hhh], | ||
287 | roundradius: 1.5 | ||
288 | }); | ||
289 | }) | ||
290 | ).subtract( /* screws for holding clamp */ | ||
291 | [-1,1].map(function(s) { | ||
292 | var nuthole = nut(CONFIG.nut); | ||
293 | var x = s*(-hhr-e.clamp.margin-e.clamp.d/2); | ||
294 | return CSG.cylinder({ | ||
295 | start: [x,-e.clamp.shell-1,e.h+e.hinge.e+hhh/2], | ||
296 | end: [x,e.clamp.shell+1,e.h+e.hinge.e+hhh/2], | ||
297 | radius: e.clamp.d/2 | ||
298 | }).union(nuthole.connectTo( | ||
299 | nuthole.properties.axis_connector, | ||
300 | new CSG.Connector([x,e.clamp.shell,e.h+e.hinge.e+hhh/2],[0,-1,0],[0,0,1]), | ||
301 | false, 0 | ||
302 | )).union(CSG.cylinder({ | ||
303 | start: [x,-e.clamp.shell-1,e.h+e.hinge.e+hhh/2], | ||
304 | end: [x,0,e.h+e.hinge.e+hhh/2], | ||
305 | radius: e.clamp.d/2+PRINT.slide_tolerance | ||
306 | })); | ||
307 | }) | ||
308 | ); | ||
309 | var ms = o.microswitch; | ||
310 | var msedge = o.effector.properties.rcorner; | ||
311 | var msh = 9.5; // microswitch holes apart | ||
312 | var mshh = Math.abs(ms.properties.switch_connector.point.z-ms.properties.screw_connector[0].point.z); // microswitch holes height | ||
313 | rv = rv.union(CSG.cube({ // connect clamp with microswitch | ||
314 | corner1: [-ms.properties.microswitch.size.x/2,-msedge+.1,e.h+e.hinge.e], | ||
315 | corner2: [+ms.properties.microswitch.size.x/2,-CONFIG.hotend.ungroove.d/2-PRINT.fit_tolerance,e.h+e.hinge.e+hhh] | ||
316 | })).union([-msh/2,msh/2].map(function(x) { // shell for microswitch screws | ||
317 | return CSG.roundedCylinder({ | ||
318 | 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], | ||
319 | end: [x,-msedge+ms.properties.microswitch.size.y,e.h+e.hinge.e+mshh], | ||
320 | radius: e.mswitch.screw.d/2+e.mswitch.screw.s | ||
321 | }); | ||
322 | })).subtract(CSG.cube({ // cut off excess if any | ||
323 | corner1:[-hhr,-msedge+ms.properties.microswitch.size.y,e.h+e.hinge.e-1], | ||
324 | corner2:[hhr,-msedge-1,e.h+e.hinge.e+hhh+e.mswitch.screw.d+e.mswitch.screw.s+1] | ||
325 | })).subtract([-msh/2,msh/2].map(function(x) { return CSG.roundedCylinder({ // screwholes | ||
326 | 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], | ||
327 | end: [x,-msedge+ms.properties.microswitch.size.y,e.h+e.hinge.e+mshh], | ||
328 | radius: e.mswitch.screw.d/2 | ||
329 | })})).subtract(CSG.cylinder({ // pulldown screw | ||
330 | start:[0,-msedge+ms.properties.microswitch.size.y+3/2/*XXX:config*/+PRINT.extrusion_width,e.h+e.hinge.e-1], | ||
331 | end:[0,-msedge+ms.properties.microswitch.size.y+3/2/*XXX:config*/+PRINT.extrusion_width,e.h+e.hinge.e+hhh+1], | ||
332 | radius: 3/2/*XXX:config*/ | ||
333 | })); | ||
334 | rv.properties.microswitch_screw_connector = new CSG.Properties(); | ||
335 | [-msh/2,msh/2].forEach(function(x,i) { | ||
336 | rv.properties.microswitch_screw_connector[i] = new CSG.Connector( | ||
337 | [x,-msedge,e.h+e.hinge.e+mshh], | ||
338 | [0,1,0], [0,0,-1] | ||
339 | ); | ||
340 | }); | ||
341 | return rv.setColor([0.3,0.8,0.3,0.9]); | ||
342 | }, | ||
343 | split_hinged: function effector_split_hinged(hinged) { | ||
344 | var e = CONFIG.effector; | ||
345 | var b = hinged.getBounds(); | ||
346 | var ymax = Math.max(Math.abs(b[0].y),Math.abs(b[1].y)); | ||
347 | var zmax = Math.max(b[0].z,b[1].z); | ||
348 | return [-1,1].map(function(s) { | ||
349 | return hinged.intersect(CSG.cube({ | ||
350 | corner1: [Math.min(b[0].x,b[1].x)-1,s*e.clamp.split/2,-zmax-1], | ||
351 | corner2: [Math.max(b[0].x,b[1].x)+1,s*(ymax+1),zmax+1] | ||
352 | })); | ||
353 | }); | ||
354 | }, | ||
355 | fanholder: function effector_fanholder() { | ||
356 | var fh = CONFIG.effector.fanholder; | ||
357 | var od = fh.screw.d+2*fh.screw.m; | ||
358 | return linear_extrude({height:fh.w},hull( | ||
359 | CAG.circle({center:[0,-this.rmount],radius:od/2}), | ||
360 | CAG.circle({center:[0,-fh.r+od/2+fh.w/2],radius:fh.w/2}) | ||
361 | )).translate([0,0,-fh.w]).union( | ||
362 | linear_extrude({height:fh.w},hull( | ||
363 | CAG.circle({center:[fh.w/2,-this.rmount-od/2-fh.w/2],radius:fh.w/2}), | ||
364 | CAG.circle({center:[od/2,-fh.r],radius:od/2}) | ||
365 | )).rotateY(90).translate([-fh.w/2,0,0]) | ||
366 | ).subtract( CSG.cylinder({ | ||
367 | start: [-fh.w,-fh.r,-od/2], | ||
368 | end: [fh.w,-fh.r,-od/2], | ||
369 | radius: fh.screw.d/2 | ||
370 | })).subtract( CSG.cylinder({ | ||
371 | start: [0,-this.rmount,1], | ||
372 | end: [0,-this.rmount,-fh.w-1], | ||
373 | radius: fh.screw.d/2 | ||
374 | })).setColor([0.3,0.8,0.3,0.9]).rotateZ(-120); | ||
375 | } | ||
376 | }; | ||
377 | |||
378 | function columns() { | ||
379 | var rv = [0,1,2].map(function(x) { | ||
380 | return union(vector_char(0,0,String.fromCharCode('A'.charCodeAt(0)+x)).segments.map(function(x) { | ||
381 | return rectangular_extrude(x,{w:2,h:1}); | ||
382 | })).center().rotateX(90).translate([0,50,0]).rotateZ(x*120+120); | ||
383 | }); | ||
384 | return union(rv); | ||
385 | } | ||
386 | |||
387 | function microswitch() { | ||
388 | var screw_connector = new CSG.Properties(); | ||
389 | var rv = CSG.cube({ center:[0,0,2.5],radius: [19.8/2,6/2,10/2] }).union( | ||
390 | CSG.cube({ center: [2.5,0.5,6], radius: [2/2,3.5/2,5/2] }) | ||
391 | ).union( | ||
392 | [-8,-1,8].map(function(x) { | ||
393 | return CSG.cube({ center:[x,0,0], radius: [0.6/2,3.2/2,13/2] }) | ||
394 | }) | ||
395 | ).subtract( | ||
396 | [-9.5/2,9.5/2].map(function(x,i) { | ||
397 | screw_connector[i] = new CSG.Connector([x,6/2,0],[0,-1,0],[0,0,1]); | ||
398 | return CSG.cylinder({ | ||
399 | start: [x,-4,0], end: [x,4,0], | ||
400 | radius: 2/2 | ||
401 | }) | ||
402 | }) | ||
403 | ); | ||
404 | rv.properties.switch_connector = new CSG.Connector([2.5,0.5,6+5/2],[0,0,1],[0,-1,0]); | ||
405 | rv.properties.screw_connector = screw_connector; | ||
406 | rv.properties.microswitch = new CSG.Properties(); | ||
407 | rv.properties.microswitch.size = new CSG.Vector3D( | ||
408 | 19.8,6,10 | ||
409 | ); | ||
410 | return rv; | ||
411 | } | ||
412 | |||
413 | function getParameterDefinitions() { | ||
414 | return [{ | ||
415 | name: 'part', | ||
416 | type: 'choice', | ||
417 | values: ['platform', 'hinged', 'clamp', 'fanholder', 'alltogethernow'], | ||
418 | captions: ['Effector platform','Hinged part', 'Clamp', 'Fan holder', 'All together now!'], | ||
419 | caption: 'Part', | ||
420 | initial: 'alltogethernow' | ||
421 | }]; | ||
422 | } | ||
423 | |||
424 | function main(params) { | ||
425 | var e = EFFECTOR.effector(); | ||
426 | var hs = E3DV6.heatsink(); | ||
427 | hs = hs.connectTo(hs.properties.grove_connector,e.properties.grove_connector,false,0); | ||
428 | var ms = microswitch(); | ||
429 | var hd = EFFECTOR.hinged({ | ||
430 | microswitch:ms,effector:e | ||
431 | }); | ||
432 | ms = ms.connectTo( | ||
433 | ms.properties.screw_connector[0], | ||
434 | hd.properties.microswitch_screw_connector[0], | ||
435 | false, 0); | ||
436 | var hdhd = EFFECTOR.split_hinged(hd); | ||
437 | var fh = EFFECTOR.fanholder(); | ||
438 | return union({ | ||
439 | platform: e, | ||
440 | hinged: hdhd[1], | ||
441 | clamp: hdhd[0], | ||
442 | fanholder: fh, | ||
443 | alltogethernow: [e,hdhd[0],hdhd[1], columns(),hs,ms,fh] | ||
444 | }[params.part||'alltogethernow']) | ||
445 | var rv = union( | ||
446 | e, | ||
447 | hs, | ||
448 | columns(), | ||
449 | ///hd, | ||
450 | hdhd[0], hdhd[1], | ||
451 | ms); | ||
452 | return rv; | ||
453 | } | ||