Compare commits
159 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
2166df5e3d
|
|||
|
12bf410aee
|
|||
|
7c8e504c46
|
|||
|
78d30db0c9
|
|||
|
522d960a37
|
|||
|
13e75fe71f
|
|||
|
0612a11e1e
|
|||
|
0d9657cf7c
|
|||
|
95cb69d268
|
|||
|
e87f579413
|
|||
|
0fd3880fa2
|
|||
|
d028736d5a
|
|||
|
80ce81c465
|
|||
|
8b5d994847
|
|||
|
852cef821c
|
|||
|
bf2f8a8a17
|
|||
|
1aea9221ff
|
|||
|
ea4beca89d
|
|||
|
aa92e57fe0
|
|||
|
0d121e834a
|
|||
|
d187312cd3
|
|||
|
4c045951c7
|
|||
|
bcf2adcaa2
|
|||
|
5e25a27d58
|
|||
|
462b4d45e0
|
|||
|
b0e5082064
|
|||
|
6df2d7a84f
|
|||
|
ef32076d98
|
|||
|
d9d1183488
|
|||
|
fe8826d86f
|
|||
|
8b96f60f37
|
|||
|
5675921875
|
|||
|
d70ccf6491
|
|||
|
432e6e74d5
|
|||
|
1e64f59134
|
|||
|
a4f2650f00
|
|||
|
c9a74ebb18
|
|||
|
0d8f74bef8
|
|||
|
29fb93ee51
|
|||
|
4564f29ef1
|
|||
|
29b7f4a828
|
|||
|
15acfdcef4
|
|||
|
b457441e9f
|
|||
|
5cdac31eeb
|
|||
|
a0fe108471
|
|||
|
4405c299b0
|
|||
|
3c1dadc917
|
|||
|
665674367c
|
|||
|
579d943268
|
|||
|
b5805b1e66
|
|||
|
c19542bb66
|
|||
|
84fb2876ad
|
|||
|
3ca41bdb47
|
|||
|
03737e2385
|
|||
|
ef68dbca48
|
|||
|
4336098fe8
|
|||
|
a67c3a3d7f
|
|||
|
950346f85a
|
|||
|
c99a18d30f
|
|||
|
3153564ad4
|
|||
|
0129cf6ce6
|
|||
|
c79427052e
|
|||
|
623118b627
|
|||
|
aff6efebb3
|
|||
|
f3d0d4b6e2
|
|||
|
97a6f52e07
|
|||
|
ecc3ffbb54
|
|||
|
73b55861b6
|
|||
|
439333c154
|
|||
|
ef16559b95
|
|||
|
2880018913
|
|||
|
ca928932ba
|
|||
|
8b4cc0b182
|
|||
|
a6b5d77671
|
|||
|
fa05469e19
|
|||
|
9375a3a1b7
|
|||
|
1557021be4
|
|||
|
9d109f1756
|
|||
|
0ea02154b5
|
|||
|
e29d9e6180
|
|||
|
f509b8df80
|
|||
|
71b2c786be
|
|||
|
5c542944d2
|
|||
|
623e025566
|
|||
|
d1a8f34c2a
|
|||
|
900ca8c751
|
|||
|
d87794db59
|
|||
|
f0d3f434a3
|
|||
|
2f027ef1fe
|
|||
|
b826ecaccf
|
|||
|
0cdd0ae846
|
|||
|
504dab935c
|
|||
|
0de2505de2
|
|||
|
fd2193cc5a
|
|||
|
766fbf2883
|
|||
|
7a03a1e38e
|
|||
|
1083492ef8
|
|||
|
765ef689c5
|
|||
|
055b103abd
|
|||
|
6ad801b8b2
|
|||
|
875513a3d3
|
|||
|
7e67c15c13
|
|||
|
e426e15884
|
|||
|
ba3e77d0cd
|
|||
|
c0ae73b139
|
|||
|
b871963cf7
|
|||
|
2c62c9119b
|
|||
|
b7910cdb44
|
|||
|
0ac3e8433f
|
|||
|
2bbf69d9a0
|
|||
|
f4c9c91d91
|
|||
|
bbe1ab25d7
|
|||
|
cb82933e50
|
|||
|
a1fc85c069
|
|||
|
850bbdf5b9
|
|||
|
7e42129594
|
|||
|
66719f84c6
|
|||
|
184664cceb
|
|||
|
903b9b40ff
|
|||
|
9fd3658518
|
|||
|
bd7b908712
|
|||
|
61a67109ce
|
|||
|
ff85423cee
|
|||
|
ca655012c5
|
|||
|
3059e01b8f
|
|||
|
2911b23db4
|
|||
|
00a1bbc065
|
|||
|
6726233beb
|
|||
|
bc68f8b0dc
|
|||
|
de3914fa85
|
|||
|
92d3f9e6d5
|
|||
|
8168797be3
|
|||
|
244ace1b4a
|
|||
|
db887b668f
|
|||
|
dccd2836b2
|
|||
|
2ed9b12ed3
|
|||
|
de0fcfd160
|
|||
|
4e65445e16
|
|||
|
d578890d96
|
|||
|
db41aa1183
|
|||
|
0d954c2630
|
|||
|
60b52eb10d
|
|||
|
63c7ade41d
|
|||
|
eaaa92004f
|
|||
|
cf218ecc1d
|
|||
|
8fd77375b7
|
|||
|
a9911820c9
|
|||
|
b9ba201c99
|
|||
|
3bd36cfbdf
|
|||
|
89e25bd001
|
|||
|
a6803450f8
|
|||
|
e41f3f4c6c
|
|||
|
3ec6132547
|
|||
|
b43b79ce19
|
|||
|
f93f20997a
|
|||
|
70b45fa18b
|
|||
|
e50629d372
|
|||
|
01d4d95f24
|
|||
|
4cefdfa26b
|
@@ -1,3 +1,4 @@
|
||||
build/
|
||||
*.stl
|
||||
|
||||
*.sw*
|
||||
|
||||
+225
@@ -0,0 +1,225 @@
|
||||
# CHANGELOG
|
||||
|
||||
Included is a summary of changes to the project, by version. Details can be found in the commit history.
|
||||
|
||||
## v4.7.1
|
||||
|
||||
### Fixes
|
||||
|
||||
* Hull-based decorative plates were accidentally grown in v4.7.0 due to ye olde refactoring. They are back to the
|
||||
dimensions they should be (give or take) because there was an underlying bug in how they were geometried pre-v4.7.1.
|
||||
* The docs/ directory in the build now includes the images referred to, especially in the README.
|
||||
|
||||
### Miscellaneous
|
||||
|
||||
* Some README tweaks, including another demonstrative photo.
|
||||
* The build creates both a ZIP of everything, including docs, for humans to download, and also a ZIP of *just* the STLs,
|
||||
to ease uploading to Printables.
|
||||
|
||||
## v4.7.0
|
||||
|
||||
### Features
|
||||
|
||||
* Inner wall pieces where the horizontal stripes jut through the horizontal stripe windows have been added, these look
|
||||
decent and avoid the outer wall feeling extremely flimsy. This piece uses a "longish" front/back piece which isn't
|
||||
retained as a separate piece, because the latter is not meant to be printed itself.
|
||||
* I somehow went this whole time without creating a simple Sega 2P layout panel and decorative plate; those have been
|
||||
added.
|
||||
* Prototype (still literally a bit rough) braces for the corners and middle have been added. These pieces cover up the
|
||||
seams of the frame, and add some visual depth and distinction, but are not for everyone. YMMV.
|
||||
* A new "superplate" of the "directional arc + W" plus "sega 2P nine" layouts combined has been added, this is a piece I
|
||||
ended up not using in a build, but it functions as well as any of the plates, so why not.
|
||||
|
||||
### Improvements
|
||||
|
||||
* Visible round edges have been made more round.
|
||||
* The single-24mm-button decorative disc has been shrunk a bit, since (IMO) it stood out a bit too much relative to the
|
||||
button.
|
||||
* The "longish" extended side has been made a bit simpler to construct.
|
||||
* The side piece construction has been reworked, making it a bit simpler to construct and reducing the build complexity,
|
||||
though preview mode still complains about 2-manifold errors.
|
||||
* The assembly documentation has been cleaned up, with more pieces explained a bit better as well.
|
||||
* Dustwashers got some small updates to shrink the size of the disc to the normal JLF dustwasher size, and to fit the
|
||||
shaft a bit tighter without obstructing the lever's ability to... be a lever.
|
||||
|
||||
### Miscellaneous
|
||||
|
||||
* The build has been improved to error when there are issues in the .scad files, to keep me from making bad packages.
|
||||
* The back pieces are aligned properly in the all together demo.
|
||||
* Updates to the docs on my preferred printing settings.
|
||||
* README updates following the previous releases' reorganizations.
|
||||
* Objects README update to add attribution to TheTrain.
|
||||
|
||||
## v4.6.0
|
||||
|
||||
### Features
|
||||
|
||||
* All frame pieces were updated to have flush edges, a la the "extended" sides, rather than the seam between the
|
||||
front/back and the sides being at a 45 degree angle on some pieces, with the latter meaning that we were maintaining
|
||||
two (complicated) duplicates of the same pieces because both 45 degree and 90 degree angles were necessary. This does
|
||||
not affect the look of the build much, but simplifies the print and the maintenance of the project.
|
||||
* A slightly-extended flat side piece was added, to add just a bit of length to the overall build.
|
||||
|
||||
### Improvements
|
||||
|
||||
* One more slash has been added to the frame pieces, just for more interesting visuals.
|
||||
* The rectangle plates' positioning was tweaked slightly.
|
||||
|
||||
### Fixes
|
||||
|
||||
* The frame solid was very slightly shorter than it should have been as the corners relied on cylinders. The core solid
|
||||
is now at its proper dimensions.
|
||||
|
||||
## v4.5.0
|
||||
|
||||
### Features
|
||||
|
||||
* Many components for the Buildable Stick System - Arcade Edition --- pieces to create a control enclosure for the Qanba
|
||||
2009 base! These pieces live in `extras/bss-ae/` but do use some parts from the base project; check that subdir's
|
||||
README.
|
||||
* Created a Sega 2P 11 button layout, basically following the curve of the fourth column and adding a fifth, plus one
|
||||
extra button
|
||||
* More decorative plates, this time square ones for an NES-styled project.
|
||||
|
||||
### Improvements
|
||||
|
||||
* Button layout positions for Sega 2P and directional arc layouts have been parameterized.
|
||||
* The decorative plates for the directional arc + W and Sega 2P 9 layout have been split into two files, since there was
|
||||
no reason to keep them as one with multiple pieces anymore.
|
||||
* Tweaks to the horizontal stripes in order to get them to print better.
|
||||
* Renamed "Sega 2P plus one" to Sega 2P 9, following the pattern of the 11 layout.
|
||||
|
||||
### Miscellaneous
|
||||
|
||||
* Renaming of extended side pieces to fit the front/back idiom.
|
||||
* Cleanups to the demos.
|
||||
|
||||
## v4.4.3
|
||||
|
||||
### Features
|
||||
|
||||
* Windowed frame wall pieces were made for the "clean" front/back walls that line up with the extended sides.
|
||||
|
||||
### Improvements
|
||||
|
||||
* The inner wall piece has been thickened, bringing its surface closer to the end of the outer wall windowed frame
|
||||
pieces, making the window less deep and the inner wall easier to see.
|
||||
* The inner wall piece has been shrunken on the Z in order to leave some material on the outer wall and thus improve the
|
||||
friction fit and clamp of the outer wall piece, which was too weakened by the unsupported top and bottom otherwise.
|
||||
|
||||
### Miscellaneous
|
||||
|
||||
* Documentation updates, especially around the printing of parts.
|
||||
* Corrected the names of some pieces that were accidentally duplicated from the file they were copied from rather than
|
||||
what they were, or otherwise didn't match the standard pattern (such as it is).
|
||||
|
||||
## v4.4.2
|
||||
|
||||
### Bugfixes
|
||||
|
||||
* Fix a regression with the small button screw-in space cutting into the frame wall supports. The screw-in space is
|
||||
potentially more important for some nuts than the thickness of the frame wall supports, so the latter have been
|
||||
thinned slightly.
|
||||
|
||||
## v4.4.1
|
||||
|
||||
### Features
|
||||
|
||||
* A new lever + Sega 2P 6 button panel has been added. The overhang version hadn't been updated in forever, but the
|
||||
inset panel moved stuff around in a way that allowed a couple aux buttons to fit in, so those have been added to the
|
||||
overhang panel as well.
|
||||
* A horizontal stripe frame windowed piece has been added. YMMV may vary a bit on this vs. an empty window --- you can
|
||||
see less of the inner object with the stripes, but it's a bit more stable.
|
||||
|
||||
### Improvements
|
||||
|
||||
* The frame wall slashes have been made a bit more reusable.
|
||||
* The area around button holes for screw-ins has been tweaked to be a bit smaller for 30mm buttons and a bit larger for
|
||||
24mm buttons.
|
||||
|
||||
### Miscellaneous
|
||||
|
||||
* A bottom overhang panel was positioned incorrectly in the demo file; this has been fixed.
|
||||
* Added a demo of the one-panel overhang lever + 6 button stick.
|
||||
|
||||
## v4.4.0
|
||||
|
||||
### Features
|
||||
|
||||
* New "windowed" frame box walls have been added, which allow for seeing through the outer wall to something else, such
|
||||
as an inner wall of a different color, or for people who like showing off their wiring, nothing.
|
||||
* An attempt at a two-panel "shiokenstar" layout has been added.
|
||||
* The "plates" decorative plate for my favorite layout was altered since I wasn't using it anyway.
|
||||
|
||||
### Improvements
|
||||
|
||||
* The frame routing hole, in either the whole frames or the interconnect, is a semicircle on one side, making it easier
|
||||
to wire (and rewire) a completed arcade stick, and it also makes button layouts that span the connection point more
|
||||
possible.
|
||||
* Less of the inner wall is cut out for e.g. Neutrik and aux buttons now, removing the possibility for inset panels to
|
||||
allow for a tiny bit of light to seep the cracks and giving panels a bit more support.
|
||||
* The piece-based frame walls now meet at 45 degree angles at the corners, which makes for fewer print anomalies to
|
||||
catch your hand or clothing on. These 45 degree angles are not used for the TE1-style extended panels, which still
|
||||
meet at 90 degree angles.
|
||||
* All of the core arcade stick parts, and extras, have been reorganized and renamed into subdirectories that make their
|
||||
purpose more obvious. This also makes it clearer what you're looking at when looking at the project file structure.
|
||||
Documentation was updated throughout for this change.
|
||||
|
||||
### Miscellaneous
|
||||
|
||||
* A stand for showing off inset-based sticks has been added to extras. This may get more love in a future release.
|
||||
* The blown up demo now uses frame pieces, as these are quickly becoming the standard build.
|
||||
* Cleanups to CONTRIBUTING.md
|
||||
* Demos have been given their own place in the repository.
|
||||
* The Makefile has been altered to use a Python script to build the files, due to the complexity of reorganizing the
|
||||
project into subdirectories.
|
||||
* An abandoned floating stand has been moved into the attic --- it barely works right.
|
||||
|
||||
## v4.3.x
|
||||
|
||||
This finally removed the posts added to the panels introduced in v4.0.
|
||||
|
||||
## v4.2.x
|
||||
|
||||
This added TE1-like bevels to the repository, which look pretty neat.
|
||||
|
||||
## v4.1.0
|
||||
|
||||
Having improved the internals in v4.0.0, this broke out the frame into modular pieces, making them easier and more
|
||||
reliable to print, with only a trivial effect on the overall stability of the stick. This also made the bottom panels
|
||||
identical to the top, easing reuse.
|
||||
|
||||
## v4.0.x
|
||||
|
||||
This was an experiment that didn't survive scrutiny to add more posts to the frames and panels, in order to improve the
|
||||
friction fit, but it really just make the whole thing more obnoxious to work with. However, this redesign also came with
|
||||
some key improvements to the construction of the stick, which has made the subsequent releases easier to work with.
|
||||
|
||||
## v3.3.x
|
||||
|
||||
Largely a cleanup, this improved the component reuse and added more complete licensing information to the project.
|
||||
|
||||
## v3.2.x
|
||||
|
||||
This improved the frame height to accommodate more levers in inset panels, along with some cleanup.
|
||||
|
||||
## v3.1.x
|
||||
|
||||
This added panels for more layouts with more buttons, establishing my go-to of a lever, a directional arc with an extra
|
||||
button in a W-as-in-WASD position, and a Sega 2P-inspired 9-button action button layout.
|
||||
|
||||
## v3.0.x
|
||||
|
||||
I think the project really took shape at this point, as it resized the panels and frames to accommodate a two-panel
|
||||
layout for nice, long sticks.
|
||||
|
||||
## v2.0.x
|
||||
|
||||
This added the overhang plates to the mix, while still sticking to the three-panel design. It also started adding
|
||||
dustwashers and decorative plates, which improved the aesthetics of the project.
|
||||
|
||||
## v1.0.x
|
||||
|
||||
This was a simple three-panel stick that was somewhat ridiculously long, but worked, and built a lot of the foundation
|
||||
for the project. Its start as being inspired by the Open Stick really showed at this point, but things were coming
|
||||
together.
|
||||
+41
-5
@@ -9,11 +9,47 @@ I do not request the copyright of contributions be assigned to me or to the proj
|
||||
be allowed to relicense your contributions. My personal oath is to maintain inbound=outbound in my open source projects,
|
||||
and the expectation is authors are responsible for their contributions.
|
||||
|
||||
I am following the the [Developer Certificate of Origin (DCO)](https://developercertificate.org/), also available at
|
||||
`DCO.txt`. The DCO is a way for contributors to certify that they wrote or otherwise have the right to license their
|
||||
code contributions to the project. Contributors must sign-off that they adhere to these requirements by adding a
|
||||
`Signed-off-by` line to their commit message, and/or, for frequent contributors, by signing off on their entry in
|
||||
`MAINTAINERS.md`.
|
||||
I am following the [Developer Certificate of Origin (DCO)](https://developercertificate.org/), reproduced below. The DCO
|
||||
is a way for contributors to certify that they wrote or otherwise have the right to license their code contributions to
|
||||
the project. Contributors must sign-off that they adhere to these requirements by adding a `Signed-off-by` line to their
|
||||
commit message, and/or, for frequent contributors, by signing off on their entry in `MAINTAINERS.md`.
|
||||
|
||||
```
|
||||
Developer Certificate of Origin
|
||||
Version 1.1
|
||||
|
||||
Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim copies of this
|
||||
license document, but changing it is not allowed.
|
||||
|
||||
|
||||
Developer's Certificate of Origin 1.1
|
||||
|
||||
By making a contribution to this project, I certify that:
|
||||
|
||||
(a) The contribution was created in whole or in part by me and I
|
||||
have the right to submit it under the open source license
|
||||
indicated in the file; or
|
||||
|
||||
(b) The contribution is based upon previous work that, to the best
|
||||
of my knowledge, is covered under an appropriate open source
|
||||
license and I have the right under that license to submit that
|
||||
work with modifications, whether created in whole or in part
|
||||
by me, under the same open source license (unless I am
|
||||
permitted to submit under a different license), as indicated
|
||||
in the file; or
|
||||
|
||||
(c) The contribution was provided directly to me by some other
|
||||
person who certified (a), (b) or (c) and I have not modified
|
||||
it.
|
||||
|
||||
(d) I understand and agree that this project and the contribution
|
||||
are public and that a record of the contribution (including all
|
||||
personal information I submit with it, including my sign-off) is
|
||||
maintained indefinitely and may be redistributed consistent with
|
||||
this project or the open source license(s) involved.
|
||||
```
|
||||
|
||||
This process is followed by a number of open source projects, most notably the Linux kernel. Here's the gist of it:
|
||||
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
Developer Certificate of Origin
|
||||
Version 1.1
|
||||
|
||||
Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim copies of this
|
||||
license document, but changing it is not allowed.
|
||||
|
||||
|
||||
Developer's Certificate of Origin 1.1
|
||||
|
||||
By making a contribution to this project, I certify that:
|
||||
|
||||
(a) The contribution was created in whole or in part by me and I
|
||||
have the right to submit it under the open source license
|
||||
indicated in the file; or
|
||||
|
||||
(b) The contribution is based upon previous work that, to the best
|
||||
of my knowledge, is covered under an appropriate open source
|
||||
license and I have the right under that license to submit that
|
||||
work with modifications, whether created in whole or in part
|
||||
by me, under the same open source license (unless I am
|
||||
permitted to submit under a different license), as indicated
|
||||
in the file; or
|
||||
|
||||
(c) The contribution was provided directly to me by some other
|
||||
person who certified (a), (b) or (c) and I have not modified
|
||||
it.
|
||||
|
||||
(d) I understand and agree that this project and the contribution
|
||||
are public and that a record of the contribution (including all
|
||||
personal information I submit with it, including my sign-off) is
|
||||
maintained indefinitely and may be redistributed consistent with
|
||||
this project or the open source license(s) involved.
|
||||
@@ -1,19 +1,13 @@
|
||||
EXCLUDES = blown-up-demo components parameters
|
||||
OBJECTS := $(filter-out $(EXCLUDES),$(patsubst src/%.scad,%,$(wildcard src/*.scad)))
|
||||
dir_guard=@mkdir -p ./build
|
||||
|
||||
all: $(OBJECTS)
|
||||
$(dir_guard)
|
||||
all:
|
||||
python build.py
|
||||
mkdir -p ./build/docs
|
||||
cp ./docs/README-objects.md ./build/README.md
|
||||
cp ./docs/assembly-and-tips.md ./build/docs/assembly-and-tips.md
|
||||
cp ./docs/printing-and-materials.md ./build/docs/printing-and-materials.md
|
||||
cp ./README.md ./build/README.md
|
||||
cp ./docs/README-objects.md ./build/README-objects.md
|
||||
cp ./docs/* ./build/docs/
|
||||
cp ./LICENSE ./build/LICENSE
|
||||
pushd ./build; zip ./buildable-stick-system-`git describe --dirty`-stls.zip . -r; popd
|
||||
|
||||
$(OBJECTS):
|
||||
$(dir_guard)
|
||||
openscad -o build/$@.stl src/$@.scad
|
||||
cp ./CHANGELOG.md ./build/CHANGELOG.md
|
||||
pushd ./build; zip ./buildable-stick-system-`git describe --dirty --always`-stls-and-docs.zip . -r; popd
|
||||
pushd ./build; zip ./buildable-stick-system-`git describe --dirty --always`-stls.zip models -r; popd
|
||||
|
||||
clean:
|
||||
rm -rf ./build
|
||||
|
||||
@@ -1,19 +1,22 @@
|
||||
# The Buildable Stick System
|
||||
|
||||
Files for 3D printing an arcade stick.
|
||||
Files for 3D printing and building an arcade stick enclosure.
|
||||
|
||||
Have you ever wanted to conjure your own arcade stick out of the ether (well, plastic), or to prototype a new layout or
|
||||
design before sending it to a custom builder? Do you just love having your space filled with arcade stick enclosures,
|
||||
because you keep making different variants, colorways, and so on? Or do you simply want a good stick on the cheap, and
|
||||
know someone or a library with a 3D printer? The Buildable Stick System may be the project for you!
|
||||
|
||||
**Join the project IRC channel: [#buildable-stick-system @
|
||||
Randomus](https://webirc.randomus.net/#buildable-stick-system)!**
|
||||
|
||||

|
||||
|
||||
[OpenSCAD-based illustration of how the components for an overhang panel-based stick fit together.]
|
||||
|
||||

|
||||

|
||||
|
||||
[Photo of a completed inset panel-based stick.]
|
||||
[Photo of a completed overhang panel-based stick.]
|
||||
|
||||
Originally an attempt to make a couple customized STL files for the [OpenStickCommunity Fightstick
|
||||
Case](https://github.com/OpenStickCommunity/Hardware/tree/main/Fightstick%20Case), the changes ballooned to fit my
|
||||
@@ -30,24 +33,52 @@ starting with an existing object and constructing what you'd like with new or ex
|
||||
## Usage of Parts
|
||||
|
||||
There are a lot of parts to pick from, but there are some structural variants to pay attention to; here's some help
|
||||
about when/how to use specific parts:
|
||||
about what the types of parts are and how to use them:
|
||||
|
||||
* `panel-inset` --- these fit flush into a frame, creating a closed box enclosure.
|
||||
* `panel-overhang` --- these have a tray that fits into a frame with the actual face extending beyond the frame,
|
||||
creating an ice cream sandwich enclosure.
|
||||
* These also yield a bit more space inside the box, for tall levers or whatever.
|
||||
* `frame` (non-pieces) --- these create the box of the enclosure, as one part. These can be hard to print well ---
|
||||
shrinkage forces tend to curl up the corners no matter what you do, and some points need supports --- but if you don't
|
||||
care about that because you're printing an ice cream sandwich, they are simpler than...
|
||||
* `frame-piece` --- these break up the frame box into four faces, and are held together by friction fit and the hex
|
||||
bolts. This is more stable than you might expect, but it does introduce some variability in the overall sturdiness of
|
||||
the enclosure compared with the frame as one box piece.
|
||||
* The `interconnect` replaces the need to bolt multiple frames together.
|
||||
* `frames/`
|
||||
* `complete/` --- these are the four walls of the frame as one piece, in a couple variations for combining into
|
||||
larger arcade sticks. They are simple to assemble, but you have fewer modularity/customization options, and they
|
||||
are harder to print because the physics of the material cooling will probably pull the corners up. They also need
|
||||
supports, since the top and bottom of the frame both have trays for panels to go into. Use at your own risk.
|
||||
* `pieces/` these are the same four walls (generally speaking) as in the complete frames above, broken out into
|
||||
modular pieces to print separately. Because they are separate pieces, you can mix and match colors, and you can
|
||||
lay them all face down on the print surface for better adhesion and surface patterns. There are also variants
|
||||
here, the "windowed" pieces, for doing two-tone variants and that kind of thing. There are also frame walls pulled
|
||||
out to create MCZ TE-style extended sides. There is an interconnect that stands in for the joined inner wall
|
||||
between boxes of the overall unit. You need this if you are combining multiple sets of walls, e.g. for a
|
||||
two-panel-long stick.
|
||||
* `panels/`
|
||||
* `inset/` --- various panels, all of the same size, that fit into and flush with the frame, making the arcade stick
|
||||
top or bottom. Aside from using up a bit of the space for components inside the frame, come with no downsides ---
|
||||
they print easily and are a pretty simple shape to tweak and remix.
|
||||
* `overhang/` --- overhang panels have their plane extending over the edge of the frame, creating a bit of a
|
||||
sandwich look. This is mostly an aesthetic choice, but they sit higher in the frame as well, the main panel being
|
||||
over/under the frame rather than within it. This extra space is useful for taller levers. The only downside to
|
||||
these is that they aren't as reusable as the inset panels, since the inset panels can go anywhere, but the
|
||||
overhang panels must be designed to not overlap with other overhang panels, so you might have to make more custom
|
||||
variants depending on where you put things.
|
||||
* `plates/`
|
||||
* Flat pieces used for cosmetic or connective reasons --- decorative plates for top buttons and similar to give
|
||||
more color variance and some layers to the arcade stick, some very simple dustwashers, plates that fit rocker
|
||||
switches and the like in Neutrik D or 20mm holes, and a lever mount spacer for getting your lever shaft at the
|
||||
desired height. You don't *need* any of these, but you'll probably use a few.
|
||||
* `misc/`
|
||||
* Pieces that I haven't organized better (yet) --- odd things and scratch ideas, mostly. There are some decorative
|
||||
corners for a bit more height/nicer seams, a sleeve to make smaller hex spacers fit in the hole as they're
|
||||
supposed to, things of that nature.
|
||||
* `extras/`
|
||||
* Various experiments and things not directly related to making an arcade stick. At time of writing, there's a
|
||||
couple pieces for a little stand for the stick, solely for vanity purposes.
|
||||
* `bss-ae/` --- these are pieces for an arcade control panel that fits on the Qanba 2009. See the docs in that
|
||||
directory for details.
|
||||
|
||||
Feel free to request or contribute to more objects. Additional documentation regarding assembling the stick is available
|
||||
in `docs/assembly-and-tips.md`.
|
||||
|
||||
## Printing
|
||||
|
||||
These items all fit on a 256mm^2 print bed; I use a Bambu Lab P1P based on what I've learned from the
|
||||
OpenStickCommunity. Standard settings seem sufficiently sturdy, but see `docs/materials-and-printing.md` for more
|
||||
OpenStickCommunity. Standard settings seem sufficiently sturdy, but see `docs/printing-and-materials.md` for more
|
||||
thoughts and settings based on my tinkering with prints.
|
||||
|
||||
## Assembling
|
||||
@@ -57,14 +88,14 @@ What you'll need beyond these objects:
|
||||
* An arcade stick board (I recommend [TheTrain's RP2040 Advanced Breakout
|
||||
Board](https://github.com/OpenStickCommunity/Hardware/tree/main/RP2040%20Advanced%20Breakout%20Board))
|
||||
* 4 M3 8mm hex bolts to secure the PCB to a panel
|
||||
* Per frame and plate combo:
|
||||
* Per frame and panel combo:
|
||||
* 4 45mm M4 hex brass standoffs (or equivalent)
|
||||
* 8 M4 countersunk hex bolts
|
||||
* Overhang plates should use 12-16mm length bolts since they are taller
|
||||
* Inset plates should probably use 8-12mm bolts --- some standoffs aren't threaded the whole way, making 16mm
|
||||
* Overhang panels should use 12-16mm length bolts since they are taller
|
||||
* Inset panels should probably use 8-12mm bolts --- some standoffs aren't threaded the whole way, making 16mm
|
||||
too long to go flush
|
||||
* If making the 45mm standoffs from multiple smaller ones, make sure they have enough length to take your bolts!
|
||||
* Per frame connection point:
|
||||
* Per frame connection point (only necessary if you are using complete frames and not frame pieces):
|
||||
* 8 16mm M4 bolts
|
||||
* 8 M4 flange nuts
|
||||
* For a lever:
|
||||
@@ -99,8 +130,8 @@ Filament masses from Bambu Studio estimates, using Bambu PLA Basic, 20% gyroid i
|
||||
stick anyway
|
||||
* You can also use a shorter length with longer bolts, or combine multiple standoffs, if either of those yield better
|
||||
prices
|
||||
* 8 16mm M4 bolts to connect top plates to frames: **$0.72 USD** (you can get a pack of 100 on Amazon for $9, as of
|
||||
* 8 12mm M4 bolts to connect bottom plates to frames: **$0.72 USD** (you can get a pack of 100 on Amazon for $9, as of
|
||||
* 8 16mm M4 bolts to connect top panels to frames: **$0.72 USD** (you can get a pack of 100 on Amazon for $9, as of
|
||||
* 8 12mm M4 bolts to connect bottom panels to frames: **$0.72 USD** (you can get a pack of 100 on Amazon for $9, as of
|
||||
2023-09-12)
|
||||
|
||||
With an enclosure coming in around $31, depending on your choices --- say, ~$30 for TheTrain's RP2040 Advanced Breakout
|
||||
@@ -108,6 +139,16 @@ Board, ~$60 for Sanwa buttons and a lever, and ~$20 for miscellaneous connectors
|
||||
full-featured controller with an open source foundation together for around $140. Reducing wall and infill settings
|
||||
will probably save you around $5 of material, and you can probably decide what you want to do from there.
|
||||
|
||||
## FAQ
|
||||
|
||||
### I get a bunch of warnings on not being able to include files when I open them in OpenSCAD, what do I do?
|
||||
|
||||
OpenSCAD pathing is relative to the current working directory by default, which is probably not the `src/` directory.
|
||||
When you start OpenSCAD, you must either start it from inside the project's `src/` directory, or point it at the path to
|
||||
the source files via e.g. `OPENSCADPATH=path/to/buildable-stick-system/src/ openscad`.
|
||||
|
||||
See <https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Include_Statement>.
|
||||
|
||||
## Miscellany
|
||||
|
||||
See the `/docs/` directory for more thoughts too scattered for this document.
|
||||
@@ -138,12 +179,13 @@ to hang out and discuss issues and features and whatnot.
|
||||
|
||||
Written by and copyright Brian S. Stephan (<bss@incorporeal.org>).
|
||||
|
||||
The Buildable Stick System 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.
|
||||
The Buildable Stick System 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.
|
||||
|
||||
The Buildable Stick System is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
The Buildable Stick System is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with the Buildable Stick System. If not, see
|
||||
<https://www.gnu.org/licenses/>.
|
||||
@@ -167,3 +209,9 @@ like the below should suffice in either electronic or printed form:
|
||||
|
||||
> This arcade stick is part of the Buildable Stick System, version X.Y.Z; the source code to this program is available
|
||||
> under the terms of the GNU General Public License, at [LINK].
|
||||
|
||||
## Gallery
|
||||
|
||||
More photos.
|
||||
|
||||

|
||||
|
||||
@@ -4,4 +4,8 @@ Notes for "next time".
|
||||
|
||||
## v4.x
|
||||
|
||||
* Engraving some cosmetic stuff? Or maybe a place to mount other plates?
|
||||
* Engraving some cosmetic stuff? Or maybe a place to mount other plates on the top?
|
||||
|
||||
## v5
|
||||
|
||||
* Finishing the build123d rewrite?
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
# The Attic
|
||||
|
||||
This directory includes abandoned pieces that I'd like to revisit some time, but I cannot support or recommend using
|
||||
as-is. Print at your own caution, or better yet, maybe fix them!
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* A stick mount that fits rectangular (non-extended) BSS sticks.
|
||||
*
|
||||
* SPDX-FileCopyrightText: © 2024 Brian S. Stephan <bss@incorporeal.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
include <../parameters.scad>
|
||||
include <../components.scad>
|
||||
|
||||
holder_x = 114;
|
||||
holder_y = 60;
|
||||
holder_z = 45;
|
||||
tall_holder_post = frame_y-10;
|
||||
|
||||
module stick_holder() {
|
||||
difference() {
|
||||
cube([holder_x, holder_y, holder_z], center=true);
|
||||
translate([14, 0, 132]) rotate([90, -40, 0]) frame_solid();
|
||||
}
|
||||
}
|
||||
|
||||
module mount() {
|
||||
difference() {
|
||||
union() {
|
||||
// lowest post
|
||||
translate([62, -frame_z-25, holder_z/2]) stick_holder(); // top = 45
|
||||
|
||||
// middle post
|
||||
translate([0, 0, ((tall_holder_post)/2)/2])
|
||||
cube([holder_x, holder_y, (tall_holder_post)/2], center=true);
|
||||
translate([0, 0, ((tall_holder_post)/2)+holder_z/2]) stick_holder(); // top = 139
|
||||
|
||||
// highest post
|
||||
translate([-62, frame_z+25, tall_holder_post/2])
|
||||
cube([holder_x, holder_y, tall_holder_post], center=true);
|
||||
translate([-62, frame_z+25, tall_holder_post+holder_z/2]) stick_holder(); // top = 233
|
||||
|
||||
// post stabilizers
|
||||
translate([31, -41, holder_z/2]) cube([52, 23, holder_z], center=true);
|
||||
translate([-31, 41, ((tall_holder_post/2)+holder_z)/2])
|
||||
cube([52, 23, (tall_holder_post/2)+holder_z], center=true);
|
||||
|
||||
// base
|
||||
hull() {
|
||||
translate([110, 103, -2.5]) cylinder(r=15, h=5, center=true);
|
||||
translate([110, -103, -2.5]) cylinder(r=15, h=5, center=true);
|
||||
translate([-110, 103, -2.5]) cylinder(r=15, h=5, center=true);
|
||||
translate([-110, -103, -2.5]) cylinder(r=15, h=5, center=true);
|
||||
}
|
||||
|
||||
// placard
|
||||
translate([0, -112, 15]) cube([frame_y, 5, 30], center=true);
|
||||
|
||||
/* // test */
|
||||
/* translate([62+14, -frame_z-25, 132+holder_z/2]) rotate([90, -40, 0]) frame_solid(); */
|
||||
/* translate([14, 0, 132+(frame_y/2)-20+holder_z/2]) rotate([90, -40, 0]) frame_solid(); */
|
||||
/* translate([-62+14, frame_z+25, 132+tall_holder_post+holder_z/2]) rotate([90, -40, 0]) frame_solid(); */
|
||||
}
|
||||
// text on the placard
|
||||
translate([-frame_z*3.3/2.5, -holder_x, 15]) rotate([90, 0, 0])
|
||||
linear_extrude(1) text("Buildable Stick System", font="Noto Sans");
|
||||
translate([-frame_z*3.3/2.5, -holder_x, 4]) rotate([90, 0, 0])
|
||||
linear_extrude(1) text("v4 by bss", font="Noto Sans", size=6);
|
||||
}
|
||||
}
|
||||
|
||||
mount();
|
||||
@@ -0,0 +1,55 @@
|
||||
"""Compile all OpenSCAD files into a build directory and package it with docs.
|
||||
|
||||
(a.k.a.: "make is hard"
|
||||
|
||||
SPDX-FileCopyrightText: © 2024 Brian S. Stephan <bss@incorporeal.org>
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
||||
"""
|
||||
import os
|
||||
import os.path
|
||||
import re
|
||||
import subprocess
|
||||
|
||||
PROJECT_ROOT = os.path.abspath(os.getcwd())
|
||||
BUILD_DIR = os.path.join(PROJECT_ROOT, 'build', 'models')
|
||||
SOURCE_DIR = os.path.join(PROJECT_ROOT, 'src')
|
||||
|
||||
EXCLUDES = ['components.scad', 'parameters.scad']
|
||||
|
||||
# set up our environment to point openscad at the right stuff
|
||||
os.environ['OPENSCADPATH'] = SOURCE_DIR
|
||||
|
||||
# track processes to wait on
|
||||
processes = []
|
||||
|
||||
os.chdir(SOURCE_DIR)
|
||||
for root, dirs, files in os.walk('.'):
|
||||
print(f"{root} {dirs} {files}")
|
||||
if root == './lib':
|
||||
continue
|
||||
|
||||
# make the current directory so that openscad can write stuff into it
|
||||
try:
|
||||
os.makedirs(os.path.join(BUILD_DIR, root))
|
||||
except FileExistsError:
|
||||
pass
|
||||
|
||||
input_dir = os.path.join(SOURCE_DIR, root)
|
||||
output_dir = os.path.join(BUILD_DIR, root)
|
||||
for file in files:
|
||||
if not re.match(r'.*\.scad$', file):
|
||||
continue
|
||||
if file in EXCLUDES:
|
||||
continue
|
||||
|
||||
stl_file = re.sub(r'\.scad$', '.stl', file)
|
||||
input_ = os.path.join(input_dir, file)
|
||||
output = os.path.join(output_dir, stl_file)
|
||||
cmd = f'openscad --hardwarnings -o {output} {input_}'
|
||||
print(cmd)
|
||||
processes.append(subprocess.Popen(cmd.split(' ')))
|
||||
|
||||
for process in processes:
|
||||
process.wait()
|
||||
if process.returncode != 0:
|
||||
raise Exception(f"building {process.args} failed")
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: © 2023 Brian S. Stephan <bss@incorporeal.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
include <parameters.scad>
|
||||
include <components.scad>
|
||||
use <frames/pieces/side-trapezoid.scad>
|
||||
use <frames/pieces/front-or-back-aux-and-neutrik.scad>
|
||||
use <frames/pieces/front-or-back-windowed-horiz-stripes.scad>
|
||||
use <panels/inset/lever-and-dir_arc-plus-w-30mm-panel.scad>
|
||||
use <panels/inset/sega-2p-nine-plus-aux-button-with-mount.scad>
|
||||
use <plates/decorative-plate-24mm-button.scad>
|
||||
use <plates/decorative-plate-dir_arc-plus-w-30mm-and-sega-2p-nine.scad>
|
||||
use <plates/dustwasher-lsx-nobi.scad>
|
||||
|
||||
top_panel_color = "#5B6579";
|
||||
bottom_panel_color = "#8E9089";
|
||||
frame_top_bottom_color = "#8E9089";
|
||||
frame_side_color = "#8E9089";
|
||||
top_deco_color = "#8E9089";
|
||||
|
||||
color(top_panel_color) translate([-panel_x/2, 0, frame_z/2-panel_z+0.01]) lever_and_dir_arc_w_30mm_panel();
|
||||
color(top_panel_color) translate([panel_x/2, 0, frame_z/2-panel_z+0.01]) sega_2p_nine_plus_aux_button_with_mount();
|
||||
color(frame_side_color) translate([-frame_x/2+4, 0, -2.5]) side_trapezoid_frame_piece();
|
||||
color(frame_side_color) translate([frame_x/2-4, 0, -2.5]) mirror([1, 0, 0]) side_trapezoid_frame_piece();
|
||||
color(frame_top_bottom_color) translate([-frame_x/2+4, 0, -2.5]) horiz_striped_windowed_front_or_back_frame_piece();
|
||||
color(frame_top_bottom_color) translate([frame_x/2-4, 0, -2.5]) horiz_striped_windowed_front_or_back_frame_piece();
|
||||
color(frame_top_bottom_color) translate([-frame_x/2+4, 0, -2.5]) rotate([180, 0, 0]) front_or_back_aux_and_neutrik_frame_piece();
|
||||
color(frame_top_bottom_color) translate([frame_x/2-4, 0, -2.5]) rotate([180, 180, 0]) front_or_back_aux_and_neutrik_frame_piece();
|
||||
color(bottom_panel_color) translate([-panel_x/2, 0, -5-frame_z/2+5]) panel();
|
||||
color(bottom_panel_color) translate([panel_x/2, 0, -5-frame_z/2+5]) panel();
|
||||
|
||||
color(top_deco_color) translate([0, 0, 3+frame_z/2-panel_z]) dir_arc_plus_w_30mm_and_sega_2p_nine_decorative_plate();
|
||||
color(top_deco_color) translate([-170, 20, 3+frame_z/2-panel_z]) lsx_nobi_dustwasher();
|
||||
color(top_deco_color) translate([panel_x-24, 30, 3+frame_z/2-panel_z]) button_24mm_decorative_plate();
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: © 2023 Brian S. Stephan <bss@incorporeal.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
include <parameters.scad>
|
||||
include <components.scad>
|
||||
use <frames/pieces/side-trapezoid-extended-to-front-trapezoid.scad>
|
||||
use <frames/pieces/front-or-back-trapezoid.scad>
|
||||
use <frames/pieces/front-or-back-aux-and-neutrik.scad>
|
||||
use <panels/inset/lever-and-ergo-wasd-five-panel-with-oled.scad>
|
||||
use <panels/inset/ergo-nine-plus-aux-button-with-mount.scad>
|
||||
use <plates/decorative-plate-24mm-button.scad>
|
||||
use <plates/decorative-plate-ergo-wasd-five-30mm-and-ergo-nine-30mm.scad>
|
||||
use <plates/dustwasher-lsx-nobi.scad>
|
||||
|
||||
top_panel_color = "#0086D6";
|
||||
bottom_panel_color = "white";
|
||||
frame_front_color = "white";
|
||||
frame_back_color = "white";
|
||||
frame_side_color = "yellow";
|
||||
top_deco_color = "white";
|
||||
|
||||
color(top_panel_color) translate([-panel_x/2, 0, frame_z/2-panel_z/2+0.001]) lever_and_ergo_wasd_five_panel_with_oled();
|
||||
color(top_panel_color) translate([panel_x/2, 0, frame_z/2-panel_z/2+0.001]) ergo_nine_plus_aux_button_panel_with_mount();
|
||||
color(frame_side_color) translate([-frame_x/2+4, 0, 0]) side_trapezoid_extended_to_front_frame_piece();
|
||||
color(frame_side_color) translate([frame_x/2-4, 0, 0]) mirror([1, 0, 0]) side_trapezoid_extended_to_front_frame_piece();
|
||||
color(frame_front_color) translate([-frame_x/2+4, 0, 0]) front_or_back_trapezoid_frame_piece();
|
||||
color(frame_front_color) translate([frame_x/2-4, 0, 0]) front_or_back_trapezoid_frame_piece();
|
||||
color(frame_back_color) translate([-frame_x/2+4, 0, 0]) rotate([180, 0, 0]) front_or_back_aux_and_neutrik_frame_piece();
|
||||
color(frame_back_color) translate([frame_x/2-4, 0, 0]) rotate([180, 180, 0]) front_or_back_aux_and_neutrik_frame_piece();
|
||||
/* color(bottom_panel_color) translate([-panel_x/2, 0, -5-frame_z/2+5]) panel(); */
|
||||
/* color(bottom_panel_color) translate([panel_x/2, 0, -5-frame_z/2+5]) panel(); */
|
||||
|
||||
color(top_deco_color) translate([0, 0, 4+frame_z/2-panel_z/2+0.001]) ergo_wasd_five_30mm_and_ergo_nine_30mm_decorative_plate();
|
||||
color(top_deco_color) translate([-170, 25, 4+frame_z/2-panel_z/2+0.001]) lsx_nobi_dustwasher();
|
||||
color(top_deco_color) translate([panel_x-24, 30, 4+frame_z/2-panel_z/2+0.001]) button_24mm_decorative_plate();
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: © 2023 Brian S. Stephan <bss@incorporeal.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
include <parameters.scad>
|
||||
include <components.scad>
|
||||
use <frames/pieces/front-or-back-trapezoid.scad>
|
||||
use <frames/pieces/side-trapezoid-extended-to-front-trapezoid.scad>
|
||||
use <frames/pieces/front-or-back-aux-and-neutrik.scad>
|
||||
use <panels/inset/lever-and-dir_arc-plus-w-30mm-panel.scad>
|
||||
use <panels/inset/lever-and-sega-2p-6-button-panel-with-aux-with-mount.scad>
|
||||
use <plates/dustwasher-jlf.scad>
|
||||
|
||||
top_panel_color = "#5B6579";
|
||||
bottom_panel_color = "#8E9089";
|
||||
frame_top_bottom_color = "#8E9089";
|
||||
frame_side_color = "#8E9089";
|
||||
top_deco_color = "#000000";
|
||||
|
||||
color(top_panel_color) translate([0, 0, frame_z/2-panel_z+0.01]) lever_and_sega_2p_6_button_panel_with_aux_with_mount();
|
||||
color(frame_side_color) translate([0, 0, -2.5]) side_trapezoid_extended_to_front_frame_piece();
|
||||
color(frame_side_color) translate([0, 0, -2.5]) mirror([1, 0, 0]) side_trapezoid_extended_to_front_frame_piece();
|
||||
color(frame_top_bottom_color) translate([0, 0, -2.5]) front_or_back_trapezoid_frame_piece();
|
||||
color(frame_top_bottom_color) translate([0, 0, -2.5]) rotate([180, 0, 0]) front_or_back_aux_and_neutrik_frame_piece();
|
||||
color(bottom_panel_color) translate([0, 0, -5-frame_z/2+5]) panel();
|
||||
|
||||
color(top_deco_color) translate([-65, 5, 3+frame_z/2-panel_z]) jlf_dustwasher();
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: © 2023 Brian S. Stephan <bss@incorporeal.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
include <parameters.scad>
|
||||
include <components.scad>
|
||||
use <frames/pieces/side.scad>
|
||||
use <frames/pieces/front-or-back.scad>
|
||||
use <frames/pieces/front-or-back-aux-and-neutrik.scad>
|
||||
use <panels/inset/lever-and-ergo-wasd-five-panel-with-oled.scad>
|
||||
use <panels/inset/ergo-nine-plus-aux-button-with-mount.scad>
|
||||
use <plates/decorative-plate-24mm-button.scad>
|
||||
use <plates/decorative-plate-ergo-wasd-five-30mm-and-ergo-nine-30mm.scad>
|
||||
use <plates/dustwasher-lsx-nobi.scad>
|
||||
|
||||
panel_color = "red";
|
||||
base_color = "gray";
|
||||
top_deco_color = "white";
|
||||
brace_color = "gray";
|
||||
|
||||
color(panel_color) translate([-panel_x/2, 0, frame_z/2-panel_z/2+0.001]) lever_and_ergo_wasd_five_panel_with_oled();
|
||||
color(panel_color) translate([panel_x/2, 0, frame_z/2-panel_z/2+0.001]) ergo_nine_plus_aux_button_panel_with_mount();
|
||||
color(base_color) translate([panel_x/2, 0, 0]) rotate([0, 180, 0]) side_frame_piece();
|
||||
color(base_color) translate([-panel_x/2, 0, 0]) side_frame_piece();
|
||||
color(base_color) translate([panel_x/2, 0, 0]) clean_edge_front_or_back_frame_piece();
|
||||
color(base_color) translate([-panel_x/2, 0, 0]) clean_edge_front_or_back_frame_piece();
|
||||
color(base_color) translate([panel_x/2, 0, 0]) rotate([180, 180, 0]) front_or_back_aux_and_neutrik_frame_piece();
|
||||
color(base_color) translate([-panel_x/2, 0, 0]) rotate([180, 0, 0]) front_or_back_aux_and_neutrik_frame_piece();
|
||||
/* color(base_color) translate([-panel_x/2, 0, -frame_z/2+panel_z/2]) panel(); */
|
||||
/* color(base_color) translate([panel_x/2, 0, -frame_z/2+panel_z/2]) panel(); */
|
||||
|
||||
color(top_deco_color) translate([0, 0, 4+frame_z/2-panel_z/2+0.001]) ergo_wasd_five_30mm_and_ergo_nine_30mm_decorative_plate();
|
||||
color(top_deco_color) translate([-170, 25, 4+frame_z/2-panel_z/2+0.001]) lsx_nobi_dustwasher();
|
||||
color(top_deco_color) translate([panel_x-24, 30, 4+frame_z/2-panel_z/2+0.001]) button_24mm_decorative_plate();
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: © 2023 Brian S. Stephan <bss@incorporeal.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
include <parameters.scad>
|
||||
include <components.scad>
|
||||
use <frames/pieces/interconnect.scad>
|
||||
use <frames/pieces/side.scad>
|
||||
use <frames/pieces/front-or-back.scad>
|
||||
use <frames/pieces/front-or-back-aux-and-neutrik.scad>
|
||||
use <panels/overhang/left-lever-and-dir_arc-plus-w-30mm-panel.scad>
|
||||
use <panels/overhang/right-sega-2p-nine-plus-aux-button-with-mount.scad>
|
||||
use <panels/overhang/left-or-right-panel.scad>
|
||||
use <plates/decorative-plate-24mm-button.scad>
|
||||
use <plates/decorative-plate-dir_arc-plus-w-30mm-and-sega-2p-nine.scad>
|
||||
use <plates/dustwasher-lsx-nobi.scad>
|
||||
|
||||
color("#C12E1F") translate([-panel_x/2-25, 0, frame_z/2+75]) lever_and_dir_arc_w_30mm_left_overhang_panel();
|
||||
color("#C12E1F") translate([panel_x/2+25, 0, frame_z/2+75]) sega_2p_nine_plus_aux_button_right_overhang_panel_with_mount();
|
||||
color("black") translate([-frame_x/2+5-25, -55, -2.5]) clean_edge_front_or_back_frame_piece();
|
||||
color("black") rotate([0, 180, 0]) translate([-frame_x/2+5-25, -55, -2.5]) clean_edge_front_or_back_frame_piece();
|
||||
color("black") translate([-frame_x/2+5-50, 0, -2.5]) side_frame_piece();
|
||||
color("black") rotate([0, 180, 0]) translate([-frame_x/2+5-50, 0, -2.5]) side_frame_piece();
|
||||
color("black") rotate([180, 0, 0]) translate([-frame_x/2+5-25, -55, -2.5]) front_or_back_aux_and_neutrik_frame_piece();
|
||||
color("black") rotate([180, 0, 0]) rotate([0, 180, 0]) translate([-frame_x/2+5-25, -55, -2.5]) front_or_back_aux_and_neutrik_frame_piece();
|
||||
color("black") rotate([0, 180, 0]) interconnect_frame_piece();
|
||||
color("#C12E1F") translate([-panel_x/2-25, 0, -5-frame_z/2-75]) left_or_right_overhang_panel();
|
||||
color("#C12E1F") mirror([0, 1, 0]) translate([panel_x/2+25, 0, -5-frame_z/2-75]) rotate([0, 0, 180])
|
||||
left_or_right_overhang_panel();
|
||||
|
||||
color("black") translate([0, 0, 3+frame_z/2+150]) dir_arc_plus_w_30mm_and_sega_2p_nine_decorative_plate();
|
||||
color("black") translate([-195, 25, 3+frame_z/2+150]) lsx_nobi_dustwasher();
|
||||
color("black") translate([panel_x, 25, 3+frame_z/2+150]) button_24mm_decorative_plate();
|
||||
+18
-34
@@ -1,40 +1,11 @@
|
||||
# The Buildable Stick System
|
||||
|
||||
Files for 3D printing an arcade stick.
|
||||
Files for 3D printing an arcade stick. See `README.md` for the core documentation, this file is specific to distributed
|
||||
objects.
|
||||
|
||||
## Objects
|
||||
## Attribution
|
||||
|
||||
The following notes document the objects in the Buildable Stick System and how you can use them:
|
||||
|
||||
* `bottom-panel-inset`: a simple solid panel that fits into the bottom of a frame box.
|
||||
* `bottom-panel-overhang-*`: solid panels whose base fits into the bottom of a frame box, but have a longer sheet that
|
||||
extends beyond the frame, creating a sandwich kind of look; the various forms hang over more or less of the frame,
|
||||
expecting it will be connected to other frames.
|
||||
* `frame-{left,middle,right,solo}`: the core frame of the stick, these are complete boxes; since they are long and
|
||||
narrow, and need supports to print the space for the insets, these may be difficult to print nicely.
|
||||
* `frame-piece-*`: the core frame broken up by individual faces, which are easier to print and essentially just as
|
||||
sturdy.
|
||||
* `frame-piece-*-extended*`: frame pieces that have been stretched out beyond the normal frame dimensions in order to
|
||||
make a nice bevel on the sides and/or bottom; this, interestingly, tends to make the stick look a bit thinner than if
|
||||
it was just a simple box.
|
||||
* `misc-decorative-plate-*`: things you can print to snazz up face buttons mounting, auxillary button points, etc..
|
||||
* `misc-dustwasher-*`: simple dustwashers for levers.
|
||||
* `misc-lever-mount-*`: lever mounts of various shapes and depths to get the desired lever height when mounting a lever
|
||||
to a panel (with the appropriate cutouts).
|
||||
* `misc-neutrik-*`: like the decorative plates, but these are a bit more necessary by their design.
|
||||
* `misc-rocker-*`: rocker SPDT switches don't have mounting holes, this allows you to attach them to the frame.
|
||||
* `top-panel-inset-*`: various lever and/or button layouts for using as the face(s) of a stick.
|
||||
* `top-panel-overhang-`: same idea as the inset top panels, but overhung over the frame to make the sandwich look; these
|
||||
also leave a bit more space inside the frame, which might accommodate a taller lever.
|
||||
|
||||
Feel free to request or contribute to more objects, see the links to Git repos below.
|
||||
|
||||
## Printing and Assembling
|
||||
|
||||
Additional documentation regarding printing the objects and assembling the stick are available in
|
||||
`docs/printing-and-materials.md` and `docs/assembly-and-tips.md`, respectively.
|
||||
|
||||
## Author and Licensing
|
||||
### Author and Licensing
|
||||
|
||||
Written by and copyright Brian S. Stephan (<bss@incorporeal.org>).
|
||||
|
||||
@@ -57,9 +28,22 @@ details.
|
||||
You should have received a copy of the GNU General Public License along with the Buildable Stick System. If not, see
|
||||
<https://www.gnu.org/licenses/>.
|
||||
|
||||
## Lineage
|
||||
### Lineage
|
||||
|
||||
Inspired by the incredible work of [TheTrain](https://github.com/TheTrainGoes) on the [OpenStickCommunity Fightstick
|
||||
Case](https://github.com/OpenStickCommunity/Hardware/tree/main/Fightstick%20Case), itself based on the incredible work
|
||||
by [Dash n'Mash](https://twitter.com/Dash_xx_Mash?s=20). Original work Copyright 2023 TheTrain, [licensed under CC BY
|
||||
4.0](https://creativecommons.org/licenses/by/4.0/).
|
||||
|
||||
Made possible by the amazing efforts of [slagcoin](https://www.slagcoin.com/).
|
||||
|
||||
### Distributing BSS Sticks
|
||||
|
||||
Under the terms of the GPLv3, you must inform the receiver of the "object code" of their rights under the GPLv3. This is
|
||||
a bit of a gray area for physical objects, but likely applies to distribution of modified or unmodified STL, STEP, etc.
|
||||
files at a minimum. The easiest way to satisfy the GPLv3 in either situation is to provide a link to the source code
|
||||
(either the unmodified mainline project, or your copy, with modifications listed in a "prominent notice"); something
|
||||
like the below should suffice in either electronic or printed form:
|
||||
|
||||
> This arcade stick is part of the Buildable Stick System, version X.Y.Z; the source code to this program is available
|
||||
> under the terms of the GNU General Public License, at [LINK].
|
||||
|
||||
+53
-33
@@ -1,28 +1,64 @@
|
||||
# Assembly and Tips
|
||||
|
||||
Just some miscellaneous notes for any dear reader, or more likely, my own forgetful self.
|
||||
These are the parts you need and instructions for creating a simple two panel arcade stick. The end product is a
|
||||
rectangular prism roughly 18" long, with ample space for back buttons and enough top panel space for almost any layout
|
||||
you can imagine. There are more pieces and designs to experiment with, but this will get you an awesome "standard"
|
||||
build.
|
||||
|
||||
## Parts for a Basic Enclosure
|
||||
|
||||
The pieces you need to print (all colors to your taste):
|
||||
|
||||
* **The base frame:** `frame/pieces/front-or-back.stl` x2 + `frame/pieces/front-or-back-aux-and-neutrik.stl` x2 +
|
||||
`frame/pieces/interconnect.stl`. This creates a large "H" with six 24mm button holes and two Neutrik D holes on the
|
||||
back, which can mount USB connectors or rocker switches, or be covered if not used. All four of the front or back
|
||||
pieces connect to the interconnect piece, which creates one frame out of the individual pieces, and also adds some
|
||||
support to the center of the enclosure. The interconnect has a large hole that can either make wire routing easier, or
|
||||
leave space in the center for button layouts that span it.
|
||||
* **The frame sides:** `frame/pieces/side.stl` x2. These cap the "H", completing the overall frame.
|
||||
* **The top:** `panels/inset/[LAYOUTS].stl`. These panels go on the top of the frame and are where you mount all of your
|
||||
main buttons and levers and whatnot. There are a couple layouts whose panels are meant to be paired (e.g.
|
||||
`shiokenstar-left-panel.stl` and `shiokenstar-right-panel.stl`), but usually you simply pick a left panel (e.g.
|
||||
`lever-panel-with-mount.stl`) and right panel (e.g. `sega-2p-panel.stl`) based on what you want. Note that one of your
|
||||
choices should be "with mount", which is where the usually-sized PCB will screw into inside the box.
|
||||
* **The bottom:** `panels/inset/panel.stl` x2. Other than being the color of your choice, these just close the box.
|
||||
You could put foam pads or something on these if you wanted.
|
||||
|
||||
The above gets you the basics. Some common things you may also want:
|
||||
|
||||
* **Mounting Neutrik connectors:** Neutrik D connectors can mount flush to the inside of the frame, but you can choose
|
||||
to have a little decorative plate (`plates/neutrik-d-plate.stl` for added depth or color choices on the outside of the
|
||||
frame, if you'd like.
|
||||
* **Mounting a 24mm switch:** a rocker switch can also be mounted in the Neutrik D connector, but it needs to be placed
|
||||
into a `plates/neutrik-d-plate-24mm-hole.stl` plate, and the plate mounted to the frame.
|
||||
* **Flair for the auxillary buttons:** the three buttons in a row on the back of the frame can also get some style, just
|
||||
place a `plates/decorative-plate-aux-control-three-button-cluster.stl` between the buttons and the frame. This only
|
||||
works for screw-in buttons.
|
||||
* **Flair for the top buttons:** same as above, a decorative plate for top panel layouts --- e.g.
|
||||
`plates/decorative-plate-sega-2p.stl` --- can be sandwiched between the buttons and panel to add some style. This also
|
||||
only tends to work on screw-in buttons.
|
||||
* **Dustwashers/flair:** same deal, if you want to print one, use e.g. `plates/dustwasher-jlf.stl`.
|
||||
|
||||
## Putting a BSS Stick Together
|
||||
|
||||
Assembly of a stick is pretty straightforward, but there are some choices that can make it easier or harder. The
|
||||
following is the most consistent way I've found to put one together. This is assuming a v4.2 or beyond stick, with two
|
||||
panels to make a long standard stick, and the frame made of pieces.
|
||||
following is the most consistent way I've found to put one together.
|
||||
|
||||
1. Prepare the frame top pieces --- `frame-piece-top-left-or-right`: this is your best shot to get auxillary buttons,
|
||||
panel connectors, and the like installed, so do it now, and give them a good tighten. You shouldn't need to adjust
|
||||
these again, so finish their installation while the pieces are free.
|
||||
1. This of course includes decorative plates --- e.g. `misc-decorative-plate-aux-control-three-button-cluster` ---
|
||||
you may choose to use. These are held to the top pieces by the buttons or component mounting screws.
|
||||
2. Start the top panels --- `top-panel-(inset|overhang)-*`: you want both to get the components installed now
|
||||
when it's easy, and to make sure that the overall assembly works with your components, so again get your buttons,
|
||||
lever, etc., in place. You can secure them at this point.
|
||||
1. Prepare the frame pieces: this is your best shot to get the e.g. Neutrik plates for the USB mount, SPDT switches, etc.
|
||||
installed, so do it now, and give them a good tighten. You shouldn't need to adjust these again, so finish their
|
||||
installation while the pieces are free.
|
||||
1. You could also do the decorative plates and related buttons, but it might be just as well to leave those for step 7,
|
||||
just to make sure the buttons don't get in the way of other buttons or a lever or so on.
|
||||
2. Start the top panels: you want both to get the components installed now when it's easy, and to make sure that the
|
||||
overall assembly works with your components, so again get your buttons, lever, etc., in place. You can secure them at
|
||||
this point.
|
||||
1. If you are using a button decorative plate that spans two panels --- e.g.
|
||||
`src/misc-decorative-plate-dir_arc-plus-w-30mm-and-sega-2p-plus-one` --- take care to align the two panels as
|
||||
tightly as possible, and accurately, as they will be hard to adjust once everything is secured and in the frame.
|
||||
2. If using a lever, don't forget the lever mount spacer --- `src/misc-lever-mount-sanwa-seimitsu` --- if you want
|
||||
it, and tighten those mounting bolts now as well.
|
||||
3. Create the frame box by combining your `frame-piece-*` parts together. This will be relatively stable just via
|
||||
friction fit.
|
||||
`plates/decorative-plate-dir_arc-plus-w-30mm-and-sega-2p-plus-one` --- take care to align the two panels as tightly
|
||||
as possible, and accurately, as they will be hard to adjust once everything is secured and in the frame.
|
||||
2. If using a lever, don't forget the lever mount spacer --- `plates/lever-mount-sanwa-seimitsu` --- if you want it,
|
||||
and tighten those mounting bolts now as well.
|
||||
3. Create the frame box by combining your frame piece parts, box or extended, together. This will be relatively stable
|
||||
just via friction fit.
|
||||
4. Rest the frame top-up on a desk, and put the standoffs through the holes. This will probably be tight, and you may
|
||||
even need a rubber mallet or similar to drive the standoffs through the holes.
|
||||
5. Insert the top panels into the frame.
|
||||
@@ -34,19 +70,3 @@ panels to make a long standard stick, and the frame made of pieces.
|
||||
|
||||
In the end, this should be extremely sturdy. None of the frame or panels should be loose at all, and you should be able
|
||||
to move, flip, gently toss, etc. the stick without anything moving or feeling loose.
|
||||
|
||||
## Removing Inset Panels
|
||||
|
||||
As of v4.1 (or in v3), the top and bottom inset panels both insert into the frame, inside the frame "lip", meaning that
|
||||
when everything is put together, they create a flush surface (more or less). This can make them hard to get out, as you
|
||||
can't grab anything to get any leverage, and especially with v4.1, the plastic posts to aid the friction fit make it
|
||||
even harder to muscle out --- in fact, even if you could get an edge and start yanking, you'd probably just break some
|
||||
of the plastic.
|
||||
|
||||
You can instead use the reverse side and the hex standoffs to push a panel out, as so:
|
||||
|
||||
1. Loosen, or completely remove, the hex bolts for the panel you would like to remove.
|
||||
2. Flip the stick over, and remove the hex bolts on the opposite side.
|
||||
3. Screw in longer bolts, or anything else that'll fit into the hole without going flush against the panel.
|
||||
4. Push the long bolts in, thus pushing the standoffs, thus pushing the desired panel out from within.
|
||||
5. You may have to even get a mallet and tap on a bolt, occasionally, as everything can be *pretty* tight.
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 121 KiB After Width: | Height: | Size: 66 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 372 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 416 KiB |
@@ -4,10 +4,19 @@ bss's random thoughts and notes on the actual printing of the Buildable Stick Sy
|
||||
|
||||
## Printing Settings
|
||||
|
||||
My preferred settings are 3 wall loops with 20% gyroid sparse infill. This gives the models a bit more weight and
|
||||
My preferred settings are 3 wall loops with 25% gyroid sparse infill. This gives the models a bit more weight and
|
||||
strength against bowing forces, but something more default, like 2 wall loops, 15% grid sparse infill, is fine and does
|
||||
not lead to a weak enclosure.
|
||||
|
||||
### Supports and Positioning
|
||||
|
||||
All of the parts are designed to be printed outside-face-down. The bevels are at an angle (45 degrees) that should print
|
||||
fine with no supports. Make sure everything is aligned properly on your plate so that the flat face you will look at the
|
||||
most is on the bottom.
|
||||
|
||||
The only exception to this is the interconnect piece(s), which are not visible and need a support to print. Maybe one
|
||||
day I'll rejigger these.
|
||||
|
||||
### Working With Flatness
|
||||
|
||||
A lot of the pieces are long and flat, so I recommend really dialing in your printer settings. The frame pieces make
|
||||
@@ -20,15 +29,36 @@ uniform lines that create reflection patterns on long, flat surfaces. This can b
|
||||
panels and their decorative plates, since they're what you're looking at 90% of the time, and the holes break up a
|
||||
perfect pattern, making the long lines stand out even more.
|
||||
|
||||
* **Top panels:** using a non-uniform pattern reduces if not eliminates the problem of the surface catching the light,
|
||||
but for some patterns, it may come at the expense of time. Other patterns may improve beyond monotonic, but hilbert
|
||||
curve seems to be the gold standard.
|
||||
* **Circle-centric decorative plates:** don't use complex patterns like Archimedean chords on decorative plates, as they
|
||||
seem to have issues with filling curves and you still want to try to maximize contact with walls. Concentric is great
|
||||
here if you dial it in.
|
||||
Some specific parts are worth some additional notes:
|
||||
|
||||
The concentric pattern is a good default and prints awesome parts, with the only exception being the top panels, which
|
||||
benefit from using a Hilbert curve initial layer pattern instead of concentric.
|
||||
* **Top panels:** using a non-uniform pattern reduces if not eliminates the problem of the surface catching the light,
|
||||
but for some patterns, it may come at the expense of time.
|
||||
* **Avoid:** monotonic.
|
||||
* **Good for the time:** Archimedean chords create the look of a circular ripple radiating out the center, and
|
||||
depending on the material, you may not even notice it much, so it's a pretty good look/speed balance.
|
||||
* **Great if you can wait:** hilbert curve leaves no discernable pattern on most materials, but some high gloss,
|
||||
high contrast materials may show the winding pattern at some angles --- consider Archimedean chords for these.
|
||||
* **Circle-centric decorative plates:** simple ones could be fine in whatever, but the ones for action buttons end up
|
||||
having lots of weird interaction points.
|
||||
* **Avoid:** none; monotonic doesn't look *good*, but the plates don't have enough surface area for the pattern to
|
||||
stand out too much.
|
||||
* **Decent:** concentric is generally good, but you can get some pitting when the pattern radiating away from
|
||||
buttons collides with other patterns, because none of the geometry lines up well.
|
||||
* **Great:** Archimedean chords, just crank up the infill/wall overlap to avoid pits on the edges.
|
||||
* **Frame walls with Neutrik or aux button cutouts:** a reduced but similar problem with the action button decorative
|
||||
plates, the circles near each other create weird interactions with the walls.
|
||||
* **Avoid:** concentric, again, has problems with pitting where geometries clash.
|
||||
* **Decent:** monotonic is pretty decent here, and you probably won't look at the sides too much, so maybe it
|
||||
doesn't bother you.
|
||||
* **Great:** Archimedean chords again, with the same infill/wall overlap as decorative plates.
|
||||
* **Flush frame walls:** you can pretty much do whatever you like here.
|
||||
* **Great:** concentric produces an interesting pattern and you won't have collision problems in a rectangle.
|
||||
* **Essentially great:** Archimedean chords yet again, you may just not like the pattern as much as the end result
|
||||
of concentric.
|
||||
|
||||
The Archimedean chord pattern is a good default and prints awesome parts, with the only exception being the top panels,
|
||||
which benefit from using a Hilbert curve initial layer pattern instead, though you may be happy enough with Archimedean
|
||||
chord.
|
||||
|
||||
## Materials
|
||||
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: © 2023 Brian S. Stephan <bss@incorporeal.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
include <parameters.scad>
|
||||
include <components.scad>
|
||||
use <frame-left.scad>
|
||||
use <frame-right.scad>
|
||||
use <top-panel-overhang-left-lever-and-dir_arc-plus-w-30mm.scad>
|
||||
use <top-panel-overhang-right-sega-2p-plus-one-plus-control-with-mount.scad>
|
||||
use <bottom-panel-overhang-left.scad>
|
||||
use <bottom-panel-overhang-right.scad>
|
||||
use <misc-decorative-plate-24mm-button.scad>
|
||||
use <misc-decorative-plate-dir_arc-plus-w-30mm-and-sega-2p-plus-one.scad>
|
||||
use <misc-dustwasher-lsx-nobi.scad>
|
||||
|
||||
color("#C12E1F") translate([-panel_x/2-25, 0, frame_z/2+75]) top_panel_left_lever_and_dir_arc_w_30mm();
|
||||
color("#C12E1F") translate([panel_x/2+25, 0, frame_z/2+75]) top_panel_right_sega_2p_plus_one_plus_control_with_mount();
|
||||
color("black") translate([-frame_x/2+5-25, 0, -2.5]) left_frame();
|
||||
color("black") translate([frame_x/2+25, 0, -2.5]) right_frame();
|
||||
color("#C12E1F") translate([-panel_x/2-25, 0, -5-frame_z/2-75]) bottom_panel_left();
|
||||
color("#C12E1F") translate([panel_x/2+25, 0, -5-frame_z/2-75]) bottom_panel_right();
|
||||
|
||||
color("black") translate([0, 0, 3+frame_z/2+150]) dir_arc_plus_w_30mm_and_sega_2p_plus_one_decorative_plate();
|
||||
color("black") translate([-195, 25, 3+frame_z/2+150]) lsx_nobi_dustwasher();
|
||||
color("black") translate([panel_x, 25, 3+frame_z/2+150]) button_24mm_decorative_plate();
|
||||
@@ -1,14 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: © 2023 Brian S. Stephan <bss@incorporeal.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
include <parameters.scad>
|
||||
include <components.scad>
|
||||
use <bottom-panel-overhang-left.scad>
|
||||
|
||||
module bottom_panel_right() {
|
||||
rotate([0, 0, 180]) bottom_panel_left();
|
||||
}
|
||||
|
||||
bottom_panel_right();
|
||||
+205
-56
@@ -11,6 +11,10 @@ module m4_hole_countersink() {
|
||||
cylinder(r1=m4_bolt_radius, r2=m4_bolt_countersink_radius, h=3.2, $fn=50, center=true);
|
||||
}
|
||||
|
||||
module m6_hole() {
|
||||
cylinder(r=m6_bolt_radius, h=100, $fn=50, center=true);
|
||||
}
|
||||
|
||||
module panel_holes() {
|
||||
// holes for mount bolts
|
||||
translate([panel_to_frame_point_x, panel_to_frame_point_y, 0]) m4_hole();
|
||||
@@ -27,27 +31,25 @@ module panel_holes() {
|
||||
// button hole, with extra wide bits for various uses (cutting out space
|
||||
// for snap-ins, etc.
|
||||
module button_24mm_hole() {
|
||||
cylinder(r=small_button_radius, h=100, $fn=50, center=true);
|
||||
// carve out space for snap-ins, leave 3mm
|
||||
// slagcoin has screw-in nut diameter at 29.5mm, so radius+3 to leave some space
|
||||
cylinder(r=small_button_radius, h=100, $fn=100, center=true);
|
||||
// carve out space for snap-ins and screw-in nuts
|
||||
// translation is to leave 3mm thickness in the plate without recentering anything
|
||||
translate([0, 0, -25]) cylinder(r=small_button_radius+3, h=49, $fn=50, center=true);
|
||||
translate([0, 0, -25]) cylinder(r=small_button_radius+button_radius_connector_space, h=49, $fn=100, center=true);
|
||||
// space for decorative button surround stuff
|
||||
translate([0, 0, 50]) cylinder(r=small_button_radius*decorative_radius_scale, h=20, $fn=50, center=true);
|
||||
translate([0, 0, 70]) cylinder(r=small_button_radius*jumbo_decorative_radius_scale, h=20, $fn=50, center=true);
|
||||
translate([0, 0, 50]) cylinder(r=small_button_radius*decorative_radius_scale, h=20, $fn=100, center=true);
|
||||
translate([0, 0, 70]) cylinder(r=small_button_radius*jumbo_decorative_radius_scale, h=20, $fn=100, center=true);
|
||||
}
|
||||
|
||||
// button hole, with extra wide bits for various uses (cutting out space
|
||||
// for snap-ins, etc.
|
||||
module button_30mm_hole() {
|
||||
cylinder(r=big_button_radius, h=100, $fn=50, center=true);
|
||||
// carve out space for snap-ins, leave 3mm
|
||||
// slagcoin has screw-in nut diameter at 36mm, so radius+6 to leave some space
|
||||
cylinder(r=big_button_radius, h=100, $fn=100, center=true);
|
||||
// carve out space for snap-ins and screw-in nuts
|
||||
// translation is to leave 3mm thickness in the plate without recentering anything
|
||||
translate([0, 0, -25]) cylinder(r=big_button_radius+6, h=49, $fn=50, center=true);
|
||||
translate([0, 0, -25]) cylinder(r=big_button_radius+button_radius_connector_space, h=49, $fn=100, center=true);
|
||||
// space for decorative button surround stuff
|
||||
translate([0, 0, 50]) cylinder(r=big_button_radius*decorative_radius_scale, h=20, $fn=50, center=true);
|
||||
translate([0, 0, 70]) cylinder(r=big_button_radius*jumbo_decorative_radius_scale, h=20, $fn=50, center=true);
|
||||
translate([0, 0, 50]) cylinder(r=big_button_radius*decorative_radius_scale, h=20, $fn=100, center=true);
|
||||
translate([0, 0, 70]) cylinder(r=big_button_radius*jumbo_decorative_radius_scale, h=20, $fn=100, center=true);
|
||||
}
|
||||
|
||||
module frame_hex_bolt_hole() {
|
||||
@@ -55,7 +57,7 @@ module frame_hex_bolt_hole() {
|
||||
}
|
||||
|
||||
module frame_interchange_hole() {
|
||||
cylinder(r=18, h=50, $fn=4, center=true);
|
||||
cylinder(r=37, h=50, $fn=50, center=true);
|
||||
}
|
||||
|
||||
module neutrik_d_hole() {
|
||||
@@ -79,9 +81,10 @@ module rocker_20mm_mount() {
|
||||
translate([-9.5, -12, 0]) neutrik_d_screw_hole();
|
||||
}
|
||||
|
||||
// space for a neutrik D mount or 24mm button - Z is to cut the whole inside without affecting panel lip
|
||||
// space for a neutrik D mount or 24mm button --- Z is meant to leave some lip now that frames
|
||||
// are primarily printed on their side
|
||||
module frame_cutout() {
|
||||
cube([30.5, 8, frame_z-(panel_z*2)], center=true);
|
||||
cube([35, 8, frame_z-(panel_z*3)], center=true);
|
||||
}
|
||||
|
||||
// bank of three 24mm buttons, commonly on a frame face
|
||||
@@ -91,6 +94,12 @@ module aux_control_three_button_cluster() {
|
||||
translate([37, 0, 0]) button_24mm_hole();
|
||||
}
|
||||
|
||||
module aux_control_three_button_tight_cluster() {
|
||||
translate([-32, 0, 0]) button_24mm_hole();
|
||||
translate([0, 0, 0]) button_24mm_hole();
|
||||
translate([32, 0, 0]) button_24mm_hole();
|
||||
}
|
||||
|
||||
module m2_mount_post() {
|
||||
difference() {
|
||||
cylinder(r=m2_screw_selftap_radius*2.25, h=3, $fn=6, center=true);
|
||||
@@ -98,16 +107,24 @@ module m2_mount_post() {
|
||||
}
|
||||
}
|
||||
|
||||
module oled_ssd1306_mount() {
|
||||
translate([11.5, 12, 0]) m2_mount_post();
|
||||
translate([11.5, -12, 0]) m2_mount_post();
|
||||
translate([-11.5, 12, 0]) m2_mount_post();
|
||||
translate([-11.5, -12, 0]) m2_mount_post();
|
||||
module adafruit_pid_326_oled_ssd1306_mount_post() {
|
||||
cylinder(r=2.25/2, h=8, $fn=50, center=true);
|
||||
}
|
||||
|
||||
module oled_ssd1306_mount_cutout() {
|
||||
translate([0, 1.9, 0]) cube([25, 14, 5], center=true);
|
||||
translate([0, 0, -1.0]) cube([35, 35, 4], center=true);
|
||||
// aligned to the cutout below
|
||||
module adafruit_pid_326_oled_ssd1306_mount() {
|
||||
translate([12, 13.25, -2]) adafruit_pid_326_oled_ssd1306_mount_post();
|
||||
translate([12, -13.25, -2]) adafruit_pid_326_oled_ssd1306_mount_post();
|
||||
translate([-12, 13.25, -2]) adafruit_pid_326_oled_ssd1306_mount_post();
|
||||
translate([-12, -13.25, -2]) adafruit_pid_326_oled_ssd1306_mount_post();
|
||||
}
|
||||
|
||||
module adafruit_pid_326_oled_ssd1306_mount_cutout() {
|
||||
translate([0, 3.5, 0]) cube([ssd1306_x, ssd1306_y, panel_z+0.1], center=true);
|
||||
translate([0, 0, -ssd1306_z/2]) cube([adafruit_pid_326_oled_ssd1306_cutout_x,
|
||||
adafruit_pid_326_oled_ssd1306_cutout_y, panel_z-ssd1306_z+0.1], center=true);
|
||||
translate([0, 0, -ssd1306_z/2-2]) cube([adafruit_pid_326_oled_ssd1306_cutout_x*3/2,
|
||||
adafruit_pid_326_oled_ssd1306_cutout_y/2, panel_z/2+0.1], center=true);
|
||||
}
|
||||
|
||||
module m3_mount_post() {
|
||||
@@ -167,10 +184,6 @@ module base_panel() {
|
||||
cube([panel_x, panel_y, panel_z], center=true);
|
||||
}
|
||||
|
||||
module base_bottom_panel() {
|
||||
mirror([0, 0, 1]) base_panel();
|
||||
}
|
||||
|
||||
module panel() {
|
||||
difference() {
|
||||
base_panel();
|
||||
@@ -178,13 +191,6 @@ module panel() {
|
||||
}
|
||||
}
|
||||
|
||||
module bottom_panel() {
|
||||
difference() {
|
||||
base_bottom_panel();
|
||||
mirror([0, 0, 1]) panel_holes();
|
||||
}
|
||||
}
|
||||
|
||||
module overhang_plate() {
|
||||
top_points = [
|
||||
// top bevel
|
||||
@@ -235,7 +241,7 @@ module panel_with_raised_overhang() {
|
||||
}
|
||||
}
|
||||
|
||||
module frame_box() {
|
||||
module frame_solid() {
|
||||
difference() {
|
||||
top_points = [
|
||||
// top bevel
|
||||
@@ -276,15 +282,21 @@ module frame_box() {
|
||||
];
|
||||
hull() {
|
||||
for (p = top_points) {
|
||||
translate(p) cylinder(r=2, h=frame_bevel_height, center=true);
|
||||
translate(p) cylinder(r=2, h=frame_bevel_height, center=true, $fn=4);
|
||||
}
|
||||
for (p = base_points) {
|
||||
translate(p) cylinder(r=2, h=frame_z-(frame_bevel_height*2), center=true);
|
||||
translate(p) cylinder(r=2, h=frame_z-(frame_bevel_height*2), center=true, $fn=4);
|
||||
}
|
||||
for (p = bottom_points) {
|
||||
translate(p) cylinder(r=2, h=frame_bevel_height, center=true);
|
||||
translate(p) cylinder(r=2, h=frame_bevel_height, center=true, $fn=4);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module frame_box() {
|
||||
difference() {
|
||||
frame_solid();
|
||||
// cut out the middle to make it a box
|
||||
cube([panel_x-(panel_support_width*2), panel_y-(panel_support_width*2), frame_z+5], center=true);
|
||||
}
|
||||
@@ -294,7 +306,11 @@ module frame_mount_column() {
|
||||
cube([frame_mount_column_width, frame_mount_column_width, frame_z], center=true);
|
||||
// add some corners back to do a lame chamfer
|
||||
linear_extrude(height=frame_z, center=true)
|
||||
polygon([[10, 10], [-20, 10], [10, -20]]);
|
||||
polygon([
|
||||
[frame_mount_column_width/2, frame_mount_column_width/2],
|
||||
[-frame_mount_column_width, frame_mount_column_width/2],
|
||||
[frame_mount_column_width/2, -frame_mount_column_width]
|
||||
]);
|
||||
}
|
||||
|
||||
module side_chopper() {
|
||||
@@ -315,7 +331,8 @@ module frame_connection_holes() {
|
||||
}
|
||||
|
||||
module frame_cable_routing_hole() {
|
||||
translate([frame_x/2, 0, 0]) rotate([0, 90, 0]) frame_interchange_hole();
|
||||
// frame_y/12 is a hack for "kinda a bit above the center point"
|
||||
translate([frame_x/2, frame_y/12+1, 25]) rotate([0, 90, 0]) frame_interchange_hole();
|
||||
}
|
||||
|
||||
module base_frame() {
|
||||
@@ -330,7 +347,7 @@ module frame() {
|
||||
difference() {
|
||||
base_frame();
|
||||
translate([0, 0, frame_z/2]) scale([1, 1, 2]) base_panel();
|
||||
translate([0, 0, -frame_z/2]) scale([1, 1, 2]) bottom_panel();
|
||||
translate([0, 0, -frame_z/2]) scale([1, 1, 2]) base_panel();;
|
||||
translate([panel_to_frame_point_x, panel_to_frame_point_y, 0]) frame_hex_bolt_hole();
|
||||
translate([-panel_to_frame_point_x, panel_to_frame_point_y, 0]) frame_hex_bolt_hole();
|
||||
translate([panel_to_frame_point_x, -panel_to_frame_point_y, 0]) frame_hex_bolt_hole();
|
||||
@@ -338,6 +355,22 @@ module frame() {
|
||||
}
|
||||
}
|
||||
|
||||
/* MISC SHAPES --- for cutting out decorative panels, frame wall windows, etc. */
|
||||
|
||||
// for cutting out slashes from the frame outer wall
|
||||
module slash_cutout() {
|
||||
polyhedron([
|
||||
[slash_inner_displacement/2, -wall_cutout_depth, -slash_height/2],
|
||||
[(slash_inner_displacement/2+slash_width), -wall_cutout_depth, -slash_height/2],
|
||||
[(slash_inner_displacement/2+slash_width), wall_cutout_depth, -slash_height/2],
|
||||
[slash_inner_displacement/2, wall_cutout_depth, -slash_height/2],
|
||||
[-(slash_inner_displacement/2+slash_width), -wall_cutout_depth, slash_height/2],
|
||||
[-slash_inner_displacement/2, -wall_cutout_depth, slash_height/2],
|
||||
[-slash_inner_displacement/2, wall_cutout_depth, slash_height/2],
|
||||
[-(slash_inner_displacement/2+slash_width), wall_cutout_depth, slash_height/2]
|
||||
], [[0, 1, 2, 3], [4, 5, 1, 0], [7, 6, 5, 4], [5, 6, 2, 1], [6, 7, 3, 2], [7, 4, 0, 3]]);
|
||||
}
|
||||
|
||||
/* LAYOUTS */
|
||||
|
||||
// Directional Arc (both hands)
|
||||
@@ -381,24 +414,40 @@ module dir_arc_plus_w_24mm_8_button() {
|
||||
|
||||
module dir_arc_30mm_thumb_button() {
|
||||
// just my guesstimate on this one, but note that this is the same position as sega 2p (just mirrored)
|
||||
translate([(panel_x/2)-28.06, (-panel_y/2)+62, 0]) button_30mm_hole();
|
||||
translate([(panel_x/2)-sega_2p_column_1_left_panel_edge_offset, (-panel_y/2)+62, 0]) button_30mm_hole();
|
||||
}
|
||||
|
||||
module dir_arc_30mm_fingers_left_button() {
|
||||
translate([-dir_arc_30mm_column_3_offset, dir_arc_30mm_row_3_offset, 0]) dir_arc_30mm_thumb_button();
|
||||
}
|
||||
|
||||
module dir_arc_30mm_fingers_middle_button() {
|
||||
translate([-dir_arc_30mm_column_2_offset, dir_arc_30mm_row_3_offset, 0]) dir_arc_30mm_thumb_button();
|
||||
}
|
||||
|
||||
module dir_arc_30mm_fingers_right_button() {
|
||||
translate([0, dir_arc_30mm_row_2_offset, 0]) dir_arc_30mm_thumb_button();
|
||||
}
|
||||
|
||||
module dir_arc_30mm_finger_buttons() {
|
||||
translate([0, 57.2, 0]) dir_arc_30mm_thumb_button();
|
||||
translate([-33.8, 57.2+12.9, 0]) dir_arc_30mm_thumb_button();
|
||||
translate([-33.8-34.8, 57.2+12.9, 0]) dir_arc_30mm_thumb_button();
|
||||
dir_arc_30mm_fingers_left_button();
|
||||
dir_arc_30mm_fingers_middle_button();
|
||||
dir_arc_30mm_fingers_right_button();
|
||||
}
|
||||
|
||||
module dir_arc_30mm_w_button() {
|
||||
translate([-26.8, dir_arc_w_30mm_row_4_offset, 0]) dir_arc_30mm_thumb_button();
|
||||
}
|
||||
|
||||
module dir_arc_w_30mm() {
|
||||
dir_arc_30mm_thumb_button();
|
||||
dir_arc_30mm_finger_buttons();
|
||||
translate([-26.8, 57.2+12.9+34.5, 0]) dir_arc_30mm_thumb_button();
|
||||
dir_arc_30mm_w_button();
|
||||
}
|
||||
|
||||
module dir_arc_w_30mm_plus_one() {
|
||||
dir_arc_w_30mm();
|
||||
translate([-33.8-34.8-33.8, 57.2, 0]) dir_arc_30mm_thumb_button();
|
||||
translate([-dir_arc_30mm_column_3_offset-33.8, dir_arc_30mm_row_2_offset, 0]) dir_arc_30mm_thumb_button();
|
||||
}
|
||||
|
||||
// Namco Noir (right hand)
|
||||
@@ -425,27 +474,127 @@ module noir_plus_one() {
|
||||
// Sega Astro City 2P (right hand)
|
||||
|
||||
module sega_2p_p1() {
|
||||
translate([-panel_x/2, -panel_y/2, 0]) translate([28.06, 140, 0]) button_30mm_hole();
|
||||
translate([-panel_x/2, -panel_y/2, 0]) translate([sega_2p_column_1_left_panel_edge_offset, 140, 0])
|
||||
button_30mm_hole();
|
||||
}
|
||||
|
||||
module sega_2p_6_button() {
|
||||
// via slagcoin
|
||||
sega_2p_p1();
|
||||
translate([30.5, 11+9, 0]) sega_2p_p1();
|
||||
translate([30.5+36, 11+9, 0]) sega_2p_p1();
|
||||
translate([sega_2p_column_2_offset, 11+9, 0]) sega_2p_p1();
|
||||
translate([sega_2p_column_3_offset, 11+9, 0]) sega_2p_p1();
|
||||
translate([0, -19-9-11, 0]) sega_2p_p1();
|
||||
translate([30.5, -19, 0]) sega_2p_p1();
|
||||
translate([30.5+36, -19, 0]) sega_2p_p1();
|
||||
translate([sega_2p_column_2_offset, -19, 0]) sega_2p_p1();
|
||||
translate([sega_2p_column_3_offset, -19, 0]) sega_2p_p1();
|
||||
}
|
||||
|
||||
module sega_2p() {
|
||||
sega_2p_6_button();
|
||||
translate([30.5+36+36, 11, 0]) sega_2p_p1();
|
||||
translate([30.5+36+36, -19-9, 0]) sega_2p_p1();
|
||||
translate([sega_2p_column_4_offset, 11, 0]) sega_2p_p1();
|
||||
translate([sega_2p_column_4_offset, -19-9, 0]) sega_2p_p1();
|
||||
}
|
||||
|
||||
module sega_2p_plus_one() {
|
||||
sega_2p();
|
||||
module sega_2p_nine_thumb_button() {
|
||||
// just my guesstimate on this one
|
||||
translate([0, -19-9-11-19-9-11, 0]) sega_2p_p1();
|
||||
}
|
||||
|
||||
module sega_2p_nine() {
|
||||
sega_2p();
|
||||
sega_2p_nine_thumb_button();
|
||||
}
|
||||
|
||||
module sega_2p_eleven() {
|
||||
sega_2p_nine();
|
||||
translate([sega_2p_column_5_offset, 0, 0]) sega_2p_p1();
|
||||
translate([sega_2p_column_5_offset, -19-9-11, 0]) sega_2p_p1();
|
||||
}
|
||||
|
||||
// BSS ERGO - 30mm
|
||||
|
||||
module wasd_30mm() {
|
||||
button_30mm_hole(); // W
|
||||
translate([0, -36, 0]) button_30mm_hole(); // S
|
||||
translate([-34.5, -36-9, 0]) button_30mm_hole(); // A
|
||||
translate([34.5, -36-9, 0]) button_30mm_hole(); // D
|
||||
}
|
||||
|
||||
module wasd_six_30mm() {
|
||||
wasd_30mm();
|
||||
translate([-34.5, -9, 0]) button_30mm_hole(); // left of W
|
||||
translate([34.5, -9, 0]) button_30mm_hole(); // right of W
|
||||
}
|
||||
|
||||
module wasd_eight_30mm() {
|
||||
wasd_six_30mm();
|
||||
translate([34.5*1.9, -9*3, 0]) button_30mm_hole(); // top right of right of W
|
||||
translate([34.5*1.9, -36-9*3, 0]) button_30mm_hole(); // right of D
|
||||
}
|
||||
|
||||
module ergo_wasd_five_30mm() {
|
||||
translate([-51.75, 65.5, 0]) rotate([0, 0, 10]) {
|
||||
wasd_30mm();
|
||||
}
|
||||
translate([0, 0, 0]) sega_2p_nine_thumb_button();
|
||||
}
|
||||
|
||||
module ergo_wasd_seven_30mm() {
|
||||
translate([-51.75, 65.5, 0]) rotate([0, 0, 10]) {
|
||||
wasd_six_30mm();
|
||||
}
|
||||
translate([0, 0, 0]) sega_2p_nine_thumb_button();
|
||||
}
|
||||
|
||||
module ergo_eight_30mm() {
|
||||
translate([-51.75, 65.5, 0]) rotate([0, 0, 10]) {
|
||||
wasd_eight_30mm();
|
||||
}
|
||||
}
|
||||
|
||||
module ergo_nine_30mm() {
|
||||
ergo_eight_30mm();
|
||||
translate([0, 0, 0]) sega_2p_nine_thumb_button();
|
||||
}
|
||||
|
||||
// BSS ERGO - 24mm
|
||||
module wasd_24mm() {
|
||||
button_24mm_hole(); // W
|
||||
translate([0, -27, 0]) button_24mm_hole(); // S
|
||||
translate([-26, -27-7, 0]) button_24mm_hole(); // A
|
||||
translate([26, -27-7, 0]) button_24mm_hole(); // D
|
||||
}
|
||||
|
||||
module wasd_six_24mm() {
|
||||
wasd_24mm();
|
||||
translate([-26, -7, 0]) button_24mm_hole(); // left of W
|
||||
translate([26, -7, 0]) button_24mm_hole(); // right of W
|
||||
}
|
||||
|
||||
module wasd_eight_24mm() {
|
||||
wasd_six_24mm();
|
||||
translate([26*2-2, -7*3, 0]) button_24mm_hole(); // top right of right of W
|
||||
translate([26*2-2, -27-7*3, 0]) button_24mm_hole(); // top right of right of W
|
||||
}
|
||||
|
||||
module ergo_wasd_five_24mm() {
|
||||
translate([-63.25, 65.5, 0]) rotate([0, 0, 10]) {
|
||||
wasd_24mm();
|
||||
}
|
||||
translate([0, 0, 0]) sega_2p_nine_thumb_button();
|
||||
}
|
||||
|
||||
module ergo_eight_24mm() {
|
||||
translate([-63.25, 65.5, 0]) rotate([0, 0, 10]) {
|
||||
wasd_eight_24mm();
|
||||
}
|
||||
}
|
||||
|
||||
module ergo_nine_24mm() {
|
||||
ergo_eight_24mm();
|
||||
translate([0, 0, 0]) sega_2p_nine_thumb_button();
|
||||
}
|
||||
|
||||
module shiokenstar() {
|
||||
translate([-172, 32, 0]) dir_arc_24mm_directionals();
|
||||
sega_2p();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
# BSS Arcade Edition
|
||||
|
||||
Pieces for mounting to a Qanba 2009 in order to create the Buildable Stick System - Arcade Edition.
|
||||
|
||||
## Pieces
|
||||
|
||||
* 4 `interconnect-x` --- creating the internal support for joining two rows of panels
|
||||
* 6 `frames/pieces/interconnect` --- (core project) the standard piece for joining two+ columns of panels
|
||||
* 4 `extended-side-no-back` --- the extended side pieces, flush on the back to connect to each other
|
||||
* 4 `frames/pieces/extended/front-or-back` --- (core project) the front extended piece
|
||||
* 2 `extended-back` --- a small piece that fits into the Qanba 2009 "lip" for running cables
|
||||
* 1 `extended-back-left-mount`
|
||||
* 1 `extended-back-right-mount` --- extended back pieces that can be mounted to the Qanba 2009 base
|
||||
* 1 `panel-front-left-mount`
|
||||
* 1 `panel-front-right-mount` --- blank panels that can be mounted to the Qanba 2009 base
|
||||
* 6 `panels/inset/panel` --- the rest of the bottom panels
|
||||
* 4 `panels/inset/` panels of your choice for the front controls
|
||||
* 2 `panel-three-aux-buttons` --- for aux controls in the back row
|
||||
* 2 `panel-three-aux-buttons-and-rocker-hole` --- for aux controls and the wired rocker in the back row
|
||||
* 4 `decorative-plate-aux-control-tight-three-button-cluster` --- for decorating the aux control clusters
|
||||
* 4 `src/misc/` decorative plates of your choice for the front controls, and similar miscellany
|
||||
* 4 `mount-spacer` --- making a flush mount between the enclosure and the base
|
||||
|
||||
## Hardware
|
||||
|
||||
* 32 45mm M4 hex brass standoffs (or equivalent) for each panel/frame compartment
|
||||
* 64 8-12mm M4 countersunk hex bolts for attaching panels to the compartments
|
||||
* 4 8-12mm M3 hex bolts and 4 M3 flange nuts for attaching rocker switches to the back panels
|
||||
* 4 40mm M6 bolts for connecting the enclosure to the base
|
||||
* 4 M6 flange nuts
|
||||
|
||||
## Components
|
||||
|
||||
* 2 controller boards, e.g. the RP2040 Advanced Breakout Board
|
||||
* buttons and/or levers as desired
|
||||
* necessary wiring
|
||||
|
||||
For the rest of the build (e.g. mounting a level to a panel), see the core README.
|
||||
@@ -0,0 +1,25 @@
|
||||
/* Decorative plate for aux buttons.
|
||||
*
|
||||
* SPDX-FileCopyrightText: © 2024 Brian S. Stephan <bss@incorporeal.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
include <parameters.scad>
|
||||
decorative_radius_scale = 1.5;
|
||||
include <components.scad>
|
||||
|
||||
module aux_control_three_button_tight_cluster_decorative_plate() {
|
||||
difference() {
|
||||
hull() difference() {
|
||||
// get a 2mm slice of the decorative button cylinders
|
||||
translate([0, 0, -50]) aux_control_three_button_tight_cluster();
|
||||
// keep a thin slice
|
||||
translate([0, 0, -100]) cube([500, 500, 198], center=true);
|
||||
translate([0, 0, 100]) cube([500, 500, 198], center=true);
|
||||
}
|
||||
// cut out the normal holes
|
||||
translate([0, 0, -1]) aux_control_three_button_tight_cluster();
|
||||
}
|
||||
}
|
||||
|
||||
aux_control_three_button_tight_cluster_decorative_plate();
|
||||
@@ -0,0 +1,26 @@
|
||||
/* A back piece of the enclosure, with a mounting hole.
|
||||
*
|
||||
* SPDX-FileCopyrightText: © 2024 Brian S. Stephan <bss@incorporeal.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
include <parameters.scad>
|
||||
include <components.scad>
|
||||
use <extended-back.scad>
|
||||
|
||||
// X: inner post to post (inclusive) is approx. 428.625mm, so half that, minus half the post itself
|
||||
// (41.28mm) is how much in from a normal panel to put the M6 mounting hole
|
||||
// Y: eyeballed it to 30mm
|
||||
mount_hole_x = (panel_x / 2) - (panel_x - ((428.625 / 2) - (41.28 / 2)));
|
||||
mount_hole_y = (panel_y / 2) + 30;
|
||||
|
||||
module left_mount_extended_back() {
|
||||
difference() {
|
||||
extended_back();
|
||||
translate([mount_hole_x, -mount_hole_y, -30]) m6_hole();
|
||||
// punch out the back for cables
|
||||
cube([frame_x-70, frame_y+160, frame_z-20], center=true);
|
||||
}
|
||||
}
|
||||
|
||||
left_mount_extended_back();
|
||||
@@ -0,0 +1,15 @@
|
||||
/* A back piece of the enclosure, with a mounting hole.
|
||||
*
|
||||
* SPDX-FileCopyrightText: © 2024 Brian S. Stephan <bss@incorporeal.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
include <parameters.scad>
|
||||
include <components.scad>
|
||||
use <extended-back-left-mount.scad>
|
||||
|
||||
module right_mount_extended_back() {
|
||||
mirror([1, 0, 0]) left_mount_extended_back();
|
||||
}
|
||||
|
||||
right_mount_extended_back();
|
||||
@@ -0,0 +1,30 @@
|
||||
/* A back piece extended the rest of the depth of the base.
|
||||
*
|
||||
* SPDX-FileCopyrightText: © 2024 Brian S. Stephan <bss@incorporeal.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
include <parameters.scad>
|
||||
include <components.scad>
|
||||
use <frames/pieces/front-or-back-trapezoid.scad>
|
||||
|
||||
module back_piece_extension() {
|
||||
// combine the original wall with a copy to "pull" the wall out
|
||||
hull() {
|
||||
linear_extrude(height=80) bottom_piece_wall();
|
||||
linear_extrude(height=(frame_wall-frame_bevel_height)) bottom_piece_wall();
|
||||
}
|
||||
}
|
||||
|
||||
module extended_back() {
|
||||
difference() {
|
||||
union() {
|
||||
clean_front_or_back();
|
||||
translate([0, -frame_y/2+frame_wall, 0]) rotate([90, 0, 0]) back_piece_extension();
|
||||
}
|
||||
cube([frame_x-60, frame_y+160-10, frame_z-10], center=true);
|
||||
translate([0, -frame_y/2-35, 0]) cube([frame_x-20, 70, frame_z-10], center=true);
|
||||
}
|
||||
}
|
||||
|
||||
extended_back();
|
||||
@@ -0,0 +1,60 @@
|
||||
/* Create an extended side that is flush on the back to lay against another side.
|
||||
*
|
||||
* SPDX-FileCopyrightText: © 2024 Brian S. Stephan <bss@incorporeal.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
include <parameters.scad>
|
||||
include <components.scad>
|
||||
use <frames/complete/left-frame.scad>
|
||||
use <frames/pieces/side.scad>
|
||||
use <frames/pieces/front-or-back-trapezoid.scad>
|
||||
|
||||
module side_frame_piece_wall() {
|
||||
// this doesn't use the side_frame_piece because of the 45 degree angle geometry
|
||||
// not creating a clean thing to cut, so we just take the whole wall and use that
|
||||
projection(cut=true) rotate([0, 90, 0]) translate([frame_x/2-frame_wall-(frame_bevel_height/2), 0, 0])
|
||||
left_frame();
|
||||
}
|
||||
|
||||
module side_and_bottom_frame_piece_wall() {
|
||||
// get a slice of the pieces, to use it in extruding
|
||||
// this doesn't use the side_frame_piece because of the 45 degree angle geometry
|
||||
// not creating a clean thing to cut, so we just take the whole wall and use that
|
||||
side_frame_piece_wall();
|
||||
projection(cut=true) translate([0, -frame_y/2+frame_wall, 0]) rotate([90, 90, 0]) bottom_piece_extension();
|
||||
}
|
||||
|
||||
module side_and_bottom_frame_piece_extension() {
|
||||
// combine the original with a shrunken piece to "pull" the wall out
|
||||
hull() {
|
||||
linear_extrude(height=frame_extension_y) scale([0.5, 0.90, 1]) side_and_bottom_frame_piece_wall();
|
||||
linear_extrude(height=frame_extension_y) scale([0.5, 1, 1])
|
||||
difference() {
|
||||
side_frame_piece_wall();
|
||||
// remove the front piece so it doesn't interfere with the front extend
|
||||
translate([0, -frame_y/2, 0]) square([frame_x, frame_y], center=true);
|
||||
}
|
||||
linear_extrude(height=frame_bevel_height) side_and_bottom_frame_piece_wall();
|
||||
}
|
||||
}
|
||||
|
||||
module extra_extended_left_or_right_frame_piece() {
|
||||
difference() {
|
||||
union() {
|
||||
difference() {
|
||||
side_frame_piece();
|
||||
// chop off the old edge which is getting replaced with the extension
|
||||
translate([-frame_x/2+frame_bevel_height/2, 0, 0])
|
||||
cube([frame_bevel_height, frame_y, frame_z], center=true);
|
||||
}
|
||||
translate([-frame_x/2+frame_bevel_height*2, 0, 0])
|
||||
rotate([0, -90, 0]) side_and_bottom_frame_piece_extension();
|
||||
}
|
||||
// minus the back piece where the wall would be, since there is no wall and the pieces and panels
|
||||
// go flush against one another
|
||||
translate([0, frame_y/2-(frame_wall/2), 0]) cube([frame_x*2, frame_wall, frame_z], center=true);
|
||||
}
|
||||
}
|
||||
|
||||
extra_extended_left_or_right_frame_piece();
|
||||
@@ -0,0 +1,30 @@
|
||||
/* Interconnect frames along the x-axis (the longer side)
|
||||
*
|
||||
* SPDX-FileCopyrightText: © 2024 Brian S. Stephan <bss@incorporeal.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
include <parameters.scad>
|
||||
include <components.scad>
|
||||
use <frames/pieces/front-or-back.scad>
|
||||
|
||||
module interconnect_frame_half_piece() {
|
||||
translate([0, frame_y/2-frame_wall, 0]) difference() {
|
||||
clean_edge_front_or_back_frame_piece();
|
||||
translate([0, (-frame_y+frame_wall)/2-panel_overhang_amount, 0])
|
||||
cube([overhang_panel_x, frame_wall+panel_overhang_amount*2, frame_z], center=true);
|
||||
}
|
||||
}
|
||||
|
||||
module interconnect_frame_piece() {
|
||||
difference() {
|
||||
union() {
|
||||
// slight translate is to make this a 2-manifold in OpenSCAD
|
||||
translate([0, -0.01, 0]) interconnect_frame_half_piece();
|
||||
mirror([0, 1, 0]) interconnect_frame_half_piece();
|
||||
}
|
||||
rotate([0, 0, 90]) translate([-frame_y/2, 0, 0]) frame_cable_routing_hole();
|
||||
}
|
||||
}
|
||||
|
||||
interconnect_frame_piece();
|
||||
@@ -0,0 +1,17 @@
|
||||
/* Just a simple washer to go between the frame post and the arcade enclosure.
|
||||
*
|
||||
* SPDX-FileCopyrightText: © 2024 Brian S. Stephan <bss@incorporeal.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
include <parameters.scad>
|
||||
include <components.scad>
|
||||
|
||||
module mount_spacer() {
|
||||
difference() {
|
||||
cylinder(r=25, h=1.25, $fn=50, center=true);
|
||||
m6_hole();
|
||||
}
|
||||
}
|
||||
|
||||
mount_spacer();
|
||||
@@ -0,0 +1,24 @@
|
||||
/* A panel with a mount point for the front left of the enclosure.
|
||||
*
|
||||
* SPDX-FileCopyrightText: © 2024 Brian S. Stephan <bss@incorporeal.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
include <parameters.scad>
|
||||
include <components.scad>
|
||||
use <panels/inset/panel.scad>
|
||||
|
||||
// X: inner post to post (inclusive) is approx. 428.625mm, so half that, minus half the post itself
|
||||
// (41.28mm) is how much in from a normal panel to put the M6 mounting hole
|
||||
// Y: eyeballed it to 2": 50.80mm
|
||||
mount_hole_x = (panel_x / 2) - (panel_x - ((428.625 / 2) - (41.28 / 2)));
|
||||
mount_hole_y = (panel_y / 2) - 50.80;
|
||||
|
||||
module front_left_mount_panel() {
|
||||
difference() {
|
||||
panel();
|
||||
translate([-mount_hole_x, -mount_hole_y, 0]) m6_hole();
|
||||
}
|
||||
}
|
||||
|
||||
front_left_mount_panel();
|
||||
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: © 2024 Brian S. Stephan <bss@incorporeal.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
include <parameters.scad>
|
||||
include <components.scad>
|
||||
use <panel-front-left-mount.scad>
|
||||
|
||||
module front_right_mount_panel() {
|
||||
mirror([1, 0, 0]) front_left_mount_panel();
|
||||
}
|
||||
|
||||
front_right_mount_panel();
|
||||
@@ -0,0 +1,18 @@
|
||||
/* A panel for mounting a couple aux buttons in a out of the way spot.
|
||||
*
|
||||
* SPDX-FileCopyrightText: © 2024 Brian S. Stephan <bss@incorporeal.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
include <parameters.scad>
|
||||
include <components.scad>
|
||||
|
||||
module three_aux_button_and_20mm_panel() {
|
||||
difference() {
|
||||
panel();
|
||||
translate([0, -70, 0]) aux_control_three_button_tight_cluster();
|
||||
translate([0, frame_y/2-30, 0]) rotate([180, 0, 0]) neutrik_d_mount();
|
||||
}
|
||||
}
|
||||
|
||||
three_aux_button_and_20mm_panel();
|
||||
@@ -0,0 +1,17 @@
|
||||
/* A panel for mounting a couple aux buttons in a out of the way spot.
|
||||
*
|
||||
* SPDX-FileCopyrightText: © 2024 Brian S. Stephan <bss@incorporeal.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
include <parameters.scad>
|
||||
include <components.scad>
|
||||
|
||||
module three_aux_button_panel() {
|
||||
difference() {
|
||||
panel();
|
||||
translate([0, -70, 0]) aux_control_three_button_tight_cluster();
|
||||
}
|
||||
}
|
||||
|
||||
three_aux_button_panel();
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: © 2024 Brian S. Stephan <bss@incorporeal.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
include <../parameters.scad>
|
||||
include <../components.scad>
|
||||
use <stand.scad>
|
||||
|
||||
module stand_base() {
|
||||
difference() {
|
||||
cube([frame_x, stand_y*2, 3], center=true);
|
||||
translate([0, 0, 1.5]) rotate([180, 0, 0]) stand();
|
||||
translate([-frame_x*0.4, 0, 1.5]) rotate([180, 0, 0]) stand();
|
||||
translate([frame_x*0.4, 0, 1.5]) rotate([180, 0, 0]) stand();
|
||||
}
|
||||
}
|
||||
|
||||
stand_base();
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: © 2024 Brian S. Stephan <bss@incorporeal.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
include <../parameters.scad>
|
||||
include <../components.scad>
|
||||
|
||||
base_extra = 10;
|
||||
back_extra_multiplier = 4.25;
|
||||
rotation_alignment = 15;
|
||||
|
||||
module stand() {
|
||||
difference() {
|
||||
union() {
|
||||
/* front lip piece */
|
||||
translate([0, 0, stand_z/2]) cube([stand_x, stand_y, stand_z], center=true);
|
||||
/* back supporting piece */
|
||||
translate([0, (stand_y-rotation_alignment)/4, stand_z*back_extra_multiplier/2])
|
||||
cube([stand_x, (stand_y+rotation_alignment)/2, stand_z*back_extra_multiplier], center=true);
|
||||
/* base */
|
||||
translate([0, 0, 0.5]) cube([stand_x+base_extra, stand_y+base_extra, 1], center=true);
|
||||
}
|
||||
/* cut out the actual frame solid */
|
||||
translate([0, rotation_alignment, (frame_y/2)+7]) rotate([65, 0, 0]) frame_solid();
|
||||
}
|
||||
}
|
||||
|
||||
stand();
|
||||
@@ -1,29 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: © 2024 Brian S. Stephan <bss@incorporeal.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
include <parameters.scad>
|
||||
include <components.scad>
|
||||
use <frame-piece-bottom-left-or-right.scad>
|
||||
|
||||
module bottom_piece_wall() {
|
||||
// get a slice of the piece, to use it in extruding
|
||||
projection(cut=true) rotate([-90, 0, 0]) translate([0, frame_y/2-frame_bevel_height, 0])
|
||||
bottom_left_or_right_frame_piece();
|
||||
}
|
||||
|
||||
module bottom_piece_extension() {
|
||||
// combine the original with a shrunken piece to "pull" the wall out
|
||||
hull() {
|
||||
linear_extrude(height=frame_extension_y) scale([1, 0.5, 1]) bottom_piece_wall();
|
||||
linear_extrude(height=frame_bevel_height) bottom_piece_wall();
|
||||
}
|
||||
}
|
||||
|
||||
module extended_bottom_left_or_right_frame_piece() {
|
||||
bottom_left_or_right_frame_piece();
|
||||
translate([0, -frame_y/2+frame_bevel_height*2, 0]) rotate([90, 0, 0]) bottom_piece_extension();
|
||||
}
|
||||
|
||||
extended_bottom_left_or_right_frame_piece();
|
||||
@@ -1,26 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: © 2024 Brian S. Stephan <bss@incorporeal.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
include <parameters.scad>
|
||||
include <components.scad>
|
||||
use <frame-left.scad>
|
||||
|
||||
module bottom_left_or_right_frame_piece() {
|
||||
piece_width = panel_support_width+frame_wall+frame_mount_column_width;
|
||||
intersection() {
|
||||
left_frame();
|
||||
difference() {
|
||||
// include the whole bottom wall (including mount columns)
|
||||
translate([0, -(frame_y/2)+(piece_width/2), 0]) cube([frame_x, piece_width, frame_z], center=true);
|
||||
// ...minus the frame wall and lip on the left
|
||||
translate([-frame_x/2+frame_wall/2, 0, 0])
|
||||
cube([frame_wall, frame_y, frame_z], center=true);
|
||||
// ...minus a slot for the combining piece to go into
|
||||
cube([frame_x, frame_y-(panel_support_width+frame_wall)*2, frame_z/4], center=true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bottom_left_or_right_frame_piece();
|
||||
@@ -1,24 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: © 2024 Brian S. Stephan <bss@incorporeal.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
include <parameters.scad>
|
||||
include <components.scad>
|
||||
use <frame-piece-top-left-or-right.scad>
|
||||
use <frame-piece-bottom-left-or-right.scad>
|
||||
|
||||
module side_frame_piece() {
|
||||
piece_width = panel_support_width+frame_wall+frame_mount_column_width;
|
||||
difference() {
|
||||
// side piece is left/right agnostic
|
||||
frame();
|
||||
// minus the top and bottom
|
||||
top_left_or_right_frame_piece();
|
||||
bottom_left_or_right_frame_piece();
|
||||
// and just chop out the rest of the frame
|
||||
translate([piece_width, 0, 0]) cube([frame_x, frame_y+1, frame_z+1], center=true);
|
||||
}
|
||||
}
|
||||
|
||||
side_frame_piece();
|
||||
@@ -1,26 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: © 2024 Brian S. Stephan <bss@incorporeal.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
include <parameters.scad>
|
||||
include <components.scad>
|
||||
use <frame-left.scad>
|
||||
|
||||
module top_left_or_right_frame_piece() {
|
||||
piece_width = panel_support_width+frame_wall+frame_mount_column_width;
|
||||
intersection() {
|
||||
left_frame();
|
||||
difference() {
|
||||
// include the whole top wall (including mount columns)
|
||||
translate([0, (frame_y/2)-(piece_width/2), 0]) cube([frame_x, piece_width, frame_z], center=true);
|
||||
// ...minus the frame wall and lip on the left
|
||||
translate([-frame_x/2+frame_wall/2, 0, 0])
|
||||
cube([frame_wall, frame_y, frame_z], center=true);
|
||||
// ...minus a slot for the combining piece to go into
|
||||
cube([frame_x, frame_y-(panel_support_width+frame_wall)*2, frame_z/4], center=true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
top_left_or_right_frame_piece();
|
||||
@@ -24,9 +24,9 @@ module left_frame() {
|
||||
frame_cable_routing_hole();
|
||||
|
||||
// aux button holes
|
||||
translate([-35, 101.5, 0]) rotate([270, 0, 0]) aux_control_three_button_cluster();
|
||||
translate([-35, (frame_y/2)-neutrik_panel_thickness-4, 0]) frame_cutout();
|
||||
translate([-72, (frame_y/2)-neutrik_panel_thickness-4, 0]) frame_cutout();
|
||||
translate([-35.25, 101.5, 0]) rotate([270, 0, 0]) aux_control_three_button_cluster();
|
||||
translate([-35.25, (frame_y/2)-neutrik_panel_thickness-4, 0]) frame_cutout();
|
||||
translate([-72.25, (frame_y/2)-neutrik_panel_thickness-4, 0]) frame_cutout();
|
||||
translate([2, (frame_y/2)-neutrik_panel_thickness-4, 0]) frame_cutout();
|
||||
|
||||
// neutrix button hole
|
||||
@@ -24,9 +24,9 @@ module right_frame() {
|
||||
mirror([1, 0, 0]) frame_cable_routing_hole();
|
||||
|
||||
// aux button holes
|
||||
translate([35, 101.5, 0]) rotate([270, 0, 0]) aux_control_three_button_cluster();
|
||||
translate([35, (frame_y/2)-neutrik_panel_thickness-4, 0]) frame_cutout();
|
||||
translate([72, (frame_y/2)-neutrik_panel_thickness-4, 0]) frame_cutout();
|
||||
translate([35.25, 101.5, 0]) rotate([270, 0, 0]) aux_control_three_button_cluster();
|
||||
translate([35.25, (frame_y/2)-neutrik_panel_thickness-4, 0]) frame_cutout();
|
||||
translate([72.25, (frame_y/2)-neutrik_panel_thickness-4, 0]) frame_cutout();
|
||||
translate([-2, (frame_y/2)-neutrik_panel_thickness-4, 0]) frame_cutout();
|
||||
|
||||
// neutrix button hole
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: © 2024 Brian S. Stephan <bss@incorporeal.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
include <parameters.scad>
|
||||
include <components.scad>
|
||||
use <front-or-back.scad>
|
||||
|
||||
module front_or_back_aux_and_neutrik_frame_piece() {
|
||||
difference() {
|
||||
clean_edge_front_or_back_frame_piece();
|
||||
|
||||
// aux button holes
|
||||
translate([-35.25, -101.5, 0]) rotate([90, 0, 0]) aux_control_three_button_cluster();
|
||||
translate([-35.25, -(frame_y/2)+neutrik_panel_thickness+4, 0]) frame_cutout();
|
||||
translate([-72.25, -(frame_y/2)+neutrik_panel_thickness+4, 0]) frame_cutout();
|
||||
translate([2, -(frame_y/2)+neutrik_panel_thickness+4, 0]) frame_cutout();
|
||||
|
||||
// neutrix button hole
|
||||
translate([frame_center_to_neutrik, -(frame_y/2)+neutrik_panel_thickness, 0])
|
||||
rotate([270, 0, 0]) neutrik_d_mount();
|
||||
translate([frame_center_to_neutrik, -(frame_y/2)+neutrik_panel_thickness+4, 0])
|
||||
frame_cutout();
|
||||
}
|
||||
}
|
||||
|
||||
front_or_back_aux_and_neutrik_frame_piece();
|
||||
@@ -0,0 +1,31 @@
|
||||
/* The inner top/bottom wall of the frame, for being displayed through a horizontal stripe windowed part.
|
||||
*
|
||||
* SPDX-FileCopyrightText: © 2025 Brian S. Stephan <bss@incorporeal.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
include <parameters.scad>
|
||||
include <components.scad>
|
||||
use <front-or-back-inner-wall.scad>
|
||||
use <front-or-back-windowed-horiz-stripes.scad>
|
||||
|
||||
// for stability's sake, this piece juts out a bit from the outside of the wall, so we
|
||||
// need to hack the window piece a bit to subtract from the longer and get ours longer
|
||||
module horiz_striped_windowed_front_or_back_frame_piece() {
|
||||
difference() {
|
||||
front_or_back_longish_frame_piece();
|
||||
// subtract frame wall windows
|
||||
front_horiz_stripes();
|
||||
// subtract the inner wall area that will be provided by the other piece
|
||||
front_or_back_inner_wall_frame_piece();
|
||||
}
|
||||
}
|
||||
|
||||
module front_or_back_windowed_horiz_stripes_inner_wall_frame_piece() {
|
||||
difference() {
|
||||
front_or_back_longish_frame_piece();
|
||||
horiz_striped_windowed_front_or_back_frame_piece();
|
||||
}
|
||||
}
|
||||
|
||||
front_or_back_windowed_horiz_stripes_inner_wall_frame_piece();
|
||||
@@ -0,0 +1,65 @@
|
||||
/* The inner top/bottom wall of the frame, for being displayed through a windowed part.
|
||||
*
|
||||
* SPDX-FileCopyrightText: © 2024 Brian S. Stephan <bss@incorporeal.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
include <parameters.scad>
|
||||
include <components.scad>
|
||||
use <front-or-back.scad>
|
||||
|
||||
module mount_column_cutout() {
|
||||
intersection() {
|
||||
frame_mount_column();
|
||||
cube([frame_mount_column_width*3/2, frame_mount_column_width*3/2, inner_frame_z*5/8], center=true);
|
||||
}
|
||||
}
|
||||
|
||||
module front_or_back_inner_wall_frame_base_piece() {
|
||||
difference() {
|
||||
// Z is scaled so that some part of the original part inner wall is retained
|
||||
scale([1, 1, inner_frame_z_decorative_scale]) clean_edge_front_or_back_frame_piece();
|
||||
// minus the outer wall
|
||||
translate([0, -(frame_y-frame_wall)/2, 0]) cube([frame_x, frame_wall, frame_z], center=true);
|
||||
// minus half of the mounting posts (the other half provided by the outer wall)
|
||||
translate([-panel_to_frame_point_x, -(panel_to_frame_point_y), 0]) rotate([0, 0, 180])
|
||||
mount_column_cutout();
|
||||
translate([panel_to_frame_point_x, -(panel_to_frame_point_y), 0]) rotate([0, 0, 270])
|
||||
mount_column_cutout();
|
||||
}
|
||||
}
|
||||
|
||||
module front_or_back_inner_wall_frame_piece() {
|
||||
front_or_back_inner_wall_frame_base_piece();
|
||||
// extend the outward face 2mm in order to have it cut deeper into the frame outer wall
|
||||
translate([0, -(frame_y-frame_wall)/2, 0]) rotate([-90, 0, 0]) linear_extrude(height=2) projection()
|
||||
translate([0, 0, 50]) rotate([90, 0, 0]) front_or_back_inner_wall_frame_base_piece();
|
||||
}
|
||||
|
||||
// this is here for use in inner wall pieces, but unlike the side longish piece (in its own
|
||||
// .scad), front_or_back_longish_frame_piece is not printable so we'll just stash it here
|
||||
module front_or_back_frame_piece_wall() {
|
||||
// get a slice of the whole wall, to use it for making the extended version
|
||||
difference() {
|
||||
front_or_back_frame_piece();
|
||||
cube([frame_x, frame_y-frame_wall*2, frame_z], center=true);
|
||||
}
|
||||
}
|
||||
|
||||
// this is here for use in inner wall pieces, but unlike the side longish piece (in its own
|
||||
// .scad), front_or_back_longish_frame_piece is not printable so we'll just stash it here
|
||||
module front_or_back_frame_piece_extension() {
|
||||
hull() {
|
||||
front_or_back_frame_piece_wall();
|
||||
translate([0, -frame_bevel_height*2, 0]) front_or_back_frame_piece_wall();
|
||||
}
|
||||
}
|
||||
|
||||
// this is here for use in inner wall pieces, but unlike the side longish piece (in its own
|
||||
// .scad), front_or_back_longish_frame_piece is not printable so we'll just stash it here
|
||||
module front_or_back_longish_frame_piece() {
|
||||
front_or_back_frame_piece_extension();
|
||||
front_or_back_frame_piece();
|
||||
}
|
||||
|
||||
front_or_back_inner_wall_frame_piece();
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: © 2024 Brian S. Stephan <bss@incorporeal.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
include <parameters.scad>
|
||||
include <components.scad>
|
||||
use <front-or-back.scad>
|
||||
|
||||
module clean_front_or_back() {
|
||||
difference() {
|
||||
front_or_back_frame_piece();
|
||||
// chop off the lip we left on the basic piece
|
||||
translate([-frame_x/2+frame_wall/2, 0, 0]) cube([frame_wall, frame_y, frame_z], center=true);
|
||||
};
|
||||
}
|
||||
|
||||
module bottom_piece_wall() {
|
||||
// get a slice of the piece (before the bevel), to use it in extruding
|
||||
projection(cut=true) rotate([-90, 0, 0]) translate([0, frame_y/2-frame_wall+0.01, 0])
|
||||
clean_front_or_back();
|
||||
}
|
||||
|
||||
module bottom_piece_extension() {
|
||||
// combine the original with a shrunken piece to "pull" the wall out
|
||||
hull() {
|
||||
linear_extrude(height=frame_extension_y) scale([1, 0.5, 1]) bottom_piece_wall();
|
||||
linear_extrude(height=frame_wall) bottom_piece_wall();
|
||||
}
|
||||
}
|
||||
|
||||
module front_or_back_trapezoid_frame_piece() {
|
||||
clean_edge_front_or_back_frame_piece();
|
||||
translate([0, -frame_y/2+frame_wall, 0]) rotate([90, 0, 0]) bottom_piece_extension();
|
||||
}
|
||||
|
||||
front_or_back_trapezoid_frame_piece();
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: © 2024 Brian S. Stephan <bss@incorporeal.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
include <parameters.scad>
|
||||
include <components.scad>
|
||||
use <front-or-back.scad>
|
||||
use <front-or-back-inner-wall.scad>
|
||||
|
||||
module backslashes() {
|
||||
translate([-70, -(frame_y-frame_wall)/2, 0]) slash_cutout();
|
||||
translate([-50, -(frame_y-frame_wall)/2, 0]) slash_cutout();
|
||||
translate([-30, -(frame_y-frame_wall)/2, 0]) slash_cutout();
|
||||
translate([-10, -(frame_y-frame_wall)/2, 0]) slash_cutout();
|
||||
translate([10, -(frame_y-frame_wall)/2, 0]) slash_cutout();
|
||||
translate([30, -(frame_y-frame_wall)/2, 0]) slash_cutout();
|
||||
translate([50, -(frame_y-frame_wall)/2, 0]) slash_cutout();
|
||||
translate([70, -(frame_y-frame_wall)/2, 0]) slash_cutout();
|
||||
}
|
||||
|
||||
module backslashes_windowed_front_or_back_frame_piece() {
|
||||
difference() {
|
||||
clean_edge_front_or_back_frame_piece();
|
||||
// subtract slashes from the frame wall
|
||||
backslashes();
|
||||
// subtract the inner wall area that will be provided by the other piece
|
||||
front_or_back_inner_wall_frame_piece();
|
||||
}
|
||||
}
|
||||
|
||||
backslashes_windowed_front_or_back_frame_piece();
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: © 2024 Brian S. Stephan <bss@incorporeal.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
include <parameters.scad>
|
||||
include <components.scad>
|
||||
use <front-or-back.scad>
|
||||
use <front-or-back-inner-wall.scad>
|
||||
use <front-or-back-windowed-backslashes.scad>
|
||||
|
||||
module forwardslashes_windowed_front_or_back_frame_piece() {
|
||||
difference() {
|
||||
clean_edge_front_or_back_frame_piece();
|
||||
// subtract slashes from the frame wall
|
||||
mirror([0, 0, 1]) backslashes();
|
||||
// subtract the inner wall area that will be provided by the other piece
|
||||
front_or_back_inner_wall_frame_piece();
|
||||
}
|
||||
}
|
||||
|
||||
forwardslashes_windowed_front_or_back_frame_piece();
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: © 2024 Brian S. Stephan <bss@incorporeal.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
include <parameters.scad>
|
||||
include <components.scad>
|
||||
use <front-or-back.scad>
|
||||
use <front-or-back-inner-wall.scad>
|
||||
|
||||
module front_horiz_stripe() {
|
||||
cube([frame_x-(frame_mount_column_width*1.75)*2, wall_cutout_depth, 5], center=true);
|
||||
}
|
||||
|
||||
module front_horiz_stripes() {
|
||||
translate([0, -(frame_y-frame_wall)/2, 18]) front_horiz_stripe();
|
||||
translate([0, -(frame_y-frame_wall)/2, 9]) front_horiz_stripe();
|
||||
translate([0, -(frame_y-frame_wall)/2, 0]) front_horiz_stripe();
|
||||
translate([0, -(frame_y-frame_wall)/2, -9]) front_horiz_stripe();
|
||||
translate([0, -(frame_y-frame_wall)/2, -18]) front_horiz_stripe();
|
||||
}
|
||||
|
||||
module horiz_striped_windowed_front_or_back_frame_piece() {
|
||||
difference() {
|
||||
clean_edge_front_or_back_frame_piece();
|
||||
// subtract frame wall windows
|
||||
front_horiz_stripes();
|
||||
// subtract the inner wall area that will be provided by the other piece
|
||||
front_or_back_inner_wall_frame_piece();
|
||||
}
|
||||
}
|
||||
|
||||
horiz_striped_windowed_front_or_back_frame_piece();
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: © 2024 Brian S. Stephan <bss@incorporeal.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
include <parameters.scad>
|
||||
include <components.scad>
|
||||
use <front-or-back.scad>
|
||||
use <front-or-back-inner-wall.scad>
|
||||
|
||||
module front_or_back_window() {
|
||||
translate([0, -frame_y/2, 0])
|
||||
cube([frame_x-frame_mount_column_width*3.5, (frame_wall+panel_support_width)*2,
|
||||
frame_z-panel_z*3], center=true);
|
||||
}
|
||||
|
||||
module windowed_front_or_back_frame_piece() {
|
||||
difference() {
|
||||
clean_edge_front_or_back_frame_piece();
|
||||
// subtract frame wall window
|
||||
front_or_back_window();
|
||||
// subtract the inner wall area that will be provided by the other piece
|
||||
front_or_back_inner_wall_frame_piece();
|
||||
}
|
||||
}
|
||||
|
||||
module windowed_front_or_back_frame_piece_for_extended_side() {
|
||||
difference() {
|
||||
windowed_front_or_back_frame_piece();
|
||||
// ...minus the frame wall and lip on the left
|
||||
translate([-frame_x/2+frame_wall/2, 0, 0]) cube([frame_wall, frame_y, frame_z], center=true);
|
||||
}
|
||||
}
|
||||
|
||||
windowed_front_or_back_frame_piece_for_extended_side();
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: © 2024 Brian S. Stephan <bss@incorporeal.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
include <parameters.scad>
|
||||
include <components.scad>
|
||||
use <frames/complete/left-frame.scad>
|
||||
use <side.scad>
|
||||
|
||||
piece_width = panel_support_width+frame_wall+frame_mount_column_width;
|
||||
module front_or_back_frame_piece() {
|
||||
intersection() {
|
||||
left_frame();
|
||||
difference() {
|
||||
// include the whole bottom wall (including mount columns)
|
||||
translate([0, -(frame_y/2)+(piece_width/2), 0])
|
||||
cube([frame_piece_x_x, piece_width, frame_z], center=true);
|
||||
// ...minus a slot for the combining piece to go into
|
||||
cube([frame_x, frame_y-(panel_support_width+frame_wall)*2, inner_frame_z/3], center=true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// there's something with the print quality/slicing where a couple layers
|
||||
// around the hex hole get fat in the walls, making this not flush with a
|
||||
// sibling piece. this removal makes it so the pieces don't touch
|
||||
// HOWEVER, the side piece uses front_or_back_frame_piece() as a difference,
|
||||
// so if we removed the little chop from that piece, it'd make the
|
||||
// side_frame_piece() bigger, defeating the purpose, so what we'll actually
|
||||
// print is this one and there'll be a little gap in between as desired
|
||||
//
|
||||
// front/back pieces that build on this shape should inherit from clean_edge_
|
||||
module clean_edge_front_or_back_frame_piece() {
|
||||
difference() {
|
||||
front_or_back_frame_piece();
|
||||
translate([panel_x/2, -(panel_y/2-15), 0]) cube([5, 30, inner_frame_z*2], center=true);
|
||||
translate([-panel_x/2, -(panel_y/2-15), 0]) cube([5, 30, inner_frame_z*2], center=true);
|
||||
}
|
||||
}
|
||||
|
||||
clean_edge_front_or_back_frame_piece();
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
include <parameters.scad>
|
||||
include <components.scad>
|
||||
use <frame-piece-side.scad>
|
||||
use <side.scad>
|
||||
|
||||
module interconnect_frame_half_piece() {
|
||||
translate([frame_x/2-frame_wall, 0, 0]) difference() {
|
||||
@@ -0,0 +1,32 @@
|
||||
/* The inner side wall of the frame, for being displayed through a horizontal stripe windowed part.
|
||||
*
|
||||
* SPDX-FileCopyrightText: © 2025 Brian S. Stephan <bss@incorporeal.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
include <parameters.scad>
|
||||
include <components.scad>
|
||||
use <side-inner-wall.scad>
|
||||
use <side-longish.scad>
|
||||
use <side-windowed-horiz-stripes.scad>
|
||||
|
||||
// for stability's sake, this piece juts out a bit from the outside of the wall, so we
|
||||
// need to hack the window piece a bit to subtract from the longer and get ours longer
|
||||
module horiz_striped_windowed_side_frame_piece() {
|
||||
difference() {
|
||||
side_longish_frame_piece();
|
||||
// subtract frame wall windows
|
||||
side_horiz_stripes();
|
||||
// subtract the inner wall area that will be provided by the other piece
|
||||
side_inner_wall_frame_piece();
|
||||
}
|
||||
}
|
||||
|
||||
module side_windowed_horiz_stripes_inner_wall_frame_piece() {
|
||||
difference() {
|
||||
side_longish_frame_piece();
|
||||
horiz_striped_windowed_side_frame_piece();
|
||||
}
|
||||
}
|
||||
|
||||
side_windowed_horiz_stripes_inner_wall_frame_piece();
|
||||
@@ -0,0 +1,43 @@
|
||||
/* The inner side wall of the frame, for being displayed through a windowed part.
|
||||
*
|
||||
* SPDX-FileCopyrightText: © 2024 Brian S. Stephan <bss@incorporeal.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
include <parameters.scad>
|
||||
include <components.scad>
|
||||
use <side.scad>
|
||||
|
||||
module mount_column_cutout() {
|
||||
intersection() {
|
||||
frame_mount_column();
|
||||
cube([frame_mount_column_width*3/2, frame_mount_column_width*3/2, inner_frame_z*21/24], center=true);
|
||||
}
|
||||
}
|
||||
|
||||
module side_inner_wall_frame_base_piece() {
|
||||
difference() {
|
||||
// Z is scaled so that some part of the original part inner wall is retained
|
||||
scale([1, 1, inner_frame_z_decorative_scale]) side_frame_piece();
|
||||
// minus the outer wall
|
||||
translate([-(frame_x-frame_wall)/2, 0, 0]) cube([frame_wall, frame_y, frame_z], center=true);
|
||||
// minus half of the mounting posts (the other half provided by the outer wall)
|
||||
translate([-panel_to_frame_point_x, panel_to_frame_point_y, inner_frame_z/2]) rotate([0, 0, 90])
|
||||
mount_column_cutout();
|
||||
translate([-panel_to_frame_point_x, -(panel_to_frame_point_y), -inner_frame_z/2]) rotate([0, 0, 180])
|
||||
mount_column_cutout();
|
||||
translate([-panel_to_frame_point_x, panel_to_frame_point_y, -inner_frame_z/2]) rotate([0, 0, 90])
|
||||
mount_column_cutout();
|
||||
translate([-panel_to_frame_point_x, -(panel_to_frame_point_y), inner_frame_z/2]) rotate([0, 0, 180])
|
||||
mount_column_cutout();
|
||||
}
|
||||
}
|
||||
|
||||
module side_inner_wall_frame_piece() {
|
||||
side_inner_wall_frame_base_piece();
|
||||
// extend the outward face 2mm in order to have it cut deeper into the frame outer wall
|
||||
translate([-(frame_x-frame_wall)/2, 0, 0]) rotate([0, 90, 0]) linear_extrude(height=2) projection()
|
||||
translate([0, 0, 50]) rotate([0, -90, 0]) side_inner_wall_frame_base_piece();
|
||||
}
|
||||
|
||||
side_inner_wall_frame_piece();
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: © 2024 Brian S. Stephan <bss@incorporeal.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
include <parameters.scad>
|
||||
include <components.scad>
|
||||
use <side.scad>
|
||||
|
||||
module side_frame_piece_wall() {
|
||||
// get a slice of the whole wall, to use it for making the extended version
|
||||
difference() {
|
||||
side_frame_piece();
|
||||
cube([frame_x-frame_wall*2, frame_y, frame_z], center=true);
|
||||
}
|
||||
}
|
||||
|
||||
module side_frame_piece_extension() {
|
||||
// hulling the two walls provides a wall with a thicker x
|
||||
hull() {
|
||||
side_frame_piece_wall();
|
||||
translate([-frame_bevel_height*2, 0, 0]) side_frame_piece_wall();
|
||||
}
|
||||
}
|
||||
|
||||
module side_longish_frame_piece() {
|
||||
// combine the wider wall and the original piece
|
||||
side_frame_piece_extension();
|
||||
side_frame_piece();
|
||||
}
|
||||
|
||||
side_longish_frame_piece();
|
||||
+9
-9
@@ -5,31 +5,31 @@
|
||||
|
||||
include <parameters.scad>
|
||||
include <components.scad>
|
||||
use <frame-piece-bottom-left-or-right-extended.scad>
|
||||
use <frame-piece-side.scad>
|
||||
use <frames/complete/left-frame.scad>
|
||||
use <side.scad>
|
||||
use <front-or-back-trapezoid.scad>
|
||||
|
||||
module side_and_bottom_frame_piece_wall() {
|
||||
// get a slice of the pieces, to use it in extruding
|
||||
projection(cut=true) rotate([0, 90, 0]) translate([frame_x/2-frame_bevel_height, 0, 0])
|
||||
side_frame_piece();
|
||||
projection(cut=true) translate([0, -frame_y/2+frame_wall, 0]) rotate([90, 90, 0]) bottom_piece_extension();
|
||||
projection(cut=true) rotate([0, 90, 0]) translate([frame_x/2-frame_wall+0.01, 0, 0]) side_frame_piece();
|
||||
projection(cut=true) translate([0, -frame_y/2+frame_wall+0.01, 0]) rotate([90, 90, 0]) bottom_piece_extension();
|
||||
}
|
||||
|
||||
module side_and_bottom_frame_piece_extension() {
|
||||
// combine the original with a shrunken piece to "pull" the wall out
|
||||
hull() {
|
||||
linear_extrude(height=frame_extension_y) scale([0.5, 0.90, 1]) side_and_bottom_frame_piece_wall();
|
||||
linear_extrude(height=frame_bevel_height) side_and_bottom_frame_piece_wall();
|
||||
linear_extrude(height=frame_wall) side_and_bottom_frame_piece_wall();
|
||||
}
|
||||
}
|
||||
|
||||
module extra_extended_left_or_right_frame_piece() {
|
||||
module side_trapezoid_extended_to_front_frame_piece() {
|
||||
difference() {
|
||||
side_frame_piece();
|
||||
// chop off the old edge which is getting replaced with the extension
|
||||
translate([-frame_x/2+frame_bevel_height/2, 0, 0]) cube([frame_bevel_height, frame_y, frame_z], center=true);
|
||||
}
|
||||
translate([-frame_x/2+frame_bevel_height*2, 0, 0]) rotate([0, -90, 0]) side_and_bottom_frame_piece_extension();
|
||||
translate([-frame_x/2+frame_wall, 0, 0]) rotate([0, -90, 0]) side_and_bottom_frame_piece_extension();
|
||||
}
|
||||
|
||||
extra_extended_left_or_right_frame_piece();
|
||||
side_trapezoid_extended_to_front_frame_piece();
|
||||
@@ -5,29 +5,29 @@
|
||||
|
||||
include <parameters.scad>
|
||||
include <components.scad>
|
||||
use <frame-piece-side.scad>
|
||||
use <frames/complete/left-frame.scad>
|
||||
use <side.scad>
|
||||
|
||||
module side_frame_piece_wall() {
|
||||
// get a slice of the piece, to use it in extruding
|
||||
projection(cut=true) rotate([0, 90, 0]) translate([frame_x/2-frame_bevel_height, 0, 0])
|
||||
side_frame_piece();
|
||||
projection(cut=true) rotate([0, 90, 0]) translate([frame_x/2-frame_wall+0.01, 0, 0]) side_frame_piece();
|
||||
}
|
||||
|
||||
module side_frame_piece_extension() {
|
||||
// combine the original with a shrunken piece to "pull" the wall out
|
||||
hull() {
|
||||
linear_extrude(height=frame_extension_y) scale([0.5, 0.85, 1]) side_frame_piece_wall();
|
||||
linear_extrude(height=frame_bevel_height) side_frame_piece_wall();
|
||||
linear_extrude(height=frame_wall) side_frame_piece_wall();
|
||||
}
|
||||
}
|
||||
|
||||
module extended_bottom_left_or_right_frame_piece() {
|
||||
module side_trapezoid_frame_piece() {
|
||||
difference() {
|
||||
side_frame_piece();
|
||||
// chop off the old edge which is getting replaced with the extension
|
||||
translate([-frame_x/2+frame_bevel_height/2, 0, 0]) cube([frame_bevel_height, frame_y, frame_z], center=true);
|
||||
}
|
||||
translate([-frame_x/2+frame_bevel_height*2, 0, 0]) rotate([0, -90, 0]) side_frame_piece_extension();
|
||||
translate([-frame_x/2+frame_wall, 0, 0]) rotate([0, -90, 0]) side_frame_piece_extension();
|
||||
}
|
||||
|
||||
extended_bottom_left_or_right_frame_piece();
|
||||
side_trapezoid_frame_piece();
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: © 2024 Brian S. Stephan <bss@incorporeal.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
include <parameters.scad>
|
||||
include <components.scad>
|
||||
use <side.scad>
|
||||
use <side-inner-wall.scad>
|
||||
|
||||
module backslashes() {
|
||||
translate([-(frame_x-frame_wall)/2, -50, 0]) rotate([0, 0, -90]) slash_cutout();
|
||||
translate([-(frame_x-frame_wall)/2, -30, 0]) rotate([0, 0, -90]) slash_cutout();
|
||||
translate([-(frame_x-frame_wall)/2, -10, 0]) rotate([0, 0, -90]) slash_cutout();
|
||||
translate([-(frame_x-frame_wall)/2, 10, 0]) rotate([0, 0, -90]) slash_cutout();
|
||||
translate([-(frame_x-frame_wall)/2, 30, 0]) rotate([0, 0, -90]) slash_cutout();
|
||||
translate([-(frame_x-frame_wall)/2, 50, 0]) rotate([0, 0, -90]) slash_cutout();
|
||||
}
|
||||
|
||||
module backslashes_windowed_side_frame_piece() {
|
||||
difference() {
|
||||
side_frame_piece();
|
||||
// subtract slashes from the frame wall
|
||||
backslashes();
|
||||
// subtract the inner wall area that will be provided by the other piece
|
||||
side_inner_wall_frame_piece();
|
||||
}
|
||||
}
|
||||
|
||||
backslashes_windowed_side_frame_piece();
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: © 2024 Brian S. Stephan <bss@incorporeal.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
include <parameters.scad>
|
||||
include <components.scad>
|
||||
use <side.scad>
|
||||
use <side-inner-wall.scad>
|
||||
use <side-windowed-backslashes.scad>
|
||||
|
||||
module forwardslashes_windowed_side_frame_piece() {
|
||||
difference() {
|
||||
side_frame_piece();
|
||||
// subtract slashes from the frame wall
|
||||
mirror([0, 0, 1]) backslashes();
|
||||
// subtract the inner wall area that will be provided by the other piece
|
||||
side_inner_wall_frame_piece();
|
||||
}
|
||||
}
|
||||
|
||||
forwardslashes_windowed_side_frame_piece();
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: © 2024 Brian S. Stephan <bss@incorporeal.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
include <parameters.scad>
|
||||
include <components.scad>
|
||||
use <side.scad>
|
||||
use <side-inner-wall.scad>
|
||||
|
||||
module side_horiz_stripe() {
|
||||
cube([wall_cutout_depth, frame_y-(frame_mount_column_width*1.75)*2, 5], center=true);
|
||||
}
|
||||
|
||||
module side_horiz_stripes() {
|
||||
translate([-(frame_x-frame_wall)/2, 0, 18]) side_horiz_stripe();
|
||||
translate([-(frame_x-frame_wall)/2, 0, 9]) side_horiz_stripe();
|
||||
translate([-(frame_x-frame_wall)/2, 0, 0]) side_horiz_stripe();
|
||||
translate([-(frame_x-frame_wall)/2, 0, -9]) side_horiz_stripe();
|
||||
translate([-(frame_x-frame_wall)/2, 0, -18]) side_horiz_stripe();
|
||||
}
|
||||
|
||||
module horiz_striped_windowed_side_frame_piece() {
|
||||
difference() {
|
||||
side_frame_piece();
|
||||
// subtract frame wall windows
|
||||
side_horiz_stripes();
|
||||
// subtract the inner wall area that will be provided by the other piece
|
||||
side_inner_wall_frame_piece();
|
||||
}
|
||||
}
|
||||
|
||||
horiz_striped_windowed_side_frame_piece();
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: © 2024 Brian S. Stephan <bss@incorporeal.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
include <parameters.scad>
|
||||
include <components.scad>
|
||||
use <side.scad>
|
||||
use <side-inner-wall.scad>
|
||||
|
||||
module windowed_side_frame_piece() {
|
||||
difference() {
|
||||
side_frame_piece();
|
||||
// subtract frame wall window
|
||||
translate([-frame_x/2, 0, 0])
|
||||
cube([(frame_wall+panel_support_width)*2, frame_y-frame_mount_column_width*3.5,
|
||||
frame_z-panel_z*3], center=true);
|
||||
// subtract the inner wall area that will be provided by the other piece
|
||||
side_inner_wall_frame_piece();
|
||||
}
|
||||
}
|
||||
|
||||
windowed_side_frame_piece();
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: © 2024 Brian S. Stephan <bss@incorporeal.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
include <parameters.scad>
|
||||
include <components.scad>
|
||||
use <frames/complete/left-frame.scad>
|
||||
use <front-or-back.scad>
|
||||
|
||||
module side_frame_piece() {
|
||||
piece_width = panel_support_width+frame_wall+frame_mount_column_width;
|
||||
difference() {
|
||||
intersection() {
|
||||
left_frame();
|
||||
// include the whole left wall (including mount columns)
|
||||
translate([-(frame_x/2)+(piece_width/2), 0, 0])
|
||||
cube([piece_width, frame_piece_y_y, frame_z], center=true);
|
||||
}
|
||||
// minus the top and bottom
|
||||
front_or_back_frame_piece();
|
||||
rotate([180, 0, 0]) front_or_back_frame_piece();
|
||||
}
|
||||
}
|
||||
|
||||
side_frame_piece();
|
||||
@@ -0,0 +1,113 @@
|
||||
// Library: MinkowskiRound.scad
|
||||
// Version: 1.0
|
||||
// Author: IrevDev
|
||||
// Copyright: 2020
|
||||
// License: MIT
|
||||
|
||||
/*
|
||||
---Modules
|
||||
round2d(outside radius,internal radius) -> takes 2d children
|
||||
This module will round 2d any shape
|
||||
|
||||
minkowskiRound(outsideRadius,internalRadius,enable,envelopecube[x,y,z]) -> takes 3d children
|
||||
This module will round any 3d shape though it takes a long time, possibly more than 12 hours (use a low $fn value, 10-15 to begin with) so make sure enable is set to 0 untill you are ready for final render,the envelopecube must be bigger than the object you are rounding, default values are [500,500,500].
|
||||
|
||||
minkowskiOutsideRound(radius,enable,envelopecube[x,y,z])
|
||||
minkowskiInsideRound(radius,enable,envelopecube[x,y,z])
|
||||
Both this modules do the same thing as minkowskiRound() but focus on either inside or outside radiuses, which means these modules use one less minkowski() (two instead of three) making them quicker if you don't want both inside and outside radiuses.
|
||||
|
||||
--Examples
|
||||
*/
|
||||
|
||||
//round2d(1,6)difference(){square([20,20]);square([10,10]);}
|
||||
//minkowskiRound(3,1.5,1)theshape();
|
||||
//minkowskiInsideRound(3,1)theshape();
|
||||
//minkowskiOutsideRound(3,1)theshape();
|
||||
|
||||
//---good test child for examples
|
||||
//module theshape(){//example shape
|
||||
// difference(){
|
||||
// cube([20,20,20]);
|
||||
// cube([10,10,10]);
|
||||
// }
|
||||
//}
|
||||
|
||||
// $fn=20;
|
||||
// minkowskiRound(0.7,1.5,1,[50,50,50])union(){//--example in the thiniverse thumbnail/main image
|
||||
// cube([6,6,22]);
|
||||
// rotate([30,45,10])cylinder(h=22,d=10);
|
||||
// }//--I rendered this out with a $fn=25 and it took more than 12 hours on my computer
|
||||
|
||||
|
||||
module round2d(OR=3,IR=1){
|
||||
offset(OR){
|
||||
offset(-IR-OR){
|
||||
offset(IR){
|
||||
children();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module minkowskiRound(OR=1,IR=1,enable=1,boundingEnvelope=[500,500,500]){
|
||||
if(enable==0){//do nothing if not enabled
|
||||
children();
|
||||
} else {
|
||||
minkowski(){//expand the now positive shape back out
|
||||
difference(){//make the negative shape positive again
|
||||
cube(boundingEnvelope-[0.1,0.1,0.1],center=true);
|
||||
minkowski(){//expand the negative shape inwards
|
||||
difference(){//create a negative of the children
|
||||
cube(boundingEnvelope,center=true);
|
||||
minkowski(){//expand the children
|
||||
children();
|
||||
sphere(IR);
|
||||
}
|
||||
}
|
||||
sphere(OR+IR);
|
||||
}
|
||||
}
|
||||
sphere(OR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module minkowskiOutsideRound(r=1,enable=1,boundingEnvelope=[500,500,500]){
|
||||
if(enable==0){//do nothing if not enabled
|
||||
children();
|
||||
} else {
|
||||
minkowski(){//expand the now positive shape
|
||||
difference(){//make the negative positive
|
||||
cube(boundingEnvelope-[0.1,0.1,0.1],center=true);
|
||||
minkowski(){//expand the negative inwards
|
||||
difference(){//create a negative of the children
|
||||
cube(boundingEnvelope,center=true);
|
||||
children();
|
||||
}
|
||||
sphere(r);
|
||||
}
|
||||
}
|
||||
sphere(r);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module minkowskiInsideRound(r=1,enable=1,boundingEnvelope=[500,500,500]){
|
||||
if(enable==0){//do nothing if not enabled
|
||||
children();
|
||||
} else {
|
||||
difference(){//make the negative positive again
|
||||
cube(boundingEnvelope-[0.1,0.1,0.1],center=true);
|
||||
minkowski(){//expand the negative shape inwards
|
||||
difference(){//make the expanded children a negative shape
|
||||
cube(boundingEnvelope,center=true);
|
||||
minkowski(){//expand the children
|
||||
children();
|
||||
sphere(r);
|
||||
}
|
||||
}
|
||||
sphere(r);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: © 2024 Brian S. Stephan <bss@incorporeal.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
include <parameters.scad>
|
||||
decorative_radius_scale = 1.5;
|
||||
jumbo_decorative_radius_scale = 0;
|
||||
include <components.scad>
|
||||
|
||||
module dir_arc_plus_w_30mm_and_sega_2p_plus_one_decorative_plate_of_plates() {
|
||||
difference() {
|
||||
// get a 2mm slice of the bigger button cylinders
|
||||
union() {
|
||||
translate([-panel_x/2, 0, -25]) {
|
||||
hull() union() {
|
||||
dir_arc_30mm_finger_buttons();
|
||||
translate([-26.8, 57.2+12.9+34.5, 0]) dir_arc_30mm_thumb_button();
|
||||
}
|
||||
}
|
||||
translate([panel_x/2, 0, -25]) {
|
||||
hull() sega_2p();
|
||||
}
|
||||
hull() {
|
||||
translate([-panel_x/2, 0, -25]) dir_arc_30mm_thumb_button();
|
||||
translate([panel_x/2, -19-9-11-19-9-11, -25]) sega_2p_p1();
|
||||
}
|
||||
difference() {
|
||||
translate([-60, -8, 0]) cube(60, center=true);
|
||||
translate([-98.35, -39.25, 0]) cylinder(h=50, r=48, $fn=50, center=true);
|
||||
}
|
||||
difference() {
|
||||
translate([43.35, -10.30, 0]) cube(50, center=true);
|
||||
translate([68.35, -35.30, 0]) cylinder(h=50, r=18, $fn=50, center=true);
|
||||
}
|
||||
difference() {
|
||||
translate([-10, 55, 0]) cube(43, center=true);
|
||||
translate([-5.15, 76.25, 0]) cylinder(h=50, r=27, $fn=50, center=true);
|
||||
}
|
||||
translate([-7, 0, 0]) cube(80, center=true);
|
||||
}
|
||||
translate([0, 0, -100]) cube([500, 500, 198], center=true);
|
||||
translate([0, 0, 100]) cube([500, 500, 198], center=true);
|
||||
// cut out the normal holes
|
||||
translate([-panel_x/2, 0, -1]) dir_arc_w_30mm();
|
||||
translate([panel_x/2, 0, -1]) sega_2p_plus_one();
|
||||
}
|
||||
}
|
||||
|
||||
dir_arc_plus_w_30mm_and_sega_2p_plus_one_decorative_plate_of_plates();
|
||||
@@ -0,0 +1,31 @@
|
||||
/* A bit of plastic to put on the corners of a case, just for more flair and seam hiding.
|
||||
*
|
||||
* Note: this only works on the standard side and front/back pieces, not the longish/extended pieces.
|
||||
*
|
||||
* SPDX-FileCopyrightText: © 2025 Brian S. Stephan <bss@incorporeal.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
include <parameters.scad>
|
||||
include <components.scad>
|
||||
|
||||
module decorative_corner() {
|
||||
deco_thickness = 2;
|
||||
difference() {
|
||||
// start with the frame shape itself, just grown a bit
|
||||
resize(newsize=[frame_x+(deco_thickness*2), frame_y+(deco_thickness*2), frame_z+(deco_thickness*2)])
|
||||
frame_solid();
|
||||
// lob off the pieces to make a corner
|
||||
translate([(panel_to_frame_point_offset+deco_thickness*2)*1.5, 0, 0])
|
||||
cube([frame_x, frame_y*2, frame_z*2], center=true);
|
||||
translate([0, (panel_to_frame_point_offset+deco_thickness*2)*1.5, 0])
|
||||
cube([frame_x*2, frame_y, frame_z*2], center=true);
|
||||
// carve out the inside
|
||||
frame_solid();
|
||||
// holes for bolts
|
||||
translate([0, 0, frame_z/2]) panel_holes();
|
||||
translate([0, 0, -frame_z/2]) rotate([0, 180, 0]) panel_holes();
|
||||
}
|
||||
}
|
||||
|
||||
decorative_corner();
|
||||
@@ -0,0 +1,36 @@
|
||||
/* A bit of plastic to put on the center of a case front, just for more flair and seam hiding.
|
||||
*
|
||||
* SPDX-FileCopyrightText: © 2025 Brian S. Stephan <bss@incorporeal.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
include <parameters.scad>
|
||||
include <components.scad>
|
||||
|
||||
module decorative_half_middle() {
|
||||
deco_thickness = 2;
|
||||
translate([-frame_x/2+frame_wall, 0, 0]) difference() {
|
||||
// start with the frame shape itself, just grown a bit
|
||||
resize(newsize=[frame_x+(deco_thickness*2), frame_y+(deco_thickness*2), frame_z+(deco_thickness*2)])
|
||||
frame_solid();
|
||||
// make this appropriate for the middle
|
||||
scale([1, 1, 2]) side_chopper();
|
||||
// lob off the pieces to make a cornerish piece
|
||||
translate([-(panel_to_frame_point_offset+deco_thickness*2)*1.65, 0, 0])
|
||||
cube([frame_x, frame_y*2, frame_z*2], center=true);
|
||||
translate([0, (panel_to_frame_point_offset+deco_thickness*2)*1.5, 0])
|
||||
cube([frame_x*2, frame_y, frame_z*2], center=true);
|
||||
// carve out the inside
|
||||
frame_solid();
|
||||
// holes for bolts
|
||||
translate([0, 0, frame_z/2]) panel_holes();
|
||||
translate([0, 0, -frame_z/2]) rotate([0, 180, 0]) panel_holes();
|
||||
}
|
||||
}
|
||||
|
||||
module decorative_middle() {
|
||||
decorative_half_middle();
|
||||
mirror([1, 0, 0]) decorative_half_middle();
|
||||
}
|
||||
|
||||
decorative_middle();
|
||||
@@ -0,0 +1,20 @@
|
||||
/* Fit a pin for the assembly holes.
|
||||
*
|
||||
* SPDX-FileCopyrightText: © 2026 Brian S. Stephan <bss@incorporeal.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
include <parameters.scad>
|
||||
include <components.scad>
|
||||
|
||||
// adjust the pin to have a good friction fit based on parameters
|
||||
pin_fit_scale = ((m4_bolt_hex_exterior_radius-hole_tolerance)*2)/(m4_bolt_hex_exterior_radius*2);
|
||||
|
||||
module frame_assembly_pin() {
|
||||
difference() {
|
||||
scale([pin_fit_scale, pin_fit_scale, 0.95]) resize([0, 0, inner_frame_z]) frame_hex_bolt_hole();
|
||||
scale([0.8, 0.8, 1]) resize([0, 0, inner_frame_z]) m4_hole();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
frame_assembly_pin();
|
||||
@@ -0,0 +1,24 @@
|
||||
/* Wrap a smaller width hex spacer with plastic to get it to fit in our standard post hole.
|
||||
*
|
||||
* Since the hex spacers can vary in width, you may have to adjust the inner dimensions
|
||||
* to make this work right for your piece, but this worked right for mine. YMMV.
|
||||
*
|
||||
* SPDX-FileCopyrightText: © 2025 Brian S. Stephan <bss@incorporeal.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
include <parameters.scad>
|
||||
include <components.scad>
|
||||
|
||||
module small_m4_hole() {
|
||||
scale([1, 1, 2]) cylinder(r=3.25, h=frame_z, $fn=6, center=true);
|
||||
}
|
||||
|
||||
module m4_hex_spacer_sleeve() {
|
||||
difference() {
|
||||
resize([0, 0, 45]) frame_hex_bolt_hole();
|
||||
small_m4_hole();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
m4_hex_spacer_sleeve();
|
||||
@@ -0,0 +1,17 @@
|
||||
/* A simple shim for improving panel-to-frame fit.
|
||||
*
|
||||
* SPDX-FileCopyrightText: © 2026 Brian S. Stephan <bss@incorporeal.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
include <parameters.scad>
|
||||
include <components.scad>
|
||||
|
||||
module shim() {
|
||||
difference() {
|
||||
cube([frame_wall*2, frame_wall*2, 2]);
|
||||
rotate([0, 5, 0]) translate([-frame_wall, 0, 0.75]) cube([frame_wall*3, frame_wall*3, 2]);
|
||||
}
|
||||
}
|
||||
|
||||
shim();
|
||||
+3
-3
@@ -6,11 +6,11 @@
|
||||
include <parameters.scad>
|
||||
include <components.scad>
|
||||
|
||||
module sega_2p_plus_one_panel() {
|
||||
module dir_arc_w_30mm_panel() {
|
||||
difference() {
|
||||
panel();
|
||||
sega_2p_plus_one();
|
||||
dir_arc_w_30mm();
|
||||
}
|
||||
}
|
||||
|
||||
sega_2p_plus_one_panel();
|
||||
dir_arc_w_30mm_panel();
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
|
||||
include <parameters.scad>
|
||||
include <components.scad>
|
||||
use <top-panel-inset-dir_arc-plus-w-30mm-plus-one.scad>
|
||||
use <dir_arc-plus-w-30mm-plus-one-panel.scad>
|
||||
|
||||
module dir_arc_w_30mm_plus_one_panel_with_mount() {
|
||||
dir_arc_w_30mm_plus_one_panel();
|
||||
@@ -0,0 +1,15 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: © 2025 Brian S. Stephan <bss@incorporeal.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
include <parameters.scad>
|
||||
include <components.scad>
|
||||
use <ergo-nine-plus-aux-button.scad>
|
||||
|
||||
module ergo_nine_plus_aux_button_panel_with_mount() {
|
||||
ergo_nine_plus_aux_button_panel();
|
||||
translate([20, -50, -(panel_z/2) - 3]) pcb_mount();
|
||||
}
|
||||
|
||||
ergo_nine_plus_aux_button_panel_with_mount();
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: © 2025 Brian S. Stephan <bss@incorporeal.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
include <parameters.scad>
|
||||
include <components.scad>
|
||||
|
||||
module ergo_nine_plus_aux_button_panel() {
|
||||
difference() {
|
||||
panel();
|
||||
ergo_nine_30mm();
|
||||
translate([89, 30, 0]) button_24mm_hole();
|
||||
}
|
||||
}
|
||||
|
||||
ergo_nine_plus_aux_button_panel();
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: © 2023 Brian S. Stephan <bss@incorporeal.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
include <parameters.scad>
|
||||
include <components.scad>
|
||||
use <lever-and-dir_arc-plus-w-30mm-panel.scad>
|
||||
|
||||
module lever_and_dir_arc_w_30mm_panel_with_oled() {
|
||||
difference() {
|
||||
lever_and_dir_arc_w_30mm_panel();
|
||||
translate([0, -(panel_y/2 - 22), 0]) adafruit_pid_326_oled_ssd1306_mount_cutout();
|
||||
}
|
||||
translate([0, -(panel_y/2 - 22), 0]) adafruit_pid_326_oled_ssd1306_mount();
|
||||
}
|
||||
|
||||
lever_and_dir_arc_w_30mm_panel_with_oled();
|
||||
+2
-2
@@ -6,7 +6,7 @@
|
||||
include <parameters.scad>
|
||||
include <components.scad>
|
||||
|
||||
module top_panel_inset_lever_and_dir_arc_w_30mm() {
|
||||
module lever_and_dir_arc_w_30mm_panel() {
|
||||
difference() {
|
||||
panel();
|
||||
dir_arc_w_30mm();
|
||||
@@ -15,4 +15,4 @@ module top_panel_inset_lever_and_dir_arc_w_30mm() {
|
||||
}
|
||||
}
|
||||
|
||||
top_panel_inset_lever_and_dir_arc_w_30mm();
|
||||
lever_and_dir_arc_w_30mm_panel();
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: © 2025 Brian S. Stephan <bss@incorporeal.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
include <parameters.scad>
|
||||
include <components.scad>
|
||||
use <lever-and-ergo-wasd-five-panel.scad>
|
||||
|
||||
module lever_and_ergo_wasd_five_panel_with_oled() {
|
||||
difference() {
|
||||
lever_and_ergo_wasd_five_panel();
|
||||
translate([0, -(panel_y/2 - 22), 0]) adafruit_pid_326_oled_ssd1306_mount_cutout();
|
||||
}
|
||||
translate([0, -(panel_y/2 - 22), 0]) adafruit_pid_326_oled_ssd1306_mount();
|
||||
}
|
||||
|
||||
lever_and_ergo_wasd_five_panel_with_oled();
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: © 2025 Brian S. Stephan <bss@incorporeal.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
include <parameters.scad>
|
||||
include <components.scad>
|
||||
|
||||
module lever_and_ergo_wasd_five_panel() {
|
||||
difference() {
|
||||
panel();
|
||||
mirror([1, 0, 0]) ergo_wasd_five_30mm();
|
||||
translate([(-panel_x/2)+55, (panel_y/2)-75, 0]) levermountholes();
|
||||
translate([(-panel_x/2)+55, (panel_y/2)-75, 0]) levermountcountersinks();
|
||||
}
|
||||
}
|
||||
|
||||
lever_and_ergo_wasd_five_panel();
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: © 2023 Brian S. Stephan <bss@incorporeal.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
include <parameters.scad>
|
||||
include <components.scad>
|
||||
|
||||
module lever_and_sega_2p_6_button_panel_with_aux_with_mount() {
|
||||
difference() {
|
||||
union() {
|
||||
panel();
|
||||
translate([45, -58, -panel_z/2]) rotate([0, 0, 13]) pcb_mount();
|
||||
}
|
||||
translate([90, -25, 0]) sega_2p_6_button();
|
||||
translate([-65, 5, 0]) union() {
|
||||
levermountholes();
|
||||
levermountcountersinks();
|
||||
}
|
||||
translate([17, 70, 0]) button_24mm_hole();
|
||||
translate([-17, 70, 0]) button_24mm_hole();
|
||||
}
|
||||
}
|
||||
|
||||
lever_and_sega_2p_6_button_panel_with_aux_with_mount();
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
|
||||
include <parameters.scad>
|
||||
include <components.scad>
|
||||
use <top-panel-inset-lever.scad>
|
||||
use <lever-panel.scad>
|
||||
|
||||
module lever_panel_with_mount() {
|
||||
lever_panel();
|
||||
@@ -6,4 +6,4 @@
|
||||
include <parameters.scad>
|
||||
include <components.scad>
|
||||
|
||||
bottom_panel();
|
||||
panel();
|
||||
@@ -0,0 +1,16 @@
|
||||
/* 11-button Sega 2P panel with PCB mount
|
||||
*
|
||||
* SPDX-FileCopyrightText: © 2023 Brian S. Stephan <bss@incorporeal.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
include <parameters.scad>
|
||||
include <components.scad>
|
||||
use <sega-2p-eleven-panel.scad>
|
||||
|
||||
module sega_2p_eleven_panel_with_mount() {
|
||||
sega_2p_eleven_panel();
|
||||
translate([20, -50, -(panel_z/2) - 3]) pcb_mount();
|
||||
}
|
||||
|
||||
sega_2p_eleven_panel_with_mount();
|
||||
@@ -0,0 +1,17 @@
|
||||
/* A panel with the Sega 2P button layout plus three extra buttons for whatever purpose.
|
||||
*
|
||||
* SPDX-FileCopyrightText: © 2024 Brian S. Stephan <bss@incorporeal.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
include <parameters.scad>
|
||||
include <components.scad>
|
||||
|
||||
module sega_2p_eleven_panel() {
|
||||
difference() {
|
||||
panel();
|
||||
sega_2p_eleven();
|
||||
}
|
||||
}
|
||||
|
||||
sega_2p_eleven_panel();
|
||||
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: © 2023 Brian S. Stephan <bss@incorporeal.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
include <parameters.scad>
|
||||
include <components.scad>
|
||||
|
||||
module sega_2p_nine_panel() {
|
||||
difference() {
|
||||
panel();
|
||||
sega_2p_nine();
|
||||
}
|
||||
}
|
||||
|
||||
sega_2p_nine_panel();
|
||||
@@ -0,0 +1,15 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: © 2023 Brian S. Stephan <bss@incorporeal.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
include <parameters.scad>
|
||||
include <components.scad>
|
||||
use <sega-2p-nine-plus-aux-button.scad>
|
||||
|
||||
module sega_2p_nine_plus_aux_button_with_mount() {
|
||||
sega_2p_nine_plus_aux_button();
|
||||
translate([20, -50, -(panel_z/2) - 3]) pcb_mount();
|
||||
}
|
||||
|
||||
sega_2p_nine_plus_aux_button_with_mount();
|
||||
+3
-4
@@ -6,13 +6,12 @@
|
||||
include <parameters.scad>
|
||||
include <components.scad>
|
||||
|
||||
module top_panel_inset_sega_2p_plus_one_plus_control() {
|
||||
module sega_2p_nine_plus_aux_button() {
|
||||
difference() {
|
||||
panel();
|
||||
sega_2p_plus_one();
|
||||
rotate([0, 0, 180]) side_chopper();
|
||||
sega_2p_nine();
|
||||
translate([89, 30, 0]) button_24mm_hole();
|
||||
}
|
||||
}
|
||||
|
||||
top_panel_inset_sega_2p_plus_one_plus_control();
|
||||
sega_2p_nine_plus_aux_button();
|
||||
@@ -0,0 +1,17 @@
|
||||
/* A top panel in the very popular Sega 2P layout.
|
||||
*
|
||||
* SPDX-FileCopyrightText: © 2025 Brian S. Stephan <bss@incorporeal.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
include <parameters.scad>
|
||||
include <components.scad>
|
||||
|
||||
module sega_2p_panel() {
|
||||
difference() {
|
||||
panel();
|
||||
sega_2p();
|
||||
}
|
||||
}
|
||||
|
||||
sega_2p_panel();
|
||||
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: © 2023 Brian S. Stephan <bss@incorporeal.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
include <parameters.scad>
|
||||
include <components.scad>
|
||||
|
||||
module shiokenstar_left_panel() {
|
||||
difference() {
|
||||
translate([-frame_x/2+frame_wall, 0, 0]) panel();
|
||||
translate([75, 0, 0]) shiokenstar();
|
||||
}
|
||||
}
|
||||
|
||||
shiokenstar_left_panel();
|
||||
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: © 2023 Brian S. Stephan <bss@incorporeal.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
include <parameters.scad>
|
||||
include <components.scad>
|
||||
|
||||
module shiokenstar_right_panel() {
|
||||
difference() {
|
||||
translate([frame_x/2-frame_wall, 0, 0]) panel();
|
||||
translate([75, 0, 0]) shiokenstar();
|
||||
}
|
||||
}
|
||||
|
||||
shiokenstar_right_panel();
|
||||
+2
-2
@@ -6,7 +6,7 @@
|
||||
include <parameters.scad>
|
||||
include <components.scad>
|
||||
|
||||
module top_panel_left_lever_and_dir_arc_w_30mm() {
|
||||
module lever_and_dir_arc_w_30mm_left_overhang_panel() {
|
||||
difference() {
|
||||
panel_with_raised_overhang();
|
||||
dir_arc_w_30mm();
|
||||
@@ -16,4 +16,4 @@ module top_panel_left_lever_and_dir_arc_w_30mm() {
|
||||
}
|
||||
}
|
||||
|
||||
top_panel_left_lever_and_dir_arc_w_30mm();
|
||||
lever_and_dir_arc_w_30mm_left_overhang_panel();
|
||||
@@ -7,7 +7,7 @@ include <parameters.scad>
|
||||
include <components.scad>
|
||||
|
||||
// combine the lever mount and generic plate, with mounting holes
|
||||
module top_panel_left_lever() {
|
||||
module lever_left_overhang_panel() {
|
||||
difference() {
|
||||
// base plate
|
||||
panel_with_raised_overhang();
|
||||
@@ -18,4 +18,4 @@ module top_panel_left_lever() {
|
||||
}
|
||||
}
|
||||
|
||||
top_panel_left_lever();
|
||||
lever_left_overhang_panel();
|
||||
@@ -5,14 +5,14 @@
|
||||
|
||||
include <parameters.scad>
|
||||
include <components.scad>
|
||||
use <bottom-panel-overhang-solo.scad>
|
||||
use <solo-panel.scad>
|
||||
|
||||
module bottom_panel_left() {
|
||||
module left_or_right_overhang_panel() {
|
||||
difference() {
|
||||
bottom_panel_solo();
|
||||
solo_overhang_panel();
|
||||
// chop the right edge off
|
||||
side_chopper();
|
||||
}
|
||||
}
|
||||
|
||||
bottom_panel_left();
|
||||
left_or_right_overhang_panel();
|
||||
+4
-4
@@ -5,11 +5,11 @@
|
||||
|
||||
include <parameters.scad>
|
||||
include <components.scad>
|
||||
use <top-panel-overhang-middle-dir_arc-plus-w-30mm.scad>
|
||||
use <middle-dir_arc-plus-w-30mm-panel.scad>
|
||||
|
||||
module top_panel_middle_dir_arc_w_30mm_with_mount() {
|
||||
top_panel_middle_dir_arc_w_30mm();
|
||||
module dir_arc_w_30mm_middle_overhang_panel_with_mount() {
|
||||
dir_arc_w_30mm_middle_overhang_panel();
|
||||
translate([-15, -40, -(panel_z/2) - 3]) rotate([0, 0, -45]) pcb_mount();
|
||||
}
|
||||
|
||||
top_panel_middle_dir_arc_w_30mm_with_mount();
|
||||
dir_arc_w_30mm_middle_overhang_panel_with_mount();
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user