Compare commits
9 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
1eb8b378e9 | ||
|
362dbdb4fc | ||
|
57d223d84b | ||
|
699385342f | ||
|
547a418cea | ||
|
b6d25048bc | ||
|
4cdab218d9 | ||
|
b6147e5684 | ||
|
966ba536ed |
1
lib.scad
@@ -43,6 +43,7 @@ include <vitamins/ldrs.scad>
|
|||||||
include <vitamins/leadnuts.scad>
|
include <vitamins/leadnuts.scad>
|
||||||
include <vitamins/led_meter.scad>
|
include <vitamins/led_meter.scad>
|
||||||
include <vitamins/light_strips.scad>
|
include <vitamins/light_strips.scad>
|
||||||
|
include <vitamins/magnets.scad>
|
||||||
include <vitamins/mains_sockets.scad>
|
include <vitamins/mains_sockets.scad>
|
||||||
include <vitamins/modules.scad>
|
include <vitamins/modules.scad>
|
||||||
include <vitamins/panel_meters.scad>
|
include <vitamins/panel_meters.scad>
|
||||||
|
BIN
libtest.png
Before Width: | Height: | Size: 816 KiB After Width: | Height: | Size: 817 KiB |
@@ -50,6 +50,7 @@ use <tests/LEDs.scad>
|
|||||||
use <tests/light_strips.scad>
|
use <tests/light_strips.scad>
|
||||||
use <tests/linear_bearings.scad>
|
use <tests/linear_bearings.scad>
|
||||||
use <tests/LED_meters.scad>
|
use <tests/LED_meters.scad>
|
||||||
|
use <tests/magnets.scad>
|
||||||
use <tests/microswitches.scad>
|
use <tests/microswitches.scad>
|
||||||
use <tests/modules.scad>
|
use <tests/modules.scad>
|
||||||
use <tests/nuts.scad>
|
use <tests/nuts.scad>
|
||||||
@@ -271,8 +272,9 @@ translate([x1, leadnuts_y])
|
|||||||
|
|
||||||
leds_y = 0;
|
leds_y = 0;
|
||||||
carriers_y = leds_y + 40;
|
carriers_y = leds_y + 40;
|
||||||
spades_y = carriers_y + 40;
|
magnets_y = carriers_y + 40;
|
||||||
buttons_y = spades_y + 40;
|
spades_y = magnets_y + 20;
|
||||||
|
buttons_y = spades_y + 20;
|
||||||
jacks_y = buttons_y + 40;
|
jacks_y = buttons_y + 40;
|
||||||
microswitches_y = jacks_y + 40;
|
microswitches_y = jacks_y + 40;
|
||||||
rockers_y = microswitches_y + 40;
|
rockers_y = microswitches_y + 40;
|
||||||
@@ -288,6 +290,9 @@ translate([x2 + 35, leds_y])
|
|||||||
translate([x2 + 8, carriers_y])
|
translate([x2 + 8, carriers_y])
|
||||||
carriers();
|
carriers();
|
||||||
|
|
||||||
|
translate([x2, magnets_y])
|
||||||
|
magnets();
|
||||||
|
|
||||||
translate([x2 + 20, carriers_y])
|
translate([x2 + 20, carriers_y])
|
||||||
led_meters();
|
led_meters();
|
||||||
|
|
||||||
|
69
readme.md
@@ -26,21 +26,21 @@ See [usage](docs/usage.md) for requirements, installation instructions and a usa
|
|||||||
<tr><td> <a href = "#Bulldogs">Bulldogs</a> </td><td> <a href = "#Leadnuts">Leadnuts</a> </td><td> <a href = "#SK_brackets">SK_brackets</a> </td><td> <a href = "#Door_hinge">Door_hinge</a> </td><td> <a href = "#Hanging_hole">Hanging_hole</a> </td><td> <a href = "#Sphere">Sphere</a> </td></tr>
|
<tr><td> <a href = "#Bulldogs">Bulldogs</a> </td><td> <a href = "#Leadnuts">Leadnuts</a> </td><td> <a href = "#SK_brackets">SK_brackets</a> </td><td> <a href = "#Door_hinge">Door_hinge</a> </td><td> <a href = "#Hanging_hole">Hanging_hole</a> </td><td> <a href = "#Sphere">Sphere</a> </td></tr>
|
||||||
<tr><td> <a href = "#Buttons">Buttons</a> </td><td> <a href = "#Light_strips">Light_strips</a> </td><td> <a href = "#SMDs">SMDs</a> </td><td> <a href = "#Door_latch">Door_latch</a> </td><td> <a href = "#Horiholes">Horiholes</a> </td><td> <a href = "#Teardrops">Teardrops</a> </td></tr>
|
<tr><td> <a href = "#Buttons">Buttons</a> </td><td> <a href = "#Light_strips">Light_strips</a> </td><td> <a href = "#SMDs">SMDs</a> </td><td> <a href = "#Door_latch">Door_latch</a> </td><td> <a href = "#Horiholes">Horiholes</a> </td><td> <a href = "#Teardrops">Teardrops</a> </td></tr>
|
||||||
<tr><td> <a href = "#Cable_strips">Cable_strips</a> </td><td> <a href = "#Linear_bearings">Linear_bearings</a> </td><td> <a href = "#SSRs">SSRs</a> </td><td> <a href = "#Fan_guard">Fan_guard</a> </td><td> <a href = "#Layout">Layout</a> </td><td></td></tr>
|
<tr><td> <a href = "#Cable_strips">Cable_strips</a> </td><td> <a href = "#Linear_bearings">Linear_bearings</a> </td><td> <a href = "#SSRs">SSRs</a> </td><td> <a href = "#Fan_guard">Fan_guard</a> </td><td> <a href = "#Layout">Layout</a> </td><td></td></tr>
|
||||||
<tr><td> <a href = "#Cameras">Cameras</a> </td><td> <a href = "#Mains_sockets">Mains_sockets</a> </td><td> <a href = "#Screws">Screws</a> </td><td> <a href = "#Fixing_block">Fixing_block</a> </td><td> <a href = "#Maths">Maths</a> </td><td></td></tr>
|
<tr><td> <a href = "#Cameras">Cameras</a> </td><td> <a href = "#Magnets">Magnets</a> </td><td> <a href = "#Screws">Screws</a> </td><td> <a href = "#Fixing_block">Fixing_block</a> </td><td> <a href = "#Maths">Maths</a> </td><td></td></tr>
|
||||||
<tr><td> <a href = "#Circlips">Circlips</a> </td><td> <a href = "#Microswitches">Microswitches</a> </td><td> <a href = "#Sealing_strip">Sealing_strip</a> </td><td> <a href = "#Flat_hinge">Flat_hinge</a> </td><td> <a href = "#Offset">Offset</a> </td><td></td></tr>
|
<tr><td> <a href = "#Circlips">Circlips</a> </td><td> <a href = "#Mains_sockets">Mains_sockets</a> </td><td> <a href = "#Sealing_strip">Sealing_strip</a> </td><td> <a href = "#Flat_hinge">Flat_hinge</a> </td><td> <a href = "#Offset">Offset</a> </td><td></td></tr>
|
||||||
<tr><td> <a href = "#Components">Components</a> </td><td> <a href = "#Microview">Microview</a> </td><td> <a href = "#Sheets">Sheets</a> </td><td> <a href = "#Foot">Foot</a> </td><td> <a href = "#Quadrant">Quadrant</a> </td><td></td></tr>
|
<tr><td> <a href = "#Components">Components</a> </td><td> <a href = "#Microswitches">Microswitches</a> </td><td> <a href = "#Sheets">Sheets</a> </td><td> <a href = "#Foot">Foot</a> </td><td> <a href = "#Quadrant">Quadrant</a> </td><td></td></tr>
|
||||||
<tr><td> <a href = "#DIP">DIP</a> </td><td> <a href = "#Modules">Modules</a> </td><td> <a href = "#Spades">Spades</a> </td><td> <a href = "#Handle">Handle</a> </td><td> <a href = "#Round">Round</a> </td><td></td></tr>
|
<tr><td> <a href = "#DIP">DIP</a> </td><td> <a href = "#Microview">Microview</a> </td><td> <a href = "#Spades">Spades</a> </td><td> <a href = "#Handle">Handle</a> </td><td> <a href = "#Round">Round</a> </td><td></td></tr>
|
||||||
<tr><td> <a href = "#D_connectors">D_connectors</a> </td><td> <a href = "#Nuts">Nuts</a> </td><td> <a href = "#Spools">Spools</a> </td><td> <a href = "#PCB_mount">PCB_mount</a> </td><td> <a href = "#Rounded_cylinder">Rounded_cylinder</a> </td><td></td></tr>
|
<tr><td> <a href = "#D_connectors">D_connectors</a> </td><td> <a href = "#Modules">Modules</a> </td><td> <a href = "#Spools">Spools</a> </td><td> <a href = "#PCB_mount">PCB_mount</a> </td><td> <a href = "#Rounded_cylinder">Rounded_cylinder</a> </td><td></td></tr>
|
||||||
<tr><td> <a href = "#Displays">Displays</a> </td><td> <a href = "#O_ring">O_ring</a> </td><td> <a href = "#Springs">Springs</a> </td><td> <a href = "#PSU_shroud">PSU_shroud</a> </td><td> <a href = "#Rounded_polygon">Rounded_polygon</a> </td><td></td></tr>
|
<tr><td> <a href = "#Displays">Displays</a> </td><td> <a href = "#Nuts">Nuts</a> </td><td> <a href = "#Springs">Springs</a> </td><td> <a href = "#PSU_shroud">PSU_shroud</a> </td><td> <a href = "#Rounded_polygon">Rounded_polygon</a> </td><td></td></tr>
|
||||||
<tr><td> <a href = "#Extrusion_brackets">Extrusion_brackets</a> </td><td> <a href = "#Opengrab">Opengrab</a> </td><td> <a href = "#Stepper_motors">Stepper_motors</a> </td><td> <a href = "#Printed_box">Printed_box</a> </td><td> <a href = "#Sector">Sector</a> </td><td></td></tr>
|
<tr><td> <a href = "#Extrusion_brackets">Extrusion_brackets</a> </td><td> <a href = "#O_ring">O_ring</a> </td><td> <a href = "#Stepper_motors">Stepper_motors</a> </td><td> <a href = "#Printed_box">Printed_box</a> </td><td> <a href = "#Sector">Sector</a> </td><td></td></tr>
|
||||||
<tr><td> <a href = "#Extrusions">Extrusions</a> </td><td> <a href = "#PCB">PCB</a> </td><td> <a href = "#Swiss_clips">Swiss_clips</a> </td><td> <a href = "#Ribbon_clamp">Ribbon_clamp</a> </td><td> <a href = "#Sweep">Sweep</a> </td><td></td></tr>
|
<tr><td> <a href = "#Extrusions">Extrusions</a> </td><td> <a href = "#Opengrab">Opengrab</a> </td><td> <a href = "#Swiss_clips">Swiss_clips</a> </td><td> <a href = "#Ribbon_clamp">Ribbon_clamp</a> </td><td> <a href = "#Sweep">Sweep</a> </td><td></td></tr>
|
||||||
<tr><td> <a href = "#Fans">Fans</a> </td><td> <a href = "#PCBs">PCBs</a> </td><td> <a href = "#Toggles">Toggles</a> </td><td> <a href = "#SSR_shroud">SSR_shroud</a> </td><td> <a href = "#Thread">Thread</a> </td><td></td></tr>
|
<tr><td> <a href = "#Fans">Fans</a> </td><td> <a href = "#PCB">PCB</a> </td><td> <a href = "#Toggles">Toggles</a> </td><td> <a href = "#SSR_shroud">SSR_shroud</a> </td><td> <a href = "#Thread">Thread</a> </td><td></td></tr>
|
||||||
<tr><td> <a href = "#Fuseholder">Fuseholder</a> </td><td> <a href = "#PSUs">PSUs</a> </td><td> <a href = "#Transformers">Transformers</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 = "#Fuseholder">Fuseholder</a> </td><td> <a href = "#PCBs">PCBs</a> </td><td> <a href = "#Transformers">Transformers</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 = "#Geared_steppers">Geared_steppers</a> </td><td> <a href = "#Panel_meters">Panel_meters</a> </td><td> <a href = "#Tubings">Tubings</a> </td><td> <a href = "#Socket_box">Socket_box</a> </td><td></td><td></td></tr>
|
<tr><td> <a href = "#Geared_steppers">Geared_steppers</a> </td><td> <a href = "#PSUs">PSUs</a> </td><td> <a href = "#Tubings">Tubings</a> </td><td> <a href = "#Socket_box">Socket_box</a> </td><td></td><td></td></tr>
|
||||||
<tr><td> <a href = "#Green_terminals">Green_terminals</a> </td><td> <a href = "#Pillars">Pillars</a> </td><td> <a href = "#Variacs">Variacs</a> </td><td> <a href = "#Strap_handle">Strap_handle</a> </td><td></td><td></td></tr>
|
<tr><td> <a href = "#Green_terminals">Green_terminals</a> </td><td> <a href = "#Panel_meters">Panel_meters</a> </td><td> <a href = "#Variacs">Variacs</a> </td><td> <a href = "#Strap_handle">Strap_handle</a> </td><td></td><td></td></tr>
|
||||||
<tr><td> <a href = "#Hot_ends">Hot_ends</a> </td><td> <a href = "#Pin_headers">Pin_headers</a> </td><td> <a href = "#Veroboard">Veroboard</a> </td><td></td><td></td><td></td></tr>
|
<tr><td> <a href = "#Hot_ends">Hot_ends</a> </td><td> <a href = "#Pillars">Pillars</a> </td><td> <a href = "#Veroboard">Veroboard</a> </td><td></td><td></td><td></td></tr>
|
||||||
<tr><td> <a href = "#Hygrometer">Hygrometer</a> </td><td> <a href = "#Pulleys">Pulleys</a> </td><td> <a href = "#Washers">Washers</a> </td><td></td><td></td><td></td></tr>
|
<tr><td> <a href = "#Hygrometer">Hygrometer</a> </td><td> <a href = "#Pin_headers">Pin_headers</a> </td><td> <a href = "#Washers">Washers</a> </td><td></td><td></td><td></td></tr>
|
||||||
<tr><td> <a href = "#IECs">IECs</a> </td><td></td><td> <a href = "#Wire">Wire</a> </td><td></td><td></td><td></td></tr>
|
<tr><td> <a href = "#IECs">IECs</a> </td><td> <a href = "#Pulleys">Pulleys</a> </td><td> <a href = "#Wire">Wire</a> </td><td></td><td></td><td></td></tr>
|
||||||
<tr><td> <a href = "#Inserts">Inserts</a> </td><td></td><td> <a href = "#Zipties">Zipties</a> </td><td></td><td></td><td></td></tr>
|
<tr><td> <a href = "#Inserts">Inserts</a> </td><td></td><td> <a href = "#Zipties">Zipties</a> </td><td></td><td></td><td></td></tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
@@ -209,6 +209,7 @@ Only models 2D paths, so not core XY!
|
|||||||
To make the back of the belt run against a smooth pulley on the outside of the loop specify a negative pitch radius.
|
To make the back of the belt run against a smooth pulley on the outside of the loop specify a negative pitch radius.
|
||||||
|
|
||||||
By default the path is a closed loop but a gap length and position can be specified to make open loops.
|
By default the path is a closed loop but a gap length and position can be specified to make open loops.
|
||||||
|
To draw the gap its XY position is specified by ```gap_pos```. ```gap_pos.z``` can be used to specify a rotation if the gap is not at the bottom of the loop.
|
||||||
|
|
||||||
Individual teeth are not drawn, instead they are represented by a lighter colour.
|
Individual teeth are not drawn, instead they are represented by a lighter colour.
|
||||||
|
|
||||||
@@ -223,6 +224,7 @@ Individual teeth are not drawn, instead they are represented by a lighter colour
|
|||||||
| Function | Description |
|
| Function | Description |
|
||||||
|:--- |:--- |
|
|:--- |:--- |
|
||||||
| ```belt_pitch(type)``` | Pitch in mm |
|
| ```belt_pitch(type)``` | Pitch in mm |
|
||||||
|
| ```belt_pitch_height(type)``` | Offset of the pitch radius from the tips of the teeth |
|
||||||
| ```belt_thickness(type)``` | Total thickness including teeth |
|
| ```belt_thickness(type)``` | Total thickness including teeth |
|
||||||
| ```belt_tooth_height(type)``` | Tooth height |
|
| ```belt_tooth_height(type)``` | Tooth height |
|
||||||
| ```belt_width(type)``` | Width in mm |
|
| ```belt_width(type)``` | Width in mm |
|
||||||
@@ -231,12 +233,12 @@ Individual teeth are not drawn, instead they are represented by a lighter colour
|
|||||||
| Function | Description |
|
| Function | Description |
|
||||||
|:--- |:--- |
|
|:--- |:--- |
|
||||||
| ```belt_length(points, gap = 0)``` | Compute belt length given path and optional gap |
|
| ```belt_length(points, gap = 0)``` | Compute belt length given path and optional gap |
|
||||||
| ```belt_pitch_height(type)``` | Offset of the pitch radius from the tips of the teeth |
|
| ```belt_pitch_to_back(type)``` | Offset of the back from the pitch radius |
|
||||||
|
|
||||||
### Modules
|
### Modules
|
||||||
| Module | Description |
|
| Module | Description |
|
||||||
|:--- |:--- |
|
|:--- |:--- |
|
||||||
| ```belt(type, points, gap = 0, gap_pt = undef, belt_colour = grey(20)``` | Draw a belt path given a set of points and pitch radii where the pulleys are. Closed loop unless a gap is specified |
|
| ```belt(type, points, gap = 0, gap_pos = undef, belt_colour = grey(20)``` | Draw a belt path given a set of points and pitch radii where the pulleys are. Closed loop unless a gap is specified |
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
@@ -244,7 +246,7 @@ Individual teeth are not drawn, instead they are represented by a lighter colour
|
|||||||
| Qty | Module call | BOM entry |
|
| Qty | Module call | BOM entry |
|
||||||
| ---:|:--- |:---|
|
| ---:|:--- |:---|
|
||||||
| 1 | ```belt(GT2x6, [ ... ])``` | Belt GT2 x 6mm x 128mm |
|
| 1 | ```belt(GT2x6, [ ... ])``` | Belt GT2 x 6mm x 128mm |
|
||||||
| 1 | ```belt(GT2x6, [ ... ], 80, [0, 0.81])``` | Belt GT2 x 6mm x 694mm |
|
| 1 | ```belt(GT2x6, [ ... ], 80, [0, 0])``` | Belt GT2 x 6mm x 696mm |
|
||||||
| 1 | ```belt(T2p5x6, [ ... ])``` | Belt T2.5 x 6mm x 130mm |
|
| 1 | ```belt(T2p5x6, [ ... ])``` | Belt T2.5 x 6mm x 130mm |
|
||||||
| 1 | ```belt(T5x10, [ ... ])``` | Belt T5 x 10mm x 130mm |
|
| 1 | ```belt(T5x10, [ ... ])``` | Belt T5 x 10mm x 130mm |
|
||||||
| 1 | ```belt(T5x6, [ ... ])``` | Belt T5 x 6mm x 130mm |
|
| 1 | ```belt(T5x6, [ ... ])``` | Belt T5 x 6mm x 130mm |
|
||||||
@@ -1250,6 +1252,7 @@ Heatfit threaded inserts. Can be pushed into thermoplastics using a soldering ir
|
|||||||
| Function | Description |
|
| Function | Description |
|
||||||
|:--- |:--- |
|
|:--- |:--- |
|
||||||
| ```insert_boss_radius(type, wall)``` | Compute the outer radius of an insert boss |
|
| ```insert_boss_radius(type, wall)``` | Compute the outer radius of an insert boss |
|
||||||
|
| ```insert_nose_length(type, d)``` | The length before the second ring. |
|
||||||
|
|
||||||
### Modules
|
### Modules
|
||||||
| Module | Description |
|
| Module | Description |
|
||||||
@@ -1673,6 +1676,36 @@ LMnUU linear bearings.
|
|||||||
| 1 | ```linear_bearing(LM8UU)``` | Linear bearing LM8UU |
|
| 1 | ```linear_bearing(LM8UU)``` | Linear bearing LM8UU |
|
||||||
|
|
||||||
|
|
||||||
|
<a href="#top">Top</a>
|
||||||
|
|
||||||
|
---
|
||||||
|
<a name="Magnets"></a>
|
||||||
|
## Magnets
|
||||||
|
Cylindrical and ring magnets.
|
||||||
|
|
||||||
|
|
||||||
|
[vitamins/magnets.scad](vitamins/magnets.scad) Object definitions.
|
||||||
|
|
||||||
|
[vitamins/magnet.scad](vitamins/magnet.scad) Implementation.
|
||||||
|
|
||||||
|
[tests/magnets.scad](tests/magnets.scad) Code for this example.
|
||||||
|
|
||||||
|
### Properties
|
||||||
|
| Function | Description |
|
||||||
|
|:--- |:--- |
|
||||||
|
| ```magnet_h(type)``` | Height |
|
||||||
|
| ```magnet_id(type)``` | Inside diameter if a ring |
|
||||||
|
| ```magnet_od(type)``` | Outer diameter |
|
||||||
|
| ```magnet_r(type)``` | Corner radius |
|
||||||
|
|
||||||
|
### Modules
|
||||||
|
| Module | Description |
|
||||||
|
|:--- |:--- |
|
||||||
|
| ```magnet(type)``` | Draw specified magnet |
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
<a href="#top">Top</a>
|
<a href="#top">Top</a>
|
||||||
|
|
||||||
---
|
---
|
||||||
|
@@ -60,7 +60,7 @@ module belt_test() {
|
|||||||
[p4.x, p4.y, pulley_pr(GT2x20ob_pulley)]
|
[p4.x, p4.y, pulley_pr(GT2x20ob_pulley)]
|
||||||
];
|
];
|
||||||
belt = GT2x6;
|
belt = GT2x6;
|
||||||
belt(belt, path, 80, [0, belt_pitch_height(belt) - belt_thickness(belt) / 2]);
|
belt(belt, path, 80, [0, 0]);
|
||||||
|
|
||||||
translate([-25, 0])
|
translate([-25, 0])
|
||||||
layout([for(b = belts) belt_width(b)], 10)
|
layout([for(b = belts) belt_width(b)], 10)
|
||||||
|
29
tests/magnets.scad
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
//
|
||||||
|
// NopSCADlib Copyright Chris Palmer 2020
|
||||||
|
// nop.head@gmail.com
|
||||||
|
// hydraraptor.blogspot.com
|
||||||
|
//
|
||||||
|
// This file is part of NopSCADlib.
|
||||||
|
//
|
||||||
|
// NopSCADlib is free software: you can redistribute it and/or modify it under the terms of the
|
||||||
|
// GNU General Public License as published by the Free Software Foundation, either version 3 of
|
||||||
|
// the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// NopSCADlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||||
|
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
// See the GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License along with NopSCADlib.
|
||||||
|
// If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
include <../core.scad>
|
||||||
|
use <../utils/layout.scad>
|
||||||
|
|
||||||
|
include <../vitamins/magnets.scad>
|
||||||
|
|
||||||
|
module magnets()
|
||||||
|
layout([for(m = magnets) magnet_od(m)], 5)
|
||||||
|
magnet(magnets[$i]);
|
||||||
|
|
||||||
|
if($preview)
|
||||||
|
magnets();
|
Before Width: | Height: | Size: 102 KiB After Width: | Height: | Size: 103 KiB |
Before Width: | Height: | Size: 125 KiB After Width: | Height: | Size: 125 KiB |
BIN
tests/png/magnets.png
Normal file
After Width: | Height: | Size: 42 KiB |
@@ -39,11 +39,13 @@ module hanging_hole(z, ir, h = 100, h2 = 100) { //! Hole radius ```ir``` hanging
|
|||||||
infill_angle = z % (2 * layer_height) ? -45 : 45;
|
infill_angle = z % (2 * layer_height) ? -45 : 45;
|
||||||
below = min(z + eps, h2);
|
below = min(z + eps, h2);
|
||||||
big = 1000;
|
big = 1000;
|
||||||
|
|
||||||
render(convexity = 3) translate_z(z)
|
render(convexity = 3) translate_z(z)
|
||||||
union() {
|
union() {
|
||||||
translate_z(2 * layer_height)
|
translate_z(2 * layer_height)
|
||||||
|
if(sides(ir) > 4)
|
||||||
polyhole(ir - eps, h - 2 * layer_height);
|
polyhole(ir - eps, h - 2 * layer_height);
|
||||||
|
else
|
||||||
|
poly_cylinder(ir, h - 2 * layer_height);
|
||||||
|
|
||||||
difference() {
|
difference() {
|
||||||
translate_z(-below)
|
translate_z(-below)
|
||||||
|
@@ -23,18 +23,21 @@
|
|||||||
include <../utils/core/core.scad>
|
include <../utils/core/core.scad>
|
||||||
|
|
||||||
module quadrant(w, r, center = false) { //! Draw a square with one rounded corner, can be centered on the arc centre, when ```center``` is ```true```.
|
module quadrant(w, r, center = false) { //! Draw a square with one rounded corner, can be centered on the arc centre, when ```center``` is ```true```.
|
||||||
offset = center ? r - w : 0;
|
h = is_list(w) ? w.y : w;
|
||||||
translate([offset, offset])
|
w = is_list(w) ? w.x : w;
|
||||||
|
offset_w = center ? r - w : 0;
|
||||||
|
offset_h = center ? r - h : 0;
|
||||||
|
translate([offset_w, offset_h])
|
||||||
hull() {
|
hull() {
|
||||||
intersection() {
|
intersection() {
|
||||||
translate([w - r, w - r])
|
translate([w - r, h - r])
|
||||||
circle4n(r);
|
circle4n(r);
|
||||||
|
|
||||||
square(w);
|
square([w, h]);
|
||||||
}
|
}
|
||||||
|
|
||||||
square([w, eps]);
|
square([w, eps]);
|
||||||
|
|
||||||
square([eps, w]);
|
square([eps, h]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -24,29 +24,33 @@
|
|||||||
//! To make the back of the belt run against a smooth pulley on the outside of the loop specify a negative pitch radius.
|
//! To make the back of the belt run against a smooth pulley on the outside of the loop specify a negative pitch radius.
|
||||||
//!
|
//!
|
||||||
//! By default the path is a closed loop but a gap length and position can be specified to make open loops.
|
//! By default the path is a closed loop but a gap length and position can be specified to make open loops.
|
||||||
|
//! To draw the gap its XY position is specified by ```gap_pos```. ```gap_pos.z``` can be used to specify a rotation if the gap is not at the bottom of the loop.
|
||||||
//!
|
//!
|
||||||
//! Individual teeth are not drawn, instead they are represented by a lighter colour.
|
//! Individual teeth are not drawn, instead they are represented by a lighter colour.
|
||||||
//
|
//
|
||||||
include <../utils/core/core.scad>
|
include <../utils/core/core.scad>
|
||||||
use <../utils/rounded_polygon.scad>
|
use <../utils/rounded_polygon.scad>
|
||||||
|
use <../utils/maths.scad>
|
||||||
|
|
||||||
function belt_pitch(type) = type[1]; //! Pitch in mm
|
function belt_pitch(type) = type[1]; //! Pitch in mm
|
||||||
function belt_width(type) = type[2]; //! Width in mm
|
function belt_width(type) = type[2]; //! Width in mm
|
||||||
function belt_thickness(type) = type[3]; //! Total thickness including teeth
|
function belt_thickness(type) = type[3]; //! Total thickness including teeth
|
||||||
function belt_tooth_height(type) = type[4]; //! Tooth height
|
function belt_tooth_height(type) = type[4]; //! Tooth height
|
||||||
function belt_pitch_height(type) = belt_tooth_height(type) + type[4]; //! Offset of the pitch radius from the tips of the teeth
|
function belt_pitch_height(type) = type[5] + belt_tooth_height(type); //! Offset of the pitch radius from the tips of the teeth
|
||||||
|
|
||||||
|
function belt_pitch_to_back(type) = belt_thickness(type) - belt_pitch_height(type); //! Offset of the back from the pitch radius
|
||||||
|
|
||||||
function no_point(str) = chr([for(c = str) if(c == ".") ord("p") else ord(c)]);
|
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.
|
// 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.
|
// The belt is then drawn by offseting each side from the pitch line.
|
||||||
//
|
//
|
||||||
module belt(type, points, gap = 0, gap_pt = undef, belt_colour = grey(20), tooth_colour = grey(50)) { //! Draw a belt path given a set of points and pitch radii where the pulleys are. Closed loop unless a gap is specified
|
module belt(type, points, gap = 0, gap_pos = undef, belt_colour = grey(20), tooth_colour = grey(50)) { //! Draw a belt path given a set of points and pitch radii where the pulleys are. Closed loop unless a gap is specified
|
||||||
width = belt_width(type);
|
width = belt_width(type);
|
||||||
pitch = belt_pitch(type);
|
pitch = belt_pitch(type);
|
||||||
thickness = belt_thickness(type);
|
thickness = belt_thickness(type);
|
||||||
part = str(type[0],pitch);
|
part = str(type[0],pitch);
|
||||||
vitamin(str("belt(", no_point(part), "x", width, ", ", points, arg(gap, 0), arg(gap_pt, undef), "): Belt ", part," x ", width, "mm x ", length, "mm"));
|
vitamin(str("belt(", no_point(part), "x", width, ", ", points, arg(gap, 0), arg(gap_pos, undef), "): Belt ", part," x ", width, "mm x ", length, "mm"));
|
||||||
|
|
||||||
len = len(points);
|
len = len(points);
|
||||||
|
|
||||||
@@ -56,24 +60,28 @@ module belt(type, points, gap = 0, gap_pt = undef, belt_colour = grey(20), tooth
|
|||||||
|
|
||||||
module shape() rounded_polygon(points, tangents);
|
module shape() rounded_polygon(points, tangents);
|
||||||
|
|
||||||
|
ph = belt_pitch_height(type);
|
||||||
|
th = belt_tooth_height(type);
|
||||||
module gap()
|
module gap()
|
||||||
if(gap)
|
if(gap)
|
||||||
translate(gap_pt)
|
translate([gap_pos.x, gap_pos.y])
|
||||||
|
rotate(is_undef(gap_pos.z) ? 0 : gap_pos.z)
|
||||||
|
translate([0, ph - thickness / 2])
|
||||||
square([gap, thickness + eps], center = true);
|
square([gap, thickness + eps], center = true);
|
||||||
|
|
||||||
color(belt_colour)
|
color(belt_colour)
|
||||||
linear_extrude(width, center = true)
|
linear_extrude(width, center = true)
|
||||||
difference() {
|
difference() {
|
||||||
offset(thickness - belt_pitch_height(type)) shape();
|
offset(-ph + thickness ) shape();
|
||||||
offset(-belt_pitch_height(type) + belt_tooth_height(type)) shape();
|
offset(-ph + th) shape();
|
||||||
gap();
|
gap();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
color(tooth_colour)
|
color(tooth_colour)
|
||||||
linear_extrude(width, center = true)
|
linear_extrude(width, center = true)
|
||||||
difference() {
|
difference() {
|
||||||
offset(-belt_pitch_height(type) + belt_tooth_height(type)) shape();
|
offset(-ph + th) shape();
|
||||||
offset(-belt_pitch_height(type)) shape();
|
offset(-ph) shape();
|
||||||
gap();
|
gap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -33,8 +33,7 @@
|
|||||||
// h t s t t t
|
// h t s t t t
|
||||||
// h
|
// h
|
||||||
//
|
//
|
||||||
JHeadMk4 = ["JHeadMk4", jhead, "JHead MK4", 64, 5.1, 16, 50, grey(20), 12, 4.64, 14, [0, 2.94, -5], 20, 20];
|
JHeadMk5 = ["JHeadMk5", jhead, "JHead MK5", 51.2, 4.75,16, 40, grey(20), 12, 4.64, 13, [0, 2.38, -5], 20, 20];
|
||||||
JHeadMk5 = ["JHeadMk5", jhead, "JHead MK5", 51.2, 5.1, 16, 40, grey(20), 12, 4.64, 13, [0, 2.38, -5], 20, 20];
|
|
||||||
E3Dv5 = ["E3Dv5", e3d, "E3D V5 direct", 70, 3.7, 16, 50.1, "silver", 12, 6, 15, [1, 5, -4.5], 14.5, 28];
|
E3Dv5 = ["E3Dv5", e3d, "E3D V5 direct", 70, 3.7, 16, 50.1, "silver", 12, 6, 15, [1, 5, -4.5], 14.5, 28];
|
||||||
E3Dv6 = ["E3Dv6", e3d, "E3D V6 direct", 62, 3.7, 16, 42.7, "silver", 12, 6, 15, [1, 5, -4.5], 14, 21];
|
E3Dv6 = ["E3Dv6", e3d, "E3D V6 direct", 62, 3.7, 16, 42.7, "silver", 12, 6, 15, [1, 5, -4.5], 14, 21];
|
||||||
E3D_clone = ["E3D_clone", e3d, "E3D clone aliexpress",66, 6.8, 16, 46, "silver", 12, 5.6, 15, [1, 5, -4.5], 14.5, 21];
|
E3D_clone = ["E3D_clone", e3d, "E3D clone aliexpress",66, 6.8, 16, 46, "silver", 12, 5.6, 15, [1, 5, -4.5], 14.5, 21];
|
||||||
|
@@ -35,6 +35,15 @@ function insert_ring3_d(type) = type[8]; //! Diameter of the bottom ring
|
|||||||
|
|
||||||
function insert_hole_length(type) = round_to_layer(insert_length(type));
|
function insert_hole_length(type) = round_to_layer(insert_length(type));
|
||||||
|
|
||||||
|
function insert_nose_length(type, d) = let( //! The length before the second ring.
|
||||||
|
length = insert_length(type),
|
||||||
|
ring1_h = insert_ring1_h(type),
|
||||||
|
chamfer1 = (insert_ring2_d(type) - insert_barrel_d(type)) / 2,
|
||||||
|
chamfer2 = (insert_ring3_d(type) - insert_barrel_d(type)) / 2,
|
||||||
|
ring2_h = ring1_h + chamfer1,
|
||||||
|
gap = (length - ring1_h - ring2_h - chamfer2) / 3
|
||||||
|
) ring1_h + gap + ring2_h - d + insert_barrel_d(type);
|
||||||
|
|
||||||
module insert(type) { //! Draw specified insert
|
module insert(type) { //! Draw specified insert
|
||||||
length = insert_length(type);
|
length = insert_length(type);
|
||||||
ring1_h = insert_ring1_h(type);
|
ring1_h = insert_ring1_h(type);
|
||||||
@@ -42,12 +51,12 @@ module insert(type) { //! Draw specified insert
|
|||||||
chamfer1 = (insert_ring2_d(type) - insert_barrel_d(type)) / 2;
|
chamfer1 = (insert_ring2_d(type) - insert_barrel_d(type)) / 2;
|
||||||
chamfer2 = (insert_ring3_d(type) - insert_barrel_d(type)) / 2;
|
chamfer2 = (insert_ring3_d(type) - insert_barrel_d(type)) / 2;
|
||||||
ring2_h = ring1_h + chamfer1;
|
ring2_h = ring1_h + chamfer1;
|
||||||
gap = (length - ring1_h - ring2_h- chamfer2) / 3;
|
gap = (length - ring1_h - ring2_h - chamfer2) / 3;
|
||||||
|
|
||||||
vitamin(str("insert(", type[0], "): Heatfit insert M", insert_screw_diameter(type)));
|
vitamin(str("insert(", type[0], "): Heatfit insert M", insert_screw_diameter(type)));
|
||||||
$fn = 64;
|
$fn = 64;
|
||||||
thread_d = insert_screw_diameter(type);
|
thread_d = insert_screw_diameter(type);
|
||||||
explode(20, offset =[0, 0, -5]) translate_z(eps) vflip() {
|
explode(20, offset = [0, 0, -5]) translate_z(eps) vflip() {
|
||||||
r1 = thread_d / 2;
|
r1 = thread_d / 2;
|
||||||
r2 = insert_barrel_d(type) / 2;
|
r2 = insert_barrel_d(type) / 2;
|
||||||
r3 = insert_ring3_d(type) / 2;
|
r3 = insert_ring3_d(type) / 2;
|
||||||
@@ -58,7 +67,7 @@ module insert(type) { //! Draw specified insert
|
|||||||
h3 = ring1_h + gap + ring2_h;
|
h3 = ring1_h + gap + ring2_h;
|
||||||
h4 = ring1_h + gap + ring2_h + gap;
|
h4 = ring1_h + gap + ring2_h + gap;
|
||||||
color(brass)
|
color(brass)
|
||||||
rotate_extrude()
|
rotate_extrude(convexity = 3)
|
||||||
polygon([
|
polygon([
|
||||||
[r1, 0],
|
[r1, 0],
|
||||||
[r1, length],
|
[r1, length],
|
||||||
|
@@ -29,7 +29,6 @@ include <zipties.scad>
|
|||||||
use <wire.scad>
|
use <wire.scad>
|
||||||
use <../utils/tube.scad>
|
use <../utils/tube.scad>
|
||||||
|
|
||||||
MK4_heater = [ 12.76, 15.88, 8.22, (15.88 / 2 - 4.5), (12.76 / 2 - 0.5 - 2.5 / 2), (-15.88 / 2 + 5), 9.5, 3];
|
|
||||||
MK5_heater = [ 12.76, 12.76, 8.22, (12.76 / 2 - 3.75), (12.76 / 2 - 0.5 - 2.5 / 2), (-12.76 / 2 + 4), 8, 2];
|
MK5_heater = [ 12.76, 12.76, 8.22, (12.76 / 2 - 3.75), (12.76 / 2 - 0.5 - 2.5 / 2), (-12.76 / 2 + 4), 8, 2];
|
||||||
|
|
||||||
function heater_width(type) = type[0];
|
function heater_width(type) = type[0];
|
||||||
@@ -71,7 +70,7 @@ module heater_block(type, resistor, thermistor) {
|
|||||||
cone_start_r = nozzle_cone(type) / 2;
|
cone_start_r = nozzle_cone(type) / 2;
|
||||||
straight = 1;
|
straight = 1;
|
||||||
nozzle_r = 0.4 / 2;
|
nozzle_r = 0.4 / 2;
|
||||||
translate_z(-h / 2) vflip()
|
translate([nozzle_x(type), 0, -h / 2]) vflip()
|
||||||
rotate_extrude()
|
rotate_extrude()
|
||||||
polygon([
|
polygon([
|
||||||
[nozzle_r, 0],
|
[nozzle_r, 0],
|
||||||
@@ -86,7 +85,7 @@ module heater_block(type, resistor, thermistor) {
|
|||||||
module jhead_hot_end(type, filament) {
|
module jhead_hot_end(type, filament) {
|
||||||
resistor = RIE1212UB5C5R6;
|
resistor = RIE1212UB5C5R6;
|
||||||
thermistor = Epcos;
|
thermistor = Epcos;
|
||||||
heater = type == JHeadMk4 ? MK4_heater : MK5_heater;
|
heater = MK5_heater;
|
||||||
|
|
||||||
insulator_length = hot_end_insulator_length(type);
|
insulator_length = hot_end_insulator_length(type);
|
||||||
inset = hot_end_inset(type);
|
inset = hot_end_inset(type);
|
||||||
@@ -106,7 +105,7 @@ module jhead_hot_end(type, filament) {
|
|||||||
|
|
||||||
square([hot_end_insulator_diameter(type) / 2 - chamfer, insulator_length]);
|
square([hot_end_insulator_diameter(type) / 2 - chamfer, insulator_length]);
|
||||||
}
|
}
|
||||||
square([3.2 / 2, insulator_length]);
|
square([(filament + 0.2) / 2, insulator_length]);
|
||||||
|
|
||||||
translate([hot_end_groove_dia(type) / 2, insulator_length - hot_end_inset(type) - hot_end_groove(type)])
|
translate([hot_end_groove_dia(type) / 2, insulator_length - hot_end_inset(type) - hot_end_groove(type)])
|
||||||
square([100, hot_end_groove(type)]);
|
square([100, hot_end_groove(type)]);
|
||||||
@@ -122,7 +121,7 @@ module jhead_hot_end(type, filament) {
|
|||||||
module jhead_hot_end_assembly(type, filament, naked = false) { //! Assembly with resistor, thermistor, tape, sleaving and ziptie
|
module jhead_hot_end_assembly(type, filament, naked = false) { //! Assembly with resistor, thermistor, tape, sleaving and ziptie
|
||||||
resistor = RIE1212UB5C5R6;
|
resistor = RIE1212UB5C5R6;
|
||||||
thermistor = Epcos;
|
thermistor = Epcos;
|
||||||
heater = type == JHeadMk4 ? MK4_heater : MK5_heater;
|
heater = MK5_heater;
|
||||||
|
|
||||||
insulator_length = hot_end_insulator_length(type);
|
insulator_length = hot_end_insulator_length(type);
|
||||||
inset = hot_end_inset(type);
|
inset = hot_end_inset(type);
|
||||||
|
49
vitamins/magnet.scad
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/>.
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
//! Cylindrical and ring magnets.
|
||||||
|
//
|
||||||
|
include <../utils/core/core.scad>
|
||||||
|
|
||||||
|
function magnet_od(type) = type[1]; //! Outer diameter
|
||||||
|
function magnet_id(type) = type[2]; //! Inside diameter if a ring
|
||||||
|
function magnet_h(type) = type[3]; //! Height
|
||||||
|
function magnet_r(type) = type[4]; //! Corner radius
|
||||||
|
|
||||||
|
module magnet(type) { //! Draw specified magnet
|
||||||
|
od = magnet_od(type);
|
||||||
|
id = magnet_id(type);
|
||||||
|
h = magnet_h(type);
|
||||||
|
r = magnet_r(type);
|
||||||
|
|
||||||
|
//vitamin(str("magnet(", type[0], "): Magnet ", od, "mm diameter, ", h, "mm high", id ? str(", ", id, "mm bore") : "" ));
|
||||||
|
|
||||||
|
or = od / 2;
|
||||||
|
ir = id / 2;
|
||||||
|
color(silver)
|
||||||
|
rotate_extrude()
|
||||||
|
union() {
|
||||||
|
translate([ir, 0])
|
||||||
|
rounded_square([or - ir, h], r, center = false);
|
||||||
|
if(!ir)
|
||||||
|
square([r, h]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
30
vitamins/magnets.scad
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
//
|
||||||
|
// NopSCADlib Copyright Chris Palmer 2020
|
||||||
|
// nop.head@gmail.com
|
||||||
|
// hydraraptor.blogspot.com
|
||||||
|
//
|
||||||
|
// This file is part of NopSCADlib.
|
||||||
|
//
|
||||||
|
// NopSCADlib is free software: you can redistribute it and/or modify it under the terms of the
|
||||||
|
// GNU General Public License as published by the Free Software Foundation, either version 3 of
|
||||||
|
// the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// NopSCADlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||||
|
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
// See the GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License along with NopSCADlib.
|
||||||
|
// If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//! Cylindrical and ring magnets.
|
||||||
|
//
|
||||||
|
|
||||||
|
// od, id, h, r
|
||||||
|
MAG8x4x4p2 = ["MAG8x4x4p2", 8, 4.2, 4, 0.5];
|
||||||
|
MAG484 = ["MAG484", inch(1/4), inch(1/8), inch(1/4), 0.5];
|
||||||
|
MAG5x8 = ["MAG484", 8, 0, 5, 0.5];
|
||||||
|
|
||||||
|
magnets = [MAG8x4x4p2, MAG484, MAG5x8];
|
||||||
|
|
||||||
|
use <magnet.scad>
|
@@ -25,7 +25,7 @@
|
|||||||
include <../utils/core/core.scad>
|
include <../utils/core/core.scad>
|
||||||
use <../utils/thread.scad>
|
use <../utils/thread.scad>
|
||||||
|
|
||||||
pitch = 33.8;
|
pitch = 33.8 / 2;
|
||||||
width = 40;
|
width = 40;
|
||||||
depth = 18;
|
depth = 18;
|
||||||
magnet = 4.3;
|
magnet = 4.3;
|
||||||
@@ -37,13 +37,15 @@ pole_l = 36;
|
|||||||
poles = 15;
|
poles = 15;
|
||||||
|
|
||||||
module opengrab_hole_positions() //! Position children at the screw positions
|
module opengrab_hole_positions() //! Position children at the screw positions
|
||||||
for(x = [-1, 1], y = [-1, 1])
|
let($d = 3.2)
|
||||||
translate([x * pitch / 2, y * pitch / 2, 0])
|
for($x = [-pitch, pitch], $y = [-pitch, pitch])
|
||||||
|
translate([$x, $y])
|
||||||
children();
|
children();
|
||||||
|
|
||||||
module opengrab_side_hole_positions() //! Position children at the two 4mm hole
|
module opengrab_side_hole_positions() //! Position children at the two 4mm hole
|
||||||
for(side = [-1, 1])
|
let($d = 4, pitch = width / 2 - 3.5)
|
||||||
translate([side * (width / 2 - 3.5), 0])
|
for($x = [-pitch, pitch])
|
||||||
|
translate([$x, 0])
|
||||||
children();
|
children();
|
||||||
|
|
||||||
function opengrab_width() = width; //! Module width
|
function opengrab_width() = width; //! Module width
|
||||||
@@ -94,9 +96,9 @@ module opengrab_target() { //! Draw OpenGrab target
|
|||||||
square([width, width], center = true);
|
square([width, width], center = true);
|
||||||
|
|
||||||
opengrab_hole_positions()
|
opengrab_hole_positions()
|
||||||
circle(d = 3.2);
|
circle(d = $d);
|
||||||
|
|
||||||
opengrab_side_hole_positions()
|
opengrab_side_hole_positions()
|
||||||
circle(d = 4);
|
circle(d = $d);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|