diff options
Diffstat (limited to 'cubbies.scad')
-rw-r--r-- | cubbies.scad | 209 |
1 files changed, 209 insertions, 0 deletions
diff --git a/cubbies.scad b/cubbies.scad new file mode 100644 index 0000000..9497c5e --- /dev/null +++ b/cubbies.scad | |||
@@ -0,0 +1,209 @@ | |||
1 | include <BOSL2/std.scad>; // https://github.com/revarbat/BOSL2 | ||
2 | include <BOSL2/walls.scad>; | ||
3 | include <BOSL2/fnliterals.scad>; | ||
4 | include <BOSL2/joiners.scad>; | ||
5 | |||
6 | $fn=20; | ||
7 | |||
8 | part="both"; // [bottom::Bottom Only,side:Side Only,female_tabs:Holes only from side,male_tabs:Tabs only from bottom,view_fit:Debugging view to confirm tab fit,both:Bottom + Side] | ||
9 | |||
10 | /* [Cubby dimensions] */ | ||
11 | cubby_width=40; | ||
12 | cubby_depth=120; | ||
13 | cubby_height=90; | ||
14 | |||
15 | // thickness of bottom and side | ||
16 | thickness=5; | ||
17 | |||
18 | // thickness of struts (used in both bottom and side) | ||
19 | strut_thickness=5; | ||
20 | |||
21 | // If set (to non zero), this is used in the max_bridge paramater for the | ||
22 | // sparse_struct BOSL 2 function (which generates the wireframe rectangles). By | ||
23 | // default, it is calculated as max_bridge=(cubby_height + cubby_width)/5. | ||
24 | max_bridge=0; | ||
25 | |||
26 | /* [Tab Dimensions] */ | ||
27 | // width of each tab | ||
28 | tab_width=10; | ||
29 | // material between tabs | ||
30 | tab_padding=5; | ||
31 | // this value will be added to the mortises for additional tolerance | ||
32 | tab_tolerance=0.5; | ||
33 | |||
34 | /* [Screw Tabs] */ | ||
35 | screw_tabs=true; | ||
36 | |||
37 | /* [Hidden] */ | ||
38 | tab_depth=thickness; | ||
39 | tab_height=thickness; | ||
40 | default_max_bridge=(cubby_height + cubby_width) / 5; | ||
41 | |||
42 | if ( part == "both" ) { | ||
43 | both(); | ||
44 | } else if ( part =="bottom") { | ||
45 | cubby_bottom(cubby_width, cubby_depth); | ||
46 | } else if ( part == "side" ) { | ||
47 | cubby_side(cubby_depth, cubby_height, screw_tabs); | ||
48 | } else if ( part == "view_fit") { | ||
49 | view_tab_fit(cubby_width, cubby_depth, cubby_height); | ||
50 | } else if ( part == "male_tabs" ) { | ||
51 | male_tabs(cubby_width, cubby_depth); | ||
52 | } else if ( part == "female_tabs" ) { | ||
53 | female_tabs(cubby_depth, cubby_height); | ||
54 | } | ||
55 | |||
56 | function assert_cubby_width() = | ||
57 | let (min_width = strut_thickness + 1) // I'm not sure why I need the +1 | ||
58 | assert(cubby_width >= min_width, | ||
59 | str("Cubby width must be atleast ", min_width, "mm")); | ||
60 | |||
61 | function assert_cubby_depth() = | ||
62 | let (min_depth = tab_width * 2) | ||
63 | assert(cubby_depth >= min_depth, | ||
64 | str("Cubby width must be atleast ", min_depth, "mm")); | ||
65 | |||
66 | function assert_cubby_height() = | ||
67 | let (min_height = cubby_side_bracket_height()) | ||
68 | assert(cubby_height >= min_height, | ||
69 | str("Cubby width must be atleast ", min_height, "mm")); | ||
70 | |||
71 | function double (x) = x * 2; | ||
72 | function half (x) = x / 2; | ||
73 | |||
74 | module both () { | ||
75 | gap=5; | ||
76 | cubby_bottom(cubby_width, cubby_depth); | ||
77 | left(((cubby_width + cubby_height) / 2) + (tab_height * 2) + gap) | ||
78 | cubby_side(cubby_depth, cubby_height, screw_tabs); | ||
79 | } | ||
80 | |||
81 | module cubby_bottom (width, depth) { | ||
82 | let (_=assert_cubby_width()); | ||
83 | let (_=assert_cubby_depth()); | ||
84 | |||
85 | rot(90) yrot(90) color("blue") bottom_wall() yrot(90) down(tab_height / 2) { | ||
86 | move_dist=(width / 2) + (tab_depth / 2); | ||
87 | fwd(move_dist) | ||
88 | alternating_tabs(false, "male", depth, tab_width, | ||
89 | tab_depth, tab_height, tab_padding, tab_tolerance); | ||
90 | back(move_dist) | ||
91 | alternating_tabs(true, "male", depth, tab_width, | ||
92 | tab_depth, tab_height, tab_padding, tab_tolerance); | ||
93 | } | ||
94 | children(); | ||
95 | module bottom_wall () { | ||
96 | strut_wall(width, depth) children(); | ||
97 | } | ||
98 | } | ||
99 | |||
100 | // this calculation needs to be referenced by the view_tab_fit function | ||
101 | function cubby_side_bracket_height() = double(tab_height) + tab_tolerance; | ||
102 | module cubby_side (depth, height, screw_tabs=true) { | ||
103 | let (_=assert_cubby_depth()); | ||
104 | let (_=assert_cubby_height()); | ||
105 | |||
106 | screw_tab_width=15; | ||
107 | screw_tab_height=20; | ||
108 | screw_tab_thickness=thickness; | ||
109 | |||
110 | yrot(-90) color("red") side_wall() { | ||
111 | if ( screw_tabs ) { | ||
112 | position(TOP+FRONT+LEFT) screw_tab(); | ||
113 | up(screw_tab_height) position(BOTTOM+FRONT+LEFT) screw_tab(); | ||
114 | } | ||
115 | attach(BOTTOM, TOP) zrot(90) tab_bracket(); | ||
116 | attach(TOP, BOTTOM) zrot(90) tab_bracket(); | ||
117 | } | ||
118 | children(); | ||
119 | |||
120 | module side_wall () { | ||
121 | strut_wall(depth, height - cubby_side_bracket_height() * 2) children(); | ||
122 | } | ||
123 | |||
124 | module tab_bracket () { | ||
125 | difference() { | ||
126 | cuboid([depth,thickness,cubby_side_bracket_height()]); | ||
127 | alternating_tabs(true, "female", depth, tab_width, tab_depth, | ||
128 | tab_height, tab_padding, tab_tolerance); | ||
129 | alternating_tabs(false, "female", depth, tab_width, tab_depth, | ||
130 | tab_height, tab_padding, tab_tolerance); | ||
131 | } | ||
132 | children(); | ||
133 | } | ||
134 | |||
135 | module screw_tab () { | ||
136 | difference() { | ||
137 | cuboid([screw_tab_width, screw_tab_thickness,screw_tab_height], | ||
138 | anchor=LEFT+TOP); | ||
139 | right(screw_tab_width * (2 / 3)) zrot(90) yrot(90) { | ||
140 | right(screw_tab_height * (1 / 3)) cyl(l=15, r=2, anchor=RIGHT); | ||
141 | right(screw_tab_height * (2 / 3)) cyl(l=15, r=2, anchor=LEFT); | ||
142 | } | ||
143 | } | ||
144 | children(); | ||
145 | } | ||
146 | } | ||
147 | |||
148 | module strut_wall(w, h) { | ||
149 | bridge=max_bridge ? max_bridge : default_max_bridge; | ||
150 | sparse_strut( | ||
151 | l=w, | ||
152 | h=h, | ||
153 | thick=thickness, | ||
154 | maxang=45, | ||
155 | strut=5, | ||
156 | max_bridge=bridge | ||
157 | ) children(); | ||
158 | } | ||
159 | |||
160 | module male_tabs (w, d) { | ||
161 | keep=(w / 2) - thickness; | ||
162 | left_half(x=-keep) cubby_bottom(cubby_width, cubby_depth); | ||
163 | } | ||
164 | |||
165 | module female_tabs (d, h) { | ||
166 | // text inscribed (when printing tolerances) | ||
167 | text_inscription_depth=0.6; | ||
168 | text_size=thickness * 0.9; | ||
169 | text=str(tab_tolerance); | ||
170 | text_pos=[-h/2 + (thickness * 0.95), | ||
171 | -d / 2 + (thickness / 2), | ||
172 | (thickness / 2)]; | ||
173 | |||
174 | xrot(180) left_half(x=(h / -2 + (thickness * 3))) | ||
175 | cubby_side(d, h, screw_tabs=false); | ||
176 | translate(text_pos) zrot(90) linear_extrude(text_inscription_depth) | ||
177 | color("green") text(size=text_size, text, font="Bitstream Vera Sans:style=Bold"); | ||
178 | } | ||
179 | |||
180 | module view_tab_fit (w, d, h) { | ||
181 | // position for testing tab fit | ||
182 | module position_fit_test (left=true) { | ||
183 | cubby_bottom(w, d); | ||
184 | dist=(w / 2) + (thickness / -2) + tab_depth - 2; | ||
185 | down=half(h) - half(thickness) - | ||
186 | tab_height - half(tab_tolerance); | ||
187 | yflip() yrot(90) down(dist * (left ? 1 : -1)) left(down) | ||
188 | cubby_side(d, h, screw_tabs); | ||
189 | } | ||
190 | |||
191 | position_fit_test(left=true); | ||
192 | yrot(180) up(h) position_fit_test(left=false); | ||
193 | } | ||
194 | |||
195 | module alternating_tabs (first, gender, length, tab_width, tab_depth, | ||
196 | tab_height, tab_padding, tolerance) { | ||
197 | dist=length - (tab_padding * 2); | ||
198 | total_tabs=dist / (tab_width + tab_padding + tolerance); | ||
199 | half_tabs=total_tabs / 2; | ||
200 | tab_qty = total_tabs % 2 == 0 ? half_tabs : first ? | ||
201 | ceil(half_tabs) : floor(half_tabs); | ||
202 | start = first ? tab_padding : (tab_padding * 2) + tab_width; | ||
203 | spacing = (tab_width + tab_padding) * 2; | ||
204 | xcopies(spacing, tab_qty, dist, sp=((dist / -2) + start)) | ||
205 | dovetail(gender, angle=0, slide=add_tol(tab_depth), | ||
206 | width=add_tol(tab_width), height=add_tol(tab_height)); | ||
207 | |||
208 | function add_tol (x) = gender == "male" ? x : x + tolerance; | ||
209 | } | ||