$fn=64; // --- Parameters --- // Outer diameter of the insert body (fits inside the pot ring) insert_diameter = 100; // Outer diameter of the top retaining lip lip_diameter = 115; // Thickness of the top retaining lip lip_thickness = 3; // Total depth of the insert bowl insert_depth = 20; // Thickness of the bottom and side walls wall_thickness = 2.5; // Diameter of the drainage holes hole_diameter = 6; // Center-to-center spacing between drainage holes hole_spacing = 14; module pot_ring_insert() { difference() { // Main solid body union() { // Lower bowl section cylinder(d=insert_diameter, h=insert_depth); // Top retaining lip translate([0, 0, insert_depth]) cylinder(d=lip_diameter, h=lip_thickness); } // Hollow interior (the bowl cutout) translate([0, 0, wall_thickness]) cylinder( d=insert_diameter - (2 * wall_thickness), h=insert_depth + lip_thickness + 1 // +1 to prevent Z-fighting ); // Drainage holes pattern // Calculate maximum safe radius to avoid cutting into the side walls max_r = (insert_diameter / 2) - wall_thickness - (hole_diameter / 2) - 1; grid_steps = floor((insert_diameter / 2) / hole_spacing); for(i = [-grid_steps : grid_steps]) { for(j = [-grid_steps : grid_steps]) { // Calculate X and Y positions symmetrically around center x_pos = i * hole_spacing; y_pos = j * hole_spacing; // Only place holes that fit within the safe radius if (sqrt((x_pos * x_pos) + (y_pos * y_pos)) <= max_r) { translate([x_pos, y_pos, -1]) cylinder(d=hole_diameter, h=wall_thickness + 2); } } } } } // Generate the model pot_ring_insert();