import cadquery as cq from cadquery import exporters from modelo import ( kbd_height, kbd_width, mounting_pillar_positions, shell_t, ti_depth, ti_radius, ) # Size of the whole object width = kbd_width + 2 * shell_t height = 66 height_bottom = 59 thickness = 48 # Will be shorter after construction # Visible screen size vis_w = 219 vis_h = 55 viewport_cutout = cq.Sketch().trapezoid(vis_w, vis_h, 90, mode="a").vertices().fillet(2) # Whole screen size scr_w = 231 scr_h = 65 scr_thickness = 5.5 screen_cutout = cq.Sketch().trapezoid(scr_w, scr_h, 90, mode="a") # Screen angle scr_angle = 20 # Circuit board and cable hole. # 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. board_cutout = cq.Sketch().trapezoid( scr_w + 5, scr_h - 10, 90, mode="a", ) kbd_cable_hole = cq.Sketch().trapezoid(20, 9, 90, mode="a").vertices().fillet(1) mounting_pillars = ( cq.Sketch() .push(mounting_pillar_positions) .trapezoid(-12, 12, 90, mode="a") .circle(ti_radius, mode="s") .clean() ) def model(): return ( cq.Workplane("XY") .workplane() .tag("mid_height") .box(width, height, thickness) # The screen goes rotated .faces(">Z") .transformed(rotate=(scr_angle, 0, 0)) # Move the screen "lower" so it doesn't interfere # so much with the back .center(0, -2) .tag("slanted") # Arbitrary huge trapezoid to cut off the material *in front* # of the inclined screen .placeSketch(cq.Sketch().trapezoid(1000, 1000, 90, mode="a")) .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 .workplaneFromTagged("slanted") .placeSketch(viewport_cutout) .cutBlind(-shell_t) # Make hole for screen assembly so the whole screen fits .workplaneFromTagged("slanted") .workplane(offset=-shell_t, centerOption="CenterOfBoundBox") # Left bezel is wider than right one, so this hole is displaced to the left .center(-3, 0) .placeSketch(screen_cutout) .cutBlind(-scr_thickness) # Make it hollow .faces("(0, -10, 5)") .fillet(2) ) if __name__ == "__main__": print("Exporting") exporters.export(model(), "screen_mount.stl") offset_width = -width / 2 right_side = ( 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=offset_width) .split(keepBottom=True) ) exporters.export(left_side, "left_screen_mount.stl")