1
0
mirror of https://github.com/nophead/NopSCADlib.git synced 2025-09-04 12:45:30 +02:00

Compare commits

...

58 Commits

Author SHA1 Message Date
Chris Palmer
654f094304 Merge branch 'martinbudden-spool_filament' 2020-02-23 14:28:57 +00:00
Chris Palmer
1e5e5860e1 Made more realistic and added a test. 2020-02-23 14:28:39 +00:00
Chris Palmer
3d8a9ec8aa Merge branch 'spool_filament' of https://github.com/martinbudden/NopSCADlib into martinbudden-spool_filament 2020-02-23 10:04:23 +00:00
Chris Palmer
9e826c1a09 Merge branch 'martinbudden-belt_colors' 2020-02-22 23:02:03 +00:00
Chris Palmer
2c1dbe04a9 Added images and readme. 2020-02-22 23:01:50 +00:00
Chris Palmer
d644d6b698 Merge branch 'belt_colors' of https://github.com/martinbudden/NopSCADlib into martinbudden-belt_colors 2020-02-22 22:47:42 +00:00
Chris Palmer
8db4cc2cb5 Merge branch 'martinbudden-pcb_jst_xh' 2020-02-22 22:40:31 +00:00
Chris Palmer
509a87939c Updated images and readme 2020-02-22 22:40:09 +00:00
Chris Palmer
40607e6cfc Merge branch 'pcb_jst_xh' of https://github.com/martinbudden/NopSCADlib into martinbudden-pcb_jst_xh 2020-02-22 22:28:16 +00:00
Chris Palmer
599fbba6c2 Reduced dependecies in pcb_mount test. 2020-02-22 22:24:45 +00:00
Chris Palmer
52729d012c Merge branch 'martinbudden-rail_carriage_coloring' 2020-02-22 22:16:50 +00:00
Chris Palmer
6097e07094 Updated images and readme. 2020-02-22 22:16:09 +00:00
Chris Palmer
9d71438a3c Merge branch 'rail_carriage_coloring' of https://github.com/martinbudden/NopSCADlib into martinbudden-rail_carriage_coloring 2020-02-22 21:59:15 +00:00
Chris Palmer
ffa1ab940b Merge branch 'martinbudden-tnuts' 2020-02-22 21:51:16 +00:00
Chris Palmer
3174013e1a Updated images and readme. 2020-02-22 21:51:05 +00:00
Chris Palmer
c4eea38a2b Added threads 2020-02-22 21:27:51 +00:00
Chris Palmer
0cd89279a5 Merge branch 'tnuts' of https://github.com/martinbudden/NopSCADlib into martinbudden-tnuts 2020-02-22 21:12:13 +00:00
Chris Palmer
92051e0b28 Merge branch 'martinbudden-gitattributes' 2020-02-22 21:05:26 +00:00
Chris Palmer
f4b22e35c7 Merge branch 'gitattributes' of https://github.com/martinbudden/NopSCADlib into martinbudden-gitattributes 2020-02-22 21:02:24 +00:00
Chris Palmer
17ecfc07f3 Merge branch 'martinbudden-screw_knob_typo' 2020-02-22 20:58:55 +00:00
Chris Palmer
9658205efd Updated readme 2020-02-22 20:58:43 +00:00
Chris Palmer
53140a4cc1 Merge branch 'screw_knob_typo' of https://github.com/martinbudden/NopSCADlib into martinbudden-screw_knob_typo 2020-02-22 20:55:17 +00:00
Chris Palmer
2798d39538 Merge branch 'martinbudden-iec_switched_fused' 2020-02-22 20:51:58 +00:00
Chris Palmer
8be0cc98ea Updated the images and readme. 2020-02-22 20:51:15 +00:00
Chris Palmer
6a5f31edd8 Merge branch 'iec_switched_fused' of https://github.com/martinbudden/NopSCADlib into martinbudden-iec_switched_fused 2020-02-22 20:01:25 +00:00
Chris Palmer
e068918e21 Added screw threads to most things that are threaded.
Added a mechanism for tests.py and views.py to have command line options.
2020-02-22 19:44:01 +00:00
Chris Palmer
1614f50b73 Merged master 2020-02-22 18:32:35 +00:00
Martin Budden
32522b28d7 Added hammer nuts. 2020-02-19 06:42:11 +00:00
Martin Budden
1936c95d06 Added IEC 320 C14 switched fused inlet module. 2020-02-18 08:24:16 +00:00
Martin Budden
16060629c0 Added sliding t nuts. Sizes M3, M4 and M5. 2020-02-18 07:48:01 +00:00
Martin Budden
dc4e24b63a Simplified drawing of filament. 2020-02-16 23:06:07 +00:00
Martin Budden
3ab934d83e Typo in screw_knob. foe corrected to for. 2020-02-07 19:58:37 +00:00
Martin Budden
d1324a670e Added JST-XH connector for pcbs. 2020-01-30 05:45:29 +00:00
Martin Budden
c55b8b6d1c Parameterised belt colors. 2020-01-29 17:40:34 +00:00
Martin Budden
728b7adf38 Add ability to display filament on spool. 2020-01-14 11:26:21 +00:00
Martin Budden
75747687d9 Parameterised coloring of linear rail carriage. 2020-01-12 10:20:10 +00:00
Martin Budden
03c97e8b6a Changed rail carriage coloring to be green with red endpiece to match common form. 2020-01-11 14:54:00 +00:00
Chris Palmer
8ac06b53e7 Updated readme and images for linear_bearings change. 2020-01-11 08:57:33 +00:00
Martin Budden
de76eb46e7 Initial commit. Set default text file line endings to LF. 2020-01-11 08:21:38 +00:00
Chris
2c77f184a2 Merge pull request #12 from martinbudden/linear_bearings
Added LM16UU and long form (LMxLUU) of linear bearings plus external grooves.
2020-01-11 08:10:49 +00:00
Martin Budden
4d3d9dfdfe Added LM16UU and long form (LMxLUU) of linear bearings.
Added external grooves.
2020-01-10 22:11:53 +00:00
Chris Palmer
f7a972f946 Added pictures and documentation for extrusions. 2020-01-10 20:10:17 +00:00
Chris
4e81fcbd4f Merge pull request #10 from martinbudden/extrusions
Initial submission of E2020 aluminium extrusion.
2020-01-10 19:32:49 +00:00
Martin Budden
1f038decd4 Initial submission of aluminium extrusion. Supports 2020, 2040, 2060, 2080, 3030, 3060, 4040, 4080 types.
Added extrusions to main picture.
2020-01-10 19:24:24 +00:00
Chris
da958fe112 Merge pull request #11 from martinbudden/e3d_naked
E3d Resistor wire drawn even if naked=true.
2020-01-10 13:26:43 +00:00
Martin Budden
61493eaa34 Resistor wire drawn even if naked=true. 2020-01-10 12:26:56 +00:00
Chris
804c00bdcb Merge pull request #8 from martinbudden/rocker_typo
Fixed typo where 'rocker' was spelt 'rocket'.
2020-01-10 10:28:21 +00:00
Chris
11ea68681f Merge pull request #9 from martinbudden/e3d_tab_formatting
Tabs used instead of spaces in module e3d_resistor.
2020-01-10 10:27:40 +00:00
Chris Palmer
d703ae4997 Added male screw threads. 2020-01-10 10:26:12 +00:00
Martin Budden
ed97d226f8 Tabs used instead of spaces in module e3d_resistor. 2020-01-10 08:49:03 +00:00
Martin Budden
4107a2c848 Fixed typo where 'rocker' was spelt 'rocket'. 2020-01-10 08:26:20 +00:00
Chris Palmer
f7ef075434 Fixed hex pillar thread length.
Reordered screws.
Random pixel changes.
2019-12-30 12:45:51 +00:00
Chris Palmer
6f93b6af9a pcb_component_position() can now be passed an index to differentiate between
multiple components of the same type.

Added pcb_grid_pos() function.
2019-11-15 13:30:27 +00:00
Chris Palmer
53f416eef1 Added more detail to the Environ+ pcb.
Changed the RPI0 SD height to be more accurate.
2019-11-15 13:28:02 +00:00
Chris Palmer
6354219627 Added tiny 17x8mm fan. 2019-11-15 13:25:32 +00:00
Chris Palmer
56e2b71bda Updated readme for last PR 2019-10-22 18:01:51 +01:00
Chris
8f5503586d Merge pull request #6 from limitz/e3d_resistor_wire_rotate
E3d resistor wire rotate
2019-10-22 17:57:14 +01:00
Eddy Pronk
d041b18025 Adds an option resistor_wire_rotate 2019-10-21 17:51:19 +02:00
111 changed files with 1425 additions and 289 deletions

16
.gitattributes vendored Normal file
View 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
View File

@@ -7,6 +7,7 @@ tests/bom/
*.log
*.html
bounds.json
options.json
times.txt
*_diff.png
*.echo

BIN
docs/metric_threads.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

@@ -39,6 +39,7 @@ pp2_colour = is_undef($pp2_colour) ? "red" : $pp2_colour; // pri
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,8 @@ 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";
brass = [255/255, 215/255, 0/255];
silver = [0.75, 0.75, 0.75];
/*
* Enums

View File

@@ -62,6 +62,7 @@ include <vitamins/spools.scad>
include <vitamins/mains_sockets.scad>
include <vitamins/ldrs.scad>
include <vitamins/geared_steppers.scad>
include <vitamins/extrusions.scad>
use <vitamins/jack.scad>
use <vitamins/meter.scad>
@@ -90,3 +91,4 @@ use <utils/layout.scad>
use <utils/round.scad>
use <utils/offset.scad>
use <utils/sector.scad>
use <utils/thread.scad>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 739 KiB

After

Width:  |  Height:  |  Size: 764 KiB

View File

@@ -32,6 +32,7 @@ use <tests/cable_strips.scad>
use <tests/components.scad>
use <tests/d_connectors.scad>
use <tests/displays.scad>
use <tests/extrusions.scad>
use <tests/fans.scad>
use <tests/fuseholder.scad>
use <tests/geared_steppers.scad>
@@ -135,13 +136,13 @@ translate([x5, cable_grommets_y + 250])
translate([900, 600])
box_test();
translate([850, 1170])
translate([850, 1260])
bbox_test();
x0 = 0;
inserts_y = 0;
nuts_y = inserts_y + 20;
washers_y = nuts_y + 60;
washers_y = nuts_y + 100;
screws_y = washers_y + 120;
o_rings_y = screws_y + 130;
springs_y = o_rings_y + 20;
@@ -152,7 +153,7 @@ 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;
@@ -203,6 +204,10 @@ translate([x0, linear_bearings_y]) {
rods();
}
translate([x0+150, linear_bearings_y+30]) {
extrusions();
}
translate([x0 + 10, hot_ends_y])
hot_ends();

View File

@@ -34,7 +34,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;

235
readme.md
View File

@@ -28,24 +28,25 @@ See [usage](docs/usage.md) for requirements, installation instructions and a usa
<tr><td> <a href = "#Components">Components</a> </td><td> <a href = "#Pulleys">Pulleys</a> </td><td> <a href = "#Fan_guard">Fan_guard</a> </td><td> <a href = "#Offset">Offset</a> </td><td></td></tr>
<tr><td> <a href = "#D_connectors">D_connectors</a> </td><td> <a href = "#Rails">Rails</a> </td><td> <a href = "#Fixing_block">Fixing_block</a> </td><td> <a href = "#Quadrant">Quadrant</a> </td><td></td></tr>
<tr><td> <a href = "#Displays">Displays</a> </td><td> <a href = "#Ring_terminals">Ring_terminals</a> </td><td> <a href = "#Flat_hinge">Flat_hinge</a> </td><td> <a href = "#Round">Round</a> </td><td></td></tr>
<tr><td> <a href = "#Fans">Fans</a> </td><td> <a href = "#Rockers">Rockers</a> </td><td> <a href = "#Foot">Foot</a> </td><td> <a href = "#Rounded_cylinder">Rounded_cylinder</a> </td><td></td></tr>
<tr><td> <a href = "#Fuseholder">Fuseholder</a> </td><td> <a href = "#Rod">Rod</a> </td><td> <a href = "#Handle">Handle</a> </td><td> <a href = "#Rounded_polygon">Rounded_polygon</a> </td><td></td></tr>
<tr><td> <a href = "#Geared_steppers">Geared_steppers</a> </td><td> <a href = "#Screws">Screws</a> </td><td> <a href = "#Pcb_mount">Pcb_mount</a> </td><td> <a href = "#Sector">Sector</a> </td><td></td></tr>
<tr><td> <a href = "#Green_terminals">Green_terminals</a> </td><td> <a href = "#Sealing_strip">Sealing_strip</a> </td><td> <a href = "#Psu_shroud">Psu_shroud</a> </td><td> <a href = "#Sweep">Sweep</a> </td><td></td></tr>
<tr><td> <a href = "#Hot_ends">Hot_ends</a> </td><td> <a href = "#Sheets">Sheets</a> </td><td> <a href = "#Ribbon_clamp">Ribbon_clamp</a> </td><td> <a href = "#Tube">Tube</a> </td><td></td></tr>
<tr><td> <a href = "#Hygrometer">Hygrometer</a> </td><td> <a href = "#Spades">Spades</a> </td><td> <a href = "#Screw_knob">Screw_knob</a> </td><td></td><td></td></tr>
<tr><td> <a href = "#Iecs">Iecs</a> </td><td> <a href = "#Spools">Spools</a> </td><td> <a href = "#Socket_box">Socket_box</a> </td><td></td><td></td></tr>
<tr><td> <a href = "#Inserts">Inserts</a> </td><td> <a href = "#Springs">Springs</a> </td><td> <a href = "#Ssr_shroud">Ssr_shroud</a> </td><td></td><td></td></tr>
<tr><td> <a href = "#Jack">Jack</a> </td><td> <a href = "#Ssrs">Ssrs</a> </td><td> <a href = "#Strap_handle">Strap_handle</a> </td><td></td><td></td></tr>
<tr><td> <a href = "#Ldrs">Ldrs</a> </td><td> <a href = "#Stepper_motors">Stepper_motors</a> </td><td></td><td></td><td></td></tr>
<tr><td> <a href = "#Leadnuts">Leadnuts</a> </td><td> <a href = "#Toggles">Toggles</a> </td><td></td><td></td><td></td></tr>
<tr><td> <a href = "#Leds">Leds</a> </td><td> <a href = "#Transformers">Transformers</a> </td><td></td><td></td><td></td></tr>
<tr><td> <a href = "#Light_strips">Light_strips</a> </td><td> <a href = "#Tubings">Tubings</a> </td><td></td><td></td><td></td></tr>
<tr><td> <a href = "#Linear_bearings">Linear_bearings</a> </td><td> <a href = "#Variacs">Variacs</a> </td><td></td><td></td><td></td></tr>
<tr><td> <a href = "#Mains_sockets">Mains_sockets</a> </td><td> <a href = "#Veroboard">Veroboard</a> </td><td></td><td></td><td></td></tr>
<tr><td> <a href = "#Meter">Meter</a> </td><td> <a href = "#Washers">Washers</a> </td><td></td><td></td><td></td></tr>
<tr><td> <a href = "#Microswitches">Microswitches</a> </td><td> <a href = "#Wire">Wire</a> </td><td></td><td></td><td></td></tr>
<tr><td> <a href = "#Microview">Microview</a> </td><td> <a href = "#Zipties">Zipties</a> </td><td></td><td></td><td></td></tr>
<tr><td> <a href = "#Extrusions">Extrusions</a> </td><td> <a href = "#Rockers">Rockers</a> </td><td> <a href = "#Foot">Foot</a> </td><td> <a href = "#Rounded_cylinder">Rounded_cylinder</a> </td><td></td></tr>
<tr><td> <a href = "#Fans">Fans</a> </td><td> <a href = "#Rod">Rod</a> </td><td> <a href = "#Handle">Handle</a> </td><td> <a href = "#Rounded_polygon">Rounded_polygon</a> </td><td></td></tr>
<tr><td> <a href = "#Fuseholder">Fuseholder</a> </td><td> <a href = "#Screws">Screws</a> </td><td> <a href = "#Pcb_mount">Pcb_mount</a> </td><td> <a href = "#Sector">Sector</a> </td><td></td></tr>
<tr><td> <a href = "#Geared_steppers">Geared_steppers</a> </td><td> <a href = "#Sealing_strip">Sealing_strip</a> </td><td> <a href = "#Psu_shroud">Psu_shroud</a> </td><td> <a href = "#Sweep">Sweep</a> </td><td></td></tr>
<tr><td> <a href = "#Green_terminals">Green_terminals</a> </td><td> <a href = "#Sheets">Sheets</a> </td><td> <a href = "#Ribbon_clamp">Ribbon_clamp</a> </td><td> <a href = "#Thread">Thread</a> </td><td></td></tr>
<tr><td> <a href = "#Hot_ends">Hot_ends</a> </td><td> <a href = "#Spades">Spades</a> </td><td> <a href = "#Screw_knob">Screw_knob</a> </td><td> <a href = "#Tube">Tube</a> </td><td></td></tr>
<tr><td> <a href = "#Hygrometer">Hygrometer</a> </td><td> <a href = "#Spools">Spools</a> </td><td> <a href = "#Socket_box">Socket_box</a> </td><td></td><td></td></tr>
<tr><td> <a href = "#Iecs">Iecs</a> </td><td> <a href = "#Springs">Springs</a> </td><td> <a href = "#Ssr_shroud">Ssr_shroud</a> </td><td></td><td></td></tr>
<tr><td> <a href = "#Inserts">Inserts</a> </td><td> <a href = "#Ssrs">Ssrs</a> </td><td> <a href = "#Strap_handle">Strap_handle</a> </td><td></td><td></td></tr>
<tr><td> <a href = "#Jack">Jack</a> </td><td> <a href = "#Stepper_motors">Stepper_motors</a> </td><td></td><td></td><td></td></tr>
<tr><td> <a href = "#Ldrs">Ldrs</a> </td><td> <a href = "#Toggles">Toggles</a> </td><td></td><td></td><td></td></tr>
<tr><td> <a href = "#Leadnuts">Leadnuts</a> </td><td> <a href = "#Transformers">Transformers</a> </td><td></td><td></td><td></td></tr>
<tr><td> <a href = "#Leds">Leds</a> </td><td> <a href = "#Tubings">Tubings</a> </td><td></td><td></td><td></td></tr>
<tr><td> <a href = "#Light_strips">Light_strips</a> </td><td> <a href = "#Variacs">Variacs</a> </td><td></td><td></td><td></td></tr>
<tr><td> <a href = "#Linear_bearings">Linear_bearings</a> </td><td> <a href = "#Veroboard">Veroboard</a> </td><td></td><td></td><td></td></tr>
<tr><td> <a href = "#Mains_sockets">Mains_sockets</a> </td><td> <a href = "#Washers">Washers</a> </td><td></td><td></td><td></td></tr>
<tr><td> <a href = "#Meter">Meter</a> </td><td> <a href = "#Wire">Wire</a> </td><td></td><td></td><td></td></tr>
<tr><td> <a href = "#Microswitches">Microswitches</a> </td><td> <a href = "#Zipties">Zipties</a> </td><td></td><td></td><td></td></tr>
<tr><td> <a href = "#Microview">Microview</a> </td><td></td><td></td><td></td><td></td></tr>
<tr><td> <a href = "#Modules">Modules</a> </td><td></td><td></td><td></td><td></td></tr>
</table>
@@ -195,7 +196,7 @@ Individual teeth are not drawn, instead they are represented by a lighter colour
### Modules
| Module | Description |
|:--- |:--- |
| ```belt(type, points, gap = 0, gap_pt = undef)``` | Draw a belt path given a set of points and pitch radii where the pulleys are. Closed loop unless a gap is specified |
| ```belt(type, points, gap = 0, gap_pt = undef, belt_colour = grey20, tooth_colour = grey50)``` | Draw a belt path given a set of points and pitch radii where the pulleys are. Closed loop unless a gap is specified |
![belts](tests/png/belts.png)
@@ -585,6 +586,54 @@ LCD dispays.
| 1 | ```display(SSD1963_4p3)``` | LCD display SSD1963 4.3" |
<a href="#top">Top</a>
---
<a name="Extrusions"></a>
## Extrusions
Aluminium extrusion.
[vitamins/extrusions.scad](vitamins/extrusions.scad) Object definitions.
[vitamins/extrusion.scad](vitamins/extrusion.scad) Implementation.
[tests/extrusions.scad](tests/extrusions.scad) Code for this example.
### Properties
| Function | Description |
|:--- |:--- |
| ```extrusion_center_hole(type)``` | Diameter of center hole |
| ```extrusion_center_square(type)``` | Size of center square |
| ```extrusion_channel_width(type)``` | Channel width |
| ```extrusion_channel_width_internal(type)``` | Internal channel width |
| ```extrusion_corner_hole(type)``` | Diameter of corner hole |
| ```extrusion_fillet(type)``` | Radius of corner fillet |
| ```extrusion_height(type)``` | Height of extrusion |
| ```extrusion_spar_thickness(type)``` | Spar thickness |
| ```extrusion_tab_thickness(type)``` | Tab thickness |
| ```extrusion_width(type)``` | Width of extrusion |
### Modules
| Module | Description |
|:--- |:--- |
| ```extrusion(type, length, cornerHole = false)``` | Draw the specified extrusion |
![extrusions](tests/png/extrusions.png)
### Vitamins
| Qty | Module call | BOM entry |
| ---:|:--- |:---|
| 1 | ```extrusion(E2020, 80)``` | Extrusion E2020 x 80mm |
| 1 | ```extrusion(E2040, 80)``` | Extrusion E2040 x 80mm |
| 1 | ```extrusion(E2060, 80)``` | Extrusion E2060 x 80mm |
| 1 | ```extrusion(E2080, 80)``` | Extrusion E2080 x 80mm |
| 1 | ```extrusion(E3030, 80)``` | Extrusion E3030 x 80mm |
| 1 | ```extrusion(E3060, 80)``` | Extrusion E3060 x 80mm |
| 1 | ```extrusion(E4040, 80)``` | Extrusion E4040 x 80mm |
| 1 | ```extrusion(E4080, 80)``` | Extrusion E4080 x 80mm |
<a href="#top">Top</a>
---
@@ -630,6 +679,7 @@ Can draw three styles: solid, open frame and open frame with screw bosses.
| Qty | Module call | BOM entry |
| ---:|:--- |:---|
| 1 | ```fan(fan120x25)``` | Fan 120mm x 25mm |
| 1 | ```fan(fan17x8)``` | Fan 17mm x 8mm |
| 1 | ```fan(fan25x10)``` | Fan 25mm x 10mm |
| 1 | ```fan(fan30x10)``` | Fan 30mm x 10mm |
| 1 | ```fan(fan40x11)``` | Fan 40mm x 11mm |
@@ -639,14 +689,17 @@ Can draw three styles: solid, open frame and open frame with screw bosses.
| 1 | ```fan(fan70x15)``` | Fan 70mm x 15mm |
| 1 | ```fan(fan80x25)``` | Fan 80mm x 25mm |
| 1 | ```fan(fan80x38)``` | Fan 80mm x 38mm |
| 4 | ```nut(M2_nut, nyloc = true)``` | Nut M2 x 1.6mm nyloc |
| 4 | ```nut(M2p5_nut, nyloc = true)``` | Nut M2.5 x 2.2mm nyloc |
| 8 | ```nut(M3_nut, nyloc = true)``` | Nut M3 x 2.4mm nyloc |
| 28 | ```nut(M4_nut, nyloc = true)``` | Nut M4 x 3.2mm nyloc |
| 4 | ```screw(M2_cap_screw, 16)``` | Screw M2 cap x 16mm |
| 4 | ```screw(M2p5_pan_screw, 20)``` | Screw M2.5 pan x 20mm |
| 8 | ```screw(M3_dome_screw, 20)``` | Screw M3 dome x 20mm |
| 20 | ```screw(M4_dome_screw, 16)``` | Screw M4 dome x 16mm |
| 4 | ```screw(M4_dome_screw, 25)``` | Screw M4 dome x 25mm |
| 4 | ```screw(M4_dome_screw, 30)``` | Screw M4 dome x 30mm |
| 8 | ```washer(M2_washer)``` | Washer M2 x 5mm x 0.3mm |
| 8 | ```washer(M2p5_washer)``` | Washer M2.5 x 5.9mm x 0.5mm |
| 12 | ```washer(M3_washer)``` | Washer M3 x 7mm x 0.5mm |
| 32 | ```washer(M4_washer)``` | Washer M4 x 9mm x 0.8mm |
@@ -825,7 +878,7 @@ Needs updating as mostly obsolete versions.
### Modules
| Module | Description |
|:--- |:--- |
| ```hot_end(type, filament, naked = false)``` | Draw specified hot end |
| ```hot_end(type, filament, naked = false, resistor_wire_rotate = [0,0,0])``` | Draw specified hot end |
![hot_ends](tests/png/hot_ends.png)
@@ -939,10 +992,11 @@ IEC mains inlets and outlet.
| 1 | ```iec(IEC_inlet)``` | IEC inlet |
| 1 | ```iec(IEC_inlet_atx)``` | IEC inlet for ATX |
| 1 | ```iec(IEC_outlet)``` | IEC outlet RS 811-7193 |
| 10 | ```nut(M3_nut, nyloc = true)``` | Nut M3 x 2.4mm nyloc |
| 1 | ```iec(IEC_switched_fused_inlet)``` | IEC320 C14 switched fused inlet module |
| 12 | ```nut(M3_nut, nyloc = true)``` | Nut M3 x 2.4mm nyloc |
| 4 | ```screw(M3_cs_cap_screw, 10)``` | Screw M3 cs cap x 10mm |
| 6 | ```screw(M3_cs_cap_screw, 12)``` | Screw M3 cs cap x 12mm |
| 10 | ```washer(M3_washer)``` | Washer M3 x 7mm x 0.5mm |
| 8 | ```screw(M3_cs_cap_screw, 12)``` | Screw M3 cs cap x 12mm |
| 12 | ```washer(M3_washer)``` | Washer M3 x 7mm x 0.5mm |
<a href="#top">Top</a>
@@ -1099,7 +1153,9 @@ Nuts for leadscrews.
| ```leadnut_hole_dia(type)``` | The diameter of the screw holes |
| ```leadnut_hole_pitch(type)``` | The radia pitch of the screw holes |
| ```leadnut_holes(type)``` | The number of screw holes |
| ```leadnut_lead(type)``` | Screw lead |
| ```leadnut_od(type)``` | Outer diameter of the shank |
| ```leadnut_pitch(type)``` | Screw pitch |
| ```leadnut_screw(type)``` | The type of the fixing screws |
### Functions
@@ -1240,6 +1296,9 @@ LMnUU linear bearings.
| Function | Description |
|:--- |:--- |
| ```bearing_dia(type)``` | Outside diameter |
| ```bearing_groove_dia(type)``` | Groove diameter |
| ```bearing_groove_length(type)``` | Groove length |
| ```bearing_groove_spacing(type)``` | Spacing between grooves, outer to outer, ie includes the grooves themselves |
| ```bearing_length(type)``` | Total length |
| ```bearing_rod_dia(type)``` | Internal diameter |
@@ -1258,12 +1317,21 @@ LMnUU linear bearings.
### Vitamins
| Qty | Module call | BOM entry |
| ---:|:--- |:---|
| 1 | ```linear_bearing(LM10LUU)``` | Linear bearing LM10LUU |
| 1 | ```linear_bearing(LM10UU)``` | Linear bearing LM10UU |
| 1 | ```linear_bearing(LM12LUU)``` | Linear bearing LM12LUU |
| 1 | ```linear_bearing(LM12UU)``` | Linear bearing LM12UU |
| 1 | ```linear_bearing(LM16LUU)``` | Linear bearing LM16LUU |
| 1 | ```linear_bearing(LM16UU)``` | Linear bearing LM16UU |
| 1 | ```linear_bearing(LM3LUU)``` | Linear bearing LM3LUU |
| 1 | ```linear_bearing(LM3UU)``` | Linear bearing LM3UU |
| 1 | ```linear_bearing(LM4LUU)``` | Linear bearing LM4LUU |
| 1 | ```linear_bearing(LM4UU)``` | Linear bearing LM4UU |
| 1 | ```linear_bearing(LM5LUU)``` | Linear bearing LM5LUU |
| 1 | ```linear_bearing(LM5UU)``` | Linear bearing LM5UU |
| 1 | ```linear_bearing(LM6LUU)``` | Linear bearing LM6LUU |
| 1 | ```linear_bearing(LM6UU)``` | Linear bearing LM6UU |
| 1 | ```linear_bearing(LM8LUU)``` | Linear bearing LM8LUU |
| 1 | ```linear_bearing(LM8UU)``` | Linear bearing LM8UU |
@@ -1555,11 +1623,16 @@ If a nut is given a child then it gets placed on its top surface.
| 1 | ```nut(M2p5_nut)``` | Nut M2.5 x 2.2mm |
| 1 | ```nut(M2p5_nut, nyloc = true)``` | Nut M2.5 x 2.2mm nyloc |
| 1 | ```nut(M2p5_nut, nylon = true)``` | Nut M2.5 x 2.2mm nylon |
| 1 | ```hammer_nut(M3_hammer_nut)``` | Nut M3 hammer |
| 1 | ```sliding_t_nut(M3_sliding_t_nut)``` | Nut M3 sliding T |
| 1 | ```nut(M3_nut)``` | Nut M3 x 2.4mm |
| 1 | ```nut(M3_nut, brass = true)``` | Nut M3 x 2.4mm brass |
| 1 | ```nut(M3_nut, nyloc = true)``` | Nut M3 x 2.4mm nyloc |
| 1 | ```hammer_nut(M4_hammer_nut)``` | Nut M4 hammer |
| 1 | ```sliding_t_nut(M4_sliding_t_nut)``` | Nut M4 sliding T |
| 1 | ```nut(M4_nut)``` | Nut M4 x 3.2mm |
| 1 | ```nut(M4_nut, nyloc = true)``` | Nut M4 x 3.2mm nyloc |
| 1 | ```sliding_t_nut(M5_sliding_t_nut)``` | Nut M5 sliding T |
| 1 | ```nut(M5_nut)``` | Nut M5 x 4mm |
| 1 | ```nut(M5_nut, nyloc = true)``` | Nut M5 x 4mm nyloc |
| 1 | ```nut(M6_half_nut)``` | Nut M6 x 3mm |
@@ -1678,8 +1751,9 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
### Functions
| Function | Description |
|:--- |:--- |
| ```pcb_component_position(type, name)``` | Return x y position of specified component |
| ```pcb_component_position(type, name, index = 0)``` | Return x y position of specified component |
| ```pcb_coord(type, p)``` | Convert offsets from the edge to coordinates relative to the centre |
| ```pcb_grid_pos(type, x, y, z = 0)``` | Returns a pcb grid position |
| ```pcb_screw(type, cap = hs_cap)``` | Mounting screw type |
### Modules
@@ -1699,7 +1773,7 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
| ```pcb_component_position(type, name)``` | Position child at the specified component position |
| ```pcb_components(type, cutouts = false, angle = undef)``` | Draw list of PCB components on the PCB |
| ```pcb_cutouts(type, angle = undef)``` | Make cut outs to clear components on a PCB |
| ```pcb_grid(type, x, y, z = 0)``` | Positions children at specified grid positions |
| ```pcb_grid(type, x, y, z = 0)``` | Positions children at specified grid position |
| ```pcb_screw_positions(type)``` | Positions children at the mounting hole positions |
| ```pcb_spacer(screw, height, wall = 1.8, taper = 0)``` | Generate STL for PCB spacer |
| ```rj45(cutout = false)``` | Draw RJ45 Ethernet connector |
@@ -1729,7 +1803,7 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
| 1 | ```molex_254(2)``` | Molex KK header 2 way |
| 1 | ```molex_254(3)``` | Molex KK header 3 way |
| 16 | ```nut(M2_nut, nyloc = true)``` | Nut M2 x 1.6mm nyloc |
| 28 | ```nut(M2p5_nut, nyloc = true)``` | Nut M2.5 x 2.2mm nyloc |
| 32 | ```nut(M2p5_nut, nyloc = true)``` | Nut M2.5 x 2.2mm nyloc |
| 12 | ```nut(M3_nut, nyloc = true)``` | Nut M3 x 2.4mm nyloc |
| 12 | ```nut(M4_nut, nyloc = true)``` | Nut M4 x 3.2mm nyloc |
| 1 | ```pcb(PI_IO)``` | PI_IO V2 |
@@ -1740,11 +1814,13 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
| 1 | ```pcb(PERF74x51)``` | Perfboard 74 x 51mm |
| 1 | ```pcb(PERF80x20)``` | Perfboard 80 x 20mm |
| 1 | ```pin_socket(2p54header, 13, 2, right_angle = true)``` | Pin socket 13 x 2 right_angle |
| 1 | ```pcb(RAMPSEndstop)``` | RAMPS Endstop Switch |
| 1 | ```pcb(RPI3)``` | Raspberry Pi 3 |
| 1 | ```pcb(RPI0)``` | Raspberry Pi Zero |
| 16 | ```screw(M2_cap_screw, 25)``` | Screw M2 cap x 25mm |
| 4 | ```screw(M2p5_cap_screw, 16)``` | Screw M2.5 cap x 16mm |
| 8 | ```screw(M2p5_cap_screw, 20)``` | Screw M2.5 cap x 20mm |
| 4 | ```screw(M2p5_cap_screw, 35)``` | Screw M2.5 cap x 35mm |
| 8 | ```screw(M2p5_pan_screw, 20)``` | Screw M2.5 pan x 20mm |
| 4 | ```screw(M2p5_pan_screw, 25)``` | Screw M2.5 pan x 25mm |
| 4 | ```screw(M2p5_pan_screw, 35)``` | Screw M2.5 pan x 35mm |
@@ -1756,7 +1832,7 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
| 2 | ```green_terminal(gt_2p54, 4)``` | Terminal block 4 way 0.1" |
| 1 | | USB A to Mini B lead |
| 16 | ```washer(M2_washer)``` | Washer M2 x 5mm x 0.3mm |
| 28 | ```washer(M2p5_washer)``` | Washer M2.5 x 5.9mm x 0.5mm |
| 32 | ```washer(M2p5_washer)``` | Washer M2.5 x 5.9mm x 0.5mm |
| 12 | ```washer(M3_washer)``` | Washer M3 x 7mm x 0.5mm |
| 12 | ```washer(M4_washer)``` | Washer M4 x 9mm x 0.8mm |
| 1 | ```pcb(ZC_A0591)``` | ZC-A0591 ULN2003 driver PCB |
@@ -1772,6 +1848,7 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
| 4 | pcb_spacer25110_2.stl |
| 4 | pcb_spacer25120_2.stl |
| 4 | pcb_spacer25230.stl |
| 4 | pcb_spacer25240.stl |
| 4 | pcb_spacer2570.stl |
| 4 | pcb_spacer2580.stl |
| 4 | pcb_spacer2590.stl |
@@ -1861,6 +1938,7 @@ Pin headers and sockets, etc.
|:--- |:--- |
| ```box_header(type, cols = 1, rows = 1, smt = false, cutout = false)``` | Draw box header |
| ```idc_transition(type, cols = 5, skip = [], cutout = false)``` | Draw IDC transition header |
| ```jst_xh_header(type, pin_count, right_angle=false, colour, pin_colour)``` | Draw JST XH connector |
| ```pin(type, length = undef)``` | Draw a header pin |
| ```pin_header(type, cols = 1, rows = 1, smt = false, right_angle = false, cutout = false)``` | Draw pin header |
| ```pin_socket(type, cols = 1, rows = 1, right_angle = false, height = 0, smt = false, cutout = false)``` | Draw pin socket |
@@ -2069,10 +2147,10 @@ Linear rails with carriages.
### Modules
| Module | Description |
|:--- |:--- |
| ```carriage(type, rail)``` | Draw the specified carriage |
| ```carriage(type, rail, end_color = grey20, wiper_color = grey20)``` | Draw the specified carriage |
| ```carriage_hole_positions(type)``` | Position children over screw holes |
| ```rail(type, length)``` | Draw the specified rail |
| ```rail_assembly(type, length, pos)``` | Rail and carriage assembly |
| ```rail_assembly(type, length, pos, carriage_end_color = grey20, carriage_wiper_color = grey20)``` | Rail and carriage assembly |
| ```rail_hole_positions(type, length, first = 0, screws = 100, both_ends = true)``` | Position children over screw holes |
| ```rail_screws(type, length, thickness, screws = 100)``` | Place screws in the rail |
@@ -2159,7 +2237,7 @@ Ring terminals and earth assemblies for DiBond panels.
---
<a name="Rockers"></a>
## Rockers
Rocket switch. Also used for neon indicator in the same form factor.
Rocker switch. Also used for neon indicator in the same form factor.
[vitamins/rockers.scad](vitamins/rockers.scad) Object definitions.
@@ -2215,16 +2293,23 @@ Steel rods and studding with chamfered ends.
### Modules
| Module | Description |
|:--- |:--- |
| ```rod(d , l)``` | Draw a smooth rod with specified length and diameter |
| ```studding(d , l)``` | Draw a threaded rod with specified length and diameter |
| ```leadscrew(d , l, lead, starts, center = true)``` | Draw a leadscrew with specified diameter, length, lead and number of starts |
| ```rod(d , l, center = true)``` | Draw a smooth rod with specified diameter and length |
| ```studding(d , l, center = true)``` | Draw a threaded rod with specified diameter and length |
![rod](tests/png/rod.png)
### Vitamins
| Qty | Module call | BOM entry |
| ---:|:--- |:---|
| 1 | ```leadscrew(10, 80, 8, 4)``` | Leadscrew 10 x 80mm, 8mm lead, 4 starts |
| 1 | ```leadscrew(12, 80, 12, 4)``` | Leadscrew 12 x 80mm, 12mm lead, 4 starts |
| 1 | ```leadscrew(16, 80, 16, 4)``` | Leadscrew 16 x 80mm, 16mm lead, 4 starts |
| 1 | ```leadscrew(6, 80, 2, 1)``` | Leadscrew 6 x 80mm, 2mm lead, 1 starts |
| 1 | ```leadscrew(8, 80, 8, 4)``` | Leadscrew 8 x 80mm, 8mm lead, 4 starts |
| 1 | ```rod(10, 80)``` | Smooth rod 10mm x 80mm |
| 1 | ```rod(12, 80)``` | Smooth rod 12mm x 80mm |
| 1 | ```rod(16, 80)``` | Smooth rod 16mm x 80mm |
| 1 | ```rod(3, 80)``` | Smooth rod 3mm x 80mm |
| 1 | ```rod(4, 80)``` | Smooth rod 4mm x 80mm |
| 1 | ```rod(5, 80)``` | Smooth rod 5mm x 80mm |
@@ -2232,6 +2317,7 @@ Steel rods and studding with chamfered ends.
| 1 | ```rod(8, 80)``` | Smooth rod 8mm x 80mm |
| 1 | ```studding(10, 80)``` | Threaded rod M10 x 80mm |
| 1 | ```studding(12, 80)``` | Threaded rod M12 x 80mm |
| 1 | ```studding(16, 80)``` | Threaded rod M16 x 80mm |
| 1 | ```studding(3, 80)``` | Threaded rod M3 x 80mm |
| 1 | ```studding(4, 80)``` | Threaded rod M4 x 80mm |
| 1 | ```studding(5, 80)``` | Threaded rod M5 x 80mm |
@@ -2290,17 +2376,17 @@ Machine screws and wood screws with various head styles.
| Qty | Module call | BOM entry |
| ---:|:--- |:---|
| 1 | ```screw(No632_pan_screw, 30)``` | Screw 6-32 pan x 30mm |
| 1 | ```screw(M2_cap_screw, 25)``` | Screw M2 cap x 25mm |
| 1 | ```screw(M2_cs_cap_screw, 25)``` | Screw M2 cs cap x 25mm |
| 1 | ```screw(M2p5_cap_screw, 25)``` | Screw M2.5 cap x 25mm |
| 1 | ```screw(M2p5_pan_screw, 30)``` | Screw M2.5 pan x 30mm |
| 1 | ```screw(M3_cap_screw, 25)``` | Screw M3 cap x 25mm |
| 1 | ```screw(M3_cs_cap_screw, 25)``` | Screw M3 cs cap x 25mm |
| 1 | ```screw(M3_dome_screw, 25)``` | Screw M3 dome x 25mm |
| 1 | ```screw(M2_cap_screw, 10)``` | Screw M2 cap x 10mm |
| 1 | ```screw(M2_cs_cap_screw, 10)``` | Screw M2 cs cap x 10mm |
| 1 | ```screw(M2p5_cap_screw, 10)``` | Screw M2.5 cap x 10mm |
| 1 | ```screw(M2p5_pan_screw, 10)``` | Screw M2.5 pan x 10mm |
| 1 | ```screw(M3_cap_screw, 10)``` | Screw M3 cap x 10mm |
| 1 | ```screw(M3_cs_cap_screw, 10)``` | Screw M3 cs cap x 10mm |
| 1 | ```screw(M3_dome_screw, 10)``` | Screw M3 dome x 10mm |
| 1 | ```screw(M3_grub_screw, 6)``` | Screw M3 grub x 6mm |
| 1 | ```screw(M3_hex_screw, 30)``` | Screw M3 hex x 30mm |
| 1 | ```screw(M3_low_cap_screw, 25)``` | Screw M3 low cap x 25mm |
| 1 | ```screw(M3_pan_screw, 30)``` | Screw M3 pan x 30mm |
| 1 | ```screw(M3_hex_screw, 10)``` | Screw M3 hex x 10mm |
| 1 | ```screw(M3_low_cap_screw, 10)``` | Screw M3 low cap x 10mm |
| 1 | ```screw(M3_pan_screw, 10)``` | Screw M3 pan x 10mm |
| 1 | ```screw(M4_cap_screw, 25)``` | Screw M4 cap x 25mm |
| 1 | ```screw(M4_cs_cap_screw, 25)``` | Screw M4 cs cap x 25mm |
| 1 | ```screw(M4_dome_screw, 25)``` | Screw M4 dome x 25mm |
@@ -2315,8 +2401,8 @@ Machine screws and wood screws with various head styles.
| 1 | ```screw(M6_pan_screw, 30)``` | Screw M6 pan x 30mm |
| 1 | ```screw(M8_cap_screw, 35)``` | Screw M8 cap x 35mm |
| 1 | ```screw(M8_hex_screw, 30)``` | Screw M8 hex x 30mm |
| 1 | ```screw(No2_screw, 30)``` | Screw No2 pan wood x 30mm |
| 1 | ```screw(No4_screw, 30)``` | Screw No4 pan wood x 30mm |
| 1 | ```screw(No2_screw, 10)``` | Screw No2 pan wood x 10mm |
| 1 | ```screw(No4_screw, 10)``` | Screw No4 pan wood x 10mm |
| 1 | ```screw(No6_cs_screw, 30)``` | Screw No6 cs wood x 30mm |
| 1 | ```screw(No6_screw, 30)``` | Screw No6 pan wood x 30mm |
@@ -2476,7 +2562,7 @@ Filament spool models
### Modules
| Module | Description |
|:--- |:--- |
| ```spool(type)``` | Draw specified spool |
| ```spool(type, filament_depth = 0, filament_colour = "white", filament_d = 3)``` | Draw specified spool with optional filament |
![spools](tests/png/spools.png)
@@ -2604,7 +2690,7 @@ NEMA stepper motor model.
| ```NEMA_length(type)``` | Body length |
| ```NEMA_radius(type)``` | End cap radius |
| ```NEMA_shaft_dia(type)``` | Shaft diameter |
| ```NEMA_shaft_length(type)``` | Shaft length above the face |
| ```NEMA_shaft_length(type)``` | Shaft length above the face, if a list then a leadscrew: length, lead, starts |
| ```NEMA_width(type)``` | Width of the square face |
### Functions
@@ -2616,7 +2702,7 @@ NEMA stepper motor model.
### Modules
| Module | Description |
|:--- |:--- |
| ```NEMA(type)``` | Draw specified NEMA stepper motor |
| ```NEMA(type, shaft_angle = 0)``` | Draw specified NEMA stepper motor |
| ```NEMA_outline(type)``` | 2D outline |
| ```NEMA_screw_positions(type, n = 4)``` | Positions children at the screw holes |
| ```NEMA_screws(type, screw, n = 4, screw_length = 8, earth = undef)``` | Place screws and optional earth tag |
@@ -3577,6 +3663,7 @@ The ring spacing as well as the number of spokes can be specified, if zero a gas
| Qty | Filename |
| ---:|:--- |
| 1 | fan_guard_120.stl |
| 1 | fan_guard_17.stl |
| 1 | fan_guard_25.stl |
| 1 | fan_guard_30.stl |
| 1 | fan_guard_40.stl |
@@ -4024,7 +4111,7 @@ Knob with embedded hex head screw.
### Modules
| Module | Description |
|:--- |:--- |
| ```screw_knob(screw)``` | Generate the STL foe a knob to fit the specified hex screw |
| ```screw_knob(screw)``` | Generate the STL for a knob to fit the specified hex screw |
| ```screw_knob_assembly(screw, length)``` | Assembly with the screw in place |
![screw_knob](tests/png/screw_knob.png)
@@ -4362,6 +4449,8 @@ Maths utilities for manipulating vectors and matrices.
### Functions
| Function | Description |
|:--- |:--- |
| ```angle_between(v1, v2)``` | Return the angle between two vectors |
| ```euler(R)``` | Convert a rotation matrix to a Euler rotation vector. |
| ```identity(n, x = 1)``` | Construct an arbitrary size identity matrix |
| ```reverse(v)``` | Reverse a vector |
| ```rotate(a, v)``` | Generate a 4x4 rotation matrix, ```a``` can be a vector of three angles or a single angle around ```z```, or around axis ```v``` |
@@ -4372,6 +4461,7 @@ Maths utilities for manipulating vectors and matrices.
| ```transpose(m)``` | Transpose an arbitrary size matrix |
| ```unit(v)``` | Convert ```v``` to a unit vector |
| ```vec3(v)``` | Return a 3 vector with the first three elements of ```v``` |
| ```vec4(v)``` | Return a 4 vector with the first three elements of ```v``` |
![maths](tests/png/maths.png)
@@ -4538,9 +4628,12 @@ An additional twist around the path can be specified. If the path is closed this
| ```after(path1, path2)``` | Translate ```path2``` so its start meets the end of ```path1``` and then concatenate |
| ```arc_points(r, a = [90, 0, 180], al = 90)``` | Generate the points of a circular arc |
| ```before(path1, path2)``` | Translate ```path1``` so its end meets the start of ```path2``` and then concatenate |
| ```circle_points(r = 1, z = 0)``` | Generate the points of a circle, setting z makes a single turn spiral |
| ```cap(facets, segment = 0, end)``` | Create the mesh for an end cap |
| ```circle_points(r = 1, z = 0, dir = -1)``` | Generate the points of a circle, setting z makes a single turn spiral |
| ```helical_twist_per_segment(r, pitch, sides)``` | Calculate the twist around Z that rotate_from_to() introduces |
| ```path_length(path, i = 0, length = 0)``` | Calculated the length along a path |
| ```rectangle_points(w, h)``` | Generate the points of a rectangle |
| ```skin_faces(points, npoints, facets, loop, offset = 0)``` | Create the mesh for the swept volume without end caps |
| ```sweep(path, profile, loop = false, twist = 0)``` | Generate the point list and face list of the swept volume |
### Modules
@@ -4551,6 +4644,50 @@ An additional twist around the path can be specified. If the path is closed this
![sweep](tests/png/sweep.png)
<a href="#top">Top</a>
---
<a name="Thread"></a>
## Thread
Utilities for making threads with sweep. They can be used to model screws, nuts, studding, leadscrews, etc, and also to make printed threads.
The ends can be tapered, flat or chamfered by setting the ```top``` and ```bot``` parameters to -1 for tapered, 0 for a flat cut and positive to
specify a chamfer angle.
Threads are by default solid, so the male version is wrapped around a cylinder and the female inside a tube. This can be suppressed to just get the helix, for
example to make a printed pot with a screw top lid.
Threads with a typical 60 degree angle appear too bright with OpenSCAD's primitive lighting model as they face towards the lights more than the top and sides of
a cylinder. To get around this a colour can be passed to thread that is used to colour the cylinder and then toned down to colour the helix.
Making the ends requires a CGAL intersection, which make threads relatively slow. For this reason they are generally disabled when using the GUI but can
be enabled by setting ```$show_threads``` to ```true```. When the tests are run, by default, threads are enabled only for things that feature them like screws.
This behaviour can be changed by setting a ```SHOW_THREADS``` environment variable to ```false``` to disable all threads and ```true``` to enable all threads.
The same variable also affects the generation of assembly diagrams.
Threads obey the $fn, $fa, $fs variables.
[utils/thread.scad](utils/thread.scad) Implementation.
[tests/thread.scad](tests/thread.scad) Code for this example.
### Functions
| Function | Description |
|:--- |:--- |
| ```metric_coarse_pitch(d)``` | Convert metric diameter to pitch |
| ```thread_profile(h, crest, angle, overlap = 0.1)``` | Create thread profile path |
### Modules
| Module | Description |
|:--- |:--- |
| ```female_metric_thread(d, pitch, length, center = true, top = -1, bot = -1, colour = undef)``` | Create female thread with metric profile |
| ```male_metric_thread(d, pitch, length, center = true, top = -1, bot = -1, solid = true, colour = undef)``` | Create male thread with metric profile |
| ```thread(dia, pitch, length, profile, center = true, top = -1, bot = -1, starts = 1, solid = true, female = false, colour = undef)``` | Create male or femail thread, ends can be tapered, chamfered or square |
![thread](tests/png/thread.png)
<a href="#top">Top</a>
---

View File

@@ -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
View 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("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

View File

@@ -27,6 +27,7 @@ import openscad
import subprocess
import bom
import times
import options
import time
import json
import shutil
@@ -96,6 +97,7 @@ def tests(tests):
index = {}
bodies = {}
times.read_times()
options.check_options(deps_dir)
#
# Make cover pic if does not exist as very slow. Delete it to force an update.
#
@@ -190,11 +192,12 @@ def tests(tests):
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 = 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)

View File

@@ -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
@@ -102,6 +103,7 @@ 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)
@@ -154,7 +156,7 @@ def views(target, do_assemblies = None):
f.write("use <%s/%s>\n" % (dir, filename))
f.write("%s();\n" % module);
#
# Run openscad on th created file
# Run openscad on the created file
#
dname = deps_name(deps_dir, filename)
for explode in [0, 1]:
@@ -163,11 +165,12 @@ def views(target, do_assemblies = None):
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)
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);
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)

View File

@@ -67,7 +67,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)

View File

@@ -35,4 +35,5 @@ module d_connectors()
}
if($preview)
d_connectors();
let($show_threads = true)
d_connectors();

30
tests/extrusions.scad Normal file
View File

@@ -0,0 +1,30 @@
//
// 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>
use <../utils/layout.scad>
include <../vitamins/extrusions.scad>
module extrusions()
layout([for(e = extrusions) extrusion_width(e)], 10)
extrusion(extrusions[$i], 80);
if ($preview)
extrusions();

View File

@@ -37,4 +37,5 @@ module inserts() {
}
if($preview)
inserts();
let($show_threads = true)
inserts();

View File

@@ -27,4 +27,5 @@ module leadnuts()
leadnut(leadnuts[$i]);
if($preview)
leadnuts();
let($show_threads = true)
leadnuts();

View File

@@ -22,8 +22,12 @@ use <../utils/layout.scad>
include <../vitamins/linear_bearings.scad>
module linear_bearings()
layout([for(b = linear_bearings) 2 * bearing_radius(b)])
layout([for(b = linear_bearings) 2 * bearing_radius(b)]) {
linear_bearing(linear_bearings[$i]);
translate([0, 30])
linear_bearing(long_linear_bearings[$i]);
}
if($preview)
linear_bearings();

View File

@@ -56,7 +56,7 @@ module maths() {
//
z = [0, 0, 1];
v = cross(u, z);
a = acos(u * z);
a = angle_between(u, z);
l = 20;
@@ -64,6 +64,11 @@ module maths() {
translate_z(l)
vflip()
arrow(l);
//
// Test Euler
//
assert(euler(rotate(r)) == r, "euler() failed");
}
rotate(45)

View File

@@ -22,13 +22,12 @@ use <../utils/layout.scad>
include <../vitamins/screws.scad>
module nuts() {
for(nyloc = [false, true])
translate([0, nyloc ? 20 : 0])
layout([for(n = nuts) 2 * nut_radius(n)], 5)
nut(nuts[$i], nyloc);
layout([for(n = nuts) 2 * nut_radius(n)], 5) let(n = nuts[$i]) {
for(nyloc = [false, true])
translate([0, nyloc ? 20 : 0])
nut(n, nyloc);
translate([0, 40])
layout([for(n = nuts) 2 * nut_radius(n)], 5) let(n = nuts[$i]) {
translate([0, 40]) {
if(n == M3_nut)
nut(n, brass = true);
@@ -45,7 +44,28 @@ module nuts() {
if(n == M8_nut)
#nut_trap(M8_cap_screw, n, h = 30);
}
translate([0, 60]) {
if(n == M3_nut)
sliding_t_nut(M3_sliding_t_nut);
if(n == M4_nut)
sliding_t_nut(M4_sliding_t_nut);
if(n == M5_nut)
sliding_t_nut(M5_sliding_t_nut);
}
translate([0, 80]) {
if(n == M3_nut)
hammer_nut(M3_hammer_nut);
if(n == M4_nut)
hammer_nut(M4_hammer_nut);
}
}
}
if($preview)
nuts();
let($show_threads = true)
nuts();

View File

@@ -29,4 +29,5 @@ module opengrab_test() {
}
if($preview)
opengrab_test();
let($show_threads = true)
opengrab_test();

View File

@@ -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 <../lib.scad>
include <../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, [],

View File

@@ -26,4 +26,5 @@ module pillars()
pillar(pillars[$i]);
if($preview)
pillars();
let($show_threads = true)
pillars();

Binary file not shown.

Before

Width:  |  Height:  |  Size: 102 KiB

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 114 KiB

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 KiB

After

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 115 KiB

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 114 KiB

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 75 KiB

After

Width:  |  Height:  |  Size: 75 KiB

BIN
tests/png/extrusions.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 121 KiB

After

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 114 KiB

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 147 KiB

After

Width:  |  Height:  |  Size: 149 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 81 KiB

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 78 KiB

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 98 KiB

After

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 109 KiB

After

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 146 KiB

After

Width:  |  Height:  |  Size: 145 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 149 KiB

After

Width:  |  Height:  |  Size: 188 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

After

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 162 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 98 KiB

After

Width:  |  Height:  |  Size: 92 KiB

BIN
tests/png/thread.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 215 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 106 KiB

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 143 KiB

After

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 92 KiB

After

Width:  |  Height:  |  Size: 93 KiB

View File

@@ -34,7 +34,7 @@ module rails()
nut = screw_nut(screw);
washer = screw_washer(screw);
rail_assembly(rail, length, rail_travel(rail, length) / 2);
rail_assembly(rail, length, rail_travel(rail, length) / 2, $i<2 ? grey20 : "green", $i<2 ? grey20 : "red");
rail_screws(rail, length, sheet + nut_thickness(nut, true) + washer_thickness(washer));

View File

@@ -24,13 +24,23 @@ include <../vitamins/linear_bearings.scad>
use <../vitamins/rod.scad>
module rods()
layout([for(b = linear_bearings) 2 * bearing_radius(b)]) {
layout([for(b = linear_bearings) 2 * bearing_radius(b)]) let(d = bearing_rod_dia(linear_bearings[$i])){
rod(bearing_rod_dia(linear_bearings[$i]), 80);
rod(d, 80);
translate([0, 20])
studding(bearing_rod_dia(linear_bearings[$i]), 80);
translate([0, 30])
studding(d, 80);
if(d >= 6)
translate([0, 60]) {
starts = d > 6 ? 4 : 1;
pitch = d > 14 ? 4
: d > 10 ? 3 : 2;
let($show_threads = true)
leadscrew(d, 80, starts * pitch, starts);
}
}
if($preview)
rods();
let($show_threads = true)
rods();

View File

@@ -25,13 +25,15 @@ for(y = [0 : len(screw_lists) -1])
for(x = [0 : len(screw_lists[y]) -1]) {
screw = screw_lists[y][x];
if(screw) {
length = screw_max_thread(screw)
? screw_longer_than(screw_max_thread(screw) + 5)
: screw_head_type(screw) == hs_grub ? 6 : 30;
length = screw_head_type(screw) == hs_grub ? 6
: screw_radius(screw) <= 1.5 ? 10
: screw_max_thread(screw) ? screw_longer_than(screw_max_thread(screw) + 5)
: 30;
translate([x * 20, y * 20])
screw(screw, length);
}
}
if($preview)
screws();
let($show_threads = true)
screws();

View File

@@ -23,9 +23,9 @@ use <../utils/layout.scad>
include <../vitamins/spools.scad>
module spools()
layout([for(s = spools) spool_height(s)], 100)
layout([for(s = spools) spool_height(s)], 100) let(s = spools[$i])
rotate([90, 0, 90])
spool(spools[$i]);
spool(s, filament_depth = spool_depth(s) / 2, filament_colour = [pp1_colour, pp2_colour, pp3_colour, pp4_colour][$i % 4], filament_d = $i ? 3 : 1.75);
if($preview)
spools();

View File

@@ -44,7 +44,7 @@ knot = [ for(i=[0:.2:359])
(19*cos(3*i) + 40)*sin(2*i),
19*sin(3*i) ] ];
sweep(knot, L_points, loop = true, twist = 0);
sweep(knot, L_points, loop = true);
p = transform_points([[0,0,0], [20,0,5], [10,30,4], [0,0,0], [0,0,20]], scale(10));
n = 100;

52
tests/thread.scad Normal file
View File

@@ -0,0 +1,52 @@
//
// 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>
use <../utils/thread.scad>
pitch = 2;
starts = 4;
profile = thread_profile(pitch / 2, pitch * 0.366, 30);
module threads()
for(female = [false, true]) translate([0, female ? -20 : 0]) {
length = female ? 8 : 40;
dia = female ? 8 : 8 - pitch;
colour = female ? brass : silver;
thread(dia, starts * pitch, length, profile, starts = starts, top = 45, bot = 45, female = female, colour = colour);
color(colour)
translate([20, 0])
thread(dia, starts * pitch, length, profile, starts = starts, top = 0, bot = 0, female = female);
translate([40, 0])
thread(dia, starts * pitch, length, profile, starts = starts, top = -1, bot = -1, female = female, colour = colour);
color(colour)
translate([60, 0])
thread(dia, 2 * pitch, length, profile, starts = 2, top = -1, bot = -1, female = female);
color(colour)
translate([80, 0])
thread(dia, pitch, length, profile, starts = 1, top = -1, bot = -1, female = female);
}
let($show_threads = true)
threads();

View File

@@ -27,4 +27,5 @@ module toggles()
toggle(toggles[$i], 3);
if($preview)
toggles();
let($show_threads = true)
toggles();

View File

@@ -43,7 +43,7 @@ module ellipse(xr, yr) scale([1, yr / xr]) circle4n(xr);
module extrude_if(h, center = true) //! Extrudes 2D object to 3D when ```h``` is nonzero, otherwise leaves it 2D
if(h)
linear_extrude(height = h, center = center) // 3D
linear_extrude(height = h, center = center, convexity = 2) // 3D
children();
else
children(); // 2D

View File

@@ -39,9 +39,9 @@ function rotate(a, v) = //! Generate a 4x4 rotation matrix, ```a``` can be a vec
sy = sin(av[1]),
sz = sin(av[2]))
[
[ cy * cz, cz * sx * sy - cx * sz, cx * cz * sy + sx * sz, 0],
[ cy * sz, cx * cz + sx * sy * sz,-cz * sx + cx * sy * sz, 0],
[-sy, cy * sx, cx * cy, 0],
[ cy * cz, sx * sy * cz - cx * sz, cx * sy * cz + sx * sz, 0],
[ cy * sz, sx * sy * sz + cx * cz, cx * sy * sz - sx * cz, 0],
[-sy, sx * cy, cx * cy, 0],
[ 0, 0, 0, 1]
]
: let(s = sin(a),
@@ -65,6 +65,7 @@ function scale(v) = let(s = is_list(v) ? v : [v, v, v]) //! Generate a 4x4 matr
];
function vec3(v) = [v.x, v.y, v.z]; //! Return a 3 vector with the first three elements of ```v```
function vec4(v) = [v.x, v.y, v.z, 1]; //! Return a 4 vector with the first three elements of ```v```
function transform(v, m) = vec3(m * [v.x, v.y, v.z, 1]); //! Apply 4x4 transform to a 3 vector by extending it and cropping it again
function transform_points(path, m) = [for(p = path) transform(p, m)]; //! Apply transform to a path
function unit(v) = let(n = norm(v)) n ? v / n : v; //! Convert ```v``` to a unit vector
@@ -74,3 +75,11 @@ function transpose(m) = [ for(j = [0 : len(m[0]) - 1]) [ for(i = [0 : len(m) - 1
function identity(n, x = 1) = [for(i = [0 : n - 1]) [for(j = [0 : n - 1]) i == j ? x : 0] ]; //! Construct an arbitrary size identity matrix
function reverse(v) = let(n = len(v) - 1) n < 0 ? [] : [for(i = [0 : n]) v[n - i]]; //! Reverse a vector
function angle_between(v1, v2) = acos(v1 * v2 / (norm(v1) * norm(v2))); //! Return the angle between two vectors
// https://www.gregslabaugh.net/publications/euler.pdf
function euler(R) = let(ay = asin(-R[2][0]), cy = cos(ay)) //! Convert a rotation matrix to a Euler rotation vector.
cy ? [ atan2(R[2][1] / cy, R[2][2] / cy), ay, atan2(R[1][0] / cy, R[0][0] / cy) ]
: R[2][0] < 0 ? [atan2( R[0][1], R[0][2]), 180, 0]
: [atan2(-R[0][1], -R[0][2]), -180, 0];

View File

@@ -62,6 +62,7 @@ function rotate_from_to(a, b) =
function calculate_twist(A, B) = let(D = transpose3(B) * A) atan2(D[1][0], D[0][0]);
//
// Compute a 4x3 matrix to orientate a frame of the sweep given the position and a 3x3 rotation matrix.
// Note that the rotation matrix is transposed to allow post multiplication.
//
function orientate(p, r) =
let(x = r[0], y = r[1], z = r[2])
@@ -79,12 +80,21 @@ function rot3_z(a) =
[ [ c, -s, 0],
[ s, c, 0],
[ 0, 0, 1] ];
//
// Calculate the unit tangent at a vertex given the indices before and after. One of these can be the same as i in the case
// of the start and end of a non closed path.
// of the start and end of a non closed path. Note that the edges are converted to unit vectors so that their relative lengths
// don't affect the direction of the tangent.
//
function tangent(path, before, i, after) = unit(unit(path[after] - path[i]) - unit(path[before] - path[i]));
function tangent(path, before, i, after) = unit(unit(path[i] - path[before]) + unit(path[after] - path[i]));
//
// Calculate the twist per segment caused by rotate_from_to() instead of a simple Euler rotation around Z.
//
function helical_twist_per_segment(r, pitch, sides) = //! Calculate the twist around Z that rotate_from_to() introduces
let(step_angle = 360 / sides,
lt = 2 * r * sin(step_angle), // length of tangent between two facets
slope = atan(2 * pitch / sides / lt) // slope of tangents
) step_angle * sin(slope); // angle tangent should rotate around z projected onto axis rotate_from_to() uses
//
// Generate all the surface points of the swept volume.
//
@@ -111,24 +121,28 @@ function skin_points(profile, path, loop, twist = 0) =
each profile4 * orientate(path[i], rotations[i] * rot3_z(za))
];
function cap(facets, segment = 0) = [for(i = [0 : facets - 1]) segment ? facets * segment + i : facets - 1 - i];
function cap(facets, segment = 0, end) = //! Create the mesh for an end cap
let(reverse = is_undef(end) ? segment : end)
[for(i = [0 : facets - 1]) facets * segment + (reverse ? i : facets - 1 - i)];
function quad(p, a, b, c, d) = norm(p[a] - p[c]) > norm(p[b] - p[d]) ? [[b, c, d], [b, d, a]] : [[a, b, c], [a, c, d]];
function skin_faces(points, segs, facets, loop) = [for(i = [0 : facets - 1], s = [0 : segs - (loop ? 1 : 2)])
each quad(points,
s * facets + i,
s * facets + (i + 1) % facets,
((s + 1) % segs) * facets + (i + 1) % facets,
((s + 1) % segs) * facets + i)];
function skin_faces(points, npoints, facets, loop, offset = 0) = //! Create the mesh for the swept volume without end caps
[for(i = [0 : facets - 1], s = [0 : npoints - (loop ? 1 : 2)])
let(j = s + offset, k = loop ? (j + 1) % npoints : j + 1)
each quad(points,
j * facets + i,
j * facets + (i + 1) % facets,
k * facets + (i + 1) % facets,
k * facets + i)];
function sweep(path, profile, loop = false, twist = 0) = //! Generate the point list and face list of the swept volume
let(
segments = len(path),
npoints = len(path),
facets = len(profile),
points = skin_points(profile, path, loop, twist),
skin_faces = skin_faces(points, segments, facets, loop),
faces = loop ? skin_faces : concat([cap(facets)], skin_faces, [cap(facets, segments - 1)])
skin_faces = skin_faces(points, npoints, facets, loop),
faces = loop ? skin_faces : concat([cap(facets)], skin_faces, [cap(facets, npoints - 1)])
) [points, faces];
module sweep(path, profile, loop = false, twist = 0) { //! Draw a polyhedron that is the swept volume
@@ -141,9 +155,9 @@ function path_length(path, i = 0, length = 0) = //! Calculated the length along
i >= len(path) - 1 ? length
: path_length(path, i + 1, length + norm(path[i + 1] - path[i]));
function circle_points(r = 1, z = 0) = //! Generate the points of a circle, setting z makes a single turn spiral
function circle_points(r = 1, z = 0, dir = -1) = //! Generate the points of a circle, setting z makes a single turn spiral
let(sides = r2sides(r))
[for(i = [0 : sides - 1]) let(a = i * 360 / sides) [r * sin(a), r * cos(a), z * a / 360]];
[for(i = [0 : sides - 1]) let(a = dir * i * 360 / sides) [r * cos(a), r * sin(a), z * i / sides]];
function rectangle_points(w, h) = [[-w/2, -h/2, 0], [-w/2, h/2, 0], [w/2, h/2, 0], [w/2, -h/2, 0]]; //! Generate the points of a rectangle

217
utils/thread.scad Normal file
View File

@@ -0,0 +1,217 @@
//
// 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/>.
//
//
//! Utilities for making threads with sweep. They can be used to model screws, nuts, studding, leadscrews, etc, and also to make printed threads.
//!
//! The ends can be tapered, flat or chamfered by setting the ```top``` and ```bot``` parameters to -1 for tapered, 0 for a flat cut and positive to
//! specify a chamfer angle.
//!
//! Threads are by default solid, so the male version is wrapped around a cylinder and the female inside a tube. This can be suppressed to just get the helix, for
//! example to make a printed pot with a screw top lid.
//!
//! Threads with a typical 60 degree angle appear too bright with OpenSCAD's primitive lighting model as they face towards the lights more than the top and sides of
//! a cylinder. To get around this a colour can be passed to thread that is used to colour the cylinder and then toned down to colour the helix.
//!
//! Making the ends requires a CGAL intersection, which make threads relatively slow. For this reason they are generally disabled when using the GUI but can
//! be enabled by setting ```$show_threads``` to ```true```. When the tests are run, by default, threads are enabled only for things that feature them like screws.
//! This behaviour can be changed by setting a ```SHOW_THREADS``` environment variable to ```false``` to disable all threads and ```true``` to enable all threads.
//! The same variable also affects the generation of assembly diagrams.
//!
//! Threads obey the $fn, $fa, $fs variables.
//
include <../core.scad>
use <sweep.scad>
use <maths.scad>
use <tube.scad>
thread_colour_factor = 0.8; // 60 degree threads appear too bright due to the angle facing the light sources
function thread_profile(h, crest, angle, overlap = 0.1) = //! Create thread profile path
let(base = crest + 2 * (h + overlap) * tan(angle / 2))
[[-base / 2, -overlap, 0], [-crest / 2, h, 0], [crest / 2, h, 0], [base / 2, -overlap, 0]];
module thread(dia, pitch, length, profile, center = true, top = -1, bot = -1, starts = 1, solid = true, female = false, colour = undef) { //! Create male or femail thread, ends can be tapered, chamfered or square
//
// Apply colour if defined
//
module colour(factor) if(is_undef(colour)) children(); else color(colour * factor) children();
//
// Compress the profile to compensate for it being tilted by the helix angle
//
scale = cos(atan(pitch / (PI * dia)));
sprofile = [for(p = profile) [p.x * scale, p.y, p.z]];
//
// Extract some properties from the profile, perhaps they should be stored in it.
//
h = max([for(p = sprofile) p.y]);
maxx = max([for(p = sprofile) p.x]);
minx = min([for(p = sprofile) p.x]);
crest_xmax = max([for(p = sprofile) if(p.x != maxx) p.x]);
crest_xmin = min([for(p = sprofile) if(p.x != minx) p.x]);
//
// If the ends don't taper we need an extra half turn past the ends to be cropped horizontally.
//
extra_top = top < 0 ? 0 : -minx / pitch;
extra_bot = bot < 0 ? 0 : maxx / pitch;
turns = length / pitch + extra_top + extra_bot;
//
// Generate the helix path, possibly with tapered ends
//
dir = female ? 1 : -1;
r = dia / 2;
sides = r2sides4n(r);
step_angle = 360 / sides;
segs = ceil(turns * sides);
leadin = ceil(sides / starts);
final = floor(turns * sides) - leadin;
path = [for(i = [0 : segs],
R = i < leadin && bot < 0 ? r + dir * (h - h * i / leadin)
: i > final && top < 0 ? r + dir * h * (i - final) / leadin : r,
a = i * step_angle - 360 * extra_bot)
[R * cos(a), R * sin(a), a * pitch / 360]];
//
// Generate the skin vertices
//
facets = len(profile);
twist = helical_twist_per_segment(r, pitch, sides);
//
// For female threads we need to invert the profile
//
iprofile = female ? reverse([for(p = sprofile) [p.x, -p.y, 0]]) : sprofile;
//
// If the bottom is tapered then the twist will be greater, so pre-twist the profile to get the straight bit at the correct angle
//
rprofile = bot < 0 ? transform_points(iprofile, rotate(-dir * (helical_twist_per_segment(r - h, pitch, sides) - twist) * sides / PI))
: iprofile;
points = skin_points(rprofile, path, false, twist * segs);
//
// To form the ends correctly we need to use intersection but it is very slow with the full thread so we just
// intersect the start and the end and sweep the rest outside of the intersection.
//
top_chamfer_h = (top > 0 ? h * tan(top) : 0);
bot_chamfer_h = (bot > 0 ? h * tan(bot) : 0);
top_overlap = max( maxx, top_chamfer_h - crest_xmin) / pitch;
bot_overlap = max(-minx, bot_chamfer_h + crest_xmax) / pitch;
start = ceil(sides * (bot_overlap + extra_bot));
end = segs - ceil(sides * (top_overlap + extra_top));
start_skin_faces = skin_faces(points, start + 1, facets, false);
middle_skin_faces = skin_faces(points, end - start + 1, facets, false, start);
end_skin_faces = skin_faces(points, segs - end + 1, facets, false, end);
start_faces = concat([cap(facets) ], start_skin_faces, [cap(facets, start)]);
middle_faces = concat([cap(facets, start, false)], middle_skin_faces, [cap(facets, end)]);
end_faces = concat([cap(facets, end, false)], end_skin_faces, [cap(facets, segs)]);
overlap = - profile[0].y;
translate_z((center ? -length / 2 : 0)) {
ends_faces = concat(start_faces, end_faces);
for(i = [0 : starts - 1])
colour(thread_colour_factor)
rotate(360 * i / starts + (female ? 180 / starts : 0)) {
render() intersection() {
polyhedron(points, ends_faces);
len = length - 2 * eps;
rotate_extrude()
if(female) {
difference() {
translate([0, eps])
square([r + h + overlap, len]);
if(top_chamfer_h)
polygon([[0, length], [r, length], [r - h, length - top_chamfer_h], [0, length - top_chamfer_h]]);
if(bot_chamfer_h)
polygon([[0, 0], [r, 0], [r - h, bot_chamfer_h], [0, bot_chamfer_h]]);
}
}
else
difference() {
hull() {
translate([0, eps])
square([r, len]);
translate([0, bot_chamfer_h])
square([r + h + overlap, len - top_chamfer_h - bot_chamfer_h]);
}
if(!solid)
square([r - overlap, length]);
}
}
polyhedron(points, middle_faces);
}
if(solid)
colour(1)
rotate(90)
if(female)
tube(or = r + (top < 0 || bot < 0 ? h : 0) + 2 * overlap, ir = r, h = length, center = false);
else
cylinder(d = dia, h = length);
}
}
module male_metric_thread(d, pitch, length, center = true, top = -1, bot = -1, solid = true, colour = undef) { //! Create male thread with metric profile
H = pitch * sqrt(3) / 2;
h = 5 * H / 8;
minor_d = d - 2 * h;
thread(minor_d, pitch, length, thread_profile(h, pitch / 8, 60), center, top, bot, solid = solid, colour = colour);
}
module female_metric_thread(d, pitch, length, center = true, top = -1, bot = -1, colour = undef) { //! Create female thread with metric profile
H = pitch * sqrt(3) / 2;
h = 5 * H / 8;
thread(d, pitch, length, thread_profile(h, pitch / 4, 60), center, top, bot, solid = false, female = true, colour = colour);
}
function metric_coarse_pitch(d) //! Convert metric diameter to pitch
= d == 1.6 ? 0.35 // M1.6
: [0.4, // M2
0.45,// M2.5
0.5, // M3
0.6, // M3.5
0.7, // M4
0,
0.8, // M5
0,
1.0, // M6
0,
0,
0,
1.25, // M8
0,
0,
0,
1.5, // M10
0,
0,
0,
1.75, // M12
0,
0,
0,
0, // M14
0,
0,
0,
2.0, // M16
][d * 2 - 4];

View File

@@ -41,9 +41,7 @@ function no_point(str) = chr([for(c = str) if(c == ".") ord("p") else ord(c)]);
// We model the belt path at the pitch radius of the pulleys and the pitch line of the belt to get an accurate length.
// The belt is then drawn by offseting each side from the pitch line.
//
module belt(type, points, gap = 0, gap_pt = undef) { //! Draw a belt path given a set of points and pitch radii where the pulleys are. Closed loop unless a gap is specified
belt_colour = grey20;
tooth_colour = grey50;
module belt(type, points, gap = 0, gap_pt = undef, belt_colour = grey20, tooth_colour = grey50) { //! Draw a belt path given a set of points and pitch radii where the pulleys are. Closed loop unless a gap is specified
width = belt_width(type);
pitch = belt_pitch(type);
thickness = belt_thickness(type);

View File

@@ -21,6 +21,7 @@
//! D-connectors. Can be any number of ways, male or female, solder buckets, PCB mount or IDC, with or without pillars.
//
include <../core.scad>
use <../utils/thread.scad>
d_pillar_color = grey90;
d_plug_shell_color = grey80;
@@ -51,16 +52,24 @@ module d_pillar() { //! Draw a pillar for a D-connector
height = 4.5;
screw = 2.5;
screw_length = 8;
color(d_pillar_color) {
translate_z(-screw_length)
cylinder(d = screw, h = screw_length + 1);
pitch = metric_coarse_pitch(screw);
translate_z(-screw_length)
if(show_threads)
male_metric_thread(screw, pitch, screw_length, false, top = 0, colour = d_pillar_color);
else
color(d_pillar_color)
cylinder(d = screw, h = screw_length + 1);
color(d_pillar_color) {
linear_extrude(height = height)
difference() {
circle(r = rad, $fn = 6);
circle(d = screw);
}
}
}
if(show_threads)
female_metric_thread(screw, pitch, height, false, colour = d_pillar_color);
}
module d_plug(type, socket = false, pcb = false, idc = false) { //! Draw specified D plug, which can be IDC, PCB or plain solder bucket

View File

@@ -61,30 +61,35 @@ heater_y = heater_width / 2;
fan_x_offset = rad_dia / 2 + 4;
module e3d_resistor(type) {
module e3d_resistor(type, naked = false, resistor_wire_rotate = [0,0,0]) {
translate([11 - heater_x, -3 - heater_y, heater_height / 2 + nozzle_h]) {
color("grey")
rotate([-90, 0, 0])
cylinder(r = resistor_dia / 2, h = resistor_len);
color("red")
translate([-3.5/2, resistor_len + 3.5/2 + 1, 0]) {
cylinder(d = 3.5, h = 36);
if(!naked)
color("red")
translate([0, resistor_len + 3.5/2 + 1, 0]) {
rotate(resistor_wire_rotate) {
translate([-3.5/2, 0, 0]) {
cylinder(d = 3.5, h = 36);
translate([3.5, 0, 0])
cylinder(r = 3.5 / 2, h = 36);
translate([3.5, 0, 0])
cylinder(r = 3.5 / 2, h = 36);
}
}
}
}
}
module heater_block(type) {
module heater_block(type, naked = false, resistor_wire_rotate = [0,0,0]) {
translate_z(-hot_end_length(type)) {
translate_z(nozzle_h)
color("lightgrey")
translate([-heater_x, -heater_y, 0])
cube([heater_length, heater_width, heater_height]);
e3d_resistor(type);
e3d_resistor(type, naked, resistor_wire_rotate);
e3d_nozzle(type);
}
}
@@ -118,7 +123,7 @@ module e3d_fan(type) {
fan(fan30x10);
}
module e3d_hot_end(type, filament, naked = false) {
module e3d_hot_end(type, filament, naked = false, resistor_wire_rotate = [0,0,0]) {
insulator_length = hot_end_insulator_length(type);
inset = hot_end_inset(type);
h_ailettes = rad_len / (2 * rad_nb_ailettes - 1);
@@ -146,17 +151,17 @@ module e3d_hot_end(type, filament, naked = false) {
}
rotate(90)
heater_block(type);
heater_block(type, naked, resistor_wire_rotate);
if(!naked)
translate_z(inset - insulator_length)
e3d_fan();
}
module e3d_hot_end_assembly(type, filament, naked = false) {
module e3d_hot_end_assembly(type, filament, naked = false, resistor_wire_rotate = [0,0,0]) {
bundle = 3.2;
e3d_hot_end(type, filament, naked);
e3d_hot_end(type, filament, naked, resistor_wire_rotate);
// Wire and ziptie
if(!naked)

128
vitamins/extrusion.scad Normal file
View File

@@ -0,0 +1,128 @@
//
// 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/>.
//
//! Aluminium extrusion.
//
include <../core.scad>
function extrusion_width(type) = type[1]; //! Width of extrusion
function extrusion_height(type) = type[2]; //! Height of extrusion
function extrusion_center_hole(type) = type[3]; //! Diameter of center hole
function extrusion_corner_hole(type) = type[4]; //! Diameter of corner hole
function extrusion_center_square(type) = type[5]; //! Size of center square
function extrusion_channel_width(type) = type[6]; //! Channel width
function extrusion_channel_width_internal(type) = type[7]; //! Internal channel width
function extrusion_tab_thickness(type) = type[8]; //! Tab thickness
function extrusion_spar_thickness(type) = type[9]; //! Spar thickness
function extrusion_fillet(type) = type[10]; //! Radius of corner fillet
module extrusion_cross_section(type, cornerHole) {
module extrusion_corner(type, cornerHole) {
width = extrusion_width(type);
tabThickness = extrusion_tab_thickness(type);
sparThickness = extrusion_spar_thickness(type);
centerSquare = extrusion_center_square(type);
channelWidth = extrusion_channel_width(type);
fillet = extrusion_fillet(type);
cornerSize = (width-channelWidth)/2;
cornerSquare = (width-extrusion_channel_width_internal(type))/2;
cornerHoleDiameter =extrusion_corner_hole(type);
translate([-width/2,-width/2]) {
difference() {
union() {
translate([fillet,0])
square([cornerSize-fillet,tabThickness]);
translate([0,fillet])
square([tabThickness,cornerSize-fillet]);
translate([fillet,fillet])
circle(fillet);
translate([fillet,fillet])
square([cornerSquare-fillet,cornerSquare-fillet]);
}
if(cornerHole)
translate([cornerSquare/2,cornerSquare/2])
circle(d=cornerHoleDiameter);
}
}
rotate(-135) translate([centerSquare/2,-sparThickness/2]) square([sqrt(2)*(width-centerSquare-cornerSquare)/2,sparThickness]);
}
module extrusion_center_section(type) {
width = extrusion_width(type);
tabThickness = extrusion_tab_thickness(type);
sparThickness = extrusion_spar_thickness(type);
centerSquare = extrusion_center_square(type);
channelWidth = extrusion_channel_width(type);
translate([0,width/2])
for(angle=[225,315])
rotate(angle)
translate([centerSquare/2,-sparThickness/2])
square([sqrt(2)*(width-centerSquare)/2,sparThickness]);
translate([0,-width/2])
for(angle=[45,135])
rotate(angle)
translate([centerSquare/2,-sparThickness/2])
square([sqrt(2)*(width-centerSquare)/2,sparThickness]);
centerHeight = width-channelWidth;
translate([-width/2,-centerHeight/2])
square([tabThickness,centerHeight]);
translate([width/2-tabThickness,-centerHeight/2])
square([tabThickness,centerHeight]);
}
centerSquare = extrusion_center_square(type);
width = extrusion_width(type);
height = extrusion_height(type);
count = (height-width)/width;
for(i=[0:count])
translate([0,i*width+(width-height)/2])
difference() {
square([centerSquare,centerSquare],center=true);
circle(d=extrusion_center_hole(type));
}
translate([0,(width-height)/2])
for(angle=[0,90])
rotate(angle)
extrusion_corner(type, cornerHole);
translate([0,-(width-height)/2])
for(angle=[180,270])
rotate(angle)
extrusion_corner(type, cornerHole);
if(count>=1)
for(i=[1:count])
translate([0,i*width-height/2])
extrusion_center_section(type);
}
module extrusion(type, length, cornerHole = false) { //! Draw the specified extrusion
vitamin(str("extrusion(", type[0], ", ", length, "): Extrusion ", type[0], " x ", length, "mm"));
color(grey90)
linear_extrude(height = length)
extrusion_cross_section(type, cornerHole);
}

35
vitamins/extrusions.scad Normal file
View 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/>.
//
//
// Extrusion
//
// W H d1 d2 s cw cwi t st f
E2020 = [ "E2020", 20, 20, 4.2, 0, 8, 6, 12.0, 2, 2, 1 ];
E2040 = [ "E2040", 20, 40, 4.2, 0, 8, 6, 12.0, 2, 2, 1 ];
E2060 = [ "E2060", 20, 60, 4.2, 0, 8, 6, 12.0, 2, 2, 1 ];
E2080 = [ "E2080", 20, 80, 4.2, 0, 8, 6, 12.0, 2, 2, 1 ];
E3030 = [ "E3030", 30, 30, 6.8, 4.2, 12, 8, 16.5, 2, 2, 1 ];
E3060 = [ "E3060", 30, 60, 6.8, 4.2, 12, 8, 16.5, 2, 2, 1 ];
E4040 = [ "E4040", 40, 40, 10.5, 6.0, 15, 10, 20.0, 5.5, 3, 1 ];
E4080 = [ "E4080", 40, 80, 10.5, 6.0, 15, 10, 20.0, 5.5, 3, 1 ];
extrusions = [E2020,E2040,E2060,E2080,E3030,E3060,E4040,E4080];
use <extrusion.scad>

View File

@@ -40,7 +40,8 @@ fan50x15 = [50, 15, 48, 20, M4_dome_screw, 25, 12.5,100,7, 0, undef];
fan40x11 = [40, 11, 37, 16, M3_dome_screw, 25, 7.5,100, 9, 0, undef];
fan30x10 = [30, 10, 27, 12, M3_dome_screw, 17, 10, 100, 5, 0, undef];
fan25x10 = [25, 10, 24, 10, M2p5_pan_screw, 16, 10, 100, 5, 0, undef];
fan17x8 = [17, 8, 16, 6.75, M2_cap_screw, 12.6, 8, 100, 7, 0, undef];
fans = [fan25x10, fan30x10, fan40x11, fan50x15, fan60x15, fan60x25, fan70x15, fan80x25, fan80x38, fan120x25];
fans = [fan17x8, fan25x10, fan30x10, fan40x11, fan50x15, fan60x15, fan60x25, fan70x15, fan80x25, fan80x38, fan120x25];
use <fan.scad>

View File

@@ -44,10 +44,10 @@ function hot_end_length(type) = hot_end_total_length(type) - hot_end_inset(type)
use <jhead.scad>
use <e3d.scad>
module hot_end(type, filament, naked = false) { //! Draw specified hot end
module hot_end(type, filament, naked = false, resistor_wire_rotate = [0,0,0]) { //! Draw specified hot end
if(hot_end_style(type) == jhead)
jhead_hot_end_assembly(type, filament, naked);
if(hot_end_style(type) == e3d)
e3d_hot_end_assembly(type, filament, naked);
e3d_hot_end_assembly(type, filament, naked, resistor_wire_rotate);
}

View File

@@ -29,6 +29,10 @@ fused_spades2 = [[spade6p4, 13, -7, 0, 0],
[spade4p8, 8.5, -7, -9, 90],
[spade4p8, 8.5, 7, -9, 90]];
iec320c14FusedSwitchedSpades = [[spade4p8, 8.5, 7, 10, 0],
[spade4p8, 8.5, 0, 20, 0],
[spade4p8, 8.5, 9, -2, 0]];
inlet_spades = [[spade6p4, 9, -7, -5.5, 0],
[spade6p4, 9, 7, -5.5, 0],
[spade6p4, 9, 0, 5.5, 0]];
@@ -52,10 +56,11 @@ outlet_spades = [[spade4p8ll, 8, -7, -2, 90],
// w h r t
IEC_fused_inlet = ["IEC_fused_inlet", "IEC fused inlet JR-101-1F", M3_cs_cap_screw, 36, 27, 16, 31, 3, 28, 31, 2, 2.0, 30, 33, 4, 3.0, 44, 15, fused_spades, false ];
IEC_fused_inlet2= ["IEC_fused_inlet2","IEC fused inlet old", M3_cs_cap_screw, 36, 27, 14, 31, 3, 28, 31, 2, 2.5, 30, 33, 4, 2.5, 44, 18, fused_spades2, false ];
IEC_320_C14_switched_fused_inlet = ["IEC_switched_fused_inlet", "IEC320 C14 switched fused inlet module",
M3_cs_cap_screw, 40, 27, 16,46.8,3,28, 48, 2.4, 1.0, 33, 57, 4, 3.0, 48,16.5, iec320c14FusedSwitchedSpades, false ];
IEC_inlet = ["IEC_inlet", "IEC inlet", M3_cs_cap_screw, 40, 28, 18, 20, 3, 28, 20.5, 4, 2.5, 37, 23, 1, 2.5, 48, 14, inlet_spades, false ];
IEC_inlet_atx = ["IEC_inlet_atx", "IEC inlet for ATX", M3_cs_cap_screw, 40, 27, 18, 19, 3, 30.5, 22, 2, 2.0, 30.5, 22, 2, 4.0, 50, 15, atx_spades, false ];
IEC_outlet = ["IEC_outlet", "IEC outlet RS 811-7193", M3_cs_cap_screw, 40, 32, 18, 24, 3, 28, 20.5, 2, 0.0, 29, 29, 2, 2.8, 50, 23, outlet_spades, true ];
iecs = [IEC_inlet, IEC_inlet_atx, IEC_fused_inlet, IEC_fused_inlet2, IEC_outlet];
iecs = [IEC_inlet, IEC_inlet_atx, IEC_fused_inlet, IEC_fused_inlet2, IEC_320_C14_switched_fused_inlet, IEC_outlet];
use <iec.scad>

View File

@@ -22,6 +22,7 @@
//
include <../core.scad>
use <../utils/quadrant.scad>
use <../utils/thread.scad>
function insert_length(type) = type[1]; //! Length
function insert_outer_d(type) = type[2]; //! Outer diameter at the top
@@ -45,17 +46,18 @@ module insert(type) { //! Draw specified insert
vitamin(str("insert(", type[0], "): Heatfit insert M", insert_screw_diameter(type)));
$fn = 64;
explode(20, offset =[0, 0, -5]) color(brass) translate_z(eps) {
vflip(){
r1 = insert_screw_diameter(type) / 2;
r2 = insert_barrel_d(type) / 2;
r3 = insert_ring3_d(type) / 2;
r4 = insert_ring2_d(type) / 2;
r5 = insert_outer_d(type) / 2;
h1 = ring1_h;
h2 = ring1_h + gap;
h3 = ring1_h + gap + ring2_h;
h4 = ring1_h + gap + ring2_h + gap;
thread_d = insert_screw_diameter(type);
explode(20, offset =[0, 0, -5]) translate_z(eps) vflip() {
r1 = thread_d / 2;
r2 = insert_barrel_d(type) / 2;
r3 = insert_ring3_d(type) / 2;
r4 = insert_ring2_d(type) / 2;
r5 = insert_outer_d(type) / 2;
h1 = ring1_h;
h2 = ring1_h + gap;
h3 = ring1_h + gap + ring2_h;
h4 = ring1_h + gap + ring2_h + gap;
color(brass)
rotate_extrude()
polygon([
[r1, 0],
@@ -72,7 +74,9 @@ module insert(type) { //! Draw specified insert
[r5, h1],
[r5, 0],
]);
}
if(show_threads)
female_metric_thread(thread_d, metric_coarse_pitch(thread_d), length, center = false, colour = brass);
}
}

View File

@@ -21,7 +21,8 @@
//! Nuts for leadscrews.
//
include <../core.scad>
include <../utils/tube.scad>
use <../utils/tube.scad>
use <../utils/thread.scad>
function leadnut_bore(type) = type[2]; //! Thread size
function leadnut_od(type) = type[3]; //! Outer diameter of the shank
@@ -33,6 +34,8 @@ function leadnut_holes(type) = type[8]; //! The number of screw hole
function leadnut_hole_dia(type) = type[9]; //! The diameter of the screw holes
function leadnut_hole_pitch(type) = type[10]; //! The radia pitch of the screw holes
function leadnut_screw(type) = type[11]; //! The type of the fixing screws
function leadnut_pitch(type) = type[12]; //! Screw pitch
function leadnut_lead(type) = type[13]; //! Screw lead
function leadnut_shank(type) = leadnut_height(type) - leadnut_flange_t(type) - leadnut_flange_offset(type); //! The length of the shank below the flange
@@ -47,11 +50,18 @@ module leadnut_screw_positions(type) { //! Position children at the screw holes
module leadnut(type) { //! Draw specified leadnut
vitamin(str("leadnut(", type[0], "): ", type[1]));
bore_r = (leadnut_bore(type) + 0.5) / 2;
bore_d = leadnut_bore(type);
bore_r = bore_d / 2;
h = leadnut_height(type);
pitch = leadnut_pitch(type);
lead = leadnut_lead(type);
color("dimgrey") vflip()
translate_z(-leadnut_flange_offset(type) - leadnut_flange_t(type)) {
tube(or = leadnut_od(type) / 2, ir = bore_r, h = leadnut_height(type), center = false);
tube(or = leadnut_od(type) / 2, ir = bore_r, h = h, center = false);
if(show_threads)
thread(bore_d, lead, h, thread_profile(pitch / 2, pitch * 0.366, 30), false, starts = lead / pitch, female = true, solid = false);
translate_z(leadnut_flange_offset(type))
linear_extrude(height = leadnut_flange_t(type))

View File

@@ -17,8 +17,8 @@
// If not, see <https://www.gnu.org/licenses/>.
//
LSN8x2 = ["LSN8x2", "Leadscrew nut 8 x 2", 8, 10.2, 15, 22, 3.5, 1.5, 4, 3.5, 8, M3_cap_screw];
LSN8x8 = ["LSN8x8", "Leadscrew nut 8 x 8 RobotDigg",8, 12.75,19, 25.4, 4.1, 0, 3, 3.5, 19.05/2, M3_cap_screw];
LSN8x2 = ["LSN8x2", "Leadscrew nut 8 x 2", 8, 10.2, 15, 22, 3.5, 1.5, 4, 3.5, 8, M3_cap_screw, 2, 2];
LSN8x8 = ["LSN8x8", "Leadscrew nut 8 x 8 RobotDigg",8, 12.75,19, 25.4, 4.1, 0, 3, 3.5, 19.05/2, M3_cap_screw, 2, 8];
leadnuts = [LSN8x2, LSN8x8];

View File

@@ -25,20 +25,41 @@ include <../core.scad>
use <../utils/tube.scad>
bearing_colour = grey70;
groove_colour = grey60;
seal_colour = grey20;
function bearing_length(type) = type[1]; //! Total length
function bearing_dia(type) = type[2]; //! Outside diameter
function bearing_rod_dia(type) = type[3]; //! Internal diameter
function bearing_length(type) = type[1]; //! Total length
function bearing_dia(type) = type[2]; //! Outside diameter
function bearing_rod_dia(type) = type[3]; //! Internal diameter
function bearing_groove_length(type) = type[4]; //! Groove length
function bearing_groove_dia(type) = type[5]; //! Groove diameter
function bearing_groove_spacing(type) = type[6]; //! Spacing between grooves, outer to outer, ie includes the grooves themselves
function bearing_radius(type) = bearing_dia(type) / 2; //! Outside radius
module linear_bearing(type) { //! Draw specified linear bearing
vitamin(str("linear_bearing(", type[0], "): Linear bearing LM", bearing_rod_dia(type),"UU"));
vitamin(str("linear_bearing(", type[0], "): Linear bearing ", type[0]));
casing_t = bearing_radius(type) / 10;
casing_ir = bearing_radius(type) - casing_t;
length = bearing_length(type);
or = bearing_radius(type);
gl = bearing_groove_length(type);
gr = bearing_groove_dia(type) / 2;
gs = bearing_groove_spacing(type);
offset = (length-gs)/2;
color(bearing_colour) tube(or = bearing_radius(type), ir = casing_ir, h = bearing_length(type));
color(seal_colour) tube(or = casing_ir, ir = bearing_rod_dia(type) / 2, h = bearing_length(type) - 0.5);
if(gs==0) {
color(bearing_colour) tube(or = or, ir = casing_ir, h = length);
} else {
translate_z(-length/2) {
color(bearing_colour) tube(or = or, ir = casing_ir, h = offset, center = false);
color(groove_colour) translate_z(offset) tube(or = gr, ir = casing_ir, h = gl,center = false);
color(bearing_colour) translate_z(offset+gl) tube(or = or, ir = casing_ir, h = gs-2*gl, center = false);
color(groove_colour) translate_z(offset+gs-gl) tube(or = gr, ir = casing_ir, h = gl, center = false);
color(bearing_colour) translate_z(offset+gs) tube(or = or, ir = casing_ir, h = offset, center = false);
}
}
color(seal_colour) tube(or = casing_ir, ir = bearing_rod_dia(type) / 2, h = length - 0.5);
}

View File

@@ -20,14 +20,25 @@
//
// Linear bearings
//
LM12UU = ["LM12UU", 30, 21, 12];
LM10UU = ["LM10UU", 29, 19, 10];
LM8UU = ["LM8UU", 24, 15, 8];
LM6UU = ["LM6UU", 19, 12, 6];
LM5UU = ["LM5UU", 15, 10, 5];
LM4UU = ["LM4UU", 12, 8, 4];
LM3UU = ["LM3UU", 10, 7, 3];
// L od id gl gd gs
LM16UU = ["LM16UU", 37, 28, 16, 1.6, 27.0, 26.5];
LM16LUU = ["LM16LUU", 70, 28, 16, 1.6, 27.0, 53.0];
LM12UU = ["LM12UU", 30, 21, 12, 1.3, 20.0, 23.0];
LM12LUU = ["LM12LUU", 57, 21, 12, 1.3, 20.0, 46.0];
LM10UU = ["LM10UU", 29, 19, 10, 1.3, 18.0, 22.0];
LM10LUU = ["LM10LUU", 55, 19, 10, 1.3, 18.0, 44.0];
LM8UU = ["LM8UU", 24, 15, 8, 1.1, 14.3, 17.5];
LM8LUU = ["LM8LUU", 45, 15, 8, 1.1, 14.3, 35.0];
LM6UU = ["LM6UU", 19, 12, 6, 1.1, 11.5, 13.5];
LM6LUU = ["LM6LUU", 35, 12, 6, 1.1, 11.5, 27.0];
LM5UU = ["LM5UU", 15, 10, 5, 1.1, 9.5, 10.2];
LM5LUU = ["LM5LUU", 28, 10, 5, 1.1, 9.5, 20.4];
LM4UU = ["LM4UU", 12, 8, 4, 0, 0, 0];
LM4LUU = ["LM4LUU", 23, 8, 4, 0, 0, 0];
LM3UU = ["LM3UU", 10, 7, 3, 0, 0, 0];
LM3LUU = ["LM3LUU", 19, 7, 3, 0, 0, 0];
linear_bearings = [LM3UU, LM4UU, LM5UU, LM6UU, LM8UU, LM10UU, LM12UU];
linear_bearings = [LM3UU, LM4UU, LM5UU, LM6UU, LM8UU, LM10UU, LM12UU, LM16UU];
long_linear_bearings = [LM3LUU, LM4LUU, LM5LUU, LM6LUU, LM8LUU, LM10LUU, LM12LUU, LM16LUU];
use <linear_bearing.scad>

View File

@@ -25,7 +25,10 @@
include <../core.scad>
use <washer.scad>
use <screw.scad>
use <../utils/fillet.scad>
use <../utils/rounded_cylinder.scad>
use <../utils/thread.scad>
use <../utils/tube.scad>
brass_colour = brass;
function nut_size(type) = type[1]; //! Diameter of the corresponding screw
@@ -37,7 +40,8 @@ function nut_trap_depth(type) = type[6]; //! Depth of nut trap
function nut_flat_radius(type) = nut_radius(type) * cos(30); //! Radius across the flats
module nut(type, nyloc = false, brass = false, nylon = false) { //! Draw specified nut
hole_rad = nut_size(type) / 2;
thread_d = nut_size(type);
hole_rad = thread_d / 2;
outer_rad = nut_radius(type);
thickness = nut_thickness(type);
nyloc_thickness = nut_thickness(type, true);
@@ -45,18 +49,29 @@ module nut(type, nyloc = false, brass = false, nylon = false) { //! Draw specifi
vitamin(str("nut(", type[0], arg(nyloc, false, "nyloc"), arg(brass, false, "brass"), arg(nylon, false, "nylon"),
"): Nut M", nut_size(type), " x ", thickness, "mm ", desc));
explode(nyloc ? 10 : 0)
color(brass ? brass_colour : nylon ? grey30: grey70) {
colour = brass ? brass_colour : nylon ? grey30: grey70;
explode(nyloc ? 10 : 0) {
color(colour) {
linear_extrude(height = thickness)
difference() {
circle(outer_rad, $fn = 6);
circle(hole_rad);
}
if(nyloc)
translate_z(-eps)
rounded_cylinder(r = outer_rad * cos(30) , h = nyloc_thickness, r2 = (nyloc_thickness - thickness) / 2, ir = hole_rad);
}
if(show_threads)
female_metric_thread(thread_d, metric_coarse_pitch(thread_d), thickness, center = false, colour = colour);
if(nyloc)
translate_z(thickness)
color("royalblue")
tube(or = thread_d / 2 + eps, ir = (thread_d * 0.8) / 2, h = (nyloc_thickness - thickness) * 0.8, center = false);
}
if($children)
translate_z(nut_thickness(type, nyloc))
children();
@@ -73,7 +88,8 @@ module nut_and_washer(type, nyloc) { //! Draw nut with corresponding washer
}
module wingnut(type) { //! Draw a wingnut
hole_rad = nut_size(type) / 2;
thread_d = nut_size(type);
hole_rad = thread_d / 2;
bottom_rad = nut_radius(type);
top_rad = type[4] / 2;
thickness = nut_thickness(type);
@@ -87,27 +103,107 @@ module wingnut(type) { //! Draw a wingnut
vitamin(str("wingnut(", type[0], "): Wingnut M", nut_size(type)));
explode(10) color(grey70) {
rotate_extrude()
polygon([
[hole_rad, 0],
[bottom_rad, 0],
[top_rad,, thickness],
[hole_rad, thickness]
]);
for(rot = [0, 180])
rotate([90, 0, rot]) linear_extrude(height = wing_thickness, center = true)
hull() {
translate([wing_span / 2 - wing_width / 2, wing_height - wing_width / 2])
circle(wing_width / 2);
polygon([
[bottom_rad * cos(top_angle) - eps, 0],
[wing_span / 2 - wing_width / 2, wing_height - wing_width / 2],
[top_rad * cos(top_angle) - eps, thickness],
]);
}
colour = silver;
explode(10) {
color(colour) {
rotate_extrude()
polygon([
[hole_rad, 0],
[bottom_rad, 0],
[top_rad,, thickness],
[hole_rad, thickness]
]);
for(rot = [0, 180])
rotate([90, 0, rot]) linear_extrude(height = wing_thickness, center = true)
hull() {
translate([wing_span / 2 - wing_width / 2, wing_height - wing_width / 2])
circle(wing_width / 2);
polygon([
[bottom_rad * cos(top_angle) - eps, 0],
[wing_span / 2 - wing_width / 2, wing_height - wing_width / 2],
[top_rad * cos(top_angle) - eps, thickness],
]);
}
}
if(show_threads)
female_metric_thread(thread_d, metric_coarse_pitch(thread_d), thickness, center = false, colour = colour);
}
}
module sliding_t_nut(type) {
vitamin(str("sliding_t_nut(", type[0], "): Nut M", nut_size(type), " sliding T"));
size = [type[7], type[2], nut_thickness(type)];
tabSizeY1 = type[8];
tabSizeY2 = type[9];
tabSizeZ = type[10];
holeRadius = nut_size(type) / 2;
if($preview)
color(grey80)
extrusionSlidingNut(size, tabSizeY1, tabSizeY2, tabSizeZ, holeRadius);
}
module hammer_nut(type) {
vitamin(str("hammer_nut(", type[0], "): Nut M", nut_size(type), " hammer"));
size = [type[7], type[2], nut_thickness(type)];
tabSizeY1 = type[8];
tabSizeY2 = type[9];
tabSizeZ = type[10];
holeRadius = nut_size(type) / 2;
if($preview)
color(grey80)
extrusionSlidingNut(size, tabSizeY1, tabSizeY2, tabSizeZ, holeRadius, 0, hammerNut = true);
}
module extrusionSlidingNut(size, tabSizeY1, tabSizeY2, tabSizeZ, holeRadius, holeOffset = 0, hammerNut = false) {
// center section
linear_extrude(size[2] - tabSizeZ)
difference() {
square([size[0], size[1]], center = true);
if(hammerNut) {
translate([size[0] / 2, size[1] / 2])
rotate(180)
fillet(1);
translate([-size[0] / 2, -size[1] / 2])
fillet(1);
}
if(holeRadius)
translate([holeOffset, 0])
circle(holeRadius);
}
translate_z(size[2] - tabSizeZ)
linear_extrude(tabSizeZ)
difference() {
square([size[0], tabSizeY2], center = true);
if(holeRadius)
translate([holeOffset, 0])
circle(holeRadius);
}
thread_d = 2 * holeRadius;
if(show_threads)
translate([holeOffset, 0])
female_metric_thread(thread_d, metric_coarse_pitch(thread_d), size[2], center = false);
// add the side tabs
for(m = [0, 1])
mirror([0, m, 0])
translate([0, tabSizeY2 / 2, size[2] - tabSizeZ]) {
cubeZ = 1;
translate([-size[0] / 2, 0, 0])
cube([size[0], (tabSizeY1 - tabSizeY2) / 2, cubeZ]);
translate_z(cubeZ)
rotate([0, -90, 0])
right_triangle(tabSizeZ - cubeZ, (tabSizeY1 - tabSizeY2) / 2, size[0], center = true);
}
}
function nut_trap_radius(nut, horizontal = false) = nut_radius(nut) + (horizontal ? layer_height / 4 : 0); //! Radius across the corners of a nut trap
function nut_trap_flat_radius(nut, horizontal = false) = nut_trap_radius(nut, horizontal) * cos(30); //! Radius across the flats of a nut trap

View File

@@ -51,6 +51,13 @@ toggle_nut = ["toggle_nut", 6.1, 9.2, 1.5, 1.5, M6_washer, 1.5];
M4_wingnut = ["M4_wingnut", 4, 10, 3.75,8, M4_washer, 0, 22, 10, 6, 3];
// sx ty1 ty2 tz
M3_sliding_t_nut = ["M3_sliding_t_nut", 3, 6, 4.0, 0, M3_washer, 0, 10, 10, 6, 3];
M4_sliding_t_nut = ["M4_sliding_t_nut", 4, 6, 4.5, 0, M4_washer, 0, 11, 10, 6, 3.25];
M5_sliding_t_nut = ["M5_sliding_t_nut", 5, 6, 4.5, 0, M5_washer, 0, 11, 10, 7, 3.25];
M3_hammer_nut = ["M3_hammer_nut", 3, 6, 4.0, 0, M3_washer, 0, 5.5, 10, 6, 2.75];
M4_hammer_nut = ["M4_hammer_nut", 4, 6, 4.5, 0, M4_washer, 0, 5.5, 10, 6, 3.25];
nuts = [M2_nut, M2p5_nut, M3_nut, M4_nut, M5_nut, M6_nut, M8_nut];
use <nut.scad>

View File

@@ -23,6 +23,7 @@
//! A permanent magnet that can be magnatized and de-magnatized electronically.
//
include <../core.scad>
use <../utils/thread.scad>
pitch = 33.8;
width = 40;
@@ -64,15 +65,20 @@ module opengrab() { //! Draw OpenGrab module
translate_z(depth - pillar - pcb / 2)
cube([width, width, pcb], center = true);
color(brass)
translate_z(1)
opengrab_hole_positions()
translate_z(1)
opengrab_hole_positions() {
color(brass)
linear_extrude(height = depth - 1)
difference() {
circle(d = 4.7 / cos(30), $fn = 6);
circle(r = 3/2);
}
if(show_threads)
female_metric_thread(3, metric_coarse_pitch(3), depth - 1, center = false, colour = brass);
}
}
module opengrab_target() { //! Draw OpenGrab target

View File

@@ -49,9 +49,12 @@ function pcb_grid(type) = type[13]; //! Grid if a perfboard
function pcb_polygon(type) = type[14]; //! Optional outline polygon for odd shaped boards
function pcb_screw(type, cap = hs_cap) = Len(type[15]) ? type[15] : find_screw(cap, screw_smaller_than(pcb_hole_d(type))); //! Mounting screw type
module pcb_grid(type, x, y, z = 0) //! Positions children at specified grid positions
translate([-pcb_length(type) / 2 + pcb_grid(type).x + 2.54 * x,
-pcb_width(type) / 2 + pcb_grid(type).y + 2.54 * y, pcb_thickness(type) + z])
function pcb_grid_pos(type, x, y, z = 0) = //! Returns a pcb grid position
[-pcb_length(type) / 2 + pcb_grid(type).x + 2.54 * x,
-pcb_width(type) / 2 + pcb_grid(type).y + 2.54 * y, pcb_thickness(type) + z];
module pcb_grid(type, x, y, z = 0) //! Positions children at specified grid position
translate(pcb_grid_pos(type, x, y, z))
children();
// allows negative ordinates to represent offsets from the far edge
@@ -715,6 +718,7 @@ module pcb_component(comp, cutouts = false, angle = undef) { //! Draw pcb compon
if(show(comp, "flat_flex")) flat_flex(cutouts);
if(show(comp, "D_plug")) if(!cutouts) translate_z(d_pcb_offset(comp[4])) d_plug(comp[4], pcb = true);
if(show(comp, "molex_hdr")) if(!cutouts) molex_254(comp[4]);
if(show(comp, "jst_xh")) if(!cutouts) jst_xh_header(jst_xh_header, comp[4], param(5, false), param(6, "white"), param(7, undef));
if(show(comp, "term254")) if(!cutouts) green_terminal(gt_2p54,comp[4], comp[5]);
if(show(comp, "gterm35")) if(!cutouts) green_terminal(gt_3p5, comp[4], comp[5]);
if(show(comp, "gterm635")) if(!cutouts) green_terminal(gt_6p35, comp[4], comp[5]);
@@ -730,8 +734,8 @@ module pcb_component(comp, cutouts = false, angle = undef) { //! Draw pcb compon
}
}
function pcb_component_position(type, name) = //! Return x y position of specified component
[for(comp = pcb_components(type), p = [pcb_coord(type, [comp.x, comp.y])]) if(comp[3] == name) [p.x, p.y]][0];
function pcb_component_position(type, name, index = 0) = //! Return x y position of specified component
[for(comp = pcb_components(type), p = [pcb_coord(type, [comp.x, comp.y])]) if(comp[3] == name) [p.x, p.y]][index];
module pcb_component_position(type, name) { //! Position child at the specified component position
for(comp = pcb_components(type)) {
@@ -807,9 +811,9 @@ module pcb(type) { //! Draw specified PCB
pcb_screw_positions(type)
tube(or = max(pcb_land_d(type), 1) / 2, ir = pcb_hole_d(type) / 2, h = t + 2 * eps);
fr4 = pcb_colour(type) == "green";
fr4 = pcb_colour(type) != "sienna";
plating = 0.15;
color(fr4 ? "silver" : "gold")
color(pcb_colour(type) == "green" ? "silver" : "gold")
translate_z(-plating)
linear_extrude(height = fr4 ? t + 2 * plating : plating)
if(Len(grid)) {

View File

@@ -218,17 +218,19 @@ RPI0 = ["RPI0", "Raspberry Pi Zero", 65, 30, 1.4, 3, 2.75, 6, "gre
[12.4, 3.4, -90, "mini_hdmi"],
[54, 2, -90, "usb_uA"],
[41.4, 2, -90, "usb_uA"],
[7.25, 16.7, 180, "uSD", [12, 11.5, 1.28]],
[7.25, 16.7, 180, "uSD", [12, 11.5, 1.4]],
[-1.3, 15, 0, "flat_flex"],
],
[": Micro SD card"],
[32.5 - 9.5 * 2.54, 26.5 - 1.27, 20, 2]];
EnviroPlus = ["EnviroPlus", "Enviro+", 65, 30, 1.6, 3, 2.75, 6, "white", false, [[3.5, 3.5], [-3.5, 3.5], [-3.5, -3.5], [3.5, -3.5]],
[[32.5, -3.5, 0, "-2p54socket", 20, 2, false, 5, true],
EnviroPlus = ["EnviroPlus", "Enviro+", 65, 30.6, 1.6, 3, 2.75, 6, "white", false, [[3.5, 3.8], [-3.5, 3.8], [-3.5, -3.8], [3.5, -3.8]],
[[32.5, -3.8, 0, "-2p54socket", 20, 2, false, 5, true],
[-15.5, 2.5, 0, "-chip", 15, 5, 3, "white"],
[-14.25,16.25, 0, "chip", 27.5, 13.5, 1.5]
],
[],
[]];
[8, 1.5, 9, 1]];
ArduinoUno3 = ["ArduinoUno3", "Arduino Uno R3", 68.58, 53.34, 1.6, 0, 3.3, 0, "#2140BE", false, [[15.24, 50.8],[66.04, 35.56],[66.04, 7.62],[13.97, 2.54]],
@@ -337,6 +339,20 @@ PERF74x51 = ["PERF74x51", "Perfboard 74 x 51mm", 74, 51, 1.0, 0, 3.0, 0, "sienna
PSU12V1A = ["PSU12V1A", "PSU 12V 1A", 67, 31, 1.7, 0, 3.9, 0, "green", true, [[3.5, 3.5], [-3.5, 3.5], [-3.5, -3.5], [3.5, -3.5]], [], []];
pcbs = [ExtruderPCB, PI_IO, RPI0, EnviroPlus, RPI3, ArduinoUno3, ArduinoLeonardo, Keyes5p1, PERF80x20, PERF70x50, PERF70x30, PERF60x40, PERF74x51, PSU12V1A, DuetE, Duex2, Duex5, Melzi, ZC_A0591];
RAMPSEndstop = ["RAMPSEndstop", "RAMPS Endstop Switch",
40.0, 16.0, 1.6, 0, 2.54, 0, "red", false,
[
[2, 2], [2, 13.5], [17, 13.5], [36, 13.5]
],
[
[ 12, 8, -90, "jst_xh", 3, true, "white", "silver"],
[ 26, 13.5, 0, "chip", 12, 4, 5.5],
[ 26, 10.5, 0, "chip", 12, 2, 5.5, "white"],
[ 27.5, 17, 15, "chip", 15, 0.5, 4.5, "silver"],
],
[]];
pcbs = [ExtruderPCB, PI_IO, RPI0, EnviroPlus, RPI3, ArduinoUno3, ArduinoLeonardo, Keyes5p1, PERF80x20, PERF70x50, PERF70x30, PERF60x40, PERF74x51, PSU12V1A, DuetE, Duex2, Duex5, Melzi, ZC_A0591, RAMPSEndstop];
use <pcb.scad>

View File

@@ -21,6 +21,7 @@
//! Threaded pillars. Each end can be male or female.
//
include <../core.scad>
use <../utils/thread.scad>
function pillar_name(type) = type[1]; //! Name of part
function pillar_thread(type) = type[2]; //! Thread diameter
@@ -41,30 +42,53 @@ module pillar(type) { //! Draw specified pillar
sex = str(sex(pillar_bot_thread(type)),"/", sex(pillar_top_thread(type)));
height = pillar_height(type);
thread_d = pillar_thread(type);
bot_thread_l = pillar_bot_thread(type);
top_thread_l = pillar_top_thread(type);
thread_colour = pillar_i_colour(type);
pitch = metric_coarse_pitch(thread_d);
vitamin(str("pillar(", type[0], "): Pillar ", pillar_name(type), " ", sex, " M", thread_d, "x", height));
if(bot_thread_l > 0)
translate_z(-bot_thread_l + eps)
if(show_threads)
male_metric_thread(thread_d, pitch, bot_thread_l, false, top = 0, colour = thread_colour);
else
color(thread_colour)
cylinder(h = bot_thread_l, d = thread_d);
if(top_thread_l > 0)
translate_z(height - eps)
if(show_threads)
male_metric_thread(thread_d, pitch, top_thread_l, false, bot = 0, colour = thread_colour);
else
color(thread_colour)
cylinder(h = top_thread_l, d = thread_d);
color(pillar_i_colour(type)) {
if(pillar_bot_thread(type) > 0)
translate_z(-pillar_bot_thread(type))
cylinder(h = pillar_bot_thread(type) + eps, d = pillar_thread(type));
if(pillar_top_thread(type) > 0)
translate_z(height - eps)
cylinder(h = pillar_top_thread(type) + eps, d = pillar_thread(type));
linear_extrude(height = height)
difference() {
circle(d = pillar_id(type), $fn = fn(pillar_ifn(type)));
circle(d = pillar_thread(type));
circle(d = thread_d);
}
top = height + min(pillar_top_thread(type), 0);
bot = -min(pillar_bot_thread(type), 0);
top = height + min(top_thread_l, 0);
bot = -min(bot_thread_l, 0);
translate_z(bot)
cylinder(h = top - bot, d = pillar_thread(type) + eps);
cylinder(h = top - bot, d = thread_d + eps);
}
if(show_threads) {
if(top_thread_l < 0)
translate_z(height)
vflip()
female_metric_thread(thread_d, pitch, -top_thread_l, false, colour = thread_colour);
if(bot_thread_l < 0)
female_metric_thread(thread_d, pitch, -bot_thread_l, false, colour = thread_colour);
}
if(pillar_od(type) > pillar_id(type))
color(pillar_o_colour(type)) linear_extrude(height = height)
difference() {

View File

@@ -30,8 +30,8 @@
// d r r d d
//
M2x16_brass_pillar = ["M2x16_brass_pillar", "nurled", 2, 16, 3.17, 3.17, 0, 0, brass, brass, 3,-3];
M3x13_hex_pillar = ["M3x13_hex_pillar", "hex", 3, 13, 5/cos(30), 5/cos(30), 6, 6, "silver", "silver", -6, 6];
M3x20_hex_pillar = ["M3x20_hex_pillar", "hex", 3, 20, 5/cos(30), 5/cos(30), 6, 6, "silver", "silver", -6, 6];
M3x13_hex_pillar = ["M3x13_hex_pillar", "hex", 3, 13, 5/cos(30), 5/cos(30), 6, 6, "silver", silver, -6, 6];
M3x20_hex_pillar = ["M3x20_hex_pillar", "hex", 3, 20, 5/cos(30), 5/cos(30), 6, 6, "silver", silver, -8, 8];
M3x20_nylon_pillar = ["M3x20_nylon_pillar", "nylon", 3, 20, 8, 5/cos(30), 0, 6, "white", brass, -6, 6];
M4x17_nylon_pillar = ["M4x17_nylon_pillar", "nylon", 4, 20, 8, 5/cos(30), 0, 6, "white", brass, -6, 6];
M3x20_nylon_hex_pillar = ["M3x20_nylon_hex_pillar", "hex nylon", 3, 20, 8/cos(30), 8/cos(30), 6, 6, grey20, grey20, -6, 6];

View File

@@ -205,3 +205,71 @@ module pin_socket(type, cols = 1, rows = 1, right_angle = false, height = 0, smt
}
}
}
module jst_xh_header(type, pin_count, right_angle=false, colour, pin_colour) { //! Draw JST XH connector
colour = colour ? colour : hdr_base_colour(type);
pin_colour = pin_colour ? pin_colour : hdr_pin_colour(type);
sizeY = 5.75;
pitch = hdr_pitch(type);
module jst_xh_socket(type, pin_count) {
socketSizeZ = hdr_socket_depth(type);
pinOffsetX = 2.45;
sizeY = 5.75;
wallThickness = 0.8;
size = [pinOffsetX * 2 + (pin_count - 1) * pitch, sizeY, socketSizeZ];
translate([-size[0] / 2, -size[1] / 2, 0]) {
// the base
cube([size[0], size[1], wallThickness]);
// the three full sides
translate([0, size[1] - wallThickness, 0])
cube([size[0], wallThickness, size[2]]);
cube([wallThickness, size[1], size[2]]);
translate([size[0] - wallThickness, 0, 0])
cube([wallThickness, size[1], size[2]]);
// the sides with cutouts
cube([size[0], wallThickness, 2]);
cutoutWidth = 1;
cutoutOffset = pinOffsetX - cutoutWidth / 2;
cube([cutoutOffset, wallThickness, size[2]]);
translate([size[0] - cutoutOffset, 0, 0])
cube([cutoutOffset, wallThickness, size[2]]);
cube([cutoutOffset, wallThickness, size[2]]);
translate([size[0]-cutoutOffset, 0, 0])
cube([cutoutOffset, wallThickness, size[2]]);
translate([cutoutOffset + cutoutWidth, 0, 0])
cube([size[0] - 2 * (cutoutWidth + cutoutOffset), wallThickness, size[2]]);
}
} // end module
color(colour)
if(right_angle)
translate([0, -1, sizeY / 2])
rotate([-90, 0, 180])
jst_xh_socket(type, pin_count);
else
jst_xh_socket(type, pin_count);
color(pin_colour)
for(x = [0 : pin_count - 1]) {
pinWidth = hdr_pin_width(type);
verticalPinLength = right_angle ? hdr_pin_below(type) + sizeY / 2 : hdr_pin_length(type);
translate([pitch * (x - (pin_count - 1) / 2), 0, 0]) {
pin(type, verticalPinLength);
if(right_angle) {
translate([0, -pinWidth / 2, sizeY / 2 - pinWidth / 2])
rotate([0, -90, 0])
rotate_extrude(angle = 90, $fn = 32)
translate([0, -pinWidth / 2])
square(pinWidth);
translate([0, -sizeY / 2 - 3 * pinWidth / 4, sizeY / 2])
rotate([90,0,0])
pin(type, hdr_pin_length(type) - hdr_pin_below(type));
}
}
}
}

Some files were not shown because too many files have changed in this diff Show More