1//////////////////////////////////////////////////////////////////////
2// LibFile: metric_screws.scad
3// Screws, Bolts, and Nuts.
4// Includes:
5// include <BOSL2/std.scad>
6// include <BOSL2/metric_screws.scad>
7// FileGroup: Threaded Parts
8// FileSummary: Metric screws, nuts, and screwholes.
9//////////////////////////////////////////////////////////////////////
10
11
12include <threading.scad>
13include <screw_drive.scad>
14
15
16// Section: Functions
17
18
19// Function: get_metric_bolt_head_size()
20// Description: Returns the diameter of a typical metric bolt's head, based on the bolt `size`.
21function get_metric_bolt_head_size(size) = lookup(size, [
22 [ 3.0, 5.5],
23 [ 4.0, 7.0],
24 [ 5.0, 8.0],
25 [ 6.0, 10.0],
26 [ 7.0, 11.0],
27 [ 8.0, 13.0],
28 [10.0, 17.0],
29 [12.0, 19.0],
30 [14.0, 22.0],
31 [16.0, 24.0],
32 [18.0, 27.0],
33 [20.0, 30.0],
34 [24.0, 36.0],
35 [30.0, 46.0],
36 [36.0, 55.0],
37 [42.0, 65.0],
38 [48.0, 75.0],
39 [56.0, 85.0],
40 [64.0, 95.0]
41 ]);
42
43
44// Function: get_metric_bolt_head_height()
45// Description: Returns the height of a typical metric bolt's head, based on the bolt `size`.
46function get_metric_bolt_head_height(size) = lookup(size, [
47 [ 1.6, 1.23],
48 [ 2.0, 1.53],
49 [ 2.5, 1.83],
50 [ 3.0, 2.13],
51 [ 4.0, 2.93],
52 [ 5.0, 3.65],
53 [ 6.0, 4.15],
54 [ 8.0, 5.45],
55 [10.0, 6.58],
56 [12.0, 7.68],
57 [14.0, 8.98],
58 [16.0, 10.18],
59 [20.0, 12.72],
60 [24.0, 15.35],
61 [30.0, 19.12],
62 [36.0, 22.92],
63 [42.0, 26.42],
64 [48.0, 30.42],
65 [56.0, 35.50],
66 [64.0, 40.50]
67 ]);
68
69
70// Function: get_metric_socket_cap_diam()
71// Description: Returns the diameter of a typical metric socket cap bolt's head, based on the bolt `size`.
72function get_metric_socket_cap_diam(size) = lookup(size, [
73 [ 1.6, 3.0],
74 [ 2.0, 3.8],
75 [ 2.5, 4.5],
76 [ 3.0, 5.5],
77 [ 4.0, 7.0],
78 [ 5.0, 8.5],
79 [ 6.0, 10.0],
80 [ 8.0, 13.0],
81 [10.0, 16.0],
82 [12.0, 18.0],
83 [14.0, 21.0],
84 [16.0, 24.0],
85 [18.0, 27.0],
86 [20.0, 30.0],
87 [22.0, 33.0],
88 [24.0, 36.0],
89 [27.0, 40.0],
90 [30.0, 45.0],
91 [33.0, 50.0],
92 [36.0, 54.0],
93 [42.0, 63.0],
94 [48.0, 72.0],
95 [56.0, 84.0],
96 [64.0, 96.0]
97 ]);
98
99
100// Function: get_metric_socket_cap_height()
101// Description: Returns the height of a typical metric socket cap bolt's head, based on the bolt `size`.
102function get_metric_socket_cap_height(size) = lookup(size, [
103 [ 1.6, 1.7],
104 [ 2.0, 2.0],
105 [ 2.5, 2.5],
106 [ 3.0, 3.0],
107 [ 4.0, 4.0],
108 [ 5.0, 5.0],
109 [ 6.0, 6.0],
110 [ 8.0, 8.0],
111 [10.0, 10.0],
112 [12.0, 12.0],
113 [14.0, 14.0],
114 [16.0, 16.0],
115 [18.0, 18.0],
116 [20.0, 20.0],
117 [22.0, 22.0],
118 [24.0, 24.0],
119 [27.0, 27.0],
120 [30.0, 30.0],
121 [33.0, 33.0],
122 [36.0, 36.0],
123 [42.0, 42.0],
124 [48.0, 48.0],
125 [56.0, 56.0],
126 [64.0, 64.0]
127 ]);
128
129
130// Function: get_metric_socket_cap_socket_size()
131// Description: Returns the diameter of a typical metric socket cap bolt's hex drive socket, based on the bolt `size`.
132function get_metric_socket_cap_socket_size(size) = lookup(size, [
133 [ 1.6, 1.5],
134 [ 2.0, 1.5],
135 [ 2.5, 2.0],
136 [ 3.0, 2.5],
137 [ 4.0, 3.0],
138 [ 5.0, 4.0],
139 [ 6.0, 5.0],
140 [ 8.0, 6.0],
141 [10.0, 8.0],
142 [12.0, 10.0],
143 [14.0, 12.0],
144 [16.0, 14.0],
145 [18.0, 14.0],
146 [20.0, 17.0],
147 [22.0, 17.0],
148 [24.0, 19.0],
149 [27.0, 19.0],
150 [30.0, 22.0],
151 [33.0, 24.0],
152 [36.0, 27.0],
153 [42.0, 32.0],
154 [48.0, 36.0],
155 [56.0, 41.0],
156 [64.0, 46.0]
157 ]);
158
159
160// Function: get_metric_socket_cap_socket_depth()
161// Description: Returns the depth of a typical metric socket cap bolt's hex drive socket, based on the bolt `size`.
162function get_metric_socket_cap_socket_depth(size) = lookup(size, [
163 [ 1.6, 0.7],
164 [ 2.0, 1.0],
165 [ 2.5, 1.1],
166 [ 3.0, 1.3],
167 [ 4.0, 2.0],
168 [ 5.0, 2.5],
169 [ 6.0, 3.0],
170 [ 8.0, 4.0],
171 [10.0, 5.0],
172 [12.0, 6.0],
173 [14.0, 7.0],
174 [16.0, 8.0],
175 [18.0, 9.0],
176 [20.0, 10.0],
177 [22.0, 11.0],
178 [24.0, 12.0],
179 [27.0, 13.5],
180 [30.0, 15.5],
181 [33.0, 18.0],
182 [36.0, 19.0],
183 [42.0, 24.0],
184 [48.0, 28.0],
185 [56.0, 34.0],
186 [64.0, 38.0]
187 ]);
188
189
190// Function: get_metric_iso_coarse_thread_pitch()
191// Description: Returns the ISO metric standard coarse threading pitch for a given bolt `size`.
192function get_metric_iso_coarse_thread_pitch(size) = lookup(size, [
193 [ 1.6, 0.35],
194 [ 2.0, 0.40],
195 [ 2.5, 0.45],
196 [ 3.0, 0.50],
197 [ 4.0, 0.70],
198 [ 5.0, 0.80],
199 [ 6.0, 1.00],
200 [ 7.0, 1.00],
201 [ 8.0, 1.25],
202 [10.0, 1.50],
203 [12.0, 1.75],
204 [14.0, 2.00],
205 [16.0, 2.00],
206 [18.0, 2.50],
207 [20.0, 2.50],
208 [22.0, 2.50],
209 [24.0, 3.00],
210 [27.0, 3.00],
211 [30.0, 3.50],
212 [33.0, 3.50],
213 [36.0, 4.00],
214 [39.0, 4.00],
215 [42.0, 4.50],
216 [45.0, 4.50],
217 [48.0, 5.00],
218 [56.0, 5.50],
219 [64.0, 6.00]
220 ]);
221
222
223// Function: get_metric_iso_fine_thread_pitch()
224// Description: Returns the ISO metric standard fine threading pitch for a given bolt `size`.
225function get_metric_iso_fine_thread_pitch(size) = lookup(size, [
226 [ 1.6, 0.35],
227 [ 2.0, 0.40],
228 [ 2.5, 0.45],
229 [ 3.0, 0.50],
230 [ 4.0, 0.70],
231 [ 5.0, 0.80],
232 [ 6.0, 1.00],
233 [ 7.0, 1.00],
234 [ 8.0, 1.00],
235 [10.0, 1.25],
236 [12.0, 1.50],
237 [14.0, 1.50],
238 [16.0, 2.00],
239 [18.0, 2.50],
240 [20.0, 2.50],
241 [22.0, 2.50],
242 [24.0, 3.00],
243 [27.0, 3.00],
244 [30.0, 3.50],
245 [33.0, 3.50],
246 [36.0, 4.00],
247 [39.0, 4.00],
248 [42.0, 4.50],
249 [45.0, 4.50],
250 [48.0, 5.00],
251 [56.0, 5.50],
252 [64.0, 6.00]
253 ]);
254
255
256// Function: get_metric_iso_superfine_thread_pitch()
257// Description: Returns the ISO metric standard superfine threading pitch for a given bolt `size`.
258function get_metric_iso_superfine_thread_pitch(size) = lookup(size, [
259 [ 1.6, 0.35],
260 [ 2.0, 0.40],
261 [ 2.5, 0.45],
262 [ 3.0, 0.50],
263 [ 4.0, 0.70],
264 [ 5.0, 0.80],
265 [ 6.0, 1.00],
266 [ 7.0, 1.00],
267 [ 8.0, 1.00],
268 [10.0, 1.00],
269 [12.0, 1.25],
270 [14.0, 1.50],
271 [16.0, 2.00],
272 [18.0, 2.50],
273 [20.0, 2.50],
274 [22.0, 2.50],
275 [24.0, 3.00],
276 [27.0, 3.00],
277 [30.0, 3.50],
278 [33.0, 3.50],
279 [36.0, 4.00],
280 [39.0, 4.00],
281 [42.0, 4.50],
282 [45.0, 4.50],
283 [48.0, 5.00],
284 [56.0, 5.50],
285 [64.0, 6.00]
286 ]);
287
288
289// Function: get_metric_jis_thread_pitch()
290// Description: Returns the JIS metric standard threading pitch for a given bolt `size`.
291function get_metric_jis_thread_pitch(size) = lookup(size, [
292 [ 2.0, 0.40],
293 [ 2.5, 0.45],
294 [ 3.0, 0.50],
295 [ 4.0, 0.70],
296 [ 5.0, 0.80],
297 [ 6.0, 1.00],
298 [ 7.0, 1.00],
299 [ 8.0, 1.25],
300 [10.0, 1.25],
301 [12.0, 1.25],
302 [14.0, 1.50],
303 [16.0, 1.50],
304 [18.0, 1.50],
305 [20.0, 1.50]
306 ]);
307
308
309// Function: get_metric_nut_size()
310// Description: Returns the typical metric nut flat-to-flat diameter for a given bolt `size`.
311function get_metric_nut_size(size) = lookup(size, [
312 [ 2.0, 4.0],
313 [ 2.5, 5.0],
314 [ 3.0, 5.5],
315 [ 4.0, 7.0],
316 [ 5.0, 8.0],
317 [ 6.0, 10.0],
318 [ 7.0, 11.0],
319 [ 8.0, 13.0],
320 [10.0, 17.0],
321 [12.0, 19.0],
322 [14.0, 22.0],
323 [16.0, 24.0],
324 [18.0, 27.0],
325 [20.0, 30.0]
326 ]);
327
328
329// Function: get_metric_nut_thickness()
330// Description: Returns the typical metric nut thickness for a given bolt `size`.
331function get_metric_nut_thickness(size) = lookup(size, [
332 [ 1.6, 1.3],
333 [ 2.0, 1.6],
334 [ 2.5, 2.0],
335 [ 3.0, 2.4],
336 [ 4.0, 3.2],
337 [ 5.0, 4.0],
338 [ 6.0, 5.0],
339 [ 7.0, 5.5],
340 [ 8.0, 6.5],
341 [10.0, 8.0],
342 [12.0, 10.0],
343 [14.0, 11.0],
344 [16.0, 13.0],
345 [18.0, 15.0],
346 [20.0, 16.0],
347 [24.0, 21.5],
348 [30.0, 25.6],
349 [36.0, 31.0],
350 [42.0, 34.0],
351 [48.0, 38.0],
352 [56.0, 45.0],
353 [64.0, 51.0]
354 ]);
355
356
357
358// Section: Modules
359
360
361// Module: generic_screw()
362// Description:
363// Makes a very simple screw model, useful for making screwholes.
364// Usage:
365// generic_screw(screwsize, screwlen, headsize, headlen)
366// Arguments:
367// screwsize = diameter of threaded part of screw.
368// screwlen = length of threaded part of screw.
369// headsize = diameter of the screw head.
370// headlen = length of the screw head.
371// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
372// spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
373// orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
374// Extra Anchors:
375// "base" = At the base of the head.
376// "countersunk" = At the head height that would be just barely exposed when countersunk.
377// Examples:
378// generic_screw(screwsize=3,screwlen=10,headsize=6,headlen=3, anchor="countersunk");
379// generic_screw(screwsize=3,screwlen=10,headsize=6,headlen=3, anchor="base");
380// Example(FlatSpin,VPD=75): Standard Anchors
381// generic_screw(screwsize=3,screwlen=10,headsize=6,headlen=3)
382// show_anchors(5, custom=false);
383// Example(FlatSpin,VPD=55): Custom Named Anchors
384// expose_anchors()
385// generic_screw(screwsize=3,screwlen=10,headsize=6,headlen=3)
386// show_anchors(5, std=false);
387module generic_screw(
388 screwsize=3,
389 screwlen=10,
390 headsize=6,
391 headlen=3,
392 pitch=undef,
393 anchor="base",
394 spin=0,
395 orient=UP
396) {
397 sides = max(12, segs(screwsize/2));
398 anchors = [
399 named_anchor("countersunk", [0,0,(headlen+screwlen)/2-0.01]),
400 named_anchor("base", [0,0,-headlen/2+screwlen/2])
401 ];
402 attachable(anchor,spin,orient, d=screwsize, l=headlen+screwlen, anchors=anchors) {
403 down(headlen/2-screwlen/2) {
404 down(screwlen/2) {
405 if (pitch == undef) {
406 cylinder(r=screwsize/2, h=screwlen+0.05, center=true, $fn=sides);
407 } else {
408 threaded_rod(d=screwsize, l=screwlen+0.05, pitch=pitch, $fn=sides);
409 }
410 }
411 cylinder(r=headsize/2, h=headlen, center=false, $fn=sides*2);
412 }
413 children();
414 }
415}
416
417
418// Module: metric_bolt()
419// Description:
420// Makes a standard metric screw model.
421// Arguments:
422// size = Diameter of threaded part of screw.
423// headtype = One of `"hex"`, `"pan"`, `"button"`, `"round"`, `"countersunk"`, `"oval"`, `"socket`". Default: `"socket"`
424// l = Length of screw, except for the head.
425// shank = Length of unthreaded portion of the shaft.
426// pitch = If given, render threads of the given pitch. If 0, then no threads. Overrides coarse argument.
427// details = If true model should be rendered with extra details. (Default: false)
428// coarse = If true, make coarse threads instead of fine threads. Default = true
429// flange = Radius of flange beyond the head. Default = 0 (no flange)
430// phillips = If given, the size of the phillips drive hole to add. (ie: "#1", "#2", or "#3")
431// torx = If given, the size of the torx drive hole to add. (ie: 10, 20, 30, etc.)
432// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
433// spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
434// orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
435// Extra Anchors:
436// "base" = At the base of the head.
437// "countersunk" = At the head height that would be just barely exposed when countersunk.
438// "shank" = At the bottom start of the unthreaded shank.
439// Example: Bolt Head Types
440// ydistribute(40) {
441// xdistribute(30) {
442// // Front Row, Left to Right
443// metric_bolt(headtype="pan", size=10, l=15, details=true, phillips="#2");
444// metric_bolt(headtype="button", size=10, l=15, details=true, phillips="#2");
445// metric_bolt(headtype="round", size=10, l=15, details=true, phillips="#2");
446// }
447// xdistribute(30) {
448// // Back Row, Left to Right
449// metric_bolt(headtype="socket", size=10, l=15, details=true);
450// metric_bolt(headtype="hex", size=10, l=15, details=true, phillips="#2");
451// metric_bolt(headtype="countersunk", size=10, l=15, details=true, phillips="#2");
452// metric_bolt(headtype="oval", size=10, l=15, details=true, phillips="#2");
453// }
454// }
455// Example: Details
456// metric_bolt(size=10, l=15, details=true, $fn=32);
457// Example: No Details Except Threads
458// metric_bolt(size=10, l=15);
459// Example: No Details, No Threads
460// metric_bolt(size=10, l=15, pitch=0);
461// Example: Fine Threads
462// metric_bolt(size=10, l=15, coarse=false);
463// Example: Flange
464// metric_bolt(size=10, l=15, flange=5);
465// Example: Shank
466// metric_bolt(size=10, l=25, shank=10);
467// Example: Hex Head with Phillips
468// metric_bolt(headtype="hex", size=10, l=15, phillips="#2");
469// Example: Hex Head with Torx
470// metric_bolt(headtype="hex", size=10, l=15, torx=50);
471// Example(FlatSpin,VPD=100): Standard Anchors
472// metric_bolt(headtype="oval", size=10, l=15, shank=5, details=true, phillips="#2")
473// show_anchors(5, custom=false);
474// Example(FlatSpin,VPD=100): Custom Named Anchors
475// expose_anchors(0.125)
476// metric_bolt(headtype="oval", size=10, l=15, shank=5, details=true, phillips="#2")
477// show_anchors(5, std=false);
478module metric_bolt(
479 headtype="socket",
480 size=3,
481 l=12,
482 shank=0,
483 pitch=undef,
484 details=false,
485 coarse=true,
486 phillips=undef,
487 torx=undef,
488 flange=0,
489 anchor="base",
490 spin=0,
491 orient=UP
492) {
493 D = headtype != "hex"?
494 get_metric_socket_cap_diam(size) :
495 get_metric_bolt_head_size(size);
496 H = headtype == "socket"?
497 get_metric_socket_cap_height(size) :
498 get_metric_bolt_head_height(size);
499 P = coarse?
500 (pitch==undef? get_metric_iso_coarse_thread_pitch(size) : pitch) :
501 (pitch==undef? get_metric_iso_fine_thread_pitch(size) : pitch);
502 tlen = l - min(l, shank);
503 sides = max(12, segs(size/2));
504 tcirc = D/cos(30);
505 bevtop = (tcirc-D)/2;
506 bevbot = P/2;
507
508 headlen = (
509 (headtype == "pan" || headtype == "round" || headtype == "button")? H*0.75 :
510 (headtype == "countersunk")? (D-size)/2 :
511 (headtype == "oval")? ((D-size)/2 + D/2/3) :
512 H
513 );
514 base = l/2 - headlen/2;
515 sunklen = (
516 (headtype == "oval")? (D-size)/2 :
517 headlen-0.001
518 );
519
520 anchors = [
521 named_anchor("countersunk", [0,0,base+sunklen]),
522 named_anchor("base", [0,0,base]),
523 named_anchor("shank", [0,0,base-shank])
524 ];
525
526 //color("silver")
527 attachable(anchor,spin,orient, d=size, l=headlen+l, anchors=anchors) {
528 up(base) {
529 difference() {
530 union() {
531 // Head
532 if (headtype == "hex") {
533 difference() {
534 cylinder(d=tcirc, h=H, $fn=6);
535
536 // Bevel hex nut top
537 if (details) {
538 up(H-bevtop) {
539 difference() {
540 cube([tcirc+1, tcirc+1, bevtop+0.5], anchor=BOTTOM);
541 down(0.01) cylinder(d1=tcirc, d2=tcirc-bevtop*2, h=bevtop+0.02, center=false);
542 }
543 }
544 }
545 }
546 } else if (headtype == "socket") {
547 sockw = get_metric_socket_cap_socket_size(size);
548 sockd = get_metric_socket_cap_socket_depth(size);
549 difference() {
550 cylinder(d=D, h=H);
551 up(H-sockd) cylinder(h=sockd+0.1, d=sockw/cos(30), $fn=6);
552 if (details) {
553 kcnt = 36;
554 zrot_copies(n=kcnt, r=D/2) up(H/3) cube([PI*D/kcnt/2, PI*D/kcnt/2, H], anchor=BOTTOM);
555 }
556 }
557 } else if (headtype == "pan") {
558 cyl(l=H*0.75, d=D, rounding2=H*0.75/2, anchor=DOWN);
559 } else if (headtype == "round") {
560 top_half(D) zscale(H*0.75/D*2) sphere(d=D);
561 } else if (headtype == "button") {
562 up(H*0.75/3) top_half(D) zscale(H*0.75*2/3/D*2) sphere(d=D);
563 cylinder(d=D, h=H*0.75/3+0.01, center=false);
564 } else if (headtype == "countersunk") {
565 cylinder(h=(D-size)/2, d1=size, d2=D);
566 } else if (headtype == "oval") {
567 up((D-size)/2) top_half(D) zscale(0.333) sphere(d=D);
568 cylinder(h=(D-size)/2, d1=size, d2=D);
569 }
570
571 // Flange
572 if (flange>0) {
573 up(headtype == "countersunk" || headtype == "oval"? (D-size)/2 : 0) {
574 cylinder(d=D+flange, h=H/8, center=false);
575 up(H/8) cylinder(d1=D+flange, d2=D, h=H/8, center=false);
576 }
577 }
578
579 // Unthreaded Shank
580 if (tlen < l) {
581 down(l-tlen) cylinder(d=size, h=l-tlen+0.05, center=false, $fn=sides);
582 }
583
584 // Threads
585 down(l) {
586 difference() {
587 up(tlen/2+0.05) {
588 if (tlen > 0) {
589 if (P > 0) {
590 threaded_rod(d=size, l=tlen+0.05, pitch=P, $fn=sides);
591 } else {
592 cylinder(d=size, h=tlen+0.05, $fn=sides, center=true);
593 }
594 }
595 }
596
597 // Bevel bottom end of threads
598 if (details) {
599 difference() {
600 down(0.5) cube([size+1, size+1, bevbot+0.5], anchor=BOTTOM);
601 cylinder(d1=size-bevbot*2, d2=size, h=bevbot+0.01, center=false);
602 }
603 }
604 }
605 }
606 }
607
608 // Phillips drive hole
609 if (headtype != "socket" && phillips != undef) {
610 down(headtype != "hex"? H/6 : 0) {
611 phillips_mask(size=phillips); //, shaft=D);
612 }
613 }
614
615 // Torx drive hole
616 if (headtype != "socket" && torx != undef) {
617 up(1) torx_mask(size=torx, l=H+0.1, center=false);
618 }
619 }
620 }
621 children();
622 }
623}
624
625
626// Module: metric_nut()
627// Description:
628// Makes a model of a standard nut for a standard metric screw.
629// Arguments:
630// size = standard metric screw size in mm. (Default: 3)
631// hole = include the hole in the nut. (Default: true)
632// pitch = pitch of threads in the hole. No threads if not given.
633// flange = radius of flange beyond the head. Default = 0 (no flange)
634// details = true if model should be rendered with extra details. (Default: false)
635// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
636// spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
637// orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
638// center = If true, centers the nut at the origin. If false, sits on top of XY plane. Overrides `anchor` if given.
639// Example: No details, No Hole. Useful for a mask.
640// metric_nut(size=10, hole=false);
641// Example: Hole, with No Threads
642// metric_nut(size=10, hole=true);
643// Example: Threads
644// metric_nut(size=10, hole=true, pitch=1.5);
645// Example: Details
646// metric_nut(size=10, hole=true, pitch=1.5, details=true);
647// Example: Centered
648// metric_nut(size=10, hole=true, pitch=1.5, details=true, center=true);
649// Example: Flange
650// metric_nut(size=10, hole=true, pitch=1.5, flange=3, details=true);
651module metric_nut(
652 size=3,
653 hole=true,
654 pitch=undef,
655 details=false,
656 flange=0,
657 center,
658 anchor,
659 spin=0,
660 orient=UP
661) {
662 H = get_metric_nut_thickness(size);
663 D = get_metric_nut_size(size);
664 boltfn = max(12, segs(size/2));
665 nutfn = max(12, segs(D/2));
666 dcirc = D/cos(30);
667 bevtop = (dcirc - D)/2;
668
669 //color("silver")
670 anchor = get_anchor(anchor,center,BOT,CENTER);
671 attachable(anchor,spin,orient, d=dcirc+flange, l=H) {
672 difference() {
673 union() {
674 difference() {
675 cylinder(d=dcirc, h=H, center=true, $fn=6);
676 if (details) {
677 up(H/2-bevtop) {
678 difference() {
679 cube([dcirc+1, dcirc+1, bevtop+0.5], anchor=BOTTOM);
680 down(0.01) cylinder(d1=dcirc, d2=dcirc-bevtop*2, h=bevtop+0.02, center=false, $fn=nutfn);
681 }
682 }
683 if (flange == 0) {
684 down(H/2) {
685 difference() {
686 down(0.5) cube([dcirc+1, dcirc+1, bevtop+0.5], anchor=BOTTOM);
687 down(0.01) cylinder(d1=dcirc-bevtop*2, d2=dcirc, h=bevtop+0.02, center=false, $fn=nutfn);
688 }
689 }
690 }
691 }
692 }
693 if (flange>0) {
694 down(H/2) {
695 cylinder(d=D+flange, h=H/8, center=false);
696 up(H/8) cylinder(d1=D+flange, d2=D, h=H/8, center=false);
697 }
698 }
699 }
700 if (hole == true) {
701 if (pitch == undef) {
702 cylinder(r=size/2, h=H+0.5, center=true, $fn=boltfn);
703 } else {
704 threaded_rod(d=size, l=H+0.5, pitch=pitch, $fn=boltfn);
705 }
706 }
707 }
708 children();
709 }
710}
711
712
713// vim: expandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap