cadquery/notebook_nueva/hinged_lid.py

267 lines
8.2 KiB
Python

import cadquery as cq
from cadquery import exporters
import screen_pillars
from modelo import (
height,
mounting_pillar_positions,
ti_depth,
ti_radius,
width,
thickness as model_thickness,
shell_t,
)
from screen_mount import height_bottom
import keyboard
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 = 43
mounting_pillar_positions = [(x, -y) for x, y in mounting_pillar_positions]
mounting_pillars = (
cq.Sketch()
.push(mounting_pillar_positions)
.trapezoid(-12, 12, 90, mode="a")
.circle(ti_radius, mode="s")
.clean()
)
# 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)
.tag("base")
.edges("|X and >Z and <Y")
.fillet(10)
.edges("|X and >Z and >Y")
.fillet(5)
.edges("|Z")
.fillet(2)
.faces("<Z")
.shell(-shell_t)
.faces(">X")
.workplane()
.center(height / 2 - hinge_offset, thickness / 2 - hinge_radius)
.tag("rightSide")
# Outer surface of the hinge
.workplaneFromTagged("rightSide")
.placeSketch(cq.Sketch().circle(hinge_radius))
.extrude(-hinge_width)
.workplaneFromTagged("rightSide")
.workplane(offset=-width + hinge_width)
.placeSketch(cq.Sketch().circle(hinge_radius))
.extrude(-hinge_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)
# Pillars to attach to base
.workplaneFromTagged("base")
.workplane(
centerOption="CenterOfBoundBox", offset=model_thickness - thickness / 2
)
.center(-width / 2, height / 2 - shell_t)
.placeSketch(mounting_pillars)
.extrude(10)
# Hole for screws
.workplaneFromTagged("rightSide")
.placeSketch(cq.Sketch().circle(screw_radius))
.cutBlind(-hinge_width)
.workplaneFromTagged("rightSide")
.workplane(offset=-width + hinge_width)
.placeSketch(cq.Sketch().circle(screw_radius))
.cutBlind(-hinge_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,
},
)