$fn=64; // --- Parameters --- width = 50; // Outer width of the roof depth = 50; // Outer depth of the roof roof_thickness = 2; // Thickness of the flat roof base parapet_height = 3.5; // Height of the top border walls parapet_thickness = 2; // Thickness of the top border walls wall_thickness = 2; // Thickness of the building walls below tolerance = 0.4; // Clearance gap for a drop-in fit insert_height = 3; // Height of the bottom alignment lip insert_thickness = 1.5; // Thickness of the bottom alignment lip // --- Calculated Variables --- insert_w = width - (wall_thickness * 2) - tolerance; insert_d = depth - (wall_thickness * 2) - tolerance; // --- Geometry --- union() { // Main flat roof slab translate([0, 0, roof_thickness / 2]) cube([width, depth, roof_thickness], center=true); // Top parapet (border wall) translate([0, 0, roof_thickness + parapet_height / 2 - 0.01]) difference() { cube([width, depth, parapet_height + 0.02], center=true); cube([width - parapet_thickness * 2, depth - parapet_thickness * 2, parapet_height + 0.1], center=true); } // Bottom alignment lip (fits inside the walls of the building) translate([0, 0, -insert_height / 2 + 0.01]) difference() { cube([insert_w, insert_d, insert_height + 0.02], center=true); cube([insert_w - insert_thickness * 2, insert_d - insert_thickness * 2, insert_height + 0.1], center=true); } // Simple roof access hatch for detail translate([width / 4, depth / 4, roof_thickness + 0.5 - 0.01]) cube([8, 8, 1], center=true); }