$fn=64; // --- Parameters --- columns = 5; rows = 3; // USB Type-A dimensions (with clearance for easy insertion) slot_width = 13.5; slot_thickness = 5.0; slot_depth = 12.0; // Layout spacing spacing_x = 22.0; spacing_y = 16.0; base_height = 18.0; corner_radius = 4.0; // --- Calculated Dimensions --- length = (columns - 1) * spacing_x + slot_width + 12; width = (rows - 1) * spacing_y + slot_thickness + 12; // --- Modules --- module base_block() { hull() { translate([corner_radius, corner_radius, 0]) cylinder(r=corner_radius, h=base_height); translate([length - corner_radius, corner_radius, 0]) cylinder(r=corner_radius, h=base_height); translate([corner_radius, width - corner_radius, 0]) cylinder(r=corner_radius, h=base_height); translate([length - corner_radius, width - corner_radius, 0]) cylinder(r=corner_radius, h=base_height); } } // --- Main Assembly --- difference() { // Main body base_block(); // Cut out the USB slots for (c = [0 : columns - 1]) { for (r = [0 : rows - 1]) { // Center the array of slots within the block x_pos = (length - ((columns - 1) * spacing_x)) / 2 + c * spacing_x; y_pos = (width - ((rows - 1) * spacing_y)) / 2 + r * spacing_y; translate([x_pos, y_pos, base_height - slot_depth]) { // Main rectangular slot cavity translate([-slot_width/2, -slot_thickness/2, 0]) cube([slot_width, slot_thickness, slot_depth]); // Chamfered opening at the top for easier insertion hull() { translate([-slot_width/2, -slot_thickness/2, slot_depth - 1.5]) cube([slot_width, slot_thickness, 0.1]); translate([-(slot_width+3)/2, -(slot_thickness+3)/2, slot_depth + 1]) cube([slot_width+3, slot_thickness+3, 0.1]); } } } } }