import cadquery2 as cq from cadquery2 import exporters # Base for the notebook. Basically a kbd base that extends back # as much as possible # Thickness of the outer material shell_t = 3 # Size of the kbd board kbd_height = 98 kbd_width = 286 kbd_angle = 5 # Size of the whole object width = kbd_width + 2 * shell_t height = 164 # Max bed size thickness = 20 + shell_t # 20 inside # Insert Positions ti_radius = 2.35 ti_depth = 6.25 # Positions are determined by measuring the keyboard # mounting holes kbd_pillars = ( cq.Sketch() .push( [ (19, -16.5), (133, -16.5), (247.5, -16.5), (24, -86), (142.5, -91), (261.5, -86), ] ) .circle(6, mode="a") # Holes for M3 threaded inserts .circle(ti_radius, mode="s") ) # These are placed where convenient, and are used to join the top and bottom # parts of the case. # Measured from top-left corner OUTSIDE mounting_pillar_positions = [ (6, -6), (width - 6, -6), (width - 6, -40), (120, -6), (170, -6), ] mounting_pillars = ( cq.Sketch() .push(mounting_pillar_positions) .trapezoid(12, 12, 90, mode="a") .circle(1.8, mode="s") ) screw_holes = cq.Sketch().push(mounting_pillar_positions).circle(3, mode="a") 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") switch_in = cq.Sketch().trapezoid(13.5, 8.5, 90, mode="a") # Motherboard mount def model(): return ( cq.Workplane("XY") .workplane(offset=thickness / 2) .tag("mid_height") # Hollow box .box(width, height, thickness) .edges("|Z") .fillet(2) .faces(">Z") .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 + 50, -5) .placeSketch(usb_in) .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 .faces(">Z") .workplane(centerOption="CenterOfBoundBox") # Top-left kbd corner inside the box .center(-width / 2 + shell_t, kbd_height - height / 2 + shell_t) .transformed(rotate=cq.Vector(kbd_angle, 0, 0)) .tag("sloped") .placeSketch(kbd_pillars) .extrude(-1000) # Remove the excess extrusion .workplaneFromTagged("mid_height") .transformed(offset=cq.Vector(0, 0, -thickness / 2)) .split(keepTop=True) # Slope for the beyboard .workplaneFromTagged("sloped") .split(keepBottom=True) # Pillars to join with top half .workplaneFromTagged("mid_height") .workplane(offset=-thickness / 2, centerOption="CenterOfBoundBox") .center(-width / 2, height / 2) .placeSketch(mounting_pillars) .extrude(thickness) # Holes to insert screws from the bottom .workplaneFromTagged("mid_height") .workplane(offset=-thickness / 2, centerOption="CenterOfBoundBox") .center(-width / 2, height / 2) .placeSketch(screw_holes) # 13 is 20-7 (screw thread length - threaded insert depth) .cutBlind(thickness - 13) ) if __name__ == "__main__": left_cutout = cq.Sketch().polygon( [(0, 0), (160, 0), (160, -100), (135, -100), (135, -200), (0, -200), (0, 0)], mode="a", ) right_side = ( model() .faces("