1
0
mirror of https://github.com/nophead/NopSCADlib.git synced 2025-09-13 16:32:36 +02:00

Compare commits

..

33 Commits

Author SHA1 Message Date
Chris Palmer
0a84bf0927 plateup.py now saves the used files to speed up processing when a part hasn't changed.
Added times to plateup.py.
2021-02-11 09:10:15 +00:00
Chris Palmer
da825b17ab Added colorama.init() to plateup.py to handle new coloured changed messages. 2021-02-10 10:22:38 +00:00
Chris Palmer
ca153c971d Fixed platters and panels not working in the GUI, a regression.
set_config() now puts $cwd in target.scad.
use_stl() and use_dxf() included again instead of used.
2021-02-10 10:17:03 +00:00
Chris Palmer
60350eb228 Updated gallery.py for new page break format. 2021-02-09 23:44:03 +00:00
Chris Palmer
4f9729cf86 Now shows what changed to trigger an openscad invocation in cyan. 2021-02-09 23:32:53 +00:00
Chris Palmer
26f1338ca2 Fixed removal of old deps 2021-02-09 14:34:27 +00:00
Chris Palmer
fc44b43638 Temporary files used during make_all and tests now in tmp dir. 2021-02-09 09:52:26 +00:00
Chris Palmer
182f39876a Moved deps directories to separate stl deps from views deps. 2021-02-09 09:18:30 +00:00
Chris Palmer
055e90cbb3 /stls/ and /dxfs/ excluded from deps to prevent circular dependencies. 2021-02-08 22:44:21 +00:00
Chris Palmer
832380f893 Fixed set_config always writing to target.scad. 2021-02-08 20:31:10 +00:00
Chris Palmer
929d082b25 openscad.py now quits if there are errors or warnings in the log.
This is because the exit status is not always set correctly.
2021-02-08 16:03:59 +00:00
Chris Palmer
57212b5701 set_config.py now defines $target. 2021-02-08 15:00:44 +00:00
Chris Palmer
1c3f136657 Fixed $cwd and $target not defined during silent run. 2021-02-08 15:00:01 +00:00
Chris Palmer
cfd2fd32a1 Now checks openscad.echo for warnings when used instead of openscad.log. 2021-02-08 14:58:50 +00:00
Chris Palmer
f573a91a09 Removed redundant rounded_rectangle center = false. 2021-02-08 09:41:07 +00:00
Chris Palmer
d75aff2ccd rounded_retangle() centre now defaults to false. 2021-02-08 09:24:00 +00:00
Chris Palmer
491d85156c Merge branch 'martinbudden-rounded_cubes' 2021-02-08 08:29:50 +00:00
Chris Palmer
c89ce6843f Updated images and readme. 2021-02-08 08:29:08 +00:00
Chris Palmer
1915dae034 Merge branch 'rounded_cubes' of https://github.com/martinbudden/NopSCADlib into martinbudden-rounded_cubes 2021-02-07 22:17:22 +00:00
Chris Palmer
05e8055ce2 Merge branch 'martinbudden-btt_skr_e3_turbo' 2021-02-07 22:01:41 +00:00
Chris Palmer
21822b9abb Updated pictures and readme. 2021-02-07 22:01:26 +00:00
Chris Palmer
d83d4b89bf Merge branch 'btt_skr_e3_turbo' of https://github.com/martinbudden/NopSCADlib into martinbudden-btt_skr_e3_turbo 2021-02-07 21:48:16 +00:00
Chris Palmer
613152f589 Merge branch 'martinbudden-bl30x10' 2021-02-07 21:46:28 +00:00
Chris Palmer
d90c00d140 Updated images and readme. 2021-02-07 21:46:15 +00:00
Chris Palmer
b52ca9589a Merge branch 'bl30x10' of https://github.com/martinbudden/NopSCADlib into martinbudden-bl30x10 2021-02-07 21:25:53 +00:00
Martin Budden
0d024060fc Added BTT_SKR_E3_TURBO. 2021-02-07 07:51:10 +00:00
Martin Budden
c4fe1d1098 Added assertion to check r value. Used extrud_if. 2021-02-07 07:29:02 +00:00
Chris Palmer
a3ced6de45 Merge branch 'martinbudden-mgn9_correction' 2021-02-06 15:29:51 +00:00
Chris Palmer
1cdfe3267c Merge branch 'mgn9_correction' of https://github.com/martinbudden/NopSCADlib into martinbudden-mgn9_correction 2021-02-06 15:28:49 +00:00
Martin Budden
812fbc106c Updated screw hole position. 2021-02-04 19:59:28 +00:00
Martin Budden
dd38fa6e5d Added 30x10 square radial fan. 2021-02-04 18:26:44 +00:00
Martin Budden
5cdcd4ad37 Corrected MGN9 rail end value. 2021-02-03 11:24:44 +00:00
Martin Budden
22b7aa956c Renamed rounded_rectangle_* to rounded_cube_*. 2021-02-02 17:32:44 +00:00
46 changed files with 381 additions and 156 deletions

View File

@@ -1,40 +1,30 @@
# A gallery of projects made with NopSCADlib # A gallery of projects made with NopSCADlib
<a name="TOP"></a>
## ArduinoThermostat ## ArduinoThermostat
Arduino thermostat to control a beer fridge to use it as an environmental chamber. Arduino thermostat to control a beer fridge to use it as an environmental chamber.
![](ArduinoThermostat.png) ![](ArduinoThermostat.png)
<a name="TOP"></a>
## EnviroPlus ## EnviroPlus
Environmental monitor using Enviro+ sensor board and a Raspberry Pi Zero. Environmental monitor using Enviro+ sensor board and a Raspberry Pi Zero.
![](EnviroPlus.png) ![](EnviroPlus.png)
<a name="TOP"></a>
## FilamentDryBox ## FilamentDryBox
A small fan oven with a spool holder to keep the filament warm and dry. A small fan oven with a spool holder to keep the filament warm and dry.
![](FilamentDryBox.png) ![](FilamentDryBox.png)
<a name="TOP"></a>
## HydraBot ## HydraBot
Current state of HydraRaptor after being modified for laser engraving. Current state of HydraRaptor after being modified for laser engraving.
![](HydraBot.png) ![](HydraBot.png)
<a name="TOP"></a>
## IOT 50V PSU ## IOT 50V PSU
WiFi controllable PSU WiFi controllable PSU
![](IOT_50V_PSU.png) ![](IOT_50V_PSU.png)
<a name="TOP"></a>
## Lab ATX PSU ## Lab ATX PSU
Bench power supply built around an ATX PSU. Bench power supply built around an ATX PSU.
@@ -47,15 +37,11 @@ Bench power supply built around an ATX PSU.
<a name="TOP"></a>
## Laser Load ## Laser Load
15kV dummy load for testing CO2 laser PSUs 15kV dummy load for testing CO2 laser PSUs
![](Laser_load.png) ![](Laser_load.png)
<a name="TOP"></a>
## MainsBreakOutBox ## MainsBreakOutBox
13A socket break out box with 4mm jacks to measure voltage and / or load current and earth leakage current. 13A socket break out box with 4mm jacks to measure voltage and / or load current and earth leakage current.
@@ -72,8 +58,6 @@ Earth leakage can be measured Canadian CSA style by disconnected the neutral lin
![](MainsBreakOutBox.png) ![](MainsBreakOutBox.png)
<a name="TOP"></a>
## Mains Box ## Mains Box
Mains isolated and variable supply with metering. Mains isolated and variable supply with metering.
@@ -81,15 +65,11 @@ Mains isolated and variable supply with metering.
<a name="TOP"></a>
## SunBot ## SunBot
A solar tracker to keep a solar panel pointing at the sun. A solar tracker to keep a solar panel pointing at the sun.
![](SunBot.png) ![](SunBot.png)
<a name="TOP"></a>
## Turntable ## Turntable
WiFi enabled remote control turntable for photography WiFi enabled remote control turntable for photography
@@ -97,8 +77,6 @@ WiFi enabled remote control turntable for photography
Was actually made from DiBond but shown made with carbon fibre here. Was actually made from DiBond but shown made with carbon fibre here.
<a name="TOP"></a>
## Variac ## Variac
Motorised variac with WiFi control, see [hydraraptor.blogspot.com/2018/04/esp8266-spi-spy](https://hydraraptor.blogspot.com/2018/04/esp8266-spi-spy.html) Motorised variac with WiFi control, see [hydraraptor.blogspot.com/2018/04/esp8266-spi-spy](https://hydraraptor.blogspot.com/2018/04/esp8266-spi-spy.html)
@@ -106,4 +84,3 @@ Motorised variac with WiFi control, see [hydraraptor.blogspot.com/2018/04/esp826

Binary file not shown.

Before

Width:  |  Height:  |  Size: 875 KiB

After

Width:  |  Height:  |  Size: 882 KiB

View File

@@ -227,7 +227,7 @@ module box_bezel(type, bottom) { //! Generates top and bottom bezel STLs
translate_z(-box_profile_overlap(type)) difference() { translate_z(-box_profile_overlap(type)) difference() {
tw = w + 2 * outset; tw = w + 2 * outset;
td = d + 2 * outset; td = d + 2 * outset;
rounded_rectangle([tw, td, feet ? foot_height : height], box_corner_rad(type), false); rounded_rectangle([tw, td, feet ? foot_height : height], box_corner_rad(type));
// //
// Remove edges between the feet // Remove edges between the feet
// //
@@ -264,7 +264,7 @@ module box_bezel(type, bottom) { //! Generates top and bottom bezel STLs
// recess for top / bottom panel // recess for top / bottom panel
// //
translate_z(cgap) translate_z(cgap)
rounded_rectangle([w + bezel_clearance, d + bezel_clearance, height], inner_r + bezel_clearance / 2, false); rounded_rectangle([w + bezel_clearance, d + bezel_clearance, height], inner_r + bezel_clearance / 2);
// //
// leave plastic over the corner profiles // leave plastic over the corner profiles
// //

View File

@@ -116,10 +116,10 @@ module MT3608_carrier_stl() { //! Generate the STL for an MT3608 carrier, two re
difference() { difference() {
hull() { hull() {
translate([offset, 0, height - eps / 2]) translate([offset, 0, height - eps / 2])
rounded_rectangle([width, pcb_width - 2, eps], 1); rounded_rectangle([width, pcb_width - 2, eps], 1, true);
translate_z(eps / 2) translate_z(eps / 2)
rounded_rectangle([width, pcb_width - 2, eps], 1); rounded_rectangle([width, pcb_width - 2, eps], 1, true);
} }
for(side = [-1, 1]) for(side = [-1, 1])
hull() { hull() {

View File

@@ -44,7 +44,7 @@ module door_latch_stl() { //! Generates the STL for the printed part
difference() { difference() {
union() { union() {
hull() { hull() {
rounded_rectangle([length, width, thickness - tan(30) * (width - ridge) / 2], rad, center = false); rounded_rectangle([length, width, thickness - tan(30) * (width - ridge) / 2], rad);
translate_z(thickness / 2) translate_z(thickness / 2)
cube([length, ridge, thickness], center = true); cube([length, ridge, thickness], center = true);

View File

@@ -182,7 +182,7 @@ module pbox(type) { //! Generate the STL for the main case
if(ledge_h) if(ledge_h)
translate_z(top_thickness + height - ledge_h) translate_z(top_thickness + height - ledge_h)
difference() { difference() {
rounded_rectangle([pbox_width(type) + 2 * outset, pbox_depth(type) + 2 * outset, ledge_h], 1, center = false); rounded_rectangle([pbox_width(type) + 2 * outset, pbox_depth(type) + 2 * outset, ledge_h], 1);
hull() { hull() {
linear_extrude(ledge_h + eps) linear_extrude(ledge_h + eps)

View File

@@ -110,7 +110,7 @@ module psu_shroud(type, cable_d, name, cables = 1) { //! Generate the STL file f
stl(str("psu_shroud_", name)) { stl(str("psu_shroud_", name)) {
// base and sides // base and sides
translate([centre_x, -centre_y]) { translate([centre_x, -centre_y]) {
rounded_rectangle([depth - eps, width - eps, top], rad, center = false); rounded_rectangle([depth - eps, width - eps, top], rad);
linear_extrude(height) linear_extrude(height)
difference() { difference() {

View File

@@ -71,7 +71,7 @@ module ssr_shroud(type, cable_d, name) { //! Generate the STL file for a spec
stl(str("ssr_shroud_", name)) { stl(str("ssr_shroud_", name)) {
// base and sides // base and sides
translate([center_x, 0]) { translate([center_x, 0]) {
rounded_rectangle([depth - eps, width - eps, top], rad, center = false); rounded_rectangle([depth - eps, width - eps, top], rad);
linear_extrude(height) difference() { linear_extrude(height) difference() {
round(or = wall / 2 - eps, ir = 0) difference() { round(or = wall / 2 - eps, ir = 0) difference() {

View File

@@ -288,6 +288,8 @@ Models of radial blowers.
| `blower_screw_holes(type)` | List of XY coordinates of the screw holes | | `blower_screw_holes(type)` | List of XY coordinates of the screw holes |
| `blower_top(type)` | Thickness of the top | | `blower_top(type)` | Thickness of the top |
| `blower_wall(type)` | Side wall thickness | | `blower_wall(type)` | Side wall thickness |
| `blower_wall_left(type)` | Left side wall thickness |
| `blower_wall_right(type)` | Right wall thickness (for square fans) |
| `blower_width(type)` | Width of enclosing rectangle | | `blower_width(type)` | Width of enclosing rectangle |
### Functions ### Functions
@@ -311,10 +313,12 @@ Models of radial blowers.
| 1 | `blower(PE4020)` | Blower Pengda Technology 4020 | | 1 | `blower(PE4020)` | Blower Pengda Technology 4020 |
| 1 | `blower(RB5015)` | Blower Runda RB5015 | | 1 | `blower(RB5015)` | Blower Runda RB5015 |
| 4 | `screw(M2_cap_screw, 8)` | Screw M2 cap x 8mm | | 4 | `screw(M2_cap_screw, 8)` | Screw M2 cap x 8mm |
| 2 | `screw(M2_cap_screw, 10)` | Screw M2 cap x 10mm |
| 3 | `screw(M3_cap_screw, 20)` | Screw M3 cap x 20mm | | 3 | `screw(M3_cap_screw, 20)` | Screw M3 cap x 20mm |
| 2 | `screw(M4_cap_screw, 25)` | Screw M4 cap x 25mm | | 2 | `screw(M4_cap_screw, 25)` | Screw M4 cap x 25mm |
| 1 | `blower(BL30x10)` | Square radial fan 3010 |
| 1 | `blower(BL40x10)` | Square radial fan 4010 | | 1 | `blower(BL40x10)` | Square radial fan 4010 |
| 4 | `washer(M2_washer)` | Washer M2 x 5mm x 0.3mm | | 6 | `washer(M2_washer)` | Washer M2 x 5mm x 0.3mm |
| 3 | `washer(M3_washer)` | Washer M3 x 7mm x 0.5mm | | 3 | `washer(M3_washer)` | Washer M3 x 7mm x 0.5mm |
| 2 | `washer(M4_washer)` | Washer M4 x 9mm x 0.8mm | | 2 | `washer(M4_washer)` | Washer M4 x 9mm x 0.8mm |
@@ -2311,6 +2315,7 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
| ---:|:--- |:---| | ---:|:--- |:---|
| 1 | `pcb(ArduinoLeonardo)` | Arduino Leonardo | | 1 | `pcb(ArduinoLeonardo)` | Arduino Leonardo |
| 1 | `pcb(ArduinoUno3)` | Arduino Uno R3 | | 1 | `pcb(ArduinoUno3)` | Arduino Uno R3 |
| 1 | `pcb(BTT_SKR_E3_TURBO)` | BigTreeTech SKR E3 Turbo |
| 1 | `pcb(BTT_SKR_MINI_E3_V2_0)` | BigTreeTech SKR Mini E3 v2.0 | | 1 | `pcb(BTT_SKR_MINI_E3_V2_0)` | BigTreeTech SKR Mini E3 v2.0 |
| 1 | `pcb(BTT_SKR_V1_4_TURBO)` | BigTreeTech SKR v1.4 Turbo | | 1 | `pcb(BTT_SKR_V1_4_TURBO)` | BigTreeTech SKR v1.4 Turbo |
| 1 | | Cat 5 patch cable 300mm | | 1 | | Cat 5 patch cable 300mm |
@@ -2321,7 +2326,7 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
| 1 | `pcb(ESP-01)` | ESP-01 | | 1 | `pcb(ESP-01)` | ESP-01 |
| 1 | `pcb(EnviroPlus)` | Enviro+ | | 1 | `pcb(EnviroPlus)` | Enviro+ |
| 1 | `pcb(ExtruderPCB)` | Extruder connection PCB | | 1 | `pcb(ExtruderPCB)` | Extruder connection PCB |
| 1 | `pcb(Keyes5p1)` | Keyes5.1 Arduino Uno expansion board | | 1 | `pcb(Keyes5p1)` | Keyes5.1 Arduino Uno expansion board - not shown |
| 1 | `pcb(MP1584EN)` | MP1584EN 3A buck converter | | 1 | `pcb(MP1584EN)` | MP1584EN 3A buck converter |
| 1 | `pcb(MT3608)` | MT3608 boost converter module | | 1 | `pcb(MT3608)` | MT3608 boost converter module |
| 1 | `pcb(Melzi)` | Melzi electronics - not shown | | 1 | `pcb(Melzi)` | Melzi electronics - not shown |
@@ -2330,8 +2335,8 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
| 1 | `molex_254(2)` | Molex KK header 2 way | | 1 | `molex_254(2)` | Molex KK header 2 way |
| 1 | `molex_254(3)` | Molex KK header 3 way | | 1 | `molex_254(3)` | Molex KK header 3 way |
| 16 | `nut(M2_nut, nyloc = true)` | Nut M2 x 1.6mm nyloc | | 16 | `nut(M2_nut, nyloc = true)` | Nut M2 x 1.6mm nyloc |
| 34 | `nut(M2p5_nut, nyloc = true)` | Nut M2.5 x 2.2mm nyloc | | 30 | `nut(M2p5_nut, nyloc = true)` | Nut M2.5 x 2.2mm nyloc |
| 17 | `nut(M3_nut, nyloc = true)` | Nut M3 x 2.4mm nyloc | | 22 | `nut(M3_nut, nyloc = true)` | Nut M3 x 2.4mm nyloc |
| 8 | `nut(M4_nut, nyloc = true)` | Nut M4 x 3.2mm nyloc | | 8 | `nut(M4_nut, nyloc = true)` | Nut M4 x 3.2mm nyloc |
| 1 | `pcb(PI_IO)` | PI_IO V2 | | 1 | `pcb(PI_IO)` | PI_IO V2 |
| 1 | `pcb(PSU12V1A)` | PSU 12V 1A - not shown | | 1 | `pcb(PSU12V1A)` | PSU 12V 1A - not shown |
@@ -2351,9 +2356,8 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
| 8 | `screw(M2p5_cap_screw, 25)` | Screw M2.5 cap x 25mm | | 8 | `screw(M2p5_cap_screw, 25)` | Screw M2.5 cap x 25mm |
| 8 | `screw(M2p5_cap_screw, 30)` | Screw M2.5 cap x 30mm | | 8 | `screw(M2p5_cap_screw, 30)` | Screw M2.5 cap x 30mm |
| 12 | `screw(M2p5_pan_screw, 25)` | Screw M2.5 pan x 25mm | | 12 | `screw(M2p5_pan_screw, 25)` | Screw M2.5 pan x 25mm |
| 4 | `screw(M2p5_pan_screw, 30)` | Screw M2.5 pan x 30mm |
| 4 | `screw(M3_cap_screw, 16)` | Screw M3 cap x 16mm | | 4 | `screw(M3_cap_screw, 16)` | Screw M3 cap x 16mm |
| 4 | `screw(M3_cap_screw, 30)` | Screw M3 cap x 30mm | | 9 | `screw(M3_cap_screw, 30)` | Screw M3 cap x 30mm |
| 9 | `screw(M3_cap_screw, 35)` | Screw M3 cap x 35mm | | 9 | `screw(M3_cap_screw, 35)` | Screw M3 cap x 35mm |
| 8 | `screw(M4_cap_screw, 35)` | Screw M4 cap x 35mm | | 8 | `screw(M4_cap_screw, 35)` | Screw M4 cap x 35mm |
| 1 | `pcb(TP4056)` | TP4056 Li-lon Battery charger module | | 1 | `pcb(TP4056)` | TP4056 Li-lon Battery charger module |
@@ -2362,8 +2366,8 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
| 1 | | USB A to Mini B lead - not shown | | 1 | | USB A to Mini B lead - not shown |
| 1 | `pcb(WD2002SJ)` | WD2002SJ Buck Boost DC-DC converter | | 1 | `pcb(WD2002SJ)` | WD2002SJ Buck Boost DC-DC converter |
| 16 | `washer(M2_washer)` | Washer M2 x 5mm x 0.3mm | | 16 | `washer(M2_washer)` | Washer M2 x 5mm x 0.3mm |
| 34 | `washer(M2p5_washer)` | Washer M2.5 x 5.9mm x 0.5mm | | 30 | `washer(M2p5_washer)` | Washer M2.5 x 5.9mm x 0.5mm |
| 17 | `washer(M3_washer)` | Washer M3 x 7mm x 0.5mm | | 22 | `washer(M3_washer)` | Washer M3 x 7mm x 0.5mm |
| 8 | `washer(M4_washer)` | Washer M4 x 9mm x 0.8mm | | 8 | `washer(M4_washer)` | Washer M4 x 9mm x 0.8mm |
| 1 | `pcb(ZC_A0591)` | ZC-A0591 ULN2003 driver PCB | | 1 | `pcb(ZC_A0591)` | ZC-A0591 ULN2003 driver PCB |
@@ -2379,11 +2383,11 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
| 4 | pcb_spacer25140.stl | | 4 | pcb_spacer25140.stl |
| 4 | pcb_spacer25150_2.stl | | 4 | pcb_spacer25150_2.stl |
| 4 | pcb_spacer25160_2.stl | | 4 | pcb_spacer25160_2.stl |
| 4 | pcb_spacer25170_2.stl | | 4 | pcb_spacer25180.stl |
| 4 | pcb_spacer25190.stl | | 4 | pcb_spacer25190.stl |
| 4 | pcb_spacer25200.stl |
| 2 | pcb_spacer2580.stl | | 2 | pcb_spacer2580.stl |
| 4 | pcb_spacer30180.stl | | 4 | pcb_spacer30170.stl |
| 5 | pcb_spacer30200.stl |
| 5 | pcb_spacer30210.stl | | 5 | pcb_spacer30210.stl |
| 4 | pcb_spacer30220.stl | | 4 | pcb_spacer30220.stl |
| 4 | pcb_spacer3050.stl | | 4 | pcb_spacer3050.stl |
@@ -6232,9 +6236,10 @@ Rectangle with rounded corners.
### Modules ### Modules
| Module | Description | | Module | Description |
|:--- |:--- | |:--- |:--- |
| `rounded_rectangle(size, r, center = true, xy_center = true)` | Like `cube()` but corners rounded in XY plane and separate centre options for xy and z. | | `rounded_cube_xy(size, r = 0, xy_center = false, z_center = false)` | Like `cube()` but corners rounded in XY plane and separate centre options for xy and z. |
| `rounded_rectangle_xz(size, r, center = true, xy_center = true)` | Like `cube()` but corners rounded in XZ plane and separate centre options for xy and z. | | `rounded_cube_xz(size, r = 0, xy_center = false, z_center = false)` | Like `cube()` but corners rounded in XZ plane and separate centre options for xy and z. |
| `rounded_rectangle_yz(size, r, center = true, xy_center = true)` | Like `cube()` but corners rounded in YX plane and separate centre options for xy and z. | | `rounded_cube_yz(size, r = 0, xy_center = false, z_center = false)` | Like `cube()` but corners rounded in YX plane and separate centre options for xy and z. |
| `rounded_rectangle(size, r, center = false, xy_center = true)` | Like `cube()` but corners rounded in XY plane and separate centre options for xy and z. |
| `rounded_square(size, r, center = true)` | Like `square()` but with with rounded corners | | `rounded_square(size, r, center = true)` | Like `square()` but with with rounded corners |
![rounded_rectangle](tests/png/rounded_rectangle.png) ![rounded_rectangle](tests/png/rounded_rectangle.png)

View File

@@ -18,6 +18,7 @@
# #
import os import os
from set_config import source_dir from set_config import source_dir
from colorama import Fore
def mtime(file): def mtime(file):
if os.path.isfile(file): if os.path.isfile(file):
@@ -41,13 +42,13 @@ def read_deps(dname):
def check_deps(target, dname): def check_deps(target, dname):
target_mtime = mtime(target) target_mtime = mtime(target)
if not target_mtime: if not target_mtime:
return target + " missing" return Fore.CYAN + target + " missing" + Fore.WHITE
if not os.path.isfile(dname): if not os.path.isfile(dname):
return "no deps" return Fore.CYAN + "no deps" + Fore.WHITE
deps = read_deps(dname) deps = read_deps(dname)
for dep in deps: for dep in deps:
if mtime(dep) > target_mtime: if mtime(dep) > target_mtime:
return dep + ' changed' return Fore.CYAN + dep + ' changed' + Fore.WHITE
return None return None
def source_dirs(bom_dir): def source_dirs(bom_dir):

View File

@@ -28,7 +28,10 @@ from set_config import *
import time import time
import times import times
from deps import * from deps import *
from tmpdir import *
import json import json
import shutil
from colorama import Fore, init
def bom_to_parts(bom_dir, part_type, assembly = None): def bom_to_parts(bom_dir, part_type, assembly = None):
# #
@@ -62,12 +65,20 @@ def make_parts(target, part_type, parts = None):
# #
top_dir = set_config(target, lambda: usage(part_type)) top_dir = set_config(target, lambda: usage(part_type))
target_dir = top_dir + part_type + 's' target_dir = top_dir + part_type + 's'
deps_dir = top_dir + "deps" deps_dir = target_dir + "/deps"
bom_dir = top_dir + "bom" bom_dir = top_dir + "bom"
tmp_dir = mktmpdir(top_dir)
if not os.path.isdir(target_dir): if not os.path.isdir(target_dir):
os.makedirs(target_dir) os.makedirs(target_dir)
if not os.path.isdir(deps_dir): if not os.path.isdir(deps_dir):
os.makedirs(deps_dir) os.makedirs(deps_dir)
old_deps = top_dir + 'deps' #old location
if os.path.isdir(old_deps):
shutil.rmtree(old_deps)
times.read_times(target_dir) times.read_times(target_dir)
# #
# Decide which files to make # Decide which files to make
@@ -120,15 +131,15 @@ def make_parts(target, part_type, parts = None):
changed = check_deps(part_file, dname) changed = check_deps(part_file, dname)
changed = times.check_have_time(changed, part) changed = times.check_have_time(changed, part)
if part_type == 'stl' and not changed and not part in bounds_map: if part_type == 'stl' and not changed and not part in bounds_map:
changed = "No bounds" changed = Fore.CYAN + "No bounds" + Fore.WHITE
if changed: if changed:
print(changed) print(changed)
# #
# make a file to use the module # make a file to use the module
# #
part_maker_name = part_type + ".scad" part_maker_name = tmp_dir + '/' + part_type + ".scad"
with open(part_maker_name, "w") as f: with open(part_maker_name, "w") as f:
f.write("use <%s/%s>\n" % (dir, filename)) f.write("use <%s/%s>\n" % (reltmp(dir, target), filename))
f.write("%s();\n" % module); f.write("%s();\n" % module);
t = time.time() t = time.time()
openscad.run("-D$bom=1", "-d", dname, "-o", part_file, part_maker_name) openscad.run("-D$bom=1", "-d", dname, "-o", part_file, part_maker_name)
@@ -145,6 +156,10 @@ def make_parts(target, part_type, parts = None):
with open(bounds_fname, 'w') as outfile: with open(bounds_fname, 'w') as outfile:
json.dump(bounds_map, outfile, indent = 4) json.dump(bounds_map, outfile, indent = 4)
# #
# Remove tmp dir
#
rmtmpdir(tmp_dir)
#
# List the ones we didn't find # List the ones we didn't find
# #
if targets: if targets:

View File

@@ -68,8 +68,9 @@ def gallery(force):
match = re.match(r"^(#+).*$", line) match = re.match(r"^(#+).*$", line)
if match: if match:
line = '#' + line line = '#' + line
if line == '---\n': if line == '---\n' or line == '<span></span>\n':
break; break
if line != '<a name="TOP"></a>\n':
print(line[:-1], file = output_file) print(line[:-1], file = output_file)
else: else:
print(Fore.MAGENTA + "Can't find", document, Fore.WHITE); print(Fore.MAGENTA + "Can't find", document, Fore.WHITE);

View File

@@ -32,12 +32,18 @@ def run_list(args, silent = False, verbose = False):
print() print()
with open("openscad.log", "w") as log: with open("openscad.log", "w") as log:
rc = subprocess.call(cmd, stdout = log, stderr = log) rc = subprocess.call(cmd, stdout = log, stderr = log)
for line in open("openscad.log", "rt"): log_file = "openscad.echo" if "openscad.echo" in cmd else "openscad.log"
bad = False
for line in open(log_file, "rt"):
if verbose or 'ERROR:' in line or 'WARNING:' in line: if verbose or 'ERROR:' in line or 'WARNING:' in line:
bad = True
print(line[:-1]) print(line[:-1])
if rc: if rc:
sys.exit(rc) sys.exit(rc)
if bad:
sys.exit(1)
def run(*args): def run(*args):
run_list(list(args), False) run_list(list(args), False)

View File

@@ -20,6 +20,7 @@
# Set command line options from enviroment variables and check if they have changed # Set command line options from enviroment variables and check if they have changed
import json, os, deps import json, os, deps
from colorama import Fore, init
def check_options(dir = '.'): def check_options(dir = '.'):
global options, options_mtime global options, options_mtime
@@ -37,7 +38,7 @@ def check_options(dir = '.'):
def have_changed(changed, target): def have_changed(changed, target):
if not changed and deps.mtime(target) < options_mtime: if not changed and deps.mtime(target) < options_mtime:
return "command line options changed" return Fore.CYAN + "command line options changed" + Fore.WHITE
return changed return changed
def list(): def list():

View File

@@ -26,8 +26,10 @@ import sys
import c14n_stl import c14n_stl
from set_config import * from set_config import *
from deps import * from deps import *
from shutil import copyfile import shutil
import re import re
import time
import times
source_dirs = { "stl" : "platters", "dxf" : "panels" } source_dirs = { "stl" : "platters", "dxf" : "panels" }
target_dirs = { "stl" : "printed", "dxf" : "routed" } target_dirs = { "stl" : "printed", "dxf" : "routed" }
@@ -41,11 +43,14 @@ def plateup(target, part_type, usage = None):
target_dir = parts_dir + '/' + target_dirs[part_type] target_dir = parts_dir + '/' + target_dirs[part_type]
source_dir1 = source_dirs[part_type] source_dir1 = source_dirs[part_type]
source_dir2 = top_dir + source_dirs[part_type] source_dir2 = top_dir + source_dirs[part_type]
times.read_times(target_dir)
# #
# Loop through source directories # Loop through source directories
# #
used = [] all_used = []
all_sources = [] all_sources = []
all_parts = []
for dir in [source_dir1, source_dir2]: for dir in [source_dir1, source_dir2]:
if not os.path.isdir(dir): if not os.path.isdir(dir):
continue continue
@@ -54,9 +59,12 @@ def plateup(target, part_type, usage = None):
# #
# Make the deps dir # Make the deps dir
# #
deps_dir = dir + "/deps" deps_dir = parts_dir + "/deps"
if not os.path.isdir(deps_dir): if not os.path.isdir(deps_dir):
os.makedirs(deps_dir) os.makedirs(deps_dir)
if os.path.isdir(dir + '/deps'): #old deps
shutil.rmtree(dir + '/deps')
# #
# Decide which files to make # Decide which files to make
# #
@@ -65,22 +73,26 @@ def plateup(target, part_type, usage = None):
# #
# Run OpenSCAD on the source files to make the targets # Run OpenSCAD on the source files to make the targets
# #
for src in sources:
src_file = dir + '/' + src
part_file = target_dir + '/' + src[:-4] + part_type
dname = deps_name(deps_dir, src)
changed = check_deps(part_file, dname)
if changed:
print(changed)
target_def = ['-D$target="%s"' % target] if target else [] target_def = ['-D$target="%s"' % target] if target else []
cwd_def = ['-D$cwd="%s"' % os.getcwd().replace('\\', '/')] cwd_def = ['-D$cwd="%s"' % os.getcwd().replace('\\', '/')]
for src in sources:
src_file = dir + '/' + src
part = src[:-4] + part_type
all_parts.append(part)
part_file = target_dir + '/' + part
uses_file = deps_dir + '/' + src[:-4] + 'txt'
dname = deps_name(deps_dir, src)
oldest = part_file if mtime(part_file) < mtime(uses_file) else uses_file
changed = check_deps(oldest, dname)
used = []
if changed:
print(changed)
t = time.time()
openscad.run_list(["-D$bom=1"] + target_def + cwd_def + ["-d", dname, "-o", part_file, src_file]) openscad.run_list(["-D$bom=1"] + target_def + cwd_def + ["-d", dname, "-o", part_file, src_file])
if part_type == 'stl': if part_type == 'stl':
c14n_stl.canonicalise(part_file) c14n_stl.canonicalise(part_file)
times.add_time(part, t)
log_name = 'openscad.log' log_name = 'openscad.log'
else:
log_name = 'openscad.echo'
openscad.run_silent("-D$bom=1", "-o", log_name, src_file)
# #
# Add the files on the BOM to the used list # Add the files on the BOM to the used list
# #
@@ -89,18 +101,27 @@ def plateup(target, part_type, usage = None):
match = re.match(r'^ECHO: "~(.*?\.' + part_type + r').*"$', line) match = re.match(r'^ECHO: "~(.*?\.' + part_type + r').*"$', line)
if match: if match:
used.append(match.group(1)) used.append(match.group(1))
with open(uses_file, "wt") as file:
for part in used:
print(part, file = file)
else:
with open(uses_file, "rt") as file:
for line in file:
used.append(line[:-1])
all_used += used
copied = [] copied = []
if all_sources: if all_sources:
# #
# Copy files that are not included # Copy files that are not included
# #
for file in os.listdir(parts_dir): for file in os.listdir(parts_dir):
if file.endswith('.' + part_type) and not file in used: if file.endswith('.' + part_type) and not file in all_used:
src = parts_dir + '/' + file src = parts_dir + '/' + file
dst = target_dir + '/' + file dst = target_dir + '/' + file
if mtime(src) > mtime(dst): if mtime(src) > mtime(dst):
print("Copying %s to %s" % (src, dst)) print("Copying %s to %s" % (src, dst))
copyfile(src, dst) shutil.copyfile(src, dst)
copied.append(file) copied.append(file)
# #
# Remove any cruft # Remove any cruft
@@ -111,3 +132,12 @@ def plateup(target, part_type, usage = None):
if not file in targets and not file in copied: if not file in targets and not file in copied:
print("Removing %s" % file) print("Removing %s" % file)
os.remove(target_dir + '/' + file) os.remove(target_dir + '/' + file)
targets = [file[:-4] + 'txt' for file in all_sources]
for file in os.listdir(deps_dir):
if file.endswith('.' + 'txt'):
if not file in targets:
print("Removing %s" % file)
os.remove(deps_dir + '/' + file)
times.print_times(all_parts)

View File

@@ -30,6 +30,7 @@ from tests import do_cmd, update_image, colour_scheme, background
from deps import mtime from deps import mtime
from colorama import init from colorama import init
import json import json
from tmpdir import *
def usage(): def usage():
print("\nusage:\n\trender [target_config] - Render images of the stl and dxf files."); print("\nusage:\n\trender [target_config] - Render images of the stl and dxf files.");
@@ -40,6 +41,7 @@ def render(target, type):
# Make the target directory # Make the target directory
# #
top_dir = set_config(target, usage) top_dir = set_config(target, usage)
tmp_dir = mktmpdir(top_dir)
target_dir = top_dir + type + 's' target_dir = top_dir + type + 's'
bom_dir = top_dir + 'bom' bom_dir = top_dir + 'bom'
if not os.path.isdir(target_dir): if not os.path.isdir(target_dir):
@@ -80,7 +82,7 @@ def render(target, type):
# make a file to import the stl # make a file to import the stl
# #
if mtime(part_file) > mtime(png_name): if mtime(part_file) > mtime(png_name):
png_maker_name = "png.scad" png_maker_name = tmp_dir + "/png.scad"
pp1 = [0, 146/255, 0] pp1 = [0, 146/255, 0]
colour = pp1 colour = pp1
if part in colours: if part in colours:
@@ -88,15 +90,19 @@ def render(target, type):
if not '[' in colour: if not '[' in colour:
colour = '"' + colour + '"' colour = '"' + colour + '"'
with open(png_maker_name, "w") as f: with open(png_maker_name, "w") as f:
f.write('color(%s) import("%s");\n' % (colour, part_file)) f.write('color(%s) import("%s");\n' % (colour, reltmp(part_file, target)))
cam = "--camera=0,0,0,70,0,315,500" if type == 'stl' else "--camera=0,0,0,0,0,0,500" cam = "--camera=0,0,0,70,0,315,500" if type == 'stl' else "--camera=0,0,0,0,0,0,500"
render = "--preview" if type == 'stl' or colour != pp1 else "--render" render = "--preview" if type == 'stl' or colour != pp1 else "--render"
tmp_name = 'tmp.png' tmp_name = tmp_dir + '/' + part[:-4] + '.png'
openscad.run(colour_scheme, "--projection=p", "--imgsize=4096,4096", cam, render, "--autocenter", "--viewall", "-o", tmp_name, png_maker_name); openscad.run(colour_scheme, "--projection=p", "--imgsize=4096,4096", cam, render, "--autocenter", "--viewall", "-o", tmp_name, png_maker_name);
do_cmd(("magick "+ tmp_name + " -trim -resize 280x280 -background %s -gravity Center -extent 280x280 -bordercolor %s -border 10 %s" do_cmd(("magick "+ tmp_name + " -trim -resize 280x280 -background %s -gravity Center -extent 280x280 -bordercolor %s -border 10 %s"
% (background, background, tmp_name)).split()) % (background, background, tmp_name)).split())
update_image(tmp_name, png_name) update_image(tmp_name, png_name)
os.remove(png_maker_name) os.remove(png_maker_name)
#
# Remove tmp dir
#
rmtmpdir(tmp_dir)
if __name__ == '__main__': if __name__ == '__main__':
init() init()

View File

@@ -69,17 +69,22 @@ def set_config(target, usage = None):
sys.exit(1) sys.exit(1)
fname = source_dir + "/target.scad" fname = source_dir + "/target.scad"
text = "include <config_%s.scad>\n" % target; text = ['include <config_%s.scad>\n' % target,
line = "" '$target = "%s";\n' % target,
'$cwd="%s";\n' % os.getcwd().replace('\\', '/')
]
lines = [""]
try: try:
with open(fname,"rt") as f: with open(fname,"rt") as f:
line = f.read() lines = f.readlines()
except: except:
pass pass
if line != text: if lines != text:
with open(fname,"wt") as f: with open(fname,"wt") as f:
f. write(text); for t in text:
f. write(t);
return target + "/" return target + "/"
def usage(): def usage():

View File

@@ -34,6 +34,7 @@ import shutil
from deps import * from deps import *
from blurb import * from blurb import *
from colorama import Fore from colorama import Fore
from tmpdir import *
w = 4096 w = 4096
h = w h = w
@@ -94,6 +95,7 @@ def usage():
def tests(tests): def tests(tests):
scad_dir = "tests" scad_dir = "tests"
tmp_dir = mktmpdir(scad_dir + '/')
deps_dir = scad_dir + "/deps" deps_dir = scad_dir + "/deps"
png_dir = scad_dir + "/png" png_dir = scad_dir + "/png"
bom_dir = scad_dir + "/bom" bom_dir = scad_dir + "/bom"
@@ -234,7 +236,7 @@ def tests(tests):
if changed: if changed:
print(changed) print(changed)
t = time.time() t = time.time()
tmp_name = 'tmp.png' tmp_name = tmp_dir + '/tmp.png'
openscad.run_list(options.list() + ["-D$bom=2", colour_scheme, "--projection=p", "--imgsize=%d,%d" % (w, h), "--camera=0,0,0,70,0,315,500", "--autocenter", "--viewall", "-d", dname, "-o", tmp_name, scad_name]); openscad.run_list(options.list() + ["-D$bom=2", colour_scheme, "--projection=p", "--imgsize=%d,%d" % (w, h), "--camera=0,0,0,70,0,315,500", "--autocenter", "--viewall", "-d", dname, "-o", tmp_name, scad_name]);
times.add_time(scad_name, t) times.add_time(scad_name, t)
do_cmd(["magick", tmp_name, "-trim", "-resize", "1000x600", "-bordercolor", background, "-border", "10", tmp_name]) do_cmd(["magick", tmp_name, "-trim", "-resize", "1000x600", "-bordercolor", background, "-border", "10", tmp_name])
@@ -303,6 +305,11 @@ def tests(tests):
with open(doc_base_name + ".html", "wt") as html_file: with open(doc_base_name + ".html", "wt") as html_file:
do_cmd(("python -m markdown -x tables " + doc_name).split(), html_file) do_cmd(("python -m markdown -x tables " + doc_name).split(), html_file)
times.print_times() times.print_times()
#
# Remove tmp dir
#
rmtmpdir(tmp_dir)
do_cmd(('codespell -L od ' + doc_name).split()) do_cmd(('codespell -L od ' + doc_name).split())
if __name__ == '__main__': if __name__ == '__main__':

View File

@@ -44,7 +44,7 @@ def got_time(name):
def check_have_time(changed, name): def check_have_time(changed, name):
if not changed and not got_time(name): if not changed and not got_time(name):
changed = "no previous time" changed = Fore.CYAN + "no previous time" + Fore.WHITE
return changed return changed
def add_time(name, start): def add_time(name, start):

40
scripts/tmpdir.py Normal file
View File

@@ -0,0 +1,40 @@
#
# NopSCADlib Copyright Chris Palmer 2021
# nop.head@gmail.com
# hydraraptor.blogspot.com
#
# This file is part of NopSCADlib.
#
# NopSCADlib is free software: you can redistribute it and/or modify it under the terms of the
# GNU General Public License as published by the Free Software Foundation, either version 3 of
# the License, or (at your option) any later version.
#
# NopSCADlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with NopSCADlib.
# If not, see <https://www.gnu.org/licenses/>.
#
"""
Make a directory for tmp files.
"""
import os
import time
def mktmpdir(top_dir):
tmp_dir = top_dir + 'tmp'
if not os.path.isdir(tmp_dir):
os.makedirs(tmp_dir)
else:
for file in os.listdir(tmp_dir):
os.remove(tmp_dir + '/' + file)
return tmp_dir
def reltmp(dir, target):
return dir if os.path.isabs(dir) else '../../' + dir if target else '../' + dir
def rmtmpdir(tmp_dir):
os.rmdir(tmp_dir)
while os.path.isdir(tmp_dir):
time.sleep(0.1)

View File

@@ -38,6 +38,7 @@ import shutil
import re import re
import copy import copy
from colorama import Fore from colorama import Fore
from tmpdir import *
def is_assembly(s): def is_assembly(s):
return s[-9:] == '_assembly' or s[-11:] == '_assemblies' return s[-9:] == '_assembly' or s[-11:] == '_assemblies'
@@ -129,8 +130,9 @@ def views(target, do_assemblies = None):
# Make the target directory # Make the target directory
# #
top_dir = set_config(target, usage) top_dir = set_config(target, usage)
tmp_dir = mktmpdir(top_dir)
target_dir = top_dir + 'assemblies' target_dir = top_dir + 'assemblies'
deps_dir = top_dir + "deps" deps_dir = target_dir + "/deps"
bom_dir = top_dir + "bom" bom_dir = top_dir + "bom"
if not os.path.isdir(target_dir): if not os.path.isdir(target_dir):
os.makedirs(target_dir) os.makedirs(target_dir)
@@ -204,15 +206,15 @@ def views(target, do_assemblies = None):
changed = check_deps(png_name, dname) changed = check_deps(png_name, dname)
changed = times.check_have_time(changed, png_name) changed = times.check_have_time(changed, png_name)
changed = options.have_changed(changed, png_name) changed = options.have_changed(changed, png_name)
tmp_name = 'tmp.png' tmp_name = tmp_dir + '/' + real_name + '.png'
if changed: if changed:
print(changed) print(changed)
# #
# make a file to use the module # make a file to use the module
# #
png_maker_name = 'png.scad' png_maker_name = tmp_dir + '/png.scad'
with open(png_maker_name, "w") as f: with open(png_maker_name, "w") as f:
f.write("use <%s/%s>\n" % (dir, filename)) f.write("use <%s/%s>\n" % (reltmp(dir, target), filename))
f.write("%s();\n" % module); f.write("%s();\n" % module);
t = time.time() t = time.time()
target_def = ['-D$target="%s"' % target] if target else [] target_def = ['-D$target="%s"' % target] if target else []
@@ -439,6 +441,10 @@ def views(target, do_assemblies = None):
dst.write(line) dst.write(line)
i += 1 i += 1
# #
# Remove tmp dir
#
rmtmpdir(tmp_dir)
#
# Spell check # Spell check
# #
do_cmd(('codespell -L od ' + top_dir + 'readme.md').split()) do_cmd(('codespell -L od ' + top_dir + 'readme.md').split())

View File

@@ -46,7 +46,7 @@ module widget(thickness) {
module widget_stl() { module widget_stl() {
stl("widget") stl("widget")
union() { union() {
rounded_rectangle([30, 30, 3], 2); rounded_rectangle([30, 30, 3], 2, true);
render() insert_boss(insert, height, 2.2); render() insert_boss(insert, height, 2.2);
} }

View File

@@ -22,7 +22,7 @@ use <../utils/layout.scad>
include <../vitamins/blowers.scad> include <../vitamins/blowers.scad>
module blowers() module blowers()
layout([for(b = blowers) blower_width(b)], 10, true) let(b = blowers[$i]){ layout([for(b = blowers) blower_width(b)], 5, true) let(b = blowers[$i]){
screw = blower_screw(b); screw = blower_screw(b);
h = blower_lug(b); h = blower_lug(b);

View File

@@ -56,7 +56,7 @@ module horiholes_stl(t = thickness) {
} }
if(t == thickness) if(t == thickness)
translate([length / 2, 0]) translate([length / 2, 0])
rounded_rectangle([length + 2 * overlap_x, thickness + 2 * overlap_y, 2], 5); rounded_rectangle([length + 2 * overlap_x, thickness + 2 * overlap_y, 2], 5, true);
} }
module horiholes() { module horiholes() {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 153 KiB

After

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 40 KiB

View File

@@ -27,10 +27,13 @@ module rounded_rectangles() {
rounded_rectangle([30, 20, 10], 3); rounded_rectangle([30, 20, 10], 3);
translate([80, 0]) translate([80, 0])
rounded_rectangle_xz([30, 20, 10], 3); rounded_cube_xy([30, 20, 10], 3);
translate([120, 0]) translate([120, 0])
rounded_rectangle_yz([30, 20, 10], 3); rounded_cube_xz([30, 20, 10], 3);
translate([160, 0])
rounded_cube_yz([30, 20, 10], 3);
} }
rounded_rectangles(); rounded_rectangles();

View File

@@ -146,17 +146,11 @@ module dxf(name) { //! Name a dxf that will appear on the B
} }
} }
module use_stl(name) { //! Import an STL to make a build platter module use_stl(name) //! Import an STL to make a build platter
stl(name); assert(false); // Here for documentation only, real version in core.scad
path = is_undef($target) ? "/stls/" : str("/", $target, "/stls/");
import(str($cwd, path, name, ".stl"));
}
module use_dxf(name) { //! Import a DXF to make a build panel module use_dxf(name) //! Import a DXF to make a build panel
dxf(name); assert(false); // Here for documentation only, real version in core.scad
path = is_undef($target) ? "/dxfs/" : str("/", $target, "/dxfs/");
import(str($cwd, path, name, ".dxf"));
}
function value_string(value) = is_string(value) ? str("\"", value, "\"") : str(value); //! Convert `value` to a string or quote it if it is already a string function value_string(value) = is_string(value) ? str("\"", value, "\"") : str(value); //! Convert `value` to a string or quote it if it is already a string

View File

@@ -25,3 +25,15 @@ include <../../global_defs.scad>
// Global functions and modules // Global functions and modules
// //
use <global.scad> use <global.scad>
module use_stl(name) { //! Import an STL to make a build platter
stl(name);
path = is_undef($target) ? "../stls/" : str($cwd, "/", $target, "/stls/");
import(str(path, name, ".stl"));
}
module use_dxf(name) { //! Import a DXF to make a build panel
dxf(name);
path = is_undef($target) ? "../dxfs/" : str($cwd, "/", $target, "/dxfs/");
import(str(path, name, ".dxf"));
}

View File

@@ -22,26 +22,33 @@
// //
module rounded_square(size, r, center = true) //! Like `square()` but with with rounded corners module rounded_square(size, r, center = true) //! Like `square()` but with with rounded corners
{ {
assert(r < min(size.x, size.y) / 2);
$fn = r2sides4n(r); $fn = r2sides4n(r);
offset(r) offset(-r) square(size, center = center); offset(r) offset(-r) square(size, center = center);
} }
module rounded_rectangle(size, r, center = true, xy_center = true) //! Like `cube()` but corners rounded in XY plane and separate centre options for xy and z. module rounded_rectangle(size, r, center = false, xy_center = true) //! Like `cube()` but corners rounded in XY plane and separate centre options for xy and z.
{ {
linear_extrude(size.z, center = center) extrude_if(size.z, center = center)
rounded_square([size.x, size.y], r, xy_center); rounded_square([size.x, size.y], r, xy_center);
} }
module rounded_rectangle_xz(size, r, center = true, xy_center = true) //! Like `cube()` but corners rounded in XZ plane and separate centre options for xy and z. module rounded_cube_xy(size, r = 0, xy_center = false, z_center = false) //! Like `cube()` but corners rounded in XY plane and separate centre options for xy and z.
{ {
translate([xy_center ? 0 : size.x / 2, xy_center ? 0 : size.y / 2, center ? 0 : size.z / 2]) extrude_if(size.z, center = z_center)
rotate([90, 0, 0]) rounded_square([size.x, size.y], r, xy_center);
rounded_rectangle([size.x, size.z, size.y], r, center = true, xy_center = true);
} }
module rounded_rectangle_yz(size, r, center = true, xy_center = true) //! Like `cube()` but corners rounded in YX plane and separate centre options for xy and z. module rounded_cube_xz(size, r = 0, xy_center = false, z_center = false) //! Like `cube()` but corners rounded in XZ plane and separate centre options for xy and z.
{ {
translate([xy_center ? 0 : size.x / 2, xy_center ? 0 : size.y / 2, center ? 0 : size.z / 2]) translate([xy_center ? 0 : size.x / 2, xy_center ? 0 : size.y / 2, z_center ? 0 : size.z / 2])
rotate([90, 0, 90]) rotate([90, 0, 0])
rounded_rectangle([size.y, size.z, size.x], r, center = true, xy_center = true); rounded_cube_xy([size.x, size.z, size.y], r, xy_center = true, z_center = true);
}
module rounded_cube_yz(size, r = 0, xy_center = false, z_center = false) //! Like `cube()` but corners rounded in YX plane and separate centre options for xy and z.
{
translate([xy_center ? 0 : size.x / 2, xy_center ? 0 : size.y / 2, z_center ? 0 : size.z / 2])
rotate([90, 0, 90])
rounded_cube_xy([size.y, size.z, size.x], r, xy_center = true, z_center = true);
} }

View File

@@ -31,15 +31,15 @@ module rounded_right_triangle(x, y, z, fillet, center = true, offset = false) {
hull() { hull() {
translate([0, fillet, size.z / 2]) translate([0, fillet, size.z / 2])
rotate([90, 90, 0]) rotate([90, 90, 0])
rounded_rectangle([size.z, 2 * fillet, eps], fillet - eps, center = false, xy_center = false); rounded_rectangle([size.z, 2 * fillet, eps], fillet - eps, xy_center = false);
translate([0, size.y, size.z / 2]) translate([0, size.y, size.z / 2])
rotate([90, 90, 0]) rotate([90, 90, 0])
rounded_rectangle([size.z, 2 * fillet, eps], fillet - eps, center = false, xy_center = false); rounded_rectangle([size.z, 2 * fillet, eps], fillet - eps, xy_center = false);
translate([fillet, 0, size.z / 2]) translate([fillet, 0, size.z / 2])
rotate([0, 90, 0]) rotate([0, 90, 0])
rounded_rectangle([size.z, 2 * fillet, eps], fillet - eps, center = false, xy_center = false); rounded_rectangle([size.z, 2 * fillet, eps], fillet - eps, xy_center = false);
translate([size.x, 0, size.z / 2]) translate([size.x, 0, size.z / 2])
rotate([0, 90, 0]) rotate([0, 90, 0])
rounded_rectangle([size.z, 2 * fillet, eps], fillet - eps, center = false, xy_center = false); rounded_rectangle([size.z, 2 * fillet, eps], fillet - eps, xy_center = false);
} }
} }

View File

@@ -128,7 +128,7 @@ module battery_contact(type, pos = true) { //! Draw a positive or negative batte
t = contact_thickness(type); t = contact_thickness(type);
color("silver") { color("silver") {
rounded_rectangle([contact_width(type), h, t], r = 1, center = false); rounded_rectangle([contact_width(type), h, t], r = 1);
translate([0, -h / 2, t]) translate([0, -h / 2, t])
rotate([90, 0, 0]) rotate([90, 0, 0])

View File

@@ -40,8 +40,10 @@ function blower_base(type) = type[13]; //! Thickness of the base
function blower_top(type) = type[14]; //! Thickness of the top function blower_top(type) = type[14]; //! Thickness of the top
function blower_wall(type) = type[15]; //! Side wall thickness function blower_wall(type) = type[15]; //! Side wall thickness
function blower_lug(type) = type[16]; //! Height of the lugs function blower_lug(type) = type[16]; //! Height of the lugs
function blower_wall_left(type) = type[15]; //! Left side wall thickness
function blower_wall_right(type) = type[17]; //! Right wall thickness (for square fans)
function blower_casing_is_square(type) = len(blower_screw_holes(type)) > 3; //! True for square radial fans, false for spiral shape radial blowers function blower_casing_is_square(type) = blower_depth(type) < 15; //! True for square radial fans, false for spiral shape radial blowers
function blower_exit_offset(type) = blower_casing_is_square(type) ? blower_length(type) / 2 : blower_exit(type) / 2; //! Offset of exit's centre from the edge function blower_exit_offset(type) = blower_casing_is_square(type) ? blower_length(type) / 2 : blower_exit(type) / 2; //! Offset of exit's centre from the edge
fan_colour = grey(20); fan_colour = grey(20);
@@ -74,41 +76,54 @@ module blower_fan(type, casing_is_square) {
module blower_square(type) { //! Draw a square blower module blower_square(type) { //! Draw a square blower
width = blower_width(type); width = blower_width(type);
depth = blower_depth(type); depth = blower_depth(type);
wall = blower_wall(type); wall_left = blower_wall_left(type);
wall_right = blower_wall_right(type);
hole_count = len(blower_screw_holes(type));
hole_pitch = (blower_screw_holes(type)[1].x - blower_screw_holes(type)[0].x) / 2; hole_pitch = (blower_screw_holes(type)[1].x - blower_screw_holes(type)[0].x) / 2;
corner_radius = width / 2 - hole_pitch; corner_radius = width / 2 - hole_pitch;
corner_inset = (width - blower_exit(type)) / 2; corner_inset = (width - blower_exit(type) - wall_left - wall_right) / (hole_count == 2 ? 1 : 2);
module inset_corners()
translate([width / 2, width / 2])
for(i = hole_count == 2 ? [1, 3] : [0 : 3])
rotate(i * 90)
translate([-width / 2 - eps, -width/ 2 - eps])
quadrant(corner_inset, corner_inset - corner_radius);
module square_inset_corners(remove_center = false) module square_inset_corners(remove_center = false)
difference() { difference() {
//overall outside //overall outside
square([width, width], center = false); rounded_square([width, width], corner_radius, center = false);
if (remove_center) { if (remove_center) {
// cut out the inside, leaving the corners // cut out the inside, leaving the corners
translate([corner_inset + wall, -eps]) translate([hole_count == 2 ? wall_left : corner_inset + wall_left, -eps])
square([width - 2 * (wall + corner_inset), width - wall + eps], center = false); square([blower_exit(type), width / 2], center = false);
translate(blower_axis(type))
translate([wall, corner_inset + wall]) circle(d = blower_bore(type) + 1);
square([width - 2 * wall, width - 2 * (wall + corner_inset)], center = false);
} else { } else {
// cut out the bore for the fan // cut out the bore for the fan
translate(blower_axis(type)) translate(blower_axis(type))
circle(d = blower_bore(type)); circle(d = blower_bore(type));
} }
// corner inset inset_corners();
translate([width / 2, width / 2])
for(i = [0 : 3])
rotate(i * 90)
translate([-width / 2 - eps, -width/ 2 - eps])
quadrant(corner_inset, corner_inset - corner_radius);
} }
base_height = blower_base(type); base_height = blower_base(type);
linear_extrude(base_height) linear_extrude(base_height)
difference () { difference () {
rounded_square([width, width], corner_radius, center = false); rounded_square([width, width], corner_radius, center = false);
blower_hole_positions(type)
circle(d = blower_screw_hole(type));
}
// add the lugs which may be higher than the base
linear_extrude(blower_lug(type))
difference () {
intersection() {
rounded_square([width, width], corner_radius, center = false);
inset_corners();
}
blower_hole_positions(type) blower_hole_positions(type)
circle(d = blower_screw_hole(type)); circle(d = blower_screw_hole(type));
} }

View File

@@ -24,8 +24,9 @@
// h h s t t // h h s t t
RB5015 = ["RB5015", "Blower Runda RB5015", 51.3, 51, 15, 31.5, M4_cap_screw, 26, [27.3, 25.4], 4.5, [[4.3, 45.4], [47.3,7.4]], 20, 14, 1.5, 1.3, 1.2, 15]; RB5015 = ["RB5015", "Blower Runda RB5015", 51.3, 51, 15, 31.5, M4_cap_screw, 26, [27.3, 25.4], 4.5, [[4.3, 45.4], [47.3,7.4]], 20, 14, 1.5, 1.3, 1.2, 15];
PE4020 = ["PE4020", "Blower Pengda Technology 4020", 40, 40, 20, 27.5, M3_cap_screw, 22, [21.5, 20 ], 3.2, [[37,3],[3,37],[37,37]], 29.3, 17, 1.7, 1.2, 1.3, 13]; PE4020 = ["PE4020", "Blower Pengda Technology 4020", 40, 40, 20, 27.5, M3_cap_screw, 22, [21.5, 20 ], 3.2, [[37,3],[3,37],[37,37]], 29.3, 17, 1.7, 1.2, 1.3, 13];
BL40x10 =["BL40x10","Square radial fan 4010", 40, 40,9.5, 27, M2_cap_screw, 16, [24, 20 ], 2.4, [[2,2],[38,2],[2,38],[38,38]], 30 , 9.5, 1.5, 1.5, 1.1, 1.5]; BL30x10 =["BL30x10","Square radial fan 3010", 30, 30,10.1,25, M2_cap_screw, 16, [16, 15 ], 2.4, [[3,27],[27,3]], 21.2, 9.5, 1.1, 1.2, 2.5, 2.8, 0.9];
BL40x10 =["BL40x10","Square radial fan 4010", 40, 40,9.5, 27, M2_cap_screw, 16, [24, 20 ], 2.4, [[2,2],[38,2],[2,38],[38,38]], 27.8, 9.5, 1.5, 1.5, 1.1, 1.5, 1.1];
blowers = [BL40x10, PE4020, RB5015]; blowers = [BL30x10, BL40x10, PE4020, RB5015];
use <blower.scad> use <blower.scad>

View File

@@ -47,7 +47,7 @@ module square_button(type, colour = "yellow") { //! Draw square button with spec
stem = square_button_cap_stem(type); stem = square_button_cap_stem(type);
color(grey(20)) { color(grey(20)) {
rounded_rectangle([w, w, h - 0.5], r = wall, center = false); rounded_rectangle([w, w, h - 0.5], r = wall);
for(x = [-1, 1], y = [-1, 1]) for(x = [-1, 1], y = [-1, 1])
translate([x * pitch, y * pitch]) translate([x * pitch, y * pitch])

View File

@@ -37,7 +37,7 @@ module camera_lens(type, offset = 0, show_lens = true) //! Draw the lens stack,
r = p[1] + offset; r = p[1] + offset;
app = p[2]; app = p[2];
if(size.x) if(size.x)
rounded_rectangle(size + [2 * offset, 2 * offset, round_to_layer(offset)], r, center = false); rounded_rectangle(size + [2 * offset, 2 * offset, round_to_layer(offset)], r);
else else
if (show_lens) if (show_lens)
translate_z(size.y) translate_z(size.y)
@@ -72,7 +72,7 @@ module camera(type, show_lens = true) { //! Draw specified PCB camera
pos = camera_connector_pos(type); pos = camera_connector_pos(type);
color(grey(20)) color(grey(20))
translate(pos) translate(pos)
rounded_rectangle(conn, 0.5, center = false); rounded_rectangle(conn, 0.5);
flex = [5, 0.1]; flex = [5, 0.1];
color("orange") color("orange")

View File

@@ -326,7 +326,7 @@ module panel_USBA() { //! Draw a panel mount USBA connector
dx = (length2 / 2 - r2); dx = (length2 / 2 - r2);
dy = (width / 2 - r1); dy = (width / 2 - r1);
translate_z(l) translate_z(l)
rounded_rectangle([length2, width, 1], r = r1, center = false); rounded_rectangle([length2, width, 1], r = r1);
translate([-dx, -dy, height2 - r2]) translate([-dx, -dy, height2 - r2])
rotate([90, 0, 0]) rotate([90, 0, 0])

View File

@@ -80,7 +80,7 @@ module display(type) { //! Draw specified display
translate_z(display_ts_thickness(type)) { translate_z(display_ts_thickness(type)) {
difference() { difference() {
color("silver") color("silver")
rounded_rectangle([w, h, t], 0.5, center = false); rounded_rectangle([w, h, t], 0.5);
color("black") color("black")
translate([aperture[0].x, aperture[0].y, - eps]) translate([aperture[0].x, aperture[0].y, - eps])

View File

@@ -59,7 +59,7 @@ module panel_meter_button(type) { //! Draw panel meter button
color(pmeter_button_colour(type)) color(pmeter_button_colour(type))
translate(pmeter_button_pos(type)) translate(pmeter_button_pos(type))
if(size.x) if(size.x)
rounded_rectangle(pmeter_button_size(type), r, center = false); rounded_rectangle(pmeter_button_size(type), r);
else else
cylinder(r = r, h = size.z); cylinder(r = r, h = size.z);
} }
@@ -93,8 +93,8 @@ module panel_meter(type) { //! Draw panel mounted LCD meter module
difference() { difference() {
if(is_list(bevel)) if(is_list(bevel))
hull() { hull() {
rounded_rectangle([bezel.x - 2 * bevel.x, bezel.y - 2 * bevel.x, bezel.z], r - bevel.x, center = false); rounded_rectangle([bezel.x - 2 * bevel.x, bezel.y - 2 * bevel.x, bezel.z], r - bevel.x);
rounded_rectangle([bezel.x, bezel.y, bevel[1]], r, center = false); rounded_rectangle([bezel.x, bezel.y, bevel[1]], r);
} }
else else
hull() { hull() {
@@ -111,7 +111,7 @@ module panel_meter(type) { //! Draw panel mounted LCD meter module
cube([ap.x + ap.z, ap.y + ap.z, eps], center = true); cube([ap.x + ap.z, ap.y + ap.z, eps], center = true);
translate_z(bezel.z + eps) translate_z(bezel.z + eps)
rounded_rectangle([ap.x, ap.y, bezel.z * 2], r, center = true); rounded_rectangle([ap.x, ap.y, bezel.z * 2], r, true);
} }
} }
// //

View File

@@ -126,7 +126,7 @@ module usb_A(h, v_flange_l, bar, cutout) {
if(cutout) if(cutout)
rotate([90, 0, 90]) rotate([90, 0, 90])
rounded_rectangle([w + 2 * v_flange_h + 2 * panel_clearance, rounded_rectangle([w + 2 * v_flange_h + 2 * panel_clearance,
h + 2 * h_flange_h + 2 * panel_clearance, 100], r = cnc_bit_r, center = false); h + 2 * h_flange_h + 2 * panel_clearance, 100], r = cnc_bit_r);
else { else {
color("silver") rotate([0, 90, 0]) { color("silver") rotate([0, 90, 0]) {
linear_extrude(l, center = true) linear_extrude(l, center = true)

View File

@@ -292,6 +292,99 @@ BTT_SKR_MINI_E3_V2_0 = [
[] // accessories [] // accessories
]; ];
BTT_SKR_E3_TURBO = [
"BTT_SKR_E3_TURBO", "BigTreeTech SKR E3 Turbo",
102, 90.25, 1.6, // size
1, // corner radius
3.5, // mounting hole diameter
5, // pad around mounting hole
grey(30), // color
false, // true if parts should be separate BOM items
[ // hole positions
for ( i=[ [0, 0], [62.15, 0.25] ])
(i + [21.6, -13.3]),
for( i=[ [0, -34.98 ], [31.80, -37.62 ], [95.68, -64.47] ])
(i + [3.75, -13.25])
],
[ // components
// cpu
[ 62.8, 42.5, 0, "chip", 14, 14, 1, grey(15) ],
// driver chips
for (x = [8.5, 27.5, 43.2, 58.5, 74])
[x, -20, 0, "chip", 5, 5, 1, grey(15)],
// mock up heat sinks over the chips
for (x = [8.5, 27.5, 43.2, 58.5, 74])
[x, -20, 0, "chip", 9, 8.5, 2, "DeepSkyBlue" ],
for (x = [8.5, 27.5, 43.2, 58.5, 74], y = [-4,-2,0,2,4])
[x, -20 + y, 0, "chip", 9, 0.75, 11, "DeepSkyBlue" ],
// heat dissipation for drivers under board
[ 43, -21, 0, "-block", 85, 8, 0.1, gold ],
// hotend and heated bed
[ 25.5, 20, 0, "chip", 10, 8.5, 4, grey(15) ],
[ 25.5, 20, 0, "-block", 11, 11, 0.1, gold ],
[ 36.25, 16.75, 0, "chip", 6.5, 6, 2.5, grey(15) ],
[ 36.25, 17, 0, "-block", 7.5, 7.5, 0.1, gold ],
[ 44.25, 16.75, 0, "chip", 6.5, 6, 2.5, grey(15) ],
[ 44.25, 17, 0, "-block", 7.5, 7.5, 0.1, gold ],
// voltage regulator
[ 15.1, 44.2, 0, "chip", 4, 5, 2, grey(15) ],
[ 12.1, 44.2, 0, "-block", 10, 10, 0.1, gold ],
// terminals
[ 5.25, 5.3, 180, "gterm", gt_5x17, 2, undef, grey(20) ],
[ 16.25, 5.4, -90, "gterm", gt_5x17, 2, undef, grey(20) ],
[ 26.25, 5.4, -90, "gterm", gt_5x17, 2, undef, grey(20) ],
[ 36.1, 6.7, -90, "gterm", gt_5x11, 2, undef, "lightgreen" ],
[ 45.0, 6.7, -90, "gterm", gt_5x11, 2, undef, "lightgreen" ],
[ -3, -(32.27 + 39.92)/2, 0, "usb_uA" ],
[ -8, -(12.13 + 27.17)/2, 0, "uSD", [17.17 - 2.13, 16, 2] ],
[ -22.2, 51.6, 0, "button_6mm" ],
// EXP
[ -4.45, 27.2, -90, "2p54boxhdr", 5, 2 ],
// AUX-2
[ -3.4, 42.5, -90, "2p54header", 4, 2 ],
// TFT
[ 73.7, 21, 0, "2p54header", 5, 1 ],
// FAN0
[ 52.1, 15.3, 180, "jst_xh", 2, false, grey(20) ],
// FAN1
[ 60.1, 15.3, 180, "jst_xh", 2, false, grey(20) ],
// PS-ON
[ 67.9, 15.3, 180, "jst_xh", 2, false, grey(20) ],
// E0-STOP
[ 77.1, 15.3, 180, "jst_xh", 3, false, grey(20) ],
// E1-STOP
[ 87.5, 15.3, 180, "jst_xh", 3, false, grey(20) ],
// Z-PROBE
[ 85.05, 34.6, 180, "jst_xh", 5, false, grey(20) ],
// NEO Pixel
[ 77, 26.8, 180, "jst_xh", 3, false, grey(20) ],
// PWR-DET
[ 87.7, 26.8, 180, "jst_xh", 3, false, grey(20) ],
// FAN2
[ 52.1, 3.8, 0, "2p54header", 1, 2],
// end stops and thermistors
for (x = [58.5 : 7.9 : 98.1])
[x, 3.7, 180, "jst_xh", 2, false, grey(20)],
// motor connections
for (x = [7, 27.1, 47.3, 67.5, 87.9])
[x, -3.9, 0, "jst_xh", 4, false, grey(20)],
[47.3, -10.4, 0, "jst_xh", 4, false, grey(20)], // second Z connector
// motor jumpers
for (x = [9.4, 26.4, 42.5, 58.7, 75.3])
[x, -33.7, 0, "2p54header", 2, 1],
// SWD
[ 45.4, 35.7, 0, "2p54header", 5, 1 ],
// USB power jumber
[ -12.6, 40.3, 0, "2p54header", 3, 1 ],
// VOUT
[ -13.9, 44.5, 0, "2p54header", 2, 2 ],
// VIN
[ 18.6, 29.8, 0, "2p54header", 2, 2 ],
],
[] // accessories
];
TMC2130 = [ TMC2130 = [
"TMC2130", "TMC2130", "TMC2130", "TMC2130",
20, 14, 1.6, // size 20, 14, 1.6, // size
@@ -654,9 +747,9 @@ ESP_01 = [
[] // accessories [] // accessories
]; ];
pcbs = [MP1584EN, TP4056, ESP_01, RAMPSEndstop, MT3608, PI_IO, ExtruderPCB, ZC_A0591, RPI0, EnviroPlus, ArduinoUno3, ArduinoLeonardo, Keyes5p1, WD2002SJ, RPI3, RPI4, BTT_SKR_MINI_E3_V2_0, BTT_SKR_V1_4_TURBO, DuetE, Duex5]; pcbs = [MP1584EN, TP4056, ESP_01, RAMPSEndstop, MT3608, PI_IO, ExtruderPCB, ZC_A0591, RPI0, EnviroPlus, ArduinoUno3, ArduinoLeonardo, WD2002SJ, RPI3, RPI4, BTT_SKR_MINI_E3_V2_0, BTT_SKR_E3_TURBO, BTT_SKR_V1_4_TURBO, DuetE, Duex5];
pcbs_not_shown = [Melzi, Duex2, PSU12V1A]; pcbs_not_shown = [Melzi, Duex2, PSU12V1A, Keyes5p1];
perfboards = [PERF74x51, PERF70x50, PERF60x40, PERF70x30, PERF80x20]; perfboards = [PERF74x51, PERF70x50, PERF60x40, PERF70x30, PERF80x20];

View File

@@ -23,7 +23,7 @@
// Wr Hr E P D d h go gw // Wr Hr E 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 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 ]; 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, 7.5, 20, 6.0, 3.5, 3.5, M3_cap_screw, M3_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, 10, 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 ]; 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 ]; SSR15= [ "SSR15", 15, 12.5, 10, 60, 7.5, 4.5, 5.3, M4_cap_screw, M4_cs_cap_screw, 2.5, 2.75 ];

View File

@@ -62,7 +62,7 @@ module sk_bracket(type) { //! SK shaft support bracket
} }
for(x = [W / 2 - 2 * fillet, -W / 2 + 2 * fillet]) for(x = [W / 2 - 2 * fillet, -W / 2 + 2 * fillet])
translate([x, G / 2, 0]) translate([x, G / 2, 0])
rounded_rectangle([4 * fillet, G, L], fillet); rounded_rectangle([4 * fillet, G, L], fillet, true);
} }
translate([0, -h, -L /2]) translate([0, -h, -L /2])

View File

@@ -56,10 +56,10 @@ module transformer(type) { //! Draw specified transformer
} }
color("white") { color("white")
translate_z(tx_lamination_height(type) / 2 + tx_bobbin_offset(type) / 2) translate_z(tx_lamination_height(type) / 2 + tx_bobbin_offset(type) / 2)
rounded_rectangle([tx_bobbin_width(type), tx_depth(type), tx_bobbin_height(type)], r = tx_bobbin_radius(type)); rounded_rectangle([tx_bobbin_width(type), tx_depth(type), tx_bobbin_height(type)], tx_bobbin_radius(type), true);
}
terminal_height = tx_height(type) - tx_lamination_height(type); terminal_height = tx_height(type) - tx_lamination_height(type);
if(terminal_height) if(terminal_height)

View File

@@ -62,7 +62,7 @@ module ziptie(type, r, t = 0) //! Draw specified ziptie wrapped around radius `r
translate([lx, -r]) translate([lx, -r])
rotate([90, 0, 0]) rotate([90, 0, 0])
union() { union() {
rounded_rectangle(latch, 0.5, center = false); rounded_rectangle(latch, 0.5);
translate_z((latch.z + 1) / 2) translate_z((latch.z + 1) / 2)
cube([ziptie_thickness(type), ziptie_width(type), latch.z + 1], center = true); cube([ziptie_thickness(type), ziptie_width(type), latch.z + 1], center = true);