$fn = 64; // --- Parameters --- gap = 0.4; // Clearance for print-in-place hinges base_t = 4; // Thickness of flat parts hex_r = 25; // Radius of base hexagons // --- Modules --- // Slightly oversized hexagon to ensure manifold overlapping module hex_shape(r, h) { rotate([0, 0, 30]) cylinder(r=r+0.1, h=h, $fn=6); } module base() { difference() { union() { // 3-hex footprint (arranged in a triangle) translate([0, 30, 0]) hex_shape(hex_r, base_t); translate([21.65, 67.5, 0]) hex_shape(hex_r, base_t); translate([-21.65, 67.5, 0]) hex_shape(hex_r, base_t); // Connection block to main hinge (with overlap) translate([-30, -1, 0]) cube([60, 32, base_t]); } // Cutout clearance for the cradle's inner knuckle to rotate freely translate([-15 - gap, -12, -1]) cube([30 + 2*gap, 44, 10]); } // Main Hinge Outer Knuckles (Print-in-place cones pointing IN) translate([-30, 0, 4]) rotate([0,90,0]) cylinder(h=15-gap, r=4); translate([-15-gap, 0, 4]) rotate([0,90,0]) cylinder(h=4, r1=4, r2=0); translate([15+gap, 0, 4]) rotate([0,90,0]) cylinder(h=15-gap, r=4); translate([15+gap, 0, 4]) rotate([0,-90,0]) cylinder(h=4, r1=4, r2=0); // Adjustable angle ridges for the prop to catch on for (i=[40 : 8 : 80]) { translate([-15, i, 3.5]) rotate([0,90,0]) cylinder(h=30, r=2); } } module cradle() { difference() { union() { // Main Hinge Inner Knuckle (with conical cutouts) translate([-15, 0, 4]) rotate([0,90,0]) difference() { cylinder(h=30, r=4); translate([0,0,-0.01]) cylinder(h=4, r1=4+gap, r2=gap); translate([0,0,30+0.01]) rotate([180,0,0]) cylinder(h=4, r1=4+gap, r2=gap); } // Neck connecting hinge to main body translate([-15, -10, 0]) cube([30, 11, base_t]); // Main Phone Support Body translate([-35, -110, 0]) cube([70, 101, base_t]); // Bottom Phone Holding Lip translate([-35, -110, 0]) cube([70, 12, 15]); // Prop Hinge Outer Knuckles translate([-15, -80, 3]) rotate([0,90,0]) cylinder(h=7.5-gap, r=3); translate([-7.5-gap, -80, 3]) rotate([0,90,0]) cylinder(h=3, r1=3, r2=0); translate([7.5+gap, -80, 3]) rotate([0,90,0]) cylinder(h=7.5-gap, r=3); translate([7.5+gap, -80, 3]) rotate([0,-90,0]) cylinder(h=3, r1=3, r2=0); } // Cutout for Prop Body to fold flush translate([-8.5, -82, -1]) cube([17, 62, 10]); // Cutout clearance for Prop Hinge Inner Knuckle translate([-7.5-gap, -85, -1]) cube([15+2*gap, 10, 10]); // Hollow out Phone Lip to prevent screen blocking and save material translate([-31, -106, 4]) cube([62, 10, 12]); } } module prop() { union() { // Prop Hinge Inner Knuckle translate([-7.5, -80, 3]) rotate([0,90,0]) difference() { cylinder(h=15, r=3); translate([0,0,-0.01]) cylinder(h=3, r1=3+gap, r2=gap); translate([0,0,15+0.01]) rotate([180,0,0]) cylinder(h=3, r1=3+gap, r2=gap); } // Prop Body (overlaps with inner knuckle to ensure manifold) translate([-7.5, -81, 0]) cube([15, 57, base_t]); // Catch / Handle at the end of the prop translate([-7.5, -25, 0]) cube([15, 5, 6]); } } // --- Assembly --- // The model is generated flat for print-in-place without supports. // Once printed, the cradle hinges upwards and the prop hinges downwards to lock into the ridges. base(); cradle(); prop();