summaryrefslogtreecommitdiffabout
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--delta.jscad29
1 files changed, 29 insertions, 0 deletions
diff --git a/delta.jscad b/delta.jscad
index 326d172..35a777c 100644
--- a/delta.jscad
+++ b/delta.jscad
@@ -1,341 +1,370 @@
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 },
150 axes: function U_axes(o) {
151 if(!o) o = {};
152 var l = o.l||20, g = o.g||0.7;
153 return union([
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]),
156 CSG.roundedCylinder({start:[0,0,0],end:[0,0,l]}).setColor([0,0,1,g])
157 ]);
158 },
159 pextract: function U_pextract(a,pn) { // TODO: monkeypatch Array
160 return a.map(function(x){return x[pn]});
161 },
162 hole: function U_hole(o) {
163 var r = o.r||o.radius||(o.d/2)||(o.diameter/2);
164 var n = Math.max(Math.round(4*r),4);
165 return CSG.cylinder({
166 start: o.start, end: o.end,
167 radius: r/Math.cos(Math.PI/n),
168 resultion: n
169 });
170 },
171
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]) },
174 P: function U_P(x) {
175 if(!x.properties.P) return x;
176 return x.connectTo(x.properties.P,U.upright(),false,0);
149 } 177 }
178
150}; 179};
151 180
152/* {h:,w:} */ 181/* {h:,w:} */
153function nut(o) { 182function nut(o) {
154 var rv = CSG.cylinder({ 183 var rv = CSG.cylinder({
155 start:[0,0,0],end:[0,0,o.h], 184 start:[0,0,0],end:[0,0,o.h],
156 radius: o.w/2/Math.cos(Math.PI/6), 185 radius: o.w/2/Math.cos(Math.PI/6),
157 resolution: 6 186 resolution: 6
158 }); 187 });
159 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]);
160 return rv; 189 return rv;
161} 190}
162 191
163var E3DV6 = { 192var E3DV6 = {
164 dimensions: { 193 dimensions: {
165 big_d: 22.3, 194 big_d: 22.3,
166 195
167 }, 196 },
168 heatsink: function() { 197 heatsink: function() {
169 var fn = 16; 198 var fn = 16;
170 var z=0; 199 var z=0;
171 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) {
172 return CSG.cylinder({ 201 return CSG.cylinder({
173 start: [0,0,z], end: [0,0,z-=x.h], 202 start: [0,0,z], end: [0,0,z-=x.h],
174 radius: x.d/2, resolution: fn 203 radius: x.d/2, resolution: fn
175 }); 204 });
176 }); 205 });
177 unite.push(CSG.cylinder({ 206 unite.push(CSG.cylinder({
178 start:[0,0,z-=1.5], end:[0,0,z-=1], 207 start:[0,0,z-=1.5], end:[0,0,z-=1],
179 radius: 16/2, resolution: fn 208 radius: 16/2, resolution: fn
180 })); 209 }));
181 for(var i=0;i<11;++i) unite.push(CSG.cylinder({ 210 for(var i=0;i<11;++i) unite.push(CSG.cylinder({
182 start:[0,0,z-=1.5], end:[0,0,z-=1], 211 start:[0,0,z-=1.5], end:[0,0,z-=1],
183 radius: this.dimensions.big_d/2, resolution: fn 212 radius: this.dimensions.big_d/2, resolution: fn
184 })); 213 }));
185 unite.push(CSG.cylinder({ 214 unite.push(CSG.cylinder({
186 start:[0,0,z], end: [0,0,-12.7], 215 start:[0,0,z], end: [0,0,-12.7],
187 radiusStart: 10/2, radiusEnd: 8.5/2, /* pretty arbitrary */ 216 radiusStart: 10/2, radiusEnd: 8.5/2, /* pretty arbitrary */
188 resolution: fn 217 resolution: fn
189 })); 218 }));
190 var rv = union(unite); 219 var rv = union(unite);
191 rv = rv.subtract([CSG.cylinder({ 220 rv = rv.subtract([CSG.cylinder({
192 start:[0,0,1], end: [0,0,z-1], 221 start:[0,0,1], end: [0,0,z-1],
193 radius: 4.2/2, resolution: fn 222 radius: 4.2/2, resolution: fn
194 }),CSG.cylinder({ 223 }),CSG.cylinder({
195 start:[0,0,1], end: [0,0,-6.7/*somewhat arbitrary*/], 224 start:[0,0,1], end: [0,0,-6.7/*somewhat arbitrary*/],
196 radius: 8/2, resolution: fn 225 radius: 8/2, resolution: fn
197 }),CSG.cylinder({ 226 }),CSG.cylinder({
198 start:[0,0,z-1], end: [0,0,z+14.8], 227 start:[0,0,z-1], end: [0,0,z+14.8],
199 radius: 6/2 /*M7*/, resolution: fn 228 radius: 6/2 /*M7*/, resolution: fn
200 })]); 229 })]);
201 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]);
202 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]);
203 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]);
204 return rv.setColor([0.8,0.8,0.8,0.9]); 233 return rv.setColor([0.8,0.8,0.8,0.9]);
205 } 234 }
206}; 235};
207 236
208var EFFECTOR = { 237var EFFECTOR = {
209 /* {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} */
210 cone: function effector_cone(o) { 239 cone: function effector_cone(o) {
211 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));
212 var rv = CSG.cylinder({ 241 var rv = CSG.cylinder({
213 start: [0,0,0], end: [0,0,o.l], 242 start: [0,0,0], end: [0,0,o.l],
214 radiusStart: rs, radiusEnd: re, 243 radiusStart: rs, radiusEnd: re,
215 resolution: Math.floor(rs*2*2) 244 resolution: Math.floor(rs*2*2)
216 }).subtract(CSG.cylinder({ 245 }).subtract(CSG.cylinder({
217 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,
218 //resolution: Math.floor(o.sd*2*2) 247 //resolution: Math.floor(o.sd*2*2)
219 })); 248 }));
220 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]);
221 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]);
222 var nuthole = nut(CONFIG.nut); 251 var nuthole = nut(CONFIG.nut);
223 rv = rv.subtract(nuthole.connectTo( 252 rv = rv.subtract(nuthole.connectTo(
224 nuthole.properties.axis_connector, rv.properties.bottom_connector, 253 nuthole.properties.axis_connector, rv.properties.bottom_connector,
225 false, 0 254 false, 0
226 )); 255 ));
227 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*/}));
228 }, 257 },
229 platform_bb: function platform_bb() { 258 platform_bb: function platform_bb() {
230 var e = CONFIG.effector; 259 var e = CONFIG.effector;
231 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);
232 var rv = CSG.sphere({ 261 var rv = CSG.sphere({
233 center: [0,0,e.h/2], radius: r, 262 center: [0,0,e.h/2], radius: r,
234 resolution: r*2*2 263 resolution: r*2*2
235 }).intersect(CSG.cube({ 264 }).intersect(CSG.cube({
236 corner1: [-r,-r,0], corner2: [r,r,e.h] 265 corner1: [-r,-r,0], corner2: [r,r,e.h]
237 })); 266 }));
238 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]);
239 return rv; 268 return rv;
240 }, 269 },
241 effector: function effector_effector() { 270 effector: function effector_effector() {
242 var e = CONFIG.effector; 271 var e = CONFIG.effector;
243 var conel = e.rodend.screw_l-e.rodend.joint_w; 272 var conel = e.rodend.screw_l-e.rodend.joint_w;
244 var nutr = CONFIG.nut.w/2/Math.cos(Math.PI/6); 273 var nutr = CONFIG.nut.w/2/Math.cos(Math.PI/6);
245 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});
246 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
247 var ropen = E3DV6.dimensions.big_d/2+e.hotend.margin; 276 var ropen = E3DV6.dimensions.big_d/2+e.hotend.margin;
248 var rmount = this.rmount = (rcorner+ropen)/2; 277 var rmount = this.rmount = (rcorner+ropen)/2;
249 var rv = []; 278 var rv = [];
250 for(var a=0;a<360;a+=120) { 279 for(var a=0;a<360;a+=120) {
251 rv.push(union([-1,1].map(function(s) { 280 rv.push(union([-1,1].map(function(s) {
252 return cone.connectTo(cone.properties.top_connector, 281 return cone.connectTo(cone.properties.top_connector,
253 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]),
254 false, 0); 283 false, 0);
255 })).union(CSG.cube({ 284 })).union(CSG.cube({
256 corner1:[e.rods_apart/2-conel+.1,e.o-nutr,0], 285 corner1:[e.rods_apart/2-conel+.1,e.o-nutr,0],
257 corner2:[-e.rods_apart/2+conel-.1, 286 corner2:[-e.rods_apart/2+conel-.1,
258 -rcorner, 287 -rcorner,
259 e.h] 288 e.h]
260 })).rotateZ(a)); 289 })).rotateZ(a));
261 } 290 }
262 rv.push(CSG.cylinder({ 291 rv.push(CSG.cylinder({
263 start:[0,0,0], end:[0,0,e.h], 292 start:[0,0,0], end:[0,0,e.h],
264 radius: U.hypotenuse(e.o-nutr,e.rods_apart/2-conel) 293 radius: U.hypotenuse(e.o-nutr,e.rods_apart/2-conel)
265 })); 294 }));
266 rv = union(rv).intersect(this.platform_bb()).subtract(CSG.cylinder({ 295 rv = union(rv).intersect(this.platform_bb()).subtract(CSG.cylinder({
267 start:[0,0,-1], end:[0,0,e.h+1], 296 start:[0,0,-1], end:[0,0,e.h+1],
268 radius: ropen, resolution: ropen*4 297 radius: ropen, resolution: ropen*4
269 })).subtract([/*0, probe here*/120,240].map(function(x) { /* nut pockets */ 298 })).subtract([/*0, probe here*/120,240].map(function(x) { /* nut pockets */
270 return CSG.cube({ 299 return CSG.cube({
271 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],
272 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]
273 }).union(CSG.cylinder({ 302 }).union(CSG.cylinder({
274 start:[0,-rmount,-1], end:[0,-rmount,e.h+1], 303 start:[0,-rmount,-1], end:[0,-rmount,e.h+1],
275 radius: 3/2 // XXX: 304 radius: 3/2 // XXX:
276 })).subtract(CSG.cylinder({ 305 })).subtract(CSG.cylinder({
277 start:[0,-rmount,(e.h+CONFIG.nut.h)/2], 306 start:[0,-rmount,(e.h+CONFIG.nut.h)/2],
278 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],
279 radius: 3/2+.1 308 radius: 3/2+.1
280 })).rotateZ(x); 309 })).rotateZ(x);
281 })).subtract( CSG.cylinder({ // pulldown screw 310 })).subtract( CSG.cylinder({ // pulldown screw
282 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],
283 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],
284 radius: 3/2+1 /*XXX: config */ 313 radius: 3/2+1 /*XXX: config */
285 })).subtract( CSG.cylinder({ /* switch-screw */ 314 })).subtract( CSG.cylinder({ /* switch-screw */
286 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],
287 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],
288 radius: e.mswitch.screw.d/2 317 radius: e.mswitch.screw.d/2
289 })); 318 }));
290 // add hinges 319 // add hinges
291 rv.properties.hinge_connector=new CSG.Properties(); 320 rv.properties.hinge_connector=new CSG.Properties();
292 var hinges_apart=e.rods_apart/2-conel; 321 var hinges_apart=e.rods_apart/2-conel;
293 rv = rv.union([-1,1].map(function hinge(s) { 322 rv = rv.union([-1,1].map(function hinge(s) {
294 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]);
295 return CSG.cube({ 324 return CSG.cube({
296 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],
297 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]
298 }).union(CSG.cylinder({ 327 }).union(CSG.cylinder({
299 start: [s*hinges_apart,e.o,e.h+e.hinge.h], 328 start: [s*hinges_apart,e.o,e.h+e.hinge.h],
300 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],
301 radius: e.hinge.d/2+e.hinge.margin 330 radius: e.hinge.d/2+e.hinge.margin
302 })).subtract(CSG.cylinder({ 331 })).subtract(CSG.cylinder({
303 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],
304 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],
305 radius: e.hinge.d/2 334 radius: e.hinge.d/2
306 })); 335 }));
307 })); 336 }));
308 // add clamp guides 337 // add clamp guides
309 var cgrr = e.guide.width/3; 338 var cgrr = e.guide.width/3;
310 rv = rv.union([-1,1].map(function guide(s) { 339 rv = rv.union([-1,1].map(function guide(s) {
311 return CSG.roundedCube({ 340 return CSG.roundedCube({
312 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],
313 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],
314 roundradius: cgrr 343 roundradius: cgrr
315 }).intersect(CSG.cube({ 344 }).intersect(CSG.cube({
316 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],
317 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],
318 roundradius: cgrr 347 roundradius: cgrr
319 })); 348 }));
320 })); 349 }));
321 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]);
322 rv.properties.rcorner = rcorner; 351 rv.properties.rcorner = rcorner;
323 return rv.setColor([0.4,0.8,0.4,0.9]); 352 return rv.setColor([0.4,0.8,0.4,0.9]);
324 }, 353 },
325 hinged: function effector_hinged(o) { 354 hinged: function effector_hinged(o) {
326 var e = CONFIG.effector; 355 var e = CONFIG.effector;
327 var conel = e.rodend.screw_l-e.rodend.joint_w; 356 var conel = e.rodend.screw_l-e.rodend.joint_w;
328 var hinges_apart = e.rods_apart/2-conel; 357 var hinges_apart = e.rods_apart/2-conel;
329 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
330 var hhh = CONFIG.hotend.groove.h+CONFIG.hotend.ungroove.above; 359 var hhh = CONFIG.hotend.groove.h+CONFIG.hotend.ungroove.above;
331 var rv = CSG.cylinder({ /* hinge */ 360 var rv = CSG.cylinder({ /* hinge */
332 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],
333 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],
334 radius: e.hinge.d/2+e.hinge.margin 363 radius: e.hinge.d/2+e.hinge.margin
335 }).union( /* lower hotend holder */ 364 }).union( /* lower hotend holder */
336 CSG.cylinder({ 365 CSG.cylinder({
337 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],
338 radius: hhr 367 radius: hhr
339 }).subtract(CSG.cylinder({ 368 }).subtract(CSG.cylinder({
340 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],
341 radius: CONFIG.hotend.groove.d/2 +PRINT.fit_tolerance 370 radius: CONFIG.hotend.groove.d/2 +PRINT.fit_tolerance