Hitching a ride on this thread rather than start one, since I’m asking just to gauge interest.
You saw how I’ve been making 3D printed panels for my synths? I don’t mention it every time but I make them out of code.
I’m toying with cleaning up my system to turn it into a more user-friendly library than my collection of copy-pasted standalone hacks.
The main value the library would provide is a collection of footprints tested to work well. For example you can see how the pots have retaining notches, or the jacks have a recessed area.
I’m considering also adding simple display objects that won’t be printed giving you a conservative estimate of the footprint of stuff (how big a jack is, how much clearance there is between knobs of a specific diameter).
Now, the code right now is a bit nasty-looking:
import cadquery as cq
# Base panel
panelWidth = 25
panelHeight = 200
panelThickness = 4.0
m3Diameter = 3.4
m2Diameter = 2.6
panel = cq.Workplane("XY").box(panelWidth, panelHeight, panelThickness)
# Slots for M3 screws in the corners
panel = (
panel.faces(">Z")
.workplane()
.rect(panelWidth - m3Diameter * 3, panelHeight - 6, forConstruction=True)
.vertices()
.slot2D(m3Diameter * 2.5, m3Diameter, 0)
.cutThruAll()
)
# Holes for switches in horizontal position
switchWidth = 13.2
switchLength = 8.2
switchHoleDiameter = 6
switchDistance = 12
switchX = 7.5
firstSwitchY = 25
switchesLocations = [
[7.5, 25],
[7.5, 35],
[7.5, 45],
[7.5, 55],
[7.5, 65],
[7.5, 75],
[7.5, 85],
[7.5, 95],
]
switchY = firstSwitchY
for pos in switchesLocations:
panel = (
panel.faces(">Z")
.vertices("<XY")
.workplane(centerOption="CenterOfMass")
.center(switchX, switchY)
.hole(switchHoleDiameter)
)
panel = (
panel.faces(">Z")
.vertices("<XY")
.workplane(centerOption="CenterOfMass")
.center(switchX, switchY)
.rect(switchWidth, switchLength)
.cutBlind(-panelThickness / 2)
)
switchY += switchDistance
# Corresponding Holes for LEDs.
ledDiameter = 5.35
ledOffset = 10.5
ledX = switchX + ledOffset
ledY = firstSwitchY
for pos in switchesLocations:
pos[0] += ledOffset
panel = (
panel.faces(">Z")
.vertices("<XY")
.workplane(centerOption="CenterOfMass")
.center(ledX, ledY)
.hole(ledDiameter)
)
ledY += switchDistance
# Reset button
resetPos = [12.5, 125]
resetInnerHole = 6.7
resetOuterHole = 6.7
panel = (
panel.faces(">Z")
.vertices("<XY")
.workplane(centerOption="CenterOfMass")
.center(resetPos[0], resetPos[1])
.hole(resetInnerHole)
)
# Holes for jacks
jackDiameter = 10
jackWidth = 16.2
jackLength = jackWidth
jackLocations = [
[12.5, 145],
[12.5, 175],
]
for pos in jackLocations:
panel = (
panel.faces(">Z")
.vertices("<XY")
.workplane(centerOption="CenterOfMass")
.center(pos[0], pos[1])
.hole(jackDiameter)
)
panel = (
panel.faces(">Z")
.vertices("<XY")
.workplane(centerOption="CenterOfMass")
.center(pos[0], pos[1])
.rect(jackWidth, jackLength)
.cutBlind(-panelThickness / 3)
)
I’d like to instead provide a simple syntax that’s closer to how you would think of a synth panel, e.g.:
import cadquery as cq
defaultThickness = 4.0
eurorackHeight = 133.35
kosmoHeight = 200.0
################## Helpers
def hp(hp: float) -> float:
"""Converts Horizontal Pitch to millimeters.
1 HP == 0.2 inches == 5.08 millimeters"""
return hp * 5.08
################## Panels
def panel(width: float = 100, height: float = 100, thickness: float = defaultThickness):
"""Returns a rectangular panel of arbitrary dimensions."""
return cq.Workplane("XY").box(width, height, thickness)
def eurorackPanel(width: float = hp(2), thickness: float = defaultThickness):
"""Returns a Eurorack panel. Width best defined in hp().
A thickness of 4mm minimum is recommended for solidity."""
return panel(width, eurorackHeight, thickness)
def kosmoPanel(width: float = 25, thickness: float = defaultThickness):
"""Returns a Kosmo (Metric 5U) panel. Widths should be multiples of 25.
A thickness of 4mm minimum is recommended for solidity."""
return panel(width, kosmoHeight, thickness)
Quick show of hands:
- Any interest in using such a system at all? No real knowledge of Python would be required beyond already knowing how to code a little in any language.
- Are you willing to tolerate an awkward UI if decent instructions are provided? It’d be a Jupyter notebook in your browser or local software (CQ-Editor) that’s a bit rough around the edges.
For example this is what I use: