Last active
June 16, 2026 12:40
-
-
Save brahimmachkouri/dad6c303edceae9bba49af1bdccf6550 to your computer and use it in GitHub Desktop.
Capsule porte-clé — Double bouchon dévissable + anneau - !! NON FINALISÉ !!
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // ===================================================================== | |
| // CAPSULE PORTE-CLÉ — double bouchon dévissable + œillet évasé | |
| // ===================================================================== | |
| // FDM / PLA. Filets via threads.scad (rcolyer, CC0). | |
| // -> threads.scad doit être dans le même dossier. | |
| // https://www.thingiverse.com/thing:1686322 | |
| // ===================================================================== | |
| use <threads.scad> | |
| /* [Dimensions principales] */ | |
| inner_d = 13; | |
| inner_len = 37; | |
| wall = 2.0; | |
| /* [Filetage] */ | |
| thread_len = 7; | |
| thread_pitch = 1.5; | |
| thread_depth = 0.65; | |
| thread_angle = 55; | |
| thread_tol = 0.35; | |
| /* [Bouchons] */ | |
| cap_wall = 2.0; | |
| cap_skirt_extra= 0.7; | |
| /* [Œillet porte-clé] */ | |
| ring_outer_d = 12; | |
| ring_hole_d = 5.5; | |
| ring_neck_h = 6.5; | |
| ring_base_w = 12; | |
| ring_top_w = 5; | |
| /* [Qualité] */ | |
| $fn = 96; | |
| /* [Affichage] */ | |
| show = "all"; // [all, body, cap_plain, cap_ring, assembled] | |
| //show = "assembled"; | |
| // ---- Dérivés ------------------------------------------------------- | |
| body_inner_r = inner_d / 2; | |
| thread_outer_d = inner_d + 2 * wall; | |
| bore_clear_r = thread_outer_d / 2 + thread_tol; | |
| cap_outer_r = bore_clear_r + cap_skirt_extra; | |
| eps = 0.02; | |
| // ===================================================================== | |
| // CORPS : tube + filet mâle aux deux extrémités | |
| // ===================================================================== | |
| module body() { | |
| total = inner_len + 2 * thread_len; | |
| difference() { | |
| union() { | |
| // partie centrale | |
| translate([0, 0, thread_len]) | |
| cylinder(h = inner_len, r = thread_outer_d / 2); | |
| // filet bas | |
| ScrewThread( | |
| thread_outer_d, | |
| thread_len, | |
| pitch = thread_pitch, | |
| tooth_angle = thread_angle, | |
| tooth_height = thread_depth, | |
| tolerance = 0 | |
| ); | |
| // filet haut inversé | |
| translate([0, 0, total]) | |
| mirror([0, 0, 1]) | |
| ScrewThread( | |
| thread_outer_d, | |
| thread_len, | |
| pitch = thread_pitch, | |
| tooth_angle = thread_angle, | |
| tooth_height = thread_depth, | |
| tolerance = 0 | |
| ); | |
| } | |
| // passage intérieur | |
| translate([0, 0, -eps]) | |
| cylinder(h = total + 2 * eps, r = body_inner_r); | |
| } | |
| } | |
| // ===================================================================== | |
| // BOUCHON : jupe moletée + taraudage femelle | |
| // ===================================================================== | |
| module cap(with_ring=false) { | |
| h_thread = thread_len + 0.8; | |
| total_h = h_thread + cap_wall; | |
| // rayon au fond du taraudage femelle | |
| female_minor_r = thread_outer_d/2 - thread_depth + thread_tol; | |
| difference() { | |
| union() { | |
| knurled_skirt(total_h, cap_outer_r); | |
| // fond plein du bouchon | |
| translate([0, 0, h_thread]) | |
| cylinder(h = cap_wall, r = cap_outer_r); | |
| } | |
| // 1) perçage au diamètre mineur | |
| translate([0,0,-eps]) | |
| cylinder(h = h_thread + 2*eps, r = female_minor_r); | |
| // 2) profil hélicoïdal pour former le taraudage | |
| translate([0,0,-eps]) | |
| ScrewThread( | |
| thread_outer_d + 2*thread_tol, | |
| h_thread + 2*eps, | |
| pitch = thread_pitch, | |
| tooth_angle = thread_angle, | |
| tooth_height = thread_depth, | |
| tolerance = 0 | |
| ); | |
| // 3) léger chanfrein d'entrée | |
| translate([0,0,-eps]) | |
| cylinder( | |
| h = 0.8, | |
| r1 = thread_outer_d/2 + thread_tol + 0.35, | |
| r2 = female_minor_r | |
| ); | |
| } | |
| if (!with_ring) { | |
| translate([0,0,total_h - eps]) | |
| cylinder(h = 0.6, r1 = cap_outer_r, r2 = cap_outer_r - 0.6); | |
| } | |
| if (with_ring) { | |
| translate([0,0,total_h - 0.8]) | |
| keyring(); | |
| } | |
| } | |
| // ===================================================================== | |
| // MOLETAGE SIMPLE | |
| // ===================================================================== | |
| module knurled_skirt(h, r) { | |
| n = floor(2 * PI * r / 1.5); | |
| union() { | |
| cylinder(h = h, r = r); | |
| for (i = [0 : n - 1]) { | |
| rotate([0, 0, 360 * i / n]) | |
| translate([r, 0, 0]) | |
| cylinder(h = h, r = 0.45, $fn = 8); | |
| } | |
| } | |
| } | |
| // ===================================================================== | |
| // ŒILLET renforcé | |
| // ===================================================================== | |
| module keyring() { | |
| R = (ring_outer_d + ring_hole_d) / 4; | |
| sr = (ring_outer_d - ring_hole_d) / 4; | |
| eye_z = ring_neck_h + R; | |
| union() { | |
| // embase renforcée sur le bouchon | |
| hull() { | |
| translate([0, 0, 0.2]) | |
| cylinder(h = 0.4, r = ring_base_w / 2); | |
| translate([0, 0, 1.8]) | |
| cylinder(h = 0.4, r = ring_base_w / 2 - 1.2); | |
| } | |
| // col arrondi | |
| hull() { | |
| for (sx = [-1, 1]) | |
| translate([sx * (ring_base_w / 2 - sr), 0, sr]) | |
| sphere(r = sr); | |
| for (sx = [-1, 1]) | |
| translate([sx * (ring_top_w / 2 - sr), 0, ring_neck_h - sr]) | |
| sphere(r = sr); | |
| } | |
| // anneau torique | |
| translate([0, 0, eye_z]) | |
| rotate([90, 0, 0]) | |
| rotate_extrude($fn = $fn) | |
| translate([R, 0]) | |
| circle(r = sr); | |
| } | |
| } | |
| // ===================================================================== | |
| // AFFICHAGE | |
| // ===================================================================== | |
| spacing = cap_outer_r * 2 + 8; | |
| if (show == "all") { | |
| body(); | |
| translate([-spacing, 0, 0]) | |
| cap(true); | |
| translate([spacing, 0, 0]) | |
| cap(false); | |
| } else if (show == "body") { | |
| body(); | |
| } else if (show == "cap_plain") { | |
| cap(false); | |
| } else if (show == "cap_ring") { | |
| cap(true); | |
| } else if (show == "assembled") { | |
| total = inner_len + 2 * thread_len; | |
| h_thread = thread_len + 0.8; | |
| total_h = h_thread + cap_wall; | |
| body(); | |
| // bouchon du haut : PAS de rotation | |
| translate([0, 0, total - eps]) | |
| cap(false); | |
| // bouchon du bas : retourné | |
| translate([0, 0, eps]) | |
| rotate([180, 0, 0]) | |
| cap(true); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment