Compare commits
96 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
0f1dff230a | ||
|
e379fa8ada | ||
|
313d7508df | ||
|
083caca4e8 | ||
|
49329df00c | ||
|
edc0b86bb1 | ||
|
5fbff060b0 | ||
|
b94ca4ad3a | ||
|
bc5515d35e | ||
|
44d213deaa | ||
|
145c5d9b1a | ||
|
7abbbd9b96 | ||
|
5b160cee88 | ||
|
3f31607840 | ||
|
1efed649cf | ||
|
b70c2f993c | ||
|
56e252f3dc | ||
|
f12b36ea04 | ||
|
bd5811e69b | ||
|
ede4da6f1d | ||
|
51cc2fd679 | ||
|
4ce2f53e20 | ||
|
e338c47e73 | ||
|
8328a70f42 | ||
|
cc794cd7c3 | ||
|
df28bd5116 | ||
|
61de6041d8 | ||
|
b2d712bca9 | ||
|
f3376edaf1 | ||
|
c073419c0b | ||
|
608168de8e | ||
|
fc45a40bd3 | ||
|
52e9c1d7fd | ||
|
ca1b34e9ca | ||
|
cbab9cea02 | ||
|
69cf998862 | ||
|
08bce9ec03 | ||
|
4aa7dbb416 | ||
|
7c7c2e5d3f | ||
|
f6f6664c0d | ||
|
2fd2e118a0 | ||
|
22c6fef113 | ||
|
dcf0c949b9 | ||
|
9ded315801 | ||
|
42e03679b4 | ||
|
d2c795f5f5 | ||
|
83b4ab2374 | ||
|
573c50774b | ||
|
4b93623492 | ||
|
d496898c80 | ||
|
544e69c71b | ||
|
240334784d | ||
|
516b225275 | ||
|
e46e6b6e5b | ||
|
4925979519 | ||
|
298d1f9284 | ||
|
fcf2f5f7f0 | ||
|
491c3b4ea8 | ||
|
94cb50f725 | ||
|
1d8275c061 | ||
|
3c605d608b | ||
|
9ba48c7e1a | ||
|
a6ebc5267b | ||
|
e9554ccffe | ||
|
0d179f3728 | ||
|
a94e462f34 | ||
|
7ce991e625 | ||
|
3e15be852f | ||
|
7c1c8e92f2 | ||
|
54c3b4f600 | ||
|
d80fc5709e | ||
|
30236046a8 | ||
|
93aeb4cf2c | ||
|
f62ca35c86 | ||
|
2320cbdbb8 | ||
|
769cb44207 | ||
|
f327df95a3 | ||
|
09956b6219 | ||
|
f8c9adca5a | ||
|
b83e56713f | ||
|
4c12d5fca4 | ||
|
da4f9fbdc3 | ||
|
614e5f3a72 | ||
|
a7eae4f549 | ||
|
3cd5769708 | ||
|
7b770abe12 | ||
|
31ab8562a7 | ||
|
db703379a3 | ||
|
cd925bc049 | ||
|
4a2951e22f | ||
|
a93a8f99fb | ||
|
73c436ee15 | ||
|
c69100bd71 | ||
|
e0b89359aa | ||
|
041d720c39 | ||
|
03a0c2fe98 |
1821
CHANGELOG.md
Normal file
@@ -1,7 +1,7 @@
|
||||
# NopSCADlib usage
|
||||
|
||||
## Requirements
|
||||
1. OpenSCAD 2019.05 or later, download it from here: https://www.openscad.org/downloads.html
|
||||
1. OpenSCAD 2021.01 or later, download it from here: https://www.openscad.org/downloads.html
|
||||
1. Python 2.7+ or 3.6+ from https://www.python.org/downloads/
|
||||
1. ImageMagick 7 www.imagemagick.org
|
||||
|
||||
|
@@ -3,6 +3,7 @@
|
||||
"name": "base_assembly",
|
||||
"big": null,
|
||||
"ngb": false,
|
||||
"zoomed": 0,
|
||||
"count": 1,
|
||||
"assemblies": {},
|
||||
"vitamins": {
|
||||
@@ -22,6 +23,7 @@
|
||||
"name": "feet_assembly",
|
||||
"big": null,
|
||||
"ngb": false,
|
||||
"zoomed": 0,
|
||||
"count": 1,
|
||||
"assemblies": {
|
||||
"base_assembly": 1
|
||||
@@ -49,6 +51,7 @@
|
||||
"name": "mains_in_assembly",
|
||||
"big": null,
|
||||
"ngb": false,
|
||||
"zoomed": 0,
|
||||
"count": 1,
|
||||
"assemblies": {
|
||||
"feet_assembly": 1
|
||||
@@ -86,6 +89,7 @@
|
||||
"name": "main_assembly",
|
||||
"big": null,
|
||||
"ngb": false,
|
||||
"zoomed": 0,
|
||||
"count": 1,
|
||||
"assemblies": {
|
||||
"mains_in_assembly": 1
|
||||
|
7
lib.scad
@@ -26,7 +26,9 @@ include <vitamins/psus.scad>
|
||||
include <vitamins/pcbs.scad>
|
||||
|
||||
include <vitamins/batteries.scad>
|
||||
include <vitamins/bearing_blocks.scad>
|
||||
include <vitamins/blowers.scad>
|
||||
include <vitamins/box_sections.scad>
|
||||
include <vitamins/bulldogs.scad>
|
||||
include <vitamins/buttons.scad>
|
||||
include <vitamins/cameras.scad>
|
||||
@@ -37,7 +39,6 @@ include <vitamins/extrusion_brackets.scad>
|
||||
include <vitamins/geared_steppers.scad>
|
||||
include <vitamins/hot_ends.scad>
|
||||
include <vitamins/inserts.scad>
|
||||
include <vitamins/kp_pillow_blocks.scad>
|
||||
include <vitamins/ldrs.scad>
|
||||
include <vitamins/leadnuts.scad>
|
||||
include <vitamins/led_meter.scad>
|
||||
@@ -47,12 +48,12 @@ include <vitamins/mains_sockets.scad>
|
||||
include <vitamins/modules.scad>
|
||||
include <vitamins/panel_meters.scad>
|
||||
include <vitamins/pillars.scad>
|
||||
include <vitamins/pillow_blocks.scad>
|
||||
include <vitamins/pin_headers.scad>
|
||||
include <vitamins/pulleys.scad>
|
||||
include <vitamins/ring_terminals.scad>
|
||||
include <vitamins/rails.scad>
|
||||
include <vitamins/rod.scad>
|
||||
include <vitamins/scs_bearing_blocks.scad>
|
||||
include <vitamins/shaft_couplings.scad>
|
||||
include <vitamins/sheets.scad>
|
||||
include <vitamins/sk_brackets.scad>
|
||||
@@ -89,7 +90,7 @@ use <utils/gears.scad>
|
||||
use <utils/hanging_hole.scad>
|
||||
use <utils/fillet.scad>
|
||||
use <utils/rounded_polygon.scad>
|
||||
use <utils/rounded_right_triangle.scad>
|
||||
use <utils/rounded_triangle.scad>
|
||||
use <utils/layout.scad>
|
||||
use <utils/round.scad>
|
||||
use <utils/offset.scad>
|
||||
|
BIN
libtest.png
Before Width: | Height: | Size: 886 KiB After Width: | Height: | Size: 892 KiB |
14
libtest.scad
@@ -33,6 +33,8 @@
|
||||
//!
|
||||
//! See [usage](docs/usage.md) for requirements, installation instructions and a usage guide.
|
||||
//!
|
||||
//! A list of changes classified as breaking, additions or fixes is maintained in [CHANGELOG.md](CHANGELOG.md).
|
||||
//!
|
||||
//! <img src="libtest.png" width="100%"/>
|
||||
//
|
||||
// This file shows all the parts in the library.
|
||||
@@ -41,8 +43,10 @@ include <lib.scad>
|
||||
|
||||
use <tests/ball_bearings.scad>
|
||||
use <tests/batteries.scad>
|
||||
use <tests/bearing_blocks.scad>
|
||||
use <tests/belts.scad>
|
||||
use <tests/blowers.scad>
|
||||
use <tests/box_sections.scad>
|
||||
use <tests/bulldogs.scad>
|
||||
use <tests/buttons.scad>
|
||||
use <tests/cable_strips.scad>
|
||||
@@ -62,7 +66,6 @@ use <tests/hot_ends.scad>
|
||||
use <tests/IECs.scad>
|
||||
use <tests/inserts.scad>
|
||||
use <tests/jack.scad>
|
||||
use <tests/KP_pillow_blocks.scad>
|
||||
use <tests/leadnuts.scad>
|
||||
use <tests/LDRs.scad>
|
||||
use <tests/LEDs.scad>
|
||||
@@ -78,6 +81,7 @@ use <tests/opengrab.scad>
|
||||
use <tests/panel_meters.scad>
|
||||
use <tests/PCBs.scad>
|
||||
use <tests/pillars.scad>
|
||||
use <tests/pillow_blocks.scad>
|
||||
use <tests/press_fit.scad>
|
||||
use <tests/PSUs.scad>
|
||||
use <tests/pulleys.scad>
|
||||
@@ -86,7 +90,6 @@ use <tests/ring_terminals.scad>
|
||||
use <tests/rockers.scad>
|
||||
use <tests/rod.scad>
|
||||
use <tests/screws.scad>
|
||||
use <tests/SCS_bearing_blocks.scad>
|
||||
use <tests/sealing_strip.scad>
|
||||
use <tests/shaft_couplings.scad>
|
||||
use <tests/sheets.scad>
|
||||
@@ -205,8 +208,8 @@ ball_bearings_y = pillars_y + 40;
|
||||
pulleys_y = ball_bearings_y +40;
|
||||
hot_ends_y = pulleys_y + 60;
|
||||
linear_bearings_y = hot_ends_y + 50;
|
||||
sheets_y = linear_bearings_y + 100;
|
||||
pcbs_y = sheets_y + 40;
|
||||
sheets_y = linear_bearings_y + 90;
|
||||
pcbs_y = sheets_y + 60;
|
||||
displays_y = pcbs_y + 170;
|
||||
fans_y = displays_y + 80;
|
||||
transformers_y = fans_y + 120;
|
||||
@@ -424,6 +427,7 @@ extrusion_brackets_y = rails_y + 250;
|
||||
sk_brackets_y = extrusion_brackets_y + 80;
|
||||
kp_pillow_blocks_y = sk_brackets_y + 50;
|
||||
scs_bearing_blocks_y = kp_pillow_blocks_y + 60;
|
||||
box_sections_y = sheets_y;
|
||||
|
||||
translate([x4 + 200, belts_y + 58]) {
|
||||
belt_test();
|
||||
@@ -457,6 +461,8 @@ translate([x4 + 120, extrusion_brackets_y])
|
||||
translate([x4, scs_bearing_blocks_y])
|
||||
scs_bearing_blocks();
|
||||
|
||||
translate([x4, box_sections_y])
|
||||
box_sections();
|
||||
|
||||
translate([x6, 125])
|
||||
light_strips();
|
||||
|
474
readme.md
@@ -14,36 +14,38 @@ The license is GNU General Public License v3.0, see [COPYING](COPYING).
|
||||
|
||||
See [usage](docs/usage.md) for requirements, installation instructions and a usage guide.
|
||||
|
||||
A list of changes classified as breaking, additions or fixes is maintained in [CHANGELOG.md](CHANGELOG.md).
|
||||
|
||||
<img src="libtest.png" width="100%"/>
|
||||
|
||||
## Table of Contents<a name="top"/>
|
||||
<table><tr>
|
||||
<th align="left"> Vitamins A-I </th><th align="left"> Vitamins J-Q </th><th align="left"> Vitamins R-Z </th><th align="left"> Printed </th><th align="left"> Utilities </th><th align="left"> Core Utilities </th></tr>
|
||||
<tr><td> <a href = "#Axials">Axials</a> </td><td> <a href = "#Jack">Jack</a> </td><td> <a href = "#Rails">Rails</a> </td><td> <a href = "#Box">Box</a> </td><td> <a href = "#Annotation">Annotation</a> </td><td> <a href = "#BOM">BOM</a> </td></tr>
|
||||
<tr><td> <a href = "#Ball_bearings">Ball_bearings</a> </td><td> <a href = "#KP_pillow_blocks">KP_pillow_blocks</a> </td><td> <a href = "#Ring_terminals">Ring_terminals</a> </td><td> <a href = "#Butt_box">Butt_box</a> </td><td> <a href = "#Bezier">Bezier</a> </td><td> <a href = "#Clip">Clip</a> </td></tr>
|
||||
<tr><td> <a href = "#Batteries">Batteries</a> </td><td> <a href = "#LDRs">LDRs</a> </td><td> <a href = "#Rockers">Rockers</a> </td><td> <a href = "#Cable_grommets">Cable_grommets</a> </td><td> <a href = "#Catenary">Catenary</a> </td><td> <a href = "#Global">Global</a> </td></tr>
|
||||
<tr><td> <a href = "#Belts">Belts</a> </td><td> <a href = "#LED_meters">LED_meters</a> </td><td> <a href = "#Rod">Rod</a> </td><td> <a href = "#Camera_housing">Camera_housing</a> </td><td> <a href = "#Dogbones">Dogbones</a> </td><td> <a href = "#Polyholes">Polyholes</a> </td></tr>
|
||||
<tr><td> <a href = "#Blowers">Blowers</a> </td><td> <a href = "#LEDs">LEDs</a> </td><td> <a href = "#SCS_bearing_blocks">SCS_bearing_blocks</a> </td><td> <a href = "#Carriers">Carriers</a> </td><td> <a href = "#Fillet">Fillet</a> </td><td> <a href = "#Rounded_rectangle">Rounded_rectangle</a> </td></tr>
|
||||
<tr><td> <a href = "#Bulldogs">Bulldogs</a> </td><td> <a href = "#Leadnuts">Leadnuts</a> </td><td> <a href = "#SK_brackets">SK_brackets</a> </td><td> <a href = "#Corner_block">Corner_block</a> </td><td> <a href = "#Gears">Gears</a> </td><td> <a href = "#Sphere">Sphere</a> </td></tr>
|
||||
<tr><td> <a href = "#Buttons">Buttons</a> </td><td> <a href = "#Light_strips">Light_strips</a> </td><td> <a href = "#SMDs">SMDs</a> </td><td> <a href = "#Door_hinge">Door_hinge</a> </td><td> <a href = "#Hanging_hole">Hanging_hole</a> </td><td> <a href = "#Teardrops">Teardrops</a> </td></tr>
|
||||
<tr><td> <a href = "#Cable_strips">Cable_strips</a> </td><td> <a href = "#Linear_bearings">Linear_bearings</a> </td><td> <a href = "#SSRs">SSRs</a> </td><td> <a href = "#Door_latch">Door_latch</a> </td><td> <a href = "#Horiholes">Horiholes</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Cameras">Cameras</a> </td><td> <a href = "#Magnets">Magnets</a> </td><td> <a href = "#Screws">Screws</a> </td><td> <a href = "#Drag_chain">Drag_chain</a> </td><td> <a href = "#Layout">Layout</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Circlips">Circlips</a> </td><td> <a href = "#Mains_sockets">Mains_sockets</a> </td><td> <a href = "#Sealing_strip">Sealing_strip</a> </td><td> <a href = "#Fan_guard">Fan_guard</a> </td><td> <a href = "#Maths">Maths</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Components">Components</a> </td><td> <a href = "#Microswitches">Microswitches</a> </td><td> <a href = "#Shaft_couplings">Shaft_couplings</a> </td><td> <a href = "#Fixing_block">Fixing_block</a> </td><td> <a href = "#Offset">Offset</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#DIP">DIP</a> </td><td> <a href = "#Microview">Microview</a> </td><td> <a href = "#Sheets">Sheets</a> </td><td> <a href = "#Flat_hinge">Flat_hinge</a> </td><td> <a href = "#Quadrant">Quadrant</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#D_connectors">D_connectors</a> </td><td> <a href = "#Modules">Modules</a> </td><td> <a href = "#Spades">Spades</a> </td><td> <a href = "#Foot">Foot</a> </td><td> <a href = "#Round">Round</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Displays">Displays</a> </td><td> <a href = "#Nuts">Nuts</a> </td><td> <a href = "#Spools">Spools</a> </td><td> <a href = "#Handle">Handle</a> </td><td> <a href = "#Rounded_cylinder">Rounded_cylinder</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Extrusion_brackets">Extrusion_brackets</a> </td><td> <a href = "#O_ring">O_ring</a> </td><td> <a href = "#Springs">Springs</a> </td><td> <a href = "#PCB_mount">PCB_mount</a> </td><td> <a href = "#Rounded_polygon">Rounded_polygon</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Extrusions">Extrusions</a> </td><td> <a href = "#Opengrab">Opengrab</a> </td><td> <a href = "#Stepper_motors">Stepper_motors</a> </td><td> <a href = "#PSU_shroud">PSU_shroud</a> </td><td> <a href = "#Rounded_right_triangle">Rounded_right_triangle</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Fans">Fans</a> </td><td> <a href = "#PCB">PCB</a> </td><td> <a href = "#Swiss_clips">Swiss_clips</a> </td><td> <a href = "#Pocket_handle">Pocket_handle</a> </td><td> <a href = "#Sector">Sector</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Fuseholder">Fuseholder</a> </td><td> <a href = "#PCBs">PCBs</a> </td><td> <a href = "#Toggles">Toggles</a> </td><td> <a href = "#Press_fit">Press_fit</a> </td><td> <a href = "#Sweep">Sweep</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Geared_steppers">Geared_steppers</a> </td><td> <a href = "#PSUs">PSUs</a> </td><td> <a href = "#Transformers">Transformers</a> </td><td> <a href = "#Printed_box">Printed_box</a> </td><td> <a href = "#Thread">Thread</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Green_terminals">Green_terminals</a> </td><td> <a href = "#Panel_meters">Panel_meters</a> </td><td> <a href = "#Tubings">Tubings</a> </td><td> <a href = "#Printed_pulleys">Printed_pulleys</a> </td><td> <a href = "#Tube">Tube</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Hot_ends">Hot_ends</a> </td><td> <a href = "#Pillars">Pillars</a> </td><td> <a href = "#Variacs">Variacs</a> </td><td> <a href = "#Ribbon_clamp">Ribbon_clamp</a> </td><td></td><td></td></tr>
|
||||
<tr><td> <a href = "#Hygrometer">Hygrometer</a> </td><td> <a href = "#Pin_headers">Pin_headers</a> </td><td> <a href = "#Veroboard">Veroboard</a> </td><td> <a href = "#SSR_shroud">SSR_shroud</a> </td><td></td><td></td></tr>
|
||||
<tr><td> <a href = "#IECs">IECs</a> </td><td> <a href = "#Pulleys">Pulleys</a> </td><td> <a href = "#Washers">Washers</a> </td><td> <a href = "#Screw_knob">Screw_knob</a> </td><td></td><td></td></tr>
|
||||
<tr><td> <a href = "#Inserts">Inserts</a> </td><td></td><td> <a href = "#Wire">Wire</a> </td><td> <a href = "#Socket_box">Socket_box</a> </td><td></td><td></td></tr>
|
||||
<tr><td></td><td></td><td> <a href = "#Zipties">Zipties</a> </td><td> <a href = "#Strap_handle">Strap_handle</a> </td><td></td><td></td></tr>
|
||||
<th align="left"> Vitamins A-H </th><th align="left"> Vitamins I-Q </th><th align="left"> Vitamins R-Z </th><th align="left"> Printed </th><th align="left"> Utilities </th><th align="left"> Core Utilities </th></tr>
|
||||
<tr><td> <a href = "#Axials">Axials</a> </td><td> <a href = "#IECs">IECs</a> </td><td> <a href = "#Rails">Rails</a> </td><td> <a href = "#Box">Box</a> </td><td> <a href = "#Annotation">Annotation</a> </td><td> <a href = "#BOM">BOM</a> </td></tr>
|
||||
<tr><td> <a href = "#Ball_bearings">Ball_bearings</a> </td><td> <a href = "#Inserts">Inserts</a> </td><td> <a href = "#Ring_terminals">Ring_terminals</a> </td><td> <a href = "#Butt_box">Butt_box</a> </td><td> <a href = "#Bezier">Bezier</a> </td><td> <a href = "#Clip">Clip</a> </td></tr>
|
||||
<tr><td> <a href = "#Batteries">Batteries</a> </td><td> <a href = "#Jack">Jack</a> </td><td> <a href = "#Rockers">Rockers</a> </td><td> <a href = "#Cable_grommets">Cable_grommets</a> </td><td> <a href = "#Catenary">Catenary</a> </td><td> <a href = "#Global">Global</a> </td></tr>
|
||||
<tr><td> <a href = "#Bearing_blocks">Bearing_blocks</a> </td><td> <a href = "#LDRs">LDRs</a> </td><td> <a href = "#Rod">Rod</a> </td><td> <a href = "#Camera_housing">Camera_housing</a> </td><td> <a href = "#Core_xy">Core_xy</a> </td><td> <a href = "#Polyholes">Polyholes</a> </td></tr>
|
||||
<tr><td> <a href = "#Belts">Belts</a> </td><td> <a href = "#LED_meters">LED_meters</a> </td><td> <a href = "#SK_brackets">SK_brackets</a> </td><td> <a href = "#Carriers">Carriers</a> </td><td> <a href = "#Dogbones">Dogbones</a> </td><td> <a href = "#Rounded_rectangle">Rounded_rectangle</a> </td></tr>
|
||||
<tr><td> <a href = "#Blowers">Blowers</a> </td><td> <a href = "#LEDs">LEDs</a> </td><td> <a href = "#SMDs">SMDs</a> </td><td> <a href = "#Corner_block">Corner_block</a> </td><td> <a href = "#Fillet">Fillet</a> </td><td> <a href = "#Sphere">Sphere</a> </td></tr>
|
||||
<tr><td> <a href = "#Box_sections">Box_sections</a> </td><td> <a href = "#Leadnuts">Leadnuts</a> </td><td> <a href = "#SSRs">SSRs</a> </td><td> <a href = "#Door_hinge">Door_hinge</a> </td><td> <a href = "#Gears">Gears</a> </td><td> <a href = "#Teardrops">Teardrops</a> </td></tr>
|
||||
<tr><td> <a href = "#Bulldogs">Bulldogs</a> </td><td> <a href = "#Light_strips">Light_strips</a> </td><td> <a href = "#Screws">Screws</a> </td><td> <a href = "#Door_latch">Door_latch</a> </td><td> <a href = "#Hanging_hole">Hanging_hole</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Buttons">Buttons</a> </td><td> <a href = "#Linear_bearings">Linear_bearings</a> </td><td> <a href = "#Sealing_strip">Sealing_strip</a> </td><td> <a href = "#Drag_chain">Drag_chain</a> </td><td> <a href = "#Horiholes">Horiholes</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Cable_strips">Cable_strips</a> </td><td> <a href = "#Magnets">Magnets</a> </td><td> <a href = "#Shaft_couplings">Shaft_couplings</a> </td><td> <a href = "#Fan_guard">Fan_guard</a> </td><td> <a href = "#Layout">Layout</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Cameras">Cameras</a> </td><td> <a href = "#Mains_sockets">Mains_sockets</a> </td><td> <a href = "#Sheets">Sheets</a> </td><td> <a href = "#Fixing_block">Fixing_block</a> </td><td> <a href = "#Maths">Maths</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Circlips">Circlips</a> </td><td> <a href = "#Microswitches">Microswitches</a> </td><td> <a href = "#Spades">Spades</a> </td><td> <a href = "#Flat_hinge">Flat_hinge</a> </td><td> <a href = "#Offset">Offset</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Components">Components</a> </td><td> <a href = "#Microview">Microview</a> </td><td> <a href = "#Spools">Spools</a> </td><td> <a href = "#Foot">Foot</a> </td><td> <a href = "#Quadrant">Quadrant</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#DIP">DIP</a> </td><td> <a href = "#Modules">Modules</a> </td><td> <a href = "#Springs">Springs</a> </td><td> <a href = "#Handle">Handle</a> </td><td> <a href = "#Round">Round</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#D_connectors">D_connectors</a> </td><td> <a href = "#Nuts">Nuts</a> </td><td> <a href = "#Stepper_motors">Stepper_motors</a> </td><td> <a href = "#PCB_mount">PCB_mount</a> </td><td> <a href = "#Rounded_cylinder">Rounded_cylinder</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Displays">Displays</a> </td><td> <a href = "#O_ring">O_ring</a> </td><td> <a href = "#Swiss_clips">Swiss_clips</a> </td><td> <a href = "#PSU_shroud">PSU_shroud</a> </td><td> <a href = "#Rounded_polygon">Rounded_polygon</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Extrusion_brackets">Extrusion_brackets</a> </td><td> <a href = "#Opengrab">Opengrab</a> </td><td> <a href = "#Toggles">Toggles</a> </td><td> <a href = "#Pocket_handle">Pocket_handle</a> </td><td> <a href = "#Rounded_triangle">Rounded_triangle</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Extrusions">Extrusions</a> </td><td> <a href = "#PCB">PCB</a> </td><td> <a href = "#Transformers">Transformers</a> </td><td> <a href = "#Press_fit">Press_fit</a> </td><td> <a href = "#Sector">Sector</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Fans">Fans</a> </td><td> <a href = "#PCBs">PCBs</a> </td><td> <a href = "#Tubings">Tubings</a> </td><td> <a href = "#Printed_box">Printed_box</a> </td><td> <a href = "#Sweep">Sweep</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Fuseholder">Fuseholder</a> </td><td> <a href = "#PSUs">PSUs</a> </td><td> <a href = "#Variacs">Variacs</a> </td><td> <a href = "#Printed_pulleys">Printed_pulleys</a> </td><td> <a href = "#Thread">Thread</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Geared_steppers">Geared_steppers</a> </td><td> <a href = "#Panel_meters">Panel_meters</a> </td><td> <a href = "#Veroboard">Veroboard</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 = "#Green_terminals">Green_terminals</a> </td><td> <a href = "#Pillars">Pillars</a> </td><td> <a href = "#Washers">Washers</a> </td><td> <a href = "#SSR_shroud">SSR_shroud</a> </td><td></td><td></td></tr>
|
||||
<tr><td> <a href = "#Hot_ends">Hot_ends</a> </td><td> <a href = "#Pillow_blocks">Pillow_blocks</a> </td><td> <a href = "#Wire">Wire</a> </td><td> <a href = "#Screw_knob">Screw_knob</a> </td><td></td><td></td></tr>
|
||||
<tr><td> <a href = "#Hygrometer">Hygrometer</a> </td><td> <a href = "#Pin_headers">Pin_headers</a> </td><td> <a href = "#Zipties">Zipties</a> </td><td> <a href = "#Socket_box">Socket_box</a> </td><td></td><td></td></tr>
|
||||
<tr><td></td><td> <a href = "#Pulleys">Pulleys</a> </td><td></td><td> <a href = "#Strap_handle">Strap_handle</a> </td><td></td><td></td></tr>
|
||||
</table>
|
||||
|
||||
---
|
||||
@@ -198,18 +200,89 @@ exposing enough information to make a battery box.
|
||||
| 1 | `battery(S25R18650)` | Cell Samsung 25R 18650 LION |
|
||||
|
||||
|
||||
<a href="#top">Top</a>
|
||||
|
||||
---
|
||||
<a name="Bearing_blocks"></a>
|
||||
## Bearing_blocks
|
||||
SCSnUU and SCSnLUU bearing blocks
|
||||
|
||||
[vitamins/bearing_blocks.scad](vitamins/bearing_blocks.scad) Object definitions.
|
||||
|
||||
[vitamins/bearing_block.scad](vitamins/bearing_block.scad) Implementation.
|
||||
|
||||
[tests/bearing_blocks.scad](tests/bearing_blocks.scad) Code for this example.
|
||||
|
||||
### Properties
|
||||
| Function | Description |
|
||||
|:--- |:--- |
|
||||
| `scs_bearing(type)` | Linear bearing used |
|
||||
| `scs_block_center_height(type)` | Height of the center of the block |
|
||||
| `scs_block_side_height(type)` | Height of the side of the block, this determines the minimum screw length |
|
||||
| `scs_circlip(type)` | Circlip used |
|
||||
| `scs_hole_offset(type)` | Offset of bearing hole from base of block |
|
||||
| `scs_screw(type)` | Screw type |
|
||||
| `scs_screw_separation_x(type)` | Screw separation in X direction |
|
||||
| `scs_screw_separation_z(type)` | Screw separation in Z direction |
|
||||
| `scs_spacer(type)` | Spacer used in long bearings |
|
||||
|
||||
### Functions
|
||||
| Function | Description |
|
||||
|:--- |:--- |
|
||||
| `scs_size(type)` | Size of scs bracket bounding block |
|
||||
|
||||
### Modules
|
||||
| Module | Description |
|
||||
|:--- |:--- |
|
||||
| `scs_bearing_block(type)` | Draw the specified SCS bearing block |
|
||||
| `scs_bearing_block_assembly(type, part_thickness, screw_type, nut_type)` | Assembly with screws and nuts in place |
|
||||
| `scs_bearing_block_hole_positions(type)` | Place children at hole positions |
|
||||
|
||||

|
||||
|
||||
### Vitamins
|
||||
| Qty | Module call | BOM entry |
|
||||
| ---:|:--- |:---|
|
||||
| 12 | `nut(M4_nut)` | Nut M4 x 3.2mm |
|
||||
| 24 | `nut(M5_nut)` | Nut M5 x 4mm |
|
||||
| 1 | `scs_bearing_block(SCS10LUU)` | SCS10LUU bearing block |
|
||||
| 1 | `scs_bearing_block(SCS10UU)` | SCS10UU bearing block |
|
||||
| 1 | `scs_bearing_block(SCS12LUU)` | SCS12LUU bearing block |
|
||||
| 1 | `scs_bearing_block(SCS12UU)` | SCS12UU bearing block |
|
||||
| 1 | `scs_bearing_block(SCS16LUU)` | SCS16LUU bearing block |
|
||||
| 1 | `scs_bearing_block(SCS16UU)` | SCS16UU bearing block |
|
||||
| 1 | `scs_bearing_block(SCS6UU)` | SCS6UU bearing block |
|
||||
| 1 | `scs_bearing_block(SCS8LUU)` | SCS8LUU bearing block |
|
||||
| 1 | `scs_bearing_block(SCS8UU)` | SCS8UU bearing block |
|
||||
| 4 | `screw(M4_cap_screw, 25)` | Screw M4 cap x 25mm |
|
||||
| 8 | `screw(M4_cap_screw, 30)` | Screw M4 cap x 30mm |
|
||||
| 16 | `screw(M5_cap_screw, 35)` | Screw M5 cap x 35mm |
|
||||
| 8 | `screw(M5_cap_screw, 45)` | Screw M5 cap x 45mm |
|
||||
| 12 | `washer(M4_washer)` | Washer M4 x 9mm x 0.8mm |
|
||||
| 24 | `washer(M5_washer)` | Washer M5 x 10mm x 1mm |
|
||||
|
||||
|
||||
<a href="#top">Top</a>
|
||||
|
||||
---
|
||||
<a name="Belts"></a>
|
||||
## Belts
|
||||
Models timing belt running over toothed or smooth pulleys and calculates an accurate length.
|
||||
Only models 2D paths, so not crossed belt core XY!
|
||||
Models timing belt running in a path over toothed or smooth pulleys and calculates an accurate length.
|
||||
Only models 2D paths, belt may twist to support crossed belt core XY and other designes where the belt twists!
|
||||
|
||||
By default the path is a closed loop. An open loop can be specified by specifying `open=true`, and in that case the start and end points are not connected, leaving the loop open.
|
||||
|
||||
To get a 180 degree twist of the loop, you can use the `twist` argument. `Twist` can be a single number, and in that case the belt will twist after
|
||||
the position with that number. Alternatively `twist` can be a list of boolean values with a boolean for each position; the belt will then twist after
|
||||
the position that have a `true` value in the `twist` list. If the path is specified with pulley/idler types, then you can use `auto_twist=true`; in
|
||||
that case the belt will automatically twist so the back of the belt always runs against idlers and the tooth side runs against pullies. If you use
|
||||
`open=true` then you might also use `start_twist=true` to let the belt start the part with the back side out.
|
||||
|
||||
The path must be specified as a list of positions. Each position should be either a vector with `[x, y, pulley]` or `[x, y, r]`. A pully is a type from
|
||||
`pulleys.scad`, and correct radius and angle will automatically be calculated. Alternatively a radius can be specified directly.
|
||||
|
||||
To make the back of the belt run against a smooth pulley on the outside of the loop specify a negative pitch radius.
|
||||
|
||||
By default the path is a closed loop but a gap length and position can be specified to make open loops.
|
||||
To draw the gap its XY position is specified by `gap_pos`. `gap_pos.z` can be used to specify a rotation if the gap is not at the bottom of the loop.
|
||||
Alternativley you can just specify smooth pulleys in the path, and it will then happen automatically.
|
||||
|
||||
Individual teeth are not drawn, instead they are represented by a lighter colour.
|
||||
|
||||
@@ -231,13 +304,15 @@ Individual teeth are not drawn, instead they are represented by a lighter colour
|
||||
### Functions
|
||||
| Function | Description |
|
||||
|:--- |:--- |
|
||||
| `belt_length(points, gap = 0)` | Compute belt length given path and optional gap |
|
||||
| `_belt_points_info(type, points, open, twist, auto_twist, start_twist)` | Helper function that calculates [twist, istwisted, points, tangents, arcs] |
|
||||
| `belt_length(type, points, open = false)` | Compute belt length given path |
|
||||
| `belt_pitch_to_back(type)` | Offset of the back from the pitch radius |
|
||||
| `belt_pulley_pr(type, pulley, twisted=false)` | Pitch radius. Default it expects the belt tooth to be against a toothed pulley an the backside to be against a smooth pulley (an idler). If `twisted` is true, the the belt is the other way around. |
|
||||
|
||||
### Modules
|
||||
| Module | Description |
|
||||
|:--- |:--- |
|
||||
| `belt(type, points, gap = 0, gap_pos = undef, belt_colour = grey(20)` | 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, belt_colour = grey(20)` | Draw a belt path given a set of points and pitch radii where the pulleys are. Closed loop unless open is specified |
|
||||
|
||||

|
||||
|
||||
@@ -245,17 +320,18 @@ Individual teeth are not drawn, instead they are represented by a lighter colour
|
||||
| Qty | Module call | BOM entry |
|
||||
| ---:|:--- |:---|
|
||||
| 1 | `belt(GT2x6, [ ... ])` | Belt GT2 x 6mm x 128mm |
|
||||
| 2 | `belt(GT2x6, [ ... ], 80, [0, 0])` | Belt GT2 x 6mm x 572mm |
|
||||
| 1 | `belt(GT2x6, [ ... ])` | Belt GT2 x 6mm x 552mm |
|
||||
| 2 | `belt(GT2x6, [ ... ])` | Belt GT2 x 6mm x 556mm |
|
||||
| 1 | `belt(T2p5x6, [ ... ])` | Belt T2.5 x 6mm x 130mm |
|
||||
| 1 | `belt(T5x10, [ ... ])` | Belt T5 x 10mm x 130mm |
|
||||
| 1 | `belt(T5x6, [ ... ])` | Belt T5 x 6mm x 130mm |
|
||||
| 2 | `insert(F1BM3)` | Heatfit insert M3 |
|
||||
| 2 | `pulley(GT2x16_toothed_idler)` | Pulley GT2 idler 16 teeth |
|
||||
| 4 | `pulley(GT2x20_toothed_idler)` | Pulley GT2 idler 20 teeth |
|
||||
| 2 | `pulley(GT2x16_plain_idler)` | Pulley GT2 idler smooth 9.63mm |
|
||||
| 2 | `pulley(GT2x20ob_pulley)` | Pulley GT2OB 20 teeth |
|
||||
| 6 | `pulley(GT2x16_plain_idler)` | Pulley GT2 idler smooth 9.63mm |
|
||||
| 3 | `pulley(GT2x20ob_pulley)` | Pulley GT2OB 20 teeth |
|
||||
| 2 | `screw(M3_cs_cap_screw, 20)` | Screw M3 cs cap x 20mm |
|
||||
| 4 | `screw(M3_grub_screw, 6)` | Screw M3 grub x 6mm |
|
||||
| 6 | `screw(M3_grub_screw, 6)` | Screw M3 grub x 6mm |
|
||||
|
||||
|
||||
<a href="#top">Top</a>
|
||||
@@ -323,6 +399,44 @@ Models of radial blowers.
|
||||
| 2 | `washer(M4_washer)` | Washer M4 x 9mm x 0.8mm |
|
||||
|
||||
|
||||
<a href="#top">Top</a>
|
||||
|
||||
---
|
||||
<a name="Box_sections"></a>
|
||||
## Box_sections
|
||||
Box sections.
|
||||
|
||||
[vitamins/box_sections.scad](vitamins/box_sections.scad) Object definitions.
|
||||
|
||||
[vitamins/box_section.scad](vitamins/box_section.scad) Implementation.
|
||||
|
||||
[tests/box_sections.scad](tests/box_sections.scad) Code for this example.
|
||||
|
||||
### Properties
|
||||
| Function | Description |
|
||||
|:--- |:--- |
|
||||
| `box_section_colour(type)` | Colour |
|
||||
| `box_section_colour2(type)` | Colour2, for woven box section |
|
||||
| `box_section_fillet(type)` | Fillet |
|
||||
| `box_section_material(type)` | Material description |
|
||||
| `box_section_size(type)` | Size |
|
||||
| `box_section_thickness(type)` | Wall thickness |
|
||||
|
||||
### Functions
|
||||
| Function | Description |
|
||||
|:--- |:--- |
|
||||
| `box_section_is_woven(type)` | Box section is woven, eg carbon fiber |
|
||||
|
||||

|
||||
|
||||
### Vitamins
|
||||
| Qty | Module call | BOM entry |
|
||||
| ---:|:--- |:---|
|
||||
| 1 | `box_section(AL12x8x1, 100)` | Aluminium rectangular box section 12mm x 8mm x 1mm, length 100mm |
|
||||
| 1 | `box_section(AL20x20x2, 100)` | Aluminium rectangular box section 20mm x 20mm x 2mm, length 100mm |
|
||||
| 1 | `box_section(CF10x10x1, 100)` | Carbon fiber rectangular box section 10mm x 10mm x 1mm, length 100mm |
|
||||
|
||||
|
||||
<a href="#top">Top</a>
|
||||
|
||||
---
|
||||
@@ -1307,58 +1421,6 @@ E.g. a "brown" socket for mains live needs to be displayed as "sienna" to look r
|
||||
| 1 | `jack_4mm_shielded("brown", 3, "sienna")` | 4mm shielded jack socket brown |
|
||||
|
||||
|
||||
<a href="#top">Top</a>
|
||||
|
||||
---
|
||||
<a name="KP_pillow_blocks"></a>
|
||||
## KP_pillow_blocks
|
||||
KP pillow block bearings
|
||||
|
||||
[vitamins/kp_pillow_blocks.scad](vitamins/kp_pillow_blocks.scad) Object definitions.
|
||||
|
||||
[vitamins/kp_pillow_block.scad](vitamins/kp_pillow_block.scad) Implementation.
|
||||
|
||||
[tests/KP_pillow_blocks.scad](tests/KP_pillow_blocks.scad) Code for this example.
|
||||
|
||||
### Properties
|
||||
| Function | Description |
|
||||
|:--- |:--- |
|
||||
| `kp_base_height(type)` | Height of base containing the bolts |
|
||||
| `kp_diameter(type)` | Rod hole diameter |
|
||||
| `kp_hole_offset(type)` | Rod hole offset |
|
||||
| `kp_screw_separation(type)` | Separation of bolts in the base |
|
||||
|
||||
### Functions
|
||||
| Function | Description |
|
||||
|:--- |:--- |
|
||||
| `kp_size(type)` | Size of bracket |
|
||||
|
||||
### Modules
|
||||
| Module | Description |
|
||||
|:--- |:--- |
|
||||
| `kp_pillow_block(type)` | Draw the KP pillow block |
|
||||
| `kp_pillow_block_assembly(type, part_thickness = 2, screw_type = M5_cap_screw, nut_type = undef)` | Assembly with fasteners in place |
|
||||
| `kp_pillow_block_hole_positions(type)` | Place children at hole positions |
|
||||
|
||||

|
||||
|
||||
### Vitamins
|
||||
| Qty | Module call | BOM entry |
|
||||
| ---:|:--- |:---|
|
||||
| 1 | `kp_pillow_block(KP000)` | KP000 pillow block |
|
||||
| 1 | `kp_pillow_block(KP001)` | KP001 pillow block |
|
||||
| 1 | `kp_pillow_block(KP08_15)` | KP08_15 pillow block |
|
||||
| 1 | `kp_pillow_block(KP08_18)` | KP08_18 pillow block |
|
||||
| 2 | `sliding_t_nut(M4_hammer_nut)` | Nut M4 hammer |
|
||||
| 2 | `sliding_t_nut(M4_sliding_t_nut)` | Nut M4 sliding T |
|
||||
| 2 | `sliding_t_nut(M5_sliding_t_nut)` | Nut M5 sliding T |
|
||||
| 2 | `nut(M5_nut, nyloc = undef)` | Nut M5 x 4mm |
|
||||
| 4 | `screw(M4_cap_screw, 10)` | Screw M4 cap x 10mm |
|
||||
| 4 | `screw(M5_cap_screw, 12)` | Screw M5 cap x 12mm |
|
||||
| 4 | `washer(M4_washer)` | Washer M4 x 9mm x 0.8mm |
|
||||
| 6 | `washer(M5_washer)` | Washer M5 x 10mm x 1mm |
|
||||
|
||||
|
||||
<a href="#top">Top</a>
|
||||
|
||||
---
|
||||
@@ -2006,6 +2068,7 @@ A permanent magnet that can be magnatized and de-magnatized electronically.
|
||||
| `opengrab_depth()` | Module height |
|
||||
| `opengrab_pcb()` | The PCB |
|
||||
| `opengrab_pcb_z()` | PCB offset from the front |
|
||||
| `opengrab_screw_depth()` | Max screw depth in pillars |
|
||||
| `opengrab_target_thickness()` | Target sheet thickness |
|
||||
| `opengrab_width()` | Module width |
|
||||
|
||||
@@ -2132,6 +2195,7 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
|
||||
### Functions
|
||||
| Function | Description |
|
||||
|:--- |:--- |
|
||||
| `pcb_component(type, name, index = 0)` | Return the component specified by name and index |
|
||||
| `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 |
|
||||
@@ -2268,6 +2332,7 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
|
||||
### Functions
|
||||
| Function | Description |
|
||||
|:--- |:--- |
|
||||
| `pcb_component(type, name, index = 0)` | Return the component specified by name and index |
|
||||
| `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 |
|
||||
@@ -2442,6 +2507,58 @@ Threaded pillars. Each end can be male or female.
|
||||
| 1 | `pillar(M4x17_nylon_pillar)` | Pillar nylon M/F M4x20 |
|
||||
|
||||
|
||||
<a href="#top">Top</a>
|
||||
|
||||
---
|
||||
<a name="Pillow_blocks"></a>
|
||||
## Pillow_blocks
|
||||
KP pillow block bearings
|
||||
|
||||
[vitamins/pillow_blocks.scad](vitamins/pillow_blocks.scad) Object definitions.
|
||||
|
||||
[vitamins/pillow_block.scad](vitamins/pillow_block.scad) Implementation.
|
||||
|
||||
[tests/pillow_blocks.scad](tests/pillow_blocks.scad) Code for this example.
|
||||
|
||||
### Properties
|
||||
| Function | Description |
|
||||
|:--- |:--- |
|
||||
| `kp_base_height(type)` | Height of base containing the bolts |
|
||||
| `kp_diameter(type)` | Rod hole diameter |
|
||||
| `kp_hole_offset(type)` | Rod hole offset |
|
||||
| `kp_screw_separation(type)` | Separation of bolts in the base |
|
||||
|
||||
### Functions
|
||||
| Function | Description |
|
||||
|:--- |:--- |
|
||||
| `kp_size(type)` | Size of bracket |
|
||||
|
||||
### Modules
|
||||
| Module | Description |
|
||||
|:--- |:--- |
|
||||
| `kp_pillow_block(type)` | Draw the KP pillow block |
|
||||
| `kp_pillow_block_assembly(type, part_thickness = 2, screw_type = M5_cap_screw, nut_type = undef)` | Assembly with fasteners in place |
|
||||
| `kp_pillow_block_hole_positions(type)` | Place children at hole positions |
|
||||
|
||||

|
||||
|
||||
### Vitamins
|
||||
| Qty | Module call | BOM entry |
|
||||
| ---:|:--- |:---|
|
||||
| 1 | `kp_pillow_block(KP000)` | KP000 pillow block |
|
||||
| 1 | `kp_pillow_block(KP001)` | KP001 pillow block |
|
||||
| 1 | `kp_pillow_block(KP08_15)` | KP08_15 pillow block |
|
||||
| 1 | `kp_pillow_block(KP08_18)` | KP08_18 pillow block |
|
||||
| 2 | `sliding_t_nut(M4_hammer_nut)` | Nut M4 hammer |
|
||||
| 2 | `sliding_t_nut(M4_sliding_t_nut)` | Nut M4 sliding T |
|
||||
| 2 | `sliding_t_nut(M5_sliding_t_nut)` | Nut M5 sliding T |
|
||||
| 2 | `nut(M5_nut, nyloc = undef)` | Nut M5 x 4mm |
|
||||
| 4 | `screw(M4_cap_screw, 10)` | Screw M4 cap x 10mm |
|
||||
| 4 | `screw(M5_cap_screw, 12)` | Screw M5 cap x 12mm |
|
||||
| 4 | `washer(M4_washer)` | Washer M4 x 9mm x 0.8mm |
|
||||
| 6 | `washer(M5_washer)` | Washer M5 x 10mm x 1mm |
|
||||
|
||||
|
||||
<a href="#top">Top</a>
|
||||
|
||||
---
|
||||
@@ -2550,6 +2667,7 @@ Face order is bottom, top, left, right, front, back.
|
||||
| Function | Description |
|
||||
|:--- |:--- |
|
||||
| `psu_face_transform(type, face)` | Returns a transformation matrix to get to the specified face |
|
||||
| `psu_size(type)` | Size |
|
||||
| `terminal_block_length(type, ways)` | Total length of terminal block |
|
||||
|
||||
### Modules
|
||||
@@ -2617,12 +2735,12 @@ Timing belt pulleys, both toothed and plain with internal bearings for idlers.
|
||||
| `pulley_height(type)` | Total height of pulley |
|
||||
| `pulley_ir(type)` | Inside radius of the teeth |
|
||||
| `pulley_offset(type)` | Offset of the belt path centre |
|
||||
| `pulley_pr(type)` | Pitch radius |
|
||||
| `pulley_pr(type, belt = undef)` | Pitch radius, `belt` only needed for non-standard belt over smooth pulleys |
|
||||
|
||||
### Modules
|
||||
| Module | Description |
|
||||
|:--- |:--- |
|
||||
| `pulley(type, colour = silver)` | Draw a pulley |
|
||||
| `pulley(type, colour = silver)` | Draw a pulley, any children are placed above. |
|
||||
| `pulley_assembly(type, colour = silver)` | Draw a pulley with its grub screws in place |
|
||||
|
||||

|
||||
@@ -2709,26 +2827,35 @@ Linear rails with carriages.
|
||||
### Vitamins
|
||||
| Qty | Module call | BOM entry |
|
||||
| ---:|:--- |:---|
|
||||
| 2 | `rail(MGN12, 200)` | Linear rail MGN12 x 200mm |
|
||||
| 1 | `rail(MGN12, 200)` | Linear rail MGN12 x 200mm |
|
||||
| 1 | `rail(MGN15, 200)` | Linear rail MGN15 x 200mm |
|
||||
| 1 | `rail(MGN5, 200)` | Linear rail MGN5 x 200mm |
|
||||
| 1 | `rail(MGN7, 200)` | Linear rail MGN7 x 200mm |
|
||||
| 1 | `rail(MGN9, 200)` | Linear rail MGN9 x 200mm |
|
||||
| 1 | `rail(SSR15, 200)` | Linear rail SSR15 x 200mm |
|
||||
| 1 | `carriage(MGN12C_carriage)` | Linear rail carriage MGN12C |
|
||||
| 1 | `carriage(MGN12H_carriage)` | Linear rail carriage MGN12H |
|
||||
| 1 | `carriage(MGN15C_carriage)` | Linear rail carriage MGN15C |
|
||||
| 1 | `carriage(MGN5C_carriage)` | Linear rail carriage MGN5C |
|
||||
| 1 | `carriage(MGN7C_carriage)` | Linear rail carriage MGN7C |
|
||||
| 1 | `carriage(MGN7H_carriage)` | Linear rail carriage MGN7H |
|
||||
| 1 | `carriage(MGN9C_carriage)` | Linear rail carriage MGN9C |
|
||||
| 1 | `carriage(MGN9H_carriage)` | Linear rail carriage MGN9H |
|
||||
| 1 | `carriage(SSR15_carriage)` | Linear rail carriage SSR15 |
|
||||
| 26 | `nut(M2_nut, nyloc = true)` | Nut M2 x 1.6mm nyloc |
|
||||
| 31 | `nut(M3_nut, nyloc = true)` | Nut M3 x 2.4mm nyloc |
|
||||
| 23 | `nut(M3_nut, nyloc = true)` | Nut M3 x 2.4mm nyloc |
|
||||
| 4 | `nut(M4_nut, nyloc = true)` | Nut M4 x 3.2mm nyloc |
|
||||
| 11 | `screw(M2_cap_screw, 10)` | Screw M2 cap x 10mm |
|
||||
| 15 | `screw(M2_cs_cap_screw, 10)` | Screw M2 cs cap x 10mm |
|
||||
| 8 | `screw(M3_cap_screw, 10)` | Screw M3 cap x 10mm |
|
||||
| 12 | `screw(M3_cap_screw, 12)` | Screw M3 cap x 12mm |
|
||||
| 6 | `screw(M3_cap_screw, 12)` | Screw M3 cap x 12mm |
|
||||
| 3 | `screw(M3_cap_screw, 16)` | Screw M3 cap x 16mm |
|
||||
| 2 | `screw(M3_cs_cap_screw, 12)` | Screw M3 cs cap x 12mm |
|
||||
| 6 | `screw(M3_cs_cap_screw, 16)` | Screw M3 cs cap x 16mm |
|
||||
| 4 | `screw(M3_cs_cap_screw, 16)` | Screw M3 cs cap x 16mm |
|
||||
| 2 | `screw(M4_cap_screw, 16)` | Screw M4 cap x 16mm |
|
||||
| 2 | `screw(M4_cs_cap_screw, 20)` | Screw M4 cs cap x 20mm |
|
||||
| 26 | `washer(M2_washer)` | Washer M2 x 5mm x 0.3mm |
|
||||
| 31 | `washer(M3_washer)` | Washer M3 x 7mm x 0.5mm |
|
||||
| 23 | `washer(M3_washer)` | Washer M3 x 7mm x 0.5mm |
|
||||
| 4 | `washer(M4_washer)` | Washer M4 x 9mm x 0.8mm |
|
||||
|
||||
|
||||
@@ -2929,7 +3056,7 @@ For an explanation of `screw_polysink()` see <https://hydraraptor.blogspot.com/2
|
||||
| `screw(type, length, hob_point = 0, nylon = false)` | Draw specified screw, optionally hobbed or nylon |
|
||||
| `screw_and_washer(type, length, star = false, penny = false)` | Screw with a washer which can be standard or penny and an optional star washer on top |
|
||||
| `screw_countersink(type, drilled = true)` | Countersink shape |
|
||||
| `screw_polysink(type, h = 100, alt = false)` | A countersink hole made from stacked polyholes for printed parts |
|
||||
| `screw_polysink(type, h = 100, alt = false, sink = 0)` | A countersink hole made from stacked polyholes for printed parts, default is flush, `sink` can be used to recess the head |
|
||||
|
||||

|
||||
|
||||
@@ -2961,6 +3088,7 @@ For an explanation of `screw_polysink()` see <https://hydraraptor.blogspot.com/2
|
||||
| 1 | `screw(M5_hex_screw, 30)` | Screw M5 hex x 30mm |
|
||||
| 1 | `screw(M5_pan_screw, 30)` | Screw M5 pan x 30mm |
|
||||
| 1 | `screw(M6_cap_screw, 30)` | Screw M6 cap x 30mm |
|
||||
| 1 | `screw(M6_cs_cap_screw, 30)` | Screw M6 cs cap x 30mm |
|
||||
| 1 | `screw(M6_hex_screw, 30)` | Screw M6 hex x 30mm |
|
||||
| 1 | `screw(M6_pan_screw, 30)` | Screw M6 pan x 30mm |
|
||||
| 1 | `screw(M8_cap_screw, 35)` | Screw M8 cap x 35mm |
|
||||
@@ -2969,6 +3097,7 @@ For an explanation of `screw_polysink()` see <https://hydraraptor.blogspot.com/2
|
||||
| 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 |
|
||||
| 1 | `screw(No8_screw, 30)` | Screw No8 pan wood x 30mm |
|
||||
|
||||
### Printed
|
||||
| Qty | Filename |
|
||||
@@ -2976,68 +3105,6 @@ For an explanation of `screw_polysink()` see <https://hydraraptor.blogspot.com/2
|
||||
| 1 | polysink.stl |
|
||||
|
||||
|
||||
<a href="#top">Top</a>
|
||||
|
||||
---
|
||||
<a name="SCS_bearing_blocks"></a>
|
||||
## SCS_bearing_blocks
|
||||
SCSnUU and SCSnLUU bearing blocks
|
||||
|
||||
[vitamins/scs_bearing_blocks.scad](vitamins/scs_bearing_blocks.scad) Object definitions.
|
||||
|
||||
[vitamins/scs_bearing_block.scad](vitamins/scs_bearing_block.scad) Implementation.
|
||||
|
||||
[tests/SCS_bearing_blocks.scad](tests/SCS_bearing_blocks.scad) Code for this example.
|
||||
|
||||
### Properties
|
||||
| Function | Description |
|
||||
|:--- |:--- |
|
||||
| `scs_bearing(type)` | Linear bearing used |
|
||||
| `scs_block_center_height(type)` | Height of the center of the block |
|
||||
| `scs_block_side_height(type)` | Height of the side of the block, this determines the minimum screw length |
|
||||
| `scs_circlip(type)` | Circlip used |
|
||||
| `scs_hole_offset(type)` | Offset of bearing hole from base of block |
|
||||
| `scs_screw(type)` | Screw type |
|
||||
| `scs_screw_separation_x(type)` | Screw separation in X direction |
|
||||
| `scs_screw_separation_z(type)` | Screw separation in Z direction |
|
||||
| `scs_spacer(type)` | Spacer used in long bearings |
|
||||
|
||||
### Functions
|
||||
| Function | Description |
|
||||
|:--- |:--- |
|
||||
| `scs_size(type)` | Size of scs bracket bounding block |
|
||||
|
||||
### Modules
|
||||
| Module | Description |
|
||||
|:--- |:--- |
|
||||
| `scs_bearing_block(type)` | Draw the specified SCS bearing block |
|
||||
| `scs_bearing_block_assembly(type, part_thickness, screw_type, nut_type)` | Assembly with screws and nuts in place |
|
||||
| `scs_bearing_block_hole_positions(type)` | Place children at hole positions |
|
||||
|
||||

|
||||
|
||||
### Vitamins
|
||||
| Qty | Module call | BOM entry |
|
||||
| ---:|:--- |:---|
|
||||
| 12 | `nut(M4_nut)` | Nut M4 x 3.2mm |
|
||||
| 24 | `nut(M5_nut)` | Nut M5 x 4mm |
|
||||
| 1 | `scs_bearing_block(SCS10LUU)` | SCS10LUU bearing block |
|
||||
| 1 | `scs_bearing_block(SCS10UU)` | SCS10UU bearing block |
|
||||
| 1 | `scs_bearing_block(SCS12LUU)` | SCS12LUU bearing block |
|
||||
| 1 | `scs_bearing_block(SCS12UU)` | SCS12UU bearing block |
|
||||
| 1 | `scs_bearing_block(SCS16LUU)` | SCS16LUU bearing block |
|
||||
| 1 | `scs_bearing_block(SCS16UU)` | SCS16UU bearing block |
|
||||
| 1 | `scs_bearing_block(SCS6UU)` | SCS6UU bearing block |
|
||||
| 1 | `scs_bearing_block(SCS8LUU)` | SCS8LUU bearing block |
|
||||
| 1 | `scs_bearing_block(SCS8UU)` | SCS8UU bearing block |
|
||||
| 4 | `screw(M4_cap_screw, 25)` | Screw M4 cap x 25mm |
|
||||
| 8 | `screw(M4_cap_screw, 30)` | Screw M4 cap x 30mm |
|
||||
| 16 | `screw(M5_cap_screw, 35)` | Screw M5 cap x 35mm |
|
||||
| 8 | `screw(M5_cap_screw, 45)` | Screw M5 cap x 45mm |
|
||||
| 12 | `washer(M4_washer)` | Washer M4 x 9mm x 0.8mm |
|
||||
| 24 | `washer(M5_washer)` | Washer M5 x 10mm x 1mm |
|
||||
|
||||
|
||||
<a href="#top">Top</a>
|
||||
|
||||
---
|
||||
@@ -3154,6 +3221,7 @@ When woven sheets (e.g. carbon fibre) are rendered it is necessary to specify th
|
||||
| 1 | `sheet(FoilTape, 30, 30, 2)` | Aluminium foil tape 30mm x 30mm x 0.05mm |
|
||||
| 1 | `sheet(AL6, 30, 30, 2)` | Aluminium tooling plate 30mm x 30mm x 6mm |
|
||||
| 1 | `sheet(AL8, 30, 30, 2)` | Aluminium tooling plate 30mm x 30mm x 8mm |
|
||||
| 1 | `sheet(Spring05, 30, 30, 2)` | Bi-metal saw blade 30mm x 30mm x 0.5mm |
|
||||
| 1 | `sheet(Cardboard, 30, 30, 2)` | Corrugated cardboard 30mm x 30mm x 5mm |
|
||||
| 1 | `sheet(Foam20, 30, 30, 2)` | Foam sponge 30mm x 30mm x 20mm |
|
||||
| 1 | `sheet(DiBond, 30, 30, 2)` | Sheet DiBond 30mm x 30mm x 3mm |
|
||||
@@ -3172,6 +3240,7 @@ When woven sheets (e.g. carbon fibre) are rendered it is necessary to specify th
|
||||
| 1 | `sheet(CF3, 30, 30, 2)` | Sheet carbon fiber 30mm x 30mm x 3mm |
|
||||
| 1 | `sheet(glass2, 30, 30, 2)` | Sheet glass 30mm x 30mm x 2mm |
|
||||
| 1 | `sheet(Steel06, 30, 30, 2)` | Sheet mild steel 30mm x 30mm x 0.6mm |
|
||||
| 1 | `sheet(Silicone3, 30, 30, 2)` | Sheet silicone 30mm x 30mm x 3mm |
|
||||
|
||||
|
||||
<a href="#top">Top</a>
|
||||
@@ -5570,6 +5639,70 @@ The coordinates of the lowest point on the curve can be retrieved by calling `ca
|
||||

|
||||
|
||||
|
||||
<a href="#top">Top</a>
|
||||
|
||||
---
|
||||
<a name="Core_xy"></a>
|
||||
## Core_xy
|
||||
Parameterised Core XY implementation. Draws the belts and provides utilities for positioning the pulleys.
|
||||
|
||||
The belts are positioned according the bottom left "anchor" pulley and the top right drive pulley.
|
||||
Implementation has the following features:
|
||||
|
||||
1. The drive and idler pulleys may be different sizes.
|
||||
2. The belt separation is parameterised.
|
||||
3. The separation of the plain and toothed pulleys on the Y carriages is parameterised, in both the X and the Y direction.
|
||||
4. The drive pulleys may be offset in the X and Y directions. If this is done, extra idler pulleys are added. This
|
||||
allows flexible positioning of the motors.
|
||||
|
||||
[utils/core_xy.scad](utils/core_xy.scad) Implementation.
|
||||
|
||||
[tests/core_xy.scad](tests/core_xy.scad) Code for this example.
|
||||
|
||||
### Properties
|
||||
| Function | Description |
|
||||
|:--- |:--- |
|
||||
| `coreXY_belt(type)` | Belt type |
|
||||
| `coreXY_drive_pulley(type)` | Drive pulley type |
|
||||
| `coreXY_lower_belt_colour(type)` | Colour of the lower belt |
|
||||
| `coreXY_lower_tooth_colour(type)` | Colour of the lower belt's teeth |
|
||||
| `coreXY_plain_idler(type)` | Plain idler type |
|
||||
| `coreXY_toothed_idler(type)` | Toothed idler type |
|
||||
| `coreXY_upper_belt_colour(type)` | Colour of the upper belt |
|
||||
| `coreXY_upper_tooth_colour(type)` | Colour of the upper belt's teeth |
|
||||
|
||||
### Functions
|
||||
| Function | Description |
|
||||
|:--- |:--- |
|
||||
| `coreXY_coincident_separation(type)` | Value of x, y separation to make y-carriage pulleys coincident |
|
||||
| `coreXY_drive_plain_idler_offset(type)` | Offset of plain drive idler pulley |
|
||||
| `coreXY_drive_pulley_x_alignment(type)` | Belt alignment offset of the drive pulley relative to the anchor pulley |
|
||||
| `coreXY_drive_toothed_idler_offset(type)` | Offset of toothed drive idler pulley |
|
||||
| `coreXY_plain_idler_offset(type)` | Offset of y-carriage plain idler |
|
||||
| `coreXY_toothed_idler_offset(type)` | offset of y-carriage toothed idler |
|
||||
|
||||
### Modules
|
||||
| Module | Description |
|
||||
|:--- |:--- |
|
||||
| `coreXY(type, size, pos, separation, x_gap, plain_idler_offset = 0, upper_drive_pulley_offset, lower_drive_pulley_offset, show_pulleys = false)` | Wrapper module to draw both belts of a coreXY setup |
|
||||
| `coreXY_belts(type, carriagePosition, coreXYPosBL, coreXYPosTR, separation, x_gap = 20, upper_drive_pulley_offset = [0, 0], lower_drive_pulley_offset = [0, 0], show_pulleys = false)` | Draw the coreXY belts |
|
||||
| `coreXY_half(type, size, pos, separation_y = 0, x_gap = 0, plain_idler_offset = 0, drive_pulley_offset = [0, 0], show_pulleys = false, lower_belt = false, hflip = false)` | Draw one belt of a coreXY setup |
|
||||
|
||||

|
||||
|
||||
### Vitamins
|
||||
| Qty | Module call | BOM entry |
|
||||
| ---:|:--- |:---|
|
||||
| 1 | `belt(GT2x6, [ ... ])` | Belt GT2 x 6mm x 728mm |
|
||||
| 1 | `belt(GT2x6, [ ... ])` | Belt GT2 x 6mm x 824mm |
|
||||
| 7 | `pulley(GT2x16_toothed_idler)` | Pulley GT2 idler 16 teeth |
|
||||
| 3 | `pulley(GT2x16_plain_idler)` | Pulley GT2 idler smooth 9.63mm |
|
||||
| 2 | `pulley(GT2x20ob_pulley)` | Pulley GT2OB 20 teeth |
|
||||
| 8 | `screw(M3_cap_screw, 20)` | Screw M3 cap x 20mm |
|
||||
| 4 | `screw(M3_grub_screw, 6)` | Screw M3 grub x 6mm |
|
||||
| 2 | `NEMA(NEMA17M)` | Stepper motor NEMA17 x 40mm |
|
||||
|
||||
|
||||
<a href="#top">Top</a>
|
||||
|
||||
---
|
||||
@@ -5752,12 +5885,17 @@ Maths utilities for manipulating vectors and matrices.
|
||||
| `circle_intersect(c1, r1, c2, r2)` | Calculate one point where two circles in the X-Z plane intersect, clockwise around c1 |
|
||||
| `cosh(x)` | hyperbolic cosine |
|
||||
| `coth(x)` | hyperbolic cotangent |
|
||||
| `cubic_real_roots(a, b, c, d)` | Returns real roots of cubic equation |
|
||||
| `degrees(radians)` | Convert degrees to radians |
|
||||
| `euler(R)` | Convert a rotation matrix to a Euler rotation vector. |
|
||||
| `identity(n, x = 1)` | Construct an arbitrary size identity matrix |
|
||||
| `invert(m)` | Invert a matrix |
|
||||
| `map(v, func)` | make a new vector where the func function argument is applied to each element of the vector v |
|
||||
| `mapi(v, func)` | make a new vector where the func function argument is applied to each element of the vector v. The func will get the index number as first argument, and the element as second argument. |
|
||||
| `nearly_zero(x)` | True if x is close to zero |
|
||||
| `quadratic_real_roots(a, b, c)` | Returns real roots of a quadratic equation, biggest first. Returns empty list if no real roots |
|
||||
| `radians(degrees)` | Convert radians to degrees |
|
||||
| `reduce(v, func, unity)` | reduce a vector v to a single entity by applying the func function recursively to the reduced value so far and the next element, starting with unity as the initial reduced value |
|
||||
| `reverse(v)` | Reverse a vector |
|
||||
| `rot2_z(a)` | Generate a 2x2 matrix to rotate around z |
|
||||
| `rot3_z(a)` | Generate a 3x3 matrix to rotate around z |
|
||||
@@ -5768,14 +5906,17 @@ Maths utilities for manipulating vectors and matrices.
|
||||
| `solve(m, i = 0, j = 0)` | Solve each row ensuring diagonal is not zero |
|
||||
| `solve_row(m, i)` | Make diagonal one by dividing the row by it and subtract from other rows to make column zero |
|
||||
| `sqr(x)` | Square x |
|
||||
| `sumv(v)` | sum a vector of values that can be added with "+" |
|
||||
| `tanh(x)` | hyperbolic tangent |
|
||||
| `transform(v, m)` | Apply 4x4 transform to a 3 vector by extending it and cropping it again |
|
||||
| `transform_points(path, m)` | Apply transform to a path |
|
||||
| `translate(v)` | Generate a 4x4 translation matrix, `v` can be `[x, y]`, `[x, y, z]` or `z` |
|
||||
| `transpose(m)` | Transpose an arbitrary size matrix |
|
||||
| `unit(v)` | Convert `v` to a unit vector |
|
||||
| `vec2(v)` | Return a 2 vector with the first two elements of `v` |
|
||||
| `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` |
|
||||
| `xor(a,b)` | Logical exclusive OR |
|
||||
|
||||
### Modules
|
||||
| Module | Description |
|
||||
@@ -5889,8 +6030,9 @@ Because the tangents need to be calculated to find the length these can be calcu
|
||||
| Function | Description |
|
||||
|:--- |:--- |
|
||||
| `circle_tangent(p1, p2)` | Compute the clockwise tangent between two circles represented as [x,y,r] |
|
||||
| `rounded_polygon_arcs(points, tangents)` | Compute the arcs at the points, for each point [angle, rotate_angle, length] |
|
||||
| `rounded_polygon_length(points, tangents)` | Calculate the length given the point list and the list of tangents computed by ` rounded_polygon_tangents` |
|
||||
| `rounded_polygon_tangents(points)` | Compute the straight sections needed to draw and to compute the lengths |
|
||||
| `rounded_polygon_tangents(points)` | Compute the straight sections between a point and the next point, for each section [start_point, end_point, length] |
|
||||
|
||||
### Modules
|
||||
| Module | Description |
|
||||
@@ -5903,20 +6045,20 @@ Because the tangents need to be calculated to find the length these can be calcu
|
||||
<a href="#top">Top</a>
|
||||
|
||||
---
|
||||
<a name="Rounded_right_triangle"></a>
|
||||
## Rounded_right_triangle
|
||||
<a name="Rounded_triangle"></a>
|
||||
## Rounded_triangle
|
||||
Draw a 3D right triangle with rounded edges. Intended to be embedded in other parts. Can be optionally offset by the filleted amount.
|
||||
|
||||
[utils/rounded_right_triangle.scad](utils/rounded_right_triangle.scad) Implementation.
|
||||
[utils/rounded_triangle.scad](utils/rounded_triangle.scad) Implementation.
|
||||
|
||||
[tests/rounded_right_triangle.scad](tests/rounded_right_triangle.scad) Code for this example.
|
||||
[tests/rounded_triangle.scad](tests/rounded_triangle.scad) Code for this example.
|
||||
|
||||
### Modules
|
||||
| Module | Description |
|
||||
|:--- |:--- |
|
||||
| `rounded_right_triangle(x, y, z, fillet, center = true, offset = false)` | Draw a 3D right triangle with rounded edges. |
|
||||
|
||||

|
||||

|
||||
|
||||
|
||||
<a href="#top">Top</a>
|
||||
@@ -6069,7 +6211,7 @@ This can speed up the generation of the build instructions greatly but isn't com
|
||||
The `pose()` module allows assembly views in the readme to be posed differently to the default view in the GUI:
|
||||
|
||||
* Setting the `exploded` parameter to `true` allows just the exploded version to be posed and setting to `false` allows just the assembled view to be posed, the default is both.
|
||||
* If the `d` parameter is set to specify the camera distance then the normal `viewall` and `autocenter` options are supressed allowing a small section to be zoomed in to fill the view.
|
||||
* If the `d` parameter is set to specify the camera distance then the normal `viewall` and `autocenter` options are suppressed allowing a small section to be zoomed in to fill the view.
|
||||
* To get the parameter values make the GUI window square, pose the view with the mouse and then copy the viewport parameters from the Edit menu and paste them into the pose invocation.
|
||||
* Two `pose()` modules can be chained to allow different poses for exploded and assembled views.
|
||||
|
||||
|
164
scripts/changelog.py
Normal file
@@ -0,0 +1,164 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
#
|
||||
# NopSCADlib Copyright Chris Palmer 2021
|
||||
# nop.head@gmail.com
|
||||
# hydraraptor.blogspot.com
|
||||
#
|
||||
# This file is part of NopSCADlib.
|
||||
#
|
||||
# NopSCADlib is free software: you can redistribute it and/or modify it under the terms of the
|
||||
# GNU General Public License as published by the Free Software Foundation, either version 3 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# NopSCADlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with NopSCADlib.
|
||||
# If not, see <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
#! Creates the changelog from the git log
|
||||
|
||||
from __future__ import print_function
|
||||
import sys
|
||||
import subprocess
|
||||
import re
|
||||
|
||||
filename = 'CHANGELOG.md'
|
||||
|
||||
def tag_version(t):
|
||||
""" Format a version tag """
|
||||
return 'v%d.%d.%d' % t
|
||||
|
||||
def initials(name):
|
||||
""" Convert full name to initials with a tooltip """
|
||||
i = ''.join([n[0].upper() + '.' for n in name.split(' ')])
|
||||
return '[%s](# "%s")' % (i, name)
|
||||
|
||||
def get_remote_url():
|
||||
""" Get the git remote URL for the repository """
|
||||
url = subprocess.check_output(["git", "config", "--get", "remote.origin.url"]).decode("utf-8").strip("\n")
|
||||
if url.startswith("git@"):
|
||||
url = url.replace(":", "/", 1).replace("git@", "https://", 1)
|
||||
if url.endswith(".git"):
|
||||
url = url[:-4]
|
||||
return url
|
||||
|
||||
def iscode(word):
|
||||
""" try to guess if the word is code """
|
||||
endings = ['()', '*']
|
||||
starts = ['$', '--']
|
||||
anywhere = ['.', '_', '=', '[', '/']
|
||||
words = ['center', 'false', 'true', 'ngb']
|
||||
|
||||
for w in words:
|
||||
if word == w:
|
||||
return True
|
||||
|
||||
for end in endings:
|
||||
if word.endswith(end):
|
||||
return True
|
||||
|
||||
for start in starts:
|
||||
if word.startswith(start):
|
||||
return True
|
||||
|
||||
for any in anywhere:
|
||||
if word.find(any) >= 0:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def codify(word, url):
|
||||
""" if a word is deemed code enclose it backticks """
|
||||
if word:
|
||||
if re.match(r'#[0-9]+', word):
|
||||
return '[%s](%s "show issue")' % (word, url + '/issues/' + word[1:])
|
||||
if iscode(word):
|
||||
return '`' + word + '`'
|
||||
return word
|
||||
|
||||
|
||||
def fixup_comment(comment, url):
|
||||
""" markup code words and fix new paragraphs """
|
||||
result = ''
|
||||
word = ''
|
||||
code = False
|
||||
for i, c in enumerate(comment):
|
||||
if c == '`' or code: # Already a code block
|
||||
result += c # Copy verbatim
|
||||
if c == '`': code = not code # Keep track of state
|
||||
else:
|
||||
if c in ' \n' or (c == '.' and (i + 1 == len(comment) or comment[i + 1] in ' \n')): # if a word terminator
|
||||
result += codify(word, url) + c # Add codified word before terminator
|
||||
word = ''
|
||||
else:
|
||||
word += c # Accumulate next word
|
||||
result += codify(word, url) # In case comment ends without a terminator
|
||||
return result.replace('\n\n','\n\n * ') # Give new paragraphs a bullet point
|
||||
|
||||
class Commit(): # members dynamically added from commit_fields
|
||||
pass
|
||||
|
||||
blurb = """
|
||||
# %s Changelog
|
||||
This changelog is generated by `changelog.py` using manually added semantic version tags to classify commits as breaking changes, additions or fixes.
|
||||
|
||||
"""
|
||||
|
||||
if __name__ == '__main__':
|
||||
url = get_remote_url()
|
||||
|
||||
commit_fields = {
|
||||
'hash': "%H|", # commit commit_hash
|
||||
'tag': "%D|", # tag
|
||||
'author': "%aN|", # author name
|
||||
'date': " %as|", # author date short form
|
||||
'comment': "%B~" # body
|
||||
}
|
||||
|
||||
# Produce the git log
|
||||
format = ''.join([v for k, v in commit_fields.items()])
|
||||
text = subprocess.check_output(["git", "log", "--topo-order", "--format=" + format]).decode("utf-8")
|
||||
|
||||
# Process the log into a list of Commit objects
|
||||
commits = []
|
||||
for line in text.split('~'):
|
||||
line = line.strip('\n')
|
||||
if line:
|
||||
fields = line.split('|')
|
||||
commit = Commit()
|
||||
for i, k in enumerate(commit_fields):
|
||||
exec('commit.%s = """%s"""' % (k, fields[i]), locals())
|
||||
# Convert version tag to tuple
|
||||
if commit.tag:
|
||||
match = re.match(r'.*tag: v([0-9]+)\.([0-9]+)\.([0-9]+).*', commit.tag)
|
||||
commit.tag = (int(match.group(1)), int(match.group(2)), int(match.group(3))) if match else ''
|
||||
commits.append(commit)
|
||||
|
||||
# Format the results from the Commit objects
|
||||
with open(filename, "wt") as file:
|
||||
print(blurb % url.split('/')[-1], file = file)
|
||||
for i, c in enumerate(commits):
|
||||
if c.tag:
|
||||
ver = tag_version(c.tag)
|
||||
level, type = (3, 'Fixes') if c.tag[2] else (2, 'Additions') if c.tag[1] else (1, 'Breaking Changes') if c.tag[0] else (1, 'First publicised version')
|
||||
|
||||
# Find the previous tagged commit
|
||||
j = i + 1
|
||||
diff = ''
|
||||
while j < len(commits):
|
||||
if commits[j].tag:
|
||||
last_ver = tag_version(commits[j].tag)
|
||||
diff = '[...](%s "diff with %s")' % (url + '/compare/' + last_ver + '...' + ver, last_ver)
|
||||
break
|
||||
j += 1
|
||||
|
||||
# Print verson info
|
||||
print('%s [%s](%s "show release") %s %s' % ('#' * (level + 1), ver, url + '/releases/tag/' + ver, type, diff), file = file)
|
||||
|
||||
# Print commits excluding merges
|
||||
|
||||
if not c.comment.startswith('Merge branch') and not c.comment.startswith('Merge pull') and not re.match(r'U..ated changelog.*', c.comment):
|
||||
print('* %s [`%s`](%s "show commit") %s %s\n' % (c.date, c.hash[:7], url + '/commit/' + c.hash, initials(c.author), fixup_comment(c.comment, url)), file = file)
|
@@ -142,7 +142,7 @@ def make_parts(target, part_type, parts = None):
|
||||
f.write("use <%s/%s>\n" % (reltmp(dir, target), filename))
|
||||
f.write("%s();\n" % module);
|
||||
t = time.time()
|
||||
openscad.run("-D$bom=1", "-d", dname, "-o", part_file, part_maker_name)
|
||||
openscad.run("-o", part_file, part_maker_name, "-D$bom=1", "-d", dname)
|
||||
times.add_time(part, t)
|
||||
if part_type == 'stl':
|
||||
bounds = c14n_stl.canonicalise(part_file)
|
||||
|
@@ -25,7 +25,7 @@ from __future__ import print_function
|
||||
import subprocess, sys
|
||||
|
||||
def run_list(args, silent = False, verbose = False):
|
||||
cmd = ["openscad", "--hardwarnings"] + args
|
||||
cmd = ["openscad"] + args + ["--hardwarnings"]
|
||||
if not silent:
|
||||
for arg in cmd:
|
||||
print(arg, end=" ")
|
||||
|
@@ -44,18 +44,22 @@ def plateup(target, part_type, usage = None):
|
||||
source_dir1 = source_dirs[part_type]
|
||||
source_dir2 = top_dir + source_dirs[part_type]
|
||||
|
||||
times.read_times(target_dir)
|
||||
#
|
||||
# Loop through source directories
|
||||
#
|
||||
all_used = []
|
||||
all_sources = []
|
||||
all_parts = []
|
||||
read_times = False
|
||||
for dir in [source_dir1, source_dir2]:
|
||||
if not os.path.isdir(dir):
|
||||
continue
|
||||
if not os.path.isdir(target_dir):
|
||||
os.makedirs(target_dir)
|
||||
|
||||
if not read_times:
|
||||
times.read_times(target_dir)
|
||||
read_times = True
|
||||
#
|
||||
# Make the deps dir
|
||||
#
|
||||
@@ -140,4 +144,4 @@ def plateup(target, part_type, usage = None):
|
||||
print("Removing %s" % file)
|
||||
os.remove(deps_dir + '/' + file)
|
||||
|
||||
times.print_times(all_parts)
|
||||
times.print_times(all_parts)
|
||||
|
@@ -8,6 +8,7 @@ They should work with both Python 2 and Python 3.
|
||||
|:---|:---|
|
||||
| `bom.py` | Generates BOM files for the project. |
|
||||
| `c14n_stl.py` | OpenSCAD produces randomly ordered STL files. This script re-orders them consistently so that GIT can tell if they have changed or not. |
|
||||
| `changelog.py` | Creates the changelog from the git log |
|
||||
| `doc_scripts.py` | Makes this document and doc/usage.md. |
|
||||
| `dxfs.py` | Generates DXF files for all the routed parts listed on the BOM or a specified list. |
|
||||
| `gallery.py` | Finds projects and adds them to the gallery. |
|
||||
|
@@ -94,7 +94,7 @@ def render(target, type):
|
||||
cam = "--camera=0,0,0,70,0,315,500" if type == 'stl' else "--camera=0,0,0,0,0,0,500"
|
||||
render = "--preview" if type == 'stl' or colour != pp1 else "--render"
|
||||
tmp_name = tmp_dir + '/' + part[:-4] + '.png'
|
||||
openscad.run(colour_scheme, "--projection=p", "--imgsize=4096,4096", cam, render, "--autocenter", "--viewall", "-o", tmp_name, png_maker_name);
|
||||
openscad.run("-o", tmp_name, png_maker_name, colour_scheme, "--projection=p", "--imgsize=4096,4096", cam, render, "--autocenter", "--viewall");
|
||||
do_cmd(("magick "+ tmp_name + " -trim -resize 280x280 -background %s -gravity Center -extent 280x280 -bordercolor %s -border 10 %s"
|
||||
% (background, background, tmp_name)).split())
|
||||
update_image(tmp_name, png_name)
|
||||
|
@@ -60,7 +60,8 @@ def compare_images(a, b, c):
|
||||
with open(log_name, 'w') as output:
|
||||
do_cmd(("magick compare -metric AE -fuzz %d%% %s %s %s" % (fuzz, a, b, c)).split(), output = output)
|
||||
with open(log_name, 'r') as f:
|
||||
pixels = int(float(f.read().strip()))
|
||||
pixels = f.read().strip()
|
||||
pixels = int(float(pixels if pixels.isnumeric() else -1))
|
||||
os.remove(log_name)
|
||||
return pixels
|
||||
|
||||
@@ -116,7 +117,7 @@ def tests(tests):
|
||||
libtest = True
|
||||
lib_blurb = scrape_blurb(scad_name)
|
||||
if not os.path.isfile(png_name):
|
||||
openscad.run(colour_scheme, "--projection=p", "--imgsize=%d,%d" % (w, h), "--camera=0,0,0,50,0,340,500", "--autocenter", "--viewall", "-o", png_name, scad_name);
|
||||
openscad.run(scad_name, "-o", png_name, colour_scheme, "--projection=p", "--imgsize=%d,%d" % (w, h), "--camera=0,0,0,50,0,340,500", "--autocenter", "--viewall");
|
||||
do_cmd(["magick", png_name, "-trim", "-resize", "1280", "-bordercolor", background, "-border", "10", png_name])
|
||||
else:
|
||||
#
|
||||
@@ -172,7 +173,7 @@ def tests(tests):
|
||||
impl_name = None
|
||||
|
||||
if libtest:
|
||||
vsplit = "AJR" + chr(ord('Z') + 1)
|
||||
vsplit = "AIR" + chr(ord('Z') + 1)
|
||||
vtype = locations[0][1]
|
||||
types = [vtype + ' ' + vsplit[i] + '-' + chr(ord(vsplit[i + 1]) - 1) for i in range(len(vsplit) - 1)] + [loc[1] for loc in locations[1 :]]
|
||||
if type == vtype:
|
||||
@@ -237,7 +238,7 @@ def tests(tests):
|
||||
print(changed)
|
||||
t = time.time()
|
||||
tmp_name = tmp_dir + '/tmp.png'
|
||||
openscad.run_list(options.list() + ["-D$bom=2", colour_scheme, "--projection=p", "--imgsize=%d,%d" % (w, h), "--camera=0,0,0,70,0,315,500", "--autocenter", "--viewall", "-d", dname, "-o", tmp_name, scad_name]);
|
||||
openscad.run_list([scad_name, "-o", tmp_name] + options.list() + ["-D$bom=2", colour_scheme, "--projection=p", "--imgsize=%d,%d" % (w, h), "--camera=0,0,0,70,0,315,500", "--autocenter", "--viewall", "-d", dname]);
|
||||
times.add_time(scad_name, t)
|
||||
do_cmd(["magick", tmp_name, "-trim", "-resize", "1000x600", "-bordercolor", background, "-border", "10", tmp_name])
|
||||
update_image(tmp_name, png_name)
|
||||
|
@@ -221,7 +221,7 @@ def views(target, do_assemblies = None):
|
||||
target_def = ['-D$target="%s"' % target] if target else []
|
||||
cwd_def = ['-D$cwd="%s"' % os.getcwd().replace('\\', '/')]
|
||||
view_def = ['--viewall', '--autocenter'] if not (zoomed & (1 << explode)) else ['--camera=0,0,0,55,0,25,140']
|
||||
openscad.run_list(options.list() + target_def + cwd_def + view_def +["-D$pose=1", "-D$explode=%d" % explode, colour_scheme, "--projection=p", "--imgsize=4096,4096", "-d", dname, "-o", tmp_name, png_maker_name]);
|
||||
openscad.run_list(["-o", tmp_name, png_maker_name] + options.list() + target_def + cwd_def + view_def + ["-D$pose=1", "-D$explode=%d" % explode, colour_scheme, "--projection=p", "--imgsize=4096,4096", "-d", dname]);
|
||||
times.add_time(png_name, t)
|
||||
do_cmd(["magick", tmp_name, "-trim", "-resize", "1004x1004", "-bordercolor", background, "-border", "10", tmp_name])
|
||||
update_image(tmp_name, png_name)
|
||||
|
@@ -29,7 +29,7 @@ module pcbs() {
|
||||
rotate(90)
|
||||
pcb_assembly(pcbs[$i], 5 + $i, 3);
|
||||
|
||||
translate([0, 120])
|
||||
translate([0, 110])
|
||||
layout([for(p = perfboards) pcb_length(p)], 10)
|
||||
translate([0, -pcb_width(perfboards[$i]) / 2])
|
||||
pcb_assembly(perfboards[$i], 5 + $i, 3);
|
||||
|
@@ -17,7 +17,7 @@
|
||||
// If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
include <../core.scad>
|
||||
include <../vitamins/scs_bearing_blocks.scad>
|
||||
include <../vitamins/bearing_blocks.scad>
|
||||
|
||||
use <../utils/layout.scad>
|
||||
|
@@ -25,9 +25,9 @@ use <../utils/layout.scad>
|
||||
module belt_test() {
|
||||
p2 = [-75, -50];
|
||||
p3 = [-75, 100];
|
||||
p4 = [75, 100];
|
||||
p4 = [ 75, 100];
|
||||
|
||||
p5 = [75 + pulley_pr(GT2x20ob_pulley) - pulley_pr(GT2x16_plain_idler), +pulley_pr(GT2x16_plain_idler)];
|
||||
p5 = [ 75 + pulley_pr(GT2x20ob_pulley) - pulley_pr(GT2x16_plain_idler), +pulley_pr(GT2x16_plain_idler)];
|
||||
p6 = [-75 + pulley_pr(GT2x20ob_pulley) + pulley_pr(GT2x16_plain_idler), -pulley_pr(GT2x16_plain_idler)];
|
||||
|
||||
module pulleys(flip = false) {
|
||||
@@ -52,19 +52,21 @@ module belt_test() {
|
||||
translate(p6) pulley_assembly(GT2x16_plain_idler);
|
||||
}
|
||||
|
||||
path = [ [p5.x, p5.y, pulley_pr(GT2x16_plain_idler)],
|
||||
path = [ [-40, 0, 0],
|
||||
[p6.x, p6.y, -pulley_pr(GT2x16_plain_idler)],
|
||||
[p2.x, p2.y, pulley_pr(GT2x20ob_pulley)],
|
||||
[p3.x, p3.y, pulley_pr(GT2x20ob_pulley)],
|
||||
[p4.x, p4.y, pulley_pr(GT2x20ob_pulley)]
|
||||
[p4.x, p4.y, pulley_pr(GT2x20ob_pulley)],
|
||||
[p5.x, p5.y, pulley_pr(GT2x16_plain_idler)],
|
||||
[40, 0, 0],
|
||||
];
|
||||
|
||||
belt = GT2x6;
|
||||
belt(belt, path, 80, [0, 0]);
|
||||
belt(belt, path, open = true);
|
||||
pulleys();
|
||||
translate_z(20)
|
||||
hflip() {
|
||||
belt(belt, path, 80, [0, 0], belt_colour = grey(90), tooth_colour = grey(50));
|
||||
belt(belt, path, open = true, belt_colour = grey(90), tooth_colour = grey(50));
|
||||
pulleys(flip=true);
|
||||
}
|
||||
|
||||
@@ -72,6 +74,31 @@ module belt_test() {
|
||||
layout([for(b = belts) belt_width(b)], 10)
|
||||
rotate([0, 90, 0])
|
||||
belt(belts[$i], [[0, 0, 20], [0, 1, 20]], belt_colour = $i%2==0 ? grey(90) : grey(20), tooth_colour = $i%2==0 ? grey(70) : grey(50));
|
||||
|
||||
// new example with open loop - this is a simplified example of the style used for example for the BLV 3D printer
|
||||
pulley = GT2x20ob_pulley;
|
||||
idler = GT2x16_plain_idler;
|
||||
corners = [[-75,-50],[75,100]];
|
||||
carriagepos = [0,0];
|
||||
carriagew = 80;
|
||||
|
||||
points = [
|
||||
[carriagepos.x - carriagew / 2, carriagepos.y, 0],
|
||||
[corners[0].x + belt_pulley_pr(belt, pulley) + belt_pulley_pr(belt, idler), carriagepos.y - belt_pulley_pr(belt, idler), idler],
|
||||
[corners[0].x, corners[0].y, pulley],
|
||||
[corners[0].x, corners[1].y, idler],
|
||||
[corners[1].x, corners[1].y, idler],
|
||||
[corners[1].x, carriagepos.y + belt_pulley_pr(belt, idler), idler],
|
||||
[carriagepos.x + carriagew / 2, carriagepos.y, 0]
|
||||
];
|
||||
translate_z(-30) {
|
||||
belt(belt, points, open=true, auto_twist=true);
|
||||
for (p = points)
|
||||
if (is_list(p.z))
|
||||
translate([p.x, p.y, 0])
|
||||
pulley_assembly(p.z);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if($preview)
|
||||
|
30
tests/box_sections.scad
Normal file
@@ -0,0 +1,30 @@
|
||||
//
|
||||
// NopSCADlib Copyright Chris Palmer 2021
|
||||
// nop.head@gmail.com
|
||||
// hydraraptor.blogspot.com
|
||||
//
|
||||
// This file is part of NopSCADlib.
|
||||
//
|
||||
// NopSCADlib is free software: you can redistribute it and/or modify it under the terms of the
|
||||
// GNU General Public License as published by the Free Software Foundation, either version 3 of
|
||||
// the License, or (at your option) any later version.
|
||||
//
|
||||
// NopSCADlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with NopSCADlib.
|
||||
// If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
include <../utils/core/core.scad>
|
||||
use <../utils/layout.scad>
|
||||
|
||||
include <../vitamins/box_sections.scad>
|
||||
|
||||
module box_sections() {
|
||||
layout([for(b = box_sections) box_section_size(b).x], 20)
|
||||
box_section(box_sections[$i], 100);
|
||||
}
|
||||
|
||||
if($preview)
|
||||
box_sections();
|
134
tests/core_xy.scad
Normal file
@@ -0,0 +1,134 @@
|
||||
//
|
||||
// NopSCADlib Copyright Chris Palmer 2020
|
||||
// nop.head@gmail.com
|
||||
// hydraraptor.blogspot.com
|
||||
//
|
||||
// This file is part of NopSCADlib.
|
||||
//
|
||||
// NopSCADlib is free software: you can redistribute it and/or modify it under the terms of the
|
||||
// GNU General Public License as published by the Free Software Foundation, either version 3 of
|
||||
// the License, or (at your option) any later version.
|
||||
//
|
||||
// NopSCADlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with NopSCADlib.
|
||||
// If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
include <../core.scad>
|
||||
include <../vitamins/pulleys.scad>
|
||||
include <../vitamins/screws.scad>
|
||||
include <../vitamins/stepper_motors.scad>
|
||||
include <../vitamins/washers.scad>
|
||||
|
||||
include <../utils/core_xy.scad>
|
||||
|
||||
|
||||
module coreXY_belts_test() {
|
||||
coreXY_type = coreXY_GT2_20_16;
|
||||
plain_idler = coreXY_plain_idler(coreXY_type);
|
||||
toothed_idler = coreXY_toothed_idler(coreXY_type);
|
||||
|
||||
coreXYPosBL = [0, 0, 0];
|
||||
coreXYPosTR = [200, 150, 0];
|
||||
separation = [0, coreXY_coincident_separation(coreXY_type).y, pulley_height(plain_idler) + washer_thickness(M3_washer)];
|
||||
pos = [100, 50];
|
||||
|
||||
upper_drive_pulley_offset = [40, 10];
|
||||
lower_drive_pulley_offset = [0, 0];
|
||||
|
||||
coreXY_belts(coreXY_type,
|
||||
carriagePosition = pos,
|
||||
coreXYPosBL = coreXYPosBL,
|
||||
coreXYPosTR = coreXYPosTR,
|
||||
separation = separation,
|
||||
x_gap = 10,
|
||||
upper_drive_pulley_offset = upper_drive_pulley_offset,
|
||||
lower_drive_pulley_offset = lower_drive_pulley_offset,
|
||||
show_pulleys = true);
|
||||
|
||||
|
||||
translate([coreXYPosBL.x + separation.x/2, coreXYPosTR.y + upper_drive_pulley_offset.y, separation.z/2]) {
|
||||
// add the upper drive pulley stepper motor
|
||||
translate([coreXY_drive_pulley_x_alignment(coreXY_type) + upper_drive_pulley_offset.x, 0, -pulley_height(coreXY_drive_pulley(coreXY_type))])
|
||||
NEMA(NEMA17M);
|
||||
|
||||
// add the screws for the upper drive offset idler pulleys if required
|
||||
if (upper_drive_pulley_offset.x > 0) {
|
||||
translate(coreXY_drive_plain_idler_offset(coreXY_type))
|
||||
translate_z(-pulley_offset(plain_idler))
|
||||
screw(M3_cap_screw, 20);
|
||||
translate(coreXY_drive_toothed_idler_offset(coreXY_type))
|
||||
translate_z(-pulley_offset(toothed_idler))
|
||||
screw(M3_cap_screw, 20);
|
||||
} else if (upper_drive_pulley_offset.x < 0) {
|
||||
translate([-pulley_od(plain_idler), coreXY_drive_plain_idler_offset(coreXY_type).y])
|
||||
translate_z(-pulley_offset(plain_idler))
|
||||
screw(M3_cap_screw, 20);
|
||||
translate([2*coreXY_drive_pulley_x_alignment(coreXY_type), coreXY_drive_toothed_idler_offset(coreXY_type).y])
|
||||
translate_z(-pulley_offset(toothed_idler))
|
||||
screw(M3_cap_screw, 20);
|
||||
}
|
||||
}
|
||||
|
||||
translate([coreXYPosTR.x - separation.x/2, coreXYPosTR.y + lower_drive_pulley_offset.y, -separation.z/2]) {
|
||||
// add the lower drive pulley stepper motor
|
||||
translate([-coreXY_drive_pulley_x_alignment(coreXY_type) + lower_drive_pulley_offset.x, 0, -pulley_height(coreXY_drive_pulley(coreXY_type))])
|
||||
NEMA(NEMA17M);
|
||||
|
||||
// add the screws for the lower drive offset idler pulleys if required
|
||||
if (lower_drive_pulley_offset.x < 0) {
|
||||
translate([-coreXY_drive_plain_idler_offset(coreXY_type).x, coreXY_drive_plain_idler_offset(coreXY_type).y])
|
||||
translate_z(-pulley_offset(plain_idler))
|
||||
screw(M3_cap_screw, 20);
|
||||
translate(coreXY_drive_toothed_idler_offset(coreXY_type))
|
||||
translate_z(-pulley_offset(toothed_idler))
|
||||
screw(M3_cap_screw, 20);
|
||||
} else if (lower_drive_pulley_offset.x > 0) {
|
||||
translate([pulley_od(plain_idler), coreXY_drive_plain_idler_offset(coreXY_type).y])
|
||||
translate_z(-pulley_offset(plain_idler))
|
||||
screw(M3_cap_screw, 20);
|
||||
translate([-2*coreXY_drive_pulley_x_alignment(coreXY_type), coreXY_drive_toothed_idler_offset(coreXY_type).y])
|
||||
translate_z(-pulley_offset(toothed_idler))
|
||||
screw(M3_cap_screw, 20);
|
||||
}
|
||||
}
|
||||
|
||||
// add the screw for the left upper idler pulley
|
||||
translate([coreXYPosBL.x + separation.x/2, coreXYPosBL.y, separation.z])
|
||||
screw(M3_cap_screw, 20);
|
||||
|
||||
// add the screw for the right upper idler pulley
|
||||
translate([coreXYPosTR.x + separation.x/2, coreXYPosBL.y, separation.z])
|
||||
screw(M3_cap_screw, 20);
|
||||
|
||||
if (separation.x != 0) {
|
||||
// add the screw for the left lower idler pulley
|
||||
translate([coreXYPosBL.x - separation.x/2, coreXYPosBL.y, 0])
|
||||
screw(M3_cap_screw, 20);
|
||||
|
||||
// add the screw for the right lower idler pulley
|
||||
translate([coreXYPosTR.x - separation.x/2, coreXYPosBL.y, 0])
|
||||
screw(M3_cap_screw, 20);
|
||||
}
|
||||
|
||||
translate([-separation.x/2, pos.y + coreXYPosBL.y -separation.y/2, -separation.z/2 + pulley_height(plain_idler)/2]) {
|
||||
// add the screw for the left Y carriage toothed idler
|
||||
translate([coreXYPosBL.x, coreXY_toothed_idler_offset(coreXY_type).y, 0])
|
||||
screw(M3_cap_screw, 20);
|
||||
// add the screw for the left Y carriage plain idler
|
||||
translate([coreXYPosBL.x + separation.x + coreXY_plain_idler_offset(coreXY_type).x, separation.y + coreXY_plain_idler_offset(coreXY_type).y, separation.z])
|
||||
screw(M3_cap_screw, 20);
|
||||
// add the screw for the right Y carriage toothed idler
|
||||
translate([coreXYPosTR.x + separation.x, coreXY_toothed_idler_offset(coreXY_type).y, separation.z])
|
||||
screw(M3_cap_screw, 20);
|
||||
// add the screw for the right Y carriage plain idler
|
||||
translate([coreXYPosTR.x - coreXY_plain_idler_offset(coreXY_type).x, separation.y + coreXY_plain_idler_offset(coreXY_type).y, 0])
|
||||
screw(M3_cap_screw, 20);
|
||||
}
|
||||
}
|
||||
|
||||
if ($preview)
|
||||
coreXY_belts_test();
|
@@ -17,7 +17,7 @@
|
||||
// If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
include <../core.scad>
|
||||
include <../vitamins/kp_pillow_blocks.scad>
|
||||
include <../vitamins/pillow_blocks.scad>
|
||||
|
||||
use <../utils/layout.scad>
|
||||
|
BIN
tests/png/bearing_blocks.png
Normal file
After Width: | Height: | Size: 92 KiB |
Before Width: | Height: | Size: 133 KiB After Width: | Height: | Size: 162 KiB |
BIN
tests/png/box_sections.png
Normal file
After Width: | Height: | Size: 26 KiB |
BIN
tests/png/core_xy.png
Normal file
After Width: | Height: | Size: 125 KiB |
Before Width: | Height: | Size: 119 KiB After Width: | Height: | Size: 119 KiB |
Before Width: | Height: | Size: 117 KiB After Width: | Height: | Size: 117 KiB |
Before Width: | Height: | Size: 102 KiB After Width: | Height: | Size: 102 KiB |
Before Width: | Height: | Size: 102 KiB After Width: | Height: | Size: 103 KiB |
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 61 KiB |
Before Width: | Height: | Size: 174 KiB After Width: | Height: | Size: 174 KiB |
Before Width: | Height: | Size: 153 KiB After Width: | Height: | Size: 153 KiB |
BIN
tests/png/pillow_blocks.png
Normal file
After Width: | Height: | Size: 85 KiB |
Before Width: | Height: | Size: 166 KiB After Width: | Height: | Size: 166 KiB |
Before Width: | Height: | Size: 71 KiB After Width: | Height: | Size: 71 KiB |
Before Width: | Height: | Size: 154 KiB After Width: | Height: | Size: 152 KiB |
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 40 KiB |
BIN
tests/png/rounded_triangle.png
Normal file
After Width: | Height: | Size: 67 KiB |
Before Width: | Height: | Size: 148 KiB After Width: | Height: | Size: 160 KiB |
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 73 KiB |
Before Width: | Height: | Size: 78 KiB After Width: | Height: | Size: 78 KiB |
Before Width: | Height: | Size: 181 KiB After Width: | Height: | Size: 181 KiB |
@@ -22,27 +22,36 @@ include <../vitamins/rails.scad>
|
||||
use <../utils/layout.scad>
|
||||
use <../vitamins/nut.scad>
|
||||
|
||||
length = 200;
|
||||
sheet = 3;
|
||||
pos = 1; //[-1 : 0.1 : 1]
|
||||
|
||||
function rail_carriages(rail) = [for(c = carriages) if(carriage_rail(c) == rail) c];
|
||||
|
||||
module rails()
|
||||
layout([for(l = carriages) carriage_width(l)], 20)
|
||||
layout([for(r = rails) carriage_width(rail_carriages(r)[0])], 20)
|
||||
rotate(-90) {
|
||||
carriage = carriages[$i];
|
||||
rail = carriage_rail(carriage);
|
||||
length = 200;
|
||||
rail = rails[$i];
|
||||
carriages = rail_carriages(rail);
|
||||
carriage = carriages[0];
|
||||
screw = rail_screw(rail);
|
||||
nut = screw_nut(screw);
|
||||
washer = screw_washer(screw);
|
||||
|
||||
rail_assembly(carriage, length, pos * carriage_travel(carriage, length) / 2, $i<2 ? grey(20) : "green", $i<2 ? grey(20) : "red");
|
||||
|
||||
if(len(carriages) > 1)
|
||||
translate([-carriage_travel(carriages[1], length) / 2, 0])
|
||||
carriage(carriages[1]);
|
||||
|
||||
rail_screws(rail, length, sheet + nut_thickness(nut, true) + washer_thickness(washer));
|
||||
|
||||
rail_hole_positions(rail, length, 0)
|
||||
translate_z(-sheet)
|
||||
vflip()
|
||||
nut_and_washer(nut, true);
|
||||
|
||||
echo(rail[0], (length - (rail_holes(rail, length) - 1) * rail_pitch(rail)) / 2);
|
||||
}
|
||||
|
||||
if($preview)
|
||||
|
@@ -18,7 +18,7 @@
|
||||
//
|
||||
|
||||
include <../global_defs.scad>
|
||||
use <../utils/rounded_right_triangle.scad>
|
||||
use <../utils/rounded_triangle.scad>
|
||||
|
||||
|
||||
module rounded_right_triangles() {
|
@@ -16,6 +16,10 @@
|
||||
// You should have received a copy of the GNU General Public License along with NopSCADlib.
|
||||
// If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
// Extra countersink depth
|
||||
sink = 0; // [0 : 0.05: 1.0]
|
||||
|
||||
include <../core.scad>
|
||||
|
||||
module polysink_stl() {
|
||||
@@ -32,9 +36,9 @@ module polysink_stl() {
|
||||
let(s = cs_screws[i])
|
||||
translate([i * 20, 0]) {
|
||||
translate_z(size.z)
|
||||
screw_polysink(s, 2 * size.z + 1);
|
||||
screw_polysink(s, 2 * size.z + 1, sink = sink);
|
||||
|
||||
screw_polysink(s, 2 * size.z + 1, alt = true);
|
||||
screw_polysink(s, 2 * size.z + 1, alt = true, sink = sink);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -25,25 +25,30 @@ include <../vitamins/screws.scad>
|
||||
width = 30;
|
||||
2d = true;
|
||||
|
||||
module sheets()
|
||||
layout([for(s = sheets) width], 5)
|
||||
let(sheet = sheets[$i], w = sheet_is_woven(sheet) ? width : undef)
|
||||
if(2d)
|
||||
render_2D_sheet(sheet, w = w, d = w)
|
||||
difference() {
|
||||
sheet_2D(sheet, width, width, 2);
|
||||
module sheets() {
|
||||
rows = 2;
|
||||
n = ceil(len(sheets) / rows);
|
||||
w = width + 5;
|
||||
for(y = [0 : rows - 1], x = [0 : n - 1], s = y * n + x)
|
||||
if(s < len(sheets))
|
||||
translate([width / 2 + x * w, y * w])
|
||||
let(sheet = sheets[s], w = sheet_is_woven(sheet) ? width : undef)
|
||||
if(2d)
|
||||
render_2D_sheet(sheet, w = w, d = w)
|
||||
difference() {
|
||||
sheet_2D(sheet, width, width, 2);
|
||||
|
||||
circle(3);
|
||||
}
|
||||
else
|
||||
render_sheet(sheet, w = w, d = w)
|
||||
difference() {
|
||||
sheet(sheet, width, width, 2);
|
||||
|
||||
translate_z(sheet_thickness(sheet) / 2)
|
||||
screw_countersink(M3_cs_cap_screw);
|
||||
}
|
||||
circle(3);
|
||||
}
|
||||
else
|
||||
render_sheet(sheet, w = w, d = w)
|
||||
difference() {
|
||||
sheet(sheet, width, width, 2);
|
||||
|
||||
translate_z(sheet_thickness(sheet) / 2)
|
||||
screw_countersink(M3_cs_cap_screw);
|
||||
}
|
||||
}
|
||||
|
||||
if($preview)
|
||||
sheets();
|
||||
|
@@ -38,7 +38,7 @@
|
||||
//! The `pose()` module allows assembly views in the readme to be posed differently to the default view in the GUI:
|
||||
//!
|
||||
//! * Setting the `exploded` parameter to `true` allows just the exploded version to be posed and setting to `false` allows just the assembled view to be posed, the default is both.
|
||||
//! * If the `d` parameter is set to specify the camera distance then the normal `viewall` and `autocenter` options are supressed allowing a small section to be zoomed in to fill the view.
|
||||
//! * If the `d` parameter is set to specify the camera distance then the normal `viewall` and `autocenter` options are suppressed allowing a small section to be zoomed in to fill the view.
|
||||
//! * To get the parameter values make the GUI window square, pose the view with the mouse and then copy the viewport parameters from the Edit menu and paste them into the pose invocation.
|
||||
//! * Two `pose()` modules can be chained to allow different poses for exploded and assembled views.
|
||||
//
|
||||
|
203
utils/core_xy.scad
Normal file
@@ -0,0 +1,203 @@
|
||||
//
|
||||
// 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/>.
|
||||
//
|
||||
|
||||
//
|
||||
//! Parameterised Core XY implementation. Draws the belts and provides utilities for positioning the pulleys.
|
||||
//!
|
||||
//! The belts are positioned according the bottom left "anchor" pulley and the top right drive pulley.
|
||||
//! Implementation has the following features:
|
||||
//!
|
||||
//! 1. The drive and idler pulleys may be different sizes.
|
||||
//! 2. The belt separation is parameterised.
|
||||
//! 3. The separation of the plain and toothed pulleys on the Y carriages is parameterised, in both the X and the Y direction.
|
||||
//! 4. The drive pulleys may be offset in the X and Y directions. If this is done, extra idler pulleys are added. This
|
||||
//! allows flexible positioning of the motors.
|
||||
//
|
||||
include <../core.scad>
|
||||
include <../vitamins/belts.scad>
|
||||
include <../vitamins/pulleys.scad>
|
||||
|
||||
|
||||
coreXY_GT2_20_20 = ["coreXY_20_20", GT2x6, GT2x20ob_pulley, GT2x20_toothed_idler, GT2x20_plain_idler, [0, 0, 1], [0, 0, 0.5, 1], [0, 1, 0], [0, 0.5, 0, 1] ];
|
||||
coreXY_GT2_20_16 = ["coreXY_20_16", GT2x6, GT2x20ob_pulley, GT2x16_toothed_idler, GT2x16_plain_idler, [0, 0, 1], [0, 0, 0.5, 1], [0, 1, 0], [0, 0.5, 0, 1] ];
|
||||
coreXY_GT2_16_16 = ["coreXY_16_16", GT2x6, GT2x16_pulley, GT2x16_toothed_idler, GT2x16_plain_idler, [0, 0, 1], [0, 0, 0.5, 1], [0, 1, 0], [0, 0.5, 0, 1] ];
|
||||
|
||||
function coreXY_belt(type) = type[1]; //! Belt type
|
||||
function coreXY_drive_pulley(type) = type[2]; //! Drive pulley type
|
||||
function coreXY_toothed_idler(type) = type[3]; //! Toothed idler type
|
||||
function coreXY_plain_idler(type) = type[4]; //! Plain idler type
|
||||
function coreXY_upper_belt_colour(type) = type[5]; //! Colour of the upper belt
|
||||
function coreXY_upper_tooth_colour(type) = type[6]; //! Colour of the upper belt's teeth
|
||||
function coreXY_lower_belt_colour(type) = type[7]; //! Colour of the lower belt
|
||||
function coreXY_lower_tooth_colour(type) = type[8]; //! Colour of the lower belt's teeth
|
||||
|
||||
// used to offset the position of the drive pulley and the y-carriage plain idler pulley
|
||||
// relative to the anchor pulley so that the belts align properly
|
||||
function coreXY_drive_pulley_x_alignment(type) = //! Belt alignment offset of the drive pulley relative to the anchor pulley
|
||||
(pulley_od(coreXY_drive_pulley(type)) - pulley_od(coreXY_toothed_idler(type))) / 2;
|
||||
|
||||
function coreXY_coincident_separation(type) = //! Value of x, y separation to make y-carriage pulleys coincident
|
||||
[ -coreXY_plain_idler_offset(type).x, -(pulley_od(coreXY_plain_idler(type)) + pulley_od(coreXY_toothed_idler(type)))/2, 0 ];
|
||||
|
||||
function coreXY_plain_idler_offset(type) = //! Offset of y-carriage plain idler
|
||||
[ (pulley_od(coreXY_plain_idler(type)) + pulley_od(coreXY_drive_pulley(type))) / 2 + coreXY_drive_pulley_x_alignment(type), pulley_od(coreXY_plain_idler(type))/2, 0 ];
|
||||
|
||||
function coreXY_toothed_idler_offset(type) = //! offset of y-carriage toothed idler
|
||||
[ 0, -pulley_pr(coreXY_toothed_idler(type)), 0 ];
|
||||
|
||||
// helper functions for positioning idlers when the stepper motor drive pulley is offset
|
||||
function coreXY_drive_toothed_idler_offset(type) = //! Offset of toothed drive idler pulley
|
||||
[ 0, coreXY_drive_pulley_x_alignment(type), 0 ];
|
||||
|
||||
function coreXY_drive_plain_idler_offset(type) = //! Offset of plain drive idler pulley
|
||||
[ coreXY_plain_idler_offset(type).x, -(pulley_od(coreXY_plain_idler(type)) + pulley_od(coreXY_drive_pulley(type))) / 2, 0 ];
|
||||
|
||||
|
||||
module coreXY_half(type, size, pos, separation_y = 0, x_gap = 0, plain_idler_offset = 0, drive_pulley_offset = [0, 0], show_pulleys = false, lower_belt = false, hflip = false) { //! Draw one belt of a coreXY setup
|
||||
|
||||
// y-carriage toothed pulley
|
||||
p0_type = coreXY_toothed_idler(type);
|
||||
p0 = [ size.x / 2, -size.y / 2 - pulley_od(p0_type) / 2 + pos.y - separation_y / 2 ];
|
||||
|
||||
// bottom right toothed idler pulley
|
||||
p1_type = p0_type;
|
||||
p1 = [ size.x / 2, -size.y / 2 ];
|
||||
|
||||
// bottom left anchor toothed idler pulley
|
||||
p2_type = p0_type;
|
||||
p2 = [ -size.x / 2, -size.y / 2 ];
|
||||
|
||||
// stepper motor drive pulley
|
||||
p3d_type = coreXY_drive_pulley(type);
|
||||
p3d = [ -size.x / 2 + coreXY_drive_pulley_x_alignment(type) + drive_pulley_offset.x,
|
||||
size.y / 2 + drive_pulley_offset.y
|
||||
];
|
||||
|
||||
// toothed idler for offset stepper motor drive pulley
|
||||
p3t_type = coreXY_toothed_idler(type);
|
||||
p3t = [ -size.x / 2 + (drive_pulley_offset.x > 0 ? 0 : 2 * coreXY_drive_pulley_x_alignment(type)),
|
||||
size.y / 2 + coreXY_drive_pulley_x_alignment(type) + drive_pulley_offset.y
|
||||
];
|
||||
|
||||
// y-carriage plain pulley
|
||||
p4_type = coreXY_plain_idler(type);
|
||||
p4 = [ -size.x / 2 + pulley_od(p4_type) / 2 + pulley_od(p3d_type) / 2 + coreXY_drive_pulley_x_alignment(type) + plain_idler_offset,
|
||||
-size.y / 2 + pulley_od(p4_type) / 2 + pos.y + separation_y / 2
|
||||
];
|
||||
|
||||
// plain idler for offset stepper motor drive pulley
|
||||
p3p_type = p4_type;
|
||||
p3p = [ drive_pulley_offset.x > 0 ? p4.x : -p0.x - pulley_od(p0_type),
|
||||
size.y / 2 - pulley_od(p3p_type) / 2 - pulley_od(p3d_type) / 2 + drive_pulley_offset.y
|
||||
];
|
||||
|
||||
// Start and end points
|
||||
start_p = [ pos.x - size.x / 2 + x_gap / 2, -size.y / 2 + pos.y - separation_y / 2, 0 ];
|
||||
end_p = [ pos.x - size.x / 2 - x_gap / 2, -size.y / 2 + pos.y + separation_y / 2, 0 ];
|
||||
|
||||
//p6_type = p0_type;
|
||||
|
||||
module show_pulleys(show_pulleys) {// Allows the pulley colour to be set for debugging
|
||||
if (is_list(show_pulleys))
|
||||
color(show_pulleys)
|
||||
children();
|
||||
else if (show_pulleys)
|
||||
children();
|
||||
}
|
||||
|
||||
show_pulleys(show_pulleys) {
|
||||
translate(p0)
|
||||
pulley_assembly(p0_type); // y-carriage toothed pulley
|
||||
|
||||
translate(p1)
|
||||
pulley_assembly(p1_type); // bottom right toothed idler pulley
|
||||
|
||||
translate(p2)
|
||||
pulley_assembly(p2_type); // bottom left anchor toothed idler pulley
|
||||
|
||||
translate(p3d)
|
||||
hflip(hflip)
|
||||
pulley_assembly(p3d_type); // top left stepper motor drive pulley
|
||||
|
||||
if (drive_pulley_offset.x) { // idler pulleys for offset stepper motor drive pulley
|
||||
translate(p3t)
|
||||
pulley_assembly(p3t_type); // toothed idler
|
||||
|
||||
translate(p3p)
|
||||
pulley_assembly(p3p_type); // plain idler
|
||||
}
|
||||
translate(p4)
|
||||
pulley_assembly(p4_type); // y-carriage plain pulley
|
||||
}
|
||||
|
||||
path0a = [
|
||||
[ p0.x, p0.y, pulley_od(p0_type) / 2 ],
|
||||
[ p1.x, p1.y, pulley_od(p1_type) / 2 ],
|
||||
[ p2.x, p2.y, pulley_od(p2_type) / 2 ]
|
||||
];
|
||||
path0b = [
|
||||
[ p3d.x, p3d.y, pulley_od(p3d_type) / 2 ],
|
||||
[ p4.x, p4.y, -pulley_od(p4_type) / 2 ]
|
||||
];
|
||||
path0c = [
|
||||
[ p3t.x, p3t.y, pulley_od(p3t_type) / 2 ],
|
||||
[ p3d.x, p3d.y, pulley_od(p3d_type) / 2 ],
|
||||
[ p3p.x, p3p.y, -pulley_od(p3p_type) / 2 ],
|
||||
[ p4.x, p4.y, -pulley_od(p4_type) / 2 ]
|
||||
];
|
||||
path0d = [
|
||||
[ p3p.x, p3p.y, -pulley_od(p3p_type) / 2 ],
|
||||
[ p3d.x, p3d.y, pulley_od(p3d_type) / 2 ],
|
||||
[ p3t.x, p3t.y, pulley_od(p3t_type) / 2 ],
|
||||
[ p4.x, p4.y, -pulley_od(p4_type) / 2 ]
|
||||
];
|
||||
|
||||
belt = coreXY_belt(type);
|
||||
|
||||
path0 = drive_pulley_offset.x == 0 ? concat(path0a, path0b) : drive_pulley_offset.x > 0 ? concat(path0a, path0c) : concat(path0a, path0d);
|
||||
path = concat([start_p], path0, [end_p]);
|
||||
|
||||
belt(type = belt,
|
||||
points = path,
|
||||
open = true,
|
||||
belt_colour = lower_belt ? coreXY_lower_belt_colour(type) : coreXY_upper_belt_colour(type),
|
||||
tooth_colour = lower_belt ? coreXY_lower_tooth_colour(type) : coreXY_upper_tooth_colour(type));
|
||||
}
|
||||
|
||||
module coreXY(type, size, pos, separation, x_gap, plain_idler_offset = 0, upper_drive_pulley_offset, lower_drive_pulley_offset, show_pulleys = false) { //! Wrapper module to draw both belts of a coreXY setup
|
||||
translate([size.x / 2 - separation.x / 2, size.y / 2, -separation.z / 2]) {
|
||||
// lower belt
|
||||
hflip()
|
||||
explode(25)
|
||||
coreXY_half(type, size, [size.x - pos.x - separation.x, pos.y], separation.y, x_gap, plain_idler_offset, [-lower_drive_pulley_offset.x, lower_drive_pulley_offset.y], show_pulleys, lower_belt = true, hflip = true);
|
||||
|
||||
// upper belt
|
||||
translate([separation.x, 0, separation.z])
|
||||
explode(25)
|
||||
coreXY_half(type, size, [pos.x, pos.y], separation.y, x_gap, plain_idler_offset, upper_drive_pulley_offset, show_pulleys, lower_belt = false, hflip=false);
|
||||
}
|
||||
}
|
||||
|
||||
module coreXY_belts(type, carriagePosition, coreXYPosBL, coreXYPosTR, separation, x_gap = 20, upper_drive_pulley_offset = [0, 0], lower_drive_pulley_offset = [0, 0], show_pulleys = false) { //! Draw the coreXY belts
|
||||
assert(coreXYPosBL.z == coreXYPosTR.z);
|
||||
|
||||
coreXYSize = coreXYPosTR - coreXYPosBL;
|
||||
translate(coreXYPosBL)
|
||||
coreXY(type, coreXYSize, [carriagePosition.x - coreXYPosBL.x + separation.x / 2, carriagePosition.y - coreXYPosBL.y], separation = separation, x_gap = x_gap, plain_idler_offset = 0, upper_drive_pulley_offset = upper_drive_pulley_offset, lower_drive_pulley_offset = lower_drive_pulley_offset, show_pulleys = show_pulleys);
|
||||
}
|
@@ -88,6 +88,7 @@ function scale(v) = let(s = is_list(v) ? v : [v, v, v]) //! Generate a 4x4 matr
|
||||
[0, 0, 0, 1]
|
||||
];
|
||||
|
||||
function vec2(v) = [v.x, v.y]; //! Return a 2 vector with the first two elements of `v`
|
||||
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
|
||||
@@ -153,3 +154,36 @@ function circle_intersect(c1, r1, c2, r2) = //! Calculate one point where tw
|
||||
d = norm(v), // Distance between centres
|
||||
a = atan2(v.z, v.x) - acos((sqr(d) + sqr(r2) - sqr(r1)) / (2 * d * r2)) // Cosine rule to find angle from c2
|
||||
) c2 + r2 * [cos(a), 0, sin(a)]; // Point on second circle
|
||||
|
||||
function map(v, func) = [ for (e = v) func(e) ]; //! make a new vector where the func function argument is applied to each element of the vector v
|
||||
function mapi(v, func) = [ for (i = [0:len(v)-1]) func(i,v[i]) ]; //! make a new vector where the func function argument is applied to each element of the vector v. The func will get the index number as first argument, and the element as second argument.
|
||||
function reduce(v, func, unity) = let ( r = function(i,val) i == len(v) ? val : r(i + 1, func(val, v[i])) ) r(0, unity); //! reduce a vector v to a single entity by applying the func function recursively to the reduced value so far and the next element, starting with unity as the initial reduced value
|
||||
function sumv(v) = reduce(v, function(a, b) a + b, 0); //! sum a vector of values that can be added with "+"
|
||||
|
||||
function xor(a,b) = (a && !b) || (!a && b); //! Logical exclusive OR
|
||||
function cuberoot(x)= sign(x)*abs(x)^(1/3);
|
||||
|
||||
function quadratic_real_roots(a, b, c) = //! Returns real roots of a quadratic equation, biggest first. Returns empty list if no real roots
|
||||
let(2a = 2 * a,
|
||||
2c = 2 * c,
|
||||
det = b^2 - 2a * 2c
|
||||
) det < 0 ? [] :
|
||||
let(r = sqrt(det),
|
||||
x1 = b < 0 ? 2c / (-b + r) : (-b - r) / 2a,
|
||||
x2 = b < 0 ? (-b + r) / 2a : 2c / (-b - r)
|
||||
) [x2, x1];
|
||||
|
||||
function cubic_real_roots(a, b, c, d) = //! Returns real roots of cubic equation
|
||||
let(b = b / a,
|
||||
c = c / a,
|
||||
d = d / a,
|
||||
inflection = -b / 3,
|
||||
p = c - b^2 / 3,
|
||||
q = 2 * b^3 / 27 - b * c / 3 + d,
|
||||
det = q^2 / 4 + p^3 / 27,
|
||||
roots = !p && !q ? 1 : nearly_zero(det) ? 2 : det < 0 ? 3 : 1,
|
||||
r = sqrt(det),
|
||||
x = cuberoot(-q / 2 - r) + cuberoot(-q / 2 + r)
|
||||
) roots == 1 ? [x] :
|
||||
roots == 2 ? [3 * q /p + inflection, -3 * q / p / 2 + inflection] :
|
||||
[for(i = [0 : roots - 1]) 2 * sqrt(-p / 3) * cos(acos(3 * q * sqrt(-3 / p) / p / 2) - i * 120) + inflection];
|
||||
|
@@ -24,6 +24,7 @@
|
||||
//! Because the tangents need to be calculated to find the length these can be calculated separately and re-used when drawing to save calculating them twice.
|
||||
//
|
||||
include <../utils/core/core.scad>
|
||||
use <../utils/maths.scad>
|
||||
|
||||
function circle_tangent(p1, p2) = //! Compute the clockwise tangent between two circles represented as [x,y,r]
|
||||
let(
|
||||
@@ -36,36 +37,45 @@ function circle_tangent(p1, p2) = //! Compute the clockwise tangent between two
|
||||
v = [cos(theta), sin(theta)]
|
||||
)[ p1 + r1 * v, p2 + r2 * v ];
|
||||
|
||||
function rounded_polygon_tangents(points) = //! Compute the straight sections needed to draw and to compute the lengths
|
||||
let(len = len(points))
|
||||
[for(i = [0 : len - 1])
|
||||
let(ends = circle_tangent(points[i], points[(i + 1) % len]))
|
||||
for(end = [0, 1])
|
||||
ends[end]];
|
||||
function rounded_polygon_arcs(points, tangents) = //! Compute the arcs at the points, for each point [angle, rotate_angle, length]
|
||||
let(
|
||||
len = len(points)
|
||||
) [ for (i = [0: len-1])
|
||||
let(
|
||||
p1 = vec2(tangents[(i - 1 + len) % len][1]),
|
||||
p2 = vec2(tangents[i][0]),
|
||||
p = vec2(points[i]),
|
||||
v1 = p1 - p,
|
||||
v2 = p2 - p,
|
||||
sr = points[i][2],
|
||||
r = abs(sr),
|
||||
a = r < 0.001 ? 0 : let( aa = acos((v1 * v2) / sqr(r)) ) cross(v1, v2) * sign(sr) <= 0 ? aa : 360 - aa,
|
||||
l = PI * a * r / 180,
|
||||
v0 = [r, 0],
|
||||
v = let (
|
||||
vv = norm(v0 - v2) < 0.001 ? 0 : abs(v2.y) < 0.001 ? 180 :
|
||||
let( aa = acos((v0 * v2) / sqr(r)) ) cross(v0, v2) * sign(sr) <= 0 ? aa : 360 - aa
|
||||
) sr > 0 ? 360 - vv : vv - a
|
||||
) [a, v, l]
|
||||
];
|
||||
|
||||
function sumv(v, i = 0, sum = 0) = i == len(v) ? sum : sumv(v, i + 1, sum + v[i]);
|
||||
function rounded_polygon_tangents(points) = //! Compute the straight sections between a point and the next point, for each section [start_point, end_point, length]
|
||||
let(len = len(points))
|
||||
[ for(i = [0 : len - 1])
|
||||
let(ends = circle_tangent(points[i], points[(i + 1) % len]))
|
||||
[ends[0], ends[1], norm(ends[0] - ends[1])]
|
||||
];
|
||||
|
||||
// the cross product of 2D vectors is the area of the parallelogram between them. We use the sign of this to decide if the angle is bigger than 180.
|
||||
function rounded_polygon_length(points, tangents) = //! Calculate the length given the point list and the list of tangents computed by ` rounded_polygon_tangents`
|
||||
let(
|
||||
len = len(points),
|
||||
indices = [0 : len - 1],
|
||||
straights = [for(i = indices) norm(tangents[2 * i] - tangents[2 * i + 1])],
|
||||
arcs = [for(i = indices) let(p1 = tangents[2 * i + 1],
|
||||
p2 = tangents[(2 * i + 2) % (2 * len)],
|
||||
corner = points[(i + 1) % len],
|
||||
c = [corner.x, corner.y],
|
||||
v1 = p1 - c,
|
||||
v2 = p2 - c,
|
||||
r = abs(corner.z),
|
||||
a = acos((v1 * v2) / sqr(r))) r ? PI * (cross(v1, v2) <= 0 ? a : 360 - a) * r / 180 : 0]
|
||||
)
|
||||
sumv(concat(straights, arcs));
|
||||
arcs = rounded_polygon_arcs(points, tangents)
|
||||
) sumv( map( concat(tangents, arcs), function(e) e[2] ) );
|
||||
|
||||
module rounded_polygon(points, _tangents = undef) { //! Draw the rounded polygon from the point list, can pass the tangent list to save it being calculated
|
||||
len = len(points);
|
||||
indices = [0 : len - 1];
|
||||
tangents = _tangents ? _tangents : rounded_polygon_tangents(points);
|
||||
tangents = [ for (t = _tangents ? _tangents : rounded_polygon_tangents(points)) each [t.x, t.y] ];
|
||||
|
||||
difference(convexity = points) {
|
||||
union() {
|
||||
@@ -74,6 +84,7 @@ module rounded_polygon(points, _tangents = undef) { //! Draw the rounded polygon
|
||||
hull() {
|
||||
translate([points[i].x, points[i].y])
|
||||
circle(points[i][2]);
|
||||
|
||||
polygon([tangents[(2 * i - 1 + 2 * len) % (2 * len)], tangents[2 * i], [points[i].x, points[i].y]]);
|
||||
}
|
||||
|
||||
@@ -85,7 +96,7 @@ module rounded_polygon(points, _tangents = undef) { //! Draw the rounded polygon
|
||||
translate([points[i].x, points[i].y])
|
||||
circle(-points[i][2]);
|
||||
|
||||
polygon([tangents[(2 * i - 1 + 2 * len) % (2 *len)], tangents[2 * i], [points[i].x, points[i].y]]);
|
||||
polygon([tangents[(2 * i - 1 + 2 * len) % (2 * len)], tangents[2 * i], [points[i].x, points[i].y]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -21,7 +21,6 @@
|
||||
//! Draw a 3D right triangle with rounded edges. Intended to be embedded in other parts. Can be optionally offset by the filleted amount.
|
||||
//
|
||||
include <../utils/core/core.scad>
|
||||
include <..//utils/core/rounded_rectangle.scad>
|
||||
|
||||
module rounded_right_triangle(x, y, z, fillet, center = true, offset = false) { //! Draw a 3D right triangle with rounded edges.
|
||||
fillet = max(fillet, eps);
|
@@ -40,4 +40,4 @@ SCS16LUU = ["SCS16LUU", 9, 19, 25, 50, 85, 38.5, 32.5, 36, 60, 7, M5_cap_sc
|
||||
scs_bearing_blocks = [SCS6UU, SCS8UU, SCS10UU, SCS12UU, SCS16UU];
|
||||
scs_bearing_blocks_long = [SCS8LUU, SCS10LUU, SCS12LUU, SCS16LUU];
|
||||
|
||||
use <scs_bearing_block.scad>
|
||||
use <bearing_block.scad>
|
@@ -18,19 +18,29 @@
|
||||
//
|
||||
|
||||
//
|
||||
//! Models timing belt running over toothed or smooth pulleys and calculates an accurate length.
|
||||
//! Only models 2D paths, so not crossed belt core XY!
|
||||
//! Models timing belt running in a path over toothed or smooth pulleys and calculates an accurate length.
|
||||
//! Only models 2D paths, belt may twist to support crossed belt core XY and other designes where the belt twists!
|
||||
//!
|
||||
//! By default the path is a closed loop. An open loop can be specified by specifying `open=true`, and in that case the start and end points are not connected, leaving the loop open.
|
||||
//!
|
||||
//! To get a 180 degree twist of the loop, you can use the `twist` argument. `Twist` can be a single number, and in that case the belt will twist after
|
||||
//! the position with that number. Alternatively `twist` can be a list of boolean values with a boolean for each position; the belt will then twist after
|
||||
//! the position that have a `true` value in the `twist` list. If the path is specified with pulley/idler types, then you can use `auto_twist=true`; in
|
||||
//! that case the belt will automatically twist so the back of the belt always runs against idlers and the tooth side runs against pullies. If you use
|
||||
//! `open=true` then you might also use `start_twist=true` to let the belt start the part with the back side out.
|
||||
//!
|
||||
//! The path must be specified as a list of positions. Each position should be either a vector with `[x, y, pulley]` or `[x, y, r]`. A pully is a type from
|
||||
//! `pulleys.scad`, and correct radius and angle will automatically be calculated. Alternatively a radius can be specified directly.
|
||||
//!
|
||||
//! To make the back of the belt run against a smooth pulley on the outside of the loop specify a negative pitch radius.
|
||||
//!
|
||||
//! By default the path is a closed loop but a gap length and position can be specified to make open loops.
|
||||
//! To draw the gap its XY position is specified by `gap_pos`. `gap_pos.z` can be used to specify a rotation if the gap is not at the bottom of the loop.
|
||||
//! Alternativley you can just specify smooth pulleys in the path, and it will then happen automatically.
|
||||
//!
|
||||
//! Individual teeth are not drawn, instead they are represented by a lighter colour.
|
||||
//
|
||||
include <../utils/core/core.scad>
|
||||
use <../utils/rounded_polygon.scad>
|
||||
use <../utils/maths.scad>
|
||||
use <pulley.scad>
|
||||
|
||||
function belt_pitch(type) = type[1]; //! Pitch in mm
|
||||
function belt_width(type) = type[2]; //! Width in mm
|
||||
@@ -41,47 +51,102 @@ function belt_pitch_height(type) = type[5] + belt_tooth_height(type); //! Offset
|
||||
function belt_pitch_to_back(type) = belt_thickness(type) - belt_pitch_height(type); //! Offset of the back from the pitch radius
|
||||
//
|
||||
// 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_pos = undef, belt_colour = grey(20), tooth_colour = grey(50)) { //! Draw a belt path given a set of points and pitch radii where the pulleys are. Closed loop unless a gap is specified
|
||||
module belt(type, points, belt_colour = grey(20), tooth_colour = grey(50), open = false, twist = undef, auto_twist = false, start_twist = false) { //! Draw a belt path given a set of points and pitch radii where the pulleys are. Closed loop unless open is specified
|
||||
width = belt_width(type);
|
||||
pitch = belt_pitch(type);
|
||||
thickness = belt_thickness(type);
|
||||
|
||||
info = _belt_points_info(type, points, open, twist, auto_twist, start_twist);
|
||||
dotwist = info[0]; // array of booleans, true if a twist happen after the position
|
||||
twisted = info[1]; // array of booleans, true if the belt is twisted at the position
|
||||
pointsx = info[2]; // array of [x,y,r], r is negative if left-angle (points may have pulleys as third element, but pointsx have radi)
|
||||
tangents = info[3];
|
||||
arcs = info[4];
|
||||
length = ceil(_belt_length(info, open) / pitch) * pitch;
|
||||
|
||||
part = str(type[0],pitch);
|
||||
vitamin(str("belt(", no_point(part), "x", width, ", ", points, arg(gap, 0), arg(gap_pos, undef), "): Belt ", part," x ", width, "mm x ", length, "mm"));
|
||||
vitamin(str("belt(", no_point(part), "x", width, ", ", pointsx, "): Belt ", part," x ", width, "mm x ", length, "mm"));
|
||||
|
||||
len = len(points);
|
||||
|
||||
tangents = rounded_polygon_tangents(points);
|
||||
|
||||
length = ceil((rounded_polygon_length(points, tangents) - (is_list(gap) ? gap.x + gap.y : gap)) / pitch) * pitch;
|
||||
|
||||
module shape() rounded_polygon(points, tangents);
|
||||
|
||||
ph = belt_pitch_height(type);
|
||||
th = belt_tooth_height(type);
|
||||
module gap()
|
||||
if(gap)
|
||||
translate([gap_pos.x, gap_pos.y])
|
||||
rotate(is_undef(gap_pos.z) ? 0 : gap_pos.z)
|
||||
translate([0, ph - thickness / 2])
|
||||
square(is_list(gap) ? [gap.x, gap.y + thickness + eps] : [gap, thickness + eps], center = true);
|
||||
ph = belt_pitch_height(type);
|
||||
module beltp() translate([ph - th, -width / 2]) square([th, width]);
|
||||
module beltb() translate([ph - thickness, -width / 2]) square([thickness - th, width]);
|
||||
|
||||
color(belt_colour)
|
||||
linear_extrude(width, center = true)
|
||||
difference() {
|
||||
offset(-ph + thickness ) shape();
|
||||
offset(-ph + th) shape();
|
||||
gap();
|
||||
}
|
||||
for (i = [0 : len - (open ? 2 : 1)]) {
|
||||
p1 = tangents[i].x;
|
||||
p2 = tangents[i].y;
|
||||
v = p2-p1;
|
||||
a = atan(v.y / v.x) - (v.x < 0 ? 180 : 0); //a2(p2-p1);
|
||||
l = norm(v);
|
||||
translate(p1) rotate([-90, 0, a - 90]) {
|
||||
twist = dotwist[i] ? 180 : 0;
|
||||
mirrored = twisted[i] ? 1 : 0;
|
||||
color(tooth_colour) linear_extrude(l, twist = twist) mirror([mirrored, 0, 0]) beltp();
|
||||
color(belt_colour) linear_extrude(l, twist = twist) mirror([mirrored, 0, 0]) beltb();
|
||||
}
|
||||
}
|
||||
|
||||
color(tooth_colour)
|
||||
linear_extrude(width, center = true)
|
||||
difference() {
|
||||
offset(-ph + th) shape();
|
||||
offset(-ph) shape();
|
||||
gap();
|
||||
}
|
||||
for (i = [(open ? 1 : 0) : len - (open ? 2 : 1)]) {
|
||||
p = pointsx[i];
|
||||
arc = arcs[i];
|
||||
translate([p.x, p.y]) rotate([0, 0, arc[1]]) {
|
||||
mirrored = xor(twisted[i], p[2] < 0) ? 0 : 1;
|
||||
color(tooth_colour) rotate_extrude(angle = arc[0]) translate([abs(p[2]), 0, 0]) mirror([mirrored, 0, 0]) beltp();
|
||||
color(belt_colour) rotate_extrude(angle = arc[0]) translate([abs(p[2]), 0, 0]) mirror([mirrored, 0, 0]) beltb();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function belt_length(points, gap = 0) = rounded_polygon_length(points, rounded_polygon_tangents(points)) - gap; //! Compute belt length given path and optional gap
|
||||
function _belt_points_info(type, points, open, twist, auto_twist, start_twist) = //! Helper function that calculates [twist, istwisted, points, tangents, arcs]
|
||||
let(
|
||||
len = len(points),
|
||||
isleft = function(i) let(
|
||||
p = vec2(points[i]),
|
||||
p0 = vec2(points[(i - 1 + len) % len]),
|
||||
p1 = vec2(points[(i + 1) % len])
|
||||
) cross(p-p0,p1-p) > 0,
|
||||
dotwist = function(i, istwisted) let( in = (i + 1) % len )
|
||||
is_list(twist) ? twist[i] :
|
||||
!is_undef(twist) ? i == twist :
|
||||
open && is_list(points[in][2]) && auto_twist ? !pulley_teeth(points[in][2]) && !xor(isleft(in), istwisted) :
|
||||
false,
|
||||
twisted = [
|
||||
for (
|
||||
i = 0,
|
||||
istwisted = start_twist,
|
||||
twist = dotwist(i, istwisted),
|
||||
nexttwisted = xor(twist, istwisted);
|
||||
i < len;
|
||||
i = i + 1,
|
||||
istwisted = nexttwisted,
|
||||
twist = dotwist(i, istwisted),
|
||||
nexttwisted = xor(twist, istwisted)
|
||||
) [twist, istwisted] ],
|
||||
pointsx = mapi(points, function(i, p) !is_list(p[2]) ? p : [p.x, p.y, let( // if p[2] is not a list it is just r, otherwise it is taken to be a pulley and we calculate r
|
||||
isleft = isleft(i),
|
||||
r = belt_pulley_pr(type, p[2], twisted = !xor(pulley_teeth(p[2]), xor(isleft, twisted[i][1])))
|
||||
) isleft ? -r : r ] ),
|
||||
tangents = rounded_polygon_tangents(pointsx),
|
||||
arcs = rounded_polygon_arcs(pointsx, tangents)
|
||||
) [ [ for (t = twisted) t[0] ], [ for (t = twisted) t[1] ], pointsx, tangents, arcs];
|
||||
|
||||
function belt_pulley_pr(type, pulley, twisted=false) = //! Pitch radius. Default it expects the belt tooth to be against a toothed pulley an the backside to be against a smooth pulley (an idler). If `twisted` is true, the the belt is the other way around.
|
||||
let(
|
||||
thickness = belt_thickness(type),
|
||||
ph = belt_pitch_height(type)
|
||||
) pulley_teeth(pulley)
|
||||
? pulley_pr(pulley) + (twisted ? thickness - ph : 0 )
|
||||
: pulley_ir(pulley) + (twisted ? ph : thickness - ph );
|
||||
|
||||
|
||||
function belt_length(type, points, open = false) = _belt_length(_belt_points_info(type, points, open), open); //! Compute belt length given path
|
||||
|
||||
function _belt_length(info, open) = let(
|
||||
len = len(info[0]),
|
||||
d = open ? 1 : 0,
|
||||
tangents = slice(info[3], 0, len - d) ,
|
||||
arcs = slice(info[4], d, len - d)
|
||||
) sumv( map( concat(tangents, arcs), function(e) e[2] ));
|
||||
|
58
vitamins/box_section.scad
Normal file
@@ -0,0 +1,58 @@
|
||||
//
|
||||
// NopSCADlib Copyright Chris Palmer 2021
|
||||
// nop.head@gmail.com
|
||||
// hydraraptor.blogspot.com
|
||||
//
|
||||
// This file is part of NopSCADlib.
|
||||
//
|
||||
// NopSCADlib is free software: you can redistribute it and/or modify it under the terms of the
|
||||
// GNU General Public License as published by the Free Software Foundation, either version 3 of
|
||||
// the License, or (at your option) any later version.
|
||||
//
|
||||
// NopSCADlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with NopSCADlib.
|
||||
// If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
//
|
||||
//! Box sections.
|
||||
//
|
||||
include <../utils/core/core.scad>
|
||||
include <../utils/tube.scad>
|
||||
|
||||
include <../vitamins/sheets.scad>
|
||||
|
||||
function box_section_material(type) = type[1]; //! Material description
|
||||
function box_section_size(type) = type[2]; //! Size
|
||||
function box_section_thickness(type) = type[3]; //! Wall thickness
|
||||
function box_section_fillet(type) = type[4]; //! Fillet
|
||||
function box_section_colour(type) = type[5]; //! Colour
|
||||
function box_section_colour2(type) = type[6]; //! Colour2, for woven box section
|
||||
function box_section_is_woven(type) = !is_undef(type[6]); //! Box section is woven, eg carbon fiber
|
||||
|
||||
module box_section(type, length, center = true) {
|
||||
vitamin(str("box_section(", type[0], arg(length, 15), "): ", box_section_material(type), ", length ", length, "mm"));
|
||||
|
||||
size = box_section_size(type);
|
||||
thickness = box_section_thickness(type);
|
||||
|
||||
if (box_section_is_woven(type))
|
||||
translate_z(center ? 0 : length / 2) {
|
||||
rotate([0, -90, 90])
|
||||
for (z = [-size.y / 2, size.y / 2 - thickness])
|
||||
translate_z(z)
|
||||
woven_sheet(CF1, thickness, box_section_colour(type), box_section_colour2(type), length, size.x)
|
||||
square([length, size.x], center=true);
|
||||
rotate([0, -90, 0])
|
||||
for (z = [-size.x / 2, size.x / 2 - thickness])
|
||||
translate_z(z)
|
||||
woven_sheet(CF1, thickness, box_section_colour(type), box_section_colour2(type), length, size.y)
|
||||
square([length, size.y], center=true);
|
||||
}
|
||||
else
|
||||
color(box_section_colour(type))
|
||||
rectangular_tube([size.x, size.y, length], center, thickness, box_section_fillet(type));
|
||||
}
|
30
vitamins/box_sections.scad
Normal file
@@ -0,0 +1,30 @@
|
||||
//
|
||||
// NopSCADlib Copyright Chris Palmer 2021
|
||||
// nop.head@gmail.com
|
||||
// hydraraptor.blogspot.com
|
||||
//
|
||||
// This file is part of NopSCADlib.
|
||||
//
|
||||
// NopSCADlib is free software: you can redistribute it and/or modify it under the terms of the
|
||||
// GNU General Public License as published by the Free Software Foundation, either version 3 of
|
||||
// the License, or (at your option) any later version.
|
||||
//
|
||||
// NopSCADlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with NopSCADlib.
|
||||
// If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
//
|
||||
// Box sections
|
||||
//
|
||||
AL12x8x1 = ["AL12x8x1", "Aluminium rectangular box section 12mm x 8mm x 1mm", [12, 8], 1, 0.5, silver, undef];
|
||||
AL20x20x2 = ["AL20x20x2", "Aluminium rectangular box section 20mm x 20mm x 2mm", [20, 20], 2, 0.5, silver, undef];
|
||||
CF10x10x1 = ["CF10x10x1", "Carbon fiber rectangular box section 10mm x 10mm x 1mm", [10, 10], 1, 0.5, grey(35), grey(20)];
|
||||
|
||||
|
||||
box_sections = [AL12x8x1, AL20x20x2, CF10x10x1];
|
||||
|
||||
use <box_section.scad>
|
@@ -62,6 +62,7 @@ function opengrab_depth() = depth; //! Module heig
|
||||
function opengrab_target_thickness() = target; //! Target sheet thickness
|
||||
function opengrab_pcb() = pcb; //! The PCB
|
||||
function opengrab_pcb_z() = depth - pillar - pcb_thickness(pcb); //! PCB offset from the front
|
||||
function opengrab_screw_depth() = 4; //! Max screw depth in pillars
|
||||
|
||||
module opengrab() { //! Draw OpenGrab module
|
||||
vitamin("opengrab(): OpenGrab V3 electro permanent magnet");
|
||||
|
@@ -55,6 +55,9 @@ function pcb_polygon(type) = type[14]; //! Optional outline polygon for odd
|
||||
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
|
||||
function pcb_size(type) = [pcb_length(type), pcb_width(type), pcb_thickness(type)]; //! Length, width and thickness in a vector
|
||||
|
||||
function pcb_component(type, name, index = 0) = //! Return the component specified by name and index
|
||||
[for(component = pcb_components(type)) if(component[3] == name) component][index];
|
||||
|
||||
|
||||
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,
|
||||
|
@@ -31,4 +31,4 @@ KP001 = ["KP001", 12, 19, 71, 56, 16, 7.0, 6, 38, 14.5, 4, 32, M6_clearanc
|
||||
|
||||
kp_pillow_blocks = [KP08_15, KP08_18, KP000, KP001];
|
||||
|
||||
use <kp_pillow_block.scad>
|
||||
use <pillow_block.scad>
|
@@ -44,6 +44,7 @@ function psu_name(type) = type[1]; //! The part name
|
||||
function psu_length(type) = type[2]; //! Length
|
||||
function psu_width(type) = type[3]; //! Width
|
||||
function psu_height(type) = type[4]; //! Height
|
||||
function psu_size(type) = [psu_length(type), psu_width(type), psu_height(type)]; //! Size
|
||||
function psu_screw(type) = type[5]; //! Screw type
|
||||
function psu_screw_hole_radius(type) = type[6]; //! Clearance hole for screw, bigger than normal on ATX
|
||||
function atx_psu(type) = type[7]; //! True if an ATX style PSU
|
||||
|
@@ -42,7 +42,7 @@ function pulley_screw(type) = type[13]; //! Grub screw type
|
||||
function pulley_screws(type) = type[14]; //! Number of grub screws
|
||||
|
||||
function pulley_ir(type) = pulley_od(type) / 2 - (pulley_teeth(type) ? belt_tooth_height(pulley_belt(type)) : 0); //! Inside radius of the teeth
|
||||
function pulley_pr(type) = let(belt = pulley_belt(type)) //! Pitch radius
|
||||
function pulley_pr(type, belt = undef) = let(belt = is_undef(belt) ? pulley_belt(type) : belt) //! Pitch radius, `belt` only needed for non-standard belt over smooth pulleys
|
||||
pulley_teeth(type) ? pulley_teeth(type) * belt_pitch(belt) / 2 / PI
|
||||
: pulley_ir(type) + belt_thickness(belt) - belt_pitch_height(belt);
|
||||
|
||||
@@ -53,7 +53,7 @@ function pulley_extent(type) = max(pulley_flange_dia(type), pulley_hub_dia(type)
|
||||
T_angle = 40;
|
||||
GT_r = 0.555;
|
||||
|
||||
module pulley(type, colour = silver) { //! Draw a pulley
|
||||
module pulley(type, colour = silver) { //! Draw a pulley, any children are placed above.
|
||||
teeth = pulley_teeth(type);
|
||||
od = pulley_od(type);
|
||||
|
||||
@@ -138,6 +138,10 @@ module pulley(type, colour = silver) { //! Draw a pulley
|
||||
else
|
||||
core();
|
||||
}
|
||||
|
||||
if($children)
|
||||
translate_z(pulley_height(type))
|
||||
children();
|
||||
}
|
||||
|
||||
module pulley_assembly(type, colour = silver) { //! Draw a pulley with its grub screws in place
|
||||
|
@@ -37,18 +37,19 @@ function rail_groove_width(type)=type[11]; //! Groove width
|
||||
|
||||
function rail_screw_height(type, screw) = rail_height(type) - rail_bore_depth(type) + screw_head_depth(screw, rail_hole(type)); //! Position screw taking into account countersink into counterbored hole
|
||||
|
||||
function carriage_length(type) = type[0]; //! Overall length
|
||||
function carriage_block_length(type) = type[1]; //! Length of the metal part
|
||||
function carriage_width(type) = type[2]; //! Width of carriage
|
||||
function carriage_height(type) = type[3]; //! Height of carriage
|
||||
function carriage_size(type) = [ type[0], type[2], type[3] ]; //! Size of carriage
|
||||
function carriage_clearance(type) = type[4]; //! Gap under the carriage
|
||||
function carriage_pitch_x(type) = type[5]; //! Screw hole x pitch
|
||||
function carriage_pitch_y(type) = type[6]; //! Screw hole y pitch
|
||||
function carriage_screw(type) = type[7]; //! Carriage screw type
|
||||
function carriage_rail(type) = type[8]; //! Rail type
|
||||
function carriage_length(type) = type[1]; //! Overall length
|
||||
function carriage_block_length(type) = type[2]; //! Length of the metal part
|
||||
function carriage_width(type) = type[3]; //! Width of carriage
|
||||
function carriage_height(type) = type[4]; //! Height of carriage
|
||||
function carriage_clearance(type) = type[5]; //! Gap under the carriage
|
||||
function carriage_pitch_x(type) = type[6]; //! Screw hole x pitch
|
||||
function carriage_pitch_y(type) = type[7]; //! Screw hole y pitch
|
||||
function carriage_screw(type) = type[8]; //! Carriage screw type
|
||||
function carriage_rail(type) = type[9]; //! Rail type
|
||||
|
||||
function carriage_screw_depth(type) = 2 * screw_radius(carriage_screw(type)); //! Carriage thread depth
|
||||
function carriage_travel(type, rail_length) = rail_length - carriage_length(type); //! How far the carriage can travel on a given length rail
|
||||
function carriage_size(type) = [ carriage_length(type), carriage_width(type), carriage_height(type) ]; //! Size of carriage
|
||||
|
||||
function rail_holes(type, length) = //! Number of holes in a rail given its `length`
|
||||
floor((length - 2 * rail_end(type)) / rail_pitch(type)) + 1;
|
||||
@@ -74,6 +75,8 @@ module carriage_hole_positions(type) { //! Position children over screw holes
|
||||
}
|
||||
|
||||
module carriage(type, end_colour = grey(20), wiper_colour = grey(20)) { //! Draw the specified carriage
|
||||
vitamin(str("carriage(", type[0], "_carriage): Linear rail carriage ", type[0]));
|
||||
|
||||
total_l = carriage_length(type);
|
||||
block_l = carriage_block_length(type);
|
||||
block_w = carriage_width(type);
|
||||
@@ -142,6 +145,7 @@ module rail(type, length, colour = grey(90), use_polycircles = false) { //! Draw
|
||||
height = rail_height(type);
|
||||
|
||||
vitamin(str("rail(", type[0], ", ", length, "): Linear rail ", type[0], " x ", length, "mm"));
|
||||
assert(rail_end(type) < (rail_pitch(type) - rail_bore(type)) / 2, type[0]);
|
||||
|
||||
color(colour) {
|
||||
rbr = rail_bore(type) / 2;
|
||||
|
@@ -20,26 +20,29 @@
|
||||
//
|
||||
// Rails
|
||||
//
|
||||
// Wr Hr E P D d h go gw
|
||||
// Wr Hr Emin P D d h go gw
|
||||
MGN5 = [ "MGN5", 5, 3.6, 5, 15, 3.6, 2.4, 0.8, M2_cs_cap_screw, M2_cs_cap_screw, 1, 1 ]; // Screw holes too small for M2 heads
|
||||
MGN7 = [ "MGN7", 7, 5, 5, 15, 4.3, 2.4, 2.6, M2_cap_screw, M2_cs_cap_screw, 1.5, 1.5 ];
|
||||
MGN9 = [ "MGN9", 9, 6, 5, 20, 6.0, 3.5, 3.5, M3_cap_screw, M3_cs_cap_screw, 1.5, 1.5 ];
|
||||
MGN12 =[ "MGN12", 12, 8, 10, 25, 6.0, 3.5, 4.5, M3_cap_screw, M3_cs_cap_screw, 2.25, 2.75];
|
||||
MGN12 =[ "MGN12", 12, 8, 7.5, 25, 6.0, 3.5, 4.5, M3_cap_screw, M3_cs_cap_screw, 2.25, 2.75];
|
||||
MGN15 =[ "MGN15", 15, 10, 10, 40, 6.0, 3.5, 5.0, M3_cap_screw, M3_cs_cap_screw, 2.5, 2.75 ];
|
||||
SSR15= [ "SSR15", 15, 12.5, 10, 60, 7.5, 4.5, 5.3, M4_cap_screw, M4_cs_cap_screw, 2.5, 2.75 ];
|
||||
//
|
||||
// Carriages
|
||||
//
|
||||
// L L1 W H H1 C B
|
||||
MGN5_carriage = [ 16, 9.6, 12, 6, 1.5, 0, 8, M2_cap_screw, MGN5 ];
|
||||
MGN7C_carriage = [ 23, 14.3, 17, 8, 1.5, 8, 12, M2_cap_screw, MGN7 ];
|
||||
MGN9C_carriage = [ 29.7, 20.8, 20, 10, 2, 10, 15, M3_cap_screw, MGN9 ];
|
||||
MGN12C_carriage = [ 34.7, 21.7, 27, 13, 3, 15, 20, M3_cap_screw, MGN12 ];
|
||||
MGN12H_carriage = [ 45.4, 32.4, 27, 13, 3, 20, 20, M3_cap_screw, MGN12 ];
|
||||
MGN15C_carriage = [ 43.3, 27.7, 32, 16, 4, 20, 25, M3_cap_screw, MGN15 ];
|
||||
SSR15_carriage = [ 40.3, 23.3, 34, 24, 4.5, 0, 26, M4_cap_screw, SSR15 ];
|
||||
// L L1 W H H1 C B
|
||||
MGN5C_carriage = ["MGN5C", 16, 9.6, 12, 6, 1.5, 0, 8, M2_cap_screw, MGN5 ];
|
||||
MGN7C_carriage = ["MGN7C", 23, 14.3, 17, 8, 1.5, 8, 12, M2_cap_screw, MGN7 ];
|
||||
MGN7H_carriage = ["MGN7H", 30.8, 21.8, 17, 8, 1.5,13, 12, M2_cap_screw, MGN7 ];
|
||||
MGN9C_carriage = ["MGN9C", 29.7, 20.8, 20, 10, 2, 10, 15, M3_cap_screw, MGN9 ];
|
||||
MGN9H_carriage = ["MGN9H", 39.9, 29.9, 20, 10, 2, 16, 15, M3_cap_screw, MGN9 ];
|
||||
MGN12C_carriage = ["MGN12C", 34.7, 21.7, 27, 13, 3, 15, 20, M3_cap_screw, MGN12 ];
|
||||
MGN12H_carriage = ["MGN12H", 45.4, 32.4, 27, 13, 3, 20, 20, M3_cap_screw, MGN12 ];
|
||||
MGN15C_carriage = ["MGN15C", 43.3, 27.7, 32, 16, 4, 20, 25, M3_cap_screw, MGN15 ];
|
||||
SSR15_carriage = ["SSR15", 40.3, 23.3, 34, 24, 4.5, 0, 26, M4_cap_screw, SSR15 ];
|
||||
|
||||
rails = [MGN5, MGN7, MGN9, MGN12, MGN15, SSR15];
|
||||
|
||||
carriages = [MGN5_carriage, MGN7C_carriage, MGN9C_carriage, MGN12C_carriage, MGN12H_carriage, MGN15C_carriage, SSR15_carriage];
|
||||
carriages = [MGN5C_carriage, MGN7C_carriage, MGN7H_carriage, MGN9C_carriage, MGN9H_carriage, MGN12C_carriage, MGN12H_carriage, MGN12H_carriage, MGN15C_carriage, SSR15_carriage];
|
||||
|
||||
use <rail.scad>
|
||||
|
@@ -284,10 +284,10 @@ function screw_polysink_r(type, z) = //! Countersink hole profile corrected for
|
||||
)
|
||||
limit(head_rad + head_t - z + (sqrt(2) - 1) * layer_height / 2, screw_clearance_radius(type), head_rad);
|
||||
|
||||
module screw_polysink(type, h = 100, alt = false) { //! A countersink hole made from stacked polyholes for printed parts
|
||||
module screw_polysink(type, h = 100, alt = false, sink = 0) { //! A countersink hole made from stacked polyholes for printed parts, default is flush, `sink` can be used to recess the head
|
||||
head_depth = screw_head_depth(type);
|
||||
assert(head_depth, "Not a countersunk screw");
|
||||
layers = ceil(head_depth / layer_height);
|
||||
layers = ceil((head_depth + sink) / layer_height);
|
||||
rmin = screw_clearance_radius(type);
|
||||
sides = sides(rmin);
|
||||
lh = layer_height + eps;
|
||||
@@ -295,7 +295,7 @@ module screw_polysink(type, h = 100, alt = false) { //! A countersink hole made
|
||||
for(side = [0, 1]) mirror([0, 0, side]) {
|
||||
for(i = [0 : layers - 1])
|
||||
translate_z(i * layer_height) {
|
||||
r = screw_polysink_r(type, i * layer_height + layer_height / 2);
|
||||
r = screw_polysink_r(type, i * layer_height + layer_height / 2 - sink);
|
||||
if(alt)
|
||||
rotate(i % 2 == layers % 2 ? 180 / sides : 0)
|
||||
poly_cylinder(r = r, h = lh, center = false, sides = sides);
|
||||
|
@@ -79,6 +79,7 @@ M2_cs_cap_screw = ["M2_cs_cap","M2 cs cap", hs_cs_cap,2, 3.8, 0, 0.65,1.3
|
||||
M3_cs_cap_screw = ["M3_cs_cap","M3 cs cap", hs_cs_cap,3, 6.0, 0, 1.05,2.0, 18, M3_washer, M3_nut, M3_tap_radius, M3_clearance_radius];
|
||||
M4_cs_cap_screw = ["M4_cs_cap","M4 cs cap", hs_cs_cap,4, 8.0, 0, 1.49,2.5, 20, M4_washer, M4_nut, M4_tap_radius, M4_clearance_radius];
|
||||
M5_cs_cap_screw = ["M5_cs_cap","M5 cs cap", hs_cs_cap,5,10.0, 0, 3.00,3.0, 22, M5_washer, M5_nut, M5_tap_radius, M5_clearance_radius];
|
||||
M6_cs_cap_screw = ["M6_cs_cap","M6 cs cap", hs_cs_cap,6,12.0, 0, 3.00,4.0, 24, M6_washer, M6_nut, M6_tap_radius, M6_clearance_radius];
|
||||
|
||||
M2_dome_screw = ["M2_dome", "M2 dome", hs_dome, 2, 3.5, 1.3, 0.6, 1.3, 16, M2_washer, M2_nut, M2_tap_radius, M2_clearance_radius];
|
||||
M3_dome_screw = ["M3_dome", "M3 dome", hs_dome, 3, 5.7, 1.65, 1.04,2.0, 18, M3_washer, M3_nut, M3_tap_radius, M3_clearance_radius];
|
||||
@@ -107,15 +108,16 @@ No2_screw = ["No2", "No2 pan wood", hs_pan, 2.2, 4.2, 1.7, 0, 0
|
||||
No4_screw = ["No4", "No4 pan wood", hs_pan, 3.0, 5.5, 2.0, 0, 0, 0 ,M3p5_washer, false, No4_pilot_radius, No4_clearance_radius];
|
||||
No6_screw = ["No6", "No6 pan wood", hs_pan, 3.5, 6.7, 2.2, 0, 0, 0 , M4_washer, false, No6_pilot_radius, No6_clearance_radius];
|
||||
No6_cs_screw = ["No6_cs", "No6 cs wood", hs_cs, 3.5, 7.0, 0, 0, 0, 0, M4_washer, false, No6_pilot_radius, No6_clearance_radius];
|
||||
No8_screw = ["No8", "No8 pan wood", hs_pan, 4.2, 8.2, 3.05, 0, 0, 0 , M5_washer, false, No8_pilot_radius, No8_clearance_radius];
|
||||
|
||||
screw_lists = [
|
||||
[ M2_cap_screw, M2p5_cap_screw, M3_cap_screw, M4_cap_screw, M5_cap_screw, M6_cap_screw, M8_cap_screw],
|
||||
[ M2_cap_screw, M2p5_cap_screw, M3_cap_screw, M4_cap_screw, M5_cap_screw, M6_cap_screw, M8_cap_screw],
|
||||
[ 0, 0, M3_low_cap_screw],
|
||||
[ M2_cs_cap_screw, 0, M3_cs_cap_screw, M4_cs_cap_screw, M5_cs_cap_screw],
|
||||
[ M2_cs_cap_screw, 0, M3_cs_cap_screw, M4_cs_cap_screw, M5_cs_cap_screw, M6_cs_cap_screw],
|
||||
[ M2_dome_screw, 0, M3_dome_screw, M4_dome_screw, M5_dome_screw],
|
||||
[ 0, 0, M3_hex_screw, M4_hex_screw, M5_hex_screw, M6_hex_screw, M8_hex_screw],
|
||||
[ 0, M2p5_pan_screw, M3_pan_screw, M4_pan_screw, M5_pan_screw, M6_pan_screw, No632_pan_screw],
|
||||
[ No2_screw, 0, No4_screw, No6_screw, No6_cs_screw],
|
||||
[ 0, 0, M3_hex_screw, M4_hex_screw, M5_hex_screw, M6_hex_screw, M8_hex_screw],
|
||||
[ 0, M2p5_pan_screw, M3_pan_screw, M4_pan_screw, M5_pan_screw, M6_pan_screw, No632_pan_screw],
|
||||
[ No2_screw, 0, No4_screw, No6_screw, No8_screw, No6_cs_screw],
|
||||
[ 0, 0, M3_grub_screw, M4_grub_screw]
|
||||
];
|
||||
|
||||
|
@@ -45,11 +45,14 @@ Foam20 = [ "Foam20", "Foam sponge", 20,[0.3, 0.3, 0.3, 1 ],
|
||||
AL6 = [ "AL6", "Aluminium tooling plate", 6, [0.9, 0.9, 0.9, 1 ], false];
|
||||
AL8 = [ "AL8", "Aluminium tooling plate", 8, [0.9, 0.9, 0.9, 1 ], false];
|
||||
Steel06 = [ "Steel06", "Sheet mild steel", 0.6,"silver" , false];
|
||||
CF1 = [ "CF1", "Sheet carbon fiber", 1, grey(30), false, 2, 2, grey(25)];
|
||||
CF2 = [ "CF2", "Sheet carbon fiber", 2, grey(30), false, 2, 2, grey(25)];
|
||||
CF3 = [ "CF3", "Sheet carbon fiber", 3, grey(30), false, 2, 2, grey(25)];
|
||||
Spring05 = [ "Spring05", "Bi-metal saw blade", 0.5,"#FBC300", false];
|
||||
Silicone3 = [ "Silicone3", "Sheet silicone", 3, [0.9, 0.9, 0.9, 0.95 ], false];
|
||||
CF1 = [ "CF1", "Sheet carbon fiber", 1, grey(35), false, 2, 2, grey(20)];
|
||||
CF2 = [ "CF2", "Sheet carbon fiber", 2, grey(35), false, 2, 2, grey(20)];
|
||||
CF3 = [ "CF3", "Sheet carbon fiber", 3, grey(35), false, 2, 2, grey(20)];
|
||||
|
||||
|
||||
sheets = [CF1, CF2, CF3, MDF6, MDF10, MDF12, MDF19, PMMA2, PMMA3, PMMA6, PMMA8, PMMA10, glass2, DiBond, DiBond6, Cardboard, FoilTape, Foam20, AL6, AL8, Steel06];
|
||||
sheets = [CF1, CF2, CF3, MDF6, MDF10, MDF12, MDF19, PMMA2, PMMA3, PMMA6, PMMA8, PMMA10,
|
||||
glass2, DiBond, DiBond6, Cardboard, FoilTape, AL6, AL8, Steel06, Spring05, Silicone3, Foam20];
|
||||
|
||||
use <sheet.scad>
|
||||
|