2023-03-28 13:46:48 +00:00
|
|
|
import cadquery as cq
|
|
|
|
import math
|
|
|
|
|
|
|
|
# Size of the kbd board
|
|
|
|
kbd_height = 95.5
|
|
|
|
kbd_width = 305
|
|
|
|
back_thickness = 17
|
|
|
|
front_thickness = 10
|
|
|
|
|
|
|
|
# Pythagoras
|
|
|
|
actual_height = (kbd_height**2 - (back_thickness - front_thickness) ** 2) ** 0.5
|
|
|
|
kbd_angle = math.acos(actual_height / kbd_height) * 180 / math.pi
|
|
|
|
|
|
|
|
kbd_pillar_positions = [
|
|
|
|
(18.25, 16),
|
|
|
|
(142.5, 25.5),
|
|
|
|
(kbd_width - 20, 16),
|
|
|
|
(23.5, 79.5),
|
|
|
|
(145.5, 82.5),
|
|
|
|
(kbd_width - 19, 79.5),
|
|
|
|
]
|
|
|
|
|
|
|
|
elements = [
|
|
|
|
# Shorter pillars
|
|
|
|
{
|
|
|
|
"x": 0,
|
|
|
|
"y": 0,
|
|
|
|
"z": 5.5,
|
2023-03-29 12:05:10 +00:00
|
|
|
"shape": cq.Sketch().push(kbd_pillar_positions).circle(5, mode="a"),
|
2023-03-28 13:46:48 +00:00
|
|
|
},
|
|
|
|
# Taller pillars with holes for self-tapping screws
|
|
|
|
{
|
|
|
|
"x": 0,
|
|
|
|
"y": 0,
|
|
|
|
"z": 2.5,
|
|
|
|
"shape": (
|
|
|
|
cq.Sketch()
|
|
|
|
.push(kbd_pillar_positions)
|
2023-03-29 12:05:10 +00:00
|
|
|
.circle(2.4, mode="a")
|
2023-03-28 13:46:48 +00:00
|
|
|
.circle(1.1, mode="s")
|
|
|
|
),
|
|
|
|
},
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
def add(
|
|
|
|
*,
|
|
|
|
model,
|
|
|
|
width,
|
|
|
|
height,
|
|
|
|
thickness,
|
|
|
|
offset_x,
|
|
|
|
offset_y,
|
|
|
|
bottom_face,
|
|
|
|
back_face,
|
|
|
|
shell_t
|
|
|
|
):
|
|
|
|
|
|
|
|
# This one is special, it creates angled things and cuts off the
|
|
|
|
# case, so ... it's going to do weird stuff
|
|
|
|
|
|
|
|
if bottom_face:
|
|
|
|
model = (
|
|
|
|
model.faces(bottom_face)
|
|
|
|
.workplane(centerOption="CenterOfBoundBox", offset=-front_thickness)
|
|
|
|
.center(
|
|
|
|
-width / 2,
|
|
|
|
height / 2,
|
|
|
|
)
|
|
|
|
.transformed(rotate=cq.Vector(kbd_angle, 0, 0))
|
|
|
|
.tag("kbd_sloped")
|
|
|
|
)
|
|
|
|
for element in elements:
|
|
|
|
model = (
|
|
|
|
model.workplaneFromTagged("kbd_sloped")
|
|
|
|
.center(offset_x + element["x"], -offset_y - element["y"])
|
|
|
|
.workplane(offset=element["z"])
|
|
|
|
.placeSketch(element["shape"])
|
|
|
|
.extrude(100)
|
|
|
|
)
|
|
|
|
|
|
|
|
model = (
|
|
|
|
model.workplaneFromTagged("mid_height")
|
|
|
|
.transformed(offset=cq.Vector(0, 0, -thickness / 2))
|
|
|
|
.split(keepTop=True)
|
|
|
|
.faces(">X")
|
|
|
|
.workplane(centerOption="CenterOfBoundBox")
|
|
|
|
.center(-height / 2, -thickness / 2)
|
|
|
|
.placeSketch(
|
|
|
|
cq.Sketch().polygon(
|
|
|
|
[
|
|
|
|
[0, front_thickness],
|
|
|
|
[actual_height, back_thickness],
|
|
|
|
[actual_height, 1000],
|
|
|
|
[0, 1000],
|
|
|
|
[0, front_thickness],
|
|
|
|
]
|
|
|
|
)
|
|
|
|
)
|
|
|
|
.cutBlind(-1000)
|
|
|
|
)
|
|
|
|
|
|
|
|
return model
|