Compare commits
219 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
f0c25d37b0 | ||
|
588a1edf62 | ||
|
3299aad5c8 | ||
|
74c52aac04 | ||
|
726d9ed2dc | ||
|
8a838dd1ce | ||
|
181c6ac624 | ||
|
e952aa7840 | ||
|
466ee31e10 | ||
|
4c926c529b | ||
|
edb1eccbf1 | ||
|
061812cc8b | ||
|
ce0c97b45e | ||
|
696b14699c | ||
|
2166a9be6a | ||
|
511729008d | ||
|
5111ec04bc | ||
|
cef3a620a6 | ||
|
da5191e52c | ||
|
d9af5b7f70 | ||
|
c30d7f1ad9 | ||
|
a5382cbe04 | ||
|
00c5c90a5e | ||
|
01c26d8a34 | ||
|
ef2102420b | ||
|
540f841163 | ||
|
1045502efb | ||
|
485184f092 | ||
|
b893c9069a | ||
|
69f4ced29d | ||
|
5c1aa849fe | ||
|
9d65f69bf3 | ||
|
515b99fdc0 | ||
|
631d052c68 | ||
|
1247303cb9 | ||
|
290be4beb6 | ||
|
24e941799d | ||
|
6a556c5879 | ||
|
14ab1bb8b6 | ||
|
be53547728 | ||
|
ba7d7d32ad | ||
|
d3049bc81b | ||
|
df35e14fc7 | ||
|
21c2aa5d62 | ||
|
c982876ebc | ||
|
5ccda42e5b | ||
|
92d0444e5f | ||
|
b239c1462e | ||
|
6413b7b2a0 | ||
|
0b0ce66c85 | ||
|
d38055c15c | ||
|
cf99418a19 | ||
|
0cd0e72d92 | ||
|
2c4a498a7a | ||
|
451101fcd6 | ||
|
c7a6d8164f | ||
|
8d7c44b80d | ||
|
dcfe4262c5 | ||
|
fe3b84f672 | ||
|
d1a17bd4ac | ||
|
b8efa11fd9 | ||
|
3bc8f35e37 | ||
|
39c11ef3b2 | ||
|
5a8a1da880 | ||
|
3147862212 | ||
|
4fc8a7f47d | ||
|
a9ed9944c3 | ||
|
9cd2dbc316 | ||
|
f3bfbbfcf2 | ||
|
baaa85ffed | ||
|
f1a49d4e28 | ||
|
0eed0673b0 | ||
|
9a4cc7ec42 | ||
|
2fb1185edf | ||
|
a782d43e67 | ||
|
ae934d47c7 | ||
|
823f3b936e | ||
|
3027b942a6 | ||
|
749a1f0648 | ||
|
5c898df217 | ||
|
7a566cc856 | ||
|
20d799a3c1 | ||
|
2ee95bba65 | ||
|
f49bb63266 | ||
|
258109811b | ||
|
b39fd536c2 | ||
|
a5a87d260d | ||
|
b09efb10e0 | ||
|
53acaac379 | ||
|
9b40e0dcef | ||
|
00ca412441 | ||
|
1e6d7f5dd6 | ||
|
ec07d95657 | ||
|
0dab0dca08 | ||
|
6e6cd45295 | ||
|
3a7fde6c56 | ||
|
c5bb898856 | ||
|
11ebe2225d | ||
|
a1e25bb878 | ||
|
9689683b7e | ||
|
08946e3d70 | ||
|
15c2946e91 | ||
|
34019196cd | ||
|
436fc71cf3 | ||
|
fd67c166f7 | ||
|
634deab911 | ||
|
e2feceb608 | ||
|
d1258e0b0c | ||
|
bd61a1dc55 | ||
|
055e83902f | ||
|
feec1e7ae5 | ||
|
be76af2fc4 | ||
|
9c1a9bf357 | ||
|
9647fb474b | ||
|
49fdfea792 | ||
|
ac0bacfeda | ||
|
6288059d99 | ||
|
0f1dff230a | ||
|
e379fa8ada | ||
|
313d7508df | ||
|
083caca4e8 | ||
|
49329df00c | ||
|
edc0b86bb1 | ||
|
5fbff060b0 | ||
|
b94ca4ad3a | ||
|
bc5515d35e | ||
|
44d213deaa | ||
|
145c5d9b1a | ||
|
7abbbd9b96 | ||
|
5b160cee88 | ||
|
3f31607840 | ||
|
1efed649cf | ||
|
b70c2f993c | ||
|
56e252f3dc | ||
|
f12b36ea04 | ||
|
bd5811e69b | ||
|
ede4da6f1d | ||
|
51cc2fd679 | ||
|
4ce2f53e20 | ||
|
e338c47e73 | ||
|
8328a70f42 | ||
|
cc794cd7c3 | ||
|
df28bd5116 | ||
|
61de6041d8 | ||
|
b2d712bca9 | ||
|
f3376edaf1 | ||
|
c073419c0b | ||
|
608168de8e | ||
|
fc45a40bd3 | ||
|
52e9c1d7fd | ||
|
ca1b34e9ca | ||
|
cbab9cea02 | ||
|
69cf998862 | ||
|
08bce9ec03 | ||
|
4aa7dbb416 | ||
|
7c7c2e5d3f | ||
|
f6f6664c0d | ||
|
2fd2e118a0 | ||
|
22c6fef113 | ||
|
dcf0c949b9 | ||
|
9ded315801 | ||
|
42e03679b4 | ||
|
d2c795f5f5 | ||
|
83b4ab2374 | ||
|
573c50774b | ||
|
4b93623492 | ||
|
d496898c80 | ||
|
544e69c71b | ||
|
240334784d | ||
|
516b225275 | ||
|
e46e6b6e5b | ||
|
4925979519 | ||
|
298d1f9284 | ||
|
fcf2f5f7f0 | ||
|
491c3b4ea8 | ||
|
94cb50f725 | ||
|
1d8275c061 | ||
|
3c605d608b | ||
|
9ba48c7e1a | ||
|
a6ebc5267b | ||
|
e9554ccffe | ||
|
0d179f3728 | ||
|
a94e462f34 | ||
|
7ce991e625 | ||
|
3e15be852f | ||
|
7c1c8e92f2 | ||
|
54c3b4f600 | ||
|
d80fc5709e | ||
|
30236046a8 | ||
|
93aeb4cf2c | ||
|
f62ca35c86 | ||
|
2320cbdbb8 | ||
|
769cb44207 | ||
|
f327df95a3 | ||
|
09956b6219 | ||
|
f8c9adca5a | ||
|
b83e56713f | ||
|
4c12d5fca4 | ||
|
da4f9fbdc3 | ||
|
614e5f3a72 | ||
|
a7eae4f549 | ||
|
3cd5769708 | ||
|
7b770abe12 | ||
|
31ab8562a7 | ||
|
db703379a3 | ||
|
cd925bc049 | ||
|
4a2951e22f | ||
|
a93a8f99fb | ||
|
73c436ee15 | ||
|
c69100bd71 | ||
|
e0b89359aa | ||
|
041d720c39 | ||
|
03a0c2fe98 | ||
|
7c2df8d36d | ||
|
8474718884 | ||
|
fe0f32ddc5 | ||
|
f191b9b0f4 | ||
|
2b3908b6fd | ||
|
0199587907 |
2017
CHANGELOG.md
Normal file
@@ -1,7 +1,7 @@
|
|||||||
# NopSCADlib usage
|
# NopSCADlib usage
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
1. OpenSCAD 2019.05 or later, download it from here: https://www.openscad.org/downloads.html
|
1. OpenSCAD 2021.01 or later, download it from here: https://www.openscad.org/downloads.html
|
||||||
1. Python 2.7+ or 3.6+ from https://www.python.org/downloads/
|
1. Python 2.7+ or 3.6+ from https://www.python.org/downloads/
|
||||||
1. ImageMagick 7 www.imagemagick.org
|
1. ImageMagick 7 www.imagemagick.org
|
||||||
|
|
||||||
@@ -270,6 +270,22 @@ The target config file is selected by generating `target.scad` that includes `co
|
|||||||
The rest of the project includes `target.scad` to use the configuration.
|
The rest of the project includes `target.scad` to use the configuration.
|
||||||
Additionally all the generated file directories (assemblies, bom, stls, dxfs, etc.) are placed in a sub-directory called `<target_name>`.
|
Additionally all the generated file directories (assemblies, bom, stls, dxfs, etc.) are placed in a sub-directory called `<target_name>`.
|
||||||
|
|
||||||
|
The build system will look for a `<target_name>_assembly` module and use it as the top level module instead of `main_assembly` if it it exists.
|
||||||
|
That allows the project description to be target specific if the top level modules are in different scad files.
|
||||||
|
The top level assembly instructions and assembly contents could also be different if appropriate.
|
||||||
|
|
||||||
|
If the top level module is just a shell wrapper that simply includes one other assembly, with no additional parts, then it is removed from the build instructions and
|
||||||
|
the assembly it calls becomes the top level. This allows a different project description for each target but only one set of top level instructions without repeating them.
|
||||||
|
|
||||||
|
### Costed BOMs
|
||||||
|
|
||||||
|
A costed bill of materials can be made by opening the generated file `bom/bom.csv` in a spreadsheet program using a single quote as the string delimiter and comma as the field separator.
|
||||||
|
That gets a list of part descriptions and quantities to which prices can be added to get the total cost and perhaps a URL of where to buy each part.
|
||||||
|
|
||||||
|
If a Python file called `parts.py` is found then `bom.py` will attempt to call functions for each part to get a price and URL.
|
||||||
|
Any functions not found are printed, so you can see the format expected.
|
||||||
|
The function are passed the quantity to allow them to calculate volume discounts, etc.
|
||||||
|
|
||||||
### Other libraries
|
### Other libraries
|
||||||
|
|
||||||
The build scripts need to be able to locate the source files where the modules to generate the STL files and assemblies reside. They will search all the scad files
|
The build scripts need to be able to locate the source files where the modules to generate the STL files and assemblies reside. They will search all the scad files
|
||||||
|
Before Width: | Height: | Size: 138 KiB After Width: | Height: | Size: 137 KiB |
16
examples/MainsBreakOutBox/bom/bom.csv
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
'Ferrule for 1.5mm^2 wire - not shown', 3
|
||||||
|
'Wire blue 30/0.25mm strands, length 150mm - not shown', 2
|
||||||
|
'Wire brown 30/0.25mm strands, length 150mm - not shown', 2
|
||||||
|
'Wire green & yellow 30/0.25mm strands, length 150mm - not shown', 2
|
||||||
|
'IEC inlet for ATX', 1
|
||||||
|
'Heatfit insert M3', 2
|
||||||
|
'4mm shielded jack socket blue', 2
|
||||||
|
'4mm shielded jack socket brown', 1
|
||||||
|
'4mm shielded jack socket green', 2
|
||||||
|
'Mains socket 13A', 1
|
||||||
|
'Nut M3 x 2.4mm nyloc', 6
|
||||||
|
'Screw M3 cs cap x 12mm', 2
|
||||||
|
'Screw M3 cs cap x 20mm', 2
|
||||||
|
'Screw M3 dome x 10mm', 4
|
||||||
|
'Heatshrink sleeving ID 3.2mm x 15mm - not shown', 8
|
||||||
|
'Washer M3 x 7mm x 0.5mm', 10
|
|
@@ -3,6 +3,7 @@
|
|||||||
"name": "base_assembly",
|
"name": "base_assembly",
|
||||||
"big": null,
|
"big": null,
|
||||||
"ngb": false,
|
"ngb": false,
|
||||||
|
"zoomed": 0,
|
||||||
"count": 1,
|
"count": 1,
|
||||||
"assemblies": {},
|
"assemblies": {},
|
||||||
"vitamins": {
|
"vitamins": {
|
||||||
@@ -22,6 +23,7 @@
|
|||||||
"name": "feet_assembly",
|
"name": "feet_assembly",
|
||||||
"big": null,
|
"big": null,
|
||||||
"ngb": false,
|
"ngb": false,
|
||||||
|
"zoomed": 0,
|
||||||
"count": 1,
|
"count": 1,
|
||||||
"assemblies": {
|
"assemblies": {
|
||||||
"base_assembly": 1
|
"base_assembly": 1
|
||||||
@@ -49,6 +51,7 @@
|
|||||||
"name": "mains_in_assembly",
|
"name": "mains_in_assembly",
|
||||||
"big": null,
|
"big": null,
|
||||||
"ngb": false,
|
"ngb": false,
|
||||||
|
"zoomed": 0,
|
||||||
"count": 1,
|
"count": 1,
|
||||||
"assemblies": {
|
"assemblies": {
|
||||||
"feet_assembly": 1
|
"feet_assembly": 1
|
||||||
@@ -86,6 +89,7 @@
|
|||||||
"name": "main_assembly",
|
"name": "main_assembly",
|
||||||
"big": null,
|
"big": null,
|
||||||
"ngb": false,
|
"ngb": false,
|
||||||
|
"zoomed": 0,
|
||||||
"count": 1,
|
"count": 1,
|
||||||
"assemblies": {
|
"assemblies": {
|
||||||
"mains_in_assembly": 1
|
"mains_in_assembly": 1
|
||||||
|
@@ -24,18 +24,16 @@
|
|||||||
// bom defaults to 0
|
// bom defaults to 0
|
||||||
// Setting $bom on the command line or in the main file before including lib.scad overrides it everywhere.
|
// Setting $bom on the command line or in the main file before including lib.scad overrides it everywhere.
|
||||||
// Setting $bom after including lib overrides bom in the libs but not in the local file.
|
// Setting $bom after including lib overrides bom in the libs but not in the local file.
|
||||||
// Setting $_bom in the local file overrides it in the local file but not in the libs.
|
|
||||||
//
|
//
|
||||||
rr_green = [0, 146/255, 0]; // RepRap logo colour
|
rr_green = [0, 146/255, 0]; // RepRap logo colour
|
||||||
|
crimson = [220/255, 20/255, 60/255];
|
||||||
|
|
||||||
$_bom = is_undef($bom) ? 0 : $bom; // 0 no bom, 1 assemblies and stls, 2 vitamins as well
|
layer_height = is_undef($layer_height) ? 0.25 : $layer_height; // layer height when printing
|
||||||
$exploded = is_undef($explode) ? 0 : $explode; // 1 for exploded view
|
|
||||||
layer_height = is_undef($layer_height) ? 0.25 : $layer_height; // layer heigth when printing
|
|
||||||
extrusion_width = is_undef($extrusion_width) ? 0.5 : $extrusion_width; // filament width when printing
|
extrusion_width = is_undef($extrusion_width) ? 0.5 : $extrusion_width; // filament width when printing
|
||||||
nozzle = is_undef($nozzle) ? 0.45 : $nozzle; // 3D printer nozzle
|
nozzle = is_undef($nozzle) ? 0.45 : $nozzle; // 3D printer nozzle
|
||||||
cnc_bit_r = is_undef($cnc_bit_r) ? 1.2 : $cnc_bit_r; // minimum tool radius when milling 2D objects
|
cnc_bit_r = is_undef($cnc_bit_r) ? 1.2 : $cnc_bit_r; // minimum tool radius when milling 2D objects
|
||||||
pp1_colour = is_undef($pp1_colour) ? rr_green : $pp1_colour; // printed part colour 1, RepRap logo colour
|
pp1_colour = is_undef($pp1_colour) ? rr_green : $pp1_colour; // printed part colour 1, RepRap logo colour
|
||||||
pp2_colour = is_undef($pp2_colour) ? "Crimson" : $pp2_colour; // printed part colour 2
|
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
|
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
|
pp4_colour = is_undef($pp4_colour) ? "darkorange" : $pp4_colour;// printed part colour 4
|
||||||
show_rays = is_undef($show_rays) ? false : $show_rays; // show camera sight lines and light direction
|
show_rays = is_undef($show_rays) ? false : $show_rays; // show camera sight lines and light direction
|
||||||
@@ -53,9 +51,10 @@ $fs = extrusion_width / 2;
|
|||||||
function round_to_layer(z) = ceil(z / layer_height) * layer_height;
|
function round_to_layer(z) = ceil(z / layer_height) * layer_height;
|
||||||
// Some additional named colours
|
// Some additional named colours
|
||||||
function grey(n) = [0.01, 0.01, 0.01] * n; //! Generate a shade of grey to pass to color().
|
function grey(n) = [0.01, 0.01, 0.01] * n; //! Generate a shade of grey to pass to color().
|
||||||
gold = [255/255, 215/255, 0/255];
|
|
||||||
brass = [255/255, 220/255, 100/255];
|
|
||||||
silver = [0.75, 0.75, 0.75];
|
silver = [0.75, 0.75, 0.75];
|
||||||
|
gold = [255, 215, 0] / 255;
|
||||||
|
brass = [255, 220, 100] / 255;
|
||||||
|
copper = [230, 140, 51] / 255;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Enums
|
* Enums
|
||||||
|
9
lib.scad
@@ -26,7 +26,10 @@ include <vitamins/psus.scad>
|
|||||||
include <vitamins/pcbs.scad>
|
include <vitamins/pcbs.scad>
|
||||||
|
|
||||||
include <vitamins/batteries.scad>
|
include <vitamins/batteries.scad>
|
||||||
|
include <vitamins/bearing_blocks.scad>
|
||||||
include <vitamins/blowers.scad>
|
include <vitamins/blowers.scad>
|
||||||
|
include <vitamins/bldc_motors.scad>
|
||||||
|
include <vitamins/box_sections.scad>
|
||||||
include <vitamins/bulldogs.scad>
|
include <vitamins/bulldogs.scad>
|
||||||
include <vitamins/buttons.scad>
|
include <vitamins/buttons.scad>
|
||||||
include <vitamins/cameras.scad>
|
include <vitamins/cameras.scad>
|
||||||
@@ -37,7 +40,6 @@ include <vitamins/extrusion_brackets.scad>
|
|||||||
include <vitamins/geared_steppers.scad>
|
include <vitamins/geared_steppers.scad>
|
||||||
include <vitamins/hot_ends.scad>
|
include <vitamins/hot_ends.scad>
|
||||||
include <vitamins/inserts.scad>
|
include <vitamins/inserts.scad>
|
||||||
include <vitamins/kp_pillow_blocks.scad>
|
|
||||||
include <vitamins/ldrs.scad>
|
include <vitamins/ldrs.scad>
|
||||||
include <vitamins/leadnuts.scad>
|
include <vitamins/leadnuts.scad>
|
||||||
include <vitamins/led_meter.scad>
|
include <vitamins/led_meter.scad>
|
||||||
@@ -47,12 +49,13 @@ include <vitamins/mains_sockets.scad>
|
|||||||
include <vitamins/modules.scad>
|
include <vitamins/modules.scad>
|
||||||
include <vitamins/panel_meters.scad>
|
include <vitamins/panel_meters.scad>
|
||||||
include <vitamins/pillars.scad>
|
include <vitamins/pillars.scad>
|
||||||
|
include <vitamins/pillow_blocks.scad>
|
||||||
include <vitamins/pin_headers.scad>
|
include <vitamins/pin_headers.scad>
|
||||||
include <vitamins/pulleys.scad>
|
include <vitamins/pulleys.scad>
|
||||||
include <vitamins/ring_terminals.scad>
|
include <vitamins/ring_terminals.scad>
|
||||||
include <vitamins/rails.scad>
|
include <vitamins/rails.scad>
|
||||||
include <vitamins/rod.scad>
|
include <vitamins/rod.scad>
|
||||||
include <vitamins/scs_bearing_blocks.scad>
|
include <vitamins/servo_motors.scad>
|
||||||
include <vitamins/shaft_couplings.scad>
|
include <vitamins/shaft_couplings.scad>
|
||||||
include <vitamins/sheets.scad>
|
include <vitamins/sheets.scad>
|
||||||
include <vitamins/sk_brackets.scad>
|
include <vitamins/sk_brackets.scad>
|
||||||
@@ -89,7 +92,7 @@ use <utils/gears.scad>
|
|||||||
use <utils/hanging_hole.scad>
|
use <utils/hanging_hole.scad>
|
||||||
use <utils/fillet.scad>
|
use <utils/fillet.scad>
|
||||||
use <utils/rounded_polygon.scad>
|
use <utils/rounded_polygon.scad>
|
||||||
use <utils/rounded_right_triangle.scad>
|
use <utils/rounded_triangle.scad>
|
||||||
use <utils/layout.scad>
|
use <utils/layout.scad>
|
||||||
use <utils/round.scad>
|
use <utils/round.scad>
|
||||||
use <utils/offset.scad>
|
use <utils/offset.scad>
|
||||||
|
BIN
libtest.png
Before Width: | Height: | Size: 882 KiB After Width: | Height: | Size: 931 KiB |
87
libtest.scad
@@ -33,16 +33,22 @@
|
|||||||
//!
|
//!
|
||||||
//! See [usage](docs/usage.md) for requirements, installation instructions and a usage guide.
|
//! See [usage](docs/usage.md) for requirements, installation instructions and a usage guide.
|
||||||
//!
|
//!
|
||||||
|
//! A list of changes classified as breaking, additions or fixes is maintained in [CHANGELOG.md](CHANGELOG.md).
|
||||||
|
//!
|
||||||
//! <img src="libtest.png" width="100%"/>
|
//! <img src="libtest.png" width="100%"/>
|
||||||
//
|
//
|
||||||
// This file shows all the parts in the library.
|
// This file shows all the parts in the library.
|
||||||
//
|
//
|
||||||
include <lib.scad>
|
include <lib.scad>
|
||||||
|
|
||||||
|
use <tests/7_segments.scad>
|
||||||
use <tests/ball_bearings.scad>
|
use <tests/ball_bearings.scad>
|
||||||
use <tests/batteries.scad>
|
use <tests/batteries.scad>
|
||||||
|
use <tests/bearing_blocks.scad>
|
||||||
use <tests/belts.scad>
|
use <tests/belts.scad>
|
||||||
|
use <tests/BLDC_motors.scad>
|
||||||
use <tests/blowers.scad>
|
use <tests/blowers.scad>
|
||||||
|
use <tests/box_sections.scad>
|
||||||
use <tests/bulldogs.scad>
|
use <tests/bulldogs.scad>
|
||||||
use <tests/buttons.scad>
|
use <tests/buttons.scad>
|
||||||
use <tests/cable_strips.scad>
|
use <tests/cable_strips.scad>
|
||||||
@@ -62,7 +68,6 @@ use <tests/hot_ends.scad>
|
|||||||
use <tests/IECs.scad>
|
use <tests/IECs.scad>
|
||||||
use <tests/inserts.scad>
|
use <tests/inserts.scad>
|
||||||
use <tests/jack.scad>
|
use <tests/jack.scad>
|
||||||
use <tests/KP_pillow_blocks.scad>
|
|
||||||
use <tests/leadnuts.scad>
|
use <tests/leadnuts.scad>
|
||||||
use <tests/LDRs.scad>
|
use <tests/LDRs.scad>
|
||||||
use <tests/LEDs.scad>
|
use <tests/LEDs.scad>
|
||||||
@@ -78,6 +83,8 @@ use <tests/opengrab.scad>
|
|||||||
use <tests/panel_meters.scad>
|
use <tests/panel_meters.scad>
|
||||||
use <tests/PCBs.scad>
|
use <tests/PCBs.scad>
|
||||||
use <tests/pillars.scad>
|
use <tests/pillars.scad>
|
||||||
|
use <tests/pillow_blocks.scad>
|
||||||
|
use <tests/potentiometers.scad>
|
||||||
use <tests/press_fit.scad>
|
use <tests/press_fit.scad>
|
||||||
use <tests/PSUs.scad>
|
use <tests/PSUs.scad>
|
||||||
use <tests/pulleys.scad>
|
use <tests/pulleys.scad>
|
||||||
@@ -86,8 +93,8 @@ use <tests/ring_terminals.scad>
|
|||||||
use <tests/rockers.scad>
|
use <tests/rockers.scad>
|
||||||
use <tests/rod.scad>
|
use <tests/rod.scad>
|
||||||
use <tests/screws.scad>
|
use <tests/screws.scad>
|
||||||
use <tests/SCS_bearing_blocks.scad>
|
|
||||||
use <tests/sealing_strip.scad>
|
use <tests/sealing_strip.scad>
|
||||||
|
use <tests/servo_motors.scad>
|
||||||
use <tests/shaft_couplings.scad>
|
use <tests/shaft_couplings.scad>
|
||||||
use <tests/sheets.scad>
|
use <tests/sheets.scad>
|
||||||
use <tests/SK_brackets.scad>
|
use <tests/SK_brackets.scad>
|
||||||
@@ -117,6 +124,7 @@ use <tests/flat_hinge.scad>
|
|||||||
use <tests/foot.scad>
|
use <tests/foot.scad>
|
||||||
use <tests/handle.scad>
|
use <tests/handle.scad>
|
||||||
use <tests/PCB_mount.scad>
|
use <tests/PCB_mount.scad>
|
||||||
|
use <tests/pocket_handle.scad>
|
||||||
use <tests/printed_box.scad>
|
use <tests/printed_box.scad>
|
||||||
use <tests/printed_pulleys.scad>
|
use <tests/printed_pulleys.scad>
|
||||||
use <tests/ribbon_clamp.scad>
|
use <tests/ribbon_clamp.scad>
|
||||||
@@ -180,13 +188,15 @@ translate([x5, cable_grommets_y + 250])
|
|||||||
translate([950, 600])
|
translate([950, 600])
|
||||||
box_test();
|
box_test();
|
||||||
|
|
||||||
translate([890, 750])
|
translate([900, 750])
|
||||||
|
pocket_handles();
|
||||||
|
|
||||||
|
translate([900, 850])
|
||||||
printed_boxes();
|
printed_boxes();
|
||||||
|
|
||||||
translate([850, 1330])
|
translate([850, 1330 + 85])
|
||||||
bbox_test();
|
bbox_test();
|
||||||
|
|
||||||
|
|
||||||
inserts_y = 0;
|
inserts_y = 0;
|
||||||
nuts_y = inserts_y + 20;
|
nuts_y = inserts_y + 20;
|
||||||
washers_y = nuts_y + 120;
|
washers_y = nuts_y + 120;
|
||||||
@@ -198,13 +208,14 @@ sealing_strip_y = springs_y + 20;
|
|||||||
tubings_y = sealing_strip_y + 20;
|
tubings_y = sealing_strip_y + 20;
|
||||||
pillars_y = tubings_y + 20;
|
pillars_y = tubings_y + 20;
|
||||||
ball_bearings_y = pillars_y + 40;
|
ball_bearings_y = pillars_y + 40;
|
||||||
pulleys_y = ball_bearings_y +40;
|
pulleys_y = ball_bearings_y + 40;
|
||||||
hot_ends_y = pulleys_y + 60;
|
leadnuts_y = pulleys_y + 60;
|
||||||
linear_bearings_y = hot_ends_y + 50;
|
linear_bearings_y = leadnuts_y + 50;
|
||||||
sheets_y = linear_bearings_y + 100;
|
steppers_y = linear_bearings_y + 110;
|
||||||
pcbs_y = sheets_y + 40;
|
sheets_y = steppers_y + 55;
|
||||||
displays_y = pcbs_y + 170;
|
pcbs_y = sheets_y + 60;
|
||||||
fans_y = displays_y + 80;
|
displays_y = pcbs_y + 140;
|
||||||
|
fans_y = displays_y + 110;
|
||||||
transformers_y = fans_y + 120;
|
transformers_y = fans_y + 120;
|
||||||
psus_y = transformers_y + 190;
|
psus_y = transformers_y + 190;
|
||||||
|
|
||||||
@@ -247,13 +258,16 @@ translate([x0, ball_bearings_y])
|
|||||||
translate([x0, pulleys_y])
|
translate([x0, pulleys_y])
|
||||||
pulleys();
|
pulleys();
|
||||||
|
|
||||||
|
translate([x0, leadnuts_y])
|
||||||
|
leadnuts();
|
||||||
|
|
||||||
translate([x0, linear_bearings_y]) {
|
translate([x0, linear_bearings_y]) {
|
||||||
linear_bearings();
|
linear_bearings();
|
||||||
rods();
|
rods();
|
||||||
}
|
}
|
||||||
|
|
||||||
translate([x0 + 10, hot_ends_y])
|
translate([x0, steppers_y])
|
||||||
hot_ends();
|
stepper_motors();
|
||||||
|
|
||||||
translate([x0, sheets_y])
|
translate([x0, sheets_y])
|
||||||
sheets();
|
sheets();
|
||||||
@@ -271,7 +285,7 @@ translate([x0, fans_y]) {
|
|||||||
fan_guards();
|
fan_guards();
|
||||||
}
|
}
|
||||||
|
|
||||||
translate([x0, transformers_y])
|
translate([760, fans_y])
|
||||||
variacs();
|
variacs();
|
||||||
|
|
||||||
translate([x0, psus_y]) {
|
translate([x0, psus_y]) {
|
||||||
@@ -283,7 +297,6 @@ translate([x0, psus_y]) {
|
|||||||
zipties_y = 0;
|
zipties_y = 0;
|
||||||
bulldogs_y = zipties_y + 30;
|
bulldogs_y = zipties_y + 30;
|
||||||
swiss_clips_y = bulldogs_y + 35;
|
swiss_clips_y = bulldogs_y + 35;
|
||||||
leadnuts_y = swiss_clips_y + 50;
|
|
||||||
|
|
||||||
translate([x1, zipties_y])
|
translate([x1, zipties_y])
|
||||||
zipties();
|
zipties();
|
||||||
@@ -294,10 +307,6 @@ translate([x1, bulldogs_y])
|
|||||||
translate([x1, swiss_clips_y])
|
translate([x1, swiss_clips_y])
|
||||||
swiss_clips();
|
swiss_clips();
|
||||||
|
|
||||||
translate([x1, leadnuts_y])
|
|
||||||
leadnuts();
|
|
||||||
|
|
||||||
|
|
||||||
leds_y = 0;
|
leds_y = 0;
|
||||||
carriers_y = leds_y + 40;
|
carriers_y = leds_y + 40;
|
||||||
magnets_y = carriers_y + 40;
|
magnets_y = carriers_y + 40;
|
||||||
@@ -354,18 +363,18 @@ iecs_y = d_connectors_y + 80;
|
|||||||
modules_y = iecs_y + 60;
|
modules_y = iecs_y + 60;
|
||||||
ssrs_y = modules_y + 80;
|
ssrs_y = modules_y + 80;
|
||||||
blowers_y = ssrs_y + 60;
|
blowers_y = ssrs_y + 60;
|
||||||
batteries_y = blowers_y + 100;
|
hot_ends_y = blowers_y + 100;
|
||||||
steppers_y = batteries_y + 55;
|
batteries_y = hot_ends_y + 55;
|
||||||
panel_meters_y = steppers_y + 70;
|
panel_meters_y = batteries_y + 70;
|
||||||
extrusions_y = panel_meters_y + 80;
|
extrusions_y = panel_meters_y + 80;
|
||||||
|
|
||||||
translate([x3, veroboard_y])
|
translate([x3, veroboard_y])
|
||||||
veroboard_test();
|
veroboard_test();
|
||||||
|
|
||||||
translate([x3 + 70, veroboard_y + 30])
|
translate([x3 + 60, veroboard_y + 20])
|
||||||
geared_steppers();
|
geared_steppers();
|
||||||
|
|
||||||
translate([x3 + 140, veroboard_y + 20])
|
translate([x3 + 160, ssrs_y])
|
||||||
pcb_mounts();
|
pcb_mounts();
|
||||||
|
|
||||||
translate([x3 + 170, veroboard_y + 16])
|
translate([x3 + 170, veroboard_y + 16])
|
||||||
@@ -401,8 +410,8 @@ translate([x3, blowers_y])
|
|||||||
translate([x3, batteries_y])
|
translate([x3, batteries_y])
|
||||||
batteries();
|
batteries();
|
||||||
|
|
||||||
translate([x2, steppers_y]) // interloper
|
translate([x3 + 10, hot_ends_y])
|
||||||
stepper_motors();
|
hot_ends();
|
||||||
|
|
||||||
translate([x2, panel_meters_y])
|
translate([x2, panel_meters_y])
|
||||||
panel_meters();
|
panel_meters();
|
||||||
@@ -410,7 +419,7 @@ translate([x2, panel_meters_y])
|
|||||||
translate([x2, extrusions_y])
|
translate([x2, extrusions_y])
|
||||||
extrusions();
|
extrusions();
|
||||||
|
|
||||||
translate([x3, transformers_y])
|
translate([400, transformers_y])
|
||||||
transformers();
|
transformers();
|
||||||
|
|
||||||
|
|
||||||
@@ -418,15 +427,21 @@ belts_y = 0;
|
|||||||
rails_y = belts_y + 200;
|
rails_y = belts_y + 200;
|
||||||
extrusion_brackets_y = rails_y + 250;
|
extrusion_brackets_y = rails_y + 250;
|
||||||
sk_brackets_y = extrusion_brackets_y + 80;
|
sk_brackets_y = extrusion_brackets_y + 80;
|
||||||
kp_pillow_blocks_y = sk_brackets_y + 50;
|
kp_pillow_blocks_y = sk_brackets_y + 60;
|
||||||
scs_bearing_blocks_y = kp_pillow_blocks_y + 60;
|
scs_bearing_blocks_y = kp_pillow_blocks_y + 60;
|
||||||
|
box_sections_y = batteries_y;
|
||||||
|
BLDC_y = scs_bearing_blocks_y + 120;
|
||||||
|
pot_y = BLDC_y + 40;
|
||||||
|
cable_strip_y = pot_y + 50;
|
||||||
|
|
||||||
|
translate([0, transformers_y])
|
||||||
|
servo_motors();
|
||||||
|
|
||||||
translate([x4 + 200, belts_y + 58]) {
|
translate([x4 + 200, belts_y + 58]) {
|
||||||
belt_test();
|
belt_test();
|
||||||
|
|
||||||
translate([0, 60])
|
translate([0, 60])
|
||||||
opengrab_test();
|
opengrab_test();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
translate([x4 + 175, belts_y, -20])
|
translate([x4 + 175, belts_y, -20])
|
||||||
@@ -435,7 +450,7 @@ translate([x4 + 175, belts_y, -20])
|
|||||||
translate([x4, rails_y + 130])
|
translate([x4, rails_y + 130])
|
||||||
rails();
|
rails();
|
||||||
|
|
||||||
translate([770, fans_y + 50])
|
translate([x4, cable_strip_y])
|
||||||
cable_strips();
|
cable_strips();
|
||||||
|
|
||||||
translate([x4, kp_pillow_blocks_y])
|
translate([x4, kp_pillow_blocks_y])
|
||||||
@@ -447,12 +462,20 @@ translate([x4, sk_brackets_y])
|
|||||||
translate([x4, extrusion_brackets_y])
|
translate([x4, extrusion_brackets_y])
|
||||||
extrusion_brackets();
|
extrusion_brackets();
|
||||||
|
|
||||||
translate([x4 + 120, extrusion_brackets_y])
|
translate([x1, swiss_clips_y + 50])
|
||||||
shaft_couplings();
|
shaft_couplings();
|
||||||
|
|
||||||
translate([x4, scs_bearing_blocks_y])
|
translate([x4, scs_bearing_blocks_y])
|
||||||
scs_bearing_blocks();
|
scs_bearing_blocks();
|
||||||
|
|
||||||
|
translate([x4, BLDC_y])
|
||||||
|
bldc_motors();
|
||||||
|
|
||||||
|
translate([x4, pot_y])
|
||||||
|
potentiometers();
|
||||||
|
|
||||||
|
translate([x2, box_sections_y])
|
||||||
|
box_sections();
|
||||||
|
|
||||||
translate([x6, 125])
|
translate([x6, 125])
|
||||||
light_strips();
|
light_strips();
|
||||||
|
@@ -54,7 +54,7 @@ function bbox(screw, sheets, base_sheet, top_sheet, span, size, name = "bbox", s
|
|||||||
[ screw, sheets, base_sheet, top_sheet, span, size.x, size.y, size.z, name, skip_blocks, star_washers ];
|
[ screw, sheets, base_sheet, top_sheet, span, size.x, size.y, size.z, name, skip_blocks, star_washers ];
|
||||||
|
|
||||||
function bbox_volume(type) = bbox_width(type) * bbox_depth(type) * bbox_height(type) / 1000000; //! Internal volume in litres
|
function bbox_volume(type) = bbox_width(type) * bbox_depth(type) * bbox_height(type) / 1000000; //! Internal volume in litres
|
||||||
function bbox_area(type) = let(w = bbox_width(type), d = bbox_depth(type), h = bbox_height(type)) //! Internal surdface area in m^2
|
function bbox_area(type) = let(w = bbox_width(type), d = bbox_depth(type), h = bbox_height(type)) //! Internal surface area in m^2
|
||||||
2 * (w * d + w * h + d * h) / 1000000;
|
2 * (w * d + w * h + d * h) / 1000000;
|
||||||
|
|
||||||
module bbox_shelf_blank(type) { //! 2D template for a shelf
|
module bbox_shelf_blank(type) { //! 2D template for a shelf
|
||||||
|
@@ -45,7 +45,7 @@ function door_hinge_stat_screw() = stat_screw; //! Screw use to fas
|
|||||||
function door_hinge_stat_width() = stat_width; //! Width of the stationary part
|
function door_hinge_stat_width() = stat_width; //! Width of the stationary part
|
||||||
function door_hinge_stat_length() = stat_length; //! Length of the stationary part
|
function door_hinge_stat_length() = stat_length; //! Length of the stationary part
|
||||||
|
|
||||||
module door_hinge_hole_positions(dir = 0) { //! Position chidren at the door hole positions
|
module door_hinge_hole_positions(dir = 0) { //! Position children at the door hole positions
|
||||||
hole_pitch = width - 10;
|
hole_pitch = width - 10;
|
||||||
|
|
||||||
for(side = [-1, 1])
|
for(side = [-1, 1])
|
||||||
|
@@ -57,7 +57,7 @@ module door_latch_stl() { //! Generates the STL for the printed part
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module door_latch_assembly(sheet_thickness = 3) { //! The assembly for a specified sheet thickess
|
module door_latch_assembly(sheet_thickness = 3) { //! The assembly for a specified sheet thickness
|
||||||
washer = screw_washer(screw);
|
washer = screw_washer(screw);
|
||||||
nut = screw_nut(screw);
|
nut = screw_nut(screw);
|
||||||
|
|
||||||
|
@@ -20,7 +20,7 @@
|
|||||||
//
|
//
|
||||||
//! Parametric cable drag chain to limit the bend radius of a cable run.
|
//! Parametric cable drag chain to limit the bend radius of a cable run.
|
||||||
//!
|
//!
|
||||||
//! Each link has a maximum bend angle of 45°, so the mininium radius is proportional to the link length.
|
//! Each link has a maximum bend angle of 45°, so the minimum radius is proportional to the link length.
|
||||||
//!
|
//!
|
||||||
//! The travel property is how far it can move in each direction, i.e. half the maximum travel if the chain is mounted in the middle of the travel.
|
//! The travel property is how far it can move in each direction, i.e. half the maximum travel if the chain is mounted in the middle of the travel.
|
||||||
//!
|
//!
|
||||||
|
@@ -17,7 +17,7 @@
|
|||||||
// If not, see <https://www.gnu.org/licenses/>.
|
// If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
//
|
//
|
||||||
//! Pintable fan finger guard to match the specified fan. To be `include`d, not `use`d.
|
//! Printable fan finger guard to match the specified fan. To be `include`d, not `use`d.
|
||||||
//!
|
//!
|
||||||
//! The ring spacing as well as the number of spokes can be specified, if zero a gasket is generated instead of a guard.
|
//! The ring spacing as well as the number of spokes can be specified, if zero a gasket is generated instead of a guard.
|
||||||
//
|
//
|
||||||
|
@@ -40,7 +40,7 @@ function hinge_knuckles(type) = type[6]; //! How many knuckles
|
|||||||
function hinge_screw(type) = type[7]; //! Screw type to mount it
|
function hinge_screw(type) = type[7]; //! Screw type to mount it
|
||||||
function hinge_screws(type) = type[8]; //! How many screws
|
function hinge_screws(type) = type[8]; //! How many screws
|
||||||
function hinge_clearance(type) = type[9]; //! Clearance between knuckles
|
function hinge_clearance(type) = type[9]; //! Clearance between knuckles
|
||||||
function hinge_margin(type) = type[10]; //! How far to keep the screws from the knuckes
|
function hinge_margin(type) = type[10]; //! How far to keep the screws from the knuckles
|
||||||
|
|
||||||
function flat_hinge(name, size, pin_d, knuckle_d, knuckles, screw, screws, clearance, margin) = //! Construct the property list for a flat hinge.
|
function flat_hinge(name, size, pin_d, knuckle_d, knuckles, screw, screws, clearance, margin) = //! Construct the property list for a flat hinge.
|
||||||
[name, size.x, size.y, size.z, pin_d, knuckle_d, knuckles, screw, screws, clearance, margin];
|
[name, size.x, size.y, size.z, pin_d, knuckle_d, knuckles, screw, screws, clearance, margin];
|
||||||
@@ -73,7 +73,7 @@ module hinge_male(type, female = false) { //! The half with the stationary
|
|||||||
assert(kr > pr, "knuckle diameter must be bigger than the pin diameter");
|
assert(kr > pr, "knuckle diameter must be bigger than the pin diameter");
|
||||||
|
|
||||||
n = hinge_knuckles(type);
|
n = hinge_knuckles(type);
|
||||||
assert(n >= 3, "must be at least three knuckes");
|
assert(n >= 3, "must be at least three knuckles");
|
||||||
mn = ceil(n / 2); // Male knuckles
|
mn = ceil(n / 2); // Male knuckles
|
||||||
fn = floor(n / 2); // Female knuckles
|
fn = floor(n / 2); // Female knuckles
|
||||||
gap = hinge_clearance(type);
|
gap = hinge_clearance(type);
|
||||||
|
154
printed/pocket_handle.scad
Normal file
@@ -0,0 +1,154 @@
|
|||||||
|
//
|
||||||
|
// NopSCADlib Copyright Chris Palmer 2021
|
||||||
|
// 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/>.
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
//! Customisable pocket handle
|
||||||
|
//
|
||||||
|
include <../core.scad>
|
||||||
|
|
||||||
|
function pocket_handle(hand_size = [90, 40, 40], slant = 35, screw = M3_cs_cap_screw, panel_t = 3, wall = 4, rad = 4) = //! Construct a pocket_handle property list
|
||||||
|
[hand_size, slant, screw, panel_t, wall, rad];
|
||||||
|
|
||||||
|
function pocket_handle_hand_size(type) = type[0]; //! Size of the hole for the fingers
|
||||||
|
function pocket_handle_slant(type) = type[1]; //! Upward slant of the hand hole
|
||||||
|
function pocket_handle_screw(type) = type[2]; //! Screw type, can be countersunk or not
|
||||||
|
function pocket_handle_panel_t(type) = type[3]; //! Thickness of the panel it is mounted in
|
||||||
|
function pocket_handle_wall(type) = type[4]; //! Wall thickness
|
||||||
|
function pocket_handle_rad(type) = type[5]; //! Min corner rad
|
||||||
|
|
||||||
|
function pocket_handle_flange(type) = //! Size of the flange
|
||||||
|
let(w = pocket_handle_wall(type),
|
||||||
|
f = washer_diameter(screw_washer(pocket_handle_screw(type))) + 2 + w,
|
||||||
|
s = pocket_handle_hand_size(type))
|
||||||
|
[s.x + 2 * f, s.y + 2 * f, w];
|
||||||
|
|
||||||
|
module pocket_handle_hole_positions(type) { //! Place children at screw hole positions
|
||||||
|
f = pocket_handle_flange(type);
|
||||||
|
h = pocket_handle_hand_size(type);
|
||||||
|
x_pitch = (f.x + h.x) / 4;
|
||||||
|
y_pitch = (f.y + h.y) / 4;
|
||||||
|
|
||||||
|
for(x = [-1, 1], y = [-1, 1])
|
||||||
|
translate([x * x_pitch, y * y_pitch])
|
||||||
|
children();
|
||||||
|
}
|
||||||
|
|
||||||
|
module pocket_handle_holes(type, h = 0) { //! Panel cutout and screw holes
|
||||||
|
hand = pocket_handle_hand_size(type);
|
||||||
|
w = pocket_handle_wall(type);
|
||||||
|
slot = [hand.x + 2 * w, hand.y + 2 * w];
|
||||||
|
t = pocket_handle_panel_t(type);
|
||||||
|
clearance = norm([slot.y, t]) - slot.y + 0.2; // has to be enough clearance for the diagonal to swing it in
|
||||||
|
|
||||||
|
extrude_if(h) {
|
||||||
|
pocket_handle_hole_positions(type)
|
||||||
|
drill(screw_clearance_radius(pocket_handle_screw(type)), 0);
|
||||||
|
|
||||||
|
rounded_square([slot.x + clearance, slot.y + clearance], pocket_handle_rad(type) + w + clearance / 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module pocket_handle(type) { //! Generate STL for pocket_handle
|
||||||
|
f = pocket_handle_flange(type);
|
||||||
|
r = pocket_handle_rad(type);
|
||||||
|
s = pocket_handle_slant(type);
|
||||||
|
o = f.z * tan(s);
|
||||||
|
h = pocket_handle_hand_size(type);
|
||||||
|
t = pocket_handle_panel_t(type);
|
||||||
|
w = pocket_handle_wall(type);
|
||||||
|
screw = pocket_handle_screw(type) ;
|
||||||
|
|
||||||
|
stl("pocket_handle")
|
||||||
|
union() {
|
||||||
|
difference() {
|
||||||
|
hull() {
|
||||||
|
rounded_rectangle(f, r);
|
||||||
|
|
||||||
|
translate_z(f.z - eps)
|
||||||
|
rounded_rectangle([f.x + 2 * o, f.y + 2 * o, eps], r + o);
|
||||||
|
}
|
||||||
|
hull() {
|
||||||
|
rounded_rectangle([h.x, h.y, f.z + eps], r);
|
||||||
|
|
||||||
|
translate_z(-eps)
|
||||||
|
rounded_rectangle([h.x + 2 * o, h.y + 2 * o, eps], r + o);
|
||||||
|
}
|
||||||
|
pocket_handle_hole_positions(type) {
|
||||||
|
if(screw_head_height(screw))
|
||||||
|
translate_z(-eps)
|
||||||
|
poly_cylinder(r = screw_clearance_radius(screw), h = f.z + 2 * eps, center = false);
|
||||||
|
else
|
||||||
|
screw_polysink(screw, h = 2 * f.z + eps, alt = true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
translate_z(f.z)
|
||||||
|
linear_extrude(t)
|
||||||
|
difference() {
|
||||||
|
rounded_square([h.x + 2 * w, h.y + 2 * w], r + w);
|
||||||
|
|
||||||
|
rounded_square([h.x, h.y], r);
|
||||||
|
}
|
||||||
|
|
||||||
|
translate_z(f.z + t)
|
||||||
|
difference() {
|
||||||
|
height = h.z - f.z - t;
|
||||||
|
hull() {
|
||||||
|
rounded_rectangle([h.x + 2 * w, h.y + 2 * w, eps], r + w);
|
||||||
|
|
||||||
|
translate((height + w) * [0, sin(s), cos(s)])
|
||||||
|
rounded_rectangle([h.x + 2 * w, h.y + 2 * w, eps], r + w);
|
||||||
|
}
|
||||||
|
|
||||||
|
hull() {
|
||||||
|
translate_z(-eps)
|
||||||
|
rounded_rectangle([h.x, h.y, eps], r);
|
||||||
|
|
||||||
|
translate(height * [0, sin(s), cos(s)])
|
||||||
|
rounded_rectangle([h.x, h.y, eps], r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module pocket_handle_assembly(type) { //! Assembly with fasteners in place
|
||||||
|
f = pocket_handle_flange(type);
|
||||||
|
screw = pocket_handle_screw(type);
|
||||||
|
nut = screw_nut(screw);
|
||||||
|
t = pocket_handle_panel_t(type);
|
||||||
|
washers = screw_head_height(screw) ? 2 : 1;
|
||||||
|
screw_length = screw_length(screw, f.z + t, washers, nyloc = true);
|
||||||
|
|
||||||
|
translate_z(f.z + t / 2) hflip() {
|
||||||
|
stl_colour(pp1_colour)
|
||||||
|
pocket_handle(type);
|
||||||
|
|
||||||
|
pocket_handle_hole_positions(type) {
|
||||||
|
translate_z(f.z + t)
|
||||||
|
explode(15, true)
|
||||||
|
nut_and_washer(nut, true);
|
||||||
|
|
||||||
|
vflip()
|
||||||
|
if(washers == 2)
|
||||||
|
screw_and_washer(screw, screw_length);
|
||||||
|
else
|
||||||
|
screw(screw, screw_length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -41,6 +41,7 @@ overlap = 6;
|
|||||||
cable_tie_inset = wall + 4;
|
cable_tie_inset = wall + 4;
|
||||||
|
|
||||||
function psu_shroud_extent(type) = 15 + wall; //! How far it extends beyond the PSU to clear the connections
|
function psu_shroud_extent(type) = 15 + wall; //! How far it extends beyond the PSU to clear the connections
|
||||||
|
function psu_shroud_wall(type) = wall; //! The wall thickness
|
||||||
function psu_shroud_depth(type) = //! Outside depth of the shroud
|
function psu_shroud_depth(type) = //! Outside depth of the shroud
|
||||||
psu_left_bay(type) + overlap + psu_shroud_extent(type);
|
psu_left_bay(type) + overlap + psu_shroud_extent(type);
|
||||||
|
|
||||||
@@ -154,7 +155,7 @@ assembly(str("PSU_shroud_", name), ngb = true) {
|
|||||||
insert(insert);
|
insert(insert);
|
||||||
}
|
}
|
||||||
|
|
||||||
module psu_shroud_fastened_assembly(type, cable_d, thickness, name, cables = 1) //! Assembly with screws in place
|
module psu_shroud_fastened_assembly(type, cable_d, thickness, name, cables = 1, screw = screw) //! Assembly with screws in place
|
||||||
{
|
{
|
||||||
screw_length = screw_length(screw,thickness + counter_bore, 2, true);
|
screw_length = screw_length(screw,thickness + counter_bore, 2, true);
|
||||||
|
|
||||||
|
@@ -31,6 +31,12 @@ from set_config import *
|
|||||||
import json
|
import json
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
try:
|
||||||
|
import parts
|
||||||
|
got_parts_py = True
|
||||||
|
except:
|
||||||
|
got_parts_py = False
|
||||||
|
|
||||||
def find_scad_file(mname):
|
def find_scad_file(mname):
|
||||||
for filename in os.listdir(source_dir):
|
for filename in os.listdir(source_dir):
|
||||||
if filename[-5:] == ".scad":
|
if filename[-5:] == ".scad":
|
||||||
@@ -46,6 +52,18 @@ def find_scad_file(mname):
|
|||||||
return filename
|
return filename
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def main_assembly(target):
|
||||||
|
file = None
|
||||||
|
if target:
|
||||||
|
assembly = target + "_assembly"
|
||||||
|
file = find_scad_file(assembly)
|
||||||
|
if not file:
|
||||||
|
assembly = "main_assembly"
|
||||||
|
file = find_scad_file(assembly)
|
||||||
|
if not file:
|
||||||
|
raise Exception("can't find source for " + assembly)
|
||||||
|
return assembly, file
|
||||||
|
|
||||||
class Part:
|
class Part:
|
||||||
def __init__(self, args):
|
def __init__(self, args):
|
||||||
self.count = 1
|
self.count = 1
|
||||||
@@ -61,6 +79,7 @@ class BOM:
|
|||||||
self.name = name
|
self.name = name
|
||||||
self.big = None
|
self.big = None
|
||||||
self.ngb = False
|
self.ngb = False
|
||||||
|
self.zoomed = 0
|
||||||
self.count = 1
|
self.count = 1
|
||||||
self.vitamins = {}
|
self.vitamins = {}
|
||||||
self.printed = {}
|
self.printed = {}
|
||||||
@@ -75,6 +94,7 @@ class BOM:
|
|||||||
"name" : self.name,
|
"name" : self.name,
|
||||||
"big" : self.big,
|
"big" : self.big,
|
||||||
"ngb" : self.ngb,
|
"ngb" : self.ngb,
|
||||||
|
"zoomed" : self.zoomed,
|
||||||
"count" : self.count,
|
"count" : self.count,
|
||||||
"assemblies" : assemblies,
|
"assemblies" : assemblies,
|
||||||
"vitamins" : {v : self.vitamins[v].data() for v in self.vitamins},
|
"vitamins" : {v : self.vitamins[v].data() for v in self.vitamins},
|
||||||
@@ -115,6 +135,33 @@ class BOM:
|
|||||||
return ass
|
return ass
|
||||||
return ass.replace("assembly", "assemblies")
|
return ass.replace("assembly", "assemblies")
|
||||||
|
|
||||||
|
def print_CSV(self, file = None):
|
||||||
|
i = 0
|
||||||
|
for part in sorted(self.vitamins):
|
||||||
|
i += 1
|
||||||
|
if ': ' in part:
|
||||||
|
part_no, description = part.split(': ')
|
||||||
|
else:
|
||||||
|
part_no, description = "", part
|
||||||
|
qty = self.vitamins[part].count
|
||||||
|
if got_parts_py:
|
||||||
|
match = re.match(r'^.*\((.*?)[,\)].*$', part_no)
|
||||||
|
if match and not match.group(1).startswith('"'):
|
||||||
|
part_no = part_no.replace('(' + match.group(1), '_' + match.group(1) + '(').replace('(, ', '(')
|
||||||
|
func = 'parts.' + part_no.replace('(', '(%d, ' % qty).replace(', )', ')')
|
||||||
|
func = func.replace('true', 'True').replace('false', 'False').replace('undef', 'None')
|
||||||
|
try:
|
||||||
|
price, url = eval(func)
|
||||||
|
print("'%s',%3d,%.2f,'=B%d*C%d',%s" % (description, qty, price, i, i, url), file=file)
|
||||||
|
except:
|
||||||
|
if part_no:
|
||||||
|
print("%s not found in parts.py" % func)
|
||||||
|
print("'%s',%3d" % (description, qty), file=file)
|
||||||
|
else:
|
||||||
|
print("'%s',%3d" % (description, qty), file=file)
|
||||||
|
if got_parts_py:
|
||||||
|
print(",'=SUM(B1:B%d)',,'=SUM(D1:D%d)'" %(i, i), file=file)
|
||||||
|
|
||||||
def print_bom(self, breakdown, file = None):
|
def print_bom(self, breakdown, file = None):
|
||||||
if self.vitamins:
|
if self.vitamins:
|
||||||
print("Vitamins:", file=file)
|
print("Vitamins:", file=file)
|
||||||
@@ -219,28 +266,20 @@ def parse_bom(file = "openscad.log", name = None):
|
|||||||
return main
|
return main
|
||||||
|
|
||||||
def usage():
|
def usage():
|
||||||
print("\nusage:\n\tbom [target_config] [<accessory_name>_assembly] - Generate BOMs for a project or an accessory to a project.")
|
print("\nusage:\n\tbom [target_config] - Generate BOMs for a project.")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
def boms(target = None, assembly = None):
|
def boms(target = None):
|
||||||
try:
|
try:
|
||||||
bom_dir = set_config(target, usage) + "bom"
|
bom_dir = set_config(target, usage) + "bom"
|
||||||
if assembly:
|
if os.path.isdir(bom_dir):
|
||||||
bom_dir += "/accessories"
|
shutil.rmtree(bom_dir)
|
||||||
if not os.path.isdir(bom_dir):
|
sleep(0.1)
|
||||||
os.makedirs(bom_dir)
|
os.makedirs(bom_dir)
|
||||||
else:
|
|
||||||
assembly = "main_assembly"
|
|
||||||
if os.path.isdir(bom_dir):
|
|
||||||
shutil.rmtree(bom_dir)
|
|
||||||
sleep(0.1)
|
|
||||||
os.makedirs(bom_dir)
|
|
||||||
#
|
#
|
||||||
# Find the scad file that makes the module
|
# Find the scad file that makes the main assembly
|
||||||
#
|
#
|
||||||
scad_file = find_scad_file(assembly)
|
assembly, scad_file = main_assembly(target)
|
||||||
if not scad_file:
|
|
||||||
raise Exception("can't find source for " + assembly)
|
|
||||||
#
|
#
|
||||||
# make a file to use the module
|
# make a file to use the module
|
||||||
#
|
#
|
||||||
@@ -257,8 +296,9 @@ def boms(target = None, assembly = None):
|
|||||||
|
|
||||||
main = parse_bom("openscad.echo", assembly)
|
main = parse_bom("openscad.echo", assembly)
|
||||||
|
|
||||||
if assembly == "main_assembly":
|
main.print_bom(True, open(bom_dir + "/bom.txt","wt"))
|
||||||
main.print_bom(True, open(bom_dir + "/bom.txt","wt"))
|
|
||||||
|
main.print_CSV(open(bom_dir + "/bom.csv","wt"))
|
||||||
|
|
||||||
for ass in main.assemblies:
|
for ass in main.assemblies:
|
||||||
with open(bom_dir + "/" + ass + ".txt", "wt") as f:
|
with open(bom_dir + "/" + ass + ".txt", "wt") as f:
|
||||||
@@ -276,20 +316,8 @@ def boms(target = None, assembly = None):
|
|||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
if len(sys.argv) > 3: usage()
|
if len(sys.argv) > 2: usage()
|
||||||
|
|
||||||
if len(sys.argv) == 3:
|
target = sys.argv[1] if len(sys.argv) == 2 else None
|
||||||
target, assembly = sys.argv[1], sys.argv[2]
|
|
||||||
else:
|
|
||||||
if len(sys.argv) == 2:
|
|
||||||
if sys.argv[1][-9:] == "_assembly":
|
|
||||||
target, assembly = None, sys.argv[1]
|
|
||||||
else:
|
|
||||||
target, assembly = sys.argv[1], None
|
|
||||||
else:
|
|
||||||
target, assembly = None, None
|
|
||||||
|
|
||||||
if assembly:
|
boms(target)
|
||||||
if assembly[-9:] != "_assembly": usage()
|
|
||||||
|
|
||||||
boms(target, assembly)
|
|
||||||
|
166
scripts/changelog.py
Normal file
@@ -0,0 +1,166 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
#
|
||||||
|
# NopSCADlib Copyright Chris Palmer 2021
|
||||||
|
# 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/>.
|
||||||
|
#
|
||||||
|
#! Creates the changelog from the git log
|
||||||
|
|
||||||
|
from __future__ import print_function
|
||||||
|
import sys
|
||||||
|
import subprocess
|
||||||
|
import re
|
||||||
|
from tests import do_cmd
|
||||||
|
|
||||||
|
filename = 'CHANGELOG.md'
|
||||||
|
|
||||||
|
def tag_version(t):
|
||||||
|
""" Format a version tag """
|
||||||
|
return 'v%d.%d.%d' % t
|
||||||
|
|
||||||
|
def initials(name):
|
||||||
|
""" Convert full name to initials with a tooltip """
|
||||||
|
i = ''.join([n[0].upper() + '.' for n in name.split(' ')])
|
||||||
|
return '[%s](# "%s")' % (i, name)
|
||||||
|
|
||||||
|
def get_remote_url():
|
||||||
|
""" Get the git remote URL for the repository """
|
||||||
|
url = subprocess.check_output(["git", "config", "--get", "remote.origin.url"]).decode("utf-8").strip("\n")
|
||||||
|
if url.startswith("git@"):
|
||||||
|
url = url.replace(":", "/", 1).replace("git@", "https://", 1)
|
||||||
|
if url.endswith(".git"):
|
||||||
|
url = url[:-4]
|
||||||
|
return url
|
||||||
|
|
||||||
|
def iscode(word):
|
||||||
|
""" try to guess if the word is code """
|
||||||
|
endings = ['()', '*']
|
||||||
|
starts = ['$', '--']
|
||||||
|
anywhere = ['.', '_', '=', '[', '/']
|
||||||
|
words = ['center', 'false', 'true', 'ngb']
|
||||||
|
|
||||||
|
for w in words:
|
||||||
|
if word == w:
|
||||||
|
return True
|
||||||
|
|
||||||
|
for end in endings:
|
||||||
|
if word.endswith(end):
|
||||||
|
return True
|
||||||
|
|
||||||
|
for start in starts:
|
||||||
|
if word.startswith(start):
|
||||||
|
return True
|
||||||
|
|
||||||
|
for any in anywhere:
|
||||||
|
if word.find(any) >= 0:
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
def codify(word, url):
|
||||||
|
""" if a word is deemed code enclose it backticks """
|
||||||
|
if word:
|
||||||
|
if re.match(r'#[0-9]+', word):
|
||||||
|
return '[%s](%s "show issue")' % (word, url + '/issues/' + word[1:])
|
||||||
|
if iscode(word):
|
||||||
|
return '`' + word + '`'
|
||||||
|
return word
|
||||||
|
|
||||||
|
|
||||||
|
def fixup_comment(comment, url):
|
||||||
|
""" markup code words and fix new paragraphs """
|
||||||
|
result = ''
|
||||||
|
word = ''
|
||||||
|
code = False
|
||||||
|
for i, c in enumerate(comment):
|
||||||
|
if c == '`' or code: # Already a code block
|
||||||
|
result += c # Copy verbatim
|
||||||
|
if c == '`': code = not code # Keep track of state
|
||||||
|
else:
|
||||||
|
if c in ' \n' or (c == '.' and (i + 1 == len(comment) or comment[i + 1] in ' \n')): # if a word terminator
|
||||||
|
result += codify(word, url) + c # Add codified word before terminator
|
||||||
|
word = ''
|
||||||
|
else:
|
||||||
|
word += c # Accumulate next word
|
||||||
|
result += codify(word, url) # In case comment ends without a terminator
|
||||||
|
return result.replace('\n\n','\n\n * ') # Give new paragraphs a bullet point
|
||||||
|
|
||||||
|
class Commit(): # members dynamically added from commit_fields
|
||||||
|
pass
|
||||||
|
|
||||||
|
blurb = """
|
||||||
|
# %s Changelog
|
||||||
|
This changelog is generated by `changelog.py` using manually added semantic version tags to classify commits as breaking changes, additions or fixes.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
url = get_remote_url()
|
||||||
|
|
||||||
|
commit_fields = {
|
||||||
|
'hash': "%H|", # commit commit_hash
|
||||||
|
'tag': "%D|", # tag
|
||||||
|
'author': "%aN|", # author name
|
||||||
|
'date': " %as|", # author date short form
|
||||||
|
'comment': "%B~" # body
|
||||||
|
}
|
||||||
|
|
||||||
|
# Produce the git log
|
||||||
|
format = ''.join([v for k, v in commit_fields.items()])
|
||||||
|
text = subprocess.check_output(["git", "log", "--topo-order", "--format=" + format]).decode("utf-8")
|
||||||
|
|
||||||
|
# Process the log into a list of Commit objects
|
||||||
|
commits = []
|
||||||
|
for line in text.split('~'):
|
||||||
|
line = line.strip('\n')
|
||||||
|
if line:
|
||||||
|
fields = line.split('|')
|
||||||
|
commit = Commit()
|
||||||
|
for i, k in enumerate(commit_fields):
|
||||||
|
exec('commit.%s = """%s"""' % (k, fields[i]), locals())
|
||||||
|
# Convert version tag to tuple
|
||||||
|
if commit.tag:
|
||||||
|
match = re.match(r'.*tag: v([0-9]+)\.([0-9]+)\.([0-9]+).*', commit.tag)
|
||||||
|
commit.tag = (int(match.group(1)), int(match.group(2)), int(match.group(3))) if match else ''
|
||||||
|
commits.append(commit)
|
||||||
|
|
||||||
|
# Format the results from the Commit objects
|
||||||
|
with open(filename, "wt") as file:
|
||||||
|
print(blurb % url.split('/')[-1], file = file)
|
||||||
|
for i, c in enumerate(commits):
|
||||||
|
if c.tag:
|
||||||
|
ver = tag_version(c.tag)
|
||||||
|
level, type = (3, 'Fixes') if c.tag[2] else (2, 'Additions') if c.tag[1] else (1, 'Breaking Changes') if c.tag[0] else (1, 'First publicised version')
|
||||||
|
|
||||||
|
# Find the previous tagged commit
|
||||||
|
j = i + 1
|
||||||
|
diff = ''
|
||||||
|
while j < len(commits):
|
||||||
|
if commits[j].tag:
|
||||||
|
last_ver = tag_version(commits[j].tag)
|
||||||
|
diff = '[...](%s "diff with %s")' % (url + '/compare/' + last_ver + '...' + ver, last_ver)
|
||||||
|
break
|
||||||
|
j += 1
|
||||||
|
|
||||||
|
# Print verson info
|
||||||
|
print('%s [%s](%s "show release") %s %s' % ('#' * (level + 1), ver, url + '/releases/tag/' + ver, type, diff), file = file)
|
||||||
|
|
||||||
|
# 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 changelog.*', 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())
|
@@ -139,10 +139,11 @@ def make_parts(target, part_type, parts = None):
|
|||||||
#
|
#
|
||||||
part_maker_name = tmp_dir + '/' + part_type + ".scad"
|
part_maker_name = tmp_dir + '/' + part_type + ".scad"
|
||||||
with open(part_maker_name, "w") as f:
|
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("use <%s/%s>\n" % (reltmp(dir, target), filename))
|
||||||
f.write("%s();\n" % module);
|
f.write("%s();\n" % module);
|
||||||
t = time.time()
|
t = time.time()
|
||||||
openscad.run("-D$bom=1", "-d", dname, "-o", part_file, part_maker_name)
|
openscad.run("-o", part_file, part_maker_name, "-D$bom=1", "-d", dname)
|
||||||
times.add_time(part, t)
|
times.add_time(part, t)
|
||||||
if part_type == 'stl':
|
if part_type == 'stl':
|
||||||
bounds = c14n_stl.canonicalise(part_file)
|
bounds = c14n_stl.canonicalise(part_file)
|
||||||
|
@@ -25,7 +25,7 @@ from __future__ import print_function
|
|||||||
import subprocess, sys
|
import subprocess, sys
|
||||||
|
|
||||||
def run_list(args, silent = False, verbose = False):
|
def run_list(args, silent = False, verbose = False):
|
||||||
cmd = ["openscad", "--hardwarnings"] + args
|
cmd = ["openscad"] + args + ["--hardwarnings"]
|
||||||
if not silent:
|
if not silent:
|
||||||
for arg in cmd:
|
for arg in cmd:
|
||||||
print(arg, end=" ")
|
print(arg, end=" ")
|
||||||
|
@@ -17,7 +17,7 @@
|
|||||||
# If not, see <https://www.gnu.org/licenses/>.
|
# If not, see <https://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
|
|
||||||
# Set command line options from enviroment variables and check if they have changed
|
# Set command line options from environment variables and check if they have changed
|
||||||
|
|
||||||
import json, os, deps
|
import json, os, deps
|
||||||
from colorama import Fore, init
|
from colorama import Fore, init
|
||||||
|
@@ -44,18 +44,22 @@ def plateup(target, part_type, usage = None):
|
|||||||
source_dir1 = source_dirs[part_type]
|
source_dir1 = source_dirs[part_type]
|
||||||
source_dir2 = top_dir + source_dirs[part_type]
|
source_dir2 = top_dir + source_dirs[part_type]
|
||||||
|
|
||||||
times.read_times(target_dir)
|
|
||||||
#
|
#
|
||||||
# Loop through source directories
|
# Loop through source directories
|
||||||
#
|
#
|
||||||
all_used = []
|
all_used = []
|
||||||
all_sources = []
|
all_sources = []
|
||||||
all_parts = []
|
all_parts = []
|
||||||
|
read_times = False
|
||||||
for dir in [source_dir1, source_dir2]:
|
for dir in [source_dir1, source_dir2]:
|
||||||
if not os.path.isdir(dir):
|
if not os.path.isdir(dir):
|
||||||
continue
|
continue
|
||||||
if not os.path.isdir(target_dir):
|
if not os.path.isdir(target_dir):
|
||||||
os.makedirs(target_dir)
|
os.makedirs(target_dir)
|
||||||
|
|
||||||
|
if not read_times:
|
||||||
|
times.read_times(target_dir)
|
||||||
|
read_times = True
|
||||||
#
|
#
|
||||||
# Make the deps dir
|
# Make the deps dir
|
||||||
#
|
#
|
||||||
@@ -140,4 +144,4 @@ def plateup(target, part_type, usage = None):
|
|||||||
print("Removing %s" % file)
|
print("Removing %s" % file)
|
||||||
os.remove(deps_dir + '/' + file)
|
os.remove(deps_dir + '/' + file)
|
||||||
|
|
||||||
times.print_times(all_parts)
|
times.print_times(all_parts)
|
||||||
|
@@ -8,6 +8,7 @@ They should work with both Python 2 and Python 3.
|
|||||||
|:---|:---|
|
|:---|:---|
|
||||||
| `bom.py` | Generates BOM files for the project. |
|
| `bom.py` | Generates BOM files for the project. |
|
||||||
| `c14n_stl.py` | OpenSCAD produces randomly ordered STL files. This script re-orders them consistently so that GIT can tell if they have changed or not. |
|
| `c14n_stl.py` | OpenSCAD produces randomly ordered STL files. This script re-orders them consistently so that GIT can tell if they have changed or not. |
|
||||||
|
| `changelog.py` | Creates the changelog from the git log |
|
||||||
| `doc_scripts.py` | Makes this document and doc/usage.md. |
|
| `doc_scripts.py` | Makes this document and doc/usage.md. |
|
||||||
| `dxfs.py` | Generates DXF files for all the routed parts listed on the BOM or a specified list. |
|
| `dxfs.py` | Generates DXF files for all the routed parts listed on the BOM or a specified list. |
|
||||||
| `gallery.py` | Finds projects and adds them to the gallery. |
|
| `gallery.py` | Finds projects and adds them to the gallery. |
|
||||||
|
@@ -94,11 +94,13 @@ def render(target, type):
|
|||||||
cam = "--camera=0,0,0,70,0,315,500" if type == 'stl' else "--camera=0,0,0,0,0,0,500"
|
cam = "--camera=0,0,0,70,0,315,500" if type == 'stl' else "--camera=0,0,0,0,0,0,500"
|
||||||
render = "--preview" if type == 'stl' or colour != pp1 else "--render"
|
render = "--preview" if type == 'stl' or colour != pp1 else "--render"
|
||||||
tmp_name = tmp_dir + '/' + part[:-4] + '.png'
|
tmp_name = tmp_dir + '/' + part[:-4] + '.png'
|
||||||
openscad.run(colour_scheme, "--projection=p", "--imgsize=4096,4096", cam, render, "--autocenter", "--viewall", "-o", tmp_name, png_maker_name);
|
dummy_deps_name = tmp_dir + '/tmp.deps' # work around for OpenSCAD issue #3879
|
||||||
|
openscad.run("-o", tmp_name, png_maker_name, colour_scheme, "--projection=p", "--imgsize=4096,4096", cam, render, "--autocenter", "--viewall", "-d", dummy_deps_name)
|
||||||
do_cmd(("magick "+ tmp_name + " -trim -resize 280x280 -background %s -gravity Center -extent 280x280 -bordercolor %s -border 10 %s"
|
do_cmd(("magick "+ tmp_name + " -trim -resize 280x280 -background %s -gravity Center -extent 280x280 -bordercolor %s -border 10 %s"
|
||||||
% (background, background, tmp_name)).split())
|
% (background, background, tmp_name)).split())
|
||||||
update_image(tmp_name, png_name)
|
update_image(tmp_name, png_name)
|
||||||
os.remove(png_maker_name)
|
os.remove(png_maker_name)
|
||||||
|
os.remove(dummy_deps_name)
|
||||||
#
|
#
|
||||||
# Remove tmp dir
|
# Remove tmp dir
|
||||||
#
|
#
|
||||||
|
@@ -60,7 +60,8 @@ def compare_images(a, b, c):
|
|||||||
with open(log_name, 'w') as output:
|
with open(log_name, 'w') as output:
|
||||||
do_cmd(("magick compare -metric AE -fuzz %d%% %s %s %s" % (fuzz, a, b, c)).split(), output = output)
|
do_cmd(("magick compare -metric AE -fuzz %d%% %s %s %s" % (fuzz, a, b, c)).split(), output = output)
|
||||||
with open(log_name, 'r') as f:
|
with open(log_name, 'r') as f:
|
||||||
pixels = int(float(f.read().strip()))
|
pixels = f.read().strip()
|
||||||
|
pixels = int(float(pixels if pixels.isnumeric() else -1))
|
||||||
os.remove(log_name)
|
os.remove(log_name)
|
||||||
return pixels
|
return pixels
|
||||||
|
|
||||||
@@ -71,6 +72,8 @@ def update_image(tmp_name, png_name):
|
|||||||
if pixels < 0 or pixels > threshold:
|
if pixels < 0 or pixels > threshold:
|
||||||
shutil.copyfile(tmp_name, png_name)
|
shutil.copyfile(tmp_name, png_name)
|
||||||
print(Fore.YELLOW + png_name + " updated" + Fore.WHITE, pixels if pixels > 0 else '')
|
print(Fore.YELLOW + png_name + " updated" + Fore.WHITE, pixels if pixels > 0 else '')
|
||||||
|
if png_name.endswith('_tn.png'):
|
||||||
|
os.remove(diff_name)
|
||||||
else:
|
else:
|
||||||
os.utime(png_name, None)
|
os.utime(png_name, None)
|
||||||
os.remove(diff_name)
|
os.remove(diff_name)
|
||||||
@@ -116,7 +119,7 @@ def tests(tests):
|
|||||||
libtest = True
|
libtest = True
|
||||||
lib_blurb = scrape_blurb(scad_name)
|
lib_blurb = scrape_blurb(scad_name)
|
||||||
if not os.path.isfile(png_name):
|
if not os.path.isfile(png_name):
|
||||||
openscad.run(colour_scheme, "--projection=p", "--imgsize=%d,%d" % (w, h), "--camera=0,0,0,50,0,340,500", "--autocenter", "--viewall", "-o", png_name, scad_name);
|
openscad.run(scad_name, "-o", png_name, colour_scheme, "--projection=p", "--imgsize=%d,%d" % (w, h), "--camera=0,0,0,50,0,340,500", "--autocenter", "--viewall");
|
||||||
do_cmd(["magick", png_name, "-trim", "-resize", "1280", "-bordercolor", background, "-border", "10", png_name])
|
do_cmd(["magick", png_name, "-trim", "-resize", "1280", "-bordercolor", background, "-border", "10", png_name])
|
||||||
else:
|
else:
|
||||||
#
|
#
|
||||||
@@ -172,7 +175,7 @@ def tests(tests):
|
|||||||
impl_name = None
|
impl_name = None
|
||||||
|
|
||||||
if libtest:
|
if libtest:
|
||||||
vsplit = "AJR" + chr(ord('Z') + 1)
|
vsplit = "AIR" + chr(ord('Z') + 1)
|
||||||
vtype = locations[0][1]
|
vtype = locations[0][1]
|
||||||
types = [vtype + ' ' + vsplit[i] + '-' + chr(ord(vsplit[i + 1]) - 1) for i in range(len(vsplit) - 1)] + [loc[1] for loc in locations[1 :]]
|
types = [vtype + ' ' + vsplit[i] + '-' + chr(ord(vsplit[i + 1]) - 1) for i in range(len(vsplit) - 1)] + [loc[1] for loc in locations[1 :]]
|
||||||
if type == vtype:
|
if type == vtype:
|
||||||
@@ -237,7 +240,7 @@ def tests(tests):
|
|||||||
print(changed)
|
print(changed)
|
||||||
t = time.time()
|
t = time.time()
|
||||||
tmp_name = tmp_dir + '/tmp.png'
|
tmp_name = tmp_dir + '/tmp.png'
|
||||||
openscad.run_list(options.list() + ["-D$bom=2", colour_scheme, "--projection=p", "--imgsize=%d,%d" % (w, h), "--camera=0,0,0,70,0,315,500", "--autocenter", "--viewall", "-d", dname, "-o", tmp_name, scad_name]);
|
openscad.run_list([scad_name, "-o", tmp_name] + options.list() + ["-D$bom=2", colour_scheme, "--projection=p", "--imgsize=%d,%d" % (w, h), "--camera=0,0,0,70,0,315,500", "--autocenter", "--viewall", "-d", dname]);
|
||||||
times.add_time(scad_name, t)
|
times.add_time(scad_name, t)
|
||||||
do_cmd(["magick", tmp_name, "-trim", "-resize", "1000x600", "-bordercolor", background, "-border", "10", tmp_name])
|
do_cmd(["magick", tmp_name, "-trim", "-resize", "1000x600", "-bordercolor", background, "-border", "10", tmp_name])
|
||||||
update_image(tmp_name, png_name)
|
update_image(tmp_name, png_name)
|
||||||
|
@@ -25,6 +25,7 @@ import time
|
|||||||
def mktmpdir(top_dir):
|
def mktmpdir(top_dir):
|
||||||
tmp_dir = top_dir + 'tmp'
|
tmp_dir = top_dir + 'tmp'
|
||||||
if not os.path.isdir(tmp_dir):
|
if not os.path.isdir(tmp_dir):
|
||||||
|
time.sleep(0.1)
|
||||||
os.makedirs(tmp_dir)
|
os.makedirs(tmp_dir)
|
||||||
else:
|
else:
|
||||||
for file in os.listdir(tmp_dir):
|
for file in os.listdir(tmp_dir):
|
||||||
|
@@ -77,12 +77,12 @@ def bom_to_assemblies(bom_dir, bounds_map):
|
|||||||
#
|
#
|
||||||
if flat_bom:
|
if flat_bom:
|
||||||
ass = flat_bom[-1]
|
ass = flat_bom[-1]
|
||||||
if len(ass["assemblies"]) < 2 and not ass["vitamins"] and not ass["printed"] and not ass["routed"]:
|
if len(ass["assemblies"]) == 1 and not ass["vitamins"] and not ass["printed"] and not ass["routed"]:
|
||||||
flat_bom = flat_bom[:-1]
|
flat_bom = flat_bom[:-1]
|
||||||
return [assembly["name"] for assembly in flat_bom]
|
return [assembly["name"] for assembly in flat_bom]
|
||||||
|
|
||||||
def eop(doc_file, last = False, first = False):
|
def eop(doc_file, last = False, first = False):
|
||||||
print('<span></span>', file = doc_file) # An invisable marker for page breaks because markdown takes much longer if the document contains a div
|
print('<span></span>', file = doc_file) # An invisible marker for page breaks because markdown takes much longer if the document contains a div
|
||||||
if not first:
|
if not first:
|
||||||
print('[Top](#TOP)', file = doc_file)
|
print('[Top](#TOP)', file = doc_file)
|
||||||
if not last:
|
if not last:
|
||||||
@@ -161,6 +161,7 @@ def views(target, do_assemblies = None):
|
|||||||
# Find all the scad files
|
# Find all the scad files
|
||||||
#
|
#
|
||||||
main_blurb = None
|
main_blurb = None
|
||||||
|
main_assembly, main_file = bom.main_assembly(target)
|
||||||
pngs = []
|
pngs = []
|
||||||
for dir in source_dirs(bom_dir):
|
for dir in source_dirs(bom_dir):
|
||||||
if os.path.isdir(dir):
|
if os.path.isdir(dir):
|
||||||
@@ -185,6 +186,7 @@ def views(target, do_assemblies = None):
|
|||||||
#
|
#
|
||||||
for ass in flat_bom:
|
for ass in flat_bom:
|
||||||
if ass["name"] == real_name:
|
if ass["name"] == real_name:
|
||||||
|
zoomed = ass['zoomed']
|
||||||
if not "blurb" in ass:
|
if not "blurb" in ass:
|
||||||
ass["blurb"] = blurb.scrape_module_blurb(lines[:line_no])
|
ass["blurb"] = blurb.scrape_module_blurb(lines[:line_no])
|
||||||
break
|
break
|
||||||
@@ -214,12 +216,14 @@ def views(target, do_assemblies = None):
|
|||||||
#
|
#
|
||||||
png_maker_name = tmp_dir + '/png.scad'
|
png_maker_name = tmp_dir + '/png.scad'
|
||||||
with open(png_maker_name, "w") as f:
|
with open(png_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("use <%s/%s>\n" % (reltmp(dir, target), filename))
|
||||||
f.write("%s();\n" % module);
|
f.write("%s();\n" % module);
|
||||||
t = time.time()
|
t = time.time()
|
||||||
target_def = ['-D$target="%s"' % target] if target else []
|
target_def = ['-D$target="%s"' % target] if target else []
|
||||||
cwd_def = ['-D$cwd="%s"' % os.getcwd().replace('\\', '/')]
|
cwd_def = ['-D$cwd="%s"' % os.getcwd().replace('\\', '/')]
|
||||||
openscad.run_list(options.list() + target_def + cwd_def + ["-D$pose=1", "-D$explode=%d" % explode, colour_scheme, "--projection=p", "--imgsize=4096,4096", "--autocenter", "--viewall", "-d", dname, "-o", tmp_name, png_maker_name]);
|
view_def = ['--viewall', '--autocenter'] if not (zoomed & (1 << explode)) else ['--camera=0,0,0,55,0,25,140']
|
||||||
|
openscad.run_list(["-o", tmp_name, png_maker_name] + options.list() + target_def + cwd_def + view_def + ["-D$pose=1", "-D$explode=%d" % explode, colour_scheme, "--projection=p", "--imgsize=4096,4096", "-d", dname]);
|
||||||
times.add_time(png_name, t)
|
times.add_time(png_name, t)
|
||||||
do_cmd(["magick", tmp_name, "-trim", "-resize", "1004x1004", "-bordercolor", background, "-border", "10", tmp_name])
|
do_cmd(["magick", tmp_name, "-trim", "-resize", "1004x1004", "-bordercolor", background, "-border", "10", tmp_name])
|
||||||
update_image(tmp_name, png_name)
|
update_image(tmp_name, png_name)
|
||||||
@@ -230,7 +234,7 @@ def views(target, do_assemblies = None):
|
|||||||
update_image(tmp_name, tn_name)
|
update_image(tmp_name, tn_name)
|
||||||
done_assemblies.append(real_name)
|
done_assemblies.append(real_name)
|
||||||
else:
|
else:
|
||||||
if module == 'main_assembly':
|
if module == main_assembly:
|
||||||
main_blurb = blurb.scrape_module_blurb(lines[:line_no])
|
main_blurb = blurb.scrape_module_blurb(lines[:line_no])
|
||||||
line_no += 1
|
line_no += 1
|
||||||
#
|
#
|
||||||
@@ -244,9 +248,6 @@ def views(target, do_assemblies = None):
|
|||||||
project = ' '.join(word[0].upper() + word[1:] for word in os.path.basename(os.getcwd()).split('_'))
|
project = ' '.join(word[0].upper() + word[1:] for word in os.path.basename(os.getcwd()).split('_'))
|
||||||
print('<a name="TOP"></a>', file = doc_file)
|
print('<a name="TOP"></a>', file = doc_file)
|
||||||
print('# %s' % project, file = doc_file)
|
print('# %s' % project, file = doc_file)
|
||||||
main_file = bom.find_scad_file('main_assembly')
|
|
||||||
if not main_file:
|
|
||||||
raise Exception("can't find source for main_assembly")
|
|
||||||
text = blurb.scrape_blurb(source_dir + '/' + main_file)
|
text = blurb.scrape_blurb(source_dir + '/' + main_file)
|
||||||
blurbs = blurb.split_blurb(text)
|
blurbs = blurb.split_blurb(text)
|
||||||
if len(text):
|
if len(text):
|
||||||
|
29
tests/7_segments.scad
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
//
|
||||||
|
// NopSCADlib Copyright Chris Palmer 2021
|
||||||
|
// 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 <../utils/layout.scad>
|
||||||
|
|
||||||
|
include <../vitamins/7_segments.scad>
|
||||||
|
|
||||||
|
module 7_segments()
|
||||||
|
layout([for(s = 7_segments) 7_segment_size(s).x * 2], 5) let(s = 7_segments[$i])
|
||||||
|
7_segment_digits(s, 2);
|
||||||
|
|
||||||
|
if($preview)
|
||||||
|
7_segments();
|
31
tests/BLDC_motors.scad
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
//
|
||||||
|
// NopSCADlib Copyright Chris Palmer 2021
|
||||||
|
// 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 <../utils/layout.scad>
|
||||||
|
|
||||||
|
include <../vitamins/bldc_motors.scad>
|
||||||
|
|
||||||
|
module bldc_motors()
|
||||||
|
layout([for(b = bldc_motors) BLDC_diameter(b)])
|
||||||
|
rotate(-90)
|
||||||
|
BLDC(bldc_motors[$i]);
|
||||||
|
|
||||||
|
if($preview)
|
||||||
|
let($show_threads = 1)
|
||||||
|
bldc_motors();
|
@@ -20,10 +20,10 @@
|
|||||||
//
|
//
|
||||||
//! BOM and assembly demonstration
|
//! BOM and assembly demonstration
|
||||||
//
|
//
|
||||||
|
$explode = 1; // Normally set on the command line when generating assembly views with views.py
|
||||||
include <../core.scad>
|
include <../core.scad>
|
||||||
include <../vitamins/sheets.scad>
|
include <../vitamins/sheets.scad>
|
||||||
use <../vitamins/insert.scad>
|
use <../vitamins/insert.scad>
|
||||||
$explode = 1; // Normally set on the command line when generating assembly views with views.py
|
|
||||||
|
|
||||||
screw = M3_cap_screw;
|
screw = M3_cap_screw;
|
||||||
sheet = PMMA3;
|
sheet = PMMA3;
|
||||||
|
@@ -16,6 +16,7 @@
|
|||||||
// You should have received a copy of the GNU General Public License along with NopSCADlib.
|
// You should have received a copy of the GNU General Public License along with NopSCADlib.
|
||||||
// If not, see <https://www.gnu.org/licenses/>.
|
// If not, see <https://www.gnu.org/licenses/>.
|
||||||
//
|
//
|
||||||
|
include <../core.scad>
|
||||||
include <../vitamins/ldrs.scad>
|
include <../vitamins/ldrs.scad>
|
||||||
|
|
||||||
use <../utils/layout.scad>
|
use <../utils/layout.scad>
|
||||||
|
@@ -22,6 +22,8 @@ include <../vitamins/d_connectors.scad>
|
|||||||
include <../vitamins/leds.scad>
|
include <../vitamins/leds.scad>
|
||||||
include <../vitamins/axials.scad>
|
include <../vitamins/axials.scad>
|
||||||
include <../vitamins/smds.scad>
|
include <../vitamins/smds.scad>
|
||||||
|
include <../vitamins/7_segments.scad>
|
||||||
|
include <../vitamins/potentiometers.scad>
|
||||||
|
|
||||||
use <../vitamins/pcb.scad>
|
use <../vitamins/pcb.scad>
|
||||||
|
|
||||||
@@ -46,7 +48,7 @@ TMC2130 = ["TMC2130", "TMC2130",
|
|||||||
[]
|
[]
|
||||||
];
|
];
|
||||||
|
|
||||||
test_pcb = ["TestPCB", "Test PCB",
|
test_pcb = ["test_pcb", "Test PCB",
|
||||||
100, 250, 1.6, // length, width, thickness
|
100, 250, 1.6, // length, width, thickness
|
||||||
3, // Corner radius
|
3, // Corner radius
|
||||||
2.75, // Mounting hole diameter
|
2.75, // Mounting hole diameter
|
||||||
@@ -64,21 +66,25 @@ test_pcb = ["TestPCB", "Test PCB",
|
|||||||
[ 16, 2, 90, "smd_res", RES1206, "1K"],
|
[ 16, 2, 90, "smd_res", RES1206, "1K"],
|
||||||
[ 19, 2, 90, "smd_res", RES0805, "1K"],
|
[ 19, 2, 90, "smd_res", RES0805, "1K"],
|
||||||
[ 22, 2, 90, "smd_res", RES0603, "1K"],
|
[ 22, 2, 90, "smd_res", RES0603, "1K"],
|
||||||
|
[ 25, 2, 90, "smd_cap", CAP1206, 1.5],
|
||||||
|
[ 28, 2, 90, "smd_cap", CAP0805, 1.0],
|
||||||
|
[ 31, 2, 90, "smd_cap", CAP0603, 0.7],
|
||||||
|
|
||||||
[ 10, 10, 0, "2p54header", 4, 1],
|
[ 10, 10, 0, "2p54header", 4, 1],
|
||||||
[ 25, 10, 0, "2p54header", 5, 1, false, "blue" ],
|
[ 25, 10, 0, "2p54header", 5, 1, false, "blue" ],
|
||||||
[ 10, 20, 0, "2p54boxhdr", 4, 2],
|
[ 10, 20, 0, "2p54boxhdr", 4, 2],
|
||||||
[ 10, 30, 0, "2p54socket", 6, 1],
|
[ 10, 30, 0, "2p54socket", 6, 1],
|
||||||
[ 25, 30, 0, "2p54socket", 4, 1, false, 0, false, "red" ],
|
[ 25, 30, 0, "2p54socket", 4, 1, false, 0, false, "red" ],
|
||||||
[ 10, 40, 0, "chip", 10, 5, 1, grey(20)],
|
[ 65, 50, 0, "led", LED3mm, "red"],
|
||||||
[ 5, 50, 0, "led", LED3mm, "red"],
|
[ 75, 50, 0, "led", LED5mm, "orange"],
|
||||||
[ 12, 50, 0, "led", LED5mm, "orange"],
|
[ 90, 50, 0, "led", LED10mm, "yellow"],
|
||||||
[ 25, 50, 0, "led", LED10mm, "yellow"],
|
[ 10, 45, 180, "rj45"],
|
||||||
[ 10, 65, 180, "rj45"],
|
[ 8, 65, 180, "usb_A"],
|
||||||
[ 8, 85, 180, "usb_A"],
|
|
||||||
[ 8, 105, 180, "usb_Ax2"],
|
[ 8, 105, 180, "usb_Ax2"],
|
||||||
|
[ 7, 85, 180, "molex_usb_Ax1"],
|
||||||
|
[ 8.5,125, 180, "molex_usb_Ax2"],
|
||||||
[ 3, 140, 180, "usb_uA"],
|
[ 3, 140, 180, "usb_uA"],
|
||||||
[ 8, 155, 180, "usb_B"],
|
[ 8, 155, 180, "usb_B"],
|
||||||
[ 8.5, 125, 180, "molex_usb_Ax2"],
|
|
||||||
[ 25, 200, 0, "buzzer", 4.5, 8.5],
|
[ 25, 200, 0, "buzzer", 4.5, 8.5],
|
||||||
[ 25, 218, 0, "buzzer"],
|
[ 25, 218, 0, "buzzer"],
|
||||||
[ 8, 190, 180, "jack"],
|
[ 8, 190, 180, "jack"],
|
||||||
@@ -91,6 +97,8 @@ test_pcb = ["TestPCB", "Test PCB",
|
|||||||
[ 65, 12, 0, "ax_res", res1_8, 1000],
|
[ 65, 12, 0, "ax_res", res1_8, 1000],
|
||||||
[ 65, 17, 0, "ax_res", res1_4, 10000],
|
[ 65, 17, 0, "ax_res", res1_4, 10000],
|
||||||
[ 65, 22, 0, "ax_res", res1_2, 100000],
|
[ 65, 22, 0, "ax_res", res1_2, 100000],
|
||||||
|
[ 55, 22, 0, "vero_pin"],
|
||||||
|
[ 55, 17, 0, "vero_pin", true],
|
||||||
|
|
||||||
[ 80, 9, 0, "link", inch(0.2), inch(0.4)],
|
[ 80, 9, 0, "link", inch(0.2), inch(0.4)],
|
||||||
[ 80, 12, 0, "ax_res", res1_8, 1000000, 1, inch(0.1)],
|
[ 80, 12, 0, "ax_res", res1_8, 1000000, 1, inch(0.1)],
|
||||||
@@ -127,11 +135,14 @@ test_pcb = ["TestPCB", "Test PCB",
|
|||||||
[ 52, 200, 0, "pcb", 11, TMC2130 ],
|
[ 52, 200, 0, "pcb", 11, TMC2130 ],
|
||||||
[ 80, 200, 0, "pdip", 24, "27C32", true, inch(0.6) ],
|
[ 80, 200, 0, "pdip", 24, "27C32", true, inch(0.6) ],
|
||||||
[ 80, 170, 0, "pdip", 8, "NE555" ],
|
[ 80, 170, 0, "pdip", 8, "NE555" ],
|
||||||
|
[ 80, 150, 0, "chip", 10, 5, 1, grey(20)],
|
||||||
|
|
||||||
[ 52, 206, 0, "2p54socket", 8, 1 ],
|
[ 52, 206, 0, "2p54socket", 8, 1 ],
|
||||||
[ 52, 194, 0, "2p54socket", 8, 1, false, 0, false, "red" ],
|
[ 52, 194, 0, "2p54socket", 8, 1, false, 0, false, "red" ],
|
||||||
[ 50, 220, 0, "standoff", 5, 4.5, 12.5, 2.54],
|
[ 50, 220, 0, "standoff", 5, 4.5, 12.5, 2.54],
|
||||||
[ 50, 240, 0, "potentiometer"],
|
[ 50, 240, 0, "potentiometer"],
|
||||||
[ 75, 240, 0, "potentiometer", 7, 8],
|
[ 75, 240, 0, "potentiometer", KY_040_encoder, 8],
|
||||||
|
[ 30, 85, -90, "7seg", WT5011BSR, 2],
|
||||||
],
|
],
|
||||||
// accessories
|
// accessories
|
||||||
[]
|
[]
|
||||||
|
@@ -21,7 +21,7 @@ include <../vitamins/pcbs.scad>
|
|||||||
|
|
||||||
use <../utils/layout.scad>
|
use <../utils/layout.scad>
|
||||||
|
|
||||||
function spacing(p) = let(w = pcb_width(p)) w < 22 ? w + 3 : w + 10;
|
function spacing(p) = let(w = pcb_width(p)) w < 22 ? w + 3 : w + 7;
|
||||||
|
|
||||||
module pcbs() {
|
module pcbs() {
|
||||||
layout([for(p = pcbs) spacing(p)], 0)
|
layout([for(p = pcbs) spacing(p)], 0)
|
||||||
@@ -29,6 +29,11 @@ module pcbs() {
|
|||||||
rotate(90)
|
rotate(90)
|
||||||
pcb_assembly(pcbs[$i], 5 + $i, 3);
|
pcb_assembly(pcbs[$i], 5 + $i, 3);
|
||||||
|
|
||||||
|
translate([0, 65])
|
||||||
|
layout([for(p = tiny_pcbs) pcb_length(p)], 3)
|
||||||
|
translate([0, -pcb_width(tiny_pcbs[$i]) / 2])
|
||||||
|
pcb_assembly(tiny_pcbs[$i], 5 + $i, 3);
|
||||||
|
|
||||||
translate([0, 120])
|
translate([0, 120])
|
||||||
layout([for(p = perfboards) pcb_length(p)], 10)
|
layout([for(p = perfboards) pcb_length(p)], 10)
|
||||||
translate([0, -pcb_width(perfboards[$i]) / 2])
|
translate([0, -pcb_width(perfboards[$i]) / 2])
|
||||||
|
@@ -22,18 +22,20 @@ include <../vitamins/extrusions.scad>
|
|||||||
|
|
||||||
use <../utils/layout.scad>
|
use <../utils/layout.scad>
|
||||||
|
|
||||||
module sk_brackets() {
|
module sk_brackets(examples = false) {
|
||||||
screws = [M4_dome_screw, M4_cap_screw, M5_cap_screw, M5_cap_screw];
|
screws = [M4_dome_screw, M4_cap_screw, M5_cap_screw, M5_cap_screw];
|
||||||
nuts = [M4_hammer_nut, M4_sliding_t_nut, M5_sliding_t_nut, undef];
|
nuts = [M4_hammer_nut, M4_sliding_t_nut, M5_sliding_t_nut, undef];
|
||||||
// channel depth = 6 for 2020 extrusion, 9 for 3030 extrusion
|
// channel depth = 6 for 2020 extrusion, 9 for 3030 extrusion
|
||||||
depths = [6, 6, 9, 0];
|
depths = [6, 6, 9, 0];
|
||||||
layout([for(s = sk_brackets) 1.5 * sk_size(s)[1]]) {
|
layout([for(s = sk_brackets) 1.5 * sk_size(s)[1]]) {
|
||||||
sk_bracket_assembly(sk_brackets[$i], screw_type = screws[$i], nut_type = nuts[$i], max_screw_depth = depths[$i]);
|
sk_bracket_assembly(sk_brackets[$i], screw_type = screws[$i], nut_type = nuts[$i], max_screw_depth = depths[$i]);
|
||||||
translate([0, -sk_hole_offset(sk_brackets[$i]) - extrusion_width($i < 2 ? E2020 : E3030) / 2, 0])
|
|
||||||
rotate([0, 90, 0])
|
if(examples)
|
||||||
extrusion($i < 2 ? E2020 : E3030, 20, false);
|
translate([0, -sk_hole_offset(sk_brackets[$i]) - extrusion_width($i < 2 ? E2020 : E3030) / 2, 0])
|
||||||
|
rotate([0, 90, 0])
|
||||||
|
extrusion($i < 2 ? E2020 : E3030, 20, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if($preview)
|
if($preview)
|
||||||
sk_brackets();
|
sk_brackets(true);
|
||||||
|
@@ -28,6 +28,11 @@ module smds() {
|
|||||||
translate([0, 3])
|
translate([0, 3])
|
||||||
layout([for(l = smd_leds) smd_led_size(l).x], 1)
|
layout([for(l = smd_leds) smd_led_size(l).x], 1)
|
||||||
smd_led(smd_leds[$i], ["green", "blue", "red"][$i % 3]);
|
smd_led(smd_leds[$i], ["green", "blue", "red"][$i % 3]);
|
||||||
|
|
||||||
|
translate([0, 6])
|
||||||
|
layout([for(c = smd_capacitors) smd_cap_size(c).x], 1)
|
||||||
|
let(c = smd_capacitors[$i])
|
||||||
|
smd_capacitor(c, smd_cap_size(c).y * 0.8);
|
||||||
}
|
}
|
||||||
|
|
||||||
if($preview)
|
if($preview)
|
||||||
|
@@ -16,7 +16,7 @@
|
|||||||
// You should have received a copy of the GNU General Public License along with NopSCADlib.
|
// You should have received a copy of the GNU General Public License along with NopSCADlib.
|
||||||
// If not, see <https://www.gnu.org/licenses/>.
|
// If not, see <https://www.gnu.org/licenses/>.
|
||||||
//
|
//
|
||||||
|
include <../core.scad>
|
||||||
use <../utils/layout.scad>
|
use <../utils/layout.scad>
|
||||||
|
|
||||||
include <../vitamins/ball_bearings.scad>
|
include <../vitamins/ball_bearings.scad>
|
||||||
|
@@ -17,7 +17,7 @@
|
|||||||
// If not, see <https://www.gnu.org/licenses/>.
|
// If not, see <https://www.gnu.org/licenses/>.
|
||||||
//
|
//
|
||||||
include <../core.scad>
|
include <../core.scad>
|
||||||
include <../vitamins/scs_bearing_blocks.scad>
|
include <../vitamins/bearing_blocks.scad>
|
||||||
|
|
||||||
use <../utils/layout.scad>
|
use <../utils/layout.scad>
|
||||||
|
|
@@ -25,9 +25,9 @@ use <../utils/layout.scad>
|
|||||||
module belt_test() {
|
module belt_test() {
|
||||||
p2 = [-75, -50];
|
p2 = [-75, -50];
|
||||||
p3 = [-75, 100];
|
p3 = [-75, 100];
|
||||||
p4 = [75, 100];
|
p4 = [ 75, 100];
|
||||||
|
|
||||||
p5 = [75 + pulley_pr(GT2x20ob_pulley) - pulley_pr(GT2x16_plain_idler), +pulley_pr(GT2x16_plain_idler)];
|
p5 = [ 75 + pulley_pr(GT2x20ob_pulley) - pulley_pr(GT2x16_plain_idler), +pulley_pr(GT2x16_plain_idler)];
|
||||||
p6 = [-75 + pulley_pr(GT2x20ob_pulley) + pulley_pr(GT2x16_plain_idler), -pulley_pr(GT2x16_plain_idler)];
|
p6 = [-75 + pulley_pr(GT2x20ob_pulley) + pulley_pr(GT2x16_plain_idler), -pulley_pr(GT2x16_plain_idler)];
|
||||||
|
|
||||||
module pulleys(flip = false) {
|
module pulleys(flip = false) {
|
||||||
@@ -52,19 +52,21 @@ module belt_test() {
|
|||||||
translate(p6) pulley_assembly(GT2x16_plain_idler);
|
translate(p6) pulley_assembly(GT2x16_plain_idler);
|
||||||
}
|
}
|
||||||
|
|
||||||
path = [ [p5.x, p5.y, pulley_pr(GT2x16_plain_idler)],
|
path = [ [-40, 0, 0],
|
||||||
[p6.x, p6.y, -pulley_pr(GT2x16_plain_idler)],
|
[p6.x, p6.y, -pulley_pr(GT2x16_plain_idler)],
|
||||||
[p2.x, p2.y, pulley_pr(GT2x20ob_pulley)],
|
[p2.x, p2.y, pulley_pr(GT2x20ob_pulley)],
|
||||||
[p3.x, p3.y, pulley_pr(GT2x20ob_pulley)],
|
[p3.x, p3.y, pulley_pr(GT2x20ob_pulley)],
|
||||||
[p4.x, p4.y, pulley_pr(GT2x20ob_pulley)]
|
[p4.x, p4.y, pulley_pr(GT2x20ob_pulley)],
|
||||||
|
[p5.x, p5.y, pulley_pr(GT2x16_plain_idler)],
|
||||||
|
[40, 0, 0],
|
||||||
];
|
];
|
||||||
|
|
||||||
belt = GT2x6;
|
belt = GT2x6;
|
||||||
belt(belt, path, 80, [0, 0]);
|
belt(belt, path, open = true);
|
||||||
pulleys();
|
pulleys();
|
||||||
translate_z(20)
|
translate_z(20)
|
||||||
hflip() {
|
hflip() {
|
||||||
belt(belt, path, 80, [0, 0], belt_colour = grey(90), tooth_colour = grey(50));
|
belt(belt, path, open = true, belt_colour = grey(90), tooth_colour = grey(50));
|
||||||
pulleys(flip=true);
|
pulleys(flip=true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,6 +74,31 @@ module belt_test() {
|
|||||||
layout([for(b = belts) belt_width(b)], 10)
|
layout([for(b = belts) belt_width(b)], 10)
|
||||||
rotate([0, 90, 0])
|
rotate([0, 90, 0])
|
||||||
belt(belts[$i], [[0, 0, 20], [0, 1, 20]], belt_colour = $i%2==0 ? grey(90) : grey(20), tooth_colour = $i%2==0 ? grey(70) : grey(50));
|
belt(belts[$i], [[0, 0, 20], [0, 1, 20]], belt_colour = $i%2==0 ? grey(90) : grey(20), tooth_colour = $i%2==0 ? grey(70) : grey(50));
|
||||||
|
|
||||||
|
// new example with open loop - this is a simplified example of the style used for example for the BLV 3D printer
|
||||||
|
pulley = GT2x20ob_pulley;
|
||||||
|
idler = GT2x16_plain_idler;
|
||||||
|
corners = [[-75,-50],[75,100]];
|
||||||
|
carriagepos = [0,0];
|
||||||
|
carriagew = 80;
|
||||||
|
|
||||||
|
points = [
|
||||||
|
[carriagepos.x - carriagew / 2, carriagepos.y, 0],
|
||||||
|
[corners[0].x + belt_pulley_pr(belt, pulley) + belt_pulley_pr(belt, idler), carriagepos.y - belt_pulley_pr(belt, idler), idler],
|
||||||
|
[corners[0].x, corners[0].y, pulley],
|
||||||
|
[corners[0].x, corners[1].y, idler],
|
||||||
|
[corners[1].x, corners[1].y, idler],
|
||||||
|
[corners[1].x, carriagepos.y + belt_pulley_pr(belt, idler), idler],
|
||||||
|
[carriagepos.x + carriagew / 2, carriagepos.y, 0]
|
||||||
|
];
|
||||||
|
translate_z(-30) {
|
||||||
|
belt(belt, points, open=true, auto_twist=true);
|
||||||
|
for (p = points)
|
||||||
|
if (is_list(p.z))
|
||||||
|
translate([p.x, p.y, 0])
|
||||||
|
pulley_assembly(p.z);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if($preview)
|
if($preview)
|
||||||
|
30
tests/box_sections.scad
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
//
|
||||||
|
// NopSCADlib Copyright Chris Palmer 2021
|
||||||
|
// 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>
|
||||||
|
|
||||||
|
include <../vitamins/box_sections.scad>
|
||||||
|
|
||||||
|
module box_sections() {
|
||||||
|
layout([for(b = box_sections) box_section_size(b).x], 20)
|
||||||
|
box_section(box_sections[$i], 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
if($preview)
|
||||||
|
box_sections();
|
134
tests/core_xy.scad
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
//
|
||||||
|
// NopSCADlib Copyright Chris Palmer 2020
|
||||||
|
// nop.head@gmail.com
|
||||||
|
// hydraraptor.blogspot.com
|
||||||
|
//
|
||||||
|
// This file is part of NopSCADlib.
|
||||||
|
//
|
||||||
|
// NopSCADlib is free software: you can redistribute it and/or modify it under the terms of the
|
||||||
|
// GNU General Public License as published by the Free Software Foundation, either version 3 of
|
||||||
|
// the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// NopSCADlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||||
|
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
// See the GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License along with NopSCADlib.
|
||||||
|
// If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
|
||||||
|
include <../core.scad>
|
||||||
|
include <../vitamins/pulleys.scad>
|
||||||
|
include <../vitamins/screws.scad>
|
||||||
|
include <../vitamins/stepper_motors.scad>
|
||||||
|
include <../vitamins/washers.scad>
|
||||||
|
|
||||||
|
include <../utils/core_xy.scad>
|
||||||
|
|
||||||
|
|
||||||
|
module coreXY_belts_test() {
|
||||||
|
coreXY_type = coreXY_GT2_20_16;
|
||||||
|
plain_idler = coreXY_plain_idler(coreXY_type);
|
||||||
|
toothed_idler = coreXY_toothed_idler(coreXY_type);
|
||||||
|
|
||||||
|
coreXYPosBL = [0, 0, 0];
|
||||||
|
coreXYPosTR = [200, 150, 0];
|
||||||
|
separation = [0, coreXY_coincident_separation(coreXY_type).y, pulley_height(plain_idler) + washer_thickness(M3_washer)];
|
||||||
|
pos = [100, 50];
|
||||||
|
|
||||||
|
upper_drive_pulley_offset = [40, 10];
|
||||||
|
lower_drive_pulley_offset = [0, 0];
|
||||||
|
|
||||||
|
coreXY_belts(coreXY_type,
|
||||||
|
carriagePosition = pos,
|
||||||
|
coreXYPosBL = coreXYPosBL,
|
||||||
|
coreXYPosTR = coreXYPosTR,
|
||||||
|
separation = separation,
|
||||||
|
x_gap = 10,
|
||||||
|
upper_drive_pulley_offset = upper_drive_pulley_offset,
|
||||||
|
lower_drive_pulley_offset = lower_drive_pulley_offset,
|
||||||
|
show_pulleys = true);
|
||||||
|
|
||||||
|
|
||||||
|
translate([coreXYPosBL.x + separation.x/2, coreXYPosTR.y + upper_drive_pulley_offset.y, separation.z/2]) {
|
||||||
|
// add the upper drive pulley stepper motor
|
||||||
|
translate([coreXY_drive_pulley_x_alignment(coreXY_type) + upper_drive_pulley_offset.x, 0, -pulley_height(coreXY_drive_pulley(coreXY_type))])
|
||||||
|
NEMA(NEMA17M);
|
||||||
|
|
||||||
|
// add the screws for the upper drive offset idler pulleys if required
|
||||||
|
if (upper_drive_pulley_offset.x > 0) {
|
||||||
|
translate(coreXY_drive_plain_idler_offset(coreXY_type))
|
||||||
|
translate_z(-pulley_offset(plain_idler))
|
||||||
|
screw(M3_cap_screw, 20);
|
||||||
|
translate(coreXY_drive_toothed_idler_offset(coreXY_type))
|
||||||
|
translate_z(-pulley_offset(toothed_idler))
|
||||||
|
screw(M3_cap_screw, 20);
|
||||||
|
} else if (upper_drive_pulley_offset.x < 0) {
|
||||||
|
translate([-pulley_od(plain_idler), coreXY_drive_plain_idler_offset(coreXY_type).y])
|
||||||
|
translate_z(-pulley_offset(plain_idler))
|
||||||
|
screw(M3_cap_screw, 20);
|
||||||
|
translate([2*coreXY_drive_pulley_x_alignment(coreXY_type), coreXY_drive_toothed_idler_offset(coreXY_type).y])
|
||||||
|
translate_z(-pulley_offset(toothed_idler))
|
||||||
|
screw(M3_cap_screw, 20);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
translate([coreXYPosTR.x - separation.x/2, coreXYPosTR.y + lower_drive_pulley_offset.y, -separation.z/2]) {
|
||||||
|
// add the lower drive pulley stepper motor
|
||||||
|
translate([-coreXY_drive_pulley_x_alignment(coreXY_type) + lower_drive_pulley_offset.x, 0, -pulley_height(coreXY_drive_pulley(coreXY_type))])
|
||||||
|
NEMA(NEMA17M);
|
||||||
|
|
||||||
|
// add the screws for the lower drive offset idler pulleys if required
|
||||||
|
if (lower_drive_pulley_offset.x < 0) {
|
||||||
|
translate([-coreXY_drive_plain_idler_offset(coreXY_type).x, coreXY_drive_plain_idler_offset(coreXY_type).y])
|
||||||
|
translate_z(-pulley_offset(plain_idler))
|
||||||
|
screw(M3_cap_screw, 20);
|
||||||
|
translate(coreXY_drive_toothed_idler_offset(coreXY_type))
|
||||||
|
translate_z(-pulley_offset(toothed_idler))
|
||||||
|
screw(M3_cap_screw, 20);
|
||||||
|
} else if (lower_drive_pulley_offset.x > 0) {
|
||||||
|
translate([pulley_od(plain_idler), coreXY_drive_plain_idler_offset(coreXY_type).y])
|
||||||
|
translate_z(-pulley_offset(plain_idler))
|
||||||
|
screw(M3_cap_screw, 20);
|
||||||
|
translate([-2*coreXY_drive_pulley_x_alignment(coreXY_type), coreXY_drive_toothed_idler_offset(coreXY_type).y])
|
||||||
|
translate_z(-pulley_offset(toothed_idler))
|
||||||
|
screw(M3_cap_screw, 20);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// add the screw for the left upper idler pulley
|
||||||
|
translate([coreXYPosBL.x + separation.x/2, coreXYPosBL.y, separation.z])
|
||||||
|
screw(M3_cap_screw, 20);
|
||||||
|
|
||||||
|
// add the screw for the right upper idler pulley
|
||||||
|
translate([coreXYPosTR.x + separation.x/2, coreXYPosBL.y, separation.z])
|
||||||
|
screw(M3_cap_screw, 20);
|
||||||
|
|
||||||
|
if (separation.x != 0) {
|
||||||
|
// add the screw for the left lower idler pulley
|
||||||
|
translate([coreXYPosBL.x - separation.x/2, coreXYPosBL.y, 0])
|
||||||
|
screw(M3_cap_screw, 20);
|
||||||
|
|
||||||
|
// add the screw for the right lower idler pulley
|
||||||
|
translate([coreXYPosTR.x - separation.x/2, coreXYPosBL.y, 0])
|
||||||
|
screw(M3_cap_screw, 20);
|
||||||
|
}
|
||||||
|
|
||||||
|
translate([-separation.x/2, pos.y + coreXYPosBL.y -separation.y/2, -separation.z/2 + pulley_height(plain_idler)/2]) {
|
||||||
|
// add the screw for the left Y carriage toothed idler
|
||||||
|
translate([coreXYPosBL.x, coreXY_toothed_idler_offset(coreXY_type).y, 0])
|
||||||
|
screw(M3_cap_screw, 20);
|
||||||
|
// add the screw for the left Y carriage plain idler
|
||||||
|
translate([coreXYPosBL.x + separation.x + coreXY_plain_idler_offset(coreXY_type).x, separation.y + coreXY_plain_idler_offset(coreXY_type).y, separation.z])
|
||||||
|
screw(M3_cap_screw, 20);
|
||||||
|
// add the screw for the right Y carriage toothed idler
|
||||||
|
translate([coreXYPosTR.x + separation.x, coreXY_toothed_idler_offset(coreXY_type).y, separation.z])
|
||||||
|
screw(M3_cap_screw, 20);
|
||||||
|
// add the screw for the right Y carriage plain idler
|
||||||
|
translate([coreXYPosTR.x - coreXY_plain_idler_offset(coreXY_type).x, separation.y + coreXY_plain_idler_offset(coreXY_type).y, 0])
|
||||||
|
screw(M3_cap_screw, 20);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($preview)
|
||||||
|
coreXY_belts_test();
|
@@ -16,6 +16,7 @@
|
|||||||
// You should have received a copy of the GNU General Public License along with NopSCADlib.
|
// You should have received a copy of the GNU General Public License along with NopSCADlib.
|
||||||
// If not, see <https://www.gnu.org/licenses/>.
|
// If not, see <https://www.gnu.org/licenses/>.
|
||||||
//
|
//
|
||||||
|
include <../core.scad>
|
||||||
use <../utils/layout.scad>
|
use <../utils/layout.scad>
|
||||||
|
|
||||||
include <../vitamins/displays.scad>
|
include <../vitamins/displays.scad>
|
||||||
@@ -23,7 +24,10 @@ use <../vitamins/pcb.scad>
|
|||||||
|
|
||||||
module displays()
|
module displays()
|
||||||
layout([for(d = displays) pcb_length(display_pcb(d))], 10)
|
layout([for(d = displays) pcb_length(display_pcb(d))], 10)
|
||||||
display(displays[$i]);
|
translate([0, pcb_width(displays[$i]) / 2])
|
||||||
|
vflip()
|
||||||
|
display(displays[$i]);
|
||||||
|
|
||||||
if($preview)
|
if($preview)
|
||||||
displays();
|
let($show_threads = true)
|
||||||
|
displays();
|
||||||
|
@@ -16,13 +16,51 @@
|
|||||||
// You should have received a copy of the GNU General Public License along with NopSCADlib.
|
// You should have received a copy of the GNU General Public License along with NopSCADlib.
|
||||||
// If not, see <https://www.gnu.org/licenses/>.
|
// If not, see <https://www.gnu.org/licenses/>.
|
||||||
//
|
//
|
||||||
include <../utils/core/core.scad>
|
include <../core.scad>
|
||||||
|
|
||||||
include <../vitamins/extrusion_brackets.scad>
|
|
||||||
include <../vitamins/extrusions.scad>
|
include <../vitamins/extrusions.scad>
|
||||||
|
include <../vitamins/extrusion_brackets.scad>
|
||||||
include <../vitamins/washers.scad>
|
include <../vitamins/washers.scad>
|
||||||
include <../vitamins/nuts.scad>
|
include <../vitamins/nuts.scad>
|
||||||
|
|
||||||
|
module inner_bracket_test(bracket, backwards = false)
|
||||||
|
rotate([90, 0, 180]) {
|
||||||
|
extrusion = extrusion_inner_corner_bracket_extrusion(bracket);
|
||||||
|
eWidth = extrusion_width(extrusion);
|
||||||
|
size = extrusion_inner_corner_bracket_size(bracket);
|
||||||
|
tnut = extrusion_inner_corner_bracket_tnut(bracket);
|
||||||
|
|
||||||
|
translate([backwards ? -eWidth : 0, 0])
|
||||||
|
extrusion_inner_corner_bracket(bracket, backwards = backwards);
|
||||||
|
|
||||||
|
translate([-eWidth / 2, 0])
|
||||||
|
rotate([-90, 0, 0])
|
||||||
|
extrusion(extrusion, size.x - nut_thickness(tnut) - extrusion_tab_thickness(extrusion), false, cornerHole = eWidth > 20);
|
||||||
|
|
||||||
|
translate([-eWidth, -eWidth / 2])
|
||||||
|
rotate([0, 90, 0])
|
||||||
|
extrusion(extrusion, eWidth + size.y - nut_thickness(tnut) - extrusion_tab_thickness(extrusion), false, cornerHole = eWidth > 20);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
module bracket_test(bracket)
|
||||||
|
rotate([90, 0, 180]) {
|
||||||
|
extrusion = extrusion_corner_bracket_extrusion(bracket);
|
||||||
|
eWidth = extrusion_width(extrusion);
|
||||||
|
size = extrusion_corner_bracket_size(bracket);
|
||||||
|
|
||||||
|
extrusion_corner_bracket_assembly(bracket);
|
||||||
|
|
||||||
|
translate([-eWidth / 2, 0])
|
||||||
|
rotate([-90, 0, 0])
|
||||||
|
extrusion(extrusion, size.y, false, cornerHole = eWidth > 20);
|
||||||
|
|
||||||
|
translate([-eWidth, -eWidth / 2])
|
||||||
|
rotate([0, 90, 0])
|
||||||
|
extrusion(extrusion, eWidth + size.x, false, cornerHole = eWidth > 20);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
module extrusion_brackets(examples = false) {
|
module extrusion_brackets(examples = false) {
|
||||||
extrusion_inner_corner_bracket(E20_inner_corner_bracket);
|
extrusion_inner_corner_bracket(E20_inner_corner_bracket);
|
||||||
|
|
||||||
@@ -32,34 +70,30 @@ module extrusion_brackets(examples = false) {
|
|||||||
translate([60, 0])
|
translate([60, 0])
|
||||||
extrusion_corner_bracket_assembly(E20_corner_bracket);
|
extrusion_corner_bracket_assembly(E20_corner_bracket);
|
||||||
|
|
||||||
eWidth = extrusion_width(E2020);
|
translate([110, 0])
|
||||||
|
extrusion_inner_corner_bracket(E40_inner_corner_bracket);
|
||||||
|
|
||||||
|
translate([140, 0])
|
||||||
|
extrusion_corner_bracket_assembly(E40_corner_bracket);
|
||||||
|
|
||||||
if(examples) {
|
if(examples) {
|
||||||
translate([20, 60, 10]) rotate([90, 0, 180]) {
|
translate([20, 50, 10])
|
||||||
extrusion_inner_corner_bracket(E20_inner_corner_bracket);
|
inner_bracket_test(E20_inner_corner_bracket, true);
|
||||||
|
|
||||||
translate([-eWidth / 2, 0, 0])
|
translate([20, 80, 10])
|
||||||
rotate([-90, 0, 0])
|
inner_bracket_test(E20_inner_corner_bracket);
|
||||||
extrusion(E2020, 20, false);
|
|
||||||
|
|
||||||
translate([-eWidth, -eWidth / 2, 0])
|
translate([20, 120, 10])
|
||||||
rotate([0, 90, 0])
|
bracket_test(E20_corner_bracket);
|
||||||
extrusion(E2020, 40, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
translate([100, 60, 10]) rotate([90, 0, 180]) {
|
translate([100, 70, 10])
|
||||||
extrusion_corner_bracket_assembly(E20_corner_bracket);
|
inner_bracket_test(E40_inner_corner_bracket);
|
||||||
|
|
||||||
translate([-eWidth / 2, 0, 0])
|
translate([100, 130, 10])
|
||||||
rotate([-90, 0, 0])
|
bracket_test(E40_corner_bracket);
|
||||||
extrusion(E2020, 30, false);
|
|
||||||
|
|
||||||
translate([-eWidth, -eWidth / 2, 0])
|
|
||||||
rotate([0, 90, 0])
|
|
||||||
extrusion(E2020, 50, false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if($preview)
|
if($preview)
|
||||||
extrusion_brackets(true);
|
let($show_threads = true)
|
||||||
|
extrusion_brackets(true);
|
||||||
|
@@ -21,9 +21,24 @@ use <../utils/layout.scad>
|
|||||||
|
|
||||||
include <../vitamins/extrusions.scad>
|
include <../vitamins/extrusions.scad>
|
||||||
|
|
||||||
|
gap = 10;
|
||||||
|
|
||||||
module extrusions()
|
module extrusions()
|
||||||
layout([for(e = extrusions) extrusion_width(e)], 10)
|
layout([for(e = extrusions) is_list(e[0]) ? extrusion_width(e[0]) : extrusion_width(e)], gap)
|
||||||
extrusion(extrusions[$i], 80, cornerHole = extrusion_width(extrusions[$i]) > 20);
|
let(e = extrusions[$i])
|
||||||
|
if(is_list(e[0])) {
|
||||||
|
list = e;
|
||||||
|
heights = [for(e = list) extrusion_height(e)];
|
||||||
|
l = len(heights) - 1;
|
||||||
|
offset = (heights * [for(i = [0 : l]) 1] + l * gap) / 2;
|
||||||
|
translate([0, -offset])
|
||||||
|
rotate(90)
|
||||||
|
layout(heights, gap)
|
||||||
|
rotate(-90)
|
||||||
|
extrusion(list[$i], 80, cornerHole = extrusion_width(list[$i]) > 20);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
extrusion(e, 80, cornerHole = extrusion_width(e) > 20);
|
||||||
|
|
||||||
if ($preview)
|
if ($preview)
|
||||||
extrusions();
|
extrusions();
|
||||||
|
@@ -16,12 +16,13 @@
|
|||||||
// You should have received a copy of the GNU General Public License along with NopSCADlib.
|
// You should have received a copy of the GNU General Public License along with NopSCADlib.
|
||||||
// If not, see <https://www.gnu.org/licenses/>.
|
// If not, see <https://www.gnu.org/licenses/>.
|
||||||
//
|
//
|
||||||
|
include <../core.scad>
|
||||||
include <../vitamins/geared_steppers.scad>
|
include <../vitamins/geared_steppers.scad>
|
||||||
|
|
||||||
use <../utils/layout.scad>
|
use <../utils/layout.scad>
|
||||||
|
|
||||||
module geared_steppers()
|
module geared_steppers()
|
||||||
layout([for(g = geared_steppers) gs_diameter(g)], 5)
|
layout([for(g = geared_steppers) max(gs_diameter(g), gs_pitch(g) + gs_lug_w(g) / 2)], 5)
|
||||||
geared_stepper(geared_steppers[$i]);
|
geared_stepper(geared_steppers[$i]);
|
||||||
|
|
||||||
geared_steppers();
|
geared_steppers();
|
||||||
|
@@ -16,6 +16,7 @@
|
|||||||
// You should have received a copy of the GNU General Public License along with NopSCADlib.
|
// You should have received a copy of the GNU General Public License along with NopSCADlib.
|
||||||
// If not, see <https://www.gnu.org/licenses/>.
|
// If not, see <https://www.gnu.org/licenses/>.
|
||||||
//
|
//
|
||||||
|
include <../core.scad>
|
||||||
use <../utils/layout.scad>
|
use <../utils/layout.scad>
|
||||||
|
|
||||||
include <../vitamins/green_terminals.scad>
|
include <../vitamins/green_terminals.scad>
|
||||||
|
@@ -16,6 +16,7 @@
|
|||||||
// You should have received a copy of the GNU General Public License along with NopSCADlib.
|
// You should have received a copy of the GNU General Public License along with NopSCADlib.
|
||||||
// If not, see <https://www.gnu.org/licenses/>.
|
// If not, see <https://www.gnu.org/licenses/>.
|
||||||
//
|
//
|
||||||
|
include <../core.scad>
|
||||||
use <../vitamins/hygrometer.scad>
|
use <../vitamins/hygrometer.scad>
|
||||||
|
|
||||||
if($preview)
|
if($preview)
|
||||||
|
@@ -16,6 +16,7 @@
|
|||||||
// You should have received a copy of the GNU General Public License along with NopSCADlib.
|
// You should have received a copy of the GNU General Public License along with NopSCADlib.
|
||||||
// If not, see <https://www.gnu.org/licenses/>.
|
// If not, see <https://www.gnu.org/licenses/>.
|
||||||
//
|
//
|
||||||
|
include <../core.scad>
|
||||||
use <../vitamins/microview.scad>
|
use <../vitamins/microview.scad>
|
||||||
|
|
||||||
microview(!$preview);
|
microview(!$preview);
|
||||||
|
@@ -52,6 +52,12 @@ module nuts() {
|
|||||||
|
|
||||||
if(n == M5_nut)
|
if(n == M5_nut)
|
||||||
sliding_t_nut(M5_sliding_t_nut);
|
sliding_t_nut(M5_sliding_t_nut);
|
||||||
|
|
||||||
|
if(n == M6_nut)
|
||||||
|
sliding_t_nut(M6_sliding_t_nut);
|
||||||
|
|
||||||
|
if(n == M8_nut)
|
||||||
|
sliding_t_nut(M8_sliding_ball_t_nut);
|
||||||
}
|
}
|
||||||
|
|
||||||
translate([0, 80]) {
|
translate([0, 80]) {
|
||||||
|
@@ -16,6 +16,7 @@
|
|||||||
// You should have received a copy of the GNU General Public License along with NopSCADlib.
|
// You should have received a copy of the GNU General Public License along with NopSCADlib.
|
||||||
// If not, see <https://www.gnu.org/licenses/>.
|
// If not, see <https://www.gnu.org/licenses/>.
|
||||||
//
|
//
|
||||||
|
include <../core.scad>
|
||||||
use <../vitamins/o_ring.scad>
|
use <../vitamins/o_ring.scad>
|
||||||
|
|
||||||
module o_rings()
|
module o_rings()
|
||||||
|
@@ -17,7 +17,7 @@
|
|||||||
// If not, see <https://www.gnu.org/licenses/>.
|
// If not, see <https://www.gnu.org/licenses/>.
|
||||||
//
|
//
|
||||||
include <../core.scad>
|
include <../core.scad>
|
||||||
include <../vitamins/kp_pillow_blocks.scad>
|
include <../vitamins/pillow_blocks.scad>
|
||||||
|
|
||||||
use <../utils/layout.scad>
|
use <../utils/layout.scad>
|
||||||
|
|
@@ -64,8 +64,9 @@ module pin_headers() {
|
|||||||
pin_socket(pin_headers[$i], 3, 3, right_angle = true);
|
pin_socket(pin_headers[$i], 3, 3, right_angle = true);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i = [0, 1], p = [5, 2][i], j = [0 , 1]) {
|
headers = [jst_zh_header, jst_ph_header, jst_xh_header];
|
||||||
h = [jst_ph_header, jst_xh_header][j];
|
for(i = [0, 1], p = [5, 2][i], j = [0 : len(headers) - 1]) {
|
||||||
|
h = headers[j];
|
||||||
translate([-20 * (i + 1), 0 + j * 40])
|
translate([-20 * (i + 1), 0 + j * 40])
|
||||||
jst_xh_header(h, p);
|
jst_xh_header(h, p);
|
||||||
|
|
||||||
|
BIN
tests/png/7_segments.png
Normal file
After Width: | Height: | Size: 37 KiB |
Before Width: | Height: | Size: 6.5 KiB After Width: | Height: | Size: 6.5 KiB |
Before Width: | Height: | Size: 282 KiB After Width: | Height: | Size: 276 KiB |
BIN
tests/png/bearing_blocks.png
Normal file
After Width: | Height: | Size: 92 KiB |
Before Width: | Height: | Size: 133 KiB After Width: | Height: | Size: 162 KiB |
Before Width: | Height: | Size: 84 KiB After Width: | Height: | Size: 84 KiB |
BIN
tests/png/bldc_motors.png
Normal file
After Width: | Height: | Size: 142 KiB |
BIN
tests/png/box_sections.png
Normal file
After Width: | Height: | Size: 26 KiB |
BIN
tests/png/core_xy.png
Normal file
After Width: | Height: | Size: 126 KiB |
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 61 KiB |
Before Width: | Height: | Size: 77 KiB After Width: | Height: | Size: 72 KiB |
Before Width: | Height: | Size: 55 KiB After Width: | Height: | Size: 85 KiB |
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 74 KiB |
Before Width: | Height: | Size: 119 KiB After Width: | Height: | Size: 119 KiB |
Before Width: | Height: | Size: 117 KiB After Width: | Height: | Size: 117 KiB |
Before Width: | Height: | Size: 102 KiB After Width: | Height: | Size: 102 KiB |
Before Width: | Height: | Size: 67 KiB After Width: | Height: | Size: 94 KiB |
Before Width: | Height: | Size: 102 KiB After Width: | Height: | Size: 102 KiB |
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 72 KiB |
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 77 KiB |
Before Width: | Height: | Size: 95 KiB After Width: | Height: | Size: 95 KiB |
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 61 KiB |
Before Width: | Height: | Size: 111 KiB After Width: | Height: | Size: 118 KiB |
Before Width: | Height: | Size: 174 KiB After Width: | Height: | Size: 180 KiB |
Before Width: | Height: | Size: 153 KiB After Width: | Height: | Size: 169 KiB |
BIN
tests/png/pillow_blocks.png
Normal file
After Width: | Height: | Size: 85 KiB |
Before Width: | Height: | Size: 166 KiB After Width: | Height: | Size: 146 KiB |
BIN
tests/png/pocket_handle.png
Normal file
After Width: | Height: | Size: 71 KiB |
BIN
tests/png/potentiometers.png
Normal file
After Width: | Height: | Size: 117 KiB |
Before Width: | Height: | Size: 116 KiB After Width: | Height: | Size: 116 KiB |
Before Width: | Height: | Size: 154 KiB After Width: | Height: | Size: 165 KiB |
Before Width: | Height: | Size: 188 KiB After Width: | Height: | Size: 188 KiB |
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 41 KiB |
BIN
tests/png/rounded_triangle.png
Normal file
After Width: | Height: | Size: 67 KiB |
Before Width: | Height: | Size: 148 KiB After Width: | Height: | Size: 176 KiB |
BIN
tests/png/servo_motors.png
Normal file
After Width: | Height: | Size: 47 KiB |
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 70 KiB |
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 47 KiB |
Before Width: | Height: | Size: 78 KiB After Width: | Height: | Size: 88 KiB |
Before Width: | Height: | Size: 181 KiB After Width: | Height: | Size: 181 KiB |
Before Width: | Height: | Size: 107 KiB After Width: | Height: | Size: 103 KiB |
Before Width: | Height: | Size: 150 KiB After Width: | Height: | Size: 149 KiB |
40
tests/pocket_handle.scad
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
//
|
||||||
|
// NopSCADlib Copyright Chris Palmer 2021
|
||||||
|
// 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>
|
||||||
|
|
||||||
|
include <../vitamins/sheets.scad>
|
||||||
|
|
||||||
|
use <../printed/pocket_handle.scad>
|
||||||
|
|
||||||
|
show_holes = false;
|
||||||
|
|
||||||
|
handle = pocket_handle();
|
||||||
|
|
||||||
|
module pocket_handles() {
|
||||||
|
if($preview) {
|
||||||
|
pocket_handle_assembly(handle);
|
||||||
|
|
||||||
|
if(show_holes)
|
||||||
|
#pocket_handle_holes(handle);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
pocket_handle(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
pocket_handles();
|
31
tests/potentiometers.scad
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
//
|
||||||
|
// NopSCADlib Copyright Chris Palmer 2021
|
||||||
|
// 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/>.
|
||||||
|
//
|
||||||
|
//! Potentiometers and rotary encoders
|
||||||
|
include <../core.scad>
|
||||||
|
include <../utils/layout.scad>
|
||||||
|
include <../vitamins/potentiometers.scad>
|
||||||
|
|
||||||
|
module potentiometers()
|
||||||
|
layout([for(p = potentiometers) pot_size(p).x])
|
||||||
|
hflip()
|
||||||
|
potentiometer(potentiometers[$i], shaft_length = 30);
|
||||||
|
|
||||||
|
if($preview)
|
||||||
|
let($show_threads = true)
|
||||||
|
potentiometers();
|
@@ -16,8 +16,8 @@
|
|||||||
// You should have received a copy of the GNU General Public License along with NopSCADlib.
|
// You should have received a copy of the GNU General Public License along with NopSCADlib.
|
||||||
// If not, see <https://www.gnu.org/licenses/>.
|
// If not, see <https://www.gnu.org/licenses/>.
|
||||||
//
|
//
|
||||||
|
include <../core.scad>
|
||||||
include <../printed/press_fit.scad>
|
use <../printed/press_fit.scad>
|
||||||
|
|
||||||
module press_fits()
|
module press_fits()
|
||||||
{
|
{
|
||||||
|