cadquery/notebook_nueva/hinged_lid.py

417 lines
13 KiB
Python
Raw Normal View History

2023-04-04 21:04:53 +00:00
import cadquery as cq
import dimensions as dim
2023-04-15 21:48:04 +00:00
import components.keyboard as keyboard
2023-04-15 22:58:12 +00:00
import components.screen_pillars as screen_pillars
2023-04-15 21:39:03 +00:00
from utils import export
2023-04-05 20:35:11 +00:00
mounting_pillar_positions = [(x, -y) for x, y in dim.mounting_pillar_positions]
mounting_pillars = (
cq.Sketch()
.push(mounting_pillar_positions)
2023-04-15 22:58:12 +00:00
.trapezoid(screen_pillars.pillar_height, screen_pillars.pillar_width, 90, mode="a")
.circle(dim.ti_radius, mode="s")
.clean()
)
2023-04-06 19:59:32 +00:00
2023-04-04 21:04:53 +00:00
def model():
2023-04-05 20:35:11 +00:00
# Create a 2-part hinged lid
2023-04-04 21:04:53 +00:00
model = (
cq.Workplane("XY")
# Hollow box
.workplane(offset=-dim.hl_full_thickness / 2)
.box(dim.width, dim.height, dim.hl_full_thickness)
2023-04-08 17:24:03 +00:00
.tag("base")
2023-04-07 20:30:57 +00:00
.edges("|X and >Z and <Y")
.fillet(10)
.edges("|X and >Z and >Y")
.fillet(5)
2023-04-06 20:39:18 +00:00
.edges("|Z")
.fillet(2)
2023-04-05 20:35:11 +00:00
.faces("<Z")
.shell(-dim.shell_t)
2023-04-04 21:04:53 +00:00
.faces(">X")
2023-04-07 20:30:57 +00:00
.workplane()
.center(
dim.height / 2 - dim.hl_hinge_offset,
dim.hl_full_thickness / 2 - dim.hl_hinge_radius,
)
2023-04-04 21:04:53 +00:00
.tag("rightSide")
2023-04-07 20:30:57 +00:00
# Outer surface of the hinge
.workplaneFromTagged("rightSide")
.placeSketch(cq.Sketch().circle(dim.hl_hinge_radius))
.extrude(-dim.hl_hinge_width)
2023-04-08 17:24:03 +00:00
.workplaneFromTagged("rightSide")
.workplane(offset=-dim.width + dim.hl_hinge_width)
.placeSketch(cq.Sketch().circle(dim.hl_hinge_radius))
.extrude(-dim.hl_hinge_width)
2023-04-05 20:35:11 +00:00
# Cut middle section between the hinges
.workplaneFromTagged("rightSide")
.workplane(offset=-dim.hl_hinge_width)
2023-04-05 20:35:11 +00:00
.placeSketch(
cq.Sketch().polygon(
[
(-dim.hl_hinge_radius, -dim.hl_hinge_radius),
(-dim.hl_hinge_radius, 0),
(-dim.hl_hinge_radius - dim.hl_hinge_slant, dim.hl_hinge_radius),
(-dim.hl_hinge_slant, dim.hl_hinge_radius),
(-dim.hl_hinge_slant, dim.hl_hinge_radius - dim.hl_hinge_slant),
(dim.hl_hinge_radius, dim.hl_hinge_radius - dim.hl_hinge_slant),
(dim.hl_hinge_radius, -dim.hl_hinge_radius),
(-dim.hl_hinge_radius, -dim.hl_hinge_radius),
2023-04-05 20:35:11 +00:00
]
)
)
.cutBlind(-dim.width + 2 * dim.hl_hinge_width - 1)
2023-04-08 17:24:03 +00:00
# Pillars to attach to base
.workplaneFromTagged("base")
.workplane(
centerOption="CenterOfBoundBox",
offset=dim.base_thickness - dim.hl_full_thickness / 2,
2023-04-08 17:24:03 +00:00
)
2023-04-08 17:41:27 +00:00
.workplaneFromTagged("base")
.workplane(offset=dim.hl_full_thickness / 2 - dim.shell_t)
.center(-dim.width / 2, dim.height / 2 - dim.shell_t)
2023-04-08 17:24:03 +00:00
.placeSketch(mounting_pillars)
2023-04-08 17:41:27 +00:00
.extrude(-10)
2023-04-04 21:04:53 +00:00
# Hole for screws
2023-04-05 20:35:11 +00:00
.workplaneFromTagged("rightSide")
.placeSketch(cq.Sketch().circle(dim.hl_screw_radius))
.cutBlind(-dim.hl_hinge_width)
2023-04-08 17:24:03 +00:00
.workplaneFromTagged("rightSide")
.workplane(offset=-dim.width + dim.hl_hinge_width)
.placeSketch(cq.Sketch().circle(dim.hl_screw_radius))
.cutBlind(-dim.hl_hinge_width)
2023-04-04 21:04:53 +00:00
# Holes for rings & screw heads
2023-04-05 20:35:11 +00:00
.workplaneFromTagged("rightSide")
.placeSketch(cq.Sketch().circle(dim.hl_ring_radius))
2023-04-04 21:04:53 +00:00
.cutBlind(-5)
2023-04-05 20:35:11 +00:00
.workplaneFromTagged("rightSide")
.workplane(offset=-dim.width + 4)
.placeSketch(cq.Sketch().circle(dim.hl_ring_radius))
2023-04-04 21:04:53 +00:00
.cutBlind(-5)
# Split hinge halves
.faces(">X")
2023-04-05 20:35:11 +00:00
.workplaneFromTagged("rightSide")
.workplane(offset=-dim.hl_hinge_width / 2)
.placeSketch(
cq.Sketch().trapezoid(
dim.hl_hinge_radius * 2 + 1, dim.hl_hinge_radius * 2, 90
)
)
2023-04-05 20:35:11 +00:00
.cutBlind(-1)
.workplaneFromTagged("rightSide")
.workplane(offset=-dim.hl_hinge_width)
.placeSketch(
cq.Sketch().trapezoid(
dim.hl_hinge_radius * 2 + 1, dim.hl_hinge_radius * 2, 90
)
)
2023-04-05 20:35:11 +00:00
.cutBlind(-1)
.workplaneFromTagged("rightSide")
.workplane(offset=-dim.width + dim.hl_hinge_width / 2)
.placeSketch(
cq.Sketch().trapezoid(
dim.hl_hinge_radius * 2 + 1, dim.hl_hinge_radius * 2, 90
)
)
2023-04-05 20:35:11 +00:00
.cutBlind(-1)
.workplaneFromTagged("rightSide")
.workplane(offset=-dim.width + dim.hl_hinge_width)
.placeSketch(
cq.Sketch().trapezoid(
dim.hl_hinge_radius * 2 + 1, dim.hl_hinge_radius * 2, 90
)
)
2023-04-04 21:04:53 +00:00
.cutBlind(-1)
# Threaded inserts
2023-04-05 20:35:11 +00:00
.workplaneFromTagged("rightSide")
.workplane(offset=-dim.hl_hinge_width / 2)
.placeSketch(cq.Sketch().circle(dim.ti_radius))
.cutBlind(-dim.ti_depth)
2023-04-05 20:35:11 +00:00
.workplaneFromTagged("rightSide")
.workplane(offset=-dim.width + dim.hl_hinge_width / 2)
.placeSketch(cq.Sketch().circle(dim.ti_radius))
.cutBlind(dim.ti_depth)
2023-04-04 21:04:53 +00:00
# Split two halves
2023-04-05 20:35:11 +00:00
# First cut for the right hinge
2023-04-04 21:04:53 +00:00
.workplaneFromTagged("rightSide")
.placeSketch(
cq.Sketch()
.polygon(
[
(0, 0),
(-dim.hl_hinge_radius - 0.2, 0),
(-dim.hl_hinge_radius - dim.hl_hinge_slant, dim.hl_hinge_radius),
(0, dim.hl_hinge_radius),
2023-04-04 21:04:53 +00:00
(0, 0),
]
)
2023-04-05 20:35:11 +00:00
.polygon(
[
(-dim.hl_hinge_radius - 0.2, 0),
(-dim.hl_hinge_radius - 0.2, -1000),
(-dim.hl_hinge_radius, -1000),
(-dim.hl_hinge_radius, 0),
(-dim.hl_hinge_radius - 0.2, 0),
2023-04-05 20:35:11 +00:00
]
)
.circle(dim.hl_hinge_radius, mode="s")
2023-04-04 21:04:53 +00:00
)
.cutBlind(-dim.hl_hinge_width / 2 - 1)
2023-04-05 20:35:11 +00:00
# Second cut for the right hinge
2023-04-04 21:04:53 +00:00
.workplaneFromTagged("rightSide")
.workplane(offset=-dim.hl_hinge_width / 2)
2023-04-04 21:04:53 +00:00
.placeSketch(
cq.Sketch()
.polygon(
[
(0, 0),
(dim.hl_hinge_radius + 0.2, 0),
(
dim.hl_hinge_radius + 0.2 + dim.hl_hinge_slant,
dim.hl_hinge_radius,
),
(0, dim.hl_hinge_radius),
2023-04-04 21:04:53 +00:00
(0, 0),
]
)
.circle(dim.hl_hinge_radius, mode="s")
2023-04-04 21:04:53 +00:00
)
.cutBlind(-dim.hl_hinge_width / 2 - 1)
2023-04-05 20:35:11 +00:00
# First cut for the left hinge
2023-04-04 21:04:53 +00:00
.workplaneFromTagged("rightSide")
.workplane(offset=-dim.width + dim.hl_hinge_width)
2023-04-04 21:04:53 +00:00
.placeSketch(
cq.Sketch()
.polygon(
[
(0, 0),
(dim.hl_hinge_radius + 0.2, 0),
(
dim.hl_hinge_radius + 0.2 + dim.hl_hinge_slant,
dim.hl_hinge_radius,
),
(0, dim.hl_hinge_radius),
2023-04-04 21:04:53 +00:00
(0, 0),
]
)
.circle(dim.hl_hinge_radius, mode="s")
2023-04-04 21:04:53 +00:00
)
.cutBlind(-dim.hl_hinge_width / 2 - 1)
2023-04-05 20:35:11 +00:00
# Second cut for the left hinge
2023-04-04 21:04:53 +00:00
.workplaneFromTagged("rightSide")
.workplane(offset=-dim.width + dim.hl_hinge_width / 2)
2023-04-04 21:04:53 +00:00
.placeSketch(
cq.Sketch()
.polygon(
[
(0, 0),
(-dim.hl_hinge_radius - 0.2, 0),
(-dim.hl_hinge_radius - dim.hl_hinge_slant, dim.hl_hinge_radius),
(0, dim.hl_hinge_radius),
2023-04-04 21:04:53 +00:00
(0, 0),
]
)
2023-04-05 20:35:11 +00:00
.polygon(
[
(-dim.hl_hinge_radius - 0.2, 0),
(-dim.hl_hinge_radius - 0.2, -1000),
(-dim.hl_hinge_radius, -1000),
(-dim.hl_hinge_radius, 0),
(-dim.hl_hinge_radius - 0.2, 0),
2023-04-05 20:35:11 +00:00
]
)
.circle(dim.hl_hinge_radius, mode="s")
2023-04-04 21:04:53 +00:00
)
.cutBlind(-dim.hl_hinge_width / 2 - 1)
2023-04-05 20:35:11 +00:00
)
2023-04-08 17:41:27 +00:00
# Screen mount
model = (
# 1st layer
2023-04-08 17:41:27 +00:00
model.workplaneFromTagged("base")
.center(0, -32)
.workplane(offset=dim.hl_full_thickness / 2 - dim.shell_t)
.tag("screen_plane")
2023-04-08 17:41:27 +00:00
.placeSketch(
cq.Sketch()
.trapezoid(
dim.scr_w + 2 * dim.hl_bezel_width,
dim.scr_h + 2 * dim.hl_bezel_height,
90,
2023-04-08 17:41:27 +00:00
)
.vertices()
.fillet(2)
)
.extrude(-2 - dim.scr_thickness)
2023-04-15 18:53:52 +00:00
# Hole for screws
2023-04-08 17:41:27 +00:00
.workplaneFromTagged("screen_plane")
.workplane(offset=1)
.rect(
dim.scr_w + 2 * dim.hl_bezel_width - dim.m3_hn_diam - 1,
dim.scr_h + 2 * dim.hl_bezel_height - dim.m3_hn_diam - 1,
forConstruction=True,
)
.vertices()
.hole(dim.m3_hn_hole, depth=10)
2023-04-15 18:53:52 +00:00
# Holes for captured nuts
.workplaneFromTagged("screen_plane")
.workplane(offset=1)
.rect(
dim.scr_w + 2 * dim.hl_bezel_width - dim.m3_hn_diam - 1,
dim.scr_h + 2 * dim.hl_bezel_height - dim.m3_hn_diam - 1,
forConstruction=True,
2023-04-08 17:41:27 +00:00
)
.vertices()
.hole(dim.m3_hn_diam, depth=dim.m3_hn_thickness + 0.5)
2023-04-15 18:53:52 +00:00
# Remove middle of the screen holder
2023-04-08 17:41:27 +00:00
.workplaneFromTagged("screen_plane")
.placeSketch(
cq.Sketch().trapezoid(
dim.scr_w - 40,
dim.scr_h + 2 * dim.hl_bezel_height,
90,
)
2023-04-08 17:41:27 +00:00
)
.cutBlind(-100)
2023-04-15 18:53:52 +00:00
# Hole to place screen
2023-04-08 17:41:27 +00:00
.workplaneFromTagged("screen_plane")
.workplane(offset=-dim.scr_thickness - 2)
.placeSketch(cq.Sketch().trapezoid(dim.scr_w, dim.scr_h, 90))
.cutBlind(dim.scr_thickness)
2023-04-08 17:41:27 +00:00
)
2023-04-05 20:35:11 +00:00
# Cut off shape of the base
model = (
model.workplaneFromTagged("rightSide")
.center(
-dim.height + dim.hl_hinge_offset,
-dim.hl_full_thickness + dim.hl_hinge_radius,
)
2023-04-05 20:35:11 +00:00
.placeSketch(
cq.Sketch().polygon(
[
(0, 0),
(0, keyboard.kbd_front_thickness),
(dim.shell_t, keyboard.kbd_front_thickness),
(keyboard.kbd_actual_height + dim.shell_t, keyboard.kbd_back_thickness),
(keyboard.kbd_actual_height + dim.shell_t, dim.base_thickness),
(dim.height, dim.base_thickness),
(dim.height, 0),
2023-04-05 20:35:11 +00:00
(0, 0),
]
)
)
.cutBlind(-1000)
2023-04-04 21:04:53 +00:00
)
return model
2023-04-15 18:53:52 +00:00
def front_bezel():
model = (
cq.Workplane("XY")
# Hollow box
.tag("base")
.placeSketch(
cq.Sketch()
.trapezoid(
dim.scr_w + 2 * dim.hl_bezel_width + 2 * dim.hl_bezel_thickness,
dim.scr_h + 2 * dim.hl_bezel_height + 2 * dim.hl_bezel_thickness,
2023-04-15 18:53:52 +00:00
90,
)
.vertices()
.fillet(2)
)
.extrude(-2 - dim.scr_thickness - dim.hl_bezel_thickness)
2023-04-15 18:53:52 +00:00
.workplaneFromTagged("base")
.workplane(offset=-dim.hl_bezel_thickness)
2023-04-15 18:53:52 +00:00
.placeSketch(
cq.Sketch()
.trapezoid(
dim.scr_w + 2 * dim.hl_bezel_width,
dim.scr_h + 2 * dim.hl_bezel_height,
2023-04-15 18:53:52 +00:00
90,
)
.vertices()
.fillet(2)
)
.cutBlind(-100)
# Holes for screws
.workplaneFromTagged("base")
.rect(
dim.scr_w + 2 * dim.hl_bezel_width - dim.m3_hn_diam - 1,
dim.scr_h + 2 * dim.hl_bezel_height - dim.m3_hn_diam - 1,
2023-04-15 18:53:52 +00:00
forConstruction=True,
)
.vertices()
.hole(dim.m3_hn_hole, depth=10)
2023-04-15 18:53:52 +00:00
# Viewport hole
.workplaneFromTagged("base")
.placeSketch(
cq.Sketch()
.trapezoid(
dim.vis_w,
dim.vis_h,
2023-04-15 18:53:52 +00:00
90,
)
.vertices()
.fillet(2)
)
.cutBlind("last")
# Cable gap
.workplaneFromTagged("base")
.workplane(offset=-dim.scr_thickness - dim.hl_bezel_thickness)
2023-04-15 18:53:52 +00:00
.center(0, 10)
.placeSketch(
cq.Sketch()
.trapezoid(
dim.vis_w,
dim.vis_h,
2023-04-15 18:53:52 +00:00
90,
)
.vertices()
.fillet(2)
)
.cutBlind(-10)
)
return model
2023-04-04 21:04:53 +00:00
if __name__ == "__main__":
model = model()
2023-04-05 20:35:11 +00:00
2023-04-15 21:39:03 +00:00
export(model, "hinged_lid.stl")
2023-04-05 20:35:11 +00:00
2023-04-15 21:39:03 +00:00
export(front_bezel(), "hinged_lid_bezel.stl")
2023-04-15 18:53:52 +00:00
2023-04-15 21:39:03 +00:00
export(
2023-04-05 20:35:11 +00:00
model,
"hinged_lid.svg",
opt={
"projectionDir": (0, 0, -1),
2023-04-05 20:35:11 +00:00
"strokeWidth": 0.3,
},
)
offset_width = -dim.width / 2
right_side = (
model.faces(">X")
.workplane(centerOption="CenterOfBoundBox", offset=offset_width)
.split(keepTop=True)
)
2023-04-15 21:39:03 +00:00
export(right_side, "hinged_lid_right.stl")
left_side = (
model.faces(">X")
.workplane(centerOption="CenterOfBoundBox", offset=offset_width)
.split(keepBottom=True)
)
2023-04-15 21:39:03 +00:00
export(left_side, "hinged_lid_left.stl")