249 Commits
v2.0.1 ... main

Author SHA1 Message Date
1a94eabd39 delete panel_clamp 2025-07-30 12:59:27 +09:00
480afbf2db remove gap 2025-07-30 10:14:15 +09:00
Edward Kisiel
760e0e6bdd updated sbcmf with new terminal class components 2025-06-22 21:17:31 -04:00
Edward Kisiel
d7e70658f3 updated readme.md and sbcmf library 2025-06-07 14:05:57 -04:00
Edward Kisiel
4f42b9a3db added washer to accessory tool, added holes to bottom of rack case for feet, updated readme.md 2025-06-01 17:40:00 -04:00
Edward Kisiel
60ca7f47bb changed rack stand foot and arc thickness, readme.md corrections. 2025-05-30 10:04:33 -04:00
Edward Kisiel
054dbb9edc added sbccb_accessory_tool.scad for user access to the accessory library, fixed rack tab hole spacing, added library parts rack_rail and rack_stand for 1u-4u cases 2025-05-29 16:50:35 -04:00
Edward Kisiel
12c99bee77 corrected interior wall height relative to floor thickness changes. 2025-05-28 18:24:07 -04:00
Edward Kisiel
3aa7e5837a adjusted removable bay clearances, added example rack case and other cleanup 2025-05-27 21:04:24 -04:00
Edward Kisiel
9a037db8a4 grommet tolerance adjustment, fixed wrong part count and other minor changes 2025-05-26 16:06:52 -04:00
Edward Kisiel
5a15316530 rack case design branch merge and sbcmf update 2025-05-25 12:32:18 -04:00
Edward Kisiel
d5d63e54a2 adjusted n2, n2+ openings and sbc placement for rack case 2025-05-25 12:02:04 -04:00
Edward Kisiel
f5dd71ec29 repositioned top and bottom cover patterns, alignment adjustments for removable bay and other changes 2025-05-23 19:37:51 -04:00
Edward Kisiel
d502252d2e add grommet() and panel_clamp() to accessory library, readme.md updated, work on removable bay sbc positioning. 2025-05-22 22:20:27 -04:00
Edward Kisiel
13ccfc6357 fixed bottom heatsink standoff mounting for relavent sbc 2025-05-21 21:41:41 -04:00
Edward Kisiel
d254f162c1 fixed rack bay external bottom heatsink standoff mounting support, raised case wall clamps, changed rack case to initial fixed depth of 100mm 2025-05-21 18:20:49 -04:00
Edward Kisiel
ed077d5039 rearranged standoff gui tabs and created h4 bottom mount panel_nas example case 2025-05-20 13:41:21 -04:00
Edward Kisiel
71034dee85 set interior walls to fixed width of 2mm 2025-05-18 10:13:35 -04:00
Edward Kisiel
b221fabed5 fixed manifold issue with lower panel clamps and other minor changes 2025-05-16 19:48:00 -04:00
Edward Kisiel
728b8398f9 added individual standoff control for rack case, fixed, open and removable bays 2025-05-16 11:56:58 -04:00
Edward Kisiel
1c64305276 added case top for rack cases 2025-05-15 15:49:59 -04:00
Edward Kisiel
1b8a47361b expanded rear conduit-grommet selection and tweaked removal bay trays 2025-05-14 21:34:24 -04:00
Edward Kisiel
8d2ebd4f94 final plumbing for rack removable bays 2025-05-13 21:56:58 -04:00
Edward Kisiel
0d28ebbc88 more work for removable bays 2025-05-12 18:31:59 -04:00
Edward Kisiel
35825add61 removable bay tray initial work 2025-05-11 22:18:14 -04:00
Edward Kisiel
0aff56b70c individual bay open front or adjoining combinations based on disabled bay wall and empty adjoining bay 2025-05-09 21:57:13 -04:00
Edward Kisiel
c3ec2837ed setup screw mask for panel_clamp and used mask for rack case 2025-05-08 16:28:54 -04:00
Edward Kisiel
cd05ff7528 view accessory part added for rack cases 2025-05-08 15:52:28 -04:00
Edward Kisiel
93b4de0444 rack case added to individual part selection as left, bottom, right 2025-05-07 20:38:20 -04:00
Edward Kisiel
9f11e2884e support for 10 inch racks and changed rack tabs to standard width 2025-05-07 17:31:29 -04:00
Edward Kisiel
c09d444913 adjusted 2mm panel_clamps, implemented bottom cover and front vents 2025-05-07 15:36:18 -04:00
Edward Kisiel
5b03cd94fc more rack bay work, fixes and code cleanup 2025-05-06 17:11:43 -04:00
Edward Kisiel
63ea4bae0b plumbed wall, fan and conduit for 6 rack bays 2025-05-05 20:43:15 -04:00
Edward Kisiel
b6554114ec additional rack sizes 1u+, 1u++ and gui additions for wall, fan and conduit 2025-05-04 19:23:45 -04:00
Edward Kisiel
6bc4920bea added middle floor clamp, expanded support to 6 devices, initial wall dividers 2025-05-03 21:44:01 -04:00
Edward Kisiel
ca26347358 rack case piece fastening geometry, added panel_clamp to library 2025-05-03 17:44:48 -04:00
Edward Kisiel
859192bd6b multi sbc support with individual location and rotation for rack case 2025-05-01 17:43:39 -04:00
Edward Kisiel
b48bb23e53 changed height of panel_nas front and back panel. 2025-05-01 13:55:39 -04:00
Edward Kisiel
5aebb0d549 initial work for rack_1u case, rack.scad with mounting tabs 2025-04-29 14:45:29 -04:00
Edward Kisiel
415d5532a1 gui work for rack case design 2025-04-27 19:52:44 -04:00
Edward Kisiel
a9e51e25dd added tol adjustment to panel_nas panel openings for right and left side for a better fit 2025-04-26 15:34:51 -04:00
Edward Kisiel
d7f043e6ed increased side slot mask depth for panel_nas 2025-04-25 22:18:51 -04:00
Edward Kisiel
2979144e28 minor gui format change, lib/vent.scad replaced 2025-04-25 22:00:34 -04:00
Edward Kisiel
43f7e0f476 added section part under view tab for panel case part 2d sections 2025-04-24 19:59:56 -04:00
Edward Kisiel
a6dd0dcb1d panel_nas right side placement and related panel size fixed 2025-04-24 18:16:50 -04:00
Edward Kisiel
3281835ac8 panel_nas case design and SBCMF update 2025-04-23 17:50:45 -04:00
Edward Kisiel
2f318b1cce cable_holder improvement, more front, top and bottom vent cover adjustments, other code cleanup and example cases 2025-04-23 15:07:23 -04:00
Edward Kisiel
86eb912784 fixed spacer and right side placment issue, updated readme.md, code cleanup and example case accessories 2025-04-21 17:30:50 -04:00
Edward Kisiel
1c2cf8e00f platter and part view plumbed and indent adjusted 2025-04-18 21:12:11 -04:00
Edward Kisiel
b369665049 added fan models for rear panel in model view 2025-04-18 18:08:03 -04:00
Edward Kisiel
db43558f9c front, top and bottom cover vent adjustments 2025-04-18 16:29:32 -04:00
Edward Kisiel
5a56f3d4fc additional tab support for 4+ hd bays 2025-04-18 11:55:11 -04:00
Edward Kisiel
5d0242ff1c for sbc wider then 100mm, added option to center hd positions on x axis using dual spacers 2025-04-17 21:40:52 -04:00
Edward Kisiel
2eea918f4f implemented hd_holes() hole or slot openings for 2.5 and 3.5 drives 2025-04-17 17:16:48 -04:00
Edward Kisiel
f5793ea453 variable length spacer placement and hd reverse, 180 z rotation, implemented 2025-04-17 15:53:56 -04:00
Edward Kisiel
53b242440f hd cableholder_spacer work, top cover adjustments, other changes 2025-04-14 20:49:57 -04:00
Edward Kisiel
c151a9047b wide format sbc support and other changes 2025-04-12 21:56:28 -04:00
Edward Kisiel
3ce75a345b more case panel fastening work 2025-04-12 15:08:07 -04:00
Edward Kisiel
3fee9e59ce added rpi5_bottom_m2hat_shell as a saved case 2025-04-11 14:47:40 -04:00
Edward Kisiel
a999585197 added panel tabs and cutouts for case assembly 2025-04-10 21:59:03 -04:00
Edward Kisiel
2e797dd1fb added top or bottom sbc mount with indents for panel_nas, other misc additions and changes 2025-04-08 17:18:01 -04:00
Edward Kisiel
a032839b3b work on parametrics for drive(s), fan and case size, other gui and misc work 2025-04-07 17:33:32 -04:00
Edward Kisiel
6f26ab2f04 more wip for panel_nas case 2025-04-06 19:06:29 -04:00
Edward Kisiel
cd2e77acc9 new case panel_nas initial work 2025-04-06 12:40:01 -04:00
Edward Kisiel
1d97917d46 saved case m2_eyespi_eink1.54 and m2_eyespi_lcd2.8 added 2025-04-05 20:06:37 -04:00
Edward Kisiel
f393da7372 fixed top standoff opening problem due to typo 2025-04-05 15:21:45 -04:00
Edward Kisiel
d6d6fb6d41 fixed top standoff z placement and height for tray_side cases 2025-04-01 17:02:45 -04:00
Edward Kisiel
c678853a6d fixed top standoff z placement and height for fitted and snap cases 2025-04-01 16:40:53 -04:00
Edward Kisiel
bb3a1d6f80 updated SBC Model Framework and added opi5max sbc in gui 2025-03-30 18:38:24 -04:00
Edward Kisiel
5456ff54f1 added m2_eyespi_shell and adjusted button clip opening 2025-03-11 13:35:19 -04:00
Edward Kisiel
b19993d63c adjustments for rock4c+ and changed status to verified in SBC Model Framework, adjusted indent for audio jack 2025-02-04 15:12:13 -05:00
Edward Kisiel
7e809f2719 fixed standoff openings from interfering with case geometry 2025-01-30 11:20:34 -05:00
Edward Kisiel
7adbea7732 m2 shell for eyespi as wip 2025-01-30 10:10:33 -05:00
Edward Kisiel
3586afff2d lowered usbc single horizontal 180 indent. 2024-11-13 14:43:52 -05:00
Edward Kisiel
24a454a492 increased case gap by .5mm and lowered usbc mask for rock5b+. 2024-11-13 10:05:25 -05:00
Edward Kisiel
c7929e7f6b library models adafruit_2030_powerboost, adafruit_4755_solar_charger and changed the name of adafruit_lcd to adafruit_4311_lcd, updated sbcmf and documentation 2024-10-25 17:27:11 -04:00
Edward Kisiel
5bd72034e8 sbcmf update 2024-10-24 19:39:05 -04:00
Edward Kisiel
89b1bf1915 update sbc model framework that includes adafruit feather-m0_express and feather-m4_express 2024-10-24 18:00:27 -04:00
Edward Kisiel
1ef63e412d changed pillar Z location and changed rpi hat to use pillars in accessories.cfg. 2024-10-19 19:52:18 -04:00
Edward Kisiel
be91de94ff pillar model added and readme.md updated, xu4_shifter_shield case added 2024-10-19 17:08:46 -04:00
Edward Kisiel
ad087dbc77 updated sbc_model_framework for rock5b+ usbc adjustment 2024-09-05 10:31:43 -04:00
Edward Kisiel
8d7b211466 added odroid-m2 and test case m2_shell both verified green, added m2_shell_lowboy case, updated sbc_model_framework 2024-09-01 15:49:24 -04:00
Edward Kisiel
cfe140a048 adjusted rock5b+ hdmi-a input location 2024-08-24 09:19:25 -04:00
Edward Kisiel
9d1cfa396c added rock5b+ and initial test case, both currently unverified 2024-08-17 22:14:44 -04:00
Edward Kisiel
1918a7bbaa updated sbc model framework for nio12l corrections, created nio12l_shell test case to verify sbc 2024-08-17 11:10:49 -04:00
Edward Kisiel
183e3bee12 updated readme.md and added animation sbc_case_builder_gui.gif 2024-07-21 18:16:36 -04:00
Edward Kisiel
fba4fc3420 added soedge_a-baseboard and test case, updated sbc model framework and readme.md 2024-07-21 13:09:11 -04:00
Edward Kisiel
8b50011e35 added a64 and a64lts and test cases a64_shell and a64-lts_shell, initial work on soedge_a_baseboard_shell, updated sbc model framework 2024-07-14 21:42:29 -04:00
Edward Kisiel
aca4c96b1d updated quartz64b and passed test case quartz64b_shell, sbc model framework updated 2024-07-10 20:17:02 -04:00
Edward Kisiel
6527951336 rockpro64 adjustments, indent reposition for jack_3.5 and sbc model framework update 2024-07-04 10:12:44 -04:00
Edward Kisiel
a4aed16cbc modifications to star64, rock64 and indent.scad for jack_3.5, updated sbc model framework 2024-07-01 20:02:17 -04:00
Edward Kisiel
8815141155 added BPi-F3_shell, milk-V_duoS_shell cases and updated sbc model framework 2024-06-24 20:03:35 -04:00
Edward Kisiel
29192ea441 changed how the inner corner fillet is derived, added a note in the README.md file about updating the submodule sbc model framework as well as other readme.md corrections. 2024-06-09 17:18:19 -04:00
Edward Kisiel
6e49f76b4e bpif3 added and sbc model framework updated 2024-06-07 19:42:03 -04:00
Edward Kisiel
c952df6a28 expanded README.md, updated get_customizer_values and acccessory entries 2024-06-06 16:13:49 -04:00
Edward Kisiel
11b869daeb rework of extended case standoff placement based on standoff support size, cs-solar_energy_meter and avr_env_sensors case adjustments 2024-06-02 17:29:58 -04:00
Edward Kisiel
82fd693b04 increased top and bottom standoff adjustments range from 20mm to 30mm 2024-06-01 20:18:54 -04:00
Edward Kisiel
45c4f7e97f added cnano-avr128da48, adjustments to cs-solarmeter and updated sbc_model_framework 2024-05-31 16:36:27 -04:00
Edward Kisiel
9511f0263b initial standoff support for multiple secondary pcb assemblies 2024-05-30 20:57:40 -04:00
Edward Kisiel
a151de9575 restored rock5b accessory entries for standoff trim 2024-05-26 16:03:43 -04:00
Edward Kisiel
319bbe516e added multi-pcb indent support, new devices nodemcu-32s and cs-solarmeter 2024-05-26 15:57:06 -04:00
Edward Kisiel
f8684b715f added oem_rpi library and corrected parametric header 2024-05-15 20:54:29 -04:00
Edward Kisiel
d233f4c9c8 added rpi_m2hat model, example case rpi5_m2hat_shell and supporting plumbing 2024-05-15 20:47:35 -04:00
Edward Kisiel
9516fc4d03 increased star64 standoff support size 2024-05-11 08:48:56 -04:00
Edward Kisiel
a6e8e1d147 updated star64 pcb thickness and sdcard style 2024-05-11 08:43:35 -04:00
Edward Kisiel
62d6d15389 fixed fan_2 mask, created shared fan and heatsink mask code and readme.md updates and corrections 2024-05-10 21:57:12 -04:00
Edward Kisiel
ba9832a972 added 25mm fan model and mask opens, more sbc model framework changes 2024-05-10 20:27:11 -04:00
Edward Kisiel
0dcc224da2 updated sbc_model_framework for star64 changes 2024-05-10 16:39:44 -04:00
Edward Kisiel
c9ad238b9f corrected stl_model classes to model in readme.md 2024-05-10 16:36:34 -04:00
Edward Kisiel
1c33a21f3d Merge pull request #33 from yegct/patch-1
Update README.md
2024-04-30 17:06:54 +00:00
Chris Thompson
513712fcf9 Update README.md
it’s -> its, trivial grammar correction
2024-04-30 08:48:59 -06:00
Edward Kisiel
a88ac9457e lowered max bottom height for h4 series and changed heatsink stub location for nio12l 2024-04-29 22:23:55 -04:00
Edward Kisiel
1f2bb6613a added h4, h4+ and h4_ultra with updated sbc model framework 2024-04-29 18:29:39 -04:00
Edward Kisiel
a3f576edb9 changed adapter hole size to 4mm 2024-04-29 10:54:00 -04:00
Edward Kisiel
ddd7c0b4bd removed unneeded h3_port_extender.stl model and updated readme.md 2024-04-28 13:43:58 -04:00
Edward Kisiel
8e73d4550f updated readme.md and sbc library 2024-04-27 17:11:13 -04:00
Edward Kisiel
821deb2445 updated sbc_model_framework 2024-04-26 10:15:55 -04:00
Edward Kisiel
e6cb0b3b8c adjusted io shield opening, moved access panel in platter view and cleaned up accessory entries. 2024-04-26 10:07:21 -04:00
Edward Kisiel
045aa2874a finished named standoff size for extended standoffs, added mini-stx-thin adapter and io shield, updated readme.md and other fixes. 2024-04-24 16:09:44 -04:00
Edward Kisiel
74084eebde implemented named fastener size m2, m2.5, m3, m4 and custom for top and bottom standoffs 2024-04-22 20:49:03 -04:00
Edward Kisiel
0807d49dbb fixed model view sections, fixed tray cases nut holder placement, changed fan mask direction and finalized standard form adapters and cases. 2024-04-22 16:09:31 -04:00
Edward Kisiel
42593fa92f fixed z axis parametric problem related to calculated bottom standoff height, more case cleanup and other fixes and changes 2024-04-20 17:27:54 -04:00
Edward Kisiel
2eef11f03f finished library documentation update, added fan and hd masks and other fixes 2024-04-18 19:47:42 -04:00
Edward Kisiel
125ec3a477 documentation work and other cleanup and fixes 2024-04-17 17:31:50 -04:00
Edward Kisiel
50f71b69e3 fixed tray side fastener placement when using extend standoffs, more standard mb case and adapter changes 2024-04-14 16:48:36 -04:00
Edward Kisiel
f56302f7a8 initial fan models 40mm, 50mm, 60mm, 80mm, 92mm, 120mm, 140mm without vanes 2024-04-13 16:36:59 -04:00
Edward Kisiel
5c7f917b9f plumbed accessory support for standard mb form adapters, added mini-stx adapter and initial work for standard mb form cases 2024-04-13 14:36:52 -04:00
Edward Kisiel
3277cc8d07 adjustments for case adapters and io plate, remove unneed stl models 2024-04-10 21:02:45 -04:00
Edward Kisiel
4f7aa53050 legacy case adapters added 2024-04-09 22:05:00 -04:00
Edward Kisiel
dc12d7f6a1 added linear top and bottom vents and removed unused exhaust vent variable 2024-04-07 16:31:30 -04:00
Edward Kisiel
8e89257759 rewrote tray side attachment routine based on SBC standoff location 2024-04-07 15:20:37 -04:00
Edward Kisiel
40e8e6bfff removed case_style and added new case_design names as replacement 2024-04-07 12:33:56 -04:00
Edward Kisiel
f5130023f0 added bottom access panel in gui and changed all related uses for accessories 2024-04-06 21:16:28 -04:00
Edward Kisiel
6a855e1ef6 finished initial accessory case conversion to new format 2024-04-06 15:59:45 -04:00
Edward Kisiel
de063b31f8 converted h3_port_extender and components from stl and implemented automask, more case conversions 2024-03-31 14:53:06 -04:00
Edward Kisiel
88691a6b61 added db9 to dsub.scad in library 2024-03-28 14:31:27 -04:00
Edward Kisiel
8a0e9f17a0 more custom case conversion to use auto-mask 2024-03-21 17:16:07 -04:00
Edward Kisiel
f71bc2e2d0 fixed regression in standoff supports and more model cahnges to support auto mask generation 2024-03-21 12:30:35 -04:00
Edward Kisiel
0fb0f4daef various plumbing to implement auto-masks for library, config changes and other modifications 2024-03-16 17:39:23 -04:00
Edward Kisiel
8bf424b99b changed oem_hk to shared component lib, added new standoff end type none 2024-03-15 15:26:23 -04:00
Edward Kisiel
2dc8e16f1e library conversion and masks for boom_speaker, hk_boom_speaker, hk_boom, hk_pwr_button, hk_m1s_ups 2024-03-05 17:52:00 -05:00
Edward Kisiel
e7b85fa217 library masks for hk_vu7c, hk_vu8m, hk_vu8s 2024-03-04 16:25:16 -05:00
Edward Kisiel
9e8fe8006f more library cleanup and mask creation for buttons and hk35_lcd 2024-03-04 11:11:24 -05:00
Edward Kisiel
c1aa6bb353 completed library masks for access_port, standoff, hc4_olded, hc4_oled_holder, hk_netcard 2024-02-28 19:38:49 -05:00
Edward Kisiel
e46ac774e4 created ui enable for individual top, bottom and extended standoffs with associated plumbing 2024-02-26 13:22:57 -05:00
Edward Kisiel
d5d23fba18 started cleaning json and cfg file, updated ui and added new features 2024-02-25 21:39:41 -05:00
Edward Kisiel
2c61849665 top and bottom extended standoff ui added and plumbed for control 2024-02-25 16:14:30 -05:00
Edward Kisiel
0b99ea5805 added sbc information in ui and plumbed 2024-02-24 21:31:38 -05:00
Edward Kisiel
2b430275cb standoff sidewall support moved to standoff module, top and bottom standoffui changes 2024-02-24 20:48:41 -05:00
Edward Kisiel
b6eb06f97c more work on mask integration and cleanup 2024-02-24 16:13:15 -05:00
Edward Kisiel
7b03aa1922 plumed in mask for add and sub parametric moves 2024-02-24 12:30:56 -05:00
Edward Kisiel
fd688d53c3 added mask variable in sbc_case_builder_accessories.cfg for all entries 2024-02-23 21:27:22 -05:00
Edward Kisiel
543162c61c sbc_case_builder_accessories.cfg corrections 2024-02-23 17:29:59 -05:00
Edward Kisiel
506d29f34e convert accessory format to arrays for size and data 2024-02-23 16:08:35 -05:00
Edward Kisiel
8c0e333450 support for stl models with stl_model, start of library work, woek on adafruit model. 2024-02-22 15:14:08 -05:00
Edward Kisiel
7b9a18279d added sidewall support selection per standoff in gui and more work on top and bottom control 2024-02-19 09:57:55 -05:00
Edward Kisiel
a288a924d5 standoff variable seperation for gui, initial work for top and bottom standoffs 2024-02-19 09:57:55 -05:00
Edward Kisiel
6262684252 updated readme and sbcmf 2024-02-18 15:09:04 -05:00
Edward Kisiel
7559d48140 changed ui for improved folded case use 2024-02-18 12:32:32 -05:00
Edward Kisiel
5c43d0961d refinement and fixes for folded cases with ui improvements 2024-02-17 17:26:09 -05:00
Edward Kisiel
0d5f8ef357 more work on folded cases, added paper_full-top case 2024-02-16 22:54:10 -05:00
Edward Kisiel
1b549ac761 initial work for folded cases added case paper_split-top 2024-02-14 21:59:44 -05:00
Edward Kisiel
5514029edc updated accessory group names and changed order of accessories tab in ui 2024-02-10 13:42:32 -05:00
Edward Kisiel
90a15ea4c9 added dxf files for custom openings and hk netcard 2024-02-08 17:20:47 -05:00
Edward Kisiel
66aeb943c6 fixed front section cut, added 45 heatsink mask, fixed vu5 and vu7 holder, adjusted accessory entries for all stored cases due to bottom calc change, other fixes and adjustments 2024-02-08 17:17:08 -05:00
Edward Kisiel
2697bc7648 included pcb_z in bottom height calculation. 2024-02-07 11:01:57 -05:00
Edward Kisiel
5fde770566 updated sbc model framework 2024-02-05 21:42:36 -05:00
Edward Kisiel
b336115556 updated library driectory name 2024-02-05 15:23:41 -05:00
Edward Kisiel
3eaaf6f03c updated sbc model framework and removed dxf directory 2024-02-05 15:21:12 -05:00
Edward Kisiel
56b392b082 added custom to heatsink mask ui pickbox 2024-02-05 14:49:36 -05:00
Edward Kisiel
4a58ab823e changed ui to include additional cooling options 2024-01-31 22:52:02 -05:00
Edward Kisiel
ebcafd0f05 fixed indent for cases with more code standardization and cleanup 2024-01-31 22:36:53 -05:00
Edward Kisiel
e5b9e8263c more cleanup and documentation 2024-01-31 21:36:04 -05:00
Edward Kisiel
a33450ac21 code cleanup, rearrangement and documentation 2024-01-30 22:08:10 -05:00
Edward Kisiel
b866bd73db removed no longer needed entries in accessory cfg. 2024-01-30 17:51:56 -05:00
Edward Kisiel
e968bbe384 positional standoff sidewall support added and ongoing code cleanup and reorg. 2024-01-30 16:04:37 -05:00
Edward Kisiel
d084cab29f plumbed new heatsink, gpio, uart mask selection thru sbcmf cmdline 2024-01-29 21:07:08 -05:00
Edward Kisiel
adf72494a1 initial work for integrating sbc model framework v2 2024-01-29 17:40:12 -05:00
Edward Kisiel
d5674f9f24 updated sbc_model_framework for typo in rpi5 and rpi5_noheatsink 2023-12-14 14:11:23 -05:00
Edward Kisiel
390df175b3 added 5mm and 8mm hex vent, adjusted m1s cases, updated sbc model framework, fixed snap top protrusion placement and other fixes. 2023-12-11 16:21:34 -05:00
Edward Kisiel
0c96b1247a adjusted m1s shell, added m1s_shell_ups case, adjusted components and cooling options. 2023-12-07 20:46:38 -05:00
Edward Kisiel
7cec418b69 added odroid-m1s, added hex vent cooling option and made other changes. 2023-11-15 21:09:42 -05:00
Edward Kisiel
59b894d738 updated sbc model framework and header info. 2023-11-10 12:18:07 -05:00
Edward Kisiel
2e7cd76f20 adjusted indent and cooling options for all rpi5 cases 2023-11-04 17:02:38 -04:00
Edward Kisiel
7eab4fe790 added rpi5 cases 2023-11-04 15:52:38 -04:00
Edward Kisiel
501da93cad fixed snap case top, removed support pieces from non-shell cases for rock5b, fixed tray bottom mounting hole location for top and interference with standoff. 2023-08-26 14:39:08 -04:00
Edward Kisiel
c83301debf opir1 added, updated sbc_model_framework and sbc_case_builder and readme.md 2023-05-30 20:58:56 -04:00
Edward Kisiel
c2d7cc3352 added rock5bq cases panel, stacked, tray, tray-sides, snap and fitted, updated sbc_model_framework 2023-05-14 17:21:51 -04:00
Edward Kisiel
20ab01b924 adjustments to rock5b-v1.42 and added rock5bq-v1.42 with updated sbc model framework, adjusted all rock5b case openings in sbc_case_builder_accessories.cfg, rock5b is now green-verified 2023-05-14 15:09:00 -04:00
Edward Kisiel
0770c17468 updated sbc model framework for visionfive2q, added visionfive2q cases, adjusted tray design side screw locations due to interference 2023-03-09 17:56:35 -05:00
Edward Kisiel
3a1ba0f811 h3_ultimate2 support added at corners 2023-03-09 12:01:28 -05:00
Edward Kisiel
572293170d reverted bottom height calc and added support ribs for h3_ultimate2 case 2023-03-06 13:26:29 -05:00
Edward Kisiel
b59f99c0b6 updated sbc model framework for h2 and h3 pcb thickness increase, changed bottom_height calc to include pcb thickness. 2023-03-05 14:57:42 -05:00
Edward Kisiel
a6795b3383 updated sbc model framework for usbc_vertical changes 2023-03-04 18:11:28 -05:00
Edward Kisiel
00648a52e9 updated sbc model framework, renamed radax rockpi to rock, rock 5b io adjustments, visionfive2 io overhang adjusted, readme.md and file comments updated. 2023-03-04 17:16:01 -05:00
Edward Kisiel
f24d3e918b implemented header_26 as a gpio, added opi5 remaining base design. 2023-02-22 19:23:42 -05:00
Edward Kisiel
b4189a6cee added opi5 sbc and updated sbc_model_framework and documentation. 2023-02-22 10:21:20 -05:00
Edward Kisiel
6aa68c568e updated sbc_model_framework 2023-02-21 12:58:08 -05:00
Edward Kisiel
efed91db76 Merge pull request #29 from amazingfate/rock5b-v1.3
add mask fix for rock5b v1.3
2023-02-21 17:55:14 +00:00
amazingfate
30d709a00e add mask fix for rock5b v1.3 2023-02-21 14:53:25 +08:00
Edward Kisiel
bb5fb69cab added visionfive2 cases, split rockpi5b into rockpi5b-v1.3 and rockpi5b-v1.42 with addtions and modifications to support pre-release and released versions. 2023-02-20 13:09:38 -05:00
Edward Kisiel
f7d06bb311 added cableholder_spacer 2023-02-11 19:32:42 -05:00
Edward Kisiel
2aad1fef87 made h3_port_extender_holder parametric and updated associated cases. 2023-02-09 22:56:59 -05:00
Edward Kisiel
adf4101e3c Merge pull request #27 from Icenowy/star64
Refinements to Star64
2023-01-31 22:58:38 +00:00
Icenowy Zheng
fa1d426130 add star64-shell accessory (fan+pcie holes) and preset
Signed-off-by: Icenowy Zheng <uwu@icenowy.me>
2023-01-31 21:12:04 +08:00
Icenowy Zheng
3af7520d67 add stacked dual rj45
Used on star64.

Signed-off-by: Icenowy Zheng <uwu@icenowy.me>
2023-01-31 21:11:35 +08:00
Edward Kisiel
d5f718ca59 updated to latest sbc_model_framework 2023-01-29 10:16:45 -05:00
Edward Kisiel
236be28bdd added h3_port_extender_holder and updated h3_ultimate2 case. 2023-01-24 22:39:50 -05:00
Edward Kisiel
6ef186018f added wall support for h3_ultimate2 2023-01-22 15:37:25 -05:00
Edward Kisiel
bf7377efbb fixed access_port and access_cover 180 rotation in portrait and landscape. 2023-01-21 20:38:03 -05:00
Edward Kisiel
addb512b7f fixed 60mm fan mask crossarms 2023-01-21 17:17:41 -05:00
Edward Kisiel
6cb1ad2e5d added nut_holder module and amended h3_ultimate2 case. 2023-01-18 17:19:43 -05:00
Edward Kisiel
eb01bb2829 work on h3_ultimate case 2023-01-15 17:44:58 -05:00
Edward Kisiel
8b11dea464 fixed other standoff opening issue and set color in vent_panel_hex. 2023-01-15 16:46:07 -05:00
Edward Kisiel
489e953d09 Merge pull request #25 from tomek-szczesny/main
h3_ultimate2 development
2023-01-15 21:27:21 +00:00
Edward Kisiel
dca4858007 fixed standoff auto openings for z height, fixed standoff sidewall supports distance on top face 2023-01-15 16:12:17 -05:00
Tomek Szczęsny
4b24af0f4b h3_ultimate2 development 2023-01-15 20:41:12 +01:00
Edward Kisiel
33e9c04da1 Merge pull request #22 from Icenowy/licheerv
Add LicheeRV + Dock support
2023-01-15 17:39:28 +00:00
Icenowy Zheng
c0da9dc727 add bigger usbc hole for LicheeRV + Dock Type-C
This Type-C port is on SoM and behind the edge of the Dock.

Signed-off-by: Icenowy Zheng <uwu@icenowy.me>
2023-01-16 01:17:44 +08:00
Icenowy Zheng
36e6538090 add licheerv+dock to model selection
Signed-off-by: Icenowy Zheng <uwu@icenowy.me>
2023-01-16 01:17:44 +08:00
Edward Kisiel
8d1d9bdaf0 updated submodule sbc model framework and n2l_gpio case gpio opening. 2023-01-15 12:06:52 -05:00
Edward Kisiel
17e4e9dd97 Merge pull request #23 from tomek-szczesny/main
h3_ultimate2 development
2023-01-15 16:53:04 +00:00
Tomek Szczęsny
44a0697e2b Changes to h3_ultimate2 2023-01-15 16:31:59 +01:00
Tomek Szczęsny
a068940140 Added mounting holes to vent_panel_hex() 2023-01-15 16:30:48 +01:00
Tomek Szczęsny
e109837ae7 added vent_panel_hex(), minor fix in vent_hex() 2023-01-15 15:08:15 +01:00
Edward Kisiel
51f453be04 added db9 model and mask, n2l sidewall support changed, work on n2l_gpio and h3_ultimate2 cases, updated readme.md. 2023-01-08 19:34:48 -05:00
Edward Kisiel
c23033d819 Merge pull request #21 from tomek-szczesny/main
h3_ultimate2 development
2023-01-06 15:58:03 +00:00
Tomek Szczęsny
c29341d1d6 h3_ultimate2 changes and adjustments 2023-01-06 16:36:16 +01:00
Tomek Szczęsny
61446a322f Adjusted Port Extender hole positions 2023-01-06 16:14:12 +01:00
Edward Kisiel
949af488aa added xu4_keyhole case 2023-01-05 19:34:38 -05:00
Edward Kisiel
d565be1614 Merge pull request #20 from tomek-szczesny/main
Added vent_hex(), updated h3_ultimate2
2023-01-05 15:53:06 +00:00
Tomek Szczęsny
000724340b Added vent_hex() sub, updated h3_ultimate2 2023-01-05 16:25:04 +01:00
Edward Kisiel
79985241c0 fixed standoff sidewall support placement, added fan masks for 60mm and code cleanup, finished h3_port_extender, created h3_ultimate2 for remote mount of port_extender. 2023-01-03 22:39:45 -05:00
Edward Kisiel
d070e829f0 added hk_pwr_button model, keyhole accessory and h3_port_extender models for header and remote mount, updated h3_ultimate case. 2023-01-01 23:23:26 -05:00
Edward Kisiel
e9b5d5508e changed parametrics for n2l_gpio case 2022-12-31 19:49:54 -05:00
Edward Kisiel
c330f3fcad added n2l_gpio case 2022-12-31 19:37:16 -05:00
Edward Kisiel
610a432a86 added accessory entry n2l_gpio 2022-12-29 21:47:15 -05:00
Edward Kisiel
7806e8d578 more port extender integration 2022-12-25 20:46:36 -05:00
Edward Kisiel
6c46501c69 initial h3 port extender work 2022-12-23 16:25:03 -05:00
Edward Kisiel
7fbb5d5f12 updated readme.md, sbc_case_builder.gif, increased possible case size to 300mm, added m1 cases, added pine64 cases, other fixes 2022-12-09 22:19:05 -05:00
Edward Kisiel
2f32d3c3b5 added part view in gui, added n2l and n2lq cases, updated sbc model framework 2022-12-07 21:07:16 -05:00
Edward Kisiel
2ed95c20d1 added h3_tallboy-ssd and h3_shell_drivebox2.5 cases 2022-11-03 17:21:10 -04:00
Edward Kisiel
788c6568ed added part selection for debug to facilitate individual part work and prints 2022-11-03 11:31:22 -04:00
Edward Kisiel
dd2162b480 added h3 tallboy case with internal fan 2022-11-02 19:50:26 -04:00
Edward Kisiel
934f88523a updated sbc model framework with h3 and h3+, added 3mm to h2 and h3 case bottoms that use an access port, access port tab and opening adjustment, additional rockpi5b changes 2022-11-01 16:44:20 -04:00
Edward Kisiel
98b8baa08d fixed panel case left hook size, added access panel and standoff trim to all rockpi5b cases, readme.md changes 2022-10-25 14:26:57 -04:00
Edward Kisiel
1d2826d015 added mask for microsdcard2, updated rockpi5b case data and sbc model framework 2022-10-22 18:16:54 -04:00
Edward Kisiel
2ccca31882 added hdmi_a_vertical mask, usbc single_vertical mask, created base cases and updated readme.md and sbc_model_framework in support of rockpi5b. 2022-10-13 20:48:17 -04:00
Edward Kisiel
3a757b95a4 changed .gitmodules from ssh to https access 2022-10-12 20:20:09 -04:00
46 changed files with 51616 additions and 27803 deletions

2
.gitmodules vendored
View File

@@ -1,3 +1,3 @@
[submodule "SBC_Model_Framework"]
path = SBC_Model_Framework
url = git@github.com:hominoids/SBC_Model_Framework.git
url = https://github.com/hominoids/SBC_Model_Framework.git

2859
README.md

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 MiB

After

Width:  |  Height:  |  Size: 3.8 MiB

BIN
SBC_Case_Builder_GUI.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 MiB

24632
dxf/astroid_8mm.dxf Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,17 +1,19 @@
// Gets a list of SBCs from the SBC Model Framework and Accessory sets
// for use with SBC Case Builder.
// After running this script, copy the output from the first Echo command into the
// list of SBC boards in `sbc_case_builder.scad:80`
// Also copy the output from the second Echo command into the list of case acceessory
// sets in `sbc_case_builder.scad:160`
/* Gets a list of SBCs from the SBC Model Framework and Accessory sets
for use with SBC Case Builder.
After running this script, copy the output from the first Echo command into the
list of SBC boards in `sbc_case_builder.scad:32` and `sbc_case_builder.scad`
6 locations line 82,90,98,106,114,122 for the sbc selection for the rack case design.
Also copy the output from the second Echo command into the list of case acceessory
sets in `sbc_case_builder.scad:196`
*/
include <./SBC_Model_Framework/sbc_models.cfg>;
include <./sbc_case_builder_accessories.cfg>;
echo(" ");
boards = [for(i=[0:1:len(sbc_data)-1]) sbc_data[i][0]];
echo("Copy the following to `sbc_case_builder.scad` for the `sbc_model` variable");
echo(boards);
echo(" ");
accessory_sets = [for(i=[0:1:len(accessory_data)-1]) accessory_data[i][0]];
echo("Copy the following to `sbc_case_builder.scad` for the `accessory_name` variable");
echo(accessory_sets);
echo(accessory_sets);
echo(" ");

170
lib/access_panel.scad Normal file
View File

@@ -0,0 +1,170 @@
/*
This file is part of SBC Case Builder https://github.com/hominoids/SBC_Case_Builder
Copyright 2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
This program 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.
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 this program. If not, see <http://www.gnu.org/licenses/>
Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
access_cover(size, orientation)
access_panel(size, orientation, mask)
*/
/*
NAME: access_cover
DESCRIPTION: creates covers for access port openings
TODO: none
USAGE: access_panel(size[], orientation)
size[0] = size_x
size[1] = size_y
size[2] = floor thickness
orientation = "landscape", "portrait"
*/
module access_cover(size, orientation) {
size_x = size[0];
size_y = size[1];
floorthick = size[2];
adj = .01;
$fn = 90;
if(orientation == "portrait") {
difference() {
union() {
translate([1, 6.25, 0]) cube([size_x-2.15, size_y-17.5, floorthick]);
translate([(size_x/2)-4.75, size_y-12.25, 0]) slab([10, 5, floorthick], 5);
translate([1, 6.25, floorthick-adj]) cube([size_x-2.15, 6, floorthick]);
translate([4.25, 3, floorthick]) cube([7.25, 4, 2]);
translate([size_x-12.75, 3, floorthick]) cube([7.25, 4, 2]);
if(size_x > 100) {
translate([(size_x/2)+.25, 3, floorthick]) cube([7.25, 4, 2]);
}
}
translate([(size_x/2)+.25, size_y-6.5, -floorthick-adj])
cylinder(d=3.2, h=(floorthick*2)+(adj*2));
translate([(size_x/2)+.25, size_y-6.5, -adj])
cylinder(d1=6, d2=3.2, h=floorthick);
}
}
if(orientation == "landscape") {
difference() {
union() {
translate([6.25, 0, 0]) cube([size_x-17.75, size_y-2, floorthick]);
translate([size_x-12.25, (size_y/2)-5.75, 0]) slab([5, 10, floorthick], 5);
translate([6.25, 0, floorthick-adj]) cube([6,size_y-2.15, floorthick]);
translate([3.5+adj, 3.25, floorthick]) cube([4, 7.25, 2]);
translate([3.5+adj, size_y-12.75, floorthick]) cube([4, 7.25, 2]);
if(size_y > 100) {
translate([3.5+adj, (size_y/2)-(7.75/2)-1, floorthick]) cube([4, 7.25, 2]);
}
}
translate([size_x-6.5, (size_y/2)-.75, -floorthick-adj])
cylinder(d=3.2, h=(floorthick*2)+(adj*2));
translate([size_x-6.5, (size_y/2)-.75, -adj])
cylinder(d1=6, d2=3.2, h=floorthick);
}
}
}
/*
NAME: access_panel
DESCRIPTION: creates opening and structure for access openings
TODO: none
USAGE: access_panel(size[], orientation, mask)
size[0] = size_x
size[1] = size_y
size[2] = floor thickness
orientation = "landscape", "portrait"
mask[0] = true enables component mask
mask[1] = mask length
mask[2] = mask setback
mask[3] = mstyle "default"
*/
module access_panel(size, orientation, mask) {
size_x = size[0];
size_y = size[1];
floorthick = size[2];
enablemask = mask[0];
mlength = mask[1];
msetback = mask[2];
mstyle = mask[3];
adj = .01;
$fn = 90;
if(enablemask == true && mstyle == "default") {
if(orientation == "portrait") {
translate([0,0,floorthick+adj-mlength+msetback]) cube([size_x, size_y, mlength]);
}
if(orientation == "landscape") {
translate([0, -1, floorthick+adj-mlength+msetback]) cube([size_x-1, size_y, mlength]);
}
}
if(enablemask == false) {
if(orientation == "portrait") {
difference() {
union() {
cube([size_x, size_y, floorthick]);
// access panel support
translate([(size_x/2)+.25, size_y-6.5, 0]) cylinder(d=9, h=floorthick+(adj*2)+5);
translate([(size_x/2)-10, size_y-11, floorthick-adj]) cube([20, 9.5, floorthick]);
translate([1, 0, floorthick-adj]) cube([size_x-2, 5, 4.5]);
}
// access opening
translate([.5, 6, -adj]) cube([size_x-1.15, size_y-17, floorthick+(adj*2)]);
translate([(size_x/2)-5, size_y-12, -adj]) slab([10.5, 5.5, floorthick], 5.5);
translate([(size_x/2)+.25, size_y-6.5, floorthick+2])
cylinder(r=3.2, h=floorthick+(adj*2)+5, $fn=6);
translate([(size_x/2)+.25, size_y-6.5, -adj])
cylinder(d=3.2, h=floorthick+(adj*2)+5);
translate([4, 2+adj, floorthick]) cube([7.75, 3, 2.75]);
translate([size_x-13, 2+adj, floorthick]) cube([7.75, 3, 2.75]);
if(size_x > 100) {
translate([(size_x/2), 2+adj, floorthick]) cube([7.75, 3, 2.75]);
}
}
}
if(orientation == "landscape") {
difference() {
union() {
translate([0, -1, 0]) cube([size_x, size_y, floorthick]);
// access panel support
translate([size_x-6.5, (size_y/2)-.5, 0]) cylinder(d=9, h=floorthick+(adj*2)+5);
translate([size_x-11, (size_y/2)-10.5, floorthick-adj]) cube([9.5, 20, floorthick]);
translate([0, 0, floorthick-adj]) cube([5, size_y-2, 4.5]);
}
// access opening
translate([6, -.5, -adj]) cube([size_x-17, size_y-1.15, floorthick+(adj*3)]);
translate([size_x-12, (size_y/2)-6, -adj]) slab([5.5, 10.5, floorthick], 5.5);
translate([size_x-6.5, (size_y/2)-.5, floorthick+2]) rotate([0, 0, 30])
cylinder(r=3.2, h=floorthick+(adj*2)+5, $fn=6);
translate([size_x-6.5, (size_y/2)-.5, -adj])
cylinder(d=3.2, h=floorthick+(adj*2)+5);
translate([2+adj, 3, floorthick]) cube([3, 8.25, 2.75]);
translate([2+adj, size_y-13, floorthick]) cube([3, 8.25, 2.75]);
if(size_y > 100) {
translate([2+adj, (size_y/2)-(7.75/2)-1.25, floorthick]) cube([3, 7.75, 2.5]);
}
}
}
}
}

59
lib/art.scad Normal file
View File

@@ -0,0 +1,59 @@
/*
This file is part of SBC Case Builder https://github.com/hominoids/SBC_Case_Builder
Copyright 2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
This program 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.
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 this program. If not, see <http://www.gnu.org/licenses/>
Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
art(scale_d1, size_z, filename)
stl_model(scale_d1, filename)
*/
/*
NAME: art
DESCRIPTION: create 2d artwork using dxf or svf
TODO: none
USAGE: art(scale_d1, size_z, filename)
scale_d1 = amount to scale file
size_z = floor thickness
filename = file name
*/
module art(scale_d1, size_z, filename) {
linear_extrude(height = size_z) import(file = filename, scale=scale_d1);
}
/*
NAME: stl_model
DESCRIPTION: import 3d artwork using stl
TODO: none
USAGE: stl_model(scale_d1, filename)
scale_d1 = amount to scale file
filename = file name
*/
module stl_model(scale_d1, filename) {
import(file = filename, scale=scale_d1);
}

132
lib/batteries.scad Normal file
View File

@@ -0,0 +1,132 @@
/*
This file is part of SBC Case Builder https://github.com/hominoids/SBC_Case_Builder
Copyright 2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
This program 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.
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 this program. If not, see <http://www.gnu.org/licenses/>
Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
battery(type)
battery_clip(bat_dia = 18.4)
batt_holder(tolerance)
*/
/*
NAME: battery
DESCRIPTION: creates 18650 and 21700 batteries
TODO: none
USAGE: battery(type)
type = "18650", "18650_convex", "21700"
*/
module battery(type) {
adj = .01;
if(type == "18650") {
difference() {
color("#73bc73") cylinder(d=18.4, h=65);
translate([0,0,65-4]) difference() {
cylinder(d=18.5, h=2);
cylinder(d=17.5, h=3);
}
}
}
if(type == "18650_convex") {
difference() {
color("#73bc73") cylinder(d=18.4, h=68);
translate([0,0,65-4]) difference() {
color("#73bc73") cylinder(d=18.5, h=2);
color("#73bc73") cylinder(d=17.5, h=3);
}
translate([0,0,65-adj]) difference() {
color("silver") cylinder(d=18.5, h=3+2*adj);
color("silver") cylinder(d=14.4, h=3+2*adj);
}
color("silver") translate([0,0,68-adj]) cylinder(d=14.4, h=.1);
}
}
if(type == "21700") {
difference() {
color("#73bc73") cylinder(d=21, h=70);
translate([0,0,70-4]) difference() {
cylinder(d=21.1, h=2);
cylinder(d=20.1, h=3);
}
}
}
}
/*
NAME: battery_clip
DESCRIPTION: creates 18650 and 21700 batteries
TODO: none
USAGE: battery_clip(bat_dia = 18.4)
*/
module battery_clip(bat_dia = 18.4) {
mat = .38;
width = 9.5;
tab = 8.9;
bat_holder = bat_dia+2*mat;
adj = .1;
translate([-5.5,0,10.5]) {
difference() {
translate([0,width,0]) rotate([90,0,0]) cylinder(d=bat_holder, h=9.5);
translate([0,width+adj,0]) rotate([90,0,0]) cylinder(d=bat_dia, h=10.5);
translate([mat/2-11.1/2,-adj,mat-1.3-bat_dia/2]) cube([11.1-mat,width+2*adj,3]);
translate([0,width+adj,0]) rotate([90,-45,0]) cube([bat_dia,bat_dia,bat_holder]);
}
difference() {
translate([-11.1/2,0,-1.3-bat_dia/2]) cube([11.1,width,3]);
translate([mat-11.1/2,-adj,mat/2-1.3-bat_dia/2]) cube([11.1-2*mat,width+2*adj,3]);
}
difference() {
translate([-(tab/2),-3.5,-1-bat_dia/2]) rotate([-5,0,0]) cube([tab,3.5,10]);
translate([-(tab/2)-adj,-3.5+mat,mat-1-bat_dia/2]) rotate([-5,0,0]) cube([tab+2*adj,3.5+mat,10]);
}
translate([0,-2.225,0]) rotate([85,0,0]) cylinder(d=tab, h=mat);
difference() {
translate([0,-2.75,0]) sphere(d=3);
translate([-5,-2.75,-5]) rotate([85,0,0]) cube([tab,10,10]);
}
}
}
/*
NAME: battery_holder
DESCRIPTION: creates cr2032 friction fit coinstyle holder
TODO: none
USAGE: batt_holder(tolerance)
*/
module batt_holder(tolerance) {
$fn = 90;
difference () {
cylinder(d=25.5,h=6);
translate ([0,0,-1]) cylinder(d=20.4+tolerance,h=8);
cube([14,26,13], true);
}
cylinder(r=12.75, h=2);
}

206
lib/buttons.scad Normal file
View File

@@ -0,0 +1,206 @@
/*
This file is part of SBC Case Builder https://github.com/hominoids/SBC_Case_Builder
Copyright 2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
This program 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.
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 this program. If not, see <http://www.gnu.org/licenses/>
Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
buttons(style, diameter, height, mask)
button_assembly(style, diameter, height)
button_clip(style)
button_plunger(style, diameter, height)
button_top(style, diameter, height)
*/
/*
NAME: buttons
DESCRIPTION: creates different button bodys and styles
TODO: none
USAGE: buttons(style, size, radius, post, mask)
style = "recess", "cutout"
size[0] = diameter of button body
size[2] = height above button
radius = radius for cutout style
post = button post size for cutout style
mask[0] = true enables component mask
mask[1] = mask length
mask[2] = mask setback
mask[3] = mstyle "default"
*/
module buttons(style, size, radius, post, mask) {
size_x = size[0];
size_y = size[1];
size_z = size[2];
diameter = size[0];
height = size[2];
gap = 1.5;
enablemask = mask[0];
mlength = mask[1];
msetback = mask[2];
mstyle = mask[3];
adj = .01;
$fn = 90;
if(enablemask == true && mstyle == "default") {
if(style == "recess") {
translate([0, 0, -adj-msetback]) cylinder(d = diameter-2*adj, h = mlength);
}
if(style == "cutout") {
translate([-size[0]+2.5, -2.5-size[1]/2, -adj-msetback]) cube([size[0]+1, size[1]+5, mlength]);
}
}
if(enablemask == false) {
if(style == "recess") {
difference() {
union() {
sphere(d=diameter);
translate([0,0,-height+3]) cylinder(d=6, h=height-6);
}
translate([-(diameter/2)-1,-(diameter/2)-1,0]) cube([diameter+2,diameter+2,(diameter/2)+2]);
difference() {
union() {
sphere(d=diameter-2);
}
}
translate([-1.75, -1.25, -height-1]) cube([3.5, 2.5, height+2]);
translate([0,0,-(diameter/2)]) cylinder(d=5, h=2);
}
}
if(style == "cutout") {
difference() {
translate([-size[0]+2, -3-size[1]/2, 0]) slab_r([size[0]+2,size[1]+6,size[2]-2*adj], [.1,.1,.1,.1]);
difference() {
translate([-size[0]+3, -size[1]/2, -adj])
slab_r([size[0],size[1],size[2]], [radius[0],radius[1],radius[2],radius[3]]);
translate([-size[0]+3+(gap/2), -size[1]/2+(gap/2), -1]) slab_r([size[0]-gap,size[1]-gap,1+size[2]+2*adj],
[radius[0],radius[1],radius[2]-gap/2,radius[3]-gap/2]);
translate([3-size[0]-gap, -1, -1]) cube([gap*2, 2, 1+height+2*adj]);
}
translate([0, 0, 2]) sphere(d=3);
}
translate([0, 0, adj-post]) cylinder(d=3, h=post);
}
}
}
/*
NAME: button_assembly
DESCRIPTION: creates button assembly of plunger,top,clip
TODO: none
USAGE: button_assembly(style, diameter, height)
style = "recess", "cutout"
diameter = diameter of button body
height = height above button
*/
module button_assembly(style, diameter, height) {
adj = .01;
$fn = 90;
if(style == "recess") {
button_plunger(style, diameter, height);
button_top(style, diameter, height);
translate([0,0,-height]) button_clip(style);
}
}
/*
NAME: button_clip
DESCRIPTION: creates button c-clip
TODO: none
USAGE: button_clip(style)
style = "recess", "cutout"
*/
module button_clip(style) {
adj = .01;
$fn = 90;
if(style == "recess") {
difference() {
cylinder(d=8.5, h=.8);
translate([-1.5,-1.75,-adj]) cube([2.75,3.25,1]);
translate([-.75,-.75,-adj]) cube([5,1.25,1.25]);
}
}
}
/*
NAME: button_plunger
DESCRIPTION: creates button plunger
TODO: none
USAGE: button_plunger(style, diameter, height)
style = "recess", "cutout"
diameter = diameter of button body
height = height above button
*/
module button_plunger(style, diameter, height) {
adj = .01;
$fn = 90;
if(style == "recess") {
difference() {
translate([-1.5,-1,-(height)-2]) cube([3,2,height+1]);
translate([-1.5-adj,-1.5,-height]) cube([.5,3,1]);
translate([1+adj,-1.5,-height]) cube([.5,3,1]);
translate([-1.5-adj,-1.5,-4]) cube([.5,3,4]);
translate([1+adj,-1.5,-4]) cube([.5,3,4]);
}
}
}
/*
NAME: button_top
DESCRIPTION: creates button top
TODO: none
USAGE: button_top(style, diameter, height)
style = "recess", "cutout"
diameter = diameter of button body
height = height above button
*/
module button_top(style, diameter, height) {
adj = .01;
$fn = 90;
if(style == "recess") {
difference() {
translate([0,0,-3]) cylinder(d=5, h=2.75);
translate([-1.25,-1.25,-3-adj]) cube([2.5,2.5,2]);
}
}
}

47
lib/cable_holder.scad Normal file
View File

@@ -0,0 +1,47 @@
/*
This file is part of SBC Case Builder https://github.com/hominoids/SBC_Case_Builder
Copyright 2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
This program 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.
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 this program. If not, see <http://www.gnu.org/licenses/>
Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
cableholder_spacer()
*/
/*
NAME: cableholder_spacer
DESCRIPTION: creates spacer and cable holder for drive mounts
TODO: none
USAGE: cableholder_spacer()
*/
module cableholder_spacer(length) {
size = [9.4,16,6];
adj = .01;
$fn = 90;
translate([0,size[2]/2,-5]) rotate([90,0,0])
difference() {
union() {
translate([size[0]/2,size[0]/2,0]) rotate([0,0,90]) long_slot(size[0],size[1],size[2]);
translate([-length,5,3]) rotate([0,90,0]) cylinder(d=6, h=length+9.4);
}
translate([-length-adj,5,3]) rotate([0,90,0]) cylinder(d=3.2, h=length+size[0]+2*adj);
translate([-1,8,-1]) cube([2,20,9]);
translate([5,9.5,-1]) rotate([0,0,90]) long_slot(4.5,11,9);
translate([3,20,-1]) rotate([0,0,45]) cube([2,6,9]);
}
}

138
lib/custom.scad Normal file
View File

@@ -0,0 +1,138 @@
/*
This file is part of SBC Case Builder https://github.com/hominoids/SBC_Case_Builder
Copyright 2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
This program 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.
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 this program. If not, see <http://www.gnu.org/licenses/>
Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
hk_h3_port_extender(style, mask)
hk_h3_port_extender_holder(part, offset)
*/
/*
NAME: hk_h3_port_extender
DESCRIPTION: @mctom's odroid-h3 gpio port extender
TODO: none
USAGE: hk_h3_port_extender(style, mask)
style = "header", "remote"
mask[0] = true enables component mask
mask[1] = mask length
mask[2] = mask setback
mask[3] = mstyle "default"
*/
module hk_h3_port_extender(style, mask) {
enablemask = mask[0];
mlength = mask[1];
msetback = mask[2];
mstyle = mask[3];
adj=.01;
$fn = 90;
if(style == "header") {
if(enablemask == true && mstyle == "default") {
translate([0, 14.5, 12-msetback]) cube([7.75, 15.75, mlength]);
translate([9.5, 14.5, 12-msetback]) cube([7.75, 15.75, mlength]);
translate([19, 14.5, 12-msetback]) cube([7.75, 15.75, mlength]);
translate([16, 32.2, 12-msetback]) cylinder(d=3, h=12);
}
if(enablemask == false) {
// gpio 24 pin front position
header("angled", -1.75, .1, 0, "top", 0, [12,2,8], ["thruhole","black","female",2.54,"silver"],
1.6, false, [true,10,2,"default"]);
difference() {
color("#008066") slab([33,35.25,1.6], .25);
color("#008066") translate([15.95,4.6,-1]) cylinder(d=3, h=6);
color("#008066") translate([15.95,32.15,-1]) cylinder(d=3, h=6);
}
header("angled", 27.65, 29.6, 0, "bottom", 90, [2,2,6], ["thruhole","black","male",2.54,"silver"],
1.6, false, [true,10,2,"default"]);
header("angled", 30.5, 16.5, 0, "bottom", 90, [5,2,6], ["thruhole","black","male",2.54,"silver"],
1.6, false, [true,10,2,"default"]);
usb2("single_up_a", .925, 15.375, 0, "top", 180, [0,10.5,0], [0], 1.6, false, [true,10,2,"default"]);
usb2("single_up_a", 10.395, 15.375, 0, "top", 180, [0,10.5,0], [0], 1.6, false, [true,10,2,"default"]);
usb2("single_up_a", 19.925, 15.375, 0, "top", 180, [0,10.5,0], [0], 1.6, false, [true,10,2,"default"]);
}
}
if(style == "remote") {
if(enablemask == true && mstyle == "default") {
translate([0, 14.5, 12-msetback]) cube([7.75, 15.75, mlength]);
translate([9.5, 14.5, 12-msetback]) cube([7.75, 15.75, mlength]);
translate([19, 14.5, 12-msetback]) cube([7.75, 15.75, mlength]);
translate([16, 32.2, 12-msetback]) cylinder(d=3, h=12);
translate([16, 4.6, 12-msetback]) cylinder(d=3, h=mlength);
}
if(enablemask == false) {
difference() {
color("#008066") slab([33,35.25,1.6], .25);
color("#008066") translate([15.95,4.6,-1]) cylinder(d=3, h=6);
color("#008066") translate([15.95,32.15,-1]) cylinder(d=3, h=6);
}
// gpio 24 pin front position
header("open", .75, 9, 0, "bottom", 0, [12,2,6], ["thruhole","black","male",2.54,"silver"],
1.6, false, [true,10,2,"default"]);
header("angled", 27.65, 29.6, 0, "bottom", 90, [2,2,6], ["thruhole","black","male",2.54,"silver"],
1.6, false, [true,10,2,"default"]);
header("angled", 30.5, 16.5, 0, "bottom", 90, [5,2,6], ["thruhole","black","male",2.54,"silver"],
1.6, false, [true,10,2,"default"]);
usb2("single_up_a", .925, 15.375, 0, "top", 180, [0,10.5,0], [0], 1.6, false, [true,10,2,"default"]);
usb2("single_up_a", 10.395, 15.375, 0, "top", 180, [0,10.5,0], [0], 1.6, false, [true,10,2,"default"]);
usb2("single_up_a", 19.925, 15.375, 0, "top", 180, [0,10.5,0], [0], 1.6, false, [true,10,2,"default"]);
}
}
}
/*
NAME: hk_h3_port_extender_holder
DESCRIPTION: holder for the @mctom's remote h3 port extender
TODO: none
USAGE: hk_h3_port_extender_holder(part, offset)
part = "top","bottom","both"
offset = distance from mount face
*/
module hk_h3_port_extender_holder(part,offset=2) {
size = [16-offset,40,5.5];
adj = .01;
if(part == "bottom" || part == "both") {
difference() {
translate([-10+offset,-3.5,2]) cube(size);
translate([-.25,-.25,-adj]) cube([2.5, 33.25, 12]);
translate([2, 2, -adj]) cube([10, 28, 12]);
translate([-12,(33.25/2)+.25,4.5]) rotate([0,90,0]) cylinder(d=2.7, h=20, $fn=60);
// translate([-7,-1.,-adj]) cylinder(d=4.25, h=20);
}
}
if(part == "top" || part == "both") {
difference() {
translate([-10+offset,-3.5,29.5]) cube(size);
translate([-.25,-.25,28]) cube([2.5, 33.25, 12]);
translate([1.5, 2, 27.5-adj]) cube([10, 28.5, 12]);
translate([-12, -4, 28]) cube([20, 13, 10]);
translate([1.35, 20, 25.5]) cube([10, 13, 5]);
translate([-12,(33.25/2)+.25,32]) rotate([0,90,0]) cylinder(d=2.7, h=20, $fn=60);
}
}
}

107
lib/dsub.scad Normal file
View File

@@ -0,0 +1,107 @@
/*
This file is part of SBC Case Builder https://github.com/hominoids/SBC_Case_Builder
Copyright 2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
This program 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.
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 this program. If not, see <http://www.gnu.org/licenses/>
Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
dsub(style, gender, mask)
*/
/*
NAME: dsub
DESCRIPTION: creates dsub connectors
TODO: 9db male, 25db male and female
USAGE: dsub(style, gender, mask)
style = "db9"
gender = "female","male"
mask[0] = true enables component mask
mask[1] = mask length
mask[2] = mask setback
mask[3] = mstyle "default"
*/
module dsub(style, gender, mask) {
enablemask = mask[0];
mlength = mask[1];
msetback = mask[2];
mstyle = mask[3];
adj = .01;
$fn = 90;
if(enablemask == true && mstyle == "default") {
translate([0,0,-msetback]) union() {
hull() {
translate([-7,3,-5]) cylinder(d=3, h=11+mlength);
translate([7,3,-5]) cylinder(d=3, h=11+mlength);
translate([-6.25,-3,-5]) cylinder(d=3, h=11+mlength);
translate([6.25,-3,-5]) cylinder(d=3, h=11+mlength);
}
// mount holes
translate([-12.5,0,-5]) cylinder(d=3.5, h=11+mlength);
translate([12.5,0,-5]) cylinder(d=3.5, h=11+mlength);
}
}
if(enablemask == false) {
if(style == "db9" && gender =="female") {
difference() {
union() {
color("silver") hull() {
translate([-6.5,2.5,-5]) cylinder(d=3, h=11);
translate([6.5,2.5,-5]) cylinder(d=3, h=11);
translate([-5.75,-2.5,-5]) cylinder(d=3, h=11);
translate([5.75,-2.5,-5]) cylinder(d=3, h=11);
}
color("black") hull() {
translate([-6,2.25,-6]) cylinder(d=3, h=12.25);
translate([6,2.25,-6]) cylinder(d=3, h=12.25);
translate([-5.25,-2.25,-6]) cylinder(d=3, h=12.25);
translate([5.25,-2.25,-6]) cylinder(d=3, h=12.25);
}
// mount plate
translate([-15.5,-6.5,-.25]) slab([31,13,.5], 2);
// rear pins
color("silver") translate([-5.48,1.4,-8]) cylinder(d=1.5, h=9);
color("silver") translate([-2.74,1.4,-8]) cylinder(d=1.5, h=9);
color("silver") translate([0,1.4,-8]) cylinder(d=1.5, h=9);
color("silver") translate([2.74,1.4,-8]) cylinder(d=1.5, h=9);
color("silver") translate([5.48,1.4,-8]) cylinder(d=1.5, h=9);
color("silver") translate([-4.12,-1.4,-8]) cylinder(d=1.5, h=9);
color("silver") translate([-1.38,-1.4,-8]) cylinder(d=1.5, h=9);
color("silver") translate([1.36,-1.4,-8]) cylinder(d=1.5, h=9);
color("silver") translate([4,-1.4,-8]) cylinder(d=1.5, h=9);
}
// mount holes
color("silver") translate([-12.5,0,-3]) cylinder(d=3.2, h=6);
color("silver") translate([12.5,0,-3]) cylinder(d=3.2, h=6);
// pin holes
color("silver") translate([-5.48,1.4,-9]) cylinder(d=1, h=16);
color("silver") translate([-2.74,1.4,-9]) cylinder(d=1, h=16);
color("silver") translate([0,1.4,-9]) cylinder(d=1, h=16);
color("silver") translate([2.74,1.4,-9]) cylinder(d=1, h=16);
color("silver") translate([5.48,1.4,-9]) cylinder(d=1, h=16);
color("silver") translate([-4.12,-1.4,-9]) cylinder(d=1, h=16);
color("silver") translate([-1.38,-1.4,-9]) cylinder(d=1, h=16);
color("silver") translate([1.36,-1.4,-9]) cylinder(d=1, h=16);
color("silver") translate([4,-1.4,-9]) cylinder(d=1, h=16);
}
}
}
}

132
lib/fans.scad Normal file
View File

@@ -0,0 +1,132 @@
/*
This file is part of SBC Case Builder https://github.com/hominoids/SBC_Case_Builder
Copyright 2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
This program 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.
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 this program. If not, see <http://www.gnu.org/licenses/>
Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
fans(style, mask)
fan_cover(size, thick)
fan_mask(size, thick, style)
*/
/*
NAME: fans
DESCRIPTION: creates different fan styles and sizes
TODO: add efficient vanes
USAGE: fans(style, mask)
style = "box",
mask[0] = true enables component mask
mask[1] = mask length
mask[2] = mask setback
mask[3] = mstyle "default", "fan_open", "fan_1", "fan_2", "fan_hex"
*/
module fans(style, mask) {
// size, thick, hole-spacing, hole-size, hub-size
fan_data = [
["box140x25", 140, 25, 124.5, 4.3, 40, "#353535"],
["box120x25", 120, 25, 105, 4.3, 40, "#353535"],
["box92x25", 92, 25, 82.5, 4.3, 40, "#353535"],
["box92x10", 92, 10, 82.5, 4.3, 40, "#353535"],
["box80x25", 80, 25, 72.5, 4.3, 35, "#353535"],
["box80x10", 80, 10, 72.5, 4.3, 35, "#353535"],
["box60x25", 60, 25, 50, 4.3, 30, "#353535"],
["box60x10", 60, 10, 50, 4.3, 30, "#353535"],
["box50x10", 60, 10, 40, 4.3, 20, "#353535"],
["box40x10", 40, 10, 32, 4.3, 18, "#353535"],
["box30x10", 30, 10, 24, 3.2, 12, "#353535"],
["box25x10", 25, 10, 20, 3, 12, "#353535"]
];
f = search([style],fan_data);
diameter = fan_data[f[0]][1];
thickness = fan_data[f[0]][2];
hole_space = fan_data[f[0]][3];
hole_size = fan_data[f[0]][4];
hole_offset = (diameter-hole_space)/2;
hub_size = fan_data[f[0]][5];
fan_color = fan_data[f[0]][6];
enablemask = mask[0];
mlength = mask[1];
msetback = mask[2];
mstyle = mask[3];
adj = .01;
$fn = 90;
if(enablemask == true) {
if(mstyle == "fan_open") {
translate([0, 0, thickness-msetback+1]) fan_mask(diameter, mlength, "fan_open");
}
if(mstyle == "default" || mstyle == "fan_1") {
translate([0, 0, thickness-msetback+1]) fan_mask(diameter, mlength, "fan_1");
}
if(mstyle == "fan_2") {
translate([0, 0, thickness-msetback+1]) fan_mask(diameter, mlength, "fan_2");
}
if(mstyle == "fan_hex") {
translate([0, 0, thickness-msetback+1]) fan_mask(diameter, mlength, "fan_hex");
}
}
if(enablemask == false) {
difference() {
union() {
color(fan_color) slab([diameter, diameter, 3], 4);
color(fan_color) translate([0, 0, thickness-3]) slab([diameter, diameter, 3], 4);
color(fan_color) translate([diameter/2, diameter/2, 0]) cylinder(d=diameter+2, h=thickness);
}
// holes
color(fan_color) translate([diameter/2, diameter/2, -1]) cylinder(d=diameter-2, h=thickness+2);
color(fan_color) translate([hole_offset,hole_offset,-1]) cylinder(d=hole_size, h=thickness+2);
color(fan_color) translate([hole_offset,diameter-hole_offset,-1]) cylinder(d=hole_size, h=thickness+2);
color(fan_color) translate([diameter-hole_offset,hole_offset,-1]) cylinder(d=hole_size, h=thickness+2);
color(fan_color) translate([diameter-hole_offset,diameter-hole_offset,-1]) cylinder(d=hole_size, h=thickness+2);
// trim sides
color(fan_color) translate([-4,-4, -1]) cube([4, diameter+8, thickness+2]);
color(fan_color) translate([diameter,-4, -1]) cube([4, diameter+8, thickness+2]);
color(fan_color) translate([-4,-4, -1]) cube([diameter+8, 4, thickness+2]);
color(fan_color) translate([-4,diameter, -1]) cube([diameter+8, 4, thickness+2]);
}
color(fan_color) translate([diameter/2, diameter/2, thickness/2]) rotate([0,0,30])
cylinder_fillet_inside(h=thickness, r=hub_size/2, top=1, bottom=1, $fn=90, fillet_fn=90, center=true);
}
}
/*
NAME: fan_cover
DESCRIPTION: creates fan covers for fan openings
TODO: none
USAGE: fan_cover(size, thick, style)
size = size of fan
thick = thickness of cover
style = "fan_open", "fan_1", "fan_2", "fan_hex"
*/
module fan_cover(size, thick, style) {
difference() {
color("grey", 1) slab([size, size, thick], 3);
color("grey", 1) fan_mask(size, thick, style);
}
}

81
lib/fastener.scad Normal file
View File

@@ -0,0 +1,81 @@
/*
This file is part of SBC Case Builder https://github.com/hominoids/SBC_Case_Builder
Copyright 2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
This program 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.
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 this program. If not, see <http://www.gnu.org/licenses/>
Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
m_insert(type="M3", icolor = "#ebdc8b")
*/
/*
NAME: m_insert
DESCRIPTION: creates brass inserts for models
TODO: none
USAGE: m_insert(type="m3", icolor = "#ebdc8b")
type = "m3"
icolor = color of insert
*/
module m_insert(type="m3", icolor = "#ebdc8b") { //#f4e6c3, #ebdc8b
odiam = type == "m3" ? 4.2 : 3.5;
idiam = type == "m3" ? 3 : 2.5;
iheight = 4;
difference() {
color(icolor,.6) cylinder(d=odiam, h=iheight);
color(icolor,.6) translate([0,0,-1]) cylinder(d=idiam, h=iheight+2);
}
for(bearing = [0:10:360]) {
color(icolor) translate([-.25+(odiam/2)*cos(bearing), -.25+(odiam/2)*sin(bearing), iheight-1.5])
cube([.5, .5, 1.5]);
}
}
/*
NAME: washer
DESCRIPTION: creates washers
TODO: none
USAGE: washer(type="round", id=3, od=6, iheight=2, sheight=2, countersunk, icolor = "#ebdc8b")
type = "round", "shouldered"
id = inside diameter
od = outside diameter
iheight = washer thickness
sheight = shoulder height
countersunk = true
icolor = color of washer
*/
module washer(type="round", id=3, od=6, iheight=2, sheight=2, countersunk = false, icolor = "#ebdc8b") { //#f4e6c3, #ebdc8b
difference() {
union() {
color(icolor,.6) cylinder(d=od, h=iheight);
if(type == "shouldered") {
color(icolor,.6) cylinder(d=od+4, h=sheight);
}
}
color(icolor,.6) translate([0,0,-1]) cylinder(d=id, h=od+sheight+2);
if(type == "shouldered" && countersunk == true) {
color(icolor,.6) translate([0,0,-.01]) cylinder(d2=id, d1=6, h=sheight);
}
}
}

42
lib/feet.scad Normal file
View File

@@ -0,0 +1,42 @@
/*
This file is part of SBC Case Builder https://github.com/hominoids/SBC_Case_Builder
Copyright 2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
This program 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.
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 this program. If not, see <http://www.gnu.org/licenses/>
Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
feet (diameter, height)
*/
/*
NAME: feet
DESCRIPTION: creates simple case feet
TODO: none
USAGE: feet (diameter, height)
diameter = size of fan
height = thickness of cover
*/
module feet (diameter, height) {
difference (){
cylinder (d=diameter,h=height);
translate([0,0,-1]) cylinder (d=3, h=height+2,$fn=90);
translate ([0,0,-1]) cylinder(r=3.35,h=height-3,$fn=6);
}
}

109
lib/grommet.scad Normal file
View File

@@ -0,0 +1,109 @@
/*
This file is part of SBC Case Builder https://github.com/hominoids/SBC_Case_Builder
Copyright 2022,2023,2024,2025 Edward A. Kisiel hominoid@cablemi.com
This program 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.
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 this program. If not, see <http://www.gnu.org/licenses/>
Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
grommet(face, style, od, id, wall, assembly, mask)
grommet_clip(style, od, id, wall)
*/
/*
NAME: grommet
DESCRIPTION: creates different groumet styles
TODO: none
USAGE: grommet(face, style, od, id, wall, assembly, mask)
data[0] = "top","bottom","front","rear","left","right"
data[1] = "sleeve"
size[0] = od outside diameter of grommet body
size[1] = id inside hole diameter of grommet body
size[2] = wall thickness of installation
data[3] = assembled true, false
mask[0] = true enables component mask
mask[1] = mask length
mask[2] = mask setback
mask[3] = mstyle "default"
*/
module grommet(face = "bottom", style = "sleeve", od, id, wall, assembly, mask) {
height = 4.5+(2*wall);
enablemask = mask[0];
mlength = height+mask[1];
msetback = mask[2];
mstyle = mask[3];
cut = .25;
lip_od = od+4;
lip_thick = 2.5;
adj = .01;
$fn = 90;
rotx = face == "rear" ? 270 : face == "front" || face == "left" || face == "right" ? 90 : face == "top" ? 180 : 0;
roty = 0;
rotz = face == "left" ? 90 : face == "right" ? 270 : 0;
rx = face == "left" ? -lip_thick : face == "right" ? lip_thick : 0;
ry = face == "front" ? lip_thick : face == "rear" ? -lip_thick : 0;
rz = face == "bottom" ? -lip_thick : face == "top" ? lip_thick : 0;
translate([rx,ry,rz]) rotate([rotx,roty,rotz]) {
if(enablemask == true && mstyle == "default") {
if(style == "sleeve") {
translate([0, 0, -adj-msetback]) cylinder(d = od+.5, h = mlength);
}
}
if(enablemask == false) {
if(style == "sleeve") {
difference() {
union() {
cylinder(d=od, h=height);
cylinder(d=lip_od, h=2.5);
}
translate([0,0,-adj]) cylinder(d=id, h=height+(2*adj));
translate([-lip_od/2,-cut/2,-adj]) cube([lip_od+(2*adj),cut,height+(2*adj)]);
translate([0,0,2.75+wall]) grommet_clip(style,od,id,wall);
}
if(assembly == true) {
translate([0,0,2.5+wall]) grommet_clip(style,od,id,wall);
}
}
}
}
}
module grommet_clip(style,od,id,wall) {
height = 2.5+wall;
lip_od = od+4;
adj = .01;
$fn = 90;
if(style == "sleeve") {
difference() {
cylinder(d=lip_od, h=2.5);
difference() {
translate([0,0,-adj]) cylinder(d=od, h=wall+2.5);
translate([-lip_od/2,-od/2,-adj]) cube([lip_od+(2*adj),2,height-2]);
translate([-lip_od/2,-2+od/2,-adj]) cube([lip_od+(2*adj),2,height-2]);
}
translate([-lip_od,-(od-6)/2,-adj]) cube([lip_od+(2*adj),od-6,wall+2.5]);
}
}
}

930
lib/hd.scad Normal file
View File

@@ -0,0 +1,930 @@
/*
This file is part of SBC Case Builder https://github.com/hominoids/SBC_Case_Builder
Copyright 2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
This program 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.
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 this program. If not, see <http://www.gnu.org/licenses/>
Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
hd25(orientation, height, mask)
hd25_tab(side)
hd25_vtab(side)
hd35(orientation, mask)
hd35_25holder(length,width)
hd35_tab(side)
hd35_vtab(side)
hd_bottom_holes(hd, orientation, side, thick, holetype)
hd_mount(hd, orientation, position, side)
*/
/*
NAME: hd25
DESCRIPTION: creates 2.5" hard drive model
TODO: none
USAGE: hd25(orientation, height, mask)
orientation = "landscape", "portrait"
height = drive height
mask[0] = true enables component mask
mask[1] = mask length
mask[2] = mask setback
mask[3] = mstyle "default", "bottom", "side", "both"
*/
module hd25(orientation, height, mask) {
hd25_x = 100;
hd25_y = 69.85;
hd25_z = height;
enablemask = mask[0];
mlength = mask[1];
msetback = mask[2];
mstyle = mask[3];
adj = .01;
$fn = 90;
if(enablemask == true) {
if(orientation == "landscape" && (mstyle == "side" || mstyle == "both" || mstyle == "default")) {
translate([0, msetback, 0]) hd_holes(2.5, "landscape", "left", mlength);
translate([0, -msetback, 0]) hd_holes(2.5, "landscape", "right", mlength);
}
if(orientation == "landscape" && (mstyle == "bottom" || mstyle == "both")) {
translate([0, 0, msetback]) hd_holes(2.5, "landscape", "bottom", mlength);
}
if(orientation == "portrait" && (mstyle == "side" || mstyle == "both" || mstyle == "default")) {
translate([msetback, 0, 0]) hd_holes(2.5, "portrait", "left", mlength);
translate([-msetback, 0, 0]) hd_holes(2.5, "portrait", "right", mlength);
}
if(orientation == "portrait" && (mstyle == "bottom" || mstyle == "both")) {
translate([0, 0, -mlength+msetback]) hd_holes(2.5, "portrait", "bottom", mlength);
}
}
if(enablemask == false) {
if(orientation == "landscape") {
difference() {
color("LightGrey",.6) cube([hd25_x,hd25_y,hd25_z]);
// bottom screw holes
color("Black",.6) translate([9.4,4.07,-adj]) cylinder(d=3,h=3);
color("Black",.6) translate([86,4.07,-adj]) cylinder(d=3,h=3);
color("Black",.6) translate([86,65.79,-adj]) cylinder(d=3,h=4);
color("Black",.6) translate([9.4,65.79,-adj]) cylinder(d=3,h=4);
// side screw holes
color("Black",.6) translate([9.4,-adj,3]) rotate([-90,0,0]) cylinder(d=3,h=3);
color("Black",.6) translate([86,-adj,3]) rotate([-90,0,0]) cylinder(d=3,h=3);
color("Black",.6) translate([86,hd25_y+adj,3]) rotate([90,0,0]) cylinder(d=3,h=3);
color("Black",.6) translate([9.4,hd25_y+adj,3]) rotate([90,0,0]) cylinder(d=3,h=3);
// connector opening
color("LightSlateGray",.6) translate([hd25_x-5,11,-1]) cube([5+adj,32,5+adj]);
}
}
if(orientation == "portrait") {
translate([0,hd25_x,0]) rotate([0,0,270])
difference() {
color("LightGrey",.6) cube([hd25_x,hd25_y,hd25_z]);
// bottom screw holes
color("Black",.6) translate([9.4,4.07,-adj]) cylinder(d=3,h=3);
color("Black",.6) translate([86,4.07,-adj]) cylinder(d=3,h=3);
color("Black",.6) translate([86,65.79,-adj]) cylinder(d=3,h=4);
color("Black",.6) translate([9.4,65.79,-adj]) cylinder(d=3,h=4);
// side screw holes
color("Black",.6) translate([9.4,-adj,3]) rotate([-90,0,0]) cylinder(d=3,h=3);
color("Black",.6) translate([86,-adj,3]) rotate([-90,0,0]) cylinder(d=3,h=3);
color("Black",.6) translate([86,hd25_y+adj,3]) rotate([90,0,0]) cylinder(d=3,h=3);
color("Black",.6) translate([9.4,hd25_y+adj,3]) rotate([90,0,0]) cylinder(d=3,h=3);
// connector opening
color("LightSlateGray",.6) translate([hd25_x-5,11,-1]) cube([5+adj,32,5+adj]);
}
}
}
}
/*
NAME: hd25_tab
DESCRIPTION: creates 2.5" hard drive tabs for horizontal mounting
TODO: none
USAGE: hd25_tab(side)
side = "left", "right"
*/
module hd25_tab(side) {
width = 15;
l_width = 26;
depth = 15;
height = 4;
fillet = 2;
hole = 3.6;
length = 3;
adj = .01;
$fn = 90;
if(side == "left") {
difference() {
union() {
translate([0,-depth/2,0]) rotate([0,-90,0])
slab_r([l_width,depth,height], [fillet,fillet,fillet,fillet]);
translate([-height,-depth/2,0]) cube([height,depth,height]);
translate([adj,-5.5,depth])
rotate([90,0,0])
linear_extrude(height = 2)
polygon(points = [ [-height,height],
[-depth+4,-depth],
[-height,-depth]]);
translate([adj,7.5,depth])
rotate([90,0,0])
linear_extrude(height = 2)
polygon(points = [ [-height,height],
[-depth+4,-depth],
[-height,-depth]]);
}
translate([4.07,0,-adj]) rotate([0,0,0]) cylinder(d=hole, h=3);
translate([-height-adj,(width/2)-(length/2)-depth/2,3]) rotate([90,0,90]) slot(hole,length,height+(2*adj));
translate([-height-adj,(width/2)-(length/2)-depth/2,21]) rotate([90,0,90]) slot(hole,length,height+(2*adj));
}
}
if(side == "right") {
difference() {
union() {
translate([height,-depth/2,0]) rotate([0,-90,0])
slab_r([l_width,depth,height], [fillet,fillet,fillet,fillet]);
translate([0,-depth/2,0]) cube([height,depth,height]);
translate([adj,-7.5,depth])
rotate([90,0,180])
linear_extrude(height = 2)
polygon(points = [ [-height,height],
[-depth+4,-depth],
[-height,-depth]]);
translate([adj,5.5,depth])
rotate([90,0,180])
linear_extrude(height = 2)
polygon(points = [ [-height,height],
[-depth+4,-depth],
[-height,-depth]]);
}
translate([-4.07,0,-adj]) rotate([0,0,0]) cylinder(d=hole, h=3);
translate([-adj,(width/2)-(length/2)-depth/2,3]) rotate([90,0,90]) slot(hole,length,height+(2*adj));
translate([-adj,(width/2)-(length/2)-depth/2,21]) rotate([90,0,90]) slot(hole,length,height+(2*adj));
}
}
}
/*
NAME: hd25_vtab
DESCRIPTION: creates 2.5" hard drive tabs for vertical mounting
TODO: none
USAGE: hd25_vtab(side)
side = "left", "right"
*/
module hd25_vtab(side) {
width = 15;
l_width = 16;
depth = 15;
height = 4;
fillet = 2;
hole = 3.6;
length = 3;
adj = .01;
$fn = 90;
if(side == "left") {
difference() {
union() {
translate([0,-depth/2,0]) rotate([0,-90,0])
slab_r([l_width,depth,height], [fillet,fillet,fillet,fillet]);
translate([-height,-depth/2,0]) cube([height,depth,height]);
translate([adj,-5.5,depth])
rotate([90,0,0])
linear_extrude(height = 2)
polygon(points = [ [-height,height-5],
[-depth+4,-depth],
[-height,-depth]]);
translate([adj,7.5,depth])
rotate([90,0,0])
linear_extrude(height = 2)
polygon(points = [ [-height,height-5],
[-depth+4,-depth],
[-height,-depth]]);
}
translate([3,0,-adj]) rotate([0,0,0]) cylinder(d=hole, h=3);
translate([-height-adj,1.5+(width/2)-(length/2)-depth/2,5.57]) rotate([90,90,90]) slot(hole,length,height+(2*adj));
}
}
if(side == "right") {
difference() {
union() {
translate([height,-depth/2,0]) rotate([0,-90,0])
slab_r([l_width,depth,height], [fillet,fillet,fillet,fillet]);
translate([0,-depth/2,0]) cube([height,depth,height]);
translate([adj,-7.5,depth])
rotate([90,0,180])
linear_extrude(height = 2)
polygon(points = [ [-height,height-5],
[-depth+4,-depth],
[-height,-depth]]);
translate([adj,5.5,depth])
rotate([90,0,180])
linear_extrude(height = 2)
polygon(points = [ [-height,height-5],
[-depth+4,-depth],
[-height,-depth]]);
}
translate([-3,0,-adj]) rotate([0,0,0]) cylinder(d=hole, h=3);
translate([-adj,1.5+(width/2)-(length/2)-depth/2,5.57]) rotate([90,90,90]) slot(hole,length,height+(2*adj));
}
}
}
/*
NAME: hd35
DESCRIPTION: creates 3.5" hard drive model
TODO: none
USAGE: hd35(orientation, mask)
orientation = "landscape", "portrait"
mask[0] = true enables component mask
mask[1] = mask length
mask[2] = mask setback
mask[3] = mstyle "default", "bottom", "side", "both"
*/
module hd35(orientation, mask) {
hd35_x = 147;
hd35_y = 101.6;
hd35_z = 26.1;
enablemask = mask[0];
mlength = mask[1];
msetback = mask[2];
mstyle = mask[3];
adj = .01;
$fn = 90;
if(enablemask == true) {
if(orientation == "landscape" && (mstyle == "side" || mstyle == "both" || mstyle == "default")) {
translate([0, msetback, 0]) hd_holes(3.5, "landscape", "left", mlength);
translate([0, -msetback, 0]) hd_holes(3.5, "landscape", "right", mlength);
}
if(orientation == "landscape" && (mstyle == "bottom" || mstyle == "both")) {
translate([0, 0, msetback]) hd_holes(3.5, "landscape", "bottom", mlength);
}
if(orientation == "portrait" && (mstyle == "side" || mstyle == "both" || mstyle == "default")) {
translate([msetback, 0, 0]) hd_holes(3.5, "portrait", "left", mlength);
translate([-msetback, 0, 0]) hd_holes(3.5, "portrait", "right", mlength);
}
if(orientation == "portrait" && (mstyle == "bottom" || mstyle == "both")) {
translate([0, 0, -mlength+msetback]) hd_holes(3.5, "portrait", "bottom", mlength);
}
}
if(enablemask == false) {
if(orientation == "landscape") {
difference() {
color("LightGrey",.6) cube([hd35_x,hd35_y,hd35_z]);
// bottom screw holes
color("Black",.6) translate([29.52,3.18,-adj]) cylinder(d=3,h=3+adj);
color("Black",.6) translate([61.27,3.18,-adj]) cylinder(d=3,h=3+adj);
color("Black",.6) translate([105.72,3.18,-adj]) cylinder(d=3,h=3+adj);
color("Black",.6) translate([29.52,98.43,-adj]) cylinder(d=3,h=3+adj);
color("Black",.6) translate([61.27,98.43,-adj]) cylinder(d=3,h=3+adj);
color("Black",.6) translate([105.72,98.43,-adj]) cylinder(d=3,h=3+adj);
// side screw holes
color("Black",.6) translate([16.9,-adj,6.35]) rotate([-90,0,0]) cylinder(d=3,h=3);
color("Black",.6) translate([76.6,-adj,6.35]) rotate([-90,0,0]) cylinder(d=3,h=3);
color("Black",.6) translate([118.5,-adj,6.35]) rotate([-90,0,0]) cylinder(d=3,h=3);
color("Black",.6) translate([118.5,hd35_y+adj,6.35]) rotate([90,0,0]) cylinder(d=3,h=3);
color("Black",.6) translate([76.6,hd35_y+adj,6.35]) rotate([90,0,0]) cylinder(d=3,h=3);
color("Black",.6) translate([16.9,hd35_y+adj,6.35]) rotate([90,0,0]) cylinder(d=3,h=3);
// connector opening
color("LightSlateGray",.6) translate([hd35_x-5,11,-1]) cube([5+adj,32,5+adj]);
}
}
if(orientation == "portrait") {
translate([0,hd35_x,0]) rotate([0,0,270])
difference() {
color("LightGrey",.6) cube([hd35_x,hd35_y,hd35_z]);
// bottom screw holes
color("Black",.6) translate([29.52,3.18,-adj]) cylinder(d=3,h=3+adj);
color("Black",.6) translate([61.27,3.18,-adj]) cylinder(d=3,h=3+adj);
color("Black",.6) translate([105.72,3.18,-adj]) cylinder(d=3,h=3+adj);
color("Black",.6) translate([29.52,98.43,-adj]) cylinder(d=3,h=3+adj);
color("Black",.6) translate([61.27,98.43,-adj]) cylinder(d=3,h=3+adj);
color("Black",.6) translate([105.72,98.43,-adj]) cylinder(d=3,h=3+adj);
// side screw holes
color("Black",.6) translate([16.9,-adj,6.35]) rotate([-90,0,0]) cylinder(d=3,h=3);
color("Black",.6) translate([76.6,-adj,6.35]) rotate([-90,0,0]) cylinder(d=3,h=3);
color("Black",.6) translate([118.5,-adj,6.35]) rotate([-90,0,0]) cylinder(d=3,h=3);
color("Black",.6) translate([118.5,hd35_y+adj,6.35]) rotate([90,0,0]) cylinder(d=3,h=3);
color("Black",.6) translate([76.6,hd35_y+adj,6.35]) rotate([90,0,0]) cylinder(d=3,h=3);
color("Black",.6) translate([16.9,hd35_y+adj,6.35]) rotate([90,0,0]) cylinder(d=3,h=3);
// connector opening
color("LightSlateGray",.6) translate([hd35_x-5,11,-1]) cube([5+adj,32,5+adj]);
}
}
}
}
/*
NAME: hd35_25holder
DESCRIPTION: 3.5" hdd to 2.5" hdd holder
TODO: none
USAGE: hd35_25holder(length, width=101.6)
length = length of holder min. 145mm for 3.5" drive
*/
module hd35_25holder(length, width=101.6) {
wallthick = 3;
floorthick = 2;
hd35_x = length; // 145mm for 3.5" drive
hd35_y = width;
hd35_z = 12;
hd25_x = 100;
hd25_y = 69.85;
hd25_z = 9.5;
hd25_xloc = 2; // or (hd35_x-hd25_x)/2
hd25_yloc = (hd35_y-hd25_y)/2;
hd25_zloc = 9.5;
adj = .1;
$fn=90;
difference() {
union() {
difference() {
translate([(hd35_x/2),(hd35_y/2),(hd35_z/2)])
cube_fillet_inside([hd35_x,hd35_y,hd35_z],
vertical=[3,3,3,3], top=[0,0,0,0], bottom=[0,0,0,0], $fn=90);
translate([(hd35_x/2),(hd35_y/2),(hd35_z/2)+floorthick])
cube_fillet_inside([hd35_x-(wallthick*2),hd35_y-(wallthick*2),hd35_z],
vertical=[0,0,0,0], top=[0,0,0,0], bottom=[0,0,0,0], $fn=90);
// end trim
translate([-adj,5,wallthick+2]) cube([wallthick+(adj*2),hd35_y-10,10]);
translate([hd35_x-wallthick-adj,5,wallthick+2]) cube([wallthick+(adj*2),hd35_y-10,10]);
// bottom vents
for ( r=[15:40:hd35_x-40]) {
for (c=[hd35_y-76:4:75]) {
translate ([r,c,-adj]) cube([35,2,wallthick+(adj*2)]);
}
}
}
// 2.5 hdd bottom support
translate([9.4+hd25_xloc,4.07+hd25_yloc,floorthick-adj]) cylinder(d=8,h=4);
translate([86+hd25_xloc,4.07+hd25_yloc,floorthick-adj]) cylinder(d=8,h=4);
translate([86+hd25_xloc,65.79+hd25_yloc,floorthick-adj]) cylinder(d=8,h=4);
translate([9.4+hd25_xloc,65.79+hd25_yloc,floorthick-adj]) cylinder(d=8,h=4);
// side nut holder support
translate([16,wallthick-adj,7]) rotate([-90,0,0]) cylinder(d=10,h=3);
translate([76,wallthick-adj,7]) rotate([-90,0,0]) cylinder(d=10,h=3);
if(length >= 120) {
translate([117.5,wallthick-adj,7]) rotate([-90,0,0]) cylinder(d=10,h=3);
translate([117.5,hd35_y-wallthick+adj,7]) rotate([90,0,0]) cylinder(d=10,h=3);
}
translate([76,hd35_y-wallthick+adj,7]) rotate([90,0,0]) cylinder(d=10,h=3);
translate([16,hd35_y-wallthick+adj,7]) rotate([90,0,0]) cylinder(d=10,h=3);
// bottom-side support
translate([wallthick,wallthick,floorthick-2]) rotate([45,0,0]) cube([hd35_x-(wallthick*2),3,3]);
translate([wallthick,hd35_y-wallthick+adj,floorthick-2]) rotate([45,0,0]) cube([hd35_x-(wallthick*2),3,3]);
}
// bottom screw holes
translate([9.4+hd25_xloc,4.07+hd25_yloc,-adj]) cylinder(d=3,h=(floorthick*3)+(adj*2));
translate([86+hd25_xloc,4.07+hd25_yloc,-adj]) cylinder(d=3,h=(floorthick*3)+(adj*2));
translate([86+hd25_xloc,65.79+hd25_yloc,-adj]) cylinder(d=3,h=(floorthick*3)+(adj*2));
translate([9.4+hd25_xloc,65.79+hd25_yloc,-adj]) cylinder(d=3,h=(floorthick*3)+(adj*2));
// countersink holes
translate([9.4+hd25_xloc,4.07+hd25_yloc,-adj]) cylinder(d1=6.5, d2=3, h=3);
translate([86+hd25_xloc,4.07+hd25_yloc,-adj]) cylinder(d1=6.5, d2=3, h=3);
translate([86+hd25_xloc,65.79+hd25_yloc,-adj]) cylinder(d1=6.5, d2=3, h=3);
translate([9.4+hd25_xloc,65.79+hd25_yloc,-adj]) cylinder(d1=6.5, d2=3, h=3);
// side screw holes
translate([16,-adj,7]) rotate([-90,0,0]) cylinder(d=3.6,h=7);
translate([76,-adj,7]) rotate([-90,0,0]) cylinder(d=3.6,h=7);
translate([117.5,-adj,7]) rotate([-90,0,0]) cylinder(d=3.6,h=7);
translate([117.5,hd35_y+adj,7]) rotate([90,0,0]) cylinder(d=3.6,h=7);
translate([76,hd35_y+adj,7]) rotate([90,0,0]) cylinder(d=3.6,h=7);
translate([16,hd35_y+adj,7]) rotate([90,0,0]) cylinder(d=3.6,h=7);
// side nut trap
translate([16,wallthick-adj,7]) rotate([-90,0,0]) cylinder(r=3.30,h=5,$fn=6);
translate([76,wallthick-adj,7]) rotate([-90,0,0]) cylinder(r=3.30,h=5,$fn=6);
translate([117.5,wallthick-adj,7]) rotate([-90,0,0]) cylinder(r=3.30,h=5,$fn=6);
translate([117.5,hd35_y-wallthick-adj,7]) rotate([90,0,0]) cylinder(r=3.30,h=5,$fn=6);
translate([76,hd35_y-wallthick-adj,7]) rotate([90,0,0]) cylinder(r=3.30,h=5,$fn=6);
translate([16,hd35_y-wallthick-adj,7]) rotate([90,0,0]) cylinder(r=3.30,h=5,$fn=6);
}
}
/*
NAME: hd35_tab
DESCRIPTION: creates 3.5" hard drive tabs for horizontal mounting
TODO: none
USAGE: hd35_tab(side)
side = "left", "right"
*/
module hd35_tab(side) {
width = 15;
l_width = 46;
depth = 15;
height = 4;
fillet = 2;
hole = 3.6;
length = 3;
adj = .01;
$fn = 90;
if(side == "left") {
difference() {
union() {
translate([0,-depth/2,0]) rotate([0,-90,0])
slab_r([l_width,depth,height], [fillet,fillet,fillet,fillet]);
translate([-height,-depth/2,0]) cube([height,depth,height]);
translate([adj,-5.5,depth])
rotate([90,0,0])
linear_extrude(height = 2)
polygon(points = [ [-height,height+20],
[-depth+4,-depth],
[-height,-depth]]);
translate([adj,7.5,depth])
rotate([90,0,0])
linear_extrude(height = 2)
polygon(points = [ [-height,height+20],
[-depth+4,-depth],
[-height,-depth]]);
}
translate([3.18,0,-adj]) rotate([0,0,0]) cylinder(d=hole, h=3);
translate([-height-adj,(width/2)-(length/2)-depth/2,6.35]) rotate([90,0,90]) slot(hole,length,height+(2*adj));
translate([-height-adj,(width/2)-(length/2)-depth/2,38.35]) rotate([90,0,90]) slot(hole,length,height+(2*adj));
}
}
if(side == "right") {
difference() {
union() {
translate([height,-depth/2,0]) rotate([0,-90,0])
slab_r([l_width,depth,height], [fillet,fillet,fillet,fillet]);
translate([0,-depth/2,0]) cube([height,depth,height]);
translate([adj,-7.5,depth])
rotate([90,0,180])
linear_extrude(height = 2)
polygon(points = [ [-height,height+20],
[-depth+4,-depth],
[-height,-depth]]);
translate([adj,5.5,depth])
rotate([90,0,180])
linear_extrude(height = 2)
polygon(points = [ [-height,height+20],
[-depth+4,-depth],
[-height,-depth]]);
}
translate([-3.18,0,-adj]) rotate([0,0,0]) cylinder(d=hole, h=3);
translate([-adj,(width/2)-(length/2)-depth/2,6.35]) rotate([90,0,90]) slot(hole,length,height+(2*adj));
translate([-adj,(width/2)-(length/2)-depth/2,38.35]) rotate([90,0,90]) slot(hole,length,height+(2*adj));
}
}
}
/*
NAME: hd35_vtab
DESCRIPTION: creates 3.5" hard drive tabs for vertical mounting
TODO: none
USAGE: hd35_vtab(side)
side = "left", "right"
*/
module hd35_vtab(side) {
width = 15;
l_width = 16;
depth = 15;
height = 4;
fillet = 2;
hole = 3.6;
length = 3;
adj = .01;
$fn = 90;
if(side == "left") {
difference() {
union() {
translate([0,-depth/2,0]) rotate([0,-90,0])
slab_r([l_width,depth,height], [fillet,fillet,fillet,fillet]);
translate([-height,-depth/2,0]) cube([height,depth,height]);
translate([adj,-5.5,depth])
rotate([90,0,0])
linear_extrude(height = 2)
polygon(points = [ [-height,height-5],
[-depth+4,-depth],
[-height,-depth]]);
translate([adj,7.5,depth])
rotate([90,0,0])
linear_extrude(height = 2)
polygon(points = [ [-height,height-5],
[-depth+4,-depth],
[-height,-depth]]);
}
translate([3,0,-adj]) rotate([0,0,0]) cylinder(d=hole, h=3);
translate([-height-adj,1.5+(width/2)-(length/2)-depth/2,5.57]) rotate([90,90,90]) slot(hole,length,height+(2*adj));
}
}
if(side == "right") {
difference() {
union() {
translate([height,-depth/2,0]) rotate([0,-90,0])
slab_r([l_width,depth,height], [fillet,fillet,fillet,fillet]);
translate([0,-depth/2,0]) cube([height,depth,height]);
translate([adj,-7.5,depth])
rotate([90,0,180])
linear_extrude(height = 2)
polygon(points = [ [-height,height-5],
[-depth+4,-depth],
[-height,-depth]]);
translate([adj,5.5,depth])
rotate([90,0,180])
linear_extrude(height = 2)
polygon(points = [ [-height,height-5],
[-depth+4,-depth],
[-height,-depth]]);
}
translate([-3,0,-adj]) rotate([0,0,0]) cylinder(d=hole, h=3);
translate([-adj,1.5+(width/2)-(length/2)-depth/2,5.57]) rotate([90,90,90]) slot(hole,length,height+(2*adj));
}
}
}
/*
NAME: hd_holes
DESCRIPTION: creates 2.5" and 3.5" hard drive hole mask for mounting
TODO: none
USAGE: hd_holes(hd, orientation, side, thick, holetype)
hd = 2.5, 3.5
orientation = "portrait", "landscape"
side = "left", "right", "both", "bottom", "all"
thick = floor thickness
holetype = "hole", "slot"
*/
module hd_holes(hd=3.5, orientation="portrait", side="all", thick=2, holetype="slot") {
hd25_x = 100;
hd25_y = 69.85;
hd35_x = 147;
hd35_y = 101.6;
hd35_z = 26.1;
hole_size = 3.2;
hole_len = 3 * hole_size;
slot_size = [hole_size, hole_len, thick];
adj = .01;
$fn = 90;
if(hd == 2.5) {
if(orientation == "portrait") {
translate([0,hd25_x,0]) rotate([0,0,270]) union() {
if(side == "left" || side == "both" || side == "all") {
if(holetype == "hole") {
translate([9.4,-thick,3]) rotate([270,0,0]) cylinder(d=hole_size,h=thick);
translate([86,-thick,3]) rotate([270,0,0]) cylinder(d=hole_size,h=thick);
}
if(holetype == "slot") {
translate([9.4-(1.5*hole_size),-thick,3]) rotate([270,0,0])
slot(hole_size, hole_len, thick);
translate([86-(1.5*hole_size),-thick,3]) rotate([270,0,0])
slot(hole_size, hole_len, thick);
}
}
if(side == "right" || side == "both" || side == "all") {
if(holetype == "hole") {
translate([9.4,hd25_y+thick,3]) rotate([90,0,0]) cylinder(d=hole_size,h=thick);
translate([86,hd25_y+thick,3]) rotate([90,0,0]) cylinder(d=hole_size,h=thick);
}
if(holetype == "slot") {
translate([9.4-(1.5*hole_size),hd25_y+thick,3]) rotate([90,0,0])
slot(hole_size, hole_len, thick);
translate([86-(1.5*hole_size),hd25_y+thick,3]) rotate([90,0,0])
slot(hole_size, hole_len, thick);
}
}
if(side == "bottom" || side == "all") {
if(holetype == "hole") {
translate([9.4,4.07,0]) cylinder(d=hole_size,h=thick);
translate([86,4.07,0]) cylinder(d=hole_size,h=thick);
translate([86,65.79,0]) cylinder(d=hole_size,h=thick);
translate([9.4,65.79,0]) cylinder(d=hole_size,h=thick);
}
if(holetype == "slot") {
translate([9.4-(1.5*hole_size),4.07,0]) slot(hole_size, hole_len, thick);
translate([86-(1.5*hole_size),4.07,0]) slot(hole_size, hole_len, thick);
translate([86-(1.5*hole_size),65.79,0]) slot(hole_size, hole_len, thick);
translate([9.4-(1.5*hole_size),65.79,0]) slot(hole_size, hole_len, thick);
}
}
}
}
if(orientation == "landscape") {
if(side == "left" || side == "both" || side == "all") {
if(holetype == "hole") {
translate([9.4,-thick,3]) rotate([270,0,0]) cylinder(d=hole_size,h=thick);
translate([86,-thick,3]) rotate([270,0,0]) cylinder(d=hole_size,h=thick);
}
if(holetype == "slot") {
translate([9.4-(1.5*hole_size),-thick,3]) rotate([270,0,0])
slot(hole_size, hole_len, thick);
translate([86-(1.5*hole_size),-thick,3]) rotate([270,0,0])
slot(hole_size, hole_len, thick);
}
}
if(side == "right" || side == "both" || side == "all") {
if(holetype == "hole") {
translate([9.4,hd25_y+thick,3]) rotate([90,0,0]) cylinder(d=hole_size,h=thick);
translate([86,hd25_y+thick,3]) rotate([90,0,0]) cylinder(d=hole_size,h=thick);
}
if(holetype == "slot") {
translate([9.4-(1.5*hole_size),hd25_y+thick,3]) rotate([90,0,0])
slot(hole_size, hole_len, thick);
translate([86-(1.5*hole_size),hd25_y+thick,3]) rotate([90,0,0])
slot(hole_size, hole_len, thick);
}
}
if(side == "bottom" || side == "all") {
if(holetype == "hole") {
translate([9.4,4.07,-thick]) cylinder(d=hole_size,h=thick);
translate([86,4.07,-thick]) cylinder(d=hole_size,h=thick);
translate([86,65.79,-thick]) cylinder(d=hole_size,h=thick);
translate([9.4,65.79,-thick]) cylinder(d=hole_size,h=thick);
}
if(holetype == "slot") {
translate([9.4-(1.5*hole_size),4.07,-thick]) slot(hole_size, hole_len, thick);
translate([86-(1.5*hole_size),4.07,-thick]) slot(hole_size, hole_len, thick);
translate([86-(1.5*hole_size),65.79,-thick]) slot(hole_size, hole_len, thick);
translate([9.4-(1.5*hole_size),65.79,-thick]) slot(hole_size, hole_len, thick);
}
}
}
}
if(hd == 3.5) {
if(orientation == "portrait") {
translate([0,hd35_x,0]) rotate([0,0,270]) union() {
if(side == "left" || side == "both" || side == "all") {
if(holetype == "hole") {
translate([16.9,-thick,6.35]) rotate([270,0,0]) cylinder(d=hole_size,h=thick);
translate([76.6,-thick,6.35]) rotate([270,0,0]) cylinder(d=hole_size,h=thick);
translate([118.5,-thick,6.35]) rotate([270,0,0]) cylinder(d=hole_size,h=thick);
}
if(holetype == "slot") {
translate([16.9-(1.5*hole_size),-thick,6.35]) rotate([270,0,0])
slot(hole_size, hole_len, thick);
translate([76.6-(1.5*hole_size),-thick,6.35]) rotate([270,0,0])
slot(hole_size, hole_len, thick);
translate([118.5-(1.5*hole_size),-thick,6.35]) rotate([270,0,0])
slot(hole_size, hole_len, thick);
}
}
if(side == "right" || side == "both" || side == "all") {
if(holetype == "hole") {
translate([118.5,hd35_y+thick,6.35]) rotate([90,0,0]) cylinder(d=hole_size,h=thick);
translate([76.6,hd35_y+thick,6.35]) rotate([90,0,0]) cylinder(d=hole_size,h=thick);
translate([16.9,hd35_y+thick,6.35]) rotate([90,0,0]) cylinder(d=hole_size,h=thick);
}
if(holetype == "slot") {
translate([118.5-(1.5*hole_size),hd35_y+thick,6.35]) rotate([90,0,0])
slot(hole_size, hole_len, thick);
translate([76.6-(1.5*hole_size),hd35_y+thick,6.35]) rotate([90,0,0])
slot(hole_size, hole_len, thick);
translate([16.9-(1.5*hole_size),hd35_y+thick,6.35]) rotate([90,0,0])
slot(hole_size, hole_len, thick);
}
}
if(side == "bottom" || side == "all") {
if(holetype == "hole") {
translate([29.52,3.18,0]) cylinder(d=hole_size,h=thick);
translate([61.27,3.18,0]) cylinder(d=hole_size,h=thick);
translate([105.72,3.18,0]) cylinder(d=hole_size,h=thick);
translate([29.52,98.43,0]) cylinder(d=hole_size,h=thick);
translate([61.27,98.43,0]) cylinder(d=hole_size,h=thick);
translate([105.72,98.43,0]) cylinder(d=hole_size,h=thick);
}
if(holetype == "slot") {
translate([29.52-(1.5*hole_size),3.18,0]) slot(hole_size, hole_len, thick);
translate([61.27-(1.5*hole_size),3.18,0]) slot(hole_size, hole_len, thick);
translate([105.72-(1.5*hole_size),3.18,0]) slot(hole_size, hole_len, thick);
translate([29.52-(1.5*hole_size),98.43,0]) slot(hole_size, hole_len, thick);
translate([61.27-(1.5*hole_size),98.43,0]) slot(hole_size, hole_len, thick);
translate([105.72-(1.5*hole_size),98.43,0]) slot(hole_size, hole_len, thick);
}
}
}
}
if(orientation == "landscape") {
if(side == "left" || side == "both" || side == "all") {
if(holetype == "hole") {
translate([16.9,-thick,6.35]) rotate([270,0,0]) cylinder(d=3,h=thick);
translate([76.6,-thick,6.35]) rotate([270,0,0]) cylinder(d=3,h=thick);
translate([118.5,-thick,6.35]) rotate([270,0,0]) cylinder(d=3,h=thick);
}
if(holetype == "slot") {
translate([16.9-(1.5*hole_size),-thick,6.35]) rotate([270,0,0])
slot(hole_size, hole_len, thick);
translate([76.6-(1.5*hole_size),-thick,6.35]) rotate([270,0,0])
slot(hole_size, hole_len, thick);
translate([118.5-(1.5*hole_size),-thick,6.35]) rotate([270,0,0])
slot(hole_size, hole_len, thick);
}
}
if(side == "right" || side == "both" || side == "all") {
if(holetype == "hole") {
translate([118.5,hd35_y+thick,6.35]) rotate([90,0,0]) cylinder(d=3,h=thick);
translate([76.6,hd35_y+thick,6.35]) rotate([90,0,0]) cylinder(d=3,h=thick);
translate([16.9,hd35_y+thick,6.35]) rotate([90,0,0]) cylinder(d=3,h=thick);
}
if(holetype == "slot") {
translate([118.5-(1.5*hole_size),hd35_y+thick,6.35]) rotate([90,0,0])
slot(hole_size, hole_len, thick);
translate([76.6-(1.5*hole_size),hd35_y+thick,6.35]) rotate([90,0,0])
slot(hole_size, hole_len, thick);
translate([16.9-(1.5*hole_size),hd35_y+thick,6.35]) rotate([90,0,0])
slot(hole_size, hole_len, thick);
}
}
if(side == "bottom" || side == "all") {
if(holetype == "hole") {
translate([29.52,3.18,-thick]) cylinder(d=3.6,h=thick);
translate([61.27,3.18,-thick]) cylinder(d=3.6,h=thick);
translate([105.72,3.18,-thick]) cylinder(d=3.6,h=thick);
translate([29.52,98.43,-thick]) cylinder(d=3.6,h=thick);
translate([61.27,98.43,-thick]) cylinder(d=3.6,h=thick);
translate([105.72,98.43,-thick]) cylinder(d=3.6,h=thick);
}
if(holetype == "slot") {
translate([29.52-(1.5*hole_size),3.18,-thick]) slot(hole_size, hole_len, thick);
translate([61.27-(1.5*hole_size),3.18,-thick]) slot(hole_size, hole_len, thick);
translate([105.72-(1.5*hole_size),3.18,-thick]) slot(hole_size, hole_len, thick);
translate([29.52-(1.5*hole_size),98.43,-thick]) slot(hole_size, hole_len, thick);
translate([61.27-(1.5*hole_size),98.43,-thick]) slot(hole_size, hole_len, thick);
translate([105.72-(1.5*hole_size),98.43,-thick]) slot(hole_size, hole_len, thick);
}
}
}
}
}
/*
NAME: hd_mount
DESCRIPTION: creates 2.5" and 3.5" hard drive mounts
TODO: none
USAGE: hd_mount(hd, orientation, position, side)
hd = 2.5, 3.5
orientation = "portrait", "landscape"
position = "vertical", "horizontal"
side = "left", "right"
*/
module hd_mount(hd, orientation, position, side) {
adj = .01;
$fn = 90;
if(hd == 2.5) {
if(orientation == "portrait") {
if(position == "vertical") {
if(side == "left") {
translate([0,14,0]) rotate([0,0,0]) hd25_vtab("right");
translate([0,90.6,0]) rotate([0,0,0]) hd25_vtab("right");
}
else { // right
translate([0,14,0]) rotate([0,0,0]) hd25_vtab("left");
translate([0,90.6,0]) rotate([0,0,0]) hd25_vtab("left");
}
}
else {
translate([-.5,14,0]) hd25_tab("left");
translate([-.5,90.6,0]) hd25_tab("left");
translate([70.35,14,0]) hd25_tab("right");
translate([70.35,90.6,0]) hd25_tab("right");
}
}
if(orientation == "landscape") {
if(position == "vertical") {
if(side == "left") {
translate([9.4,0,0]) rotate([0,0,90]) hd25_vtab("right");
translate([86,0,0]) rotate([0,0,90]) hd25_vtab("right");
}
else { // right
translate([9.4,0,0]) rotate([0,0,90]) hd25_vtab("left");
translate([86,0,0]) rotate([0,0,90]) hd25_vtab("left");
}
}
else {
translate([9.4,4.07-4.5,0]) rotate([0,0,90]) hd25_tab("left");
translate([86,4.07-4.5,0]) rotate([0,0,90]) hd25_tab("left");
translate([86,65.79+4.5,0]) rotate([0,0,90]) hd25_tab("right");
translate([9.4,65.79+4.5,0]) rotate([0,0,90]) hd25_tab("right");
}
}
}
if(hd == 3.5) {
if(orientation == "portrait") {
if(position == "vertical") {
if(side == "left") {
translate([0,41.28,0]) rotate([0,0,0]) hd35_vtab("right");
translate([0,41.28+44.45,0]) rotate([0,0,0]) hd35_vtab("right");
translate([0,41.28+76.20,0]) rotate([0,0,0]) hd35_vtab("right");
}
else { // right
translate([0,41.28,0]) rotate([0,0,0]) hd35_vtab("left");
translate([0,41.28+44.45,0]) rotate([0,0,0]) hd35_vtab("left");
translate([0,41.28+76.20,0]) rotate([0,0,0]) hd35_vtab("left");
}
}
else {
translate([-.5,28.5,0]) hd35_tab("left");
translate([-.5,69.75,0]) hd35_tab("left");
translate([-.5,130.1,0]) hd35_tab("left");
translate([101.6+.5,28.5,0]) hd35_tab("right");
translate([101.6+.5,69.75,0]) hd35_tab("right");
translate([101.6+.5,130.1,0]) hd35_tab("right");
}
}
if(orientation == "landscape") {
if(position == "vertical") {
if(side == "left") {
translate([9.4,0,0]) rotate([0,0,90]) hd35_vtab("right");
translate([86,0,0]) rotate([0,0,90]) hd35_vtab("right");
}
else { // right
translate([9.4,0,0]) rotate([0,0,90]) hd35_vtab("left");
translate([86,0,0]) rotate([0,0,90]) hd35_vtab("left");
}
}
else {
translate([16.9,-.5,0]) rotate([0,0,90]) hd35_tab("left");
translate([76.6,-.5,0]) rotate([0,0,90]) hd35_tab("left");
translate([118.5,-.5,0]) rotate([0,0,90]) hd35_tab("left");
translate([16.9,101.6-.5,0]) rotate([0,0,90]) hd35_tab("right");
translate([76.6,101.6-.5,0]) rotate([0,0,90]) hd35_tab("right");
translate([118.5,101.6-.5,0]) rotate([0,0,90]) hd35_tab("right");
}
}
}
}

447
lib/holder.scad Normal file
View File

@@ -0,0 +1,447 @@
/*
This file is part of SBC Case Builder https://github.com/hominoids/SBC_Case_Builder
Copyright 2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
This program 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.
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 this program. If not, see <http://www.gnu.org/licenses/>
Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
nut_holder(nut, style, dia_x, dia_y, height)
pcb_holder(size, wallthick)
vu_holder(vu_model, side, vesa, cheight)
*/
/*
NAME: nut_holder
DESCRIPTION: creates various nut holders
TODO: none
USAGE: nut_holder(nut, style, dia_x, dia_y, height, mask)
nut = "m2", "m2.5", "m3", "m4", "m3-insert"
style = "default", "sloped", "trap"
dia_x = top diameter or x size in mm
dia_y = bottom diameter or y size in mm
height = holder height in mm
mask[0] = true enables component mask
mask[1] = mask length
mask[2] = mask setback
mask[3] = mstyle "default"
*/
module nut_holder(nut, style, dia_x, dia_y, height, mask) {
nuts = [[2,4,1.6], // m2 size, diameter, height
[2.5,5,2], // m2.5 size, diameter, height
[3,5.5,2.4], // m3 size, diameter, height
[4,7,3.2]]; // m4 size, diameter, height
enablemask = mask[0];
mlength = mask[1];
msetback = mask[2];
mstyle = mask[3];
adj = .01;
$fn = 90;
if(enablemask == true && mstyle == "default") {
if(nut == "m2") {
translate([0, 0, -mlength+msetback]) cylinder(d = nuts[0][0], h = mlength);
}
if(nut == "m2.5") {
translate([0, 0, -mlength+msetback]) cylinder(d = nuts[1][0], h = mlength);
}
if(nut == "m3") {
translate([0, 0, -mlength+msetback]) cylinder(d = nuts[2][0], h = mlength);
}
if(nut == "m4") {
translate([0, 0, -mlength+msetback]) cylinder(d = nuts[3][0], h = mlength);
}
}
if(enablemask == false) {
if( style == "default") {
difference() {
cylinder(d=dia_x, h=height);
if(nut == "m2") {
translate([0, 0, -1]) cylinder(d=nuts[0][0]+.25, h=height+2);
translate([0, 0, 2]) cylinder(d=nuts[0][1]*2/sqrt(3), h=height, $fn=6);
}
if(nut == "m2.5") {
translate([0, 0, -1]) cylinder(d=nuts[1][0]+.25, h=height+2);
translate([0, 0, 2]) cylinder(d=nuts[1][1]*2/sqrt(3), h=height, $fn=6);
}
if(nut == "m3") {
translate([0, 0, -1]) cylinder(d=nuts[2][0]+.5, h=height+2);
translate([0, 0, 2]) cylinder(d=nuts[2][1]*2/sqrt(3), h=height, $fn=6);
}
if(nut == "m3-insert") {
translate([0, 0, -1]) cylinder(d=nuts[2][0]+.5, h=height+2);
translate([0, 0, 0]) cylinder(d=4.2, h=5.1);
}
if(nut == "m4") {
translate([0, 0, -1]) cylinder(d=nuts[3][0]+.5, h=height+2);
translate([0, 0, 2]) cylinder(d=nuts[3][1]*2/sqrt(3), h=height, $fn=6);
}
}
}
if( style == "sloped") {
difference() {
cylinder(d2=dia_x, d1=dia_y, h=height);
if(nut == "m2") {
translate([0, 0, -1]) cylinder(d=nuts[0][0]+.25, h=height+2);
translate([0, 0, 2]) cylinder(d=nuts[0][1]*2/sqrt(3), h=height, $fn=6);
}
if(nut == "m2.5") {
translate([0, 0, -1]) cylinder(d=nuts[1][0]+.25, h=height+2);
translate([0, 0, 2]) cylinder(d=nuts[1][1]*2/sqrt(3), h=height, $fn=6);
}
if(nut == "m3") {
translate([0, 0, -1]) cylinder(d=nuts[2][0]+.5, h=height+2);
translate([0, 0, 0]) cylinder(d=nuts[2][1]*2/sqrt(3), h=height+5, $fn=6);
}
if(nut == "m3-insert") {
translate([0, 0, -1]) cylinder(d=nuts[2][0]+.5, h=height+2);
translate([0, 0, 0]) cylinder(d=4.2, h=5.1);
}
if(nut == "m4") {
translate([0, 0, -1]) cylinder(d=nuts[3][0]+.5, h=height+2);
translate([0, 0, 2]) cylinder(d=nuts[3][1]*2/sqrt(3), h=height, $fn=6);
}
}
}
if( style == "trap") {
if(nut == "m2") {
difference() {
translate([-dia_x/2, -dia_y/2, 0]) cube([dia_x, dia_y, height]);
translate([0, 0, -1]) cylinder(d=nuts[0][0]+.25, h=height+2);
translate([0, 0, 2]) rotate([0,0,30]) cylinder(d=nuts[0][1]*2/sqrt(3), h=nuts[0][2], $fn=6);
translate([-nuts[0][1]/2, 0, 2]) cube([nuts[0][1], dia_x, nuts[0][2]]);
}
}
if(nut == "m2.5") {
difference() {
translate([-dia_x/2, -dia_y/2, 0]) cube([dia_x, dia_y, height]);
translate([0, 0, -1]) cylinder(d=nuts[1][0]+.325, h=height+2);
translate([0, 0, 2]) rotate([0,0,30]) cylinder(d=nuts[1][1]*2/sqrt(3), h=nuts[1][2], $fn=6);
translate([-nuts[1][1]/2, 0, 2]) cube([nuts[1][1], dia_x, nuts[1][2]]);
}
}
if(nut == "m3") {
difference() {
translate([-dia_x/2, -dia_y/2, 0]) cube([dia_x, dia_y, height]);
translate([0, 0, -1]) cylinder(d=nuts[2][0]+.5, h=height+2);
translate([0, 0, 2]) rotate([0,0,30]) cylinder(d=nuts[2][1]*2/sqrt(3), h=nuts[2][2], $fn=6);
translate([-nuts[2][1]/2, 0, 2]) cube([nuts[2][1], dia_x, nuts[2][2]]);
}
}
if(nut == "m4") {
difference() {
translate([-dia_x/2, -dia_y/2, 0]) cube([dia_x, dia_y, height]);
translate([0, 0, -1]) cylinder(d=nuts[3][0]+.5, h=height+2);
translate([0, 0, 2]) rotate([0,0,30]) cylinder(d=nuts[3][1]*2/sqrt(3), h=nuts[3][2], $fn=6);
translate([-nuts[3][1]/2, 0, 2]) cube([nuts[3][1], dia_x, nuts[3][2]]);
}
}
}
}
}
/*
NAME: pcb_holder
DESCRIPTION: pcb bottom edge holder
TODO: none
USAGE: pcb_holder(size, wallthick)
size = width of holder
wallthick = holder wall thickness
*/
module pcb_holder(size, wallthick) {
adj=.01;
$fn = 90;
difference() {
union() {
translate([-1.85,-1.75,0]) cube([size[0]+3.5,5,6]);
translate([size[0]+1.65,-5.75,1])
rotate([0,-90,0])
linear_extrude(height = size[0]+3.5)
polygon(points = [ [-wallthick/2,-wallthick/2],
[2,wallthick],
[4,4],
[-wallthick/2,4]]);
translate([-1.85,4,1])
rotate([0,-90,180])
linear_extrude(height = size[0]+3.5)
polygon(points = [ [-wallthick/2,-wallthick/2],
[2,wallthick],
[2,2],
[-wallthick/2,2]]);
}
translate([-.5,0,2]) cube([size[0]+1,size[2],5]);
translate([6,-adj-5-1.75,-adj]) cube([size[0]-12,14,8]);
}
}
/*
NAME: vu_holder
DESCRIPTION: hk vu5,vu5a,vu7,vu7a display holder
TODO: none
USAGE: vu_holder(vu_model, side, vesa, cheight)
vu_model = "vu5", "vu7"
side = "left", "right"
vesa = 75 for vu5, 100 for vu7
cheight = case_z+90 for vu5, case_z+122 for vu7
*/
module vu_holder(vu_model, side, vesa, cheight) {
//cheight = case_z+90;
v_fillet = 3;
vu5_case_x_offset = 6.5; // for uniform front vu5=6.5, vu7=20
vu5_pcb_width = 121;
vu5_pcb_height = 93.31;
vu5_width = vu5_pcb_width + vu5_case_x_offset;
vu5_height = vu5_pcb_height + 9.75;
vu7_case_x_offset = 20; // for uniform front vu5=6.5, vu7=20
vu7_pcb_width = 172.90;
vu7_pcb_height = 124.27;
vu7_width = vu7_pcb_width + vu7_case_x_offset;
vu7_height = vu7_pcb_height + 9.75;
vu_rotation = [15,0,0];
difference() {
union() {
if(side == "right") {
translate([width-wallthick-gap,-(2*wallthick)-gap,0])
cube([sidethick,depth+2*wallthick,cheight]);
// right tabs for vu5 attachment
if(vu_model == "vu5") {
translate([(width/2)+((width-vesa)/2)+(vesa/2)-sidethick,depth-39,
case_z+80]) rotate([75,180,0])
slab_r([((width-vesa)/2)+4.5,10,sidethick], [.01,.01,3,3]);
translate([(width/2)+((width-vesa)/2)+(vesa/2)-sidethick,depth-26,
case_z+31.5]) rotate([75,180,0])
slab_r([((width-vesa)/2)+4.5,10,sidethick], [.01,.01,3,3]);
translate([(width/2)+((width-vesa)/2)+(vesa/2)-sidethick-1.5,depth-40.85-adj,
case_z+79.5]) rotate([75,180,0])
difference() {
cube([sidethick,10,sidethick]);
translate([0,-adj,sidethick]) rotate([0,45,0])
cube([2*sidethick,10+(2*adj),sidethick]);
}
translate([(width/2)+((width-vesa)/2)+(vesa/2)-sidethick-1.5,depth-27.85-adj,
case_z+31]) rotate([75,180,0])
difference() {
cube([sidethick,10,sidethick]);
translate([0,-adj,sidethick]) rotate([0,45,0])
cube([2*sidethick,10+(2*adj),sidethick]);
}
}
// right tabs for vu7 attachment
if(vu_model == "vu7") {
translate([(width/2)+((width-vesa)/2)+(vesa/2)-sidethick-1,depth-49.40,
case_z+vu7_height-15]) rotate([75,180,0])
slab_r([((width-vesa)/2)+12,10,sidethick], [.01,.01,3,3]);
translate([(width/2)+((width-vesa)/2)+(vesa/2)-sidethick-1,depth-23.60,
case_z+22.5]) rotate([75,180,0])
slab_r([((width-vesa)/2)+12,10,sidethick], [.01,.01,3,3]);
translate([(width/2)+((width-vesa)/2)+(vesa/2)-sidethick-1.5,depth-51.25,
case_z+vu7_height-15.5]) rotate([75,180,0])
difference() {
cube([sidethick,10,sidethick]);
translate([0,-adj,sidethick]) rotate([0,45,0])
cube([2*sidethick,10+(2*adj),sidethick]);
}
translate([(width/2)+((width-vesa)/2)+(vesa/2)-sidethick-1.5,depth-25.5,
case_z+21.8]) rotate([75,180,0])
difference() {
cube([sidethick,10,sidethick]);
translate([0,-adj,sidethick]) rotate([0,45,0])
cube([2*sidethick,10+(2*adj),sidethick]);
}
}
// top rail
translate([width-6.9-adj,-gap,case_z-floorthick-.5])
cube([4,depth-2*(wallthick+gap),2]);
}
if(side == "left") {
translate([-wallthick-gap-sidethick,-(2*wallthick)-gap,0])
cube([sidethick,depth+2*wallthick,cheight]);
// left tabs for vu5 attachment
if(vu_model == "vu5") {
translate([-((width-vesa)/2)+(width/2)-(vesa/2)-3.5-adj,depth-36.4,
case_z+70]) rotate([105,0,0])
slab_r([((width-vesa)/2)+4,10, sidethick], [.01,.01,3,3]);
translate([-((width-vesa)/2)+(width/2)-(vesa/2)-3.5-adj,depth-23.5,
case_z+22]) rotate([105,0,0])
slab_r([((width-vesa)/2)+4,10,sidethick], [.01,.01,3,3]);
translate([-((width-vesa)/2)+(width/2)-(vesa/2)-3.5-adj,depth-38.35+adj,
case_z+69.5]) rotate([105,0,0])
difference() {
cube([sidethick,10,sidethick]);
translate([0,-adj,sidethick]) rotate([0,45,0])
cube([2*sidethick,10+(2*adj),2*sidethick]);
}
translate([-((width-vesa)/2)+(width/2)-(vesa/2)-3.5-adj,depth-25.4+adj,
case_z+21.5]) rotate([105,0,0])
difference() {
cube([sidethick,10,sidethick]);
translate([0,-adj,sidethick]) rotate([0,45,0])
cube([2*sidethick,10+(2*adj),2*sidethick]);
}
}
// left tabs for vu7 attachment
if(vu_model == "vu7") {
translate([-((width-vesa)/2)+(width/2)-(vesa/2)-4.25-adj,depth-46.85,
case_z+vu7_height-24.5]) rotate([105,0,0])
slab_r([((width-vesa)/2),10, sidethick], [.01,.01,3,3]);
translate([-((width-vesa)/2)+(width/2)-(vesa/2)-4.25-adj,depth-21,
case_z+13]) rotate([105,0,0])
slab_r([((width-vesa)/2),10,sidethick], [.01,.01,3,3]);
translate([-((width-vesa)/2)+(width/2)-(vesa/2)-3.5-adj,depth-48.75+adj,
case_z+vu7_height-25]) rotate([105,0,0])
difference() {
cube([sidethick,10,sidethick]);
translate([0,-adj,sidethick]) rotate([0,45,0])
cube([2*sidethick,10+(2*adj),2*sidethick]);
}
translate([-((width-vesa)/2)+(width/2)-(vesa/2)-3.5-adj,depth-22.65+adj,
case_z+12.5]) rotate([105,0,0])
difference() {
cube([sidethick,10,sidethick]);
translate([0,-adj,sidethick]) rotate([0,45,0])
cube([2*sidethick,10+(2*adj),2*sidethick]);
}
}
// top rail
translate([-wallthick-gap-adj,-gap,case_z-floorthick-.5])
cube([4,depth-2*(wallthick+gap),2]);
}
}
if(side == "right") {
// vu5 shape and back cut
if(vu_model == "vu5") {
translate([width+adj,-.6,case_z+sidethick+2.5])
rotate([0,-90,0])
linear_extrude(height = 3*sidethick)
polygon(points = [ [-sidethick,-sidethick-wallthick-5],
[cheight-bottom_height-top_height-3,-sidethick-wallthick-5],
[cheight-bottom_height-top_height-3,depth-53],
[-sidethick,depth-33]]);
translate([width-(sidethick/2),depth-8,case_z+(121/2)])
rotate([vu_rotation[0],0,0])
cube_fillet_inside([10,50,110],vertical=[v_fillet,v_fillet,v_fillet,v_fillet],
top=[0,0,0,0],bottom=[3,3,3,3], $fn=90);
// tab holes
translate([width/2+(vesa/2)-3,depth-37,
case_z+75]) rotate([75,180,0]) cylinder(d=3, h=sidethick+1);
translate([width/2+(vesa/2)-3,depth-24,
case_z+26.75]) rotate([75,180,0]) cylinder(d=3, h=sidethick+1);
}
// vu7 shape and back cut
if(vu_model == "vu7") {
translate([width+adj,-.6,case_z+sidethick+2.5])
rotate([0,-90,0])
linear_extrude(height = 2*sidethick)
polygon(points = [ [-sidethick,-sidethick-wallthick-5],
[cheight-bottom_height-top_height-3,-sidethick-wallthick-5],
[cheight-bottom_height-top_height-3,depth-63],
[-sidethick,depth-33]]);
translate([width-(sidethick/2),depth-10.5,case_z+70.5])
rotate([vu_rotation[0],0,0])
cube_fillet_inside([10,50,130],vertical=[v_fillet,v_fillet,v_fillet,v_fillet],
top=[0,0,0,0],bottom=[3,3,3,3], $fn=90);
// tab holes
translate([width/2+(vesa/2)-10,depth-47,case_z+vu7_height-19.75])
rotate([75,180,0]) cylinder(d=3, h=sidethick+4);
translate([width/2+(vesa/2)-10,depth-21.25,case_z+18])
rotate([75,180,0]) cylinder(d=3, h=sidethick+4);
}
// bottom attachment holes
translate([width-wallthick-gap-adj-5,wallthick+gap+10,
((bottom_height+floorthick)/2)-1]) rotate([0,90,0]) cylinder(d=3, h=sidethick+(2*adj)+10);
translate([width-wallthick-gap-adj-5,depth-wallthick-gap-10,
((bottom_height+floorthick)/2)-1]) rotate([0,90,0]) cylinder(d=3, h=sidethick+(2*adj)+10);
}
if(side == "left") {
// vu5 shape and back cut
if(vu_model == "vu5") {
translate([-sidethick+adj,-.6,case_z+sidethick+2.5])
rotate([0,-90,0])
linear_extrude(height = 3*sidethick)
polygon(points = [ [-sidethick,-sidethick-wallthick-5],
[cheight-bottom_height-top_height-3,-sidethick-wallthick-5],
[cheight-bottom_height-top_height-3,depth-53],
[-sidethick,depth-33]]);
translate([-wallthick-gap-(sidethick/2),depth-8,case_z+(121/2)])
rotate([vu_rotation[0],0,0])
cube_fillet_inside([10,50,110],vertical=[v_fillet,v_fillet,v_fillet,v_fillet],
top=[0,0,0,0],bottom=[3,3,3,3], $fn=90);
// tab holes
translate([width/2-(vesa/2)-3,depth-36.75,case_z+75])
rotate([105,0,0]) cylinder(d=3, h=sidethick+1);
translate([width/2-(vesa/2)-3,depth-24.25,case_z+26.75])
rotate([75,0,0]) cylinder(d=3, h=sidethick+1);
}
// vu7 shape and back cut
if(vu_model == "vu7") {
translate([-sidethick+adj,-.6,case_z+sidethick+2.5])
rotate([0,-90,0])
linear_extrude(height = 2*sidethick)
polygon(points = [ [-sidethick,-sidethick-wallthick-5],
[cheight-bottom_height-top_height-3,-sidethick-wallthick-5],
[cheight-bottom_height-top_height-3,depth-63],
[-sidethick,depth-33]]);
translate([-wallthick-gap-(sidethick/2),depth-10.5,case_z+70.5])
rotate([vu_rotation[0],0,0])
cube_fillet_inside([10,50,130],vertical=[v_fillet,v_fillet,v_fillet,v_fillet],
top=[0,0,0,0],bottom=[3,3,3,3], $fn=90);
// tab holes
translate([width/2-(vesa/2)-10,depth-48,case_z+vu7_height-19.75])
rotate([105,0,0]) cylinder(d=3, h=sidethick+4);
translate([width/2-(vesa/2)-10,depth-22.25,case_z+18])
rotate([105,0,0]) cylinder(d=3, h=sidethick+4);
}
// bottom attachment holes
translate([-sidethick-adj-6,wallthick+gap+10,((bottom_height+floorthick)/2)-1])
rotate([0,90,0]) cylinder(d=3, h=sidethick+(2*adj)+10);
if(depth >= 75) {
translate([-sidethick-adj-6,depth-wallthick-gap-10,
((bottom_height+floorthick)/2)-1]) rotate([0,90,0]) cylinder(d=3, h=sidethick+(2*adj)+10);
}
else {
translate([-sidethick-adj-6,wallthick+gap+40.5,((bottom_height+floorthick)/2)-1])
rotate([0,90,0]) cylinder(d=3, h=sidethick+(2*adj)+10);
}
}
}
}

84
lib/keyhole.scad Normal file
View File

@@ -0,0 +1,84 @@
/*
This file is part of SBC Case Builder https://github.com/hominoids/SBC_Case_Builder
Copyright 2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
This program 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.
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 this program. If not, see <http://www.gnu.org/licenses/>
Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
*/
/*
NAME: keyhole
DESCRIPTION: enclosed keyhole
TODO: none
USAGE: keyhole(keysize, mask)
keysize[0] = size_x
keysize[1] = size_y
keysize[2] = size_z
mask[0] = true enables component mask
mask[1] = mask length
mask[2] = mask setback
mask[3] = mstyle "default"
*/
module keyhole(keysize, mask) {
enablemask = mask[0];
mlength = mask[1];
msetback = mask[2];
mstyle = mask[3];
adj=.01;
$fn = 90;
if(enablemask == true && mstyle == "default") {
union() {
translate([0, 0, -adj]) cylinder(h=keysize[3]+2*adj, d=keysize[0]);
translate([-keysize[1]/2, 0, -adj]) cube([keysize[1], keysize[2]+keysize[0]/2, keysize[3]+2*adj]);
translate([0, -keysize[1]/2, -adj]) cube([keysize[2]+keysize[0]/2, keysize[1], keysize[3]+2*adj]);
}
}
else {
difference() {
union() {
translate([0, 0, -adj])
difference() {
difference() {
translate([-keysize[2], -keysize[2], keysize[3]]) cube([keysize[2]*3, keysize[2]*3, 4.5]);
translate([0, -10, 0]) rotate([0, 0, 135]) cube([20, 10, 10]);
translate([keysize[2], keysize[2], -adj]) cube([keysize[2]*3, keysize[2]*3, keysize[3]+5]);
}
difference() {
translate([-keysize[2]+2, -keysize[2]+2, keysize[3]-adj])
cube([-4+keysize[2]*3, -4+keysize[2]*3, 3.5]);
translate([2, -10, 0]) rotate([0, 0, 135]) cube([20, 10, 10]);
translate([+keysize[2]-2, keysize[2]-2, -adj])
cube([keysize[2]*3, keysize[2]*3, keysize[3]+5]);
}
}
difference() {
translate([-keysize[2], -keysize[2], 0]) cube([keysize[2]*3, keysize[2]*3, keysize[3]]);
translate([0, -10, -adj]) rotate([0, 0, 135]) cube([20, 10, 10]);
}
}
translate([keysize[2], keysize[2], -adj]) cube([keysize[2]*3, keysize[2]*3, keysize[3]+2*adj]);
union() {
translate([0, 0, -adj]) cylinder(h=keysize[3]+2*adj, d=keysize[0]);
translate([-keysize[1]/2, 0, -adj]) cube([keysize[1], keysize[2]+keysize[0]/2, keysize[3]+2*adj]);
translate([0, -keysize[1]/2, -adj]) cube([keysize[2]+keysize[0]/2, keysize[1], keysize[3]+2*adj]);
}
}
}
}

214
lib/oem_adafruit.scad Normal file
View File

@@ -0,0 +1,214 @@
/*
This file is part of SBC Case Builder https://github.com/hominoids/SBC_Case_Builder
Copyright 2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
This program 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.
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 this program. If not, see <http://www.gnu.org/licenses/>
Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
adafruit_2030_powerboost(mask)
adafruit_4311_lcd(mask)
adafruit_4755_solar_charger(mask)
*/
/*
NAME: adafruit_2030_powerboost
DESCRIPTION: adafruit 2030 Powerboost 1000 Basic
TODO: none
USAGE: adafruit_2030_powerboost(mask[])
mask[0] = true enables mask
mask[1] = mask length
mask[2] = mask setback
mask[3] = mstyle "default"
*/
module adafruit_2030_powerboost(mask) {
size_x = 29.21;
size_y = 22.86;
size_z = 1.6;
lcd_size = [34.75,48,2];
corner_radius = 2;
hole_size = 2.54;
enablemask = mask[0];
mlen = mask[1];
back = mask[2];
mstyle = mask[3];
adj = .01;
$fn = 90;
if(enablemask == true && mstyle == "default") {
jst("ph",0,8.5,0,"top",90,[2,0,0],["thruhole","side","white"], size_z, enablemask, [true,10,2,"default"]);
usb2("single_horizontal_a",23,4.5,0,"top",270,[0,13,0],[0], size_z, enablemask, [true,12,7,"default"]);
}
if(enablemask == false) {
difference() {
color("#252525") slab([size_x, size_y, size_z], corner_radius);
color("#252525") translate([hole_size, size_y-hole_size, -adj]) cylinder(d=hole_size,h=6);
color("#252525") translate([hole_size, hole_size, -adj]) cylinder(d=hole_size, h=4);
for(i=[6:2.54:20]) {
color("#fee5a6",1) translate([i, 21.5, -adj]) cylinder(d=.8, h=6);
}
}
pcbpad("round", 6, 21.5, 0, "top", 0, [6, 1, 0], [.8, "#fee5a6", 1.2], size_z, enablemask, [false, 20, 0, "default"]);
pcbpad("round", hole_size, size_y-hole_size, 0, "top", 0, [1, 1, 0],
[hole_size, "#fee5a6", hole_size+1], size_z, enablemask, [false, 20, 0, "default"]);
pcbpad("round", hole_size, hole_size, 0, "top", 0, [1, 1, 0],
[hole_size, "#fee5a6", hole_size+1], size_z, enablemask, [false, 20, 0, "default"]);
ic("generic", 12.5, 11, 0, "top", 0, [9, 9, 2], ["dimgrey"], size_z, enablemask, [false, 20, 0, "default"]);
ic("generic", 13.5, 5, 0, "top", 0, [4, 4, .8], ["dimgrey"], size_z, enablemask, [false, 20, 0, "default"]);
jst("ph",0,8.5,0,"top",90,[2,0,0],["thruhole","side","white"], size_z, enablemask, [true,10,2,"default"]);
usb2("single_horizontal_a",23,4.5,0,"top",270,[0,13,0],[0], size_z, enablemask, [true,10,2,"default"]);
}
}
/*
NAME: adafruit_lcd
DESCRIPTION: adafruit 4311 2in TFT IPS Display model
TODO: none
USAGE: adafruit_4311_lcd(mask[])
mask[0] = true enables mask
mask[1] = mask length
mask[2] = mask setback
mask[3] = mstyle "default"
*/
module adafruit_4311_lcd(mask) {
size_x = 35.5;
size_y = 59;
size_z = 1.6;
size_xm = size_x+1;
size_ym = size_y+1;
lcd_size = [34.75,48,2];
corner_radius = 2;
hole_size = 2.5;
enablemask = mask[0];
mlen = mask[1];
back = mask[2];
mstyle = mask[3];
adj = .01;
$fn = 90;
if(enablemask == true && mstyle == "default") {
translate([2.25, 11, size_z+2.5-back]) cube([lcd_size[0]-4, lcd_size[1]-7, mlen]);
storage("microsdcard", 11, 44, 0, "bottom", 180, [size_x, size_z, size_y], [0], size_z, enablemask, [true, 20, 0, "default"]);
fpc("fh19", .5, 22, 0, "bottom", 270, [18,0,0], ["smt","side","white","black"], size_z, enablemask, [true,10,2,"default"]);
}
if(enablemask == false) {
difference() {
union() {
color("#252525") slab([size_x, size_y, size_z], corner_radius);
color("black",1) translate([0.375, 5.75, size_z-adj]) cube([lcd_size[0], lcd_size[1], 2.5]);
color("#353535",1) translate([.375, 9.25, size_z+2.5-adj]) cube([lcd_size[0], lcd_size[1]-4, .1]);
color("dimgrey",1) translate([2.25, 11, size_z+2.5-adj]) cube([lcd_size[0]-4, lcd_size[1]-7, .2]);
}
color("#252525") translate([hole_size, size_y-hole_size, -adj]) cylinder(d=hole_size,h=6);
color("#252525") translate([size_x-hole_size, size_y-hole_size, -adj]) cylinder(d=hole_size, h=4);
for(i=[5:2.54:31]) {
color("#fee5a6",1) translate([i, 2.5, -adj]) cylinder(d=.8, h=6);
}
}
storage("microsdcard", 11, 44, 0, "bottom", 180, [size_x, size_z, size_y], [0], size_z, enablemask, [true, 20, 0, "default"]);
ic("generic", 13.25, 9, 0, "bottom", 0, [4, 10, 1.75], ["dimgrey"], size_z, enablemask, [false, 20, 0, "default"]);
fpc("fh19", .5, 22, 0, "bottom", 270, [18,0,0], ["smt","side","white","black"], size_z, enablemask, [true,10,2,"default"]);
for(i=[5:2.54:31]) {
pcbpad("round", i, 2.5, 0, "top", 0, [1, 1, 0], [.8, "#fee5a6", 1.2], size_z, enablemask, [false, 20, 0, "default"]);
}
pcbpad("round", hole_size, size_y-hole_size, 0, "top", 0, [1, 1, 0],
[hole_size, "#fee5a6", hole_size+1], size_z, enablemask, [false, 20, 0, "default"]);
pcbpad("round", size_x-hole_size, size_y-hole_size, 0, "top", 0, [1, 1, 0],
[hole_size, "#fee5a6", hole_size+1], size_z, enablemask, [false, 20, 0, "default"]);
}
}
/*
NAME: adafruit_4755_solar_charger
DESCRIPTION: adafruit 4755 Universal USB/DC/Solar Lithium Ion/Polymer charger - bq24074
TODO: none
USAGE: adafruit_4755_solar_charger(mask[])
mask[0] = true enables mask
mask[1] = mask length
mask[2] = mask setback
mask[3] = mstyle "default"
*/
module adafruit_4755_solar_charger(mask) {
size_x = 38.1;
size_y = 33.02;
size_z = 1.6;
lcd_size = [34.75,48,2];
corner_radius = 2;
hole_size = 2.54;
enablemask = mask[0];
mlen = mask[1];
back = mask[2];
mstyle = mask[3];
adj = .01;
$fn = 90;
if(enablemask == true && mstyle == "default") {
jst("ph",33.5,8,0,"top",270,[2,0,0],["thruhole","side","white"], size_z, enablemask, [true,10,2,"default"]);
jst("ph",33.5,19,0,"top",270,[2,0,0],["thruhole","side","white"], size_z, enablemask, [true,10,2,"default"]);
usbc("single_horizontal",-1,5.5,0,"top",90,[0,13,0],[0], size_z, enablemask, [true,10,2,"default"]);
power("pj-202ah",-2,17.5,0,"top",90,[0,13,0],[0], size_z, enablemask, [true,10,2,"default"]);
}
if(enablemask == false) {
difference() {
color("#252525") slab([size_x, size_y, size_z], corner_radius);
color("#252525") translate([hole_size, size_y-hole_size, -adj]) cylinder(d=hole_size,h=6);
color("#252525") translate([hole_size, hole_size, -adj]) cylinder(d=hole_size, h=4);
color("#252525") translate([size_x-hole_size, size_y-hole_size, -adj]) cylinder(d=hole_size,h=6);
color("#252525") translate([size_x-hole_size, hole_size, -adj]) cylinder(d=hole_size, h=4);
for(i=[6.5:2.54:25]) {
color("#fee5a6",1) translate([i, 2.5, -adj]) cylinder(d=.8, h=6);
}
}
pcbpad("round", 6.5, 2.5, 0, "top", 0, [11, 1, 0], [.8, "#fee5a6", 1.2], size_z, enablemask, [false, 20, 0, "default"]);
pcbpad("round", hole_size, size_y-hole_size, 0, "top", 0, [1, 1, 0],
[hole_size, "#fee5a6", hole_size+1], size_z, enablemask, [false, 20, 0, "default"]);
pcbpad("round", hole_size, hole_size, 0, "top", 0, [1, 1, 0],
[hole_size, "#fee5a6", hole_size+1], size_z, enablemask, [false, 20, 0, "default"]);
pcbpad("round", size_x-hole_size, size_y-hole_size, 0, "top", 0, [1, 1, 0],
[hole_size, "#fee5a6", hole_size+1], size_z, enablemask, [false, 20, 0, "default"]);
pcbpad("round", size_x-hole_size, hole_size, 0, "top", 0, [1, 1, 0],
[hole_size, "#fee5a6", hole_size+1], size_z, enablemask, [false, 20, 0, "default"]);
ic("generic", 17.5, 15, 0, "top", 0, [4, 4, .8], ["dimgrey"], size_z, enablemask, [false, 20, 0, "default"]);
jst("ph",33.5,8,0,"top",270,[2,0,0],["thruhole","side","white"], size_z, enablemask, [true,10,2,"default"]);
jst("ph",33.5,19,0,"top",270,[2,0,0],["thruhole","side","white"], size_z, enablemask, [true,10,2,"default"]);
usbc("single_horizontal",-1,5.5,0,"top",90,[0,13,0],[0], size_z, enablemask, [true,10,2,"default"]);
power("pj-202ah",-2,17.5,0,"top",90,[0,13,0],[0], size_z, enablemask, [true,10,2,"default"]);
}
}

1628
lib/oem_hk.scad Normal file

File diff suppressed because it is too large Load Diff

86
lib/oem_rpi.scad Normal file
View File

@@ -0,0 +1,86 @@
/*
This file is part of SBC Case Builder https://github.com/hominoids/SBC_Case_Builder
Copyright 2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
This program 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.
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 this program. If not, see <http://www.gnu.org/licenses/>
Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
rpi_m2hat(mask)
*/
/*
NAME: rpi_m2hat
DESCRIPTION: Raspberry Pi M.2 HAT+ M Key model
TODO: none
USAGE: rpim2-hat(mask[])
mask[0] = true enables mask
mask[1] = mask length
mask[2] = mask setback
mask[3] = mstyle "default"
*/
module rpi_m2hat(mask) {
size_x = 65;
size_y = 56.5;
size_z = 1.6;
corner_radius = 3.5;
hole_size = 3.5;
enablemask = mask[0];
mlen = mask[1];
back = mask[2];
mstyle = mask[3];
adj = .01;
$fn = 90;
if(enablemask == true && mstyle == "default") {
translate([6, 49, 0]) slab([52.8, 7, mlen],1);
}
if(enablemask == false) {
difference() {
color("#008066") slab([size_x, size_y, size_z], corner_radius);
color("#008066") translate([hole_size, size_y-hole_size, -adj]) cylinder(d=hole_size,h=6);
color("#008066") translate([size_x-hole_size, size_y-hole_size, -adj]) cylinder(d=hole_size, h=4);
color("#008066") translate([hole_size, hole_size, -adj]) cylinder(d=hole_size,h=6);
color("#008066") translate([size_x-hole_size, hole_size, -adj]) cylinder(d=hole_size, h=4);
color("#008066") translate([-3, 21, -adj]) slab([8,18,6],2);
color("#008066") translate([47.5, -2, -adj]) slab([10,18,6],2);
}
header("open",7,50,0,"top",0,[20,2,4],["smt","black","female",2.54,"#fee5a6"], size_z, enablemask, [false,10,-2,"none"]);
fpc("fh19", 6.5, 25, 0, "top", 90, [16,0,0], ["smt","side","grey","white"], size_z, enablemask, [true,10,2,"default"]);
storage("m.2_header",15,17,0,"top",270,[0,0,0],[0], size_z, enablemask, [true,10,2,"default"]);
pcbpad("round", hole_size, size_y-hole_size, 0, "top", 0, [1, 1, 0],
[hole_size, "#fee5a6", hole_size+1], size_z, enablemask, [false, 20, 0, "default"]);
pcbpad("round", size_x-hole_size, size_y-hole_size, 0, "top", 0, [1, 1, 0],
[hole_size, "#fee5a6", hole_size+1], size_z, enablemask, [false, 20, 0, "default"]);
pcbpad("round", hole_size, hole_size, 0, "top", 0, [1, 1, 0],
[hole_size, "#fee5a6", hole_size+1], size_z, enablemask, [false, 20, 0, "default"]);
pcbpad("round", size_x-hole_size, hole_size, 0, "top", 0, [1, 1, 0],
[hole_size, "#fee5a6", hole_size+1], size_z, enablemask, [false, 20, 0, "default"]);
// pillar("hex", hole_size-4, size_y-hole_size, 0, "bottom", 0, [4, 3, 16],
// [0, "#fee5a6"], size_z, enablemask, [false, 20, 0, "default"]);
// pillar("hex", size_x-hole_size-4, size_y-hole_size, 0, "bottom", 0, [4, 3, 16],
// [0, "#fee5a6"], size_z, enablemask, [false, 20, 0, "default"]);
// pillar("hex", hole_size-4, hole_size, 0, "bottom", 0, [4, 3, 16],
// [0, "#fee5a6"], size_z, enablemask, [false, 20, 0, "default"]);
// pillar("hex", size_x-hole_size-4, hole_size, 0, "bottom", 0, [4, 3, 16],
// [0, "#fee5a6"], size_z, enablemask, [false, 20, 0, "default"]);
}
}

118
lib/panel_clamp.scad Normal file
View File

@@ -0,0 +1,118 @@
/*
NAME: panel_clamp
DESCRIPTION: creates various clamps to join two panels
TODO: none
USAGE: panel_clamp(face, style, screw, dia_x, dia_y, height, mask)
data[0] = "top","bottom","rear","front","left","right"
data[1] = "sloped"
data[2] = "m2", "m2.5", "m3", "m4"
size_x = top diameter or x size in mm
size_y = bottom diameter or y size in mm
size_z = clamp height in mm
mask[0] = true enables component mask
mask[1] = mask length
mask[2] = mask setback
mask[3] = mstyle "default", "holes"
*/
module panel_clamp(face, style, screw, dia_x, dia_y, height, mask) {
nuts = [[2,4,1.6], // m2 size, diameter, height
[2.5,5,2], // m2.5 size, diameter, height
[3,5.5,2.4], // m3 size, diameter, height
[4,7,3.2]]; // m4 size, diameter, height
enablemask = mask[0];
mlength = mask[1];
msetback = mask[2];
mstyle = mask[3];
adj = .01;
$fn = 90;
rotx = face == "rear" ? 270 : face == "front" || face == "left" || face == "right" ? 90 : face == "top" ? 180 : 0;
roty = 0;
rotz = face == "left" ? 90 : face == "right" ? 270 : 0;
if(enablemask == true) {
rotate([rotx,roty,rotz]) {
if(mstyle == "default") {
cylinder(d=dia_y, h=height);
}
if(screw == "m2" && mstyle == "holes") {
translate([(-dia_y-(nuts[2][0]+.5)/2)/2, 0, 2.25]) rotate([0,90,0])
cylinder(d=nuts[0][0]+.5, h=dia_y+2);
translate([-(dia_y/2), 0, 2.25]) rotate([0,90,0])
cylinder(d=nuts[0][1]*2/sqrt(3), h=dia_y*.375, $fn=6);
translate([nuts[0][0]+.5, 0, 2.25]) rotate([0,90,0])
cylinder(d=nuts[0][1]+.5, h=dia_y*.375);
}
if(screw == "m2.5" && mstyle == "holes") {
translate([(-dia_y-(nuts[2][0]+.5)/2)/2, 0, 3]) rotate([0,90,0])
cylinder(d=nuts[1][0]+.5, h=dia_y+2);
translate([-(dia_y/2), 0, 3]) rotate([0,90,0])
cylinder(d=nuts[1][1]*2/sqrt(3), h=dia_y*.375, $fn=6);
translate([nuts[1][0]+.5, 0, 3]) rotate([0,90,0])
cylinder(d=nuts[1][1]+.5, h=dia_y*.375);
}
if(screw == "m3" && mstyle == "holes") {
translate([(-dia_y-(nuts[2][0]+.5)/2)/2, 0, 3]) rotate([0,90,0])
cylinder(d=nuts[2][0]+.5, h=dia_y+2);
translate([-(dia_y/2), 0, 3]) rotate([0,90,0])
cylinder(d=nuts[2][1]*2/sqrt(3), h=dia_y*.375, $fn=6);
translate([nuts[2][0]+.5, 0, 3]) rotate([0,90,0])
cylinder(d=nuts[2][1]+.5, h=dia_y*.375);
}
if(screw == "m4" && mstyle == "holes") {
translate([(-dia_y-(nuts[2][0]+.5)/2)/2, 0, 3]) rotate([0,90,0])
cylinder(d=nuts[3][0]+.5, h=dia_y+2);
translate([-(dia_y/2), 0, 3]) rotate([0,90,0])
cylinder(d=nuts[3][1]*2/sqrt(3), h=dia_y*.375, $fn=6);
translate([nuts[3][0]+.5, 0, 3]) rotate([0,90,0])
cylinder(d=nuts[3][1]+.5, h=dia_y*.375);
}
}
}
if(enablemask == false) {
rotate([rotx,roty,rotz]) {
difference() {
cylinder(d2=dia_x, d1=dia_y, h=height);
if(screw == "m2") {
translate([(-dia_y-(nuts[2][0]+.5)/2)/2, 0, 2.25]) rotate([0,90,0])
cylinder(d=nuts[0][0]+.5, h=dia_y+2);
translate([-(dia_y/2), 0, 2.25]) rotate([0,90,0])
cylinder(d=nuts[0][1]*2/sqrt(3), h=dia_y*.375, $fn=6);
translate([nuts[0][0]+.5, 0, 2.25]) rotate([0,90,0])
cylinder(d=nuts[0][1]+.5, h=dia_y*.375);
}
if(screw == "m2.5") {
translate([(-dia_y-(nuts[2][0]+.5)/2)/2, 0, 3]) rotate([0,90,0])
cylinder(d=nuts[1][0]+.5, h=dia_y+2);
translate([-(dia_y/2), 0, 3]) rotate([0,90,0])
cylinder(d=nuts[1][1]*2/sqrt(3), h=dia_y*.375, $fn=6);
translate([nuts[1][0]+.5, 0, 3]) rotate([0,90,0])
cylinder(d=nuts[1][1]+.5, h=dia_y*.375);
}
if(screw == "m3") {
translate([(-dia_y-(nuts[2][0]+.5)/2)/2, 0, 3]) rotate([0,90,0])
cylinder(d=nuts[2][0]+.5, h=dia_y+2);
translate([-(dia_y/2), 0, 3]) rotate([0,90,0])
cylinder(d=nuts[2][1]*2/sqrt(3), h=dia_y*.375, $fn=6);
translate([nuts[2][0]+.5, 0, 3]) rotate([0,90,0])
cylinder(d=nuts[2][1]+.5, h=dia_y*.375);
}
if(screw == "m4") {
translate([(-dia_y-(nuts[2][0]+.5)/2)/2, 0, 3]) rotate([0,90,0])
cylinder(d=nuts[3][0]+.5, h=dia_y+2);
translate([-(dia_y/2), 0, 3]) rotate([0,90,0])
cylinder(d=nuts[3][1]*2/sqrt(3), h=dia_y*.375, $fn=6);
translate([nuts[3][0]+.5, 0, 3]) rotate([0,90,0])
cylinder(d=nuts[3][1]+.5, h=dia_y*.375);
}
}
}
}
}

205
lib/rack.scad Normal file
View File

@@ -0,0 +1,205 @@
/*
This file is part of SBC Case Builder https://github.com/hominoids/SBC_Case_Builder
Copyright 2022,2023,2024,2025 Edward A. Kisiel hominoid@cablemi.com
This program 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.
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 this program. If not, see <http://www.gnu.org/licenses/>
Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
rack_end_bracket(side, size, thick)
rack_rail(style, rack_1u, hole_dia, thick)
rack_stand(rack_1u)
*/
/*
NAME: rack_end_bracket
DESCRIPTION: creates rack mounting ears
TODO: none
USAGE: rack_end_bracket(side, size, thick)
side = "left", "right"
size = "1u", "2u", "3u", "4u"
thick = thickness of bracket
*/
module rack_end_bracket(side, size, thick) {
u1 = 44.45;
depth = size == "1u" ? 44.45 : size == "1u+" ? 59.26 : size == "1u++" ? 74.07 : size == "2u" ? 2*44.45 : size == "3u" ? 3*44.45 : 4*44.45;
mask = size == "1u" ? 44.45 : size == "1u+" ? 88.9 : size == "1u++" ? 88.9 : size == "2u" ? 2*44.45 : size == "3u" ? 3*44.45 : 4*44.45;
c_fillet = 2;
hole = 3.2;
rack_hole = 6;
tab_width = 15.875+thick;
b_width = thick;
b_depth = depth;
b_height = thick;
b_loc = [-thick,0,0];
adjust = .01;
$fn=90;
if(side == "left") {
translate([thick,0,0]) rotate([90,0,0])
difference() {
union() {
translate([(-tab_width/2),(depth/2),thick/2])
cube_fillet_inside([tab_width,depth,thick],
vertical=[0,c_fillet,c_fillet,0],top=[0,0,0,0],bottom=[0,0,0,0], $fn=90);
translate([(b_width/2)+b_loc[0],(b_depth/2)+b_loc[1],(b_height/2)+b_loc[2]])
cube_fillet_inside([b_width,b_depth,b_height],
vertical=[0,0,0,0],top=[c_fillet,0,c_fillet,0],bottom=[0,0,0,0], $fn=90);
}
for(i=[0:u1:mask-u1]) {
for(c=[6.35:15.875:44.45]) {
translate([(3-thick)-9-(15.875-9)/2,c+i,-adjust])
slot(rack_hole,3,thick+(adjust*2));
}
}
}
}
if(side == "right") {
translate([-thick,-thick,0]) rotate([270,180,0])
difference() {
union() {
translate([(-tab_width/2),(depth/2),thick/2])
cube_fillet_inside([tab_width,depth,thick],
vertical=[0,c_fillet,c_fillet,0],top=[0,0,0,0],bottom=[0,0,0,0], $fn=90);
translate([(b_width/2)+b_loc[0],(b_depth/2)+b_loc[1],(b_height/2)+b_loc[2]])
cube_fillet_inside([b_width,b_depth,b_height],
vertical=[0,0,0,0],top=[c_fillet,0,c_fillet,0],bottom=[0,0,0,0], $fn=90);
}
for(i=[0:u1:mask-u1]) {
for(c=[6.35:15.875:44.45]) {
translate([(3-thick)-9-(15.875-9)/2,c+i,-adjust]) slot(rack_hole,3,thick+(adjust*2));
}
}
}
}
}
/*
NAME: rack_rail
DESCRIPTION: creates rack rail lengths
TODO: none
USAGE: rack_rail(style, rack_1u, hole_dia, thick)
style = "none", "nut", "insert"
rack_1u = number of 1u
hole_dia = hole size to create
thick = thickness of bracket
*/
module rack_rail(style, rack_1u, hole_dia, thick) {
1u = 44.45;
mount_rail = 15.875;
1u_hole_offset = 6.35;
1u_hole_spacing = 15.875;
height = rack_1u * 1u;
difference() {
union() {
cube([mount_rail, thick, height]);
if(style == "nut" || style == "insert") {
fastner = style == "insert" ? "m3-insert" : "m3";
for(i=[0:rack_1u-1]) {
translate([mount_rail/2, adj, i*1u]) {
translate([0,0,1u_hole_offset]) rotate([90,0,0])
nut_holder(fastner, "sloped", 7, mount_rail-1, 3, [false,10,2,"default"]);
translate([0,0,1u_hole_offset+1u_hole_spacing])
rotate([90,0,0]) nut_holder(fastner, "sloped", 7, mount_rail-1, 3, [false,10,2,"default"]);
translate([0,0,1u_hole_offset+2*1u_hole_spacing])
rotate([90,0,0]) nut_holder(fastner, "sloped", 7, mount_rail-1, 3, [false,10,2,"default"]);
}
}
}
}
for(i=[0:rack_1u-1]) {
translate([mount_rail/2, -1, i*1u]) {
translate([0,thick+2,1u_hole_offset]) rotate([90,0,0]) cylinder(d = hole_dia, h=thick+2);
translate([0,thick+2,1u_hole_offset+1u_hole_spacing]) rotate([90,0,0]) cylinder(d = hole_dia, h=thick+2);
translate([0,thick+2,1u_hole_offset+2*1u_hole_spacing]) rotate([90,0,0]) cylinder(d = hole_dia, h=thick+2);
}
}
translate([-1,-1,height]) cube([mount_rail+2,thick+2,10]);
}
}
/*
NAME: rack_stand
DESCRIPTION: creates rack stand of 1u hieght
TODO: none
USAGE: rack_stand(rack_1u)
rack_1u = number of 1u
*/
module rack_stand(rack_1u) {
1u = 44.45;
mount_rail = 15.875;
thick = 5;
height = rack_1u * 1u;
height_offset = 25.4/2;
hole_dia = 3.2;
c_fillet = 9;
rail_offset = 87.5;
foot_length = 175;
foot_thick = 4;
$fn=180;
// vertical rack rails
translate([0, 0, height_offset-adj]) rack_rail(rack_fasteners, rack_1u, hole_dia, thick);
// bottom feet
translate([mount_rail/2, -rail_offset/2, foot_thick-2]) cube_fillet_inside([mount_rail, foot_length, foot_thick],
vertical=[0,0,0,0], top=[c_fillet,0,c_fillet,0], bottom=[0,0,0,0], $fn=90);
// bottom connection piece
translate([0, 0, 0]) cube([mount_rail, thick, height_offset]);
// top extension piece
ext_len = rack_1u == 4 ? thick : rack_1u == 3 ? thick : thick;
translate([0, 0, height+height_offset-adj]) cube([mount_rail, thick, ext_len]);
// support arc
if(rack_1u > 0) {
ext_adj = rack_1u == 4 ? 4.5*thick : rack_1u == 3 ? 3.5*thick : 2.5*thick;
difference() {
translate([0,(height/2)-5*thick,ext_adj]) rotate([0,90,0]) {
difference() {
translate([0,0,0]) cylinder(d=(2*height)+(3*thick), h=mount_rail);
translate([0,0,-adj]) cylinder(d=(2*height)+thick+4, h=mount_rail+(2*adj));
}
}
// top trim
translate([-1, thick, height+height_offset-5]) cube([mount_rail+2, 300, 40]);
// front trim
translate([-1, 42.75, -175]) cube([mount_rail+2, 300, 400]);
translate([-1, thick, foot_thick]) cube([mount_rail+2, 300, 400]);
// bottom trim
translate([-1, -150, -174.5]) cube([mount_rail+2, 300, 175]);
}
}
}

190
lib/standoff.scad Normal file
View File

@@ -0,0 +1,190 @@
/*
This file is part of SBC Case Builder https://github.com/hominoids/SBC_Case_Builder
Copyright 2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
This program 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.
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 this program. If not, see <http://www.gnu.org/licenses/>
Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
*/
/*
NAME: standoff
DESCRIPTION: create standoffs
TODO: none
USAGE: standoff(stand_off, mask)
stand_off[size, diameter, height, holesize, supportsize, supportheight, sink, pillarstyle,
pillarsupport, reverse, insert_e, i_dia, i_depth], mask)
size = "m2_tap","m2","m2+","m2.5_tap","m2.5","m2.5+","m3_tap","m3","m3+","m4_tap","m4","m4+","custom"
diameter = pillar diameter
height = total height
holesize = hole diameter
supportsize = support size for sink
supportheight = height of support for sink
sink = none, countersunk, recessed, nut holder, blind
pillarstyle = hex, round
pillarsupport = none, left, rear, front, right
reverse = true or false
insert_e = true or false
i_dia = insert diameter
i_depth = insert hole depth
mask[0] = enablemask
mask[1] = mlength
mask[2] = msetback
mask[3] = mstyle
*/
module standoff(stand_off, mask){
size = stand_off[0];
diameter = size == "m2_tap" || size == "m2" || size == "m2+" ? 4 :
size == "m2.5_tap" || size == "m2.5" || size == "m2.5+" ? 4 :
size == "m3_tap" || size == "m3" || size == "m3+" ? 5 :
size == "m4_tap" || size == "m4" || size == "m4+" ? 6 : stand_off[1];
height = stand_off[2];
holesize = size == "m2_tap" ? 1.6 : size == "m2" ? 2 : size == "m2+" ? 2.26 :
size == "m2.5_tap" ? 2.05 : size == "m2.5" ? 2.5 : size == "m2.5+" ? 2.83 :
size == "m3_tap" ? 2.5 : size == "m3" ? 3 : size == "m3+" ? 3.4 :
size == "m4_tap" ? 3.3 : size == "m4" ? 4 : size == "m4+" ? 4.4 : stand_off[3];
supportsize = stand_off[4];
supportheight = stand_off[5];
sink = stand_off[6];
pillarstyle = stand_off[7];
pillarsupport = stand_off[8];
reverse = stand_off[9];
insert_e = stand_off[10];
i_dia = stand_off[11];
i_depth = stand_off[12];
enablemask = mask[0];
mlength = mask[1];
msetback = mask[2];
mstyle = mask[3];
ps = size == "m2_tap" || size == "m2" || size == "m2+" ? 4 :
size == "m2.5_tap" || size == "m2.5" || size == "m2.5+" ? 5.375 :
size == "m3_tap" || size == "m3" || size == "m3+" ? 6.72 :
size == "m4_tap" || size == "m4" || size == "m4+" ? 8.96 : (2*holesize)+.5;
ds = size == "m2_tap" || size == "m2" || size == "m2+" ? 1.2 :
size == "m2.5_tap" || size == "m2.5" || size == "m2.5+" ? 1.5 :
size == "m3_tap" || size == "m3" || size == "m3+" ? 1.86 :
size == "m4_tap" || size == "m4" || size == "m4+" ? 2.48 : holesize*.465;
adj = 0.1;
$fn = 90;
if(enablemask == true && mstyle == "default") {
if(reverse == true) {
translate([0,0,-msetback-adj]) cylinder(d=supportsize-2*adj,h=mlength);
}
else {
translate([0,0,-mlength+msetback+adj]) cylinder(d=supportsize-2*adj,h=mlength);
}
}
if(enablemask == false) {
difference (){
union () {
if(pillarstyle == "hex" && reverse == false) {
rotate([0,0,30]) cylinder(d=diameter*2/sqrt(3), h=height, $fn=6);
}
if(pillarstyle == "hex" && reverse == true) {
translate([0,0,-height]) rotate([0,0,30]) cylinder(d=diameter*2/sqrt(3), h=height, $fn=6);
}
if(pillarstyle == "round" && reverse == false) {
cylinder(d=diameter, h=height);
}
if(pillarstyle == "round" && reverse == true) {
translate([0,0,-height]) cylinder(d=diameter, h=height);
}
if(reverse == true) {
translate([0,0,-supportheight]) cylinder(d=supportsize, h=supportheight);
}
else {
cylinder(d=(supportsize),h=supportheight);
}
if(pillarsupport == "rear" && reverse == true) {
translate([-1,-supportsize/2,-height]) cube([2, supportsize/2, height]);
}
if(pillarsupport == "rear" && reverse == false) {
translate([-1,-supportsize/2,0]) cube([2, supportsize/2, height]);
}
if(pillarsupport == "front" && reverse == true) {
translate([-1,0,-height]) cube([2, supportsize/2, height]);
}
if(pillarsupport == "front" && reverse == false) {
translate([-1,0,0]) cube([2, supportsize/2, height]);
}
if(pillarsupport == "left" && reverse == true) {
translate([-supportsize/2,-1,-height]) cube([supportsize/2, 2, height]);
}
if(pillarsupport == "left" && reverse == false) {
translate([-supportsize/2,-1,0]) cube([supportsize/2, 2, height]);
}
if(pillarsupport == "right" && reverse == true) {
translate([0,-1,-height]) cube([supportsize/2, 2, height]);
}
if(pillarsupport == "right" && reverse == false) {
translate([0,-1,0]) cube([supportsize/2, 2, height]);
}
}
// hole
if(sink == "none" && reverse == false) {
translate([0,0,-adj]) cylinder(d=holesize, h=height+(adj*2));
}
if(sink != "blind" && reverse == false) {
translate([0,0,-adj]) cylinder(d=holesize, h=height+(adj*2));
}
if(sink != "blind" && reverse == true) {
translate([0,0,-adj-height]) cylinder(d=holesize, h=height+(adj*2));
}
// countersink hole
if(sink == "countersunk" && reverse == false) {
translate([0,0,-adj]) cylinder(d1=ps, d2=holesize, h=ds);
}
if(sink == "countersunk" && reverse == true) {
translate([0,0,+adj-ds]) cylinder(d1=holesize, d2=ps, h=ds);
}
// recessed hole
if(sink == "recessed" && reverse == false) {
translate([0,0,-adj]) cylinder(d=6.5, h=supportheight-2);
}
if(sink == "recessed" && reverse == true) {
translate([0,0,+adj-supportheight+2]) cylinder(d=6.5, h=supportheight-2);
}
// nut holder
if(sink == "nut holder" && reverse == false) {
translate([0,0,-adj]) cylinder(d=ps*2/sqrt(3),h=ds,$fn=6);
}
if(sink == "nut holder" && reverse == true) {
translate([0,0,+adj-ds]) cylinder(d=ps*2/sqrt(3),h=ds,$fn=6);
}
// blind hole
if(sink == "blind" && reverse == false) {
translate([0,0,2]) cylinder(d=holesize, h=height);
}
if(sink == "blind" && reverse == true) {
translate([0,0,-height-2-adj]) cylinder(d=holesize, h=height);
}
if(insert_e == true && reverse == false) {
translate([0,0,height-i_depth]) cylinder(d=i_dia, h=i_depth+adj);
}
if(insert_e == true && reverse == true) {
translate([0,0,-height-adj]) cylinder(d=i_dia, h=i_depth+adj);
}
}
}
}

63
lib/vent.scad Normal file
View File

@@ -0,0 +1,63 @@
/*
This file is part of SBC Case Builder https://github.com/hominoids/SBC_Case_Builder
Copyright 2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
This program 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.
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 this program. If not, see <http://www.gnu.org/licenses/>
Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
vent_panel_hex(x, y, thick, cell_size, cell_spacing, border, borders);
*/
/*
NAME: vent_panel_hex
DESCRIPTION: creates hex vent panel
TODO: none
USAGE: vent_panel_hex(x, y, thick, cell_size=8, cell_spacing=3, border=3, borders="default")
x = #rows
y = #columns
thick = pattern thickness
cell_size = size of hex
cell_spacing = space between hex
border = size of borber
borders = "none", "default"
*/
module vent_panel_hex(x, y, thick, cell_size=8, cell_spacing=3, border=3, borders="default") {
hole = 3.2;
xb = (borders == "y" || borders == "none") ? cell_spacing : border;
yb = (borders == "x" || borders == "none") ? cell_spacing : border;
hxb = max(yb/2, cell_spacing + hole);
hyb = max(xb/2, cell_spacing + hole);
cells_x = floor((2*(x-2*xb-cell_size)/(cell_size+cell_spacing))+1);
cells_y = floor(((sqrt(12)*(y-2*yb)-4*cell_size)/(3*(cell_size+cell_spacing)))+1);
csx = cell_size + (cells_x-1)*(cell_size+cell_spacing)/2;
csy = sqrt(4/3)*cell_size + ((cell_size+cell_spacing)*sqrt(3/4)*(cells_y-1));
difference() {
color("grey",1) slab([x,y,thick],2);
color("grey",1) translate([(x-csx)/2,(y-csy)/2,-1])
vent_hex(cells_x, cells_y, thick+3, cell_size, cell_spacing, "horizontal");
if (borders != "none") {
color("grey",1) translate([ hxb, hyb, -1]) cylinder(d=hole, h=thick+3);
color("grey",1) translate([x - hxb, hyb, -1]) cylinder(d=hole, h=thick+3);
color("grey",1) translate([ hxb, y - hyb, -1]) cylinder(d=hole, h=thick+3);
color("grey",1) translate([x - hxb, y - hyb, -1]) cylinder(d=hole, h=thick+3);
}
}
}

226
mod/add.scad Normal file
View File

@@ -0,0 +1,226 @@
/*
This file is part of SBC Case Builder https://github.com/hominoids/SBC_Case_Builder
Copyright 2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
This program 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.
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 this program. If not, see <http://www.gnu.org/licenses/>
Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
NAME: add
DESCRIPTION: places additive objects
TODO: none
USAGE: add(type, loc_x, loc_y, loc_z, face, rotation, size[], data[], mask[])
type = component type
loc_x = x location placement
loc_y = y location placement
loc_z = z location placement
face = "top", "bottom", "left", "right", "front", "rear"
rotation[] = object rotation
parametric[] = parametric movement array
size[] = size array x,y,z
data[] = data variable on type
mask[0] = true enables component mask
mask[1] = mask length
mask[2] = mask setback
mask[3] = mstyle "default"
*/
module add(type, loc_x, loc_y, loc_z, face, rotation, size, data, mask) {
size_x = size[0];
size_y = size[1];
size_z = size[2];
enablemask = mask[0];
mlen = mask[1];
msetback = mask[2];
mstyle = mask[3];
if(type == "access_cover") {
if(rotation[2] == 180) {
color("grey",1) translate([loc_x+size_x,loc_y+size_y,loc_z]) rotate(rotation) access_cover([size_x,size_y,size_z],data[0]);
}
else {
color("grey",1) translate([loc_x,loc_y,loc_z]) rotate(rotation) access_cover([size_x,size_y,size_z],data[0]);
}
}
if(type == "access_panel") {
if(rotation[2] == 180) {
translate([loc_x+size_x,loc_y+size_y,loc_z]) rotate(rotation) access_panel([size_x,size_y,size_z],data[0],mask);
}
else {
translate([loc_x,loc_y,loc_z]) rotate(rotation) access_panel([size_x,size_y,size_z],data[0],mask);
}
}
if(type == "art") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) art(data[0],data[1],data[2]);
}
if(type == "batt_holder") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) batt_holder(data[0]);
}
if(type == "button") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) buttons(data[0],[size_x,size_y,size_z],data[1],data[2],mask);
}
if(type == "button_assembly") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) button_assembly(data[0],size_x,size_z);
}
if(type == "fan_cover") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) fan_cover(size_x, size_z, data[0]);
}
if(type == "feet") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) feet(size_x, size_z);
}
if(type == "grommet") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) grommet(data[0], data[1], size_x, size_y, size_z, data[2], mask);
}
if(type == "hd_holder") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hd_mount(data[0],data[1],data[2],data[3]);
}
if(type == "hk_boom_grill") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hk_boom_grill(data[0],size_z);
}
if(type == "hk_boom_speaker_holder") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hk_boom_speaker_holder(data[0],data[1]);
}
if(type == "hk_boom_vring") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hk_boom_vring(data[0]);
}
if(type == "hk_h3_port_extender_holder") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hk_h3_port_extender_holder(data[1],data[0]);
}
if(type == "hk_hc4_oled_holder") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hk_hc4_oled_holder(face, size_z, mask);
}
if(type == "hk_uart_holder") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hk_uart_holder(mask);
}
if(type == "hk_uart_strap") {
color("grey",1) translate([loc_x,loc_y,loc_z]) rotate(rotation) hk_uart_strap();
}
if(type == "keyhole") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) keyhole(data[0],mask);
}
if(type == "nut_holder") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) nut_holder(data[0], data[1], size_x, size_y, size_z, mask);
}
if(type == "panel_clamp") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) panel_clamp(data[0], data[1], data[2], size_x, size_y, size_z, mask);
}
if(type == "pcb_holder") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) pcb_holder([size_x,size_y,size_z],data[0]);
}
if(type == "rectangle") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) slab_r([size_x,size_y,size_z],data[0]);
}
if(type == "round") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) cylinder(d=size_x,h=size_z);
}
if(type == "slot") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) slot(size_x,size_y,size_z);
}
if(type == "sphere") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) sphere(d=size_x);
}
if(type == "standoff") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) standoff(data[0], mask);
}
if(type == "text") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) linear_extrude(height = size_z) text(data[1], size=data[0]);
}
if(type == "vent_panel_hex") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) vent_panel_hex(size_x, size_y, thick=size_z,
cell_size=data[0], cell_spacing=data[1], border=data[3], borders=data[2]);
}
// models
if(type == "adafruit_2030_powerboost") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) adafruit_2030_powerboost(mask);
}
if(type == "adafruit_4311_lcd") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) adafruit_4311_lcd(mask);
}
if(type == "adafruit_4755_solar_charger") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) adafruit_4755_solar_charger(mask);
}
if(type == "dsub") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) dsub(data[0], data[1], mask);
}
if(type == "fan") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) fans(data[0],mask);
}
if(type == "hd25") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hd25(data[0],data[1],mask);
}
if(type == "hd35") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hd35(data[0],mask);
}
if(type == "hk_boom") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hk_boom(data[0],data[1],mask);
}
if(type == "hk_boom_speaker") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hk_boom_speaker(mask);
}
if(type == "hk_boom_speaker_pcb") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hk_boom_speaker_pcb(data[1],true,data[0],mask);
}
if(type == "hk_h3_port_extender") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hk_h3_port_extender(data[0],mask);
}
if(type == "hk_hc4_oled") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hk_hc4_oled(mask);
}
if(type == "hk_lcd35") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hk_35lcd(mask);
}
if(type == "hk_m1s_ups") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hk_m1s_ups(mask);
}
if(type == "hk_netcard") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hk_netcard(mask);
}
if(type == "hk_pwr_button") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hk_pwr_button(mask);
}
if(type == "hk_speaker") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hk_speaker(mask);
}
if(type == "hk_uart") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hk_uart(mask);
}
if(type == "hk_vu7c") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hk_vu7c(data[0],data[1],mask);
}
if(type == "hk_vu8m") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hk_vu8m(data[0],mask);
}
if(type == "hk_vu8s") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hk_vu8s(mask);
}
if(type == "hk_wb2") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hk_wb2();
}
if(type == "hk_xu4_shifter_shield") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hk_xu4_shifter_shield(mask);
}
if(type == "pillar") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) pillar(data[0], 0, 0, 0, data[2], 0, size, data, 0, false, mask);
}
if(type == "rpi_m2hat") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) rpi_m2hat(mask);
}
if(type == "stl_model") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) stl_model(data[0],data[1]);
}
}

428
mod/case_adapter.scad Normal file
View File

@@ -0,0 +1,428 @@
/*
This file is part of SBC Case Builder https://github.com/hominoids/SBC_Case_Builder
Copyright 2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
This program 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.
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 this program. If not, see <http://www.gnu.org/licenses/>
Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
NAME: case_adapter
DESCRIPTION: creates adapters for legacy cases footprints
TODO: nano-itx hole locations
USAGE: case_adapter(case_design)
*/
module case_adapter(case_design) {
mb_adapters=[
["adapter_ssi-eeb", 304.8, 330.2, ["left_rear", 6.35, 33.02], ["middle_rear", 163.83, 10.16], ["right_rear", 288.29, 10.16],
["left_middle", 6.35, 165.1], ["middle_middle", 163.83, 165.1], ["right_middle", 288.29, 165.1],
["middle_middle2", 209.55, 237.49], ["right_middle2", 288.29, 237.49],
["left_front", 6.35, 322.58], ["middle_front", 163.83, 322.58], ["right_front", 299.72, 322.58]],
["adapter_ssi-ceb", 304.8, 266.7, ["left_rear", 6.35, 33.02], ["middle_rear", 163.83, 10.16], ["right_rear", 288.29, 10.16],
["left_middle", 6.35, 165.1], ["middle_middle", 163.83, 165.1], ["right_middle", 288.29, 165.1],
["middle_front", 209.55, 237.49], ["right_front", 288.29, 237.49]],
["adapter_atx", 304.8, 243.84, ["left_rear", 6.35, 33.02], ["middle_rear", 163.83, 10.16],
["middle2_rear", 211.99, 10.16], ["right_rear", 288.29, 10.16],
["left_middle", 6.35, 165.1], ["middle_middle", 163.83, 165.1], ["right_middle", 288.29, 165.1],
["left_front", 6.35, 237.49], ["middle_front", 163.83, 237.49], ["right_front", 288.29, 237.49]],
["adapter_micro-atx", 243.84, 243.84, ["left_rear", 6.35, 33.02], ["middle_rear", 163.83, 10.16], ["right_rear", 211.99, 10.16],
["left_middle", 6.35, 165.1], ["middle_middle", 163.83, 165.1],
["middle2_middle", 209.55, 165.1], ["right_middle", 229.87, 165.1],
["left_front", 6.35, 237.49], ["right_front", 163.83, 237.49]],
["adapter_dtx", 230.2, 243.84, ["left_rear", 6.35, 33.02], ["middle_rear", 163.83, 10.16], ["right_rear", 211.99, 10.16],
["left_middle", 6.35, 165.1], ["middle_middle", 163.83, 165.1], ["right_middle", 209.55, 165.1],
["left_front", 6.35, 237.49], ["right_front", 163.83, 237.49]],
["adapter_flex-atx", 228.6, 190.5, ["left_rear", 6.35, 33.02], ["middle_rear", 163.83, 10.16], ["right_rear", 211.99, 10.16],
["left_front", 6.35, 165.1], ["middle_front", 163.83, 165.1],
["right_front", 209.55, 165.1]],
["adapter_mini-dtx", 203.2, 170.18, ["left_rear", 6.35, 33.02], ["right_rear", 163.83, 10.16],
["left_front", 6.35, 165.1], ["right_front", 163.83, 165.1]],
["adapter_mini-itx", 170, 170, ["left_rear", 6.35, 33.02], ["right_rear", 163.83, 10.16],
["left_front", 6.35, 165.1], ["right_front", 163.83, 165.1]],
["adapter_mini-itx_thin", 170, 170, ["left_rear", 6.35, 33.02], ["right_rear", 163.83, 10.16],
["left_front", 6.35, 165.1], ["right_front", 163.83, 165.1]],
["adapter_mini-stx", 140, 147, ["left_rear", 5, 5], ["right_rear", 135, 5],
["left_front", 5, 142], ["right_front", 135, 142]],
["adapter_mini-stx_thin", 140, 147, ["left_rear", 5, 5], ["right_rear", 135, 5],
["left_front", 5, 142], ["right_front", 135, 142]],
];
mb = search([case_design],mb_adapters);
mba_x = mb_adapters[mb[0]][1];
mba_y = mb_adapters[mb[0]][2];
mba_z = floorthick;
mba_offset_x = -8.35;
mba_offset_y = 0;
mba_radius = 5;
mba_standoff = [6.75, floorthick, 4, 7, floorthick, "none", "round", "none", true, false, 0, 0];
io_offset = 6.35;
adj = .01;
difference() {
union() {
difference() {
union() {
translate([mba_offset_x,mba_offset_y,0]) slab([mba_x,mba_y,mba_z], mba_radius);
// additive accessories
if(accessory_name != "none") {
for (i=[1:11:len(accessory_data[a[0]])-1]) {
class = accessory_data[a[0]][i];
type = accessory_data[a[0]][i+1];
loc_x = accessory_data[a[0]][i+2];
loc_y = accessory_data[a[0]][i+3];
loc_z = accessory_data[a[0]][i+4];
face = accessory_data[a[0]][i+5];
rotation = accessory_data[a[0]][i+6];
parametric = accessory_data[a[0]][i+7];
size = accessory_data[a[0]][i+8];
data = accessory_data[a[0]][i+9];
mask = accessory_data[a[0]][i+10];
if(class == "add1" && face == "bottom") {
parametric_move_add(type, loc_x, loc_y, loc_z, face, rotation, parametric, size, data, [false,mask[1],mask[2],mask[3]]);
}
}
}
}
// adapter holes
for (i=[2:len(mb_adapters[mb[0]])-3:len(mb_adapters[mb[0]])-3]) {
for (c=[1:1:len(mb_adapters[mb[0]])-3]) {
mbhole_pos = mb_adapters[mb[0]][i+c][0];
mbhole_x = mb_adapters[mb[0]][i+c][1]+mba_offset_x;
mbhole_y = mb_adapters[mb[0]][i+c][2]+mba_offset_y;
mbhole_z = -floorthick;
translate([mbhole_x,mbhole_y,-1]) cylinder(d=4, h=mba_z+2);
}
}
// pcb standoff holes
if(sbc_bottom_standoffs == true) {
for (i=[1:11:len(sbc_data[s[0]])-2]) {
class = sbc_data[s[0]][i+1];
type = sbc_data[s[0]][i+2];
id = sbc_data[s[0]][i+3];
pcbhole_x = sbc_data[s[0]][i+4]+pcb_loc_x;
pcbhole_y = sbc_data[s[0]][i+5]+pcb_loc_y;
pcbhole_z = sbc_data[s[0]][i+6];
pcbhole_size = sbc_data[s[0]][i+9][0];
pcbhole_pos = sbc_data[s[0]][i+10][4];
if (class == "pcbhole" && id == pcb_id && pcbhole_pos == "left_rear" &&
bottom_rear_left_enable == true && bottom_standoff[6] != "blind") {
translate([pcbhole_x,pcbhole_y,-1]) cylinder(d=bottom_standoff[4]-.2, h=bottom_height);
}
if (class == "pcbhole" && id == pcb_id && pcbhole_pos == "left_front" &&
bottom_front_left_enable == true && bottom_standoff[6] != "blind") {
translate([pcbhole_x,pcbhole_y,-1]) cylinder(d=bottom_standoff[4]-.2, h=bottom_height);
}
if (class == "pcbhole" && id == pcb_id && pcbhole_pos == "right_rear" &&
bottom_rear_right_enable == true && bottom_standoff[6] != "blind") {
translate([pcbhole_x,pcbhole_y,-1]) cylinder(d=bottom_standoff[4]-.2, h=bottom_height);
}
if (class == "pcbhole" && id == pcb_id && pcbhole_pos == "right_front" &&
bottom_front_right_enable == true && bottom_standoff[6] != "blind") {
translate([pcbhole_x,pcbhole_y,-1]) cylinder(d=bottom_standoff[4]-.2, h=bottom_height);
}
}
}
// bottom cover pattern
if(bottom_cover_pattern != "solid") {
if(bottom_cover_pattern == "hex_5mm") {
translate([1,0,-2]) vent_hex(mba_x/3.75,mba_y/6,floorthick+4,5,1.5,"horizontal");
}
if(bottom_cover_pattern == "hex_8mm") {
translate([1,2,-2]) vent_hex(mba_x/5.5,mba_y/9.5,floorthick+4,8,1.5,"horizontal");
}
if(bottom_cover_pattern == "linear_vertical") {
translate([0,-gap,-2]) vent(wallthick,mba_y-2*wallthick-gap,floorthick+4,1,1,(mba_x-2*wallthick-gap)/4,"horizontal");
}
if(bottom_cover_pattern == "linear_horizontal") {
translate([-gap,-gap,-2]) vent(mba_x-2*wallthick-gap,wallthick,floorthick+4,1,(mba_y-2*wallthick-gap)/3,1,"horizontal");
}
if(bottom_cover_pattern == "astroid") {
for(c=[3:12:mba_y-8]) {
for(r=[4:12:mba_x-8]) {
translate([r,c,-4]) linear_extrude(floorthick+5) import("./dxf/astroid_8mm.dxf");
}
}
}
}
// subtractive accessories
if(accessory_name != "none") {
for (i=[1:11:len(accessory_data[a[0]])-1]) {
class = accessory_data[a[0]][i];
type = accessory_data[a[0]][i+1];
loc_x = accessory_data[a[0]][i+2];
loc_y = accessory_data[a[0]][i+3];
loc_z = accessory_data[a[0]][i+4];
face = accessory_data[a[0]][i+5];
rotation = accessory_data[a[0]][i+6];
parametric = accessory_data[a[0]][i+7];
size_x = accessory_data[a[0]][i+8][0];
size_y = accessory_data[a[0]][i+8][1];
size_z = accessory_data[a[0]][i+8][2];
data = accessory_data[a[0]][i+9];
mask = accessory_data[a[0]][i+10];
if ((class == "sub" && face == "bottom") || class == "suball") {
if(accessory_highlight == false) {
parametric_move_sub(type, loc_x, loc_y, loc_z, face, rotation, parametric,
[size_x,size_y,size_z],data, mask);
}
else {
#parametric_move_sub(type,loc_x,loc_y,loc_z,face,rotation,parametric,
[size_x,size_y,size_z],data, mask);
}
}
// create openings for additive
if ((class == "add1" || class == "add2" || class == "model") && mask[0] == true) {
if(accessory_highlight == false) {
parametric_move_add(type,loc_x,loc_y,loc_z,face,rotation,parametric,[size_x,size_y,size_z],data,[true,mask[1],mask[2],mask[3]]);
}
else {
#parametric_move_add(type,loc_x,loc_y,loc_z,face,rotation,parametric,[size_x,size_y,size_z],data,[true,mask[1],mask[2],mask[3]]);
}
}
}
}
// ui access panel
if(bottom_access_panel_enable == true) {
if(access_panel_rotation == 0) {
translate([access_panel_location[0],access_panel_location[1], 0]) rotate([0,0,access_panel_rotation])
access_panel([access_panel_size[0],access_panel_size[1],floorthick], access_panel_orientation, [true,10,2,"default"]);
}
if(access_panel_rotation == 90) {
translate([access_panel_location[0]+access_panel_size[1],access_panel_location[1], 0]) rotate([0,0,access_panel_rotation])
access_panel([access_panel_size[0],access_panel_size[1],floorthick], access_panel_orientation, [true,10,2,"default"]);
}
if(access_panel_rotation == 180) {
translate([access_panel_location[0]+access_panel_size[0],access_panel_location[1]+access_panel_size[1],0]) rotate([0,0,access_panel_rotation])
access_panel([access_panel_size[0],access_panel_size[1],floorthick], access_panel_orientation, [true,10,2,"default"]);
}
if(access_panel_rotation == 270) {
translate([access_panel_location[0],access_panel_location[1]+access_panel_size[0], 0]) rotate([0,0,access_panel_rotation])
access_panel([access_panel_size[0],access_panel_size[1],floorthick], access_panel_orientation, [true,10,2,"default"]);
}
}
}
// adapter standoffs
for (i=[2:len(mb_adapters[mb[0]])-3:len(mb_adapters[mb[0]])-3]) {
for (c=[1:1:len(mb_adapters[mb[0]])-3]) {
mbhole_pos = mb_adapters[mb[0]][i+c][0];
mbhole_x = mb_adapters[mb[0]][i+c][1]+mba_offset_x;
mbhole_y = mb_adapters[mb[0]][i+c][2]+mba_offset_y;
mbhole_z = -floorthick;
translate([mbhole_x,mbhole_y,floorthick]) standoff(mba_standoff,[false,10,2,"default"]);
}
}
// pcb standoffs
if(sbc_bottom_standoffs == true) {
for (i=[1:11:len(sbc_data[s[0]])-2]) {
class = sbc_data[s[0]][i+1];
type = sbc_data[s[0]][i+2];
id = sbc_data[s[0]][i+3];
pcbhole_x = sbc_data[s[0]][i+4]+pcb_loc_x;
pcbhole_y = sbc_data[s[0]][i+5]+pcb_loc_y;
pcbhole_z = sbc_data[s[0]][i+6];
pcbhole_size = sbc_data[s[0]][i+9][0];
pcbhole_pos = sbc_data[s[0]][i+10][4];
if(class == "pcbhole" && id == pcb_id &&
(pcbhole_pos == "left_rear" || pcbhole_pos == "left_front" || pcbhole_pos == "right_rear" || pcbhole_pos == "right_front")) {
if (pcbhole_pos == "left_rear" && bottom_rear_left_enable == true) {
bottom_support = bottom_sidewall_support == true ? bottom_rear_left_support : "none";
pcb_standoff = [bottom_standoff[0],
bottom_standoff[1],
bottom_height-pcb_z+pcb_loc_z+bottom_rear_left_adjust,
bottom_standoff[3],
bottom_standoff[4],
bottom_standoff[5],
bottom_standoff[6],
bottom_standoff[7],
bottom_support,
bottom_standoff[9],
bottom_standoff[10],
bottom_standoff[11],
bottom_standoff[12]];
translate([pcbhole_x,pcbhole_y,0]) standoff(pcb_standoff,[false,10,2,"default"]);
}
if (pcbhole_pos == "left_front" && bottom_front_left_enable == true) {
bottom_support = bottom_sidewall_support == true ? bottom_front_left_support : "none";
pcb_standoff = [bottom_standoff[0],
bottom_standoff[1],
bottom_height-pcb_z+pcb_loc_z+bottom_front_left_adjust,
bottom_standoff[3],
bottom_standoff[4],
bottom_standoff[5],
bottom_standoff[6],
bottom_standoff[7],
bottom_support,
bottom_standoff[9],
bottom_standoff[10],
bottom_standoff[11],
bottom_standoff[12]];
translate([pcbhole_x,pcbhole_y,0]) standoff(pcb_standoff,[false,10,2,"default"]);
}
if (pcbhole_pos == "right_rear" && bottom_rear_right_enable == true) {
bottom_support = bottom_sidewall_support == true ? bottom_rear_right_support : "none";
pcb_standoff = [bottom_standoff[0],
bottom_standoff[1],
bottom_height-pcb_z+pcb_loc_z+bottom_rear_right_adjust,
bottom_standoff[3],
bottom_standoff[4],
bottom_standoff[5],
bottom_standoff[6],
bottom_standoff[7],
bottom_support,
bottom_standoff[9],
bottom_standoff[10],
bottom_standoff[11],
bottom_standoff[12]];
translate([pcbhole_x,pcbhole_y,0]) standoff(pcb_standoff,[false,10,2,"default"]);
}
if (pcbhole_pos == "right_front" && bottom_front_right_enable == true) {
bottom_support = bottom_sidewall_support == true ? bottom_front_right_support : "none";
pcb_standoff = [bottom_standoff[0],
bottom_standoff[1],
bottom_height-pcb_z+pcb_loc_z+bottom_front_right_adjust,
bottom_standoff[3],
bottom_standoff[4],
bottom_standoff[5],
bottom_standoff[6],
bottom_standoff[7],
bottom_support,
bottom_standoff[9],
bottom_standoff[10],
bottom_standoff[11],
bottom_standoff[12]];
translate([pcbhole_x,pcbhole_y,0]) standoff(pcb_standoff,[false,10,2,"default"]);
}
}
}
}
}
translate([mba_offset_x-10, -10, -1]) cube([mba_x+20, 10, floorthick+10]);
}
// additive accessories
if(accessory_name != "none") {
for (i=[1:11:len(accessory_data[a[0]])-1]) {
class = accessory_data[a[0]][i];
type = accessory_data[a[0]][i+1];
loc_x = accessory_data[a[0]][i+2];
loc_y = accessory_data[a[0]][i+3];
loc_z = accessory_data[a[0]][i+4];
face = accessory_data[a[0]][i+5];
rotation = accessory_data[a[0]][i+6];
parametric = accessory_data[a[0]][i+7];
size = accessory_data[a[0]][i+8];
data = accessory_data[a[0]][i+9];
mask = accessory_data[a[0]][i+10];
if(class == "add2" && face == "bottom") {
parametric_move_add(type, loc_x, loc_y, loc_z, face, rotation, parametric, size, data, [false,mask[1],mask[2],mask[3]]);
}
}
}
// ui access port
if(bottom_access_panel_enable == true) {
if(access_panel_rotation == 0) {
translate([access_panel_location[0],access_panel_location[1], 0]) rotate([0,0,access_panel_rotation])
access_panel([access_panel_size[0],access_panel_size[1],floorthick], access_panel_orientation, [false,10,2,"default"]);
}
if(access_panel_rotation == 90) {
translate([access_panel_location[0]+access_panel_size[1],access_panel_location[1], 0]) rotate([0,0,access_panel_rotation])
access_panel([access_panel_size[0],access_panel_size[1],floorthick], access_panel_orientation, [false,10,2,"default"]);
}
if(access_panel_rotation == 180) {
translate([access_panel_location[0]+access_panel_size[0],access_panel_location[1]+access_panel_size[1],0]) rotate([0,0,access_panel_rotation])
access_panel([access_panel_size[0],access_panel_size[1],floorthick], access_panel_orientation, [false,10,2,"default"]);
}
if(access_panel_rotation == 270) {
translate([access_panel_location[0],access_panel_location[1]+access_panel_size[0], 0]) rotate([0,0,access_panel_rotation])
access_panel([access_panel_size[0],access_panel_size[1],floorthick], access_panel_orientation, [false,10,2,"default"]);
}
}
}
/*
NAME: io_shield
DESCRIPTION: creates rear io panel for legacy cases
TODO: none
USAGE: io_shield()
*/
module io_shield() {
io_window_x = case_design == "adapter_mini-stx_thin" || case_design == ("adapter_mini-stx") ? 123.95 : 158.75;
io_window_y = 4;
io_window_z = case_design == "adapter_mini-stx" ? 40 : case_design == "adapter_mini-stx_thin" || case_design == "adapter_mini-itx_thin" ? 25 : 44;
io_offset = case_design == "adapter_mini-stx_thin" || case_design == "adapter_mini-stx" ? 1.2 : 10.79;
difference() {
union() {
translate([-1,io_window_y-1,-1]) cube([io_window_x+2,1,io_window_z+2]);
cube([io_window_x,4,io_window_z]);
}
translate([2,-2,2]) cube([io_window_x-4,5,io_window_z-4]);
translate([io_offset+pcb_loc_x,6+pcb_loc_y,bottom_height-pcb_z+pcb_loc_z+2])
sbc(sbc_model, cooling, fan_size, gpio_opening, uart_opening, true);
// subtractive accessories
if(accessory_name != "none") {
for (i=[1:11:len(accessory_data[a[0]])-1]) {
class = accessory_data[a[0]][i];
type = accessory_data[a[0]][i+1];
loc_x = accessory_data[a[0]][i+2]+io_offset;
loc_y = accessory_data[a[0]][i+3]+io_window_y;
loc_z = accessory_data[a[0]][i+4]+2;
face = accessory_data[a[0]][i+5];
rotation = accessory_data[a[0]][i+6];
parametric = accessory_data[a[0]][i+7];
size_x = accessory_data[a[0]][i+8][0];
size_y = accessory_data[a[0]][i+8][1];
size_z = accessory_data[a[0]][i+8][2];
data = accessory_data[a[0]][i+9];
mask = accessory_data[a[0]][i+10];
if ((class == "sub" && face == "bottom") || class == "suball") {
if(accessory_highlight == false) {
parametric_move_sub(type, loc_x, loc_y, loc_z, face, rotation, parametric,
[size_x,size_y,size_z],data, mask);
}
else {
#parametric_move_sub(type,loc_x,loc_y,loc_z,face,rotation,parametric,
[size_x,size_y,size_z],data, mask);
}
}
// create openings for additive
if ((class == "add1" || class == "add2" || class == "model") && mask[0] == true) {
if(accessory_highlight == false) {
parametric_move_add(type,loc_x,loc_y,loc_z,face,rotation,parametric,[size_x,size_y,size_z],data,[true,mask[1],mask[2],mask[3]]);
}
else {
#parametric_move_add(type,loc_x,loc_y,loc_z,face,rotation,parametric,[size_x,size_y,size_z],data,[true,mask[1],mask[2],mask[3]]);
}
}
}
}
}
}

1053
mod/case_bottom.scad Normal file

File diff suppressed because it is too large Load Diff

292
mod/case_folded.scad Normal file
View File

@@ -0,0 +1,292 @@
/*
This file is part of SBC Case Builder https://github.com/hominoids/SBC_Case_Builder
Copyright 2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
This program 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.
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 this program. If not, see <http://www.gnu.org/licenses/>
Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
NAME: case_folded
DESCRIPTION: creates folded case flat blanks for supported designs
TODO: none
USAGE: case_folded(case_design)
case_design = paper_full-top, paper_split-top
*/
module case_folded(case_design) {
section_position = 2;
ba = bend_allowance;
slit_len = pcb_depth < pcb_width ? pcb_depth/10 : pcb_width/10;
slit_width = material_thickness;
slit_offset = pcb_depth < pcb_width ? pcb_depth/10 : pcb_width/10;
fold_height = pcb_tmaxz+bottom_clearence+pcb_z+ba;
flap_y = 12;
tab_x = pcb_depth/4;
tab_y = fold_height/2;
tab_inset = 6;
if(case_design == "paper_split-top") {
// rear
difference() {
union() {
folded_base(fold_height, ba, flap_y, tab_x, tab_y, tab_inset, slit_len, slit_width, slit_offset);
translate([0, -fold_height-(pcb_depth/2)-ba, 0])
cube([pcb_width, (pcb_depth/2)+ba, material_thickness]);
translate([0, pcb_depth+fold_height, 0])
cube([pcb_width, (pcb_depth/2)+ba, material_thickness]);
// flaps rear left
translate([-tab_y, -fold_height+tab_inset-(pcb_depth/2), 0])
slab_r([tab_y, tab_x, material_thickness], [tab_x/2,tab_x/2,.1,.1]);
// flaps rear right
translate([pcb_width, -fold_height-(pcb_depth/2)+tab_inset, 0])
slab_r([tab_y, tab_x, material_thickness], [.1,.1,tab_x/2,tab_x/2]);
// flaps front left
translate([-tab_y, pcb_depth+fold_height-tab_inset+tab_x, 0])
slab_r([tab_y, tab_x, material_thickness], [tab_x/2,tab_x/2,.1,.1]);
// flaps front right
translate([pcb_width, pcb_depth+fold_height-tab_inset+tab_x, 0])
slab_r([tab_y, tab_x, material_thickness], [.1,.1,tab_x/2,tab_x/2]);
// flaps left rear
difference() {
translate([-(fold_height), 0, 0])
linear_extrude(material_thickness) polygon([[0, 0],
[1, (-pcb_depth/4)],
[(fold_height)-2, (-pcb_depth/4)],
[(fold_height), 0],
[0, 0]]);
translate([-bottom_clearence, 0, section_position]) rotate([90, 0, 270])
sbc(sbc_model, "disable", 0, gpio_opening, uart_opening, true);
}
// flaps left front
difference() {
translate([-(fold_height), pcb_depth, 0])
linear_extrude(material_thickness) polygon([[0, 0],
[1, (pcb_depth/4)],
[(fold_height)-2, (pcb_depth/4)],
[(fold_height), 0],
[0, 0]]);
translate([-bottom_clearence, pcb_depth, pcb_depth+section_position]) rotate([-90, 0, 90])
sbc(sbc_model, "disable", 0, gpio_opening, uart_opening, true);
}
// flaps right rear
difference() {
translate([pcb_width, 0, 0])
linear_extrude(material_thickness) polygon([[0, 0],
[2, (-pcb_depth/4)],
[(fold_height)-1, (-pcb_depth/4)],
[(fold_height), 0],
[0, 0]]);
translate([bottom_clearence+pcb_width, -pcb_width, section_position]) rotate([90, 0, 90])
sbc(sbc_model, "disable", 0, gpio_opening, uart_opening, true);
}
// flaps right front
difference() {
translate([pcb_width, pcb_depth, 0])
linear_extrude(material_thickness) polygon([[0, 0],
[2, (pcb_depth/4)],
[(fold_height)-1, (pcb_depth/4)],
[(fold_height), 0],
[0, 0]]);
translate([bottom_clearence+pcb_width, pcb_width+pcb_depth, section_position+pcb_depth])
rotate([270, 0, 270]) sbc(sbc_model, "disable", 0, gpio_opening, uart_opening, true);
}
}
translate([0, -fold_height, pcb_tmaxz+2+material_thickness]) rotate([180, 0, 0])
sbc(sbc_model, cooling, 0, "disable", "disable", true);
translate([0, 2*pcb_depth+fold_height, pcb_tmaxz+2+material_thickness]) rotate([180, 0, 0])
sbc(sbc_model, cooling, 0, "disable", "disable", true);
}
translate([0, -fold_height-(pcb_depth/2)-ba, 0]) cube([pcb_width, 2, material_thickness]);
translate([0, pcb_depth+fold_height+(pcb_depth/2)-ba, 0]) cube([pcb_width, 2, material_thickness]);
}
if(case_design == "paper_full-top") {
// rear
difference() {
union() {
folded_base(fold_height, ba, flap_y, tab_x, tab_y, tab_inset, slit_len, slit_width, slit_offset);
translate([0, -fold_height-pcb_depth-ba, 0])
cube([pcb_width, pcb_depth+ba, material_thickness]);
translate([0, pcb_depth+fold_height, 0])
cube([pcb_width, (pcb_depth/4)+ba, material_thickness]);
// flaps rear left
translate([tab_inset, -fold_height-pcb_depth-tab_y, 0])
slab_r([tab_x, tab_y, material_thickness], [tab_x/2,.1,.1,tab_x/2]);
// flaps rear right
translate([pcb_width-tab_x-tab_inset, -fold_height-pcb_depth-tab_y, 0])
slab_r([tab_x, tab_y, material_thickness], [tab_x/2,.1,.1,tab_x/2]);
// flaps left rear
difference() {
translate([-(fold_height), 0, 0])
linear_extrude(material_thickness) polygon([[0, 0],
[1, (-pcb_depth/4)],
[(fold_height)-2, (-pcb_depth/4)],
[(fold_height), 0],
[0, 0]]);
translate([-bottom_clearence, 0, section_position]) rotate([90, 0, 270])
sbc(sbc_model, "disable", 0, gpio_opening, uart_opening, true);
}
// flaps left front
difference() {
translate([-(fold_height), pcb_depth, 0])
linear_extrude(material_thickness) polygon([[0, 0],
[1, (pcb_depth/4)],
[(fold_height)-2, (pcb_depth/4)],
[(fold_height), 0],
[0, 0]]);
translate([-bottom_clearence, pcb_depth, pcb_depth+section_position]) rotate([-90, 0, 90])
sbc(sbc_model, "disable", 0, gpio_opening, uart_opening, true);
}
// flaps right rear
difference() {
translate([pcb_width, 0, 0])
linear_extrude(material_thickness) polygon([[0, 0],
[2, (-pcb_depth/4)],
[(fold_height)-1, (-pcb_depth/4)],
[(fold_height), 0],
[0, 0]]);
translate([bottom_clearence+pcb_width, -pcb_width, section_position]) rotate([90, 0, 90])
sbc(sbc_model, "disable", 0, gpio_opening, uart_opening, true);
}
// flaps right front
difference() {
translate([pcb_width, pcb_depth, 0])
linear_extrude(material_thickness) polygon([[0, 0],
[2, (pcb_depth/4)],
[(fold_height)-1, (pcb_depth/4)],
[(fold_height), 0],
[0, 0]]);
translate([bottom_clearence+pcb_width, pcb_width+pcb_depth, section_position+pcb_depth])
rotate([270, 0, 270]) sbc(sbc_model, "disable", 0, gpio_opening, uart_opening, true);
}
}
// top closure tab slits
translate([tab_inset, pcb_depth+fold_height, 0]) cube([tab_x, slit_width, material_thickness+(2*adj)]);
translate([pcb_width-tab_x-tab_inset, pcb_depth+fold_height, 0])
cube([tab_x, slit_width, material_thickness+2*adj]);
translate([0, -fold_height, pcb_tmaxz+2+material_thickness]) rotate([180, 0, 0])
sbc(sbc_model, cooling, 0, "disable", "disable", true);
translate([0, 2*pcb_depth+fold_height, pcb_tmaxz+2+material_thickness]) rotate([180, 0, 0])
sbc(sbc_model, cooling, 0, "disable", "disable", true);
}
}
}
// base folding case
module folded_base(fold_height, ba, flap_y, tab_x, tab_y, tab_inset, slit_len, slit_width, slit_offset) {
section_position = 2;
// rear
difference() {
translate([0, -fold_height, 0]) cube([pcb_width, fold_height, material_thickness]);
// folding slits
translate([slit_offset, -fold_height, -adj])
cube([slit_len, slit_width, material_thickness+(2*adj)]);
translate([pcb_width/2-slit_len/2, -fold_height, -adj])
cube([slit_len, slit_width, material_thickness+(2*adj)]);
translate([pcb_width-slit_offset-slit_len, -fold_height, -adj])
cube([slit_len, slit_width, material_thickness+(2*adj)]);
translate([0, -bottom_clearence, section_position]) rotate([90, 0, 0])
sbc(sbc_model, "disable", 0, gpio_opening, uart_opening, true);
}
// left side
difference() {
union() {
translate([-fold_height, 0, 0])
cube([fold_height, pcb_depth, material_thickness]);
translate([-fold_height-flap_y, 0, 0]) cube([flap_y, pcb_depth, material_thickness]);
}
// folding slits
translate([-fold_height, (pcb_depth/2)+tab_inset, -adj])
cube([slit_width, tab_x, material_thickness+(2*adj)]);
translate([-fold_height, (pcb_depth/2)-tab_x-tab_inset, -adj])
cube([slit_width, tab_x, material_thickness+(2*adj)]);
translate([-bottom_clearence, 0, section_position]) rotate([0, -90, 0])
sbc(sbc_model, "disable", 0, gpio_opening, uart_opening, true);
}
// front
difference() {
translate([0, pcb_depth, 0]) cube([pcb_width, fold_height, material_thickness]);
// folding slits
translate([slit_offset, pcb_depth+fold_height-slit_width, -adj])
cube([slit_len, slit_width, material_thickness+(2*adj)]);
translate([pcb_width/2-slit_len/2, pcb_depth+fold_height-slit_width, -adj])
cube([slit_len, slit_width, material_thickness+(2*adj)]);
translate([pcb_width-slit_offset-slit_len, pcb_depth+fold_height-slit_width, -adj])
cube([slit_len, slit_width, material_thickness+(2*adj)]);
translate([0, pcb_depth+bottom_clearence, pcb_depth+section_position]) rotate([-90, 0, 0])
sbc(sbc_model, "disable", 0, gpio_opening, uart_opening, true);
}
// right side
difference() {
union() {
translate([pcb_width, 0, 0]) cube([fold_height, pcb_depth, material_thickness]);
translate([pcb_width+fold_height, 0, 0])
cube([flap_y, pcb_depth, material_thickness]);
}
// folding slits
translate([pcb_width+fold_height, (pcb_depth/2)+tab_inset, -adj])
cube([slit_width, tab_x, material_thickness+(2*adj)]);
translate([pcb_width+fold_height, (pcb_depth/2)-tab_x-tab_inset, -adj])
cube([slit_width, tab_x, material_thickness+(2*adj)]);
translate([pcb_width+bottom_clearence, 0, pcb_width+section_position]) rotate([0, 90, 0])
sbc(sbc_model, "disable", 0, gpio_opening, uart_opening, true);
}
// pcb section
difference() {
cube([pcb_width, pcb_depth, material_thickness]);
translate([0, 0, 1+material_thickness]) sbc(sbc_model, "disable", 0, gpio_opening, uart_opening, true);
// pcb folding slits rear
translate([slit_offset, 0, -adj]) cube([slit_len, slit_width, material_thickness+(2*adj)]);
translate([pcb_width/2-slit_len/2, 0, -adj]) cube([slit_len, slit_width, material_thickness+(2*adj)]);
translate([pcb_width-slit_offset-slit_len, 0, -adj]) cube([slit_len, slit_width, material_thickness+(2*adj)]);
// pcb folding slits left
translate([0, slit_offset, -adj]) cube([slit_width, slit_len, material_thickness+(2*adj)]);
translate([0, pcb_depth/2-slit_len/2, -adj]) cube([slit_width, slit_len, material_thickness+(2*adj)]);
translate([0, pcb_depth-slit_offset-slit_len, -adj]) cube([slit_width, slit_len, material_thickness+(2*adj)]);
// pcb folding slits front
translate([slit_offset, pcb_depth-slit_width, -adj]) cube([slit_len, slit_width, material_thickness+(2*adj)]);
translate([pcb_width/2-slit_len/2, pcb_depth-slit_width, -adj]) cube([slit_len, slit_width, material_thickness+(2*adj)]);
translate([pcb_width-slit_offset-slit_len, pcb_depth-slit_width, -adj]) cube([slit_len, slit_width, material_thickness+(2*adj)]);
// pcb folding slits right
translate([pcb_width-slit_width, slit_offset, -adj]) cube([slit_width, slit_len, material_thickness+(2*adj)]);
translate([pcb_width-slit_width, pcb_depth/2-slit_len/2, -adj]) cube([slit_width, slit_len, material_thickness+(2*adj)]);
translate([pcb_width-slit_width, pcb_depth-slit_offset-slit_len, -adj]) cube([slit_width, slit_len, material_thickness+(2*adj)]);
}
}

1293
mod/case_rack.scad Normal file

File diff suppressed because it is too large Load Diff

657
mod/case_side.scad Normal file
View File

@@ -0,0 +1,657 @@
/*
This file is part of SBC Case Builder https://github.com/hominoids/SBC_Case_Builder
Copyright 2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
This program 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.
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 this program. If not, see <http://www.gnu.org/licenses/>
Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
NAME: case_side
DESCRIPTION: creates case side for supported designs and styles
TODO: none
USAGE: case_side(case_design, side)
*/
module case_side(case_design, side) {
difference() {
union() {
if(case_design == "panel") {
if(side == "rear") {
difference() {
union() {
translate([-gap,-wallthick-gap,-floorthick])
cube([width-2*wallthick,wallthick,case_z+2*floorthick]);
// right hook
difference() {
translate([width-(2*wallthick)-gap-adj,-wallthick-gap,
((case_z)/2)-4])
cube([(2*wallthick)+.5,wallthick,8]);
translate([width-(2*wallthick)-gap-adj,-wallthick-gap-adj,
((case_z)/2)-4-adj])
cube([wallthick+.25,wallthick+(2*adj),4.25]);
}
// left hook
difference() {
translate([-(2*wallthick)-gap-adj-.25,-wallthick-gap,
((case_z)/2)-4])
cube([(2*wallthick)+.5,wallthick,8]);
translate([-wallthick-gap-adj-.25,-wallthick-gap-adj,
((case_z)/2)-4-adj])
cube([wallthick+.25,wallthick+(2*adj),4.25]);
}
}
// top slots
translate([(width*(1/5))-8.25-(wallthick+gap),-wallthick-gap-adj,
case_z-floorthick-.25])
cube([8.5,wallthick+2*adj,floorthick+.5]);
translate([width-(width*(1/5))-(wallthick+gap)-.25,-wallthick-gap-adj,
case_z-floorthick-.25])
cube([8.5,wallthick+2*adj,floorthick+.5]);
// bottom slots
translate([(width*(1/5))-8.25-(wallthick+gap),-wallthick-gap-adj,-.25])
cube([8.5,wallthick+2*adj,floorthick+.5]);
translate([width-(width*(1/5))-(wallthick+gap)-.25,-wallthick-gap-adj,-.25])
cube([8.5,wallthick+2*adj,floorthick+.5]);
}
}
if(side == "front") {
difference() {
union() {
translate([-gap,depth-2*(wallthick)-gap,-floorthick])
cube([width-2*wallthick,wallthick,case_z+2*floorthick]);
// right hook
difference() {
translate([width-(2*wallthick)-gap-adj,depth-2*(wallthick)-gap-adj,
((case_z)/2)-4])
cube([(2*wallthick)+.5,wallthick,8]);
translate([width-(2*wallthick)-gap-adj,
depth-2*(wallthick)-adj-gap-adj,((case_z)/2)-4-adj])
cube([wallthick+.25,wallthick+(2*adj),4.25]);
}
// left hook
difference() {
translate([-(2*wallthick)-gap-adj-.25,depth-2*(wallthick)-gap-adj,(
(case_z)/2)-4])
cube([(2*wallthick)+.5,wallthick,8]);
translate([-wallthick-gap-adj-.25,depth-2*(wallthick)-adj-gap-adj,
((case_z)/2)-4-adj])
cube([wallthick+.25,wallthick+(2*adj),4.25]);
}
}
// top slots
translate([(width*(1/5))-8.25-(wallthick+gap),depth-2*wallthick-gap-adj,
case_z-floorthick-.25])
cube([8.5,wallthick+2*adj,floorthick+.5]);
translate([width-(width*(1/5))-(wallthick+gap)-.25,depth-2*wallthick-gap-adj,
case_z-floorthick-.25])
cube([8.5,wallthick+2*adj,floorthick+.5]);
// bottom slots
translate([(width*(1/5))-8.25-(wallthick+gap),depth-2*wallthick-gap-adj,-.25])
cube([8.5,wallthick+2*adj,floorthick+.5]);
translate([width-(width*(1/5))-(wallthick+gap)-.25,
depth-2*wallthick-gap-adj,-.25]) cube([8.5,wallthick+2*adj,floorthick+.5]);
}
}
if(side == "right") {
difference() {
translate([width-(2*wallthick)-gap,-(2*wallthick)-gap,-wallthick])
cube([wallthick,depth+2*wallthick,case_z+(2*wallthick)]);
translate([width-(2*wallthick)-gap-adj,-wallthick-gap-.25,
((case_z)/2)]) cube([wallthick+2*adj,wallthick+.5,8.5]);
translate([width-(2*wallthick)-gap-adj,depth-2*(wallthick)-gap-.25,
((case_z)/2)])
cube([wallthick+2*adj,wallthick+.5,8.5]);
}
}
if(side == "left") {
difference() {
translate([-wallthick-gap,-(2*wallthick)-gap,-wallthick])
cube([wallthick,depth+2*wallthick,case_z+(2*wallthick)]);
translate([-wallthick-gap-adj,-wallthick-gap-.25,((case_z)/2)])
cube([wallthick+2*adj,wallthick+.5,8.5]);
translate([-wallthick-gap-adj,depth-2*(wallthick)-gap-.25,
((case_z)/2)])
cube([wallthick+2*adj,wallthick+.5,8.5]);
}
}
}
if(case_design == "panel_nas") {
x_adj = pcb_width > 100 ? width-2*sidethick : 101.6+case_offset_x;
xtab_adj = pcb_width > 100 ? width-gap-2*sidethick-adj : 101.6-gap+case_offset_x-adj;
xvent8_adj = pcb_width > 100 ? width/5.5 : width/6;
if(side == "rear") {
difference() {
union() {
translate([-gap,-(2*wallthick),0])
cube([x_adj,wallthick,case_z-floorthick]);
// bottom right tab
translate([xtab_adj,-(2*wallthick),20])
cube([sidethick+(2*adj),wallthick,10]);
// top right tab
translate([xtab_adj,-(2*wallthick),case_z-30])
cube([sidethick+(2*adj),wallthick,10]);
// bottom left tab
translate([-sidethick-gap-adj,-(2*wallthick),20])
cube([sidethick+(2*adj),wallthick,10]);
// top left tab
translate([-sidethick-gap-adj,-(2*wallthick),case_z-30])
cube([sidethick+(2*adj),wallthick,10]);
if(hd_bays > 3) {
// middle right tab
translate([xtab_adj,-(2*wallthick),(case_z/2)-5])
cube([sidethick+(2*adj),wallthick,10]);
// middle left tab
translate([-sidethick-gap-adj,-(2*wallthick),(case_z/2)-5])
cube([sidethick+(2*adj),wallthick,10]);
}
}
if(rear_fan == 1 || rear_fan == 2) {
if(rear_fan_center == false) {
translate([-1+(101.6-rear_fan_size)/2,-1,rear_fan_position])
rotate([90,0,0]) fan_mask(rear_fan_size, wallthick+2, rear_cooling);
}
if(rear_fan_center == true) {
translate([-1+(101.6-rear_fan_size)/2+(width-2*(sidethick+gap)-101.6)/2,-1,rear_fan_position])
rotate([90,0,0]) fan_mask(rear_fan_size, wallthick+2, rear_cooling);
}
}
if(rear_fan == 2) {
if(rear_fan_center == false) {
translate([-1+(101.6-rear_fan_size)/2,-1,rear_fan_position+rear_dualfan_spacing+rear_fan_size])
rotate([90,0,0]) fan_mask(rear_fan_size, wallthick+2, rear_cooling);
}
if(rear_fan_center == true) {
translate([-1+(101.6-rear_fan_size)/2+(width-2*(sidethick+gap)-101.6)/2,
-1,rear_fan_position+rear_dualfan_spacing+rear_fan_size])
rotate([90,0,0]) fan_mask(rear_fan_size, wallthick+2, rear_cooling);
}
}
}
}
if(side == "front") {
difference() {
union() {
translate([-gap,depth-(4*wallthick),floorthick])
cube([x_adj,wallthick,case_z-3*floorthick]);
// bottom right tab
translate([xtab_adj,depth-(4*wallthick),20])
cube([sidethick+(2*adj),wallthick,10]);
// top right tab
translate([xtab_adj,depth-(4*wallthick),case_z-30])
cube([sidethick+(2*adj),wallthick,10]);
// bottom left tab
translate([-sidethick-gap-adj,depth-(4*wallthick),20])
cube([sidethick+(2*adj),wallthick,10]);
// top left tab
translate([-sidethick-gap-adj,depth-(4*wallthick),case_z-30])
cube([sidethick+(2*adj),wallthick,10]);
if(hd_bays > 3) {
// middle right tab
translate([xtab_adj,depth-(4*wallthick),(case_z/2)-5])
cube([sidethick+(2*adj),wallthick,10]);
// middle left tab
translate([-sidethick-gap-adj,depth-(4*wallthick),(case_z/2)-5])
cube([sidethick+(2*adj),wallthick,10]);
}
}
// front cover pattern
if(front_cover_pattern != "solid" && case_design == "panel_nas") {
xvent_pos = pcb_width <= 100 ? -gap+3 : -gap+6;
if(front_cover_pattern == "hex_5mm" && hd_bays < 6) {
translate([xvent_pos,depth-3*(wallthick)+gap,hd_z_position-5])
vent_hex(round(width/3.85),round(hd_bays*(27.1+hd_space)/5.75),wallthick+4,5,1.5,"vertical");
}
if(front_cover_pattern == "hex_5mm" && hd_bays == 6) {
translate([xvent_pos,depth-3*(wallthick)+gap,hd_z_position])
vent_hex(round(width/3.85),round(hd_bays*(27.1+hd_space)/5.75),wallthick+4,5,1.5,"vertical");
}
if(front_cover_pattern == "hex_8mm") {
translate([-gap+4,depth-3*(wallthick)+gap,hd_z_position])
vent_hex(xvent8_adj,round(hd_bays*(27.1+hd_space)/5.75)-5,floorthick+4,8,1.5,"vertical");
}
if(front_cover_pattern == "linear_vertical") {
translate([-gap+4,depth-3*(wallthick)+gap,hd_z_position])
vent(wallthick,(case_z-2*(wallthick+gap)-20)/8,floorthick+4,1,1,
(width-2*(sidethick+gap))/5.35,"vertical");
translate([-gap+4,depth-3*(wallthick)+gap,case_z-(top_height+bottom_height+4*floorthick)-5])
vent(wallthick,(case_z-2*(wallthick+gap)-20)/8,floorthick+4,1,1,
(width-2*(sidethick+gap))/5.35,"vertical");
}
if(front_cover_pattern == "linear_horizontal") {
translate([wallthick+gap,depth-3*(wallthick)+gap,hd_z_position])
vent(width-2*(wallthick+gap+sidethick)-4,wallthick,floorthick+4,2,
(case_z-2*(wallthick+gap)-20)/20,1,"vertical");
translate([wallthick+gap,depth-3*(wallthick)+gap,
case_z-(top_height+bottom_height+4*floorthick)-20])
vent(width-4*(sidethick+gap),,wallthick,floorthick+4,2,
(case_z-2*(wallthick+gap)-20)/20,1,"vertical");
}
if(front_cover_pattern == "astroid") {
xast_adj = pcb_width <= 100 ? 8 : 6;
for(c=[xast_adj:12:case_z-20]) {
for(r=[8:12:width-8]) {
translate([r,depth-2*wallthick,c]) rotate([90,0,0])
linear_extrude(wallthick+5) import("./dxf/astroid_8mm.dxf");
}
}
}
}
}
}
if(side == "right") {
difference() {
if(case_design == "panel_nas") {
if(pcb_width > 100) {
translate([pcb_width+sidethick+gap+case_offset_x,-(3*wallthick)-gap,-2*wallthick])
rotate([0,-90,0]) slab([case_z+(3*wallthick),depth+2*wallthick,sidethick],corner_fillet);
}
if(pcb_width <= 100) {
translate([101.6-gap+sidethick+case_offset_x,-(3*wallthick)-gap,-2*wallthick])
rotate([0,-90,0]) slab([case_z+(3*wallthick),depth+2*wallthick,sidethick],corner_fillet);
}
}
else {
translate([width-2*sidethick-gap,-(3*wallthick)-gap,-2*wallthick])
rotate([0,-90,0]) slab([case_z+(3*wallthick),depth+2*wallthick,sidethick],corner_fillet);
}
// rear edge top tab openings
translate([width-3*sidethick-gap-adj,-2*wallthick+adj-tol,case_z-30])
cube([2*sidethick+2*adj,wallthick+tol,20+tol]);
translate([width-3*sidethick-gap-adj,-(4*wallthick)+2*adj,case_z-20])
cube([2*sidethick+(2*adj),2*wallthick,10+tol]);
// rear edge bottom tab openings
translate([width-3*sidethick-gap-adj,-2*wallthick+adj-tol,20])
cube([2*sidethick+2*adj,wallthick+tol,20+tol]);
translate([width-3*sidethick-gap-adj,-(4*wallthick)+2*adj,30])
cube([2*sidethick+(2*adj),2*wallthick,10+tol]);
// front edge top tab openings
translate([width-3*sidethick-gap-adj,depth-(4*wallthick),case_z-30])
cube([2*sidethick+(2*adj),wallthick+tol,20+tol]);
translate([width-3*sidethick-gap-adj,depth-(4*wallthick),case_z-20])
cube([2*sidethick+(2*adj),3*wallthick,10+tol]);
// front edge bottom tab openings
translate([width-3*sidethick-gap-adj,depth-(4*wallthick),20])
cube([2*sidethick+(2*adj),wallthick+tol,20+tol]);
translate([width-3*sidethick-gap-adj,depth-(4*wallthick),30])
cube([2*sidethick+(2*adj),3*wallthick,10+tol]);
if(hd_bays > 3) {
// front edge middle tab openings
translate([width-3*sidethick-gap-adj,depth-(4*wallthick),(case_z/2)-5])
cube([2*sidethick+2*adj,wallthick+tol,20+tol]);
translate([width-3*sidethick-gap-adj,depth-(4*wallthick),(case_z/2)-5+10])
cube([2*sidethick+(2*adj),3*wallthick,10+tol]);
// rear edge middle tab openings
translate([width-3*sidethick-gap-adj,-2*wallthick+adj-tol,(case_z/2)-5])
cube([2*sidethick+2*adj,wallthick+tol,20+tol]);
translate([width-3*sidethick-gap-adj,-(4*wallthick),(case_z/2)-5+10])
cube([2*sidethick+(2*adj),3*wallthick,10+tol]);
}
// hd holes for bays
if(hd_reverse == false) {
for( i=[0:1:hd_bays-1]) {
translate([(width-101.6)-(4*sidethick)-gap+adj,
-(3*wallthick)-gap+hd_y_position,hd_z_position+(hd_space+27.1)*i])
hd_holes(3.5, "portrait", "both", 4*sidethick+2);
}
}
else {
for( i=[0:1:hd_bays-1]) {
translate([width-(4*sidethick)-adj,-(3*wallthick)-gap+hd_y_position+147,
hd_z_position+(hd_space+27.1)*i])
rotate([0,0,180]) hd_holes(3.5, "portrait", "both", 4*sidethick+2);
}
}
// top edge front tab opening
translate([width-3*sidethick-gap-adj,depth-(3*wallthick)-gap-adj-30-tol,
case_z-(2*floorthick)])
cube([2*sidethick+(2*adj),20+tol,floorthick+tol]);
translate([width-3*sidethick-gap-adj,depth-(3*wallthick)-gap-adj-30-tol,
case_z-(2*floorthick)])
cube([2*sidethick+(2*adj),10+tol,(3*floorthick)+adj]);
// top edge rear tab opening
translate([width-3*sidethick-gap-adj,40-wallthick-gap-adj-tol,
case_z-(2*floorthick)])
cube([2*sidethick+(2*adj),10+tol,floorthick+tol]);
translate([width-3*sidethick-gap-adj,30-wallthick-gap+adj-tol,
case_z-(2*floorthick)])
cube([2*sidethick+(2*adj),10+tol,(3*floorthick)+adj]);
// bottom edge front tab opening
translate([width-3*sidethick-gap-adj,depth-(3*wallthick)-gap-adj-30-tol,-tol])
cube([2*sidethick+2*adj,20+tol,floorthick+tol]);
translate([width-3*sidethick-gap-adj,depth-(3*wallthick)-gap-adj-30-tol,-(3*floorthick)+adj])
cube([2*sidethick+2*adj,10+tol,(3*floorthick)+adj]);
// bottom edge rear tab opening
translate([width-3*sidethick-gap-adj,30-wallthick-gap+adj-tol,-tol])
cube([2*sidethick+2*adj,20+tol,floorthick+tol]);
translate([width-3*sidethick-gap-adj,30-wallthick-gap+adj-tol,-(3*floorthick)+adj])
cube([2*sidethick+(2*adj),10+tol,(3*floorthick)+adj]);
}
}
if(side == "left") {
difference() {
translate([-gap,-(3*wallthick)-gap,-2*wallthick])
rotate([0,-90,0]) slab([case_z+(3*wallthick),depth+(2*wallthick),sidethick],corner_fillet);
// rear edge top tab openings
translate([-sidethick-gap-adj,-2*wallthick+adj-tol,case_z-30])
cube([sidethick+2*adj,wallthick+tol,20]);
translate([-sidethick-gap-adj,-(4*wallthick)+tol,case_z-20])
cube([sidethick+(2*adj),3*wallthick+adj,10+tol]);
// rear edge bottom tab openings
translate([-sidethick-gap-adj,-2*wallthick+adj-tol,20])
cube([sidethick+2*adj,wallthick+tol,20]);
translate([-sidethick-gap-adj,-(4*wallthick)+tol,30])
cube([sidethick+(2*adj),3*wallthick,10+tol]);
// front edge top tab openings
translate([-sidethick-gap-adj,depth-(4*wallthick),case_z-30])
cube([sidethick+(2*adj),wallthick+tol,20]);
translate([-sidethick-gap-adj,depth-(4*wallthick),case_z-20])
cube([sidethick+(2*adj),3*wallthick,10+tol]);
// front edge bottom tab openings
translate([-sidethick-gap-adj,depth-(4*wallthick),20])
cube([sidethick+(2*adj),wallthick+tol,20]);
translate([-sidethick-gap-adj,depth-(4*wallthick),30])
cube([sidethick+(2*adj),3*wallthick,10+tol]);
if(hd_bays > 3) {
// rear edge middle tab openings
translate([-sidethick-gap-adj,-2*wallthick+adj-tol,(case_z/2)-5])
cube([sidethick+2*adj,wallthick+tol,20]);
translate([-sidethick-gap-adj,-(4*wallthick)+tol,(case_z/2)-5+10])
cube([sidethick+(2*adj),3*wallthick,10+tol]);
// front edge middle tab openings
translate([-sidethick-gap-adj,depth-(4*wallthick),(case_z/2)-5])
cube([sidethick+2*adj,wallthick+tol,20]);
translate([-sidethick-gap-adj,depth-(4*wallthick),(case_z/2)-5+10])
cube([sidethick+(2*adj),3*wallthick,10+tol]);
}
// hd holes for bays
if(hd_reverse == false) {
for( i=[0:1:hd_bays-1]) {
translate([-gap+adj,-(3*wallthick)-gap+hd_y_position,hd_z_position+(hd_space+27.1)*i])
hd_holes(3.5, "portrait", "both", sidethick+2);
}
}
else {
for( i=[0:1:hd_bays-1]) {
translate([101.6-gap+adj,-(3*wallthick)-gap+hd_y_position+147,
hd_z_position+(hd_space+27.1)*i])
rotate([0,0,180]) hd_holes(3.5, "portrait", "both", sidethick+2);
}
}
// top edge front tab openings
translate([-gap-sidethick-adj,depth-(3*wallthick)-gap-adj-30,
case_z-(2*floorthick)])
cube([sidethick+(2*adj),20,floorthick+tol]);
translate([-gap-sidethick-adj,depth-(3*wallthick)-gap-adj-30-tol,
case_z-(2*floorthick)])
cube([sidethick+(2*adj),10+tol,(3*floorthick)+adj]);
// top edge rear tab openings
translate([-gap-sidethick-adj,30-wallthick-gap+adj,
case_z-(2*floorthick)])
cube([sidethick+(2*adj),20,floorthick+tol]);
translate([-gap-sidethick-adj,30-wallthick-gap+adj-tol,
case_z-(2*floorthick)])
cube([sidethick+(2*adj),10+tol,(3*floorthick)+adj]);
// bottom edge front tab openings
translate([-gap-sidethick-adj,depth-(3*wallthick)-gap-adj-30,-tol])
cube([sidethick+(2*adj),20,floorthick+tol]);
translate([-gap-sidethick-adj,depth-(3*wallthick)-gap-adj-30-tol,-(2*floorthick)-adj])
cube([sidethick+(2*adj),10+tol,(3*floorthick)+adj]);
// bottom edge rear tab openings
translate([-gap-sidethick-adj,30-wallthick-gap+adj,-tol])
cube([sidethick+(2*adj),20,floorthick+tol]);
translate([-gap-sidethick-adj,30-wallthick-gap+adj-tol,-(2*floorthick)-adj])
cube([sidethick+(2*adj),10+tol,(3*floorthick)+adj]);
}
}
}
if(case_design == "tray_sides") {
if(side == "right") {
difference() {
union() {
translate([width-wallthick-gap,-(2*wallthick)-gap,0])
cube([sidethick,depth+2*wallthick,case_z+(2*wallthick)]);
translate([width-gap-wallthick-1+adj,depth-2*(wallthick+gap)-.5,case_z+(2*wallthick)-2])
cube([1,6,2]);
translate([width-gap-wallthick-1+adj,-2*(wallthick+gap)+1.5,case_z+(2*wallthick)-2])
cube([1,6,2]);
// top rail
translate([width-6.9-adj,-gap,case_z-floorthick-.5])
cube([4,depth-2*(wallthick+gap),2]);
}
// right side bottom attachment holes
translate([width-2*(wallthick+gap)-sidethick-adj,wallthick+gap+10,
((bottom_height+floorthick)/2)-1]) rotate([0,90,0]) cylinder(d=3, h=10+sidethick+(2*adj));
if(depth >= 75) {
translate([width-2*(wallthick+gap)-sidethick-adj,depth-wallthick-gap-10,
((bottom_height+floorthick)/2)-1]) rotate([0,90,0])
cylinder(d=3, h=10+sidethick+(2*adj));
}
else {
translate([width-2*(wallthick+gap)-sidethick-adj,wallthick+gap+40,
((bottom_height+floorthick)/2)-1]) rotate([0,90,0])
cylinder(d=3, h=10+sidethick+(2*adj));
}
}
}
if(side == "left") {
difference() {
union() {
translate([-wallthick-gap-sidethick,-(2*wallthick)-gap,0])
cube([sidethick,depth+2*wallthick,case_z+(2*wallthick)]);
translate([-gap-wallthick-adj,depth-2*(wallthick+gap)-.5,case_z+(2*wallthick)-2])
cube([1,6,2]);
translate([-gap-wallthick-adj,-2*(wallthick+gap)+1.5,case_z+(2*wallthick)-2])
cube([1,6,2]);
// top rail
translate([-wallthick-gap-adj,-gap,case_z-floorthick-.5])
cube([4,depth-2*(wallthick+gap),2]);
}
// left side bottom attachment holes
translate([-wallthick-gap-adj-5,wallthick+gap+10,
((bottom_height+floorthick)/2)-1]) rotate([0,90,0]) cylinder(d=3, h=10+sidethick+(2*adj));
if(depth >= 75) {
translate([-wallthick-gap-adj-6,depth-wallthick-gap-10,
((bottom_height+floorthick)/2)-1]) rotate([0,90,0])
cylinder(d=3, h=10+sidethick+(2*adj));
}
else {
translate([-wallthick-gap-adj-6,wallthick+gap+40,
((bottom_height+floorthick)/2)-1]) rotate([0,90,0])
cylinder(d=3, h=10+sidethick+(2*adj));
}
}
}
}
if(case_design == "tray_vu5") {
cheight = case_z+90;
vesa = 75;
vu_holder("vu5",side,vesa,cheight);
}
if(case_design == "tray_vu7") {
cheight = case_z+122;
vesa = 100;
vu_holder("vu7",side,vesa,cheight);
}
// additive accessories
if(accessory_name != "none") {
for (i=[1:11:len(accessory_data[a[0]])-1]) {
class = accessory_data[a[0]][i];
type = accessory_data[a[0]][i+1];
loc_x = accessory_data[a[0]][i+2];
loc_y = accessory_data[a[0]][i+3];
loc_z = accessory_data[a[0]][i+4];
face = accessory_data[a[0]][i+5];
rotation = accessory_data[a[0]][i+6];
parametric = accessory_data[a[0]][i+7];
size = accessory_data[a[0]][i+8];
data = accessory_data[a[0]][i+9];
mask = accessory_data[a[0]][i+10];
if (class == "add1" && face == side) {
parametric_move_add(type,loc_x,loc_y,loc_z,face,rotation,parametric,size,data,[false,mask[1],mask[2],mask[3]]);
}
}
}
}
// subtractive accessories
if(accessory_name != "none") {
for (i=[1:11:len(accessory_data[a[0]])-1]) {
class = accessory_data[a[0]][i];
type = accessory_data[a[0]][i+1];
loc_x = accessory_data[a[0]][i+2];
loc_y = accessory_data[a[0]][i+3];
loc_z = accessory_data[a[0]][i+4];
face = accessory_data[a[0]][i+5];
rotation = accessory_data[a[0]][i+6];
parametric = accessory_data[a[0]][i+7];
size_x = accessory_data[a[0]][i+8][0];
size_y = accessory_data[a[0]][i+8][1];
size_z = accessory_data[a[0]][i+8][2];
data = accessory_data[a[0]][i+9];
mask = accessory_data[a[0]][i+10];
if ((class == "sub" && face == side) || class == "suball") {
if(accessory_highlight == false) {
parametric_move_sub(type,loc_x,loc_y,loc_z,face,rotation,parametric,
[size_x,size_y,size_z],data,mask);
}
else {
#parametric_move_sub(type,loc_x,loc_y,loc_z,face,rotation,parametric,
[size_x,size_y,size_z],data,mask);
}
}
// create openings for additive
if((class == "add1" || class == "add2" || class == "model") && mask[0] == true) {
if(accessory_highlight == false) {
parametric_move_add(type,loc_x,loc_y,loc_z,face,rotation,parametric,[size_x,size_y,size_z],data,mask);
}
else {
#parametric_move_add(type,loc_x,loc_y,loc_z,face,rotation,parametric,[size_x,size_y,size_z],data,mask);
}
}
}
}
// sbc openings
if(case_design != "panel_nas") {
if(sbc_highlight == true) {
#translate([pcb_loc_x ,pcb_loc_y,bottom_height-pcb_z+pcb_loc_z-adj-adj])
sbc(sbc_model, cooling, fan_size, gpio_opening, uart_opening, true);
}
else {
translate([pcb_loc_x ,pcb_loc_y,bottom_height-pcb_z+pcb_loc_z-adj-adj])
sbc(sbc_model, cooling, fan_size, gpio_opening, uart_opening, true);
}
}
else {
if(nas_sbc_location == "top") {
if(sbc_highlight == true) {
#translate([pcb_loc_x ,pcb_loc_y,case_z-(top_height+pcb_loc_z+(2*floorthick))])
sbc(sbc_model, cooling, fan_size, gpio_opening, uart_opening, true);
}
else {
translate([pcb_loc_x ,pcb_loc_y,case_z-(top_height+pcb_loc_z+(2*floorthick))])
sbc(sbc_model, cooling, fan_size, gpio_opening, uart_opening, true);
}
}
if(nas_sbc_location == "bottom") {
if(sbc_highlight == true) {
#translate([pcb_loc_x ,pcb_loc_y,bottom_height-pcb_z+pcb_loc_z])
sbc(sbc_model, cooling, fan_size, gpio_opening, uart_opening, true);
}
else {
translate([pcb_loc_x ,pcb_loc_y,bottom_height-pcb_z+pcb_loc_z])
sbc(sbc_model, cooling, fan_size, gpio_opening, uart_opening, true);
}
}
}
// indents
if(indents == true) {
for (i=[1:11:len(sbc_data[s[0]])-2]) {
class = sbc_data[s[0]][i+1];
type = sbc_data[s[0]][i+2];
pcbid = sbc_data[s[0]][i+3];
pcbloc_x = sbc_data[s[0]][i+4];
pcbloc_y = sbc_data[s[0]][i+5];
pcbloc_z = sbc_data[s[0]][i+6];
if(class == "pcb") {
for (i=[1:11:len(sbc_data[s[0]])-2]) {
class = sbc_data[s[0]][i+1];
type = sbc_data[s[0]][i+2];
id = sbc_data[s[0]][i+3];
loc_x = sbc_data[s[0]][i+4]+pcb_loc_x+pcbloc_x;
loc_y = sbc_data[s[0]][i+5]+pcb_loc_y+pcbloc_y;
loc_z = sbc_data[s[0]][i+6]+pcb_loc_z+pcbloc_z;
side = sbc_data[s[0]][i+7];
rotation = sbc_data[s[0]][i+8];
if(id == pcbid && case_design != "panel_nas") {
indent(loc_x, loc_y, bottom_height+loc_z-adj, rotation[2], side, class, type, wallthick, gap, floorthick, pcb_z);
}
if(id == pcbid && case_design == "panel_nas" && nas_sbc_location == "bottom") {
indent(loc_x, loc_y, bottom_height+loc_z-adj, rotation[2], side, class,
type, 2*wallthick, gap, floorthick, pcb_z);
}
if(id == pcbid && case_design == "panel_nas" && nas_sbc_location == "top") {
indent(loc_x, loc_y, case_z-(top_height+pcb_loc_z+(2*floorthick))+.5, rotation[2],
side, class, type, 2*wallthick, gap, floorthick, pcb_z);
}
}
}
}
}
}
if(accessory_name != "none") {
for (i=[1:11:len(accessory_data[a[0]])-1]) {
class = accessory_data[a[0]][i];
type = accessory_data[a[0]][i+1];
loc_x = accessory_data[a[0]][i+2];
loc_y = accessory_data[a[0]][i+3];
loc_z = accessory_data[a[0]][i+4];
face = accessory_data[a[0]][i+5];
rotation = accessory_data[a[0]][i+6];
parametric = accessory_data[a[0]][i+7];
size = accessory_data[a[0]][i+8];
data = accessory_data[a[0]][i+9];
mask = accessory_data[a[0]][i+10];
if (class == "add2" && face == side) {
parametric_move_add(type,loc_x,loc_y,loc_z,face,rotation,parametric,size,data,[false,mask[1],mask[2],mask[3]]);
}
}
}
}

972
mod/case_top.scad Normal file
View File

@@ -0,0 +1,972 @@
/*
This file is part of SBC Case Builder https://github.com/hominoids/SBC_Case_Builder
Copyright 2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
This program 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.
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 this program. If not, see <http://www.gnu.org/licenses/>
Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
NAME: case_top
DESCRIPTION: creates case top for supported designs
TODO: none
USAGE: case_top(case_design)
*/
module case_top(case_design) {
lip = 5;
vu_rotation = [15,0,0];
case_fn = 360; // circle segments for round cases
case_ffn = 90; // circle segments for fillet of round cases
adj = .01;
difference() {
union() {
difference() {
union() {
if(case_design == "shell") {
difference() {
translate([(width/2)-wallthick-gap,
(depth/2)-wallthick-gap,bottom_height+(top_height/2)])
cube_fillet_inside([width,depth,top_height],
vertical=[corner_fillet,corner_fillet,corner_fillet,corner_fillet],
top=[edge_fillet,edge_fillet,edge_fillet,edge_fillet,edge_fillet],
bottom=[0,0,0,0], $fn=90);
translate([(width/2)-wallthick-gap,(depth/2)-wallthick-gap,
bottom_height+(top_height/2)-floorthick])
cube_fillet_inside([width-(wallthick*2),depth-(wallthick*2),top_height],
vertical=[corner_fillet-wallthick,corner_fillet-wallthick,corner_fillet-wallthick,corner_fillet-wallthick],
top=[edge_fillet,edge_fillet,edge_fillet,edge_fillet,edge_fillet],
bottom=[0,0,0,0], $fn=90);
}
}
if(case_design == "panel") {
union() {
translate([-gap,-gap,case_z-floorthick])
cube([width-(2*wallthick),depth-(2*wallthick),floorthick]);
translate([(width*(1/5))-8-(wallthick+gap),depth-(2*wallthick)-gap-adj,
case_z-floorthick])
cube([8,wallthick+2*adj,floorthick]);
translate([width-(width*(1/5))-(wallthick+gap),depth-(2*wallthick)-gap-adj,
case_z-floorthick])
cube([8,wallthick+2*adj,floorthick]);
translate([(width*(1/5))-8-(wallthick+gap),-wallthick-gap+adj,
case_z-floorthick])
cube([8,wallthick+2*adj,floorthick]);
translate([width-(width*(1/5))-(wallthick+gap),-wallthick-gap+adj,
case_z-floorthick])
cube([8,wallthick+2*adj,floorthick]);
}
}
if(case_design == "panel_nas") {
x_adj = pcb_width > 100 ? width-2*sidethick : 101.6+case_offset_x;
xtab_adj = pcb_width > 100 ? width-gap-2*sidethick-adj : 101.6-gap+case_offset_x-adj;
union() {
translate([-gap,-wallthick,case_z-2*floorthick])
cube([x_adj,depth-(2*wallthick),floorthick]);
translate([-gap-sidethick+(2*adj),depth-(3*wallthick)-gap-adj-20,
case_z-2*floorthick])
cube([sidethick+(2*adj),10,floorthick]);
translate([xtab_adj,depth-(3*wallthick)-gap-adj-20,
case_z-2*floorthick])
cube([sidethick+2*adj,10,floorthick]);
translate([-gap-sidethick+(2*adj),40-wallthick-gap+adj,
case_z-2*floorthick])
cube([sidethick+2*adj,10,floorthick]);
translate([xtab_adj,40-wallthick-gap+adj,
case_z-2*floorthick])
cube([sidethick+2*adj,10,floorthick]);
}
}
if(case_design == "stacked") {
translate([(width/2)-wallthick-gap,(depth/2)-wallthick-gap,
case_z-(floorthick/2)])
cube_fillet_inside([width-(2*wallthick),depth-(2*wallthick),floorthick],
vertical=[corner_fillet,corner_fillet,corner_fillet,corner_fillet],
top=[0,0,0,0], bottom=[0,0,0,0], $fn=90);
}
if(case_design == "tray_vu5" || case_design == "tray_vu7" || case_design == "tray_sides") {
translate([-wallthick-gap+.5,-wallthick-gap,case_z])
cube([width-1,depth,floorthick]);
translate([-wallthick-gap+.5,-wallthick-gap,
case_z-floorthick+adj]) cube([width-1,wallthick,wallthick]);
}
if(case_design == "tray") {
difference() {
translate([(width/2)-wallthick-gap,(depth/2)-wallthick-gap,case_z/2])
cube_fillet_inside([width+2*wallthick+1,depth,case_z],
vertical=[0,0,0,0], top=[0,edge_fillet,0,edge_fillet,edge_fillet],
bottom=[0,0,0,0], $fn=90);
translate([(width/2)-wallthick-gap,(depth/2)-wallthick-gap,(case_z/2)-floorthick+.25])
cube_fillet_inside([width+1,depth+(wallthick*2),case_z],
vertical=[corner_fillet-wallthick,corner_fillet-wallthick,corner_fillet-wallthick,
corner_fillet-wallthick],top=[0,0,0,0],bottom=[0,0,0,0], $fn=90);
for (i=[1:11:len(sbc_data[s[0]])-2]) {
class = sbc_data[s[0]][i+1];
type = sbc_data[s[0]][i+2];
id = sbc_data[s[0]][i+3];
pcbhole_x = sbc_data[s[0]][i+4]+pcb_loc_x;
pcbhole_y = sbc_data[s[0]][i+5]+pcb_loc_y;
pcbhole_z = sbc_data[s[0]][i+6];
pcbhole_size = sbc_data[s[0]][i+9][0];
pcbhole_pos = sbc_data[s[0]][i+10][4];
if(class == "pcbhole" && id == pcb_id && pcbhole_pos == "left_rear") {
if((pcbhole_y <= 10 && pcbhole_x <= 10) || (ext_top_standoffs == true &&
ext_top_rear_left_enable == true)) {
translate([-wallthick-gap-adj-6,wallthick+gap+10,floorthick+3.4]) rotate([0,90,0])
cylinder(d=3, h=10+sidethick+(2*adj));
}
else {
translate([-wallthick-gap-adj-6,wallthick+gap+2,floorthick+3.4]) rotate([0,90,0])
cylinder(d=3, h=10+sidethick+(2*adj));
}
}
if(class == "pcbhole" && id == pcb_id && pcbhole_pos == "left_front") {
if((pcbhole_y >= pcb_depth+case_offset_y-10 && pcbhole_x <= 10) ||
(ext_top_standoffs == true && ext_top_front_left_enable == true)) {
translate([-wallthick-gap-adj-6,wallthick-gap+pcb_depth+case_offset_y-14,
floorthick+3.4]) rotate([0,90,0]) cylinder(d=3, h=10+sidethick+(2*adj));
}
else {
translate([-wallthick-gap-adj-6,wallthick+gap+pcb_depth+case_offset_y-8,
floorthick+3.4]) rotate([0,90,0]) cylinder(d=3, h=10+sidethick+(2*adj));
}
}
if(class == "pcbhole" && id == pcb_id && pcbhole_pos == "right_rear") {
if((pcbhole_y <= 10 && pcbhole_x >= pcb_width-10) || (ext_top_standoffs == true &&
ext_top_rear_right_enable == true)) {
translate([width-2*(wallthick+gap)-sidethick-adj,wallthick+gap+10,floorthick+3.4])
rotate([0,90,0]) cylinder(d=3, h=10+sidethick+(2*adj));
}
else {
translate([width-2*(wallthick+gap)-sidethick-adj,wallthick+gap+2,floorthick+3.4])
rotate([0,90,0]) cylinder(d=3, h=10+sidethick+(2*adj));
}
}
if(class == "pcbhole" && id == pcb_id && pcbhole_pos == "right_front") {
if((pcbhole_y >= pcb_depth+case_offset_y-10 && pcbhole_x >= width-10) ||
(ext_bottom_standoffs == true && ext_bottom_front_right_enable == true)) {
translate([width-3*(wallthick+gap)-adj,wallthick-gap+pcb_depth+case_offset_y-14,
floorthick+3.4]) rotate([0,90,0]) cylinder(d=3, h=10+sidethick+(2*adj));
}
else {
translate([width-3*(wallthick+gap)-adj,wallthick-gap+pcb_depth+case_offset_y-8,
floorthick+3.4]) rotate([0,90,0]) cylinder(d=3, h=10+sidethick+(2*adj));
}
}
}
}
}
if(case_design == "round") {
difference() {
translate([pcb_width/2,pcb_depth/2,bottom_height+(top_height/2)-lip/2]) rotate([0,0,30])
cylinder_fillet_inside(h=top_height+lip, r=case_diameter/2,
top=edge_fillet, bottom=0, $fn=case_fn, fillet_fn=case_ffn, center=true);
translate([pcb_width/2,pcb_depth/2,bottom_height+(top_height/2)-floorthick-lip/2]) rotate([0,0,30])
cylinder_fillet_inside(h=top_height+lip, r=(case_diameter/2)-wallthick,
top=edge_fillet-1, bottom=0, $fn=case_fn, fillet_fn=case_ffn, center=true);
translate([pcb_width/2,pcb_depth/2,bottom_height-adj-lip/2]) rotate([0,0,30])
cylinder_fillet_inside(h=lip+2*adj, r=(case_diameter/2)-wallthick/2+tol/2,
top=edge_fillet-1, bottom=0, $fn=case_fn, fillet_fn=case_ffn, center=true);
// io cutout
if(width/depth >= 1.4 && sbc_model != "vim1" && sbc_model != "vim2" &&
sbc_model != "vim3l" && sbc_model != "vim3" && sbc_model != "vim4" &&
sbc_model != "rpizero" && sbc_model != "rpizero2w") {
translate([width,(depth/2)-wallthick-gap,bottom_height-lip+top_height/2-floorthick])
cube_fillet_inside([18,depth-2*(wallthick+gap)-1,top_height+lip+2],
vertical=[0,0,0,0], top=[0,0,0,0], bottom=[0,0,0,0], $fn=90);
}
else {
translate([(width/2)-wallthick-gap,-20,bottom_height-lip+top_height/2-floorthick])
cube_fillet_inside([width-2*(wallthick+gap)-1,40,top_height+lip+2],
vertical=[0,0,0,0], top=[0,0,0,0], bottom=[0,0,0,0], $fn=90);
}
}
if(width/depth >= 1.4 && sbc_model != "vim1" && sbc_model != "vim2" &&
sbc_model != "vim3l" && sbc_model != "vim3" && sbc_model != "vim4" &&
sbc_model != "rpizero" && sbc_model != "rpizero2w") {
translate([width-2*wallthick-gap-.95,depth/2-wallthick-gap-(depth-2*(floorthick+gap))/2,
bottom_height]) cube([wallthick-adj,depth-2*(floorthick+gap),top_height+adj]);
}
else {
translate([-.95,depth/2-2*wallthick-gap-(depth-2*(floorthick+gap))/2,
bottom_height]) cube([width-2*(floorthick+gap),wallthick-adj,top_height+adj]);
}
}
if(case_design == "hex") {
if(width/depth >= 1.4 && sbc_model != "vim1" && sbc_model != "vim2" &&
sbc_model != "vim3l" && sbc_model != "vim3" && sbc_model != "vim4" &&
sbc_model != "rpizero" && sbc_model != "rpizero2w") {
difference() {
translate([pcb_width/2,pcb_depth/2,bottom_height+(top_height/2)-lip/2]) rotate([0,0,30])
cylinder_fillet_inside(h=top_height+lip, r=case_diameter/2,
top=edge_fillet, bottom=0, $fn=6, fillet_fn=case_ffn, center=true);
translate([pcb_width/2,pcb_depth/2,bottom_height+(top_height/2)-floorthick-lip/2]) rotate([0,0,30])
cylinder_fillet_inside(h=top_height+lip, r=(case_diameter/2)-wallthick,
top=edge_fillet-1, bottom=0, $fn=6, fillet_fn=case_ffn, center=true);
translate([pcb_width/2,pcb_depth/2,bottom_height-adj-lip/2]) rotate([0,0,30])
cylinder_fillet_inside(h=lip+2*adj, r=(case_diameter/2)-wallthick/2+tol/2,
top=edge_fillet-1, bottom=0, $fn=6, fillet_fn=case_ffn, center=true);
// io cutout
translate([width,(depth/2)-wallthick-gap,bottom_height-lip+top_height/2-floorthick])
cube_fillet_inside([18,depth-2*(wallthick+gap)-1,top_height+lip+2],
vertical=[0,0,0,0], top=[0,0,0,0], bottom=[0,0,0,0], $fn=90);
}
}
else {
difference() {
translate([pcb_width/2,pcb_depth/2,bottom_height+(top_height/2)-lip/2])
cylinder_fillet_inside(h=top_height+lip, r=hex_diameter/2,
top=edge_fillet, bottom=0, $fn=6, fillet_fn=case_ffn, center=true);
translate([pcb_width/2,pcb_depth/2,bottom_height+(top_height/2)-floorthick-lip/2])
cylinder_fillet_inside(h=top_height+lip, r=(hex_diameter/2)-wallthick,
top=edge_fillet-1, bottom=0, $fn=6, fillet_fn=case_ffn, center=true);
translate([pcb_width/2,pcb_depth/2,bottom_height-adj-lip/2])
cylinder_fillet_inside(h=lip+2*adj, r=(hex_diameter/2)-wallthick/2+tol/2,
top=edge_fillet-1, bottom=0, $fn=6, fillet_fn=case_ffn, center=true);
// io cutout
translate([(width/2)-wallthick-gap,-23,bottom_height-lip+top_height/2-floorthick])
cube_fillet_inside([width-2*(wallthick+gap),40,top_height+lip+2],
vertical=[0,0,0,0], top=[0,0,0,0], bottom=[0,0,0,0], $fn=90);
}
}
if(width/depth >= 1.4 && sbc_model != "vim1" && sbc_model != "vim2" &&
sbc_model != "vim3l" && sbc_model != "vim3" && sbc_model != "vim4" &&
sbc_model != "rpizero" && sbc_model != "rpizero2w") {
translate([width-2*wallthick-gap-.95,depth/2-wallthick-gap-(depth-2*(floorthick+gap))/2,
bottom_height]) cube([wallthick-adj,depth-2*(floorthick+gap),top_height+adj]);
}
else {
translate([0,depth/2-2.25*(wallthick+gap)-(depth-2*(floorthick+gap))/2,
bottom_height]) cube([width-2*(floorthick+gap),wallthick-adj,top_height+adj]);
}
}
if(case_design == "snap") {
translate([(width/2)-wallthick-gap,(depth/2)-wallthick-gap,floorthick*1.5+case_z])
cube_fillet_inside([width,depth,floorthick],
vertical=[corner_fillet,corner_fillet,corner_fillet,corner_fillet],
top=[0,0,0,0],bottom=[edge_fillet,edge_fillet,edge_fillet,edge_fillet,edge_fillet], $fn=90);
difference() {
translate([(width/2)-wallthick-gap,(depth/2)-wallthick-gap,case_z-adj])
cube_fillet_inside([width-2*wallthick-tol,depth-2*wallthick-tol,2*floorthick+1.5],
vertical=[corner_fillet,corner_fillet,corner_fillet,corner_fillet],
top=[0,0,0,0],bottom=[edge_fillet,edge_fillet,edge_fillet,edge_fillet,edge_fillet], $fn=90);
translate([(width/2)-wallthick-gap,(depth/2)-wallthick-gap,case_z-adj])
cube_fillet_inside([width-(3*wallthick),depth-(3*wallthick),2*floorthick+1.5+adj],
vertical=[corner_fillet-wallthick,corner_fillet-wallthick,corner_fillet-wallthick,
corner_fillet-wallthick],top=[0,0,0,0],
bottom=[edge_fillet,edge_fillet,edge_fillet,edge_fillet,edge_fillet], $fn=90);
}
// snap top outdent
difference() {
translate([-wallthick-gap+1.25+tol,(depth/2)-((depth*.75)/2)+2.5-gap-wallthick,case_z-.5])
rotate([0,45,0]) cube([4,(depth*.75)-5,4]);
translate([-wallthick-gap+3,(depth/2)-((depth*.75)/2)+1.25-gap-wallthick,case_z+floorthick-5.75])
cube([6,(depth*.75)-2,6]);
}
difference() {
translate([width-wallthick-gap-6.8-tol,(depth/2)-((depth*.75)/2)+2.5-gap-wallthick,case_z-.5])
rotate([0,45,0]) cube([4,(depth*.75)-5,4]);
translate([width-wallthick-gap-8.5,(depth/2)-((depth*.75)/2)+1.25-gap-wallthick,
case_z+floorthick-5.75]) cube([6,(depth*.75)-2,6]);
}
}
if(case_design == "fitted") {
difference() {
translate([(width/2)-wallthick-gap,
(depth/2)-wallthick-gap,case_z+floorthick/2-(lip)/2])
cube_fillet_inside([width,depth,lip+floorthick],
vertical=[corner_fillet,corner_fillet,corner_fillet,corner_fillet],
top=[edge_fillet,edge_fillet,edge_fillet,edge_fillet,edge_fillet],
bottom=[0,0,0,0], $fn=90);
translate([(width/2)-wallthick-gap,(depth/2)-wallthick-gap,case_z-floorthick-1])
cube_fillet_inside([width-wallthick+tol,depth-wallthick+tol,lip+floorthick],
vertical=[corner_fillet-wallthick,corner_fillet-wallthick,corner_fillet-wallthick,corner_fillet-wallthick],
top=[edge_fillet,edge_fillet,edge_fillet,edge_fillet,edge_fillet],
bottom=[0,0,0,0], $fn=90);
}
}
if(accessory_name != "none") {
for (i=[1:11:len(accessory_data[a[0]])-1]) {
class = accessory_data[a[0]][i];
type = accessory_data[a[0]][i+1];
loc_x = accessory_data[a[0]][i+2];
loc_y = accessory_data[a[0]][i+3];
loc_z = accessory_data[a[0]][i+4];
face = accessory_data[a[0]][i+5];
rotation = accessory_data[a[0]][i+6];
parametric = accessory_data[a[0]][i+7];
size = accessory_data[a[0]][i+8];
data = accessory_data[a[0]][i+9];
mask = accessory_data[a[0]][i+10];
if (class == "add1" && face == "top") {
parametric_move_add(type,loc_x,loc_y,loc_z,face,rotation,parametric,size,data,[false,mask[1],mask[2],mask[3]]);
}
}
}
}
// pcb standoff holes
if(sbc_top_standoffs == true) {
for (i=[1:11:len(sbc_data[s[0]])-2]) {
class = sbc_data[s[0]][i+1];
type = sbc_data[s[0]][i+2];
id = sbc_data[s[0]][i+3];
pcbhole_x = sbc_data[s[0]][i+4]+pcb_loc_x;
pcbhole_y = sbc_data[s[0]][i+5]+pcb_loc_y;
pcbhole_z = sbc_data[s[0]][i+6];
pcbhole_size = sbc_data[s[0]][i+9][0];
pcbhole_pos = sbc_data[s[0]][i+10][4];
case_z = case_design == "fitted" || case_design == "tray_sides" ||
case_design == "tray_vu5" || case_design == "tray_vu7" ? case_z+floorthick :
case_design == "snap" ? case_z+(2 * floorthick) :
case_design == "panel_nas" ? case_z-floorthick : case_z;
if (class == "pcbhole" && id == 0 && pcbhole_pos == "left_rear" &&
top_rear_left_enable == true && top_standoff[6] != "blind") {
translate([pcbhole_x,pcbhole_y,case_z-(floorthick+adj)])
cylinder(d=top_standoff[4]-.2, h=floorthick+(2*adj));
}
if (class == "pcbhole" && id == 0 && pcbhole_pos == "left_front" &&
top_front_left_enable == true && top_standoff[6] != "blind") {
translate([pcbhole_x,pcbhole_y,case_z-(floorthick+adj)])
cylinder(d=top_standoff[4]-.2, h=floorthick+(2*adj));
}
if (class == "pcbhole" && id == 0 && pcbhole_pos == "right_rear" &&
top_rear_right_enable == true && top_standoff[6] != "blind") {
translate([pcbhole_x,pcbhole_y,case_z-(floorthick+adj)])
cylinder(d=top_standoff[4]-.2, h=floorthick+(2*adj));
}
if (class == "pcbhole" && id == 0 && pcbhole_pos == "right_front" &&
top_front_right_enable == true && top_standoff[6] != "blind") {
translate([pcbhole_x,pcbhole_y,case_z-(floorthick+adj)])
cylinder(d=top_standoff[4]-.2, h=floorthick+(2*adj));
}
}
}
// multi-pcb standoff holes
if(multipcb_top_standoffs == true) {
for (i=[1:11:len(sbc_data[s[0]])-2]) {
class = sbc_data[s[0]][i+1];
type = sbc_data[s[0]][i+2];
pcbid = sbc_data[s[0]][i+3];
pcbloc_x = sbc_data[s[0]][i+4];
pcbloc_y = sbc_data[s[0]][i+5];
pcbloc_z = sbc_data[s[0]][i+6];
if(class == "pcb") {
for (i=[1:11:len(sbc_data[s[0]])-2]) {
pcbclass = sbc_data[s[0]][i+1];
pcbtype = sbc_data[s[0]][i+2];
id = sbc_data[s[0]][i+3];
pcbhole_x = sbc_data[s[0]][i+4]+pcb_loc_x+pcbloc_x;
pcbhole_y = sbc_data[s[0]][i+5]+pcb_loc_y+pcbloc_y;
pcbhole_z = sbc_data[s[0]][i+6];
pcbhole_size = sbc_data[s[0]][i+9][0];
pcbhole_state = sbc_data[s[0]][i+10][0];
pcbhole_pos = sbc_data[s[0]][i+10][4];
case_z = case_design == "fitted" || case_design == "tray_sides" ||
case_design == "tray_vu5" || case_design == "tray_vu7" ? case_z+floorthick :
case_design == "snap" ? case_z+(2 * floorthick) :
case_design == "panel_nas" ? case_z-floorthick : case_z;
if(id == pcbid && id != 0 && pcbclass == "pcbhole") {
if (pcbclass == "pcbhole" && pcbhole_pos == "left_rear" &&
multipcb_top_rear_left_enable == true &&
(pcbhole_state == "top" || pcbhole_state == "both")) {
translate([pcbhole_x,pcbhole_y,case_z-(floorthick+adj)])
cylinder(d=multipcb_top_standoff[4]-.2, h=floorthick+(2*adj));
}
if (pcbclass == "pcbhole" && pcbhole_pos == "left_front" &&
multipcb_top_front_left_enable == true &&
(pcbhole_state == "top" || pcbhole_state == "both")) {
translate([pcbhole_x,pcbhole_y,case_z-(floorthick+adj)])
cylinder(d=multipcb_top_standoff[4]-.2, h=floorthick+(2*adj));
}
if (pcbclass == "pcbhole" && pcbhole_pos == "right_rear" &&
multipcb_top_rear_right_enable == true &&
(pcbhole_state == "top" || pcbhole_state == "both")) {
translate([pcbhole_x,pcbhole_y,case_z-(floorthick+adj)])
cylinder(d=multipcb_top_standoff[4]-.2, h=floorthick+(2*adj));
}
if (pcbclass == "pcbhole" && pcbhole_pos == "right_front" &&
multipcb_top_front_right_enable == true &&
(pcbhole_state == "top" || pcbhole_state == "both")) {
translate([pcbhole_x,pcbhole_y,case_z-(floorthick+adj)])
cylinder(d=multipcb_top_standoff[4]-.2, h=floorthick+(2*adj));
}
}
}
}
}
}
// extended standoff holes
if(ext_top_standoffs == true) {
case_z = case_design == "fitted" || case_design == "tray_sides" ||
case_design == "tray_vu5" || case_design == "tray_vu7" ? case_z+floorthick :
case_design == "snap" ? case_z+(2 * floorthick) :
case_design == "panel_nas" ? case_z-floorthick : case_z;
// right-rear standoff
if((width-pcb_loc_x-pcb_width-(gap+2*wallthick) >= ext_top_standoff_support_size ||
pcb_loc_y >= ext_top_standoff_support_size) &&
ext_top_rear_right_enable == true && ext_top_standoff[6] != "blind") {
translate([width-ext_top_standoff_support_size/4-(2*(wallthick+gap)),
ext_top_standoff_support_size/4,case_z-(floorthick+adj)])
cylinder(d=ext_top_standoff[4]-.2, h=floorthick+(2*adj));
}
// right-front standoff
if(((width-pcb_loc_x-pcb_width-(gap+2*wallthick) >= ext_top_standoff_support_size &&
depth-pcb_loc_y-pcb_depth >= ext_top_standoff_support_size) ||
(width-pcb_loc_x-pcb_width-(gap+2*wallthick) >= ext_top_standoff_support_size &&
depth-pcb_loc_y-pcb_depth <= ext_top_standoff_support_size) ||
(width-pcb_loc_x-pcb_width-(gap+2*wallthick) <= ext_top_standoff_support_size &&
depth-pcb_loc_y-pcb_depth >= ext_top_standoff_support_size)) &&
ext_top_front_right_enable == true && ext_top_standoff[6] != "blind") {
translate([width-ext_top_standoff_support_size/4-(2*(wallthick+gap)),
depth-ext_top_standoff_support_size/4-(2*(wallthick+gap)),case_z-(floorthick+adj)])
cylinder(d=ext_top_standoff[4]-.2, h=floorthick+(2*adj));
}
// left-rear standoff
if((pcb_loc_x >= ext_top_standoff_support_size || pcb_loc_y >= ext_top_standoff_support_size) &&
ext_top_rear_left_enable == true && ext_top_standoff[6] != "blind") {
translate([ext_top_standoff_support_size/4, ext_top_standoff_support_size/4,case_z-(floorthick+adj)])
cylinder(d=ext_top_standoff[4]-.2, h=floorthick+(2*adj));
}
// left-front standoff
if(((pcb_loc_x >= ext_top_standoff_support_size &&
(depth-(pcb_loc_y+pcb_depth)) >= ext_top_standoff_support_size) ||
(pcb_loc_x <= ext_top_standoff_support_size &&
(depth-(pcb_loc_y+pcb_depth)) >= ext_top_standoff_support_size) ||
(pcb_loc_x >= ext_top_standoff_support_size &&
(depth-(pcb_loc_y+pcb_depth)) <= ext_top_standoff_support_size)) &&
ext_top_front_left_enable == true && ext_top_standoff[6] != "blind") {
translate([ext_top_standoff_support_size/4,
depth-ext_top_standoff_support_size/4-(2*(wallthick+gap)),case_z-(floorthick+adj)])
cylinder(d=ext_top_standoff[4]-.2, h=floorthick+(2*adj));
}
}
// top cover pattern
if(top_cover_pattern != "solid") {
xvent8_adj = pcb_width > 100 ? width/5.5 : width/6;
if(top_cover_pattern == "hex_5mm") {
if(case_design == "panel_nas") {
translate([6,5,case_z-(2*floorthick)])
vent_hex((width-10)/3.75,(depth-10)/7,floorthick+4,5,1.5,"horizontal");
}
else {
translate([1,0,case_z-(2*floorthick)]) vent_hex(width/3.75,depth/6,floorthick+4,5,1.5,"horizontal");
}
}
if(top_cover_pattern == "hex_8mm") {
if(case_design == "panel_nas") {
translate([-gap+5,6,case_z-(2*floorthick)]) vent_hex(xvent8_adj,depth/9.5,floorthick+4,8,1.5,"horizontal");
}
else {
translate([1,2,case_z-(2*floorthick)]) vent_hex(width/5.5,depth/9.5,floorthick+4,8,1.5,"horizontal");
}
}
if(top_cover_pattern == "linear_vertical") {
if(case_design == "panel_nas") {
translate([wallthick+gap,wallthick,case_z-(2*floorthick)])
vent(wallthick,depth-6*wallthick-gap,floorthick+4,1,1,(width-2*(sidethick+gap))/5.35,"horizontal");
}
else {
translate([0,-gap,case_z-(2*floorthick)])
vent(wallthick,depth-2*wallthick-gap,floorthick+4,1,1,(width-2*wallthick-gap)/4,"horizontal");
}
}
if(top_cover_pattern == "linear_horizontal") {
if(case_design == "panel_nas") {
translate([wallthick+gap,wallthick,case_z-(2*floorthick)])
vent(width-4*(sidethick+gap),wallthick,floorthick+4,1,
(depth-2*(wallthick-gap))/4.35,1,"horizontal");
}
else {
translate([-gap,-gap,case_z-(2*floorthick)])
vent(width-2*wallthick-gap,wallthick,floorthick+4,1,(depth-2*wallthick-gap)/3,1,"horizontal");
}
}
if(top_cover_pattern == "astroid") {
xast_adj = pcb_width <= 100 ? 8 : 6;
if(case_design == "panel_nas") {
for(c=[xast_adj:12:depth-16]) {
for(r=[8:12:width-16]) {
translate([r,c,case_z-(2*floorthick)-adj])
linear_extrude(floorthick+5) import("./dxf/astroid_8mm.dxf");
}
}
}
else {
for(c=[3:12:depth-8]) {
for(r=[4:12:width-8]) {
translate([r,c,case_z-(2*floorthick)-adj])
linear_extrude(floorthick+5) import("./dxf/astroid_8mm.dxf");
}
}
}
}
}
// rear io shield opening for standard form motherboards
if(rear_io_shield == true) {
if(sbc_model == "mini-stx_thin") {
translate([6.2+pcb_loc_x,-4.5,-4.15+bottom_height-pcb_z+pcb_loc_z]) cube([123.95, 10+pcb_loc_y, 25]);
}
if(sbc_model == "mini-stx") {
translate([6.2+pcb_loc_x,-4.5,-4.15+bottom_height-pcb_z+pcb_loc_z]) cube([123.95, 10+pcb_loc_y, 40]);
}
if(sbc_model == "mini-itx_thin") {
translate([-2.62+pcb_loc_x,-4.5,-1.75+bottom_height-pcb_z+pcb_loc_z]) cube([158.75, 10+pcb_loc_y, 25]);
}
if(sbc_model != "mini-stx_thin" && sbc_model != "mini-stx" && sbc_model != "mini-itx_thin") {
translate([-2.62+pcb_loc_x,-4.5,-1.75+bottom_height-pcb_z+pcb_loc_z]) cube([158.75, 10+pcb_loc_y, 44]);
}
}
}
// pcb standoffs
if(sbc_top_standoffs == true) {
for (i=[1:11:len(sbc_data[s[0]])-2]) {
class = sbc_data[s[0]][i+1];
type = sbc_data[s[0]][i+2];
id = sbc_data[s[0]][i+3];
pcbhole_x = sbc_data[s[0]][i+4]+pcb_loc_x;
pcbhole_y = sbc_data[s[0]][i+5]+pcb_loc_y;
pcbhole_z = sbc_data[s[0]][i+6];
pcbhole_size = sbc_data[s[0]][i+9][0];
pcbhole_pos = sbc_data[s[0]][i+10][4];
case_z = case_design == "fitted" || case_design == "tray_sides" ||
case_design == "tray_vu5" || case_design == "tray_vu7" ? case_z+floorthick :
case_design == "snap" ? case_z+(2 * floorthick) :
case_design == "panel_nas" ? case_z-floorthick : case_z;
stand_off_adj = case_design == "fitted" || case_design == "tray_sides" ||
case_design == "tray_vu5" || case_design == "tray_vu7" ? floorthick :
case_design == "snap" ? 2 * floorthick : 0;
if(class == "pcbhole" && id == pcb_id &&
(pcbhole_pos == "left_rear" || pcbhole_pos == "left_front" ||
pcbhole_pos == "right_rear" || pcbhole_pos == "right_front")) {
if (pcbhole_pos == "left_rear" && top_rear_left_enable == true) {
top_support = top_sidewall_support == true ? top_rear_left_support : "none";
pcb_standoff = [top_standoff[0],
top_standoff[1],
top_height+top_rear_left_adjust-pcb_loc_z+stand_off_adj,
top_standoff[3],
top_standoff[4],
top_standoff[5],
top_standoff[6],
top_standoff[7],
top_support,
top_standoff[9],
top_standoff[10],
top_standoff[11],
top_standoff[12]];
translate([pcbhole_x,pcbhole_y,case_z]) standoff(pcb_standoff,[false,10,2,"default"]);
}
if (pcbhole_pos == "left_front" && top_front_left_enable == true) {
top_support = top_sidewall_support == true ? top_front_left_support : "none";
pcb_standoff = [top_standoff[0],
top_standoff[1],
top_height+top_front_left_adjust-pcb_loc_z+stand_off_adj,
top_standoff[3],
top_standoff[4],
top_standoff[5],
top_standoff[6],
top_standoff[7],
top_support,
top_standoff[9],
top_standoff[10],
top_standoff[11],
top_standoff[12]];
translate([pcbhole_x,pcbhole_y,case_z]) standoff(pcb_standoff,[false,10,2,"default"]);
}
if (pcbhole_pos == "right_rear" && top_rear_right_enable == true) {
top_support = top_sidewall_support == true ? top_rear_right_support : "none";
pcb_standoff = [top_standoff[0],
top_standoff[1],
top_height+top_rear_right_adjust-pcb_loc_z+stand_off_adj,
top_standoff[3],
top_standoff[4],
top_standoff[5],
top_standoff[6],
top_standoff[7],
top_support,
top_standoff[9],
top_standoff[10],
top_standoff[11],
top_standoff[12]];
translate([pcbhole_x,pcbhole_y,case_z]) standoff(pcb_standoff,[false,10,2,"default"]);
}
if (pcbhole_pos == "right_front" && top_front_right_enable == true) {
top_support = top_sidewall_support == true ? top_front_right_support : "none";
pcb_standoff = [top_standoff[0],
top_standoff[1],
top_height+top_front_right_adjust-pcb_loc_z+stand_off_adj,
top_standoff[3],
top_standoff[4],
top_standoff[5],
top_standoff[6],
top_standoff[7],
top_support,
top_standoff[9],
top_standoff[10],
top_standoff[11],
top_standoff[12]];
translate([pcbhole_x,pcbhole_y,case_z]) standoff(pcb_standoff,[false,10,2,"default"]);
}
}
}
}
// multi-pcb standoffs
if(multipcb_top_standoffs == true) {
for (i=[1:11:len(sbc_data[s[0]])-2]) {
class = sbc_data[s[0]][i+1];
type = sbc_data[s[0]][i+2];
pcbid = sbc_data[s[0]][i+3];
pcbloc_x = sbc_data[s[0]][i+4];
pcbloc_y = sbc_data[s[0]][i+5];
pcbloc_z = sbc_data[s[0]][i+6];
if(class == "pcb") {
for (i=[1:11:len(sbc_data[s[0]])-2]) {
pcbclass = sbc_data[s[0]][i+1];
pcbtype = sbc_data[s[0]][i+2];
id = sbc_data[s[0]][i+3];
pcbhole_x = sbc_data[s[0]][i+4]+pcb_loc_x+pcbloc_x;
pcbhole_y = sbc_data[s[0]][i+5]+pcb_loc_y+pcbloc_y;
pcbhole_z = sbc_data[s[0]][i+6];
pcbhole_size = sbc_data[s[0]][i+9][0];
pcbhole_state = sbc_data[s[0]][i+10][0];
pcbhole_pos = sbc_data[s[0]][i+10][4];
case_z = case_design == "fitted" || case_design == "tray_sides" ||
case_design == "tray_vu5" || case_design == "tray_vu7" ? case_z+floorthick :
case_design == "snap" ? case_z+(2 * floorthick) :
case_design == "panel_nas" ? case_z-floorthick : case_z;
stand_off_adj = case_design == "fitted" || case_design == "tray_sides" ||
case_design == "tray_vu5" || case_design == "tray_vu7" ? floorthick :
case_design == "snap" ? 2 * floorthick : 0;
if(pcbclass == "pcbhole" && pcbid == id && id != 0) {
if (pcbhole_pos == "left_rear" && multipcb_top_rear_left_enable == true &&
(pcbhole_state == "top" || pcbhole_state == "both")) {
top_support = multipcb_top_sidewall_support == true ? multipcb_top_rear_left_support : "none";
pcb_standoff = [multipcb_top_standoff[0],
multipcb_top_standoff[1],
top_height+top_rear_right_adjust-pcb_loc_z+stand_off_adj,
multipcb_top_standoff[3],
multipcb_top_standoff[4],
multipcb_top_standoff[5],
multipcb_top_standoff[6],
multipcb_top_standoff[7],
top_support,
multipcb_top_standoff[9],
multipcb_top_standoff[10],
multipcb_top_standoff[11],
multipcb_top_standoff[12]];
translate([pcbhole_x,pcbhole_y,case_z]) standoff(pcb_standoff,[false,10,2,"default"]);
}
if (pcbhole_pos == "left_front" && multipcb_top_front_left_enable == true &&
(pcbhole_state == "top" || pcbhole_state == "both")) {
top_support = multipcb_top_sidewall_support == true ? multipcb_top_front_left_support : "none";
pcb_standoff = [multipcb_top_standoff[0],
multipcb_top_standoff[1],
top_height+top_rear_right_adjust-pcb_loc_z+stand_off_adj,
multipcb_top_standoff[3],
multipcb_top_standoff[4],
multipcb_top_standoff[5],
multipcb_top_standoff[6],
multipcb_top_standoff[7],
top_support,
multipcb_top_standoff[9],
multipcb_top_standoff[10],
multipcb_top_standoff[11],
multipcb_top_standoff[12]];
translate([pcbhole_x,pcbhole_y,case_z]) standoff(pcb_standoff,[false,10,2,"default"]);
}
if (pcbhole_pos == "right_rear" && multipcb_top_rear_right_enable == true &&
(pcbhole_state == "top" || pcbhole_state == "both")) {
top_support = multipcb_top_sidewall_support == true ? multipcb_top_rear_right_support : "none";
pcb_standoff = [multipcb_top_standoff[0],
multipcb_top_standoff[1],
top_height+top_rear_right_adjust-pcb_loc_z+stand_off_adj,
multipcb_top_standoff[3],
multipcb_top_standoff[4],
multipcb_top_standoff[5],
multipcb_top_standoff[6],
multipcb_top_standoff[7],
top_support,
multipcb_top_standoff[9],
multipcb_top_standoff[10],
multipcb_top_standoff[11],
multipcb_top_standoff[12]];
translate([pcbhole_x,pcbhole_y,case_z]) standoff(pcb_standoff,[false,10,2,"default"]);
}
if (pcbhole_pos == "right_front" && multipcb_top_front_right_enable == true &&
(pcbhole_state == "top" || pcbhole_state == "both")) {
top_support = multipcb_top_sidewall_support == true ? multipcb_top_front_right_support : "none";
pcb_standoff = [multipcb_top_standoff[0],
multipcb_top_standoff[1],
top_height+top_rear_right_adjust-pcb_loc_z+stand_off_adj,
multipcb_top_standoff[3],
multipcb_top_standoff[4],
multipcb_top_standoff[5],
multipcb_top_standoff[6],
multipcb_top_standoff[7],
top_support,
multipcb_top_standoff[9],
multipcb_top_standoff[10],
multipcb_top_standoff[11],
multipcb_top_standoff[12]];
translate([pcbhole_x,pcbhole_y,case_z]) standoff(pcb_standoff,[false,10,2,"default"]);
}
}
}
}
}
}
// extended standoffs
if(ext_top_standoffs == true) {
case_z = case_design == "fitted" || case_design == "tray_sides" ||
case_design == "tray_vu5" || case_design == "tray_vu7" ? case_z+floorthick :
case_design == "snap" ? case_z+(2 * floorthick) :
case_design == "panel_nas" ? case_z-floorthick : case_z;
stand_off_adj = case_design == "fitted" || case_design == "tray_sides" ||
case_design == "tray_vu5" || case_design == "tray_vu7" ? floorthick :
case_design == "snap" ? 2 * floorthick : 0;
// extended right-rear standoff
if((width-pcb_loc_x-pcb_width-(gap+2*wallthick) >= ext_top_standoff_support_size ||
pcb_loc_y >= ext_top_standoff_support_size) && ext_top_rear_right_enable == true) {
extended_standoff = [ext_top_standoff[0],
ext_top_standoff[1],
top_height+ext_top_rear_right_adjust+stand_off_adj,
ext_top_standoff[3],
ext_top_standoff[4],
ext_top_standoff[5],
ext_top_standoff[6],
ext_top_standoff[7],
ext_top_rear_right_support,
ext_top_standoff[9],
ext_top_standoff[10],
ext_top_standoff[11],
ext_top_standoff[12]];
translate([width-ext_top_standoff_support_size/4-(2*(wallthick+gap)),
ext_top_standoff_support_size/4,case_z]) standoff(extended_standoff,[false,10,2,"default"]);
}
// extended right-front standoff
if(((width-pcb_loc_x-pcb_width-(gap+2*wallthick) >= ext_top_standoff_support_size &&
depth-pcb_loc_y-pcb_depth >= ext_top_standoff_support_size) ||
(width-pcb_loc_x-pcb_width-(gap+2*wallthick) >= ext_top_standoff_support_size &&
depth-pcb_loc_y-pcb_depth <= ext_top_standoff_support_size) ||
(width-pcb_loc_x-pcb_width-(gap+2*wallthick) <= ext_top_standoff_support_size &&
depth-pcb_loc_y-pcb_depth >= ext_top_standoff_support_size)) &&
ext_top_front_right_enable == true) {
extended_standoff = [ext_top_standoff[0],
ext_top_standoff[1],
top_height+ext_top_front_right_adjust+stand_off_adj,
ext_top_standoff[3],
ext_top_standoff[4],
ext_top_standoff[5],
ext_top_standoff[6],
ext_top_standoff[7],
ext_top_front_right_support,
ext_top_standoff[9],
ext_top_standoff[10],
ext_top_standoff[11],
ext_top_standoff[12]];
translate([width-ext_top_standoff_support_size/4-(2*(wallthick+gap)),
depth-ext_top_standoff_support_size/4-(2*(wallthick+gap)),case_z])
standoff(extended_standoff,[false,10,2,"default"]);
}
// extended left-rear standoff
if((pcb_loc_x >= ext_top_standoff_support_size || pcb_loc_y >= ext_top_standoff_support_size) &&
ext_top_rear_left_enable == true) {
extended_standoff = [ext_top_standoff[0],
ext_top_standoff[1],
top_height+ext_top_rear_left_adjust+stand_off_adj,
ext_top_standoff[3],
ext_top_standoff[4],
ext_top_standoff[5],
ext_top_standoff[6],
ext_top_standoff[7],
ext_top_rear_left_support,
ext_top_standoff[9],
ext_top_standoff[10],
ext_top_standoff[11],
ext_top_standoff[12]];
translate([ext_top_standoff_support_size/4,
ext_top_standoff_support_size/4,case_z]) standoff(extended_standoff,[false,10,2,"default"]);
}
// extended left-front standoff
if(((pcb_loc_x >= ext_top_standoff_support_size &&
(depth-(pcb_loc_y+pcb_depth)) >= ext_top_standoff_support_size) ||
(pcb_loc_x <= ext_top_standoff_support_size &&
(depth-(pcb_loc_y+pcb_depth)) >= ext_top_standoff_support_size) ||
(pcb_loc_x >= ext_top_standoff_support_size &&
depth-(pcb_loc_y+pcb_depth) <= ext_top_standoff_support_size)) &&
ext_top_front_left_enable == true) {
extended_standoff = [ext_top_standoff[0],
ext_top_standoff[1],
top_height+ext_top_front_left_adjust+stand_off_adj,
ext_top_standoff[3],
ext_top_standoff[4],
ext_top_standoff[5],
ext_top_standoff[6],
ext_top_standoff[7],
ext_top_front_left_support,
ext_top_standoff[9],
ext_top_standoff[10],
ext_top_standoff[11],
ext_top_standoff[12]];
translate([ext_top_standoff_support_size/4,
depth-ext_top_standoff_support_size/4-(2*(wallthick+gap)), case_z])
standoff(extended_standoff,[false,10,2,"default"]);
}
}
}
// subtractive accessories
if(accessory_name != "none") {
for (i=[1:11:len(accessory_data[a[0]])-1]) {
class = accessory_data[a[0]][i];
type = accessory_data[a[0]][i+1];
loc_x = accessory_data[a[0]][i+2];
loc_y = accessory_data[a[0]][i+3];
loc_z = accessory_data[a[0]][i+4];
face = accessory_data[a[0]][i+5];
rotation = accessory_data[a[0]][i+6];
parametric = accessory_data[a[0]][i+7];
size_x = accessory_data[a[0]][i+8][0];
size_y = accessory_data[a[0]][i+8][1];
size_z = accessory_data[a[0]][i+8][2];
data = accessory_data[a[0]][i+9];
mask = accessory_data[a[0]][i+10];
if ((class == "sub" && face == "top") || class == "suball") {
if(accessory_highlight == false) {
parametric_move_sub(type,loc_x,loc_y,loc_z,face,rotation,
parametric,[size_x,size_y,size_z],data,mask);
}
else {
#parametric_move_sub(type,loc_x,loc_y,loc_z,face,rotation,
parametric,[size_x,size_y,size_z],data,mask);
}
}
// create openings for additive
if((class == "add1" || class == "add2" || class == "model") && mask[0] == true) {
if(accessory_highlight == false) {
parametric_move_add(type,loc_x,loc_y,loc_z,face,rotation,
parametric,[size_x,size_y,size_z],data,mask);
}
else {
#parametric_move_add(type,loc_x,loc_y,loc_z,face,rotation,
parametric,[size_x,size_y,size_z],data,mask);
}
}
}
}
// sbc openings
if(case_design != "panel_nas") {
if(sbc_highlight == true) {
#translate([pcb_loc_x ,pcb_loc_y,bottom_height-pcb_z+pcb_loc_z-adj])
sbc(sbc_model, cooling, fan_size, gpio_opening, uart_opening, true);
}
else {
translate([pcb_loc_x ,pcb_loc_y,bottom_height-pcb_z+pcb_loc_z-adj])
sbc(sbc_model, cooling, fan_size, gpio_opening, uart_opening, true);
}
}
else {
if(nas_sbc_location == "top") {
if(sbc_highlight == true) {
#translate([pcb_loc_x ,pcb_loc_y,case_z-(top_height+pcb_loc_z+(2*floorthick))])
sbc(sbc_model, cooling, fan_size, gpio_opening, uart_opening, true);
}
else {
translate([pcb_loc_x ,pcb_loc_y,case_z-(top_height+pcb_loc_z+(2*floorthick))])
sbc(sbc_model, cooling, fan_size, gpio_opening, uart_opening, true);
}
}
if(nas_sbc_location == "bottom") {
if(sbc_highlight == true) {
#translate([pcb_loc_x ,pcb_loc_y,bottom_height-pcb_z+pcb_loc_z])
sbc(sbc_model, cooling, fan_size, gpio_opening, uart_opening, true);
}
else {
translate([pcb_loc_x ,pcb_loc_y,bottom_height-pcb_z+pcb_loc_z])
sbc(sbc_model, cooling, fan_size, gpio_opening, uart_opening, true);
}
}
}
// indents
if(indents == true) {
for (i=[1:11:len(sbc_data[s[0]])-2]) {
class = sbc_data[s[0]][i+1];
type = sbc_data[s[0]][i+2];
pcbid = sbc_data[s[0]][i+3];
pcbloc_x = sbc_data[s[0]][i+4];
pcbloc_y = sbc_data[s[0]][i+5];
pcbloc_z = sbc_data[s[0]][i+6];
if(class == "pcb") {
for (i=[1:11:len(sbc_data[s[0]])-2]) {
class = sbc_data[s[0]][i+1];
type = sbc_data[s[0]][i+2];
id = sbc_data[s[0]][i+3];
loc_x = sbc_data[s[0]][i+4]+pcb_loc_x+pcbloc_x;
loc_y = sbc_data[s[0]][i+5]+pcb_loc_y+pcbloc_y;
loc_z = sbc_data[s[0]][i+6]+pcb_loc_z+pcbloc_z;
side = sbc_data[s[0]][i+7];
rotation = sbc_data[s[0]][i+8];
if(id == pcbid) {
indent(loc_x, loc_y, bottom_height+loc_z-adj, rotation[2],
side, class, type, wallthick, gap, floorthick, pcb_z);
}
}
}
}
}
// clean fillets
if(case_design == "shell") {
translate(([(width/2)-wallthick-gap,(depth/2)-wallthick-gap,
bottom_height+(top_height/2)]) )
cube_negative_fillet([width,depth,top_height], radius=-1,
vertical=[corner_fillet,corner_fillet,corner_fillet,corner_fillet],
top=[edge_fillet,edge_fillet,edge_fillet,edge_fillet,edge_fillet],
bottom=[0,0,0,0], $fn=90);
}
}
// additive accessories
if(accessory_name != "none") {
for (i=[1:11:len(accessory_data[a[0]])-1]) {
class = accessory_data[a[0]][i];
type = accessory_data[a[0]][i+1];
loc_x = accessory_data[a[0]][i+2];
loc_y = accessory_data[a[0]][i+3];
loc_z = accessory_data[a[0]][i+4];
face = accessory_data[a[0]][i+5];
rotation = accessory_data[a[0]][i+6];
parametric = accessory_data[a[0]][i+7];
size = accessory_data[a[0]][i+8];
data = accessory_data[a[0]][i+9];
mask = accessory_data[a[0]][i+10];
if (class == "add2" && face == "top") {
parametric_move_add(type,loc_x,loc_y,loc_z,face,rotation,
parametric,size,data,[false,mask[1],mask[2],mask[3]]);
}
}
}
}

268
mod/indent.scad Normal file
View File

@@ -0,0 +1,268 @@
/*
This file is part of SBC Case Builder https://github.com/hominoids/SBC_Case_Builder
Copyright 2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
This program 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.
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 this program. If not, see <http://www.gnu.org/licenses/>
Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
NAME: indent
DESCRIPTION: creates case IO indents
TODO: none
USAGE: indent(loc_x, loc_y, loc_z, rotation, side, class, type, wallthick, gap, floorthick, pcb_z)
*/
module indent(loc_x, loc_y, loc_z, rotation, side, class, type, wallthick, gap, floorthick, pcb_z) {
adj = .01;
$fn=90;
// hdmi indent
if(class == "video" && type == "hdmi_a" && side == "top" && rotation == 0) {
place(loc_x+2.375,-(wallthick+gap)+wallthick/2,loc_z+3.75,12,10,rotation,side)
rotate([90,0,0]) long_slot(12,10,wallthick);
}
if(class == "video" && type == "hdmi_a" && side == "top" && rotation == 90) {
place(-gap-wallthick/2,loc_y,loc_z+3.75,12,10,rotation,side)
rotate([90,0,0]) long_slot(12,10,wallthick);
}
if(class == "video" && type == "hdmi_a" && side == "top" && rotation == 180) {
place(loc_x,depth-(wallthick+gap)-10-wallthick/2,loc_z+3.75,12,10,rotation,side)
rotate([90,0,0]) long_slot(12,10,wallthick);
}
if(class == "video" && type == "hdmi_a" && side == "top" && rotation == 270) {
place(width-(wallthick+gap)-10-wallthick/2,loc_y+2.375,loc_z+3.75,12,10,rotation,side)
rotate([90,0,0]) long_slot(12,10,wallthick);
}
if(class == "video" && type == "hdmi_a" && side == "bottom" && rotation == 0) {
place(loc_x,-(wallthick+gap)+wallthick/2,loc_z-pcb_z-3.75,12,10,rotation,side)
rotate([90,0,0]) long_slot(12,10,wallthick);
}
if(class == "video" && type == "hdmi_a" && side == "bottom" && rotation == 90) {
place(width-(wallthick+gap)-10-wallthick/2,loc_y,loc_z-5.25,12,10,rotation,side)
rotate([90,0,0]) long_slot(12,10,wallthick);
}
if(class == "video" && type == "hdmi_a" && side == "bottom" && rotation == 180) {
place(loc_x+2.375,depth-(wallthick+gap)-10-wallthick/2,loc_z-pcb_z-3.75,12,10,rotation,side)
rotate([90,0,0]) long_slot(12,10,wallthick);
}
if(class == "video" && type == "hdmi_a" && side == "bottom" && rotation == 270) {
place(-gap-wallthick/2,loc_y+1.75,loc_z-pcb_z-3.75,12,10,rotation,side)
rotate([90,0,0]) long_slot(12,10,wallthick);
}
// hdmi micro indent
if(class == "video" && type == "hdmi_micro" && rotation == 0 && side == "top") {
place(loc_x-.75,-(wallthick+gap)+wallthick/2,loc_z+1.5,6,8,rotation,side)
rotate([90,0,0]) long_slot(6,8,wallthick);
}
if(class == "video" && type == "hdmi_micro" && rotation == 90 && side == "top") {
place(-gap-wallthick/2,loc_y+1.5,loc_z+1.5,6,8,rotation,side)
rotate([90,0,0]) long_slot(6,8,wallthick);
}
if(class == "video" && type == "hdmi_micro" && rotation == 180 && side == "top") {
place(loc_x+1,depth-(wallthick+gap)-8-wallthick/2,loc_z+1.5,6,8,rotation,side)
rotate([90,0,0]) long_slot(6,8,wallthick);
}
if(class == "video" && type == "hdmi_micro" && rotation == 270 && side == "top") {
place(width-(wallthick+gap)-8-wallthick/2,loc_y-.75,loc_z+1.5,6,8,rotation,side)
rotate([90,0,0]) long_slot(6,8,wallthick);
}
if(class == "video" && type == "hdmi_micro" && rotation == 0 && side == "bottom") {
place(loc_x+1.5,-(wallthick+gap)+wallthick/2,loc_z-3,6,8,rotation,side)
rotate([90,0,0]) long_slot(6,8,wallthick);
}
if(class == "video" && type == "hdmi_micro" && rotation == 90 && side == "bottom") {
place(width-(wallthick+gap)-8-wallthick/2,loc_y+1.25,loc_z-3,6,8,rotation,side)
rotate([90,0,0]) long_slot(6,8,wallthick);
}
if(class == "video" && type == "hdmi_micro" && rotation == 180 && side == "bottom") {
place(loc_x-1,depth-(wallthick+gap)-8-wallthick/2,loc_z-3,6,8,rotation,side)
rotate([90,0,0]) long_slot(6,8,wallthick);
}
if(class == "video" && type == "hdmi_micro" && rotation == 270 && side == "bottom") {
place(-gap-wallthick/2,loc_y-.5,loc_z-3,6,8,rotation,side)
rotate([90,0,0]) long_slot(6,8,wallthick);
}
// hdmi mini indent
if(class == "video" && type == "hdmi_mini" && rotation == 0 && side == "top") {
place(loc_x+.5,loc_y-gap-wallthick/2+1,loc_z+1.5,6,10,rotation,side)
rotate([90,0,0]) long_slot(6,10,wallthick);
}
if(class == "video" && type == "hdmi_mini" && rotation == 90 && side == "top") {
place(loc_x-wallthick/2,loc_y+3.5,loc_z+1.5,6,8,rotation,side)
rotate([90,0,0]) long_slot(6,8,wallthick);
}
if(class == "video" && type == "hdmi_mini" && rotation == 180 && side == "top") {
place(loc_x+4.5,loc_y-wallthick/2,loc_z+1.5,6,10,rotation,side)
rotate([90,0,0]) long_slot(6,10,wallthick);
}
if(class == "video" && type == "hdmi_mini" && rotation == 270 && side == "top") {
place(loc_x+wallthick/2,loc_y+1.5,loc_z+1.5,6,8,rotation,side)
rotate([90,0,0]) long_slot(6,8,wallthick);
}
if(class == "video" && type == "hdmi_mini" && rotation == 0 && side == "bottom") {
place(loc_x+4.5,loc_y-gap-wallthick/2+1,loc_z-3,6,10,rotation,side)
rotate([90,0,0]) long_slot(6,10,wallthick);
}
if(class == "video" && type == "hdmi_mini" && rotation == 90 && side == "bottom") {
place(loc_x+wallthick/2,loc_y+3.5,loc_z-3,6,8,rotation,side)
rotate([90,0,0]) long_slot(6,8,wallthick);
}
if(class == "video" && type == "hdmi_mini" && rotation == 180 && side == "bottom") {
place(loc_x+.5,loc_y-wallthick/2,loc_z-3,6,10,rotation,side)
rotate([90,0,0]) long_slot(6,10,wallthick);
}
if(class == "video" && type == "hdmi_mini" && rotation == 270 && side == "bottom") {
place(loc_x-wallthick/2,loc_y+1.5,loc_z-3,6,8,rotation,side)
rotate([90,0,0]) long_slot(6,8,wallthick);
}
// power plug indent
if(class == "power" && type == "pwr5.5_7.5x11.5" && rotation == 0 && side == "top") {
place(loc_x+3.75,-(wallthick+gap)+wallthick/2,loc_z+6.25,10,10,rotation,side)
rotate([90,0,0]) cylinder(d=10, h=wallthick);
}
if(class == "power" && type == "pwr5.5_7.5x11.5" && rotation == 90 && side == "top") {
place(-gap-wallthick/2,loc_y-6.25,loc_z+6.25,10,10,rotation,side)
rotate([90,0,0]) cylinder(d=10, h=wallthick);
}
if(class == "power" && type == "pwr5.5_7.5x11.5" && rotation == 180 && side == "top") {
place(loc_x-6.5,depth-10-(wallthick+gap)-wallthick/2,loc_z+6.25,10,10,rotation,side)
rotate([90,0,0]) cylinder(d=10, h=wallthick);
}
if(class == "power" && type == "pwr5.5_7.5x11.5" && rotation == 270 && side == "top") {
place(width-(wallthick+gap)-10-wallthick/2,loc_y+3.75,loc_z+6.25,10,10,rotation,side)
rotate([90,0,0]) cylinder(d=10, h=wallthick);
}
if(class == "power" && type == "pwr2.5_5x7.5" && rotation == 0 && side == "top") {
place(loc_x+2.75,-(wallthick+gap)+wallthick/2,loc_z+2.1,7,7,rotation,side)
rotate([90,0,0]) cylinder(d=9, h=wallthick);
}
if(class == "power" && type == "pwr2.5_5x7.5" && rotation == 90 && side == "top") {
place(-(wallthick+gap)+wallthick/2,loc_y-4.5,loc_z+2,7,7,rotation,side)
rotate([90,0,0]) cylinder(d=9, h=wallthick);
}
if(class == "power" && type == "pwr2.5_5x7.5" && rotation == 180 && side == "top") {
place(loc_x-4.5,depth-(wallthick+gap)-7-wallthick/2,loc_z+2,7,7,rotation,side)
rotate([90,0,0]) cylinder(d=9, h=wallthick);
}
if(class == "power" && type == "pwr2.5_5x7.5" && rotation == 270 && side == "top") {
place(width-(wallthick+gap)-7-wallthick/2,loc_y+2.5,loc_z+2,7,7,rotation,side)
rotate([90,0,0]) cylinder(d=9, h=wallthick);
}
// micro usb indent
if(class == "usb2" && type == "micro" && rotation == 0 && side == "top") {
place(loc_x-.5,-(wallthick+gap)+wallthick/2,loc_z+1.9,6,8,rotation,side)
rotate([90,0,0]) long_slot(6,8,wallthick);
}
if(class == "usb2" && type == "micro" && rotation == 90 && side == "top") {
place(-gap-wallthick/2,loc_y+1.5,loc_z+1.9,6,8,rotation,side)
rotate([90,0,0]) long_slot(6,8,wallthick);
}
if(class == "usb2" && type == "micro" && rotation == 180 && side == "top") {
place(loc_x+1.5,depth-(wallthick+gap)-8-wallthick/2,loc_z+1.9,6,8,rotation,side)
rotate([90,0,0]) long_slot(6,8,wallthick);
}
if(class == "usb2" && type == "micro" && rotation == 270 && side == "top") {
place(width-(wallthick+gap)-8-wallthick/2,loc_y-.5,loc_z+1.9,6,8,rotation,side)
rotate([90,0,0]) long_slot(6,8,wallthick);
}
if(class == "usb2" && type == "micro" && rotation == 0 && side == "bottom") {
place(loc_x+1.5,-(wallthick+gap)+wallthick/2,loc_z-3.25,6,8,rotation,side)
rotate([90,0,0]) long_slot(6,8,wallthick);
}
if(class == "usb2" && type == "micro" && rotation == 90 && side == "bottom") {
place(width-(wallthick+gap)-8-wallthick/2,loc_y+1.5,loc_z-3.25,6,8,rotation,side)
rotate([90,0,0]) long_slot(6,8,wallthick);
}
if(class == "usb2" && type == "micro" && rotation == 180 && side == "bottom") {
place(loc_x-.5,depth-(wallthick+gap)-8-wallthick/2,loc_z-3.25,6,8,rotation,side)
rotate([90,0,0]) long_slot(6,8,wallthick);
}
if(class == "usb2" && type == "micro" && rotation == 270 && side == "bottom") {
place(-gap-wallthick/2,loc_y-.5,loc_z-3.25,6,8,rotation,side)
rotate([90,0,0]) long_slot(6,8,wallthick);
}
// single horizontal usbc indent
if(class == "usbc" && type == "single_horizontal" && rotation == 0 && side == "top") {
place(loc_x+.5,-(wallthick+gap)+wallthick/2,loc_z+1.75,6,8,rotation,side)
rotate([90,0,0]) long_slot(6,8,wallthick);
}
if(class == "usbc" && type == "single_horizontal" && rotation == 90 && side == "top") {
place(-gap-wallthick/2,loc_y+2.5,loc_z+1.75,6,8,rotation,side)
rotate([90,0,0]) long_slot(6,8,wallthick);
}
if(class == "usbc" && type == "single_horizontal" && rotation == 180 && side == "top") {
place(loc_x+2.5,depth-(wallthick+gap)-8-wallthick/2,loc_z+1.875,6,8,rotation,side)
rotate([90,0,0]) long_slot(6,8,wallthick);
}
if(class == "usbc" && type == "single_horizontal" && rotation == 270 && side == "top") {
place(width-(wallthick+gap)-8-wallthick/2,loc_y+.5,loc_z+1.75,6,8,rotation,side)
rotate([90,0,0]) long_slot(6,8,wallthick);
}
if(class == "usbc" && type == "single_horizontal" && rotation == 0 && side == "bottom") {
place(loc_x+2.75,-(wallthick+gap)+wallthick/2,loc_z-3.25,6,8,rotation,side)
rotate([90,0,0]) long_slot(6,8,wallthick);
}
if(class == "usbc" && type == "single_horizontal" && rotation == 90 && side == "bottom") {
place(width-(wallthick+gap)-8-wallthick/2,loc_y+2.5,loc_z-3.25,6,8,rotation,side)
rotate([90,0,0]) long_slot(6,8,wallthick-(wallthick+gap)+wallthick/2);
}
if(class == "usbc" && type == "single_horizontal" && rotation == 180 && side == "bottom") {
place(loc_x+.5,depth-(wallthick+gap)-8-wallthick/2,loc_z-3.25,6,8,rotation,side)
rotate([90,0,0]) long_slot(6,8,wallthick);
}
if(class == "usbc" && type == "single_horizontal" && rotation == 270 && side == "bottom") {
place(-gap-wallthick/2,loc_y+.5,loc_z-3.25,6,8,rotation,side)
rotate([90,0,0]) long_slot(6,8,wallthick);
}
// audio jack indent
if(class == "audio" && type == "jack_3.5" && rotation == 0 && side == "top") {
place(loc_x+3.25,-(wallthick+gap)+wallthick/2,loc_z+2.75,8,8,rotation,side)
rotate([90,0,0]) cylinder(d=10, h=wallthick);
}
if(class == "audio" && type == "jack_3.5" && rotation == 90 && side == "top") {
place(-gap-wallthick/2,loc_y-4.6,loc_z+2,8,8,rotation,side)
rotate([90,0,0]) cylinder(d=10, h=wallthick);
}
if(class == "audio" && type == "jack_3.5" && rotation == 180 && side == "top") {
place(loc_x-5.5,depth-(wallthick+gap)-8-wallthick/2,loc_z+2,8,8,rotation,side)
rotate([90,0,0]) cylinder(d=10, h=wallthick);
}
if(class == "audio" && type == "jack_3.5" && rotation == 270 && side == "top") {
place(width-(wallthick+gap)-8-wallthick/2,loc_y+3.25,loc_z+2.5,8,8,rotation,side)
rotate([90,0,0]) cylinder(d=10, h=wallthick);
}
if(class == "audio" && type == "jack_3.5" && rotation == 0 && side == "bottom") {
place(loc_x-4.6,-(wallthick+gap)+wallthick/2,loc_z-3.5,8,8,rotation,side)
rotate([90,0,0]) cylinder(d=10, h=wallthick);
}
if(class == "audio" && type == "jack_3.5" && rotation == 90 && side == "bottom") {
place(width-(wallthick+gap)-8-wallthick/2,loc_y-4.6,loc_z-3.5,8,8,rotation,side)
rotate([90,0,0]) cylinder(d=10, h=wallthick);
}
if(class == "audio" && type == "jack_3.5" && rotation == 180 && side == "bottom") {
place(loc_x+3.15,depth-(wallthick+gap)-8-wallthick/2,loc_z-3.5,8,8,rotation,side)
rotate([90,0,0]) cylinder(d=10, h=wallthick);
}
if(class == "audio" && type == "jack_3.5" && rotation == 270 && side == "bottom") {
place(-gap-wallthick/2,loc_y+3.15,loc_z-3.5,8,8,rotation,side)
rotate([90,0,0]) cylinder(d=10, h=wallthick);
}
}

300
mod/parametric_move.scad Normal file
View File

@@ -0,0 +1,300 @@
/*
This file is part of SBC Case Builder https://github.com/hominoids/SBC_Case_Builder
Copyright 2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
This program 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.
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 this program. If not, see <http://www.gnu.org/licenses/>
Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
NAME: parametric_move_add
DESCRIPTION: places parametric additive objects
TODO: none
USAGE: parametric_move_add(type, loc_x, loc_y, loc_z, face, rotation, parametric[], size[], data[], mask[])
type = component type
loc_x = x location placement
loc_y = y location placement
loc_z = z location placement
face = "top", "bottom", "left", "right", "front", "rear"
rotation[] = object rotation
parametric[] = parametric movement array
size[] = size array x,y,z
data[] = data filed
mask[0] = true enables component mask
mask[1] = mask length
mask[2] = mask setback
mask[3] = mstyle "default"
*/
module parametric_move_add(type, loc_x, loc_y, loc_z, face, rotation, parametric, size, data, mask) {
// absolute no parametrics
if(parametric[1] == false && parametric[2] == false && parametric[3] == false) {
add(type, loc_x, loc_y, loc_z, face, rotation, size, data, mask);
}
// x axis accessory parametrics
if(parametric[1] == true && parametric[2] == false && parametric[3] == false) {
if(parametric[0] == "case") {
add(type, loc_x+case_offset_x, loc_y, loc_z, face, rotation, size, data, mask);
}
if(parametric[0] == "sbc") {
add(type, loc_x+pcb_loc_x, loc_y, loc_z, face, rotation, size, data, mask);
}
}
// y axis accessory parametrics
if(parametric[1] == false && parametric[2] == true && parametric[3] == false) {
if(parametric[0] == "case") {
add(type, loc_x, loc_y+case_offset_y, loc_z, face, rotation, size, data, mask);
}
if(parametric[0] == "sbc") {
add(type, loc_x, loc_y+pcb_loc_y, loc_z, face, rotation, size, data, mask);
}
}
// z axis accessory parametrics
if(parametric[1] == false && parametric[2] == false && parametric[3] == true) {
if(parametric[0] == "case" && face == "top") {
add(type, loc_x, loc_y, loc_z+case_offset_tz+case_offset_bz, face, rotation, size, data, mask);
}
if(parametric[0] == "case" && face == "bottom") {
add(type, loc_x, loc_y, loc_z+case_offset_bz, face, rotation, size, data, mask);
}
if(parametric[0] == "case" && face != "bottom" && face != "top") {
add(type, loc_x, loc_y, loc_z, face, rotation, size, data, mask);
}
if(parametric[0] == "sbc") {
add(type, loc_x, loc_y, loc_z+pcb_loc_z+case_offset_bz, face, rotation, size, data, mask);
}
if(parametric[0] == "sbc-case_z" && face == "top") {
add(type, loc_x, loc_y, loc_z+case_offset_tz+case_offset_bz, face, rotation, size, data, mask);
}
if(parametric[0] == "sbc-case_z" && face == "bottom") {
add(type, loc_x, loc_y, loc_z+case_offset_bz, face, rotation, size, data, mask);
}
}
// xy axis accessory parametrics
if(parametric[1] == true && parametric[2] == true && parametric[3] == false) {
if(parametric[0] == "case") {
add(type, loc_x+case_offset_x, loc_y+case_offset_y, loc_z, face, rotation, size, data, mask);
}
if(parametric[0] == "sbc") {
add(type, loc_x+pcb_loc_x, loc_y+pcb_loc_y, loc_z, face, rotation, size, data, mask);
}
}
// xz axis accessory parametrics
if(parametric[1] == true && parametric[2] == false && parametric[3] == true) {
if(parametric[0] == "case" && face == "top") {
add(type, loc_x+case_offset_x, loc_y, loc_z+case_offset_tz+case_offset_bz, face, rotation, size, data, mask);
}
if(parametric[0] == "case" && face == "bottom") {
add(type, loc_x+case_offset_x, loc_y, loc_z+case_offset_bz, face, rotation, size, data, mask);
}
if(parametric[0] == "case" && face != "bottom" && face != "top") {
add(type, loc_x+case_offset_x, loc_y, loc_z, face, rotation, size, data, mask);
}
if(parametric[0] == "sbc") {
add(type, loc_x+pcb_loc_x, loc_y, loc_z+pcb_loc_z+case_offset_bz, face, rotation, size, data, mask);
}
if(parametric[0] == "sbc-case_z" && face == "top") {
add(type, loc_x+pcb_loc_x, loc_y, loc_z+case_offset_tz+case_offset_bz, face, rotation, size, data, mask);
}
if(parametric[0] == "sbc-case_z" && face == "bottom") {
add(type, loc_x+pcb_loc_x, loc_y, loc_z+case_offset_bz, face, rotation, size, data, mask);
}
}
// yz axis accessory parametrics
if(parametric[1] == false && parametric[2] == true && parametric[3] == true) {
if(parametric[0] == "case" && face == "top") {
add(type, loc_x, loc_y+case_offset_y, loc_z+case_offset_tz+case_offset_bz, face, rotation, size, data, mask);
}
if(parametric[0] == "case" && face == "bottom") {
add(type, loc_x, loc_y+case_offset_y, loc_z+case_offset_bz, face, rotation, size, data, mask);
}
if(parametric[0] == "case" && face != "bottom" && face != "top") {
add(type, loc_x, loc_y+case_offset_y, loc_z, face, rotation, size, data, mask);
}
if(parametric[0] == "sbc") {
add(type, loc_x, loc_y+pcb_loc_y, loc_z+pcb_loc_z+case_offset_bz, face, rotation, size, data, mask);
}
if(parametric[0] == "sbc-case_z" && face == "top") {
add(type, loc_x,loc_y+pcb_loc_y, loc_z+case_offset_tz+case_offset_bz, face, rotation, size, data, mask);
}
if(parametric[0] == "sbc-case_z" && face == "bottom") {
add(type, loc_x, loc_y+pcb_loc_y, loc_z+case_offset_bz, face, rotation, size, data, mask);
}
}
// xyz axis accessory parametrics
if(parametric[1] == true && parametric[2] == true && parametric[3] == true) {
if(parametric[0] == "case" && face == "top") {
add(type, loc_x+case_offset_x, loc_y+case_offset_y, loc_z+case_offset_tz+case_offset_bz, face, rotation, size, data, mask);
}
if(parametric[0] == "case" && face == "bottom") {
add(type, loc_x+case_offset_x, loc_y+case_offset_y, loc_z+case_offset_bz, face, rotation, size, data, mask);
}
if(parametric[0] == "case" && face != "bottom" && face != "top") {
add(type, loc_x+case_offset_x, loc_y+case_offset_y, loc_z, face, rotation, size, data, mask);
}
if(parametric[0] == "sbc") {
add(type, loc_x+pcb_loc_x, loc_y+pcb_loc_y, loc_z+pcb_loc_z+case_offset_bz, face, rotation, size, data, mask);
}
if(parametric[0] == "sbc-case_z" && face == "top") {
add(type, loc_x+pcb_loc_x, loc_y+pcb_loc_y, loc_z+case_offset_tz+case_offset_bz, face, rotation, size, data, mask);
}
if(parametric[0] == "sbc-case_z" && face == "bottom") {
add(type, loc_x+pcb_loc_x, loc_y+pcb_loc_y, loc_z+case_offset_bz, face, rotation, size, data, mask);
}
}
}
/*
NAME: parametric_move_sub
DESCRIPTION: places parametric subtractive objects
TODO: none
USAGE: parametric_move_sub(type, loc_x, loc_y, loc_z, face, rotation, parametric[], size[], data[], mask[])
type = component type
loc_x = x location placement
loc_y = y location placement
loc_z = z location placement
face = "top", "bottom", "left", "right", "front", "rear"
rotation[] = object rotation
parametric[] = parametric movement array
size[] = size array x,y,z
mask[0] = true enables component mask
mask[1] = mask length
mask[2] = mask setback
mask[3] = mstyle "default"
*/
module parametric_move_sub(type, loc_x, loc_y, loc_z, face, rotation, parametric, size, data, mask) {
// absolute no parametrics
if(parametric[1] == false && parametric[2] == false && parametric[3] == false) {
sub(type, loc_x, loc_y, loc_z, face, rotation, size, data, mask);
}
// x axis accessory parametrics
if(parametric[1] == true && parametric[2] == false && parametric[3] == false) {
if(parametric[0] == "case") {
sub(type, loc_x+case_offset_x, loc_y, loc_z, face, rotation, size, data, mask);
}
if(parametric[0] == "sbc") {
sub(type, loc_x+pcb_loc_x, loc_y, loc_z, face, rotation, size, data, mask);
}
}
// y axis accessory parametrics
if(parametric[1] == false && parametric[2] == true && parametric[3] == false) {
if(parametric[0] == "case") {
sub(type, loc_x, loc_y+case_offset_y, loc_z, face, rotation, size, data, mask);
}
if(parametric[0] == "sbc") {
sub(type, loc_x, loc_y+pcb_loc_y, loc_z, face, rotation, size, data, mask);
}
}
// z axis accessory parametrics
if(parametric[1] == false && parametric[2] == false && parametric[3] == true) {
if(parametric[0] == "case" && face == "top") {
sub(type, loc_x, loc_y, loc_z+case_offset_tz+case_offset_bz, face, rotation, size, data, mask);
}
if(parametric[0] == "case" && face == "bottom") {
sub(type, loc_x, loc_y, loc_z+case_offset_bz, face, rotation, size, data, mask);
}
if(parametric[0] == "case" && face != "bottom" && face != "top") {
sub(type, loc_x, loc_y, loc_z, face, rotation, size, data, mask);
}
if(parametric[0] == "sbc") {
sub(type, loc_x, loc_y, loc_z+pcb_loc_z, face, rotation, size, data, mask);
}
if(parametric[0] == "sbc-case_z" && face == "top") {
sub(type, loc_x, loc_y, loc_z+case_offset_tz+case_offset_bz, face, rotation, size, data, mask);
}
if(parametric[0] == "sbc-case_z" && face == "bottom") {
sub(type, loc_x, loc_y, loc_z+case_offset_bz, face, rotation, size, data, mask);
}
}
// xy axis accessory parametrics
if(parametric[1] == true && parametric[2] == true && parametric[3] == false) {
if(parametric[0] == "case") {
sub(type, loc_x+case_offset_x, loc_y+case_offset_y, loc_z, face, rotation, size, data, mask);
}
if(parametric[0] == "sbc") {
sub(type, loc_x+pcb_loc_x, loc_y+pcb_loc_y,loc_z, face, rotation, size, data, mask);
}
}
// xz axis accessory parametrics
if(parametric[1] == true && parametric[2] == false && parametric[3] == true) {
if(parametric[0] == "case" && face == "top") {
sub(type, loc_x+case_offset_x, loc_y, loc_z+case_offset_tz+case_offset_bz, face, rotation, size, data, mask);
}
if(parametric[0] == "case" && face == "bottom") {
sub(type, loc_x+case_offset_x, loc_y, loc_z+case_offset_bz, face, rotation, size, data, mask);
}
if(parametric[0] == "case" && face != "bottom" && face != "top") {
sub(type, loc_x+case_offset_x, loc_y, loc_z, face, rotation, size, data, mask);
}
if(parametric[0] == "sbc") {
sub(type, loc_x+pcb_loc_x, loc_y, loc_z+pcb_loc_z, face, rotation, size, data, mask);
}
if(parametric[0] == "sbc-case_z" && face == "top") {
sub(type, loc_x+pcb_loc_x, loc_y, loc_z+case_offset_tz+case_offset_bz, face, rotation, size, data, mask);
}
if(parametric[0] == "sbc-case_z" && face == "bottom") {
sub(type, loc_x+pcb_loc_x, loc_y, loc_z+case_offset_bz, face, rotation, size, data, mask);
}
}
// yz axis accessory parametrics
if(parametric[1] == false && parametric[2] == true && parametric[3] == true) {
if(parametric[0] == "case" && face == "top") {
sub(type, loc_x, loc_y+case_offset_y, loc_z+case_offset_tz+case_offset_bz, face, rotation, size, data, mask);
}
if(parametric[0] == "case" && face == "bottom") {
sub(type, loc_x, loc_y+case_offset_y, loc_z+case_offset_bz, face, rotation, size, data, mask);
}
if(parametric[0] == "case" && face != "bottom" && face != "top") {
sub(type, loc_x, loc_y+case_offset_y, loc_z, face, rotation, size, data, mask);
}
if(parametric[0] == "sbc") {
sub(type, loc_x, loc_y+pcb_loc_y, loc_z+pcb_loc_z, face, rotation, size, data, mask);
}
if(parametric[0] == "sbc-case_z" && face == "top") {
sub(type, loc_x, loc_y+pcb_loc_y, loc_z+case_offset_tz+case_offset_bz, face, rotation, size, data, mask);
}
if(parametric[0] == "sbc-case_z" && face == "bottom") {
sub(type, loc_x, loc_y+pcb_loc_y, loc_z+case_offset_bz, face, rotation, size, data, mask);
}
}
// xyz axis accessory parametrics
if(parametric[1] == true && parametric[2] == true && parametric[3] == true) {
if(parametric[0] == "case" && face == "top") {
sub(type, loc_x+case_offset_x, loc_y+case_offset_y, loc_z+case_offset_tz+case_offset_bz, face, rotation, size, data, mask);
}
if(parametric[0] == "case" && face == "bottom") {
sub(type, loc_x+case_offset_x, loc_y+case_offset_y, loc_z+case_offset_bz, face, rotation, size, data, mask);
}
if(parametric[0] == "case" && face != "bottom" && face != "top") {
sub(type, loc_x+case_offset_x, loc_y+case_offset_y, loc_z, face, rotation, size, data, mask);
}
if(parametric[0] == "sbc") {
sub(type, loc_x+pcb_loc_x, loc_y+pcb_loc_y, loc_z+pcb_loc_z, face, rotation, size, data, mask);
}
if(parametric[0] == "sbc-case_z" && face == "top") {
sub(type, loc_x+pcb_loc_x, loc_y+pcb_loc_y, loc_z+case_offset_tz+case_offset_bz, face, rotation, size, data, mask);
}
if(parametric[0] == "sbc-case_z" && face == "bottom") {
sub(type, loc_x+pcb_loc_x, loc_y+pcb_loc_y, loc_z+case_offset_bz, face, rotation, size, data, mask);
}
}
}

66
mod/place.scad Normal file
View File

@@ -0,0 +1,66 @@
/*
This file is part of SBC Case Builder https://github.com/hominoids/SBC_Case_Builder
Copyright 2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
This program 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.
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 this program. If not, see <http://www.gnu.org/licenses/>
Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
NAME: place
DESCRIPTION: transformation to place objects on either side of a geometric plane of a given thickness
TODO: none
USAGE: place(x, y, z, size_x, size_y, rotation, side)
*/
/* placement module *must be first* for children() */
module place(x, y, z, size_x, size_y, rotation, side) {
if (side == "top") {
if (rotation == 0 || rotation == 90 || rotation == 180 || rotation == 270) {
if ((rotation >= 0 && rotation < 90) || (rotation < -270 && rotation > -360))
translate([x,y,z]) rotate([0,0,-rotation]) children();
if ((rotation >= 90 && rotation < 180) || (rotation < -180 && rotation >= -270))
translate([x,y+size_x,z]) rotate([0,0,-rotation]) children();
if ((rotation >= 180 && rotation < 270) || (rotation < -90 && rotation >= -180))
translate([x+size_x,y+size_y,z]) rotate([0,0,-rotation]) children(0);
if ((rotation >= 270 && rotation < 360) || (rotation < 0 && rotation >= -90))
translate([x+size_y,y,z]) rotate([0,0,-rotation]) children(); }
else {
translate([x,y,z]) rotate([0,0,-rotation]) children();
}
}
if (side == "bottom") {
if (rotation == 0 || rotation == 90 || rotation == 180 || rotation == 270) {
if ((rotation >= 0 && rotation < 90) || (rotation < -270 && rotation > -360))
translate([x+size_x,y,z]) rotate([0,180,rotation]) children();
if ((rotation >= 90 && rotation < 180) || (rotation < -180 && rotation >= -270))
translate([x+size_y,y+size_x,z]) rotate([0,180,rotation]) children();
if ((rotation >= 180 && rotation < 270) || (rotation < -90 && rotation >= -180))
translate([x,y+size_y,z]) rotate([0,180,rotation]) children();
if ((rotation >= 270 && rotation < 360) || (rotation < 0 && rotation >= -90))
translate([x,y,z]) rotate([0,180,rotation]) children(); }
else {
translate([x,y,z]) rotate([0,180,rotation]) children();
}
}
children([1:1:$children-1]);
}

84
mod/sub.scad Normal file
View File

@@ -0,0 +1,84 @@
/*
This file is part of SBC Case Builder https://github.com/hominoids/SBC_Case_Builder
Copyright 2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
This program 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.
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 this program. If not, see <http://www.gnu.org/licenses/>
Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
NAME: sub
DESCRIPTION: places subtractive objects
TODO: none
USAGE: sub(type, loc_x, loc_y, loc_z, face, rotation, size[], data[], mask[])
type = component type
loc_x = x location placement
loc_y = y location placement
loc_z = z location placement
face = "top", "bottom", "left", "right", "front", "rear"
rotation[] = object rotation
parametric[] = parametric movement array
size[] = size array x,y,z
data[] = data variable on type
mask[0] = true enables component mask
mask[1] = mask length
mask[2] = mask setback
mask[3] = mstyle "default"
*/
module sub(type, loc_x, loc_y, loc_z, face, rotation, size, data, mask) {
size_x = size[0];
size_y = size[1];
size_z = size[2];
enablemask = mask[0];
mlen = mask[1];
msetback = mask[2];
mstyle = mask[3];
if(type == "art") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) art(data[0],data[1],data[2]);
}
if(type == "fan_mask") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) fan_mask(size_x, size_z, data[0]);
}
if(type == "hd_holes") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hd_bottom_holes(data[0],data[1],data[2],data[3],data[4]);
}
if(type == "knockout") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) knockout(size_x,size_y,data[0],size_z,data[1],data[2]);
}
if(type == "rectangle") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) slab_r([size_x,size_y,size_z],data[0]);
}
if(type == "round") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) cylinder(d=size_x,h=size_z);
}
if(type == "slot") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) slot(size_x,size_y,size_z);
}
if(type == "sphere") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) sphere(d=size_x);
}
if(type == "text") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) linear_extrude(height = size_z) text(data_2, size=data[0]);
}
if(type == "vent") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) vent(size_x,size_y,size_z,data[3],data[0],data[1],data[2]);
}
if(type == "vent_hex") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) vent_hex(size_x,size_y,size_z,data[0],data[1],data[2]);
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

114
sbccb_accessory_tool.scad Normal file
View File

@@ -0,0 +1,114 @@
/*
SBC Case Builder Accessory Tool Copyright 2025 Edward A. Kisiel hominoid@cablemi.com
This file is part of SBC Case Builder https://github.com/hominoids/SBC_Case_Builder
This program 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.
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 this program. If not, see <http://www.gnu.org/licenses/>.
Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
see https://github.com/hominoids/SBC_Case_Builder
*/
include <./sbc_case_builder_library.scad>;
/* [View] */
// viewing mode "model", "platter"
view = "model"; // [model, platter]
individual_part = "bottom"; // [top, bottom, right, left, front, rear, io_shield, accessories]
// section individual parts for panel cases
section_part = false; // [true,false]
accessory = "grommet"; // ["1u rack stand", "2.5 drive holder", "fan cover", "grommet", "washer"]
/* [1U Rack Stand] */
rack_width = 19; // [10, 19]
rack_1u = 4; // [1 : 4]
rack_fasteners = "nut"; // ["none", "nut", "insert"]
/* [2.5" Drive Holder] */
holder_length = 110; // [110, 145]
holder_width = 101.6; // [101.6 : .1 : 150]
/* [Fan Cover] */
fan_style = "fan_hex"; // ["fan_open", "fan_1", "fan_2", "fan_hex"]
fan_size = 40; // [25, 30, 40, 50, 60, 80, 92, 120]
fan_cover_thickness = 2; // [2 : .25 : 5]
/* [Grommet] */
grommet_style = "sleeve"; // ["sleeve"]
grommet_od = 10; // [6 : .25 : 20]
grommet_id = 6; // [2 : .25 : 20]
installation_wall_thickness = 2; // [2 : .25 : 5]
/* [Washer] */
washer_style = "flat"; // ["flat", "shouldered"]
washer_od = 5; // [3 : .25 : 20]
washer_id = 3; // [2 : .25 : 20]
washer_thickness = 2; // [1 : .25 : 8]
shoulder_height = 3; // [1 : .25 : 4]
shoulder_countersunk = false; // [true,false]
/* [Hidden] */
mask = [true, 10, 2, "default"];
nmask = [false, 10, 2, "default"];
rack_depth = 150;
adj = .01;
$fn = 90;
// model view
if (view == "model") {
if(accessory == "1u rack stand") {
rack_stand(rack_1u);
}
if(accessory == "2.5 drive holder") {
hd35_25holder(holder_length, holder_width);
}
if(accessory == "fan cover") {
fan_cover(fan_size, fan_cover_thickness, fan_style);
}
if(accessory == "grommet") {
grommet("front", grommet_style, grommet_od, grommet_id, installation_wall_thickness, true, nmask);
}
if(accessory == "washer") {
washer(washer_style, washer_id, washer_od, washer_thickness, shoulder_height, shoulder_countersunk, "silver");;
}
}
// platter view
if (view == "platter") {
if(accessory == "1u rack stand") {
rotate([0,270,0]) rack_stand(rack_1u);
}
if(accessory == "2.5 drive holder") {
hd35_25holder(holder_length, holder_width);
}
if(accessory == "fan cover") {
fan_cover(fan_size, fan_cover_thickness, fan_style);
}
if(accessory == "grommet" && grommet_style == "sleeve") {
translate([0,0,0]) rotate([270,0,0]) difference() {
grommet("bottom", grommet_style, grommet_od, grommet_id, installation_wall_thickness, false, nmask);
translate([-grommet_od,-.125,-3]) cube([20,10,20]);
}
translate([0,20,0]) rotate([270,0,0]) difference() {
grommet("bottom", grommet_style, grommet_od, grommet_id, installation_wall_thickness, false, nmask);
translate([-grommet_od,-.125,-3]) cube([20,10,20]);
}
translate([0,-20,0])
grommet_clip(grommet_style, grommet_od, grommet_id, installation_wall_thickness);
}
if(accessory == "washer") {
washer(washer_style, washer_id, washer_od, washer_thickness,
shoulder_height, shoulder_countersunk, "silver");
}
}

View File

@@ -1,20 +0,0 @@
/* find correct tolerance and use for respective entry's data_1 value within sbc_case_builder.cfg */
use <./sbc_case_builder_library.scad>;
battery_tolerance = 0;
speaker_tolerance = 0;
volume_tolerance = 0;
$fn = 90;
translate([-33,0,0]) batt_holder(battery_tolerance);
difference() {
translate([-17,-17,0]) cube([34,34,2]);
translate([0,0,-1]) cylinder(d=24, h=4);
}
translate([0,0,1.99]) boom_speaker_holder("friction",speaker_tolerance);
translate([30,0,0]) boom_vring(volume_tolerance);