chiark / gitweb /
ksafe-base: refactor BoltHoles (nfc)
[reprap-play.git] / ksafe-base.scad
1 // -*- C -*-
2
3 // from actual ksafe
4 bolt_above = 8.50 - 0.50;
5 bolthole_height = 4.24 + 1.00;
6 wall_thick = 4.50;
7 bolthole_width = 16.62 + 2.00;
8 main_sz = 150.56 + 0.75;
9 cnr_rad = 13.5; // approx
10 lidinner_thick_allow = 20.78 + 0.50;
11 display_width = 69.81 - 0.50;
12
13 dpp3 = [ -5.5, 8.5 ];
14 dpp2 = [ -11.0, 7.0 ];
15 dpp1 = [ -34.0, 14.0 ];
16
17 // other parameters
18 web_thick = 4;
19 web_height = 20; // excluding wall and base thick
20 bolthole_rhs = 20;
21 bolthole_lhs = 20;
22 boltreinf_thick = 6;
23 anchor_wall_space = 25;
24 base_thick = 4;
25 space = 25;
26 anchor_thick = 4;
27 anchor_rad = 4;
28 bevel = 8;
29 string_slot = 3.0;
30 string_depth = 6.0;
31 thumbslot_depth = 5.0;
32 thumbslot_width = 15.0;
33 thumbslot_between = 10;
34 ksafecover_lip = 4.62;
35 display_rhs_secs = 15;
36 dcover_endthick = 3.0;
37 dcover_mainthick = 5.0;
38 dcover_slop_height = 0.35;
39 dcover_slop_depth = 0.25;
40 dcover_slop_inside = 1.50;
41 dcover_commonvertoff = 0.00; // slop_height or slop_inside is added too
42 dcover_edge_gap_more_width = 2.0; // each side
43
44 // ----- calculated -----
45
46 hsz = main_sz/2;
47 cut = main_sz + 20;
48
49 gppA = [0,0];
50 gppB = gppA - [ wall_thick, 0 ];
51
52 gppL = [ gppB[0], -(lidinner_thick_allow + space + base_thick) ];
53
54 yw1 = -web_thick/2;
55 yw2 = yw1 - bolthole_rhs;
56 yw3 = yw2 - anchor_thick;
57 yw4 = yw3 - anchor_wall_space;
58 yw5 = yw4 - wall_thick;
59 yw6 = -(hsz - cnr_rad + 0.1);
60
61 yw10 = web_thick/2;
62 yw11 = yw2 + anchor_wall_space;
63 yw12 = yw11 + wall_thick;
64 yw13 = -yw6;
65
66 cpp1 = dpp1 + [  dcover_slop_depth, dcover_slop_height ];
67 cpp2 = [ dpp2[0] - dcover_slop_depth, dpp3[1] + dcover_slop_height ];
68 cppH = cpp1 + [ 0, dcover_endthick ];
69 cppA = [ cpp2[0], dpp3[1] + dcover_slop_inside ];
70 cppK = cppA + [ 0, dcover_mainthick ];
71 cppZ = [ -ksafecover_lip, -dcover_commonvertoff ];
72 cppD = cppZ + [ 0, -dcover_slop_inside ];
73 cppE = cppD + [ 0, -dcover_mainthick ];
74 cppC = [ dcover_slop_inside, cppD[1] ];
75 cppF = cppC + dcover_mainthick * [1,-1];
76 cppB = [ cppC[0], cppA[1] ];
77 cppG = [ cppF[0], cppK[1] ];
78
79 // anchor
80
81 anchor_b = anchor_thick + anchor_rad;
82 appM = gppL + anchor_b * [1,1];
83
84 a_bevel = 2 * anchor_b * (1 + sqrt(0.5));
85
86 module upp_app_Vars(t_bevel){
87   $xppE = gppL + t_bevel * [0,1];
88   $xppF = gppL + t_bevel * [1,0];
89
90   $xppJ = $xppE + wall_thick * [ 1, tan(22.5) ];
91   $xppI = $xppF + base_thick * [ tan(22.5), 1 ];
92
93   // must pass a_bevel for t_bevel for these to be valid
94   $gppP = gppA + [0,-1] * lidinner_thick_allow;
95   $gppQ = $gppP + [1,-1] * web_height;
96   $gppR = $xppJ + [ 1, tan(22.5) ] * web_height;
97   $gppS = $xppI + [ tan(22.5), 1 ] * web_height;
98   $gppT = [ $gppQ[0], $xppE[1] ];
99
100   children();
101 }
102
103 module upp_app_Profile(){
104   polygon([ gppA,
105             gppB,
106             $xppE,
107             $xppF,
108             $xppF + [1,0],
109             $xppI + [1,0],
110             $xppJ ],
111           convexity=10);
112 }
113
114
115 module UsualProfile(){
116   upp_app_Vars(bevel) upp_app_Profile();
117 }
118
119 module NearAnchorProfile(){
120   upp_app_Vars(a_bevel) upp_app_Profile();
121 }
122
123 module AnchorProfile(){
124   upp_app_Vars(a_bevel) {
125
126     upp_app_Profile();
127
128     difference(){
129       hull(){
130         polygon([ $xppE,
131                   $xppF,
132                   $xppF + [0,1],
133                   $xppE + [1,0] ],
134           convexity=10);
135         translate(appM) circle(r= anchor_b);
136       }
137       translate(appM) circle(r= anchor_rad);
138     }
139   }
140 }
141
142 module AnchorWallProfile(){
143   UsualProfile();
144   NearAnchorProfile();
145   hull(){
146     for (bev = [bevel, a_bevel]) {
147       upp_app_Vars(bev) {
148         polygon([ $xppE,
149                   $xppF,
150                   $xppI,
151                   $xppJ ],
152           convexity=10);
153       }
154     }
155   }
156 }
157
158 module WebProfile(){
159   upp_app_Vars(a_bevel){
160     if ($gppR[1] <= $gppP[1]) {
161       polygon([ $gppP,
162                 $xppE,
163                 $gppT,
164                 $gppQ ]);
165       polygon([ $gppP,
166                 $xppE,
167                 $xppF,
168                 $gppS,
169                 $gppR ],
170           convexity=10);
171     } else {
172       polygon([ $gppP,
173                 $xppE,
174                 $xppF,
175                 $gppS,
176                 $gppP + web_height * [1,0] ],
177           convexity=10);
178     }
179     polygon([ $gppS,
180               $xppF,
181               $xppF + [1,0],
182               $gppS + [1,0] ],
183           convexity=10);
184   }
185 }
186
187 module SomeBaseProfile(I, F){
188   polygon([ I,
189             F,
190             [ hsz+1, F[1] ],
191             [ hsz+1, I[1] ] ]);
192 }
193
194 module BaseProfile(){
195   SomeBaseProfile($xppI, $xppF);
196 }
197
198 module DCoverProfileRaw(){
199   polygon([ cpp1,
200             cpp2,
201             cppA,
202             cppB,
203             cppC,
204             cppD,
205             cppE,
206             cppF,
207             cppG,
208             cppK,
209             cppH ],
210           convexity = 10);
211 }
212
213 module DCoverProfile(){
214   mirror([1,0])
215     translate(-cppZ)
216     DCoverProfileRaw();
217 }
218
219 module SWalls(ymin, ymax, t_bevel) {
220   upp_app_Vars(t_bevel) {
221     translate([0,ymin,0])
222       mirror([0,1,0])
223       rotate([90,0,0])
224       linear_extrude(height= ymax-ymin, convexity=10)
225       for (xm=[0,1])
226         mirror([xm,0])
227           translate([-hsz, 0])
228             children();
229   }
230 }
231
232 module AtTwoCorners(){
233   for (xm=[0,1]) {
234     mirror([xm,0,0]) 
235     translate((hsz - cnr_rad) * [1,1])
236     intersection(){
237       rotate_extrude(convexity=10)
238         translate([-cnr_rad,0])
239         children();
240       translate([0,0,-250])
241         cube([50,50,500]);
242     }
243   }
244 }
245
246 module Box(){
247   /// corners, and front and back of base
248   for (ym=[0,1]) mirror([0,ym,0]) {
249     AtTwoCorners(){
250       UsualProfile();
251     }
252     hull() AtTwoCorners(){
253       upp_app_Vars(bevel){
254         polygon([ $xppI,
255                   $xppF,
256                   $xppF + [0.1, 0],
257                   $xppI + [0.1, 0]
258                   ]);
259       }
260     }
261   }
262
263   // side walls and base
264   SWalls(yw6 , yw4 , bevel  ) { UsualProfile();      BaseProfile(); }
265   SWalls(yw5 , yw4 , a_bevel) { AnchorWallProfile(); BaseProfile(); }
266   SWalls(yw5 , yw12, a_bevel) { NearAnchorProfile(); BaseProfile(); }
267   SWalls(yw3 , yw2 , a_bevel) { AnchorProfile();     BaseProfile(); }
268   SWalls(yw11, yw12, a_bevel) { AnchorWallProfile(); BaseProfile(); }
269   SWalls(yw11, yw13, bevel  ) { UsualProfile();      BaseProfile(); }
270   SWalls(yw1,  yw10, a_bevel) { WebProfile(); SomeBaseProfile($gppS, $xppF); }
271
272   // front and rear walls
273   rotate([0,0,90]) SWalls(yw6, yw13, bevel) UsualProfile();
274 }
275
276 module DCover(){ ////toplevel
277   translate([ -display_width/2, -hsz, 0 ])
278     rotate([0,90,0])
279     rotate([0,0,90])
280     linear_extrude( display_width - display_rhs_secs, convexity = 10)
281     DCoverProfile();
282 }
283
284 module DCoverSupportAllowance(){
285   translate([0, -hsz, 0])
286     cube(center=true,
287          [ display_width + 2 * dcover_edge_gap_more_width,
288            wall_thick * 2,
289            dcover_slop_inside * 2 + 0.01 ]);
290 }
291
292 module BoltHoles(){
293   translate([0,0, -(bolt_above + 0.5 * bolthole_height)])
294     cube(center=true, [ cut, bolthole_width, bolthole_height ]);
295 }
296
297 module KsafeBase(){ ////toplevel
298   DCover();
299
300   difference(){
301     Box();
302
303     BoltHoles();
304
305     // string slot
306     translate([ -cut,
307                 -(bolthole_width/2 + bolthole_rhs),
308                 1 ])
309       mirror([0,1,0]) mirror([0,0,1])
310       cube([ cut*2,
311              string_slot,
312              lidinner_thick_allow + string_depth + 1 ]);
313
314     // thumb slots
315     for (mx=[0,1]) mirror([mx,0,0]) {
316       translate([ thumbslot_between/2,
317                   0,
318                   -thumbslot_depth ])
319         cube([ thumbslot_width,
320                cut,
321                thumbslot_depth+1 ]);
322     }
323
324     DCoverSupportAllowance();
325   }
326 }
327
328 module DemoProfiles(){ ////toplevel
329   translate([0,0,-2]) color("yellow") AnchorWallProfile();
330   color("red") AnchorProfile();
331   translate([0,0,2]) color("black") NearAnchorProfile();
332   translate([0,0,4]) color("blue") UsualProfile();
333   translate([0,0,-4]) color("pink") WebProfile();
334   translate([0,0,6]) color("purple") DCoverProfile();
335 }
336
337 module RimTest(){ ////toplevel
338   intersection(){
339     Box();
340     cube(center=true, [ main_sz*2, main_sz*2,
341                         2.5 ]);
342   }
343 }
344
345 module DCoverTest(){ ////toplevel
346   intersection(){
347     difference(){
348       union(){
349         Box();
350         DCover();
351       }
352       DCoverSupportAllowance();
353       BoltHoles();
354     }
355     translate([0,0,60])
356     cube(center=true, [ main_sz*2, main_sz*2,
357                         2 * (60 + 10) ]);
358   }
359 }
360
361 module BoltTest(){ ////toplevel
362   dy = 0.5 * (bolthole_width+4);
363   intersection(){
364     KsafeBase();
365     translate([ 0, -dy, -(bolt_above + bolthole_height + 1) ])
366       cube([ main_sz, dy*2, 50 ]);
367   }
368 }
369
370 //DemoProfiles();
371 //Box();
372 //KsafeBase();
373 //RimTest();