Compare commits
61 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
73d814d2fe | ||
|
fa658d9eaa | ||
|
6d3f54b7a5 | ||
|
157ff60e19 | ||
|
cbd3cf29af | ||
|
bf618bb482 | ||
|
1e6f0a5c4d | ||
|
53c3cdb598 | ||
|
f4857f6862 | ||
|
1acc8d01c0 | ||
|
344e8d1583 | ||
|
dd757a1461 | ||
|
b4f8892b1a | ||
|
4b033d9945 | ||
|
d5a711f4cc | ||
|
42b76ab8d3 | ||
|
f18044915d | ||
|
17b12c7f31 | ||
|
18ff4c6d46 | ||
|
2eecce819c | ||
|
f7d81738bb | ||
|
6d44124bab | ||
|
9bb9f09dca | ||
|
773a53829f | ||
|
07766d8cf0 | ||
|
ceac5cdb27 | ||
|
c5b35daeac | ||
|
ffb4512523 | ||
|
35ffbad74c | ||
|
fb685a0f42 | ||
|
5d42b2e1ab | ||
|
2fe815d1bd | ||
|
5c577cccd0 | ||
|
1dbfafd366 | ||
|
68b3dfb098 | ||
|
25dceee20a | ||
|
d70ddf5359 | ||
|
70b60522ce | ||
|
ecba7eaea4 | ||
|
f751dd9a73 | ||
|
3f359f6839 | ||
|
3e5947c161 | ||
|
66dc430541 | ||
|
4dc83d62cb | ||
|
ebbec3c903 | ||
|
9944aab73e | ||
|
eb9bcf0ada | ||
|
ff5e8c0372 | ||
|
17ebf36e27 | ||
|
e38d9abfa0 | ||
|
fc7fd5482e | ||
|
cee1202fd9 | ||
|
6e342441c6 | ||
|
072c38f955 | ||
|
b342549d74 | ||
|
2b83a15e5d | ||
|
ab81c6538c | ||
|
27b0a442e4 | ||
|
38acef9e27 | ||
|
5415beb80d | ||
|
040985c0db |
@@ -35,8 +35,8 @@ extrusion_width = is_undef($extrusion_width) ? 0.5 : $extrusion_width; // fil
|
||||
nozzle = is_undef($nozzle) ? 0.45 : $nozzle; // 3D printer nozzle
|
||||
cnc_bit_r = is_undef($cnc_bit_r) ? 1.2 : $cnc_bit_r; // minimum tool radius when milling 2D objects
|
||||
pp1_colour = is_undef($pp1_colour) ? [0, 146/255, 0] : $pp1_colour; // printed part colour 1, RepRap logo colour
|
||||
pp2_colour = is_undef($pp2_colour) ? "red" : $pp2_colour; // printed part colour 2
|
||||
pp3_colour = is_undef($pp3_colour) ? "blue" : $pp3_colour; // printed part colour 3
|
||||
pp2_colour = is_undef($pp2_colour) ? "Crimson" : $pp2_colour; // printed part colour 2
|
||||
pp3_colour = is_undef($pp3_colour) ? "SteelBlue" : $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
|
||||
|
BIN
libtest.png
Before Width: | Height: | Size: 829 KiB After Width: | Height: | Size: 854 KiB |
13
libtest.scad
@@ -52,6 +52,7 @@ use <tests/circlips.scad>
|
||||
use <tests/components.scad>
|
||||
use <tests/d_connectors.scad>
|
||||
use <tests/displays.scad>
|
||||
use <tests/drag_chain.scad>
|
||||
use <tests/extrusions.scad>
|
||||
use <tests/extrusion_brackets.scad>
|
||||
use <tests/fans.scad>
|
||||
@@ -77,6 +78,7 @@ use <tests/opengrab.scad>
|
||||
use <tests/panel_meters.scad>
|
||||
use <tests/PCBs.scad>
|
||||
use <tests/pillars.scad>
|
||||
use <tests/press_fit.scad>
|
||||
use <tests/PSUs.scad>
|
||||
use <tests/pulleys.scad>
|
||||
use <tests/rails.scad>
|
||||
@@ -136,9 +138,12 @@ cable_grommets_y = 0;
|
||||
translate([x5, cable_grommets_y])
|
||||
cable_grommets();
|
||||
|
||||
translate([x5 + 80, cable_grommets_y])
|
||||
translate([x5 + 50, cable_grommets_y])
|
||||
ribbon_clamps();
|
||||
|
||||
translate([x5 + 95, cable_grommets_y])
|
||||
press_fits();
|
||||
|
||||
translate([x5, cable_grommets_y + 60])
|
||||
fixing_blocks();
|
||||
|
||||
@@ -417,12 +422,16 @@ translate([x4 + 200, belts_y + 58]) {
|
||||
|
||||
translate([0, 60])
|
||||
opengrab_test();
|
||||
|
||||
}
|
||||
|
||||
translate([x4 + 175, belts_y, -20])
|
||||
drag_chains();
|
||||
|
||||
translate([x4, rails_y + 130])
|
||||
rails();
|
||||
|
||||
translate([800, fans_y + 50])
|
||||
translate([770, fans_y + 50])
|
||||
cable_strips();
|
||||
|
||||
translate([x4, kp_pillow_blocks_y])
|
||||
|
@@ -121,11 +121,12 @@ module grill(width, height, r = 1000, poly = false, h = 0) { //! A staggered arr
|
||||
|
||||
module box_corner_profile_2D(type) { //! The 2D shape of the corner profile.
|
||||
t = box_sheet_slot(type);
|
||||
inset = box_corner_gap(type) + box_profile_overlap(type);
|
||||
difference() {
|
||||
union() {
|
||||
quadrant(box_hole_inset(type) + box_boss_r(type), box_boss_r(type)); // inside corner
|
||||
|
||||
translate([box_corner_gap(type) + box_profile_overlap(type), box_corner_gap(type) + box_profile_overlap(type)])
|
||||
translate([inset, inset])
|
||||
rotate(180)
|
||||
quadrant(box_profile_overlap(type) + box_corner_rad(type), box_corner_rad(type)); // outside corner
|
||||
}
|
||||
@@ -212,33 +213,39 @@ module box_bezel(type, bottom) { //! Generates top and bottom bezel STLs
|
||||
feet = bottom && box_feet(type);
|
||||
t = box_sheet_slot(type);
|
||||
outset = box_outset(type);
|
||||
inset = box_inset(type);
|
||||
inner_r = box_sheet_r(type);
|
||||
foot_height = box_corner_gap(type) + sheet_thickness(box_base_sheet(type)) + washer_thickness(box_washer(type)) + screw_head_height(box_screw(type)) + box_profile_overlap(type) + 2;
|
||||
cgap = box_corner_gap(type);
|
||||
foot_height = cgap + sheet_thickness(box_base_sheet(type)) + washer_thickness(box_washer(type)) + screw_head_height(box_screw(type)) + box_profile_overlap(type) + 2;
|
||||
foot_length = box_corner_rad(type) * 2;
|
||||
height = box_bezel_height(type, bottom);
|
||||
foot_extension = foot_height - height;
|
||||
|
||||
difference() {
|
||||
w = box_width(type);
|
||||
d = box_depth(type);
|
||||
translate_z(-box_profile_overlap(type)) difference() {
|
||||
rounded_rectangle([box_width(type) + 2 * outset, box_depth(type) + 2 * outset, feet ? foot_height : height], box_corner_rad(type), false);
|
||||
tw = w + 2 * outset;
|
||||
td = d + 2 * outset;
|
||||
rounded_rectangle([tw, td, feet ? foot_height : height], box_corner_rad(type), false);
|
||||
//
|
||||
// Remove edges between the feet
|
||||
//
|
||||
if(feet)
|
||||
hull() {
|
||||
translate_z(height + 0.5)
|
||||
cube([box_width(type) - 2 * foot_length, box_depth(type) + 2 * outset + 1, 1], center = true);
|
||||
cube([w - 2 * foot_length, td + 1, 1], center = true);
|
||||
|
||||
translate_z(foot_height + 1)
|
||||
cube([box_width(type) - 2 * (foot_length - foot_extension), box_depth(type) + 2 * outset + 1, 1], center = true);
|
||||
cube([w - 2 * (foot_length - foot_extension), td + 1, 1], center = true);
|
||||
}
|
||||
if(feet)
|
||||
hull() {
|
||||
translate_z(height + 0.5)
|
||||
cube([box_width(type) + 2 * outset + 1, box_depth(type) - 2 * foot_length, 1], center = true);
|
||||
cube([tw + 1, d - 2 * foot_length, 1], center = true);
|
||||
|
||||
translate_z(foot_height + 1)
|
||||
cube([box_width(type) + 2 * outset + 1, box_depth(type) - 2 * (foot_length - foot_extension), 1], center = true);
|
||||
cube([tw + 1, d - 2 * (foot_length - foot_extension), 1], center = true);
|
||||
}
|
||||
}
|
||||
//
|
||||
@@ -247,28 +254,28 @@ module box_bezel(type, bottom) { //! Generates top and bottom bezel STLs
|
||||
translate_z(-box_profile_overlap(type))
|
||||
linear_extrude(2 * box_profile_overlap(type), center = true)
|
||||
for(i = [-1, 1]) {
|
||||
translate([i * (box_width(type) / 2 + t / 2 - sheet_slot_clearance / 2), 0])
|
||||
square([t, box_depth(type) - 2 * box_corner_gap(type)], center = true);
|
||||
translate([i * (w + t - sheet_slot_clearance) / 2, 0])
|
||||
square([t, d - 2 * cgap], center = true);
|
||||
|
||||
translate([0, i * (box_depth(type) / 2 + t / 2 - sheet_slot_clearance / 2)])
|
||||
square([box_width(type) - 2 * box_corner_gap(type), t], center = true);
|
||||
translate([0, i * (d + t - sheet_slot_clearance) / 2])
|
||||
square([w - 2 * cgap, t], center = true);
|
||||
}
|
||||
//
|
||||
// recess for top / bottom panel
|
||||
//
|
||||
translate_z(box_corner_gap(type))
|
||||
rounded_rectangle([box_width(type) + bezel_clearance, box_depth(type) + bezel_clearance, height], inner_r + bezel_clearance / 2, false);
|
||||
translate_z(cgap)
|
||||
rounded_rectangle([w + bezel_clearance, d + bezel_clearance, height], inner_r + bezel_clearance / 2, false);
|
||||
//
|
||||
// leave plastic over the corner profiles
|
||||
//
|
||||
translate_z(-box_profile_overlap(type) - 1)
|
||||
linear_extrude(box_profile_overlap(type) + box_corner_gap(type) + 2)
|
||||
linear_extrude(box_profile_overlap(type) + cgap + 2)
|
||||
union() {
|
||||
difference() {
|
||||
square([box_width(type) - 2 * box_inset(type),
|
||||
box_depth(type) - 2 * box_inset(type)], center = true);
|
||||
square([w - 2 * inset,
|
||||
d - 2 * inset], center = true);
|
||||
|
||||
box_corner_quadrants(type, box_width(type), box_depth(type));
|
||||
box_corner_quadrants(type, w, d);
|
||||
}
|
||||
box_screw_hole_positions(type)
|
||||
poly_circle(screw_clearance_radius(box_screw(type)));
|
||||
@@ -291,7 +298,9 @@ module box_bezel_section(type, bottom, rows, cols, x, y) { //! Generates interlo
|
||||
dw = bw - 2 * dowel_wall;
|
||||
dh = box_bezel_height(type, bottom) - dowel_h_wall;
|
||||
|
||||
dh2 = box_profile_overlap(type) + box_corner_gap(type) - dowel_h_wall;
|
||||
profile_overlap = box_profile_overlap(type);
|
||||
|
||||
dh2 = profile_overlap + box_corner_gap(type) - dowel_h_wall;
|
||||
|
||||
end_clearance = 0.5;
|
||||
module male() {
|
||||
@@ -299,14 +308,14 @@ module box_bezel_section(type, bottom, rows, cols, x, y) { //! Generates interlo
|
||||
linear_extrude(dowel_length - 2 * end_clearance, center = true)
|
||||
difference() {
|
||||
union() {
|
||||
h = dh - layer_height;
|
||||
h1 = dh - layer_height;
|
||||
h2 = dh2 - layer_height;
|
||||
hull() {
|
||||
translate([bw / 2, h / 2])
|
||||
square([dw - 1, h], center = true);
|
||||
translate([bw / 2, h1 / 2])
|
||||
square([dw - 1, h1], center = true);
|
||||
|
||||
translate([bw / 2, (h - 1) / 2])
|
||||
square([dw, h - 1], center = true);
|
||||
translate([bw / 2, (h1 - 1) / 2])
|
||||
square([dw, h1 - 1], center = true);
|
||||
}
|
||||
|
||||
hull() {
|
||||
@@ -318,7 +327,7 @@ module box_bezel_section(type, bottom, rows, cols, x, y) { //! Generates interlo
|
||||
}
|
||||
}
|
||||
translate([bw2 / 2, 0])
|
||||
square([box_sheet_slot(type), 2 * box_profile_overlap(type)], center = true);
|
||||
square([box_sheet_slot(type), 2 * profile_overlap], center = true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -359,7 +368,7 @@ module box_bezel_section(type, bottom, rows, cols, x, y) { //! Generates interlo
|
||||
render() difference() {
|
||||
union() {
|
||||
clip(xmin = 0, xmax = w, ymin = 0, ymax = h)
|
||||
translate([tw / 2 - x * w, th / 2 - y * h, box_profile_overlap(type)])
|
||||
translate([tw / 2 - x * w, th / 2 - y * h, profile_overlap])
|
||||
box_bezel(type, bottom);
|
||||
|
||||
if(x < cols - 1 && y == 0)
|
||||
@@ -419,10 +428,14 @@ module box_bezel_section(type, bottom, rows, cols, x, y) { //! Generates interlo
|
||||
}
|
||||
}
|
||||
|
||||
module box_screw_hole_positions(type)
|
||||
module box_screw_hole_positions(type) {
|
||||
inset = box_hole_inset(type);
|
||||
w = box_width(type) / 2 - inset;
|
||||
d = box_depth(type) / 2 - inset;
|
||||
for(x = [-1, 1], y = [-1, 1])
|
||||
translate([x * (box_width(type) / 2 - box_hole_inset(type)), y * (box_depth(type) / 2 - box_hole_inset(type))])
|
||||
translate([x * w, y * d])
|
||||
children();
|
||||
}
|
||||
|
||||
module box_base_blank(type) { //! Generates a 2D template for the base sheet
|
||||
dxf("box_base");
|
||||
|
321
printed/drag_chain.scad
Normal file
@@ -0,0 +1,321 @@
|
||||
//
|
||||
// NopSCADlib Copyright Chris Palmer 2020
|
||||
// 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/>.
|
||||
//
|
||||
|
||||
//
|
||||
//! Parametric cable drag chain to limit the bend radius of a cable run.
|
||||
//!
|
||||
//! Each link has a maximum bend angle of 45°, so the mininium radius is proportional to the link length.
|
||||
//!
|
||||
//! The travel property is how far it can move in each direction, i.e. half the maximum travel if the chain is mounted in the middle of the travel.
|
||||
//!
|
||||
//! The ends can have screw lugs with four screw positions to choose from, specified by a list of two arrays of four bools.
|
||||
//! If none are enabled then a child object is expected to customise the end and this gets unioned with the blank end.
|
||||
//! If both ends are customised then two children are expected.
|
||||
//! Each child is called twice, once with ```$fasteners``` set to 0 to augment the STL and again with ```$fasteners``` set to 1 to add
|
||||
//! to the assembly, for example to add inserts.
|
||||
//
|
||||
|
||||
include <../core.scad>
|
||||
use <../utils/horiholes.scad>
|
||||
use <../utils/maths.scad>
|
||||
|
||||
clearance = 0.1;
|
||||
|
||||
function drag_chain_name(type) = type[0]; //! The name to allow more than one in a project
|
||||
function drag_chain_size(type) = type[1]; //! The internal size and link length
|
||||
function drag_chain_travel(type) = type[2]; //! X travel
|
||||
function drag_chain_wall(type) = type[3]; //! Side wall thickness
|
||||
function drag_chain_bwall(type) = type[4]; //! Bottom wall
|
||||
function drag_chain_twall(type) = type[5]; //! Top wall
|
||||
function drag_chain_screw(type) = type[6]; //! Mounting screw for the ends
|
||||
function drag_chain_screw_lists(type) = type[7]; //! Two lists of four bools to say which screws positions are used
|
||||
|
||||
function drag_chain_clearance() = clearance; //! Clearance around joints.
|
||||
|
||||
function drag_chain_radius(type) = //! The bend radius at the pivot centres
|
||||
let(s = drag_chain_size(type))
|
||||
s.x / 2 / sin(360 / 16);
|
||||
|
||||
function drag_chain_z(type) = //! Outside dimension of a 180 bend
|
||||
let(os = drag_chain_outer_size(type), s = drag_chain_size(type))
|
||||
2 * drag_chain_radius(type) + os.z;
|
||||
|
||||
function drag_chain(name, size, travel, wall = 1.6, bwall = 1.5, twall = 1.5, screw = M2_cap_screw, screw_lists = [[1,0,0,1],[1,0,0,1]]) = //! Constructor
|
||||
[name, size, travel, wall, bwall, twall, screw, screw_lists];
|
||||
|
||||
function drag_chain_outer_size(type) = //! Link outer dimensions
|
||||
let(s = drag_chain_size(type), z = s.z + drag_chain_bwall(type) + drag_chain_twall(type))
|
||||
[s.x + z, s.y + 4 * drag_chain_wall(type) + 2 * clearance, z];
|
||||
|
||||
function screw_lug_radius(screw) = //! Radius of a screw lug
|
||||
corrected_radius(screw_clearance_radius(screw)) + 3.1 * extrusion_width;
|
||||
|
||||
module screw_lug(screw, h = 0) //! Create a D shaped lug for a screw
|
||||
extrude_if(h, center = false)
|
||||
difference() {
|
||||
r = screw_lug_radius(screw);
|
||||
hull() {
|
||||
circle4n(r);
|
||||
|
||||
translate([-r, -r])
|
||||
square([2 * r, eps]);
|
||||
}
|
||||
poly_circle(screw_clearance_radius(screw));
|
||||
}
|
||||
|
||||
function bool2int(b) = b ? 1 : 0;
|
||||
|
||||
module drag_chain_screw_positions(type, end) { //! Place children at the screw positions, end = 0 for the start, 1 for the end
|
||||
r = screw_lug_radius(drag_chain_screw(type));
|
||||
s = drag_chain_size(type);
|
||||
os = drag_chain_outer_size(type);
|
||||
R = os.z / 2;
|
||||
x0 = end ? R + norm([drag_chain_cam_x(type), R - drag_chain_twall(type)]) + clearance + r : r;
|
||||
x1 = end ? os.x - r : os.x - 2 * R - clearance - r;
|
||||
for(i = [0 : 3], x = [x0, x1, x0, x1][i], y = [-1, -1, 1, 1][i])
|
||||
if(drag_chain_screw_lists(type)[bool2int(end)][i])
|
||||
translate([x, y * (s.y / 2 + r)])
|
||||
let($a = [180, 0, 180, 0][i])
|
||||
children();
|
||||
}
|
||||
|
||||
function drag_chain_cam_x(type) = // how far the cam sticks out
|
||||
let(s = drag_chain_size(type),
|
||||
r = drag_chain_outer_size(type).z / 2,
|
||||
wall = drag_chain_wall(type),
|
||||
cam_r = s.x - 2 * clearance - wall - r, // inner_x_normal - clearance - r
|
||||
twall = drag_chain_twall(type)
|
||||
) min(sqrt(max(sqr(cam_r) - sqr(r - twall), 0)), r);
|
||||
|
||||
module drag_chain_link(type, start = false, end = false, check_kids = true) { //! One link of the chain, special case for start and end
|
||||
stl(str(drag_chain_name(type), "_drag_chain_link", start ? "_start" : end ? "_end" : ""));
|
||||
|
||||
s = drag_chain_size(type);
|
||||
wall = drag_chain_wall(type);
|
||||
bwall = drag_chain_bwall(type);
|
||||
twall = drag_chain_twall(type);
|
||||
os = drag_chain_outer_size(type);
|
||||
r = os.z / 2;
|
||||
pin_r = r / 2;
|
||||
|
||||
socket_x = r;
|
||||
pin_x = socket_x + s.x;
|
||||
|
||||
outer_normal_x = pin_x - r - clearance; // s.x - clearance
|
||||
outer_end_x = end ? os.x : outer_normal_x;
|
||||
|
||||
inner_x = start ? 0 : outer_normal_x - wall; // s.x - clearance - wall
|
||||
|
||||
roof_x_normal = 2 * r - twall;
|
||||
roof_x = start ? 0 : roof_x_normal;
|
||||
|
||||
floor_x = start ? 0 : 2 * r;
|
||||
cam_x = drag_chain_cam_x(type);
|
||||
assert(r + norm([drag_chain_cam_x(type), r - drag_chain_twall(type)]) + clearance <= inner_x || start, "Link must be longer");
|
||||
|
||||
difference() {
|
||||
union() {
|
||||
for(side = [-1, 1])
|
||||
rotate([90, 0, 0]) {
|
||||
// Outer cheeks
|
||||
translate_z(side * (os.y / 2 - wall / 2))
|
||||
linear_extrude(wall, center = true)
|
||||
difference() {
|
||||
hull() {
|
||||
if(start)
|
||||
square([eps, os.z]);
|
||||
else
|
||||
translate([socket_x, r])
|
||||
rotate(180)
|
||||
teardrop(r = r, h = 0);
|
||||
|
||||
translate([outer_end_x - eps, 0])
|
||||
square([eps, os.z]);
|
||||
}
|
||||
if(!start)
|
||||
translate([socket_x, r])
|
||||
horihole(pin_r, r);
|
||||
}
|
||||
// Inner cheeks
|
||||
translate_z(side * (s.y / 2 + wall / 2))
|
||||
linear_extrude(wall, center = true)
|
||||
difference() {
|
||||
union() {
|
||||
hull() {
|
||||
if(!end) {
|
||||
translate([pin_x, r])
|
||||
rotate(180)
|
||||
teardrop(r = r, h = 0);
|
||||
|
||||
translate([pin_x, twall])
|
||||
square([cam_x, eps]);
|
||||
}
|
||||
else
|
||||
translate([os.x - eps, 0])
|
||||
square([eps, os.z]);
|
||||
|
||||
translate([inner_x, 0])
|
||||
square([eps, os.z]);
|
||||
}
|
||||
}
|
||||
// Cutout for top wall
|
||||
if(!end)
|
||||
intersection() {
|
||||
translate([pin_x - r, 0])
|
||||
square([3 * r, twall]); // When straight
|
||||
|
||||
translate([pin_x, r])
|
||||
rotate(-45)
|
||||
translate([-r + roof_x_normal, -r - twall]) // When bent fully
|
||||
square(os.z);
|
||||
}
|
||||
}
|
||||
// Pin
|
||||
if(!end)
|
||||
translate([pin_x, r, side * (s.y / 2 + wall + clearance)])
|
||||
horicylinder(r = pin_r, z = r, h = 2 * wall);
|
||||
|
||||
// Cheek joint
|
||||
translate([inner_x, 0, side * (s.y / 2 + wall) - 0.5])
|
||||
cube([outer_end_x - inner_x, os.z, 1]);
|
||||
}
|
||||
|
||||
// Roof, actually the floor when printed
|
||||
roof_end = end ? s.x + 2 * r : s.x + r - twall - clearance;
|
||||
translate([roof_x, -s.y / 2 - 0.5])
|
||||
cube([roof_end - roof_x , s.y + 1, twall]);
|
||||
|
||||
translate([roof_x, -os.y / 2 + 0.5])
|
||||
cube([s.x - clearance - roof_x, os.y - 1, twall]);
|
||||
|
||||
// Floor, actually the roof when printed
|
||||
floor_end = end ? s.x + 2 * r : s.x + r;
|
||||
translate([floor_x, -s.y / 2 - wall, os.z - bwall])
|
||||
cube([floor_end - floor_x, s.y + 2 * wall, bwall]);
|
||||
|
||||
translate([floor_x, -os.y / 2 + 0.5, os.z - bwall])
|
||||
cube([s.x - floor_x - clearance, os.y -1, bwall]);
|
||||
|
||||
if(start || end) {
|
||||
drag_chain_screw_positions(type, end)
|
||||
rotate($a)
|
||||
screw_lug(drag_chain_screw(type), os.z);
|
||||
|
||||
if(check_kids) {
|
||||
custom = drag_chain_screw_lists(type)[bool2int(end)] == [0, 0, 0, 0];
|
||||
assert($children == bool2int(custom), str("wrong number of children for ", end ? "end" : "start", " STL customisation: ", $children));
|
||||
}
|
||||
children();
|
||||
}
|
||||
}
|
||||
if(start || end)
|
||||
translate_z(-eps)
|
||||
drag_chain_screw_positions(type, end)
|
||||
rotate($a)
|
||||
poly_cylinder(r = screw_clearance_radius(drag_chain_screw(type)), h = os.z + 2 * eps, center = false);
|
||||
|
||||
}
|
||||
|
||||
if(show_supports() && !end) {
|
||||
for(side = [-1, 1]) {
|
||||
w = 2.1 * extrusion_width;
|
||||
translate([s.x + r + cam_x - w / 2, side * (s.y / 2 + wall / 2), twall / 2])
|
||||
cube([w, wall, twall], center = true);
|
||||
|
||||
h = round_to_layer(r - pin_r / sqrt(2));
|
||||
y = s.y / 2 + max(wall + w / 2 + clearance, 2 * wall + clearance - w / 2);
|
||||
translate([s.x + r, side * y, h / 2])
|
||||
cube([pin_r * sqrt(2), w, h], center = true);
|
||||
|
||||
gap = cam_x - pin_r / sqrt(2) + extrusion_width;
|
||||
translate([s.x + r + cam_x - gap / 2, side * (s.y / 2 + wall + clearance / 2), layer_height / 2])
|
||||
cube([gap, 2 * wall + clearance, layer_height], center = true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Need to use a wrapper because can't define nested modules in an assembly
|
||||
module _drag_chain_assembly(type, pos = 0) {
|
||||
s = drag_chain_size(type);
|
||||
x = (1 + exploded()) * s.x;
|
||||
r = drag_chain_radius(type) * x / s.x;
|
||||
travel = drag_chain_travel(type);
|
||||
links = ceil(travel / s.x);
|
||||
actual_travel = links * s.x;
|
||||
z = drag_chain_outer_size(type).z;
|
||||
|
||||
zb = z / 2; // z of bottom track
|
||||
c = [actual_travel / 2 + pos / 2, 0, r + zb]; // centre of bend
|
||||
|
||||
points = [ // Calculate list of hinge points
|
||||
for(i = 0, p = [0, 0, z / 2 + 2 * r]; i < links + 5;
|
||||
i = i + 1,
|
||||
dx = p.z > c.z ? x : -x,
|
||||
p = max(p.x + dx, p.x) <= c.x ? p + [dx, 0, 0] // Straight sections
|
||||
: let(q = circle_intersect(p, x, c, r))
|
||||
q.x <= c.x ? [p.x - sqrt(sqr(x) - sqr(p.z - zb)), 0, zb] // Transition back to straight
|
||||
: q) // Circular section
|
||||
p
|
||||
];
|
||||
npoints = len(points);
|
||||
|
||||
module link(n) // Position and colour link with origin at the hinge hole
|
||||
translate([-z / 2, 0, -z / 2]) {
|
||||
stl_colour(n < 0 || n == npoints - 1 ? pp3_colour : n % 2 ? pp1_colour : pp2_colour)
|
||||
drag_chain_link(type, start = n == -1, end = n == npoints - 1, check_kids = false)
|
||||
let($fasteners = 0) children();
|
||||
let($fasteners = 1) children();
|
||||
}
|
||||
|
||||
screws = drag_chain_screw_lists(type);
|
||||
custom_start = screws[0] == [0, 0, 0, 0];
|
||||
custom_end = screws[1] == [0, 0, 0, 0];
|
||||
assert($children == bool2int(custom_start) + bool2int(custom_end), str("wrong number of children for end customisation: ", $children));
|
||||
|
||||
for(i = [0 : npoints - 2]) let(v = points[i + 1] - points[i])
|
||||
translate(points[i])
|
||||
rotate([0, -atan2(v.z, v.x), 0])
|
||||
link(i);
|
||||
|
||||
translate(points[0] - [x, 0, 0])
|
||||
link(-1)
|
||||
if(custom_start)
|
||||
children(0);
|
||||
|
||||
translate(points[npoints - 1])
|
||||
hflip()
|
||||
link(npoints - 1)
|
||||
if(custom_end)
|
||||
children(custom_start ? 1 : 0);
|
||||
}
|
||||
|
||||
//! 1. Remove the support material from the links with side cutters.
|
||||
//! 1. Clip the links together with the special ones at the ends.
|
||||
module drag_chain_assembly(type, pos = 0) //! Drag chain assembly
|
||||
assembly(str(drag_chain_name(type), "_drag_chain"), big = true)
|
||||
if($children == 2)
|
||||
_drag_chain_assembly(type, pos) {
|
||||
children(0);
|
||||
children(1);
|
||||
}
|
||||
else if($children == 1)
|
||||
_drag_chain_assembly(type, pos)
|
||||
children(0);
|
||||
else
|
||||
_drag_chain_assembly(type, pos);
|
50
printed/press_fit.scad
Normal file
@@ -0,0 +1,50 @@
|
||||
//
|
||||
// NopSCADlib Copyright Chris Palmer 2020
|
||||
// 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/>.
|
||||
//
|
||||
|
||||
//
|
||||
//! Utility for making printed press fit connectors to join printed parts.
|
||||
//!
|
||||
//! Add solvent or glue to make a permanent fixture.
|
||||
//
|
||||
include <../core.scad>
|
||||
|
||||
interference = 0.0;
|
||||
|
||||
bridge_droop = layer_height; //sqrt(4 * layer_height * filament_width / PI) - layer_height;
|
||||
|
||||
module press_fit_socket(w = 5, h = 50, horizontal = false) { //! Make a square hole to accept a peg
|
||||
h = horizontal ? h : h + bridge_droop;
|
||||
|
||||
cube([w, w, 2 * h], center = true);
|
||||
}
|
||||
|
||||
module press_fit_peg(h, w = 5, horizontal = false) { //! Make a rounded chamfered peg for easy insertion
|
||||
module chamfered_square(w, horizontal) {
|
||||
h = horizontal ? w - bridge_droop : w;
|
||||
rounded_square([w, h], 1);
|
||||
}
|
||||
|
||||
translate_z(-eps)
|
||||
linear_extrude(height = h + eps - layer_height)
|
||||
chamfered_square(w + interference, horizontal);
|
||||
|
||||
translate_z(h - layer_height - eps)
|
||||
linear_extrude(height = layer_height + eps)
|
||||
chamfered_square(w - layer_height, horizontal);
|
||||
}
|
@@ -81,7 +81,7 @@ module ribbon_clamp(ways, screw = screw) { //! Generate STL for given number of
|
||||
}
|
||||
}
|
||||
|
||||
module ribbon_clamp_assembly(ways, screw) pose([55, 180, 25]) //! Printed part with inserts in place
|
||||
module ribbon_clamp_assembly(ways, screw = screw) pose([55, 180, 25]) //! Printed part with inserts in place
|
||||
assembly(let(screw_d = screw_radius(screw) * 2)str("ribbon_clamp_", ways, screw_d != 3 ? str("_", screw_d) : "")) {
|
||||
h = ribbon_clamp_height(screw);
|
||||
insert = screw_insert(screw);
|
||||
@@ -117,9 +117,13 @@ module ribbon_clamp_fastened_assembly(ways, thickness, screw = screw) { //! Clam
|
||||
|
||||
module ribbon_clamp_20_stl() ribbon_clamp(20);
|
||||
module ribbon_clamp_8_2_stl() ribbon_clamp(8, M2_dome_screw);
|
||||
module ribbon_clamp_7_2_stl() ribbon_clamp(8, M2_dome_screw);
|
||||
|
||||
//! * Place inserts into the holes and press home with a soldering iron with a conical bit heated to 200°C.
|
||||
module ribbon_clamp_20_assembly() ribbon_clamp_assembly(20);
|
||||
|
||||
//! * Place inserts into the holes and press home with a soldering iron with a conical bit heated to 200°C.
|
||||
module ribbon_clamp_8_2_assembly() ribbon_clamp_assembly(8, M2_dome_screw);
|
||||
|
||||
//! * Place inserts into the holes and press home with a soldering iron with a conical bit heated to 200°C.
|
||||
module ribbon_clamp_7_2_assembly() ribbon_clamp_assembly(8, M2_dome_screw);
|
||||
|
185
readme.md
@@ -28,21 +28,21 @@ See [usage](docs/usage.md) for requirements, installation instructions and a usa
|
||||
<tr><td> <a href = "#Bulldogs">Bulldogs</a> </td><td> <a href = "#Leadnuts">Leadnuts</a> </td><td> <a href = "#SK_brackets">SK_brackets</a> </td><td> <a href = "#Corner_block">Corner_block</a> </td><td> <a href = "#Gears">Gears</a> </td><td> <a href = "#Sphere">Sphere</a> </td></tr>
|
||||
<tr><td> <a href = "#Buttons">Buttons</a> </td><td> <a href = "#Light_strips">Light_strips</a> </td><td> <a href = "#SMDs">SMDs</a> </td><td> <a href = "#Door_hinge">Door_hinge</a> </td><td> <a href = "#Hanging_hole">Hanging_hole</a> </td><td> <a href = "#Teardrops">Teardrops</a> </td></tr>
|
||||
<tr><td> <a href = "#Cable_strips">Cable_strips</a> </td><td> <a href = "#Linear_bearings">Linear_bearings</a> </td><td> <a href = "#SSRs">SSRs</a> </td><td> <a href = "#Door_latch">Door_latch</a> </td><td> <a href = "#Horiholes">Horiholes</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Cameras">Cameras</a> </td><td> <a href = "#Magnets">Magnets</a> </td><td> <a href = "#Screws">Screws</a> </td><td> <a href = "#Fan_guard">Fan_guard</a> </td><td> <a href = "#Layout">Layout</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Circlips">Circlips</a> </td><td> <a href = "#Mains_sockets">Mains_sockets</a> </td><td> <a href = "#Sealing_strip">Sealing_strip</a> </td><td> <a href = "#Fixing_block">Fixing_block</a> </td><td> <a href = "#Maths">Maths</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Components">Components</a> </td><td> <a href = "#Microswitches">Microswitches</a> </td><td> <a href = "#Shaft_couplings">Shaft_couplings</a> </td><td> <a href = "#Flat_hinge">Flat_hinge</a> </td><td> <a href = "#Offset">Offset</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#DIP">DIP</a> </td><td> <a href = "#Microview">Microview</a> </td><td> <a href = "#Sheets">Sheets</a> </td><td> <a href = "#Foot">Foot</a> </td><td> <a href = "#Quadrant">Quadrant</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#D_connectors">D_connectors</a> </td><td> <a href = "#Modules">Modules</a> </td><td> <a href = "#Spades">Spades</a> </td><td> <a href = "#Handle">Handle</a> </td><td> <a href = "#Round">Round</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Displays">Displays</a> </td><td> <a href = "#Nuts">Nuts</a> </td><td> <a href = "#Spools">Spools</a> </td><td> <a href = "#PCB_mount">PCB_mount</a> </td><td> <a href = "#Rounded_cylinder">Rounded_cylinder</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Extrusion_brackets">Extrusion_brackets</a> </td><td> <a href = "#O_ring">O_ring</a> </td><td> <a href = "#Springs">Springs</a> </td><td> <a href = "#PSU_shroud">PSU_shroud</a> </td><td> <a href = "#Rounded_polygon">Rounded_polygon</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Extrusions">Extrusions</a> </td><td> <a href = "#Opengrab">Opengrab</a> </td><td> <a href = "#Stepper_motors">Stepper_motors</a> </td><td> <a href = "#Printed_box">Printed_box</a> </td><td> <a href = "#Sector">Sector</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Fans">Fans</a> </td><td> <a href = "#PCB">PCB</a> </td><td> <a href = "#Swiss_clips">Swiss_clips</a> </td><td> <a href = "#Ribbon_clamp">Ribbon_clamp</a> </td><td> <a href = "#Sweep">Sweep</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Fuseholder">Fuseholder</a> </td><td> <a href = "#PCBs">PCBs</a> </td><td> <a href = "#Toggles">Toggles</a> </td><td> <a href = "#SSR_shroud">SSR_shroud</a> </td><td> <a href = "#Thread">Thread</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Geared_steppers">Geared_steppers</a> </td><td> <a href = "#PSUs">PSUs</a> </td><td> <a href = "#Transformers">Transformers</a> </td><td> <a href = "#Screw_knob">Screw_knob</a> </td><td> <a href = "#Tube">Tube</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Green_terminals">Green_terminals</a> </td><td> <a href = "#Panel_meters">Panel_meters</a> </td><td> <a href = "#Tubings">Tubings</a> </td><td> <a href = "#Socket_box">Socket_box</a> </td><td></td><td></td></tr>
|
||||
<tr><td> <a href = "#Hot_ends">Hot_ends</a> </td><td> <a href = "#Pillars">Pillars</a> </td><td> <a href = "#Variacs">Variacs</a> </td><td> <a href = "#Strap_handle">Strap_handle</a> </td><td></td><td></td></tr>
|
||||
<tr><td> <a href = "#Hygrometer">Hygrometer</a> </td><td> <a href = "#Pin_headers">Pin_headers</a> </td><td> <a href = "#Veroboard">Veroboard</a> </td><td></td><td></td><td></td></tr>
|
||||
<tr><td> <a href = "#IECs">IECs</a> </td><td> <a href = "#Pulleys">Pulleys</a> </td><td> <a href = "#Washers">Washers</a> </td><td></td><td></td><td></td></tr>
|
||||
<tr><td> <a href = "#Cameras">Cameras</a> </td><td> <a href = "#Magnets">Magnets</a> </td><td> <a href = "#Screws">Screws</a> </td><td> <a href = "#Drag_chain">Drag_chain</a> </td><td> <a href = "#Layout">Layout</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Circlips">Circlips</a> </td><td> <a href = "#Mains_sockets">Mains_sockets</a> </td><td> <a href = "#Sealing_strip">Sealing_strip</a> </td><td> <a href = "#Fan_guard">Fan_guard</a> </td><td> <a href = "#Maths">Maths</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Components">Components</a> </td><td> <a href = "#Microswitches">Microswitches</a> </td><td> <a href = "#Shaft_couplings">Shaft_couplings</a> </td><td> <a href = "#Fixing_block">Fixing_block</a> </td><td> <a href = "#Offset">Offset</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#DIP">DIP</a> </td><td> <a href = "#Microview">Microview</a> </td><td> <a href = "#Sheets">Sheets</a> </td><td> <a href = "#Flat_hinge">Flat_hinge</a> </td><td> <a href = "#Quadrant">Quadrant</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#D_connectors">D_connectors</a> </td><td> <a href = "#Modules">Modules</a> </td><td> <a href = "#Spades">Spades</a> </td><td> <a href = "#Foot">Foot</a> </td><td> <a href = "#Round">Round</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Displays">Displays</a> </td><td> <a href = "#Nuts">Nuts</a> </td><td> <a href = "#Spools">Spools</a> </td><td> <a href = "#Handle">Handle</a> </td><td> <a href = "#Rounded_cylinder">Rounded_cylinder</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Extrusion_brackets">Extrusion_brackets</a> </td><td> <a href = "#O_ring">O_ring</a> </td><td> <a href = "#Springs">Springs</a> </td><td> <a href = "#PCB_mount">PCB_mount</a> </td><td> <a href = "#Rounded_polygon">Rounded_polygon</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Extrusions">Extrusions</a> </td><td> <a href = "#Opengrab">Opengrab</a> </td><td> <a href = "#Stepper_motors">Stepper_motors</a> </td><td> <a href = "#PSU_shroud">PSU_shroud</a> </td><td> <a href = "#Sector">Sector</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Fans">Fans</a> </td><td> <a href = "#PCB">PCB</a> </td><td> <a href = "#Swiss_clips">Swiss_clips</a> </td><td> <a href = "#Press_fit">Press_fit</a> </td><td> <a href = "#Sweep">Sweep</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Fuseholder">Fuseholder</a> </td><td> <a href = "#PCBs">PCBs</a> </td><td> <a href = "#Toggles">Toggles</a> </td><td> <a href = "#Printed_box">Printed_box</a> </td><td> <a href = "#Thread">Thread</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Geared_steppers">Geared_steppers</a> </td><td> <a href = "#PSUs">PSUs</a> </td><td> <a href = "#Transformers">Transformers</a> </td><td> <a href = "#Ribbon_clamp">Ribbon_clamp</a> </td><td> <a href = "#Tube">Tube</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Green_terminals">Green_terminals</a> </td><td> <a href = "#Panel_meters">Panel_meters</a> </td><td> <a href = "#Tubings">Tubings</a> </td><td> <a href = "#SSR_shroud">SSR_shroud</a> </td><td></td><td></td></tr>
|
||||
<tr><td> <a href = "#Hot_ends">Hot_ends</a> </td><td> <a href = "#Pillars">Pillars</a> </td><td> <a href = "#Variacs">Variacs</a> </td><td> <a href = "#Screw_knob">Screw_knob</a> </td><td></td><td></td></tr>
|
||||
<tr><td> <a href = "#Hygrometer">Hygrometer</a> </td><td> <a href = "#Pin_headers">Pin_headers</a> </td><td> <a href = "#Veroboard">Veroboard</a> </td><td> <a href = "#Socket_box">Socket_box</a> </td><td></td><td></td></tr>
|
||||
<tr><td> <a href = "#IECs">IECs</a> </td><td> <a href = "#Pulleys">Pulleys</a> </td><td> <a href = "#Washers">Washers</a> </td><td> <a href = "#Strap_handle">Strap_handle</a> </td><td></td><td></td></tr>
|
||||
<tr><td> <a href = "#Inserts">Inserts</a> </td><td></td><td> <a href = "#Wire">Wire</a> </td><td></td><td></td><td></td></tr>
|
||||
<tr><td></td><td></td><td> <a href = "#Zipties">Zipties</a> </td><td></td><td></td><td></td></tr>
|
||||
</table>
|
||||
@@ -208,7 +208,7 @@ exposing enough information to make a battery box.
|
||||
<a name="Belts"></a>
|
||||
## Belts
|
||||
Models timing belt running over toothed or smooth pulleys and calculates an accurate length.
|
||||
Only models 2D paths, so not core XY!
|
||||
Only models 2D paths, so not crossed belt core XY!
|
||||
|
||||
To make the back of the belt run against a smooth pulley on the outside of the loop specify a negative pitch radius.
|
||||
|
||||
@@ -250,15 +250,16 @@ Individual teeth are not drawn, instead they are represented by a lighter colour
|
||||
| Qty | Module call | BOM entry |
|
||||
| ---:|:--- |:---|
|
||||
| 1 | ```belt(GT2x6, [ ... ])``` | Belt GT2 x 6mm x 128mm |
|
||||
| 1 | ```belt(GT2x6, [ ... ], 80, [0, 0])``` | Belt GT2 x 6mm x 696mm |
|
||||
| 2 | ```belt(GT2x6, [ ... ], 80, [0, 0])``` | Belt GT2 x 6mm x 572mm |
|
||||
| 1 | ```belt(T2p5x6, [ ... ])``` | Belt T2.5 x 6mm x 130mm |
|
||||
| 1 | ```belt(T5x10, [ ... ])``` | Belt T5 x 10mm x 130mm |
|
||||
| 1 | ```belt(T5x6, [ ... ])``` | Belt T5 x 6mm x 130mm |
|
||||
| 1 | ```insert(F1BM3)``` | Heatfit insert M3 |
|
||||
| 2 | ```pulley(GT2x20_toothed_idler)``` | Pulley GT2 idler 20 teeth |
|
||||
| 2 | ```insert(F1BM3)``` | Heatfit insert M3 |
|
||||
| 2 | ```pulley(GT2x16_toothed_idler)``` | Pulley GT2 idler 16 teeth |
|
||||
| 4 | ```pulley(GT2x20_toothed_idler)``` | Pulley GT2 idler 20 teeth |
|
||||
| 2 | ```pulley(GT2x16_plain_idler)``` | Pulley GT2 idler smooth 9.63mm |
|
||||
| 2 | ```pulley(GT2x20ob_pulley)``` | Pulley GT2OB 20 teeth |
|
||||
| 1 | ```screw(M3_cs_cap_screw, 20)``` | Screw M3 cs cap x 20mm |
|
||||
| 2 | ```screw(M3_cs_cap_screw, 20)``` | Screw M3 cs cap x 20mm |
|
||||
| 4 | ```screw(M3_grub_screw, 6)``` | Screw M3 grub x 6mm |
|
||||
|
||||
|
||||
@@ -295,11 +296,18 @@ Models of radial blowers.
|
||||
| ```blower_wall(type)``` | Side wall thickness |
|
||||
| ```blower_width(type)``` | Width of enclosing rectangle |
|
||||
|
||||
### Functions
|
||||
| Function | Description |
|
||||
|:--- |:--- |
|
||||
| ```blower_casing_is_square(type)``` | True for square radial fans, false for spiral shape radial blowers |
|
||||
| ```blower_exit_offset(type)``` | Offset of exit's centre from the edge |
|
||||
|
||||
### Modules
|
||||
| Module | Description |
|
||||
|:--- |:--- |
|
||||
| ```blower(type)``` | Draw specified blower |
|
||||
| ```blower_hole_positions(type)``` | Translate children to screw hole positions |
|
||||
| ```blower_square(type)``` | Draw a square blower |
|
||||
|
||||

|
||||
|
||||
@@ -308,8 +316,11 @@ Models of radial blowers.
|
||||
| ---:|:--- |:---|
|
||||
| 1 | ```blower(PE4020)``` | Blower Pengda Technology 4020 |
|
||||
| 1 | ```blower(RB5015)``` | Blower Runda RB5015 |
|
||||
| 4 | ```screw(M2_cap_screw, 8)``` | Screw M2 cap x 8mm |
|
||||
| 3 | ```screw(M3_cap_screw, 20)``` | Screw M3 cap x 20mm |
|
||||
| 2 | ```screw(M4_cap_screw, 25)``` | Screw M4 cap x 25mm |
|
||||
| 1 | ```blower(BL40x10)``` | Square radial 4010 |
|
||||
| 4 | ```washer(M2_washer)``` | Washer M2 x 5mm x 0.3mm |
|
||||
| 3 | ```washer(M3_washer)``` | Washer M3 x 7mm x 0.5mm |
|
||||
| 2 | ```washer(M4_washer)``` | Washer M4 x 9mm x 0.8mm |
|
||||
|
||||
@@ -463,8 +474,8 @@ PCB cameras.
|
||||
### Modules
|
||||
| Module | Description |
|
||||
|:--- |:--- |
|
||||
| ```camera(type)``` | Draw specified PCB camera |
|
||||
| ```camera_lens(type, offset = 0)``` | Draw the lens stack, with optional offset for making a clearance hole |
|
||||
| ```camera(type, show_lens = true)``` | Draw specified PCB camera |
|
||||
| ```camera_lens(type, offset = 0, show_lens = true)``` | Draw the lens stack, with optional offset for making a clearance hole |
|
||||
|
||||

|
||||
|
||||
@@ -757,6 +768,7 @@ LCD dispays.
|
||||
### Vitamins
|
||||
| Qty | Module call | BOM entry |
|
||||
| ---:|:--- |:---|
|
||||
| 1 | ```display(BigTreeTech_TFT35v3_0)``` | BigTreeTech TFT35 v3.0 |
|
||||
| 1 | ```display(HDMI5)``` | HDMI display 5" |
|
||||
| 1 | ```display(LCD1602A)``` | LCD display 1602A |
|
||||
| 1 | ```display(LCDS7282B)``` | LCD display S-7282B |
|
||||
@@ -2695,6 +2707,7 @@ Linear rails with carriages.
|
||||
| Function | Description |
|
||||
|:--- |:--- |
|
||||
| ```carriage_screw_depth(type)``` | Carriage thread depth |
|
||||
| ```rail_holes(type, length)``` | Number of holes in a rail given its ```length``` |
|
||||
| ```rail_screw_height(type, screw)``` | Position screw taking into account countersink into counterbored hole |
|
||||
| ```rail_travel(type, length)``` | How far the carriage can travel |
|
||||
|
||||
@@ -2891,6 +2904,8 @@ These items are sysmtrical, so by default the origin is in the centre but it can
|
||||
## Screws
|
||||
Machine screws and wood screws with various head styles.
|
||||
|
||||
For an explanation of ```screw_polysink()``` see <https://hydraraptor.blogspot.com/2020/12/sinkholes.html>.
|
||||
|
||||
|
||||
[vitamins/screws.scad](vitamins/screws.scad) Object definitions.
|
||||
|
||||
@@ -2917,9 +2932,10 @@ Machine screws and wood screws with various head styles.
|
||||
| Function | Description |
|
||||
|:--- |:--- |
|
||||
| ```screw_boss_diameter(type)``` | Boss big enough for nut trap and washer |
|
||||
| ```screw_head_depth(type, d)``` | How far a counter sink head will go into a straight hole diameter d |
|
||||
| ```screw_head_depth(type, d = 0)``` | How far a counter sink head will go into a straight hole diameter d |
|
||||
| ```screw_longer_than(x)``` | Returns shortest screw length longer or equal to x |
|
||||
| ```screw_nut_radius(type)``` | Radius of matching nut |
|
||||
| ```screw_polysink_r(type, z)``` | Countersink hole profile corrected for rounded staircase extrusions. |
|
||||
| ```screw_shorter_than(x)``` | Returns longest screw length shorter than or equal to x |
|
||||
|
||||
### Modules
|
||||
@@ -2927,7 +2943,8 @@ Machine screws and wood screws with various head styles.
|
||||
|:--- |:--- |
|
||||
| ```screw(type, length, hob_point = 0, nylon = false)``` | Draw specified screw, optionally hobbed or nylon |
|
||||
| ```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 |
|
||||
| ```screw_countersink(type)``` | Countersink shape |
|
||||
| ```screw_countersink(type, drilled = true)``` | Countersink shape |
|
||||
| ```screw_polysink(type, h = 100, alt = false)``` | A countersink hole made from stacked polyholes for printed parts |
|
||||
|
||||

|
||||
|
||||
@@ -2966,6 +2983,11 @@ Machine screws and wood screws with various head styles.
|
||||
| 1 | ```screw(No6_cs_screw, 30)``` | Screw No6 cs wood x 30mm |
|
||||
| 1 | ```screw(No6_screw, 30)``` | Screw No6 pan wood x 30mm |
|
||||
|
||||
### Printed
|
||||
| Qty | Filename |
|
||||
| ---:|:--- |
|
||||
| 1 | polysink.stl |
|
||||
|
||||
|
||||
<a href="#top">Top</a>
|
||||
|
||||
@@ -4537,6 +4559,73 @@ Door latch for 6mm acrylic door for 3D printer. See [door_hinge](#door_hinge).
|
||||
| 1 | door_latch.stl |
|
||||
|
||||
|
||||
<a href="#top">Top</a>
|
||||
|
||||
---
|
||||
<a name="Drag_chain"></a>
|
||||
## Drag_chain
|
||||
Parametric cable drag chain to limit the bend radius of a cable run.
|
||||
|
||||
Each link has a maximum bend angle of 45°, so the mininium radius is proportional to the link length.
|
||||
|
||||
The travel property is how far it can move in each direction, i.e. half the maximum travel if the chain is mounted in the middle of the travel.
|
||||
|
||||
The ends can have screw lugs with four screw positions to choose from, specified by a list of two arrays of four bools.
|
||||
If none are enabled then a child object is expected to customise the end and this gets unioned with the blank end.
|
||||
If both ends are customised then two children are expected.
|
||||
Each child is called twice, once with ```$fasteners``` set to 0 to augment the STL and again with ```$fasteners``` set to 1 to add
|
||||
to the assembly, for example to add inserts.
|
||||
|
||||
|
||||
[printed/drag_chain.scad](printed/drag_chain.scad) Implementation.
|
||||
|
||||
[tests/drag_chain.scad](tests/drag_chain.scad) Code for this example.
|
||||
|
||||
### Properties
|
||||
| Function | Description |
|
||||
|:--- |:--- |
|
||||
| ```drag_chain_bwall(type)``` | Bottom wall |
|
||||
| ```drag_chain_name(type)``` | The name to allow more than one in a project |
|
||||
| ```drag_chain_screw(type)``` | Mounting screw for the ends |
|
||||
| ```drag_chain_screw_lists(type)``` | Two lists of four bools to say which screws positions are used |
|
||||
| ```drag_chain_size(type)``` | The internal size and link length |
|
||||
| ```drag_chain_travel(type)``` | X travel |
|
||||
| ```drag_chain_twall(type)``` | Top wall |
|
||||
| ```drag_chain_wall(type)``` | Side wall thickness |
|
||||
|
||||
### Functions
|
||||
| Function | Description |
|
||||
|:--- |:--- |
|
||||
| ```drag_chain(name, size, travel, wall = 1.6, bwall = 1.5, twall = 1.5, screw = M2_cap_screw, screw_lists = [[1,0,0,1],[1,0,0,1]])``` | Constructor |
|
||||
| ```drag_chain_clearance()``` | Clearance around joints. |
|
||||
| ```drag_chain_outer_size(type)``` | Link outer dimensions |
|
||||
| ```drag_chain_radius(type)``` | The bend radius at the pivot centres |
|
||||
| ```drag_chain_z(type)``` | Outside dimension of a 180 bend |
|
||||
| ```screw_lug_radius(screw)``` | Radius of a screw lug |
|
||||
|
||||
### Modules
|
||||
| Module | Description |
|
||||
|:--- |:--- |
|
||||
| ```drag_chain_assembly(type, pos = 0)``` | Drag chain assembly |
|
||||
| ```drag_chain_link(type, start = false, end = false, check_kids = true)``` | One link of the chain, special case for start and end |
|
||||
| ```drag_chain_screw_positions(type, end)``` | Place children at the screw positions, end = 0 for the start, 1 for the end |
|
||||
| ```screw_lug(screw, h = 0)``` | Create a D shaped lug for a screw |
|
||||
|
||||

|
||||
|
||||
### Printed
|
||||
| Qty | Filename |
|
||||
| ---:|:--- |
|
||||
| 14 | x_drag_chain_link.stl |
|
||||
| 1 | x_drag_chain_link_end.stl |
|
||||
| 1 | x_drag_chain_link_start.stl |
|
||||
|
||||
### Assemblies
|
||||
| Qty | Name |
|
||||
| ---:|:--- |
|
||||
| 1 | x_drag_chain_assembly |
|
||||
|
||||
|
||||
<a href="#top">Top</a>
|
||||
|
||||
---
|
||||
@@ -4898,6 +4987,29 @@ The stl must be given a parameterless wrapper in the project that uses it.
|
||||
| 1 | pcb_mount_PI_IO_5.stl |
|
||||
|
||||
|
||||
<a href="#top">Top</a>
|
||||
|
||||
---
|
||||
<a name="Press_fit"></a>
|
||||
## Press_fit
|
||||
Utility for making printed press fit connectors to join printed parts.
|
||||
|
||||
Add solvent or glue to make a permanent fixture.
|
||||
|
||||
|
||||
[printed/press_fit.scad](printed/press_fit.scad) Implementation.
|
||||
|
||||
[tests/press_fit.scad](tests/press_fit.scad) Code for this example.
|
||||
|
||||
### Modules
|
||||
| Module | Description |
|
||||
|:--- |:--- |
|
||||
| ```press_fit_peg(h, w = 5, horizontal = false)``` | Make a rounded chamfered peg for easy insertion |
|
||||
| ```press_fit_socket(w = 5, h = 50, horizontal = false)``` | Make a square hole to accept a peg |
|
||||
|
||||

|
||||
|
||||
|
||||
<a href="#top">Top</a>
|
||||
|
||||
---
|
||||
@@ -5065,7 +5177,7 @@ Clamp for ribbon cable and polypropylene strip.
|
||||
| Module | Description |
|
||||
|:--- |:--- |
|
||||
| ```ribbon_clamp(ways, screw = screw)``` | Generate STL for given number of ways |
|
||||
| ```ribbon_clamp_assembly(ways, screw)``` | Printed part with inserts in place |
|
||||
| ```ribbon_clamp_assembly(ways, screw = screw)``` | Printed part with inserts in place |
|
||||
| ```ribbon_clamp_fastened_assembly(ways, thickness, screw = screw)``` | Clamp with fasteners in place |
|
||||
| ```ribbon_clamp_hole_positions(ways, screw = screw, side = undef)``` | Place children at hole positions |
|
||||
| ```ribbon_clamp_holes(ways, h = 20, screw = screw)``` | Drill screw holes |
|
||||
@@ -5749,7 +5861,7 @@ A sector of a circle between two angles.
|
||||
Utility to generate a polhedron by sweeping a 2D profile along a 3D path and utilities for generating paths.
|
||||
|
||||
The initial orientation is the Y axis of the profile points towards the initial center of curvature, Frenet-Serret style.
|
||||
This means the first three points must not be colinear. Subsequent rotations use the minimum rotation method.
|
||||
Subsequent rotations use the minimum rotation method.
|
||||
|
||||
The path can be open or closed. If closed sweep ensures that the start and end have the same rotation to line up.
|
||||
An additional twist around the path can be specified. If the path is closed this should be a multiple of 360.
|
||||
@@ -5985,11 +6097,11 @@ Global constants, functions and modules. This file is used directly or indirectl
|
||||
| ```circle4n(r, d = undef)``` | Circle with multiple of 4 vertices |
|
||||
| ```ellipse(xr, yr)``` | Draw an ellipse |
|
||||
| ```extrude_if(h, center = true)``` | Extrudes 2D object to 3D when ```h``` is nonzero, otherwise leaves it 2D |
|
||||
| ```hflip()``` | Invert children by doing a 180° flip around the Y axis |
|
||||
| ```hflip(flip=true)``` | Invert children by doing a 180° flip around the Y axis |
|
||||
| ```right_triangle(width, height, h, center = true)``` | A right angled triangle with the 90° corner at the origin. 3D when ```h``` is nonzero, otherwise 2D |
|
||||
| ```semi_circle(r, d = undef)``` | A semi circle in the positive Y domain |
|
||||
| ```translate_z(z)``` | Shortcut for Z only translations |
|
||||
| ```vflip()``` | Invert children by doing a 180° flip around the X axis |
|
||||
| ```vflip(flip=true)``` | Invert children by doing a 180° flip around the X axis |
|
||||
|
||||

|
||||
|
||||
@@ -6004,6 +6116,16 @@ it gets the linear dimensions right. See <https://hydraraptor.blogspot.com/2011/
|
||||
|
||||
The module provides `poly_circle()`, `poly_cylinder()` and `poly_ring()` that is useful for making printed washers and pillars.
|
||||
|
||||
`poly_cylinder()` has a `twist` parameter which can be set to make the polygon rotate each layer.
|
||||
This can be used to mitigate the number of sides being small and make small holes stronger and more round, but is quite slow due to the
|
||||
large increase in the number of facets.
|
||||
When set to 1 the polygons alternate each layer, when set higher the rotation takes `twist + 1` layers to repeat.
|
||||
A small additional rotation is added to make the polygon rotate one more side over the length of the hole to make it appear round when
|
||||
veiwed end on.
|
||||
|
||||
When `twist` is set the resulting cylinder is extended by `eps` at each end so that the exact length of the hole can be used without
|
||||
leaving a scar on either surface.
|
||||
|
||||
|
||||
[utils/core/polyholes.scad](utils/core/polyholes.scad) Implementation.
|
||||
|
||||
@@ -6021,7 +6143,7 @@ The module provides `poly_circle()`, `poly_cylinder()` and `poly_ring()` that is
|
||||
|:--- |:--- |
|
||||
| ```drill(r, h = 100, center = true)``` | Make a cylinder for drilling holes suitable for CNC routing, set h = 0 for circle |
|
||||
| ```poly_circle(r, sides = 0)``` | Make a circle adjusted to print the correct size |
|
||||
| ```poly_cylinder(r, h, center = false, sides = 0, chamfer = false)``` | Make a cylinder adjusted to print the correct size |
|
||||
| ```poly_cylinder(r, h, center = false, sides = 0, chamfer = false, twist = 0)``` | Make a cylinder adjusted to print the correct size |
|
||||
| ```poly_drill(r, h = 100, center = true)``` | Make a cylinder for drilling holes suitable for CNC routing if cnc_bit_r is non zero, otherwise a poly_cylinder. |
|
||||
| ```poly_ring(or, ir, sides = 0)``` | Make a 2D ring adjusted to have the correct internal radius |
|
||||
| ```poly_tube(or, ir, h, center = false)``` | Make a tube adjusted to have the correct internal radius |
|
||||
@@ -6055,6 +6177,11 @@ The module provides `poly_circle()`, `poly_cylinder()` and `poly_ring()` that is
|
||||
| 1 | ```rod(9.5, 43)``` | Smooth rod 9.5mm x 43mm |
|
||||
| 1 | ```rod(9, 41)``` | Smooth rod 9mm x 41mm |
|
||||
|
||||
### Printed
|
||||
| Qty | Filename |
|
||||
| ---:|:--- |
|
||||
| 1 | polyhole.stl |
|
||||
|
||||
|
||||
<a href="#top">Top</a>
|
||||
|
||||
|
@@ -87,24 +87,25 @@ def plateup(target, part_type, usage = None):
|
||||
match = re.match(r'^ECHO: "~(.*?\.' + part_type + r').*"$', line)
|
||||
if match:
|
||||
used.append(match.group(1))
|
||||
#
|
||||
# Copy file that are not included
|
||||
#
|
||||
copied = []
|
||||
for file in os.listdir(parts_dir):
|
||||
if file.endswith('.' + part_type) and not file in used:
|
||||
src = parts_dir + '/' + file
|
||||
dst = target_dir + '/' + file
|
||||
if mtime(src) > mtime(dst):
|
||||
print("Copying %s to %s" % (src, dst))
|
||||
copyfile(src, dst)
|
||||
copied.append(file)
|
||||
#
|
||||
# Remove any cruft
|
||||
#
|
||||
targets = [file[:-4] + part_type for file in all_sources]
|
||||
for file in os.listdir(target_dir):
|
||||
if file.endswith('.' + part_type):
|
||||
if not file in targets and not file in copied:
|
||||
print("Removing %s" % file)
|
||||
os.remove(target_dir + '/' + file)
|
||||
if all_sources:
|
||||
#
|
||||
# Copy files that are not included
|
||||
#
|
||||
for file in os.listdir(parts_dir):
|
||||
if file.endswith('.' + part_type) and not file in used:
|
||||
src = parts_dir + '/' + file
|
||||
dst = target_dir + '/' + file
|
||||
if mtime(src) > mtime(dst):
|
||||
print("Copying %s to %s" % (src, dst))
|
||||
copyfile(src, dst)
|
||||
copied.append(file)
|
||||
#
|
||||
# Remove any cruft
|
||||
#
|
||||
targets = [file[:-4] + part_type for file in all_sources]
|
||||
for file in os.listdir(target_dir):
|
||||
if file.endswith('.' + part_type):
|
||||
if not file in targets and not file in copied:
|
||||
print("Removing %s" % file)
|
||||
os.remove(target_dir + '/' + file)
|
||||
|
@@ -308,8 +308,7 @@ def views(target, do_assemblies = None):
|
||||
if printed:
|
||||
print('### 3D Printed parts', file = doc_file)
|
||||
keys = sorted(list(printed.keys()))
|
||||
for i in range(len(keys)):
|
||||
p = keys[i]
|
||||
for i, p in enumerate(keys):
|
||||
print('%s %d x %s |' % ('\n|' if not (i % 3) else '', printed[p]["count"], p), file = doc_file, end = '')
|
||||
if (i % 3) == 2 or i == len(printed) - 1:
|
||||
n = (i % 3) + 1
|
||||
@@ -324,8 +323,7 @@ def views(target, do_assemblies = None):
|
||||
if routed:
|
||||
print("### CNC Routed parts", file = doc_file)
|
||||
keys = sorted(list(routed.keys()))
|
||||
for i in range(len(keys)):
|
||||
r = keys[i]
|
||||
for i, r in enumerate(keys):
|
||||
print('%s %d x %s |' % ('\n|' if not (i % 3) else '', routed[r]["count"], r), file = doc_file, end = '')
|
||||
if (i % 3) == 2 or i == len(routed) - 1:
|
||||
n = (i % 3) + 1
|
||||
@@ -340,8 +338,7 @@ def views(target, do_assemblies = None):
|
||||
if sub_assemblies:
|
||||
print("### Sub-assemblies", file = doc_file)
|
||||
keys = sorted(list(sub_assemblies.keys()))
|
||||
for i in range(len(keys)):
|
||||
a = keys[i]
|
||||
for i, a in enumerate(keys):
|
||||
print('%s %d x %s |' % ('\n|' if not (i % 3) else '', sub_assemblies[a], a), file = doc_file, end = '')
|
||||
if (i % 3) == 2 or i == len(keys) - 1:
|
||||
n = (i % 3) + 1
|
||||
|
@@ -23,46 +23,52 @@ use <../vitamins/insert.scad>
|
||||
use <../utils/layout.scad>
|
||||
|
||||
module belt_test() {
|
||||
p1 = [75, -50];
|
||||
p2 = [-75, -50];
|
||||
p3 = [-75, 100];
|
||||
p4 = [75, 100];
|
||||
|
||||
p5 = [75 - pulley_pr(GT2x20ob_pulley) - pulley_pr(GT2x16_plain_idler), -pulley_pr(GT2x16_plain_idler)];
|
||||
p6 = [-75 + pulley_pr(GT2x20ob_pulley) + pulley_pr(GT2x16_plain_idler), -pulley_pr(GT2x16_plain_idler)];
|
||||
p5 = [75 + pulley_pr(GT2x20ob_pulley) - pulley_pr(GT2x16_plain_idler), +pulley_pr(GT2x16_plain_idler)];
|
||||
p6 = [-75 + pulley_pr(GT2x20ob_pulley) + pulley_pr(GT2x16_plain_idler), -pulley_pr(GT2x16_plain_idler)];
|
||||
|
||||
translate(p1) pulley_assembly(GT2x20ob_pulley);
|
||||
translate(p2) pulley_assembly(GT2x20ob_pulley);
|
||||
translate(p3) pulley_assembly(GT2x20_toothed_idler);
|
||||
translate(p4) pulley_assembly(GT2x20_toothed_idler);
|
||||
module pulleys(flip = false) {
|
||||
translate(p2) rotate([0, flip ? 180 : 0, 0]) pulley_assembly(GT2x20ob_pulley);
|
||||
translate(p3) pulley_assembly(GT2x20_toothed_idler);
|
||||
translate(p4) pulley_assembly(GT2x20_toothed_idler);
|
||||
translate(p5) {
|
||||
pulley = GT2x16_toothed_idler;
|
||||
screw = find_screw(hs_cs_cap, pulley_bore(pulley));
|
||||
insert = screw_insert(screw);
|
||||
|
||||
translate(p5) {
|
||||
pulley = GT2x16_plain_idler;
|
||||
screw = find_screw(hs_cs_cap, pulley_bore(pulley));
|
||||
insert = screw_insert(screw);
|
||||
|
||||
pulley_assembly(pulley);
|
||||
translate_z(pulley_height(pulley) + pulley_offset(pulley) + screw_head_depth(screw, pulley_bore(pulley)))
|
||||
screw(screw, 20);
|
||||
|
||||
translate_z(pulley_offset(pulley) - insert_length(insert))
|
||||
vflip()
|
||||
insert(insert);
|
||||
hflip(flip) {
|
||||
pulley_assembly(pulley);
|
||||
translate_z(pulley_height(pulley) + pulley_offset(pulley) + screw_head_depth(screw, pulley_bore(pulley)))
|
||||
screw(screw, 20);
|
||||
|
||||
translate_z(pulley_offset(pulley) - insert_length(insert))
|
||||
vflip()
|
||||
insert(insert);
|
||||
}
|
||||
}
|
||||
translate(p6) pulley_assembly(GT2x16_plain_idler);
|
||||
}
|
||||
translate(p6) pulley_assembly(GT2x16_plain_idler);
|
||||
|
||||
path = [ [p1.x, p1.y, pulley_pr(GT2x20ob_pulley)],
|
||||
[p5.x, p5.y, -pulley_pr(GT2x16_plain_idler)],
|
||||
path = [ [p5.x, p5.y, pulley_pr(GT2x16_plain_idler)],
|
||||
[p6.x, p6.y, -pulley_pr(GT2x16_plain_idler)],
|
||||
[p2.x, p2.y, pulley_pr(GT2x20ob_pulley)],
|
||||
[p3.x, p3.y, pulley_pr(GT2x20ob_pulley)],
|
||||
[p4.x, p4.y, pulley_pr(GT2x20ob_pulley)]
|
||||
];
|
||||
|
||||
belt = GT2x6;
|
||||
belt(belt, path, 80, [0, 0]);
|
||||
pulleys();
|
||||
translate_z(20)
|
||||
hflip() {
|
||||
belt(belt, path, 80, [0, 0], belt_colour = grey(90), tooth_colour = grey(50));
|
||||
pulleys(flip=true);
|
||||
}
|
||||
|
||||
translate([-25, 0])
|
||||
translate([-25, 0, 10])
|
||||
layout([for(b = belts) belt_width(b)], 10)
|
||||
rotate([0, 90, 0])
|
||||
belt(belts[$i], [[0, 0, 20], [0, 1, 20]], belt_colour = $i%2==0 ? grey(90) : grey(20), tooth_colour = $i%2==0 ? grey(70) : grey(50));
|
||||
|
59
tests/drag_chain.scad
Normal file
@@ -0,0 +1,59 @@
|
||||
//
|
||||
// NopSCADlib Copyright Chris Palmer 2020
|
||||
// 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/>.
|
||||
//
|
||||
|
||||
// Link length between hinges
|
||||
x = 10; //[8 : 30]
|
||||
|
||||
// Link inner width
|
||||
y = 10; //[5 : 30]
|
||||
|
||||
// Link inner height
|
||||
z = 5; //[4 : 11]
|
||||
// Side wall thickness
|
||||
wall = 1.6; //[0.9: 0.1: 3]
|
||||
// Bottom wall thickness
|
||||
bwall = 1.5; //[1: 0.25: 3]
|
||||
// Top wall thickness
|
||||
twall = 1.5; //[1: 0.25: 3]
|
||||
// Max travel in each direction
|
||||
travel = 100;
|
||||
// Current position
|
||||
pos = 50; // [-100 : 1 : 100]
|
||||
|
||||
include <../core.scad>
|
||||
use <../printed/drag_chain.scad>
|
||||
|
||||
include <../vitamins/leadnuts.scad>
|
||||
|
||||
drag_chain = drag_chain("x", [x, y, z], travel, wall = wall, bwall = bwall, twall = twall);
|
||||
|
||||
module drag_chains()
|
||||
drag_chain_assembly(drag_chain, pos);
|
||||
|
||||
if($preview)
|
||||
drag_chains();
|
||||
else {
|
||||
drag_chain_link(drag_chain);
|
||||
|
||||
translate([-x * 2, 0])
|
||||
drag_chain_link(drag_chain, start = true);
|
||||
|
||||
translate([x * 2, 0])
|
||||
drag_chain_link(drag_chain, end = true);
|
||||
}
|
Before Width: | Height: | Size: 103 KiB After Width: | Height: | Size: 133 KiB |
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 49 KiB |
Before Width: | Height: | Size: 112 KiB After Width: | Height: | Size: 119 KiB |
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 60 KiB |
Before Width: | Height: | Size: 67 KiB After Width: | Height: | Size: 68 KiB |
Before Width: | Height: | Size: 104 KiB After Width: | Height: | Size: 117 KiB |
Before Width: | Height: | Size: 73 KiB After Width: | Height: | Size: 76 KiB |
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 76 KiB |
BIN
tests/png/drag_chain.png
Normal file
After Width: | Height: | Size: 154 KiB |
Before Width: | Height: | Size: 148 KiB After Width: | Height: | Size: 152 KiB |
Before Width: | Height: | Size: 68 KiB After Width: | Height: | Size: 70 KiB |
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 111 KiB After Width: | Height: | Size: 112 KiB |
Before Width: | Height: | Size: 114 KiB After Width: | Height: | Size: 136 KiB |
BIN
tests/png/press_fit.png
Normal file
After Width: | Height: | Size: 85 KiB |
Before Width: | Height: | Size: 128 KiB After Width: | Height: | Size: 129 KiB |
Before Width: | Height: | Size: 84 KiB After Width: | Height: | Size: 148 KiB |
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 35 KiB |
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 62 KiB |
Before Width: | Height: | Size: 160 KiB After Width: | Height: | Size: 181 KiB |
@@ -21,30 +21,60 @@ include <../utils/core/core.scad>
|
||||
use <../vitamins/rod.scad>
|
||||
include <../vitamins/sheets.scad>
|
||||
|
||||
module polyholes() {
|
||||
module positions()
|
||||
for(i = [1 : 10]) {
|
||||
translate([(i * i + i) / 2 + 3 * i , 8])
|
||||
let($r = i / 2)
|
||||
module positions()
|
||||
for(i = [1 : 10]) {
|
||||
translate([(i * i + i) / 2 + 3 * i , 8])
|
||||
let($r = i / 2)
|
||||
children();
|
||||
|
||||
let(d = i + 0.5)
|
||||
translate([(d * d + d) / 2 + 3 * d, 19])
|
||||
let($r = d / 2)
|
||||
children();
|
||||
}
|
||||
|
||||
let(d = i + 0.5)
|
||||
translate([(d * d + d) / 2 + 3 * d, 19])
|
||||
let($r = d / 2)
|
||||
children();
|
||||
}
|
||||
module polyhole_stl() {
|
||||
stl("polyhole");
|
||||
|
||||
stl_colour(pp1_colour) linear_extrude(3, center = true)
|
||||
linear_extrude(3, center = true)
|
||||
difference() {
|
||||
square([100, 27]);
|
||||
|
||||
positions()
|
||||
poly_circle(r = $r);
|
||||
}
|
||||
}
|
||||
|
||||
positions()
|
||||
module alt_polyhole_stl() {
|
||||
holes = [2.5, 2, 1.5];
|
||||
n = len(holes);
|
||||
size = [n * 10, 10, 10];
|
||||
difference() {
|
||||
translate([-size.x / n / 2, $preview ? 0 : -size.y / 2])
|
||||
cube($preview ? [size.x, size.y / 2, size.z] : size);
|
||||
|
||||
for(i = [0 : n - 1])
|
||||
translate([i * 10, 0])
|
||||
if(i % 2)
|
||||
translate_z(size.z)
|
||||
poly_cylinder(r = holes[i] / 2, h = 2 * size.z, center = true, twist = i + 1);
|
||||
else
|
||||
poly_cylinder(r = holes[i] / 2, h = size.z, center = false, twist = i + 1);
|
||||
}
|
||||
}
|
||||
|
||||
module polyholes() {
|
||||
stl_colour(pp1_colour)
|
||||
polyhole_stl();
|
||||
|
||||
positions()
|
||||
rod(d = 2 * $r, l = 8 * $r + 5);
|
||||
//
|
||||
// Alternating polyholes
|
||||
//
|
||||
translate([30, -40])
|
||||
alt_polyhole_stl();
|
||||
//
|
||||
// Poly rings
|
||||
//
|
||||
ir = 3 / 2;
|
||||
@@ -74,4 +104,11 @@ module polyholes() {
|
||||
}
|
||||
}
|
||||
|
||||
polyholes();
|
||||
if($preview)
|
||||
polyholes();
|
||||
else {
|
||||
polyhole_stl();
|
||||
|
||||
translate([50, -20])
|
||||
alt_polyhole_stl();
|
||||
}
|
||||
|
71
tests/press_fit.scad
Normal file
@@ -0,0 +1,71 @@
|
||||
//
|
||||
// NopSCADlib Copyright Chris Palmer 2020
|
||||
// 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/>.
|
||||
//
|
||||
|
||||
include <../printed/press_fit.scad>
|
||||
|
||||
module press_fits()
|
||||
{
|
||||
thickness = 2;
|
||||
width = 20;
|
||||
vthickness = 4;
|
||||
|
||||
translate([0, width + 2])
|
||||
difference() {
|
||||
cube([width, width, thickness]);
|
||||
|
||||
for(x = [0.25, 0.75])
|
||||
for(y = [0.25, 0.75])
|
||||
translate([x * width, y * width])
|
||||
press_fit_socket();
|
||||
}
|
||||
|
||||
union() {
|
||||
cube([width, width, thickness]);
|
||||
|
||||
for(x = [0.25, 0.75])
|
||||
for(y = [0.25, 0.75])
|
||||
translate([x * width, y * width, thickness])
|
||||
press_fit_peg(h = thickness);
|
||||
}
|
||||
|
||||
translate([width + 2, width + 2])
|
||||
difference() {
|
||||
cube([width, vthickness, width]);
|
||||
|
||||
for(x = [0.25, 0.75])
|
||||
for(y = [0.25, 0.75])
|
||||
translate([x, 0, y] * width)
|
||||
rotate([90, 0, 0])
|
||||
press_fit_socket();
|
||||
}
|
||||
|
||||
translate([width + 2, 0])
|
||||
union() {
|
||||
cube([width, width, thickness]);
|
||||
|
||||
for(x = [0.25, 0.75])
|
||||
for(y = [0.25, 0.75])
|
||||
translate([x * width, y * width, thickness])
|
||||
press_fit_peg(h = vthickness, horizontal = true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
press_fits();
|
@@ -23,6 +23,7 @@ use <../utils/layout.scad>
|
||||
use <../vitamins/nut.scad>
|
||||
|
||||
sheet = 3;
|
||||
pos = 1; //[-1 : 0.1 : 1]
|
||||
|
||||
module rails()
|
||||
layout([for(l = rails) carriage_width(rail_carriage(l))], 20)
|
||||
@@ -33,7 +34,7 @@ module rails()
|
||||
nut = screw_nut(screw);
|
||||
washer = screw_washer(screw);
|
||||
|
||||
rail_assembly(rail, length, rail_travel(rail, length) / 2, $i<2 ? grey(20) : "green", $i<2 ? grey(20) : "red");
|
||||
rail_assembly(rail, length, pos * rail_travel(rail, length) / 2, $i<2 ? grey(20) : "green", $i<2 ? grey(20) : "red");
|
||||
|
||||
rail_screws(rail, length, sheet + nut_thickness(nut, true) + washer_thickness(washer));
|
||||
|
||||
|
@@ -18,20 +18,46 @@
|
||||
//
|
||||
include <../core.scad>
|
||||
|
||||
module screws()
|
||||
for(y = [0 : len(screw_lists) -1])
|
||||
for(x = [0 : len(screw_lists[y]) -1]) {
|
||||
screw = screw_lists[y][x];
|
||||
if(screw) {
|
||||
length = screw_head_type(screw) == hs_grub ? 6
|
||||
: screw_radius(screw) <= 1.5 ? 10
|
||||
: screw_max_thread(screw) ? screw_longer_than(screw_max_thread(screw) + 5)
|
||||
: 30;
|
||||
translate([x * 20, y * 20])
|
||||
screw(screw, length);
|
||||
}
|
||||
module polysink_stl() {
|
||||
stl("polysink");
|
||||
|
||||
cs_screws = [for(list = screw_lists, screw = list) if(screw_head_type(screw) == hs_cs_cap) screw];
|
||||
n = len(cs_screws);
|
||||
size = [n * 20, 20, 10];
|
||||
difference() {
|
||||
translate([-size.x / n / 2, $preview ? 0 : -size.y / 2])
|
||||
cube($preview ? [size.x, size.y / 2, size.z] : size);
|
||||
|
||||
for(i = [0 : n - 1])
|
||||
let(s = cs_screws[i])
|
||||
translate([i * 20, 0]) {
|
||||
translate_z(size.z)
|
||||
screw_polysink(s, 2 * size.z + 1);
|
||||
|
||||
screw_polysink(s, 2 * size.z + 1, alt = true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module screws() {
|
||||
for(y = [0 : len(screw_lists) -1])
|
||||
for(x = [0 : len(screw_lists[y]) -1]) {
|
||||
screw = screw_lists[y][x];
|
||||
if(screw) {
|
||||
length = screw_head_type(screw) == hs_grub ? 6
|
||||
: screw_radius(screw) <= 1.5 ? 10
|
||||
: screw_max_thread(screw) ? screw_longer_than(screw_max_thread(screw) + 5)
|
||||
: 30;
|
||||
translate([x * 20, y * 20])
|
||||
screw(screw, length);
|
||||
}
|
||||
}
|
||||
translate([80, 20])
|
||||
polysink_stl();
|
||||
}
|
||||
|
||||
if($preview)
|
||||
let($show_threads = true)
|
||||
screws();
|
||||
else
|
||||
polysink_stl();
|
||||
|
@@ -39,8 +39,8 @@ function r2sides4n(r) = floor((r2sides(r) + 3) / 4) * 4;
|
||||
function limit(x, min, max) = max(min(x, max), min); //! Force x in range min <= x <= max
|
||||
|
||||
module translate_z(z) translate([0, 0, z]) children(); //! Shortcut for Z only translations
|
||||
module vflip() rotate([180, 0, 0]) children(); //! Invert children by doing a 180° flip around the X axis
|
||||
module hflip() rotate([0, 180, 0]) children(); //! Invert children by doing a 180° flip around the Y axis
|
||||
module vflip(flip=true) rotate([flip ? 180 : 0, 0, 0]) children(); //! Invert children by doing a 180° flip around the X axis
|
||||
module hflip(flip=true) rotate([0, flip ? 180: 0, 0]) children(); //! Invert children by doing a 180° flip around the Y axis
|
||||
module ellipse(xr, yr) scale([1, yr / xr]) circle4n(xr); //! Draw an ellipse
|
||||
|
||||
function slice_str(str, start, end, s ="") = start >= end ? s : slice_str(str, start + 1, end, str(s, str[start])); // Helper for slice()
|
||||
|
@@ -22,6 +22,16 @@
|
||||
//! it gets the linear dimensions right. See <https://hydraraptor.blogspot.com/2011/02/polyholes.html>
|
||||
//!
|
||||
//! The module provides `poly_circle()`, `poly_cylinder()` and `poly_ring()` that is useful for making printed washers and pillars.
|
||||
//!
|
||||
//! `poly_cylinder()` has a `twist` parameter which can be set to make the polygon rotate each layer.
|
||||
//! This can be used to mitigate the number of sides being small and make small holes stronger and more round, but is quite slow due to the
|
||||
//! large increase in the number of facets.
|
||||
//! When set to 1 the polygons alternate each layer, when set higher the rotation takes `twist + 1` layers to repeat.
|
||||
//! A small additional rotation is added to make the polygon rotate one more side over the length of the hole to make it appear round when
|
||||
//! veiwed end on.
|
||||
//!
|
||||
//! When `twist` is set the resulting cylinder is extended by `eps` at each end so that the exact length of the hole can be used without
|
||||
//! leaving a scar on either surface.
|
||||
//
|
||||
function sides(r) = max(round(4 * r), 3); //! Optimium number of sides for specified radius
|
||||
function corrected_radius(r, n = 0) = r / cos(180 / (n ? n : sides(r))); //! Adjusted radius to make flats lie on the circle
|
||||
@@ -32,9 +42,26 @@ module poly_circle(r, sides = 0) { //! Make a circle adjusted to print the corre
|
||||
circle(r = corrected_radius(r,n), $fn = n);
|
||||
}
|
||||
|
||||
module poly_cylinder(r, h, center = false, sides = 0, chamfer = false) {//! Make a cylinder adjusted to print the correct size
|
||||
extrude_if(h, center)
|
||||
poly_circle(r, sides);
|
||||
module poly_cylinder(r, h, center = false, sides = 0, chamfer = false, twist = 0) {//! Make a cylinder adjusted to print the correct size
|
||||
if(twist) {
|
||||
slices = ceil(h / layer_height);
|
||||
twist = min(twist, slices - 1);
|
||||
sides = sides ? sides : sides(r);
|
||||
rot = 360 / sides / (twist + 1) * (1 + 1 / slices);
|
||||
if(center)
|
||||
for(side = [0, 1])
|
||||
mirror([0, 0, side])
|
||||
poly_cylinder(r = r, h = h / 2, sides = sides, twist = twist);
|
||||
else
|
||||
render(convexity = 5)
|
||||
for(i = [0 : slices - 1])
|
||||
translate_z(i * layer_height - eps)
|
||||
rotate(rot * i)
|
||||
poly_cylinder(r = r, h = layer_height + 2 * eps, sides = sides);
|
||||
}
|
||||
else
|
||||
extrude_if(h, center)
|
||||
poly_circle(r, sides);
|
||||
|
||||
if(h && chamfer)
|
||||
poly_cylinder(r + layer_height, center ? layer_height * 2 : layer_height, center, sides = sides ? sides : sides(r));
|
||||
|
@@ -35,7 +35,7 @@ module hanging_hole(z, ir, h = 100, h2 = 100) { //! Hole radius ```ir``` hanging
|
||||
poly_cylinder(r - eps, h - layer_height);
|
||||
}
|
||||
}
|
||||
assert(z % layer_height == 0, str(z));
|
||||
assert(z - layer_height * floor(z / layer_height) < eps, str(z));
|
||||
infill_angle = z % (2 * layer_height) ? -45 : 45;
|
||||
below = min(z + eps, h2);
|
||||
big = 1000;
|
||||
|
@@ -60,7 +60,7 @@ function rounded_polygon_length(points, tangents) = //! Calculate the length giv
|
||||
v1 = p1 - c,
|
||||
v2 = p2 - c,
|
||||
r = abs(corner.z),
|
||||
a = acos((v1 * v2) / sqr(r))) PI * (cross(v1,v2) <= 0 ? a : 360 - a) * r / 180]
|
||||
a = acos((v1 * v2) / sqr(r))) r ? PI * (cross(v1, v2) <= 0 ? a : 360 - a) * r / 180 : 0]
|
||||
)
|
||||
sumv(concat(straights, arcs));
|
||||
|
||||
|
@@ -21,7 +21,7 @@
|
||||
//! Utility to generate a polhedron by sweeping a 2D profile along a 3D path and utilities for generating paths.
|
||||
//!
|
||||
//! The initial orientation is the Y axis of the profile points towards the initial center of curvature, Frenet-Serret style.
|
||||
//! This means the first three points must not be colinear. Subsequent rotations use the minimum rotation method.
|
||||
//! Subsequent rotations use the minimum rotation method.
|
||||
//!
|
||||
//! The path can be open or closed. If closed sweep ensures that the start and end have the same rotation to line up.
|
||||
//! An additional twist around the path can be specified. If the path is closed this should be a multiple of 360.
|
||||
|
@@ -19,7 +19,7 @@
|
||||
|
||||
//
|
||||
//! Models timing belt running over toothed or smooth pulleys and calculates an accurate length.
|
||||
//! Only models 2D paths, so not core XY!
|
||||
//! Only models 2D paths, so not crossed belt core XY!
|
||||
//!
|
||||
//! To make the back of the belt run against a smooth pulley on the outside of the loop specify a negative pitch radius.
|
||||
//!
|
||||
@@ -54,7 +54,7 @@ module belt(type, points, gap = 0, gap_pos = undef, belt_colour = grey(20), toot
|
||||
|
||||
tangents = rounded_polygon_tangents(points);
|
||||
|
||||
length = ceil((rounded_polygon_length(points, tangents) - gap) / pitch) * pitch;
|
||||
length = ceil((rounded_polygon_length(points, tangents) - (is_list(gap) ? gap.x + gap.y : gap)) / pitch) * pitch;
|
||||
|
||||
module shape() rounded_polygon(points, tangents);
|
||||
|
||||
@@ -65,7 +65,7 @@ module belt(type, points, gap = 0, gap_pos = undef, belt_colour = grey(20), toot
|
||||
translate([gap_pos.x, gap_pos.y])
|
||||
rotate(is_undef(gap_pos.z) ? 0 : gap_pos.z)
|
||||
translate([0, ph - thickness / 2])
|
||||
square([gap, thickness + eps], center = true);
|
||||
square(is_list(gap) ? [gap.x, gap.y + thickness + eps] : [gap, thickness + eps], center = true);
|
||||
|
||||
color(belt_colour)
|
||||
linear_extrude(width, center = true)
|
||||
|
@@ -22,6 +22,8 @@
|
||||
//
|
||||
include <../utils/core/core.scad>
|
||||
use <../utils/rounded_cylinder.scad>
|
||||
use <../utils/quadrant.scad>
|
||||
use <screw.scad>
|
||||
|
||||
function blower_length(type) = type[2]; //! Length of enclosing rectangle
|
||||
function blower_width(type) = type[3]; //! Width of enclosing rectangle
|
||||
@@ -39,8 +41,87 @@ function blower_top(type) = type[14]; //! Thickness of the top
|
||||
function blower_wall(type) = type[15]; //! Side wall thickness
|
||||
function blower_lug(type) = type[16]; //! Height of the lugs
|
||||
|
||||
function blower_casing_is_square(type) = len(blower_screw_holes(type)) > 3; //! True for square radial fans, false for spiral shape radial blowers
|
||||
function blower_exit_offset(type) = blower_casing_is_square(type) ? blower_length(type) / 2 : blower_exit(type) / 2; //! Offset of exit's centre from the edge
|
||||
|
||||
fan_colour = grey(20);
|
||||
|
||||
module blower_fan(type, casing_is_square) {
|
||||
module squarish(s, n) {
|
||||
polygon([
|
||||
for(i = [0 : n]) [i * s.x / n, s.y + (i % 2) * eps],
|
||||
for(i = [0 : n]) [s.x - i * s.x / n, (i % 2) * eps],
|
||||
]);
|
||||
}
|
||||
|
||||
depth = blower_depth(type);
|
||||
blade_ir = blower_hub(type) / 2 + 0.5; // slight gap between main part of blades and hub
|
||||
blade_len = casing_is_square
|
||||
? (blower_bore(type) - 1) / 2 - blade_ir // fan constrained by bore hole
|
||||
: blower_width(type) - blower_axis(type).x- blower_wall(type) - blade_ir; // fan extends to casing
|
||||
blade_thickness = 0.75;
|
||||
blade_count = 25;
|
||||
|
||||
base_offset = 1;
|
||||
translate([blower_axis(type).x, blower_axis(type).y, blower_base(type) + base_offset])
|
||||
linear_extrude(blower_hub_height(type) - 0.5 - blower_base(type) - base_offset, center = false, convexity = 4, twist = -30, slices = round(depth / 2))
|
||||
for(i = [0 : blade_count - 1])
|
||||
rotate((360 * i) / blade_count)
|
||||
translate([blade_ir, -blade_thickness / 2])
|
||||
squarish([blade_len, blade_thickness], round(blade_len / 2));
|
||||
}
|
||||
|
||||
module blower_square(type) { //! Draw a square blower
|
||||
width = blower_width(type);
|
||||
depth = blower_depth(type);
|
||||
wall = blower_wall(type);
|
||||
hole_pitch = (blower_screw_holes(type)[1].x - blower_screw_holes(type)[0].x) / 2;
|
||||
corner_radius = width / 2 - hole_pitch;
|
||||
corner_inset = (width - blower_exit(type)) / 2;
|
||||
|
||||
module square_inset_corners(remove_center = false)
|
||||
difference() {
|
||||
//overall outside
|
||||
square([width, width], center = false);
|
||||
|
||||
if (remove_center) {
|
||||
// cut out the inside, leaving the corners
|
||||
translate([corner_inset + wall, -eps])
|
||||
square([width - 2 * (wall + corner_inset), width - wall + eps], center = false);
|
||||
|
||||
translate([wall, corner_inset + wall])
|
||||
square([width - 2 * wall, width - 2 * (wall + corner_inset)], center = false);
|
||||
} else {
|
||||
// cut out the bore for the fan
|
||||
translate(blower_axis(type))
|
||||
circle(d = blower_bore(type));
|
||||
}
|
||||
// corner inset
|
||||
translate([width / 2, width / 2])
|
||||
for(i = [0 : 3])
|
||||
rotate(i * 90)
|
||||
translate([-width / 2 - eps, -width/ 2 - eps])
|
||||
quadrant(corner_inset, corner_inset - corner_radius);
|
||||
}
|
||||
|
||||
base_height = blower_base(type);
|
||||
linear_extrude(base_height)
|
||||
difference () {
|
||||
rounded_square([width, width], corner_radius, center = false);
|
||||
|
||||
blower_hole_positions(type)
|
||||
circle(d = blower_screw_hole(type));
|
||||
}
|
||||
|
||||
translate_z(base_height)
|
||||
linear_extrude(depth - base_height)
|
||||
square_inset_corners(remove_center = true);
|
||||
|
||||
translate_z(depth - base_height)
|
||||
linear_extrude(blower_top(type))
|
||||
square_inset_corners();
|
||||
}
|
||||
|
||||
module blower(type) { //! Draw specified blower
|
||||
length = blower_length(type);
|
||||
width = blower_width(type);
|
||||
@@ -70,55 +151,63 @@ module blower(type) { //! Draw specified blower
|
||||
|
||||
vitamin(str("blower(", type[0], "): ", type[1]));
|
||||
|
||||
is_square = blower_casing_is_square(type); // Description starts with square!
|
||||
color(fan_colour) {
|
||||
// screw lugs
|
||||
linear_extrude(blower_lug(type), center = false)
|
||||
for(hole = blower_screw_holes(type))
|
||||
difference() {
|
||||
hull() {
|
||||
if (is_square) {
|
||||
blower_square(type);
|
||||
} else {
|
||||
// screw lugs
|
||||
linear_extrude(blower_lug(type), center = false)
|
||||
for(hole = blower_screw_holes(type))
|
||||
difference() {
|
||||
hull() {
|
||||
translate(hole)
|
||||
circle(d = blower_screw_hole(type) + 2 * blower_wall(type));
|
||||
|
||||
translate(blower_axis(type))
|
||||
circle(d = blower_screw_hole(type) + 2 * blower_wall(type) + 7);
|
||||
}
|
||||
translate(hole)
|
||||
circle(d = blower_screw_hole(type) + 2 * blower_wall(type));
|
||||
circle(d = blower_screw_hole(type));
|
||||
|
||||
translate(blower_axis(type))
|
||||
circle(d = blower_screw_hole(type) + 2 * blower_wall(type) + 7);
|
||||
}
|
||||
translate(hole)
|
||||
circle(d = blower_screw_hole(type));
|
||||
shape(true);
|
||||
}
|
||||
|
||||
shape(true);
|
||||
}
|
||||
// rotor
|
||||
translate(concat(blower_axis(type), [blower_base(type) + 1]))
|
||||
rounded_cylinder(r = blower_hub(type) / 2, h = blower_hub_height(type) - blower_base(type) - 1, r2 = 1);
|
||||
*%square([length, width]);
|
||||
|
||||
*%square([length, width]);
|
||||
|
||||
// base
|
||||
linear_extrude(blower_base(type))
|
||||
difference() {
|
||||
shape();
|
||||
|
||||
translate(concat(blower_axis(type), [blower_base(type)]))
|
||||
circle(d = 2);
|
||||
}
|
||||
// sides
|
||||
linear_extrude(depth)
|
||||
difference() {
|
||||
shape();
|
||||
|
||||
offset(-blower_wall(type))
|
||||
shape(true);
|
||||
}
|
||||
|
||||
// top
|
||||
translate_z(depth -blower_top(type))
|
||||
linear_extrude(blower_top(type))
|
||||
// base
|
||||
linear_extrude(blower_base(type))
|
||||
difference() {
|
||||
shape();
|
||||
|
||||
translate(concat(blower_axis(type), [blower_base(type)]))
|
||||
circle(d = blower_bore(type));
|
||||
}
|
||||
circle(d = 2);
|
||||
}
|
||||
|
||||
// sides
|
||||
linear_extrude(depth)
|
||||
difference() {
|
||||
shape();
|
||||
|
||||
offset(-blower_wall(type))
|
||||
shape(true);
|
||||
}
|
||||
|
||||
// top
|
||||
translate_z(depth -blower_top(type))
|
||||
linear_extrude(blower_top(type))
|
||||
difference() {
|
||||
shape();
|
||||
|
||||
translate(concat(blower_axis(type), [blower_base(type)]))
|
||||
circle(d = blower_bore(type));
|
||||
}
|
||||
}
|
||||
// rotor
|
||||
translate(concat(blower_axis(type), [blower_base(type) + 1]))
|
||||
rounded_cylinder(r = blower_hub(type) / 2, h = blower_hub_height(type) - blower_base(type) - 1, r2 = 1);
|
||||
|
||||
blower_fan(type, is_square);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -16,10 +16,16 @@
|
||||
// You should have received a copy of the GNU General Public License along with NopSCADlib.
|
||||
// If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
// l w d b s h a s s e h b t w l
|
||||
// e i e o c u x c c x u a o a u
|
||||
// n d p r r b i r r i b s p l g
|
||||
// g t t e e s e e t e l
|
||||
// t h h w d w w t
|
||||
// h h s t t
|
||||
RB5015 = ["RB5015", "Blower Runda RB5015", 51.3, 51, 15, 31.5, M4_cap_screw, 26, [27.3, 25.4], 4.5, [[4.3, 45.4], [47.3,7.4]], 20, 14, 1.5, 1.3, 1.2, 15];
|
||||
PE4020 = ["PE4020", "Blower Pengda Technology 4020", 40, 40, 20, 27.5, M3_cap_screw, 22, [21.5, 20 ], 3.2, [[37,3],[3,37],[37,37]], 29.3, 17, 1.7, 1.2, 1.3, 13];
|
||||
BL40x10 =["BL40x10","Square radial 4010", 40, 40,9.5, 27, M2_cap_screw, 16, [24, 20 ], 2.4, [[2,2],[38,2],[2,38],[38,38]], 30 , 9.5, 1.5, 1.5, 1.1, 1.5];
|
||||
|
||||
RB5015 = ["RB5015", "Blower Runda RB5015", 51.3, 51, 15, 31.5, M4_cap_screw, 26, [27.3, 25.4], 4.5, [[4.3, 45.4], [47.3,7.4]], 20, 14, 1.5, 1.3, 1.2, 15];
|
||||
PE4020 = ["PE4020", "Blower Pengda Technology 4020", 40, 40, 20, 27.5, M3_cap_screw, 22, [21.5, 20 ], 3.2, [[37,3],[3,37],[37,37]], 29.3, 17, 1.7, 1.2, 1.3, 13];
|
||||
|
||||
blowers = [PE4020, RB5015];
|
||||
blowers = [BL40x10, PE4020, RB5015];
|
||||
|
||||
use <blower.scad>
|
||||
|
@@ -29,7 +29,7 @@ function camera_lens(type) = type[4]; //! Stack of lens parts, can be r
|
||||
function camera_connector_pos(type) = type[5]; //! The flex connector block for the camera itself's position
|
||||
function camera_connector_size(type)= type[6]; //! The flex connector block for the camera itself's size
|
||||
|
||||
module camera_lens(type, offset = 0) //! Draw the lens stack, with optional offset for making a clearance hole
|
||||
module camera_lens(type, offset = 0, show_lens = true) //! Draw the lens stack, with optional offset for making a clearance hole
|
||||
color(grey(20))
|
||||
translate(camera_lens_offset(type))
|
||||
for(p = camera_lens(type)) {
|
||||
@@ -39,24 +39,25 @@ module camera_lens(type, offset = 0) //! Draw the lens stack, with optional offs
|
||||
if(size.x)
|
||||
rounded_rectangle(size + [2 * offset, 2 * offset, round_to_layer(offset)], r, center = false);
|
||||
else
|
||||
translate_z(size.y)
|
||||
rotate_extrude()
|
||||
difference() {
|
||||
square([r, size.z + round_to_layer(offset)]);
|
||||
if (show_lens)
|
||||
translate_z(size.y)
|
||||
rotate_extrude()
|
||||
difference() {
|
||||
square([r, size.z + round_to_layer(offset)]);
|
||||
|
||||
if(app)
|
||||
translate([0, size.z])
|
||||
hull() {
|
||||
translate([0, -eps])
|
||||
square([app.y, eps * 2]);
|
||||
if(app)
|
||||
translate([0, size.z])
|
||||
hull() {
|
||||
translate([0, -eps])
|
||||
square([app.y, eps * 2]);
|
||||
|
||||
translate([0, -app.z])
|
||||
square([app.x, app.z]);
|
||||
}
|
||||
}
|
||||
translate([0, -app.z])
|
||||
square([app.x, app.z]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module camera(type) { //! Draw specified PCB camera
|
||||
module camera(type, show_lens = true) { //! Draw specified PCB camera
|
||||
vitamin(str("camera(", type[0], "): ", type[1]));
|
||||
pcb = camera_pcb(type);
|
||||
|
||||
@@ -64,7 +65,7 @@ module camera(type) { //! Draw specified PCB camera
|
||||
pcb(pcb);
|
||||
|
||||
translate_z(pcb_thickness(pcb)) {
|
||||
camera_lens(type);
|
||||
camera_lens(type, show_lens = show_lens);
|
||||
|
||||
conn = camera_connector_size(type);
|
||||
if(conn) {
|
||||
|
@@ -73,6 +73,42 @@ SSD1963_4p3 = ["SSD1963_4p3", "LCD display SSD1963 4.3\"", 105.5, 67.2, 3.4, SSD
|
||||
[[0, -34.5], [12, -31.5]],
|
||||
];
|
||||
|
||||
displays = [HDMI5, SSD1963_4p3, LCD1602A, LCDS7282B];
|
||||
BigTreeTech_TFT35v3_0_PCB = ["", "",
|
||||
110, 55.77, 1.6, 0, 3, 0, "green", false,
|
||||
[ [-3.12, 3.17], [-3.12, -3.17], [3.12, -3.17], [3.12, 3.17] ],
|
||||
[
|
||||
[ 10, 7.5, 0, "-button_6mm" ],
|
||||
[ 9, 43, 0, "-buzzer", 5, 9 ],
|
||||
[ 9, 27, 0, "-potentiometer" ],
|
||||
[ 102,28.82, 0, "uSD", [26.5, 16, 3] ],
|
||||
[16.5, 5.9, 0, "2p54boxhdr", 5, 2 ],
|
||||
[36.5, 5.9, 0, "2p54boxhdr", 5, 2 ],
|
||||
[56.5, 5.9, 0, "2p54boxhdr", 5, 2 ],
|
||||
[82.5, 4, 0, "jst_xh", 5 ],
|
||||
[26.5, 52.8, 180, "jst_xh", 2 ],
|
||||
[39.5, 52.8, 180, "jst_xh", 3 ],
|
||||
[52.5, 52.8, 180, "jst_xh", 3 ],
|
||||
[65.5, 52.8, 180, "jst_xh", 3 ],
|
||||
[78.5, 52.8, 180, "jst_xh", 3 ],
|
||||
[94.5, 52.8, 180, "jst_xh", 5 ],
|
||||
[ 8, 43, 180, "usb_A" ],
|
||||
[ 97, 4, 0, "chip", 9, 3.5, 1, grey(20) ],
|
||||
// ESP-8266
|
||||
[ 23, 28, 90, "2p54socket", 4, 2 ],
|
||||
],
|
||||
[]
|
||||
];
|
||||
|
||||
BigTreeTech_TFT35v3_0 = ["BigTreeTech_TFT35v3_0", "BigTreeTech TFT35 v3.0",
|
||||
84.5, 54.5, 4, BigTreeTech_TFT35v3_0_PCB,
|
||||
[-6, 0, 0], // pcb offset
|
||||
[[-40, -26.5], [41.5, 26.5, 0.5]], // aperture
|
||||
[], // touch screen
|
||||
0, // thread length
|
||||
[], // clearance need for the ts ribbon
|
||||
];
|
||||
|
||||
|
||||
displays = [HDMI5, SSD1963_4p3, BigTreeTech_TFT35v3_0, LCD1602A, LCDS7282B];
|
||||
|
||||
use <display.scad>
|
||||
|
@@ -29,7 +29,7 @@
|
||||
// d d h d d
|
||||
// d
|
||||
//
|
||||
F1BM2 = [ "F1BM2", 4.0, 3.6, 3.2, 2, 3.0, 1.0, 3.4, 3.1 ];
|
||||
F1BM2 = [ "F1BM2", 4.0, 3.6, 3.2, 2, 3.0, 1.0, 3.4, 3.1 ];
|
||||
F1BM2p5 = [ "F1BM2p5", 5.8, 4.6, 4.0, 2.5, 3.65, 1.6, 4.4, 3.9 ];
|
||||
F1BM3 = [ "F1BM3", 5.8, 4.6, 4.0, 3, 3.65, 1.6, 4.4, 3.9 ];
|
||||
F1BM4 = [ "F1BM4", 8.2, 6.3, 5.6, 4, 5.15, 2.3, 6.0, 5.55 ];
|
||||
|
@@ -116,7 +116,7 @@ module mains_socket(type) { //! Draw specified 13A socket
|
||||
cylinder(r = screw_clearance_radius(screw), h = 100, center = true);
|
||||
|
||||
translate_z(height)
|
||||
screw_countersink(screw);
|
||||
screw_countersink(screw, drilled = false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -46,12 +46,16 @@ function carriage_pitch_y(type) = type[6]; //! Screw hole y pitch
|
||||
function carriage_screw(type) = type[7]; //! Carriage screw type
|
||||
function carriage_screw_depth(type) = 2 * screw_radius(carriage_screw(type)); //! Carriage thread depth
|
||||
|
||||
function rail_holes(type, length) = //! Number of holes in a rail given its ```length```
|
||||
floor((length - 2 * rail_end(type)) / rail_pitch(type)) + 1;
|
||||
|
||||
module rail_hole_positions(type, length, first = 0, screws = 100, both_ends = true) { //! Position children over screw holes
|
||||
pitch = rail_pitch(type);
|
||||
holes = floor((length - 2 * rail_end(type)) / pitch) + 1;
|
||||
for(i = [first : holes - 1 - first])
|
||||
if(i < screws || (holes - i <= screws && both_ends))
|
||||
translate([i * pitch - length / 2 + (length - (holes -1) * pitch) / 2, 0, 0])
|
||||
holes = rail_holes(type, length);
|
||||
last = first + screws;
|
||||
for(i = [first : holes - 1], j = holes - 1 - i)
|
||||
if(i < last || both_ends && (j >= first && j < last))
|
||||
translate([i * pitch - length / 2 + (length - (holes - 1) * pitch) / 2, 0])
|
||||
children();
|
||||
}
|
||||
|
||||
@@ -104,24 +108,27 @@ module carriage(type, rail, end_colour = grey(20), wiper_colour = grey(20)) { //
|
||||
|
||||
module carriage_end(type, end_w, end_h, end_l) {
|
||||
wiper_length = 0.5;
|
||||
color(wiper_colour) translate_z(-end_l/2) linear_extrude(wiper_length)
|
||||
color(wiper_colour) translate_z(-end_l / 2) linear_extrude(wiper_length)
|
||||
difference() {
|
||||
translate([-end_w/2, carriage_clearance(type)])
|
||||
translate([-end_w / 2, carriage_clearance(type)])
|
||||
square([end_w, end_h]);
|
||||
|
||||
cutout();
|
||||
}
|
||||
color(end_colour) translate_z(wiper_length-end_l/2) linear_extrude(end_l-wiper_length)
|
||||
color(end_colour) translate_z(wiper_length-end_l / 2) linear_extrude(end_l - wiper_length)
|
||||
difference() {
|
||||
translate([-end_w/2, carriage_clearance(type)])
|
||||
translate([-end_w / 2, carriage_clearance(type)])
|
||||
square([end_w, end_h]);
|
||||
|
||||
cutout();
|
||||
}
|
||||
}
|
||||
|
||||
translate([-(block_l+end_l)/2,0,0])
|
||||
translate([-(block_l + end_l) / 2, 0])
|
||||
rotate([90, 0, 90])
|
||||
carriage_end(type, end_w, end_h, end_l);
|
||||
translate([(block_l+end_l)/2,0,0])
|
||||
|
||||
translate([(block_l + end_l) / 2, 0])
|
||||
rotate([90, 0, -90])
|
||||
carriage_end(type, end_w, end_h, end_l);
|
||||
}
|
||||
@@ -171,7 +178,6 @@ module rail_assembly(type, length, pos, carriage_end_colour = grey(20), carriage
|
||||
|
||||
translate([pos, 0])
|
||||
carriage(rail_carriage(type), type, carriage_end_colour, carriage_wiper_colour);
|
||||
|
||||
}
|
||||
|
||||
module rail_screws(type, length, thickness, screws = 100) { //! Place screws in the rail
|
||||
@@ -187,6 +193,6 @@ module rail_screws(type, length, thickness, screws = 100) { //! Place screws in
|
||||
screw(end_screw, end_screw_len);
|
||||
|
||||
translate_z(rail_screw_height(type, screw))
|
||||
rail_hole_positions(type, length, index_screws, screws)
|
||||
rail_hole_positions(type, length, index_screws, min(screws, rail_holes(type, length)) - 2 * index_screws)
|
||||
screw(screw, screw_len);
|
||||
}
|
||||
|
@@ -33,11 +33,11 @@ SSR15_carriage = [ 40.3, 23.3, 34, 24, 4.5, 0, 26, M4_cap_screw ];
|
||||
//
|
||||
//
|
||||
// Wr Hr E P D d h
|
||||
MGN5 = [ "MGN5", 5, 3.6, 5, 15, 3.5, 2.4, 0.8, M2_cs_cap_screw, MGN5_carriage, M2_cs_cap_screw ]; // Screw holes too small for M2 heads
|
||||
MGN5 = [ "MGN5", 5, 3.6, 5, 15, 3.6, 2.4, 0.8, M2_cs_cap_screw, MGN5_carriage, M2_cs_cap_screw ]; // Screw holes too small for M2 heads
|
||||
MGN7 = [ "MGN7", 7, 5, 5, 15, 4.3, 2.4, 2.6, M2_cap_screw, MGN7_carriage, M2_cs_cap_screw ];
|
||||
MGN9 = [ "MGN9", 9, 6, 7.5, 20, 6.0, 3.5, 3.5, M3_cap_screw, MGN9_carriage, M3_cs_cap_screw ];
|
||||
MGN12= [ "MGN12", 12, 8, 10, 25, 6.0, 3.5, 4.5, M3_cap_screw, MGN12_carriage, M3_cs_cap_screw ];
|
||||
MGN12H=[ "MGN12H",12, 8, 10, 25, 6.0, 3.5, 4.5, M3_cap_screw, MGN12H_carriage,M3_cs_cap_screw ];
|
||||
MGN12H=[ "MGN12H",12, 8, 10, 25, 6.0, 3.5, 4.5, M3_cap_screw, MGN12H_carriage,M3_cs_cap_screw ];
|
||||
MGN15= [ "MGN15", 15, 10, 10, 40, 6.0, 3.5, 5.0, M3_cap_screw, MGN15_carriage, M3_cs_cap_screw ];
|
||||
SSR15= [ "SSR15", 15, 12.5,10, 60, 7.5, 4.5, 5.3, M4_cap_screw, SSR15_carriage, M4_cs_cap_screw ];
|
||||
|
||||
|
@@ -19,6 +19,8 @@
|
||||
|
||||
//
|
||||
//! 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>
|
||||
|
||||
@@ -41,9 +43,13 @@ function screw_pilot_hole(type) = type[11]; //! Pilot hole radius for w
|
||||
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) = screw_head_height(type) ? 0 : screw_head_radius(type) - d / 2; //! How far a counter sink head will go into a straight hole diameter d
|
||||
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 shortest screw length longer or equal to x
|
||||
x <= 6 ? 6 :
|
||||
x <= 8 ? 8 :
|
||||
x <= 10 ? 10 :
|
||||
x <= 12 ? 12 :
|
||||
@@ -109,6 +115,27 @@ module screw(type, length, hob_point = 0, nylon = false) { //! Draw specified sc
|
||||
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) {
|
||||
@@ -201,63 +228,76 @@ module screw(type, length, hob_point = 0, nylon = false) { //! Draw specified sc
|
||||
}
|
||||
|
||||
if(head_type == hs_cs) {
|
||||
head_height = head_rad;
|
||||
socket_rad = 0.6 * head_rad;
|
||||
socket_depth = 0.3 * head_rad;
|
||||
socket_width = 1;
|
||||
color(colour) {
|
||||
rotate_extrude()
|
||||
difference() {
|
||||
polygon([[0, 0], [head_rad, 0], [0, -head_height]]);
|
||||
color(colour)
|
||||
cs_head(socket_rad, socket_depth) {
|
||||
square([2 * socket_rad, socket_width], center = true);
|
||||
square([socket_width, 2 * socket_rad], center = true);
|
||||
}
|
||||
|
||||
translate([0, -socket_depth + eps])
|
||||
square([socket_rad + 0.1, 10]);
|
||||
}
|
||||
|
||||
translate_z(-socket_depth)
|
||||
linear_extrude(socket_depth)
|
||||
difference() {
|
||||
circle(socket_rad + 0.1);
|
||||
|
||||
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) {
|
||||
head_height = head_rad;
|
||||
color(colour) {
|
||||
rotate_extrude()
|
||||
difference() {
|
||||
polygon([[0, 0], [head_rad, 0], [0, -head_height]]);
|
||||
color(colour)
|
||||
cs_head(socket_rad, socket_depth)
|
||||
circle(socket_rad, $fn = 6);
|
||||
|
||||
translate([0, -socket_depth + eps])
|
||||
square([socket_rad, 10]);
|
||||
}
|
||||
|
||||
translate_z(-socket_depth)
|
||||
linear_extrude(socket_depth)
|
||||
difference() {
|
||||
circle(socket_rad + 0.1);
|
||||
|
||||
circle(socket_rad, $fn = 6);
|
||||
}
|
||||
}
|
||||
shaft(socket_depth);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module screw_countersink(type) { //! Countersink shape
|
||||
module screw_countersink(type, drilled = true) { //! Countersink shape
|
||||
head_type = screw_head_type(type);
|
||||
head_rad = screw_head_radius(type);
|
||||
head_height = head_rad;
|
||||
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)
|
||||
cylinder(h = head_height, r1 = 0, r2 = head_rad);
|
||||
if(drilled)
|
||||
cylinder(h = head_height + eps, r1 = 0, r2 = head_rad + head_t);
|
||||
else
|
||||
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) { //! A countersink hole made from stacked polyholes for printed parts
|
||||
head_depth = screw_head_depth(type);
|
||||
assert(head_depth, "Not a countersunk screw");
|
||||
layers = ceil(head_depth / 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);
|
||||
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);
|
||||
}
|
||||
|
||||
translate_z(layers * layer_height)
|
||||
poly_cylinder(r = rmin, h = h / 2 - layers * layer_height, 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
|
||||
|
@@ -107,14 +107,14 @@ No6_screw = ["No6", "No6 pan wood", hs_pan, 3.5, 6.7, 2.2, 0, 0
|
||||
No6_cs_screw = ["No6_cs", "No6 cs wood", hs_cs, 3.5, 7.0, 0, 0, 0, 0, M4_washer, false, No6_pilot_radius, No6_clearance_radius];
|
||||
|
||||
screw_lists = [
|
||||
[ M2_cap_screw, M2p5_cap_screw, M3_cap_screw, M4_cap_screw, M5_cap_screw, M6_cap_screw, M8_cap_screw],
|
||||
[ 0, 0, M3_low_cap_screw],
|
||||
[ 0, 0, M3_hex_screw, M4_hex_screw, M5_hex_screw, M6_hex_screw, M8_hex_screw],
|
||||
[ 0, M2p5_pan_screw, M3_pan_screw, M4_pan_screw, M5_pan_screw, M6_pan_screw, No632_pan_screw],
|
||||
[ 0, No2_screw, No4_screw, No6_screw, No6_cs_screw],
|
||||
[ 0, M2_cs_cap_screw,M3_cs_cap_screw, M4_cs_cap_screw],
|
||||
[ 0, M2_dome_screw, M3_dome_screw, M4_dome_screw],
|
||||
[ 0, 0, M3_grub_screw, M4_grub_screw]
|
||||
[ M2_cap_screw, M2p5_cap_screw, M3_cap_screw, M4_cap_screw, M5_cap_screw, M6_cap_screw, M8_cap_screw],
|
||||
[ 0, 0, M3_low_cap_screw],
|
||||
[ M2_cs_cap_screw, 0, M3_cs_cap_screw, M4_cs_cap_screw],
|
||||
[ M2_dome_screw, 0, M3_dome_screw, M4_dome_screw],
|
||||
[ 0, 0, M3_hex_screw, M4_hex_screw, M5_hex_screw, M6_hex_screw, M8_hex_screw],
|
||||
[ 0, M2p5_pan_screw, M3_pan_screw, M4_pan_screw, M5_pan_screw, M6_pan_screw, No632_pan_screw],
|
||||
[ No2_screw, 0, No4_screw, No6_screw, No6_cs_screw],
|
||||
[ 0, 0, M3_grub_screw, M4_grub_screw]
|
||||
];
|
||||
|
||||
use <screw.scad>
|
||||
|
@@ -38,7 +38,7 @@ PMMA8 = [ "PMMA8", "Sheet acrylic", 8, [1, 1, 1, 0.5 ],
|
||||
PMMA10 = [ "PMMA10", "Sheet acrylic", 10, [1, 1, 1, 0.5 ], false]; // ~3/8"
|
||||
glass2 = [ "glass2", "Sheet glass", 2, [1, 1, 1, 0.25 ], false];
|
||||
DiBond = [ "DiBond", "Sheet DiBond", 3, [0.2, 0.2, 0.2, 1 ], false];
|
||||
DiBond6 = [ "DiBond6", "Sheet DiBond", 6, "RoyalBlue", false];
|
||||
DiBond6 = [ "DiBond6", "Sheet DiBond", 6, [0.2, 0.2, 0.2, 1 ], false];
|
||||
Cardboard = [ "Cardboard", "Corrugated cardboard", 5, [0.8, 0.6, 0.3, 1 ], false];
|
||||
FoilTape = [ "FoilTape", "Aluminium foil tape", 0.05,[0.9, 0.9, 0.9, 1 ], false];
|
||||
Foam20 = [ "Foam20", "Foam sponge", 20,[0.3, 0.3, 0.3, 1 ], true];
|
||||
|