Added male screw threads.
@ -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
|
||||
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_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
|
||||
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];
|
||||
grey80 = [0.8, 0.8, 0.8];
|
||||
grey90 = [0.9, 0.9, 0.9];
|
||||
brass = "gold";
|
||||
brass = [255/255, 215/255, 0/255];
|
||||
silver = [0.75, 0.75, 0.75];
|
||||
|
||||
/*
|
||||
* Enums
|
||||
|
1
lib.scad
@ -90,3 +90,4 @@ use <utils/layout.scad>
|
||||
use <utils/round.scad>
|
||||
use <utils/offset.scad>
|
||||
use <utils/sector.scad>
|
||||
use <utils/thread.scad>
|
||||
|
@ -154,7 +154,7 @@ def views(target, do_assemblies = None):
|
||||
f.write("use <%s/%s>\n" % (dir, filename))
|
||||
f.write("%s();\n" % module);
|
||||
#
|
||||
# Run openscad on th created file
|
||||
# Run openscad on the created file
|
||||
#
|
||||
dname = deps_name(deps_dir, filename)
|
||||
for explode in [0, 1]:
|
||||
@ -167,7 +167,7 @@ def views(target, do_assemblies = None):
|
||||
if changed:
|
||||
print(changed)
|
||||
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)
|
||||
do_cmd(["magick", tmp_name, "-trim", "-resize", "1004x1004", "-bordercolor", background, "-border", "10", tmp_name])
|
||||
update_image(tmp_name, png_name)
|
||||
|
@ -35,4 +35,5 @@ module d_connectors()
|
||||
}
|
||||
|
||||
if($preview)
|
||||
d_connectors();
|
||||
let($show_threads = true)
|
||||
d_connectors();
|
||||
|
@ -26,4 +26,5 @@ module pillars()
|
||||
pillar(pillars[$i]);
|
||||
|
||||
if($preview)
|
||||
pillars();
|
||||
let($show_threads = true)
|
||||
pillars();
|
||||
|
Before Width: | Height: | Size: 114 KiB After Width: | Height: | Size: 118 KiB |
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 94 KiB |
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 90 KiB |
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 99 KiB |
@ -33,4 +33,5 @@ module rods()
|
||||
}
|
||||
|
||||
if($preview)
|
||||
rods();
|
||||
let($show_threads = true)
|
||||
rods();
|
||||
|
@ -34,4 +34,5 @@ for(y = [0 : len(screw_lists) -1])
|
||||
}
|
||||
|
||||
if($preview)
|
||||
screws();
|
||||
let($show_threads = true)
|
||||
screws();
|
||||
|
@ -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
|
||||
if(h)
|
||||
linear_extrude(height = h, center = center) // 3D
|
||||
linear_extrude(height = h, center = center, convexity = 2) // 3D
|
||||
children();
|
||||
else
|
||||
children(); // 2D
|
||||
|
114
utils/thread.scad
Normal 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);
|
@ -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.
|
||||
//
|
||||
include <../core.scad>
|
||||
use <../utils/thread.scad>
|
||||
|
||||
d_pillar_color = grey90;
|
||||
d_plug_shell_color = grey80;
|
||||
@ -51,16 +52,21 @@ module d_pillar() { //! Draw a pillar for a D-connector
|
||||
height = 4.5;
|
||||
screw = 2.5;
|
||||
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)
|
||||
difference() {
|
||||
circle(r = rad, $fn = 6);
|
||||
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
|
||||
|
@ -21,6 +21,7 @@
|
||||
//! Threaded pillars. Each end can be male or female.
|
||||
//
|
||||
include <../core.scad>
|
||||
use <../utils/thread.scad>
|
||||
|
||||
function pillar_name(type) = type[1]; //! Name of part
|
||||
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)));
|
||||
height = pillar_height(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));
|
||||
|
||||
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)) {
|
||||
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)
|
||||
difference() {
|
||||
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);
|
||||
bot = -min(pillar_bot_thread(type), 0);
|
||||
top = height + min(top_thread_l, 0);
|
||||
bot = -min(bot_thread_l, 0);
|
||||
|
||||
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))
|
||||
color(pillar_o_colour(type)) linear_extrude(height = height)
|
||||
difference() {
|
||||
|
@ -30,8 +30,8 @@
|
||||
// d r r d d
|
||||
//
|
||||
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];
|
||||
M3x20_hex_pillar = ["M3x20_hex_pillar", "hex", 3, 20, 5/cos(30), 5/cos(30), 6, 6, "silver", "silver", -8, 8];
|
||||
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_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];
|
||||
M3x20_nylon_hex_pillar = ["M3x20_nylon_hex_pillar", "hex nylon", 3, 20, 8/cos(30), 8/cos(30), 6, 6, grey20, grey20, -6, 6];
|
||||
|
@ -21,6 +21,7 @@
|
||||
//! Steel rods and studding with chamfered ends.
|
||||
//
|
||||
include <../core.scad>
|
||||
use <../utils/thread.scad>
|
||||
|
||||
rod_colour = grey80;
|
||||
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"));
|
||||
|
||||
chamfer = d / 20;
|
||||
pitch = metric_coarse_pitch(d);
|
||||
color(studding_colour)
|
||||
hull() {
|
||||
cylinder(d = d, h = l - 2 * chamfer, center = true);
|
||||
if(show_threads && pitch)
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ include <../core.scad>
|
||||
|
||||
use <washer.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_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_rad = socket_af / cos(30) / 2;
|
||||
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;
|
||||
colour = nylon || head_type == hs_grub ? grey40 : grey80;
|
||||
|
||||
|
||||
module shaft(headless = 0) {
|
||||
point = screw_nut(type) ? 0 : 3 * rad;
|
||||
color(colour * 0.9 )
|
||||
rotate_extrude() {
|
||||
translate([0, -length + point])
|
||||
square([rad, length - headless - point]);
|
||||
d = 2 * screw_radius(type);
|
||||
pitch = metric_coarse_pitch(d);
|
||||
l = length - shank;
|
||||
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)
|
||||
polygon([
|
||||
[0, -length], [0, point - length], [rad - 0.1, point - length]
|
||||
]);
|
||||
}
|
||||
if(shank >= 5)
|
||||
if(point)
|
||||
polygon([
|
||||
[0, -length], [0, point - length], [rad - 0.1, point - length]
|
||||
]);
|
||||
}
|
||||
if(shank - headless > 0)
|
||||
color(colour)
|
||||
translate_z(-shank)
|
||||
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)
|
||||
difference() {
|
||||
circle(head_rad);
|
||||
|
||||
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) {
|
||||
color(colour) {
|
||||
translate_z(-socket_depth)
|
||||
linear_extrude(height = socket_depth)
|
||||
difference() {
|
||||
circle(r = rad);
|
||||
circle(socket_rad, $fn = 6);
|
||||
}
|
||||
if(!show_threads) {
|
||||
translate_z(-socket_depth)
|
||||
linear_extrude(height = socket_depth)
|
||||
difference() {
|
||||
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) {
|
||||
|