$fn = 64; // --- Parameters --- tower_height = 120; base_radius = 40; top_radius = 32; wall_thickness = 4; // Cable routing dimensions cable_hole_width = 22; cable_hole_height = 25; // Height of the straight section before the arch // Castle details crenellation_height = 12; crenellation_count = 8; crenellation_gap = 14; // --- Helper Module --- module arch_cutout(width, height, depth) { translate([-width/2, 0, -1]) cube([width, depth, height + 1]); translate([0, 0, height]) rotate([-90, 0, 0]) cylinder(h = depth, d = width); } // --- Main Model --- difference() { // 1. Solid Outer Shell union() { // Base flare for stability cylinder(h = 10, r1 = base_radius + 8, r2 = base_radius); // Main tower body cylinder(h = tower_height, r1 = base_radius, r2 = top_radius); // Top flare (corbel) translate([0, 0, tower_height - 10]) cylinder(h = 10, r1 = top_radius, r2 = top_radius + 6); // Top crenellation ring translate([0, 0, tower_height]) cylinder(h = crenellation_height, r = top_radius + 6); } // 2. Hollow Interior for Cables translate([0, 0, -1]) cylinder( h = tower_height + crenellation_height + 2, r1 = base_radius - wall_thickness, r2 = top_radius - wall_thickness ); // 3. Bottom Cable Entrance (Front) rotate([0, 0, 180]) arch_cutout(cable_hole_width, cable_hole_height, base_radius + 20); // 4. Top Cable Exit (Back) translate([0, 0, tower_height - cable_hole_height - 20]) arch_cutout(cable_hole_width, cable_hole_height, base_radius + 20); // 5. Crenellation Gaps (Battlements) for (i = [0 : crenellation_count - 1]) { rotate([0, 0, i * (360 / crenellation_count)]) translate([-crenellation_gap/2, top_radius - 5, tower_height - 1]) cube([crenellation_gap, 20, crenellation_height + 2]); } }