1
0
mirror of https://github.com/nophead/NopSCADlib.git synced 2025-09-02 11:52:42 +02:00

Compare commits

...

427 Commits

Author SHA1 Message Date
Chris Palmer
1eb8b378e9 Added magnets 2020-08-23 16:46:29 +01:00
Chris Palmer
362dbdb4fc Opengrab hole position children now passed diameter. 2020-08-22 14:32:23 +01:00
Chris Palmer
57d223d84b Added insert_nose_length() 2020-08-22 14:31:06 +01:00
Chris Palmer
699385342f quadrant can now have different height and width if passed a vector. 2020-08-22 14:27:01 +01:00
Chris Palmer
547a418cea Hanging hole now works when the hole has only four sides. 2020-08-22 13:52:25 +01:00
Chris Palmer
b6d25048bc Fixed belt gap positioning and added ability to rotae it. 2020-08-22 11:16:56 +01:00
Chris Palmer
4cdab218d9 Fix belt positioning bug.
Belt gap position is now relative to the pitch line.
Added belt_pitch_to_back().
2020-08-22 09:45:13 +01:00
Chris Palmer
b6147e5684 Code formatting 2020-08-13 17:02:14 +01:00
Chris Palmer
966ba536ed Fixed J-Head nozzle offset.
Reduced J-Head inset.
Removed J-Head MK4.
2020-08-13 12:44:17 +01:00
Chris Palmer
2419d50641 Added more PTFE tube sizes and amde them whiter. 2020-08-13 12:30:39 +01:00
Chris Palmer
02211c2034 Added tubing_or() and center option. 2020-08-13 11:56:53 +01:00
Chris Palmer
77d73b075d Added opengrab_side_hole_positions() 2020-08-13 11:55:31 +01:00
Chris Palmer
cb54a3131b Added USB-C connector, micro hdmi and RPI4. 2020-08-01 19:38:22 +01:00
Chris Palmer
3cf275579c Fixed ball bearing chamfers. 2020-07-31 01:33:33 +01:00
Chris Palmer
fb41f218fe Added involute_gear_od() function. 2020-07-28 21:24:01 +01:00
Chris Palmer
e6a26bc7b1 Changed some teardrop holes to teardrop plus. 2020-07-20 20:39:01 +01:00
Chris Palmer
cb4fa40643 Reimplemented teardrop_plus() again. 2020-07-20 16:55:55 +01:00
Chris Palmer
6a26903514 Added blog links for horiholes. 2020-07-18 23:53:15 +01:00
Chris Palmer
d08d949887 Corrected teardrop_plus() shape to be an accurate compensation for slicer
staircasing and added a plus option to tearslot(), etc.

Added horiholes.scad to depict staircase holes.
2020-07-18 19:28:26 +01:00
Chris Palmer
574a73e527 More spelling 2020-07-14 23:39:36 +01:00
Chris Palmer
87a35126de Spelling. 2020-07-14 09:48:30 +01:00
Chris Palmer
1ca485b66b Added involute_worm_profile() and involute_rack_tooth_profile() functions. 2020-07-14 09:47:45 +01:00
Chris Palmer
bc919529d3 Tweaks to thread.
Better thread crest detection.
No longer shrtens thread by eps (to avoid z fight) if all one colour.
Comment about left hand threads.
2020-07-14 09:42:32 +01:00
Chris Palmer
9f4ed2b915 Fixed capitalisation of Swiss_clips.scad. 2020-07-12 00:27:26 +01:00
Chris Palmer
7ce055373a Add rack to mesh with involute spur gears. 2020-07-07 22:36:34 +01:00
Chris Palmer
71ac571346 Added a utility for making involute spur gears 2020-07-06 23:22:11 +01:00
Chris Palmer
e4d93366fa Added degrees, radians and rot2_z() to maths.scad. 2020-07-06 12:43:24 +01:00
Chris Palmer
f047ac27f7 Added SMR95 ball bearing 2020-07-04 17:30:26 +01:00
Chris Palmer
a9e479d971 Documented camera lens module. 2020-07-04 14:57:01 +01:00
Chris Palmer
47b01af1ea Added RPI camera V2
Add cameras to lib.scad
2020-07-04 14:54:19 +01:00
Chris Palmer
fe19eba237 Tweaked flat_flex connectors. 2020-07-04 14:14:25 +01:00
Chris Palmer
235f7b86e3 Camera connector position and size separated.
Camera_lens() module added.
2020-07-04 09:55:38 +01:00
Chris Palmer
92d7e18b16 Added pcb_size() function. 2020-07-04 09:53:09 +01:00
Chris Palmer
6a7226120f Fixed RPI camera component positions. 2020-06-30 18:57:14 +01:00
Chris Palmer
8aa00cd041 Added MGN12H rail and included MGN12 in the test. 2020-06-30 09:28:32 +01:00
Chris Palmer
f6b512da1f Added a couple of Raspberry Pi cameras. 2020-06-29 23:03:54 +01:00
Chris Palmer
c7ea0939b9 Made flat_flex parametric and changed default orientation. 2020-06-29 23:01:34 +01:00
Chris Palmer
265b5ab555 Fixed layout to work with an empty list. 2020-06-27 20:00:47 +01:00
Chris Palmer
186dbbfd08 Added SMT resistors and 0603 LED. 2020-06-27 19:59:49 +01:00
Chris Palmer
60659a43f8 Added light_strip_clip_wall(). 2020-06-24 16:42:17 +01:00
Chris Palmer
f412cb1736 Tweaked lightstrip dimensions. 2020-06-21 20:35:13 +01:00
Chris Palmer
2b878556fc Bug fix to platters.scad for last change. 2020-06-21 16:00:26 +01:00
Chris Palmer
1f1a360b7c Mods to allow panels and platters to be target specific or not. 2020-06-21 12:53:14 +01:00
Chris Palmer
a547c98995 Added shelf bracket to printed/box.scad. 2020-06-20 15:12:09 +01:00
Chris Palmer
d9fa8c8668 Added position children used for drilling holes on sheets. 2020-06-20 15:04:03 +01:00
Chris Palmer
bf5b6d7c30 Added matrix inversion 2020-06-20 15:01:01 +01:00
Chris Palmer
9cfde7f524 Updated readme for grey() change. 2020-06-20 14:56:38 +01:00
Chris Palmer
184f19ef04 Replaced grey constants with a function grey().
Done to reduced the number of global constants.
2020-06-20 10:17:29 +01:00
Chris Palmer
c88472121e Replaced hard coded number with constant. 2020-06-01 13:46:11 +01:00
Chris Palmer
a74bf094aa Added TUK FACK2SPM Cat5E RJ45 shielded panel mount coupler. 2020-05-30 15:29:28 +01:00
Chris Palmer
5a06f79466 Updated gallery pic. 2020-05-26 18:24:04 +01:00
Chris Palmer
98e17080d8 Added meter_shunt_y() function to led_meter. 2020-05-26 15:19:38 +01:00
Chris Palmer
d3f308a45e Pixel differences in images due to OpenSCAD version update. 2020-05-20 21:58:07 +01:00
Chris Palmer
fe454884e0 Fixed Ampmeter typo. 2020-05-20 21:41:54 +01:00
Chris Palmer
c019448dd3 Unused imaged removed. 2020-05-20 21:40:13 +01:00
Chris Palmer
eadc541e8f Screw_and_washer() no longer adds washers for countersunk screws. 2020-05-18 15:29:19 +01:00
Chris Palmer
02791c40ac pbox_outer_shape() added and pbox_screw_positions() documented. 2020-05-18 15:28:26 +01:00
Chris Palmer
85b8ffbbc3 Fixed pin header parameter values passed from PCBs. 2020-05-18 15:27:22 +01:00
Chris Palmer
dd5d3869ad Removed old file 2020-05-18 15:04:41 +01:00
Chris Palmer
b84eb3cf31 Updated big picture 2020-05-02 21:38:53 +01:00
Chris Palmer
0ec7aabcfb Modelled DSP5005 power supply module as a panel_meter.
Panel_meters can now have inner apertures and buttons.
2020-05-02 20:42:26 +01:00
Chris Palmer
baa737c4d8 Updated example to use Foot contructor. 2020-05-02 20:28:55 +01:00
Chris Palmer
70b13d2f27 Added functions to create property lists that are created by the client.
Foot, box, bbox, pbox, flat_hinge and strap_handle.
2020-05-02 20:27:32 +01:00
Chris Palmer
c9aad0178e Fixed typo 2020-05-02 11:50:01 +01:00
Chris Palmer
df96551b11 Fixed PCB cutouts bugs, i.e. components drawn instead of cutouts. 2020-04-30 13:31:20 +01:00
Chris Palmer
a5a360e0d1 Updated images. 2020-04-29 15:19:39 +01:00
Chris Palmer
828e5ad36e make_all.py now terminates early if there are any errors in bom generation. 2020-04-29 15:19:10 +01:00
Chris Palmer
cedaafed3d More precise led positions on WD2002SJ pcb. 2020-04-25 19:39:16 +01:00
Chris Palmer
0d38d82416 led_ammeter size tweaks. 2020-04-25 19:38:43 +01:00
Chris Palmer
041341b946 Fixed indentation in platters.py. 2020-04-24 12:05:10 +01:00
Chris Palmer
70622ba8de Gallery update 2020-04-24 10:17:55 +01:00
Chris Palmer
4ab0a981ef Added panel_meters for panel mount digital meters. 2020-04-23 23:45:25 +01:00
Chris Palmer
bb7dd51270 Added poly_drill() and used it for LED and trimpot cutouts.
Uses drill if cnc_bit_r is non-zero else poly_cylinder.
2020-04-23 23:13:10 +01:00
Chris Palmer
48293b9abd Poly_ring now can have specified number of sides. 2020-04-23 10:52:34 +01:00
Chris Palmer
c9d10eeb8b Renamed meters to LED_meters and added ammeter version. 2020-04-21 21:50:38 +01:00
Chris Palmer
192460c0fa Added SMD 0805 LEDs. 2020-04-21 11:02:48 +01:00
Chris Palmer
d4402c6713 Corrected Molex USB tab length 2020-04-20 18:51:26 +01:00
Chris Palmer
b9890ca589 Reduced printed box screw inset when top_thickness is zero. 2020-04-20 17:53:26 +01:00
Chris Palmer
026b9daf59 Added molex_usb_Ax2 connector. 2020-04-20 17:52:37 +01:00
Chris Palmer
2afc00cfa9 Added tongues to USB A connectors 2020-04-20 17:51:02 +01:00
Chris Palmer
84b5686af6 Corrected WD2002SJ heatsink thickness 2020-04-20 17:47:37 +01:00
Chris Palmer
71af8f98ed Added Swiss clip. 2020-04-16 00:59:27 +01:00
Chris Palmer
6cecb4d466 Added missing comment 2020-04-14 18:21:42 +01:00
Chris Palmer
4ef926a18f Added axial PCB mounted resistors. 2020-04-14 18:09:58 +01:00
Chris Palmer
5afc4f816c Added PDIP ICS and sockets. 2020-04-13 18:06:09 +01:00
Chris Palmer
5be14f5e89 Fixed bug updating the times file when case changes.
First column split of vitamins now at J.
2020-04-13 18:02:03 +01:00
Chris Palmer
efff17dfc7 Ball bearing chamfer less and 6808 hub corrected. 2020-04-11 23:46:37 +01:00
Chris Palmer
ac4a5500a9 Added chamfers and made hub and rim properties of ball_bearings. 2020-04-11 17:29:02 +01:00
Chris
6b90a7aac8 Merge pull request #72 from ledvinap/patch-1
nut_radius is needed for screw_boss_diameter
2020-04-10 12:51:39 +01:00
Chris Palmer
3c3d72f366 Merge branch 'master' of https://github.com/nophead/NopSCADlib 2020-04-10 12:41:41 +01:00
Chris Palmer
dbcab8377f LEDs can now be placed on PCBs. 2020-04-10 12:41:05 +01:00
Chris Palmer
11d96d37e1 LEDs can not be placed on PCBs. 2020-04-10 12:39:46 +01:00
Petr Ledvina
40843b421f nut_radius is needed for screw_boss_diameter
using `include <NopSCADlib/lib.scad>` in main file fails in `screw_boss_diameter`:
`WARNING: Ignoring unknown function 'nut_radius', in file ../../../sw/OpenSCAD/libraries/NopSCADlib/vitamins/screw.scad, line 41.`

Maybe my library usage is wrong, I did not investigate further ...
2020-04-09 20:33:59 +02:00
Chris Palmer
cc8f4d3bd3 Tweaked test PCB layout 2020-04-09 18:33:59 +01:00
Chris Palmer
69d6fc8bf0 PCB test now shorter and wider for better view. 2020-04-09 17:35:49 +01:00
Chris Palmer
01b1e2e84d Added WD2002SJ Buck Boost DC-DC converter PCB 2020-04-08 20:53:19 +01:00
Chris Palmer
cb64cadb92 Added gterm508. 2020-04-08 19:52:35 +01:00
Chris Palmer
b57b50d2b0 Added yet another type of green terminal that is blue. 2020-04-08 19:38:52 +01:00
Chris Palmer
8f282775a4 Fixed green terminal pin centering. 2020-04-08 19:15:38 +01:00
Chris Palmer
bf833b0452 Fixed some typos 2020-04-08 19:13:06 +01:00
Chris Palmer
52011fd6f7 Renders of dxfs now use the sheet colour. 2020-04-07 22:07:28 +01:00
Chris Palmer
9da8634769 Bom generation now calls openscad with --hardwarnings to stop ASAP. 2020-04-07 19:36:38 +01:00
Chris Palmer
147ff9b24f Added alpha parameter to stl_colour() 2020-04-07 17:02:10 +01:00
Chris Palmer
b4379907a2 Updated gallery 2020-04-06 16:21:58 +01:00
Chris Palmer
3be88f6517 Some more stl_colours. 2020-04-06 15:02:50 +01:00
Chris Palmer
d42f99e437 stl_colour() now used in tests and examples. 2020-04-06 10:27:17 +01:00
Chris Palmer
65455930f8 Reverted incorrect use of stl_colour(). 2020-04-05 18:51:21 +01:00
Chris Palmer
7e0c5fdb6e Renders of STLs are now the correct colour. Fixes #71 2020-04-05 16:18:24 +01:00
Chris Palmer
bc4e18d788 The assembly module now has a big parameter to force large or small views. 2020-04-04 12:06:14 +01:00
Chris Palmer
f5980b4703 Made the ground surfaces of steppers lighter. 2020-04-02 19:54:30 +01:00
Chris Palmer
7b3d7fab55 Fixed some more colour spellings 2020-03-29 21:36:11 +01:00
Chris Palmer
654571a70e Colour now always spelt colour except the call to color(). 2020-03-29 20:39:17 +01:00
Chris Palmer
e8abcde52f Removed the height parameter from linear_extrude 2020-03-29 20:18:57 +01:00
Chris Palmer
390957fdd0 Added MT3608 and TP4065 PCBs.
Perfboards now have their own row in the test to shorten the picture.
2020-03-28 10:54:06 +00:00
Chris Palmer
bde8cbe7a6 Added cutout for trimpot10. 2020-03-28 10:51:43 +00:00
Chris Palmer
fbe8533a42 Added function to get the height of pcb carriers. 2020-03-27 17:30:35 +00:00
Chris Palmer
a9c2f854c6 Can now have rectangular lands on PCB holes. 2020-03-27 17:29:50 +00:00
Chris Palmer
6187d90c57 Added 10 turn trimpots 2020-03-27 17:28:20 +00:00
Chris Palmer
65f320141d Added printed carriers for MT3608 and TP4056 modules. 2020-03-26 22:33:05 +00:00
Chris Palmer
d367e743da Image churn due to change of computer. 2020-03-24 17:30:10 +00:00
Chris Palmer
3a4305f5ca Nuts can now have non-standard pitch, toggle switch nut pitch fixed. 2020-03-24 17:29:29 +00:00
Chris Palmer
a7dde2d4e2 Fixed short thread bug although threads should not be that short. 2020-03-24 17:28:10 +00:00
Chris Palmer
56390bf8dd Updated big picture 2020-03-24 17:27:33 +00:00
Chris Palmer
53f0bbcd6e Fixed long SCS_bearing blocks to use two short bearings and added circlips. 2020-03-24 17:24:08 +00:00
Chris Palmer
f2ec3e71f4 Added circlips. 2020-03-24 17:22:32 +00:00
Chris Palmer
c1b5bd1b87 Added seal lip to linear_bearings. 2020-03-24 17:20:59 +00:00
Chris Palmer
268c066965 Added documentation for platters and panels in usage.md. 2020-03-15 21:11:15 +00:00
Chris Palmer
fd8712d6bf Updated images and readme. 2020-03-15 17:35:21 +00:00
Chris Palmer
b6a32b6b41 Fixed square nut threads. 2020-03-15 17:16:28 +00:00
Chris Palmer
0738893510 Merge branch 'square-nuts' of https://github.com/FLamparski/NopSCADlib into FLamparski-square-nuts 2020-03-15 17:06:15 +00:00
Filip Wieland
849bc479cc Adds DIN 562 square nuts 2020-03-15 17:01:48 +00:00
Chris
86d7e0f124 Merge pull request #66 from FLamparski/fix-windows-paths-with-spaces
Fix handling of (Windows) paths with spaces
2020-03-15 16:34:58 +00:00
Filip Wieland
c897060726 Fix handling of Windows paths with spaces 2020-03-15 16:25:18 +00:00
Chris Palmer
b2c2fc668b Added descriptions to doc_scripts.py and gallery.py. 2020-03-15 16:11:27 +00:00
Chris Palmer
4914f90994 Now ensures project scad dir searched first. 2020-03-12 22:56:56 +00:00
Chris Palmer
2210396234 Now uses the dependencies to locate modules for printed parts and assemblies. 2020-03-12 22:47:27 +00:00
Chris Palmer
2eef050f60 Missing bracket. 2020-03-11 23:11:34 +00:00
Chris Palmer
23a64f238d Added usage messages to all the scripts and documented multiple configuration
projects.
2020-03-11 23:09:03 +00:00
Chris Palmer
a8422a6aa6 Updated main image 2020-03-07 22:16:53 +00:00
Chris Palmer
b56ddea1e3 Can now have PCB screw holes without screws for RAMPS endstop. 2020-03-07 22:11:09 +00:00
Chris Palmer
c16a1c3804 Moved cable strips nearer the back of the libtest picture. 2020-03-05 20:55:57 +00:00
Chris Palmer
245b158f1d Added threads to fuseholder. 2020-03-05 10:15:42 +00:00
Chris Palmer
60628dfec0 Added threads to 4mm jack sockets. 2020-03-04 17:42:03 +00:00
Chris Palmer
f7db793c74 Assembly module search in views.py now case insensitive
allowing the module name string to specify the capitalisaing used in the
build instructions.
2020-03-04 12:15:48 +00:00
Chris Palmer
53292c9f89 Filenames of tests can now be capitalised to get the correct titles.
The implementation files are still lower case for backwards compatibility.
2020-03-03 20:33:53 +00:00
Chris Palmer
bd60b50b09 Removed lower case tests 2020-03-03 20:28:18 +00:00
Chris Palmer
4d51cb73f3 Table of contents now has three vitamin coloumns 2020-03-03 09:32:08 +00:00
Chris Palmer
3b77c97532 Example now include core.scad instead of lib.scad. 2020-03-02 21:04:19 +00:00
Chris Palmer
4442042197 Include of wire.scad changed to use. 2020-03-02 21:03:41 +00:00
Chris Palmer
4e233e5e9d Updated readme and images 2020-03-02 19:45:28 +00:00
Martin Budden
675953d334 Allow no center hole in extrusion. 2020-03-02 19:06:53 +00:00
Martin Budden
9527fa1c1f Added E1515 extrusion. 2020-03-02 18:51:27 +00:00
Chris
3f209cbdd3 Merge pull request #60 from nophead/issue_57
Fix for issue #57, now searches multiple directories.
2020-03-02 18:38:36 +00:00
Chris Palmer
7b76aceaad Changed microswitch include to a use. 2020-03-02 14:15:51 +00:00
Chris Palmer
4edd08977f Added green_terminals and pin_headers to lib.scad.
Removed terminal_254() because it can't work.
2020-03-02 13:51:59 +00:00
Chris Palmer
a1d385f9ec Updated gallery images 2020-03-02 13:49:41 +00:00
Chris Palmer
fc17b52518 Added missing includes in lib.scad: extrusion_brackets and kp_pillow_blocks.
Since kp_pillow_blocks includes ball bearings, they were also missing.
2020-03-02 09:52:31 +00:00
Chris Palmer
9fbdb82991 bom.py now shows errors and warnings. 2020-03-02 09:38:37 +00:00
Chris Palmer
7706716fa2 Updated readme for threads. 2020-03-01 20:08:19 +00:00
Chris Palmer
c815c1592d SHOW_THREADS renamed NOPSCADLIB_SHOW_THREADS for #61 2020-03-01 19:10:40 +00:00
Chris Palmer
e32ef88c90 Small optimisation to views.py 2020-03-01 19:09:18 +00:00
Chris Palmer
702c450a27 Small optimisation to exports.py 2020-03-01 18:35:53 +00:00
Chris Palmer
343351155c Made library search order deterministic by sorting the result of os.listdir() 2020-03-01 17:53:20 +00:00
Chris Palmer
c41b1fa115 Fix for issue #57, now searches multiple directories. 2020-03-01 10:55:52 +00:00
Chris Palmer
1a197ac823 Fixed missing screw holes in blowers. 2020-02-29 20:34:05 +00:00
Chris Palmer
ab592e049c Screws.scad is now included in core.scad, so doesn't need to be included
anywhere else. utils/core/core.scad is the old version without fasteners to
be used internally in the library.
2020-02-29 17:52:36 +00:00
Chris Palmer
9b104e4fe7 Changed the default printed part colour, pp1_colour to RepRap logo green. 2020-02-29 10:30:15 +00:00
Chris Palmer
f0b4d767e9 Replaced "lime" with pp1_colour. 2020-02-29 10:26:25 +00:00
Chris Palmer
82baed4c8f Updated images and readme. 2020-02-29 09:00:20 +00:00
Chris Palmer
acb2cb2a48 Changed PSU list order to get all the shrouds together. 2020-02-29 08:55:40 +00:00
Chris Palmer
cf94972b18 Merge branch 'psu_vents' of https://github.com/martinbudden/NopSCADlib into martinbudden-psu_vents 2020-02-29 08:48:33 +00:00
Chris Palmer
7c0a48d0c1 Added parametric printed box 2020-02-29 01:27:17 +00:00
Martin Budden
a5a640e273 Added facility to add vents to PSU. Added vents to S_300_12. 2020-02-28 21:21:11 +00:00
Chris Palmer
95c4359421 Better test coverage of stepper earth tag position. 2020-02-28 14:27:35 +00:00
Chris Palmer
bcff26a27b Added threads to stepper motors and made the test show them. 2020-02-28 12:02:24 +00:00
Chris Palmer
07b00fabe0 Added a guard against and empty BOM in views.py. 2020-02-28 09:22:50 +00:00
Chris Palmer
8ed0f3c1af Updated readme and images. 2020-02-28 09:05:59 +00:00
Martin Budden
0e8e387d35 Improved S_300_12 PSU. 2020-02-28 03:05:45 +00:00
Chris Palmer
0c17620adb Removed echo from extrusion_bracket.scad 2020-02-28 01:59:00 +00:00
Chris Palmer
6470f1b004 Extrusions now default to centered. New parts added to the libtest picture.
Extrusion bracket examples rotated for clearer view and made optional.
Added missing description for scs_bearing_blocks.
Extrusion no longer shows centre parameter but does show no default cornerHole.
2020-02-27 17:55:03 +00:00
Chris Palmer
29ba402530 Updated image 2020-02-27 11:22:02 +00:00
Chris Palmer
aed4a699f2 Merge branch 'kp_pillow_block_fix' of https://github.com/martinbudden/NopSCADlib into martinbudden-kp_pillow_block_fix 2020-02-27 11:18:54 +00:00
Chris Palmer
10b846c0d5 Updated images 2020-02-27 11:17:07 +00:00
Martin Budden
2de479d691 Fixed incomplete webbing on side of kp_pillow_block. 2020-02-27 10:44:00 +00:00
Chris Palmer
054dab5025 Merge branch 'linear_rail_groove' of https://github.com/martinbudden/NopSCADlib into martinbudden-linear_rail_groove 2020-02-27 10:35:09 +00:00
Chris Palmer
b559319b03 Ensured all Markdown table heading markers have at least three dashes. 2020-02-27 10:15:37 +00:00
Martin Budden
a487ca0f20 Added groove to linear_rail. 2020-02-27 09:47:36 +00:00
Chris Palmer
a2ce3f1278 Updated readme 2020-02-27 09:44:54 +00:00
Chris Palmer
01eb6931d9 Merge branch 'extrusion_center' of https://github.com/martinbudden/NopSCADlib into martinbudden-extrusion_center 2020-02-27 09:41:01 +00:00
Chris Palmer
c09a74b4c9 Added center option to spring and documented the origin of rods, etc. 2020-02-27 09:39:05 +00:00
Martin Budden
aab7f3d683 Added center parameter. Added cornerhole dimensions to E20. 2020-02-27 09:03:23 +00:00
Chris Palmer
ad719dad5a Added copyright boiler plate and description.
Updated images and readme.
2020-02-26 19:43:02 +00:00
Chris Palmer
00690b61d2 Merge branch 'extrusion_corner_brackets' of https://github.com/martinbudden/NopSCADlib into martinbudden-extrusion_corner_brackets 2020-02-26 19:23:39 +00:00
Chris Palmer
1a24e0d87e Added image and updated readme. 2020-02-26 15:55:22 +00:00
Chris Palmer
171c9a6a34 Merge branch 'pcb_additions' of https://github.com/martinbudden/NopSCADlib into martinbudden-pcb_additions 2020-02-26 15:39:12 +00:00
Chris Palmer
8bb4b3881e Fixed test, image and readme updated. 2020-02-26 15:24:33 +00:00
Chris Palmer
79f8bc66e1 Merge branch 'Drachenkaetzchen-patch-1' of https://github.com/Drachenkaetzchen/NopSCADlib into Drachenkaetzchen-Drachenkaetzchen-patch-1 2020-02-26 14:58:27 +00:00
Chris Palmer
33c9d158ef REmoved fans.scad from lib.scad as already included from psus.scad. 2020-02-26 14:03:46 +00:00
Chris Palmer
d2874a0531 Moved washers.scad from screws.scad to nuts.scad.
Moved screw_insert() from inserts.scad to screw.scad.
Changed most includes of inserts.scad to use insert.scad.
Removed linear_bearings, iecs, rockers and microswitches from lib.scad as
already included by other vitamins.
2020-02-26 13:46:11 +00:00
Felicia Hummel
b6fd795a25 Updated readme to reflect the pillow block changes 2020-02-26 13:02:17 +01:00
Felicia Hummel
ad0882db40 Added 15mm and 18mm variants for the KP08 blocks 2020-02-26 12:57:53 +01:00
Chris Palmer
8afb08aaa4 Updated image 2020-02-26 10:23:05 +00:00
Martin Budden
e87dffd92c More pcb component examples. Allowed more colour setting. 2020-02-26 07:19:55 +00:00
Martin Budden
c364bf06b2 Code tidy. 2020-02-25 22:34:13 +00:00
Martin Budden
1668f9c54c Naming update. 2020-02-25 22:23:44 +00:00
Martin Budden
e0dd174010 Parameterisation of extrusion brackets. 2020-02-25 22:19:20 +00:00
Martin Budden
f104bd42e5 Added back jst_xh connector to ramps endstop. 2020-02-25 21:38:53 +00:00
Martin Budden
8342ba87e9 Update as per code review. 2020-02-25 21:07:29 +00:00
Martin Budden
0e58e92fbc Allowed parameterised green terminals on PCBs. 2020-02-25 21:01:04 +00:00
Martin Budden
1af2e18594 Added usb_Ax1 and potentiometer. 2020-02-25 20:39:37 +00:00
Martin Budden
598527edbe Added a test pcb. 2020-02-25 20:13:15 +00:00
Martin Budden
9c666f8f47 Merge branch 'pin_header_color' into pcb_additions 2020-02-25 19:07:58 +00:00
Martin Budden
bc1f135e40 Added ability to set socket color. 2020-02-25 17:06:16 +00:00
Martin Budden
ce36729e50 Allow pin header base colour to be set on PCB. 2020-02-25 17:05:48 +00:00
Martin Budden
1dca024e64 Internal and external corner brackets for 20nn extrusion. 2020-02-25 16:53:51 +00:00
Chris Palmer
c1833f0820 Updated image and readme. 2020-02-25 13:42:31 +00:00
Chris Palmer
6a7f7dcbbf Merge branch 'sk_bracket_screw_length' of https://github.com/martinbudden/NopSCADlib into martinbudden-sk_bracket_screw_length 2020-02-25 12:34:19 +00:00
Chris Palmer
5d3f1115bb Updated readme and images 2020-02-25 11:11:05 +00:00
Chris Palmer
9f9adeb6ca Merge branch 'teardrop_chamfer' of https://github.com/martinbudden/NopSCADlib into martinbudden-teardrop_chamfer 2020-02-25 09:44:38 +00:00
Chris Palmer
f9b06c855c Merge branch 'martinbudden-kp_pillow_block' 2020-02-25 09:32:55 +00:00
Chris Palmer
05bfe9b159 Updated and images. 2020-02-25 09:32:40 +00:00
Martin Budden
f961874ce3 Added kp_pillow_blocks. 2020-02-25 07:55:47 +00:00
Martin Budden
7a6210f442 Add optional chamfer to teardrops. Defaults to no chamfer. 2020-02-25 07:46:57 +00:00
Martin Budden
5bae0aaa51 Better sk_bracket screw length calculation. 2020-02-25 07:33:07 +00:00
Chris Palmer
8649d59e8a Merge branch 'martinbudden-print_search_path' 2020-02-25 00:05:12 +00:00
Chris Palmer
e9bc300b8d Fix for printed directory not present. 2020-02-24 23:58:22 +00:00
Chris Palmer
dcb1e74894 Merge branch 'print_search_path' of https://github.com/martinbudden/NopSCADlib into martinbudden-print_search_path 2020-02-24 19:02:50 +00:00
Chris Palmer
42b9479094 Merge branch 'martinbudden-tnuts_and_hammer_nuts' 2020-02-24 18:37:40 +00:00
Chris Palmer
f46f35e909 Updated readme 2020-02-24 18:37:25 +00:00
Chris Palmer
0513b151b2 Merge branch 'tnuts_and_hammer_nuts' of https://github.com/martinbudden/NopSCADlib into martinbudden-tnuts_and_hammer_nuts 2020-02-24 18:22:05 +00:00
Chris Palmer
dcf258f11a Brass colour now distinct from gold. 2020-02-24 18:15:20 +00:00
Martin Budden
4ff6c7d0a8 Unified tnuts and hammer nuts. 2020-02-24 17:40:39 +00:00
Chris Palmer
2edb6d4df2 Shorter screws when using T-nut but mignt not be a suitable standard size. 2020-02-24 12:01:40 +00:00
Chris Palmer
26e8497018 Merge branch 'martinbudden-sk_brackets_tidy' 2020-02-24 11:42:07 +00:00
Chris Palmer
bfde879ce2 Updated readme and images. 2020-02-24 11:41:39 +00:00
Chris Palmer
4641e3a642 More nut and screw types 2020-02-24 11:40:30 +00:00
Chris Palmer
42cfed8846 Set default part thickness to 2. 2020-02-24 11:38:31 +00:00
Chris Palmer
8c339a18c4 Removed washers from T-nuts and used the lack to detect them. 2020-02-24 11:23:10 +00:00
Chris Palmer
065ec0a430 Corrected nut placement 2020-02-24 11:18:34 +00:00
Chris Palmer
e7eea0520c T nut thickness no longer includes the stem to simplyfy placement and screw
length calculations.
2020-02-24 11:14:30 +00:00
Chris Palmer
5cb994b58b Retabulated nut table 2020-02-24 10:21:37 +00:00
Chris Palmer
573425055a Fixed origin of T-nuts to be consistent with others.
I.e the mating face is at Z = 0.
2020-02-24 09:11:59 +00:00
Chris Palmer
66a7a9bfe0 Used named elements of size. 2020-02-24 08:57:22 +00:00
Chris Palmer
0335545334 Merge branch 'sk_brackets_tidy' of https://github.com/martinbudden/NopSCADlib into martinbudden-sk_brackets_tidy 2020-02-24 08:38:16 +00:00
Chris Palmer
fa91acbaad Merge branch 'martinbudden-scs_bearing_blocks' 2020-02-24 00:03:42 +00:00
Chris Palmer
8bad05e721 Added to lib.scad 2020-02-24 00:00:32 +00:00
Chris Palmer
9d6727d371 Added images and readme 2020-02-23 23:57:18 +00:00
Chris Palmer
8902d83f0a Merge branch 'scs_bearing_blocks' of https://github.com/martinbudden/NopSCADlib into martinbudden-scs_bearing_blocks 2020-02-23 23:40:02 +00:00
Martin Budden
e40b10f5a0 Added comment. 2020-02-23 23:08:34 +00:00
Martin Budden
66a8d1d583 Tidy of sk_brackets as per scs_bearing_blocks code review. 2020-02-23 22:56:47 +00:00
Martin Budden
d066648a76 Renamed sheet_thickness to part_thickness. 2020-02-23 22:34:59 +00:00
Chris Palmer
b8546414c0 Fixed leadscrew when center = false. 2020-02-23 21:54:26 +00:00
Martin Budden
581c2f8a96 Used accessor functions internally. 2020-02-23 21:49:35 +00:00
Martin Budden
e9ee88dfe9 Updates as per code review. 2020-02-23 21:41:47 +00:00
Martin Budden
b07a8ad245 Added SCS bearing blocks, SCSnUU and SCSnLUU variants 2020-02-23 21:06:38 +00:00
Chris Palmer
ab17de3b0b Merge branch 'martinbudden-green_terminals' 2020-02-23 19:53:10 +00:00
Chris Palmer
0b8141844c Updated readme. 2020-02-23 19:52:18 +00:00
Chris Palmer
7d0548b033 Merge branch 'green_terminals' of https://github.com/martinbudden/NopSCADlib into martinbudden-green_terminals 2020-02-23 19:49:16 +00:00
Martin Budden
ad3e8d85af Added scad/printed to stl search path. 2020-02-23 17:54:28 +00:00
Chris Palmer
8435a350d0 Merge branch 'martinbudden-sk_brackets' 2020-02-23 17:32:54 +00:00
Chris Palmer
3e5d4b1c8e Added to lib.scad. 2020-02-23 17:12:47 +00:00
Chris Palmer
20f830a008 Added image and updated readme. 2020-02-23 16:46:27 +00:00
Chris Palmer
10bd8ff354 Merge branch 'sk_brackets' of https://github.com/martinbudden/NopSCADlib into martinbudden-sk_brackets 2020-02-23 16:22:11 +00:00
Chris Palmer
4459cca3ea Merge branch 'martinbudden-screw_length_formatting' 2020-02-23 16:16:30 +00:00
Chris Palmer
95bbebd42d Updated readme. 2020-02-23 16:16:09 +00:00
Martin Budden
cc84a5a536 Added comments and ability to set colour to green terminals. 2020-02-23 15:38:02 +00:00
Chris Palmer
28c795e9f4 Merge branch 'screw_length_formatting' of https://github.com/martinbudden/NopSCADlib into martinbudden-screw_length_formatting 2020-02-23 15:24:43 +00:00
Chris Palmer
9a0477d16b Merge branch 'martinbudden-pcb_microswitch2' 2020-02-23 15:22:43 +00:00
Chris Palmer
0583da2eb7 Added images 2020-02-23 15:22:25 +00:00
Chris
9a08fe9b5c Merge branch 'master' into pcb_microswitch2 2020-02-23 15:10:13 +00:00
Chris Palmer
8ab7993148 Merge branch 'martinbudden-rocker_color' 2020-02-23 15:03:23 +00:00
Chris Palmer
16dd8d6d17 Added images and readme. 2020-02-23 15:02:39 +00:00
Chris Palmer
08c268145e Merge branch 'rocker_color' of https://github.com/martinbudden/NopSCADlib into martinbudden-rocker_color 2020-02-23 14:52:11 +00:00
Chris Palmer
ba7e64233a Clarified path settings in usage.md. 2020-02-23 14:46:39 +00:00
Chris Palmer
7090c714ce Merge branch 'martinbudden-pcb_buzzer' 2020-02-23 14:34:04 +00:00
Martin Budden
c5038db6d9 Added support for tNuts in sk_brackets. 2020-02-23 14:32:40 +00:00
Chris Palmer
654f094304 Merge branch 'martinbudden-spool_filament' 2020-02-23 14:28:57 +00:00
Chris Palmer
1e5e5860e1 Made more realistic and added a test. 2020-02-23 14:28:39 +00:00
Martin Budden
a08216d0b8 Added SK shaft support brackets. 2020-02-23 13:57:14 +00:00
Chris Palmer
3d8a9ec8aa Merge branch 'spool_filament' of https://github.com/martinbudden/NopSCADlib into martinbudden-spool_filament 2020-02-23 10:04:23 +00:00
Chris Palmer
7ec059142f Updated readme. 2020-02-23 10:01:28 +00:00
Chris Palmer
7f0d96b824 Merge branch 'pcb_buzzer' of https://github.com/martinbudden/NopSCADlib into martinbudden-pcb_buzzer 2020-02-22 23:06:08 +00:00
Chris Palmer
9e826c1a09 Merge branch 'martinbudden-belt_colors' 2020-02-22 23:02:03 +00:00
Chris Palmer
2c1dbe04a9 Added images and readme. 2020-02-22 23:01:50 +00:00
Chris Palmer
d644d6b698 Merge branch 'belt_colors' of https://github.com/martinbudden/NopSCADlib into martinbudden-belt_colors 2020-02-22 22:47:42 +00:00
Chris Palmer
8db4cc2cb5 Merge branch 'martinbudden-pcb_jst_xh' 2020-02-22 22:40:31 +00:00
Chris Palmer
509a87939c Updated images and readme 2020-02-22 22:40:09 +00:00
Chris Palmer
40607e6cfc Merge branch 'pcb_jst_xh' of https://github.com/martinbudden/NopSCADlib into martinbudden-pcb_jst_xh 2020-02-22 22:28:16 +00:00
Chris Palmer
599fbba6c2 Reduced dependecies in pcb_mount test. 2020-02-22 22:24:45 +00:00
Chris Palmer
52729d012c Merge branch 'martinbudden-rail_carriage_coloring' 2020-02-22 22:16:50 +00:00
Chris Palmer
6097e07094 Updated images and readme. 2020-02-22 22:16:09 +00:00
Chris Palmer
9d71438a3c Merge branch 'rail_carriage_coloring' of https://github.com/martinbudden/NopSCADlib into martinbudden-rail_carriage_coloring 2020-02-22 21:59:15 +00:00
Chris Palmer
ffa1ab940b Merge branch 'martinbudden-tnuts' 2020-02-22 21:51:16 +00:00
Chris Palmer
3174013e1a Updated images and readme. 2020-02-22 21:51:05 +00:00
Chris Palmer
c4eea38a2b Added threads 2020-02-22 21:27:51 +00:00
Chris Palmer
0cd89279a5 Merge branch 'tnuts' of https://github.com/martinbudden/NopSCADlib into martinbudden-tnuts 2020-02-22 21:12:13 +00:00
Chris Palmer
92051e0b28 Merge branch 'martinbudden-gitattributes' 2020-02-22 21:05:26 +00:00
Chris Palmer
f4b22e35c7 Merge branch 'gitattributes' of https://github.com/martinbudden/NopSCADlib into martinbudden-gitattributes 2020-02-22 21:02:24 +00:00
Chris Palmer
17ecfc07f3 Merge branch 'martinbudden-screw_knob_typo' 2020-02-22 20:58:55 +00:00
Chris Palmer
9658205efd Updated readme 2020-02-22 20:58:43 +00:00
Chris Palmer
53140a4cc1 Merge branch 'screw_knob_typo' of https://github.com/martinbudden/NopSCADlib into martinbudden-screw_knob_typo 2020-02-22 20:55:17 +00:00
Chris Palmer
2798d39538 Merge branch 'martinbudden-iec_switched_fused' 2020-02-22 20:51:58 +00:00
Chris Palmer
8be0cc98ea Updated the images and readme. 2020-02-22 20:51:15 +00:00
Chris Palmer
6a5f31edd8 Merge branch 'iec_switched_fused' of https://github.com/martinbudden/NopSCADlib into martinbudden-iec_switched_fused 2020-02-22 20:01:25 +00:00
Chris Palmer
e068918e21 Added screw threads to most things that are threaded.
Added a mechanism for tests.py and views.py to have command line options.
2020-02-22 19:44:01 +00:00
Chris Palmer
1614f50b73 Merged master 2020-02-22 18:32:35 +00:00
Martin Budden
32522b28d7 Added hammer nuts. 2020-02-19 06:42:11 +00:00
Martin Budden
1936c95d06 Added IEC 320 C14 switched fused inlet module. 2020-02-18 08:24:16 +00:00
Martin Budden
16060629c0 Added sliding t nuts. Sizes M3, M4 and M5. 2020-02-18 07:48:01 +00:00
Martin Budden
b7b5c837bd Used tube for buzzer. 2020-02-17 19:40:49 +00:00
Martin Budden
a793cb6d43 Added ability to use microswitch on a pcb. 2020-02-17 06:58:09 +00:00
Martin Budden
dc4e24b63a Simplified drawing of filament. 2020-02-16 23:06:07 +00:00
Martin Budden
8f85ac73dc Added space before screw length when length < 10 to ensure correct ordering.
This means 5mm, 6mm etc comes before 10mm in BOM.
2020-02-16 21:15:44 +00:00
Martin Budden
3ab934d83e Typo in screw_knob. foe corrected to for. 2020-02-07 19:58:37 +00:00
Martin Budden
d1324a670e Added JST-XH connector for pcbs. 2020-01-30 05:45:29 +00:00
Martin Budden
f5fdec613c Allow setting of color of rocker switch. Defaults to current colors. 2020-01-29 17:46:32 +00:00
Martin Budden
c55b8b6d1c Parameterised belt colors. 2020-01-29 17:40:34 +00:00
Martin Budden
56ec8e03ad Added PCB buzzer. 2020-01-29 17:37:01 +00:00
Martin Budden
728b7adf38 Add ability to display filament on spool. 2020-01-14 11:26:21 +00:00
Martin Budden
75747687d9 Parameterised coloring of linear rail carriage. 2020-01-12 10:20:10 +00:00
Martin Budden
03c97e8b6a Changed rail carriage coloring to be green with red endpiece to match common form. 2020-01-11 14:54:00 +00:00
Chris Palmer
8ac06b53e7 Updated readme and images for linear_bearings change. 2020-01-11 08:57:33 +00:00
Martin Budden
de76eb46e7 Initial commit. Set default text file line endings to LF. 2020-01-11 08:21:38 +00:00
Chris
2c77f184a2 Merge pull request #12 from martinbudden/linear_bearings
Added LM16UU and long form (LMxLUU) of linear bearings plus external grooves.
2020-01-11 08:10:49 +00:00
Martin Budden
4d3d9dfdfe Added LM16UU and long form (LMxLUU) of linear bearings.
Added external grooves.
2020-01-10 22:11:53 +00:00
Chris Palmer
f7a972f946 Added pictures and documentation for extrusions. 2020-01-10 20:10:17 +00:00
Chris
4e81fcbd4f Merge pull request #10 from martinbudden/extrusions
Initial submission of E2020 aluminium extrusion.
2020-01-10 19:32:49 +00:00
Martin Budden
1f038decd4 Initial submission of aluminium extrusion. Supports 2020, 2040, 2060, 2080, 3030, 3060, 4040, 4080 types.
Added extrusions to main picture.
2020-01-10 19:24:24 +00:00
Chris
da958fe112 Merge pull request #11 from martinbudden/e3d_naked
E3d Resistor wire drawn even if naked=true.
2020-01-10 13:26:43 +00:00
Martin Budden
61493eaa34 Resistor wire drawn even if naked=true. 2020-01-10 12:26:56 +00:00
Chris
804c00bdcb Merge pull request #8 from martinbudden/rocker_typo
Fixed typo where 'rocker' was spelt 'rocket'.
2020-01-10 10:28:21 +00:00
Chris
11ea68681f Merge pull request #9 from martinbudden/e3d_tab_formatting
Tabs used instead of spaces in module e3d_resistor.
2020-01-10 10:27:40 +00:00
Chris Palmer
d703ae4997 Added male screw threads. 2020-01-10 10:26:12 +00:00
Martin Budden
ed97d226f8 Tabs used instead of spaces in module e3d_resistor. 2020-01-10 08:49:03 +00:00
Martin Budden
4107a2c848 Fixed typo where 'rocker' was spelt 'rocket'. 2020-01-10 08:26:20 +00:00
Chris Palmer
f7ef075434 Fixed hex pillar thread length.
Reordered screws.
Random pixel changes.
2019-12-30 12:45:51 +00:00
Chris Palmer
6f93b6af9a pcb_component_position() can now be passed an index to differentiate between
multiple components of the same type.

Added pcb_grid_pos() function.
2019-11-15 13:30:27 +00:00
Chris Palmer
53f416eef1 Added more detail to the Environ+ pcb.
Changed the RPI0 SD height to be more accurate.
2019-11-15 13:28:02 +00:00
Chris Palmer
6354219627 Added tiny 17x8mm fan. 2019-11-15 13:25:32 +00:00
Chris Palmer
56e2b71bda Updated readme for last PR 2019-10-22 18:01:51 +01:00
Chris
8f5503586d Merge pull request #6 from limitz/e3d_resistor_wire_rotate
E3d resistor wire rotate
2019-10-22 17:57:14 +01:00
Chris
1cd9edfe87 Merge pull request #5 from limitz/blower_typo
Small typo fix for blower RB5015 in source (string) and documentation
2019-10-22 17:54:17 +01:00
Chris Palmer
a85fdaf176 Added printed pcb_mount to hold PCBs without mounting holes. 2019-10-22 17:47:46 +01:00
Chris Palmer
18294b4b81 Added Enviro+ PCB 2019-10-22 16:32:26 +01:00
Chris Palmer
ad62ce362c Can now force fan screws to be the full depth and nuts then get washers. 2019-10-22 16:21:58 +01:00
Chris Palmer
9f27f26894 Added pcb_component_position() function. 2019-10-22 16:17:22 +01:00
Chris Palmer
2eaa4bfc21 Readme changes for last commit. 2019-10-22 16:16:12 +01:00
Chris Palmer
1944039f22 Added crimp version of ring terminal. 2019-10-22 16:12:58 +01:00
Chris Palmer
1c221ad612 Added S-7282B LCD display 2019-10-22 16:12:00 +01:00
Chris Palmer
85adf7b4f4 Readme changes for last commit. 2019-10-22 16:09:46 +01:00
Chris Palmer
64bde2cb3a Added right angle pin headers. 2019-10-22 16:08:15 +01:00
Chris Palmer
c34469e852 Added more sizes of cable grommets. 2019-10-22 15:37:10 +01:00
Chris Palmer
dbc3c36f44 Can now override the front panel width of a butt_box to make it wider. 2019-10-22 15:36:37 +01:00
Chris Palmer
8c51183ba6 Added volume and area functions to butt_box. 2019-10-22 15:34:08 +01:00
Chris Palmer
a9c4e60cac Added another spool size 2019-10-22 15:27:49 +01:00
Eddy Pronk
d041b18025 Adds an option resistor_wire_rotate 2019-10-21 17:51:19 +02:00
Eddy Pronk
e85887fec4 Small typo fix for blower RB5015 in source (string) and documentation 2019-10-21 17:17:11 +02:00
Chris Palmer
ededb514b8 Fixed some missing commas in pin_header vitamin calls. 2019-09-15 18:28:42 +01:00
Chris Palmer
d0d525b97a Added RPi 0 model 2019-09-14 23:26:26 +01:00
Chris Palmer
371d274906 Fixed missing include for hygrometer. 2019-09-14 23:09:21 +01:00
Chris Palmer
7118e6eb03 Typo in comment. 2019-09-06 11:28:49 +01:00
Chris Palmer
46004381b7 Merge branch 'master' into Execute_attributes 2019-08-21 22:04:27 +01:00
Chris Palmer
cfdf759a49 Added missing files from last push. 2019-08-21 18:51:45 +01:00
Chris Palmer
aeded1b807 Added a hygrometer module. 2019-08-21 18:50:15 +01:00
Chris Palmer
79f1c95136 Insert lug made more flexible and insert_boss made faster.
Both added to the insert test.
2019-08-21 17:31:23 +01:00
Chris Palmer
9bb84593be Added two more projects to the gallery. 2019-08-21 16:50:00 +01:00
Chris Palmer
ab91defcd2 Added Arduino Leonardo 2019-08-21 16:28:32 +01:00
Chris Palmer
7c1ff5ecd5 Added comment to belts about using negative pitch radius for outside pulleys. 2019-08-21 11:36:48 +01:00
Chris Palmer
6f4859a4b5 Merge branch 'master' into Execute_attributes 2019-08-18 18:42:42 +01:00
Chris Palmer
e35fb695a2 Ziptie width added to BOM description. 2019-08-18 18:39:56 +01:00
Chris Palmer
61bec656d7 Fixed box header BOM descripion. 2019-08-18 18:32:22 +01:00
Chris Palmer
3a087be0e9 Merge branch 'master' into Execute_attributes 2019-08-18 15:22:47 +01:00
Chris Palmer
854adab665 Fix for Python 2 2019-08-18 15:21:01 +01:00
Chris Palmer
77aa8fe44d Merge branch 'master' into Execute_attributes 2019-08-18 14:30:28 +01:00
Chris Palmer
6fe4548213 Set execute attributes on scripts for Linux. 2019-08-18 14:29:15 +01:00
Chris Palmer
b7654f0384 Fixed readme index order for Python 2.
Fixed index order being different on Linux due to os.listdir order being
inconsistent with Windows.
2019-08-18 14:26:14 +01:00
Chris Palmer
312f12dfd0 Butt_box made more flexible with extra parameters. 2019-08-18 14:18:21 +01:00
Chris Palmer
be3999ed3e Added documentation for the last change. 2019-08-18 12:52:17 +01:00
Chris Palmer
566cbce98f Corrner block and fixing block assemblies now more flexible.
Can split the fasteners between assemblies and omit the star washers.
2019-08-18 12:36:13 +01:00
Chris Palmer
b8dba626d2 Can now flip the fasteners in a foot_assembly. 2019-08-18 12:32:29 +01:00
Chris Palmer
2adb936f41 Fixed toggle switch part number typo. 2019-08-18 12:27:41 +01:00
Chris Palmer
017ec480c0 Added tesrdrop option to mouse_hole. 2019-08-18 12:26:25 +01:00
Chris Palmer
e3a500e9c6 Added pcb_component_position(). 2019-08-18 12:19:48 +01:00
Chris Palmer
4ac48c9603 Added studding. 2019-08-18 12:18:12 +01:00
Chris Palmer
78ce316b86 Added 2mm acrylic sheets. 2019-08-18 12:04:58 +01:00
Chris Palmer
ec274fdca1 Update readme for last change. 2019-08-18 11:56:05 +01:00
Chris Palmer
3640963da1 Added small geared stepper and driver board. 2019-08-18 11:46:33 +01:00
Chris Palmer
466a7a667d Added platters.py and panels.py to aggregate parts for printing / routing. 2019-08-18 11:08:44 +01:00
Chris Palmer
be324c31da Missing targets now named when dependency checking. 2019-08-18 10:53:22 +01:00
Chris Palmer
49c3b6be2c Fixed Microview stl suffix case for Linux. 2019-08-17 14:39:45 +01:00
Chris Palmer
8583f5472d Would help to include the code! 2019-07-29 20:43:03 +01:00
Chris Palmer
645ff21d3d Added right_triangle. 2019-07-29 19:30:07 +01:00
Chris Palmer
4ff12b1d8b LDRs thicker 2019-07-29 16:39:09 +01:00
Chris Palmer
847dba544f Fixed fillet back to front 2019-07-28 22:08:21 +01:00
Chris Palmer
13c654a10e Fixed nut child placement when it is a nyloc 2019-07-27 21:50:04 +01:00
Chris Palmer
49ee92db8e Fixed tapered PCB spacers. 2019-07-25 21:20:41 +01:00
Chris Palmer
be14a52c21 Fixed LDR comment 2019-07-25 19:31:16 +01:00
Chris Palmer
af4c5e2b3e Added missing image 2019-07-25 11:05:58 +01:00
Chris Palmer
f85a7e85be Added LDR models 2019-07-25 11:00:04 +01:00
Chris Palmer
c68f879d13 Added insert_lug() to make flying insert lugs. 2019-07-25 10:39:31 +01:00
Chris Palmer
3d4653fc0f Added insert_boss_radius(). 2019-07-24 13:48:44 +01:00
Chris Palmer
b40c076d23 Removed extraneous echo. 2019-07-21 19:10:15 +01:00
Chris Palmer
5ae040079e Now shows the CNC routed parts in the master BOM and total parts count. 2019-07-21 18:58:38 +01:00
Chris Palmer
881a032aa3 Typo 2019-07-21 17:39:42 +01:00
Chris Palmer
4b1d6298e4 Typo 2019-07-21 17:39:23 +01:00
Chris Palmer
b4cc6f6c37 Added semi_teardrop.
mouse_grommets now teardropped.
2019-07-19 11:10:44 +01:00
Chris Palmer
6238f82bf0 Added poly_tube(), an extruded poly_ring().
Added missing hinge image.
2019-07-19 11:03:26 +01:00
Chris Palmer
fbc688c81f Vitamins now sorted alphabetically in build instructions. 2019-07-19 10:57:14 +01:00
Chris Palmer
7b2b239a8b Can now override the screw type for a fan assembly. 2019-07-19 10:51:59 +01:00
Chris Palmer
de8eb594a7 Reduced the number of waves on a screw_knob to make it more comfortable.
Added build instructions to the screw_knob assemblies.
2019-07-19 10:50:08 +01:00
Chris Palmer
f061b0a2f8 Added alternative ring_terminal earth assembly with cap screw. 2019-07-19 10:46:38 +01:00
Chris Palmer
43b17c6f0b Added spool_pitch() function and more modern 300mm filament spool. 2019-07-19 10:39:05 +01:00
Chris Palmer
886319a6e4 Added pose_vflip() and pose_hflip() to make posing assembly views easier. 2019-07-19 10:37:10 +01:00
Chris Palmer
723be7ac64 Fixed round_grommet_hole() size.
Added more grommet stls.
2019-07-19 10:34:38 +01:00
Chris Palmer
3a5e027bbb Added parametric printed hinges. 2019-07-19 10:30:02 +01:00
Chris Palmer
d068b972ff Fixed bug in butt_box.scad when box was tall enough for extra fixing blocks. 2019-07-06 16:26:56 +01:00
Chris Palmer
0fb0432b39 Added 4.3" LCD display 2019-07-06 14:05:27 +01:00
Chris Palmer
107951aad0 Typo 2019-07-04 14:48:09 +01:00
Chris Palmer
55fd552c8f Added Duet Ethernet and Duex PCB models.
Made green terminals parametric.
Separated pin_headers and green_terminals out from pcb.scad.
2019-07-04 12:03:38 +01:00
Chris Palmer
8014aadd1d Can now change the box shelf material. 2019-07-01 15:05:06 +01:00
Chris Palmer
a3e51d2607 Added PSU shrouds. 2019-06-27 13:20:50 +01:00
Chris Palmer
8ea7d92997 Rounded up wire_hole_radius to nearest half mm. 2019-06-27 11:37:55 +01:00
Chris Palmer
e386ce7927 Added more imperial and metric units as requested. 2019-06-27 11:10:37 +01:00
Chris
fbc0b1d27d Merge pull request #2 from twoxe/patch-1
Change LED.scad to led.scad
2019-06-27 10:12:27 +01:00
Chris Palmer
5f287ef8ad Fixed ssr shroud mounting height. 2019-06-27 10:06:13 +01:00
Chris Palmer
0ccda3378e Better ziptie model.
Better cable_tie using zipties.
Added cable ties to ssr_shroud_fastened_assembly().
Added test and documentation for wire.scad.
2019-06-25 17:41:59 +01:00
twoxe
c155e95599 Change LED.scad to led.scad
The file LED.scad is not found if a case sensitive file system is used
2019-06-25 10:35:41 +02:00
423 changed files with 12163 additions and 2548 deletions

16
.gitattributes vendored Normal file
View File

@@ -0,0 +1,16 @@
# Set the default behavior, in case people don't have core.autocrlf set.
* text=auto eol=lf
# Declare text files that are normalized and converted on checkout.
*.scad text
*.py text
*.md text
# Handle Windows batch and command files
*.{bat,[bB][aA][tT]} text eol=crlf
*.{cmd,[cC][mM][dD]} text eol=crlf
# Denote files that are binary and should not be modified.
*.png binary
*.jpg binary

1
.gitignore vendored
View File

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

View File

@@ -18,10 +18,10 @@
//
//
// Include this file to use the miniumum library
// Include this file to use the miniumum library plus screws, nuts and washers
//
include <global_defs.scad>
include <utils/core/core.scad>
//
// Global functions and modules
// Fasteners used by a lot of other vitamins
//
use <utils/core/global.scad>
include <vitamins/screws.scad>

BIN
docs/metric_threads.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

@@ -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.
@@ -116,8 +116,8 @@ get shared if other files in the project include ```lib.scad``` as well, or if y
One downside is that any change to the library will mean all the project files need regenerating.
A more optimised approach for large projects is to include [NopSCADlib/core.scad](../core.scad) instead.
That only has the a small set of utilities and the global settings in [global_defs.scad](../global_defs.scad). Any vitamins used need to be included explicitly.
One can copy the include or use line from [NopSCADlib/lib.scad](../lib.scad).
That only has the a small set of utilities and the global settings in [global_defs.scad](../global_defs.scad) plus screws, nuts and washers that are required by a lot of other vitamins.
Any other vitamins used need to be included explicitly. One can copy the includes or use a line from [NopSCADlib/lib.scad](../lib.scad).
### Parametric parts.
@@ -164,7 +164,7 @@ This is achieved by having a pair of modules: -
module handle_assembly() pose([225, 0, 150], [0, 0, 14]) //! Printed part with inserts in place
assembly("handle") {
translate_z(handle_height())
color(pp1_colour) vflip() handle_stl();
stl_colour(pp1_colour) vflip() handle_stl();
handle_screw_positions()
vflip()
@@ -233,3 +233,33 @@ Vitamins are only ever previewed, so they are optimised to draw quickly in F5 an
In OpenCSG 3D difference and intersection are relatively slow and the negative volumes interfere with nearby objects when they are composed into assemblies. For this reason as much
as possible is done by unioning primitives and extruded 2D shapes. Any 3D differences or intersections are wrapped in ```render()``` so that CGAL will compute a polyhedron
that is cached and reused. This will be very slow the first time it renders but very fast afterwards.
### Panels and Platters
The ```stls``` and ```dxfs``` scripts produce a file for each part but often it is desirable to print or route collections of parts laid out together.
This can be done by adding scad files to folders called ```platters``` for STL files and ```panels``` for DXF files.
These can aggregate and lay out parts by including ```NopSCADlib/core.scad``` and using modules ```use_stl(name)``` and ```use_dxf(name)```.
These modules import the already generated singular STL and DXF files, so they are relatively fast. The name does not include the suffix.
The scad files typically also need to include other files from the project to get the dimensions of the parts to calculate their positions.
The composite part files have the same name as the scad file that generates them, with the suffix changed to ```.stl``` or ```.dxf```.
The generated files are placed in ```stls/printed``` and ```dxfs/routed```.
Any parts that are not covered by the platters / panels are copied into the ```printed``` / ```routed``` directories, so that they contain everything to be made.
### Multiple configurations
Some parametric designs might have several configurations, for example a 3D printer with different size options. If several configurations need to be supported at the
same time multiple sets of BOMS, STLS and DXFs need to be generated in separate diectories. NopSCADlib supports this by having multiple configuration files named
```config_<target_name>.scad```. All the scripts take an optional first parameter that selects one of these config files by specifying ```target_name```.
The target config file is selected by generating ```target.scad``` that includes ```config_<target_name>.scad```.
The rest of the project includes ```target.scad``` to use the configuration.
Additionally all the generated file directories (assemblies, bom, stls, dxfs, etc.) are placed in a sub-directory called ```<target_name>```.
### Other libraries
The build scripts need to be able to locate the source files where the modules to generate the STL files and assemblies reside. They will search all the scad files
in the project plus any ```printed``` directories outside the project. This covers the printed parts in NopSCADlib but also allows other libraries of printed parts.
Other libraries of vitamins and utilities can be used provided they follow the same convensions of NopSCADlib. The build scripts don't need to search those.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 96 KiB

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 107 KiB

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 104 KiB

After

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 130 KiB

After

Width:  |  Height:  |  Size: 137 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 179 KiB

After

Width:  |  Height:  |  Size: 200 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 121 KiB

After

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 130 KiB

After

Width:  |  Height:  |  Size: 134 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

View File

@@ -1,67 +1,119 @@
[
{
"name": "base_assembly",
"big": null,
"count": 1,
"assemblies": {},
"vitamins": {
"insert(F1BM3): Heatfit insert M3": 2
"insert(F1BM3): Heatfit insert M3": {
"count": 2
}
},
"printed": {
"socket_box.stl": 1
"socket_box.stl": {
"count": 1,
"colour": "dimgrey"
}
},
"routed": {}
},
{
"name": "feet_assembly",
"big": null,
"count": 1,
"assemblies": {
"base_assembly": 1
},
"vitamins": {
"washer(M3_washer): Washer M3 x 7mm x 0.5mm": 8,
"screw(M3_dome_screw, 10): Screw M3 dome x 10mm": 4,
"nut(M3_nut, nyloc = true): Nut M3 x 2.4mm nyloc": 4
"washer(M3_washer): Washer M3 x 7mm x 0.5mm": {
"count": 8
},
"screw(M3_dome_screw, 10): Screw M3 dome x 10mm": {
"count": 4
},
"nut(M3_nut, nyloc = true): Nut M3 x 2.4mm nyloc": {
"count": 4
}
},
"printed": {
"foot.stl": 4
"foot.stl": {
"count": 4,
"colour": "darkorange"
}
},
"routed": {}
},
{
"name": "mains_in_assembly",
"big": null,
"count": 1,
"assemblies": {
"feet_assembly": 1
},
"vitamins": {
": Wire green & yellow 30/0.25mm strands, length 150mm - not shown": 1,
": Wire blue 30/0.25mm strands, length 150mm - not shown": 1,
": Wire brown 30/0.25mm strands, length 150mm - not shown": 2,
"tubing(HSHRNK32): Heatshrink sleeving ID 3.2mm x 15mm - not shown": 3,
"iec(IEC_inlet_atx): IEC inlet for ATX": 1,
"screw(M3_cs_cap_screw, 12): Screw M3 cs cap x 12mm": 2,
"washer(M3_washer): Washer M3 x 7mm x 0.5mm": 2,
"nut(M3_nut, nyloc = true): Nut M3 x 2.4mm nyloc": 2
": Wire green & yellow 30/0.25mm strands, length 150mm - not shown": {
"count": 1
},
": Wire blue 30/0.25mm strands, length 150mm - not shown": {
"count": 1
},
": Wire brown 30/0.25mm strands, length 150mm - not shown": {
"count": 2
},
"tubing(HSHRNK32): Heatshrink sleeving ID 3.2mm x 15mm - not shown": {
"count": 3
},
"iec(IEC_inlet_atx): IEC inlet for ATX": {
"count": 1
},
"screw(M3_cs_cap_screw, 12): Screw M3 cs cap x 12mm": {
"count": 2
},
"washer(M3_washer): Washer M3 x 7mm x 0.5mm": {
"count": 2
},
"nut(M3_nut, nyloc = true): Nut M3 x 2.4mm nyloc": {
"count": 2
}
},
"printed": {},
"routed": {}
},
{
"name": "main_assembly",
"big": null,
"count": 1,
"assemblies": {
"mains_in_assembly": 1
},
"vitamins": {
": Wire green & yellow 30/0.25mm strands, length 150mm - not shown": 1,
": Wire blue 30/0.25mm strands, length 150mm - not shown": 1,
"tubing(HSHRNK32): Heatshrink sleeving ID 3.2mm x 15mm - not shown": 5,
": Ferrule for 1.5mm^2 wire - not shown": 3,
"mains_socket(Contactum): Mains socket 13A": 1,
"screw(M3_cs_cap_screw, 20): Screw M3 cs cap x 20mm": 2,
"jack_4mm_shielded(\"blue\", 3, \"royalblue\"): 4mm shielded jack socket blue": 2,
"jack_4mm_shielded(\"brown\", 3, \"sienna\"): 4mm shielded jack socket brown": 1,
"jack_4mm_shielded(\"green\", 3): 4mm shielded jack socket green": 2
": Wire green & yellow 30/0.25mm strands, length 150mm - not shown": {
"count": 1
},
": Wire blue 30/0.25mm strands, length 150mm - not shown": {
"count": 1
},
"tubing(HSHRNK32): Heatshrink sleeving ID 3.2mm x 15mm - not shown": {
"count": 5
},
": Ferrule for 1.5mm^2 wire - not shown": {
"count": 3
},
"mains_socket(Contactum): Mains socket 13A": {
"count": 1
},
"screw(M3_cs_cap_screw, 20): Screw M3 cs cap x 20mm": {
"count": 2
},
"jack_4mm_shielded(\"blue\", 3, \"royalblue\"): 4mm shielded jack socket blue": {
"count": 2
},
"jack_4mm_shielded(\"brown\", 3, \"sienna\"): 4mm shielded jack socket brown": {
"count": 1
},
"jack_4mm_shielded(\"green\", 3): 4mm shielded jack socket green": {
"count": 2
}
},
"printed": {},
"routed": {}

View File

@@ -30,7 +30,8 @@ Earth leakage can be measured Canadian CSA style by disconnected the neutral lin
<a name="Parts_list"></a>
## Parts list
| <span style="writing-mode: vertical-rl; text-orientation: mixed;">Base</span> | <span style="writing-mode: vertical-rl; text-orientation: mixed;">Feet</span> | <span style="writing-mode: vertical-rl; text-orientation: mixed;">Mains&nbsp;In</span> | <span style="writing-mode: vertical-rl; text-orientation: mixed;">Main</span> | <span style="writing-mode: vertical-rl; text-orientation: mixed;">TOTALS</span> | |
|--:|--:|--:|--:|--:|:--|
|---:|---:|---:|---:|---:|:---|
| | | | | | **Vitamins** |
| &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;2&nbsp; | &nbsp;&nbsp;2&nbsp; | &nbsp;&nbsp; 4mm shielded jack socket blue |
| &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;1&nbsp; | &nbsp;&nbsp;1&nbsp; | &nbsp;&nbsp; 4mm shielded jack socket brown |
| &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;2&nbsp; | &nbsp;&nbsp;2&nbsp; | &nbsp;&nbsp; 4mm shielded jack socket green |
@@ -47,9 +48,11 @@ Earth leakage can be measured Canadian CSA style by disconnected the neutral lin
| &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;1&nbsp; | &nbsp;&nbsp;1&nbsp; | &nbsp;&nbsp;2&nbsp; | &nbsp;&nbsp; Wire blue 30/0.25mm strands, length 150mm - not shown |
| &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;2&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;2&nbsp; | &nbsp;&nbsp; Wire brown 30/0.25mm strands, length 150mm - not shown |
| &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;1&nbsp; | &nbsp;&nbsp;1&nbsp; | &nbsp;&nbsp;2&nbsp; | &nbsp;&nbsp; Wire green & yellow 30/0.25mm strands, length 150mm - not shown |
| | | | | | **3D Printed parts** |
| &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;4&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;4&nbsp; | &nbsp;&nbsp;&nbsp;foot.stl |
| &nbsp;&nbsp;1&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;1&nbsp; | &nbsp;&nbsp;&nbsp;socket_box.stl |
| &nbsp;&nbsp;2&nbsp; | &nbsp;&nbsp;16&nbsp; | &nbsp;&nbsp;14&nbsp; | &nbsp;&nbsp;18&nbsp; | &nbsp;&nbsp;50&nbsp; | &nbsp;&nbsp;Total vitamins count |
| | | | | | **3D printed parts** |
| &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;4&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;4&nbsp; | &nbsp;&nbsp;foot.stl |
| &nbsp;&nbsp;1&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;1&nbsp; | &nbsp;&nbsp;socket_box.stl |
| &nbsp;&nbsp;1&nbsp; | &nbsp;&nbsp;4&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;.&nbsp; | &nbsp;&nbsp;5&nbsp; | &nbsp;&nbsp;Total 3D printed parts count |
[Top](#TOP)
@@ -58,14 +61,14 @@ Earth leakage can be measured Canadian CSA style by disconnected the neutral lin
## Base Assembly
### Vitamins
|Qty|Description|
|--:|:----------|
|---:|:----------|
|2| Heatfit insert M3|
### 3D Printed parts
| 1 x socket_box.stl |
|--|
|---|
| ![socket_box.stl](stls/socket_box.png)
@@ -85,16 +88,16 @@ Earth leakage can be measured Canadian CSA style by disconnected the neutral lin
## Feet Assembly
### Vitamins
|Qty|Description|
|--:|:----------|
|8| Washer M3 x 7mm x 0.5mm|
|4| Screw M3 dome x 10mm|
|---:|:----------|
|4| Nut M3 x 2.4mm nyloc|
|4| Screw M3 dome x 10mm|
|8| Washer M3 x 7mm x 0.5mm|
### 3D Printed parts
| 4 x foot.stl |
|--|
|---|
| ![foot.stl](stls/foot.png)
@@ -102,7 +105,7 @@ Earth leakage can be measured Canadian CSA style by disconnected the neutral lin
### Sub-assemblies
| 1 x base_assembly |
|--|
|---|
| ![base_assembled](assemblies/base_assembled_tn.png)
@@ -121,21 +124,21 @@ Earth leakage can be measured Canadian CSA style by disconnected the neutral lin
## Mains In Assembly
### Vitamins
|Qty|Description|
|--:|:----------|
|1| Wire green & yellow 30/0.25mm strands, length 150mm - not shown|
|1| Wire blue 30/0.25mm strands, length 150mm - not shown|
|2| Wire brown 30/0.25mm strands, length 150mm - not shown|
|---:|:----------|
|3| Heatshrink sleeving ID 3.2mm x 15mm - not shown|
|1| IEC inlet for ATX|
|2| Nut M3 x 2.4mm nyloc|
|2| Screw M3 cs cap x 12mm|
|2| Washer M3 x 7mm x 0.5mm|
|2| Nut M3 x 2.4mm nyloc|
|1| Wire blue 30/0.25mm strands, length 150mm - not shown|
|2| Wire brown 30/0.25mm strands, length 150mm - not shown|
|1| Wire green & yellow 30/0.25mm strands, length 150mm - not shown|
### Sub-assemblies
| 1 x feet_assembly |
|--|
|---|
| ![feet_assembled](assemblies/feet_assembled_tn.png)
@@ -160,22 +163,22 @@ Earth leakage can be measured Canadian CSA style by disconnected the neutral lin
## Main Assembly
### Vitamins
|Qty|Description|
|--:|:----------|
|1| Wire green & yellow 30/0.25mm strands, length 150mm - not shown|
|1| Wire blue 30/0.25mm strands, length 150mm - not shown|
|5| Heatshrink sleeving ID 3.2mm x 15mm - not shown|
|3| Ferrule for 1.5mm^2 wire - not shown|
|1| Mains socket 13A|
|2| Screw M3 cs cap x 20mm|
|---:|:----------|
|2| 4mm shielded jack socket blue|
|1| 4mm shielded jack socket brown|
|2| 4mm shielded jack socket green|
|3| Ferrule for 1.5mm^2 wire - not shown|
|5| Heatshrink sleeving ID 3.2mm x 15mm - not shown|
|1| Mains socket 13A|
|2| Screw M3 cs cap x 20mm|
|1| Wire blue 30/0.25mm strands, length 150mm - not shown|
|1| Wire green & yellow 30/0.25mm strands, length 150mm - not shown|
### Sub-assemblies
| 1 x mains_in_assembly |
|--|
|---|
| ![mains_in_assembled](assemblies/mains_in_assembled_tn.png)

View File

@@ -35,7 +35,14 @@ $extrusion_width = 0.5;
$pp1_colour = "dimgrey";
$pp2_colour = [0.9, 0.9, 0.9];
include <NopSCADlib/lib.scad>
include <NopSCADlib/core.scad>
include <NopSCADlib/vitamins/iecs.scad>
include <NopSCADlib/vitamins/mains_sockets.scad>
include <NopSCADlib/vitamins/tubings.scad>
use <NopSCADlib/vitamins/insert.scad>
use <NopSCADlib/vitamins/wire.scad>
use <NopSCADlib/vitamins/jack.scad>
use <NopSCADlib/printed/foot.scad>
echo(extrusion_width = extrusion_width, layer_height = layer_height);
@@ -45,7 +52,7 @@ iec = IEC_inlet_atx;
socket = Contactum;
foot = [20, 8, 3, 1, M3_dome_screw, 10];
foot = Foot(d = 20, h = 8, t = 3, r = 1, screw = M3_dome_screw);
module foot_stl() foot(foot);
@@ -166,7 +173,7 @@ module socket_box_stl() {
//
module base_assembly()
assembly("base") {
color(pp1_colour) render() /*clip(ymax = 0)*/ socket_box_stl();
stl_colour(pp1_colour) render() /*clip(ymax = 0)*/ socket_box_stl();
mains_socket_hole_positions(socket)
translate_z(height)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 108 KiB

After

Width:  |  Height:  |  Size: 107 KiB

BIN
gallery/EnviroPlus.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

BIN
gallery/FilamentDryBox.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 166 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 169 KiB

After

Width:  |  Height:  |  Size: 168 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 280 KiB

After

Width:  |  Height:  |  Size: 290 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 291 KiB

After

Width:  |  Height:  |  Size: 293 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 286 KiB

After

Width:  |  Height:  |  Size: 286 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 230 KiB

After

Width:  |  Height:  |  Size: 236 KiB

BIN
gallery/SunBot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 178 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 207 KiB

After

Width:  |  Height:  |  Size: 215 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 198 KiB

After

Width:  |  Height:  |  Size: 202 KiB

View File

@@ -6,6 +6,20 @@ Arduino thermostat to control a beer fridge to use it as an environmental chambe
![](ArduinoThermostat.png)
<a name="TOP"></a>
## EnviroPlus
Environmental monitor using Enviro+ sensor board and a Raspberry Pi Zero.
![](EnviroPlus.png)
<a name="TOP"></a>
## FilamentDryBox
A small fan oven with a spool holder to keep the filament warm and dry.
![](FilamentDryBox.png)
<a name="TOP"></a>
## HydraBot
Current state of HydraRaptor after being modified for laser engraving.
@@ -68,6 +82,13 @@ Mains isolated and variable supply with metering.
![](Mains_Box.png)
<a name="TOP"></a>
## SunBot
A solar tracker to keep a solar panel pointing at the sun.
![](SunBot.png)
<a name="TOP"></a>
## Turntable
WiFi enabled remote control turntable for photography

View File

@@ -34,11 +34,12 @@ layer_height = is_undef($layer_height) ? 0.25 : $layer_height; // lay
extrusion_width = is_undef($extrusion_width) ? 0.5 : $extrusion_width; // filament width when printing
nozzle = is_undef($nozzle) ? 0.45 : $nozzle; // 3D printer nozzle
cnc_bit_r = is_undef($cnc_bit_r) ? 1.2 : $cnc_bit_r; // miniumum tool radius when milling 2D objects
pp1_colour = is_undef($pp1_colour) ? "lime" : $pp1_colour; // printed part colour 1
pp1_colour = is_undef($pp1_colour) ? [0, 146/255, 0] : $pp1_colour; // printed part colour 1, RepRap logo colour
pp2_colour = is_undef($pp2_colour) ? "red" : $pp2_colour; // printed part colour 2
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)
@@ -50,16 +51,11 @@ $fa = 6;
$fs = extrusion_width / 2;
function round_to_layer(z) = ceil(z / layer_height) * layer_height;
// Some additional named colors
grey20 = [0.2, 0.2, 0.2];
grey30 = [0.3, 0.3, 0.3];
grey40 = [0.4, 0.4, 0.4];
grey50 = [0.5, 0.5, 0.5];
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";
// Some additional named colours
function grey(n) = [0.01, 0.01, 0.01] * n; //! Generate a shade of grey to pass to color().
gold = [255/255, 215/255, 0/255];
brass = [255/255, 220/255, 100/255];
silver = [0.75, 0.75, 0.75];
/*
* Enums

View File

@@ -22,48 +22,53 @@
//
include <core.scad>
include <vitamins/fans.scad>
include <vitamins/psus.scad>
include <vitamins/pcbs.scad>
include <vitamins/batteries.scad>
include <vitamins/blowers.scad>
include <vitamins/bulldogs.scad>
include <vitamins/buttons.scad>
include <vitamins/cameras.scad>
include <vitamins/components.scad>
include <vitamins/displays.scad>
include <vitamins/extrusions.scad>
include <vitamins/extrusion_brackets.scad>
include <vitamins/geared_steppers.scad>
include <vitamins/green_terminals.scad>
include <vitamins/hot_ends.scad>
include <vitamins/inserts.scad>
include <vitamins/kp_pillow_blocks.scad>
include <vitamins/ldrs.scad>
include <vitamins/leadnuts.scad>
include <vitamins/led_meter.scad>
include <vitamins/light_strips.scad>
include <vitamins/magnets.scad>
include <vitamins/mains_sockets.scad>
include <vitamins/modules.scad>
include <vitamins/panel_meters.scad>
include <vitamins/pillars.scad>
include <vitamins/pin_headers.scad>
include <vitamins/pulleys.scad>
include <vitamins/ring_terminals.scad>
include <vitamins/rails.scad>
include <vitamins/belts.scad>
include <vitamins/pulleys.scad>
include <vitamins/sheets.scad>
include <vitamins/stepper_motors.scad>
include <vitamins/components.scad>
include <vitamins/hot_ends.scad>
include <vitamins/tubings.scad>
include <vitamins/zipties.scad>
include <vitamins/linear_bearings.scad>
include <vitamins/rod.scad>
include <vitamins/leadnuts.scad>
include <vitamins/bulldogs.scad>
include <vitamins/pillars.scad>
include <vitamins/psus.scad>
include <vitamins/iecs.scad>
include <vitamins/rockers.scad>
include <vitamins/scs_bearing_blocks.scad>
include <vitamins/sheets.scad>
include <vitamins/sk_brackets.scad>
include <vitamins/spools.scad>
include <vitamins/ssrs.scad>
include <vitamins/d_connectors.scad>
include <vitamins/buttons.scad>
include <vitamins/pcbs.scad>
include <vitamins/modules.scad>
include <vitamins/displays.scad>
include <vitamins/blowers.scad>
include <vitamins/leds.scad>
include <vitamins/stepper_motors.scad>
include <vitamins/swiss_clips.scad>
include <vitamins/toggles.scad>
include <vitamins/transformers.scad>
include <vitamins/tubings.scad>
include <vitamins/variacs.scad>
include <vitamins/springs.scad>
include <vitamins/batteries.scad>
include <vitamins/microswitches.scad>
include <vitamins/ball_bearings.scad>
include <vitamins/light_strips.scad>
include <vitamins/spools.scad>
include <vitamins/mains_sockets.scad>
include <vitamins/zipties.scad>
use <vitamins/jack.scad>
use <vitamins/meter.scad>
use <vitamins/fuseholder.scad>
use <vitamins/hygrometer.scad>
use <vitamins/opengrab.scad>
use <vitamins/wire.scad>
@@ -80,6 +85,7 @@ use <utils/rounded_cylinder.scad>
use <utils/dogbones.scad>
use <utils/tube.scad>
use <utils/quadrant.scad>
use <utils/gears.scad>
use <utils/hanging_hole.scad>
use <utils/fillet.scad>
use <utils/rounded_polygon.scad>
@@ -87,3 +93,4 @@ use <utils/layout.scad>
use <utils/round.scad>
use <utils/offset.scad>
use <utils/sector.scad>
use <utils/thread.scad>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 660 KiB

After

Width:  |  Height:  |  Size: 817 KiB

View File

@@ -29,40 +29,52 @@ use <tests/blowers.scad>
use <tests/bulldogs.scad>
use <tests/buttons.scad>
use <tests/cable_strips.scad>
use <tests/cameras.scad>
use <tests/circlips.scad>
use <tests/components.scad>
use <tests/d_connectors.scad>
use <tests/displays.scad>
use <tests/extrusions.scad>
use <tests/extrusion_brackets.scad>
use <tests/fans.scad>
use <tests/fuseholder.scad>
use <tests/geared_steppers.scad>
use <tests/hot_ends.scad>
use <tests/iecs.scad>
use <tests/IECs.scad>
use <tests/inserts.scad>
use <tests/jack.scad>
use <tests/KP_pillow_blocks.scad>
use <tests/leadnuts.scad>
use <tests/leds.scad>
use <tests/LDRs.scad>
use <tests/LEDs.scad>
use <tests/light_strips.scad>
use <tests/linear_bearings.scad>
use <tests/meter.scad>
use <tests/LED_meters.scad>
use <tests/magnets.scad>
use <tests/microswitches.scad>
use <tests/modules.scad>
use <tests/nuts.scad>
use <tests/o_ring.scad>
use <tests/opengrab.scad>
use <tests/pcbs.scad>
use <tests/panel_meters.scad>
use <tests/PCBs.scad>
use <tests/pillars.scad>
use <tests/psus.scad>
use <tests/PSUs.scad>
use <tests/pulleys.scad>
use <tests/rails.scad>
use <tests/ring_terminals.scad>
use <tests/rockers.scad>
use <tests/rod.scad>
use <tests/screws.scad>
use <tests/SCS_bearing_blocks.scad>
use <tests/sealing_strip.scad>
use <tests/sheets.scad>
use <tests/SK_brackets.scad>
use <tests/spades.scad>
use <tests/springs.scad>
use <tests/ssrs.scad>
use <tests/SSRs.scad>
use <tests/stepper_motors.scad>
use <tests/Swiss_clips.scad>
use <tests/toggles.scad>
use <tests/transformers.scad>
use <tests/tubings.scad>
@@ -80,15 +92,25 @@ use <tests/door_hinge.scad>
use <tests/door_latch.scad>
use <tests/fan_guard.scad>
use <tests/fixing_block.scad>
use <tests/flat_hinge.scad>
use <tests/foot.scad>
use <tests/handle.scad>
use <tests/PCB_mount.scad>
use <tests/printed_box.scad>
use <tests/ribbon_clamp.scad>
use <tests/screw_knob.scad>
use <tests/socket_box.scad>
use <tests/strap_handle.scad>
use <tests/ssr_shroud.scad>
use <tests/SSR_shroud.scad>
use <tests/PSU_shroud.scad>
x5 = 800;
x0 = 0;
x1 = x0 + 110;
x2 = x1 + 90;
x3 = x2 + 130;
x4 = x3 + 200;
x5 = 850;
x6 = x5 + 150;
cable_grommets_y = 0;
@@ -113,6 +135,9 @@ translate([x5 + 70, cable_grommets_y + 150])
translate([x5, cable_grommets_y + 470]) {
door_hinges()
door_latches();
translate([120, 0])
flat_hinges();
}
translate([x5, cable_grommets_y + 370])
@@ -124,34 +149,38 @@ translate([x5 + 60, cable_grommets_y + 200])
translate([x5, cable_grommets_y + 250])
handle();
translate([900, 600])
translate([950, 600])
box_test();
translate([850, 1170])
translate([890, 750])
printed_boxes();
translate([850, 1330])
bbox_test();
x0 = 0;
inserts_y = 0;
nuts_y = inserts_y + 20;
washers_y = nuts_y + 60;
washers_y = nuts_y + 120;
screws_y = washers_y + 120;
o_rings_y = screws_y + 130;
springs_y = o_rings_y + 20;
circlips_y = screws_y + 160;
springs_y = circlips_y + 20;
o_rings_y = springs_y;
sealing_strip_y = springs_y + 20;
tubings_y = sealing_strip_y + 20;
pillars_y = tubings_y + 20;
leadnuts_y = pillars_y + 40;
pulleys_y = leadnuts_y +40;
ball_bearings_y = pillars_y + 40;
pulleys_y = ball_bearings_y +40;
hot_ends_y = pulleys_y + 60;
linear_bearings_y = hot_ends_y + 50;
sheets_y = linear_bearings_y + 50;
sheets_y = linear_bearings_y + 100;
pcbs_y = sheets_y + 40;
displays_y = pcbs_y + 150;
fans_y = displays_y + 100;
displays_y = pcbs_y + 170;
fans_y = displays_y + 80;
transformers_y = fans_y + 120;
psus_y = transformers_y + 190;
translate([x0 + 20, inserts_y])
translate([x0 + 35, inserts_y])
inserts();
translate([x0, inserts_y])
@@ -166,10 +195,13 @@ translate([x0, washers_y])
translate([x0, screws_y])
screws();
translate([x0, circlips_y])
circlips();
translate([x0, o_rings_y])
o_rings();
translate([x0, springs_y])
translate([x0 + 20, springs_y])
springs();
translate([x0 + 50, sealing_strip_y])
@@ -181,10 +213,7 @@ translate([x0, tubings_y])
translate([x0, pillars_y])
pillars();
translate([x0, leadnuts_y ])
leadnuts();
translate([x0 + 80, leadnuts_y])
translate([x0, ball_bearings_y])
ball_bearings();
translate([x0, pulleys_y])
@@ -217,13 +246,16 @@ translate([x0, fans_y]) {
translate([x0, transformers_y])
variacs();
translate([x0, psus_y])
translate([x0, psus_y]) {
psus();
psu_shrouds();
}
x1 = x0 + 100;
zipties_y = 0;
bulldogs_y = zipties_y + 40;
bulldogs_y = zipties_y + 30;
swiss_clips_y = bulldogs_y + 35;
leadnuts_y = swiss_clips_y + 50;
translate([x1, zipties_y])
zipties();
@@ -231,27 +263,40 @@ translate([x1, zipties_y])
translate([x1, bulldogs_y])
bulldogs();
x2 = x1 + 90;
translate([x1, swiss_clips_y])
swiss_clips();
translate([x1, leadnuts_y])
leadnuts();
leds_y = 0;
carriers_y = leds_y + 40;
spades_y = carriers_y + 40;
buttons_y = spades_y + 40;
magnets_y = carriers_y + 40;
spades_y = magnets_y + 20;
buttons_y = spades_y + 20;
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])
leds();
translate([x2 + 35, leds_y])
ldrs();
translate([x2 + 8, carriers_y])
carriers();
translate([x2+ 38, carriers_y])
meters();
translate([x2, magnets_y])
magnets();
translate([x2 + 68, carriers_y])
translate([x2 + 20, carriers_y])
led_meters();
translate([x2 + 70, leds_y])
fuseholders();
translate([x2, spades_y])
@@ -275,8 +320,6 @@ translate([x2, toggles_y])
translate([x2, components_y])
components();
x3 = x2 + 150;
veroboard_y = 0;
d_connectors_y = veroboard_y + 110;
iecs_y = d_connectors_y + 80;
@@ -285,10 +328,21 @@ ssrs_y = modules_y + 80;
blowers_y = ssrs_y + 60;
batteries_y = blowers_y + 100;
steppers_y = batteries_y + 70;
panel_meters_y = steppers_y + 70;
extrusions_y = panel_meters_y + 80;
translate([x3, veroboard_y])
veroboard_test();
translate([x3 + 70, veroboard_y + 30])
geared_steppers();
translate([x3 + 140, veroboard_y + 20])
pcb_mounts();
translate([x3 + 170, veroboard_y + 16])
cameras();
translate([x3, d_connectors_y])
d_connectors();
@@ -298,7 +352,10 @@ translate([x3, iecs_y])
translate([x3 + 15, modules_y])
microview();
translate([x3 + 40, modules_y])
translate([x3 + 60, modules_y])
hygrometer();
translate([x3 + 90, modules_y])
modules();
translate([x3, ssrs_y]) {
@@ -316,16 +373,24 @@ translate([x3, batteries_y])
translate([x2, steppers_y]) // interloper
stepper_motors();
translate([x2, panel_meters_y])
panel_meters();
translate([x2, extrusions_y])
extrusions();
translate([x3, transformers_y])
transformers();
x4 = x3 + 220;
belts_y = 0;
rails_y = belts_y + 200;
cable_strips_y = rails_y + 300;
extrusion_brackets_y = rails_y + 250;
sk_brackets_y = extrusion_brackets_y + 80;
kp_pillow_blocks_y = sk_brackets_y + 50;
scs_bearing_blocks_y = kp_pillow_blocks_y + 60;
translate([x4 + 112, belts_y + 58]) {
translate([x4 + 200, belts_y + 58]) {
belt_test();
translate([0, 60])
@@ -335,9 +400,21 @@ translate([x4 + 112, belts_y + 58]) {
translate([x4, rails_y + 130])
rails();
translate([x4, cable_strips_y])
translate([800, fans_y + 50])
cable_strips();
x6 = x5 + 150;
translate([x4, kp_pillow_blocks_y])
kp_pillow_blocks();
translate([x4, sk_brackets_y])
sk_brackets();
translate([x4, extrusion_brackets_y])
extrusion_brackets();
translate([x4, scs_bearing_blocks_y])
scs_bearing_blocks();
translate([x6, 125])
light_strips();

View File

@@ -33,25 +33,27 @@
//
include <../core.scad>
use <../vitamins/sheet.scad>
use <../vitamins/screw.scad>
use <../vitamins/washer.scad>
include <../vitamins/inserts.scad>
use <../vitamins/insert.scad>
use <../utils/quadrant.scad>
use <../utils/round.scad>
bezel_clearance = 0.2;
sheet_end_clearance = 1;
sheet_slot_clearance = 0.2;
function box_screw(type) = type[0]; //! Screw type to be used at the corners
function box_wall(type) = type[1]; //! Wall thickness of 3D parts
function box_sheets(type) = type[2]; //! Sheet type used for the sides
function box_top_sheet(type) = type[3]; //! Sheet type for the top
function box_base_sheet(type)= type[4]; //! Sheet type for the bottom
function box_feet(type) = type[5]; //! True to enable feet on the bottom bezel
function box_width(type) = type[6]; //! Internal width
function box_depth(type) = type[7]; //! Internal depth
function box_height(type) = type[8]; //! Internal height
function box_screw(type) = type[0]; //! Screw type to be used at the corners
function box_shelf_screw(type) = type[1]; //! Screw type to hold a shelf
function box_wall(type) = type[2]; //! Wall thickness of 3D parts
function box_sheets(type) = type[3]; //! Sheet type used for the sides
function box_top_sheet(type) = type[4]; //! Sheet type for the top
function box_base_sheet(type) = type[5]; //! Sheet type for the bottom
function box_feet(type) = type[6]; //! True to enable feet on the bottom bezel
function box_width(type) = type[7]; //! Internal width
function box_depth(type) = type[8]; //! Internal depth
function box_height(type) = type[9]; //! Internal height
function box(screw, wall, sheets, top_sheet, base_sheet, size, feet = false, shelf_screw = M3_dome_screw) = //! Construct a property list for a box.
concat([screw, shelf_screw, wall, sheets, top_sheet, base_sheet, feet], size);
function box_bezel_clearance(type) = bezel_clearance;
@@ -60,6 +62,7 @@ function box_profile_overlap(type) = 3 + sheet_end_clearance / 2;
function box_washer(type) = screw_washer(box_screw(type));
function box_insert(type) = screw_insert(box_screw(type));
function box_shelf_insert(type) = screw_insert(box_shelf_screw(type));
function box_hole_inset(type) = washer_radius(box_washer(type)) + 1;
function box_insert_r(type) = insert_hole_radius(box_insert(type));
@@ -88,23 +91,32 @@ function box_bezel_height(type, bottom) = //! Bezel height for top or bottom
grill_hole = 5;
grill_gap = 1.9;
module grill(width, height, r = 1000, poly = false, h = 0) { //! A staggered array of 5mm holes to make grills in sheets. Can be constrained to be circular. Set ```poly``` ```true``` for printing, ```false``` for milling.
function box_grill_hole_r() = grill_hole / 2;
module grill_hole_positions(width, height, r = 1000) {
nx = floor(width / (grill_hole + grill_gap));
xpitch = width / nx;
ny = floor(height / ((grill_hole + grill_gap) * cos(30)));
ypitch = height / ny;
for(y = [0 : ny - 1], x = [0 : nx - 1 - (y % 2)]) {
$x = -width / 2 + (x + 0.5 + (y % 2) / 2) * xpitch;
$y = -height / 2 + (y + 0.5) * ypitch;
if(sqrt(sqr($x) + sqr($y)) + grill_hole / 2 <= r)
translate([$x, $y])
children();
}
}
module grill(width, height, r = 1000, poly = false, h = 0) { //! A staggered array of 5mm holes to make grills in sheets. Can be constrained to be circular. Set ```poly``` ```true``` for printing, ```false``` for milling.
extrude_if(h)
for(y = [0 : ny - 1], x = [0 : nx - 1 - (y % 2)]) {
x = -width / 2 + (x + 0.5 + (y % 2) / 2) * xpitch;
y = -height / 2 + (y + 0.5) * ypitch;
if(sqrt(sqr(x) + sqr(y)) + grill_hole / 2 <= r)
translate([x, y])
if(poly)
poly_circle(r = grill_hole / 2);
else
circle(d = grill_hole);
}
if(poly)
grill_hole_positions(width, height, r)
poly_circle(r = grill_hole / 2);
else
grill_hole_positions(width, height, r)
circle(d = grill_hole);
}
module box_corner_profile_2D(type) { //! The 2D shape of the corner profile.
@@ -130,7 +142,7 @@ module box_corner_profile(type) { //! Generates the corner profile STL for 3D pr
length = box_height(type) - 2 * box_margin(type);
difference() {
linear_extrude(height = length, center = true, convexity = 5)
linear_extrude(length, center = true, convexity = 5)
box_corner_profile_2D(type);
for(z = [-1, 1])
@@ -149,24 +161,24 @@ module box_corner_profile_section(type, section, sections) { //! Generates inter
difference() {
union() {
linear_extrude(height = h, convexity = 5)
linear_extrude(h, convexity = 5)
box_corner_profile_2D(type);
if(!last_section) // male end always at the top
translate_z(section_length - 1)
for(i = [0 : 1], offset = i * layer_height)
linear_extrude(height = overlap + 1 - offset)
linear_extrude(overlap + 1 - offset)
offset(1 + offset - layer_height)
offset(-overlap_wall - 1)
box_corner_profile_2D(type);
}
if(section > 0)
translate_z(last_section ? h : 0) { // female at bottom unless last section
linear_extrude(height = 2 * (overlap + layer_height), center = true, convexity = 5)
linear_extrude(2 * (overlap + layer_height), center = true, convexity = 5)
offset(-overlap_wall)
box_corner_profile_2D(type);
linear_extrude(height = 2 * layer_height, center = true, convexity = 5)
linear_extrude(2 * layer_height, center = true, convexity = 5)
offset(-overlap_wall + layer_height)
box_corner_profile_2D(type);
}
@@ -176,6 +188,15 @@ module box_corner_profile_section(type, section, sections) { //! Generates inter
}
}
module box_corner_profile_sections(type, section, sections) { //! Generate four copies of a corner profile section
stl("box_corner_profile");
offset = box_boss_r(type) + 1;
for(i = [0 : 3])
rotate(i * 90)
translate([offset, offset])
box_corner_profile_section(type, section, sections);
}
module box_corner_quadrants(type, width, depth)
for(corner = [0:3]) {
x = [-1,1,1,-1][corner];
@@ -224,7 +245,7 @@ module box_bezel(type, bottom) { //! Generates top and bottom bezel STLs
// slots for side panels
//
translate_z(-box_profile_overlap(type))
linear_extrude(height = 2 * box_profile_overlap(type), center = true)
linear_extrude(2 * box_profile_overlap(type), center = true)
for(i = [-1, 1]) {
translate([i * (box_width(type) / 2 + t / 2 - sheet_slot_clearance / 2), 0])
square([t, box_depth(type) - 2 * box_corner_gap(type)], center = true);
@@ -241,7 +262,7 @@ module box_bezel(type, bottom) { //! Generates top and bottom bezel STLs
// leave plastic over the corner profiles
//
translate_z(-box_profile_overlap(type) - 1)
linear_extrude(height = box_profile_overlap(type) + box_corner_gap(type) + 2)
linear_extrude(box_profile_overlap(type) + box_corner_gap(type) + 2)
union() {
difference() {
square([box_width(type) - 2 * box_inset(type),
@@ -259,10 +280,11 @@ dowel_length = 20;
dowel_wall = extrusion_width * 3;
dowel_h_wall = layer_height * 6;
module box_bezel_section(type, bottom, rows, cols, x, y) { //! Generates interlocking sections of the bezel to allow it to be bigger than the printer
w = (box_width(type) + 2 * box_outset(type)) / cols;
h = (box_depth(type) + 2 * box_outset(type)) / rows;
tw = box_width(type) + 2 * box_outset(type);
w = tw / cols;
th = box_depth(type) + 2 * box_outset(type);
h = th / rows;
bw = box_outset(type) - bezel_clearance / 2;
bw2 = box_outset(type) + box_inset(type);
@@ -274,7 +296,7 @@ module box_bezel_section(type, bottom, rows, cols, x, y) { //! Generates interlo
end_clearance = 0.5;
module male() {
rotate([90, 0, 90])
linear_extrude(height = dowel_length - 2 * end_clearance, center = true)
linear_extrude(dowel_length - 2 * end_clearance, center = true)
difference() {
union() {
h = dh - layer_height;
@@ -337,7 +359,7 @@ module box_bezel_section(type, bottom, rows, cols, x, y) { //! Generates interlo
render() difference() {
union() {
clip(xmin = 0, xmax = w, ymin = 0, ymax = h)
translate([box_width(type) / 2 + box_outset(type) - x * w, box_depth(type) / 2 + box_outset(type) - y * h, box_profile_overlap(type)])
translate([tw / 2 - x * w, th / 2 - y * h, box_profile_overlap(type)])
box_bezel(type, bottom);
if(x < cols - 1 && y == 0)
@@ -397,17 +419,6 @@ module box_bezel_section(type, bottom, rows, cols, x, y) { //! Generates interlo
}
}
module box_shelf_blank(type) { //! Generates a 2D template for a shelf sheet
dxf("box_shelf");
difference() {
sheet_2D(box_sheets(type), box_width(type) - bezel_clearance, box_depth(type) - bezel_clearance, 1);
offset(bezel_clearance / 2)
box_corner_quadrants(type, box_width(type), box_depth(type));
}
}
module box_screw_hole_positions(type)
for(x = [-1, 1], y = [-1, 1])
translate([x * (box_width(type) / 2 - box_hole_inset(type)), y * (box_depth(type) / 2 - box_hole_inset(type))])
@@ -439,6 +450,107 @@ function subst_sheet(type, sheet) =
let(s = box_sheets(type))
sheet ? assert(sheet_thickness(sheet) == sheet_thickness(s)) sheet : s;
module box_shelf_blank(type, sheet = false) { //! Generates a 2D template for a shelf sheet
dxf("box_shelf");
difference() {
sheet_2D(subst_sheet(type, sheet), box_width(type) - bezel_clearance, box_depth(type) - bezel_clearance, 1);
offset(bezel_clearance / 2)
box_corner_quadrants(type, box_width(type), box_depth(type));
}
}
module box_shelf_screw_positions(type, screw_positions, thickness = 0, wall = undef) { //! Place children at the shelf screw positions
w = is_undef(wall) ? box_wall(type) : wall;
insert = box_shelf_insert(type);
translate_z(-insert_boss_radius(insert, w))
for(p = screw_positions)
multmatrix(p)
translate_z(thickness)
children();
}
module box_shelf_bracket(type, screw_positions, wall = undef) { //! Generates a shelf bracket, the first optional child is a 2D cutout and the second 3D cutouts
stl("shelf_bracket");
w = is_undef(wall) ? box_wall(type) : wall;
insert = box_shelf_insert(type);
lip = 2 * insert_boss_radius(insert, w);
width = insert_length(insert) + w;
module shape()
difference() {
square([box_width(type), box_depth(type)], center = true);
offset(bezel_clearance / 2)
box_corner_quadrants(type, box_width(type), box_depth(type));
if($children)
hflip()
children();
}
module boss()
translate_z(-width + eps)
linear_extrude(width - 2 * eps)
hull() {
circle4n(r = lip / 2 - eps);
translate([-lip / 2, -lip / 2 + eps])
square([lip, eps]);
}
difference() {
union() {
linear_extrude(w)
difference() {
shape()
if($children)
children(0);
round(2) offset(-width)
shape()
if($children)
children(0);
}
linear_extrude(lip)
difference() {
shape()
if($children)
children(0);
offset(-w)
shape()
if($children)
children(0);
}
hflip()
box_shelf_screw_positions(type, screw_positions, 0, w)
boss();
}
if($children > 1)
hflip()
children(1);
hflip()
box_shelf_screw_positions(type, screw_positions, 0, w)
insert_hole(insert, counterbore = 1, horizontal = true);
}
}
module box_shelf_bracket_section(type, rows, cols, x, y) { //! Generates sections of the shelf bracket to allow it to be bigger than the printer
tw = box_width(type);
w = tw / cols;
th = box_depth(type);
h = th / rows;
clip(xmin = 0, xmax = w, ymin = 0, ymax = h)
translate([tw / 2 - x * w, th / 2 - y * h])
children();
}
module box_left_blank(type, sheet = false) { //! Generates a 2D template for the left sheet, ```sheet``` can be set to override the type
dxf("box_left");

View File

@@ -33,7 +33,7 @@ assembly("box") {
y = [-1,-1,1,1][corner];
translate([x * (box_width(type) / 2 + 25 * exploded()), y * (box_depth(type) / 2 + 25 * exploded())])
rotate(corner * 90) {
color(pp2_colour) render()
stl_colour(pp2_colour) render()
box_corner_profile(type);
translate([box_hole_inset(type), box_hole_inset(type)])
@@ -50,7 +50,7 @@ assembly("box") {
translate_z(z * (box_height(type) / 2 - box_corner_gap(type) + 50 * exploded()))
rotate([z * 90 - 90, 0, 0])
if(bezels && (z > 0 ? top : base))
color(pp1_colour) render() box_bezel(type, z < 0);
stl_colour(pp1_colour) render() box_bezel(type, z < 0);
translate_z(z * (box_height(type) / 2 + sheet_thickness + 50 * exploded()))
box_screw_hole_positions(type)

View File

@@ -27,6 +27,10 @@
//! A list specifies the internal dimensions, screw type, top, bottom and side sheet types and the block
//! maximum spacing.
//!
//! * An optional name can be specified to allow more then one box in a project.
//! * An optional list of fixing blocks to be omitted can be given.
//! * Star washers can be omitted by setting the 11th parameter to false.
//!
//! Uses [fixing blocks](#fixing_block) and [corner blocks](#corner_block).
//
@@ -34,17 +38,27 @@ use <fixing_block.scad>
use <corner_block.scad>
use <../utils/maths.scad>
function bbox_screw(type) = type[0]; //! Screw type for corner blocks
function bbox_sheets(type) = type[1]; //! Sheet type for the sides
function bbox_base_sheet(type)= type[2]; //! Sheet type for the base
function bbox_top_sheet(type) = type[3]; //! Sheet type for the top
function bbox_span(type) = type[4]; //! Maximum span between fixing blocks
function bbox_width(type) = type[5]; //! Internal width
function bbox_depth(type) = type[6]; //! Internal depth
function bbox_height(type) = type[7]; //! Internal height
function bbox_screw(type) = type[0]; //! Screw type for corner blocks
function bbox_sheets(type) = type[1]; //! Sheet type for the sides
function bbox_base_sheet(type) = type[2]; //! Sheet type for the base
function bbox_top_sheet(type) = type[3]; //! Sheet type for the top
function bbox_span(type) = type[4]; //! Maximum span between fixing blocks
function bbox_width(type) = type[5]; //! Internal width
function bbox_depth(type) = type[6]; //! Internal depth
function bbox_height(type) = type[7]; //! Internal height
function bbox_name(type) = type[8] ? type[8] : "bbox"; //! Optional name if there is more than one box in a project
function bbox_skip_blocks(type)= type[9] ? type[9] : []; //! List of fixing blocks to skip, used to allow a hinged panel for example
function star_washers(type) = type[10] ? type[10] : is_undef(type[10]); //! Set to false to remove star washers.
function bbox(screw, sheets, base_sheet, top_sheet, span, size, name = "bbox", skip_blocks = [], star_washers = true) = //! Construct the property list for a butt_box
[ screw, sheets, base_sheet, top_sheet, span, size.x, size.y, size.z, name, skip_blocks, star_washers ];
function bbox_volume(type) = bbox_width(type) * bbox_depth(type) * bbox_height(type) / 1000000; //! Internal volume in litres
function bbox_area(type) = let(w = bbox_width(type), d = bbox_depth(type), h = bbox_height(type)) //! Internal surdface area in m^2
2 * (w * d + w * h + d * h) / 1000000;
module bbox_shelf_blank(type) { //! 2D template for a shelf
dxf("bbox_shelf");
dxf(str(bbox_name(type), "_shelf"));
sheet_2D(bbox_sheets(type), bbox_width(type), bbox_depth(type), 1);
}
@@ -60,18 +74,8 @@ function corner_block_positions(type) = let(
y = [-1,-1,1,1][corner]
) translate([x * (width / 2), y * (depth / 2), z * height / 2]) *
rotate([z > 0 ? 180 : 0, 0, corner * 90 + (z > 0 ? 90 : 0)])
];
module corner_block_positions(type) {
bt = sheet_thickness(bbox_base_sheet(type));
tt = sheet_thickness(bbox_top_sheet(type));
for(p = corner_block_positions(type))
let($thickness = transform([0, 0, 0], p).z > 0 ? tt : bt)
multmatrix(p)
children();
}
function corner_holes(type) = [for(p = corner_block_positions(type), q = corner_block_holes(bbox_screw(type))) p * q];
function fixing_block_positions(type) = let(
@@ -84,55 +88,44 @@ function fixing_block_positions(type) = let(
dspans = floor(depth / span),
dspan = depth / (dspans + 1),
hspans = floor(height / span),
hspan = height / (hspans + 1)
hspan = height / (hspans + 1),
skips = bbox_skip_blocks(type)
)
[
for(i = [0 : 1 : wspans - 1], y = [-1, 1], z = [-1, 1])
translate([(i - (wspans - 1) / 2) * wspan, y * depth / 2, z * height / 2]) *
rotate([0, z * 90 + 90, y * 90 + 90]),
if(!in(skips, [0, y, z]))
translate([(i - (wspans - 1) / 2) * wspan, y * depth / 2, z * height / 2]) *
rotate([0, z * 90 + 90, y * 90 + 90]),
for(i = [0 : 1 : dspans - 1], x = [-1, 1], z = [-1, 1])
translate([x * width / 2, (i - (dspans - 1) / 2) * dspan, z * height / 2]) *
rotate([0, z * 90 + 90, x * 90]),
if(!in(skips, [x, 0, z]))
translate([x * width / 2, (i - (dspans - 1) / 2) * dspan, z * height / 2]) *
rotate([0, z * 90 + 90, x * 90]),
for(i = [0 : 1 : hspans - 1], x = [-1, 1], y = [-1, 1])
translate([x * width / 2, y * depth / 2, (i - (hspans - 1) / 2) * hspan]) *
rotate([y > 0 ? 180 : 0, x * y * 90]),
if(!in(skips, [x, y, 0]))
translate([x * width / 2, y * depth / 2, (i - (hspans - 1) / 2) * hspan]) *
rotate([y > 0 ? 180 : 0, x * y * 90, 0]),
];
function side_holes(type) = [for(p = fixing_block_positions(type), q = fixing_block_holes(bbox_screw(type))) p * q];
module fixing_block_positions(type) {
t = sheet_thickness(bbox_sheets(type));
bt = sheet_thickness(bbox_base_sheet(type));
tt = sheet_thickness(bbox_top_sheet(type));
h = bbox_height(type) / 2 - 1;
for(p = fixing_block_positions(type))
let(z = transform([0, 0, 0], p).z, $thickness = z > h ? tt : z < -h ? bt : t)
multmatrix(p)
children();
}
module drill_holes(type, t)
for(list = [corner_holes(type), side_holes(type)], p = list)
let(q = t * p)
if(abs(transform([0, 0, 0], q).z) < eps)
multmatrix(q)
drill(screw_clearance_radius(bbox_screw(type)), 0);
module bbox_drill_holes(type, t)
position_children(concat(corner_holes(type), side_holes(type)), t)
drill(screw_clearance_radius(bbox_screw(type)), 0);
module bbox_base_blank(type) { //! 2D template for the base
dxf("bbox_base");
dxf(str(bbox_name(type), "_base"));
difference() {
sheet_2D(bbox_base_sheet(type), bbox_width(type), bbox_depth(type), 1);
drill_holes(type, translate(bbox_height(type) / 2));
bbox_drill_holes(type, translate(bbox_height(type) / 2));
}
}
module bbox_top_blank(type) { //! 2D template for the top
dxf("bbox_top");
dxf(str(bbox_name(type), "_top"));
t = sheet_thickness(bbox_sheets(type));
@@ -140,40 +133,44 @@ module bbox_top_blank(type) { //! 2D template for the top
translate([0, t / 2])
sheet_2D(bbox_top_sheet(type), bbox_width(type) + 2 * t, bbox_depth(type) + t);
drill_holes(type, translate(-bbox_height(type) / 2));
bbox_drill_holes(type, translate(-bbox_height(type) / 2));
}
}
module bbox_left_blank(type) { //! 2D template for the left side
dxf("bbox_left");
function subst_sheet(type, sheet) =
let(s = bbox_sheets(type))
sheet ? assert(sheet_thickness(sheet) == sheet_thickness(s)) sheet : s;
module bbox_left_blank(type, sheet = false) { //! 2D template for the left side
dxf(str(bbox_name(type), "_left"));
t = sheet_thickness(bbox_sheets(type));
bb = sheet_thickness(bbox_base_sheet(type));
difference() {
translate([-t / 2, -bb / 2])
sheet_2D(bbox_sheets(type), bbox_depth(type) + t, bbox_height(type) + bb);
sheet_2D(subst_sheet(type, sheet), bbox_depth(type) + t, bbox_height(type) + bb);
drill_holes(type, rotate([0, 90, 90]) * translate([bbox_width(type) / 2, 0]));
bbox_drill_holes(type, rotate([0, 90, 90]) * translate([bbox_width(type) / 2, 0]));
}
}
module bbox_right_blank(type) { //! 2D template for the right side
dxf("bbox_right");
module bbox_right_blank(type, sheet = false) { //! 2D template for the right side
dxf(str(bbox_name(type), "_right"));
t = sheet_thickness(bbox_sheets(type));
bb = sheet_thickness(bbox_base_sheet(type));
difference() {
translate([t / 2, -bb / 2])
sheet_2D(bbox_sheets(type), bbox_depth(type) + t, bbox_height(type) + bb);
sheet_2D(subst_sheet(type, sheet), bbox_depth(type) + t, bbox_height(type) + bb);
drill_holes(type, rotate([0, -90, 90]) * translate([-bbox_width(type) / 2, 0]));
bbox_drill_holes(type, rotate([0, 90, 90]) * translate([-bbox_width(type) / 2, 0]));
}
}
module bbox_front_blank(type) { //! 2D template for the front
dxf("bbox_front");
module bbox_front_blank(type, sheet = false, width = 0) { //! 2D template for the front
dxf(str(bbox_name(type), "_front"));
t = sheet_thickness(bbox_sheets(type));
bb = sheet_thickness(bbox_base_sheet(type));
@@ -181,23 +178,23 @@ module bbox_front_blank(type) { //! 2D template for the front
difference() {
translate([0, (bt - bb) / 2])
sheet_2D(bbox_sheets(type), bbox_width(type) + 2 * t, bbox_height(type) + bb + bt);
sheet_2D(subst_sheet(type, sheet), max(bbox_width(type) + 2 * t, width), bbox_height(type) + bb + bt);
drill_holes(type, rotate([-90, 0, 0]) * translate([0, bbox_depth(type) / 2]));
bbox_drill_holes(type, rotate([-90, 0, 0]) * translate([0, bbox_depth(type) / 2]));
}
}
module bbox_back_blank(type) { //! 2D template for the back
dxf("bbox_back");
module bbox_back_blank(type, sheet = false) { //! 2D template for the back
dxf(str(bbox_name(type), "_back"));
bb = sheet_thickness(bbox_base_sheet(type));
t = sheet_thickness(bbox_sheets(type));
difference() {
translate([0, -bb / 2])
sheet_2D(bbox_sheets(type), bbox_width(type), bbox_height(type) + bb);
sheet_2D(subst_sheet(type, sheet), bbox_width(type), bbox_height(type) + bb);
drill_holes(type, rotate([90, 0, 0]) * translate([0, -bbox_depth(type) / 2]));
bbox_drill_holes(type, rotate([-90, 0, 0]) * translate([0, -bbox_depth(type) / 2]));
}
}
@@ -208,54 +205,64 @@ module bbox_front(type) render_2D_sheet(bbox_sheets(type)) bbox_front_blank(type
module bbox_left(type) render_2D_sheet(bbox_sheets(type)) bbox_left_blank(type); //! Default left side, can be overridden to customise
module bbox_right(type) render_2D_sheet(bbox_sheets(type)) bbox_right_blank(type); //! Default right side, can be overridden to customise
module _bbox_assembly(type, top = true, base = true, left = true, right = true, back = true, front = true) //! The box assembly, wrap with a local copy without parameters
assembly("bbox") {
module _bbox_assembly(type, top = true, base = true, left = true, right = true, back = true, front = true) { //! The box assembly, wrap with a local copy without parameters
width = bbox_width(type);
depth = bbox_depth(type);
height = bbox_height(type);
echo("Box:", width, depth, height);
echo("Box:", width, depth, height, volume = bbox_volume(type), area = bbox_area(type));
t = sheet_thickness(bbox_sheets(type));
bt = sheet_thickness(bbox_base_sheet(type));
tt = sheet_thickness(bbox_top_sheet(type));
corner_block_positions(type)
fastened_corner_block_assembly(t, bbox_screw(type), $thickness);
function is_missing_screw(p) = p.y > depth / 2 - 1 ? !back : false;
fixing_block_positions(type)
fastened_fixing_block_assembly(t, bbox_screw(type), thickness2 = $thickness);
assembly(bbox_name(type)) {
for(x = [-1, 1])
translate([x * (width / 2 + t / 2 + eps + 25 * exploded()), 0])
rotate([90, 0, x * 90])
if(x > 0) {
if(right)
bbox_right(type);
for(p = corner_block_positions(type))
let(q = transform([0, 0, 0], p), thickness = q.z > 0 ? tt : bt)
multmatrix(p)
fastened_corner_block_assembly(is_missing_screw(q) && ((q.z > 0) != (q.x > 0)) ? 0 : t, bbox_screw(type), thickness,
is_missing_screw(q) && ((q.z > 0) == (q.x > 0)) ? 0 : t, star_washers = star_washers(type));
h = height / 2 - 1;
for(p = fixing_block_positions(type))
let(q = transform([0, 0, 0], p), thickness = q.z > h ? tt : q.z < -h ? bt : t)
multmatrix(p)
fastened_fixing_block_assembly(is_missing_screw(q) ? 0 : t, bbox_screw(type), thickness2 = thickness, star_washers = star_washers(type));
for(x = [-1, 1])
translate([x * (width / 2 + t / 2 + eps + 25 * exploded()), 0])
rotate([90, 0, x * 90])
if(x > 0) {
if(right)
bbox_right(type);
}
else
if(left)
bbox_left(type);
for(y = [1, -1])
translate([0, y * (depth / 2 + t / 2 + eps + 25 * exploded())])
rotate([90, 0, y * 90 + 90])
if(y < 0) {
if(front)
bbox_front(type);
}
else
if(back)
bbox_back(type);
for(z = [-1, 1]) {
sheet_thickness = z > 0 ? tt : bt;
translate_z(z * (height / 2 + sheet_thickness / 2 + eps + 100 * exploded()))
if(z > 0) {
if(top)
bbox_top(type);
}
else
if(left)
bbox_left(type);
for(y = [-1, 1])
translate([0, y * (depth / 2 + t / 2 + eps + 25 * exploded())])
rotate([90, 0, y * 90 + 90])
if(y < 0) {
if(front)
bbox_front(type);
}
else
if(back)
bbox_back(type);
for(z = [-1, 1]) {
sheet_thickness = z > 0 ? tt : bt;
translate_z(z * (height / 2 + sheet_thickness / 2 + eps + 100 * exploded()))
if(z > 0) {
if(top)
bbox_top(type);
}
else
if(base)
bbox_base(type);
if(base)
bbox_base(type);
}
}
}

View File

@@ -21,7 +21,7 @@
//! Printed cable grommets for passing cables through panels avoiding sharp edges and in the case
//! of conductive panels, an extra layer of insulation.
//
include <../core.scad>
include <../utils/core/core.scad>
use <../vitamins/cable_strip.scad>
base = 1.25;
@@ -59,7 +59,7 @@ module ribbon_grommet(ways, thickness) { //! Generate the STL for a printed ribb
union() {
for(side = [-1, 1])
translate_z(side * (width - wall) / 2)
linear_extrude(height = wall, center = true, convexity = 5)
linear_extrude(wall, center = true, convexity = 5)
difference() {
hull() {
translate([-length / 2, 0])
@@ -73,7 +73,7 @@ module ribbon_grommet(ways, thickness) { //! Generate the STL for a printed ribb
square([slot_length, slot_height]);
}
linear_extrude(height = width -1, center = true)
linear_extrude(width -1, center = true)
difference() {
ribbon_grommet_hole(ways, expand = false, h = 0);
@@ -130,15 +130,15 @@ module round_grommet_bottom(diameter, od = undef) { //! Generate the STL for a r
}
module round_grommet_hole(diameter, h = 100) //! Make a hole for a round grommet
drill(diameter / 2 + wall + clearance, h);
drill(corrected_radius(diameter / 2) + wall + clearance, h);
module round_grommet_assembly(diameter, thickness, od = undef) {
color(pp1_colour)
stl_colour(pp1_colour)
translate_z(wall)
vflip()
round_grommet_top(diameter, thickness, od);
color(pp2_colour)
stl_colour(pp2_colour)
translate_z(-thickness)
vflip()
round_grommet_bottom(diameter, od);
@@ -149,12 +149,17 @@ module mouse_grommet_hole(r, h = 50, z = undef, expand = wall + clearance) //! M
hull(){
R = r + expand;
translate([0, z == undef ? R : z])
semi_circle(R);
if(expand)
semi_circle(R);
else
semi_teardrop(r = R, h = 0);
translate([-R, 0])
square([2 * R, eps]);
}
function mouse_grommet_offset(r) = r + wall;
module mouse_grommet(r, thickness) { //! Make the STL for a mouse grommet
stl(str("mouse_grommet_", r * 10, "_", thickness));
@@ -165,14 +170,14 @@ module mouse_grommet(r, thickness) { //! Make the STL for a mouse grommet
union() {
for(side = [-1, 1])
translate_z(side * (width - wall) / 2)
linear_extrude(height = wall, center = true)
linear_extrude(wall, center = true)
difference() {
mouse_grommet_hole(r + wall + overlap, z = r + wall, h = 0, expand = 0);
mouse_grommet_hole(r, z = r + wall, h = 0, expand = wall + overlap);
translate([0, wall])
mouse_grommet_hole(r, h = 0, expand = 0);
}
linear_extrude(height = width - 1, center = true)
linear_extrude(width - 1, center = true)
difference() {
mouse_grommet_hole(r, h = 0, z = r + wall, expand = wall);
@@ -182,6 +187,23 @@ module mouse_grommet(r, thickness) { //! Make the STL for a mouse grommet
}
}
module mouse_grommet_assembly(r, thickness)
stl_colour(pp1_colour)
rotate([-90, 0, 0])
mouse_grommet(r, thickness);
module ribbon_grommet_20_3_stl() ribbon_grommet(20, 3);
module mouse_grommet_20_3_stl() mouse_grommet(2,3);
module mouse_grommet_30_3_stl() mouse_grommet(3,3);
module mouse_grommet_15_3_stl() mouse_grommet(1.5, 3);
module mouse_grommet_20_3_stl() mouse_grommet(2, 3);
module mouse_grommet_25_3_stl() mouse_grommet(2.5, 3);
module mouse_grommet_30_3_stl() mouse_grommet(3, 3);
module round_grommet_bottom_30_stl() round_grommet_bottom(3);
module round_grommet_bottom_40_stl() round_grommet_bottom(4);
module round_grommet_bottom_50_stl() round_grommet_bottom(5);
module round_grommet_bottom_60_stl() round_grommet_bottom(6);
module round_grommet_top_30_3_stl() round_grommet_top(3, 3);
module round_grommet_top_40_3_stl() round_grommet_top(4, 3);
module round_grommet_top_50_3_stl() round_grommet_top(5, 3);
module round_grommet_top_60_3_stl() round_grommet_top(6, 3);

View File

@@ -18,11 +18,13 @@
//
//
//! Adapts ESP12 module to 0.1" grid. See <https://hydraraptor.blogspot.com/2018/04/esp-12-module-breakout-adaptor.html>.
//! Adapts ESP12 modules and various small PCBs to 0.1" grid. See <https://hydraraptor.blogspot.com/2018/04/esp-12-module-breakout-adaptor.html>.
//
$extrusion_width = 0.5;
include <../core.scad>
include <../utils/core/core.scad>
function carrier_height() = 3; //! Height of PCB carrier
module ESP12F_carrier_stl() { //! Generate the STL for an ESP12 carrier
stl("ESP12F_carrier");
@@ -33,7 +35,7 @@ module ESP12F_carrier_stl() { //! Generate the STL for an ESP12 carrier
hole2 = pitch2 - 3 * extrusion_width;
length1 = (pins - 1) * pitch1 + hole + squeezed_wall * 2;
length2 = (pins - 1) * pitch2 + hole + squeezed_wall * 2;
height = 3;
height = carrier_height();
wpitch1 = (pins - 1) * pitch1;
wpitch2 = ceil(wpitch1 / 2.54) * 2.54;
@@ -61,3 +63,71 @@ module ESP12F_carrier_stl() { //! Generate the STL for an ESP12 carrier
}
}
}
module TP4056_carrier_stl() { //! Generate the STL for an TP4056 carrier, two required
stl("TP4056_carrier");
pitch = 2.54;
outer_pitch = 13.9;
inner_pitch = 7.54;
hole = pitch - 3 * extrusion_width;
pins = 6;
length1 = outer_pitch + hole + squeezed_wall * 2;
length2 = (pins - 1) * pitch + hole + squeezed_wall * 2;
height = carrier_height();
width = hole + squeezed_wall * 2;
spacing = inch(0.9);
difference() {
hull() {
translate_z(height - eps / 2)
cube([width, length1, eps], center = true);
translate_z(eps / 2)
cube([width, length2, eps], center = true);
}
for(i = [0 : pins - 1])
let(x = [-outer_pitch / 2, - inner_pitch / 2, 0, 0, inner_pitch / 2, outer_pitch / 2][i])
if(x)
hull() {
translate([0, x, height])
cube([hole, hole, eps], center = true);
translate([0, i * pitch - (pins - 1) * pitch / 2])
cube([hole, hole, eps], center = true);
}
}
}
module MT3608_carrier_stl() { //! Generate the STL for an MT3608 carrier, two required
stl("MT3608_carrier");
pcb_width = 17;
w_pitch_top = 6.81;
w_pitch_bot = inch(0.3);
l_pitch_top = 30.855;
l_pitch_bot = inch(1.2);
hole = 1;
height = carrier_height();
wall = 2 * extrusion_width;
width = hole + 2 * wall;
offset = (l_pitch_top - l_pitch_bot) / 2;
difference() {
hull() {
translate([offset, 0, height - eps / 2])
rounded_rectangle([width, pcb_width - 2, eps], 1);
translate_z(eps / 2)
rounded_rectangle([width, pcb_width - 2, eps], 1);
}
for(side = [-1, 1])
hull() {
translate([offset, side * w_pitch_top / 2, height])
cube([hole, hole, eps], center = true);
translate([0, side * w_pitch_bot / 2])
cube([hole, hole, eps], center = true);
}
}
}

View File

@@ -24,10 +24,14 @@
//! See [butt_box](#Butt_box) for an example of usage.
//!
//! Note that the block with its inserts is defined as a sub assembly, but its fasteners get added to the parent assembly.
//!
//! Specific fasteners can be omitted by setting a side's thickness to 0 and the block omitted by setting ```show_block``` to false.
//! This allows the block and one set of fasteners to be on one assembly and the other fasteners on the mating assemblies.
//!
//! Star washers can be omitted by setting ```star_washers``` to false.
//
include <../core.scad>
include <../vitamins/screws.scad>
include <../vitamins/inserts.scad>
use <../vitamins/insert.scad>
use <../utils/rounded_cylinder.scad>
use <../utils/maths.scad>
@@ -57,8 +61,8 @@ module corner_block_v_hole(screw = def_screw) //! Place children at the bottom s
multmatrix(corner_block_v_hole(screw))
children();
module corner_block_h_holes(screw = def_screw) //! Place children at the side screw holes
for(p = corner_block_h_holes(screw))
module corner_block_h_holes(screw = def_screw, index = undef) //! Place children at the side screw holes
for(p = !is_undef(index) ? [corner_block_h_holes(screw)[index]] : corner_block_h_holes(screw))
multmatrix(p)
children();
@@ -116,7 +120,7 @@ module corner_block_assembly(screw = def_screw, name = false) //! The printed bl
assembly(str("corner_block_M", 20 * screw_radius(screw))) {
insert = screw_insert(screw);
color(name ? pp2_colour : pp1_colour)
stl_colour(name ? pp2_colour : pp1_colour)
render() corner_block(screw, name) children();
corner_block_h_holes(screw)
@@ -126,22 +130,33 @@ assembly(str("corner_block_M", 20 * screw_radius(screw))) {
insert(insert);
}
module fastened_corner_block_assembly(thickness, screw = def_screw, thickness_below = undef, name = false) { //! Printed block with all fasteners
module fastened_corner_block_assembly(thickness, screw = def_screw, thickness_below = undef, thickness_side2 = undef, name = false, show_block = true, star_washers = true) { //! Printed block with all fasteners
thickness2 = !is_undef(thickness_below) ? thickness_below : thickness;
thickness3 = !is_undef(thickness_side2) ? thickness_side2 : thickness;
washer = screw_washer(screw);
insert = screw_insert(screw);
screw_length = screw_shorter_than(2 * washer_thickness(washer) + thickness + insert_length(insert) + overshoot);
function screw_length(t) = screw_shorter_than((star_washers ? 2 : 1) * washer_thickness(washer) + t + insert_length(insert) + overshoot);
screw_length = screw_length(thickness);
screw_length2 = screw_length(thickness2);
screw_length3 = screw_length(thickness3);
corner_block_assembly(screw, name) children();
if(show_block)
corner_block_assembly(screw, name) children();
corner_block_h_holes(screw)
translate_z(thickness)
screw_and_washer(screw, screw_length, true);
if(thickness)
corner_block_h_holes(screw, 0)
translate_z(thickness)
screw_and_washer(screw, screw_length, star_washers);
thickness2 = thickness_below ? thickness_below : thickness;
screw_length2 = screw_shorter_than(2 * washer_thickness(washer) + thickness2 + insert_length(insert) + overshoot);
corner_block_v_hole(screw)
translate_z(thickness2)
screw_and_washer(screw, screw_length2, true);
if(thickness3)
corner_block_h_holes(screw, 1)
translate_z(thickness3)
screw_and_washer(screw, screw_length3, star_washers);
if(thickness2)
corner_block_v_hole(screw)
translate_z(thickness2)
screw_and_washer(screw, screw_length2, star_washers);
}
module corner_block_M20_stl() corner_block(M2_cap_screw);

View File

@@ -24,7 +24,6 @@
//! Rubber door [sealing strip](#sealing_strip) is used to make it airtight and a [door_latch](#door_latch) holds it closed.
//
include <../core.scad>
include <../vitamins/screws.scad>
width = 18;
thickness = 4;
@@ -61,7 +60,7 @@ module door_hinge(door_thickness) { //! Generates STL fo
union() {
rotate([90, 0, 0])
linear_extrude(height = width, center = true)
linear_extrude(width, center = true)
difference() {
hull() {
translate([dia / 2, thickness + door_thickness / 2])
@@ -75,9 +74,9 @@ module door_hinge(door_thickness) { //! Generates STL fo
square([1, thickness + door_thickness]);
}
translate([dia / 2, thickness + door_thickness / 2])
teardrop(r = screw_clearance_radius(pin_screw), h = 0);
teardrop_plus(r = screw_clearance_radius(pin_screw), h = 0);
}
linear_extrude(height = thickness)
linear_extrude(thickness)
difference() {
hull() {
translate([0, -width / 2])
@@ -109,7 +108,7 @@ module door_hinge_stat_stl() { //! Generates the STL for the stationary part
stl("door_hinge_stat");
union() {
linear_extrude(height = thickness)
linear_extrude(thickness)
difference() {
rounded_square([stat_length, stat_width], rad);
@@ -118,7 +117,7 @@ module door_hinge_stat_stl() { //! Generates the STL for the stationary part
}
rotate([90, 0, 0])
linear_extrude(height = stat_width, center = true)
linear_extrude(stat_width, center = true)
difference() {
hull() {
translate([0, dia / 2 + stat_clearance])
@@ -128,7 +127,7 @@ module door_hinge_stat_stl() { //! Generates the STL for the stationary part
square([dia, 1], center = true);
}
translate([0, dia / 2 + stat_clearance])
teardrop(r = screw_clearance_radius(pin_screw), h = 0);
teardrop_plus(r = screw_clearance_radius(pin_screw), h = 0);
}
}
}
@@ -142,7 +141,7 @@ module door_hinge_assembly(top, door_thickness = 6) { //! The moving assembly th
translate([0, pin_y - (thickness + door_thickness / 2), dir * width / 2]) {
rotate([90, 0, 180])
color("red") door_hinge(door_thickness);
stl_colour(pp2_colour) door_hinge(door_thickness);
rotate([90, 0, 0])
door_hinge_hole_positions()
@@ -166,7 +165,7 @@ module door_hinge_static_assembly(top, sheet_thickness = 3) { //! The stationary
translate([pin_x, 0, -dir * (stat_width / 2 + washer_thickness(screw_washer(pin_screw)))])
rotate([90, 0, 0]) {
color("lime") door_hinge_stat_stl();
stl_colour(pp1_colour) door_hinge_stat_stl();
door_hinge_stat_hole_positions() {
screw_and_washer(stat_screw, stat_screw_length);

View File

@@ -22,7 +22,6 @@
//
include <../core.scad>
use <../utils/hanging_hole.scad>
include <../vitamins/screws.scad>
length = 35;
width = 12;
@@ -66,7 +65,7 @@ module door_latch_assembly(sheet_thickness = 3) { //! The assembly for a specifi
translate([0, -height - washer_thickness(washer)])
rotate([-90, 0, 0]) {
color("lime") render() door_latch_stl();
stl_colour(pp1_colour) render() door_latch_stl();
translate_z(nut_trap_depth)
vflip()

View File

@@ -24,10 +24,14 @@
//! See [butt_box](#Butt_box) for an example of usage.
//!
//! Note that the block with its inserts is defined as a sub assembly, but its fasteners get added to the parent assembly.
//!
//! Specific fasteners can be omitted by setting a side's thickness to 0 and the block omitted by setting ```show_block``` to false.
//! This allows the block and one set of fasteners to be on one assembly and the other fasteners on the mating assemblies.
//!
//! Star washers can be omitted by setting ```star_washers``` to false.
//
include <../core.scad>
include <../vitamins/screws.scad>
include <../vitamins/inserts.scad>
use <../vitamins/insert.scad>
use <../utils/maths.scad>
def_screw = M3_cap_screw;
@@ -77,7 +81,7 @@ module fixing_block(screw = def_screw) { //! Generate the STL
difference() {
union() {
linear_extrude(height = fb_height, convexity = 5)
linear_extrude(fb_height, convexity = 5)
difference() {
hull() {
for(side = [-1, 1]) {
@@ -105,7 +109,7 @@ module fixing_block_assembly(screw = def_screw) pose([55, 180, 25], [0, 4.8, 4.8
assembly(str("fixing_block_M", 20 * screw_radius(screw))) {
translate_z(fixing_block_height(screw))
rotate([0, 180, 0])
color(pp1_colour) render() fixing_block(screw);
stl_colour(pp1_colour) render() fixing_block(screw);
insert = screw_insert(screw);
@@ -116,20 +120,24 @@ assembly(str("fixing_block_M", 20 * screw_radius(screw))) {
insert(insert);
}
module fastened_fixing_block_assembly(thickness, screw = def_screw, screw2 = undef, thickness2 = undef) { //! Assembly with fasteners in place
module fastened_fixing_block_assembly(thickness, screw = def_screw, screw2 = undef, thickness2 = undef, show_block = true, star_washers = true) { //! Assembly with fasteners in place
module fb_screw(screw, thickness) {
washer = screw_washer(screw);
insert = screw_insert(screw);
screw_length = screw_longer_than(2 * washer_thickness(washer) + thickness + insert_length(insert));
screw_length = screw_longer_than((star_washers ? 2 : 1) * washer_thickness(washer) + thickness + insert_length(insert));
translate_z(thickness)
screw_and_washer(screw, screw_length, true);
if(thickness)
translate_z(thickness)
screw_and_washer(screw, screw_length, star_washers);
}
no_pose() fixing_block_assembly(screw);
if(show_block)
no_pose()
fixing_block_assembly(screw);
t2 = !is_undef(thickness2) ? thickness2 : thickness;
fixing_block_v_holes(screw)
fb_screw(screw, thickness2 ? thickness2 : thickness);
fb_screw(screw, t2);
fixing_block_h_hole(screw)
fb_screw(screw2 ? screw2 : screw, thickness);

182
printed/flat_hinge.scad Normal file
View File

@@ -0,0 +1,182 @@
//
// NopSCADlib Copyright Chris Palmer 2018
// 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/>.
//
//
//! A parametric flat hinge. A piece of filament can be used for the hinge pin.
//!
//! The width, depth, thickness, number and type of screws, number of knuckles, knuckle diameter, pin diameter and clearance can all be varied.
//! A margin between the screws and the knuckle edge can be enforced to allow the hinge to bend all the way back to 270&deg; from closed.
//!
//! Opening the test in OpenSCAD with its customiser enabled allows these parameters to be played with.
//!
//! Note setting ```thickness1``` or ```thickness2``` to zero in the ```hinge_fastened_assembly()``` removes the screws from one side or the other and
//! setting ```show_hinge``` to false removes the hinge.
//! This allows the hinges and one set of screws to belong to one assembly and the other set of screws to another assembly.
//
include <../core.scad>
function hinge_width(type) = type[1]; //! Width
function hinge_depth(type) = type[2]; //! Depth of each leaf
function hinge_thickness(type) = type[3]; //! Thickness of the leaves
function hinge_pin_dia(type) = type[4]; //! The pin diameter
function hinge_knuckle_dia(type) = type[5]; //! The knuckle diameter
function hinge_knuckles(type) = type[6]; //! How many knuckles
function hinge_screw(type) = type[7]; //! Screw type to mount it
function hinge_screws(type) = type[8]; //! How many screws
function hinge_clearance(type) = type[9]; //! Clearance between knuckles
function hinge_margin(type) = type[10]; //! How far to keep the screws from the knuckes
function flat_hinge(name, size, pin_d, knuckle_d, knuckles, screw, screws, clearance, margin) = //! Construct the property list for a flat hinge.
[name, size.x, size.y, size.z, pin_d, knuckle_d, knuckles, screw, screws, clearance, margin];
function hinge_radius(type) = washer_radius(screw_washer(hinge_screw(type))) + 1;
module hinge_screw_positions(type) { //! Place children at the screw positions
screws = hinge_screws(type);
w = hinge_width(type);
d = hinge_depth(type);
r = hinge_radius(type);
m = hinge_margin(type);
assert(screws > 1, "must be at least two screws");
w_pitch = (w - 2 * r) / (screws - 1);
d_pitch = d - 2 * r - m;
wr = washer_radius(screw_washer(hinge_screw(type)));
assert(w_pitch >= wr && norm([w_pitch, d_pitch]) >= 2 * wr && d_pitch >= 0, "not enough room for screws");
for(i = [0 : screws - 1])
translate([-w / 2 + r + i * w_pitch, r + m + (i % 2) * d_pitch])
children();
}
module hinge_male(type, female = false) { //! The half with the stationary pin
stl(str("hinge_", female ? "fe": "", "male_", type[0]));
r = hinge_radius(type);
w = hinge_width(type);
t = hinge_thickness(type);
kr = hinge_knuckle_dia(type) / 2;
pr = hinge_pin_dia(type) / 2;
assert(kr > pr, "knuckle diameter must be bigger than the pin diameter");
n = hinge_knuckles(type);
assert(n >= 3, "must be at least three knuckes");
mn = ceil(n / 2); // Male knuckles
fn = floor(n / 2); // Female knuckles
gap = hinge_clearance(type);
mw = (w - (n - 1) * gap) / 2 / mn; // Male knuckle width
fw = (w - (n - 1) * gap) / 2 / fn; // Female knuckle width
teardrop_r = kr / cos(22.5); // The corner on the teardrop
inset = sqrt(sqr(teardrop_r + gap) - sqr(kr - t)) - kr;
linear_extrude(t)
difference() {
hull() {
for(side = [-1, 1])
translate([side * (w / 2 - r), hinge_depth(type) - r])
circle4n(r);
translate([-w / 2, inset])
square([w, eps]);
}
hinge_screw_positions(type)
poly_circle(screw_clearance_radius(hinge_screw(type)));
}
pitch = mw + gap + fw + gap;
dir = female ? -1 : 1;
translate([0, -kr, kr])
rotate([90, 0, -90])
for(z = [0 : (female ? fn : mn) - 1])
translate_z(-dir * w / 2 + z * dir * pitch + (female ? -fw - mw - gap : 0))
linear_extrude(female ? fw : mw)
difference() {
hull() {
rotate(180)
teardrop(r = kr, h = 0);
translate([-kr - 1, -kr])
square(1);
}
teardrop_plus(r = pr + (female ? gap : 0), h = 0);
}
}
module hinge_female(type) hinge_male(type, true);
module hinge_both(type) { //! Both parts together for printing
hinge_male(type);
translate([0, -hinge_knuckle_dia(type)])
rotate(180)
hinge_female(type);
}
module hinge_assembly(type, angle = 0)
assembly(str("hinge_", type[0])) { //! Assembled hinge
kr = hinge_knuckle_dia(type) / 2;
hr = hinge_pin_dia(type) / 2;
w = hinge_width(type);
vitamin(str(": Hinge pin ", w, " x ", 2 * hr, "mm"));
stl_colour(pp1_colour) hinge_male(type);
translate([0, -kr, kr]) {
rotate([0, 90, 0])
explode(w + 10)
stl_colour("silver") cylinder(r = hr , h = w, center = true);
rotate([-angle, 0, 0])
translate([0, -kr, -kr])
rotate(180)
stl_colour(pp2_colour) hinge_female(type);
}
}
module hinge_fastened_assembly(type, thickness1, thickness2, angle, show_hinge = true) { //! Assembled hinge with its fasteners
if(show_hinge)
hinge_assembly(type, angle);
screw = hinge_screw(type);
washer_t = 2 * washer_thickness(screw_washer(screw));
nut = screw_nut(screw);
nut_t = nut_thickness(nut, true);
t = hinge_thickness(type);
kr = hinge_knuckle_dia(type) / 2;
module fasteners(thickness)
if(thickness)
hinge_screw_positions(type) {
translate_z(t)
screw_and_washer(screw, screw_longer_than(t + thickness + washer_t + nut_t));
translate_z(-thickness)
vflip()
nut_and_washer(nut, true);
}
fasteners(thickness1);
translate([0, -kr, kr])
rotate([-angle, 0, 0])
translate([0, -kr, - kr])
rotate(180)
fasteners(thickness2);
}

View File

@@ -22,13 +22,13 @@
//! inserts don't grip well in rubber.
//
include <../core.scad>
include <../vitamins/screws.scad>
include <../vitamins/inserts.scad>
use <../vitamins/insert.scad>
foot = [25, 12, 3, 2, M4_cap_screw, 10];
insert_foot = [20, 10, 0, 2, M3_cap_screw, 10];
function Foot(d, h, t, r, screw, slant = 10) = [d, h, t, r, screw, slant]; //! Construct a foot property list
foot = Foot(25, 12, 3, 2, M4_cap_screw);
insert_foot = Foot(20, 10, 0, 2, M3_cap_screw);
function foot() = foot; //! Default foot used unless a list of parameters is passed
function insert_foot() = insert_foot; //! Default foot with insert
function foot_diameter(type = foot) = type[0]; //! Outside maximum diameter
@@ -58,7 +58,7 @@ module foot(type = foot) { //! Generate STL
circle4n(r);
}
}
linear_extrude(height = t)
linear_extrude(t)
difference() {
circle(r1 + eps);
@@ -67,7 +67,7 @@ module foot(type = foot) { //! Generate STL
}
}
module foot_assembly(t = 0, type = foot) { //! Assembly with fasteners in place for specified sheet thickness
module foot_assembly(t = 0, type = foot, flip = false) { //! Assembly with fasteners in place for specified sheet thickness
screw = foot_screw(type);
washer = screw_washer(screw);
nut = screw_nut(screw);
@@ -75,16 +75,22 @@ module foot_assembly(t = 0, type = foot) { //! Assembly with fasteners in place
screw_length = screw_longer_than(foot_thickness(type) + t + 2 * washer_thickness(washer) + nut_thickness(nut, true) - squeeze);
vflip() explode(15, true) {
color(pp4_colour) foot(type);
stl_colour(pp4_colour) foot(type);
if(t)
explode(15, true)
translate_z(foot_thickness(type))
screw_and_washer(screw, screw_length);
if(flip)
nut_and_washer(nut, true);
else
screw_and_washer(screw, screw_length);
}
if(t)
translate_z(t)
nut_and_washer(nut, true);
if(flip)
screw_and_washer(screw, screw_length);
else
nut_and_washer(nut, true);
}
module insert_foot(type = insert_foot) { //! Generate STL for foot with insert
@@ -112,7 +118,7 @@ module insert_foot(type = insert_foot) { //! Generate STL for foot with insert
}
}
}
linear_extrude(height = h2 + eps)
linear_extrude(h2 + eps)
difference() {
circle(r5 + eps);
@@ -132,7 +138,7 @@ assembly("insert_foot") {
insert = screw_insert(screw);
vflip()
color(pp1_colour) insert_foot(type);
stl_colour(pp4_colour) insert_foot(type);
translate_z(-foot_thickness(type))
insert(insert);

View File

@@ -21,8 +21,7 @@
//! Printed handle that can be printed without needing support material due to its truncated teardrop profile.
//
include <../core.scad>
include <../vitamins/screws.scad>
include <../vitamins/inserts.scad>
use <../vitamins/insert.scad>
dia = 18;
length = 90; // inside length
@@ -84,7 +83,7 @@ module handle_stl() { //! generate the STL
module handle_assembly() pose([225, 0, 150], [0, 0, 14]) //! Printed part with inserts in place
assembly("handle") {
translate_z(handle_height())
color(pp1_colour) vflip() handle_stl();
stl_colour(pp1_colour) vflip() handle_stl();
handle_screw_positions()
vflip()

123
printed/pcb_mount.scad Normal file
View File

@@ -0,0 +1,123 @@
//
// 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/>.
//
//
//! A frame to mount a PCB by its corners when it has no mounting holes.
//! The stl must be given a parameterless wrapper in the project that uses it.
//
include <../core.scad>
use <../vitamins/pcb.scad>
clearance = 0.2;
min_wall = extrusion_width * 2;
wall = 2;
overlap = 2;
screw = M3_cap_screw;
screw_clearance_r = 3.1 / 2;
pillar_r = corrected_radius(screw_clearance_r) + wall;
function pillar_x_pitch(pcb) = pcb_length(pcb) + 2 * clearance + 2 * (pillar_r - overlap) / sqrt(2); //! x pitch of screw pillars
function pillar_y_pitch(pcb) = pcb_width(pcb) + 2 * clearance + 2 * (pillar_r - overlap) / sqrt(2); //! y pitch of screw pillars
function pcb_mount_length(pcb) = pillar_x_pitch(pcb) + 2 * pillar_r; //! Outside length of the mount
function pcb_mount_width(pcb) = pillar_y_pitch(pcb) + 2 * pillar_r; //! Outside width of the mount
frame_w = 3;
frame_t = 2;
washer_thickness = 1.25;
module pcb_mount_screw_positions(pcb) //! Positions of the screws and pillars
for(x = [-1, 1], y = [-1, 1])
translate([x * pillar_x_pitch(pcb) / 2, y * pillar_y_pitch(pcb) / 2])
children();
module pcb_mount_holes(pcb, h = 0) //! Drill holes for PCB mount
pcb_mount_screw_positions(pcb)
drill(screw_clearance_radius(screw), h);
module pcb_mount_ring()
difference() {
circle(pillar_r);
poly_circle(screw_clearance_r);
}
module pcb_mount_washer_stl() //! A plastic washer to clamp a PCB
linear_extrude(washer_thickness)
pcb_mount_ring();
module pcb_mount(pcb, height = 5, washers = true) { //! Make the STL of a pcb mount for the specified PCB.
stl(str("pcb_mount_", pcb[0], "_", height));
y_pitch = pcb_width(pcb) > 4 * pillar_r + 4 ? pillar_r + 1
: pcb_width(pcb) / 2 + frame_w + 1 + pillar_r;
if(washers)
for(x = [-1, 1], y = [-1, 1])
translate([x * (pillar_r + 1), y * y_pitch, 0])
pcb_mount_washer_stl();
for(x = [-1, 1])
translate([x * pillar_x_pitch(pcb) / 2, 0, frame_t / 2])
cube([frame_w, pillar_y_pitch(pcb) - 2 * wall, frame_t], center = true);
for(y = [-1, 1])
translate([0, y * pillar_y_pitch(pcb) / 2, frame_t / 2])
cube([pillar_x_pitch(pcb) - 2 * wall, frame_w, frame_t], center = true);
pcb_mount_screw_positions(pcb)
linear_extrude(height)
pcb_mount_ring();
linear_extrude(height + pcb_thickness(pcb) - layer_height)
difference() {
pcb_mount_screw_positions(pcb)
pcb_mount_ring();
square([pcb_length(pcb) + 2 * clearance, pcb_width(pcb) + 2 * clearance], center = true);
}
}
module pcb_mount_assembly(pcb, thickness, height = 5) { //! A PCB mount assembly with fasteners
translate_z(height)
pcb(pcb);
stl_colour(pp1_colour) pcb_mount(pcb, washers = false);
washer = screw_washer(screw);
nut = screw_nut(screw);
t = pcb_thickness(pcb);
screw_length = screw_longer_than(height + t + washer_thickness + thickness + washer_thickness(washer) + nut_thickness(nut, true));
pcb_mount_screw_positions(pcb) {
translate_z(height + t) {
stl_colour(pp2_colour) pcb_mount_washer_stl();
translate_z(washer_thickness)
screw(screw, screw_length);
}
translate_z(-thickness)
vflip()
nut_and_washer(nut, true);
}
}

235
printed/printed_box.scad Normal file
View File

@@ -0,0 +1,235 @@
//
// 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/>.
//
//
//! A fully parametric 3D printed case that can be customised with cutouts and additions specified by children.
//!
//! The walls can be made wavy, which possibly reduces warping when printing and looks nice, however if holes need to be made
//! in the sides you can't print a wavy bridge. Any holes need to be surrounded by a 45&deg; chamfer to make the bridges straight.
//! See the mounting points for the feet in the first example.
//!
//! It can also have printed feet on the base with the screws doubling up to hold the base on.
//
include <../core.scad>
use <../vitamins/insert.scad>
use <foot.scad>
function pbox(name, wall, top_t, base_t, radius, size, foot = false, screw = false, ridges = [0, 0]) //! Construct a printed box property list
= concat([name, wall, top_t, base_t, foot, screw, radius, ridges], size);
function pbox_name(type) = type[0]; //! Name to allow more than one box in a project
function pbox_wall(type) = type[1]; //! Wall thickness
function pbox_top(type) = type[2]; //! Top thickness
function pbox_base(type) = type[3]; //! Base thickness, can be zero for no base
function pbox_foot(type) = type[4]; //! Printed foot, can be false to suppress feet
function pbox_base_screw(type) = type[5]; //! Screw type if no feet
function pbox_radius(type) = type[6]; //! Internal corner radius
function pbox_ridges(type) = type[7]; //! Ridge wavelength and amplitude
function pbox_width(type) = type[8]; //! Internal width
function pbox_depth(type) = type[9]; //! Internal depth
function pbox_height(type) = type[10]; //! Internal height
base_outset = 1; // How much the base overlaps the inner dimensions
base_overlap = 2; // The width of ledge the base sits on
height_overlap = 1; // How far the edges sit below the base
function pbox_inclusion(type) = pbox_base(type) ? base_overlap - base_outset : 0; //! How far the ledge for the base extends inwards
function pbox_total_height(type) = //! Total height including base overlap
let(base = pbox_base(type),
foot = pbox_foot(type),
washer = pbox_washer(type),
screw = pbox_screw(type))
pbox_height(type) + pbox_top(type) + base + (base ? height_overlap : 0) + (foot || !base ? 0 : washer_thickness(washer) + screw_head_height(screw));
function pbox_screw(type) = //! Foot screw if got feet else base_screw
let(foot = pbox_foot(type)) foot ? foot_screw(foot) : pbox_base_screw(type);
function pbox_insert(type) = screw_insert(pbox_screw(type)); //! The insert for the base screws
function pbox_washer(type) = screw_washer(pbox_screw(type)); //! The washer for the base screws
function pbox_screw_length(type, panel_thickness = 0) = //! Length of the base screw
let(foot = pbox_foot(type))
screw_shorter_than(pbox_base(type) + washer_thickness(pbox_washer(type))
+ insert_length(pbox_insert(type))
+ (foot ? foot_thickness(foot) : panel_thickness));
function pbox_mid_offset(type) = pbox_ridges(type).y + pbox_wall(type) / 2; // Offset to wall midpoint
function pbox_screw_inset(type) = //! How far the base screws are inset
let(foot = pbox_foot(type),
r = foot ? foot_diameter(foot) / 2 : pbox_base(type) ? washer_radius(pbox_washer(type)) : insert_hole_radius(pbox_insert(type)),
R = pbox_radius(type)
) max(r, R - (R - r) / sqrt(2));
module pbox_screw_positions(type) { //! Place children at base screw positions
foot = pbox_foot(type);
inset = pbox_screw_inset(type);
for(x = [-1, 1], y = [-1, 1])
translate([x * (pbox_width(type) / 2 - inset), y * (pbox_depth(type) / 2 - inset)])
rotate((y > 0 ? -x * 45 : -x * 135) + 90)
children();
}
module pbox_mid_shape(type) {
ridges = pbox_ridges(type);
offset = ridges.y + pbox_wall(type) / 2;
rad = pbox_radius(type) + offset;
w = pbox_width(type) + 2 * offset;
d = pbox_depth(type) + 2 * offset;
module waves(length) {
l = length - 2 * rad;
waves = round(l / ridges.x);
points = 16;
translate([-l / 2, ridges.y / 2])
polygon(concat([[0, -10]], [for(i = [0 : waves * points], a = 360 * i / points) [i * l / waves / points, -cos(a) * ridges.y / 2] ], [[l, -10]]));
}
difference() {
rounded_square([w, d], rad, center = true);
if(ridges.y)
for(side = [-1, 1]) {
translate([0, side * d / 2])
rotate(90 + side * 90)
waves(w);
translate([side * w / 2, 0])
rotate(side * 90)
waves(d);
}
}
}
module pbox_inner_shape(type) {
rad = pbox_radius(type);
w = pbox_width(type);
d = pbox_depth(type);
rounded_square([w, d], rad, center = true);
}
module pbox_outer_shape(type) //! 2D outer shape of the box
offset(pbox_wall(type) / 2) pbox_mid_shape(type);
module pbox_base(type) { //! Generate the STL for the base
stl(str(pbox_name(type),"_base"));
t = pbox_base(type);
difference() {
union() {
linear_extrude(t)
offset(base_outset - 0.2)
pbox_inner_shape(type);
if($children > 0)
children(0);
}
pbox_screw_positions(type)
poly_cylinder(r = screw_clearance_radius(pbox_screw(type)), h = 2 * t + eps, center = true);
if($children > 1)
children(1);
}
}
module pbox(type) { //! Generate the STL for the main case
stl(pbox_name(type));
height = pbox_height(type);
total_height = pbox_total_height(type);
top_thickness = pbox_top(type);
wall = pbox_wall(type);
ledge_outset = pbox_ridges(type).y;
ledge_inset = base_outset - base_overlap;
ledge_h = pbox_base(type) ? (ledge_outset - ledge_inset) * 2 : 0;
difference() {
union() {
linear_extrude(total_height)
pbox_outer_shape(type);
if($children > 2)
children(2);
}
difference() {
translate_z(top_thickness)
union() {
linear_extrude(height + eps)
offset(-wall / 2) pbox_mid_shape(type);
translate_z(height) // Recess for the base
linear_extrude(total_height - height)
offset(base_outset)
pbox_inner_shape(type);
}
// Ledge to support the lid
if(ledge_h)
translate_z(top_thickness + height - ledge_h)
difference() {
rounded_rectangle([pbox_width(type) + 2 * outset, pbox_depth(type) + 2 * outset, ledge_h], 1, center = false);
hull() {
linear_extrude(ledge_h + eps)
offset(ledge_inset)
pbox_inner_shape(type);
linear_extrude(eps)
offset(ledge_outset)
pbox_inner_shape(type);
}
pbox_screw_positions(type)
insert_hole(pbox_insert(type));
}
// Corner lugs for inserts
outset = wall + pbox_ridges(type).y;
or = pbox_radius(type) + outset;
inset = pbox_screw_inset(type) + outset;
br = insert_boss_radius(pbox_insert(type), wall);
ext = sqrt(2) * inset - or * (sqrt(2) - 1) - br;
translate_z(height + top_thickness)
pbox_screw_positions(type)
insert_lug(pbox_insert(type), wall, counter_bore = 0, extension = ext, corner_r = or);
if($children > 0)
children(0);
}
if($children > 1)
children(1);
}
}
module pbox_inserts(type) //! Place the inserts for the base screws
translate_z(pbox_height(type) + pbox_top(type))
pbox_screw_positions(type)
insert(pbox_insert(type));
module pbox_base_screws(type, thickness = 0) //! Place the screws and feet
translate_z(pbox_height(type) + pbox_top(type) + pbox_base(type))
pbox_screw_positions(type) {
foot = pbox_foot(type);
if(foot)
stl_colour(pp4_colour)
foot(foot);
translate_z(foot ? foot_thickness(foot) : thickness)
screw_and_washer(pbox_screw(type), pbox_screw_length(type, thickness));
}

171
printed/psu_shroud.scad Normal file
View File

@@ -0,0 +1,171 @@
//
// NopSCADlib Copyright Chris Palmer 2018
// 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/>.
//
//
//! A cover to go over the mains end of a PSU terminal strip to make it safe.
//! The stl and assembly must be given a name and parameterless wrappers for the stl and assembly added to the project.
//
include <../core.scad>
use <../vitamins/insert.scad>
use <../vitamins/wire.scad>
use <../vitamins/psu.scad>
use <../utils/round.scad>
wall = 1.8;
top = 1.5;
screw = M3_cap_screw;
insert = screw_insert(screw);
boss_r = insert_boss_radius(insert, wall);
counter_bore = 2;
rad = 2;
clearance = layer_height;
overlap = 6;
cable_tie_inset = wall + 4;
function psu_shroud_extent(type) = 15 + wall; //! How far it extends beyond the PSU to clear the connections
function psu_shroud_depth(type) = //! Outside depth of the shroud
psu_left_bay(type) + overlap + psu_shroud_extent(type);
function psu_shroud_width(type) = //! Outside width of the shroud
let(terminals = psu_terminals(type))
terminals ?
let(y = terminals.y, tb = terminals.z)
wall + clearance / 2 + y + 3 * terminal_block_pitch(tb) + terminal_block_divider(tb) / 2 + wall / 2
: psu_width(type) + 2 * wall + clearance;
function psu_shroud_height(type) = psu_height(type) + top + clearance; //! Outside height
function psu_shroud_centre_y(type) = //! Shroud centre relative to PSU centre
psu_width(type) / 2 + clearance / 2 + wall - psu_shroud_width(type) / 2;
function psu_shroud_pitch(type) = psu_shroud_width(type) - 2 * boss_r - eps;
function psu_shroud_screw(type) = screw; //! Screw used to fasten
function psu_shroud_cable_pitch(cable_d) = cable_d + 5; //! Pitch between cable entries
module psu_shroud_hole_positions(type) //! Place children at the screw hole positions
for($side = [-1, 1])
translate([-psu_length(type) / 2 - boss_r - 1, psu_shroud_centre_y(type) + $side * psu_shroud_pitch(type) / 2])
children();
module psu_shroud_cable_positions(type, cable_d, cables = 1) //! Place children at the cable tie positions
for(i = [0 : 1 : cables - 1])
translate([-psu_length(type) / 2 - psu_shroud_extent(type) + cable_tie_inset,
psu_shroud_centre_y(type) + (i - cables / 2 + 0.5) * psu_shroud_cable_pitch(cable_d)])
children();
module psu_shroud_holes(type, cable_d, cables = 1) { //! Drill the screw and ziptie holes
psu_shroud_hole_positions(type)
drill(screw_clearance_radius(screw), 0);
psu_shroud_cable_positions(type, cable_d, cables)
cable_tie_holes(cable_d / 2, h = 0);
}
module psu_shroud(type, cable_d, name, cables = 1) { //! Generate the STL file for a specified ssr and cable
stl(str("psu_shroud_", name));
extent = psu_shroud_extent(type);
depth = psu_shroud_depth(type);
width = psu_shroud_width(type);
height = psu_shroud_height(type);
centre_x = -psu_length(type) / 2 - psu_shroud_extent(type) + psu_shroud_depth(type) / 2;
centre_y = psu_shroud_centre_y(type);
terminal_clearance = 0.5;
tb = psu_terminals(type).z;
module shape() {
difference() {
round(or = wall / 2 - eps, ir = 0) difference() {
rounded_square([depth, width], rad);
rounded_square([depth - 2 * wall, width - 2 * wall], rad - wall);
translate([depth / 2, 0])
square([2 * rad, width], center = true);
translate([depth / 2, width / 2 - 5])
square([2 * (overlap + terminal_clearance), 10], center = true);
}
for(i = [0 : 1 : cables - 1])
translate([0, (i - cables / 2 + 0.5) * psu_shroud_cable_pitch(cable_d)])
square([depth + 1, cable_d], center = true);
}
}
// base and sides
translate([centre_x, -centre_y]) {
rounded_rectangle([depth - eps, width - eps, top], rad, center = false);
linear_extrude(height)
difference() {
shape();
translate([depth / 2, width / 2 - 5])
square([2 * (depth - extent + terminal_clearance), 10], center = true);
}
linear_extrude(height - terminal_block_height(tb) - psu_terminal_block_z(type) - terminal_clearance)
shape();
}
// cable slots
for(i = [0 : 1 : cables - 1])
translate([centre_x - depth / 2 + wall / 2, -centre_y + (i - cables / 2 + 0.5) * psu_shroud_cable_pitch(cable_d), height / 2])
rotate([90, 0, 90])
linear_extrude(wall, center = true)
difference() {
square([cable_d + eps, height], center = true);
translate([0, height / 2])
vertical_tearslot(h = 0, r = cable_d / 2, l = cable_d);
}
// insert lugs
mirror([0, 1, 0])
psu_shroud_hole_positions(type)
translate_z(height)
rotate($side * 90)
insert_lug(insert, wall, counter_bore);
}
module psu_shroud_assembly(type, cable_d, name, cables = 1) //! The printed parts with inserts fitted
assembly(str("PSU_shroud_", name)) {
translate_z(psu_shroud_height(type))
vflip()
stl_colour(pp1_colour) psu_shroud(type, cable_d, name, cables);
psu_shroud_hole_positions(type)
vflip()
insert(insert);
}
module psu_shroud_fastened_assembly(type, cable_d, thickness, name, cables = 1) //! Assembly with screws in place
{
washer = screw_washer(screw);
screw_length = screw_shorter_than(2 * washer_thickness(washer) + thickness + insert_length(insert) + counter_bore);
psu_shroud_assembly(type, cable_d, name, cables);
translate_z(-thickness)
psu_shroud_hole_positions(type)
vflip()
screw_and_washer(screw, screw_length, true);
psu_shroud_cable_positions(type, cable_d, cables)
cable_tie(cable_d / 2, thickness);
}

View File

@@ -21,8 +21,7 @@
//! Clamp for ribbon cable and polypropylene strip.
//
include <../core.scad>
include <../vitamins/screws.scad>
include <../vitamins/inserts.scad>
use <../vitamins/insert.scad>
use <../vitamins/cable_strip.scad>
wall = 2;
@@ -32,7 +31,7 @@ insert = screw_insert(screw);
screw_depth = insert_length(insert) + 1;
function ribbon_clamp_hole_pitch(ways) = ribbon_clamp_slot(ways) + 2 * min_wall + 2 * corrected_radius(insert_hole_radius(insert)); //! Hole pitch
function ribbon_clamp_width() = 2 * (insert_hole_radius(insert) + 2); //! Width
function ribbon_clamp_width() = 2 * (insert_hole_radius(insert) + wall); //! Width
function ribbon_clamp_length(ways) = ribbon_clamp_hole_pitch(ways) + ribbon_clamp_width(); //! Length given ways
function ribbon_clamp_height() = screw_depth + 1; //! Height
@@ -84,7 +83,7 @@ module ribbon_clamp_assembly(ways) pose([55, 180, 25]) //! Printed part with in
assembly(str("ribbon_clamp_", ways)) {
h = ribbon_clamp_height();
color(pp1_colour) render()
stl_colour(pp1_colour) render()
translate_z(h) vflip() ribbon_clamp(ways);
ribbon_clamp_hole_positions(ways)

View File

@@ -21,7 +21,6 @@
//! Knob with embedded hex head screw.
//
include <../core.scad>
include <../vitamins/screws.scad>
use <../utils/hanging_hole.scad>
knob_wall = 2;
@@ -30,11 +29,11 @@ knob_stem_h = 6;
knob_thickness = 4;
knob_r = 8;
knob_wave = 1;
knob_waves = 9;
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;
@@ -49,7 +48,7 @@ module screw_knob(screw) { //! Generate the STL foe a knob to fit the specified
rotate(45)
circle(r = nut_trap_radius(screw_nut(screw)), $fn = 6);
}
linear_extrude(height = knob_thickness, convexity = 3)
linear_extrude(knob_thickness, convexity = 3)
difference() {
polygon(points = [for(a = [0 : 359]) [wave(a) * sin(a), wave(a) * cos(a)]]);
@@ -63,7 +62,7 @@ module screw_knob_assembly(screw, length) //! Assembly with the screw in place
assembly(str("screw_knob_M", 20 * screw_radius(screw), "_", length)) {
translate_z(knob_height)
vflip()
color(pp1_colour) screw_knob(screw);
stl_colour(pp1_colour) screw_knob(screw);
translate_z(knob_height - knob_nut_trap_depth(screw))
rotate(-45)
@@ -73,5 +72,8 @@ assembly(str("screw_knob_M", 20 * screw_radius(screw), "_", length)) {
module screw_knob_M30_stl() screw_knob(M3_hex_screw);
module screw_knob_M40_stl() screw_knob(M4_hex_screw);
//! * Press the M3 x 16 hex screw into the knob
module screw_knob_M30_16_assembly() screw_knob_assembly(M3_hex_screw, 16);
//! * Press the M4 x 16 hex screw into the knob
module screw_knob_M40_16_assembly() screw_knob_assembly(M4_hex_screw, 16);

View File

@@ -22,9 +22,8 @@
//
include <../core.scad>
include <../vitamins/mains_sockets.scad>
include <../vitamins/screws.scad>
include <../vitamins/inserts.scad>
include <../vitamins/ring_terminals.scad>
use <../vitamins/insert.scad>
box_height = 19;
base_thickness = 2;
@@ -53,12 +52,12 @@ module socket_box(type) { //! Generate STL of the backbox for the specified sock
insert_hole_radius = insert_hole_radius(insert);
difference() {
linear_extrude(height = height, convexity = 5)
linear_extrude(height, convexity = 5)
face_plate(type);
difference() {
translate_z(base_thickness)
linear_extrude(height = height, convexity = 5)
linear_extrude(height, convexity = 5)
offset(-wall) offset(1) face_plate(type);
for(side = [-1, 1])
@@ -93,7 +92,7 @@ assembly(str("socket_box_", type[0])) {
screw = mains_socket_screw(type);
insert = screw_insert(screw);
color("lime") render() socket_box(type);
stl_colour(pp1_colour) render() socket_box(type);
mains_socket_hole_positions(type)
translate_z(height)

View File

@@ -19,23 +19,21 @@
//
//! A cover to go over the mains end of an SSR to make it safe to be touched.
//! The stl and assembly must be given a name and parameterless wrappers for the stl and assembly added to the project.
//! The STL and assembly must be given a name and parameterless wrappers for the stl and assembly added to the project.
//
include <../core.scad>
include <../vitamins/screws.scad>
include <../vitamins/inserts.scad>
use <../vitamins/insert.scad>
use <../vitamins/wire.scad>
use <../vitamins/ssr.scad>
use <../utils/round.scad>
wall = 1.8;
top = 1.5;
screw = M3_cap_screw;
screw_length = 10;
insert = screw_insert(screw);
boss_r = wall + corrected_radius(insert_hole_radius(insert));
boss_h = insert_hole_length(insert);
boss_r = insert_boss_radius(insert, wall);
counter_bore = 2;
boss_h2 = boss_h + counter_bore;
rad = 3;
clearance = layer_height;
@@ -44,6 +42,7 @@ function ssr_shroud_screw(type) = screw; //!
function ssr_shroud_extent(type, cable_d) = 2 * boss_r + 1 + cable_d + rad; //! How far it extends beyond the SSR
function ssr_shroud_width(type) = ssr_width(type) + 2 * wall + clearance; //! Outside width of shroud
function ssr_shroud_height(type) = ssr_height(type) + top + clearance; //! Outside height
function ssr_shroud_cable_x(type, cable_d) = -ssr_length(type) / 2 - 2 * boss_r - 1 - cable_d / 2; //! Position of cable entry holes
module ssr_shroud_hole_positions(type) //! Place children at the screw hole positions
for($side = [-1, 1])
@@ -51,23 +50,30 @@ module ssr_shroud_hole_positions(type) //!
vflip()
children();
module ssr_shroud_holes(type) //: Drill the screw holes
module ssr_shroud_holes(type, cable_d) { //! Drill the screw and ziptie holes
ssr_shroud_hole_positions(type)
drill(screw_clearance_radius(screw), 0);
for(side = [-1, 1])
translate([ssr_shroud_cable_x(type, cable_d), side * (ssr_width(type) / 2 - 2 * boss_r)])
rotate(-90)
cable_tie_holes(cable_d / 2, h = 0);
}
module ssr_shroud(type, cable_d, name) { //! Generate the STL file for a specified ssr and cable
stl(str("ssr_shroud_", name));
width = ssr_shroud_width(type);
depth = ssr_length(type) / 3 + ssr_shroud_extent(type, cable_d);
height = ssr_shroud_height(type);
cable_x = -ssr_length(type) / 2 - 2 * boss_r - 1 - cable_d / 2;
cable_x = ssr_shroud_cable_x(type, cable_d);
center_x = -ssr_length(type) / 6 - depth / 2;
// base and sides
translate([center_x, 0]) {
rounded_rectangle([depth - eps, width - eps, top], rad, center = false);
linear_extrude(height = height) difference() {
linear_extrude(height) difference() {
round(or = wall / 2 - eps, ir = 0) difference() {
rounded_square([depth, width], rad);
@@ -81,74 +87,55 @@ module ssr_shroud(type, cable_d, name) { //! Generate the STL file for a spec
square([cable_d, width + 1], center = true);
}
}
// cable slots
for(side = [-1, 1])
translate([cable_x, side * (width / 2 - wall / 2), height / 2])
rotate([90, 0, 0])
linear_extrude(height = wall, center = true)
linear_extrude(wall, center = true)
difference() {
square([cable_d + eps, height], center = true);
translate([0, height / 2])
vertical_tearslot(h = 0, r = cable_d / 2, l = cable_d);
}
translate_z(height - boss_h)
linear_extrude(height = boss_h)
ssr_shroud_hole_positions(type)
difference() {
hull() {
circle(boss_r);
translate([0, -$side * (boss_r - 1)])
square([2 * boss_r, eps], center = true);
}
poly_circle(insert_hole_radius(insert));
}
translate_z(height - boss_h2)
linear_extrude(height = counter_bore + eps)
ssr_shroud_hole_positions(type)
difference() {
hull() {
circle(boss_r);
translate([0, -$side * (boss_r - 1)])
square([2 * boss_r, eps], center = true);
}
poly_circle(insert_screw_diameter(insert) / 2 + 0.1);
}
// insert boss
ssr_shroud_hole_positions(type)
hull() {
translate_z(-height + boss_h2) {
cylinder(h = eps, r = boss_r - eps);
translate([0, -$side * (boss_r - 1)])
cube([2 * boss_r, eps, eps], center = true);
}
translate([0, -$side * (boss_r - wall), -height + boss_h2 + (2 * boss_r - wall)])
cube(eps);
}
vflip()
translate_z(height)
rotate($side * 90)
insert_lug(insert, wall, counter_bore);
}
module ssr_shroud_assembly(type, cable_d, name) //! The printed parts with inserts fitted
assembly(str("ssr_shroud_", name)) {
assembly(str("SSR_shroud_", name)) {
translate_z(ssr_height(type) + top)
translate_z(ssr_shroud_height(type))
vflip()
color(pp1_colour) ssr_shroud(type, cable_d, name);
stl_colour(pp1_colour) ssr_shroud(type, cable_d, name);
ssr_shroud_hole_positions(type)
insert(insert);
}
module ssr_shroud_fastened_assembly(type, cable_d, thickness, name) //! Assembly with screws in place
{
washer = screw_washer(screw);
screw_length = screw_shorter_than(2 * washer_thickness(washer) + thickness + insert_length(insert) + counter_bore);
ssr_shroud_assembly(type, cable_d, name);
translate_z(-thickness)
ssr_shroud_hole_positions(type)
screw_and_washer(screw, screw_length, true);
for(side = [-1, 1])
translate([ssr_shroud_cable_x(type, cable_d), side * (ssr_width(type) / 2 - 2 * boss_r)]) {
rotate(-90)
cable_tie(cable_d / 2, thickness);
*translate_z(cable_d / 2)
rotate([90, 0, 0])
stl_colour(grey(20))
cylinder(d = cable_d, h = 20, center = true);
}
}

View File

@@ -22,11 +22,9 @@
//! be fully customised by passing a list of properties.
//
include <../core.scad>
include <../vitamins/screws.scad>
include <../vitamins/inserts.scad>
use <../vitamins/insert.scad>
strap = [18, 2, M3_pan_screw, 3, 25];
function strap() = strap;
strap = strap();
wall = 2;
clearance = 0.5;
@@ -41,6 +39,10 @@ function strap_screw(type = strap) = type[2]; //! Screw type
function strap_panel(type = strap) = type[3]; //! Panel thickness
function strap_extension(type = strap) = type[4]; //! How much length of the strap that can pull out
function strap(width = 18, thickness = 2, screw = M3_pan_screw, panel_thickness = 3, extension = 25) = //! Construct a property list for a strap
[ width, thickness, screw, panel_thickness, extension ];
function strap_insert(type) = screw_insert(strap_screw(type)); //! The insert type
function strap_key(type) = strap_panel(type) - panel_clearance;
function strap_height(type) = wall + max(insert_length(strap_insert(type)) - strap_key(type), strap_thickness(type) + clearance); //! Height of the ends
@@ -78,7 +80,7 @@ module strap(length, type = strap) { //! Generate the STL for the rubber strap
len = length - 2 * (wall + clearance);
w = strap_width(type);
linear_extrude(height = strap_thickness(type), convexity = 3)
linear_extrude(strap_thickness(type), convexity = 3)
difference() {
rounded_square([len, w], w / 2 - eps);
@@ -120,12 +122,12 @@ module strap_end(type = strap) { //! Generate the STL for end piece
}
union() {
linear_extrude(height = z1)
linear_extrude(z1)
with_hole()
outer();
translate_z(z1)
linear_extrude(height = strap_height(type) - z1)
linear_extrude(strap_height(type) - z1)
difference() {
outer();
@@ -138,11 +140,11 @@ module strap_end(type = strap) { //! Generate the STL for end piece
}
}
linear_extrude(height = strap_height(type) - layer_height)
linear_extrude(strap_height(type) - layer_height)
with_hole()
strap_boss_shape(type);
linear_extrude(height = z2)
linear_extrude(z2)
with_hole()
offset(cnc_bit_r)
offset(-step - cnc_bit_r)
@@ -161,7 +163,7 @@ module strap_end(type = strap) { //! Generate the STL for end piece
//
module strap_end_assembly(type = strap)
assembly("strap_end") {
color(pp1_colour)
stl_colour(pp1_colour)
strap_end(type);
translate_z(strap_height(type) + strap_key(type))
@@ -176,7 +178,7 @@ module strap_assembly(length, type = strap) { //! Assembly with screws in place
screw_length = screw_shorter_than(washer_thickness(washer) + washer_thickness(penny) + insert_length(insert) + panel_clearance + counterbore);
color(pp4_colour) strap(length, type);
stl_colour(pp4_colour) strap(length, type);
strap_screw_positions(length, type)
translate_z(strap_height(type))

2357
readme.md

File diff suppressed because it is too large Load Diff

173
scripts/bom.py Normal file → Executable file
View File

@@ -29,6 +29,7 @@ import openscad
from time import *
from set_config import *
import json
import re
def find_scad_file(mname):
for filename in os.listdir(source_dir):
@@ -45,9 +46,20 @@ def find_scad_file(mname):
return filename
return None
class Part:
def __init__(self, args):
self.count = 1
for arg in args:
arg = arg.replace('true', 'True').replace('false', 'False').replace('undef', 'None')
exec('self.' + arg)
def data(self):
return self.__dict__
class BOM:
def __init__(self, name):
self.name = name
self.big = None
self.count = 1
self.vitamins = {}
self.printed = {}
@@ -60,14 +72,20 @@ class BOM:
assemblies[ass] = self.assemblies[ass].count
return {
"name" : self.name,
"big" : self.big,
"count" : self.count,
"assemblies" : assemblies,
"vitamins" : self.vitamins,
"printed" : self.printed,
"routed" : self.routed
"vitamins" : {v : self.vitamins[v].data() for v in self.vitamins},
"printed" : {p : self.printed[p].data() for p in self.printed},
"routed" : {r : self.routed[r].data() for r in self.routed}
}
def add_part(self, s):
args = []
match = re.match(r'^(.*?\.stl|.*?\.dxf)\((.*)\)$', s) #look for name.stl(...) or name.dxf(...)
if match:
s = match.group(1)
args = [match.group(2)]
if s[-4:] == ".stl":
parts = self.printed
else:
@@ -76,15 +94,19 @@ class BOM:
else:
parts = self.vitamins
if s in parts:
parts[s] += 1
parts[s].count += 1
else:
parts[s] = 1
parts[s] = Part(args)
def add_assembly(self, ass):
def add_assembly(self, ass, args = []):
if ass in self.assemblies:
self.assemblies[ass].count += 1
else:
self.assemblies[ass] = BOM(ass)
bom = BOM(ass)
for arg in args:
arg = arg.replace('true', 'True').replace('false', 'False').replace('undef', 'None')
exec('bom.' + arg, locals())
self.assemblies[ass] = bom
def make_name(self, ass):
if self.count == 1:
@@ -119,10 +141,10 @@ class BOM:
for ass in sorted(self.assemblies):
bom = self.assemblies[ass]
if part in bom.vitamins:
file.write("%2d|" % bom.vitamins[part])
file.write("%2d|" % bom.vitamins[part].count)
else:
file.write(" |")
print("%3d" % self.vitamins[part], description, file=file)
print("%3d" % self.vitamins[part].count, description, file=file)
if self.printed:
if self.vitamins:
@@ -133,10 +155,10 @@ class BOM:
for ass in sorted(self.assemblies):
bom = self.assemblies[ass]
if part in bom.printed:
file.write("%2d|" % bom.printed[part])
file.write("%2d|" % bom.printed[part].count)
else:
file.write(" |")
print("%3d" % self.printed[part], part, file=file)
print("%3d" % self.printed[part].count, part, file=file)
if self.routed:
print(file=file)
@@ -146,10 +168,10 @@ class BOM:
for ass in sorted(self.assemblies):
bom = self.assemblies[ass]
if part in bom.routed:
file.write("%2d|" % bom.routed[part])
file.write("%2d|" % bom.routed[part].count)
else:
file.write(" |")
print("%3d" % self.routed[part], part, file=file)
print("%3d" % self.routed[part].count, part, file=file)
if self.assemblies:
print(file=file)
@@ -161,17 +183,22 @@ def parse_bom(file = "openscad.log", name = None):
main = BOM(name)
main.ordered_assemblies = []
stack = []
prog = re.compile(r'^(.*)\((.*)\)$')
for line in open(file):
pos = line.find('ECHO: "~')
if pos > -1:
s = line[pos + 8 : line.rfind('"')]
if s[-1] == '{':
ass = s[:-1]
args = []
match = prog.match(ass) #look for (...)
if match:
ass = match.group(1)
args = match.group(2).split(',')
if stack:
main.assemblies[stack[-1]].add_assembly(ass) #add to nested BOM
stack.append(ass)
main.add_assembly(ass) #add to flat BOM
main.add_assembly(ass, args) #add to flat BOM
if ass in main.ordered_assemblies:
main.ordered_assemblies.remove(ass)
main.ordered_assemblies.insert(0, ass)
@@ -184,63 +211,83 @@ def parse_bom(file = "openscad.log", name = None):
main.add_part(s)
if stack:
main.assemblies[stack[-1]].add_part(s)
else:
if 'ERROR:' in line or 'WARNING:' in line:
raise Exception(line[:-1])
return main
def usage():
print("\nusage:\n\tbom [target_config] [<accessory_name>_assembly] - Generate BOMs for a project or an accessory to a project.")
sys.exit(1)
def boms(target = None, assembly = None):
bom_dir = set_config(target) + "bom"
if assembly:
bom_dir += "/accessories"
if not os.path.isdir(bom_dir):
try:
bom_dir = set_config(target, usage) + "bom"
if assembly:
bom_dir += "/accessories"
if not os.path.isdir(bom_dir):
os.makedirs(bom_dir)
else:
assembly = "main_assembly"
if os.path.isdir(bom_dir):
shutil.rmtree(bom_dir)
sleep(0.1)
os.makedirs(bom_dir)
else:
assembly = "main_assembly"
if os.path.isdir(bom_dir):
shutil.rmtree(bom_dir)
sleep(0.1)
os.makedirs(bom_dir)
#
# Find the scad file that makes the module
#
scad_file = find_scad_file(assembly)
if not scad_file:
raise Exception("can't find source for " + assembly)
#
# make a file to use the module
#
bom_maker_name = source_dir + "/bom.scad"
with open(bom_maker_name, "w") as f:
f.write("use <%s>\n" % scad_file)
f.write("%s();\n" % assembly);
#
# Run openscad
#
openscad.run("-D","$bom=2","-D","$preview=true","-o", "openscad.echo", bom_maker_name)
os.remove(bom_maker_name)
print("Generating bom ...", end=" ")
#
# Find the scad file that makes the module
#
scad_file = find_scad_file(assembly)
if not scad_file:
raise Exception("can't find source for " + assembly)
#
# make a file to use the module
#
bom_maker_name = source_dir + "/bom.scad"
with open(bom_maker_name, "w") as f:
f.write("use <%s>\n" % scad_file)
f.write("%s();\n" % assembly);
#
# Run openscad
#
openscad.run("-D", "$bom=2", "-D", "$preview=true", "--hardwarnings", "-o", "openscad.echo", "-d", bom_dir + "/bom.deps", bom_maker_name)
os.remove(bom_maker_name)
print("Generating bom ...", end=" ")
main = parse_bom("openscad.echo", assembly)
main = parse_bom("openscad.echo", assembly)
if assembly == "main_assembly":
main.print_bom(True, open(bom_dir + "/bom.txt","wt"))
if assembly == "main_assembly":
main.print_bom(True, open(bom_dir + "/bom.txt","wt"))
for ass in main.assemblies:
with open(bom_dir + "/" + ass + ".txt", "wt") as f:
bom = main.assemblies[ass]
print(bom.make_name(ass) + ":", file=f)
bom.print_bom(False, f)
for ass in main.assemblies:
with open(bom_dir + "/" + ass + ".txt", "wt") as f:
bom = main.assemblies[ass]
print(bom.make_name(ass) + ":", file=f)
bom.print_bom(False, f)
data = [main.assemblies[ass].flat_data() for ass in main.ordered_assemblies]
with open(bom_dir + "/bom.json", 'w') as outfile:
json.dump(data, outfile, indent = 4)
data = [main.assemblies[ass].flat_data() for ass in main.ordered_assemblies]
with open(bom_dir + "/bom.json", 'w') as outfile:
json.dump(data, outfile, indent = 4)
print("done")
print("done")
except Exception as e:
print(str(e))
sys.exit(1)
if __name__ == '__main__':
args = len(sys.argv)
if args > 1:
if args > 2:
boms(sys.argv[1], sys.argv[2])
else:
boms(sys.argv[1])
if len(sys.argv) > 3: usage()
if len(sys.argv) == 3:
target, assembly = sys.argv[1], sys.argv[2]
else:
boms();
if len(sys.argv) == 2:
if sys.argv[1][-9:] == "_assembly":
target, assembly = None, sys.argv[1]
else:
target, assembly = sys.argv[1], None
else:
target, assembly = None, None
if assembly:
if assembly[-9:] != "_assembly": usage()
boms(target, assembly)

View File

@@ -113,5 +113,5 @@ if __name__ == '__main__':
if len(sys.argv) == 2:
canonicalise(sys.argv[1])
else:
print("usage: c14n_stl file")
print("\nusage:\n\t c14n_stl file - Canonicalise an STL file created by OpenSCAD.")
sys.exit(1)

View File

@@ -17,6 +17,7 @@
# If not, see <https://www.gnu.org/licenses/>.
#
import os
from set_config import source_dir
def mtime(file):
if os.path.isfile(file):
@@ -32,14 +33,15 @@ def read_deps(dname):
deps = []
for line in lines:
if line.startswith('\t'):
dep = line[1 : -1].rstrip(' \\')
dep = line[1 : -1].rstrip(' \\').replace('\\ ', ' ')
if not os.path.basename(dep) in ['stl.scad', 'dxf.scad', 'svf.scad', 'png.scad', 'target.scad']:
deps.append(dep)
return deps
def check_deps(target_mtime, dname):
def check_deps(target, dname):
target_mtime = mtime(target)
if not target_mtime:
return "target missing"
return target + " missing"
if not os.path.isfile(dname):
return "no deps"
deps = read_deps(dname)
@@ -47,3 +49,18 @@ def check_deps(target_mtime, dname):
if mtime(dep) > target_mtime:
return dep + ' changed'
return None
def source_dirs(bom_dir):
dirs = set()
lib_dirs = set()
deps = read_deps(bom_dir + '/bom.deps')
cwd = os.getcwd().replace('\\', '/')
for dep in deps:
dir = os.path.dirname(dep)
if dir.startswith(cwd):
dirs.add(dir[len(cwd) + 1:])
else:
if dir.endswith('/printed'):
lib_dirs.add(dir)
dirs.remove(source_dir)
return [source_dir] + sorted(dirs) + sorted(lib_dirs)

4
scripts/doc_scripts.py Normal file → Executable file
View File

@@ -26,6 +26,7 @@ from __future__ import print_function
import os
from tests import do_cmd
import argparse
dir = 'scripts'
@@ -40,7 +41,7 @@ These are located in the ```scripts``` subdirectory, which needs to be added to
They should work with both Python 2 and Python 3.
| Script | Function |
|:--|:--|''', file = doc_file)
|:---|:---|''', file = doc_file)
for file in os.listdir('scripts'):
if file.endswith('.py'):
blurb = ''
@@ -74,4 +75,5 @@ They should work with both Python 2 and Python 3.
if __name__ == '__main__':
argparse.ArgumentParser(description='Generate scripts/readme.md and make html versions of that and doc/usage.md').parse_args()
doc_scripts()

0
scripts/dxfs.py Normal file → Executable file
View File

View File

@@ -30,14 +30,14 @@ import times
from deps import *
import json
def bom_to_parts(target_dir, part_type, assembly = None):
def bom_to_parts(bom_dir, part_type, assembly = None):
#
# Make a list of all the parts in the BOM
#
part_files = []
bom = assembly + '.txt' if assembly else "bom.txt"
suffix = ".dxf" if part_type == 'svg' else '.' + part_type
with open(target_dir + "/../bom/" + bom, "rt") as f:
with open(bom_dir + '/' + bom, "rt") as f:
for line in f.readlines():
words = line.split()
if words:
@@ -46,13 +46,24 @@ def bom_to_parts(target_dir, part_type, assembly = None):
part_files.append(last_word[:-4] + '.' + part_type)
return part_files
def usage(t):
print("\nusage:\n\t%ss [target_config] [<name1>.%s] ... [<nameN>.%s] - Generate specified %s files or all if none specified." % ( t, t, t, t.upper()))
sys.exit(1)
def make_parts(target, part_type, parts = None):
#
# Check list of parts is the correct type
#
if parts:
for p in parts:
if not p.endswith('.' + part_type): usage(part_type)
#
# Make the target directory
#
top_dir = set_config(target)
top_dir = set_config(target, lambda: usage(part_type))
target_dir = top_dir + part_type + 's'
deps_dir = top_dir + "deps"
bom_dir = top_dir + "bom"
if not os.path.isdir(target_dir):
os.makedirs(target_dir)
if not os.path.isdir(deps_dir):
@@ -64,7 +75,7 @@ def make_parts(target, part_type, parts = None):
if parts:
targets = list(parts) #copy the list so we dont modify the list passed in
else:
targets = bom_to_parts(target_dir, part_type)
targets = bom_to_parts(bom_dir, part_type)
for file in os.listdir(target_dir):
if file.endswith('.' + part_type):
if not file in targets:
@@ -83,56 +94,49 @@ def make_parts(target, part_type, parts = None):
#
# Find all the scad files
#
lib_dir = os.environ['OPENSCADPATH'] + '/NopSCADlib/printed'
used = []
module_suffix = '_dxf' if part_type == 'svg' else '_' + part_type
for dir in [source_dir, lib_dir]:
for filename in os.listdir(dir):
if filename[-5:] == ".scad":
#
# find any modules ending in _<part_type>
#
with open(dir + "/" + filename, "r") as f:
for line in f.readlines():
words = line.split()
if(len(words) and words[0] == "module"):
module = words[1].split('(')[0]
if module.endswith(module_suffix):
base_name = module[:-4]
part = base_name + '.' + part_type
if part in targets:
#
# make a file to use the module
#
part_maker_name = part_type + ".scad"
with open(part_maker_name, "w") as f:
f.write("use <%s/%s>\n" % (dir, filename))
f.write("%s();\n" % module);
#
# Run openscad on the created file
#
part_file = target_dir + "/" + part
dname = deps_name(deps_dir, filename)
changed = check_deps(mtime(part_file), dname)
changed = times.check_have_time(changed, part)
if part_type == 'stl' and not changed and not part in bounds_map:
changed = "No bounds"
if changed:
print(changed)
t = time.time()
openscad.run("-D$bom=1", "-d", dname, "-o", part_file, part_maker_name)
times.add_time(part, t)
if part_type == 'stl':
bounds = c14n_stl.canonicalise(part_file)
bounds_map[part] = bounds
targets.remove(part)
os.remove(part_maker_name)
#
# Add the files on the BOM to the used list for plates.py
#
for line in open("openscad.log"):
if line[:7] == 'ECHO: "' and line[-6:] == '.' + part_type + '"\n':
used.append(line[7:-2])
for dir in source_dirs(bom_dir):
if targets and os.path.isdir(dir):
for filename in os.listdir(dir):
if targets and filename[-5:] == ".scad":
#
# find any modules ending in _<part_type>
#
with open(dir + "/" + filename, "r") as f:
for line in f.readlines():
words = line.split()
if(len(words) and words[0] == "module"):
module = words[1].split('(')[0]
if module.endswith(module_suffix):
base_name = module[:-4]
part = base_name + '.' + part_type
if part in targets:
#
# Run openscad on the created file
#
part_file = target_dir + "/" + part
dname = deps_name(deps_dir, filename)
changed = check_deps(part_file, dname)
changed = times.check_have_time(changed, part)
if part_type == 'stl' and not changed and not part in bounds_map:
changed = "No bounds"
if changed:
print(changed)
#
# make a file to use the module
#
part_maker_name = part_type + ".scad"
with open(part_maker_name, "w") as f:
f.write("use <%s/%s>\n" % (dir, filename))
f.write("%s();\n" % module);
t = time.time()
openscad.run("-D$bom=1", "-d", dname, "-o", part_file, part_maker_name)
times.add_time(part, t)
if part_type == 'stl':
bounds = c14n_stl.canonicalise(part_file)
bounds_map[part] = bounds
os.remove(part_maker_name)
targets.remove(part)
#
# Write new bounds file
#
@@ -144,10 +148,6 @@ def make_parts(target, part_type, parts = None):
#
if targets:
for part in targets:
if part[-4:] != '.' + part_type:
print(part, "is not a", part_type, "file")
else:
print("Could not find a module called", part[:-4] + module_suffix, "to make", part)
sys.exit(1)
print("Could not find a module called", part[:-4] + module_suffix, "to make", part)
usage(part_type)
times.print_times()
return used

8
scripts/gallery.py Normal file → Executable file
View File

@@ -30,6 +30,7 @@ import re
from shutil import copyfile
from tests import update_image
import sys
import argparse
project_dirs = ['../..', 'examples']
target_dir = 'gallery'
@@ -39,7 +40,6 @@ def gallery(force):
if not os.path.isdir(target_dir):
os.makedirs(target_dir)
paths = sorted([pdir + '/' + i for pdir in project_dirs for i in os.listdir(pdir) if os.path.isdir(pdir + '/' + i + '/assemblies')], key = lambda s: os.path.basename(s))
with open(output_name, 'wt') as output_file:
print("# A gallery of projects made with NopSCADlib", file = output_file)
@@ -78,4 +78,8 @@ def gallery(force):
if __name__ == '__main__':
init()
gallery(force = len(sys.argv) > 1 and sys.argv[1] == '-f')
parser = argparse.ArgumentParser(description='Creates a galley of projects by copying the top level image and description to gallery/readme.md.')
parser.add_argument("-f", help = "run make_all in each project to force update", action="store_true")
args = parser.parse_args()
gallery(force = args.f)

11
scripts/make_all.py Normal file → Executable file
View File

@@ -26,11 +26,22 @@ from exports import make_parts
from bom import boms
from render import render
from views import views
from plateup import plateup
from set_config import set_config
def usage():
print("\nusage:\n\tmake_all [target_config] - Make all the manufacturing files and readme for a project.")
sys.exit(1)
if __name__ == '__main__':
if len(sys.argv) > 2: usage()
target = None if len(sys.argv) == 1 else sys.argv[1]
set_config(target, usage)
boms(target)
for part in ['stl', 'dxf']:
make_parts(target, part)
render(target, part)
plateup(target, part)
views(target)

View File

@@ -24,11 +24,12 @@ from __future__ import print_function
import subprocess, sys
def run(*args):
cmd = ["openscad"] + list(args)
for arg in cmd:
print(arg, end=" ")
print()
def run_list(args, silent = False):
cmd = ["openscad"] + args
if not silent:
for arg in cmd:
print(arg, end=" ")
print()
with open("openscad.log", "w") as log:
rc = subprocess.call(cmd, stdout = log, stderr = log)
for line in open("openscad.log", "rt"):
@@ -36,3 +37,9 @@ def run(*args):
print(line[:-1])
if rc:
sys.exit(rc)
def run(*args):
run_list(list(args), False)
def run_silent(*args):
run_list(list(args), True);

49
scripts/options.py Normal file
View File

@@ -0,0 +1,49 @@
#
# NopSCADlib Copyright Chris Palmer 2020
# nop.head@gmail.com
# hydraraptor.blogspot.com
#
# This file is part of NopSCADlib.
#
# NopSCADlib is free software: you can redistribute it and/or modify it under the terms of the
# GNU General Public License as published by the Free Software Foundation, either version 3 of
# the License, or (at your option) any later version.
#
# NopSCADlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with NopSCADlib.
# If not, see <https://www.gnu.org/licenses/>.
#
# Set command line options from enviroment variables and check if they have changed
import json, os, deps
def check_options(dir = '.'):
global options, options_mtime
options = { "show_threads": str(os.getenv("NOPSCADLIB_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

39
scripts/panels.py Normal file
View File

@@ -0,0 +1,39 @@
#!/usr/bin/env python
#
# NopSCADlib Copyright Chris Palmer 2018
# 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/>.
#
#! Panelises DXF files so they can be routed together by running scad files found in the ```panels``` directory.
from __future__ import print_function
import sys
from plateup import plateup
def usage():
print("\nusage:\n\tpanels [target_config] - Aggregate DXF files for routing together.")
sys.exit(1)
if __name__ == '__main__':
if len(sys.argv) > 2: usage()
if len(sys.argv) > 1:
target = sys.argv[1]
else:
target = None
plateup(target, 'dxf', usage)

110
scripts/plateup.py Normal file
View File

@@ -0,0 +1,110 @@
#!/usr/bin/env python
#
# NopSCADlib Copyright Chris Palmer 2018
# 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/>.
#
from __future__ import print_function
import os
import openscad
import sys
import c14n_stl
from set_config import *
from deps import *
from shutil import copyfile
import re
source_dirs = { "stl" : "platters", "dxf" : "panels" }
target_dirs = { "stl" : "printed", "dxf" : "routed" }
def plateup(target, part_type, usage = None):
#
# Make the target directory
#
top_dir = set_config(target, usage)
parts_dir = top_dir + part_type + 's'
target_dir = parts_dir + '/' + target_dirs[part_type]
source_dir1 = source_dirs[part_type]
source_dir2 = top_dir + source_dirs[part_type]
#
# Loop through source directories
#
used = []
all_sources = []
for dir in [source_dir1, source_dir2]:
if not os.path.isdir(dir):
continue
if not os.path.isdir(target_dir):
os.makedirs(target_dir)
#
# Make the deps dir
#
deps_dir = dir + "/deps"
if not os.path.isdir(deps_dir):
os.makedirs(deps_dir)
#
# Decide which files to make
#
sources = [file for file in os.listdir(dir) if file.endswith('.scad')]
all_sources += sources
#
# Run OpenSCAD on the source files to make the targets
#
for src in sources:
src_file = dir + '/' + src
part_file = target_dir + '/' + src[:-4] + part_type
dname = deps_name(deps_dir, src)
changed = check_deps(part_file, dname)
if changed:
print(changed)
openscad.run("-D$bom=1", "-d", dname, "-o", part_file, src_file)
if part_type == 'stl':
c14n_stl.canonicalise(part_file)
log_name = 'openscad.log'
else:
log_name = 'openscad.echo'
openscad.run_silent("-D$bom=1", "-o", log_name, src_file)
#
# Add the files on the BOM to the used list
#
with open(log_name) as file:
for line in file.readlines():
match = re.match(r'^ECHO: "~(.*?\.' + part_type + r').*"$', line)
if match:
used.append(match.group(1))
#
# Copy file that are not included
#
copied = []
for file in os.listdir(parts_dir):
if file.endswith('.' + part_type) and not file in used:
src = parts_dir + '/' + file
dst = target_dir + '/' + file
if mtime(src) > mtime(dst):
print("Copying %s to %s" % (src, dst))
copyfile(src, dst)
copied.append(file)
#
# Remove any cruft
#
targets = [file[:-4] + part_type for file in all_sources]
for file in os.listdir(target_dir):
if file.endswith('.' + part_type):
if not file in targets and not file in copied:
print("Removing %s" % file)
os.remove(target_dir + '/' + file)

39
scripts/platters.py Normal file
View File

@@ -0,0 +1,39 @@
#!/usr/bin/env python
#
# NopSCADlib Copyright Chris Palmer 2018
# 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/>.
#
#! Generates build plates of STL files for efficient printing by running scad files found in the ```platters``` directory.
from __future__ import print_function
import sys
from plateup import plateup
def usage():
print("\nusage:\n\tplatters [target_config] - Aggregate STL files for printing together.")
sys.exit(1)
if __name__ == '__main__':
if len(sys.argv) > 2: usage()
if len(sys.argv) > 1:
target = sys.argv[1]
else:
target = None
plateup(target, 'stl', usage)

View File

@@ -5,13 +5,15 @@ These are located in the ```scripts``` subdirectory, which needs to be added to
They should work with both Python 2 and Python 3.
| Script | Function |
|:--|:--|
|:---|:---|
| ```bom.py``` | Generates BOM files for the project. |
| ```c14n_stl.py``` | OpenSCAD produces randomly ordered STL files. This script re-orders them consistently so that GIT can tell if they have changed or not. |
| ```doc_scripts.py``` | Makes this document and doc/usage.md. |
| ```dxfs.py``` | Generates DXF files for all the routed parts listed on the BOM or a specified list. |
| ```gallery.py``` | Finds projects and adds them to the gallery. |
| ```make_all.py``` | Generates all the files for a project by running ```bom.py```, ```stls.py```, ```dxfs.py```, ```render.py``` and ```views.py```. |
| ```panels.py``` | Panelises DXF files so they can be routed together by running scad files found in the ```panels``` directory. |
| ```platters.py``` | Generates build plates of STL files for efficient printing by running scad files found in the ```platters``` directory. |
| ```render.py``` | Renders STL and DXF files to PNG for inclusion in the build instructions. |
| ```set_config.py``` | Sets the target configuration for multi-target projects that have variable configurations. |
| ```stls.py``` | Generates STL files for all the printed parts listed on the BOM or a specified list. |

40
scripts/render.py Normal file → Executable file
View File

@@ -29,18 +29,39 @@ import openscad
from tests import do_cmd, update_image, colour_scheme, background
from deps import mtime
from colorama import init
import json
def usage():
print("\nusage:\n\trender [target_config] - Render images of the stl and dxf files.");
sys.exit(1)
def render(target, type):
#
# Make the target directory
#
target_dir = set_config(target) + type + 's'
top_dir = set_config(target, usage)
target_dir = top_dir + type + 's'
bom_dir = top_dir + 'bom'
if not os.path.isdir(target_dir):
os.makedirs(target_dir)
#
# Find all the parts
#
parts = bom_to_parts(target_dir, type)
parts = bom_to_parts(bom_dir, type)
#
# Read the json bom to get the colours
#
bom_file = bom_dir + "/bom.json"
with open(bom_file) as json_file:
flat_bom = json.load(json_file)
things = { 'stl' : 'printed', 'dxf' : 'routed' }[type]
colours = {}
for ass in flat_bom:
for part in ass[things]:
obj = ass[things][part]
if "colour" in obj:
colours[part] = obj["colour"]
#
# Remove unused png files
#
@@ -49,7 +70,9 @@ def render(target, type):
if not file[:-4] + '.' + type in parts:
print("Removing %s" % file)
os.remove(target_dir + '/' + file)
#
# Render the parts
#
for part in parts:
part_file = target_dir + '/' + part
png_name = target_dir + '/' + part[:-4] + '.png'
@@ -58,10 +81,16 @@ def render(target, type):
#
if mtime(part_file) > mtime(png_name):
png_maker_name = "png.scad"
pp1 = [0, 146/255, 0]
colour = pp1
if part in colours:
colour = colours[part]
if not '[' in colour:
colour = '"' + colour + '"'
with open(png_maker_name, "w") as f:
f.write('color("lime") import("%s");\n' % part_file)
f.write('color(%s) import("%s");\n' % (colour, part_file))
cam = "--camera=0,0,0,70,0,315,500" if type == 'stl' else "--camera=0,0,0,0,0,0,500"
render = "--preview" if type == 'stl' else "--render"
render = "--preview" if type == 'stl' or colour != pp1 else "--render"
tmp_name = 'tmp.png'
openscad.run(colour_scheme, "--projection=p", "--imgsize=4096,4096", cam, render, "--autocenter", "--viewall", "-o", tmp_name, png_maker_name);
do_cmd(("magick "+ tmp_name + " -trim -resize 280x280 -background %s -gravity Center -extent 280x280 -bordercolor %s -border 10 %s"
@@ -71,6 +100,7 @@ def render(target, type):
if __name__ == '__main__':
init()
if len(sys.argv) > 2: usage()
target = sys.argv[1] if len(sys.argv) > 1 else None
render(target, 'stl')
render(target, 'dxf')

18
scripts/set_config.py Normal file → Executable file
View File

@@ -45,20 +45,27 @@ def valid_targets_string():
return result
def set_config(target):
def set_config(target, usage = None):
if target and target[:1] == '-' and usage: usage()
targets = valid_targets()
if not target:
if not targets:
return ""
print("Must specify a configuration: " + valid_targets_string())
if usage:
usage()
sys.exit(1)
if not targets:
print("Not a muli-configuration project (no config_<target>.scad files found)")
if usage:
usage()
sys.exit(1)
if not target in targets:
print(target + " is not a configuration, avaliable configurations are: " + valid_targets_string())
if usage:
usage()
sys.exit(1)
fname = source_dir + "/target.scad"
@@ -75,10 +82,13 @@ def set_config(target):
f. write(text);
return target + "/"
def usage():
print("\nusage:\n\tset_config config_name")
sys.exit(1)
if __name__ == '__main__':
args = len(sys.argv)
if args == 2:
set_config(sys.argv[1])
set_config(sys.argv[1], usage)
else:
print("usage: set_config config_name")
sys.exit(1)
usage()

0
scripts/stls.py Normal file → Executable file
View File

44
scripts/tests.py Normal file → Executable file
View File

@@ -27,6 +27,7 @@ import openscad
import subprocess
import bom
import times
import options
import time
import json
import shutil
@@ -84,6 +85,10 @@ def depluralise(name):
def is_plural(name):
return name != depluralise(name)
def usage():
print("\nusage:\n\ttests [test_name1] ... [test_nameN] - Run specified tests or all tests in none specified.");
sys.exit(1)
def tests(tests):
scad_dir = "tests"
deps_dir = scad_dir + "/deps"
@@ -95,7 +100,9 @@ def tests(tests):
doc_name = "readme.md"
index = {}
bodies = {}
done = []
times.read_times()
options.check_options(deps_dir)
#
# Make cover pic if does not exist as very slow. Delete it to force an update.
#
@@ -107,13 +114,15 @@ def tests(tests):
#
# List of individual part files
#
scads = [i for i in os.listdir(scad_dir) if i[-5:] == ".scad"]
scads = [i for i in sorted(os.listdir(scad_dir), key = lambda s: s.lower()) if i[-5:] == ".scad"]
for scad in scads:
base_name = scad[:-5]
if not tests or base_name in tests:
done.append(base_name)
print(base_name)
cap_name = base_name[0].capitalize() + base_name[1:]
base_name = base_name.lower()
scad_name = scad_dir + '/' + scad
png_name = png_dir + '/' + base_name + '.png'
bom_name = bom_dir + '/' + base_name + '.json'
@@ -138,11 +147,14 @@ def tests(tests):
print("Can't find implementation!")
continue
vsplit = "N"
vsplit = "AJR" + chr(ord('Z') + 1)
vtype = locations[0][1]
types = [vtype + ' A-' + vsplit[0], vtype + ' ' + chr(ord(vsplit) + 1) + '-Z'] + [loc[1] for loc in locations[1 :]]
types = [vtype + ' ' + vsplit[i] + '-' + chr(ord(vsplit[i + 1]) - 1) for i in range(len(vsplit) - 1)] + [loc[1] for loc in locations[1 :]]
if type == vtype:
type = types[0] if cap_name[0] <= vsplit else types[1]
for i in range(1, len(vsplit)):
if cap_name[0] < vsplit[i]:
type = types[i - 1]
break
for t in types:
if not t in bodies:
@@ -186,15 +198,16 @@ def tests(tests):
body += ["![%s](%s)\n" %(base_name, png_name)]
dname = deps_name(deps_dir, scad)
oldest = min(mtime(png_name), mtime(bom_name))
dname = deps_name(deps_dir, scad.lower())
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)
@@ -219,14 +232,23 @@ def tests(tests):
j = name.find(']]') + 2
name = name.replace(name[i : j], '[ ... ]')
desc = vit[1]
body += ['| %3d | %s | %s |' % (things[item], name, desc)]
body += ['| %3d | %s | %s |' % (things[item]["count"], name, desc)]
else:
body += ['| %3d | %s |' % (things[item], name)]
count = things[item] if thing == 'assemblies' else things[item]["count"]
body += ['| %3d | %s |' % (count, name)]
body += ['']
body += ['\n<a href="#top">Top</a>']
body += ["\n---"]
for test in done:
if test in tests:
tests.remove(test)
if tests:
for test in tests:
print(Fore.MAGENTA + "Could not find a test called", test, Fore.WHITE)
usage()
with open(doc_name, "wt") as doc_file:
print('# NopSCADlib', file = doc_file)
print('''\
@@ -257,7 +279,7 @@ See [usage](docs/usage.md) for requirements, installation instructions and a usa
print('<tr>', file = doc_file, end = '')
for type in types:
if i < len(index[type]):
name = index[type][i]
name = sorted(index[type])[i]
print('<td> <a href = "#' + name + '">' + name + '</a> </td>', file = doc_file, end = '')
else:
print('<td></td>', file = doc_file, end = '')
@@ -272,4 +294,6 @@ See [usage](docs/usage.md) for requirements, installation instructions and a usa
do_cmd('codespell -L od readme.md'.split())
if __name__ == '__main__':
for arg in sys.argv[1:]:
if arg[:1] == '-': usage()
tests(sys.argv[1:])

View File

@@ -48,6 +48,8 @@ def check_have_time(changed, name):
return changed
def add_time(name, start):
if name.lower() in times:
del times[name.lower()]
times[name] = round(time.time() - start, 3)
def print_times():

264
scripts/views.py Normal file → Executable file
View File

@@ -28,6 +28,7 @@ import openscad
from tests import do_cmd, update_image, colour_scheme, background
import time
import times
import options
from deps import *
import os
import json
@@ -51,28 +52,30 @@ def bom_to_assemblies(bom_dir, bounds_map):
# Decide if we need big or small assembly pictures
#
for bom in flat_bom:
big = False
for ass in bom["assemblies"]:
for b in flat_bom:
if b["name"] == ass:
if b["big"]:
if bom["big"] == None:
big = False
for ass in bom["assemblies"]:
for b in flat_bom:
if b["name"] == ass:
if b["big"]:
big = True
break
if not big:
for stl in bom["printed"]:
bounds = bounds_map[stl]
width = bounds[1][0] - bounds[0][0]
depth = bounds[1][1] - bounds[0][1]
if max(width, depth) > 80:
big = True
break
if not big:
for stl in bom["printed"]:
bounds = bounds_map[stl]
width = bounds[1][0] - bounds[0][0]
depth = bounds[1][1] - bounds[0][1]
if max(width, depth) > 80:
big = True
break
bom["big"] = big or bom["routed"]
break
bom["big"] = big or bom["routed"]
#
# Remove the main assembly if it is a shell
#
ass = flat_bom[-1]
if len(ass["assemblies"]) < 2 and not ass["vitamins"] and not ass["printed"] and not ass["routed"]:
flat_bom = flat_bom[:-1]
if flat_bom:
ass = flat_bom[-1]
if len(ass["assemblies"]) < 2 and not ass["vitamins"] and not ass["printed"] and not ass["routed"]:
flat_bom = flat_bom[:-1]
return [assembly["name"] for assembly in flat_bom]
def eop(print_mode, doc_file, last = False, first = False):
@@ -87,12 +90,24 @@ def eop(print_mode, doc_file, last = False, first = False):
def pad(s, before, after = 0):
return '&nbsp;' * before + str(s) + '&nbsp;' * after
def titalise(name):
cap_next = True
result = ''
for c in name.replace('_', ' '):
result = result + (c.upper() if cap_next else c);
cap_next = c == ' '
return result
def usage():
print("\nusage:\n\t views [target_config] [<name1>_assembly] ... [<nameN>_assembly] - Create assembly images and readme.")
sys.exit(1)
def views(target, do_assemblies = None):
done_assemblies = []
#
# Make the target directory
#
top_dir = set_config(target)
top_dir = set_config(target, usage)
target_dir = top_dir + 'assemblies'
deps_dir = top_dir + "deps"
bom_dir = top_dir + "bom"
@@ -102,13 +117,15 @@ 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)
#
# Find all the assemblies
# Find all the assemblies and remove any old views
#
assemblies = bom_to_assemblies(bom_dir, bounds_map)
lc_assemblies = [ass.lower() for ass in assemblies]
for file in os.listdir(target_dir):
if file.endswith('.png'):
assembly = file[:-4].replace('_assembled', '_assembly')
@@ -121,66 +138,69 @@ def views(target, do_assemblies = None):
# Find all the scad files
#
main_blurb = None
lib_dir = os.environ['OPENSCADPATH'] + '/NopSCADlib/printed'
for dir in [source_dir, lib_dir]:
for filename in os.listdir(dir):
if filename.endswith('.scad'):
#
# find any modules with names ending in _assembly
#
with open(dir + "/" + filename, "r") as f:
lines = f.readlines()
line_no = 0
for line in lines:
words = line.split()
if len(words) and words[0] == "module":
module = words[1].split('(')[0]
if is_assembly(module):
if module in assemblies:
#
# Scrape the assembly instructions
#
for ass in flat_bom:
if ass["name"] == module:
if not "blurb" in ass:
ass["blurb"] = blurb.scrape_module_blurb(lines[:line_no])
break
if not do_assemblies or module in do_assemblies:
for dir in source_dirs(bom_dir):
if os.path.isdir(dir):
for filename in os.listdir(dir):
if filename.endswith('.scad'):
#
# find any modules with names ending in _assembly
#
with open(dir + "/" + filename, "r") as f:
lines = f.readlines()
line_no = 0
for line in lines:
words = line.split()
if len(words) and words[0] == "module":
module = words[1].split('(')[0]
if is_assembly(module):
lc_module = module.lower()
if lc_module in lc_assemblies:
real_name = assemblies[lc_assemblies.index(lc_module)]
#
# make a file to use the module
# Scrape the assembly instructions
#
png_maker_name = 'png.scad'
with open(png_maker_name, "w") as f:
f.write("use <%s/%s>\n" % (dir, filename))
f.write("%s();\n" % module);
#
# Run openscad on the created file
#
dname = deps_name(deps_dir, filename)
for explode in [0, 1]:
png_name = target_dir + '/' + module + '.png'
if not explode:
png_name = png_name.replace('_assembly', '_assembled')
changed = check_deps(mtime(png_name), dname)
changed = times.check_have_time(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);
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)
tn_name = png_name.replace('.png', '_tn.png')
if mtime(png_name) > mtime(tn_name):
do_cmd(("magick "+ png_name + " -trim -resize 280x280 -background " + background + " -gravity Center -extent 280x280 -bordercolor " + background + " -border 10 " + tmp_name).split())
update_image(tmp_name, tn_name)
os.remove(png_maker_name)
done_assemblies.append(module)
else:
if module == 'main_assembly':
main_blurb = blurb.scrape_module_blurb(lines[:line_no])
line_no += 1
for ass in flat_bom:
if ass["name"] == real_name:
if not "blurb" in ass:
ass["blurb"] = blurb.scrape_module_blurb(lines[:line_no])
break
if not do_assemblies or real_name in do_assemblies:
#
# Run openscad on the created file
#
dname = deps_name(deps_dir, filename)
for explode in [0, 1]:
png_name = target_dir + '/' + real_name + '.png'
if not explode:
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)
#
# make a file to use the module
#
png_maker_name = 'png.scad'
with open(png_maker_name, "w") as f:
f.write("use <%s/%s>\n" % (dir, filename))
f.write("%s();\n" % module);
t = time.time()
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)
os.remove(png_maker_name)
tn_name = png_name.replace('.png', '_tn.png')
if mtime(png_name) > mtime(tn_name):
do_cmd(("magick "+ png_name + " -trim -resize 280x280 -background " + background + " -gravity Center -extent 280x280 -bordercolor " + background + " -border 10 " + tmp_name).split())
update_image(tmp_name, tn_name)
done_assemblies.append(real_name)
else:
if module == 'main_assembly':
main_blurb = blurb.scrape_module_blurb(lines[:line_no])
line_no += 1
times.print_times()
#
# Build the document
@@ -211,7 +231,7 @@ def views(target, do_assemblies = None):
print('1. [Parts list](#Parts_list)', file = doc_file)
for ass in flat_bom:
name = ass["name"]
cap_name = name.replace('_', ' ').title()
cap_name = titalise(name)
print('1. [%s](#%s)' % (cap_name, name), file = doc_file)
print(file = doc_file)
eop(print_mode, doc_file)
@@ -219,36 +239,49 @@ def views(target, do_assemblies = None):
# Global BOM
#
print('<a name="Parts_list"></a>\n## Parts list', file = doc_file)
vitamins = {}
printed = {}
routed = {}
types = ["vitamins", "printed", "routed"]
headings = {"vitamins" : "vitamins", "printed" : "3D printed parts", "routed" : "CNC routed parts"}
things = {}
for t in types:
things[t] = {}
for ass in flat_bom:
for v in ass["vitamins"]:
if v in vitamins:
vitamins[v] += ass["vitamins"][v]
else:
vitamins[v] = ass["vitamins"][v]
for p in ass["printed"]:
if p in printed:
printed[p] += ass["printed"][p]
else:
printed[p] = ass["printed"][p]
for t in types:
for thing in ass[t]:
if thing in things[t]:
things[t][thing] += ass[t][thing]["count"]
else:
things[t][thing] = ass[t][thing]["count"]
for ass in flat_bom:
name = ass["name"][:-9].replace('_', ' ').title().replace(' ','&nbsp;')
name = titalise(ass["name"][:-9]).replace(' ','&nbsp;')
print('| <span style="writing-mode: vertical-rl; text-orientation: mixed;">%s</span> ' % name, file = doc_file, end = '')
print('| <span style="writing-mode: vertical-rl; text-orientation: mixed;">TOTALS</span> | |', file = doc_file)
print(('|--:' * len(flat_bom) + '|--:|:--|'), file = doc_file)
for v in sorted(vitamins, key = lambda s: s.split(":")[-1]):
for ass in flat_bom:
count = ass["vitamins"][v] if v in ass["vitamins"] else '.'
print('| %s ' % pad(count, 2, 1), file = doc_file, end = '')
print('| %s | %s |' % (pad(vitamins[v], 2, 1), pad(v.split(":")[1], 2)), file = doc_file)
print(('| ' * len(flat_bom) + '| | **3D Printed parts** |'), file = doc_file)
for p in sorted(printed):
for ass in flat_bom:
count = ass["printed"][p] if p in ass["printed"] else '.'
print('| %s ' % pad(count, 2, 1), file = doc_file, end = '')
print('| %s | %s |' % (pad(printed[p], 2, 1), pad(p, 3)), file = doc_file)
print(('|---:' * len(flat_bom) + '|---:|:---|'), file = doc_file)
for t in types:
if things[t]:
totals = {}
heading = headings[t][0:1].upper() + headings[t][1:]
print(('| ' * len(flat_bom) + '| | **%s** |') % heading, file = doc_file)
for thing in sorted(things[t], key = lambda s: s.split(":")[-1]):
for ass in flat_bom:
count = ass[t][thing]["count"] if thing in ass[t] else 0
print('| %s ' % pad(count if count else '.', 2, 1), file = doc_file, end = '')
name = ass["name"]
if name in totals:
totals[name] += count
else:
totals[name] = count
print('| %s | %s |' % (pad(things[t][thing], 2, 1), pad(thing.split(":")[-1], 2)), file = doc_file)
grand_total = 0
for ass in flat_bom:
name = ass["name"]
total = totals[name] if name in totals else 0
print('| %s ' % pad(total if total else '.', 2, 1), file = doc_file, end = '')
grand_total += total
print("| %s | %s |" % (pad(grand_total, 2, 1), pad('Total %s count' % headings[t], 2)), file = doc_file)
print(file = doc_file)
eop(print_mode, doc_file)
#
@@ -256,7 +289,7 @@ def views(target, do_assemblies = None):
#
for ass in flat_bom:
name = ass["name"]
cap_name = name.replace('_', ' ').title()
cap_name = titalise(name)
if ass["count"] > 1:
print('<a name="%s"></a>\n## %d x %s' % (name, ass["count"], cap_name), file = doc_file)
@@ -266,9 +299,9 @@ def views(target, do_assemblies = None):
if vitamins:
print("### Vitamins", file = doc_file)
print("|Qty|Description|", file = doc_file)
print("|--:|:----------|", file = doc_file)
for v in vitamins:
print("|%d|%s|" % (vitamins[v], v.split(":")[1]), file = doc_file)
print("|---:|:----------|", file = doc_file)
for v in sorted(vitamins, key = lambda s: s.split(":")[-1]):
print("|%d|%s|" % (vitamins[v]["count"], v.split(":")[1]), file = doc_file)
print("\n", file = doc_file)
printed = ass["printed"]
@@ -277,10 +310,10 @@ def views(target, do_assemblies = None):
keys = sorted(list(printed.keys()))
for i in range(len(keys)):
p = keys[i]
print('%s %d x %s |' % ('\n|' if not (i % 3) else '', printed[p], p), file = doc_file, end = '')
print('%s %d x %s |' % ('\n|' if not (i % 3) else '', printed[p]["count"], p), file = doc_file, end = '')
if (i % 3) == 2 or i == len(printed) - 1:
n = (i % 3) + 1
print('\n|%s' % ('--|' * n), file = doc_file)
print('\n|%s' % ('---|' * n), file = doc_file)
for j in range(n):
part = keys[i - n + j + 1]
print('| ![%s](stls/%s) %s' % (part, part.replace('.stl','.png'), '|\n' if j == j - 1 else ''), end = '', file = doc_file)
@@ -293,10 +326,10 @@ def views(target, do_assemblies = None):
keys = sorted(list(routed.keys()))
for i in range(len(keys)):
r = keys[i]
print('%s %d x %s |' % ('\n|' if not (i % 3) else '', routed[r], r), file = doc_file, end = '')
print('%s %d x %s |' % ('\n|' if not (i % 3) else '', routed[r]["count"], r), file = doc_file, end = '')
if (i % 3) == 2 or i == len(routed) - 1:
n = (i % 3) + 1
print('\n|%s' % ('--|' * n), file = doc_file)
print('\n|%s' % ('---|' * n), file = doc_file)
for j in range(n):
part = keys[i - n + j + 1]
print('| ![%s](dxfs/%s) %s' % (part, part.replace('.dxf','.png'), '|\n' if j == j - 1 else ''), end = '', file = doc_file)
@@ -312,7 +345,7 @@ def views(target, do_assemblies = None):
print('%s %d x %s |' % ('\n|' if not (i % 3) else '', sub_assemblies[a], a), file = doc_file, end = '')
if (i % 3) == 2 or i == len(keys) - 1:
n = (i % 3) + 1
print('\n|%s' % ('--|' * n), file = doc_file)
print('\n|%s' % ('---|' * n), file = doc_file)
for j in range(n):
a = keys[i - n + j + 1].replace('_assembly', '_assembled')
print('| ![%s](assemblies/%s) %s' % (a, a + '_tn.png', '|\n' if j == j - 1 else ''), end = '', file = doc_file)
@@ -367,4 +400,7 @@ if __name__ == '__main__':
else:
target, assemblies = None, sys.argv[1:]
for a in assemblies:
if a[-9:] != "_assembly": usage()
views(target, assemblies)

View File

@@ -21,9 +21,8 @@
//! BOM and assembly demonstration
//
include <../core.scad>
include <../vitamins/screws.scad>
include <../vitamins/inserts.scad>
include <../vitamins/sheets.scad>
use <../vitamins/insert.scad>
$explode = 1; // Normally set on the command line when generating assembly views with views.py
screw = M3_cap_screw;
@@ -68,7 +67,7 @@ module widgit_dxf() {
//! * Push the insert into the base with a soldering iron heated to 200&deg;C
module widgit_base_assembly()
assembly("widgit_base") {
color(pp1_colour)
stl_colour(pp1_colour)
widgit_stl();
translate_z(height)

30
tests/DIP.scad Normal file
View File

@@ -0,0 +1,30 @@
//
// NopSCADlib Copyright Chris Palmer 2020
// nop.head@gmail.com
// hydraraptor.blogspot.com
//
// This file is part of NopSCADlib.
//
// NopSCADlib is free software: you can redistribute it and/or modify it under the terms of the
// GNU General Public License as published by the Free Software Foundation, either version 3 of
// the License, or (at your option) any later version.
//
// NopSCADlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with NopSCADlib.
// If not, see <https://www.gnu.org/licenses/>.
//
include <../core.scad>
use <../vitamins/dip.scad>
dips = [[6, "OPTO"], [8, "NE555"], [14, "74HC00"], [16, "ULN2003"], [18, "ULN2803"], [20, "74HC245"], [28, "ATMEGA328"]];
module dips()
for(i = [0 : len(dips) - 1]) let(dip = dips[i])
translate([i * inch(0.5), 0])
pdip(dip[0], dip[1], dip[0] > 20);
if($preview)
dips();

View File

@@ -17,10 +17,10 @@
// If not, see <https://www.gnu.org/licenses/>.
//
include <../core.scad>
use <../utils/layout.scad>
include <../vitamins/iecs.scad>
use <../utils/layout.scad>
module iecs()
layout([for(i = iecs) iec_flange_h(i)], 10)
rotate(90)

View File

@@ -0,0 +1,33 @@
//
// NopSCADlib Copyright Chris Palmer 2018
// nop.head@gmail.com
// hydraraptor.blogspot.com
//
// This file is part of NopSCADlib.
//
// NopSCADlib is free software: you can redistribute it and/or modify it under the terms of the
// GNU General Public License as published by the Free Software Foundation, either version 3 of
// the License, or (at your option) any later version.
//
// NopSCADlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with NopSCADlib.
// If not, see <https://www.gnu.org/licenses/>.
//
include <../core.scad>
include <../vitamins/kp_pillow_blocks.scad>
use <../utils/layout.scad>
module kp_pillow_blocks() {
screws = [M4_cap_screw, M4_cap_screw, M5_cap_screw, M5_cap_screw];
nuts = [M4_sliding_t_nut, M4_hammer_nut, M5_sliding_t_nut, M5_nut];
assert(len(screws) == len(kp_pillow_blocks) && len(nuts) == len(kp_pillow_blocks));
layout([for(k = kp_pillow_blocks) 2 * kp_size(k)[1]])
kp_pillow_block_assembly(kp_pillow_blocks[$i], screw_type = screws[$i], nut_type = nuts[$i]);
}
if($preview)
kp_pillow_blocks();

27
tests/LDRs.scad Normal file
View File

@@ -0,0 +1,27 @@
//
// NopSCADlib Copyright Chris Palmer 2018
// 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 <../vitamins/ldrs.scad>
use <../utils/layout.scad>
module ldrs()
layout([for(l = ldrs) ldr_diameter(l)], 5)
LDR(ldrs[$i]);
ldrs();

37
tests/LED_meters.scad Normal file
View File

@@ -0,0 +1,37 @@
//
// NopSCADlib Copyright Chris Palmer 2018
// nop.head@gmail.com
// hydraraptor.blogspot.com
//
// This file is part of NopSCADlib.
//
// NopSCADlib is free software: you can redistribute it and/or modify it under the terms of the
// GNU General Public License as published by the Free Software Foundation, either version 3 of
// the License, or (at your option) any later version.
//
// NopSCADlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with NopSCADlib.
// If not, see <https://www.gnu.org/licenses/>.
//
include <../utils/core/core.scad>
include <../utils/layout.scad>
include <../vitamins/led_meters.scad>
module led_meters()
layout([for(m = led_meters) meter_bezel_length(m)], 5) let(m = led_meters[$i])
if($preview) {
hflip()
meter(m, colour = "blue", value = "123");
if(!$i)
translate([0, meter_bezel_width(m)])
meter_assembly(m, value = "123");
}
else
meter_bezel(m);
led_meters();

View File

@@ -16,7 +16,7 @@
// You should have received a copy of the GNU General Public License along with NopSCADlib.
// If not, see <https://www.gnu.org/licenses/>.
//
include <../core.scad>
include <../utils/core/core.scad>
use <../utils/layout.scad>
include <../vitamins/leds.scad>

139
tests/PCB.scad Normal file
View File

@@ -0,0 +1,139 @@
//
// NopSCADlib Copyright Chris Palmer 2020
// nop.head@gmail.com
// hydraraptor.blogspot.com
//
// This file is part of NopSCADlib.
//
// NopSCADlib is free software: you can redistribute it and/or modify it under the terms of the
// GNU General Public License as published by the Free Software Foundation, either version 3 of
// the License, or (at your option) any later version.
//
// NopSCADlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with NopSCADlib.
// If not, see <https://www.gnu.org/licenses/>.
//
include <../core.scad>
include <../vitamins/microswitches.scad>
include <../vitamins/d_connectors.scad>
include <../vitamins/leds.scad>
include <../vitamins/axials.scad>
include <../vitamins/smds.scad>
use <../vitamins/pcb.scad>
gt_5x17 = ["gt_5x17", 5, 10, 17, 5, 11, 0.4, 9, 2,1.5, 1, 3, 6, 0.5, 0, 0, 0];
gt_5x11 = ["gt_5x11", 5, 8, 11, 5, 7, 0.4, 7, 1.5,1.5, 1,2.5, 6, 0.5, 0, 0, 0];
TMC2130HeatSinkColor = "DeepSkyBlue";
TMC2130 = ["TMC2130", "TMC2130",
20, 14, 1.6, 0, 3, 0, "white", false, [],
[
[ 10, 1, 0, "-2p54header", 8, 1 ,undef, "blue" ],
[ 10, 13, 0, "-2p54header", 8, 1],
[ 12, 7, 0, "-chip", 6, 4, 1, grey(20) ],
// mock up a heat sink
[ 10, 7, 0, "block", 9, 9, 2, TMC2130HeatSinkColor ],
[ 10, 11, 0, "block", 9, 1, 11, TMC2130HeatSinkColor ],
[ 10, 9, 0, "block", 9, 1, 11, TMC2130HeatSinkColor ],
[ 10, 7, 0, "block", 9, 1, 11, TMC2130HeatSinkColor ],
[ 10, 5, 0, "block", 9, 1, 11, TMC2130HeatSinkColor ],
[ 10, 3, 0, "block", 9, 1, 11, TMC2130HeatSinkColor ],
],
[]
];
test_pcb = ["TestPCB", "Test PCB",
100, 250, 1.6, // length, width, thickness
3, // Corner radius
2.75, // Mounting hole diameter
5.5, // Pad around mounting hole
"green",// Color
true, // True if the parts should be separate BOM items
// hole offsets
[ [3, 3], [3, -3], [-3, 3], [-3, -3] ],
// components
[
[ 20, -5, 180, "trimpot10"],
[ 20, -15, 90, "trimpot10", true],
[ 10, 2, 90, "smd_led", LED0805, "red"],
[ 13, 2, 90, "smd_led", LED0603, "orange"],
[ 16, 2, 90, "smd_res", RES1206, "1K"],
[ 19, 2, 90, "smd_res", RES0805, "1K"],
[ 22, 2, 90, "smd_res", RES0603, "1K"],
[ 10, 10, 0, "2p54header", 4, 1],
[ 25, 10, 0, "2p54header", 5, 1, false, "blue" ],
[ 10, 20, 0, "2p54boxhdr", 4, 2],
[ 10, 30, 0, "2p54socket", 6, 1],
[ 25, 30, 0, "2p54socket", 4, 1, false, 0, false, "red" ],
[ 10, 40, 0, "chip", 10, 5, 1, grey(20)],
[ 5, 50, 0, "led", LED3mm, "red"],
[ 12, 50, 0, "led", LED5mm, "orange"],
[ 25, 50, 0, "led", LED10mm, "yellow"],
[ 10, 65, 180, "rj45"],
[ 8, 85, 180, "usb_A"],
[ 8, 105, 180, "usb_Ax2"],
[ 3, 140, 180, "usb_uA"],
[ 8, 155, 180, "usb_B"],
[ 8.5, 125, 180, "molex_usb_Ax2"],
[ 25, 200, 0, "buzzer", 4.5, 8.5],
[ 25, 218, 0, "buzzer"],
[ 8, 190, 180, "jack"],
[ 6, 200, 180, "barrel_jack"],
[ 5, 218, 180, "hdmi"],
[ 3, 235, 180, "mini_hdmi"],
[ 6, 175, 180, "uSD", [12, 11.5, 1.4]],
[ 65, 12, 0, "ax_res", res1_8, 1000],
[ 65, 17, 0, "ax_res", res1_4, 10000],
[ 65, 22, 0, "ax_res", res1_2, 100000],
[ 80, 12, 0, "ax_res", res1_8, 1000000, 1, inch(0.1)],
[ 80, 17, 0, "ax_res", res1_4, 100, 2, inch(0.1)],
[ 80, 22, 0, "ax_res", res1_2, 10, 10, inch(0.2)],
[ 60, 3, 0, "flex"],
[ 50, 15, -90, "flat_flex"],
[ 40, 15, -90, "flat_flex", true],
[ 60, 35, 0, "D_plug", DCONN9],
[ 50, 50, 0, "molex_hdr", 2],
[ 50, 60, 0, "jst_xh", 2],
[ 50, 70, 180, "term254", 3],
[ 63, 70, 180, "term254", 3, undef, grey(20)],
[ 75, 70, 180, "gterm508",2, undef, "blue"],
[ 50, 90, 180, "gterm35", 4, [1,2]],
[ 63, 90, 180, "gterm35", 4, [1,2], "red"],
[ 75, 90, 180, "gterm", gt_5x11, 3],
[ 90, 90, 180, "gterm", gt_5x17, 3, [1], "red"],
[ 55, 110, 180, "gterm635", 2],
[ 75, 110, 180, "gterm635", 2, undef, "blue"],
[ 90, 110, 180, "gterm", gt_5x17, 2, undef, grey(20)],
[ 50, 130, 180, "term35", 4],
[ 70, 130, 180, "term35", 3, "lime"],
[ 50, 150, 0, "transition", 5],
[ 50, 160, 0, "block", 10, 5, 8, "orange"],
[ 50, 170, 0, "button_6mm"],
[ 50, 185, 0, "microswitch", small_microswitch],
[ 52, 200, 0, "pcb", 11, TMC2130 ],
[ 80, 200, 0, "pdip", 24, "27C32", true, inch(0.6) ],
[ 80, 170, 0, "pdip", 8, "NE555" ],
[ 52, 206, 0, "2p54socket", 8, 1 ],
[ 52, 194, 0, "2p54socket", 8, 1, false, 0, false, "red" ],
[ 50, 220, 0, "standoff", 5, 4.5, 12.5, 2.54],
[ 50, 240, 0, "potentiometer"],
[ 75, 240, 0, "potentiometer", 7, 8],
],
// accessories
[]
];
if($preview)
let($show_threads = true)
pcb(test_pcb);

35
tests/PCB_mount.scad Normal file
View File

@@ -0,0 +1,35 @@
//
// 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/>.
//
include <../utils/core/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, [],
[[(3.015 - 2.7) * 25.4 - 3.5 /2, (4.5 - 3.685) * 25.4, 90, "term35", 2],
[(3.46 - 2.7) * 25.4 - 3.5 /2, (4.5 - 3.69) * 25.4, 90, "term35", 2],
[(3.91 - 2.7) * 25.4 - 3.5 /2, (4.5 - 3.69) * 25.4, 90, "term35", 2],
[(3.4 - 2.7) * 25.4, (4.5 - 4.15) * 25.4, 0, "2p54socket", 13, 2],
], []];
module pcb_mounts()
if($preview)
pcb_mount_assembly(PI_IO, 3);
else
pcb_mount(PI_IO);
pcb_mounts();

View File

@@ -17,16 +17,20 @@
// If not, see <https://www.gnu.org/licenses/>.
//
include <../core.scad>
use <../utils/layout.scad>
include <../vitamins/d_connectors.scad>
include <../vitamins/pcbs.scad>
module pcbs()
layout([for(p = pcbs) pcb_width(p)], 15)
use <../utils/layout.scad>
module pcbs() {
layout([for(p = pcbs) pcb_width(p)], 10)
translate([0, pcb_length(pcbs[$i]) / 2])
rotate(90)
pcb_assembly(pcbs[$i], 5 + $i, 3);
translate([0, 120])
layout([for(p = perfboards) pcb_length(p)], 10)
translate([0, -pcb_width(perfboards[$i]) / 2])
pcb_assembly(perfboards[$i], 5 + $i, 3);
}
if($preview)
pcbs();

37
tests/PSU_shroud.scad Normal file
View File

@@ -0,0 +1,37 @@
//
// NopSCADlib Copyright Chris Palmer 2018
// nop.head@gmail.com
// hydraraptor.blogspot.com
//
// This file is part of NopSCADlib.
//
// NopSCADlib is free software: you can redistribute it and/or modify it under the terms of the
// GNU General Public License as published by the Free Software Foundation, either version 3 of
// the License, or (at your option) any later version.
//
// NopSCADlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with NopSCADlib.
// If not, see <https://www.gnu.org/licenses/>.
//
include <../core.scad>
include <../vitamins/psus.scad>
use <../utils/layout.scad>
use <../printed/psu_shroud.scad>
thickness = 3;
module psu_shrouds()
layout([for(p = psus) psu_width(p)], 10) let(psu = psus[$i])
if(psu_terminals(psu))
rotate(90) {
if($preview)
psu_shroud_fastened_assembly(psu, 6, thickness, psu[0]);
else
psu_shroud(psu, 6, psu[0]);
}
psu_shrouds();

View File

@@ -17,11 +17,10 @@
// If not, see <https://www.gnu.org/licenses/>.
//
include <../core.scad>
use <../utils/layout.scad>
include <../vitamins/screws.scad>
include <../vitamins/psus.scad>
use <../utils/layout.scad>
module psus()
layout([for(p = psus) psu_width(p)], 10) let(p = psus[$i])
rotate(atx_psu(p) ? 0 : 90) {

View File

@@ -0,0 +1,35 @@
//
// NopSCADlib Copyright Chris Palmer 2020
// nop.head@gmail.com
// hydraraptor.blogspot.com
//
// This file is part of NopSCADlib.
//
// NopSCADlib is free software: you can redistribute it and/or modify it under the terms of the
// GNU General Public License as published by the Free Software Foundation, either version 3 of
// the License, or (at your option) any later version.
//
// NopSCADlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with NopSCADlib.
// If not, see <https://www.gnu.org/licenses/>.
//
include <../core.scad>
include <../vitamins/scs_bearing_blocks.scad>
use <../utils/layout.scad>
module scs_bearing_blocks()
layout([for(s = scs_bearing_blocks) scs_size(s).x], 10) {
part_thickness = 5;
scs_bearing_block_assembly(scs_bearing_blocks[$i], part_thickness);
if($i > 0) // skip $i==0, since no SCS6LUU long variant to match SCS6UU
translate([0, 60])
scs_bearing_block_assembly(scs_bearing_blocks_long[$i - 1], part_thickness);
}
if($preview)
scs_bearing_blocks();

39
tests/SK_brackets.scad Normal file
View File

@@ -0,0 +1,39 @@
//
// NopSCADlib Copyright Chris Palmer 2018
// nop.head@gmail.com
// hydraraptor.blogspot.com
//
// This file is part of NopSCADlib.
//
// NopSCADlib is free software: you can redistribute it and/or modify it under the terms of the
// GNU General Public License as published by the Free Software Foundation, either version 3 of
// the License, or (at your option) any later version.
//
// NopSCADlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with NopSCADlib.
// If not, see <https://www.gnu.org/licenses/>.
//
include <../core.scad>
include <../vitamins/sk_brackets.scad>
include <../vitamins/extrusions.scad>
use <../utils/layout.scad>
module sk_brackets() {
screws = [M4_dome_screw, M4_cap_screw, M5_cap_screw, M5_cap_screw];
nuts = [M4_hammer_nut, M4_sliding_t_nut, M5_sliding_t_nut, undef];
// channel depth = 6 for 2020 extrusion, 9 for 3030 extrusion
depths = [6, 6, 9, 0];
layout([for(s = sk_brackets) 1.5 * sk_size(s)[1]]) {
sk_bracket_assembly(sk_brackets[$i], screw_type = screws[$i], nut_type = nuts[$i], max_screw_depth = depths[$i]);
translate([0, -sk_hole_offset(sk_brackets[$i]) - extrusion_width($i < 2 ? E2020 : E3030) / 2, 0])
rotate([0, 90, 0])
extrusion($i < 2 ? E2020 : E3030, 20, false);
}
}
if($preview)
sk_brackets();

34
tests/SMDs.scad Normal file
View File

@@ -0,0 +1,34 @@
//
// 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 <../utils/core/core.scad>
use <../utils/layout.scad>
include <../vitamins/smds.scad>
module smds() {
layout([for(r = smd_resistors) smd_res_size(r).x], 1)
smd_resistor(smd_resistors[$i], ["1R0", "10M", "100K"][$i % 3]);
translate([0, 3])
layout([for(l = smd_leds) smd_led_size(l).x], 1)
smd_led(smd_leds[$i], ["green", "blue", "red"][$i % 3]);
}
if($preview)
smds();

View File

@@ -17,10 +17,9 @@
// If not, see <https://www.gnu.org/licenses/>.
//
include <../core.scad>
use <../utils/layout.scad>
include <../vitamins/screws.scad>
include <../vitamins/ssrs.scad>
use <../utils/layout.scad>
use <../printed/ssr_shroud.scad>
thickness = 3;
@@ -31,7 +30,7 @@ module ssr_shrouds()
if($preview)
ssr_shroud_fastened_assembly(ssr, 6, thickness, ssr[0]);
else
ssr_shroud(ssrs[$i], 6, ssr[0]);
ssr_shroud(ssr, 6, ssr[0]);
}
ssr_shrouds();

View File

@@ -17,11 +17,10 @@
// If not, see <https://www.gnu.org/licenses/>.
//
include <../core.scad>
use <../utils/layout.scad>
include <../vitamins/screws.scad>
include <../vitamins/ssrs.scad>
use <../utils/layout.scad>
module ssrs()
layout([for(s = ssrs) ssr_width(s)], 15)
rotate(90)

52
tests/Swiss_clips.scad Normal file
View File

@@ -0,0 +1,52 @@
//
// NopSCADlib Copyright Chris Palmer 2020
// nop.head@gmail.com
// hydraraptor.blogspot.com
//
// This file is part of NopSCADlib.
//
// NopSCADlib is free software: you can redistribute it and/or modify it under the terms of the
// GNU General Public License as published by the Free Software Foundation, either version 3 of
// the License, or (at your option) any later version.
//
// NopSCADlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with NopSCADlib.
// If not, see <https://www.gnu.org/licenses/>.
//
include <../utils/core/core.scad>
use <../utils/layout.scad>
include <../vitamins/swiss_clips.scad>
include <../vitamins/sheets.scad>
glass = glass2;
bed = AL6;
gap = sheet_thickness(bed) + sheet_thickness(glass);
module swiss_clips()
layout([for(s = swiss_clips) sclip_length(s)], 5, true)
let(s = swiss_clips[$i]) {
swiss_clip(s);
translate([0, 20]) {
swiss_clip(s, gap);
translate([20, 0, -5])
render_2D_sheet(bed)
difference() {
sheet_2D(bed, 40, 20, 1);
translate([-20, 0])
swiss_clip_hole(s, gap);
}
translate([20, 0, -1 + eps])
render_sheet(glass) sheet(glass, 40, 20, 1);
}
}
if($preview)
swiss_clips();

View File

@@ -16,7 +16,7 @@
// You should have received a copy of the GNU General Public License along with NopSCADlib.
// If not, see <https://www.gnu.org/licenses/>.
//
include <../core.scad>
include <../utils/core/core.scad>
use <../utils/annotation.scad>
module annotations() {

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