$fn = 64; // --- Parameters --- brush_diameter = 14; // Diameter of the top holes for brush handles recess_diameter = 10; // Diameter of the bottom recesses to hold brush tips rows = 2; // Number of rows cols = 6; // Number of columns (2 x 6 = 12 brushes) spacing = 20; // Distance between hole centers margin = 15; // Margin from the outer edge to the first hole center holder_height = 75; // Overall height of the holder wall = 3; // Thickness of the outer walls bottom_thick = 6; // Thickness of the bottom base top_thick = 3; // Thickness of the top plate // --- Calculated Dimensions --- width = (cols - 1) * spacing + 2 * margin; depth = (rows - 1) * spacing + 2 * margin; // --- Main Geometry --- difference() { // Main outer body cube([width, depth, holder_height]); // Hollow interior to save filament (creates a self-supporting box) translate([wall, wall, bottom_thick]) cube([width - 2 * wall, depth - 2 * wall, holder_height - bottom_thick - top_thick]); // Top holes for brushes for(r = [0 : rows - 1]) { for(c = [0 : cols - 1]) { translate([margin + c * spacing, margin + r * spacing, holder_height - top_thick - 1]) cylinder(h = top_thick + 2, d = brush_diameter); } } // Bottom recesses to prevent brushes from sliding (3mm deep) for(r = [0 : rows - 1]) { for(c = [0 : cols - 1]) { translate([margin + c * spacing, margin + r * spacing, bottom_thick - 3]) cylinder(h = 4, d = recess_diameter); } } }