diff options
author | Steven <steven.vasilogianis@gmail.com> | 2021-10-26 18:15:41 -0400 |
---|---|---|
committer | Steven <steven.vasilogianis@gmail.com> | 2021-10-26 18:15:41 -0400 |
commit | 9543c5d898fac81ca34c06878df6bd4e2b4ca0ab (patch) | |
tree | 5b25f3df0150ca25ff7e150d50fb42683f2fa52d | |
parent | 6cbd9460671d9348d77259c9d11e14e73546f733 (diff) |
Use BOSL2 library for dovetails, inscribe tolerance on tolerance test pieces. and other stuff
-rw-r--r-- | cubbies.scad | 248 |
1 files changed, 136 insertions, 112 deletions
diff --git a/cubbies.scad b/cubbies.scad index fdd4eb8..a05ae97 100644 --- a/cubbies.scad +++ b/cubbies.scad | |||
@@ -1,88 +1,123 @@ | |||
1 | include <BOSL2/std.scad>; // https://github.com/revarbat/BOSL2 | 1 | include <BOSL2/std.scad>; // https://github.com/revarbat/BOSL2 |
2 | include <BOSL2/walls.scad>; | 2 | include <BOSL2/walls.scad>; |
3 | include <BOSL2/fnliterals.scad>; | ||
4 | include <BOSL2/joiners.scad>; | ||
3 | 5 | ||
4 | $fn=20; | 6 | $fn=100; |
5 | 7 | ||
6 | part="divider"; // [both:Bottom + Divider,bottom::Bottom Only,divider:Divider Only,male tab line:Line of male tabs,female tab line: Line of female tabs,view_fit_test:Generate a model to view tab fit (for debugging)] | 8 | /* $fs = 0.01; */ |
9 | /* $fa = 1; */ | ||
10 | |||
11 | |||
12 | part="side test fit"; // [both:Bottom + Side,bottom::Bottom Only,side:Side Only,view_fit:Debugging view to confirm tab fit,bottom_tabs:Tabs only from bottom,side_tabs:Holes only from side] | ||
7 | 13 | ||
8 | /* [Cubby dimensions] */ | 14 | /* [Cubby dimensions] */ |
9 | cubby_width=50; | 15 | cubby_width=150; |
10 | cubby_depth=180; | 16 | cubby_depth=120; |
11 | cubby_divider_height=90; | 17 | cubby_height=90; |
12 | 18 | ||
13 | // thickness of both bottom + dividers | 19 | // thickness of bottom and side |
14 | thickness=5; | 20 | thickness=5; |
15 | 21 | ||
16 | // thickness of struts | 22 | // thickness of struts (used in both bottom and side) |
17 | strut_thickness=5; | 23 | strut_thickness=5; |
18 | 24 | ||
25 | // If set (to non zero), this is used in the max_bridge paramater for the | ||
26 | // sparse_struct BOSL 2 function (which generates the wireframe rectangles). By | ||
27 | // default, it is calculated as max_bridge=(cubby_height + cubby_width)/5. | ||
28 | max_bridge=0; | ||
29 | |||
19 | /* [Tab Dimensions] */ | 30 | /* [Tab Dimensions] */ |
20 | tab_width=10; | 31 | tab_width=10; |
21 | tab_padding=5; | 32 | tab_padding=5; // minimum material between tabs |
22 | tab_tolerance=0.5; | 33 | tab_tolerance=0.5; |
23 | 34 | ||
35 | /* [Used only in tab fit tests] */ | ||
36 | // Smallest tolerance | ||
37 | //tolerance_start=0.5; | ||
38 | // Largest tolerance | ||
39 | //tolerance_end=1.0; | ||
40 | // Steps to increment from smallest to largest tolerance | ||
41 | //tolerance_step=0.1; | ||
42 | /* [Screw Tabs] */ | ||
43 | screw_tabs=true; | ||
44 | |||
24 | /* [Hidden] */ | 45 | /* [Hidden] */ |
25 | tab_depth=thickness; | 46 | tab_depth=thickness; |
26 | tab_height=thickness; | 47 | tab_height=thickness; |
27 | 48 | ||
28 | 49 | /* text inscribed (when printing tolerances) */ | |
29 | if ( part == "bottom" ) { | 50 | text_extrude=2; |
30 | rot(90) yrot(90) cubby_bottom(cubby_width, cubby_depth); | 51 | text_size=thickness * 0.8; |
31 | } else if ( part == "divider" ) { | 52 | |
32 | yrot(180+90) cubby_divider(cubby_depth, cubby_divider_height); | 53 | |
33 | } else if ( part == "male tab line" ) { | 54 | if ( part == "both" ) { |
34 | print_tab_line(cubby_width, cubby_depth, cubby_divider_height, male=true); | 55 | both(); |
35 | } else if ( part == "female tab line" ) { | 56 | } else if ( part =="bottom") { |
36 | print_tab_line(cubby_width, cubby_depth, cubby_divider_height, male=false); | 57 | cubby_bottom(cubby_width, cubby_depth); |
37 | } else if ( part == "male tab" ) { | 58 | } else if ( part == "side" ) { |
38 | print_single_tab(male=true); | 59 | cubby_side(cubby_depth, cubby_height, screw_tabs); |
39 | } else if ( part == "female tab") { | 60 | } else if ( part == "view_fit") { |
40 | print_single_tab(male=false); | 61 | view_tab_fit(cubby_width, cubby_depth, cubby_height); |
41 | } else if ( part == "view fit test") { | 62 | } else if ( part == "bottom_tabs" ) { |
42 | view_tab_fit(cubby_width, cubby_depth, cubby_divider_height); | 63 | bottom_test_fit(cubby_width, cubby_depth); |
43 | } else if ( part == "both") { | 64 | } else if ( part == "side_tabs" ) { |
44 | cubby(cubby_width, cubby_depth, cubby_divider_height); | 65 | side_test_fit(cubby_depth, cubby_height); |
45 | } | 66 | } |
46 | 67 | ||
47 | module cubby (w, d, h) { | 68 | function double (x) = x * 2; |
48 | position_flat() children(); | 69 | function half (x) = x / 2; |
49 | 70 | ||
50 | module position_flat () { | 71 | module both () { |
51 | rot(90) yrot(90) cubby_bottom(w, d); | 72 | gap=5; |
52 | gap=5; | 73 | cubby_bottom(cubby_width, cubby_depth); |
53 | yrot(180+90) { | 74 | left(((cubby_width + cubby_height) / 2) + (tab_height * 2) + gap) |
54 | down(((w + h) / 2) + (tab_height * 2) + gap) cubby_divider(d, h); | 75 | cubby_side(cubby_depth, cubby_height, screw_tabs); |
55 | } | ||
56 | } | ||
57 | } | 76 | } |
58 | 77 | ||
59 | module cubby_divider (depth, height, screw_tabs=true) { | 78 | module cubby_bottom (width, depth) { |
60 | function bracket_height() = thickness * 2; | 79 | rot(90) yrot(90) color("blue") bottom_wall() yrot(90) down(tab_height / 2) { |
80 | move_dist=width / 2 + (tab_depth / 2); | ||
81 | fwd(move_dist) | ||
82 | alternating_tabs(false, "male", depth, tab_width, | ||
83 | tab_depth, tab_height, tab_padding, tab_tolerance); | ||
84 | back(move_dist) | ||
85 | alternating_tabs(true, "male", depth, tab_width, | ||
86 | tab_depth, tab_height, tab_padding, tab_tolerance); | ||
87 | } | ||
88 | children(); | ||
89 | module bottom_wall () { | ||
90 | strut_wall(width, depth) children(); | ||
91 | } | ||
92 | } | ||
93 | |||
94 | /* this calculation needs to be referenced by the view_tab_fit function */ | ||
95 | function cubby_side_bracket_height() = double(tab_height) + tab_tolerance; | ||
96 | module cubby_side (depth, height, screw_tabs=true) { | ||
61 | screw_tab_width=15; | 97 | screw_tab_width=15; |
62 | screw_tab_height=20; | 98 | screw_tab_height=20; |
63 | screw_tab_thickness=thickness; | 99 | screw_tab_thickness=thickness; |
64 | 100 | ||
65 | divider_wall() { | 101 | yrot(180+-90) color("red") side_wall() { |
66 | if ( screw_tabs ) { | 102 | if ( screw_tabs ) { |
67 | position(TOP+FRONT+LEFT) screw_tab(); | 103 | position(TOP+FRONT+LEFT) screw_tab(); |
68 | up(screw_tab_height) position(BOTTOM+FRONT+LEFT) screw_tab(); | 104 | up(screw_tab_height) position(BOTTOM+FRONT+LEFT) screw_tab(); |
69 | } | 105 | } |
70 | attach(BOTTOM, TOP) zrot(90) tab_bracket(); | 106 | attach(BOTTOM, TOP) zrot(90) tab_bracket(); |
71 | attach(TOP, BOTTOM) zrot(90) tab_bracket(); | 107 | attach(TOP, BOTTOM) zrot(90) tab_bracket(); |
72 | } | 108 | } |
73 | children(); | 109 | children(); |
74 | 110 | ||
75 | module divider_wall () { | 111 | module side_wall () { |
76 | strut_wall(depth, height - bracket_height()) children(); | 112 | strut_wall(depth, height - cubby_side_bracket_height() * 2) children(); |
77 | } | 113 | } |
78 | 114 | ||
79 | module tab_bracket () { | 115 | module tab_bracket () { |
80 | difference() { | 116 | difference() { |
81 | cuboid([depth,thickness,bracket_height()]); | 117 | cuboid([depth,thickness,cubby_side_bracket_height()]); |
82 | add_tabs(depth, male=false, between=false); | 118 | alternating_tabs(true, "female", depth, tab_width, tab_depth, tab_height, tab_padding, tab_tolerance); |
83 | add_tabs(depth, male=false, between=true); | 119 | alternating_tabs(false, "female", depth, tab_width, tab_depth, tab_height, tab_padding, tab_tolerance); |
84 | } | 120 | } |
85 | |||
86 | children(); | 121 | children(); |
87 | } | 122 | } |
88 | 123 | ||
@@ -91,8 +126,8 @@ module cubby_divider (depth, height, screw_tabs=true) { | |||
91 | cuboid([screw_tab_width, screw_tab_thickness,screw_tab_height], | 126 | cuboid([screw_tab_width, screw_tab_thickness,screw_tab_height], |
92 | anchor=LEFT+TOP); | 127 | anchor=LEFT+TOP); |
93 | right(screw_tab_width * (2 / 3)) zrot(90) yrot(90) { | 128 | right(screw_tab_width * (2 / 3)) zrot(90) yrot(90) { |
94 | right(screw_tab_height * (1 / 3)) #cyl(l=15, r=2, anchor=RIGHT); | 129 | right(screw_tab_height * (1 / 3)) cyl(l=15, r=2, anchor=RIGHT); |
95 | right(screw_tab_height * (2 / 3)) #cyl(l=15, r=2, anchor=LEFT); | 130 | right(screw_tab_height * (2 / 3)) cyl(l=15, r=2, anchor=LEFT); |
96 | } | 131 | } |
97 | 132 | ||
98 | } | 133 | } |
@@ -100,79 +135,68 @@ module cubby_divider (depth, height, screw_tabs=true) { | |||
100 | } | 135 | } |
101 | } | 136 | } |
102 | 137 | ||
103 | module cubby_bottom (width, depth) { | ||
104 | color("blue") { | ||
105 | bottom_wall(); | ||
106 | yrot(90) { | ||
107 | move_dist=width / 2 + (tab_depth / 2); | ||
108 | fwd(move_dist) | ||
109 | add_tabs(depth, male=true, between=false); | ||
110 | back(move_dist) | ||
111 | add_tabs(depth, male=true, between=true); | ||
112 | } | ||
113 | } | ||
114 | children(); | ||
115 | |||
116 | module bottom_wall () { | ||
117 | strut_wall(width, depth) children(); | ||
118 | } | ||
119 | } | ||
120 | |||
121 | module strut_wall(w, h) { | 138 | module strut_wall(w, h) { |
139 | bridge=max_bridge ? max_bridge : (h+w)/5; | ||
122 | sparse_strut( | 140 | sparse_strut( |
123 | l=w, | 141 | l=w, |
124 | h=h, | 142 | h=h, |
125 | thick=thickness, | 143 | thick=thickness, |
126 | maxang=45, | 144 | maxang=45, |
127 | strut=5, | 145 | strut=5, |
128 | max_bridge=(h+w)/5 | 146 | max_bridge=bridge |
129 | ) children(); | 147 | ) children(); |
130 | } | 148 | } |
131 | 149 | ||
150 | module bottom_test_fit (w, d) { | ||
151 | keep=(w / 2) - thickness; | ||
152 | //right_half(x=keep) cubby_bottom(cubby_width, cubby_depth); | ||
132 | 153 | ||
133 | function tab_spacing (tab_width) = tab_width * 3.5; | 154 | text=str("t=", tab_tolerance); |
134 | 155 | text_pos=[(-w / 2) + (thickness * 0.9), | |
135 | module single_tab ( | 156 | -d / 2 + thickness, |
136 | tab_width=10, | 157 | (thickness / 2) - text_extrude]; |
137 | tab_depth=5, | 158 | |
138 | tab_height=5, | 159 | difference() { |
139 | male=true, | 160 | left_half(x=-keep) cubby_bottom(cubby_width, cubby_depth); |
140 | tolerance=1 | 161 | #translate(text_pos) zrot(90) linear_extrude(text_extrude) color("green") text(size=text_size, text); |
141 | ) { | ||
142 | size=male | ||
143 | ? [tab_width, tab_depth, tab_height] | ||
144 | : [tab_width + tolerance, tab_depth + tolerance, tab_height + tolerance]; | ||
145 | if (male) { | ||
146 | #cuboid(size) children(); | ||
147 | } else { | ||
148 | cuboid(size) children(); | ||
149 | } | 162 | } |
150 | } | 163 | } |
151 | 164 | ||
152 | /* module single_hole ( size_of_yo_hole = 2000mm ) { */ | 165 | module side_test_fit (d, h) { |
153 | /* if (male) { */ | 166 | text=str("t=", tab_tolerance); |
154 | /* #cylinder(size_of_yo_hole) children(); */ | 167 | text_pos=[-h/2 + (thickness * 0.9), |
155 | /* } else { */ | 168 | -d / 2 + thickness, |
156 | /* cylinder(size_of_yo_hole) children(); */ | 169 | (thickness / 2) - text_extrude]; |
157 | /* } */ | 170 | |
158 | 171 | difference() { | |
159 | /* } */ | 172 | left_half(x=(h / -2 + (thickness * 3))) |
160 | 173 | cubby_side(d, h, screw_tabs=false); | |
161 | module tab_line ( | 174 | #translate(text_pos) zrot(90) linear_extrude(text_extrude) color("green") text(size=text_size, text); |
162 | distance=100, | 175 | } |
163 | tab_width=10, | 176 | } |
164 | tab_depth=5, | 177 | |
165 | tab_height=5, | 178 | module view_tab_fit (w, d, h) { |
166 | tab_padding=5, | 179 | // position for testing tab fit |
167 | male=true, | 180 | module position_fit_test (left=true) { |
168 | tolerance=1, | 181 | cubby_bottom(w, d); |
169 | edge_padding=0, | 182 | dist=(w / 2) + (thickness / -2) + tab_depth - 2; |
170 | between=false, | 183 | down=half(h) - half(thickness) - tab_height - half(tab_tolerance); |
171 | ) { | 184 | yflip() yrot(90) down(dist * (left ? 1 : -1)) left(down) cubby_side(d, h, screw_tabs); |
172 | start = between ? ((tab_padding * 2) + tab_width) : tab_padding; | 185 | } |
173 | tab_spacing = (tab_width * 2) + (tab_padding * 2); | 186 | |
174 | shift = (distance - (tab_padding * 2)) / -2; | 187 | position_fit_test(left=true); |
175 | for ( i = [shift+start:tab_spacing:(shift * -1) - tab_padding] ) { | 188 | yrot(180) up(h) position_fit_test(left=false); |
176 | right(i) #single_tab(tab_width, tab_depth, tab_height, male, tolerance); | 189 | } |
177 | } | 190 | |
191 | module alternating_tabs ( first, gender, length, tab_width, tab_depth, tab_height, tab_padding, tolerance ) { | ||
192 | dist=length - (tab_padding * 2); | ||
193 | total_tabs=dist / (tab_width + tab_padding + tolerance); | ||
194 | half_tabs=total_tabs / 2; | ||
195 | tab_qty = total_tabs % 2 == 0 ? half_tabs : first ? ceil(half_tabs) : floor(half_tabs); | ||
196 | start = first ? tab_padding : (tab_padding * 2) + tab_width; | ||
197 | spacing = (tab_width + tab_padding) * 2; | ||
198 | xcopies(spacing, tab_qty, dist, sp=((dist / -2) + start)) | ||
199 | #dovetail(gender, angle=0, slide=add_tol(tab_depth), width=add_tol(tab_width), height=add_tol(tab_height)); | ||
200 | |||
201 | function add_tol (x) = gender == "male" ? x : x + tolerance; | ||
178 | } | 202 | } |