Compare commits

..

22 Commits

Author SHA1 Message Date
3059e01b8f
update build blown up demo and example photo
Signed-off-by: Brian S. Stephan <bss@incorporeal.org>
2024-06-24 15:50:25 -05:00
2911b23db4
rewrite "plates" as two separate plates
could these be broken up? yes. but this .scad was never used AFAIK, so
I'm just going to repurpose it

Signed-off-by: Brian S. Stephan <bss@incorporeal.org>
2024-06-24 15:35:43 -05:00
00a1bbc065
don't error if the necessary build directories already exist
Signed-off-by: Brian S. Stephan <bss@incorporeal.org>
2024-06-24 15:35:14 -05:00
6726233beb
favor symmetry in the front/back and side wall windowed pieces
I think the lack of symmetry led to a varying amount of force being
applied when joined with the interconnect. take for instance:

OUTER  INTER  INNER
INTER  INTER  INTER
INNER  INTER  OUTER

if OUTER (the "windowed" piece, the outside wall + one half of the
mounting column) is on top on the left side and on the bottom on the
right side, and INNER (the inner wall, the one that floats around
relative to the outer wall) vice versa on the other side, the two pieces
side by side would not create a clean line --- left would be ~0.5mm
lower than the right.

if there was a way to clamp these down relative to each other, the
problem might go away, but these are pretty pivotal to the overall stick
being aligned and the panels don't cross the interconnect, so probably
panels and a completed stick would have been similarly misaligned.

this, I believe, fixes it, and also fixes a tiny issue where a bit too
much material was being cut out of the inner walls by way of the mount
columns having a triangular point not normally seen because it's inside
the inner wall

Signed-off-by: Brian S. Stephan <bss@incorporeal.org>
2024-06-22 09:01:19 -05:00
bc68f8b0dc
naming consistency: panels are top/bottom
vertical planes that make up the frame are either sides or front/back

Signed-off-by: Brian S. Stephan <bss@incorporeal.org>
2024-06-21 11:38:31 -05:00
de3914fa85
more documentation updates for the assembly, after renaming stuff
Signed-off-by: Brian S. Stephan <bss@incorporeal.org>
2024-06-21 09:07:46 -05:00
92d3f9e6d5
some minor documentation updates
Signed-off-by: Brian S. Stephan <bss@incorporeal.org>
2024-06-21 08:44:40 -05:00
8168797be3
rewrite the README notes on parts, now that I reorganized them
Signed-off-by: Brian S. Stephan <bss@incorporeal.org>
2024-06-21 08:36:08 -05:00
244ace1b4a
add box pieces for a vent kind of look
no particular reference for this, just took some "slashes" and cut them
out of the walls with the expectation of using the inner wall in a
different color. designed, as much as I'd call it a design, for the Eva
stick, but this is mostly just me trying stuff at the moment

Signed-off-by: Brian S. Stephan <bss@incorporeal.org>
2024-06-21 08:34:18 -05:00
db887b668f
reorganize all the parts into subdirectories
src/ was getting pretty unreadable and I finally had time to do
something about it

Signed-off-by: Brian S. Stephan <bss@incorporeal.org>
2024-06-20 17:58:19 -05:00
dccd2836b2
start some frame pieces that have openings for decoration
essentially, the whole inner wall and part of the outer wall gets cut
out of the piece, and a new inner wall piece (probably printed in a
different color, or with some design of its own) created that can be
seen through the outer wall's window

multiple window and inner options are possible, this is just the start
while I do other organization

Signed-off-by: Brian S. Stephan <bss@incorporeal.org>
2024-06-20 14:02:19 -05:00
2ed9b12ed3
simplify my Makefile by writing the build stuff in Python
I'm going to move all of the .scad files into subdirectories and I
couldn't figure out how to recurse properly in make, so... do it the
easy way

make is hard, let's go shopping

Signed-off-by: Brian S. Stephan <bss@incorporeal.org>
2024-06-20 10:51:16 -05:00
de0fcfd160
use gray in the demo so that it's easier to see edges
Signed-off-by: Brian S. Stephan <bss@incorporeal.org>
2024-06-19 13:28:23 -05:00
4e65445e16
fix the extended pieces, sans 45 degree box corner
box pieces having a 45 degree cut for the corners looks very nice, and
works well, but the cut interferes with the extended piece options, so
this reuses the pieces to take ones with the 45 degree lip cut off,
which would be combined with the flush extended pieces, much like how
things used to work for these pieces before I made the box pieces use
said cut.

this also commits a demo of combining everything extended-style

phew

Signed-off-by: Brian S. Stephan <bss@incorporeal.org>
2024-06-19 13:23:01 -05:00
d578890d96
rename box-style frame pieces to be explicitly for boxes
I'm going to need to duplicate and edit the top/bottom pieces in
order to create better extended pieces, so this moves them into
something explicitly-named. next commit will fix the extended pieces

Signed-off-by: Brian S. Stephan <bss@incorporeal.org>
2024-06-19 12:54:13 -05:00
db41aa1183
add demo of a stick as if was assembled
Signed-off-by: Brian S. Stephan <bss@incorporeal.org>
2024-06-19 11:12:33 -05:00
0d954c2630
fix the blown up demo and move it to a demo/ dir
Signed-off-by: Brian S. Stephan <bss@incorporeal.org>
2024-06-19 10:46:27 -05:00
60b52eb10d
DRY: base top_or_bottom_aux_and_neutrik_frame_piece on basic piece
Signed-off-by: Brian S. Stephan <bss@incorporeal.org>
2024-06-19 10:05:07 -05:00
63c7ade41d
split the top/bottom and side walls' corners in the middle
this makes them meet at the corner at a 45 degree angle, rather than the
side having the whole wall, which tended not to print well. the behavior
of the extended walls, where the whole side is on the extended side
piece, is retained --- this only affects the box walls

Signed-off-by: Brian S. Stephan <bss@incorporeal.org>
2024-06-19 09:57:38 -05:00
eaaa92004f
scoot the 3 aux buttons a bit closer to the edge
this is just to line up with the frame/panel mount column a bit better
and remove some weird geometry

Signed-off-by: Brian S. Stephan <bss@incorporeal.org>
2024-06-18 13:58:55 -05:00
cf218ecc1d
tweaks to the frame pieces for better names and post sizes
in addition to renaming a number of the frame pieces, and adjusting the
pieces affected by those renames, this tweaks how the interlocking
pieces are designed by using 1/3 of the inner z of the frame rather than
dividing up the outer z. this is more consistent and might be a relevant
tweak in a later part I'm working on

Signed-off-by: Brian S. Stephan <bss@incorporeal.org>
2024-06-18 07:37:52 -05:00
8fd77375b7
parameterize the construction of the frame_mount_column chamfer
Signed-off-by: Brian S. Stephan <bss@incorporeal.org>
2024-06-17 12:22:31 -05:00
83 changed files with 740 additions and 332 deletions

View File

@ -1,9 +1,5 @@
EXCLUDES = blown-up-demo components parameters
OBJECTS := $(filter-out $(EXCLUDES),$(patsubst src/%.scad,%,$(wildcard src/*.scad)))
dir_guard=@mkdir -p ./build
all: $(OBJECTS)
$(dir_guard)
all:
python build.py
mkdir -p ./build/docs
cp ./docs/README-objects.md ./build/README.md
cp ./docs/assembly-and-tips.md ./build/docs/assembly-and-tips.md
@ -11,9 +7,5 @@ all: $(OBJECTS)
cp ./LICENSE ./build/LICENSE
pushd ./build; zip ./buildable-stick-system-`git describe --dirty`-stls.zip . -r; popd
$(OBJECTS):
$(dir_guard)
openscad -o build/$@.stl src/$@.scad
clean:
rm -rf ./build

View File

@ -11,7 +11,7 @@ know someone or a library with a 3D printer? The Buildable Stick System may be t
[OpenSCAD-based illustration of how the components for an overhang panel-based stick fit together.]
![A photo of a completed stick](docs/finished-v4.2.jpg)
![A photo of a completed stick](docs/finished-v4.4.jpg)
[Photo of a completed inset panel-based stick.]
@ -30,19 +30,42 @@ starting with an existing object and constructing what you'd like with new or ex
## Usage of Parts
There are a lot of parts to pick from, but there are some structural variants to pay attention to; here's some help
about when/how to use specific parts:
about what the types of parts are and how to use them:
* `panel-inset` --- these fit flush into a frame, creating a closed box enclosure.
* `panel-overhang` --- these have a tray that fits into a frame with the actual face extending beyond the frame,
creating an ice cream sandwich enclosure.
* These also yield a bit more space inside the box, for tall levers or whatever.
* `frame` (non-pieces) --- these create the box of the enclosure, as one part. These can be hard to print well ---
shrinkage forces tend to curl up the corners no matter what you do, and some points need supports --- but if you don't
care about that because you're printing an ice cream sandwich, they are simpler than...
* `frame-piece` --- these break up the frame box into four faces, and are held together by friction fit and the hex
bolts. This is more stable than you might expect, but it does introduce some variability in the overall sturdiness of
the enclosure compared with the frame as one box piece.
* The `interconnect` replaces the need to bolt multiple frames together.
* `frames/`
* `complete/` --- these are the four walls of the frame as one piece, in a couple variations for combining into
larger arcade sticks. They are simple to assemble, but you have fewer modularity/customization options, and they
are harder to print because the physics of the material cooling will probably pull the corners up. They also need
supports, since the top and bottom of the frame both have trays for panels to go into. Use at your own risk.
* `pieces/`
* `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.
## Printing
@ -57,14 +80,14 @@ What you'll need beyond these objects:
* An arcade stick board (I recommend [TheTrain's RP2040 Advanced Breakout
Board](https://github.com/OpenStickCommunity/Hardware/tree/main/RP2040%20Advanced%20Breakout%20Board))
* 4 M3 8mm hex bolts to secure the PCB to a panel
* Per frame and plate combo:
* Per frame and panel combo:
* 4 45mm M4 hex brass standoffs (or equivalent)
* 8 M4 countersunk hex bolts
* Overhang plates should use 12-16mm length bolts since they are taller
* Inset plates should probably use 8-12mm bolts --- some standoffs aren't threaded the whole way, making 16mm
* Overhang panels should use 12-16mm length bolts since they are taller
* Inset panels should probably use 8-12mm bolts --- some standoffs aren't threaded the whole way, making 16mm
too long to go flush
* If making the 45mm standoffs from multiple smaller ones, make sure they have enough length to take your bolts!
* Per frame connection point:
* Per frame connection point (only necessary if you are using complete frames and not frame pieces):
* 8 16mm M4 bolts
* 8 M4 flange nuts
* For a lever:
@ -99,8 +122,8 @@ Filament masses from Bambu Studio estimates, using Bambu PLA Basic, 20% gyroid i
stick anyway
* You can also use a shorter length with longer bolts, or combine multiple standoffs, if either of those yield better
prices
* 8 16mm M4 bolts to connect top plates to frames: **$0.72 USD** (you can get a pack of 100 on Amazon for $9, as of
* 8 12mm M4 bolts to connect bottom plates to frames: **$0.72 USD** (you can get a pack of 100 on Amazon for $9, as of
* 8 16mm M4 bolts to connect top panels to frames: **$0.72 USD** (you can get a pack of 100 on Amazon for $9, as of
* 8 12mm M4 bolts to connect bottom panels to frames: **$0.72 USD** (you can get a pack of 100 on Amazon for $9, as of
2023-09-12)
With an enclosure coming in around $31, depending on your choices --- say, ~$30 for TheTrain's RP2040 Advanced Breakout

View File

@ -4,4 +4,4 @@ Notes for "next time".
## v4.x
* Engraving some cosmetic stuff? Or maybe a place to mount other plates?
* Engraving some cosmetic stuff? Or maybe a place to mount other plates on the top?

50
build.py Normal file
View File

@ -0,0 +1,50 @@
"""Compile all OpenSCAD files into a build directory and package it with docs.
(a.k.a.: "make is hard"
SPDX-FileCopyrightText: © 2024 Brian S. Stephan <bss@incorporeal.org>
SPDX-License-Identifier: GPL-3.0-or-later
"""
import os
import os.path
import re
import subprocess
PROJECT_ROOT = os.path.abspath(os.getcwd())
BUILD_DIR = os.path.join(PROJECT_ROOT, 'build/')
SOURCE_DIR = os.path.join(PROJECT_ROOT, 'src/')
EXCLUDES = ['components.scad', 'parameters.scad']
# set up our environment to point openscad at the right stuff
os.environ['OPENSCADPATH'] = SOURCE_DIR
# track processes to wait on
processes = []
os.chdir(SOURCE_DIR)
for root, dirs, files in os.walk('.'):
print(f"{root} {dirs} {files}")
# make the current directory so that openscad can write stuff into it
try:
os.makedirs(os.path.join(BUILD_DIR, root))
except FileExistsError:
pass
input_dir = os.path.join(SOURCE_DIR, root)
output_dir = os.path.join(BUILD_DIR, root)
for file in files:
if not re.match(r'.*\.scad$', file):
continue
if file in EXCLUDES:
continue
stl_file = re.sub(r'\.scad$', '.stl', file)
input_ = os.path.join(input_dir, file)
output = os.path.join(output_dir, stl_file)
cmd = f'openscad -o {output} {input_}'
print(cmd)
processes.append(subprocess.Popen(cmd.split(' ')))
for process in processes:
process.wait()

View File

@ -0,0 +1,38 @@
/*
* 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/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-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-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 = "#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_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-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

@ -0,0 +1,35 @@
/*
* SPDX-FileCopyrightText: © 2023 Brian S. Stephan <bss@incorporeal.org>
* SPDX-License-Identifier: GPL-3.0-or-later
*/
include <parameters.scad>
include <components.scad>
use <frames/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-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-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>
panel_color = "red";
base_color = "gray";
top_deco_color = "white";
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(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();

33
demo/blown-up-demo.scad Normal file
View File

@ -0,0 +1,33 @@
/*
* SPDX-FileCopyrightText: © 2023 Brian S. Stephan <bss@incorporeal.org>
* SPDX-License-Identifier: GPL-3.0-or-later
*/
include <parameters.scad>
include <components.scad>
use <frames/pieces/interconnect.scad>
use <frames/pieces/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-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-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_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]) left_or_right_overhang_panel();
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

@ -6,26 +6,40 @@ Files for 3D printing an arcade stick.
The following notes document the objects in the Buildable Stick System and how you can use them:
* `bottom-panel-inset`: a simple solid panel that fits into the bottom of a frame box.
* `bottom-panel-overhang-*`: solid panels whose base fits into the bottom of a frame box, but have a longer sheet that
extends beyond the frame, creating a sandwich kind of look; the various forms hang over more or less of the frame,
expecting it will be connected to other frames.
* `frame-{left,middle,right,solo}`: the core frame of the stick, these are complete boxes; since they are long and
narrow, and need supports to print the space for the insets, these may be difficult to print nicely.
* `frame-piece-*`: the core frame broken up by individual faces, which are easier to print and essentially just as
sturdy.
* `frame-piece-*-extended*`: frame pieces that have been stretched out beyond the normal frame dimensions in order to
make a nice bevel on the sides and/or bottom; this, interestingly, tends to make the stick look a bit thinner than if
it was just a simple box.
* `misc-decorative-plate-*`: things you can print to snazz up face buttons mounting, auxillary button points, etc..
* `misc-dustwasher-*`: simple dustwashers for levers.
* `misc-lever-mount-*`: lever mounts of various shapes and depths to get the desired lever height when mounting a lever
to a panel (with the appropriate cutouts).
* `misc-neutrik-*`: like the decorative plates, but these are a bit more necessary by their design.
* `misc-rocker-*`: rocker SPDT switches don't have mounting holes, this allows you to attach them to the frame.
* `top-panel-inset-*`: various lever and/or button layouts for using as the face(s) of a stick.
* `top-panel-overhang-`: same idea as the inset top panels, but overhung over the frame to make the sandwich look; these
also leave a bit more space inside the frame, which might accommodate a taller lever.
* `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.

View File

@ -8,21 +8,21 @@ Assembly of a stick is pretty straightforward, but there are some choices that c
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 top pieces --- `frame-piece-top-left-or-right`: this is your best shot to get auxillary buttons,
panel connectors, and the like installed, so do it now, and give them a good tighten. You shouldn't need to adjust
these again, so finish their installation while the pieces are free.
1. This of course includes decorative plates --- e.g. `misc-decorative-plate-aux-control-three-button-cluster` ---
you may choose to use. These are held to the top pieces by the buttons or component mounting screws.
2. Start the top panels --- `top-panel-(inset|overhang)-*`: you want both to get the components installed now
when it's easy, and to make sure that the overall assembly works with your components, so again get your buttons,
lever, etc., in place. You can secure them at this point.
1. Prepare the frame pieces: this is your best shot to get the e.g. Neutrik plates for the USB mount, SPDT switches, etc.
installed, so do it now, and give them a good tighten. You shouldn't need to adjust these again, so finish their
installation while the pieces are free.
1. You could also do the decorative plates and related buttons, but it might be just as well to leave those for step 7,
just to make sure the buttons don't get in the way of other buttons or a lever or so on.
2. Start the top panels: you want both to get the components installed now when it's easy, and to make sure that the
overall assembly works with your components, so again get your buttons, lever, etc., in place. You can secure them at
this point.
1. If you are using a button decorative plate that spans two panels --- e.g.
`src/misc-decorative-plate-dir_arc-plus-w-30mm-and-sega-2p-plus-one` --- take care to align the two panels as
tightly as possible, and accurately, as they will be hard to adjust once everything is secured and in the frame.
2. If using a lever, don't forget the lever mount spacer --- `src/misc-lever-mount-sanwa-seimitsu` --- if you want
it, and tighten those mounting bolts now as well.
3. Create the frame box by combining your `frame-piece-*` parts together. This will be relatively stable just via
friction fit.
`misc/decorative-plate-dir_arc-plus-w-30mm-and-sega-2p-plus-one` --- take care to align the two panels as tightly
as possible, and accurately, as they will be hard to adjust once everything is secured and in the frame.
2. If using a lever, don't forget the lever mount spacer --- `misc/lever-mount-sanwa-seimitsu` --- if you want it,
and tighten those mounting bolts now as well.
3. Create the frame box by combining your frame piece parts, box or extended, together. This will be relatively stable
just via friction fit.
4. Rest the frame top-up on a desk, and put the standoffs through the holes. This will probably be tight, and you may
even need a rubber mallet or similar to drive the standoffs through the holes.
5. Insert the top panels into the frame.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

After

Width:  |  Height:  |  Size: 66 KiB

BIN
docs/finished-v4.4.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 372 KiB

View File

@ -1,34 +0,0 @@
/*
* SPDX-FileCopyrightText: © 2023 Brian S. Stephan <bss@incorporeal.org>
* SPDX-License-Identifier: GPL-3.0-or-later
*/
include <parameters.scad>
include <components.scad>
use <frame-piece-bottom-left-or-right.scad>
use <frame-piece-interconnect.scad>
use <frame-piece-side.scad>
use <frame-piece-top-left-or-right.scad>
use <top-panel-overhang-left-lever-and-dir_arc-plus-w-30mm.scad>
use <top-panel-overhang-right-sega-2p-plus-one-plus-control-with-mount.scad>
use <bottom-panel-overhang-left.scad>
use <bottom-panel-overhang-right.scad>
use <misc-decorative-plate-24mm-button.scad>
use <misc-decorative-plate-dir_arc-plus-w-30mm-and-sega-2p-plus-one.scad>
use <misc-dustwasher-lsx-nobi.scad>
color("#C12E1F") translate([-panel_x/2-25, 0, frame_z/2+75]) top_panel_left_lever_and_dir_arc_w_30mm();
color("#C12E1F") translate([panel_x/2+25, 0, frame_z/2+75]) top_panel_right_sega_2p_plus_one_plus_control_with_mount();
color("black") translate([-frame_x/2+5-25, 35, -2.5]) top_left_or_right_frame_piece();
color("black") rotate([0, 180, 0]) translate([-frame_x/2+5-25, 35, -2.5]) top_left_or_right_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") translate([-frame_x/2+5-25, -35, -2.5]) bottom_left_or_right_frame_piece();
color("black") rotate([0, 180, 0]) translate([-frame_x/2+5-25, -35, -2.5]) bottom_left_or_right_frame_piece();
color("black") interconnect_frame_piece();
color("#C12E1F") translate([-panel_x/2-25, 0, -5-frame_z/2-75]) bottom_panel_left();
color("#C12E1F") translate([panel_x/2+25, 0, -5-frame_z/2-75]) bottom_panel_right();
color("black") translate([0, 0, 3+frame_z/2+150]) dir_arc_plus_w_30mm_and_sega_2p_plus_one_decorative_plate();
color("black") translate([-195, 25, 3+frame_z/2+150]) lsx_nobi_dustwasher();
color("black") translate([panel_x, 25, 3+frame_z/2+150]) button_24mm_decorative_plate();

View File

@ -1,14 +0,0 @@
/*
* SPDX-FileCopyrightText: © 2023 Brian S. Stephan <bss@incorporeal.org>
* SPDX-License-Identifier: GPL-3.0-or-later
*/
include <parameters.scad>
include <components.scad>
use <bottom-panel-overhang-left.scad>
module bottom_panel_right() {
rotate([0, 0, 180]) bottom_panel_left();
}
bottom_panel_right();

View File

@ -168,10 +168,6 @@ module base_panel() {
cube([panel_x, panel_y, panel_z], center=true);
}
module base_bottom_panel() {
mirror([0, 0, 1]) base_panel();
}
module panel() {
difference() {
base_panel();
@ -179,13 +175,6 @@ module panel() {
}
}
module bottom_panel() {
difference() {
base_bottom_panel();
mirror([0, 0, 1]) panel_holes();
}
}
module overhang_plate() {
top_points = [
// top bevel
@ -301,7 +290,11 @@ module frame_mount_column() {
cube([frame_mount_column_width, frame_mount_column_width, frame_z], center=true);
// add some corners back to do a lame chamfer
linear_extrude(height=frame_z, center=true)
polygon([[10, 10], [-20, 10], [10, -20]]);
polygon([
[frame_mount_column_width/2, frame_mount_column_width/2],
[-frame_mount_column_width, frame_mount_column_width/2],
[frame_mount_column_width/2, -frame_mount_column_width]
]);
}
module side_chopper() {
@ -338,7 +331,7 @@ module frame() {
difference() {
base_frame();
translate([0, 0, frame_z/2]) scale([1, 1, 2]) base_panel();
translate([0, 0, -frame_z/2]) scale([1, 1, 2]) bottom_panel();
translate([0, 0, -frame_z/2]) scale([1, 1, 2]) base_panel();;
translate([panel_to_frame_point_x, panel_to_frame_point_y, 0]) frame_hex_bolt_hole();
translate([-panel_to_frame_point_x, panel_to_frame_point_y, 0]) frame_hex_bolt_hole();
translate([panel_to_frame_point_x, -panel_to_frame_point_y, 0]) frame_hex_bolt_hole();

View File

@ -1,29 +0,0 @@
/*
* SPDX-FileCopyrightText: © 2024 Brian S. Stephan <bss@incorporeal.org>
* SPDX-License-Identifier: GPL-3.0-or-later
*/
include <parameters.scad>
include <components.scad>
use <frame-piece-bottom-left-or-right.scad>
module bottom_piece_wall() {
// get a slice of the piece, to use it in extruding
projection(cut=true) rotate([-90, 0, 0]) translate([0, frame_y/2-frame_bevel_height, 0])
bottom_left_or_right_frame_piece();
}
module bottom_piece_extension() {
// combine the original with a shrunken piece to "pull" the wall out
hull() {
linear_extrude(height=frame_extension_y) scale([1, 0.5, 1]) bottom_piece_wall();
linear_extrude(height=frame_bevel_height) bottom_piece_wall();
}
}
module extended_bottom_left_or_right_frame_piece() {
bottom_left_or_right_frame_piece();
translate([0, -frame_y/2+frame_bevel_height*2, 0]) rotate([90, 0, 0]) bottom_piece_extension();
}
extended_bottom_left_or_right_frame_piece();

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 <frame-left.scad>
module top_left_or_right_frame_piece() {
piece_width = panel_support_width+frame_wall+frame_mount_column_width;
intersection() {
left_frame();
difference() {
// include the whole top wall (including mount columns)
translate([0, (frame_y/2)-(piece_width/2), 0]) cube([frame_x, piece_width, frame_z], center=true);
// ...minus the frame wall and lip on the left
translate([-frame_x/2+frame_wall/2, 0, 0])
cube([frame_wall, frame_y, frame_z], center=true);
// ...minus a slot for the combining piece to go into
cube([frame_x, frame_y-(panel_support_width+frame_wall)*2, frame_z/4], center=true);
}
}
}
top_left_or_right_frame_piece();

View File

@ -24,9 +24,9 @@ module left_frame() {
frame_cable_routing_hole();
// aux button holes
translate([-35, 101.5, 0]) rotate([270, 0, 0]) aux_control_three_button_cluster();
translate([-35, (frame_y/2)-neutrik_panel_thickness-4, 0]) frame_cutout();
translate([-72, (frame_y/2)-neutrik_panel_thickness-4, 0]) frame_cutout();
translate([-35.25, 101.5, 0]) rotate([270, 0, 0]) aux_control_three_button_cluster();
translate([-35.25, (frame_y/2)-neutrik_panel_thickness-4, 0]) frame_cutout();
translate([-72.25, (frame_y/2)-neutrik_panel_thickness-4, 0]) frame_cutout();
translate([2, (frame_y/2)-neutrik_panel_thickness-4, 0]) frame_cutout();
// neutrix button hole

View File

@ -24,9 +24,9 @@ module right_frame() {
mirror([1, 0, 0]) frame_cable_routing_hole();
// aux button holes
translate([35, 101.5, 0]) rotate([270, 0, 0]) aux_control_three_button_cluster();
translate([35, (frame_y/2)-neutrik_panel_thickness-4, 0]) frame_cutout();
translate([72, (frame_y/2)-neutrik_panel_thickness-4, 0]) frame_cutout();
translate([35.25, 101.5, 0]) rotate([270, 0, 0]) aux_control_three_button_cluster();
translate([35.25, (frame_y/2)-neutrik_panel_thickness-4, 0]) frame_cutout();
translate([72.25, (frame_y/2)-neutrik_panel_thickness-4, 0]) frame_cutout();
translate([-2, (frame_y/2)-neutrik_panel_thickness-4, 0]) frame_cutout();
// neutrix button hole

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.scad>
module front_or_back_aux_and_neutrik_box_frame_piece() {
difference() {
front_or_back_box_frame_piece();
// aux button holes
translate([-35.25, -101.5, 0]) rotate([90, 0, 0]) aux_control_three_button_cluster();
translate([-35.25, -(frame_y/2)+neutrik_panel_thickness+4, 0]) frame_cutout();
translate([-72.25, -(frame_y/2)+neutrik_panel_thickness+4, 0]) frame_cutout();
translate([2, -(frame_y/2)+neutrik_panel_thickness+4, 0]) frame_cutout();
// neutrix button hole
translate([frame_center_to_neutrik, -(frame_y/2)+neutrik_panel_thickness, 0])
rotate([270, 0, 0]) neutrik_d_mount();
translate([frame_center_to_neutrik, -(frame_y/2)+neutrik_panel_thickness+4, 0])
frame_cutout();
}
}
front_or_back_aux_and_neutrik_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,40 @@
/*
* 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 backslash() {
polyhedron([[5, -frame_y/2, -(frame_z-panel_z*3)/2], [20, -frame_y/2, -(frame_z-panel_z*3)/2],
[20, -frame_y/2+frame_wall, -(frame_z-panel_z*3)/2], [5, -frame_y/2+frame_wall, -(frame_z-panel_z*3)/2],
[-20, -frame_y/2, (frame_z-panel_z*3)/2], [-5, -frame_y/2, (frame_z-panel_z*3)/2],
[-5, -frame_y/2+frame_wall, (frame_z-panel_z*3)/2], [-20, -frame_y/2+frame_wall, (frame_z-panel_z*3)/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]]
);
}
module backslashes() {
translate([-60, 0, 0]) backslash();
translate([-40, 0, 0]) backslash();
translate([-20, 0, 0]) backslash();
backslash();
translate([20, 0, 0]) backslash();
translate([40, 0, 0]) backslash();
translate([60, 0, 0]) backslash();
}
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

@ -0,0 +1,22 @@
/*
* SPDX-FileCopyrightText: © 2024 Brian S. Stephan <bss@incorporeal.org>
* SPDX-License-Identifier: GPL-3.0-or-later
*/
include <parameters.scad>
include <components.scad>
use <front-or-back.scad>
use <front-or-back-inner-wall.scad>
use <front-or-back-windowed-backslashes.scad>
module forwardslashes_windowed_front_or_back_box_frame_piece() {
difference() {
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
front_or_back_inner_wall_frame_piece();
}
}
forwardslashes_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

@ -5,9 +5,9 @@
include <parameters.scad>
include <components.scad>
use <frame-left.scad>
use <frames/complete/left-frame.scad>
module bottom_left_or_right_frame_piece() {
module front_or_back_box_frame_piece() {
piece_width = panel_support_width+frame_wall+frame_mount_column_width;
intersection() {
left_frame();
@ -16,11 +16,15 @@ module bottom_left_or_right_frame_piece() {
translate([0, -(frame_y/2)+(piece_width/2), 0]) cube([frame_x, piece_width, frame_z], center=true);
// ...minus the frame wall and lip on the left
translate([-frame_x/2+frame_wall/2, 0, 0])
cube([frame_wall, frame_y, frame_z], center=true);
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, frame_z/4], center=true);
cube([frame_x, frame_y-(panel_support_width+frame_wall)*2, inner_frame_z/3], center=true);
}
}
}
bottom_left_or_right_frame_piece();
front_or_back_box_frame_piece();

View File

@ -0,0 +1,35 @@
/* The inner side wall of the frame, for being displayed through a windowed part.
*
* SPDX-FileCopyrightText: © 2024 Brian S. Stephan <bss@incorporeal.org>
* SPDX-License-Identifier: GPL-3.0-or-later
*/
include <parameters.scad>
include <components.scad>
use <side.scad>
module mount_column_cutout() {
intersection() {
frame_mount_column();
cube([frame_mount_column_width*3/2, frame_mount_column_width*3/2, inner_frame_z*21/24], center=true);
}
}
module side_inner_wall_frame_piece() {
difference() {
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)
translate([-panel_to_frame_point_x, panel_to_frame_point_y, inner_frame_z/2]) rotate([0, 0, 90])
mount_column_cutout();
translate([-panel_to_frame_point_x, -(panel_to_frame_point_y), -inner_frame_z/2]) rotate([0, 0, 180])
mount_column_cutout();
translate([-panel_to_frame_point_x, panel_to_frame_point_y, -inner_frame_z/2]) rotate([0, 0, 90])
mount_column_cutout();
translate([-panel_to_frame_point_x, -(panel_to_frame_point_y), inner_frame_z/2]) rotate([0, 0, 180])
mount_column_cutout();
}
}
side_inner_wall_frame_piece();

View File

@ -0,0 +1,38 @@
/*
* 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 backslash() {
polyhedron([[-frame_x/2, -5, -(frame_z-panel_z*3)/2], [-frame_x/2, -20, -(frame_z-panel_z*3)/2],
[-frame_x/2+frame_wall, -20, -(frame_z-panel_z*3)/2], [-frame_x/2+frame_wall, -5, -(frame_z-panel_z*3)/2],
[-frame_x/2, 20, (frame_z-panel_z*3)/2], [-frame_x/2, 5, (frame_z-panel_z*3)/2],
[-frame_x/2+frame_wall, 5, (frame_z-panel_z*3)/2], [-frame_x/2+frame_wall, 20, (frame_z-panel_z*3)/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]]
);
}
module backslashes() {
translate([0, -40, 0]) backslash();
translate([0, -20, 0]) backslash();
backslash();
translate([0, 20, 0]) backslash();
translate([0, 40, 0]) backslash();
}
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

@ -0,0 +1,22 @@
/*
* SPDX-FileCopyrightText: © 2024 Brian S. Stephan <bss@incorporeal.org>
* SPDX-License-Identifier: GPL-3.0-or-later
*/
include <parameters.scad>
include <components.scad>
use <side.scad>
use <side-inner-wall.scad>
use <side-windowed-backslashes.scad>
module forwardslashes_windowed_side_box_frame_piece() {
difference() {
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
side_inner_wall_frame_piece();
}
}
forwardslashes_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 <side.scad>
use <side-inner-wall.scad>
module windowed_side_box_frame_piece() {
difference() {
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,
frame_z-panel_z*3], center=true);
// subtract the inner wall area that will be provided by the other piece
side_inner_wall_frame_piece();
}
}
windowed_side_box_frame_piece();

View File

@ -5,20 +5,19 @@
include <parameters.scad>
include <components.scad>
use <frame-piece-top-left-or-right.scad>
use <frame-piece-bottom-left-or-right.scad>
use <front-or-back.scad>
module side_frame_piece() {
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
top_left_or_right_frame_piece();
bottom_left_or_right_frame_piece();
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_frame_piece();
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

@ -0,0 +1,37 @@
/*
* SPDX-FileCopyrightText: © 2024 Brian S. Stephan <bss@incorporeal.org>
* SPDX-License-Identifier: GPL-3.0-or-later
*/
include <parameters.scad>
include <components.scad>
use <front-or-back-clean-for-extended-side.scad>
module clean_front_or_back() {
difference() {
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);
};
}
module bottom_piece_wall() {
// get a slice of the piece (before the bevel), to use it in extruding
projection(cut=true) rotate([-90, 0, 0]) translate([0, frame_y/2-(frame_wall-frame_bevel_height)*3/2, 0])
clean_front_or_back();
}
module bottom_piece_extension() {
// combine the original with a shrunken piece to "pull" the wall out
hull() {
linear_extrude(height=frame_extension_y) scale([1, 0.5, 1]) bottom_piece_wall();
linear_extrude(height=(frame_wall-frame_bevel_height)) bottom_piece_wall();
}
}
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();
}
extended_front_or_back_frame_piece();

View File

@ -5,13 +5,16 @@
include <parameters.scad>
include <components.scad>
use <frame-piece-bottom-left-or-right-extended.scad>
use <frame-piece-side.scad>
use <frames/complete/left-frame.scad>
use <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
projection(cut=true) rotate([0, 90, 0]) translate([frame_x/2-frame_bevel_height, 0, 0])
side_frame_piece();
// 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();
projection(cut=true) translate([0, -frame_y/2+frame_wall, 0]) rotate([90, 90, 0]) bottom_piece_extension();
}
@ -25,7 +28,7 @@ module side_and_bottom_frame_piece_extension() {
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);
}

View File

@ -5,12 +5,16 @@
include <parameters.scad>
include <components.scad>
use <frame-piece-side.scad>
use <frames/complete/left-frame.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
projection(cut=true) rotate([0, 90, 0]) translate([frame_x/2-frame_bevel_height, 0, 0])
side_frame_piece();
// 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_frame_piece_extension() {
@ -23,7 +27,7 @@ module side_frame_piece_extension() {
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);
}

View File

@ -5,11 +5,11 @@
include <parameters.scad>
include <components.scad>
use <frame-piece-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,50 +0,0 @@
/*
* SPDX-FileCopyrightText: © 2024 Brian S. Stephan <bss@incorporeal.org>
* SPDX-License-Identifier: GPL-3.0-or-later
*/
include <parameters.scad>
decorative_radius_scale = 1.5;
jumbo_decorative_radius_scale = 0;
include <components.scad>
module dir_arc_plus_w_30mm_and_sega_2p_plus_one_decorative_plate_of_plates() {
difference() {
// get a 2mm slice of the bigger button cylinders
union() {
translate([-panel_x/2, 0, -25]) {
hull() union() {
dir_arc_30mm_finger_buttons();
translate([-26.8, 57.2+12.9+34.5, 0]) dir_arc_30mm_thumb_button();
}
}
translate([panel_x/2, 0, -25]) {
hull() sega_2p();
}
hull() {
translate([-panel_x/2, 0, -25]) dir_arc_30mm_thumb_button();
translate([panel_x/2, -19-9-11-19-9-11, -25]) sega_2p_p1();
}
difference() {
translate([-60, -8, 0]) cube(60, center=true);
translate([-98.35, -39.25, 0]) cylinder(h=50, r=48, $fn=50, center=true);
}
difference() {
translate([43.35, -10.30, 0]) cube(50, center=true);
translate([68.35, -35.30, 0]) cylinder(h=50, r=18, $fn=50, center=true);
}
difference() {
translate([-10, 55, 0]) cube(43, center=true);
translate([-5.15, 76.25, 0]) cylinder(h=50, r=27, $fn=50, center=true);
}
translate([-7, 0, 0]) cube(80, center=true);
}
translate([0, 0, -100]) cube([500, 500, 198], center=true);
translate([0, 0, 100]) cube([500, 500, 198], center=true);
// cut out the normal holes
translate([-panel_x/2, 0, -1]) dir_arc_w_30mm();
translate([panel_x/2, 0, -1]) sega_2p_plus_one();
}
}
dir_arc_plus_w_30mm_and_sega_2p_plus_one_decorative_plate_of_plates();

View File

@ -5,7 +5,7 @@
include <parameters.scad>
include <components.scad>
use <misc-neutrik-d-plate.scad>
use <neutrik-d-plate.scad>
module aux_connectors_two_neutrik_cluster_decorative_plate() {
difference() {

View File

@ -5,7 +5,7 @@
include <parameters.scad>
include <components.scad>
use <misc-neutrik-d-plate.scad>
use <neutrik-d-plate.scad>
module aux_control_three_button_cluster_decorative_plate() {
difference() {

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

@ -5,7 +5,7 @@
include <parameters.scad>
include <components.scad>
use <misc-neutrik-d-plate.scad>
use <neutrik-d-plate.scad>
module neutrik_d_plate_24mm() {
difference() {

View File

@ -5,7 +5,7 @@
include <parameters.scad>
include <components.scad>
use <misc-neutrik-d-plate.scad>
use <neutrik-d-plate.scad>
module rocker_plate_20mm() {
difference() {

View File

@ -5,7 +5,7 @@
include <parameters.scad>
include <components.scad>
use <top-panel-inset-dir_arc-plus-w-30mm-plus-one.scad>
use <dir_arc-plus-w-30mm-plus-one-panel.scad>
module dir_arc_w_30mm_plus_one_panel_with_mount() {
dir_arc_w_30mm_plus_one_panel();

View File

@ -6,7 +6,7 @@
include <parameters.scad>
include <components.scad>
module top_panel_inset_lever_and_dir_arc_w_30mm() {
module lever_and_dir_arc_w_30mm_panel() {
difference() {
panel();
dir_arc_w_30mm();
@ -15,4 +15,4 @@ module top_panel_inset_lever_and_dir_arc_w_30mm() {
}
}
top_panel_inset_lever_and_dir_arc_w_30mm();
lever_and_dir_arc_w_30mm_panel();

View File

@ -5,7 +5,7 @@
include <parameters.scad>
include <components.scad>
use <top-panel-inset-lever.scad>
use <lever-panel.scad>
module lever_panel_with_mount() {
lever_panel();

View File

@ -6,4 +6,4 @@
include <parameters.scad>
include <components.scad>
bottom_panel();
panel();

View File

@ -5,11 +5,11 @@
include <parameters.scad>
include <components.scad>
use <top-panel-inset-sega-2p-plus-one-plus-control.scad>
use <sega-2p-plus-one-plus-control-panel.scad>
module top_panel_inset_sega_2p_plus_one_plus_control_with_mount() {
top_panel_inset_sega_2p_plus_one_plus_control();
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();
}
top_panel_inset_sega_2p_plus_one_plus_control_with_mount();
sega_2p_plus_one_plus_control_panel_with_mount();

View File

@ -6,7 +6,7 @@
include <parameters.scad>
include <components.scad>
module top_panel_inset_sega_2p_plus_one_plus_control() {
module sega_2p_plus_one_plus_control_panel() {
difference() {
panel();
sega_2p_plus_one();
@ -15,4 +15,4 @@ module top_panel_inset_sega_2p_plus_one_plus_control() {
}
}
top_panel_inset_sega_2p_plus_one_plus_control();
sega_2p_plus_one_plus_control_panel();

View File

@ -6,11 +6,11 @@
include <parameters.scad>
include <components.scad>
module top_panel_inset_shiokenstar_left() {
module shiokenstar_left_panel() {
difference() {
translate([-frame_x/2+frame_wall, 0, 0]) panel();
translate([75, 0, 0]) shiokenstar();
}
}
top_panel_inset_shiokenstar_left();
shiokenstar_left_panel();

View File

@ -6,11 +6,11 @@
include <parameters.scad>
include <components.scad>
module top_panel_inset_shiokenstar_right() {
module shiokenstar_right_panel() {
difference() {
translate([frame_x/2-frame_wall, 0, 0]) panel();
translate([75, 0, 0]) shiokenstar();
}
}
top_panel_inset_shiokenstar_right();
shiokenstar_right_panel();

View File

@ -6,7 +6,7 @@
include <parameters.scad>
include <components.scad>
module top_panel_left_lever_and_dir_arc_w_30mm() {
module lever_and_dir_arc_w_30mm_left_overhang_panel() {
difference() {
panel_with_raised_overhang();
dir_arc_w_30mm();
@ -16,4 +16,4 @@ module top_panel_left_lever_and_dir_arc_w_30mm() {
}
}
top_panel_left_lever_and_dir_arc_w_30mm();
lever_and_dir_arc_w_30mm_left_overhang_panel();

View File

@ -7,7 +7,7 @@ include <parameters.scad>
include <components.scad>
// combine the lever mount and generic plate, with mounting holes
module top_panel_left_lever() {
module lever_left_overhang_panel() {
difference() {
// base plate
panel_with_raised_overhang();
@ -18,4 +18,4 @@ module top_panel_left_lever() {
}
}
top_panel_left_lever();
lever_left_overhang_panel();

View File

@ -5,14 +5,14 @@
include <parameters.scad>
include <components.scad>
use <bottom-panel-overhang-solo.scad>
use <solo-panel.scad>
module bottom_panel_left() {
module left_or_right_overhang_panel() {
difference() {
bottom_panel_solo();
solo_overhang_panel();
// chop the right edge off
side_chopper();
}
}
bottom_panel_left();
left_or_right_overhang_panel();

View File

@ -5,11 +5,11 @@
include <parameters.scad>
include <components.scad>
use <top-panel-overhang-middle-dir_arc-plus-w-30mm.scad>
use <middle-dir_arc-plus-w-30mm-panel.scad>
module top_panel_middle_dir_arc_w_30mm_with_mount() {
top_panel_middle_dir_arc_w_30mm();
module dir_arc_w_30mm_middle_overhang_panel_with_mount() {
dir_arc_w_30mm_middle_overhang_panel();
translate([-15, -40, -(panel_z/2) - 3]) rotate([0, 0, -45]) pcb_mount();
}
top_panel_middle_dir_arc_w_30mm_with_mount();
dir_arc_w_30mm_middle_overhang_panel_with_mount();

View File

@ -6,7 +6,7 @@
include <parameters.scad>
include <components.scad>
module top_panel_middle_dir_arc_w_30mm() {
module dir_arc_w_30mm_middle_overhang_panel() {
difference() {
panel_with_raised_overhang();
dir_arc_w_30mm();
@ -15,4 +15,4 @@ module top_panel_middle_dir_arc_w_30mm() {
}
}
top_panel_middle_dir_arc_w_30mm();
dir_arc_w_30mm_middle_overhang_panel();

View File

@ -5,14 +5,13 @@
include <parameters.scad>
include <components.scad>
use <bottom-panel-overhang-left.scad>
use <bottom-panel-overhang-right.scad>
use <left-or-right-panel.scad>
module bottom_panel_middle() {
module middle_overhang_panel() {
intersection() {
bottom_panel_left();
bottom_panel_right();
left_or_right_overhang_panel();
mirror([1, 0, 0]) left_or_right_overhang_panel();
}
}
bottom_panel_middle();
middle_overhang_panel();

View File

@ -5,11 +5,11 @@
include <parameters.scad>
include <components.scad>
use <top-panel-overhang-right-sega-2p-plus-one.scad>
use <right-sega-2p-plus-one-panel.scad>
module top_panel_right_sega_2p_plus_one_with_mount() {
top_panel_right_sega_2p_plus_one();
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();
}
top_panel_right_sega_2p_plus_one_with_mount();
sega_2p_plus_one_with_mount_right_overhang_panel();

View File

@ -6,7 +6,7 @@
include <parameters.scad>
include <components.scad>
module top_panel_right_sega_2p_plus_one() {
module sega_2p_plus_one_right_overhang_panel() {
difference() {
panel_with_raised_overhang();
sega_2p_plus_one();
@ -14,4 +14,4 @@ module top_panel_right_sega_2p_plus_one() {
}
}
top_panel_right_sega_2p_plus_one();
sega_2p_plus_one_right_overhang_panel();

View File

@ -5,14 +5,14 @@
include <parameters.scad>
include <components.scad>
use <top-panel-overhang-right-sega-2p-plus-one-plus-control-with-mount.scad>
use <right-sega-2p-plus-one-plus-control-panel-with-mount.scad>
module top_panel_right_sega_2p_plus_one_plus_control_with_mount_with_oled() {
module sega_2p_plus_one_plus_control_right_overhang_panel_with_mount_with_oled() {
difference() {
top_panel_right_sega_2p_plus_one_plus_control_with_mount();
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();
}
top_panel_right_sega_2p_plus_one_plus_control_with_mount_with_oled();
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,7 +6,7 @@
include <parameters.scad>
include <components.scad>
module top_panel_right_sega_2p_plus_one_plus_control() {
module sega_2p_plus_one_plus_control_right_overhang_panel() {
difference() {
panel_with_raised_overhang();
sega_2p_plus_one();
@ -15,4 +15,4 @@ module top_panel_right_sega_2p_plus_one_plus_control() {
}
}
top_panel_right_sega_2p_plus_one_plus_control();
sega_2p_plus_one_plus_control_right_overhang_panel();

View File

@ -6,11 +6,11 @@
include <parameters.scad>
include <components.scad>
module dir_arc_24mm_6_button_panel() {
module dir_arc_24mm_6_button_solo_overhang_panel() {
difference() {
panel_with_raised_overhang();
translate([-71.5, -panel_y/2+122.5, 0]) dir_arc_24mm_6_button();
}
}
dir_arc_24mm_6_button_panel();
dir_arc_24mm_6_button_solo_overhang_panel();

View File

@ -6,11 +6,11 @@
include <parameters.scad>
include <components.scad>
module dir_arc_plus_w_24mm_8_button_panel() {
module dir_arc_plus_w_24mm_8_button_solo_overhang_panel() {
difference() {
panel_with_raised_overhang();
translate([-80.5, panel_y/6, 0]) dir_arc_plus_w_24mm_8_button();
}
}
dir_arc_plus_w_24mm_8_button_panel();
dir_arc_plus_w_24mm_8_button_solo_overhang_panel();

View File

@ -6,7 +6,7 @@
include <parameters.scad>
include <components.scad>
module top_panel_solo_lever_and_sega_2p_6_button() {
module lever_and_sega_2p_6_button_solo_overhang_panel() {
difference() {
// base plate
union() {
@ -18,4 +18,4 @@ module top_panel_solo_lever_and_sega_2p_6_button() {
}
}
top_panel_solo_lever_and_sega_2p_6_button();
lever_and_sega_2p_6_button_solo_overhang_panel();

View File

@ -6,11 +6,11 @@
include <parameters.scad>
include <components.scad>
module bottom_panel_solo() {
module solo_overhang_panel() {
difference() {
rotate([180, 0, 0]) base_panel_with_raised_overhang();
rotate([180, 0, 0]) panel_holes();
}
}
bottom_panel_solo();
solo_overhang_panel();

View File

@ -67,6 +67,9 @@ panel_x = frame_x - (frame_wall * 2);
panel_y = frame_y - (frame_wall * 2);
panel_z = 5;
// inside the frame
inner_frame_z = frame_z - (panel_z * 2);
// how much the top plate x/y is expanded to overhang the frame
// note that this is relative to the top plate (so the wall is added back)
panel_overhang_amount = 8.5;

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