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) (show 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
@@ -85,785 +85,787 @@ var CONFIG = {
85 s: 1.3, // screw shell 85 s: 1.3, // screw shell
86 o: [-9.5/2,9.5/2].map(function(x) { 86 o: [-9.5/2,9.5/2].map(function(x) {
87 return -19.8/2+x; 87 return -19.8/2+x;
88 }) 88 })
89 }, 89 },
90 switch_x: 2.5 90 switch_x: 2.5
91 }, 91 },
92 guide: { 92 guide: {
93 width: 3, height: 5+1, length: 6 93 width: 3, height: 5+1, length: 6
94 }, 94 },
95 fanholder: { 95 fanholder: {
96 r: 30, 96 r: 30,
97 screw: { d: 3, m: 2.5/*margin*/ }, 97 screw: { d: 3, m: 2.5/*margin*/ },
98 w: 3 98 w: 3
99 } 99 }
100 }, 100 },
101 nut: { h: 2.3, w: 5.5 }, 101 nut: { h: 2.3, w: 5.5 },
102 color: { 102 color: {
103 extrusion: [0.8, 0.8, 0.8, 0.8], 103 extrusion: [0.8, 0.8, 0.8, 0.8],
104 pcb: [ 0, 0.3, 0.2, 0.8 ], 104 pcb: [ 0, 0.3, 0.2, 0.8 ],
105 bulk: [ .9, .9, .9, .2 ], 105 bulk: [ .9, .9, .9, .2 ],
106 parts: [ 0, 0.8, 0, 0.9 ], 106 parts: [ 0, 0.8, 0, 0.9 ],
107 softparts: [ 0, 0, 0.8, 0.9 ], 107 softparts: [ 0, 0, 0.8, 0.9 ],
108 heatbed: [0.8, 0.8, 0.8, 0.8 ], 108 heatbed: [0.8, 0.8, 0.8, 0.8 ],
109 glass: [0.9, 0.9, 0.9, 0.7 ] 109 glass: [0.9, 0.9, 0.9, 0.7 ]
110 } 110 }
111}; 111};
112 112
113var CD = { 113var CD = {
114 base: (function(){ 114 base: (function(){
115 var rv = {}; 115 var rv = {};
116 rv.circumscription_r = 116 rv.circumscription_r =
117 CONFIG.base.sl/2/Math.cos(Math.PI/6); 117 CONFIG.base.sl/2/Math.cos(Math.PI/6);
118 rv.outer_inscription_r = 118 rv.outer_inscription_r =
119 Math.sqrt(Math.pow(rv.circumscription_r,2)- 119 Math.sqrt(Math.pow(rv.circumscription_r,2)-
120 Math.pow(CONFIG.base.sl/2,2)); 120 Math.pow(CONFIG.base.sl/2,2));
121 rv.mid_inscription_r = 121 rv.mid_inscription_r =
122 rv.outer_inscription_r-CONFIG.extrusion.w/2; 122 rv.outer_inscription_r-CONFIG.extrusion.w/2;
123 rv.inner_inscription_r = 123 rv.inner_inscription_r =
124 rv.outer_inscription_r-CONFIG.extrusion.w; 124 rv.outer_inscription_r-CONFIG.extrusion.w;
125 // TODO: properly calculate 125 // TODO: properly calculate
126 rv.column_r = rv.circumscription_r - 48.29; 126 rv.column_r = rv.circumscription_r - 48.29;
127 return rv; 127 return rv;
128 })(), 128 })(),
129 duetholder: (function() { 129 duetholder: (function() {
130 var rv = {}; 130 var rv = {};
131 var s = CONFIG.base.sl; 131 var s = CONFIG.base.sl;
132 var l = CONFIG.duet.hole_spacing.x; 132 var l = CONFIG.duet.hole_spacing.x;
133 var w = CONFIG.duet.hole_spacing.y; 133 var w = CONFIG.duet.hole_spacing.y;
134 var h = s*Math.cos(Math.PI/6); 134 var h = s*Math.cos(Math.PI/6);
135 var h1 = h*(1-l/s); 135 var h1 = h*(1-l/s);
136 rv.distance = (h1-w)/3; // hole to side 136 rv.distance = (h1-w)/3; // hole to side
137 return rv; 137 return rv;
138 })() 138 })()
139}; 139};
140console.log(CONFIG); console.log(CD); 140console.log(CONFIG); console.log(CD);
141 141
142var U = { 142var U = {
143 hypotenuse: function(a,b) { 143 hypotenuse: function(a,b) {
144 return Math.sqrt(Math.pow(a,2)+Math.pow(b,2)); 144 return Math.sqrt(Math.pow(a,2)+Math.pow(b,2));
145 }, 145 },
146 peek: function(x,m) { 146 peek: function(x,m) {
147 console.log(x,m); 147 console.log(x,m);
148 return x; 148 return x;
149 }, 149 },
150 axes: function U_axes(o) { 150 axes: function U_axes(o) {
151 if(!o) o = {}; 151 if(!o) o = {};
152 var l = o.l||20, g = o.g||0.7; 152 var l = o.l||20, g = o.g||0.7;
153 return union([ 153 return union([
154 CSG.roundedCylinder({start:[0,0,0],end:[l,0,0]}).setColor([1,0,0,g]), 154 CSG.roundedCylinder({start:[0,0,0],end:[l,0,0]}).setColor([1,0,0,g]),
155 CSG.roundedCylinder({start:[0,0,0],end:[0,l,0]}).setColor([0,1,0,g]), 155 CSG.roundedCylinder({start:[0,0,0],end:[0,l,0]}).setColor([0,1,0,g]),
156 CSG.roundedCylinder({start:[0,0,0],end:[0,0,l]}).setColor([0,0,1,g]) 156 CSG.roundedCylinder({start:[0,0,0],end:[0,0,l]}).setColor([0,0,1,g])
157 ]); 157 ]);
158 }, 158 },
159 pextract: function U_pextract(a,pn) { // TODO: monkeypatch Array 159 pextract: function U_pextract(a,pn) { // TODO: monkeypatch Array
160 return a.map(function(x){return x[pn]}); 160 return a.map(function(x){return x[pn]});
161 }, 161 },
162 hole: function U_hole(o) { 162 hole: function U_hole(o) {
163 var r = o.r||o.radius||(o.d/2)||(o.diameter/2); 163 var r = o.r||o.radius||(o.d/2)||(o.diameter/2);
164 var n = Math.max(Math.round(4*r),4); 164 var n = Math.max(Math.round(4*r),4);
165 return CSG.cylinder({ 165 return CSG.cylinder({
166 start: o.start, end: o.end, 166 start: o.start, end: o.end,
167 radius: r/Math.cos(Math.PI/n), 167 radius: r/Math.cos(Math.PI/n),
168 resultion: n 168 resultion: n
169 }); 169 });
170 }, 170 },
171 171
172 upright: function U_upright() { return new CSG.Connector([0,0,0],[0,0,1],[1,0,0]) }, 172 upright: function U_upright() { return new CSG.Connector([0,0,0],[0,0,1],[1,0,0]) },
173 downright: function U_downright() { return new CSG.Connector([0,0,0],[0,0,-1],[1,0,0]) }, 173 downright: function U_downright() { return new CSG.Connector([0,0,0],[0,0,-1],[1,0,0]) },
174 P: function U_P(x) { 174 P: function U_P(x) {
175 if(!x.properties.P) return x; 175 if(!x.properties.P) return x;
176 return x.connectTo(x.properties.P,U.upright(),false,0); 176 return x.connectTo(x.properties.P,U.upright(),false,0);
177 } 177 }
178 178
179}; 179};
180 180
181/* {h:,w:} */ 181/* {h:,w:} */
182function nut(o) { 182function nut(o) {
183 var rv = CSG.cylinder({ 183 var rv = CSG.cylinder({
184 start:[0,0,0],end:[0,0,o.h], 184 start:[0,0,0],end:[0,0,o.h],
185 radius: o.w/2/Math.cos(Math.PI/6), 185 radius: o.w/2/Math.cos(Math.PI/6),
186 resolution: 6 186 resolution: 6
187 }); 187 });
188 rv.properties.axis_connector = new CSG.Connector([0,0,0],[0,0,1],[0,1,0]); 188 rv.properties.axis_connector = new CSG.Connector([0,0,0],[0,0,1],[0,1,0]);
189 return rv; 189 return rv;
190} 190}
191 191
192var E3DV6 = { 192var E3DV6 = {
193 dimensions: { 193 dimensions: {
194 big_d: 22.3, 194 big_d: 22.3,
195 195
196 }, 196 },
197 heatsink: function() { 197 heatsink: function() {
198 var fn = 16; 198 var fn = 16;
199 var z=0; 199 var z=0;
200 var unite = [ {d:16,h:3.7},{d:12,h:6},{d:16,h:3} ].map(function(x) { 200 var unite = [ {d:16,h:3.7},{d:12,h:6},{d:16,h:3} ].map(function(x) {
201 return CSG.cylinder({ 201 return CSG.cylinder({
202 start: [0,0,z], end: [0,0,z-=x.h], 202 start: [0,0,z], end: [0,0,z-=x.h],
203 radius: x.d/2, resolution: fn 203 radius: x.d/2, resolution: fn
204 }); 204 });
205 }); 205 });
206 unite.push(CSG.cylinder({ 206 unite.push(CSG.cylinder({
207 start:[0,0,z-=1.5], end:[0,0,z-=1], 207 start:[0,0,z-=1.5], end:[0,0,z-=1],
208 radius: 16/2, resolution: fn 208 radius: 16/2, resolution: fn
209 })); 209 }));
210 for(var i=0;i<11;++i) unite.push(CSG.cylinder({ 210 for(var i=0;i<11;++i) unite.push(CSG.cylinder({
211 start:[0,0,z-=1.5], end:[0,0,z-=1], 211 start:[0,0,z-=1.5], end:[0,0,z-=1],
212 radius: this.dimensions.big_d/2, resolution: fn 212 radius: this.dimensions.big_d/2, resolution: fn
213 })); 213 }));
214 unite.push(CSG.cylinder({ 214 unite.push(CSG.cylinder({
215 start:[0,0,z], end: [0,0,-12.7], 215 start:[0,0,z], end: [0,0,-12.7],
216 radiusStart: 10/2, radiusEnd: 8.5/2, /* pretty arbitrary */ 216 radiusStart: 10/2, radiusEnd: 8.5/2, /* pretty arbitrary */
217 resolution: fn 217 resolution: fn
218 })); 218 }));
219 var rv = union(unite); 219 var rv = union(unite);
220 rv = rv.subtract([CSG.cylinder({ 220 rv = rv.subtract([CSG.cylinder({
221 start:[0,0,1], end: [0,0,z-1], 221 start:[0,0,1], end: [0,0,z-1],
222 radius: 4.2/2, resolution: fn 222 radius: 4.2/2, resolution: fn
223 }),CSG.cylinder({ 223 }),CSG.cylinder({
224 start:[0,0,1], end: [0,0,-6.7/*somewhat arbitrary*/], 224 start:[0,0,1], end: [0,0,-6.7/*somewhat arbitrary*/],
225 radius: 8/2, resolution: fn 225 radius: 8/2, resolution: fn
226 }),CSG.cylinder({ 226 }),CSG.cylinder({
227 start:[0,0,z-1], end: [0,0,z+14.8], 227 start:[0,0,z-1], end: [0,0,z+14.8],
228 radius: 6/2 /*M7*/, resolution: fn 228 radius: 6/2 /*M7*/, resolution: fn
229 })]); 229 })]);
230 rv.properties.pushfit_connector = new CSG.Connector([0,0,0],[0,0,-1],[1,0,0]); 230 rv.properties.pushfit_connector = new CSG.Connector([0,0,0],[0,0,-1],[1,0,0]);
231 rv.properties.heatbreak_connector = new CSG.Connector([0,0,z+14.8],[0,0,-1],[1,0,0]); 231 rv.properties.heatbreak_connector = new CSG.Connector([0,0,z+14.8],[0,0,-1],[1,0,0]);
232 rv.properties.grove_connector = new CSG.Connector([0,0,-3.7-3],[0,0,1],[1,0,0]); 232 rv.properties.grove_connector = new CSG.Connector([0,0,-3.7-3],[0,0,1],[1,0,0]);
233 return rv.setColor([0.8,0.8,0.8,0.9]); 233 return rv.setColor([0.8,0.8,0.8,0.9]);
234 } 234 }
235}; 235};
236 236
237var EFFECTOR = { 237var EFFECTOR = {
238 /* {sd: screw diameter, l: cone length, s: screw shell, a: angle from axis} */ 238 /* {sd: screw diameter, l: cone length, s: screw shell, a: angle from axis} */
239 cone: function effector_cone(o) { 239 cone: function effector_cone(o) {
240 var re = o.sd/2+o.s, rs = re+o.l*Math.tan(o.a||(Math.PI/4)); 240 var re = o.sd/2+o.s, rs = re+o.l*Math.tan(o.a||(Math.PI/4));
241 var rv = CSG.cylinder({ 241 var rv = CSG.cylinder({
242 start: [0,0,0], end: [0,0,o.l], 242 start: [0,0,0], end: [0,0,o.l],
243 radiusStart: rs, radiusEnd: re, 243 radiusStart: rs, radiusEnd: re,
244 resolution: Math.floor(rs*2*2) 244 resolution: Math.floor(rs*2*2)
245 }).subtract(CSG.cylinder({ 245 }).subtract(CSG.cylinder({
246 start:[0,0,-1], end:[0,0,o.l+1], radius: o.sd, 246 start:[0,0,-1], end:[0,0,o.l+1], radius: o.sd,
247 //resolution: Math.floor(o.sd*2*2) 247 //resolution: Math.floor(o.sd*2*2)
248 })); 248 }));
249 rv.properties.top_connector = new CSG.Connector([0,0,o.l],[0,0,-1],[1,0,0]); 249 rv.properties.top_connector = new CSG.Connector([0,0,o.l],[0,0,-1],[1,0,0]);
250 rv.properties.bottom_connector = new CSG.Connector([0,0,0],[0,0,1],[1,0,0]); 250 rv.properties.bottom_connector = new CSG.Connector([0,0,0],[0,0,1],[1,0,0]);
251 var nuthole = nut(CONFIG.nut); 251 var nuthole = nut(CONFIG.nut);
252 rv = rv.subtract(nuthole.connectTo( 252 rv = rv.subtract(nuthole.connectTo(
253 nuthole.properties.axis_connector, rv.properties.bottom_connector, 253 nuthole.properties.axis_connector, rv.properties.bottom_connector,
254 false, 0 254 false, 0
255 )); 255 ));
256 return rv.intersect(CSG.cylinder({start:[0,0,0],end:[0,0,o.l],radius:6/*TODO:calculate*/})); 256 return rv.intersect(CSG.cylinder({start:[0,0,0],end:[0,0,o.l],radius:6/*TODO:calculate*/}));
257 }, 257 },
258 platform_bb: function platform_bb() { 258 platform_bb: function platform_bb() {
259 var e = CONFIG.effector; 259 var e = CONFIG.effector;
260 var r = U.hypotenuse(e.rods_apart/2,e.o+e.rodend.screw_d/2+e.cone.shell); 260 var r = U.hypotenuse(e.rods_apart/2,e.o+e.rodend.screw_d/2+e.cone.shell);
261 var rv = CSG.sphere({ 261 var rv = CSG.sphere({
262 center: [0,0,e.h/2], radius: r, 262 center: [0,0,e.h/2], radius: r,
263 resolution: r*2*2 263 resolution: r*2*2
264 }).intersect(CSG.cube({ 264 }).intersect(CSG.cube({
265 corner1: [-r,-r,0], corner2: [r,r,e.h] 265 corner1: [-r,-r,0], corner2: [r,r,e.h]
266 })); 266 }));
267 rv.properties.base_connector = new CSG.Connector([0,0,0],[0,0,1],[1,0,0]); 267 rv.properties.base_connector = new CSG.Connector([0,0,0],[0,0,1],[1,0,0]);
268 return rv; 268 return rv;
269 }, 269 },
270 effector: function effector_effector() { 270 effector: function effector_effector() {
271 var e = CONFIG.effector; 271 var e = CONFIG.effector;
272 var conel = e.rodend.screw_l-e.rodend.joint_w; 272 var conel = e.rodend.screw_l-e.rodend.joint_w;
273 var nutr = CONFIG.nut.w/2/Math.cos(Math.PI/6); 273 var nutr = CONFIG.nut.w/2/Math.cos(Math.PI/6);
274 var cone = this.cone({sd:e.rodend.screw_d/2,l:conel,s:e.cone.shell,a:e.cone.angle}); 274 var cone = this.cone({sd:e.rodend.screw_d/2,l:conel,s:e.cone.shell,a:e.cone.angle});
275 var rcorner = U.hypotenuse(e.o-e.rodend.screw_d/2-e.cone.shell,e.rods_apart/2)-3.85; //XXX:config/calc 275 var rcorner = U.hypotenuse(e.o-e.rodend.screw_d/2-e.cone.shell,e.rods_apart/2)-3.85; //XXX:config/calc
276 var ropen = E3DV6.dimensions.big_d/2+e.hotend.margin; 276 var ropen = E3DV6.dimensions.big_d/2+e.hotend.margin;
277 var rmount = this.rmount = (rcorner+ropen)/2; 277 var rmount = this.rmount = (rcorner+ropen)/2;
278 var rv = []; 278 var rv = [];
279 for(var a=0;a<360;a+=120) { 279 for(var a=0;a<360;a+=120) {
280 rv.push(union([-1,1].map(function(s) { 280 rv.push(union([-1,1].map(function(s) {
281 return cone.connectTo(cone.properties.top_connector, 281 return cone.connectTo(cone.properties.top_connector,
282 new CSG.Connector([s*e.rods_apart/2,e.o,e.h/2],[-s,0,0],[0,0,1]), 282 new CSG.Connector([s*e.rods_apart/2,e.o,e.h/2],[-s,0,0],[0,0,1]),
283 false, 0); 283 false, 0);
284 })).union(CSG.cube({ 284 })).union(CSG.cube({
285 corner1:[e.rods_apart/2-conel+.1,e.o-nutr,0], 285 corner1:[e.rods_apart/2-conel+.1,e.o-nutr,0],
286 corner2:[-e.rods_apart/2+conel-.1, 286 corner2:[-e.rods_apart/2+conel-.1,
287 -rcorner, 287 -rcorner,
288 e.h] 288 e.h]
289 })).rotateZ(a)); 289 })).rotateZ(a));
290 } 290 }
291 rv.push(CSG.cylinder({ 291 rv.push(CSG.cylinder({
292 start:[0,0,0], end:[0,0,e.h], 292 start:[0,0,0], end:[0,0,e.h],
293 radius: U.hypotenuse(e.o-nutr,e.rods_apart/2-conel) 293 radius: U.hypotenuse(e.o-nutr,e.rods_apart/2-conel)
294 })); 294 }));
295 rv = union(rv).intersect(this.platform_bb()).subtract(CSG.cylinder({ 295 rv = union(rv).intersect(this.platform_bb()).subtract(CSG.cylinder({
296 start:[0,0,-1], end:[0,0,e.h+1], 296 start:[0,0,-1], end:[0,0,e.h+1],
297 radius: ropen, resolution: ropen*4 297 radius: ropen, resolution: ropen*4
298 })).subtract([/*0, probe here*/120,240].map(function(x) { /* nut pockets */ 298 })).subtract([/*0, probe here*/120,240].map(function(x) { /* nut pockets */
299 return CSG.cube({ 299 return CSG.cube({
300 corner1:[-CONFIG.nut.w/2,0,(e.h-CONFIG.nut.h)/2], 300 corner1:[-CONFIG.nut.w/2,0,(e.h-CONFIG.nut.h)/2],
301 corner2:[CONFIG.nut.w/2,-rcorner-1,(e.h+CONFIG.nut.h)/2] 301 corner2:[CONFIG.nut.w/2,-rcorner-1,(e.h+CONFIG.nut.h)/2]
302 }).union(CSG.cylinder({ 302 }).union(CSG.cylinder({
303 start:[0,-rmount,-1], end:[0,-rmount,e.h+1], 303 start:[0,-rmount,-1], end:[0,-rmount,e.h+1],
304 radius: 3/2 // XXX: 304 radius: 3/2 // XXX:
305 })).subtract(CSG.cylinder({ 305 })).subtract(CSG.cylinder({
306 start:[0,-rmount,(e.h+CONFIG.nut.h)/2], 306 start:[0,-rmount,(e.h+CONFIG.nut.h)/2],
307 end:[0,-rmount,(e.h+CONFIG.nut.h)/2+PRINT.layer_height*3/2], 307 end:[0,-rmount,(e.h+CONFIG.nut.h)/2+PRINT.layer_height*3/2],
308 radius: 3/2+.1 308 radius: 3/2+.1
309 })).rotateZ(x); 309 })).rotateZ(x);
310 })).subtract( CSG.cylinder({ // pulldown screw 310 })).subtract( CSG.cylinder({ // pulldown screw
311 start: [0,-rcorner+e.mswitch.size[1]+PRINT.extrusion_width+3/2/*XXX:conf*/,-1], 311 start: [0,-rcorner+e.mswitch.size[1]+PRINT.extrusion_width+3/2/*XXX:conf*/,-1],
312 end: [0,-rcorner+e.mswitch.size[1]+PRINT.extrusion_width+3/2/*XXX:conf*/,e.h+1], 312 end: [0,-rcorner+e.mswitch.size[1]+PRINT.extrusion_width+3/2/*XXX:conf*/,e.h+1],
313 radius: 3/2+1 /*XXX: config */ 313 radius: 3/2+1 /*XXX: config */
314 })).subtract( CSG.cylinder({ /* switch-screw */ 314 })).subtract( CSG.cylinder({ /* switch-screw */
315 start: [e.mswitch.switch_x,-rcorner+e.mswitch.size[1]/2,-1], 315 start: [e.mswitch.switch_x,-rcorner+e.mswitch.size[1]/2,-1],
316 end: [e.mswitch.switch_x,-rcorner+e.mswitch.size[1]/2,e.h+1], 316 end: [e.mswitch.switch_x,-rcorner+e.mswitch.size[1]/2,e.h+1],
317 radius: e.mswitch.screw.d/2 317 radius: e.mswitch.screw.d/2
318 })); 318 }));
319 // add hinges 319 // add hinges
320 rv.properties.hinge_connector=new CSG.Properties(); 320 rv.properties.hinge_connector=new CSG.Properties();
321 var hinges_apart=e.rods_apart/2-conel; 321 var hinges_apart=e.rods_apart/2-conel;
322 rv = rv.union([-1,1].map(function hinge(s) { 322 rv = rv.union([-1,1].map(function hinge(s) {
323 rv.properties.hinge_connector[s]=new CSG.Connector([s*hinges_apart,e.o,e.h+e.hinge.h],[s,0,0],[0,0,1]); 323 rv.properties.hinge_connector[s]=new CSG.Connector([s*hinges_apart,e.o,e.h+e.hinge.h],[s,0,0],[0,0,1]);
324 return CSG.cube({ 324 return CSG.cube({
325 corner1: [s*hinges_apart,e.o-e.hinge.margin-e.hinge.d/2,e.h], 325 corner1: [s*hinges_apart,e.o-e.hinge.margin-e.hinge.d/2,e.h],
326 corner2: [s*(hinges_apart+e.hinge.w),e.o+e.hinge.margin+e.hinge.d/2,e.h+e.hinge.h] 326 corner2: [s*(hinges_apart+e.hinge.w),e.o+e.hinge.margin+e.hinge.d/2,e.h+e.hinge.h]
327 }).union(CSG.cylinder({ 327 }).union(CSG.cylinder({
328 start: [s*hinges_apart,e.o,e.h+e.hinge.h], 328 start: [s*hinges_apart,e.o,e.h+e.hinge.h],
329 end: [s*(hinges_apart+e.hinge.w),e.o,e.h+e.hinge.h], 329 end: [s*(hinges_apart+e.hinge.w),e.o,e.h+e.hinge.h],
330 radius: e.hinge.d/2+e.hinge.margin 330 radius: e.hinge.d/2+e.hinge.margin
331 })).subtract(CSG.cylinder({ 331 })).subtract(CSG.cylinder({
332 start: [s*(hinges_apart-1),e.o,e.h+e.hinge.h], 332 start: [s*(hinges_apart-1),e.o,e.h+e.hinge.h],
333 end: [s*(hinges_apart+e.hinge.w+1),e.o,e.h+e.hinge.h], 333 end: [s*(hinges_apart+e.hinge.w+1),e.o,e.h+e.hinge.h],
334 radius: e.hinge.d/2 334 radius: e.hinge.d/2
335 })); 335 }));
336 })); 336 }));
337 // add clamp guides 337 // add clamp guides
338 var cgrr = e.guide.width/3; 338 var cgrr = e.guide.width/3;
339 rv = rv.union([-1,1].map(function guide(s) { 339 rv = rv.union([-1,1].map(function guide(s) {
340 return CSG.roundedCube({ 340 return CSG.roundedCube({
341 center: [s*(e.mswitch.size[0]+PRINT.slide_tolerance+e.guide.width)/2,-rcorner+e.guide.length/2,e.h+e.guide.height/2-cgrr], 341 center: [s*(e.mswitch.size[0]+PRINT.slide_tolerance+e.guide.width)/2,-rcorner+e.guide.length/2,e.h+e.guide.height/2-cgrr],
342 radius: [e.guide.width/2,e.guide.length/2,e.guide.height/2+cgrr], 342 radius: [e.guide.width/2,e.guide.length/2,e.guide.height/2+cgrr],
343 roundradius: cgrr 343 roundradius: cgrr
344 }).intersect(CSG.cube({ 344 }).intersect(CSG.cube({
345 center: [s*(e.mswitch.size[0]+PRINT.slide_tolerance+e.guide.width)/2,-rcorner+e.guide.length/2,e.h+e.guide.height/2], 345 center: [s*(e.mswitch.size[0]+PRINT.slide_tolerance+e.guide.width)/2,-rcorner+e.guide.length/2,e.h+e.guide.height/2],
346 radius: [e.guide.width/2,e.guide.length/2,e.guide.height/2+.1], 346 radius: [e.guide.width/2,e.guide.length/2,e.guide.height/2+.1],
347 roundradius: cgrr 347 roundradius: cgrr
348 })); 348 }));
349 })); 349 }));
350 rv.properties.grove_connector = new CSG.Connector([0,0,e.h+e.hinge.e+6/2],[0,0,1],[1,0,0]); 350 rv.properties.grove_connector = new CSG.Connector([0,0,e.h+e.hinge.e+6/2],[0,0,1],[1,0,0]);
351 rv.properties.rcorner = rcorner; 351 rv.properties.rcorner = rcorner;
352 return rv.setColor([0.4,0.8,0.4,0.9]); 352 return rv.setColor([0.4,0.8,0.4,0.9]);
353 }, 353 },
354 hinged: function effector_hinged(o) { 354 hinged: function effector_hinged(o) {
355 var e = CONFIG.effector; 355 var e = CONFIG.effector;
356 var conel = e.rodend.screw_l-e.rodend.joint_w; 356 var conel = e.rodend.screw_l-e.rodend.joint_w;
357 var hinges_apart = e.rods_apart/2-conel; 357 var hinges_apart = e.rods_apart/2-conel;
358 var hhr = e.o-e.hinge.d/2-e.hinge.margin; // hotend holder radius 358 var hhr = e.o-e.hinge.d/2-e.hinge.margin; // hotend holder radius
359 var hhh = CONFIG.hotend.groove.h+CONFIG.hotend.ungroove.above; 359 var hhh = CONFIG.hotend.groove.h+CONFIG.hotend.ungroove.above;
360 var rv = CSG.cylinder({ /* hinge */ 360 var rv = CSG.cylinder({ /* hinge */
361 start: [-hinges_apart+PRINT.slide_tolerance,e.o,e.h+e.hinge.h], 361 start: [-hinges_apart+PRINT.slide_tolerance,e.o,e.h+e.hinge.h],
362 end: [hinges_apart-PRINT.slide_tolerance,e.o,e.h+e.hinge.h], 362 end: [hinges_apart-PRINT.slide_tolerance,e.o,e.h+e.hinge.h],
363 radius: e.hinge.d/2+e.hinge.margin 363 radius: e.hinge.d/2+e.hinge.margin
364 }).union( /* lower hotend holder */ 364 }).union( /* lower hotend holder */
365 CSG.cylinder({ 365 CSG.cylinder({
366 start: [0,0,e.h+e.hinge.e], end: [0,0,e.h+e.hinge.e+CONFIG.hotend.groove.h], 366 start: [0,0,e.h+e.hinge.e], end: [0,0,e.h+e.hinge.e+CONFIG.hotend.groove.h],
367 radius: hhr 367 radius: hhr
368 }).subtract(CSG.cylinder({ 368 }).subtract(CSG.cylinder({
369 start: [0,0,e.h+e.hinge.e-1], end: [0,0,e.h+e.hinge.e+CONFIG.hotend.groove.h+1], 369 start: [0,0,e.h+e.hinge.e-1], end: [0,0,e.h+e.hinge.e+CONFIG.hotend.groove.h+1],
370 radius: CONFIG.hotend.groove.d/2 +PRINT.fit_tolerance 370 radius: CONFIG.hotend.groove.d/2 +PRINT.fit_tolerance
371 })) 371 }))
372 ).union( /* upper hotend holder */ 372 ).union( /* upper hotend holder */
373 CSG.cylinder({ 373 CSG.cylinder({
374 start: [0,0,e.h+e.hinge.e+CONFIG.hotend.groove.h], 374 start: [0,0,e.h+e.hinge.e+CONFIG.hotend.groove.h],
375 end: [0,0,e.h+e.hinge.e+CONFIG.hotend.groove.h+CONFIG.hotend.ungroove.above], 375 end: [0,0,e.h+e.hinge.e+CONFIG.hotend.groove.h+CONFIG.hotend.ungroove.above],
376 radius: hhr 376 radius: hhr
377 }).subtract(CSG.cylinder({ 377 }).subtract(CSG.cylinder({
378 start: [0,0,e.h+e.hinge.e+CONFIG.hotend.groove.h-1], 378 start: [0,0,e.h+e.hinge.e+CONFIG.hotend.groove.h-1],
379 end: [0,0,e.h+e.hinge.e+CONFIG.hotend.groove.h+CONFIG.hotend.ungroove.above+1], 379 end: [0,0,e.h+e.hinge.e+CONFIG.hotend.groove.h+CONFIG.hotend.ungroove.above+1],
380 radius: CONFIG.hotend.ungroove.d/2 +PRINT.fit_tolerance 380 radius: CONFIG.hotend.ungroove.d/2 +PRINT.fit_tolerance
381 })) 381 }))
382 ).union( /* connect mount with hinge */ 382 ).union( /* connect mount with hinge */
383 CSG.cube({ 383 CSG.cube({
384 corner1: [-hinges_apart+PRINT.slide_tolerance,CONFIG.hotend.ungroove.d/2+PRINT.fit_tolerance,e.h+e.hinge.e], 384 corner1: [-hinges_apart+PRINT.slide_tolerance,CONFIG.hotend.ungroove.d/2+PRINT.fit_tolerance,e.h+e.hinge.e],
385 corner2: [hinges_apart-PRINT.slide_tolerance,e.o,e.h+e.hinge.h+e.hinge.d/2+e.hinge.margin] 385 corner2: [hinges_apart-PRINT.slide_tolerance,e.o,e.h+e.hinge.h+e.hinge.d/2+e.hinge.margin]
386 }) 386 })
387 ).subtract( /* hinge screwhole */ 387 ).subtract( /* hinge screwhole */
388 CSG.cylinder({ 388 CSG.cylinder({
389 start: [-hinges_apart-1,e.o,e.h+e.hinge.h], 389 start: [-hinges_apart-1,e.o,e.h+e.hinge.h],
390 end: [hinges_apart+1,e.o,e.h+e.hinge.h], 390 end: [hinges_apart+1,e.o,e.h+e.hinge.h],
391 radius: e.hinge.d/2 391 radius: e.hinge.d/2
392 }) 392 })
393 ).union( /* hold clamp together */ 393 ).union( /* hold clamp together */
394 [-1,1].map(function(s) { 394 [-1,1].map(function(s) {
395 return CSG.roundedCube({ 395 return CSG.roundedCube({
396 corner1: [s*(-hhr-e.clamp.margin*2-e.clamp.d),-e.clamp.shell,e.h+e.hinge.e], 396 corner1: [s*(-hhr-e.clamp.margin*2-e.clamp.d),-e.clamp.shell,e.h+e.hinge.e],
397 corner2: [s*(-CONFIG.hotend.ungroove.d/2-PRINT.fit_tolerance),+e.clamp.shell,e.h+e.hinge.e+hhh], 397 corner2: [s*(-CONFIG.hotend.ungroove.d/2-PRINT.fit_tolerance),+e.clamp.shell,e.h+e.hinge.e+hhh],
398 roundradius: 1.5 398 roundradius: 1.5
399 }); 399 });
400 }) 400 })
401 ).subtract( /* screws for holding clamp */ 401 ).subtract( /* screws for holding clamp */
402 [-1,1].map(function(s) { 402 [-1,1].map(function(s) {
403 var nuthole = nut(CONFIG.nut); 403 var nuthole = nut(CONFIG.nut);
404 var x = s*(-hhr-e.clamp.margin-e.clamp.d/2); 404 var x = s*(-hhr-e.clamp.margin-e.clamp.d/2);
405 return CSG.cylinder({ 405 return CSG.cylinder({
406 start: [x,-e.clamp.shell-1,e.h+e.hinge.e+hhh/2], 406 start: [x,-e.clamp.shell-1,e.h+e.hinge.e+hhh/2],
407 end: [x,e.clamp.shell+1,e.h+e.hinge.e+hhh/2], 407 end: [x,e.clamp.shell+1,e.h+e.hinge.e+hhh/2],
408 radius: e.clamp.d/2 408 radius: e.clamp.d/2
409 }).union(nuthole.connectTo( 409 }).union(nuthole.connectTo(
410 nuthole.properties.axis_connector, 410 nuthole.properties.axis_connector,
411 new CSG.Connector([x,e.clamp.shell,e.h+e.hinge.e+hhh/2],[0,-1,0],[0,0,1]), 411 new CSG.Connector([x,e.clamp.shell,e.h+e.hinge.e+hhh/2],[0,-1,0],[0,0,1]),
412 false, 0 412 false, 0
413 )).union(CSG.cylinder({ 413 )).union(CSG.cylinder({
414 start: [x,-e.clamp.shell-1,e.h+e.hinge.e+hhh/2], 414 start: [x,-e.clamp.shell-1,e.h+e.hinge.e+hhh/2],
415 end: [x,0,e.h+e.hinge.e+hhh/2], 415 end: [x,0,e.h+e.hinge.e+hhh/2],
416 radius: e.clamp.d/2+PRINT.slide_tolerance 416 radius: e.clamp.d/2+PRINT.slide_tolerance
417 })); 417 }));
418 }) 418 })
419 ); 419 );
420 var ms = o.microswitch; 420 var ms = o.microswitch;
421 var msedge = o.effector.properties.rcorner; 421 var msedge = o.effector.properties.rcorner;
422 var msh = 9.5; // microswitch holes apart 422 var msh = 9.5; // microswitch holes apart
423 var mshh = Math.abs(ms.properties.switch_connector.point.z-ms.properties.screw_connector[0].point.z); // microswitch holes height 423 var mshh = Math.abs(ms.properties.switch_connector.point.z-ms.properties.screw_connector[0].point.z); // microswitch holes height
424 rv = rv.union(CSG.cube({ // connect clamp with microswitch 424 rv = rv.union(CSG.cube({ // connect clamp with microswitch
425 corner1: [-ms.properties.microswitch.size.x/2,-msedge+.1,e.h+e.hinge.e], 425 corner1: [-ms.properties.microswitch.size.x/2,-msedge+.1,e.h+e.hinge.e],
426 corner2: [+ms.properties.microswitch.size.x/2,-CONFIG.hotend.ungroove.d/2-PRINT.fit_tolerance,e.h+e.hinge.e+hhh] 426 corner2: [+ms.properties.microswitch.size.x/2,-CONFIG.hotend.ungroove.d/2-PRINT.fit_tolerance,e.h+e.hinge.e+hhh]
427 })).union([-msh/2,msh/2].map(function(x) { // shell for microswitch screws 427 })).union([-msh/2,msh/2].map(function(x) { // shell for microswitch screws
428 return CSG.roundedCylinder({ 428 return CSG.roundedCylinder({
429 start: [x,-CONFIG.hotend.ungroove.d/2-PRINT.fit_tolerance-(e.mswitch.screw.d/2+e.mswitch.screw.s),e.h+e.hinge.e+mshh], 429 start: [x,-CONFIG.hotend.ungroove.d/2-PRINT.fit_tolerance-(e.mswitch.screw.d/2+e.mswitch.screw.s),e.h+e.hinge.e+mshh],
430 end: [x,-msedge+ms.properties.microswitch.size.y,e.h+e.hinge.e+mshh], 430 end: [x,-msedge+ms.properties.microswitch.size.y,e.h+e.hinge.e+mshh],
431 radius: e.mswitch.screw.d/2+e.mswitch.screw.s 431 radius: e.mswitch.screw.d/2+e.mswitch.screw.s
432 }); 432 });
433 })).subtract(CSG.cube({ // cut off excess if any 433 })).subtract(CSG.cube({ // cut off excess if any
434 corner1:[-hhr,-msedge+ms.properties.microswitch.size.y,e.h+e.hinge.e-1], 434 corner1:[-hhr,-msedge+ms.properties.microswitch.size.y,e.h+e.hinge.e-1],
435 corner2:[hhr,-msedge-1,e.h+e.hinge.e+hhh+e.mswitch.screw.d+e.mswitch.screw.s+1] 435 corner2:[hhr,-msedge-1,e.h+e.hinge.e+hhh+e.mswitch.screw.d+e.mswitch.screw.s+1]
436 })).subtract([-msh/2,msh/2].map(function(x) { return CSG.roundedCylinder({ // screwholes 436 })).subtract([-msh/2,msh/2].map(function(x) { return CSG.roundedCylinder({ // screwholes
437 start: [x,-CONFIG.hotend.ungroove.d/2-PRINT.fit_tolerance-(e.mswitch.screw.d/2+e.mswitch.screw.s),e.h+e.hinge.e+mshh], 437 start: [x,-CONFIG.hotend.ungroove.d/2-PRINT.fit_tolerance-(e.mswitch.screw.d/2+e.mswitch.screw.s),e.h+e.hinge.e+mshh],
438 end: [x,-msedge+ms.properties.microswitch.size.y,e.h+e.hinge.e+mshh], 438 end: [x,-msedge+ms.properties.microswitch.size.y,e.h+e.hinge.e+mshh],
439 radius: e.mswitch.screw.d/2 439 radius: e.mswitch.screw.d/2
440 })})).subtract(CSG.cylinder({ // pulldown screw 440 })})).subtract(CSG.cylinder({ // pulldown screw
441 start:[0,-msedge+ms.properties.microswitch.size.y+3/2/*XXX:config*/+PRINT.extrusion_width,e.h+e.hinge.e-1], 441 start:[0,-msedge+ms.properties.microswitch.size.y+3/2/*XXX:config*/+PRINT.extrusion_width,e.h+e.hinge.e-1],
442 end:[0,-msedge+ms.properties.microswitch.size.y+3/2/*XXX:config*/+PRINT.extrusion_width,e.h+e.hinge.e+hhh+1], 442 end:[0,-msedge+ms.properties.microswitch.size.y+3/2/*XXX:config*/+PRINT.extrusion_width,e.h+e.hinge.e+hhh+1],
443 radius: 3/2/*XXX:config*/ 443 radius: 3/2/*XXX:config*/
444 })); 444 }));
445 rv.properties.microswitch_screw_connector = new CSG.Properties(); 445 rv.properties.microswitch_screw_connector = new CSG.Properties();
446 [-msh/2,msh/2].forEach(function(x,i) { 446 [-msh/2,msh/2].forEach(function(x,i) {
447 rv.properties.microswitch_screw_connector[i] = new CSG.Connector( 447 rv.properties.microswitch_screw_connector[i] = new CSG.Connector(
448 [x,-msedge,e.h+e.hinge.e+mshh], 448 [x,-msedge,e.h+e.hinge.e+mshh],
449 [0,1,0], [0,0,-1] 449 [0,1,0], [0,0,-1]
450 ); 450 );
451 }); 451 });
452 return rv.setColor([0.3,0.8,0.3,0.9]); 452 return rv.setColor([0.3,0.8,0.3,0.9]);
453 }, 453 },
454 split_hinged: function effector_split_hinged(hinged) { 454 split_hinged: function effector_split_hinged(hinged) {
455 var e = CONFIG.effector; 455 var e = CONFIG.effector;
456 var b = hinged.getBounds(); 456 var b = hinged.getBounds();
457 var ymax = Math.max(Math.abs(b[0].y),Math.abs(b[1].y)); 457 var ymax = Math.max(Math.abs(b[0].y),Math.abs(b[1].y));
458 var zmax = Math.max(b[0].z,b[1].z); 458 var zmax = Math.max(b[0].z,b[1].z);
459 return [-1,1].map(function(s) { 459 return [-1,1].map(function(s) {
460 return hinged.intersect(CSG.cube({ 460 return hinged.intersect(CSG.cube({
461 corner1: [Math.min(b[0].x,b[1].x)-1,s*e.clamp.split/2,-zmax-1], 461 corner1: [Math.min(b[0].x,b[1].x)-1,s*e.clamp.split/2,-zmax-1],
462 corner2: [Math.max(b[0].x,b[1].x)+1,s*(ymax+1),zmax+1] 462 corner2: [Math.max(b[0].x,b[1].x)+1,s*(ymax+1),zmax+1]
463 })); 463 }));
464 }); 464 });
465 }, 465 },
466 fanholder: function effector_fanholder() { 466 fanholder: function effector_fanholder() {
467 var fh = CONFIG.effector.fanholder; 467 var fh = CONFIG.effector.fanholder;
468 var od = fh.screw.d+2*fh.screw.m; 468 var od = fh.screw.d+2*fh.screw.m;
469 return linear_extrude({height:fh.w},hull( 469 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
678 start: [0,0,F.h-F.nut.h-PRINT.play_tolerance], 680 start: [0,0,F.h-F.nut.h-PRINT.play_tolerance],
679 end: [0,0,F.h], 681 end: [0,0,F.h],
680 radius: F.nut.d/2+PRINT.slide_tolerance, resolution: 6 682 radius: F.nut.d/2+PRINT.slide_tolerance, resolution: 6
681 }), CSG.cylinder({ // bolthead/washer hole 683 }), CSG.cylinder({ // bolthead/washer hole
682 start: [0,0,-1], end: [0,0,F.h-F.nut.h-PRINT.play_tolerance-F.shell], 684 start: [0,0,-1], end: [0,0,F.h-F.nut.h-PRINT.play_tolerance-F.shell],
683 radius: F.bolt.hd/2+PRINT.play_tolerance 685 radius: F.bolt.hd/2+PRINT.play_tolerance
684 }) 686 })
685 ]).union(CSG.cylinder({ // bridging patch 687 ]).union(CSG.cylinder({ // bridging patch
686 start: [0,0,F.h-F.nut.h-PRINT.play_tolerance-PRINT.layer_height], 688 start: [0,0,F.h-F.nut.h-PRINT.play_tolerance-PRINT.layer_height],
687 end: [0,0,F.h-F.nut.h-PRINT.play_tolerance], 689 end: [0,0,F.h-F.nut.h-PRINT.play_tolerance],
688 radius: F.nut.d/2 690 radius: F.nut.d/2
689 })); 691 }));
690 rv.properties.c_column = new CSG.Connector([0,0,F.h],[0,0,1],[1,0,0]); 692 rv.properties.c_column = new CSG.Connector([0,0,F.h],[0,0,1],[1,0,0]);
691 rv.properties.c_shoe = new CSG.Connector([0,0,0],[0,0,1],[1,0,0]); 693 rv.properties.c_shoe = new CSG.Connector([0,0,0],[0,0,1],[1,0,0]);
692 rv.properties.P = new CSG.Connector([0,0,F.h],[0,0,-1],[1,0,0]); 694 rv.properties.P = new CSG.Connector([0,0,F.h],[0,0,-1],[1,0,0]);
693 return rv.setColor(CONFIG.color.parts); 695 return rv.setColor(CONFIG.color.parts);
694} 696}
695function shoe() { 697function shoe() {
696 var F = CONFIG.foot; 698 var F = CONFIG.foot;
697 var rv = CSG.cylinder({ 699 var rv = CSG.cylinder({
698 start: [0,0,0], end: [0,0,F.foot.ho], 700 start: [0,0,0], end: [0,0,F.foot.ho],
699 radius: F.bolt.hd/2+F.margin 701 radius: F.bolt.hd/2+F.margin
700 }).union(CSG.cylinder({ 702 }).union(CSG.cylinder({
701 start: [0,0,0], end: [0,0,F.foot.ho+F.foot.hi], 703 start: [0,0,0], end: [0,0,F.foot.ho+F.foot.hi],
702 radius: F.bolt.hd/2+PRINT.play_tolerance-PRINT.fit_tolerance 704 radius: F.bolt.hd/2+PRINT.play_tolerance-PRINT.fit_tolerance
703 })); 705 }));
704 rv.properties.c_foot = new CSG.Connector([0,0,F.foot.ho],[0,0,1],[1,0,0]); 706 rv.properties.c_foot = new CSG.Connector([0,0,F.foot.ho],[0,0,1],[1,0,0]);
705 rv.properties.P = new CSG.Connector([0,0,0],[0,0,1],[1,0,0]); 707 rv.properties.P = new CSG.Connector([0,0,0],[0,0,1],[1,0,0]);
706 return rv.setColor(CONFIG.color.softparts); 708 return rv.setColor(CONFIG.color.softparts);
707} 709}
708 710
709function duetholder() { 711function duetholder() {
710 var DH = CONFIG.duetholder; 712 var DH = CONFIG.duetholder;
711 var DHD = CD.duetholder; 713 var DHD = CD.duetholder;
712 var hw = DH.bolt.head.d+2*DH.margin; 714 var hw = DH.bolt.head.d+2*DH.margin;
713 var s = DH.bolt.l-CONFIG.extrusion.slotdepth+PRINT.play_tolerance*2; 715 var s = DH.bolt.l-CONFIG.extrusion.slotdepth+PRINT.play_tolerance*2;
714 var lower = CONFIG.foot.h-2*DH.s; 716 var lower = CONFIG.foot.h-2*DH.s;
715 var hl = DHD.distance-CONFIG.extrusion.w; 717 var hl = DHD.distance-CONFIG.extrusion.w;
716 var rv = union([ 718 var rv = union([
717 CSG.cube({ // vertical 719 CSG.cube({ // vertical
718 corner1: [-hw/2,s,CONFIG.extrusion.w], 720 corner1: [-hw/2,s,CONFIG.extrusion.w],
719 corner2: [hw/2,0,-lower] 721 corner2: [hw/2,0,-lower]
720 }), 722 }),
721 CSG.cube({ // horizontal extrusion 723 CSG.cube({ // horizontal extrusion
722 corner1: [-hw/2,-CONFIG.extrusion.w,0], 724 corner1: [-hw/2,-CONFIG.extrusion.w,0],
723 corner2: [ hw/2,0,-s] 725 corner2: [ hw/2,0,-s]
724 }), 726 }),
725 CSG.cube({ // horizontal 727 CSG.cube({ // horizontal
726 corner1: [-hw/2,0,-lower], 728 corner1: [-hw/2,0,-lower],
727 corner2: [hw/2,hl,-lower+DH.s] 729 corner2: [hw/2,hl,-lower+DH.s]
728 }), 730 }),
729 CSG.cylinder({ // boltend of horizontal part 731 CSG.cylinder({ // boltend of horizontal part
730 start: [0,hl,-lower], end: [0,hl,-lower+DH.s], 732 start: [0,hl,-lower], end: [0,hl,-lower+DH.s],
731 radius: hw/2 733 radius: hw/2
732 }) 734 })
733 ]); 735 ]);
734 rv = rv.subtract([ 736 rv = rv.subtract([
735 CSG.cylinder({ // through vertical 737 CSG.cylinder({ // through vertical
736 start: [0,-1,CONFIG.extrusion.w/2], end: [0,s+1,CONFIG.extrusion.w/2], 738 start: [0,-1,CONFIG.extrusion.w/2], end: [0,s+1,CONFIG.extrusion.w/2],
737 radius: DH.bolt.d/2+PRINT.slide_tolerance 739 radius: DH.bolt.d/2+PRINT.slide_tolerance
738 }), 740 }),
739 CSG.cylinder({ // through horizontal to extrusion 741 CSG.cylinder({ // through horizontal to extrusion
740 start: [0,-CONFIG.extrusion.w/2,-s-1], 742 start: [0,-CONFIG.extrusion.w/2,-s-1],
741 end: [0,-CONFIG.extrusion.w/2,1], 743 end: [0,-CONFIG.extrusion.w/2,1],
742 radius: DH.bolt.d/2+PRINT.slide_tolerance 744 radius: DH.bolt.d/2+PRINT.slide_tolerance
743 }), 745 }),
744 CSG.cube({ // cut off 746 CSG.cube({ // cut off
745 corner1: [-hw/2-1,-2*s,0], 747 corner1: [-hw/2-1,-2*s,0],
746 corner2: [hw/2+1,0,-2*s] 748 corner2: [hw/2+1,0,-2*s]
747 }).rotateX(45).translate([0,-CONFIG.extrusion.w,0]), 749 }).rotateX(45).translate([0,-CONFIG.extrusion.w,0]),
748 CSG.cylinder({ // duet bolt 750 CSG.cylinder({ // duet bolt
749 start: [0,hl,-lower], end: [0,hl,-lower+DH.s], 751 start: [0,hl,-lower], end: [0,hl,-lower+DH.s],
750 radius: DH.bolt.d/2+PRINT.slide_tolerance 752 radius: DH.bolt.d/2+PRINT.slide_tolerance
751 }) 753 })
752 ]); 754 ]);
753 var cp = [0,hl,-lower+DH.s]; 755 var cp = [0,hl,-lower+DH.s];
754 rv.properties.duet = new CSG.Properties(); 756 rv.properties.duet = new CSG.Properties();
755 rv.properties.duet.c_sw = new CSG.Connector(cp,[0,0,1],[1,0,0]); 757 rv.properties.duet.c_sw = new CSG.Connector(cp,[0,0,1],[1,0,0]);
756 rv.properties.duet.c_se = new CSG.Connector(cp,[0,0,1],[1,0,0]); 758 rv.properties.duet.c_se = new CSG.Connector(cp,[0,0,1],[1,0,0]);
757 rv.properties.duet.c_ne = new CSG.Connector(cp,[0,0,1],[-Math.cos(Math.PI/3),-Math.sin(Math.PI/3),0]); 759 rv.properties.duet.c_ne = new CSG.Connector(cp,[0,0,1],[-Math.cos(Math.PI/3),-Math.sin(Math.PI/3),0]);
758 rv.properties.duet.c_nw = new CSG.Connector(cp,[0,0,1],[-Math.cos(Math.PI/3),Math.sin(Math.PI/3),0]); 760 rv.properties.duet.c_nw = new CSG.Connector(cp,[0,0,1],[-Math.cos(Math.PI/3),Math.sin(Math.PI/3),0]);
759 rv.properties.c_h = new CSG.Connector([0,-CONFIG.extrusion.w/2,0],[0,0,1],[1,0,0]); 761 rv.properties.c_h = new CSG.Connector([0,-CONFIG.extrusion.w/2,0],[0,0,1],[1,0,0]);
760 rv.properties.c_v = new CSG.Connector([0,0,CONFIG.extrusion.w/2],[0,-1,0],[0,0,1]); 762 rv.properties.c_v = new CSG.Connector([0,0,CONFIG.extrusion.w/2],[0,-1,0],[0,0,1]);
761 rv.properties.P = new CSG.Connector([-hw/2,0,0],[1,0,0],[0,1,0]); 763 rv.properties.P = new CSG.Connector([-hw/2,0,0],[1,0,0],[0,1,0]);
762 return rv.setColor(CONFIG.color.parts); 764 return rv.setColor(CONFIG.color.parts);
763} 765}
764 766
765function heatbed() { 767function heatbed() {
766 var rv = CSG.cylinder({ 768 var rv = CSG.cylinder({
767 start: [0,0,0], end: [0,0,CONFIG.heatbed.h], 769 start: [0,0,0], end: [0,0,CONFIG.heatbed.h],
768 radius: CONFIG.heatbed.r, resolution: 72 770 radius: CONFIG.heatbed.r, resolution: 72
769 }); 771 });
770 var screw = CSG.cylinder({ 772 var screw = CSG.cylinder({
771 start: [0,-CONFIG.heatbed.sr,-1], 773 start: [0,-CONFIG.heatbed.sr,-1],
772 end: [0,-CONFIG.heatbed.sr,CONFIG.heatbed.h+1], 774 end: [0,-CONFIG.heatbed.sr,CONFIG.heatbed.h+1],
773 radius: 3/2 775 radius: 3/2
774 }); 776 });
775 var screws = []; 777 var screws = [];
776 for(var a=0;a<360;a+=60) screws.push(screw.rotateZ(a)); // TODO: connectors 778 for(var a=0;a<360;a+=60) screws.push(screw.rotateZ(a)); // TODO: connectors
777 rv = rv.subtract(screws); 779 rv = rv.subtract(screws);
778 rv.properties.c_glass = new CSG.Connector([0,0,CONFIG.heatbed.h],[0,0,1],[1,0,0]); 780 rv.properties.c_glass = new CSG.Connector([0,0,CONFIG.heatbed.h],[0,0,1],[1,0,0]);
779 rv.properties.P = new CSG.Connector( 781 rv.properties.P = new CSG.Connector(
780 [0,0,-CONFIG.foot.h-CONFIG.extrusion.w*2-CONFIG.base.gap-CONFIG.bedholder.h], 782 [0,0,-CONFIG.foot.h-CONFIG.extrusion.w*2-CONFIG.base.gap-CONFIG.bedholder.h],
781 [0,0,1],[1,0,0]); 783 [0,0,1],[1,0,0]);
782 rv.properties.vitamin = true; 784 rv.properties.vitamin = true;
783 return rv.setColor(CONFIG.color.heatbed); 785 return rv.setColor(CONFIG.color.heatbed);
784} 786}
785function glass() { 787function glass() {
786 var rv = CSG.cylinder({ 788 var rv = CSG.cylinder({
787 start: [0,0,0], end: [0,0,CONFIG.glass.h], 789 start: [0,0,0], end: [0,0,CONFIG.glass.h],
788 radius: CONFIG.glass.r, resolution: 72 790 radius: CONFIG.glass.r, resolution: 72
789 }); 791 });
790 rv.properties.c_bed = new CSG.Connector([0,0,0],[0,0,1],[1,0,0]); 792 rv.properties.c_bed = new CSG.Connector([0,0,0],[0,0,1],[1,0,0]);
791 rv.properties.P = new CSG.Connector([0,0,-CONFIG.foot.h-CONFIG.heatbed.h],[0,0,1],[1,0,0]); 793 rv.properties.P = new CSG.Connector([0,0,-CONFIG.foot.h-CONFIG.heatbed.h],[0,0,1],[1,0,0]);
792 rv.properties.vitamin = true; 794 rv.properties.vitamin = true;
793 return rv.setColor(CONFIG.color.glass); 795 return rv.setColor(CONFIG.color.glass);
794} 796}
795function platform() { 797function platform() {
796 var b = heatbed(); 798 var b = heatbed();
797 var g = glass(); 799 var g = glass();
798 g = g.connectTo(g.properties.c_bed,b.properties.c_glass,false,0); 800 g = g.connectTo(g.properties.c_bed,b.properties.c_glass,false,0);
799 return b.union(g); 801 return b.union(g);
800} 802}
801 803
802function bedholder(params) { 804function bedholder(params) {
803 var h0 = CONFIG.foot.h+CONFIG.extrusion.w*2+CONFIG.base.gap; 805 var h0 = CONFIG.foot.h+CONFIG.extrusion.w*2+CONFIG.base.gap;
804 var e_h=E2020.T.thickness; // height of the bump for extrusion 806 var e_h=E2020.T.thickness; // height of the bump for extrusion
805 var e_w=E2020.slot_width-PRINT.fit_tolerance; // width of the bump for extrusion 807 var e_w=E2020.slot_width-PRINT.fit_tolerance; // width of the bump for extrusion
806 var e_o=E2020.slot_width+PRINT.fit_tolerance; // opening for the T-Nut width 808 var e_o=E2020.slot_width+PRINT.fit_tolerance; // opening for the T-Nut width
807 var rv = CSG.cylinder({ 809 var rv = CSG.cylinder({
808 start: [0,0,h0], end: [0,0,h0+CONFIG.bedholder.h], 810 start: [0,0,h0], end: [0,0,h0+CONFIG.bedholder.h],
809 radiusStart: CD.base.outer_inscription_r, 811 radiusStart: CD.base.outer_inscription_r,
810 radiusEnd: CD.base.outer_inscription_r+CONFIG.bedholder.h/2, 812 radiusEnd: CD.base.outer_inscription_r+CONFIG.bedholder.h/2,
811 resolution: 240 813 resolution: 240
812 }); 814 });
813 rv=rv.intersect(CSG.cube({ 815 rv=rv.intersect(CSG.cube({
814 corner1: [-CONFIG.extrusion.w/2,-CD.base.inner_inscription_r,h0], 816 corner1: [-CONFIG.extrusion.w/2,-CD.base.inner_inscription_r,h0],
815 corner2: [ CONFIG.extrusion.w/2,-CD.base.mid_inscription_r*2,h0+2*CONFIG.bedholder.h] 817 corner2: [ CONFIG.extrusion.w/2,-CD.base.mid_inscription_r*2,h0+2*CONFIG.bedholder.h]
816 })); 818 }));
817 819
818 rv=rv.union(CSG.cube({ // bump to fix on extrusion 820 rv=rv.union(CSG.cube({ // bump to fix on extrusion
819 corner1: [-CONFIG.extrusion.w/2,-CD.base.mid_inscription_r-e_w/2,h0], 821 corner1: [-CONFIG.extrusion.w/2,-CD.base.mid_inscription_r-e_w/2,h0],
820 corner2: [ CONFIG.extrusion.w/2,-CD.base.mid_inscription_r+e_w/2,h0-e_h] 822 corner2: [ CONFIG.extrusion.w/2,-CD.base.mid_inscription_r+e_w/2,h0-e_h]
821 }).subtract( 823 }).subtract(
822 CSG.cube({center:[0,0,0],radius:[(e_o+2*e_h)/(2*Math.sqrt(2)),e_w+2,(e_o+2*e_h)/(2*Math.sqrt(2))]}) 824 CSG.cube({center:[0,0,0],radius:[(e_o+2*e_h)/(2*Math.sqrt(2)),e_w+2,(e_o+2*e_h)/(2*Math.sqrt(2))]})
823 .rotateY(45) 825 .rotateY(45)
824 .translate([0,-CD.base.mid_inscription_r,h0-e_h]) 826 .translate([0,-CD.base.mid_inscription_r,h0-e_h])
825 )); 827 ));
826 828
827 var ebolt_s = CONFIG.bedholder.bolt.l-CONFIG.extrusion.slotdepth+PRINT.play_tolerance*2; 829 var ebolt_s = CONFIG.bedholder.bolt.l-CONFIG.extrusion.slotdepth+PRINT.play_tolerance*2;
828 rv=rv.subtract([ 830 rv=rv.subtract([
829 CSG.cylinder({ // base screw 831 CSG.cylinder({ // base screw
830 start: [0,-CD.base.mid_inscription_r,h0-1], 832 start: [0,-CD.base.mid_inscription_r,h0-1],
831 end: [0,-CD.base.mid_inscription_r,h0+CONFIG.bedholder.h+1], 833 end: [0,-CD.base.mid_inscription_r,h0+CONFIG.bedholder.h+1],
832 radius: CONFIG.bedholder.bolt.d/2+PRINT.screw_tolerance/2 834 radius: CONFIG.bedholder.bolt.d/2+PRINT.screw_tolerance/2
833 }), 835 }),
834 CSG.cylinder({ // base screw head 836 CSG.cylinder({ // base screw head
835 start: [0,-CD.base.mid_inscription_r,h0+ebolt_s], 837 start: [0,-CD.base.mid_inscription_r,h0+ebolt_s],
836 end: [0,-CD.base.mid_inscription_r,h0+CONFIG.bedholder.h+1], 838 end: [0,-CD.base.mid_inscription_r,h0+CONFIG.bedholder.h+1],
837 radius: CONFIG.bedholder.bolt.head.d/2+PRINT.play_tolerance 839 radius: CONFIG.bedholder.bolt.head.d/2+PRINT.play_tolerance
838 }) 840 })
839 ]); 841 ]);
840 842
841 var nuth=h0+CONFIG.bedholder.h*3/4; 843 var nuth=h0+CONFIG.bedholder.h*3/4;
842 rv=rv.subtract([ 844 rv=rv.subtract([
843 CSG.cylinder({ // bed screw 845 CSG.cylinder({ // bed screw
844 start: [0,-CONFIG.heatbed.sr,h0-1], 846 start: [0,-CONFIG.heatbed.sr,h0-1],
845 end: [0,-CONFIG.heatbed.sr,h0+CONFIG.bedholder.h+1], 847 end: [0,-CONFIG.heatbed.sr,h0+CONFIG.bedholder.h+1],
846 radius: CONFIG.bedholder.bolt.d/2+PRINT.screw_tolerance/2 848 radius: CONFIG.bedholder.bolt.d/2+PRINT.screw_tolerance/2
847 }), 849 }),
848 CSG.cube({ // nut pocket 850 CSG.cube({ // nut pocket
849 center: [0,-CONFIG.heatbed.sr,nuth], 851 center: [0,-CONFIG.heatbed.sr,nuth],
850 radius: [CONFIG.extrusion.w/2+1,CONFIG.bedholder.nut.w/2+PRINT.slide_tolerance/2,CONFIG.bedholder.nut.h/2+PRINT.slide_tolerance/2] 852 radius: [CONFIG.extrusion.w/2+1,CONFIG.bedholder.nut.w/2+PRINT.slide_tolerance/2,CONFIG.bedholder.nut.h/2+PRINT.slide_tolerance/2]
851 }) 853 })
852 ]); 854 ]);
853 855
854 rv.properties.P = new CSG.Connector([-CONFIG.extrusion.w/2,-CD.base.mid_inscription_r,h0+CONFIG.bedholder.h/2], 856 rv.properties.P = new CSG.Connector([-CONFIG.extrusion.w/2,-CD.base.mid_inscription_r,h0+CONFIG.bedholder.h/2],
855 [1,0,0],[0,0,1]); 857 [1,0,0],[0,0,1]);
856 return rv.setColor(CONFIG.color.parts); 858 return rv.setColor(CONFIG.color.parts);
857 var bolt_s = CONFIG.bedholder.bolt.l-CONFIG.extrusion.slotdepth+PRINT.play_tolerance*2; 859 var bolt_s = CONFIG.bedholder.bolt.l-CONFIG.extrusion.slotdepth+PRINT.play_tolerance*2;
858 var nuth=h0+CONFIG.bedholder.h*3/4; 860 var nuth=h0+CONFIG.bedholder.h*3/4;
859 var nutth = nuth+CONFIG.bedholder.nut.h/2+PRINT.slide_tolerance/2; 861 var nutth = nuth+CONFIG.bedholder.nut.h/2+PRINT.slide_tolerance/2;
860 var rv = CSG.roundedCube({ 862 var rv = CSG.roundedCube({
861 corner1: [-CONFIG.extrusion.w/2,-CD.base.inner_inscription_r,h0], 863 corner1: [-CONFIG.extrusion.w/2,-CD.base.inner_inscription_r,h0],
862 corner2: [ CONFIG.extrusion.w/2,-CONFIG.heatbed.sr-3/2-CONFIG.bedholder.margin,h0+CONFIG.bedholder.h], 864 corner2: [ CONFIG.extrusion.w/2,-CONFIG.heatbed.sr-3/2-CONFIG.bedholder.margin,h0+CONFIG.bedholder.h],
863 roundradius: CONFIG.bedholder.margin 865 roundradius: CONFIG.bedholder.margin
864 }); 866 });
865 rv = rv.subtract([ 867 rv = rv.subtract([
866 CSG.cylinder({ // base screw 868 CSG.cylinder({ // base screw
867 start: [0,-CD.base.mid_inscription_r,h0-1], 869 start: [0,-CD.base.mid_inscription_r,h0-1],
868 end: [0,-CD.base.mid_inscription_r,h0+CONFIG.bedholder.h+1], 870 end: [0,-CD.base.mid_inscription_r,h0+CONFIG.bedholder.h+1],
869 radius: CONFIG.bedholder.bolt.d/2+PRINT.screw_tolerance/2 871 radius: CONFIG.bedholder.bolt.d/2+PRINT.screw_tolerance/2