Compare commits

..

4 Commits

Author SHA1 Message Date
d4217405e1
TEMP build123d framework stuff part 2
Signed-off-by: Brian S. Stephan <bss@incorporeal.org>
2024-07-05 17:23:11 -05:00
0dcd1cb5ff
TEMP build123d extremely basic panel demo
Signed-off-by: Brian S. Stephan <bss@incorporeal.org>
2024-07-05 17:21:57 -05:00
e63a5da6a2
TEMP build123d framework stuff and test layout
Signed-off-by: Brian S. Stephan <bss@incorporeal.org>
2024-07-04 21:58:43 -05:00
82d914c30c
TEMP build123d environment part 1
Signed-off-by: Brian S. Stephan <bss@incorporeal.org>
2024-07-02 10:24:13 -05:00
103 changed files with 2411 additions and 1716 deletions

6
.gitignore vendored
View File

@ -1,4 +1,8 @@
build/
*.stl
venv/
*.egg-info/
.tox/
*.pyc
*.sw*
.coverage

2
.pylintrc Normal file
View File

@ -0,0 +1,2 @@
[MESSAGES CONTROL]
disable = W,C,R

View File

@ -2,146 +2,6 @@
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

View File

@ -1,13 +1,12 @@
all:
python build.py
mkdir -p ./build/docs
cp ./README.md ./build/README.md
cp ./docs/README-objects.md ./build/README-objects.md
cp ./docs/* ./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 ./LICENSE ./build/LICENSE
cp ./CHANGELOG.md ./build/CHANGELOG.md
pushd ./build; zip ./buildable-stick-system-`git describe --dirty`-stls-and-docs.zip . -r; popd
pushd ./build; zip ./buildable-stick-system-`git describe --dirty`-stls.zip extras frames misc panels -r; popd
pushd ./build; zip ./buildable-stick-system-`git describe --dirty`-stls.zip . -r; popd
clean:
rm -rf ./build

View File

@ -1,15 +1,12 @@
# The Buildable Stick System
Files for 3D printing and building an arcade stick enclosure.
Files for 3D printing an arcade stick.
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)!**
![An example of stick components displayed in OpenSCAD](docs/blown-up-demo.png)
[OpenSCAD-based illustration of how the components for an overhang panel-based stick fit together.]
@ -40,17 +37,21 @@ about what the types of parts are and how to use them:
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.
* `pieces/`
* `box/` --- 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.
* `extended/` --- the frame walls are pulled out to create MCZ TE-style extended sides. Rather than getting a
box look, you get a longer slab with nice bevels. These look nice, but slightly fiddily to print (and of
course need more material) --- watch your surface adhesion.
* `interconnect` --- complete frames are bolted to one another, but for frame pieces, there is an interconnect
that stands in for the joined inner wall. 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.
top or bottom. These work equally well with box or extended frames, and aside from using up a bit of the space
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
@ -65,16 +66,11 @@ about what the types of parts are and how to use them:
* `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/printing-and-materials.md` for more
OpenStickCommunity. Standard settings seem sufficiently sturdy, but see `docs/materials-and-printing.md` for more
thoughts and settings based on my tinkering with prints.
## Assembling
@ -165,13 +161,12 @@ 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/>.
@ -195,9 +190,3 @@ 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.
![A photo of three completed sticks](docs/finished-v4.7-x3.jpg)

View File

@ -5,7 +5,3 @@ Notes for "next time".
## v4.x
* Engraving some cosmetic stuff? Or maybe a place to mount other plates on the top?
## v5
* Finishing the build123d rewrite?

View File

@ -42,11 +42,9 @@ for root, dirs, files in os.walk('.'):
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_}'
cmd = f'openscad -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")

View File

@ -1,36 +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 <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-control-panel-with-mount.scad>
use <misc/decorative-plate-24mm-button.scad>
use <misc/decorative-plate-dir_arc-plus-w-30mm-and-sega-2p-nine.scad>
use <misc/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_control_panel_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();

View File

@ -5,33 +5,34 @@
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 <frames/pieces/extended/front-or-back.scad>
use <frames/pieces/extended/side-extended-to-bottom.scad>
use <frames/pieces/extended/front-or-back-clean-for-extended-side-aux-and-neutrik.scad>
use <panels/inset/lever-and-dir_arc-plus-w-30mm-panel.scad>
use <panels/inset/sega-2p-nine-plus-control-panel-with-mount.scad>
use <panels/inset/sega-2p-plus-one-plus-control-panel-with-mount.scad>
use <misc/decorative-plate-24mm-button.scad>
use <misc/decorative-plate-dir_arc-plus-w-30mm-and-sega-2p-nine.scad>
use <misc/decorative-plate-dir_arc-plus-w-30mm-and-sega-2p-plus-one.scad>
use <misc/decorative-plate-dir_arc-plus-w-30mm-and-sega-2p-plus-one-plates.scad>
use <misc/dustwasher-lsx-nobi.scad>
top_panel_color = "purple";
bottom_panel_color = "black";
frame_front_color = "black";
frame_back_color = "black";
frame_side_color = "red";
top_deco_color = "white";
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_control_panel_with_mount();
color(frame_side_color) translate([-frame_x/2+4, 0, -2.5]) side_trapezoid_extended_to_front_frame_piece();
color(frame_side_color) translate([frame_x/2-4, 0, -2.5]) mirror([1, 0, 0]) side_trapezoid_extended_to_front_frame_piece();
color(frame_front_color) translate([-frame_x/2+4, 0, -2.5]) front_or_back_trapezoid_frame_piece();
color(frame_front_color) translate([frame_x/2-4, 0, -2.5]) front_or_back_trapezoid_frame_piece();
color(frame_back_color) translate([-frame_x/2+4, 0, -2.5]) rotate([180, 0, 0]) front_or_back_aux_and_neutrik_frame_piece();
color(frame_back_color) translate([frame_x/2-4, 0, -2.5]) rotate([180, 180, 0]) front_or_back_aux_and_neutrik_frame_piece();
color(top_panel_color) translate([panel_x/2, 0, frame_z/2-panel_z+0.01]) sega_2p_plus_one_plus_control_panel_with_mount();
color(frame_side_color) translate([-frame_x/2+4, 0, -2.5]) extra_extended_left_or_right_frame_piece();
color(frame_side_color) translate([frame_x/2-4, 0, -2.5]) mirror([1, 0, 0]) extra_extended_left_or_right_frame_piece();
color(frame_top_bottom_color) translate([-frame_x/2+4, 0, -2.5]) extended_front_or_back_frame_piece();
color(frame_top_bottom_color) translate([frame_x/2-4, 0, -2.5]) extended_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_box_frame_piece_for_extended_side();
color(frame_top_bottom_color) translate([frame_x/2-4, 0, -2.5]) rotate([180, 180, 0]) front_or_back_aux_and_neutrik_box_frame_piece_for_extended_side();
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([0, 0, 3+frame_z/2-4]) dir_arc_plus_w_30mm_and_sega_2p_plus_one_decorative_plate_of_plates(); */
color(top_deco_color) translate([0, 0, 3+frame_z/2-panel_z]) dir_arc_plus_w_30mm_and_sega_2p_plus_one_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();

View File

@ -1,28 +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 <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 <misc/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();

View File

@ -5,37 +5,31 @@
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 <frames/complete/left-frame.scad>
use <frames/pieces/box/side.scad>
use <frames/pieces/box/front-or-back.scad>
use <frames/pieces/box/front-or-back-aux-and-neutrik.scad>
use <panels/inset/lever-and-dir_arc-plus-w-30mm-panel.scad>
use <panels/inset/sega-2p-nine-plus-control-panel-with-mount.scad>
use <panels/inset/sega-2p-plus-one-plus-control-panel-with-mount.scad>
use <misc/decorative-plate-24mm-button.scad>
use <misc/decorative-plate-dir_arc-plus-w-30mm-and-sega-2p-nine.scad>
use <misc/decorative-plate-dir_arc-plus-w-30mm-and-sega-2p-plus-one.scad>
use <misc/decorative-plate-dir_arc-plus-w-30mm-and-sega-2p-plus-one-plates.scad>
use <misc/dustwasher-lsx-nobi.scad>
use <misc/decorative-corner.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_dir_arc_w_30mm_panel();
color(panel_color) translate([panel_x/2, 0, frame_z/2-panel_z/2+0.001]) sega_2p_nine_plus_control_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]) front_or_back_frame_piece();
color(base_color) translate([-panel_x/2, 0, 0]) 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(panel_color) translate([-panel_x/2, 0, frame_z/2-panel_z+0.01]) lever_and_dir_arc_w_30mm_panel();
color(panel_color) translate([panel_x/2, 0, frame_z/2-panel_z+0.01]) sega_2p_plus_one_plus_control_panel_with_mount();
color(base_color) translate([-frame_x/2+5, 0, -2.5]) left_frame();
color(base_color) translate([panel_x/2, 0, -2.5]) rotate([0, 180, 0]) side_box_frame_piece();
color(base_color) translate([panel_x/2, 0, -2.5]) front_or_back_box_frame_piece();
color(base_color) translate([panel_x/2, 0, -2.5]) rotate([180, 180, 0]) front_or_back_aux_and_neutrik_box_frame_piece();
color(base_color) translate([-panel_x/2, 0, -5-frame_z/2+5]) panel();
color(base_color) translate([panel_x/2, 0, -5-frame_z/2+5]) panel();
color(brace_color) translate([-panel_x/2, 0, 0]) decorative_corner();
color(brace_color) mirror([1, 0, 0]) translate([-panel_x/2, 0, 0]) decorative_corner();
color(brace_color) mirror([0, 1, 0]) translate([-panel_x/2, 0, 0]) decorative_corner();
color(brace_color) mirror([1, 0, 0]) mirror([0, 1, 0]) translate([-panel_x/2, 0, 0]) decorative_corner();
color(top_deco_color) translate([0, 0, 4+frame_z/2-panel_z/2+0.001]) dir_arc_plus_w_30mm_and_sega_2p_nine_decorative_plate();
color(top_deco_color) translate([-170, 20, 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();
/* color(top_deco_color) translate([0, 0, 3+frame_z/2-4]) dir_arc_plus_w_30mm_and_sega_2p_plus_one_decorative_plate_of_plates(); */
color(top_deco_color) translate([0, 0, 3+frame_z/2-panel_z]) dir_arc_plus_w_30mm_and_sega_2p_plus_one_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();

View File

@ -6,29 +6,29 @@
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 <frames/pieces/box/side.scad>
use <frames/pieces/box/front-or-back.scad>
use <frames/pieces/box/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-control-panel-with-mount.scad>
use <panels/overhang/right-sega-2p-plus-one-plus-control-panel-with-mount.scad>
use <panels/overhang/left-or-right-panel.scad>
use <misc/decorative-plate-24mm-button.scad>
use <misc/decorative-plate-dir_arc-plus-w-30mm-and-sega-2p-nine.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]) 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_control_right_overhang_panel_with_mount();
color("black") translate([-frame_x/2+5-25, -55, -2.5]) front_or_back_frame_piece();
color("black") rotate([0, 180, 0]) translate([-frame_x/2+5-25, -55, -2.5]) 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("#C12E1F") translate([panel_x/2+25, 0, frame_z/2+75]) sega_2p_plus_one_plus_control_right_overhang_panel_with_mount();
color("black") translate([-frame_x/2+5-25, -55, -2.5]) front_or_back_box_frame_piece();
color("black") rotate([0, 180, 0]) translate([-frame_x/2+5-25, -55, -2.5]) front_or_back_box_frame_piece();
color("black") translate([-frame_x/2+5-50, 0, -2.5]) side_box_frame_piece();
color("black") rotate([0, 180, 0]) translate([-frame_x/2+5-50, 0, -2.5]) side_box_frame_piece();
color("black") rotate([180, 0, 0]) translate([-frame_x/2+5-25, -55, -2.5]) front_or_back_aux_and_neutrik_box_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_box_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([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();

View File

@ -1,11 +1,54 @@
# The Buildable Stick System
Files for 3D printing an arcade stick. See `README.md` for the core documentation, this file is specific to distributed
objects.
Files for 3D printing an arcade stick.
## Attribution
## Objects
### Author and Licensing
The following notes document the objects in the Buildable Stick System and how you can use them:
* `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/`
* `box/` --- 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.
* `extended/` --- the frame walls are pulled out to create MCZ TE-style extended sides. Rather than getting a
box look, you get a longer slab with nice bevels. These look nice, but slightly fiddily to print (and of
course need more material) --- watch your surface adhesion.
* `interconnect` --- complete frames are bolted to one another, but for frame pieces, there is an interconnect
that stands in for the joined inner wall. 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. These work equally well with box or extended frames, and aside from using up a bit of the space
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.
* `misc/`
* Pieces that I haven't organized better (yet) --- there are 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.
* `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.
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
Written by and copyright Brian S. Stephan (<bss@incorporeal.org>).
@ -28,22 +71,9 @@ 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].

View File

@ -1,48 +1,12 @@
# Assembly and Tips
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 (`misc/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 `misc/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 `misc/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.
`misc/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. `misc/dustwasher-jlf.stl`.
Just some miscellaneous notes for any dear reader, or more likely, my own forgetful self.
## 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.
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.
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
@ -70,3 +34,19 @@ following is the most consistent way I've found to put one together.
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: 416 KiB

View File

@ -4,19 +4,10 @@ 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 25% gyroid sparse infill. This gives the models a bit more weight and
My preferred settings are 3 wall loops with 20% 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
@ -29,36 +20,15 @@ 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.
Some specific parts are worth some additional notes:
* **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.
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.
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.
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.
## Materials

53
pyproject.toml Normal file
View File

@ -0,0 +1,53 @@
[build-system]
requires = ["setuptools>=61.0", "setuptools_scm[toml]>=6.2"]
build-backend = "setuptools.build_meta"
[project]
name = "buildable-stick-system"
description = "Files for 3D printing an arcade stick."
readme = "README.md"
license = {text = "GPL-3.0-or-later"}
authors = [
{name = "Brian S. Stephan", email = "bss@incorporeal.org"},
]
requires-python = "<3.12,>=3.9"
dependencies = ["build123d"]
dynamic = ["version"]
classifiers = [
# TODO
]
[project.urls]
# TODO
[project.optional-dependencies]
dev = ["bandit", "flake8", "flake8-blind-except", "flake8-builtins", "flake8-docstrings",
"flake8-executable", "flake8-fixme", "flake8-isort", "flake8-logging-format", "flake8-mutable",
"flake8-pyproject", "mypy", "pip-tools", "pytest", "pytest-asyncio", "pytest-cov", "reuse",
"setuptools-scm", "tox", "twine"]
gui = ["cadquery>=2.2", "CQ-Editor@git+https://github.com/jdegenstein/jmwright-CQ-Editor"]
[project.scripts]
# TODO
[tool.flake8]
enable-extensions = "G,M"
exclude = [".tox/", "venv/", "_version.py", "tests/test-files/"]
extend-ignore = "T101"
max-complexity = 10
max-line-length = 120
[tool.isort]
line_length = 120
[tool.mypy]
ignore_missing_imports = true
[tool.pytest]
python_files = ["*_tests.py", "tests.py", "test_*.py"]
[tool.setuptools]
# TODO
[tool.setuptools_scm]
# TODO

View File

@ -0,0 +1,644 @@
#
# This file is autogenerated by pip-compile with Python 3.11
# by the following command:
#
# pip-compile --extra=dev --extra=gui --output-file=requirements/requirements-dev-and-gui.txt
#
alabaster==0.7.16
# via sphinx
anytree==2.12.1
# via build123d
arrow==1.3.0
# via cookiecutter
astroid==3.2.2
# via pylint
asttokens==2.4.1
# via stack-data
atomicwrites==1.4.1
# via spyder
attrs==23.2.0
# via
# jsonschema
# referencing
autopep8==2.0.4
# via python-lsp-server
babel==2.15.0
# via sphinx
backports-tarfile==1.2.0
# via jaraco-context
bandit==1.7.9
# via buildable-stick-system (pyproject.toml)
beautifulsoup4==4.12.3
# via nbconvert
binaryornot==0.4.4
# via
# cookiecutter
# reuse
black==24.4.2
# via python-lsp-black
bleach==6.1.0
# via nbconvert
boolean-py==4.0
# via
# license-expression
# reuse
build==1.2.1
# via pip-tools
build123d==0.4.0
# via buildable-stick-system (pyproject.toml)
cachetools==5.3.3
# via tox
cadquery==2.4.0
# via buildable-stick-system (pyproject.toml)
cadquery-ocp==7.7.2
# via
# build123d
# cadquery
# ocpsvg
casadi==3.6.5
# via cadquery
certifi==2024.6.2
# via requests
cffi==1.16.0
# via cryptography
chardet==5.2.0
# via
# binaryornot
# python-debian
# spyder
# tox
charset-normalizer==3.3.2
# via requests
click==8.1.7
# via
# black
# cookiecutter
# pip-tools
cloudpickle==3.0.0
# via
# spyder
# spyder-kernels
colorama==0.4.6
# via tox
comm==0.2.2
# via ipykernel
cookiecutter==2.6.0
# via spyder
coverage[toml]==7.5.4
# via pytest-cov
cq-editor @ git+https://github.com/jdegenstein/jmwright-CQ-Editor
# via buildable-stick-system (pyproject.toml)
cryptography==42.0.8
# via secretstorage
debugpy==1.8.2
# via ipykernel
decorator==5.1.1
# via ipython
defusedxml==0.7.1
# via nbconvert
diff-match-patch==20230430
# via
# spyder
# three-merge
dill==0.3.8
# via pylint
distlib==0.3.8
# via virtualenv
docstring-to-markdown==0.15
# via python-lsp-server
docutils==0.21.2
# via
# readme-renderer
# sphinx
executing==2.0.1
# via stack-data
ezdxf==1.3.1
# via
# build123d
# cadquery
fastjsonschema==2.20.0
# via nbformat
filelock==3.15.4
# via
# tox
# virtualenv
flake8==7.0.0
# via
# buildable-stick-system (pyproject.toml)
# flake8-builtins
# flake8-docstrings
# flake8-executable
# flake8-isort
# flake8-mutable
# flake8-pyproject
# python-lsp-server
flake8-blind-except==0.2.1
# via buildable-stick-system (pyproject.toml)
flake8-builtins==2.5.0
# via buildable-stick-system (pyproject.toml)
flake8-docstrings==1.7.0
# via buildable-stick-system (pyproject.toml)
flake8-executable==2.1.3
# via buildable-stick-system (pyproject.toml)
flake8-fixme==1.1.1
# via buildable-stick-system (pyproject.toml)
flake8-isort==6.1.1
# via buildable-stick-system (pyproject.toml)
flake8-logging-format==2024.24.12
# via buildable-stick-system (pyproject.toml)
flake8-mutable==1.2.0
# via buildable-stick-system (pyproject.toml)
flake8-pyproject==1.2.3
# via buildable-stick-system (pyproject.toml)
fonttools==4.53.0
# via ezdxf
idna==3.7
# via requests
imagesize==1.4.1
# via sphinx
importlib-metadata==8.0.0
# via
# keyring
# twine
# yapf
inflection==0.5.1
# via qstylizer
iniconfig==2.0.0
# via pytest
intervaltree==3.1.0
# via spyder
ipykernel==6.29.5
# via
# qtconsole
# spyder-kernels
ipython==8.26.0
# via
# build123d
# cq-editor
# ipykernel
# spyder
# spyder-kernels
isort==5.13.2
# via
# flake8-isort
# pylint
jaraco-classes==3.4.0
# via keyring
jaraco-context==5.3.0
# via keyring
jaraco-functools==4.0.1
# via keyring
jedi==0.19.1
# via
# ipython
# python-lsp-server
# spyder
jeepney==0.8.0
# via
# keyring
# secretstorage
jellyfish==1.0.4
# via spyder
jinja2==3.1.4
# via
# cookiecutter
# nbconvert
# reuse
# sphinx
jsonschema==4.22.0
# via
# nbformat
# spyder
jsonschema-specifications==2023.12.1
# via jsonschema
jupyter-client==8.6.2
# via
# ipykernel
# nbclient
# qtconsole
# spyder-kernels
jupyter-core==5.7.2
# via
# ipykernel
# jupyter-client
# nbclient
# nbconvert
# nbformat
# qtconsole
jupyterlab-pygments==0.3.0
# via nbconvert
keyring==25.2.1
# via
# spyder
# twine
license-expression==30.3.0
# via reuse
logbook==1.7.0.post0
# via cq-editor
markdown-it-py==3.0.0
# via rich
markupsafe==2.1.5
# via
# jinja2
# nbconvert
matplotlib-inline==0.1.7
# via
# ipykernel
# ipython
mccabe==0.7.0
# via
# flake8
# pylint
# python-lsp-server
mdurl==0.1.2
# via markdown-it-py
mistune==3.0.2
# via nbconvert
more-itertools==10.3.0
# via
# jaraco-classes
# jaraco-functools
multimethod==1.9.1
# via cadquery
mypy==1.10.1
# via buildable-stick-system (pyproject.toml)
mypy-extensions==1.0.0
# via
# black
# mypy
nbclient==0.10.0
# via nbconvert
nbconvert==7.16.4
# via spyder
nbformat==5.10.4
# via
# nbclient
# nbconvert
nest-asyncio==1.6.0
# via ipykernel
nh3==0.2.17
# via readme-renderer
nlopt==2.7.1
# via cadquery
nptyping==2.0.1
# via cadquery
numpy==1.26.4
# via
# build123d
# casadi
# ezdxf
# nlopt
# nptyping
# numpy-stl
# pyqtgraph
# scipy
# svgpathtools
numpy-stl==3.1.1
# via build123d
numpydoc==1.7.0
# via spyder
ocpsvg==0.2.1
# via build123d
packaging==24.1
# via
# black
# build
# ipykernel
# nbconvert
# pyproject-api
# pytest
# pytoolconfig
# qtconsole
# qtpy
# setuptools-scm
# sphinx
# tox
pandocfilters==1.5.1
# via nbconvert
parso==0.8.4
# via
# jedi
# spyder
path==16.14.0
# via
# cadquery
# cq-editor
pathspec==0.12.1
# via black
pbr==6.0.0
# via stevedore
pexpect==4.9.0
# via
# ipython
# spyder
pickleshare==0.7.5
# via spyder
pip-tools==7.4.1
# via buildable-stick-system (pyproject.toml)
pkginfo==1.10.0
# via twine
platformdirs==4.2.2
# via
# black
# jupyter-core
# pylint
# pytoolconfig
# tox
# virtualenv
# yapf
pluggy==1.5.0
# via
# pytest
# python-lsp-server
# tox
prompt-toolkit==3.0.47
# via ipython
psutil==6.0.0
# via
# ipykernel
# spyder
ptyprocess==0.7.0
# via pexpect
pure-eval==0.2.2
# via stack-data
py-lib3mf==2.3.1
# via build123d
pycodestyle==2.11.1
# via
# autopep8
# flake8
# python-lsp-server
pycparser==2.22
# via cffi
pydocstyle==6.3.0
# via
# flake8-docstrings
# python-lsp-server
pyflakes==3.2.0
# via
# flake8
# python-lsp-server
pygments==2.18.0
# via
# ipython
# nbconvert
# qtconsole
# readme-renderer
# rich
# sphinx
# spyder
pylint==3.2.5
# via
# python-lsp-server
# spyder
pylint-venv==3.0.3
# via spyder
pyls-spyder==0.4.0
# via spyder
pyparsing==3.1.2
# via ezdxf
pyproject-api==1.7.1
# via tox
pyproject-hooks==1.1.0
# via
# build
# pip-tools
pyqt5==5.15.10
# via
# cq-editor
# pyqtwebengine
# spyder
pyqt5-qt5==5.15.14
# via pyqt5
pyqt5-sip==12.13.0
# via
# pyqt5
# pyqtwebengine
pyqtgraph==0.13.7
# via cq-editor
pyqtwebengine==5.15.6
# via spyder
pyqtwebengine-qt5==5.15.14
# via pyqtwebengine
pytest==8.2.2
# via
# buildable-stick-system (pyproject.toml)
# pytest-asyncio
# pytest-cov
pytest-asyncio==0.23.7
# via buildable-stick-system (pyproject.toml)
pytest-cov==5.0.0
# via buildable-stick-system (pyproject.toml)
python-dateutil==2.9.0.post0
# via
# arrow
# jupyter-client
python-debian==0.1.49
# via reuse
python-lsp-black==2.0.0
# via spyder
python-lsp-jsonrpc==1.1.2
# via python-lsp-server
python-lsp-server[all]==1.11.0
# via
# pyls-spyder
# python-lsp-black
# spyder
python-slugify==8.0.4
# via cookiecutter
python-utils==3.8.2
# via numpy-stl
pytoolconfig[global]==1.3.1
# via rope
pyxdg==0.28
# via spyder
pyyaml==6.0.1
# via
# bandit
# cookiecutter
pyzmq==26.0.3
# via
# ipykernel
# jupyter-client
# qtconsole
# spyder
# spyder-kernels
qdarkstyle==3.2.3
# via spyder
qstylizer==0.2.3
# via spyder
qtawesome==1.3.1
# via spyder
qtconsole==5.5.2
# via spyder
qtpy==2.4.1
# via
# qdarkstyle
# qtawesome
# qtconsole
# spyder
readme-renderer==43.0
# via twine
referencing==0.35.1
# via
# jsonschema
# jsonschema-specifications
requests==2.32.3
# via
# cookiecutter
# cq-editor
# requests-toolbelt
# sphinx
# twine
requests-toolbelt==1.0.0
# via twine
reuse==3.0.2
# via buildable-stick-system (pyproject.toml)
rfc3986==2.0.0
# via twine
rich==13.7.1
# via
# bandit
# cookiecutter
# twine
rope==1.13.0
# via python-lsp-server
rpds-py==0.18.1
# via
# jsonschema
# referencing
rtree==1.2.0
# via spyder
scipy==1.14.0
# via svgpathtools
secretstorage==3.3.3
# via keyring
setuptools-scm==8.1.0
# via buildable-stick-system (pyproject.toml)
six==1.16.0
# via
# anytree
# asttokens
# bleach
# python-dateutil
snowballstemmer==2.2.0
# via
# pydocstyle
# sphinx
sortedcontainers==2.4.0
# via intervaltree
soupsieve==2.5
# via beautifulsoup4
sphinx==7.3.7
# via
# numpydoc
# spyder
sphinxcontrib-applehelp==1.0.8
# via sphinx
sphinxcontrib-devhelp==1.0.6
# via sphinx
sphinxcontrib-htmlhelp==2.0.5
# via sphinx
sphinxcontrib-jsmath==1.0.1
# via sphinx
sphinxcontrib-qthelp==1.0.7
# via sphinx
sphinxcontrib-serializinghtml==1.1.10
# via sphinx
spyder==5.5.5
# via cq-editor
spyder-kernels==2.5.2
# via spyder
stack-data==0.6.3
# via ipython
stevedore==5.2.0
# via bandit
svgelements==1.9.6
# via ocpsvg
svgpathtools==1.6.1
# via
# build123d
# ocpsvg
svgwrite==1.4.3
# via svgpathtools
tabulate==0.9.0
# via numpydoc
text-unidecode==1.3
# via python-slugify
textdistance==4.6.2
# via spyder
three-merge==0.1.1
# via spyder
tinycss2==1.3.0
# via
# nbconvert
# qstylizer
tomli==2.0.1
# via yapf
tomlkit==0.12.5
# via pylint
tornado==6.4.1
# via
# ipykernel
# jupyter-client
tox==4.15.1
# via buildable-stick-system (pyproject.toml)
traitlets==5.14.3
# via
# comm
# ipykernel
# ipython
# jupyter-client
# jupyter-core
# matplotlib-inline
# nbclient
# nbconvert
# nbformat
# qtconsole
trianglesolver==1.2
# via build123d
twine==5.1.1
# via buildable-stick-system (pyproject.toml)
types-python-dateutil==2.9.0.20240316
# via arrow
typing-extensions==4.12.2
# via
# build123d
# ezdxf
# ipython
# mypy
# python-utils
typish==1.9.3
# via cadquery
ujson==5.10.0
# via
# python-lsp-jsonrpc
# python-lsp-server
urllib3==2.2.2
# via
# requests
# twine
virtualenv==20.26.3
# via tox
watchdog==4.0.1
# via spyder
wcwidth==0.2.13
# via prompt-toolkit
webencodings==0.5.1
# via
# bleach
# tinycss2
whatthepatch==1.0.5
# via python-lsp-server
wheel==0.43.0
# via pip-tools
wurlitzer==3.1.1
# via spyder-kernels
yapf==0.40.2
# via python-lsp-server
zipp==3.19.2
# via importlib-metadata
# The following packages are considered to be unsafe in a requirements file:
# pip
# setuptools

View File

@ -0,0 +1,295 @@
#
# This file is autogenerated by pip-compile with Python 3.11
# by the following command:
#
# pip-compile --extra=dev --output-file=requirements/requirements-dev.txt
#
anytree==2.12.1
# via build123d
asttokens==2.4.1
# via stack-data
backports-tarfile==1.2.0
# via jaraco-context
bandit==1.7.9
# via buildable-stick-system (pyproject.toml)
binaryornot==0.4.4
# via reuse
boolean-py==4.0
# via
# license-expression
# reuse
build==1.2.1
# via pip-tools
build123d==0.5.0
# via buildable-stick-system (pyproject.toml)
cachetools==5.3.3
# via tox
cadquery-ocp==7.7.2
# via
# build123d
# ocpsvg
certifi==2024.6.2
# via requests
cffi==1.16.0
# via cryptography
chardet==5.2.0
# via
# binaryornot
# python-debian
# tox
charset-normalizer==3.3.2
# via requests
click==8.1.7
# via pip-tools
colorama==0.4.6
# via tox
coverage[toml]==7.5.4
# via pytest-cov
cryptography==42.0.8
# via secretstorage
decorator==5.1.1
# via ipython
distlib==0.3.8
# via virtualenv
docutils==0.21.2
# via readme-renderer
executing==2.0.1
# via stack-data
ezdxf==1.3.1
# via build123d
filelock==3.15.4
# via
# tox
# virtualenv
flake8==7.1.0
# via
# buildable-stick-system (pyproject.toml)
# flake8-builtins
# flake8-docstrings
# flake8-executable
# flake8-isort
# flake8-mutable
# flake8-pyproject
flake8-blind-except==0.2.1
# via buildable-stick-system (pyproject.toml)
flake8-builtins==2.5.0
# via buildable-stick-system (pyproject.toml)
flake8-docstrings==1.7.0
# via buildable-stick-system (pyproject.toml)
flake8-executable==2.1.3
# via buildable-stick-system (pyproject.toml)
flake8-fixme==1.1.1
# via buildable-stick-system (pyproject.toml)
flake8-isort==6.1.1
# via buildable-stick-system (pyproject.toml)
flake8-logging-format==2024.24.12
# via buildable-stick-system (pyproject.toml)
flake8-mutable==1.2.0
# via buildable-stick-system (pyproject.toml)
flake8-pyproject==1.2.3
# via buildable-stick-system (pyproject.toml)
fonttools==4.53.0
# via ezdxf
idna==3.7
# via requests
importlib-metadata==8.0.0
# via
# keyring
# twine
iniconfig==2.0.0
# via pytest
ipython==8.26.0
# via build123d
isort==5.13.2
# via flake8-isort
jaraco-classes==3.4.0
# via keyring
jaraco-context==5.3.0
# via keyring
jaraco-functools==4.0.1
# via keyring
jedi==0.19.1
# via ipython
jeepney==0.8.0
# via
# keyring
# secretstorage
jinja2==3.1.4
# via reuse
keyring==25.2.1
# via twine
license-expression==30.3.0
# via reuse
markdown-it-py==3.0.0
# via rich
markupsafe==2.1.5
# via jinja2
matplotlib-inline==0.1.7
# via ipython
mccabe==0.7.0
# via flake8
mdurl==0.1.2
# via markdown-it-py
more-itertools==10.3.0
# via
# jaraco-classes
# jaraco-functools
mypy==1.10.1
# via buildable-stick-system (pyproject.toml)
mypy-extensions==1.0.0
# via mypy
nh3==0.2.17
# via readme-renderer
numpy==1.26.4
# via
# build123d
# ezdxf
# numpy-stl
# scipy
# svgpathtools
numpy-stl==3.1.1
# via build123d
ocpsvg==0.2.1
# via build123d
packaging==24.1
# via
# build
# pyproject-api
# pytest
# setuptools-scm
# tox
parso==0.8.4
# via jedi
pbr==6.0.0
# via stevedore
pexpect==4.9.0
# via ipython
pip-tools==7.4.1
# via buildable-stick-system (pyproject.toml)
pkginfo==1.10.0
# via twine
platformdirs==4.2.2
# via
# tox
# virtualenv
pluggy==1.5.0
# via
# pytest
# tox
prompt-toolkit==3.0.47
# via ipython
ptyprocess==0.7.0
# via pexpect
pure-eval==0.2.2
# via stack-data
py-lib3mf==2.3.1
# via build123d
pycodestyle==2.12.0
# via flake8
pycparser==2.22
# via cffi
pydocstyle==6.3.0
# via flake8-docstrings
pyflakes==3.2.0
# via flake8
pygments==2.18.0
# via
# ipython
# readme-renderer
# rich
pyparsing==3.1.2
# via ezdxf
pyproject-api==1.7.1
# via tox
pyproject-hooks==1.1.0
# via
# build
# pip-tools
pytest==8.2.2
# via
# buildable-stick-system (pyproject.toml)
# pytest-asyncio
# pytest-cov
pytest-asyncio==0.23.7
# via buildable-stick-system (pyproject.toml)
pytest-cov==5.0.0
# via buildable-stick-system (pyproject.toml)
python-debian==0.1.49
# via reuse
python-utils==3.8.2
# via numpy-stl
pyyaml==6.0.1
# via bandit
readme-renderer==43.0
# via twine
requests==2.32.3
# via
# requests-toolbelt
# twine
requests-toolbelt==1.0.0
# via twine
reuse==3.0.2
# via buildable-stick-system (pyproject.toml)
rfc3986==2.0.0
# via twine
rich==13.7.1
# via
# bandit
# twine
scipy==1.14.0
# via svgpathtools
secretstorage==3.3.3
# via keyring
setuptools-scm==8.1.0
# via buildable-stick-system (pyproject.toml)
six==1.16.0
# via
# anytree
# asttokens
snowballstemmer==2.2.0
# via pydocstyle
stack-data==0.6.3
# via ipython
stevedore==5.2.0
# via bandit
svgelements==1.9.6
# via ocpsvg
svgpathtools==1.6.1
# via
# build123d
# ocpsvg
svgwrite==1.4.3
# via svgpathtools
tox==4.15.1
# via buildable-stick-system (pyproject.toml)
traitlets==5.14.3
# via
# ipython
# matplotlib-inline
trianglesolver==1.2
# via build123d
twine==5.1.1
# via buildable-stick-system (pyproject.toml)
typing-extensions==4.12.2
# via
# build123d
# ezdxf
# ipython
# mypy
# python-utils
urllib3==2.2.2
# via
# requests
# twine
virtualenv==20.26.3
# via tox
wcwidth==0.2.13
# via prompt-toolkit
wheel==0.43.0
# via pip-tools
zipp==3.19.2
# via importlib-metadata
# The following packages are considered to be unsafe in a requirements file:
# pip
# setuptools

View File

@ -0,0 +1,508 @@
#
# This file is autogenerated by pip-compile with Python 3.11
# by the following command:
#
# pip-compile --extra=gui --output-file=requirements/requirements-gui.txt
#
alabaster==0.7.16
# via sphinx
anytree==2.12.1
# via build123d
arrow==1.3.0
# via cookiecutter
astroid==3.2.2
# via pylint
asttokens==2.4.1
# via stack-data
atomicwrites==1.4.1
# via spyder
attrs==23.2.0
# via
# jsonschema
# referencing
autopep8==2.0.4
# via python-lsp-server
babel==2.15.0
# via sphinx
backports-tarfile==1.2.0
# via jaraco-context
beautifulsoup4==4.12.3
# via nbconvert
binaryornot==0.4.4
# via cookiecutter
black==24.4.2
# via python-lsp-black
bleach==6.1.0
# via nbconvert
build123d==0.5.0
# via buildable-stick-system (pyproject.toml)
cadquery==2.4.0
# via buildable-stick-system (pyproject.toml)
cadquery-ocp==7.7.2
# via
# build123d
# cadquery
# ocpsvg
casadi==3.6.5
# via cadquery
certifi==2024.6.2
# via requests
cffi==1.16.0
# via cryptography
chardet==5.2.0
# via
# binaryornot
# spyder
charset-normalizer==3.3.2
# via requests
click==8.1.7
# via
# black
# cookiecutter
cloudpickle==3.0.0
# via
# spyder
# spyder-kernels
comm==0.2.2
# via ipykernel
cookiecutter==2.6.0
# via spyder
cq-editor @ git+https://github.com/jdegenstein/jmwright-CQ-Editor
# via buildable-stick-system (pyproject.toml)
cryptography==42.0.8
# via secretstorage
debugpy==1.8.2
# via ipykernel
decorator==5.1.1
# via ipython
defusedxml==0.7.1
# via nbconvert
diff-match-patch==20230430
# via
# spyder
# three-merge
dill==0.3.8
# via pylint
docstring-to-markdown==0.15
# via python-lsp-server
docutils==0.21.2
# via sphinx
executing==2.0.1
# via stack-data
ezdxf==1.3.1
# via
# build123d
# cadquery
fastjsonschema==2.20.0
# via nbformat
flake8==7.0.0
# via python-lsp-server
fonttools==4.53.0
# via ezdxf
idna==3.7
# via requests
imagesize==1.4.1
# via sphinx
importlib-metadata==8.0.0
# via
# keyring
# yapf
inflection==0.5.1
# via qstylizer
intervaltree==3.1.0
# via spyder
ipykernel==6.29.5
# via
# qtconsole
# spyder-kernels
ipython==8.26.0
# via
# build123d
# cq-editor
# ipykernel
# spyder
# spyder-kernels
isort==5.13.2
# via pylint
jaraco-classes==3.4.0
# via keyring
jaraco-context==5.3.0
# via keyring
jaraco-functools==4.0.1
# via keyring
jedi==0.19.1
# via
# ipython
# python-lsp-server
# spyder
jeepney==0.8.0
# via
# keyring
# secretstorage
jellyfish==1.0.4
# via spyder
jinja2==3.1.4
# via
# cookiecutter
# nbconvert
# sphinx
jsonschema==4.22.0
# via
# nbformat
# spyder
jsonschema-specifications==2023.12.1
# via jsonschema
jupyter-client==8.6.2
# via
# ipykernel
# nbclient
# qtconsole
# spyder-kernels
jupyter-core==5.7.2
# via
# ipykernel
# jupyter-client
# nbclient
# nbconvert
# nbformat
# qtconsole
jupyterlab-pygments==0.3.0
# via nbconvert
keyring==25.2.1
# via spyder
logbook==1.7.0.post0
# via cq-editor
markdown-it-py==3.0.0
# via rich
markupsafe==2.1.5
# via
# jinja2
# nbconvert
matplotlib-inline==0.1.7
# via
# ipykernel
# ipython
mccabe==0.7.0
# via
# flake8
# pylint
# python-lsp-server
mdurl==0.1.2
# via markdown-it-py
mistune==3.0.2
# via nbconvert
more-itertools==10.3.0
# via
# jaraco-classes
# jaraco-functools
multimethod==1.9.1
# via cadquery
mypy-extensions==1.0.0
# via black
nbclient==0.10.0
# via nbconvert
nbconvert==7.16.4
# via spyder
nbformat==5.10.4
# via
# nbclient
# nbconvert
nest-asyncio==1.6.0
# via ipykernel
nlopt==2.7.1
# via cadquery
nptyping==2.0.1
# via cadquery
numpy==1.26.4
# via
# build123d
# casadi
# ezdxf
# nlopt
# nptyping
# numpy-stl
# pyqtgraph
# scipy
# svgpathtools
numpy-stl==3.1.1
# via build123d
numpydoc==1.7.0
# via spyder
ocpsvg==0.2.1
# via build123d
packaging==24.1
# via
# black
# ipykernel
# nbconvert
# pytoolconfig
# qtconsole
# qtpy
# sphinx
pandocfilters==1.5.1
# via nbconvert
parso==0.8.4
# via
# jedi
# spyder
path==16.14.0
# via
# cadquery
# cq-editor
pathspec==0.12.1
# via black
pexpect==4.9.0
# via
# ipython
# spyder
pickleshare==0.7.5
# via spyder
platformdirs==4.2.2
# via
# black
# jupyter-core
# pylint
# pytoolconfig
# yapf
pluggy==1.5.0
# via python-lsp-server
prompt-toolkit==3.0.47
# via ipython
psutil==6.0.0
# via
# ipykernel
# spyder
ptyprocess==0.7.0
# via pexpect
pure-eval==0.2.2
# via stack-data
py-lib3mf==2.3.1
# via build123d
pycodestyle==2.11.1
# via
# autopep8
# flake8
# python-lsp-server
pycparser==2.22
# via cffi
pydocstyle==6.3.0
# via python-lsp-server
pyflakes==3.2.0
# via
# flake8
# python-lsp-server
pygments==2.18.0
# via
# ipython
# nbconvert
# qtconsole
# rich
# sphinx
# spyder
pylint==3.2.5
# via
# python-lsp-server
# spyder
pylint-venv==3.0.3
# via spyder
pyls-spyder==0.4.0
# via spyder
pyparsing==3.1.2
# via ezdxf
pyqt5==5.15.10
# via
# cq-editor
# pyqtwebengine
# spyder
pyqt5-qt5==5.15.14
# via pyqt5
pyqt5-sip==12.13.0
# via
# pyqt5
# pyqtwebengine
pyqtgraph==0.13.7
# via cq-editor
pyqtwebengine==5.15.6
# via spyder
pyqtwebengine-qt5==5.15.14
# via pyqtwebengine
python-dateutil==2.9.0.post0
# via
# arrow
# jupyter-client
python-lsp-black==2.0.0
# via spyder
python-lsp-jsonrpc==1.1.2
# via python-lsp-server
python-lsp-server[all]==1.11.0
# via
# pyls-spyder
# python-lsp-black
# spyder
python-slugify==8.0.4
# via cookiecutter
python-utils==3.8.2
# via numpy-stl
pytoolconfig[global]==1.3.1
# via rope
pyxdg==0.28
# via spyder
pyyaml==6.0.1
# via cookiecutter
pyzmq==26.0.3
# via
# ipykernel
# jupyter-client
# qtconsole
# spyder
# spyder-kernels
qdarkstyle==3.2.3
# via spyder
qstylizer==0.2.3
# via spyder
qtawesome==1.3.1
# via spyder
qtconsole==5.5.2
# via spyder
qtpy==2.4.1
# via
# qdarkstyle
# qtawesome
# qtconsole
# spyder
referencing==0.35.1
# via
# jsonschema
# jsonschema-specifications
requests==2.32.3
# via
# cookiecutter
# cq-editor
# sphinx
rich==13.7.1
# via cookiecutter
rope==1.13.0
# via python-lsp-server
rpds-py==0.18.1
# via
# jsonschema
# referencing
rtree==1.2.0
# via spyder
scipy==1.14.0
# via svgpathtools
secretstorage==3.3.3
# via keyring
six==1.16.0
# via
# anytree
# asttokens
# bleach
# python-dateutil
snowballstemmer==2.2.0
# via
# pydocstyle
# sphinx
sortedcontainers==2.4.0
# via intervaltree
soupsieve==2.5
# via beautifulsoup4
sphinx==7.3.7
# via
# numpydoc
# spyder
sphinxcontrib-applehelp==1.0.8
# via sphinx
sphinxcontrib-devhelp==1.0.6
# via sphinx
sphinxcontrib-htmlhelp==2.0.5
# via sphinx
sphinxcontrib-jsmath==1.0.1
# via sphinx
sphinxcontrib-qthelp==1.0.7
# via sphinx
sphinxcontrib-serializinghtml==1.1.10
# via sphinx
spyder==5.5.5
# via cq-editor
spyder-kernels==2.5.2
# via spyder
stack-data==0.6.3
# via ipython
svgelements==1.9.6
# via ocpsvg
svgpathtools==1.6.1
# via
# build123d
# ocpsvg
svgwrite==1.4.3
# via svgpathtools
tabulate==0.9.0
# via numpydoc
text-unidecode==1.3
# via python-slugify
textdistance==4.6.2
# via spyder
three-merge==0.1.1
# via spyder
tinycss2==1.3.0
# via
# nbconvert
# qstylizer
tomli==2.0.1
# via yapf
tomlkit==0.12.5
# via pylint
tornado==6.4.1
# via
# ipykernel
# jupyter-client
traitlets==5.14.3
# via
# comm
# ipykernel
# ipython
# jupyter-client
# jupyter-core
# matplotlib-inline
# nbclient
# nbconvert
# nbformat
# qtconsole
trianglesolver==1.2
# via build123d
types-python-dateutil==2.9.0.20240316
# via arrow
typing-extensions==4.12.2
# via
# build123d
# ezdxf
# ipython
# python-utils
typish==1.9.3
# via cadquery
ujson==5.10.0
# via
# python-lsp-jsonrpc
# python-lsp-server
urllib3==2.2.2
# via requests
watchdog==4.0.1
# via spyder
wcwidth==0.2.13
# via prompt-toolkit
webencodings==0.5.1
# via
# bleach
# tinycss2
whatthepatch==1.0.5
# via python-lsp-server
wurlitzer==3.1.1
# via spyder-kernels
yapf==0.40.2
# via python-lsp-server
zipp==3.19.2
# via importlib-metadata
# The following packages are considered to be unsafe in a requirements file:
# setuptools

View File

@ -0,0 +1,89 @@
#
# This file is autogenerated by pip-compile with Python 3.11
# by the following command:
#
# pip-compile --output-file=requirements/requirements.txt
#
anytree==2.12.1
# via build123d
asttokens==2.4.1
# via stack-data
build123d==0.5.0
# via buildable-stick-system (pyproject.toml)
cadquery-ocp==7.7.2
# via
# build123d
# ocpsvg
decorator==5.1.1
# via ipython
executing==2.0.1
# via stack-data
ezdxf==1.3.1
# via build123d
fonttools==4.53.0
# via ezdxf
ipython==8.26.0
# via build123d
jedi==0.19.1
# via ipython
matplotlib-inline==0.1.7
# via ipython
numpy==1.26.4
# via
# build123d
# ezdxf
# numpy-stl
# scipy
# svgpathtools
numpy-stl==3.1.1
# via build123d
ocpsvg==0.2.1
# via build123d
parso==0.8.4
# via jedi
pexpect==4.9.0
# via ipython
prompt-toolkit==3.0.47
# via ipython
ptyprocess==0.7.0
# via pexpect
pure-eval==0.2.2
# via stack-data
py-lib3mf==2.3.1
# via build123d
pygments==2.18.0
# via ipython
pyparsing==3.1.2
# via ezdxf
python-utils==3.8.2
# via numpy-stl
scipy==1.14.0
# via svgpathtools
six==1.16.0
# via
# anytree
# asttokens
stack-data==0.6.3
# via ipython
svgelements==1.9.6
# via ocpsvg
svgpathtools==1.6.1
# via
# build123d
# ocpsvg
svgwrite==1.4.3
# via svgpathtools
traitlets==5.14.3
# via
# ipython
# matplotlib-inline
trianglesolver==1.2
# via build123d
typing-extensions==4.12.2
# via
# build123d
# ezdxf
# ipython
# python-utils
wcwidth==0.2.13
# via prompt-toolkit

1
src/bss/__init__.py Normal file
View File

@ -0,0 +1 @@
"""The Buildable Stick System, code to generate arcade stick components."""

68
src/bss/core.py Normal file
View File

@ -0,0 +1,68 @@
"""Shared parameters and foundational objects.
Reminder that the default unit is millimeters.
SPDX-FileCopyrightText: © 2023 Brian S. Stephan <bss@incorporeal.org>
SPDX-License-Identifier: GPL-3.0-or-later
"""
import build123d as bd
####################
# measurements for holes and connectors
####################
HOLE_TOLERANCE = 0.15
M4_BOLT_RADIUS = 2 + HOLE_TOLERANCE
M4_BOLT_COUNTERSINK_RADIUS = M4_BOLT_RADIUS + 2
####################
# basic dimensions necessary for proper object composition
####################
# these are for ONE frame box, not the overall case, which may be composed
# of multiple frames
FRAME_X = 233
FRAME_Y = 208
FRAME_Z = 57
# the "wall" is the space inside the frame that is reserved to make a lip for panels
FRAME_WALL = 4
# panel dimensions for either an inset panel or the inner tray of an overhang panel
PANEL_X = FRAME_X - (FRAME_WALL * 2)
PANEL_Y = FRAME_Y - (FRAME_WALL * 2)
PANEL_Z = 5
# the center point of where the standoff and bolts connecting a panel to a frame go,
# relative to a centered object
PANEL_TO_FRAME_POINT_OFFSET = 10
PANEL_TO_FRAME_POINT_X = (PANEL_X/2) - PANEL_TO_FRAME_POINT_OFFSET
PANEL_TO_FRAME_POINT_Y = (PANEL_Y/2) - PANEL_TO_FRAME_POINT_OFFSET
####################
# commonly used button dimensions
####################
BUTTON_30MM_RADIUS = 15 + HOLE_TOLERANCE
BUTTON_24MM_RADIUS = 12 + HOLE_TOLERANCE
# carve out space for snap-ins
# judgng by https://www.slagcoin.com/joystick/attributes_brands.html 2.5mm is good for everything
BUTTON_SNAP_IN_THICKNESS = 2.5
# make sure the carve out space is also enough for screw-in nuts
# slagcoin has screw-in nut diameter at 36mm for 30mm buttons, 29.5 for 24mm buttons
# radius + value below should leave space for the nut and for fingers to grab the nut
BUTTON_30MM_RADIUS_CONNECTOR_SPACE = 6
####################
# arcade stick parts that are relevant in a number of contexts
####################
class CutoutButtonHole(bd.CounterBoreHole):
"""Use an inverted counter bore hole as the button hole with the extra thin space for snap-ins."""
def __init__(self, radius, **kwargs):
"""Initialize the inverted counter bore hole with the right thinness for e.g. a panel to take snap-ins."""
super().__init__(radius, radius+BUTTON_30MM_RADIUS_CONNECTOR_SPACE, BUTTON_SNAP_IN_THICKNESS, **kwargs)

31
src/bss/layouts.py Normal file
View File

@ -0,0 +1,31 @@
"""Button and other component layouts for use in panels.
SPDX-FileCopyrightText: © 2023 Brian S. Stephan <bss@incorporeal.org>
SPDX-License-Identifier: GPL-3.0-or-later
"""
import build123d as bd
from bss import core
####################
# collected points and related data, to be used to construct a layout
####################
# 3x3, centered on top left (P1) button
SEGA_2P_SIX_BUTTON = {'radius': core.BUTTON_30MM_RADIUS,
'positions': [(0, 0), (30.5, 11 + 9), (30.5 + 36, 11 + 9),
(0, -19 - 9 - 11), (30.5, -19), (30.5 + 36, -19)]}
####################
# Layouts are Locations with extra stuff to document what it is
####################
class Layout(bd.Locations):
"""A set of button positions that can be adjusted relative to some parameters."""
def __init__(self, layout, *args, distance_scale=1.00, **kwargs):
"""Lay out the points for the buttons, etc. but can be scaled."""
self.points = list(map(lambda x: (x[0] * distance_scale, x[1] * distance_scale), layout['positions']))
self.button_radius = layout['radius']
super().__init__(self.points, *args, **kwargs)

45
src/bss/panels.py Normal file
View File

@ -0,0 +1,45 @@
"""The base panel from which all other panels inherit.
SPDX-FileCopyrightText: © 2023 Brian S. Stephan <bss@incorporeal.org>
SPDX-License-Identifier: GPL-3.0-or-later
"""
import logging
import build123d as bd
from bss import core, layouts
logger = logging.getLogger(__name__)
class Panel(bd.BasePartObject):
"""A panel meant to be secured to the top or bottom of a base.
This is a hard box by default as an inset panel will be flush with the frame.
"""
def __init__(self, *args, **kwargs):
"""Create our part."""
with bd.BuildPart() as panel:
bd.Box(core.PANEL_X, core.PANEL_Y, core.PANEL_Z)
logger.info(panel.faces().sort_by(bd.Axis.Z))
with bd.Locations(panel.faces().sort_by(bd.Axis.Z)[-1]):
with bd.Locations((core.PANEL_TO_FRAME_POINT_X, core.PANEL_TO_FRAME_POINT_Y),
(-core.PANEL_TO_FRAME_POINT_X, core.PANEL_TO_FRAME_POINT_Y),
(-core.PANEL_TO_FRAME_POINT_X, -core.PANEL_TO_FRAME_POINT_Y),
(core.PANEL_TO_FRAME_POINT_X, -core.PANEL_TO_FRAME_POINT_Y)):
bd.CounterSinkHole(core.M4_BOLT_RADIUS, core.M4_BOLT_COUNTERSINK_RADIUS)
super().__init__(panel.part, *args, **kwargs)
with bd.BuildPart() as sega_2p_panel:
panel = Panel()
with layouts.Layout(layouts.SEGA_2P_SIX_BUTTON):
with bd.Locations((5, 45)):
with bd.Locations(panel.faces().sort_by(bd.Axis.Z)[0]):
core.CutoutButtonHole(layouts.SEGA_2P_SIX_BUTTON['radius'])
try:
show_object(sega_2p_panel)
except NameError:
pass

View File

@ -11,10 +11,6 @@ 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();
@ -31,25 +27,27 @@ 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=100, center=true);
// carve out space for snap-ins and screw-in nuts
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
// translation is to leave 3mm thickness in the plate without recentering anything
translate([0, 0, -25]) cylinder(r=small_button_radius+button_radius_connector_space, h=49, $fn=100, center=true);
translate([0, 0, -25]) cylinder(r=small_button_radius+3, h=49, $fn=50, center=true);
// space for decorative button surround stuff
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);
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);
}
// 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=100, center=true);
// carve out space for snap-ins and screw-in nuts
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
// translation is to leave 3mm thickness in the plate without recentering anything
translate([0, 0, -25]) cylinder(r=big_button_radius+button_radius_connector_space, h=49, $fn=100, center=true);
translate([0, 0, -25]) cylinder(r=big_button_radius+6, h=49, $fn=50, center=true);
// space for decorative button surround stuff
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);
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);
}
module frame_hex_bolt_hole() {
@ -84,7 +82,7 @@ module rocker_20mm_mount() {
// 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([35, 8, frame_z-(panel_z*3)], center=true);
cube([30.5, 8, frame_z-(panel_z*3)], center=true);
}
// bank of three 24mm buttons, commonly on a frame face
@ -94,12 +92,6 @@ 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);
@ -107,24 +99,16 @@ module 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() {
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();
}
// 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 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);
}
module m3_mount_post() {
@ -282,13 +266,13 @@ module frame_solid() {
];
hull() {
for (p = top_points) {
translate(p) cylinder(r=2, h=frame_bevel_height, center=true, $fn=4);
translate(p) cylinder(r=2, h=frame_bevel_height, center=true);
}
for (p = base_points) {
translate(p) cylinder(r=2, h=frame_z-(frame_bevel_height*2), center=true, $fn=4);
translate(p) cylinder(r=2, h=frame_z-(frame_bevel_height*2), center=true);
}
for (p = bottom_points) {
translate(p) cylinder(r=2, h=frame_bevel_height, center=true, $fn=4);
translate(p) cylinder(r=2, h=frame_bevel_height, center=true);
}
}
}
@ -360,14 +344,14 @@ module frame() {
// 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]
[slash_inner_displacement/2, -frame_wall/2, -slash_height/2],
[(slash_inner_displacement/2+slash_width), -frame_wall/2, -slash_height/2],
[(slash_inner_displacement/2+slash_width), frame_wall/2, -slash_height/2],
[slash_inner_displacement/2, frame_wall/2, -slash_height/2],
[-(slash_inner_displacement/2+slash_width), -frame_wall/2, slash_height/2],
[-slash_inner_displacement/2, -frame_wall/2, slash_height/2],
[-slash_inner_displacement/2, frame_wall/2, slash_height/2],
[-(slash_inner_displacement/2+slash_width), frame_wall/2, 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]]);
}
@ -414,40 +398,24 @@ 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)-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();
translate([(panel_x/2)-28.06, (-panel_y/2)+62, 0]) button_30mm_hole();
}
module dir_arc_30mm_finger_buttons() {
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();
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();
}
module dir_arc_w_30mm() {
dir_arc_30mm_thumb_button();
dir_arc_30mm_finger_buttons();
dir_arc_30mm_w_button();
translate([-26.8, 57.2+12.9+34.5, 0]) dir_arc_30mm_thumb_button();
}
module dir_arc_w_30mm_plus_one() {
dir_arc_w_30mm();
translate([-dir_arc_30mm_column_3_offset-33.8, dir_arc_30mm_row_2_offset, 0]) dir_arc_30mm_thumb_button();
translate([-33.8-34.8-33.8, 57.2, 0]) dir_arc_30mm_thumb_button();
}
// Namco Noir (right hand)
@ -474,42 +442,31 @@ module noir_plus_one() {
// Sega Astro City 2P (right hand)
module sega_2p_p1() {
translate([-panel_x/2, -panel_y/2, 0]) translate([sega_2p_column_1_left_panel_edge_offset, 140, 0])
button_30mm_hole();
translate([-panel_x/2, -panel_y/2, 0]) translate([28.06, 140, 0]) button_30mm_hole();
}
module sega_2p_6_button() {
// via slagcoin
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([30.5, 11+9, 0]) sega_2p_p1();
translate([30.5+36, 11+9, 0]) sega_2p_p1();
translate([0, -19-9-11, 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();
translate([30.5, -19, 0]) sega_2p_p1();
translate([30.5+36, -19, 0]) sega_2p_p1();
}
module sega_2p() {
sega_2p_6_button();
translate([sega_2p_column_4_offset, 11, 0]) sega_2p_p1();
translate([sega_2p_column_4_offset, -19-9, 0]) sega_2p_p1();
translate([30.5+36+36, 11, 0]) sega_2p_p1();
translate([30.5+36+36, -19-9, 0]) sega_2p_p1();
}
module sega_2p_nine_thumb_button() {
module sega_2p_plus_one() {
sega_2p();
// 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();
}
module shiokenstar() {
translate([-172, 32, 0]) dir_arc_24mm_directionals();
sega_2p();

View File

@ -1,38 +0,0 @@
# 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.

View File

@ -1,25 +0,0 @@
/* 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();

View File

@ -1,26 +0,0 @@
/* 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();

View File

@ -1,15 +0,0 @@
/* 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();

View File

@ -1,30 +0,0 @@
/* 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();

View File

@ -1,60 +0,0 @@
/* 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();

View File

@ -1,30 +0,0 @@
/* 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() {
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();

View File

@ -1,17 +0,0 @@
/* 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();

View File

@ -1,24 +0,0 @@
/* 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();

View File

@ -1,14 +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 <panel-front-left-mount.scad>
module front_right_mount_panel() {
mirror([1, 0, 0]) front_left_mount_panel();
}
front_right_mount_panel();

View File

@ -1,18 +0,0 @@
/* 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();

View File

@ -1,17 +0,0 @@
/* 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();

View File

@ -7,9 +7,9 @@ include <parameters.scad>
include <components.scad>
use <front-or-back.scad>
module front_or_back_aux_and_neutrik_frame_piece() {
module front_or_back_aux_and_neutrik_box_frame_piece() {
difference() {
front_or_back_frame_piece();
front_or_back_box_frame_piece();
// aux button holes
translate([-35.25, -101.5, 0]) rotate([90, 0, 0]) aux_control_three_button_cluster();
@ -25,4 +25,4 @@ module front_or_back_aux_and_neutrik_frame_piece() {
}
}
front_or_back_aux_and_neutrik_frame_piece();
front_or_back_aux_and_neutrik_box_frame_piece();

View File

@ -0,0 +1,31 @@
/* 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_piece() {
difference() {
front_or_back_box_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();
}
}
front_or_back_inner_wall_frame_piece();

View File

@ -0,0 +1,31 @@
/*
* 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([-60, -(frame_y-frame_wall)/2, 0]) slash_cutout();
translate([-40, -(frame_y-frame_wall)/2, 0]) slash_cutout();
translate([-20, -(frame_y-frame_wall)/2, 0]) slash_cutout();
translate([0, -(frame_y-frame_wall)/2, 0]) slash_cutout();
translate([20, -(frame_y-frame_wall)/2, 0]) slash_cutout();
translate([40, -(frame_y-frame_wall)/2, 0]) slash_cutout();
translate([60, -(frame_y-frame_wall)/2, 0]) slash_cutout();
}
module backslashes_windowed_front_or_back_box_frame_piece() {
difference() {
front_or_back_box_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_box_frame_piece();

View File

@ -9,9 +9,9 @@ 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() {
module forwardslashes_windowed_front_or_back_box_frame_piece() {
difference() {
front_or_back_frame_piece();
front_or_back_box_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
@ -19,12 +19,4 @@ module forwardslashes_windowed_front_or_back_frame_piece() {
}
}
module forwardslashes_windowed_front_or_back_frame_piece_for_extended_side() {
difference() {
forwardslashes_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);
}
}
forwardslashes_windowed_front_or_back_frame_piece_for_extended_side();
forwardslashes_windowed_front_or_back_box_frame_piece();

View File

@ -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>
use <front-or-back.scad>
use <front-or-back-inner-wall.scad>
module front_stripe() {
cube([frame_x-(frame_mount_column_width*1.75)*2, frame_wall, 6], center=true);
}
module windowed_front_or_back_box_frame_piece() {
difference() {
front_or_back_box_frame_piece();
// subtract frame wall windows
translate([0, -(frame_y-frame_wall)/2, 18]) front_stripe();
translate([0, -(frame_y-frame_wall)/2, 9]) front_stripe();
translate([0, -(frame_y-frame_wall)/2, 0]) front_stripe();
translate([0, -(frame_y-frame_wall)/2, -9]) front_stripe();
translate([0, -(frame_y-frame_wall)/2, -18]) front_stripe();
// subtract the inner wall area that will be provided by the other piece
front_or_back_inner_wall_frame_piece();
}
}
windowed_front_or_back_box_frame_piece();

View File

@ -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 <front-or-back.scad>
use <front-or-back-inner-wall.scad>
module windowed_front_or_back_box_frame_piece() {
difference() {
front_or_back_box_frame_piece();
// subtract frame wall 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);
// subtract the inner wall area that will be provided by the other piece
front_or_back_inner_wall_frame_piece();
}
}
windowed_front_or_back_box_frame_piece();

View File

@ -6,20 +6,25 @@
include <parameters.scad>
include <components.scad>
use <frames/complete/left-frame.scad>
use <side.scad>
module front_or_back_frame_piece() {
module front_or_back_box_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_piece_x_x, piece_width, frame_z], center=true);
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_wall*2, frame_z], center=true);
linear_extrude(height=frame_z, center=true) polygon([
[-frame_x/2, -frame_y/2], [-frame_x/2+frame_wall, -frame_y/2+frame_wall],
[-frame_x/2, -frame_y/2+frame_wall]
]);
// ...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);
}
}
}
front_or_back_frame_piece();
front_or_back_box_frame_piece();

View File

@ -15,10 +15,9 @@ module mount_column_cutout() {
}
}
module side_inner_wall_frame_base_piece() {
module side_inner_wall_frame_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();
side_box_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)
@ -33,11 +32,4 @@ module side_inner_wall_frame_base_piece() {
}
}
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();

View File

@ -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>
use <side.scad>
use <side-inner-wall.scad>
module backslashes() {
translate([-(frame_x-frame_wall)/2, -40, 0]) rotate([0, 0, -90]) slash_cutout();
translate([-(frame_x-frame_wall)/2, -20, 0]) rotate([0, 0, -90]) slash_cutout();
translate([-(frame_x-frame_wall)/2, 0, 0]) rotate([0, 0, -90]) slash_cutout();
translate([-(frame_x-frame_wall)/2, 20, 0]) rotate([0, 0, -90]) slash_cutout();
translate([-(frame_x-frame_wall)/2, 40, 0]) rotate([0, 0, -90]) slash_cutout();
}
module backslashes_windowed_side_box_frame_piece() {
difference() {
side_box_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_box_frame_piece();

View File

@ -9,9 +9,9 @@ use <side.scad>
use <side-inner-wall.scad>
use <side-windowed-backslashes.scad>
module forwardslashes_windowed_side_frame_piece() {
module forwardslashes_windowed_side_box_frame_piece() {
difference() {
side_frame_piece();
side_box_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
@ -19,4 +19,4 @@ module forwardslashes_windowed_side_frame_piece() {
}
}
forwardslashes_windowed_side_frame_piece();
forwardslashes_windowed_side_box_frame_piece();

View File

@ -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>
use <side.scad>
use <side-inner-wall.scad>
module side_stripe() {
cube([frame_wall, frame_y-(frame_mount_column_width*1.75)*2, 6], center=true);
}
module windowed_side_box_frame_piece() {
difference() {
side_box_frame_piece();
// subtract frame wall windows
translate([-(frame_x-frame_wall)/2, 0, 18]) side_stripe();
translate([-(frame_x-frame_wall)/2, 0, 9]) side_stripe();
translate([-(frame_x-frame_wall)/2, 0, 0]) side_stripe();
translate([-(frame_x-frame_wall)/2, 0, -9]) side_stripe();
translate([-(frame_x-frame_wall)/2, 0, -18]) side_stripe();
// subtract the inner wall area that will be provided by the other piece
side_inner_wall_frame_piece();
}
}
windowed_side_box_frame_piece();

View File

@ -8,9 +8,9 @@ include <components.scad>
use <side.scad>
use <side-inner-wall.scad>
module windowed_side_frame_piece() {
module windowed_side_box_frame_piece() {
difference() {
side_frame_piece();
side_box_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,
@ -20,4 +20,4 @@ module windowed_side_frame_piece() {
}
}
windowed_side_frame_piece();
windowed_side_box_frame_piece();

View File

@ -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 <front-or-back.scad>
module side_box_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
front_or_back_box_frame_piece();
rotate([180, 0, 0]) front_or_back_box_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_box_frame_piece();

View File

@ -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-clean-for-extended-side.scad>
module front_or_back_aux_and_neutrik_box_frame_piece_for_extended_side() {
difference() {
front_or_back_box_frame_piece_for_extended_side();
// 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_box_frame_piece_for_extended_side();

View File

@ -0,0 +1,18 @@
/*
* 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/box/front-or-back.scad>
module front_or_back_box_frame_piece_for_extended_side() {
difference() {
front_or_back_box_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);
}
}
front_or_back_box_frame_piece_for_extended_side();

View File

@ -5,11 +5,11 @@
include <parameters.scad>
include <components.scad>
use <front-or-back.scad>
use <front-or-back-clean-for-extended-side.scad>
module clean_front_or_back() {
difference() {
front_or_back_frame_piece();
front_or_back_box_frame_piece_for_extended_side();
// 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);
};
@ -29,9 +29,9 @@ module bottom_piece_extension() {
}
}
module front_or_back_trapezoid_frame_piece() {
module extended_front_or_back_frame_piece() {
clean_front_or_back();
translate([0, -frame_y/2+frame_wall, 0]) rotate([90, 0, 0]) bottom_piece_extension();
}
front_or_back_trapezoid_frame_piece();
extended_front_or_back_frame_piece();

View File

@ -6,8 +6,8 @@
include <parameters.scad>
include <components.scad>
use <frames/complete/left-frame.scad>
use <side.scad>
use <front-or-back-trapezoid.scad>
use <frames/pieces/box/side.scad>
use <front-or-back.scad>
module side_and_bottom_frame_piece_wall() {
// get a slice of the pieces, to use it in extruding
@ -26,13 +26,13 @@ module side_and_bottom_frame_piece_extension() {
}
}
module side_trapezoid_extended_to_front_frame_piece() {
module extra_extended_left_or_right_frame_piece() {
difference() {
side_frame_piece();
side_box_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();
}
side_trapezoid_extended_to_front_frame_piece();
extra_extended_left_or_right_frame_piece();

View File

@ -6,7 +6,8 @@
include <parameters.scad>
include <components.scad>
use <frames/complete/left-frame.scad>
use <side.scad>
use <frames/pieces/box/side.scad>
use <front-or-back-clean-for-extended-side.scad>
module side_frame_piece_wall() {
// get a slice of the piece, to use it in extruding
@ -24,13 +25,13 @@ module side_frame_piece_extension() {
}
}
module side_trapezoid_frame_piece() {
module extended_bottom_left_or_right_frame_piece() {
difference() {
side_frame_piece();
side_box_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();
}
side_trapezoid_frame_piece();
extended_bottom_left_or_right_frame_piece();

View File

@ -1,31 +0,0 @@
/* 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();

View File

@ -1,65 +0,0 @@
/* 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]) 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();

View File

@ -1,40 +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 <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() {
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();
}
}
module backslashes_windowed_front_or_back_frame_piece_for_extended_side() {
difference() {
backslashes_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);
}
}
backslashes_windowed_front_or_back_frame_piece_for_extended_side();

View File

@ -1,33 +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 <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() {
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();

View File

@ -1,35 +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 <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() {
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();

View File

@ -5,11 +5,11 @@
include <parameters.scad>
include <components.scad>
use <side.scad>
use <box/side.scad>
module interconnect_frame_half_piece() {
translate([frame_x/2-frame_wall, 0, 0]) difference() {
side_frame_piece();
side_box_frame_piece();
rotate([0, 0, 180]) side_chopper();
}
}

View File

@ -1,32 +0,0 @@
/* 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();

View File

@ -1,32 +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 <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();

View File

@ -1,30 +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 <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();

View File

@ -1,33 +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 <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();

View File

@ -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 <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();

View File

@ -1,31 +0,0 @@
/* 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();

View File

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

View File

@ -4,13 +4,12 @@
*/
include <parameters.scad>
decorative_radius_scale = 1.5;
include <components.scad>
module button_24mm_decorative_plate() {
difference() {
// get a 2mm slice of the decorative button cylinders
translate([0, 0, -50]) button_24mm_hole();
// get a 2mm slice of the bigger button cylinders
translate([0, 0, -55]) button_24mm_hole();
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

View File

@ -8,8 +8,8 @@ include <components.scad>
module dir_arc_plus_w_24mm_8_button_decorative_plate() {
difference() {
// get a 2mm slice of the decorative button cylinders
translate([0, 0, -50]) dir_arc_plus_w_24mm_8_button();
// get a 2mm slice of the bigger button cylinders
translate([0, 0, -55]) dir_arc_plus_w_24mm_8_button();
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

View File

@ -1,35 +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;
include <components.scad>
module dir_arc_plus_w_30mm_and_sega_2p_nine_decorative_plate_of_plates() {
difference() {
// layout offset + 30 = width for layout plus button width + 19+3 = space around button
left_plate_x = dir_arc_30mm_column_3_offset + 30 + 19;
// layout offset + 30 = width for layout plus button width + 19+3 = space around button
left_plate_y = dir_arc_w_30mm_row_4_offset + 30 + 19;
left_plate_center_x = (left_plate_x + sega_2p_column_1_left_panel_edge_offset - 22)/2;
// layout offset + 30 = width for layout plus button width + 19+3 = space around button
right_plate_x = sega_2p_column_4_offset + 30 + 19;
right_plate_center_x = (right_plate_x + sega_2p_column_1_left_panel_edge_offset - 22)/2;
union() {
// y values are based on the other half below
translate([right_plate_center_x, 15, 0]) linear_extrude(2) offset(r=3, $fn=100)
square([right_plate_x, left_plate_y], center=true);
translate([-left_plate_center_x, 15, 0]) linear_extrude(2) offset(r=3, $fn=100)
square([left_plate_x, left_plate_y], center=true);
/* translate([-50, 0, 0]) cube([200, 200, 2], 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_nine();
}
}
dir_arc_plus_w_30mm_and_sega_2p_nine_decorative_plate_of_plates();

View File

@ -1,34 +0,0 @@
/* decorative plate for directional and action buttons.
*
* SPDX-FileCopyrightText: © 2025 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 dir_arc_plus_w_30mm_and_sega_2p_nine_decorative_superplate() {
difference() {
union() {
hull() difference() {
// get a 2mm slice of the decorative button cylinders
union() {
translate([-panel_x/2, 0, -50]) dir_arc_w_30mm();
translate([panel_x/2, 0, -50]) sega_2p_nine();
// customized position to make a top point even with the
// top of the dir_arc_w_30mm piece, because it being
// at an angle otherwise looks silly IMO
translate([panel_x*23/32, 26.6, -50]) sega_2p_p1();
}
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_nine();
}
}
dir_arc_plus_w_30mm_and_sega_2p_nine_decorative_superplate();

View File

@ -0,0 +1,26 @@
/*
* 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() dir_arc_w_30mm();
translate([panel_x/2, 0, -25]) hull() sega_2p_plus_one();
}
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();

View File

@ -6,19 +6,19 @@
include <parameters.scad>
include <components.scad>
module dir_arc_plus_w_30mm_and_sega_2p_nine_decorative_plate() {
module dir_arc_plus_w_30mm_and_sega_2p_plus_one_decorative_plate() {
difference() {
// get a 2mm slice of the jumbo decorative button cylinders
// get a 2mm slice of the bigger button cylinders
union() {
translate([-panel_x/2, 0, -70]) dir_arc_w_30mm();
translate([panel_x/2, 0, -70]) sega_2p_nine();
translate([-panel_x/2, 0, -65]) dir_arc_w_30mm();
translate([panel_x/2, 0, -65]) sega_2p_plus_one();
}
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_nine();
translate([panel_x/2, 0, -1]) sega_2p_plus_one();
}
}
dir_arc_plus_w_30mm_and_sega_2p_nine_decorative_plate();
dir_arc_plus_w_30mm_and_sega_2p_plus_one_decorative_plate();

View File

@ -1,24 +0,0 @@
/* Decorative plate for directional 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 dir_arc_plus_w_30mm_plate_decorative_plate() {
difference() {
hull() difference() {
// get a 2mm slice of the decorative button cylinders
translate([-panel_x/2, 0, -50]) dir_arc_w_30mm();
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();
}
}
dir_arc_plus_w_30mm_plate_decorative_plate();

View File

@ -8,8 +8,8 @@ include <components.scad>
module dir_arc_plus_w_30mm_decorative_plate() {
difference() {
// get a 2mm slice of the decorative button cylinders
translate([0, 0, -50]) dir_arc_w_30mm();
// get a 2mm slice of the bigger button cylinders
translate([0, 0, -55]) dir_arc_w_30mm();
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

View File

@ -8,8 +8,8 @@ include <components.scad>
module sega_2p_6_button_decorative_plate() {
difference() {
// get a 2mm slice of the decorative button cylinders
translate([0, 0, -50]) sega_2p_6_button();
// get a 2mm slice of the bigger button cylinders
translate([0, 0, -55]) sega_2p_6_button();
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

View File

@ -1,24 +0,0 @@
/* Decorative plate for directional 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 sega_2p_eleven_plate_decorative_plate() {
difference() {
hull() difference() {
// get a 2mm slice of the decorative button cylinders
translate([panel_x/2, 0, -50]) sega_2p_eleven();
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]) sega_2p_eleven();
}
}
sega_2p_eleven_plate_decorative_plate();

View File

@ -1,24 +0,0 @@
/* A rounded corner decorative plate for the Sega 2P + 1 button layout.
*
* 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 sega_2p_nine_decorative_plate() {
difference() {
hull() difference() {
// get a 2mm slice of the decorative button cylinders
translate([panel_x/2, 0, -50]) sega_2p_nine();
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]) sega_2p_nine();
}
}
sega_2p_nine_decorative_plate();

View File

@ -6,15 +6,15 @@
include <parameters.scad>
include <components.scad>
module sega_2p_nine_decorative_plate() {
module sega_2p_plus_one_decorative_plate() {
difference() {
// get a 2mm slice of the decorative button cylinders
translate([0, 0, -50]) sega_2p_nine();
// get a 2mm slice of the bigger button cylinders
translate([0, 0, -55]) sega_2p_plus_one();
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]) sega_2p_nine();
translate([0, 0, -1]) sega_2p_plus_one();
}
}
sega_2p_nine_decorative_plate();
sega_2p_plus_one_decorative_plate();

View File

@ -1,21 +0,0 @@
/* A decorative plate for the Sega 2P layout.
*
* 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_decorative_plate() {
difference() {
// get a 2mm slice of the decorative button cylinders
translate([0, 0, -50]) sega_2p();
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]) sega_2p();
}
}
sega_2p_decorative_plate();

View File

@ -8,9 +8,9 @@ include <components.scad>
module jlf_dustwasher() {
difference() {
cylinder(r=jlf_dustwasher_radius, h=2, $fn=100, center=true);
cylinder(r1=jlf_shaft_inner_radius, r2=jlf_shaft_inner_radius+shaft_position_tolerance,
h=2.001, $fn=100, center=true);
cylinder(r=lever_plate_hole*decorative_radius_scale, h=2, $fn=50, center=true);
// 5.25 = 4.55 (diameter of shaft is 9.10mm) + .25 to let it take an angle
cylinder(r=4.8, h=2.1, $fn=50, center=true);
}
}

View File

@ -8,9 +8,9 @@ include <components.scad>
module lsx_nobi_dustwasher() {
difference() {
cylinder(r=lsx_nobi_dustwasher_radius, h=2, $fn=100, center=true);
cylinder(r1=lsx_nobi_shaft_inner_radius, r2=lsx_nobi_shaft_inner_radius+shaft_position_tolerance,
h=2.001, $fn=100, center=true);
cylinder(r=lever_plate_hole*decorative_radius_scale, h=2, $fn=50, center=true);
// 5.25 = 5 (diameter of shaft is 10mm) + .25 to let it take an angle
cylinder(r=5.25+hole_tolerance, h=2.1, $fn=50, center=true);
}
}

View File

@ -1,29 +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 <lever-and-dir_arc-plus-w-30mm-panel.scad>
module lever_and_dir_arc_w_30mm_panel_with_oled() {
/* // TEMP FOR PRINTING JUST THE SECTION AS A TEST */
/* intersection() { */
/* union() { */
/* difference() { */
/* lever_and_dir_arc_w_30mm_panel(); */
/* translate([0, -(panel_y/2 - 30), 0]) adafruit_pid_326_oled_ssd1306_mount_cutout(); */
/* } */
/* translate([0, -(panel_y/2 - 30), 0]) adafruit_pid_326_oled_ssd1306_mount(); */
/* } */
/* translate([0, -(panel_y/2-30), 0]) cube([50, 40, 10], center=true); */
/* } */
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();

View File

@ -1,25 +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>
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();

View File

@ -1,16 +0,0 @@
/* 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([30, -50, -(panel_z/2) - 3]) pcb_mount();
}
sega_2p_eleven_panel_with_mount();

View File

@ -1,17 +0,0 @@
/* 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();

View File

@ -1,16 +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>
module sega_2p_nine_panel() {
difference() {
panel();
sega_2p_nine();
}
}
sega_2p_nine_panel();

View File

@ -1,17 +0,0 @@
/* 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();

View File

@ -6,11 +6,11 @@
include <parameters.scad>
include <components.scad>
module dir_arc_w_30mm_panel() {
module sega_2p_plus_one_panel() {
difference() {
panel();
dir_arc_w_30mm();
sega_2p_plus_one();
}
}
dir_arc_w_30mm_panel();
sega_2p_plus_one_panel();

View File

@ -5,11 +5,11 @@
include <parameters.scad>
include <components.scad>
use <right-sega-2p-nine-panel.scad>
use <sega-2p-plus-one-plus-control-panel.scad>
module sega_2p_nine_with_mount_right_overhang_panel() {
sega_2p_nine_right_overhang_panel();
module sega_2p_plus_one_plus_control_panel_with_mount() {
sega_2p_plus_one_plus_control_panel();
translate([30, -50, -(panel_z/2) - 3]) pcb_mount();
}
sega_2p_nine_with_mount_right_overhang_panel();
sega_2p_plus_one_plus_control_panel_with_mount();

View File

@ -6,12 +6,13 @@
include <parameters.scad>
include <components.scad>
module sega_2p_nine_plus_control_panel() {
module sega_2p_plus_one_plus_control_panel() {
difference() {
panel();
sega_2p_nine();
sega_2p_plus_one();
rotate([0, 0, 180]) side_chopper();
translate([89, 30, 0]) button_24mm_hole();
}
}
sega_2p_nine_plus_control_panel();
sega_2p_plus_one_plus_control_panel();

View File

@ -1,15 +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 <right-sega-2p-nine-plus-control-panel.scad>
module sega_2p_nine_plus_control_right_overhang_panel_with_mount() {
sega_2p_nine_plus_control_right_overhang_panel();
translate([30, -50, -(panel_z/2) - 3]) pcb_mount();
}
sega_2p_nine_plus_control_right_overhang_panel_with_mount();

View File

@ -5,11 +5,11 @@
include <parameters.scad>
include <components.scad>
use <sega-2p-nine-plus-control-panel.scad>
use <right-sega-2p-plus-one-panel.scad>
module sega_2p_nine_plus_control_panel_with_mount() {
sega_2p_nine_plus_control_panel();
module sega_2p_plus_one_with_mount_right_overhang_panel() {
sega_2p_plus_one_right_overhang_panel();
translate([30, -50, -(panel_z/2) - 3]) pcb_mount();
}
sega_2p_nine_plus_control_panel_with_mount();
sega_2p_plus_one_with_mount_right_overhang_panel();

View File

@ -6,12 +6,12 @@
include <parameters.scad>
include <components.scad>
module sega_2p_nine_right_overhang_panel() {
module sega_2p_plus_one_right_overhang_panel() {
difference() {
panel_with_raised_overhang();
sega_2p_nine();
sega_2p_plus_one();
rotate([0, 0, 180]) side_chopper();
}
}
sega_2p_nine_right_overhang_panel();
sega_2p_plus_one_right_overhang_panel();

View File

@ -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 <right-sega-2p-plus-one-plus-control-panel-with-mount.scad>
module sega_2p_plus_one_plus_control_right_overhang_panel_with_mount_with_oled() {
difference() {
sega_2p_plus_one_plus_control_right_overhang_panel_with_mount();
translate([75, 77.5, 0]) oled_ssd1306_mount_cutout();
}
translate([75, 77.5, 0.5]) oled_ssd1306_mount();
}
sega_2p_plus_one_plus_control_right_overhang_panel_with_mount_with_oled();

View File

@ -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 <right-sega-2p-plus-one-plus-control-panel.scad>
module sega_2p_plus_one_plus_control_right_overhang_panel_with_mount() {
sega_2p_plus_one_plus_control_right_overhang_panel();
translate([30, -50, -(panel_z/2) - 3]) pcb_mount();
}
sega_2p_plus_one_plus_control_right_overhang_panel_with_mount();

View File

@ -6,13 +6,13 @@
include <parameters.scad>
include <components.scad>
module sega_2p_nine_plus_control_right_overhang_panel() {
module sega_2p_plus_one_plus_control_right_overhang_panel() {
difference() {
panel_with_raised_overhang();
sega_2p_nine();
sega_2p_plus_one();
rotate([0, 0, 180]) side_chopper();
translate([89, 30, 0]) button_24mm_hole();
}
}
sega_2p_nine_plus_control_right_overhang_panel();
sega_2p_plus_one_plus_control_right_overhang_panel();

Some files were not shown because too many files have changed in this diff Show More