1
0
mirror of https://github.com/nophead/NopSCADlib.git synced 2025-09-22 05:01:30 +02:00

Compare commits

..

6 Commits

Author SHA1 Message Date
Chris Palmer
97cea65f41 Cable clips can now use inserts or nut traps. 2024-04-21 12:08:40 +01:00
Chris Palmer
c7e912cd77 A optional path can now be specified for tubing. 2024-04-21 10:26:28 +01:00
Chris Palmer
f563645e45 Corrected M2 nut_trap_depth, was too big. 2024-04-21 10:20:36 +01:00
Chris Palmer
2840cc2390 Washer now uses sweep.scad instead of including it, leaking its interface. 2024-04-21 10:18:34 +01:00
Chris Palmer
a5b2018008 Added offset_paths() to sweep.scad.
show_path() now takes an optional radius.
2024-04-21 08:47:44 +01:00
Chris Palmer
7a395e475e Updated changelog. 2024-03-14 23:56:12 +00:00
11 changed files with 125 additions and 88 deletions

View File

@@ -3,6 +3,11 @@
This changelog is generated by `changelog.py` using manually added semantic version tags to classify commits as breaking changes, additions or fixes. This changelog is generated by `changelog.py` using manually added semantic version tags to classify commits as breaking changes, additions or fixes.
### [v21.18.0](https://github.com/nophead/NopSCADlib/releases/tag/v21.18.0 "show release") Additions [...](https://github.com/nophead/NopSCADlib/compare/v21.17.0...v21.18.0 "diff with v21.17.0")
* 2024-03-14 [`19dadcb`](https://github.com/nophead/NopSCADlib/commit/19dadcb58db0dd7408726c69d46cf2b7b26c764b "show commit") [C.P.](# "Chris Palmer") Updated images and readme.
* 2024-03-14 [`c565f29`](https://github.com/nophead/NopSCADlib/commit/c565f2912e7319575fc6ec3262699b73305c46b4 "show commit") [V.](# "V.Shkriabets") Update MT3608 pcb module
### [v21.17.0](https://github.com/nophead/NopSCADlib/releases/tag/v21.17.0 "show release") Additions [...](https://github.com/nophead/NopSCADlib/compare/v21.16.1...v21.17.0 "diff with v21.16.1") ### [v21.17.0](https://github.com/nophead/NopSCADlib/releases/tag/v21.17.0 "show release") Additions [...](https://github.com/nophead/NopSCADlib/compare/v21.16.1...v21.17.0 "diff with v21.16.1")
* 2024-03-14 [`5579c0d`](https://github.com/nophead/NopSCADlib/commit/5579c0d988c6d7983d3884afa7e42fdb283109a8 "show commit") [C.P.](# "Chris Palmer") Fixed `box_shelf_bracket()` horizontal holes. * 2024-03-14 [`5579c0d`](https://github.com/nophead/NopSCADlib/commit/5579c0d988c6d7983d3884afa7e42fdb283109a8 "show commit") [C.P.](# "Chris Palmer") Fixed `box_shelf_bracket()` horizontal holes.
Added a third child to `box_shelf_bracket()` to allow custom additions. Added a third child to `box_shelf_bracket()` to allow custom additions.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1001 KiB

After

Width:  |  Height:  |  Size: 1001 KiB

View File

@@ -18,7 +18,7 @@
// //
// //
//! Cable clips to order. Can be for one or two cables of different sizes. Can use an insert and a screw from below or a screw and nut either way up. //! Cable clips to order. Can be for one or two cables of different sizes. Can use an insert and a screw from below or a screw and nut, nyloc or plain, either way up.
// //
include <../core.scad> include <../core.scad>
use <../vitamins/wire.scad> use <../vitamins/wire.scad>
@@ -30,27 +30,29 @@ wall = 2;
function cable_clip_insert(screw, insert = true) = //! Insert type for clip, given screw. function cable_clip_insert(screw, insert = true) = //! Insert type for clip, given screw.
is_list(insert) ? insert : insert ? screw_insert(screw, true) : false; is_list(insert) ? insert : insert ? screw_insert(screw, true) : false;
function cable_clip_width(screw, insert = false) = //! Width given the `screw` and possibly insert. function cable_clip_width(screw, insert = false, nut = false) = //! Width given the `screw` and possibly insert or nut.
let(insert = cable_clip_insert(screw, insert)) let(insert = cable_clip_insert(screw, insert))
insert ? 2 * (insert_hole_radius(insert) + wall) : insert ? 2 * (insert_hole_radius(insert) + wall) :
max(wall + 2 * screw_clearance_radius(screw) + wall, washer_diameter(screw_washer(screw))); nut ? 2 * (nut_radius(screw_nut(screw)) + wall) :
max(wall + 2 * screw_clearance_radius(screw) + wall, washer_diameter(screw_washer(screw)));
function cable_clip_height(cable, screw = false, insert = false) = //! Height given the `cable`. function cable_clip_height(cable, screw = false, insert = false, nut = false) = //! Height given the `cable`.
let(insert = cable_clip_insert(screw, insert)) let(insert = cable_clip_insert(screw, insert))
max(cable_height(cable) + wall, insert ? insert_hole_length(insert) + 1 : 0); max(cable_height(cable) + wall, insert ? insert_hole_length(insert) + 1 : 0, nut ? nut_trap_depth(screw_nut(screw)) + wall : 0);
function cable_clip_extent(screw, cable, insert = false) = cable_clip_width(screw, insert) / 2 + cable_width(cable) + wall; //! How far it extends from the screw. function cable_clip_extent(screw, cable, insert = false, nut = false) = cable_clip_width(screw, insert, nut) / 2 + cable_width(cable) + wall; //! How far it extends from the screw.
function cable_clip_offset(screw, cable, insert = false) = cable_clip_width(screw, insert) / 2 + cable_width(cable) / 2; //! The offset of the cable from the screw. function cable_clip_offset(screw, cable, insert = false, nut = false) = cable_clip_width(screw, insert, nut) / 2 + cable_width(cable) / 2; //! The offset of the cable from the screw.
module single_cable_clip(screw, cable, h = 0, insert = false) { module single_cable_clip(screw, cable, h = 0, insert = false, nut = false) {
insert = cable_clip_insert(screw, insert); insert = cable_clip_insert(screw, insert);
height = cable_clip_width(screw, insert); height = cable_clip_width(screw, insert, nut);
depth = h ? h : cable_clip_height(cable, screw, insert); depth = h ? h : cable_clip_height(cable, screw, insert, nut);
w = cable_width(cable); w = cable_width(cable);
width = wall + w + height; width = wall + w + height;
hole_x = wall + w + height / 2; hole_x = wall + w + height / 2;
rad = min(wall + cable_wire_size(cable) / 2, depth / 2); rad = min(wall + cable_wire_size(cable) / 2, depth / 2);
r = extrusion_width - eps; r = extrusion_width - eps;
the_nut = screw_nut(screw);
translate([-hole_x, 0]) translate([-hole_x, 0])
difference() { difference() {
linear_extrude(height) linear_extrude(height)
@@ -85,62 +87,68 @@ module single_cable_clip(screw, cable, h = 0, insert = false) {
if(insert) if(insert)
insert_hole(insert, 10, horizontal = true); insert_hole(insert, 10, horizontal = true);
else else
teardrop_plus(h = 2 * depth + 1, r = screw_clearance_radius(screw), center = true); if(nut) {
translate_z(depth - wall - nut_trap_depth(the_nut))
nut_trap(screw, the_nut, horizontal = true);
nut_trap(screw, the_nut, horizontal = true);
}
else
teardrop_plus(h = 2 * depth + 1, r = screw_clearance_radius(screw), center = true);
} }
} }
module double_cable_clip(screw, cable1, cable2, insert = false) { module double_cable_clip(screw, cable1, cable2, insert = false, nut = false) {
h = max(cable_clip_height(cable1, screw, insert), cable_clip_height(cable2, screw, insert)); h = max(cable_clip_height(cable1, screw, insert, nut), cable_clip_height(cable2, screw, insert, nut));
union() { union() {
single_cable_clip(screw, cable1, h, insert); single_cable_clip(screw, cable1, h, insert, nut);
mirror([1,0,0]) single_cable_clip(screw, cable2, h, insert); mirror([1,0,0]) single_cable_clip(screw, cable2, h, insert, nut);
} }
} }
module cable_clip(screw, cable1, cable2 = 0, insert = false) { //! Create the STL for a single cable or two cable clip module cable_clip(screw, cable1, cable2 = 0, insert = false, nut = false) { //! Create the STL for a single cable or two cable clip
function clip_str(screw) = str("cable_clip_", screw_radius(screw) * 20, insert ? "I" : ""); function clip_str(screw) = str("cable_clip_", screw_radius(screw) * 20, insert ? "I" : nut ? "N" : "");
function cable_str(cable) = str("_", cable_wires(cable), "_", round(cable_wire_size(cable) * 10)); function cable_str(cable) = str("_", cable_wires(cable), "_", round(cable_wire_size(cable) * 10));
assert(!(insert && nut), "insert and nut mutually exclusive");
if(cable2) { if(cable2)
stl(str(clip_str(screw), cable_str(cable1), cable_str(cable2))); stl(str(clip_str(screw), cable_str(cable1), cable_str(cable2)))
double_cable_clip(screw, cable1, cable2, insert, nut);
double_cable_clip(screw, cable1, cable2, insert); else
} stl(str(clip_str(screw), cable_str(cable1)))
else { single_cable_clip(screw, cable1, h = 0, insert = insert, nut = nut);
stl(str(clip_str(screw), cable_str(cable1)));
single_cable_clip(screw, cable1, h = 0, insert = insert);
}
} }
module cable_clip_assembly(screw, thickness, cable1, cable2 = 0, flip = false, insert = false, nut = false, nyloc = true) { //! Cable clip with the fasteners
module cable_clip_assembly(screw, thickness, cable1, cable2 = 0, flip = false, insert = false) { //! Cable clip with the fasteners flip = flip || insert || nut; // Screw must be below if using an insert or nut
flip = flip || insert; // Screw must be below if using an insert
insert = cable_clip_insert(screw, insert); insert = cable_clip_insert(screw, insert);
height = max(cable_clip_height(cable1, screw, insert), cable2 ? cable_clip_height(cable2, screw, insert) : 0); height = max(cable_clip_height(cable1, screw, insert, nut), cable2 ? cable_clip_height(cable2, screw, insert, nut) : 0);
stl_colour(pp1_colour) render() stl_colour(pp1_colour) render()
translate([0, cable_clip_width(screw, insert) / 2]) translate([0, cable_clip_width(screw, insert, nut) / 2])
rotate([90, 0, 0]) rotate([90, 0, 0])
cable_clip(screw, cable1, cable2, insert); cable_clip(screw, cable1, cable2, insert, nut);
nut = screw_nut(screw); the_nut = screw_nut(screw);
screw_len = screw_length(screw, height + thickness, 2, nyloc = !insert, insert = insert); screw_len = nut ? screw_length(screw, thickness + wall, nyloc ? 1 : 2, nyloc = nyloc, nut = !nyloc)
: screw_length(screw, thickness + height, 2, nut = !nyloc && !insert, nyloc = !insert && nyloc, insert = insert);
translate_z(height) translate_z(height)
if(flip) if(flip)
if(insert) if(insert)
insert(insert); insert(insert);
else else
nut_and_washer(nut, true); if(nut)
translate_z(-height + wall)
nut(the_nut, nyloc);
else
nut_and_washer(the_nut, nyloc);
else else
screw_and_washer(screw, screw_len); screw_and_washer(screw, screw_len);
translate_z(-thickness) translate_z(-thickness)
vflip() vflip()
if(flip) if(flip)
screw_and_washer(screw, screw_len, insert); screw_and_washer(screw, screw_len, insert || !nyloc);
else else
nut_and_washer(nut, true); nut_and_washer(the_nut, nyloc);
} }

View File

@@ -4771,7 +4771,7 @@ T-Tracks used in woodworking jigs
--- ---
<a name="tubings"></a> <a name="tubings"></a>
## Tubings ## Tubings
Tubing and sleeving. The internal diameter can be forced to stretch it over something. Tubing and sleeving. The internal diameter can be forced to stretch it over something. A path can be specified, otherwise it is just straight with the specified length.
[vitamins/tubings.scad](vitamins/tubings.scad) Object definitions. [vitamins/tubings.scad](vitamins/tubings.scad) Object definitions.
@@ -4796,7 +4796,7 @@ Tubing and sleeving. The internal diameter can be forced to stretch it over some
### Modules ### Modules
| Module | Description | | Module | Description |
|:--- |:--- | |:--- |:--- |
| `tubing(type, length = 15, forced_id = 0, center = true)` | Draw specified tubing with optional forced internal diameter | | `tubing(type, length = 15, forced_id = 0, center = true, path = [])` | Draw specified tubing with optional forced internal diameter and optional path. |
![tubings](tests/png/tubings.png) ![tubings](tests/png/tubings.png)
@@ -5365,7 +5365,7 @@ fixing_blocks along the sides.
--- ---
<a name="cable_clip"></a> <a name="cable_clip"></a>
## Cable_clip ## Cable_clip
Cable clips to order. Can be for one or two cables of different sizes. Can use an insert and a screw from below or a screw and nut either way up. Cable clips to order. Can be for one or two cables of different sizes. Can use an insert and a screw from below or a screw and nut, nyloc or plain, either way up.
[printed/cable_clip.scad](printed/cable_clip.scad) Implementation. [printed/cable_clip.scad](printed/cable_clip.scad) Implementation.
@@ -5374,17 +5374,17 @@ Cable clips to order. Can be for one or two cables of different sizes. Can use a
### Functions ### Functions
| Function | Description | | Function | Description |
|:--- |:--- | |:--- |:--- |
| `cable_clip_extent(screw, cable, insert = false)` | How far it extends from the screw. | | `cable_clip_extent(screw, cable, insert = false, nut = false)` | How far it extends from the screw. |
| `cable_clip_height(cable, screw = false, insert = false)` | Height given the `cable`. | | `cable_clip_height(cable, screw = false, insert = false, nut = false)` | Height given the `cable`. |
| `cable_clip_insert(screw, insert = true)` | Insert type for clip, given screw. | | `cable_clip_insert(screw, insert = true)` | Insert type for clip, given screw. |
| `cable_clip_offset(screw, cable, insert = false)` | The offset of the cable from the screw. | | `cable_clip_offset(screw, cable, insert = false, nut = false)` | The offset of the cable from the screw. |
| `cable_clip_width(screw, insert = false)` | Width given the `screw` and possibly insert. | | `cable_clip_width(screw, insert = false, nut = false)` | Width given the `screw` and possibly insert or nut. |
### Modules ### Modules
| Module | Description | | Module | Description |
|:--- |:--- | |:--- |:--- |
| `cable_clip(screw, cable1, cable2 = 0, insert = false)` | Create the STL for a single cable or two cable clip | | `cable_clip(screw, cable1, cable2 = 0, insert = false, nut = false)` | Create the STL for a single cable or two cable clip |
| `cable_clip_assembly(screw, thickness, cable1, cable2 = 0, flip = false, insert = false)` | Cable clip with the fasteners | | `cable_clip_assembly(screw, thickness, cable1, cable2 = 0, flip = false, insert = false, nut = false, nyloc = true)` | Cable clip with the fasteners |
![cable_clip](tests/png/cable_clip.png) ![cable_clip](tests/png/cable_clip.png)
@@ -5393,10 +5393,10 @@ Cable clips to order. Can be for one or two cables of different sizes. Can use a
| ---:|:--- |:---| | ---:|:--- |:---|
| 2 | `insert(CNCKM3)` | Heatfit insert M3 x 3mm | | 2 | `insert(CNCKM3)` | Heatfit insert M3 x 3mm |
| 5 | `nut(M3_nut, nyloc = true)` | Nut M3 x 2.4mm nyloc | | 5 | `nut(M3_nut, nyloc = true)` | Nut M3 x 2.4mm nyloc |
| 2 | `screw(M3_dome_screw, 10)` | Screw M3 dome x 10mm | | 3 | `screw(M3_dome_screw, 10)` | Screw M3 dome x 10mm |
| 1 | `screw(M3_dome_screw, 12)` | Screw M3 dome x 12mm | | 1 | `screw(M3_dome_screw, 12)` | Screw M3 dome x 12mm |
| 4 | `screw(M3_dome_screw, 16)` | Screw M3 dome x 16mm | | 3 | `screw(M3_dome_screw, 16)` | Screw M3 dome x 16mm |
| 12 | `washer(M3_washer)` | Washer M3 x 7mm x 0.5mm | | 11 | `washer(M3_washer)` | Washer M3 x 7mm x 0.5mm |
| 2 | `star_washer(M3_washer)` | Washer star M3 x 0.5mm | | 2 | `star_washer(M3_washer)` | Washer star M3 x 0.5mm |
### Printed ### Printed
@@ -5404,10 +5404,10 @@ Cable clips to order. Can be for one or two cables of different sizes. Can use a
| ---:|:--- | | ---:|:--- |
| 1 | cable_clip_30I_10_13.stl | | 1 | cable_clip_30I_10_13.stl |
| 1 | cable_clip_30I_5_14_6_14.stl | | 1 | cable_clip_30I_5_14_6_14.stl |
| 1 | cable_clip_30N_7_14_8_14.stl |
| 1 | cable_clip_30_1_14_2_14.stl | | 1 | cable_clip_30_1_14_2_14.stl |
| 1 | cable_clip_30_1_60.stl | | 1 | cable_clip_30_1_60.stl |
| 1 | cable_clip_30_3_14_4_14.stl | | 1 | cable_clip_30_3_14_4_14.stl |
| 1 | cable_clip_30_7_14_8_14.stl |
| 1 | cable_clip_30_9_14.stl | | 1 | cable_clip_30_9_14.stl |
@@ -5488,7 +5488,8 @@ Housings for PCB cameras.
| 1 | `camera(rpi_camera_v1)` | Raspberry Pi camera V1 | | 1 | `camera(rpi_camera_v1)` | Raspberry Pi camera V1 |
| 1 | `camera(rpi_camera_v2)` | Raspberry Pi camera V2 | | 1 | `camera(rpi_camera_v2)` | Raspberry Pi camera V2 |
| 1 | `camera(rpi_camera)` | Raspberry Pi focusable camera | | 1 | `camera(rpi_camera)` | Raspberry Pi focusable camera |
| 7 | `screw(M2_cap_screw, 10)` | Screw M2 cap x 10mm | | 3 | `screw(M2_cap_screw, 8)` | Screw M2 cap x 8mm |
| 4 | `screw(M2_cap_screw, 10)` | Screw M2 cap x 10mm |
| 4 | `screw(M3_cap_screw, 16)` | Screw M3 cap x 16mm | | 4 | `screw(M3_cap_screw, 16)` | Screw M3 cap x 16mm |
| 4 | `screw(M3_dome_screw, 10)` | Screw M3 dome x 10mm | | 4 | `screw(M3_dome_screw, 10)` | Screw M3 dome x 10mm |
| 2 | `screw(M3_dome_screw, 12)` | Screw M3 dome x 12mm | | 2 | `screw(M3_dome_screw, 12)` | Screw M3 dome x 12mm |
@@ -7451,6 +7452,7 @@ Each vertex, apart from the first and the last, has an associated radius and the
| `cap(facets, segment = 0, end)` | Create the mesh for an end cap | | `cap(facets, segment = 0, end)` | Create the mesh for an end cap |
| `circle_points(r = 1, z = 0, dir = -1)` | Generate the points of a circle, setting z makes a single turn spiral | | `circle_points(r = 1, z = 0, dir = -1)` | Generate the points of a circle, setting z makes a single turn spiral |
| `helical_twist_per_segment(r, pitch, sides)` | Calculate the twist around Z that rotate_from_to() introduces | | `helical_twist_per_segment(r, pitch, sides)` | Calculate the twist around Z that rotate_from_to() introduces |
| `offset_paths(path, offsets, twists = 0)` | Create new paths offset from the original, optionally spiralling around it |
| `rectangle_points(w, h)` | Generate the points of a rectangle | | `rectangle_points(w, h)` | Generate the points of a rectangle |
| `rounded_path(path)` | Convert a rounded_path, consisting of a start coordinate, vertex / radius pairs and then an end coordinate, to a path of points for sweep. | | `rounded_path(path)` | Convert a rounded_path, consisting of a start coordinate, vertex / radius pairs and then an end coordinate, to a path of points for sweep. |
| `rounded_path_vertices(path)` | Show the unrounded version of a rounded_path for debug | | `rounded_path_vertices(path)` | Show the unrounded version of a rounded_path for debug |
@@ -7462,7 +7464,7 @@ Each vertex, apart from the first and the last, has an associated radius and the
### Modules ### Modules
| Module | Description | | Module | Description |
|:--- |:--- | |:--- |:--- |
| `show_path(path)` | Show a path using a chain of hulls for debugging, duplicate points are highlighted. | | `show_path(path, r = 0.1)` | Show a path using a chain of hulls for debugging, duplicate points are highlighted. |
| `sweep(path, profile, loop = false, twist = 0, convexity = 1)` | Draw a polyhedron that is the swept volume | | `sweep(path, profile, loop = false, twist = 0, convexity = 1)` | Draw a polyhedron that is the swept volume |
![sweep](tests/png/sweep.png) ![sweep](tests/png/sweep.png)

View File

@@ -20,33 +20,39 @@
include <../core.scad> include <../core.scad>
use <../printed/cable_clip.scad> use <../printed/cable_clip.scad>
use <../vitamins/wire.scad> use <../vitamins/wire.scad>
use <../utils/layout.scad>
screw = M3_dome_screw;
sheet_thickness = 3; sheet_thickness = 3;
cables = [ cables = [
[10, inch(0.05), true], 0, for(i = [1 : 9]) [i, 1.4], 0, [1, 6], 0, [10, inch(0.05), true], 0, for(i = [1 : 9]) [i, 1.4], 0, [1, 6], 0,
]; ];
screw = M3_dome_screw; clips = [for(i = [0 : ceil(len(cables) / 2) - 1]) let(c1= cables[2 * i], c2 = cables[2 * i + 1]) [c1, c2]];
function use_insert(i) = in([0, 3], i);
function use_nut(i) = in([4], i);
clip_lengths = [for(i = [0 : len(clips) - 1])
let(c = clips[i], c1 = c.x, c2 = c.y, ins = use_insert(i), nut = use_nut(i))
cable_clip_extent(screw, c1, insert = ins, nut = nut) + (c2 ? cable_clip_extent(screw, c2, insert = ins, nut = nut) : cable_clip_width(screw, insert = ins, nut = nut) / 2)];
module cable_clips() { module cable_clips() {
for(i = [0 : ceil(len(cables) / 2) - 1]) { layout(clip_lengths, 3, true) let(cable1 = clips[$i].x, cable2 = clips[$i].y) {
cable1 = cables[2 * i]; insert = use_insert($i);
cable2 = cables[2 * i + 1]; nut = use_nut($i);
translate([i * 21 + (!cable2 ? cable_clip_offset(screw, cable1) / 2 : 0), 0]) { translate([cable_clip_extent(screw, cable1, insert = insert, nut = nut) - clip_lengths[$i] / 2, 0]) {
insert = in([0, 3], i);
if($preview) { if($preview) {
cable_clip_assembly(screw, sheet_thickness, cable1, cable2, insert = insert, flip = i == 1); cable_clip_assembly(screw, sheet_thickness, cable1, cable2, insert = insert, nut = nut, flip = $i == 1);
for(j = [0 : 1]) for(j = [0 : 1])
let(cable = cables[2 * i + j]) let(cable = clips[$i][j])
if(cable) if(cable)
let(positions = cable_bundle_positions(cable)) let(positions = cable_bundle_positions(cable))
for(i = [0 : len(positions) - 1]) for(i = [0 : len(positions) - 1])
let(p = positions[i]) let(p = positions[i])
translate([p.x + [-1, 1][j] * cable_clip_offset(screw, cable, insert = insert), 0, p.y]) translate([p.x + [-1, 1][j] * cable_clip_offset(screw, cable, insert = insert, nut = nut), 0, p.y])
rotate([90, 0, 0]) rotate([90, 0, 0])
color([grey(20), "blue", "red", "orange", "yellow", "green", "brown", "purple", "grey", "white"][i]) color([grey(20), "blue", "red", "orange", "yellow", "green", "brown", "purple", "grey", "white"][i])
cylinder(d = cable_wire_size(cable), h = 30, center = true); cylinder(d = cable_wire_size(cable), h = 30, center = true);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 131 KiB

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 122 KiB

After

Width:  |  Height:  |  Size: 122 KiB

View File

@@ -111,7 +111,7 @@ function helical_twist_per_segment(r, pitch, sides) = //! Calculate the twist ar
// //
// Generate all the transforms for the profile of the swept volume. // Generate all the transforms for the profile of the swept volume.
// //
function sweep_transforms(path, loop = false, twist = 0) = function sweep_transforms(path, loop = false, twist = 0, initial_rotation = undef) =
let(len = len(path), let(len = len(path),
last = len - 1, last = len - 1,
@@ -122,7 +122,7 @@ function sweep_transforms(path, loop = false, twist = 0) =
lengths = [for(i = 0, t = 0; i < len; t = t + norm(path[min(i + 1, last)] - path[i]), i = i + 1) t], lengths = [for(i = 0, t = 0; i < len; t = t + norm(path[min(i + 1, last)] - path[i]), i = i + 1) t],
length = lengths[last], length = lengths[last],
rotations = [for(i = 0, rot = fs_frame(tangents); rotations = [for(i = 0, rot = is_undef(initial_rotation) ? fs_frame(tangents) : rot3_z(initial_rotation);
i < len; i < len;
i = i + 1, i = i + 1,
rot = i < len ? rotate_from_to(tangents[i - 1], tangents[i]) * rot : undef) rot], rot = i < len ? rotate_from_to(tangents[i - 1], tangents[i]) * rot : undef) rot],
@@ -169,7 +169,7 @@ function sweep(path, profile, loop = false, twist = 0) = //! Generate the point
points = skin_points(profile, path, loop, twist), points = skin_points(profile, path, loop, twist),
skin_faces = skin_faces(points, npoints, facets, loop), skin_faces = skin_faces(points, npoints, facets, loop),
faces = loop ? skin_faces : concat([cap(facets)], skin_faces, [cap(facets, npoints - 1)]) faces = loop ? skin_faces : concat([cap(facets)], skin_faces, [cap(facets, npoints - 1)])
) [points, faces]; ) [points, faces];
module sweep(path, profile, loop = false, twist = 0, convexity = 1) { //! Draw a polyhedron that is the swept volume module sweep(path, profile, loop = false, twist = 0, convexity = 1) { //! Draw a polyhedron that is the swept volume
mesh = sweep(path, profile, loop, twist); mesh = sweep(path, profile, loop, twist);
@@ -229,16 +229,20 @@ function rounded_path(path) = //! Convert a rounded_path, consisting of a start
function segmented_path(path, min_segment) = [ //! Add points to a path to enforce a minimum segment length function segmented_path(path, min_segment) = [ //! Add points to a path to enforce a minimum segment length
for(i = [0 : len(path) - 2]) for(i = [0 : len(path) - 2])
let(delta = let(delta =
assert(path[i] != path[i + 1], str("Coincident points at path[", i, "] = ", path[i])) assert(path[i] != path[i + 1], str("Coincident points at path[", i, "] = ", path[i]))
path[i+1] - path[i], path[i+1] - path[i],
segs = ceil(norm(delta) / min_segment) segs = ceil(norm(delta) / min_segment)
) )
for(j = [0 : segs - 1]) for(j = [0 : segs - 1])
path[i] + delta * j / segs, // Linear interpolation path[i] + delta * j / segs, // Linear interpolation
path[len(path) - 1] path[len(path) - 1]
]; ];
function offset_paths(path, offsets, twists = 0) = let( //! Create new paths offset from the original, optionally spiralling around it
transforms = sweep_transforms(path, twist = 360 * twists, initial_rotation = 0)
) [for(o = offsets) let(initial = [o.x, o.y, o.z, 1]) [for(t = transforms) initial * t]];
function spiral_paths(path, n, r, twists, start_angle) = let( //! Create a new paths which spiral around the given path. Use for making twisted cables function spiral_paths(path, n, r, twists, start_angle) = let( //! Create a new paths which spiral around the given path. Use for making twisted cables
segment = twists ? path_length(path) / twists / r2sides(2 * r) : inf, segment = twists ? path_length(path) / twists / r2sides(2 * r) : inf,
transforms = sweep_transforms(segmented_path(path, segment), twist = 360 * twists) transforms = sweep_transforms(segmented_path(path, segment), twist = 360 * twists)
@@ -246,16 +250,16 @@ function spiral_paths(path, n, r, twists, start_angle) = let( //! Create a new p
function rounded_path_vertices(path) = [path[0], for(i = [1 : 2 : len(path) - 1]) path[i]]; //! Show the unrounded version of a rounded_path for debug function rounded_path_vertices(path) = [path[0], for(i = [1 : 2 : len(path) - 1]) path[i]]; //! Show the unrounded version of a rounded_path for debug
module show_path(path) //! Show a path using a chain of hulls for debugging, duplicate points are highlighted. module show_path(path, r = 0.1) //! Show a path using a chain of hulls for debugging, duplicate points are highlighted.
for(i = [0 : len(path) - 2]) { for(i = [0 : len(path) - 2]) {
hull($fn = 16) { hull($fn = 16) {
translate(path[i]) translate(path[i])
sphere(0.1); sphere(r);
translate(path[i + 1]) translate(path[i + 1])
sphere(0.1); sphere(r);
} }
if(path[i] == path[i + 1]) if(path[i] == path[i + 1])
translate(path[i]) translate(path[i])
color("red") sphere(1); color("red") sphere($fn = 16, r * 4);
} }

View File

@@ -20,7 +20,7 @@ include <washers.scad>
// //
// Nuts // Nuts
// //
M2_nut_trap_depth = 2.5; M2_nut_trap_depth = 1.75;
M2p5_nut_trap_depth = 2.5; M2p5_nut_trap_depth = 2.5;
M3_nut_trap_depth = 3; M3_nut_trap_depth = 3;
M4_nut_trap_depth = 4; M4_nut_trap_depth = 4;

View File

@@ -18,10 +18,11 @@
// //
// //
//! Tubing and sleeving. The internal diameter can be forced to stretch it over something. //! Tubing and sleeving. The internal diameter can be forced to stretch it over something. A path can be specified, otherwise it is just straight with the specified length.
// //
include <../utils/core/core.scad> include <../utils/core/core.scad>
include <../utils/tube.scad> include <../utils/tube.scad>
include <../utils/sweep.scad>
function tubing_material(type) = type[1]; //! Material description function tubing_material(type) = type[1]; //! Material description
function tubing_od(type) = type[2]; //! Outside diameter function tubing_od(type) = type[2]; //! Outside diameter
@@ -31,11 +32,12 @@ function tubing_colour(type) = type[4]; //! Colour
function tubing_or(type) = tubing_od(type) / 2; //! Outside radius function tubing_or(type) = tubing_od(type) / 2; //! Outside radius
function tubing_ir(type) = tubing_id(type) / 2; //! Inside radius function tubing_ir(type) = tubing_id(type) / 2; //! Inside radius
module tubing(type, length = 15, forced_id = 0, center = true) { //! Draw specified tubing with optional forced internal diameter module tubing(type, length = 15, forced_id = 0, center = true, path = []) { //! Draw specified tubing with optional forced internal diameter and optional path.
original_od = tubing_od(type); original_od = tubing_od(type);
original_id = tubing_id(type); original_id = tubing_id(type);
id = forced_id ? forced_id : original_id; id = forced_id ? forced_id : original_id;
od = original_od + id - original_id; od = original_od + id - original_id;
length = path ? round(path_length(path)) : length;
if(tubing_material(type) == "Heatshrink sleeving") if(tubing_material(type) == "Heatshrink sleeving")
vitamin(str("tubing(", type[0], arg(length, 15), "): ", tubing_material(type), " ID ", original_id, "mm x ",length, "mm")); vitamin(str("tubing(", type[0], arg(length, 15), "): ", tubing_material(type), " ID ", original_id, "mm x ",length, "mm"));
else else
@@ -45,9 +47,19 @@ module tubing(type, length = 15, forced_id = 0, center = true) { //! Draw specif
woven_tube(od / 2, id /2, center = center, length, colour = tubing_colour(type)); woven_tube(od / 2, id /2, center = center, length, colour = tubing_colour(type));
else else
color(tubing_colour(type)) color(tubing_colour(type))
linear_extrude(length, center = center, convexity = 4) if(path)
difference() { render_if(manifold)
circle(d = od); difference() {
circle(d = id); sweep(path, circle_points(od / 2));
} start = path[0] - eps * unit(path[1] - path[0]);
n = len(path) - 1;
end = path[n] + eps * unit(path[n] - path[n - 1]);
sweep(concat([start], path, [end]), circle_points(id / 2));
}
else
linear_extrude(length, center = center, convexity = 4)
difference() {
circle(d = od);
circle(d = id);
}
} }

View File

@@ -23,7 +23,7 @@
//! If a washer is given a child, usually a screw or a nut, then it is placed on its top surface. //! If a washer is given a child, usually a screw or a nut, then it is placed on its top surface.
// //
include <../utils/core/core.scad> include <../utils/core/core.scad>
include <../utils/sweep.scad> use <../utils/sweep.scad>
soft_washer_colour = grey(20); soft_washer_colour = grey(20);
hard_washer_colour = grey(85); hard_washer_colour = grey(85);