234 lines
7.2 KiB
Python
234 lines
7.2 KiB
Python
import cadquery as cq
|
|
from cadquery import exporters
|
|
|
|
from modelo import (
|
|
height,
|
|
mounting_pillar_positions,
|
|
ti_depth,
|
|
ti_radius,
|
|
width,
|
|
thickness as model_thickness,
|
|
shell_t,
|
|
)
|
|
|
|
import keyboard
|
|
import screen_mount
|
|
|
|
hinge_radius = 5.5
|
|
screw_radius = 1.5 # M3
|
|
ring_radius = 5 # M3
|
|
hinge_offset = max(p[1] for p in mounting_pillar_positions) + 6
|
|
hinge_width = 25
|
|
thickness = 42
|
|
|
|
# This is a constant used to control how far back the hinges go
|
|
# when open. It's arbitrary and can be adjusted experimentally
|
|
# printing small samples
|
|
hinge_slant = shell_t + 2
|
|
|
|
|
|
def model():
|
|
# Create a 2-part hinged lid
|
|
|
|
model = (
|
|
cq.Workplane("XY")
|
|
# Hollow box
|
|
.workplane(offset=-thickness / 2)
|
|
.box(width, height, thickness)
|
|
.edges("<Y and >Z")
|
|
.fillet(10)
|
|
.edges(">Y and >Z")
|
|
.fillet(5)
|
|
.faces("<Z")
|
|
.shell(-shell_t)
|
|
# Outer surface of the hinge
|
|
.faces(">X")
|
|
.workplane(centerOption="CenterOfBoundBox")
|
|
.center(height / 2 - hinge_offset, thickness / 2 - hinge_radius)
|
|
.tag("rightSide")
|
|
.placeSketch(cq.Sketch().circle(hinge_radius))
|
|
.extrude(-width)
|
|
# Cut middle section between the hinges
|
|
.workplaneFromTagged("rightSide")
|
|
.workplane(offset=-hinge_width)
|
|
.placeSketch(
|
|
cq.Sketch().polygon(
|
|
[
|
|
(-hinge_radius, -hinge_radius),
|
|
(-hinge_radius, 0),
|
|
(-hinge_radius - hinge_slant, hinge_radius),
|
|
(-hinge_slant, hinge_radius),
|
|
(-hinge_slant, hinge_radius - hinge_slant),
|
|
(hinge_radius, hinge_radius - hinge_slant),
|
|
(hinge_radius, -hinge_radius),
|
|
(-hinge_radius, -hinge_radius),
|
|
]
|
|
)
|
|
)
|
|
.cutBlind(-width + 2 * hinge_width - 1)
|
|
# Hole for screws
|
|
.workplaneFromTagged("rightSide")
|
|
.placeSketch(cq.Sketch().circle(screw_radius))
|
|
.cutBlind(-width)
|
|
# Holes for rings & screw heads
|
|
.workplaneFromTagged("rightSide")
|
|
.placeSketch(cq.Sketch().circle(ring_radius))
|
|
.cutBlind(-5)
|
|
.workplaneFromTagged("rightSide")
|
|
.workplane(offset=-width + 4)
|
|
.placeSketch(cq.Sketch().circle(ring_radius))
|
|
.cutBlind(-5)
|
|
# Split hinge halves
|
|
.faces(">X")
|
|
.workplaneFromTagged("rightSide")
|
|
.workplane(offset=-hinge_width / 2)
|
|
.placeSketch(cq.Sketch().trapezoid(hinge_radius * 2 + 1, hinge_radius * 2, 90))
|
|
.cutBlind(-1)
|
|
.workplaneFromTagged("rightSide")
|
|
.workplane(offset=-hinge_width)
|
|
.placeSketch(cq.Sketch().trapezoid(hinge_radius * 2 + 1, hinge_radius * 2, 90))
|
|
.cutBlind(-1)
|
|
.workplaneFromTagged("rightSide")
|
|
.workplane(offset=-width + hinge_width / 2)
|
|
.placeSketch(cq.Sketch().trapezoid(hinge_radius * 2 + 1, hinge_radius * 2, 90))
|
|
.cutBlind(-1)
|
|
.workplaneFromTagged("rightSide")
|
|
.workplane(offset=-width + hinge_width)
|
|
.placeSketch(cq.Sketch().trapezoid(hinge_radius * 2 + 1, hinge_radius * 2, 90))
|
|
.cutBlind(-1)
|
|
# Threaded inserts
|
|
.workplaneFromTagged("rightSide")
|
|
.workplane(offset=-hinge_width / 2)
|
|
.placeSketch(cq.Sketch().circle(ti_radius))
|
|
.cutBlind(-ti_depth)
|
|
.workplaneFromTagged("rightSide")
|
|
.workplane(offset=-width + hinge_width / 2)
|
|
.placeSketch(cq.Sketch().circle(ti_radius))
|
|
.cutBlind(ti_depth)
|
|
# Split two halves
|
|
# First cut for the right hinge
|
|
.workplaneFromTagged("rightSide")
|
|
.placeSketch(
|
|
cq.Sketch()
|
|
.polygon(
|
|
[
|
|
(0, 0),
|
|
(-hinge_radius - 0.2, 0),
|
|
(-hinge_radius - hinge_slant, hinge_radius),
|
|
(0, hinge_radius),
|
|
(0, 0),
|
|
]
|
|
)
|
|
.polygon(
|
|
[
|
|
(-hinge_radius - 0.2, 0),
|
|
(-hinge_radius - 0.2, -1000),
|
|
(-hinge_radius, -1000),
|
|
(-hinge_radius, 0),
|
|
(-hinge_radius - 0.2, 0),
|
|
]
|
|
)
|
|
.circle(hinge_radius, mode="s")
|
|
)
|
|
.cutBlind(-hinge_width / 2 - 1)
|
|
# Second cut for the right hinge
|
|
.workplaneFromTagged("rightSide")
|
|
.workplane(offset=-hinge_width / 2)
|
|
.placeSketch(
|
|
cq.Sketch()
|
|
.polygon(
|
|
[
|
|
(0, 0),
|
|
(hinge_radius + 0.2, 0),
|
|
(hinge_radius + 0.2 + hinge_slant, hinge_radius),
|
|
(0, hinge_radius),
|
|
(0, 0),
|
|
]
|
|
)
|
|
.circle(hinge_radius, mode="s")
|
|
)
|
|
.cutBlind(-hinge_width / 2 - 1)
|
|
# First cut for the left hinge
|
|
.workplaneFromTagged("rightSide")
|
|
.workplane(offset=-width + hinge_width)
|
|
.placeSketch(
|
|
cq.Sketch()
|
|
.polygon(
|
|
[
|
|
(0, 0),
|
|
(hinge_radius + 0.2, 0),
|
|
(hinge_radius + 0.2 + hinge_slant, hinge_radius),
|
|
(0, hinge_radius),
|
|
(0, 0),
|
|
]
|
|
)
|
|
.circle(hinge_radius, mode="s")
|
|
)
|
|
.cutBlind(-hinge_width / 2 - 1)
|
|
# Second cut for the left hinge
|
|
.workplaneFromTagged("rightSide")
|
|
.workplane(offset=-width + hinge_width / 2)
|
|
.placeSketch(
|
|
cq.Sketch()
|
|
.polygon(
|
|
[
|
|
(0, 0),
|
|
(-hinge_radius - 0.2, 0),
|
|
(-hinge_radius - hinge_slant, hinge_radius),
|
|
(0, hinge_radius),
|
|
(0, 0),
|
|
]
|
|
)
|
|
.polygon(
|
|
[
|
|
(-hinge_radius - 0.2, 0),
|
|
(-hinge_radius - 0.2, -1000),
|
|
(-hinge_radius, -1000),
|
|
(-hinge_radius, 0),
|
|
(-hinge_radius - 0.2, 0),
|
|
]
|
|
)
|
|
.circle(hinge_radius, mode="s")
|
|
)
|
|
.cutBlind(-hinge_width / 2 - 1)
|
|
)
|
|
|
|
# Cut off shape of the base
|
|
|
|
model = (
|
|
model.workplaneFromTagged("rightSide")
|
|
.center(-height + hinge_offset, -thickness + hinge_radius)
|
|
.placeSketch(
|
|
cq.Sketch().polygon(
|
|
[
|
|
(0, 0),
|
|
(0, keyboard.front_thickness),
|
|
(shell_t, keyboard.front_thickness),
|
|
(keyboard.actual_height + shell_t, keyboard.back_thickness),
|
|
(keyboard.actual_height + shell_t, model_thickness),
|
|
(height, model_thickness),
|
|
(height, 0),
|
|
(0, 0),
|
|
]
|
|
)
|
|
)
|
|
.cutBlind(-1000)
|
|
)
|
|
|
|
return model
|
|
|
|
|
|
if __name__ == "__main__":
|
|
model = model()
|
|
|
|
exporters.export(model, "hinged_lid.stl")
|
|
|
|
exporters.export(
|
|
model,
|
|
"hinged_lid.svg",
|
|
opt={
|
|
"projectionDir": (0, 0, 1),
|
|
"strokeWidth": 0.3,
|
|
},
|
|
)
|