Compare commits

16 Commits

Author SHA1 Message Date
64db220a46 Integrated Battery holder 2023-02-16 14:57:32 -03:00
4624a2531f Integrated CPU holder 2023-02-16 14:42:31 -03:00
be6245aa3b Removed cable hole in screen mount
This cut is not needed with the lower keyboard position.
2023-02-01 10:28:58 -03:00
4b0cf1cfa0 Cleanup and adjustments for rev2
* Removed holes that make no sense anymore
* Made case shorter to avoid unsightly gap between screen and keyboard
* Added comments
2023-02-01 10:21:29 -03:00
6eb3eba4f2 Re-add back strip so mounting pillars print easier 2023-01-30 18:01:50 -03:00
dbaa9832f8 Move USB hole up a little 2023-01-30 16:09:48 -03:00
76af86ac70 Added 6th screen mounting pillar, improved kbd cable hole placement and screen mounting code 2023-01-30 10:57:33 -03:00
6cbd7e2b15 Tweaks 2023-01-27 17:01:37 -03:00
459021ff83 Playing with screen mount parameters, angle to 20 degrees 2023-01-27 16:11:28 -03:00
4f2c1e35f6 Redesigned screen holder for 30 degree screen 2023-01-27 15:43:54 -03:00
1e89b41995 Redesigned screen holder for 30 degree screen 2023-01-27 15:32:04 -03:00
37d96b0e4f Bring the keyboard 1.5 mm lower INTO the case 2023-01-27 13:16:09 -03:00
b85ba1f3e1 2-level kbd mounting pillars 2023-01-27 11:23:04 -03:00
a6d3f32797 larger hole for kbd mounting screws 2023-01-27 11:16:40 -03:00
92291013c6 Smaller kbd pillars, fix base splitting 2023-01-26 15:11:16 -03:00
d048e19cec Starting rev 2
* Adjusted sizes and other parameters for the new 65% keyboard
* Commented battery holder (waiting on the 18650 charger)
2023-01-26 11:08:58 -03:00
15 changed files with 345482 additions and 258901 deletions

View File

@ -0,0 +1,12 @@
import cadquery2 as cq
from cadquery2 import exporters
cpu_stand_positions = [(0, 0), (58, 0), (58, 48), (0, 48)]
lower_stands = (
cq.Sketch().push(cpu_stand_positions).circle(3, mode="a")
)
higher_stands = (
cq.Sketch().push(cpu_stand_positions).circle(2.65 / 2, 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.

View File

@ -1,28 +1,12 @@
import cadquery2 as cq import cadquery2 as cq
from cadquery2 import exporters from cadquery2 import exporters
cpu_stand_positions = [(0, 0), (23, 0), (23, 58), (0, 58)]
lower_stands = ( lower_stands = (
cq.Sketch().push([(0, 0), (58, 0), (58, 23), (0, 23)]).circle(3, mode="a") cq.Sketch().push(cpu_stand_positions).circle(3, mode="a")
) )
higher_stands = ( higher_stands = (
cq.Sketch().push([(0, 0), (58, 0), (58, 23), (0, 23)]).circle(2.65 / 2, mode="a") cq.Sketch().push(cpu_stand_positions).circle(2.65 / 2, mode="a")
) )
model = (
cq.Workplane("XY")
.workplane()
.box(75, 40, 2)
.edges("+Z")
.fillet(3)
.faces(">Z")
.workplane(centerOption="CenterOfBoundBox")
.center(-29, -11.5)
.placeSketch(lower_stands)
.extrude(4)
.workplane()
.placeSketch(higher_stands)
.extrude(9)
)
exporters.export(model, "cpu_holder.stl")

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,9 @@
import cadquery2 as cq import cadquery2 as cq
from cadquery2 import exporters from cadquery2 import exporters
import battery_holder
import cpu_holder
# Base for the notebook. Basically a kbd base that extends back # Base for the notebook. Basically a kbd base that extends back
# as much as possible # as much as possible
@ -8,13 +11,13 @@ from cadquery2 import exporters
shell_t = 3 shell_t = 3
# Size of the kbd board # Size of the kbd board
kbd_height = 98 kbd_height = 95.5
kbd_width = 286 kbd_width = 305
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 = 164 # Max bed size height = 159
thickness = 20 + shell_t # 20 inside thickness = 20 + shell_t # 20 inside
# Insert Positions # Insert Positions
@ -22,22 +25,34 @@ 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( .push(kbd_pillar_positions)
[ .circle(2.2, mode="a")
(19, -16.5), # Holes for self-tapping screws
(133, -16.5), .circle(1.1, mode="s")
(247.5, -16.5), )
(24, -86),
(142.5, -91), kbd_lower_pillars = (
(261.5, -86), cq.Sketch()
] .push(kbd_pillar_positions)
) .circle(4, mode="a")
.circle(6, mode="a") # Holes for self-tapping screws
# Holes for M3 threaded inserts .circle(1.1, mode="s")
.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
@ -45,6 +60,7 @@ kbd_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), (120, -6),
(170, -6), (170, -6),
(width - 6, -6), (width - 6, -6),
@ -60,32 +76,18 @@ 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")
battery_holder = ( # Hole for the USB hub's exposed port
cq.Sketch() usb_in = cq.Sketch().trapezoid(13, 5.5, 90, mode="a")
.polygon(
[(-67, 5), (0, 5), (0, -12), (-67, -12), (-67, 5)],
mode="a", # CPU stand pins
) lower_stands = (
.trapezoid(83, 83, 90, mode="a") cq.Sketch().push([(0, 0), (58, 0), (58, 23), (0, 23)]).circle(3, 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",
)
) )
higher_stands = (
power_in = cq.Sketch().circle(5, mode="a") cq.Sketch().push([(0, 0), (58, 0), (58, 23), (0, 23)]).circle(2.65 / 2, mode="a")
usb_in = cq.Sketch().trapezoid(13, 5.5, 90, mode="a") )
switch_in = cq.Sketch().trapezoid(13.5, 8.5, 90, mode="a")
# Motherboard mount
def model(): def model():
@ -99,38 +101,30 @@ 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")
.center(-height / 2 + shell_t + 50, -5) # The position is arbitrary, based on the components
# 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))
@ -151,13 +145,41 @@ def model():
.placeSketch(screw_holes) .placeSketch(screw_holes)
# 13 is 20-7 (screw thread length - threaded insert depth) # 13 is 20-7 (screw thread length - threaded insert depth)
.cutBlind(thickness - 13) .cutBlind(thickness - 13)
# CPU Stands (lower)
# The -65, -40 is the position of the CPU,
# and should be a parameter (TODO)
.workplaneFromTagged("mid_height")
.workplane(offset=-thickness / 2, centerOption="CenterOfBoundBox")
.center (width/2 - 40, height/2 - 65)
.placeSketch(cpu_holder.lower_stands)
.extrude(7)
# CPU Stands (higher)
.workplaneFromTagged("mid_height")
.workplane(offset=-thickness / 2, centerOption="CenterOfBoundBox")
.center (width/2 - 40, height/2 - 65)
.placeSketch(cpu_holder.higher_stands)
.extrude(11)
# Battery Stands (lower)
# The +18, -55 is the position of the battery system,
# and should be a parameter (TODO)
.workplaneFromTagged("mid_height")
.workplane(offset=-thickness / 2, centerOption="CenterOfBoundBox")
.center (-width/2 + 18, height/2 - 55)
.placeSketch(battery_holder.lower_stands)
.extrude(shell_t + 5)
# Battery Stands (higher)
.workplaneFromTagged("mid_height")
.workplane(offset=-thickness / 2, centerOption="CenterOfBoundBox")
.center (-width/2 + 18, height/2 - 55)
.placeSketch(battery_holder.higher_stands)
.extrude(shell_t + 8)
) )
if __name__ == "__main__": if __name__ == "__main__":
left_cutout = cq.Sketch().polygon( left_cutout = cq.Sketch().polygon(
[(0, 0), (160, 0), (160, -100), (135, -100), (135, -200), (0, -200), (0, 0)], [(0, 0), (width / 2, 0), (width / 2, -height), (0, -height), (0, 0)],
mode="a", mode="a",
) )
@ -175,13 +197,11 @@ if __name__ == "__main__":
right_cutout = cq.Sketch().polygon( right_cutout = cq.Sketch().polygon(
[ [
(160, 0), (width / 2, 0),
(width, 0), (width, 0),
(width, -height), (width, -height),
(135, -height), (width / 2, -height),
(135, -100), (width / 2, 0),
(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.

View File

@ -12,8 +12,9 @@ from modelo import (
# Size of the whole object # Size of the whole object
width = kbd_width + 2 * shell_t width = kbd_width + 2 * shell_t
height = 59 height = 66
thickness = 62 # Will be shorter after construction height_bottom = 59
thickness = 48 # Will be shorter after construction
# Visible screen size # Visible screen size
vis_w = 220 vis_w = 220
@ -26,6 +27,9 @@ 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.
@ -36,18 +40,15 @@ board_cutout = cq.Sketch().trapezoid(
mode="a", mode="a",
) )
kbd_cable_hole = cq.Sketch().trapezoid(15, 6, 90, mode="a").vertices().fillet(1) kbd_cable_hole = cq.Sketch().trapezoid(20, 9, 90, mode="a").vertices().fillet(1)
# The last mounting pillar is handled specially
x, y = mounting_pillar_positions[-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")
.polygon(
[(x - 6, y - 6), (x - 6, y + 6), (x + 6, y + 6), (x + 6, y - 6), (x - 6, y - 6)]
)
.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()
) )
@ -57,9 +58,9 @@ def model():
.workplane() .workplane()
.tag("mid_height") .tag("mid_height")
.box(width, height, thickness) .box(width, height, thickness)
# The screen goes at a 45 degree angle # The screen goes rotated
.faces(">Z") .faces(">Z")
.transformed(rotate=(45, 0, 0)) .transformed(rotate=(scr_angle, 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)
@ -68,6 +69,35 @@ 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)
@ -79,11 +109,6 @@ 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
@ -93,19 +118,17 @@ def model():
.workplane(offset=-scr_thickness, centerOption="CenterOfBoundBox") .workplane(offset=-scr_thickness, centerOption="CenterOfBoundBox")
.placeSketch(board_cutout) .placeSketch(board_cutout)
.cutBlind(-6) .cutBlind(-6)
# Fillet top of the object # # Make small hole for the keyboard cable
.edges(">Z and |X") # # not needed with this keyboard
.fillet(5) # .faces("<Y")
# Make small hole for the keyboard cable # .workplane(centerOption="CenterOfBoundBox")
.faces(">Y") # .center(width / 2 - 175, -4)
.workplane(offset=-5, centerOption="CenterOfBoundBox") # .placeSketch(kbd_cable_hole)
.center(-width / 2 + 134, -24) # .cutBlind(-height / 2)
.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 / 2) .center(-width / 2, height_bottom - height / 2)
.placeSketch(mounting_pillars) .placeSketch(mounting_pillars)
.extrude(10) .extrude(10)
) )
@ -116,7 +139,7 @@ if __name__ == "__main__":
print("Exporting") print("Exporting")
exporters.export(model(), "screen_mount.stl") exporters.export(model(), "screen_mount.stl")
offset_width = -133 offset_width = -width / 2
right_side = ( right_side = (
model() model()

File diff suppressed because it is too large Load Diff