$fn = 64; // Parametric dimensions clip_length = 75; clip_width = 15; arm_thickness = 2.5; hinge_inner_radius = 5; hinge_thickness = 1.8; module bag_clip() { // Extrude the entire 2D profile to make it perfectly 3D printable on its side // This orientation ensures maximum strength for the hinge and latch linear_extrude(height = clip_width) { union() { // 1. Flexible C-Hinge (Left side) difference() { circle(r = hinge_inner_radius + hinge_thickness); circle(r = hinge_inner_radius); // Cut the right half to create the "C" shape translate([0, -(hinge_inner_radius + hinge_thickness + 1)]) square([(hinge_inner_radius + hinge_thickness + 1) * 2, (hinge_inner_radius + hinge_thickness + 1) * 2]); } // 2. Bottom Arm translate([0, -hinge_inner_radius - hinge_thickness]) square([clip_length, arm_thickness]); // 3. Bottom Jaw Platform (Clamping surface with slight overlap for manifoldness) translate([15, -hinge_inner_radius - hinge_thickness + arm_thickness - 0.1]) square([clip_length - 35, hinge_inner_radius + hinge_thickness - arm_thickness - 0.5 + 0.1]); // 4. Bottom Teeth (Grip) for(i = [25 : 10 : 45]) { translate([i, -0.5]) circle(r = 1.5); } // 5. Top Arm with Jaw Platform and Thumb Tab difference() { union() { // Main top arm translate([0, hinge_inner_radius + hinge_thickness - arm_thickness]) square([clip_length - 2, arm_thickness]); // Top Jaw Platform translate([15, 1.5]) square([clip_length - 35, hinge_inner_radius + hinge_thickness - arm_thickness - 1.5 + 0.1]); // Rounded tip for smooth snapping over the latch translate([clip_length - 2, hinge_inner_radius + hinge_thickness - arm_thickness / 2]) circle(d = arm_thickness + 0.1); // Thumb tab on top arm for easier pressing translate([clip_length - 12, hinge_inner_radius + hinge_thickness]) polygon([[0, 0], [8, 0], [6, 3], [2, 3]]); } // Top Grooves (Matches bottom teeth for tight interlocking) for(i = [25 : 10 : 45]) { translate([i, 1.5]) circle(r = 2.0); } } // 6. Snap Latch / Hook on Bottom Arm hook_x = clip_length; polygon([ [hook_x - 0.1, -hinge_inner_radius - hinge_thickness], // slight overlap with bottom arm [hook_x + 4, -hinge_inner_radius - hinge_thickness], [hook_x + 4, 5], [hook_x + 8, 5], // Release thumb tab bottom [hook_x + 8, 7.5], // Release thumb tab top [hook_x, 7.5], // Hook top [hook_x - 3, 5.0], // Catch lip tip (chamfered for snap-fit) [hook_x, 3.5] // Catch resting surface ]); } } } // Center the model on the build plate translate([-clip_length / 2, 0, 0]) bag_clip();