Compare commits
115 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1a94eabd39 | |||
| 480afbf2db | |||
|
|
760e0e6bdd | ||
|
|
d7e70658f3 | ||
|
|
4f42b9a3db | ||
|
|
60ca7f47bb | ||
|
|
054dbb9edc | ||
|
|
12c99bee77 | ||
|
|
3aa7e5837a | ||
|
|
9a037db8a4 | ||
|
|
5a15316530 | ||
|
|
d5d63e54a2 | ||
|
|
f5dd71ec29 | ||
|
|
d502252d2e | ||
|
|
13ccfc6357 | ||
|
|
d254f162c1 | ||
|
|
ed077d5039 | ||
|
|
71034dee85 | ||
|
|
b221fabed5 | ||
|
|
728b8398f9 | ||
|
|
1c64305276 | ||
|
|
1b8a47361b | ||
|
|
8d2ebd4f94 | ||
|
|
0d28ebbc88 | ||
|
|
35825add61 | ||
|
|
0aff56b70c | ||
|
|
c3ec2837ed | ||
|
|
cd05ff7528 | ||
|
|
93b4de0444 | ||
|
|
9f11e2884e | ||
|
|
c09d444913 | ||
|
|
5b03cd94fc | ||
|
|
63ea4bae0b | ||
|
|
b6554114ec | ||
|
|
6bc4920bea | ||
|
|
ca26347358 | ||
|
|
859192bd6b | ||
|
|
b48bb23e53 | ||
|
|
5aebb0d549 | ||
|
|
415d5532a1 | ||
|
|
a9e51e25dd | ||
|
|
d7f043e6ed | ||
|
|
2979144e28 | ||
|
|
43f7e0f476 | ||
|
|
a6dd0dcb1d | ||
|
|
3281835ac8 | ||
|
|
2f318b1cce | ||
|
|
86eb912784 | ||
|
|
1c2cf8e00f | ||
|
|
b369665049 | ||
|
|
db43558f9c | ||
|
|
5a56f3d4fc | ||
|
|
5d0242ff1c | ||
|
|
2eea918f4f | ||
|
|
f5793ea453 | ||
|
|
53b242440f | ||
|
|
c151a9047b | ||
|
|
3ce75a345b | ||
|
|
3fee9e59ce | ||
|
|
a999585197 | ||
|
|
2e797dd1fb | ||
|
|
a032839b3b | ||
|
|
6f26ab2f04 | ||
|
|
cd2e77acc9 | ||
|
|
1d97917d46 | ||
|
|
f393da7372 | ||
|
|
d6d6fb6d41 | ||
|
|
c678853a6d | ||
|
|
bb3a1d6f80 | ||
|
|
5456ff54f1 | ||
|
|
b19993d63c | ||
|
|
7e809f2719 | ||
|
|
7adbea7732 | ||
|
|
3586afff2d | ||
|
|
24a454a492 | ||
|
|
c7929e7f6b | ||
|
|
5bd72034e8 | ||
|
|
89b1bf1915 | ||
|
|
1ef63e412d | ||
|
|
be91de94ff | ||
|
|
ad087dbc77 | ||
|
|
8d7b211466 | ||
|
|
cfe140a048 | ||
|
|
9d1cfa396c | ||
|
|
1918a7bbaa | ||
|
|
183e3bee12 | ||
|
|
fba4fc3420 | ||
|
|
8b50011e35 | ||
|
|
aca4c96b1d | ||
|
|
6527951336 | ||
|
|
a4aed16cbc | ||
|
|
8815141155 | ||
|
|
29192ea441 | ||
|
|
6e49f76b4e | ||
|
|
c952df6a28 | ||
|
|
11b869daeb | ||
|
|
82fd693b04 | ||
|
|
45c4f7e97f | ||
|
|
9511f0263b | ||
|
|
a151de9575 | ||
|
|
319bbe516e | ||
|
|
f8684b715f | ||
|
|
d233f4c9c8 | ||
|
|
9516fc4d03 | ||
|
|
a6e8e1d147 | ||
|
|
62d6d15389 | ||
|
|
ba9832a972 | ||
|
|
0dcc224da2 | ||
|
|
c9ad238b9f | ||
|
|
1c33a21f3d | ||
|
|
513712fcf9 | ||
|
|
a88ac9457e | ||
|
|
1f2bb6613a | ||
|
|
a3f576edb9 | ||
|
|
ddd7c0b4bd |
423
README.md
423
README.md
@@ -19,7 +19,9 @@ License: GPLv3.
|
||||
git submodule update
|
||||
|
||||
```
|
||||
NOTE: The submodule *SBC Model Framework* needs to be updated anytime SBC Case Builder is updated.
|
||||
|
||||
|
||||
## SBC Case Builder Features:
|
||||
- Autonomous Multi-SBC, Multi-Case Parametric Generation
|
||||
- Autonomous SBC and Accessory Model I/O Openings
|
||||
@@ -32,7 +34,12 @@ License: GPLv3.
|
||||
- SBC Associations
|
||||
- SBC_X,Y - Case_Z Association
|
||||
- Graphical User Interface
|
||||
- SBC Model Framework Validation Tool
|
||||
- SBC Meta Data Access
|
||||
- Individual Standoff Parameter Control
|
||||
- Dynamic Heatsink Fan Size, Vent and Mask Openings
|
||||
- Top and Bottom Case Cover Patterns
|
||||
- Parametric Bottom Access Panel
|
||||
|
||||
|
||||
### Base Case Designs:
|
||||
- Shell - complete
|
||||
@@ -49,50 +56,130 @@ License: GPLv3.
|
||||
- Paper, Folded - complete
|
||||
- Standard MB SBC Adapters & io plates - completed
|
||||
+ SSI-EEB, SSI-CEB, ATX, Micro-ATX, DTX, Flex-ATX, Mini-DTX, Mini-Itx, Mini-ITX Thin, Mini-STX, Mini-STX Thin
|
||||
- Standard MB Cases - completed
|
||||
- Standard MB Cases - complete
|
||||
+ SSI-EEB, SSI-CEB, ATX, Micro-ATX, DTX, Flex-ATX, Mini-DTX, Mini-ITX, Mini-ITX Thin, Mini-STX, Mini-STX Thin, Nano-ITX, NUC, Pico-ITX
|
||||
- Sheet Metal, Folded
|
||||
- NAS - panel_nas complete
|
||||
- Rack - 1U and 2U complete
|
||||
- Stacked Levels
|
||||
- Sliding
|
||||
- Cylinder
|
||||
- Free Form
|
||||
- NAS
|
||||
- Rack
|
||||
- Sheet Metal, Folded
|
||||
- CNC Cases
|
||||
|
||||
All case data is stored in the json file sbc_case_builder.json with the accessory data stored in a separate file structure in sbc_case_builder_accessories.cfg. An accessory group name for a given case is stored as part of the case data in the json file. This allows for the reuse or sharing of an accessory set by different cases and can be used to manage groups of accessories.
|
||||
|
||||
Variable height automated SBC standoffs, which can be individually adjusted, are also implemented to integrate add-on PCB, hats, heatsinks or other accessories that share SBC standoffs for mounting.
|
||||
|
||||
Multi-associative parametric positioning of accessories is implemented and allows each accessory to enable or disable parametric movement of the accessory for each axis. The XY and Z axis can be associated with the case offset (size), SBC positioning, multi-associated axises or absolute positioning. For instance, a SBC fan opening needs to follow the SBC in the X and Y axis but the case Z axis for the correct height.
|
||||
```
|
||||
p
|
||||
a
|
||||
r
|
||||
r a s
|
||||
o m e
|
||||
t e s s s l t m
|
||||
c l l l a t i i i e s
|
||||
l t o o o f t r z z z d m n b t
|
||||
a y c c c a i i e e e a a g a y
|
||||
s p c o c t s t c l
|
||||
s, e, x, y, z, e, n, s, x,y,z, a, k h k e
|
||||
|
||||
"sub","fan",10,10,24.5,"top",[0,0,0],["sbc-case_z",true,true,true],[40,0,6],[0],[true,10,2,"default"],
|
||||
## Graphical User Interface
|
||||
The GUI has multiple tabs that control what model and case is displayed, how it is presented, its adjustments, options and associated accessories. There are separate tabs in the GUI for *Folded Case Adjustments*, *Standard Motherboard Case Adjustments* and *3D Case Adjustments*. The first two have unique settings that only apply to the respective case designs. 3D case adjustments affect all others case designs and some entries can also affect Folded and Standard Motherboard cases as well. There are three groups of two tabs each associated with SBC, Extended Case and Multi-PCB standoffs.
|
||||
|
||||

|
||||
|
||||
### View Tab
|
||||
The View Tab allows the selection of various viewing modes and the selection of the device model for which a case is being generated. The *view* pickbox allows the respective case to be displayed as a 3D model, platter for 3D printing and as an individual case part, which can be selected using the *individual part* pickbox. The *section part* checkbox sections the selected part for dxf or other 2D export. The *sbc model* pickbox selects the device (SBC, MCU, Motherboard, etc). The *sbc off* and *sbc information* are self explanatory. The *sbc highlight* shows the subtractive openings that are being automatically created by SBC Model Framework while the *accessory highlight* shows the subtractive openings being generated by entries in the file sbc_case_builder_accessories.cfg. The later is useful when trying to visually place a subtractive accessory.
|
||||
|
||||
|
||||
### Folded Case Adjustments Tab
|
||||
This tab exclusively deals with folded cases. At this time the bend allowance equations are not complete and limits its use to paper and other thin materials with a low bend radius. Once folded metal cases are implemented the bend allowance equations will be complete and allow for any bendable material of any given bend radius. With that said, these adjustments are used for the paper_full-top and paper_split-top case designs and the *material thickness* and *bend Allowance* adjustments still need to be set appropriately for proper use. The *bottom clearance* adjustment allows additional bottom height adjustment for those wishing to use user provided standoffs on the bottom of the device for better stability. The *flat blank section* checkbox generates a flat blank based on the aforementioned settings. Once it has been generated the model must be rendered(F6) to produce a 2D blank that can then be exported as a DXF or SVG file for printing or fed to a CNC cutter.
|
||||
|
||||
|
||||
### Standard Motherboard Case Adjustments Tab
|
||||
Both standard motherboard adapters and cases can be generated with SBC Case Builder and this tab controls the specific settings. Since it is not possible to know the motherboard thickness it is set to 2mm and the *standard motherboard thickness* setting is used to add or subtract thickness for an accurate representation of the user provided PCB. The *rear io shield* setting is only used when generating full cases and is not needed when generating adapters and io shields. Most of the adjustments in the *3D Case Adjustments* tab also work for motherboard adapters which allows for the SBC or other device to be repositioned on the adapter while providing the full use of the accessory subsystem. Any accessory entries in the sbc_case_builder_accessories.cfg file should reference the bottom face. The *bottom cover pattern* in the *Fan and Vent Openings* tab and the *SBC Bottom Standoff* tabs also apply to motherboard adapters. There are predefined example cases and adapters available in the GUI for further reference.
|
||||
|
||||
|
||||
### Rack Mount Case Adjustments Tab
|
||||
Both 1U and 2U, 10" and 19", rack cases are configured in this tab. The first entry *rack width* selects if 10" or 19" rack cases are being created. The *rack size* sets whether 1U or 2U. There is a 2mm wall in front of every removable bay. *removable bay height* allows the tray height to be reduced to form an opening which allows for tray removal and venting when installed with other rack cases above. The remaining tab is divided into six groups of settings each representing a virtual bay. Each bay group specifies the SBC thru the pickbox *Rack Bay1* respectively. With *rack bay1 xyz loc* and *rack bay1 rotation determining the position and z-axis rotation. The type of bay is set in the *rack bay1 face* pickbox followed by two checkboxes for the internal dividing wall, rear fan and a bay conduit selection pickbox.
|
||||
|
||||
|
||||
### 3D Case Adjustments Tab
|
||||
The *3D Case Adjustments* tab makes up the bulk of the possible case adjustments for 3D printed cases. Most of the entries in this tab are self explanatory. The *pcb loc* adjustments allow the selected device model to be moved in the case design, the *case offset* adjustments increase the selected case design dimensions. The *wallthick*, *floorthick* and *sidethick* adjust their respective areas. Do note that the *floorthick* adjustment also determines the ceiling thickness for all case designs and the *sidethick* only affects the tray_sides, tray_vu5, tray_vu7 case designs. The *gap* entry is the distance between the device PCB and the sidewall of the case design. The *tol* adjustment, located at the bottom of the tab, is a tolerance fitment adjustment for the snap, fitted, round and hex case design tops. Adjust accordingly if the tops are too tight or loose.
|
||||
|
||||
|
||||
### Fan and Vent Openings Tab
|
||||
This tab handles the fan and cooling options for case designs. The *top cover pattern*, *bottom cover pattern* and *front cover pattern* contain several options for the creation of vent patterns that cover the complete panel, including a solid covering. The *cooling* pickbox selects fan and vent openings exclusively for the heatsink associated with the device in SBC Model Framework.
|
||||
```
|
||||
disable - turns off the heatsink model and mask
|
||||
off - heatsink model is off, mask is on and default will be used
|
||||
default - heatsink model is on and uses the mask setting in ./SBC_Model_Framework/sbc_models.cfg
|
||||
none - heatsink model is on and mask is off.
|
||||
fan and vent pattern selections - open, fan_open, fan_1, fan_2, fan_hex, vent, vent_hex_5mm, vent_hex_8mm
|
||||
custom - uses the file ./SBC_Model_Framework/customfan.dxf
|
||||
```
|
||||
The *fan size* allows the selection of different fan size masks over the default size selected by 0. The rear fan entries are for the *panel_nas* case design and allow for the same types of fan adjustments as the heatsink. There is also the choice of one or two rear fans as well as additional adjustments for the position and spacing of them.
|
||||
|
||||
|
||||
### Bottom Access Panel Tab
|
||||
This tab allows the creation of a bottom access panel and its entries are self explanatory. Additional access panels can be implemented using the accessory subsystem.
|
||||
|
||||
|
||||
### Options and Accessories
|
||||
The entrys in this tab allow for the enablement and selection of different options and accessories. It includes case indents, GPIO, and UART openings based on their type identifier in SBC_Model_Framework. It also contains hard drive options for the panel_nas case.
|
||||
|
||||
#### GPIO Selections
|
||||
```
|
||||
disable - turns off the GPIO model and mask
|
||||
off - GPIO model is off, mask is on and default will be used
|
||||
default - GPIO model is on and uses the mask setting stored in ./SBC_Model_Framework/sbc_models.cfg
|
||||
none - GPIO model is on and mask is off
|
||||
mask opening selections - open, block, knockout, vent
|
||||
```
|
||||
|
||||
An array holds a string and 3 Boolean that represent which association and axis are enabled for parametric movement. In the accessory example above, the 8th parameter `["sbc-case_z",true,true,true]` means all axises are enabled for multi-associative movement with the X and Y accessory axis following the SBC X and Y axis and the accessory Z axis following the case Z axis. The other currently supported associations are “sbc” and “case”. If other associations of objects are needed or are of value, they can be added in the future. All of the existing cases have been made parametric and can serve as further working examples.
|
||||
#### UART Selections
|
||||
```
|
||||
default - UART model is on and uses the mask setting stored in ./SBC_Model_Framework/sbc_models.cfg
|
||||
none - UART model is on and mask is off
|
||||
mask opening selections - open, knockout
|
||||
```
|
||||
|
||||
## Notes
|
||||
The *indent* checkbox enables indents for a select group of components defined in SBC Model Framework. The currently support components are - video-hmdi_a, video-hdmi_micro, video-hdmi_mini, power-pwr5.5_7.5x11.5, power-pwr2.5_5x7.5, usb2-micro, usbc-single_horizontal, audio-jack_3.5. The *accessory name* pickbox uses the unique accessory group name to associate a given accessory set with a case design. Entries are stored in the file sbc_case_builder_accessories.cfg which is covered in detail with the Accessory Subsystem in this document. The remaining two entries select the color and proportional font used with the *sbc information* display when enabled in the *View* tab.
|
||||
|
||||
Due to the number of possibilities, no pre-compiled case stl’s are included.
|
||||
#### NAS HD Options
|
||||
The *nas sbc location* pickbox allows the positioning of the SBC at the top or bottom of a NAS case. *hd bays* sets the number of drive bays, *hd reverse* checkbox rotates the drives 180 degrees while *hd center* centers the drives in the x-axis. The next entry, *hd space* determines the spacing between drives and *hd y position* and *hd z position* sets the respective axis locations.
|
||||
|
||||
“tol”, located at the bottom of the Adjustments Tab, is a tolerance fitment adjustment for the snap, fitted, round and hex tops. Adjust accordingly if the tops are too tight or loose.
|
||||
#### Accessory Group Name
|
||||
The *accessory name* allows the selection of an accessory group to be associated with the current case. These groups are located in the file sbc_case_builder_accessories.cfg and provide a means to add or subtract geometry, models and add items to the print platter. See the *Accessory Subsystem* area below for further details and use.
|
||||
|
||||
## Case Designs and Styles
|
||||
The case naming convention for standard cases in the configuration file follow the basic form of “sbc”_”design”_”style” e.g. c4_shell or c4_tray_vu5.
|
||||
### Standoff Tabs
|
||||
There are 3 types of standoffs available in the user interface, SBC Standoffs, Extended Case Standoffs and Multi-PCB Standoffs. The SBC standoffs control adjustments for the SBC or pcbid 0 as defined by the entry in SBC Model Framework file ./SBC_Model_Framework/sbc_models.cfg. The Extended Case Standoffs control case corner standoffs when the case exceeds the SBC size by the *SBC Standoff Support Size*. The Multi-PCB standoffs are used for additional PCB in multi-PCB configurations as defined in ./SBC_Model_Framework/sbc_models.cfg e.g. pcbid 1, pcbid 2, etc. All three standoff types have similar controls made up of a global tab and individual Settings tab in the GUI.
|
||||
|
||||
## Accessory Schema
|
||||
The schema for case accessories is documented in the beginning of the file sbc_case_builder_accessories.cfg. There is one fixed entry that is the accessory set name followed by an unlimited number of accessory entries each containing 11 entries.
|
||||
The main difference between the different standoff groups are that the SBC Standoffs are located by the SBC PCB holes, the Extended Case Standoffs are located in the four corners of a case design that exceeds dimensions of the intended device by the size of the *SBC Case Standoff Support Size* and the Multiple PCB Standoffs are located by the holes of the additional PCBs that makeup a given device. The entries for the standoffs are basically the same so only the top SBC standoffs will be specifically covered.
|
||||
|
||||
|
||||
#### Standoff Global Settings
|
||||
The tab *SBC Top Standoff Global Settings* affects all the respective standoffs and starts with three checkboxes. The first, *sbc top standoffs*, enables or disable all the top standoffs. The second, *top standoff reverse*, rotates the standoff 180 degrees and is used primarily for standoffs associated with the top face of all case designs. The last, *top sidewall support*, enables or disables the side wall support for all SBC top standoffs. The first pickbox in the tab is called *top standoff size* and determines the overall size of the SBC top standoffs. It is made up of named sizes that are predefined and a custom entry that is defined by the remaining entries in the tab. The predefined named top standoff sizes are further divided into entries where only the hole size is different e.g. m3, m3+, m3_tap. The m3 entry has a 3mm hole, the m3+ entry's hole is approximately 15% larger for clearance and the m3_tap entry's hole size is the tap drill size. When a named size is selected the *top standoff diameter* and *top standoff hole size* entries have no effect but the remaining entries do apply - it is the *custom* entry that allows full control of all parameters.
|
||||
|
||||
The *top standoff support size* and *top standoff support height* is what allows recessed *top standoff type* entries to work on thin wall
|
||||
floors and ceilings by providing the extra size and depth for the given recess. This applies to the *top standoff type* selections countersunk, recessed and nutholder. The recessed entry also allows for deep recessed screws by recessing the standoff for the full height of the *standoff support height* less 2mm. This can be deployed for tall cases in order to use shorter fasteners and is the most practical way to handle this scenario. The *top standoff insert* checkbox enables the use of inserts of the size defined by *top standoff insert dia* and *top Standoff insert height* at the opposite end of the standoff. This allows case halves to be fastened together thru the bottom of the case and is another alternative to dealing with tall case designs.
|
||||
|
||||
|
||||
#### Standoff Individual Settings
|
||||
The *SBC Top Individual Settings* entries control variable on a per standoff basis. There are four entry groups each controlling a standoff's enablement, height adjustment and sidewall support location. This is useful when dealing with hats or other accessories that share SBC PCB holes for mounting. Likewise, being able to change the direction of the sidewall support allows for a wider choice to strengthen and tie the standoff to the case walls or completely disable them if SBC components interfere. The length of the sidewall support is equal to the respective *standoff support size* for SBC, Extended Case and Multi-PCB standoffs.
|
||||
|
||||
As indicated previously, The SBC Standoffs, Extended Case Standoffs and Multi-PCB Standoffs all work the same with the following exceptions. The *standoff support size* is also used to determine the corner proximity for the Extended Case standoffs. The Multiple PCB Standoffs present a unique challenge due to their nature. There will be situations with multiple PCB devices when not all the standoffs created by the PCB holes will be needed. Imagine two PCBs next to each other that would normally create eight standoffs. In many scenarios only outer standoffs are needed for both the top and bottom and the bottom inner standoffs for PCB support. In order to handle this and many other situations without creating a complex and burdensome GUI, an entry for the creation of the PCB hole can be used to disable the top, bottom or both standoffs. This is accomplished within the SBC Model Framework pcbhole class. The person creating the sbc_models.cfg entry can determine and override the creation of these standoffs in SBC Case Builder. See the SBC Model Framework pcbhole class for further details.
|
||||
|
||||
## Notes, Tips and Things to Check
|
||||
SBC Case Builder by default makes the smallest symmetrical case possible for the SBC selected and default parameters. Most times this works well but some SBC need asymmetrical spacing, extra gap or additional standoff clearance and may require tweaking to obtain the best results. If there is a saved case for an SBC it is best to start your new case with it, or at least become familiar with any special changes made, since they might apply to a new case.
|
||||
|
||||
### Standoff Selection, Inserts and Clearance
|
||||
Standoff selection and implementation is the most effected part of customizing a case. Some SBC can use a M3 screw and others only use a M2.5 or M2 screw. Finding the best fastening approach can be influenced too by the hardware one has on-hand or personal preference. If using inserts, a custom standoff size must be used since the standard standoff sizes are to small for their respective insert diameter. For tall cases, fastener length can be reduced by using a deep recessed standoff, the depth set by the *standoff support height* after selecting a *recessed* type under the appropriate global Tab . Watch for standoff clearance issues around PCB holes and neighboring components. Some SBC designs crowd the area and can interfere with standoff diameter sizes, especially when inserts are being used. This is one factor that may determine whether to fasten the case from the top or bottom.
|
||||
|
||||
### Component Overhang and Case Gap
|
||||
As previously stated, symmetrical cases use the same gap spacing for all sides. This has worked well but more recently many SBC use significantly different component overhangs and could benefit from an asymmetrical case. By increasing the case size by the needed amount in an axis and possibly shifting the PCB the same amount or not, an asymmetrical case gap can be created to accommodate SBC with significantly differing overhangs. This is especially import if opposing sides of an SBC use component overhangs greater then 2mm which may also influence the assembly of the case.
|
||||
|
||||
### Geometry Placement, Alignment and Interference Checking
|
||||
When using subtractive geometry accessories, turning on *accessory highlight* under the *View Tab* will help in placing and aligning objects.
|
||||
Use case sections to view inside a closed case by setting to -1 the *move side* slider under the *View Tab*. Platter view can be useful to view changes and as a final check if everything is configured as required prior to STL export.
|
||||
|
||||
### Using Accessories Dynamically
|
||||
Having SBC Case Builder running while editing the sbc_case_builder_accessories.cfg file using a separate text editor will aide in visual accessory manipulation and placement. OpenSCAD will automatically regenerate the model preview when the accessory configuration files is saved.
|
||||
|
||||
## Accessory Subsystem
|
||||
Case accessories entries are kept in the file sbc_case_builder_accessories.cfg. Newly created accessory group names also need to be added to the variable accessory_name in sbc_models.scad on or around line #128 in order for them to appear in the GUI pickbox. Any new accessory group names must be added to the pickbox entry or they will not be present in the GUI. This can be done manually or the helper script get_customizer_values.scad can be used to generate a complete accessory names list for copy and paste from the console.
|
||||
|
||||
### Accessory Schema
|
||||
Each accessory group consists of a unique name followed by an unlimited number of accessory entries each containing 11 variables.
|
||||
```
|
||||
schema:
|
||||
|
||||
@@ -122,36 +209,37 @@ e.g.
|
||||
"sub","fan",10,10,24.5,"top",[0,0,0],["sbc-case_z",true,true,true],[40,0,6],[0],[true,10,2,"default"],
|
||||
```
|
||||
|
||||
Every type, regardless of it’s class, uses a basic set of variables
|
||||
Every type, regardless of its class, uses a basic set of variables
|
||||
`(loc_x,loc_y,loc_z,”face”,rotation[],parametrics[])`
|
||||
but each type doesn’t necessarily use all available data fields
|
||||
`(size[],data[])`
|
||||
|
||||
The parametric array specifies the axis to enable for associated parametric positoning. An accessory can be associated with the sbc position("sbc"), case offset("case"),multi-associated which use sbc xy postion and case z offset(sbc-case_z) or use absolute values if all axises are false.
|
||||
Multi-associative parametric positioning of accessories is implemented and allows each accessory to enable or disable parametric movement of the accessory for each axis. The XY and Z axis can be associated with the case offset (size), SBC positioning, multi-associated axis's or absolute positioning. For instance, a SBC fan opening needs to follow the SBC in the X and Y axis but the case Z axis for the correct height. The parametric array specifies the axis to enable for associated parametric positioning. An accessory can be associated with the sbc position("sbc"), case offset("case"),multi-associated which use sbc xy position and case z offset("sbc-case_z") or use absolute values if all axis's are false. In the accessory example above, the 8th parameter `["sbc-case_z",true,true,true]` means all axis's are enabled for multi-associative movement with the X and Y accessory axis following the SBC X and Y axis and the accessory Z axis following the case Z axis.
|
||||
|
||||
|
||||
### classes: add1, sub, suball, add2, model, platter
|
||||
|
||||
Class “add1” and “add2” are used to add geometry to the case. The difference is when the addition occurs. “add1” happens at the beginning when the core case geometry is created before any subtractions and add2 happens at the end after all subtractions have occurred. “suball” is used to affect all faces of a case, not just a single face. The “face” is the case piece that will be effected by the addition or subtraction. The "model" class is for placing supporting accessories in the model view. e.g. hard drives, fans. The "platter" class is for adding supporting accessories to the print platter.
|
||||
Class *add1* and *add2* are used to add geometry to the case. The difference is when the addition occurs. *add1* happens at the beginning when the core case geometry is created before any subtractions and *add2* happens at the end after all subtractions have occurred. *suball* is used to affect all faces of a case, not just a single face. The “face” is the case piece that will be effected by the addition or subtraction. The *model* class is for placing supporting accessories in the model view. e.g. hard drives, fans. The *platter* class is for adding supporting accessories, that are not part of the core case geometry, to the print platter for printing e.g. a fan cover or access panel cover.
|
||||
|
||||
|
||||
**additive type:**
|
||||
|
||||
circle, rectangle, slot, text, art, standoff, batt_holder, uart_holder, hd_holder, hd_holes, hd_vertright_holes, hc4_oled_holder, access_panel, button, pcb_holder, boom_grill, boom_speaker_holder
|
||||
art, access_panel, batt_holder, button, button_assembly, fan_cover, feet, grommet, hd_holder, hk_boom_grill, hk_boom_speaker_holder, hk_boom_vring, hk_h3_port_extender_holder, hk_hc4_oled_holder, hk_uart_holder, hk_uart_strap, keyhole, nut_holder, panel_clamp, pcb_holder, rectangle, round, slot, sphere, standoff, text, vent_panel_hex, uart_holder, hc4_oled_holder, button, pcb_holder
|
||||
|
||||
|
||||
**subtractive type:**
|
||||
|
||||
circle, rectangle, slot, text, art, punchout, vent, fan, hd_holes, hd_vertleft_holes, hd_vertright_holes, microusb, sphere
|
||||
art, fan_mask, hd_holes, knockout, rectangle, round, slot, sphere, text, vent, vent_hex
|
||||
|
||||
|
||||
**model type:**
|
||||
|
||||
uart_strap, fan_cover, hd25, hd35, hc4_oled, feet, access_cover, net_card, hk35_lcd, hk_boom, boom_speaker, boom_vring, hk_uart
|
||||
access_cover, adafruit_lcd, dsub, fan, hd25, hd35, hk_boom, hk_boom_speaker, hk_h3_port_extender, hk_hc4_oled, hk35_lcd, hk_m1s_ups, hk_net_card, hk_pwr_button, hk_speaker, hk_uart, hk_vu7c, hk_vu8m, hk_vu8s, hk_wb2, hk_xu4_shifter_shield, pillar, rpi_m2hat, stl_model
|
||||
|
||||
|
||||
**platter type:**
|
||||
|
||||
uart_strap, fan_cover, access_cover, button_assembly, boom_vring
|
||||
access_cover, button_assembly, fan_cover, feet, grommet, hk_boom_vring, hk_h3_port_extender_holder, hk_uart_strap, vent_panel_hex
|
||||
|
||||
|
||||
## Accessory Reference Manual
|
||||
@@ -376,6 +464,35 @@ DESCRIPTION: creates case feet.
|
||||
```
|
||||
|
||||
|
||||
### grommet
|
||||
|
||||
```
|
||||
CLASSES: add1, add2, platter
|
||||
DESCRIPTION: creates different groumet styles.
|
||||
MASK: yes
|
||||
USAGE: "class", "grommet", loc_x, loc_y, loc_z, face, rotation[], parametric[], size[], data[], mask[]
|
||||
|
||||
class = "add1", "add2", "platter"
|
||||
type = "grommet"
|
||||
loc_x = x location placement
|
||||
loc_y = y location placement
|
||||
loc_z = z location placement
|
||||
face = "top", "bottom", "right", "left", "front", "rear"
|
||||
rotation[] = object rotation
|
||||
parametric[] = "case", "sbc", "sbc-case_z"
|
||||
size[0] = od outside diameter of grommet body
|
||||
size[1] = id inside hole diameter of grommet body
|
||||
size[2] = wall thickness of installation
|
||||
data[0] = "top","bottom","front","rear","left","right"
|
||||
data[1] = "sleeve"
|
||||
data[2] = assembled true, false
|
||||
mask[0] = true enables component mask
|
||||
mask[1] = mask length
|
||||
mask[2] = mask setback
|
||||
mask[3] = mstyle "default"
|
||||
```
|
||||
|
||||
|
||||
### hd_holder
|
||||
|
||||
```
|
||||
@@ -679,7 +796,7 @@ DESCRIPTION: creates nut holder of various styles.
|
||||
size[0] = top diameter or x size in mm
|
||||
size[1] = bottom diameter or y size in mm
|
||||
size[2] = holder height in mm
|
||||
data[0] = "m2", "m2.5", "m3", "m4"
|
||||
data[0] = "m2", "m2.5", "m3", "m4", "m3-insert"
|
||||
data[1] = "default", "sloped", "trap"
|
||||
mask[0] = true
|
||||
mask[1] = length
|
||||
@@ -688,6 +805,35 @@ DESCRIPTION: creates nut holder of various styles.
|
||||
```
|
||||
|
||||
|
||||
### panel_clamp
|
||||
|
||||
```
|
||||
CLASSES: add1, add2
|
||||
DESCRIPTION: creates clamps to join two panels.
|
||||
MASK: yes
|
||||
USAGE: "class", "panel_clamp", loc_x, loc_y, loc_z, face, rotation[], parametric[], size[], data[], mask[]
|
||||
|
||||
class = "add1", "add2"
|
||||
type = "panel_clamp"
|
||||
loc_x = x location placement
|
||||
loc_y = y location placement
|
||||
loc_z = z location placement
|
||||
face = "top", "bottom", "right", "left", "front", "rear"
|
||||
rotation[] = object rotation
|
||||
parametric[] = "case", "sbc", "sbc-case_z"
|
||||
size[0] = top diameter or x size in mm
|
||||
size[1] = bottom diameter or y size in mm
|
||||
size[2] = clamp height in mm
|
||||
data[0] = orientation "top","bottom","rear","front","left","right"
|
||||
data[1] = "sloped"
|
||||
data[2] = "m2", "m2.5", "m3", "m4"
|
||||
mask[0] = false
|
||||
mask[1] = length
|
||||
mask[2] = set back
|
||||
mask[3] = mstyle "default", "holes"
|
||||
```
|
||||
|
||||
|
||||
### pcb_holder
|
||||
|
||||
```
|
||||
@@ -998,6 +1144,7 @@ DESCRIPTION: creates hard drive holes for 2.5 and 3.5 drives in various orientat
|
||||
data[1] = "portrait", "landscape"
|
||||
data[2] = "left", "right", "both", "bottom", "all"
|
||||
data[3] = floor thickness
|
||||
data[4] = "hole", "slot"
|
||||
mask[0] = false, not used
|
||||
mask[1] = length
|
||||
mask[2] = set back
|
||||
@@ -1232,16 +1379,66 @@ DESCRIPTION: creates horizontal or vertical hex vent openings.
|
||||
## Model class “types”
|
||||
|
||||
|
||||
### adafruit_lcd
|
||||
### adafruit_2030_powerboost
|
||||
|
||||
```
|
||||
CLASSES: model
|
||||
DESCRIPTION: creates bottom access cover for access panels.
|
||||
DESCRIPTION: creates Adafruit 2030 Powerboost 1000 basic.
|
||||
MASK: yes
|
||||
USAGE: "model", "adafruit_lcd", loc_x, loc_y, loc_z, face, rotation[], parametric[], size[], data[], mask[]
|
||||
USAGE: "model", "adafruit_2030_powerboost", loc_x, loc_y, loc_z, face, rotation[], parametric[], size[], data[], mask[]
|
||||
|
||||
class = "model"
|
||||
type = "adafruit_lcd"
|
||||
type = "adafruit_2030_powerboost"
|
||||
loc_x = x location placement
|
||||
loc_y = y location placement
|
||||
loc_z = z location placement
|
||||
face = "top", "bottom", "right", "left", "front", "rear"
|
||||
rotation[] = object rotation
|
||||
parametric[] = "case", "sbc", "sbc-case_z"
|
||||
size[] = not used
|
||||
data[] = not used
|
||||
mask[0] = true
|
||||
mask[1] = length
|
||||
mask[2] = set back
|
||||
mask[3] = mstyle "default"
|
||||
```
|
||||
|
||||
|
||||
### adafruit_4311_lcd
|
||||
|
||||
```
|
||||
CLASSES: model
|
||||
DESCRIPTION: creates Adafruit 4311 2.0" 320x240 Color IPS TFT Display with microSD Card Breakout - ST7789 EYESPI.
|
||||
MASK: yes
|
||||
USAGE: "model", "adafruit_4311_lcd", loc_x, loc_y, loc_z, face, rotation[], parametric[], size[], data[], mask[]
|
||||
|
||||
class = "model"
|
||||
type = "adafruit_4311_lcd"
|
||||
loc_x = x location placement
|
||||
loc_y = y location placement
|
||||
loc_z = z location placement
|
||||
face = "top", "bottom", "right", "left", "front", "rear"
|
||||
rotation[] = object rotation
|
||||
parametric[] = "case", "sbc", "sbc-case_z"
|
||||
size[] = not used
|
||||
data[] = not used
|
||||
mask[0] = true
|
||||
mask[1] = length
|
||||
mask[2] = set back
|
||||
mask[3] = mstyle "default"
|
||||
```
|
||||
|
||||
|
||||
### adafruit_4755_solar_charger
|
||||
|
||||
```
|
||||
CLASSES: model
|
||||
DESCRIPTION: creates Adafruit 4755 Universal USB/DC/Solar Lithium Ion/Polymer charger - bq24074.
|
||||
MASK: yes
|
||||
USAGE: "model", "adafruit_4755_solar_charger", loc_x, loc_y, loc_z, face, rotation[], parametric[], size[], data[], mask[]
|
||||
|
||||
class = "model"
|
||||
type = "adafruit_4755_solar_charger"
|
||||
loc_x = x location placement
|
||||
loc_y = y location placement
|
||||
loc_z = z location placement
|
||||
@@ -1287,7 +1484,7 @@ DESCRIPTION: creates db connectors.
|
||||
|
||||
```
|
||||
CLASSES: model
|
||||
DESCRIPTION: creates db connectors.
|
||||
DESCRIPTION: creates fans.
|
||||
MASK: yes
|
||||
USAGE: "model", "fan", loc_x, loc_y, loc_z, face, rotation[], parametric[], size[], data[], mask[]
|
||||
|
||||
@@ -1300,7 +1497,7 @@ DESCRIPTION: creates db connectors.
|
||||
rotation[] = object rotation
|
||||
parametric[] = "case", "sbc", "sbc-case_z"
|
||||
size[] = not used
|
||||
data[0] = "box30x10","box40x10","box50x10","box60x10","box80x10","box80x25","box92x10","box92x25","box120x25","box140x25"
|
||||
data[0] = "box25x10","box30x10","box40x10","box50x10","box60x10","box80x10","box80x25","box92x10","box92x25","box120x25","box140x25"
|
||||
mask[0] = true
|
||||
mask[1] = length
|
||||
mask[2] = set back
|
||||
@@ -1763,15 +1960,69 @@ DESCRIPTION: creates hk odroid-xu5 level shifter shield model.
|
||||
```
|
||||
|
||||
|
||||
### pillar
|
||||
|
||||
```
|
||||
CLASSES: model
|
||||
DESCRIPTION: creates pillars with female ends.
|
||||
MASK: yes
|
||||
USAGE: "model", "pillar", loc_x, loc_y, loc_z, face, rotation[], parametric[], size[], data[], mask[]
|
||||
|
||||
class = "model"
|
||||
type = "pillar"
|
||||
loc_x = x location placement
|
||||
loc_y = y location placement
|
||||
loc_z = z location placement
|
||||
face = "top", "bottom", "right", "left", "front", "rear"
|
||||
rotation[] = object rotation
|
||||
parametric[] = "case", "sbc", "sbc-case_z"
|
||||
size[0] = outside diameter
|
||||
size[1] = inside diameter
|
||||
size[2] = height
|
||||
data[0] = "hex", "round"
|
||||
data[1] = "color"
|
||||
data[2] = side "top" or "bottom"
|
||||
mask[0] = false
|
||||
mask[1] = length
|
||||
mask[2] = set back
|
||||
mask[3] = mstyle "default"
|
||||
```
|
||||
|
||||
|
||||
### rpi_m2hat
|
||||
|
||||
```
|
||||
CLASSES: model
|
||||
DESCRIPTION: adds Raspberry Pi M.2 HAT+ M Key model
|
||||
MASK: yes
|
||||
USAGE: "model", "rpi_m2hat", loc_x, loc_y, loc_z, face, rotation[], parametric[], size[], data[], mask[]
|
||||
|
||||
class = "model"
|
||||
type = "rpi_m2hat"
|
||||
loc_x = x location placement
|
||||
loc_y = y location placement
|
||||
loc_z = z location placement
|
||||
face = "top", "bottom", "right", "left", "front", "rear"
|
||||
rotation[] = object rotation
|
||||
parametric[] = "case", "sbc", "sbc-case_z"
|
||||
size[] = not used
|
||||
data[] = not used
|
||||
mask[0] = true, false
|
||||
mask[1] = length
|
||||
mask[2] = set back
|
||||
mask[3] = mstyle "default"
|
||||
```
|
||||
|
||||
|
||||
### stl_model
|
||||
|
||||
```
|
||||
CLASSES: add1, add2
|
||||
CLASSES: model
|
||||
DESCRIPTION: adds stl models.
|
||||
MASK: no
|
||||
USAGE: "class", "stl_model", loc_x, loc_y, loc_z, face, rotation[], parametric[], size[], data[], mask[]
|
||||
USAGE: "model", "stl_model", loc_x, loc_y, loc_z, face, rotation[], parametric[], size[], data[], mask[]
|
||||
|
||||
class = "add1", "add2"
|
||||
class = "model"
|
||||
type = "stl_model"
|
||||
loc_x = x location placement
|
||||
loc_y = y location placement
|
||||
@@ -1781,7 +2032,7 @@ DESCRIPTION: adds stl models.
|
||||
parametric[] = "case", "sbc", "sbc-case_z"
|
||||
size[] = not used
|
||||
data[0] = scale
|
||||
data[1] = "file"
|
||||
data[1] = "file name"
|
||||
mask[0] = false, not used
|
||||
mask[1] = length
|
||||
mask[2] = set back
|
||||
@@ -1900,6 +2151,35 @@ DESCRIPTION: creates case feet.
|
||||
```
|
||||
|
||||
|
||||
### grommet
|
||||
|
||||
```
|
||||
CLASSES: add1, add2, platter
|
||||
DESCRIPTION: creates different groumet styles.
|
||||
MASK: yes
|
||||
USAGE: "class", "grommet", loc_x, loc_y, loc_z, face, rotation[], parametric[], size[], data[], mask[]
|
||||
|
||||
class = "add1", "add2", "platter"
|
||||
type = "grommet"
|
||||
loc_x = x location placement
|
||||
loc_y = y location placement
|
||||
loc_z = z location placement
|
||||
face = "top", "bottom", "right", "left", "front", "rear"
|
||||
rotation[] = object rotation
|
||||
parametric[] = "case", "sbc", "sbc-case_z"
|
||||
size[0] = od outside diameter of grommet body
|
||||
size[1] = id inside hole diameter of grommet body
|
||||
size[2] = wall thickness of installation
|
||||
data[0] = "top","bottom","front","rear","left","right"
|
||||
data[1] = "sleeve"
|
||||
data[2] = assembled true, false
|
||||
mask[0] = true enables component mask
|
||||
mask[1] = mask length
|
||||
mask[2] = mask setback
|
||||
mask[3] = mstyle "default"
|
||||
```
|
||||
|
||||
|
||||
### hk_boom_speaker_holder
|
||||
|
||||
```
|
||||
@@ -2032,21 +2312,62 @@ DESCRIPTION: creates hex pattern covers for vent openings.
|
||||
```
|
||||
|
||||
|
||||
## Accuracy
|
||||
In the past there was been no way of validating whether a SBC Model Framework model and it’s components were dimensionaly accurate in their size and placement other then trial and error. Along with producing cases this project provides a much needed model validation tool to assure model accuracy thru the use of test cases. It works on the very simple premise that if the real SBC fits the test case then the virtual model is accurate or otherwise shows were corrections are needed. This will further increased the overall accuracy of models.
|
||||
## Case Build Notes
|
||||
This area covers specific build notes for specific cases. Hardware used or other relavent information is list by case design name.
|
||||
|
||||
Some SBC in SBC Model Framework have not been validated or may be missing component data and may produce one or more aspects of a case incorrectly. SBC status is noted in sbc.png, the README.md file and at the beginning of the SBC entry defined in sbc_models.cfg, all a part of SBC Model Framework. The color coded indicator of an SBC’s verification and completion as indicated in sbc.png is as follows:
|
||||
### panel_nas Case Design
|
||||
The panel_nas design can be CNC cut or 3D printed. By changing the top and bottom standoff type to "none" in the *SBC Standoff Global Settings* tabs respectively, only a hole is generated for CNC cutting support. Panels can be exported in DXF or SVG by selecting the *part" view under the *view* tab, then the indivual part and select the *section part* checkbox. After the projection has been generated render it by pressing F7 or by selecting render from the user interface. Exported DXF and SVG file formats are available under the File->Export menu.
|
||||
|
||||
Normally the top and bottom height added together is the overall case height for other cases. But with hard drives involved there is additional height which is represented in its total by the height value. In the example, the top is 41mm tall from the outside of the case to the top of the PCB. In a bottom mounted case, 22.25mm measurement would be from the bottom of the case to the top of the PCB, which is sunk by it’s thickness so that the PCB top is even with the top edge of the bottom case piece normally. So the equations for the standoff lengths would be:
|
||||
|
||||
Top standoff length = top height – floor thickness
|
||||
38mm = 41mm – 3mm
|
||||
|
||||
Bottom standoff height = bottom height – floor thickness – PCB thickness
|
||||
17mm = 22.25mm – 3mm – 2.25mm
|
||||
|
||||
2.5” drives are supported using a 3.5” holder adapter. There is one in SBCCB that can be accessed using a new program, sbccb_accessory_tool.scad. The holder can also be wider then a 3.5” drive (101.6mm) for an exact case fit.
|
||||
|
||||
For internal mounted rear fans, room above the rear fans equal to the 10mm tab size is required to remove the rear piece.
|
||||
|
||||
### rack Case Design
|
||||
This case is divided into 3 pieces for the 19" cases and 2 pieces for the 10" cases. They can be selected in the *part* view for STL export under the *view* tab by selecting the left, bottom or right individual part. The peices are held together using M2x8mm screws and nuts.
|
||||
|
||||
10” rack case Qty 5 - M2x8mm screws cap or countersunk with nuts.
|
||||
19” rack case Qty 10 - M2x8mm screws cap or countersunk with nuts.
|
||||
Appropriate fasteners for all SBC.
|
||||
|
||||
For a better fit, prep the edges of the case pieces prior to assembly. Use sand paper or a file to remove any imperfections and true the edge.
|
||||
|
||||
Using 2mm thickness for the floor and walls provides for an adequate case in most enclosed applications but a 3mm floor or better is recommended for removable and open front cases.
|
||||
|
||||
There are 3mm holes on the left, center and right, both front and rear, to use for feet when deployed as a single bench top case. If using the rack stands, the holes can be used to mount an external standoff to support the rear of a heavy case.
|
||||
|
||||
All case bodies can be printed without the use of support. Only the removable bay tray needs support for printing. SBC placement so as to bisect a SBC opening with a case divide, will require print supports.
|
||||
|
||||
Varies accessories (1u rack stand, grommets, fan covers, 2.5” drive holder, washers, etc) are available from sbccb_accessory_tool.scad. The table top rack stand is comprised of two interchangeable brackets that can hold 1U-4U rack cases.
|
||||
|
||||
|
||||
## Accuracy
|
||||
|
||||
In the past there was been no way of validating whether a SBC Model Framework model and its components were dimensionaly accurate in their size and placement other then trial and error. Along with producing cases this project provides a much needed model validation tool to assure model accuracy thru the use of test cases. It works on the very simple premise that if the real SBC fits the test case then the virtual model is accurate or otherwise shows were corrections are needed. This will further increased the overall accuracy of models over time.
|
||||
|
||||
Some SBC in SBC Model Framework have not been validated or may be missing component data and may produce one or more aspects of a case incorrectly. SBC status is noted in sbc.png and sbc_models_viwer.scad, all a part of SBC Model Framework. The color coded indicator of a SBC’s verification and completion is indicated in sbc.png as follows:
|
||||
|
||||
- GREEN = verified, complete and passes SBC Case Builder
|
||||
- YELLOW = unverified, mostlikely usable and/or missing minor information
|
||||
- ORANGE = unverified, may be usable but missing component data
|
||||
- RED = unverified, not usable due to incomplete component data
|
||||
|
||||
The SBC that I do not own have been created using manufacturer supplied mechanical drawings. Some of the drawings are missing information or have errors that effect all or part of the drawings and subsequent SBC models. If you own an SBC that is not represented or verified in SBC Model Framework, please consider adding it or helping to correct errors in existing SBC data. An SBC can be verified to be accurate if a printed shell case from SBC Case Builder fits. Any misalignment is corrected in the SBC Model Framework model data(sbc_models.cfg).
|
||||
The SBC that I do not own have been created using manufacturer supplied models, mechanical drawings or contributed by users. Some of the drawings are missing information or have errors that effect all or part of the subsequent SBC models. If you own an SBC that is not represented or verified in SBC Model Framework, please consider adding it or helping to correct any errors in the SBC data. An SBC can be verified to be accurate if a printed shell case from SBC Case Builder fits. Any misalignment is corrected in the SBC Model Framework model data(sbc_models.cfg).
|
||||
|
||||
## Future Development
|
||||
|
||||
There are a few more ideas for base cases to be worked on as well as a host of supporting accessory models that need to be created. It would also be nice to have all of the OEM accessories for each SBC in the library as well. I’m still looking for a better way to create accessory entries and groups, and continue to expand and verify as many SBC as possible. With that and the obvious benefit of autonomously making SBC cases, this project has also been helping fulfill another personal goal.
|
||||
There are a few more ideas for base cases to be worked on as well as a host of supporting accessory models that need to be created. It would also be nice to have all of the OEM accessories for each OEM in the library as well. I’m still looking for a better way to create accessory entries and groups, and continue to expand and verify as many SBC as possible. With that and the obvious benefit of autonomously making SBC cases, this project has also been helping fulfill another personal goal.
|
||||
|
||||
Computer aided design(CAD) has been around along time but I have been interested in exploring approaches to the next step, computer autonomous design. Regardless of the current or future object creation method, whether it be manufactured or materialized, I believe a universal approach to autonomous design will be needed to advance the human condition. This application has helped me explore and think about practical approaches that might be possible right now in autonomous design and I hope to continue this work by developing new tools and techniques for the new CAD, Computer Autonomous Design.
|
||||
Computer aided design(CAD) has been around a long time but I have been interested in exploring approaches to the next step, computer autonomous design. Regardless of the current or future object creation method, whether it be manufactured or materialized, I believe a universal approach to autonomous design will be needed to advance the human condition. This application has helped me explore and think about practical approaches that might be possible right now in autonomous design and I hope to continue this work by developing new tools and techniques for the new CAD, Computer Autonomous Design.
|
||||
|
||||
|
||||
## Project Supporters
|
||||
|
||||
Thank You to the contributors for their contributions and also HardKernel and Pine64 for their support through the donation of SBC.
|
||||
|
||||
BIN
SBC_Case_Builder_GUI.gif
Normal file
BIN
SBC_Case_Builder_GUI.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 19 MiB |
Submodule SBC_Model_Framework updated: a81d9cf373...8868a26a2f
@@ -1,17 +1,19 @@
|
||||
// Gets a list of SBCs from the SBC Model Framework and Accessory sets
|
||||
// for use with SBC Case Builder.
|
||||
// After running this script, copy the output from the first Echo command into the
|
||||
// list of SBC boards in `sbc_case_builder.scad:32`
|
||||
// Also copy the output from the second Echo command into the list of case acceessory
|
||||
// sets in `sbc_case_builder.scad:196`
|
||||
|
||||
/* Gets a list of SBCs from the SBC Model Framework and Accessory sets
|
||||
for use with SBC Case Builder.
|
||||
After running this script, copy the output from the first Echo command into the
|
||||
list of SBC boards in `sbc_case_builder.scad:32` and `sbc_case_builder.scad`
|
||||
6 locations line 82,90,98,106,114,122 for the sbc selection for the rack case design.
|
||||
Also copy the output from the second Echo command into the list of case acceessory
|
||||
sets in `sbc_case_builder.scad:196`
|
||||
*/
|
||||
include <./SBC_Model_Framework/sbc_models.cfg>;
|
||||
include <./sbc_case_builder_accessories.cfg>;
|
||||
|
||||
echo(" ");
|
||||
boards = [for(i=[0:1:len(sbc_data)-1]) sbc_data[i][0]];
|
||||
echo("Copy the following to `sbc_case_builder.scad` for the `sbc_model` variable");
|
||||
echo(boards);
|
||||
|
||||
echo(" ");
|
||||
accessory_sets = [for(i=[0:1:len(accessory_data)-1]) accessory_data[i][0]];
|
||||
echo("Copy the following to `sbc_case_builder.scad` for the `accessory_name` variable");
|
||||
echo(accessory_sets);
|
||||
echo(" ");
|
||||
@@ -144,7 +144,7 @@ $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([-1.5,-1.75,-adj]) cube([2.75,3.25,1]);
|
||||
translate([-.75,-.75,-adj]) cube([5,1.25,1.25]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,16 +28,20 @@
|
||||
|
||||
*/
|
||||
|
||||
module cableholder_spacer() {
|
||||
module cableholder_spacer(length) {
|
||||
|
||||
size = [9.4,16,6];
|
||||
adj = .01;
|
||||
$fn = 90;
|
||||
translate([0,size[2]/2,-5]) rotate([90,0,0])
|
||||
difference() {
|
||||
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);
|
||||
union() {
|
||||
translate([size[0]/2,size[0]/2,0]) rotate([0,0,90]) long_slot(size[0],size[1],size[2]);
|
||||
translate([-length,5,3]) rotate([0,90,0]) cylinder(d=6, h=length+9.4);
|
||||
}
|
||||
translate([-length-adj,5,3]) rotate([0,90,0]) cylinder(d=3.2, h=length+size[0]+2*adj);
|
||||
translate([-1,8,-1]) cube([2,20,9]);
|
||||
translate([5,9.5,-1]) rotate([0,0,90]) long_slot(4.5,11,9);
|
||||
translate([3,20,-1]) rotate([0,0,45]) cube([2,6,9]);
|
||||
}
|
||||
}
|
||||
|
||||
249
lib/fans.scad
249
lib/fans.scad
@@ -50,7 +50,8 @@ module fans(style, mask) {
|
||||
["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"]
|
||||
["box30x10", 30, 10, 24, 3.2, 12, "#353535"],
|
||||
["box25x10", 25, 10, 20, 3, 12, "#353535"]
|
||||
];
|
||||
|
||||
f = search([style],fan_data);
|
||||
@@ -129,249 +130,3 @@ module fan_cover(size, thick, style) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,20 +21,20 @@
|
||||
|
||||
|
||||
/*
|
||||
NAME: fan_cover
|
||||
DESCRIPTION: creates fan covers for fan openings
|
||||
NAME: m_insert
|
||||
DESCRIPTION: creates brass inserts for models
|
||||
TODO: none
|
||||
|
||||
USAGE: m_insert(type="M3", icolor = "#ebdc8b")
|
||||
USAGE: m_insert(type="m3", icolor = "#ebdc8b")
|
||||
|
||||
type = "M3"
|
||||
type = "m3"
|
||||
icolor = color of insert
|
||||
*/
|
||||
|
||||
module m_insert(type="M3", icolor = "#ebdc8b") { //#f4e6c3, #ebdc8b
|
||||
module m_insert(type="m3", icolor = "#ebdc8b") { //#f4e6c3, #ebdc8b
|
||||
|
||||
odiam = type == "M3" ? 4.2 : 3.5;
|
||||
idiam = type == "M3" ? 3 : 2.5;
|
||||
odiam = type == "m3" ? 4.2 : 3.5;
|
||||
idiam = type == "m3" ? 3 : 2.5;
|
||||
iheight = 4;
|
||||
|
||||
difference() {
|
||||
@@ -46,3 +46,36 @@ module m_insert(type="M3", icolor = "#ebdc8b") { //#f4e6c3, #ebdc8b
|
||||
cube([.5, .5, 1.5]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
NAME: washer
|
||||
DESCRIPTION: creates washers
|
||||
TODO: none
|
||||
|
||||
USAGE: washer(type="round", id=3, od=6, iheight=2, sheight=2, countersunk, icolor = "#ebdc8b")
|
||||
|
||||
type = "round", "shouldered"
|
||||
id = inside diameter
|
||||
od = outside diameter
|
||||
iheight = washer thickness
|
||||
sheight = shoulder height
|
||||
countersunk = true
|
||||
icolor = color of washer
|
||||
*/
|
||||
|
||||
module washer(type="round", id=3, od=6, iheight=2, sheight=2, countersunk = false, icolor = "#ebdc8b") { //#f4e6c3, #ebdc8b
|
||||
|
||||
difference() {
|
||||
union() {
|
||||
color(icolor,.6) cylinder(d=od, h=iheight);
|
||||
if(type == "shouldered") {
|
||||
color(icolor,.6) cylinder(d=od+4, h=sheight);
|
||||
}
|
||||
}
|
||||
color(icolor,.6) translate([0,0,-1]) cylinder(d=id, h=od+sheight+2);
|
||||
if(type == "shouldered" && countersunk == true) {
|
||||
color(icolor,.6) translate([0,0,-.01]) cylinder(d2=id, d1=6, h=sheight);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
109
lib/grommet.scad
Normal file
109
lib/grommet.scad
Normal file
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
This file is part of SBC Case Builder https://github.com/hominoids/SBC_Case_Builder
|
||||
Copyright 2022,2023,2024,2025 Edward A. Kisiel hominoid@cablemi.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
|
||||
|
||||
grommet(face, style, od, id, wall, assembly, mask)
|
||||
grommet_clip(style, od, id, wall)
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
NAME: grommet
|
||||
DESCRIPTION: creates different groumet styles
|
||||
TODO: none
|
||||
|
||||
USAGE: grommet(face, style, od, id, wall, assembly, mask)
|
||||
|
||||
data[0] = "top","bottom","front","rear","left","right"
|
||||
data[1] = "sleeve"
|
||||
size[0] = od outside diameter of grommet body
|
||||
size[1] = id inside hole diameter of grommet body
|
||||
size[2] = wall thickness of installation
|
||||
data[3] = assembled true, false
|
||||
mask[0] = true enables component mask
|
||||
mask[1] = mask length
|
||||
mask[2] = mask setback
|
||||
mask[3] = mstyle "default"
|
||||
*/
|
||||
|
||||
|
||||
module grommet(face = "bottom", style = "sleeve", od, id, wall, assembly, mask) {
|
||||
|
||||
height = 4.5+(2*wall);
|
||||
enablemask = mask[0];
|
||||
mlength = height+mask[1];
|
||||
msetback = mask[2];
|
||||
mstyle = mask[3];
|
||||
cut = .25;
|
||||
lip_od = od+4;
|
||||
lip_thick = 2.5;
|
||||
|
||||
adj = .01;
|
||||
$fn = 90;
|
||||
|
||||
rotx = face == "rear" ? 270 : face == "front" || face == "left" || face == "right" ? 90 : face == "top" ? 180 : 0;
|
||||
roty = 0;
|
||||
rotz = face == "left" ? 90 : face == "right" ? 270 : 0;
|
||||
|
||||
rx = face == "left" ? -lip_thick : face == "right" ? lip_thick : 0;
|
||||
ry = face == "front" ? lip_thick : face == "rear" ? -lip_thick : 0;
|
||||
rz = face == "bottom" ? -lip_thick : face == "top" ? lip_thick : 0;
|
||||
|
||||
translate([rx,ry,rz]) rotate([rotx,roty,rotz]) {
|
||||
if(enablemask == true && mstyle == "default") {
|
||||
if(style == "sleeve") {
|
||||
translate([0, 0, -adj-msetback]) cylinder(d = od+.5, h = mlength);
|
||||
}
|
||||
}
|
||||
if(enablemask == false) {
|
||||
if(style == "sleeve") {
|
||||
difference() {
|
||||
union() {
|
||||
cylinder(d=od, h=height);
|
||||
cylinder(d=lip_od, h=2.5);
|
||||
}
|
||||
translate([0,0,-adj]) cylinder(d=id, h=height+(2*adj));
|
||||
translate([-lip_od/2,-cut/2,-adj]) cube([lip_od+(2*adj),cut,height+(2*adj)]);
|
||||
translate([0,0,2.75+wall]) grommet_clip(style,od,id,wall);
|
||||
}
|
||||
if(assembly == true) {
|
||||
translate([0,0,2.5+wall]) grommet_clip(style,od,id,wall);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module grommet_clip(style,od,id,wall) {
|
||||
|
||||
height = 2.5+wall;
|
||||
lip_od = od+4;
|
||||
adj = .01;
|
||||
$fn = 90;
|
||||
|
||||
if(style == "sleeve") {
|
||||
difference() {
|
||||
cylinder(d=lip_od, h=2.5);
|
||||
difference() {
|
||||
translate([0,0,-adj]) cylinder(d=od, h=wall+2.5);
|
||||
translate([-lip_od/2,-od/2,-adj]) cube([lip_od+(2*adj),2,height-2]);
|
||||
translate([-lip_od/2,-2+od/2,-adj]) cube([lip_od+(2*adj),2,height-2]);
|
||||
}
|
||||
translate([-lip_od,-(od-6)/2,-adj]) cube([lip_od+(2*adj),od-6,wall+2.5]);
|
||||
}
|
||||
}
|
||||
}
|
||||
204
lib/hd.scad
204
lib/hd.scad
@@ -19,10 +19,10 @@
|
||||
hd25_tab(side)
|
||||
hd25_vtab(side)
|
||||
hd35(orientation, mask)
|
||||
hdd35_25holder(length)
|
||||
hd35_25holder(length,width)
|
||||
hd35_tab(side)
|
||||
hd35_vtab(side)
|
||||
hd_bottom_holes(hd, orientation, side, thick)
|
||||
hd_bottom_holes(hd, orientation, side, thick, holetype)
|
||||
hd_mount(hd, orientation, position, side)
|
||||
|
||||
*/
|
||||
@@ -366,7 +366,7 @@ module hd35(orientation, mask) {
|
||||
DESCRIPTION: 3.5" hdd to 2.5" hdd holder
|
||||
TODO: none
|
||||
|
||||
USAGE: hdd35_25holder(length, width=101.6)
|
||||
USAGE: hd35_25holder(length, width=101.6)
|
||||
|
||||
length = length of holder min. 145mm for 3.5" drive
|
||||
*/
|
||||
@@ -614,21 +614,25 @@ module hd35_vtab(side) {
|
||||
DESCRIPTION: creates 2.5" and 3.5" hard drive hole mask for mounting
|
||||
TODO: none
|
||||
|
||||
USAGE: hd_bottom_holes(hd, orientation, side, thick)
|
||||
USAGE: hd_holes(hd, orientation, side, thick, holetype)
|
||||
|
||||
hd = 2.5, 3.5
|
||||
orientation = "portrait", "landscape"
|
||||
side = "left", "right", "both", "bottom", "all"
|
||||
thick = floor thickness
|
||||
holetype = "hole", "slot"
|
||||
*/
|
||||
|
||||
module hd_holes(hd, orientation, side, thick) {
|
||||
module hd_holes(hd=3.5, orientation="portrait", side="all", thick=2, holetype="slot") {
|
||||
|
||||
hd25_x = 100;
|
||||
hd25_y = 69.85;
|
||||
hd35_x = 147;
|
||||
hd35_y = 101.6;
|
||||
hd35_z = 26.1;
|
||||
hole_size = 3.2;
|
||||
hole_len = 3 * hole_size;
|
||||
slot_size = [hole_size, hole_len, thick];
|
||||
adj = .01;
|
||||
$fn = 90;
|
||||
|
||||
@@ -636,35 +640,83 @@ module hd_holes(hd, orientation, side, thick) {
|
||||
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(holetype == "hole") {
|
||||
translate([9.4,-thick,3]) rotate([270,0,0]) cylinder(d=hole_size,h=thick);
|
||||
translate([86,-thick,3]) rotate([270,0,0]) cylinder(d=hole_size,h=thick);
|
||||
}
|
||||
if(holetype == "slot") {
|
||||
translate([9.4-(1.5*hole_size),-thick,3]) rotate([270,0,0])
|
||||
slot(hole_size, hole_len, thick);
|
||||
translate([86-(1.5*hole_size),-thick,3]) rotate([270,0,0])
|
||||
slot(hole_size, hole_len, thick);
|
||||
}
|
||||
}
|
||||
if(side == "right" || side == "both" || side == "all") {
|
||||
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(holetype == "hole") {
|
||||
translate([9.4,hd25_y+thick,3]) rotate([90,0,0]) cylinder(d=hole_size,h=thick);
|
||||
translate([86,hd25_y+thick,3]) rotate([90,0,0]) cylinder(d=hole_size,h=thick);
|
||||
}
|
||||
if(holetype == "slot") {
|
||||
translate([9.4-(1.5*hole_size),hd25_y+thick,3]) rotate([90,0,0])
|
||||
slot(hole_size, hole_len, thick);
|
||||
translate([86-(1.5*hole_size),hd25_y+thick,3]) rotate([90,0,0])
|
||||
slot(hole_size, hole_len, thick);
|
||||
}
|
||||
}
|
||||
if(side == "bottom" || side == "all") {
|
||||
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(holetype == "hole") {
|
||||
translate([9.4,4.07,0]) cylinder(d=hole_size,h=thick);
|
||||
translate([86,4.07,0]) cylinder(d=hole_size,h=thick);
|
||||
translate([86,65.79,0]) cylinder(d=hole_size,h=thick);
|
||||
translate([9.4,65.79,0]) cylinder(d=hole_size,h=thick);
|
||||
}
|
||||
if(holetype == "slot") {
|
||||
translate([9.4-(1.5*hole_size),4.07,0]) slot(hole_size, hole_len, thick);
|
||||
translate([86-(1.5*hole_size),4.07,0]) slot(hole_size, hole_len, thick);
|
||||
translate([86-(1.5*hole_size),65.79,0]) slot(hole_size, hole_len, thick);
|
||||
translate([9.4-(1.5*hole_size),65.79,0]) slot(hole_size, hole_len, thick);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(orientation == "landscape") {
|
||||
if(side == "left" || side == "both" || side == "all") {
|
||||
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(holetype == "hole") {
|
||||
translate([9.4,-thick,3]) rotate([270,0,0]) cylinder(d=hole_size,h=thick);
|
||||
translate([86,-thick,3]) rotate([270,0,0]) cylinder(d=hole_size,h=thick);
|
||||
}
|
||||
if(holetype == "slot") {
|
||||
translate([9.4-(1.5*hole_size),-thick,3]) rotate([270,0,0])
|
||||
slot(hole_size, hole_len, thick);
|
||||
translate([86-(1.5*hole_size),-thick,3]) rotate([270,0,0])
|
||||
slot(hole_size, hole_len, thick);
|
||||
}
|
||||
}
|
||||
if(side == "right" || side == "both" || side == "all") {
|
||||
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(holetype == "hole") {
|
||||
translate([9.4,hd25_y+thick,3]) rotate([90,0,0]) cylinder(d=hole_size,h=thick);
|
||||
translate([86,hd25_y+thick,3]) rotate([90,0,0]) cylinder(d=hole_size,h=thick);
|
||||
}
|
||||
if(holetype == "slot") {
|
||||
translate([9.4-(1.5*hole_size),hd25_y+thick,3]) rotate([90,0,0])
|
||||
slot(hole_size, hole_len, thick);
|
||||
translate([86-(1.5*hole_size),hd25_y+thick,3]) rotate([90,0,0])
|
||||
slot(hole_size, hole_len, thick);
|
||||
}
|
||||
}
|
||||
if(side == "bottom" || side == "all") {
|
||||
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(holetype == "hole") {
|
||||
translate([9.4,4.07,-thick]) cylinder(d=hole_size,h=thick);
|
||||
translate([86,4.07,-thick]) cylinder(d=hole_size,h=thick);
|
||||
translate([86,65.79,-thick]) cylinder(d=hole_size,h=thick);
|
||||
translate([9.4,65.79,-thick]) cylinder(d=hole_size,h=thick);
|
||||
}
|
||||
if(holetype == "slot") {
|
||||
translate([9.4-(1.5*hole_size),4.07,-thick]) slot(hole_size, hole_len, thick);
|
||||
translate([86-(1.5*hole_size),4.07,-thick]) slot(hole_size, hole_len, thick);
|
||||
translate([86-(1.5*hole_size),65.79,-thick]) slot(hole_size, hole_len, thick);
|
||||
translate([9.4-(1.5*hole_size),65.79,-thick]) slot(hole_size, hole_len, thick);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -672,45 +724,103 @@ module hd_holes(hd, orientation, side, thick) {
|
||||
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(holetype == "hole") {
|
||||
translate([16.9,-thick,6.35]) rotate([270,0,0]) cylinder(d=hole_size,h=thick);
|
||||
translate([76.6,-thick,6.35]) rotate([270,0,0]) cylinder(d=hole_size,h=thick);
|
||||
translate([118.5,-thick,6.35]) rotate([270,0,0]) cylinder(d=hole_size,h=thick);
|
||||
}
|
||||
if(holetype == "slot") {
|
||||
translate([16.9-(1.5*hole_size),-thick,6.35]) rotate([270,0,0])
|
||||
slot(hole_size, hole_len, thick);
|
||||
translate([76.6-(1.5*hole_size),-thick,6.35]) rotate([270,0,0])
|
||||
slot(hole_size, hole_len, thick);
|
||||
translate([118.5-(1.5*hole_size),-thick,6.35]) rotate([270,0,0])
|
||||
slot(hole_size, hole_len, thick);
|
||||
}
|
||||
}
|
||||
if(side == "right" || side == "both" || side == "all") {
|
||||
translate([118.5,hd35_y+thick,6.35]) rotate([90,0,0]) cylinder(d=3,h=thick);
|
||||
translate([76.6,hd35_y+thick,6.35]) rotate([90,0,0]) cylinder(d=3,h=thick);
|
||||
translate([16.9,hd35_y+thick,6.35]) rotate([90,0,0]) cylinder(d=3,h=thick);
|
||||
if(holetype == "hole") {
|
||||
translate([118.5,hd35_y+thick,6.35]) rotate([90,0,0]) cylinder(d=hole_size,h=thick);
|
||||
translate([76.6,hd35_y+thick,6.35]) rotate([90,0,0]) cylinder(d=hole_size,h=thick);
|
||||
translate([16.9,hd35_y+thick,6.35]) rotate([90,0,0]) cylinder(d=hole_size,h=thick);
|
||||
}
|
||||
if(holetype == "slot") {
|
||||
translate([118.5-(1.5*hole_size),hd35_y+thick,6.35]) rotate([90,0,0])
|
||||
slot(hole_size, hole_len, thick);
|
||||
translate([76.6-(1.5*hole_size),hd35_y+thick,6.35]) rotate([90,0,0])
|
||||
slot(hole_size, hole_len, thick);
|
||||
translate([16.9-(1.5*hole_size),hd35_y+thick,6.35]) rotate([90,0,0])
|
||||
slot(hole_size, hole_len, thick);
|
||||
}
|
||||
}
|
||||
if(side == "bottom" || side == "all") {
|
||||
// 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(holetype == "hole") {
|
||||
translate([29.52,3.18,0]) cylinder(d=hole_size,h=thick);
|
||||
translate([61.27,3.18,0]) cylinder(d=hole_size,h=thick);
|
||||
translate([105.72,3.18,0]) cylinder(d=hole_size,h=thick);
|
||||
translate([29.52,98.43,0]) cylinder(d=hole_size,h=thick);
|
||||
translate([61.27,98.43,0]) cylinder(d=hole_size,h=thick);
|
||||
translate([105.72,98.43,0]) cylinder(d=hole_size,h=thick);
|
||||
}
|
||||
if(holetype == "slot") {
|
||||
translate([29.52-(1.5*hole_size),3.18,0]) slot(hole_size, hole_len, thick);
|
||||
translate([61.27-(1.5*hole_size),3.18,0]) slot(hole_size, hole_len, thick);
|
||||
translate([105.72-(1.5*hole_size),3.18,0]) slot(hole_size, hole_len, thick);
|
||||
translate([29.52-(1.5*hole_size),98.43,0]) slot(hole_size, hole_len, thick);
|
||||
translate([61.27-(1.5*hole_size),98.43,0]) slot(hole_size, hole_len, thick);
|
||||
translate([105.72-(1.5*hole_size),98.43,0]) slot(hole_size, hole_len, thick);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(orientation == "landscape") {
|
||||
if(side == "left" || side == "both" || side == "all") {
|
||||
translate([16.9,-thick,6.35]) rotate([270,0,0]) cylinder(d=3,h=thick);
|
||||
translate([76.6,-thick,6.35]) rotate([270,0,0]) cylinder(d=3,h=thick);
|
||||
translate([118.5,-thick,6.35]) rotate([270,0,0]) cylinder(d=3,h=thick);
|
||||
if(holetype == "hole") {
|
||||
translate([16.9,-thick,6.35]) rotate([270,0,0]) cylinder(d=3,h=thick);
|
||||
translate([76.6,-thick,6.35]) rotate([270,0,0]) cylinder(d=3,h=thick);
|
||||
translate([118.5,-thick,6.35]) rotate([270,0,0]) cylinder(d=3,h=thick);
|
||||
}
|
||||
if(holetype == "slot") {
|
||||
translate([16.9-(1.5*hole_size),-thick,6.35]) rotate([270,0,0])
|
||||
slot(hole_size, hole_len, thick);
|
||||
translate([76.6-(1.5*hole_size),-thick,6.35]) rotate([270,0,0])
|
||||
slot(hole_size, hole_len, thick);
|
||||
translate([118.5-(1.5*hole_size),-thick,6.35]) rotate([270,0,0])
|
||||
slot(hole_size, hole_len, thick);
|
||||
}
|
||||
}
|
||||
if(side == "right" || side == "both" || side == "all") {
|
||||
translate([118.5,hd35_y+thick,6.35]) rotate([90,0,0]) cylinder(d=3,h=thick);
|
||||
translate([76.6,hd35_y+thick,6.35]) rotate([90,0,0]) cylinder(d=3,h=thick);
|
||||
translate([16.9,hd35_y+thick,6.35]) rotate([90,0,0]) cylinder(d=3,h=thick);
|
||||
if(holetype == "hole") {
|
||||
translate([118.5,hd35_y+thick,6.35]) rotate([90,0,0]) cylinder(d=3,h=thick);
|
||||
translate([76.6,hd35_y+thick,6.35]) rotate([90,0,0]) cylinder(d=3,h=thick);
|
||||
translate([16.9,hd35_y+thick,6.35]) rotate([90,0,0]) cylinder(d=3,h=thick);
|
||||
}
|
||||
if(holetype == "slot") {
|
||||
translate([118.5-(1.5*hole_size),hd35_y+thick,6.35]) rotate([90,0,0])
|
||||
slot(hole_size, hole_len, thick);
|
||||
translate([76.6-(1.5*hole_size),hd35_y+thick,6.35]) rotate([90,0,0])
|
||||
slot(hole_size, hole_len, thick);
|
||||
translate([16.9-(1.5*hole_size),hd35_y+thick,6.35]) rotate([90,0,0])
|
||||
slot(hole_size, hole_len, thick);
|
||||
}
|
||||
}
|
||||
if(side == "bottom" || side == "all") {
|
||||
// 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);
|
||||
if(holetype == "hole") {
|
||||
translate([29.52,3.18,-thick]) cylinder(d=3.6,h=thick);
|
||||
translate([61.27,3.18,-thick]) cylinder(d=3.6,h=thick);
|
||||
translate([105.72,3.18,-thick]) cylinder(d=3.6,h=thick);
|
||||
translate([29.52,98.43,-thick]) cylinder(d=3.6,h=thick);
|
||||
translate([61.27,98.43,-thick]) cylinder(d=3.6,h=thick);
|
||||
translate([105.72,98.43,-thick]) cylinder(d=3.6,h=thick);
|
||||
}
|
||||
if(holetype == "slot") {
|
||||
translate([29.52-(1.5*hole_size),3.18,-thick]) slot(hole_size, hole_len, thick);
|
||||
translate([61.27-(1.5*hole_size),3.18,-thick]) slot(hole_size, hole_len, thick);
|
||||
translate([105.72-(1.5*hole_size),3.18,-thick]) slot(hole_size, hole_len, thick);
|
||||
translate([29.52-(1.5*hole_size),98.43,-thick]) slot(hole_size, hole_len, thick);
|
||||
translate([61.27-(1.5*hole_size),98.43,-thick]) slot(hole_size, hole_len, thick);
|
||||
translate([105.72-(1.5*hole_size),98.43,-thick]) slot(hole_size, hole_len, thick);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
USAGE: nut_holder(nut, style, dia_x, dia_y, height, mask)
|
||||
|
||||
nut = "m2", "m2.5", "m3", "m4"
|
||||
nut = "m2", "m2.5", "m3", "m4", "m3-insert"
|
||||
style = "default", "sloped", "trap"
|
||||
dia_x = top diameter or x size in mm
|
||||
dia_y = bottom diameter or y size in mm
|
||||
@@ -87,6 +87,10 @@ module nut_holder(nut, style, dia_x, dia_y, height, mask) {
|
||||
translate([0, 0, -1]) cylinder(d=nuts[2][0]+.5, h=height+2);
|
||||
translate([0, 0, 2]) cylinder(d=nuts[2][1]*2/sqrt(3), h=height, $fn=6);
|
||||
}
|
||||
if(nut == "m3-insert") {
|
||||
translate([0, 0, -1]) cylinder(d=nuts[2][0]+.5, h=height+2);
|
||||
translate([0, 0, 0]) cylinder(d=4.2, h=5.1);
|
||||
}
|
||||
if(nut == "m4") {
|
||||
translate([0, 0, -1]) cylinder(d=nuts[3][0]+.5, h=height+2);
|
||||
translate([0, 0, 2]) cylinder(d=nuts[3][1]*2/sqrt(3), h=height, $fn=6);
|
||||
@@ -106,7 +110,11 @@ module nut_holder(nut, style, dia_x, dia_y, height, mask) {
|
||||
}
|
||||
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);
|
||||
translate([0, 0, 0]) cylinder(d=nuts[2][1]*2/sqrt(3), h=height+5, $fn=6);
|
||||
}
|
||||
if(nut == "m3-insert") {
|
||||
translate([0, 0, -1]) cylinder(d=nuts[2][0]+.5, h=height+2);
|
||||
translate([0, 0, 0]) cylinder(d=4.2, h=5.1);
|
||||
}
|
||||
if(nut == "m4") {
|
||||
translate([0, 0, -1]) cylinder(d=nuts[3][0]+.5, h=height+2);
|
||||
|
||||
@@ -15,17 +15,19 @@
|
||||
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)
|
||||
adafruit_2030_powerboost(mask)
|
||||
adafruit_4311_lcd(mask)
|
||||
adafruit_4755_solar_charger(mask)
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
NAME: adafruit_lcd
|
||||
DESCRIPTION: adafruit 4311 2in TFT IPS Display model
|
||||
NAME: adafruit_2030_powerboost
|
||||
DESCRIPTION: adafruit 2030 Powerboost 1000 Basic
|
||||
TODO: none
|
||||
|
||||
USAGE: adafruit_lcd(mask[])
|
||||
USAGE: adafruit_2030_powerboost(mask[])
|
||||
|
||||
mask[0] = true enables mask
|
||||
mask[1] = mask length
|
||||
@@ -34,7 +36,65 @@
|
||||
|
||||
*/
|
||||
|
||||
module adafruit_lcd(mask) {
|
||||
module adafruit_2030_powerboost(mask) {
|
||||
|
||||
size_x = 29.21;
|
||||
size_y = 22.86;
|
||||
size_z = 1.6;
|
||||
lcd_size = [34.75,48,2];
|
||||
corner_radius = 2;
|
||||
hole_size = 2.54;
|
||||
enablemask = mask[0];
|
||||
mlen = mask[1];
|
||||
back = mask[2];
|
||||
mstyle = mask[3];
|
||||
|
||||
adj = .01;
|
||||
$fn = 90;
|
||||
|
||||
if(enablemask == true && mstyle == "default") {
|
||||
jst("ph",0,8.5,0,"top",90,[2,0,0],["thruhole","side","white"], size_z, enablemask, [true,10,2,"default"]);
|
||||
usb2("single_horizontal_a",23,4.5,0,"top",270,[0,13,0],[0], size_z, enablemask, [true,12,7,"default"]);
|
||||
}
|
||||
if(enablemask == false) {
|
||||
difference() {
|
||||
color("#252525") slab([size_x, size_y, size_z], corner_radius);
|
||||
color("#252525") translate([hole_size, size_y-hole_size, -adj]) cylinder(d=hole_size,h=6);
|
||||
color("#252525") translate([hole_size, hole_size, -adj]) cylinder(d=hole_size, h=4);
|
||||
|
||||
for(i=[6:2.54:20]) {
|
||||
color("#fee5a6",1) translate([i, 21.5, -adj]) cylinder(d=.8, h=6);
|
||||
}
|
||||
}
|
||||
pcbpad("round", 6, 21.5, 0, "top", 0, [6, 1, 0], [.8, "#fee5a6", 1.2], size_z, enablemask, [false, 20, 0, "default"]);
|
||||
|
||||
pcbpad("round", hole_size, size_y-hole_size, 0, "top", 0, [1, 1, 0],
|
||||
[hole_size, "#fee5a6", hole_size+1], size_z, enablemask, [false, 20, 0, "default"]);
|
||||
pcbpad("round", hole_size, hole_size, 0, "top", 0, [1, 1, 0],
|
||||
[hole_size, "#fee5a6", hole_size+1], size_z, enablemask, [false, 20, 0, "default"]);
|
||||
ic("generic", 12.5, 11, 0, "top", 0, [9, 9, 2], ["dimgrey"], size_z, enablemask, [false, 20, 0, "default"]);
|
||||
ic("generic", 13.5, 5, 0, "top", 0, [4, 4, .8], ["dimgrey"], size_z, enablemask, [false, 20, 0, "default"]);
|
||||
jst("ph",0,8.5,0,"top",90,[2,0,0],["thruhole","side","white"], size_z, enablemask, [true,10,2,"default"]);
|
||||
usb2("single_horizontal_a",23,4.5,0,"top",270,[0,13,0],[0], size_z, enablemask, [true,10,2,"default"]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
NAME: adafruit_lcd
|
||||
DESCRIPTION: adafruit 4311 2in TFT IPS Display model
|
||||
TODO: none
|
||||
|
||||
USAGE: adafruit_4311_lcd(mask[])
|
||||
|
||||
mask[0] = true enables mask
|
||||
mask[1] = mask length
|
||||
mask[2] = mask setback
|
||||
mask[3] = mstyle "default"
|
||||
|
||||
*/
|
||||
|
||||
module adafruit_4311_lcd(mask) {
|
||||
|
||||
size_x = 35.5;
|
||||
size_y = 59;
|
||||
@@ -83,4 +143,72 @@ module adafruit_lcd(mask) {
|
||||
pcbpad("round", size_x-hole_size, size_y-hole_size, 0, "top", 0, [1, 1, 0],
|
||||
[hole_size, "#fee5a6", hole_size+1], size_z, enablemask, [false, 20, 0, "default"]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
NAME: adafruit_4755_solar_charger
|
||||
DESCRIPTION: adafruit 4755 Universal USB/DC/Solar Lithium Ion/Polymer charger - bq24074
|
||||
TODO: none
|
||||
|
||||
USAGE: adafruit_4755_solar_charger(mask[])
|
||||
|
||||
mask[0] = true enables mask
|
||||
mask[1] = mask length
|
||||
mask[2] = mask setback
|
||||
mask[3] = mstyle "default"
|
||||
|
||||
*/
|
||||
|
||||
module adafruit_4755_solar_charger(mask) {
|
||||
|
||||
size_x = 38.1;
|
||||
size_y = 33.02;
|
||||
size_z = 1.6;
|
||||
lcd_size = [34.75,48,2];
|
||||
corner_radius = 2;
|
||||
hole_size = 2.54;
|
||||
enablemask = mask[0];
|
||||
mlen = mask[1];
|
||||
back = mask[2];
|
||||
mstyle = mask[3];
|
||||
|
||||
adj = .01;
|
||||
$fn = 90;
|
||||
|
||||
if(enablemask == true && mstyle == "default") {
|
||||
jst("ph",33.5,8,0,"top",270,[2,0,0],["thruhole","side","white"], size_z, enablemask, [true,10,2,"default"]);
|
||||
jst("ph",33.5,19,0,"top",270,[2,0,0],["thruhole","side","white"], size_z, enablemask, [true,10,2,"default"]);
|
||||
usbc("single_horizontal",-1,5.5,0,"top",90,[0,13,0],[0], size_z, enablemask, [true,10,2,"default"]);
|
||||
power("pj-202ah",-2,17.5,0,"top",90,[0,13,0],[0], size_z, enablemask, [true,10,2,"default"]);
|
||||
}
|
||||
if(enablemask == false) {
|
||||
difference() {
|
||||
color("#252525") slab([size_x, size_y, size_z], corner_radius);
|
||||
color("#252525") translate([hole_size, size_y-hole_size, -adj]) cylinder(d=hole_size,h=6);
|
||||
color("#252525") translate([hole_size, hole_size, -adj]) cylinder(d=hole_size, h=4);
|
||||
color("#252525") translate([size_x-hole_size, size_y-hole_size, -adj]) cylinder(d=hole_size,h=6);
|
||||
color("#252525") translate([size_x-hole_size, hole_size, -adj]) cylinder(d=hole_size, h=4);
|
||||
|
||||
for(i=[6.5:2.54:25]) {
|
||||
color("#fee5a6",1) translate([i, 2.5, -adj]) cylinder(d=.8, h=6);
|
||||
}
|
||||
}
|
||||
pcbpad("round", 6.5, 2.5, 0, "top", 0, [11, 1, 0], [.8, "#fee5a6", 1.2], size_z, enablemask, [false, 20, 0, "default"]);
|
||||
pcbpad("round", hole_size, size_y-hole_size, 0, "top", 0, [1, 1, 0],
|
||||
[hole_size, "#fee5a6", hole_size+1], size_z, enablemask, [false, 20, 0, "default"]);
|
||||
pcbpad("round", hole_size, hole_size, 0, "top", 0, [1, 1, 0],
|
||||
[hole_size, "#fee5a6", hole_size+1], size_z, enablemask, [false, 20, 0, "default"]);
|
||||
pcbpad("round", size_x-hole_size, size_y-hole_size, 0, "top", 0, [1, 1, 0],
|
||||
[hole_size, "#fee5a6", hole_size+1], size_z, enablemask, [false, 20, 0, "default"]);
|
||||
pcbpad("round", size_x-hole_size, hole_size, 0, "top", 0, [1, 1, 0],
|
||||
[hole_size, "#fee5a6", hole_size+1], size_z, enablemask, [false, 20, 0, "default"]);
|
||||
ic("generic", 17.5, 15, 0, "top", 0, [4, 4, .8], ["dimgrey"], size_z, enablemask, [false, 20, 0, "default"]);
|
||||
jst("ph",33.5,8,0,"top",270,[2,0,0],["thruhole","side","white"], size_z, enablemask, [true,10,2,"default"]);
|
||||
jst("ph",33.5,19,0,"top",270,[2,0,0],["thruhole","side","white"], size_z, enablemask, [true,10,2,"default"]);
|
||||
usbc("single_horizontal",-1,5.5,0,"top",90,[0,13,0],[0], size_z, enablemask, [true,10,2,"default"]);
|
||||
power("pj-202ah",-2,17.5,0,"top",90,[0,13,0],[0], size_z, enablemask, [true,10,2,"default"]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
86
lib/oem_rpi.scad
Normal file
86
lib/oem_rpi.scad
Normal file
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
This file is part of SBC Case Builder https://github.com/hominoids/SBC_Case_Builder
|
||||
Copyright 2022,2023,2024 Edward A. Kisiel hominoid@cablemi.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
|
||||
|
||||
rpi_m2hat(mask)
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
NAME: rpi_m2hat
|
||||
DESCRIPTION: Raspberry Pi M.2 HAT+ M Key model
|
||||
TODO: none
|
||||
|
||||
USAGE: rpim2-hat(mask[])
|
||||
|
||||
mask[0] = true enables mask
|
||||
mask[1] = mask length
|
||||
mask[2] = mask setback
|
||||
mask[3] = mstyle "default"
|
||||
|
||||
*/
|
||||
|
||||
module rpi_m2hat(mask) {
|
||||
|
||||
size_x = 65;
|
||||
size_y = 56.5;
|
||||
size_z = 1.6;
|
||||
corner_radius = 3.5;
|
||||
hole_size = 3.5;
|
||||
enablemask = mask[0];
|
||||
mlen = mask[1];
|
||||
back = mask[2];
|
||||
mstyle = mask[3];
|
||||
|
||||
adj = .01;
|
||||
$fn = 90;
|
||||
|
||||
if(enablemask == true && mstyle == "default") {
|
||||
translate([6, 49, 0]) slab([52.8, 7, mlen],1);
|
||||
}
|
||||
if(enablemask == false) {
|
||||
difference() {
|
||||
color("#008066") slab([size_x, size_y, size_z], corner_radius);
|
||||
color("#008066") translate([hole_size, size_y-hole_size, -adj]) cylinder(d=hole_size,h=6);
|
||||
color("#008066") translate([size_x-hole_size, size_y-hole_size, -adj]) cylinder(d=hole_size, h=4);
|
||||
color("#008066") translate([hole_size, hole_size, -adj]) cylinder(d=hole_size,h=6);
|
||||
color("#008066") translate([size_x-hole_size, hole_size, -adj]) cylinder(d=hole_size, h=4);
|
||||
color("#008066") translate([-3, 21, -adj]) slab([8,18,6],2);
|
||||
color("#008066") translate([47.5, -2, -adj]) slab([10,18,6],2);
|
||||
}
|
||||
header("open",7,50,0,"top",0,[20,2,4],["smt","black","female",2.54,"#fee5a6"], size_z, enablemask, [false,10,-2,"none"]);
|
||||
fpc("fh19", 6.5, 25, 0, "top", 90, [16,0,0], ["smt","side","grey","white"], size_z, enablemask, [true,10,2,"default"]);
|
||||
storage("m.2_header",15,17,0,"top",270,[0,0,0],[0], size_z, enablemask, [true,10,2,"default"]);
|
||||
|
||||
pcbpad("round", hole_size, size_y-hole_size, 0, "top", 0, [1, 1, 0],
|
||||
[hole_size, "#fee5a6", hole_size+1], size_z, enablemask, [false, 20, 0, "default"]);
|
||||
pcbpad("round", size_x-hole_size, size_y-hole_size, 0, "top", 0, [1, 1, 0],
|
||||
[hole_size, "#fee5a6", hole_size+1], size_z, enablemask, [false, 20, 0, "default"]);
|
||||
pcbpad("round", hole_size, hole_size, 0, "top", 0, [1, 1, 0],
|
||||
[hole_size, "#fee5a6", hole_size+1], size_z, enablemask, [false, 20, 0, "default"]);
|
||||
pcbpad("round", size_x-hole_size, hole_size, 0, "top", 0, [1, 1, 0],
|
||||
[hole_size, "#fee5a6", hole_size+1], size_z, enablemask, [false, 20, 0, "default"]);
|
||||
// pillar("hex", hole_size-4, size_y-hole_size, 0, "bottom", 0, [4, 3, 16],
|
||||
// [0, "#fee5a6"], size_z, enablemask, [false, 20, 0, "default"]);
|
||||
// pillar("hex", size_x-hole_size-4, size_y-hole_size, 0, "bottom", 0, [4, 3, 16],
|
||||
// [0, "#fee5a6"], size_z, enablemask, [false, 20, 0, "default"]);
|
||||
// pillar("hex", hole_size-4, hole_size, 0, "bottom", 0, [4, 3, 16],
|
||||
// [0, "#fee5a6"], size_z, enablemask, [false, 20, 0, "default"]);
|
||||
// pillar("hex", size_x-hole_size-4, hole_size, 0, "bottom", 0, [4, 3, 16],
|
||||
// [0, "#fee5a6"], size_z, enablemask, [false, 20, 0, "default"]);
|
||||
}
|
||||
}
|
||||
118
lib/panel_clamp.scad
Normal file
118
lib/panel_clamp.scad
Normal file
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
NAME: panel_clamp
|
||||
DESCRIPTION: creates various clamps to join two panels
|
||||
TODO: none
|
||||
|
||||
USAGE: panel_clamp(face, style, screw, dia_x, dia_y, height, mask)
|
||||
|
||||
data[0] = "top","bottom","rear","front","left","right"
|
||||
data[1] = "sloped"
|
||||
data[2] = "m2", "m2.5", "m3", "m4"
|
||||
size_x = top diameter or x size in mm
|
||||
size_y = bottom diameter or y size in mm
|
||||
size_z = clamp height in mm
|
||||
mask[0] = true enables component mask
|
||||
mask[1] = mask length
|
||||
mask[2] = mask setback
|
||||
mask[3] = mstyle "default", "holes"
|
||||
|
||||
*/
|
||||
|
||||
|
||||
module panel_clamp(face, style, screw, dia_x, dia_y, height, mask) {
|
||||
|
||||
nuts = [[2,4,1.6], // m2 size, diameter, height
|
||||
[2.5,5,2], // m2.5 size, diameter, height
|
||||
[3,5.5,2.4], // m3 size, diameter, height
|
||||
[4,7,3.2]]; // m4 size, diameter, height
|
||||
|
||||
enablemask = mask[0];
|
||||
mlength = mask[1];
|
||||
msetback = mask[2];
|
||||
mstyle = mask[3];
|
||||
adj = .01;
|
||||
$fn = 90;
|
||||
|
||||
rotx = face == "rear" ? 270 : face == "front" || face == "left" || face == "right" ? 90 : face == "top" ? 180 : 0;
|
||||
roty = 0;
|
||||
rotz = face == "left" ? 90 : face == "right" ? 270 : 0;
|
||||
|
||||
if(enablemask == true) {
|
||||
rotate([rotx,roty,rotz]) {
|
||||
if(mstyle == "default") {
|
||||
cylinder(d=dia_y, h=height);
|
||||
}
|
||||
if(screw == "m2" && mstyle == "holes") {
|
||||
translate([(-dia_y-(nuts[2][0]+.5)/2)/2, 0, 2.25]) rotate([0,90,0])
|
||||
cylinder(d=nuts[0][0]+.5, h=dia_y+2);
|
||||
translate([-(dia_y/2), 0, 2.25]) rotate([0,90,0])
|
||||
cylinder(d=nuts[0][1]*2/sqrt(3), h=dia_y*.375, $fn=6);
|
||||
translate([nuts[0][0]+.5, 0, 2.25]) rotate([0,90,0])
|
||||
cylinder(d=nuts[0][1]+.5, h=dia_y*.375);
|
||||
}
|
||||
if(screw == "m2.5" && mstyle == "holes") {
|
||||
translate([(-dia_y-(nuts[2][0]+.5)/2)/2, 0, 3]) rotate([0,90,0])
|
||||
cylinder(d=nuts[1][0]+.5, h=dia_y+2);
|
||||
translate([-(dia_y/2), 0, 3]) rotate([0,90,0])
|
||||
cylinder(d=nuts[1][1]*2/sqrt(3), h=dia_y*.375, $fn=6);
|
||||
translate([nuts[1][0]+.5, 0, 3]) rotate([0,90,0])
|
||||
cylinder(d=nuts[1][1]+.5, h=dia_y*.375);
|
||||
}
|
||||
if(screw == "m3" && mstyle == "holes") {
|
||||
translate([(-dia_y-(nuts[2][0]+.5)/2)/2, 0, 3]) rotate([0,90,0])
|
||||
cylinder(d=nuts[2][0]+.5, h=dia_y+2);
|
||||
translate([-(dia_y/2), 0, 3]) rotate([0,90,0])
|
||||
cylinder(d=nuts[2][1]*2/sqrt(3), h=dia_y*.375, $fn=6);
|
||||
translate([nuts[2][0]+.5, 0, 3]) rotate([0,90,0])
|
||||
cylinder(d=nuts[2][1]+.5, h=dia_y*.375);
|
||||
}
|
||||
if(screw == "m4" && mstyle == "holes") {
|
||||
translate([(-dia_y-(nuts[2][0]+.5)/2)/2, 0, 3]) rotate([0,90,0])
|
||||
cylinder(d=nuts[3][0]+.5, h=dia_y+2);
|
||||
translate([-(dia_y/2), 0, 3]) rotate([0,90,0])
|
||||
cylinder(d=nuts[3][1]*2/sqrt(3), h=dia_y*.375, $fn=6);
|
||||
translate([nuts[3][0]+.5, 0, 3]) rotate([0,90,0])
|
||||
cylinder(d=nuts[3][1]+.5, h=dia_y*.375);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(enablemask == false) {
|
||||
rotate([rotx,roty,rotz]) {
|
||||
difference() {
|
||||
cylinder(d2=dia_x, d1=dia_y, h=height);
|
||||
if(screw == "m2") {
|
||||
translate([(-dia_y-(nuts[2][0]+.5)/2)/2, 0, 2.25]) rotate([0,90,0])
|
||||
cylinder(d=nuts[0][0]+.5, h=dia_y+2);
|
||||
translate([-(dia_y/2), 0, 2.25]) rotate([0,90,0])
|
||||
cylinder(d=nuts[0][1]*2/sqrt(3), h=dia_y*.375, $fn=6);
|
||||
translate([nuts[0][0]+.5, 0, 2.25]) rotate([0,90,0])
|
||||
cylinder(d=nuts[0][1]+.5, h=dia_y*.375);
|
||||
}
|
||||
if(screw == "m2.5") {
|
||||
translate([(-dia_y-(nuts[2][0]+.5)/2)/2, 0, 3]) rotate([0,90,0])
|
||||
cylinder(d=nuts[1][0]+.5, h=dia_y+2);
|
||||
translate([-(dia_y/2), 0, 3]) rotate([0,90,0])
|
||||
cylinder(d=nuts[1][1]*2/sqrt(3), h=dia_y*.375, $fn=6);
|
||||
translate([nuts[1][0]+.5, 0, 3]) rotate([0,90,0])
|
||||
cylinder(d=nuts[1][1]+.5, h=dia_y*.375);
|
||||
}
|
||||
if(screw == "m3") {
|
||||
translate([(-dia_y-(nuts[2][0]+.5)/2)/2, 0, 3]) rotate([0,90,0])
|
||||
cylinder(d=nuts[2][0]+.5, h=dia_y+2);
|
||||
translate([-(dia_y/2), 0, 3]) rotate([0,90,0])
|
||||
cylinder(d=nuts[2][1]*2/sqrt(3), h=dia_y*.375, $fn=6);
|
||||
translate([nuts[2][0]+.5, 0, 3]) rotate([0,90,0])
|
||||
cylinder(d=nuts[2][1]+.5, h=dia_y*.375);
|
||||
}
|
||||
if(screw == "m4") {
|
||||
translate([(-dia_y-(nuts[2][0]+.5)/2)/2, 0, 3]) rotate([0,90,0])
|
||||
cylinder(d=nuts[3][0]+.5, h=dia_y+2);
|
||||
translate([-(dia_y/2), 0, 3]) rotate([0,90,0])
|
||||
cylinder(d=nuts[3][1]*2/sqrt(3), h=dia_y*.375, $fn=6);
|
||||
translate([nuts[3][0]+.5, 0, 3]) rotate([0,90,0])
|
||||
cylinder(d=nuts[3][1]+.5, h=dia_y*.375);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
205
lib/rack.scad
Normal file
205
lib/rack.scad
Normal file
@@ -0,0 +1,205 @@
|
||||
/*
|
||||
This file is part of SBC Case Builder https://github.com/hominoids/SBC_Case_Builder
|
||||
Copyright 2022,2023,2024,2025 Edward A. Kisiel hominoid@cablemi.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
|
||||
|
||||
rack_end_bracket(side, size, thick)
|
||||
rack_rail(style, rack_1u, hole_dia, thick)
|
||||
rack_stand(rack_1u)
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
NAME: rack_end_bracket
|
||||
DESCRIPTION: creates rack mounting ears
|
||||
TODO: none
|
||||
|
||||
USAGE: rack_end_bracket(side, size, thick)
|
||||
|
||||
side = "left", "right"
|
||||
size = "1u", "2u", "3u", "4u"
|
||||
thick = thickness of bracket
|
||||
|
||||
*/
|
||||
|
||||
|
||||
module rack_end_bracket(side, size, thick) {
|
||||
|
||||
u1 = 44.45;
|
||||
depth = size == "1u" ? 44.45 : size == "1u+" ? 59.26 : size == "1u++" ? 74.07 : size == "2u" ? 2*44.45 : size == "3u" ? 3*44.45 : 4*44.45;
|
||||
mask = size == "1u" ? 44.45 : size == "1u+" ? 88.9 : size == "1u++" ? 88.9 : size == "2u" ? 2*44.45 : size == "3u" ? 3*44.45 : 4*44.45;
|
||||
c_fillet = 2;
|
||||
hole = 3.2;
|
||||
rack_hole = 6;
|
||||
tab_width = 15.875+thick;
|
||||
b_width = thick;
|
||||
b_depth = depth;
|
||||
b_height = thick;
|
||||
b_loc = [-thick,0,0];
|
||||
|
||||
adjust = .01;
|
||||
$fn=90;
|
||||
|
||||
if(side == "left") {
|
||||
translate([thick,0,0]) rotate([90,0,0])
|
||||
difference() {
|
||||
union() {
|
||||
translate([(-tab_width/2),(depth/2),thick/2])
|
||||
cube_fillet_inside([tab_width,depth,thick],
|
||||
vertical=[0,c_fillet,c_fillet,0],top=[0,0,0,0],bottom=[0,0,0,0], $fn=90);
|
||||
translate([(b_width/2)+b_loc[0],(b_depth/2)+b_loc[1],(b_height/2)+b_loc[2]])
|
||||
cube_fillet_inside([b_width,b_depth,b_height],
|
||||
vertical=[0,0,0,0],top=[c_fillet,0,c_fillet,0],bottom=[0,0,0,0], $fn=90);
|
||||
}
|
||||
for(i=[0:u1:mask-u1]) {
|
||||
for(c=[6.35:15.875:44.45]) {
|
||||
translate([(3-thick)-9-(15.875-9)/2,c+i,-adjust])
|
||||
slot(rack_hole,3,thick+(adjust*2));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(side == "right") {
|
||||
translate([-thick,-thick,0]) rotate([270,180,0])
|
||||
difference() {
|
||||
union() {
|
||||
translate([(-tab_width/2),(depth/2),thick/2])
|
||||
cube_fillet_inside([tab_width,depth,thick],
|
||||
vertical=[0,c_fillet,c_fillet,0],top=[0,0,0,0],bottom=[0,0,0,0], $fn=90);
|
||||
translate([(b_width/2)+b_loc[0],(b_depth/2)+b_loc[1],(b_height/2)+b_loc[2]])
|
||||
cube_fillet_inside([b_width,b_depth,b_height],
|
||||
vertical=[0,0,0,0],top=[c_fillet,0,c_fillet,0],bottom=[0,0,0,0], $fn=90);
|
||||
}
|
||||
for(i=[0:u1:mask-u1]) {
|
||||
for(c=[6.35:15.875:44.45]) {
|
||||
translate([(3-thick)-9-(15.875-9)/2,c+i,-adjust]) slot(rack_hole,3,thick+(adjust*2));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
NAME: rack_rail
|
||||
DESCRIPTION: creates rack rail lengths
|
||||
TODO: none
|
||||
|
||||
USAGE: rack_rail(style, rack_1u, hole_dia, thick)
|
||||
|
||||
style = "none", "nut", "insert"
|
||||
rack_1u = number of 1u
|
||||
hole_dia = hole size to create
|
||||
thick = thickness of bracket
|
||||
|
||||
*/
|
||||
|
||||
module rack_rail(style, rack_1u, hole_dia, thick) {
|
||||
|
||||
1u = 44.45;
|
||||
mount_rail = 15.875;
|
||||
1u_hole_offset = 6.35;
|
||||
1u_hole_spacing = 15.875;
|
||||
height = rack_1u * 1u;
|
||||
|
||||
difference() {
|
||||
union() {
|
||||
cube([mount_rail, thick, height]);
|
||||
if(style == "nut" || style == "insert") {
|
||||
fastner = style == "insert" ? "m3-insert" : "m3";
|
||||
for(i=[0:rack_1u-1]) {
|
||||
translate([mount_rail/2, adj, i*1u]) {
|
||||
translate([0,0,1u_hole_offset]) rotate([90,0,0])
|
||||
nut_holder(fastner, "sloped", 7, mount_rail-1, 3, [false,10,2,"default"]);
|
||||
translate([0,0,1u_hole_offset+1u_hole_spacing])
|
||||
rotate([90,0,0]) nut_holder(fastner, "sloped", 7, mount_rail-1, 3, [false,10,2,"default"]);
|
||||
translate([0,0,1u_hole_offset+2*1u_hole_spacing])
|
||||
rotate([90,0,0]) nut_holder(fastner, "sloped", 7, mount_rail-1, 3, [false,10,2,"default"]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for(i=[0:rack_1u-1]) {
|
||||
translate([mount_rail/2, -1, i*1u]) {
|
||||
translate([0,thick+2,1u_hole_offset]) rotate([90,0,0]) cylinder(d = hole_dia, h=thick+2);
|
||||
translate([0,thick+2,1u_hole_offset+1u_hole_spacing]) rotate([90,0,0]) cylinder(d = hole_dia, h=thick+2);
|
||||
translate([0,thick+2,1u_hole_offset+2*1u_hole_spacing]) rotate([90,0,0]) cylinder(d = hole_dia, h=thick+2);
|
||||
}
|
||||
}
|
||||
translate([-1,-1,height]) cube([mount_rail+2,thick+2,10]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
NAME: rack_stand
|
||||
DESCRIPTION: creates rack stand of 1u hieght
|
||||
TODO: none
|
||||
|
||||
USAGE: rack_stand(rack_1u)
|
||||
|
||||
rack_1u = number of 1u
|
||||
|
||||
*/
|
||||
|
||||
module rack_stand(rack_1u) {
|
||||
|
||||
1u = 44.45;
|
||||
mount_rail = 15.875;
|
||||
thick = 5;
|
||||
height = rack_1u * 1u;
|
||||
height_offset = 25.4/2;
|
||||
hole_dia = 3.2;
|
||||
c_fillet = 9;
|
||||
rail_offset = 87.5;
|
||||
foot_length = 175;
|
||||
foot_thick = 4;
|
||||
$fn=180;
|
||||
|
||||
// vertical rack rails
|
||||
translate([0, 0, height_offset-adj]) rack_rail(rack_fasteners, rack_1u, hole_dia, thick);
|
||||
|
||||
// bottom feet
|
||||
translate([mount_rail/2, -rail_offset/2, foot_thick-2]) cube_fillet_inside([mount_rail, foot_length, foot_thick],
|
||||
vertical=[0,0,0,0], top=[c_fillet,0,c_fillet,0], bottom=[0,0,0,0], $fn=90);
|
||||
|
||||
// bottom connection piece
|
||||
translate([0, 0, 0]) cube([mount_rail, thick, height_offset]);
|
||||
|
||||
// top extension piece
|
||||
ext_len = rack_1u == 4 ? thick : rack_1u == 3 ? thick : thick;
|
||||
translate([0, 0, height+height_offset-adj]) cube([mount_rail, thick, ext_len]);
|
||||
|
||||
// support arc
|
||||
if(rack_1u > 0) {
|
||||
ext_adj = rack_1u == 4 ? 4.5*thick : rack_1u == 3 ? 3.5*thick : 2.5*thick;
|
||||
difference() {
|
||||
translate([0,(height/2)-5*thick,ext_adj]) rotate([0,90,0]) {
|
||||
difference() {
|
||||
translate([0,0,0]) cylinder(d=(2*height)+(3*thick), h=mount_rail);
|
||||
translate([0,0,-adj]) cylinder(d=(2*height)+thick+4, h=mount_rail+(2*adj));
|
||||
}
|
||||
}
|
||||
// top trim
|
||||
translate([-1, thick, height+height_offset-5]) cube([mount_rail+2, 300, 40]);
|
||||
// front trim
|
||||
translate([-1, 42.75, -175]) cube([mount_rail+2, 300, 400]);
|
||||
translate([-1, thick, foot_thick]) cube([mount_rail+2, 300, 400]);
|
||||
// bottom trim
|
||||
translate([-1, -150, -174.5]) cube([mount_rail+2, 300, 175]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -76,7 +76,7 @@ module standoff(stand_off, mask){
|
||||
mstyle = mask[3];
|
||||
|
||||
ps = size == "m2_tap" || size == "m2" || size == "m2+" ? 4 :
|
||||
size == "m2.5_tap" || size == "m2.5" || size == "m2.5+" ? 5 :
|
||||
size == "m2.5_tap" || size == "m2.5" || size == "m2.5+" ? 5.375 :
|
||||
size == "m3_tap" || size == "m3" || size == "m3+" ? 6.72 :
|
||||
size == "m4_tap" || size == "m4" || size == "m4+" ? 8.96 : (2*holesize)+.5;
|
||||
ds = size == "m2_tap" || size == "m2" || size == "m2+" ? 1.2 :
|
||||
|
||||
22
mod/add.scad
22
mod/add.scad
@@ -82,6 +82,9 @@ module add(type, loc_x, loc_y, loc_z, face, rotation, size, data, mask) {
|
||||
if(type == "feet") {
|
||||
translate([loc_x,loc_y,loc_z]) rotate(rotation) feet(size_x, size_z);
|
||||
}
|
||||
if(type == "grommet") {
|
||||
translate([loc_x,loc_y,loc_z]) rotate(rotation) grommet(data[0], data[1], size_x, size_y, size_z, data[2], mask);
|
||||
}
|
||||
if(type == "hd_holder") {
|
||||
translate([loc_x,loc_y,loc_z]) rotate(rotation) hd_mount(data[0],data[1],data[2],data[3]);
|
||||
}
|
||||
@@ -112,6 +115,9 @@ module add(type, loc_x, loc_y, loc_z, face, rotation, size, data, mask) {
|
||||
if(type == "nut_holder") {
|
||||
translate([loc_x,loc_y,loc_z]) rotate(rotation) nut_holder(data[0], data[1], size_x, size_y, size_z, mask);
|
||||
}
|
||||
if(type == "panel_clamp") {
|
||||
translate([loc_x,loc_y,loc_z]) rotate(rotation) panel_clamp(data[0], data[1], data[2], size_x, size_y, size_z, mask);
|
||||
}
|
||||
if(type == "pcb_holder") {
|
||||
translate([loc_x,loc_y,loc_z]) rotate(rotation) pcb_holder([size_x,size_y,size_z],data[0]);
|
||||
}
|
||||
@@ -139,8 +145,14 @@ module add(type, loc_x, loc_y, loc_z, face, rotation, size, data, mask) {
|
||||
}
|
||||
|
||||
// models
|
||||
if(type == "adafruit_lcd") {
|
||||
translate([loc_x,loc_y,loc_z]) rotate(rotation) adafruit_lcd(mask);
|
||||
if(type == "adafruit_2030_powerboost") {
|
||||
translate([loc_x,loc_y,loc_z]) rotate(rotation) adafruit_2030_powerboost(mask);
|
||||
}
|
||||
if(type == "adafruit_4311_lcd") {
|
||||
translate([loc_x,loc_y,loc_z]) rotate(rotation) adafruit_4311_lcd(mask);
|
||||
}
|
||||
if(type == "adafruit_4755_solar_charger") {
|
||||
translate([loc_x,loc_y,loc_z]) rotate(rotation) adafruit_4755_solar_charger(mask);
|
||||
}
|
||||
if(type == "dsub") {
|
||||
translate([loc_x,loc_y,loc_z]) rotate(rotation) dsub(data[0], data[1], mask);
|
||||
@@ -202,6 +214,12 @@ module add(type, loc_x, loc_y, loc_z, face, rotation, size, data, mask) {
|
||||
if(type == "hk_xu4_shifter_shield") {
|
||||
translate([loc_x,loc_y,loc_z]) rotate(rotation) hk_xu4_shifter_shield(mask);
|
||||
}
|
||||
if(type == "pillar") {
|
||||
translate([loc_x,loc_y,loc_z]) rotate(rotation) pillar(data[0], 0, 0, 0, data[2], 0, size, data, 0, false, mask);
|
||||
}
|
||||
if(type == "rpi_m2hat") {
|
||||
translate([loc_x,loc_y,loc_z]) rotate(rotation) rpi_m2hat(mask);
|
||||
}
|
||||
if(type == "stl_model") {
|
||||
translate([loc_x,loc_y,loc_z]) rotate(rotation) stl_model(data[0],data[1]);
|
||||
}
|
||||
|
||||
@@ -97,14 +97,14 @@ mb_adapters=[
|
||||
}
|
||||
}
|
||||
}
|
||||
// adapter standoff holes
|
||||
// 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=6.5, h=mba_z+2);
|
||||
translate([mbhole_x,mbhole_y,-1]) cylinder(d=4, h=mba_z+2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ module case_bottom(case_design) {
|
||||
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],
|
||||
vertical=[corner_fillet-wallthick,corner_fillet-wallthick,corner_fillet-wallthick,corner_fillet-wallthick],
|
||||
top=[0,0,0,0], bottom=[edge_fillet,edge_fillet,edge_fillet,edge_fillet,edge_fillet], $fn=90);
|
||||
}
|
||||
}
|
||||
@@ -62,6 +62,22 @@ module case_bottom(case_design) {
|
||||
cube([8,wallthick+2*adj,floorthick]);
|
||||
}
|
||||
}
|
||||
if(case_design == "panel_nas") {
|
||||
x_adj = pcb_width > 100 ? width-2*sidethick : 101.6+case_offset_x;
|
||||
xtab_adj = pcb_width > 100 ? width-gap-2*sidethick-adj : 101.6-gap+case_offset_x-adj;
|
||||
union() {
|
||||
translate([-gap,-wallthick,0])
|
||||
cube([x_adj,depth-(2*wallthick),floorthick]);
|
||||
translate([-gap-sidethick-(2*adj),depth-(3*wallthick)-gap-adj-20,0])
|
||||
cube([sidethick+(2*adj),10,floorthick]);
|
||||
translate([xtab_adj,depth-(3*wallthick)-gap-adj-20,0])
|
||||
cube([sidethick+2*adj,10,floorthick]);
|
||||
translate([-gap-sidethick-(2*adj),40-wallthick-gap+adj,0])
|
||||
cube([sidethick+2*adj,10,floorthick]);
|
||||
translate([xtab_adj,40-wallthick-gap+adj,0])
|
||||
cube([sidethick+2*adj,10,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],
|
||||
@@ -76,7 +92,7 @@ module case_bottom(case_design) {
|
||||
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],
|
||||
vertical=[corner_fillet-wallthick,corner_fillet-wallthick,corner_fillet-wallthick,corner_fillet-wallthick],
|
||||
top=[0,0,0,0],bottom=[2,2,2,2], $fn=90);
|
||||
}
|
||||
// case nut placement
|
||||
@@ -91,7 +107,8 @@ module case_bottom(case_design) {
|
||||
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)) {
|
||||
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);
|
||||
}
|
||||
@@ -101,7 +118,8 @@ module case_bottom(case_design) {
|
||||
}
|
||||
}
|
||||
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)) {
|
||||
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);
|
||||
}
|
||||
@@ -111,7 +129,8 @@ module case_bottom(case_design) {
|
||||
}
|
||||
}
|
||||
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)) {
|
||||
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);
|
||||
}
|
||||
@@ -121,13 +140,16 @@ module case_bottom(case_design) {
|
||||
}
|
||||
}
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -135,11 +157,11 @@ module case_bottom(case_design) {
|
||||
// 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]);
|
||||
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]);
|
||||
cube([width,wallthick,top_height-floorthick]);
|
||||
}
|
||||
|
||||
// rear panel
|
||||
@@ -214,21 +236,21 @@ module case_bottom(case_design) {
|
||||
}
|
||||
else {
|
||||
difference() {
|
||||
translate([pcb_width/2,pcb_depth/2,bottom_height/2]) rotate([0,0,0])
|
||||
translate([pcb_width/2,pcb_depth/2,bottom_height/2])
|
||||
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])
|
||||
translate([pcb_width/2,pcb_depth/2,(bottom_height/2)+floorthick])
|
||||
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])
|
||||
translate([pcb_width/2,pcb_depth/2,bottom_height-lip])
|
||||
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])
|
||||
translate([pcb_width/2,pcb_depth/2,bottom_height-lip])
|
||||
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])
|
||||
translate([pcb_width/2,pcb_depth/2,(bottom_height/2)+2*floorthick])
|
||||
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);
|
||||
@@ -247,7 +269,7 @@ module case_bottom(case_design) {
|
||||
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],
|
||||
vertical=[corner_fillet-wallthick,corner_fillet-wallthick,corner_fillet-wallthick,corner_fillet-wallthick],
|
||||
top=[0,0,0,0], bottom=[edge_fillet,edge_fillet,edge_fillet,edge_fillet,edge_fillet], $fn=90);
|
||||
// snap top indent
|
||||
translate([-gap-wallthick+.75,(depth/2)-(depth*.75)/2-gap-wallthick,case_z-.5])
|
||||
@@ -265,7 +287,7 @@ module case_bottom(case_design) {
|
||||
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],
|
||||
vertical=[corner_fillet-wallthick,corner_fillet-wallthick,corner_fillet-wallthick,corner_fillet-wallthick],
|
||||
top=[0,0,0,0], bottom=[edge_fillet,edge_fillet,edge_fillet,edge_fillet,edge_fillet], $fn=90);
|
||||
difference() {
|
||||
translate([(width/2)-wallthick-gap,(depth/2)-wallthick-gap,case_z-lip/2])
|
||||
@@ -275,7 +297,7 @@ module case_bottom(case_design) {
|
||||
|
||||
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],
|
||||
vertical=[corner_fillet-wallthick,corner_fillet-wallthick,corner_fillet-wallthick,corner_fillet-wallthick],top=[0,0,0,0],
|
||||
bottom=[edge_fillet,edge_fillet,edge_fillet,edge_fillet,edge_fillet], $fn=90);
|
||||
}
|
||||
}
|
||||
@@ -384,77 +406,191 @@ echo(pcb_depth+case_offset_y-10);
|
||||
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 (class == "pcbhole" && id == 0 && 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);
|
||||
ahpx = sbc_model == "n2" ? 7 : sbc_model == "n2+" ? 9.25 :
|
||||
sbc_model == "m1" ? 9.25 : pcbhole_x;
|
||||
ahpy = sbc_model == "n2" ? 15 : sbc_model == "n2+" ? 9.25 :
|
||||
sbc_model == "m1" ? 9.25 : pcbhole_y;
|
||||
translate([ahpx,ahpy,-adj])
|
||||
cylinder(d=bottom_standoff[4]-.2, h=floorthick+(2*adj));
|
||||
}
|
||||
if (class == "pcbhole" && id == pcb_id && pcbhole_pos == "left_front" &&
|
||||
if (class == "pcbhole" && id == 0 && 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);
|
||||
ahpx = sbc_model == "n2" ? 8 : sbc_model == "n2+" ? 9.25 :
|
||||
sbc_model == "m1" ? 9.25 : pcbhole_x;
|
||||
ahpy = sbc_model == "n2" ? 75 : sbc_model == "n2+" ? 80.75 :
|
||||
sbc_model == "m1" ? 112.75 : pcbhole_y;
|
||||
translate([ahpx,ahpy,-adj])
|
||||
cylinder(d=bottom_standoff[4]-.2, h=floorthick+(2*adj));
|
||||
}
|
||||
if (class == "pcbhole" && id == pcb_id && pcbhole_pos == "right_rear" &&
|
||||
if (class == "pcbhole" && id == 0 && 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);
|
||||
ahpx = sbc_model == "n2" ? 82 : sbc_model == "n2+" ? 80.75 :
|
||||
sbc_model == "m1" ? 80.75 : pcbhole_x;
|
||||
ahpy = sbc_model == "n2" ? 6 : sbc_model == "n2+" ? 9.25 :
|
||||
sbc_model == "m1" ? 9.25 : pcbhole_y;
|
||||
translate([ahpx,ahpy,-adj])
|
||||
cylinder(d=bottom_standoff[4]-.2, h=floorthick+(2*adj));
|
||||
}
|
||||
if (class == "pcbhole" && id == pcb_id && pcbhole_pos == "right_front" &&
|
||||
if (class == "pcbhole" && id == 0 && 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);
|
||||
ahpx = sbc_model == "n2" ? 82 : sbc_model == "n2+" ? 80.75 :
|
||||
sbc_model == "m1" ? 80.75 : pcbhole_x;
|
||||
ahpy = sbc_model == "n2" ? 75 : sbc_model == "n2+" ? 80.75 :
|
||||
sbc_model == "m1" ? 112.75 : pcbhole_y;
|
||||
translate([ahpx,ahpy,-adj])
|
||||
cylinder(d=bottom_standoff[4]-.2, h=floorthick+(2*adj));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
// multi-pcb standoff holes
|
||||
if(multipcb_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];
|
||||
pcbid = sbc_data[s[0]][i+3];
|
||||
pcbloc_x = sbc_data[s[0]][i+4];
|
||||
pcbloc_y = sbc_data[s[0]][i+5];
|
||||
pcbloc_z = sbc_data[s[0]][i+6];
|
||||
if(class == "pcb") {
|
||||
for (i=[1:11:len(sbc_data[s[0]])-2]) {
|
||||
pcbclass = sbc_data[s[0]][i+1];
|
||||
pcbtype = sbc_data[s[0]][i+2];
|
||||
id = sbc_data[s[0]][i+3];
|
||||
pcbhole_x = sbc_data[s[0]][i+4]+pcb_loc_x+pcbloc_x;
|
||||
pcbhole_y = sbc_data[s[0]][i+5]+pcb_loc_y+pcbloc_y;
|
||||
pcbhole_z = sbc_data[s[0]][i+6];
|
||||
pcbhole_size = sbc_data[s[0]][i+9][0];
|
||||
pcbhole_state = sbc_data[s[0]][i+10][0];
|
||||
pcbhole_pos = sbc_data[s[0]][i+10][4];
|
||||
|
||||
if(id == pcbid && id != 0 && pcbclass == "pcbhole") {
|
||||
if (pcbclass == "pcbhole" && pcbhole_pos == "left_rear" &&
|
||||
multipcb_bottom_rear_left_enable == true &&
|
||||
(pcbhole_state == "bottom" || pcbhole_state == "both")) {
|
||||
translate([pcbhole_x,pcbhole_y,-adj]) cylinder(d=multipcb_bottom_standoff[4]-.2, h=floorthick+(2*adj));
|
||||
}
|
||||
if (pcbclass == "pcbhole" && pcbhole_pos == "left_front" &&
|
||||
multipcb_bottom_front_left_enable == true &&
|
||||
(pcbhole_state == "bottom" || pcbhole_state == "both")) {
|
||||
translate([pcbhole_x,pcbhole_y,-adj]) cylinder(d=multipcb_bottom_standoff[4]-.2, h=floorthick+(2*adj));
|
||||
}
|
||||
if (pcbclass == "pcbhole" && pcbhole_pos == "right_rear" &&
|
||||
multipcb_bottom_rear_right_enable == true &&
|
||||
(pcbhole_state == "bottom" || pcbhole_state == "both")) {
|
||||
translate([pcbhole_x,pcbhole_y,-adj]) cylinder(d=multipcb_bottom_standoff[4]-.2, h=floorthick+(2*adj));
|
||||
}
|
||||
if (pcbclass == "pcbhole" && pcbhole_pos == "right_front" &&
|
||||
multipcb_bottom_front_right_enable == true &&
|
||||
(pcbhole_state == "bottom" || pcbhole_state == "both")) {
|
||||
translate([pcbhole_x,pcbhole_y,-adj]) cylinder(d=multipcb_bottom_standoff[4]-.2, h=floorthick+(2*adj));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 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)) &&
|
||||
if(((width-pcb_loc_x-pcb_width-(gap+2*wallthick) >= ext_bottom_standoff_support_size
|
||||
|| pcb_loc_y >= ext_bottom_standoff_support_size)) &&
|
||||
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);
|
||||
translate([width-ext_bottom_standoff_support_size/4-(2*(wallthick+gap)),
|
||||
ext_bottom_standoff_support_size/4,-adj])
|
||||
cylinder(d=ext_bottom_standoff[4]-.2, h=floorthick+(2+adj));
|
||||
}
|
||||
// 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);
|
||||
if(((width-pcb_loc_x-pcb_width-(gap+2*wallthick) >= ext_bottom_standoff_support_size &&
|
||||
depth-pcb_loc_y-pcb_depth >= ext_bottom_standoff_support_size) ||
|
||||
(width-pcb_loc_x-pcb_width-(gap+2*wallthick) >= ext_bottom_standoff_support_size &&
|
||||
depth-pcb_loc_y-pcb_depth <= ext_bottom_standoff_support_size) ||
|
||||
(width-pcb_loc_x-pcb_width-(gap+2*wallthick) <= ext_bottom_standoff_support_size &&
|
||||
depth-pcb_loc_y-pcb_depth >= ext_bottom_standoff_support_size)) &&
|
||||
ext_bottom_front_right_enable == true && ext_bottom_standoff[6] != "blind") {
|
||||
translate([width-ext_bottom_standoff_support_size/4-(2*(wallthick+gap)),
|
||||
depth-ext_bottom_standoff_support_size/4-(2*(wallthick+gap)),-adj])
|
||||
cylinder(d=ext_bottom_standoff[4]-.2, h=floorthick+(2*adj));
|
||||
}
|
||||
// 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);
|
||||
if((pcb_loc_x >= ext_bottom_standoff_support_size || pcb_loc_y >= ext_bottom_standoff_support_size) &&
|
||||
ext_bottom_rear_left_enable == true && ext_bottom_standoff[6] != "blind") {
|
||||
translate([ext_bottom_standoff_support_size/4,
|
||||
ext_bottom_standoff_support_size/4,-adj])
|
||||
cylinder(d=ext_bottom_standoff[4]-.2, h=floorthick+(2*adj));
|
||||
}
|
||||
// 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);
|
||||
if(((pcb_loc_x >= ext_bottom_standoff_support_size &&
|
||||
(depth-(pcb_loc_y+pcb_depth)) >= ext_bottom_standoff_support_size) ||
|
||||
(pcb_loc_x <= ext_bottom_standoff_support_size &&
|
||||
(depth-(pcb_loc_y+pcb_depth)) >= ext_bottom_standoff_support_size) ||
|
||||
(pcb_loc_x >= ext_bottom_standoff_support_size &&
|
||||
(depth-(pcb_loc_y+pcb_depth)) <= ext_bottom_standoff_support_size)) &&
|
||||
ext_bottom_front_left_enable == true && ext_bottom_standoff[6] != "blind") {
|
||||
translate([ext_bottom_standoff_support_size/4,
|
||||
depth-(ext_bottom_standoff_support_size/4)-(2*(wallthick+gap)),-adj])
|
||||
cylinder(d=ext_bottom_standoff[4]-.2, h=floorthick+(2*adj));
|
||||
}
|
||||
}
|
||||
// bottom cover pattern
|
||||
if(bottom_cover_pattern != "solid") {
|
||||
xvent8_adj = pcb_width > 100 ? width/5.5 : width/6;
|
||||
if(bottom_cover_pattern == "hex_5mm") {
|
||||
translate([1,0,-2]) vent_hex((width)/3.75,(depth)/6,floorthick+4,5,1.5,"horizontal");
|
||||
if(case_design == "panel_nas") {
|
||||
translate([6,5,-floorthick+adj])
|
||||
vent_hex((width-10)/3.75,(depth-10)/7,floorthick+4,5,1.5,"horizontal");
|
||||
}
|
||||
else {
|
||||
translate([1,0,-floorthick]) 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(case_design == "panel_nas") {
|
||||
translate([-gap+5,6,-floorthick+adj]) vent_hex(xvent8_adj,depth/9.5,floorthick+4,8,1.5,"horizontal");
|
||||
}
|
||||
else {
|
||||
translate([1,2,-floorthick]) 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(case_design == "panel_nas") {
|
||||
translate([wallthick+gap,wallthick,-floorthick+adj])
|
||||
vent(wallthick,depth-6*wallthick-gap,floorthick+4,1,1,(width-2*(sidethick+gap))/5.35,"horizontal");
|
||||
}
|
||||
else {
|
||||
translate([0,-gap,-floorthick])
|
||||
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(case_design == "panel_nas") {
|
||||
translate([wallthick+gap,wallthick,-floorthick+adj])
|
||||
vent(width-4*(sidethick+gap),wallthick,floorthick+4,1,
|
||||
(depth-2*(wallthick-gap))/4.35,1,"horizontal");
|
||||
}
|
||||
else {
|
||||
translate([-gap,-gap,-floorthick])
|
||||
vent(width-2*(wallthick+gap),wallthick,floorthick+4,1,(depth-2*wallthick-gap)/3,1,"horizontal");
|
||||
}
|
||||
}
|
||||
if(bottom_cover_pattern == "astroid") {
|
||||
if(case_design == "panel_nas") {
|
||||
xast_adj = pcb_width <= 100 ? 8 : 6;
|
||||
for(c=[xast_adj:12:depth-16]) {
|
||||
for(r=[12:12:width-16]) {
|
||||
translate([r,c,-floorthick]) linear_extrude(floorthick+5) import("./dxf/astroid_8mm.dxf");
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for(c=[3:12:depth-8]) {
|
||||
for(r=[4:12:width-8]) {
|
||||
translate([r,c,-4]) linear_extrude(floorthick+5) import("./dxf/astroid_8mm.dxf");
|
||||
translate([r,c,-(2*floorthick)]) linear_extrude(floorthick+5) import("./dxf/astroid_8mm.dxf");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// rear io shield opening for standard form motherboards
|
||||
@@ -473,7 +609,7 @@ echo(pcb_depth+case_offset_y-10);
|
||||
}
|
||||
}
|
||||
}
|
||||
// pcb standoffs
|
||||
// primary pcb standoffs
|
||||
if(sbc_bottom_standoffs == true) {
|
||||
for (i=[1:11:len(sbc_data[s[0]])-2]) {
|
||||
class = sbc_data[s[0]][i+1];
|
||||
@@ -484,14 +620,15 @@ echo(pcb_depth+case_offset_y-10);
|
||||
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];
|
||||
pcbadj_z = sbc_model == "n2" || sbc_model == "m1" ? -6 :
|
||||
sbc_model == "n2+" ? -4.5 : 0;
|
||||
|
||||
if(class == "pcbhole" && id == pcb_id &&
|
||||
(pcbhole_pos == "left_rear" || pcbhole_pos == "left_front" || pcbhole_pos == "right_rear" || pcbhole_pos == "right_front")) {
|
||||
if(class == "pcbhole" && id == pcb_id) {
|
||||
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_height-pcb_z+pcb_loc_z+bottom_rear_left_adjust+pcbadj_z,
|
||||
bottom_standoff[3],
|
||||
bottom_standoff[4],
|
||||
bottom_standoff[5],
|
||||
@@ -502,13 +639,18 @@ echo(pcb_depth+case_offset_y-10);
|
||||
bottom_standoff[10],
|
||||
bottom_standoff[11],
|
||||
bottom_standoff[12]];
|
||||
translate([pcbhole_x,pcbhole_y,0]) standoff(pcb_standoff,[false,10,2,"default"]);
|
||||
ahpx = sbc_model == "n2" ? 7 : sbc_model == "n2+" ? 9.25 :
|
||||
sbc_model == "m1" ? 9.25 : pcbhole_x;
|
||||
ahpy = sbc_model == "n2" ? 15 : sbc_model == "n2+" ? 9.25 :
|
||||
sbc_model == "m1" ? 9.25 : pcbhole_y;
|
||||
translate([ahpx,ahpy,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_height-pcb_z+pcb_loc_z+bottom_front_left_adjust+pcbadj_z,
|
||||
bottom_standoff[3],
|
||||
bottom_standoff[4],
|
||||
bottom_standoff[5],
|
||||
@@ -519,13 +661,18 @@ echo(pcb_depth+case_offset_y-10);
|
||||
bottom_standoff[10],
|
||||
bottom_standoff[11],
|
||||
bottom_standoff[12]];
|
||||
translate([pcbhole_x,pcbhole_y,0]) standoff(pcb_standoff,[false,10,2,"default"]);
|
||||
ahpx = sbc_model == "n2" ? 8 : sbc_model == "n2+" ? 9.25 :
|
||||
sbc_model == "m1" ? 9.25 : pcbhole_x;
|
||||
ahpy = sbc_model == "n2" ? 75 : sbc_model == "n2+" ? 80.75 :
|
||||
sbc_model == "m1" ? 112.75 : pcbhole_y;
|
||||
translate([ahpx,ahpy,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_height-pcb_z+pcb_loc_z+bottom_rear_right_adjust+pcbadj_z,
|
||||
bottom_standoff[3],
|
||||
bottom_standoff[4],
|
||||
bottom_standoff[5],
|
||||
@@ -536,13 +683,18 @@ echo(pcb_depth+case_offset_y-10);
|
||||
bottom_standoff[10],
|
||||
bottom_standoff[11],
|
||||
bottom_standoff[12]];
|
||||
translate([pcbhole_x,pcbhole_y,0]) standoff(pcb_standoff,[false,10,2,"default"]);
|
||||
ahpx = sbc_model == "n2" ? 82 : sbc_model == "n2+" ? 80.75 :
|
||||
sbc_model == "m1" ? 80.75 : pcbhole_x;
|
||||
ahpy = sbc_model == "n2" ? 6 : sbc_model == "n2+" ? 9.25 :
|
||||
sbc_model == "m1" ? 9.25 : pcbhole_y;
|
||||
translate([ahpx,ahpy,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_height-pcb_z+pcb_loc_z+bottom_front_right_adjust+pcbadj_z,
|
||||
bottom_standoff[3],
|
||||
bottom_standoff[4],
|
||||
bottom_standoff[5],
|
||||
@@ -553,16 +705,120 @@ echo(pcb_depth+case_offset_y-10);
|
||||
bottom_standoff[10],
|
||||
bottom_standoff[11],
|
||||
bottom_standoff[12]];
|
||||
translate([pcbhole_x,pcbhole_y,0]) standoff(pcb_standoff,[false,10,2,"default"]);
|
||||
ahpx = sbc_model == "n2" ? 82 : sbc_model == "n2+" ? 80.75 :
|
||||
sbc_model == "m1" ? 80.75 : pcbhole_x;
|
||||
ahpy = sbc_model == "n2" ? 75 : sbc_model == "n2+" ? 80.75 :
|
||||
sbc_model == "m1" ? 112.75 : pcbhole_y;
|
||||
translate([ahpx,ahpy,0])
|
||||
standoff(pcb_standoff,[false,10,2,"default"]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// multi-pcb standoffs
|
||||
if(multipcb_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];
|
||||
pcbid = sbc_data[s[0]][i+3];
|
||||
pcbloc_x = sbc_data[s[0]][i+4];
|
||||
pcbloc_y = sbc_data[s[0]][i+5];
|
||||
pcbloc_z = sbc_data[s[0]][i+6];
|
||||
if(class == "pcb") {
|
||||
for (i=[1:11:len(sbc_data[s[0]])-2]) {
|
||||
pcbclass = sbc_data[s[0]][i+1];
|
||||
pcbtype = sbc_data[s[0]][i+2];
|
||||
id = sbc_data[s[0]][i+3];
|
||||
pcbhole_x = sbc_data[s[0]][i+4]+pcb_loc_x+pcbloc_x;
|
||||
pcbhole_y = sbc_data[s[0]][i+5]+pcb_loc_y+pcbloc_y;
|
||||
pcbhole_z = sbc_data[s[0]][i+6];
|
||||
pcbhole_size = sbc_data[s[0]][i+9][0];
|
||||
pcbhole_state = sbc_data[s[0]][i+10][0];
|
||||
pcbhole_pos = sbc_data[s[0]][i+10][4];
|
||||
|
||||
if(pcbclass == "pcbhole" && pcbid == id && id != 0) {
|
||||
if (pcbhole_pos == "left_rear" && multipcb_bottom_rear_left_enable == true &&
|
||||
(pcbhole_state == "bottom" || pcbhole_state == "both")) {
|
||||
bottom_support = multipcb_bottom_sidewall_support == true ? multipcb_bottom_rear_left_support : "none";
|
||||
pcb_standoff = [multipcb_bottom_standoff[0],
|
||||
multipcb_bottom_standoff[1],
|
||||
bottom_height-pcb_z+pcb_loc_z+multipcb_bottom_rear_left_adjust,
|
||||
multipcb_bottom_standoff[3],
|
||||
multipcb_bottom_standoff[4],
|
||||
multipcb_bottom_standoff[5],
|
||||
multipcb_bottom_standoff[6],
|
||||
multipcb_bottom_standoff[7],
|
||||
bottom_support,
|
||||
multipcb_bottom_standoff[9],
|
||||
multipcb_bottom_standoff[10],
|
||||
multipcb_bottom_standoff[11],
|
||||
multipcb_bottom_standoff[12]];
|
||||
translate([pcbhole_x,pcbhole_y,0]) standoff(pcb_standoff,[false,10,2,"default"]);
|
||||
}
|
||||
if (pcbhole_pos == "left_front" && multipcb_bottom_front_left_enable == true &&
|
||||
(pcbhole_state == "bottom" || pcbhole_state == "both")) {
|
||||
bottom_support = multipcb_bottom_sidewall_support == true ? multipcb_bottom_front_left_support : "none";
|
||||
pcb_standoff = [multipcb_bottom_standoff[0],
|
||||
multipcb_bottom_standoff[1],
|
||||
bottom_height-pcb_z+pcb_loc_z+multipcb_bottom_front_left_adjust,
|
||||
multipcb_bottom_standoff[3],
|
||||
multipcb_bottom_standoff[4],
|
||||
multipcb_bottom_standoff[5],
|
||||
multipcb_bottom_standoff[6],
|
||||
multipcb_bottom_standoff[7],
|
||||
bottom_support,
|
||||
multipcb_bottom_standoff[9],
|
||||
multipcb_bottom_standoff[10],
|
||||
multipcb_bottom_standoff[11],
|
||||
multipcb_bottom_standoff[12]];
|
||||
translate([pcbhole_x,pcbhole_y,0]) standoff(pcb_standoff,[false,10,2,"default"]);
|
||||
}
|
||||
if (pcbhole_pos == "right_rear" && multipcb_bottom_rear_right_enable == true &&
|
||||
(pcbhole_state == "bottom" || pcbhole_state == "both")) {
|
||||
bottom_support = multipcb_bottom_sidewall_support == true ? multipcb_bottom_rear_right_support : "none";
|
||||
pcb_standoff = [multipcb_bottom_standoff[0],
|
||||
multipcb_bottom_standoff[1],
|
||||
bottom_height-pcb_z+pcb_loc_z+multipcb_bottom_rear_right_adjust,
|
||||
multipcb_bottom_standoff[3],
|
||||
multipcb_bottom_standoff[4],
|
||||
multipcb_bottom_standoff[5],
|
||||
multipcb_bottom_standoff[6],
|
||||
multipcb_bottom_standoff[7],
|
||||
bottom_support,
|
||||
multipcb_bottom_standoff[9],
|
||||
multipcb_bottom_standoff[10],
|
||||
multipcb_bottom_standoff[11],
|
||||
multipcb_bottom_standoff[12]];
|
||||
translate([pcbhole_x,pcbhole_y,0]) standoff(pcb_standoff,[false,10,2,"default"]);
|
||||
}
|
||||
if (pcbhole_pos == "right_front" && multipcb_bottom_front_right_enable == true &&
|
||||
(pcbhole_state == "bottom" || pcbhole_state == "both")) {
|
||||
bottom_support = multipcb_bottom_sidewall_support == true ? multipcb_bottom_front_right_support : "none";
|
||||
pcb_standoff = [multipcb_bottom_standoff[0],
|
||||
multipcb_bottom_standoff[1],
|
||||
bottom_height-pcb_z+pcb_loc_z+multipcb_bottom_front_right_adjust,
|
||||
multipcb_bottom_standoff[3],
|
||||
multipcb_bottom_standoff[4],
|
||||
multipcb_bottom_standoff[5],
|
||||
multipcb_bottom_standoff[6],
|
||||
multipcb_bottom_standoff[7],
|
||||
bottom_support,
|
||||
multipcb_bottom_standoff[9],
|
||||
multipcb_bottom_standoff[10],
|
||||
multipcb_bottom_standoff[11],
|
||||
multipcb_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) {
|
||||
if((width-pcb_loc_x-pcb_width-(gap+2*wallthick) >= ext_bottom_standoff_support_size ||
|
||||
pcb_loc_y >= ext_bottom_standoff_support_size) && ext_bottom_rear_right_enable == true) {
|
||||
extended_standoff = [ext_bottom_standoff[0],
|
||||
ext_bottom_standoff[1],
|
||||
bottom_height+ext_bottom_rear_right_adjust,
|
||||
@@ -576,14 +832,18 @@ echo(pcb_depth+case_offset_y-10);
|
||||
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"]);
|
||||
translate([width-ext_bottom_standoff_support_size/4-(2*(wallthick+gap)),
|
||||
ext_bottom_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) {
|
||||
if(((width-pcb_loc_x-pcb_width-(gap+2*wallthick) >= ext_bottom_standoff_support_size &&
|
||||
depth-pcb_loc_y-pcb_depth >= ext_bottom_standoff_support_size) ||
|
||||
(width-pcb_loc_x-pcb_width-(gap+2*wallthick) >= ext_bottom_standoff_support_size &&
|
||||
depth-pcb_loc_y-pcb_depth <= ext_bottom_standoff_support_size) ||
|
||||
(width-pcb_loc_x-pcb_width-(gap+2*wallthick) <= ext_bottom_standoff_support_size &&
|
||||
depth-pcb_loc_y-pcb_depth >= ext_bottom_standoff_support_size)) &&
|
||||
ext_bottom_front_right_enable == true) {
|
||||
extended_standoff = [ext_bottom_standoff[0],
|
||||
ext_bottom_standoff[1],
|
||||
bottom_height+ext_bottom_front_right_adjust,
|
||||
@@ -597,11 +857,13 @@ echo(pcb_depth+case_offset_y-10);
|
||||
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"]);
|
||||
translate([width-ext_bottom_standoff_support_size/4-(2*(wallthick+gap)),
|
||||
depth-ext_bottom_standoff_support_size/4-(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) {
|
||||
if((pcb_loc_x >= ext_bottom_standoff_support_size || pcb_loc_y >= ext_bottom_standoff_support_size)
|
||||
&& ext_bottom_rear_left_enable == true) {
|
||||
extended_standoff = [ext_bottom_standoff[0],
|
||||
ext_bottom_standoff[1],
|
||||
bottom_height+ext_bottom_rear_left_adjust,
|
||||
@@ -615,14 +877,17 @@ echo(pcb_depth+case_offset_y-10);
|
||||
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"]);
|
||||
translate([ext_bottom_standoff_support_size/4, ext_bottom_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) {
|
||||
if(((pcb_loc_x >= ext_bottom_standoff_support_size &&
|
||||
depth-(pcb_loc_y+pcb_depth) >= ext_bottom_standoff_support_size) ||
|
||||
(pcb_loc_x <= ext_bottom_standoff_support_size &&
|
||||
depth-(pcb_loc_y+pcb_depth) >= ext_bottom_standoff_support_size) ||
|
||||
(pcb_loc_x >= ext_bottom_standoff_support_size &&
|
||||
depth-(pcb_loc_y+pcb_depth) <= ext_bottom_standoff_support_size)) &&
|
||||
ext_bottom_front_left_enable == true) {
|
||||
extended_standoff = [ext_bottom_standoff[0],
|
||||
ext_bottom_standoff[1],
|
||||
bottom_height+ext_bottom_front_left_adjust,
|
||||
@@ -636,8 +901,8 @@ echo(pcb_depth+case_offset_y-10);
|
||||
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])
|
||||
translate([ext_bottom_standoff_support_size/4,
|
||||
depth-(ext_bottom_standoff_support_size/4)-(2*(wallthick+gap)),0])
|
||||
standoff(extended_standoff,[false,10,2,"default"]);
|
||||
}
|
||||
}
|
||||
@@ -694,7 +959,8 @@ echo(pcb_depth+case_offset_y-10);
|
||||
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])
|
||||
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) {
|
||||
@@ -713,20 +979,29 @@ echo(pcb_depth+case_offset_y-10);
|
||||
}
|
||||
// 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);
|
||||
}
|
||||
pcbid = sbc_data[s[0]][i+3];
|
||||
pcbloc_x = sbc_data[s[0]][i+4];
|
||||
pcbloc_y = sbc_data[s[0]][i+5];
|
||||
pcbloc_z = sbc_data[s[0]][i+6];
|
||||
if(class == "pcb") {
|
||||
for (i=[1:11:len(sbc_data[s[0]])-2]) {
|
||||
class = sbc_data[s[0]][i+1];
|
||||
type = sbc_data[s[0]][i+2];
|
||||
id = sbc_data[s[0]][i+3];
|
||||
loc_x = sbc_data[s[0]][i+4]+pcb_loc_x+pcbloc_x;
|
||||
loc_y = sbc_data[s[0]][i+5]+pcb_loc_y+pcbloc_y;
|
||||
loc_z = sbc_data[s[0]][i+6]+pcb_loc_z+pcbloc_z;
|
||||
side = sbc_data[s[0]][i+7];
|
||||
rotation = sbc_data[s[0]][i+8];
|
||||
if(id == pcbid) {
|
||||
indent(loc_x, loc_y, bottom_height+loc_z-adj, rotation[2], side, class, type, wallthick, gap, floorthick, pcb_z);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// clean fillets
|
||||
if(case_design == "shell") {
|
||||
|
||||
1293
mod/case_rack.scad
Normal file
1293
mod/case_rack.scad
Normal file
File diff suppressed because it is too large
Load Diff
@@ -128,6 +128,317 @@ module case_side(case_design, side) {
|
||||
}
|
||||
}
|
||||
}
|
||||
if(case_design == "panel_nas") {
|
||||
x_adj = pcb_width > 100 ? width-2*sidethick : 101.6+case_offset_x;
|
||||
xtab_adj = pcb_width > 100 ? width-gap-2*sidethick-adj : 101.6-gap+case_offset_x-adj;
|
||||
xvent8_adj = pcb_width > 100 ? width/5.5 : width/6;
|
||||
if(side == "rear") {
|
||||
difference() {
|
||||
union() {
|
||||
translate([-gap,-(2*wallthick),0])
|
||||
cube([x_adj,wallthick,case_z-floorthick]);
|
||||
// bottom right tab
|
||||
translate([xtab_adj,-(2*wallthick),20])
|
||||
cube([sidethick+(2*adj),wallthick,10]);
|
||||
// top right tab
|
||||
translate([xtab_adj,-(2*wallthick),case_z-30])
|
||||
cube([sidethick+(2*adj),wallthick,10]);
|
||||
// bottom left tab
|
||||
translate([-sidethick-gap-adj,-(2*wallthick),20])
|
||||
cube([sidethick+(2*adj),wallthick,10]);
|
||||
// top left tab
|
||||
translate([-sidethick-gap-adj,-(2*wallthick),case_z-30])
|
||||
cube([sidethick+(2*adj),wallthick,10]);
|
||||
if(hd_bays > 3) {
|
||||
// middle right tab
|
||||
translate([xtab_adj,-(2*wallthick),(case_z/2)-5])
|
||||
cube([sidethick+(2*adj),wallthick,10]);
|
||||
// middle left tab
|
||||
translate([-sidethick-gap-adj,-(2*wallthick),(case_z/2)-5])
|
||||
cube([sidethick+(2*adj),wallthick,10]);
|
||||
}
|
||||
}
|
||||
if(rear_fan == 1 || rear_fan == 2) {
|
||||
if(rear_fan_center == false) {
|
||||
translate([-1+(101.6-rear_fan_size)/2,-1,rear_fan_position])
|
||||
rotate([90,0,0]) fan_mask(rear_fan_size, wallthick+2, rear_cooling);
|
||||
}
|
||||
if(rear_fan_center == true) {
|
||||
translate([-1+(101.6-rear_fan_size)/2+(width-2*(sidethick+gap)-101.6)/2,-1,rear_fan_position])
|
||||
rotate([90,0,0]) fan_mask(rear_fan_size, wallthick+2, rear_cooling);
|
||||
}
|
||||
}
|
||||
if(rear_fan == 2) {
|
||||
if(rear_fan_center == false) {
|
||||
translate([-1+(101.6-rear_fan_size)/2,-1,rear_fan_position+rear_dualfan_spacing+rear_fan_size])
|
||||
rotate([90,0,0]) fan_mask(rear_fan_size, wallthick+2, rear_cooling);
|
||||
}
|
||||
if(rear_fan_center == true) {
|
||||
translate([-1+(101.6-rear_fan_size)/2+(width-2*(sidethick+gap)-101.6)/2,
|
||||
-1,rear_fan_position+rear_dualfan_spacing+rear_fan_size])
|
||||
rotate([90,0,0]) fan_mask(rear_fan_size, wallthick+2, rear_cooling);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(side == "front") {
|
||||
difference() {
|
||||
union() {
|
||||
translate([-gap,depth-(4*wallthick),floorthick])
|
||||
cube([x_adj,wallthick,case_z-3*floorthick]);
|
||||
// bottom right tab
|
||||
translate([xtab_adj,depth-(4*wallthick),20])
|
||||
cube([sidethick+(2*adj),wallthick,10]);
|
||||
// top right tab
|
||||
translate([xtab_adj,depth-(4*wallthick),case_z-30])
|
||||
cube([sidethick+(2*adj),wallthick,10]);
|
||||
// bottom left tab
|
||||
translate([-sidethick-gap-adj,depth-(4*wallthick),20])
|
||||
cube([sidethick+(2*adj),wallthick,10]);
|
||||
// top left tab
|
||||
translate([-sidethick-gap-adj,depth-(4*wallthick),case_z-30])
|
||||
cube([sidethick+(2*adj),wallthick,10]);
|
||||
if(hd_bays > 3) {
|
||||
// middle right tab
|
||||
translate([xtab_adj,depth-(4*wallthick),(case_z/2)-5])
|
||||
cube([sidethick+(2*adj),wallthick,10]);
|
||||
// middle left tab
|
||||
translate([-sidethick-gap-adj,depth-(4*wallthick),(case_z/2)-5])
|
||||
cube([sidethick+(2*adj),wallthick,10]);
|
||||
}
|
||||
}
|
||||
// front cover pattern
|
||||
if(front_cover_pattern != "solid" && case_design == "panel_nas") {
|
||||
xvent_pos = pcb_width <= 100 ? -gap+3 : -gap+6;
|
||||
if(front_cover_pattern == "hex_5mm" && hd_bays < 6) {
|
||||
translate([xvent_pos,depth-3*(wallthick)+gap,hd_z_position-5])
|
||||
vent_hex(round(width/3.85),round(hd_bays*(27.1+hd_space)/5.75),wallthick+4,5,1.5,"vertical");
|
||||
}
|
||||
if(front_cover_pattern == "hex_5mm" && hd_bays == 6) {
|
||||
translate([xvent_pos,depth-3*(wallthick)+gap,hd_z_position])
|
||||
vent_hex(round(width/3.85),round(hd_bays*(27.1+hd_space)/5.75),wallthick+4,5,1.5,"vertical");
|
||||
}
|
||||
if(front_cover_pattern == "hex_8mm") {
|
||||
translate([-gap+4,depth-3*(wallthick)+gap,hd_z_position])
|
||||
vent_hex(xvent8_adj,round(hd_bays*(27.1+hd_space)/5.75)-5,floorthick+4,8,1.5,"vertical");
|
||||
}
|
||||
if(front_cover_pattern == "linear_vertical") {
|
||||
translate([-gap+4,depth-3*(wallthick)+gap,hd_z_position])
|
||||
vent(wallthick,(case_z-2*(wallthick+gap)-20)/8,floorthick+4,1,1,
|
||||
(width-2*(sidethick+gap))/5.35,"vertical");
|
||||
translate([-gap+4,depth-3*(wallthick)+gap,case_z-(top_height+bottom_height+4*floorthick)-5])
|
||||
vent(wallthick,(case_z-2*(wallthick+gap)-20)/8,floorthick+4,1,1,
|
||||
(width-2*(sidethick+gap))/5.35,"vertical");
|
||||
}
|
||||
if(front_cover_pattern == "linear_horizontal") {
|
||||
translate([wallthick+gap,depth-3*(wallthick)+gap,hd_z_position])
|
||||
vent(width-2*(wallthick+gap+sidethick)-4,wallthick,floorthick+4,2,
|
||||
(case_z-2*(wallthick+gap)-20)/20,1,"vertical");
|
||||
translate([wallthick+gap,depth-3*(wallthick)+gap,
|
||||
case_z-(top_height+bottom_height+4*floorthick)-20])
|
||||
vent(width-4*(sidethick+gap),,wallthick,floorthick+4,2,
|
||||
(case_z-2*(wallthick+gap)-20)/20,1,"vertical");
|
||||
}
|
||||
if(front_cover_pattern == "astroid") {
|
||||
xast_adj = pcb_width <= 100 ? 8 : 6;
|
||||
for(c=[xast_adj:12:case_z-20]) {
|
||||
for(r=[8:12:width-8]) {
|
||||
translate([r,depth-2*wallthick,c]) rotate([90,0,0])
|
||||
linear_extrude(wallthick+5) import("./dxf/astroid_8mm.dxf");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(side == "right") {
|
||||
difference() {
|
||||
if(case_design == "panel_nas") {
|
||||
if(pcb_width > 100) {
|
||||
translate([pcb_width+sidethick+gap+case_offset_x,-(3*wallthick)-gap,-2*wallthick])
|
||||
rotate([0,-90,0]) slab([case_z+(3*wallthick),depth+2*wallthick,sidethick],corner_fillet);
|
||||
}
|
||||
if(pcb_width <= 100) {
|
||||
translate([101.6-gap+sidethick+case_offset_x,-(3*wallthick)-gap,-2*wallthick])
|
||||
rotate([0,-90,0]) slab([case_z+(3*wallthick),depth+2*wallthick,sidethick],corner_fillet);
|
||||
}
|
||||
}
|
||||
else {
|
||||
translate([width-2*sidethick-gap,-(3*wallthick)-gap,-2*wallthick])
|
||||
rotate([0,-90,0]) slab([case_z+(3*wallthick),depth+2*wallthick,sidethick],corner_fillet);
|
||||
}
|
||||
|
||||
// rear edge top tab openings
|
||||
translate([width-3*sidethick-gap-adj,-2*wallthick+adj-tol,case_z-30])
|
||||
cube([2*sidethick+2*adj,wallthick+tol,20+tol]);
|
||||
translate([width-3*sidethick-gap-adj,-(4*wallthick)+2*adj,case_z-20])
|
||||
cube([2*sidethick+(2*adj),2*wallthick,10+tol]);
|
||||
|
||||
// rear edge bottom tab openings
|
||||
translate([width-3*sidethick-gap-adj,-2*wallthick+adj-tol,20])
|
||||
cube([2*sidethick+2*adj,wallthick+tol,20+tol]);
|
||||
translate([width-3*sidethick-gap-adj,-(4*wallthick)+2*adj,30])
|
||||
cube([2*sidethick+(2*adj),2*wallthick,10+tol]);
|
||||
|
||||
// front edge top tab openings
|
||||
translate([width-3*sidethick-gap-adj,depth-(4*wallthick),case_z-30])
|
||||
cube([2*sidethick+(2*adj),wallthick+tol,20+tol]);
|
||||
translate([width-3*sidethick-gap-adj,depth-(4*wallthick),case_z-20])
|
||||
cube([2*sidethick+(2*adj),3*wallthick,10+tol]);
|
||||
|
||||
// front edge bottom tab openings
|
||||
translate([width-3*sidethick-gap-adj,depth-(4*wallthick),20])
|
||||
cube([2*sidethick+(2*adj),wallthick+tol,20+tol]);
|
||||
translate([width-3*sidethick-gap-adj,depth-(4*wallthick),30])
|
||||
cube([2*sidethick+(2*adj),3*wallthick,10+tol]);
|
||||
|
||||
if(hd_bays > 3) {
|
||||
// front edge middle tab openings
|
||||
translate([width-3*sidethick-gap-adj,depth-(4*wallthick),(case_z/2)-5])
|
||||
cube([2*sidethick+2*adj,wallthick+tol,20+tol]);
|
||||
translate([width-3*sidethick-gap-adj,depth-(4*wallthick),(case_z/2)-5+10])
|
||||
cube([2*sidethick+(2*adj),3*wallthick,10+tol]);
|
||||
|
||||
// rear edge middle tab openings
|
||||
translate([width-3*sidethick-gap-adj,-2*wallthick+adj-tol,(case_z/2)-5])
|
||||
cube([2*sidethick+2*adj,wallthick+tol,20+tol]);
|
||||
translate([width-3*sidethick-gap-adj,-(4*wallthick),(case_z/2)-5+10])
|
||||
cube([2*sidethick+(2*adj),3*wallthick,10+tol]);
|
||||
}
|
||||
|
||||
// hd holes for bays
|
||||
if(hd_reverse == false) {
|
||||
for( i=[0:1:hd_bays-1]) {
|
||||
translate([(width-101.6)-(4*sidethick)-gap+adj,
|
||||
-(3*wallthick)-gap+hd_y_position,hd_z_position+(hd_space+27.1)*i])
|
||||
hd_holes(3.5, "portrait", "both", 4*sidethick+2);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for( i=[0:1:hd_bays-1]) {
|
||||
translate([width-(4*sidethick)-adj,-(3*wallthick)-gap+hd_y_position+147,
|
||||
hd_z_position+(hd_space+27.1)*i])
|
||||
rotate([0,0,180]) hd_holes(3.5, "portrait", "both", 4*sidethick+2);
|
||||
}
|
||||
}
|
||||
// top edge front tab opening
|
||||
translate([width-3*sidethick-gap-adj,depth-(3*wallthick)-gap-adj-30-tol,
|
||||
case_z-(2*floorthick)])
|
||||
cube([2*sidethick+(2*adj),20+tol,floorthick+tol]);
|
||||
translate([width-3*sidethick-gap-adj,depth-(3*wallthick)-gap-adj-30-tol,
|
||||
case_z-(2*floorthick)])
|
||||
cube([2*sidethick+(2*adj),10+tol,(3*floorthick)+adj]);
|
||||
|
||||
// top edge rear tab opening
|
||||
translate([width-3*sidethick-gap-adj,40-wallthick-gap-adj-tol,
|
||||
case_z-(2*floorthick)])
|
||||
cube([2*sidethick+(2*adj),10+tol,floorthick+tol]);
|
||||
translate([width-3*sidethick-gap-adj,30-wallthick-gap+adj-tol,
|
||||
case_z-(2*floorthick)])
|
||||
cube([2*sidethick+(2*adj),10+tol,(3*floorthick)+adj]);
|
||||
|
||||
// bottom edge front tab opening
|
||||
translate([width-3*sidethick-gap-adj,depth-(3*wallthick)-gap-adj-30-tol,-tol])
|
||||
cube([2*sidethick+2*adj,20+tol,floorthick+tol]);
|
||||
translate([width-3*sidethick-gap-adj,depth-(3*wallthick)-gap-adj-30-tol,-(3*floorthick)+adj])
|
||||
cube([2*sidethick+2*adj,10+tol,(3*floorthick)+adj]);
|
||||
|
||||
// bottom edge rear tab opening
|
||||
translate([width-3*sidethick-gap-adj,30-wallthick-gap+adj-tol,-tol])
|
||||
cube([2*sidethick+2*adj,20+tol,floorthick+tol]);
|
||||
translate([width-3*sidethick-gap-adj,30-wallthick-gap+adj-tol,-(3*floorthick)+adj])
|
||||
cube([2*sidethick+(2*adj),10+tol,(3*floorthick)+adj]);
|
||||
|
||||
}
|
||||
}
|
||||
if(side == "left") {
|
||||
difference() {
|
||||
translate([-gap,-(3*wallthick)-gap,-2*wallthick])
|
||||
rotate([0,-90,0]) slab([case_z+(3*wallthick),depth+(2*wallthick),sidethick],corner_fillet);
|
||||
|
||||
// rear edge top tab openings
|
||||
translate([-sidethick-gap-adj,-2*wallthick+adj-tol,case_z-30])
|
||||
cube([sidethick+2*adj,wallthick+tol,20]);
|
||||
translate([-sidethick-gap-adj,-(4*wallthick)+tol,case_z-20])
|
||||
cube([sidethick+(2*adj),3*wallthick+adj,10+tol]);
|
||||
|
||||
// rear edge bottom tab openings
|
||||
translate([-sidethick-gap-adj,-2*wallthick+adj-tol,20])
|
||||
cube([sidethick+2*adj,wallthick+tol,20]);
|
||||
translate([-sidethick-gap-adj,-(4*wallthick)+tol,30])
|
||||
cube([sidethick+(2*adj),3*wallthick,10+tol]);
|
||||
|
||||
// front edge top tab openings
|
||||
translate([-sidethick-gap-adj,depth-(4*wallthick),case_z-30])
|
||||
cube([sidethick+(2*adj),wallthick+tol,20]);
|
||||
translate([-sidethick-gap-adj,depth-(4*wallthick),case_z-20])
|
||||
cube([sidethick+(2*adj),3*wallthick,10+tol]);
|
||||
|
||||
// front edge bottom tab openings
|
||||
translate([-sidethick-gap-adj,depth-(4*wallthick),20])
|
||||
cube([sidethick+(2*adj),wallthick+tol,20]);
|
||||
translate([-sidethick-gap-adj,depth-(4*wallthick),30])
|
||||
cube([sidethick+(2*adj),3*wallthick,10+tol]);
|
||||
|
||||
if(hd_bays > 3) {
|
||||
// rear edge middle tab openings
|
||||
translate([-sidethick-gap-adj,-2*wallthick+adj-tol,(case_z/2)-5])
|
||||
cube([sidethick+2*adj,wallthick+tol,20]);
|
||||
translate([-sidethick-gap-adj,-(4*wallthick)+tol,(case_z/2)-5+10])
|
||||
cube([sidethick+(2*adj),3*wallthick,10+tol]);
|
||||
|
||||
// front edge middle tab openings
|
||||
translate([-sidethick-gap-adj,depth-(4*wallthick),(case_z/2)-5])
|
||||
cube([sidethick+2*adj,wallthick+tol,20]);
|
||||
translate([-sidethick-gap-adj,depth-(4*wallthick),(case_z/2)-5+10])
|
||||
cube([sidethick+(2*adj),3*wallthick,10+tol]);
|
||||
}
|
||||
|
||||
// hd holes for bays
|
||||
if(hd_reverse == false) {
|
||||
for( i=[0:1:hd_bays-1]) {
|
||||
translate([-gap+adj,-(3*wallthick)-gap+hd_y_position,hd_z_position+(hd_space+27.1)*i])
|
||||
hd_holes(3.5, "portrait", "both", sidethick+2);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for( i=[0:1:hd_bays-1]) {
|
||||
translate([101.6-gap+adj,-(3*wallthick)-gap+hd_y_position+147,
|
||||
hd_z_position+(hd_space+27.1)*i])
|
||||
rotate([0,0,180]) hd_holes(3.5, "portrait", "both", sidethick+2);
|
||||
}
|
||||
}
|
||||
|
||||
// top edge front tab openings
|
||||
translate([-gap-sidethick-adj,depth-(3*wallthick)-gap-adj-30,
|
||||
case_z-(2*floorthick)])
|
||||
cube([sidethick+(2*adj),20,floorthick+tol]);
|
||||
translate([-gap-sidethick-adj,depth-(3*wallthick)-gap-adj-30-tol,
|
||||
case_z-(2*floorthick)])
|
||||
cube([sidethick+(2*adj),10+tol,(3*floorthick)+adj]);
|
||||
// top edge rear tab openings
|
||||
translate([-gap-sidethick-adj,30-wallthick-gap+adj,
|
||||
case_z-(2*floorthick)])
|
||||
cube([sidethick+(2*adj),20,floorthick+tol]);
|
||||
translate([-gap-sidethick-adj,30-wallthick-gap+adj-tol,
|
||||
case_z-(2*floorthick)])
|
||||
cube([sidethick+(2*adj),10+tol,(3*floorthick)+adj]);
|
||||
|
||||
// bottom edge front tab openings
|
||||
translate([-gap-sidethick-adj,depth-(3*wallthick)-gap-adj-30,-tol])
|
||||
cube([sidethick+(2*adj),20,floorthick+tol]);
|
||||
translate([-gap-sidethick-adj,depth-(3*wallthick)-gap-adj-30-tol,-(2*floorthick)-adj])
|
||||
cube([sidethick+(2*adj),10+tol,(3*floorthick)+adj]);
|
||||
|
||||
// bottom edge rear tab openings
|
||||
translate([-gap-sidethick-adj,30-wallthick-gap+adj,-tol])
|
||||
cube([sidethick+(2*adj),20,floorthick+tol]);
|
||||
translate([-gap-sidethick-adj,30-wallthick-gap+adj-tol,-(2*floorthick)-adj])
|
||||
cube([sidethick+(2*adj),10+tol,(3*floorthick)+adj]);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
if(case_design == "tray_sides") {
|
||||
if(side == "right") {
|
||||
difference() {
|
||||
@@ -256,29 +567,72 @@ module case_side(case_design, side) {
|
||||
}
|
||||
}
|
||||
// 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);
|
||||
if(case_design != "panel_nas") {
|
||||
if(sbc_highlight == true) {
|
||||
#translate([pcb_loc_x ,pcb_loc_y,bottom_height-pcb_z+pcb_loc_z-adj-adj])
|
||||
sbc(sbc_model, cooling, fan_size, gpio_opening, uart_opening, true);
|
||||
}
|
||||
else {
|
||||
translate([pcb_loc_x ,pcb_loc_y,bottom_height-pcb_z+pcb_loc_z-adj-adj])
|
||||
sbc(sbc_model, cooling, fan_size, gpio_opening, uart_opening, true);
|
||||
}
|
||||
}
|
||||
else {
|
||||
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);
|
||||
if(nas_sbc_location == "top") {
|
||||
if(sbc_highlight == true) {
|
||||
#translate([pcb_loc_x ,pcb_loc_y,case_z-(top_height+pcb_loc_z+(2*floorthick))])
|
||||
sbc(sbc_model, cooling, fan_size, gpio_opening, uart_opening, true);
|
||||
}
|
||||
else {
|
||||
translate([pcb_loc_x ,pcb_loc_y,case_z-(top_height+pcb_loc_z+(2*floorthick))])
|
||||
sbc(sbc_model, cooling, fan_size, gpio_opening, uart_opening, true);
|
||||
}
|
||||
}
|
||||
if(nas_sbc_location == "bottom") {
|
||||
if(sbc_highlight == true) {
|
||||
#translate([pcb_loc_x ,pcb_loc_y,bottom_height-pcb_z+pcb_loc_z])
|
||||
sbc(sbc_model, cooling, fan_size, gpio_opening, uart_opening, true);
|
||||
}
|
||||
else {
|
||||
translate([pcb_loc_x ,pcb_loc_y,bottom_height-pcb_z+pcb_loc_z])
|
||||
sbc(sbc_model, cooling, fan_size, gpio_opening, uart_opening, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
// indents
|
||||
if(indents == true) {
|
||||
|
||||
for (i=[1:11:len(sbc_data[s[0]])-2]) {
|
||||
class = sbc_data[s[0]][i+1];
|
||||
type = sbc_data[s[0]][i+2];
|
||||
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];
|
||||
pcbid = sbc_data[s[0]][i+3];
|
||||
pcbloc_x = sbc_data[s[0]][i+4];
|
||||
pcbloc_y = sbc_data[s[0]][i+5];
|
||||
pcbloc_z = sbc_data[s[0]][i+6];
|
||||
if(class == "pcb") {
|
||||
for (i=[1:11:len(sbc_data[s[0]])-2]) {
|
||||
class = sbc_data[s[0]][i+1];
|
||||
type = sbc_data[s[0]][i+2];
|
||||
id = sbc_data[s[0]][i+3];
|
||||
loc_x = sbc_data[s[0]][i+4]+pcb_loc_x+pcbloc_x;
|
||||
loc_y = sbc_data[s[0]][i+5]+pcb_loc_y+pcbloc_y;
|
||||
loc_z = sbc_data[s[0]][i+6]+pcb_loc_z+pcbloc_z;
|
||||
side = sbc_data[s[0]][i+7];
|
||||
rotation = sbc_data[s[0]][i+8];
|
||||
if(id == pcbid && case_design != "panel_nas") {
|
||||
indent(loc_x, loc_y, bottom_height+loc_z-adj, rotation[2], side, class, type, wallthick, gap, floorthick, pcb_z);
|
||||
}
|
||||
if(id == pcbid && case_design == "panel_nas" && nas_sbc_location == "bottom") {
|
||||
indent(loc_x, loc_y, bottom_height+loc_z-adj, rotation[2], side, class,
|
||||
type, 2*wallthick, gap, floorthick, pcb_z);
|
||||
|
||||
indent(loc_x, loc_y, bottom_height+pcb_loc_z-adj, rotation[2], side, class, type, wallthick, gap, floorthick, pcb_z);
|
||||
}
|
||||
}
|
||||
if(id == pcbid && case_design == "panel_nas" && nas_sbc_location == "top") {
|
||||
indent(loc_x, loc_y, case_z-(top_height+pcb_loc_z+(2*floorthick))+.5, rotation[2],
|
||||
side, class, type, 2*wallthick, gap, floorthick, pcb_z);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(accessory_name != "none") {
|
||||
|
||||
@@ -47,7 +47,7 @@ module case_top(case_design) {
|
||||
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],
|
||||
vertical=[corner_fillet-wallthick,corner_fillet-wallthick,corner_fillet-wallthick,corner_fillet-wallthick],
|
||||
top=[edge_fillet,edge_fillet,edge_fillet,edge_fillet,edge_fillet],
|
||||
bottom=[0,0,0,0], $fn=90);
|
||||
}
|
||||
@@ -70,6 +70,26 @@ module case_top(case_design) {
|
||||
cube([8,wallthick+2*adj,floorthick]);
|
||||
}
|
||||
}
|
||||
if(case_design == "panel_nas") {
|
||||
x_adj = pcb_width > 100 ? width-2*sidethick : 101.6+case_offset_x;
|
||||
xtab_adj = pcb_width > 100 ? width-gap-2*sidethick-adj : 101.6-gap+case_offset_x-adj;
|
||||
union() {
|
||||
translate([-gap,-wallthick,case_z-2*floorthick])
|
||||
cube([x_adj,depth-(2*wallthick),floorthick]);
|
||||
translate([-gap-sidethick+(2*adj),depth-(3*wallthick)-gap-adj-20,
|
||||
case_z-2*floorthick])
|
||||
cube([sidethick+(2*adj),10,floorthick]);
|
||||
translate([xtab_adj,depth-(3*wallthick)-gap-adj-20,
|
||||
case_z-2*floorthick])
|
||||
cube([sidethick+2*adj,10,floorthick]);
|
||||
translate([-gap-sidethick+(2*adj),40-wallthick-gap+adj,
|
||||
case_z-2*floorthick])
|
||||
cube([sidethick+2*adj,10,floorthick]);
|
||||
translate([xtab_adj,40-wallthick-gap+adj,
|
||||
case_z-2*floorthick])
|
||||
cube([sidethick+2*adj,10,floorthick]);
|
||||
}
|
||||
}
|
||||
if(case_design == "stacked") {
|
||||
translate([(width/2)-wallthick-gap,(depth/2)-wallthick-gap,
|
||||
case_z-(floorthick/2)])
|
||||
@@ -91,8 +111,8 @@ module case_top(case_design) {
|
||||
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);
|
||||
vertical=[corner_fillet-wallthick,corner_fillet-wallthick,corner_fillet-wallthick,
|
||||
corner_fillet-wallthick],top=[0,0,0,0],bottom=[0,0,0,0], $fn=90);
|
||||
for (i=[1:11:len(sbc_data[s[0]])-2]) {
|
||||
class = sbc_data[s[0]][i+1];
|
||||
type = sbc_data[s[0]][i+2];
|
||||
@@ -104,7 +124,8 @@ module case_top(case_design) {
|
||||
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)) {
|
||||
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));
|
||||
}
|
||||
@@ -114,7 +135,8 @@ module case_top(case_design) {
|
||||
}
|
||||
}
|
||||
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)) {
|
||||
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));
|
||||
}
|
||||
@@ -124,7 +146,8 @@ module case_top(case_design) {
|
||||
}
|
||||
}
|
||||
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)) {
|
||||
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));
|
||||
}
|
||||
@@ -134,7 +157,8 @@ module case_top(case_design) {
|
||||
}
|
||||
}
|
||||
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)) {
|
||||
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));
|
||||
}
|
||||
@@ -204,13 +228,13 @@ module case_top(case_design) {
|
||||
}
|
||||
else {
|
||||
difference() {
|
||||
translate([pcb_width/2,pcb_depth/2,bottom_height+(top_height/2)-lip/2]) rotate([0,0,0])
|
||||
translate([pcb_width/2,pcb_depth/2,bottom_height+(top_height/2)-lip/2])
|
||||
cylinder_fillet_inside(h=top_height+lip, r=hex_diameter/2,
|
||||
top=edge_fillet, bottom=0, $fn=6, fillet_fn=case_ffn, center=true);
|
||||
translate([pcb_width/2,pcb_depth/2,bottom_height+(top_height/2)-floorthick-lip/2])
|
||||
rotate([0,0,0]) cylinder_fillet_inside(h=top_height+lip, r=(hex_diameter/2)-wallthick,
|
||||
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])
|
||||
translate([pcb_width/2,pcb_depth/2,bottom_height-adj-lip/2])
|
||||
cylinder_fillet_inside(h=lip+2*adj, r=(hex_diameter/2)-wallthick/2+tol/2,
|
||||
top=edge_fillet-1, bottom=0, $fn=6, fillet_fn=case_ffn, center=true);
|
||||
// io cutout
|
||||
@@ -243,21 +267,22 @@ module case_top(case_design) {
|
||||
|
||||
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);
|
||||
vertical=[corner_fillet-wallthick,corner_fillet-wallthick,corner_fillet-wallthick,
|
||||
corner_fillet-wallthick],top=[0,0,0,0],
|
||||
bottom=[edge_fillet,edge_fillet,edge_fillet,edge_fillet,edge_fillet], $fn=90);
|
||||
}
|
||||
// snap top outdent
|
||||
difference() {
|
||||
translate([-wallthick-gap+1.25+tol,(depth/2)-((depth*.75)/2)+2.5-gap-wallthick,case_z-.5])
|
||||
rotate([0,45,0]) cube([4,(depth*.75)-5,4]);
|
||||
translate([-wallthick-gap+3,(depth/2)-((depth*.75)/2)+1.25-gap-wallthick,case_z+floorthick-5.75])
|
||||
rotate([0,0,0]) cube([6,(depth*.75)-2,6]);
|
||||
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]);
|
||||
translate([width-wallthick-gap-8.5,(depth/2)-((depth*.75)/2)+1.25-gap-wallthick,
|
||||
case_z+floorthick-5.75]) cube([6,(depth*.75)-2,6]);
|
||||
}
|
||||
}
|
||||
if(case_design == "fitted") {
|
||||
@@ -270,7 +295,7 @@ module case_top(case_design) {
|
||||
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],
|
||||
vertical=[corner_fillet-wallthick,corner_fillet-wallthick,corner_fillet-wallthick,corner_fillet-wallthick],
|
||||
top=[edge_fillet,edge_fillet,edge_fillet,edge_fillet,edge_fillet],
|
||||
bottom=[0,0,0,0], $fn=90);
|
||||
}
|
||||
@@ -306,77 +331,194 @@ module case_top(case_design) {
|
||||
pcbhole_z = sbc_data[s[0]][i+6];
|
||||
pcbhole_size = sbc_data[s[0]][i+9][0];
|
||||
pcbhole_pos = sbc_data[s[0]][i+10][4];
|
||||
case_z = case_design == "fitted" || case_design == "tray_sides" ||
|
||||
case_design == "tray_vu5" || case_design == "tray_vu7" ? case_z+floorthick :
|
||||
case_design == "snap" ? case_z+(2 * floorthick) :
|
||||
case_design == "panel_nas" ? case_z-floorthick : case_z;
|
||||
|
||||
if (class == "pcbhole" && id == 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 == 0 && pcbhole_pos == "left_rear" &&
|
||||
top_rear_left_enable == true && top_standoff[6] != "blind") {
|
||||
translate([pcbhole_x,pcbhole_y,case_z-(floorthick+adj)])
|
||||
cylinder(d=top_standoff[4]-.2, h=floorthick+(2*adj));
|
||||
}
|
||||
if (class == "pcbhole" && id == 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 == 0 && pcbhole_pos == "left_front" &&
|
||||
top_front_left_enable == true && top_standoff[6] != "blind") {
|
||||
translate([pcbhole_x,pcbhole_y,case_z-(floorthick+adj)])
|
||||
cylinder(d=top_standoff[4]-.2, h=floorthick+(2*adj));
|
||||
}
|
||||
if (class == "pcbhole" && id == 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 == 0 && pcbhole_pos == "right_rear" &&
|
||||
top_rear_right_enable == true && top_standoff[6] != "blind") {
|
||||
translate([pcbhole_x,pcbhole_y,case_z-(floorthick+adj)])
|
||||
cylinder(d=top_standoff[4]-.2, h=floorthick+(2*adj));
|
||||
}
|
||||
if (class == "pcbhole" && id == 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);
|
||||
if (class == "pcbhole" && id == 0 && pcbhole_pos == "right_front" &&
|
||||
top_front_right_enable == true && top_standoff[6] != "blind") {
|
||||
translate([pcbhole_x,pcbhole_y,case_z-(floorthick+adj)])
|
||||
cylinder(d=top_standoff[4]-.2, h=floorthick+(2*adj));
|
||||
}
|
||||
}
|
||||
}
|
||||
// multi-pcb standoff holes
|
||||
if(multipcb_top_standoffs == true) {
|
||||
for (i=[1:11:len(sbc_data[s[0]])-2]) {
|
||||
class = sbc_data[s[0]][i+1];
|
||||
type = sbc_data[s[0]][i+2];
|
||||
pcbid = sbc_data[s[0]][i+3];
|
||||
pcbloc_x = sbc_data[s[0]][i+4];
|
||||
pcbloc_y = sbc_data[s[0]][i+5];
|
||||
pcbloc_z = sbc_data[s[0]][i+6];
|
||||
if(class == "pcb") {
|
||||
for (i=[1:11:len(sbc_data[s[0]])-2]) {
|
||||
pcbclass = sbc_data[s[0]][i+1];
|
||||
pcbtype = sbc_data[s[0]][i+2];
|
||||
id = sbc_data[s[0]][i+3];
|
||||
pcbhole_x = sbc_data[s[0]][i+4]+pcb_loc_x+pcbloc_x;
|
||||
pcbhole_y = sbc_data[s[0]][i+5]+pcb_loc_y+pcbloc_y;
|
||||
pcbhole_z = sbc_data[s[0]][i+6];
|
||||
pcbhole_size = sbc_data[s[0]][i+9][0];
|
||||
pcbhole_state = sbc_data[s[0]][i+10][0];
|
||||
pcbhole_pos = sbc_data[s[0]][i+10][4];
|
||||
case_z = case_design == "fitted" || case_design == "tray_sides" ||
|
||||
case_design == "tray_vu5" || case_design == "tray_vu7" ? case_z+floorthick :
|
||||
case_design == "snap" ? case_z+(2 * floorthick) :
|
||||
case_design == "panel_nas" ? case_z-floorthick : case_z;
|
||||
|
||||
if(id == pcbid && id != 0 && pcbclass == "pcbhole") {
|
||||
if (pcbclass == "pcbhole" && pcbhole_pos == "left_rear" &&
|
||||
multipcb_top_rear_left_enable == true &&
|
||||
(pcbhole_state == "top" || pcbhole_state == "both")) {
|
||||
translate([pcbhole_x,pcbhole_y,case_z-(floorthick+adj)])
|
||||
cylinder(d=multipcb_top_standoff[4]-.2, h=floorthick+(2*adj));
|
||||
}
|
||||
if (pcbclass == "pcbhole" && pcbhole_pos == "left_front" &&
|
||||
multipcb_top_front_left_enable == true &&
|
||||
(pcbhole_state == "top" || pcbhole_state == "both")) {
|
||||
translate([pcbhole_x,pcbhole_y,case_z-(floorthick+adj)])
|
||||
cylinder(d=multipcb_top_standoff[4]-.2, h=floorthick+(2*adj));
|
||||
}
|
||||
if (pcbclass == "pcbhole" && pcbhole_pos == "right_rear" &&
|
||||
multipcb_top_rear_right_enable == true &&
|
||||
(pcbhole_state == "top" || pcbhole_state == "both")) {
|
||||
translate([pcbhole_x,pcbhole_y,case_z-(floorthick+adj)])
|
||||
cylinder(d=multipcb_top_standoff[4]-.2, h=floorthick+(2*adj));
|
||||
}
|
||||
if (pcbclass == "pcbhole" && pcbhole_pos == "right_front" &&
|
||||
multipcb_top_front_right_enable == true &&
|
||||
(pcbhole_state == "top" || pcbhole_state == "both")) {
|
||||
translate([pcbhole_x,pcbhole_y,case_z-(floorthick+adj)])
|
||||
cylinder(d=multipcb_top_standoff[4]-.2, h=floorthick+(2*adj));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// extended standoff holes
|
||||
if(ext_top_standoffs == true) {
|
||||
|
||||
case_z = case_design == "fitted" || case_design == "tray_sides" ||
|
||||
case_design == "tray_vu5" || case_design == "tray_vu7" ? case_z+floorthick :
|
||||
case_design == "snap" ? case_z+(2 * floorthick) :
|
||||
case_design == "panel_nas" ? case_z-floorthick : case_z;
|
||||
|
||||
// right-rear standoff
|
||||
if((width-pcb_loc_x-pcb_width-(gap+2*wallthick) >= 10 || pcb_loc_y >= 10) &&
|
||||
if((width-pcb_loc_x-pcb_width-(gap+2*wallthick) >= ext_top_standoff_support_size ||
|
||||
pcb_loc_y >= ext_top_standoff_support_size) &&
|
||||
ext_top_rear_right_enable == true && ext_top_standoff[6] != "blind") {
|
||||
translate([width-ext_top_standoff_support_size/4-(2*(wallthick+gap))-(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);
|
||||
translate([width-ext_top_standoff_support_size/4-(2*(wallthick+gap)),
|
||||
ext_top_standoff_support_size/4,case_z-(floorthick+adj)])
|
||||
cylinder(d=ext_top_standoff[4]-.2, h=floorthick+(2*adj));
|
||||
}
|
||||
// right-front standoff
|
||||
if(((width-pcb_loc_x-pcb_width-(gap+2*wallthick) >= 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);
|
||||
if(((width-pcb_loc_x-pcb_width-(gap+2*wallthick) >= ext_top_standoff_support_size &&
|
||||
depth-pcb_loc_y-pcb_depth >= ext_top_standoff_support_size) ||
|
||||
(width-pcb_loc_x-pcb_width-(gap+2*wallthick) >= ext_top_standoff_support_size &&
|
||||
depth-pcb_loc_y-pcb_depth <= ext_top_standoff_support_size) ||
|
||||
(width-pcb_loc_x-pcb_width-(gap+2*wallthick) <= ext_top_standoff_support_size &&
|
||||
depth-pcb_loc_y-pcb_depth >= ext_top_standoff_support_size)) &&
|
||||
ext_top_front_right_enable == true && ext_top_standoff[6] != "blind") {
|
||||
translate([width-ext_top_standoff_support_size/4-(2*(wallthick+gap)),
|
||||
depth-ext_top_standoff_support_size/4-(2*(wallthick+gap)),case_z-(floorthick+adj)])
|
||||
cylinder(d=ext_top_standoff[4]-.2, h=floorthick+(2*adj));
|
||||
}
|
||||
// left-rear standoff
|
||||
if((pcb_loc_x >= 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);
|
||||
if((pcb_loc_x >= ext_top_standoff_support_size || pcb_loc_y >= ext_top_standoff_support_size) &&
|
||||
ext_top_rear_left_enable == true && ext_top_standoff[6] != "blind") {
|
||||
translate([ext_top_standoff_support_size/4, ext_top_standoff_support_size/4,case_z-(floorthick+adj)])
|
||||
cylinder(d=ext_top_standoff[4]-.2, h=floorthick+(2*adj));
|
||||
}
|
||||
// left-front standoff
|
||||
if(((pcb_loc_x >= 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);
|
||||
if(((pcb_loc_x >= ext_top_standoff_support_size &&
|
||||
(depth-(pcb_loc_y+pcb_depth)) >= ext_top_standoff_support_size) ||
|
||||
(pcb_loc_x <= ext_top_standoff_support_size &&
|
||||
(depth-(pcb_loc_y+pcb_depth)) >= ext_top_standoff_support_size) ||
|
||||
(pcb_loc_x >= ext_top_standoff_support_size &&
|
||||
(depth-(pcb_loc_y+pcb_depth)) <= ext_top_standoff_support_size)) &&
|
||||
ext_top_front_left_enable == true && ext_top_standoff[6] != "blind") {
|
||||
translate([ext_top_standoff_support_size/4,
|
||||
depth-ext_top_standoff_support_size/4-(2*(wallthick+gap)),case_z-(floorthick+adj)])
|
||||
cylinder(d=ext_top_standoff[4]-.2, h=floorthick+(2*adj));
|
||||
}
|
||||
}
|
||||
// top cover pattern
|
||||
if(top_cover_pattern != "solid") {
|
||||
xvent8_adj = pcb_width > 100 ? width/5.5 : width/6;
|
||||
if(top_cover_pattern == "hex_5mm") {
|
||||
translate([1,0,case_z-2]) vent_hex((width)/3.75,(depth)/6,floorthick+4,5,1.5,"horizontal");
|
||||
if(case_design == "panel_nas") {
|
||||
translate([6,5,case_z-(2*floorthick)])
|
||||
vent_hex((width-10)/3.75,(depth-10)/7,floorthick+4,5,1.5,"horizontal");
|
||||
}
|
||||
else {
|
||||
translate([1,0,case_z-(2*floorthick)]) vent_hex(width/3.75,depth/6,floorthick+4,5,1.5,"horizontal");
|
||||
}
|
||||
}
|
||||
if(top_cover_pattern == "hex_8mm") {
|
||||
translate([1,2,case_z-2]) vent_hex((width)/5.5,(depth)/9.5,floorthick+4,8,1.5,"horizontal");
|
||||
if(top_cover_pattern == "hex_8mm") {
|
||||
if(case_design == "panel_nas") {
|
||||
translate([-gap+5,6,case_z-(2*floorthick)]) vent_hex(xvent8_adj,depth/9.5,floorthick+4,8,1.5,"horizontal");
|
||||
}
|
||||
else {
|
||||
translate([1,2,case_z-(2*floorthick)]) vent_hex(width/5.5,depth/9.5,floorthick+4,8,1.5,"horizontal");
|
||||
}
|
||||
}
|
||||
if(top_cover_pattern == "linear_vertical") {
|
||||
translate([0,-gap,case_z-2]) vent(wallthick,depth-2*wallthick-gap,floorthick+4,1,1,(width-2*wallthick-gap)/4,"horizontal");
|
||||
if(case_design == "panel_nas") {
|
||||
translate([wallthick+gap,wallthick,case_z-(2*floorthick)])
|
||||
vent(wallthick,depth-6*wallthick-gap,floorthick+4,1,1,(width-2*(sidethick+gap))/5.35,"horizontal");
|
||||
}
|
||||
else {
|
||||
translate([0,-gap,case_z-(2*floorthick)])
|
||||
vent(wallthick,depth-2*wallthick-gap,floorthick+4,1,1,(width-2*wallthick-gap)/4,"horizontal");
|
||||
}
|
||||
}
|
||||
if(top_cover_pattern == "linear_horizontal") {
|
||||
translate([-gap,-gap,case_z-2]) vent(width-2*wallthick-gap,wallthick,floorthick+4,1,(depth-2*wallthick-gap)/3,1,"horizontal");
|
||||
if(case_design == "panel_nas") {
|
||||
translate([wallthick+gap,wallthick,case_z-(2*floorthick)])
|
||||
vent(width-4*(sidethick+gap),wallthick,floorthick+4,1,
|
||||
(depth-2*(wallthick-gap))/4.35,1,"horizontal");
|
||||
}
|
||||
else {
|
||||
translate([-gap,-gap,case_z-(2*floorthick)])
|
||||
vent(width-2*wallthick-gap,wallthick,floorthick+4,1,(depth-2*wallthick-gap)/3,1,"horizontal");
|
||||
}
|
||||
}
|
||||
if(top_cover_pattern == "astroid") {
|
||||
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");
|
||||
xast_adj = pcb_width <= 100 ? 8 : 6;
|
||||
if(case_design == "panel_nas") {
|
||||
for(c=[xast_adj:12:depth-16]) {
|
||||
for(r=[8:12:width-16]) {
|
||||
translate([r,c,case_z-(2*floorthick)-adj])
|
||||
linear_extrude(floorthick+5) import("./dxf/astroid_8mm.dxf");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for(c=[3:12:depth-8]) {
|
||||
for(r=[4:12:width-8]) {
|
||||
translate([r,c,case_z-(2*floorthick)-adj])
|
||||
linear_extrude(floorthick+5) import("./dxf/astroid_8mm.dxf");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// rear io shield opening for standard form motherboards
|
||||
@@ -406,13 +548,22 @@ module case_top(case_design) {
|
||||
pcbhole_z = sbc_data[s[0]][i+6];
|
||||
pcbhole_size = sbc_data[s[0]][i+9][0];
|
||||
pcbhole_pos = sbc_data[s[0]][i+10][4];
|
||||
case_z = case_design == "fitted" || case_design == "tray_sides" ||
|
||||
case_design == "tray_vu5" || case_design == "tray_vu7" ? case_z+floorthick :
|
||||
case_design == "snap" ? case_z+(2 * floorthick) :
|
||||
case_design == "panel_nas" ? case_z-floorthick : case_z;
|
||||
stand_off_adj = case_design == "fitted" || case_design == "tray_sides" ||
|
||||
case_design == "tray_vu5" || case_design == "tray_vu7" ? floorthick :
|
||||
case_design == "snap" ? 2 * floorthick : 0;
|
||||
|
||||
if(class == "pcbhole" && id == pcb_id &&
|
||||
(pcbhole_pos == "left_rear" || pcbhole_pos == "left_front" || pcbhole_pos == "right_rear" || pcbhole_pos == "right_front")) {
|
||||
(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_height+top_rear_left_adjust-pcb_loc_z+stand_off_adj,
|
||||
top_standoff[3],
|
||||
top_standoff[4],
|
||||
top_standoff[5],
|
||||
@@ -429,7 +580,7 @@ module case_top(case_design) {
|
||||
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_height+top_front_left_adjust-pcb_loc_z+stand_off_adj,
|
||||
top_standoff[3],
|
||||
top_standoff[4],
|
||||
top_standoff[5],
|
||||
@@ -446,7 +597,7 @@ module case_top(case_design) {
|
||||
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_height+top_rear_right_adjust-pcb_loc_z+stand_off_adj,
|
||||
top_standoff[3],
|
||||
top_standoff[4],
|
||||
top_standoff[5],
|
||||
@@ -463,7 +614,7 @@ module case_top(case_design) {
|
||||
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_height+top_front_right_adjust-pcb_loc_z+stand_off_adj,
|
||||
top_standoff[3],
|
||||
top_standoff[4],
|
||||
top_standoff[5],
|
||||
@@ -479,13 +630,129 @@ module case_top(case_design) {
|
||||
}
|
||||
}
|
||||
}
|
||||
// multi-pcb standoffs
|
||||
if(multipcb_top_standoffs == true) {
|
||||
for (i=[1:11:len(sbc_data[s[0]])-2]) {
|
||||
class = sbc_data[s[0]][i+1];
|
||||
type = sbc_data[s[0]][i+2];
|
||||
pcbid = sbc_data[s[0]][i+3];
|
||||
pcbloc_x = sbc_data[s[0]][i+4];
|
||||
pcbloc_y = sbc_data[s[0]][i+5];
|
||||
pcbloc_z = sbc_data[s[0]][i+6];
|
||||
if(class == "pcb") {
|
||||
for (i=[1:11:len(sbc_data[s[0]])-2]) {
|
||||
pcbclass = sbc_data[s[0]][i+1];
|
||||
pcbtype = sbc_data[s[0]][i+2];
|
||||
id = sbc_data[s[0]][i+3];
|
||||
pcbhole_x = sbc_data[s[0]][i+4]+pcb_loc_x+pcbloc_x;
|
||||
pcbhole_y = sbc_data[s[0]][i+5]+pcb_loc_y+pcbloc_y;
|
||||
pcbhole_z = sbc_data[s[0]][i+6];
|
||||
pcbhole_size = sbc_data[s[0]][i+9][0];
|
||||
pcbhole_state = sbc_data[s[0]][i+10][0];
|
||||
pcbhole_pos = sbc_data[s[0]][i+10][4];
|
||||
case_z = case_design == "fitted" || case_design == "tray_sides" ||
|
||||
case_design == "tray_vu5" || case_design == "tray_vu7" ? case_z+floorthick :
|
||||
case_design == "snap" ? case_z+(2 * floorthick) :
|
||||
case_design == "panel_nas" ? case_z-floorthick : case_z;
|
||||
stand_off_adj = case_design == "fitted" || case_design == "tray_sides" ||
|
||||
case_design == "tray_vu5" || case_design == "tray_vu7" ? floorthick :
|
||||
case_design == "snap" ? 2 * floorthick : 0;
|
||||
|
||||
if(pcbclass == "pcbhole" && pcbid == id && id != 0) {
|
||||
if (pcbhole_pos == "left_rear" && multipcb_top_rear_left_enable == true &&
|
||||
(pcbhole_state == "top" || pcbhole_state == "both")) {
|
||||
top_support = multipcb_top_sidewall_support == true ? multipcb_top_rear_left_support : "none";
|
||||
pcb_standoff = [multipcb_top_standoff[0],
|
||||
multipcb_top_standoff[1],
|
||||
top_height+top_rear_right_adjust-pcb_loc_z+stand_off_adj,
|
||||
multipcb_top_standoff[3],
|
||||
multipcb_top_standoff[4],
|
||||
multipcb_top_standoff[5],
|
||||
multipcb_top_standoff[6],
|
||||
multipcb_top_standoff[7],
|
||||
top_support,
|
||||
multipcb_top_standoff[9],
|
||||
multipcb_top_standoff[10],
|
||||
multipcb_top_standoff[11],
|
||||
multipcb_top_standoff[12]];
|
||||
translate([pcbhole_x,pcbhole_y,case_z]) standoff(pcb_standoff,[false,10,2,"default"]);
|
||||
}
|
||||
if (pcbhole_pos == "left_front" && multipcb_top_front_left_enable == true &&
|
||||
(pcbhole_state == "top" || pcbhole_state == "both")) {
|
||||
top_support = multipcb_top_sidewall_support == true ? multipcb_top_front_left_support : "none";
|
||||
pcb_standoff = [multipcb_top_standoff[0],
|
||||
multipcb_top_standoff[1],
|
||||
top_height+top_rear_right_adjust-pcb_loc_z+stand_off_adj,
|
||||
multipcb_top_standoff[3],
|
||||
multipcb_top_standoff[4],
|
||||
multipcb_top_standoff[5],
|
||||
multipcb_top_standoff[6],
|
||||
multipcb_top_standoff[7],
|
||||
top_support,
|
||||
multipcb_top_standoff[9],
|
||||
multipcb_top_standoff[10],
|
||||
multipcb_top_standoff[11],
|
||||
multipcb_top_standoff[12]];
|
||||
translate([pcbhole_x,pcbhole_y,case_z]) standoff(pcb_standoff,[false,10,2,"default"]);
|
||||
}
|
||||
if (pcbhole_pos == "right_rear" && multipcb_top_rear_right_enable == true &&
|
||||
(pcbhole_state == "top" || pcbhole_state == "both")) {
|
||||
top_support = multipcb_top_sidewall_support == true ? multipcb_top_rear_right_support : "none";
|
||||
pcb_standoff = [multipcb_top_standoff[0],
|
||||
multipcb_top_standoff[1],
|
||||
top_height+top_rear_right_adjust-pcb_loc_z+stand_off_adj,
|
||||
multipcb_top_standoff[3],
|
||||
multipcb_top_standoff[4],
|
||||
multipcb_top_standoff[5],
|
||||
multipcb_top_standoff[6],
|
||||
multipcb_top_standoff[7],
|
||||
top_support,
|
||||
multipcb_top_standoff[9],
|
||||
multipcb_top_standoff[10],
|
||||
multipcb_top_standoff[11],
|
||||
multipcb_top_standoff[12]];
|
||||
translate([pcbhole_x,pcbhole_y,case_z]) standoff(pcb_standoff,[false,10,2,"default"]);
|
||||
}
|
||||
if (pcbhole_pos == "right_front" && multipcb_top_front_right_enable == true &&
|
||||
(pcbhole_state == "top" || pcbhole_state == "both")) {
|
||||
top_support = multipcb_top_sidewall_support == true ? multipcb_top_front_right_support : "none";
|
||||
pcb_standoff = [multipcb_top_standoff[0],
|
||||
multipcb_top_standoff[1],
|
||||
top_height+top_rear_right_adjust-pcb_loc_z+stand_off_adj,
|
||||
multipcb_top_standoff[3],
|
||||
multipcb_top_standoff[4],
|
||||
multipcb_top_standoff[5],
|
||||
multipcb_top_standoff[6],
|
||||
multipcb_top_standoff[7],
|
||||
top_support,
|
||||
multipcb_top_standoff[9],
|
||||
multipcb_top_standoff[10],
|
||||
multipcb_top_standoff[11],
|
||||
multipcb_top_standoff[12]];
|
||||
translate([pcbhole_x,pcbhole_y,case_z]) standoff(pcb_standoff,[false,10,2,"default"]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// extended standoffs
|
||||
if(ext_top_standoffs == true) {
|
||||
|
||||
case_z = case_design == "fitted" || case_design == "tray_sides" ||
|
||||
case_design == "tray_vu5" || case_design == "tray_vu7" ? case_z+floorthick :
|
||||
case_design == "snap" ? case_z+(2 * floorthick) :
|
||||
case_design == "panel_nas" ? case_z-floorthick : case_z;
|
||||
stand_off_adj = case_design == "fitted" || case_design == "tray_sides" ||
|
||||
case_design == "tray_vu5" || case_design == "tray_vu7" ? floorthick :
|
||||
case_design == "snap" ? 2 * floorthick : 0;
|
||||
|
||||
// extended right-rear standoff
|
||||
if((width-pcb_loc_x-pcb_width-(gap+2*wallthick) >= 10 || pcb_loc_y >= 10) && ext_top_rear_right_enable == true) {
|
||||
if((width-pcb_loc_x-pcb_width-(gap+2*wallthick) >= ext_top_standoff_support_size ||
|
||||
pcb_loc_y >= ext_top_standoff_support_size) && ext_top_rear_right_enable == true) {
|
||||
extended_standoff = [ext_top_standoff[0],
|
||||
ext_top_standoff[1],
|
||||
top_height+ext_top_rear_right_adjust,
|
||||
top_height+ext_top_rear_right_adjust+stand_off_adj,
|
||||
ext_top_standoff[3],
|
||||
ext_top_standoff[4],
|
||||
ext_top_standoff[5],
|
||||
@@ -496,17 +763,20 @@ module case_top(case_design) {
|
||||
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"]);
|
||||
translate([width-ext_top_standoff_support_size/4-(2*(wallthick+gap)),
|
||||
ext_top_standoff_support_size/4,case_z]) standoff(extended_standoff,[false,10,2,"default"]);
|
||||
}
|
||||
// extended right-front standoff
|
||||
if(((width-pcb_loc_x-pcb_width-(gap+2*wallthick) >= 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) {
|
||||
if(((width-pcb_loc_x-pcb_width-(gap+2*wallthick) >= ext_top_standoff_support_size &&
|
||||
depth-pcb_loc_y-pcb_depth >= ext_top_standoff_support_size) ||
|
||||
(width-pcb_loc_x-pcb_width-(gap+2*wallthick) >= ext_top_standoff_support_size &&
|
||||
depth-pcb_loc_y-pcb_depth <= ext_top_standoff_support_size) ||
|
||||
(width-pcb_loc_x-pcb_width-(gap+2*wallthick) <= ext_top_standoff_support_size &&
|
||||
depth-pcb_loc_y-pcb_depth >= ext_top_standoff_support_size)) &&
|
||||
ext_top_front_right_enable == true) {
|
||||
extended_standoff = [ext_top_standoff[0],
|
||||
ext_top_standoff[1],
|
||||
top_height+ext_top_front_right_adjust,
|
||||
top_height+ext_top_front_right_adjust+stand_off_adj,
|
||||
ext_top_standoff[3],
|
||||
ext_top_standoff[4],
|
||||
ext_top_standoff[5],
|
||||
@@ -517,36 +787,40 @@ module case_top(case_design) {
|
||||
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"]);
|
||||
translate([width-ext_top_standoff_support_size/4-(2*(wallthick+gap)),
|
||||
depth-ext_top_standoff_support_size/4-(2*(wallthick+gap)),case_z])
|
||||
standoff(extended_standoff,[false,10,2,"default"]);
|
||||
}
|
||||
// extended left-rear standoff
|
||||
if((pcb_loc_x >= 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"]);
|
||||
if((pcb_loc_x >= ext_top_standoff_support_size || pcb_loc_y >= ext_top_standoff_support_size) &&
|
||||
ext_top_rear_left_enable == true) {
|
||||
extended_standoff = [ext_top_standoff[0],
|
||||
ext_top_standoff[1],
|
||||
top_height+ext_top_rear_left_adjust+stand_off_adj,
|
||||
ext_top_standoff[3],
|
||||
ext_top_standoff[4],
|
||||
ext_top_standoff[5],
|
||||
ext_top_standoff[6],
|
||||
ext_top_standoff[7],
|
||||
ext_top_rear_left_support,
|
||||
ext_top_standoff[9],
|
||||
ext_top_standoff[10],
|
||||
ext_top_standoff[11],
|
||||
ext_top_standoff[12]];
|
||||
translate([ext_top_standoff_support_size/4,
|
||||
ext_top_standoff_support_size/4,case_z]) standoff(extended_standoff,[false,10,2,"default"]);
|
||||
}
|
||||
// extended left-front standoff
|
||||
if(((pcb_loc_x >= 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) {
|
||||
if(((pcb_loc_x >= ext_top_standoff_support_size &&
|
||||
(depth-(pcb_loc_y+pcb_depth)) >= ext_top_standoff_support_size) ||
|
||||
(pcb_loc_x <= ext_top_standoff_support_size &&
|
||||
(depth-(pcb_loc_y+pcb_depth)) >= ext_top_standoff_support_size) ||
|
||||
(pcb_loc_x >= ext_top_standoff_support_size &&
|
||||
depth-(pcb_loc_y+pcb_depth) <= ext_top_standoff_support_size)) &&
|
||||
ext_top_front_left_enable == true) {
|
||||
extended_standoff = [ext_top_standoff[0],
|
||||
ext_top_standoff[1],
|
||||
top_height+ext_top_front_left_adjust,
|
||||
top_height+ext_top_front_left_adjust+stand_off_adj,
|
||||
ext_top_standoff[3],
|
||||
ext_top_standoff[4],
|
||||
ext_top_standoff[5],
|
||||
@@ -557,8 +831,8 @@ module case_top(case_design) {
|
||||
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])
|
||||
translate([ext_top_standoff_support_size/4,
|
||||
depth-ext_top_standoff_support_size/4-(2*(wallthick+gap)), case_z])
|
||||
standoff(extended_standoff,[false,10,2,"default"]);
|
||||
}
|
||||
}
|
||||
@@ -594,38 +868,75 @@ module case_top(case_design) {
|
||||
// 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);
|
||||
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);
|
||||
#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);
|
||||
if(case_design != "panel_nas") {
|
||||
if(sbc_highlight == true) {
|
||||
#translate([pcb_loc_x ,pcb_loc_y,bottom_height-pcb_z+pcb_loc_z-adj])
|
||||
sbc(sbc_model, cooling, fan_size, gpio_opening, uart_opening, true);
|
||||
}
|
||||
else {
|
||||
translate([pcb_loc_x ,pcb_loc_y,bottom_height-pcb_z+pcb_loc_z-adj])
|
||||
sbc(sbc_model, cooling, fan_size, gpio_opening, uart_opening, true);
|
||||
}
|
||||
}
|
||||
else {
|
||||
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);
|
||||
if(nas_sbc_location == "top") {
|
||||
if(sbc_highlight == true) {
|
||||
#translate([pcb_loc_x ,pcb_loc_y,case_z-(top_height+pcb_loc_z+(2*floorthick))])
|
||||
sbc(sbc_model, cooling, fan_size, gpio_opening, uart_opening, true);
|
||||
}
|
||||
else {
|
||||
translate([pcb_loc_x ,pcb_loc_y,case_z-(top_height+pcb_loc_z+(2*floorthick))])
|
||||
sbc(sbc_model, cooling, fan_size, gpio_opening, uart_opening, true);
|
||||
}
|
||||
}
|
||||
if(nas_sbc_location == "bottom") {
|
||||
if(sbc_highlight == true) {
|
||||
#translate([pcb_loc_x ,pcb_loc_y,bottom_height-pcb_z+pcb_loc_z])
|
||||
sbc(sbc_model, cooling, fan_size, gpio_opening, uart_opening, true);
|
||||
}
|
||||
else {
|
||||
translate([pcb_loc_x ,pcb_loc_y,bottom_height-pcb_z+pcb_loc_z])
|
||||
sbc(sbc_model, cooling, fan_size, gpio_opening, uart_opening, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
// indents
|
||||
if(indents == true) {
|
||||
|
||||
for (i=[1:11:len(sbc_data[s[0]])-2]) {
|
||||
class = sbc_data[s[0]][i+1];
|
||||
type = sbc_data[s[0]][i+2];
|
||||
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);
|
||||
}
|
||||
pcbid = sbc_data[s[0]][i+3];
|
||||
pcbloc_x = sbc_data[s[0]][i+4];
|
||||
pcbloc_y = sbc_data[s[0]][i+5];
|
||||
pcbloc_z = sbc_data[s[0]][i+6];
|
||||
if(class == "pcb") {
|
||||
for (i=[1:11:len(sbc_data[s[0]])-2]) {
|
||||
class = sbc_data[s[0]][i+1];
|
||||
type = sbc_data[s[0]][i+2];
|
||||
id = sbc_data[s[0]][i+3];
|
||||
loc_x = sbc_data[s[0]][i+4]+pcb_loc_x+pcbloc_x;
|
||||
loc_y = sbc_data[s[0]][i+5]+pcb_loc_y+pcbloc_y;
|
||||
loc_z = sbc_data[s[0]][i+6]+pcb_loc_z+pcbloc_z;
|
||||
side = sbc_data[s[0]][i+7];
|
||||
rotation = sbc_data[s[0]][i+8];
|
||||
if(id == pcbid) {
|
||||
indent(loc_x, loc_y, bottom_height+loc_z-adj, rotation[2],
|
||||
side, class, type, wallthick, gap, floorthick, pcb_z);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// clean fillets
|
||||
if(case_design == "shell") {
|
||||
@@ -653,7 +964,8 @@ module case_top(case_design) {
|
||||
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]]);
|
||||
parametric_move_add(type,loc_x,loc_y,loc_z,face,rotation,
|
||||
parametric,size,data,[false,mask[1],mask[2],mask[3]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ module indent(loc_x, loc_y, loc_z, rotation, side, class, type, wallthick, gap,
|
||||
}
|
||||
// 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)
|
||||
place(loc_x-.75,-(wallthick+gap)+wallthick/2,loc_z+1.5,6,8,rotation,side)
|
||||
rotate([90,0,0]) long_slot(6,8,wallthick);
|
||||
}
|
||||
if(class == "video" && type == "hdmi_micro" && rotation == 90 && side == "top") {
|
||||
@@ -150,19 +150,19 @@ module indent(loc_x, loc_y, loc_z, rotation, side, class, type, wallthick, gap,
|
||||
}
|
||||
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);
|
||||
rotate([90,0,0]) cylinder(d=9, h=wallthick);
|
||||
}
|
||||
if(class == "power" && type == "pwr2.5_5x7.5" && rotation == 90 && side == "top") {
|
||||
place(-(wallthick+gap)+wallthick/2,loc_y-4.5,loc_z+2,7,7,rotation,side)
|
||||
rotate([90,0,0]) cylinder(d=7, h=wallthick);
|
||||
rotate([90,0,0]) cylinder(d=9, h=wallthick);
|
||||
}
|
||||
if(class == "power" && type == "pwr2.5_5x7.5" && rotation == 180 && side == "top") {
|
||||
place(loc_x-4.5,depth-(wallthick+gap)-7-wallthick/2,loc_z+2,7,7,rotation,side)
|
||||
rotate([90,0,0]) cylinder(d=7, h=wallthick);
|
||||
rotate([90,0,0]) cylinder(d=9, h=wallthick);
|
||||
}
|
||||
if(class == "power" && type == "pwr2.5_5x7.5" && rotation == 270 && side == "top") {
|
||||
place(width-(wallthick+gap)-7-wallthick/2,loc_y+2.5,loc_z+2,7,7,rotation,side)
|
||||
rotate([90,0,0]) cylinder(d=7, h=wallthick);
|
||||
rotate([90,0,0]) cylinder(d=9, h=wallthick);
|
||||
}
|
||||
// micro usb indent
|
||||
if(class == "usb2" && type == "micro" && rotation == 0 && side == "top") {
|
||||
@@ -209,7 +209,7 @@ module indent(loc_x, loc_y, loc_z, rotation, side, class, type, wallthick, gap,
|
||||
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)
|
||||
place(loc_x+2.5,depth-(wallthick+gap)-8-wallthick/2,loc_z+1.875,6,8,rotation,side)
|
||||
rotate([90,0,0]) long_slot(6,8,wallthick);
|
||||
}
|
||||
if(class == "usbc" && type == "single_horizontal" && rotation == 270 && side == "top") {
|
||||
@@ -234,7 +234,7 @@ module indent(loc_x, loc_y, loc_z, rotation, side, class, type, wallthick, gap,
|
||||
}
|
||||
// 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)
|
||||
place(loc_x+3.25,-(wallthick+gap)+wallthick/2,loc_z+2.75,8,8,rotation,side)
|
||||
rotate([90,0,0]) cylinder(d=10, h=wallthick);
|
||||
}
|
||||
if(class == "audio" && type == "jack_3.5" && rotation == 90 && side == "top") {
|
||||
@@ -242,11 +242,11 @@ module indent(loc_x, loc_y, loc_z, rotation, side, class, type, wallthick, gap,
|
||||
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)
|
||||
place(loc_x-5.5,depth-(wallthick+gap)-8-wallthick/2,loc_z+2,8,8,rotation,side)
|
||||
rotate([90,0,0]) cylinder(d=10, h=wallthick);
|
||||
}
|
||||
if(class == "audio" && type == "jack_3.5" && rotation == 270 && side == "top") {
|
||||
place(width-(wallthick+gap)-8-wallthick/2,loc_y+3.15,loc_z+2,8,8,rotation,side)
|
||||
place(width-(wallthick+gap)-8-wallthick/2,loc_y+3.25,loc_z+2.5,8,8,rotation,side)
|
||||
rotate([90,0,0]) cylinder(d=10, h=wallthick);
|
||||
}
|
||||
if(class == "audio" && type == "jack_3.5" && rotation == 0 && side == "bottom") {
|
||||
|
||||
@@ -55,7 +55,7 @@ module sub(type, loc_x, loc_y, loc_z, face, rotation, size, data, 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]);
|
||||
translate([loc_x,loc_y,loc_z]) rotate(rotation) hd_bottom_holes(data[0],data[1],data[2],data[3],data[4]);
|
||||
}
|
||||
if(type == "knockout") {
|
||||
translate([loc_x,loc_y,loc_z]) rotate(rotation) knockout(size_x,size_y,data[0],size_z,data[1],data[2]);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -33,7 +33,8 @@
|
||||
hk_boom_grill,hk_boom_speaker_holder,hk_boom_vring,hk_h3_port_extender_holder,hk_hc4_oled_holder,hk_uart_holder,
|
||||
hk_uart_strap,keyhole,nut_holder,pcb_holder,rectangle,round,slot,sphere,standoff,text,vent_panel_hex
|
||||
types for subtractive: art,fan_mask,hd_holes,knockout,rectangle,round,slot,sphere,text,vent,vent_hex
|
||||
types for model: adafruit_lcd,dsub,fan,hd25,hd35,hk_boom,hk_boom_speaker,hk_h3_port_extender,hk_hc4_oled,hk_lcd35,hk_m1s_ups,hk_netcard,
|
||||
types for model: adafruit_2030_powerboost,adafruit_4311_lcd,adafruit_4755_solar_charger,dsub,fan,hd25,hd35,hk_boom,
|
||||
hk_boom_speaker,hk_h3_port_extender,hk_hc4_oled,hk_lcd35,hk_m1s_ups,hk_netcard,
|
||||
hk_pwr_button,hk_speaker,hk_uart,hk_vu7c,hk_vu8m,hk_vu8s,hk_wb2,hk_xu4_shifter_shield,stl_model
|
||||
types for platter: access_cover,button_assembly,fan_cover,feet,hk_boom_speaker_holder,hk_boom_vring,hk_h3_port_extender_holder,hk_uart_strap,vent_panel_hex
|
||||
|
||||
@@ -118,19 +119,19 @@ accessory_data = [
|
||||
"sub","round",-3.75,54,-32,"left",[0,90,0],["case",false,false,false],[60,0,3],[0],[false,10,2,"default"],
|
||||
"sub","round",126.4,54,-32,"right",[0,90,0],["case",false,false,false],[60,0,3],[0],[false,10,2,"default"],
|
||||
"sub","vent",-3,22,13,"left",[0,0,90],["case",false,false,false],[2,10,5],[1,8,"vertical",1],[false,10,2,"default"],
|
||||
"add2","button",89.875,45,27,"top",[0,0,180],["sbc-case_z",false,false,true],[12,8,2],["cutout",[2,2,2,2],2.25],[true,10,2,"default"],
|
||||
"add2","button",89.875,34,27,"top",[0,0,180],["sbc-case_z",false,false,true],[12,8,2],["cutout",[2,2,2,2],2.25],[true,10,2,"default"],
|
||||
"add2","button",89.875,23,27,"top",[0,0,180],["sbc-case_z",false,false,true],[12,8,2],["cutout",[2,2,2,2],2.25],[true,10,2,"default"],
|
||||
"add2","button",89.875,12,27,"top",[0,0,180],["sbc-case_z",false,false,true],[12,8,2],["cutout",[2,2,2,2],2.25],[true,10,2,"default"],
|
||||
"add2","button",100.875,45,31,"top",[0,0,180],["sbc-case_z",false,false,true],[12,8,2],["cutout",[2,2,2,2],2.25],[true,10,2,"default"],
|
||||
"add2","button",100.875,34,31,"top",[0,0,180],["sbc-case_z",false,false,true],[12,8,2],["cutout",[2,2,2,2],2.25],[true,10,2,"default"],
|
||||
"add2","button",100.875,23,31,"top",[0,0,180],["sbc-case_z",false,false,true],[12,8,2],["cutout",[2,2,2,2],2.25],[true,10,2,"default"],
|
||||
"add2","button",100.875,12,31,"top",[0,0,180],["sbc-case_z",false,false,true],[12,8,2],["cutout",[2,2,2,2],2.25],[true,10,2,"default"],
|
||||
"add2","pcb_holder",.75,66.1,1.99,"bottom",[0,0,0],["case",false,false,false],[123.5,35,1.6],[2],[false,10,2,"default"],
|
||||
"add2","hk_boom_grill",16.5,72.5,21.5,"front",[90,0,180],["case",false,false,false],[0,0,2],["flat"],[false,10,2,"default"],
|
||||
"add2","hk_boom_grill",108,72.5,21.5,"front",[90,0,180],["case",false,false,false],[0,0,2],["flat"],[false,10,2,"default"],
|
||||
"add2","hk_boom_grill",16.5,72.5,21.5,"front",[90,0,180],["case",false,false,false],[0,0,2],["flat"],[true,10,2,"default"],
|
||||
"add2","hk_boom_grill",108,72.5,21.5,"front",[90,0,180],["case",false,false,false],[0,0,2],["flat"],[true,10,2,"default"],
|
||||
"add2","hk_uart_holder",10,0,1.9,"bottom",[0,0,0],["case",false,false,false],[10,10,0],[0],[true,10,2,"default"],
|
||||
"model","hk_uart",12.5,22,5,"bottom",[0,0,270],["case",false,false,false],[10,10,0],[0],[false,10,2,"default"],
|
||||
"model","hk_uart_strap",25,15,5,"bottom",[0,0,90],["case",false,false,false],[0,0,0],[0],[false,10,2,"default"],
|
||||
// "model","hk_boom",32.25,68,4,"bottom",[90,0,0],["case",false,false,false],[0,0,0],[true,"front"],[true,10,2,"default"],
|
||||
"model","hk_boom",32.25,68,4,"bottom",[90,0,0],["case",false,false,false],[0,0,0],[true,"front"],[true,10,2,"default"],
|
||||
"model","hk_boom_vring",76.75,64.5,31,"bottom",[90,0,0],["case",false,false,false],[0,0,0],[0],[false,10,2,"default"],
|
||||
"model","hk_lcd35",106.25,55,22.5,"bottom",[0,0,180],["sbc",false,false,true],[0,0,0],[0],[true,10,2,"default"],
|
||||
"model","hk_lcd35",106.25,55,18.5,"bottom",[0,0,180],["sbc",false,false,true],[0,0,0],[0],[true,10,2,"default"],
|
||||
"platter","hk_uart_strap",-35,75,-9,"bottom",[0,0,0],["case",false,false,false],[0,0,0],[0],[false,10,2,"default"],
|
||||
"platter","hk_boom_vring",-60,100,0,"bottom",[0,0,0],["case",false,false,false],[0,0,0],[0],[false,10,2,"default"]],
|
||||
|
||||
@@ -177,11 +178,27 @@ accessory_data = [
|
||||
"suball","round",10.5,-2,14.5,"top",[90,0,0],["case",false,false,false],[11,0,18],[0],[false,10,2,"default"],
|
||||
"suball","rectangle",35,-26,4,"top",[0,0,0],["case",false,false,false],[21,10,15.5],[[1,1,1,1]],[false,10,2,"default"]],
|
||||
|
||||
["c-series_rack19-1u",
|
||||
"add2","hd_holder",320,9,1.99,"bottom",[0,0,0],["case",false,false,false],[0,0,0],[2.5,"landscape"],[false,10,2,"default"],
|
||||
"model","hd25",320,9,2,"bottom",[0,0,0],["case",false,false,false],[0,0,0],["landscape",15],[true,25,2,"both"],
|
||||
"model","hd25",320,9,20.5,"bottom",[0,0,0],["case",false,false,false],[0,0,0],["landscape",15],[true,25,2,"default"]],
|
||||
|
||||
// Odroid-XU4
|
||||
["xu4_shifter_shield",
|
||||
"model","pillar",3.5,3.5,8,"bottom",[0,0,0],["sbc",true,true,true],[4,3,19],["hex","silver","top"],[false,10,2,"default"],
|
||||
"model","pillar",3.5,55.5,8,"bottom",[0,0,0],["sbc",true,true,true],[4,3,19],["hex","silver","top"],[false,10,2,"default"],
|
||||
"model","pillar",79.5,3.5,8,"bottom",[0,0,0],["sbc",true,true,true],[4,3,19],["hex","silver","top"],[false,10,2,"default"],
|
||||
"model","pillar",79.5,55.5,8,"bottom",[0,0,0],["sbc",true,true,true],[4,3,19],["hex","silver","top"],[false,10,2,"default"],
|
||||
"model","hk_xu4_shifter_shield",0,0,27,"bottom",[0,0,0],["sbc",true,true,true],[0,0,0],[0],[true,10,2,"default"]],
|
||||
|
||||
["xu4_keyhole",
|
||||
"add1","keyhole",40,30,0,"bottom",[0,0,0],["case",false,false,false],[0,0,0],[[7,3.2,6,2]],[true,10,2,"default"]],
|
||||
|
||||
// Odroid-HC4
|
||||
["hc4_panel_nas",
|
||||
"add2","hk_hc4_oled_holder",35,178,2.99,"bottom",[0,0,0],["case",true,true,false],[0,0,2],[0],[true,10,2,"default"],
|
||||
"model","hk_hc4_oled",35,178,2.99,"bottom",[0,0,0],["case",true,true,false],[0,0,0],[0],[true,10,2,"default"]],
|
||||
|
||||
["hc4_shell_drivebox2.5",
|
||||
"add2","hk_hc4_oled_holder",20,82,1.99,"bottom",[0,0,0],["case",false,true,false],[0,0,2],[0],[true,10,2,"default"],
|
||||
"model","hk_hc4_oled",20,82,1.99,"bottom",[0,0,0],["case",false,true,false],[0,0,0],[0],[false,10,2,"default"],
|
||||
@@ -243,6 +260,47 @@ accessory_data = [
|
||||
"model","fan_cover",37,-4,7,"bottom",[90,0,0],["case",true,false,false],[40,0,3],["fan_1"],[false,10,2,"default"],
|
||||
"platter","fan_cover",-50,50,0,"bottom",[0,0,0],["case",false,false,false],[40,0,3],["fan_1"],[false,10,2,"default"]],
|
||||
|
||||
// Odroid-N2
|
||||
["n-series_rack19-1u",
|
||||
"add2","hd_holder",234,101,1.99,"bottom",[0,0,180],["case",false,false,false],[0,0,0],[2.5,"portrait"],[false,10,2,"default"],
|
||||
"model","hd25",234,101,2,"bottom",[0,0,180],["case",false,false,false],[0,0,0],["portrait",15],[true,10,2,"both"],
|
||||
"model","hd25",234,101,20.5,"bottom",[0,0,180],["case",false,false,false],[0,0,0],["portrait",15],[true,10,2,"default"]],
|
||||
["n1_rack10-1u",
|
||||
"add2","hd_holder",1,10,1.99,"bottom",[0,0,0],["case",false,false,false],[0,0,0],[2.5,"landscape"],[false,10,2,"default"],
|
||||
"model","hd25",1,10,3,"bottom",[0,0,0],["case",false,false,false],[0,0,0],["landscape",15],[true,20,2,"both"],
|
||||
"model","hd25",1,10,20.5,"bottom",[0,0,0],["case",false,false,false],[0,0,0],["landscape",15],[true,20,2,"default"]],
|
||||
|
||||
// Odroid-M2
|
||||
["m2_shell",
|
||||
"add2","button",5.5,56,24,"top",[0,0,180],["sbc-case_z",false,false,true],[12,8,1.5],["cutout",[2,2,2,2],2.25],[true,10,2,"default"]],
|
||||
|
||||
// Adafruit models available at https://github.com/adafruit/Adafruit_CAD_Parts/tree/main
|
||||
["m2_eyespi_eink1.54",
|
||||
// "model","stl_model",109.62,9.8,19.25,"bottom",[0,0,180],["sbc",true,true,true],[0,0,0],[1,"stl/EYESPI-Dual_I2C.stl"],[false,10,2,"default"],
|
||||
// "model","stl_model",50.5,99.75,3,"bottom",[90,0,180],["sbc",false,false,false],[0,0,0],[1,"adafruit/4196 1.54in eink display SSD1681.stl"],[false,10,2,"default"],
|
||||
"add2","pcb_holder",56,99.5,49.5,"top",[180,0,180],["case",false,false,false],[47,35,2.5],[2],[false,10,2,"default"],
|
||||
"add2","standoff",13.5,104.5,5.5,"bottom",[90,0,0],["sbc",false,false,false],[0,0,0],[["m2.5+",3,3.25,3.6,6,3.25,"countersunk","hex",false,false,4.5,5.1]],[true,10,2,"default"],
|
||||
"add2","standoff",51.5,104.5,5.5,"bottom",[90,0,0],["sbc",false,false,false],[0,0,0],[["m2.5+",3,3.25,3.6,6,3.25,"countersunk","hex",false,false,4.5,5.1]],[true,10,2,"default"],
|
||||
"sub","rectangle",17,100,8.75,"top",[0,0,0],["sbc",true,true,true],[31,5,31.5],[[1,1,1,1]],[false,10,2,"default"],
|
||||
"sub","rectangle",80,83,8.75,"top",[0,0,0],["sbc",true,true,true],[5,7,15],[[1,1,1,1]],[false,10,2,"default"],
|
||||
"add1","rectangle",11,101.25,1.5,"bottom",[0,0,0],["sbc",false,false,false],[5,2,2.5],[[1,1,1,1]],[false,10,2,"default"],
|
||||
"add1","rectangle",49,101.25,1.5,"bottom",[0,0,0],["sbc",false,false,false],[5,2,2.5],[[1,1,1,1]],[false,10,2,"default"],
|
||||
"add2","button",5.5,56,25.5,"top",[0,0,0],["sbc-case_z",true,true,true],[10,0,25],["recess"],[true,10,2,"default"],
|
||||
"model","button_assembly",5.5,56,25.5,"top",[0,0,0],["sbc-case_z",true,true,true],[10,0,26],["recess"],[false,10,2,"default"],
|
||||
"platter","button_assembly",-20,0,0,"top",[0,0,0],["case",false,false,false],[10,0,26.5],["recess"],[false,10,2,"default"]],
|
||||
|
||||
|
||||
["m2_eyespi_lcd2.8",
|
||||
// "model","stl_model",109.62,9.8,19.25,"bottom",[0,0,180],["sbc",true,true,true],[0,0,0],[1,"stl/EYESPI-Dual_I2C.stl"],[false,10,2,"default"],
|
||||
// "model","stl_model",46,100.75,34,"bottom",[90,90,0],["sbc",false,false,false],[0,0,0],[1,"adafruit/2090 2.8in TFT Cap Touch.stl"],[false,10,2,"default"],
|
||||
"add2","pcb_holder",5,99.5,0,"bottom",[0,0,0],["case",false,false,false],[82,63,2.5],[2],[false,10,2,"default"],
|
||||
"add2","pcb_holder",87,99.5,68.5,"top",[180,0,180],["case",false,false,false],[82,63,2.5],[2],[false,10,2,"default"],
|
||||
"sub","rectangle",19,90.5,12,"top",[0,0,0],["case",false,true,false],[58,5,44],[[1,1,1,1]],[false,10,2,"default"],
|
||||
"add2","button",5.5,56,25.5,"top",[0,0,0],["sbc-case_z",true,true,true],[10,0,44],["recess"],[true,10,2,"default"],
|
||||
"model","button_assembly",5.5,56,25.5,"top",[0,0,0],["sbc-case_z",true,true,true],[10,0,44.5],["recess"],[false,10,2,"default"],
|
||||
"platter","button_assembly",-20,0,0,"top",[0,0,0],["case",false,false,false],[10,0,26.5],["recess"],[false,10,2,"default"]],
|
||||
|
||||
|
||||
// Odroid-M1S
|
||||
["m1s_shell_nvme",
|
||||
"sub","vent_hex",37,5,-1,"bottom",[0,0,0],["sbc",false,false,false],[11,3,5],[5,1.5,"horizontal",1],[false,10,2,"default"],
|
||||
@@ -368,6 +426,9 @@ accessory_data = [
|
||||
"platter","button_assembly",-20,0,0,"top",[0,0,0],["case",false,false,false],[10,0,11],["recess"],[false,10,2,"default"],
|
||||
"platter","button_assembly",-30,0,0,"top",[0,0,0],["case",false,false,false],[10,0,11],["recess"],[false,10,2,"default"]],
|
||||
|
||||
["h3_panel_nas",
|
||||
"model","hk_pwr_button",20,150,137,"top",[0,0,0],["case",true,true,true],[0,0,0],[0],[true,10,2,"default"]],
|
||||
|
||||
["h3_ultimate",
|
||||
"sub","vent",-3.5,30,58,"top",[0,0,90],["case",false,false,false],[2,12,4],[1,17,"vertical",1],[false,10,2,"default"],
|
||||
"sub","vent",111.5,30,58,"top",[0,0,90],["case",true,false,false],[2,12,4],[1,17,"vertical",1],[false,10,2,"default"],
|
||||
@@ -420,11 +481,45 @@ accessory_data = [
|
||||
"model","hk_pwr_button",18,113,55.25,"top",[0,0,180],["case",false,false,true],[0,0,0],[0],[true,10,2,"default"],
|
||||
"model","dsub",18,-1,46,"top",[90,90,0],["case",false,false,false],[0,0,0],["db9","female"],[true,10,2,"default"]],
|
||||
|
||||
// Odroid-H4
|
||||
["h4_panel_nas",
|
||||
"model","hk_pwr_button",20,150,206,"top",[0,0,0],["case",true,true,true],[0,0,0],[0],[true,10,2,"default"]],
|
||||
|
||||
["h4_panel_nas-bottom_sbc",
|
||||
"model","hk_pwr_button",20,155,183.5,"top",[0,0,0],["case",true,true,true],[0,0,0],[0],[true,10,2,"default"]],
|
||||
|
||||
["show2_shell",
|
||||
"model","hk_wb2",6.25,24.675,16,"bottom",[0,0,180],["sbc",true,true,true],[0,0,0],[0],[false,10,2,"default"],
|
||||
"sub","rectangle",.5,8,8.5,"top",[0,0,0],["case",false,false,false],[6,16.5,8],[[.5,.5,.5,.5]],[false,10,2,"default"]],
|
||||
|
||||
|
||||
// RPI
|
||||
["rpi5_m2hat",
|
||||
"model","pillar",3.5,3.5,9.65,"bottom",[0,0,0],["sbc",true,true,true],[4,3,16],["hex","#fee5a6","top"],[false,10,2,"default"],
|
||||
"model","pillar",3.5,52.5,9.65,"bottom",[0,0,0],["sbc",true,true,true],[4,3,16],["hex","#fee5a6","top"],[false,10,2,"default"],
|
||||
"model","pillar",61.5,3.5,9.65,"bottom",[0,0,0],["sbc",true,true,true],[4,3,16],["hex","#fee5a6","top"],[false,10,2,"default"],
|
||||
"model","pillar",61.5,52.5,9.65,"bottom",[0,0,0],["sbc",true,true,true],[4,3,16],["hex","#fee5a6","top"],[false,10,2,"default"],
|
||||
"model","rpi_m2hat",0,0,25.65,"top",[0,0,0],["sbc",true,true,true],[0,0,0],[0],[true,20,2,"default"]],
|
||||
|
||||
["rpi5_bottom_m2hat",
|
||||
// "model","stl_model",-1,0,7.6,"bottom",[0,0,0],["sbc",true,true,false],[0,0,0],[1,"./pimoroni-nvme-rpi5-base.stl"],[false,20,2,"default"],
|
||||
"model","pillar",3.5,3.5,1,"bottom",[0,0,0],["sbc",true,true,true],[4,3,7],["hex","#fee5a6","top"],[false,10,2,"default"],
|
||||
"model","pillar",3.5,52.5,1,"bottom",[0,0,0],["sbc",true,true,true],[4,3,7],["hex","#fee5a6","top"],[false,10,2,"default"],
|
||||
"model","pillar",61.5,3.5,1,"bottom",[0,0,0],["sbc",true,true,true],[4,3,7],["hex","#fee5a6","top"],[false,10,2,"default"],
|
||||
"model","pillar",61.5,52.5,1,"bottom",[0,0,0],["sbc",true,true,true],[4,3,7],["hex","#fee5a6","top"],[false,10,2,"default"]],
|
||||
|
||||
|
||||
|
||||
// Radxa
|
||||
["rock5b",
|
||||
// UL standoff adjustment
|
||||
"sub","rectangle",-1,66.5,12.99,"top",[0,0,0],["sbc",true,true,true],[10,2,8],[[.25,.25,.25,.25]],[false,10,2,"default"],
|
||||
// LR standoff adjustment
|
||||
"sub","rectangle",92,17.5,12.99,"top",[0,0,0],["sbc",true,true,true],[10,2,15],[[.25,.25,.25,.25]],[false,10,2,"default"],
|
||||
// LR standoff adjustment
|
||||
"sub","rectangle",93,17.5,12.99,"top",[0,0,0],["sbc",true,true,true],[2,10,15],[[.25,.25,.25,.25]],[false,10,2,"default"]],
|
||||
|
||||
|
||||
// Standard Motherboard Cases
|
||||
["adapter_mini-stx_m1s",
|
||||
"add2","standoff",5,100,0,"bottom",[0,0,0],["sbc",false,false,false],[0,0,0],[["custom",5.75,5,3.6,10,4,"countersunk","hex",false,false,4.5,5.1]],[true,10,2,"default"],
|
||||
@@ -432,5 +527,88 @@ accessory_data = [
|
||||
"add2","standoff",113,100,0,"bottom",[0,0,0],["sbc",false,false,false],[0,0,0],[["custom",5.75,5,3.6,10,4,"countersunk","hex",false,false,4.5,5.1]],[true,10,2,"default"],
|
||||
"add2","standoff",113,125,0,"bottom",[0,0,0],["sbc",false,false,false],[0,0,0],[["custom",5.75,5,3.6,10,4,"countersunk","hex",false,false,4.5,5.1]],[true,10,2,"default"],
|
||||
"model","hk_m1s_ups",2,97,5,"bottom",[0,0,0],["sbc",false,false,false],[0,0,0],[0],[true,110,2,"default"]],
|
||||
|
||||
// NAS Case
|
||||
["nas",
|
||||
"model","hd35",-1,-67,40,"bottom",[0,0,0],["case",true,true,false],[0,0,0],["portrait"],[true,20,2,"both"]],
|
||||
|
||||
// circuitsetup solar energy meter
|
||||
["cs_solarmeter",
|
||||
"sub","slot",-3,47,10.1,"top",[0,90,0],["sbc",true,true,true],[1.6,4.5,4],[[0]],[false,10,2,"default"]],
|
||||
|
||||
|
||||
// N2L environmental sensors
|
||||
// Adafruit models available at https://github.com/adafruit/Adafruit_CAD_Parts/tree/main
|
||||
["n2l_env_sensors",
|
||||
// divider walls
|
||||
"add1","rectangle",-1,57,0,"bottom",[0,0,0],["case",false,false,false],[71,2,10.25],[[.1,.1,.1,.1]],[false,10,2,"default"],
|
||||
"add2","rectangle",-1,57,10.2,"top",[0,0,0],["case",false,false,false],[71,2,33],[[.1,.1,.1,.1]],[false,10,2,"default"],
|
||||
"suball","round",35,61,9,"bottom",[90,0,0],["case",false,false,false],[4,0,6],[[.1,.1,.1,.1]],[false,10,2,"default"],
|
||||
// wall opening
|
||||
"suball","rectangle",69,70,4.5,"bottom",[0,0,0],["case",false,false,false],[6,45,34],[[.1,.1,.1,.1]],[false,10,2,"default"],
|
||||
// i2c radial hub holder
|
||||
// "model","stl_model",31,60.75,4,"bottom",[90,0,180],["sbc",false,false,false],[0,0,0],[1,"./adafruit/5625 Stemma 5 Port Hub.stl"],[false,10,2,"default"],
|
||||
"add2","pcb_holder",5,60.75,1,"bottom",[0,0,0],["case",false,false,false],[26.5,35,1.65],[2],[false,10,2,"default"],
|
||||
// BMP388 and holder
|
||||
// "model","stl_model",38,121,22,"bottom",[90,180,90],["sbc",false,false,false],[0,0,0],[1,"./adafruit/3966 BMP388 QT.stl",0,0],[false,10,2,"default"],
|
||||
"add2","pcb_holder",39.5,95,1,"bottom",[0,0,90],["case",false,false,false],[26.5,35,1.65],[2],[false,10,2,"default"],
|
||||
// SCD30 and holder
|
||||
// "model","stl_model",55,69,27,"bottom",[270,0,90],["sbc",false,false,false],[0,0,0],[1,"./adafruit/4867 Adafruit SCD30.stl"],[false,10,2,"default"],
|
||||
"add2","pcb_holder",55,68,1,"bottom",[0,0,90],["case",false,false,false],[53,35,1.65],[2],[false,10,2,"default"],
|
||||
// ST7789 IPS TFT Display and holder
|
||||
// "model","stl_model",67,61,4,"bottom",[90,270,270],["sbc",false,false,false],[0,0,0],[1,"./adafruit/4311 2in TFT IPS Display.stl"],[false,10,2,"default"],
|
||||
"add2","pcb_holder",65.4,121,1,"bottom",[0,0,270],["case",false,false,false],[61,35,1.65],[2],[false,10,2,"default"],
|
||||
// PMSA003I Partical Air Quality
|
||||
// "model","stl_model",0,70,4,"bottom",[0,0,0],["sbc",false,false,false],[0,0,0],[1,"./adafruit/4632 PMSA003I.stl"],[false,10,2,"default"],
|
||||
"add2","standoff",2.75,72.5,0,"bottom",[0,0,0],["case",false,false,false],[0,0,0],[["m2",5.75,4,3.6,7,3,"countersunk","hex",false,false,4.5,5.1]],[true,10,2,"default"],
|
||||
"add2","standoff",2.75,117.5,0,"bottom",[0,0,0],["case",false,false,false],[0,0,0],[["m2",5.75,4,3.6,7,3,"countersunk","hex",false,false,4.5,5.1]],[true,10,2,"default"],
|
||||
"add2","standoff",32.75,72.5,0,"bottom",[0,0,0],["case",false,false,false],[0,0,0],[["m2",5.75,4,3.6,7,3,"countersunk","hex",false,false,4.5,5.1]],[true,10,2,"default"],
|
||||
"add2","standoff",32.75,117.5,0,"bottom",[0,0,0],["case",false,false,false],[0,0,0],[["m2",5.75,4,3.6,8,3,"countersunk","hex",false,false,4.5,5.1]],[true,10,2,"default"],
|
||||
"sub","vent",-3,100,11,"top",[0,0,90],["case",false,false,false],[2,7,4],[1,5,"vertical",1],[false,10,2,"default"],
|
||||
// SGP30 VOC and eCO2 holder
|
||||
"add2","pcb_holder",39.5,61,1,"bottom",[0,0,90],["case",false,false,false],[26.5,35,1.65],[2],[false,10,2,"default"]],
|
||||
|
||||
|
||||
// avr128da48 environmental sensors
|
||||
// Adafruit models available at https://github.com/adafruit/Adafruit_CAD_Parts/tree/main
|
||||
["avr_env_sensors",
|
||||
// i2c radial hub holder
|
||||
// "model","stl_model",31,24,4,"bottom",[90,0,180],["sbc",true,true,false],[0,0,0],[1,"./adafruit/5625 Stemma 5 Port Hub.stl"],[false,10,2,"default"],
|
||||
"add2","pcb_holder",5,24,0,"bottom",[0,0,0],["sbc",true,true,false],[26.5,35,1.65],[2],[false,10,2,"default"],
|
||||
// SGP30 VOC and eCO2 holder
|
||||
"add2","pcb_holder",40.5,26,0,"bottom",[0,0,90],["sbc",true,true,false],[26.5,35,1.65],[2],[false,10,2,"default"],
|
||||
// BMP388 and holder
|
||||
// "model","stl_model",39,84,22,"bottom",[90,180,90],["sbc",true,true,false],[0,0,0],[1,"./adafruit/3966 BMP388 QT.stl",0,0],[false,10,2,"default"],
|
||||
"add2","pcb_holder",40.5,58,0,"bottom",[0,0,90],["sbc",true,true,false],[26.5,35,1.65],[2],[false,10,2,"default"],
|
||||
// SCD30 and holder
|
||||
// "model","stl_model",69,32,27,"bottom",[270,0,90],["sbc",true,true,false],[0,0,0],[1,"./adafruit/4867 Adafruit SCD30.stl"],[false,10,2,"default"],
|
||||
"add2","pcb_holder",69,31,0,"bottom",[0,0,90],["sbc",true,true,false],[53,35,1.65],[2],[false,10,2,"default"],
|
||||
// ST7789 IPS TFT Display and holder
|
||||
// "model","stl_model",82,23,2.5,"bottom",[90,270,270],["sbc",true,true,false],[0,0,0],[1,"./adafruit/4311 2in TFT IPS Display.stl"],[false,10,2,"default"],
|
||||
"add2","pcb_holder",80.5,83,0,"bottom",[0,0,270],["sbc",true,true,false],[61,35,1.65],[2],[false,10,2,"default"],
|
||||
"add2","pcb_holder",80.5,22,10.5,"top",[0,180,270],["sbc-case_z",true,true,true],[61,35,1.65],[2],[false,10,2,"default"],
|
||||
// display opening
|
||||
"suball","rectangle",82,32,3,"bottom",[0,0,0],["sbc",true,true,false],[6,44,34],[[.1,.1,.1,.1]],[false,10,2,"default"],
|
||||
// empty
|
||||
"add2","pcb_holder",52,58,0,"bottom",[0,0,90],["sbc",true,true,false],[26.5,35,1.65],[2],[false,10,2,"default"],
|
||||
"add2","pcb_holder",52,26,0,"bottom",[0,0,90],["sbc",true,true,false],[26.5,35,1.65],[2],[false,10,2,"default"],
|
||||
// PMSA003I Partical Air Quality
|
||||
// "model","stl_model",.25,32.5,4,"bottom",[0,0,0],["sbc",true,true,false],[0,0,0],[1,"./adafruit/4632 PMSA003I.stl"],[false,10,2,"default"],
|
||||
"add2","standoff",2.75,35,0,"bottom",[0,0,0],["sbc",true,true,false],[0,0,0],[["m2",5.75,4,3.6,7,3,"countersunk","hex",false,false,4.5,5.1]],[true,10,2,"default"],
|
||||
"add2","standoff",2.75,80.75,0,"bottom",[0,0,0],["sbc",true,true,false],[0,0,0],[["m2",5.75,4,3.6,7,3,"countersunk","hex",false,false,4.5,5.1]],[true,10,2,"default"],
|
||||
"add2","standoff",33.25,35,0,"bottom",[0,0,0],["sbc",true,true,false],[0,0,0],[["m2",5.75,4,3.6,7,3,"countersunk","hex",false,false,4.5,5.1]],[true,10,2,"default"],
|
||||
"add2","standoff",33.25,80.75,0,"bottom",[0,0,0],["sbc",true,true,false],[0,0,0],[["m2",5.75,4,3.6,8,3,"countersunk","hex",false,false,4.5,5.1]],[true,10,2,"default"],
|
||||
"sub","vent",-3,61.5,11,"top",[0,0,90],["sbc",true,true,false],[2,7,4],[1,5,"vertical",1],[false,10,2,"default"]],
|
||||
|
||||
|
||||
// adafruit solar charger
|
||||
["adafruit_solar_charger",
|
||||
// "add2","standoff",2.75,35,0,"bottom",[0,0,0],["sbc",true,true,false],[0,0,0],[["m2",5.75,4,3.6,7,3,"countersunk","hex",false,false,4.5,5.1]],[true,10,2,"default"],
|
||||
// "add2","standoff",2.75,80.75,0,"bottom",[0,0,0],["sbc",true,true,false],[0,0,0],[["m2",5.75,4,3.6,7,3,"countersunk","hex",false,false,4.5,5.1]],[true,10,2,"default"],
|
||||
// "add2","standoff",33.25,35,0,"bottom",[0,0,0],["sbc",true,true,false],[0,0,0],[["m2",5.75,4,3.6,7,3,"countersunk","hex",false,false,4.5,5.1]],[true,10,2,"default"],
|
||||
// "add2","standoff",33.25,80.75,0,"bottom",[0,0,0],["sbc",true,true,false],[0,0,0],[["m2",5.75,4,3.6,8,3,"countersunk","hex",false,false,4.5,5.1]],[true,10,2,"default"],
|
||||
"model","adafruit_4755_solar_charger",0,24,4,"bottom",[0,0,0],["sbc",false,false,false],[0,0,0],[0],[true,10,2,"default"],
|
||||
"model","adafruit_2030_powerboost",53,34,4,"bottom",[0,0,0],["sbc",false,false,false],[0,0,0],[0],[true,10,2,"default"]]
|
||||
|
||||
];
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ use <./SBC_Model_Framework/sbc_models_library.scad>
|
||||
include <./mod/add.scad>;
|
||||
include <./mod/case_adapter.scad>;
|
||||
include <./mod/case_bottom.scad>;
|
||||
include <./mod/case_rack.scad>;
|
||||
include <./mod/case_side.scad>;
|
||||
include <./mod/case_top.scad>;
|
||||
include <./mod/case_folded.scad>;
|
||||
@@ -44,10 +45,14 @@ include <./lib/dsub.scad>;
|
||||
include <./lib/fans.scad>;
|
||||
include <./lib/fastener.scad>;
|
||||
include <./lib/feet.scad>;
|
||||
include <./lib/grommet.scad>;
|
||||
include <./lib/hd.scad>;
|
||||
include <./lib/holder.scad>;
|
||||
include <./lib/keyhole.scad>;
|
||||
include <./lib/oem_adafruit.scad>;
|
||||
include <./lib/oem_hk.scad>;
|
||||
include <./lib/oem_rpi.scad>;
|
||||
include <./lib/panel_clamp.scad>;
|
||||
include <./lib/rack.scad>;
|
||||
include <./lib/standoff.scad>;
|
||||
include <./lib/vent.scad>;
|
||||
|
||||
114
sbccb_accessory_tool.scad
Normal file
114
sbccb_accessory_tool.scad
Normal file
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
SBC Case Builder Accessory Tool Copyright 2025 Edward A. Kisiel hominoid@cablemi.com
|
||||
This file is part of SBC Case Builder https://github.com/hominoids/SBC_Case_Builder
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
Code released under GPLv3: http://www.gnu.org/licenses/gpl.html
|
||||
|
||||
see https://github.com/hominoids/SBC_Case_Builder
|
||||
*/
|
||||
|
||||
include <./sbc_case_builder_library.scad>;
|
||||
|
||||
/* [View] */
|
||||
// viewing mode "model", "platter"
|
||||
view = "model"; // [model, platter]
|
||||
individual_part = "bottom"; // [top, bottom, right, left, front, rear, io_shield, accessories]
|
||||
// section individual parts for panel cases
|
||||
section_part = false; // [true,false]
|
||||
accessory = "grommet"; // ["1u rack stand", "2.5 drive holder", "fan cover", "grommet", "washer"]
|
||||
|
||||
/* [1U Rack Stand] */
|
||||
rack_width = 19; // [10, 19]
|
||||
rack_1u = 4; // [1 : 4]
|
||||
rack_fasteners = "nut"; // ["none", "nut", "insert"]
|
||||
|
||||
/* [2.5" Drive Holder] */
|
||||
holder_length = 110; // [110, 145]
|
||||
holder_width = 101.6; // [101.6 : .1 : 150]
|
||||
|
||||
/* [Fan Cover] */
|
||||
fan_style = "fan_hex"; // ["fan_open", "fan_1", "fan_2", "fan_hex"]
|
||||
fan_size = 40; // [25, 30, 40, 50, 60, 80, 92, 120]
|
||||
fan_cover_thickness = 2; // [2 : .25 : 5]
|
||||
|
||||
/* [Grommet] */
|
||||
grommet_style = "sleeve"; // ["sleeve"]
|
||||
grommet_od = 10; // [6 : .25 : 20]
|
||||
grommet_id = 6; // [2 : .25 : 20]
|
||||
installation_wall_thickness = 2; // [2 : .25 : 5]
|
||||
|
||||
/* [Washer] */
|
||||
washer_style = "flat"; // ["flat", "shouldered"]
|
||||
washer_od = 5; // [3 : .25 : 20]
|
||||
washer_id = 3; // [2 : .25 : 20]
|
||||
washer_thickness = 2; // [1 : .25 : 8]
|
||||
shoulder_height = 3; // [1 : .25 : 4]
|
||||
shoulder_countersunk = false; // [true,false]
|
||||
|
||||
/* [Hidden] */
|
||||
mask = [true, 10, 2, "default"];
|
||||
nmask = [false, 10, 2, "default"];
|
||||
rack_depth = 150;
|
||||
|
||||
adj = .01;
|
||||
$fn = 90;
|
||||
|
||||
// model view
|
||||
if (view == "model") {
|
||||
if(accessory == "1u rack stand") {
|
||||
rack_stand(rack_1u);
|
||||
}
|
||||
if(accessory == "2.5 drive holder") {
|
||||
hd35_25holder(holder_length, holder_width);
|
||||
}
|
||||
if(accessory == "fan cover") {
|
||||
fan_cover(fan_size, fan_cover_thickness, fan_style);
|
||||
}
|
||||
if(accessory == "grommet") {
|
||||
grommet("front", grommet_style, grommet_od, grommet_id, installation_wall_thickness, true, nmask);
|
||||
}
|
||||
if(accessory == "washer") {
|
||||
washer(washer_style, washer_id, washer_od, washer_thickness, shoulder_height, shoulder_countersunk, "silver");;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// platter view
|
||||
if (view == "platter") {
|
||||
if(accessory == "1u rack stand") {
|
||||
rotate([0,270,0]) rack_stand(rack_1u);
|
||||
}
|
||||
if(accessory == "2.5 drive holder") {
|
||||
hd35_25holder(holder_length, holder_width);
|
||||
}
|
||||
if(accessory == "fan cover") {
|
||||
fan_cover(fan_size, fan_cover_thickness, fan_style);
|
||||
}
|
||||
if(accessory == "grommet" && grommet_style == "sleeve") {
|
||||
translate([0,0,0]) rotate([270,0,0]) difference() {
|
||||
grommet("bottom", grommet_style, grommet_od, grommet_id, installation_wall_thickness, false, nmask);
|
||||
translate([-grommet_od,-.125,-3]) cube([20,10,20]);
|
||||
}
|
||||
translate([0,20,0]) rotate([270,0,0]) difference() {
|
||||
grommet("bottom", grommet_style, grommet_od, grommet_id, installation_wall_thickness, false, nmask);
|
||||
translate([-grommet_od,-.125,-3]) cube([20,10,20]);
|
||||
}
|
||||
translate([0,-20,0])
|
||||
grommet_clip(grommet_style, grommet_od, grommet_id, installation_wall_thickness);
|
||||
}
|
||||
if(accessory == "washer") {
|
||||
washer(washer_style, washer_id, washer_od, washer_thickness,
|
||||
shoulder_height, shoulder_countersunk, "silver");
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -1,20 +0,0 @@
|
||||
|
||||
/* find correct tolerance and use for respective entry's data_1 value within sbc_case_builder.cfg */
|
||||
|
||||
use <./sbc_case_builder_library.scad>;
|
||||
|
||||
battery_tolerance = 0;
|
||||
speaker_tolerance = 0;
|
||||
volume_tolerance = 0;
|
||||
|
||||
$fn = 90;
|
||||
|
||||
translate([-33,0,0]) batt_holder(battery_tolerance);
|
||||
difference() {
|
||||
translate([-17,-17,0]) cube([34,34,2]);
|
||||
translate([0,0,-1]) cylinder(d=24, h=4);
|
||||
}
|
||||
translate([0,0,1.99]) boom_speaker_holder("friction",speaker_tolerance);
|
||||
|
||||
translate([30,0,0]) boom_vring(volume_tolerance);
|
||||
|
||||
Reference in New Issue
Block a user