137 Commits

Author SHA1 Message Date
Edward Kisiel
1f2bb6613a added h4, h4+ and h4_ultra with updated sbc model framework 2024-04-29 18:29:39 -04:00
Edward Kisiel
a3f576edb9 changed adapter hole size to 4mm 2024-04-29 10:54:00 -04:00
Edward Kisiel
ddd7c0b4bd removed unneeded h3_port_extender.stl model and updated readme.md 2024-04-28 13:43:58 -04:00
Edward Kisiel
8e73d4550f updated readme.md and sbc library 2024-04-27 17:11:13 -04:00
Edward Kisiel
821deb2445 updated sbc_model_framework 2024-04-26 10:15:55 -04:00
Edward Kisiel
e6cb0b3b8c adjusted io shield opening, moved access panel in platter view and cleaned up accessory entries. 2024-04-26 10:07:21 -04:00
Edward Kisiel
045aa2874a finished named standoff size for extended standoffs, added mini-stx-thin adapter and io shield, updated readme.md and other fixes. 2024-04-24 16:09:44 -04:00
Edward Kisiel
74084eebde implemented named fastener size m2, m2.5, m3, m4 and custom for top and bottom standoffs 2024-04-22 20:49:03 -04:00
Edward Kisiel
0807d49dbb fixed model view sections, fixed tray cases nut holder placement, changed fan mask direction and finalized standard form adapters and cases. 2024-04-22 16:09:31 -04:00
Edward Kisiel
42593fa92f fixed z axis parametric problem related to calculated bottom standoff height, more case cleanup and other fixes and changes 2024-04-20 17:27:54 -04:00
Edward Kisiel
2eef11f03f finished library documentation update, added fan and hd masks and other fixes 2024-04-18 19:47:42 -04:00
Edward Kisiel
125ec3a477 documentation work and other cleanup and fixes 2024-04-17 17:31:50 -04:00
Edward Kisiel
50f71b69e3 fixed tray side fastener placement when using extend standoffs, more standard mb case and adapter changes 2024-04-14 16:48:36 -04:00
Edward Kisiel
f56302f7a8 initial fan models 40mm, 50mm, 60mm, 80mm, 92mm, 120mm, 140mm without vanes 2024-04-13 16:36:59 -04:00
Edward Kisiel
5c7f917b9f plumbed accessory support for standard mb form adapters, added mini-stx adapter and initial work for standard mb form cases 2024-04-13 14:36:52 -04:00
Edward Kisiel
3277cc8d07 adjustments for case adapters and io plate, remove unneed stl models 2024-04-10 21:02:45 -04:00
Edward Kisiel
4f7aa53050 legacy case adapters added 2024-04-09 22:05:00 -04:00
Edward Kisiel
dc12d7f6a1 added linear top and bottom vents and removed unused exhaust vent variable 2024-04-07 16:31:30 -04:00
Edward Kisiel
8e89257759 rewrote tray side attachment routine based on SBC standoff location 2024-04-07 15:20:37 -04:00
Edward Kisiel
40e8e6bfff removed case_style and added new case_design names as replacement 2024-04-07 12:33:56 -04:00
Edward Kisiel
f5130023f0 added bottom access panel in gui and changed all related uses for accessories 2024-04-06 21:16:28 -04:00
Edward Kisiel
6a855e1ef6 finished initial accessory case conversion to new format 2024-04-06 15:59:45 -04:00
Edward Kisiel
de063b31f8 converted h3_port_extender and components from stl and implemented automask, more case conversions 2024-03-31 14:53:06 -04:00
Edward Kisiel
88691a6b61 added db9 to dsub.scad in library 2024-03-28 14:31:27 -04:00
Edward Kisiel
8a0e9f17a0 more custom case conversion to use auto-mask 2024-03-21 17:16:07 -04:00
Edward Kisiel
f71bc2e2d0 fixed regression in standoff supports and more model cahnges to support auto mask generation 2024-03-21 12:30:35 -04:00
Edward Kisiel
0fb0f4daef various plumbing to implement auto-masks for library, config changes and other modifications 2024-03-16 17:39:23 -04:00
Edward Kisiel
8bf424b99b changed oem_hk to shared component lib, added new standoff end type none 2024-03-15 15:26:23 -04:00
Edward Kisiel
2dc8e16f1e library conversion and masks for boom_speaker, hk_boom_speaker, hk_boom, hk_pwr_button, hk_m1s_ups 2024-03-05 17:52:00 -05:00
Edward Kisiel
e7b85fa217 library masks for hk_vu7c, hk_vu8m, hk_vu8s 2024-03-04 16:25:16 -05:00
Edward Kisiel
9e8fe8006f more library cleanup and mask creation for buttons and hk35_lcd 2024-03-04 11:11:24 -05:00
Edward Kisiel
c1aa6bb353 completed library masks for access_port, standoff, hc4_olded, hc4_oled_holder, hk_netcard 2024-02-28 19:38:49 -05:00
Edward Kisiel
e46ac774e4 created ui enable for individual top, bottom and extended standoffs with associated plumbing 2024-02-26 13:22:57 -05:00
Edward Kisiel
d5d23fba18 started cleaning json and cfg file, updated ui and added new features 2024-02-25 21:39:41 -05:00
Edward Kisiel
2c61849665 top and bottom extended standoff ui added and plumbed for control 2024-02-25 16:14:30 -05:00
Edward Kisiel
0b99ea5805 added sbc information in ui and plumbed 2024-02-24 21:31:38 -05:00
Edward Kisiel
2b430275cb standoff sidewall support moved to standoff module, top and bottom standoffui changes 2024-02-24 20:48:41 -05:00
Edward Kisiel
b6eb06f97c more work on mask integration and cleanup 2024-02-24 16:13:15 -05:00
Edward Kisiel
7b03aa1922 plumed in mask for add and sub parametric moves 2024-02-24 12:30:56 -05:00
Edward Kisiel
fd688d53c3 added mask variable in sbc_case_builder_accessories.cfg for all entries 2024-02-23 21:27:22 -05:00
Edward Kisiel
543162c61c sbc_case_builder_accessories.cfg corrections 2024-02-23 17:29:59 -05:00
Edward Kisiel
506d29f34e convert accessory format to arrays for size and data 2024-02-23 16:08:35 -05:00
Edward Kisiel
8c0e333450 support for stl models with stl_model, start of library work, woek on adafruit model. 2024-02-22 15:14:08 -05:00
Edward Kisiel
7b9a18279d added sidewall support selection per standoff in gui and more work on top and bottom control 2024-02-19 09:57:55 -05:00
Edward Kisiel
a288a924d5 standoff variable seperation for gui, initial work for top and bottom standoffs 2024-02-19 09:57:55 -05:00
Edward Kisiel
6262684252 updated readme and sbcmf 2024-02-18 15:09:04 -05:00
Edward Kisiel
7559d48140 changed ui for improved folded case use 2024-02-18 12:32:32 -05:00
Edward Kisiel
5c43d0961d refinement and fixes for folded cases with ui improvements 2024-02-17 17:26:09 -05:00
Edward Kisiel
0d5f8ef357 more work on folded cases, added paper_full-top case 2024-02-16 22:54:10 -05:00
Edward Kisiel
1b549ac761 initial work for folded cases added case paper_split-top 2024-02-14 21:59:44 -05:00
Edward Kisiel
5514029edc updated accessory group names and changed order of accessories tab in ui 2024-02-10 13:42:32 -05:00
Edward Kisiel
90a15ea4c9 added dxf files for custom openings and hk netcard 2024-02-08 17:20:47 -05:00
Edward Kisiel
66aeb943c6 fixed front section cut, added 45 heatsink mask, fixed vu5 and vu7 holder, adjusted accessory entries for all stored cases due to bottom calc change, other fixes and adjustments 2024-02-08 17:17:08 -05:00
Edward Kisiel
2697bc7648 included pcb_z in bottom height calculation. 2024-02-07 11:01:57 -05:00
Edward Kisiel
5fde770566 updated sbc model framework 2024-02-05 21:42:36 -05:00
Edward Kisiel
b336115556 updated library driectory name 2024-02-05 15:23:41 -05:00
Edward Kisiel
3eaaf6f03c updated sbc model framework and removed dxf directory 2024-02-05 15:21:12 -05:00
Edward Kisiel
56b392b082 added custom to heatsink mask ui pickbox 2024-02-05 14:49:36 -05:00
Edward Kisiel
4a58ab823e changed ui to include additional cooling options 2024-01-31 22:52:02 -05:00
Edward Kisiel
ebcafd0f05 fixed indent for cases with more code standardization and cleanup 2024-01-31 22:36:53 -05:00
Edward Kisiel
e5b9e8263c more cleanup and documentation 2024-01-31 21:36:04 -05:00
Edward Kisiel
a33450ac21 code cleanup, rearrangement and documentation 2024-01-30 22:08:10 -05:00
Edward Kisiel
b866bd73db removed no longer needed entries in accessory cfg. 2024-01-30 17:51:56 -05:00
Edward Kisiel
e968bbe384 positional standoff sidewall support added and ongoing code cleanup and reorg. 2024-01-30 16:04:37 -05:00
Edward Kisiel
d084cab29f plumbed new heatsink, gpio, uart mask selection thru sbcmf cmdline 2024-01-29 21:07:08 -05:00
Edward Kisiel
adf72494a1 initial work for integrating sbc model framework v2 2024-01-29 17:40:12 -05:00
Edward Kisiel
d5674f9f24 updated sbc_model_framework for typo in rpi5 and rpi5_noheatsink 2023-12-14 14:11:23 -05:00
Edward Kisiel
390df175b3 added 5mm and 8mm hex vent, adjusted m1s cases, updated sbc model framework, fixed snap top protrusion placement and other fixes. 2023-12-11 16:21:34 -05:00
Edward Kisiel
0c96b1247a adjusted m1s shell, added m1s_shell_ups case, adjusted components and cooling options. 2023-12-07 20:46:38 -05:00
Edward Kisiel
7cec418b69 added odroid-m1s, added hex vent cooling option and made other changes. 2023-11-15 21:09:42 -05:00
Edward Kisiel
59b894d738 updated sbc model framework and header info. 2023-11-10 12:18:07 -05:00
Edward Kisiel
2e7cd76f20 adjusted indent and cooling options for all rpi5 cases 2023-11-04 17:02:38 -04:00
Edward Kisiel
7eab4fe790 added rpi5 cases 2023-11-04 15:52:38 -04:00
Edward Kisiel
501da93cad fixed snap case top, removed support pieces from non-shell cases for rock5b, fixed tray bottom mounting hole location for top and interference with standoff. 2023-08-26 14:39:08 -04:00
Edward Kisiel
c83301debf opir1 added, updated sbc_model_framework and sbc_case_builder and readme.md 2023-05-30 20:58:56 -04:00
Edward Kisiel
c2d7cc3352 added rock5bq cases panel, stacked, tray, tray-sides, snap and fitted, updated sbc_model_framework 2023-05-14 17:21:51 -04:00
Edward Kisiel
20ab01b924 adjustments to rock5b-v1.42 and added rock5bq-v1.42 with updated sbc model framework, adjusted all rock5b case openings in sbc_case_builder_accessories.cfg, rock5b is now green-verified 2023-05-14 15:09:00 -04:00
Edward Kisiel
0770c17468 updated sbc model framework for visionfive2q, added visionfive2q cases, adjusted tray design side screw locations due to interference 2023-03-09 17:56:35 -05:00
Edward Kisiel
3a1ba0f811 h3_ultimate2 support added at corners 2023-03-09 12:01:28 -05:00
Edward Kisiel
572293170d reverted bottom height calc and added support ribs for h3_ultimate2 case 2023-03-06 13:26:29 -05:00
Edward Kisiel
b59f99c0b6 updated sbc model framework for h2 and h3 pcb thickness increase, changed bottom_height calc to include pcb thickness. 2023-03-05 14:57:42 -05:00
Edward Kisiel
a6795b3383 updated sbc model framework for usbc_vertical changes 2023-03-04 18:11:28 -05:00
Edward Kisiel
00648a52e9 updated sbc model framework, renamed radax rockpi to rock, rock 5b io adjustments, visionfive2 io overhang adjusted, readme.md and file comments updated. 2023-03-04 17:16:01 -05:00
Edward Kisiel
f24d3e918b implemented header_26 as a gpio, added opi5 remaining base design. 2023-02-22 19:23:42 -05:00
Edward Kisiel
b4189a6cee added opi5 sbc and updated sbc_model_framework and documentation. 2023-02-22 10:21:20 -05:00
Edward Kisiel
6aa68c568e updated sbc_model_framework 2023-02-21 12:58:08 -05:00
Edward Kisiel
efed91db76 Merge pull request #29 from amazingfate/rock5b-v1.3
add mask fix for rock5b v1.3
2023-02-21 17:55:14 +00:00
amazingfate
30d709a00e add mask fix for rock5b v1.3 2023-02-21 14:53:25 +08:00
Edward Kisiel
bb5fb69cab added visionfive2 cases, split rockpi5b into rockpi5b-v1.3 and rockpi5b-v1.42 with addtions and modifications to support pre-release and released versions. 2023-02-20 13:09:38 -05:00
Edward Kisiel
f7d06bb311 added cableholder_spacer 2023-02-11 19:32:42 -05:00
Edward Kisiel
2aad1fef87 made h3_port_extender_holder parametric and updated associated cases. 2023-02-09 22:56:59 -05:00
Edward Kisiel
adf4101e3c Merge pull request #27 from Icenowy/star64
Refinements to Star64
2023-01-31 22:58:38 +00:00
Icenowy Zheng
fa1d426130 add star64-shell accessory (fan+pcie holes) and preset
Signed-off-by: Icenowy Zheng <uwu@icenowy.me>
2023-01-31 21:12:04 +08:00
Icenowy Zheng
3af7520d67 add stacked dual rj45
Used on star64.

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

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

2
.gitmodules vendored
View File

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

2445
README.md

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 MiB

After

Width:  |  Height:  |  Size: 3.8 MiB

24632
dxf/astroid_8mm.dxf Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,9 +1,9 @@
// Gets a list of SBCs from the SBC Model Framework and Accessory sets
// for use with SBC Case Builder.
// After running this script, copy the output from the first Echo command into the
// list of SBC boards in `sbc_case_builder.scad:80`
// list of SBC boards in `sbc_case_builder.scad:32`
// Also copy the output from the second Echo command into the list of case acceessory
// sets in `sbc_case_builder.scad:160`
// sets in `sbc_case_builder.scad:196`
include <./SBC_Model_Framework/sbc_models.cfg>;
include <./sbc_case_builder_accessories.cfg>;
@@ -14,4 +14,4 @@ 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);
echo(accessory_sets);

170
lib/access_panel.scad Normal file
View File

@@ -0,0 +1,170 @@
/*
This file is part of SBC Case Builder https://github.com/hominoids/SBC_Case_Builder
Copyright 2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
access_cover(size, orientation)
access_panel(size, orientation, mask)
*/
/*
NAME: access_cover
DESCRIPTION: creates covers for access port openings
TODO: none
USAGE: access_panel(size[], orientation)
size[0] = size_x
size[1] = size_y
size[2] = floor thickness
orientation = "landscape", "portrait"
*/
module access_cover(size, orientation) {
size_x = size[0];
size_y = size[1];
floorthick = size[2];
adj = .01;
$fn = 90;
if(orientation == "portrait") {
difference() {
union() {
translate([1, 6.25, 0]) cube([size_x-2.15, size_y-17.5, floorthick]);
translate([(size_x/2)-4.75, size_y-12.25, 0]) slab([10, 5, floorthick], 5);
translate([1, 6.25, floorthick-adj]) cube([size_x-2.15, 6, floorthick]);
translate([4.25, 3, floorthick]) cube([7.25, 4, 2]);
translate([size_x-12.75, 3, floorthick]) cube([7.25, 4, 2]);
if(size_x > 100) {
translate([(size_x/2)+.25, 3, floorthick]) cube([7.25, 4, 2]);
}
}
translate([(size_x/2)+.25, size_y-6.5, -floorthick-adj])
cylinder(d=3.2, h=(floorthick*2)+(adj*2));
translate([(size_x/2)+.25, size_y-6.5, -adj])
cylinder(d1=6, d2=3.2, h=floorthick);
}
}
if(orientation == "landscape") {
difference() {
union() {
translate([6.25, 0, 0]) cube([size_x-17.75, size_y-2, floorthick]);
translate([size_x-12.25, (size_y/2)-5.75, 0]) slab([5, 10, floorthick], 5);
translate([6.25, 0, floorthick-adj]) cube([6,size_y-2.15, floorthick]);
translate([3.5+adj, 3.25, floorthick]) cube([4, 7.25, 2]);
translate([3.5+adj, size_y-12.75, floorthick]) cube([4, 7.25, 2]);
if(size_y > 100) {
translate([3.5+adj, (size_y/2)-(7.75/2)-1, floorthick]) cube([4, 7.25, 2]);
}
}
translate([size_x-6.5, (size_y/2)-.75, -floorthick-adj])
cylinder(d=3.2, h=(floorthick*2)+(adj*2));
translate([size_x-6.5, (size_y/2)-.75, -adj])
cylinder(d1=6, d2=3.2, h=floorthick);
}
}
}
/*
NAME: access_panel
DESCRIPTION: creates opening and structure for access openings
TODO: none
USAGE: access_panel(size[], orientation, mask)
size[0] = size_x
size[1] = size_y
size[2] = floor thickness
orientation = "landscape", "portrait"
mask[0] = true enables component mask
mask[1] = mask length
mask[2] = mask setback
mask[3] = mstyle "default"
*/
module access_panel(size, orientation, mask) {
size_x = size[0];
size_y = size[1];
floorthick = size[2];
enablemask = mask[0];
mlength = mask[1];
msetback = mask[2];
mstyle = mask[3];
adj = .01;
$fn = 90;
if(enablemask == true && mstyle == "default") {
if(orientation == "portrait") {
translate([0,0,floorthick+adj-mlength+msetback]) cube([size_x, size_y, mlength]);
}
if(orientation == "landscape") {
translate([0, -1, floorthick+adj-mlength+msetback]) cube([size_x-1, size_y, mlength]);
}
}
if(enablemask == false) {
if(orientation == "portrait") {
difference() {
union() {
cube([size_x, size_y, floorthick]);
// access panel support
translate([(size_x/2)+.25, size_y-6.5, 0]) cylinder(d=9, h=floorthick+(adj*2)+5);
translate([(size_x/2)-10, size_y-11, floorthick-adj]) cube([20, 9.5, floorthick]);
translate([1, 0, floorthick-adj]) cube([size_x-2, 5, 4.5]);
}
// access opening
translate([.5, 6, -adj]) cube([size_x-1.15, size_y-17, floorthick+(adj*2)]);
translate([(size_x/2)-5, size_y-12, -adj]) slab([10.5, 5.5, floorthick], 5.5);
translate([(size_x/2)+.25, size_y-6.5, floorthick+2])
cylinder(r=3.2, h=floorthick+(adj*2)+5, $fn=6);
translate([(size_x/2)+.25, size_y-6.5, -adj])
cylinder(d=3.2, h=floorthick+(adj*2)+5);
translate([4, 2+adj, floorthick]) cube([7.75, 3, 2.75]);
translate([size_x-13, 2+adj, floorthick]) cube([7.75, 3, 2.75]);
if(size_x > 100) {
translate([(size_x/2), 2+adj, floorthick]) cube([7.75, 3, 2.75]);
}
}
}
if(orientation == "landscape") {
difference() {
union() {
translate([0, -1, 0]) cube([size_x, size_y, floorthick]);
// access panel support
translate([size_x-6.5, (size_y/2)-.5, 0]) cylinder(d=9, h=floorthick+(adj*2)+5);
translate([size_x-11, (size_y/2)-10.5, floorthick-adj]) cube([9.5, 20, floorthick]);
translate([0, 0, floorthick-adj]) cube([5, size_y-2, 4.5]);
}
// access opening
translate([6, -.5, -adj]) cube([size_x-17, size_y-1.15, floorthick+(adj*3)]);
translate([size_x-12, (size_y/2)-6, -adj]) slab([5.5, 10.5, floorthick], 5.5);
translate([size_x-6.5, (size_y/2)-.5, floorthick+2]) rotate([0, 0, 30])
cylinder(r=3.2, h=floorthick+(adj*2)+5, $fn=6);
translate([size_x-6.5, (size_y/2)-.5, -adj])
cylinder(d=3.2, h=floorthick+(adj*2)+5);
translate([2+adj, 3, floorthick]) cube([3, 8.25, 2.75]);
translate([2+adj, size_y-13, floorthick]) cube([3, 8.25, 2.75]);
if(size_y > 100) {
translate([2+adj, (size_y/2)-(7.75/2)-1.25, floorthick]) cube([3, 7.75, 2.5]);
}
}
}
}
}

59
lib/art.scad Normal file
View File

@@ -0,0 +1,59 @@
/*
This file is part of SBC Case Builder https://github.com/hominoids/SBC_Case_Builder
Copyright 2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
art(scale_d1, size_z, filename)
stl_model(scale_d1, filename)
*/
/*
NAME: art
DESCRIPTION: create 2d artwork using dxf or svf
TODO: none
USAGE: art(scale_d1, size_z, filename)
scale_d1 = amount to scale file
size_z = floor thickness
filename = file name
*/
module art(scale_d1, size_z, filename) {
linear_extrude(height = size_z) import(file = filename, scale=scale_d1);
}
/*
NAME: stl_model
DESCRIPTION: import 3d artwork using stl
TODO: none
USAGE: stl_model(scale_d1, filename)
scale_d1 = amount to scale file
filename = file name
*/
module stl_model(scale_d1, filename) {
import(file = filename, scale=scale_d1);
}

132
lib/batteries.scad Normal file
View File

@@ -0,0 +1,132 @@
/*
This file is part of SBC Case Builder https://github.com/hominoids/SBC_Case_Builder
Copyright 2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
battery(type)
battery_clip(bat_dia = 18.4)
batt_holder(tolerance)
*/
/*
NAME: battery
DESCRIPTION: creates 18650 and 21700 batteries
TODO: none
USAGE: battery(type)
type = "18650", "18650_convex", "21700"
*/
module battery(type) {
adj = .01;
if(type == "18650") {
difference() {
color("#73bc73") cylinder(d=18.4, h=65);
translate([0,0,65-4]) difference() {
cylinder(d=18.5, h=2);
cylinder(d=17.5, h=3);
}
}
}
if(type == "18650_convex") {
difference() {
color("#73bc73") cylinder(d=18.4, h=68);
translate([0,0,65-4]) difference() {
color("#73bc73") cylinder(d=18.5, h=2);
color("#73bc73") cylinder(d=17.5, h=3);
}
translate([0,0,65-adj]) difference() {
color("silver") cylinder(d=18.5, h=3+2*adj);
color("silver") cylinder(d=14.4, h=3+2*adj);
}
color("silver") translate([0,0,68-adj]) cylinder(d=14.4, h=.1);
}
}
if(type == "21700") {
difference() {
color("#73bc73") cylinder(d=21, h=70);
translate([0,0,70-4]) difference() {
cylinder(d=21.1, h=2);
cylinder(d=20.1, h=3);
}
}
}
}
/*
NAME: battery_clip
DESCRIPTION: creates 18650 and 21700 batteries
TODO: none
USAGE: battery_clip(bat_dia = 18.4)
*/
module battery_clip(bat_dia = 18.4) {
mat = .38;
width = 9.5;
tab = 8.9;
bat_holder = bat_dia+2*mat;
adj = .1;
translate([-5.5,0,10.5]) {
difference() {
translate([0,width,0]) rotate([90,0,0]) cylinder(d=bat_holder, h=9.5);
translate([0,width+adj,0]) rotate([90,0,0]) cylinder(d=bat_dia, h=10.5);
translate([mat/2-11.1/2,-adj,mat-1.3-bat_dia/2]) cube([11.1-mat,width+2*adj,3]);
translate([0,width+adj,0]) rotate([90,-45,0]) cube([bat_dia,bat_dia,bat_holder]);
}
difference() {
translate([-11.1/2,0,-1.3-bat_dia/2]) cube([11.1,width,3]);
translate([mat-11.1/2,-adj,mat/2-1.3-bat_dia/2]) cube([11.1-2*mat,width+2*adj,3]);
}
difference() {
translate([-(tab/2),-3.5,-1-bat_dia/2]) rotate([-5,0,0]) cube([tab,3.5,10]);
translate([-(tab/2)-adj,-3.5+mat,mat-1-bat_dia/2]) rotate([-5,0,0]) cube([tab+2*adj,3.5+mat,10]);
}
translate([0,-2.225,0]) rotate([85,0,0]) cylinder(d=tab, h=mat);
difference() {
translate([0,-2.75,0]) sphere(d=3);
translate([-5,-2.75,-5]) rotate([85,0,0]) cube([tab,10,10]);
}
}
}
/*
NAME: battery_holder
DESCRIPTION: creates cr2032 friction fit coinstyle holder
TODO: none
USAGE: batt_holder(tolerance)
*/
module batt_holder(tolerance) {
$fn = 90;
difference () {
cylinder(d=25.5,h=6);
translate ([0,0,-1]) cylinder(d=20.4+tolerance,h=8);
cube([14,26,13], true);
}
cylinder(r=12.75, h=2);
}

206
lib/buttons.scad Normal file
View File

@@ -0,0 +1,206 @@
/*
This file is part of SBC Case Builder https://github.com/hominoids/SBC_Case_Builder
Copyright 2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
buttons(style, diameter, height, mask)
button_assembly(style, diameter, height)
button_clip(style)
button_plunger(style, diameter, height)
button_top(style, diameter, height)
*/
/*
NAME: buttons
DESCRIPTION: creates different button bodys and styles
TODO: none
USAGE: buttons(style, size, radius, post, mask)
style = "recess", "cutout"
size[0] = diameter of button body
size[2] = height above button
radius = radius for cutout style
post = button post size for cutout style
mask[0] = true enables component mask
mask[1] = mask length
mask[2] = mask setback
mask[3] = mstyle "default"
*/
module buttons(style, size, radius, post, mask) {
size_x = size[0];
size_y = size[1];
size_z = size[2];
diameter = size[0];
height = size[2];
gap = 1.5;
enablemask = mask[0];
mlength = mask[1];
msetback = mask[2];
mstyle = mask[3];
adj = .01;
$fn = 90;
if(enablemask == true && mstyle == "default") {
if(style == "recess") {
translate([0, 0, -adj-msetback]) cylinder(d = diameter-2*adj, h = mlength);
}
if(style == "cutout") {
translate([-size[0]+2.5, -2.5-size[1]/2, -adj-msetback]) cube([size[0]+1, size[1]+5, mlength]);
}
}
if(enablemask == false) {
if(style == "recess") {
difference() {
union() {
sphere(d=diameter);
translate([0,0,-height+3]) cylinder(d=6, h=height-6);
}
translate([-(diameter/2)-1,-(diameter/2)-1,0]) cube([diameter+2,diameter+2,(diameter/2)+2]);
difference() {
union() {
sphere(d=diameter-2);
}
}
translate([-1.75, -1.25, -height-1]) cube([3.5, 2.5, height+2]);
translate([0,0,-(diameter/2)]) cylinder(d=5, h=2);
}
}
if(style == "cutout") {
difference() {
translate([-size[0]+2, -3-size[1]/2, 0]) slab_r([size[0]+2,size[1]+6,size[2]-2*adj], [.1,.1,.1,.1]);
difference() {
translate([-size[0]+3, -size[1]/2, -adj])
slab_r([size[0],size[1],size[2]], [radius[0],radius[1],radius[2],radius[3]]);
translate([-size[0]+3+(gap/2), -size[1]/2+(gap/2), -1]) slab_r([size[0]-gap,size[1]-gap,1+size[2]+2*adj],
[radius[0],radius[1],radius[2]-gap/2,radius[3]-gap/2]);
translate([3-size[0]-gap, -1, -1]) cube([gap*2, 2, 1+height+2*adj]);
}
translate([0, 0, 2]) sphere(d=3);
}
translate([0, 0, adj-post]) cylinder(d=3, h=post);
}
}
}
/*
NAME: button_assembly
DESCRIPTION: creates button assembly of plunger,top,clip
TODO: none
USAGE: button_assembly(style, diameter, height)
style = "recess", "cutout"
diameter = diameter of button body
height = height above button
*/
module button_assembly(style, diameter, height) {
adj = .01;
$fn = 90;
if(style == "recess") {
button_plunger(style, diameter, height);
button_top(style, diameter, height);
translate([0,0,-height]) button_clip(style);
}
}
/*
NAME: button_clip
DESCRIPTION: creates button c-clip
TODO: none
USAGE: button_clip(style)
style = "recess", "cutout"
*/
module button_clip(style) {
adj = .01;
$fn = 90;
if(style == "recess") {
difference() {
cylinder(d=8.5, h=.8);
translate([-1.5,-1.75,-adj]) cube([2.75,3.5,1]);
translate([-.75,-.75,-adj]) cube([5,1.25,1.25]);
}
}
}
/*
NAME: button_plunger
DESCRIPTION: creates button plunger
TODO: none
USAGE: button_plunger(style, diameter, height)
style = "recess", "cutout"
diameter = diameter of button body
height = height above button
*/
module button_plunger(style, diameter, height) {
adj = .01;
$fn = 90;
if(style == "recess") {
difference() {
translate([-1.5,-1,-(height)-2]) cube([3,2,height+1]);
translate([-1.5-adj,-1.5,-height]) cube([.5,3,1]);
translate([1+adj,-1.5,-height]) cube([.5,3,1]);
translate([-1.5-adj,-1.5,-4]) cube([.5,3,4]);
translate([1+adj,-1.5,-4]) cube([.5,3,4]);
}
}
}
/*
NAME: button_top
DESCRIPTION: creates button top
TODO: none
USAGE: button_top(style, diameter, height)
style = "recess", "cutout"
diameter = diameter of button body
height = height above button
*/
module button_top(style, diameter, height) {
adj = .01;
$fn = 90;
if(style == "recess") {
difference() {
translate([0,0,-3]) cylinder(d=5, h=2.75);
translate([-1.25,-1.25,-3-adj]) cube([2.5,2.5,2]);
}
}
}

43
lib/cable_holder.scad Normal file
View File

@@ -0,0 +1,43 @@
/*
This file is part of SBC Case Builder https://github.com/hominoids/SBC_Case_Builder
Copyright 2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
cableholder_spacer()
*/
/*
NAME: cableholder_spacer
DESCRIPTION: creates spacer and cable holder for drive mounts
TODO: none
USAGE: cableholder_spacer()
*/
module cableholder_spacer() {
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]);
}
}

138
lib/custom.scad Normal file
View File

@@ -0,0 +1,138 @@
/*
This file is part of SBC Case Builder https://github.com/hominoids/SBC_Case_Builder
Copyright 2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
hk_h3_port_extender(style, mask)
hk_h3_port_extender_holder(part, offset)
*/
/*
NAME: hk_h3_port_extender
DESCRIPTION: @mctom's odroid-h3 gpio port extender
TODO: none
USAGE: hk_h3_port_extender(style, mask)
style = "header", "remote"
mask[0] = true enables component mask
mask[1] = mask length
mask[2] = mask setback
mask[3] = mstyle "default"
*/
module hk_h3_port_extender(style, mask) {
enablemask = mask[0];
mlength = mask[1];
msetback = mask[2];
mstyle = mask[3];
adj=.01;
$fn = 90;
if(style == "header") {
if(enablemask == true && mstyle == "default") {
translate([0, 14.5, 12-msetback]) cube([7.75, 15.75, mlength]);
translate([9.5, 14.5, 12-msetback]) cube([7.75, 15.75, mlength]);
translate([19, 14.5, 12-msetback]) cube([7.75, 15.75, mlength]);
translate([16, 32.2, 12-msetback]) cylinder(d=3, h=12);
}
if(enablemask == false) {
// gpio 24 pin front position
header("angled", -1.75, .1, 0, "top", 0, [12,2,8], ["thruhole","black","female",2.54,"silver"],
1.6, false, [true,10,2,"default"]);
difference() {
color("#008066") slab([33,35.25,1.6], .25);
color("#008066") translate([15.95,4.6,-1]) cylinder(d=3, h=6);
color("#008066") translate([15.95,32.15,-1]) cylinder(d=3, h=6);
}
header("angled", 27.65, 29.6, 0, "bottom", 90, [2,2,6], ["thruhole","black","male",2.54,"silver"],
1.6, false, [true,10,2,"default"]);
header("angled", 30.5, 16.5, 0, "bottom", 90, [5,2,6], ["thruhole","black","male",2.54,"silver"],
1.6, false, [true,10,2,"default"]);
usb2("single_up_a", .925, 15.375, 0, "top", 180, [0,10.5,0], [0], 1.6, false, [true,10,2,"default"]);
usb2("single_up_a", 10.395, 15.375, 0, "top", 180, [0,10.5,0], [0], 1.6, false, [true,10,2,"default"]);
usb2("single_up_a", 19.925, 15.375, 0, "top", 180, [0,10.5,0], [0], 1.6, false, [true,10,2,"default"]);
}
}
if(style == "remote") {
if(enablemask == true && mstyle == "default") {
translate([0, 14.5, 12-msetback]) cube([7.75, 15.75, mlength]);
translate([9.5, 14.5, 12-msetback]) cube([7.75, 15.75, mlength]);
translate([19, 14.5, 12-msetback]) cube([7.75, 15.75, mlength]);
translate([16, 32.2, 12-msetback]) cylinder(d=3, h=12);
translate([16, 4.6, 12-msetback]) cylinder(d=3, h=mlength);
}
if(enablemask == false) {
difference() {
color("#008066") slab([33,35.25,1.6], .25);
color("#008066") translate([15.95,4.6,-1]) cylinder(d=3, h=6);
color("#008066") translate([15.95,32.15,-1]) cylinder(d=3, h=6);
}
// gpio 24 pin front position
header("open", .75, 9, 0, "bottom", 0, [12,2,6], ["thruhole","black","male",2.54,"silver"],
1.6, false, [true,10,2,"default"]);
header("angled", 27.65, 29.6, 0, "bottom", 90, [2,2,6], ["thruhole","black","male",2.54,"silver"],
1.6, false, [true,10,2,"default"]);
header("angled", 30.5, 16.5, 0, "bottom", 90, [5,2,6], ["thruhole","black","male",2.54,"silver"],
1.6, false, [true,10,2,"default"]);
usb2("single_up_a", .925, 15.375, 0, "top", 180, [0,10.5,0], [0], 1.6, false, [true,10,2,"default"]);
usb2("single_up_a", 10.395, 15.375, 0, "top", 180, [0,10.5,0], [0], 1.6, false, [true,10,2,"default"]);
usb2("single_up_a", 19.925, 15.375, 0, "top", 180, [0,10.5,0], [0], 1.6, false, [true,10,2,"default"]);
}
}
}
/*
NAME: hk_h3_port_extender_holder
DESCRIPTION: holder for the @mctom's remote h3 port extender
TODO: none
USAGE: hk_h3_port_extender_holder(part, offset)
part = "top","bottom","both"
offset = distance from mount face
*/
module hk_h3_port_extender_holder(part,offset=2) {
size = [16-offset,40,5.5];
adj = .01;
if(part == "bottom" || part == "both") {
difference() {
translate([-10+offset,-3.5,2]) cube(size);
translate([-.25,-.25,-adj]) cube([2.5, 33.25, 12]);
translate([2, 2, -adj]) cube([10, 28, 12]);
translate([-12,(33.25/2)+.25,4.5]) rotate([0,90,0]) cylinder(d=2.7, h=20, $fn=60);
// translate([-7,-1.,-adj]) cylinder(d=4.25, h=20);
}
}
if(part == "top" || part == "both") {
difference() {
translate([-10+offset,-3.5,29.5]) cube(size);
translate([-.25,-.25,28]) cube([2.5, 33.25, 12]);
translate([1.5, 2, 27.5-adj]) cube([10, 28.5, 12]);
translate([-12, -4, 28]) cube([20, 13, 10]);
translate([1.35, 20, 25.5]) cube([10, 13, 5]);
translate([-12,(33.25/2)+.25,32]) rotate([0,90,0]) cylinder(d=2.7, h=20, $fn=60);
}
}
}

107
lib/dsub.scad Normal file
View File

@@ -0,0 +1,107 @@
/*
This file is part of SBC Case Builder https://github.com/hominoids/SBC_Case_Builder
Copyright 2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
dsub(style, gender, mask)
*/
/*
NAME: dsub
DESCRIPTION: creates dsub connectors
TODO: 9db male, 25db male and female
USAGE: dsub(style, gender, mask)
style = "db9"
gender = "female","male"
mask[0] = true enables component mask
mask[1] = mask length
mask[2] = mask setback
mask[3] = mstyle "default"
*/
module dsub(style, gender, mask) {
enablemask = mask[0];
mlength = mask[1];
msetback = mask[2];
mstyle = mask[3];
adj = .01;
$fn = 90;
if(enablemask == true && mstyle == "default") {
translate([0,0,-msetback]) union() {
hull() {
translate([-7,3,-5]) cylinder(d=3, h=11+mlength);
translate([7,3,-5]) cylinder(d=3, h=11+mlength);
translate([-6.25,-3,-5]) cylinder(d=3, h=11+mlength);
translate([6.25,-3,-5]) cylinder(d=3, h=11+mlength);
}
// mount holes
translate([-12.5,0,-5]) cylinder(d=3.5, h=11+mlength);
translate([12.5,0,-5]) cylinder(d=3.5, h=11+mlength);
}
}
if(enablemask == false) {
if(style == "db9" && gender =="female") {
difference() {
union() {
color("silver") hull() {
translate([-6.5,2.5,-5]) cylinder(d=3, h=11);
translate([6.5,2.5,-5]) cylinder(d=3, h=11);
translate([-5.75,-2.5,-5]) cylinder(d=3, h=11);
translate([5.75,-2.5,-5]) cylinder(d=3, h=11);
}
color("black") hull() {
translate([-6,2.25,-6]) cylinder(d=3, h=12.25);
translate([6,2.25,-6]) cylinder(d=3, h=12.25);
translate([-5.25,-2.25,-6]) cylinder(d=3, h=12.25);
translate([5.25,-2.25,-6]) cylinder(d=3, h=12.25);
}
// mount plate
translate([-15.5,-6.5,-.25]) slab([31,13,.5], 2);
// rear pins
color("silver") translate([-5.48,1.4,-8]) cylinder(d=1.5, h=9);
color("silver") translate([-2.74,1.4,-8]) cylinder(d=1.5, h=9);
color("silver") translate([0,1.4,-8]) cylinder(d=1.5, h=9);
color("silver") translate([2.74,1.4,-8]) cylinder(d=1.5, h=9);
color("silver") translate([5.48,1.4,-8]) cylinder(d=1.5, h=9);
color("silver") translate([-4.12,-1.4,-8]) cylinder(d=1.5, h=9);
color("silver") translate([-1.38,-1.4,-8]) cylinder(d=1.5, h=9);
color("silver") translate([1.36,-1.4,-8]) cylinder(d=1.5, h=9);
color("silver") translate([4,-1.4,-8]) cylinder(d=1.5, h=9);
}
// mount holes
color("silver") translate([-12.5,0,-3]) cylinder(d=3.2, h=6);
color("silver") translate([12.5,0,-3]) cylinder(d=3.2, h=6);
// pin holes
color("silver") translate([-5.48,1.4,-9]) cylinder(d=1, h=16);
color("silver") translate([-2.74,1.4,-9]) cylinder(d=1, h=16);
color("silver") translate([0,1.4,-9]) cylinder(d=1, h=16);
color("silver") translate([2.74,1.4,-9]) cylinder(d=1, h=16);
color("silver") translate([5.48,1.4,-9]) cylinder(d=1, h=16);
color("silver") translate([-4.12,-1.4,-9]) cylinder(d=1, h=16);
color("silver") translate([-1.38,-1.4,-9]) cylinder(d=1, h=16);
color("silver") translate([1.36,-1.4,-9]) cylinder(d=1, h=16);
color("silver") translate([4,-1.4,-9]) cylinder(d=1, h=16);
}
}
}
}

377
lib/fans.scad Normal file
View File

@@ -0,0 +1,377 @@
/*
This file is part of SBC Case Builder https://github.com/hominoids/SBC_Case_Builder
Copyright 2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
fans(style, mask)
fan_cover(size, thick)
fan_mask(size, thick, style)
*/
/*
NAME: fans
DESCRIPTION: creates different fan styles and sizes
TODO: add efficient vanes
USAGE: fans(style, mask)
style = "box",
mask[0] = true enables component mask
mask[1] = mask length
mask[2] = mask setback
mask[3] = mstyle "default", "fan_open", "fan_1", "fan_2", "fan_hex"
*/
module fans(style, mask) {
// size, thick, hole-spacing, hole-size, hub-size
fan_data = [
["box140x25", 140, 25, 124.5, 4.3, 40, "#353535"],
["box120x25", 120, 25, 105, 4.3, 40, "#353535"],
["box92x25", 92, 25, 82.5, 4.3, 40, "#353535"],
["box92x10", 92, 10, 82.5, 4.3, 40, "#353535"],
["box80x25", 80, 25, 72.5, 4.3, 35, "#353535"],
["box80x10", 80, 10, 72.5, 4.3, 35, "#353535"],
["box60x25", 60, 25, 50, 4.3, 30, "#353535"],
["box60x10", 60, 10, 50, 4.3, 30, "#353535"],
["box50x10", 60, 10, 40, 4.3, 20, "#353535"],
["box40x10", 40, 10, 32, 4.3, 18, "#353535"],
["box30x10", 30, 10, 24, 3.2, 12, "#353535"]
];
f = search([style],fan_data);
diameter = fan_data[f[0]][1];
thickness = fan_data[f[0]][2];
hole_space = fan_data[f[0]][3];
hole_size = fan_data[f[0]][4];
hole_offset = (diameter-hole_space)/2;
hub_size = fan_data[f[0]][5];
fan_color = fan_data[f[0]][6];
enablemask = mask[0];
mlength = mask[1];
msetback = mask[2];
mstyle = mask[3];
adj = .01;
$fn = 90;
if(enablemask == true) {
if(mstyle == "fan_open") {
translate([0, 0, thickness-msetback+1]) fan_mask(diameter, mlength, "fan_open");
}
if(mstyle == "default" || mstyle == "fan_1") {
translate([0, 0, thickness-msetback+1]) fan_mask(diameter, mlength, "fan_1");
}
if(mstyle == "fan_2") {
translate([0, 0, thickness-msetback+1]) fan_mask(diameter, mlength, "fan_2");
}
if(mstyle == "fan_hex") {
translate([0, 0, thickness-msetback+1]) fan_mask(diameter, mlength, "fan_hex");
}
}
if(enablemask == false) {
difference() {
union() {
color(fan_color) slab([diameter, diameter, 3], 4);
color(fan_color) translate([0, 0, thickness-3]) slab([diameter, diameter, 3], 4);
color(fan_color) translate([diameter/2, diameter/2, 0]) cylinder(d=diameter+2, h=thickness);
}
// holes
color(fan_color) translate([diameter/2, diameter/2, -1]) cylinder(d=diameter-2, h=thickness+2);
color(fan_color) translate([hole_offset,hole_offset,-1]) cylinder(d=hole_size, h=thickness+2);
color(fan_color) translate([hole_offset,diameter-hole_offset,-1]) cylinder(d=hole_size, h=thickness+2);
color(fan_color) translate([diameter-hole_offset,hole_offset,-1]) cylinder(d=hole_size, h=thickness+2);
color(fan_color) translate([diameter-hole_offset,diameter-hole_offset,-1]) cylinder(d=hole_size, h=thickness+2);
// trim sides
color(fan_color) translate([-4,-4, -1]) cube([4, diameter+8, thickness+2]);
color(fan_color) translate([diameter,-4, -1]) cube([4, diameter+8, thickness+2]);
color(fan_color) translate([-4,-4, -1]) cube([diameter+8, 4, thickness+2]);
color(fan_color) translate([-4,diameter, -1]) cube([diameter+8, 4, thickness+2]);
}
color(fan_color) translate([diameter/2, diameter/2, thickness/2]) rotate([0,0,30])
cylinder_fillet_inside(h=thickness, r=hub_size/2, top=1, bottom=1, $fn=90, fillet_fn=90, center=true);
}
}
/*
NAME: fan_cover
DESCRIPTION: creates fan covers for fan openings
TODO: none
USAGE: fan_cover(size, thick, style)
size = size of fan
thick = thickness of cover
style = "fan_open", "fan_1", "fan_2", "fan_hex"
*/
module fan_cover(size, thick, style) {
difference() {
color("grey", 1) slab([size, size, thick], 3);
color("grey", 1) fan_mask(size, thick, style);
}
}
/*
DESCRIPTION: creates fan masks for openings
TODO:
USAGE: fan_mask(size, thick, style)
size = size of fan
thick = thickness of cover
style = "fan_open", "fan_1", "fan_2", "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 == "fan_open") {
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 == "fan_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 == "fan_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 == "fan_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 == "fan_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 == "fan_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, 11])
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+4], center=true);
rotate([0, 0, 45]) cube([bar_size, size, thick+4], center=true);
}
}
}
}
if(style == "fan_hex") {
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);
}
}

48
lib/fastener.scad Normal file
View File

@@ -0,0 +1,48 @@
/*
This file is part of SBC Case Builder https://github.com/hominoids/SBC_Case_Builder
Copyright 2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
m_insert(type="M3", icolor = "#ebdc8b")
*/
/*
NAME: 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]);
}
}

42
lib/feet.scad Normal file
View File

@@ -0,0 +1,42 @@
/*
This file is part of SBC Case Builder https://github.com/hominoids/SBC_Case_Builder
Copyright 2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
feet (diameter, height)
*/
/*
NAME: feet
DESCRIPTION: creates simple case feet
TODO: none
USAGE: feet (diameter, height)
diameter = size of fan
height = thickness of cover
*/
module feet (diameter, height) {
difference (){
cylinder (d=diameter,h=height);
translate([0,0,-1]) cylinder (d=3, h=height+2,$fn=90);
translate ([0,0,-1]) cylinder(r=3.35,h=height-3,$fn=6);
}
}

820
lib/hd.scad Normal file
View File

@@ -0,0 +1,820 @@
/*
This file is part of SBC Case Builder https://github.com/hominoids/SBC_Case_Builder
Copyright 2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
hd25(orientation, height, mask)
hd25_tab(side)
hd25_vtab(side)
hd35(orientation, mask)
hdd35_25holder(length)
hd35_tab(side)
hd35_vtab(side)
hd_bottom_holes(hd, orientation, side, thick)
hd_mount(hd, orientation, position, side)
*/
/*
NAME: hd25
DESCRIPTION: creates 2.5" hard drive model
TODO: none
USAGE: hd25(orientation, height, mask)
orientation = "landscape", "portrait"
height = drive height
mask[0] = true enables component mask
mask[1] = mask length
mask[2] = mask setback
mask[3] = mstyle "default", "bottom", "side", "both"
*/
module hd25(orientation, height, mask) {
hd25_x = 100;
hd25_y = 69.85;
hd25_z = height;
enablemask = mask[0];
mlength = mask[1];
msetback = mask[2];
mstyle = mask[3];
adj = .01;
$fn = 90;
if(enablemask == true) {
if(orientation == "landscape" && (mstyle == "side" || mstyle == "both" || mstyle == "default")) {
translate([0, msetback, 0]) hd_holes(2.5, "landscape", "left", mlength);
translate([0, -msetback, 0]) hd_holes(2.5, "landscape", "right", mlength);
}
if(orientation == "landscape" && (mstyle == "bottom" || mstyle == "both")) {
translate([0, 0, msetback]) hd_holes(2.5, "landscape", "bottom", mlength);
}
if(orientation == "portrait" && (mstyle == "side" || mstyle == "both" || mstyle == "default")) {
translate([msetback, 0, 0]) hd_holes(2.5, "portrait", "left", mlength);
translate([-msetback, 0, 0]) hd_holes(2.5, "portrait", "right", mlength);
}
if(orientation == "portrait" && (mstyle == "bottom" || mstyle == "both")) {
translate([0, 0, -mlength+msetback]) hd_holes(2.5, "portrait", "bottom", mlength);
}
}
if(enablemask == false) {
if(orientation == "landscape") {
difference() {
color("LightGrey",.6) cube([hd25_x,hd25_y,hd25_z]);
// bottom screw holes
color("Black",.6) translate([9.4,4.07,-adj]) cylinder(d=3,h=3);
color("Black",.6) translate([86,4.07,-adj]) cylinder(d=3,h=3);
color("Black",.6) translate([86,65.79,-adj]) cylinder(d=3,h=4);
color("Black",.6) translate([9.4,65.79,-adj]) cylinder(d=3,h=4);
// side screw holes
color("Black",.6) translate([9.4,-adj,3]) rotate([-90,0,0]) cylinder(d=3,h=3);
color("Black",.6) translate([86,-adj,3]) rotate([-90,0,0]) cylinder(d=3,h=3);
color("Black",.6) translate([86,hd25_y+adj,3]) rotate([90,0,0]) cylinder(d=3,h=3);
color("Black",.6) translate([9.4,hd25_y+adj,3]) rotate([90,0,0]) cylinder(d=3,h=3);
// connector opening
color("LightSlateGray",.6) translate([hd25_x-5,11,-1]) cube([5+adj,32,5+adj]);
}
}
if(orientation == "portrait") {
translate([0,hd25_x,0]) rotate([0,0,270])
difference() {
color("LightGrey",.6) cube([hd25_x,hd25_y,hd25_z]);
// bottom screw holes
color("Black",.6) translate([9.4,4.07,-adj]) cylinder(d=3,h=3);
color("Black",.6) translate([86,4.07,-adj]) cylinder(d=3,h=3);
color("Black",.6) translate([86,65.79,-adj]) cylinder(d=3,h=4);
color("Black",.6) translate([9.4,65.79,-adj]) cylinder(d=3,h=4);
// side screw holes
color("Black",.6) translate([9.4,-adj,3]) rotate([-90,0,0]) cylinder(d=3,h=3);
color("Black",.6) translate([86,-adj,3]) rotate([-90,0,0]) cylinder(d=3,h=3);
color("Black",.6) translate([86,hd25_y+adj,3]) rotate([90,0,0]) cylinder(d=3,h=3);
color("Black",.6) translate([9.4,hd25_y+adj,3]) rotate([90,0,0]) cylinder(d=3,h=3);
// connector opening
color("LightSlateGray",.6) translate([hd25_x-5,11,-1]) cube([5+adj,32,5+adj]);
}
}
}
}
/*
NAME: hd25_tab
DESCRIPTION: creates 2.5" hard drive tabs for horizontal mounting
TODO: none
USAGE: hd25_tab(side)
side = "left", "right"
*/
module hd25_tab(side) {
width = 15;
l_width = 26;
depth = 15;
height = 4;
fillet = 2;
hole = 3.6;
length = 3;
adj = .01;
$fn = 90;
if(side == "left") {
difference() {
union() {
translate([0,-depth/2,0]) rotate([0,-90,0])
slab_r([l_width,depth,height], [fillet,fillet,fillet,fillet]);
translate([-height,-depth/2,0]) cube([height,depth,height]);
translate([adj,-5.5,depth])
rotate([90,0,0])
linear_extrude(height = 2)
polygon(points = [ [-height,height],
[-depth+4,-depth],
[-height,-depth]]);
translate([adj,7.5,depth])
rotate([90,0,0])
linear_extrude(height = 2)
polygon(points = [ [-height,height],
[-depth+4,-depth],
[-height,-depth]]);
}
translate([4.07,0,-adj]) rotate([0,0,0]) cylinder(d=hole, h=3);
translate([-height-adj,(width/2)-(length/2)-depth/2,3]) rotate([90,0,90]) slot(hole,length,height+(2*adj));
translate([-height-adj,(width/2)-(length/2)-depth/2,21]) rotate([90,0,90]) slot(hole,length,height+(2*adj));
}
}
if(side == "right") {
difference() {
union() {
translate([height,-depth/2,0]) rotate([0,-90,0])
slab_r([l_width,depth,height], [fillet,fillet,fillet,fillet]);
translate([0,-depth/2,0]) cube([height,depth,height]);
translate([adj,-7.5,depth])
rotate([90,0,180])
linear_extrude(height = 2)
polygon(points = [ [-height,height],
[-depth+4,-depth],
[-height,-depth]]);
translate([adj,5.5,depth])
rotate([90,0,180])
linear_extrude(height = 2)
polygon(points = [ [-height,height],
[-depth+4,-depth],
[-height,-depth]]);
}
translate([-4.07,0,-adj]) rotate([0,0,0]) cylinder(d=hole, h=3);
translate([-adj,(width/2)-(length/2)-depth/2,3]) rotate([90,0,90]) slot(hole,length,height+(2*adj));
translate([-adj,(width/2)-(length/2)-depth/2,21]) rotate([90,0,90]) slot(hole,length,height+(2*adj));
}
}
}
/*
NAME: hd25_vtab
DESCRIPTION: creates 2.5" hard drive tabs for vertical mounting
TODO: none
USAGE: hd25_vtab(side)
side = "left", "right"
*/
module hd25_vtab(side) {
width = 15;
l_width = 16;
depth = 15;
height = 4;
fillet = 2;
hole = 3.6;
length = 3;
adj = .01;
$fn = 90;
if(side == "left") {
difference() {
union() {
translate([0,-depth/2,0]) rotate([0,-90,0])
slab_r([l_width,depth,height], [fillet,fillet,fillet,fillet]);
translate([-height,-depth/2,0]) cube([height,depth,height]);
translate([adj,-5.5,depth])
rotate([90,0,0])
linear_extrude(height = 2)
polygon(points = [ [-height,height-5],
[-depth+4,-depth],
[-height,-depth]]);
translate([adj,7.5,depth])
rotate([90,0,0])
linear_extrude(height = 2)
polygon(points = [ [-height,height-5],
[-depth+4,-depth],
[-height,-depth]]);
}
translate([3,0,-adj]) rotate([0,0,0]) cylinder(d=hole, h=3);
translate([-height-adj,1.5+(width/2)-(length/2)-depth/2,5.57]) rotate([90,90,90]) slot(hole,length,height+(2*adj));
}
}
if(side == "right") {
difference() {
union() {
translate([height,-depth/2,0]) rotate([0,-90,0])
slab_r([l_width,depth,height], [fillet,fillet,fillet,fillet]);
translate([0,-depth/2,0]) cube([height,depth,height]);
translate([adj,-7.5,depth])
rotate([90,0,180])
linear_extrude(height = 2)
polygon(points = [ [-height,height-5],
[-depth+4,-depth],
[-height,-depth]]);
translate([adj,5.5,depth])
rotate([90,0,180])
linear_extrude(height = 2)
polygon(points = [ [-height,height-5],
[-depth+4,-depth],
[-height,-depth]]);
}
translate([-3,0,-adj]) rotate([0,0,0]) cylinder(d=hole, h=3);
translate([-adj,1.5+(width/2)-(length/2)-depth/2,5.57]) rotate([90,90,90]) slot(hole,length,height+(2*adj));
}
}
}
/*
NAME: hd35
DESCRIPTION: creates 3.5" hard drive model
TODO: none
USAGE: hd35(orientation, mask)
orientation = "landscape", "portrait"
mask[0] = true enables component mask
mask[1] = mask length
mask[2] = mask setback
mask[3] = mstyle "default", "bottom", "side", "both"
*/
module hd35(orientation, mask) {
hd35_x = 147;
hd35_y = 101.6;
hd35_z = 26.1;
enablemask = mask[0];
mlength = mask[1];
msetback = mask[2];
mstyle = mask[3];
adj = .01;
$fn = 90;
if(enablemask == true) {
if(orientation == "landscape" && (mstyle == "side" || mstyle == "both" || mstyle == "default")) {
translate([0, msetback, 0]) hd_holes(3.5, "landscape", "left", mlength);
translate([0, -msetback, 0]) hd_holes(3.5, "landscape", "right", mlength);
}
if(orientation == "landscape" && (mstyle == "bottom" || mstyle == "both")) {
translate([0, 0, msetback]) hd_holes(3.5, "landscape", "bottom", mlength);
}
if(orientation == "portrait" && (mstyle == "side" || mstyle == "both" || mstyle == "default")) {
translate([msetback, 0, 0]) hd_holes(3.5, "portrait", "left", mlength);
translate([-msetback, 0, 0]) hd_holes(3.5, "portrait", "right", mlength);
}
if(orientation == "portrait" && (mstyle == "bottom" || mstyle == "both")) {
translate([0, 0, -mlength+msetback]) hd_holes(3.5, "portrait", "bottom", mlength);
}
}
if(enablemask == false) {
if(orientation == "landscape") {
difference() {
color("LightGrey",.6) cube([hd35_x,hd35_y,hd35_z]);
// bottom screw holes
color("Black",.6) translate([29.52,3.18,-adj]) cylinder(d=3,h=3+adj);
color("Black",.6) translate([61.27,3.18,-adj]) cylinder(d=3,h=3+adj);
color("Black",.6) translate([105.72,3.18,-adj]) cylinder(d=3,h=3+adj);
color("Black",.6) translate([29.52,98.43,-adj]) cylinder(d=3,h=3+adj);
color("Black",.6) translate([61.27,98.43,-adj]) cylinder(d=3,h=3+adj);
color("Black",.6) translate([105.72,98.43,-adj]) cylinder(d=3,h=3+adj);
// side screw holes
color("Black",.6) translate([16.9,-adj,6.35]) rotate([-90,0,0]) cylinder(d=3,h=3);
color("Black",.6) translate([76.6,-adj,6.35]) rotate([-90,0,0]) cylinder(d=3,h=3);
color("Black",.6) translate([118.5,-adj,6.35]) rotate([-90,0,0]) cylinder(d=3,h=3);
color("Black",.6) translate([118.5,hd35_y+adj,6.35]) rotate([90,0,0]) cylinder(d=3,h=3);
color("Black",.6) translate([76.6,hd35_y+adj,6.35]) rotate([90,0,0]) cylinder(d=3,h=3);
color("Black",.6) translate([16.9,hd35_y+adj,6.35]) rotate([90,0,0]) cylinder(d=3,h=3);
// connector opening
color("LightSlateGray",.6) translate([hd35_x-5,11,-1]) cube([5+adj,32,5+adj]);
}
}
if(orientation == "portrait") {
translate([0,hd35_x,0]) rotate([0,0,270])
difference() {
color("LightGrey",.6) cube([hd35_x,hd35_y,hd35_z]);
// bottom screw holes
color("Black",.6) translate([29.52,3.18,-adj]) cylinder(d=3,h=3+adj);
color("Black",.6) translate([61.27,3.18,-adj]) cylinder(d=3,h=3+adj);
color("Black",.6) translate([105.72,3.18,-adj]) cylinder(d=3,h=3+adj);
color("Black",.6) translate([29.52,98.43,-adj]) cylinder(d=3,h=3+adj);
color("Black",.6) translate([61.27,98.43,-adj]) cylinder(d=3,h=3+adj);
color("Black",.6) translate([105.72,98.43,-adj]) cylinder(d=3,h=3+adj);
// side screw holes
color("Black",.6) translate([16.9,-adj,6.35]) rotate([-90,0,0]) cylinder(d=3,h=3);
color("Black",.6) translate([76.6,-adj,6.35]) rotate([-90,0,0]) cylinder(d=3,h=3);
color("Black",.6) translate([118.5,-adj,6.35]) rotate([-90,0,0]) cylinder(d=3,h=3);
color("Black",.6) translate([118.5,hd35_y+adj,6.35]) rotate([90,0,0]) cylinder(d=3,h=3);
color("Black",.6) translate([76.6,hd35_y+adj,6.35]) rotate([90,0,0]) cylinder(d=3,h=3);
color("Black",.6) translate([16.9,hd35_y+adj,6.35]) rotate([90,0,0]) cylinder(d=3,h=3);
// connector opening
color("LightSlateGray",.6) translate([hd35_x-5,11,-1]) cube([5+adj,32,5+adj]);
}
}
}
}
/*
NAME: hd35_25holder
DESCRIPTION: 3.5" hdd to 2.5" hdd holder
TODO: none
USAGE: hdd35_25holder(length, width=101.6)
length = length of holder min. 145mm for 3.5" drive
*/
module hd35_25holder(length, width=101.6) {
wallthick = 3;
floorthick = 2;
hd35_x = length; // 145mm for 3.5" drive
hd35_y = width;
hd35_z = 12;
hd25_x = 100;
hd25_y = 69.85;
hd25_z = 9.5;
hd25_xloc = 2; // or (hd35_x-hd25_x)/2
hd25_yloc = (hd35_y-hd25_y)/2;
hd25_zloc = 9.5;
adj = .1;
$fn=90;
difference() {
union() {
difference() {
translate([(hd35_x/2),(hd35_y/2),(hd35_z/2)])
cube_fillet_inside([hd35_x,hd35_y,hd35_z],
vertical=[3,3,3,3], top=[0,0,0,0], bottom=[0,0,0,0], $fn=90);
translate([(hd35_x/2),(hd35_y/2),(hd35_z/2)+floorthick])
cube_fillet_inside([hd35_x-(wallthick*2),hd35_y-(wallthick*2),hd35_z],
vertical=[0,0,0,0], top=[0,0,0,0], bottom=[0,0,0,0], $fn=90);
// end trim
translate([-adj,5,wallthick+2]) cube([wallthick+(adj*2),hd35_y-10,10]);
translate([hd35_x-wallthick-adj,5,wallthick+2]) cube([wallthick+(adj*2),hd35_y-10,10]);
// bottom vents
for ( r=[15:40:hd35_x-40]) {
for (c=[hd35_y-76:4:75]) {
translate ([r,c,-adj]) cube([35,2,wallthick+(adj*2)]);
}
}
}
// 2.5 hdd bottom support
translate([9.4+hd25_xloc,4.07+hd25_yloc,floorthick-adj]) cylinder(d=8,h=4);
translate([86+hd25_xloc,4.07+hd25_yloc,floorthick-adj]) cylinder(d=8,h=4);
translate([86+hd25_xloc,65.79+hd25_yloc,floorthick-adj]) cylinder(d=8,h=4);
translate([9.4+hd25_xloc,65.79+hd25_yloc,floorthick-adj]) cylinder(d=8,h=4);
// side nut holder support
translate([16,wallthick-adj,7]) rotate([-90,0,0]) cylinder(d=10,h=3);
translate([76,wallthick-adj,7]) rotate([-90,0,0]) cylinder(d=10,h=3);
if(length >= 120) {
translate([117.5,wallthick-adj,7]) rotate([-90,0,0]) cylinder(d=10,h=3);
translate([117.5,hd35_y-wallthick+adj,7]) rotate([90,0,0]) cylinder(d=10,h=3);
}
translate([76,hd35_y-wallthick+adj,7]) rotate([90,0,0]) cylinder(d=10,h=3);
translate([16,hd35_y-wallthick+adj,7]) rotate([90,0,0]) cylinder(d=10,h=3);
// bottom-side support
translate([wallthick,wallthick,floorthick-2]) rotate([45,0,0]) cube([hd35_x-(wallthick*2),3,3]);
translate([wallthick,hd35_y-wallthick+adj,floorthick-2]) rotate([45,0,0]) cube([hd35_x-(wallthick*2),3,3]);
}
// bottom screw holes
translate([9.4+hd25_xloc,4.07+hd25_yloc,-adj]) cylinder(d=3,h=(floorthick*3)+(adj*2));
translate([86+hd25_xloc,4.07+hd25_yloc,-adj]) cylinder(d=3,h=(floorthick*3)+(adj*2));
translate([86+hd25_xloc,65.79+hd25_yloc,-adj]) cylinder(d=3,h=(floorthick*3)+(adj*2));
translate([9.4+hd25_xloc,65.79+hd25_yloc,-adj]) cylinder(d=3,h=(floorthick*3)+(adj*2));
// countersink holes
translate([9.4+hd25_xloc,4.07+hd25_yloc,-adj]) cylinder(d1=6.5, d2=3, h=3);
translate([86+hd25_xloc,4.07+hd25_yloc,-adj]) cylinder(d1=6.5, d2=3, h=3);
translate([86+hd25_xloc,65.79+hd25_yloc,-adj]) cylinder(d1=6.5, d2=3, h=3);
translate([9.4+hd25_xloc,65.79+hd25_yloc,-adj]) cylinder(d1=6.5, d2=3, h=3);
// side screw holes
translate([16,-adj,7]) rotate([-90,0,0]) cylinder(d=3.6,h=7);
translate([76,-adj,7]) rotate([-90,0,0]) cylinder(d=3.6,h=7);
translate([117.5,-adj,7]) rotate([-90,0,0]) cylinder(d=3.6,h=7);
translate([117.5,hd35_y+adj,7]) rotate([90,0,0]) cylinder(d=3.6,h=7);
translate([76,hd35_y+adj,7]) rotate([90,0,0]) cylinder(d=3.6,h=7);
translate([16,hd35_y+adj,7]) rotate([90,0,0]) cylinder(d=3.6,h=7);
// side nut trap
translate([16,wallthick-adj,7]) rotate([-90,0,0]) cylinder(r=3.30,h=5,$fn=6);
translate([76,wallthick-adj,7]) rotate([-90,0,0]) cylinder(r=3.30,h=5,$fn=6);
translate([117.5,wallthick-adj,7]) rotate([-90,0,0]) cylinder(r=3.30,h=5,$fn=6);
translate([117.5,hd35_y-wallthick-adj,7]) rotate([90,0,0]) cylinder(r=3.30,h=5,$fn=6);
translate([76,hd35_y-wallthick-adj,7]) rotate([90,0,0]) cylinder(r=3.30,h=5,$fn=6);
translate([16,hd35_y-wallthick-adj,7]) rotate([90,0,0]) cylinder(r=3.30,h=5,$fn=6);
}
}
/*
NAME: hd35_tab
DESCRIPTION: creates 3.5" hard drive tabs for horizontal mounting
TODO: none
USAGE: hd35_tab(side)
side = "left", "right"
*/
module hd35_tab(side) {
width = 15;
l_width = 46;
depth = 15;
height = 4;
fillet = 2;
hole = 3.6;
length = 3;
adj = .01;
$fn = 90;
if(side == "left") {
difference() {
union() {
translate([0,-depth/2,0]) rotate([0,-90,0])
slab_r([l_width,depth,height], [fillet,fillet,fillet,fillet]);
translate([-height,-depth/2,0]) cube([height,depth,height]);
translate([adj,-5.5,depth])
rotate([90,0,0])
linear_extrude(height = 2)
polygon(points = [ [-height,height+20],
[-depth+4,-depth],
[-height,-depth]]);
translate([adj,7.5,depth])
rotate([90,0,0])
linear_extrude(height = 2)
polygon(points = [ [-height,height+20],
[-depth+4,-depth],
[-height,-depth]]);
}
translate([3.18,0,-adj]) rotate([0,0,0]) cylinder(d=hole, h=3);
translate([-height-adj,(width/2)-(length/2)-depth/2,6.35]) rotate([90,0,90]) slot(hole,length,height+(2*adj));
translate([-height-adj,(width/2)-(length/2)-depth/2,38.35]) rotate([90,0,90]) slot(hole,length,height+(2*adj));
}
}
if(side == "right") {
difference() {
union() {
translate([height,-depth/2,0]) rotate([0,-90,0])
slab_r([l_width,depth,height], [fillet,fillet,fillet,fillet]);
translate([0,-depth/2,0]) cube([height,depth,height]);
translate([adj,-7.5,depth])
rotate([90,0,180])
linear_extrude(height = 2)
polygon(points = [ [-height,height+20],
[-depth+4,-depth],
[-height,-depth]]);
translate([adj,5.5,depth])
rotate([90,0,180])
linear_extrude(height = 2)
polygon(points = [ [-height,height+20],
[-depth+4,-depth],
[-height,-depth]]);
}
translate([-3.18,0,-adj]) rotate([0,0,0]) cylinder(d=hole, h=3);
translate([-adj,(width/2)-(length/2)-depth/2,6.35]) rotate([90,0,90]) slot(hole,length,height+(2*adj));
translate([-adj,(width/2)-(length/2)-depth/2,38.35]) rotate([90,0,90]) slot(hole,length,height+(2*adj));
}
}
}
/*
NAME: hd35_vtab
DESCRIPTION: creates 3.5" hard drive tabs for vertical mounting
TODO: none
USAGE: hd35_vtab(side)
side = "left", "right"
*/
module hd35_vtab(side) {
width = 15;
l_width = 16;
depth = 15;
height = 4;
fillet = 2;
hole = 3.6;
length = 3;
adj = .01;
$fn = 90;
if(side == "left") {
difference() {
union() {
translate([0,-depth/2,0]) rotate([0,-90,0])
slab_r([l_width,depth,height], [fillet,fillet,fillet,fillet]);
translate([-height,-depth/2,0]) cube([height,depth,height]);
translate([adj,-5.5,depth])
rotate([90,0,0])
linear_extrude(height = 2)
polygon(points = [ [-height,height-5],
[-depth+4,-depth],
[-height,-depth]]);
translate([adj,7.5,depth])
rotate([90,0,0])
linear_extrude(height = 2)
polygon(points = [ [-height,height-5],
[-depth+4,-depth],
[-height,-depth]]);
}
translate([3,0,-adj]) rotate([0,0,0]) cylinder(d=hole, h=3);
translate([-height-adj,1.5+(width/2)-(length/2)-depth/2,5.57]) rotate([90,90,90]) slot(hole,length,height+(2*adj));
}
}
if(side == "right") {
difference() {
union() {
translate([height,-depth/2,0]) rotate([0,-90,0])
slab_r([l_width,depth,height], [fillet,fillet,fillet,fillet]);
translate([0,-depth/2,0]) cube([height,depth,height]);
translate([adj,-7.5,depth])
rotate([90,0,180])
linear_extrude(height = 2)
polygon(points = [ [-height,height-5],
[-depth+4,-depth],
[-height,-depth]]);
translate([adj,5.5,depth])
rotate([90,0,180])
linear_extrude(height = 2)
polygon(points = [ [-height,height-5],
[-depth+4,-depth],
[-height,-depth]]);
}
translate([-3,0,-adj]) rotate([0,0,0]) cylinder(d=hole, h=3);
translate([-adj,1.5+(width/2)-(length/2)-depth/2,5.57]) rotate([90,90,90]) slot(hole,length,height+(2*adj));
}
}
}
/*
NAME: hd_holes
DESCRIPTION: creates 2.5" and 3.5" hard drive hole mask for mounting
TODO: none
USAGE: hd_bottom_holes(hd, orientation, side, thick)
hd = 2.5, 3.5
orientation = "portrait", "landscape"
side = "left", "right", "both", "bottom", "all"
thick = floor thickness
*/
module hd_holes(hd, orientation, side, thick) {
hd25_x = 100;
hd25_y = 69.85;
hd35_x = 147;
hd35_y = 101.6;
hd35_z = 26.1;
adj = .01;
$fn = 90;
if(hd == 2.5) {
if(orientation == "portrait") {
translate([0,hd25_x,0]) rotate([0,0,270]) union() {
if(side == "left" || side == "both" || side == "all") {
translate([9.4,-thick,3]) rotate([270,0,0]) cylinder(d=3.6,h=thick);
translate([86,-thick,3]) rotate([270,0,0]) cylinder(d=3.6,h=thick);
}
if(side == "right" || side == "both" || side == "all") {
translate([9.4,hd25_y+thick,3]) rotate([90,0,0]) cylinder(d=3.6,h=thick);
translate([86,hd25_y+thick,3]) rotate([90,0,0]) cylinder(d=3.6,h=thick);
}
if(side == "bottom" || side == "all") {
translate([9.4,4.07,0]) cylinder(d=3.6,h=thick);
translate([86,4.07,0]) cylinder(d=3.6,h=thick);
translate([86,65.79,0]) cylinder(d=3.6,h=thick);
translate([9.4,65.79,0]) cylinder(d=3.6,h=thick);
}
}
}
if(orientation == "landscape") {
if(side == "left" || side == "both" || side == "all") {
translate([9.4,-thick,3]) rotate([270,0,0]) cylinder(d=3.6,h=thick);
translate([86,-thick,3]) rotate([270,0,0]) cylinder(d=3.6,h=thick);
}
if(side == "right" || side == "both" || side == "all") {
translate([9.4,hd25_y+thick,3]) rotate([90,0,0]) cylinder(d=3.6,h=thick);
translate([86,hd25_y+thick,3]) rotate([90,0,0]) cylinder(d=3.6,h=thick);
}
if(side == "bottom" || side == "all") {
translate([9.4,4.07,-thick]) cylinder(d=3.6,h=thick);
translate([86,4.07,-thick]) cylinder(d=3.6,h=thick);
translate([86,65.79,-thick]) cylinder(d=3.6,h=thick);
translate([9.4,65.79,-thick]) cylinder(d=3.6,h=thick);
}
}
}
if(hd == 3.5) {
if(orientation == "portrait") {
translate([0,hd35_x,0]) rotate([0,0,270]) union() {
if(side == "left" || side == "both" || side == "all") {
translate([16.9,-thick,6.35]) rotate([270,0,0]) cylinder(d=3,h=thick);
translate([76.6,-thick,6.35]) rotate([270,0,0]) cylinder(d=3,h=thick);
translate([118.5,-thick,6.35]) rotate([270,0,0]) cylinder(d=3,h=thick);
}
if(side == "right" || side == "both" || side == "all") {
translate([118.5,hd35_y+thick,6.35]) rotate([90,0,0]) cylinder(d=3,h=thick);
translate([76.6,hd35_y+thick,6.35]) rotate([90,0,0]) cylinder(d=3,h=thick);
translate([16.9,hd35_y+thick,6.35]) rotate([90,0,0]) cylinder(d=3,h=thick);
}
if(side == "bottom" || side == "all") {
// landscape 3.5" bottom screw holes
translate([29.52,3.18,0]) cylinder(d=3.6,h=thick);
translate([61.27,3.18,0]) cylinder(d=3.6,h=thick);
translate([105.72,3.18,0]) cylinder(d=3.6,h=thick);
translate([29.52,98.43,0]) cylinder(d=3.6,h=thick);
translate([61.27,98.43,0]) cylinder(d=3.6,h=thick);
translate([105.72,98.43,0]) cylinder(d=3.6,h=thick);
}
}
}
if(orientation == "landscape") {
if(side == "left" || side == "both" || side == "all") {
translate([16.9,-thick,6.35]) rotate([270,0,0]) cylinder(d=3,h=thick);
translate([76.6,-thick,6.35]) rotate([270,0,0]) cylinder(d=3,h=thick);
translate([118.5,-thick,6.35]) rotate([270,0,0]) cylinder(d=3,h=thick);
}
if(side == "right" || side == "both" || side == "all") {
translate([118.5,hd35_y+thick,6.35]) rotate([90,0,0]) cylinder(d=3,h=thick);
translate([76.6,hd35_y+thick,6.35]) rotate([90,0,0]) cylinder(d=3,h=thick);
translate([16.9,hd35_y+thick,6.35]) rotate([90,0,0]) cylinder(d=3,h=thick);
}
if(side == "bottom" || side == "all") {
// landscape 3.5" bottom screw holes
translate([29.52,3.18,-thick]) cylinder(d=3.6,h=thick);
translate([61.27,3.18,-thick]) cylinder(d=3.6,h=thick);
translate([105.72,3.18,-thick]) cylinder(d=3.6,h=thick);
translate([29.52,98.43,-thick]) cylinder(d=3.6,h=thick);
translate([61.27,98.43,-thick]) cylinder(d=3.6,h=thick);
translate([105.72,98.43,-thick]) cylinder(d=3.6,h=thick);
}
}
}
}
/*
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");
}
}
}
}

439
lib/holder.scad Normal file
View File

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

84
lib/keyhole.scad Normal file
View File

@@ -0,0 +1,84 @@
/*
This file is part of SBC Case Builder https://github.com/hominoids/SBC_Case_Builder
Copyright 2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
*/
/*
NAME: keyhole
DESCRIPTION: enclosed keyhole
TODO: none
USAGE: keyhole(keysize, mask)
keysize[0] = size_x
keysize[1] = size_y
keysize[2] = size_z
mask[0] = true enables component mask
mask[1] = mask length
mask[2] = mask setback
mask[3] = mstyle "default"
*/
module keyhole(keysize, mask) {
enablemask = mask[0];
mlength = mask[1];
msetback = mask[2];
mstyle = mask[3];
adj=.01;
$fn = 90;
if(enablemask == true && mstyle == "default") {
union() {
translate([0, 0, -adj]) cylinder(h=keysize[3]+2*adj, d=keysize[0]);
translate([-keysize[1]/2, 0, -adj]) cube([keysize[1], keysize[2]+keysize[0]/2, keysize[3]+2*adj]);
translate([0, -keysize[1]/2, -adj]) cube([keysize[2]+keysize[0]/2, keysize[1], keysize[3]+2*adj]);
}
}
else {
difference() {
union() {
translate([0, 0, -adj])
difference() {
difference() {
translate([-keysize[2], -keysize[2], keysize[3]]) cube([keysize[2]*3, keysize[2]*3, 4.5]);
translate([0, -10, 0]) rotate([0, 0, 135]) cube([20, 10, 10]);
translate([keysize[2], keysize[2], -adj]) cube([keysize[2]*3, keysize[2]*3, keysize[3]+5]);
}
difference() {
translate([-keysize[2]+2, -keysize[2]+2, keysize[3]-adj])
cube([-4+keysize[2]*3, -4+keysize[2]*3, 3.5]);
translate([2, -10, 0]) rotate([0, 0, 135]) cube([20, 10, 10]);
translate([+keysize[2]-2, keysize[2]-2, -adj])
cube([keysize[2]*3, keysize[2]*3, keysize[3]+5]);
}
}
difference() {
translate([-keysize[2], -keysize[2], 0]) cube([keysize[2]*3, keysize[2]*3, keysize[3]]);
translate([0, -10, -adj]) rotate([0, 0, 135]) cube([20, 10, 10]);
}
}
translate([keysize[2], keysize[2], -adj]) cube([keysize[2]*3, keysize[2]*3, keysize[3]+2*adj]);
union() {
translate([0, 0, -adj]) cylinder(h=keysize[3]+2*adj, d=keysize[0]);
translate([-keysize[1]/2, 0, -adj]) cube([keysize[1], keysize[2]+keysize[0]/2, keysize[3]+2*adj]);
translate([0, -keysize[1]/2, -adj]) cube([keysize[2]+keysize[0]/2, keysize[1], keysize[3]+2*adj]);
}
}
}
}

86
lib/oem_adafruit.scad Normal file
View File

@@ -0,0 +1,86 @@
/*
This file is part of SBC Case Builder https://github.com/hominoids/SBC_Case_Builder
Copyright 2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
adafruit_lcd(mask)
*/
/*
NAME: adafruit_lcd
DESCRIPTION: adafruit 4311 2in TFT IPS Display model
TODO: none
USAGE: adafruit_lcd(mask[])
mask[0] = true enables mask
mask[1] = mask length
mask[2] = mask setback
mask[3] = mstyle "default"
*/
module adafruit_lcd(mask) {
size_x = 35.5;
size_y = 59;
size_z = 1.6;
size_xm = size_x+1;
size_ym = size_y+1;
lcd_size = [34.75,48,2];
corner_radius = 2;
hole_size = 2.5;
enablemask = mask[0];
mlen = mask[1];
back = mask[2];
mstyle = mask[3];
adj = .01;
$fn = 90;
if(enablemask == true && mstyle == "default") {
translate([2.25, 11, size_z+2.5-back]) cube([lcd_size[0]-4, lcd_size[1]-7, mlen]);
storage("microsdcard", 11, 44, 0, "bottom", 180, [size_x, size_z, size_y], [0], size_z, enablemask, [true, 20, 0, "default"]);
fpc("fh19", .5, 22, 0, "bottom", 270, [18,0,0], ["smt","side","white","black"], size_z, enablemask, [true,10,2,"default"]);
}
if(enablemask == false) {
difference() {
union() {
color("#252525") slab([size_x, size_y, size_z], corner_radius);
color("black",1) translate([0.375, 5.75, size_z-adj]) cube([lcd_size[0], lcd_size[1], 2.5]);
color("#353535",1) translate([.375, 9.25, size_z+2.5-adj]) cube([lcd_size[0], lcd_size[1]-4, .1]);
color("dimgrey",1) translate([2.25, 11, size_z+2.5-adj]) cube([lcd_size[0]-4, lcd_size[1]-7, .2]);
}
color("#252525") translate([hole_size, size_y-hole_size, -adj]) cylinder(d=hole_size,h=6);
color("#252525") translate([size_x-hole_size, size_y-hole_size, -adj]) cylinder(d=hole_size, h=4);
for(i=[5:2.54:31]) {
color("#fee5a6",1) translate([i, 2.5, -adj]) cylinder(d=.8, h=6);
}
}
storage("microsdcard", 11, 44, 0, "bottom", 180, [size_x, size_z, size_y], [0], size_z, enablemask, [true, 20, 0, "default"]);
ic("generic", 13.25, 9, 0, "bottom", 0, [4, 10, 1.75], ["dimgrey"], size_z, enablemask, [false, 20, 0, "default"]);
fpc("fh19", .5, 22, 0, "bottom", 270, [18,0,0], ["smt","side","white","black"], size_z, enablemask, [true,10,2,"default"]);
for(i=[5:2.54:31]) {
pcbpad("round", i, 2.5, 0, "top", 0, [1, 1, 0], [.8, "#fee5a6", 1.2], size_z, enablemask, [false, 20, 0, "default"]);
}
pcbpad("round", hole_size, size_y-hole_size, 0, "top", 0, [1, 1, 0],
[hole_size, "#fee5a6", hole_size+1], size_z, enablemask, [false, 20, 0, "default"]);
pcbpad("round", size_x-hole_size, size_y-hole_size, 0, "top", 0, [1, 1, 0],
[hole_size, "#fee5a6", hole_size+1], size_z, enablemask, [false, 20, 0, "default"]);
}
}

1628
lib/oem_hk.scad Normal file

File diff suppressed because it is too large Load Diff

190
lib/standoff.scad Normal file
View File

@@ -0,0 +1,190 @@
/*
This file is part of SBC Case Builder https://github.com/hominoids/SBC_Case_Builder
Copyright 2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
*/
/*
NAME: standoff
DESCRIPTION: create standoffs
TODO: none
USAGE: standoff(stand_off, mask)
stand_off[size, diameter, height, holesize, supportsize, supportheight, sink, pillarstyle,
pillarsupport, reverse, insert_e, i_dia, i_depth], mask)
size = "m2_tap","m2","m2+","m2.5_tap","m2.5","m2.5+","m3_tap","m3","m3+","m4_tap","m4","m4+","custom"
diameter = pillar diameter
height = total height
holesize = hole diameter
supportsize = support size for sink
supportheight = height of support for sink
sink = none, countersunk, recessed, nut holder, blind
pillarstyle = hex, round
pillarsupport = none, left, rear, front, right
reverse = true or false
insert_e = true or false
i_dia = insert diameter
i_depth = insert hole depth
mask[0] = enablemask
mask[1] = mlength
mask[2] = msetback
mask[3] = mstyle
*/
module standoff(stand_off, mask){
size = stand_off[0];
diameter = size == "m2_tap" || size == "m2" || size == "m2+" ? 4 :
size == "m2.5_tap" || size == "m2.5" || size == "m2.5+" ? 4 :
size == "m3_tap" || size == "m3" || size == "m3+" ? 5 :
size == "m4_tap" || size == "m4" || size == "m4+" ? 6 : stand_off[1];
height = stand_off[2];
holesize = size == "m2_tap" ? 1.6 : size == "m2" ? 2 : size == "m2+" ? 2.26 :
size == "m2.5_tap" ? 2.05 : size == "m2.5" ? 2.5 : size == "m2.5+" ? 2.83 :
size == "m3_tap" ? 2.5 : size == "m3" ? 3 : size == "m3+" ? 3.4 :
size == "m4_tap" ? 3.3 : size == "m4" ? 4 : size == "m4+" ? 4.4 : stand_off[3];
supportsize = stand_off[4];
supportheight = stand_off[5];
sink = stand_off[6];
pillarstyle = stand_off[7];
pillarsupport = stand_off[8];
reverse = stand_off[9];
insert_e = stand_off[10];
i_dia = stand_off[11];
i_depth = stand_off[12];
enablemask = mask[0];
mlength = mask[1];
msetback = mask[2];
mstyle = mask[3];
ps = size == "m2_tap" || size == "m2" || size == "m2+" ? 4 :
size == "m2.5_tap" || size == "m2.5" || size == "m2.5+" ? 5 :
size == "m3_tap" || size == "m3" || size == "m3+" ? 6.72 :
size == "m4_tap" || size == "m4" || size == "m4+" ? 8.96 : (2*holesize)+.5;
ds = size == "m2_tap" || size == "m2" || size == "m2+" ? 1.2 :
size == "m2.5_tap" || size == "m2.5" || size == "m2.5+" ? 1.5 :
size == "m3_tap" || size == "m3" || size == "m3+" ? 1.86 :
size == "m4_tap" || size == "m4" || size == "m4+" ? 2.48 : holesize*.465;
adj = 0.1;
$fn = 90;
if(enablemask == true && mstyle == "default") {
if(reverse == true) {
translate([0,0,-msetback-adj]) cylinder(d=supportsize-2*adj,h=mlength);
}
else {
translate([0,0,-mlength+msetback+adj]) cylinder(d=supportsize-2*adj,h=mlength);
}
}
if(enablemask == false) {
difference (){
union () {
if(pillarstyle == "hex" && reverse == false) {
rotate([0,0,30]) cylinder(d=diameter*2/sqrt(3), h=height, $fn=6);
}
if(pillarstyle == "hex" && reverse == true) {
translate([0,0,-height]) rotate([0,0,30]) cylinder(d=diameter*2/sqrt(3), h=height, $fn=6);
}
if(pillarstyle == "round" && reverse == false) {
cylinder(d=diameter, h=height);
}
if(pillarstyle == "round" && reverse == true) {
translate([0,0,-height]) cylinder(d=diameter, h=height);
}
if(reverse == true) {
translate([0,0,-supportheight]) cylinder(d=supportsize, h=supportheight);
}
else {
cylinder(d=(supportsize),h=supportheight);
}
if(pillarsupport == "rear" && reverse == true) {
translate([-1,-supportsize/2,-height]) cube([2, supportsize/2, height]);
}
if(pillarsupport == "rear" && reverse == false) {
translate([-1,-supportsize/2,0]) cube([2, supportsize/2, height]);
}
if(pillarsupport == "front" && reverse == true) {
translate([-1,0,-height]) cube([2, supportsize/2, height]);
}
if(pillarsupport == "front" && reverse == false) {
translate([-1,0,0]) cube([2, supportsize/2, height]);
}
if(pillarsupport == "left" && reverse == true) {
translate([-supportsize/2,-1,-height]) cube([supportsize/2, 2, height]);
}
if(pillarsupport == "left" && reverse == false) {
translate([-supportsize/2,-1,0]) cube([supportsize/2, 2, height]);
}
if(pillarsupport == "right" && reverse == true) {
translate([0,-1,-height]) cube([supportsize/2, 2, height]);
}
if(pillarsupport == "right" && reverse == false) {
translate([0,-1,0]) cube([supportsize/2, 2, height]);
}
}
// hole
if(sink == "none" && reverse == false) {
translate([0,0,-adj]) cylinder(d=holesize, h=height+(adj*2));
}
if(sink != "blind" && reverse == false) {
translate([0,0,-adj]) cylinder(d=holesize, h=height+(adj*2));
}
if(sink != "blind" && reverse == true) {
translate([0,0,-adj-height]) cylinder(d=holesize, h=height+(adj*2));
}
// countersink hole
if(sink == "countersunk" && reverse == false) {
translate([0,0,-adj]) cylinder(d1=ps, d2=holesize, h=ds);
}
if(sink == "countersunk" && reverse == true) {
translate([0,0,+adj-ds]) cylinder(d1=holesize, d2=ps, h=ds);
}
// recessed hole
if(sink == "recessed" && reverse == false) {
translate([0,0,-adj]) cylinder(d=6.5, h=supportheight-2);
}
if(sink == "recessed" && reverse == true) {
translate([0,0,+adj-supportheight+2]) cylinder(d=6.5, h=supportheight-2);
}
// nut holder
if(sink == "nut holder" && reverse == false) {
translate([0,0,-adj]) cylinder(d=ps*2/sqrt(3),h=ds,$fn=6);
}
if(sink == "nut holder" && reverse == true) {
translate([0,0,+adj-ds]) cylinder(d=ps*2/sqrt(3),h=ds,$fn=6);
}
// blind hole
if(sink == "blind" && reverse == false) {
translate([0,0,2]) cylinder(d=holesize, h=height);
}
if(sink == "blind" && reverse == true) {
translate([0,0,-height-2-adj]) cylinder(d=holesize, h=height);
}
if(insert_e == true && reverse == false) {
translate([0,0,height-i_depth]) cylinder(d=i_dia, h=i_depth+adj);
}
if(insert_e == true && reverse == true) {
translate([0,0,-height-adj]) cylinder(d=i_dia, h=i_depth+adj);
}
}
}
}

63
lib/vent.scad Normal file
View File

@@ -0,0 +1,63 @@
/*
This file is part of SBC Case Builder https://github.com/hominoids/SBC_Case_Builder
Copyright 2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
vent_panel_hex(x, y, thick, cell_size, cell_spacing, border, borders);
*/
/*
NAME: vent_panel_hex
DESCRIPTION: creates hex vent panel
TODO: none
USAGE: vent_panel_hex(x, y, thick, cell_size=8, cell_spacing=3, border=3, borders="default")
x = #rows
y = #columns
thick = pattern thickness
cell_size = size of hex
cell_spacing = space between hex
border = size of borber
borders = "none", "default"
*/
module vent_panel_hex(x, y, thick, cell_size=8, cell_spacing=3, border=3, borders="default") {
hole = 3.2;
xb = (borders == "y" || borders == "none") ? cell_spacing : border;
yb = (borders == "x" || borders == "none") ? cell_spacing : border;
hxb = max(yb/2, cell_spacing + hole);
hyb = max(xb/2, cell_spacing + hole);
cells_x = floor((2*(x-2*xb-cell_size)/(cell_size+cell_spacing))+1);
cells_y = floor(((sqrt(12)*(y-2*yb)-4*cell_size)/(3*(cell_size+cell_spacing)))+1);
csx = cell_size + (cells_x-1)*(cell_size+cell_spacing)/2;
csy = sqrt(4/3)*cell_size + ((cell_size+cell_spacing)*sqrt(3/4)*(cells_y-1));
difference() {
color("grey",1) slab([x,y,thick],2);
color("grey",1) translate([(x-csx)/2,(y-csy)/2,-1])
vent_hex(cells_x, cells_y, thick+3, cell_size, cell_spacing, "horizontal");
if (borders != "none") {
color("grey",1) translate([ hxb, hyb, -1]) cylinder(d=hole, h=thick+3);
color("grey",1) translate([x - hxb, hyb, -1]) cylinder(d=hole, h=thick+3);
color("grey",1) translate([ hxb, y - hyb, -1]) cylinder(d=hole, h=thick+3);
color("grey",1) translate([x - hxb, y - hyb, -1]) cylinder(d=hole, h=thick+3);
}
}
}

208
mod/add.scad Normal file
View File

@@ -0,0 +1,208 @@
/*
This file is part of SBC Case Builder https://github.com/hominoids/SBC_Case_Builder
Copyright 2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
NAME: add
DESCRIPTION: places additive objects
TODO: none
USAGE: add(type, loc_x, loc_y, loc_z, face, rotation, size[], data[], mask[])
type = component type
loc_x = x location placement
loc_y = y location placement
loc_z = z location placement
face = "top", "bottom", "left", "right", "front", "rear"
rotation[] = object rotation
parametric[] = parametric movement array
size[] = size array x,y,z
data[] = data variable on type
mask[0] = true enables component mask
mask[1] = mask length
mask[2] = mask setback
mask[3] = mstyle "default"
*/
module add(type, loc_x, loc_y, loc_z, face, rotation, size, data, mask) {
size_x = size[0];
size_y = size[1];
size_z = size[2];
enablemask = mask[0];
mlen = mask[1];
msetback = mask[2];
mstyle = mask[3];
if(type == "access_cover") {
if(rotation[2] == 180) {
color("grey",1) translate([loc_x+size_x,loc_y+size_y,loc_z]) rotate(rotation) access_cover([size_x,size_y,size_z],data[0]);
}
else {
color("grey",1) translate([loc_x,loc_y,loc_z]) rotate(rotation) access_cover([size_x,size_y,size_z],data[0]);
}
}
if(type == "access_panel") {
if(rotation[2] == 180) {
translate([loc_x+size_x,loc_y+size_y,loc_z]) rotate(rotation) access_panel([size_x,size_y,size_z],data[0],mask);
}
else {
translate([loc_x,loc_y,loc_z]) rotate(rotation) access_panel([size_x,size_y,size_z],data[0],mask);
}
}
if(type == "art") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) art(data[0],data[1],data[2]);
}
if(type == "batt_holder") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) batt_holder(data[0]);
}
if(type == "button") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) buttons(data[0],[size_x,size_y,size_z],data[1],data[2],mask);
}
if(type == "button_assembly") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) button_assembly(data[0],size_x,size_z);
}
if(type == "fan_cover") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) fan_cover(size_x, size_z, data[0]);
}
if(type == "feet") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) feet(size_x, size_z);
}
if(type == "hd_holder") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hd_mount(data[0],data[1],data[2],data[3]);
}
if(type == "hk_boom_grill") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hk_boom_grill(data[0],size_z);
}
if(type == "hk_boom_speaker_holder") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hk_boom_speaker_holder(data[0],data[1]);
}
if(type == "hk_boom_vring") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hk_boom_vring(data[0]);
}
if(type == "hk_h3_port_extender_holder") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hk_h3_port_extender_holder(data[1],data[0]);
}
if(type == "hk_hc4_oled_holder") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hk_hc4_oled_holder(face, size_z, mask);
}
if(type == "hk_uart_holder") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hk_uart_holder(mask);
}
if(type == "hk_uart_strap") {
color("grey",1) translate([loc_x,loc_y,loc_z]) rotate(rotation) hk_uart_strap();
}
if(type == "keyhole") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) keyhole(data[0],mask);
}
if(type == "nut_holder") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) nut_holder(data[0], data[1], size_x, size_y, size_z, mask);
}
if(type == "pcb_holder") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) pcb_holder([size_x,size_y,size_z],data[0]);
}
if(type == "rectangle") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) slab_r([size_x,size_y,size_z],data[0]);
}
if(type == "round") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) cylinder(d=size_x,h=size_z);
}
if(type == "slot") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) slot(size_x,size_y,size_z);
}
if(type == "sphere") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) sphere(d=size_x);
}
if(type == "standoff") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) standoff(data[0], mask);
}
if(type == "text") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) linear_extrude(height = size_z) text(data[1], size=data[0]);
}
if(type == "vent_panel_hex") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) vent_panel_hex(size_x, size_y, thick=size_z,
cell_size=data[0], cell_spacing=data[1], border=data[3], borders=data[2]);
}
// models
if(type == "adafruit_lcd") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) adafruit_lcd(mask);
}
if(type == "dsub") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) dsub(data[0], data[1], mask);
}
if(type == "fan") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) fans(data[0],mask);
}
if(type == "hd25") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hd25(data[0],data[1],mask);
}
if(type == "hd35") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hd35(data[0],mask);
}
if(type == "hk_boom") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hk_boom(data[0],data[1],mask);
}
if(type == "hk_boom_speaker") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hk_boom_speaker(mask);
}
if(type == "hk_boom_speaker_pcb") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hk_boom_speaker_pcb(data[1],true,data[0],mask);
}
if(type == "hk_h3_port_extender") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hk_h3_port_extender(data[0],mask);
}
if(type == "hk_hc4_oled") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hk_hc4_oled(mask);
}
if(type == "hk_lcd35") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hk_35lcd(mask);
}
if(type == "hk_m1s_ups") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hk_m1s_ups(mask);
}
if(type == "hk_netcard") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hk_netcard(mask);
}
if(type == "hk_pwr_button") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hk_pwr_button(mask);
}
if(type == "hk_speaker") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hk_speaker(mask);
}
if(type == "hk_uart") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hk_uart(mask);
}
if(type == "hk_vu7c") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hk_vu7c(data[0],data[1],mask);
}
if(type == "hk_vu8m") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hk_vu8m(data[0],mask);
}
if(type == "hk_vu8s") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hk_vu8s(mask);
}
if(type == "hk_wb2") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hk_wb2();
}
if(type == "hk_xu4_shifter_shield") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hk_xu4_shifter_shield(mask);
}
if(type == "stl_model") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) stl_model(data[0],data[1]);
}
}

428
mod/case_adapter.scad Normal file
View File

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

778
mod/case_bottom.scad Normal file
View File

@@ -0,0 +1,778 @@
/*
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) {
lip = 5;
vu_rotation = [15,0,0];
case_fn = 360; // circle segments for round cases
case_ffn = 90; // circle segments for fillet of round cases
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=[corner_fillet,corner_fillet,corner_fillet,corner_fillet],
top=[0,0,0,0], bottom=[edge_fillet,edge_fillet,edge_fillet,edge_fillet,edge_fillet], $fn=90);
translate([(width/2)-wallthick-gap,
(depth/2)-wallthick-gap,(bottom_height/2)+floorthick])
cube_fillet_inside([width-(wallthick*2),depth-(wallthick*2),bottom_height],
vertical=[corner_fillet-1,corner_fillet-1,corner_fillet-1,corner_fillet-1],
top=[0,0,0,0], bottom=[edge_fillet,edge_fillet,edge_fillet,edge_fillet,edge_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=[corner_fillet,corner_fillet,corner_fillet,corner_fillet],
top=[0,0,0,0], bottom=[0,0,0,0], $fn=90);
}
if(case_design == "tray" || case_design == "tray_vu5" || case_design == "tray_vu7" || case_design == "tray_sides") {
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=[edge_fillet,edge_fillet,edge_fillet,edge_fillet,edge_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=[corner_fillet-1,corner_fillet-1,corner_fillet-1,corner_fillet-1],
top=[0,0,0,0],bottom=[2,2,2,2], $fn=90);
}
// case nut placement
for (i=[1:11:len(sbc_data[s[0]])-2]) {
class = sbc_data[s[0]][i+1];
type = sbc_data[s[0]][i+2];
id = sbc_data[s[0]][i+3];
pcbhole_x = sbc_data[s[0]][i+4]+pcb_loc_x;
pcbhole_y = sbc_data[s[0]][i+5]+pcb_loc_y;
pcbhole_z = sbc_data[s[0]][i+6];
pcbhole_size = sbc_data[s[0]][i+9][0];
pcbhole_pos = sbc_data[s[0]][i+10][4];
if(class == "pcbhole" && id == pcb_id && pcbhole_pos == "left_rear") {
if((pcbhole_y <= 10 && pcbhole_x <= 10) || (ext_bottom_standoffs == true && ext_bottom_rear_left_enable == true)) {
translate([-adj-gap,wallthick+gap+10,floorthick+3.4]) rotate([90,0,90])
cylinder(d=10, h=4, $fn=6);
}
else {
translate([-adj-gap,wallthick+gap+2,floorthick+3.4]) rotate([90,0,90])
cylinder(d=10, h=4, $fn=6);
}
}
if(class == "pcbhole" && id == pcb_id && pcbhole_pos == "left_front") {
if((pcbhole_y >= pcb_depth+case_offset_y-10 && pcbhole_x <= 10) || (ext_bottom_standoffs == true && ext_bottom_front_left_enable == true)) {
translate([-adj-gap,wallthick-gap+pcb_depth+case_offset_y-14,floorthick+3.4])
rotate([90,0,90]) cylinder(d=10, h=4, $fn=6);
}
else {
translate([-adj-gap,wallthick+gap+pcb_depth+case_offset_y-8,floorthick+3.4])
rotate([90,0,90]) cylinder(d=10, h=4, $fn=6);
}
}
if(class == "pcbhole" && id == pcb_id && pcbhole_pos == "right_rear") {
if((pcbhole_y <= 10 && pcbhole_x >= pcb_width-10) || (ext_bottom_standoffs == true && ext_bottom_rear_right_enable == true)) {
translate([width-wallthick-gap-wallthick-4+adj,wallthick+gap+10,floorthick+3.4])
rotate([90,0,90]) cylinder(d=10, h=4, $fn=6);
}
else {
translate([width-wallthick-gap-wallthick-4+adj,wallthick+gap+2,floorthick+3.4])
rotate([90,0,90]) cylinder(d=10, h=4, $fn=6);
}
}
if(class == "pcbhole" && id == pcb_id && pcbhole_pos == "right_front") {
if((pcbhole_y >= pcb_depth+case_offset_y-10 && pcbhole_x >= width-10) || (ext_bottom_standoffs == true && ext_bottom_front_right_enable == true)) {
translate([width-wallthick-gap-wallthick-4+adj,wallthick-gap+pcb_depth+case_offset_y-14,floorthick+3.4])
rotate([90,0,90]) cylinder(d=10, h=4, $fn=6);
}
else {
translate([width-wallthick-gap-wallthick-4+adj,wallthick+gap+pcb_depth+case_offset_y-8,floorthick+3.4])
rotate([90,0,90]) cylinder(d=10, h=4, $fn=6);
}
}
}
// front panel
if(case_design == "tray_vu5" || case_design == "tray_vu7" || case_design == "tray_sides") {
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=edge_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=edge_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=edge_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=edge_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=edge_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=edge_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=edge_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=edge_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=edge_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=[corner_fillet,corner_fillet,corner_fillet,corner_fillet],
top=[0,0,0,0], bottom=[edge_fillet,edge_fillet,edge_fillet,edge_fillet,edge_fillet], $fn=90);
translate([(width/2)-wallthick-gap,(depth/2)-wallthick-gap,floorthick+(floorthick+case_z)/2])
cube_fillet_inside([width-(wallthick*2),depth-(wallthick*2),case_z+floorthick],
vertical=[corner_fillet-1,corner_fillet-1,corner_fillet-1,corner_fillet-1],
top=[0,0,0,0], bottom=[edge_fillet,edge_fillet,edge_fillet,edge_fillet,edge_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=[corner_fillet,corner_fillet,corner_fillet,corner_fillet],
top=[0,0,0,0], bottom=[edge_fillet,edge_fillet,edge_fillet,edge_fillet,edge_fillet], $fn=90);
translate([(width/2)-wallthick-gap,
(depth/2)-wallthick-gap,(case_z/2)+floorthick])
cube_fillet_inside([width-(wallthick*2),depth-(wallthick*2),case_z],
vertical=[corner_fillet-1,corner_fillet-1,corner_fillet-1,corner_fillet-1],
top=[0,0,0,0], bottom=[edge_fillet,edge_fillet,edge_fillet,edge_fillet,edge_fillet], $fn=90);
difference() {
translate([(width/2)-wallthick-gap,(depth/2)-wallthick-gap,case_z-lip/2])
cube_fillet_inside([width+adj,depth+adj,lip+adj],
vertical=[corner_fillet,corner_fillet,corner_fillet,corner_fillet],
top=[0,0,0,0],bottom=[edge_fillet,edge_fillet,edge_fillet,edge_fillet,edge_fillet], $fn=90);
translate([(width/2)-wallthick-gap,(depth/2)-wallthick-gap,case_z-lip/2])
cube_fillet_inside([width-wallthick,depth-wallthick,lip+adj],
vertical=[corner_fillet-1,corner_fillet-1,corner_fillet-1,corner_fillet-1],top=[0,0,0,0],
bottom=[edge_fillet,edge_fillet,edge_fillet,edge_fillet,edge_fillet], $fn=90);
}
}
}
// additive accessories
if(accessory_name != "none") {
for (i=[1:11:len(accessory_data[a[0]])-1]) {
class = accessory_data[a[0]][i];
type = accessory_data[a[0]][i+1];
loc_x = accessory_data[a[0]][i+2];
loc_y = accessory_data[a[0]][i+3];
loc_z = accessory_data[a[0]][i+4];
face = accessory_data[a[0]][i+5];
rotation = accessory_data[a[0]][i+6];
parametric = accessory_data[a[0]][i+7];
size = accessory_data[a[0]][i+8];
data = accessory_data[a[0]][i+9];
mask = accessory_data[a[0]][i+10];
if(class == "add1" && face == "bottom") {
parametric_move_add(type, loc_x, loc_y, loc_z, face, rotation, parametric, size, data, [false,mask[1],mask[2],mask[3]]);
}
}
}
}
// tray side attachment holes
if(case_design == "tray" || case_design == "tray_vu5" || case_design == "tray_vu7" || case_design == "tray_sides") {
for (i=[1:11:len(sbc_data[s[0]])-2]) {
class = sbc_data[s[0]][i+1];
type = sbc_data[s[0]][i+2];
id = sbc_data[s[0]][i+3];
pcbhole_x = sbc_data[s[0]][i+4]+pcb_loc_x;
pcbhole_y = sbc_data[s[0]][i+5]+pcb_loc_y;
pcbhole_z = sbc_data[s[0]][i+6];
pcbhole_size = sbc_data[s[0]][i+9][0];
pcbhole_pos = sbc_data[s[0]][i+10][4];
if(class == "pcbhole" && id == pcb_id && pcbhole_pos == "left_rear") {
if((pcbhole_y <= 10 && pcbhole_x <= 10) || (ext_bottom_standoffs == true && ext_bottom_rear_left_enable == true)) {
translate([-wallthick-gap-adj-6,wallthick+gap+10,floorthick+3.4]) rotate([0,90,0])
cylinder(d=3, h=10+sidethick+(2*adj));
translate([-gap+.6,wallthick+gap+10,floorthick+3.4]) rotate([90,0,90])
cylinder(d=6.6, h=3.5, $fn=6);
}
else {
translate([-wallthick-gap-adj-6,wallthick+gap+2,floorthick+3.4]) rotate([0,90,0])
cylinder(d=3, h=10+sidethick+(2*adj));
translate([-gap+.6,wallthick+gap+2,floorthick+3.4]) rotate([90,0,90])
cylinder(d=6.6, h=3.5, $fn=6);
}
}
if(class == "pcbhole" && id == pcb_id && pcbhole_pos == "left_front") {
if((pcbhole_y >= pcb_depth+case_offset_y-10 && pcbhole_x <= 10) || (ext_bottom_standoffs == true && ext_bottom_front_left_enable == true)) {
translate([-wallthick-gap-adj-6,wallthick-gap+pcb_depth+case_offset_y-14,
floorthick+3.4]) rotate([0,90,0]) cylinder(d=3, h=10+sidethick+(2*adj));
translate([-gap+.6,wallthick-gap+pcb_depth+case_offset_y-14,floorthick+3.4])
rotate([90,0,90]) cylinder(d=6.6, h=3.5, $fn=6);
}
else {
echo(pcb_depth+case_offset_y-10);
translate([-wallthick-gap-adj-6,wallthick+gap+pcb_depth+case_offset_y-8,
floorthick+3.4]) rotate([0,90,0]) cylinder(d=3, h=10+sidethick+(2*adj));
translate([-gap+.6,wallthick+gap+pcb_depth+case_offset_y-8,floorthick+3.4])
rotate([90,0,90]) cylinder(d=6.6, h=3.5, $fn=6);
}
}
if(class == "pcbhole" && id == pcb_id && pcbhole_pos == "right_rear") {
if((pcbhole_y <= 10 && pcbhole_x >= pcb_width-10) || (ext_bottom_standoffs == true && ext_bottom_rear_right_enable == true)) {
translate([width-2*(wallthick+gap)-sidethick-adj,wallthick+gap+10,floorthick+3.4])
rotate([0,90,0]) cylinder(d=3, h=10+sidethick+(2*adj));
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);
}
else {
translate([width-2*(wallthick+gap)-sidethick-adj,wallthick+gap+2,floorthick+3.4])
rotate([0,90,0]) cylinder(d=3, h=10+sidethick+(2*adj));
translate([width-3.5-(2*wallthick)-gap-.6,wallthick+gap+2,floorthick+3.4])
rotate([90,0,90]) cylinder(d=6.6, h=3.5, $fn=6);
}
}
if(class == "pcbhole" && id == pcb_id && pcbhole_pos == "right_front") {
if((pcbhole_y >= pcb_depth+case_offset_y-10 && pcbhole_x >= width-10) || (ext_bottom_standoffs == true && ext_bottom_front_right_enable == true)) {
translate([width-3*(wallthick+gap)-adj,wallthick-gap+pcb_depth+case_offset_y-14,
floorthick+3.4]) rotate([0,90,0]) cylinder(d=3, h=10+sidethick+(2*adj));
translate([width-3.5-(2*wallthick)-gap-.6,wallthick-gap+pcb_depth+case_offset_y-14,
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+pcb_depth+case_offset_y-8,
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+pcb_depth+case_offset_y-8,
floorthick+3.4])rotate([90,0,90]) cylinder(d=6.6, h=3.5, $fn=6);
}
}
}
}
// pcb standoff holes
if(sbc_bottom_standoffs == true) {
for (i=[1:11:len(sbc_data[s[0]])-2]) {
class = sbc_data[s[0]][i+1];
type = sbc_data[s[0]][i+2];
id = sbc_data[s[0]][i+3];
pcbhole_x = sbc_data[s[0]][i+4]+pcb_loc_x;
pcbhole_y = sbc_data[s[0]][i+5]+pcb_loc_y;
pcbhole_z = sbc_data[s[0]][i+6];
pcbhole_size = sbc_data[s[0]][i+9][0];
pcbhole_pos = sbc_data[s[0]][i+10][4];
if (class == "pcbhole" && id == pcb_id && pcbhole_pos == "left_rear" &&
bottom_rear_left_enable == true && bottom_standoff[6] != "blind") {
translate([pcbhole_x,pcbhole_y,-1]) cylinder(d=bottom_standoff[4]-.2, h=bottom_height);
}
if (class == "pcbhole" && id == pcb_id && pcbhole_pos == "left_front" &&
bottom_front_left_enable == true && bottom_standoff[6] != "blind") {
translate([pcbhole_x,pcbhole_y,-1]) cylinder(d=bottom_standoff[4]-.2, h=bottom_height);
}
if (class == "pcbhole" && id == pcb_id && pcbhole_pos == "right_rear" &&
bottom_rear_right_enable == true && bottom_standoff[6] != "blind") {
translate([pcbhole_x,pcbhole_y,-1]) cylinder(d=bottom_standoff[4]-.2, h=bottom_height);
}
if (class == "pcbhole" && id == pcb_id && pcbhole_pos == "right_front" &&
bottom_front_right_enable == true && bottom_standoff[6] != "blind") {
translate([pcbhole_x,pcbhole_y,-1]) cylinder(d=bottom_standoff[4]-.2, h=bottom_height);
}
}
}
// extended standoff holes
if(ext_bottom_standoffs == true) {
// right-rear standoff
if(((width-pcb_loc_x-pcb_width-(gap+2*wallthick) >= 10 || pcb_loc_y >= 10)) &&
ext_bottom_rear_right_enable == true && ext_bottom_standoff[6] != "blind") {
translate([width-ext_bottom_standoff_support_size/4-(2*(wallthick+gap))-(corner_fillet/2),
(corner_fillet/2)+ext_bottom_standoff_support_size/4,-1]) cylinder(d=ext_bottom_standoff[4]-.2, h=bottom_height);
}
// right-front standoff
if(((width-pcb_loc_x-pcb_width-(gap+2*wallthick) >= 10 && depth-pcb_loc_y-pcb_depth >= 10) ||
(width-pcb_loc_x-pcb_width-(gap+2*wallthick) >= 10 && depth-pcb_loc_y-pcb_depth <= 10) ||
(width-pcb_loc_x-pcb_width-(gap+2*wallthick) <= 10 && depth-pcb_loc_y-pcb_depth >= 10)) &&
ext_bottom_front_right_enable == true && ext_bottom_standoff[6] != "blind") {
translate([width-ext_bottom_standoff_support_size/4-(corner_fillet/2)-(2*(wallthick+gap)),
depth-ext_bottom_standoff_support_size/4-(corner_fillet/2)-(2*(wallthick+gap)),-1])
cylinder(d=ext_bottom_standoff[4]-.2, h=bottom_height);
}
// left-rear standoff
if((pcb_loc_x >= 10 || pcb_loc_y >= 10) && ext_bottom_rear_left_enable == true && ext_bottom_standoff[6] != "blind") {
translate([(corner_fillet/2)+ext_bottom_standoff_support_size/4,
(corner_fillet/2)+ext_bottom_standoff_support_size/4,-1]) cylinder(d=ext_bottom_standoff[4]-.2, h=bottom_height);
}
// left-front standoff
if(((pcb_loc_x >= 10 && (depth-(pcb_loc_y+pcb_depth)) >= 10) ||
(pcb_loc_x <= 10 && (depth-(pcb_loc_y+pcb_depth)) >= 10) ||
(pcb_loc_x >= 10 && (depth-(pcb_loc_y+pcb_depth)) <= 10)) &&
ext_bottom_front_left_enable == true && ext_bottom_standoff[6] != "blind") {
translate([(corner_fillet/2)+ext_bottom_standoff_support_size/4,
depth-ext_bottom_standoff_support_size/4-(corner_fillet/2)-(2*(wallthick+gap)),-1])
cylinder(d=ext_bottom_standoff[4]-.2, h=bottom_height);
}
}
// bottom cover pattern
if(bottom_cover_pattern != "solid") {
if(bottom_cover_pattern == "hex_5mm") {
translate([1,0,-2]) vent_hex((width)/3.75,(depth)/6,floorthick+4,5,1.5,"horizontal");
}
if(bottom_cover_pattern == "hex_8mm") {
translate([1,2,-2]) vent_hex((width)/5.5,(depth)/9.5,floorthick+4,8,1.5,"horizontal");
}
if(bottom_cover_pattern == "linear_vertical") {
translate([0,-gap,-2]) vent(wallthick,depth-2*wallthick-gap,floorthick+4,1,1,(width-2*wallthick-gap)/4,"horizontal");
}
if(bottom_cover_pattern == "linear_horizontal") {
translate([-gap,-gap,-2]) vent(width-2*wallthick-gap,wallthick,floorthick+4,1,(depth-2*wallthick-gap)/3,1,"horizontal");
}
if(bottom_cover_pattern == "astroid") {
for(c=[3:12:depth-8]) {
for(r=[4:12:width-8]) {
translate([r,c,-4]) linear_extrude(floorthick+5) import("./dxf/astroid_8mm.dxf");
}
}
}
}
// rear io shield opening for standard form motherboards
if(rear_io_shield == true) {
if(sbc_model == "mini-stx_thin") {
translate([6.2+pcb_loc_x,-4.5,-4.65+bottom_height-pcb_z+pcb_loc_z]) cube([123.95, 10+pcb_loc_y, 25]);
}
if(sbc_model == "mini-stx") {
translate([6.2+pcb_loc_x,-4.5,-4.65+bottom_height-pcb_z+pcb_loc_z]) cube([123.95, 10+pcb_loc_y, 40]);
}
if(sbc_model == "mini-itx_thin") {
translate([-2.62+pcb_loc_x,-4.5,-2.25+bottom_height-pcb_z+pcb_loc_z]) cube([158.75, 10+pcb_loc_y, 25]);
}
if(sbc_model != "mini-stx_thin" && sbc_model != "mini-stx" && sbc_model != "mini-itx_thin") {
translate([-2.62+pcb_loc_x,-4.5,-2.25+bottom_height-pcb_z+pcb_loc_z]) cube([158.75, 10+pcb_loc_y, 44]);
}
}
}
// pcb standoffs
if(sbc_bottom_standoffs == true) {
for (i=[1:11:len(sbc_data[s[0]])-2]) {
class = sbc_data[s[0]][i+1];
type = sbc_data[s[0]][i+2];
id = sbc_data[s[0]][i+3];
pcbhole_x = sbc_data[s[0]][i+4]+pcb_loc_x;
pcbhole_y = sbc_data[s[0]][i+5]+pcb_loc_y;
pcbhole_z = sbc_data[s[0]][i+6];
pcbhole_size = sbc_data[s[0]][i+9][0];
pcbhole_pos = sbc_data[s[0]][i+10][4];
if(class == "pcbhole" && id == pcb_id &&
(pcbhole_pos == "left_rear" || pcbhole_pos == "left_front" || pcbhole_pos == "right_rear" || pcbhole_pos == "right_front")) {
if (pcbhole_pos == "left_rear" && bottom_rear_left_enable == true) {
bottom_support = bottom_sidewall_support == true ? bottom_rear_left_support : "none";
pcb_standoff = [bottom_standoff[0],
bottom_standoff[1],
bottom_height-pcb_z+pcb_loc_z+bottom_rear_left_adjust,
bottom_standoff[3],
bottom_standoff[4],
bottom_standoff[5],
bottom_standoff[6],
bottom_standoff[7],
bottom_support,
bottom_standoff[9],
bottom_standoff[10],
bottom_standoff[11],
bottom_standoff[12]];
translate([pcbhole_x,pcbhole_y,0]) standoff(pcb_standoff,[false,10,2,"default"]);
}
if (pcbhole_pos == "left_front" && bottom_front_left_enable == true) {
bottom_support = bottom_sidewall_support == true ? bottom_front_left_support : "none";
pcb_standoff = [bottom_standoff[0],
bottom_standoff[1],
bottom_height-pcb_z+pcb_loc_z+bottom_front_left_adjust,
bottom_standoff[3],
bottom_standoff[4],
bottom_standoff[5],
bottom_standoff[6],
bottom_standoff[7],
bottom_support,
bottom_standoff[9],
bottom_standoff[10],
bottom_standoff[11],
bottom_standoff[12]];
translate([pcbhole_x,pcbhole_y,0]) standoff(pcb_standoff,[false,10,2,"default"]);
}
if (pcbhole_pos == "right_rear" && bottom_rear_right_enable == true) {
bottom_support = bottom_sidewall_support == true ? bottom_rear_right_support : "none";
pcb_standoff = [bottom_standoff[0],
bottom_standoff[1],
bottom_height-pcb_z+pcb_loc_z+bottom_rear_right_adjust,
bottom_standoff[3],
bottom_standoff[4],
bottom_standoff[5],
bottom_standoff[6],
bottom_standoff[7],
bottom_support,
bottom_standoff[9],
bottom_standoff[10],
bottom_standoff[11],
bottom_standoff[12]];
translate([pcbhole_x,pcbhole_y,0]) standoff(pcb_standoff,[false,10,2,"default"]);
}
if (pcbhole_pos == "right_front" && bottom_front_right_enable == true) {
bottom_support = bottom_sidewall_support == true ? bottom_front_right_support : "none";
pcb_standoff = [bottom_standoff[0],
bottom_standoff[1],
bottom_height-pcb_z+pcb_loc_z+bottom_front_right_adjust,
bottom_standoff[3],
bottom_standoff[4],
bottom_standoff[5],
bottom_standoff[6],
bottom_standoff[7],
bottom_support,
bottom_standoff[9],
bottom_standoff[10],
bottom_standoff[11],
bottom_standoff[12]];
translate([pcbhole_x,pcbhole_y,0]) standoff(pcb_standoff,[false,10,2,"default"]);
}
}
}
}
// extended standoffs
if(ext_bottom_standoffs == true) {
// extended right-rear standoff
if((width-pcb_loc_x-pcb_width-(gap+2*wallthick) >= 10 || pcb_loc_y >= 10) && ext_bottom_rear_right_enable == true) {
extended_standoff = [ext_bottom_standoff[0],
ext_bottom_standoff[1],
bottom_height+ext_bottom_rear_right_adjust,
ext_bottom_standoff[3],
ext_bottom_standoff[4],
ext_bottom_standoff[5],
ext_bottom_standoff[6],
ext_bottom_standoff[7],
ext_bottom_rear_right_support,
ext_bottom_standoff[9],
ext_bottom_standoff[10],
ext_bottom_standoff[11],
ext_bottom_standoff[12]];
translate([width-ext_top_standoff_support_size/4-(2*(wallthick+gap))-(corner_fillet/2),
(corner_fillet/2)+ext_top_standoff_support_size/4,0]) standoff(extended_standoff,[false,10,2,"default"]);
}
// extended right-front standoff
if(((width-pcb_loc_x-pcb_width-(gap+2*wallthick) >= 10 && depth-pcb_loc_y-pcb_depth >= 10) ||
(width-pcb_loc_x-pcb_width-(gap+2*wallthick) >= 10 && depth-pcb_loc_y-pcb_depth <= 10) ||
(width-pcb_loc_x-pcb_width-(gap+2*wallthick) <= 10 && depth-pcb_loc_y-pcb_depth >= 10)) &&
ext_bottom_front_right_enable == true) {
extended_standoff = [ext_bottom_standoff[0],
ext_bottom_standoff[1],
bottom_height+ext_bottom_front_right_adjust,
ext_bottom_standoff[3],
ext_bottom_standoff[4],
ext_bottom_standoff[5],
ext_bottom_standoff[6],
ext_bottom_standoff[7],
ext_bottom_front_right_support,
ext_bottom_standoff[9],
ext_bottom_standoff[10],
ext_bottom_standoff[11],
ext_bottom_standoff[12]];
translate([width-ext_top_standoff_support_size/4-(corner_fillet/2)-(2*(wallthick+gap)),
depth-ext_top_standoff_support_size/4-(corner_fillet/2)-(2*(wallthick+gap)),0]) standoff(extended_standoff,[false,10,2,"default"]);
}
// extended left-rear standoff
if((pcb_loc_x >= 10 || pcb_loc_y >= 10) && ext_bottom_rear_left_enable == true) {
extended_standoff = [ext_bottom_standoff[0],
ext_bottom_standoff[1],
bottom_height+ext_bottom_rear_left_adjust,
ext_bottom_standoff[3],
ext_bottom_standoff[4],
ext_bottom_standoff[5],
ext_bottom_standoff[6],
ext_bottom_standoff[7],
ext_bottom_rear_left_support,
ext_bottom_standoff[9],
ext_bottom_standoff[10],
ext_bottom_standoff[11],
ext_bottom_standoff[12]];
translate([(corner_fillet/2)+ext_top_standoff_support_size/4,
(corner_fillet/2)+ext_top_standoff_support_size/4,0]) standoff(extended_standoff,[false,10,2,"default"]);
}
// extended left-front standoff
if(((pcb_loc_x >= 10 && depth-(pcb_loc_y+pcb_depth) >= 10) ||
(pcb_loc_x <= 10 && depth-(pcb_loc_y+pcb_depth) >= 10) ||
(pcb_loc_x >= 10 && depth-(pcb_loc_y+pcb_depth) <= 10)) &&
ext_bottom_front_left_enable == true) {
extended_standoff = [ext_bottom_standoff[0],
ext_bottom_standoff[1],
bottom_height+ext_bottom_front_left_adjust,
ext_bottom_standoff[3],
ext_bottom_standoff[4],
ext_bottom_standoff[5],
ext_bottom_standoff[6],
ext_bottom_standoff[7],
ext_bottom_front_left_support,
ext_bottom_standoff[9],
ext_bottom_standoff[10],
ext_bottom_standoff[11],
ext_bottom_standoff[12]];
translate([(corner_fillet/2)+ext_top_standoff_support_size/4,
depth-ext_top_standoff_support_size/4-(corner_fillet/2)-(2*(wallthick+gap)),0])
standoff(extended_standoff,[false,10,2,"default"]);
}
}
}
// subtractive accessories
if(accessory_name != "none") {
for (i=[1:11:len(accessory_data[a[0]])-1]) {
class = accessory_data[a[0]][i];
type = accessory_data[a[0]][i+1];
loc_x = accessory_data[a[0]][i+2];
loc_y = accessory_data[a[0]][i+3];
loc_z = accessory_data[a[0]][i+4];
face = accessory_data[a[0]][i+5];
rotation = accessory_data[a[0]][i+6];
parametric = accessory_data[a[0]][i+7];
size_x = accessory_data[a[0]][i+8][0];
size_y = accessory_data[a[0]][i+8][1];
size_z = accessory_data[a[0]][i+8][2];
data = accessory_data[a[0]][i+9];
mask = accessory_data[a[0]][i+10];
if ((class == "sub" && face == "bottom") || class == "suball") {
if(accessory_highlight == false) {
parametric_move_sub(type, loc_x, loc_y, loc_z, face, rotation, parametric,
[size_x,size_y,size_z],data, mask);
}
else {
#parametric_move_sub(type,loc_x,loc_y,loc_z,face,rotation,parametric,
[size_x,size_y,size_z],data, mask);
}
}
// create openings for additive
if ((class == "add1" || class == "add2" || class == "model") && mask[0] == true) {
if(accessory_highlight == false) {
parametric_move_add(type,loc_x,loc_y,loc_z,face,rotation,parametric,[size_x,size_y,size_z],data,[true,mask[1],mask[2],mask[3]]);
}
else {
#parametric_move_add(type,loc_x,loc_y,loc_z,face,rotation,parametric,[size_x,size_y,size_z],data,[true,mask[1],mask[2],mask[3]]);
}
}
}
}
// ui access panel
if(bottom_access_panel_enable == true) {
if(access_panel_rotation == 0) {
translate([access_panel_location[0],access_panel_location[1], 0]) rotate([0,0,access_panel_rotation])
access_panel([access_panel_size[0],access_panel_size[1],floorthick], access_panel_orientation, [true,10,2,"default"]);
}
if(access_panel_rotation == 90) {
translate([access_panel_location[0]+access_panel_size[1],access_panel_location[1], 0]) rotate([0,0,access_panel_rotation])
access_panel([access_panel_size[0],access_panel_size[1],floorthick], access_panel_orientation, [true,10,2,"default"]);
}
if(access_panel_rotation == 180) {
translate([access_panel_location[0]+access_panel_size[0],access_panel_location[1]+access_panel_size[1],0]) rotate([0,0,access_panel_rotation])
access_panel([access_panel_size[0],access_panel_size[1],floorthick], access_panel_orientation, [true,10,2,"default"]);
}
if(access_panel_rotation == 270) {
translate([access_panel_location[0],access_panel_location[1]+access_panel_size[0], 0]) rotate([0,0,access_panel_rotation])
access_panel([access_panel_size[0],access_panel_size[1],floorthick], access_panel_orientation, [true,10,2,"default"]);
}
}
// 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);
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=[corner_fillet,corner_fillet,corner_fillet,corner_fillet], top=[0,0,0,0],
bottom=[edge_fillet,edge_fillet,edge_fillet,edge_fillet,edge_fillet], $fn=90);
}
}
// additive accessories
if(accessory_name != "none") {
for (i=[1:11:len(accessory_data[a[0]])-1]) {
class = accessory_data[a[0]][i];
type = accessory_data[a[0]][i+1];
loc_x = accessory_data[a[0]][i+2];
loc_y = accessory_data[a[0]][i+3];
loc_z = accessory_data[a[0]][i+4];
face = accessory_data[a[0]][i+5];
rotation = accessory_data[a[0]][i+6];
parametric = accessory_data[a[0]][i+7];
size = accessory_data[a[0]][i+8];
data = accessory_data[a[0]][i+9];
mask = accessory_data[a[0]][i+10];
if(class == "add2" && face == "bottom") {
parametric_move_add(type, loc_x, loc_y, loc_z, face, rotation, parametric, size, data, [false,mask[1],mask[2],mask[3]]);
}
}
}
// ui access port
if(bottom_access_panel_enable == true) {
if(access_panel_rotation == 0) {
translate([access_panel_location[0],access_panel_location[1], 0]) rotate([0,0,access_panel_rotation])
access_panel([access_panel_size[0],access_panel_size[1],floorthick], access_panel_orientation, [false,10,2,"default"]);
}
if(access_panel_rotation == 90) {
translate([access_panel_location[0]+access_panel_size[1],access_panel_location[1], 0]) rotate([0,0,access_panel_rotation])
access_panel([access_panel_size[0],access_panel_size[1],floorthick], access_panel_orientation, [false,10,2,"default"]);
}
if(access_panel_rotation == 180) {
translate([access_panel_location[0]+access_panel_size[0],access_panel_location[1]+access_panel_size[1],0]) rotate([0,0,access_panel_rotation])
access_panel([access_panel_size[0],access_panel_size[1],floorthick], access_panel_orientation, [false,10,2,"default"]);
}
if(access_panel_rotation == 270) {
translate([access_panel_location[0],access_panel_location[1]+access_panel_size[0], 0]) rotate([0,0,access_panel_rotation])
access_panel([access_panel_size[0],access_panel_size[1],floorthick], access_panel_orientation, [false,10,2,"default"]);
}
}
}

292
mod/case_folded.scad Normal file
View File

@@ -0,0 +1,292 @@
/*
This file is part of SBC Case Builder https://github.com/hominoids/SBC_Case_Builder
Copyright 2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
NAME: case_folded
DESCRIPTION: creates folded case flat blanks for supported designs
TODO: none
USAGE: case_folded(case_design)
case_design = paper_full-top, paper_split-top
*/
module case_folded(case_design) {
section_position = 2;
ba = bend_allowance;
slit_len = pcb_depth < pcb_width ? pcb_depth/10 : pcb_width/10;
slit_width = material_thickness;
slit_offset = pcb_depth < pcb_width ? pcb_depth/10 : pcb_width/10;
fold_height = pcb_tmaxz+bottom_clearence+pcb_z+ba;
flap_y = 12;
tab_x = pcb_depth/4;
tab_y = fold_height/2;
tab_inset = 6;
if(case_design == "paper_split-top") {
// rear
difference() {
union() {
folded_base(fold_height, ba, flap_y, tab_x, tab_y, tab_inset, slit_len, slit_width, slit_offset);
translate([0, -fold_height-(pcb_depth/2)-ba, 0])
cube([pcb_width, (pcb_depth/2)+ba, material_thickness]);
translate([0, pcb_depth+fold_height, 0])
cube([pcb_width, (pcb_depth/2)+ba, material_thickness]);
// flaps rear left
translate([-tab_y, -fold_height+tab_inset-(pcb_depth/2), 0])
slab_r([tab_y, tab_x, material_thickness], [tab_x/2,tab_x/2,.1,.1]);
// flaps rear right
translate([pcb_width, -fold_height-(pcb_depth/2)+tab_inset, 0])
slab_r([tab_y, tab_x, material_thickness], [.1,.1,tab_x/2,tab_x/2]);
// flaps front left
translate([-tab_y, pcb_depth+fold_height-tab_inset+tab_x, 0])
slab_r([tab_y, tab_x, material_thickness], [tab_x/2,tab_x/2,.1,.1]);
// flaps front right
translate([pcb_width, pcb_depth+fold_height-tab_inset+tab_x, 0])
slab_r([tab_y, tab_x, material_thickness], [.1,.1,tab_x/2,tab_x/2]);
// flaps left rear
difference() {
translate([-(fold_height), 0, 0])
linear_extrude(material_thickness) polygon([[0, 0],
[1, (-pcb_depth/4)],
[(fold_height)-2, (-pcb_depth/4)],
[(fold_height), 0],
[0, 0]]);
translate([-bottom_clearence, 0, section_position]) rotate([90, 0, 270])
sbc(sbc_model, "disable", 0, gpio_opening, uart_opening, true);
}
// flaps left front
difference() {
translate([-(fold_height), pcb_depth, 0])
linear_extrude(material_thickness) polygon([[0, 0],
[1, (pcb_depth/4)],
[(fold_height)-2, (pcb_depth/4)],
[(fold_height), 0],
[0, 0]]);
translate([-bottom_clearence, pcb_depth, pcb_depth+section_position]) rotate([-90, 0, 90])
sbc(sbc_model, "disable", 0, gpio_opening, uart_opening, true);
}
// flaps right rear
difference() {
translate([pcb_width, 0, 0])
linear_extrude(material_thickness) polygon([[0, 0],
[2, (-pcb_depth/4)],
[(fold_height)-1, (-pcb_depth/4)],
[(fold_height), 0],
[0, 0]]);
translate([bottom_clearence+pcb_width, -pcb_width, section_position]) rotate([90, 0, 90])
sbc(sbc_model, "disable", 0, gpio_opening, uart_opening, true);
}
// flaps right front
difference() {
translate([pcb_width, pcb_depth, 0])
linear_extrude(material_thickness) polygon([[0, 0],
[2, (pcb_depth/4)],
[(fold_height)-1, (pcb_depth/4)],
[(fold_height), 0],
[0, 0]]);
translate([bottom_clearence+pcb_width, pcb_width+pcb_depth, section_position+pcb_depth])
rotate([270, 0, 270]) sbc(sbc_model, "disable", 0, gpio_opening, uart_opening, true);
}
}
translate([0, -fold_height, pcb_tmaxz+2+material_thickness]) rotate([180, 0, 0])
sbc(sbc_model, cooling, 0, "disable", "disable", true);
translate([0, 2*pcb_depth+fold_height, pcb_tmaxz+2+material_thickness]) rotate([180, 0, 0])
sbc(sbc_model, cooling, 0, "disable", "disable", true);
}
translate([0, -fold_height-(pcb_depth/2)-ba, 0]) cube([pcb_width, 2, material_thickness]);
translate([0, pcb_depth+fold_height+(pcb_depth/2)-ba, 0]) cube([pcb_width, 2, material_thickness]);
}
if(case_design == "paper_full-top") {
// rear
difference() {
union() {
folded_base(fold_height, ba, flap_y, tab_x, tab_y, tab_inset, slit_len, slit_width, slit_offset);
translate([0, -fold_height-pcb_depth-ba, 0])
cube([pcb_width, pcb_depth+ba, material_thickness]);
translate([0, pcb_depth+fold_height, 0])
cube([pcb_width, (pcb_depth/4)+ba, material_thickness]);
// flaps rear left
translate([tab_inset, -fold_height-pcb_depth-tab_y, 0])
slab_r([tab_x, tab_y, material_thickness], [tab_x/2,.1,.1,tab_x/2]);
// flaps rear right
translate([pcb_width-tab_x-tab_inset, -fold_height-pcb_depth-tab_y, 0])
slab_r([tab_x, tab_y, material_thickness], [tab_x/2,.1,.1,tab_x/2]);
// flaps left rear
difference() {
translate([-(fold_height), 0, 0])
linear_extrude(material_thickness) polygon([[0, 0],
[1, (-pcb_depth/4)],
[(fold_height)-2, (-pcb_depth/4)],
[(fold_height), 0],
[0, 0]]);
translate([-bottom_clearence, 0, section_position]) rotate([90, 0, 270])
sbc(sbc_model, "disable", 0, gpio_opening, uart_opening, true);
}
// flaps left front
difference() {
translate([-(fold_height), pcb_depth, 0])
linear_extrude(material_thickness) polygon([[0, 0],
[1, (pcb_depth/4)],
[(fold_height)-2, (pcb_depth/4)],
[(fold_height), 0],
[0, 0]]);
translate([-bottom_clearence, pcb_depth, pcb_depth+section_position]) rotate([-90, 0, 90])
sbc(sbc_model, "disable", 0, gpio_opening, uart_opening, true);
}
// flaps right rear
difference() {
translate([pcb_width, 0, 0])
linear_extrude(material_thickness) polygon([[0, 0],
[2, (-pcb_depth/4)],
[(fold_height)-1, (-pcb_depth/4)],
[(fold_height), 0],
[0, 0]]);
translate([bottom_clearence+pcb_width, -pcb_width, section_position]) rotate([90, 0, 90])
sbc(sbc_model, "disable", 0, gpio_opening, uart_opening, true);
}
// flaps right front
difference() {
translate([pcb_width, pcb_depth, 0])
linear_extrude(material_thickness) polygon([[0, 0],
[2, (pcb_depth/4)],
[(fold_height)-1, (pcb_depth/4)],
[(fold_height), 0],
[0, 0]]);
translate([bottom_clearence+pcb_width, pcb_width+pcb_depth, section_position+pcb_depth])
rotate([270, 0, 270]) sbc(sbc_model, "disable", 0, gpio_opening, uart_opening, true);
}
}
// top closure tab slits
translate([tab_inset, pcb_depth+fold_height, 0]) cube([tab_x, slit_width, material_thickness+(2*adj)]);
translate([pcb_width-tab_x-tab_inset, pcb_depth+fold_height, 0])
cube([tab_x, slit_width, material_thickness+2*adj]);
translate([0, -fold_height, pcb_tmaxz+2+material_thickness]) rotate([180, 0, 0])
sbc(sbc_model, cooling, 0, "disable", "disable", true);
translate([0, 2*pcb_depth+fold_height, pcb_tmaxz+2+material_thickness]) rotate([180, 0, 0])
sbc(sbc_model, cooling, 0, "disable", "disable", true);
}
}
}
// base folding case
module folded_base(fold_height, ba, flap_y, tab_x, tab_y, tab_inset, slit_len, slit_width, slit_offset) {
section_position = 2;
// rear
difference() {
translate([0, -fold_height, 0]) cube([pcb_width, fold_height, material_thickness]);
// folding slits
translate([slit_offset, -fold_height, -adj])
cube([slit_len, slit_width, material_thickness+(2*adj)]);
translate([pcb_width/2-slit_len/2, -fold_height, -adj])
cube([slit_len, slit_width, material_thickness+(2*adj)]);
translate([pcb_width-slit_offset-slit_len, -fold_height, -adj])
cube([slit_len, slit_width, material_thickness+(2*adj)]);
translate([0, -bottom_clearence, section_position]) rotate([90, 0, 0])
sbc(sbc_model, "disable", 0, gpio_opening, uart_opening, true);
}
// left side
difference() {
union() {
translate([-fold_height, 0, 0])
cube([fold_height, pcb_depth, material_thickness]);
translate([-fold_height-flap_y, 0, 0]) cube([flap_y, pcb_depth, material_thickness]);
}
// folding slits
translate([-fold_height, (pcb_depth/2)+tab_inset, -adj])
cube([slit_width, tab_x, material_thickness+(2*adj)]);
translate([-fold_height, (pcb_depth/2)-tab_x-tab_inset, -adj])
cube([slit_width, tab_x, material_thickness+(2*adj)]);
translate([-bottom_clearence, 0, section_position]) rotate([0, -90, 0])
sbc(sbc_model, "disable", 0, gpio_opening, uart_opening, true);
}
// front
difference() {
translate([0, pcb_depth, 0]) cube([pcb_width, fold_height, material_thickness]);
// folding slits
translate([slit_offset, pcb_depth+fold_height-slit_width, -adj])
cube([slit_len, slit_width, material_thickness+(2*adj)]);
translate([pcb_width/2-slit_len/2, pcb_depth+fold_height-slit_width, -adj])
cube([slit_len, slit_width, material_thickness+(2*adj)]);
translate([pcb_width-slit_offset-slit_len, pcb_depth+fold_height-slit_width, -adj])
cube([slit_len, slit_width, material_thickness+(2*adj)]);
translate([0, pcb_depth+bottom_clearence, pcb_depth+section_position]) rotate([-90, 0, 0])
sbc(sbc_model, "disable", 0, gpio_opening, uart_opening, true);
}
// right side
difference() {
union() {
translate([pcb_width, 0, 0]) cube([fold_height, pcb_depth, material_thickness]);
translate([pcb_width+fold_height, 0, 0])
cube([flap_y, pcb_depth, material_thickness]);
}
// folding slits
translate([pcb_width+fold_height, (pcb_depth/2)+tab_inset, -adj])
cube([slit_width, tab_x, material_thickness+(2*adj)]);
translate([pcb_width+fold_height, (pcb_depth/2)-tab_x-tab_inset, -adj])
cube([slit_width, tab_x, material_thickness+(2*adj)]);
translate([pcb_width+bottom_clearence, 0, pcb_width+section_position]) rotate([0, 90, 0])
sbc(sbc_model, "disable", 0, gpio_opening, uart_opening, true);
}
// pcb section
difference() {
cube([pcb_width, pcb_depth, material_thickness]);
translate([0, 0, 1+material_thickness]) sbc(sbc_model, "disable", 0, gpio_opening, uart_opening, true);
// pcb folding slits rear
translate([slit_offset, 0, -adj]) cube([slit_len, slit_width, material_thickness+(2*adj)]);
translate([pcb_width/2-slit_len/2, 0, -adj]) cube([slit_len, slit_width, material_thickness+(2*adj)]);
translate([pcb_width-slit_offset-slit_len, 0, -adj]) cube([slit_len, slit_width, material_thickness+(2*adj)]);
// pcb folding slits left
translate([0, slit_offset, -adj]) cube([slit_width, slit_len, material_thickness+(2*adj)]);
translate([0, pcb_depth/2-slit_len/2, -adj]) cube([slit_width, slit_len, material_thickness+(2*adj)]);
translate([0, pcb_depth-slit_offset-slit_len, -adj]) cube([slit_width, slit_len, material_thickness+(2*adj)]);
// pcb folding slits front
translate([slit_offset, pcb_depth-slit_width, -adj]) cube([slit_len, slit_width, material_thickness+(2*adj)]);
translate([pcb_width/2-slit_len/2, pcb_depth-slit_width, -adj]) cube([slit_len, slit_width, material_thickness+(2*adj)]);
translate([pcb_width-slit_offset-slit_len, pcb_depth-slit_width, -adj]) cube([slit_len, slit_width, material_thickness+(2*adj)]);
// pcb folding slits right
translate([pcb_width-slit_width, slit_offset, -adj]) cube([slit_width, slit_len, material_thickness+(2*adj)]);
translate([pcb_width-slit_width, pcb_depth/2-slit_len/2, -adj]) cube([slit_width, slit_len, material_thickness+(2*adj)]);
translate([pcb_width-slit_width, pcb_depth-slit_offset-slit_len, -adj]) cube([slit_width, slit_len, material_thickness+(2*adj)]);
}
}

303
mod/case_side.scad Normal file
View File

@@ -0,0 +1,303 @@
/*
This file is part of SBC Case Builder https://github.com/hominoids/SBC_Case_Builder
Copyright 2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
NAME: case_side
DESCRIPTION: creates case side for supported designs and styles
TODO: none
USAGE: case_side(case_design, side)
*/
module case_side(case_design, side) {
difference() {
union() {
if(case_design == "panel") {
if(side == "rear") {
difference() {
union() {
translate([-gap,-wallthick-gap,-floorthick])
cube([width-2*wallthick,wallthick,case_z+2*floorthick]);
// right hook
difference() {
translate([width-(2*wallthick)-gap-adj,-wallthick-gap,
((case_z)/2)-4])
cube([(2*wallthick)+.5,wallthick,8]);
translate([width-(2*wallthick)-gap-adj,-wallthick-gap-adj,
((case_z)/2)-4-adj])
cube([wallthick+.25,wallthick+(2*adj),4.25]);
}
// left hook
difference() {
translate([-(2*wallthick)-gap-adj-.25,-wallthick-gap,
((case_z)/2)-4])
cube([(2*wallthick)+.5,wallthick,8]);
translate([-wallthick-gap-adj-.25,-wallthick-gap-adj,
((case_z)/2)-4-adj])
cube([wallthick+.25,wallthick+(2*adj),4.25]);
}
}
// top slots
translate([(width*(1/5))-8.25-(wallthick+gap),-wallthick-gap-adj,
case_z-floorthick-.25])
cube([8.5,wallthick+2*adj,floorthick+.5]);
translate([width-(width*(1/5))-(wallthick+gap)-.25,-wallthick-gap-adj,
case_z-floorthick-.25])
cube([8.5,wallthick+2*adj,floorthick+.5]);
// bottom slots
translate([(width*(1/5))-8.25-(wallthick+gap),-wallthick-gap-adj,-.25])
cube([8.5,wallthick+2*adj,floorthick+.5]);
translate([width-(width*(1/5))-(wallthick+gap)-.25,-wallthick-gap-adj,-.25])
cube([8.5,wallthick+2*adj,floorthick+.5]);
}
}
if(side == "front") {
difference() {
union() {
translate([-gap,depth-2*(wallthick)-gap,-floorthick])
cube([width-2*wallthick,wallthick,case_z+2*floorthick]);
// right hook
difference() {
translate([width-(2*wallthick)-gap-adj,depth-2*(wallthick)-gap-adj,
((case_z)/2)-4])
cube([(2*wallthick)+.5,wallthick,8]);
translate([width-(2*wallthick)-gap-adj,
depth-2*(wallthick)-adj-gap-adj,((case_z)/2)-4-adj])
cube([wallthick+.25,wallthick+(2*adj),4.25]);
}
// left hook
difference() {
translate([-(2*wallthick)-gap-adj-.25,depth-2*(wallthick)-gap-adj,(
(case_z)/2)-4])
cube([(2*wallthick)+.5,wallthick,8]);
translate([-wallthick-gap-adj-.25,depth-2*(wallthick)-adj-gap-adj,
((case_z)/2)-4-adj])
cube([wallthick+.25,wallthick+(2*adj),4.25]);
}
}
// top slots
translate([(width*(1/5))-8.25-(wallthick+gap),depth-2*wallthick-gap-adj,
case_z-floorthick-.25])
cube([8.5,wallthick+2*adj,floorthick+.5]);
translate([width-(width*(1/5))-(wallthick+gap)-.25,depth-2*wallthick-gap-adj,
case_z-floorthick-.25])
cube([8.5,wallthick+2*adj,floorthick+.5]);
// bottom slots
translate([(width*(1/5))-8.25-(wallthick+gap),depth-2*wallthick-gap-adj,-.25])
cube([8.5,wallthick+2*adj,floorthick+.5]);
translate([width-(width*(1/5))-(wallthick+gap)-.25,
depth-2*wallthick-gap-adj,-.25]) cube([8.5,wallthick+2*adj,floorthick+.5]);
}
}
if(side == "right") {
difference() {
translate([width-(2*wallthick)-gap,-(2*wallthick)-gap,-wallthick])
cube([wallthick,depth+2*wallthick,case_z+(2*wallthick)]);
translate([width-(2*wallthick)-gap-adj,-wallthick-gap-.25,
((case_z)/2)]) cube([wallthick+2*adj,wallthick+.5,8.5]);
translate([width-(2*wallthick)-gap-adj,depth-2*(wallthick)-gap-.25,
((case_z)/2)])
cube([wallthick+2*adj,wallthick+.5,8.5]);
}
}
if(side == "left") {
difference() {
translate([-wallthick-gap,-(2*wallthick)-gap,-wallthick])
cube([wallthick,depth+2*wallthick,case_z+(2*wallthick)]);
translate([-wallthick-gap-adj,-wallthick-gap-.25,((case_z)/2)])
cube([wallthick+2*adj,wallthick+.5,8.5]);
translate([-wallthick-gap-adj,depth-2*(wallthick)-gap-.25,
((case_z)/2)])
cube([wallthick+2*adj,wallthick+.5,8.5]);
}
}
}
if(case_design == "tray_sides") {
if(side == "right") {
difference() {
union() {
translate([width-wallthick-gap,-(2*wallthick)-gap,0])
cube([sidethick,depth+2*wallthick,case_z+(2*wallthick)]);
translate([width-gap-wallthick-1+adj,depth-2*(wallthick+gap)-.5,case_z+(2*wallthick)-2])
cube([1,6,2]);
translate([width-gap-wallthick-1+adj,-2*(wallthick+gap)+1.5,case_z+(2*wallthick)-2])
cube([1,6,2]);
// top rail
translate([width-6.9-adj,-gap,case_z-floorthick-.5])
cube([4,depth-2*(wallthick+gap),2]);
}
// right side bottom attachment holes
translate([width-2*(wallthick+gap)-sidethick-adj,wallthick+gap+10,
((bottom_height+floorthick)/2)-1]) rotate([0,90,0]) cylinder(d=3, h=10+sidethick+(2*adj));
if(depth >= 75) {
translate([width-2*(wallthick+gap)-sidethick-adj,depth-wallthick-gap-10,
((bottom_height+floorthick)/2)-1]) rotate([0,90,0])
cylinder(d=3, h=10+sidethick+(2*adj));
}
else {
translate([width-2*(wallthick+gap)-sidethick-adj,wallthick+gap+40,
((bottom_height+floorthick)/2)-1]) rotate([0,90,0])
cylinder(d=3, h=10+sidethick+(2*adj));
}
}
}
if(side == "left") {
difference() {
union() {
translate([-wallthick-gap-sidethick,-(2*wallthick)-gap,0])
cube([sidethick,depth+2*wallthick,case_z+(2*wallthick)]);
translate([-gap-wallthick-adj,depth-2*(wallthick+gap)-.5,case_z+(2*wallthick)-2])
cube([1,6,2]);
translate([-gap-wallthick-adj,-2*(wallthick+gap)+1.5,case_z+(2*wallthick)-2])
cube([1,6,2]);
// top rail
translate([-wallthick-gap-adj,-gap,case_z-floorthick-.5])
cube([4,depth-2*(wallthick+gap),2]);
}
// left side bottom attachment holes
translate([-wallthick-gap-adj-5,wallthick+gap+10,
((bottom_height+floorthick)/2)-1]) rotate([0,90,0]) cylinder(d=3, h=10+sidethick+(2*adj));
if(depth >= 75) {
translate([-wallthick-gap-adj-6,depth-wallthick-gap-10,
((bottom_height+floorthick)/2)-1]) rotate([0,90,0])
cylinder(d=3, h=10+sidethick+(2*adj));
}
else {
translate([-wallthick-gap-adj-6,wallthick+gap+40,
((bottom_height+floorthick)/2)-1]) rotate([0,90,0])
cylinder(d=3, h=10+sidethick+(2*adj));
}
}
}
}
if(case_design == "tray_vu5") {
cheight = case_z+90;
vesa = 75;
vu_holder("vu5",side,vesa,cheight);
}
if(case_design == "tray_vu7") {
cheight = case_z+122;
vesa = 100;
vu_holder("vu7",side,vesa,cheight);
}
// additive accessories
if(accessory_name != "none") {
for (i=[1:11:len(accessory_data[a[0]])-1]) {
class = accessory_data[a[0]][i];
type = accessory_data[a[0]][i+1];
loc_x = accessory_data[a[0]][i+2];
loc_y = accessory_data[a[0]][i+3];
loc_z = accessory_data[a[0]][i+4];
face = accessory_data[a[0]][i+5];
rotation = accessory_data[a[0]][i+6];
parametric = accessory_data[a[0]][i+7];
size = accessory_data[a[0]][i+8];
data = accessory_data[a[0]][i+9];
mask = accessory_data[a[0]][i+10];
if (class == "add1" && face == side) {
parametric_move_add(type,loc_x,loc_y,loc_z,face,rotation,parametric,size,data,[false,mask[1],mask[2],mask[3]]);
}
}
}
}
// subtractive accessories
if(accessory_name != "none") {
for (i=[1:11:len(accessory_data[a[0]])-1]) {
class = accessory_data[a[0]][i];
type = accessory_data[a[0]][i+1];
loc_x = accessory_data[a[0]][i+2];
loc_y = accessory_data[a[0]][i+3];
loc_z = accessory_data[a[0]][i+4];
face = accessory_data[a[0]][i+5];
rotation = accessory_data[a[0]][i+6];
parametric = accessory_data[a[0]][i+7];
size_x = accessory_data[a[0]][i+8][0];
size_y = accessory_data[a[0]][i+8][1];
size_z = accessory_data[a[0]][i+8][2];
data = accessory_data[a[0]][i+9];
mask = accessory_data[a[0]][i+10];
if ((class == "sub" && face == side) || class == "suball") {
if(accessory_highlight == false) {
parametric_move_sub(type,loc_x,loc_y,loc_z,face,rotation,parametric,
[size_x,size_y,size_z],data,mask);
}
else {
#parametric_move_sub(type,loc_x,loc_y,loc_z,face,rotation,parametric,
[size_x,size_y,size_z],data,mask);
}
}
// create openings for additive
if((class == "add1" || class == "add2" || class == "model") && mask[0] == true) {
if(accessory_highlight == false) {
parametric_move_add(type,loc_x,loc_y,loc_z,face,rotation,parametric,[size_x,size_y,size_z],data,mask);
}
else {
#parametric_move_add(type,loc_x,loc_y,loc_z,face,rotation,parametric,[size_x,size_y,size_z],data,mask);
}
}
}
}
// sbc openings
if(sbc_highlight == true) {
#translate([pcb_loc_x ,pcb_loc_y,bottom_height-pcb_z+pcb_loc_z-adj-adj])
sbc(sbc_model, cooling, fan_size, gpio_opening, uart_opening, true);
}
else {
translate([pcb_loc_x ,pcb_loc_y,bottom_height-pcb_z+pcb_loc_z-adj-adj])
sbc(sbc_model, cooling, fan_size, gpio_opening, uart_opening, true);
}
// 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:11:len(accessory_data[a[0]])-1]) {
class = accessory_data[a[0]][i];
type = accessory_data[a[0]][i+1];
loc_x = accessory_data[a[0]][i+2];
loc_y = accessory_data[a[0]][i+3];
loc_z = accessory_data[a[0]][i+4];
face = accessory_data[a[0]][i+5];
rotation = accessory_data[a[0]][i+6];
parametric = accessory_data[a[0]][i+7];
size = accessory_data[a[0]][i+8];
data = accessory_data[a[0]][i+9];
mask = accessory_data[a[0]][i+10];
if (class == "add2" && face == side) {
parametric_move_add(type,loc_x,loc_y,loc_z,face,rotation,parametric,size,data,[false,mask[1],mask[2],mask[3]]);
}
}
}
}

660
mod/case_top.scad Normal file
View File

@@ -0,0 +1,660 @@
/*
This file is part of SBC Case Builder https://github.com/hominoids/SBC_Case_Builder
Copyright 2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
NAME: case_top
DESCRIPTION: creates case top for supported designs
TODO: none
USAGE: case_top(case_design)
*/
module case_top(case_design) {
lip = 5;
vu_rotation = [15,0,0];
case_fn = 360; // circle segments for round cases
case_ffn = 90; // circle segments for fillet of round cases
adj = .01;
difference() {
union() {
difference() {
union() {
if(case_design == "shell") {
difference() {
translate([(width/2)-wallthick-gap,
(depth/2)-wallthick-gap,bottom_height+(top_height/2)])
cube_fillet_inside([width,depth,top_height],
vertical=[corner_fillet,corner_fillet,corner_fillet,corner_fillet],
top=[edge_fillet,edge_fillet,edge_fillet,edge_fillet,edge_fillet],
bottom=[0,0,0,0], $fn=90);
translate([(width/2)-wallthick-gap,(depth/2)-wallthick-gap,
bottom_height+(top_height/2)-floorthick])
cube_fillet_inside([width-(wallthick*2),depth-(wallthick*2),top_height],
vertical=[corner_fillet-1,corner_fillet-1,corner_fillet-1,corner_fillet-1],
top=[edge_fillet,edge_fillet,edge_fillet,edge_fillet,edge_fillet],
bottom=[0,0,0,0], $fn=90);
}
}
if(case_design == "panel") {
union() {
translate([-gap,-gap,case_z-floorthick])
cube([width-(2*wallthick),depth-(2*wallthick),floorthick]);
translate([(width*(1/5))-8-(wallthick+gap),depth-(2*wallthick)-gap-adj,
case_z-floorthick])
cube([8,wallthick+2*adj,floorthick]);
translate([width-(width*(1/5))-(wallthick+gap),depth-(2*wallthick)-gap-adj,
case_z-floorthick])
cube([8,wallthick+2*adj,floorthick]);
translate([(width*(1/5))-8-(wallthick+gap),-wallthick-gap+adj,
case_z-floorthick])
cube([8,wallthick+2*adj,floorthick]);
translate([width-(width*(1/5))-(wallthick+gap),-wallthick-gap+adj,
case_z-floorthick])
cube([8,wallthick+2*adj,floorthick]);
}
}
if(case_design == "stacked") {
translate([(width/2)-wallthick-gap,(depth/2)-wallthick-gap,
case_z-(floorthick/2)])
cube_fillet_inside([width-(2*wallthick),depth-(2*wallthick),floorthick],
vertical=[corner_fillet,corner_fillet,corner_fillet,corner_fillet],
top=[0,0,0,0], bottom=[0,0,0,0], $fn=90);
}
if(case_design == "tray_vu5" || case_design == "tray_vu7" || case_design == "tray_sides") {
translate([-wallthick-gap+.5,-wallthick-gap,case_z])
cube([width-1,depth,floorthick]);
translate([-wallthick-gap+.5,-wallthick-gap,
case_z-floorthick+adj]) cube([width-1,wallthick,wallthick]);
}
if(case_design == "tray") {
difference() {
translate([(width/2)-wallthick-gap,(depth/2)-wallthick-gap,case_z/2])
cube_fillet_inside([width+2*wallthick+1,depth,case_z],
vertical=[0,0,0,0], top=[0,edge_fillet,0,edge_fillet,edge_fillet],
bottom=[0,0,0,0], $fn=90);
translate([(width/2)-wallthick-gap,(depth/2)-wallthick-gap,(case_z/2)-floorthick+.25])
cube_fillet_inside([width+1,depth+(wallthick*2),case_z],
vertical=[corner_fillet-1,corner_fillet-1,corner_fillet-1,corner_fillet-1],
top=[0,0,0,0],bottom=[0,0,0,0], $fn=90);
for (i=[1:11:len(sbc_data[s[0]])-2]) {
class = sbc_data[s[0]][i+1];
type = sbc_data[s[0]][i+2];
id = sbc_data[s[0]][i+3];
pcbhole_x = sbc_data[s[0]][i+4]+pcb_loc_x;
pcbhole_y = sbc_data[s[0]][i+5]+pcb_loc_y;
pcbhole_z = sbc_data[s[0]][i+6];
pcbhole_size = sbc_data[s[0]][i+9][0];
pcbhole_pos = sbc_data[s[0]][i+10][4];
if(class == "pcbhole" && id == pcb_id && pcbhole_pos == "left_rear") {
if((pcbhole_y <= 10 && pcbhole_x <= 10) || (ext_top_standoffs == true && ext_top_rear_left_enable == true)) {
translate([-wallthick-gap-adj-6,wallthick+gap+10,floorthick+3.4]) rotate([0,90,0])
cylinder(d=3, h=10+sidethick+(2*adj));
}
else {
translate([-wallthick-gap-adj-6,wallthick+gap+2,floorthick+3.4]) rotate([0,90,0])
cylinder(d=3, h=10+sidethick+(2*adj));
}
}
if(class == "pcbhole" && id == pcb_id && pcbhole_pos == "left_front") {
if((pcbhole_y >= pcb_depth+case_offset_y-10 && pcbhole_x <= 10) || (ext_top_standoffs == true && ext_top_front_left_enable == true)) {
translate([-wallthick-gap-adj-6,wallthick-gap+pcb_depth+case_offset_y-14,
floorthick+3.4]) rotate([0,90,0]) cylinder(d=3, h=10+sidethick+(2*adj));
}
else {
translate([-wallthick-gap-adj-6,wallthick+gap+pcb_depth+case_offset_y-8,
floorthick+3.4]) rotate([0,90,0]) cylinder(d=3, h=10+sidethick+(2*adj));
}
}
if(class == "pcbhole" && id == pcb_id && pcbhole_pos == "right_rear") {
if((pcbhole_y <= 10 && pcbhole_x >= pcb_width-10) || (ext_top_standoffs == true && ext_top_rear_right_enable == true)) {
translate([width-2*(wallthick+gap)-sidethick-adj,wallthick+gap+10,floorthick+3.4])
rotate([0,90,0]) cylinder(d=3, h=10+sidethick+(2*adj));
}
else {
translate([width-2*(wallthick+gap)-sidethick-adj,wallthick+gap+2,floorthick+3.4])
rotate([0,90,0]) cylinder(d=3, h=10+sidethick+(2*adj));
}
}
if(class == "pcbhole" && id == pcb_id && pcbhole_pos == "right_front") {
if((pcbhole_y >= pcb_depth+case_offset_y-10 && pcbhole_x >= width-10) || (ext_bottom_standoffs == true && ext_bottom_front_right_enable == true)) {
translate([width-3*(wallthick+gap)-adj,wallthick-gap+pcb_depth+case_offset_y-14,
floorthick+3.4]) rotate([0,90,0]) cylinder(d=3, h=10+sidethick+(2*adj));
}
else {
translate([width-3*(wallthick+gap)-adj,wallthick-gap+pcb_depth+case_offset_y-8,
floorthick+3.4]) rotate([0,90,0]) cylinder(d=3, h=10+sidethick+(2*adj));
}
}
}
}
}
if(case_design == "round") {
difference() {
translate([pcb_width/2,pcb_depth/2,bottom_height+(top_height/2)-lip/2]) rotate([0,0,30])
cylinder_fillet_inside(h=top_height+lip, r=case_diameter/2,
top=edge_fillet, bottom=0, $fn=case_fn, fillet_fn=case_ffn, center=true);
translate([pcb_width/2,pcb_depth/2,bottom_height+(top_height/2)-floorthick-lip/2]) rotate([0,0,30])
cylinder_fillet_inside(h=top_height+lip, r=(case_diameter/2)-wallthick,
top=edge_fillet-1, bottom=0, $fn=case_fn, fillet_fn=case_ffn, center=true);
translate([pcb_width/2,pcb_depth/2,bottom_height-adj-lip/2]) rotate([0,0,30])
cylinder_fillet_inside(h=lip+2*adj, r=(case_diameter/2)-wallthick/2+tol/2,
top=edge_fillet-1, bottom=0, $fn=case_fn, fillet_fn=case_ffn, center=true);
// io cutout
if(width/depth >= 1.4 && sbc_model != "vim1" && sbc_model != "vim2" &&
sbc_model != "vim3l" && sbc_model != "vim3" && sbc_model != "vim4" &&
sbc_model != "rpizero" && sbc_model != "rpizero2w") {
translate([width,(depth/2)-wallthick-gap,bottom_height-lip+top_height/2-floorthick])
cube_fillet_inside([18,depth-2*(wallthick+gap)-1,top_height+lip+2],
vertical=[0,0,0,0], top=[0,0,0,0], bottom=[0,0,0,0], $fn=90);
}
else {
translate([(width/2)-wallthick-gap,-20,bottom_height-lip+top_height/2-floorthick])
cube_fillet_inside([width-2*(wallthick+gap)-1,40,top_height+lip+2],
vertical=[0,0,0,0], top=[0,0,0,0], bottom=[0,0,0,0], $fn=90);
}
}
if(width/depth >= 1.4 && sbc_model != "vim1" && sbc_model != "vim2" &&
sbc_model != "vim3l" && sbc_model != "vim3" && sbc_model != "vim4" &&
sbc_model != "rpizero" && sbc_model != "rpizero2w") {
translate([width-2*wallthick-gap-.95,depth/2-wallthick-gap-(depth-2*(floorthick+gap))/2,
bottom_height]) cube([wallthick-adj,depth-2*(floorthick+gap),top_height+adj]);
}
else {
translate([-.95,depth/2-2*wallthick-gap-(depth-2*(floorthick+gap))/2,
bottom_height]) cube([width-2*(floorthick+gap),wallthick-adj,top_height+adj]);
}
}
if(case_design == "hex") {
if(width/depth >= 1.4 && sbc_model != "vim1" && sbc_model != "vim2" &&
sbc_model != "vim3l" && sbc_model != "vim3" && sbc_model != "vim4" &&
sbc_model != "rpizero" && sbc_model != "rpizero2w") {
difference() {
translate([pcb_width/2,pcb_depth/2,bottom_height+(top_height/2)-lip/2]) rotate([0,0,30])
cylinder_fillet_inside(h=top_height+lip, r=case_diameter/2,
top=edge_fillet, bottom=0, $fn=6, fillet_fn=case_ffn, center=true);
translate([pcb_width/2,pcb_depth/2,bottom_height+(top_height/2)-floorthick-lip/2]) rotate([0,0,30])
cylinder_fillet_inside(h=top_height+lip, r=(case_diameter/2)-wallthick,
top=edge_fillet-1, bottom=0, $fn=6, fillet_fn=case_ffn, center=true);
translate([pcb_width/2,pcb_depth/2,bottom_height-adj-lip/2]) rotate([0,0,30])
cylinder_fillet_inside(h=lip+2*adj, r=(case_diameter/2)-wallthick/2+tol/2,
top=edge_fillet-1, bottom=0, $fn=6, fillet_fn=case_ffn, center=true);
// io cutout
translate([width,(depth/2)-wallthick-gap,bottom_height-lip+top_height/2-floorthick])
cube_fillet_inside([18,depth-2*(wallthick+gap)-1,top_height+lip+2],
vertical=[0,0,0,0], top=[0,0,0,0], bottom=[0,0,0,0], $fn=90);
}
}
else {
difference() {
translate([pcb_width/2,pcb_depth/2,bottom_height+(top_height/2)-lip/2]) rotate([0,0,0])
cylinder_fillet_inside(h=top_height+lip, r=hex_diameter/2,
top=edge_fillet, bottom=0, $fn=6, fillet_fn=case_ffn, center=true);
translate([pcb_width/2,pcb_depth/2,bottom_height+(top_height/2)-floorthick-lip/2])
rotate([0,0,0]) cylinder_fillet_inside(h=top_height+lip, r=(hex_diameter/2)-wallthick,
top=edge_fillet-1, bottom=0, $fn=6, fillet_fn=case_ffn, center=true);
translate([pcb_width/2,pcb_depth/2,bottom_height-adj-lip/2]) rotate([0,0,0])
cylinder_fillet_inside(h=lip+2*adj, r=(hex_diameter/2)-wallthick/2+tol/2,
top=edge_fillet-1, bottom=0, $fn=6, fillet_fn=case_ffn, center=true);
// io cutout
translate([(width/2)-wallthick-gap,-23,bottom_height-lip+top_height/2-floorthick])
cube_fillet_inside([width-2*(wallthick+gap),40,top_height+lip+2],
vertical=[0,0,0,0], top=[0,0,0,0], bottom=[0,0,0,0], $fn=90);
}
}
if(width/depth >= 1.4 && sbc_model != "vim1" && sbc_model != "vim2" &&
sbc_model != "vim3l" && sbc_model != "vim3" && sbc_model != "vim4" &&
sbc_model != "rpizero" && sbc_model != "rpizero2w") {
translate([width-2*wallthick-gap-.95,depth/2-wallthick-gap-(depth-2*(floorthick+gap))/2,
bottom_height]) cube([wallthick-adj,depth-2*(floorthick+gap),top_height+adj]);
}
else {
translate([0,depth/2-2.25*(wallthick+gap)-(depth-2*(floorthick+gap))/2,
bottom_height]) cube([width-2*(floorthick+gap),wallthick-adj,top_height+adj]);
}
}
if(case_design == "snap") {
translate([(width/2)-wallthick-gap,(depth/2)-wallthick-gap,floorthick*1.5+case_z])
cube_fillet_inside([width,depth,floorthick],
vertical=[corner_fillet,corner_fillet,corner_fillet,corner_fillet],
top=[0,0,0,0],bottom=[edge_fillet,edge_fillet,edge_fillet,edge_fillet,edge_fillet], $fn=90);
difference() {
translate([(width/2)-wallthick-gap,(depth/2)-wallthick-gap,case_z-adj])
cube_fillet_inside([width-2*wallthick-tol,depth-2*wallthick-tol,2*floorthick+1.5],
vertical=[corner_fillet,corner_fillet,corner_fillet,corner_fillet],
top=[0,0,0,0],bottom=[edge_fillet,edge_fillet,edge_fillet,edge_fillet,edge_fillet], $fn=90);
translate([(width/2)-wallthick-gap,(depth/2)-wallthick-gap,case_z-adj])
cube_fillet_inside([width-(3*wallthick),depth-(3*wallthick),2*floorthick+1.5+adj],
vertical=[corner_fillet-1,corner_fillet-1,corner_fillet-1,corner_fillet-1],top=[0,0,0,0],
bottom=[edge_fillet,edge_fillet,edge_fillet,edge_fillet,edge_fillet], $fn=90);
}
// snap top outdent
difference() {
translate([-wallthick-gap+1.25+tol,(depth/2)-((depth*.75)/2)+2.5-gap-wallthick,case_z-.5])
rotate([0,45,0]) cube([4,(depth*.75)-5,4]);
translate([-wallthick-gap+3,(depth/2)-((depth*.75)/2)+1.25-gap-wallthick,case_z+floorthick-5.75])
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=[corner_fillet,corner_fillet,corner_fillet,corner_fillet],
top=[edge_fillet,edge_fillet,edge_fillet,edge_fillet,edge_fillet],
bottom=[0,0,0,0], $fn=90);
translate([(width/2)-wallthick-gap,(depth/2)-wallthick-gap,case_z-floorthick-1])
cube_fillet_inside([width-wallthick+tol,depth-wallthick+tol,lip+floorthick],
vertical=[corner_fillet-1,corner_fillet-1,corner_fillet-1,corner_fillet-1],
top=[edge_fillet,edge_fillet,edge_fillet,edge_fillet,edge_fillet],
bottom=[0,0,0,0], $fn=90);
}
}
if(accessory_name != "none") {
for (i=[1:11:len(accessory_data[a[0]])-1]) {
class = accessory_data[a[0]][i];
type = accessory_data[a[0]][i+1];
loc_x = accessory_data[a[0]][i+2];
loc_y = accessory_data[a[0]][i+3];
loc_z = accessory_data[a[0]][i+4];
face = accessory_data[a[0]][i+5];
rotation = accessory_data[a[0]][i+6];
parametric = accessory_data[a[0]][i+7];
size = accessory_data[a[0]][i+8];
data = accessory_data[a[0]][i+9];
mask = accessory_data[a[0]][i+10];
if (class == "add1" && face == "top") {
parametric_move_add(type,loc_x,loc_y,loc_z,face,rotation,parametric,size,data,[false,mask[1],mask[2],mask[3]]);
}
}
}
}
// pcb standoff holes
if(sbc_top_standoffs == true) {
for (i=[1:11:len(sbc_data[s[0]])-2]) {
class = sbc_data[s[0]][i+1];
type = sbc_data[s[0]][i+2];
id = sbc_data[s[0]][i+3];
pcbhole_x = sbc_data[s[0]][i+4]+pcb_loc_x;
pcbhole_y = sbc_data[s[0]][i+5]+pcb_loc_y;
pcbhole_z = sbc_data[s[0]][i+6];
pcbhole_size = sbc_data[s[0]][i+9][0];
pcbhole_pos = sbc_data[s[0]][i+10][4];
if (class == "pcbhole" && id == pcb_id && pcbhole_pos == "left_rear" && top_rear_left_enable == true &&
top_standoff[6] != "blind") {
translate([pcbhole_x,pcbhole_y,top_height+5]) cylinder(d=top_standoff[4]-.2, h=top_height);
}
if (class == "pcbhole" && id == pcb_id && pcbhole_pos == "left_front" && top_front_left_enable == true &&
top_standoff[6] != "blind") {
translate([pcbhole_x,pcbhole_y,top_height+5]) cylinder(d=top_standoff[4]-.2, h=top_height);
}
if (class == "pcbhole" && id == pcb_id && pcbhole_pos == "right_rear" && top_rear_right_enable == true &&
top_standoff[6] != "blind") {
translate([pcbhole_x,pcbhole_y,top_height+5]) cylinder(d=top_standoff[4]-.2, h=top_height);
}
if (class == "pcbhole" && id == pcb_id && pcbhole_pos == "right_front" && top_front_right_enable == true &&
top_standoff[6] != "blind") {
translate([pcbhole_x,pcbhole_y,top_height+5]) cylinder(d=top_standoff[4]-.2, h=top_height);
}
}
}
// extended standoff holes
if(ext_top_standoffs == true) {
// right-rear standoff
if((width-pcb_loc_x-pcb_width-(gap+2*wallthick) >= 10 || pcb_loc_y >= 10) &&
ext_top_rear_right_enable == true && ext_top_standoff[6] != "blind") {
translate([width-ext_top_standoff_support_size/4-(2*(wallthick+gap))-(corner_fillet/2),
(corner_fillet/2)+ext_top_standoff_support_size/4,top_height+5]) cylinder(d=ext_top_standoff[4]-.2, h=top_height);
}
// right-front standoff
if(((width-pcb_loc_x-pcb_width-(gap+2*wallthick) >= 10 && depth-pcb_loc_y-pcb_depth >= 10) ||
(width-pcb_loc_x-pcb_width-(gap+2*wallthick) >= 10 && depth-pcb_loc_y-pcb_depth <= 10) ||
(width-pcb_loc_x-pcb_width-(gap+2*wallthick) <= 10 && depth-pcb_loc_y-pcb_depth >= 10)) &&
ext_top_front_right_enable == true && ext_top_standoff[6] != "blind") {
translate([width-ext_top_standoff_support_size/4-(corner_fillet/2)-(2*(wallthick+gap)),
depth-ext_top_standoff_support_size/4-(corner_fillet/2)-(2*(wallthick+gap)),top_height+5])
cylinder(d=ext_top_standoff[4]-.2, h=top_height);
}
// left-rear standoff
if((pcb_loc_x >= 10 || pcb_loc_y >= 10) && ext_top_rear_left_enable == true && ext_top_standoff[6] != "blind") {
translate([(corner_fillet/2)+ext_top_standoff_support_size/4,
(corner_fillet/2)+ext_top_standoff_support_size/4,top_height+5]) cylinder(d=ext_top_standoff[4]-.2, h=top_height);
}
// left-front standoff
if(((pcb_loc_x >= 10 && (depth-(pcb_loc_y+pcb_depth)) >= 10) ||
(pcb_loc_x <= 10 && (depth-(pcb_loc_y+pcb_depth)) >= 10) ||
(pcb_loc_x >= 10 && (depth-(pcb_loc_y+pcb_depth)) <= 10)) &&
ext_top_front_left_enable == true && ext_top_standoff[6] != "blind") {
translate([+(corner_fillet/2)+ext_top_standoff_support_size/4,
depth-ext_top_standoff_support_size/4-(corner_fillet/2)-(2*(wallthick+gap)),top_height+5])
cylinder(d=ext_top_standoff[4]-.2, h=top_height);
}
}
// top cover pattern
if(top_cover_pattern != "solid") {
if(top_cover_pattern == "hex_5mm") {
translate([1,0,case_z-2]) vent_hex((width)/3.75,(depth)/6,floorthick+4,5,1.5,"horizontal");
}
if(top_cover_pattern == "hex_8mm") {
translate([1,2,case_z-2]) vent_hex((width)/5.5,(depth)/9.5,floorthick+4,8,1.5,"horizontal");
}
if(top_cover_pattern == "linear_vertical") {
translate([0,-gap,case_z-2]) vent(wallthick,depth-2*wallthick-gap,floorthick+4,1,1,(width-2*wallthick-gap)/4,"horizontal");
}
if(top_cover_pattern == "linear_horizontal") {
translate([-gap,-gap,case_z-2]) vent(width-2*wallthick-gap,wallthick,floorthick+4,1,(depth-2*wallthick-gap)/3,1,"horizontal");
}
if(top_cover_pattern == "astroid") {
for(c=[3:12:depth-8]) {
for(r=[4:12:width-8]) {
translate([r,c,case_z-4]) linear_extrude(floorthick+5) import("./dxf/astroid_8mm.dxf");
}
}
}
}
// rear io shield opening for standard form motherboards
if(rear_io_shield == true) {
if(sbc_model == "mini-stx_thin") {
translate([6.2+pcb_loc_x,-4.5,-4.15+bottom_height-pcb_z+pcb_loc_z]) cube([123.95, 10+pcb_loc_y, 25]);
}
if(sbc_model == "mini-stx") {
translate([6.2+pcb_loc_x,-4.5,-4.15+bottom_height-pcb_z+pcb_loc_z]) cube([123.95, 10+pcb_loc_y, 40]);
}
if(sbc_model == "mini-itx_thin") {
translate([-2.62+pcb_loc_x,-4.5,-1.75+bottom_height-pcb_z+pcb_loc_z]) cube([158.75, 10+pcb_loc_y, 25]);
}
if(sbc_model != "mini-stx_thin" && sbc_model != "mini-stx" && sbc_model != "mini-itx_thin") {
translate([-2.62+pcb_loc_x,-4.5,-1.75+bottom_height-pcb_z+pcb_loc_z]) cube([158.75, 10+pcb_loc_y, 44]);
}
}
}
// pcb standoffs
if(sbc_top_standoffs == true) {
for (i=[1:11:len(sbc_data[s[0]])-2]) {
class = sbc_data[s[0]][i+1];
type = sbc_data[s[0]][i+2];
id = sbc_data[s[0]][i+3];
pcbhole_x = sbc_data[s[0]][i+4]+pcb_loc_x;
pcbhole_y = sbc_data[s[0]][i+5]+pcb_loc_y;
pcbhole_z = sbc_data[s[0]][i+6];
pcbhole_size = sbc_data[s[0]][i+9][0];
pcbhole_pos = sbc_data[s[0]][i+10][4];
if(class == "pcbhole" && id == pcb_id &&
(pcbhole_pos == "left_rear" || pcbhole_pos == "left_front" || pcbhole_pos == "right_rear" || pcbhole_pos == "right_front")) {
if (pcbhole_pos == "left_rear" && top_rear_left_enable == true) {
top_support = top_sidewall_support == true ? top_rear_left_support : "none";
pcb_standoff = [top_standoff[0],
top_standoff[1],
top_height+top_rear_left_adjust-pcb_loc_z,
top_standoff[3],
top_standoff[4],
top_standoff[5],
top_standoff[6],
top_standoff[7],
top_support,
top_standoff[9],
top_standoff[10],
top_standoff[11],
top_standoff[12]];
translate([pcbhole_x,pcbhole_y,case_z]) standoff(pcb_standoff,[false,10,2,"default"]);
}
if (pcbhole_pos == "left_front" && top_front_left_enable == true) {
top_support = top_sidewall_support == true ? top_front_left_support : "none";
pcb_standoff = [top_standoff[0],
top_standoff[1],
top_height+top_front_left_adjust-pcb_loc_z,
top_standoff[3],
top_standoff[4],
top_standoff[5],
top_standoff[6],
top_standoff[7],
top_support,
top_standoff[9],
top_standoff[10],
top_standoff[11],
top_standoff[12]];
translate([pcbhole_x,pcbhole_y,case_z]) standoff(pcb_standoff,[false,10,2,"default"]);
}
if (pcbhole_pos == "right_rear" && top_rear_right_enable == true) {
top_support = top_sidewall_support == true ? top_rear_right_support : "none";
pcb_standoff = [top_standoff[0],
top_standoff[1],
top_height+top_rear_right_adjust-pcb_loc_z,
top_standoff[3],
top_standoff[4],
top_standoff[5],
top_standoff[6],
top_standoff[7],
top_support,
top_standoff[9],
top_standoff[10],
top_standoff[11],
top_standoff[12]];
translate([pcbhole_x,pcbhole_y,case_z]) standoff(pcb_standoff,[false,10,2,"default"]);
}
if (pcbhole_pos == "right_front" && top_front_right_enable == true) {
top_support = top_sidewall_support == true ? top_front_right_support : "none";
pcb_standoff = [top_standoff[0],
top_standoff[1],
top_height+top_front_right_adjust-pcb_loc_z,
top_standoff[3],
top_standoff[4],
top_standoff[5],
top_standoff[6],
top_standoff[7],
top_support,
top_standoff[9],
top_standoff[10],
top_standoff[11],
top_standoff[12]];
translate([pcbhole_x,pcbhole_y,case_z]) standoff(pcb_standoff,[false,10,2,"default"]);
}
}
}
}
// extended standoffs
if(ext_top_standoffs == true) {
// extended right-rear standoff
if((width-pcb_loc_x-pcb_width-(gap+2*wallthick) >= 10 || pcb_loc_y >= 10) && ext_top_rear_right_enable == true) {
extended_standoff = [ext_top_standoff[0],
ext_top_standoff[1],
top_height+ext_top_rear_right_adjust,
ext_top_standoff[3],
ext_top_standoff[4],
ext_top_standoff[5],
ext_top_standoff[6],
ext_top_standoff[7],
ext_top_rear_right_support,
ext_top_standoff[9],
ext_top_standoff[10],
ext_top_standoff[11],
ext_top_standoff[12]];
translate([width-ext_top_standoff_support_size/4-(2*(wallthick+gap))-(corner_fillet/2),
(corner_fillet/2)+ext_top_standoff_support_size/4,case_z]) standoff(extended_standoff,[false,10,2,"default"]);
}
// extended right-front standoff
if(((width-pcb_loc_x-pcb_width-(gap+2*wallthick) >= 10 && depth-pcb_loc_y-pcb_depth >= 10) ||
(width-pcb_loc_x-pcb_width-(gap+2*wallthick) >= 10 && depth-pcb_loc_y-pcb_depth <= 10) ||
(width-pcb_loc_x-pcb_width-(gap+2*wallthick) <= 10 && depth-pcb_loc_y-pcb_depth >= 10)) &&
ext_top_front_right_enable == true) {
extended_standoff = [ext_top_standoff[0],
ext_top_standoff[1],
top_height+ext_top_front_right_adjust,
ext_top_standoff[3],
ext_top_standoff[4],
ext_top_standoff[5],
ext_top_standoff[6],
ext_top_standoff[7],
ext_top_front_right_support,
ext_top_standoff[9],
ext_top_standoff[10],
ext_top_standoff[11],
ext_top_standoff[12]];
translate([width-ext_top_standoff_support_size/4-(corner_fillet/2)-(2*(wallthick+gap)),
depth-ext_top_standoff_support_size/4-(corner_fillet/2)-(2*(wallthick+gap)),case_z])
standoff(extended_standoff,[false,10,2,"default"]);
}
// extended left-rear standoff
if((pcb_loc_x >= 10 || pcb_loc_y >= 10) && ext_top_rear_left_enable == true) {
extended_standoff = [ext_top_standoff[0],
ext_top_standoff[1],
top_height+ext_top_rear_left_adjust,
ext_top_standoff[3],
ext_top_standoff[4],
ext_top_standoff[5],
ext_top_standoff[6],
ext_top_standoff[7],
ext_top_rear_left_support,
ext_top_standoff[9],
ext_top_standoff[10],
ext_top_standoff[11],
ext_top_standoff[12]];
translate([(corner_fillet/2)+ext_top_standoff_support_size/4,
(corner_fillet/2)+ext_top_standoff_support_size/4,case_z]) standoff(extended_standoff,[false,10,2,"default"]);
}
// extended left-front standoff
if(((pcb_loc_x >= 10 && (depth-(pcb_loc_y+pcb_depth)) >= 10) ||
(pcb_loc_x <= 10 && (depth-(pcb_loc_y+pcb_depth)) >= 10) ||
(pcb_loc_x >= 10 && depth-(pcb_loc_y+pcb_depth) <= 10)) &&
ext_top_front_left_enable == true) {
extended_standoff = [ext_top_standoff[0],
ext_top_standoff[1],
top_height+ext_top_front_left_adjust,
ext_top_standoff[3],
ext_top_standoff[4],
ext_top_standoff[5],
ext_top_standoff[6],
ext_top_standoff[7],
ext_top_front_left_support,
ext_top_standoff[9],
ext_top_standoff[10],
ext_top_standoff[11],
ext_top_standoff[12]];
translate([(corner_fillet/2)+ext_top_standoff_support_size/4,
depth-ext_top_standoff_support_size/4-(corner_fillet/2)-(2*(wallthick+gap)), case_z])
standoff(extended_standoff,[false,10,2,"default"]);
}
}
}
// subtractive accessories
if(accessory_name != "none") {
for (i=[1:11:len(accessory_data[a[0]])-1]) {
class = accessory_data[a[0]][i];
type = accessory_data[a[0]][i+1];
loc_x = accessory_data[a[0]][i+2];
loc_y = accessory_data[a[0]][i+3];
loc_z = accessory_data[a[0]][i+4];
face = accessory_data[a[0]][i+5];
rotation = accessory_data[a[0]][i+6];
parametric = accessory_data[a[0]][i+7];
size_x = accessory_data[a[0]][i+8][0];
size_y = accessory_data[a[0]][i+8][1];
size_z = accessory_data[a[0]][i+8][2];
data = accessory_data[a[0]][i+9];
mask = accessory_data[a[0]][i+10];
if ((class == "sub" && face == "top") || class == "suball") {
if(accessory_highlight == false) {
parametric_move_sub(type,loc_x,loc_y,loc_z,face,rotation,
parametric,[size_x,size_y,size_z],data,mask);
}
else {
#parametric_move_sub(type,loc_x,loc_y,loc_z,face,rotation,
parametric,[size_x,size_y,size_z],data,mask);
}
}
// create openings for additive
if((class == "add1" || class == "add2" || class == "model") && mask[0] == true) {
if(accessory_highlight == false) {
parametric_move_add(type,loc_x,loc_y,loc_z,face,rotation,parametric,[size_x,size_y,size_z],data,mask);
}
else {
#parametric_move_add(type,loc_x,loc_y,loc_z,face,rotation,parametric,[size_x,size_y,size_z],data,mask);
}
}
}
}
// sbc openings
if(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=[corner_fillet,corner_fillet,corner_fillet,corner_fillet],
top=[edge_fillet,edge_fillet,edge_fillet,edge_fillet,edge_fillet],
bottom=[0,0,0,0], $fn=90);
}
}
// additive accessories
if(accessory_name != "none") {
for (i=[1:11:len(accessory_data[a[0]])-1]) {
class = accessory_data[a[0]][i];
type = accessory_data[a[0]][i+1];
loc_x = accessory_data[a[0]][i+2];
loc_y = accessory_data[a[0]][i+3];
loc_z = accessory_data[a[0]][i+4];
face = accessory_data[a[0]][i+5];
rotation = accessory_data[a[0]][i+6];
parametric = accessory_data[a[0]][i+7];
size = accessory_data[a[0]][i+8];
data = accessory_data[a[0]][i+9];
mask = accessory_data[a[0]][i+10];
if (class == "add2" && face == "top") {
parametric_move_add(type,loc_x,loc_y,loc_z,face,rotation,parametric,size,data,[false,mask[1],mask[2],mask[3]]);
}
}
}
}

268
mod/indent.scad Normal file
View File

@@ -0,0 +1,268 @@
/*
This file is part of SBC Case Builder https://github.com/hominoids/SBC_Case_Builder
Copyright 2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
NAME: indent
DESCRIPTION: creates case IO indents
TODO: none
USAGE: indent(loc_x, loc_y, loc_z, rotation, side, class, type, wallthick, gap, floorthick, pcb_z)
*/
module indent(loc_x, loc_y, loc_z, rotation, side, class, type, wallthick, gap, floorthick, pcb_z) {
adj = .01;
$fn=90;
// hdmi indent
if(class == "video" && type == "hdmi_a" && side == "top" && rotation == 0) {
place(loc_x+2.375,-(wallthick+gap)+wallthick/2,loc_z+3.75,12,10,rotation,side)
rotate([90,0,0]) long_slot(12,10,wallthick);
}
if(class == "video" && type == "hdmi_a" && side == "top" && rotation == 90) {
place(-gap-wallthick/2,loc_y,loc_z+3.75,12,10,rotation,side)
rotate([90,0,0]) long_slot(12,10,wallthick);
}
if(class == "video" && type == "hdmi_a" && side == "top" && rotation == 180) {
place(loc_x,depth-(wallthick+gap)-10-wallthick/2,loc_z+3.75,12,10,rotation,side)
rotate([90,0,0]) long_slot(12,10,wallthick);
}
if(class == "video" && type == "hdmi_a" && side == "top" && rotation == 270) {
place(width-(wallthick+gap)-10-wallthick/2,loc_y+2.375,loc_z+3.75,12,10,rotation,side)
rotate([90,0,0]) long_slot(12,10,wallthick);
}
if(class == "video" && type == "hdmi_a" && side == "bottom" && rotation == 0) {
place(loc_x,-(wallthick+gap)+wallthick/2,loc_z-pcb_z-3.75,12,10,rotation,side)
rotate([90,0,0]) long_slot(12,10,wallthick);
}
if(class == "video" && type == "hdmi_a" && side == "bottom" && rotation == 90) {
place(width-(wallthick+gap)-10-wallthick/2,loc_y,loc_z-5.25,12,10,rotation,side)
rotate([90,0,0]) long_slot(12,10,wallthick);
}
if(class == "video" && type == "hdmi_a" && side == "bottom" && rotation == 180) {
place(loc_x+2.375,depth-(wallthick+gap)-10-wallthick/2,loc_z-pcb_z-3.75,12,10,rotation,side)
rotate([90,0,0]) long_slot(12,10,wallthick);
}
if(class == "video" && type == "hdmi_a" && side == "bottom" && rotation == 270) {
place(-gap-wallthick/2,loc_y+1.75,loc_z-pcb_z-3.75,12,10,rotation,side)
rotate([90,0,0]) long_slot(12,10,wallthick);
}
// hdmi micro indent
if(class == "video" && type == "hdmi_micro" && rotation == 0 && side == "top") {
place(loc_x-.5,-(wallthick+gap)+wallthick/2,loc_z+1.5,6,8,rotation,side)
rotate([90,0,0]) long_slot(6,8,wallthick);
}
if(class == "video" && type == "hdmi_micro" && rotation == 90 && side == "top") {
place(-gap-wallthick/2,loc_y+1.5,loc_z+1.5,6,8,rotation,side)
rotate([90,0,0]) long_slot(6,8,wallthick);
}
if(class == "video" && type == "hdmi_micro" && rotation == 180 && side == "top") {
place(loc_x+1,depth-(wallthick+gap)-8-wallthick/2,loc_z+1.5,6,8,rotation,side)
rotate([90,0,0]) long_slot(6,8,wallthick);
}
if(class == "video" && type == "hdmi_micro" && rotation == 270 && side == "top") {
place(width-(wallthick+gap)-8-wallthick/2,loc_y-.75,loc_z+1.5,6,8,rotation,side)
rotate([90,0,0]) long_slot(6,8,wallthick);
}
if(class == "video" && type == "hdmi_micro" && rotation == 0 && side == "bottom") {
place(loc_x+1.5,-(wallthick+gap)+wallthick/2,loc_z-3,6,8,rotation,side)
rotate([90,0,0]) long_slot(6,8,wallthick);
}
if(class == "video" && type == "hdmi_micro" && rotation == 90 && side == "bottom") {
place(width-(wallthick+gap)-8-wallthick/2,loc_y+1.25,loc_z-3,6,8,rotation,side)
rotate([90,0,0]) long_slot(6,8,wallthick);
}
if(class == "video" && type == "hdmi_micro" && rotation == 180 && side == "bottom") {
place(loc_x-1,depth-(wallthick+gap)-8-wallthick/2,loc_z-3,6,8,rotation,side)
rotate([90,0,0]) long_slot(6,8,wallthick);
}
if(class == "video" && type == "hdmi_micro" && rotation == 270 && side == "bottom") {
place(-gap-wallthick/2,loc_y-.5,loc_z-3,6,8,rotation,side)
rotate([90,0,0]) long_slot(6,8,wallthick);
}
// hdmi mini indent
if(class == "video" && type == "hdmi_mini" && rotation == 0 && side == "top") {
place(loc_x+.5,loc_y-gap-wallthick/2+1,loc_z+1.5,6,10,rotation,side)
rotate([90,0,0]) long_slot(6,10,wallthick);
}
if(class == "video" && type == "hdmi_mini" && rotation == 90 && side == "top") {
place(loc_x-wallthick/2,loc_y+3.5,loc_z+1.5,6,8,rotation,side)
rotate([90,0,0]) long_slot(6,8,wallthick);
}
if(class == "video" && type == "hdmi_mini" && rotation == 180 && side == "top") {
place(loc_x+4.5,loc_y-wallthick/2,loc_z+1.5,6,10,rotation,side)
rotate([90,0,0]) long_slot(6,10,wallthick);
}
if(class == "video" && type == "hdmi_mini" && rotation == 270 && side == "top") {
place(loc_x+wallthick/2,loc_y+1.5,loc_z+1.5,6,8,rotation,side)
rotate([90,0,0]) long_slot(6,8,wallthick);
}
if(class == "video" && type == "hdmi_mini" && rotation == 0 && side == "bottom") {
place(loc_x+4.5,loc_y-gap-wallthick/2+1,loc_z-3,6,10,rotation,side)
rotate([90,0,0]) long_slot(6,10,wallthick);
}
if(class == "video" && type == "hdmi_mini" && rotation == 90 && side == "bottom") {
place(loc_x+wallthick/2,loc_y+3.5,loc_z-3,6,8,rotation,side)
rotate([90,0,0]) long_slot(6,8,wallthick);
}
if(class == "video" && type == "hdmi_mini" && rotation == 180 && side == "bottom") {
place(loc_x+.5,loc_y-wallthick/2,loc_z-3,6,10,rotation,side)
rotate([90,0,0]) long_slot(6,10,wallthick);
}
if(class == "video" && type == "hdmi_mini" && rotation == 270 && side == "bottom") {
place(loc_x-wallthick/2,loc_y+1.5,loc_z-3,6,8,rotation,side)
rotate([90,0,0]) long_slot(6,8,wallthick);
}
// power plug indent
if(class == "power" && type == "pwr5.5_7.5x11.5" && rotation == 0 && side == "top") {
place(loc_x+3.75,-(wallthick+gap)+wallthick/2,loc_z+6.25,10,10,rotation,side)
rotate([90,0,0]) cylinder(d=10, h=wallthick);
}
if(class == "power" && type == "pwr5.5_7.5x11.5" && rotation == 90 && side == "top") {
place(-gap-wallthick/2,loc_y-6.25,loc_z+6.25,10,10,rotation,side)
rotate([90,0,0]) cylinder(d=10, h=wallthick);
}
if(class == "power" && type == "pwr5.5_7.5x11.5" && rotation == 180 && side == "top") {
place(loc_x-6.5,depth-10-(wallthick+gap)-wallthick/2,loc_z+6.25,10,10,rotation,side)
rotate([90,0,0]) cylinder(d=10, h=wallthick);
}
if(class == "power" && type == "pwr5.5_7.5x11.5" && rotation == 270 && side == "top") {
place(width-(wallthick+gap)-10-wallthick/2,loc_y+3.75,loc_z+6.25,10,10,rotation,side)
rotate([90,0,0]) cylinder(d=10, h=wallthick);
}
if(class == "power" && type == "pwr2.5_5x7.5" && rotation == 0 && side == "top") {
place(loc_x+2.75,-(wallthick+gap)+wallthick/2,loc_z+2.1,7,7,rotation,side)
rotate([90,0,0]) cylinder(d=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]) long_slot(6,8,wallthick);
}
if(class == "usb2" && type == "micro" && rotation == 90 && side == "top") {
place(-gap-wallthick/2,loc_y+1.5,loc_z+1.9,6,8,rotation,side)
rotate([90,0,0]) long_slot(6,8,wallthick);
}
if(class == "usb2" && type == "micro" && rotation == 180 && side == "top") {
place(loc_x+1.5,depth-(wallthick+gap)-8-wallthick/2,loc_z+1.9,6,8,rotation,side)
rotate([90,0,0]) long_slot(6,8,wallthick);
}
if(class == "usb2" && type == "micro" && rotation == 270 && side == "top") {
place(width-(wallthick+gap)-8-wallthick/2,loc_y-.5,loc_z+1.9,6,8,rotation,side)
rotate([90,0,0]) long_slot(6,8,wallthick);
}
if(class == "usb2" && type == "micro" && rotation == 0 && side == "bottom") {
place(loc_x+1.5,-(wallthick+gap)+wallthick/2,loc_z-3.25,6,8,rotation,side)
rotate([90,0,0]) long_slot(6,8,wallthick);
}
if(class == "usb2" && type == "micro" && rotation == 90 && side == "bottom") {
place(width-(wallthick+gap)-8-wallthick/2,loc_y+1.5,loc_z-3.25,6,8,rotation,side)
rotate([90,0,0]) long_slot(6,8,wallthick);
}
if(class == "usb2" && type == "micro" && rotation == 180 && side == "bottom") {
place(loc_x-.5,depth-(wallthick+gap)-8-wallthick/2,loc_z-3.25,6,8,rotation,side)
rotate([90,0,0]) long_slot(6,8,wallthick);
}
if(class == "usb2" && type == "micro" && rotation == 270 && side == "bottom") {
place(-gap-wallthick/2,loc_y-.5,loc_z-3.25,6,8,rotation,side)
rotate([90,0,0]) long_slot(6,8,wallthick);
}
// single horizontal usbc indent
if(class == "usbc" && type == "single_horizontal" && rotation == 0 && side == "top") {
place(loc_x+.5,-(wallthick+gap)+wallthick/2,loc_z+1.75,6,8,rotation,side)
rotate([90,0,0]) long_slot(6,8,wallthick);
}
if(class == "usbc" && type == "single_horizontal" && rotation == 90 && side == "top") {
place(-gap-wallthick/2,loc_y+2.5,loc_z+1.75,6,8,rotation,side)
rotate([90,0,0]) long_slot(6,8,wallthick);
}
if(class == "usbc" && type == "single_horizontal" && rotation == 180 && side == "top") {
place(loc_x+2.5,depth-(wallthick+gap)-8-wallthick/2,loc_z+2,6,8,rotation,side)
rotate([90,0,0]) long_slot(6,8,wallthick);
}
if(class == "usbc" && type == "single_horizontal" && rotation == 270 && side == "top") {
place(width-(wallthick+gap)-8-wallthick/2,loc_y+.5,loc_z+1.75,6,8,rotation,side)
rotate([90,0,0]) long_slot(6,8,wallthick);
}
if(class == "usbc" && type == "single_horizontal" && rotation == 0 && side == "bottom") {
place(loc_x+2.75,-(wallthick+gap)+wallthick/2,loc_z-3.25,6,8,rotation,side)
rotate([90,0,0]) long_slot(6,8,wallthick);
}
if(class == "usbc" && type == "single_horizontal" && rotation == 90 && side == "bottom") {
place(width-(wallthick+gap)-8-wallthick/2,loc_y+2.5,loc_z-3.25,6,8,rotation,side)
rotate([90,0,0]) long_slot(6,8,wallthick-(wallthick+gap)+wallthick/2);
}
if(class == "usbc" && type == "single_horizontal" && rotation == 180 && side == "bottom") {
place(loc_x+.5,depth-(wallthick+gap)-8-wallthick/2,loc_z-3.25,6,8,rotation,side)
rotate([90,0,0]) long_slot(6,8,wallthick);
}
if(class == "usbc" && type == "single_horizontal" && rotation == 270 && side == "bottom") {
place(-gap-wallthick/2,loc_y+.5,loc_z-3.25,6,8,rotation,side)
rotate([90,0,0]) long_slot(6,8,wallthick);
}
// audio jack indent
if(class == "audio" && type == "jack_3.5" && rotation == 0 && side == "top") {
place(loc_x+3.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);
}
}

300
mod/parametric_move.scad Normal file
View File

@@ -0,0 +1,300 @@
/*
This file is part of SBC Case Builder https://github.com/hominoids/SBC_Case_Builder
Copyright 2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
NAME: parametric_move_add
DESCRIPTION: places parametric additive objects
TODO: none
USAGE: parametric_move_add(type, loc_x, loc_y, loc_z, face, rotation, parametric[], size[], data[], mask[])
type = component type
loc_x = x location placement
loc_y = y location placement
loc_z = z location placement
face = "top", "bottom", "left", "right", "front", "rear"
rotation[] = object rotation
parametric[] = parametric movement array
size[] = size array x,y,z
data[] = data filed
mask[0] = true enables component mask
mask[1] = mask length
mask[2] = mask setback
mask[3] = mstyle "default"
*/
module parametric_move_add(type, loc_x, loc_y, loc_z, face, rotation, parametric, size, data, mask) {
// absolute no parametrics
if(parametric[1] == false && parametric[2] == false && parametric[3] == false) {
add(type, loc_x, loc_y, loc_z, face, rotation, size, data, mask);
}
// x axis accessory parametrics
if(parametric[1] == true && parametric[2] == false && parametric[3] == false) {
if(parametric[0] == "case") {
add(type, loc_x+case_offset_x, loc_y, loc_z, face, rotation, size, data, mask);
}
if(parametric[0] == "sbc") {
add(type, loc_x+pcb_loc_x, loc_y, loc_z, face, rotation, size, data, mask);
}
}
// y axis accessory parametrics
if(parametric[1] == false && parametric[2] == true && parametric[3] == false) {
if(parametric[0] == "case") {
add(type, loc_x, loc_y+case_offset_y, loc_z, face, rotation, size, data, mask);
}
if(parametric[0] == "sbc") {
add(type, loc_x, loc_y+pcb_loc_y, loc_z, face, rotation, size, data, mask);
}
}
// z axis accessory parametrics
if(parametric[1] == false && parametric[2] == false && parametric[3] == true) {
if(parametric[0] == "case" && face == "top") {
add(type, loc_x, loc_y, loc_z+case_offset_tz+case_offset_bz, face, rotation, size, data, mask);
}
if(parametric[0] == "case" && face == "bottom") {
add(type, loc_x, loc_y, loc_z+case_offset_bz, face, rotation, size, data, mask);
}
if(parametric[0] == "case" && face != "bottom" && face != "top") {
add(type, loc_x, loc_y, loc_z, face, rotation, size, data, mask);
}
if(parametric[0] == "sbc") {
add(type, loc_x, loc_y, loc_z+pcb_loc_z+case_offset_bz, face, rotation, size, data, mask);
}
if(parametric[0] == "sbc-case_z" && face == "top") {
add(type, loc_x, loc_y, loc_z+case_offset_tz+case_offset_bz, face, rotation, size, data, mask);
}
if(parametric[0] == "sbc-case_z" && face == "bottom") {
add(type, loc_x, loc_y, loc_z+case_offset_bz, face, rotation, size, data, mask);
}
}
// xy axis accessory parametrics
if(parametric[1] == true && parametric[2] == true && parametric[3] == false) {
if(parametric[0] == "case") {
add(type, loc_x+case_offset_x, loc_y+case_offset_y, loc_z, face, rotation, size, data, mask);
}
if(parametric[0] == "sbc") {
add(type, loc_x+pcb_loc_x, loc_y+pcb_loc_y, loc_z, face, rotation, size, data, mask);
}
}
// xz axis accessory parametrics
if(parametric[1] == true && parametric[2] == false && parametric[3] == true) {
if(parametric[0] == "case" && face == "top") {
add(type, loc_x+case_offset_x, loc_y, loc_z+case_offset_tz+case_offset_bz, face, rotation, size, data, mask);
}
if(parametric[0] == "case" && face == "bottom") {
add(type, loc_x+case_offset_x, loc_y, loc_z+case_offset_bz, face, rotation, size, data, mask);
}
if(parametric[0] == "case" && face != "bottom" && face != "top") {
add(type, loc_x+case_offset_x, loc_y, loc_z, face, rotation, size, data, mask);
}
if(parametric[0] == "sbc") {
add(type, loc_x+pcb_loc_x, loc_y, loc_z+pcb_loc_z+case_offset_bz, face, rotation, size, data, mask);
}
if(parametric[0] == "sbc-case_z" && face == "top") {
add(type, loc_x+pcb_loc_x, loc_y, loc_z+case_offset_tz+case_offset_bz, face, rotation, size, data, mask);
}
if(parametric[0] == "sbc-case_z" && face == "bottom") {
add(type, loc_x+pcb_loc_x, loc_y, loc_z+case_offset_bz, face, rotation, size, data, mask);
}
}
// yz axis accessory parametrics
if(parametric[1] == false && parametric[2] == true && parametric[3] == true) {
if(parametric[0] == "case" && face == "top") {
add(type, loc_x, loc_y+case_offset_y, loc_z+case_offset_tz+case_offset_bz, face, rotation, size, data, mask);
}
if(parametric[0] == "case" && face == "bottom") {
add(type, loc_x, loc_y+case_offset_y, loc_z+case_offset_bz, face, rotation, size, data, mask);
}
if(parametric[0] == "case" && face != "bottom" && face != "top") {
add(type, loc_x, loc_y+case_offset_y, loc_z, face, rotation, size, data, mask);
}
if(parametric[0] == "sbc") {
add(type, loc_x, loc_y+pcb_loc_y, loc_z+pcb_loc_z+case_offset_bz, face, rotation, size, data, mask);
}
if(parametric[0] == "sbc-case_z" && face == "top") {
add(type, loc_x,loc_y+pcb_loc_y, loc_z+case_offset_tz+case_offset_bz, face, rotation, size, data, mask);
}
if(parametric[0] == "sbc-case_z" && face == "bottom") {
add(type, loc_x, loc_y+pcb_loc_y, loc_z+case_offset_bz, face, rotation, size, data, mask);
}
}
// xyz axis accessory parametrics
if(parametric[1] == true && parametric[2] == true && parametric[3] == true) {
if(parametric[0] == "case" && face == "top") {
add(type, loc_x+case_offset_x, loc_y+case_offset_y, loc_z+case_offset_tz+case_offset_bz, face, rotation, size, data, mask);
}
if(parametric[0] == "case" && face == "bottom") {
add(type, loc_x+case_offset_x, loc_y+case_offset_y, loc_z+case_offset_bz, face, rotation, size, data, mask);
}
if(parametric[0] == "case" && face != "bottom" && face != "top") {
add(type, loc_x+case_offset_x, loc_y+case_offset_y, loc_z, face, rotation, size, data, mask);
}
if(parametric[0] == "sbc") {
add(type, loc_x+pcb_loc_x, loc_y+pcb_loc_y, loc_z+pcb_loc_z+case_offset_bz, face, rotation, size, data, mask);
}
if(parametric[0] == "sbc-case_z" && face == "top") {
add(type, loc_x+pcb_loc_x, loc_y+pcb_loc_y, loc_z+case_offset_tz+case_offset_bz, face, rotation, size, data, mask);
}
if(parametric[0] == "sbc-case_z" && face == "bottom") {
add(type, loc_x+pcb_loc_x, loc_y+pcb_loc_y, loc_z+case_offset_bz, face, rotation, size, data, mask);
}
}
}
/*
NAME: parametric_move_sub
DESCRIPTION: places parametric subtractive objects
TODO: none
USAGE: parametric_move_sub(type, loc_x, loc_y, loc_z, face, rotation, parametric[], size[], data[], mask[])
type = component type
loc_x = x location placement
loc_y = y location placement
loc_z = z location placement
face = "top", "bottom", "left", "right", "front", "rear"
rotation[] = object rotation
parametric[] = parametric movement array
size[] = size array x,y,z
mask[0] = true enables component mask
mask[1] = mask length
mask[2] = mask setback
mask[3] = mstyle "default"
*/
module parametric_move_sub(type, loc_x, loc_y, loc_z, face, rotation, parametric, size, data, mask) {
// absolute no parametrics
if(parametric[1] == false && parametric[2] == false && parametric[3] == false) {
sub(type, loc_x, loc_y, loc_z, face, rotation, size, data, mask);
}
// x axis accessory parametrics
if(parametric[1] == true && parametric[2] == false && parametric[3] == false) {
if(parametric[0] == "case") {
sub(type, loc_x+case_offset_x, loc_y, loc_z, face, rotation, size, data, mask);
}
if(parametric[0] == "sbc") {
sub(type, loc_x+pcb_loc_x, loc_y, loc_z, face, rotation, size, data, mask);
}
}
// y axis accessory parametrics
if(parametric[1] == false && parametric[2] == true && parametric[3] == false) {
if(parametric[0] == "case") {
sub(type, loc_x, loc_y+case_offset_y, loc_z, face, rotation, size, data, mask);
}
if(parametric[0] == "sbc") {
sub(type, loc_x, loc_y+pcb_loc_y, loc_z, face, rotation, size, data, mask);
}
}
// z axis accessory parametrics
if(parametric[1] == false && parametric[2] == false && parametric[3] == true) {
if(parametric[0] == "case" && face == "top") {
sub(type, loc_x, loc_y, loc_z+case_offset_tz+case_offset_bz, face, rotation, size, data, mask);
}
if(parametric[0] == "case" && face == "bottom") {
sub(type, loc_x, loc_y, loc_z+case_offset_bz, face, rotation, size, data, mask);
}
if(parametric[0] == "case" && face != "bottom" && face != "top") {
sub(type, loc_x, loc_y, loc_z, face, rotation, size, data, mask);
}
if(parametric[0] == "sbc") {
sub(type, loc_x, loc_y, loc_z+pcb_loc_z, face, rotation, size, data, mask);
}
if(parametric[0] == "sbc-case_z" && face == "top") {
sub(type, loc_x, loc_y, loc_z+case_offset_tz+case_offset_bz, face, rotation, size, data, mask);
}
if(parametric[0] == "sbc-case_z" && face == "bottom") {
sub(type, loc_x, loc_y, loc_z+case_offset_bz, face, rotation, size, data, mask);
}
}
// xy axis accessory parametrics
if(parametric[1] == true && parametric[2] == true && parametric[3] == false) {
if(parametric[0] == "case") {
sub(type, loc_x+case_offset_x, loc_y+case_offset_y, loc_z, face, rotation, size, data, mask);
}
if(parametric[0] == "sbc") {
sub(type, loc_x+pcb_loc_x, loc_y+pcb_loc_y,loc_z, face, rotation, size, data, mask);
}
}
// xz axis accessory parametrics
if(parametric[1] == true && parametric[2] == false && parametric[3] == true) {
if(parametric[0] == "case" && face == "top") {
sub(type, loc_x+case_offset_x, loc_y, loc_z+case_offset_tz+case_offset_bz, face, rotation, size, data, mask);
}
if(parametric[0] == "case" && face == "bottom") {
sub(type, loc_x+case_offset_x, loc_y, loc_z+case_offset_bz, face, rotation, size, data, mask);
}
if(parametric[0] == "case" && face != "bottom" && face != "top") {
sub(type, loc_x+case_offset_x, loc_y, loc_z, face, rotation, size, data, mask);
}
if(parametric[0] == "sbc") {
sub(type, loc_x+pcb_loc_x, loc_y, loc_z+pcb_loc_z, face, rotation, size, data, mask);
}
if(parametric[0] == "sbc-case_z" && face == "top") {
sub(type, loc_x+pcb_loc_x, loc_y, loc_z+case_offset_tz+case_offset_bz, face, rotation, size, data, mask);
}
if(parametric[0] == "sbc-case_z" && face == "bottom") {
sub(type, loc_x+pcb_loc_x, loc_y, loc_z+case_offset_bz, face, rotation, size, data, mask);
}
}
// yz axis accessory parametrics
if(parametric[1] == false && parametric[2] == true && parametric[3] == true) {
if(parametric[0] == "case" && face == "top") {
sub(type, loc_x, loc_y+case_offset_y, loc_z+case_offset_tz+case_offset_bz, face, rotation, size, data, mask);
}
if(parametric[0] == "case" && face == "bottom") {
sub(type, loc_x, loc_y+case_offset_y, loc_z+case_offset_bz, face, rotation, size, data, mask);
}
if(parametric[0] == "case" && face != "bottom" && face != "top") {
sub(type, loc_x, loc_y+case_offset_y, loc_z, face, rotation, size, data, mask);
}
if(parametric[0] == "sbc") {
sub(type, loc_x, loc_y+pcb_loc_y, loc_z+pcb_loc_z, face, rotation, size, data, mask);
}
if(parametric[0] == "sbc-case_z" && face == "top") {
sub(type, loc_x, loc_y+pcb_loc_y, loc_z+case_offset_tz+case_offset_bz, face, rotation, size, data, mask);
}
if(parametric[0] == "sbc-case_z" && face == "bottom") {
sub(type, loc_x, loc_y+pcb_loc_y, loc_z+case_offset_bz, face, rotation, size, data, mask);
}
}
// xyz axis accessory parametrics
if(parametric[1] == true && parametric[2] == true && parametric[3] == true) {
if(parametric[0] == "case" && face == "top") {
sub(type, loc_x+case_offset_x, loc_y+case_offset_y, loc_z+case_offset_tz+case_offset_bz, face, rotation, size, data, mask);
}
if(parametric[0] == "case" && face == "bottom") {
sub(type, loc_x+case_offset_x, loc_y+case_offset_y, loc_z+case_offset_bz, face, rotation, size, data, mask);
}
if(parametric[0] == "case" && face != "bottom" && face != "top") {
sub(type, loc_x+case_offset_x, loc_y+case_offset_y, loc_z, face, rotation, size, data, mask);
}
if(parametric[0] == "sbc") {
sub(type, loc_x+pcb_loc_x, loc_y+pcb_loc_y, loc_z+pcb_loc_z, face, rotation, size, data, mask);
}
if(parametric[0] == "sbc-case_z" && face == "top") {
sub(type, loc_x+pcb_loc_x, loc_y+pcb_loc_y, loc_z+case_offset_tz+case_offset_bz, face, rotation, size, data, mask);
}
if(parametric[0] == "sbc-case_z" && face == "bottom") {
sub(type, loc_x+pcb_loc_x, loc_y+pcb_loc_y, loc_z+case_offset_bz, face, rotation, size, data, mask);
}
}
}

66
mod/place.scad Normal file
View File

@@ -0,0 +1,66 @@
/*
This file is part of SBC Case Builder https://github.com/hominoids/SBC_Case_Builder
Copyright 2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
NAME: place
DESCRIPTION: transformation to place objects on either side of a geometric plane of a given thickness
TODO: none
USAGE: place(x, y, z, size_x, size_y, rotation, side)
*/
/* placement module *must be first* for children() */
module place(x, y, z, size_x, size_y, rotation, side) {
if (side == "top") {
if (rotation == 0 || rotation == 90 || rotation == 180 || rotation == 270) {
if ((rotation >= 0 && rotation < 90) || (rotation < -270 && rotation > -360))
translate([x,y,z]) rotate([0,0,-rotation]) children();
if ((rotation >= 90 && rotation < 180) || (rotation < -180 && rotation >= -270))
translate([x,y+size_x,z]) rotate([0,0,-rotation]) children();
if ((rotation >= 180 && rotation < 270) || (rotation < -90 && rotation >= -180))
translate([x+size_x,y+size_y,z]) rotate([0,0,-rotation]) children(0);
if ((rotation >= 270 && rotation < 360) || (rotation < 0 && rotation >= -90))
translate([x+size_y,y,z]) rotate([0,0,-rotation]) children(); }
else {
translate([x,y,z]) rotate([0,0,-rotation]) children();
}
}
if (side == "bottom") {
if (rotation == 0 || rotation == 90 || rotation == 180 || rotation == 270) {
if ((rotation >= 0 && rotation < 90) || (rotation < -270 && rotation > -360))
translate([x+size_x,y,z]) rotate([0,180,rotation]) children();
if ((rotation >= 90 && rotation < 180) || (rotation < -180 && rotation >= -270))
translate([x+size_y,y+size_x,z]) rotate([0,180,rotation]) children();
if ((rotation >= 180 && rotation < 270) || (rotation < -90 && rotation >= -180))
translate([x,y+size_y,z]) rotate([0,180,rotation]) children();
if ((rotation >= 270 && rotation < 360) || (rotation < 0 && rotation >= -90))
translate([x,y,z]) rotate([0,180,rotation]) children(); }
else {
translate([x,y,z]) rotate([0,180,rotation]) children();
}
}
children([1:1:$children-1]);
}

84
mod/sub.scad Normal file
View File

@@ -0,0 +1,84 @@
/*
This file is part of SBC Case Builder https://github.com/hominoids/SBC_Case_Builder
Copyright 2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
NAME: sub
DESCRIPTION: places subtractive objects
TODO: none
USAGE: sub(type, loc_x, loc_y, loc_z, face, rotation, size[], data[], mask[])
type = component type
loc_x = x location placement
loc_y = y location placement
loc_z = z location placement
face = "top", "bottom", "left", "right", "front", "rear"
rotation[] = object rotation
parametric[] = parametric movement array
size[] = size array x,y,z
data[] = data variable on type
mask[0] = true enables component mask
mask[1] = mask length
mask[2] = mask setback
mask[3] = mstyle "default"
*/
module sub(type, loc_x, loc_y, loc_z, face, rotation, size, data, mask) {
size_x = size[0];
size_y = size[1];
size_z = size[2];
enablemask = mask[0];
mlen = mask[1];
msetback = mask[2];
mstyle = mask[3];
if(type == "art") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) art(data[0],data[1],data[2]);
}
if(type == "fan_mask") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) fan_mask(size_x, size_z, data[0]);
}
if(type == "hd_holes") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) hd_bottom_holes(data[0],data[1],data[2],data[3]);
}
if(type == "knockout") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) knockout(size_x,size_y,data[0],size_z,data[1],data[2]);
}
if(type == "rectangle") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) slab_r([size_x,size_y,size_z],data[0]);
}
if(type == "round") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) cylinder(d=size_x,h=size_z);
}
if(type == "slot") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) slot(size_x,size_y,size_z);
}
if(type == "sphere") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) sphere(d=size_x);
}
if(type == "text") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) linear_extrude(height = size_z) text(data_2, size=data[0]);
}
if(type == "vent") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) vent(size_x,size_y,size_z,data[3],data[0],data[1],data[2]);
}
if(type == "vent_hex") {
translate([loc_x,loc_y,loc_z]) rotate(rotation) vent_hex(size_x,size_y,size_z,data[0],data[1],data[2]);
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff