button_od = 23.6; // Outside diameter of button tab_offset = 22; // How far down the button the little tabs are tab_width = 4; // Size of the tabs tab_protrusion = 1.5; // How far tabs stick out guide_size = 2.5; // How wide the guide channels are wall_width = 1.8; // How thick should the walls be rod_od = 3.5; // The outside diameter of the rod button_curvature_depth = 5; button_wall = 1; // Computed values button_id = button_od - wall_width*2; rod_width = rod_od / sqrt(2); // It's easier to print if the rod is square button_height = 24; // How tall the button is inset_height = button_curvature_depth + button_wall; module rod(width, height) { translate([-width/2, -width/2, 0]) cube([width, width, height]); } rotate(180, [1, 0, 0]) { difference() { union() { // Outer button difference() { cylinder(h=button_height, r=button_od/2, $fn=360); // Inner cup for the rod translate([0, 0, inset_height]) { rod(rod_width + 0.2, button_height); } // There's this guiderail thingy for (a = [30, 150, 270]) { rotate(a=a, v=[0,0,1]) { translate([button_id/2 + wall_width - 0.8, -guide_size/2, 0]) { cube([wall_width, guide_size, button_height+1]); } } } // The part you press with your finger rotate(a=-60, v=[0,0,1]) { // The button is actually sloped rotate(a=-4, v=[1,0,0]) { translate([-button_od, -button_od, -1.185]) { cube([button_od*2, button_od*2, 2]); } } // A little curvature on outside where you press the button resize([button_od*.75, button_od*.75, button_curvature_depth+3]) { sphere(r=10, , $fn=90); } } // There's a cutout on the right side at the end. I just eyeballed it. rotate(a=-50, v=[0,0,1]) { translate([button_od*.39, -button_od/2, button_height-4]) { cube(button_od); } } } // Tabs on the side for stops intersection() { union() { for (a = [0, 180]) { rotate(a=a, v=[0,0,1]) { translate([(button_od - wall_width)/2, 0, tab_offset+1]) { cube([wall_width+tab_protrusion, tab_width, 2], center=true); } } } } cylinder(h=button_height, r1=button_od, r2=button_od/2, $fn=360); } } } }