Compare commits
245 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
390957fdd0 | ||
|
bde8cbe7a6 | ||
|
fbe8533a42 | ||
|
a9c2f854c6 | ||
|
6187d90c57 | ||
|
65f320141d | ||
|
d367e743da | ||
|
3a4305f5ca | ||
|
a7dde2d4e2 | ||
|
56390bf8dd | ||
|
53f0bbcd6e | ||
|
f2ec3e71f4 | ||
|
c1b5bd1b87 | ||
|
268c066965 | ||
|
fd8712d6bf | ||
|
b6a32b6b41 | ||
|
0738893510 | ||
|
849bc479cc | ||
|
86d7e0f124 | ||
|
c897060726 | ||
|
b2c2fc668b | ||
|
4914f90994 | ||
|
2210396234 | ||
|
2eef050f60 | ||
|
23a64f238d | ||
|
a8422a6aa6 | ||
|
b56ddea1e3 | ||
|
c16a1c3804 | ||
|
245b158f1d | ||
|
60628dfec0 | ||
|
f7db793c74 | ||
|
53292c9f89 | ||
|
bd60b50b09 | ||
|
4d51cb73f3 | ||
|
3b77c97532 | ||
|
4442042197 | ||
|
4e233e5e9d | ||
|
675953d334 | ||
|
9527fa1c1f | ||
|
3f209cbdd3 | ||
|
7b76aceaad | ||
|
4edd08977f | ||
|
a1d385f9ec | ||
|
fc17b52518 | ||
|
9fbdb82991 | ||
|
7706716fa2 | ||
|
c815c1592d | ||
|
e32ef88c90 | ||
|
702c450a27 | ||
|
343351155c | ||
|
c41b1fa115 | ||
|
1a197ac823 | ||
|
ab592e049c | ||
|
9b104e4fe7 | ||
|
f0b4d767e9 | ||
|
82baed4c8f | ||
|
acb2cb2a48 | ||
|
cf94972b18 | ||
|
7c0a48d0c1 | ||
|
a5a640e273 | ||
|
95c4359421 | ||
|
bcff26a27b | ||
|
07b00fabe0 | ||
|
8ed0f3c1af | ||
|
0e8e387d35 | ||
|
0c17620adb | ||
|
6470f1b004 | ||
|
29ba402530 | ||
|
aed4a699f2 | ||
|
10b846c0d5 | ||
|
2de479d691 | ||
|
054dab5025 | ||
|
b559319b03 | ||
|
a487ca0f20 | ||
|
a2ce3f1278 | ||
|
01eb6931d9 | ||
|
c09a74b4c9 | ||
|
aab7f3d683 | ||
|
ad719dad5a | ||
|
00690b61d2 | ||
|
1a24e0d87e | ||
|
171c9a6a34 | ||
|
8bb4b3881e | ||
|
79f8bc66e1 | ||
|
33c9d158ef | ||
|
d2874a0531 | ||
|
b6fd795a25 | ||
|
ad0882db40 | ||
|
8afb08aaa4 | ||
|
e87dffd92c | ||
|
c364bf06b2 | ||
|
1668f9c54c | ||
|
e0dd174010 | ||
|
f104bd42e5 | ||
|
8342ba87e9 | ||
|
0e58e92fbc | ||
|
1af2e18594 | ||
|
598527edbe | ||
|
9c666f8f47 | ||
|
bc1f135e40 | ||
|
ce36729e50 | ||
|
1dca024e64 | ||
|
c1833f0820 | ||
|
6a7f7dcbbf | ||
|
5d3f1115bb | ||
|
9f9adeb6ca | ||
|
f9b06c855c | ||
|
05bfe9b159 | ||
|
f961874ce3 | ||
|
7a6210f442 | ||
|
5bae0aaa51 | ||
|
8649d59e8a | ||
|
e9bc300b8d | ||
|
dcb1e74894 | ||
|
42b9479094 | ||
|
f46f35e909 | ||
|
0513b151b2 | ||
|
dcf258f11a | ||
|
4ff6c7d0a8 | ||
|
2edb6d4df2 | ||
|
26e8497018 | ||
|
bfde879ce2 | ||
|
4641e3a642 | ||
|
42cfed8846 | ||
|
8c339a18c4 | ||
|
065ec0a430 | ||
|
e7eea0520c | ||
|
5cb994b58b | ||
|
573425055a | ||
|
66a7a9bfe0 | ||
|
0335545334 | ||
|
fa91acbaad | ||
|
8bad05e721 | ||
|
9d6727d371 | ||
|
8902d83f0a | ||
|
e40b10f5a0 | ||
|
66a8d1d583 | ||
|
d066648a76 | ||
|
b8546414c0 | ||
|
581c2f8a96 | ||
|
e9ee88dfe9 | ||
|
b07a8ad245 | ||
|
ab17de3b0b | ||
|
0b8141844c | ||
|
7d0548b033 | ||
|
ad3e8d85af | ||
|
8435a350d0 | ||
|
3e5d4b1c8e | ||
|
20f830a008 | ||
|
10bd8ff354 | ||
|
4459cca3ea | ||
|
95bbebd42d | ||
|
cc84a5a536 | ||
|
28c795e9f4 | ||
|
9a0477d16b | ||
|
0583da2eb7 | ||
|
9a08fe9b5c | ||
|
8ab7993148 | ||
|
16dd8d6d17 | ||
|
08c268145e | ||
|
ba7e64233a | ||
|
7090c714ce | ||
|
c5038db6d9 | ||
|
654f094304 | ||
|
1e5e5860e1 | ||
|
a08216d0b8 | ||
|
3d8a9ec8aa | ||
|
7ec059142f | ||
|
7f0d96b824 | ||
|
9e826c1a09 | ||
|
2c1dbe04a9 | ||
|
d644d6b698 | ||
|
8db4cc2cb5 | ||
|
509a87939c | ||
|
40607e6cfc | ||
|
599fbba6c2 | ||
|
52729d012c | ||
|
6097e07094 | ||
|
9d71438a3c | ||
|
ffa1ab940b | ||
|
3174013e1a | ||
|
c4eea38a2b | ||
|
0cd89279a5 | ||
|
92051e0b28 | ||
|
f4b22e35c7 | ||
|
17ecfc07f3 | ||
|
9658205efd | ||
|
53140a4cc1 | ||
|
2798d39538 | ||
|
8be0cc98ea | ||
|
6a5f31edd8 | ||
|
e068918e21 | ||
|
1614f50b73 | ||
|
32522b28d7 | ||
|
1936c95d06 | ||
|
16060629c0 | ||
|
b7b5c837bd | ||
|
a793cb6d43 | ||
|
dc4e24b63a | ||
|
8f85ac73dc | ||
|
3ab934d83e | ||
|
d1324a670e | ||
|
f5fdec613c | ||
|
c55b8b6d1c | ||
|
56ec8e03ad | ||
|
728b7adf38 | ||
|
75747687d9 | ||
|
03c97e8b6a | ||
|
8ac06b53e7 | ||
|
de76eb46e7 | ||
|
2c77f184a2 | ||
|
4d3d9dfdfe | ||
|
f7a972f946 | ||
|
4e81fcbd4f | ||
|
1f038decd4 | ||
|
da958fe112 | ||
|
61493eaa34 | ||
|
804c00bdcb | ||
|
11ea68681f | ||
|
d703ae4997 | ||
|
ed97d226f8 | ||
|
4107a2c848 | ||
|
f7ef075434 | ||
|
6f93b6af9a | ||
|
53f416eef1 | ||
|
6354219627 | ||
|
56e2b71bda | ||
|
8f5503586d | ||
|
1cd9edfe87 | ||
|
a85fdaf176 | ||
|
18294b4b81 | ||
|
ad62ce362c | ||
|
9f27f26894 | ||
|
2eaa4bfc21 | ||
|
1944039f22 | ||
|
1c221ad612 | ||
|
85adf7b4f4 | ||
|
64bde2cb3a | ||
|
c34469e852 | ||
|
dbc3c36f44 | ||
|
8c51183ba6 | ||
|
a9c4e60cac | ||
|
d041b18025 | ||
|
e85887fec4 | ||
|
ededb514b8 |
16
.gitattributes
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
# Set the default behavior, in case people don't have core.autocrlf set.
|
||||
* text=auto eol=lf
|
||||
|
||||
# Declare text files that are normalized and converted on checkout.
|
||||
*.scad text
|
||||
*.py text
|
||||
*.md text
|
||||
|
||||
# Handle Windows batch and command files
|
||||
*.{bat,[bB][aA][tT]} text eol=crlf
|
||||
*.{cmd,[cC][mM][dD]} text eol=crlf
|
||||
|
||||
# Denote files that are binary and should not be modified.
|
||||
*.png binary
|
||||
*.jpg binary
|
||||
|
1
.gitignore
vendored
@@ -7,6 +7,7 @@ tests/bom/
|
||||
*.log
|
||||
*.html
|
||||
bounds.json
|
||||
options.json
|
||||
times.txt
|
||||
*_diff.png
|
||||
*.echo
|
||||
|
20
core.scad
@@ -18,22 +18,10 @@
|
||||
//
|
||||
|
||||
//
|
||||
// Include this file to use the miniumum library
|
||||
// Include this file to use the miniumum library plus screws, nuts and washers
|
||||
//
|
||||
include <global_defs.scad>
|
||||
include <utils/core/core.scad>
|
||||
//
|
||||
// Global functions and modules
|
||||
// Fasteners used by a lot of other vitamins
|
||||
//
|
||||
use <utils/core/global.scad>
|
||||
|
||||
module use_stl(name) { //! Import an STL to make a build platter
|
||||
stl(name);
|
||||
|
||||
import(str("../stls/", name, ".stl"));
|
||||
}
|
||||
|
||||
module use_dxf(name) { //! Import a DXF to make a build panel
|
||||
dxf(name);
|
||||
|
||||
import(str("../dxfs/", name, ".dxf"));
|
||||
}
|
||||
include <vitamins/screws.scad>
|
||||
|
BIN
docs/metric_threads.png
Normal file
After Width: | Height: | Size: 17 KiB |
@@ -26,7 +26,7 @@ OpenSCAD has to be setup to find libraries by setting the ```OPENSCADPATH``` env
|
||||
in the directory it points to. This can be done with ```git clone https://github.com/nophead/NopSCADlib.git``` while in that directory or, if you don't want to use GIT,
|
||||
by downloading https://github.com/nophead/NopSCADlib/archive/master.zip and unzipping it to a directory called NopSCADlib.
|
||||
|
||||
The ```NopSCADlib/scripts``` directory needs to be added to the executable search path.
|
||||
The ```NopSCADlib/scripts``` directory needs to be added to the executable search path, ```PATH``` on Windows and ```path``` on Linux and Mac.
|
||||
|
||||
The installation can be tested by opening ```NopSCADlib/libtest.scad``` in the OpenSCAD GUI. It should render all the objects in the library in about 1 minute.
|
||||
|
||||
@@ -116,8 +116,8 @@ get shared if other files in the project include ```lib.scad``` as well, or if y
|
||||
|
||||
One downside is that any change to the library will mean all the project files need regenerating.
|
||||
A more optimised approach for large projects is to include [NopSCADlib/core.scad](../core.scad) instead.
|
||||
That only has the a small set of utilities and the global settings in [global_defs.scad](../global_defs.scad). Any vitamins used need to be included explicitly.
|
||||
One can copy the include or use line from [NopSCADlib/lib.scad](../lib.scad).
|
||||
That only has the a small set of utilities and the global settings in [global_defs.scad](../global_defs.scad) plus screws, nuts and washers that are required by a lot of other vitamins.
|
||||
Any other vitamins used need to be included explicitly. One can copy the includes or use a line from [NopSCADlib/lib.scad](../lib.scad).
|
||||
|
||||
### Parametric parts.
|
||||
|
||||
@@ -233,3 +233,33 @@ Vitamins are only ever previewed, so they are optimised to draw quickly in F5 an
|
||||
In OpenCSG 3D difference and intersection are relatively slow and the negative volumes interfere with nearby objects when they are composed into assemblies. For this reason as much
|
||||
as possible is done by unioning primitives and extruded 2D shapes. Any 3D differences or intersections are wrapped in ```render()``` so that CGAL will compute a polyhedron
|
||||
that is cached and reused. This will be very slow the first time it renders but very fast afterwards.
|
||||
|
||||
### Panels and Platters
|
||||
|
||||
The ```stls``` and ```dxfs``` scripts produce a file for each part but often it is desirable to print or route collections of parts laid out together.
|
||||
This can be done by adding scad files to folders called ```platters``` for STL files and ```panels``` for DXF files.
|
||||
These can aggregate and lay out parts by including ```NopSCADlib/core.scad``` and using modules ```use_stl(name)``` and ```use_dxf(name)```.
|
||||
These modules import the already generated singular STL and DXF files, so they are relatively fast. The name does not include the suffix.
|
||||
The scad files typically also need to include other files from the project to get the dimensions of the parts to calculate their positions.
|
||||
|
||||
The composite part files have the same name as the scad file that generates them, with the suffix changed to ```.stl``` or ```.dxf```.
|
||||
|
||||
The generated files are placed in ```stls/printed``` and ```dxfs/routed```.
|
||||
Any parts that are not covered by the platters / panels are copied into the ```printed``` / ```routed``` directories, so that they contain everything to be made.
|
||||
|
||||
### Multiple configurations
|
||||
|
||||
Some parametric designs might have several configurations, for example a 3D printer with different size options. If several configurations need to be supported at the
|
||||
same time multiple sets of BOMS, STLS and DXFs need to be generated in separate diectories. NopSCADlib supports this by having multiple configuration files named
|
||||
```config_<target_name>.scad```. All the scripts take an optional first parameter that selects one of these config files by specifying ```target_name```.
|
||||
|
||||
The target config file is selected by generating ```target.scad``` that includes ```config_<target_name>.scad```.
|
||||
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>```.
|
||||
|
||||
### 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
|
||||
in the project plus any ```printed``` directories outside the project. This covers the printed parts in NopSCADlib but also allows other libraries of printed parts.
|
||||
|
||||
Other libraries of vitamins and utilities can be used provided they follow the same convensions of NopSCADlib. The build scripts don't need to search those.
|
||||
|
Before Width: | Height: | Size: 96 KiB After Width: | Height: | Size: 96 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 107 KiB After Width: | Height: | Size: 108 KiB |
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 104 KiB After Width: | Height: | Size: 105 KiB |
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 130 KiB After Width: | Height: | Size: 137 KiB |
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 179 KiB After Width: | Height: | Size: 200 KiB |
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 33 KiB |
Before Width: | Height: | Size: 121 KiB After Width: | Height: | Size: 124 KiB |
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 130 KiB After Width: | Height: | Size: 134 KiB |
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
@@ -30,7 +30,7 @@ Earth leakage can be measured Canadian CSA style by disconnected the neutral lin
|
||||
<a name="Parts_list"></a>
|
||||
## Parts list
|
||||
| <span style="writing-mode: vertical-rl; text-orientation: mixed;">Base</span> | <span style="writing-mode: vertical-rl; text-orientation: mixed;">Feet</span> | <span style="writing-mode: vertical-rl; text-orientation: mixed;">Mains In</span> | <span style="writing-mode: vertical-rl; text-orientation: mixed;">Main</span> | <span style="writing-mode: vertical-rl; text-orientation: mixed;">TOTALS</span> | |
|
||||
|--:|--:|--:|--:|--:|:--|
|
||||
|---:|---:|---:|---:|---:|:---|
|
||||
| | | | | | **Vitamins** |
|
||||
| . | . | . | 2 | 2 | 4mm shielded jack socket blue |
|
||||
| . | . | . | 1 | 1 | 4mm shielded jack socket brown |
|
||||
@@ -61,14 +61,14 @@ Earth leakage can be measured Canadian CSA style by disconnected the neutral lin
|
||||
## Base Assembly
|
||||
### Vitamins
|
||||
|Qty|Description|
|
||||
|--:|:----------|
|
||||
|---:|:----------|
|
||||
|2| Heatfit insert M3|
|
||||
|
||||
|
||||
### 3D Printed parts
|
||||
|
||||
| 1 x socket_box.stl |
|
||||
|--|
|
||||
|---|
|
||||
| 
|
||||
|
||||
|
||||
@@ -88,7 +88,7 @@ Earth leakage can be measured Canadian CSA style by disconnected the neutral lin
|
||||
## Feet Assembly
|
||||
### Vitamins
|
||||
|Qty|Description|
|
||||
|--:|:----------|
|
||||
|---:|:----------|
|
||||
|4| Nut M3 x 2.4mm nyloc|
|
||||
|4| Screw M3 dome x 10mm|
|
||||
|8| Washer M3 x 7mm x 0.5mm|
|
||||
@@ -97,7 +97,7 @@ Earth leakage can be measured Canadian CSA style by disconnected the neutral lin
|
||||
### 3D Printed parts
|
||||
|
||||
| 4 x foot.stl |
|
||||
|--|
|
||||
|---|
|
||||
| 
|
||||
|
||||
|
||||
@@ -105,7 +105,7 @@ Earth leakage can be measured Canadian CSA style by disconnected the neutral lin
|
||||
### Sub-assemblies
|
||||
|
||||
| 1 x base_assembly |
|
||||
|--|
|
||||
|---|
|
||||
| 
|
||||
|
||||
|
||||
@@ -124,7 +124,7 @@ Earth leakage can be measured Canadian CSA style by disconnected the neutral lin
|
||||
## Mains In Assembly
|
||||
### Vitamins
|
||||
|Qty|Description|
|
||||
|--:|:----------|
|
||||
|---:|:----------|
|
||||
|3| Heatshrink sleeving ID 3.2mm x 15mm - not shown|
|
||||
|1| IEC inlet for ATX|
|
||||
|2| Nut M3 x 2.4mm nyloc|
|
||||
@@ -138,7 +138,7 @@ Earth leakage can be measured Canadian CSA style by disconnected the neutral lin
|
||||
### Sub-assemblies
|
||||
|
||||
| 1 x feet_assembly |
|
||||
|--|
|
||||
|---|
|
||||
| 
|
||||
|
||||
|
||||
@@ -163,7 +163,7 @@ Earth leakage can be measured Canadian CSA style by disconnected the neutral lin
|
||||
## Main Assembly
|
||||
### Vitamins
|
||||
|Qty|Description|
|
||||
|--:|:----------|
|
||||
|---:|:----------|
|
||||
|2| 4mm shielded jack socket blue|
|
||||
|1| 4mm shielded jack socket brown|
|
||||
|2| 4mm shielded jack socket green|
|
||||
@@ -178,7 +178,7 @@ Earth leakage can be measured Canadian CSA style by disconnected the neutral lin
|
||||
### Sub-assemblies
|
||||
|
||||
| 1 x mains_in_assembly |
|
||||
|--|
|
||||
|---|
|
||||
| 
|
||||
|
||||
|
||||
|
@@ -35,7 +35,14 @@ $extrusion_width = 0.5;
|
||||
$pp1_colour = "dimgrey";
|
||||
$pp2_colour = [0.9, 0.9, 0.9];
|
||||
|
||||
include <NopSCADlib/lib.scad>
|
||||
include <NopSCADlib/core.scad>
|
||||
include <NopSCADlib/vitamins/iecs.scad>
|
||||
include <NopSCADlib/vitamins/mains_sockets.scad>
|
||||
include <NopSCADlib/vitamins/tubings.scad>
|
||||
|
||||
use <NopSCADlib/vitamins/insert.scad>
|
||||
use <NopSCADlib/vitamins/wire.scad>
|
||||
use <NopSCADlib/vitamins/jack.scad>
|
||||
use <NopSCADlib/printed/foot.scad>
|
||||
|
||||
echo(extrusion_width = extrusion_width, layer_height = layer_height);
|
||||
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 108 KiB After Width: | Height: | Size: 107 KiB |
BIN
gallery/EnviroPlus.png
Normal file
After Width: | Height: | Size: 121 KiB |
Before Width: | Height: | Size: 124 KiB After Width: | Height: | Size: 179 KiB |
Before Width: | Height: | Size: 169 KiB After Width: | Height: | Size: 169 KiB |
Before Width: | Height: | Size: 280 KiB After Width: | Height: | Size: 280 KiB |
Before Width: | Height: | Size: 291 KiB After Width: | Height: | Size: 291 KiB |
Before Width: | Height: | Size: 286 KiB After Width: | Height: | Size: 287 KiB |
Before Width: | Height: | Size: 230 KiB After Width: | Height: | Size: 230 KiB |
Before Width: | Height: | Size: 206 KiB After Width: | Height: | Size: 205 KiB |
Before Width: | Height: | Size: 207 KiB After Width: | Height: | Size: 207 KiB |
Before Width: | Height: | Size: 198 KiB After Width: | Height: | Size: 198 KiB |
@@ -6,6 +6,13 @@ Arduino thermostat to control a beer fridge to use it as an environmental chambe
|
||||

|
||||
|
||||
|
||||
<a name="TOP"></a>
|
||||
## EnviroPlus
|
||||
Environmental monitor using Enviro+ sensor board and a Raspberry Pi Zero.
|
||||
|
||||

|
||||
|
||||
|
||||
<a name="TOP"></a>
|
||||
## FilamentDryBox
|
||||
A small fan oven with a spool holder to keep the filament warm and dry.
|
||||
|
@@ -34,11 +34,12 @@ layer_height = is_undef($layer_height) ? 0.25 : $layer_height; // lay
|
||||
extrusion_width = is_undef($extrusion_width) ? 0.5 : $extrusion_width; // filament width when printing
|
||||
nozzle = is_undef($nozzle) ? 0.45 : $nozzle; // 3D printer nozzle
|
||||
cnc_bit_r = is_undef($cnc_bit_r) ? 1.2 : $cnc_bit_r; // miniumum tool radius when milling 2D objects
|
||||
pp1_colour = is_undef($pp1_colour) ? "lime" : $pp1_colour; // printed part colour 1
|
||||
pp1_colour = is_undef($pp1_colour) ? [0, 146/255, 0] : $pp1_colour; // printed part colour 1, RepRap logo colour
|
||||
pp2_colour = is_undef($pp2_colour) ? "red" : $pp2_colour; // printed part colour 2
|
||||
pp3_colour = is_undef($pp3_colour) ? "blue" : $pp3_colour; // printed part colour 3
|
||||
pp4_colour = is_undef($pp4_colour) ? "darkorange" : $pp4_colour;// printed part colour 4
|
||||
show_rays = is_undef($show_rays) ? false : $show_rays; // show camera sight lines and light direction
|
||||
show_threads = is_undef($show_threads) ? false : $show_threads; // show screw threads
|
||||
|
||||
// Minimum wall is about two filaments wide but we extrude it closer to get better bonding
|
||||
squeezed_wall = $preview ? 2 * extrusion_width - layer_height * (1 - PI / 4)
|
||||
@@ -59,7 +60,9 @@ grey60 = [0.6, 0.6, 0.6];
|
||||
grey70 = [0.7, 0.7, 0.7];
|
||||
grey80 = [0.8, 0.8, 0.8];
|
||||
grey90 = [0.9, 0.9, 0.9];
|
||||
brass = "gold";
|
||||
gold = [255/255, 215/255, 0/255];
|
||||
brass = [255/255, 220/255, 100/255];
|
||||
silver = [0.75, 0.75, 0.75];
|
||||
|
||||
/*
|
||||
* Enums
|
||||
|
64
lib.scad
@@ -22,46 +22,45 @@
|
||||
//
|
||||
include <core.scad>
|
||||
|
||||
include <vitamins/fans.scad>
|
||||
include <vitamins/psus.scad>
|
||||
include <vitamins/pcbs.scad>
|
||||
|
||||
include <vitamins/batteries.scad>
|
||||
include <vitamins/blowers.scad>
|
||||
include <vitamins/bulldogs.scad>
|
||||
include <vitamins/buttons.scad>
|
||||
include <vitamins/components.scad>
|
||||
include <vitamins/displays.scad>
|
||||
include <vitamins/extrusions.scad>
|
||||
include <vitamins/extrusion_brackets.scad>
|
||||
include <vitamins/geared_steppers.scad>
|
||||
include <vitamins/green_terminals.scad>
|
||||
include <vitamins/hot_ends.scad>
|
||||
include <vitamins/inserts.scad>
|
||||
include <vitamins/kp_pillow_blocks.scad>
|
||||
include <vitamins/ldrs.scad>
|
||||
include <vitamins/leadnuts.scad>
|
||||
include <vitamins/leds.scad>
|
||||
include <vitamins/light_strips.scad>
|
||||
include <vitamins/mains_sockets.scad>
|
||||
include <vitamins/modules.scad>
|
||||
include <vitamins/pillars.scad>
|
||||
include <vitamins/pin_headers.scad>
|
||||
include <vitamins/pulleys.scad>
|
||||
include <vitamins/ring_terminals.scad>
|
||||
include <vitamins/rails.scad>
|
||||
include <vitamins/belts.scad>
|
||||
include <vitamins/pulleys.scad>
|
||||
include <vitamins/sheets.scad>
|
||||
include <vitamins/stepper_motors.scad>
|
||||
include <vitamins/components.scad>
|
||||
include <vitamins/hot_ends.scad>
|
||||
include <vitamins/tubings.scad>
|
||||
include <vitamins/zipties.scad>
|
||||
include <vitamins/linear_bearings.scad>
|
||||
include <vitamins/rod.scad>
|
||||
include <vitamins/leadnuts.scad>
|
||||
include <vitamins/bulldogs.scad>
|
||||
include <vitamins/pillars.scad>
|
||||
include <vitamins/psus.scad>
|
||||
include <vitamins/iecs.scad>
|
||||
include <vitamins/rockers.scad>
|
||||
include <vitamins/scs_bearing_blocks.scad>
|
||||
include <vitamins/sheets.scad>
|
||||
include <vitamins/sk_brackets.scad>
|
||||
include <vitamins/spools.scad>
|
||||
include <vitamins/ssrs.scad>
|
||||
include <vitamins/d_connectors.scad>
|
||||
include <vitamins/buttons.scad>
|
||||
include <vitamins/pcbs.scad>
|
||||
include <vitamins/modules.scad>
|
||||
include <vitamins/displays.scad>
|
||||
include <vitamins/blowers.scad>
|
||||
include <vitamins/leds.scad>
|
||||
include <vitamins/stepper_motors.scad>
|
||||
include <vitamins/toggles.scad>
|
||||
include <vitamins/transformers.scad>
|
||||
include <vitamins/tubings.scad>
|
||||
include <vitamins/variacs.scad>
|
||||
include <vitamins/springs.scad>
|
||||
include <vitamins/batteries.scad>
|
||||
include <vitamins/microswitches.scad>
|
||||
include <vitamins/ball_bearings.scad>
|
||||
include <vitamins/light_strips.scad>
|
||||
include <vitamins/spools.scad>
|
||||
include <vitamins/mains_sockets.scad>
|
||||
include <vitamins/ldrs.scad>
|
||||
include <vitamins/geared_steppers.scad>
|
||||
include <vitamins/zipties.scad>
|
||||
|
||||
use <vitamins/jack.scad>
|
||||
use <vitamins/meter.scad>
|
||||
@@ -90,3 +89,4 @@ use <utils/layout.scad>
|
||||
use <utils/round.scad>
|
||||
use <utils/offset.scad>
|
||||
use <utils/sector.scad>
|
||||
use <utils/thread.scad>
|
||||
|
BIN
libtest.png
Before Width: | Height: | Size: 721 KiB After Width: | Height: | Size: 774 KiB |
101
libtest.scad
@@ -29,19 +29,23 @@ use <tests/blowers.scad>
|
||||
use <tests/bulldogs.scad>
|
||||
use <tests/buttons.scad>
|
||||
use <tests/cable_strips.scad>
|
||||
use <tests/circlips.scad>
|
||||
use <tests/components.scad>
|
||||
use <tests/d_connectors.scad>
|
||||
use <tests/displays.scad>
|
||||
use <tests/extrusions.scad>
|
||||
use <tests/extrusion_brackets.scad>
|
||||
use <tests/fans.scad>
|
||||
use <tests/fuseholder.scad>
|
||||
use <tests/geared_steppers.scad>
|
||||
use <tests/hot_ends.scad>
|
||||
use <tests/iecs.scad>
|
||||
use <tests/IECs.scad>
|
||||
use <tests/inserts.scad>
|
||||
use <tests/jack.scad>
|
||||
use <tests/KP_pillow_blocks.scad>
|
||||
use <tests/leadnuts.scad>
|
||||
use <tests/leds.scad>
|
||||
use <tests/ldrs.scad>
|
||||
use <tests/LDRs.scad>
|
||||
use <tests/LEDs.scad>
|
||||
use <tests/light_strips.scad>
|
||||
use <tests/linear_bearings.scad>
|
||||
use <tests/meter.scad>
|
||||
@@ -50,20 +54,22 @@ use <tests/modules.scad>
|
||||
use <tests/nuts.scad>
|
||||
use <tests/o_ring.scad>
|
||||
use <tests/opengrab.scad>
|
||||
use <tests/pcbs.scad>
|
||||
use <tests/PCBs.scad>
|
||||
use <tests/pillars.scad>
|
||||
use <tests/psus.scad>
|
||||
use <tests/PSUs.scad>
|
||||
use <tests/pulleys.scad>
|
||||
use <tests/rails.scad>
|
||||
use <tests/ring_terminals.scad>
|
||||
use <tests/rockers.scad>
|
||||
use <tests/rod.scad>
|
||||
use <tests/screws.scad>
|
||||
use <tests/SCS_bearing_blocks.scad>
|
||||
use <tests/sealing_strip.scad>
|
||||
use <tests/sheets.scad>
|
||||
use <tests/SK_brackets.scad>
|
||||
use <tests/spades.scad>
|
||||
use <tests/springs.scad>
|
||||
use <tests/ssrs.scad>
|
||||
use <tests/SSRs.scad>
|
||||
use <tests/stepper_motors.scad>
|
||||
use <tests/toggles.scad>
|
||||
use <tests/transformers.scad>
|
||||
@@ -82,17 +88,25 @@ use <tests/door_hinge.scad>
|
||||
use <tests/door_latch.scad>
|
||||
use <tests/fan_guard.scad>
|
||||
use <tests/fixing_block.scad>
|
||||
use <tests/flat_hinge.scad>
|
||||
use <tests/foot.scad>
|
||||
use <tests/handle.scad>
|
||||
use <tests/PCB_mount.scad>
|
||||
use <tests/printed_box.scad>
|
||||
use <tests/ribbon_clamp.scad>
|
||||
use <tests/screw_knob.scad>
|
||||
use <tests/socket_box.scad>
|
||||
use <tests/strap_handle.scad>
|
||||
use <tests/ssr_shroud.scad>
|
||||
use <tests/psu_shroud.scad>
|
||||
use <tests/flat_hinge.scad>
|
||||
use <tests/SSR_shroud.scad>
|
||||
use <tests/PSU_shroud.scad>
|
||||
|
||||
x5 = 800;
|
||||
x0 = 0;
|
||||
x1 = x0 + 100;
|
||||
x2 = x1 + 90;
|
||||
x3 = x2 + 130;
|
||||
x4 = x3 + 200;
|
||||
x5 = 850;
|
||||
x6 = x5 + 150;
|
||||
|
||||
cable_grommets_y = 0;
|
||||
|
||||
@@ -131,19 +145,23 @@ translate([x5 + 60, cable_grommets_y + 200])
|
||||
translate([x5, cable_grommets_y + 250])
|
||||
handle();
|
||||
|
||||
translate([900, 600])
|
||||
translate([950, 600])
|
||||
box_test();
|
||||
|
||||
translate([850, 1170])
|
||||
translate([890, 750])
|
||||
printed_boxes();
|
||||
|
||||
translate([850, 1330])
|
||||
bbox_test();
|
||||
|
||||
x0 = 0;
|
||||
|
||||
inserts_y = 0;
|
||||
nuts_y = inserts_y + 20;
|
||||
washers_y = nuts_y + 60;
|
||||
washers_y = nuts_y + 120;
|
||||
screws_y = washers_y + 120;
|
||||
o_rings_y = screws_y + 130;
|
||||
springs_y = o_rings_y + 20;
|
||||
circlips_y = screws_y + 160;
|
||||
springs_y = circlips_y + 20;
|
||||
o_rings_y = springs_y;
|
||||
sealing_strip_y = springs_y + 20;
|
||||
tubings_y = sealing_strip_y + 20;
|
||||
pillars_y = tubings_y + 20;
|
||||
@@ -151,10 +169,10 @@ leadnuts_y = pillars_y + 40;
|
||||
pulleys_y = leadnuts_y +40;
|
||||
hot_ends_y = pulleys_y + 60;
|
||||
linear_bearings_y = hot_ends_y + 50;
|
||||
sheets_y = linear_bearings_y + 50;
|
||||
sheets_y = linear_bearings_y + 100;
|
||||
pcbs_y = sheets_y + 40;
|
||||
displays_y = pcbs_y + 150;
|
||||
fans_y = displays_y + 100;
|
||||
displays_y = pcbs_y + 170;
|
||||
fans_y = displays_y + 80;
|
||||
transformers_y = fans_y + 120;
|
||||
psus_y = transformers_y + 190;
|
||||
|
||||
@@ -173,10 +191,13 @@ translate([x0, washers_y])
|
||||
translate([x0, screws_y])
|
||||
screws();
|
||||
|
||||
translate([x0, circlips_y])
|
||||
circlips();
|
||||
|
||||
translate([x0, o_rings_y])
|
||||
o_rings();
|
||||
|
||||
translate([x0, springs_y])
|
||||
translate([x0 + 20, springs_y])
|
||||
springs();
|
||||
|
||||
translate([x0 + 50, sealing_strip_y])
|
||||
@@ -191,7 +212,7 @@ translate([x0, pillars_y])
|
||||
translate([x0, leadnuts_y ])
|
||||
leadnuts();
|
||||
|
||||
translate([x0 + 80, leadnuts_y])
|
||||
translate([x0 + 60, leadnuts_y])
|
||||
ball_bearings();
|
||||
|
||||
translate([x0, pulleys_y])
|
||||
@@ -230,7 +251,6 @@ translate([x0, psus_y]) {
|
||||
psu_shrouds();
|
||||
}
|
||||
|
||||
x1 = x0 + 100;
|
||||
zipties_y = 0;
|
||||
bulldogs_y = zipties_y + 40;
|
||||
|
||||
@@ -240,7 +260,6 @@ translate([x1, zipties_y])
|
||||
translate([x1, bulldogs_y])
|
||||
bulldogs();
|
||||
|
||||
x2 = x1 + 90;
|
||||
leds_y = 0;
|
||||
carriers_y = leds_y + 40;
|
||||
spades_y = carriers_y + 40;
|
||||
@@ -248,7 +267,7 @@ buttons_y = spades_y + 40;
|
||||
jacks_y = buttons_y + 40;
|
||||
microswitches_y = jacks_y + 40;
|
||||
rockers_y = microswitches_y + 40;
|
||||
toggles_y = rockers_y + 40;
|
||||
toggles_y = rockers_y + 60;
|
||||
components_y = toggles_y + 40;
|
||||
|
||||
translate([x2, leds_y])
|
||||
@@ -287,8 +306,6 @@ translate([x2, toggles_y])
|
||||
translate([x2, components_y])
|
||||
components();
|
||||
|
||||
|
||||
x3 = x2 + 150;
|
||||
veroboard_y = 0;
|
||||
d_connectors_y = veroboard_y + 110;
|
||||
iecs_y = d_connectors_y + 80;
|
||||
@@ -297,6 +314,7 @@ ssrs_y = modules_y + 80;
|
||||
blowers_y = ssrs_y + 60;
|
||||
batteries_y = blowers_y + 100;
|
||||
steppers_y = batteries_y + 70;
|
||||
extrusions_y = steppers_y + 100;
|
||||
|
||||
translate([x3, veroboard_y])
|
||||
veroboard_test();
|
||||
@@ -304,6 +322,9 @@ translate([x3, veroboard_y])
|
||||
translate([x3 + 70, veroboard_y + 30])
|
||||
geared_steppers();
|
||||
|
||||
translate([x3 + 140, veroboard_y + 20])
|
||||
pcb_mounts();
|
||||
|
||||
translate([x3, d_connectors_y])
|
||||
d_connectors();
|
||||
|
||||
@@ -334,16 +355,22 @@ translate([x3, batteries_y])
|
||||
translate([x2, steppers_y]) // interloper
|
||||
stepper_motors();
|
||||
|
||||
translate([x2, extrusions_y]) {
|
||||
extrusions();
|
||||
}
|
||||
|
||||
translate([x3, transformers_y])
|
||||
transformers();
|
||||
|
||||
|
||||
x4 = x3 + 220;
|
||||
belts_y = 0;
|
||||
rails_y = belts_y + 200;
|
||||
cable_strips_y = rails_y + 300;
|
||||
extrusion_brackets_y = rails_y + 250;
|
||||
sk_brackets_y = extrusion_brackets_y + 80;
|
||||
kp_pillow_blocks_y = sk_brackets_y + 50;
|
||||
scs_bearing_blocks_y = kp_pillow_blocks_y + 60;
|
||||
|
||||
translate([x4 + 112, belts_y + 58]) {
|
||||
translate([x4 + 150, belts_y + 58]) {
|
||||
belt_test();
|
||||
|
||||
translate([0, 60])
|
||||
@@ -353,9 +380,21 @@ translate([x4 + 112, belts_y + 58]) {
|
||||
translate([x4, rails_y + 130])
|
||||
rails();
|
||||
|
||||
translate([x4, cable_strips_y])
|
||||
translate([800, fans_y + 50])
|
||||
cable_strips();
|
||||
|
||||
x6 = x5 + 150;
|
||||
translate([x4, kp_pillow_blocks_y])
|
||||
kp_pillow_blocks();
|
||||
|
||||
translate([x4, sk_brackets_y])
|
||||
sk_brackets();
|
||||
|
||||
translate([x4, extrusion_brackets_y])
|
||||
extrusion_brackets();
|
||||
|
||||
translate([x4, scs_bearing_blocks_y])
|
||||
scs_bearing_blocks();
|
||||
|
||||
|
||||
translate([x6, 125])
|
||||
light_strips();
|
||||
|
@@ -31,12 +31,11 @@
|
||||
//!
|
||||
//! Normally the side sheets are the same type but they can be overridden individually as long as the substitute has the same thickness.
|
||||
//
|
||||
include <../core.scad>
|
||||
include <../utils/core/core.scad>
|
||||
use <../vitamins/sheet.scad>
|
||||
use <../vitamins/screw.scad>
|
||||
use <../vitamins/washer.scad>
|
||||
|
||||
include <../vitamins/inserts.scad>
|
||||
use <../vitamins/insert.scad>
|
||||
use <../utils/quadrant.scad>
|
||||
|
||||
bezel_clearance = 0.2;
|
||||
|
@@ -50,6 +50,10 @@ function bbox_name(type) = type[8] ? type[8] : "bbox"; //! Optional name i
|
||||
function bbox_skip_blocks(type)= type[9] ? type[9] : []; //! List of fixing blocks to skip, used to allow a hinged panel for example
|
||||
function star_washers(type) = type[10] ? type[10] : is_undef(type[10]); //! Set to false to remove star washers.
|
||||
|
||||
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
|
||||
2 * (w * d + w * h + d * h) / 1000000;
|
||||
|
||||
module bbox_shelf_blank(type) { //! 2D template for a shelf
|
||||
dxf(str(bbox_name(type), "_shelf"));
|
||||
|
||||
@@ -165,7 +169,7 @@ module bbox_right_blank(type, sheet = false) { //! 2D template for the right sid
|
||||
}
|
||||
}
|
||||
|
||||
module bbox_front_blank(type, sheet = false) { //! 2D template for the front
|
||||
module bbox_front_blank(type, sheet = false, width = 0) { //! 2D template for the front
|
||||
dxf(str(bbox_name(type), "_front"));
|
||||
|
||||
t = sheet_thickness(bbox_sheets(type));
|
||||
@@ -174,7 +178,7 @@ module bbox_front_blank(type, sheet = false) { //! 2D template for the front
|
||||
|
||||
difference() {
|
||||
translate([0, (bt - bb) / 2])
|
||||
sheet_2D(subst_sheet(type, sheet), bbox_width(type) + 2 * t, bbox_height(type) + bb + bt);
|
||||
sheet_2D(subst_sheet(type, sheet), max(bbox_width(type) + 2 * t, width), bbox_height(type) + bb + bt);
|
||||
|
||||
drill_holes(type, rotate([-90, 0, 0]) * translate([0, bbox_depth(type) / 2]));
|
||||
}
|
||||
@@ -205,7 +209,7 @@ module _bbox_assembly(type, top = true, base = true, left = true, right = true,
|
||||
width = bbox_width(type);
|
||||
depth = bbox_depth(type);
|
||||
height = bbox_height(type);
|
||||
echo("Box:", width, depth, height);
|
||||
echo("Box:", width, depth, height, volume = bbox_volume(type), area = bbox_area(type));
|
||||
|
||||
t = sheet_thickness(bbox_sheets(type));
|
||||
bt = sheet_thickness(bbox_base_sheet(type));
|
||||
|
@@ -21,7 +21,7 @@
|
||||
//! Printed cable grommets for passing cables through panels avoiding sharp edges and in the case
|
||||
//! of conductive panels, an extra layer of insulation.
|
||||
//
|
||||
include <../core.scad>
|
||||
include <../utils/core/core.scad>
|
||||
use <../vitamins/cable_strip.scad>
|
||||
|
||||
base = 1.25;
|
||||
@@ -195,12 +195,15 @@ module mouse_grommet_assembly(r, thickness)
|
||||
module ribbon_grommet_20_3_stl() ribbon_grommet(20, 3);
|
||||
module mouse_grommet_15_3_stl() mouse_grommet(1.5, 3);
|
||||
module mouse_grommet_20_3_stl() mouse_grommet(2, 3);
|
||||
module mouse_grommet_25_3_stl() mouse_grommet(2.5, 3);
|
||||
module mouse_grommet_30_3_stl() mouse_grommet(3, 3);
|
||||
|
||||
module round_grommet_bottom_30_stl() round_grommet_bottom(3);
|
||||
module round_grommet_bottom_40_stl() round_grommet_bottom(4);
|
||||
module round_grommet_bottom_50_stl() round_grommet_bottom(5);
|
||||
module round_grommet_bottom_60_stl() round_grommet_bottom(6);
|
||||
|
||||
module round_grommet_top_30_3_stl() round_grommet_top(3, 3);
|
||||
module round_grommet_top_40_3_stl() round_grommet_top(4, 3);
|
||||
module round_grommet_top_50_3_stl() round_grommet_top(5, 3);
|
||||
module round_grommet_top_60_3_stl() round_grommet_top(6, 3);
|
||||
|
@@ -18,11 +18,13 @@
|
||||
//
|
||||
|
||||
//
|
||||
//! Adapts ESP12 module to 0.1" grid. See <https://hydraraptor.blogspot.com/2018/04/esp-12-module-breakout-adaptor.html>.
|
||||
//! Adapts ESP12 modules and various small PCBs to 0.1" grid. See <https://hydraraptor.blogspot.com/2018/04/esp-12-module-breakout-adaptor.html>.
|
||||
//
|
||||
$extrusion_width = 0.5;
|
||||
|
||||
include <../core.scad>
|
||||
include <../utils/core/core.scad>
|
||||
|
||||
function carrier_height() = 3; //! Height of PCB carrier
|
||||
|
||||
module ESP12F_carrier_stl() { //! Generate the STL for an ESP12 carrier
|
||||
stl("ESP12F_carrier");
|
||||
@@ -33,7 +35,7 @@ module ESP12F_carrier_stl() { //! Generate the STL for an ESP12 carrier
|
||||
hole2 = pitch2 - 3 * extrusion_width;
|
||||
length1 = (pins - 1) * pitch1 + hole + squeezed_wall * 2;
|
||||
length2 = (pins - 1) * pitch2 + hole + squeezed_wall * 2;
|
||||
height = 3;
|
||||
height = carrier_height();
|
||||
|
||||
wpitch1 = (pins - 1) * pitch1;
|
||||
wpitch2 = ceil(wpitch1 / 2.54) * 2.54;
|
||||
@@ -61,3 +63,71 @@ module ESP12F_carrier_stl() { //! Generate the STL for an ESP12 carrier
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module TP4056_carrier_stl() { //! Generate the STL for an TP4056 carrier, two required
|
||||
stl("TP4056_carrier");
|
||||
pitch = 2.54;
|
||||
outer_pitch = 13.9;
|
||||
inner_pitch = 7.54;
|
||||
hole = pitch - 3 * extrusion_width;
|
||||
pins = 6;
|
||||
length1 = outer_pitch + hole + squeezed_wall * 2;
|
||||
length2 = (pins - 1) * pitch + hole + squeezed_wall * 2;
|
||||
height = carrier_height();
|
||||
|
||||
width = hole + squeezed_wall * 2;
|
||||
spacing = inch(0.9);
|
||||
|
||||
difference() {
|
||||
hull() {
|
||||
translate_z(height - eps / 2)
|
||||
cube([width, length1, eps], center = true);
|
||||
|
||||
translate_z(eps / 2)
|
||||
cube([width, length2, eps], center = true);
|
||||
}
|
||||
|
||||
for(i = [0 : pins - 1])
|
||||
let(x = [-outer_pitch / 2, - inner_pitch / 2, 0, 0, inner_pitch / 2, outer_pitch / 2][i])
|
||||
if(x)
|
||||
hull() {
|
||||
translate([0, x, height])
|
||||
cube([hole, hole, eps], center = true);
|
||||
|
||||
translate([0, i * pitch - (pins - 1) * pitch / 2])
|
||||
cube([hole, hole, eps], center = true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module MT3608_carrier_stl() { //! Generate the STL for an MT3608 carrier, two required
|
||||
stl("MT3608_carrier");
|
||||
pcb_width = 17;
|
||||
w_pitch_top = 6.81;
|
||||
w_pitch_bot = inch(0.3);
|
||||
l_pitch_top = 30.855;
|
||||
l_pitch_bot = inch(1.2);
|
||||
hole = 1;
|
||||
height = carrier_height();
|
||||
wall = 2 * extrusion_width;
|
||||
width = hole + 2 * wall;
|
||||
offset = (l_pitch_top - l_pitch_bot) / 2;
|
||||
|
||||
difference() {
|
||||
hull() {
|
||||
translate([offset, 0, height - eps / 2])
|
||||
rounded_rectangle([width, pcb_width - 2, eps], 1);
|
||||
|
||||
translate_z(eps / 2)
|
||||
rounded_rectangle([width, pcb_width - 2, eps], 1);
|
||||
}
|
||||
for(side = [-1, 1])
|
||||
hull() {
|
||||
translate([offset, side * w_pitch_top / 2, height])
|
||||
cube([hole, hole, eps], center = true);
|
||||
|
||||
translate([0, side * w_pitch_bot / 2])
|
||||
cube([hole, hole, eps], center = true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -31,8 +31,7 @@
|
||||
//! Star washers can be omitted by setting ```star_washers``` to false.
|
||||
//
|
||||
include <../core.scad>
|
||||
include <../vitamins/screws.scad>
|
||||
include <../vitamins/inserts.scad>
|
||||
use <../vitamins/insert.scad>
|
||||
use <../utils/rounded_cylinder.scad>
|
||||
use <../utils/maths.scad>
|
||||
|
||||
|
@@ -24,7 +24,6 @@
|
||||
//! Rubber door [sealing strip](#sealing_strip) is used to make it airtight and a [door_latch](#door_latch) holds it closed.
|
||||
//
|
||||
include <../core.scad>
|
||||
include <../vitamins/screws.scad>
|
||||
|
||||
width = 18;
|
||||
thickness = 4;
|
||||
@@ -142,7 +141,7 @@ module door_hinge_assembly(top, door_thickness = 6) { //! The moving assembly th
|
||||
|
||||
translate([0, pin_y - (thickness + door_thickness / 2), dir * width / 2]) {
|
||||
rotate([90, 0, 180])
|
||||
color("red") door_hinge(door_thickness);
|
||||
color(pp2_colour) door_hinge(door_thickness);
|
||||
|
||||
rotate([90, 0, 0])
|
||||
door_hinge_hole_positions()
|
||||
@@ -166,7 +165,7 @@ module door_hinge_static_assembly(top, sheet_thickness = 3) { //! The stationary
|
||||
|
||||
translate([pin_x, 0, -dir * (stat_width / 2 + washer_thickness(screw_washer(pin_screw)))])
|
||||
rotate([90, 0, 0]) {
|
||||
color("lime") door_hinge_stat_stl();
|
||||
color(pp1_colour) door_hinge_stat_stl();
|
||||
|
||||
door_hinge_stat_hole_positions() {
|
||||
screw_and_washer(stat_screw, stat_screw_length);
|
||||
|
@@ -22,7 +22,6 @@
|
||||
//
|
||||
include <../core.scad>
|
||||
use <../utils/hanging_hole.scad>
|
||||
include <../vitamins/screws.scad>
|
||||
|
||||
length = 35;
|
||||
width = 12;
|
||||
@@ -66,7 +65,7 @@ module door_latch_assembly(sheet_thickness = 3) { //! The assembly for a specifi
|
||||
|
||||
translate([0, -height - washer_thickness(washer)])
|
||||
rotate([-90, 0, 0]) {
|
||||
color("lime") render() door_latch_stl();
|
||||
color(pp1_colour) render() door_latch_stl();
|
||||
|
||||
translate_z(nut_trap_depth)
|
||||
vflip()
|
||||
|
@@ -31,8 +31,7 @@
|
||||
//! Star washers can be omitted by setting ```star_washers``` to false.
|
||||
//
|
||||
include <../core.scad>
|
||||
include <../vitamins/screws.scad>
|
||||
include <../vitamins/inserts.scad>
|
||||
use <../vitamins/insert.scad>
|
||||
use <../utils/maths.scad>
|
||||
|
||||
def_screw = M3_cap_screw;
|
||||
|
@@ -30,7 +30,6 @@
|
||||
//! This allows the hinges and one set of screws to belong to one assembly and the other set of screws to another assembly.
|
||||
//
|
||||
include <../core.scad>
|
||||
include <../vitamins/screws.scad>
|
||||
|
||||
function hinge_width(type) = type[1]; //! Width
|
||||
function hinge_depth(type) = type[2]; //! Depth of each leaf
|
||||
|
@@ -22,8 +22,7 @@
|
||||
//! inserts don't grip well in rubber.
|
||||
//
|
||||
include <../core.scad>
|
||||
include <../vitamins/screws.scad>
|
||||
include <../vitamins/inserts.scad>
|
||||
use <../vitamins/insert.scad>
|
||||
|
||||
foot = [25, 12, 3, 2, M4_cap_screw, 10];
|
||||
insert_foot = [20, 10, 0, 2, M3_cap_screw, 10];
|
||||
|
@@ -21,8 +21,7 @@
|
||||
//! Printed handle that can be printed without needing support material due to its truncated teardrop profile.
|
||||
//
|
||||
include <../core.scad>
|
||||
include <../vitamins/screws.scad>
|
||||
include <../vitamins/inserts.scad>
|
||||
use <../vitamins/insert.scad>
|
||||
|
||||
dia = 18;
|
||||
length = 90; // inside length
|
||||
|
123
printed/pcb_mount.scad
Normal file
@@ -0,0 +1,123 @@
|
||||
//
|
||||
// NopSCADlib Copyright Chris Palmer 2019
|
||||
// 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/>.
|
||||
//
|
||||
|
||||
//
|
||||
//! A frame to mount a PCB by its corners when it has no mounting holes.
|
||||
//! The stl must be given a parameterless wrapper in the project that uses it.
|
||||
//
|
||||
include <../core.scad>
|
||||
use <../vitamins/pcb.scad>
|
||||
|
||||
clearance = 0.2;
|
||||
min_wall = extrusion_width * 2;
|
||||
wall = 2;
|
||||
|
||||
overlap = 2;
|
||||
|
||||
screw = M3_cap_screw;
|
||||
screw_clearance_r = 3.1 / 2;
|
||||
pillar_r = corrected_radius(screw_clearance_r) + wall;
|
||||
|
||||
function pillar_x_pitch(pcb) = pcb_length(pcb) + 2 * clearance + 2 * (pillar_r - overlap) / sqrt(2); //! x pitch of screw pillars
|
||||
function pillar_y_pitch(pcb) = pcb_width(pcb) + 2 * clearance + 2 * (pillar_r - overlap) / sqrt(2); //! y pitch of screw pillars
|
||||
|
||||
function pcb_mount_length(pcb) = pillar_x_pitch(pcb) + 2 * pillar_r; //! Outside length of the mount
|
||||
function pcb_mount_width(pcb) = pillar_y_pitch(pcb) + 2 * pillar_r; //! Outside width of the mount
|
||||
|
||||
frame_w = 3;
|
||||
frame_t = 2;
|
||||
|
||||
washer_thickness = 1.25;
|
||||
|
||||
module pcb_mount_screw_positions(pcb) //! Positions of the screws and pillars
|
||||
for(x = [-1, 1], y = [-1, 1])
|
||||
translate([x * pillar_x_pitch(pcb) / 2, y * pillar_y_pitch(pcb) / 2])
|
||||
children();
|
||||
|
||||
module pcb_mount_holes(pcb, h = 0) //! Drill holes for PCB mount
|
||||
pcb_mount_screw_positions(pcb)
|
||||
drill(screw_clearance_radius(screw), h);
|
||||
|
||||
module pcb_mount_ring()
|
||||
difference() {
|
||||
circle(pillar_r);
|
||||
|
||||
poly_circle(screw_clearance_r);
|
||||
}
|
||||
|
||||
module pcb_mount_washer_stl() //! A plastic washer to clamp a PCB
|
||||
linear_extrude(height = washer_thickness)
|
||||
pcb_mount_ring();
|
||||
|
||||
module pcb_mount(pcb, height = 5, washers = true) { //! Make the STL of a pcb mount for the specified PCB.
|
||||
stl(str("pcb_mount_", pcb[0], "_", height));
|
||||
|
||||
y_pitch = pcb_width(pcb) > 4 * pillar_r + 4 ? pillar_r + 1
|
||||
: pcb_width(pcb) / 2 + frame_w + 1 + pillar_r;
|
||||
|
||||
if(washers)
|
||||
for(x = [-1, 1], y = [-1, 1])
|
||||
translate([x * (pillar_r + 1), y * y_pitch, 0])
|
||||
pcb_mount_washer_stl();
|
||||
|
||||
for(x = [-1, 1])
|
||||
translate([x * pillar_x_pitch(pcb) / 2, 0, frame_t / 2])
|
||||
cube([frame_w, pillar_y_pitch(pcb) - 2 * wall, frame_t], center = true);
|
||||
|
||||
for(y = [-1, 1])
|
||||
translate([0, y * pillar_y_pitch(pcb) / 2, frame_t / 2])
|
||||
cube([pillar_x_pitch(pcb) - 2 * wall, frame_w, frame_t], center = true);
|
||||
|
||||
pcb_mount_screw_positions(pcb)
|
||||
linear_extrude(height = height)
|
||||
pcb_mount_ring();
|
||||
|
||||
linear_extrude(height = height + pcb_thickness(pcb) - layer_height)
|
||||
difference() {
|
||||
pcb_mount_screw_positions(pcb)
|
||||
pcb_mount_ring();
|
||||
|
||||
square([pcb_length(pcb) + 2 * clearance, pcb_width(pcb) + 2 * clearance], center = true);
|
||||
}
|
||||
}
|
||||
|
||||
module pcb_mount_assembly(pcb, thickness, height = 5) { //! A PCB mount assembly with fasteners
|
||||
translate_z(height)
|
||||
pcb(pcb);
|
||||
|
||||
color(pp1_colour) pcb_mount(pcb, washers = false);
|
||||
|
||||
washer = screw_washer(screw);
|
||||
nut = screw_nut(screw);
|
||||
t = pcb_thickness(pcb);
|
||||
screw_length = screw_longer_than(height + t + washer_thickness + thickness + washer_thickness(washer) + nut_thickness(nut, true));
|
||||
|
||||
pcb_mount_screw_positions(pcb) {
|
||||
translate_z(height + t) {
|
||||
color(pp2_colour) pcb_mount_washer_stl();
|
||||
|
||||
translate_z(washer_thickness)
|
||||
screw(screw, screw_length);
|
||||
}
|
||||
|
||||
translate_z(-thickness)
|
||||
vflip()
|
||||
nut_and_washer(nut, true);
|
||||
}
|
||||
}
|
229
printed/printed_box.scad
Normal file
@@ -0,0 +1,229 @@
|
||||
//
|
||||
// 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/>.
|
||||
//
|
||||
|
||||
//
|
||||
//! A fully parametric 3D printed case that can be customised with cutouts and additions specified by children.
|
||||
//!
|
||||
//! The walls can be made wavy, which possibly reduces warping when printing and looks nice, however if holes need to be made
|
||||
//! in the sides you can't print a wavy bridge. Any holes need to be surrounded by a 45° chamfer to make the bridges straight.
|
||||
//! See the mounting points for the feet in the first example.
|
||||
//!
|
||||
//! It can also have printed feet on the base with the screws doubling up to hold the base on.
|
||||
//
|
||||
include <../core.scad>
|
||||
use <../vitamins/insert.scad>
|
||||
use <foot.scad>
|
||||
|
||||
function pbox_name(type) = type[0]; //! Name to allow more than one box in a project
|
||||
function pbox_wall(type) = type[1]; //! Wall thickness
|
||||
function pbox_top(type) = type[2]; //! Top thickness
|
||||
function pbox_base(type) = type[3]; //! Base thickness, can be zero for no base
|
||||
function pbox_foot(type) = type[4]; //! Printed foot, can be false to suppress feet
|
||||
function pbox_base_screw(type) = type[5]; //! Screw type if no feet
|
||||
function pbox_radius(type) = type[6]; //! Internal corner radius
|
||||
function pbox_ridges(type) = type[7]; //! Ridge wavelength and amplitude
|
||||
function pbox_width(type) = type[8]; //! Internal width
|
||||
function pbox_depth(type) = type[9]; //! Internal depth
|
||||
function pbox_height(type) = type[10]; //! Internal height
|
||||
|
||||
base_outset = 1; // How much the base overlaps the inner dimensions
|
||||
base_overlap = 2; // The width of ledge the base sits on
|
||||
height_overlap = 1; // How far the edges sit below the base
|
||||
|
||||
function pbox_inclusion(type) = pbox_base(type) ? base_overlap - base_outset : 0; //! How far the ledge for the base extends inwards
|
||||
|
||||
function pbox_total_height(type) = //! Total height including base overlap
|
||||
let(base = pbox_base(type),
|
||||
foot = pbox_foot(type),
|
||||
washer = pbox_washer(type),
|
||||
screw = pbox_screw(type))
|
||||
pbox_height(type) + pbox_top(type) + base + (base ? height_overlap : 0) + (foot || !base ? 0 : washer_thickness(washer) + screw_head_height(screw));
|
||||
|
||||
function pbox_screw(type) = //! Foot screw if got feet else base_screw
|
||||
let(foot = pbox_foot(type)) foot ? foot_screw(foot) : pbox_base_screw(type);
|
||||
|
||||
function pbox_insert(type) = screw_insert(pbox_screw(type)); //! The insert for the base screws
|
||||
function pbox_washer(type) = screw_washer(pbox_screw(type)); //! The washer for the base screws
|
||||
|
||||
function pbox_screw_length(type, panel_thickness = 0) = //! Length of the base screw
|
||||
let(foot = pbox_foot(type))
|
||||
screw_shorter_than(pbox_base(type) + washer_thickness(pbox_washer(type))
|
||||
+ insert_length(pbox_insert(type))
|
||||
+ (foot ? foot_thickness(foot) : panel_thickness));
|
||||
|
||||
function pbox_mid_offset(type) = pbox_ridges(type).y + pbox_wall(type) / 2; // Offset to wall midpoint
|
||||
|
||||
function pbox_screw_inset(type) = //! How far the base screws are inset
|
||||
let(foot = pbox_foot(type),
|
||||
r = foot ? foot_diameter(foot) / 2 : washer_radius(pbox_washer(type)),
|
||||
R = pbox_radius(type)
|
||||
) max(r, R - (R - r) / sqrt(2));
|
||||
|
||||
module pbox_screw_positions(type) {
|
||||
foot = pbox_foot(type);
|
||||
inset = pbox_screw_inset(type);
|
||||
for(x = [-1, 1], y = [-1, 1])
|
||||
translate([x * (pbox_width(type) / 2 - inset), y * (pbox_depth(type) / 2 - inset)])
|
||||
rotate((y > 0 ? -x * 45 : -x * 135) + 90)
|
||||
children();
|
||||
}
|
||||
|
||||
module pbox_mid_shape(type) {
|
||||
ridges = pbox_ridges(type);
|
||||
offset = ridges.y + pbox_wall(type) / 2;
|
||||
rad = pbox_radius(type) + offset;
|
||||
w = pbox_width(type) + 2 * offset;
|
||||
d = pbox_depth(type) + 2 * offset;
|
||||
|
||||
module waves(length) {
|
||||
l = length - 2 * rad;
|
||||
|
||||
waves = round(l / ridges.x);
|
||||
points = 16;
|
||||
translate([-l / 2, ridges.y / 2])
|
||||
polygon(concat([[0, -10]], [for(i = [0 : waves * points], a = 360 * i / points) [i * l / waves / points, -cos(a) * ridges.y / 2] ], [[l, -10]]));
|
||||
}
|
||||
|
||||
difference() {
|
||||
rounded_square([w, d], rad, center = true);
|
||||
|
||||
if(ridges.y)
|
||||
for(side = [-1, 1]) {
|
||||
translate([0, side * d / 2])
|
||||
rotate(90 + side * 90)
|
||||
waves(w);
|
||||
|
||||
translate([side * w / 2, 0])
|
||||
rotate(side * 90)
|
||||
waves(d);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module pbox_inner_shape(type) {
|
||||
rad = pbox_radius(type);
|
||||
w = pbox_width(type);
|
||||
d = pbox_depth(type);
|
||||
|
||||
rounded_square([w, d], rad, center = true);
|
||||
}
|
||||
|
||||
module pbox_base(type) { //! Generate the STL for the base
|
||||
stl(str(pbox_name(type),"_base"));
|
||||
t = pbox_base(type);
|
||||
difference() {
|
||||
union() {
|
||||
linear_extrude(height = t)
|
||||
offset(base_outset - 0.2)
|
||||
pbox_inner_shape(type);
|
||||
|
||||
if($children > 0)
|
||||
children(0);
|
||||
}
|
||||
pbox_screw_positions(type)
|
||||
poly_cylinder(r = screw_clearance_radius(pbox_screw(type)), h = 2 * t + eps, center = true);
|
||||
|
||||
if($children > 1)
|
||||
children(1);
|
||||
}
|
||||
}
|
||||
|
||||
module pbox(type) { //! Generate the STL for the main case
|
||||
stl(pbox_name(type));
|
||||
|
||||
height = pbox_height(type);
|
||||
total_height = pbox_total_height(type);
|
||||
top_thickness = pbox_top(type);
|
||||
wall = pbox_wall(type);
|
||||
ledge_outset = pbox_ridges(type).y;
|
||||
ledge_inset = base_outset - base_overlap;
|
||||
ledge_h = pbox_base(type) ? (ledge_outset - ledge_inset) * 2 : 0;
|
||||
|
||||
difference() {
|
||||
union() {
|
||||
linear_extrude(height = total_height)
|
||||
offset(wall / 2) pbox_mid_shape(type);
|
||||
|
||||
if($children > 2)
|
||||
children(2);
|
||||
}
|
||||
difference() {
|
||||
translate_z(top_thickness)
|
||||
union() {
|
||||
linear_extrude(height = height + eps)
|
||||
offset(-wall / 2) pbox_mid_shape(type);
|
||||
|
||||
translate_z(height) // Recess for the base
|
||||
linear_extrude(height = total_height - height)
|
||||
offset(base_outset)
|
||||
pbox_inner_shape(type);
|
||||
}
|
||||
// Ledge to support the lid
|
||||
if(ledge_h)
|
||||
translate_z(top_thickness + height - ledge_h)
|
||||
difference() {
|
||||
rounded_rectangle([pbox_width(type) + 2 * outset, pbox_depth(type) + 2 * outset, ledge_h], 1, center = false);
|
||||
|
||||
hull() {
|
||||
linear_extrude(height = ledge_h + eps)
|
||||
offset(ledge_inset)
|
||||
pbox_inner_shape(type);
|
||||
|
||||
linear_extrude(height = eps)
|
||||
offset(ledge_outset)
|
||||
pbox_inner_shape(type);
|
||||
}
|
||||
pbox_screw_positions(type)
|
||||
insert_hole(pbox_insert(type));
|
||||
}
|
||||
|
||||
// Corner lugs for inserts
|
||||
outset = wall + pbox_ridges(type).y;
|
||||
or = pbox_radius(type) + outset;
|
||||
inset = pbox_screw_inset(type) + outset;
|
||||
br = insert_boss_radius(pbox_insert(type), wall);
|
||||
ext = sqrt(2) * inset - or * (sqrt(2) - 1) - br;
|
||||
translate_z(height + top_thickness)
|
||||
pbox_screw_positions(type)
|
||||
insert_lug(pbox_insert(type), wall, counter_bore = 0, extension = ext, corner_r = or);
|
||||
|
||||
if($children > 0)
|
||||
children(0);
|
||||
}
|
||||
if($children > 1)
|
||||
children(1);
|
||||
}
|
||||
}
|
||||
|
||||
module pbox_inserts(type) //! Place the inserts for the base screws
|
||||
translate_z(pbox_height(type) + pbox_top(type))
|
||||
pbox_screw_positions(type)
|
||||
insert(pbox_insert(type));
|
||||
|
||||
module pbox_base_screws(type, thickness = 0) //! Place the screws and feet
|
||||
translate_z(pbox_height(type) + pbox_top(type) + pbox_base(type))
|
||||
pbox_screw_positions(type) {
|
||||
foot = pbox_foot(type);
|
||||
if(foot)
|
||||
color(pp4_colour)
|
||||
foot(foot);
|
||||
|
||||
translate_z(foot ? foot_thickness(foot) : thickness)
|
||||
screw_and_washer(pbox_screw(type), pbox_screw_length(type, thickness));
|
||||
}
|
@@ -22,8 +22,7 @@
|
||||
//! The stl and assembly must be given a name and parameterless wrappers for the stl and assembly added to the project.
|
||||
//
|
||||
include <../core.scad>
|
||||
include <../vitamins/screws.scad>
|
||||
include <../vitamins/inserts.scad>
|
||||
use <../vitamins/insert.scad>
|
||||
|
||||
use <../vitamins/wire.scad>
|
||||
use <../vitamins/psu.scad>
|
||||
@@ -144,7 +143,7 @@ module psu_shroud(type, cable_d, name, cables = 1) { //! Generate the STL file f
|
||||
}
|
||||
|
||||
module psu_shroud_assembly(type, cable_d, name, cables = 1) //! The printed parts with inserts fitted
|
||||
assembly(str("psu_shroud_", name)) {
|
||||
assembly(str("PSU_shroud_", name)) {
|
||||
|
||||
translate_z(psu_shroud_height(type))
|
||||
vflip()
|
||||
|
@@ -21,8 +21,7 @@
|
||||
//! Clamp for ribbon cable and polypropylene strip.
|
||||
//
|
||||
include <../core.scad>
|
||||
include <../vitamins/screws.scad>
|
||||
include <../vitamins/inserts.scad>
|
||||
use <../vitamins/insert.scad>
|
||||
use <../vitamins/cable_strip.scad>
|
||||
|
||||
wall = 2;
|
||||
|
@@ -21,7 +21,6 @@
|
||||
//! Knob with embedded hex head screw.
|
||||
//
|
||||
include <../core.scad>
|
||||
include <../vitamins/screws.scad>
|
||||
use <../utils/hanging_hole.scad>
|
||||
|
||||
knob_wall = 2;
|
||||
@@ -34,7 +33,7 @@ knob_waves = 5;
|
||||
knob_height = knob_stem_h + knob_thickness;
|
||||
function knob_height() = knob_height;
|
||||
|
||||
module screw_knob(screw) { //! Generate the STL foe a knob to fit the specified hex screw
|
||||
module screw_knob(screw) { //! Generate the STL for a knob to fit the specified hex screw
|
||||
stl(str("screw_knob_M", screw_radius(screw) * 20));
|
||||
|
||||
knob_stem_r = nut_trap_radius(screw_nut(screw)) + knob_wall;
|
||||
|
@@ -22,9 +22,8 @@
|
||||
//
|
||||
include <../core.scad>
|
||||
include <../vitamins/mains_sockets.scad>
|
||||
include <../vitamins/screws.scad>
|
||||
include <../vitamins/inserts.scad>
|
||||
include <../vitamins/ring_terminals.scad>
|
||||
use <../vitamins/insert.scad>
|
||||
|
||||
box_height = 19;
|
||||
base_thickness = 2;
|
||||
@@ -93,7 +92,7 @@ assembly(str("socket_box_", type[0])) {
|
||||
screw = mains_socket_screw(type);
|
||||
insert = screw_insert(screw);
|
||||
|
||||
color("lime") render() socket_box(type);
|
||||
color(pp1_colour) render() socket_box(type);
|
||||
|
||||
mains_socket_hole_positions(type)
|
||||
translate_z(height)
|
||||
|
@@ -19,11 +19,10 @@
|
||||
|
||||
//
|
||||
//! A cover to go over the mains end of an SSR to make it safe to be touched.
|
||||
//! The stl and assembly must be given a name and parameterless wrappers for the stl and assembly added to the project.
|
||||
//! The STL and assembly must be given a name and parameterless wrappers for the stl and assembly added to the project.
|
||||
//
|
||||
include <../core.scad>
|
||||
include <../vitamins/screws.scad>
|
||||
include <../vitamins/inserts.scad>
|
||||
use <../vitamins/insert.scad>
|
||||
|
||||
use <../vitamins/wire.scad>
|
||||
use <../vitamins/ssr.scad>
|
||||
@@ -108,7 +107,7 @@ module ssr_shroud(type, cable_d, name) { //! Generate the STL file for a spec
|
||||
}
|
||||
|
||||
module ssr_shroud_assembly(type, cable_d, name) //! The printed parts with inserts fitted
|
||||
assembly(str("ssr_shroud_", name)) {
|
||||
assembly(str("SSR_shroud_", name)) {
|
||||
|
||||
translate_z(ssr_shroud_height(type))
|
||||
vflip()
|
||||
|
@@ -22,8 +22,7 @@
|
||||
//! be fully customised by passing a list of properties.
|
||||
//
|
||||
include <../core.scad>
|
||||
include <../vitamins/screws.scad>
|
||||
include <../vitamins/inserts.scad>
|
||||
use <../vitamins/insert.scad>
|
||||
|
||||
strap = [18, 2, M3_pan_screw, 3, 25];
|
||||
function strap() = strap;
|
||||
|
@@ -184,10 +184,17 @@ def parse_bom(file = "openscad.log", name = None):
|
||||
main.add_part(s)
|
||||
if stack:
|
||||
main.assemblies[stack[-1]].add_part(s)
|
||||
else:
|
||||
if 'ERROR:' in line or 'WARNING:' in line:
|
||||
print(line[:-1])
|
||||
return main
|
||||
|
||||
def usage():
|
||||
print("\nusage:\n\tbom [target_config] [<accessory_name>_assembly] - Generate BOMs for a project or an accessory to a project.")
|
||||
sys.exit(1)
|
||||
|
||||
def boms(target = None, assembly = None):
|
||||
bom_dir = set_config(target) + "bom"
|
||||
bom_dir = set_config(target, usage) + "bom"
|
||||
if assembly:
|
||||
bom_dir += "/accessories"
|
||||
if not os.path.isdir(bom_dir):
|
||||
@@ -214,7 +221,7 @@ def boms(target = None, assembly = None):
|
||||
#
|
||||
# Run openscad
|
||||
#
|
||||
openscad.run("-D","$bom=2","-D","$preview=true","-o", "openscad.echo", bom_maker_name)
|
||||
openscad.run("-D","$bom=2","-D","$preview=true","-o", "openscad.echo", "-d", bom_dir + "/bom.deps", bom_maker_name)
|
||||
os.remove(bom_maker_name)
|
||||
print("Generating bom ...", end=" ")
|
||||
|
||||
@@ -236,11 +243,24 @@ def boms(target = None, assembly = None):
|
||||
print("done")
|
||||
|
||||
if __name__ == '__main__':
|
||||
args = len(sys.argv)
|
||||
if args > 1:
|
||||
if args > 2:
|
||||
boms(sys.argv[1], sys.argv[2])
|
||||
else:
|
||||
boms(sys.argv[1])
|
||||
if len(sys.argv) > 3: usage()
|
||||
|
||||
if len(sys.argv) == 3:
|
||||
target, assembly = sys.argv[1], sys.argv[2]
|
||||
else:
|
||||
boms();
|
||||
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:
|
||||
if assembly[-9:] != "_assembly": usage()
|
||||
|
||||
try:
|
||||
boms(target, assembly)
|
||||
except Exception as e:
|
||||
print(str(e))
|
||||
sys.exit(1)
|
||||
|
@@ -113,5 +113,5 @@ if __name__ == '__main__':
|
||||
if len(sys.argv) == 2:
|
||||
canonicalise(sys.argv[1])
|
||||
else:
|
||||
print("usage: c14n_stl file")
|
||||
print("\nusage:\n\t c14n_stl file - Canonicalise an STL file created by OpenSCAD.")
|
||||
sys.exit(1)
|
||||
|
@@ -17,6 +17,7 @@
|
||||
# If not, see <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
import os
|
||||
from set_config import source_dir
|
||||
|
||||
def mtime(file):
|
||||
if os.path.isfile(file):
|
||||
@@ -32,7 +33,7 @@ def read_deps(dname):
|
||||
deps = []
|
||||
for line in lines:
|
||||
if line.startswith('\t'):
|
||||
dep = line[1 : -1].rstrip(' \\')
|
||||
dep = line[1 : -1].rstrip(' \\').replace('\\ ', ' ')
|
||||
if not os.path.basename(dep) in ['stl.scad', 'dxf.scad', 'svf.scad', 'png.scad', 'target.scad']:
|
||||
deps.append(dep)
|
||||
return deps
|
||||
@@ -48,3 +49,18 @@ def check_deps(target, dname):
|
||||
if mtime(dep) > target_mtime:
|
||||
return dep + ' changed'
|
||||
return None
|
||||
|
||||
def source_dirs(bom_dir):
|
||||
dirs = set()
|
||||
lib_dirs = set()
|
||||
deps = read_deps(bom_dir + '/bom.deps')
|
||||
cwd = os.getcwd().replace('\\', '/')
|
||||
for dep in deps:
|
||||
dir = os.path.dirname(dep)
|
||||
if dir.startswith(cwd):
|
||||
dirs.add(dir[len(cwd) + 1:])
|
||||
else:
|
||||
if dir.endswith('/printed'):
|
||||
lib_dirs.add(dir)
|
||||
dirs.remove(source_dir)
|
||||
return [source_dir] + sorted(dirs) + sorted(lib_dirs)
|
||||
|
@@ -26,6 +26,7 @@ from __future__ import print_function
|
||||
|
||||
import os
|
||||
from tests import do_cmd
|
||||
import argparse
|
||||
|
||||
dir = 'scripts'
|
||||
|
||||
@@ -40,7 +41,7 @@ These are located in the ```scripts``` subdirectory, which needs to be added to
|
||||
They should work with both Python 2 and Python 3.
|
||||
|
||||
| Script | Function |
|
||||
|:--|:--|''', file = doc_file)
|
||||
|:---|:---|''', file = doc_file)
|
||||
for file in os.listdir('scripts'):
|
||||
if file.endswith('.py'):
|
||||
blurb = ''
|
||||
@@ -74,4 +75,5 @@ They should work with both Python 2 and Python 3.
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
argparse.ArgumentParser(description='Generate scripts/readme.md and make html versions of that and doc/usage.md').parse_args()
|
||||
doc_scripts()
|
||||
|
@@ -30,14 +30,14 @@ import times
|
||||
from deps import *
|
||||
import json
|
||||
|
||||
def bom_to_parts(target_dir, part_type, assembly = None):
|
||||
def bom_to_parts(bom_dir, part_type, assembly = None):
|
||||
#
|
||||
# Make a list of all the parts in the BOM
|
||||
#
|
||||
part_files = []
|
||||
bom = assembly + '.txt' if assembly else "bom.txt"
|
||||
suffix = ".dxf" if part_type == 'svg' else '.' + part_type
|
||||
with open(target_dir + "/../bom/" + bom, "rt") as f:
|
||||
with open(bom_dir + '/' + bom, "rt") as f:
|
||||
for line in f.readlines():
|
||||
words = line.split()
|
||||
if words:
|
||||
@@ -46,13 +46,24 @@ def bom_to_parts(target_dir, part_type, assembly = None):
|
||||
part_files.append(last_word[:-4] + '.' + part_type)
|
||||
return part_files
|
||||
|
||||
def usage(t):
|
||||
print("\nusage:\n\t%ss [target_config] [<name1>.%s] ... [<nameN>.%s] - Generate specified %s files or all if none specified." % ( t, t, t, t.upper()))
|
||||
sys.exit(1)
|
||||
|
||||
def make_parts(target, part_type, parts = None):
|
||||
#
|
||||
# Check list of parts is the correct type
|
||||
#
|
||||
if parts:
|
||||
for p in parts:
|
||||
if not p.endswith('.' + part_type): usage(part_type)
|
||||
#
|
||||
# Make the target directory
|
||||
#
|
||||
top_dir = set_config(target)
|
||||
top_dir = set_config(target, lambda: usage(part_type))
|
||||
target_dir = top_dir + part_type + 's'
|
||||
deps_dir = top_dir + "deps"
|
||||
bom_dir = top_dir + "bom"
|
||||
if not os.path.isdir(target_dir):
|
||||
os.makedirs(target_dir)
|
||||
if not os.path.isdir(deps_dir):
|
||||
@@ -64,7 +75,7 @@ def make_parts(target, part_type, parts = None):
|
||||
if parts:
|
||||
targets = list(parts) #copy the list so we dont modify the list passed in
|
||||
else:
|
||||
targets = bom_to_parts(target_dir, part_type)
|
||||
targets = bom_to_parts(bom_dir, part_type)
|
||||
for file in os.listdir(target_dir):
|
||||
if file.endswith('.' + part_type):
|
||||
if not file in targets:
|
||||
@@ -83,50 +94,49 @@ def make_parts(target, part_type, parts = None):
|
||||
#
|
||||
# Find all the scad files
|
||||
#
|
||||
lib_dir = os.environ['OPENSCADPATH'] + '/NopSCADlib/printed'
|
||||
module_suffix = '_dxf' if part_type == 'svg' else '_' + part_type
|
||||
for dir in [source_dir, lib_dir]:
|
||||
for filename in os.listdir(dir):
|
||||
if filename[-5:] == ".scad":
|
||||
#
|
||||
# find any modules ending in _<part_type>
|
||||
#
|
||||
with open(dir + "/" + filename, "r") as f:
|
||||
for line in f.readlines():
|
||||
words = line.split()
|
||||
if(len(words) and words[0] == "module"):
|
||||
module = words[1].split('(')[0]
|
||||
if module.endswith(module_suffix):
|
||||
base_name = module[:-4]
|
||||
part = base_name + '.' + part_type
|
||||
if part in targets:
|
||||
#
|
||||
# make a file to use the module
|
||||
#
|
||||
part_maker_name = part_type + ".scad"
|
||||
with open(part_maker_name, "w") as f:
|
||||
f.write("use <%s/%s>\n" % (dir, filename))
|
||||
f.write("%s();\n" % module);
|
||||
#
|
||||
# Run openscad on the created file
|
||||
#
|
||||
part_file = target_dir + "/" + part
|
||||
dname = deps_name(deps_dir, filename)
|
||||
changed = check_deps(part_file, dname)
|
||||
changed = times.check_have_time(changed, part)
|
||||
if part_type == 'stl' and not changed and not part in bounds_map:
|
||||
changed = "No bounds"
|
||||
if changed:
|
||||
print(changed)
|
||||
t = time.time()
|
||||
openscad.run("-D$bom=1", "-d", dname, "-o", part_file, part_maker_name)
|
||||
times.add_time(part, t)
|
||||
if part_type == 'stl':
|
||||
bounds = c14n_stl.canonicalise(part_file)
|
||||
bounds_map[part] = bounds
|
||||
|
||||
targets.remove(part)
|
||||
os.remove(part_maker_name)
|
||||
for dir in source_dirs(bom_dir):
|
||||
if targets and os.path.isdir(dir):
|
||||
for filename in os.listdir(dir):
|
||||
if targets and filename[-5:] == ".scad":
|
||||
#
|
||||
# find any modules ending in _<part_type>
|
||||
#
|
||||
with open(dir + "/" + filename, "r") as f:
|
||||
for line in f.readlines():
|
||||
words = line.split()
|
||||
if(len(words) and words[0] == "module"):
|
||||
module = words[1].split('(')[0]
|
||||
if module.endswith(module_suffix):
|
||||
base_name = module[:-4]
|
||||
part = base_name + '.' + part_type
|
||||
if part in targets:
|
||||
#
|
||||
# Run openscad on the created file
|
||||
#
|
||||
part_file = target_dir + "/" + part
|
||||
dname = deps_name(deps_dir, filename)
|
||||
changed = check_deps(part_file, dname)
|
||||
changed = times.check_have_time(changed, part)
|
||||
if part_type == 'stl' and not changed and not part in bounds_map:
|
||||
changed = "No bounds"
|
||||
if changed:
|
||||
print(changed)
|
||||
#
|
||||
# make a file to use the module
|
||||
#
|
||||
part_maker_name = part_type + ".scad"
|
||||
with open(part_maker_name, "w") as f:
|
||||
f.write("use <%s/%s>\n" % (dir, filename))
|
||||
f.write("%s();\n" % module);
|
||||
t = time.time()
|
||||
openscad.run("-D$bom=1", "-d", dname, "-o", part_file, part_maker_name)
|
||||
times.add_time(part, t)
|
||||
if part_type == 'stl':
|
||||
bounds = c14n_stl.canonicalise(part_file)
|
||||
bounds_map[part] = bounds
|
||||
os.remove(part_maker_name)
|
||||
targets.remove(part)
|
||||
#
|
||||
# Write new bounds file
|
||||
#
|
||||
@@ -138,9 +148,6 @@ def make_parts(target, part_type, parts = None):
|
||||
#
|
||||
if targets:
|
||||
for part in targets:
|
||||
if part[-4:] != '.' + part_type:
|
||||
print(part, "is not a", part_type, "file")
|
||||
else:
|
||||
print("Could not find a module called", part[:-4] + module_suffix, "to make", part)
|
||||
sys.exit(1)
|
||||
print("Could not find a module called", part[:-4] + module_suffix, "to make", part)
|
||||
usage(part_type)
|
||||
times.print_times()
|
||||
|
@@ -30,6 +30,7 @@ import re
|
||||
from shutil import copyfile
|
||||
from tests import update_image
|
||||
import sys
|
||||
import argparse
|
||||
|
||||
project_dirs = ['../..', 'examples']
|
||||
target_dir = 'gallery'
|
||||
@@ -39,7 +40,6 @@ def gallery(force):
|
||||
if not os.path.isdir(target_dir):
|
||||
os.makedirs(target_dir)
|
||||
|
||||
|
||||
paths = sorted([pdir + '/' + i for pdir in project_dirs for i in os.listdir(pdir) if os.path.isdir(pdir + '/' + i + '/assemblies')], key = lambda s: os.path.basename(s))
|
||||
with open(output_name, 'wt') as output_file:
|
||||
print("# A gallery of projects made with NopSCADlib", file = output_file)
|
||||
@@ -78,4 +78,8 @@ def gallery(force):
|
||||
|
||||
if __name__ == '__main__':
|
||||
init()
|
||||
gallery(force = len(sys.argv) > 1 and sys.argv[1] == '-f')
|
||||
parser = argparse.ArgumentParser(description='Creates a galley of projects by copying the top level image and description to gallery/readme.md.')
|
||||
parser.add_argument("-f", help = "run make_all in each project to force update", action="store_true")
|
||||
args = parser.parse_args()
|
||||
|
||||
gallery(force = args.f)
|
||||
|
@@ -27,9 +27,17 @@ from bom import boms
|
||||
from render import render
|
||||
from views import views
|
||||
from plateup import plateup
|
||||
from set_config import set_config
|
||||
|
||||
|
||||
def usage():
|
||||
print("\nusage:\n\tmake_all [target_config] - Make all the manufacturing files and readme for a project.")
|
||||
sys.exit(1)
|
||||
|
||||
if __name__ == '__main__':
|
||||
if len(sys.argv) > 2: usage()
|
||||
target = None if len(sys.argv) == 1 else sys.argv[1]
|
||||
set_config(target, usage)
|
||||
boms(target)
|
||||
for part in ['stl', 'dxf']:
|
||||
make_parts(target, part)
|
||||
|
@@ -24,7 +24,7 @@ from __future__ import print_function
|
||||
|
||||
import subprocess, sys
|
||||
|
||||
def _run(args, silent):
|
||||
def run_list(args, silent = False):
|
||||
cmd = ["openscad"] + args
|
||||
if not silent:
|
||||
for arg in cmd:
|
||||
@@ -39,7 +39,7 @@ def _run(args, silent):
|
||||
sys.exit(rc)
|
||||
|
||||
def run(*args):
|
||||
_run(list(args), False)
|
||||
run_list(list(args), False)
|
||||
|
||||
def run_silent(*args):
|
||||
_run(list(args), True);
|
||||
run_list(list(args), True);
|
||||
|
49
scripts/options.py
Normal file
@@ -0,0 +1,49 @@
|
||||
#
|
||||
# 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/>.
|
||||
#
|
||||
|
||||
# Set command line options from enviroment variables and check if they have changed
|
||||
|
||||
import json, os, deps
|
||||
|
||||
def check_options(dir = '.'):
|
||||
global options, options_mtime
|
||||
options = { "show_threads": str(os.getenv("NOPSCADLIB_SHOW_THREADS")) }
|
||||
options_fname = dir + '/options.json'
|
||||
try:
|
||||
with open(options_fname) as json_file:
|
||||
last_options = json.load(json_file)
|
||||
except:
|
||||
last_options = {}
|
||||
if last_options != options:
|
||||
with open(options_fname, 'w') as outfile:
|
||||
json.dump(options, outfile, indent = 4)
|
||||
options_mtime = deps.mtime(options_fname)
|
||||
|
||||
def have_changed(changed, target):
|
||||
if not changed and deps.mtime(target) < options_mtime:
|
||||
return "command line options changed"
|
||||
return changed
|
||||
|
||||
def list():
|
||||
result = []
|
||||
for name in options.keys():
|
||||
value = options[name]
|
||||
if value != 'None':
|
||||
result.append('-D$' + name + '=' + value)
|
||||
return result
|
@@ -25,9 +25,15 @@ import sys
|
||||
|
||||
from plateup import plateup
|
||||
|
||||
def usage():
|
||||
print("\nusage:\n\tpanels [target_config] - Aggregate DXF files for routing together.")
|
||||
sys.exit(1)
|
||||
|
||||
if __name__ == '__main__':
|
||||
if len(sys.argv) > 2: usage()
|
||||
|
||||
if len(sys.argv) > 1:
|
||||
target = sys.argv[1]
|
||||
else:
|
||||
target = None
|
||||
plateup(target, 'dxf')
|
||||
plateup(target, 'dxf', usage)
|
||||
|
@@ -31,11 +31,11 @@ from shutil import copyfile
|
||||
source_dirs = { "stl" : "platters", "dxf" : "panels" }
|
||||
target_dirs = { "stl" : "printed", "dxf" : "routed" }
|
||||
|
||||
def plateup(target, part_type):
|
||||
def plateup(target, part_type, usage = None):
|
||||
#
|
||||
# Make the target directory
|
||||
#
|
||||
top_dir = set_config(target)
|
||||
top_dir = set_config(target, usage)
|
||||
parts_dir = top_dir + part_type + 's'
|
||||
target_dir = parts_dir + '/' + target_dirs[part_type]
|
||||
source_dir = top_dir + source_dirs[part_type]
|
||||
|
@@ -25,9 +25,15 @@ import sys
|
||||
|
||||
from plateup import plateup
|
||||
|
||||
def usage():
|
||||
print("\nusage:\n\tplatters [target_config] - Aggregate STL files for printing together.")
|
||||
sys.exit(1)
|
||||
|
||||
if __name__ == '__main__':
|
||||
if len(sys.argv) > 2: usage()
|
||||
|
||||
if len(sys.argv) > 1:
|
||||
target = sys.argv[1]
|
||||
else:
|
||||
target = None
|
||||
plateup(target, 'stl')
|
||||
plateup(target, 'stl', usage)
|
||||
|
@@ -5,7 +5,7 @@ These are located in the ```scripts``` subdirectory, which needs to be added to
|
||||
They should work with both Python 2 and Python 3.
|
||||
|
||||
| Script | Function |
|
||||
|:--|:--|
|
||||
|:---|:---|
|
||||
| ```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. |
|
||||
| ```doc_scripts.py``` | Makes this document and doc/usage.md. |
|
||||
|
@@ -30,17 +30,23 @@ from tests import do_cmd, update_image, colour_scheme, background
|
||||
from deps import mtime
|
||||
from colorama import init
|
||||
|
||||
def usage():
|
||||
print("\nusage:\n\trender [target_config] - Render images of the stl and dxf files.");
|
||||
sys.exit(1)
|
||||
|
||||
def render(target, type):
|
||||
#
|
||||
# Make the target directory
|
||||
#
|
||||
target_dir = set_config(target) + type + 's'
|
||||
top_dir = set_config(target, usage)
|
||||
target_dir = top_dir + type + 's'
|
||||
bom_dir = top_dir + 'bom'
|
||||
if not os.path.isdir(target_dir):
|
||||
os.makedirs(target_dir)
|
||||
#
|
||||
# Find all the parts
|
||||
#
|
||||
parts = bom_to_parts(target_dir, type)
|
||||
parts = bom_to_parts(bom_dir, type)
|
||||
#
|
||||
# Remove unused png files
|
||||
#
|
||||
@@ -59,7 +65,7 @@ def render(target, type):
|
||||
if mtime(part_file) > mtime(png_name):
|
||||
png_maker_name = "png.scad"
|
||||
with open(png_maker_name, "w") as f:
|
||||
f.write('color("lime") import("%s");\n' % part_file)
|
||||
f.write('color([0, 146/255, 0]) import("%s");\n' % part_file)
|
||||
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' else "--render"
|
||||
tmp_name = 'tmp.png'
|
||||
@@ -71,6 +77,7 @@ def render(target, type):
|
||||
|
||||
if __name__ == '__main__':
|
||||
init()
|
||||
if len(sys.argv) > 2: usage()
|
||||
target = sys.argv[1] if len(sys.argv) > 1 else None
|
||||
render(target, 'stl')
|
||||
render(target, 'dxf')
|
||||
|
@@ -45,20 +45,27 @@ def valid_targets_string():
|
||||
return result
|
||||
|
||||
|
||||
def set_config(target):
|
||||
def set_config(target, usage = None):
|
||||
if target and target[:1] == '-' and usage: usage()
|
||||
targets = valid_targets()
|
||||
if not target:
|
||||
if not targets:
|
||||
return ""
|
||||
print("Must specify a configuration: " + valid_targets_string())
|
||||
if usage:
|
||||
usage()
|
||||
sys.exit(1)
|
||||
|
||||
if not targets:
|
||||
print("Not a muli-configuration project (no config_<target>.scad files found)")
|
||||
if usage:
|
||||
usage()
|
||||
sys.exit(1)
|
||||
|
||||
if not target in targets:
|
||||
print(target + " is not a configuration, avaliable configurations are: " + valid_targets_string())
|
||||
if usage:
|
||||
usage()
|
||||
sys.exit(1)
|
||||
|
||||
fname = source_dir + "/target.scad"
|
||||
@@ -75,10 +82,13 @@ def set_config(target):
|
||||
f. write(text);
|
||||
return target + "/"
|
||||
|
||||
def usage():
|
||||
print("\nusage:\n\tset_config config_name")
|
||||
sys.exit(1)
|
||||
|
||||
if __name__ == '__main__':
|
||||
args = len(sys.argv)
|
||||
if args == 2:
|
||||
set_config(sys.argv[1])
|
||||
set_config(sys.argv[1], usage)
|
||||
else:
|
||||
print("usage: set_config config_name")
|
||||
sys.exit(1)
|
||||
usage()
|
||||
|
@@ -27,6 +27,7 @@ import openscad
|
||||
import subprocess
|
||||
import bom
|
||||
import times
|
||||
import options
|
||||
import time
|
||||
import json
|
||||
import shutil
|
||||
@@ -84,6 +85,10 @@ def depluralise(name):
|
||||
def is_plural(name):
|
||||
return name != depluralise(name)
|
||||
|
||||
def usage():
|
||||
print("\nusage:\n\ttests [test_name1] ... [test_nameN] - Run specified tests or all tests in none specified.");
|
||||
sys.exit(1)
|
||||
|
||||
def tests(tests):
|
||||
scad_dir = "tests"
|
||||
deps_dir = scad_dir + "/deps"
|
||||
@@ -95,7 +100,9 @@ def tests(tests):
|
||||
doc_name = "readme.md"
|
||||
index = {}
|
||||
bodies = {}
|
||||
done = []
|
||||
times.read_times()
|
||||
options.check_options(deps_dir)
|
||||
#
|
||||
# Make cover pic if does not exist as very slow. Delete it to force an update.
|
||||
#
|
||||
@@ -107,13 +114,15 @@ def tests(tests):
|
||||
#
|
||||
# List of individual part files
|
||||
#
|
||||
scads = [i for i in sorted(os.listdir(scad_dir)) if i[-5:] == ".scad"]
|
||||
scads = [i for i in sorted(os.listdir(scad_dir), key = lambda s: s.lower()) if i[-5:] == ".scad"]
|
||||
|
||||
for scad in scads:
|
||||
base_name = scad[:-5]
|
||||
if not tests or base_name in tests:
|
||||
done.append(base_name)
|
||||
print(base_name)
|
||||
cap_name = base_name[0].capitalize() + base_name[1:]
|
||||
base_name = base_name.lower()
|
||||
scad_name = scad_dir + '/' + scad
|
||||
png_name = png_dir + '/' + base_name + '.png'
|
||||
bom_name = bom_dir + '/' + base_name + '.json'
|
||||
@@ -138,11 +147,14 @@ def tests(tests):
|
||||
print("Can't find implementation!")
|
||||
continue
|
||||
|
||||
vsplit = "M"
|
||||
vsplit = "AKR" + chr(ord('Z') + 1)
|
||||
vtype = locations[0][1]
|
||||
types = [vtype + ' A-' + vsplit[0], vtype + ' ' + chr(ord(vsplit) + 1) + '-Z'] + [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:
|
||||
type = types[0] if cap_name[0] <= vsplit else types[1]
|
||||
for i in range(1, len(vsplit)):
|
||||
if cap_name[0] < vsplit[i]:
|
||||
type = types[i - 1]
|
||||
break
|
||||
|
||||
for t in types:
|
||||
if not t in bodies:
|
||||
@@ -186,15 +198,16 @@ def tests(tests):
|
||||
|
||||
body += ["\n" %(base_name, png_name)]
|
||||
|
||||
dname = deps_name(deps_dir, scad)
|
||||
dname = deps_name(deps_dir, scad.lower())
|
||||
oldest = png_name if mtime(png_name) < mtime(bom_name) else bom_name
|
||||
changed = check_deps(oldest, dname)
|
||||
changed = times.check_have_time(changed, scad_name)
|
||||
changed = times.check_have_time(changed, scad_name.lower())
|
||||
changed = options.have_changed(changed, oldest)
|
||||
if changed:
|
||||
print(changed)
|
||||
t = time.time()
|
||||
tmp_name = 'tmp.png'
|
||||
openscad.run("-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(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]);
|
||||
times.add_time(scad_name, t)
|
||||
do_cmd(["magick", tmp_name, "-trim", "-resize", "1000x600", "-bordercolor", background, "-border", "10", tmp_name])
|
||||
update_image(tmp_name, png_name)
|
||||
@@ -227,6 +240,14 @@ def tests(tests):
|
||||
body += ['\n<a href="#top">Top</a>']
|
||||
body += ["\n---"]
|
||||
|
||||
for test in done:
|
||||
if test in tests:
|
||||
tests.remove(test)
|
||||
if tests:
|
||||
for test in tests:
|
||||
print(Fore.MAGENTA + "Could not find a test called", test, Fore.WHITE)
|
||||
usage()
|
||||
|
||||
with open(doc_name, "wt") as doc_file:
|
||||
print('# NopSCADlib', file = doc_file)
|
||||
print('''\
|
||||
@@ -272,4 +293,6 @@ See [usage](docs/usage.md) for requirements, installation instructions and a usa
|
||||
do_cmd('codespell -L od readme.md'.split())
|
||||
|
||||
if __name__ == '__main__':
|
||||
for arg in sys.argv[1:]:
|
||||
if arg[:1] == '-': usage()
|
||||
tests(sys.argv[1:])
|
||||
|
164
scripts/views.py
@@ -28,6 +28,7 @@ import openscad
|
||||
from tests import do_cmd, update_image, colour_scheme, background
|
||||
import time
|
||||
import times
|
||||
import options
|
||||
from deps import *
|
||||
import os
|
||||
import json
|
||||
@@ -70,9 +71,10 @@ def bom_to_assemblies(bom_dir, bounds_map):
|
||||
#
|
||||
# Remove the main assembly if it is a shell
|
||||
#
|
||||
ass = flat_bom[-1]
|
||||
if len(ass["assemblies"]) < 2 and not ass["vitamins"] and not ass["printed"] and not ass["routed"]:
|
||||
flat_bom = flat_bom[:-1]
|
||||
if flat_bom:
|
||||
ass = flat_bom[-1]
|
||||
if len(ass["assemblies"]) < 2 and not ass["vitamins"] and not ass["printed"] and not ass["routed"]:
|
||||
flat_bom = flat_bom[:-1]
|
||||
return [assembly["name"] for assembly in flat_bom]
|
||||
|
||||
def eop(print_mode, doc_file, last = False, first = False):
|
||||
@@ -87,12 +89,24 @@ def eop(print_mode, doc_file, last = False, first = False):
|
||||
def pad(s, before, after = 0):
|
||||
return ' ' * before + str(s) + ' ' * after
|
||||
|
||||
def titalise(name):
|
||||
cap_next = True
|
||||
result = ''
|
||||
for c in name.replace('_', ' '):
|
||||
result = result + (c.upper() if cap_next else c);
|
||||
cap_next = c == ' '
|
||||
return result
|
||||
|
||||
def usage():
|
||||
print("\nusage:\n\t views [target_config] [<name1>_assembly] ... [<nameN>_assembly] - Create assembly images and readme.")
|
||||
sys.exit(1)
|
||||
|
||||
def views(target, do_assemblies = None):
|
||||
done_assemblies = []
|
||||
#
|
||||
# Make the target directory
|
||||
#
|
||||
top_dir = set_config(target)
|
||||
top_dir = set_config(target, usage)
|
||||
target_dir = top_dir + 'assemblies'
|
||||
deps_dir = top_dir + "deps"
|
||||
bom_dir = top_dir + "bom"
|
||||
@@ -102,13 +116,15 @@ def views(target, do_assemblies = None):
|
||||
os.makedirs(deps_dir)
|
||||
|
||||
times.read_times(target_dir)
|
||||
options.check_options(deps_dir)
|
||||
bounds_fname = top_dir + 'stls/bounds.json'
|
||||
with open(bounds_fname) as json_file:
|
||||
bounds_map = json.load(json_file)
|
||||
#
|
||||
# Find all the assemblies
|
||||
# Find all the assemblies and remove any old views
|
||||
#
|
||||
assemblies = bom_to_assemblies(bom_dir, bounds_map)
|
||||
lc_assemblies = [ass.lower() for ass in assemblies]
|
||||
for file in os.listdir(target_dir):
|
||||
if file.endswith('.png'):
|
||||
assembly = file[:-4].replace('_assembled', '_assembly')
|
||||
@@ -121,66 +137,69 @@ def views(target, do_assemblies = None):
|
||||
# Find all the scad files
|
||||
#
|
||||
main_blurb = None
|
||||
lib_dir = os.environ['OPENSCADPATH'] + '/NopSCADlib/printed'
|
||||
for dir in [source_dir, lib_dir]:
|
||||
for filename in os.listdir(dir):
|
||||
if filename.endswith('.scad'):
|
||||
#
|
||||
# find any modules with names ending in _assembly
|
||||
#
|
||||
with open(dir + "/" + filename, "r") as f:
|
||||
lines = f.readlines()
|
||||
line_no = 0
|
||||
for line in lines:
|
||||
words = line.split()
|
||||
if len(words) and words[0] == "module":
|
||||
module = words[1].split('(')[0]
|
||||
if is_assembly(module):
|
||||
if module in assemblies:
|
||||
#
|
||||
# Scrape the assembly instructions
|
||||
#
|
||||
for ass in flat_bom:
|
||||
if ass["name"] == module:
|
||||
if not "blurb" in ass:
|
||||
ass["blurb"] = blurb.scrape_module_blurb(lines[:line_no])
|
||||
break
|
||||
if not do_assemblies or module in do_assemblies:
|
||||
for dir in source_dirs(bom_dir):
|
||||
if os.path.isdir(dir):
|
||||
for filename in os.listdir(dir):
|
||||
if filename.endswith('.scad'):
|
||||
#
|
||||
# find any modules with names ending in _assembly
|
||||
#
|
||||
with open(dir + "/" + filename, "r") as f:
|
||||
lines = f.readlines()
|
||||
line_no = 0
|
||||
for line in lines:
|
||||
words = line.split()
|
||||
if len(words) and words[0] == "module":
|
||||
module = words[1].split('(')[0]
|
||||
if is_assembly(module):
|
||||
lc_module = module.lower()
|
||||
if lc_module in lc_assemblies:
|
||||
real_name = assemblies[lc_assemblies.index(lc_module)]
|
||||
#
|
||||
# make a file to use the module
|
||||
# Scrape the assembly instructions
|
||||
#
|
||||
png_maker_name = 'png.scad'
|
||||
with open(png_maker_name, "w") as f:
|
||||
f.write("use <%s/%s>\n" % (dir, filename))
|
||||
f.write("%s();\n" % module);
|
||||
#
|
||||
# Run openscad on th created file
|
||||
#
|
||||
dname = deps_name(deps_dir, filename)
|
||||
for explode in [0, 1]:
|
||||
png_name = target_dir + '/' + module + '.png'
|
||||
if not explode:
|
||||
png_name = png_name.replace('_assembly', '_assembled')
|
||||
changed = check_deps(png_name, dname)
|
||||
changed = times.check_have_time(changed, png_name)
|
||||
tmp_name = 'tmp.png'
|
||||
if changed:
|
||||
print(changed)
|
||||
t = time.time()
|
||||
openscad.run("-D$pose=1", "-D$explode=%d" % explode, colour_scheme, "--projection=p", "--imgsize=4096,4096", "--autocenter", "--viewall", "-d", dname, "-o", tmp_name, png_maker_name);
|
||||
times.add_time(png_name, t)
|
||||
do_cmd(["magick", tmp_name, "-trim", "-resize", "1004x1004", "-bordercolor", background, "-border", "10", tmp_name])
|
||||
update_image(tmp_name, png_name)
|
||||
tn_name = png_name.replace('.png', '_tn.png')
|
||||
if mtime(png_name) > mtime(tn_name):
|
||||
do_cmd(("magick "+ png_name + " -trim -resize 280x280 -background " + background + " -gravity Center -extent 280x280 -bordercolor " + background + " -border 10 " + tmp_name).split())
|
||||
update_image(tmp_name, tn_name)
|
||||
os.remove(png_maker_name)
|
||||
done_assemblies.append(module)
|
||||
else:
|
||||
if module == 'main_assembly':
|
||||
main_blurb = blurb.scrape_module_blurb(lines[:line_no])
|
||||
line_no += 1
|
||||
for ass in flat_bom:
|
||||
if ass["name"] == real_name:
|
||||
if not "blurb" in ass:
|
||||
ass["blurb"] = blurb.scrape_module_blurb(lines[:line_no])
|
||||
break
|
||||
if not do_assemblies or real_name in do_assemblies:
|
||||
#
|
||||
# Run openscad on the created file
|
||||
#
|
||||
dname = deps_name(deps_dir, filename)
|
||||
for explode in [0, 1]:
|
||||
png_name = target_dir + '/' + real_name + '.png'
|
||||
if not explode:
|
||||
png_name = png_name.replace('_assembly', '_assembled')
|
||||
changed = check_deps(png_name, dname)
|
||||
changed = times.check_have_time(changed, png_name)
|
||||
changed = options.have_changed(changed, png_name)
|
||||
tmp_name = 'tmp.png'
|
||||
if changed:
|
||||
print(changed)
|
||||
#
|
||||
# make a file to use the module
|
||||
#
|
||||
png_maker_name = 'png.scad'
|
||||
with open(png_maker_name, "w") as f:
|
||||
f.write("use <%s/%s>\n" % (dir, filename))
|
||||
f.write("%s();\n" % module);
|
||||
t = time.time()
|
||||
openscad.run_list(options.list() + ["-D$pose=1", "-D$explode=%d" % explode, colour_scheme, "--projection=p", "--imgsize=4096,4096", "--autocenter", "--viewall", "-d", dname, "-o", tmp_name, png_maker_name]);
|
||||
times.add_time(png_name, t)
|
||||
do_cmd(["magick", tmp_name, "-trim", "-resize", "1004x1004", "-bordercolor", background, "-border", "10", tmp_name])
|
||||
update_image(tmp_name, png_name)
|
||||
os.remove(png_maker_name)
|
||||
tn_name = png_name.replace('.png', '_tn.png')
|
||||
if mtime(png_name) > mtime(tn_name):
|
||||
do_cmd(("magick "+ png_name + " -trim -resize 280x280 -background " + background + " -gravity Center -extent 280x280 -bordercolor " + background + " -border 10 " + tmp_name).split())
|
||||
update_image(tmp_name, tn_name)
|
||||
done_assemblies.append(real_name)
|
||||
else:
|
||||
if module == 'main_assembly':
|
||||
main_blurb = blurb.scrape_module_blurb(lines[:line_no])
|
||||
line_no += 1
|
||||
times.print_times()
|
||||
#
|
||||
# Build the document
|
||||
@@ -211,7 +230,7 @@ def views(target, do_assemblies = None):
|
||||
print('1. [Parts list](#Parts_list)', file = doc_file)
|
||||
for ass in flat_bom:
|
||||
name = ass["name"]
|
||||
cap_name = name.replace('_', ' ').title()
|
||||
cap_name = titalise(name)
|
||||
print('1. [%s](#%s)' % (cap_name, name), file = doc_file)
|
||||
print(file = doc_file)
|
||||
eop(print_mode, doc_file)
|
||||
@@ -232,11 +251,11 @@ def views(target, do_assemblies = None):
|
||||
else:
|
||||
things[t][thing] = ass[t][thing]
|
||||
for ass in flat_bom:
|
||||
name = ass["name"][:-9].replace('_', ' ').title().replace(' ',' ')
|
||||
name = titalise(ass["name"][:-9]).replace(' ',' ')
|
||||
print('| <span style="writing-mode: vertical-rl; text-orientation: mixed;">%s</span> ' % name, file = doc_file, end = '')
|
||||
print('| <span style="writing-mode: vertical-rl; text-orientation: mixed;">TOTALS</span> | |', file = doc_file)
|
||||
|
||||
print(('|--:' * len(flat_bom) + '|--:|:--|'), file = doc_file)
|
||||
print(('|---:' * len(flat_bom) + '|---:|:---|'), file = doc_file)
|
||||
|
||||
for t in types:
|
||||
if things[t]:
|
||||
@@ -269,7 +288,7 @@ def views(target, do_assemblies = None):
|
||||
#
|
||||
for ass in flat_bom:
|
||||
name = ass["name"]
|
||||
cap_name = name.replace('_', ' ').title()
|
||||
cap_name = titalise(name)
|
||||
|
||||
if ass["count"] > 1:
|
||||
print('<a name="%s"></a>\n## %d x %s' % (name, ass["count"], cap_name), file = doc_file)
|
||||
@@ -279,7 +298,7 @@ def views(target, do_assemblies = None):
|
||||
if vitamins:
|
||||
print("### Vitamins", file = doc_file)
|
||||
print("|Qty|Description|", file = doc_file)
|
||||
print("|--:|:----------|", file = doc_file)
|
||||
print("|---:|:----------|", file = doc_file)
|
||||
for v in sorted(vitamins, key = lambda s: s.split(":")[-1]):
|
||||
print("|%d|%s|" % (vitamins[v], v.split(":")[1]), file = doc_file)
|
||||
print("\n", file = doc_file)
|
||||
@@ -293,7 +312,7 @@ def views(target, do_assemblies = None):
|
||||
print('%s %d x %s |' % ('\n|' if not (i % 3) else '', printed[p], p), file = doc_file, end = '')
|
||||
if (i % 3) == 2 or i == len(printed) - 1:
|
||||
n = (i % 3) + 1
|
||||
print('\n|%s' % ('--|' * n), file = doc_file)
|
||||
print('\n|%s' % ('---|' * n), file = doc_file)
|
||||
for j in range(n):
|
||||
part = keys[i - n + j + 1]
|
||||
print('|  %s' % (part, part.replace('.stl','.png'), '|\n' if j == j - 1 else ''), end = '', file = doc_file)
|
||||
@@ -309,7 +328,7 @@ def views(target, do_assemblies = None):
|
||||
print('%s %d x %s |' % ('\n|' if not (i % 3) else '', routed[r], r), file = doc_file, end = '')
|
||||
if (i % 3) == 2 or i == len(routed) - 1:
|
||||
n = (i % 3) + 1
|
||||
print('\n|%s' % ('--|' * n), file = doc_file)
|
||||
print('\n|%s' % ('---|' * n), file = doc_file)
|
||||
for j in range(n):
|
||||
part = keys[i - n + j + 1]
|
||||
print('|  %s' % (part, part.replace('.dxf','.png'), '|\n' if j == j - 1 else ''), end = '', file = doc_file)
|
||||
@@ -325,7 +344,7 @@ def views(target, do_assemblies = None):
|
||||
print('%s %d x %s |' % ('\n|' if not (i % 3) else '', sub_assemblies[a], a), file = doc_file, end = '')
|
||||
if (i % 3) == 2 or i == len(keys) - 1:
|
||||
n = (i % 3) + 1
|
||||
print('\n|%s' % ('--|' * n), file = doc_file)
|
||||
print('\n|%s' % ('---|' * n), file = doc_file)
|
||||
for j in range(n):
|
||||
a = keys[i - n + j + 1].replace('_assembly', '_assembled')
|
||||
print('|  %s' % (a, a + '_tn.png', '|\n' if j == j - 1 else ''), end = '', file = doc_file)
|
||||
@@ -380,4 +399,7 @@ if __name__ == '__main__':
|
||||
else:
|
||||
target, assemblies = None, sys.argv[1:]
|
||||
|
||||
for a in assemblies:
|
||||
if a[-9:] != "_assembly": usage()
|
||||
|
||||
views(target, assemblies)
|
||||
|
@@ -21,9 +21,8 @@
|
||||
//! BOM and assembly demonstration
|
||||
//
|
||||
include <../core.scad>
|
||||
include <../vitamins/screws.scad>
|
||||
include <../vitamins/inserts.scad>
|
||||
include <../vitamins/sheets.scad>
|
||||
use <../vitamins/insert.scad>
|
||||
$explode = 1; // Normally set on the command line when generating assembly views with views.py
|
||||
|
||||
screw = M3_cap_screw;
|
@@ -17,10 +17,10 @@
|
||||
// If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
include <../core.scad>
|
||||
use <../utils/layout.scad>
|
||||
|
||||
include <../vitamins/iecs.scad>
|
||||
|
||||
use <../utils/layout.scad>
|
||||
|
||||
module iecs()
|
||||
layout([for(i = iecs) iec_flange_h(i)], 10)
|
||||
rotate(90)
|
33
tests/KP_pillow_blocks.scad
Normal file
@@ -0,0 +1,33 @@
|
||||
//
|
||||
// NopSCADlib Copyright Chris Palmer 2018
|
||||
// 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/kp_pillow_blocks.scad>
|
||||
|
||||
use <../utils/layout.scad>
|
||||
|
||||
module kp_pillow_blocks() {
|
||||
screws = [M4_cap_screw, M4_cap_screw, M5_cap_screw, M5_cap_screw];
|
||||
nuts = [M4_sliding_t_nut, M4_hammer_nut, M5_sliding_t_nut, M5_nut];
|
||||
assert(len(screws) == len(kp_pillow_blocks) && len(nuts) == len(kp_pillow_blocks));
|
||||
layout([for(k = kp_pillow_blocks) 2 * kp_size(k)[1]])
|
||||
kp_pillow_block_assembly(kp_pillow_blocks[$i], screw_type = screws[$i], nut_type = nuts[$i]);
|
||||
}
|
||||
|
||||
if($preview)
|
||||
kp_pillow_blocks();
|
@@ -16,7 +16,7 @@
|
||||
// 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 <../utils/core/core.scad>
|
||||
use <../utils/layout.scad>
|
||||
|
||||
include <../vitamins/leds.scad>
|
111
tests/PCB.scad
Normal file
@@ -0,0 +1,111 @@
|
||||
//
|
||||
// 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/microswitches.scad>
|
||||
include <../vitamins/d_connectors.scad>
|
||||
|
||||
use <../vitamins/pcb.scad>
|
||||
|
||||
gt_5x17 = ["gt_5x17", 5, 10, 17, 5, 11, 0.4, 9, 2,1.5, 1, 3, 6, 0, 0, 0];
|
||||
gt_5x11 = ["gt_5x11", 5, 8, 11, 5, 7, 0.4, 7, 1.5,1.5, 1,2.5, 6, 0, 0, 0];
|
||||
|
||||
TMC2130HeatSinkColor = "DeepSkyBlue";
|
||||
TMC2130 = ["TMC2130", "TMC2130",
|
||||
20, 14, 1.6, 0, 3, 0, "white", false, [],
|
||||
[
|
||||
[ 10, 1, 0, "-2p54header", 8, 1 ,undef, "blue" ],
|
||||
[ 10, 13, 0, "-2p54header", 8, 1],
|
||||
[ 12, 7, 0, "-chip", 6, 4, 1, grey20 ],
|
||||
// mock up a heat sink
|
||||
[ 10, 7, 0, "block", 9, 9, 2, TMC2130HeatSinkColor ],
|
||||
[ 10, 11, 0, "block", 9, 1, 11, TMC2130HeatSinkColor ],
|
||||
[ 10, 9, 0, "block", 9, 1, 11, TMC2130HeatSinkColor ],
|
||||
[ 10, 7, 0, "block", 9, 1, 11, TMC2130HeatSinkColor ],
|
||||
[ 10, 5, 0, "block", 9, 1, 11, TMC2130HeatSinkColor ],
|
||||
[ 10, 3, 0, "block", 9, 1, 11, TMC2130HeatSinkColor ],
|
||||
],
|
||||
[]
|
||||
];
|
||||
|
||||
test_pcb = ["TestPCB", "Test PCB",
|
||||
50, 500, 1.6, // length, width, thickness
|
||||
3, // Corner radius
|
||||
2.75, // Mounting hole diameter
|
||||
6, // Pad around mounting hole
|
||||
"green",// Color
|
||||
false, // True if the parts should be separate BOM items
|
||||
// hole offsets
|
||||
[ [3, 3], [3, -3], [-3, 3], [-3, -3] ],
|
||||
// components
|
||||
[
|
||||
[ 10, 10, 0, "2p54header", 4, 1],
|
||||
[ 25, 10, 0, "2p54header", 5, 1, undef, "blue" ],
|
||||
[ 10, 20, 0, "2p54boxhdr", 4, 2],
|
||||
[ 10, 30, 0, "2p54socket", 6, 1],
|
||||
[ 25, 30, 0, "2p54socket", 4, 1, undef, undef, undef, "red" ],
|
||||
[ 10, 40, 0, "chip", 10, 5, 1, grey20],
|
||||
[ 10, 60, 180, "rj45"],
|
||||
[ 8, 80, 180, "usb_A"],
|
||||
[ 8, 100, 180, "usb_Ax2"],
|
||||
[ 3, 120, 180, "usb_uA"],
|
||||
[ 8, 140, 180, "usb_B"],
|
||||
[ 10, 160, 0, "buzzer"],
|
||||
[ 25, 160, 0, "buzzer", 4.5, 8.5],
|
||||
[ 10, 175, 0, "potentiometer"],
|
||||
[ 30, 175, 0, "potentiometer", 7, 8],
|
||||
[ 8, 190, 180, "jack"],
|
||||
[ 6, 200, 180, "barrel_jack"],
|
||||
[ 5, 220, 180, "hdmi"],
|
||||
[ 3, 240, 180, "mini_hdmi"],
|
||||
[ 10, 250, 0, "flex"],
|
||||
[ 10, 265, 0, "flat_flex"],
|
||||
[ 10, 280, 0, "D_plug", DCONN9],
|
||||
[ 10, 300, 0, "molex_hdr", 2],
|
||||
[ 10, 310, 0, "jst_xh", 2],
|
||||
[ 10, 320, 180, "term254", 3],
|
||||
[ 20, 320, 180, "term254", 3, undef, grey20],
|
||||
[ 10, 340, 180, "gterm35", 4, [1,2]],
|
||||
[ 20, 340, 180, "gterm35", 4, [1,2], "red"],
|
||||
[ 30, 340, 180, "gterm", gt_5x11, 3],
|
||||
[ 10, 360, 180, "gterm635", 2],
|
||||
[ 25, 360, 180, "gterm635", 2, undef, "blue"],
|
||||
[ 40, 360, 180, "gterm", gt_5x17, 2, undef, grey20],
|
||||
[ 40, 340, 180, "gterm", gt_5x17, 3, [1], "red"],
|
||||
[ 10, 380, 180, "term35", 4],
|
||||
[ 20, 380, 180, "term35", 3, "lime"],
|
||||
[ 10, 400, 0, "transition", 5],
|
||||
[ 10, 410, 0, "block", 10, 5, 8, "orange"],
|
||||
[ 10, 420, 0, "button_6mm"],
|
||||
[ 10, 435, 0, "microswitch", small_microswitch],
|
||||
[ 12, 450, 0, "pcb", 11, TMC2130 ],
|
||||
[ 12, 456, 0, "2p54socket", 8, 1 ],
|
||||
[ 12, 444, 0, "2p54socket", 8, 1, undef, undef, undef, "red" ],
|
||||
[ 10, 470, 0, "standoff", 5, 4.5, 12.5, 2.54],
|
||||
[ 6, 480, 180, "uSD", [12, 11.5, 1.4]],
|
||||
[ 20, -5, 180, "trimpot10"],
|
||||
[ 20, -15, 0, "trimpot10", true],
|
||||
],
|
||||
// accessories
|
||||
[]
|
||||
];
|
||||
|
||||
|
||||
if($preview)
|
||||
let($show_threads = true)
|
||||
pcb(test_pcb);
|
35
tests/PCB_mount.scad
Normal file
@@ -0,0 +1,35 @@
|
||||
//
|
||||
// NopSCADlib Copyright Chris Palmer 2019
|
||||
// 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 <../printed/pcb_mount.scad>
|
||||
|
||||
PI_IO = ["PI_IO", "PI_IO V2", 35.56, 25.4, 1.6, 0, 0, 0, "green", true, [],
|
||||
[[(3.015 - 2.7) * 25.4 - 3.5 /2, (4.5 - 3.685) * 25.4, 90, "term35", 2],
|
||||
[(3.46 - 2.7) * 25.4 - 3.5 /2, (4.5 - 3.69) * 25.4, 90, "term35", 2],
|
||||
[(3.91 - 2.7) * 25.4 - 3.5 /2, (4.5 - 3.69) * 25.4, 90, "term35", 2],
|
||||
[(3.4 - 2.7) * 25.4, (4.5 - 4.15) * 25.4, 0, "2p54socket", 13, 2],
|
||||
], []];
|
||||
|
||||
module pcb_mounts()
|
||||
if($preview)
|
||||
pcb_mount_assembly(PI_IO, 3);
|
||||
else
|
||||
pcb_mount(PI_IO);
|
||||
|
||||
pcb_mounts();
|
@@ -17,16 +17,20 @@
|
||||
// If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
include <../core.scad>
|
||||
use <../utils/layout.scad>
|
||||
|
||||
include <../vitamins/d_connectors.scad>
|
||||
include <../vitamins/pcbs.scad>
|
||||
|
||||
module pcbs()
|
||||
use <../utils/layout.scad>
|
||||
|
||||
module pcbs() {
|
||||
layout([for(p = pcbs) pcb_width(p)], 10)
|
||||
translate([0, pcb_length(pcbs[$i]) / 2])
|
||||
rotate(90)
|
||||
pcb_assembly(pcbs[$i], 5 + $i, 3);
|
||||
|
||||
translate([0, 120])
|
||||
layout([for(p = perfboards) pcb_length(p)], 10)
|
||||
translate([0, -pcb_width(perfboards[$i]) / 2])
|
||||
pcb_assembly(perfboards[$i], 5 + $i, 3);
|
||||
}
|
||||
if($preview)
|
||||
pcbs();
|
@@ -17,10 +17,9 @@
|
||||
// If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
include <../core.scad>
|
||||
use <../utils/layout.scad>
|
||||
|
||||
include <../vitamins/screws.scad>
|
||||
include <../vitamins/psus.scad>
|
||||
|
||||
use <../utils/layout.scad>
|
||||
use <../printed/psu_shroud.scad>
|
||||
|
||||
thickness = 3;
|
@@ -17,11 +17,10 @@
|
||||
// If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
include <../core.scad>
|
||||
use <../utils/layout.scad>
|
||||
|
||||
include <../vitamins/screws.scad>
|
||||
include <../vitamins/psus.scad>
|
||||
|
||||
use <../utils/layout.scad>
|
||||
|
||||
module psus()
|
||||
layout([for(p = psus) psu_width(p)], 10) let(p = psus[$i])
|
||||
rotate(atx_psu(p) ? 0 : 90) {
|
35
tests/SCS_bearing_blocks.scad
Normal file
@@ -0,0 +1,35 @@
|
||||
//
|
||||
// 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/scs_bearing_blocks.scad>
|
||||
|
||||
use <../utils/layout.scad>
|
||||
|
||||
module scs_bearing_blocks()
|
||||
layout([for(s = scs_bearing_blocks) scs_size(s).x], 10) {
|
||||
part_thickness = 5;
|
||||
scs_bearing_block_assembly(scs_bearing_blocks[$i], part_thickness);
|
||||
|
||||
if($i > 0) // skip $i==0, since no SCS6LUU long variant to match SCS6UU
|
||||
translate([0, 60])
|
||||
scs_bearing_block_assembly(scs_bearing_blocks_long[$i - 1], part_thickness);
|
||||
}
|
||||
|
||||
if($preview)
|
||||
scs_bearing_blocks();
|
39
tests/SK_brackets.scad
Normal file
@@ -0,0 +1,39 @@
|
||||
//
|
||||
// NopSCADlib Copyright Chris Palmer 2018
|
||||
// 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/sk_brackets.scad>
|
||||
include <../vitamins/extrusions.scad>
|
||||
|
||||
use <../utils/layout.scad>
|
||||
|
||||
module sk_brackets() {
|
||||
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];
|
||||
// channel depth = 6 for 2020 extrusion, 9 for 3030 extrusion
|
||||
depths = [6, 6, 9, 0];
|
||||
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]);
|
||||
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)
|
||||
sk_brackets();
|
@@ -17,10 +17,9 @@
|
||||
// If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
include <../core.scad>
|
||||
use <../utils/layout.scad>
|
||||
|
||||
include <../vitamins/screws.scad>
|
||||
include <../vitamins/ssrs.scad>
|
||||
|
||||
use <../utils/layout.scad>
|
||||
use <../printed/ssr_shroud.scad>
|
||||
|
||||
thickness = 3;
|
@@ -17,11 +17,10 @@
|
||||
// If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
include <../core.scad>
|
||||
use <../utils/layout.scad>
|
||||
|
||||
include <../vitamins/screws.scad>
|
||||
include <../vitamins/ssrs.scad>
|
||||
|
||||
use <../utils/layout.scad>
|
||||
|
||||
module ssrs()
|
||||
layout([for(s = ssrs) ssr_width(s)], 15)
|
||||
rotate(90)
|
@@ -16,7 +16,7 @@
|
||||
// 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 <../utils/core/core.scad>
|
||||
use <../utils/annotation.scad>
|
||||
|
||||
module annotations() {
|
||||
|
@@ -16,10 +16,9 @@
|
||||
// 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 <../utils/core/core.scad>
|
||||
use <../utils/layout.scad>
|
||||
|
||||
include <../vitamins/springs.scad>
|
||||
include <../vitamins/batteries.scad>
|
||||
|
||||
module batteries()
|
||||
|
@@ -18,10 +18,8 @@
|
||||
//
|
||||
include <../core.scad>
|
||||
|
||||
include <../vitamins/belts.scad>
|
||||
include <../vitamins/screws.scad>
|
||||
include <../vitamins/inserts.scad>
|
||||
include <../vitamins/pulleys.scad>
|
||||
use <../vitamins/insert.scad>
|
||||
use <../utils/layout.scad>
|
||||
|
||||
module belt_test() {
|
||||
@@ -67,7 +65,7 @@ module belt_test() {
|
||||
translate([-25, 0])
|
||||
layout([for(b = belts) belt_width(b)], 10)
|
||||
rotate([0, 90, 0])
|
||||
belt(belts[$i], [[0, 0, 20], [0, 1, 20]]);
|
||||
belt(belts[$i], [[0, 0, 20], [0, 1, 20]], belt_colour = $i%2==0 ? grey90 : grey20, tooth_colour = $i%2==0 ? grey70 : grey50);
|
||||
}
|
||||
|
||||
if($preview)
|
||||
|
@@ -16,7 +16,7 @@
|
||||
// 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 <../utils/core/core.scad>
|
||||
use <../utils/bezier.scad>
|
||||
use <../utils/sweep.scad>
|
||||
use <../utils/annotation.scad>
|
||||
|
@@ -19,7 +19,6 @@
|
||||
include <../core.scad>
|
||||
use <../utils/layout.scad>
|
||||
|
||||
include <../vitamins/screws.scad>
|
||||
include <../vitamins/blowers.scad>
|
||||
|
||||
module blowers()
|
||||
|
@@ -18,9 +18,8 @@
|
||||
//
|
||||
include <../core.scad>
|
||||
|
||||
include <../vitamins/screws.scad>
|
||||
include <../vitamins/sheets.scad>
|
||||
include <../vitamins/inserts.scad>
|
||||
use <../vitamins/insert.scad>
|
||||
|
||||
use <../printed/box.scad>
|
||||
|
||||
|
@@ -16,7 +16,7 @@
|
||||
// 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 <../utils/core/core.scad>
|
||||
use <../utils/layout.scad>
|
||||
|
||||
include <../vitamins/bulldogs.scad>
|
||||
|
@@ -18,9 +18,8 @@
|
||||
//
|
||||
include <../core.scad>
|
||||
|
||||
include <../vitamins/screws.scad>
|
||||
include <../vitamins/sheets.scad>
|
||||
include <../vitamins/inserts.scad>
|
||||
use <../vitamins/insert.scad>
|
||||
|
||||
include <../printed/butt_box.scad>
|
||||
|
||||
|
@@ -16,7 +16,7 @@
|
||||
// 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 <../utils/core/core.scad>
|
||||
use <../utils/layout.scad>
|
||||
|
||||
include <../vitamins/buttons.scad>
|
||||
|
@@ -16,7 +16,7 @@
|
||||
// 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 <../utils/core/core.scad>
|
||||
|
||||
use <../printed/cable_grommets.scad>
|
||||
|
||||
|