summaryrefslogtreecommitdiffabout
authorMichael Krelin <hacker@klever.net>2016-03-20 14:39:18 (UTC)
committer Michael Krelin <hacker@klever.net>2016-03-20 14:39:18 (UTC)
commit4a633d30598c5c230e42d3feafbca39b43292acc (patch) (unidiff)
treedf14b54b33c5af558cab0d5e6dcd878aaa22a9c7
parent00a023fb1fa3370550b2b30b6ce06aec45436a52 (diff)
downloadredelta-master.zip
redelta-master.tar.gz
redelta-master.tar.bz2
fanholder changes of no effectHEADmaster
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--delta.jscad6
1 files changed, 4 insertions, 2 deletions
diff --git a/delta.jscad b/delta.jscad
index b783913..b46534a 100644
--- a/delta.jscad
+++ b/delta.jscad
@@ -277,401 +277,403 @@ var EFFECTOR = {
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 var rv = 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 }));
486 rv.properties.P = new CSG.Connector([0,0,0],[0,0,-1],[1,0,0]);
487 return rv.setColor([0.3,0.8,0.3,0.9]).rotateZ(-120);
486 } 488 }
487}; 489};
488 490
489function columns() { 491function columns() {
490 var rv = [0,1,2].map(function(x) { 492 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) { 493 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}); 494 return rectangular_extrude(x,{w:2,h:1});
493 })).center().rotateX(90).translate([0,50,0]).rotateZ(x*120+120); 495 })).center().rotateX(90).translate([0,50,0]).rotateZ(x*120+120);
494 }); 496 });
495 return union(rv); 497 return union(rv);
496} 498}
497 499
498function microswitch() { 500function microswitch() {
499 var screw_connector = new CSG.Properties(); 501 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( 502 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] }) 503 CSG.cube({ center: [2.5,0.5,6], radius: [2/2,3.5/2,5/2] })
502 ).union( 504 ).union(
503 [-8,-1,8].map(function(x) { 505 [-8,-1,8].map(function(x) {
504 return CSG.cube({ center:[x,0,0], radius: [0.6/2,3.2/2,13/2] }) 506 return CSG.cube({ center:[x,0,0], radius: [0.6/2,3.2/2,13/2] })
505 }) 507 })
506 ).subtract( 508 ).subtract(
507 [-9.5/2,9.5/2].map(function(x,i) { 509 [-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]); 510 screw_connector[i] = new CSG.Connector([x,6/2,0],[0,-1,0],[0,0,1]);
509 return CSG.cylinder({ 511 return CSG.cylinder({
510 start: [x,-4,0], end: [x,4,0], 512 start: [x,-4,0], end: [x,4,0],
511 radius: 2/2 513 radius: 2/2
512 }) 514 })
513 }) 515 })
514 ); 516 );
515 rv.properties.switch_connector = new CSG.Connector([2.5,0.5,6+5/2],[0,0,1],[0,-1,0]); 517 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; 518 rv.properties.screw_connector = screw_connector;
517 rv.properties.microswitch = new CSG.Properties(); 519 rv.properties.microswitch = new CSG.Properties();
518 rv.properties.microswitch.size = new CSG.Vector3D( 520 rv.properties.microswitch.size = new CSG.Vector3D(
519 19.8,6,10 521 19.8,6,10
520 ); 522 );
521 return rv; 523 return rv;
522} 524}
523 525
524var FOURWINDS = [0,90,180,270]; 526var FOURWINDS = [0,90,180,270];
525 527
526var E2020 = { 528var E2020 = {
527 outer: 20, thickness: 1.8, 529 outer: 20, thickness: 1.8,
528 roundius: 1, centerhole: 5, 530 roundius: 1, centerhole: 5,
529 slot_width: 6, 531 slot_width: 6,
530 T: { width: 10, thickness: 1.5, depth: 6.5 }, 532 T: { width: 10, thickness: 1.5, depth: 6.5 },
531 533
532 extrusion: function(o) { 534 extrusion: function(o) {
533 if(!o) o = {}; 535 if(!o) o = {};
534 var e = o.extrusion || this; 536 var e = o.extrusion || this;
535 var l = o.l||5; 537 var l = o.l||5;
536 var iy = e.outer/2-e.T.depth; 538 var iy = e.outer/2-e.T.depth;
537 var ix = e.T.width/2-(e.outer/2-iy-e.thickness-e.T.thickness); 539 var ix = e.T.width/2-(e.outer/2-iy-e.thickness-e.T.thickness);
538 var rv = CAG.roundedRectangle({ 540 var rv = CAG.roundedRectangle({
539 corner1: [-e.outer/2,-e.outer/2], corner2: [e.outer/2,e.outer/2], 541 corner1: [-e.outer/2,-e.outer/2], corner2: [e.outer/2,e.outer/2],
540 roundradius: e.roundius 542 roundradius: e.roundius
541 }).subtract( 543 }).subtract(
542 FOURWINDS.map(function(w) { 544 FOURWINDS.map(function(w) {
543 return CAG.fromPoints([ 545 return CAG.fromPoints([
544 [ e.slot_width/2,e.outer/2+1], 546 [ e.slot_width/2,e.outer/2+1],
545 [ e.slot_width/2,e.outer/2-e.thickness], 547 [ e.slot_width/2,e.outer/2-e.thickness],
546 [ e.T.width/2,e.outer/2-e.thickness], 548 [ e.T.width/2,e.outer/2-e.thickness],
547 [ e.T.width/2,e.outer/2-e.thickness-e.T.thickness], 549 [ e.T.width/2,e.outer/2-e.thickness-e.T.thickness],
548 [ ix, iy ], 550 [ ix, iy ],
549 [ -ix, iy ], 551 [ -ix, iy ],
550 [ -e.T.width/2,e.outer/2-e.thickness-e.T.thickness], 552 [ -e.T.width/2,e.outer/2-e.thickness-e.T.thickness],
551 [ -e.T.width/2,e.outer/2-e.thickness], 553 [ -e.T.width/2,e.outer/2-e.thickness],
552 [ -e.slot_width/2,e.outer/2-e.thickness], 554 [ -e.slot_width/2,e.outer/2-e.thickness],
553 [ -e.slot_width/2,e.outer/2+1], 555 [ -e.slot_width/2,e.outer/2+1],
554 ]).rotateZ(w); 556 ]).rotateZ(w);
555 }) 557 })
556 ).subtract(CAG.circle({ 558 ).subtract(CAG.circle({
557 center: [0,0], radius: e.centerhole/2 559 center: [0,0], radius: e.centerhole/2
558 })).extrude({offset:[0,0,l]}); 560 })).extrude({offset:[0,0,l]});
559 rv.properties.c_top=rv.properties.c_left 561 rv.properties.c_top=rv.properties.c_left
560 = new CSG.Connector([0,0,l],[0,0,-1],[1,0,0]); 562 = new CSG.Connector([0,0,l],[0,0,-1],[1,0,0]);
561 rv.properties.c_bottom=rv.properties.c_right 563 rv.properties.c_bottom=rv.properties.c_right
562 = new CSG.Connector([0,0,0],[0,0,1],[1,0,0]); 564 = 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]); 565 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]); 566 rv.properties.P = new CSG.Connector([0,0,0],[0,0,1],[1,0,0]);
565 rv.properties.vitamin = true; 567 rv.properties.vitamin = true;
566 return rv; 568 return rv;
567 }, 569 },
568 570
569 cap: function extrusion_cap(o) { 571 cap: function extrusion_cap(o) {
570 if(!o) o = {}; 572 if(!o) o = {};
571 var e = o.extrusion || this; 573 var e = o.extrusion || this;
572 var thickness = o.thickness||2, l = o.l||5; 574 var thickness = o.thickness||2, l = o.l||5;
573 var rv = CSG.roundedCube({ 575 var rv = CSG.roundedCube({
574 corner1: [-e.outer/2,-e.outer/2,thickness], 576 corner1: [-e.outer/2,-e.outer/2,thickness],
575 corner2: [e.outer/2,e.outer/2,0], 577 corner2: [e.outer/2,e.outer/2,0],
576 roundradius: [e.roundius,e.roundius,0] 578 roundradius: [e.roundius,e.roundius,0]
577 }); 579 });
578 var fw = [0,90,180,270]; // four winds 580 var fw = [0,90,180,270]; // four winds
579 var iy = e.outer/2-e.T.depth; 581 var iy = e.outer/2-e.T.depth;
580 var ix = e.T.width/2-(e.outer/2-iy-e.thickness-e.T.thickness); 582 var ix = e.T.width/2-(e.outer/2-iy-e.thickness-e.T.thickness);
581 rv = rv.union(fw.map(function(w) { 583 rv = rv.union(fw.map(function(w) {
582 return CAG.fromPoints([ 584 return CAG.fromPoints([
583 [ e.slot_width/2,e.outer/2], 585 [ e.slot_width/2,e.outer/2],
584 [ e.slot_width/2,e.outer/2-e.thickness], 586 [ e.slot_width/2,e.outer/2-e.thickness],
585 [ e.T.width/2,e.outer/2-e.thickness], 587 [ e.T.width/2,e.outer/2-e.thickness],
586 [ e.T.width/2,e.outer/2-e.thickness-e.T.thickness], 588 [ e.T.width/2,e.outer/2-e.thickness-e.T.thickness],
587 [ ix, iy ], 589 [ ix, iy ],
588 [ -ix, iy ], 590 [ -ix, iy ],
589 [ -e.T.width/2,e.outer/2-e.thickness-e.T.thickness], 591 [ -e.T.width/2,e.outer/2-e.thickness-e.T.thickness],
590 [ -e.T.width/2,e.outer/2-e.thickness], 592 [ -e.T.width/2,e.outer/2-e.thickness],
591 [ -e.slot_width/2,e.outer/2-e.thickness], 593 [ -e.slot_width/2,e.outer/2-e.thickness],
592 [ -e.slot_width/2,e.outer/2], 594 [ -e.slot_width/2,e.outer/2],
593 ]).extrude({offset:[0,0,l+thickness]}).rotateZ(w); 595 ]).extrude({offset:[0,0,l+thickness]}).rotateZ(w);
594 })); 596 }));
595 rv.properties.P = new CSG.Connector([0,0,0],[0,0,1],[1,0,0]); 597 rv.properties.P = new CSG.Connector([0,0,0],[0,0,1],[1,0,0]);
596 return rv; 598 return rv;
597 } 599 }
598}; 600};
599 601
600var THREEWINDS = [0,120,240]; 602var THREEWINDS = [0,120,240];
601 603
602function base_sides() { 604function base_sides() {
603 return [0,1].map(function(l) { 605 return [0,1].map(function(l) {
604 return THREEWINDS.map(function(w) { 606 return THREEWINDS.map(function(w) {
605 var e = E2020.extrusion({l:CONFIG.base.el}); 607 var e = E2020.extrusion({l:CONFIG.base.el});
606 e = e.connectTo(e.properties.c_midway, 608 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]), 609 new CSG.Connector([0,-CD.base.mid_inscription_r,CONFIG.extrusion.w/2],[1,0,0],[0,0,1]),
608 false, 0); 610 false, 0);
609 return ( e.translate([0,0,CONFIG.foot.h+l*(CONFIG.extrusion.w+CONFIG.base.gap)]) 611 return ( e.translate([0,0,CONFIG.foot.h+l*(CONFIG.extrusion.w+CONFIG.base.gap)])
610 .rotateZ(w) 612 .rotateZ(w)
611 .setColor(CONFIG.color.extrusion) ); 613 .setColor(CONFIG.color.extrusion) );
612 }); 614 });
613 }); 615 });
614} 616}
615function base_extrusions() { 617function base_extrusions() {
616 var rv = union( base_sides().map(function(x){return union(x)}) ); 618 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]); 619 rv.properties.P = new CSG.Connector([0,0,0],[0,0,1],[1,0,0]);
618 return rv; 620 return rv;
619} 621}
620 622
621function columns() { 623function columns() {
622 return THREEWINDS.map(function(w) { 624 return THREEWINDS.map(function(w) {
623 return (E2020.extrusion({l:CONFIG.column.h}) 625 return (E2020.extrusion({l:CONFIG.column.h})
624 .translate([0,CD.base.column_r,CONFIG.foot.h]) 626 .translate([0,CD.base.column_r,CONFIG.foot.h])
625 .rotateZ(w).setColor(CONFIG.color.extrusion) 627 .rotateZ(w).setColor(CONFIG.color.extrusion)
626 ); 628 );
627 }); 629 });
628} 630}
629function column_extrusions() { 631function column_extrusions() {
630 var rv = union( columns() ); 632 var rv = union( columns() );
631 rv.properties.P = new CSG.Connector([0,0,0],[0,0,1],[1,0,0]); 633 rv.properties.P = new CSG.Connector([0,0,0],[0,0,1],[1,0,0]);
632 return rv; 634 return rv;
633} 635}
634 636
635function duet() { 637function duet() {
636 var C = CONFIG.duet; 638 var C = CONFIG.duet;
637 var pholes = new CSG.Properties(); 639 var pholes = new CSG.Properties();
638 var hx = C.hole_spacing.x/2; 640 var hx = C.hole_spacing.x/2;
639 var hy = C.hole_spacing.y/2; 641 var hy = C.hole_spacing.y/2;
640 var hh = { nw: [-1,1], ne: [1,1], se: [1,-1], sw: [-1,-1] }; 642 var hh = { nw: [-1,1], ne: [1,1], se: [1,-1], sw: [-1,-1] };
641 var holes = []; 643 var holes = [];
642 for(w in hh) { 644 for(w in hh) {
643 var h = hh[w],_x=h[0]*hx,_y=h[1]*hy; 645 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})); 646 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]); 647 pholes['c_'+w] = new CSG.Connector([_x,_y,0],[0,0,1],[1,0,0]);
646 } 648 }
647 rv = CSG.cube({ 649 rv = CSG.cube({
648 corner1: [-C.pcb_size.x/2, -C.pcb_size.y/2, 0], 650 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] 651 corner2: [ C.pcb_size.x/2, C.pcb_size.y/2, C.pcb_size.z]
650 }).subtract(holes).setColor(CONFIG.color.pcb).union( 652 }).subtract(holes).setColor(CONFIG.color.pcb).union(
651 CSG.cube({ 653 CSG.cube({
652 corner1: [-C.pcb_size.x/2,-C.hole_spacing.y/2+3,C.pcb_size.z], 654 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] 655 corner2: [ C.pcb_size.x/2, C.hole_spacing.y/2-3,C.h]
654 }).setColor(CONFIG.color.bulk) 656 }).setColor(CONFIG.color.bulk)
655 ); 657 );
656 rv.properties.holes = pholes; 658 rv.properties.holes = pholes;
657 rv.properties.P = new CSG.Connector([0,0,0],[0,0,1],[1,0,0]); 659 rv.properties.P = new CSG.Connector([0,0,0],[0,0,1],[1,0,0]);
658 rv.properties.vitamin = true; 660 rv.properties.vitamin = true;
659 return rv; 661 return rv;
660} 662}
661 663
662function foot() { 664function foot() {
663 var F = CONFIG.foot; 665 var F = CONFIG.foot;
664 var br = F.bolt.hd/2+F.margin; 666 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)); 667 var bh = F.zscalefactor*Math.sqrt(Math.pow(F.d/2,2)-Math.pow(br,2));
666 var th = F.h-bh; 668 var th = F.h-bh;
667 var r = 2*F.d; 669 var r = 2*F.d;
668 var rv = CSG.sphere({ // botom contorted sphere 670 var rv = CSG.sphere({ // botom contorted sphere
669 center: [0,0,0], radius: F.d/2, resolution: r 671 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 672 }).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 673 start: [0,0,bh], end: [0,0,F.h], radius: F.d/2, resolution: r
672 })).intersect(CSG.cylinder({ // cut off excess 674 })).intersect(CSG.cylinder({ // cut off excess
673 start: [0,0,0], end: [0,0,F.h], radius: F.d 675 start: [0,0,0], end: [0,0,F.h], radius: F.d
674 })).subtract([ 676 })).subtract([
675 CSG.cylinder({ // bolt hole 677 CSG.cylinder({ // bolt hole
676 start: [0,0,-1], end: [0,0,F.h+1], radius: F.bolt.d/2+PRINT.slide_tolerance 678 start: [0,0,-1], end: [0,0,F.h+1], radius: F.bolt.d/2+PRINT.slide_tolerance
677 }), CSG.cylinder({ // nut hole 679 }), CSG.cylinder({ // nut hole