// Petzl Am'D Ball-Lock Carabiner Keychain Replica // Parametric model designed for 3D printing /* [Dimensions] */ // Total length of the carabiner (mm) total_length = 60; // [40:1:120] // Width ratio relative to length width_ratio = 0.67; // [0.55:0.01:0.8] // Frame bar thickness (mm) bar_thickness = 5.2; // [3.5:0.1:8.0] // Frame depth / extrusion thickness (mm) bar_depth = 5.8; // [3.5:0.1:8.0] // Add optional small keychain ring hole at spine corner keychain_hole = false; keychain_hole_dia = 3.2; // [2:0.1:5] /* [Colors] */ frame_color = "#C8CED6"; // Anodized aluminum frame gate_sleeve_color = "#202022";// Black Ball-Lock sleeve gate_body_color = "#E0E4E8"; // Silver gate cylinder & pin ball_color = "#00C853"; // Bright green lock indicator ball text_color = "#8D96A0"; // Engraved spine text /* [Quality] */ $fn = 40; // Calculated dimensions total_width = total_length * width_ratio; scale_factor = total_length / 60; // baseline 60mm // Baseline coordinates (scaled by total_length / 60) // Centerline of the aluminum frame in 2D (spine on left, basket on top, gate on right) module frame_path_nodes() { // Defined normalized to 60mm length, centered around origin // Y: -28 (bottom narrow end) to +28 (top basket) // X: -16 (spine) to +18 (outer curve) } // 2D profile of the frame cross-section with subtle ergonomic Am'D flattened oval module bar_profile(r_x = bar_thickness/2, r_z = bar_depth/2) { resize([r_x * 2, r_z * 2]) circle(r = max(r_x, r_z)); } // 3D smooth segment between two points with scaled cross-sections module frame_segment(p1, p2, rx1, rz1, rx2, rz2) { hull() { translate(p1) scale([rx1 / (bar_thickness/2), rx1 / (bar_thickness/2), rz1 / (bar_depth/2)]) sphere(d = bar_thickness); translate(p2) scale([rx2 / (bar_thickness/2), rx2 / (bar_thickness/2), rz2 / (bar_depth/2)]) sphere(d = bar_thickness); } } // Am'D Spine & Body Path points [X, Y] // Spine on bottom when rotated, or vertical. Let's orient vertically (spine along -X): spine_x = -total_width * 0.42; // Key nodes around the frame loop: p_spine_bottom = [spine_x, -total_length * 0.24, 0]; p_spine_mid = [spine_x - 0.8 * scale_factor, 0, 0]; p_spine_top = [spine_x + 0.5 * scale_factor, total_length * 0.24, 0]; // Bottom corner (narrow harness end) p_bot_corner = [spine_x + 4 * scale_factor, -total_length * 0.44, 0]; p_bot_mid = [spine_x + 13 * scale_factor, -total_length * 0.48, 0]; p_bot_hinge = [spine_x + 22 * scale_factor, -total_length * 0.38, 0]; // hinge anchor // Top corner (wide basket end) p_top_corner = [spine_x + 8 * scale_factor, total_length * 0.46, 0]; p_top_mid = [spine_x + 21 * scale_factor, total_length * 0.48, 0]; p_top_outer = [spine_x + 34 * scale_factor, total_length * 0.36, 0]; p_top_nose = [spine_x + 26.5 * scale_factor, total_length * 0.24, 0]; // nose crook frame_nodes = [ p_bot_hinge, [spine_x + 18 * scale_factor, -total_length * 0.45, 0], p_bot_mid, p_bot_corner, [spine_x - 0.5 * scale_factor, -total_length * 0.36, 0], p_spine_bottom, p_spine_mid, p_spine_top, [spine_x + 2 * scale_factor, total_length * 0.38, 0], p_top_corner, p_top_mid, p_top_outer, [spine_x + 32 * scale_factor, total_length * 0.28, 0], p_top_nose ]; module carabiner_frame() { color(frame_color) { difference() { union() { // Continuous curved frame for (i = [0 : len(frame_nodes)-2]) { hull() { translate(frame_nodes[i]) scale([1, 1, bar_depth/bar_thickness]) sphere(d = bar_thickness); translate(frame_nodes[i+1]) scale([1, 1, bar_depth/bar_thickness]) sphere(d = bar_thickness); } } // Hinge boss (tangent blend at bottom gate connection) translate(p_bot_hinge) { rotate([0, 0, 15]) scale([1, 1, bar_depth/bar_thickness]) cylinder(d = bar_thickness * 1.05, h = bar_thickness, center = true); } // Nose hook detail translate(p_top_nose) { rotate([0, 0, -30]) scale([1, 1, bar_depth/bar_thickness]) cylinder(d = bar_thickness * 0.95, h = bar_thickness, center = true); } } // Optional keychain ring hole at bottom-spine corner if (keychain_hole) { translate([spine_x + 3 * scale_factor, -total_length * 0.40, 0]) cylinder(d = keychain_hole_dia, h = bar_depth * 2, center = true); } // Engraved text on spine flat translate([spine_x - bar_thickness * 0.42, 0, 0]) rotate([90, 0, 90]) linear_extrude(height = 0.5 * scale_factor, center = true) rotate([0, 0, -90]) text("PETZL Am'D", size = 2.4 * scale_factor, font = "Liberation Sans:style=Bold", halign = "center", valign = "center"); } } } // Gate Assembly: Hinge, silver gate barrel, black Ball-Lock sleeve, and green ball module gate_assembly() { p1 = p_bot_hinge; p2 = p_top_nose; gate_vec = p2 - p1; gate_len = norm(gate_vec); gate_dir = gate_vec / gate_len; // Calculate rotation angle to align with gate axis angle_z = atan2(gate_vec[1], gate_vec[0]); translate(p1) rotate([0, 0, angle_z]) { // Inner silver gate core cylinder spanning hinge to nose color(gate_body_color) { translate([0, 0, 0]) rotate([0, 90, 0]) cylinder(d = bar_thickness * 0.82, h = gate_len, $fn = 32); // Hinge pivot pin translate([gate_len * 0.12, 0, 0]) cylinder(d = 1.8 * scale_factor, h = bar_depth * 1.02, center = true); // Nose notch hood translate([gate_len - 1.5 * scale_factor, 0, 0]) rotate([0, 90, 0]) cylinder(d = bar_thickness * 0.78, h = 1.8 * scale_factor, center = true); } // Black Ball-Lock locking sleeve sleeve_len = gate_len * 0.62; sleeve_offset = gate_len * 0.18; sleeve_dia = bar_thickness * 1.55; color(gate_sleeve_color) { difference() { // Outer sleeve barrel with Petzl multi-faceted / ergonomic contour translate([sleeve_offset, 0, 0]) rotate([0, 90, 0]) union() { // Main cylindrical & tapered body cylinder(d1 = sleeve_dia * 0.95, d2 = sleeve_dia, h = sleeve_len * 0.5, $fn = 36); translate([0, 0, sleeve_len * 0.5]) cylinder(d1 = sleeve_dia, d2 = sleeve_dia * 0.92, h = sleeve_len * 0.5, $fn = 36); } // Inner bore for gate core translate([sleeve_offset - 1, 0, 0]) rotate([0, 90, 0]) cylinder(d = bar_thickness * 0.86, h = sleeve_len + 2, $fn = 32); // Thumb depression / concavity for the Ball-Lock green button translate([sleeve_offset + sleeve_len * 0.68, 0, sleeve_dia * 0.46]) scale([1.8, 1.0, 0.6]) sphere(d = sleeve_dia * 0.7); // Asymmetric cutout notch at top of sleeve where nose connects translate([sleeve_offset + sleeve_len - 1.5 * scale_factor, sleeve_dia * 0.22, 0]) cube([3.5 * scale_factor, sleeve_dia, sleeve_dia * 1.2], center = true); // Slot for hinge pin travel / twist indication translate([sleeve_offset + 1.5 * scale_factor, 0, 0]) cube([2.2 * scale_factor, sleeve_dia * 1.1, 1.4 * scale_factor], center = true); } } // Green Ball-Lock button color(ball_color) { translate([sleeve_offset + sleeve_len * 0.68, 0, sleeve_dia * 0.32]) sphere(d = 2.4 * scale_factor, $fn = 24); } } } // Complete Assembly module petzl_amd_carabiner() { // Place flat on XY build plane, spine aligned for printing carabiner_frame(); gate_assembly(); } petzl_amd_carabiner();