1
0
mirror of https://github.com/nophead/NopSCADlib.git synced 2025-09-03 12:22:46 +02:00

Compare commits

...

25 Commits

Author SHA1 Message Date
Chris Palmer
c5b35daeac Added rail_holes() function. 2020-11-24 23:38:12 +00:00
Chris Palmer
ffb4512523 Drag chain ends can now be customised by adding children to the assembly. 2020-11-23 12:07:34 +00:00
Chris Palmer
35ffbad74c Drag chain ends now pp3_colour and explode. 2020-11-22 12:47:30 +00:00
Chris Palmer
fb685a0f42 Fixed missing screw default for ribbon_clamp_assembly(). 2020-11-22 12:04:55 +00:00
Chris Palmer
5d42b2e1ab Merge branch 'martinbudden-camera_no_lens' 2020-11-21 20:55:25 +00:00
Chris Palmer
2fe815d1bd Updated readme 2020-11-21 20:54:38 +00:00
Martin Budden
5c577cccd0 Added facility to display camera without lens. 2020-11-21 20:45:39 +00:00
Chris Palmer
1dbfafd366 Merge branch 'martinbudden-conditional_flip' 2020-11-20 12:13:44 +00:00
Chris Palmer
68b3dfb098 Updated readme. 2020-11-20 12:13:26 +00:00
Martin Budden
25dceee20a Made hflip and vflip conditional. 2020-11-20 08:46:17 +00:00
Chris Palmer
d70ddf5359 Type in drag chain blurb, fixes #100 2020-11-19 19:41:59 +00:00
Chris Palmer
70b60522ce Added drag_chain to the cover picture. 2020-11-18 16:25:45 +00:00
Chris Palmer
ecba7eaea4 Merge branch 'martinbudden-square_blower' 2020-11-18 11:31:57 +00:00
Chris Palmer
f751dd9a73 Tweaks to make interface consistent with blowers.
Added blower_exit_offset().
Fixed corner shape and exit dimensions.
Updated images and readme.
2020-11-18 11:31:40 +00:00
Chris Palmer
3f359f6839 Merge branch 'square_blower' of https://github.com/martinbudden/NopSCADlib into martinbudden-square_blower 2020-11-17 16:41:34 +00:00
Chris Palmer
3e5947c161 Added another size of ribbon clamp 2020-11-17 16:23:12 +00:00
Chris
66dc430541 Merge pull request #92 from martinbudden/belt_gap
Allow user to set y size of belt gap.
2020-11-17 16:18:44 +00:00
Chris Palmer
4dc83d62cb Finished end links. 2020-11-17 16:14:25 +00:00
Martin Budden
ebbec3c903 Allow user to set y size of belt gap. 2020-11-16 07:36:34 +00:00
Chris Palmer
9944aab73e Merge branch 'master' into drag 2020-11-15 17:49:30 +00:00
Chris Palmer
eb9bcf0ada Fixed recent bug in plateup when no platters / panels. 2020-11-15 16:29:50 +00:00
Chris Palmer
ff5e8c0372 Added ends 2020-11-15 16:28:24 +00:00
Martin Budden
17ebf36e27 Initial commit of square blower. 2020-11-15 08:16:22 +00:00
Chris Palmer
e38d9abfa0 Merge branch 'master' into drag 2020-11-14 17:46:29 +00:00
Chris Palmer
38acef9e27 Needs end pieces 2020-11-14 14:27:22 +00:00
17 changed files with 670 additions and 113 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 839 KiB

After

Width:  |  Height:  |  Size: 848 KiB

View File

@@ -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>
@@ -417,8 +418,12 @@ 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();

308
printed/drag_chain.scad Normal file
View File

@@ -0,0 +1,308 @@
//
// 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&deg;, 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 if 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 = i % 2;
y = bool2int(i > 1);
if(drag_chain_screw_lists(type)[bool2int(end)][i])
translate([(x0 + x1) / 2, 0])
mirror([x, 0])
mirror([0, y])
translate([(x1 - x0) / 2, s.y / 2 + r])
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) { //! 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)
screw_lug(drag_chain_screw(type), os.z);
children();
}
}
if(start || end)
translate_z(-eps)
drag_chain_screw_positions(type, end)
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);
}
}
}
//! 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
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)
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), "wrong number of children for end customisation");
assembly(str(drag_chain_name(type), "_drag_chain")) {
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);
}
}

View File

@@ -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&deg;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&deg;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&deg;C.
module ribbon_clamp_7_2_assembly() ribbon_clamp_assembly(8, M2_dome_screw);

116
readme.md
View File

@@ -28,20 +28,20 @@ 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 = "#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 = "#Printed_box">Printed_box</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 = "#Ribbon_clamp">Ribbon_clamp</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 = "#SSR_shroud">SSR_shroud</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 = "#Screw_knob">Screw_knob</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 = "#Socket_box">Socket_box</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 = "#Strap_handle">Strap_handle</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></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>
@@ -296,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 |
![blowers](tests/png/blowers.png)
@@ -309,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 |
@@ -464,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 |
![cameras](tests/png/cameras.png)
@@ -2697,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 |
@@ -4539,6 +4550,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&deg;, 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 if a screw lug |
### Modules
| Module | Description |
|:--- |:--- |
| ```drag_chain_assembly(type, pos = 0)``` | Drag chain assembly |
| ```drag_chain_link(type, start = false, end = false)``` | 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 |
![drag_chain](tests/png/drag_chain.png)
### 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>
---
@@ -5067,7 +5145,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 |
@@ -5987,11 +6065,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&deg; flip around the Y axis |
| ```hflip(flip=true)``` | Invert children by doing a 180&deg; flip around the Y axis |
| ```right_triangle(width, height, h, center = true)``` | A right angled triangle with the 90&deg; 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&deg; flip around the X axis |
| ```vflip(flip=true)``` | Invert children by doing a 180&deg; flip around the X axis |
![global](tests/png/global.png)

View File

@@ -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)

View File

@@ -39,7 +39,7 @@ module belt_test() {
screw = find_screw(hs_cs_cap, pulley_bore(pulley));
insert = screw_insert(screw);
rotate([0, flip ? 180 : 0, 0]) {
hflip(flip) {
pulley_assembly(pulley);
translate_z(pulley_height(pulley) + pulley_offset(pulley) + screw_head_depth(screw, pulley_bore(pulley)))
screw(screw, 20);

59
tests/drag_chain.scad Normal file
View 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);
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 104 KiB

After

Width:  |  Height:  |  Size: 106 KiB

BIN
tests/png/drag_chain.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 KiB

View File

@@ -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&deg; flip around the X axis
module hflip() rotate([0, 180, 0]) children(); //! Invert children by doing a 180&deg; flip around the Y axis
module vflip(flip=true) rotate([flip ? 180 : 0, 0, 0]) children(); //! Invert children by doing a 180&deg; flip around the X axis
module hflip(flip=true) rotate([0, flip ? 180: 0, 0]) children(); //! Invert children by doing a 180&deg; 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()

View File

@@ -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)

View File

@@ -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);
}
}

View File

@@ -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>

View File

@@ -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) {

View File

@@ -46,12 +46,15 @@ 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;
holes = rail_holes(type, length);
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])
translate([i * pitch - length / 2 + (length - (holes - 1) * pitch) / 2, 0])
children();
}
@@ -104,24 +107,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);
}