$fn = 64; // Parametric Variables jaw_width = 28; jaw_thick = 4; hinge_len = 14; b_jaw_len = 90; t_jaw_len = 88; hole_offset = 45; spout_r = 13; spout_h = 16; ring_r = 10; ring_h = 5; thread_pitch = 4; thread_depth = 1.2; // Main Assembly bag_clip(); translate([0, 45, 0]) bag_cap(); // --- Modules --- module bag_clip() { union() { bottom_jaw(); living_hinge(); top_jaw(); } } module bottom_jaw() { difference() { union() { // Main bottom body translate([hinge_len/2, -jaw_width/2, 0]) cube([b_jaw_len, jaw_width, jaw_thick]); // Inner sealing ring translate([hinge_len/2 + hole_offset, 0, jaw_thick - 0.1]) cylinder(r1=ring_r, r2=ring_r-0.5, h=ring_h + 0.1); // Latch base translate([hinge_len/2 + b_jaw_len - 2, -8, 0]) cube([2, 16, jaw_thick + 7]); // Latch snap hook translate([hinge_len/2 + b_jaw_len - 2, 0, jaw_thick + 4.5]) rotate([90, 0, 0]) cylinder(r=1.2, h=16, center=true); } // Hole through the ring for the bag translate([hinge_len/2 + hole_offset, 0, -1]) cylinder(r=ring_r - 2, h=jaw_thick + ring_h + 2); } } module top_jaw() { difference() { union() { // Main top body translate([-hinge_len/2 - t_jaw_len, -jaw_width/2, 0]) cube([t_jaw_len, jaw_width, jaw_thick]); // Threaded spout base translate([-hinge_len/2 - hole_offset, 0, jaw_thick - 0.1]) cylinder(r1=spout_r, r2=spout_r-0.5, h=spout_h + 0.1); // Spout threads translate([-hinge_len/2 - hole_offset, 0, jaw_thick]) helical_thread(r=spout_r, h=spout_h - 1.5, pitch=thread_pitch, depth=thread_depth); } // Clearance hole for the sealing ring and bag translate([-hinge_len/2 - hole_offset, 0, -1]) cylinder(r=ring_r + 0.6, h=jaw_thick + spout_h + 2); } } module living_hinge() { // Thin flexible bridge connecting the jaws translate([-hinge_len/2, -jaw_width/2, 0]) cube([hinge_len, jaw_width, 0.8]); } module bag_cap() { difference() { // Outer cap body cylinder(r=spout_r + 5, h=spout_h + 3); // Internal cavity translate([0, 0, 2.5]) cylinder(r=spout_r + 0.6, h=spout_h + 1); // Internal female threads translate([0, 0, 2.5]) helical_thread(r=spout_r + 0.6, h=spout_h, pitch=thread_pitch, depth=thread_depth); // Outer knurling for grip for(i = [0 : 15]) { rotate([0, 0, i * (360/16)]) translate([spout_r + 5.5, 0, -1]) cylinder(r=2, h=spout_h + 5); } } } module helical_thread(r, h, pitch, depth, starts=3) { for(i = [0 : starts - 1]) { rotate([0, 0, i * (360/starts)]) linear_extrude(height=h, twist=-360*(h/pitch), slices=round(h*12)) translate([r, 0, 0]) circle(r=depth, $fn=16); } }