Compare commits
1 Commits
be6245aa3b
...
resin
Author | SHA1 | Date | |
---|---|---|---|
895e24575e |
7464
notebook_nueva/bottom_left.stl
Normal file
7464
notebook_nueva/bottom_left.stl
Normal file
File diff suppressed because it is too large
Load Diff
13848
notebook_nueva/bottom_right.stl
Normal file
13848
notebook_nueva/bottom_right.stl
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
138778
notebook_nueva/model.stl
138778
notebook_nueva/model.stl
File diff suppressed because it is too large
Load Diff
@ -8,13 +8,13 @@ from cadquery2 import exporters
|
|||||||
shell_t = 3
|
shell_t = 3
|
||||||
|
|
||||||
# Size of the kbd board
|
# Size of the kbd board
|
||||||
kbd_height = 95.5
|
kbd_height = 98
|
||||||
kbd_width = 305
|
kbd_width = 286
|
||||||
kbd_angle = 5
|
kbd_angle = 5
|
||||||
|
|
||||||
# Size of the whole object
|
# Size of the whole object
|
||||||
width = kbd_width + 2 * shell_t
|
width = kbd_width + 2 * shell_t
|
||||||
height = 159
|
height = 164 # Max bed size
|
||||||
thickness = 20 + shell_t # 20 inside
|
thickness = 20 + shell_t # 20 inside
|
||||||
|
|
||||||
# Insert Positions
|
# Insert Positions
|
||||||
@ -22,34 +22,22 @@ ti_radius = 2.35
|
|||||||
ti_depth = 6.25
|
ti_depth = 6.25
|
||||||
|
|
||||||
# Positions are determined by measuring the keyboard
|
# Positions are determined by measuring the keyboard
|
||||||
|
# mounting holes
|
||||||
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),
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
# 2-level mounting pillars for the kbd
|
|
||||||
# Width of these need to be tweaked for
|
|
||||||
# each specific keyboard
|
|
||||||
kbd_pillars = (
|
kbd_pillars = (
|
||||||
cq.Sketch()
|
cq.Sketch()
|
||||||
.push(kbd_pillar_positions)
|
.push(
|
||||||
.circle(2.2, mode="a")
|
[
|
||||||
# Holes for self-tapping screws
|
(19, -16.5),
|
||||||
.circle(1.1, mode="s")
|
(133, -16.5),
|
||||||
)
|
(247.5, -16.5),
|
||||||
|
(24, -86),
|
||||||
kbd_lower_pillars = (
|
(142.5, -91),
|
||||||
cq.Sketch()
|
(261.5, -86),
|
||||||
.push(kbd_pillar_positions)
|
]
|
||||||
.circle(4, mode="a")
|
)
|
||||||
# Holes for self-tapping screws
|
.circle(6, mode="a")
|
||||||
.circle(1.1, mode="s")
|
# Holes for M3 threaded inserts
|
||||||
|
.circle(ti_radius, mode="s")
|
||||||
)
|
)
|
||||||
|
|
||||||
# These are placed where convenient, and are used to join the top and bottom
|
# These are placed where convenient, and are used to join the top and bottom
|
||||||
@ -57,11 +45,10 @@ kbd_lower_pillars = (
|
|||||||
# Measured from top-left corner OUTSIDE
|
# Measured from top-left corner OUTSIDE
|
||||||
mounting_pillar_positions = [
|
mounting_pillar_positions = [
|
||||||
(6, -6),
|
(6, -6),
|
||||||
(6, -40),
|
|
||||||
(120, -6),
|
|
||||||
(170, -6),
|
|
||||||
(width - 6, -6),
|
(width - 6, -6),
|
||||||
(width - 6, -40),
|
(width - 6, -40),
|
||||||
|
(120, -6),
|
||||||
|
(170, -6),
|
||||||
]
|
]
|
||||||
|
|
||||||
mounting_pillars = (
|
mounting_pillars = (
|
||||||
@ -73,8 +60,32 @@ mounting_pillars = (
|
|||||||
|
|
||||||
screw_holes = cq.Sketch().push(mounting_pillar_positions).circle(3, mode="a")
|
screw_holes = cq.Sketch().push(mounting_pillar_positions).circle(3, mode="a")
|
||||||
|
|
||||||
# Hole for the USB hub's exposed port
|
battery_holder = (
|
||||||
|
cq.Sketch()
|
||||||
|
.polygon(
|
||||||
|
[(-67, 5), (0, 5), (0, -12), (-67, -12), (-67, 5)],
|
||||||
|
mode="a",
|
||||||
|
)
|
||||||
|
.trapezoid(83, 83, 90, mode="a")
|
||||||
|
.trapezoid(80, 80, 90, mode="s")
|
||||||
|
.polygon(
|
||||||
|
[(-67, 3), (0, 3), (0, -10), (-67, -10), (-67, 3)],
|
||||||
|
mode="s",
|
||||||
|
)
|
||||||
|
# Cutout for the
|
||||||
|
.polygon(
|
||||||
|
[(-67, 30), (0, 30), (0, 12), (-67, 12), (-67, 30)],
|
||||||
|
mode="s",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
power_in = cq.Sketch().circle(5, mode="a")
|
||||||
usb_in = cq.Sketch().trapezoid(13, 5.5, 90, mode="a")
|
usb_in = cq.Sketch().trapezoid(13, 5.5, 90, mode="a")
|
||||||
|
switch_in = cq.Sketch().trapezoid(13.5, 8, 90, mode="a")
|
||||||
|
|
||||||
|
|
||||||
|
# Motherboard mount
|
||||||
|
|
||||||
|
|
||||||
def model():
|
def model():
|
||||||
@ -88,30 +99,38 @@ def model():
|
|||||||
.fillet(2)
|
.fillet(2)
|
||||||
.faces(">Z")
|
.faces(">Z")
|
||||||
.shell(-shell_t)
|
.shell(-shell_t)
|
||||||
|
# Battery holder
|
||||||
|
.workplaneFromTagged("mid_height")
|
||||||
|
.center(-width / 2 + shell_t + 65, height / 2 - shell_t - 45)
|
||||||
|
.placeSketch(battery_holder)
|
||||||
|
.extrude(-height / 2)
|
||||||
|
# Power cable inlet
|
||||||
|
.faces("<X")
|
||||||
|
.workplane(centerOption="CenterOfBoundBox")
|
||||||
|
.center(-height / 2 + shell_t + 48.5, -3)
|
||||||
|
.placeSketch(power_in)
|
||||||
|
.cutBlind(-shell_t)
|
||||||
# USB inlet
|
# USB inlet
|
||||||
.faces(">X")
|
.faces(">X")
|
||||||
.workplane(centerOption="CenterOfBoundBox")
|
.workplane(centerOption="CenterOfBoundBox")
|
||||||
# The position is arbitrary, based on the components
|
.center(-height / 2 + shell_t + 50, -5)
|
||||||
# available, keyboard height, cable length, etc.
|
|
||||||
.center(-height / 2 + shell_t + 60, -5)
|
|
||||||
.placeSketch(usb_in)
|
.placeSketch(usb_in)
|
||||||
.cutBlind(-shell_t)
|
.cutBlind(-shell_t)
|
||||||
|
# Hole for power switch
|
||||||
|
.faces(">Y")
|
||||||
|
.workplane(centerOption="CenterOfBoundBox")
|
||||||
|
.center(0, 0)
|
||||||
|
.placeSketch(switch_in)
|
||||||
|
.cutBlind(-shell_t)
|
||||||
# Slanted mounting pillars on the kbd top
|
# Slanted mounting pillars on the kbd top
|
||||||
.faces(">Z")
|
.faces(">Z")
|
||||||
.workplane(centerOption="CenterOfBoundBox")
|
.workplane(centerOption="CenterOfBoundBox")
|
||||||
# Top-left kbd corner inside the box
|
# Top-left kbd corner inside the box
|
||||||
.center(-width / 2 + shell_t, kbd_height - height / 2 + shell_t)
|
.center(-width / 2 + shell_t, kbd_height - height / 2 + shell_t)
|
||||||
.transformed(rotate=cq.Vector(kbd_angle, 0, 0))
|
.transformed(rotate=cq.Vector(kbd_angle, 0, 0))
|
||||||
# These two offsets push the keyboard "down" into the case
|
|
||||||
# and need to be adjusted per-keyboard
|
|
||||||
.tag("sloped")
|
.tag("sloped")
|
||||||
.workplane(offset=-2.5)
|
|
||||||
.placeSketch(kbd_pillars)
|
.placeSketch(kbd_pillars)
|
||||||
.extrude(-1000)
|
.extrude(-1000)
|
||||||
.workplaneFromTagged("sloped")
|
|
||||||
.workplane(offset=-5.5)
|
|
||||||
.placeSketch(kbd_lower_pillars)
|
|
||||||
.extrude(-1000)
|
|
||||||
# Remove the excess extrusion
|
# Remove the excess extrusion
|
||||||
.workplaneFromTagged("mid_height")
|
.workplaneFromTagged("mid_height")
|
||||||
.transformed(offset=cq.Vector(0, 0, -thickness / 2))
|
.transformed(offset=cq.Vector(0, 0, -thickness / 2))
|
||||||
@ -138,7 +157,7 @@ def model():
|
|||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
||||||
left_cutout = cq.Sketch().polygon(
|
left_cutout = cq.Sketch().polygon(
|
||||||
[(0, 0), (width / 2, 0), (width / 2, -height), (0, -height), (0, 0)],
|
[(0, 0), (160, 0), (160, -100), (135, -100), (135, -200), (0, -200), (0, 0)],
|
||||||
mode="a",
|
mode="a",
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -156,11 +175,13 @@ if __name__ == "__main__":
|
|||||||
|
|
||||||
right_cutout = cq.Sketch().polygon(
|
right_cutout = cq.Sketch().polygon(
|
||||||
[
|
[
|
||||||
(width / 2, 0),
|
(160, 0),
|
||||||
(width, 0),
|
(width, 0),
|
||||||
(width, -height),
|
(width, -height),
|
||||||
(width / 2, -height),
|
(135, -height),
|
||||||
(width / 2, 0),
|
(135, -100),
|
||||||
|
(160, -100),
|
||||||
|
(160, 0),
|
||||||
],
|
],
|
||||||
mode="a",
|
mode="a",
|
||||||
)
|
)
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@ -10,11 +10,12 @@ from modelo import (
|
|||||||
ti_radius,
|
ti_radius,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
ti_radius = 2.5
|
||||||
|
|
||||||
# Size of the whole object
|
# Size of the whole object
|
||||||
width = kbd_width + 2 * shell_t
|
width = kbd_width + 2 * shell_t
|
||||||
height = 66
|
height = 59
|
||||||
height_bottom = 59
|
thickness = 62 # Will be shorter after construction
|
||||||
thickness = 48 # Will be shorter after construction
|
|
||||||
|
|
||||||
# Visible screen size
|
# Visible screen size
|
||||||
vis_w = 220
|
vis_w = 220
|
||||||
@ -27,9 +28,6 @@ scr_h = 65
|
|||||||
scr_thickness = 5.5
|
scr_thickness = 5.5
|
||||||
screen_cutout = cq.Sketch().trapezoid(scr_w, scr_h, 90, mode="a")
|
screen_cutout = cq.Sketch().trapezoid(scr_w, scr_h, 90, mode="a")
|
||||||
|
|
||||||
# Screen angle
|
|
||||||
scr_angle = 20
|
|
||||||
|
|
||||||
# Circuit board and cable hole.
|
# Circuit board and cable hole.
|
||||||
# This is in the back of the screen, and is a bit shorter in height than the
|
# This is in the back of the screen, and is a bit shorter in height than the
|
||||||
# screen. It's wider so it removes enough material to make the shape simpler.
|
# screen. It's wider so it removes enough material to make the shape simpler.
|
||||||
@ -40,15 +38,13 @@ board_cutout = cq.Sketch().trapezoid(
|
|||||||
mode="a",
|
mode="a",
|
||||||
)
|
)
|
||||||
|
|
||||||
kbd_cable_hole = cq.Sketch().trapezoid(20, 9, 90, mode="a").vertices().fillet(1)
|
kbd_cable_hole = cq.Sketch().trapezoid(15, 5, 90, mode="a").vertices().fillet(1)
|
||||||
|
|
||||||
mounting_pillars = (
|
mounting_pillars = (
|
||||||
cq.Sketch()
|
cq.Sketch()
|
||||||
.polygon([(0, 0), (width, 0), (width, -12), (0, -12), (0, 0)], mode="a")
|
.polygon([(0, 0), (width, 0), (width, -12), (0, -12), (0, 0)], mode="a")
|
||||||
.push(mounting_pillar_positions)
|
.push(mounting_pillar_positions)
|
||||||
.trapezoid(-12, 12, 90, mode="a")
|
|
||||||
.circle(ti_radius, mode="s")
|
.circle(ti_radius, mode="s")
|
||||||
.clean()
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -58,9 +54,9 @@ def model():
|
|||||||
.workplane()
|
.workplane()
|
||||||
.tag("mid_height")
|
.tag("mid_height")
|
||||||
.box(width, height, thickness)
|
.box(width, height, thickness)
|
||||||
# The screen goes rotated
|
# The screen goes at a 45 degree angle
|
||||||
.faces(">Z")
|
.faces(">Z")
|
||||||
.transformed(rotate=(scr_angle, 0, 0))
|
.transformed(rotate=(45, 0, 0))
|
||||||
# Move the screen "lower" so it doesn't interfere
|
# Move the screen "lower" so it doesn't interfere
|
||||||
# so much with the back
|
# so much with the back
|
||||||
.center(0, -2)
|
.center(0, -2)
|
||||||
@ -69,35 +65,6 @@ def model():
|
|||||||
# of the inclined screen
|
# of the inclined screen
|
||||||
.placeSketch(cq.Sketch().trapezoid(1000, 1000, 90, mode="a"))
|
.placeSketch(cq.Sketch().trapezoid(1000, 1000, 90, mode="a"))
|
||||||
.cutBlind(1000)
|
.cutBlind(1000)
|
||||||
# Trim the top
|
|
||||||
.workplaneFromTagged("mid_height")
|
|
||||||
.workplane(offset=21)
|
|
||||||
.placeSketch(cq.Sketch().trapezoid(1000, 1000, 90, mode="a"))
|
|
||||||
.cutBlind(100)
|
|
||||||
# Make bottom smaller to fit with base
|
|
||||||
.faces(">X")
|
|
||||||
.workplane(centerOption="CenterOfBoundBox")
|
|
||||||
.center(-height / 2, -thickness / 2)
|
|
||||||
.placeSketch(
|
|
||||||
cq.Sketch()
|
|
||||||
.polygon(
|
|
||||||
[
|
|
||||||
(height_bottom, 0),
|
|
||||||
(height_bottom, thickness / 3),
|
|
||||||
(height, thickness - 21),
|
|
||||||
(height, thickness),
|
|
||||||
(height + 5, thickness + 5),
|
|
||||||
(height + 5, 0),
|
|
||||||
(height_bottom, 0),
|
|
||||||
]
|
|
||||||
)
|
|
||||||
.vertices()
|
|
||||||
.fillet(3)
|
|
||||||
)
|
|
||||||
.cutBlind(-1000)
|
|
||||||
# Fillet top of the object
|
|
||||||
.edges("|X and >Z")
|
|
||||||
.fillet(3)
|
|
||||||
# Cut off viewport hole so we can see the screen
|
# Cut off viewport hole so we can see the screen
|
||||||
.workplaneFromTagged("slanted")
|
.workplaneFromTagged("slanted")
|
||||||
.placeSketch(viewport_cutout)
|
.placeSketch(viewport_cutout)
|
||||||
@ -109,6 +76,11 @@ def model():
|
|||||||
.center(-3, 0)
|
.center(-3, 0)
|
||||||
.placeSketch(screen_cutout)
|
.placeSketch(screen_cutout)
|
||||||
.cutBlind(-scr_thickness)
|
.cutBlind(-scr_thickness)
|
||||||
|
# Trim the top
|
||||||
|
.workplaneFromTagged("mid_height")
|
||||||
|
.workplane(offset=21)
|
||||||
|
.placeSketch(cq.Sketch().trapezoid(1000, 1000, 90, mode="a"))
|
||||||
|
.cutBlind(100)
|
||||||
# Make it hollow
|
# Make it hollow
|
||||||
.faces("<Z")
|
.faces("<Z")
|
||||||
# Can't be exactly shell_t because cq fails
|
# Can't be exactly shell_t because cq fails
|
||||||
@ -118,43 +90,44 @@ def model():
|
|||||||
.workplane(offset=-scr_thickness, centerOption="CenterOfBoundBox")
|
.workplane(offset=-scr_thickness, centerOption="CenterOfBoundBox")
|
||||||
.placeSketch(board_cutout)
|
.placeSketch(board_cutout)
|
||||||
.cutBlind(-6)
|
.cutBlind(-6)
|
||||||
# # Make small hole for the keyboard cable
|
# Fillet top of the object
|
||||||
# # not needed with this keyboard
|
.edges(">Z and |X")
|
||||||
# .faces("<Y")
|
.fillet(5)
|
||||||
# .workplane(centerOption="CenterOfBoundBox")
|
# Make small hole for the keyboard cable
|
||||||
# .center(width / 2 - 175, -4)
|
.faces(">Y")
|
||||||
# .placeSketch(kbd_cable_hole)
|
.workplane(offset=-5, centerOption="CenterOfBoundBox")
|
||||||
# .cutBlind(-height / 2)
|
.center(-width / 2 + 128, -23)
|
||||||
|
.placeSketch(kbd_cable_hole)
|
||||||
|
.cutBlind(-1000)
|
||||||
# Pillars to join with bottom half
|
# Pillars to join with bottom half
|
||||||
.workplaneFromTagged("mid_height")
|
.workplaneFromTagged("mid_height")
|
||||||
.workplane(offset=-thickness / 2, centerOption="CenterOfBoundBox")
|
.workplane(offset=-thickness / 2, centerOption="CenterOfBoundBox")
|
||||||
.center(-width / 2, height_bottom - height / 2)
|
.center(-width / 2, height / 2)
|
||||||
.placeSketch(mounting_pillars)
|
.placeSketch(mounting_pillars)
|
||||||
.extrude(10)
|
.extrude(10)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
exporters.export(model(), "screen_mount.stl")
|
||||||
|
|
||||||
print("Exporting")
|
split_offset = -133
|
||||||
exporters.export(model(), "screen_mount.stl")
|
|
||||||
|
|
||||||
offset_width = -width / 2
|
right_side = (
|
||||||
|
model()
|
||||||
|
.faces(">X")
|
||||||
|
.workplane(centerOption="CenterOfBoundBox", offset=split_offset)
|
||||||
|
.center(0, height / 2)
|
||||||
|
.split(keepTop=True)
|
||||||
|
)
|
||||||
|
|
||||||
right_side = (
|
exporters.export(right_side, "right_screen_mount.stl")
|
||||||
model()
|
|
||||||
.faces(">X")
|
|
||||||
.workplane(centerOption="CenterOfBoundBox", offset=offset_width)
|
|
||||||
.split(keepTop=True)
|
|
||||||
)
|
|
||||||
|
|
||||||
exporters.export(right_side, "right_screen_mount.stl")
|
left_side = (
|
||||||
|
model()
|
||||||
|
.faces(">X")
|
||||||
|
.workplane(centerOption="CenterOfBoundBox", offset=split_offset)
|
||||||
|
.center(0, height / 2)
|
||||||
|
.split(keepBottom=True)
|
||||||
|
)
|
||||||
|
|
||||||
left_side = (
|
exporters.export(left_side, "left_screen_mount.stl")
|
||||||
model()
|
|
||||||
.faces(">X")
|
|
||||||
.workplane(centerOption="CenterOfBoundBox", offset=offset_width)
|
|
||||||
.split(keepBottom=True)
|
|
||||||
)
|
|
||||||
|
|
||||||
exporters.export(left_side, "left_screen_mount.stl")
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user