1//////////////////////////////////////////////////////////////////////
2// LibFile: hingesnaps.scad
3// Modules for creating snap-locking foldable hined parts. Includes the mask to create the hinge and
4// modules to create the snap-locks.
5// Includes:
6// include <BOSL2/std.scad>
7// include <BOSL2/hingesnaps.scad>
8// FileGroup: Parts
9// FileSummary: Foldable, snap-locking parts.
10//////////////////////////////////////////////////////////////////////
11
12// Section: Hinges and Snaps
13
14// Module: apply_folding_hinges_and_snaps()
15// Usage:
16// apply_folding_hinges_and_snaps(thick, [foldangle=], [hinges=], [snaps=], [sockets=], [snaplen=], [snapdiam=], [hingegap=], [layerheight=], [$slop=]) CHILDREN;
17// Description:
18// Adds snaplocks and create hinges in children at the given positions.
19// Arguments:
20// thick = Thickness in mm of the material to make the hinge in.
21// foldangle = The interior angle in degrees of the joint to be created with the hinge. Default: 90
22// hinges = List of [LENGTH, POSITION, SPIN] for each hinge to difference from the children.
23// snaps = List of [POSITION, SPIN] for each central snaplock to add to the children.
24// sockets = List of [POSITION, SPIN] for each outer snaplock sockets to add to the children.
25// snaplen = Length of locking snaps.
26// snapdiam = Diameter/width of locking snaps.
27// hingegap = Size in mm of the gap at the bottom of the hinge, to make room for folding.
28// layerheight = The expected printing layer height in mm.
29// ---
30// $slop = increase hinge gap by twice this amount
31// Example(Med):
32// size=100;
33// apply_folding_hinges_and_snaps(
34// thick=3, foldangle=54.74,
35// hinges=[
36// for (a=[0,120,240], b=[-size/2,size/4]) each [
37// [200, polar_to_xy(b,a), a+90]
38// ]
39// ],
40// snaps=[
41// for (a=[0,120,240]) each [
42// [rot(a,p=[ size/4, 0 ]), a+90],
43// [rot(a,p=[-size/2,-size/2.33]), a-90]
44// ]
45// ],
46// sockets=[
47// for (a=[0,120,240]) each [
48// [rot(a,p=[ size/4, 0 ]), a+90],
49// [rot(a,p=[-size/2, size/2.33]), a+90]
50// ]
51// ]
52// ) {
53// $fn=3;
54// difference() {
55// cylinder(r=size-1, h=3);
56// down(0.01) cylinder(r=size/4.5, h=3.1, spin=180);
57// down(0.01) for (a=[0:120:359.9]) zrot(a) right(size/2) cylinder(r=size/4.5, h=3.1);
58// }
59// }
60module apply_folding_hinges_and_snaps(thick, foldangle=90, hinges=[], snaps=[], sockets=[], snaplen=5, snapdiam=5, hingegap=undef, layerheight=0.2)
61{
62 hingegap = default(hingegap, layerheight)+2*get_slop();
63 difference() {
64 children();
65 for (hinge = hinges) {
66 translate(hinge[1]) {
67 folding_hinge_mask(
68 l=hinge[0], thick=thick, layerheight=layerheight,
69 foldangle=foldangle, hingegap=hingegap, spin=hinge[2]
70 );
71 }
72 }
73 }
74 for (snap = snaps) {
75 translate(snap[0]) {
76 snap_lock(
77 thick=thick, snaplen=snaplen, snapdiam=snapdiam,
78 layerheight=layerheight, foldangle=foldangle,
79 hingegap=hingegap, spin=snap[1]
80 );
81 }
82 }
83 for (socket = sockets) {
84 translate(socket[0]) {
85 snap_socket(
86 thick=thick, snaplen=snaplen, snapdiam=snapdiam,
87 layerheight=layerheight, foldangle=foldangle,
88 hingegap=hingegap, spin=socket[1]
89 );
90 }
91 }
92}
93
94
95
96// Module: folding_hinge_mask()
97// Usage:
98// folding_hinge_mask(l, thick, [layerheight=], [foldangle=], [hingegap=], [$slop=], [anchor=], [spin=], [orient=]) [ATTACHMENTS];
99// Description:
100// Creates a mask to be differenced away from a plate to create a foldable hinge.
101// Center the mask at the bottom of the plate you want to make a hinge in.
102// The mask will leave hinge material two `layerheight`s thick on the bottom of the hinge.
103// Arguments:
104// l = Length of the hinge in mm.
105// thick = Thickness in mm of the material to make the hinge in.
106// ---
107// layerheight = The expected printing layer height in mm.
108// foldangle = The interior angle in degrees of the joint to be created with the hinge. Default: 90
109// hingegap = Size in mm of the gap at the bottom of the hinge, to make room for folding.
110// $slop = Increase size of hinge gap by double this amount
111// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
112// spin = Rotate this many degrees around the Z axis. See [spin](attachments.scad#subsection-spin). Default: `0`
113// orient = Vector to rotate top towards. See [orient](attachments.scad#subsection-orient). Default: `UP`
114// Example:
115// folding_hinge_mask(l=100, thick=3, foldangle=60);
116module folding_hinge_mask(l, thick, layerheight=0.2, foldangle=90, hingegap=undef, anchor=CENTER, spin=0, orient=UP)
117{
118 hingegap = default(hingegap, layerheight)+2*get_slop();
119 size = [l, hingegap, 2*thick];
120 size2 = [l, hingegap+2*thick*tan(foldangle/2)];
121 attachable(anchor,spin,orient, size=size, size2=size2) {
122 up(layerheight*2) prismoid([l,hingegap], [l, hingegap+2*thick/tan(foldangle/2)], h=thick, anchor=BOT);
123 children();
124 }
125}
126
127
128// Module: snap_lock()
129// Usage:
130// snap_lock(thick, [snaplen=], [snapdiam=], [layerheight=], [foldangle=], [hingegap=], [$slop=], [anchor=], [spin=], [orient=]) [ATTACHMENTS];
131// Description:
132// Creates the central snaplock part.
133// Arguments:
134// thick = Thickness in mm of the material to make the hinge in.
135// ---
136// snaplen = Length of locking snaps.
137// snapdiam = Diameter/width of locking snaps.
138// layerheight = The expected printing layer height in mm.
139// foldangle = The interior angle in degrees of the joint to be created with the hinge. Default: 90
140// hingegap = Size in mm of the gap at the bottom of the hinge, to make room for folding.
141// $slop = increase size of hinge gap by double this amount
142// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
143// spin = Rotate this many degrees around the Z axis. See [spin](attachments.scad#subsection-spin). Default: `0`
144// orient = Vector to rotate top towards. See [orient](attachments.scad#subsection-orient). Default: `UP`
145// Example:
146// snap_lock(thick=3, foldangle=60);
147module snap_lock(thick, snaplen=5, snapdiam=5, layerheight=0.2, foldangle=90, hingegap=undef, anchor=CENTER, spin=0, orient=UP)
148{
149 hingegap = default(hingegap, layerheight)+2*get_slop();
150 snap_x = (snapdiam/2) / tan(foldangle/2) + (thick-2*layerheight)/tan(foldangle/2) + hingegap/2;
151 size = [snaplen, snapdiam, 2*thick];
152 attachable(anchor,spin,orient, size=size) {
153 back(snap_x) {
154 cube([snaplen, snapdiam, snapdiam/2+thick], anchor=BOT) {
155 attach(TOP) xcyl(l=snaplen, d=snapdiam, $fn=16);
156 attach(TOP) xcopies(snaplen-snapdiam/4/3) xscale(0.333) sphere(d=snapdiam*0.8, $fn=12);
157 }
158 }
159 children();
160 }
161}
162
163
164// Module: snap_socket()
165// Usage:
166// snap_socket(thick, [snaplen=], [snapdiam=], [layerheight=], [foldangle=], [hingegap=], [$slop=], [anchor=], [spin=], [orient=]) [ATTACHMENTS];
167// Description:
168// Creates the outside snaplock socketed part.
169// Arguments:
170// thick = Thickness in mm of the material to make the hinge in.
171// ---
172// snaplen = Length of locking snaps.
173// snapdiam = Diameter/width of locking snaps.
174// layerheight = The expected printing layer height in mm.
175// foldangle = The interior angle in degrees of the joint to be created with the hinge. Default: 90
176// hingegap = Size in mm of the gap at the bottom of the hinge, to make room for folding.
177// $slop = Increase size of hinge gap by double this amount
178// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
179// spin = Rotate this many degrees around the Z axis. See [spin](attachments.scad#subsection-spin). Default: `0`
180// orient = Vector to rotate top towards. See [orient](attachments.scad#subsection-orient). Default: `UP`
181// Example:
182// snap_socket(thick=3, foldangle=60);
183module snap_socket(thick, snaplen=5, snapdiam=5, layerheight=0.2, foldangle=90, hingegap=undef, anchor=CENTER, spin=0, orient=UP)
184{
185 hingegap = default(hingegap, layerheight)+2*get_slop();
186 snap_x = (snapdiam/2) / tan(foldangle/2) + (thick-2*layerheight)/tan(foldangle/2) + hingegap/2;
187 size = [snaplen, snapdiam, 2*thick];
188 attachable(anchor,spin,orient, size=size) {
189 fwd(snap_x) {
190 zrot_copies([0,180], r=snaplen+get_slop()) {
191 diff("divot")
192 cube([snaplen, snapdiam, snapdiam/2+thick], anchor=BOT) {
193 attach(TOP) xcyl(l=snaplen, d=snapdiam, $fn=16);
194 tag("divot") attach(TOP) left((snaplen+snapdiam/4/3)/2) xscale(0.333) sphere(d=snapdiam*0.8, $fn=12);
195 }
196 }
197 }
198 children();
199 }
200}
201
202
203
204
205// vim: expandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap