$fn = 72; include module keyboard_base_plate(pcb_dimensions, pcb_screw_holes, switch_z_range) { pcb_width = pcb_dimensions[0]; pcb_length = pcb_dimensions[1]; pcb_height = pcb_dimensions[2]; switch_z_min = switch_z_range[0]; switch_z_max = switch_z_range[1]; pcb_clearance_edge = 1.0; pcb_clearance_bottom = -switch_z_min - pcb_height + 0.5; pcb_screw_diameter = 2.5; pcb_screw_hole_diameter = 2.5; pcb_screw_height = 3.0; thickness = 1.75; corner_radius = 0.2; case_color = [0.5, 0.5, 0.5, 1.0]; wall_width = pcb_width + 2 * (pcb_clearance_edge + thickness) - 2 * corner_radius; wall_length = pcb_length + 2 * (pcb_clearance_edge + thickness) - 2 * corner_radius; wall_height = pcb_screw_height + pcb_height + switch_z_max; bottom_width = 2 * (pcb_clearance_edge) + pcb_width; bottom_length = 2 * (pcb_clearance_edge) + pcb_length; bottom_height = thickness; module round_corner(rotation) { color(case_color) rotate(rotation) rotate_extrude(angle=90) { intersection() { circle(r=corner_radius); square(corner_radius*2); } } } module round_edge(rotation, length) { color(case_color) rotate(rotation) linear_extrude(length) intersection() { circle(r=corner_radius); square(corner_radius*2); } } module panel(dimensions) { color(case_color) linear_extrude(dimensions[2]) square([dimensions[0], dimensions[1]], false); } module wall_corner(rotation, radius, length) { color(case_color) rotate(rotation) linear_extrude(length) intersection() { circle(r=radius); square([radius, radius], false); } } module screw_post(h, d) { diameter_outer = 3 * d; diameter_inner = d; color(case_color) difference() { cylinder(h=h, r1 = (diameter_outer / 2.0) * 1.5); cylinder(h=h, r = diameter_inner / 2.0); } } module ridges(width, height) { horizontal = [ (bottom_length / 3), (bottom_length / 3) * 2 ]; vertical = [ (bottom_width / 3), (bottom_width / 3) * 2 ]; for (y = horizontal) { translate([0 - pcb_clearance_edge, y, 0]) panel([bottom_width, width, height]); } for (x = vertical) { translate([x, 0 - pcb_clearance_edge, 0]) panel([width, bottom_length, height]); } } /* Upper wall */ translate([-pcb_clearance_edge - thickness + corner_radius, pcb_clearance_edge + pcb_length, -thickness + corner_radius]) panel([wall_width, thickness, wall_height + thickness - corner_radius]); /* Right wall */ translate([ pcb_clearance_edge + pcb_width, -pcb_clearance_edge - thickness + corner_radius, -thickness + corner_radius]) panel([thickness, wall_length, wall_height + thickness - corner_radius]); /* Lower wall */ translate([-pcb_clearance_edge - thickness + corner_radius, -pcb_clearance_edge - thickness, -thickness + corner_radius]) panel([wall_width, thickness, wall_height + thickness - corner_radius]); /* Left wall */ translate([-pcb_clearance_edge - thickness, -pcb_clearance_edge - thickness + corner_radius, -thickness + corner_radius]) panel([thickness, wall_length, wall_height + thickness - corner_radius]); /* Upper right wall corner */ translate([pcb_clearance_edge + thickness + pcb_width - corner_radius, pcb_clearance_edge + thickness + pcb_length - corner_radius, -thickness + corner_radius]) wall_corner([0, 0, 0], corner_radius, wall_height + thickness - corner_radius); /* Lower right wall corner */ translate([ pcb_clearance_edge + thickness + pcb_width - corner_radius, -pcb_clearance_edge - thickness + corner_radius, -thickness + corner_radius]) wall_corner([0, 0, 270], corner_radius, wall_height + thickness - corner_radius); /* Lower left wall corner */ translate([-pcb_clearance_edge - thickness + corner_radius, -pcb_clearance_edge - thickness + corner_radius, -thickness + corner_radius]) wall_corner([0, 0, 180], corner_radius, wall_height + thickness - corner_radius); /* Upper left wall corner */ translate([-pcb_clearance_edge - thickness + corner_radius, pcb_clearance_edge + pcb_length + thickness - corner_radius, -thickness + corner_radius]) wall_corner([0, 0, 90], corner_radius, wall_height + thickness - corner_radius); /* Bottom plate */ translate([-pcb_clearance_edge - thickness + corner_radius, -pcb_clearance_edge - thickness + corner_radius, -thickness]) panel([bottom_width + 2 * thickness - 2 * corner_radius, bottom_length + 2 * thickness - 2 * corner_radius, thickness]); /* Upper edge */ translate([-pcb_clearance_edge - thickness + corner_radius, pcb_clearance_edge + thickness + pcb_length - corner_radius, -thickness + corner_radius]) round_edge([0, 90, 0], wall_width); /* Right edge */ translate([ pcb_clearance_edge + thickness + pcb_width - corner_radius, -pcb_clearance_edge - thickness + corner_radius, -thickness + corner_radius]) round_edge([270, 0, 0], wall_length); /* Lower edge */ translate([-pcb_clearance_edge - thickness + corner_radius, -pcb_clearance_edge - thickness + corner_radius, -thickness + corner_radius]) round_edge([90, 180, 90], wall_width); /* Left edge */ translate([-pcb_clearance_edge - thickness + corner_radius, -pcb_clearance_edge - thickness + corner_radius, -thickness + corner_radius]) round_edge([270, 90, 0], wall_length); /* Upper right corner */ translate([pcb_clearance_edge + thickness + pcb_width - corner_radius, pcb_clearance_edge + thickness + pcb_length - corner_radius, -thickness + corner_radius]) round_corner([90, 90, 90]); /* Lower right corner */ translate([ pcb_clearance_edge + thickness + pcb_width - corner_radius, -pcb_clearance_edge - thickness + corner_radius, -thickness + corner_radius]) round_corner([180, 90, 90]); /* Lower left corner */ translate([-pcb_clearance_edge - thickness + corner_radius, -pcb_clearance_edge - thickness + corner_radius, -thickness + corner_radius]) round_corner([-90, 90, 90]); /* Upper left corner */ translate([-pcb_clearance_edge - thickness + corner_radius, pcb_clearance_edge + thickness + pcb_length - corner_radius, -thickness + corner_radius]) round_corner([0, 90, 90]); /* Screw holes */ for (screw_hole = pcb_screw_holes) { translate([screw_hole[0], screw_hole[1], 0]) screw_post(pcb_screw_height, pcb_screw_diameter); } /* Ridges (for rigidity!) */ ridges(thickness * 2, pcb_clearance_bottom / 2); } keyboard_base_plate([keyboard_pcb_width, keyboard_pcb_length, keyboard_pcb_height], keyboard_pcb_screw_holes, [-keyboard_switch_leg_length, keyboard_switch_height]);