1
0
mirror of https://github.com/nophead/NopSCADlib.git synced 2025-09-03 12:22:46 +02:00

Compare commits

...

169 Commits

Author SHA1 Message Date
Chris Palmer
fc7fd5482e Corrected core XY comment. 2020-11-14 17:40:20 +00:00
Chris Palmer
cee1202fd9 Merge branch 'martinbudden-belt_test_corexy' 2020-11-14 17:20:18 +00:00
Chris Palmer
6e342441c6 Added images and readme. 2020-11-14 17:19:18 +00:00
Chris Palmer
072c38f955 Enabled the two belt version. 2020-11-14 17:18:08 +00:00
Chris Palmer
b342549d74 Merge branch 'belt_test_corexy' of https://github.com/martinbudden/NopSCADlib into martinbudden-belt_test_corexy 2020-11-14 17:00:11 +00:00
Chris Palmer
2b83a15e5d Merge branch 'martinbudden-BTT_TFT35v3' 2020-11-14 14:44:01 +00:00
Chris Palmer
ab81c6538c Updated images and readme. 2020-11-14 14:41:27 +00:00
Chris Palmer
27b0a442e4 Changed the order to avoid a clash with fans. 2020-11-14 14:32:23 +00:00
Martin Budden
5415beb80d Added BigTreeTech TFT35 v 3.0 display. 2020-11-14 14:13:53 +00:00
Martin Budden
040985c0db Converted belts test to coreXY. 2020-11-14 09:40:37 +00:00
Chris Palmer
0216093a68 Added printed camera housings. 2020-11-13 22:43:55 +00:00
Chris
30302431c0 Merge pull request #94 from martinbudden/carbon_tube_fix
Fix to centering of carbon fiber tubing.
2020-11-13 19:35:14 +00:00
Chris Palmer
1fb429e9a5 Merge branch 'martinbudden-shaft_couplings' 2020-11-13 19:32:03 +00:00
Chris Palmer
9571e68629 Updated lib.scad, images and readme. 2020-11-13 19:31:49 +00:00
Chris Palmer
b01e6a673c type[0] should be the name of the constant. 2020-11-13 19:30:46 +00:00
Martin Budden
9239c6da3c Fix to centering of carbon fiber tubing. 2020-11-13 19:27:02 +00:00
Chris Palmer
ba5e5fa390 Used tube.scad to shorten code. 2020-11-13 18:55:26 +00:00
Chris Palmer
c7dfdd0fb9 Merge branch 'shaft_couplings' of https://github.com/martinbudden/NopSCADlib into martinbudden-shaft_couplings 2020-11-13 18:11:29 +00:00
Chris Palmer
814ce4f15d Merge branch 'martinbudden-bowden_connector' 2020-11-13 17:59:17 +00:00
Chris Palmer
f661cf6934 Updated images and readme 2020-11-13 17:57:13 +00:00
Chris Palmer
305d2146f2 Colours passed to thread need to be numeric, not strings. 2020-11-13 17:51:30 +00:00
Chris Palmer
e39ee1797d Merge branch 'bowden_connector' of https://github.com/martinbudden/NopSCADlib into martinbudden-bowden_connector 2020-11-13 17:45:47 +00:00
Chris Palmer
520569cb30 Made small idler pulley 6.5mm by default and added a 7mm one. 2020-11-13 13:55:15 +00:00
Chris Palmer
f73a7b46a2 Merge branch 'martinbudden-carbon_fiber_tube' 2020-11-13 10:51:24 +00:00
Chris Palmer
fb9eca85c6 Updated images and readme. 2020-11-13 10:50:29 +00:00
Martin Budden
166ed05d4a Add optional bowden connector to E3D hotends. 2020-11-13 10:21:38 +00:00
Chris Palmer
ce6aec428d Merge branch 'carbon_fiber_tube' of https://github.com/martinbudden/NopSCADlib into martinbudden-carbon_fiber_tube 2020-11-13 10:03:15 +00:00
Chris Palmer
4e9d169c31 Updated cover pic 2020-11-13 09:57:17 +00:00
Martin Budden
1810160103 Added carbon fiber tubing with woven pattern. 2020-11-13 09:35:56 +00:00
Chris Palmer
0c9ae8d60c PCBs now drawn before components so that transparent LEDs draw correctly. 2020-11-13 09:24:15 +00:00
Chris Palmer
9a0bad4e61 Made stepper motor encap paramatric.
Made connector position based on encap height and added PCB.
2020-11-12 23:36:35 +00:00
Chris Palmer
90047815b0 Added JST PH connectors.
Made jst_xh_header() more parametric and corrected pin positions.
2020-11-12 23:34:59 +00:00
Martin Budden
b583202fb7 Added hole for grub screw to shaft coupling. 2020-11-10 14:49:11 +00:00
Chris Palmer
eac0086199 tests.py now allows parts of projects to be tested without finding an implementation. 2020-11-10 12:01:57 +00:00
Martin Budden
03beaec470 Initial submission of shaft couplings vitamin. 2020-11-10 09:11:30 +00:00
Chris Palmer
51c649cc53 Merge branch 'martinbudden-tests_script' 2020-11-09 16:19:45 +00:00
Chris Palmer
5fa33d7c4d Tests.py now works in projects and makes tests.md and tests.html.
NopSCADlib blurb now scraped from libtest.scad.
libtest.scad no longer required and lack of it is used to detect a project.
2020-11-09 16:17:02 +00:00
Chris Palmer
78ce51d045 Merge branch 'tests_script' of https://github.com/martinbudden/NopSCADlib into martinbudden-tests_script 2020-11-08 21:36:56 +00:00
Chris Palmer
23cbadf6df Merge branch 'martinbudden-stepper_motor_jst_connector' 2020-11-08 21:29:03 +00:00
Chris Palmer
c9c2ffafba Fixed connector position, fixed missing wires, updated images.
Reverted the jst header pin position change.
2020-11-08 21:28:08 +00:00
Martin Budden
2e0e833d40 Made jst_connector a parameter to NEMA. 2020-11-08 15:14:19 +00:00
Martin Budden
6c51f8726c Updated tests.py to better support generic testing. 2020-11-08 14:56:52 +00:00
Martin Budden
0b035dbd15 Added optional jst connector to stepper motors. 2020-11-08 12:20:15 +00:00
Chris Palmer
34b58e3b64 Added convexity parameter to sweep. 2020-11-04 22:27:31 +00:00
Chris Palmer
df43fe7dc6 Added list and string slicing. 2020-11-04 21:44:07 +00:00
Chris Palmer
b5fe03fcb2 Test image pixel differences due to switch to winter computer 2020-11-04 20:48:22 +00:00
Chris Palmer
1658f6f0b4 Sweep can now cope with the start having colinear points. 2020-11-04 19:56:51 +00:00
Chris Palmer
7b126f9792 More spelling 2020-11-04 19:50:35 +00:00
Chris Palmer
479207fd4f Spelling 2020-11-04 10:52:57 +00:00
Chris Palmer
3ee55981f9 Comment spelling. 2020-10-05 12:02:54 +01:00
Chris Palmer
8c2b4a20fe Added tesrdrop_minus() and horicylinder(). 2020-10-05 10:59:50 +01:00
Chris Palmer
1529759406 Fixes for lazy union. 2020-10-05 10:42:13 +01:00
Chris Palmer
c4a986aa21 Test for circle_intersect() 2020-10-05 10:41:27 +01:00
Chris Palmer
ebee729d08 Added MP1584EN PCB. Melzi no longer displayed. 2020-10-05 10:40:43 +01:00
Chris Palmer
90e7f1a315 Added circle_intersect() calculation to maths.scad. 2020-10-04 22:01:08 +01:00
Chris Palmer
e39af154bb Fixed use of intersection with conditional argument to suit new OpenSCAD behaviour. 2020-10-03 15:53:41 +01:00
Chris Palmer
933fea687c Removed debug code 2020-09-20 09:07:01 +01:00
Chris Palmer
a7803b1efb Improved numerical accuarcy of catenary calculations. 2020-09-19 23:52:57 +01:00
Chris Palmer
1255e71271 Added catenary curves. 2020-09-19 12:11:54 +01:00
Chris Palmer
b11c5914b3 Added hyperbolic maths functions 2020-09-15 20:58:39 +01:00
Chris Palmer
ac60057801 Fixes for additional warnings in OpenSCAD 2020.09.12.ci5914 2020-09-14 22:54:55 +01:00
Chris Palmer
332933a4fd Made ribbon_clamps parametric on screw size. 2020-09-11 19:53:14 +01:00
Chris Palmer
6b0132c32e Added chamfer option to poly_cylinder(). 2020-09-11 12:36:37 +01:00
Chris Palmer
afac5f9737 Added PCB components to OpenGrab and functions to access PCB. 2020-09-11 12:35:22 +01:00
Chris Palmer
8d8df3cb8a Added 4.5mm button to PCBs. 2020-09-11 12:30:00 +01:00
Chris Palmer
81eb183db9 Fixed PCB cutout for right angle pin headers. 2020-09-11 12:24:07 +01:00
Chris Palmer
c99ed98a64 Can now have right angle pin headers on PCBs.
Fixed bugs right angle pin headers with rows not equal to two.
Added more tests for pin headers.
2020-09-11 00:20:28 +01:00
Chris Palmer
7f65e5d539 Added M2 dome head screws. 2020-09-10 18:38:24 +01:00
Chris Palmer
ffb7f87cc5 Fixed typo in insert name. 2020-09-10 18:27:56 +01:00
Chris Palmer
d0513c7299 Bodge to jhead to allow the ziptie and sleaving to be removed by setting naked to undef. 2020-09-06 12:33:44 +01:00
Chris Palmer
d1429a3b7d Verboard can now have components on the underside, same as PCBs. 2020-09-06 12:32:42 +01:00
Chris Palmer
70513993bd Can now put wire links on PCBs 2020-09-06 12:31:41 +01:00
Chris Palmer
9eb35accfd Updated fan_guard picture. 2020-09-06 11:59:32 +01:00
Chris Palmer
7276f18566 Spacing 2020-09-06 11:56:55 +01:00
Chris Palmer
d944198dc4 25mm fans are actually 25.4, i.e. 1". 2020-09-06 11:55:58 +01:00
Chris Palmer
04f2499a9e Moved no_point(str) from belt.scad to global.scad 2020-09-06 11:51:33 +01:00
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
199 changed files with 5229 additions and 1129 deletions

View File

@@ -18,7 +18,7 @@
//
//
// Include this file to use the miniumum library plus screws, nuts and washers
// Include this file to use the minimum library plus screws, nuts and washers
//
include <utils/core/core.scad>
//

View File

@@ -52,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);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 179 KiB

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: 230 KiB

After

Width:  |  Height:  |  Size: 236 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 242 KiB

After

Width:  |  Height:  |  Size: 178 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 199 KiB

After

Width:  |  Height:  |  Size: 202 KiB

View File

@@ -33,7 +33,7 @@ $exploded = is_undef($explode) ? 0 : $explode; // 1 f
layer_height = is_undef($layer_height) ? 0.25 : $layer_height; // layer heigth when printing
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
cnc_bit_r = is_undef($cnc_bit_r) ? 1.2 : $cnc_bit_r; // minimum tool radius when milling 2D objects
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
@@ -52,14 +52,7 @@ $fs = extrusion_width / 2;
function round_to_layer(z) = ceil(z / layer_height) * layer_height;
// Some additional named colours
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];
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];

View File

@@ -29,6 +29,7 @@ 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>
@@ -40,10 +41,12 @@ include <vitamins/inserts.scad>
include <vitamins/kp_pillow_blocks.scad>
include <vitamins/ldrs.scad>
include <vitamins/leadnuts.scad>
include <vitamins/leds.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>
@@ -51,11 +54,13 @@ include <vitamins/ring_terminals.scad>
include <vitamins/rails.scad>
include <vitamins/rod.scad>
include <vitamins/scs_bearing_blocks.scad>
include <vitamins/shaft_couplings.scad>
include <vitamins/sheets.scad>
include <vitamins/sk_brackets.scad>
include <vitamins/spools.scad>
include <vitamins/ssrs.scad>
include <vitamins/stepper_motors.scad>
include <vitamins/swiss_clips.scad>
include <vitamins/toggles.scad>
include <vitamins/transformers.scad>
include <vitamins/tubings.scad>
@@ -63,7 +68,6 @@ include <vitamins/variacs.scad>
include <vitamins/zipties.scad>
use <vitamins/jack.scad>
use <vitamins/meter.scad>
use <vitamins/fuseholder.scad>
use <vitamins/hygrometer.scad>
@@ -82,6 +86,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>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 780 KiB

After

Width:  |  Height:  |  Size: 839 KiB

View File

@@ -17,6 +17,23 @@
// If not, see <https://www.gnu.org/licenses/>.
//
//!# NopSCADlib
//! An ever expanding library of parts modelled in OpenSCAD useful for 3D printers and enclosures for electronics, etc.
//!
//! It contains lots of vitamins (the RepRap term for non-printed parts), some general purpose printed parts and some utilities.
//! There are also Python scripts to generate Bills of Materials (BOMs),
//! STL files for all the printed parts, DXF files for CNC routed parts in a project and a manual containing assembly
//! instructions and exploded views by scraping markdown embedded in OpenSCAD comments, [see scripts](scripts/readme.md).
//!
//! A simple example project can be found [here](examples/MainsBreakOutBox/readme.md).
//!
//! For more examples of what it can make see the [gallery](gallery/readme.md).
//!
//! The license is GNU General Public License v3.0, see [COPYING](COPYING).
//!
//! See [usage](docs/usage.md) for requirements, installation instructions and a usage guide.
//!
//! <img src="libtest.png" width="100%"/>
//
// This file shows all the parts in the library.
//
@@ -29,6 +46,8 @@ use <tests/blowers.scad>
use <tests/bulldogs.scad>
use <tests/buttons.scad>
use <tests/cable_strips.scad>
use <tests/cameras.scad>
use <tests/camera_housing.scad>
use <tests/circlips.scad>
use <tests/components.scad>
use <tests/d_connectors.scad>
@@ -48,12 +67,14 @@ 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/panel_meters.scad>
use <tests/PCBs.scad>
use <tests/pillars.scad>
use <tests/PSUs.scad>
@@ -65,12 +86,14 @@ use <tests/rod.scad>
use <tests/screws.scad>
use <tests/SCS_bearing_blocks.scad>
use <tests/sealing_strip.scad>
use <tests/shaft_couplings.scad>
use <tests/sheets.scad>
use <tests/SK_brackets.scad>
use <tests/spades.scad>
use <tests/springs.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>
@@ -101,7 +124,7 @@ use <tests/SSR_shroud.scad>
use <tests/PSU_shroud.scad>
x0 = 0;
x1 = x0 + 100;
x1 = x0 + 110;
x2 = x1 + 90;
x3 = x2 + 130;
x4 = x3 + 200;
@@ -113,17 +136,17 @@ cable_grommets_y = 0;
translate([x5, cable_grommets_y])
cable_grommets();
translate([x5, cable_grommets_y + 50])
feet();
translate([x5 + 80, cable_grommets_y])
ribbon_clamps();
translate([x5, cable_grommets_y + 75])
translate([x5, cable_grommets_y + 60])
fixing_blocks();
translate([x5, cable_grommets_y + 100])
translate([x5, cable_grommets_y + 90])
corner_blocks();
translate([x5, cable_grommets_y + 150])
ribbon_clamps();
feet();
translate([x5 + 70, cable_grommets_y + 150])
screw_knobs();
@@ -165,8 +188,8 @@ 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 + 100;
@@ -176,7 +199,7 @@ fans_y = displays_y + 80;
transformers_y = fans_y + 120;
psus_y = transformers_y + 190;
translate([x0 + 30, inserts_y])
translate([x0 + 35, inserts_y])
inserts();
translate([x0, inserts_y])
@@ -209,10 +232,7 @@ translate([x0, tubings_y])
translate([x0, pillars_y])
pillars();
translate([x0, leadnuts_y ])
leadnuts();
translate([x0 + 60, leadnuts_y])
translate([x0, ball_bearings_y])
ball_bearings();
translate([x0, pulleys_y])
@@ -252,7 +272,9 @@ translate([x0, psus_y]) {
}
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();
@@ -260,10 +282,18 @@ translate([x1, zipties_y])
translate([x1, bulldogs_y])
bulldogs();
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;
@@ -273,16 +303,19 @@ components_y = toggles_y + 40;
translate([x2, leds_y])
leds();
translate([x2 + 40, leds_y])
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])
@@ -314,7 +347,8 @@ ssrs_y = modules_y + 80;
blowers_y = ssrs_y + 60;
batteries_y = blowers_y + 100;
steppers_y = batteries_y + 70;
extrusions_y = steppers_y + 100;
panel_meters_y = steppers_y + 70;
extrusions_y = panel_meters_y + 80;
translate([x3, veroboard_y])
veroboard_test();
@@ -325,9 +359,15 @@ translate([x3 + 70, veroboard_y + 30])
translate([x3 + 140, veroboard_y + 20])
pcb_mounts();
translate([x3 + 170, veroboard_y + 16])
cameras();
translate([x3, d_connectors_y])
d_connectors();
translate([x3 + 170, d_connectors_y - 10])
camera_housings();
translate([x3, iecs_y])
iecs();
@@ -355,9 +395,11 @@ translate([x3, batteries_y])
translate([x2, steppers_y]) // interloper
stepper_motors();
translate([x2, extrusions_y]) {
translate([x2, panel_meters_y])
panel_meters();
translate([x2, extrusions_y])
extrusions();
}
translate([x3, transformers_y])
transformers();
@@ -370,7 +412,7 @@ 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 + 150, belts_y + 58]) {
translate([x4 + 200, belts_y + 58]) {
belt_test();
translate([0, 60])
@@ -392,6 +434,9 @@ translate([x4, sk_brackets_y])
translate([x4, extrusion_brackets_y])
extrusion_brackets();
translate([x4 + 120, extrusion_brackets_y])
shaft_couplings();
translate([x4, scs_bearing_blocks_y])
scs_bearing_blocks();

View File

@@ -31,26 +31,29 @@
//!
//! Normally the side sheets are the same type but they can be overridden individually as long as the substitute has the same thickness.
//
include <../utils/core/core.scad>
include <../core.scad>
use <../vitamins/sheet.scad>
use <../vitamins/screw.scad>
use <../vitamins/washer.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;
@@ -59,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));
@@ -87,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.
@@ -175,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];
@@ -258,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);
@@ -336,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)
@@ -396,7 +419,6 @@ module box_bezel_section(type, bottom, rows, cols, x, y) { //! Generates interlo
}
}
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 +461,96 @@ module box_shelf_blank(type, sheet = false) { //! Generates a 2D template for a
}
}
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

@@ -50,6 +50,9 @@ function bbox_name(type) = type[8] ? type[8] : "bbox"; //! Optional name i
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;
@@ -107,12 +110,9 @@ function fixing_block_positions(type) = let(
function side_holes(type) = [for(p = fixing_block_positions(type), q = fixing_block_holes(bbox_screw(type))) p * q];
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(str(bbox_name(type), "_base"));
@@ -120,7 +120,7 @@ module bbox_base_blank(type) { //! 2D template for the 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));
}
}
@@ -133,7 +133,7 @@ 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));
}
}
@@ -151,7 +151,7 @@ module bbox_left_blank(type, sheet = false) { //! 2D template for the left side
translate([-t / 2, -bb / 2])
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]));
}
}
@@ -165,7 +165,7 @@ module bbox_right_blank(type, sheet = false) { //! 2D template for the right sid
translate([t / 2, -bb / 2])
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]));
}
}
@@ -180,7 +180,7 @@ module bbox_front_blank(type, sheet = false, width = 0) { //! 2D template for th
translate([0, (bt - bb) / 2])
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]));
}
}
@@ -194,7 +194,7 @@ module bbox_back_blank(type, sheet = false) { //! 2D template for the back
translate([0, -bb / 2])
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]));
}
}

392
printed/camera_housing.scad Normal file
View File

@@ -0,0 +1,392 @@
//
// 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/>.
//
//
//! Housings for PCB cameras.
//
include <../core.scad>
include <../vitamins/cameras.scad>
use <../vitamins/pcb.scad>
use <../vitamins/insert.scad>
wall = 1.75;
min_wall = 2 * extrusion_width;
clearance = 0.2;
connector_size = [23, 6, 2.65]; // Worst case size of flat flex connector
cam_back_clearance = round_to_layer(1.5); // Clearance for components on the back of the pcb
cam_back_overlap = 1; // How much the back overlaps the edge of the pcb
cam_back_wall = min_wall;
function cam_front_clearance(cam) = round_to_layer(camera_connector_size(cam).z + clearance);
function cam_back_size(cam) = let(
pcb = camera_pcb(cam),
pcb_size = pcb_size(pcb),
nut = screw_nut(pcb_screw(pcb)),
holes = [for(h = pcb_holes(pcb)) pcb_coord(pcb, h).x],
pitch = max(holes) - min(holes),
length = pitch + 2 * (nut_radius(nut) + min_wall),
width = pcb_size.y + (length - pcb_size.x) * cos(30)
) [length, width, wall + max(connector_size.z, cam_back_clearance + nut_trap_depth(nut))];
function cam_front_size(cam) = cam_back_size(cam) + [ //! Outside dimensions of the case
2 * (wall + clearance),
2 * (wall + clearance),
pcb_thickness(camera_pcb(cam)) + cam_front_clearance(cam) + wall
];
hinge_screw = M2_cap_screw;
hinge_nut = screw_nut(hinge_screw);
hinge_screw_length = 12;
hinge_r = nut_trap_radius(hinge_nut) + 3 * extrusion_width;
hinge_h = wall + nut_trap_depth(hinge_nut);
hinge_offset = hinge_r + 1;
bracket_screw = M3_dome_screw;
function cam_screw_length(cam) = let(
front = cam_front_size(cam),
screw = pcb_screw(camera_pcb(cam)),
nut = screw_nut(screw)
) screw_longer_than(front.z + washer_thickness(screw_washer(screw)) - nut_trap_depth(nut) + nut_thickness(nut, true));
function hinge_z(cam) = cam_screw_length(cam) - hinge_r;
module cam_holes(cam) {
pcb = camera_pcb(cam);
lens_y = camera_lens_offset(cam).y;
two_holes = !!len([for (h = pcb_holes(pcb)) if(abs(pcb_coord(pcb, h).y - lens_y) < 1) true]);
pcb_screw_positions(pcb) // screw holes
if($i > 1 || !two_holes)
children();
}
module rpi_camera_focus_ring_stl() { //! Focus ring the glue onto RPI lens
stl("rpi_camera_focus_ring");
rad = 15 / 2;
hole_r1 = 2.5 / 2;
hole_r2 = 5 / 2;
thickness = 3;
flutes = 8;
angle = 180 / flutes;
x = rad / (sin(angle / 2) + cos(angle / 2));
r = x * sin(angle / 2);
difference() {
linear_extrude(height = thickness, convexity = 5)
difference() {
union() {
circle(x);
for(i = [0 : flutes - 1])
rotate([0, 0, 2 * angle * i])
translate([x, 0])
circle(r);
}
for(i = [0 : flutes - 1])
rotate([0, 0, 2 * angle * i + angle])
translate([x, 0])
circle(r);
}
hull() {
poly_cylinder(r = hole_r1, h = 0.1, center = true);
translate([0, 0, thickness])
poly_cylinder(r = hole_r2, h = 0.1, center = true);
}
}
}
module camera_back(cam) { //! Make the STL for a camera case back
stl(str("camera_back_", cam[0]));
pcb = camera_pcb(cam);
back = cam_back_size(cam);
screw = pcb_screw(pcb);
nut = screw_nut(screw);
translate_z(back.z)
hflip()
difference() {
translate_z(back.z / 2)
cube(back, center = true);
translate([0, -cam_back_overlap])
cube([pcb_length(pcb) - 2 * cam_back_overlap, pcb_width(pcb), 2 * cam_back_clearance], center = true);
translate([0, -pcb_width(pcb) / 2])
cube([connector_size.x + 2 * clearance, 2 * connector_size.y + 1, 2 * round_to_layer(connector_size.z + clearance)], center = true);
translate_z(back.z)
cam_holes(cam)
hflip()
nut_trap(screw, nut, supported = true);
}
}
module camera_front(cam, hinge = 0) { //! Make the STL for a camera case front
stl(str("camera_front_", cam[0]));
front = cam_front_size(cam);
back = cam_back_size(cam);
pcb = camera_pcb(cam);
pcb_size = pcb_size(pcb);
lens_offset = camera_lens_offset(cam);
screw = pcb_screw(pcb);
shelf = front.z - back.z;
connector_slot = connector_size + 2 * [clearance, 0, layer_height];
rad = wall;
led_hole_r = 1;
led_clearance = [5, 2, 1 * 2];
res_clearance = [3.5, 2, 1 * 2];
conn_pos = camera_connector_pos(cam);
conn = camera_connector_size(cam);
sensor_length = conn_pos.y + conn.y / 2 - lens_offset.y + clearance;
module hinge_pos()
if(!is_undef(hinge))
rotate(hinge * 90)
translate([0, (hinge ? front.x * hinge : front.y) / 2 + hinge_offset, hinge_r])
children();
difference() {
union() {
hull()
for(x = [-1, 1], y = [-1, 1])
translate([x * (front.x / 2 - rad), y * (front.y / 2 - rad)])
hull() { // 3D truncated teardrop gives radiused edges without exceeding 45 degree overhang
translate_z(front.z - 1)
cylinder(r = rad, h = 1);
translate_z(rad)
sphere(rad);
cylinder(r = rad * (sqrt(2) - 1), h = eps);
}
hinge_pos()
hull() {
rotate([-90, 0, -90])
teardrop(r = hinge_r, h = hinge_h, center = false);
translate([0, -10, -hinge_r])
cube([hinge_h, eps, 2 * hinge_r]);
}
}
hinge_pos()
rotate([90, 0, 90])
teardrop_plus(r = screw_clearance_radius(hinge_screw), h = 100, center = true);
translate_z(front.z / 2 + shelf - layer_height) // recess for the back
cube([back.x + 2 * clearance, back.y + 2 * clearance, front.z], center = true);
translate_z(front.z / 2 + shelf - pcb_size.z) // recess for PCB
cube([pcb_size.x + 2 * clearance, pcb_size.y + 2 * clearance, front.z], center = true);
translate_z(shelf)
hflip() {
pcb_component_position(pcb, "smd_led") // clearance for LED
cube(led_clearance, center = true);
pcb_component_position(pcb, "smd_res") // clearance for resistor
cube(res_clearance, center = true);
}
translate([conn_pos.x, lens_offset.y + sensor_length / 2, shelf - pcb_size.z]) // clearance for sensor connector
cube([conn.x + 2 * clearance, sensor_length, 2 * cam_front_clearance(cam)], center = true);
translate([0, -front.y / 2, shelf + front.z / 2]) // slot for connector
cube([connector_slot.x, connector_slot.y, front.z], center = true);
translate_z(cam_back_clearance + layer_height)
cam_holes(cam)
rotate(90)
poly_cylinder(r = screw_clearance_radius(screw), h = 100, center = true);
translate_z(shelf - pcb_size.z)
hflip()
camera_lens(cam, clearance);
hflip()
pcb_component_position(pcb, "smd_led")
rotate(45)
poly_cylinder(r = led_hole_r, h = 100, center = true); // hole for led
}
}
function bracket_thickness(cam) = max(wall, min(3.5, hinge_z(cam) - hinge_r - 1));
module camera_bracket_screw_positions(cam) { //! Position children at the bracket screw positions
r = washer_radius(screw_washer(bracket_screw)) + 0.5;
wide = bracket_thickness(cam) == wall;
pitch = wide ? cam_front_size(cam).x / 2 - r : hinge_h + 1 + r;
for(side = [-1, 1])
translate([side * pitch, 0])
children();
}
module camera_bracket_position(cam) //! Position children at the bracket position
translate([0, cam_front_size(cam).y / 2 + hinge_offset])
children();
module camera_bracket(cam) { //! Make the STL for the camera bracket
stl(str("camera_bracket_", cam[0]));
t = bracket_thickness(cam);
z = hinge_z(cam);
translate([hinge_h / 2, 0])
difference() {
hull() {
translate_z(eps / 2)
cube([hinge_h, 2 * hinge_r, eps], center = true);
translate_z(z)
rotate([0, 90, 0])
cylinder(r = hinge_r, h = hinge_h, center = true);
}
translate([hinge_h / 2, 0, z])
rotate([90, 0, 90])
nut_trap(hinge_screw, screw_nut(hinge_screw), horizontal = true);
}
linear_extrude(t)
difference() {
hull()
camera_bracket_screw_positions(cam)
circle(washer_radius(screw_washer(bracket_screw)) + 0.5);
camera_bracket_screw_positions(cam)
poly_circle(screw_clearance_radius(bracket_screw));
}
}
module camera_assembly(cam, angle = 0) //! Camera case assembly
assembly(str("camera_", cam[0])) {
front = cam_front_size(cam);
screw = pcb_screw(camera_pcb(cam));
nut = screw_nut(screw);
screw_length = cam_screw_length(cam);
hinge_z = hinge_z(cam);
hinge_pos = [0, front.y / 2 + hinge_offset, -hinge_r];
camera_bracket_position(cam) {
nut = screw_nut(hinge_screw);
stl_colour(pp1_colour) render()
camera_bracket(cam);
translate([-hinge_h, 0, hinge_z(cam)])
rotate([-90, 0, 90]) {
vflip()
translate_z(2 * hinge_h - nut_trap_depth(nut))
nut(nut, true);
screw_and_washer(hinge_screw, screw_longer_than(2 * hinge_h));
}
}
translate_z(hinge_z(cam) + hinge_r)
translate(hinge_pos)
rotate([-angle, 0, 0])
translate(-hinge_pos) {
translate_z(cam_back_size(cam).z - front.z)
camera(cam);
stl_colour(pp1_colour) render()
translate_z(-front.z)
camera_back(cam);
cam_holes(cam) {
screw_and_washer(screw, screw_length);
translate_z(-front.z + nut_trap_depth(nut))
vflip()
nut(nut, true);
}
*translate(camera_lens_offset(cam))
translate_z(1.5)
stl_colour(pp1_colour) render()
rpi_camera_focus_ring_stl();
stl_colour(pp2_colour) render()
hflip()
camera_front(cam, 0);
}
}
module camera_fastened_assembly(cam, thickness, angle = 0) {
camera_assembly(cam, angle);
camera_bracket_position(cam)
camera_bracket_screw_positions(cam) {
nut = screw_nut(bracket_screw);
washer = screw_washer(bracket_screw);
t = bracket_thickness(cam);
screw_length = screw_longer_than(thickness + t + nut_thickness(nut, true) + 2 * washer_thickness(washer));
vflip()
translate_z(thickness)
screw_and_washer(bracket_screw, screw_length);
translate_z(t)
nut_and_washer(nut, true);
}
}
module camera_back_rpi_camera_stl() camera_back(rpi_camera);
module camera_back_rpi_camera_v1_stl() camera_back(rpi_camera_v1);
module camera_back_rpi_camera_v2_stl() camera_back(rpi_camera_v2);
module camera_front_rpi_camera_stl() camera_front(rpi_camera);
module camera_front_rpi_camera_v1_stl() camera_front(rpi_camera_v1);
module camera_front_rpi_camera_v2_stl() camera_front(rpi_camera_v2);
module camera_bracket_rpi_camera_stl() camera_bracket(rpi_camera);
module camera_bracket_rpi_camera_v1_stl() camera_bracket(rpi_camera_v1);
module camera_bracket_rpi_camera_v2_stl() camera_bracket(rpi_camera_v2);
module camera_rpi_camera_assembly() camera_assembly(rpi_camera);
module camera_rpi_camera_v1_assembly() camera_assembly(rpi_camera_v1);
module camera_rpi_camera_v2_assembly() camera_assembly(rpi_camera_v2);
module camera_housing(cam) {
front = cam_front_size(cam);
camera_front(cam, 0);
translate([front.x, 0])
camera_back(cam);
translate([-front.x / 2 - 2 - hinge_r, 0])
rotate(90)
camera_bracket(cam);
}
cam = rpi_camera_v2;
if($preview)
camera_fastened_assembly(cam, 3);
else
camera_housing(cam);

View File

@@ -74,7 +74,7 @@ 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(thickness)
difference() {
@@ -127,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);
}
}
}

View File

@@ -42,6 +42,9 @@ 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

View File

@@ -24,8 +24,10 @@
include <../core.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 insert_foot() = insert_foot; //! Default foot with insert

View File

@@ -30,6 +30,9 @@ 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
@@ -71,11 +74,11 @@ function pbox_mid_offset(type) = pbox_ridges(type).y + pbox_wall(type) / 2; // O
function pbox_screw_inset(type) = //! How far the base screws are inset
let(foot = pbox_foot(type),
r = foot ? foot_diameter(foot) / 2 : washer_radius(pbox_washer(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) {
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])
@@ -124,6 +127,9 @@ module pbox_inner_shape(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);
@@ -158,7 +164,7 @@ module pbox(type) { //! Generate the STL for the main case
difference() {
union() {
linear_extrude(total_height)
offset(wall / 2) pbox_mid_shape(type);
pbox_outer_shape(type);
if($children > 2)
children(2);

View File

@@ -24,69 +24,72 @@ include <../core.scad>
use <../vitamins/insert.scad>
use <../vitamins/cable_strip.scad>
wall = 2;
wall = 1.6;
min_wall = 2 * extrusion_width;
screw = M3_cap_screw;
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_length(ways) = ribbon_clamp_hole_pitch(ways) + ribbon_clamp_width(); //! Length given ways
function ribbon_clamp_height() = screw_depth + 1; //! Height
function ribbon_clamp_screw_depth(screw = screw) = insert_length(screw_insert(screw)) + 1;
function ribbon_clamp_hole_pitch(ways, screw = screw) =
ribbon_clamp_slot(ways) + 2 * min_wall + 2 * corrected_radius(insert_hole_radius(screw_insert(screw))); //! Hole pitch
module ribbon_clamp_hole_positions(ways, side = undef) //! Place children at hole positions
function ribbon_clamp_width(screw = screw) = 2 * (insert_hole_radius(screw_insert(screw)) + wall); //! Width
function ribbon_clamp_length(ways, screw = screw) = ribbon_clamp_hole_pitch(ways, screw) + ribbon_clamp_width(screw); //! Length given ways
function ribbon_clamp_height(screw = screw) = ribbon_clamp_screw_depth(screw) + 1; //! Height
module ribbon_clamp_hole_positions(ways, screw = screw, side = undef) //! Place children at hole positions
for(x = is_undef(side) ? [-1, 1] : side)
translate([x * ribbon_clamp_hole_pitch(ways) / 2, 0])
translate([x * ribbon_clamp_hole_pitch(ways, screw) / 2, 0])
children();
module ribbon_clamp_holes(ways, h = 20) //! Drill screw holes
ribbon_clamp_hole_positions(ways)
module ribbon_clamp_holes(ways, h = 20, screw = screw) //! Drill screw holes
ribbon_clamp_hole_positions(ways, screw)
drill(screw_clearance_radius(screw), h);
module ribbon_clamp(ways) { //! Generate STL for given number of ways
stl(str("ribbon_clamp_", ways));
module ribbon_clamp(ways, screw = screw) { //! Generate STL for given number of ways
screw_d = screw_radius(screw) * 2;
stl(str("ribbon_clamp_", ways, screw_d != 3 ? str("_", screw_d) : ""));
pitch = ribbon_clamp_hole_pitch(ways);
d = ribbon_clamp_width();
h = ribbon_clamp_height();
t = h - ribbon_clamp_slot_depth() - wall;
pitch = ribbon_clamp_hole_pitch(ways, screw);
d = ribbon_clamp_width(screw);
h = ribbon_clamp_height(screw);
t = round_to_layer(ribbon_clamp_slot_depth() + wall);
insert = screw_insert(screw);
difference() {
union() {
hull() {
translate_z(h - t / 2)
cube([ribbon_clamp_hole_pitch(ways), d, t], center = true);
cube([ribbon_clamp_hole_pitch(ways, screw), d, t], center = true);
translate_z(1)
cube([pitch, max(wall, d - 2 * (h - t)), 2], center = true);
}
ribbon_clamp_hole_positions(ways, -1)
ribbon_clamp_hole_positions(ways, screw, -1)
cylinder(d = d, h = h);
ribbon_clamp_hole_positions(ways, 1)
ribbon_clamp_hole_positions(ways, screw, 1)
cylinder(d = d, h = h);
}
translate_z(h)
cube([ribbon_clamp_slot(ways), d + 1, ribbon_clamp_slot_depth() * 2], center = true);
ribbon_clamp_hole_positions(ways)
ribbon_clamp_hole_positions(ways, screw)
translate_z(h)
rotate(22.5)
insert_hole(insert, screw_depth - insert_length(insert));
insert_hole(insert, ribbon_clamp_screw_depth(screw) - insert_length(insert));
}
}
module ribbon_clamp_assembly(ways) pose([55, 180, 25]) //! Printed part with inserts in place
assembly(str("ribbon_clamp_", ways)) {
h = ribbon_clamp_height();
module ribbon_clamp_assembly(ways, screw) pose([55, 180, 25]) //! Printed part with inserts in place
assembly(let(screw_d = screw_radius(screw) * 2)str("ribbon_clamp_", ways, screw_d != 3 ? str("_", screw_d) : "")) {
h = ribbon_clamp_height(screw);
insert = screw_insert(screw);
stl_colour(pp1_colour) render()
translate_z(h) vflip() ribbon_clamp(ways);
translate_z(h) vflip() ribbon_clamp(ways, screw);
ribbon_clamp_hole_positions(ways)
ribbon_clamp_hole_positions(ways, screw)
vflip()
insert(insert);
}
@@ -99,20 +102,24 @@ module ribbon_clamp_fastened_assembly(ways, thickness, screw = screw) { //! Clam
vitamin(str(": Tape self amalgamating silicone ",tape_l," x 25mm"));
washer = screw_washer(screw);
screw_length = screw_shorter_than(2 * washer_thickness(washer) + thickness + screw_depth);
screw_length = screw_shorter_than(2 * washer_thickness(washer) + thickness + ribbon_clamp_screw_depth(screw));
ribbon_clamp_assembly(ways);
ribbon_clamp_assembly(ways, screw);
color("red") translate_z(tape_thickness / 2)
cube([tape_l, tape_width, tape_thickness], center = true);
ribbon_clamp_hole_positions(ways)
ribbon_clamp_hole_positions(ways, screw)
vflip()
translate_z(thickness)
screw_and_washer(screw, screw_length, true);
}
module ribbon_clamp_20_stl() ribbon_clamp(20);
module ribbon_clamp_8_2_stl() ribbon_clamp(8, M2_dome_screw);
//! * Place inserts into the holes and press home with a soldering iron with a conical bit heated to 200&deg;C.
module ribbon_clamp_20_assembly() ribbon_clamp_assembly(20);
//! * Place inserts into the holes and press home with a soldering iron with a conical bit heated to 200&deg;C.
module ribbon_clamp_8_2_assembly() ribbon_clamp_assembly(8, M2_dome_screw);

View File

@@ -135,7 +135,7 @@ module ssr_shroud_fastened_assembly(type, cable_d, thickness, name) //! Assembly
*translate_z(cable_d / 2)
rotate([90, 0, 0])
stl_colour(grey20)
stl_colour(grey(20))
cylinder(d = cable_d, h = 20, center = true);
}
}

View File

@@ -24,8 +24,7 @@
include <../core.scad>
use <../vitamins/insert.scad>
strap = [18, 2, M3_pan_screw, 3, 25];
function strap() = strap;
strap = strap();
wall = 2;
clearance = 0.5;
@@ -40,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

1006
readme.md

File diff suppressed because it is too large Load Diff

View File

@@ -213,7 +213,7 @@ def parse_bom(file = "openscad.log", name = None):
main.assemblies[stack[-1]].add_part(s)
else:
if 'ERROR:' in line or 'WARNING:' in line:
print(line[:-1])
raise Exception(line[:-1])
return main
def usage():
@@ -221,53 +221,57 @@ def usage():
sys.exit(1)
def boms(target = None, assembly = None):
bom_dir = set_config(target, usage) + "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", "--hardwarnings", "-o", "openscad.echo", "-d", bom_dir + "/bom.deps", 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__':
if len(sys.argv) > 3: usage()
@@ -286,8 +290,4 @@ if __name__ == '__main__':
if assembly:
if assembly[-9:] != "_assembly": usage()
try:
boms(target, assembly)
except Exception as e:
print(str(e))
sys.exit(1)
boms(target, assembly)

View File

@@ -27,6 +27,7 @@ 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" }
@@ -38,43 +39,54 @@ def plateup(target, part_type, usage = None):
top_dir = set_config(target, usage)
parts_dir = top_dir + part_type + 's'
target_dir = parts_dir + '/' + target_dirs[part_type]
source_dir = top_dir + source_dirs[part_type]
deps_dir = source_dir + "/deps"
if not os.path.isdir(source_dir):
return
if not os.path.isdir(target_dir):
os.makedirs(target_dir)
if not os.path.isdir(deps_dir):
os.makedirs(deps_dir)
source_dir1 = source_dirs[part_type]
source_dir2 = top_dir + source_dirs[part_type]
#
# Decide which files to make
#
sources = [file for file in os.listdir(source_dir) if file.endswith('.scad')]
#
# Run OpenSCAD on the source files to make the targets
# Loop through source directories
#
used = []
for src in sources:
src_file = source_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)
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)
#
# Add the files on the BOM to the used list
# Make the deps dir
#
with open(log_name) as file:
for line in file.readlines():
if line.startswith('ECHO: "~') and line.endswith('.' + part_type + '"\n'):
used.append(line[8:-2])
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
#
@@ -90,7 +102,7 @@ def plateup(target, part_type, usage = None):
#
# Remove any cruft
#
targets = [file[:-4] + part_type for file in sources]
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:

View File

@@ -30,7 +30,7 @@ def usage():
sys.exit(1)
if __name__ == '__main__':
if len(sys.argv) > 2: usage()
if len(sys.argv) > 2: usage()
if len(sys.argv) > 1:
target = sys.argv[1]

View File

@@ -97,7 +97,6 @@ def tests(tests):
for dir in [deps_dir, png_dir, bom_dir]:
if not os.path.isdir(dir):
os.makedirs(dir)
doc_name = "readme.md"
index = {}
bodies = {}
done = []
@@ -108,19 +107,33 @@ def tests(tests):
#
png_name = "libtest.png"
scad_name = "libtest.scad"
if not os.path.isfile(png_name):
openscad.run(colour_scheme, "--projection=p", "--imgsize=%d,%d" % (w, h), "--camera=0,0,0,50,0,340,500", "--autocenter", "--viewall", "-o", png_name, scad_name);
do_cmd(["magick", png_name, "-trim", "-resize", "1280", "-bordercolor", background, "-border", "10", png_name])
if os.path.isfile(scad_name):
libtest = True
lib_blurb = scrape_blurb(scad_name)
if not os.path.isfile(png_name):
openscad.run(colour_scheme, "--projection=p", "--imgsize=%d,%d" % (w, h), "--camera=0,0,0,50,0,340,500", "--autocenter", "--viewall", "-o", png_name, scad_name);
do_cmd(["magick", png_name, "-trim", "-resize", "1280", "-bordercolor", background, "-border", "10", png_name])
else:
#
# Project tests so just a title
#
libtest = False
project = ' '.join(word[0].upper() + word[1:] for word in os.path.basename(os.getcwd()).split('_'))
lib_blurb = '#' + project + ' Tests\n'
doc_base_name = "readme" if libtest else "tests"
doc_name = doc_base_name + ".md"
#
# List of individual part files
#
scads = [i for i in sorted(os.listdir(scad_dir), key = lambda s: s.lower()) if i[-5:] == ".scad"]
scads = [i for i in sorted(os.listdir(scad_dir), key = lambda s: s.lower()) if i[-5:] == ".scad"]
types = []
for scad in scads:
base_name = scad[:-5]
if not tests or base_name in tests:
done.append(base_name)
print(base_name)
print('\n'+base_name)
cap_name = base_name[0].capitalize() + base_name[1:]
base_name = base_name.lower()
scad_name = scad_dir + '/' + scad
@@ -132,29 +145,42 @@ def tests(tests):
if is_plural(base_name) and os.path.isfile(vits_name):
objects_name = vits_name
locations = [
('vitamins/' + depluralise(base_name) + '.scad', 'Vitamins'),
('printed/' + base_name + '.scad', 'Printed'),
('utils/' + base_name + '.scad', 'Utilities'),
('utils/core/' + base_name + '.scad', 'Core Utilities'),
]
locations = []
if os.path.isdir('vitamins'):
locations.append(('vitamins/' + depluralise(base_name) + '.scad', 'Vitamins'))
if os.path.isdir('printed'):
locations.append(('printed/' + base_name + '.scad', 'Printed'))
if os.path.isdir('utils'):
locations.append(('utils/' + base_name + '.scad', 'Utilities'))
if libtest and os.path.isdir('utils/core'):
locations.append(('utils/core/' + base_name + '.scad', 'Core Utilities'))
for name, type in locations:
if os.path.isfile(name):
impl_name = name
break
else:
print("Can't find implementation!")
continue
if libtest:
print("Can't find implementation!")
continue
else:
type = 'Tests' # OK when testing part of a project
impl_name = None
vsplit = "AKR" + chr(ord('Z') + 1)
vtype = locations[0][1]
types = [vtype + ' ' + vsplit[i] + '-' + chr(ord(vsplit[i + 1]) - 1) for i in range(len(vsplit) - 1)] + [loc[1] for loc in locations[1 :]]
if type == vtype:
for i in range(1, len(vsplit)):
if cap_name[0] < vsplit[i]:
type = types[i - 1]
break
if libtest:
vsplit = "AJR" + chr(ord('Z') + 1)
vtype = locations[0][1]
types = [vtype + ' ' + vsplit[i] + '-' + chr(ord(vsplit[i + 1]) - 1) for i in range(len(vsplit) - 1)] + [loc[1] for loc in locations[1 :]]
if type == vtype:
for i in range(1, len(vsplit)):
if cap_name[0] < vsplit[i]:
type = types[i - 1]
break
else:
if not types:
types = [loc[1] for loc in locations] # No need to split up the vitamin list
if not type in types: # Will happen when implementation is not found and type is set to Tests
types.append(type)
for t in types:
if not t in bodies:
@@ -201,7 +227,7 @@ def tests(tests):
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.lower())
changed = times.check_have_time(changed, scad_name)
changed = options.have_changed(changed, oldest)
if changed:
print(changed)
@@ -250,24 +276,7 @@ def tests(tests):
usage()
with open(doc_name, "wt") as doc_file:
print('# NopSCADlib', file = doc_file)
print('''\
An ever expanding library of parts modelled in OpenSCAD useful for 3D printers and enclosures for electronics, etc.
It contains lots of vitamins (the RepRap term for non-printed parts), some general purpose printed parts and
some utilities. There are also Python scripts to generate Bills of Materials (BOMs),
STL files for all the printed parts, DXF files for CNC routed parts in a project and a manual containing assembly
instructions and exploded views by scraping markdown embedded in OpenSCAD comments, [see scripts](scripts/readme.md). A simple example project can be found [here](examples/MainsBreakOutBox/readme.md).
For more examples of what it can make see the [gallery](gallery/readme.md).
The license is GNU General Public License v3.0, see [COPYING](COPYING).
See [usage](docs/usage.md) for requirements, installation instructions and a usage guide.
<img src="libtest.png" width="100%"/>\n
''', file = doc_file)
print(lib_blurb, file = doc_file)
print('## Table of Contents<a name="top"/>', file = doc_file)
print('<table><tr>', file = doc_file)
n = 0
@@ -288,10 +297,10 @@ See [usage](docs/usage.md) for requirements, installation instructions and a usa
for type in types:
for line in bodies[type]:
print(line, file = doc_file)
with open("readme.html", "wt") as html_file:
do_cmd("python -m markdown -x tables readme.md".split(), html_file)
with open(doc_base_name + ".html", "wt") as html_file:
do_cmd(("python -m markdown -x tables " + doc_name).split(), html_file)
times.print_times()
do_cmd('codespell -L od readme.md'.split())
do_cmd(('codespell -L od ' + doc_name).split())
if __name__ == '__main__':
for arg in 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():

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();

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

@@ -19,6 +19,9 @@
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>
@@ -31,7 +34,7 @@ TMC2130 = ["TMC2130", "TMC2130",
[
[ 10, 1, 0, "-2p54header", 8, 1 ,undef, "blue" ],
[ 10, 13, 0, "-2p54header", 8, 1],
[ 12, 7, 0, "-chip", 6, 4, 1, grey20 ],
[ 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 ],
@@ -55,35 +58,54 @@ test_pcb = ["TestPCB", "Test PCB",
// components
[
[ 20, -5, 180, "trimpot10"],
[ 20, -15, 0, "trimpot10", true],
[ 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, undef, "blue" ],
[ 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, undef, undef, undef, "red" ],
[ 10, 40, 0, "chip", 10, 5, 1, grey20],
[ 10, 60, 180, "rj45"],
[ 8, 80, 180, "usb_A"],
[ 8, 100, 180, "usb_Ax2"],
[ 3, 120, 180, "usb_uA"],
[ 8, 140, 180, "usb_B"],
[ 5, 160, 0, "buzzer", 4.5, 8.5],
[ 20, 160, 0, "buzzer"],
[ 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, 9, 0, "link", inch(0.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, 9, 0, "link", inch(0.2), inch(0.4)],
[ 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, 0, "flat_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, grey20],
[ 63, 70, 180, "term254", 3, undef, grey(20)],
[ 75, 70, 180, "gterm508",2, undef, "blue"],
[ 50, 90, 180, "gterm35", 4, [1,2]],
@@ -93,17 +115,20 @@ test_pcb = ["TestPCB", "Test PCB",
[ 55, 110, 180, "gterm635", 2],
[ 75, 110, 180, "gterm635", 2, undef, "blue"],
[ 90, 110, 180, "gterm", gt_5x17, 2, undef, grey20],
[ 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"],
[ 45, 170, 0, "button_6mm"],
[ 55, 170, 0, "button_4p5mm"],
[ 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, undef, undef, undef, "red" ],
[ 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],

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();

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();

43
tests/axials.scad Normal file
View File

@@ -0,0 +1,43 @@
//
// 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/pcbs.scad>
module axials() {
pcb = PERF60x40;
pcb(pcb);
pcb_grid(pcb, 0, 2)
rotate(90)
wire_link(0.8, inch(0.4));
for(i = [0 : len(ax_resistors) - 1]) {
pcb_grid(pcb, 2 * i + 2, 1 + [0, 0.5, 1.5][i])
rotate(90)
ax_res(ax_resistors[i], [1000, 47000, 8200][i], 5);
pcb_grid(pcb, 2 * i + 2, 6.5)
rotate(-90)
ax_res(ax_resistors[i], [2200, 39000, 8250][i], 1, inch(0.1));
}
}
if($preview)
axials();

View File

@@ -23,49 +23,55 @@ use <../vitamins/insert.scad>
use <../utils/layout.scad>
module belt_test() {
p1 = [75, -50];
p2 = [-75, -50];
p3 = [-75, 100];
p4 = [75, 100];
p5 = [75 - pulley_pr(GT2x20ob_pulley) - pulley_pr(GT2x16_plain_idler), -pulley_pr(GT2x16_plain_idler)];
p6 = [-75 + pulley_pr(GT2x20ob_pulley) + pulley_pr(GT2x16_plain_idler), -pulley_pr(GT2x16_plain_idler)];
p5 = [75 + pulley_pr(GT2x20ob_pulley) - pulley_pr(GT2x16_plain_idler), +pulley_pr(GT2x16_plain_idler)];
p6 = [-75 + pulley_pr(GT2x20ob_pulley) + pulley_pr(GT2x16_plain_idler), -pulley_pr(GT2x16_plain_idler)];
translate(p1) pulley_assembly(GT2x20ob_pulley);
translate(p2) pulley_assembly(GT2x20ob_pulley);
translate(p3) pulley_assembly(GT2x20_toothed_idler);
translate(p4) pulley_assembly(GT2x20_toothed_idler);
module pulleys(flip = false) {
translate(p2) rotate([0, flip ? 180 : 0, 0]) pulley_assembly(GT2x20ob_pulley);
translate(p3) pulley_assembly(GT2x20_toothed_idler);
translate(p4) pulley_assembly(GT2x20_toothed_idler);
translate(p5) {
pulley = GT2x16_toothed_idler;
screw = find_screw(hs_cs_cap, pulley_bore(pulley));
insert = screw_insert(screw);
translate(p5) {
pulley = GT2x16_plain_idler;
screw = find_screw(hs_cs_cap, pulley_bore(pulley));
insert = screw_insert(screw);
pulley_assembly(pulley);
translate_z(pulley_height(pulley) + pulley_offset(pulley) + screw_head_depth(screw, pulley_bore(pulley)))
screw(screw, 20);
translate_z(pulley_offset(pulley) - insert_length(insert))
vflip()
insert(insert);
rotate([0, flip ? 180 : 0, 0]) {
pulley_assembly(pulley);
translate_z(pulley_height(pulley) + pulley_offset(pulley) + screw_head_depth(screw, pulley_bore(pulley)))
screw(screw, 20);
translate_z(pulley_offset(pulley) - insert_length(insert))
vflip()
insert(insert);
}
}
translate(p6) pulley_assembly(GT2x16_plain_idler);
}
translate(p6) pulley_assembly(GT2x16_plain_idler);
path = [ [p1.x, p1.y, pulley_pr(GT2x20ob_pulley)],
[p5.x, p5.y, -pulley_pr(GT2x16_plain_idler)],
path = [ [p5.x, p5.y, pulley_pr(GT2x16_plain_idler)],
[p6.x, p6.y, -pulley_pr(GT2x16_plain_idler)],
[p2.x, p2.y, pulley_pr(GT2x20ob_pulley)],
[p3.x, p3.y, pulley_pr(GT2x20ob_pulley)],
[p4.x, p4.y, pulley_pr(GT2x20ob_pulley)]
];
belt = GT2x6;
belt(belt, path, 80, [0, belt_pitch_height(belt) - belt_thickness(belt) / 2]);
translate([-25, 0])
belt = GT2x6;
belt(belt, path, 80, [0, 0]);
pulleys();
translate_z(20)
hflip() {
belt(belt, path, 80, [0, 0], belt_colour = grey(90), tooth_colour = grey(50));
pulleys(flip=true);
}
translate([-25, 0, 10])
layout([for(b = belts) belt_width(b)], 10)
rotate([0, 90, 0])
belt(belts[$i], [[0, 0, 20], [0, 1, 20]], belt_colour = $i%2==0 ? grey90 : grey20, tooth_colour = $i%2==0 ? grey70 : grey50);
belt(belts[$i], [[0, 0, 20], [0, 1, 20]], belt_colour = $i%2==0 ? grey(90) : grey(20), tooth_colour = $i%2==0 ? grey(70) : grey(50));
}
if($preview)

View File

@@ -23,7 +23,7 @@ use <../vitamins/insert.scad>
use <../printed/box.scad>
box = [M3_dome_screw, 3, DiBond, PMMA3, DiBond6, true, 150, 100, 70];
box = box(screw = M3_dome_screw, wall = 3, sheets = DiBond, top_sheet = PMMA3, base_sheet = DiBond6, feet = true, size = [150, 100, 70]);
include <../printed/box_assembly.scad>

View File

@@ -25,7 +25,7 @@ include <../printed/butt_box.scad>
$explode = 0;
box = [M3_dome_screw, DiBond, DiBond6, PMMA3, 250, 400, 300, 120];
box = bbox(screw = M3_dome_screw, sheets = DiBond, base_sheet = DiBond6, top_sheet = PMMA3, span = 250, size = [400, 300, 120]);
module bbox_assembly() _bbox_assembly(box);

33
tests/camera_housing.scad Normal file
View File

@@ -0,0 +1,33 @@
//
// NopSCADlib Copyright Chris Palmer 2020
// nop.head@gmail.com
// hydraraptor.blogspot.com
//
// This file is part of NopSCADlib.
//
// NopSCADlib is free software: you can redistribute it and/or modify it under the terms of the
// GNU General Public License as published by the Free Software Foundation, either version 3 of
// the License, or (at your option) any later version.
//
// NopSCADlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with NopSCADlib.
// If not, see <https://www.gnu.org/licenses/>.
//
include <../core.scad>
use <../utils/layout.scad>
use <../printed/camera_housing.scad>
include <../vitamins/cameras.scad>
use <../vitamins/pcb.scad>
module camera_housings()
layout([for(c = cameras) pcb_length(camera_pcb(c))], 15, false) let(c = cameras[$i])
camera_fastened_assembly(c, 3);
if($preview)
camera_housings();

31
tests/cameras.scad Normal file
View File

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

56
tests/catenary.scad Normal file
View File

@@ -0,0 +1,56 @@
//
// 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/>.
//
l = 250; // [1: 1000]
x = 200; // [1: 1000]
y = 50; //[-500 : 500]
include <../utils/core/core.scad>
use <../utils/catenary.scad>
use <../utils/sweep.scad>
use <../utils/annotation.scad>
module catenaries() {
//
// catenary curve path from control points
//
curve = [for(p = catenary_points(l, x, y)) [p.x, p.y, 0]];
//
// Draw the curve
//
r = 0.5;
sweep(curve, circle_points(r, $fn = 64));
//
// Minimum Z
//
min_z = catenary_points(l, x, y, 0);
color("blue") {
translate([min_z.x, min_z.y + r])
rotate([-90, 0, 0])
arrow();
translate([min_z.x, min_z.y - r])
rotate([90, 0, 0])
arrow();
}
}
if($preview)
rotate(is_undef($bom) ? 0 : [70, 0, 315])
catenaries();

View File

@@ -41,9 +41,12 @@ module components() {
translate([0, 50])
TO220("Generic TO220 package");
translate([50, 50])
translate([40, 50])
panel_USBA();
translate([80, 50])
fack2spm();
translate([0,80])
thermal_cutouts();

View File

@@ -32,8 +32,8 @@ clearance = 0.2;
angle = 0; // [-90 : 180]
big_hinge = ["big", width, depth, thickness, pin_diameter, knuckle_diameter, knuckles, M3_dome_screw, screws, clearance, margin];
small_hinge = ["small", 20, 16, 2, 2.85, 7, 3, M3_dome_screw, 2, 0.2, 0];
big_hinge = flat_hinge(name = "big", size = [width, depth, thickness], pin_d = pin_diameter, knuckle_d = knuckle_diameter, knuckles = knuckles, screw = M3_dome_screw, screws = screws, clearance = clearance, margin = margin);
small_hinge = flat_hinge(name = "small", size =[ 20, 16, 2], pin_d = 2.85, knuckle_d = 7, knuckles = 3, screw = M3_dome_screw, screws = 2, clearance = 0.2, margin = 0);
hinges = [small_hinge, big_hinge];

View File

@@ -21,14 +21,14 @@ use <../printed/foot.scad>
module feet()
if($preview) {
translate([50, 0])
translate([40, 0])
foot_assembly(3);
translate([foot_diameter(insert_foot()) / 2, 0])
fastened_insert_foot_assembly(3);
}
else {
translate([50, 0])
translate([40, 0])
foot();
insert_foot();

66
tests/gears.scad Normal file
View File

@@ -0,0 +1,66 @@
//
// 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/gears.scad>
// left gear teeth
z1 = 39; // [7 : 1 : 99]
// Right gear teeth
z2 = 7; // [7 : 1 : 99]
// Modulus
m = 2.0; // [0.1 : 0.1 : 5.0]
// Pressure angle
pa = 20; // [14.5, 20, 22.5, 25]
$show_numbers = false;
module gears() {
color(pp1_colour)
rotate(-$t * 360)
linear_extrude(eps, center = true, convexity = z1)
difference() {
involute_gear_profile(m, z1, pa);
circle(r = m * z1 / 10);
}
color(pp2_colour)
translate([centre_distance(m, z1, z2, pa), 0])
rotate(180 + 180 / z2 + $t * 360 * z1 / z2)
linear_extrude(eps, center = true, convexity = z2)
difference() {
involute_gear_profile(m, z2, pa);
circle(r = m * z2 / 10);
}
z3 = floor((z1 + z2) / PI);
angle = -$t * 360 + 90 - floor(z1 / 4) * 360 / z1; // Line up the rack 1/4 turn around the gear
pitch = m * PI;
color(pp3_colour)
translate([(angle % ((z3 / z1) * 360)) / 360 * z1 * pitch, -centre_distance(m, z1, 0, pa)])
linear_extrude(eps, center = true)
involute_rack_profile(m, z3, 3 * m, pa);
}
rotate(is_undef($bom) ? 0 : [70, 0, 315])
gears();

View File

@@ -29,6 +29,23 @@ module globals() {
translate([50, 0])
right_triangle(10, 20, 0);
}
assert(slice("ABCD") == "ABCD");
assert(slice("ABCD", 1) == "BCD");
assert(slice("ABCD", 2) == "CD");
assert(slice("ABCD", 3) == "D");
assert(slice("ABCD", 4) == "");
assert(slice("ABCD", 1, -1) == "BC");
assert(slice("ABCD", 2, -1) == "C");
assert(slice("ABCD", 3, -1) == "");
assert(slice("ABCD", 4, -1) == "");
assert(slice("ABCD", 0, -1) == "ABC");
assert(slice("ABCD", 0, -2) == "AB");
assert(slice("ABCD", 0, -3) == "A");
assert(slice("ABCD", 0, -4) == "");
assert(slice("ABCD", 0, 0) == "");
assert(slice("ABCD", 0, 1) == "A");
assert(slice("ABCD", 0, 2) == "AB");
assert(slice("ABCD", 0, 3) == "ABC");
}
rotate([70, 0, 315]) globals();

94
tests/horiholes.scad Normal file
View File

@@ -0,0 +1,94 @@
//
// 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/>.
//
$layer_height = 0.25;
include <../utils/core/core.scad>
use <../utils/horiholes.scad>
show_disc = true;
use_horihole = true;
thickness = 6;
length = 60;
height = 20;
overlap_x = 15;
overlap_y = 10;
module hole_positions() {
x0 = (length - 40) / 2;
for($i = [0 : 4], $z = 5 + $i * layer_height / 5, $r = 3)
translate([x0 + $i * 10, $z])
children();
for($i = [0 : 4], $z = 15 + $i * layer_height / 5, $r = 0.5 + $i / 2)
translate([x0 + $i * 10, $z])
children();
}
module horiholes_stl(t = thickness) {
rotate([90, 0, 0])
difference() {
linear_extrude(t, center = true) {
difference() {
square([length, height]);
hole_positions()
if(use_horihole)
horihole($r, $z);
else
teardrop_plus(h = 0, r = $r);
}
}
}
if(t == thickness)
translate([length / 2, 0])
rounded_rectangle([length + 2 * overlap_x, thickness + 2 * overlap_y, 2], 5);
}
module horiholes() {
stl_colour(pp1_colour)
rotate([-90, 0, 0])
horiholes_stl(eps);
if(show_disc)
hole_positions()
color(silver)
cylinder(r = $r, h = eps, center = true, $fn = 360);
hole_positions()
color("blue")
horicylinder(r = $r, z = $z, h = 2 * eps, center = true, $fn = 360);
hole_positions()
color("red")
linear_extrude(3 * eps, center = true)
intersection() {
difference() {
square(8, center = true);
horihole($r, $z);
}
circle($r, $fn = 360);
}
}
if($preview)
rotate(is_undef($bom) ? 0 : [70, 0, 315])
horiholes();
else
horiholes_stl();

View File

@@ -25,7 +25,7 @@ module hot_ends()
layout([for(h = hot_ends) 40])
translate([-20, 0])
rotate(90)
hot_end(hot_ends[$i], 3);
hot_end(hot_ends[$i], 3, bowden = $i == 3);
if($preview)
hot_ends();

29
tests/magnets.scad Normal file
View File

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

View File

@@ -69,6 +69,33 @@ module maths() {
// Test Euler
//
assert(euler(rotate(r)) == r, "euler() failed");
//
// Circle intersect
//
r1 = 10;
c1 = [50, 0, 10];
r2 = 20;
c2 = [67, 0, 0];
p1 = circle_intersect(c1, r1, c2, r2);
p2 = circle_intersect(c2, r2, c1, r1);
rotate(90) {
color(grey(90))
translate(c1) rotate([90, 0, 0]) cylinder(r = r1, h = 4 * eps, center = true);
color(grey(80))
translate(c2) rotate([90, 0, 0]) cylinder(r = r2, h = eps, center = true);
color("red")
translate(p1) rotate([90, 0, 0]) cylinder(r = 0.1, h = 6 * eps, center = true);
color("blue")
translate(p2) rotate([90, 0, 0]) cylinder(r = 0.1, h = 6 * eps, center = true);
translate(p1) arrow();
translate(p2) vflip() arrow();
}
}
rotate(45)

View File

@@ -21,11 +21,11 @@ include <../utils/core/core.scad>
use <../vitamins/opengrab.scad>
module opengrab_test() {
opengrab_target();
rotate(45)
translate_z(opengrab_target_thickness())
opengrab();
opengrab_target();
translate_z(opengrab_target_thickness())
opengrab();
}
if($preview)

29
tests/panel_meters.scad Normal file
View File

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

View File

@@ -23,26 +23,56 @@ include <../vitamins/pin_headers.scad>
pins = 10;
module pin_headers()
module pin_headers() {
layout([for(p = pin_headers) hdr_pitch(p) * pins], 15) {
idc_transition(pin_headers[$i], 10);
translate([0, 20])
pin_header(pin_headers[$i], 10, 2, right_angle = true);
pin_header(pin_headers[$i], 3, 2, right_angle = true);
translate([-10, 20])
pin_header(pin_headers[$i], 3, 1, right_angle = true);
translate([10, 20])
pin_header(pin_headers[$i], 3, 3, right_angle = true);
translate([0, 30])
pin_header(pin_headers[$i], 8, 1);
translate([0, 40])
pin_header(pin_headers[$i], 10, 2);
translate([0, 50])
box_header(pin_headers[$i], 8, 1);
translate([0, 60])
box_header(pin_headers[$i], 10, 2);
translate([0, 70])
pin_socket(pin_headers[$i], 8, 1);
translate([0, 80])
pin_socket(pin_headers[$i], 10, 2);
translate([0, 110])
pin_socket(pin_headers[$i], 10, 2, right_angle = true);
translate([-10, 105])
pin_socket(pin_headers[$i], 3, 1, right_angle = true);
translate([0, 105])
pin_socket(pin_headers[$i], 3, 2, right_angle = true);
translate([10, 105])
pin_socket(pin_headers[$i], 3, 3, right_angle = true);
}
for(i = [0, 1], p = [5, 2][i], j = [0 , 1]) {
h = [jst_ph_header, jst_xh_header][j];
translate([-20 * (i + 1), 0 + j * 40])
jst_xh_header(h, p);
translate([-20 * (i + 1), 20 + j * 40])
jst_xh_header(h, p, true);
}
}
if($preview)
pin_headers();

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

After

Width:  |  Height:  |  Size: 6.5 KiB

BIN
tests/png/axials.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 282 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 86 KiB

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 102 KiB

After

Width:  |  Height:  |  Size: 133 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 84 KiB

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 112 KiB

After

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

BIN
tests/png/cameras.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

BIN
tests/png/catenary.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 101 KiB

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 118 KiB

After

Width:  |  Height:  |  Size: 118 KiB

BIN
tests/png/dip.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 74 KiB

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 118 KiB

After

Width:  |  Height:  |  Size: 119 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 117 KiB

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 148 KiB

After

Width:  |  Height:  |  Size: 148 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 95 KiB

After

Width:  |  Height:  |  Size: 102 KiB

BIN
tests/png/gears.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

BIN
tests/png/horiholes.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 125 KiB

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 84 KiB

After

Width:  |  Height:  |  Size: 85 KiB

BIN
tests/png/led_meters.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 115 KiB

After

Width:  |  Height:  |  Size: 115 KiB

BIN
tests/png/magnets.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 61 KiB

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 97 KiB

BIN
tests/png/panel_meters.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 144 KiB

After

Width:  |  Height:  |  Size: 174 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 158 KiB

After

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 103 KiB

After

Width:  |  Height:  |  Size: 166 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 137 KiB

After

Width:  |  Height:  |  Size: 137 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 119 KiB

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 66 KiB

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 188 KiB

After

Width:  |  Height:  |  Size: 188 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 86 KiB

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
tests/png/smds.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 160 KiB

After

Width:  |  Height:  |  Size: 160 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 KiB

After

Width:  |  Height:  |  Size: 104 KiB

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