176 Commits

Author SHA1 Message Date
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
Edward Kisiel
d59191109e adjusted cases and accessories, updated README.md and SBC_Case_Builder_Cases.gif 2022-10-11 14:45:48 -04:00
Edward Kisiel
1cbc923d2c updated version in all files, updated readme.md and other small tweaks and corrections 2022-10-06 17:05:57 -04:00
Edward Kisiel
b0a82b3519 updated readme.md 2022-10-05 18:11:50 -04:00
Edward Kisiel
4ab67184aa finished rewrite of indents, added hdmi_mini,hdmi_micro,pwr5.5_7.5x11.5,pwr2.5_5x7.5 2022-10-02 15:03:24 -04:00
Edward Kisiel
98c3f02294 rewrite of indents, added usb2-micro,usbc-single_horizontal,audio-jack_3.5 and video-hdmi_a indents in all orientations, top and bottom, created new mask openings for bottom side components as needed. 2022-10-01 18:25:55 -04:00
Edward Kisiel
cfab47dd60 updated to latest sbc_model_framework 2022-09-25 17:39:49 -04:00
Edward Kisiel
5f775d3f39 added cutaway view when case face is not movable. 2022-09-24 20:51:43 -04:00
Edward Kisiel
06516ff821 all existing case accessories changed to use parametrics. 2022-09-24 20:08:11 -04:00
Edward Kisiel
6e5842f8a8 Merge pull request #14 from davejlong/new_fan
Fixes spacing of vents and rendering
2022-09-23 16:52:35 -04:00
David Long
e7fb885769 Updated new fan style to style type 3 2022-09-23 12:34:54 -04:00
David Long
5fa96e3e32 Merge remote-tracking branch 'upstream/main' into new_fan 2022-09-22 10:23:20 -04:00
David Long
af5bb195d5 Update fan ring base to 95% of the fan size 2022-09-22 10:00:37 -04:00
Edward Kisiel
fb0ee1f361 some more changes to existing case accessories to use parametrics. 2022-09-18 21:11:20 -04:00
Edward Kisiel
e0ae29f0fb more changes to existing case accessories to use parametrics. 2022-09-18 17:16:38 -04:00
Edward Kisiel
33bace995f added multi-associative parametric positioning of accessories which use sbc xy postion and case z offset, sbc-case_z. 2022-09-17 22:04:05 -04:00
David Long
138171c638 Made all elements of test 3d to allow for surface and wireframe checking 2022-09-15 17:10:31 -04:00
David Long
9ca1c2d425 Labels for fan mask test 2022-09-15 17:04:24 -04:00
David Long
7051bf871d Removed extra echo calls 2022-09-15 16:57:28 -04:00
David Long
861c2231fc Update fan logic to handle larger fan sizes better. Improved positioning and placement of fan parts. 2022-09-15 16:54:37 -04:00
David Long
ac3d1b7993 Merge branch 'main' into new_fan 2022-09-15 14:23:13 -04:00
David Long
a2fbf8d17b Fixed comment in test 2022-09-14 17:05:18 -04:00
David Long
97f1c4c26e rotated cross bars to 45deg. added a test file to generate a few sizes of masks 2022-09-14 17:00:00 -04:00
David Long
8b7092c859 Fixes spacing of vents and rendering 2022-09-13 22:19:09 -04:00
Edward Kisiel
363c9698d1 changed default view to model for rpi4b_shell_geeekpi_poe_hat, turned off acc highlight and changed fan to 40mm. 2022-09-13 21:36:26 -04:00
Edward Kisiel
d0cd8f6c99 Revert "new fan design that supports more fan sizes"
This reverts commit d3b19d09ba.
There are problems with this design. The code is causing warnings and using to much processing power.
2022-09-13 21:22:31 -04:00
Edward Kisiel
f0c5106801 Merge branch 'davejlong-rpi4b_geeekpi' into main 2022-09-13 20:12:26 -04:00
Edward Kisiel
a2e78bd4da Merge branch 'rpi4b_geeekpi' of github.com:davejlong/SBC_Case_Builder into davejlong-rpi4b_geeekpi 2022-09-13 20:11:32 -04:00
Edward Kisiel
057145e7e8 Merge pull request #12 from davejlong/new_fan
new fan design that supports more fan sizes
2022-09-13 19:37:49 -04:00
Edward Kisiel
71702e2435 Merge pull request #11 from davejlong/board_list_generator
Board list generator
2022-09-13 19:35:20 -04:00
David Long
fb41a52214 Adds a new preset for Raspberry Pi 4b with GeeekPi PoE Hat 2022-09-12 22:16:30 -04:00
David Long
d3b19d09ba new fan design that supports more fan sizes 2022-09-12 22:11:55 -04:00
David Long
1f154229c2 Adds accessory data to customizer values generator 2022-09-12 22:01:40 -04:00
David Long
76fb895b64 Updates list of boards supported. 2022-09-12 11:18:10 -04:00
Edward Kisiel
73e70ccf6f updated readme.md, added new variables to json entires, converted all case except HK to parametric accessories 2022-09-11 19:54:41 -04:00
Edward Kisiel
acc6ef9d9a added individually controlled variable height case standoffs 2022-09-10 21:51:01 -04:00
Edward Kisiel
f589cc70c1 more accessory associated parametric positioning 2022-09-10 18:52:13 -04:00
Edward Kisiel
9238ca6d8c start of accessory parameteric positioning 2022-09-04 22:09:33 -04:00
Edward Kisiel
3357afbf86 added opizero,opizero2,opir1plus_lts, changed ui 2022-08-29 19:29:10 -04:00
Edward Kisiel
3226156e13 modified hex case for low width/depth ratio sbc, other fixes and updates. 2022-08-28 15:14:50 -04:00
Edward Kisiel
0c7e482576 add round case for low width/depth ratio sbc, fixed vent location, added rj-45_short mask 2022-08-27 19:45:38 -04:00
Edward Kisiel
6c00bb37b4 added rpi3a+ cases and other case modifications 2022-08-22 20:17:58 -04:00
Edward Kisiel
63161e5145 updated sbc_model_framework to fix typo 2022-08-22 08:47:25 -04:00
Edward Kisiel
c573e3e9f7 plumbed vim heatsink, adjusted vim case heights, added mask for combo usb3-usbc and other case adjustments. 2022-08-21 16:44:52 -04:00
Edward Kisiel
9fd72e357c added momentary_7x3x3 mask, changed snap size for snap case, new case configurations. 2022-08-20 21:05:24 -04:00
Edward Kisiel
3b0465bc73 more sbc_model_framework corrections 2022-08-20 10:23:51 -04:00
Edward Kisiel
7ae702fc6e updated sbc_model_framework for heatsink name correction. 2022-08-19 21:56:08 -04:00
Edward Kisiel
884261a56c updated sbc_model_library and started update of customizer and case additions of multiple new sbc. 2022-08-19 21:38:07 -04:00
Edward Kisiel
edfe3a4056 added rockpi4c case and dp_mini mask 2022-08-14 23:12:08 -04:00
Edward Kisiel
c607f1e094 updated sbc_model_framework 2022-08-14 22:24:46 -04:00
Edward Kisiel
bcda274cb4 added remaining component masks for recent sbc additions 2022-08-14 17:21:24 -04:00
Edward Kisiel
dd71020fc6 added sbc rpi3a+,rpi4b,rpizero,rock64,rockpi4c+,rockpi4b+ to customizer, added mask for usb2 and usb3 single_horizontal_a 2022-08-13 20:03:30 -04:00
Edward Kisiel
1aa242375a adjusted floor thickness for snap and fitted cases 2022-08-08 16:47:07 -04:00
Edward Kisiel
7f09be5e0b fixed floorthick in round and hex cases, updated readme 2022-08-07 19:43:20 -04:00
Edward Kisiel
34acbbd295 added lip in top for round and hex cases 2022-08-07 19:17:12 -04:00
Edward Kisiel
a49bb6473a updated json and cfg files, more round and hex case development 2022-08-07 17:32:38 -04:00
Edward Kisiel
f658b458ef added sbc_highlight to ui, changed to sbc_case_builder_accessories.cfg,updated json data, other case adjustments and fixes 2022-08-06 20:38:24 -04:00
Edward Kisiel
2d5d3a7c31 round and hex case work and parameteric fixes 2022-08-04 20:44:46 -04:00
Edward Kisiel
82c1d908b6 finished reformatting remaining cases to json 2022-08-03 21:08:17 -04:00
Edward Kisiel
51b6e7d141 reformatted n2 and n2+ cases to json 2022-08-02 20:02:07 -04:00
Edward Kisiel
a67c0ea64c reformatted m1 and n1 cases to json 2022-08-02 17:52:21 -04:00
Edward Kisiel
44bf215ff6 reformatted c1+,c2,c4,xu4,xu4q,hc4 cases, adjusted multiple accessories and other changes. 2022-07-31 22:52:29 -04:00
Edward Kisiel
3eb91c0b39 more json integration, fixed round, hex, fitted, snap cases, other minor fixes 2022-07-31 17:36:15 -04:00
Edward Kisiel
2e9f05f8bd fixed indent to adjust correctly based on wallthick, fixed standoff wall support placement,
more customizer integration work, removed case data from sbc_case_builder.cfg, additional
cases in json format.
2022-07-30 22:40:03 -04:00
Edward Kisiel
3c8abbdcd8 updated customizer and added json file 2022-07-29 23:46:44 -04:00
Edward Kisiel
0792cb7981 customizer and json format base 2022-07-29 20:27:44 -04:00
Edward Kisiel
7307a131eb code cleanup 2022-07-28 21:51:40 -04:00
Edward Kisiel
18ac05627d added fitted case 2022-07-28 21:43:53 -04:00
Edward Kisiel
ba574aba8a added snap top and hexagon cases 2022-07-27 22:02:29 -04:00
Edward Kisiel
f4c9078d85 added round case 2022-07-26 18:20:54 -04:00
Edward Kisiel
ba027dbae4 merge conflict resolution 2022-07-26 15:36:07 -04:00
Edward Kisiel
b47cf5d845 even more README.md formatting 2022-07-12 23:03:59 -04:00
Edward Kisiel
03c60b8d1f more README.md formatting 2022-07-12 22:14:42 -04:00
Edward Kisiel
6430829c9d Merge pull request #4 from davejlong/main
Adds support for OpenSCAD customizer
2022-07-12 20:54:51 -04:00
David Long
5858340e51 Merge branch 'hominoids:main' into main 2022-07-12 10:33:16 -04:00
David Long
11337b6a71 Merge branch 'main' of github.com:davejlong/SBC_Case_Builder 2022-07-12 10:30:33 -04:00
David Long
fa8c94c6e7 Updated settings to work with OpenSCAD customizer 2022-07-12 10:30:09 -04:00
Edward Kisiel
f4c2f765a1 updated README.md 2022-07-07 21:32:00 -04:00
Edward Kisiel
086ff0766c more code cleanup and fixes 2022-07-07 20:34:09 -04:00
David Long
e621df86af Removed a commented out config 2022-07-07 09:53:11 -04:00
David Long
625050370f Removed SBC_Library_Framework files from lib 2022-07-07 09:51:26 -04:00
David Long
551c4736db Updated submodule to point upstream 2022-07-07 09:49:45 -04:00
David Long
97936f16a2 build raspberry pi cases 2022-07-05 09:59:30 -04:00
David Long
f80f4e9516 Updates to support rockpro64 board 2022-06-23 19:37:03 -04:00
Edward Kisiel
260752a32d added round case for odroid c-series and other rpi format sbc 2022-05-22 13:11:32 -04:00
50 changed files with 37533 additions and 127556 deletions

3
.gitmodules vendored Normal file
View File

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

719
README.md
View File

@@ -3,14 +3,727 @@
## Introduction
This project is about autonomous SBC case creation. It utilizes the SBC Model Framework project
to automatically generate cases based on the data for any given SBC contained within the framework.
This project is about autonomous SBC case creation. It utilizes the SBC Model Framework project to automatically generate cases based on the data for any of the 84 current devices contained within the framework. This allows legacy, current and future SBC to have multiple cases available on day one of their inclusion in the framework. There are multiple base case designs(shell, panel, stacked, tray, tray-sides, round, hex, snap, fitted) available and each allows for different styles within the design.
All case openings are created automatically based on SBC data and the dimensions of any case design can be expanded in any axis allowing for the creation of larger cases. If you reposition the SBC in a case, you will see i/o openings created or removed appropriately based on its proximity to the case geometry. These cases might be useful for prototypes or other in house uses to quickly and easily create standard, specialized and custom SBC cases thru different case designs, styles and accessories.
License: GPLv3.
![Image](SBC_Case_Builder_Cases.gif)
### Install
```
git clone https://github.com/hominoids/SBC_Case_Builder.git
cd SBC_Case_Builder
git submodule init
git submodule update
```
### SBC Case Builder Features:
- Autonomous Multi-SBC, Multi-Case Parametric Generation
- Autonomous Case Standoffs with Variable Height
- Extended Standoff SBC collision detection
- Accessory Customization Framework
- Accessory Multi-Associative Parametric Positioning
- Absolute Location
- Case Associations
- SBC Associations
- SBC_X,Y - Case_Z Association
- SBC Model Framework Validation Tool
### Base Case Designs:
- Shell - complete
- Panel - complete
- Stacked - complete
- Tray - complete
- Tray-Sides - complete
- Tray-Vu5 - complete
- Tray-Vu7 - complete
- Round - complete
- Hex - complete
- Snap - complete
- Fitted - complete
- Paper, Folded - complete
- Sheet Metal, Folded
- Sliding
- Cylinder
- NAS
- Rack
- Adapters(itx, matx)
- CNC Cases
All case data is stored in the json file sbc_case_builder.json with the accessory data stored in a separate file structure in sbc_case_builder_accessories.cfg. An accessory group name for a given case is stored as part of the case data in the json file. This allows for the reuse or sharing of an accessory set by different cases and can be used to manage groups of accessories.
Variable height automated SBC standoffs, which can be individually adjusted, are also implemented to integrate add-on PCB, hats, heatsinks or other accessories that share SBC standoffs for mounting.
Multi-associative parametric positioning of accessories is implemented and allows each accessory to enable or disable parametric movement of the accessory for each axis. The XY and Z axis can be associated with the case offset (size), SBC positioning, multi-associated axises or absolute positioning. For instance, a SBC fan opening needs to follow the SBC in the X and Y axis but the case Z axis for the correct height.
```
p
a
r
r a
o m
t e s s s d d d d
c l l l a t i i i a a a a
l t o o o f t r z z z t t t t
a y c c c a i i e e e a a a a
s p c o c
s, e, x, y, z, e, n, s, x,y,z,1,2,3,4
`"sub","fan",10,10,24.5,"top",[0,0,0],["sbc-case_z",true,true,true],40,0,6,2,0,"",0]`
```
An array holds a string and 3 Boolean that represent which association and axis are enabled for parametric movement. In the accessory example above, the 8th parameter `["sbc-case_z",true,true,true]` means all axises are enabled for multi-associative movement with the X and Y accessory axis following the SBC X and Y axis and the accessory Z axis following the case Z axis. The other currently supported associations are “sbc” and “case”. If other associations of objects are needed or are of value, they can be added in the future. All of the existing cases have been made parametric and can serve as further working examples.
### Accuracy
In the past there was been no way of validating whether a SBC Model Framework model and its components were dimensionaly accurate in their size and placement other then trial and error. Along with producing cases this project provides a much needed model validation tool to assure model accuracy thru the use of test cases. It works on the very simple premise that if the real SBC fits the test case then the virtual model is accurate or otherwise shows were corrections are needed. This will further increased the overall accuracy of models.
Some SBC in SBC Model Framework have not been validated or may be missing component data and may produce one or more aspects of a case incorrectly. SBC status is noted in sbc.png, the README.md file and at the beginning of the SBC entry defined in sbc_models.cfg, all a part of SBC Model Framework. The color coded indicator of an SBCs verification and completion as indicated in sbc.png is as follows:
- GREEN = verified, complete and passes SBC Case Builder
- YELLOW = unverified, mostlikely usable and/or missing minor information
- ORANGE = unverified, may be usable but missing component data
- RED = unverified, not usable due to incomplete component data
The SBC that I do not own have been created using manufacturer supplied mechanical drawings. Some of the drawings are missing information or have errors that effect all or part of the drawings and subsequent SBC models. If you own an SBC that is not represented or verified in SBC Model Framework, please consider adding it or helping to correct errors in existing SBC data. An SBC can be verified to be accurate if a printed shell case from SBC Case Builder fits. Any misalignment is corrected in the SBC Model Framework model data(sbc_models.cfg).
### Future Development
There are a few more ideas for base cases to be worked on as well as a host of supporting accessory models that need to be created. It would also be nice to have all of the OEM accessories for each SBC in the library as well. Im still looking for a better way to create accessory entries and groups, and continue to expand and verify as many SBC as possible. With that and the obvious benefit of autonomously making SBC cases, this project has also been helping fulfill another personal goal.
Computer aided design(CAD) has been around along time but I have been interested in exploring approaches to the next step, computer autonomous design. Regardless of the current or future object creation method, whether it be manufactured or materialized, I believe a universal approach to autonomous design will be needed to advance the human condition. This application has helped me explore and think about practical approaches that might be possible right now in autonomous design and I hope to continue this work by developing new tools and techniques for the new CAD, Computer Autonomous Design.
### Notes
More information can be found at this [Hard Kernel forum thread](https://forum.odroid.com/viewtopic.php?f=53&t=43948)
Due to the number of possibilities, no pre-compiled case stls are included.
“tol”, located at the bottom of the Adjustments Tab, is a tolerance fitment adjustment for the snap, fitted, round and hex tops. Adjust accordingly if the tops are too tight or loose.
### Case Designs and Styles
The case naming convention for standard cases in the configuration file follow the basic form of “sbc”_”design”_”style” e.g. c4_shell or c4_tray_vu5.
#### Last Case Count 457
##### Hardkernel - 194
**Odorid-C1+ cases** - 16 : c1+_shell, c1+_panel, c1+_panel_lcd3.5, c1+_desktop_lcd3.5, c1+_stacked, c1+_tray, c1+_tray_sides, c1+_tray_vu5,
c1+_tray_vu7, c1+_shell_boombox, c1+_panel_boombox, c1+_tray_boombox, c1+_round, c1+_hex, c1+_snap, c1+_fitted
**Odorid-C2 cases** - 17 : c2_shell, c2_panel, c2_panel_lcd3.5, c2_desktop_lcd3.5, c2_stacked, c2_tray, c2_tray_sides, c2_tray_vu5,
c2_tray_vu7, c2_shell_boombox, c2_panel_boombox, c2_deskboom_lcd3.5, c2_tray_boombox, c2_round, c2_hex, c2_snap, c2_fitted
**Odorid-C4 cases** - 17 : c4_shell, c4_panel, c4_panel_lcd3.5, c4_desktop_lcd3.5, c4_stacked, c4_tray, c4_tray_sides, c4_tray_vu5,
c4_tray_vu7, c4_shell_boombox, c4_panel_boombox, c4_deskboom_lcd3.5, c4_tray_boombox, c4_round, c4_hex, c4_snap, c4_fitted
**Odorid-HC4 cases** - 15 : hc4_shell, hc4_shell_drivebox2.5, hc4_shell_drivebox2.5v, hc4_shell_drivebox3.5, hc4_panel, hc4_stacked
, hc4_tray, hc4_tray_sides, hc4_tray_vu5, hc4_tray_vu7, hc4_tray_drivebox2.5, hc4_round, hc4_hex, hc4_snap, hc4_fitted
**Odorid-N1 cases** - 11 : n1_shell, n1_panel, n1_stacked, n1_tray, n1_tray_sides, n1_tray_vu5, n1_tray_vu7, n1_round, n1_hex, n1_snap, n1_fitted
**Odorid-N2 cases** - 9 : n2_panel, n2_tray, n2_tray_sides, n2_tray_vu5, n2_tray_vu7, n2_round, n2_hex, n2_snap, n2_fitted
**Odorid-N2+ cases** - 9 :n2+_panel, n2+_tray, n2+_tray_sides, n2+_tray_vu5, n2+_tray_vu7, n2+_round, n2+_hex, n2+_snap, n2+_fitted
**Odorid-N2L cases** - 9 :n2l_shell, n2l_panel, n2l_stacked, n2l_tray, n2l_tray_sides, n2l_tray_vu5, n2l_tray_vu7, n2l_snap, n2l_fitted
**Odorid-N2LQ cases** - 9 :n2lq_shell, n2lq_panel, n2lq_stacked, n2lq_tray, n2lq_tray_sides, n2lq_tray_vu5, n2lq_tray_vu7, n2lq_snap, n2lq_fitted
**Odorid-M1S cases** - 12 : m1s_shell, m1s_shell_nvme, m1s_shell_ups, m1s_panel, m1s_stacked, m1s_tray, m1s_tray_ups, m1s_tray_vu5, m1s_tray_vu7, m1s_tray_sides, m1s_snap, m1s_fitted
**Odorid-M1 cases** - 12 : m1_panel, m1_tray, m1_tray_drive, m1_tray_sides, m1_tray_vu5, m1_tray_vu7, m1_snap, m1_fitted, m1_fitted_drivebox2.5, m1_fitted_drivebox3.5, m1_fitted_pizzabox, m1_fitted_drivebox3.5v
**Odorid-XU4 cases** - 11 : xu4_shell, xu4_panel, xu4_stacked, xu4_tray, xu4_tray_sides, xu4_tray_vu5, xu4_tray_vu7, xu4_round, xu4_hex, xu4_snap, xu4_fitted
**Odorid-XU4Q cases** - 11 : xu4q_shell, xu4q_panel, xu4q_stacked, xu4q_tray, xu4q_tray_sides, xu4q_tray_vu5, xu4q_tray_vu7, xu4q_round, xu4q_hex, xu4q_snap, xu4q_fitted
**Odroid-H2 cases** - 17 : h2_shell, h2_lowboy, h2_lowboy_router, h2_shell_router, h2_shell_router-ssd, h2_panel, h2_stacked, h2_tray, h2_tray_sides, h2_tray_vu5, h2_tray_vu7, h2_tray_router, h2_router_station, h2_round, h2_hex, h2_snap, h2_fitted
**Odroid-H3 cases** - 18 : h3_shell, h3_shell-internalfan, h3_lowboy, h3_lowboy_router, h3_shell_router, h3_shell_router-ssd, h3_panel, h3_stacked, h3_tray, h3_tray_sides, h3_tray_vu5, h3_tray_vu7, h3_tray_router, h3_router_station, h3_round, h3_hex, h3_snap, h3_fitted
**Odroid-Show2** cases - 1 : show2_shell
##### Pine64 - 24
**Rock64** - 9 : rockp64_shell, rock64_panel, rock64_stacked, rock64_tray, rock64_tray_sides, rock64_round, rock64_hex, rock64_snap, rock64_fitted
**RockPro64** - 9 : rockpro64_shell, rockpro64_panel, rockpro64_stacked, rockpro64_tray, rockpro64_tray_sides, rockpro64_round, rockpro64_hex, rockpro64_snap, rockpro64_fitted
**Quartz64a** - 2 : quartz64a_shell, quartz64a_panel
**Quartz64b** - 2 : quartz64b_shell, quartz64b_panel
**h64b** - 2 : h64b_shell, h64b_panel
**star64** - 1 : star64_shell
##### Raspberry PI - 72
**RPIzero** - 9 : rpizero_shell, rpizero_panel, rpizero_stacked, rpizero_tray, rpizero_tray_sides, rpizero_round, rpizero_hex, rpizero_snap, rpizero_fitted
**RPIzero2w+** - 9 : rpizero2w_shell, rpizero2w_panel, rpizero2w_stacked, rpizero2w_tray, rpizero2w_tray_sides, rpizero2w_round, rpizero2w_hex, rpizero2w_snap, rpizero2w_fitted
**RPI1a+** - 9 : rpi1a+_shell, rpi1a+_panel, rpi1a+_stacked, rpi1a+_tray, rpi1a+_tray_sides, rpi1a+_round, rpi1a+_hex, rpi1a+_snap, rpi1a+_fitted
**RPI1b+** - 9 : rpi1b+_shell, rpi1b+_panel, rpi1b+_stacked, rpi1b+_tray, rpi1b+_tray_sides, rpi1b+_round, rpi1b+_hex, rpi1b+_snap, rpi1b+_fitted
**RPI3a+** - 9 : rpi3a+_shell, rpi3a+_panel, rpi3a+_stacked, rpi3a+_tray, rpi3a+_tray_sides, rpi3a+_round, rpi3a+_hex, rpi3a+_snap, rpi3a+_fitted
**RPI3b** - 9 : rpi3b_shell, rpi3b_panel, rpi3b_stacked, rpi3b_tray, rpi3b_tray_sides, rpi3b_round, rpi3b_hex, rpi3b_snap, rpi3b_fitted
**RPI3b+** - 9 : rpi3b+_shell, rpi3b+_panel, rpi3b+_stacked, rpi3b+_tray, rpi3b+_tray_sides, rpi3b+_round, rpi3b+_hex, rpi3b+_snap, rpi3b+_fitted
**RPI4b** - 9 : rpi4b_shell, rpi4b_panel, rpi4b_stacked, rpi4b_tray, rpi4b_tray_sides, rpi4b_round, rpi4b_hex, rpi4b_snap, rpi4b_fitted
##### Nivida - 1
**Jetson Nano** - 9 : jetsonnano_shell, jetsonnano_panel, jetsonnano_stacked, jetsonnano_tray, jetsonnano_tray_sides, jetsonnano_round, jetsonnano_hex, jetsonnano_snap, jetsonnano_fitted
##### Radxa - 37
**ROCK 4b+** - 9 : rock4b+_shell, rock4b+_panel, rock4b+_stacked, rock4b+_tray, rock4b+_tray_sides, rock4b+_round, rock4b+_hex, rock4b+_snap, rock4b+_fitted
**ROCK 4c** - 9 : rock4c_shell, rock4c_panel, rock4c_stacked, rock4c_tray, rock4c_tray_sides, rock4c_round, rock4c_hex, rock4c_snap, rock4c_fitted
**ROCK 4c+** - 9 : rock4c+_shell, rock4c+_panel, rock4c+_stacked, rock4c+_tray, rock4c+_tray_sides, rock4c+_round, rock4c+_hex, rock4c+_snap, rock4c+_fitted
**ROCK 5b** - 10 : rock5b_shell,rock5b_shell-v1.3, rock5b_panel, rock5b_stacked, rock5b_tray, rock5b_tray_sides, rock5b_round, rock5b_hex, rock5b_snap, rock5b_fitted
##### Khadas - 45
**Vim1** - 9 : vim1_shell, vim1_panel, vim1_stacked, vim1_tray, vim1_tray_sides, vim1_round, vim1_hex, vim1_snap, vim1_fitted
**Vim2** - 9 : vim2_shell, vim2_panel, vim2_stacked, vim2_tray, vim2_tray_sides, vim2_round, vim2_hex, vim2_snap, vim2_fitted
**Vim3** - 9 : vim3_shell, vim3_panel, vim3_stacked, vim3_tray, vim3_tray_sides, vim3_round, vim3_hex, vim3_snap, vim3_fitted
**Vim3l** - 9 : vim3l_shell, vim3l_panel, vim3l_stacked, vim3l_tray, vim3l_tray_sides, vim3l_round, vim3l_hex, vim3l_snap, vim3l_fitted
**Vim4** - 9 : vim4_shell, vim4_panel, vim4_stacked, vim4_tray, vim4_tray_sides, vim4_round, vim4_hex, vim4_snap, vim4_fitted
##### Asus - 36
**Tinkerboard** - 9 : tinkerboard_shell, tinkerboard_panel, tinkerboard_stacked, tinkerboard_tray, tinkerboard_tray_sides, tinkerboard_round, tinkerboard_hex, tinkerboard_snap, tinkerboard_fitted
**Tinkerboard S** - 9 : tinkerboard-s_shell, tinkerboard_panel, tinkerboard-s_stacked, tinkerboard-s_tray, tinkerboard-s_tray_sides, tinkerboard-s_round, tinkerboard-s_hex, tinkerboard-s_snap, tinkerboard-s_fitted
**Tinkerboard 2/2S** - 9 : tinkerboard-2_shell, tinkerboard-2_panel, tinkerboard-2_stacked, tinkerboard-2_tray, tinkerboard-2_tray_sides, tinkerboard-2_round, tinkerboard-2_hex, tinkerboard-2_snap, tinkerboard-2_fitted
**Tinkerboard R2/R2S** - 9 : tinkerboard-r2_shell, tinkerboard-r2_panel, tinkerboard-r2_stacked, tinkerboard-r2_tray, tinkerboard-r2_tray_sides, tinkerboard-r2_round, tinkerboard-r2_hex, tinkerboard-r2_snap, tinkerboard-r2_fitted
##### Orange PI - 34
**OPI 5** - 7 : opi5_shell, opi5_panel, opi5_stacked, opi5_tray, opi5_tray_sides, opi5_snap, opi5_fitted
**OPI Zero/ZeroPlus** - 9 : opizero_shell, opizero_panel, opizero_stacked, opizero_tray, opizero_tray_sides, opizero_round, opizero_hex, opizero_snap, opizero_fitted
**OPI Zero2** - 9 : opizero2_shell, opizero2_panel, opizero2_stacked, opizero2_tray, opizero2_tray_sides, opizero2_round, opizero2_hex, opizero2_snap, opizero2_fitted
**OPI R1** - 1 : opir1_shell
**OPI R1PlusLTS** - 9 : opir1plus_lts_shell, opir1plus_lts_panel, opir1plus_lts_stacked, opir1plus_lts_tray, opir1plus_lts_tray_sides, opir1plus_lts_round, opir1plus_lts_hex, opir1plus_lts_snap, opir1plus_lts_fitted
##### Libre Computer - 0
**lepotato** - 0:
**sweetpotato** - 0:
**tirtium-h2+** - 0:
**tritium-h3** - 0:
**tritium-h5** - 0:
**solitude** - 0:
**alta** - 0:
##### Sipeed - 1
**licheerv+dock** - 0 :
##### StarFive - 14
**visionfive2** - 7 : visionfive2_shell, visionfive2_panel, visionfive2_stacked, visionfive2_tray, visionfive2_tray_sides, visionfive2_snap, visionfive2_fitted
**visionfive2q** - 7 : visionfive2q_shell, visionfive2q_panel, visionfive2q_stacked, visionfive2q_tray, visionfive2q_tray_sides, visionfive2q_snap, visionfive2q_fitted
### Accessory Schema
The schema for case accessories is documented in the beginning of the file sbc_case_builder_accessories.cfg. There is one fixed entry that is the accessory set name followed by an unlimited number of accessory entries each containing 15 entries.
```
schema:
"accessory_name",
"class","type",loc_x,loc_y,loc_z,face,rotation[x,y,z],parametrics[association,x,y,z],size_x,size_y,size_z,data_1,data_2,"data_3",data_4[]
```
### Accessories Entries
There are 6 classes, “add1”,“sub”,”suball”,”add2”,”model”,”platter” and all use the same command format for various “type”.
```
"class","type",loc_x,loc_y,loc_z,size_x,size_y,size_z,"face",rotation[],parametrics[],data_1,data_2,"data_3",data_4[]
```
e.g.
```
p
a
r
r a
o m
t e s s s d d d d
c l l l a t i i i a a a a
l t o o o f t r z z z t t t t
a y c c c a i i e e e a a a a
s p c o c
s, e, x, y, z, e, n, s, x,y,z,1,2,3,4
"sub","fan",10,10,24.5,"top",[0,0,0],["sbc-case_z",true,true,true],40,0,6,2,0,"",0]
```
Every type, regardless of its class, uses a basic set of variables
`(loc_x,loc_y,loc_z,”face”,rotation[],parametrics[])`
but each type doesnt necessarily use all available data fields
`(size_x,size_y,size_z,data_1,data_2,”data_3”,data_4[])`
The parametric array specifies the axis to enable for associated parametric positoning. An accessory can be associated with the sbc position("sbc"), case offset("case"),multi-associated which use sbc xy postion and case z offset(sbc-case_z) or uses absolute values if all axises are false.
#### classes: add1, sub, suball, add2, model, platter
Class “add1” and “add2” are used to add geometry to the case. The difference is when the addition occurs. “add1” happens at the beginning when the core case geometry is created and add2 happens after all subtractions have occurred. “suball” is used to affect all faces of a case, not just “face”. The “face” is the case piece that will be effected by the addition or subtraction. The "model" class is for placing supporting accessories in the model view. e.g. hard drives, fans. The "platter" class is for adding supporting accessories to the print platter.
**additive type:**
circle, rectangle, slot, text, art, standoff, batt_holder, uart_holder, hd_holder, hd_holes, hd_vertright_holes, hc4_oled_holder, access_port, button, pcb_holder, boom_grill, boom_speaker_holder
**subtractive type:**
circle, rectangle, slot, text, art, punchout, vent, fan, hd_holes, hd_vertleft_holes, hd_vertright_holes, microusb, sphere
**model type:**
uart_strap, fan_cover, hd25, hd35, hc4_oled, feet, access_cover, net_card, hk35_lcd, hk_boom, boom_speaker, boom_vring, hk_uart
**platter type:**
uart_strap, fan_cover, access_cover, button_top, boom_vring
#### Shared add and sub “type” commands
**circle**
```
DESCRIPTION: circlular geometry.
USES: size_x=dia, size_z=height
```
**rectangle**
```
DESCRIPTION: rectangular geometry with individual defined corner fillets. Radius1 is lower left corner then moves clockwise.
USES: size_x, size_y, size_z, data_4=[radius1, radius2, radius3, radius4]
```
**slot**
```
DESCRIPTION: slot geometry.
USES: size_x=diameter, size_y=length, size_z=height
```
**text**
```
DESCRIPTION: raised or sunk text
USES: data_1=size, data_3="text"
```
**art**
```
DESCRIPTION: art work in dxf or svg format
USES: data_1=scale, data_2=height, data_3=file
```
**keyhole**
```
DESCRIPTION: enclosed keyhole
USES: data4=[head_dia, slot_width, slot_length, floor_thick]
```
#### Add class only “types”
**uart_holder**
```
DESCRIPTION: console uart holder
USES: none
```
**batt_holder**
```
DESCRIPTION: rtc battery holder
USES: none
```
**standoff**
```
DESCRIPTION: user defined standoff
USES: data_4=
[ 6.75, // radius
5, // height
3.6, // holesize
10, // supportsize
4, // supportheight
1, // 0=none, 1=countersink, 2=recessed hole, 3=nut holder, 4=blind hole
0, // standoff style 0=hex, 1=cylinder
0, // enable reverse standoff
0, // enable insert at top of standoff
4.5, // insert hole dia. mm
5.1] // insert depth mm
```
**hd_holder**
```
DESCRIPTION: double stacked holder for 2.5 and 3.5 drives
USES: data_1=2.5 or 3.5, data_3=”portrait” or “landscape”
```
**hd_vertleft_holder**
```
DESCRIPTION: vertical left side holder for 2.5 and 3.5 drives
USES: data_1=2.5 or 3.5, data_3=”portrait” or “landscape”
```
**hd_vertright_holder**
```
DESCRIPTION: vertical right side holder for 2.5 and 3.5 drives
USES: data_1=2.5 or 3.5, data_3=”portrait” or “landscape”
```
**hc4_oled_holder**
```
DESCRIPTION: hc4 oled holder
USES: size_z=floorthick
```
**access_port**
```
DESCRIPTION: bottom access for sd and emmc
USES: size_z=floorthick, data_3=”portrait” or “landscape”
```
**button**
```
DESCRIPTION: button top and plunger
USES: size_x=diameter,size_z=height, data_3=”reccess”
```
**pcb_holder**
```
DESCRIPTION: pcb bottom edge holder
USES: size_x=pcb_x,size_y=pcb_y,size_z=pcb_z, data_1=wall_thick
```
**boom_grill**
```
DESCRIPTION: hk boom bonnet grill covers
USES: data_3="flat", "dome", "frame"
```
**boom_speaker_holder**
```
DESCRIPTION: hk boom bonnet speaker friction holder
USES: data_1=tolorence
```
**nut_holder**
```
DESCRIPTION: nut holder
USES: size_x=top diameter or x size in mm, size_y=bottom diameter or y size in mm, size_z=holder height in mm, data_0="m2" or "m2.5" or "m3" or "m4", data_1="default" or "sloped" or "trap"
```
#### Sub class only “types”
**punchout**
```
DESCRIPTION: punchout in rectangle, round or slot shape
USES: size_x=width, size_y=depth, data_1=gap, size_z=thick, data_2=fillet, data_3="rectangle","round" or "slot"
```
**vent**
```
DESCRIPTION: horizontal or vertical vent openings
USES: size_x=open_width, size_y=open_length, size_z=thick, data_1=rows, data_2=columns,
data_3=orientation("vertical","horizontal"), data_4=gap
```
**vent_hex**(cells_x, cells_y, cell_size, cell_spacing, orientation)
```
DESCRIPTION: horizontal or vertical hex vent openings
USES: size_x=cells_x, size_y=cells_y, size_z=thick, data_1=cell_size, data_2=cell_spacing,
data_3=orientation("vertical","horizontal")
```
**fan**
```
DESCRIPTION: fan opening
USES: size_x=size, size_z=thick, date_1=style(0=open, 1=fan_1, 2=fan_2, 3=fan_hex)
```
**hd_holes**
```
DESCRIPTION: bottom hole pattern for 2.5 or 3.5 drives
USES: data_1=2.5 or 3.5, data_2=thick, data_3=”portrait” or “landscape”
```
**hd_vertleft_holes**
```
DESCRIPTION: bottom hole pattern for 2.5 or 3.5 drives
USES: data_1=2.5 or 3.5, data_2=thick, data_3=”portrait” or “landscape”
```
**hd_vertright_holes**
```
DESCRIPTION: bottom hole pattern for 2.5 or 3.5 drives
USES: data_1=2.5 or 3.5, data_2=thick, data_3=”portrait” or “landscape”-component mask(incomplete)
```
**microusb**
```
DESCRIPTION: micro usb opening
USES: none
```
**sphere**
```
DESCRIPTION: sphere subtraction
USES: size_x=diameter
```
#### Model class “types”
**uart_strap**
```
DESCRIPTION: console uart holder strap
USES: none
```
**fan_cover**
```
DESCRIPTION: cover for fan hole opening
USES: size_x=fan size, size_z=thick, data_1=style (0=open, 1=fan_1, 2=fan_2, 3=fan_hex)
```
**hd25**
```
DESCRIPTION: 2.5 hard drive
USES: data_1=height
```
**hd35**
```
DESCRIPTION: 3.5 hard drive
USES: none
```
**hc4_oled**
```
DESCRIPTION: hc4_oled model
USES: none
```
**feet**
```
DESCRIPTION: case feet
USES: size_x=diameter, size_z=height
```
**access_cover**
```
DESCRIPTION: bottom access cover for sd and emmc
USES: size_z=floorthick, data_3=”portrait” or “landscape”
```
**button_top**
```
DESCRIPTION: button top and plunger
USES: size_x=diameter,size_z=height, data_3=”reccess”
```
**h2_netcard**
```
DESCRIPTION: h2 network card model
USES: none
```
**hk_lcd35**
```
DESCRIPTION: hk 3.5 inch lcd model
USES: none
```
**hk_boom**
```
DESCRIPTION: hk stereo boom bonnet model
USES: data_1=speakers(true or false), data_3=”front” or "rear"
```
**boom_speaker**
```
DESCRIPTION: hk stereo boom bonnet speaker
USES: data_1=pcb(true or false), data_3=”left” or "right"
```
**hk_speaker**
```
DESCRIPTION: hk speaker model
USES: none
```
**boom_vring**
```
DESCRIPTION: hk stereo boom bonnet volume wheel extention
USES: data_1=tolerence
```
**hk_uart**
```
DESCRIPTION: hk console uart model
USES: none
```
**h3_port_extender**
```
DESCRIPTION: h3 usb port extender model
USES: data_3="header" or "remote"
```
**hk_pwr_button**
```
DESCRIPTION: hk power button model
USES: none
```
**dsub**
```
DESCRIPTION: d-sub connectors
USES: data4=[pin, type("male" or "female"), floor_thick]
```
**vent_panel_hex**
```
DESCRIPTION: cover for vent opening, honeycomb pattern
USES: size_x=x, size_y=y, size_z=thick,
data1=cell_size, data2=cell_spacing,
data3="x", "y", "none", or "default", data4=border
```
#### Platter class “types”
**uart_strap**
```
DESCRIPTION: console uart holder strap
USES: none
```
**fan_cover**
```
DESCRIPTION: cover for fan hole opening
USES: size_x=40 or 80, size_z=thick
```
**access_cover**
```
DESCRIPTION:bottom access cover for sd and emmc
USES: size_z=floorthick, data_3=”portrait” or “landscape”
```
**button_top**
```
DESCRIPTION: button top and plunger
USES: size_x=diameter,size_z=height, data_3=”reccess”
```
**boom_vring**
```
DESCRIPTION: hk stereo boom bonnet volume wheel extention
USES: data_1=tolerence
```
**vent_panel_hex**
```
DESCRIPTION: cover for vent opening, honeycomb pattern
USES: size_x=x, size_y=y, size_z=thick,
data1=cell_size, data2=cell_spacing,
data3="x", "y", "none", or "default", data4=border
```

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 MiB

After

Width:  |  Height:  |  Size: 3.8 MiB

1
SBC_Model_Framework Submodule

Submodule SBC_Model_Framework added at 9c530aa942

View File

@@ -0,0 +1,17 @@
// 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:83`
// Also copy the output from the second Echo command into the list of case acceessory
// sets in `sbc_case_builder.scad:164`
include <./SBC_Model_Framework/sbc_models.cfg>;
include <./sbc_case_builder_accessories.cfg>;
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);
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);

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

Binary file not shown.

145
lib/access_panel.scad Normal file
View File

@@ -0,0 +1,145 @@
/*
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_port(size, orientation)
access_cover(size, orientation)
*/
/*
NAME: access_port
DESCRIPTION: creates opening and structure for access openings
TODO: none
USAGE: access_port(size[], orientation)
size[0] = size_x
size[1] = size_y
size[2] = floor thickness
orientation = "landscape", "portrait"
*/
module access_port(size, orientation) {
floorthick = size[2];
adj = .01;
$fn = 90;
if(orientation == "portrait") {
difference() {
union() {
cube([size[0], size[1], size[2]]);
// access panel support
translate([(size[0]/2)+.25, size[1]-6.5, 0]) cylinder(d=9, h=floorthick+(adj*2)+5);
translate([(size[0]/2)-10, size[1]-11, floorthick-adj]) cube([20, 9.5, floorthick]);
translate([1, 0, floorthick-adj]) cube([size[0]-2, 5, 4.5]);
}
// access opening
translate([.5, 6, -adj]) cube([size[0]-1.15, size[1]-17, floorthick+(adj*2)]);
translate([(size[0]/2)-5, size[1]-12, -adj]) slab([10.5, 5.5, floorthick], 5.5);
translate([(size[0]/2)+.25, size[1]-6.5, floorthick+2])
cylinder(r=3.2, h=floorthick+(adj*2)+5, $fn=6);
translate([(size[0]/2)+.25, size[1]-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[0]-13, 2+adj, floorthick]) cube([7.75, 3, 2.75]);
if(size[0] > 100) {
translate([(size[0]/2), 2+adj, floorthick]) cube([7.75, 3, 2.75]);
}
}
}
if(orientation == "landscape") {
difference() {
union() {
translate([0, -1, 0]) cube([size[0], size[1], size[2]]);
// access panel support
translate([size[0]-6.5, (size[1]/2)-.5, 0]) cylinder(d=9, h=floorthick+(adj*2)+5);
translate([size[0]-11, (size[1]/2)-10.5, floorthick-adj]) cube([9.5, 20, floorthick]);
translate([0, 0, floorthick-adj]) cube([5, size[1]-2, 4.5]);
}
// access opening
translate([6, -.5, -adj]) cube([size[0]-17, size[1]-1.15, floorthick+(adj*3)]);
translate([size[0]-12, (size[1]/2)-6, -adj]) slab([5.5, 10.5, floorthick], 5.5);
translate([size[0]-6.5, (size[1]/2)-.5, floorthick+2]) rotate([0, 0, 30])
cylinder(r=3.2, h=floorthick+(adj*2)+5, $fn=6);
translate([size[0]-6.5, (size[1]/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[1]-13, floorthick]) cube([3, 8.25, 2.75]);
if(size[1] > 100) {
translate([2+adj, (size[1]/2)-(7.75/2)-1.25, floorthick]) cube([3, 7.75, 2.5]);
}
}
}
}
/*
NAME: access_cover
DESCRIPTION: creates covers for access port openings
TODO: none
USAGE: access_port(size[], orientation)
size[0] = size_x
size[1] = size_y
size[2] = floor thickness
orientation = "landscape", "portrait"
*/
module access_cover(size, orientation) {
floorthick = size[2];
adj = .01;
$fn = 90;
if(orientation == "portrait") {
difference() {
union() {
translate([1, 6.25, 0]) cube([size[0]-2.15, size[1]-17.5, floorthick]);
translate([(size[0]/2)-4.75, size[1]-12.25, 0]) slab([10, 5, floorthick], 5);
translate([1, 6.25, floorthick-adj]) cube([size[0]-2.15, 6, floorthick]);
translate([4.25, 3, floorthick]) cube([7.25, 4, 2]);
translate([size[0]-12.75, 3, floorthick]) cube([7.25, 4, 2]);
if(size[0] > 100) {
translate([(size[0]/2)+.25, 3, floorthick]) cube([7.25, 4, 2]);
}
}
translate([(size[0]/2)+.25, size[1]-6.5, -floorthick-adj])
cylinder(d=3.2, h=(floorthick*2)+(adj*2));
translate([(size[0]/2)+.25, size[1]-6.5, -adj])
cylinder(d1=6, d2=3.2, h=floorthick);
}
}
if(orientation == "landscape") {
difference() {
union() {
translate([6.25, 0, 0]) cube([size[0]-17.75, size[1]-2, floorthick]);
translate([size[0]-12.25, (size[1]/2)-5.75, 0]) slab([5, 10, floorthick], 5);
translate([6.25, 0, floorthick-adj]) cube([6,size[1]-2.15, floorthick]);
translate([3.5+adj, 3.25, floorthick]) cube([4, 7.25, 2]);
translate([3.5+adj, size[1]-12.75, floorthick]) cube([4, 7.25, 2]);
if(size[1] > 100) {
translate([3.5+adj, (size[1]/2)-(7.75/2)-1, floorthick]) cube([4, 7.25, 2]);
}
}
translate([size[0]-6.5, (size[1]/2)-.75, -floorthick-adj])
cylinder(d=3.2, h=(floorthick*2)+(adj*2));
translate([size[0]-6.5, (size[1]/2)-.75, -adj])
cylinder(d1=6, d2=3.2, h=floorthick);
}
}
}

34
lib/art.scad Normal file
View File

@@ -0,0 +1,34 @@
/*
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: art
DESCRIPTION: create artwork using dxf or svf
TODO: none
USAGE: art(scale_d1, size_z, type)
scale_d1 = amount to scale file
size_z = floor thickness
type = file name
*/
module art(scale_d1, size_z, type) {
linear_extrude(height = size_z) import(file = type, scale=scale_d1);
}

130
lib/battery.scad Normal file
View File

@@ -0,0 +1,130 @@
/*
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)
module 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() {
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() {
cylinder(d=18.4, h=68);
translate([0,0,65-4]) difference() {
cylinder(d=18.5, h=2);
cylinder(d=17.5, h=3);
}
translate([0,0,65-adj]) difference() {
cylinder(d=18.5, h=3+2*adj);
cylinder(d=14.4, h=3+2*adj);
}
}
}
if(type == "21700") {
difference() {
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);
}

181
lib/button.scad Normal file
View File

@@ -0,0 +1,181 @@
/*
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
button(style, diameter, height)
button_assembly(style, diameter, height)
button_plunger(style, diameter, height)
button_top(style, diameter, height)
button_clip(style)
*/
/*
NAME: button
DESCRIPTION: creates different button bodys and styles
TODO: none
USAGE: button(style, diameter, height)
style = "recess", "cutout"
diameter = diameter of button body
height = height above button
*/
module button(style, size, radius, pad) {
diameter = size[0];
height = size[2];
gap = 1.5;
adj = .01;
$fn = 90;
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([-size[0]+3-gap,-1,-1]) cube([gap*2,2,1+height+2*adj]);
}
translate([0,0,2]) sphere(d=3);
}
translate([0,0,-pad+adj]) cylinder(d=3, h=pad);
}
}
/*
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_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]);
}
}
}
/*
NAME: button_top
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.5,1]);
translate([-.75,-.75,-adj]) cube([5,1.25,1.25]);
}
}
}

38
lib/cable_holder.scad Normal file
View File

@@ -0,0 +1,38 @@
/*
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: cableholder_spacer
DESCRIPTION: creates 18650 and 21700 batteries
TODO: none
USAGE: cableholder_spacer()
*/
module cableholder_spacer() {
size = [9.4,16,6];
$fn = 90;
translate([0,size[2]/2,-5]) rotate([90,0,0])
difference() {
translate([size[0]/2,size[0]/2,0]) rotate([0,0,90]) slot(size[0],size[1],size[2]);
translate([-1,5,3]) rotate([0,90,0]) cylinder(d=3.2, h=12);
translate([-1,7.5,-1]) cube([2,20,9]);
translate([5,9.5,-1]) rotate([0,0,90]) slot(4.5,11,9);
translate([3,20,-1]) rotate([0,0,45]) cube([2,6,9]);
}
}

335
lib/component.scad Normal file
View File

@@ -0,0 +1,335 @@
/*
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(dsubsize, mask = false)
hdmi_a()
header_f(pins, height)
usb_micro()
uart_micro()
rj45()
header(pins)
encl_header_12()
micro2pin()
audio_jack35()
capacitor(diameter, height)
ic(size)
led(ledcolor = "red")
usbc()
*/
/*
NAME: hdmi_a
DESCRIPTION: hdmi-a female model
TODO: none
USAGE: hdmi_a()
*/
module hdmi_a() {
size_x = 14.5;
size_y = 11.5;
translate([0,0,.75])
union() {
difference() {
color("silver") translate([0,0,0]) cube([size_x, size_y, 5.5]);
color("dimgray") translate([.5,-.1,.5]) cube([13.5, 11, 4.5]);
color("silver") translate([0,-.1,0]) rotate ([-90,0,0])
cylinder(d=4, h=13.5,$fn=30);
color("silver") translate([14.5,-.1,0]) rotate ([-90,0,0])
cylinder(d=4, h=13.5,$fn=30);
}
difference() {
union() {
color("silver") translate([0,-.1,0]) rotate ([-90,0,0])
cylinder(d=4, h=11.5,$fn=30);
color("silver") translate([14.5,-.1,0]) rotate ([-90,0,0])
cylinder(d=4, h=11.5,$fn=30);
}
color("silver") translate([0,-.2,0]) rotate ([-90,0,0])
cylinder(d=3, h=13.5,$fn=30);
color("silver") translate([14.5,-.2,0]) rotate ([-90,0,0])
cylinder(d=3, h=13.5,$fn=30);
color("silver") translate([-3,-1,-3]) cube([3,13.5,7.5]);
color("silver") translate([14.5,-1,-3]) cube([3,13.5,7.5]);
color("silver") translate([-1,-1,-3]) cube([16.5,13.5,3]);
}
color("black") translate([2.5,.5,2.25]) cube([9.25,10.5,1.5]);
}
}
// single row female headers
module header_f(pins, height) {
adj = .01;
$fn = 90;
size_x = 2.5;
size_y = 2.5 * pins;
union() {
color("black") cube([size_x, size_y, height]);
for (i=[1:2.5:size_y]) {
color("dimgray") translate ([1,i,height-5+adj]) cube([.64,.64,5]);
}
}
}
// uart micro connector type
module uart_micro() {
size_x = 12.5;
size_y = 5;
union() {
difference() {
union() {
difference () {
color("white") translate([0,0,0]) cube([size_x,size_y,6]);
color("darkgray") translate([.5,.5,2]) cube([11.5,4,6]);
}
}
color("white") translate([12.5,0,-.5]) cube([2,6,7]);
color("white") translate([-1,0,-.5]) cube([1,6,7]);
color("white") translate([-1,5,-.5]) cube([14,2,7]);
color("darkgray") translate([-1,1.5,2]) cube([14,1,7]);
}
for (i=[2.5:2.5:10]) {
color("silver") translate ([i,3,.5]) cube([.6,.6,5]);
}
}
}
// usb2 micro otg
module usb_micro() {
size_x = 7;
size_y = 4.5;
union() {
difference () {
color("silver") translate([0,0,0]) cube([size_x, size_y, 3.5]);
color("dimgray") translate([.5,-.1,.5]) cube([6, 3.5, 2.5]);
color("silver") translate([0,-.1,0]) rotate ([-90,0,0])
cylinder(d=2.5, h=6.5,$fn=30);
color("silver") translate([7,-.1,0]) rotate ([-90,0,0])
cylinder(d=2.5, h=6.5,$fn=30);
}
difference() {
union() {
color("silver") translate([0,-.1,0]) rotate ([-90,0,0])
cylinder(d=2.5, h=4.5,$fn=30);
color("silver") translate([7,-.1,0]) rotate ([-90,0,0])
cylinder(d=2.5, h=4.5,$fn=30);
}
color("silver") translate([0,-.2,0]) rotate ([-90,0,0])
cylinder(d=1.25, h=6.5,$fn=30);
color("silver") translate([7,-.2,0]) rotate ([-90,0,0])
cylinder(d=1.25, h=6.5,$fn=30);
color("silver") translate([-3,-1,-3]) cube([3,6.5,7.5]);
color("silver") translate([7,-1,-3]) cube([3,6.5,7.5]);
color("silver") translate([0,-1,-3]) cube([9,6.5,3]);
color("silver") translate([-1,-1,-3]) cube([9,6.5,3]);
}
color("black") translate([1.5,.5,1.25]) cube([4,3.5,1]);
}
}
// rj45 single socket
module rj45(x,y,rotation,side,pcbsize_z) {
size_x = 15.9;
size_y = 21.3;
place(x,y,0,size_x,size_y,rotation,side)
union() {
difference () {
color("lightgray") translate([0,0,0]) cube([size_x, size_y, 13.5]);
color("darkgray") translate([1.5,-1,1.5]) cube([13, 19.5, 8]);
color("darkgray") translate([5.5,-2,7]) cube([5, 19.5, 5]);
}
color("green") translate([2,-.1,10]) cube([3, 2, 2]);
color("orange") translate([11,-.1,10]) cube([3, 2, 2]);
}
}
// momentary_4.5x4.5x1.5 button
module momentary45x15() {
adj = .01;
$fn = 90;
size_x = 4.5;
size_y = 4.5;
size_z = 3.1;
union() {
color("black") translate([0,0,0]) cube([size_x,size_y,3]);
color("silver") translate([0,0,3-adj]) cube([size_x,size_y,.1]);
color("black") translate([2.25,2.25,3.1-adj]) cylinder(d=2.35,h=1.50);
color("black") translate([.75,.75,3]) sphere(d=.75);
color("black") translate([.75,3.75,3]) sphere(d=.75);
color("black") translate([3.75,.75,3]) sphere(d=.75);
color("black") translate([3.75,3.75,3]) sphere(d=.75);
}
}
// single row headers
module header(pins) {
adj = .01;
$fn = 90;
size_x = 2.54;
size_y = 2.54 * pins;
union() {
color("black") translate([0,0,0]) cube([size_x, size_y, 2.5]);
for (i=[1:2.54:size_y]) {
color("silver") translate ([1,i,2.5]) cube([.64,.64,5]);
}
}
}
// gpio 12 enclosed header
module encl_header_12() {
size_x = 19.5;
size_y = 5.5;
union() {
difference () {
color("black") translate([0,0,0]) cube([size_x,size_y,6.25]);
color ("dimgray") translate ([.5,.5,.6]) cube([18.5,4.5,5.75]);
}
for (i=[4.5:2:16]) {
color("silver") translate ([i,1.5,1]) cube([.5,.5,5]);
color("silver") translate ([i,3.5,1]) cube([.5,.5,5]);
}
}
}
// micro connector type
module micro2pin() {
size_x = 7.5;
size_y = 3.75;
union() {
difference () {
color("white") translate([0,0,0]) cube([size_x,size_y,4.75]);
color("darkgray") translate([1.5,.5,1]) cube([4.5,2.75,6]);
color("white") translate([-.5,.75,-.5]) cube([1,2.5,6]);
color("white") translate([7,.75,-.5]) cube([1,2.5,6]);
color("darkgray") translate([2.25,-.5,1]) cube([3,2,6]);
}
color("silver") translate ([2.75,2,.5]) cube([.6,.6,4]);
color("silver") translate ([4.5,2,.5]) cube([.6,.6,4]);
}
}
// 3.5mm audio plug
module audio_jack35() {
adj = .01;
$fn = 90;
size_x = 6.5;
size_y = 13.5;
difference () {
union() {
color("dimgray") cube([size_x,size_y,3]);
color("dimgray") cube([size_x,5.6,4]);
color("dimgray") translate([size_x/2,0,2.25]) rotate([-90,0,0]) cylinder(d=6, h=size_y);
}
color("gray") translate([size_x/2,0,2.25]) rotate([-90,0,0]) cylinder(d=3, h=size_y+adj);
}
}
// can capacitor
module capacitor(diameter, height) {
adj = .01;
$fn = 90;
color("dimgray") rotate([0,0,0]) cylinder(d=diameter+.5, h=.5);
color("silver") translate([0,0,.5]) cylinder(d=diameter+.5, h=.5);
color("silver") translate([0,0,1]) cylinder(d=diameter, h=height-1);
}
// ic
module ic(size) {
color("dimgray") cube(size);
}
// d-sub connector
module dsub(dsubsize, mask = false) {
adj=.01;
$fn = 90;
if(mask == true) {
union() {
translate([-1, 1, -.75]) rotate([90,0,0]) slab_r([19,10.5,10], [4,4,4,4]);
translate([-4, 1, 4.5]) rotate([90,0,0]) cylinder(h=10, d=3);
translate([21, 1, 4.5]) rotate([90,0,0]) cylinder(h=10, d=3);
}
}
else {
if(dsubsize[0] == 9 && dsubsize[1] == "female") {
translate([8.5,0.4,4.5]) rotate([90,0,0]) import("./stl/db9_f.stl");
}
if(dsubsize[0] == 9 && dsubsize[1] == "male") {
translate([8.5,0.4,4.5]) rotate([90,0,0]) import("./stl/db9_m.stl");
}
}
}
module led(ledcolor = "red") {
color(ledcolor) cube([3,1.5,.4]);
color("silver") cube([.5,1.5,.5]);
color("silver") translate([2.5,0,0]) cube([.5,1.5,.5]);
}
module usbc() {
$fn=90;
adj = .01;
// usbc horizontal type
size_x = 9;
size_y = 7;
dia = 3.5;
diam = 3.75;
rotate([90, 0, 0]) translate([dia/2, dia/2, -size_y]) union() {
difference () {
color("silver")
hull() {
translate([0,0,0]) cylinder(d=dia,h=size_y);
translate([size_x-dia,0,0]) cylinder(d=dia,h=size_y);
}
color("silver") translate([0,0,1])
hull() {
translate([0,0,0]) cylinder(d=3,h=size_y+.2);
translate([size_x-dia,0,0]) cylinder(d=3,h=size_y+.2);
}
}
color("black") translate([0,-1.2/2,.1]) cube([5.5,1.2,6]);
}
}

111
lib/custom.scad Normal file
View File

@@ -0,0 +1,111 @@
/*
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
h3_port_extender(style, mask = false)
h3_port_extender_holder(part, offset)
*/
/*
NAME: h3_port_extender
DESCRIPTION: @mctom's odroid-h3 gpio port extender
TODO: none
USAGE: h3_port_extender(style, mask = false)
style = "header", "remote"
mask = true or false, mask for openings
*/
module h3_port_extender(style, mask = false) {
adj=.01;
$fn = 90;
if(style == "header") {
if(mask == true) {
translate([-20, 6.25, 15]) cube([12, 7.5, 14.75]);
translate([-20, 15.875, 15]) cube([12, 7.5, 14.75]);
translate([-20, 25.375, 15]) cube([12, 7.5, 14.75]);
translate([-20, 17, 32.2]) rotate([0, 90, 0]) cylinder(d=3.5, h=12);
}
else {
// gpio 24 pin front position
color("silver") translate([1.6, 188.5, 84]) rotate([90, 0, 270]) import("stl/h3_port_extender.stl");
// color("dimgrey") translate([-3, 15.75, 0.25]) rotate([90, 180, 180]) import("stl/header_f_2x12_90.stl");
translate([0, 2, 8.25]) rotate([0, 180, 0]) header_f(12,8);
translate([-2.54, 2, 8.25]) rotate([0, 180, 0]) header_f(12,8);
color("dimgrey") translate([-2.5, 0, 29.5]) rotate([270, 0, 90]) import("stl/header_2x2_90.stl");
}
}
if(style == "remote") {
if(mask == true) {
translate([-19, 6.25, 15]) cube([12,7.5,14.75]);
translate([-19, 15.875, 15]) cube([12,7.5,14.75]);
translate([-19, 25.375, 15]) cube([12,7.5,14.75]);
translate([-19, 17, 32.2]) rotate([0,90,0]) cylinder(d=2.5, h=12);
translate([-19, 17, 4.6]) rotate([0,90,0]) cylinder(d=2.5, h=12);
}
else {
// gpio 24 pin front position
color("silver") translate([1.6, 188.5, 84]) rotate([90, 0, 270]) import("stl/h3_port_extender.stl");
color("dimgrey") translate([-2.5, 0, 29.5]) rotate([270, 0, 90]) import("stl/header_2x2_90.stl");
color("dimgrey")translate([9,-.5,12.75]) rotate([0,270,90]) import("stl/header_encl_2x5_90.stl");
translate([2, 2, 14.08]) rotate([0, 90, 0]) header(12);
translate([2, 2, 11.54]) rotate([0, 90, 0]) header(12);
}
}
}
/*
NAME: h3_port_extender
DESCRIPTION: holder for the @mctom's remote h3 port extender
TODO: none
USAGE: h3_port_extender_holder(part, offset)
part = "top","bottom","both"
mask = true or false, mask for openings
*/
module 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);
}
}
}

286
lib/fan.scad Normal file
View File

@@ -0,0 +1,286 @@
/*
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
fan_cover(size, thick)
fan_mask(size, thick, style)
*/
/*
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 mask style
*/
module fan_cover(size, thick, style) {
difference() {
color("grey", 1) slab([size, size, thick], 3);
color("grey", 1) fan_mask(size, thick, style);
}
}
/*
DESCRIPTION: creates heatsink masks for openings
TODO:
USAGE: heatsink_mask(size, thick, style)
size = size of fan
thick = thickness of cover
style = 0="fan_open", 1="fan_1", 2="fan_2", 3"fan_hex"
*/
module fan_mask(size, thick, style) {
hole_pos = size == 30 ? 3 :
size == 40 ? 4 :
size == 50 || size == 60 || size == 70 ? 5 :
size >= 80 ? 3.75 : 3.75;
$fn = 90;
adj = .01;
if(style == 0) {
translate([size/2, size/2, -1]) cylinder(h=thick+2, d=size-1);
// mount holes
translate([size-hole_pos, size-hole_pos, -1]) cylinder(h=thick+2, d=3);
translate([size-hole_pos, hole_pos, -1]) cylinder(h=thick+2, d=3);
translate([hole_pos, size-hole_pos, -1]) cylinder(h=thick+2, d=3);
translate([hole_pos, hole_pos, -1]) cylinder(h=thick+2, d=3);
}
if(style == 1 && size == 30) {
union() {
difference() {
union () {
difference() {
translate([size/2, size/2, -1]) cylinder(h=thick+2, d=size-2);
translate([size/2, size/2, -2]) cylinder(h=thick+4, d=size-8);
}
difference() {
translate([size/2, size/2, -1]) cylinder(h=thick+2, d=size-11);
translate([size/2, size/2, -2]) cylinder(h=thick+4, d=size-17);
}
difference() {
translate([size/2, size/2, -1]) cylinder(h=thick+2, d=size-20);
translate([size/2, size/2, -2]) cylinder(h=thick+4, d=size-25);
}
// mount holes
translate([size-hole_pos, size-hole_pos, -1]) cylinder(h=thick+2, d=3);
translate([size-hole_pos, hole_pos, -1]) cylinder(h=thick+2, d=3);
translate([hole_pos, size-hole_pos, -1]) cylinder(h=thick+2, d=3);
translate([hole_pos, hole_pos, -1]) cylinder(h=thick+2, d=3);
}
translate([5, 4, -2]) rotate([0, 0, 45]) cube([size, 1.5, thick+4]);
translate([4, size-5, -2]) rotate([0, 0, -45]) cube([size, 1.5, thick+4]);
}
}
}
if(style == 1 && size == 40) {
union() {
difference() {
union () {
difference() {
translate([size/2, size/2, -1]) cylinder(h=thick+2, d=size-2);
translate([size/2, size/2, -2]) cylinder(h=thick+4, d=size-8);
}
difference() {
translate([size/2, size/2, -1]) cylinder(h=thick+2, d=size-11);
translate([size/2, size/2, -2]) cylinder(h=thick+4, d=size-17);
}
difference() {
translate([size/2, size/2, -1]) cylinder(h=thick+2, d=size-20);
translate([size/2, size/2, -2]) cylinder(h=thick+4, d=size-25);
}
difference() {
translate([size/2, size/2, -1]) cylinder(h=thick+2, d=size-28);
translate([size/2, size/2, -2]) cylinder(h=thick+4, d=size-35);
}
// mount holes
translate([size-hole_pos, size-hole_pos, -1]) cylinder(h=thick+2, d=3);
translate([size-hole_pos, hole_pos, -1]) cylinder(h=thick+2, d=3);
translate([hole_pos, size-hole_pos, -1]) cylinder(h=thick+2, d=3);
translate([hole_pos, hole_pos, -1]) cylinder(h=thick+2, d=3);
}
translate([6.5, 5.5, -2]) rotate([0, 0, 45]) cube([size, 1.5, thick+4]);
translate([5, size-6, -2]) rotate([0, 0, -45]) cube([size, 1.5, thick+4]);
}
}
}
if(style == 1 && (size == 50 || size == 60 || size == 70)) {
union() {
difference() {
union () {
difference() {
translate([size/2, size/2, -1]) cylinder(h=thick+2, d=size-2);
translate([size/2, size/2, -2]) cylinder(h=thick+4, d=size-14);
}
difference() {
translate([size/2, size/2, -1]) cylinder(h=thick+2, d=size-18);
translate([size/2, size/2, -2]) cylinder(h=thick+4, d=size-30);
}
difference() {
translate([size/2, size/2, -1]) cylinder(h=thick+2, d=size-34);
translate([size/2, size/2, -2]) cylinder(h=thick+4, d=size-46);
}
if(size > 50) {
difference() {
translate([size/2, size/2, -1]) cylinder(h=thick+2, d=size-50);
translate([size/2, size/2, -2]) cylinder(h=thick+4, d=size-59);
}
}
// mount holes
translate([size-hole_pos, size-hole_pos, -1]) cylinder(h=thick+2, d=3);
translate([size-hole_pos, hole_pos, -1]) cylinder(h=thick+2, d=3);
translate([hole_pos, size-hole_pos, -1]) cylinder(h=thick+2, d=3);
translate([hole_pos, hole_pos, -1]) cylinder(h=thick+2, d=3);
}
translate([8.5, 7, -2]) rotate([0, 0, 45]) cube([size > 60 ? size+4 : size+1, 2, thick+4]);
translate([6.5, size-8, -2]) rotate([0, 0, -45]) cube([size > 60 ? size+4 : size+1, 2, thick+4]);
}
}
}
if(style == 1 && size >= 80) {
union() {
difference() {
union () {
difference() {
translate([size/2, size/2, -1]) cylinder(h=thick+2, d=size-2);
translate([size/2, size/2, -2]) cylinder(h=thick+4, d=size-9);
}
difference() {
translate([size/2, size/2, -1]) cylinder(h=thick+2, d=size-14);
translate([size/2, size/2, -2]) cylinder(h=thick+4, d=size-21);
}
difference() {
translate([size/2, size/2, -1]) cylinder(h=thick+2, d=size-26);
translate([size/2, size/2, -2]) cylinder(h=thick+4, d=size-33);
}
difference() {
translate([size/2, size/2, -1]) cylinder(h=thick+2, d=size-38);
translate([size/2, size/2, -2]) cylinder(h=thick+4, d=size-45);
}
difference() {
translate([size/2, size/2, -1]) cylinder(h=thick+2, d=size-50);
translate([size/2, size/2, -2]) cylinder(h=thick+4, d=size-57);
}
difference() {
translate([size/2, size/2, -1]) cylinder(h=thick+2, d=size-62);
translate([size/2, size/2, -2]) cylinder(h=thick+4, d=size-68);
}
if(size == 92) {
difference() {
translate([size/2, size/2, -1]) cylinder(h=thick+2, d=size-74);
translate([size/2, size/2, -2]) cylinder(h=thick+4, d=size-80);
}
difference() {
translate([size/2, size/2, -1]) cylinder(h=thick+2, d=size-85);
translate([size/2, size/2, -2]) cylinder(h=thick+4, d=size-91);
}
}
// mount holes
translate([size-hole_pos, size-hole_pos, -1]) cylinder(h=thick+2, d=3);
translate([size-hole_pos, hole_pos, -1]) cylinder(h=thick+2, d=3);
translate([hole_pos, size-hole_pos, -1]) cylinder(h=thick+2, d=3);
translate([hole_pos, hole_pos, -1]) cylinder(h=thick+2, d=3);
}
translate([6.5, 4.25, -2]) rotate([0, 0, 45]) cube([size*1.2, 3, thick+4]);
translate([4.25, size-6.5, -2]) rotate([0, 0, -45]) cube([size*1.2, 3, thick+4]);
}
}
}
if(style == 2) {
inner = size == 30 ? 24 :
size == 40 ? 32 :
size == 50 ? 40 :
size == 60 ? 50 :
size == 70 ? 61.9 :
size == 80 ? 71.5 :
size * 0.8; // Use 80% as default
rings = size <= 40 ? 4 : 6;
bar_size = size <= 40 ? 2 : 3;
screw_offset = inner / 2;
center_point = size * 0.5;
base_ring_size = size * 0.95;
rings_spacing = size / rings;
translate([size/2, size/2, -1])
union() {
translate([screw_offset, screw_offset, (thick+2)/2]) cylinder(d=3, h=thick+2, center=true);
translate([-screw_offset, screw_offset, (thick+2)/2]) cylinder(d=3, h=thick+2, center=true);
translate([screw_offset, -screw_offset, (thick+2)/2]) cylinder(d=3, h=thick+2, center=true);
translate([-screw_offset, -screw_offset, (thick+2)/2]) cylinder(d=3, h=thick+2, center=true);
difference() {
union() {
for(i=[inner:-rings_spacing:0]) {
difference() {
cylinder(d=base_ring_size - i, h=thick+2);
translate([0, 0, -1]) cylinder(d=base_ring_size - i - (rings_spacing/2), h=thick+4);
}
}
}
translate([0, 0, 2])
union() {
cylinder(d=bar_size*2+0.1, thick+2); // Add a circle to prevent any tiny holes around cross bar
rotate([0, 0, 45]) cube([size, bar_size, thick+2], center=true);
rotate([0, 0, 45]) cube([bar_size, size, thick+2], center=true);
}
}
}
}
if(style == 3) {
hex_pos = size == 30 ? [-11.75, -4.5, 0] :
size == 40 ? [-14, -11.25, 0] :
size == 50 ? [-16, -6.5, 0] :
size == 60 ? [-11, -1.5, 0] :
size == 70 ? [-13, -3.5, 0] :
size >= 80 ? [-8.25, -3.5, 0] : [-9, -4, 0];
union() {
difference () {
translate([1+(size-2)/2, 1+(size-2)/2, -1]) cylinder(h=thick+2, d=size-2);
union() {
difference() {
translate([1+(size-2)/2, 1+(size-2)/2, -1-adj]) cylinder(h=thick+3, d=size-2);
translate(hex_pos) vent_hex(15, 8, thick+4, 12, 2, "horizontal");
}
}
}
}
// mount holes
translate([size-hole_pos, size-hole_pos, -1]) cylinder(h=thick+2, d=3);
translate([size-hole_pos, hole_pos, -1]) cylinder(h=thick+2, d=3);
translate([hole_pos, size-hole_pos, -1]) cylinder(h=thick+2, d=3);
translate([hole_pos, hole_pos, -1]) cylinder(h=thick+2, d=3);
}
}

78
lib/fastener.scad Normal file
View File

@@ -0,0 +1,78 @@
/*
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")
screw(screw_type)
*/
/*
NAME: fan_cover
DESCRIPTION: creates fan covers for fan openings
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: screw
DESCRIPTION: creates screws
TODO: needs improvement
USAGE: screw(screw_type)
screw_type = [d,l,style]
d = thread diameter
l = thread length
style = screw head style, 0 = Mushroom head, 5mm diameter
*/
module screw(screw_type) {
d = screw_type[0];
l = screw_type[1];
style = screw_type[2];
if(style == 0) {
difference() {
translate([ 0, 0, -0.3]) sphere(2.7);
translate([-10,-10,-10]) cube([20,20,10]);
translate([-10,-10, 2]) cube([20,20,10]);
}
}
rotate([180,0,0]) cylinder(d=d, h=l);
}

36
lib/feet.scad Normal file
View File

@@ -0,0 +1,36 @@
/*
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: 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);
}
}

706
lib/hd.scad Normal file
View File

@@ -0,0 +1,706 @@
/*
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
hd_mount(hd, orientation, position, side)
hd25_tab(side)
hd25_vtab(side)
hd35_tab(side)
hd35_vtab(side)
hd_bottom_holes(hd, orientation, position, side, thick)
hd25(height)
hd35()
hdd35_25holder(length)
*/
/*
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");
}
}
}
}
/*
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_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_bottom_holes
DESCRIPTION: creates 2.5" and 3.5" hard drive hole mask for mounting
TODO: none
USAGE: hd_bottom_holes(hd, orientation, position, side, thick)
hd = 2.5, 3.5
orientation = "portrait", "landscape"
position = "vertical", "horizontal"
side = "left", "right"
thick = floor thickness
*/
module hd_bottom_holes(hd, orientation, position, side, thick) {
adj = .01;
$fn = 90;
if(hd == 2.5) {
if(orientation == "portrait") {
if(position == "vertical") {
if(side == "left") {
translate([-3,14,0]) cylinder(d=3.6,h=thick+(adj*2));
translate([-3,90.6,0]) cylinder(d=3.6,h=thick+(adj*2));
}
else {
// portrait 2.5" bottom screw holes
translate([3,14,0]) cylinder(d=3.6,h=thick+(adj*2));
translate([3,90.6,0]) cylinder(d=3.6,h=thick+(adj*2));
}
}
else {
// portrait 2.5" bottom screw holes
translate([4.07,14,0]) cylinder(d=3.6,h=thick+(adj*2));
translate([4.07,90.6,0]) cylinder(d=3.6,h=thick+(adj*2));
translate([65.79,90.6,0]) cylinder(d=3.6,h=thick+(adj*2));
translate([65.79,14,0]) cylinder(d=3.6,h=thick+(adj*2));
}
}
if(orientation == "landscape") {
if(position == "vertical") {
if(side == "left") {
translate([9.4,-3,0]) cylinder(d=3.6,h=thick+5);
translate([86,-3,0]) cylinder(d=3.6,h=thick+5);
}
else {
echo(side);
translate([9.4,3,0]) cylinder(d=3.6,h=thick+5);
translate([86,3,0]) cylinder(d=3.6,h=thick+5);
}
}
else {
// landscape 2.5" bottom screw holes
translate([9.4,4.07,0]) cylinder(d=3.6,h=thick+(adj*2));
translate([86,4.07,0]) cylinder(d=3.6,h=thick+(adj*2));
translate([86,65.79,0]) cylinder(d=3.6,h=thick+(adj*2));
translate([9.4,65.79,0]) cylinder(d=3.6,h=thick+(adj*2));
}
}
}
if(hd == 3.5) {
if(orientation == "portrait") {
if(position == "vertical") {
if(side == "left") {
translate([-6,28.5,0]) cylinder(d=3.6,h=thick+5);
translate([-6,70.5,0]) cylinder(d=3.6,h=thick+5);
translate([-6,28.5+101.6,0]) cylinder(d=3.6,h=thick+5);
}
else {
// portrait 3.5" bottom screw holes
translate([6,28.5,0]) cylinder(d=3.6,h=thick+5);
translate([6,70.5,0]) cylinder(d=3.6,h=thick+5);
translate([6,28.5+101.6,0]) cylinder(d=3.6,h=thick+5);
}
}
else {
// portrait 3.5" bottom screw holes
translate([3.18,41.28,0]) cylinder(d=3.6,h=thick+(adj*2));
translate([3.18,85.73,0]) cylinder(d=3.6,h=thick+(adj*2));
translate([3.18,117.48,0]) cylinder(d=3.6,h=thick+(adj*2));
translate([98.43,41.28,0]) cylinder(d=3.6,h=thick+(adj*2));
translate([98.43,85.73,0]) cylinder(d=3.6,h=thick+(adj*2));
translate([98.43,117.48,0]) cylinder(d=3.6,h=thick+(adj*2));
}
}
if(orientation == "landscape") {
// landscape 3.5" bottom screw holes
translate([29.52,3.18,0]) cylinder(d=3.6,h=thick+(adj*2));
translate([61.27,3.18,0]) cylinder(d=3.6,h=thick+(adj*2));
translate([105.72,3.18,0]) cylinder(d=3.6,h=thick+(adj*2));
translate([29.52,98.43,0]) cylinder(d=3.6,h=thick+(adj*2));
translate([61.27,98.43,0]) cylinder(d=3.6,h=thick+(adj*2));
translate([105.72,98.43,0]) cylinder(d=3.6,h=thick+(adj*2));
}
}
}
/*
NAME: hd25
DESCRIPTION: creates 2.5" hard drive model
TODO: none
USAGE: hd25(height)
height = drive height
*/
module hd25(height) {
hd25_x = 100;
hd25_y = 69.85;
hd25_z = height;
adj = .01;
$fn=90;
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: hd35
DESCRIPTION: creates 3.5" hard drive model
TODO: none
USAGE: hd35()
*/
module hd35() {
hd35_x = 147;
hd35_y = 101.6;
hd35_z = 26.1;
adj = .01;
$fn=90;
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: hd25
DESCRIPTION: 3.5" hdd to 2.5" hdd holder
TODO: none
USAGE: hdd35_25holder(length, width=101.6)
length = length of holder min. 145mm for 3.5" drive
*/
module hdd35_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);
}
}

409
lib/holder.scad Normal file
View File

@@ -0,0 +1,409 @@
/*
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
pcb_holder(size, wallthick)
nut_holder(nut, style, dia_x, dia_y, height)
vu_holder(vu_model, side, vesa, cheight)
*/
/*
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: nut_holder
DESCRIPTION: creates various nut holders
TODO: none
USAGE: nut_holder(nut, style, dia_x, dia_y, height)
nut = "m2", "m2.5", "m3", "m4"
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
*/
module nut_holder(nut, style, dia_x, dia_y, height) {
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
$fn = 180;
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 == "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, 2]) cylinder(d=nuts[2][1]*2/sqrt(3), h=height, $fn=6);
}
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: 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;
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(case_style == "vu5") {
translate([(width/2)+((width-vesa)/2)+(vesa/2)-sidethick,depth-39,
case_z+80]) rotate([90-vu_rotation[0],180,0])
slab_r([((width-vesa)/2)+4.5,10,sidethick], [.1,.1,3,3]);
translate([(width/2)+((width-vesa)/2)+(vesa/2)-sidethick,depth-26,
case_z+31.5]) rotate([90-vu_rotation[0],180,0])
slab_r([((width-vesa)/2)+4.5,10,sidethick], [.1,.1,3,3]);
translate([(width/2)+((width-vesa)/2)+(vesa/2)-sidethick,depth-41.85-adj,
case_z+79.25]) rotate([90-vu_rotation[0],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,depth-28.85-adj,
case_z+30.75]) rotate([90-vu_rotation[0],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(case_style == "vu7") {
translate([(width/2)+((width-vesa)/2)+(vesa/2)-sidethick-1,depth-49.40,
case_z+vu7_height-15]) rotate([90-vu_rotation[0],180,0])
slab_r([((width-vesa)/2)+12,10,sidethick], [.1,.1,3,3]);
translate([(width/2)+((width-vesa)/2)+(vesa/2)-sidethick-1,depth-23.60,
case_z+22.5]) rotate([90-vu_rotation[0],180,0])
slab_r([((width-vesa)/2)+12,10,sidethick], [.1,.1,3,3]);
translate([(width/2)+((width-vesa)/2)+(vesa/2)-sidethick,depth-52.25,
case_z+vu7_height-15.75]) rotate([90-vu_rotation[0],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,depth-26.5,
case_z+21.8]) rotate([90-vu_rotation[0],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(case_style == "vu5") {
translate([-((width-vesa)/2)+(width/2)-(vesa/2)-3.5-adj,depth-36.4,
case_z+70]) rotate([90+vu_rotation[0],0,0])
slab_r([((width-vesa)/2)+4,10, sidethick], [.1,.1,3,3]);
translate([-((width-vesa)/2)+(width/2)-(vesa/2)-3.5-adj,depth-23.5,
case_z+22]) rotate([90+vu_rotation[0],0,0])
slab_r([((width-vesa)/2)+4,10,sidethick], [.1,.1,3,3]);
translate([-((width-vesa)/2)+(width/2)-(vesa/2)-3.5-adj,depth-39.35+adj,
case_z+69.25]) rotate([90+vu_rotation[0],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-26.4+adj,
case_z+21.25]) rotate([90+vu_rotation[0],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(case_style == "vu7") {
translate([-((width-vesa)/2)+(width/2)-(vesa/2)-4.25-adj,depth-46.85,
case_z+vu7_height-24.5]) rotate([90+vu_rotation[0],0,0])
slab_r([((width-vesa)/2),10, sidethick], [.1,.1,3,3]);
translate([-((width-vesa)/2)+(width/2)-(vesa/2)-4.25-adj,depth-21,
case_z+13]) rotate([90+vu_rotation[0],0,0])
slab_r([((width-vesa)/2),10,sidethick], [.1,.1,3,3]);
translate([-((width-vesa)/2)+(width/2)-(vesa/2)-4-adj,depth-49.75+adj,
case_z+vu7_height-25.25]) rotate([90+vu_rotation[0],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)-4-adj,depth-23.75+adj,
case_z+12.25]) rotate([90+vu_rotation[0],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(case_style == "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([90-vu_rotation[0],180,0]) cylinder(d=3, h=sidethick+1);
translate([width/2+(vesa/2)-3,depth-24,
case_z+26.75]) rotate([90-vu_rotation[0],180,0]) cylinder(d=3, h=sidethick+1);
}
// vu7 shape and back cut
if(case_style == "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([90-vu_rotation[0],180,0]) cylinder(d=3, h=sidethick+4);
translate([width/2+(vesa/2)-10,depth-21.25,case_z+18])
rotate([90-vu_rotation[0],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(case_style == "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([90+vu_rotation[0],0,0]) cylinder(d=3, h=sidethick+1);
translate([width/2-(vesa/2)-3,depth-24.25,case_z+26.75])
rotate([90+vu_rotation[0],0,0]) cylinder(d=3, h=sidethick+1);
}
// vu7 shape and back cut
if(case_style == "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([90+vu_rotation[0],0,0]) cylinder(d=3, h=sidethick+4);
translate([width/2-(vesa/2)-10,depth-22.25,case_z+18])
rotate([90+vu_rotation[0],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);
}
}
}
}

74
lib/keyhole.scad Normal file
View File

@@ -0,0 +1,74 @@
/*
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 = false)
keysize[0] = size_x
keysize[1] = size_y
keysize[2] = size_z
mask = true, false enable mask
*/
module keyhole(keysize, mask = false) {
adj=.01;
$fn = 90;
if(mask == true) {
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]);
}
}
}
}

1366
lib/oem_hk.scad Normal file

File diff suppressed because it is too large Load Diff

52
lib/pcb_pad.scad Normal file
View File

@@ -0,0 +1,52 @@
/*
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: pcb_pad
DESCRIPTION: single row pcb pad
TODO: none
USAGE: pcb_pad(pads = 1, style = "round")
pads = # pads
style = "round", "square"
*/
module pcb_pad(pads = 1, style = "round") {
adj = .01;
$fn = 90;
pad_size = 1.25;
size_y = 2.54;
size_x = 2.54 * (pads-1);
union() {
for (i=[0:2.54:size_x]) {
if(style == "round") {
difference() {
color("#fee5a6") translate ([i,0,0]) cylinder(d=pad_size, h=.125);
color("dimgray") translate([i,0,-adj]) cylinder(d=.625, h=.125+2*adj);
}
}
if(style == "square") {
difference() {
color("#fee5a6") translate ([i-pad_size/2,-pad_size/2,0]) cube([pad_size, pad_size, .125]);
color("dimgray") translate([i,0,-adj]) cylinder(d=.625, h=.125+2*adj);
}
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,721 +0,0 @@
/*
SBC Data Library Copyright 2018,2019,2020,2021,2022 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
20190214 Version 1.0.0 sbc data set models "xu4","c2","n1","mc1","hc1","c1+","h2","rpi3b+","a64","rock64","rockpro64"
20190218 Version 1.0.1 Added HK Odroid N2 as "n2"
20200425 Version 1.0.2 Added AtomicPi as "atomicpi"
Updated Odroid n2 sbc data
Added Nvidia Jetson Nano as "jetsonnano"
Updated Odroid h2 sbc data
Added Odroid-C4 as "c4"
Added Odroid-XU4Q as "xu4q"
20200725 Version 1.0.3 Added Odroid-N2+ as "n2+"
20201021 Version 1.0.4 Added Odroid-HC4 as "hc4"
20220202 Version 1.0.5 Added HK Show2
Updated Odroid-HC4 sbc data
raised C4 hdmi, updated Odroid-XU4Q, add type sdcard_i, adjusted C2 usb
20220413 Version 1.0.6 Added Odroid-M1 as m1, adjustments h2, c4 gpio
20220515 Version 1.0.7 Added rockpro64, jetsonnano and other fixes and adjustments
see https://github.com/hominoids/SBC_Case_Builder
Instructions: All measurements from lower left corner of PCB to lower left
corner of component or opening, holes measured to center. All measurements in mm.
PCB orientation is long side of board along the x axis.
Bottom components measured from top left corner to top left corner
of component or opening with the PCB rotated around the x axis.
schema:
"model",pcbsize_x, pcbsize_y, pcbsize_z, pcbcorner_radius, topmax_component_z, bottommax_component_z
pcb_hole1_x, pcb_hole1_y, pcb1_hole_size, pcb_hole2_x, pcb_hole2_y, pcb2_hole_size
pcb_hole3_x, pcb_hole3_y, pcb3_hole_size, pcb_hole4_x, pcb_hole4_y, pcb4_hole_size
pcb_hole5_x, pcb_hole5_y, pcb5_hole_size, pcb_hole6_x, pcb_hole6_y, pcb6_hole_size
pcb_hole7_x, pcb_hole7_y, pcb7_hole_size, pcb_hole8_x, pcb_hole8_y, pcb8_hole_size
pcb_hole9_x, pcb_hole9_y, pcb9_hole_size, pcb_hole10_x, pcb_hole10_y, pcb10_hole_size
soc1size_x, soc1size_y, soc1size_z, soc1loc_x, soc1loc_y, soc1loc_z, soc1_rotation, "soc1_side",
soc2size_x, soc2size_y, soc2size_z, soc2loc_x, soc2loc_y, soc2loc_z, soc2_rotation, "soc2_side",
soc3size_x, soc3size_y, soc3size_z, soc3loc_x, soc3loc_y, soc3loc_z, soc3_rotation, "soc3_side",
soc4size_x, soc4size_y, soc4size_z, soc4loc_x, soc4loc_y, soc4loc_z, soc4_rotation, "soc4_side",
component_x, component_y, component_rotation, "component_side", "component_class","component_type"
component classes and types:
memory - "emmc","emmc_plug","sodimm_5.2","sodimm_9.2"
switch - slide_4x9
button - "momentary_6x6x9","momentary_6x6x4","momentary_6x6x4_90","momentary_4x2x1"
plug - "pwr2.5_5x7.5","pwr5.5_7.5x11.5","pwr5.5_10x10","rtc_micro","audio_micro","uart_micro","molex_4x1","small_encl_satapwr"
usb2 - "single_vert_a","double_stacked_a","micro"
usb3 - double_stacked_a
network - rj45_single
video - "hdmi_a","dp-hdmi_a","mipi_csi","mipi_dsi"
fan - "micro","encl_pmw","encl_pmw_h"
gpio - "encl_header_30","encl_header_12","header_40","header_20"
ic - "ic_2.8x2.8","ic_3x3","ic_3.7x3.7","ic_4x4","ic_4.7x4.7","ic_5x5","ic_5.75x5.75","ic_6x6","ic_6.4x6.4",ic_6.75x6.75",
"ic_7x7","ic_4.3x5.1","ic_5.4x5.3","ic_6.7x8.4","ic_9x9","ic_11x8","ic_13x8","ic_13x9","ic_16x10"
audio - "out-in-spdif","jack_3.5"
storage - "sdcard","sdcard_i","sata_header","sata_power_vrec","sata_encl_power","sata_encl_header","m.2_header","m.2_stud"
combo - "rj45-usb2_double","rj45-usb3_double"
jumper - "header_2x1","header_3x2","header_5x1","header_6x1","header_7x1"
misc - "ir_1","led_3x1.5","lcd_2.2","bat_hold_1"
heatsink - "hc4_oem","c4_oem","c2_oem","c1+_oem","xu4_oem","n1_oem","xu4q_oem","n2_oem","n2+_oem","m1_oem","h2_oem"
pcie - "x4"
jst_ph - number of pins from 2-16
sbc models "c1+","c2","c4","xu4","xu4q","mc1","hc1","hc4","n1","n2","n2+","h2","rpi3b+","a64","rock64","rockpro64","atomicpi","jetsonnano"
*/
sbc_data = [
// Hard Kernel Odroids
["c1+",85,56,1,3.5,17,6, // sbc model, pcb size and component height
3.5,3.5,3,3.5,52.5,3, // pcb holes 1 and 2 location and pcb hole size
61.5,3.5,3,61.5,52.5,3, // pcb holes 3 and 4 location and pcb hole size
9.385,38,3,60.615,18,3, // pcb holes 5 and 6 location and pcb hole size
0,0,0,0,0,0, // pcb holes 7 and 8 location and pcb hole size
0,0,0,0,0,0, // pcb holes 9 and 10 location and pcb hole size
12,12,1.25,34.4,22,0,0,"top", // soc1 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc2 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc3 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc4 size, location, rotation and side
42.28,27.6,90,"bottom","-memory","emmc_plug", // emmc plug location, rotation, side, class and type
40.62,25.25,90,"bottom","memory","emmc", // emmc location, rotation, side, class and type
46.5,40.5,180,"bottom","storage","sdcard", // sdcard location, rotation, side, class and type
6.8,-1,0,"top","usb2","micro", // usb2 otg location, rotation, side, class and type
24.5,-1,0,"top","video","hdmi_a", // hdmi location, rotation, side, class and type
46.5,0,0,"top","plug","pwr2.5_5x7.5", // pwrplug location, rotation, side, class and type
65,2.25,270,"top","network","rj45_single", // ethernet location, rotation, side, class and type
69.61,39.4,270,"top","usb2","double_stacked_a", // usb2 location, rotation, side, class and type
69.61,21.4,270,"top","usb2","double_stacked_a", // usb1 location, rotation, side, class and type
7,50,0,"top","gpio","header_40", // gpio location, rotation, side, class and type
2.5,40.7,90,"top","misc","ir_1", // ir location, rotation, side, class and type
0,15.2,90,"top","plug","uart_micro", // uart location, rotation, side, class and type
14.7,11.86,0,"top","jumper","header_7x1", // jumper location, rotation, side, class and type
16.5,16,0,"top","ic","ic_11x8", // memory location, rotation, side, class and type
16.5,31,0,"top","ic","ic_11x8", // memory location, rotation, side, class and type
55,9,0,"top","ic","ic_5x5", // usbhub 5mm location, rotation, side, class and type
57.7,36,0,"top","ic","ic_5x5", // usbhub 5mm location, rotation, side, class and type
16.5,16,0,"bottom","ic","ic_11x8", // memory location, rotation, side, class and type
16.5,31,0,"bottom","ic","ic_11x8", // memory location, rotation, side, class and type
9.385,38,0,"top","heatsink","c1+_oem"], // heatsink location, rotation, side, class and type
["c2",85,56,1,3.5,17,6, // sbc model, pcb size and component height
3.5,3.5,3,3.5,52.5,3, // pcb holes 1 and 2 location and pcb hole size
61.5,3.5,3,61.5,52.5,3, // pcb holes 3 and 4 location and pcb hole size
9.385,38,3,60.615,18,3, // pcb holes 5 and 6 location and pcb hole size
0,0,0,0,0,0, // pcb holes 7 and 8 location and pcb hole size
0,0,0,0,0,0, // pcb holes 9 and 10 location and pcb hole size
13,13,1.25,32.5,24,0,0,"top", // soc1 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc2 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc3 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc4 size, location, rotation and side
47.09,26.35,90,"bottom","-memory","emmc_plug", // emmc plug location, rotation, side, class and type
45.5,24,90,"bottom","memory","emmc", // emmc location, rotation, side, class and type
46.5,40.5,180,"bottom","storage","sdcard", // sdcard location, rotation, side, class and type
6.8,-1,0,"top","usb2","micro", // usb2 otg location, rotation, side, class and type
18.73,0,90,"top","jumper","header_2x1", // jumper location, rotation, side, class and type
24.5,-1,0,"top","video","hdmi_a", // hdmi location, rotation, side, class and type
46.5,0,0,"top","plug","pwr2.5_5x7.5", // pwrplug location, rotation, side, class and type
65,2.25,270,"top","network","rj45_single", // ethernet location, rotation, side, class and type
69.61,39.6,270,"top","usb2","double_stacked_a", // usb2 location, rotation, side, class and type
69.61,21.6,270,"top","usb2","double_stacked_a", // usb1 location, rotation, side, class and type
7,50,0,"top","gpio","header_40", // gpio location, rotation, side, class and type
2.5,40.7,90,"top","misc","ir_1", // ir location, rotation, side, class and type
0,15.2,90,"top","plug","uart_micro", // uart location, rotation, side, class and type
14.7,11.86,0,"top","jumper","header_7x1", // jumper location, rotation, side, class and type
17,18.25,0,"top","ic","ic_11x8", // memory location, rotation, side, class and type
17,30,0,"top","ic","ic_11x8", // memory location, rotation, side, class and type
55,9,0,"top","ic","ic_5x5", // usbhub 5mm location, rotation, side, class and type
57.7,36,0,"top","ic","ic_5x5", // usbhub 5mm location, rotation, side, class and type
17,18.25,0,"bottom","ic","ic_11x8", // memory location, rotation, side, class and type
17,30,0,"bottom","ic","ic_11x8", // memory location, rotation, side, class and type
9.385,38,0,"top","heatsink","c2_oem"], // heatsink location, rotation, side, class and type
["c4",85,56,1,3.5,18,6, // sbc model, pcb size and component height
3.5,3.5,3,3.5,52.5,3, // pcb holes 1 and 2 location and pcb hole size
61.5,3.5,3,61.5,52.5,3, // pcb holes 3 and 4 location and pcb hole size
4.19,38.1,3,55.39,18.175,3, // pcb holes 5 and 6 location and pcb hole size
0,0,0,0,0,0, // pcb holes 7 and 8 location and pcb hole size
0,0,0,0,0,0, // pcb holes 9 and 10 location and pcb hole size
14.5,14.5,1.25,32.875,22.4,0,0,"top", // soc1 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc2 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc3 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc4 size, location, rotation and side
39.23,15,0,"bottom","-memory","emmc_plug", // emmc plug location, rotation, side, class and type
36.8,1.34,0,"bottom","memory","emmc", // emmc location, rotation, side, class and type
39.5,39.8,180,"bottom","storage","sdcard_i", // sdcard location, rotation, side, class and type
19.75,-1,0,"top","usb2","micro", // usb2 otg location, rotation, side, class and type
38.5,-1,0,"top","video","hdmi_a", // hdmi location, rotation, side, class and type
6.75,-1,0,"top","plug","pwr5.5_7.5x11.5", // pwrplug location, rotation, side, class and type
65.765,2,270,"top","network","rj45_single", // ethernet location, rotation, side, class and type
70,40,270,"top","usb3","double_stacked_a", // usb3 location, rotation, side, class and type
70,22,270,"top","usb3","double_stacked_a", // usb3 location, rotation, side, class and type
8.15,49,0,"top","gpio","header_40", // gpio location, rotation, side, class and type
2.5,41.25,90,"top","misc","ir_1", // ir location, rotation, side, class and type
0,11.5,90,"top","plug","uart_micro", // uart location, rotation, side, class and type
15.25,10.75,0,"top","jumper","header_7x1", // jumper location, rotation, side, class and type
13.185,17.16,0,"top","ic","ic_13x9", // memory location, rotation, side, class and type
13.185,35.174,0,"top","ic","ic_13x9", // memory location, rotation, side, class and type
56.46,33.38,0,"top","ic","ic_9x9", // usbhub 5mm location, rotation, side, class and type
57.6,9.3,0,"top","ic","ic_5x5", // ethernet 5mm location, rotation, side, class and type
13.185,17.16,0,"bottom","ic","ic_13x9", // memory location, rotation, side, class and type
13.185,35.174,0,"bottom","ic","ic_13x9", // memory location, rotation, side, class and type
4.16,38.175,0,"top","heatsink","c4_oem"], // heatsink location, rotation, side, class and type
["xu4",83,59,1,3.5,17,6, // sbc model, pcb size and component height
3.5,3.5,3,3.5,55.5,3, // pcb holes 1 and 2 location and pcb hole size
79.5,3.5,3,79.5,55.5,3, // pcb holes 3 and 4 location and pcb hole size
79.19,21.82,3,28.2,41.82,3, // pcb holes 5 and 6 location and pcb hole size
0,0,3.3,0,0,3.3, // pcb holes 7 and 8 location and pcb hole size
0,0,0,0,0,0, // pcb holes 9 and 10 location and pcb hole size
14.5,15.75,1.25,59,20,0,0,"top", // soc1 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc2 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc3 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc4 size, location, rotation and side
47.5,13.7,0,"bottom","-memory","emmc_plug", // emmc plug location, rotation, side, class and type
45,0,0,"bottom","memory","emmc", // emmc location, rotation, side, class and type
45.85,5,0,"top","storage","sdcard", // sdcard location, rotation, side, class and type
79,7.15,270,"top","switch","slide_4x9", // switch location, rotation, side, class and type
25.925,52.925,0,"top","button","momentary_6x6x9", // pwrbutton location, rotation, side, class and type
34.5,-1,0,"top","plug","pwr5.5_7.5x11.5", // pwrplug location, rotation, side, class and type
26,0,0,"top","usb2","single_vert_a", // usb2 location, rotation, side, class and type
7.55,41.6,180,"top","usb3","double_stacked_a", // usb3 location, rotation, side, class and type
7.4,0,0,"top","network","rj45_single", // ethernet location, rotation, side, class and type
60,-1,0,"top","video","hdmi_a", // hdmi location, rotation, side, class and type
0,37.8,90,"top","plug","uart_micro", // uart location, rotation, side, class and type
0,25,270,"top","plug","rtc_micro", // rtc location, rotation, side, class and type
27,22,90,"top","fan","micro", // fan location, rotation, side, class and type
35.4,52.25,0,"top","gpio","encl_header_30", // gpio1 location, rotation, side, class and type
76.25,32.5,270,"top","gpio","encl_header_12", // gpio2 location, rotation, side, class and type
43.8,27.25,0,"top","ic","ic_5.75x5.75", // pmic location, rotation, side, class and type
32.5,40.5,0,"top","ic","ic_7x7", // usbhum 7mm location, rotation, side, class and type
11.7,22.8,0,"top","ic","ic_6x6", // nic location, rotation, side, class and type
28.39,42,0,"top","heatsink","xu4_oem"], // heatsink location, rotation, side, class and type
["xu4q",83,59,1,3.5,27,6, // sbc model, pcb size and component height
3.5,3.5,3,3.5,55.5,3, // pcb holes 1 and 2 location and pcb hole size
79.5,3.5,3,79.5,55.5,3, // pcb holes 3 and 4 location and pcb hole size
79.19,21.82,3,28.2,41.82,3, // pcb holes 5 and 6 location and pcb hole size
0,0,3.3,0,0,3.3, // pcb holes 7 and 8 location and pcb hole size
0,0,0,0,0,0, // pcb holes 9 and 10 location and pcb hole size
14.5,15.75,1.25,59,20,0,0,"top", // soc1 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc2 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc3 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc4 size, location, rotation and side
47.5,13.7,0,"bottom","-memory","emmc_plug", // emmc plug location, rotation, side, class and type
45,0,0,"bottom","memory","emmc", // emmc location, rotation, side, class and type
45.85,5,0,"top","storage","sdcard", // sdcard location, rotation, side, class and type
79,7.15,270,"top","switch","slide_4x9", // switch location, rotation, side, class and type
25.925,52.925,0,"top","button","momentary_6x6x9", // pwrbutton location, rotation, side, class and type
34.85,-1,0,"top","plug","pwr5.5_7.5x11.5", // pwrplug location, rotation, side, class and type
26,0,0,"top","usb2","single_vert_a", // usb2 location, rotation, side, class and type
7.55,41.6,180,"top","usb3","double_stacked_a", // usb3 location, rotation, side, class and type
7.4,0,0,"top","network","rj45_single", // ethernet location, rotation, side, class and type
60,-1,0,"top","video","hdmi_a", // hdmi location, rotation, side, class and type
0,37.8,90,"top","plug","uart_micro", // uart location, rotation, side, class and type
0,25,270,"top","plug","rtc_micro", // rtc location, rotation, side, class and type
27,22,90,"top","fan","micro", // fan location, rotation, side, class and type
35.4,52.25,0,"top","gpio","encl_header_30", // gpio1 location, rotation, side, class and type
76.25,32.5,270,"top","gpio","encl_header_12", // gpio2 location, rotation, side, class and type
43.8,27.25,0,"top","ic","ic_5.75x5.75", // pmic location, rotation, side, class and type
32.5,40.5,0,"top","ic","ic_7x7", // usbhum 7mm location, rotation, side, class and type
11.7,22.8,0,"top","ic","ic_6x6", // nic location, rotation, side, class and type
28.39,42,0,"top","heatsink","xu4q_oem"], // heatsink location, rotation, side, class and type
["mc1",55,47,1,3.5,16,10, // sbc model, pcb size and component height
2.5,10.5,3,2.5,37,3, // pcb holes 1 and 2 location and pcb hole size
52.5,32.5,3,0,0,3, // pcb holes 3 and 4 location and pcb hole size
0,0,0,0,0,0, // pcb holes 5 and 6 location and pcb hole size
0,0,0,0,0,0, // pcb holes 7 and 8 location and pcb hole size
0,0,0,0,0,0, // pcb holes 9 and 10 location and pcb hole size
14.5,15.75,1.25,2,15,0,0,"bottom", // soc1 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc2 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc3 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc4 size, location, rotation and side
5.5,3,0,"top","storage","sdcard", // sdcard location, rotation, side, class and type
19,-1,0,"top","plug","pwr5.5_7.5x11.5", // pwrplug location, rotation, side, class and type
29.5,-1,0,"top","usb2","single_vert_a", // usb2 location, rotation, side, class and type
37.7,-1,0,"top","network","rj45_single", // ethernet location, rotation, side, class and type
44.2,34.4,90,"top","plug","uart_micro", // uart location, rotation, side, class and type
35,32.3,0,"top","plug","rtc_micro", // rtc location, rotation, side, class and type
42.8,21.85,0,"top","ic","ic_6x6"], // nic location, rotation, side, class and type
["hc1",55,47,1,3.5,16,10, // sbc model, pcb size and component height
2.5,10.5,3,2.5,37,3, // pcb holes 1 and 2 location and pcb hole size
52.5,32.5,3,0,0,3, // pcb holes 3 and 4 location and pcb hole size
0,0,0,0,0,0, // pcb holes 5 and 6 location and pcb hole size
0,0,0,0,0,0, // pcb holes 7 and 8 location and pcb hole size
0,0,0,0,0,0, // pcb holes 9 and 10 location and pcb hole size
14.5,15.75,1.25,2,15,0,0,"bottom", // soc1 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc2 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc3 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc4 size, location, rotation and side
5.5,3,0,"top","storage","sdcard", // sdcard location, rotation, side, class and type
19,-1,0,"top","plug","pwr5.5_7.5x11.5", // pwrplug location, rotation, side, class and type
29.5,-1,0,"top","usb2","single_vert_a", // usb2 location, rotation, side, class and type
37.7,-1,0,"top","network","rj45_single", // ethernet location, rotation, side, class and type
44.2,34.4,90,"top","plug","uart_micro", // uart location, rotation, side, class and type
35,32.3,0,"top","plug","rtc_micro", // rtc location, rotation, side, class and type
42.8,21.85,0,"top","ic","ic_6x6", // nic location, rotation, side, class and type
2,41,0,"top","storage","sata_encl_power"], // sata location, rotation, side, class and type
["n1",90,90,1.5,3.5,16,6, // sbc model, pcb size and component height
12,43,3,3.8,86.5,3, // pcb holes 1 and 2 location and pcb hole size
86.5,28,3,86.5,86.5,3, // pcb holes 3 and 4 location and pcb hole size
24.5,42,3,0,0,3, // pcb holes 5 and 6 location and pcb hole size
75,64.5,3,0,0,3, // pcb holes 7 and 8 location and pcb hole size
0,0,0,0,0,0, // pcb holes 9 and 10 location and pcb hole size
21,21,1.51,48.5,37.5,0,-45,"top", // soc1 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc2 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc3 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc4 size, location, rotation and side
78.7,50,270,"bottom","-memory","emmc_plug", // emmc plug location, rotation, side, class and type
65,48,270,"bottom","memory","emmc", // emmc location, rotation, side, class and type
75,36,90,"bottom","storage","sdcard", // sdcard location, rotation, side, class and type
3,0,0,"top","plug","pwr5.5_7.5x11.5", // pwrplug location, rotation, side, class and type
17,-1,0,"top","video","hdmi_a", // hdmi location, rotation, side, class and type
36,0,0,"top","usb3","double_stacked_a", // usb3 location, rotation, side, class and type
54,0,0,"top","usb2","double_stacked_a", // usb2 location, rotation, side, class and type
72,0,0,"top","network","rj45_single", // ethernet location, rotation, side, class and type
83,32,270,"top","gpio","header_40", // gpio location, rotation, side, class and type
7.5,80,0,"top","button","tall_6x6", // reset button location, rotation, side, class and type
15,80,0,"top","button","tall_6x6", // power button location, rotation, side, class and type
0,24,270,"top","storage","sata_header", // sata location, rotation, side, class and type
0,42.5,270,"top","storage","sata_header", // sata location, rotation, side, class and type
0,59,270,"top","plug","uart_micro", // uart location, rotation, side, class and type
0,74,270,"top","plug","rtc_micro", // rtc location, rotation, side, class and type
20,54,-45,"top","fan","micro", // fan location, rotation, side, class and type
5.5,52,270,"top","plug","molex_4x1", // pwrplug location, rotation, side, class and type
15,31,0,"top","ic","ic_7x7", // sata ic 7mm location, rotation, side, class and type
74.5,24.5,0,"top","ic","ic_6x6", // nic location, rotation, side, class and type
50,25,90,"top","ic","ic_7x7", // usb hum 7mm location, rotation, side, class and type
24,69,90,"top","ic","ic_13x8", // memory location, rotation, side, class and type
38.5,69,90,"top","ic","ic_13x8", // memory location, rotation, side, class and type
50.5,69,90,"top","ic","ic_13x8", // memory location, rotation, side, class and type
65,69,90,"top","ic","ic_13x8", // memory location, rotation, side, class and type
3.5,17.5,90,"top","ic","ic_6x6", // memory location, rotation, side, class and type
12.5,17.5,90,"top","ic","ic_6x6", // memory location, rotation, side, class and type
// 24.5,42,45,"top","heatsink","n1_oem"], // heatsink location, rotation, side, class and type
-15.5,42.5,-45,"top","heatsink","n1_oem"], // heatsink location, rotation, side, class and type
["n2",90,90,1.7,.2,17,20, // sbc model, pcb size and component height
3,28.5,3.3,86.5,28.5,3.3, // pcb holes 1 and 2 location and pcb hole size
3,86.5,3.3,86.5,86.5,3.3, // pcb holes 3 and 4 location and pcb hole size
0,0,0,0,0,0, // pcb holes 5 and 6 location and pcb hole size
0,0,0,0,0,0, // pcb holes 7 and 8 location and pcb hole size
0,0,0,0,0,0, // pcb holes 9 and 10 location and pcb hole size
14.5,16.25,1.51,37.78,50.88,0,0,"bottom", // soc1 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc4 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc4 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc4 size, location, rotation and side
2.35,-1,0,"top","plug","pwr5.5_7.5x11.5", // power plug location, rotation, side, class and type
16.55,0,0,"top","usb3","double_stacked_a", // usb3 location, rotation, side, class and type
34.8,0,0,"top","usb3","double_stacked_a", // usb3 location, rotation, side, class and type
54.5,-1,0,"top","video","hdmi_a", // hdmi location, rotation, side, class and type
71.75,0,0,"top","network","rj45_single", // ethernet location, rotation, side, class and type
83.96,32.1,90,"top","gpio","header_40", // gpio location, rotation, side, class and type
17.61,39.73,0,"top","jumper","header_7x1", // jumper location, rotation, side, class and type
.2,69.05,270,"top","plug","uart_micro", // uart location, rotation, side, class and type
75.05,42.44,180,"top","plug","rtc_micro", // rtc location, rotation, side, class and type
68.5,68.8,90,"top","fan","micro", // fan location, rotation, side, class and type
7.2,76.82,180,"top","storage","sdcard", // sdcard location, rotation, side, class and type
59.35,85.4,180,"top","usb2","micro", // usb2 otg location, rotation, side, class and type
35.85,85.62,0,"top","memory","emmc_plug", // emmc plug location, rotation, side, class and type
33.5,72,0,"top","memory","emmc", // emmc location, rotation, side, class and type
22.4,86.6,180,"top","misc","ir_1", // ir location, rotation, side, class and type
48.45,86.7,180,"top","switch","slide_4x9", // switch location, rotation, side, class and type
73.67,78.95,180,"top","audio","jack_3.5", // switch location, rotation, side, class and type
18.95,46.23,0,"top","ic","ic_13x8", // memory top size, location, rotation and side
19.04,64.24,0,"top","ic","ic_13x8", // memory top size, location, rotation and side
18.95,46.23,0,"bottom","ic","ic_13x8", // memory bottom size, location, rotation and side
19.04,64.24,0,"bottom","ic","ic_13x8", // memory bottom size, location, rotation and side
45.74,27.51,0,"top","ic","ic_6.4x6.4", // component, location, rotation, side, class and type
75.08,25,0,"top","ic","ic_3.7x3.7", // component, location, rotation, side, class and type
74.3,69.54,0,"top","ic","ic_4.3x5.1", // component, location, rotation, side, class and type
50.8,77.25,0,"top","ic","ic_5.4x5.3", // component, location, rotation, side, class and type
77.03,51.92,0,"top","ic","ic_3x3", // component, location, rotation, side, class and type
-1,.5,180,"top","heatsink","n2_oem"], // heatsink location, rotation, side, class and type
["n2+",90,90,1.7,.2,17,14, // sbc model, pcb size and component height
3,28.5,3.3,86.5,28.5,3.3, // pcb holes 1 and 2 location and pcb hole size
3,86.5,3.3,86.5,86.5,3.3, // pcb holes 3 and 4 location and pcb hole size
0,0,0,0,0,0, // pcb holes 5 and 6 location and pcb hole size
0,0,0,0,0,0, // pcb holes 7 and 8 location and pcb hole size
0,0,0,0,0,0, // pcb holes 9 and 10 location and pcb hole size
14.5,16.25,1.51,37.78,50.88,0,0,"bottom", // soc1 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc4 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc4 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc4 size, location, rotation and side
2.35,-1,0,"top","plug","pwr5.5_7.5x11.5", // power plug location, rotation, side, class and type
18,0,0,"top","usb3","double_stacked_a", // usb3 location, rotation, side, class and type
36,0,0,"top","usb3","double_stacked_a", // usb3 location, rotation, side, class and type
54.5,-1,0,"top","video","hdmi_a", // hdmi location, rotation, side, class and type
71.75,0,0,"top","network","rj45_single", // ethernet location, rotation, side, class and type
83.96,32.1,90,"top","gpio","header_40", // gpio location, rotation, side, class and type
17.61,39.73,0,"top","jumper","header_7x1", // jumper location, rotation, side, class and type
.2,69.05,270,"top","plug","uart_micro", // uart location, rotation, side, class and type
53,35,0,"top","misc","bat_hold_1", // battery holder, location, rotation, side, class and type
68.5,68.8,90,"top","fan","micro", // fan location, rotation, side, class and type
7.2,76.82,180,"top","storage","sdcard", // sdcard location, rotation, side, class and type
59.35,85.4,180,"top","usb2","micro", // usb2 otg location, rotation, side, class and type
35.85,85.62,0,"top","memory","emmc_plug", // emmc plug location, rotation, side, class and type
33.5,72,0,"top","memory","emmc", // emmc location, rotation, side, class and type
22.4,86.6,180,"top","misc","ir_1", // ir location, rotation, side, class and type
48.45,86.7,180,"top","switch","slide_4x9", // switch location, rotation, side, class and type
73.67,78.95,180,"top","audio","jack_3.5", // switch location, rotation, side, class and type
18.95,46.23,0,"top","ic","ic_13x8", // memory top size, location, rotation and side
19.04,64.24,0,"top","ic","ic_13x8", // memory top size, location, rotation and side
18.95,46.23,0,"bottom","ic","ic_13x8", // memory bottom size, location, rotation and side
19.04,64.24,0,"bottom","ic","ic_13x8", // memory bottom size, location, rotation and side
45.74,27.51,0,"top","ic","ic_6.4x6.4", // component, location, rotation, side, class and type
75.08,25,0,"top","ic","ic_3.7x3.7", // component, location, rotation, side, class and type
74.3,69.54,0,"top","ic","ic_4.3x5.1", // component, location, rotation, side, class and type
50.8,77.25,0,"top","ic","ic_5.4x5.3", // component, location, rotation, side, class and type
77.03,51.92,0,"top","ic","ic_3x3", // component, location, rotation, side, class and type
1,-.5,0,"top","heatsink","n2+_oem"], // heatsink location, rotation, side, class and type
["n2+_noheatsink",90,90,1.7,.2,17,14, // sbc model, pcb size and component height
3,28.5,3.3,86.5,28.5,3.3, // pcb holes 1 and 2 location and pcb hole size
3,86.5,3.3,86.5,86.5,3.3, // pcb holes 3 and 4 location and pcb hole size
0,0,0,0,0,0, // pcb holes 5 and 6 location and pcb hole size
0,0,0,0,0,0, // pcb holes 7 and 8 location and pcb hole size
0,0,0,0,0,0, // pcb holes 9 and 10 location and pcb hole size
14.5,16.25,1.51,37.78,50.88,0,0,"bottom", // soc1 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc4 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc4 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc4 size, location, rotation and side
2.35,-1,0,"top","plug","pwr5.5_7.5x11.5", // power plug location, rotation, side, class and type
18,0,0,"top","usb3","double_stacked_a", // usb3 location, rotation, side, class and type
36,0,0,"top","usb3","double_stacked_a", // usb3 location, rotation, side, class and type
54.5,-1,0,"top","video","hdmi_a", // hdmi location, rotation, side, class and type
71.75,0,0,"top","network","rj45_single", // ethernet location, rotation, side, class and type
83.96,32.1,90,"top","gpio","header_40", // gpio location, rotation, side, class and type
17.61,39.73,0,"top","jumper","header_7x1", // jumper location, rotation, side, class and type
.2,69.05,270,"top","plug","uart_micro", // uart location, rotation, side, class and type
53,35,0,"top","misc","bat_hold_1", // battery holder, location, rotation, side, class and type
68.5,68.8,90,"top","fan","micro", // fan location, rotation, side, class and type
7.2,76.82,180,"top","storage","sdcard", // sdcard location, rotation, side, class and type
59.35,85.4,180,"top","usb2","micro", // usb2 otg location, rotation, side, class and type
35.85,85.62,0,"top","memory","emmc_plug", // emmc plug location, rotation, side, class and type
33.5,72,0,"top","memory","emmc", // emmc location, rotation, side, class and type
22.4,86.6,180,"top","misc","ir_1", // ir location, rotation, side, class and type
48.45,86.7,270,"top","switch","slide_4x9", // switch location, rotation, side, class and type
73.67,78.95,180,"top","audio","jack_3.5", // switch location, rotation, side, class and type
18.95,46.23,0,"top","ic","ic_13x8", // memory top size, location, rotation and side
19.04,64.24,0,"top","ic","ic_13x8", // memory top size, location, rotation and side
18.95,46.23,0,"bottom","ic","ic_13x8", // memory bottom size, location, rotation and side
19.04,64.24,0,"bottom","ic","ic_13x8", // memory bottom size, location, rotation and side
45.74,27.51,0,"top","ic","ic_6.4x6.4", // component, location, rotation, side, class and type
75.08,25,0,"top","ic","ic_3.7x3.7", // component, location, rotation, side, class and type
74.3,69.54,0,"top","ic","ic_4.3x5.1", // component, location, rotation, side, class and type
50.8,77.25,0,"top","ic","ic_5.4x5.3", // component, location, rotation, side, class and type
77.03,51.92,0,"top","ic","ic_3x3"], // component, location, rotation, side, class and type
["m1",90,122,1.7,.2,17,14, // sbc model, pcb size and component height
3,28.5,3,3,118.5,3, // pcb holes 1 and 2 location and pcb hole size
86.5,118.5,3,,86.5,28.5,3, // pcb holes 3 and 4 location and pcb hole size
3,67,3,66,25,3, // pcb holes 5 and 6 location and pcb hole size
86.5,47,3,0,0,0, // pcb holes 7 and 8 location and pcb hole size
0,0,0,0,0,0, // pcb holes 9 and 10 location and pcb hole size
19,19,1.51,45,43.5,0,45,"bottom", // soc1 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc4 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc4 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc4 size, location, rotation and side
2.35,-1,0,"top","plug","pwr5.5_7.5x11.5", // power plug location, rotation, side, class and type
17,0,0,"top","usb3","double_stacked_a", // usb3 location, rotation, side, class and type
35,0,0,"top","usb2","double_stacked_a", // usb3 location, rotation, side, class and type
54.5,-1,0,"top","video","hdmi_a", // hdmi location, rotation, side, class and type
71.25,0,0,"top","network","rj45_single", // ethernet location, rotation, side, class and type
84.375,62.25,90,"top","gpio","header_40", // gpio location, rotation, side, class and type
.2,101,270,"top","plug","uart_micro", // uart location, rotation, side, class and type
21,88,120,"top","misc","bat_hold_1", // battery holder, location, rotation, side, class and type
61,118,0,"top","plug","audio_micro", // micro location, rotation, side, class and type
7.2,108.82,180,"top","storage","sdcard", // sdcard location, rotation, side, class and type
20,0,0,"bottom","usb2","micro", // usb2 otg location, rotation, side, class and type
35.85,117,0,"top","memory","emmc_plug", // emmc plug location, rotation, side, class and type
33.5,103,0,"top","memory","emmc", // emmc location, rotation, side, class and type
22.4,118.58,180,"top","misc","ir_1", // ir location, rotation, side, class and type
73.73,111.5,180,"top","audio","jack_3.5", // audio jack location, rotation, side, class and type
0,88.2,270,"top","plug","small_encl_satapwr", // pwrplug location, rotation, side, class and type
.25,72,270,"top","storage","sata_header", // sata location, rotation, side, class and type
50,115.65,0,"top","button","momentary_6x6x4", // spi button location, rotation, side, class and type
7,101,0,"top","jumper","header_2x1", // jumper location, rotation, side, class and type
7,103.5,0,"top","jumper","header_2x1", // jumper location, rotation, side, class and type
3.5,35.87,270,"top","storage","m.2_header", // m2 socket location, rotation, side, class and type
36.28,73,0,"bottom","ic","ic_16x10", // memory bottom size, location, rotation and side
75.75,25,0,"top","ic","ic_5x5", // ic bottom size, location, rotation and side
50.5,109.22,0,"top","ic","ic_5x5", // ic bottom size, location, rotation and side
58,72,0,"top","video","mipi_csi", // mipi csi size, location, rotation and side
65,93,0,"top","video","mipi_dsi", // mipi dsi size, location, rotation and side
.5,0,0,"top","heatsink","m1_oem", // heatsink location, rotation, side, class and type
86.5,47,0,"top","storage","m.2_stud"], // m2 stud location, rotation, side, class and type
["m1_noheatsink",90,122,1.7,.2,17,1.6, // sbc model, pcb size and component height
3,28.5,3,3,118.5,3, // pcb holes 1 and 2 location and pcb hole size
86.5,118.5,3,,86.5,28.5,3, // pcb holes 3 and 4 location and pcb hole size
3,67,3,66,25,3, // pcb holes 5 and 6 location and pcb hole size
86.5,47,3,0,0,0, // pcb holes 7 and 8 location and pcb hole size
0,0,0,0,0,0, // pcb holes 9 and 10 location and pcb hole size
19,19,1.51,45,43.5,0,45,"bottom", // soc1 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc4 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc4 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc4 size, location, rotation and side
2.35,-1,0,"top","plug","pwr5.5_7.5x11.5", // power plug location, rotation, side, class and type
18,0,0,"top","usb3","double_stacked_a", // usb3 location, rotation, side, class and type
36,0,0,"top","usb2","double_stacked_a", // usb3 location, rotation, side, class and type
54.5,-1,0,"top","video","hdmi_a", // hdmi location, rotation, side, class and type
71.75,0,0,"top","network","rj45_single", // ethernet location, rotation, side, class and type
84.375,62.25,90,"top","gpio","header_40", // gpio location, rotation, side, class and type
.2,101,270,"top","plug","uart_micro", // uart location, rotation, side, class and type
21,88,120,"top","misc","bat_hold_1", // battery holder, location, rotation, side, class and type
61,118,0,"top","plug","audio_micro", // micro location, rotation, side, class and type
7.2,108.82,180,"top","storage","sdcard", // sdcard location, rotation, side, class and type
20,0,0,"bottom","usb2","micro", // usb2 otg location, rotation, side, class and type
35.85,117,0,"top","memory","emmc_plug", // emmc plug location, rotation, side, class and type
33.5,103,0,"top","memory","emmc", // emmc location, rotation, side, class and type
22.4,118.58,180,"top","misc","ir_1", // ir location, rotation, side, class and type
73.73,111.5,180,"top","audio","jack_3.5", // audio jack location, rotation, side, class and type
0,88.2,270,"top","plug","small_encl_satapwr", // pwrplug location, rotation, side, class and type
.25,72,270,"top","storage","sata_header", // sata location, rotation, side, class and type
50,115.65,0,"top","button","momentary_6x6x4", // spi button location, rotation, side, class and type
7,101,0,"top","jumper","header_2x1", // jumper location, rotation, side, class and type
7,103.5,0,"top","jumper","header_2x1", // jumper location, rotation, side, class and type
3.5,35.87,270,"top","storage","m.2_header", // m2 socket location, rotation, side, class and type
36.28,73,0,"bottom","ic","ic_16x10", // memory bottom size, location, rotation and side
75.75,25,0,"top","ic","ic_5x5", // ic bottom size, location, rotation and side
50.5,109.22,0,"top","ic","ic_5x5", // ic bottom size, location, rotation and side
58,72,0,"top","video","mipi_csi", // mipi csi size, location, rotation and side
65,93,0,"top","video","mipi_dsi", // mipi dsi size, location, rotation and side
86.5,47,0,"top","storage","m.2_stud"], // m2 stud location, rotation, side, class and type
["h2",110,110,2,3.5,38,11, // sbc model, pcb size and component height
3.81,17.78,3.5,3.81,106.19,3.5, // pcb holes 1 and 2 location and pcb hole size
106.04,24.77,3.5,106.04,106.2,3.5, // pcb holes 3 and 4 location and pcb hole size
20.17,43.82,3,0,0,0, // pcb holes 5 and 6 location and pcb hole size
32,40,2.5,82,40,2.5, // pcb holes 7 and 8 location and pcb hole size
32,75,2.5,82,75,2.5, // pcb holes 9 and 10 location and pcb hole size
25,24,1.344,45.29,48.95,0,0,"top", // soc1 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc2 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc3 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc4 size, location, rotation and side
88.72,58.04,0,"top","memory","emmc_plug", // emmc plug location, rotation, side, class and type
86.87,43.84,0,"top","-memory","emmc", // emmc location, rotation, side, class and type
9.34,103.43,0,"top","button","momentary_6x6x4", // power button location, rotation, side, class and type
20.77,103.43,0,"top","button","momentary_6x6x4", // reset button location, rotation, side, class and type
1.27,76.76,90,"top","gpio","header_20", // gpio location, rotation, side, class and type
1.98,-1.73,0,"top","plug","pwr5.5_10x10", // pwrplug location, rotation, side, class and type
20.49,-.71,0,"top","combo","rj45-usb2_double", // rj45 and double usb2 ports location, rotation, side class and type
45.26,-.71,0,"top","combo","rj45-usb3_double", // rj45 and double usb3 ports location, rotation, side class and type
68.81,-.57,0,"top","video","dp-hdmi_a", // display port and hdmi location, rotation, side, class and type
95.25,-1.37,0,"top","audio","out-in-spdif", // audio out, in and spdif location, rotation, side, class and type
103.11,65.85,270,"top","storage","sata_encl_header", // sata location, rotation, side, class and type
103.11,83.62,270,"top","storage","sata_encl_header", // sata location, rotation, side, class and type
103,38.74,90,"top","plug","small_encl_satapwr", // sata power connector location, rotation, side, class and type
103,52.07,90,"top","plug","small_encl_satapwr", // sata power connector location, rotation, side, class and type
105.43,28.59,90,"top","plug","rtc_micro", // rtc location, rotation, side, class and type
0,49.94,270,"top","fan","encl_pmw", // fan pwm connector location, rotation, side, class and type
93.15,23.94,0,"top","ic","ic_6.75x6.75", // audio 6.75mm location, rotation, side, class and type
17.97,53.53,0,"top","ic","ic_4.7x4.7", // ic 4.7mm location, rotation, side, class and type
8.74,15.24,0,"top","ic","ic_6.7x8.4", // ic 6.7x8.4xmm location, rotation, side, class and type
10.76,97.37,0,"bottom","ic","ic_7x7", // ic 7mm location, rotation, side, class and type
29.08,30.99,0,"bottom","ic","ic_2.8x2.8", // ic 2.8mm location, rotation, side, class and type
53.21,30.99,0,"bottom","ic","ic_2.8x2.8", // ic 2.8mm location, rotation, side, class and type
96.32,32.87,270,"bottom","storage","m.2_header", // m2 socket location, rotation, side, class and type
21.98,82.05,0,"bottom","memory","sodimm_5.2", // sodimm socket location, rotation, side, class and type
21.98,98.6,0,"bottom","memory","sodimm_9.2", // sodimm socket location, rotation, side, class and type
32,40,0,"top","heatsink","h2_oem"], // heatsink location, rotation, side, class and type
["hc4",90.6,84,1.6,9,15,13, // sbc model, pcb size and component height
4,5.5,3.5,4,58.5,3.5, // pcb holes 1 and 2 location and pcb hole size
86.5,6,3.5,87,78.5,3.5, // pcb holes 3 and 4 location and pcb hole size
87,15.5,3.5,16.91,44.52,3, // pcb holes 5 and 6 location and pcb hole size
68.09,64.53,3,0,0,0, // pcb holes 7 and 8 location and pcb hole size
0,0,0,0,0,0, // pcb holes 9 and 10 location and pcb hole size
14.5,14.5,1.25,45.86,46,0,0,"bottom", // soc1 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc2 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc3 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc4 size, location, rotation and side
19.2,2,0,"top","storage","sdcard", // sdcard location, rotation, side, class and type
7.3,-1,0,"top","plug","pwr5.5_7.5x11.5", // pwrplug location, rotation, side, class and type
36,-1,0,"top","usb2","single_vert_a", // usb2 location, rotation, side, class and type
67,-1,0,"top","network","rj45_single", // ethernet location, rotation, side, class and type
84.7,38.55,270,"top","plug","uart_micro", // uart location, rotation, side, class and type
75.3,79.45,180,"top","misc","ir_1", // ir location, rotation, side, class and type
85.25,53,90,"top","jumper","header_5x1", // jumper location, rotation, side, class and type
34.65,74.85,0,"bottom","button","momentary_6x6x4", // boot button location, rotation, side, class and type
10,80.70,0,"bottom","fan","encl_pmw_h", // fan pwm connector location, rotation, side, class and type
47.38,-1,0,"bottom","video","hdmi_a", // hdmi location, rotation, side, class and type
25.05,28.85,0,"top","storage","sata_power_vrec", // sata location, rotation, side, class and type
25.05,69.55,0,"top","storage","sata_power_vrec", // sata location, rotation, side, class and type
25.87,38.45,0,"top","ic","ic_13x9", // memory bottom size, location, rotation and side
25.87,56.46,0,"top","ic","ic_13x9", // memory bottom size, location, rotation and side
25.87,38.45,0,"bottom","ic","ic_13x9", // memory bottom size, location, rotation and side
25.87,56.46,0,"bottom","ic","ic_13x9", // memory bottom size, location, rotation and side
78.78,27.6,0,"top","ic","ic_6x6", // nic location, rotation, side, class and type
53.63,32.67,0,"bottom","ic","ic_7x7", // pcie bridge location, rotation, side, class and type
10,59.53,0,"bottom","heatsink","hc4_oem"], // heatsink location, rotation, side, class and type
["show2",83,48,1,3.5,7,3, // sbc model, pcb size and component height
3.5,3.5,3.5,3.5,44.5,3.5, // pcb holes 1 and 2 location and pcb hole size
79.5,3.5,3.5,79.5,44.5,3.5, // pcb holes 3 and 4 location and pcb hole size
0,0,0,0,0,0, // pcb holes 5 and 6 location and pcb hole size
0,0,0,0,0,0, // pcb holes 7 and 8 location and pcb hole size
0,0,0,0,0,0, // pcb holes 9 and 10 location and pcb hole size
8,8,1.25,8,20,0,0,"top", // soc1 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc2 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc3 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc4 size, location, rotation and side
7.5,44,180,"top","usb2","micro", // usb2 otg location, rotation, side, class and type
2,8.83,270,"top","jumper","header_6x1", // jumper location, rotation, side, class and type
15.5,42,270,"top","jumper","header_2x1", // jumper location, rotation, side, class and type
2,35,0,"top","jumper","header_3x2", // jumper location, rotation, side, class and type
2,25.5,270,"top","plug","rtc_micro", // battery location, rotation, side, class and type
7.65,2,0,"top","switch","slide_4x9", // switch location, rotation, side, class and type
21.4,2,0,"top","button","momentary_6x6x4", // power button location, rotation, side, class and type
29.8,3,0,"top","misc","led_3x1.5", // led location, rotation, side, class and type
34,3,0,"top","misc","led_3x1.5", // led location, rotation, side, class and type
38.2,3,0,"top","misc","led_3x1.5", // led location, rotation, side, class and type
46.6,1,180,"top","button","momentary_4x2x1", // momentary button location, rotation, side, class and type
55.2,1,180,"top","button","momentary_4x2x1", // momentary button location, rotation, side, class and type
63.8,1,180,"top","button","momentary_4x2x1", // momentary button location, rotation, side, class and type
19,9,0,"top","misc","lcd_2.2"], // lcd location, rotation, side, class and type
// RasberryPi 3B+, 3B, 3A+, 2, 1B+
["rpi3b+",85.6,56.5,1,3,16,6, // sbc model, pcb size and component height
3.5,3.5,2.75,3.5,52.5,2.75, // pcb holes 1 and 2 location and pcb hole size
61.5,3.5,2.75,61.5,52.5,2.75, // pcb holes 3 and 4 location and pcb hole size
0,0,0,0,0,0, // pcb holes 5 and 6 location and pcb hole size
0,0,0,0,0,0, // pcb holes 7 and 8 location and pcb hole size
0,0,0,0,0,0, // pcb holes 9 and 10 location and pcb hole size
14,14,1.5,19.975,24.525,0,0,"top", // soc1 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc2 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc3 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc4 size, location, rotation and side
0,0,0,"","",""], // component location, rotation, side, class and type
// Pine64 SBCs
["a64",127,79,1.6,3.5,0,0, // sbc model, pcb size and component height
4.5,4,3.3,122.5,4,3.3, // pcb holes 1 and 2 location and pcb hole size
4.5,75,3.3,122.5,75,3.3, // pcb holes 3 and 4 location and pcb hole size
0,0,0,0,0,0, // pcb holes 5 and 6 location and pcb hole size
0,0,0,0,0,0, // pcb holes 7 and 8 location and pcb hole size
0,0,0,0,0,0, // pcb holes 9 and 10 location and pcb hole size
0,0,0,0,0,0,0,"", // soc1 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc2 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc3 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc4 size, location, rotation and side
0,0,0,"","",""], // component, location, rotation, side, class and type
["rock64",85,56,1.6,3.5,14.8,1.7, // sbc model, pcb size and component height
3.5,3.5,2.8,3.5,52.5,2.8, // pcb holes 1 and 2 location and pcb hole size
61.5,3.5,2.8,61.5,52.5,2.8, // pcb holes 3 and 4 location and pcb hole size
0,0,0,0,0,0, // pcb holes 5 and 6 location and pcb hole size
0,0,0,0,0,0, // pcb holes 7 and 8 location and pcb hole size
0,0,0,0,0,0, // pcb holes 9 and 10 location and pcb hole size
0,0,0,0,0,0,0,"", // soc1 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc2 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc3 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc4 size, location, rotation and side
0,0,0,"","",""], // component, location, rotation, side, class and type
["rockpro64",127,79.5,2,3.5,17,8, // sbc model, pcb size and component height
4.5,4.25,3.25,4.5,75.25,3.25, // pcb holes 1 and 2 location and pcb hole size
122.5,4.25,3.25,122.5,75.25,3.25, // pcb holes 3 and 4 location and pcb hole size
45.5,67.4,3.25,87,25.6,3.25, // pcb holes 5 and 6 location and pcb hole size
0,0,0,0,0,0, // pcb holes 7 and 8 location and pcb hole size
0,0,0,0,0,0, // pcb holes 9 and 10 location and pcb hole size
21,21,1.5,48,47.3,0,45,"top", // soc1 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc2 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc3 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc4 size, location, rotation and side
-1.5,12,90,"top","plug","pwr5.5_7.5x11.5", // component, location, rotation, side, class and type
-1.5, 32, 90, "top", "network", "rj45_single", // rj45 ethernet port
-1.5, 52.4, 90, "top", "video", "hdmi_a", // hdmi port
114.4, 9.8, 270, "top", "audio", "jack_3.5", // audio jack
118, 19.5, 270, "top", "button", "momentary_6x6x4_90", // Power button
118, 28.5, 270, "top", "button", "momentary_6x6x4_90", // Reset button
112, 38.7, 270, "top", "usb2", "double_stacked_a", // USB-2 stack
112, 55, 270, "top", "usb3", "double_stacked_a", // USB-3 / USB-C stack
13.6, 73.4, 0, "top", "button", "momentary_4x2x1", // recover button
42.6, 73.4, 0, "top", "gpio", "header_40", // gpio
43.5, 0, 0, "top", "pcie", "x4", // pcie x4 port
98.9, 14.7, 0, "top", "memory", "emmc_plug", // mmc port
97.2, 0, 0, "bottom", "storage", "sdcard", // micro sdcard
94.6, 73.4, 0, "top", "jst_ph", 2, // fan header
101.4, 73.4, 0, "top", "jst_ph", 3, // SPDIF header
110.3, 73.4, 0, "top", "jst_ph", 2, // rtc header
10.6, 13.2, 270, "top", "jst_ph", 4], // sata dc out
["atomicpi",130.44,99.9,1.63,3,14,8, // sbc model, pcb size and component height
4.22,3.95,3,126.22,3.95,3, // pcb holes 1 and 2 location and pcb hole size
126.22,95.95,3,4.22,95.95,3, // pcb holes 3 and 4 location and pcb hole size
64.67,95.95,3,0,0,0, // pcb holes 5 and 6 location and pcb hole size
0,0,0,0,0,0, // pcb holes 7 and 8 location and pcb hole size
0,0,0,0,0,0, // pcb holes 9 and 10 location and pcb hole size
0,0,0,0,0,0,0,"", // soc1 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc2 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc3 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc4 size, location, rotation and side
0,0,0,"","",""], // component, location, rotation, side, class and type
["jetsonnano",100,80,1.63,.2,27,3, // sbc model, pcb size and component height
4,17,3,4,75,3, // pcb holes 1 and 2 location and pcb hole size
90,17,3,90,75,3, // pcb holes 3 and 4 location and pcb hole size
16,75,3,80,75,3, // pcb holes 5 and 6 location and pcb hole size
0,0,0,0,0,0, // pcb holes 7 and 8 location and pcb hole size
0,0,0,0,0,0, // pcb holes 9 and 10 location and pcb hole size
0,0,0,0,0,0,0,"", // soc1 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc2 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc3 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc4 size, location, rotation and side
2,-1,0,"top","plug","pwr5.5_7.5x11.5", // power plug location, rotation, side, class and type
14,-1,0,"top","video","dp-hdmi_a", // hdmi location, rotation, side, class and type
36,0,0,"top","usb3","double_stacked_a", // usb3 location, rotation, side, class and type
53,0,0,"top","usb3","double_stacked_a", // usb3 location, rotation, side, class and type
68.5,0,0,"top","network","rj45_single", // ethernet location, rotation, side, class and type
88,-1,0,"top","usb2","micro", // otg location, rotation, side, class and type
29,53,0,"top","ic","ic_9x9", // hub size, location, rotation and side
2,36,90,"top","video","mipi_csi", // mipi_csi location, rotation, side, class and type
72,45,90,"top","storage","m.2_header", // m.2 header location, rotation, side, class and type
44,57,0,"top","storage","m.2_stud", // m.2 stud location, rotation, side, class and type
11.5,30,180,"top","cm_holder","jetsonnano", // cm holder location, rotation, side, class and type
13,33,0,"top","cm","jetsonnano", // cm location, rotation, side, class and type
87.5,20,90,"top","gpio","header_40", // gpio location, rotation, side, class and type
72,24,0,"top","jumper","header_2x1", // jumper location, rotation, side, class and type
77,24,0,"top","jumper","header_2x1", // jumper location, rotation, side, class and type
.5,30,0,"top","jumper","header_2x1", // jumper location, rotation, side, class and type
.5,68.25,0,"top","jumper","header_2x1", // jumper location, rotation, side, class and type
.5,65.5,0,"top","jumper","header_2x1", // jumper location, rotation, side, class and type
.5,62.75,0,"top","jumper","header_2x1", // jumper location, rotation, side, class and type
.5,60,0,"top","jumper","header_2x1", // jumper location, rotation, side, class and type
93,72.5,90,"top","jumper","header_2x1", // jumper location, rotation, side, class and type
95.75,72.5,90,"top","jumper","header_2x1", // jumper location, rotation, side, class and type
8,62,90,"top","jumper","header_6x1"], // jumper location, rotation, side, class and type
["test",127,79,1.6,3.5,17,6, // sbc model, pcb size and component height
4.5,4,3.3,122.5,4,3.3, // pcb holes 1 and 2 location and pcb hole size
4.5,75,3.3,122.5,75,3.3, // pcb holes 3 and 4 location and pcb hole size
0,0,0,0,0,0, // pcb holes 5 and 6 location and pcb hole size
0,0,0,0,0,0, // pcb holes 7 and 8 location and pcb hole size
0,0,0,0,0,0, // pcb holes 9 and 10 location and pcb hole size
0,0,0,0,0,0,0,"", // soc1 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc2 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc3 size, location, rotation and side
0,0,0,0,0,0,0,"", // soc4 size, location, rotation and side
100, -1, 0, "top", "misc", "ir_1", // ir_1
-1, 67, 90, "top", "misc", "ir_1", // ir_1
60, 61, 180, "top", "misc", "ir_1", // ir_1
108.5, 67, 270, "top", "misc", "ir_1", // ir_1
0,0,0,"","",""] // component, location, rotation, side, class and type
];

View File

@@ -1,214 +0,0 @@
/*
SBC Models Copyright 2016,2017,2018,2019,2020,2021,2022 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
20190214 Version 1.0.0 SBC Model Framework
20190218 Version 1.0.1 Added HK Odroid-N2 as "n2"
20200425 Version 1.0.2 Added AtomicPi as "atomicpi"
Added Nvidia JetsonNano as "jetsonnano"
Updated Odroid-N2 sbc data
Updated Odroid-H2 sbc data
Added Odroid-C4 as"c4"
Added oem heatsinks
Added Odroid-XU4Q as "xu4q"
20200725 Version 1.0.3 Added Odroid-N2+ and heatsink
20201021 Version 1.0.4 Added HK Odroid-HC4 as "hc4"
20220202 Version 1.0.5 Added HK Show2 as "show2"
20220413 Version 1.0.6 Added Odroid-M1 as "m1"
20220515 Version 1.0.7 Added rockpro64, jetsonnano, updated sbc_test.scad, sbc_test_components.scad and other fixes and adjustments
see https://github.com/hominoids/SBC_Case_Builder
USE: sbc(model)
model = "c1+","c2","c4","xu4","xu4q","mc1","hc1","hc4","n1","n2","n2+","h2"
"rpi3b+","a64","rock64","rockpro64","atomicpi","jetsonnano","show2"
*/
include <./sbc_models.cfg>
use <./sbc_library.scad>
module sbc(model) {
sbc_model = [model];
s = search(sbc_model,sbc_data);
$fn=60;
// pcb and holes
// pcbsize_x, pcbsize_y, pcbsize_z, pcbcorner_radius, topmax_component_z, bottommax_component_z
pcbsize_x = sbc_data[s[0]][1];
pcbsize_y = sbc_data[s[0]][2];
pcbsize_z = sbc_data[s[0]][3];
pcbcorner_radius = sbc_data[s[0]][4];
difference() {
color("tan") pcb([pcbsize_x,pcbsize_y,pcbsize_z], pcbcorner_radius);
// pcb mounting holes
for (i=[7:3:36]) {
pcb_hole_x = sbc_data[s[0]][i];
pcb_hole_y = sbc_data[s[0]][i+1];
pcb_hole_size = sbc_data[s[0]][i+2];
if (pcb_hole_x!=0 && pcb_hole_y!=0) {
translate([pcb_hole_x,pcb_hole_y,-1])
cylinder(d=pcb_hole_size, h=5);
}
}
}
// soc placement
// soc1size_x, soc1size_y, soc1size_z, soc1loc_x, soc1loc_y, soc1loc_z, soc1_rotation, "soc1_side"
for (i=[37:8:68]) {
soc1size_x = sbc_data[s[0]][i];
soc1size_y = sbc_data[s[0]][i+1];
soc1size_z = sbc_data[s[0]][i+2];
soc1loc_x = sbc_data[s[0]][i+3];
soc1loc_y = sbc_data[s[0]][i+4];
soc1loc_z = sbc_data[s[0]][i+5];
soc1_rotation = sbc_data[s[0]][i+6];
soc1_side = sbc_data[s[0]][i+7];
if (soc1size_x!=0 && soc1size_y!=0) {
if (soc1_side == "top" ) {
color("dimgray",1)
translate([soc1loc_x,soc1loc_y,pcbsize_z])
rotate([0,0,-soc1_rotation])
cube([soc1size_x,soc1size_y,soc1size_z]);
}
if (soc1_side == "bottom") {
color("dimgray",1)
translate([soc1loc_x,soc1loc_y,-pcbsize_z])
rotate([0,0,soc1_rotation])
cube([soc1size_x,soc1size_y,soc1size_z]);
}
}
}
// component placement loc_x, loc_y, rotation, "side", "type"
for (i=[69:6:len(sbc_data[s[0]])]) {
loc_x = sbc_data[s[0]][i];
loc_y = sbc_data[s[0]][i+1];
rotation = sbc_data[s[0]][i+2];
side = sbc_data[s[0]][i+3];
class = sbc_data[s[0]][i+4];
type = sbc_data[s[0]][i+5];
if (class == "memory") {
if (loc_x!=0 || loc_y!=0) {
memory(loc_x,loc_y,rotation,side,type,pcbsize_z);
}
}
if (class == "switch") {
if (loc_x!=0 || loc_y!=0) {
switch(loc_x,loc_y,rotation,side,type,pcbsize_z);
}
}
if (class == "button") {
if (loc_x!=0 || loc_y!=0) {
button(loc_x,loc_y,rotation,side,type,pcbsize_z);
}
}
if (class == "plug") {
if (loc_x!=0 || loc_y!=0) {
plug(loc_x,loc_y,rotation,side,type,pcbsize_z);
}
}
if (class == "usb2") {
if (loc_x!=0 || loc_y!=0) {
usb2(loc_x,loc_y,rotation,side,type,pcbsize_z);
}
}
if (class == "usb3") {
if (loc_x!=0 || loc_y!=0) {
usb3(loc_x,loc_y,rotation,side,type,pcbsize_z);
}
}
if (class == "network") {
if (loc_x!=0 || loc_y!=0) {
network(loc_x,loc_y,rotation,side,type,pcbsize_z);
}
}
if (class == "video") {
if (loc_x!=0 || loc_y!=0) {
video(loc_x,loc_y,rotation,side,type,pcbsize_z);
}
}
if (class == "fan") {
if (loc_x!=0 || loc_y!=0) {
fan(loc_x,loc_y,rotation,side,type,pcbsize_z);
}
}
if (class == "gpio") {
if (loc_x!=0 || loc_y!=0) {
gpio(loc_x,loc_y,rotation,side,type,pcbsize_z);
}
}
if (class == "audio") {
if (loc_x!=0 || loc_y!=0) {
audio(loc_x,loc_y,rotation,side,type,pcbsize_z);
}
}
if (class == "storage") {
if (loc_x!=0 || loc_y!=0) {
storage(loc_x,loc_y,rotation,side,type,pcbsize_z);
}
}
if (class == "combo") {
if (loc_x!=0 || loc_y!=0) {
combo(loc_x,loc_y,rotation,side,type,pcbsize_z);
}
}
if (class == "jumper") {
if (loc_x!=0 || loc_y!=0) {
jumper(loc_x,loc_y,rotation,side,type,pcbsize_z);
}
}
if (class == "ic") {
if (loc_x!=0 || loc_y!=0) {
ic(loc_x,loc_y,rotation,side,type,pcbsize_z);
}
}
if (class == "misc") {
if (loc_x!=0 || loc_y!=0) {
misc(loc_x,loc_y,rotation,side,type,pcbsize_z);
}
}
if (class == "heatsink") {
if (loc_x!=0 || loc_y!=0) {
heatsink(loc_x,loc_y,rotation,side,type,pcbsize_z,sbc_data[s[0]][39]);
}
}
if (class == "pcie") {
if(loc_x!=0 || loc_y!=0) {
pcie(loc_x, loc_y, rotation, side, type, pcbsize_z);
}
}
if (class == "jst_ph") {
if(loc_x!=0 || loc_y!=0) {
jst_ph(loc_x, loc_y, rotation, side, type, pcbsize_z);
}
}
if (class == "cm_holder") {
if(loc_x!=0 || loc_y!=0) {
cm_holder(loc_x, loc_y, rotation, side, type, pcbsize_z);
}
}
if (class == "cm") {
if(loc_x!=0 || loc_y!=0) {
cm(loc_x, loc_y, rotation, side, type, pcbsize_z);
}
}
}
}

242
lib/shape.scad Normal file
View File

@@ -0,0 +1,242 @@
/*
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
slab(size, radius)
slab_r(size, radius)
slot(hole,length,depth)
knockout(width,depth,gap,thick,fillet,shape)
hdmi_open(hdmi_style)
microusb_open()
*/
/*
NAME: slab
DESCRIPTION: create rectangle with uniform fillet corners
TODO: none
USAGE: slab(size, radius)
size = [x, y, z]
radius = corner fillet size
*/
module slab(size, radius) {
x = size[0];
y = size[1];
z = size[2];
linear_extrude(height=z)
hull() {
translate([0+radius ,0+radius, 0]) circle(r=radius);
translate([0+radius, y-radius, 0]) circle(r=radius);
translate([x-radius, y-radius, 0]) circle(r=radius);
translate([x-radius, 0+radius, 0]) circle(r=radius);
}
}
/*
NAME: slab_r
DESCRIPTION: create rectangle with multi-radius fillet corners
TODO: none
USAGE: slab_r(size, radius)
size = [x, y, z]
radius = [radius1, radius2, radius3, radius4]
*/
module slab_r(size, radius) {
x = size[0];
y = size[1];
z = size[2];
r0 = radius[0];
r1 = radius[1];
r2 = radius[2];
r3 = radius[3];
linear_extrude(height=z)
hull() {
translate([0+radius[0] ,0+radius[0], 0]) circle(r=radius[0]);
translate([0+radius[1], y-radius[1], 0]) circle(r=radius[1]);
translate([x-radius[2], y-radius[2], 0]) circle(r=radius[2]);
translate([x-radius[3], 0+radius[3], 0]) circle(r=radius[3]);
}
}
/*
NAME: slot
DESCRIPTION: create slot shape
TODO: none
USAGE: slot(hole, length, depth)
hole = diameter of slot
length = length of slot
depth = thickness of slot
*/
module slot(hole, length, depth) {
hull() {
translate([0,0,0]) cylinder(d=hole,h=depth);
translate([length,0,0]) cylinder(d=hole,h=depth);
}
}
/*
NAME: knockout
DESCRIPTION: create knockout shapes
TODO: none
USAGE: knockout(width, depth, gap, thick, fillet, shape)
width = length
depth = width
gap = space between
thick = thickness
fillet = corner fillet
shape = "slot", "rectangle", "round"
*/
module knockout(width, depth, gap, thick, fillet, shape) {
adj = .01;
$fn=90;
// slot knockout
if(shape == "slot") {
difference() {
slot(depth, width, thick);
translate([gap/2, 0, -adj]) slot(depth-gap, width-gap, thick+(2*adj));
// cross ties
translate([(depth/2), -(depth/2)-1, -adj]) cube([2, depth+2, thick+(2*adj)]);
translate([(width/2)-1-(width/4)+4, -(depth/2)-1, -adj]) cube([2,depth+2, thick+(2*adj)]);
translate([(width/2)-1+(width/4)-4, -(depth/2)-1, -adj]) cube([2, depth+2, thick+(2*adj)]);
translate([width-(depth/2)-2, -(depth/2)-1, -adj]) cube([2, depth+2, thick+(2*adj)]);
}
}
if(shape == "rectangle") {
difference() {
translate([(width/2), (depth/2), thick/2])
cube_fillet_inside([width, depth, thick],
vertical=[fillet, fillet, fillet, fillet],
top=[0, 0, 0, 0], bottom=[0, 0, 0, 0], $fn=90);
translate([(width/2), (depth/2), (thick/2)-adj])
cube_fillet_inside([width-gap, depth-gap, thick+(3*adj)],
vertical=[fillet, fillet, fillet, fillet],
top=[0, 0, 0, 0], bottom=[0, 0, 0, 0], $fn=90);
// cross ties
translate([-1, (depth/2)-1, -adj]) cube([gap+2, 2, thick+(2*adj)]);
translate([width-4, depth-gap-1, -adj]) cube([2, gap+2, thick+(2*adj)]);
translate([2, depth-gap-1, -adj]) cube([2, gap+2, thick+(2*adj)]);
translate([width-gap-1, (depth/2)-1, -adj]) cube([gap+2, 2, thick+(2*adj)]);
translate([width-4, -1, -adj]) cube([2, gap+2, thick+(2*adj)]);
translate([2, -1, -adj]) cube([2, gap+2, thick+(2*adj)]);
}
}
if(shape == "round") {
difference() {
translate([(width/2),(width/2),0])
cylinder(d=width, h=thick);
translate([(width/2), (width/2), -adj])
cylinder(d=width-gap, h=thick+2*adj);
// cross ties
translate([-1, (depth/2)-1, -adj]) cube([gap+2, 2, thick+(2*adj)]);
translate([(width/2)-1, depth-gap-1, -adj]) cube([2, gap+2, thick+(2*adj)]);
translate([width-gap-1, (depth/2)-1, -adj]) cube([gap+2, 2, thick+(2*adj)]);
translate([(width/2)-1, -1, -adj]) cube([2, gap+2, thick+(2*adj)]);
}
}
}
/*
NAME: hdmi_open
DESCRIPTION: create hdmi mask opening
TODO: none
USAGE: hdmi_open(hdmi_style)
hdmi_style = "hdmi_a", "hdmi_micro", "hdmi_mini", "dp_mini"
*/
module hdmi_open(hdmi_style) {
if(hdmi_style == "hdmi_a") {
union() {
difference() {
translate([0,-5,1.25]) cube([15.5,8,5.75]);
translate([0.5,-5.2,.5]) rotate ([-90,0,0]) cylinder(d=3, h=13.5,$fn=30);
translate([15,-5.2,.5]) rotate ([-90,0,0]) cylinder(d=3, h=13.5,$fn=30);
}
translate([1.75,-5,.5]) cube([12, 8, 1]);
}
}
if(hdmi_style == "hdmi_micro") {
union() {
difference() {
translate([-.25,-6,-.01]) cube([7,8,3.15]);
translate([-.25,-6.2,0]) rotate ([-90,0,0]) cylinder(d=1.5, h=9.5,$fn=30);
translate([6.75,-6.2,0]) rotate ([-90,0,0]) cylinder(d=1.5, h=9.5,$fn=30);
}
}
}
if(hdmi_style == "hdmi_mini") {
union() {
difference() {
translate([-.25,-6,-.01]) cube([11.5,8,3.5]);
translate([-1,-6.2,-.5]) rotate ([-90,0,0]) cylinder(d=3, h=10,$fn=30);
translate([12.25,-6.2,-.5]) rotate ([-90,0,0]) cylinder(d=3, h=10,$fn=30);
}
}
}
if(hdmi_style=="dp_mini") {
size_x = 9;
size_y = 8;
union() {
difference() {
translate([-.25,-6,0]) cube([size_x, size_y, 5.75]);
translate([-7.5,-7,1]) rotate([0,45,0]) cube([size_x, size_y+2, 5.6]);
translate([10,-7,-5]) rotate([0,-45,0]) cube([size_x, size_y+2, 5.6]);
}
}
}
}
/*
NAME: microusb_open
DESCRIPTION: create micro-usb mask opening
TODO: none
USAGE: microusb_open()
*/
module microusb_open() {
translate([0,0,.5])rotate([90,0,0])
hull() {
translate([6,1.5,-5]) cylinder(d=3.5,h=12);
translate([1,1.5,-5]) cylinder(d=3.5,h=12);
}
}

123
lib/standoff.scad Normal file
View File

@@ -0,0 +1,123 @@
/*
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)
stand_off[radius,
height,
holesize,
supportsize,
supportheight,
sink,
0 = none
1 = countersink
2 = recessed hole
3 = nut holder
4 = blind hole
style,
0 = hex shape
1 = cylinder
reverse,
insert_e,
i_dia,
i_depth]
*/
module standoff(stand_off){
radius = stand_off[0];
height = stand_off[1];
holesize = stand_off[2];
supportsize = stand_off[3];
supportheight = stand_off[4];
sink = stand_off[5];
style = stand_off[6];
reverse = stand_off[7];
insert_e = stand_off[8];
i_dia = stand_off[9];
i_depth = stand_off[10];
adj = 0.1;
difference (){
union () {
if(style == 0 && reverse == 0) {
rotate([0,0,30]) cylinder(d=radius*2/sqrt(3),h=height,$fn=6);
}
if(style == 0 && reverse == 1) {
translate([0,0,-height]) rotate([0,0,30]) cylinder(d=radius*2/sqrt(3),h=height,$fn=6);
}
if(style == 1 && reverse == 0) {
cylinder(d=radius,h=height,$fn=90);
}
if(style == 1 && reverse == 1) {
translate([0,0,-height]) cylinder(d=radius,h=height,$fn=90);
}
if(reverse == 1) {
translate([0,0,-supportheight]) cylinder(d=(supportsize),h=supportheight,$fn=60);
}
else {
cylinder(d=(supportsize),h=supportheight,$fn=60);
}
}
// hole
if(sink <= 3 && reverse == 0) {
translate([0,0,-adj]) cylinder(d=holesize, h=height+(adj*2),$fn=90);
}
if(sink <= 3 && reverse == 1) {
translate([0,0,-adj-height]) cylinder(d=holesize, h=height+(adj*2),$fn=90);
}
// countersink hole
if(sink == 1 && reverse == 0) {
translate([0,0,-adj]) cylinder(d1=6.5, d2=(holesize), h=3);
}
if(sink == 1 && reverse == 1) {
translate([0,0,+adj-2.5]) cylinder(d1=(holesize), d2=6.5, h=3);
}
// recessed hole
if(sink == 2 && reverse == 0) {
translate([0,0,-adj]) cylinder(d=6.5, h=3);
}
if(sink == 2 && reverse == 1) {
translate([0,0,+adj-3]) cylinder(d=6.5, h=3);
}
// nut holder
if(sink == 3 && reverse == 0) {
translate([0,0,-adj]) cylinder(r=3.3,h=3,$fn=6);
}
if(sink == 3 && reverse == 1) {
translate([0,0,+adj-3]) cylinder(r=3.3,h=3,$fn=6);
}
// blind hole
if(sink == 4 && reverse == 0) {
translate([0,0,2]) cylinder(d=holesize, h=height,$fn=90);
}
if(sink == 4 && reverse == 1) {
translate([0,0,-height-2-adj]) cylinder(d=holesize, h=height,$fn=90);
}
if(insert_e > 0 && reverse == 0) {
translate([0,0,height-i_depth]) cylinder(d=i_dia, h=i_depth+adj,$fn=90);
}
if(insert_e > 0 && reverse == 1) {
translate([0,0,-height-adj]) cylinder(d=i_dia, h=i_depth+adj,$fn=90);
}
}
}

143
lib/vent.scad Normal file
View File

@@ -0,0 +1,143 @@
/*
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(width, length, height, gap, rows, columns, orientation)
vent_hex(cells_x, cells_y, thickness, cell_size, cell_spacing, orientation)
vent_panel_hex(x, y, thick, cell_size, cell_spacing, border, borders);
*/
/*
NAME: vent
DESCRIPTION: creates vent mask patterns
TODO: none
USAGE: vent(width, length, height, gap, rows, columns, orientation)
width = coloumn size_x
length = column size_y
height = size_z
gap = space between
rows = #row
columns = #columns
orientation = "horizontal", "vertical"
*/
module vent(width, length, height, gap, rows, columns, orientation) {
fillet = width/2;
adj = .01;
$fn=90;
// vertical orientation
if(orientation == "vertical") { rotate([90,0,0])
for (r=[0:length+gap:rows*(length+gap)-1]) {
for (c=[0:width+(2*gap):(columns*(width+(2*gap)))-1]) {
translate ([c,r,-1]) cube([width,length,height]);
}
}
}
// horizontal orientation
if(orientation == "horizontal") {
for (r=[0:length+(2*gap):rows*(length+gap)]) {
for (c=[0:width+(2*gap):(columns*(width+(2*gap)))-1]) {
translate ([c,r,-1]) cube([width,length,height]);
}
}
}
}
/*
NAME: vent_hex
DESCRIPTION: creates hex vent mask patterns
TODO: none
USAGE: vent_hex(cells_x, cells_y, thickness, cell_size, cell_spacing, orientation)
cells_x = #rows
cells_y = #columns
thickness = pattern thickness
cell_size = size of hex
cell_spacing = space between hex
orientation = "horizontal", "vertical"
*/
module vent_hex(cells_x, cells_y, thickness, cell_size, cell_spacing, orientation) {
xs = cell_size + cell_spacing;
ys = xs * sqrt(3/4);
rot = (orientation=="vertical") ? 90 : 0;
rotate([rot,0,0]) translate([cell_size/2, cell_size*sqrt(1/3),-1]) {
for (ix = [0 : ceil(cells_x/2)-1]) {
for (iy = [0 : 2 : cells_y-1]) {
translate([ix*xs, iy*ys,0]) rotate([0,0,90])
cylinder(r=cell_size/sqrt(3), h=thickness, $fn=6);
}
}
for (ix = [0 : (cells_x/2)-1]) {
for (iy = [1 : 2 : cells_y-1]) {
translate([(ix+0.5)*xs, iy*ys,0]) rotate([0,0,90])
cylinder(r=cell_size/sqrt(3), h=thickness, $fn=6);
}
}
}
}
/*
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);
}
}
}

182
mod/add.scad Normal file
View File

@@ -0,0 +1,182 @@
/*
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_x, size_y, size_z, data_1, data_2, data_3, data_4)
type =
loc_x =
loc_y =
loc_z =
face =
rotation =
size[0] = size_x
size[1] = size_y
size[2] = size_z
data[0] =
data[1] =
data[2] =
*/
module add(type, loc_x, loc_y, loc_z, face, rotation, size_x, size_y, size_z, data_1, data_2, data_3, data_4) {
if(type == "rectangle") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) slab_r([size_x,size_y,size_z],data_4);
}
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 == "text") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) linear_extrude(height = size_z) text(data_3, size=data_1);
}
if(type == "art") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) art(data_1,data_2,data_3);
}
if(type == "button") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) button(data_3,[size_x,size_y,size_z],data_4,data_1);
}
if(type == "button_top") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) button_assembly(data_3,size_x,size_z);
}
if(type == "pcb_holder") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) pcb_holder([size_x,size_y,size_z],data_1);
}
if(type == "batt_holder") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) batt_holder(data_1);
}
if(type == "hk_uart_holder") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hk_uart_holder();
}
if(type == "hk_uart_strap") {
color("grey",1) translate([loc_x,loc_y,loc_z]) rotate(rotation) hk_uart_strap();
}
if(type == "standoff") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) standoff(data_4);
}
if(type == "hd_holder") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hd_mount(data_1,data_3,"horizontal","none");
}
if(type == "hd_vertleft") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hd_mount(data_1,data_3,"vertical","left");
}
if(type == "hd_vertright") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hd_mount(data_1,data_3,"vertical","right");
}
if(type == "hd25") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hd25(data_1);
}
if(type == "hd35") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hd35();
}
if(type == "hk_wb2") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hk_wb2();
}
if(type == "hc4_oled") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hc4_oled();
}
if(type == "hc4_oled_holder") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hc4_oled_holder(face,size_z);
}
if(type == "h2_netcard") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) h2_netcard();
}
if(type == "hk_lcd35") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hk35_lcd();
}
if(type == "hk_m1s_ups") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hk_m1s_ups();
}
if(type == "hk_uart") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hk_uart();
}
if(type == "hk_vu7c") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hk_vu7c(data_1,data_2);
}
if(type == "hk_boom") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hk_boom(data_1,data_3);
}
if(type == "boom_speaker") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hk_boom_speaker(data_3,true,data_1);
}
if(type == "boom_grill") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hk_boom_grill(data_3,size_z);
}
if(type == "boom_speaker_holder") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) boom_speaker_holder(data_1);
}
if(type == "hk_speaker") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hk_speaker();
}
if(type == "fan_cover") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) fan_cover(size_x, size_z, data_1);
}
if(type == "vent_panel_hex") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) vent_panel_hex(x=size_x, y=size_y, thick=size_z,
cell_size=data_1, cell_spacing=data_2, border=data_4, borders=data_3);
}
if(type == "feet") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) feet(size_x, size_z);
}
if(type == "access_port") {
if(rotation[2] == 180) {
translate([loc_x+size_x,loc_y+size_y,loc_z]) rotate(rotation) access_port([size_x,size_y,size_z],data_3);
}
else {
translate([loc_x,loc_y,loc_z]) rotate(rotation) access_port([size_x,size_y,size_z],data_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_3);
}
else {
color("grey",1) translate([loc_x,loc_y,loc_z]) rotate(rotation) access_cover([size_x,size_y,size_z],data_3);
}
}
if(type == "boom_vring") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) boom_vring(data_1);
}
if(type == "h3_port_extender") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) h3_port_extender(data_3);
}
if(type == "h3_port_extender_holder") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) h3_port_extender_holder(data_3,data_1);
}
if(type == "hk_pwr_button") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hk_pwr_button();
}
if(type == "keyhole") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) keyhole(data_4);
}
if(type == "dsub") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) dsub(data_4);
}
if(type == "nut_holder") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) nut_holder(data_1, data_2, size_x, size_y, size_z);
}
if(type == "standoff") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) standoff(data_4);
}
}

699
mod/case_bottom.scad Normal file
View File

@@ -0,0 +1,699 @@
/*
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_bottom
DESCRIPTION: creates case bottom for supported designs
TODO: none
USAGE: case_bottom(case_design)
*/
module case_bottom(case_design) {
difference() {
union() {
difference() {
union() {
if(case_design == "shell") {
difference() {
translate([(width/2)-wallthick-gap,(depth/2)-wallthick-gap,bottom_height/2])
cube_fillet_inside([width,depth,bottom_height],
vertical=[c_fillet,c_fillet,c_fillet,c_fillet],
top=[0,0,0,0], bottom=[fillet,fillet,fillet,fillet,fillet], $fn=90);
translate([(width/2)-wallthick-gap,
(depth/2)-wallthick-gap,(bottom_height/2)+floorthick])
cube_fillet_inside([width-(wallthick*2),depth-(wallthick*2),bottom_height],
vertical=[c_fillet-1,c_fillet-1,c_fillet-1,c_fillet-1],
top=[0,0,0,0], bottom=[fillet,fillet,fillet,fillet,fillet], $fn=90);
}
}
if(case_design == "panel") {
union() {
translate([-gap,-gap,0])
cube([width-(2*wallthick),depth-(2*wallthick),floorthick]);
translate([(width*(1/5))-8-(wallthick+gap),depth-(2*wallthick)-gap-adj,0])
cube([8,wallthick+2*adj,floorthick]);
translate([width-(width*(1/5))-(wallthick+gap),depth-(2*wallthick)-gap-adj,0])
cube([8,wallthick+2*adj,floorthick]);
translate([(width*(1/5))-8-(wallthick+gap),-wallthick-gap+adj,0])
cube([8,wallthick+2*adj,floorthick]);
translate([width-(width*(1/5))-(wallthick+gap),-wallthick-gap+adj,0])
cube([8,wallthick+2*adj,floorthick]);
}
}
if(case_design == "stacked") {
translate([(width/2)-wallthick-gap,(depth/2)-wallthick-gap,floorthick/2])
cube_fillet_inside([width-(2*wallthick),depth-(2*wallthick),floorthick],
vertical=[c_fillet,c_fillet,c_fillet,c_fillet],
top=[0,0,0,0], bottom=[0,0,0,0], $fn=90);
}
if(case_design == "tray") {
difference() {
translate([(width/2)-wallthick-gap,(depth/2)-wallthick-gap,(bottom_height)/2])
cube_fillet_inside([width,depth,bottom_height],
vertical=[0,0,0,0], top=[0,0,0,0],
bottom=[fillet,fillet,fillet,fillet,fillet], $fn=90);
translate([(width/2)-wallthick-gap,(depth/2)-wallthick-gap,(bottom_height/2)+floorthick])
cube_fillet_inside([width-(wallthick*2),depth-(wallthick*2),bottom_height+adj],
vertical=[c_fillet-1,c_fillet-1,c_fillet-1,c_fillet-1],
top=[0,0,0,0],bottom=[2,2,2,2], $fn=90);
}
// right side nut
translate([width-wallthick-gap-wallthick-4+adj,wallthick+gap+10,
floorthick+3.4]) rotate([90,0,90])
cylinder(d=10, h=4, $fn=6);
// left side nut
translate([-adj-gap,wallthick+gap+10,floorthick+3.4])
rotate([90,0,90]) cylinder(d=10, h=4, $fn=6);
if(depth >= 75 && sbc_model != "visionfive2" && sbc_model != "visionfive2q" &&
sbc_model != "rock5b" && sbc_model != "rock5bq" && sbc_model != "rock5b-v1.3") {
translate([width-wallthick-gap-wallthick-4+adj,depth-wallthick-gap-10,
floorthick+3.4]) rotate([90,0,90]) cylinder(d=10, h=4, $fn=6);
translate([-adj-gap,depth-wallthick-gap-10,floorthick+3.4])
rotate([90,0,90]) cylinder(d=10, h=4, $fn=6);
}
else {
if(sbc_model == "visionfive2" || sbc_model == "visionfive2q" || sbc_model == "rock5b" ||
sbc_model == "rock5bq" || sbc_model == "rock5b-v1.3") {
translate([width-wallthick-gap-wallthick-4+adj,wallthick+gap+58,
floorthick+3.4]) rotate([90,0,90]) cylinder(d=10, h=4, $fn=6);
translate([-adj-gap,wallthick+gap+58,floorthick+3.4])
rotate([90,0,90]) cylinder(d=10, h=4, $fn=6);
}
else {
translate([width-wallthick-gap-wallthick-4+adj,wallthick+gap+40,
floorthick+3.4]) rotate([90,0,90]) cylinder(d=10, h=4, $fn=6);
translate([-adj-gap,wallthick+gap+40,floorthick+3.4])
rotate([90,0,90]) cylinder(d=10, h=4, $fn=6);
}
}
// front panel
if(case_style == "sides" || case_style == "vu5" || case_style == "vu7") {
translate([-wallthick-gap,depth-(2*wallthick)-gap,bottom_height-adj])
rotate([0,0,0]) cube([width,wallthick,top_height]);
}
else {
translate([-wallthick-gap,depth-(2*wallthick)-gap,bottom_height-adj])
rotate([0,0,0]) cube([width,wallthick,top_height-floorthick]);
}
// rear panel
translate([-wallthick-gap,-wallthick-gap,bottom_height-adj])
cube([width,wallthick,top_height-floorthick]);
}
if(case_design == "round") {
difference() {
translate([pcb_width/2,pcb_depth/2,bottom_height/2]) rotate([0,0,30])
cylinder_fillet_inside(h=bottom_height, r=case_diameter/2,
top=0, bottom=fillet, $fn=case_fn, fillet_fn=case_ffn, center=true);
translate([pcb_width/2,pcb_depth/2,(bottom_height/2)+floorthick]) rotate([0,0,30])
cylinder_fillet_inside(h=bottom_height+adj, r=(case_diameter/2)-lip/2,
top=0, bottom=fillet-1, $fn=case_fn, fillet_fn=case_ffn, center=true);
difference() {
translate([pcb_width/2,pcb_depth/2,bottom_height-lip]) rotate([0,0,30])
cylinder(h=lip+adj, r=(case_diameter/2)+1, $fn=case_fn);
translate([pcb_width/2,pcb_depth/2,bottom_height-lip]) rotate([0,0,30])
cylinder(h=lip+2*adj, r=(case_diameter/2)-lip/4, $fn=case_fn);
}
}
difference() {
translate([pcb_width/2,pcb_depth/2,(bottom_height/2)+2*floorthick]) rotate([0,0,30])
cylinder_fillet_inside(h=bottom_height+adj+floorthick+lip,
r=(case_diameter/2)-lip/2,top=0,bottom=fillet-1, $fn=case_fn,
fillet_fn=case_ffn, center=true);
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([-16,(depth/2)-150,-adj])
cube([width+10,300,case_z-2*floorthick-2]);
translate([width-9,(depth/2)-62.5,bottom_height-2*adj])
cube([20,110,top_height-2*floorthick-2]);
}
else {
translate([-width/2,0,-adj])
cube([300,depth+100,case_z-2*floorthick-2]);
translate([(-width+50)/2,-50,bottom_height-2*adj])
cube([width+50,50+adj,top_height-2*floorthick-2]);
}
}
}
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/2]) rotate([0,0,30])
cylinder_fillet_inside(h=bottom_height, r=case_diameter/2,
top=0, bottom=fillet, $fn=6, fillet_fn=case_ffn, center=true);
translate([pcb_width/2,pcb_depth/2,(bottom_height/2)+floorthick]) rotate([0,0,30])
cylinder_fillet_inside(h=bottom_height+adj,r=(case_diameter/2)-lip/2,top=0,
bottom=fillet-1,$fn=6,fillet_fn=case_ffn, center=true);
difference() {
translate([pcb_width/2,pcb_depth/2,bottom_height-lip]) rotate([0,0,30])
cylinder(h=lip+adj,r=(case_diameter/2)+1, $fn=6);
translate([pcb_width/2,pcb_depth/2,bottom_height-lip]) rotate([0,0,30])
cylinder(h=lip+2*adj,r=(case_diameter/2)-lip/4, $fn=6);
}
}
difference() {
translate([pcb_width/2,pcb_depth/2,(bottom_height/2)+2*floorthick]) rotate([0,0,30])
cylinder_fillet_inside(h=bottom_height+adj+floorthick+lip,
r=(case_diameter/2)-lip/2,top=0, bottom=fillet-1, $fn=6,
fillet_fn=case_ffn, center=true);
translate([-16,(depth/2)-150,-adj])
cube([width+10,300,case_z-2*floorthick-2]);
translate([width-9,(depth/2)-62.5,bottom_height-2*adj])
cube([20,110,top_height-2*floorthick-2]);
}
}
else {
difference() {
translate([pcb_width/2,pcb_depth/2,bottom_height/2]) rotate([0,0,0])
cylinder_fillet_inside(h=bottom_height, r=hex_diameter/2,
top=0, bottom=fillet, $fn=6, fillet_fn=case_ffn, center=true);
translate([pcb_width/2,pcb_depth/2,(bottom_height/2)+floorthick]) rotate([0,0,0])
cylinder_fillet_inside(h=bottom_height+adj,r=(hex_diameter/2)-lip/2,top=0,
bottom=fillet-1,$fn=6,fillet_fn=case_ffn, center=true);
difference() {
translate([pcb_width/2,pcb_depth/2,bottom_height-lip]) rotate([0,0,0])
cylinder(h=lip+adj,r=(hex_diameter/2)+1, $fn=6);
translate([pcb_width/2,pcb_depth/2,bottom_height-lip]) rotate([0,0,0])
cylinder(h=lip+2*adj,r=(hex_diameter/2)-lip/4, $fn=6);
}
}
difference() {
translate([pcb_width/2,pcb_depth/2,(bottom_height/2)+2*floorthick]) rotate([0,0,0])
cylinder_fillet_inside(h=bottom_height+adj+floorthick+lip,
r=(hex_diameter/2)-lip/2,top=0, bottom=fillet-1, $fn=6,
fillet_fn=case_ffn, center=true);
translate([-width/2,0,-adj])
cube([300,depth+100,case_z-2*floorthick-2]);
translate([(-width+50)/2,-50,bottom_height-2*adj])
cube([width+50,50+adj,top_height-2*floorthick-2]);
}
}
}
if(case_design == "snap") {
difference() {
translate([(width/2)-wallthick-gap,(depth/2)-wallthick-gap,(floorthick+case_z)/2])
cube_fillet_inside([width,depth,floorthick+case_z],
vertical=[c_fillet,c_fillet,c_fillet,c_fillet],
top=[0,0,0,0], bottom=[fillet,fillet,fillet,fillet,fillet], $fn=90);
translate([(width/2)-wallthick-gap,(depth/2)-wallthick-gap,floorthick+(floorthick+case_z)/2])
cube_fillet_inside([width-(wallthick*2),depth-(wallthick*2),case_z+floorthick],
vertical=[c_fillet-1,c_fillet-1,c_fillet-1,c_fillet-1],
top=[0,0,0,0], bottom=[fillet,fillet,fillet,fillet,fillet], $fn=90);
// snap top indent
translate([-gap-wallthick+.75,(depth/2)-(depth*.75)/2-gap-wallthick,case_z-.5])
rotate([0,45,0]) cube([4,depth*.75,4]);
translate([width-wallthick-gap-6.25,(depth/2)-(depth*.75)/2-gap-wallthick,case_z-.5])
rotate([0,45,0]) cube([4,depth*.75,4]);
}
}
if(case_design == "fitted") {
difference() {
translate([(width/2)-wallthick-gap,(depth/2)-wallthick-gap,case_z/2])
cube_fillet_inside([width,depth,case_z],
vertical=[c_fillet,c_fillet,c_fillet,c_fillet],
top=[0,0,0,0], bottom=[fillet,fillet,fillet,fillet,fillet], $fn=90);
translate([(width/2)-wallthick-gap,
(depth/2)-wallthick-gap,(case_z/2)+floorthick])
cube_fillet_inside([width-(wallthick*2),depth-(wallthick*2),case_z],
vertical=[c_fillet-1,c_fillet-1,c_fillet-1,c_fillet-1],
top=[0,0,0,0], bottom=[fillet,fillet,fillet,fillet,fillet], $fn=90);
difference() {
translate([(width/2)-wallthick-gap,(depth/2)-wallthick-gap,case_z-lip/2])
cube_fillet_inside([width+adj,depth+adj,lip+adj],
vertical=[c_fillet,c_fillet,c_fillet,c_fillet],
top=[0,0,0,0],bottom=[fillet,fillet,fillet,fillet,fillet], $fn=90);
translate([(width/2)-wallthick-gap,(depth/2)-wallthick-gap,case_z-lip/2])
cube_fillet_inside([width-wallthick,depth-wallthick,lip+adj],
vertical=[c_fillet-1,c_fillet-1,c_fillet-1,c_fillet-1],top=[0,0,0,0],
bottom=[fillet,fillet,fillet,fillet,fillet], $fn=90);
}
}
}
// additive accessories
if(accessory_name != "none") {
for (i=[1:15: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];
size_y = accessory_data[a[0]][i+9];
size_z = accessory_data[a[0]][i+10];
data_1 = accessory_data[a[0]][i+11];
data_2 = accessory_data[a[0]][i+12];
data_3 = accessory_data[a[0]][i+13];
data_4 = accessory_data[a[0]][i+14];
if(class == "add1" && face == "bottom") {
parametric_move_add(type,loc_x,loc_y,loc_z,face,rotation,parametric,
size_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
}
}
}
// side attachment holes
if(case_design == "tray") {
// right side bottom attachment holes
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));
// right side bottom nut inset
translate([width-3.5-(2*wallthick)-gap-.6,wallthick+gap+10,
floorthick+3.4]) rotate([90,0,90]) cylinder(d=6.6, h=3.5, $fn=6);
// left side bottom attachment holes
translate([-wallthick-gap-adj,wallthick+gap+10,floorthick+3.4]) rotate([0,90,0])
cylinder(d=3, h=10+sidethick+(2*adj));
// left side bottom nut inset
translate([-gap+.6,wallthick+gap+10,floorthick+3.4])
rotate([90,0,90]) cylinder(d=6.6, h=3.5, $fn=6);
if(depth >= 75 && sbc_model != "visionfive2" && sbc_model != "visionfive2q" &&
sbc_model != "rock5b" && sbc_model != "rock5bq" && sbc_model != "rock5b-v1.3") {
translate([width-2*(wallthick+gap)-sidethick-adj,depth-wallthick-gap-10,
floorthick+3.4]) rotate([0,90,0])
cylinder(d=3, h=10+sidethick+(2*adj));
translate([-wallthick-gap-adj-6,depth-wallthick-gap-10,
floorthick+3.4]) rotate([0,90,0])
cylinder(d=3, h=10+sidethick+(2*adj));
translate([width-3.5-(2*wallthick)-gap-.6,depth-wallthick-gap-10,
floorthick+3.4])rotate([90,0,90]) cylinder(d=6.6, h=3.5, $fn=6);
translate([-gap+.6,depth-wallthick-gap-10,floorthick+3.4])
rotate([90,0,90]) cylinder(d=6.6, h=3.5, $fn=6);
}
else {
if(sbc_model == "visionfive2" || sbc_model == "visionfive2q" || sbc_model == "rock5b" ||
sbc_model == "rock5bq" || sbc_model == "rock5b-v1.3") {
translate([width-3*(wallthick+gap)-adj,wallthick+gap+58,
floorthick+3.4]) rotate([0,90,0])
cylinder(d=3, h=10+sidethick+(2*adj));
translate([-wallthick-gap-adj-6,wallthick+gap+58,
floorthick+3.4]) rotate([0,90,0])
cylinder(d=3, h=10+sidethick+(2*adj));
translate([width-3.5-(2*wallthick)-gap-.6,wallthick+gap+58,
floorthick+3.4])rotate([90,0,90]) cylinder(d=6.6, h=3.5, $fn=6);
translate([-gap+.6,wallthick+gap+58,floorthick+3.4])
rotate([90,0,90]) cylinder(d=6.6, h=3.5, $fn=6);
}
else {
translate([width-3*(wallthick+gap)-adj,wallthick+gap+40,
floorthick+3.4]) rotate([0,90,0]) cylinder(d=3, h=10+sidethick+(2*adj));
translate([-wallthick-gap-adj-6,wallthick+gap+40,
floorthick+3.4]) rotate([0,90,0]) cylinder(d=3, h=10+sidethick+(2*adj));
translate([width-3.5-(2*wallthick)-gap-.6,wallthick+gap+40,
floorthick+3.4])rotate([90,0,90]) cylinder(d=6.6, h=3.5, $fn=6);
translate([-gap+.6,wallthick+gap+40,floorthick+3.4])
rotate([90,0,90]) cylinder(d=6.6, h=3.5, $fn=6);
}
}
}
// pcb standoff holes
if(sbc_bottom_standoffs == true && bottom_standoff[5] != 4) {
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")) {
translate([pcbhole_x,pcbhole_y,-1]) cylinder(d=6.5, h=bottom_height);
}
}
}
// extended standoff holes
if(case_ext_standoffs == true) {
// right-rear standoff
if(width-pcb_loc_x-pcb_width >= 10 || pcb_loc_y >= 10) {
translate([width-(2*(wallthick+gap))-(c_fillet/2),(c_fillet/2),-1]) cylinder(d=6.5, h=bottom_height);
}
// right-front standoff
if((width-pcb_loc_x-pcb_width >= 10 && depth-pcb_loc_y-pcb_depth >= 10) || width-pcb_loc_x-pcb_width >= 10) {
translate([width-(c_fillet/2)-(2*(wallthick+gap)),
depth-(c_fillet/2)-(2*(wallthick+gap)),-1]) cylinder(d=6.5, h=bottom_height);
}
// left-rear standoff
if(pcb_loc_x >= 10 || pcb_loc_y >= 10) {
translate([(c_fillet/2),(c_fillet/2),-1]) cylinder(d=6.5, h=bottom_height);
}
// left-front standoff
if(pcb_loc_x >= 10 || depth-pcb_loc_y-pcb_depth >= 10) {
translate([(c_fillet/2),depth-(c_fillet/2)-(2*(wallthick+gap)),-1])
cylinder(d=6.5, h=bottom_height);
}
}
}
// 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") {
normal_standoff = [bottom_standoff[0],
bottom_height-pcb_z+pcb_loc_z+bottom_rear_left,
bottom_standoff[2],
bottom_standoff[3],
bottom_standoff[4],
bottom_standoff[5],
bottom_standoff[6],
bottom_standoff[7],
bottom_standoff[8],
bottom_standoff[9],
bottom_standoff[10]];
translate([pcbhole_x,pcbhole_y,0]) standoff(normal_standoff);
}
if (pcbhole_pos == "left_front") {
normal_standoff = [bottom_standoff[0],
bottom_height-pcb_z+pcb_loc_z+bottom_front_left,
bottom_standoff[2],
bottom_standoff[3],
bottom_standoff[4],
bottom_standoff[5],
bottom_standoff[6],
bottom_standoff[7],
bottom_standoff[8],
bottom_standoff[9],
bottom_standoff[10]];
translate([pcbhole_x,pcbhole_y,0]) standoff(normal_standoff);
}
if (pcbhole_pos == "right_rear") {
normal_standoff = [bottom_standoff[0],
bottom_height-pcb_z+pcb_loc_z+bottom_rear_right,
bottom_standoff[2],
bottom_standoff[3],
bottom_standoff[4],
bottom_standoff[5],
bottom_standoff[6],
bottom_standoff[7],
bottom_standoff[8],
bottom_standoff[9],
bottom_standoff[10]];
translate([pcbhole_x,pcbhole_y,0]) standoff(normal_standoff);
}
if (pcbhole_pos == "right_front") {
normal_standoff = [bottom_standoff[0],
bottom_height-pcb_z+pcb_loc_z+bottom_front_right,
bottom_standoff[2],
bottom_standoff[3],
bottom_standoff[4],
bottom_standoff[5],
bottom_standoff[6],
bottom_standoff[7],
bottom_standoff[8],
bottom_standoff[9],
bottom_standoff[10]];
translate([pcbhole_x,pcbhole_y,0]) standoff(normal_standoff);
}
}
}
}
// extended standoffs
if(case_ext_standoffs == true) {
// right-rear standoff
if(width-pcb_loc_x-pcb_width >= 10 || pcb_loc_y >= 10) {
translate([width-(2*(wallthick+gap))-(c_fillet/2),(c_fillet/2),0]) standoff(bottom_ext_standoff);
}
// right-front standoff
if((width-pcb_loc_x-pcb_width >= 10 && depth-pcb_loc_y-pcb_depth >= 10) || width-pcb_loc_x-pcb_width >= 10) {
translate([width-(c_fillet/2)-(2*(wallthick+gap)),
depth-(c_fillet/2)-(2*(wallthick+gap)),0]) standoff(bottom_ext_standoff);
}
// left-rear standoff
if(pcb_loc_x >= 10 || pcb_loc_y >= 10) {
translate([(c_fillet/2),(c_fillet/2),0]) standoff(bottom_ext_standoff);
}
// left-front standoff
if(pcb_loc_x >= 10 || depth-pcb_loc_y-pcb_depth >= 10) {
translate([(c_fillet/2),depth-(c_fillet/2)-(2*(wallthick+gap)),0])
standoff(bottom_ext_standoff);
}
}
// standoff sidewall support
if(sidewall_support == true && 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];
pcb_side_pos = sbc_data[s[0]][i+10][2];
pcbhole_pos = sbc_data[s[0]][i+10][4];
ex_stand = 0;
if (class == "pcbhole" && id == pcb_id && (pcbhole_pos == "left_rear" || pcbhole_pos == "left_front" ||
pcbhole_pos == "right_rear" || pcbhole_pos == "right_front")) {
ex_stand = pcbhole_pos == "left_rear" ? bottom_rear_left :
pcbhole_pos == "left_front" ? bottom_front_left :
pcbhole_pos == "right_rear" ? bottom_rear_right :
pcbhole_pos == "right_front" ? bottom_front_right : 0;
if(pcb_side_pos == "rear") {
translate([pcbhole_x-1, pcbhole_y-(bottom_standoff[0]/2)-(gap-adj)-1.4, 0])
cube([2,gap+1.6,bottom_height-pcb_z+pcb_loc_z+ex_stand]);
}
if(pcb_side_pos == "front") {
translate([pcbhole_x-1, pcbhole_y+(bottom_standoff[0]/2)-.6+adj,0])
cube([2,gap+1.6,bottom_height-pcb_z+pcb_loc_z+ex_stand]);
}
if(pcb_side_pos == "left") {
translate([pcbhole_x-(bottom_standoff[0]/2)-2.4+adj,pcbhole_y-1,0])
cube([gap+1.6,2,bottom_height-pcb_z+pcb_loc_z+ex_stand]);
}
if(pcb_side_pos == "right") {
translate([pcbhole_x+(bottom_standoff[0]/2)-.6+adj,pcbhole_y-1,0])
cube([gap+1.6,2,bottom_height-pcb_z+pcb_loc_z+ex_stand]);
}
}
}
}
// extended standoff sidewall support
if(case_ext_standoffs == true && sidewall_support == true) {
// right-rear standoff
if(width-pcb_loc_x-pcb_width >= 10 || pcb_loc_y >= 10) {
translate([width-(2*(wallthick+gap))-(c_fillet/2)+(bottom_ext_standoff[0]/2)-.5,
(c_fillet/2)-1,0]) cube([gap+adj+2,2,bottom_ext_standoff[1]]);
}
// right-front standoff
if((width-pcb_loc_x-pcb_width >= 10 && depth-pcb_loc_y-pcb_depth >= 10)
|| width-pcb_loc_x-pcb_width >= 10) {
translate([width-(2*(wallthick+gap))-(c_fillet/2)+(bottom_ext_standoff[0]/2)-.5,
depth-(c_fillet/2)-(2*(wallthick+gap))-1,0])
cube([gap+adj+2,2,bottom_ext_standoff[1]]);
}
// left-rear standoff
if(pcb_loc_x >= 10 || pcb_loc_y >= 10) {
translate([(c_fillet/2)-(wallthick+gap)-(bottom_ext_standoff[0]/2)+.6,
(c_fillet/2)-1,0]) cube([gap+adj+2,2,bottom_ext_standoff[1]]);
}
// left-front standoff
if(pcb_loc_x >= 10 || depth-pcb_loc_y-pcb_depth >= 10) {
translate([(c_fillet/2)-(wallthick+gap)-(bottom_ext_standoff[0]/2)+.6,
depth-(c_fillet/2)-(2*(wallthick+gap))-1,0])
cube([gap+adj+2,2,bottom_ext_standoff[1]]);
}
}
}
// subtractive accessories
if(accessory_name != "none") {
for (i=[1:15: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];
size_y = accessory_data[a[0]][i+9];
size_z = accessory_data[a[0]][i+10];
data_1 = accessory_data[a[0]][i+11];
data_2 = accessory_data[a[0]][i+12];
data_3 = accessory_data[a[0]][i+13];
data_4 = accessory_data[a[0]][i+14];
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_1,data_2,data_3,data_4);
}
else {
#parametric_move_sub(type,loc_x,loc_y,loc_z,face,rotation,parametric,
size_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
}
// create openings for additive
if (class == "add2" && face == "bottom" && type == "standoff") {
parametric_move_sub("round",loc_x,loc_y,loc_z-.1,face,rotation,parametric,
6.5,size_y,floorthick+1,data_1,data_2,data_3,data_4);
}
if ((class == "add1" || class == "add2") && type == "uart_holder") {
if(accessory_highlight == false) {
parametric_move_sub("microusb",loc_x+5.25,loc_y-5,loc_z+4,face,rotation,parametric,
0,0,0,data_1,data_2,data_3,data_4);
}
else {
#parametric_move_sub("microusb",loc_x+5.25,loc_y-5,loc_z+4,face,rotation,parametric,
0,0,0,data_1,data_2,data_3,data_4);
}
}
if ((class == "add1" || class == "add2") && face == "bottom" && type == "hc4_oled_holder") {
parametric_move_sub("rectangle",loc_x+1,loc_y+1.75,loc_z+25.5,face,rotation,parametric,
26.5,wallthick+gap+4,15,data_1,data_2,data_3,[.1,.1,.1,.1]);
}
if ((class == "add1" || class == "add2") && face == "bottom" && type == "access_port") {
if(data_3 == "landscape") {
if(rotation[2] == 180) {
parametric_move_sub("rectangle",loc_x-6+size_x,loc_y+.5+size_y,loc_z-adj,face,rotation,
parametric,size_x-17,size_y-1,floorthick+1,data_1,data_2,data_3,[.1,.1,.1,.1]);
parametric_move_sub("rectangle",loc_x-size_x+12.5+size_x,loc_y-(size_y/2)+6+size_y,loc_z-adj,
face,rotation,parametric,5.5,10.5,floorthick+.12,data_1,data_2,data_3,[5.5,5.5,5.5,5.5]);
}
else {
parametric_move_sub("rectangle",loc_x+6,loc_y-.5,loc_z-adj,face,rotation,
parametric,size_x-17,size_y-1,floorthick+1,data_1,data_2,data_3,[.1,.1,.1,.1]);
parametric_move_sub("rectangle",loc_x+size_x-12.5,loc_y+(size_y/2)-6,loc_z-adj,face,rotation,
parametric,5.5,10.5,floorthick+.12,data_1,data_2,data_3,[5.5,5.5,5.5,5.5]);
}
}
else {
if(rotation[2] == 180) {
if(data_3 == "portrait") {
parametric_move_sub("rectangle",loc_x+size_x-.5,loc_y+size_y-5.75,loc_z-adj,face,
rotation,parametric,size_x-1,size_y-17,floorthick+1,data_1,data_2,data_3,[.1,.1,.1,.1]);
parametric_move_sub("rectangle",loc_x-(size_x/2)+5+size_x,loc_y-size_y+12.5+size_y,
loc_z-adj,face,rotation,parametric,10.5,5.5,floorthick+.12,data_1,data_2,data_3,
[5.5,5.5,5.5,5.5]);
}
else {
parametric_move_sub("rectangle",loc_x-.5,loc_y-5.75,loc_z-adj,face,rotation,
parametric,size_x-1,size_y-17,floorthick+1,data_1,data_2,data_3,[.1,.1,.1,.1]);
parametric_move_sub("rectangle",loc_x-(size_x/2)+5,loc_y-size_y+12.5,loc_z-adj,face,
rotation,parametric,10.5,5.5,floorthick+.12,data_1,data_2,data_3,[5.5,5.5,5.5,5.5]);
}
}
else {
parametric_move_sub("rectangle",loc_x+.5,loc_y+5.75,loc_z-adj,face,rotation,
parametric,size_x-1,size_y-17,floorthick+1,data_1,data_2,data_3,[.1,.1,.1,.1]);
parametric_move_sub("rectangle",loc_x+(size_x/2)-5,loc_y+size_y-12.5,loc_z-adj,face,rotation,
parametric,10.5,5.5,floorthick+.12,data_1,data_2,data_3,[5.5,5.5,5.5,5.5]);
}
}
}
if ((class == "model") && face == "bottom" && type == "h2_netcard") {
parametric_move_sub("rectangle",loc_x+25,loc_y-6,loc_z-14,face,rotation,
parametric,68.5,wallthick+3,14.5,data_1,data_2,data_3,[1,1,1,1]);
}
if ((class == "add1" || class == "add2") && face == "bottom" && type == "button") {
if(data_3 == "recess") {
#parametric_move_sub("sphere",loc_x,loc_y,loc_z,face,rotation,
parametric,size_x-1,size_y,size_z,data_1,data_2,data_3,0);
}
if(data_3 == "cutout") {
parametric_move_sub("rectangle",loc_x+10,loc_y+4,loc_z-adj,face,rotation,
parametric,size_x+2,size_y+1,size_z+2*adj,data_1,data_2,data_3,[.1,.1,.1,.1]);
}
}
}
}
// sbc openings
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);
}
// 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];
id = sbc_data[s[0]][i+3];
loc_x = sbc_data[s[0]][i+4]+pcb_loc_x;
loc_y = sbc_data[s[0]][i+5]+pcb_loc_y;
loc_z = sbc_data[s[0]][i+6]+pcb_loc_z;
side = sbc_data[s[0]][i+7];
rotation = sbc_data[s[0]][i+8];
indent(loc_x, loc_y, bottom_height+pcb_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/2])
cube_negative_fillet([width,depth,bottom_height], radius=-1,
vertical=[c_fillet,c_fillet,c_fillet,c_fillet], top=[0,0,0,0],
bottom=[fillet,fillet,fillet,fillet,fillet], $fn=90);
}
}
// additive accessories
if(accessory_name != "none") {
for (i=[1:15: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];
size_y = accessory_data[a[0]][i+9];
size_z = accessory_data[a[0]][i+10];
data_1 = accessory_data[a[0]][i+11];
data_2 = accessory_data[a[0]][i+12];
data_3 = accessory_data[a[0]][i+13];
data_4 = accessory_data[a[0]][i+14];
if(class == "add2" && face == "bottom") {
parametric_move_add(type,loc_x,loc_y,loc_z,face,rotation,parametric,
size_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
}
}
}

293
mod/case_folded.scad Normal file
View File

@@ -0,0 +1,293 @@
/*
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_style)
case_design = paper
case_style = split-top, full-top
*/
module case_folded(case_design, case_style) {
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_style == "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_style == "full-top" || case_style == "none") {
// 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)]);
}
}

361
mod/case_side.scad Normal file
View File

@@ -0,0 +1,361 @@
/*
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, case_style, side)
*/
module case_side(case_design, case_style, 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 == "tray" && case_style == "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" && case_style == "vu5") {
cheight = case_z+90;
vesa = 75;
vu_holder(case_style,side,vesa,cheight);
}
if(case_design == "tray" && case_style == "vu7") {
cheight = case_z+122;
vesa = 100;
vu_holder(case_style,side,vesa,cheight);
}
// additive accessories
if(accessory_name != "none") {
for (i=[1:15: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];
size_y = accessory_data[a[0]][i+9];
size_z = accessory_data[a[0]][i+10];
data_1 = accessory_data[a[0]][i+11];
data_2 = accessory_data[a[0]][i+12];
data_3 = accessory_data[a[0]][i+13];
data_4 = accessory_data[a[0]][i+14];
if (class == "add1" && face == side) {
parametric_move_add(type,loc_x,loc_y,loc_z,face,rotation,parametric,
size_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
}
}
}
if(accessory_name != "none") {
for (i=[1:15: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];
size_y = accessory_data[a[0]][i+9];
size_z = accessory_data[a[0]][i+10];
data_1 = accessory_data[a[0]][i+11];
data_2 = accessory_data[a[0]][i+12];
data_3 = accessory_data[a[0]][i+13];
data_4 = accessory_data[a[0]][i+14];
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_1,data_2,data_3,data_4);
}
else {
#parametric_move_sub(type,loc_x,loc_y,loc_z,face,rotation,parametric,
size_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
}
// create openings for additive
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_1,data_2,data_3,data_4);
}
else {
#parametric_move_sub(type,loc_x,loc_y,loc_z,face,rotation,parametric,
size_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
}
// create openings for additive
if (class == "add2" && face == "bottom" && type == "standoff") {
parametric_move_sub("round",loc_x,loc_y,-.1,face,rotation,parametric,
6.5,size_y,floorthick+1,data_1,data_2,data_3,data_4);
}
if ((class == "add1" || class == "add2") && face == "bottom" && type == "uart_holder") {
if(accessory_highlight == false) {
parametric_move_sub("microusb",loc_x+5.25,loc_y-5,loc_z+4,face,rotation,parametric,
0,0,0,data_1,data_2,data_3,data_4);
}
else {
#parametric_move_sub("microusb",loc_x+5.25,loc_y-5,loc_z+4,face,rotation,parametric,
0,0,0,data_1,data_2,data_3,data_4);
}
}
if ((class == "add1" || class == "add2") && face == "bottom" && type == "hc4_oled_holder") {
parametric_move_sub("rectangle",loc_x+1,loc_y+1.75,loc_z+25.5,face,rotation,
parametric,26.5,wallthick+gap+4,15,data_1,data_2,data_3,[.1,.1,.1,.1]);
}
if ((class == "add1" || class == "add2") && face == "bottom" && type == "access_port") {
if(data_3 == "landscape") {
parametric_move_sub("rectangle",loc_x+6,loc_y-.5,loc_z-adj,face,rotation,
parametric,size_x-17,size_y-1,floorthick+1,data_1,data_2,data_3,[.1,.1,.1,.1]);
parametric_move_sub("rectangle",loc_x+size_x-12.5,loc_y+(size_y/2)-6,loc_z-adj,face,rotation,
parametric,5.5,10.5,floorthick+.12,data_1,data_2,data_3,[5.5,5.5,5.5,5.5]);
}
else {
parametric_move_sub("rectangle",loc_x+.5,loc_y+5.75,loc_z-adj,face,rotation,parametric,
size_x-1,size_y-17,floorthick+1,data_1,data_2,data_3,[.1,.1,.1,.1]);
parametric_move_sub("rectangle",loc_x+(size_x/2)-5,loc_y+size_y-12.5,loc_z-adj,face,rotation,
parametric,10.5,5.5,floorthick+.12,data_1,data_2,data_3,[5.5,5.5,5.5,5.5]);
}
}
if ((class == "model") && face == "bottom" && type == "h2_netcard") {
parametric_move_sub("rectangle",loc_x+25,loc_y-6,loc_z-14,face,rotation,
parametric,68.5,wallthick+3,14.5,data_1,data_2,data_3,[1,1,1,1]);
}
if ((class == "add1" || class == "add2") && face == "bottom" && type == "button") {
if(data_3 == "recess") {
parametric_move_sub("sphere",loc_x,loc_y,loc_z,face,rotation,
parametric,size_x-1,size_y,size_z,data_1,data_2,data_3,0);
}
if(data_3 == "cutout") {
parametric_move_sub("rectangle",loc_x+10,loc_y+4,loc_z-adj,face,rotation,
parametric,size_x+2,size_y+1,size_z+2*adj,data_1,data_2,data_3,[.1,.1,.1,.1]);
}
}
}
}
// sbc openings
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);
}
// 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];
id = sbc_data[s[0]][i+3];
loc_x = sbc_data[s[0]][i+4]+pcb_loc_x;
loc_y = sbc_data[s[0]][i+5]+pcb_loc_y;
loc_z = sbc_data[s[0]][i+6]+pcb_loc_z;
side = sbc_data[s[0]][i+7];
rotation = sbc_data[s[0]][i+8];
indent(loc_x, loc_y, bottom_height+pcb_loc_z-adj, rotation[2], side, class, type, wallthick, gap, floorthick, pcb_z);
}
}
}
if(accessory_name != "none") {
for (i=[1:15: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];
size_y = accessory_data[a[0]][i+9];
size_z = accessory_data[a[0]][i+10];
data_1 = accessory_data[a[0]][i+11];
data_2 = accessory_data[a[0]][i+12];
data_3 = accessory_data[a[0]][i+13];
data_4 = accessory_data[a[0]][i+14];
if (class == "add2" && face == side) {
parametric_move_add(type,loc_x,loc_y,loc_z,face,rotation,parametric,
size_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
}
}
}

603
mod/case_top.scad Normal file
View File

@@ -0,0 +1,603 @@
/*
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) {
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=[c_fillet,c_fillet,c_fillet,c_fillet],
top=[fillet,fillet,fillet,fillet,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=[c_fillet-1,c_fillet-1,c_fillet-1,c_fillet-1],
top=[fillet,fillet,fillet,fillet,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 == "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=[c_fillet,c_fillet,c_fillet,c_fillet],
top=[0,0,0,0], bottom=[0,0,0,0], $fn=90);
}
if(case_design == "tray" && (case_style == "vu5" || case_style == "vu7" || case_style == "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" && case_style == "none") {
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,fillet,0,fillet,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=[c_fillet-1,c_fillet-1,c_fillet-1,c_fillet-1],
top=[0,0,0,0],bottom=[0,0,0,0], $fn=90);
// right side bottom attachment hole
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));
// left side bottom attachment hole
translate([-2*(wallthick+gap)-sidethick-adj,wallthick+gap+10,
floorthick+3.4]) rotate([0,90,0]) cylinder(d=3, h=10+sidethick+(2*adj));
if(depth >= 75 && sbc_model != "visionfive2" && sbc_model != "visionfive2q" &&
sbc_model != "rock5b" && sbc_model != "rock5bq" && sbc_model != "rock5b-v1.3") {
translate([width-2*(wallthick+gap)-sidethick-adj,depth-wallthick-gap-10,
floorthick+3.4]) rotate([0,90,0]) cylinder(d=3, h=10+sidethick+(2*adj));
translate([-wallthick-gap-adj-6,depth-wallthick-gap-10,
floorthick+3.4]) rotate([0,90,0]) cylinder(d=3, h=10+sidethick+(2*adj));
}
else {
if(sbc_model == "visionfive2" || sbc_model == "visionfive2q" || sbc_model == "rock5b" ||
sbc_model == "rock5bq" || sbc_model == "rock5b-v1.3") {
translate([width-2*(wallthick+gap)-sidethick-adj,wallthick+gap+58,
floorthick+3.4]) rotate([0,90,0]) cylinder(d=3, h=10+sidethick+(2*adj));
translate([-wallthick-gap-adj-6,wallthick+gap+58,
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+40,
floorthick+3.4]) rotate([0,90,0]) cylinder(d=3, h=10+sidethick+(2*adj));
translate([-wallthick-gap-adj-6,wallthick+gap+40,
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=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=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=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=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=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=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]) rotate([0,0,0])
cylinder_fillet_inside(h=top_height+lip, r=hex_diameter/2,
top=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,0]) cylinder_fillet_inside(h=top_height+lip, r=(hex_diameter/2)-wallthick,
top=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,0])
cylinder_fillet_inside(h=lip+2*adj, r=(hex_diameter/2)-wallthick/2+tol/2,
top=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=[c_fillet,c_fillet,c_fillet,c_fillet],
top=[0,0,0,0],bottom=[fillet,fillet,fillet,fillet,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=[c_fillet,c_fillet,c_fillet,c_fillet],
top=[0,0,0,0],bottom=[fillet,fillet,fillet,fillet,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=[c_fillet-1,c_fillet-1,c_fillet-1,c_fillet-1],top=[0,0,0,0],
bottom=[fillet,fillet,fillet,fillet,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])
rotate([0,0,0]) 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])
rotate([0,0,0]) 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=[c_fillet,c_fillet,c_fillet,c_fillet],
top=[fillet,fillet,fillet,fillet,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=[c_fillet-1,c_fillet-1,c_fillet-1,c_fillet-1],
top=[fillet,fillet,fillet,fillet,fillet],
bottom=[0,0,0,0], $fn=90);
}
}
if(accessory_name != "none") {
for (i=[1:15: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];
size_y = accessory_data[a[0]][i+9];
size_z = accessory_data[a[0]][i+10];
data_1 = accessory_data[a[0]][i+11];
data_2 = accessory_data[a[0]][i+12];
data_3 = accessory_data[a[0]][i+13];
data_4 = accessory_data[a[0]][i+14];
if (class == "add1" && face == "top") {
parametric_move_add(type,loc_x,loc_y,loc_z,face,rotation,
parametric,size_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
}
}
}
// pcb standoff holes
if(sbc_top_standoffs == true && top_standoff[5] != 4) {
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")) {
translate([pcbhole_x,pcbhole_y,top_height+1]) cylinder(d=6.5, h=top_height);
}
}
}
// extended standoff holes
if(case_ext_standoffs == true) {
// right-rear standoff
if(width-pcb_loc_x-pcb_width >= 10 || pcb_loc_y >= 10) {
translate([width-(2*(wallthick+gap))-(c_fillet/2),(c_fillet/2),top_height+1])
cylinder(d=6.5, h=top_height);
}
// right-front standoff
if((width-pcb_loc_x-pcb_width >= 10 && depth-pcb_loc_y-pcb_depth >= 10) || width-pcb_loc_x-pcb_width >= 10) {
translate([width-(c_fillet/2)-(2*(wallthick+gap)),
depth-(c_fillet/2)-(2*(wallthick+gap)),top_height+1]) cylinder(d=6.5, h=top_height);
}
// left-rear standoff
if(pcb_loc_x >= 10 || pcb_loc_y >= 10) {
translate([(c_fillet/2),(c_fillet/2),top_height+1]) cylinder(d=6.5, h=top_height);
}
// left-front standoff
if(pcb_loc_x >= 10 || depth-pcb_loc_y-pcb_depth >= 10) {
translate([+(c_fillet/2),depth-(c_fillet/2)-(2*(wallthick+gap)),
top_height+1]) cylinder(d=6.5, h=top_height+1);
}
}
}
// 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];
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") {
normal_standoff = [top_standoff[0],
top_height+pcb_loc_z+top_rear_left,
top_standoff[2],
top_standoff[3],
top_standoff[4],
top_standoff[5],
top_standoff[6],
top_standoff[7],
top_standoff[8],
top_standoff[9],
top_standoff[10]];
translate([pcbhole_x,pcbhole_y,case_z]) standoff(normal_standoff);
}
if (pcbhole_pos == "left_front") {
normal_standoff = [top_standoff[0],
top_height+pcb_loc_z+top_front_left,
top_standoff[2],
top_standoff[3],
top_standoff[4],
top_standoff[5],
top_standoff[6],
top_standoff[7],
top_standoff[8],
top_standoff[9],
top_standoff[10]];
translate([pcbhole_x,pcbhole_y,case_z]) standoff(normal_standoff);
}
if (pcbhole_pos == "right_rear") {
normal_standoff = [top_standoff[0],
top_height+pcb_loc_z+top_rear_right,
top_standoff[2],
top_standoff[3],
top_standoff[4],
top_standoff[5],
top_standoff[6],
top_standoff[7],
top_standoff[8],
top_standoff[9],
top_standoff[10]];
translate([pcbhole_x,pcbhole_y,case_z]) standoff(normal_standoff);
}
if (pcbhole_pos == "right_front") {
normal_standoff = [top_standoff[0],
top_height+pcb_loc_z+top_front_right,
top_standoff[2],
top_standoff[3],
top_standoff[4],
top_standoff[5],
top_standoff[6],
top_standoff[7],
top_standoff[8],
top_standoff[9],
top_standoff[10]];
translate([pcbhole_x,pcbhole_y,case_z]) standoff(normal_standoff);
}
}
}
}
// extended standoffs
if(case_ext_standoffs == true) {
// right-rear standoff
if(width-pcb_loc_x-pcb_width >= 10 || pcb_loc_y >= 10) {
translate([width-(2*(wallthick+gap))-(c_fillet/2),(c_fillet/2),case_z])
standoff(top_ext_standoff);
}
// right-front standoff
if((width-pcb_loc_x-pcb_width >= 10 && depth-pcb_loc_y-pcb_depth >= 10)
|| width-pcb_loc_x-pcb_width >= 10) {
translate([width-(c_fillet/2)-(2*(wallthick+gap)),
depth-(c_fillet/2)-(2*(wallthick+gap)),case_z]) standoff(top_ext_standoff);
}
// left-rear standoff
if(pcb_loc_x >= 10 || pcb_loc_y >= 10) {
translate([(c_fillet/2),(c_fillet/2),case_z]) standoff(top_ext_standoff);
}
// left-front standoff
if(pcb_loc_x >= 10 || depth-pcb_loc_y-pcb_depth >= 10) {
translate([(c_fillet/2),depth-(c_fillet/2)-(2*(wallthick+gap)),
case_z]) standoff(top_ext_standoff);
}
}
// standoff sidewall support
if(sidewall_support == true && 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];
pcb_side_pos = sbc_data[s[0]][i+10][2];
pcbhole_pos = sbc_data[s[0]][i+10][4];
ex_stand = 0;
if (class == "pcbhole" && id == pcb_id && (pcbhole_pos == "left_rear" || pcbhole_pos == "left_front" ||
pcbhole_pos == "right_rear" || pcbhole_pos == "right_front")) {
ex_stand = pcbhole_pos == "left_rear" ? top_rear_left :
pcbhole_pos == "left_front" ? top_front_left :
pcbhole_pos == "right_rear" ? top_rear_right :
pcbhole_pos == "right_front" ? top_front_right : 0;
if(pcb_side_pos == "rear") {
translate([pcbhole_x-1, pcbhole_y-(top_standoff[0]/2)-(gap-adj)-1.4, case_z-top_height-ex_stand])
cube([2,gap+1.6,top_height+ex_stand]);
}
if(pcb_side_pos == "front") {
translate([pcbhole_x-1, pcbhole_y+(top_standoff[0]/2)-.6+adj,case_z-top_height-ex_stand])
cube([2,gap+1.6,top_height+ex_stand]);
}
if(pcb_side_pos == "left") {
translate([pcbhole_x-(top_standoff[0]/2)-2.4+adj,pcbhole_y-1,case_z-top_height-ex_stand])
cube([gap+1.6,2,top_height+ex_stand]);
}
if(pcb_side_pos == "right") {
translate([pcbhole_x+(top_standoff[0]/2)-.6+adj,pcbhole_y-1,case_z-top_height-ex_stand])
cube([gap+1.6,2,top_height+ex_stand]);
}
}
}
}
// extended standoff sidewall support
if(case_ext_standoffs == true && sidewall_support == true) {
// right-rear standoff
if(width-pcb_loc_x-pcb_width >= 10 || pcb_loc_y >= 10) {
translate([width-(2*(wallthick+gap))-(c_fillet/2)+(top_ext_standoff[0]/2)-.6,
(c_fillet/2)-1,bottom_height]) cube([gap+adj+2,2,top_height]);
}
// right-front standoff
if((width-pcb_loc_x-pcb_width >= 10 && depth-pcb_loc_y-pcb_depth >= 10)
|| width-pcb_loc_x-pcb_width >= 10) {
translate([width-(2*(wallthick+gap))-(c_fillet/2)+(top_ext_standoff[0]/2)-.6,
depth-(c_fillet/2)-(2*(wallthick+gap))-1,bottom_height])
cube([gap+adj+2,2,top_height]);
}
// left-rear standoff
if(pcb_loc_x >= 10 || pcb_loc_y >= 10) {
translate([(c_fillet/2)-(wallthick+gap)-(top_ext_standoff[0]/2)+.6,(c_fillet/2)-1,
bottom_height]) cube([gap+adj+2,2,top_height]);
}
// left-front standoff
if(pcb_loc_x >= 10 || depth-pcb_loc_y-pcb_depth >= 10) {
translate([(c_fillet/2)-(wallthick+gap)-(top_ext_standoff[0]/2)+.6,
depth-(c_fillet/2)-(2*(wallthick+gap))-1, bottom_height])
cube([gap+adj+2,2,top_height]);
}
}
}
// subtractive accessories
if(accessory_name != "none") {
for (i=[1:15: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];
size_y = accessory_data[a[0]][i+9];
size_z = accessory_data[a[0]][i+10];
data_1 = accessory_data[a[0]][i+11];
data_2 = accessory_data[a[0]][i+12];
data_3 = accessory_data[a[0]][i+13];
data_4 = accessory_data[a[0]][i+14];
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_1,data_2,data_3,data_4);
}
else {
#parametric_move_sub(type,loc_x,loc_y,loc_z,face,rotation,
parametric,size_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
}
// create openings for additive
if (class == "add2" && face == "top" && type == "standoff") {
parametric_move_sub("round",loc_x,loc_y,loc_z,face,rotation,parametric,
6.5,size_y,floorthick+1,data_1,data_2,data_3,data_4);
}
if ((class == "add1" || class == "add2") && face == "bottom" && type == "uart_holder") {
if(accessory_highlight == false) {
parametric_move_sub("microusb",loc_x+5.25,loc_y-5,loc_z+4,face,rotation,parametric,
0,0,0,data_1,data_2,data_3,data_4);
}
else {
#parametric_move_sub("microusb",loc_x+5.25,loc_y-5,loc_z+4,face,rotation,parametric,
0,0,0,data_1,data_2,data_3,data_4);
}
}
if ((class == "add1" || class == "add2") && face == "bottom" && type == "hc4_oled_holder") {
parametric_move_sub("rectangle",loc_x+1,loc_y+1.75,loc_z+26,face,rotation,
parametric,26.5,wallthick+gap+4,14.5,data_1,data_2,data_3,[.1,.1,.1,.1]);
}
if ((class == "add1" || class == "add2") && face == "top" && type == "button") {
if(data_3 == "recess") {
parametric_move_sub("sphere",loc_x,loc_y,loc_z,face,rotation,
parametric,size_x-1,size_y,size_z,data_1,data_2,data_3,0);
}
if(data_3 == "cutout") {
parametric_move_sub("rectangle",loc_x+10,loc_y+4,loc_z-adj,face,rotation,
parametric,size_x+2,size_y+1,size_z+2*adj,data_1,data_2,data_3,[.1,.1,.1,.1]);
}
}
if (class == "model" && face == "bottom" && type == "hk_boom" &&
rotation[0] == 90 && rotation[1] == 0 && rotation[2] == 0) {
parametric_move_sub("round",loc_x+11,loc_y-4,loc_z,face,[0,0,0],
parametric,5,size_y,80,data_1,data_2,data_3,data_4);
parametric_move_sub("slot",loc_x+37.5,loc_y-4.75,loc_z,face,[0,0,0],
parametric,6,14,80,data_1,data_2,data_3,data_4);
}
}
}
// sbc openings
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);
}
// 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];
id = sbc_data[s[0]][i+3];
loc_x = sbc_data[s[0]][i+4]+pcb_loc_x;
loc_y = sbc_data[s[0]][i+5]+pcb_loc_y;
loc_z = sbc_data[s[0]][i+6]+pcb_loc_z;
side = sbc_data[s[0]][i+7];
rotation = sbc_data[s[0]][i+8];
indent(loc_x, loc_y, bottom_height+pcb_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=[c_fillet,c_fillet,c_fillet,c_fillet],
top=[fillet,fillet,fillet,fillet,fillet],
bottom=[0,0,0,0], $fn=90);
}
}
// additive accessories
if(accessory_name != "none") {
for (i=[1:15: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];
size_y = accessory_data[a[0]][i+9];
size_z = accessory_data[a[0]][i+10];
data_1 = accessory_data[a[0]][i+11];
data_2 = accessory_data[a[0]][i+12];
data_3 = accessory_data[a[0]][i+13];
data_4 = accessory_data[a[0]][i+14];
if (class == "add2" && face == "top") {
parametric_move_add(type,loc_x,loc_y,loc_z,face,rotation,parametric,
size_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
}
}
}

View File

@@ -6,7 +6,7 @@
function poly_sides_r(r) = (max(round(4 * r),3)+1);
// 2d primitive for outside fillets.
module fillet_2d_o(fillet_r, fillet_angle=90, fillet_fn=90) {
module fillet_2d_o(fillet_r, fillet_angle=90, fillet_fn=0) {
add=0.01;
f_fn=(fillet_fn>0) ? fillet_fn*4 : (ceil(poly_sides_r(fillet_r)/4)*4);
if (fillet_r>0) {
@@ -23,7 +23,7 @@ module fillet_2d_o(fillet_r, fillet_angle=90, fillet_fn=90) {
}
// 2d primitive for inside fillets.
module fillet_2d_i(fillet_r, fillet_angle=90, fillet_fn=90) {
module fillet_2d_i(fillet_r, fillet_angle=90, fillet_fn=0) {
add=0.01;
f_fn=(fillet_fn>0) ? fillet_fn*4 : (ceil(poly_sides_r(fillet_r)/4)*4);
if (fillet_r>0) {
@@ -41,7 +41,7 @@ module fillet_2d_i(fillet_r, fillet_angle=90, fillet_fn=90) {
}
// 3d rotated outside fillet.
module fillet_polar_o(inner_r, fillet_r, fillet_angle=90, fillet_fn=90, rotate_fn=0) {
module fillet_polar_o(inner_r, fillet_r, fillet_angle=90, fillet_fn=0, rotate_fn=0) {
if (fillet_r>0) {
rotate_extrude(convexity=8, $fn=rotate_fn) {
translate([inner_r, 0, 0]) {
@@ -52,7 +52,7 @@ module fillet_polar_o(inner_r, fillet_r, fillet_angle=90, fillet_fn=90, rotate_f
}
// 3d rotated inside fillet.
module fillet_polar_i(inner_r, fillet_r, fillet_angle=90, fillet_fn=90, rotate_fn=0) {
module fillet_polar_i(inner_r, fillet_r, fillet_angle=90, fillet_fn=0, rotate_fn=0) {
if (fillet_r>0) {
rotate_extrude(convexity=8, $fn=rotate_fn) {
translate([inner_r, 0, 0]) {
@@ -62,7 +62,7 @@ module fillet_polar_i(inner_r, fillet_r, fillet_angle=90, fillet_fn=90, rotate_f
}
// 3d rotated inside fillet negative.
module fillet_polar_i_n(outer_r, fillet_r, fillet_angle=90, fillet_fn=90, rotate_fn=0) {
module fillet_polar_i_n(outer_r, fillet_r, fillet_angle=90, fillet_fn=0, rotate_fn=0) {
if (fillet_r>0) {
rotate_extrude(convexity=8, $fn=rotate_fn) {
translate([outer_r, 0, 0]) {
@@ -72,7 +72,7 @@ module fillet_polar_i_n(outer_r, fillet_r, fillet_angle=90, fillet_fn=90, rotate
}
// 3d linear outside fillet.
module fillet_linear_o(l, fillet_r, fillet_angle=90, fillet_fn=90, add=0.02) {
module fillet_linear_o(l, fillet_r, fillet_angle=90, fillet_fn=0, add=0.02) {
if (fillet_r>0) {
translate([0,0,-add/2])
linear_extrude(height=l+add, center=false) {
@@ -82,7 +82,7 @@ translate([0,0,-add/2])
}
// 3d linear inside fillet.
module fillet_linear_i(l, fillet_r, fillet_angle=90, fillet_fn=90, add=0.02) {
module fillet_linear_i(l, fillet_r, fillet_angle=90, fillet_fn=0, add=0.02) {
if (fillet_r>0) {
translate([0,0,-add/2])
linear_extrude(height=l+add, center=false) {
@@ -173,7 +173,7 @@ module cube_fillet_inside(size, radius=-1, vertical=[0,0,0,0], top=[0,0,0,0], bo
}
}
module cylinder_fillet_inside(h=10, r=10, top=3, bottom=3, $fn=0, fillet_fn=90, center=false) {
module cylinder_fillet_inside(h=10, r=10, top=3, bottom=3, $fn=0, fillet_fn=0, center=false) {
c_fn=($fn>0) ? $fn : poly_sides_r(r);
rotfix=(($fn>0) ? 0 : 180/c_fn);
cent=(center) ? -h/2 : 0;
@@ -191,7 +191,7 @@ module cylinder_fillet_inside(h=10, r=10, top=3, bottom=3, $fn=0, fillet_fn=90,
}
}
module cylinder_fillet_outside(h=10, r=10, top=3, bottom=3, $fn=0, fillet_fn=90, center=false) {
module cylinder_fillet_outside(h=10, r=10, top=3, bottom=3, $fn=0, fillet_fn=0, center=false) {
c_fn=($fn>0) ? $fn : poly_sides_r(r);
rotfix=(($fn>0) ? 0 : 180/c_fn);
cent=(center) ? -h/2 : 0;

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]) 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]) 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]) 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]) 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]) 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]) 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]) 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]) slot(12,10,wallthick);
}
// hdmi micro indent
if(class == "video" && type == "hdmi_micro" && rotation == 0 && side == "top") {
place(loc_x-.5,-(wallthick+gap)+wallthick/2,loc_z+1.5,6,8,rotation,side)
rotate([90,0,0]) 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]) 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]) 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]) 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]) 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]) 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]) 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]) 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]) 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]) 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]) 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]) 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]) 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]) 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]) 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]) 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=7, 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=7, 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=7, 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=7, 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]) 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]) 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]) 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]) 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]) 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]) 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]) 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]) 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]) 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]) 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+2,6,8,rotation,side)
rotate([90,0,0]) 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]) 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]) 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]) 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]) 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]) slot(6,8,wallthick);
}
// audio jack indent
if(class == "audio" && type == "jack_3.5" && rotation == 0 && side == "top") {
place(loc_x+3.15,-(wallthick+gap)+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 == 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-4.6,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.15,loc_z+2,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);
}
}

363
mod/parametric_move.scad Normal file
View File

@@ -0,0 +1,363 @@
/*
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_x, size_y, size_z, data_1, data_2, data_3, data_4)
type =
loc_x =
loc_y =
loc_z =
face =
rotation =
parametric[] =
size[0] = size_x
size[1] = size_y
size[2] = size_z
data[0] =
data[1] =
data[2] =
data[3] =
*/
module parametric_move_add(type, loc_x, loc_y, loc_z, face, rotation, parametric, size_x, size_y, size_z, data_1, data_2, data_3, data_4) {
// absolute no parametrics
if(parametric[1] == false && parametric[2] == false && parametric[3] == false) {
add(type,loc_x,loc_y,loc_z,face,rotation,size_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
// 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_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
if(parametric[0] == "sbc") {
add(type,loc_x+pcb_loc_x,loc_y,loc_z,
face,rotation,size_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
}
// 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_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
if(parametric[0] == "sbc") {
add(type,loc_x,loc_y+pcb_loc_y,loc_z,
face,rotation,size_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
}
// 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_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
if(parametric[0] == "case" && face == "bottom") {
add(type,loc_x,loc_y,loc_z+case_offset_bz,
face,rotation,size_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
if(parametric[0] == "case" && face != "bottom" && face != "top") {
add(type,loc_x,loc_y,loc_z,
face,rotation,size_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
if(parametric[0] == "sbc") {
add(type,loc_x,loc_y,loc_z+pcb_loc_z,
face,rotation,size_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
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_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
if(parametric[0] == "sbc-case_z" && face == "bottom") {
add(type,loc_x,loc_y,loc_z+case_offset_bz,
face,rotation,size_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
}
// 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_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
if(parametric[0] == "sbc") {
add(type,loc_x+pcb_loc_x,loc_y+pcb_loc_y,loc_z,
face,rotation,size_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
}
// 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_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
if(parametric[0] == "case" && face == "bottom") {
add(type,loc_x+case_offset_x,loc_y,loc_z+case_offset_bz,
face,rotation,size_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
if(parametric[0] == "case" && face != "bottom" && face != "top") {
add(type,loc_x+case_offset_x,loc_y,loc_z,
face,rotation,size_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
if(parametric[0] == "sbc") {
add(type,loc_x+pcb_loc_x,loc_y,loc_z+pcb_loc_z,
face,rotation,size_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
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_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
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_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
}
// 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_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
if(parametric[0] == "case" && face == "bottom") {
add(type,loc_x,loc_y+case_offset_y,loc_z+case_offset_bz,
face,rotation,size_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
if(parametric[0] == "case" && face != "bottom" && face != "top") {
add(type,loc_x,loc_y+case_offset_y,loc_z,
face,rotation,size_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
if(parametric[0] == "sbc") {
add(type,loc_x,loc_y+pcb_loc_y,loc_z+pcb_loc_z,
face,rotation,size_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
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_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
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_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
}
// 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_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
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_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
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_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
if(parametric[0] == "sbc") {
add(type,loc_x+pcb_loc_x,loc_y+pcb_loc_y,loc_z+pcb_loc_z,
face,rotation,size_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
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_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
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_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
}
}
/*
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_x, size_y, size_z, data_1, data_2, data_3, data_4)
type =
loc_x =
loc_y =
loc_z =
face =
rotation =
parametric[] =
size[0] = size_x
size[1] = size_y
size[2] = size_z
data[0] =
data[1] =
data[2] =
data[3] =
*/
module parametric_move_sub(type, loc_x, loc_y, loc_z, face, rotation, parametric, size_x, size_y, size_z, data_1, data_2, data_3, data_4) {
// absolute no parametrics
if(parametric[1] == false && parametric[2] == false && parametric[3] == false) {
sub(type,loc_x,loc_y,loc_z,face,rotation,size_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
// 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_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
if(parametric[0] == "sbc") {
sub(type,loc_x+pcb_loc_x,loc_y,loc_z,
face,rotation,size_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
}
// 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_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
if(parametric[0] == "sbc") {
sub(type,loc_x,loc_y+pcb_loc_y,loc_z,
face,rotation,size_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
}
// 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_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
if(parametric[0] == "case" && face == "bottom") {
sub(type,loc_x,loc_y,loc_z+case_offset_bz,
face,rotation,size_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
if(parametric[0] == "case" && face != "bottom" && face != "top") {
sub(type,loc_x,loc_y,loc_z,
face,rotation,size_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
if(parametric[0] == "sbc") {
sub(type,loc_x,loc_y,loc_z+pcb_loc_z,
face,rotation,size_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
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_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
if(parametric[0] == "sbc-case_z" && face == "bottom") {
sub(type,loc_x,loc_y,loc_z+case_offset_bz,
face,rotation,size_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
}
// 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_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
if(parametric[0] == "sbc") {
sub(type,loc_x+pcb_loc_x,loc_y+pcb_loc_y,loc_z,
face,rotation,size_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
}
// 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_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
if(parametric[0] == "case" && face == "bottom") {
sub(type,loc_x+case_offset_x,loc_y,loc_z+case_offset_bz,
face,rotation,size_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
if(parametric[0] == "case" && face != "bottom" && face != "top") {
sub(type,loc_x+case_offset_x,loc_y,loc_z,
face,rotation,size_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
if(parametric[0] == "sbc") {
sub(type,loc_x+pcb_loc_x,loc_y,loc_z+pcb_loc_z,
face,rotation,size_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
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_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
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_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
}
// 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_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
if(parametric[0] == "case" && face == "bottom") {
sub(type,loc_x,loc_y+case_offset_y,loc_z+case_offset_bz,
face,rotation,size_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
if(parametric[0] == "case" && face != "bottom" && face != "top") {
sub(type,loc_x,loc_y+case_offset_y,loc_z,
face,rotation,size_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
if(parametric[0] == "sbc") {
sub(type,loc_x,loc_y+pcb_loc_y,loc_z+pcb_loc_z,
face,rotation,size_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
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_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
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_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
}
// 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_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
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_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
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_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
if(parametric[0] == "sbc") {
sub(type,loc_x+pcb_loc_x,loc_y+pcb_loc_y,loc_z+pcb_loc_z,
face,rotation,size_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
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_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
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_x,size_y,size_z,data_1,data_2,data_3,data_4);
}
}
}

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]);
}

102
mod/sub.scad Normal file
View File

@@ -0,0 +1,102 @@
/*
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_x, size_y, size_z, data_1, data_2, data_3, data_4)
type =
loc_x =
loc_y =
loc_z =
face =
rotation =
size[0] = size_x
size[1] = size_y
size[2] = size_z
data[0] =
data[1] =
data[2] =
*/
module sub(type, loc_x, loc_y, loc_z, face, rotation, size_x, size_y, size_z, data_1, data_2, data_3, data_4) {
if(type == "rectangle") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) slab_r([size_x,size_y,size_z],data_4);
}
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 == "text") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) linear_extrude(height = size_z) text(data_3, size=data_1);
}
if(type == "art") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) art(data_1,data_2,data_3);
}
if(type == "button") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) button(data_3,[size_x,size_y,size_z],data_4,data_1);
}
if(type == "hd_holes") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hd_bottom_holes(data_1,data_3,"none","none",data_2);
}
if(type == "hd_vertleft_holes") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hd_bottom_holes(data_1,data_3,"vertical","left",data_2);
}
if(type == "hd_vertright_holes") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hd_bottom_holes(data_1,data_3,"vertical","right",data_2);
}
if(type == "hk_fan_top") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hk_fan_top();
}
if(type == "knockout") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) knockout(size_x,size_y,data_1,size_z,data_2,data_3);
}
if(type == "fan") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) fan_mask(size_x, size_z, data_1);
}
if(type == "vent") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) vent(size_x,size_y,size_z,data_4,data_1,data_2,data_3);
}
if(type == "vent_hex") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) vent_hex(size_x,size_y,size_z,data_1,data_2,data_3);
}
if(type == "microusb") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) microusb_open();
}
if(type == "sphere") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) sphere(d=size_x);
}
if(type == "keyhole") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) keyhole(data_4, true);
}
if(type == "h3_port_extender") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) h3_port_extender(data_3, true);
}
if(type == "hk_pwr_button") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hk_pwr_button(true);
}
if(type == "dsub") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) dsub(data_4, true);
}
}

File diff suppressed because it is too large Load Diff

27332
sbc_case_builder.json Normal file

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

BIN
stl/db9_f.stl Normal file

Binary file not shown.

BIN
stl/db9_m.stl Normal file

Binary file not shown.

BIN
stl/h3_port_extender.stl Normal file

Binary file not shown.

BIN
stl/header_2x2_90.stl Normal file

Binary file not shown.

BIN
stl/header_encl_2x5_90.stl Normal file

Binary file not shown.