discuss@lists.openscad.org

OpenSCAD general discussion

View all threads

Designing this small bolt?

T
Terrypin
Tue, Jun 8, 2021 5:18 PM

Could someone help me to design this small bolt please? This will be a great
learning exercise in how to choose and use library files, and 'include' or
'use' them, as well as the practical matter of replacing the bolt for the
mains plug cover we recently discussed.

http://forum.openscad.org/file/t3184/SmallBolt.jpg

To be honest I'm not sure where to start. Although I've downloaded various
apparently relevant files they all seem dauntingly complicated. For example,
can my bolt be made by using this file from nophead?

//
// NopSCADlib Copyright Chris Palmer 2018
// nop.head@gmail.com
// hydraraptor.blogspot.com
//
// This file is part of NopSCADlib.
//
// NopSCADlib is free software: you can redistribute it and/or modify it
under the terms of the
// GNU General Public License as published by the Free Software Foundation,
either version 3 of
// the License, or (at your option) any later version.
//
// NopSCADlib is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY;
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
with NopSCADlib.
// If not, see https://www.gnu.org/licenses/.
//

//
//! Machine screws and wood screws with various head styles.
//!
//! For an explanation of screw_polysink() see
https://hydraraptor.blogspot.com/2020/12/sinkholes.html.
//
include <../utils/core/core.scad>

use <washer.scad>
use <nut.scad>
use <../utils/rounded_cylinder.scad>
use <../utils/thread.scad>
include <inserts.scad>

function screw_head_type(type)        = type[2];    //! Head style hs_cap,
hs_pan, hs_cs, hs_hex, hs_grub, hs_cs_cap, hs_dome
function screw_radius(type)          = type[3] / 2; //! Nominal radius
function screw_head_radius(type)      = type[4] / 2; //! Head radius
function screw_head_height(type)      = type[5];    //! Head height
function screw_socket_depth(type)    = type[6];    //! Socket or slot
depth
function screw_socket_af(type)        = type[7];    //! Socket across flats
function screw_max_thread(type)      = type[8];    //! Maximum thread
length
function screw_washer(type)          = type[9];    //! Default washer
function screw_nut(type)              = type[10];    //! Default nut
function screw_pilot_hole(type)      = type[11];    //! Pilot hole radius
for wood screws, tap radius for machine screws
function screw_clearance_radius(type) = type[12];    //! Clearance hole
radius
function screw_nut_radius(type) = screw_nut(type) ?
nut_radius(screw_nut(type)) : 0; //! Radius of matching nut
function screw_boss_diameter(type) = max(washer_diameter(screw_washer(type))

  • 1, 2 * (screw_nut_radius(type) + 3 * extrusion_width)); //! Boss big
    enough for nut trap and washer
    function screw_head_depth(type, d = 0) =            //! How far a counter
    sink head will go into a straight hole diameter d
    screw_head_height(type)
    ? 0
    : let(r = screw_radius(type)) screw_head_radius(type) - max(r, d /
    • r / 5;

function screw_longer_than(x) = x <=  5 ?  5 : //! Returns the length of the
shortest screw length longer or equal to x
x <=  6 ?  6 :
x <=  8 ?  8 :
x <= 10 ? 10 :
x <= 12 ? 12 :
x <= 16 ? 16 :
ceil(x / 5) * 5;

function screw_shorter_than(x) = x >= 20 ? floor(x / 5) * 5 : //! Returns
the length of the longest screw shorter than or equal to x
x >= 16 ? 16 :
x >= 12 ? 12 :
x >= 10 ? 10 :
x >=  8 ?  8 :
x >=  6 ?  6 :
5;

function screw_length(screw, thickness, washers, insert = false, nyloc =
false, nut = false, longer = false) = //! Returns the length of the longest
or shortest screw that will got through thickness and washers and
possibly an insert, nut or nyloc
let(washer = washers ? washers * washer_thickness(screw_washer(screw)) :
0,
insert = insert ? insert_length(screw_insert(screw)) : 0,
nut = nut || nyloc ? nut_thickness(screw_nut(screw), nyloc)  : 0,
total = thickness + washer + insert + nut
)
longer || nut || nyloc ? screw_longer_than(total) :
screw_shorter_than(total);

function screw_smaller_than(d) = d >= 2.5 && d < 3 ? 2.5 : floor(d); //
Largest diameter screw less than or equal to specified diameter

function screw_insert(screw, i = 0) = let(d = screw_radius(screw) * 2)
i >= len(inserts) ? undef
: insert_screw_diameter(inserts[i]) == d ? inserts[i]
:
screw_insert(screw, i + 1);

module screw(type, length, hob_point = 0, nylon = false) { //! Draw
specified screw, optionally hobbed or nylon
description = str("Screw ", nylon ? "Nylon " : "", type[1], length < 10
? " x  " : " x ", length, "mm", hob_point ? str(", hobbed at ", hob_point) :
"");
vitamin(str("screw(", type[0], "_screw, ", length, arg(hob_point, 0,
"hob_point"), arg(nylon, false, "nylon"), "): ", description));

head_type   = screw_head_type(type);
rad         = screw_radius(type) - eps;
head_rad    = screw_head_radius(type);
head_height = screw_head_height(type);
socket_af   = screw_socket_af(type);
socket_depth= screw_socket_depth(type);
socket_rad  = socket_af / cos(30) / 2;
max_thread  = screw_max_thread(type);
thread = max_thread ? length >= max_thread + 5 ? max_thread
                                               : length
                    : length;
d = 2 * screw_radius(type);
pitch = metric_coarse_pitch(d);
colour = nylon || head_type == hs_grub ? grey(40) : grey(80);

module shaft(socket = 0, headless = false) {
    point = screw_nut(type) ? 0 : 3 * rad;
    shank  = length - thread - socket;

    if(show_threads && !point && pitch)
        translate_z(-length)
            male_metric_thread(d, pitch, thread - (shank > 0 || headless

? 0 : socket), false, top = headless ? -1 : 0, solid = !headless, colour =
colour);
else
color(colour * 0.9)
rotate_extrude() {
translate([0, -length + point])
square([rad, length - socket - point]);

                if(point)
                    polygon([
                        [0.4, -length], [0, point - length], [rad, point
  • length]
    ]);
    }

      if(shank > 0)
          color(colour)
              translate_z(-shank - socket)
                  cylinder(r = rad + eps, h = shank);
    

    }

    module cs_head(socket_rad, socket_depth) {
    head_t = rad / 5;
    head_height = head_rad + head_t;

      rotate_extrude()
          difference() {
              polygon([[0, 0], [head_rad, 0], [head_rad, -head_t], [0,
    

-head_height]]);

            translate([0, -socket_depth + eps])
                square([socket_rad, 10]);
        }

    translate_z(-socket_depth)
        linear_extrude(socket_depth)
            difference() {
                circle(socket_rad + 0.1);

                children();
            }
}

explode(length + 10) {
    if(head_type == hs_cap) {
        color(colour) {
            cylinder(r = head_rad, h = head_height - socket_depth);

            translate_z(head_height - socket_depth)
                linear_extrude(socket_depth)
                    difference() {
                        circle(head_rad);

                        circle(socket_rad, $fn = 6);
                    }

        }
        shaft();
    }
    if(head_type == hs_grub) {
        color(colour) {
            r = show_threads ? rad - pitch / 2 : rad;
            translate_z(-socket_depth)
                linear_extrude(socket_depth)
                    difference() {
                        circle(r);

                        circle(socket_rad, $fn = 6);
                    }

            shaft(socket_depth, true);

            if(show_threads)
                translate_z(-length)
                    cylinder(r = r, h = length - socket_depth);
        }
    }
    if(head_type == hs_hex) {
        color(colour)
            cylinder(r = head_rad, h = head_height, $fn = 6);

        shaft();
    }
    if(head_type == hs_pan) {
        socket_rad = 0.6 * head_rad;
        socket_depth = 0.5 * head_height;
        socket_width = 1;
        color(colour) {
            rotate_extrude()
                difference() {
                    rounded_corner(r = head_rad, h = head_height, r2 =

head_height / 2);

                    translate([0, head_height - socket_depth])
                        square([socket_rad, 10]);
                }

            linear_extrude(head_height)
                difference() {
                    circle(socket_rad + eps);

                    square([2 * socket_rad, socket_width], center =

true);
square([socket_width, 2 * socket_rad], center =
true);
}
}
shaft();
}

    if(head_type == hs_dome) {
        lift = 0.38;
        h = head_height - lift;
        r = min(2 * head_height, (sqr(head_rad) + sqr(h)) / 2 * h); //

Special case for M2
y = sqrt(sqr(r) - sqr(head_rad));
color(colour) {
rotate_extrude() {
difference() {
intersection() {
translate([0, -y + lift])
circle(r);

                        square([head_rad, head_height]);
                    }
                    translate([0, head_height - socket_depth])
                        square([socket_rad, 10]);
                }
            }
            linear_extrude(head_height)
                difference() {
                    circle(socket_rad + eps);
                    circle(socket_rad, $fn = 6);
                }
        }
        shaft();
    }

    if(head_type == hs_cs) {
        socket_rad = 0.6 * head_rad;
        socket_depth = 0.3 * head_rad;
        socket_width = 1;
        color(colour)
            cs_head(socket_rad, socket_depth) {
                square([2 * socket_rad, socket_width], center = true);
                square([socket_width, 2 * socket_rad], center = true);
            }

        shaft(socket_depth);
    }

    if(head_type == hs_cs_cap) {
        color(colour)
            cs_head(socket_rad, socket_depth)
                circle(socket_rad, $fn = 6);

        shaft(socket_depth);
    }
}

}

module screw_countersink(type, drilled = true) { //! Countersink shape
head_type  = screw_head_type(type);
head_rad    = screw_head_radius(type);
rad = screw_radius(type);
head_t = rad / 5;
head_height = head_rad + head_t;

if(head_type == hs_cs || head_type == hs_cs_cap)
    translate_z(-head_height)
        if(drilled)
            cylinder(h = head_height + eps, r1 = 0, r2 = head_rad +

head_t);
else
render() intersection() {
cylinder(h = head_height + eps, r1 = 0, r2 = head_rad +
head_t);

                cylinder(h = head_height + eps, r = head_rad + eps);
            }

}

function screw_polysink_r(type, z) = //! Countersink hole profile corrected
for rounded staircase extrusions.
let(rad = screw_radius(type),
head_t = rad / 5,
head_rad = screw_head_radius(type)
)
limit(head_rad + head_t - z + (sqrt(2) - 1) * layer_height / 2,
screw_clearance_radius(type), head_rad);

module screw_polysink(type, h = 100, alt = false, sink = 0) { //! A
countersink hole made from stacked polyholes for printed parts, default is
flush, sink can be used to recess the head
head_depth = screw_head_depth(type);
assert(head_depth, "Not a countersunk screw");
layers = ceil((head_depth + sink) / layer_height);
rmin = screw_clearance_radius(type);
sides = sides(rmin);
lh = layer_height + eps;
render(convexity = 5)
for(side = [0, 1]) mirror([0, 0, side]) {
for(i = [0 : layers - 1])
translate_z(i * layer_height) {
r = screw_polysink_r(type, i * layer_height +
layer_height / 2 - sink);
if(alt)
rotate(i % 2 == layers % 2 ? 180 / sides : 0)
poly_cylinder(r = r, h = lh, center = false,
sides = sides);
else
poly_cylinder(r = r, h = lh, center = false);
}

        remainder = h / 2 - layers * layer_height;
        if(remainder > 0)
            translate_z(layers * layer_height)
                poly_cylinder(r = rmin, h = remainder, center = false);
    }

}

module screw_and_washer(type, length, star = false, penny = false) { //!
Screw with a washer which can be standard or penny and an optional star
washer on top
washer = screw_washer(type);
head_type = screw_head_type(type);

if(head_type != hs_cs && head_type != hs_cs_cap) {
    translate_z(exploded() * 6)
        if(penny)
            penny_washer(washer);
        else
            washer(washer);

    translate_z(washer_thickness(washer)) {
        if(star) {
            translate_z(exploded() * 8)
                star_washer(washer);

            translate_z(washer_thickness(washer))
                screw(type, length);
        }
        else
            screw(type, length);
    }
}
else
    translate_z(eps)
        screw(type, length);

}

--
Sent from: http://forum.openscad.org/

Could someone help me to design this small bolt please? This will be a great learning exercise in how to choose and use library files, and 'include' or 'use' them, as well as the practical matter of replacing the bolt for the mains plug cover we recently discussed. <http://forum.openscad.org/file/t3184/SmallBolt.jpg> To be honest I'm not sure where to start. Although I've downloaded various apparently relevant files they all seem dauntingly complicated. For example, can my bolt be made by using this file from nophead? // // NopSCADlib Copyright Chris Palmer 2018 // nop.head@gmail.com // hydraraptor.blogspot.com // // This file is part of NopSCADlib. // // NopSCADlib is free software: you can redistribute it and/or modify it under the terms of the // GNU General Public License as published by the Free Software Foundation, either version 3 of // the License, or (at your option) any later version. // // NopSCADlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; // without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // See the GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along with NopSCADlib. // If not, see <https://www.gnu.org/licenses/>. // // //! Machine screws and wood screws with various head styles. //! //! For an explanation of `screw_polysink()` see <https://hydraraptor.blogspot.com/2020/12/sinkholes.html>. // include <../utils/core/core.scad> use <washer.scad> use <nut.scad> use <../utils/rounded_cylinder.scad> use <../utils/thread.scad> include <inserts.scad> function screw_head_type(type) = type[2]; //! Head style hs_cap, hs_pan, hs_cs, hs_hex, hs_grub, hs_cs_cap, hs_dome function screw_radius(type) = type[3] / 2; //! Nominal radius function screw_head_radius(type) = type[4] / 2; //! Head radius function screw_head_height(type) = type[5]; //! Head height function screw_socket_depth(type) = type[6]; //! Socket or slot depth function screw_socket_af(type) = type[7]; //! Socket across flats function screw_max_thread(type) = type[8]; //! Maximum thread length function screw_washer(type) = type[9]; //! Default washer function screw_nut(type) = type[10]; //! Default nut function screw_pilot_hole(type) = type[11]; //! Pilot hole radius for wood screws, tap radius for machine screws function screw_clearance_radius(type) = type[12]; //! Clearance hole radius function screw_nut_radius(type) = screw_nut(type) ? nut_radius(screw_nut(type)) : 0; //! Radius of matching nut function screw_boss_diameter(type) = max(washer_diameter(screw_washer(type)) + 1, 2 * (screw_nut_radius(type) + 3 * extrusion_width)); //! Boss big enough for nut trap and washer function screw_head_depth(type, d = 0) = //! How far a counter sink head will go into a straight hole diameter d screw_head_height(type) ? 0 : let(r = screw_radius(type)) screw_head_radius(type) - max(r, d / 2) + r / 5; function screw_longer_than(x) = x <= 5 ? 5 : //! Returns the length of the shortest screw length longer or equal to x x <= 6 ? 6 : x <= 8 ? 8 : x <= 10 ? 10 : x <= 12 ? 12 : x <= 16 ? 16 : ceil(x / 5) * 5; function screw_shorter_than(x) = x >= 20 ? floor(x / 5) * 5 : //! Returns the length of the longest screw shorter than or equal to x x >= 16 ? 16 : x >= 12 ? 12 : x >= 10 ? 10 : x >= 8 ? 8 : x >= 6 ? 6 : 5; function screw_length(screw, thickness, washers, insert = false, nyloc = false, nut = false, longer = false) = //! Returns the length of the longest or shortest screw that will got through `thickness` and `washers` and possibly an `insert`, `nut` or `nyloc` let(washer = washers ? washers * washer_thickness(screw_washer(screw)) : 0, insert = insert ? insert_length(screw_insert(screw)) : 0, nut = nut || nyloc ? nut_thickness(screw_nut(screw), nyloc) : 0, total = thickness + washer + insert + nut ) longer || nut || nyloc ? screw_longer_than(total) : screw_shorter_than(total); function screw_smaller_than(d) = d >= 2.5 && d < 3 ? 2.5 : floor(d); // Largest diameter screw less than or equal to specified diameter function screw_insert(screw, i = 0) = let(d = screw_radius(screw) * 2) i >= len(inserts) ? undef : insert_screw_diameter(inserts[i]) == d ? inserts[i] : screw_insert(screw, i + 1); module screw(type, length, hob_point = 0, nylon = false) { //! Draw specified screw, optionally hobbed or nylon description = str("Screw ", nylon ? "Nylon " : "", type[1], length < 10 ? " x " : " x ", length, "mm", hob_point ? str(", hobbed at ", hob_point) : ""); vitamin(str("screw(", type[0], "_screw, ", length, arg(hob_point, 0, "hob_point"), arg(nylon, false, "nylon"), "): ", description)); head_type = screw_head_type(type); rad = screw_radius(type) - eps; head_rad = screw_head_radius(type); head_height = screw_head_height(type); socket_af = screw_socket_af(type); socket_depth= screw_socket_depth(type); socket_rad = socket_af / cos(30) / 2; max_thread = screw_max_thread(type); thread = max_thread ? length >= max_thread + 5 ? max_thread : length : length; d = 2 * screw_radius(type); pitch = metric_coarse_pitch(d); colour = nylon || head_type == hs_grub ? grey(40) : grey(80); module shaft(socket = 0, headless = false) { point = screw_nut(type) ? 0 : 3 * rad; shank = length - thread - socket; if(show_threads && !point && pitch) translate_z(-length) male_metric_thread(d, pitch, thread - (shank > 0 || headless ? 0 : socket), false, top = headless ? -1 : 0, solid = !headless, colour = colour); else color(colour * 0.9) rotate_extrude() { translate([0, -length + point]) square([rad, length - socket - point]); if(point) polygon([ [0.4, -length], [0, point - length], [rad, point - length] ]); } if(shank > 0) color(colour) translate_z(-shank - socket) cylinder(r = rad + eps, h = shank); } module cs_head(socket_rad, socket_depth) { head_t = rad / 5; head_height = head_rad + head_t; rotate_extrude() difference() { polygon([[0, 0], [head_rad, 0], [head_rad, -head_t], [0, -head_height]]); translate([0, -socket_depth + eps]) square([socket_rad, 10]); } translate_z(-socket_depth) linear_extrude(socket_depth) difference() { circle(socket_rad + 0.1); children(); } } explode(length + 10) { if(head_type == hs_cap) { color(colour) { cylinder(r = head_rad, h = head_height - socket_depth); translate_z(head_height - socket_depth) linear_extrude(socket_depth) difference() { circle(head_rad); circle(socket_rad, $fn = 6); } } shaft(); } if(head_type == hs_grub) { color(colour) { r = show_threads ? rad - pitch / 2 : rad; translate_z(-socket_depth) linear_extrude(socket_depth) difference() { circle(r); circle(socket_rad, $fn = 6); } shaft(socket_depth, true); if(show_threads) translate_z(-length) cylinder(r = r, h = length - socket_depth); } } if(head_type == hs_hex) { color(colour) cylinder(r = head_rad, h = head_height, $fn = 6); shaft(); } if(head_type == hs_pan) { socket_rad = 0.6 * head_rad; socket_depth = 0.5 * head_height; socket_width = 1; color(colour) { rotate_extrude() difference() { rounded_corner(r = head_rad, h = head_height, r2 = head_height / 2); translate([0, head_height - socket_depth]) square([socket_rad, 10]); } linear_extrude(head_height) difference() { circle(socket_rad + eps); square([2 * socket_rad, socket_width], center = true); square([socket_width, 2 * socket_rad], center = true); } } shaft(); } if(head_type == hs_dome) { lift = 0.38; h = head_height - lift; r = min(2 * head_height, (sqr(head_rad) + sqr(h)) / 2 * h); // Special case for M2 y = sqrt(sqr(r) - sqr(head_rad)); color(colour) { rotate_extrude() { difference() { intersection() { translate([0, -y + lift]) circle(r); square([head_rad, head_height]); } translate([0, head_height - socket_depth]) square([socket_rad, 10]); } } linear_extrude(head_height) difference() { circle(socket_rad + eps); circle(socket_rad, $fn = 6); } } shaft(); } if(head_type == hs_cs) { socket_rad = 0.6 * head_rad; socket_depth = 0.3 * head_rad; socket_width = 1; color(colour) cs_head(socket_rad, socket_depth) { square([2 * socket_rad, socket_width], center = true); square([socket_width, 2 * socket_rad], center = true); } shaft(socket_depth); } if(head_type == hs_cs_cap) { color(colour) cs_head(socket_rad, socket_depth) circle(socket_rad, $fn = 6); shaft(socket_depth); } } } module screw_countersink(type, drilled = true) { //! Countersink shape head_type = screw_head_type(type); head_rad = screw_head_radius(type); rad = screw_radius(type); head_t = rad / 5; head_height = head_rad + head_t; if(head_type == hs_cs || head_type == hs_cs_cap) translate_z(-head_height) if(drilled) cylinder(h = head_height + eps, r1 = 0, r2 = head_rad + head_t); else render() intersection() { cylinder(h = head_height + eps, r1 = 0, r2 = head_rad + head_t); cylinder(h = head_height + eps, r = head_rad + eps); } } function screw_polysink_r(type, z) = //! Countersink hole profile corrected for rounded staircase extrusions. let(rad = screw_radius(type), head_t = rad / 5, head_rad = screw_head_radius(type) ) limit(head_rad + head_t - z + (sqrt(2) - 1) * layer_height / 2, screw_clearance_radius(type), head_rad); module screw_polysink(type, h = 100, alt = false, sink = 0) { //! A countersink hole made from stacked polyholes for printed parts, default is flush, `sink` can be used to recess the head head_depth = screw_head_depth(type); assert(head_depth, "Not a countersunk screw"); layers = ceil((head_depth + sink) / layer_height); rmin = screw_clearance_radius(type); sides = sides(rmin); lh = layer_height + eps; render(convexity = 5) for(side = [0, 1]) mirror([0, 0, side]) { for(i = [0 : layers - 1]) translate_z(i * layer_height) { r = screw_polysink_r(type, i * layer_height + layer_height / 2 - sink); if(alt) rotate(i % 2 == layers % 2 ? 180 / sides : 0) poly_cylinder(r = r, h = lh, center = false, sides = sides); else poly_cylinder(r = r, h = lh, center = false); } remainder = h / 2 - layers * layer_height; if(remainder > 0) translate_z(layers * layer_height) poly_cylinder(r = rmin, h = remainder, center = false); } } module screw_and_washer(type, length, star = false, penny = false) { //! Screw with a washer which can be standard or penny and an optional star washer on top washer = screw_washer(type); head_type = screw_head_type(type); if(head_type != hs_cs && head_type != hs_cs_cap) { translate_z(exploded() * 6) if(penny) penny_washer(washer); else washer(washer); translate_z(washer_thickness(washer)) { if(star) { translate_z(exploded() * 8) star_washer(washer); translate_z(washer_thickness(washer)) screw(type, length); } else screw(type, length); } } else translate_z(eps) screw(type, length); } -- Sent from: http://forum.openscad.org/
JB
Jordan Brown
Wed, Jun 9, 2021 12:04 AM

What's your goal?

Do you want a bolt that will actually work, that you can thread into a
nut, printed on a conventional plastic-extruding 3D printer?  I haven't
tried to do it myself, but my bet is that you can't do it, that a 3D
printer isn't precise enough and the plastic isn't strong enough.

Do you want a part that you can drop into a preview to see what it will
look like, to see how it fits together?  Sure looks like two cylinders
to me.  Maybe two cylinders as the base plus a bunch more tiny cylinders
to visually simulate threads.  (Note that threads have to be a helix to
work, but visually it's mostly OK if they're just circles.)

Do you want a part that you will build into an assembly so that it
looks like there's a screw there?  Looks like some kind of squashed
sphere with a couple of cubes differenced out of it, and you don't have
to model the threaded part because it's hidden.

What's your goal? Do you want a bolt that will actually work, that you can thread into a nut, printed on a conventional plastic-extruding 3D printer?  I haven't tried to do it myself, but my bet is that you can't do it, that a 3D printer isn't precise enough and the plastic isn't strong enough. Do you want a part that you can drop into a preview to see what it will look like, to see how it fits together?  Sure looks like two cylinders to me.  Maybe two cylinders as the base plus a bunch more tiny cylinders to visually simulate threads.  (Note that threads have to be a helix to work, but visually it's mostly OK if they're just circles.) Do you want a part that you will build into an assembly so that it *looks* like there's a screw there?  Looks like some kind of squashed sphere with a couple of cubes differenced out of it, and you don't have to model the threaded part because it's hidden.
AC
A. Craig West
Wed, Jun 9, 2021 12:40 AM

I frequently print those, actually. Pla is relatively strong, and the
precision is rather good

On Tue, 8 Jun 2021, 20:04 Jordan Brown, openscad@jordan.maileater.net
wrote:

What's your goal?

Do you want a bolt that will actually work, that you can thread into a
nut, printed on a conventional plastic-extruding 3D printer?  I haven't
tried to do it myself, but my bet is that you can't do it, that a 3D
printer isn't precise enough and the plastic isn't strong enough.

Do you want a part that you can drop into a preview to see what it will
look like, to see how it fits together?  Sure looks like two cylinders to
me.  Maybe two cylinders as the base plus a bunch more tiny cylinders to
visually simulate threads.  (Note that threads have to be a helix to work,
but visually it's mostly OK if they're just circles.)

Do you want a part that you will build into an assembly so that it looks
like there's a screw there?  Looks like some kind of squashed sphere with a
couple of cubes differenced out of it, and you don't have to model the
threaded part because it's hidden.


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

I frequently print those, actually. Pla is relatively strong, and the precision is rather good On Tue, 8 Jun 2021, 20:04 Jordan Brown, <openscad@jordan.maileater.net> wrote: > What's your goal? > > Do you want a bolt that will actually work, that you can thread into a > nut, printed on a conventional plastic-extruding 3D printer? I haven't > tried to do it myself, but my bet is that you can't do it, that a 3D > printer isn't precise enough and the plastic isn't strong enough. > > Do you want a part that you can drop into a preview to see what it will > look like, to see how it fits together? Sure looks like two cylinders to > me. Maybe two cylinders as the base plus a bunch more tiny cylinders to > visually simulate threads. (Note that threads have to be a helix to work, > but visually it's mostly OK if they're just circles.) > > Do you want a part that you will build into an assembly so that it *looks* > like there's a screw there? Looks like some kind of squashed sphere with a > couple of cubes differenced out of it, and you don't have to model the > threaded part because it's hidden. > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org >
JB
Jordan Brown
Wed, Jun 9, 2021 3:58 AM

On 6/8/2021 5:40 PM, A. Craig West wrote:

I frequently print those, actually. Pla is relatively strong, and the
precision is rather good

Well, like I said, I have no experience trying to do it myself.  I'm
just amazed; it seems like those threads would be not much more than
printer resolution, and assuming that you print them vertically the
strands are all running the wrong direction for strength.

Maybe part of it is that I almost always use 0.3mm vertical resolution.

I sit corrected.

(But still:  always consider whether you need to model the full
mechanical behavior of the object, or if it only has to look right.)

On 6/8/2021 5:40 PM, A. Craig West wrote: > I frequently print those, actually. Pla is relatively strong, and the > precision is rather good Well, like I said, I have no experience trying to do it myself.  I'm just amazed; it seems like those threads would be not much more than printer resolution, and assuming that you print them vertically the strands are all running the wrong direction for strength. Maybe part of it is that I almost always use 0.3mm vertical resolution. I sit corrected. (But still:  always consider whether you need to model the full mechanical behavior of the object, or if it only has to look right.)
T
Terrypin
Wed, Jun 9, 2021 7:19 AM

/“ I frequently print those, actually. Pla is relatively strong, and the
precision is rather good”./

Can you help me to get started then please! Just one brief working example
of a similar style of small screw or bolt would be really helpful.

Terry

--
Sent from: http://forum.openscad.org/

/“ I frequently print those, actually. Pla is relatively strong, and the precision is rather good”./ Can you help me to get started then please! Just one brief working example of a similar style of small screw or bolt would be really helpful. Terry -- Sent from: http://forum.openscad.org/
T
Terrypin
Wed, Jun 9, 2021 7:31 AM

I added the following EDIT to my opening post last night. But Michael has
just reminded me that edits do not reach email-only users. And that the only
alternative is tp post again. (I’d hoped that, as I am now also an email
subscriber, that strange restriction would have disappeared.)

EDIT, 20:34 8th June.
Just found that by happy timing in the middle of thread ‘How do I edit….’
there’s a very similar question from Karl. I’ll study those promising
replies for a start.
Terry

--
Sent from: http://forum.openscad.org/

I added the following EDIT to my opening post last night. But Michael has just reminded me that edits do not reach email-only users. And that the only alternative is tp post again. (I’d hoped that, as I am now also an email subscriber, that strange restriction would have disappeared.) EDIT, 20:34 8th June. Just found that by happy timing in the middle of thread ‘How do I edit….’ there’s a very similar question from Karl. I’ll study those promising replies for a start. Terry -- Sent from: http://forum.openscad.org/
T
Terrypin
Wed, Jun 9, 2021 7:37 AM

Yes Jordan, as mentioned it’s for “… replacing the bolt for the mains plug
cover we recently discussed.”

Of course, I could do it after a few minutes searching my junk box for a
self-tapping screw of small enough diameter - but wouldn’t learn anything!

--
Sent from: http://forum.openscad.org/

Yes Jordan, as mentioned it’s for “… replacing the bolt for the mains plug cover we recently discussed.” Of course, I could do it after a few minutes searching my junk box for a self-tapping screw of small enough diameter - but wouldn’t learn anything! -- Sent from: http://forum.openscad.org/
A
adrianv
Wed, Jun 9, 2021 10:49 AM

Here's an example for printing screws using BOSL2.  It's UTS instead of
metric, but you can substitute metric sizes.  This test prints 3 nuts and 3
bolts at 3 different tolerances.  Standard metal bolts and nuts are defined
at different fit tolerances.  The $slop parameter causes the model to be
undersized by the specified amount to handle overextrusion.  The fit you get
will depend on the $slop parameter and the tolerance you use.  The
tolerances for metric screws are totally different and more confusing than
UTS.  You can try the default tolerance and specify a size like "M4" and
experiment with the $slop parameter to see how that affects your fit.  (You
can pass it individually to a screw call like $fn.)

If you want screws to be as strong as possible you should 3d print them
sideways with enough of the screw cut off so you don't need supports.  The
full round screw isn't needed for it to function, and this avoids the
problem of the screw failing at layer lines.  (You can find tests on youtube
showing that this is stronger.)  I printed the above at 0.15 layer
thickness and was able to get a decent fit with standard metal screws.  (I
don't recall which one fit the best.)

include<BOSL2/std.scad>
include<BOSL2/screws.scad>

$fn=64;
$slop = 0.05;

// Example: The three different UTS screw tolerances
module label(val)
{
difference(){
children();
yflip()linear_extrude(height=.35)
text(val,valign="center",halign="center",size=8);
}
}
xdistribute(spacing=15){
label("1") screw("1/4-20,5/8",
head="hex",orient=DOWN,anchor_head=TOP,tolerance="1A");  // Loose
label("2") screw("1/4-20,5/8",
head="hex",orient=DOWN,anchor_head=TOP,tolerance="2A");  // Standard
label("3") screw("1/4-20,5/8",
head="hex",orient=DOWN,anchor_head=TOP,tolerance="3A");  // Tight
}

// Example: The three different UTS nut tolerances
inch=25.4;
module mark(number)
{
difference(){
children();
ycopies(n=number, spacing=1.5)right(.25inch-2)up(8-.35)cyl(d=1,
h=1);
}
}
back(20)
xdistribute(spacing=17){
mark(1) nut("1/4-20", thickness=8, diameter=0.5
inch,tolerance="1B");
mark(2) nut("1/4-20", thickness=8, diameter=0.5inch,tolerance="2B");
mark(3) nut("1/4-20", thickness=8, diameter=0.5
inch,tolerance="3B");
}

--
Sent from: http://forum.openscad.org/

Here's an example for printing screws using BOSL2. It's UTS instead of metric, but you can substitute metric sizes. This test prints 3 nuts and 3 bolts at 3 different tolerances. Standard metal bolts and nuts are defined at different fit tolerances. The $slop parameter causes the model to be undersized by the specified amount to handle overextrusion. The fit you get will depend on the $slop parameter and the tolerance you use. The tolerances for metric screws are totally different and more confusing than UTS. You can try the default tolerance and specify a size like "M4" and experiment with the $slop parameter to see how that affects your fit. (You can pass it individually to a screw call like $fn.) If you want screws to be as strong as possible you should 3d print them sideways with enough of the screw cut off so you don't need supports. The full round screw isn't needed for it to function, and this avoids the problem of the screw failing at layer lines. (You can find tests on youtube showing that this is stronger.) I printed the above at 0.15 layer thickness and was able to get a decent fit with standard metal screws. (I don't recall which one fit the best.) include<BOSL2/std.scad> include<BOSL2/screws.scad> $fn=64; $slop = 0.05; // Example: The three different UTS screw tolerances module label(val) { difference(){ children(); yflip()linear_extrude(height=.35) text(val,valign="center",halign="center",size=8); } } xdistribute(spacing=15){ label("1") screw("1/4-20,5/8", head="hex",orient=DOWN,anchor_head=TOP,tolerance="1A"); // Loose label("2") screw("1/4-20,5/8", head="hex",orient=DOWN,anchor_head=TOP,tolerance="2A"); // Standard label("3") screw("1/4-20,5/8", head="hex",orient=DOWN,anchor_head=TOP,tolerance="3A"); // Tight } // Example: The three different UTS nut tolerances inch=25.4; module mark(number) { difference(){ children(); ycopies(n=number, spacing=1.5)right(.25*inch-2)up(8-.35)cyl(d=1, h=1); } } back(20) xdistribute(spacing=17){ mark(1) nut("1/4-20", thickness=8, diameter=0.5*inch,tolerance="1B"); mark(2) nut("1/4-20", thickness=8, diameter=0.5*inch,tolerance="2B"); mark(3) nut("1/4-20", thickness=8, diameter=0.5*inch,tolerance="3B"); } -- Sent from: http://forum.openscad.org/
NH
nop head
Wed, Jun 9, 2021 12:03 PM

Sorry this went into my spam folder. The screws in my library are not
intended to be printed. They just represent screws in assembly views. For
example the cross in a pozidriv head is just a flat cross but a real one is
a specific shape to fit the screwdriver. Probably a hex head would be more
practical for printing. Also there is no consideration for round objects
printing too small and they may not even be manifolds.

I do use my library to make printed threads for things like screw top
containers but there I use a non-standard coarse thread designed to be easy
to print. I don't print fasteners because they only cost pennies, so I have
thousands of them but always need some more but I can always get them in a
few days from eBay in small volumes.

On Tue, 8 Jun 2021 at 18:20, Terrypin terrypingm@gmail.com wrote:

Could someone help me to design this small bolt please? This will be a
great learning exercise in how to choose and use library files, and
'include' or 'use' them, as well as the practical matter of replacing the
bolt for the mains plug cover we recently discussed.

To be honest I'm not sure where to start. Although I've downloaded various
apparently relevant files they all seem dauntingly complicated. For
example, can my bolt be made by using this file from nophead?

//
// NopSCADlib Copyright Chris Palmer 2018
// nop.head@gmail.com
// hydraraptor.blogspot.com
//
// This file is part of NopSCADlib.
//
// NopSCADlib is free software: you can redistribute it and/or modify it
under the terms of the
// GNU General Public License as published by the Free Software
Foundation, either version 3 of
// the License, or (at your option) any later version.
//
// NopSCADlib is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY;
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
with NopSCADlib.
// If not, see https://www.gnu.org/licenses/.
//

//
//! Machine screws and wood screws with various head styles.
//!
//! For an explanation of screw_polysink() see <
https://hydraraptor.blogspot.com/2020/12/sinkholes.html>.
//
include <../utils/core/core.scad>

use <washer.scad>
use <nut.scad>
use <../utils/rounded_cylinder.scad>
use <../utils/thread.scad>
include <inserts.scad>

function screw_head_type(type)        = type[2];    //! Head style
hs_cap, hs_pan, hs_cs, hs_hex, hs_grub, hs_cs_cap, hs_dome
function screw_radius(type)          = type[3] / 2; //! Nominal radius
function screw_head_radius(type)      = type[4] / 2; //! Head radius
function screw_head_height(type)      = type[5];    //! Head height
function screw_socket_depth(type)    = type[6];    //! Socket or slot
depth
function screw_socket_af(type)        = type[7];    //! Socket across
flats
function screw_max_thread(type)      = type[8];    //! Maximum thread
length
function screw_washer(type)          = type[9];    //! Default washer
function screw_nut(type)              = type[10];    //! Default nut
function screw_pilot_hole(type)      = type[11];    //! Pilot hole radius
for wood screws, tap radius for machine screws
function screw_clearance_radius(type) = type[12];    //! Clearance hole
radius
function screw_nut_radius(type) = screw_nut(type) ?
nut_radius(screw_nut(type)) : 0; //! Radius of matching nut
function screw_boss_diameter(type) =
max(washer_diameter(screw_washer(type)) + 1, 2 * (screw_nut_radius(type) +
3 * extrusion_width)); //! Boss big enough for nut trap and washer
function screw_head_depth(type, d = 0) =            //! How far a counter
sink head will go into a straight hole diameter d
screw_head_height(type)
? 0
: let(r = screw_radius(type)) screw_head_radius(type) - max(r, d /
2) + r / 5;

function screw_longer_than(x) = x <=  5 ?  5 : //! Returns the length of
the shortest screw length longer or equal to x
x <=  6 ?  6 :
x <=  8 ?  8 :
x <= 10 ? 10 :
x <= 12 ? 12 :
x <= 16 ? 16 :
ceil(x / 5) * 5;

function screw_shorter_than(x) = x >= 20 ? floor(x / 5) * 5 : //! Returns
the length of the longest screw shorter than or equal to x
x >= 16 ? 16 :
x >= 12 ? 12 :
x >= 10 ? 10 :
x >=  8 ?  8 :
x >=  6 ?  6 :
5;

function screw_length(screw, thickness, washers, insert = false, nyloc =
false, nut = false, longer = false) = //! Returns the length of the longest
or shortest screw that will got through thickness and washers and
possibly an insert, nut or nyloc
let(washer = washers ? washers * washer_thickness(screw_washer(screw))
: 0,
insert = insert ? insert_length(screw_insert(screw)) : 0,
nut = nut || nyloc ? nut_thickness(screw_nut(screw), nyloc)  : 0,
total = thickness + washer + insert + nut
)
longer || nut || nyloc ? screw_longer_than(total) :
screw_shorter_than(total);

function screw_smaller_than(d) = d >= 2.5 && d < 3 ? 2.5 : floor(d); //
Largest diameter screw less than or equal to specified diameter

function screw_insert(screw, i = 0) = let(d = screw_radius(screw) * 2)
i >= len(inserts) ? undef
: insert_screw_diameter(inserts[i]) == d ?
inserts[i]
:
screw_insert(screw, i + 1);

module screw(type, length, hob_point = 0, nylon = false) { //! Draw
specified screw, optionally hobbed or nylon
description = str("Screw ", nylon ? "Nylon " : "", type[1], length <
10 ? " x  " : " x ", length, "mm", hob_point ? str(", hobbed at ",
hob_point) : "");
vitamin(str("screw(", type[0], "_screw, ", length, arg(hob_point, 0,
"hob_point"), arg(nylon, false, "nylon"), "): ", description));

 head_type   = screw_head_type(type);
 rad         = screw_radius(type) - eps;
 head_rad    = screw_head_radius(type);
 head_height = screw_head_height(type);
 socket_af   = screw_socket_af(type);
 socket_depth= screw_socket_depth(type);
 socket_rad  = socket_af / cos(30) / 2;
 max_thread  = screw_max_thread(type);
 thread = max_thread ? length >= max_thread + 5 ? max_thread
                                                : length
                     : length;
 d = 2 * screw_radius(type);
 pitch = metric_coarse_pitch(d);
 colour = nylon || head_type == hs_grub ? grey(40) : grey(80);

 module shaft(socket = 0, headless = false) {
     point = screw_nut(type) ? 0 : 3 * rad;
     shank  = length - thread - socket;

     if(show_threads && !point && pitch)
         translate_z(-length)
             male_metric_thread(d, pitch, thread - (shank > 0 ||

headless ? 0 : socket), false, top = headless ? -1 : 0, solid = !headless,
colour = colour);
else
color(colour * 0.9)
rotate_extrude() {
translate([0, -length + point])
square([rad, length - socket - point]);

                 if(point)
                     polygon([
                         [0.4, -length], [0, point - length], [rad,

point - length]
]);
}

     if(shank > 0)
         color(colour)
             translate_z(-shank - socket)
                 cylinder(r = rad + eps, h = shank);
 }

 module cs_head(socket_rad, socket_depth) {
     head_t = rad / 5;
     head_height = head_rad + head_t;

     rotate_extrude()
         difference() {
             polygon([[0, 0], [head_rad, 0], [head_rad, -head_t], [0,

-head_height]]);

             translate([0, -socket_depth + eps])
                 square([socket_rad, 10]);
         }

     translate_z(-socket_depth)
         linear_extrude(socket_depth)
             difference() {
                 circle(socket_rad + 0.1);

                 children();
             }
 }

 explode(length + 10) {
     if(head_type == hs_cap) {
         color(colour) {
             cylinder(r = head_rad, h = head_height - socket_depth);

             translate_z(head_height - socket_depth)
                 linear_extrude(socket_depth)
                     difference() {
                         circle(head_rad);

                         circle(socket_rad, $fn = 6);
                     }

         }
         shaft();
     }
     if(head_type == hs_grub) {
         color(colour) {
             r = show_threads ? rad - pitch / 2 : rad;
             translate_z(-socket_depth)
                 linear_extrude(socket_depth)
                     difference() {
                         circle(r);

                         circle(socket_rad, $fn = 6);
                     }

             shaft(socket_depth, true);

             if(show_threads)
                 translate_z(-length)
                     cylinder(r = r, h = length - socket_depth);
         }
     }
     if(head_type == hs_hex) {
         color(colour)
             cylinder(r = head_rad, h = head_height, $fn = 6);

         shaft();
     }
     if(head_type == hs_pan) {
         socket_rad = 0.6 * head_rad;
         socket_depth = 0.5 * head_height;
         socket_width = 1;
         color(colour) {
             rotate_extrude()
                 difference() {
                     rounded_corner(r = head_rad, h = head_height, r2 =

head_height / 2);

                     translate([0, head_height - socket_depth])
                         square([socket_rad, 10]);
                 }

             linear_extrude(head_height)
                 difference() {
                     circle(socket_rad + eps);

                     square([2 * socket_rad, socket_width], center =

true);
square([socket_width, 2 * socket_rad], center =
true);
}
}
shaft();
}

     if(head_type == hs_dome) {
         lift = 0.38;
         h = head_height - lift;
         r = min(2 * head_height, (sqr(head_rad) + sqr(h)) / 2 * h); //

Special case for M2
y = sqrt(sqr(r) - sqr(head_rad));
color(colour) {
rotate_extrude() {
difference() {
intersection() {
translate([0, -y + lift])
circle(r);

                         square([head_rad, head_height]);
                     }
                     translate([0, head_height - socket_depth])
                         square([socket_rad, 10]);
                 }
             }
             linear_extrude(head_height)
                 difference() {
                     circle(socket_rad + eps);
                     circle(socket_rad, $fn = 6);
                 }
         }
         shaft();
     }

     if(head_type == hs_cs) {
         socket_rad = 0.6 * head_rad;
         socket_depth = 0.3 * head_rad;
         socket_width = 1;
         color(colour)
             cs_head(socket_rad, socket_depth) {
                 square([2 * socket_rad, socket_width], center = true);
                 square([socket_width, 2 * socket_rad], center = true);
             }

         shaft(socket_depth);
     }

     if(head_type == hs_cs_cap) {
         color(colour)
             cs_head(socket_rad, socket_depth)
                 circle(socket_rad, $fn = 6);

         shaft(socket_depth);
     }
 }

}

module screw_countersink(type, drilled = true) { //! Countersink shape
head_type  = screw_head_type(type);
head_rad    = screw_head_radius(type);
rad = screw_radius(type);
head_t = rad / 5;
head_height = head_rad + head_t;

 if(head_type == hs_cs || head_type == hs_cs_cap)
     translate_z(-head_height)
         if(drilled)
             cylinder(h = head_height + eps, r1 = 0, r2 = head_rad +

head_t);
else
render() intersection() {
cylinder(h = head_height + eps, r1 = 0, r2 = head_rad

  • head_t);

                  cylinder(h = head_height + eps, r = head_rad + eps);
              }
    

}

function screw_polysink_r(type, z) = //! Countersink hole profile
corrected for rounded staircase extrusions.
let(rad = screw_radius(type),
head_t = rad / 5,
head_rad = screw_head_radius(type)
)
limit(head_rad + head_t - z + (sqrt(2) - 1) * layer_height / 2,
screw_clearance_radius(type), head_rad);

module screw_polysink(type, h = 100, alt = false, sink = 0) { //! A
countersink hole made from stacked polyholes for printed parts, default is
flush, sink can be used to recess the head
head_depth = screw_head_depth(type);
assert(head_depth, "Not a countersunk screw");
layers = ceil((head_depth + sink) / layer_height);
rmin = screw_clearance_radius(type);
sides = sides(rmin);
lh = layer_height + eps;
render(convexity = 5)
for(side = [0, 1]) mirror([0, 0, side]) {
for(i = [0 : layers - 1])
translate_z(i * layer_height) {
r = screw_polysink_r(type, i * layer_height +
layer_height / 2 - sink);
if(alt)
rotate(i % 2 == layers % 2 ? 180 / sides : 0)
poly_cylinder(r = r, h = lh, center = false,
sides = sides);
else
poly_cylinder(r = r, h = lh, center = false);
}

         remainder = h / 2 - layers * layer_height;
         if(remainder > 0)
             translate_z(layers * layer_height)
                 poly_cylinder(r = rmin, h = remainder, center =

false);
}
}

module screw_and_washer(type, length, star = false, penny = false) { //!
Screw with a washer which can be standard or penny and an optional star
washer on top
washer = screw_washer(type);
head_type = screw_head_type(type);

 if(head_type != hs_cs && head_type != hs_cs_cap) {
     translate_z(exploded() * 6)
         if(penny)
             penny_washer(washer);
         else
             washer(washer);

     translate_z(washer_thickness(washer)) {
         if(star) {
             translate_z(exploded() * 8)
                 star_washer(washer);

             translate_z(washer_thickness(washer))
                 screw(type, length);
         }
         else
             screw(type, length);
     }
 }
 else
     translate_z(eps)
         screw(type, length);

}

Sent from the OpenSCAD mailing list archive http://forum.openscad.org/
at Nabble.com.


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

Sorry this went into my spam folder. The screws in my library are not intended to be printed. They just represent screws in assembly views. For example the cross in a pozidriv head is just a flat cross but a real one is a specific shape to fit the screwdriver. Probably a hex head would be more practical for printing. Also there is no consideration for round objects printing too small and they may not even be manifolds. I do use my library to make printed threads for things like screw top containers but there I use a non-standard coarse thread designed to be easy to print. I don't print fasteners because they only cost pennies, so I have thousands of them but always need some more but I can always get them in a few days from eBay in small volumes. On Tue, 8 Jun 2021 at 18:20, Terrypin <terrypingm@gmail.com> wrote: > Could someone help me to design this small bolt please? This will be a > great learning exercise in how to choose and use library files, and > 'include' or 'use' them, as well as the practical matter of replacing the > bolt for the mains plug cover we recently discussed. > > > > To be honest I'm not sure where to start. Although I've downloaded various > apparently relevant files they all seem dauntingly complicated. For > example, can my bolt be made by using this file from nophead? > > > // > // NopSCADlib Copyright Chris Palmer 2018 > // nop.head@gmail.com > // hydraraptor.blogspot.com > // > // This file is part of NopSCADlib. > // > // NopSCADlib is free software: you can redistribute it and/or modify it > under the terms of the > // GNU General Public License as published by the Free Software > Foundation, either version 3 of > // the License, or (at your option) any later version. > // > // NopSCADlib is distributed in the hope that it will be useful, but > WITHOUT ANY WARRANTY; > // without even the implied warranty of MERCHANTABILITY or FITNESS FOR A > PARTICULAR PURPOSE. > // See the GNU General Public License for more details. > // > // You should have received a copy of the GNU General Public License along > with NopSCADlib. > // If not, see <https://www.gnu.org/licenses/>. > // > > // > //! Machine screws and wood screws with various head styles. > //! > //! For an explanation of `screw_polysink()` see < > https://hydraraptor.blogspot.com/2020/12/sinkholes.html>. > // > include <../utils/core/core.scad> > > use <washer.scad> > use <nut.scad> > use <../utils/rounded_cylinder.scad> > use <../utils/thread.scad> > include <inserts.scad> > > function screw_head_type(type) = type[2]; //! Head style > hs_cap, hs_pan, hs_cs, hs_hex, hs_grub, hs_cs_cap, hs_dome > function screw_radius(type) = type[3] / 2; //! Nominal radius > function screw_head_radius(type) = type[4] / 2; //! Head radius > function screw_head_height(type) = type[5]; //! Head height > function screw_socket_depth(type) = type[6]; //! Socket or slot > depth > function screw_socket_af(type) = type[7]; //! Socket across > flats > function screw_max_thread(type) = type[8]; //! Maximum thread > length > function screw_washer(type) = type[9]; //! Default washer > function screw_nut(type) = type[10]; //! Default nut > function screw_pilot_hole(type) = type[11]; //! Pilot hole radius > for wood screws, tap radius for machine screws > function screw_clearance_radius(type) = type[12]; //! Clearance hole > radius > function screw_nut_radius(type) = screw_nut(type) ? > nut_radius(screw_nut(type)) : 0; //! Radius of matching nut > function screw_boss_diameter(type) = > max(washer_diameter(screw_washer(type)) + 1, 2 * (screw_nut_radius(type) + > 3 * extrusion_width)); //! Boss big enough for nut trap and washer > function screw_head_depth(type, d = 0) = //! How far a counter > sink head will go into a straight hole diameter d > screw_head_height(type) > ? 0 > : let(r = screw_radius(type)) screw_head_radius(type) - max(r, d / > 2) + r / 5; > > function screw_longer_than(x) = x <= 5 ? 5 : //! Returns the length of > the shortest screw length longer or equal to x > x <= 6 ? 6 : > x <= 8 ? 8 : > x <= 10 ? 10 : > x <= 12 ? 12 : > x <= 16 ? 16 : > ceil(x / 5) * 5; > > function screw_shorter_than(x) = x >= 20 ? floor(x / 5) * 5 : //! Returns > the length of the longest screw shorter than or equal to x > x >= 16 ? 16 : > x >= 12 ? 12 : > x >= 10 ? 10 : > x >= 8 ? 8 : > x >= 6 ? 6 : > 5; > > function screw_length(screw, thickness, washers, insert = false, nyloc = > false, nut = false, longer = false) = //! Returns the length of the longest > or shortest screw that will got through `thickness` and `washers` and > possibly an `insert`, `nut` or `nyloc` > let(washer = washers ? washers * washer_thickness(screw_washer(screw)) > : 0, > insert = insert ? insert_length(screw_insert(screw)) : 0, > nut = nut || nyloc ? nut_thickness(screw_nut(screw), nyloc) : 0, > total = thickness + washer + insert + nut > ) > longer || nut || nyloc ? screw_longer_than(total) : > screw_shorter_than(total); > > function screw_smaller_than(d) = d >= 2.5 && d < 3 ? 2.5 : floor(d); // > Largest diameter screw less than or equal to specified diameter > > function screw_insert(screw, i = 0) = let(d = screw_radius(screw) * 2) > i >= len(inserts) ? undef > : insert_screw_diameter(inserts[i]) == d ? > inserts[i] > : > screw_insert(screw, i + 1); > > module screw(type, length, hob_point = 0, nylon = false) { //! Draw > specified screw, optionally hobbed or nylon > description = str("Screw ", nylon ? "Nylon " : "", type[1], length < > 10 ? " x " : " x ", length, "mm", hob_point ? str(", hobbed at ", > hob_point) : ""); > vitamin(str("screw(", type[0], "_screw, ", length, arg(hob_point, 0, > "hob_point"), arg(nylon, false, "nylon"), "): ", description)); > > head_type = screw_head_type(type); > rad = screw_radius(type) - eps; > head_rad = screw_head_radius(type); > head_height = screw_head_height(type); > socket_af = screw_socket_af(type); > socket_depth= screw_socket_depth(type); > socket_rad = socket_af / cos(30) / 2; > max_thread = screw_max_thread(type); > thread = max_thread ? length >= max_thread + 5 ? max_thread > : length > : length; > d = 2 * screw_radius(type); > pitch = metric_coarse_pitch(d); > colour = nylon || head_type == hs_grub ? grey(40) : grey(80); > > module shaft(socket = 0, headless = false) { > point = screw_nut(type) ? 0 : 3 * rad; > shank = length - thread - socket; > > if(show_threads && !point && pitch) > translate_z(-length) > male_metric_thread(d, pitch, thread - (shank > 0 || > headless ? 0 : socket), false, top = headless ? -1 : 0, solid = !headless, > colour = colour); > else > color(colour * 0.9) > rotate_extrude() { > translate([0, -length + point]) > square([rad, length - socket - point]); > > if(point) > polygon([ > [0.4, -length], [0, point - length], [rad, > point - length] > ]); > } > > if(shank > 0) > color(colour) > translate_z(-shank - socket) > cylinder(r = rad + eps, h = shank); > } > > module cs_head(socket_rad, socket_depth) { > head_t = rad / 5; > head_height = head_rad + head_t; > > rotate_extrude() > difference() { > polygon([[0, 0], [head_rad, 0], [head_rad, -head_t], [0, > -head_height]]); > > translate([0, -socket_depth + eps]) > square([socket_rad, 10]); > } > > translate_z(-socket_depth) > linear_extrude(socket_depth) > difference() { > circle(socket_rad + 0.1); > > children(); > } > } > > explode(length + 10) { > if(head_type == hs_cap) { > color(colour) { > cylinder(r = head_rad, h = head_height - socket_depth); > > translate_z(head_height - socket_depth) > linear_extrude(socket_depth) > difference() { > circle(head_rad); > > circle(socket_rad, $fn = 6); > } > > } > shaft(); > } > if(head_type == hs_grub) { > color(colour) { > r = show_threads ? rad - pitch / 2 : rad; > translate_z(-socket_depth) > linear_extrude(socket_depth) > difference() { > circle(r); > > circle(socket_rad, $fn = 6); > } > > shaft(socket_depth, true); > > if(show_threads) > translate_z(-length) > cylinder(r = r, h = length - socket_depth); > } > } > if(head_type == hs_hex) { > color(colour) > cylinder(r = head_rad, h = head_height, $fn = 6); > > shaft(); > } > if(head_type == hs_pan) { > socket_rad = 0.6 * head_rad; > socket_depth = 0.5 * head_height; > socket_width = 1; > color(colour) { > rotate_extrude() > difference() { > rounded_corner(r = head_rad, h = head_height, r2 = > head_height / 2); > > translate([0, head_height - socket_depth]) > square([socket_rad, 10]); > } > > linear_extrude(head_height) > difference() { > circle(socket_rad + eps); > > square([2 * socket_rad, socket_width], center = > true); > square([socket_width, 2 * socket_rad], center = > true); > } > } > shaft(); > } > > if(head_type == hs_dome) { > lift = 0.38; > h = head_height - lift; > r = min(2 * head_height, (sqr(head_rad) + sqr(h)) / 2 * h); // > Special case for M2 > y = sqrt(sqr(r) - sqr(head_rad)); > color(colour) { > rotate_extrude() { > difference() { > intersection() { > translate([0, -y + lift]) > circle(r); > > square([head_rad, head_height]); > } > translate([0, head_height - socket_depth]) > square([socket_rad, 10]); > } > } > linear_extrude(head_height) > difference() { > circle(socket_rad + eps); > circle(socket_rad, $fn = 6); > } > } > shaft(); > } > > if(head_type == hs_cs) { > socket_rad = 0.6 * head_rad; > socket_depth = 0.3 * head_rad; > socket_width = 1; > color(colour) > cs_head(socket_rad, socket_depth) { > square([2 * socket_rad, socket_width], center = true); > square([socket_width, 2 * socket_rad], center = true); > } > > shaft(socket_depth); > } > > if(head_type == hs_cs_cap) { > color(colour) > cs_head(socket_rad, socket_depth) > circle(socket_rad, $fn = 6); > > shaft(socket_depth); > } > } > } > > module screw_countersink(type, drilled = true) { //! Countersink shape > head_type = screw_head_type(type); > head_rad = screw_head_radius(type); > rad = screw_radius(type); > head_t = rad / 5; > head_height = head_rad + head_t; > > if(head_type == hs_cs || head_type == hs_cs_cap) > translate_z(-head_height) > if(drilled) > cylinder(h = head_height + eps, r1 = 0, r2 = head_rad + > head_t); > else > render() intersection() { > cylinder(h = head_height + eps, r1 = 0, r2 = head_rad > + head_t); > > cylinder(h = head_height + eps, r = head_rad + eps); > } > } > > function screw_polysink_r(type, z) = //! Countersink hole profile > corrected for rounded staircase extrusions. > let(rad = screw_radius(type), > head_t = rad / 5, > head_rad = screw_head_radius(type) > ) > limit(head_rad + head_t - z + (sqrt(2) - 1) * layer_height / 2, > screw_clearance_radius(type), head_rad); > > module screw_polysink(type, h = 100, alt = false, sink = 0) { //! A > countersink hole made from stacked polyholes for printed parts, default is > flush, `sink` can be used to recess the head > head_depth = screw_head_depth(type); > assert(head_depth, "Not a countersunk screw"); > layers = ceil((head_depth + sink) / layer_height); > rmin = screw_clearance_radius(type); > sides = sides(rmin); > lh = layer_height + eps; > render(convexity = 5) > for(side = [0, 1]) mirror([0, 0, side]) { > for(i = [0 : layers - 1]) > translate_z(i * layer_height) { > r = screw_polysink_r(type, i * layer_height + > layer_height / 2 - sink); > if(alt) > rotate(i % 2 == layers % 2 ? 180 / sides : 0) > poly_cylinder(r = r, h = lh, center = false, > sides = sides); > else > poly_cylinder(r = r, h = lh, center = false); > } > > remainder = h / 2 - layers * layer_height; > if(remainder > 0) > translate_z(layers * layer_height) > poly_cylinder(r = rmin, h = remainder, center = > false); > } > } > > module screw_and_washer(type, length, star = false, penny = false) { //! > Screw with a washer which can be standard or penny and an optional star > washer on top > washer = screw_washer(type); > head_type = screw_head_type(type); > > if(head_type != hs_cs && head_type != hs_cs_cap) { > translate_z(exploded() * 6) > if(penny) > penny_washer(washer); > else > washer(washer); > > translate_z(washer_thickness(washer)) { > if(star) { > translate_z(exploded() * 8) > star_washer(washer); > > translate_z(washer_thickness(washer)) > screw(type, length); > } > else > screw(type, length); > } > } > else > translate_z(eps) > screw(type, length); > } > ------------------------------ > Sent from the OpenSCAD mailing list archive <http://forum.openscad.org/> > at Nabble.com. > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org >
T
Terrypin
Wed, Jun 9, 2021 12:13 PM

Thanks so much Adrian. I’ll get stuck into that later today.

I haven’t yet properly organised and tested my libraries, so can I meanwhile
just ensure those two extra files are copied to the same folder as the one
you’ve created for me?

--
Sent from: http://forum.openscad.org/

Thanks so much Adrian. I’ll get stuck into that later today. I haven’t yet properly organised and tested my libraries, so can I meanwhile just ensure those two extra files are copied to the same folder as the one you’ve created for me? -- Sent from: http://forum.openscad.org/