$fn = 72; key_switch_sizes = [ [0.5, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0], [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.5], [1.25, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.25], [1.75, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.75], [1.0, 1.25, 1.25, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0] ]; pcb_screw_holes = [ [ 4.7625, 85.7250], [ 66.6750, 85.7250], [161.9250, 85.7250], [238.1250, 85.7250], [ 61.9125, 47.6250], [138.1125, 47.6250], [214.3125, 47.6250], [ 19.0500, 9.5250], [123.8250, 9.5250], [238.1250, 9.5250] ]; module top_case(key_switch_sizes, pcb_screw_holes) { case_width_top = 317.5000; case_width_bottom = 320.0000; case_length_top = 150.0000; case_length_bottom = 151.5000; wall_width = 2.5000; wall_height = 17.2500; key_switch_width = 19.0500; key_switch_length = 19.0500; keyboard_width = key_switch_width * 13.5; keyboard_length = key_switch_length * 5.0; keyboard_x_offset = 12.2500; keyboard_y_offset = 12.2500; accent_width = 1.0000; accent_depth = 0.5; accent_y_stride = (keyboard_length - accent_width) / 5.0; accent_y_bottom = keyboard_y_offset; fin_width = 2.0000; fin_gap_width = 2.0000; fin_gap_length = 2.0000; fin_gap_height = 12.0000; fin_gap_count = 32; fin_gap_x_first = keyboard_x_offset + keyboard_width - fin_gap_count * (fin_width + fin_gap_width); fin_gap_y_offset = case_length_bottom - fin_gap_length; module fascia() { linear_extrude(wall_width) difference() { square([case_width_bottom, case_length_bottom], false); translate([keyboard_x_offset, keyboard_y_offset, 0]) square([keyboard_width, keyboard_length], false); } } module fin_gaps() { for (i = [0:fin_gap_count]) { x = fin_gap_x_first + (i * (fin_width + fin_gap_width)); translate([x, fin_gap_y_offset, wall_height - fin_gap_height]) cube([fin_gap_width, fin_gap_length, fin_gap_height], false); } } module accents() { for (y = [accent_y_bottom: accent_y_stride: case_length_bottom]) { /* Top */ translate([0, y, wall_height - accent_depth]) cube([case_width_bottom, accent_width, accent_depth], false); /* Right */ translate([case_width_bottom - accent_depth, y, 0]) cube([accent_depth, accent_width, wall_height], false); /* Left */ translate([0, y, 0]) cube([accent_depth, accent_width, wall_height], false); } } module body() { translate([0, 0, wall_height - wall_width]) fascia(); /* Upper */ translate([0, case_length_bottom - wall_width, 0]) cube([case_width_bottom, wall_width, wall_height], false); /* Right */ translate([case_width_bottom - wall_width, 0, 0]) cube([wall_width, case_length_bottom, wall_height], false); /* Lower */ cube([case_width_bottom, wall_width, wall_height], false); /* Left */ cube([wall_width, case_length_bottom, wall_height - wall_width], false); } module screw_holes() { pcb_screw_diameter = 1.5; for (screw_hole = pcb_screw_holes) { translate([screw_hole[0], screw_hole[1], 0]) cylinder(h=wall_width, d=pcb_screw_diameter); } } module keyboard_deck() { key_switch_footprint = [16.0, 16.0]; function add(v) = [for(p=v) 1]*v; function slice(v, x, y) = [for (i=[x:y]) v[i]]; function addrange(v, x, y) = add(slice(v, x, y)); module key_switch_plate(key_switch_size) { plate_width = key_switch_width * key_switch_size; plate_length = key_switch_length; if (key_switch_size <= 0.5) { cube([key_switch_width * key_switch_size, key_switch_length, wall_width], false); } else { hole_width = key_switch_footprint[0]; hole_length = key_switch_footprint[1]; hole_x = plate_width / 2 - hole_width / 2; hole_y = plate_length / 2 - hole_length / 2; linear_extrude(wall_width) difference() { square([plate_width, plate_length], false); translate([hole_x, hole_y, 0]) square([hole_width, hole_length], false); } } } module body() { rows = len(key_switch_sizes); for (i = [0: rows-1]) { y = key_switch_length * (rows - 1 - i); key_switch_row = key_switch_sizes[i]; cols = len(key_switch_row); for (j = [0: cols-1]) { x = key_switch_width * ((j == 0)? 0: addrange(key_switch_row, 0, j-1)); key_switch_size = key_switch_row[j]; translate([x, y, 0]) key_switch_plate(key_switch_size); } } } difference() { body(); screw_holes(); } } difference() { body(); accents(); fin_gaps(); } translate([0, 0, 20]) keyboard_deck(); } top_case(key_switch_sizes, pcb_screw_holes);