$fn = 64; // --- Parameters --- // Cup Dimensions cup_top_id = 80; // Inner diameter at top (tapered for secure grip) cup_bottom_id = 70; // Inner diameter at bottom holder_height = 60; // Height of the cup holder wall_thickness = 3; // Wall thickness of the cup holder base_thickness = 3; // Thickness of the bottom base // Rail Mount Dimensions (ArtArsenal / Generic Rail) mount_width = 40; // Width of the wall bracket mount_height = 80; // Total height of the wall bracket plate_thickness = 5; // Thickness of the main backplate rail_gap = 5; // Thickness of the rail lip (gap width) hook_thick = 5; // Thickness of the hook walls hook_length = 15; // How far the hook drops down behind the rail standoff_height = 10; // Height of the bottom wall standoff // Structural spine_thick = 15; // Thickness of the connecting spine // --- Derived Variables --- cup_top_od = cup_top_id + wall_thickness * 2; cup_bottom_od = cup_bottom_id + wall_thickness * 2; overlap = 1; cup_y = -cup_top_od/2 + overlap; // --- Modules --- module rail_mount() { rotate([90, 0, 90]) linear_extrude(height=mount_width, center=true) polygon([ [0, 0], [plate_thickness + rail_gap + hook_thick, 0], [plate_thickness + rail_gap + hook_thick, standoff_height], [plate_thickness, standoff_height + 5], [plate_thickness, mount_height - hook_thick], [plate_thickness + rail_gap, mount_height - hook_thick], [plate_thickness + rail_gap, mount_height - hook_thick - hook_length], [plate_thickness + rail_gap + hook_thick, mount_height - hook_thick - hook_length], [plate_thickness + rail_gap + hook_thick, mount_height], [0, mount_height] ]); } // --- Main Assembly --- difference() { union() { // Main Cup Holder Body translate([0, cup_y, 0]) cylinder(d1=cup_bottom_od, d2=cup_top_od, h=holder_height); // Wall Rail Mount rail_mount(); // Connecting Spine translate([-spine_thick/2, cup_y, 0]) cube([spine_thick, abs(cup_y) + overlap, holder_height]); } // Inner Cup Cutout translate([0, cup_y, base_thickness]) cylinder(d1=cup_bottom_id, d2=cup_top_id, h=holder_height + 1); // Top Chamfer for easy insertion translate([0, cup_y, holder_height - 2]) cylinder(d1=cup_top_id, d2=cup_top_id + 4, h=2.1); // Bottom Drain Hole translate([0, cup_y, -1]) cylinder(d=cup_bottom_id - 20, h=base_thickness + 2); }