Compare commits
26 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
f8a9c16360 | ||
|
38988bacfa | ||
|
f26ed7443d | ||
|
453b68aaf9 | ||
|
1ce7b64c73 | ||
|
9230fa78d7 | ||
|
a85c5cfa4b | ||
|
926dd8ca90 | ||
|
2ccfc1b506 | ||
|
fff0e9e3cb | ||
|
43b101ae1e | ||
|
f85fdca051 | ||
|
1fc2be04d5 | ||
|
e3ad32713d | ||
|
82980392c9 | ||
|
3961d7f1a4 | ||
|
1996189ab2 | ||
|
9f8c309643 | ||
|
3995f685dd | ||
|
e2ba69be46 | ||
|
41859ec224 | ||
|
cd95ef95ab | ||
|
7a9e73830e | ||
|
ad82ca21c5 | ||
|
ebe2dfd4fd | ||
|
49cc8333fd |
23
CHANGELOG.md
@@ -3,6 +3,29 @@
|
||||
This changelog is generated by `changelog.py` using manually added semantic version tags to classify commits as breaking changes, additions or fixes.
|
||||
|
||||
|
||||
### [v21.11.0](https://github.com/nophead/NopSCADlib/releases/tag/v21.11.0 "show release") Additions [...](https://github.com/nophead/NopSCADlib/compare/v21.10.1...v21.11.0 "diff with v21.10.1")
|
||||
* 2024-01-14 [`41859ec`](https://github.com/nophead/NopSCADlib/commit/41859ec2245e3fee41cb9c79fb5a627193a4fec8 "show commit") [C.P.](# "Chris Palmer") Added `screw_thread_radius()` and `screw_angle()` functions.
|
||||
|
||||
* 2024-01-14 [`cd95ef9`](https://github.com/nophead/NopSCADlib/commit/cd95ef95abed30e4004905972c9abcacdad0dc5e "show commit") [C.P.](# "Chris Palmer") Added GT2x12, GT3x6, GT3x9 and GT3x12 belts.
|
||||
|
||||
* 2024-01-12 [`7a9e738`](https://github.com/nophead/NopSCADlib/commit/7a9e73830e16a843a14debb8d9b770243067cf63 "show commit") [C.P.](# "Chris Palmer") Belt part number is not always the same as the pitch.
|
||||
|
||||
#### [v21.10.1](https://github.com/nophead/NopSCADlib/releases/tag/v21.10.1 "show release") Fixes [...](https://github.com/nophead/NopSCADlib/compare/v21.10.0...v21.10.1 "diff with v21.10.0")
|
||||
* 2023-12-01 [`ebe2dfd`](https://github.com/nophead/NopSCADlib/commit/ebe2dfd4fd8ba042b634030f7d463d0ba0d8c4cd "show commit") [C.P.](# "Chris Palmer") Fixed explode line position on short inserts.
|
||||
|
||||
### [v21.10.0](https://github.com/nophead/NopSCADlib/releases/tag/v21.10.0 "show release") Additions [...](https://github.com/nophead/NopSCADlib/compare/v21.9.1...v21.10.0 "diff with v21.9.1")
|
||||
* 2023-11-27 [`0137a43`](https://github.com/nophead/NopSCADlib/commit/0137a43a638777ecdf6b311579006c0922650a9c "show commit") [C.P.](# "Chris Palmer") Updated images and readme.
|
||||
|
||||
* 2023-11-12 [`72e5d1a`](https://github.com/nophead/NopSCADlib/commit/72e5d1abfb744ddcdf665b02ba7a1cf2b6bcff38 "show commit") [X.](# "XrXca") Update `pcbs.scad`
|
||||
|
||||
* Update `pcbs.scad`
|
||||
|
||||
* Update `pcbs.scad`
|
||||
|
||||
* Update `pcbs.scad`
|
||||
|
||||
* 2023-11-27 [`b5afd7b`](https://github.com/nophead/NopSCADlib/commit/b5afd7bd41a1a46b7a1745c30755b3fb6c25b9a1 "show commit") [C.P.](# "Chris Palmer") ESP-01M added.
|
||||
|
||||
#### [v21.9.1](https://github.com/nophead/NopSCADlib/releases/tag/v21.9.1 "show release") Fixes [...](https://github.com/nophead/NopSCADlib/compare/v21.9.0...v21.9.1 "diff with v21.9.0")
|
||||
* 2023-11-26 [`b9d1017`](https://github.com/nophead/NopSCADlib/commit/b9d101749eb2b19963299d85b75f0fa489fba552 "show commit") [C.P.](# "Chris Palmer") Updated images due to pixel differences on new PC
|
||||
|
||||
|
BIN
libtest.png
Before Width: | Height: | Size: 966 KiB After Width: | Height: | Size: 976 KiB |
@@ -482,7 +482,7 @@ cable_strip_y = sheets_y + 30;
|
||||
translate([0, transformers_y])
|
||||
servo_motors();
|
||||
|
||||
translate([x4 + 200, belts_y + 58]) {
|
||||
translate([x4 + 200 + 16, belts_y + 58]) {
|
||||
belt_test();
|
||||
|
||||
translate([0, 60])
|
||||
|
49
readme.md
@@ -437,10 +437,14 @@ Individual teeth are not drawn, instead they are represented by a lighter colour
|
||||
### Vitamins
|
||||
| Qty | Module call | BOM entry |
|
||||
| ---:|:--- |:---|
|
||||
| 1 | `belt(GT2x12, [ ... ])` | Belt GT2 x 12mm x 128mm |
|
||||
| 1 | `belt(GT2x6, [ ... ])` | Belt GT2 x 6mm x 128mm |
|
||||
| 1 | `belt(GT2x6, [ ... ])` | Belt GT2 x 6mm x 552mm |
|
||||
| 2 | `belt(GT2x6, [ ... ])` | Belt GT2 x 6mm x 556mm |
|
||||
| 1 | `belt(GT2x6, [ ... ])` | Belt GT2 x 6mm x 584mm |
|
||||
| 2 | `belt(GT2x6, [ ... ])` | Belt GT2 x 6mm x 588mm |
|
||||
| 1 | `belt(GT2x9, [ ... ])` | Belt GT2 x 9mm x 128mm |
|
||||
| 1 | `belt(GT3x12, [ ... ])` | Belt GT3 x 12mm x 128mm |
|
||||
| 1 | `belt(GT3x6, [ ... ])` | Belt GT3 x 6mm x 128mm |
|
||||
| 1 | `belt(GT3x9, [ ... ])` | Belt GT3 x 9mm x 128mm |
|
||||
| 1 | `belt(T2p5x6, [ ... ])` | Belt T2.5 x 6mm x 130mm |
|
||||
| 1 | `belt(T5x10, [ ... ])` | Belt T5 x 10mm x 130mm |
|
||||
| 1 | `belt(T5x6, [ ... ])` | Belt T5 x 6mm x 130mm |
|
||||
@@ -1087,6 +1091,7 @@ LCD displays.
|
||||
| 1 | `display(HDMI5)` | HDMI display 5" |
|
||||
| 1 | `display(TFT128x160)` | LCD TFT ST7735 display 128x160 |
|
||||
| 1 | `display(LCD1602A)` | LCD display 1602A |
|
||||
| 1 | `display(LCD2004A)` | LCD display 2004A |
|
||||
| 1 | `display(LCDS7282B)` | LCD display S-7282B |
|
||||
| 1 | `display(SSD1963_4p3)` | LCD display SSD1963 4.3" |
|
||||
|
||||
@@ -2844,6 +2849,7 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
|
||||
| 1 | `pcb(ESP32_DOIT_V1)` | ESP32 DOIT DEV KIT V1 |
|
||||
| 1 | `pcb(EnviroPlus)` | Enviro+ |
|
||||
| 1 | `pcb(ExtruderPCB)` | Extruder connection PCB - not shown |
|
||||
| 1 | `pcb(HW803_1WAY_RELAY)` | HW-803 5V 1 way relay module |
|
||||
| 1 | `pcb(KY_040)` | KY-040 rotart encoder breakout |
|
||||
| 1 | `pcb(Keyes5p1)` | Keyes5.1 Arduino Uno expansion board - not shown |
|
||||
| 1 | `pcb(L9110S)` | L9110S 2-Channel motor driver module |
|
||||
@@ -2857,7 +2863,7 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
|
||||
| 1 | `molex_254(3)` | Molex KK header 3 way - not shown |
|
||||
| 20 | `nut(M2_nut, nyloc = true)` | Nut M2 x 1.6mm nyloc |
|
||||
| 38 | `nut(M2p5_nut, nyloc = true)` | Nut M2.5 x 2.2mm nyloc |
|
||||
| 43 | `nut(M3_nut, nyloc = true)` | Nut M3 x 2.4mm nyloc |
|
||||
| 47 | `nut(M3_nut, nyloc = true)` | Nut M3 x 2.4mm nyloc |
|
||||
| 8 | `nut(M4_nut, nyloc = true)` | Nut M4 x 3.2mm nyloc |
|
||||
| 1 | `pcb(OPZ2)` | Orange Pi Zero 2 |
|
||||
| 1 | `pcb(PI_IO)` | PI_IO V2 - not shown |
|
||||
@@ -2880,14 +2886,17 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
|
||||
| 8 | `screw(M2_cap_screw, 20)` | Screw M2 cap x 20mm |
|
||||
| 4 | `screw(M2_cap_screw, 25)` | Screw M2 cap x 25mm |
|
||||
| 2 | `screw(M2p5_cap_screw, 20)` | Screw M2.5 cap x 20mm |
|
||||
| 8 | `screw(M2p5_cap_screw, 25)` | Screw M2.5 cap x 25mm |
|
||||
| 4 | `screw(M2p5_cap_screw, 25)` | Screw M2.5 cap x 25mm |
|
||||
| 4 | `screw(M2p5_cap_screw, 30)` | Screw M2.5 cap x 30mm |
|
||||
| 12 | `screw(M2p5_cap_screw, 35)` | Screw M2.5 cap x 35mm |
|
||||
| 4 | `screw(M2p5_dome_screw, 25)` | Screw M2.5 dome x 25mm |
|
||||
| 4 | `screw(M2p5_pan_screw, 20)` | Screw M2.5 pan x 20mm |
|
||||
| 8 | `screw(M2p5_pan_screw, 30)` | Screw M2.5 pan x 30mm |
|
||||
| 19 | `screw(M3_cap_screw, 16)` | Screw M3 cap x 16mm |
|
||||
| 13 | `screw(M3_cap_screw, 20)` | Screw M3 cap x 20mm |
|
||||
| 11 | `screw(M3_cap_screw, 30)` | Screw M3 cap x 30mm |
|
||||
| 4 | `screw(M3_cap_screw, 25)` | Screw M3 cap x 25mm |
|
||||
| 8 | `screw(M3_cap_screw, 30)` | Screw M3 cap x 30mm |
|
||||
| 3 | `screw(M3_cap_screw, 35)` | Screw M3 cap x 35mm |
|
||||
| 4 | `screw(M4_cap_screw, 20)` | Screw M4 cap x 20mm |
|
||||
| 4 | `screw(M4_cap_screw, 25)` | Screw M4 cap x 25mm |
|
||||
| 1 | `pcb(XIAO)` | Seeeduino XIAO |
|
||||
@@ -2899,7 +2908,7 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
|
||||
| 1 | `pcb(WD2002SJ)` | WD2002SJ Buck Boost DC-DC converter |
|
||||
| 20 | `washer(M2_washer)` | Washer M2 x 5mm x 0.3mm |
|
||||
| 38 | `washer(M2p5_washer)` | Washer M2.5 x 5.9mm x 0.5mm |
|
||||
| 43 | `washer(M3_washer)` | Washer M3 x 7mm x 0.5mm |
|
||||
| 47 | `washer(M3_washer)` | Washer M3 x 7mm x 0.5mm |
|
||||
| 8 | `washer(M4_washer)` | Washer M4 x 9mm x 0.8mm |
|
||||
| 1 | `pcb(ZC_A0591)` | ZC-A0591 ULN2003 driver PCB |
|
||||
|
||||
@@ -2907,23 +2916,24 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
|
||||
| Qty | Filename |
|
||||
| ---:|:--- |
|
||||
| 4 | pcb_spacer20100.stl |
|
||||
| 4 | pcb_spacer20130.stl |
|
||||
| 4 | pcb_spacer20140.stl |
|
||||
| 4 | pcb_spacer2070.stl |
|
||||
| 4 | pcb_spacer2080.stl |
|
||||
| 4 | pcb_spacer2090.stl |
|
||||
| 4 | pcb_spacer25120.stl |
|
||||
| 4 | pcb_spacer25150.stl |
|
||||
| 2 | pcb_spacer25100.stl |
|
||||
| 4 | pcb_spacer25130.stl |
|
||||
| 4 | pcb_spacer25160.stl |
|
||||
| 4 | pcb_spacer25170_2.stl |
|
||||
| 4 | pcb_spacer25170.stl |
|
||||
| 4 | pcb_spacer25180_2.stl |
|
||||
| 4 | pcb_spacer25220.stl |
|
||||
| 4 | pcb_spacer25190_2.stl |
|
||||
| 4 | pcb_spacer25230.stl |
|
||||
| 4 | pcb_spacer25240.stl |
|
||||
| 4 | pcb_spacer25250.stl |
|
||||
| 4 | pcb_spacer2580.stl |
|
||||
| 2 | pcb_spacer2590.stl |
|
||||
| 4 | pcb_spacer30190.stl |
|
||||
| 4 | pcb_spacer30120.stl |
|
||||
| 4 | pcb_spacer30200.stl |
|
||||
| 3 | pcb_spacer30210.stl |
|
||||
| 4 | pcb_spacer30210.stl |
|
||||
| 3 | pcb_spacer30220.stl |
|
||||
| 10 | pcb_spacer3050.stl |
|
||||
| 9 | pcb_spacer3060.stl |
|
||||
| 9 | pcb_spacer3070.stl |
|
||||
@@ -3750,6 +3760,7 @@ For an explanation of `screw_polysink()` see <https://hydraraptor.blogspot.com/2
|
||||
### Functions
|
||||
| Function | Description |
|
||||
|:--- |:--- |
|
||||
| `screw_angle(type, length, nut_distance)` | How much to rotate the screw to align it with a nut at the specified `distance` from the head |
|
||||
| `screw_boss_diameter(type)` | Boss big enough for nut trap and washer |
|
||||
| `screw_head_depth(type, d = 0)` | How far a counter sink head will go into a straight hole diameter d |
|
||||
| `screw_insert(screw, short = false, i = 0)` | Find insert to fit specified screw, defaults to longest but can specify the shortest |
|
||||
@@ -3758,6 +3769,7 @@ For an explanation of `screw_polysink()` see <https://hydraraptor.blogspot.com/2
|
||||
| `screw_nut_radius(type)` | Radius of matching nut |
|
||||
| `screw_polysink_r(type, z)` | Countersink hole profile corrected for rounded staircase extrusions. |
|
||||
| `screw_shorter_than(x)` | Returns the length of the longest screw shorter than or equal to x |
|
||||
| `screw_thread_radius(type)` | Thread radius |
|
||||
|
||||
### Modules
|
||||
| Module | Description |
|
||||
@@ -4006,6 +4018,8 @@ When woven sheets (e.g. carbon fibre) are rendered it is necessary to specify th
|
||||
| 1 | `sheet(MDF10, 30, 30, 2)` | Sheet MDF 30mm x 30mm x 10mm |
|
||||
| 1 | `sheet(MDF12, 30, 30, 2)` | Sheet MDF 30mm x 30mm x 12mm |
|
||||
| 1 | `sheet(MDF19, 30, 30, 2)` | Sheet MDF 30mm x 30mm x 19mm |
|
||||
| 1 | `sheet(MDF22, 30, 30, 2)` | Sheet MDF 30mm x 30mm x 22mm |
|
||||
| 1 | `sheet(MDF3, 30, 30, 2)` | Sheet MDF 30mm x 30mm x 3mm |
|
||||
| 1 | `sheet(MDF6, 30, 30, 2)` | Sheet MDF 30mm x 30mm x 6mm |
|
||||
| 1 | `sheet(PMMA1p25, 30, 30, 2)` | Sheet acrylic 30mm x 30mm x 1.25mm |
|
||||
| 1 | `sheet(PMMA10, 30, 30, 2)` | Sheet acrylic 30mm x 30mm x 10mm |
|
||||
@@ -7430,7 +7444,7 @@ This is to prevent the global BOM page becoming too wide in large projects by ha
|
||||
The example below shows how to define a vitamin and incorporate it into an assembly with sub-assemblies and make an exploded view.
|
||||
The resulting flat BOM is shown but hierarchical BOMs are also generated for real projects.
|
||||
|
||||
If the code to make an STL or DXF is made a child of the `stl()` or `dxf()` module then the STL or DXF will be used in the assembly views generated by `views.py` instead of generating
|
||||
If the code to make an STL, DXF or SVG is made a child of the `stl()`, `dxf()` or `svg()` module then the STL, DXF or SVG will be used in the assembly views generated by `views.py` instead of generating
|
||||
it with code.
|
||||
This can speed up the generation of the build instructions greatly but isn't compatible with STLs that include support structures.
|
||||
|
||||
@@ -7469,8 +7483,10 @@ The `pose()` module allows assembly views in the readme to be posed differently
|
||||
| `pose_vflip(exploded = undef)` | Pose an STL or assembly for rendering to png by flipping around the X axis, `exploded = true for` just the exploded view or `false` for unexploded only. |
|
||||
| `stl(name)` | Name an stl that will appear on the BOM, there needs to a module named `<name>_stl` to make it |
|
||||
| `stl_colour(colour = pp1_colour, alpha = 1)` | Colour an stl where it is placed in an assembly. `alpha` can be used to make it appear transparent. |
|
||||
| `svg(name)` | Name an svg that will appear on the BOM, there needs to a module named `<name>_svg` to make it |
|
||||
| `use_dxf(name)` | Import a DXF to make a build panel |
|
||||
| `use_stl(name)` | Import an STL to make a build platter |
|
||||
| `use_svg(name)` | Import an SVG to make a build panel |
|
||||
| `vitamin(description)` | Describe a vitamin for the BOM entry and precede it with a module call that creates it, eg. "widget(42): Widget size 42" |
|
||||
|
||||

|
||||
@@ -7481,6 +7497,8 @@ The `pose()` module allows assembly views in the readme to be posed differently
|
||||
| 1 | `insert(F1BM3)` | Heatfit insert M3 x 5.8mm |
|
||||
| 1 | `widget(3)` | Rivet like thing for 3mm sheets |
|
||||
| 1 | `screw(M3_cap_screw, 8)` | Screw M3 cap x 8mm |
|
||||
| 4 | `screw(M3_cap_screw, 10)` | Screw M3 cap x 10mm |
|
||||
| 1 | `sheet(MDF6, 40, 40)` | Sheet MDF 40mm x 40mm x 6mm |
|
||||
| 1 | `sheet(PMMA3, 20, 20, 1)` | Sheet acrylic 20mm x 20mm x 3mm |
|
||||
| 1 | `washer(M3_washer)` | Washer M3 x 7mm x 0.5mm |
|
||||
| 1 | `star_washer(M3_washer)` | Washer star M3 x 0.5mm |
|
||||
@@ -7493,6 +7511,7 @@ The `pose()` module allows assembly views in the readme to be posed differently
|
||||
### Routed
|
||||
| Qty | Filename |
|
||||
| ---:|:--- |
|
||||
| 1 | mdf.svg |
|
||||
| 1 | widget.dxf |
|
||||
|
||||
### Assemblies
|
||||
|
@@ -104,14 +104,14 @@ class BOM:
|
||||
|
||||
def add_part(self, s):
|
||||
args = []
|
||||
match = re.match(r'^(.*?\.stl|.*?\.dxf)\((.*)\)$', s) #look for name.stl(...) or name.dxf(...)
|
||||
match = re.match(r'^(.*?\.stl|.*?\.dxf|.*?\.svg)\((.*)\)$', s) #look for name.stl(...), name.dxf(...) or name.svg(...)
|
||||
if match:
|
||||
s = match.group(1)
|
||||
args = [match.group(2)]
|
||||
if s[-4:] == ".stl":
|
||||
parts = self.printed
|
||||
else:
|
||||
if s[-4:] == ".dxf":
|
||||
if s[-4:] == ".dxf" or s[-4:] == ".svg":
|
||||
parts = self.routed
|
||||
else:
|
||||
parts = self.vitamins
|
||||
|
@@ -35,7 +35,7 @@ def read_deps(dname):
|
||||
for line in lines:
|
||||
if line.startswith('\t'):
|
||||
dep = line[1 : -1].rstrip(' \\').replace('\\ ', ' ')
|
||||
if not os.path.basename(dep) in ['stl.scad', 'dxf.scad', 'svf.scad', 'png.scad', 'target.scad']:
|
||||
if not os.path.basename(dep) in ['stl.scad', 'dxf.scad', 'svg.scad', 'png.scad', 'target.scad']:
|
||||
deps.append(dep)
|
||||
return deps
|
||||
|
||||
|
@@ -39,7 +39,7 @@ def bom_to_parts(bom_dir, part_type, assembly = None):
|
||||
#
|
||||
part_files = []
|
||||
bom = assembly + '.txt' if assembly else "bom.txt"
|
||||
suffix = ".dxf" if part_type == 'svg' else '.' + part_type
|
||||
suffix = '.' + part_type
|
||||
with open(bom_dir + '/' + bom, "rt") as f:
|
||||
for line in f.readlines():
|
||||
words = line.split()
|
||||
@@ -106,7 +106,7 @@ def make_parts(target, part_type, parts = None):
|
||||
#
|
||||
# Find all the scad files
|
||||
#
|
||||
module_suffix = '_dxf' if part_type == 'svg' else '_' + part_type
|
||||
module_suffix = '_' + part_type
|
||||
for dir in source_dirs(bom_dir):
|
||||
if targets and os.path.isdir(dir):
|
||||
for filename in os.listdir(dir):
|
||||
@@ -141,7 +141,7 @@ def make_parts(target, part_type, parts = None):
|
||||
with open(part_maker_name, "w") as f:
|
||||
f.write("include <NopSCADlib/global_defs.scad>\n")
|
||||
f.write("use <%s/%s>\n" % (reltmp(dir, target), filename))
|
||||
f.write("%s();\n" % module);
|
||||
f.write("%s();\n" % module)
|
||||
t = time.time()
|
||||
openscad.run("-o", part_file, part_maker_name, "-D$bom=1", "-d", dname)
|
||||
times.add_time(part, t)
|
||||
|
@@ -39,7 +39,7 @@ if __name__ == '__main__':
|
||||
target = None if len(sys.argv) == 1 else sys.argv[1]
|
||||
set_config(target, usage)
|
||||
boms(target)
|
||||
for part in ['stl', 'dxf']:
|
||||
for part in ['stl', 'dxf', 'svg']:
|
||||
make_parts(target, part)
|
||||
render(target, part)
|
||||
plateup(target, part)
|
||||
|
@@ -31,8 +31,8 @@ import re
|
||||
import time
|
||||
import times
|
||||
|
||||
source_dirs = { "stl" : "platters", "dxf" : "panels" }
|
||||
target_dirs = { "stl" : "printed", "dxf" : "routed" }
|
||||
source_dirs = { "stl" : "platters", "dxf" : "panels", "svg" : "panels" }
|
||||
target_dirs = { "stl" : "printed", "dxf" : "routed", "svg" : "routed" }
|
||||
|
||||
def plateup(target, part_type, usage = None):
|
||||
#
|
||||
|
@@ -33,7 +33,7 @@ import json
|
||||
from tmpdir import *
|
||||
|
||||
def usage():
|
||||
print("\nusage:\n\trender [target_config] - Render images of the stl and dxf files.");
|
||||
print("\nusage:\n\trender [target_config] - Render images of the stl, dxf and svg files.");
|
||||
sys.exit(1)
|
||||
|
||||
def render(target, type):
|
||||
@@ -57,7 +57,7 @@ def render(target, type):
|
||||
with open(bom_file) as json_file:
|
||||
flat_bom = json.load(json_file)
|
||||
|
||||
things = { 'stl' : 'printed', 'dxf' : 'routed' }[type]
|
||||
things = { 'stl' : 'printed', 'dxf' : 'routed', 'svg' : 'routed' }[type]
|
||||
colours = {}
|
||||
for ass in flat_bom:
|
||||
for part in ass[things]:
|
||||
@@ -112,3 +112,4 @@ if __name__ == '__main__':
|
||||
target = sys.argv[1] if len(sys.argv) > 1 else None
|
||||
render(target, 'stl')
|
||||
render(target, 'dxf')
|
||||
render(target, 'svg')
|
||||
|
@@ -374,7 +374,12 @@ def views(target, do_assemblies = None):
|
||||
print('\n|%s' % ('---|' * n), file = doc_file)
|
||||
for j in range(n):
|
||||
part = keys[i - n + j + 1]
|
||||
print('|  %s' % (part, part.replace('.dxf','.png'), '|\n' if j == j - 1 else ''), end = '', file = doc_file)
|
||||
if (part[-4:] == ".dxf"):
|
||||
print('|  %s' % (part, part.replace('.dxf','.png'), '|\n' if j == j - 1 else ''), end = '', file = doc_file)
|
||||
elif (part[-4:] == ".svg"):
|
||||
print('|  %s' % (part, part.replace('.svg','.png'), '|\n' if j == j - 1 else ''), end = '', file = doc_file)
|
||||
else:
|
||||
print("Unkown file type ", part[-4:], " for file ", part)
|
||||
print('\n', file = doc_file)
|
||||
print('\n', file = doc_file)
|
||||
|
||||
|
@@ -25,11 +25,11 @@ include <../core.scad>
|
||||
include <../vitamins/sheets.scad>
|
||||
use <../vitamins/insert.scad>
|
||||
|
||||
screw = M3_cap_screw;
|
||||
screwM3 = M3_cap_screw;
|
||||
sheet = PMMA3;
|
||||
height = 10;
|
||||
|
||||
insert = screw_insert(screw);
|
||||
insert = screw_insert(screwM3);
|
||||
|
||||
module widget(thickness) {
|
||||
vitamin(str("widget(", thickness, "): Rivet like thing for ", thickness, "mm sheets"));
|
||||
@@ -46,7 +46,13 @@ module widget(thickness) {
|
||||
module widget_stl() {
|
||||
stl("widget")
|
||||
union() {
|
||||
rounded_rectangle([30, 30, 3], 2, true);
|
||||
difference() {
|
||||
rounded_rectangle([30, 30, 3], 2, true);
|
||||
for(x = [-10,10])
|
||||
for (y=[-10,10])
|
||||
translate([x,y,-1.5])
|
||||
cylinder(r=2, h=3.5);
|
||||
}
|
||||
|
||||
render() insert_boss(insert, height, 2.2);
|
||||
}
|
||||
@@ -57,7 +63,18 @@ module widget_dxf() {
|
||||
difference() {
|
||||
sheet_2D(sheet, 20, 20, 1);
|
||||
|
||||
drill(screw_clearance_radius(screw), 0);
|
||||
drill(screw_clearance_radius(screwM3), 0);
|
||||
}
|
||||
}
|
||||
|
||||
module mdf_svg() {
|
||||
svg("mdf")
|
||||
difference() {
|
||||
sheet_2D(MDF6, 40,40);
|
||||
for(x = [-10,10])
|
||||
for (y=[-10,10])
|
||||
translate([x,y,0])
|
||||
drill(screw_clearance_radius(screwM3), 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,11 +102,23 @@ assembly("widget_top") {
|
||||
module widget_assembly()
|
||||
assembly("widget") {
|
||||
|
||||
widget_base_assembly(); // Note this is not exploded because it is sub-assembly
|
||||
translate_z(-6) {
|
||||
render_2D_sheet(MDF6)
|
||||
mdf_svg();
|
||||
|
||||
explode(0)
|
||||
for(x = [-10,10])
|
||||
for (y=[-10,10])
|
||||
translate([x,y,-10])
|
||||
screw(screwM3, 10);
|
||||
}
|
||||
|
||||
explode(3)
|
||||
widget_base_assembly(); // Note this is not exploded because it is sub-assembly
|
||||
|
||||
translate_z(height) {
|
||||
translate_z(sheet_thickness(sheet))
|
||||
screw_and_washer(screw, screw_length(screw, sheet_thickness(sheet) + 3, 2, longer = true), true);
|
||||
screw_and_washer(screwM3, screw_length(screwM3, sheet_thickness(sheet) + 3, 2, longer = true), true);
|
||||
|
||||
explode(5)
|
||||
translate_z(sheet_thickness(sheet) / 2 + eps)
|
||||
|
@@ -21,14 +21,20 @@ include <../core.scad>
|
||||
include <../vitamins/pulleys.scad>
|
||||
use <../vitamins/insert.scad>
|
||||
use <../utils/layout.scad>
|
||||
use <../utils/maths.scad>
|
||||
|
||||
module belt_test() {
|
||||
p2 = [-75, -50];
|
||||
p3 = [-75, 100];
|
||||
p4 = [ 75, 100];
|
||||
widths = [for(b = belts) belt_width(b)];
|
||||
gap = 5;
|
||||
belts_width = sumv(widths) + (len(belts) - 1) * gap;
|
||||
width = belts_width + 50;
|
||||
|
||||
p5 = [ 75 + pulley_pr(GT2x20ob_pulley) - pulley_pr(GT2x16_plain_idler), +pulley_pr(GT2x16_plain_idler)];
|
||||
p6 = [-75 + pulley_pr(GT2x20ob_pulley) + pulley_pr(GT2x16_plain_idler), -pulley_pr(GT2x16_plain_idler)];
|
||||
p2 = [-width / 2, -50];
|
||||
p3 = [-width / 2, 100];
|
||||
p4 = [ width / 2, 100];
|
||||
|
||||
p5 = [ width / 2 + pulley_pr(GT2x20ob_pulley) - pulley_pr(GT2x16_plain_idler), +pulley_pr(GT2x16_plain_idler)];
|
||||
p6 = [-width / 2 + pulley_pr(GT2x20ob_pulley) + pulley_pr(GT2x16_plain_idler), -pulley_pr(GT2x16_plain_idler)];
|
||||
|
||||
module pulleys(flip = false) {
|
||||
translate(p2) rotate([0, flip ? 180 : 0, 0]) pulley_assembly(GT2x20ob_pulley);
|
||||
@@ -70,15 +76,15 @@ module belt_test() {
|
||||
pulleys(flip=true);
|
||||
}
|
||||
|
||||
translate([-25, 0, 10])
|
||||
layout([for(b = belts) belt_width(b)], 10)
|
||||
translate([-belts_width / 2, 0, 10])
|
||||
layout(widths, gap)
|
||||
rotate([0, 90, 0])
|
||||
belt(belts[$i], [[0, 0, 20], [0, 1, 20]], belt_colour = $i%2==0 ? grey(90) : grey(20), tooth_colour = $i%2==0 ? grey(70) : grey(50));
|
||||
|
||||
// new example with open loop - this is a simplified example of the style used for example for the BLV 3D printer
|
||||
pulley = GT2x20ob_pulley;
|
||||
idler = GT2x16_plain_idler;
|
||||
corners = [[-75,-50],[75,100]];
|
||||
corners = [[-width / 2,-50],[width / 2,100]];
|
||||
carriagepos = [0,0];
|
||||
carriagew = 80;
|
||||
|
||||
@@ -94,7 +100,7 @@ module belt_test() {
|
||||
translate_z(-30) {
|
||||
belt(belt, points, open=true, auto_twist=true);
|
||||
for (p = points)
|
||||
if (is_list(p.z))
|
||||
if(is_list(p.z))
|
||||
translate([p.x, p.y, 0])
|
||||
pulley_assembly(p.z);
|
||||
}
|
||||
|
Before Width: | Height: | Size: 163 KiB After Width: | Height: | Size: 177 KiB |
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 63 KiB |
Before Width: | Height: | Size: 73 KiB After Width: | Height: | Size: 70 KiB |
Before Width: | Height: | Size: 250 KiB After Width: | Height: | Size: 244 KiB |
Before Width: | Height: | Size: 70 KiB After Width: | Height: | Size: 69 KiB |
@@ -31,7 +31,7 @@
|
||||
//! The example below shows how to define a vitamin and incorporate it into an assembly with sub-assemblies and make an exploded view.
|
||||
//! The resulting flat BOM is shown but hierarchical BOMs are also generated for real projects.
|
||||
//!
|
||||
//! If the code to make an STL or DXF is made a child of the `stl()` or `dxf()` module then the STL or DXF will be used in the assembly views generated by `views.py` instead of generating
|
||||
//! If the code to make an STL, DXF or SVG is made a child of the `stl()`, `dxf()` or `svg()` module then the STL, DXF or SVG will be used in the assembly views generated by `views.py` instead of generating
|
||||
//! it with code.
|
||||
//! This can speed up the generation of the build instructions greatly but isn't compatible with STLs that include support structures.
|
||||
//!
|
||||
@@ -168,12 +168,32 @@ module dxf(name) { //! Name a dxf that will appear on the B
|
||||
}
|
||||
}
|
||||
|
||||
module svg(name) { //! Name an svg that will appear on the BOM, there needs to a module named `<name>_svg` to make it
|
||||
if(bom_mode() && is_undef($in_svg)) {
|
||||
if(is_undef($dxf_colour))
|
||||
echo(str("~", name, ".svg"));
|
||||
else
|
||||
echo(str("~", name, ".svg(colour='", $dxf_colour, "')"));
|
||||
}
|
||||
if($children)
|
||||
if(is_undef($pose))
|
||||
let($in_svg = true)
|
||||
children();
|
||||
else {
|
||||
path = is_undef($target) ? "/svgs/" : str("/", $target, "/svgs/");
|
||||
import(str($cwd, path, name, ".svg"));
|
||||
}
|
||||
}
|
||||
|
||||
module use_stl(name) //! Import an STL to make a build platter
|
||||
assert(false); // Here for documentation only, real version in core.scad
|
||||
|
||||
module use_dxf(name) //! Import a DXF to make a build panel
|
||||
assert(false); // Here for documentation only, real version in core.scad
|
||||
|
||||
module use_svg(name) //! Import an SVG to make a build panel
|
||||
assert(false); // Here for documentation only, real version in core.scad
|
||||
|
||||
function value_string(value) = is_string(value) ? str("\"", value, "\"") : str(value); //! Convert `value` to a string or quote it if it is already a string
|
||||
|
||||
function arg(value, default, name = "") = //! Create string for arg if not default, helper for `vitamin()`
|
||||
|
@@ -37,3 +37,9 @@ module use_dxf(name) { //! Import a DXF to make a build panel
|
||||
path = is_undef($target) ? "../dxfs/" : str($cwd, "/", $target, "/dxfs/");
|
||||
import(str(path, name, ".dxf"));
|
||||
}
|
||||
|
||||
module use_svg(name) { //! Import an SVG to make a build panel
|
||||
svg(name);
|
||||
path = is_undef($target) ? "../svgs/" : str($cwd, "/", $target, "/svgs/");
|
||||
import(str(path, name, ".svg"));
|
||||
}
|
||||
|
@@ -65,7 +65,7 @@ module belt(type, points, belt_colour = grey(20), tooth_colour = grey(50), open
|
||||
arcs = info[4];
|
||||
length = ceil(_belt_length(info, open) / pitch) * pitch;
|
||||
|
||||
part = str(type[0],pitch);
|
||||
part = type[0];
|
||||
vitamin(str("belt(", no_point(part), "x", width, ", ", pointsx, "): Belt ", part," x ", width, "mm x ", length, "mm"));
|
||||
|
||||
len = len(points);
|
||||
|
@@ -20,17 +20,23 @@
|
||||
//
|
||||
// Belt model
|
||||
//
|
||||
// p w t t p
|
||||
// i i h o i
|
||||
// t d i o t
|
||||
// c t c t c
|
||||
// h h k h h line from tooth base
|
||||
// p w t t p
|
||||
// i i h o i
|
||||
// t d i o t
|
||||
// c t c t c
|
||||
// h h k h h line from tooth base
|
||||
//
|
||||
T5x6 = ["T", 5, 6, 2.2, 1.2, 0.5];
|
||||
T5x10 = ["T", 5, 10, 2.2, 1.2, 0.5];
|
||||
T2p5x6 =["T", 2.5, 6, 1.7, 0.7, 0.3];
|
||||
GT2x6 = ["GT", 2.0, 6, 1.38, 0.75, 0.254];
|
||||
GT2x9 = ["GT", 2.0, 9, 1.38, 0.75, 0.254];
|
||||
T5x6 = ["T5", 5, 6, 2.2, 1.2, 0.5];
|
||||
T5x10 = ["T5", 5, 10,2.2, 1.2, 0.5];
|
||||
T2p5x6 =["T2.5", 2.5, 6, 1.7, 0.7, 0.3];
|
||||
|
||||
belts = [T5x6, T5x10, T2p5x6, GT2x6, GT2x9];
|
||||
GT2x6 = ["GT2", 2.0, 6, 1.38, 0.75, 0.254];
|
||||
GT2x9 = ["GT2", 2.0, 9, 1.38, 0.75, 0.254];
|
||||
GT2x12 =["GT2", 2.0, 12, 1.38, 0.75, 0.254];
|
||||
|
||||
GT3x6 = ["GT3", 2.0, 6, 1.52, 0.75, 0.254];
|
||||
GT3x9 = ["GT3", 2.0, 9, 1.52, 0.75, 0.254];
|
||||
GT3x12 =["GT3", 2.0, 12, 1.52, 0.75, 0.254];
|
||||
|
||||
belts = [T5x6, T5x10, T2p5x6, GT2x6, GT2x9, GT2x12, GT3x6, GT3x9, GT3x12];
|
||||
use <belt.scad>
|
||||
|
@@ -54,6 +54,24 @@ LCD1602A = ["LCD1602A", "LCD display 1602A", 71.3, 24.3, 7.0, LCD1602APCB,
|
||||
[], // clearance need for the ts ribbon
|
||||
];
|
||||
|
||||
LCD2004APCB = pcb("", "", [98, 60, 1.65], hole_d = 2.9, land_d = 5, colour = "green",
|
||||
holes = [[-2.5, -2.5], [-2.5, 2.5], [2.5, 2.5], [2.5, -2.5]],
|
||||
components = [
|
||||
[49+19.05, - 2.5, 0, "2p54header", 16, 1]
|
||||
],
|
||||
grid = [
|
||||
49, 60 - 2.5, 16, 1, silver, inch(0.1), inch(0.1),
|
||||
]
|
||||
);
|
||||
|
||||
LCD2004A = ["LCD2004A", "LCD display 2004A", 97, 39.5, 9.0, LCD2004APCB,
|
||||
[0, 0, 0], // pcb offst
|
||||
[[-76 / 2, -26 / 2], [76 / 2, 26 / 2, 0.6]], // aperture
|
||||
[], // touch screen
|
||||
0, // thread length
|
||||
[], // clearance need for the ts ribbon
|
||||
];
|
||||
|
||||
LCDS7282BPCB = pcb("", "", [85, 36, 1.65], hole_d = 2.56, colour = "green",
|
||||
holes = [[-2.5, -2.5], [-2.5, 2.5], [2.5, 2.5], [2.5, -2.5]],
|
||||
components = [
|
||||
@@ -149,6 +167,6 @@ BigTreeTech_TFT35v3_0 = ["BigTreeTech_TFT35v3_0", "BigTreeTech TFT35 v3.0",
|
||||
];
|
||||
|
||||
|
||||
displays = [HDMI5, SSD1963_4p3, BigTreeTech_TFT35v3_0, LCD1602A, LCDS7282B, TFT128x160];
|
||||
displays = [HDMI5, SSD1963_4p3, LCD2004A, BigTreeTech_TFT35v3_0, LCD1602A, LCDS7282B, TFT128x160];
|
||||
|
||||
use <display.scad>
|
||||
|
@@ -56,7 +56,7 @@ module insert(type) { //! Draw specified insert
|
||||
vitamin(str("insert(", type[0], "): Heatfit insert M", insert_screw_diameter(type), " x ", length, "mm"));
|
||||
$fn = 64;
|
||||
thread_d = insert_screw_diameter(type);
|
||||
explode(20, offset = [0, 0, -5]) translate_z(eps) vflip() {
|
||||
explode(20, offset = [0, 0, -length]) translate_z(eps) vflip() {
|
||||
r1 = thread_d / 2;
|
||||
r2 = insert_barrel_d(type) / 2;
|
||||
r3 = insert_ring3_d(type) / 2;
|
||||
|
@@ -765,6 +765,27 @@ MT3608 = ["MT3608", "MT3608 boost converter module", 37, 17, 1.2, 2, 1.5,
|
||||
[ [-12.05 , -6.8, 180, "trimpot10"]
|
||||
]];
|
||||
|
||||
HW803_1WAY_RELAY = [
|
||||
"HW803_1WAY_RELAY", "HW-803 5V 1 way relay module",
|
||||
50, 26, 1.6, // size
|
||||
2, // corner radius
|
||||
3, // mounting hole diameter
|
||||
4, // pad around mounting hole
|
||||
"red", // color
|
||||
false, // true if parts should be separate BOM items
|
||||
[ // hole positions
|
||||
[3, 3], [-3, 3], [3, -3], [-3, -3]
|
||||
],
|
||||
[ // components
|
||||
[ 10.5 + 19/2, 26/2, 0, "block", 19, 15, 15.5, "SkyBlue" ],
|
||||
[ 50-5, 26/2, 0, "term35", 3],
|
||||
[ 5, 26/2, 180, "term35", 3],
|
||||
[ 34, 2, 0, "2p54header", 3, 1 ],
|
||||
],
|
||||
[], // accessories
|
||||
[], // grid
|
||||
];
|
||||
|
||||
TP4056 = ["TP4056", "TP4056 Li-lon Battery charger module", 26.2, 17.5, 1.0, 0, 1.0, [2.4, 2.4], "#2140BE", false,
|
||||
[[1.67, 1.8], [1.67, -1.8], [-1.67, 1.8], [-1.67, -1.8], [-1.67, -4.98], [-1.67, 4.98]],
|
||||
[ [ 2, 17.5 / 2, 180, "usb_uA"],
|
||||
@@ -1197,11 +1218,11 @@ tiny_buck = pcb("tiny_buck", "Ultra Small 3A buck regulator", [20, 11, 1.6],
|
||||
]
|
||||
);
|
||||
|
||||
tiny_pcbs = [ESP_201, ESP_12F, XIAO, MP1584EN, ESP_01, ESP_01M, tiny_buck, LIPO_fuel_gauge];
|
||||
tiny_pcbs = [ESP_201, ESP_01M, XIAO, ESP_12F, MP1584EN, ESP_01,tiny_buck, LIPO_fuel_gauge];
|
||||
|
||||
big_pcbs = [BTT_RELAY_V1_2, BTT_SKR_MINI_E3_V2_0, BTT_SKR_E3_TURBO, BTT_SKR_V1_4_TURBO, DuetE, Duex5];
|
||||
|
||||
pcbs = [KY_040, TP4056, L9110S, ZC_A0591, RAMPSEndstop, MT3608, ArduinoNano, Feather405, RPI_Pico, ESP32_DOIT_V1, RPI0, EnviroPlus, ArduinoUno3, ArduinoLeonardo, WD2002SJ, OPZ2, PanelDue_v3, RPI3A, RPI3, RPI4];
|
||||
pcbs = [KY_040, TP4056, L9110S, ZC_A0591, MT3608, RAMPSEndstop, ArduinoNano, HW803_1WAY_RELAY, Feather405, RPI_Pico, ESP32_DOIT_V1, RPI0, EnviroPlus, ArduinoUno3, ArduinoLeonardo, WD2002SJ, OPZ2, PanelDue_v3, RPI3A, RPI3, RPI4];
|
||||
|
||||
pcbs_not_shown = [Melzi, Duex2, PSU12V1A, Keyes5p1, PI_IO, ExtruderPCB];
|
||||
|
||||
|
@@ -49,6 +49,12 @@ function screw_head_depth(type, d = 0) = //! How far a counter sink
|
||||
? 0
|
||||
: let(r = screw_radius(type)) screw_head_radius(type) - max(r, d / 2) + r / 5;
|
||||
|
||||
function screw_thread_radius(type) = //! Thread radius
|
||||
let(d = screw_thread_diameter(type)) is_undef(d) ? screw_radius(type) : d / 2;
|
||||
|
||||
function screw_angle(type, length, nut_distance) = //! How much to rotate the screw to align it with a nut at the specified `distance` from the head
|
||||
-360 * (length - nut_distance) / metric_coarse_pitch(screw_thread_radius(type) * 2);
|
||||
|
||||
function screw_longer_than(x) = x <= 5 ? 5 : //! Returns the length of the shortest screw length longer or equal to x
|
||||
x <= 6 ? 6 :
|
||||
x <= 8 ? 8 :
|
||||
@@ -96,7 +102,7 @@ module screw(type, length, hob_point = 0, nylon = false) { //! Draw specified sc
|
||||
socket_rad = socket_af / cos(30) / 2;
|
||||
max_thread = screw_max_thread(type);
|
||||
has_shoulder = !is_undef(screw_thread_diameter(type));
|
||||
thread_rad = has_shoulder ? screw_thread_diameter(type) / 2 : screw_radius(type);
|
||||
thread_rad = screw_thread_radius(type);
|
||||
thread = max_thread ? length >= max_thread + 5 ? max_thread
|
||||
: length
|
||||
: length;
|
||||
|
@@ -26,11 +26,13 @@
|
||||
//
|
||||
mdf_colour = "#BEA587"; // sampled from a photo
|
||||
|
||||
MDF3 = [ "MDF3", "Sheet MDF", 3, mdf_colour, true];
|
||||
MDF6 = [ "MDF6", "Sheet MDF", 6, mdf_colour, true]; // ~1/4"
|
||||
MDF10 = [ "MDF10", "Sheet MDF", 10, mdf_colour, true]; // ~3/8"
|
||||
MDF12 = [ "MDF12", "Sheet MDF", 12, mdf_colour, true]; // ~1/2"
|
||||
MDF18 = [ "MDF18", "Sheet MDF", 18, mdf_colour, true];
|
||||
MDF19 = [ "MDF19", "Sheet MDF", 19, mdf_colour, true]; // ~3/4"
|
||||
MDF22 = [ "MDF22", "Sheet MDF", 22, mdf_colour, true];
|
||||
PMMA1p25 = [ "PMMA1p25", "Sheet acrylic", 1.25,[1, 1, 1, 0.5 ], false];
|
||||
PMMA2 = [ "PMMA2", "Sheet acrylic", 2, [1, 1, 1, 0.5 ], false];
|
||||
PMMA3 = [ "PMMA3", "Sheet acrylic", 3, [1, 1, 1, 0.5 ], false]; // ~1/8"
|
||||
@@ -56,7 +58,7 @@ CF2 = [ "CF2", "Sheet carbon fiber", 2, grey(35),
|
||||
CF3 = [ "CF3", "Sheet carbon fiber", 3, grey(35), false, 2, 2, grey(20)];
|
||||
|
||||
|
||||
sheets = [CF1, CF2, CF3, MDF6, MDF10, MDF12, MDF19, PMMA1p25, PMMA2, PMMA3, PMMA6, PMMA8, PMMA10,
|
||||
sheets = [CF1, CF2, CF3, MDF3, MDF6, MDF10, MDF12, MDF19, MDF22, PMMA1p25, PMMA2, PMMA3, PMMA6, PMMA8, PMMA10,
|
||||
glass2, DiBond, DiBond6, Cardboard, FoilTape, AL1_6, AL2, AL3, AL6, AL8, Steel06, Spring08, Silicone3, Foam20];
|
||||
|
||||
use <sheet.scad>
|
||||
|