$fn = 64; // --- Parametric Dimensions --- bottle_radius = 32; core_radius = 14; neck_radius = 16; wall = 4; hole_radius = 3.5; // Z-height segments for easy stacking h_base_chamfer = 10; h_base_straight = 8; h_slope = bottle_radius - core_radius; // 18mm (ensures 45-degree printable overhang) h_core = 24; h_shoulder = 16; h_neck = 16; // Cumulative Z heights z1 = h_base_chamfer; z2 = z1 + h_base_straight; z3 = z2 + h_slope; z4 = z3 + h_core; z5 = z4 + h_slope; z6 = z5 + h_base_straight; z7 = z6 + h_shoulder; z8 = z7 + h_neck; module potion_bottle() { difference() { // Outer Shell union() { cylinder(r1=bottle_radius-10, r2=bottle_radius, h=h_base_chamfer + 0.01); translate([0, 0, z1]) cylinder(r=bottle_radius, h=h_base_straight + 0.01); translate([0, 0, z2]) cylinder(r1=bottle_radius, r2=core_radius, h=h_slope + 0.01); translate([0, 0, z3]) cylinder(r=core_radius, h=h_core + 0.01); translate([0, 0, z4]) cylinder(r1=core_radius, r2=bottle_radius, h=h_slope + 0.01); translate([0, 0, z5]) cylinder(r=bottle_radius, h=h_base_straight + 0.01); translate([0, 0, z6]) cylinder(r1=bottle_radius, r2=neck_radius, h=h_shoulder + 0.01); translate([0, 0, z7]) cylinder(r=neck_radius, h=h_neck); // Flared Lip translate([0, 0, z8 - 4]) cylinder(r1=neck_radius, r2=neck_radius+4, h=2.01); translate([0, 0, z8 - 2]) cylinder(r=neck_radius+4, h=4.01); translate([0, 0, z8 + 2]) cylinder(r1=neck_radius+4, r2=neck_radius, h=2); } // Inner Cavity (Hollow out the center for storing cable ends/plugs) union() { translate([0, 0, wall]) cylinder(r1=bottle_radius-10-wall, r2=bottle_radius-wall, h=h_base_chamfer-wall + 0.01); translate([0, 0, z1]) cylinder(r=bottle_radius-wall, h=h_base_straight + 0.01); translate([0, 0, z2]) cylinder(r1=bottle_radius-wall, r2=core_radius-wall, h=h_slope + 0.01); translate([0, 0, z3]) cylinder(r=core_radius-wall, h=h_core + 0.01); translate([0, 0, z4]) cylinder(r1=core_radius-wall, r2=bottle_radius-wall, h=h_slope + 0.01); translate([0, 0, z5]) cylinder(r=bottle_radius-wall, h=h_base_straight + 0.01); translate([0, 0, z6]) cylinder(r1=bottle_radius-wall, r2=neck_radius-wall, h=h_shoulder + 0.01); translate([0, 0, z7]) cylinder(r=neck_radius-wall, h=h_neck + 10); // Extend through top } // Cable pass-through holes in the spool core translate([0, 0, z3 + h_core*0.25]) rotate([90, 0, 0]) cylinder(r=hole_radius, h=bottle_radius*3, center=true); translate([0, 0, z3 + h_core*0.75]) rotate([90, 0, 0]) cylinder(r=hole_radius, h=bottle_radius*3, center=true); // Cable retaining notches on the outer flanges for (i = [0 : 90 : 270]) { rotate([0, 0, i]) { translate([bottle_radius, 0, z1 + h_base_straight/2]) sphere(r=hole_radius); translate([bottle_radius, 0, z5 + h_base_straight/2]) sphere(r=hole_radius); } } } } module cork() { // Positioned beside the bottle for easy support-free printing translate([bottle_radius * 2, 0, 0]) { cylinder(r1=neck_radius-wall-0.5, r2=neck_radius-wall+2, h=15); translate([0, 0, 15]) scale([1, 1, 0.4]) sphere(r=neck_radius-wall+2); } } // Render the models potion_bottle(); cork();