Merge branch 'master' into pcb_microswitch2
16
.gitattributes
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
# Set the default behavior, in case people don't have core.autocrlf set.
|
||||
* text=auto eol=lf
|
||||
|
||||
# Declare text files that are normalized and converted on checkout.
|
||||
*.scad text
|
||||
*.py text
|
||||
*.md text
|
||||
|
||||
# Handle Windows batch and command files
|
||||
*.{bat,[bB][aA][tT]} text eol=crlf
|
||||
*.{cmd,[cC][mM][dD]} text eol=crlf
|
||||
|
||||
# Denote files that are binary and should not be modified.
|
||||
*.png binary
|
||||
*.jpg binary
|
||||
|
1
.gitignore
vendored
@ -7,6 +7,7 @@ tests/bom/
|
||||
*.log
|
||||
*.html
|
||||
bounds.json
|
||||
options.json
|
||||
times.txt
|
||||
*_diff.png
|
||||
*.echo
|
||||
|
BIN
docs/metric_threads.png
Normal file
After Width: | Height: | Size: 17 KiB |
@ -26,7 +26,7 @@ OpenSCAD has to be setup to find libraries by setting the ```OPENSCADPATH``` env
|
||||
in the directory it points to. This can be done with ```git clone https://github.com/nophead/NopSCADlib.git``` while in that directory or, if you don't want to use GIT,
|
||||
by downloading https://github.com/nophead/NopSCADlib/archive/master.zip and unzipping it to a directory called NopSCADlib.
|
||||
|
||||
The ```NopSCADlib/scripts``` directory needs to be added to the executable search path.
|
||||
The ```NopSCADlib/scripts``` directory needs to be added to the executable search path, ```PATH``` on Windows and ```path``` on Linux and Mac.
|
||||
|
||||
The installation can be tested by opening ```NopSCADlib/libtest.scad``` in the OpenSCAD GUI. It should render all the objects in the library in about 1 minute.
|
||||
|
||||
|
@ -39,6 +39,7 @@ pp2_colour = is_undef($pp2_colour) ? "red" : $pp2_colour; // pri
|
||||
pp3_colour = is_undef($pp3_colour) ? "blue" : $pp3_colour; // printed part colour 3
|
||||
pp4_colour = is_undef($pp4_colour) ? "darkorange" : $pp4_colour;// printed part colour 4
|
||||
show_rays = is_undef($show_rays) ? false : $show_rays; // show camera sight lines and light direction
|
||||
show_threads = is_undef($show_threads) ? false : $show_threads; // show screw threads
|
||||
|
||||
// Minimum wall is about two filaments wide but we extrude it closer to get better bonding
|
||||
squeezed_wall = $preview ? 2 * extrusion_width - layer_height * (1 - PI / 4)
|
||||
@ -59,7 +60,8 @@ grey60 = [0.6, 0.6, 0.6];
|
||||
grey70 = [0.7, 0.7, 0.7];
|
||||
grey80 = [0.8, 0.8, 0.8];
|
||||
grey90 = [0.9, 0.9, 0.9];
|
||||
brass = "gold";
|
||||
brass = [255/255, 215/255, 0/255];
|
||||
silver = [0.75, 0.75, 0.75];
|
||||
|
||||
/*
|
||||
* Enums
|
||||
|
1
lib.scad
@ -91,3 +91,4 @@ use <utils/layout.scad>
|
||||
use <utils/round.scad>
|
||||
use <utils/offset.scad>
|
||||
use <utils/sector.scad>
|
||||
use <utils/thread.scad>
|
||||
|
BIN
libtest.png
Before Width: | Height: | Size: 760 KiB After Width: | Height: | Size: 766 KiB |
@ -136,13 +136,13 @@ translate([x5, cable_grommets_y + 250])
|
||||
translate([900, 600])
|
||||
box_test();
|
||||
|
||||
translate([850, 1220])
|
||||
translate([850, 1260])
|
||||
bbox_test();
|
||||
|
||||
x0 = 0;
|
||||
inserts_y = 0;
|
||||
nuts_y = inserts_y + 20;
|
||||
washers_y = nuts_y + 60;
|
||||
washers_y = nuts_y + 100;
|
||||
screws_y = washers_y + 120;
|
||||
o_rings_y = screws_y + 130;
|
||||
springs_y = o_rings_y + 20;
|
||||
@ -254,7 +254,7 @@ buttons_y = spades_y + 40;
|
||||
jacks_y = buttons_y + 40;
|
||||
microswitches_y = jacks_y + 40;
|
||||
rockers_y = microswitches_y + 40;
|
||||
toggles_y = rockers_y + 40;
|
||||
toggles_y = rockers_y + 60;
|
||||
components_y = toggles_y + 40;
|
||||
|
||||
translate([x2, leds_y])
|
||||
|
@ -34,7 +34,7 @@ knob_waves = 5;
|
||||
knob_height = knob_stem_h + knob_thickness;
|
||||
function knob_height() = knob_height;
|
||||
|
||||
module screw_knob(screw) { //! Generate the STL foe a knob to fit the specified hex screw
|
||||
module screw_knob(screw) { //! Generate the STL for a knob to fit the specified hex screw
|
||||
stl(str("screw_knob_M", screw_radius(screw) * 20));
|
||||
|
||||
knob_stem_r = nut_trap_radius(screw_nut(screw)) + knob_wall;
|
||||
|
135
readme.md
@ -32,8 +32,8 @@ See [usage](docs/usage.md) for requirements, installation instructions and a usa
|
||||
<tr><td> <a href = "#Fans">Fans</a> </td><td> <a href = "#Rod">Rod</a> </td><td> <a href = "#Handle">Handle</a> </td><td> <a href = "#Rounded_polygon">Rounded_polygon</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Fuseholder">Fuseholder</a> </td><td> <a href = "#Screws">Screws</a> </td><td> <a href = "#Pcb_mount">Pcb_mount</a> </td><td> <a href = "#Sector">Sector</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Geared_steppers">Geared_steppers</a> </td><td> <a href = "#Sealing_strip">Sealing_strip</a> </td><td> <a href = "#Psu_shroud">Psu_shroud</a> </td><td> <a href = "#Sweep">Sweep</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Green_terminals">Green_terminals</a> </td><td> <a href = "#Sheets">Sheets</a> </td><td> <a href = "#Ribbon_clamp">Ribbon_clamp</a> </td><td> <a href = "#Tube">Tube</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Hot_ends">Hot_ends</a> </td><td> <a href = "#Spades">Spades</a> </td><td> <a href = "#Screw_knob">Screw_knob</a> </td><td></td><td></td></tr>
|
||||
<tr><td> <a href = "#Green_terminals">Green_terminals</a> </td><td> <a href = "#Sheets">Sheets</a> </td><td> <a href = "#Ribbon_clamp">Ribbon_clamp</a> </td><td> <a href = "#Thread">Thread</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Hot_ends">Hot_ends</a> </td><td> <a href = "#Spades">Spades</a> </td><td> <a href = "#Screw_knob">Screw_knob</a> </td><td> <a href = "#Tube">Tube</a> </td><td></td></tr>
|
||||
<tr><td> <a href = "#Hygrometer">Hygrometer</a> </td><td> <a href = "#Spools">Spools</a> </td><td> <a href = "#Socket_box">Socket_box</a> </td><td></td><td></td></tr>
|
||||
<tr><td> <a href = "#Iecs">Iecs</a> </td><td> <a href = "#Springs">Springs</a> </td><td> <a href = "#Ssr_shroud">Ssr_shroud</a> </td><td></td><td></td></tr>
|
||||
<tr><td> <a href = "#Inserts">Inserts</a> </td><td> <a href = "#Ssrs">Ssrs</a> </td><td> <a href = "#Strap_handle">Strap_handle</a> </td><td></td><td></td></tr>
|
||||
@ -196,7 +196,7 @@ Individual teeth are not drawn, instead they are represented by a lighter colour
|
||||
### Modules
|
||||
| Module | Description |
|
||||
|:--- |:--- |
|
||||
| ```belt(type, points, gap = 0, gap_pt = undef)``` | Draw a belt path given a set of points and pitch radii where the pulleys are. Closed loop unless a gap is specified |
|
||||
| ```belt(type, points, gap = 0, gap_pt = undef, belt_colour = grey20, tooth_colour = grey50)``` | Draw a belt path given a set of points and pitch radii where the pulleys are. Closed loop unless a gap is specified |
|
||||
|
||||
![belts](tests/png/belts.png)
|
||||
|
||||
@ -992,10 +992,11 @@ IEC mains inlets and outlet.
|
||||
| 1 | ```iec(IEC_inlet)``` | IEC inlet |
|
||||
| 1 | ```iec(IEC_inlet_atx)``` | IEC inlet for ATX |
|
||||
| 1 | ```iec(IEC_outlet)``` | IEC outlet RS 811-7193 |
|
||||
| 10 | ```nut(M3_nut, nyloc = true)``` | Nut M3 x 2.4mm nyloc |
|
||||
| 1 | ```iec(IEC_switched_fused_inlet)``` | IEC320 C14 switched fused inlet module |
|
||||
| 12 | ```nut(M3_nut, nyloc = true)``` | Nut M3 x 2.4mm nyloc |
|
||||
| 4 | ```screw(M3_cs_cap_screw, 10)``` | Screw M3 cs cap x 10mm |
|
||||
| 6 | ```screw(M3_cs_cap_screw, 12)``` | Screw M3 cs cap x 12mm |
|
||||
| 10 | ```washer(M3_washer)``` | Washer M3 x 7mm x 0.5mm |
|
||||
| 8 | ```screw(M3_cs_cap_screw, 12)``` | Screw M3 cs cap x 12mm |
|
||||
| 12 | ```washer(M3_washer)``` | Washer M3 x 7mm x 0.5mm |
|
||||
|
||||
|
||||
<a href="#top">Top</a>
|
||||
@ -1152,7 +1153,9 @@ Nuts for leadscrews.
|
||||
| ```leadnut_hole_dia(type)``` | The diameter of the screw holes |
|
||||
| ```leadnut_hole_pitch(type)``` | The radia pitch of the screw holes |
|
||||
| ```leadnut_holes(type)``` | The number of screw holes |
|
||||
| ```leadnut_lead(type)``` | Screw lead |
|
||||
| ```leadnut_od(type)``` | Outer diameter of the shank |
|
||||
| ```leadnut_pitch(type)``` | Screw pitch |
|
||||
| ```leadnut_screw(type)``` | The type of the fixing screws |
|
||||
|
||||
### Functions
|
||||
@ -1620,11 +1623,16 @@ If a nut is given a child then it gets placed on its top surface.
|
||||
| 1 | ```nut(M2p5_nut)``` | Nut M2.5 x 2.2mm |
|
||||
| 1 | ```nut(M2p5_nut, nyloc = true)``` | Nut M2.5 x 2.2mm nyloc |
|
||||
| 1 | ```nut(M2p5_nut, nylon = true)``` | Nut M2.5 x 2.2mm nylon |
|
||||
| 1 | ```hammer_nut(M3_hammer_nut)``` | Nut M3 hammer |
|
||||
| 1 | ```sliding_t_nut(M3_sliding_t_nut)``` | Nut M3 sliding T |
|
||||
| 1 | ```nut(M3_nut)``` | Nut M3 x 2.4mm |
|
||||
| 1 | ```nut(M3_nut, brass = true)``` | Nut M3 x 2.4mm brass |
|
||||
| 1 | ```nut(M3_nut, nyloc = true)``` | Nut M3 x 2.4mm nyloc |
|
||||
| 1 | ```hammer_nut(M4_hammer_nut)``` | Nut M4 hammer |
|
||||
| 1 | ```sliding_t_nut(M4_sliding_t_nut)``` | Nut M4 sliding T |
|
||||
| 1 | ```nut(M4_nut)``` | Nut M4 x 3.2mm |
|
||||
| 1 | ```nut(M4_nut, nyloc = true)``` | Nut M4 x 3.2mm nyloc |
|
||||
| 1 | ```sliding_t_nut(M5_sliding_t_nut)``` | Nut M5 sliding T |
|
||||
| 1 | ```nut(M5_nut)``` | Nut M5 x 4mm |
|
||||
| 1 | ```nut(M5_nut, nyloc = true)``` | Nut M5 x 4mm nyloc |
|
||||
| 1 | ```nut(M6_half_nut)``` | Nut M6 x 3mm |
|
||||
@ -1752,6 +1760,7 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
|
||||
| Module | Description |
|
||||
|:--- |:--- |
|
||||
| ```barrel_jack(cutout = false)``` | Draw barrel power jack |
|
||||
| ```buzzer(height, diameter, colour)``` | Draw PCB buzzer with specified height, diameter and color |
|
||||
| ```chip(length, width, thickness, colour, cutout = false)``` | Draw a coloured cube to represent a chip, or other rectangular component |
|
||||
| ```flat_flex(cutout = false)``` | Draw flat flexistrip connector as used on RPI0 |
|
||||
| ```flex(cutout = false)``` | Draw flexistrip connector |
|
||||
@ -1795,7 +1804,7 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
|
||||
| 1 | ```molex_254(2)``` | Molex KK header 2 way |
|
||||
| 1 | ```molex_254(3)``` | Molex KK header 3 way |
|
||||
| 16 | ```nut(M2_nut, nyloc = true)``` | Nut M2 x 1.6mm nyloc |
|
||||
| 28 | ```nut(M2p5_nut, nyloc = true)``` | Nut M2.5 x 2.2mm nyloc |
|
||||
| 32 | ```nut(M2p5_nut, nyloc = true)``` | Nut M2.5 x 2.2mm nyloc |
|
||||
| 12 | ```nut(M3_nut, nyloc = true)``` | Nut M3 x 2.4mm nyloc |
|
||||
| 12 | ```nut(M4_nut, nyloc = true)``` | Nut M4 x 3.2mm nyloc |
|
||||
| 1 | ```pcb(PI_IO)``` | PI_IO V2 |
|
||||
@ -1806,11 +1815,13 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
|
||||
| 1 | ```pcb(PERF74x51)``` | Perfboard 74 x 51mm |
|
||||
| 1 | ```pcb(PERF80x20)``` | Perfboard 80 x 20mm |
|
||||
| 1 | ```pin_socket(2p54header, 13, 2, right_angle = true)``` | Pin socket 13 x 2 right_angle |
|
||||
| 1 | ```pcb(RAMPSEndstop)``` | RAMPS Endstop Switch |
|
||||
| 1 | ```pcb(RPI3)``` | Raspberry Pi 3 |
|
||||
| 1 | ```pcb(RPI0)``` | Raspberry Pi Zero |
|
||||
| 16 | ```screw(M2_cap_screw, 25)``` | Screw M2 cap x 25mm |
|
||||
| 4 | ```screw(M2p5_cap_screw, 16)``` | Screw M2.5 cap x 16mm |
|
||||
| 8 | ```screw(M2p5_cap_screw, 20)``` | Screw M2.5 cap x 20mm |
|
||||
| 4 | ```screw(M2p5_cap_screw, 35)``` | Screw M2.5 cap x 35mm |
|
||||
| 8 | ```screw(M2p5_pan_screw, 20)``` | Screw M2.5 pan x 20mm |
|
||||
| 4 | ```screw(M2p5_pan_screw, 25)``` | Screw M2.5 pan x 25mm |
|
||||
| 4 | ```screw(M2p5_pan_screw, 35)``` | Screw M2.5 pan x 35mm |
|
||||
@ -1822,7 +1833,7 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
|
||||
| 2 | ```green_terminal(gt_2p54, 4)``` | Terminal block 4 way 0.1" |
|
||||
| 1 | | USB A to Mini B lead |
|
||||
| 16 | ```washer(M2_washer)``` | Washer M2 x 5mm x 0.3mm |
|
||||
| 28 | ```washer(M2p5_washer)``` | Washer M2.5 x 5.9mm x 0.5mm |
|
||||
| 32 | ```washer(M2p5_washer)``` | Washer M2.5 x 5.9mm x 0.5mm |
|
||||
| 12 | ```washer(M3_washer)``` | Washer M3 x 7mm x 0.5mm |
|
||||
| 12 | ```washer(M4_washer)``` | Washer M4 x 9mm x 0.8mm |
|
||||
| 1 | ```pcb(ZC_A0591)``` | ZC-A0591 ULN2003 driver PCB |
|
||||
@ -1838,6 +1849,7 @@ PCBs and perfboard with optional components. The shape can be a rectangle with o
|
||||
| 4 | pcb_spacer25110_2.stl |
|
||||
| 4 | pcb_spacer25120_2.stl |
|
||||
| 4 | pcb_spacer25230.stl |
|
||||
| 4 | pcb_spacer25240.stl |
|
||||
| 4 | pcb_spacer2570.stl |
|
||||
| 4 | pcb_spacer2580.stl |
|
||||
| 4 | pcb_spacer2590.stl |
|
||||
@ -1927,6 +1939,7 @@ Pin headers and sockets, etc.
|
||||
|:--- |:--- |
|
||||
| ```box_header(type, cols = 1, rows = 1, smt = false, cutout = false)``` | Draw box header |
|
||||
| ```idc_transition(type, cols = 5, skip = [], cutout = false)``` | Draw IDC transition header |
|
||||
| ```jst_xh_header(type, pin_count, right_angle=false, colour, pin_colour)``` | Draw JST XH connector |
|
||||
| ```pin(type, length = undef)``` | Draw a header pin |
|
||||
| ```pin_header(type, cols = 1, rows = 1, smt = false, right_angle = false, cutout = false)``` | Draw pin header |
|
||||
| ```pin_socket(type, cols = 1, rows = 1, right_angle = false, height = 0, smt = false, cutout = false)``` | Draw pin socket |
|
||||
@ -2135,10 +2148,10 @@ Linear rails with carriages.
|
||||
### Modules
|
||||
| Module | Description |
|
||||
|:--- |:--- |
|
||||
| ```carriage(type, rail)``` | Draw the specified carriage |
|
||||
| ```carriage(type, rail, end_color = grey20, wiper_color = grey20)``` | Draw the specified carriage |
|
||||
| ```carriage_hole_positions(type)``` | Position children over screw holes |
|
||||
| ```rail(type, length)``` | Draw the specified rail |
|
||||
| ```rail_assembly(type, length, pos)``` | Rail and carriage assembly |
|
||||
| ```rail_assembly(type, length, pos, carriage_end_color = grey20, carriage_wiper_color = grey20)``` | Rail and carriage assembly |
|
||||
| ```rail_hole_positions(type, length, first = 0, screws = 100, both_ends = true)``` | Position children over screw holes |
|
||||
| ```rail_screws(type, length, thickness, screws = 100)``` | Place screws in the rail |
|
||||
|
||||
@ -2246,7 +2259,7 @@ Rocker switch. Also used for neon indicator in the same form factor.
|
||||
| ```rocker_height(type)``` | Body height |
|
||||
| ```rocker_part(type)``` | Part description |
|
||||
| ```rocker_pivot(type)``` | Pivot distance from the back of the flange |
|
||||
| ```rocker_slot_h(type)``` | Panel slow height |
|
||||
| ```rocker_slot_h(type)``` | Panel slot height |
|
||||
| ```rocker_slot_w(type)``` | Panel slot width |
|
||||
| ```rocker_spades(type)``` | Spade types and positions |
|
||||
| ```rocker_width(type)``` | Body width |
|
||||
@ -2254,7 +2267,7 @@ Rocker switch. Also used for neon indicator in the same form factor.
|
||||
### Modules
|
||||
| Module | Description |
|
||||
|:--- |:--- |
|
||||
| ```rocker(type)``` | Draw the specified rocker switch |
|
||||
| ```rocker(type, colour)``` | Draw the specified rocker switch |
|
||||
| ```rocker_hole(type, h = 0)``` | Make a hole to accept a rocker switch, by default 2D, set h for 3D |
|
||||
|
||||
![rockers](tests/png/rockers.png)
|
||||
@ -2262,8 +2275,8 @@ Rocker switch. Also used for neon indicator in the same form factor.
|
||||
### Vitamins
|
||||
| Qty | Module call | BOM entry |
|
||||
| ---:|:--- |:---|
|
||||
| 1 | ```rocker(neon_indicator)``` | Neon Indicator H8630FBNAL |
|
||||
| 1 | ```rocker(small_rocker)``` | Rocker Switch PRASA1-16F-BB0BW |
|
||||
| 2 | ```rocker(neon_indicator)``` | Neon Indicator H8630FBNAL |
|
||||
| 2 | ```rocker(small_rocker)``` | Rocker Switch PRASA1-16F-BB0BW |
|
||||
|
||||
|
||||
<a href="#top">Top</a>
|
||||
@ -2281,14 +2294,20 @@ Steel rods and studding with chamfered ends.
|
||||
### Modules
|
||||
| Module | Description |
|
||||
|:--- |:--- |
|
||||
| ```rod(d , l)``` | Draw a smooth rod with specified length and diameter |
|
||||
| ```studding(d , l)``` | Draw a threaded rod with specified length and diameter |
|
||||
| ```leadscrew(d , l, lead, starts, center = true)``` | Draw a leadscrew with specified diameter, length, lead and number of starts |
|
||||
| ```rod(d , l, center = true)``` | Draw a smooth rod with specified diameter and length |
|
||||
| ```studding(d , l, center = true)``` | Draw a threaded rod with specified diameter and length |
|
||||
|
||||
![rod](tests/png/rod.png)
|
||||
|
||||
### Vitamins
|
||||
| Qty | Module call | BOM entry |
|
||||
| ---:|:--- |:---|
|
||||
| 1 | ```leadscrew(10, 80, 8, 4)``` | Leadscrew 10 x 80mm, 8mm lead, 4 starts |
|
||||
| 1 | ```leadscrew(12, 80, 12, 4)``` | Leadscrew 12 x 80mm, 12mm lead, 4 starts |
|
||||
| 1 | ```leadscrew(16, 80, 16, 4)``` | Leadscrew 16 x 80mm, 16mm lead, 4 starts |
|
||||
| 1 | ```leadscrew(6, 80, 2, 1)``` | Leadscrew 6 x 80mm, 2mm lead, 1 starts |
|
||||
| 1 | ```leadscrew(8, 80, 8, 4)``` | Leadscrew 8 x 80mm, 8mm lead, 4 starts |
|
||||
| 1 | ```rod(10, 80)``` | Smooth rod 10mm x 80mm |
|
||||
| 1 | ```rod(12, 80)``` | Smooth rod 12mm x 80mm |
|
||||
| 1 | ```rod(16, 80)``` | Smooth rod 16mm x 80mm |
|
||||
@ -2358,17 +2377,17 @@ Machine screws and wood screws with various head styles.
|
||||
| Qty | Module call | BOM entry |
|
||||
| ---:|:--- |:---|
|
||||
| 1 | ```screw(No632_pan_screw, 30)``` | Screw 6-32 pan x 30mm |
|
||||
| 1 | ```screw(M2_cap_screw, 25)``` | Screw M2 cap x 25mm |
|
||||
| 1 | ```screw(M2_cs_cap_screw, 25)``` | Screw M2 cs cap x 25mm |
|
||||
| 1 | ```screw(M2p5_cap_screw, 25)``` | Screw M2.5 cap x 25mm |
|
||||
| 1 | ```screw(M2p5_pan_screw, 30)``` | Screw M2.5 pan x 30mm |
|
||||
| 1 | ```screw(M3_cap_screw, 25)``` | Screw M3 cap x 25mm |
|
||||
| 1 | ```screw(M3_cs_cap_screw, 25)``` | Screw M3 cs cap x 25mm |
|
||||
| 1 | ```screw(M3_dome_screw, 25)``` | Screw M3 dome x 25mm |
|
||||
| 1 | ```screw(M2_cap_screw, 10)``` | Screw M2 cap x 10mm |
|
||||
| 1 | ```screw(M2_cs_cap_screw, 10)``` | Screw M2 cs cap x 10mm |
|
||||
| 1 | ```screw(M2p5_cap_screw, 10)``` | Screw M2.5 cap x 10mm |
|
||||
| 1 | ```screw(M2p5_pan_screw, 10)``` | Screw M2.5 pan x 10mm |
|
||||
| 1 | ```screw(M3_cap_screw, 10)``` | Screw M3 cap x 10mm |
|
||||
| 1 | ```screw(M3_cs_cap_screw, 10)``` | Screw M3 cs cap x 10mm |
|
||||
| 1 | ```screw(M3_dome_screw, 10)``` | Screw M3 dome x 10mm |
|
||||
| 1 | ```screw(M3_grub_screw, 6)``` | Screw M3 grub x 6mm |
|
||||
| 1 | ```screw(M3_hex_screw, 30)``` | Screw M3 hex x 30mm |
|
||||
| 1 | ```screw(M3_low_cap_screw, 25)``` | Screw M3 low cap x 25mm |
|
||||
| 1 | ```screw(M3_pan_screw, 30)``` | Screw M3 pan x 30mm |
|
||||
| 1 | ```screw(M3_hex_screw, 10)``` | Screw M3 hex x 10mm |
|
||||
| 1 | ```screw(M3_low_cap_screw, 10)``` | Screw M3 low cap x 10mm |
|
||||
| 1 | ```screw(M3_pan_screw, 10)``` | Screw M3 pan x 10mm |
|
||||
| 1 | ```screw(M4_cap_screw, 25)``` | Screw M4 cap x 25mm |
|
||||
| 1 | ```screw(M4_cs_cap_screw, 25)``` | Screw M4 cs cap x 25mm |
|
||||
| 1 | ```screw(M4_dome_screw, 25)``` | Screw M4 dome x 25mm |
|
||||
@ -2383,8 +2402,8 @@ Machine screws and wood screws with various head styles.
|
||||
| 1 | ```screw(M6_pan_screw, 30)``` | Screw M6 pan x 30mm |
|
||||
| 1 | ```screw(M8_cap_screw, 35)``` | Screw M8 cap x 35mm |
|
||||
| 1 | ```screw(M8_hex_screw, 30)``` | Screw M8 hex x 30mm |
|
||||
| 1 | ```screw(No2_screw, 30)``` | Screw No2 pan wood x 30mm |
|
||||
| 1 | ```screw(No4_screw, 30)``` | Screw No4 pan wood x 30mm |
|
||||
| 1 | ```screw(No2_screw, 10)``` | Screw No2 pan wood x 10mm |
|
||||
| 1 | ```screw(No4_screw, 10)``` | Screw No4 pan wood x 10mm |
|
||||
| 1 | ```screw(No6_cs_screw, 30)``` | Screw No6 cs wood x 30mm |
|
||||
| 1 | ```screw(No6_screw, 30)``` | Screw No6 pan wood x 30mm |
|
||||
|
||||
@ -2544,7 +2563,7 @@ Filament spool models
|
||||
### Modules
|
||||
| Module | Description |
|
||||
|:--- |:--- |
|
||||
| ```spool(type)``` | Draw specified spool |
|
||||
| ```spool(type, filament_depth = 0, filament_colour = "white", filament_d = 3)``` | Draw specified spool with optional filament |
|
||||
|
||||
![spools](tests/png/spools.png)
|
||||
|
||||
@ -2672,7 +2691,7 @@ NEMA stepper motor model.
|
||||
| ```NEMA_length(type)``` | Body length |
|
||||
| ```NEMA_radius(type)``` | End cap radius |
|
||||
| ```NEMA_shaft_dia(type)``` | Shaft diameter |
|
||||
| ```NEMA_shaft_length(type)``` | Shaft length above the face |
|
||||
| ```NEMA_shaft_length(type)``` | Shaft length above the face, if a list then a leadscrew: length, lead, starts |
|
||||
| ```NEMA_width(type)``` | Width of the square face |
|
||||
|
||||
### Functions
|
||||
@ -2684,7 +2703,7 @@ NEMA stepper motor model.
|
||||
### Modules
|
||||
| Module | Description |
|
||||
|:--- |:--- |
|
||||
| ```NEMA(type)``` | Draw specified NEMA stepper motor |
|
||||
| ```NEMA(type, shaft_angle = 0)``` | Draw specified NEMA stepper motor |
|
||||
| ```NEMA_outline(type)``` | 2D outline |
|
||||
| ```NEMA_screw_positions(type, n = 4)``` | Positions children at the screw holes |
|
||||
| ```NEMA_screws(type, screw, n = 4, screw_length = 8, earth = undef)``` | Place screws and optional earth tag |
|
||||
@ -4093,7 +4112,7 @@ Knob with embedded hex head screw.
|
||||
### Modules
|
||||
| Module | Description |
|
||||
|:--- |:--- |
|
||||
| ```screw_knob(screw)``` | Generate the STL foe a knob to fit the specified hex screw |
|
||||
| ```screw_knob(screw)``` | Generate the STL for a knob to fit the specified hex screw |
|
||||
| ```screw_knob_assembly(screw, length)``` | Assembly with the screw in place |
|
||||
|
||||
![screw_knob](tests/png/screw_knob.png)
|
||||
@ -4431,6 +4450,8 @@ Maths utilities for manipulating vectors and matrices.
|
||||
### Functions
|
||||
| Function | Description |
|
||||
|:--- |:--- |
|
||||
| ```angle_between(v1, v2)``` | Return the angle between two vectors |
|
||||
| ```euler(R)``` | Convert a rotation matrix to a Euler rotation vector. |
|
||||
| ```identity(n, x = 1)``` | Construct an arbitrary size identity matrix |
|
||||
| ```reverse(v)``` | Reverse a vector |
|
||||
| ```rotate(a, v)``` | Generate a 4x4 rotation matrix, ```a``` can be a vector of three angles or a single angle around ```z```, or around axis ```v``` |
|
||||
@ -4441,6 +4462,7 @@ Maths utilities for manipulating vectors and matrices.
|
||||
| ```transpose(m)``` | Transpose an arbitrary size matrix |
|
||||
| ```unit(v)``` | Convert ```v``` to a unit vector |
|
||||
| ```vec3(v)``` | Return a 3 vector with the first three elements of ```v``` |
|
||||
| ```vec4(v)``` | Return a 4 vector with the first three elements of ```v``` |
|
||||
|
||||
![maths](tests/png/maths.png)
|
||||
|
||||
@ -4607,9 +4629,12 @@ An additional twist around the path can be specified. If the path is closed this
|
||||
| ```after(path1, path2)``` | Translate ```path2``` so its start meets the end of ```path1``` and then concatenate |
|
||||
| ```arc_points(r, a = [90, 0, 180], al = 90)``` | Generate the points of a circular arc |
|
||||
| ```before(path1, path2)``` | Translate ```path1``` so its end meets the start of ```path2``` and then concatenate |
|
||||
| ```circle_points(r = 1, z = 0)``` | Generate the points of a circle, setting z makes a single turn spiral |
|
||||
| ```cap(facets, segment = 0, end)``` | Create the mesh for an end cap |
|
||||
| ```circle_points(r = 1, z = 0, dir = -1)``` | Generate the points of a circle, setting z makes a single turn spiral |
|
||||
| ```helical_twist_per_segment(r, pitch, sides)``` | Calculate the twist around Z that rotate_from_to() introduces |
|
||||
| ```path_length(path, i = 0, length = 0)``` | Calculated the length along a path |
|
||||
| ```rectangle_points(w, h)``` | Generate the points of a rectangle |
|
||||
| ```skin_faces(points, npoints, facets, loop, offset = 0)``` | Create the mesh for the swept volume without end caps |
|
||||
| ```sweep(path, profile, loop = false, twist = 0)``` | Generate the point list and face list of the swept volume |
|
||||
|
||||
### Modules
|
||||
@ -4620,6 +4645,50 @@ An additional twist around the path can be specified. If the path is closed this
|
||||
![sweep](tests/png/sweep.png)
|
||||
|
||||
|
||||
<a href="#top">Top</a>
|
||||
|
||||
---
|
||||
<a name="Thread"></a>
|
||||
## Thread
|
||||
Utilities for making threads with sweep. They can be used to model screws, nuts, studding, leadscrews, etc, and also to make printed threads.
|
||||
|
||||
The ends can be tapered, flat or chamfered by setting the ```top``` and ```bot``` parameters to -1 for tapered, 0 for a flat cut and positive to
|
||||
specify a chamfer angle.
|
||||
|
||||
Threads are by default solid, so the male version is wrapped around a cylinder and the female inside a tube. This can be suppressed to just get the helix, for
|
||||
example to make a printed pot with a screw top lid.
|
||||
|
||||
Threads with a typical 60 degree angle appear too bright with OpenSCAD's primitive lighting model as they face towards the lights more than the top and sides of
|
||||
a cylinder. To get around this a colour can be passed to thread that is used to colour the cylinder and then toned down to colour the helix.
|
||||
|
||||
Making the ends requires a CGAL intersection, which make threads relatively slow. For this reason they are generally disabled when using the GUI but can
|
||||
be enabled by setting ```$show_threads``` to ```true```. When the tests are run, by default, threads are enabled only for things that feature them like screws.
|
||||
This behaviour can be changed by setting a ```SHOW_THREADS``` environment variable to ```false``` to disable all threads and ```true``` to enable all threads.
|
||||
The same variable also affects the generation of assembly diagrams.
|
||||
|
||||
Threads obey the $fn, $fa, $fs variables.
|
||||
|
||||
|
||||
[utils/thread.scad](utils/thread.scad) Implementation.
|
||||
|
||||
[tests/thread.scad](tests/thread.scad) Code for this example.
|
||||
|
||||
### Functions
|
||||
| Function | Description |
|
||||
|:--- |:--- |
|
||||
| ```metric_coarse_pitch(d)``` | Convert metric diameter to pitch |
|
||||
| ```thread_profile(h, crest, angle, overlap = 0.1)``` | Create thread profile path |
|
||||
|
||||
### Modules
|
||||
| Module | Description |
|
||||
|:--- |:--- |
|
||||
| ```female_metric_thread(d, pitch, length, center = true, top = -1, bot = -1, colour = undef)``` | Create female thread with metric profile |
|
||||
| ```male_metric_thread(d, pitch, length, center = true, top = -1, bot = -1, solid = true, colour = undef)``` | Create male thread with metric profile |
|
||||
| ```thread(dia, pitch, length, profile, center = true, top = -1, bot = -1, starts = 1, solid = true, female = false, colour = undef)``` | Create male or femail thread, ends can be tapered, chamfered or square |
|
||||
|
||||
![thread](tests/png/thread.png)
|
||||
|
||||
|
||||
<a href="#top">Top</a>
|
||||
|
||||
---
|
||||
|
@ -24,7 +24,7 @@ from __future__ import print_function
|
||||
|
||||
import subprocess, sys
|
||||
|
||||
def _run(args, silent):
|
||||
def run_list(args, silent = False):
|
||||
cmd = ["openscad"] + args
|
||||
if not silent:
|
||||
for arg in cmd:
|
||||
@ -39,7 +39,7 @@ def _run(args, silent):
|
||||
sys.exit(rc)
|
||||
|
||||
def run(*args):
|
||||
_run(list(args), False)
|
||||
run_list(list(args), False)
|
||||
|
||||
def run_silent(*args):
|
||||
_run(list(args), True);
|
||||
run_list(list(args), True);
|
||||
|
49
scripts/options.py
Normal file
@ -0,0 +1,49 @@
|
||||
#
|
||||
# NopSCADlib Copyright Chris Palmer 2020
|
||||
# nop.head@gmail.com
|
||||
# hydraraptor.blogspot.com
|
||||
#
|
||||
# This file is part of NopSCADlib.
|
||||
#
|
||||
# NopSCADlib is free software: you can redistribute it and/or modify it under the terms of the
|
||||
# GNU General Public License as published by the Free Software Foundation, either version 3 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# NopSCADlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with NopSCADlib.
|
||||
# If not, see <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
# Set command line options from enviroment variables and check if they have changed
|
||||
|
||||
import json, os, deps
|
||||
|
||||
def check_options(dir = '.'):
|
||||
global options, options_mtime
|
||||
options = { "show_threads": str(os.getenv("SHOW_THREADS")) }
|
||||
options_fname = dir + '/options.json'
|
||||
try:
|
||||
with open(options_fname) as json_file:
|
||||
last_options = json.load(json_file)
|
||||
except:
|
||||
last_options = {}
|
||||
if last_options != options:
|
||||
with open(options_fname, 'w') as outfile:
|
||||
json.dump(options, outfile, indent = 4)
|
||||
options_mtime = deps.mtime(options_fname)
|
||||
|
||||
def have_changed(changed, target):
|
||||
if not changed and deps.mtime(target) < options_mtime:
|
||||
return "command line options changed"
|
||||
return changed
|
||||
|
||||
def list():
|
||||
result = []
|
||||
for name in options.keys():
|
||||
value = options[name]
|
||||
if value != 'None':
|
||||
result.append('-D$' + name + '=' + value)
|
||||
return result
|
@ -27,6 +27,7 @@ import openscad
|
||||
import subprocess
|
||||
import bom
|
||||
import times
|
||||
import options
|
||||
import time
|
||||
import json
|
||||
import shutil
|
||||
@ -96,6 +97,7 @@ def tests(tests):
|
||||
index = {}
|
||||
bodies = {}
|
||||
times.read_times()
|
||||
options.check_options(deps_dir)
|
||||
#
|
||||
# Make cover pic if does not exist as very slow. Delete it to force an update.
|
||||
#
|
||||
@ -190,11 +192,12 @@ def tests(tests):
|
||||
oldest = png_name if mtime(png_name) < mtime(bom_name) else bom_name
|
||||
changed = check_deps(oldest, dname)
|
||||
changed = times.check_have_time(changed, scad_name)
|
||||
changed = options.have_changed(changed, oldest)
|
||||
if changed:
|
||||
print(changed)
|
||||
t = time.time()
|
||||
tmp_name = 'tmp.png'
|
||||
openscad.run("-D", "$bom=2", colour_scheme, "--projection=p", "--imgsize=%d,%d" % (w, h), "--camera=0,0,0,70,0,315,500", "--autocenter", "--viewall", "-d", dname, "-o", tmp_name, scad_name);
|
||||
openscad.run_list(options.list() + ["-D$bom=2", colour_scheme, "--projection=p", "--imgsize=%d,%d" % (w, h), "--camera=0,0,0,70,0,315,500", "--autocenter", "--viewall", "-d", dname, "-o", tmp_name, scad_name]);
|
||||
times.add_time(scad_name, t)
|
||||
do_cmd(["magick", tmp_name, "-trim", "-resize", "1000x600", "-bordercolor", background, "-border", "10", tmp_name])
|
||||
update_image(tmp_name, png_name)
|
||||
|
@ -28,6 +28,7 @@ import openscad
|
||||
from tests import do_cmd, update_image, colour_scheme, background
|
||||
import time
|
||||
import times
|
||||
import options
|
||||
from deps import *
|
||||
import os
|
||||
import json
|
||||
@ -102,6 +103,7 @@ def views(target, do_assemblies = None):
|
||||
os.makedirs(deps_dir)
|
||||
|
||||
times.read_times(target_dir)
|
||||
options.check_options(deps_dir)
|
||||
bounds_fname = top_dir + 'stls/bounds.json'
|
||||
with open(bounds_fname) as json_file:
|
||||
bounds_map = json.load(json_file)
|
||||
@ -154,7 +156,7 @@ def views(target, do_assemblies = None):
|
||||
f.write("use <%s/%s>\n" % (dir, filename))
|
||||
f.write("%s();\n" % module);
|
||||
#
|
||||
# Run openscad on th created file
|
||||
# Run openscad on the created file
|
||||
#
|
||||
dname = deps_name(deps_dir, filename)
|
||||
for explode in [0, 1]:
|
||||
@ -163,11 +165,12 @@ def views(target, do_assemblies = None):
|
||||
png_name = png_name.replace('_assembly', '_assembled')
|
||||
changed = check_deps(png_name, dname)
|
||||
changed = times.check_have_time(changed, png_name)
|
||||
changed = options.have_changed(changed, png_name)
|
||||
tmp_name = 'tmp.png'
|
||||
if changed:
|
||||
print(changed)
|
||||
t = time.time()
|
||||
openscad.run("-D$pose=1", "-D$explode=%d" % explode, colour_scheme, "--projection=p", "--imgsize=4096,4096", "--autocenter", "--viewall", "-d", dname, "-o", tmp_name, png_maker_name);
|
||||
openscad.run_list(options.list() + ["-D$pose=1", "-D$explode=%d" % explode, colour_scheme, "--projection=p", "--imgsize=4096,4096", "--autocenter", "--viewall", "-d", dname, "-o", tmp_name, png_maker_name]);
|
||||
times.add_time(png_name, t)
|
||||
do_cmd(["magick", tmp_name, "-trim", "-resize", "1004x1004", "-bordercolor", background, "-border", "10", tmp_name])
|
||||
update_image(tmp_name, png_name)
|
||||
|
@ -67,7 +67,7 @@ module belt_test() {
|
||||
translate([-25, 0])
|
||||
layout([for(b = belts) belt_width(b)], 10)
|
||||
rotate([0, 90, 0])
|
||||
belt(belts[$i], [[0, 0, 20], [0, 1, 20]]);
|
||||
belt(belts[$i], [[0, 0, 20], [0, 1, 20]], belt_colour = $i%2==0 ? grey90 : grey20, tooth_colour = $i%2==0 ? grey70 : grey50);
|
||||
}
|
||||
|
||||
if($preview)
|
||||
|
@ -35,4 +35,5 @@ module d_connectors()
|
||||
}
|
||||
|
||||
if($preview)
|
||||
d_connectors();
|
||||
let($show_threads = true)
|
||||
d_connectors();
|
||||
|
@ -37,4 +37,5 @@ module inserts() {
|
||||
}
|
||||
|
||||
if($preview)
|
||||
inserts();
|
||||
let($show_threads = true)
|
||||
inserts();
|
||||
|
@ -27,4 +27,5 @@ module leadnuts()
|
||||
leadnut(leadnuts[$i]);
|
||||
|
||||
if($preview)
|
||||
leadnuts();
|
||||
let($show_threads = true)
|
||||
leadnuts();
|
||||
|
@ -56,7 +56,7 @@ module maths() {
|
||||
//
|
||||
z = [0, 0, 1];
|
||||
v = cross(u, z);
|
||||
a = acos(u * z);
|
||||
a = angle_between(u, z);
|
||||
|
||||
|
||||
l = 20;
|
||||
@ -64,6 +64,11 @@ module maths() {
|
||||
translate_z(l)
|
||||
vflip()
|
||||
arrow(l);
|
||||
|
||||
//
|
||||
// Test Euler
|
||||
//
|
||||
assert(euler(rotate(r)) == r, "euler() failed");
|
||||
}
|
||||
|
||||
rotate(45)
|
||||
|
@ -22,13 +22,12 @@ use <../utils/layout.scad>
|
||||
include <../vitamins/screws.scad>
|
||||
|
||||
module nuts() {
|
||||
for(nyloc = [false, true])
|
||||
translate([0, nyloc ? 20 : 0])
|
||||
layout([for(n = nuts) 2 * nut_radius(n)], 5)
|
||||
nut(nuts[$i], nyloc);
|
||||
layout([for(n = nuts) 2 * nut_radius(n)], 5) let(n = nuts[$i]) {
|
||||
for(nyloc = [false, true])
|
||||
translate([0, nyloc ? 20 : 0])
|
||||
nut(n, nyloc);
|
||||
|
||||
translate([0, 40])
|
||||
layout([for(n = nuts) 2 * nut_radius(n)], 5) let(n = nuts[$i]) {
|
||||
translate([0, 40]) {
|
||||
if(n == M3_nut)
|
||||
nut(n, brass = true);
|
||||
|
||||
@ -45,7 +44,28 @@ module nuts() {
|
||||
if(n == M8_nut)
|
||||
#nut_trap(M8_cap_screw, n, h = 30);
|
||||
}
|
||||
|
||||
translate([0, 60]) {
|
||||
if(n == M3_nut)
|
||||
sliding_t_nut(M3_sliding_t_nut);
|
||||
|
||||
if(n == M4_nut)
|
||||
sliding_t_nut(M4_sliding_t_nut);
|
||||
|
||||
if(n == M5_nut)
|
||||
sliding_t_nut(M5_sliding_t_nut);
|
||||
}
|
||||
|
||||
translate([0, 80]) {
|
||||
if(n == M3_nut)
|
||||
hammer_nut(M3_hammer_nut);
|
||||
|
||||
if(n == M4_nut)
|
||||
hammer_nut(M4_hammer_nut);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if($preview)
|
||||
nuts();
|
||||
let($show_threads = true)
|
||||
nuts();
|
||||
|
@ -29,4 +29,5 @@ module opengrab_test() {
|
||||
}
|
||||
|
||||
if($preview)
|
||||
opengrab_test();
|
||||
let($show_threads = true)
|
||||
opengrab_test();
|
||||
|
@ -16,7 +16,7 @@
|
||||
// You should have received a copy of the GNU General Public License along with NopSCADlib.
|
||||
// If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
include <../lib.scad>
|
||||
include <../core.scad>
|
||||
use <../printed/pcb_mount.scad>
|
||||
|
||||
PI_IO = ["PI_IO", "PI_IO V2", 35.56, 25.4, 1.6, 0, 0, 0, "green", true, [],
|
||||
|
@ -26,4 +26,5 @@ module pillars()
|
||||
pillar(pillars[$i]);
|
||||
|
||||
if($preview)
|
||||
pillars();
|
||||
let($show_threads = true)
|
||||
pillars();
|
||||
|
Before Width: | Height: | Size: 102 KiB After Width: | Height: | Size: 102 KiB |
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 39 KiB |
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 50 KiB |
Before Width: | Height: | Size: 114 KiB After Width: | Height: | Size: 114 KiB |
Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 63 KiB |
Before Width: | Height: | Size: 94 KiB After Width: | Height: | Size: 101 KiB |
Before Width: | Height: | Size: 115 KiB After Width: | Height: | Size: 117 KiB |
Before Width: | Height: | Size: 114 KiB After Width: | Height: | Size: 118 KiB |
Before Width: | Height: | Size: 73 KiB After Width: | Height: | Size: 73 KiB |
Before Width: | Height: | Size: 75 KiB After Width: | Height: | Size: 75 KiB |
Before Width: | Height: | Size: 116 KiB After Width: | Height: | Size: 116 KiB |
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 42 KiB |
Before Width: | Height: | Size: 114 KiB After Width: | Height: | Size: 118 KiB |
Before Width: | Height: | Size: 147 KiB After Width: | Height: | Size: 149 KiB |
Before Width: | Height: | Size: 81 KiB After Width: | Height: | Size: 92 KiB |
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 60 KiB |
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 39 KiB |
Before Width: | Height: | Size: 78 KiB After Width: | Height: | Size: 82 KiB |
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 61 KiB |
Before Width: | Height: | Size: 98 KiB After Width: | Height: | Size: 107 KiB |
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 52 KiB |
Before Width: | Height: | Size: 109 KiB After Width: | Height: | Size: 112 KiB |
Before Width: | Height: | Size: 147 KiB After Width: | Height: | Size: 145 KiB |
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 97 KiB |
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 41 KiB |
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 44 KiB |
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 111 KiB |
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 67 KiB |
Before Width: | Height: | Size: 149 KiB After Width: | Height: | Size: 188 KiB |
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 75 KiB |
Before Width: | Height: | Size: 55 KiB After Width: | Height: | Size: 112 KiB |
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 82 KiB |
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 86 KiB |
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 63 KiB |
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 162 KiB |
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 50 KiB |
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 62 KiB |
Before Width: | Height: | Size: 98 KiB After Width: | Height: | Size: 92 KiB |
BIN
tests/png/thread.png
Normal file
After Width: | Height: | Size: 215 KiB |
Before Width: | Height: | Size: 106 KiB After Width: | Height: | Size: 111 KiB |
Before Width: | Height: | Size: 143 KiB After Width: | Height: | Size: 152 KiB |
Before Width: | Height: | Size: 92 KiB After Width: | Height: | Size: 93 KiB |
@ -34,7 +34,7 @@ module rails()
|
||||
nut = screw_nut(screw);
|
||||
washer = screw_washer(screw);
|
||||
|
||||
rail_assembly(rail, length, rail_travel(rail, length) / 2);
|
||||
rail_assembly(rail, length, rail_travel(rail, length) / 2, $i<2 ? grey20 : "green", $i<2 ? grey20 : "red");
|
||||
|
||||
rail_screws(rail, length, sheet + nut_thickness(nut, true) + washer_thickness(washer));
|
||||
|
||||
|
@ -21,9 +21,13 @@ use <../utils/layout.scad>
|
||||
|
||||
include <../vitamins/rockers.scad>
|
||||
|
||||
module rockers()
|
||||
layout([for(r = rockers) rocker_flange_w(r)], 5)
|
||||
module rockers() {
|
||||
layout([for(r = rockers) rocker_flange_w(r)], 5) {
|
||||
rocker(rockers[$i]);
|
||||
translate([0, 25])
|
||||
rocker(rockers[$i], $i==0 ? "red" : "green");
|
||||
}
|
||||
}
|
||||
|
||||
if($preview)
|
||||
rockers();
|
||||
|
@ -24,13 +24,23 @@ include <../vitamins/linear_bearings.scad>
|
||||
use <../vitamins/rod.scad>
|
||||
|
||||
module rods()
|
||||
layout([for(b = linear_bearings) 2 * bearing_radius(b)]) {
|
||||
layout([for(b = linear_bearings) 2 * bearing_radius(b)]) let(d = bearing_rod_dia(linear_bearings[$i])){
|
||||
|
||||
rod(bearing_rod_dia(linear_bearings[$i]), 80);
|
||||
rod(d, 80);
|
||||
|
||||
translate([0, 30])
|
||||
studding(bearing_rod_dia(linear_bearings[$i]), 80);
|
||||
studding(d, 80);
|
||||
|
||||
if(d >= 6)
|
||||
translate([0, 60]) {
|
||||
starts = d > 6 ? 4 : 1;
|
||||
pitch = d > 14 ? 4
|
||||
: d > 10 ? 3 : 2;
|
||||
let($show_threads = true)
|
||||
leadscrew(d, 80, starts * pitch, starts);
|
||||
}
|
||||
}
|
||||
|
||||
if($preview)
|
||||
rods();
|
||||
let($show_threads = true)
|
||||
rods();
|
||||
|
@ -25,13 +25,15 @@ for(y = [0 : len(screw_lists) -1])
|
||||
for(x = [0 : len(screw_lists[y]) -1]) {
|
||||
screw = screw_lists[y][x];
|
||||
if(screw) {
|
||||
length = screw_max_thread(screw)
|
||||
? screw_longer_than(screw_max_thread(screw) + 5)
|
||||
: screw_head_type(screw) == hs_grub ? 6 : 30;
|
||||
length = screw_head_type(screw) == hs_grub ? 6
|
||||
: screw_radius(screw) <= 1.5 ? 10
|
||||
: screw_max_thread(screw) ? screw_longer_than(screw_max_thread(screw) + 5)
|
||||
: 30;
|
||||
translate([x * 20, y * 20])
|
||||
screw(screw, length);
|
||||
}
|
||||
}
|
||||
|
||||
if($preview)
|
||||
screws();
|
||||
let($show_threads = true)
|
||||
screws();
|
||||
|
@ -23,9 +23,9 @@ use <../utils/layout.scad>
|
||||
include <../vitamins/spools.scad>
|
||||
|
||||
module spools()
|
||||
layout([for(s = spools) spool_height(s)], 100)
|
||||
layout([for(s = spools) spool_height(s)], 100) let(s = spools[$i])
|
||||
rotate([90, 0, 90])
|
||||
spool(spools[$i]);
|
||||
spool(s, filament_depth = spool_depth(s) / 2, filament_colour = [pp1_colour, pp2_colour, pp3_colour, pp4_colour][$i % 4], filament_d = $i ? 3 : 1.75);
|
||||
|
||||
if($preview)
|
||||
spools();
|
||||
|
@ -44,7 +44,7 @@ knot = [ for(i=[0:.2:359])
|
||||
(19*cos(3*i) + 40)*sin(2*i),
|
||||
19*sin(3*i) ] ];
|
||||
|
||||
sweep(knot, L_points, loop = true, twist = 0);
|
||||
sweep(knot, L_points, loop = true);
|
||||
|
||||
p = transform_points([[0,0,0], [20,0,5], [10,30,4], [0,0,0], [0,0,20]], scale(10));
|
||||
n = 100;
|
||||
|
52
tests/thread.scad
Normal file
@ -0,0 +1,52 @@
|
||||
//
|
||||
// NopSCADlib Copyright Chris Palmer 2020
|
||||
// nop.head@gmail.com
|
||||
// hydraraptor.blogspot.com
|
||||
//
|
||||
// This file is part of NopSCADlib.
|
||||
//
|
||||
// NopSCADlib is free software: you can redistribute it and/or modify it under the terms of the
|
||||
// GNU General Public License as published by the Free Software Foundation, either version 3 of
|
||||
// the License, or (at your option) any later version.
|
||||
//
|
||||
// NopSCADlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with NopSCADlib.
|
||||
// If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
include <../core.scad>
|
||||
use <../utils/thread.scad>
|
||||
|
||||
pitch = 2;
|
||||
starts = 4;
|
||||
|
||||
profile = thread_profile(pitch / 2, pitch * 0.366, 30);
|
||||
|
||||
module threads()
|
||||
for(female = [false, true]) translate([0, female ? -20 : 0]) {
|
||||
length = female ? 8 : 40;
|
||||
dia = female ? 8 : 8 - pitch;
|
||||
colour = female ? brass : silver;
|
||||
|
||||
thread(dia, starts * pitch, length, profile, starts = starts, top = 45, bot = 45, female = female, colour = colour);
|
||||
|
||||
color(colour)
|
||||
translate([20, 0])
|
||||
thread(dia, starts * pitch, length, profile, starts = starts, top = 0, bot = 0, female = female);
|
||||
|
||||
translate([40, 0])
|
||||
thread(dia, starts * pitch, length, profile, starts = starts, top = -1, bot = -1, female = female, colour = colour);
|
||||
|
||||
color(colour)
|
||||
translate([60, 0])
|
||||
thread(dia, 2 * pitch, length, profile, starts = 2, top = -1, bot = -1, female = female);
|
||||
|
||||
color(colour)
|
||||
translate([80, 0])
|
||||
thread(dia, pitch, length, profile, starts = 1, top = -1, bot = -1, female = female);
|
||||
}
|
||||
|
||||
let($show_threads = true)
|
||||
threads();
|
@ -27,4 +27,5 @@ module toggles()
|
||||
toggle(toggles[$i], 3);
|
||||
|
||||
if($preview)
|
||||
toggles();
|
||||
let($show_threads = true)
|
||||
toggles();
|
||||
|
@ -43,7 +43,7 @@ module ellipse(xr, yr) scale([1, yr / xr]) circle4n(xr);
|
||||
|
||||
module extrude_if(h, center = true) //! Extrudes 2D object to 3D when ```h``` is nonzero, otherwise leaves it 2D
|
||||
if(h)
|
||||
linear_extrude(height = h, center = center) // 3D
|
||||
linear_extrude(height = h, center = center, convexity = 2) // 3D
|
||||
children();
|
||||
else
|
||||
children(); // 2D
|
||||
|
@ -39,9 +39,9 @@ function rotate(a, v) = //! Generate a 4x4 rotation matrix, ```a``` can be a vec
|
||||
sy = sin(av[1]),
|
||||
sz = sin(av[2]))
|
||||
[
|
||||
[ cy * cz, cz * sx * sy - cx * sz, cx * cz * sy + sx * sz, 0],
|
||||
[ cy * sz, cx * cz + sx * sy * sz,-cz * sx + cx * sy * sz, 0],
|
||||
[-sy, cy * sx, cx * cy, 0],
|
||||
[ cy * cz, sx * sy * cz - cx * sz, cx * sy * cz + sx * sz, 0],
|
||||
[ cy * sz, sx * sy * sz + cx * cz, cx * sy * sz - sx * cz, 0],
|
||||
[-sy, sx * cy, cx * cy, 0],
|
||||
[ 0, 0, 0, 1]
|
||||
]
|
||||
: let(s = sin(a),
|
||||
@ -65,6 +65,7 @@ function scale(v) = let(s = is_list(v) ? v : [v, v, v]) //! Generate a 4x4 matr
|
||||
];
|
||||
|
||||
function vec3(v) = [v.x, v.y, v.z]; //! Return a 3 vector with the first three elements of ```v```
|
||||
function vec4(v) = [v.x, v.y, v.z, 1]; //! Return a 4 vector with the first three elements of ```v```
|
||||
function transform(v, m) = vec3(m * [v.x, v.y, v.z, 1]); //! Apply 4x4 transform to a 3 vector by extending it and cropping it again
|
||||
function transform_points(path, m) = [for(p = path) transform(p, m)]; //! Apply transform to a path
|
||||
function unit(v) = let(n = norm(v)) n ? v / n : v; //! Convert ```v``` to a unit vector
|
||||
@ -74,3 +75,11 @@ function transpose(m) = [ for(j = [0 : len(m[0]) - 1]) [ for(i = [0 : len(m) - 1
|
||||
function identity(n, x = 1) = [for(i = [0 : n - 1]) [for(j = [0 : n - 1]) i == j ? x : 0] ]; //! Construct an arbitrary size identity matrix
|
||||
|
||||
function reverse(v) = let(n = len(v) - 1) n < 0 ? [] : [for(i = [0 : n]) v[n - i]]; //! Reverse a vector
|
||||
|
||||
function angle_between(v1, v2) = acos(v1 * v2 / (norm(v1) * norm(v2))); //! Return the angle between two vectors
|
||||
|
||||
// https://www.gregslabaugh.net/publications/euler.pdf
|
||||
function euler(R) = let(ay = asin(-R[2][0]), cy = cos(ay)) //! Convert a rotation matrix to a Euler rotation vector.
|
||||
cy ? [ atan2(R[2][1] / cy, R[2][2] / cy), ay, atan2(R[1][0] / cy, R[0][0] / cy) ]
|
||||
: R[2][0] < 0 ? [atan2( R[0][1], R[0][2]), 180, 0]
|
||||
: [atan2(-R[0][1], -R[0][2]), -180, 0];
|
||||
|
@ -62,6 +62,7 @@ function rotate_from_to(a, b) =
|
||||
function calculate_twist(A, B) = let(D = transpose3(B) * A) atan2(D[1][0], D[0][0]);
|
||||
//
|
||||
// Compute a 4x3 matrix to orientate a frame of the sweep given the position and a 3x3 rotation matrix.
|
||||
// Note that the rotation matrix is transposed to allow post multiplication.
|
||||
//
|
||||
function orientate(p, r) =
|
||||
let(x = r[0], y = r[1], z = r[2])
|
||||
@ -79,12 +80,21 @@ function rot3_z(a) =
|
||||
[ [ c, -s, 0],
|
||||
[ s, c, 0],
|
||||
[ 0, 0, 1] ];
|
||||
|
||||
//
|
||||
// Calculate the unit tangent at a vertex given the indices before and after. One of these can be the same as i in the case
|
||||
// of the start and end of a non closed path.
|
||||
// of the start and end of a non closed path. Note that the edges are converted to unit vectors so that their relative lengths
|
||||
// don't affect the direction of the tangent.
|
||||
//
|
||||
function tangent(path, before, i, after) = unit(unit(path[after] - path[i]) - unit(path[before] - path[i]));
|
||||
function tangent(path, before, i, after) = unit(unit(path[i] - path[before]) + unit(path[after] - path[i]));
|
||||
//
|
||||
// Calculate the twist per segment caused by rotate_from_to() instead of a simple Euler rotation around Z.
|
||||
//
|
||||
function helical_twist_per_segment(r, pitch, sides) = //! Calculate the twist around Z that rotate_from_to() introduces
|
||||
let(step_angle = 360 / sides,
|
||||
lt = 2 * r * sin(step_angle), // length of tangent between two facets
|
||||
slope = atan(2 * pitch / sides / lt) // slope of tangents
|
||||
) step_angle * sin(slope); // angle tangent should rotate around z projected onto axis rotate_from_to() uses
|
||||
|
||||
//
|
||||
// Generate all the surface points of the swept volume.
|
||||
//
|
||||
@ -111,24 +121,28 @@ function skin_points(profile, path, loop, twist = 0) =
|
||||
each profile4 * orientate(path[i], rotations[i] * rot3_z(za))
|
||||
];
|
||||
|
||||
function cap(facets, segment = 0) = [for(i = [0 : facets - 1]) segment ? facets * segment + i : facets - 1 - i];
|
||||
function cap(facets, segment = 0, end) = //! Create the mesh for an end cap
|
||||
let(reverse = is_undef(end) ? segment : end)
|
||||
[for(i = [0 : facets - 1]) facets * segment + (reverse ? i : facets - 1 - i)];
|
||||
|
||||
function quad(p, a, b, c, d) = norm(p[a] - p[c]) > norm(p[b] - p[d]) ? [[b, c, d], [b, d, a]] : [[a, b, c], [a, c, d]];
|
||||
|
||||
function skin_faces(points, segs, facets, loop) = [for(i = [0 : facets - 1], s = [0 : segs - (loop ? 1 : 2)])
|
||||
each quad(points,
|
||||
s * facets + i,
|
||||
s * facets + (i + 1) % facets,
|
||||
((s + 1) % segs) * facets + (i + 1) % facets,
|
||||
((s + 1) % segs) * facets + i)];
|
||||
function skin_faces(points, npoints, facets, loop, offset = 0) = //! Create the mesh for the swept volume without end caps
|
||||
[for(i = [0 : facets - 1], s = [0 : npoints - (loop ? 1 : 2)])
|
||||
let(j = s + offset, k = loop ? (j + 1) % npoints : j + 1)
|
||||
each quad(points,
|
||||
j * facets + i,
|
||||
j * facets + (i + 1) % facets,
|
||||
k * facets + (i + 1) % facets,
|
||||
k * facets + i)];
|
||||
|
||||
function sweep(path, profile, loop = false, twist = 0) = //! Generate the point list and face list of the swept volume
|
||||
let(
|
||||
segments = len(path),
|
||||
npoints = len(path),
|
||||
facets = len(profile),
|
||||
points = skin_points(profile, path, loop, twist),
|
||||
skin_faces = skin_faces(points, segments, facets, loop),
|
||||
faces = loop ? skin_faces : concat([cap(facets)], skin_faces, [cap(facets, segments - 1)])
|
||||
skin_faces = skin_faces(points, npoints, facets, loop),
|
||||
faces = loop ? skin_faces : concat([cap(facets)], skin_faces, [cap(facets, npoints - 1)])
|
||||
) [points, faces];
|
||||
|
||||
module sweep(path, profile, loop = false, twist = 0) { //! Draw a polyhedron that is the swept volume
|
||||
@ -141,9 +155,9 @@ function path_length(path, i = 0, length = 0) = //! Calculated the length along
|
||||
i >= len(path) - 1 ? length
|
||||
: path_length(path, i + 1, length + norm(path[i + 1] - path[i]));
|
||||
|
||||
function circle_points(r = 1, z = 0) = //! Generate the points of a circle, setting z makes a single turn spiral
|
||||
function circle_points(r = 1, z = 0, dir = -1) = //! Generate the points of a circle, setting z makes a single turn spiral
|
||||
let(sides = r2sides(r))
|
||||
[for(i = [0 : sides - 1]) let(a = i * 360 / sides) [r * sin(a), r * cos(a), z * a / 360]];
|
||||
[for(i = [0 : sides - 1]) let(a = dir * i * 360 / sides) [r * cos(a), r * sin(a), z * i / sides]];
|
||||
|
||||
function rectangle_points(w, h) = [[-w/2, -h/2, 0], [-w/2, h/2, 0], [w/2, h/2, 0], [w/2, -h/2, 0]]; //! Generate the points of a rectangle
|
||||
|
||||
|
217
utils/thread.scad
Normal file
@ -0,0 +1,217 @@
|
||||
//
|
||||
// NopSCADlib Copyright Chris Palmer 2019
|
||||
// nop.head@gmail.com
|
||||
// hydraraptor.blogspot.com
|
||||
//
|
||||
// This file is part of NopSCADlib.
|
||||
//
|
||||
// NopSCADlib is free software: you can redistribute it and/or modify it under the terms of the
|
||||
// GNU General Public License as published by the Free Software Foundation, either version 3 of
|
||||
// the License, or (at your option) any later version.
|
||||
//
|
||||
// NopSCADlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with NopSCADlib.
|
||||
// If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
//
|
||||
//! Utilities for making threads with sweep. They can be used to model screws, nuts, studding, leadscrews, etc, and also to make printed threads.
|
||||
//!
|
||||
//! The ends can be tapered, flat or chamfered by setting the ```top``` and ```bot``` parameters to -1 for tapered, 0 for a flat cut and positive to
|
||||
//! specify a chamfer angle.
|
||||
//!
|
||||
//! Threads are by default solid, so the male version is wrapped around a cylinder and the female inside a tube. This can be suppressed to just get the helix, for
|
||||
//! example to make a printed pot with a screw top lid.
|
||||
//!
|
||||
//! Threads with a typical 60 degree angle appear too bright with OpenSCAD's primitive lighting model as they face towards the lights more than the top and sides of
|
||||
//! a cylinder. To get around this a colour can be passed to thread that is used to colour the cylinder and then toned down to colour the helix.
|
||||
//!
|
||||
//! Making the ends requires a CGAL intersection, which make threads relatively slow. For this reason they are generally disabled when using the GUI but can
|
||||
//! be enabled by setting ```$show_threads``` to ```true```. When the tests are run, by default, threads are enabled only for things that feature them like screws.
|
||||
//! This behaviour can be changed by setting a ```SHOW_THREADS``` environment variable to ```false``` to disable all threads and ```true``` to enable all threads.
|
||||
//! The same variable also affects the generation of assembly diagrams.
|
||||
//!
|
||||
//! Threads obey the $fn, $fa, $fs variables.
|
||||
//
|
||||
include <../core.scad>
|
||||
use <sweep.scad>
|
||||
use <maths.scad>
|
||||
use <tube.scad>
|
||||
|
||||
thread_colour_factor = 0.8; // 60 degree threads appear too bright due to the angle facing the light sources
|
||||
|
||||
function thread_profile(h, crest, angle, overlap = 0.1) = //! Create thread profile path
|
||||
let(base = crest + 2 * (h + overlap) * tan(angle / 2))
|
||||
[[-base / 2, -overlap, 0], [-crest / 2, h, 0], [crest / 2, h, 0], [base / 2, -overlap, 0]];
|
||||
|
||||
module thread(dia, pitch, length, profile, center = true, top = -1, bot = -1, starts = 1, solid = true, female = false, colour = undef) { //! Create male or femail thread, ends can be tapered, chamfered or square
|
||||
//
|
||||
// Apply colour if defined
|
||||
//
|
||||
module colour(factor) if(is_undef(colour)) children(); else color(colour * factor) children();
|
||||
//
|
||||
// Compress the profile to compensate for it being tilted by the helix angle
|
||||
//
|
||||
scale = cos(atan(pitch / (PI * dia)));
|
||||
sprofile = [for(p = profile) [p.x * scale, p.y, p.z]];
|
||||
//
|
||||
// Extract some properties from the profile, perhaps they should be stored in it.
|
||||
//
|
||||
h = max([for(p = sprofile) p.y]);
|
||||
maxx = max([for(p = sprofile) p.x]);
|
||||
minx = min([for(p = sprofile) p.x]);
|
||||
crest_xmax = max([for(p = sprofile) if(p.x != maxx) p.x]);
|
||||
crest_xmin = min([for(p = sprofile) if(p.x != minx) p.x]);
|
||||
//
|
||||
// If the ends don't taper we need an extra half turn past the ends to be cropped horizontally.
|
||||
//
|
||||
extra_top = top < 0 ? 0 : -minx / pitch;
|
||||
extra_bot = bot < 0 ? 0 : maxx / pitch;
|
||||
turns = length / pitch + extra_top + extra_bot;
|
||||
//
|
||||
// Generate the helix path, possibly with tapered ends
|
||||
//
|
||||
dir = female ? 1 : -1;
|
||||
r = dia / 2;
|
||||
sides = r2sides4n(r);
|
||||
step_angle = 360 / sides;
|
||||
segs = ceil(turns * sides);
|
||||
leadin = ceil(sides / starts);
|
||||
final = floor(turns * sides) - leadin;
|
||||
path = [for(i = [0 : segs],
|
||||
R = i < leadin && bot < 0 ? r + dir * (h - h * i / leadin)
|
||||
: i > final && top < 0 ? r + dir * h * (i - final) / leadin : r,
|
||||
a = i * step_angle - 360 * extra_bot)
|
||||
[R * cos(a), R * sin(a), a * pitch / 360]];
|
||||
//
|
||||
// Generate the skin vertices
|
||||
//
|
||||
facets = len(profile);
|
||||
twist = helical_twist_per_segment(r, pitch, sides);
|
||||
//
|
||||
// For female threads we need to invert the profile
|
||||
//
|
||||
iprofile = female ? reverse([for(p = sprofile) [p.x, -p.y, 0]]) : sprofile;
|
||||
//
|
||||
// If the bottom is tapered then the twist will be greater, so pre-twist the profile to get the straight bit at the correct angle
|
||||
//
|
||||
rprofile = bot < 0 ? transform_points(iprofile, rotate(-dir * (helical_twist_per_segment(r - h, pitch, sides) - twist) * sides / PI))
|
||||
: iprofile;
|
||||
points = skin_points(rprofile, path, false, twist * segs);
|
||||
//
|
||||
// To form the ends correctly we need to use intersection but it is very slow with the full thread so we just
|
||||
// intersect the start and the end and sweep the rest outside of the intersection.
|
||||
//
|
||||
top_chamfer_h = (top > 0 ? h * tan(top) : 0);
|
||||
bot_chamfer_h = (bot > 0 ? h * tan(bot) : 0);
|
||||
top_overlap = max( maxx, top_chamfer_h - crest_xmin) / pitch;
|
||||
bot_overlap = max(-minx, bot_chamfer_h + crest_xmax) / pitch;
|
||||
start = ceil(sides * (bot_overlap + extra_bot));
|
||||
end = segs - ceil(sides * (top_overlap + extra_top));
|
||||
|
||||
start_skin_faces = skin_faces(points, start + 1, facets, false);
|
||||
middle_skin_faces = skin_faces(points, end - start + 1, facets, false, start);
|
||||
end_skin_faces = skin_faces(points, segs - end + 1, facets, false, end);
|
||||
|
||||
start_faces = concat([cap(facets) ], start_skin_faces, [cap(facets, start)]);
|
||||
middle_faces = concat([cap(facets, start, false)], middle_skin_faces, [cap(facets, end)]);
|
||||
end_faces = concat([cap(facets, end, false)], end_skin_faces, [cap(facets, segs)]);
|
||||
|
||||
overlap = - profile[0].y;
|
||||
translate_z((center ? -length / 2 : 0)) {
|
||||
ends_faces = concat(start_faces, end_faces);
|
||||
for(i = [0 : starts - 1])
|
||||
colour(thread_colour_factor)
|
||||
rotate(360 * i / starts + (female ? 180 / starts : 0)) {
|
||||
render() intersection() {
|
||||
polyhedron(points, ends_faces);
|
||||
|
||||
len = length - 2 * eps;
|
||||
rotate_extrude()
|
||||
if(female) {
|
||||
difference() {
|
||||
translate([0, eps])
|
||||
square([r + h + overlap, len]);
|
||||
|
||||
if(top_chamfer_h)
|
||||
polygon([[0, length], [r, length], [r - h, length - top_chamfer_h], [0, length - top_chamfer_h]]);
|
||||
|
||||
if(bot_chamfer_h)
|
||||
polygon([[0, 0], [r, 0], [r - h, bot_chamfer_h], [0, bot_chamfer_h]]);
|
||||
}
|
||||
}
|
||||
else
|
||||
difference() {
|
||||
hull() {
|
||||
translate([0, eps])
|
||||
square([r, len]);
|
||||
|
||||
translate([0, bot_chamfer_h])
|
||||
square([r + h + overlap, len - top_chamfer_h - bot_chamfer_h]);
|
||||
}
|
||||
if(!solid)
|
||||
square([r - overlap, length]);
|
||||
}
|
||||
}
|
||||
|
||||
polyhedron(points, middle_faces);
|
||||
}
|
||||
|
||||
if(solid)
|
||||
colour(1)
|
||||
rotate(90)
|
||||
if(female)
|
||||
tube(or = r + (top < 0 || bot < 0 ? h : 0) + 2 * overlap, ir = r, h = length, center = false);
|
||||
else
|
||||
cylinder(d = dia, h = length);
|
||||
}
|
||||
}
|
||||
|
||||
module male_metric_thread(d, pitch, length, center = true, top = -1, bot = -1, solid = true, colour = undef) { //! Create male thread with metric profile
|
||||
H = pitch * sqrt(3) / 2;
|
||||
h = 5 * H / 8;
|
||||
minor_d = d - 2 * h;
|
||||
thread(minor_d, pitch, length, thread_profile(h, pitch / 8, 60), center, top, bot, solid = solid, colour = colour);
|
||||
}
|
||||
|
||||
module female_metric_thread(d, pitch, length, center = true, top = -1, bot = -1, colour = undef) { //! Create female thread with metric profile
|
||||
H = pitch * sqrt(3) / 2;
|
||||
h = 5 * H / 8;
|
||||
thread(d, pitch, length, thread_profile(h, pitch / 4, 60), center, top, bot, solid = false, female = true, colour = colour);
|
||||
}
|
||||
|
||||
function metric_coarse_pitch(d) //! Convert metric diameter to pitch
|
||||
= d == 1.6 ? 0.35 // M1.6
|
||||
: [0.4, // M2
|
||||
0.45,// M2.5
|
||||
0.5, // M3
|
||||
0.6, // M3.5
|
||||
0.7, // M4
|
||||
0,
|
||||
0.8, // M5
|
||||
0,
|
||||
1.0, // M6
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1.25, // M8
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1.5, // M10
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1.75, // M12
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0, // M14
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
2.0, // M16
|
||||
][d * 2 - 4];
|
@ -41,9 +41,7 @@ function no_point(str) = chr([for(c = str) if(c == ".") ord("p") else ord(c)]);
|
||||
// We model the belt path at the pitch radius of the pulleys and the pitch line of the belt to get an accurate length.
|
||||
// The belt is then drawn by offseting each side from the pitch line.
|
||||
//
|
||||
module belt(type, points, gap = 0, gap_pt = undef) { //! Draw a belt path given a set of points and pitch radii where the pulleys are. Closed loop unless a gap is specified
|
||||
belt_colour = grey20;
|
||||
tooth_colour = grey50;
|
||||
module belt(type, points, gap = 0, gap_pt = undef, belt_colour = grey20, tooth_colour = grey50) { //! Draw a belt path given a set of points and pitch radii where the pulleys are. Closed loop unless a gap is specified
|
||||
width = belt_width(type);
|
||||
pitch = belt_pitch(type);
|
||||
thickness = belt_thickness(type);
|
||||
|
@ -21,6 +21,7 @@
|
||||
//! D-connectors. Can be any number of ways, male or female, solder buckets, PCB mount or IDC, with or without pillars.
|
||||
//
|
||||
include <../core.scad>
|
||||
use <../utils/thread.scad>
|
||||
|
||||
d_pillar_color = grey90;
|
||||
d_plug_shell_color = grey80;
|
||||
@ -51,16 +52,24 @@ module d_pillar() { //! Draw a pillar for a D-connector
|
||||
height = 4.5;
|
||||
screw = 2.5;
|
||||
screw_length = 8;
|
||||
color(d_pillar_color) {
|
||||
translate_z(-screw_length)
|
||||
cylinder(d = screw, h = screw_length + 1);
|
||||
pitch = metric_coarse_pitch(screw);
|
||||
|
||||
translate_z(-screw_length)
|
||||
if(show_threads)
|
||||
male_metric_thread(screw, pitch, screw_length, false, top = 0, colour = d_pillar_color);
|
||||
else
|
||||
color(d_pillar_color)
|
||||
cylinder(d = screw, h = screw_length + 1);
|
||||
|
||||
color(d_pillar_color) {
|
||||
linear_extrude(height = height)
|
||||
difference() {
|
||||
circle(r = rad, $fn = 6);
|
||||
circle(d = screw);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(show_threads)
|
||||
female_metric_thread(screw, pitch, height, false, colour = d_pillar_color);
|
||||
}
|
||||
|
||||
module d_plug(type, socket = false, pcb = false, idc = false) { //! Draw specified D plug, which can be IDC, PCB or plain solder bucket
|
||||
|
@ -29,6 +29,10 @@ fused_spades2 = [[spade6p4, 13, -7, 0, 0],
|
||||
[spade4p8, 8.5, -7, -9, 90],
|
||||
[spade4p8, 8.5, 7, -9, 90]];
|
||||
|
||||
iec320c14FusedSwitchedSpades = [[spade4p8, 8.5, 7, 10, 0],
|
||||
[spade4p8, 8.5, 0, 20, 0],
|
||||
[spade4p8, 8.5, 9, -2, 0]];
|
||||
|
||||
inlet_spades = [[spade6p4, 9, -7, -5.5, 0],
|
||||
[spade6p4, 9, 7, -5.5, 0],
|
||||
[spade6p4, 9, 0, 5.5, 0]];
|
||||
@ -52,10 +56,11 @@ outlet_spades = [[spade4p8ll, 8, -7, -2, 90],
|
||||
// w h r t
|
||||
IEC_fused_inlet = ["IEC_fused_inlet", "IEC fused inlet JR-101-1F", M3_cs_cap_screw, 36, 27, 16, 31, 3, 28, 31, 2, 2.0, 30, 33, 4, 3.0, 44, 15, fused_spades, false ];
|
||||
IEC_fused_inlet2= ["IEC_fused_inlet2","IEC fused inlet old", M3_cs_cap_screw, 36, 27, 14, 31, 3, 28, 31, 2, 2.5, 30, 33, 4, 2.5, 44, 18, fused_spades2, false ];
|
||||
|
||||
IEC_320_C14_switched_fused_inlet = ["IEC_switched_fused_inlet", "IEC320 C14 switched fused inlet module",
|
||||
M3_cs_cap_screw, 40, 27, 16,46.8,3,28, 48, 2.4, 1.0, 33, 57, 4, 3.0, 48,16.5, iec320c14FusedSwitchedSpades, false ];
|
||||
IEC_inlet = ["IEC_inlet", "IEC inlet", M3_cs_cap_screw, 40, 28, 18, 20, 3, 28, 20.5, 4, 2.5, 37, 23, 1, 2.5, 48, 14, inlet_spades, false ];
|
||||
IEC_inlet_atx = ["IEC_inlet_atx", "IEC inlet for ATX", M3_cs_cap_screw, 40, 27, 18, 19, 3, 30.5, 22, 2, 2.0, 30.5, 22, 2, 4.0, 50, 15, atx_spades, false ];
|
||||
IEC_outlet = ["IEC_outlet", "IEC outlet RS 811-7193", M3_cs_cap_screw, 40, 32, 18, 24, 3, 28, 20.5, 2, 0.0, 29, 29, 2, 2.8, 50, 23, outlet_spades, true ];
|
||||
|
||||
iecs = [IEC_inlet, IEC_inlet_atx, IEC_fused_inlet, IEC_fused_inlet2, IEC_outlet];
|
||||
iecs = [IEC_inlet, IEC_inlet_atx, IEC_fused_inlet, IEC_fused_inlet2, IEC_320_C14_switched_fused_inlet, IEC_outlet];
|
||||
use <iec.scad>
|
||||
|
@ -22,6 +22,7 @@
|
||||
//
|
||||
include <../core.scad>
|
||||
use <../utils/quadrant.scad>
|
||||
use <../utils/thread.scad>
|
||||
|
||||
function insert_length(type) = type[1]; //! Length
|
||||
function insert_outer_d(type) = type[2]; //! Outer diameter at the top
|
||||
@ -45,17 +46,18 @@ module insert(type) { //! Draw specified insert
|
||||
|
||||
vitamin(str("insert(", type[0], "): Heatfit insert M", insert_screw_diameter(type)));
|
||||
$fn = 64;
|
||||
explode(20, offset =[0, 0, -5]) color(brass) translate_z(eps) {
|
||||
vflip(){
|
||||
r1 = insert_screw_diameter(type) / 2;
|
||||
r2 = insert_barrel_d(type) / 2;
|
||||
r3 = insert_ring3_d(type) / 2;
|
||||
r4 = insert_ring2_d(type) / 2;
|
||||
r5 = insert_outer_d(type) / 2;
|
||||
h1 = ring1_h;
|
||||
h2 = ring1_h + gap;
|
||||
h3 = ring1_h + gap + ring2_h;
|
||||
h4 = ring1_h + gap + ring2_h + gap;
|
||||
thread_d = insert_screw_diameter(type);
|
||||
explode(20, offset =[0, 0, -5]) translate_z(eps) vflip() {
|
||||
r1 = thread_d / 2;
|
||||
r2 = insert_barrel_d(type) / 2;
|
||||
r3 = insert_ring3_d(type) / 2;
|
||||
r4 = insert_ring2_d(type) / 2;
|
||||
r5 = insert_outer_d(type) / 2;
|
||||
h1 = ring1_h;
|
||||
h2 = ring1_h + gap;
|
||||
h3 = ring1_h + gap + ring2_h;
|
||||
h4 = ring1_h + gap + ring2_h + gap;
|
||||
color(brass)
|
||||
rotate_extrude()
|
||||
polygon([
|
||||
[r1, 0],
|
||||
@ -72,7 +74,9 @@ module insert(type) { //! Draw specified insert
|
||||
[r5, h1],
|
||||
[r5, 0],
|
||||
]);
|
||||
}
|
||||
|
||||
if(show_threads)
|
||||
female_metric_thread(thread_d, metric_coarse_pitch(thread_d), length, center = false, colour = brass);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,8 @@
|
||||
//! Nuts for leadscrews.
|
||||
//
|
||||
include <../core.scad>
|
||||
include <../utils/tube.scad>
|
||||
use <../utils/tube.scad>
|
||||
use <../utils/thread.scad>
|
||||
|
||||
function leadnut_bore(type) = type[2]; //! Thread size
|
||||
function leadnut_od(type) = type[3]; //! Outer diameter of the shank
|
||||
@ -33,6 +34,8 @@ function leadnut_holes(type) = type[8]; //! The number of screw hole
|
||||
function leadnut_hole_dia(type) = type[9]; //! The diameter of the screw holes
|
||||
function leadnut_hole_pitch(type) = type[10]; //! The radia pitch of the screw holes
|
||||
function leadnut_screw(type) = type[11]; //! The type of the fixing screws
|
||||
function leadnut_pitch(type) = type[12]; //! Screw pitch
|
||||
function leadnut_lead(type) = type[13]; //! Screw lead
|
||||
|
||||
function leadnut_shank(type) = leadnut_height(type) - leadnut_flange_t(type) - leadnut_flange_offset(type); //! The length of the shank below the flange
|
||||
|
||||
@ -47,11 +50,18 @@ module leadnut_screw_positions(type) { //! Position children at the screw holes
|
||||
|
||||
module leadnut(type) { //! Draw specified leadnut
|
||||
vitamin(str("leadnut(", type[0], "): ", type[1]));
|
||||
bore_r = (leadnut_bore(type) + 0.5) / 2;
|
||||
bore_d = leadnut_bore(type);
|
||||
bore_r = bore_d / 2;
|
||||
h = leadnut_height(type);
|
||||
pitch = leadnut_pitch(type);
|
||||
lead = leadnut_lead(type);
|
||||
|
||||
color("dimgrey") vflip()
|
||||
translate_z(-leadnut_flange_offset(type) - leadnut_flange_t(type)) {
|
||||
tube(or = leadnut_od(type) / 2, ir = bore_r, h = leadnut_height(type), center = false);
|
||||
tube(or = leadnut_od(type) / 2, ir = bore_r, h = h, center = false);
|
||||
|
||||
if(show_threads)
|
||||
thread(bore_d, lead, h, thread_profile(pitch / 2, pitch * 0.366, 30), false, starts = lead / pitch, female = true, solid = false);
|
||||
|
||||
translate_z(leadnut_flange_offset(type))
|
||||
linear_extrude(height = leadnut_flange_t(type))
|
||||
|
@ -17,8 +17,8 @@
|
||||
// If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
LSN8x2 = ["LSN8x2", "Leadscrew nut 8 x 2", 8, 10.2, 15, 22, 3.5, 1.5, 4, 3.5, 8, M3_cap_screw];
|
||||
LSN8x8 = ["LSN8x8", "Leadscrew nut 8 x 8 RobotDigg",8, 12.75,19, 25.4, 4.1, 0, 3, 3.5, 19.05/2, M3_cap_screw];
|
||||
LSN8x2 = ["LSN8x2", "Leadscrew nut 8 x 2", 8, 10.2, 15, 22, 3.5, 1.5, 4, 3.5, 8, M3_cap_screw, 2, 2];
|
||||
LSN8x8 = ["LSN8x8", "Leadscrew nut 8 x 8 RobotDigg",8, 12.75,19, 25.4, 4.1, 0, 3, 3.5, 19.05/2, M3_cap_screw, 2, 8];
|
||||
|
||||
leadnuts = [LSN8x2, LSN8x8];
|
||||
|
||||
|
@ -25,7 +25,10 @@
|
||||
include <../core.scad>
|
||||
use <washer.scad>
|
||||
use <screw.scad>
|
||||
use <../utils/fillet.scad>
|
||||
use <../utils/rounded_cylinder.scad>
|
||||
use <../utils/thread.scad>
|
||||
use <../utils/tube.scad>
|
||||
brass_colour = brass;
|
||||
|
||||
function nut_size(type) = type[1]; //! Diameter of the corresponding screw
|
||||
@ -37,7 +40,8 @@ function nut_trap_depth(type) = type[6]; //! Depth of nut trap
|
||||
function nut_flat_radius(type) = nut_radius(type) * cos(30); //! Radius across the flats
|
||||
|
||||
module nut(type, nyloc = false, brass = false, nylon = false) { //! Draw specified nut
|
||||
hole_rad = nut_size(type) / 2;
|
||||
thread_d = nut_size(type);
|
||||
hole_rad = thread_d / 2;
|
||||
outer_rad = nut_radius(type);
|
||||
thickness = nut_thickness(type);
|
||||
nyloc_thickness = nut_thickness(type, true);
|
||||
@ -45,18 +49,29 @@ module nut(type, nyloc = false, brass = false, nylon = false) { //! Draw specifi
|
||||
vitamin(str("nut(", type[0], arg(nyloc, false, "nyloc"), arg(brass, false, "brass"), arg(nylon, false, "nylon"),
|
||||
"): Nut M", nut_size(type), " x ", thickness, "mm ", desc));
|
||||
|
||||
explode(nyloc ? 10 : 0)
|
||||
color(brass ? brass_colour : nylon ? grey30: grey70) {
|
||||
colour = brass ? brass_colour : nylon ? grey30: grey70;
|
||||
explode(nyloc ? 10 : 0) {
|
||||
color(colour) {
|
||||
linear_extrude(height = thickness)
|
||||
difference() {
|
||||
circle(outer_rad, $fn = 6);
|
||||
|
||||
circle(hole_rad);
|
||||
}
|
||||
|
||||
if(nyloc)
|
||||
translate_z(-eps)
|
||||
rounded_cylinder(r = outer_rad * cos(30) , h = nyloc_thickness, r2 = (nyloc_thickness - thickness) / 2, ir = hole_rad);
|
||||
}
|
||||
|
||||
if(show_threads)
|
||||
female_metric_thread(thread_d, metric_coarse_pitch(thread_d), thickness, center = false, colour = colour);
|
||||
|
||||
if(nyloc)
|
||||
translate_z(thickness)
|
||||
color("royalblue")
|
||||
tube(or = thread_d / 2 + eps, ir = (thread_d * 0.8) / 2, h = (nyloc_thickness - thickness) * 0.8, center = false);
|
||||
}
|
||||
if($children)
|
||||
translate_z(nut_thickness(type, nyloc))
|
||||
children();
|
||||
@ -73,7 +88,8 @@ module nut_and_washer(type, nyloc) { //! Draw nut with corresponding washer
|
||||
}
|
||||
|
||||
module wingnut(type) { //! Draw a wingnut
|
||||
hole_rad = nut_size(type) / 2;
|
||||
thread_d = nut_size(type);
|
||||
hole_rad = thread_d / 2;
|
||||
bottom_rad = nut_radius(type);
|
||||
top_rad = type[4] / 2;
|
||||
thickness = nut_thickness(type);
|
||||
@ -87,27 +103,107 @@ module wingnut(type) { //! Draw a wingnut
|
||||
|
||||
vitamin(str("wingnut(", type[0], "): Wingnut M", nut_size(type)));
|
||||
|
||||
explode(10) color(grey70) {
|
||||
rotate_extrude()
|
||||
polygon([
|
||||
[hole_rad, 0],
|
||||
[bottom_rad, 0],
|
||||
[top_rad,, thickness],
|
||||
[hole_rad, thickness]
|
||||
]);
|
||||
for(rot = [0, 180])
|
||||
rotate([90, 0, rot]) linear_extrude(height = wing_thickness, center = true)
|
||||
hull() {
|
||||
translate([wing_span / 2 - wing_width / 2, wing_height - wing_width / 2])
|
||||
circle(wing_width / 2);
|
||||
polygon([
|
||||
[bottom_rad * cos(top_angle) - eps, 0],
|
||||
[wing_span / 2 - wing_width / 2, wing_height - wing_width / 2],
|
||||
[top_rad * cos(top_angle) - eps, thickness],
|
||||
]);
|
||||
}
|
||||
colour = silver;
|
||||
explode(10) {
|
||||
color(colour) {
|
||||
rotate_extrude()
|
||||
polygon([
|
||||
[hole_rad, 0],
|
||||
[bottom_rad, 0],
|
||||
[top_rad,, thickness],
|
||||
[hole_rad, thickness]
|
||||
]);
|
||||
for(rot = [0, 180])
|
||||
rotate([90, 0, rot]) linear_extrude(height = wing_thickness, center = true)
|
||||
hull() {
|
||||
translate([wing_span / 2 - wing_width / 2, wing_height - wing_width / 2])
|
||||
circle(wing_width / 2);
|
||||
polygon([
|
||||
[bottom_rad * cos(top_angle) - eps, 0],
|
||||
[wing_span / 2 - wing_width / 2, wing_height - wing_width / 2],
|
||||
[top_rad * cos(top_angle) - eps, thickness],
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
if(show_threads)
|
||||
female_metric_thread(thread_d, metric_coarse_pitch(thread_d), thickness, center = false, colour = colour);
|
||||
}
|
||||
}
|
||||
|
||||
module sliding_t_nut(type) {
|
||||
vitamin(str("sliding_t_nut(", type[0], "): Nut M", nut_size(type), " sliding T"));
|
||||
|
||||
size = [type[7], type[2], nut_thickness(type)];
|
||||
tabSizeY1 = type[8];
|
||||
tabSizeY2 = type[9];
|
||||
tabSizeZ = type[10];
|
||||
holeRadius = nut_size(type) / 2;
|
||||
|
||||
if($preview)
|
||||
color(grey80)
|
||||
extrusionSlidingNut(size, tabSizeY1, tabSizeY2, tabSizeZ, holeRadius);
|
||||
|
||||
}
|
||||
|
||||
module hammer_nut(type) {
|
||||
vitamin(str("hammer_nut(", type[0], "): Nut M", nut_size(type), " hammer"));
|
||||
|
||||
size = [type[7], type[2], nut_thickness(type)];
|
||||
tabSizeY1 = type[8];
|
||||
tabSizeY2 = type[9];
|
||||
tabSizeZ = type[10];
|
||||
holeRadius = nut_size(type) / 2;
|
||||
|
||||
if($preview)
|
||||
color(grey80)
|
||||
extrusionSlidingNut(size, tabSizeY1, tabSizeY2, tabSizeZ, holeRadius, 0, hammerNut = true);
|
||||
|
||||
}
|
||||
|
||||
module extrusionSlidingNut(size, tabSizeY1, tabSizeY2, tabSizeZ, holeRadius, holeOffset = 0, hammerNut = false) {
|
||||
// center section
|
||||
linear_extrude(size[2] - tabSizeZ)
|
||||
difference() {
|
||||
square([size[0], size[1]], center = true);
|
||||
if(hammerNut) {
|
||||
translate([size[0] / 2, size[1] / 2])
|
||||
rotate(180)
|
||||
fillet(1);
|
||||
translate([-size[0] / 2, -size[1] / 2])
|
||||
fillet(1);
|
||||
}
|
||||
if(holeRadius)
|
||||
translate([holeOffset, 0])
|
||||
circle(holeRadius);
|
||||
}
|
||||
translate_z(size[2] - tabSizeZ)
|
||||
linear_extrude(tabSizeZ)
|
||||
difference() {
|
||||
square([size[0], tabSizeY2], center = true);
|
||||
if(holeRadius)
|
||||
translate([holeOffset, 0])
|
||||
circle(holeRadius);
|
||||
}
|
||||
|
||||
thread_d = 2 * holeRadius;
|
||||
if(show_threads)
|
||||
translate([holeOffset, 0])
|
||||
female_metric_thread(thread_d, metric_coarse_pitch(thread_d), size[2], center = false);
|
||||
|
||||
// add the side tabs
|
||||
for(m = [0, 1])
|
||||
mirror([0, m, 0])
|
||||
translate([0, tabSizeY2 / 2, size[2] - tabSizeZ]) {
|
||||
cubeZ = 1;
|
||||
translate([-size[0] / 2, 0, 0])
|
||||
cube([size[0], (tabSizeY1 - tabSizeY2) / 2, cubeZ]);
|
||||
translate_z(cubeZ)
|
||||
rotate([0, -90, 0])
|
||||
right_triangle(tabSizeZ - cubeZ, (tabSizeY1 - tabSizeY2) / 2, size[0], center = true);
|
||||
}
|
||||
}
|
||||
|
||||
function nut_trap_radius(nut, horizontal = false) = nut_radius(nut) + (horizontal ? layer_height / 4 : 0); //! Radius across the corners of a nut trap
|
||||
function nut_trap_flat_radius(nut, horizontal = false) = nut_trap_radius(nut, horizontal) * cos(30); //! Radius across the flats of a nut trap
|
||||
|
||||
|
@ -51,6 +51,13 @@ toggle_nut = ["toggle_nut", 6.1, 9.2, 1.5, 1.5, M6_washer, 1.5];
|
||||
|
||||
M4_wingnut = ["M4_wingnut", 4, 10, 3.75,8, M4_washer, 0, 22, 10, 6, 3];
|
||||
|
||||
// sx ty1 ty2 tz
|
||||
M3_sliding_t_nut = ["M3_sliding_t_nut", 3, 6, 4.0, 0, M3_washer, 0, 10, 10, 6, 3];
|
||||
M4_sliding_t_nut = ["M4_sliding_t_nut", 4, 6, 4.5, 0, M4_washer, 0, 11, 10, 6, 3.25];
|
||||
M5_sliding_t_nut = ["M5_sliding_t_nut", 5, 6, 4.5, 0, M5_washer, 0, 11, 10, 7, 3.25];
|
||||
M3_hammer_nut = ["M3_hammer_nut", 3, 6, 4.0, 0, M3_washer, 0, 5.5, 10, 6, 2.75];
|
||||
M4_hammer_nut = ["M4_hammer_nut", 4, 6, 4.5, 0, M4_washer, 0, 5.5, 10, 6, 3.25];
|
||||
|
||||
nuts = [M2_nut, M2p5_nut, M3_nut, M4_nut, M5_nut, M6_nut, M8_nut];
|
||||
|
||||
use <nut.scad>
|
||||
|
@ -23,6 +23,7 @@
|
||||
//! A permanent magnet that can be magnatized and de-magnatized electronically.
|
||||
//
|
||||
include <../core.scad>
|
||||
use <../utils/thread.scad>
|
||||
|
||||
pitch = 33.8;
|
||||
width = 40;
|
||||
@ -64,15 +65,20 @@ module opengrab() { //! Draw OpenGrab module
|
||||
translate_z(depth - pillar - pcb / 2)
|
||||
cube([width, width, pcb], center = true);
|
||||
|
||||
color(brass)
|
||||
translate_z(1)
|
||||
opengrab_hole_positions()
|
||||
|
||||
translate_z(1)
|
||||
opengrab_hole_positions() {
|
||||
color(brass)
|
||||
linear_extrude(height = depth - 1)
|
||||
difference() {
|
||||
circle(d = 4.7 / cos(30), $fn = 6);
|
||||
|
||||
circle(r = 3/2);
|
||||
}
|
||||
|
||||
if(show_threads)
|
||||
female_metric_thread(3, metric_coarse_pitch(3), depth - 1, center = false, colour = brass);
|
||||
}
|
||||
}
|
||||
|
||||
module opengrab_target() { //! Draw OpenGrab target
|
||||
|
@ -201,6 +201,13 @@ module jack(cutout = false) { //! Draw 3.5mm jack
|
||||
}
|
||||
}
|
||||
|
||||
module buzzer(height, diameter, colour) { //! Draw PCB buzzer with specified height, diameter and color
|
||||
color (colour)
|
||||
tube(or = diameter / 2, ir = height > 5 ? 1 : 0.75, h = height);
|
||||
color("white")
|
||||
cylinder(d = 2, h = max(height - 3 , 0.5));
|
||||
}
|
||||
|
||||
function hdmi_depth(type) = type[2]; //! Front to back depth
|
||||
function hdmi_width1(type) = type[3]; //! Inside width at the top
|
||||
function hdmi_width2(type) = type[4]; //! Inside width at the bottom
|
||||
@ -711,6 +718,7 @@ module pcb_component(comp, cutouts = false, angle = undef) { //! Draw pcb compon
|
||||
if(show(comp, "usb_Ax2")) usb_Ax2(cutouts);
|
||||
if(show(comp, "usb_uA")) usb_uA(cutouts);
|
||||
if(show(comp, "usb_B")) usb_B(cutouts);
|
||||
if(show(comp, "buzzer")) buzzer(param(4, 9), param(5, 12), param(6, grey20));
|
||||
if(show(comp, "jack")) jack(cutouts);
|
||||
if(show(comp, "barrel_jack")) barrel_jack(cutouts);
|
||||
if(show(comp, "hdmi")) hdmi(hdmi_full, cutouts);
|
||||
@ -719,6 +727,7 @@ module pcb_component(comp, cutouts = false, angle = undef) { //! Draw pcb compon
|
||||
if(show(comp, "flat_flex")) flat_flex(cutouts);
|
||||
if(show(comp, "D_plug")) if(!cutouts) translate_z(d_pcb_offset(comp[4])) d_plug(comp[4], pcb = true);
|
||||
if(show(comp, "molex_hdr")) if(!cutouts) molex_254(comp[4]);
|
||||
if(show(comp, "jst_xh")) if(!cutouts) jst_xh_header(jst_xh_header, comp[4], param(5, false), param(6, "white"), param(7, undef));
|
||||
if(show(comp, "term254")) if(!cutouts) green_terminal(gt_2p54,comp[4], comp[5]);
|
||||
if(show(comp, "gterm35")) if(!cutouts) green_terminal(gt_3p5, comp[4], comp[5]);
|
||||
if(show(comp, "gterm635")) if(!cutouts) green_terminal(gt_6p35, comp[4], comp[5]);
|
||||
|
@ -21,6 +21,7 @@
|
||||
//! Threaded pillars. Each end can be male or female.
|
||||
//
|
||||
include <../core.scad>
|
||||
use <../utils/thread.scad>
|
||||
|
||||
function pillar_name(type) = type[1]; //! Name of part
|
||||
function pillar_thread(type) = type[2]; //! Thread diameter
|
||||
@ -41,30 +42,53 @@ module pillar(type) { //! Draw specified pillar
|
||||
sex = str(sex(pillar_bot_thread(type)),"/", sex(pillar_top_thread(type)));
|
||||
height = pillar_height(type);
|
||||
thread_d = pillar_thread(type);
|
||||
bot_thread_l = pillar_bot_thread(type);
|
||||
top_thread_l = pillar_top_thread(type);
|
||||
thread_colour = pillar_i_colour(type);
|
||||
pitch = metric_coarse_pitch(thread_d);
|
||||
|
||||
vitamin(str("pillar(", type[0], "): Pillar ", pillar_name(type), " ", sex, " M", thread_d, "x", height));
|
||||
|
||||
if(bot_thread_l > 0)
|
||||
translate_z(-bot_thread_l + eps)
|
||||
if(show_threads)
|
||||
male_metric_thread(thread_d, pitch, bot_thread_l, false, top = 0, colour = thread_colour);
|
||||
else
|
||||
color(thread_colour)
|
||||
cylinder(h = bot_thread_l, d = thread_d);
|
||||
|
||||
if(top_thread_l > 0)
|
||||
translate_z(height - eps)
|
||||
if(show_threads)
|
||||
male_metric_thread(thread_d, pitch, top_thread_l, false, bot = 0, colour = thread_colour);
|
||||
else
|
||||
color(thread_colour)
|
||||
cylinder(h = top_thread_l, d = thread_d);
|
||||
|
||||
color(pillar_i_colour(type)) {
|
||||
if(pillar_bot_thread(type) > 0)
|
||||
translate_z(-pillar_bot_thread(type))
|
||||
cylinder(h = pillar_bot_thread(type) + eps, d = pillar_thread(type));
|
||||
|
||||
if(pillar_top_thread(type) > 0)
|
||||
translate_z(height - eps)
|
||||
cylinder(h = pillar_top_thread(type) + eps, d = pillar_thread(type));
|
||||
|
||||
linear_extrude(height = height)
|
||||
difference() {
|
||||
circle(d = pillar_id(type), $fn = fn(pillar_ifn(type)));
|
||||
circle(d = pillar_thread(type));
|
||||
circle(d = thread_d);
|
||||
}
|
||||
|
||||
top = height + min(pillar_top_thread(type), 0);
|
||||
bot = -min(pillar_bot_thread(type), 0);
|
||||
top = height + min(top_thread_l, 0);
|
||||
bot = -min(bot_thread_l, 0);
|
||||
|
||||
translate_z(bot)
|
||||
cylinder(h = top - bot, d = pillar_thread(type) + eps);
|
||||
cylinder(h = top - bot, d = thread_d + eps);
|
||||
}
|
||||
|
||||
if(show_threads) {
|
||||
if(top_thread_l < 0)
|
||||
translate_z(height)
|
||||
vflip()
|
||||
female_metric_thread(thread_d, pitch, -top_thread_l, false, colour = thread_colour);
|
||||
|
||||
if(bot_thread_l < 0)
|
||||
female_metric_thread(thread_d, pitch, -bot_thread_l, false, colour = thread_colour);
|
||||
}
|
||||
|
||||
if(pillar_od(type) > pillar_id(type))
|
||||
color(pillar_o_colour(type)) linear_extrude(height = height)
|
||||
difference() {
|
||||
|
@ -30,8 +30,8 @@
|
||||
// d r r d d
|
||||
//
|
||||
M2x16_brass_pillar = ["M2x16_brass_pillar", "nurled", 2, 16, 3.17, 3.17, 0, 0, brass, brass, 3,-3];
|
||||
M3x13_hex_pillar = ["M3x13_hex_pillar", "hex", 3, 13, 5/cos(30), 5/cos(30), 6, 6, "silver", "silver", -6, 6];
|
||||
M3x20_hex_pillar = ["M3x20_hex_pillar", "hex", 3, 20, 5/cos(30), 5/cos(30), 6, 6, "silver", "silver", -8, 8];
|
||||
M3x13_hex_pillar = ["M3x13_hex_pillar", "hex", 3, 13, 5/cos(30), 5/cos(30), 6, 6, "silver", silver, -6, 6];
|
||||
M3x20_hex_pillar = ["M3x20_hex_pillar", "hex", 3, 20, 5/cos(30), 5/cos(30), 6, 6, "silver", silver, -8, 8];
|
||||
M3x20_nylon_pillar = ["M3x20_nylon_pillar", "nylon", 3, 20, 8, 5/cos(30), 0, 6, "white", brass, -6, 6];
|
||||
M4x17_nylon_pillar = ["M4x17_nylon_pillar", "nylon", 4, 20, 8, 5/cos(30), 0, 6, "white", brass, -6, 6];
|
||||
M3x20_nylon_hex_pillar = ["M3x20_nylon_hex_pillar", "hex nylon", 3, 20, 8/cos(30), 8/cos(30), 6, 6, grey20, grey20, -6, 6];
|
||||
|
@ -205,3 +205,71 @@ module pin_socket(type, cols = 1, rows = 1, right_angle = false, height = 0, smt
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module jst_xh_header(type, pin_count, right_angle=false, colour, pin_colour) { //! Draw JST XH connector
|
||||
colour = colour ? colour : hdr_base_colour(type);
|
||||
pin_colour = pin_colour ? pin_colour : hdr_pin_colour(type);
|
||||
sizeY = 5.75;
|
||||
pitch = hdr_pitch(type);
|
||||
|
||||
module jst_xh_socket(type, pin_count) {
|
||||
socketSizeZ = hdr_socket_depth(type);
|
||||
pinOffsetX = 2.45;
|
||||
sizeY = 5.75;
|
||||
wallThickness = 0.8;
|
||||
size = [pinOffsetX * 2 + (pin_count - 1) * pitch, sizeY, socketSizeZ];
|
||||
translate([-size[0] / 2, -size[1] / 2, 0]) {
|
||||
// the base
|
||||
cube([size[0], size[1], wallThickness]);
|
||||
// the three full sides
|
||||
translate([0, size[1] - wallThickness, 0])
|
||||
cube([size[0], wallThickness, size[2]]);
|
||||
cube([wallThickness, size[1], size[2]]);
|
||||
translate([size[0] - wallThickness, 0, 0])
|
||||
cube([wallThickness, size[1], size[2]]);
|
||||
// the sides with cutouts
|
||||
cube([size[0], wallThickness, 2]);
|
||||
cutoutWidth = 1;
|
||||
cutoutOffset = pinOffsetX - cutoutWidth / 2;
|
||||
cube([cutoutOffset, wallThickness, size[2]]);
|
||||
translate([size[0] - cutoutOffset, 0, 0])
|
||||
cube([cutoutOffset, wallThickness, size[2]]);
|
||||
cube([cutoutOffset, wallThickness, size[2]]);
|
||||
translate([size[0]-cutoutOffset, 0, 0])
|
||||
cube([cutoutOffset, wallThickness, size[2]]);
|
||||
translate([cutoutOffset + cutoutWidth, 0, 0])
|
||||
cube([size[0] - 2 * (cutoutWidth + cutoutOffset), wallThickness, size[2]]);
|
||||
}
|
||||
} // end module
|
||||
|
||||
|
||||
color(colour)
|
||||
if(right_angle)
|
||||
translate([0, -1, sizeY / 2])
|
||||
rotate([-90, 0, 180])
|
||||
jst_xh_socket(type, pin_count);
|
||||
else
|
||||
jst_xh_socket(type, pin_count);
|
||||
|
||||
color(pin_colour)
|
||||
for(x = [0 : pin_count - 1]) {
|
||||
pinWidth = hdr_pin_width(type);
|
||||
verticalPinLength = right_angle ? hdr_pin_below(type) + sizeY / 2 : hdr_pin_length(type);
|
||||
translate([pitch * (x - (pin_count - 1) / 2), 0, 0]) {
|
||||
pin(type, verticalPinLength);
|
||||
|
||||
if(right_angle) {
|
||||
translate([0, -pinWidth / 2, sizeY / 2 - pinWidth / 2])
|
||||
rotate([0, -90, 0])
|
||||
rotate_extrude(angle = 90, $fn = 32)
|
||||
translate([0, -pinWidth / 2])
|
||||
square(pinWidth);
|
||||
|
||||
translate([0, -sizeY / 2 - 3 * pinWidth / 4, sizeY / 2])
|
||||
rotate([90,0,0])
|
||||
pin(type, hdr_pin_length(type) - hdr_pin_below(type));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
// c
|
||||
//
|
||||
2p54header = ["2p54header", 2.54, 11.6, 3.2, 0.66, "gold", grey20, 8.5];
|
||||
jst_xh_header = ["JST XH header",2.5,10,3.4, 0.64, "gold", grey90, 7];
|
||||
|
||||
pin_headers = [ 2p54header ];
|
||||
|
||||
|
@ -65,7 +65,7 @@ module carriage_hole_positions(type) { //! Position children over screw holes
|
||||
children();
|
||||
}
|
||||
|
||||
module carriage(type, rail) { //! Draw the specified carriage
|
||||
module carriage(type, rail, end_color = grey20, wiper_color = grey20) { //! Draw the specified carriage
|
||||
total_l = carriage_length(type);
|
||||
block_l = carriage_block_length(type);
|
||||
block_w = carriage_width(type);
|
||||
@ -100,19 +100,30 @@ module carriage(type, rail) { //! Draw the specified carriage
|
||||
carriage_hole_positions(type)
|
||||
circle(screw_pilot_hole(screw));
|
||||
}
|
||||
|
||||
}
|
||||
color(grey20)
|
||||
for(end = [-1, 1])
|
||||
translate([end * (block_l / 2 + end_l / 2), 0])
|
||||
rotate([90, 0, 90])
|
||||
linear_extrude(height = end_l, center = true)
|
||||
difference() {
|
||||
translate([-end_w / 2, carriage_clearance(type)])
|
||||
square([end_w, end_h]);
|
||||
|
||||
cutout();
|
||||
}
|
||||
module carriage_end(type, end_w, end_h, end_l) {
|
||||
wiper_length = 0.5;
|
||||
color(wiper_color) translate_z(-end_l/2) linear_extrude(wiper_length)
|
||||
difference() {
|
||||
translate([-end_w/2, carriage_clearance(type)])
|
||||
square([end_w, end_h]);
|
||||
cutout();
|
||||
}
|
||||
color(end_color) translate_z(wiper_length-end_l/2) linear_extrude(end_l-wiper_length)
|
||||
difference() {
|
||||
translate([-end_w/2, carriage_clearance(type)])
|
||||
square([end_w, end_h]);
|
||||
cutout();
|
||||
}
|
||||
}
|
||||
|
||||
translate([-(block_l+end_l)/2,0,0])
|
||||
rotate([90, 0, 90])
|
||||
carriage_end(type, end_w, end_h, end_l);
|
||||
translate([(block_l+end_l)/2,0,0])
|
||||
rotate([90, 0, -90])
|
||||
carriage_end(type, end_w, end_h, end_l);
|
||||
}
|
||||
|
||||
module rail(type, length) { //! Draw the specified rail
|
||||
@ -139,11 +150,11 @@ module rail(type, length) { //! Draw the specified rail
|
||||
}
|
||||
}
|
||||
|
||||
module rail_assembly(type, length, pos) { //! Rail and carriage assembly
|
||||
module rail_assembly(type, length, pos, carriage_end_color = grey20, carriage_wiper_color = grey20) { //! Rail and carriage assembly
|
||||
rail(type, length);
|
||||
|
||||
translate([pos, 0])
|
||||
carriage(rail_carriage(type), type);
|
||||
carriage(rail_carriage(type), type, carriage_end_color, carriage_wiper_color);
|
||||
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,7 @@ use <spade.scad>
|
||||
|
||||
function rocker_part(type) = type[1]; //! Part description
|
||||
function rocker_slot_w(type) = type[2]; //! Panel slot width
|
||||
function rocker_slot_h(type) = type[3]; //! Panel slow height
|
||||
function rocker_slot_h(type) = type[3]; //! Panel slot height
|
||||
function rocker_flange_w(type) = type[4]; //! Flange width
|
||||
function rocker_flange_h(type) = type[5]; //! Flange height
|
||||
function rocker_flange_t(type) = type[6]; //! Flange thickness
|
||||
@ -37,7 +37,7 @@ function rocker_pivot(type) = type[11]; //! Pivot distance from the back of
|
||||
function rocker_button(type) = type[12]; //! How far the button extends from the bezel
|
||||
function rocker_spades(type) = type[13]; //! Spade types and positions
|
||||
|
||||
module rocker(type) { //! Draw the specified rocker switch
|
||||
module rocker(type, colour) { //! Draw the specified rocker switch
|
||||
vitamin(str("rocker(", type[0], "): ", rocker_part(type)));
|
||||
|
||||
bezel = rocker_bezel(type);
|
||||
@ -65,7 +65,7 @@ module rocker(type) { //! Draw the specified rocker switch
|
||||
rounded_rectangle([rocker_width(type), rocker_height(type), rocker_depth(type) + eps], 0.5, center = false);
|
||||
}
|
||||
if(rocker_pivot(type))
|
||||
color(grey30)
|
||||
color(colour ? colour : grey30)
|
||||
translate_z(rocker_pivot(type))
|
||||
rotate([90, 0, 90])
|
||||
linear_extrude(height = rocker_w, center = true)
|
||||
@ -78,7 +78,7 @@ module rocker(type) { //! Draw the specified rocker switch
|
||||
}
|
||||
|
||||
else
|
||||
color("red") cube([rocker_w, rocker_h, 2 * (rocker_flange_t(type) + rocker_button(type))], center = true);
|
||||
color(colour ? colour : "red") cube([rocker_w, rocker_h, 2 * (rocker_flange_t(type) + rocker_button(type))], center = true);
|
||||
|
||||
for(spade = rocker_spades(type))
|
||||
translate([spade[2], spade[3], -rocker_depth(type)])
|
||||
|
@ -21,30 +21,57 @@
|
||||
//! Steel rods and studding with chamfered ends.
|
||||
//
|
||||
include <../core.scad>
|
||||
use <../utils/thread.scad>
|
||||
|
||||
rod_colour = grey80;
|
||||
studding_colour = grey70;
|
||||
leadscrew_colour = grey70;
|
||||
|
||||
module rod(d , l) { //! Draw a smooth rod with specified length and diameter
|
||||
module rod(d , l, center = true) { //! Draw a smooth rod with specified diameter and length
|
||||
vitamin(str("rod(", d, ", ", l, "): Smooth rod ", d, "mm x ", l, "mm"));
|
||||
|
||||
chamfer = d / 10;
|
||||
color(rod_colour)
|
||||
hull() {
|
||||
cylinder(d = d, h = l - 2 * chamfer, center = true);
|
||||
translate_z(center ? 0 : l / 2)
|
||||
hull() {
|
||||
cylinder(d = d, h = l - 2 * chamfer, center = true);
|
||||
|
||||
cylinder(d = d - 2 * chamfer, h = l, center = true);
|
||||
}
|
||||
cylinder(d = d - 2 * chamfer, h = l, center = true);
|
||||
}
|
||||
}
|
||||
|
||||
module studding(d , l) { //! Draw a threaded rod with specified length and diameter
|
||||
module studding(d , l, center = true) { //! Draw a threaded rod with specified diameter and length
|
||||
vitamin(str("studding(", d, ", ", l,"): Threaded rod M", d, " x ", l, "mm"));
|
||||
|
||||
chamfer = d / 20;
|
||||
color(studding_colour)
|
||||
hull() {
|
||||
cylinder(d = d, h = l - 2 * chamfer, center = true);
|
||||
pitch = metric_coarse_pitch(d);
|
||||
|
||||
cylinder(d = d - 2 * chamfer, h = l, center = true);
|
||||
}
|
||||
translate_z(center ? 0 : l / 2)
|
||||
if(show_threads && pitch)
|
||||
male_metric_thread(d, pitch, l, colour = rod_colour);
|
||||
else
|
||||
color(studding_colour)
|
||||
hull() {
|
||||
cylinder(d = d, h = l - 2 * chamfer, center = true);
|
||||
|
||||
cylinder(d = d - 2 * chamfer, h = l, center = true);
|
||||
}
|
||||
}
|
||||
|
||||
module leadscrew(d , l, lead, starts, center = true) { //! Draw a leadscrew with specified diameter, length, lead and number of starts
|
||||
vitamin(str("leadscrew(", d, ", ", l, ", ", lead, ", ", starts, "): Leadscrew ", d, " x ", l, "mm, ", lead, "mm lead, ", starts, " starts"));
|
||||
|
||||
pitch = lead / starts;
|
||||
chamfer = pitch / 2;
|
||||
|
||||
translate_z(center ? 0 : l / 2)
|
||||
if(show_threads && pitch)
|
||||
thread(d - pitch, lead, l, thread_profile(pitch / 2, pitch * 0.366, 30), top = 45, bot = 45, starts = starts, center = center, colour = rod_colour);
|
||||
else
|
||||
color(leadscrew_colour)
|
||||
hull() {
|
||||
cylinder(d = d, h = l - 2 * chamfer, center = true);
|
||||
|
||||
cylinder(d = d - 2 * chamfer, h = l, center = true);
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ include <../core.scad>
|
||||
|
||||
use <washer.scad>
|
||||
use <../utils/rounded_cylinder.scad>
|
||||
use <../utils/thread.scad>
|
||||
|
||||
function screw_head_type(type) = type[2]; //! Head style hs_cap, hs_pan, hs_cs, hs_hex, hs_grub, hs_cs_cap, hs_dome
|
||||
function screw_radius(type) = type[3] / 2; //! Nominal radius
|
||||
@ -69,28 +70,36 @@ module screw(type, length, hob_point = 0, nylon = false) { //! Draw specified sc
|
||||
socket_depth= screw_socket_depth(type);
|
||||
socket_rad = socket_af / cos(30) / 2;
|
||||
max_thread = screw_max_thread(type);
|
||||
thread = max_thread ? min(length, max_thread) : length;
|
||||
shank = length - thread;
|
||||
thread = max_thread ? length >= max_thread + 5 ? max_thread
|
||||
: length
|
||||
: length;
|
||||
d = 2 * screw_radius(type);
|
||||
pitch = metric_coarse_pitch(d);
|
||||
colour = nylon || head_type == hs_grub ? grey40 : grey80;
|
||||
|
||||
|
||||
module shaft(headless = 0) {
|
||||
module shaft(socket = 0, headless = false) {
|
||||
point = screw_nut(type) ? 0 : 3 * rad;
|
||||
color(colour * 0.9 )
|
||||
rotate_extrude() {
|
||||
translate([0, -length + point])
|
||||
square([rad, length - headless - point]);
|
||||
shank = length - thread - socket;
|
||||
|
||||
if(point)
|
||||
polygon([
|
||||
[0, -length], [0, point - length], [rad - 0.1, point - length]
|
||||
]);
|
||||
}
|
||||
if(shank >= 5)
|
||||
if(show_threads && !point && pitch)
|
||||
translate_z(-length)
|
||||
male_metric_thread(d, pitch, thread - (shank > 0 || headless ? 0 : socket), false, top = headless ? -1 : 0, solid = !headless, colour = colour);
|
||||
else
|
||||
color(colour * 0.9)
|
||||
rotate_extrude() {
|
||||
translate([0, -length + point])
|
||||
square([rad, length - socket - point]);
|
||||
|
||||
if(point)
|
||||
polygon([
|
||||
[0.4, -length], [0, point - length], [rad, point - length]
|
||||
]);
|
||||
}
|
||||
|
||||
if(shank > 0)
|
||||
color(colour)
|
||||
translate_z(-shank)
|
||||
cylinder(r = rad + eps, h = shank - headless);
|
||||
|
||||
translate_z(-shank - socket)
|
||||
cylinder(r = rad + eps, h = shank);
|
||||
}
|
||||
|
||||
explode(length + 10) {
|
||||
@ -102,6 +111,7 @@ module screw(type, length, hob_point = 0, nylon = false) { //! Draw specified sc
|
||||
linear_extrude(height = socket_depth)
|
||||
difference() {
|
||||
circle(head_rad);
|
||||
|
||||
circle(socket_rad, $fn = 6);
|
||||
}
|
||||
|
||||
@ -110,14 +120,20 @@ module screw(type, length, hob_point = 0, nylon = false) { //! Draw specified sc
|
||||
}
|
||||
if(head_type == hs_grub) {
|
||||
color(colour) {
|
||||
r = show_threads ? rad - pitch / 2 : rad;
|
||||
translate_z(-socket_depth)
|
||||
linear_extrude(height = socket_depth)
|
||||
difference() {
|
||||
circle(r = rad);
|
||||
circle(r);
|
||||
|
||||
circle(socket_rad, $fn = 6);
|
||||
}
|
||||
|
||||
shaft(socket_depth);
|
||||
shaft(socket_depth, true);
|
||||
|
||||
if(show_threads)
|
||||
translate_z(-length)
|
||||
cylinder(r = r, h = length - socket_depth);
|
||||
}
|
||||
}
|
||||
if(head_type == hs_hex) {
|
||||
|
@ -20,6 +20,7 @@
|
||||
//! Filament spool models
|
||||
|
||||
include <../core.scad>
|
||||
include <../utils/tube.scad>
|
||||
|
||||
function spool_diameter(type) = type[1]; //! Outside diameter
|
||||
function spool_width(type) = type[2]; //! Internal width
|
||||
@ -32,7 +33,7 @@ function spool_hub_taper(type) = type[8]; //! Diameter at which it tapers do
|
||||
function spool_height(type) = spool_width(type) + 2 * spool_hub_thickness(type); //! Outside width
|
||||
function spool_pitch(type) = spool_width(type) + spool_rim_thickness(type); //! Spacing of the rims
|
||||
|
||||
module spool(type) { //! Draw specified spool
|
||||
module spool(type, filament_depth = 0, filament_colour = "white", filament_d = 3) { //! Draw specified spool with optional filament
|
||||
vitamin(str("spool(", type[0], "): Filament spool ", spool_diameter(type), " x ", spool_width(type)));
|
||||
|
||||
h = spool_height(type);
|
||||
@ -57,4 +58,25 @@ module spool(type) { //! Draw specified spool
|
||||
[r3, h - spool_hub_thickness(type) + spool_rim_thickness(type)],
|
||||
[r2, h],
|
||||
]);
|
||||
|
||||
if(filament_depth) {
|
||||
w = spool_width(type);
|
||||
r = r5 + filament_depth;
|
||||
color(filament_colour)
|
||||
if(filament_d) {
|
||||
n = round(w / filament_d) + 1;
|
||||
fd = w / n;
|
||||
rotate_extrude($fn = 180) {
|
||||
for(i = [0 : n -1])
|
||||
translate([r - fd / 2, i * fd - w / 2 + fd / 2])
|
||||
circle(d = fd, $fn = 32);
|
||||
|
||||
translate([r5, -w / 2])
|
||||
square([filament_depth - fd / 2, w]);
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
tube(r, r5, w, $fn = 180);
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ include <screws.scad>
|
||||
use <washer.scad>
|
||||
include <ring_terminals.scad>
|
||||
use <../utils/tube.scad>
|
||||
use <rod.scad>
|
||||
|
||||
function NEMA_width(type) = type[1]; //! Width of the square face
|
||||
function NEMA_length(type) = type[2]; //! Body length
|
||||
@ -34,7 +35,7 @@ function NEMA_body_radius(type) = type[4]; //! Body radius
|
||||
function NEMA_boss_radius(type) = type[5]; //! Boss around the spindle radius
|
||||
function NEMA_boss_height(type) = type[6]; //! Boss height
|
||||
function NEMA_shaft_dia(type) = type[7]; //! Shaft diameter
|
||||
function NEMA_shaft_length(type)= type[8]; //! Shaft length above the face
|
||||
function NEMA_shaft_length(type)= type[8]; //! Shaft length above the face, if a list then a leadscrew: length, lead, starts
|
||||
function NEMA_hole_pitch(type) = type[9]; //! Screw hole pitch
|
||||
function NEMA_holes(type) = [-NEMA_hole_pitch(type) / 2, NEMA_hole_pitch(type) / 2]; //! Screw positions for for loop
|
||||
function NEMA_big_hole(type) = NEMA_boss_radius(type) + 0.2; //! Clearance hole for the big boss
|
||||
@ -50,7 +51,7 @@ module NEMA_outline(type) //! 2D outline
|
||||
circle(NEMA_radius(type));
|
||||
}
|
||||
|
||||
module NEMA(type) { //! Draw specified NEMA stepper motor
|
||||
module NEMA(type, shaft_angle = 0) { //! Draw specified NEMA stepper motor
|
||||
side = NEMA_width(type);
|
||||
length = NEMA_length(type);
|
||||
body_rad = NEMA_body_radius(type);
|
||||
@ -88,9 +89,15 @@ module NEMA(type) { //! Draw specified NEMA stepper motor
|
||||
}
|
||||
}
|
||||
|
||||
color(NEMA_shaft_length(type) > 50 ? "silver" : stepper_cap_colour)
|
||||
translate_z(-5)
|
||||
cylinder(r = shaft_rad, h = NEMA_shaft_length(type) + 5); // shaft
|
||||
shaft = NEMA_shaft_length(type);
|
||||
translate_z(-5)
|
||||
rotate(shaft_angle)
|
||||
if(!is_list(shaft))
|
||||
color(stepper_cap_colour)
|
||||
cylinder(r = shaft_rad, h = shaft + 5); // shaft
|
||||
else
|
||||
not_on_bom()
|
||||
leadscrew(shaft_rad * 2, shaft.x + 5, shaft.y, shaft.z, center = false)
|
||||
|
||||
translate([0, side / 2, -length + cap / 2])
|
||||
rotate([90, 0, 0])
|
||||
|
@ -22,14 +22,14 @@
|
||||
//
|
||||
|
||||
// corner body boss boss shaft
|
||||
// side, length, radius, radius, radius, depth, shaft, length, holes
|
||||
NEMA17 = ["NEMA17", 42.3, 47, 53.6/2, 25, 11, 2, 5, 24, 31 ];
|
||||
NEMA17M = ["NEMA17M", 42.3, 40, 53.6/2, 25, 11, 2, 5, 20, 31 ];
|
||||
NEMA17M8= ["NEMA17M8", 42.3, 40, 53.6/2, 25, 11, 2, 8, 280, 31 ];
|
||||
NEMA17S = ["NEMA17S", 42.3, 34, 53.6/2, 25, 11, 2, 5, 24, 31 ];
|
||||
NEMA16 = ["NEMA16", 39.5, 19.2, 50.6/2, 50.6/2, 11, 2, 5, 12, 31 ];
|
||||
NEMA14 = ["NEMA14", 35.2, 36, 46.4/2, 21, 11, 2, 5, 21, 26 ];
|
||||
NEMA23 = ["NEMA23", 56.4, 51.2, 75.7/2, 35, 38.1/2, 1.6, 6.35, 24, 47.1 ];
|
||||
// side, length, radius, radius, radius, depth, shaft, length, holes
|
||||
NEMA17 = ["NEMA17", 42.3, 47, 53.6/2, 25, 11, 2, 5, 24, 31 ];
|
||||
NEMA17M = ["NEMA17M", 42.3, 40, 53.6/2, 25, 11, 2, 5, 20, 31 ];
|
||||
NEMA17M8= ["NEMA17M8", 42.3, 40, 53.6/2, 25, 11, 2, 8, [280, 8, 4], 31 ];
|
||||
NEMA17S = ["NEMA17S", 42.3, 34, 53.6/2, 25, 11, 2, 5, 24, 31 ];
|
||||
NEMA16 = ["NEMA16", 39.5, 19.2, 50.6/2, 50.6/2, 11, 2, 5, 12, 31 ];
|
||||
NEMA14 = ["NEMA14", 35.2, 36, 46.4/2, 21, 11, 2, 5, 21, 26 ];
|
||||
NEMA23 = ["NEMA23", 56.4, 51.2, 75.7/2, 35, 38.1/2, 1.6, 6.35, 24, 47.1 ];
|
||||
|
||||
stepper_motors = [NEMA14, NEMA16, NEMA17S, NEMA17M, NEMA17, NEMA23];
|
||||
|
||||
|
@ -23,6 +23,8 @@
|
||||
include <../core.scad>
|
||||
use <nut.scad>
|
||||
use <washer.scad>
|
||||
use <../utils/thread.scad>
|
||||
use <../utils/tube.scad>
|
||||
|
||||
function toggle_part(type) = type[1]; //! Part description
|
||||
function toggle_width(type) = type[2]; //! Body width
|
||||
@ -80,7 +82,29 @@ module toggle(type, thickness) { //! Draw specified toggle switch with the nuts
|
||||
translate_z(-h1 / 2 - t)
|
||||
cube([toggle_width(type), toggle_height(type), h1], center = true);
|
||||
|
||||
color("silver") {
|
||||
if(show_threads) {
|
||||
d = toggle_od(type);
|
||||
pitch = inch(1/40);
|
||||
h = 5 * pitch * sqrt(3) / 16;
|
||||
|
||||
male_metric_thread(d, pitch, thread, center = false, solid = false, colour = silver);
|
||||
|
||||
color(silver)
|
||||
tube(or = d / 2 - h, ir = toggle_id(type) / 2, h = thread, center = false);
|
||||
}
|
||||
else
|
||||
color(silver)
|
||||
rotate_extrude()
|
||||
difference() {
|
||||
hull() {
|
||||
square([toggle_od(type) / 2, thread - chamfer]);
|
||||
|
||||
square([toggle_od(type) / 2 - chamfer, thread]);
|
||||
}
|
||||
square([toggle_id(type) / 2, thread + 1]);
|
||||
}
|
||||
|
||||
color(silver) {
|
||||
if(toggle_collar_t(type))
|
||||
cylinder(d = toggle_collar_d(type), h = toggle_collar_t(type));
|
||||
|
||||
@ -90,15 +114,6 @@ module toggle(type, thickness) { //! Draw specified toggle switch with the nuts
|
||||
translate_z(-h2 / 2)
|
||||
cube([toggle_width(type) + 2 * eps, toggle_height(type) - 2 * inset, h2], center = true);
|
||||
|
||||
rotate_extrude()
|
||||
difference() {
|
||||
hull() {
|
||||
square([toggle_od(type) / 2, thread - chamfer]);
|
||||
|
||||
square([toggle_od(type) / 2 - chamfer, thread]);
|
||||
}
|
||||
square([toggle_id(type) / 2, thread + 1]);
|
||||
}
|
||||
|
||||
translate_z(toggle_pivot(type)) {
|
||||
angle = toggle_angle(type);
|
||||
|