$fn = 64; // --- Parameters --- grid_x = 4; // Number of cells in X direction grid_y = 6; // Number of cells in Y direction cell_size = 30; // Size of each square grid cell (mm) plate_thickness = 5; // Thickness of the baseplate (mm) hole_diameter = 5; // Diameter of the connection peg holes (mm) dovetail_width_base = 12; // Width of the dovetail at the edge (mm) dovetail_width_tip = 18; // Width of the dovetail at the tip (mm) dovetail_length = 7; // How far the dovetail extends (mm) tolerance = 0.2; // Clearance for the female dovetails (mm) // --- Modules --- // 2D profile for the interlocking dovetail module dovetail_2d(is_female = false) { tol = is_female ? tolerance : 0; base_y = is_female ? -1 : 0; // Extend base slightly for clean boolean cut polygon([ [-(dovetail_width_base/2) - tol, base_y], [ (dovetail_width_base/2) + tol, base_y], [ (dovetail_width_tip/2) + tol, dovetail_length + tol], [-(dovetail_width_tip/2) - tol, dovetail_length + tol] ]); } // Main 4x6 Modular Baseplate module figure_stage_baseplate() { difference() { union() { // Main platform body cube([grid_x * cell_size, grid_y * cell_size, plate_thickness]); // Male dovetails (Right edge / +X) for(j = [0 : grid_y - 1]) { translate([grid_x * cell_size, j * cell_size + (cell_size / 2), 0]) linear_extrude(plate_thickness) rotate(-90) dovetail_2d(false); } // Male dovetails (Top edge / +Y) for(i = [0 : grid_x - 1]) { translate([i * cell_size + (cell_size / 2), grid_y * cell_size, 0]) linear_extrude(plate_thickness) rotate(0) dovetail_2d(false); } } // Female dovetails (Left edge / -X) for(j = [0 : grid_y - 1]) { translate([0, j * cell_size + (cell_size / 2), -1]) linear_extrude(plate_thickness + 2) rotate(-90) dovetail_2d(true); } // Female dovetails (Bottom edge / -Y) for(i = [0 : grid_x - 1]) { translate([i * cell_size + (cell_size / 2), 0, -1]) linear_extrude(plate_thickness + 2) rotate(0) dovetail_2d(true); } // Grid connection holes for(i = [0 : grid_x - 1]) { for(j = [0 : grid_y - 1]) { // Center hole translate([i * cell_size + (cell_size / 2), j * cell_size + (cell_size / 2), -1]) cylinder(d = hole_diameter, h = plate_thickness + 2); // Optional: Corner holes for maximum grid flexibility translate([i * cell_size, j * cell_size, -1]) if(i > 0 && j > 0) { cylinder(d = hole_diameter, h = plate_thickness + 2); } } } } } // --- Render --- figure_stage_baseplate();