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

Compare commits

...

56 Commits

Author SHA1 Message Date
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
Chris Palmer
7b7348d98f Merge branch 'vshcryabets-update/mt3608-pcb' 2024-03-14 23:54:17 +00:00
Chris Palmer
19dadcb58d Updated images and readme. 2024-03-14 23:53:44 +00:00
Chris Palmer
60a2ef8976 Merge branch 'update/mt3608-pcb' of https://github.com/vshcryabets/NopSCADlib into vshcryabets-update/mt3608-pcb 2024-03-14 23:22:14 +00:00
Chris Palmer
188b3f706d Updated changelog. 2024-03-14 21:41:08 +00:00
Chris Palmer
5579c0d988 Fixed box_shelf_bracket() horizontal holes.
Added a third child to box_shelf_bracket() to allow custom additions.
2024-03-14 21:36:04 +00:00
Chris Palmer
67408f8422 Added d_hole() module. 2024-03-14 21:02:20 +00:00
Chris Palmer
929abbefda Updated front page image. 2024-03-14 21:01:37 +00:00
Chris Palmer
c7727e7106 Added Sellotape to sheets. 2024-03-14 20:58:54 +00:00
Chris Palmer
1dbba5a650 Added camera_lens_height() function. 2024-03-14 20:58:02 +00:00
Chris Palmer
db2a9a8a24 Ziptie test can now show wires with t = 0. 2024-03-14 20:56:20 +00:00
Chris Palmer
6ced9c871c Fixed FOV for ESP32 camera being rotated.
Shortened the ESP32 camera header pins.
2024-03-14 20:51:05 +00:00
Chris Palmer
d6b00fbf57 Removed unused test code. 2024-03-14 20:48:05 +00:00
Chris Palmer
2c996bb7a1 Fixed random error caused by not running bom first. 2024-03-14 20:47:11 +00:00
V.Shkriabets
c565f2912e Update MT3608 pcb module 2024-03-14 19:21:52 +02:00
Chris Palmer
dbd3004021 Updated changelog. 2024-02-19 19:07:26 +00:00
Chris Palmer
fb656c8fad Merge branch 'jeroenrnl-t-tracks' 2024-02-19 19:03:47 +00:00
Chris Palmer
fdb92ec263 Improved layout to fit into front page view. 2024-02-19 19:03:20 +00:00
Chris Palmer
cff4c71909 Merge branch 't-tracks' of https://github.com/jeroenrnl/NopSCADlib into jeroenrnl-t-tracks 2024-02-19 16:28:24 +00:00
Chris Palmer
db917ef2bc Updated changelog. 2024-02-19 16:15:34 +00:00
Chris Palmer
a2d98f9d3a Merge branch 'jeroenrnl-threaded_inserts' 2024-02-19 16:13:26 +00:00
Chris Palmer
30c67e742b Updated the front page image. 2024-02-19 16:10:19 +00:00
Chris Palmer
2506e5aa31 Merge branch 'threaded_inserts' of https://github.com/jeroenrnl/NopSCADlib into jeroenrnl-threaded_inserts 2024-02-19 15:00:48 +00:00
Chris Palmer
1f313aa4ac Updated changelog. 2024-02-19 00:06:35 +00:00
Chris Palmer
63a4271c4c Updated libtest image. 2024-02-18 23:56:47 +00:00
Chris Palmer
0edf3a2f75 Cable clips can now handle up to 9 wires, have the nut and bolt flipped or use an insert.
cable_radius() now handles cables with up to 20 wires.
cable_bundle() and cable_bundle_positions() now handle bundles up to 9 wires.
Added cable_merge().
2024-02-18 23:51:30 +00:00
Jeroen Roos
f6404b939f Added T-Tracks and accessories 2024-02-18 22:10:01 +01:00
Jeroen Roos
efb1153e22 Add threaded inserts 2024-02-15 22:01:36 +01:00
Chris Palmer
a3b27a736e Changelog updated. 2024-02-10 12:22:37 +00:00
Chris Palmer
8540e04a10 Metal hex pillars now chamfered. 2024-02-10 12:21:17 +00:00
Chris Palmer
4c6a2b177f Updated changelog. 2024-02-10 01:13:56 +00:00
Chris Palmer
79478104d6 Dome option added to nut to draw acorn nuts.
Chamfers added to nuts and hex head screws when manifold is used.
2024-02-10 01:11:54 +00:00
Chris Palmer
38196e9f78 Mods to allow the manifold experimetal option to be used. 2024-02-10 01:05:24 +00:00
Chris Palmer
9666c018a0 Made sheet overridable in box_base_blank(). 2024-02-05 19:16:10 +00:00
Chris Palmer
8372655f25 Updated changelog. 2024-02-05 01:03:52 +00:00
Chris Palmer
f8a9c16360 Merge branch 'jeroenrnl-extra_mdf' 2024-02-05 00:59:29 +00:00
Chris Palmer
38988bacfa Updated images. 2024-02-05 00:55:17 +00:00
Chris Palmer
f26ed7443d Merge branch 'extra_mdf' of https://github.com/jeroenrnl/NopSCADlib into jeroenrnl-extra_mdf 2024-02-05 00:33:04 +00:00
Chris Palmer
453b68aaf9 Merge branch 'jeroenrnl-svg' 2024-02-05 00:22:41 +00:00
Chris Palmer
1ce7b64c73 Updated image. 2024-02-05 00:21:58 +00:00
Chris Palmer
9230fa78d7 Merge branch 'svg' of https://github.com/jeroenrnl/NopSCADlib into jeroenrnl-svg 2024-02-04 23:41:03 +00:00
Chris Palmer
a85c5cfa4b Merge branch 'igramul-feature/add-HW-803-1-way-relais-module' 2024-02-04 23:39:39 +00:00
Chris Palmer
926dd8ca90 Reordered the PCB lists to fix the layout.
Updated the images.
2024-02-04 23:32:13 +00:00
Chris Palmer
2ccfc1b506 Merge branch 'feature/add-HW-803-1-way-relais-module' of https://github.com/igramul/NopSCADlib into igramul-feature/add-HW-803-1-way-relais-module 2024-02-04 22:58:56 +00:00
Chris Palmer
fff0e9e3cb Merge branch 'igramul-feature/add-display-LCD2004A' 2024-02-04 22:57:32 +00:00
Chris Palmer
43b101ae1e Reordered the display list into reducing height for better layout.
Updated the images.
2024-02-04 22:56:09 +00:00
Jeroen Roos
f85fdca051 Add generating SVG file for CNC usage
Generate SVG files, like DXF files for CNC usage
2024-02-04 23:41:55 +01:00
Chris Palmer
1fc2be04d5 Merge branch 'feature/add-display-LCD2004A' of https://github.com/igramul/NopSCADlib into igramul-feature/add-display-LCD2004A 2024-02-04 21:19:16 +00:00
Chris
e3ad32713d Rename pcb_utils.scad to PCB_utils.scad
Fixed the filename case of PCB_utils.scad.
2024-02-04 19:02:14 +00:00
Jeroen Roos
82980392c9 Add extra MDF thicknesses 2024-02-04 19:22:21 +01:00
Lukas Burger
3961d7f1a4 add HW-803 5V 1 way relay module 2024-02-02 20:31:19 +01:00
Lukas Burger
1996189ab2 update readme file 2024-01-31 20:43:50 +01:00
Lukas Burger
9f8c309643 add display LCD2004A 2024-01-30 21:18:01 +01:00
Chris Palmer
3995f685dd Removed debug echo(). 2024-01-14 23:03:10 +00:00
Chris Palmer
e2ba69be46 Updated changelog. 2024-01-14 22:53:29 +00:00
99 changed files with 1182 additions and 323 deletions

View File

@@ -3,6 +3,98 @@
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")
* 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.
* 2024-03-14 [`67408f8`](https://github.com/nophead/NopSCADlib/commit/67408f8422918416c617ec7389dbc09b2c62a2ae "show commit") [C.P.](# "Chris Palmer") Added `d_hole()` module.
* 2024-03-14 [`929abbe`](https://github.com/nophead/NopSCADlib/commit/929abbefda2c380b121c775371f197860c6c3aff "show commit") [C.P.](# "Chris Palmer") Updated front page image.
* 2024-03-14 [`c7727e7`](https://github.com/nophead/NopSCADlib/commit/c7727e7106e3829a6b5f6c501b1a082d540a4a68 "show commit") [C.P.](# "Chris Palmer") Added Sellotape to sheets.
* 2024-03-14 [`1dbba5a`](https://github.com/nophead/NopSCADlib/commit/1dbba5a650f8dac2d05a5668008e61a5ec22ea4f "show commit") [C.P.](# "Chris Palmer") Added `camera_lens_height()` function.
#### [v21.16.1](https://github.com/nophead/NopSCADlib/releases/tag/v21.16.1 "show release") Fixes [...](https://github.com/nophead/NopSCADlib/compare/v21.16.0...v21.16.1 "diff with v21.16.0")
* 2024-03-14 [`db2a9a8`](https://github.com/nophead/NopSCADlib/commit/db2a9a8a24966f098d4c0c8157de98a885b79a85 "show commit") [C.P.](# "Chris Palmer") Ziptie test can now show wires with t `=` 0.
* 2024-03-14 [`6ced9c8`](https://github.com/nophead/NopSCADlib/commit/6ced9c871c5a637dbe8494836a4233e1f6cd4971 "show commit") [C.P.](# "Chris Palmer") Fixed FOV for ESP32 camera being rotated.
Shortened the ESP32 camera header pins.
* 2024-03-14 [`d6b00fb`](https://github.com/nophead/NopSCADlib/commit/d6b00fbf5719239adc5e8b66f863c003a50806d3 "show commit") [C.P.](# "Chris Palmer") Removed unused test code.
* 2024-03-14 [`2c996bb`](https://github.com/nophead/NopSCADlib/commit/2c996bb7a143a85c21833a69f56f2f47afabe072 "show commit") [C.P.](# "Chris Palmer") Fixed random error caused by not running bom first.
### [v21.16.0](https://github.com/nophead/NopSCADlib/releases/tag/v21.16.0 "show release") Additions [...](https://github.com/nophead/NopSCADlib/compare/v21.15.0...v21.16.0 "diff with v21.15.0")
* 2024-02-19 [`fdb92ec`](https://github.com/nophead/NopSCADlib/commit/fdb92ec263d60a42e04f06abfeec5e1648a12b6b "show commit") [C.P.](# "Chris Palmer") Improved layout to fit into front page view.
* 2024-02-18 [`f6404b9`](https://github.com/nophead/NopSCADlib/commit/f6404b939f714b3121dc6e9737cc24f3b9c64ebb "show commit") [J.R.](# "Jeroen Roos") Added T-Tracks and accessories
### [v21.15.0](https://github.com/nophead/NopSCADlib/releases/tag/v21.15.0 "show release") Additions [...](https://github.com/nophead/NopSCADlib/compare/v21.14.0...v21.15.0 "diff with v21.14.0")
* 2024-02-19 [`30c67e7`](https://github.com/nophead/NopSCADlib/commit/30c67e742bb3603fa41b41e1a144989947e58ad7 "show commit") [C.P.](# "Chris Palmer") Updated the front page image.
* 2024-02-12 [`efb1153`](https://github.com/nophead/NopSCADlib/commit/efb1153e2245fa67193cd7b49ac0926239c3b703 "show commit") [J.R.](# "Jeroen Roos") Add threaded inserts
### [v21.14.0](https://github.com/nophead/NopSCADlib/releases/tag/v21.14.0 "show release") Additions [...](https://github.com/nophead/NopSCADlib/compare/v21.13.1...v21.14.0 "diff with v21.13.1")
* 2024-02-18 [`63a4271`](https://github.com/nophead/NopSCADlib/commit/63a4271c4c1bc97e93e67e8178515be1cfda9e43 "show commit") [C.P.](# "Chris Palmer") Updated libtest image.
* 2024-02-18 [`0edf3a2`](https://github.com/nophead/NopSCADlib/commit/0edf3a2f75d729aa663836878d278226e7bd8094 "show commit") [C.P.](# "Chris Palmer") Cable clips can now handle up to 9 wires, have the nut and bolt flipped or use an insert.
`cable_radius()` now handles cables with up to 20 wires.
`cable_bundle()` and `cable_bundle_positions()` now handle bundles up to 9 wires.
Added `cable_merge()`.
#### [v21.13.1](https://github.com/nophead/NopSCADlib/releases/tag/v21.13.1 "show release") Fixes [...](https://github.com/nophead/NopSCADlib/compare/v21.13.0...v21.13.1 "diff with v21.13.0")
* 2024-02-10 [`8540e04`](https://github.com/nophead/NopSCADlib/commit/8540e04a10d83be4ff454fa8999614e5137dd0ab "show commit") [C.P.](# "Chris Palmer") Metal hex pillars now chamfered.
### [v21.13.0](https://github.com/nophead/NopSCADlib/releases/tag/v21.13.0 "show release") Additions [...](https://github.com/nophead/NopSCADlib/compare/v21.12.0...v21.13.0 "diff with v21.12.0")
* 2024-02-10 [`7947810`](https://github.com/nophead/NopSCADlib/commit/79478104d6b3a8673ae405606d2576ad98c4e90e "show commit") [C.P.](# "Chris Palmer") Dome option added to nut to draw acorn nuts.
Chamfers added to nuts and hex head screws when manifold is used.
* 2024-02-10 [`38196e9`](https://github.com/nophead/NopSCADlib/commit/38196e9f78f07d0f9a4eca0355cc6e99f29332fb "show commit") [C.P.](# "Chris Palmer") Mods to allow the manifold experimental option to be used.
* 2024-02-05 [`9666c01`](https://github.com/nophead/NopSCADlib/commit/9666c018a0a99be8d24a2454a4c1448b09f83af0 "show commit") [C.P.](# "Chris Palmer") Made sheet overridable in `box_base_blank()`.
### [v21.12.0](https://github.com/nophead/NopSCADlib/releases/tag/v21.12.0 "show release") Additions [...](https://github.com/nophead/NopSCADlib/compare/v21.11.0...v21.12.0 "diff with v21.11.0")
* 2024-02-05 [`38988ba`](https://github.com/nophead/NopSCADlib/commit/38988bacfa41dea19408b19cf06f134e51338ab0 "show commit") [C.P.](# "Chris Palmer") Updated images.
* 2024-02-04 [`8298039`](https://github.com/nophead/NopSCADlib/commit/82980392c9c9d13aa4619db888bd38c620b09ac0 "show commit") [J.R.](# "Jeroen Roos") Add extra MDF thicknesses
* 2024-02-05 [`1ce7b64`](https://github.com/nophead/NopSCADlib/commit/1ce7b64c73c77aa86f20c2b069ee031b30024818 "show commit") [C.P.](# "Chris Palmer") Updated image.
* 2024-02-04 [`f85fdca`](https://github.com/nophead/NopSCADlib/commit/f85fdca051a3cd11a35bfe2424c50cc4da018de4 "show commit") [J.R.](# "Jeroen Roos") Add generating SVG file for CNC usage
* Generate SVG files, like DXF files for CNC usage
* 2024-02-04 [`926dd8c`](https://github.com/nophead/NopSCADlib/commit/926dd8ca908030328d394dcc20e16ce036cbc51c "show commit") [C.P.](# "Chris Palmer") Reordered the PCB lists to fix the layout.
Updated the images.
* 2024-02-02 [`3961d7f`](https://github.com/nophead/NopSCADlib/commit/3961d7f1a4d3fd04a2fb174735d52ad8f95ecf7a "show commit") [L.B.](# "Lukas Burger") add HW-803 5V 1 way relay module
* 2024-02-04 [`43b101a`](https://github.com/nophead/NopSCADlib/commit/43b101ae1eb063018b29eb97172722d1977c1c53 "show commit") [C.P.](# "Chris Palmer") Reordered the display list into reducing height for better layout.
Updated the images.
* 2024-01-31 [`1996189`](https://github.com/nophead/NopSCADlib/commit/1996189ab232820a16cfa4a4b2d627cf508d6eb9 "show commit") [L.B.](# "Lukas Burger") update readme file
* 2024-01-30 [`9f8c309`](https://github.com/nophead/NopSCADlib/commit/9f8c3096435b7fea8a8870f07781a0f52adac7c3 "show commit") [L.B.](# "Lukas Burger") add display LCD2004A
* 2024-02-04 [`e3ad327`](https://github.com/nophead/NopSCADlib/commit/e3ad32713dbb5dfab3a14d70f9c6f5f8aaaa59d1 "show commit") [C.](# "Chris") Rename `pcb_utils.scad` to `PCB_utils.scad`
* Fixed the filename case of `PCB_utils.scad`.
* 2024-01-14 [`3995f68`](https://github.com/nophead/NopSCADlib/commit/3995f685dd31b087a2eec4cfe8b9f760f5eef3b9 "show commit") [C.P.](# "Chris Palmer") Removed debug `echo()`.
### [v21.11.0](https://github.com/nophead/NopSCADlib/releases/tag/v21.11.0 "show release") Additions [...](https://github.com/nophead/NopSCADlib/compare/v21.10.1...v21.11.0 "diff with v21.10.1")
* 2024-01-14 [`41859ec`](https://github.com/nophead/NopSCADlib/commit/41859ec2245e3fee41cb9c79fb5a627193a4fec8 "show commit") [C.P.](# "Chris Palmer") Added `screw_thread_radius()` and `screw_angle()` functions.
* 2024-01-14 [`cd95ef9`](https://github.com/nophead/NopSCADlib/commit/cd95ef95abed30e4004905972c9abcacdad0dc5e "show commit") [C.P.](# "Chris Palmer") Added GT2x12, GT3x6, GT3x9 and GT3x12 belts.
* 2024-01-12 [`7a9e738`](https://github.com/nophead/NopSCADlib/commit/7a9e73830e16a843a14debb8d9b770243067cf63 "show commit") [C.P.](# "Chris Palmer") Belt part number is not always the same as the pitch.
#### [v21.10.1](https://github.com/nophead/NopSCADlib/releases/tag/v21.10.1 "show release") Fixes [...](https://github.com/nophead/NopSCADlib/compare/v21.10.0...v21.10.1 "diff with v21.10.0")
* 2023-12-01 [`ebe2dfd`](https://github.com/nophead/NopSCADlib/commit/ebe2dfd4fd8ba042b634030f7d463d0ba0d8c4cd "show commit") [C.P.](# "Chris Palmer") Fixed explode line position on short inserts.

View File

@@ -41,13 +41,14 @@ pp1_colour = is_undef($pp1_colour) ? rr_green : $pp1_colour;// pri
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
manifold = is_undef($manifold) ? false : $manifold; // Manifold library being used instead of cgal
// Minimum wall is about two filaments wide but we extrude it closer to get better bonding
squeezed_wall = $preview ? 2 * extrusion_width - layer_height * (1 - PI / 4)
: extrusion_width - layer_height / 2 + nozzle / 2 + extrusion_width / 2;
inf = 1e10; // very big
inf = 1e10; // very big
big = manifold ? 1e3 : inf; // Not too big for manifold
eps = 1/128; // small fudge factor to stop CSG barfing on coincident faces.
fa = is_undef($vitamin_fa) ? 6 : $vitamin_fa; // Used for drawing vitamins, rather than printing.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 969 KiB

After

Width:  |  Height:  |  Size: 1001 KiB

View File

@@ -112,6 +112,7 @@ use <tests/stepper_motors.scad>
use <tests/Swiss_clips.scad>
use <tests/toggles.scad>
use <tests/transformers.scad>
use <tests/ttracks.scad>
use <tests/tubings.scad>
use <tests/veroboard.scad>
use <tests/washers.scad>
@@ -220,15 +221,12 @@ translate([950, box_y])
box_test();
translate([950, 1525])
rotate(-90)
bbox_test();
inserts_y = 0;
nuts_y = inserts_y + 20;
washers_y = nuts_y + 120;
washers_y = nuts_y + 140;
screws_y = washers_y + 120;
circlips_y = screws_y + 180;
threaded_inserts_y = screws_y + 180;
circlips_y = threaded_inserts_y + 30;
springs_y = circlips_y + 20;
o_rings_y = springs_y;
sealing_strip_y = springs_y + 20;
@@ -246,6 +244,10 @@ fans_y = displays_y + 110;
transformers_y = fans_y + 120;
psus_y = transformers_y + 190;
ttracks_y = pcbs_y + 150;
translate([840, ttracks_y])
ttracks();
translate([x0 + 35, inserts_y])
inserts();
@@ -258,6 +260,9 @@ translate([x0, nuts_y])
translate([x0, washers_y])
washers();
translate([x0, threaded_inserts_y])
threaded_inserts();
translate([x0, screws_y])
screws();
@@ -467,6 +472,9 @@ translate([370, transformers_y])
translate([x4, transformers_y])
no_explode() socket_boxes();
translate([950, transformers_y + 110])
rotate(-90)
bbox_test();
belts_y = 0;
rails_y = belts_y + 200;

View File

@@ -452,9 +452,10 @@ module box_screw_hole_positions(type) {
children();
}
module box_base_blank(type) { //! Generates a 2D template for the base sheet
module box_base_blank(type, sheet = false) { //! Generates a 2D template for the base sheet, `sheet` can be set to override the type
s = sheet ? sheet : box_base_sheet(type);
difference() {
sheet_2D(box_base_sheet(type), box_width(type), box_depth(type), box_sheet_r(type));
sheet_2D(s, box_width(type), box_depth(type), box_sheet_r(type));
box_screw_hole_positions(type)
drill(screw_clearance_radius(box_screw(type)), 0);
@@ -493,7 +494,8 @@ module box_shelf_screw_positions(type, screw_positions, thickness = 0, wall = un
for(p = screw_positions)
multmatrix(p)
translate_z(thickness)
children();
let($horizontal = true)
children();
r = box_boss_r(type);
inset = box_intrusion(type) - r + (r + insert_boss_radius(insert, w) + bezel_clearance / 2) / sqrt(2);
@@ -502,10 +504,11 @@ module box_shelf_screw_positions(type, screw_positions, thickness = 0, wall = un
for(x = [-1, 1], y = [-1, 1])
translate([x * (box_width(type) / 2 - inset), y * (box_depth(type) / 2 - inset)])
rotate(45 * x * (2 + y))
children();
let($horizontal = false)
children();
}
module box_shelf_bracket(type, screw_positions, wall = undef) { //! Generates a shelf bracket, the first optional child is a 2D cutout and the second 3D cutouts
module box_shelf_bracket(type, screw_positions, wall = undef) { //! Generates a shelf bracket, the first optional child is a 2D cutout and the second 3D cutouts, third child is 3D additions.
w = is_undef(wall) ? box_wall(type) : wall;
insert = box_shelf_insert(type);
lip = 2 * insert_boss_radius(insert, w);
@@ -560,9 +563,13 @@ module box_shelf_bracket(type, screw_positions, wall = undef) { //! Generates a
children(0);
}
hflip()
hflip() {
box_shelf_screw_positions(type, screw_positions, 0, w)
boss();
if($children > 2)
children(2);
}
}
if($children > 1)
hflip()
@@ -570,7 +577,7 @@ module box_shelf_bracket(type, screw_positions, wall = undef) { //! Generates a
hflip()
box_shelf_screw_positions(type, screw_positions, 0, w)
insert_hole(insert, counterbore = 1, horizontal = true);
insert_hole(insert, counterbore = 1, horizontal = $horizontal);
}
}

View File

@@ -18,100 +18,129 @@
//
//
//! Cable clips to order. Can be for one or two cables of different sizes.
//! 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.
//
include <../core.scad>
use <../vitamins/wire.scad>
use <../utils/fillet.scad>
use <../vitamins/insert.scad>
wall = 2;
function cable_clip_width(screw) = max(wall + 2 * screw_clearance_radius(screw) + wall, washer_diameter(screw_washer(screw))); //! Width given the `screw`.
function cable_clip_height(cable) = cable_height(cable) + wall; //! Height given the `cable`.
function cable_clip_extent(screw, cable) = screw_clearance_radius(screw) + wall + cable_width(cable) + wall; //! How far it extends from the screw.
function cable_clip_offset(screw, cable) = screw_clearance_radius(screw) + wall + cable_width(cable) / 2; //! The offset of the cable from the screw
function cable_clip_insert(screw, insert = true) = //! Insert type for clip, given screw.
is_list(insert) ? insert : insert ? screw_insert(screw, true) : false;
module single_cable_clip(screw, cable, h = 0) {
screw_dia = 2 * screw_clearance_radius(screw);
height = cable_clip_width(screw);
depth = h ? h : cable_height(cable) + wall;
function cable_clip_width(screw, insert = false) = //! Width given the `screw` and possibly insert.
let(insert = cable_clip_insert(screw, insert))
insert ? 2 * (insert_hole_radius(insert) + 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`.
let(insert = cable_clip_insert(screw, insert))
max(cable_height(cable) + wall, insert ? insert_hole_length(insert) + 1 : 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_offset(screw, cable, insert = false) = cable_clip_width(screw, insert) / 2 + cable_width(cable) / 2; //! The offset of the cable from the screw.
module single_cable_clip(screw, cable, h = 0, insert = false) {
insert = cable_clip_insert(screw, insert);
height = cable_clip_width(screw, insert);
depth = h ? h : cable_clip_height(cable, screw, insert);
w = cable_width(cable);
width = wall + w + wall + screw_dia + wall;
hole_x = wall + w + wall + screw_dia / 2;
width = wall + w + height;
hole_x = wall + w + height / 2;
rad = min(wall + cable_wire_size(cable) / 2, depth / 2);
r = extrusion_width - eps;
translate([-hole_x, 0]) difference() {
linear_extrude(height)
difference() {
hull() {
rounded_square([width, 1], r, center = false);
translate([width - 1, 0])
rounded_square([1, depth], r, center = false);
translate([rad, depth - rad])
circle(r = rad);
}
translate([wall + cable_width(cable) / 2, 0]) {
translate([-hole_x, 0])
difference() {
linear_extrude(height)
difference() {
hull() {
for(p = cable_bundle_positions(cable))
translate(p)
circle(d = cable_wire_size(cable));
rounded_square([width, 1], r, center = false);
square([w, eps], center = true);
translate([width - 1, 0])
rounded_square([1, depth], r, center = false);
translate([rad, depth - rad])
circle(r = rad);
}
translate([wall + cable_width(cable) / 2, 0]) {
hull() {
for(p = cable_bundle_positions(cable))
translate(p)
circle(d = cable_wire_size(cable));
square([w, eps], center = true);
}
for(side = [-1, 1])
translate([side * w / 2, 0])
hflip(side < 0)
fillet(r = r, h = 0);
}
for(side = [-1, 1])
translate([side * w / 2, 0])
hflip(side < 0)
fillet(r = r, h = 0);
}
}
translate([hole_x, depth / 2, height / 2])
rotate([90,0,0])
teardrop_plus(h = depth + 1, r = screw_dia / 2, center = true);
}
translate([hole_x, depth, height / 2])
rotate([90, 0, 0])
if(insert)
insert_hole(insert, 10, horizontal = true);
else
teardrop_plus(h = 2 * depth + 1, r = screw_clearance_radius(screw), center = true);
}
}
module double_cable_clip(screw, cable1, cable2) {
h = max(cable_clip_height(cable1), cable_clip_height(cable2));
module double_cable_clip(screw, cable1, cable2, insert = false) {
h = max(cable_clip_height(cable1, screw, insert), cable_clip_height(cable2, screw, insert));
union() {
single_cable_clip(screw, cable1, h);
single_cable_clip(screw, cable1, h, insert);
mirror([1,0,0]) single_cable_clip(screw, cable2, h);
mirror([1,0,0]) single_cable_clip(screw, cable2, h, insert);
}
}
module cable_clip(screw, cable1, cable2 = 0) { //! Create the STL for a single cable or two cable clip
function clip_str(screw) = str("cable_clip_", screw_radius(screw) * 20);
module cable_clip(screw, cable1, cable2 = 0, insert = 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 cable_str(cable) = str("_", cable_wires(cable), "_", round(cable_wire_size(cable) * 10));
if(cable2) {
stl(str(clip_str(screw), cable_str(cable1), cable_str(cable2)));
double_cable_clip(screw, cable1, cable2);
double_cable_clip(screw, cable1, cable2, insert);
}
else {
stl(str(clip_str(screw), cable_str(cable1)));
single_cable_clip(screw, cable1);
single_cable_clip(screw, cable1, h = 0, insert = insert);
}
}
module cable_clip_assembly(screw, thickness, cable1, cable2 = 0) { //! Cable clip with the fasteners
height = max(cable_clip_height(cable1), cable2 ? cable_clip_height(cable2) : 0);
module cable_clip_assembly(screw, thickness, cable1, cable2 = 0, flip = false, insert = false) { //! Cable clip with the fasteners
flip = flip || insert; // Screw must be below if using an insert
insert = cable_clip_insert(screw, insert);
height = max(cable_clip_height(cable1, screw, insert), cable2 ? cable_clip_height(cable2, screw, insert) : 0);
stl_colour(pp1_colour) render()
translate([0, cable_clip_width(screw) / 2]) rotate([90, 0, 0])
cable_clip(screw, cable1, cable2);
translate([0, cable_clip_width(screw, insert) / 2])
rotate([90, 0, 0])
cable_clip(screw, cable1, cable2, insert);
nut = screw_nut(screw);
screw_len = screw_length(screw, height + thickness, 2, nyloc = !insert, insert = insert);
translate_z(height)
screw_and_washer(screw, screw_length(screw, height + thickness, 2, nyloc = true));
if(flip)
if(insert)
insert(insert);
else
nut_and_washer(nut, true);
else
screw_and_washer(screw, screw_len);
translate_z(-thickness)
vflip()
nut_and_washer(screw_nut(screw), true);
if(flip)
screw_and_washer(screw, screw_len, insert);
else
nut_and_washer(nut, true);
}

View File

@@ -383,9 +383,3 @@ module camera_housing(cam) {
rotate(90)
camera_bracket(cam);
}
cam = rpi_camera_v2;
if($preview)
camera_fastened_assembly(cam, 3);
else
camera_housing(cam);

198
readme.md
View File

@@ -43,13 +43,13 @@ A list of changes classified as breaking, additions or fixes is maintained in [C
<tr><td> <a href = "#extrusion_brackets">Extrusion_brackets</a> </td><td> <a href = "#psus">PSUs</a> </td><td> <a href = "#terminals">Terminals</a> </td><td> <a href = "#pocket_handle">Pocket_handle</a> </td><td> <a href = "#sweep">Sweep</a> </td><td></td></tr>
<tr><td> <a href = "#extrusions">Extrusions</a> </td><td> <a href = "#panel_meters">Panel_meters</a> </td><td> <a href = "#toggles">Toggles</a> </td><td> <a href = "#press_fit">Press_fit</a> </td><td> <a href = "#thread">Thread</a> </td><td></td></tr>
<tr><td> <a href = "#fans">Fans</a> </td><td> <a href = "#photo_interrupters">Photo_interrupters</a> </td><td> <a href = "#transformers">Transformers</a> </td><td> <a href = "#printed_box">Printed_box</a> </td><td> <a href = "#tube">Tube</a> </td><td></td></tr>
<tr><td> <a href = "#fastons">Fastons</a> </td><td> <a href = "#pillars">Pillars</a> </td><td> <a href = "#tubings">Tubings</a> </td><td> <a href = "#printed_pulleys">Printed_pulleys</a> </td><td></td><td></td></tr>
<tr><td> <a href = "#fuseholder">Fuseholder</a> </td><td> <a href = "#pillow_blocks">Pillow_blocks</a> </td><td> <a href = "#variacs">Variacs</a> </td><td> <a href = "#ribbon_clamp">Ribbon_clamp</a> </td><td></td><td></td></tr>
<tr><td> <a href = "#gear_motors">Gear_motors</a> </td><td> <a href = "#pin_headers">Pin_headers</a> </td><td> <a href = "#veroboard">Veroboard</a> </td><td> <a href = "#ssr_shroud">SSR_shroud</a> </td><td></td><td></td></tr>
<tr><td> <a href = "#geared_steppers">Geared_steppers</a> </td><td> <a href = "#potentiometers">Potentiometers</a> </td><td> <a href = "#washers">Washers</a> </td><td> <a href = "#screw_knob">Screw_knob</a> </td><td></td><td></td></tr>
<tr><td> <a href = "#green_terminals">Green_terminals</a> </td><td> <a href = "#pulleys">Pulleys</a> </td><td> <a href = "#wire">Wire</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></td><td> <a href = "#zipties">Zipties</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></td><td></td><td></td><td></td><td></td></tr>
<tr><td> <a href = "#fastons">Fastons</a> </td><td> <a href = "#pillars">Pillars</a> </td><td> <a href = "#ttracks">Ttracks</a> </td><td> <a href = "#printed_pulleys">Printed_pulleys</a> </td><td></td><td></td></tr>
<tr><td> <a href = "#fuseholder">Fuseholder</a> </td><td> <a href = "#pillow_blocks">Pillow_blocks</a> </td><td> <a href = "#tubings">Tubings</a> </td><td> <a href = "#ribbon_clamp">Ribbon_clamp</a> </td><td></td><td></td></tr>
<tr><td> <a href = "#gear_motors">Gear_motors</a> </td><td> <a href = "#pin_headers">Pin_headers</a> </td><td> <a href = "#variacs">Variacs</a> </td><td> <a href = "#ssr_shroud">SSR_shroud</a> </td><td></td><td></td></tr>
<tr><td> <a href = "#geared_steppers">Geared_steppers</a> </td><td> <a href = "#potentiometers">Potentiometers</a> </td><td> <a href = "#veroboard">Veroboard</a> </td><td> <a href = "#screw_knob">Screw_knob</a> </td><td></td><td></td></tr>
<tr><td> <a href = "#green_terminals">Green_terminals</a> </td><td> <a href = "#pulleys">Pulleys</a> </td><td> <a href = "#washers">Washers</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></td><td> <a href = "#wire">Wire</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></td><td> <a href = "#zipties">Zipties</a> </td><td></td><td></td><td></td></tr>
</table>
---
@@ -779,6 +779,11 @@ PCB cameras.
| `camera_lens_offset(type)` | Offset of the lens center from the PCB centre |
| `camera_pcb(type)` | The PCB part of the camera |
### Functions
| Function | Description |
|:--- |:--- |
| `camera_lens_height(type)` | The height of the lens stack |
### Modules
| Module | Description |
|:--- |:--- |
@@ -982,6 +987,7 @@ D-connectors. Can be any number of ways, male or female, solder buckets, PCB mou
| Module | Description |
|:--- |:--- |
| `d_connector_holes(type)` | Place children at the screw hole positions |
| `d_hole(type, h = 0, center = true, clearance = 0.2)` | Make a hole to clear the back of d-connector |
| `d_pillar()` | Draw a pillar for a D-connector |
| `d_plug(type, socket = false, pcb = false, idc = false)` | Draw specified D plug, which can be IDC, PCB or plain solder bucket |
| `d_plug_D(length, width, rad)` | D plug D shape |
@@ -1091,6 +1097,7 @@ LCD displays.
| 1 | `display(HDMI5)` | HDMI display 5" |
| 1 | `display(TFT128x160)` | LCD TFT ST7735 display 128x160 |
| 1 | `display(LCD1602A)` | LCD display 1602A |
| 1 | `display(LCD2004A)` | LCD display 2004A |
| 1 | `display(LCDS7282B)` | LCD display S-7282B |
| 1 | `display(SSD1963_4p3)` | LCD display SSD1963 4.3" |
@@ -1702,6 +1709,8 @@ Heatfit threaded inserts. Can be pushed into thermoplastics using a soldering ir
| `insert_ring2_d(type)` | Diameter of the middle ring |
| `insert_ring3_d(type)` | Diameter of the bottom ring |
| `insert_screw_diameter(type)` | Screw size |
| `threaded_insert_chamfer(type)` | Size of the chamfer for threaded inserts |
| `threaded_insert_pitch(type)` | Pitch of the outer thread for threaded inserts |
### Functions
| Function | Description |
@@ -1717,6 +1726,7 @@ Heatfit threaded inserts. Can be pushed into thermoplastics using a soldering ir
| `insert_boss(type, z, wall = 2 * extrusion_width)` | Make a boss to take an insert |
| `insert_hole(type, counterbore = 0, horizontal = false)` | Make a hole to take an insert, `counterbore` is the extra length for the screw |
| `insert_lug(insert, wall, counter_bore = 0, extension = 0, corner_r = 0, flying = true)` | Make a flying insert lug, see [ssr_shroud](#Ssr_shroud) |
| `threaded_insert(type)` | Draw specified threaded insert, for use in wood |
![inserts](tests/png/inserts.png)
@@ -1731,6 +1741,14 @@ Heatfit threaded inserts. Can be pushed into thermoplastics using a soldering ir
| 1 | `insert(CNCKM4)` | Heatfit insert M4 x 4mm |
| 1 | `insert(F1BM4)` | Heatfit insert M4 x 8.2mm |
| 2 | `insert(CNCKM5)` | Heatfit insert M5 x 5.8mm |
| 1 | `threaded_insert(M10x25)` | Threaded insert M10 x 25mm |
| 1 | `threaded_insert(M12x30)` | Threaded insert M12 x 30mm |
| 1 | `threaded_insert(M16x30)` | Threaded insert M16 x 30mm |
| 1 | `threaded_insert(M3x8)` | Threaded insert M3 x 8mm |
| 1 | `threaded_insert(M4x10)` | Threaded insert M4 x 10mm |
| 1 | `threaded_insert(M5x12)` | Threaded insert M5 x 12mm |
| 1 | `threaded_insert(M6x15)` | Threaded insert M6 x 15mm |
| 1 | `threaded_insert(M8x18)` | Threaded insert M8 x 18mm |
<a href="#top">Top</a>
@@ -2347,6 +2365,7 @@ If a nut is given a child then it gets placed on its top surface.
### Properties
| Function | Description |
|:--- |:--- |
| `nut_dome(type)` | Dome height and max thread depth if a domed acorn nut |
| `nut_pitch(type)` | Pitch if not standard metric course thread |
| `nut_radius(type)` | Radius across the corners |
| `nut_size(type)` | Diameter of the corresponding screw |
@@ -2359,8 +2378,10 @@ If a nut is given a child then it gets placed on its top surface.
### Functions
| Function | Description |
|:--- |:--- |
| `nut_dome_height(type)` | Height of the domed version |
| `nut_flat_radius(type)` | Radius across the flats |
| `nut_thickness(type, nyloc = false)` | Thickness of plain or nyloc version |
| `nut_thread_depth(type)` | Max thread depth in domed version |
| `nut_trap_flat_radius(nut, horizontal = false)` | Radius across the flats of a nut trap |
| `nut_trap_radius(nut, horizontal = false)` | Radius across the corners of a nut trap |
| `t_nut_tab(type)` | Sliding t-nut T dimensions |
@@ -2368,7 +2389,7 @@ If a nut is given a child then it gets placed on its top surface.
### Modules
| Module | Description |
|:--- |:--- |
| `nut(type, nyloc = false, brass = false, nylon = false)` | Draw specified nut |
| `nut(type, nyloc = false, brass = false, nylon = false, dome = false)` | Draw specified nut |
| `nut_and_washer(type, nyloc)` | Draw nut with corresponding washer |
| `nut_square(type, brass = false, nylon = false)` | Draw specified square nut |
| `nut_trap(screw, nut, depth = 0, horizontal = false, supported = false, h = 200)` | Make a nut trap |
@@ -2389,24 +2410,29 @@ If a nut is given a child then it gets placed on its top surface.
| 1 | `sliding_t_nut(M3_sliding_t_nut)` | Nut M3 sliding T |
| 1 | `nut(M3_nut)` | Nut M3 x 2.4mm |
| 1 | `nut(M3_nut, brass = true)` | Nut M3 x 2.4mm brass |
| 1 | `nut(M3_nut, dome = true)` | Nut M3 x 2.4mm domed |
| 1 | `nut(M3_nut, nyloc = true)` | Nut M3 x 2.4mm nyloc |
| 1 | `nut(M3nS_thin_nut)` | Nut M3nS 5.5 x 1.8mm |
| 1 | `sliding_t_nut(M4_hammer_nut)` | Nut M4 hammer |
| 1 | `sliding_t_nut(M4_sliding_t_nut)` | Nut M4 sliding T |
| 1 | `nut(M4_nut)` | Nut M4 x 3.2mm |
| 1 | `nut(M4_nut, dome = true)` | Nut M4 x 3.2mm domed |
| 1 | `nut(M4_nut, nyloc = true)` | Nut M4 x 3.2mm nyloc |
| 1 | `nut(M4nS_thin_nut)` | Nut M4nS 7 x 2.2mm |
| 1 | `sliding_t_nut(M5_sliding_t_nut)` | Nut M5 sliding T |
| 1 | `nut(M5_nut)` | Nut M5 x 4mm |
| 1 | `nut(M5_nut, dome = true)` | Nut M5 x 4mm domed |
| 1 | `nut(M5_nut, nyloc = true)` | Nut M5 x 4mm nyloc |
| 1 | `nut(M5nS_thin_nut)` | Nut M5nS 8 x 2.7mm |
| 1 | `sliding_t_nut(M6_sliding_t_nut)` | Nut M6 hammer |
| 1 | `nut(M6_half_nut)` | Nut M6 x 3mm |
| 1 | `nut(M6_nut)` | Nut M6 x 5mm |
| 1 | `nut(M6_nut, dome = true)` | Nut M6 x 5mm domed |
| 1 | `nut(M6_nut, nyloc = true)` | Nut M6 x 5mm nyloc |
| 1 | `nut(M6nS_thin_nut)` | Nut M6nS 10 x 3.2mm |
| 1 | `sliding_t_nut(M8_sliding_ball_t_nut)` | Nut M8 sliding T with spring loaded ball |
| 1 | `nut(M8_nut)` | Nut M8 x 6.5mm |
| 1 | `nut(M8_nut, dome = true)` | Nut M8 x 6.5mm domed |
| 1 | `nut(M8_nut, nyloc = true)` | Nut M8 x 6.5mm nyloc |
| 1 | `nut(M8nS_thin_nut)` | Nut M8nS 13 x 4mm |
| 1 | `washer(M6_washer)` | Washer M6 x 12.5mm x 1.5mm |
@@ -2848,6 +2874,7 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
| 1 | `pcb(ESP32_DOIT_V1)` | ESP32 DOIT DEV KIT V1 |
| 1 | `pcb(EnviroPlus)` | Enviro+ |
| 1 | `pcb(ExtruderPCB)` | Extruder connection PCB - not shown |
| 1 | `pcb(HW803_1WAY_RELAY)` | HW-803 5V 1 way relay module |
| 1 | `pcb(KY_040)` | KY-040 rotart encoder breakout |
| 1 | `pcb(Keyes5p1)` | Keyes5.1 Arduino Uno expansion board - not shown |
| 1 | `pcb(L9110S)` | L9110S 2-Channel motor driver module |
@@ -2861,7 +2888,7 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
| 1 | `molex_254(3)` | Molex KK header 3 way - not shown |
| 20 | `nut(M2_nut, nyloc = true)` | Nut M2 x 1.6mm nyloc |
| 38 | `nut(M2p5_nut, nyloc = true)` | Nut M2.5 x 2.2mm nyloc |
| 43 | `nut(M3_nut, nyloc = true)` | Nut M3 x 2.4mm nyloc |
| 47 | `nut(M3_nut, nyloc = true)` | Nut M3 x 2.4mm nyloc |
| 8 | `nut(M4_nut, nyloc = true)` | Nut M4 x 3.2mm nyloc |
| 1 | `pcb(OPZ2)` | Orange Pi Zero 2 |
| 1 | `pcb(PI_IO)` | PI_IO V2 - not shown |
@@ -2884,14 +2911,17 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
| 8 | `screw(M2_cap_screw, 20)` | Screw M2 cap x 20mm |
| 4 | `screw(M2_cap_screw, 25)` | Screw M2 cap x 25mm |
| 2 | `screw(M2p5_cap_screw, 20)` | Screw M2.5 cap x 20mm |
| 8 | `screw(M2p5_cap_screw, 25)` | Screw M2.5 cap x 25mm |
| 4 | `screw(M2p5_cap_screw, 25)` | Screw M2.5 cap x 25mm |
| 4 | `screw(M2p5_cap_screw, 30)` | Screw M2.5 cap x 30mm |
| 12 | `screw(M2p5_cap_screw, 35)` | Screw M2.5 cap x 35mm |
| 4 | `screw(M2p5_dome_screw, 25)` | Screw M2.5 dome x 25mm |
| 4 | `screw(M2p5_pan_screw, 20)` | Screw M2.5 pan x 20mm |
| 8 | `screw(M2p5_pan_screw, 30)` | Screw M2.5 pan x 30mm |
| 19 | `screw(M3_cap_screw, 16)` | Screw M3 cap x 16mm |
| 13 | `screw(M3_cap_screw, 20)` | Screw M3 cap x 20mm |
| 11 | `screw(M3_cap_screw, 30)` | Screw M3 cap x 30mm |
| 4 | `screw(M3_cap_screw, 25)` | Screw M3 cap x 25mm |
| 8 | `screw(M3_cap_screw, 30)` | Screw M3 cap x 30mm |
| 3 | `screw(M3_cap_screw, 35)` | Screw M3 cap x 35mm |
| 4 | `screw(M4_cap_screw, 20)` | Screw M4 cap x 20mm |
| 4 | `screw(M4_cap_screw, 25)` | Screw M4 cap x 25mm |
| 1 | `pcb(XIAO)` | Seeeduino XIAO |
@@ -2903,7 +2933,7 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
| 1 | `pcb(WD2002SJ)` | WD2002SJ Buck Boost DC-DC converter |
| 20 | `washer(M2_washer)` | Washer M2 x 5mm x 0.3mm |
| 38 | `washer(M2p5_washer)` | Washer M2.5 x 5.9mm x 0.5mm |
| 43 | `washer(M3_washer)` | Washer M3 x 7mm x 0.5mm |
| 47 | `washer(M3_washer)` | Washer M3 x 7mm x 0.5mm |
| 8 | `washer(M4_washer)` | Washer M4 x 9mm x 0.8mm |
| 1 | `pcb(ZC_A0591)` | ZC-A0591 ULN2003 driver PCB |
@@ -2911,23 +2941,24 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
| Qty | Filename |
| ---:|:--- |
| 4 | pcb_spacer20100.stl |
| 4 | pcb_spacer20130.stl |
| 4 | pcb_spacer20140.stl |
| 4 | pcb_spacer2070.stl |
| 4 | pcb_spacer2080.stl |
| 4 | pcb_spacer2090.stl |
| 4 | pcb_spacer25120.stl |
| 4 | pcb_spacer25150.stl |
| 2 | pcb_spacer25100.stl |
| 4 | pcb_spacer25130.stl |
| 4 | pcb_spacer25160.stl |
| 4 | pcb_spacer25170_2.stl |
| 4 | pcb_spacer25170.stl |
| 4 | pcb_spacer25180_2.stl |
| 4 | pcb_spacer25220.stl |
| 4 | pcb_spacer25190_2.stl |
| 4 | pcb_spacer25230.stl |
| 4 | pcb_spacer25240.stl |
| 4 | pcb_spacer25250.stl |
| 4 | pcb_spacer2580.stl |
| 2 | pcb_spacer2590.stl |
| 4 | pcb_spacer30190.stl |
| 4 | pcb_spacer30120.stl |
| 4 | pcb_spacer30200.stl |
| 3 | pcb_spacer30210.stl |
| 4 | pcb_spacer30210.stl |
| 3 | pcb_spacer30220.stl |
| 10 | pcb_spacer3050.stl |
| 9 | pcb_spacer3060.stl |
| 9 | pcb_spacer3070.stl |
@@ -2996,6 +3027,7 @@ Threaded pillars. Each end can be male or female.
| Function | Description |
|:--- |:--- |
| `pillar_bot_thread(type)` | Bottom thread length, + for male, - for female |
| `pillar_chamfered(type)` | True if pillar is chamfered |
| `pillar_height(type)` | Body height |
| `pillar_i_colour(type)` | Colour of the inner part |
| `pillar_id(type)` | Inner diameter of metal part |
@@ -4007,11 +4039,14 @@ When woven sheets (e.g. carbon fibre) are rendered it is necessary to specify th
| 1 | `sheet(Spring08, 30, 30, 2)` | Bi-metal saw blade 30mm x 30mm x 0.8mm |
| 1 | `sheet(Cardboard, 30, 30, 2)` | Corrugated cardboard 30mm x 30mm x 5mm |
| 1 | `sheet(Foam20, 30, 30, 2)` | Foam sponge 30mm x 30mm x 20mm |
| 1 | `sheet(Sellotape, 30, 30, 2)` | Sellotape tape 30mm x 30mm x 0.05mm |
| 1 | `sheet(DiBond, 30, 30, 2)` | Sheet DiBond 30mm x 30mm x 3mm |
| 1 | `sheet(DiBond6, 30, 30, 2)` | Sheet DiBond 30mm x 30mm x 6mm |
| 1 | `sheet(MDF10, 30, 30, 2)` | Sheet MDF 30mm x 30mm x 10mm |
| 1 | `sheet(MDF12, 30, 30, 2)` | Sheet MDF 30mm x 30mm x 12mm |
| 1 | `sheet(MDF19, 30, 30, 2)` | Sheet MDF 30mm x 30mm x 19mm |
| 1 | `sheet(MDF22, 30, 30, 2)` | Sheet MDF 30mm x 30mm x 22mm |
| 1 | `sheet(MDF3, 30, 30, 2)` | Sheet MDF 30mm x 30mm x 3mm |
| 1 | `sheet(MDF6, 30, 30, 2)` | Sheet MDF 30mm x 30mm x 6mm |
| 1 | `sheet(PMMA1p25, 30, 30, 2)` | Sheet acrylic 30mm x 30mm x 1.25mm |
| 1 | `sheet(PMMA10, 30, 30, 2)` | Sheet acrylic 30mm x 30mm x 10mm |
@@ -4194,6 +4229,7 @@ E.g. 475A is 4.7uF 10V on the parts list.
### Vitamins
| Qty | Module call | BOM entry |
| ---:|:--- |:---|
| 1 | `smd_inductor(CDRH104)` | CDRH104 package 10R |
| 1 | `smd_diode(DO214AC)` | DO214AC package SS34 |
| 1 | `smd_inductor(IND2525)` | IND2525 package 4R7 |
| 1 | `smd_led(LED0603, green)` | SMD LED 0603 green |
@@ -4656,6 +4692,80 @@ Iron core transformers. The grey shaded area is the keep out region where the te
| 1 | `transformer(SMALLTX)` | Transformer Small mains |
<a href="#top">Top</a>
---
<a name="ttracks"></a>
## Ttracks
T-Tracks used in woodworking jigs
[vitamins/ttracks.scad](vitamins/ttracks.scad) Object definitions.
[vitamins/ttrack.scad](vitamins/ttrack.scad) Implementation.
[tests/ttracks.scad](tests/ttracks.scad) Code for this example.
### Properties
| Function | Description |
|:--- |:--- |
| `t_insert_description(type)` | Description of this t-track insert |
| `t_insert_height(type)` | Height of t-track insert |
| `t_insert_thread(type)` | M thread for this the screw hole in this insert |
| `t_insert_top_thickness(type)` | Top thickness for t-track insert |
| `t_insert_top_width(type)` | Top Width of t-track insert |
| `t_insert_width(type)` | Width of t-track insert |
| `tbolt_description(type)` | Description of this t-track bolt |
| `tbolt_head_length(type)` | Head length for t-track bolt |
| `tbolt_head_thickness(type)` | Head thickness for t-track bolt |
| `tbolt_head_width(type)` | Head width for t-track bolt |
| `tbolt_thread(type)` | M thread for this bolt |
| `ttrack_fixture(type)` | Fixture, such as T-bolt or Miter insert used with this track |
| `ttrack_height(type)` | Height of track section |
| `ttrack_opening(type)` | Width of the opening |
| `ttrack_screw(type)` | Screw used to fasten track |
| `ttrack_screw_pitch(type)` | Distance between screws |
| `ttrack_slot_height(type)` | Height of the slot |
| `ttrack_slot_width(type)` | Width of the slot |
| `ttrack_top_thickness(type)` | Thickness of the top layer |
| `ttrack_width(type)` | Width of track section |
### Functions
| Function | Description |
|:--- |:--- |
| `ttrack_holes(type, length)` | Number of holes in a rail given its `length` |
### Modules
| Module | Description |
|:--- |:--- |
| `ttrack(type, length, colour = "LightSlateGray")` | Draw the specified rail |
| `ttrack_hole_positions(type, length)` | Position children over screw holes |
| `ttrack_place_bolt(type, pos, bolt = undef)` | Place a T-Bolt relative to the centre of the track |
| `ttrack_place_insert(type, pos, insert = undef)` | Place a T-Insert relative to the centre of the track |
![ttracks](tests/png/ttracks.png)
### Vitamins
| Qty | Module call | BOM entry |
| ---:|:--- |:---|
| 3 | `screw(M3_cs_cap_screw, 15)` | Screw M3 cs cap x 15mm |
| 3 | `screw(M4_cs_cap_screw, 15)` | Screw M4 cs cap x 15mm |
| 2 | `screw(M6_hex_screw, 15)` | Screw M6 hex x 15mm |
| 1 | `ttrack(ttrack_mitre_30mm, 120)` | T-Track ttrack_mitre_30mm x 120mm |
| 1 | `ttrack(ttrack_mitre_30mm, 200)` | T-Track ttrack_mitre_30mm x 200mm |
| 1 | `ttrack(ttrack_mitre_36mm, 120)` | T-Track ttrack_mitre_36mm x 120mm |
| 1 | `ttrack(ttrack_universal_19mm, 120)` | T-Track ttrack_universal_19mm x 120mm |
| 1 | `ttrack(ttrack_universal_19mm, 200)` | T-Track ttrack_universal_19mm x 200mm |
| 1 | `ttrack(ttrack_universal_19mm_A, 120, colour="red")` | T-Track ttrack_universal_19mm_A x 120mm |
| 1 | `ttrack(ttrack_universal_19mm_B, 120, colour="blue")` | T-Track ttrack_universal_19mm_B x 120mm |
| 1 | `T-Track Bolt M6` | M6 x 30mm |
| 1 | `T-Track Bolt M6 with small head` | M6 x 30mm |
| 3 | `T-Track Bolt M8` | M8 x 30mm |
| 1 | `ttrack_insert(TTrack_insert_Miter30_M6, 30, 1)` | T-Track insert, Miter track 30mm, M6 thread, M30mm, with 1 M6 |
| 1 | `ttrack_insert(TTrack_insert_Miter30_M6, 30, 1, colour="red")` | T-Track insert, Miter track 30mm, M6 thread, M30mm, with 1 M6 |
| 1 | `ttrack_insert(TTrack_insert_Miter30_M6, 60, 2, colour="red")` | T-Track insert, Miter track 30mm, M6 thread, M60mm, with 2 M6 |
| 1 | `ttrack_insert(TTrack_insert_Miter30_M8, 30, 1, colour="red")` | T-Track insert, Miter track 30mm, M8 thread, M30mm, with 1 M8 |
<a href="#top">Top</a>
---
@@ -4951,6 +5061,7 @@ Utilities for adding wires to the BOM and optionally drawing them and cable bund
| `cable_bundle_positions(cable)` | Positions of wires in a bundle to go through a cable strip |
| `cable_height(cable)` | Height in flat clip |
| `cable_is_ribbon(cable)` | Is a ribbon cable? |
| `cable_merge(cable1, cable2)` | Combine the wires of two cables |
| `cable_radius(cable)` | Radius of a bundle of wires, see <http://mathworld.wolfram.com/CirclePacking.html>. |
| `cable_tlen(cable)` | Twisted cable twist length |
| `cable_twisted_radius(cable)` | Approximate radius of a cable when twisted |
@@ -5082,7 +5193,7 @@ The top bezel can have an optional child, which is subtracted to allow modificat
| `box_back(type)` | Default back, can be overridden to customise |
| `box_back_blank(type, sheet = false)` | Generates a 2D template for the back sheet, `sheet` can be set to override the type |
| `box_base(type)` | Default base, can be overridden to customise |
| `box_base_blank(type)` | Generates a 2D template for the base sheet |
| `box_base_blank(type, sheet = false)` | Generates a 2D template for the base sheet, `sheet` can be set to override the type |
| `box_bezel(type, bottom)` | Generates top and bottom bezel STLs |
| `box_bezel_section(type, bottom, rows, cols, x, y)` | Generates interlocking sections of the bezel to allow it to be bigger than the printer |
| `box_corner_profile(type)` | Generates the corner profile STL for 3D printing. |
@@ -5096,7 +5207,7 @@ The top bezel can have an optional child, which is subtracted to allow modificat
| `box_right(type)` | Default right side, can be overridden to customise |
| `box_right_blank(type, sheet = false)` | Generates a 2D template for the right sheet, `sheet` can be set to override the type |
| `box_shelf_blank(type, sheet = false, wall = undef)` | Generates a 2D template for a shelf sheet |
| `box_shelf_bracket(type, screw_positions, wall = undef)` | Generates a shelf bracket, the first optional child is a 2D cutout and the second 3D cutouts |
| `box_shelf_bracket(type, screw_positions, wall = undef)` | Generates a shelf bracket, the first optional child is a 2D cutout and the second 3D cutouts, third child is 3D additions. |
| `box_shelf_bracket_section(type, rows, cols, x, y)` | Generates sections of the shelf bracket to allow it to be bigger than the printer |
| `box_shelf_screw_positions(type, screw_positions, thickness = 0, wall = undef, top_screws = true)` | Place children at the shelf screw positions |
| `box_top(type)` | Default top, can be overridden to customise |
@@ -5254,7 +5365,7 @@ fixing_blocks along the sides.
---
<a name="cable_clip"></a>
## Cable_clip
Cable clips to order. Can be for one or two cables of different sizes.
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.
[printed/cable_clip.scad](printed/cable_clip.scad) Implementation.
@@ -5263,35 +5374,41 @@ Cable clips to order. Can be for one or two cables of different sizes.
### Functions
| Function | Description |
|:--- |:--- |
| `cable_clip_extent(screw, cable)` | How far it extends from the screw. |
| `cable_clip_height(cable)` | Height given the `cable`. |
| `cable_clip_offset(screw, cable)` | The offset of the cable from the screw |
| `cable_clip_width(screw)` | Width given the `screw`. |
| `cable_clip_extent(screw, cable, insert = false)` | How far it extends from the screw. |
| `cable_clip_height(cable, screw = false, insert = false)` | Height given the `cable`. |
| `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_width(screw, insert = false)` | Width given the `screw` and possibly insert. |
### Modules
| Module | Description |
|:--- |:--- |
| `cable_clip(screw, cable1, cable2 = 0)` | Create the STL for a single cable or two cable clip |
| `cable_clip_assembly(screw, thickness, cable1, cable2 = 0)` | Cable clip with the fasteners |
| `cable_clip(screw, cable1, cable2 = 0, insert = 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](tests/png/cable_clip.png)
### Vitamins
| Qty | Module call | BOM entry |
| ---:|:--- |:---|
| 2 | `insert(CNCKM3)` | Heatfit insert M3 x 3mm |
| 5 | `nut(M3_nut, nyloc = true)` | Nut M3 x 2.4mm nyloc |
| 2 | `screw(M3_dome_screw, 12)` | Screw M3 dome x 12mm |
| 3 | `screw(M3_dome_screw, 16)` | Screw M3 dome x 16mm |
| 10 | `washer(M3_washer)` | Washer M3 x 7mm x 0.5mm |
| 2 | `screw(M3_dome_screw, 10)` | Screw M3 dome x 10mm |
| 1 | `screw(M3_dome_screw, 12)` | Screw M3 dome x 12mm |
| 4 | `screw(M3_dome_screw, 16)` | Screw M3 dome x 16mm |
| 12 | `washer(M3_washer)` | Washer M3 x 7mm x 0.5mm |
| 2 | `star_washer(M3_washer)` | Washer star M3 x 0.5mm |
### Printed
| Qty | Filename |
| ---:|:--- |
| 1 | cable_clip_30_10_13.stl |
| 1 | cable_clip_30I_10_13.stl |
| 1 | cable_clip_30I_5_14_6_14.stl |
| 1 | cable_clip_30_1_14_2_14.stl |
| 1 | cable_clip_30_1_60.stl |
| 1 | cable_clip_30_3_14_4_14.stl |
| 1 | cable_clip_30_5_14_6_14.stl |
| 1 | cable_clip_30_7_14_8_14.stl |
| 1 | cable_clip_30_9_14.stl |
<a href="#top">Top</a>
@@ -7334,6 +7451,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 |
| `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 |
| `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 |
| `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 |
@@ -7345,7 +7463,7 @@ Each vertex, apart from the first and the last, has an associated radius and the
### Modules
| 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](tests/png/sweep.png)
@@ -7436,7 +7554,7 @@ This is to prevent the global BOM page becoming too wide in large projects by ha
The example below shows how to define a vitamin and incorporate it into an assembly with sub-assemblies and make an exploded view.
The resulting flat BOM is shown but hierarchical BOMs are also generated for real projects.
If the code to make an STL or DXF is made a child of the `stl()` or `dxf()` module then the STL or DXF will be used in the assembly views generated by `views.py` instead of generating
If the code to make an STL, DXF or SVG is made a child of the `stl()`, `dxf()` or `svg()` module then the STL, DXF or SVG will be used in the assembly views generated by `views.py` instead of generating
it with code.
This can speed up the generation of the build instructions greatly but isn't compatible with STLs that include support structures.
@@ -7475,8 +7593,10 @@ The `pose()` module allows assembly views in the readme to be posed differently
| `pose_vflip(exploded = undef)` | Pose an STL or assembly for rendering to png by flipping around the X axis, `exploded = true for` just the exploded view or `false` for unexploded only. |
| `stl(name)` | Name an stl that will appear on the BOM, there needs to a module named `<name>_stl` to make it |
| `stl_colour(colour = pp1_colour, alpha = 1)` | Colour an stl where it is placed in an assembly. `alpha` can be used to make it appear transparent. |
| `svg(name)` | Name an svg that will appear on the BOM, there needs to a module named `<name>_svg` to make it |
| `use_dxf(name)` | Import a DXF to make a build panel |
| `use_stl(name)` | Import an STL to make a build platter |
| `use_svg(name)` | Import an SVG to make a build panel |
| `vitamin(description)` | Describe a vitamin for the BOM entry and precede it with a module call that creates it, eg. "widget(42): Widget size 42" |
![bom](tests/png/bom.png)
@@ -7487,6 +7607,8 @@ The `pose()` module allows assembly views in the readme to be posed differently
| 1 | `insert(F1BM3)` | Heatfit insert M3 x 5.8mm |
| 1 | `widget(3)` | Rivet like thing for 3mm sheets |
| 1 | `screw(M3_cap_screw, 8)` | Screw M3 cap x 8mm |
| 4 | `screw(M3_cap_screw, 10)` | Screw M3 cap x 10mm |
| 1 | `sheet(MDF6, 40, 40)` | Sheet MDF 40mm x 40mm x 6mm |
| 1 | `sheet(PMMA3, 20, 20, 1)` | Sheet acrylic 20mm x 20mm x 3mm |
| 1 | `washer(M3_washer)` | Washer M3 x 7mm x 0.5mm |
| 1 | `star_washer(M3_washer)` | Washer star M3 x 0.5mm |
@@ -7499,6 +7621,7 @@ The `pose()` module allows assembly views in the readme to be posed differently
### Routed
| Qty | Filename |
| ---:|:--- |
| 1 | mdf.svg |
| 1 | widget.dxf |
### Assemblies
@@ -7526,7 +7649,7 @@ Original version by Doug Moen on the OpenSCAD forum
| Module | Description |
|:--- |:--- |
| `box(xmin, ymin, zmin, xmax, ymax, zmax)` | Construct a box given its bounds |
| `clip(xmin = -inf, ymin = -inf, zmin = -inf, xmax = inf, ymax = inf, zmax = inf, convexity = 1)` | Clip child to specified boundaries |
| `clip(xmin = -big, ymin = -big, zmin = -big, xmax = big, ymax = big, zmax = big, convexity = 1)` | Clip child to specified boundaries |
![clip](tests/png/clip.png)
@@ -7572,6 +7695,7 @@ See [global_defs.scad](../../global_defs.scad) for a list of global constants.
| `extrude_if(h, center = true)` | Extrudes 2D object to 3D when `h` is nonzero, otherwise leaves it 2D |
| `hflip(flip=true)` | Invert children by doing a 180&deg; flip around the Y axis |
| `render_if(render = true, convexity = 2)` | Renders an object if `render` is true, otherwise leaves it unrendered |
| `render_manifold()` | Render if manifold to work around convexity bug in manifold |
| `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 |

View File

@@ -104,14 +104,14 @@ class BOM:
def add_part(self, s):
args = []
match = re.match(r'^(.*?\.stl|.*?\.dxf)\((.*)\)$', s) #look for name.stl(...) or name.dxf(...)
match = re.match(r'^(.*?\.stl|.*?\.dxf|.*?\.svg)\((.*)\)$', s) #look for name.stl(...), name.dxf(...) or name.svg(...)
if match:
s = match.group(1)
args = [match.group(2)]
if s[-4:] == ".stl":
parts = self.printed
else:
if s[-4:] == ".dxf":
if s[-4:] == ".dxf" or s[-4:] == ".svg":
parts = self.routed
else:
parts = self.vitamins

View File

@@ -169,6 +169,9 @@ if __name__ == '__main__':
# Print commits excluding merges
if not c.comment.startswith('Merge branch') and not c.comment.startswith('Merge pull') and not re.match(r'U.?.ated ch.*log.*', c.comment):
if not c.comment.startswith('Merge branch') \
and not c.comment.startswith('Merge pull') \
and not re.match(r'U.?.ated ch.*log.*', c.comment) \
and not re.match(r'Changelog updated.*', c.comment):
print('* %s [`%s`](%s "show commit") %s %s\n' % (c.date, c.hash[:7], url + '/commit/' + c.hash, initials(c.author), fixup_comment(c.comment, url)), file = file)
do_cmd(('codespell -w -L od ' + filename).split())

View File

@@ -35,7 +35,7 @@ def read_deps(dname):
for line in lines:
if line.startswith('\t'):
dep = line[1 : -1].rstrip(' \\').replace('\\ ', ' ')
if not os.path.basename(dep) in ['stl.scad', 'dxf.scad', 'svf.scad', 'png.scad', 'target.scad']:
if not os.path.basename(dep) in ['stl.scad', 'dxf.scad', 'svg.scad', 'png.scad', 'target.scad']:
deps.append(dep)
return deps
@@ -63,5 +63,5 @@ def source_dirs(bom_dir):
else:
if dir.endswith('/printed'):
lib_dirs.add(dir)
dirs.remove(source_dir)
dirs.discard(source_dir)
return [source_dir] + sorted(dirs) + sorted(lib_dirs)

View File

@@ -39,7 +39,7 @@ def bom_to_parts(bom_dir, part_type, assembly = None):
#
part_files = []
bom = assembly + '.txt' if assembly else "bom.txt"
suffix = ".dxf" if part_type == 'svg' else '.' + part_type
suffix = '.' + part_type
with open(bom_dir + '/' + bom, "rt") as f:
for line in f.readlines():
words = line.split()
@@ -106,7 +106,7 @@ def make_parts(target, part_type, parts = None):
#
# Find all the scad files
#
module_suffix = '_dxf' if part_type == 'svg' else '_' + part_type
module_suffix = '_' + part_type
for dir in source_dirs(bom_dir):
if targets and os.path.isdir(dir):
for filename in os.listdir(dir):
@@ -141,7 +141,7 @@ def make_parts(target, part_type, parts = None):
with open(part_maker_name, "w") as f:
f.write("include <NopSCADlib/global_defs.scad>\n")
f.write("use <%s/%s>\n" % (reltmp(dir, target), filename))
f.write("%s();\n" % module);
f.write("%s();\n" % module)
t = time.time()
openscad.run("-o", part_file, part_maker_name, "-D$bom=1", "-d", dname)
times.add_time(part, t)

View File

@@ -39,7 +39,7 @@ if __name__ == '__main__':
target = None if len(sys.argv) == 1 else sys.argv[1]
set_config(target, usage)
boms(target)
for part in ['stl', 'dxf']:
for part in ['stl', 'dxf', 'svg']:
make_parts(target, part)
render(target, part)
plateup(target, part)

View File

@@ -26,6 +26,8 @@ import subprocess, sys
def run_list(args, silent = False, verbose = False):
cmd = ["openscad"] + args + ["--hardwarnings"]
if "-D$manifold=true" in args:
cmd += ["--enable"] + ["manifold"]
if not silent:
for arg in cmd:
print(arg, end=" ")

View File

@@ -26,8 +26,9 @@ def check_options(dir = '.'):
global options, options_mtime
options = {
"show_threads": str(os.getenv("NOPSCADLIB_SHOW_THREADS")),
"vitamin_fa": str(os.getenv("NOPSCADLIB_VITAMIN_FA")),
"vitamin_fs": str(os.getenv("NOPSCADLIB_VITAMIN_FS"))
"vitamin_fa" : str(os.getenv("NOPSCADLIB_VITAMIN_FA")),
"vitamin_fs" : str(os.getenv("NOPSCADLIB_VITAMIN_FS")),
"manifold" : str(os.getenv("NOPSCADLIB_MANIFOLD"))
}
options_fname = dir + '/options.json'
try:

View File

@@ -31,8 +31,8 @@ import re
import time
import times
source_dirs = { "stl" : "platters", "dxf" : "panels" }
target_dirs = { "stl" : "printed", "dxf" : "routed" }
source_dirs = { "stl" : "platters", "dxf" : "panels", "svg" : "panels" }
target_dirs = { "stl" : "printed", "dxf" : "routed", "svg" : "routed" }
def plateup(target, part_type, usage = None):
#

View File

@@ -33,7 +33,7 @@ import json
from tmpdir import *
def usage():
print("\nusage:\n\trender [target_config] - Render images of the stl and dxf files.");
print("\nusage:\n\trender [target_config] - Render images of the stl, dxf and svg files.");
sys.exit(1)
def render(target, type):
@@ -57,7 +57,7 @@ def render(target, type):
with open(bom_file) as json_file:
flat_bom = json.load(json_file)
things = { 'stl' : 'printed', 'dxf' : 'routed' }[type]
things = { 'stl' : 'printed', 'dxf' : 'routed', 'svg' : 'routed' }[type]
colours = {}
for ass in flat_bom:
for part in ass[things]:
@@ -112,3 +112,4 @@ if __name__ == '__main__':
target = sys.argv[1] if len(sys.argv) > 1 else None
render(target, 'stl')
render(target, 'dxf')
render(target, 'svg')

View File

@@ -374,7 +374,12 @@ def views(target, do_assemblies = None):
print('\n|%s' % ('---|' * n), file = doc_file)
for j in range(n):
part = keys[i - n + j + 1]
print('| ![%s](dxfs/%s) %s' % (part, part.replace('.dxf','.png'), '|\n' if j == j - 1 else ''), end = '', file = doc_file)
if (part[-4:] == ".dxf"):
print('| ![%s](dxfs/%s) %s' % (part, part.replace('.dxf','.png'), '|\n' if j == j - 1 else ''), end = '', file = doc_file)
elif (part[-4:] == ".svg"):
print('| ![%s](svgs/%s) %s' % (part, part.replace('.svg','.png'), '|\n' if j == j - 1 else ''), end = '', file = doc_file)
else:
print("Unkown file type ", part[-4:], " for file ", part)
print('\n', file = doc_file)
print('\n', file = doc_file)

View File

@@ -25,11 +25,11 @@ include <../core.scad>
include <../vitamins/sheets.scad>
use <../vitamins/insert.scad>
screw = M3_cap_screw;
screwM3 = M3_cap_screw;
sheet = PMMA3;
height = 10;
insert = screw_insert(screw);
insert = screw_insert(screwM3);
module widget(thickness) {
vitamin(str("widget(", thickness, "): Rivet like thing for ", thickness, "mm sheets"));
@@ -46,7 +46,13 @@ module widget(thickness) {
module widget_stl() {
stl("widget")
union() {
rounded_rectangle([30, 30, 3], 2, true);
difference() {
rounded_rectangle([30, 30, 3], 2, true);
for(x = [-10,10])
for (y=[-10,10])
translate([x,y,-1.5])
cylinder(r=2, h=3.5);
}
render() insert_boss(insert, height, 2.2);
}
@@ -57,7 +63,18 @@ module widget_dxf() {
difference() {
sheet_2D(sheet, 20, 20, 1);
drill(screw_clearance_radius(screw), 0);
drill(screw_clearance_radius(screwM3), 0);
}
}
module mdf_svg() {
svg("mdf")
difference() {
sheet_2D(MDF6, 40,40);
for(x = [-10,10])
for (y=[-10,10])
translate([x,y,0])
drill(screw_clearance_radius(screwM3), 0);
}
}
@@ -85,11 +102,23 @@ assembly("widget_top") {
module widget_assembly()
assembly("widget") {
widget_base_assembly(); // Note this is not exploded because it is sub-assembly
translate_z(-6) {
render_2D_sheet(MDF6)
mdf_svg();
explode(0)
for(x = [-10,10])
for (y=[-10,10])
translate([x,y,-10])
screw(screwM3, 10);
}
explode(3)
widget_base_assembly(); // Note this is not exploded because it is sub-assembly
translate_z(height) {
translate_z(sheet_thickness(sheet))
screw_and_washer(screw, screw_length(screw, sheet_thickness(sheet) + 3, 2, longer = true), true);
screw_and_washer(screwM3, screw_length(screwM3, sheet_thickness(sheet) + 3, 2, longer = true), true);
explode(5)
translate_z(sheet_thickness(sheet) / 2 + eps)

View File

@@ -50,4 +50,5 @@ module pcbs() {
pcb(p);
}
if($preview)
pcbs();
let($show_threads = false)
pcbs();

View File

@@ -67,7 +67,7 @@ module smds() {
translate([0, 39])
layout([for(i = smd_inductors) smd_inductor_leads(i).x], 1)
let(i = smd_inductors[$i])
smd_inductor(i, "4R7");
smd_inductor(i, ["4R7", "10R"][$i % 2]);
translate([20, 6])
layout([for(q = smd_qfps) smd_qfp_body_size(q).x], 3)

View File

@@ -25,20 +25,20 @@ use <../vitamins/wire.scad>
sheet_thickness = 3;
cables = [
for(i = [1 : 6]) [i, 1.4], [1, 6], 0, [10, inch(0.05), true], 0
[10, inch(0.05), true], 0, for(i = [1 : 9]) [i, 1.4], 0, [1, 6], 0,
];
screw = M3_dome_screw;
module cable_clips() {
for(i = [0 : ceil(len(cables) / 2) - 1])
translate([i * 25, 0]) {
cable1 = cables[2 * i];
cable2 = cables[2 * i + 1];
for(i = [0 : ceil(len(cables) / 2) - 1]) {
cable1 = cables[2 * i];
cable2 = cables[2 * i + 1];
translate([i * 21 + (!cable2 ? cable_clip_offset(screw, cable1) / 2 : 0), 0]) {
insert = in([0, 3], i);
if($preview) {
cable_clip_assembly(screw, sheet_thickness, cable1, cable2);
cable_clip_assembly(screw, sheet_thickness, cable1, cable2, insert = insert, flip = i == 1);
for(j = [0 : 1])
let(cable = cables[2 * i + j])
@@ -46,14 +46,15 @@ module cable_clips() {
let(positions = cable_bundle_positions(cable))
for(i = [0 : len(positions) - 1])
let(p = positions[i])
translate([p.x + [-1, 1][j] * cable_clip_offset(screw, cable), 0, p.y])
translate([p.x + [-1, 1][j] * cable_clip_offset(screw, cable, insert = insert), 0, p.y])
rotate([90, 0, 0])
color([grey(20), "blue", "red", "orange", "yellow", "green", "brown", "purple", "grey", "white"][i])
cylinder(d = cable_wire_size(cable), h = 30, center = true);
}
else
cable_clip(screw, cable1, cable2);
cable_clip(screw, cable1, cable2, insert = insert);
}
}
}
cable_clips();

View File

@@ -20,8 +20,10 @@ include <../utils/core/core.scad>
use <../vitamins/fuseholder.scad>
thickness = 6;
module fuseholders()
fuseholder(6);
fuseholder(thickness);
if($preview)
let($show_threads = 1)

View File

@@ -22,7 +22,6 @@ use <../utils/layout.scad>
include <../vitamins/inserts.scad>
module inserts() {
for(i = [0: len(inserts) -1])
translate([10 * i, 5])
insert(inserts[i]);
@@ -32,7 +31,6 @@ module inserts() {
insert(short_inserts[i]);
stl_colour(pp1_colour)
translate([len(inserts) * 10, 0]) {
insert_lug(inserts[0], 2, 1);
@@ -42,6 +40,17 @@ module inserts() {
}
}
module threaded_inserts()
for(i = [0: len(threaded_inserts) -1]) {
d = insert_hole_radius(threaded_inserts[i]);
translate([(10 + d) * i, 0])
threaded_insert(threaded_inserts[i]);
}
if($preview)
let($show_threads = true)
let($show_threads = true) {
inserts();
translate([0, 20])
threaded_inserts();
}

View File

@@ -25,7 +25,11 @@ module nuts() {
translate([0, nyloc ? 20 : 0])
nut(n, nyloc);
translate([0, 40]) {
translate([0, 40])
if(nut_dome(n))
nut(n, dome = true);
translate([0, 60]) {
if(n == M3_nut)
nut(n, brass = true);
@@ -43,7 +47,7 @@ module nuts() {
#nut_trap(M8_cap_screw, n, h = 30);
}
translate([0, 60]) {
translate([0, 80]) {
if(n == M3_nut)
sliding_t_nut(M3_sliding_t_nut);
@@ -61,7 +65,7 @@ module nuts() {
sliding_t_nut(M8_sliding_ball_t_nut);
}
translate([0, 80]) {
translate([0, 100]) {
if(n == M3_nut)
sliding_t_nut(M3_hammer_nut);
@@ -69,7 +73,7 @@ module nuts() {
sliding_t_nut(M4_hammer_nut);
}
translate([0, 100]) {
translate([0, 120]) {
if(n == M3_nut)
nut_square(M3nS_thin_nut);
if(n == M4_nut)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 274 KiB

After

Width:  |  Height:  |  Size: 274 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 81 KiB

After

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 127 KiB

After

Width:  |  Height:  |  Size: 131 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 123 KiB

After

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 KiB

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 146 KiB

After

Width:  |  Height:  |  Size: 145 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 118 KiB

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 74 KiB

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 147 KiB

After

Width:  |  Height:  |  Size: 147 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 99 KiB

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 138 KiB

After

Width:  |  Height:  |  Size: 151 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 100 KiB

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 119 KiB

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 112 KiB

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 250 KiB

After

Width:  |  Height:  |  Size: 245 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 105 KiB

After

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 136 KiB

After

Width:  |  Height:  |  Size: 133 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 116 KiB

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 164 KiB

After

Width:  |  Height:  |  Size: 164 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 191 KiB

After

Width:  |  Height:  |  Size: 193 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 81 KiB

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 161 KiB

After

Width:  |  Height:  |  Size: 160 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 179 KiB

After

Width:  |  Height:  |  Size: 190 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 81 KiB

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 111 KiB

After

Width:  |  Height:  |  Size: 114 KiB

BIN
tests/png/ttracks.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 168 KiB

After

Width:  |  Height:  |  Size: 168 KiB

View File

@@ -73,7 +73,7 @@ module polyholes() {
// Alternating polyholes
//
translate([30, -40])
alt_polyhole_stl();
render_manifold() alt_polyhole_stl();
//
// Poly rings
//

View File

@@ -57,7 +57,7 @@ module screws() {
}
}
translate([20, 60, -15])
polysink_stl();
render_manifold() polysink_stl();
}
if($preview)

73
tests/ttracks.scad Normal file
View File

@@ -0,0 +1,73 @@
//
// NopSCADlib Copyright Chris Palmer 2024
// 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 <../utils/core/core.scad>
use <../utils/layout.scad>
use <../utils/maths.scad>
include <../vitamins/ttracks.scad>
module ttracks() {
colours = [ "LightSlateGray", "red", "blue", "LightSlateGray", "LightSlateGray" ];
gap = 8;
widths = [for(t = ttracks) ttrack_width(t)];
translate([0, 60])
layout(widths, gap) {
ttrack(ttracks[$i], 120, colours[$i]);
if($i < len(ttrack_bolts))
translate([0, -80])
ttrack_bolt(ttrack_bolts[$i], 30);
let(i = $i - len(ttrack_bolts))
if(i >= 0 && i < len(ttrack_inserts))
translate([0, -85])
rotate(90)
ttrack_insert(ttrack_inserts[i], 30, colour=colours[i]);
}
x = sumv(widths) + len(ttracks) * gap + ttrack_width(ttrack_universal_19mm) / 2;
translate([x, 20]) {
ttrack_assembly(ttrack_universal_19mm, 200);
ttrack_place_bolt(ttrack_universal_19mm, 50)
ttrack_bolt(ttrack_fixture(ttrack_universal_19mm), 30);
ttrack_place_bolt(ttrack_universal_19mm, -60)
ttrack_bolt(ttrack_fixture(ttrack_universal_19mm), 30);
}
x2 = x + ttrack_width(ttrack_universal_19mm) / 2 + gap + ttrack_width(ttrack_mitre_30mm) / 2;
translate([x2, 20]) {
ttrack_assembly(ttrack_mitre_30mm, 200);
ttrack_place_insert(ttrack_mitre_30mm, 50)
ttrack_insert(ttrack_fixture(ttrack_mitre_30mm), 30, 1, "red");
ttrack_place_insert(ttrack_mitre_30mm, -60) {
ttrack_insert(ttrack_fixture(ttrack_mitre_30mm), 60, 2, "red");
ttrack_insert_hole_positions(ttrack_fixture(ttrack_mitre_30mm), 60, 2)
translate_z(8)
screw(M6_hex_screw, 15);
}
}
}
if($preview)
let($show_threads = true)
ttracks();

View File

@@ -17,7 +17,7 @@
// If not, see <https://www.gnu.org/licenses/>.
//
wire_r = 5; // [1 : 20]
t = 0; // [0 : 3]
t = -1; // [-1 : 3]
include <../utils/core/core.scad>
use <../utils/layout.scad>
@@ -26,9 +26,9 @@ include <../vitamins/zipties.scad>
module zipties()
layout([for(z = zipties) 9], 2 * wire_r) {
ziptie(zipties[$i], wire_r, t);
ziptie(zipties[$i], wire_r, max(t, 0));
if(t)
if(t >= 0)
color(grey(20))
cylinder(r = wire_r, h = 10, center = true);

View File

@@ -31,7 +31,7 @@
//! The example below shows how to define a vitamin and incorporate it into an assembly with sub-assemblies and make an exploded view.
//! The resulting flat BOM is shown but hierarchical BOMs are also generated for real projects.
//!
//! If the code to make an STL or DXF is made a child of the `stl()` or `dxf()` module then the STL or DXF will be used in the assembly views generated by `views.py` instead of generating
//! If the code to make an STL, DXF or SVG is made a child of the `stl()`, `dxf()` or `svg()` module then the STL, DXF or SVG will be used in the assembly views generated by `views.py` instead of generating
//! it with code.
//! This can speed up the generation of the build instructions greatly but isn't compatible with STLs that include support structures.
//!
@@ -168,12 +168,32 @@ module dxf(name) { //! Name a dxf that will appear on the B
}
}
module svg(name) { //! Name an svg that will appear on the BOM, there needs to a module named `<name>_svg` to make it
if(bom_mode() && is_undef($in_svg)) {
if(is_undef($dxf_colour))
echo(str("~", name, ".svg"));
else
echo(str("~", name, ".svg(colour='", $dxf_colour, "')"));
}
if($children)
if(is_undef($pose))
let($in_svg = true)
children();
else {
path = is_undef($target) ? "/svgs/" : str("/", $target, "/svgs/");
import(str($cwd, path, name, ".svg"));
}
}
module use_stl(name) //! Import an STL to make a build platter
assert(false); // Here for documentation only, real version in core.scad
module use_dxf(name) //! Import a DXF to make a build panel
assert(false); // Here for documentation only, real version in core.scad
module use_svg(name) //! Import an SVG to make a build panel
assert(false); // Here for documentation only, real version in core.scad
function value_string(value) = is_string(value) ? str("\"", value, "\"") : str(value); //! Convert `value` to a string or quote it if it is already a string
function arg(value, default, name = "") = //! Create string for arg if not default, helper for `vitamin()`

View File

@@ -41,7 +41,7 @@ module box(xmin, ymin, zmin, xmax, ymax, zmax) //! Construct a box given its bou
[0,2,3,1]] // left
);
module clip(xmin = -inf, ymin = -inf, zmin = -inf, xmax = inf, ymax = inf, zmax = inf, convexity = 1) //! Clip child to specified boundaries
module clip(xmin = -big, ymin = -big, zmin = -big, xmax = big, ymax = big, zmax = big, convexity = 1) //! Clip child to specified boundaries
render(convexity = convexity) intersection() {
children();

View File

@@ -37,3 +37,9 @@ module use_dxf(name) { //! Import a DXF to make a build panel
path = is_undef($target) ? "../dxfs/" : str($cwd, "/", $target, "/dxfs/");
import(str(path, name, ".dxf"));
}
module use_svg(name) { //! Import an SVG to make a build panel
svg(name);
path = is_undef($target) ? "../svgs/" : str($cwd, "/", $target, "/svgs/");
import(str(path, name, ".svg"));
}

View File

@@ -74,6 +74,10 @@ module render_if(render = true, convexity = 2) //! Renders an object if `re
else
children();
module render_manifold() //! Render if manifold to work around convexity bug in manifold
render_if(manifold)
children();
module extrude_if(h, center = true) //! Extrudes 2D object to 3D when `h` is nonzero, otherwise leaves it 2D
if(h)
linear_extrude(h, center = center, convexity = 5) // 3D

View File

@@ -47,11 +47,11 @@ module offset_3D(r, chamfer_base = false) { //! Offset 3D shape by specified rad
else
if(r < 0)
render() difference() {
cube(inf / 2, center = true);
cube(big / 2, center = true);
minkowski() {
difference() {
cube(inf, center = true);
cube(big, center = true);
children();
}

View File

@@ -52,6 +52,6 @@ module cylindrical_wrap(r, h = eps) { //! Wrap a 2D child extruded to height `h`
translate([(sides / 2 - i) * -dx, 0])
children();
square([dx, inf], center = true);
square([dx, big], center = true);
}
}

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.
//
function sweep_transforms(path, loop = false, twist = 0) =
function sweep_transforms(path, loop = false, twist = 0, initial_rotation = undef) =
let(len = len(path),
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],
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 = i + 1,
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),
skin_faces = skin_faces(points, npoints, facets, loop),
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
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
for(i = [0 : len(path) - 2])
let(delta =
assert(path[i] != path[i + 1], str("Coincident points at path[", i, "] = ", path[i]))
path[i+1] - path[i],
segs = ceil(norm(delta) / min_segment)
)
for(j = [0 : segs - 1])
path[i] + delta * j / segs, // Linear interpolation
path[len(path) - 1]
let(delta =
assert(path[i] != path[i + 1], str("Coincident points at path[", i, "] = ", path[i]))
path[i+1] - path[i],
segs = ceil(norm(delta) / min_segment)
)
for(j = [0 : segs - 1])
path[i] + delta * j / segs, // Linear interpolation
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
segment = twists ? path_length(path) / twists / r2sides(2 * r) : inf,
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
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]) {
hull($fn = 16) {
translate(path[i])
sphere(0.1);
sphere(r);
translate(path[i + 1])
sphere(0.1);
sphere(r);
}
if(path[i] == path[i + 1])
translate(path[i])
color("red") sphere(1);
color("red") sphere($fn = 16, r * 4);
}

View File

@@ -30,6 +30,9 @@ function camera_connector_pos(type) = type[5]; //! The flex connector block for
function camera_connector_size(type)= type[6]; //! The flex connector block for the camera itself's size
function camera_fov(type) = type[7]; //! The field of view of the camera lens
function camera_lens_height(type) = //! The height of the lens stack
let(lenses = camera_lens(type), lens = lenses[len(lenses) - 1][0]) lens.y + lens.z;
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))

View File

@@ -67,7 +67,8 @@ rpi_camera = ["rpi_camera", "Raspberry Pi focusable camera", rpi_camera_pcb, [0,
[[0, 0, 12], 6],
[[0, 11, 4.3], 14 / 2, [8/2, 11/2, 1]],
],
[0, 18 - 1.5 - 2.5], [8, 5, 1.6]
[0, 18 - 1.5 - 2.5], [8, 5, 1.6],
[54, 41] // FOV
];
esp32_cam_x = 1; // Seems to vary as mine is offset but pictures on the web show it more centered.
@@ -96,7 +97,7 @@ ESP32_module = ["", "", 18, 26, 0.8, 0, 0.7, [1.1, 1.1, 0, gold], grey(18), f
ESP32_CAM_pcb = ["", "", 27, 40, 1.7, 2.5, 0, 0, grey(15), false, [],
[
[27 / 2, 26 / 2, 0, "-pcb", 0, ESP32_module],
for(side = [-1, 1]) [side * inch(0.45) + 27 / 2, -(4.2 + inch(.35)), 0, "-2p54header", 1, 8],
for(side = [-1, 1]) [side * inch(0.45) + 27 / 2, -(4.2 + inch(.35)), 0, "-2p54joiner", 1, 8],
[ 27 / 2, -8, 90, "uSD", [14.85, 14.65, 1.8]],
[ 27 / 2 + 1, 15, 0, "flat_flex", false],
[ 27 / 2 + inch(0.45), 10.5, 0, "block", 3, 3, 0.8, grey(90)],
@@ -151,7 +152,7 @@ ESP32_CAM = ["ESP32_CAM", "ESP32-CAM Camera module", ESP32_CAM_pcb, [esp32_cam_x
[[0, 0, 6.3], 3.5, [1, 1, 0.5]],
],
[1, -4], [15, 2.2, 1],
[54, 41] // FOV
[41, 54] // FOV
];

View File

@@ -23,6 +23,7 @@
include <../utils/core/core.scad>
use <../utils/thread.scad>
use <../utils/pcb_utils.scad>
use <nut.scad>
d_pillar_colour = grey(90);
d_plug_shell_colour = grey(80);
@@ -62,17 +63,13 @@ module d_pillar() { //! Draw a pillar for a D-connector
color(d_pillar_colour)
cylinder(d = screw, h = screw_length + 1);
color(d_pillar_colour) {
linear_extrude(height)
difference() {
circle(r = rad, $fn = 6);
circle(d = screw);
}
}
if(show_threads)
female_metric_thread(screw, pitch, height, false, colour = d_pillar_colour);
draw_nut(rad * 2, screw, height, pitch, d_pillar_colour, show_threads);
color(d_pillar_colour)
cylinder(d = screw + eps, h = 1);
}
module d_plug_D(length, width, rad) { //! D plug D shape
d = width / 2 - rad;
offset = d * sin(10);
@@ -83,6 +80,13 @@ module d_plug_D(length, width, rad) { //! D plug D shape
circle(rad);
}
module d_hole(type, h = 0, center = true, clearance = 0.2) { //! Make a hole to clear the back of d-connector
dwall = 0.5 + clearance;
extrude_if(h, center)
d_plug_D(d_lengths(type)[0] + 2 * dwall, d_widths(type)[0] + 2 * dwall, 2.5 + dwall);
}
module d_plug(type, socket = false, pcb = false, idc = false) { //! Draw specified D plug, which can be IDC, PCB or plain solder bucket
hole_r = 3.05 / 2;
dwall = 0.5;
@@ -109,7 +113,7 @@ module d_plug(type, socket = false, pcb = false, idc = false) { //! Draw specifi
// Shell
//
color(d_plug_shell_colour) {
linear_extrude( d_flange_thickness(type))
linear_extrude(d_flange_thickness(type))
difference() {
rounded_square([flange_length, flange_width], 2);

View File

@@ -54,6 +54,24 @@ LCD1602A = ["LCD1602A", "LCD display 1602A", 71.3, 24.3, 7.0, LCD1602APCB,
[], // clearance need for the ts ribbon
];
LCD2004APCB = pcb("", "", [98, 60, 1.65], hole_d = 2.9, land_d = 5, colour = "green",
holes = [[-2.5, -2.5], [-2.5, 2.5], [2.5, 2.5], [2.5, -2.5]],
components = [
[49+19.05, - 2.5, 0, "2p54header", 16, 1]
],
grid = [
49, 60 - 2.5, 16, 1, silver, inch(0.1), inch(0.1),
]
);
LCD2004A = ["LCD2004A", "LCD display 2004A", 97, 39.5, 9.0, LCD2004APCB,
[0, 0, 0], // pcb offst
[[-76 / 2, -26 / 2], [76 / 2, 26 / 2, 0.6]], // aperture
[], // touch screen
0, // thread length
[], // clearance need for the ts ribbon
];
LCDS7282BPCB = pcb("", "", [85, 36, 1.65], hole_d = 2.56, colour = "green",
holes = [[-2.5, -2.5], [-2.5, 2.5], [2.5, 2.5], [2.5, -2.5]],
components = [
@@ -149,6 +167,6 @@ BigTreeTech_TFT35v3_0 = ["BigTreeTech_TFT35v3_0", "BigTreeTech TFT35 v3.0",
];
displays = [HDMI5, SSD1963_4p3, BigTreeTech_TFT35v3_0, LCD1602A, LCDS7282B, TFT128x160];
displays = [HDMI5, SSD1963_4p3, LCD2004A, BigTreeTech_TFT35v3_0, LCD1602A, LCDS7282B, TFT128x160];
use <display.scad>

View File

@@ -20,7 +20,7 @@
//
//! 20mm panel mount fuse holder.
//
include <../utils/core/core.scad>
include <../core.scad>
include <spades.scad>
use <../utils/tube.scad>
use <../utils/thread.scad>
@@ -69,18 +69,10 @@ module fuseholder(thickness) { //! Fuseholder with nut in place for specified pa
vflip()
translate_z(thickness)
explode(height, explode_children = true) {
color(colour) {
color(colour)
tube(or = nut_d / 2, ir = thread_d / 2, h = nut_flange_t, center = false);
linear_extrude(nut_t)
difference() {
circle(d = nut_d, $fn = 6);
circle(d = thread_d);
}
}
if(show_threads && exploded())
female_metric_thread(thread_d, thread_p, nut_t, false, colour = colour);
draw_nut(nut_d, thread_d, nut_t, thread_p, colour, show_threads && exploded() || thickness > thread);
}
//
// Body

View File

@@ -32,6 +32,9 @@ function insert_barrel_d(type) = type[5]; //! Diameter of the main bar
function insert_ring1_h(type) = type[6]; //! Height of the top and middle rings
function insert_ring2_d(type) = type[7]; //! Diameter of the middle ring
function insert_ring3_d(type) = type[8]; //! Diameter of the bottom ring
function threaded_insert_pitch(type) = type[9]; //! Pitch of the outer thread for threaded inserts
function threaded_insert_chamfer(type) = type[10]; //! Size of the chamfer for threaded inserts
function insert_hole_length(type) = round_to_layer(insert_length(type)); //! Length of the insert rounded to layer height
@@ -46,6 +49,14 @@ function insert_nose_length(type, d) = let( //! The length before the second rin
module insert(type) { //! Draw specified insert
length = insert_length(type);
vitamin(str("insert(", type[0], "): Heatfit insert M", insert_screw_diameter(type), " x ", length, "mm"));
base_insert(type);
}
module base_insert(type) {
length = insert_length(type);
ring1_h = insert_ring1_h(type);
chamfer1 = (insert_ring2_d(type) - insert_barrel_d(type)) / 2;
@@ -53,7 +64,6 @@ module insert(type) { //! Draw specified insert
ring2_h = ring1_h + chamfer1;
gap = (length - ring1_h - ring2_h - chamfer2) / 3;
vitamin(str("insert(", type[0], "): Heatfit insert M", insert_screw_diameter(type), " x ", length, "mm"));
$fn = 64;
thread_d = insert_screw_diameter(type);
explode(20, offset = [0, 0, -length]) translate_z(eps) vflip() {
@@ -186,3 +196,54 @@ module insert_lug(insert, wall, counter_bore = 0, extension = 0, corner_r = 0, f
}
}
}
module threaded_insert(type) { //! Draw specified threaded insert, for use in wood
d2 = insert_outer_d(type);
d3 = insert_barrel_d(type);
pitch = threaded_insert_pitch(type);
profile = thread_profile((d2 - d3) /2 , 0, 60);
socket = insert_screw_diameter(type) / cos(30) / 2;
length = insert_length(type);
r=insert_barrel_d(type) / 2;
z=threaded_insert_chamfer(type);
thread_l = insert_length(type) - z; // - insert_ring1_h(type);
vitamin(str("threaded_insert(", type[0], "): Threaded insert M", insert_screw_diameter(type), " x ", length, "mm"));
union() {
color(silver)
difference() {
base_insert(type);
translate_z(-socket/2 + 0.01)
cylinder(r=socket, $fn = 6, h=socket/2);
// chamfer the end
rotate_extrude(convexity = 3)
polygon([
[r - z, -length],
[r + 0.1, - length],
[r + 0.1, - length + z + 0.1]
]);
}
translate_z(-thread_l/2)
thread(insert_barrel_d(type),
pitch,
thread_l,
profile,
center = true,
top = 1,
bot = -1,
starts = 1,
solid = false,
female = false,
colour = silver);
}
}

View File

@@ -39,8 +39,23 @@ CNCKM3 = [ "CNCKM3", 3.0, 4.6, 4.0, 3, 3.65, 0.7, 4.4, 3.9 ];
CNCKM4 = [ "CNCKM4", 4.0, 6.3, 5.6, 4, 5.15, 1.0, 6.0, 5.55];
CNCKM5 = [ "CNCKM5", 5.8, 7.1, 6.4, 5, 6.0, 1.6, 6.8, 6.33];
// Measurements according to DIN 7965
//
// If you want to add an additional length, it should be sufficient copy one with the same
// M size and change the name (2x) and the first number column (l), all others are dependent
// on the M size.
// l, d2, d5, d, d3, h, d3, d3, P1 (h), z
M3x8 = [ "M3x8", 8, 6, 5, 3, 4.5, 0.5, 4.5, 4.5, 2, 0.6];
M4x10 = [ "M4x10", 10, 8, 6.5, 4, 5.5, 0.5, 5.5, 5.5, 2.5, 0.6];
M5x12 = [ "M5x12", 12, 10, 8.5, 5, 7.5, 0.5, 7.5, 7.5, 3.5, 0.8];
M6x15 = [ "M6x15", 15, 12, 10.5, 6, 9.5, 0.5, 9.5, 9.5, 4, 1];
M8x18 = [ "M8x18", 18, 16, 14.5, 8, 12.5, 0.5, 12.5, 12.5, 5, 1];
M10x25 = [ "M10x25", 25, 18.5, 17, 10, 15, 0.5, 15, 15, 5, 1.6];
M12x30 = [ "M12x30", 30, 22, 20, 12, 18, 0.5, 18, 18, 5, 1.6];
M16x30 = [ "M16x30", 30, 25, 22.5, 16, 20.5, 0.5, 20.5, 20.5, 5, 1.6];
inserts = [ F1BM2, F1BM2p5, F1BM3, F1BM4, CNCKM5 ];
short_inserts = [ F1BM2, CNCKM2p5, CNCKM3, CNCKM4, CNCKM5 ];
threaded_inserts = [ M3x8, M4x10, M5x12, M6x15, M8x18, M10x25, M12x30, M16x30 ];
use <insert.scad>

View File

@@ -149,18 +149,8 @@ module jack_4mm_plastic(colour, thickness, display_colour = false) { //! Draw a
}
translate_z(-thickness)
explode(-length)
vflip() {
color(silver)
linear_extrude(nut_t)
difference() {
circle(d = nut_d, $fn = 6);
circle(d = thread_d);
}
if(show_threads)
female_metric_thread(thread_d, thread_p, nut_t, false, colour = silver);
}
vflip()
draw_nut(nut_d, thread_d, nut_t, thread_p, silver, show_threads);
}
function jack_4mm_shielded_hole_radius() = 12 / 2; //! Panel hole radius for 4mm shielded jack
@@ -282,14 +272,7 @@ module post_4mm(colour, thickness, display_colour = false) { //! Draw a 4mm bind
module nut() {
nut_t = 2.3;
color(silver)
linear_extrude(nut_t) difference() {
circle(d = 6.3 / cos(30), $fn = 6);
circle(d = thread_d);
}
if(show_threads)
female_metric_thread(thread_d, thread_p, nut_t, false, colour = silver);
draw_nut(6.3 / cos(30), thread_d, nut_t, thread_p, silver, show_threads);
translate_z(nut_t)
children();
@@ -498,16 +481,6 @@ module power_jack(thickness) { //! Draw a power jack socket with nut positioned
// Nut
translate_z(-thickness)
explode(-length)
vflip() {
color(silver)
linear_extrude(nut_t)
difference() {
circle(d = nut_d, $fn = 6);
circle(d = thread_d);
}
if(show_threads)
female_metric_thread(thread_d, thread_p, nut_t, false, colour = silver);
}
vflip()
draw_nut(nut_d, thread_d, nut_t, thread_p, silver, show_threads);
}

View File

@@ -37,6 +37,7 @@ function nut_thickness(type, nyloc = false) = nyloc ? type[4] : type[3]; //! Thi
function nut_washer(type) = type[5]; //! Corresponding washer
function nut_trap_depth(type) = type[6]; //! Depth of nut trap
function nut_pitch(type) = type[7]; //! Pitch if not standard metric course thread
function nut_dome(type) = type[8]; //! Dome height and max thread depth if a domed acorn nut
function nut_flat_radius(type) = nut_radius(type) * cos(30); //! Radius across the flats
@@ -44,36 +45,84 @@ function nut_square_size(type) = type[1]; //! Diameter of the corresponding
function nut_square_width(type) = type[2]; //! Width of the square nut
function nut_square_thickness(type) = type[3]; //! Thickness of the square nut
module nut(type, nyloc = false, brass = false, nylon = false) { //! Draw specified nut
function nut_dome_height(type) = let(d = nut_dome(type)) d ? d[0] : nut_thickness(type); //! Height of the domed version
function nut_thread_depth(type) = let(d = nut_dome(type)) d ? d[1] : nut_thickness(type); //! Max thread depth in domed version
module draw_nut(od, id, t, pitch, colour, show_thread, thread_h = undef ) {
th = is_undef(thread_h) ? t : thread_h;
color(colour) {
or = od / 2;
fr = or * cos(30);
render_if(manifold) intersection() {
linear_extrude(t, convexity = 5)
difference() {
circle(or, $fn = 6);
if(id)
circle(d = id);
}
if(manifold)
rotate_extrude()
hull() {
h = (or - fr) * tan(30);
translate([0, -eps])
square([fr, t + eps]);
translate([or, h])
square([eps, t - 2 * h]);
}
}
}
if(show_thread && id)
female_metric_thread(id, pitch,
th,
top = th > t ? 0 : manifold ? 1 : -1,
bot = manifold ? 1 : -1,
center = false, colour = colour);
}
module nut(type, nyloc = false, brass = false, nylon = false, dome = false) { //! Draw specified nut
thread_d = nut_size(type);
thread_p = nut_pitch(type) ? nut_pitch(type) : metric_coarse_pitch(thread_d);
hole_rad = thread_d / 2;
outer_rad = nut_radius(type);
thickness = nut_thickness(type);
nyloc_thickness = nut_thickness(type, true);
desc = nyloc ? "nyloc" : brass ? "brass" : nylon ? "nylon" : "";
vitamin(str("nut(", type[0], arg(nyloc, false, "nyloc"), arg(brass, false, "brass"), arg(nylon, false, "nylon"),
desc = nyloc ? "nyloc" : brass ? "brass" : nylon ? "nylon" : dome ? "domed" : "";
vitamin(str("nut(", type[0],
arg(nyloc, false, "nyloc"),
arg(brass, false, "brass"),
arg(nylon, false, "nylon"),
arg(dome, false, "dome"),
"): Nut M", nut_size(type), " x ", thickness, "mm ", desc));
$fs = fs; $fa = fa;
colour = brass ? brass_colour : nylon ? grey(30): grey(70);
explode(nyloc ? 10 : 0) {
draw_nut(outer_rad * 2, thread_d, thickness, thread_p, colour, show_threads, dome ? nut_thread_depth(type) : thickness);
fr = nut_flat_radius(type);
color(colour) {
linear_extrude(thickness)
difference() {
circle(outer_rad, $fn = 6);
circle(hole_rad);
}
if(nyloc)
translate_z(-eps)
rounded_cylinder(r = outer_rad * cos(30) , h = nyloc_thickness, r2 = (nyloc_thickness - thickness) / 2, ir = hole_rad);
}
translate_z(eps)
rounded_cylinder(r = outer_rad * cos(30), h = nyloc_thickness - eps, r2 = (nyloc_thickness - thickness) / 2, ir = hole_rad);
if(show_threads)
female_metric_thread(thread_d, thread_p, thickness, center = false, colour = colour);
if(dome)
translate_z(thickness)
rotate_extrude()
difference() {
h = nut_dome_height(type) - thickness;
r = fr - eps;
rounded_corner(r, h, r);
square([thread_d / 2, nut_thread_depth(type) - thickness]);
}
}
if(nyloc)
translate_z(thickness)

View File

@@ -28,25 +28,25 @@ M5_nut_depth = 4;
M6_nut_depth = 5;
M8_nut_depth = 6.5;
// s d t n w t t
// c i h y a r h
// r a i l s a r
// e m c o h p e
// s d t n w t t d d
// c i h y a r h o o
// r a i l s a r m m
// e m c o h p e e e
// w e k c e d
// t n r d
// e e t e p
// r s h p i
// s k t t
// h c
// h
// t n r d h t
// e e t e p e h
// r s h p i i r
// s k t t g e
// h c h a
// h t d
M2_nut = ["M2_nut", 2, 4.9, 1.6, 2.4, M2_washer, M2_nut_trap_depth, 0];
M2p5_nut = ["M2p5_nut", 2.5, 5.8, 2.2, 3.8, M2p5_washer, M2p5_nut_trap_depth, 0];
M3_nut = ["M3_nut", 3, 6.4, 2.4, 4, M3_washer, M3_nut_trap_depth, 0];
M4_nut = ["M4_nut", 4, 8.1, 3.2, 5, M4_washer, M4_nut_trap_depth, 0];
M5_nut = ["M5_nut", 5, 9.2, 4, 6.25, M5_washer, M5_nut_depth, 0];
M6_nut = ["M6_nut", 6, 11.5, 5, 8, M6_washer, M6_nut_depth, 0];
M3_nut = ["M3_nut", 3, 6.4, 2.4, 4, M3_washer, M3_nut_trap_depth, 0, [6, 5.40]];
M4_nut = ["M4_nut", 4, 8.1, 3.2, 5, M4_washer, M4_nut_trap_depth, 0, [8, 5.74]];
M5_nut = ["M5_nut", 5, 9.2, 4, 6.25, M5_washer, M5_nut_depth, 0, [10, 7.79]];
M6_nut = ["M6_nut", 6, 11.5, 5, 8, M6_washer, M6_nut_depth, 0, [12, 8.29]];
M6_half_nut = ["M6_half_nut", 6, 11.5, 3, 8, M6_washer, 3, 0];
M8_nut = ["M8_nut", 8, 15, 6.5, 8, M8_washer, M8_nut_depth, 0];
M8_nut = ["M8_nut", 8, 15, 6.5, 8, M8_washer, M8_nut_depth, 0, [15, 11.35]];
toggle_nut = ["toggle_nut", 6.1, 9.2, 1.5, 1.5, M6_washer, 1.5, inch(1/40)];
M4_wingnut = ["M4_wingnut", 4, 10, 3.75,8, M4_washer, 0, 22, 10, 6, 3];

View File

@@ -730,7 +730,6 @@ Keyes5p1 = ["Keyes5p1", "Keyes5.1 Arduino Uno expansion board", 68.58, 53.34, 1.
M2p5_pan_screw
];
ExtruderPCB = ["ExtruderPCB", "Extruder connection PCB",
33.02, 24.13, 1.6, 0, 0, 0, "green", true, [],
[[3 * 1.27, 24.13 / 2, 90, "D_plug", DCONN15],
@@ -761,9 +760,36 @@ ZC_A0591 = ["ZC_A0591", "ZC-A0591 ULN2003 driver PCB", 35, 32, 1.6, 0, 2.5, 0, "
], [], [], [], M2p5_pan_screw];
MT3608 = ["MT3608", "MT3608 boost converter module", 37, 17, 1.2, 2, 1.5, [5, 3], "#2140BE", false, [[3.0725, 5.095], [3.0725, -5.095], [-3.0725, 5.095], [-3.0725, -5.095]],
[ [-12.05 , -6.8, 180, "trimpot10"]
]];
MT3608 = ["MT3608", "MT3608 boost converter module", 37, 17, 1.2, 2, 1.5, [5, 3], "#2140BE", false,
[[3.0725, 5.095], [3.0725, -5.095], [-3.0725, 5.095], [-3.0725, -5.095]],
[[-12.05 , -6.8, 180, "trimpot10"],
[-24.05 , 13.8, 90, "smd_soic", SOT23_6, "B628"],
[-12.3, -14.4, 0, "smd_diode",DO214AC, "SS34"],
[-28.5, 13.2, 90,"smd_cap", CAP1206, 0.5],
[-20, 13.2, 90,"smd_cap", CAP1206, 0.5],
[-24.05 , -11.8, 180, "smd_inductor", CDRH104, "220"]]
];
HW803_1WAY_RELAY = [
"HW803_1WAY_RELAY", "HW-803 5V 1 way relay module",
50, 26, 1.6, // size
2, // corner radius
3, // mounting hole diameter
4, // pad around mounting hole
"red", // color
false, // true if parts should be separate BOM items
[ // hole positions
[3, 3], [-3, 3], [3, -3], [-3, -3]
],
[ // components
[ 10.5 + 19/2, 26/2, 0, "block", 19, 15, 15.5, "SkyBlue" ],
[ 50-5, 26/2, 0, "term35", 3],
[ 5, 26/2, 180, "term35", 3],
[ 34, 2, 0, "2p54header", 3, 1 ],
],
[], // accessories
[], // grid
];
TP4056 = ["TP4056", "TP4056 Li-lon Battery charger module", 26.2, 17.5, 1.0, 0, 1.0, [2.4, 2.4], "#2140BE", false,
[[1.67, 1.8], [1.67, -1.8], [-1.67, 1.8], [-1.67, -1.8], [-1.67, -4.98], [-1.67, 4.98]],
@@ -1176,7 +1202,6 @@ ESP_12F = pcb("ESP_12F", "ESP-12F ESP8266 WiFi module", [24, 16, 0.8],
]
);
tiny_buck = pcb("tiny_buck", "Ultra Small 3A buck regulator", [20, 11, 1.6],
hole_d = 1.2,
land_d = [2, 2],
@@ -1197,11 +1222,11 @@ tiny_buck = pcb("tiny_buck", "Ultra Small 3A buck regulator", [20, 11, 1.6],
]
);
tiny_pcbs = [ESP_201, ESP_12F, XIAO, MP1584EN, ESP_01, ESP_01M, tiny_buck, LIPO_fuel_gauge];
tiny_pcbs = [ESP_201, ESP_01M, XIAO, ESP_12F, MP1584EN, ESP_01,tiny_buck, LIPO_fuel_gauge];
big_pcbs = [BTT_RELAY_V1_2, BTT_SKR_MINI_E3_V2_0, BTT_SKR_E3_TURBO, BTT_SKR_V1_4_TURBO, DuetE, Duex5];
pcbs = [KY_040, TP4056, L9110S, ZC_A0591, RAMPSEndstop, MT3608, ArduinoNano, Feather405, RPI_Pico, ESP32_DOIT_V1, RPI0, EnviroPlus, ArduinoUno3, ArduinoLeonardo, WD2002SJ, OPZ2, PanelDue_v3, RPI3A, RPI3, RPI4];
pcbs = [KY_040, TP4056, L9110S, ZC_A0591, MT3608, RAMPSEndstop, ArduinoNano, HW803_1WAY_RELAY, Feather405, RPI_Pico, ESP32_DOIT_V1, RPI0, EnviroPlus, ArduinoUno3, ArduinoLeonardo, WD2002SJ, OPZ2, PanelDue_v3, RPI3A, RPI3, RPI4];
pcbs_not_shown = [Melzi, Duex2, PSU12V1A, Keyes5p1, PI_IO, ExtruderPCB];

View File

@@ -22,6 +22,7 @@
//
include <../utils/core/core.scad>
use <../utils/thread.scad>
use <nut.scad>
function pillar_name(type) = type[1]; //! Name of part
function pillar_thread(type) = type[2]; //! Thread diameter
@@ -34,6 +35,7 @@ function pillar_o_colour(type) = type[8]; //! Colour of the outer part
function pillar_i_colour(type) = type[9]; //! Colour of the inner part
function pillar_top_thread(type) = type[10]; //! Top thread length, + for male, - for female
function pillar_bot_thread(type) = type[11]; //! Bottom thread length, + for male, - for female
function pillar_chamfered(type) = type[12]; //! True if pillar is chamfered
module pillar(type) { //! Draw specified pillar
function sex(thread) = thread > 0 ? "M" : "F";
@@ -67,12 +69,15 @@ module pillar(type) { //! Draw specified pillar
color(thread_colour)
cylinder(h = top_thread_l, d = thread_d);
color(pillar_i_colour(type)) {
linear_extrude(height)
difference() {
circle(d = pillar_id(type), $fn = fn(pillar_ifn(type)));
circle(d = thread_d);
}
color(thread_colour) {
if(pillar_chamfered(type))
draw_nut(pillar_id(type), thread_d, height, 0, thread_colour, false);
else
linear_extrude(height)
difference() {
circle(d = pillar_id(type), $fn = fn(pillar_ifn(type)));
circle(d = thread_d);
}
top = height + min(top_thread_l, 0);
bot = -min(bot_thread_l, 0);
@@ -85,10 +90,10 @@ module pillar(type) { //! Draw specified pillar
if(top_thread_l < 0)
translate_z(height)
vflip()
female_metric_thread(thread_d, pitch, -top_thread_l, false, colour = thread_colour);
female_metric_thread(thread_d, pitch, -top_thread_l, bot = 1, false, colour = thread_colour);
if(bot_thread_l < 0)
female_metric_thread(thread_d, pitch, -bot_thread_l, false, colour = thread_colour);
female_metric_thread(thread_d, pitch, -bot_thread_l, false, bot = 1, colour = thread_colour);
}
if(pillar_od(type) > pillar_id(type))

View File

@@ -20,23 +20,23 @@
//
// Nylon pillars
//
// n t h o i o i o i b t
// a h e d d f f
// m r i n n c c t t
// e e g o o h h
// a h l l r r
// d t o o e e
// u u a a
// d r r d d
//
M2x16_brass_pillar = ["M2x16_brass_pillar", "nurled", 2, 16, 3.17, 3.17, 0, 0, brass, brass, 3,-3];
M3x6_hex_pillar = ["M3x6_hex_pillar", "hex", 3, 6, 5/cos(30), 5/cos(30), 6, 6, brass, brass, -5, 6];
M3x13_hex_pillar = ["M3x13_hex_pillar", "hex", 3, 13, 5/cos(30), 5/cos(30), 6, 6, "silver", silver, -6, 6];
M3x20_hex_pillar = ["M3x20_hex_pillar", "hex", 3, 20, 5/cos(30), 5/cos(30), 6, 6, "silver", silver, -8, 8];
M3x20_nylon_pillar = ["M3x20_nylon_pillar", "nylon", 3, 20, 8, 5/cos(30), 0, 6, "white", brass, -6, 6];
M4x17_nylon_pillar = ["M4x17_nylon_pillar", "nylon", 4, 20, 8, 5/cos(30), 0, 6, "white", brass, -6, 6];
M3x20_nylon_hex_pillar = ["M3x20_nylon_hex_pillar", "hex nylon", 3, 20, 8/cos(30), 8/cos(30), 6, 6, grey(20), grey(20), -6, 6];
M3x10_nylon_hex_pillar = ["M3x10_nylon_hex_pillar", "hex nylon", 3, 10,5.5/cos(30),5.5/cos(30),6, 6, grey(20), grey(20), -6, 6];
// n t h o i o i o i b t c
// a h e d d f f h
// m r i n n c c t t a
// e e g o o h h m
// a h l l r r f
// d t o o e e e
// u u a a r
// d r r d d e
// d
M2x16_brass_pillar = ["M2x16_brass_pillar", "nurled", 2, 16, 3.17, 3.17, 0, 0, brass, brass, 3,-3, false];
M3x6_hex_pillar = ["M3x6_hex_pillar", "hex", 3, 6, 5/cos(30), 5/cos(30), 6, 6, brass, brass, -5, 6, true];
M3x13_hex_pillar = ["M3x13_hex_pillar", "hex", 3, 13, 5/cos(30), 5/cos(30), 6, 6, "silver", silver, -6, 6, true];
M3x20_hex_pillar = ["M3x20_hex_pillar", "hex", 3, 20, 5/cos(30), 5/cos(30), 6, 6, "silver", silver, -8, 8, true];
M3x20_nylon_pillar = ["M3x20_nylon_pillar", "nylon", 3, 20, 8, 5/cos(30), 0, 6, "white", brass, -6, 6, false];
M4x17_nylon_pillar = ["M4x17_nylon_pillar", "nylon", 4, 20, 8, 5/cos(30), 0, 6, "white", brass, -6, 6, false];
M3x20_nylon_hex_pillar = ["M3x20_nylon_hex_pillar", "hex nylon", 3, 20, 8/cos(30), 8/cos(30), 6, 6, grey(20), grey(20), -6, 6, false];
M3x10_nylon_hex_pillar = ["M3x10_nylon_hex_pillar", "hex nylon", 3, 10,5.5/cos(30),5.5/cos(30),6, 6, grey(20), grey(20), -6, 6, false];
pillars = [M2x16_brass_pillar, M3x6_hex_pillar, M3x13_hex_pillar, M3x20_hex_pillar, M3x20_nylon_pillar, M4x17_nylon_pillar, M3x10_nylon_hex_pillar, M3x20_nylon_hex_pillar];

View File

@@ -17,7 +17,7 @@
// If not, see <https://www.gnu.org/licenses/>.
//
//! Potentiometers and rotary encoders
include <../utils/core/core.scad>
include <../core.scad>
use <../utils/rounded_cylinder.scad>
use <../utils/round.scad>
use <../utils/thread.scad>
@@ -71,18 +71,8 @@ module pot_nut(type, washer = true) { //! Draw the nut for a potentiometer and p
}
if(nut)
color(nut[2])
translate_z(nut_z + exploded() * 10) {
linear_extrude(nut[1])
difference() {
circle(d = nut.x / cos(30), $fn = 6);
circle(d = thread_d);
}
if(show_threads && exploded())
female_metric_thread(thread_d, pot_thread_p(type), nut[1], center = false, colour = nut[2]);
}
translate_z(nut_z + exploded() * 10)
draw_nut(nut.x / cos(30), thread_d, nut[1], pot_thread_p(type), nut[2], show_threads && exploded());
}
}

View File

@@ -161,7 +161,7 @@ module psu(type) { //! Draw a power supply
fan_holes(fan.z, h = 0);
difference() {
square(inf, true);
square(big, true);
fan_guard(fan.z, thickness = 0, grill = true);
}

View File

@@ -50,7 +50,7 @@ function screw_head_depth(type, d = 0) = //! How far a counter sink
: let(r = screw_radius(type)) screw_head_radius(type) - max(r, d / 2) + r / 5;
function screw_thread_radius(type) = //! Thread radius
let(d = echoit(screw_thread_diameter(type))) is_undef(d) ? screw_radius(type) : d / 2;
let(d = screw_thread_diameter(type)) is_undef(d) ? screw_radius(type) : d / 2;
function screw_angle(type, length, nut_distance) = //! How much to rotate the screw to align it with a nut at the specified `distance` from the head
-360 * (length - nut_distance) / metric_coarse_pitch(screw_thread_radius(type) * 2);
@@ -205,8 +205,7 @@ module screw(type, length, hob_point = 0, nylon = false) { //! Draw specified sc
cylinder(h=2 * eps, r=socket_rad, $fn = 6);
}
if(head_type == hs_hex) {
color(colour)
cylinder(r = head_rad, h = head_height, $fn = 6);
draw_nut(head_rad * 2, 0, head_height, 0, colour, false);
shaft();
}

View File

@@ -26,11 +26,13 @@
//
mdf_colour = "#BEA587"; // sampled from a photo
MDF3 = [ "MDF3", "Sheet MDF", 3, mdf_colour, true];
MDF6 = [ "MDF6", "Sheet MDF", 6, mdf_colour, true]; // ~1/4"
MDF10 = [ "MDF10", "Sheet MDF", 10, mdf_colour, true]; // ~3/8"
MDF12 = [ "MDF12", "Sheet MDF", 12, mdf_colour, true]; // ~1/2"
MDF18 = [ "MDF18", "Sheet MDF", 18, mdf_colour, true];
MDF19 = [ "MDF19", "Sheet MDF", 19, mdf_colour, true]; // ~3/4"
MDF22 = [ "MDF22", "Sheet MDF", 22, mdf_colour, true];
PMMA1p25 = [ "PMMA1p25", "Sheet acrylic", 1.25,[1, 1, 1, 0.5 ], false];
PMMA2 = [ "PMMA2", "Sheet acrylic", 2, [1, 1, 1, 0.5 ], false];
PMMA3 = [ "PMMA3", "Sheet acrylic", 3, [1, 1, 1, 0.5 ], false]; // ~1/8"
@@ -42,6 +44,7 @@ DiBond = [ "DiBond", "Sheet DiBond", 3, [0.2, 0.2, 0.2, 1 ],
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];
Sellotape = [ "Sellotape", "Sellotape tape", 0.05,[1, 1, 0.9, 0.5 ], false];
Foam20 = [ "Foam20", "Foam sponge", 20,[0.3, 0.3, 0.3, 1 ], true];
AL1_6 = [ "AL1_6", "Aluminium tooling plate", 1.6, [0.5, 0.5, 0.5, 0.5], false];
AL2 = [ "AL2", "Aluminium tooling plate", 2, [0.9, 0.9, 0.9, 1 ], false];
@@ -56,7 +59,7 @@ CF2 = [ "CF2", "Sheet carbon fiber", 2, grey(35),
CF3 = [ "CF3", "Sheet carbon fiber", 3, grey(35), false, 2, 2, grey(20)];
sheets = [CF1, CF2, CF3, MDF6, MDF10, MDF12, MDF19, PMMA1p25, PMMA2, PMMA3, PMMA6, PMMA8, PMMA10,
glass2, DiBond, DiBond6, Cardboard, FoilTape, AL1_6, AL2, AL3, AL6, AL8, Steel06, Spring08, Silicone3, Foam20];
sheets = [CF1, CF2, CF3, MDF3, MDF6, MDF10, MDF12, MDF19, MDF22, PMMA1p25, PMMA2, PMMA3, PMMA6, PMMA8, PMMA10,
glass2, DiBond, DiBond6, Cardboard, FoilTape, Sellotape, AL1_6, AL2, AL3, AL6, AL8, Steel06, Spring08, Silicone3, Foam20];
use <sheet.scad>

View File

@@ -70,8 +70,9 @@ TANT_C = ["TANT_C", [5.8, 3.2, 2.6], 0.1, 1.3, [6.0, 2.2, 0.08, 2.9], ["#E9D769
smd_tants = [TANT_A, TANT_B, TANT_C];
IND2525 = ["IND2525", [6.75, 6.75, 2], 0.1, 1.75, [7.24, 3.2, 0.15, 4.4], grey(50)];
CDRH104 = ["CDRH104", [10.3, 10.3, 4.0], 0.1, 3.85, [10.5, 3.2, 0.15, 4.4], grey(50)];
smd_inductors = [IND2525];
smd_inductors = [IND2525, CDRH104];
TC33X1 = ["TC33X1", [3.0, 3.8, 0.5], [0.95, 0.9, 0.88, 1.5, 0.2, 0.75],[3.0, 0.1, 0.2, 1.2, 1.7, 1.2, 1, 0.5], [2.1, 0.5], 1.5];

209
vitamins/ttrack.scad Normal file
View File

@@ -0,0 +1,209 @@
//
// NopSCADlib Copyright Chris Palmer 2024
// 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/>.
//
//! T-Tracks used in woodworking jigs
//
include <../utils/core/core.scad>
use <../utils/thread.scad>
use <screw.scad>
function ttrack_width(type) = type[1]; //! Width of track section
function ttrack_height(type) = type[2]; //! Height of track section
function ttrack_opening(type) = type[3]; //! Width of the opening
function ttrack_slot_width(type) = type[4]; //! Width of the slot
function ttrack_slot_height(type) = type[5]; //! Height of the slot
function ttrack_top_thickness(type) = type[6]; //! Thickness of the top layer
function ttrack_screw_pitch(type) = type[7]; //! Distance between screws
function ttrack_screw(type) = type[8]; //! Screw used to fasten track
function ttrack_fixture(type) = type[9]; //! Fixture, such as T-bolt or Miter insert used with this track
function tbolt_description(type) = type[1]; //! Description of this t-track bolt
function tbolt_head_length(type) = type[2]; //! Head length for t-track bolt
function tbolt_head_width(type) = type[3]; //! Head width for t-track bolt
function tbolt_head_thickness(type) = type[4]; //! Head thickness for t-track bolt
function tbolt_thread(type) = type[5]; //! M thread for this bolt
function t_insert_description(type) = type[1]; //! Description of this t-track insert
function t_insert_top_width(type) = type[2]; //! Top Width of t-track insert
function t_insert_width(type) = type[3]; //! Width of t-track insert
function t_insert_height(type) = type[4]; //! Height of t-track insert
function t_insert_top_thickness(type) = type[5]; //! Top thickness for t-track insert
function t_insert_thread(type) = type[6]; //! M thread for this the screw hole in this insert
function ttrack_holes(type, length) = //! Number of holes in a rail given its `length`
floor((length - 2 * ttrack_screw_end(type)) / ttrack_screw_pitch(type)) + 1;
module ttrack(type, length, colour = "LightSlateGray") { //! Draw the specified rail
W = ttrack_width(type);
H = ttrack_height(type);
SW = ttrack_slot_width(type);
SH = ttrack_slot_height(type);
T = ttrack_top_thickness(type);
O = ttrack_opening(type);
screw=ttrack_screw(type);
vit_colour = (colour == "LightSlateGray" ? "" : str(", colour=\"", colour, "\""));
vitamin(str("ttrack(", type[0], ", ", length, vit_colour, "): T-Track ", type[0], " x ", length, "mm"));
color(colour) {
difference() {
rotate([90,0,0])
linear_extrude(length, center=true, convexity = 3)
polygon([
[ -O/2, 0 ], // left side of the opening
[ -W/2, 0 ], // left top
[ -W/2, -H ], // left bottom
[ W/2, -H ], // right bottom
[ W/2, 0 ], // right top
[ O/2, 0 ], // right side of the opening
[ O/2, -T ], // right bottom side of the opening
[ SW/2, -T ], // right top of the slot
[ SW/2, -T - SH ], // right bottom of the slot
[ -SW/2,-T - SH ], // left bottom of the slot
[ -SW/2, -T ], // left top of the slot
[ -O/2, -T ] // left bottom side of the opening
]);
ttrack_hole_positions(type, length) {
B = H - (SH + T);
screw_countersink(screw, true);
translate_z(-B/2)
cylinder(r=screw_clearance_radius(screw), h=(H-(SH+T) + 0.2), center=true);
}
}
}
}
module ttrack_assembly(type, length, colour = "LightSlateGray") {
ttrack(type, length, colour);
ttrack_hole_positions(type, length)
explode(20)
screw(ttrack_screw(type), 15);
}
module ttrack_hole_positions(type, length) { //! Position children over screw holes
P = ttrack_screw_pitch(type);
H = ttrack_height(type);
B = H - (ttrack_slot_height(type) + ttrack_top_thickness(type));
count = floor(length / P);
first = (length - count * P)/2;
c = first < P/3 ? count - 1 : count; // we don't want screws right on the edge
N = (length - c * P)/2;
for (y = [N:P:length-N])
translate([0,length/2 - y, -H + B])
children();
}
module ttrack_place_bolt(type, pos, bolt = undef) { //! Place a T-Bolt relative to the centre of the track
bolt = is_undef(bolt) ? ttrack_fixture(type) : bolt;
T = tbolt_head_thickness(bolt);
translate([0,pos,-(ttrack_top_thickness(type)/2) - T])
rotate([0,0,90])
children();
}
module ttrack_place_insert(type, pos, insert = undef) { //! Place a T-Insert relative to the centre of the track
insert = is_undef(insert) ? ttrack_fixture(type) : insert;
TT = t_insert_top_thickness(insert);
T = ttrack_top_thickness(type);
translate([0,pos,-T+TT])
rotate([0,0,90])
children();
}
module ttrack_bolt(type, length) {
L = tbolt_head_length(type);
W = tbolt_head_width(type);
T = tbolt_head_thickness(type);
distance = L - W;
D = tbolt_thread(type);
pitch = metric_coarse_pitch(D);
vitamin(str(tbolt_description(type), ":", "M", D, " x ", length, "mm"));
color(silver) {
hull()
for (x = [-1, 1])
translate([x * distance/2, 0, 0])
cylinder(d=W, h=T, center=true);
translate_z((length/2))
male_metric_thread(D, pitch, length - T, center = true, top = -1, bot = 0, solid = true, colour = undef);
}
}
module ttrack_insert(type, length, num_holes = 1, colour="LightSlateGray") {
TW = t_insert_top_width(type);
W = t_insert_width(type);
H = t_insert_height(type);
T = t_insert_top_thickness(type);
//distance = L - W;
D = t_insert_thread(type);
pitch = metric_coarse_pitch(D);
vit_colour = (colour == "LightSlateGray" ? "" : str(", colour=\"", colour, "\""));
vitamin(str("ttrack_insert(", type[0], ", ", length, ", ", num_holes, vit_colour, "):", t_insert_description(type), ", M", length, "mm, with ", num_holes, " M", D));
color(colour) {
union() {
difference() {
rotate([90,0,90]) {
linear_extrude(length, center=true, convexity=2)
polygon([
[ -TW/2, 0 ], // left top
[ -TW/2, -T ], // left centre, bottom of top
[ -W/2, -T ], // left centre
[ -W/2, -H ], // left bottom
[ W/2, -H ], // right bottom
[ W/2, -T ], // right centre
[ TW/2, -T ], // right centre, bottom of top
[ TW/2, 0 ] // right top
]);
}
ttrack_insert_hole_positions(type, length, num_holes)
translate_z(-H/2)
cylinder(h=H+1, d=t_insert_thread(type), center=true);
}
ttrack_insert_hole_positions(type, length, num_holes)
translate_z(-H/2)
female_metric_thread(D, pitch, H, center = true);
}
}
}
module ttrack_insert_hole_positions(type, length, num_holes) {
P = length / (num_holes + 1);
for (x = [P:P:length-P])
translate([length/2 - x,0,0])
children();
}

52
vitamins/ttracks.scad Normal file
View File

@@ -0,0 +1,52 @@
//
// NopSCADlib Copyright Chris Palmer 2024
// 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 <../core.scad>
use <screw.scad>
// Bolts HL, HW, HT, Thread M
ttrack_bolt_M6 = [ "ttrack_bolt_M6", "T-Track Bolt M6", 18, 12, 2.5, 6 ];
ttrack_bolt_M6_small = [ "ttrack_bolt_M6_small", "T-Track Bolt M6 with small head", 18, 11, 2.5, 6 ];
ttrack_bolt_M8 = [ "ttrack_bolt_M8", "T-Track Bolt M8", 22.5, 12.6, 3, 8 ];
// Inserts
// TW, W, H, SH, Thread M
ttrack_insert_mitre_30_M6 = [ "TTrack_insert_Miter30_M6", "T-Track insert, Miter track 30mm, M6 thread", 19, 23, 7.8, 4.8, 6 ];
ttrack_insert_mitre_30_M8 = [ "TTrack_insert_Miter30_M8", "T-Track insert, Miter track 30mm, M8 thread", 19, 23, 7.8, 4.8, 8 ];
//
// Tracks
// Width, Depth, Opening, Slot width, slot height, Top thickness, Screw pitch
// W D O SW SH TT Sp
ttrack_universal_19mm = [ "ttrack_universal_19mm", 19, 9.5, 9.5, 14.2, 3.3, 2.4, 75, M3_cs_cap_screw, ttrack_bolt_M8 ];
ttrack_universal_19mm_A = [ "ttrack_universal_19mm_A", 18.7, 12.5, 8.3, 12, 7.3, 3.5, 75, M3_cs_cap_screw, ttrack_bolt_M6 ];
ttrack_universal_19mm_B = [ "ttrack_universal_19mm_B", 19, 9.5, 6.6, 11.3, 4, 2.5, 75, M3_cs_cap_screw, ttrack_bolt_M6_small ];
ttrack_mitre_30mm = [ "ttrack_mitre_30mm", 30, 12.8, 19.3, 23.6, 3.1, 5.4, 75, M4_cs_cap_screw, ttrack_insert_mitre_30_M6 ];
ttrack_mitre_36mm = [ "ttrack_mitre_36mm", 36, 13.5, 19, 23.5, 3.6, 3.6, 75, M4_cs_cap_screw ];
ttracks = [ ttrack_universal_19mm, ttrack_universal_19mm_A, ttrack_universal_19mm_B, ttrack_mitre_30mm, ttrack_mitre_36mm];
ttrack_bolts = [ ttrack_bolt_M6, ttrack_bolt_M6_small, ttrack_bolt_M8 ];
ttrack_inserts = [ ttrack_insert_mitre_30_M6, ttrack_insert_mitre_30_M8 ];
use <ttrack.scad>

View File

@@ -44,23 +44,62 @@ function cable_is_ribbon(cable) = len(cable) > 2 && cable[2]; //! Is a ribbon ca
function cable_wire_colours(cable) = assert(len(cable[3]) >= cable_wires(cable)) cable[3]; //! Individual wire colours
function cable_tlen(cable) = cable[4]; //! Twisted cable twist length
function cable(wires, size, colours, ribbon = false, tlen = 25) = [wires, size, ribbon, colours, tlen]; //! Cable constructor
function cable_merge(cable1, cable2) = //! Combine the wires of two cables
assert(cable_wire_size(cable1) == cable_wire_size(cable2))
assert(cable_is_ribbon(cable1) == cable_is_ribbon(cable2))
cable(cable_wires(cable1) + cable_wires(cable2),
cable_wire_size(cable1),
concat(cable_wire_colours(cable1), cable_wire_colours(cable1)),
cable_is_ribbon(cable1));
// numbers from http://mathworld.wolfram.com/CirclePacking.html
function cable_radius(cable) = [0, 1, 2, 2.15, 2.41, 2.7, 3, 3, 3.3][cable_wires(cable)] * cable_wire_size(cable) / 2; //! Radius of a bundle of wires, see <http://mathworld.wolfram.com/CirclePacking.html>.
// numbers from https://en.wikipedia.org/wiki/Circle_packing_in_a_circle
function cable_radius(cable) = [ //! Radius of a bundle of wires, see <http://mathworld.wolfram.com/CirclePacking.html>.
0, 1, 2,
2.154, // 3
2.414, // 4
2.701, // 5
3, // 6
3, // 7
3.304, // 8
3.613, // 9
3.813, // 10
3.923, // 11
4.029, // 12
4.236, // 13
4.328, // 14
4.521, // 15
4.615, // 16
4.792, // 17
4.863, // 18
4.863, // 19
5.122, // 20
][cable_wires(cable)] * cable_wire_size(cable) / 2;
function wire_hole_radius(cable) = ceil(4 * cable_radius(cable) + 1) / 4; //! Radius of a hole to accept a bundle of wires, rounded up to standard metric drill size
function cable_bundle(cable) = //! Dimensions of the bounding rectangle of a bundle of wires in a flat cable clip
(cable_is_ribbon(cable) ? [cable_wires(cable), 1] :
[[0,0], [1,1], [2,1], [2, 1 + sin(60)], [2,2], [3, 1 + sin(60)], [3,2]][cable_wires(cable)]) * cable_wire_size(cable);
[[0, 0], // 0
[1, 1], // 1
[2, 1], // 2
[2, 1 + sin(60)], // 3
[2, 2], // 4
[3, 1 + sin(60)], // 5
[3, 2], // 6
[4, 1 + sin(60)], // 7
[3, 2 + sin(60)], // 8
[3, 3]
][cable_wires(cable)]) * cable_wire_size(cable);
function cable_bundle_positions(cable) = let( //! Positions of wires in a bundle to go through a cable strip
wires = cable_wires(cable),
bottom = cable_is_ribbon(cable) ? wires : wires < 3 ? wires : ceil(wires / 2),
top = wires - bottom
bottom = cable_is_ribbon(cable) ? wires : wires < 3 ? wires : wires <= 7 ? ceil(wires / 2) : min(wires, 3),
middle = min(wires - bottom, 3),
top = wires - bottom - middle
)
[for(i = [0 : 1 : bottom - 1]) [i - (bottom - 1) / 2, 0.5],
for(i = [top - 1 : -1 : 0]) [i - (top - 1) / 2, top == bottom ? 1.5 : 0.5 + sin(60)]
[for(i = [0 : 1 : bottom - 1]) [i - (bottom - 1) / 2, 0.5],
for(i = [middle - 1 : -1 : 0]) [i - (middle - 1) / 2, middle == bottom ? 1.5 : 0.5 + sin(60)],
for(i = [0 : 1 : top - 1]) [i - [0.5, 0.5, 1][top - 1], top == middle ? 2.5 : 1.5 + sin(60)]
] * cable_wire_size(cable);
function cable_width(cable) = cable_bundle(cable).x; //! Width in flat clip