$fn = 30; cabuchon_dia = 8.1; plate_width = 36; plate_height = 36; plate_thickness = 2.5; lens_recess = 2; led_spacing = 7.37; fit_tolerance = 0.1; lip = 0.25; wall_thickness = 1; top_thickness = 0.5; module grid_of_circles(n, spacing, r) { translate([ -(n-1)/2*spacing, -(n-1)/2*spacing]) for (x = [0:n-1]) for (y = [0:n-1]) translate([x*spacing,y*spacing]) circle(r); } module lens_plate(n=4) { difference() { linear_extrude(plate_thickness) difference() { square([plate_width, plate_height], center=true); grid_of_circles(n, cabuchon_dia, cabuchon_dia/2-lip); } translate([0,0,plate_thickness-lens_recess]) linear_extrude(h=plate_thickness) intersection() { grid_of_circles(n+2, cabuchon_dia, cabuchon_dia/2+fit_tolerance); square( [ plate_width -wall_thickness*2, plate_height-wall_thickness*2 ], center=true); } } } module lens_shell(n=4) { difference() { linear_extrude(plate_thickness+top_thickness) difference() { square([ plate_width+wall_thickness*2 + fit_tolerance*4, plate_height+wall_thickness*2 + fit_tolerance*4 ], center=true); grid_of_circles(n, cabuchon_dia, cabuchon_dia/2-lip); } translate([0,0,-0.1]) linear_extrude(plate_thickness) square([ plate_width + fit_tolerance*4, plate_height + fit_tolerance*4 ], center=true); } } //lens_plate(4); rotate([0,180,0]) lens_shell(4);