Added male screw threads.

This commit is contained in:
Chris Palmer 2020-01-10 10:26:12 +00:00
parent f7ef075434
commit d703ae4997
18 changed files with 215 additions and 49 deletions

View File

@ -39,6 +39,7 @@ pp2_colour = is_undef($pp2_colour) ? "red" : $pp2_colour; // pri
pp3_colour = is_undef($pp3_colour) ? "blue" : $pp3_colour; // printed part colour 3 pp3_colour = is_undef($pp3_colour) ? "blue" : $pp3_colour; // printed part colour 3
pp4_colour = is_undef($pp4_colour) ? "darkorange" : $pp4_colour;// printed part colour 4 pp4_colour = is_undef($pp4_colour) ? "darkorange" : $pp4_colour;// printed part colour 4
show_rays = is_undef($show_rays) ? false : $show_rays; // show camera sight lines and light direction show_rays = is_undef($show_rays) ? false : $show_rays; // show camera sight lines and light direction
show_threads = is_undef($show_threads) ? false : $show_threads; // show screw threads
// Minimum wall is about two filaments wide but we extrude it closer to get better bonding // Minimum wall is about two filaments wide but we extrude it closer to get better bonding
squeezed_wall = $preview ? 2 * extrusion_width - layer_height * (1 - PI / 4) squeezed_wall = $preview ? 2 * extrusion_width - layer_height * (1 - PI / 4)
@ -59,7 +60,8 @@ grey60 = [0.6, 0.6, 0.6];
grey70 = [0.7, 0.7, 0.7]; grey70 = [0.7, 0.7, 0.7];
grey80 = [0.8, 0.8, 0.8]; grey80 = [0.8, 0.8, 0.8];
grey90 = [0.9, 0.9, 0.9]; grey90 = [0.9, 0.9, 0.9];
brass = "gold"; brass = [255/255, 215/255, 0/255];
silver = [0.75, 0.75, 0.75];
/* /*
* Enums * Enums

View File

@ -90,3 +90,4 @@ use <utils/layout.scad>
use <utils/round.scad> use <utils/round.scad>
use <utils/offset.scad> use <utils/offset.scad>
use <utils/sector.scad> use <utils/sector.scad>
use <utils/thread.scad>

View File

@ -154,7 +154,7 @@ def views(target, do_assemblies = None):
f.write("use <%s/%s>\n" % (dir, filename)) f.write("use <%s/%s>\n" % (dir, filename))
f.write("%s();\n" % module); f.write("%s();\n" % module);
# #
# Run openscad on th created file # Run openscad on the created file
# #
dname = deps_name(deps_dir, filename) dname = deps_name(deps_dir, filename)
for explode in [0, 1]: for explode in [0, 1]:
@ -167,7 +167,7 @@ def views(target, do_assemblies = None):
if changed: if changed:
print(changed) print(changed)
t = time.time() t = time.time()
openscad.run("-D$pose=1", "-D$explode=%d" % explode, colour_scheme, "--projection=p", "--imgsize=4096,4096", "--autocenter", "--viewall", "-d", dname, "-o", tmp_name, png_maker_name); openscad.run("-D$show_threads=1", "-D$pose=1", "-D$explode=%d" % explode, colour_scheme, "--projection=p", "--imgsize=4096,4096", "--autocenter", "--viewall", "-d", dname, "-o", tmp_name, png_maker_name);
times.add_time(png_name, t) times.add_time(png_name, t)
do_cmd(["magick", tmp_name, "-trim", "-resize", "1004x1004", "-bordercolor", background, "-border", "10", tmp_name]) do_cmd(["magick", tmp_name, "-trim", "-resize", "1004x1004", "-bordercolor", background, "-border", "10", tmp_name])
update_image(tmp_name, png_name) update_image(tmp_name, png_name)

View File

@ -35,4 +35,5 @@ module d_connectors()
} }
if($preview) if($preview)
d_connectors(); let($show_threads = true)
d_connectors();

View File

@ -26,4 +26,5 @@ module pillars()
pillar(pillars[$i]); pillar(pillars[$i]);
if($preview) if($preview)
pillars(); let($show_threads = true)
pillars();

Binary file not shown.

Before

Width:  |  Height:  |  Size: 114 KiB

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 57 KiB

After

Width:  |  Height:  |  Size: 99 KiB

View File

@ -33,4 +33,5 @@ module rods()
} }
if($preview) if($preview)
rods(); let($show_threads = true)
rods();

View File

@ -34,4 +34,5 @@ for(y = [0 : len(screw_lists) -1])
} }
if($preview) if($preview)
screws(); let($show_threads = true)
screws();

View File

@ -43,7 +43,7 @@ module ellipse(xr, yr) scale([1, yr / xr]) circle4n(xr);
module extrude_if(h, center = true) //! Extrudes 2D object to 3D when ```h``` is nonzero, otherwise leaves it 2D module extrude_if(h, center = true) //! Extrudes 2D object to 3D when ```h``` is nonzero, otherwise leaves it 2D
if(h) if(h)
linear_extrude(height = h, center = center) // 3D linear_extrude(height = h, center = center, convexity = 2) // 3D
children(); children();
else else
children(); // 2D children(); // 2D

114
utils/thread.scad Normal file
View File

@ -0,0 +1,114 @@
//
// NopSCADlib Copyright Chris Palmer 2019
// 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/>.
//
//
//! A utilities for making threads with sweep.
//
include <../core.scad>
use <sweep.scad>
use <maths.scad>
function thread_profile(h, crest, angle) = //! Create thread profile path
let(base = crest + 2 * h * tan(angle / 2))
[[-base / 2, 0, 0], [-crest / 2, h, 0], [crest / 2, h, 0], [base / 2, 0, 0]];
module male_thread(pitch, minor_d, length, profile, taper_top = true, center = true, solid = true) { //! Create male thread
turns = length / pitch + (taper_top ? 0 : 1);
r = minor_d / 2;
sides = r2sides(r);
h = max([for(p = profile) p.y]);
final = (turns - 1) * sides;
path = [for(i = [0 : sides * turns],
R = i < sides ? r - h + h * i / sides
: i > final && taper_top ? r - h * (i - final) / sides : r,
a = i * 360 / sides)
[R * sin(-a), R * cos(-a), pitch * a / 360]];
t = atan(pitch / sides / (r * cos(225 / sides)));
translate_z(center ? -length / 2 : 0) {
render() intersection() {
sweep(path, profile, twist = t * sides * turns);
cylinder(d = minor_d + 5, h = length);
}
if(solid)
rotate(90)
cylinder(d = minor_d + eps, h = length);
}
}
module female_thread(pitch, outer_d, length, profile, taper_top = true, center = true) { //! Create female thread
turns = length / pitch + (taper_top ? 0 : 1);
r = outer_d / 2;
sides = r2sides(r);
h = max([for(p = profile) p.y]);
final = (turns - 1) * sides;
path = [for(i = [0 : sides * turns],
R = i < sides ? r + h - h * i / sides
: i > final && taper_top ? r + h * (i - final) / sides : r,
a = i * 360 / sides)
[R * sin(-a), R * cos(-a), pitch * a / 360]];
t = atan(pitch / sides / (r * cos(225 / sides)));
translate_z(center ? -length / 2 : 0) {
render() intersection() {
sweep(path, reverse([for(p = profile) [p.x, -p.y, 0]]), twist = t * sides * turns);
cylinder(d = outer_d + 5, h = length);
}
}
}
module male_metric_thread(d, pitch, length, taper_top = true, center = true) { //! Create male thread with metric profile
h = sqrt(3) / 2 * pitch;
minor_d = d - 5 * h / 4;
male_thread(pitch, minor_d, length, thread_profile((d - minor_d) / 2, pitch / 8, 60), taper_top, center);
}
module female_metric_thread(d, pitch, length, taper_top = true, center = true) { //! Create male thread with metric profile
h = sqrt(3) / 2 * pitch;
outer_d = d + 5 * h / 4;
male_thread(pitch, outer_d, length, thread_profile((outer_d - d) / 2, pitch / 8, 60), taper_top, center);
}
function metric_coarse_pitch(d) //! Convert metric diameter to pitch
= d == 1.6 ? 0.35 // M1.6
: [0.4, // M2
0.45,// M2.5
0.5, // M3
0.6, // M3.5
0.7, // M4
0,
0.8, // M5
0,
1.0, // M6
0,
0,
0,
1.25, // M8
0,
0,
0,
1.5, // M10
0,
0,
0,
1.75, // M12
][d * 2 - 4];
male_metric_thread(3, 0.5, 25);
translate([10, 0])
male_metric_thread(8, 1.25, 30);

View File

@ -21,6 +21,7 @@
//! D-connectors. Can be any number of ways, male or female, solder buckets, PCB mount or IDC, with or without pillars. //! D-connectors. Can be any number of ways, male or female, solder buckets, PCB mount or IDC, with or without pillars.
// //
include <../core.scad> include <../core.scad>
use <../utils/thread.scad>
d_pillar_color = grey90; d_pillar_color = grey90;
d_plug_shell_color = grey80; d_plug_shell_color = grey80;
@ -51,16 +52,21 @@ module d_pillar() { //! Draw a pillar for a D-connector
height = 4.5; height = 4.5;
screw = 2.5; screw = 2.5;
screw_length = 8; screw_length = 8;
color(d_pillar_color) {
translate_z(-screw_length)
cylinder(d = screw, h = screw_length + 1);
translate_z(-screw_length)
if(show_threads)
color(d_pillar_color * 0.7)
male_metric_thread(screw, metric_coarse_pitch(screw), screw_length, false, false);
else
color(d_pillar_color)
cylinder(d = screw, h = screw_length + 1);
color(d_pillar_color)
linear_extrude(height = height) linear_extrude(height = height)
difference() { difference() {
circle(r = rad, $fn = 6); circle(r = rad, $fn = 6);
circle(d = screw); circle(d = screw);
} }
}
} }
module d_plug(type, socket = false, pcb = false, idc = false) { //! Draw specified D plug, which can be IDC, PCB or plain solder bucket module d_plug(type, socket = false, pcb = false, idc = false) { //! Draw specified D plug, which can be IDC, PCB or plain solder bucket

View File

@ -21,6 +21,7 @@
//! Threaded pillars. Each end can be male or female. //! Threaded pillars. Each end can be male or female.
// //
include <../core.scad> include <../core.scad>
use <../utils/thread.scad>
function pillar_name(type) = type[1]; //! Name of part function pillar_name(type) = type[1]; //! Name of part
function pillar_thread(type) = type[2]; //! Thread diameter function pillar_thread(type) = type[2]; //! Thread diameter
@ -41,30 +42,43 @@ module pillar(type) { //! Draw specified pillar
sex = str(sex(pillar_bot_thread(type)),"/", sex(pillar_top_thread(type))); sex = str(sex(pillar_bot_thread(type)),"/", sex(pillar_top_thread(type)));
height = pillar_height(type); height = pillar_height(type);
thread_d = pillar_thread(type); thread_d = pillar_thread(type);
bot_thread_l = pillar_bot_thread(type);
top_thread_l = pillar_top_thread(type);
thread_colour = pillar_i_colour(type) * (show_threads ? 0.7 : 1);
vitamin(str("pillar(", type[0], "): Pillar ", pillar_name(type), " ", sex, " M", thread_d, "x", height)); vitamin(str("pillar(", type[0], "): Pillar ", pillar_name(type), " ", sex, " M", thread_d, "x", height));
color(thread_colour) {
if(bot_thread_l > 0)
translate_z(-bot_thread_l + eps)
if(show_threads)
male_metric_thread(thread_d, metric_coarse_pitch(thread_d), bot_thread_l, false, false);
else
cylinder(h = bot_thread_l, d = thread_d);
if(top_thread_l > 0)
translate_z(height + top_thread_l - eps)
if(show_threads)
vflip()
male_metric_thread(thread_d, metric_coarse_pitch(thread_d), top_thread_l, false, false);
else
cylinder(h = top_thread_l, d = thread_d);
}
color(pillar_i_colour(type)) { color(pillar_i_colour(type)) {
if(pillar_bot_thread(type) > 0)
translate_z(-pillar_bot_thread(type))
cylinder(h = pillar_bot_thread(type) + eps, d = pillar_thread(type));
if(pillar_top_thread(type) > 0)
translate_z(height - eps)
cylinder(h = pillar_top_thread(type) + eps, d = pillar_thread(type));
linear_extrude(height = height) linear_extrude(height = height)
difference() { difference() {
circle(d = pillar_id(type), $fn = fn(pillar_ifn(type))); circle(d = pillar_id(type), $fn = fn(pillar_ifn(type)));
circle(d = pillar_thread(type)); circle(d = thread_d);
} }
top = height + min(pillar_top_thread(type), 0); top = height + min(top_thread_l, 0);
bot = -min(pillar_bot_thread(type), 0); bot = -min(bot_thread_l, 0);
translate_z(bot) translate_z(bot)
cylinder(h = top - bot, d = pillar_thread(type) + eps); cylinder(h = top - bot, d = thread_d + eps);
} }
if(pillar_od(type) > pillar_id(type)) if(pillar_od(type) > pillar_id(type))
color(pillar_o_colour(type)) linear_extrude(height = height) color(pillar_o_colour(type)) linear_extrude(height = height)
difference() { difference() {

View File

@ -30,8 +30,8 @@
// d r r d d // d r r d d
// //
M2x16_brass_pillar = ["M2x16_brass_pillar", "nurled", 2, 16, 3.17, 3.17, 0, 0, brass, brass, 3,-3]; M2x16_brass_pillar = ["M2x16_brass_pillar", "nurled", 2, 16, 3.17, 3.17, 0, 0, brass, brass, 3,-3];
M3x13_hex_pillar = ["M3x13_hex_pillar", "hex", 3, 13, 5/cos(30), 5/cos(30), 6, 6, "silver", "silver", -6, 6]; M3x13_hex_pillar = ["M3x13_hex_pillar", "hex", 3, 13, 5/cos(30), 5/cos(30), 6, 6, "silver", silver, -6, 6];
M3x20_hex_pillar = ["M3x20_hex_pillar", "hex", 3, 20, 5/cos(30), 5/cos(30), 6, 6, "silver", "silver", -8, 8]; M3x20_hex_pillar = ["M3x20_hex_pillar", "hex", 3, 20, 5/cos(30), 5/cos(30), 6, 6, "silver", silver, -8, 8];
M3x20_nylon_pillar = ["M3x20_nylon_pillar", "nylon", 3, 20, 8, 5/cos(30), 0, 6, "white", brass, -6, 6]; M3x20_nylon_pillar = ["M3x20_nylon_pillar", "nylon", 3, 20, 8, 5/cos(30), 0, 6, "white", brass, -6, 6];
M4x17_nylon_pillar = ["M4x17_nylon_pillar", "nylon", 4, 20, 8, 5/cos(30), 0, 6, "white", brass, -6, 6]; M4x17_nylon_pillar = ["M4x17_nylon_pillar", "nylon", 4, 20, 8, 5/cos(30), 0, 6, "white", brass, -6, 6];
M3x20_nylon_hex_pillar = ["M3x20_nylon_hex_pillar", "hex nylon", 3, 20, 8/cos(30), 8/cos(30), 6, 6, grey20, grey20, -6, 6]; M3x20_nylon_hex_pillar = ["M3x20_nylon_hex_pillar", "hex nylon", 3, 20, 8/cos(30), 8/cos(30), 6, 6, grey20, grey20, -6, 6];

View File

@ -21,6 +21,7 @@
//! Steel rods and studding with chamfered ends. //! Steel rods and studding with chamfered ends.
// //
include <../core.scad> include <../core.scad>
use <../utils/thread.scad>
rod_colour = grey80; rod_colour = grey80;
studding_colour = grey70; studding_colour = grey70;
@ -41,10 +42,14 @@ module studding(d , l) { //! Draw a threaded rod with specified length and diame
vitamin(str("studding(", d, ", ", l,"): Threaded rod M", d, " x ", l, "mm")); vitamin(str("studding(", d, ", ", l,"): Threaded rod M", d, " x ", l, "mm"));
chamfer = d / 20; chamfer = d / 20;
pitch = metric_coarse_pitch(d);
color(studding_colour) color(studding_colour)
hull() { if(show_threads && pitch)
cylinder(d = d, h = l - 2 * chamfer, center = true); male_metric_thread(d, pitch, l);
else
hull() {
cylinder(d = d, h = l - 2 * chamfer, center = true);
cylinder(d = d - 2 * chamfer, h = l, center = true); cylinder(d = d - 2 * chamfer, h = l, center = true);
} }
} }

View File

@ -24,6 +24,7 @@ include <../core.scad>
use <washer.scad> use <washer.scad>
use <../utils/rounded_cylinder.scad> use <../utils/rounded_cylinder.scad>
use <../utils/thread.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_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_radius(type) = type[3] / 2; //! Nominal radius
@ -69,24 +70,33 @@ module screw(type, length, hob_point = 0, nylon = false) { //! Draw specified sc
socket_depth= screw_socket_depth(type); socket_depth= screw_socket_depth(type);
socket_rad = socket_af / cos(30) / 2; socket_rad = socket_af / cos(30) / 2;
max_thread = screw_max_thread(type); max_thread = screw_max_thread(type);
thread = max_thread ? min(length, max_thread) : length; thread = max_thread ? length >= max_thread + 5 ? max_thread
: length
: length;
shank = length - thread; shank = length - thread;
colour = nylon || head_type == hs_grub ? grey40 : grey80; colour = nylon || head_type == hs_grub ? grey40 : grey80;
module shaft(headless = 0) { module shaft(headless = 0) {
point = screw_nut(type) ? 0 : 3 * rad; point = screw_nut(type) ? 0 : 3 * rad;
color(colour * 0.9 ) d = 2 * screw_radius(type);
rotate_extrude() { pitch = metric_coarse_pitch(d);
translate([0, -length + point]) l = length - shank;
square([rad, length - headless - point]); if(show_threads && !point && pitch)
translate_z(-l - shank)
color(colour * 0.7)
male_metric_thread(d, pitch, l, !!headless, false);
else
color(colour * 0.9)
rotate_extrude() {
translate([0, -length + point])
square([rad, length - headless - point]);
if(point) if(point)
polygon([ polygon([
[0, -length], [0, point - length], [rad - 0.1, point - length] [0, -length], [0, point - length], [rad - 0.1, point - length]
]); ]);
} }
if(shank >= 5) if(shank - headless > 0)
color(colour) color(colour)
translate_z(-shank) translate_z(-shank)
cylinder(r = rad + eps, h = shank - headless); cylinder(r = rad + eps, h = shank - headless);
@ -102,6 +112,7 @@ module screw(type, length, hob_point = 0, nylon = false) { //! Draw specified sc
linear_extrude(height = socket_depth) linear_extrude(height = socket_depth)
difference() { difference() {
circle(head_rad); circle(head_rad);
circle(socket_rad, $fn = 6); circle(socket_rad, $fn = 6);
} }
@ -110,14 +121,23 @@ module screw(type, length, hob_point = 0, nylon = false) { //! Draw specified sc
} }
if(head_type == hs_grub) { if(head_type == hs_grub) {
color(colour) { color(colour) {
translate_z(-socket_depth) if(!show_threads) {
linear_extrude(height = socket_depth) translate_z(-socket_depth)
difference() { linear_extrude(height = socket_depth)
circle(r = rad); difference() {
circle(socket_rad, $fn = 6); circle(r = rad);
}
shaft(socket_depth); circle(socket_rad, $fn = 6);
}
shaft(socket_depth);
}
else
render() difference() {
shaft(socket_depth);
cylinder(r = socket_rad, $fn = 6, h = 2 * socket_depth, center = true);
}
} }
} }
if(head_type == hs_hex) { if(head_type == hs_hex) {