-rw-r--r-- | delta.jscad | 44 |
1 files changed, 43 insertions, 1 deletions
diff --git a/delta.jscad b/delta.jscad index b718fd4..fa33a0d 100644 --- a/delta.jscad +++ b/delta.jscad | |||
@@ -1,133 +1,142 @@ | |||
1 | var PRINT = { | 1 | var 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 | 5 | fit_tolerance: .2, slide_tolerance: .4, play_tolerance: .6 |
6 | }; | 6 | }; |
7 | 7 | ||
8 | var CONFIG = { | 8 | var CONFIG = { |
9 | extrusion: { | 9 | extrusion: { |
10 | w: 20 | 10 | w: 20 |
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: { | ||
35 | d: 20*Math.sqrt(2), h: 30, | ||
36 | bolt: { d:5, l: 19, hd: 10 }, | ||
37 | margin: 2.5, | ||
38 | nut: { d: 8.6 /* TODO: */, h: 3.5 }, | ||
39 | shell: 4, | ||
40 | zscalefactor: 1.6 | ||
41 | }, | ||
34 | hotend: { | 42 | hotend: { |
35 | h: 62.4, // full assembly height | 43 | h: 62.4, // full assembly height |
36 | groove: { d:12, h:6 }, // grove diameter and height | 44 | groove: { d:12, h:6 }, // grove diameter and height |
37 | ungroove: { d:16, above:3.7, below: 3+4 } | 45 | ungroove: { d:16, above:3.7, below: 3+4 } |
38 | }, | 46 | }, |
39 | effector: { | 47 | effector: { |
40 | h: 6, | 48 | h: 6, |
41 | o: 20,// offset to the rod mounts line | 49 | o: 20,// offset to the rod mounts line |
42 | rods_apart: 40, | 50 | rods_apart: 40, |
43 | cone: { shell: 1, angle: Math.PI/6 }, | 51 | cone: { shell: 1, angle: Math.PI/6 }, |
44 | rodend: { | 52 | rodend: { |
45 | joint_w: 7,// thickness of the joint | 53 | joint_w: 7,// thickness of the joint |
46 | screw_l: 20-1, // 20 with the head | 54 | screw_l: 20-1, // 20 with the head |
47 | screw_d: 3 | 55 | screw_d: 3 |
48 | }, | 56 | }, |
49 | hotend: { margin: 2 }, | 57 | hotend: { margin: 2 }, |
50 | hinge: { | 58 | hinge: { |
51 | d: 3, w: 5, margin: 2.5, | 59 | d: 3, w: 5, margin: 2.5, |
52 | h: 1+(6+3.7)/2, // elevation + grove + top | 60 | h: 1+(6+3.7)/2, // elevation + grove + top |
53 | e: 1 // elevation | 61 | e: 1 // elevation |
54 | }, | 62 | }, |
55 | clamp: { | 63 | clamp: { |
56 | shell: 4.6, | 64 | shell: 4.6, |
57 | d: 3, | 65 | d: 3, |
58 | margin: 2.5, | 66 | margin: 2.5, |
59 | split: 0.6 | 67 | split: 0.6 |
60 | }, | 68 | }, |
61 | mswitch: { | 69 | mswitch: { |
62 | size: [ 19.8, 6, 10 ], | 70 | size: [ 19.8, 6, 10 ], |
63 | screw: { | 71 | screw: { |
64 | d: 2, h: 10/2-2, | 72 | d: 2, h: 10/2-2, |
65 | s: 1.3, // screw shell | 73 | s: 1.3, // screw shell |
66 | o: [-9.5/2,9.5/2].map(function(x) { | 74 | o: [-9.5/2,9.5/2].map(function(x) { |
67 | return -19.8/2+x; | 75 | return -19.8/2+x; |
68 | }) | 76 | }) |
69 | }, | 77 | }, |
70 | switch_x: 2.5 | 78 | switch_x: 2.5 |
71 | }, | 79 | }, |
72 | guide: { | 80 | guide: { |
73 | width: 3, height: 5+1, length: 6 | 81 | width: 3, height: 5+1, length: 6 |
74 | }, | 82 | }, |
75 | fanholder: { | 83 | fanholder: { |
76 | r: 30, | 84 | r: 30, |
77 | screw: { d: 3, m: 2.5/*margin*/ }, | 85 | screw: { d: 3, m: 2.5/*margin*/ }, |
78 | w: 3 | 86 | w: 3 |
79 | } | 87 | } |
80 | }, | 88 | }, |
81 | nut: { h: 2.3, w: 5.5 }, | 89 | nut: { h: 2.3, w: 5.5 }, |
82 | color: { | 90 | color: { |
83 | extrusion: [0.8, 0.8, 0.8, 0.8], | 91 | extrusion: [0.8, 0.8, 0.8, 0.8], |
84 | pcb: [ 0, 0.3, 0.2, 0.8 ], | 92 | pcb: [ 0, 0.3, 0.2, 0.8 ], |
85 | bulk: [ .9, .9, .9, .2 ] | 93 | bulk: [ .9, .9, .9, .2 ], |
94 | parts: [ 0, 0.8, 0, 0.9 ] | ||
86 | } | 95 | } |
87 | }; | 96 | }; |
88 | 97 | ||
89 | var CD = { | 98 | var CD = { |
90 | base: (function(){ | 99 | base: (function(){ |
91 | var rv = {}; | 100 | var rv = {}; |
92 | rv.circumscription_r = | 101 | rv.circumscription_r = |
93 | CONFIG.base.sl/2/Math.cos(Math.PI/6); | 102 | CONFIG.base.sl/2/Math.cos(Math.PI/6); |
94 | rv.outer_inscription_r = | 103 | rv.outer_inscription_r = |
95 | Math.sqrt(Math.pow(rv.circumscription_r,2)- | 104 | Math.sqrt(Math.pow(rv.circumscription_r,2)- |
96 | Math.pow(CONFIG.base.sl/2,2)); | 105 | Math.pow(CONFIG.base.sl/2,2)); |
97 | rv.mid_inscription_r = | 106 | rv.mid_inscription_r = |
98 | rv.outer_inscription_r-CONFIG.extrusion.w/2; | 107 | rv.outer_inscription_r-CONFIG.extrusion.w/2; |
99 | rv.inner_inscription_r = | 108 | rv.inner_inscription_r = |
100 | rv.outer_inscription_r-CONFIG.extrusion.w/2; | 109 | rv.outer_inscription_r-CONFIG.extrusion.w/2; |
101 | // TODO: properly calculate | 110 | // TODO: properly calculate |
102 | rv.column_r = rv.circumscription_r - 48.29; | 111 | rv.column_r = rv.circumscription_r - 48.29; |
103 | return rv; | 112 | return rv; |
104 | })() | 113 | })() |
105 | }; | 114 | }; |
106 | 115 | ||
107 | var U = { | 116 | var U = { |
108 | hypotenuse: function(a,b) { | 117 | hypotenuse: function(a,b) { |
109 | return Math.sqrt(Math.pow(a,2)+Math.pow(b,2)); | 118 | return Math.sqrt(Math.pow(a,2)+Math.pow(b,2)); |
110 | }, | 119 | }, |
111 | peek: function(x,m) { | 120 | peek: function(x,m) { |
112 | console.log(x,m); | 121 | console.log(x,m); |
113 | return x; | 122 | return x; |
114 | } | 123 | } |
115 | }; | 124 | }; |
116 | 125 | ||
117 | /* {h:,w:} */ | 126 | /* {h:,w:} */ |
118 | function nut(o) { | 127 | function nut(o) { |
119 | var rv = CSG.cylinder({ | 128 | var rv = CSG.cylinder({ |
120 | start:[0,0,0],end:[0,0,o.h], | 129 | start:[0,0,0],end:[0,0,o.h], |
121 | radius: o.w/2/Math.cos(Math.PI/6), | 130 | radius: o.w/2/Math.cos(Math.PI/6), |
122 | resolution: 6 | 131 | resolution: 6 |
123 | }); | 132 | }); |
124 | rv.properties.axis_connector = new CSG.Connector([0,0,0],[0,0,1],[0,1,0]); | 133 | rv.properties.axis_connector = new CSG.Connector([0,0,0],[0,0,1],[0,1,0]); |
125 | return rv; | 134 | return rv; |
126 | } | 135 | } |
127 | 136 | ||
128 | var E3DV6 = { | 137 | var E3DV6 = { |
129 | dimensions: { | 138 | dimensions: { |
130 | big_d: 22.3, | 139 | big_d: 22.3, |
131 | 140 | ||
132 | }, | 141 | }, |
133 | heatsink: function() { | 142 | heatsink: function() { |
@@ -539,112 +548,145 @@ function base_extrusions() { | |||
539 | var rv = union( THREEWINDS.map(function(w) { | 548 | var rv = union( THREEWINDS.map(function(w) { |
540 | var e = E2020.extrusion({l:CONFIG.base.el}); | 549 | var e = E2020.extrusion({l:CONFIG.base.el}); |
541 | e = e.connectTo(e.properties.c_midway, | 550 | e = e.connectTo(e.properties.c_midway, |
542 | new CSG.Connector([0,-CD.base.mid_inscription_r,CONFIG.extrusion.w/2],[1,0,0],[0,0,1]), | 551 | new CSG.Connector([0,-CD.base.mid_inscription_r,CONFIG.extrusion.w/2],[1,0,0],[0,0,1]), |
543 | false, 0); | 552 | false, 0); |
544 | return union( [0,CONFIG.extrusion.w+CONFIG.base.gap].map(function(z) { | 553 | return union( [0,CONFIG.extrusion.w+CONFIG.base.gap].map(function(z) { |
545 | return e.translate([0,0,z]); | 554 | return e.translate([0,0,z]); |
546 | }) ).rotateZ(w); | 555 | }) ).rotateZ(w); |
547 | }) ); | 556 | }) ); |
548 | rv.properties.P = new CSG.Connector([0,0,0],[0,0,1],[1,0,0]); | 557 | rv.properties.P = new CSG.Connector([0,0,0],[0,0,1],[1,0,0]); |
549 | return rv.setColor(CONFIG.color.extrusion); | 558 | return rv.setColor(CONFIG.color.extrusion); |
550 | } | 559 | } |
551 | 560 | ||
552 | function column_extrusions() { | 561 | function column_extrusions() { |
553 | var rv = union( THREEWINDS.map(function(w) { | 562 | var rv = union( THREEWINDS.map(function(w) { |
554 | return E2020.extrusion({l:CONFIG.column.h}).translate([0,CD.base.column_r,0]).rotateZ(w); | 563 | return E2020.extrusion({l:CONFIG.column.h}).translate([0,CD.base.column_r,0]).rotateZ(w); |
555 | }) ); | 564 | }) ); |
556 | rv.properties.P = new CSG.Connector([0,0,0],[0,0,1],[1,0,0]); | 565 | rv.properties.P = new CSG.Connector([0,0,0],[0,0,1],[1,0,0]); |
557 | return rv.setColor(CONFIG.color.extrusion); | 566 | return rv.setColor(CONFIG.color.extrusion); |
558 | } | 567 | } |
559 | 568 | ||
560 | function duet() { | 569 | function duet() { |
561 | var C = CONFIG.duet; | 570 | var C = CONFIG.duet; |
562 | var pholes = new CSG.Properties(); | 571 | var pholes = new CSG.Properties(); |
563 | var hx = C.hole_spacing.x/2; | 572 | var hx = C.hole_spacing.x/2; |
564 | var hy = C.hole_spacing.y/2; | 573 | var hy = C.hole_spacing.y/2; |
565 | var hh = { nw: [1,-1], ne: [1,1], se: [-1,1], sw: [-1,-1] }; | 574 | var hh = { nw: [1,-1], ne: [1,1], se: [-1,1], sw: [-1,-1] }; |
566 | var holes = []; | 575 | var holes = []; |
567 | for(w in hh) { | 576 | for(w in hh) { |
568 | var h = hh[w],_x=h[0]*hx,_y=h[1]*hy; | 577 | var h = hh[w],_x=h[0]*hx,_y=h[1]*hy; |
569 | holes.push(CSG.cylinder({start:[_x,_y,-1],end:[_x,_y,C.pcb_size.z+1],radius:3/2})); | 578 | holes.push(CSG.cylinder({start:[_x,_y,-1],end:[_x,_y,C.pcb_size.z+1],radius:3/2})); |
570 | pholes['c_'+w] = new CSG.Connector([_x,_y,0],[0,0,1],[1,0,0]); | 579 | pholes['c_'+w] = new CSG.Connector([_x,_y,0],[0,0,1],[1,0,0]); |
571 | } | 580 | } |
572 | rv = CSG.cube({ | 581 | rv = CSG.cube({ |
573 | corner1: [-C.pcb_size.x/2, -C.pcb_size.y/2, 0], | 582 | corner1: [-C.pcb_size.x/2, -C.pcb_size.y/2, 0], |
574 | corner2: [ C.pcb_size.x/2, C.pcb_size.y/2, C.pcb_size.z] | 583 | corner2: [ C.pcb_size.x/2, C.pcb_size.y/2, C.pcb_size.z] |
575 | }).subtract(holes).setColor(CONFIG.color.pcb).union( | 584 | }).subtract(holes).setColor(CONFIG.color.pcb).union( |
576 | CSG.cube({ | 585 | CSG.cube({ |
577 | corner1: [-C.pcb_size.x/2,-C.hole_spacing.y/2+3,C.pcb_size.z], | 586 | corner1: [-C.pcb_size.x/2,-C.hole_spacing.y/2+3,C.pcb_size.z], |
578 | corner2: [ C.pcb_size.x/2, C.hole_spacing.y/2-3,C.h] | 587 | corner2: [ C.pcb_size.x/2, C.hole_spacing.y/2-3,C.h] |
579 | }).setColor(CONFIG.color.bulk) | 588 | }).setColor(CONFIG.color.bulk) |
580 | ); | 589 | ); |
581 | rv.properties.holes = pholes; | 590 | rv.properties.holes = pholes; |
582 | rv.properties.P = new CSG.Connector([0,0,0],[0,0,1],[1,0,0]); | 591 | rv.properties.P = new CSG.Connector([0,0,0],[0,0,1],[1,0,0]); |
583 | rv.properties.vitamin = true; | 592 | rv.properties.vitamin = true; |
584 | return rv; | 593 | return rv; |
585 | } | 594 | } |
586 | 595 | ||
596 | function foot() { | ||
597 | var F = CONFIG.foot; | ||
598 | var br = F.bolt.hd/2+F.margin; | ||
599 | var bh = F.zscalefactor*Math.sqrt(Math.pow(F.d/2,2)-Math.pow(br,2)); | ||
600 | var th = F.h-bh; | ||
601 | var r = 2*F.d; | ||
602 | var rv = CSG.sphere({ // botom contorted sphere | ||
603 | center: [0,0,0], radius: F.d/2, resolution: r | ||
604 | }).scale([1,1,F.zscalefactor]).translate([0,0,bh]).union(CSG.cylinder({ // top hat | ||
605 | start: [0,0,bh], end: [0,0,F.h], radius: F.d/2, resolution: r | ||
606 | })).intersect(CSG.cylinder({ // cut off excess | ||
607 | start: [0,0,0], end: [0,0,F.h], radius: F.d | ||
608 | })).subtract([ | ||
609 | CSG.cylinder({ // bolt hole | ||
610 | start: [0,0,-1], end: [0,0,F.h+1], radius: F.bolt.d/2+PRINT.slide_tolerance | ||
611 | }), CSG.cylinder({ // nut hole | ||
612 | start: [0,0,F.h-F.nut.h-PRINT.play_tolerance], | ||
613 | end: [0,0,F.h], | ||
614 | radius: F.nut.d/2+PRINT.slide_tolerance, resolution: 6 | ||
615 | }), CSG.cylinder({ // bolthead/washer hole | ||
616 | start: [0,0,-1], end: [0,0,F.h-F.nut.h-PRINT.play_tolerance-F.shell], | ||
617 | radius: F.bolt.hd/2+PRINT.play_tolerance | ||
618 | }) | ||
619 | ]).union(CSG.cylinder({ // bridging patch | ||
620 | start: [0,0,F.h-F.nut.h-PRINT.play_tolerance-PRINT.layer_height], | ||
621 | end: [0,0,F.h-F.nut.h-PRINT.play_tolerance], | ||
622 | radius: F.nut.d/2 | ||
623 | })); | ||
624 | rv.properties.P = new CSG.Connector([0,0,F.h],[0,0,-1],[1,0,0]); | ||
625 | return rv.setColor(CONFIG.color.parts); | ||
626 | } | ||
627 | |||
587 | function refaxes(o) { | 628 | function refaxes(o) { |
588 | if(!o) o = {}; | 629 | if(!o) o = {}; |
589 | var l = o.l||20, g = o.g||0.7; | 630 | var l = o.l||20, g = o.g||0.7; |
590 | return union([ | 631 | return union([ |
591 | CSG.cylinder({start:[0,0,0],end:[l,0,0]}).setColor([1,0,0,g]), | 632 | CSG.cylinder({start:[0,0,0],end:[l,0,0]}).setColor([1,0,0,g]), |
592 | CSG.cylinder({start:[0,0,0],end:[0,l,0]}).setColor([0,1,0,g]), | 633 | CSG.cylinder({start:[0,0,0],end:[0,l,0]}).setColor([0,1,0,g]), |
593 | CSG.cylinder({start:[0,0,0],end:[0,0,l]}).setColor([0,0,1,g]) | 634 | CSG.cylinder({start:[0,0,0],end:[0,0,l]}).setColor([0,0,1,g]) |
594 | ]); | 635 | ]); |
595 | } | 636 | } |
596 | 637 | ||
597 | function P(x) { | 638 | function P(x) { |
598 | return x.connectTo(x.properties.P,new CSG.Connector([0,0,0],[0,0,1],[1,0,0]), false, 0); | 639 | return x.connectTo(x.properties.P,new CSG.Connector([0,0,0],[0,0,1],[1,0,0]), false, 0); |
599 | } | 640 | } |
600 | 641 | ||
601 | var PARTS = { | 642 | var PARTS = { |
602 | wip: function(params) { | 643 | wip: function(params) { |
644 | return foot(); | ||
603 | return union(base_extrusions(),column_extrusions(),duet()); | 645 | return union(base_extrusions(),column_extrusions(),duet()); |
604 | } | 646 | } |
605 | }; | 647 | }; |
606 | 648 | ||
607 | function main(params) { | 649 | function main(params) { |
608 | var part = params.part && PARTS[params.part]; | 650 | var part = params.part && PARTS[params.part]; |
609 | if(!part) return refaxes(); | 651 | if(!part) return refaxes(); |
610 | var rv = P(part(params)); | 652 | var rv = P(part(params)); |
611 | if(!params.print) rv = rv.union(refaxes()); | 653 | if(!params.print) rv = rv.union(refaxes()); |
612 | return rv; | 654 | return rv; |
613 | } | 655 | } |
614 | 656 | ||
615 | function _main(params) { | 657 | function _main(params) { |
616 | var e = EFFECTOR.effector(); | 658 | var e = EFFECTOR.effector(); |
617 | var hs = E3DV6.heatsink(); | 659 | var hs = E3DV6.heatsink(); |
618 | hs = hs.connectTo(hs.properties.grove_connector,e.properties.grove_connector,false,0); | 660 | hs = hs.connectTo(hs.properties.grove_connector,e.properties.grove_connector,false,0); |
619 | var ms = microswitch(); | 661 | var ms = microswitch(); |
620 | var hd = EFFECTOR.hinged({ | 662 | var hd = EFFECTOR.hinged({ |
621 | microswitch:ms,effector:e | 663 | microswitch:ms,effector:e |
622 | }); | 664 | }); |
623 | ms = ms.connectTo( | 665 | ms = ms.connectTo( |
624 | ms.properties.screw_connector[0], | 666 | ms.properties.screw_connector[0], |
625 | hd.properties.microswitch_screw_connector[0], | 667 | hd.properties.microswitch_screw_connector[0], |
626 | false, 0); | 668 | false, 0); |
627 | var hdhd = EFFECTOR.split_hinged(hd); | 669 | var hdhd = EFFECTOR.split_hinged(hd); |
628 | var fh = EFFECTOR.fanholder(); | 670 | var fh = EFFECTOR.fanholder(); |
629 | return union({ | 671 | return union({ |
630 | platform: e, | 672 | platform: e, |
631 | hinged: hdhd[1], | 673 | hinged: hdhd[1], |
632 | clamp: hdhd[0], | 674 | clamp: hdhd[0], |
633 | fanholder: fh, | 675 | fanholder: fh, |
634 | alltogethernow: [e,hdhd[0],hdhd[1], columns(),hs,ms,fh] | 676 | alltogethernow: [e,hdhd[0],hdhd[1], columns(),hs,ms,fh] |
635 | }[params.part||'alltogethernow']) | 677 | }[params.part||'alltogethernow']) |
636 | var rv = union( | 678 | var rv = union( |
637 | e, | 679 | e, |
638 | hs, | 680 | hs, |
639 | columns(), | 681 | columns(), |
640 | ///hd, | 682 | ///hd, |
641 | hdhd[0], hdhd[1], | 683 | hdhd[0], hdhd[1], |
642 | ms); | 684 | ms); |
643 | return rv; | 685 | return rv; |
644 | } | 686 | } |
645 | 687 | ||
646 | function getParameterDefinitions() { | 688 | function getParameterDefinitions() { |
647 | return [{ | 689 | return [{ |
648 | name: 'part', | 690 | name: 'part', |
649 | type: 'choice', | 691 | type: 'choice', |
650 | values: [ | 692 | values: [ |