$fn=64; // --- Parameters --- board_thickness = 15; // Thickness of the canvas/easel board board_insert_depth = 25; // How deep the clip slides onto the board wall_thickness = 4; // Outer wall thickness clip_width = 20; // Width of the clip (Y-axis) photo_insert_depth = 15; // How deep the photo slides into the top slot paper_slot_width = 0.5; // Width of the top pinch slot // --- Derived Dimensions --- total_depth = board_thickness + wall_thickness * 2; total_height = board_insert_depth + wall_thickness + photo_insert_depth; mid_z = board_insert_depth + wall_thickness; cw = clip_width + 2; // Extended width for clean boolean cuts // Recommended to print on its side (rotate 90 degrees on X or Y) // for optimal layer line strength and no supports. module reference_photo_clip() { difference() { // Main Body union() { // Lower body (Board attachment section) hull() { translate([wall_thickness, 0, wall_thickness]) rotate([-90, 0, 0]) cylinder(h=clip_width, r=wall_thickness); translate([total_depth - wall_thickness, 0, wall_thickness]) rotate([-90, 0, 0]) cylinder(h=clip_width, r=wall_thickness); translate([wall_thickness, 0, mid_z]) rotate([-90, 0, 0]) cylinder(h=clip_width, r=wall_thickness); translate([total_depth - wall_thickness, 0, mid_z]) rotate([-90, 0, 0]) cylinder(h=clip_width, r=wall_thickness); } // Upper body (Photo attachment section) hull() { translate([wall_thickness, 0, mid_z]) rotate([-90, 0, 0]) cylinder(h=clip_width, r=wall_thickness); translate([total_depth - wall_thickness, 0, mid_z]) rotate([-90, 0, 0]) cylinder(h=clip_width, r=wall_thickness); translate([total_depth/2 - 3, 0, total_height - 3]) rotate([-90, 0, 0]) cylinder(h=clip_width, r=3); translate([total_depth/2 + 3, 0, total_height - 3]) rotate([-90, 0, 0]) cylinder(h=clip_width, r=3); } } // 1. Board Slot Cutout translate([wall_thickness, -1, -1]) cube([board_thickness, cw, board_insert_depth + 1]); // Board Slot Chamfers (Lead-in for easy sliding onto canvas) translate([wall_thickness, -1, 0]) rotate([-90, 0, 0]) cylinder(h=cw, r=1.5, $fn=4); translate([wall_thickness + board_thickness, -1, 0]) rotate([-90, 0, 0]) cylinder(h=cw, r=1.5, $fn=4); // 2. Photo Slot Cutout translate([total_depth/2 - paper_slot_width/2, -1, total_height - photo_insert_depth]) cube([paper_slot_width, cw, photo_insert_depth + 1]); // Photo Slot V-Groove (Lead-in to guide paper easily) translate([total_depth/2, -1, total_height + 1.5]) rotate([-90, 0, 0]) cylinder(h=cw, r=3, $fn=4); // Photo Slot Stress Relief (Prevents snapping, adds flex) translate([total_depth/2, -1, total_height - photo_insert_depth]) rotate([-90, 0, 0]) cylinder(h=cw, r=1.2); } } // Center the object for better visualization translate([-total_depth/2, -clip_width/2, 0]) reference_photo_clip();