Skip to content

Commit 76e1a36

Browse files
committed
Add new project box features, convert to library
1 parent 56bd734 commit 76e1a36

File tree

7 files changed

+469
-153
lines changed

7 files changed

+469
-153
lines changed

electronics/project-box/SConscript

+1-3
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,7 @@ for opts in GenerateOptions(part=["lid", "box"], dims=dimensions):
1515
model,
1616
{
1717
"Part": opts.part,
18-
"Width": opts.dims[0],
19-
"Length": opts.dims[1],
20-
"Height": opts.dims[2],
18+
"Dimensions": opts.dims,
2119
},
2220
)
2321
b.Image("demo.png", model, {"Part": "all"})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../libraries/honeycomb-openscad
-6.01 KB
Loading
-5.73 KB
Loading
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,377 @@
1+
/*
2+
* Electronics project box
3+
* By smkent (GitHub) / bulbasaur0 (Printables)
4+
*
5+
* Licensed under Creative Commons (4.0 International License) Attribution-ShareAlike
6+
*/
7+
8+
include <honeycomb-openscad/honeycomb.scad>;
9+
10+
/* [Development Toggles] */
11+
12+
module __end_customizer_options__() { }
13+
14+
// Constants //
15+
16+
$fa = $preview ? $fa : 2;
17+
$fs = $preview ? $fs / 4 : 0.4;
18+
19+
slop = 0.001;
20+
21+
// Functions //
22+
23+
function vec_add(v, add) = [for (i = v) i + add];
24+
25+
function eyelet_thickness() = $e_thickness * 2;
26+
27+
function attachment_screw_xpos() = $e_thickness + $e_attachment_screw_diameter * 1.125;
28+
29+
function attachment_screw_eyelet_d() = $e_attachment_screw_diameter * 1.125;
30+
31+
// Modules //
32+
33+
module hc_fill(x, y, hex_size=8, separation=2.2, height=$e_thickness) {
34+
translate([0, 0, -slop * 5])
35+
linear_extrude(height=height + slop * 10)
36+
difference() {
37+
square([x, y], center=true);
38+
translate([-x/2, -y/2])
39+
honeycomb(x, y, hex_size, separation, whole_only=true);
40+
}
41+
}
42+
43+
module hull_pair(height) {
44+
slop = 0.001;
45+
hull() {
46+
for (child_obj = [
47+
// Child index, height offset
48+
[0, 0],
49+
[1, height - slop]
50+
]) {
51+
translate([0, 0, child_obj[1]])
52+
linear_extrude(height=slop)
53+
children(child_obj[0]);
54+
}
55+
}
56+
}
57+
58+
module round_3d(radius = $e_edge_radius) {
59+
if (radius == 0) {
60+
children();
61+
} else {
62+
render()
63+
minkowski() {
64+
children();
65+
for (mz = [0, 1])
66+
mirror([0, 0, mz])
67+
cylinder(r1=radius, r2=0, h=radius);
68+
}
69+
}
70+
}
71+
72+
module screw_hole(d, h, fit=0, style="flat", print_upside_down=false) {
73+
inset_min_h = (style == "inset") ? max((h - d), 2) - (h - d) : 0;
74+
translate([0, 0, -slop])
75+
cylinder(d=(d + fit), h=h + slop * 2);
76+
if (style == "countersink" || style == "inset") {
77+
translate([0, 0, h + inset_min_h + slop * 2])
78+
mirror([0, 0, 1])
79+
cylinder(d1=d * 2, d2=d * (style == "inset" ? 2 : 1), h=d);
80+
}
81+
if (style == "inset" && print_upside_down) {
82+
layer_height = 0.2;
83+
translate([0, 0, (h + inset_min_h) - d - layer_height])
84+
linear_extrude(height=layer_height + slop * 2)
85+
intersection() {
86+
square([d * 2, d + fit], center=true);
87+
circle(d=d*2);
88+
}
89+
}
90+
}
91+
92+
module at_screws() {
93+
if ($e_screw_count == 2) {
94+
for (m = [0, 1])
95+
mirror([m, 0])
96+
mirror([0, m])
97+
translate([$e_width / 2 - $e_screw_inset, $e_length / 2 - $e_screw_inset])
98+
children();
99+
} else {
100+
for (mx = [0, 1], my = [0, 1])
101+
mirror([mx, 0])
102+
mirror([0, my])
103+
translate([$e_width / 2 - $e_screw_inset, $e_length / 2 - $e_screw_inset])
104+
children();
105+
}
106+
}
107+
108+
module at_box_screws() {
109+
for (mx = [0, 1])
110+
mirror([mx, 0])
111+
translate([$e_width / 2 + attachment_screw_xpos(), 0])
112+
children();
113+
}
114+
115+
module box_shape(radius=$e_corner_radius, add=0) {
116+
offset(r=radius)
117+
offset(r=-radius)
118+
square([$e_width + add * 2, $e_length + add * 2], center=true);
119+
}
120+
121+
module box_interior() {
122+
union() {
123+
screw_corner = $e_insert_diameter + $e_screw_inset;
124+
start_ht = $e_height - $e_lid_height + $e_insert_diameter * 0.40;
125+
interior_corner_radius = max(0.5, ($e_corner_radius - $e_thickness));
126+
127+
// Interior shape
128+
color("mintcream", 0.8)
129+
translate([0, 0, $e_thickness])
130+
round_3d()
131+
translate([0, 0, $e_edge_radius])
132+
union() {
133+
linear_extrude(height=(start_ht - $e_insert_depth - screw_corner) - $e_edge_radius * 2)
134+
box_shape(add=-$e_edge_radius);
135+
136+
linear_extrude(height=$e_height - $e_edge_radius * 2)
137+
offset(r=interior_corner_radius)
138+
offset(r=-interior_corner_radius)
139+
difference() {
140+
box_shape(add=-$e_edge_radius);
141+
at_screws()
142+
union() {
143+
r = $e_insert_diameter + $e_edge_radius;
144+
circle(r=r);
145+
for (tr = [[0, -r], [-r, 0]])
146+
translate(tr)
147+
square([r, r]);
148+
}
149+
}
150+
}
151+
152+
// Interior screw support chamfer
153+
color("mediumpurple", 0.8)
154+
translate([0, 0, (start_ht - $e_insert_depth - screw_corner) + $e_thickness])
155+
union() {
156+
hull_pair(screw_corner) {
157+
offset(r=interior_corner_radius)
158+
offset(r=-interior_corner_radius)
159+
box_shape(radius=$e_corner_radius + $e_edge_radius);
160+
box_shape(radius=$e_corner_radius + $e_edge_radius, add=-screw_corner);
161+
}
162+
if ($e_edge_radius > 0) {
163+
translate([0, 0, -$e_edge_radius + slop])
164+
linear_extrude(height=$e_edge_radius + slop)
165+
box_shape(radius=$e_corner_radius + $e_edge_radius);
166+
}
167+
}
168+
}
169+
}
170+
171+
module box_body() {
172+
translate([0, 0, $e_edge_radius])
173+
round_3d()
174+
linear_extrude(height=$e_height + $e_thickness * 2 - $e_edge_radius * 2)
175+
box_shape(add=$e_thickness - $e_edge_radius);
176+
}
177+
178+
module box_screw_eyelets() {
179+
eyelet_round = attachment_screw_xpos() * 2;
180+
round_3d()
181+
translate([0, 0, $e_edge_radius])
182+
linear_extrude(height=eyelet_thickness() - $e_edge_radius * 2)
183+
offset(r=-$e_edge_radius)
184+
offset(r=$e_thickness)
185+
offset(r=-eyelet_round)
186+
offset(r=eyelet_round)
187+
union() {
188+
box_shape();
189+
at_box_screws()
190+
union() {
191+
d = attachment_screw_eyelet_d();
192+
circle(d=d * 2);
193+
translate([-d, 0])
194+
square(d * 2, center=true);
195+
}
196+
}
197+
}
198+
199+
module box_screws() {
200+
at_box_screws()
201+
screw_hole(
202+
d=$e_attachment_screw_diameter,
203+
fit=$e_screw_fit,
204+
h=eyelet_thickness() + slop * 2,
205+
style=$e_attachment_screw_style,
206+
);
207+
}
208+
209+
module box_patterns() {
210+
if ($e_fill_bottom)
211+
hc_fill($e_width - $e_screw_inset * 2, $e_length - $e_screw_inset * 2);
212+
for (fw = [0:1:3]) {
213+
if ($e_fill_walls[fw] > 0) {
214+
fill_x = (((fw % 2) == 0) ? $e_width : $e_length) - $e_insert_diameter * 2 * 2;
215+
pos_y = ((fw % 2) == 0) ? $e_length : $e_width;
216+
mirror([fw == 3 ? 1 : 0, fw == 2 ? 1 : 0])
217+
rotate((fw % 2) != 0 ? 90 : 0)
218+
translate([0, pos_y / 2 + $e_thickness, ($e_height - $e_lid_height) / 2 + $e_thickness])
219+
rotate([90, 0, 0])
220+
hc_fill(fill_x - $e_screw_inset * 2, ($e_height - $e_lid_height) - $e_screw_inset * 2);
221+
}
222+
}
223+
}
224+
225+
module box() {
226+
color("mintcream", 0.8)
227+
render()
228+
union() {
229+
difference() {
230+
intersection() {
231+
union() {
232+
if ($e_screw_eyelets)
233+
box_screw_eyelets();
234+
box_body();
235+
}
236+
linear_extrude(height=$e_height + $e_thickness * 2 - $e_lid_height)
237+
scale([2, 1])
238+
box_shape(add=$e_thickness + $e_edge_radius, radius=0);
239+
}
240+
difference() {
241+
box_interior();
242+
ebox_contents();
243+
}
244+
at_screws()
245+
translate([0, 0, ($e_height + $e_thickness) - $e_lid_height - $e_insert_depth])
246+
screw_hole(d=$e_insert_diameter, fit=$e_screw_fit, h=$e_insert_depth + $e_thickness);
247+
if ($e_screw_eyelets)
248+
box_screws();
249+
box_patterns();
250+
ebox_cutouts();
251+
}
252+
}
253+
ebox_extras();
254+
}
255+
256+
module lid() {
257+
color("lightsteelblue", (Part == "preview" ? 0.4 : 0.8))
258+
render()
259+
difference() {
260+
intersection() {
261+
box_body();
262+
translate([0, 0, $e_height + $e_thickness * 2 - $e_lid_height])
263+
linear_extrude(height=$e_lid_height)
264+
box_shape(add=$e_thickness + $e_edge_radius, radius=0);
265+
}
266+
difference() {
267+
box_interior();
268+
ebox_contents();
269+
}
270+
at_screws()
271+
translate([0, 0, $e_height + $e_thickness * 2 - $e_lid_height])
272+
screw_hole(
273+
d=$e_screw_diameter,
274+
fit=$e_screw_fit,
275+
h=$e_lid_height,
276+
style=$e_screw_style,
277+
print_upside_down=true
278+
);
279+
if ($e_fill_lid)
280+
translate([0, 0, $e_height + $e_thickness])
281+
hc_fill($e_width - $e_screw_inset * 2, $e_length - $e_screw_inset * 2);
282+
ebox_cutouts();
283+
}
284+
}
285+
286+
module ebox(
287+
dimensions,
288+
thickness,
289+
lid_height,
290+
screw_diameter,
291+
insert_diameter,
292+
insert_depth,
293+
screw_style,
294+
attachment_screw_diameter,
295+
attachment_screw_style,
296+
screw_eyelets,
297+
fill_lid,
298+
fill_bottom,
299+
fill_walls=[0, 0, 0, 0]
300+
) {
301+
$e_dimensions = dimensions;
302+
$e_width = dimensions[0];
303+
$e_length = dimensions[1];
304+
$e_height = dimensions[2];
305+
$e_thickness = thickness;
306+
$e_lid_height = lid_height;
307+
$e_screw_diameter = screw_diameter;
308+
$e_insert_diameter = insert_diameter;
309+
$e_insert_depth = insert_depth;
310+
$e_screw_style = screw_style;
311+
$e_attachment_screw_diameter = attachment_screw_diameter;
312+
$e_attachment_screw_style = attachment_screw_style;
313+
$e_screw_eyelets = screw_eyelets;
314+
$e_fill_lid = fill_lid;
315+
$e_fill_bottom = fill_bottom;
316+
$e_fill_walls = fill_walls;
317+
ebox_adjustments()
318+
children();
319+
}
320+
321+
module ebox_adjustments(
322+
print_orientation=true,
323+
screw_inset=4,
324+
corner_radius=3,
325+
edge_radius=1.5,
326+
screw_count=4,
327+
screw_fit=0.4
328+
) {
329+
$e_print_orientation = print_orientation;
330+
$e_screw_inset = screw_inset;
331+
$e_corner_radius = corner_radius;
332+
$e_edge_radius = edge_radius;
333+
$e_screw_count = screw_count;
334+
$e_screw_fit = screw_fit;
335+
children();
336+
}
337+
338+
module ebox_part(part) {
339+
if (Part == "preview") {
340+
box();
341+
translate([0, 0, slop])
342+
lid();
343+
} else if (Part == "all") {
344+
sep = $e_length / 2 + $e_thickness * 2;
345+
translate([0, sep, 0])
346+
box();
347+
translate([0, -sep, 0])
348+
if ($e_print_orientation) {
349+
rotate([180, 0, 0])
350+
translate([0, 0, -($e_height + $e_thickness * 2)])
351+
lid();
352+
} else {
353+
translate([0, 0, -($e_height - $e_lid_height) - $e_thickness * 2])
354+
lid();
355+
}
356+
} else if (Part == "box") {
357+
box();
358+
} else if (Part == "lid") {
359+
if ($e_print_orientation) {
360+
rotate([180, 0, 0])
361+
translate([0, 0, -($e_height + $e_thickness * 2)])
362+
lid();
363+
} else {
364+
translate([0, 0, -($e_height + $e_thickness)])
365+
lid();
366+
}
367+
}
368+
}
369+
370+
module ebox_cutouts() {
371+
}
372+
373+
module ebox_contents() {
374+
}
375+
376+
module ebox_extras() {
377+
}

0 commit comments

Comments
 (0)