$fn = 64; // --- Parameters --- cable_diameter = 18; number_of_clips = 4; wall_thickness = 3; strip_depth = 15; // Width of the strip along the cable opening_width = 13.5; // Snap gap (smaller than cable diameter for snap fit) flare_extra = 4; // How much wider the opening gets at the top for easy insertion // Mounting parameters flange_length = 15; screw_hole_diameter = 4; screw_offset = 7.5; // Distance from edge to screw hole center base_height = 4; // Calculated values spacing = cable_diameter + wall_thickness * 2 + 2; total_length = number_of_clips * spacing + 2 * flange_length; outer_diameter = cable_diameter + wall_thickness * 2; module cable_clip_strip() { difference() { // Main solid body union() { // Base strip translate([0, -strip_depth/2, 0]) cube([total_length, strip_depth, base_height]); // Clip bodies for(i = [0 : number_of_clips - 1]) { cx = flange_length + spacing/2 + i * spacing; cz = base_height + cable_diameter/2; // Outer cylindrical shell translate([cx, 0, cz]) rotate([90, 0, 0]) cylinder(h=strip_depth, d=outer_diameter, center=true); // Solid block connecting outer cylinder to the base translate([cx - outer_diameter/2, -strip_depth/2, 0]) cube([outer_diameter, strip_depth, cz]); } } // Cutouts for cables and screws // Screw holes translate([screw_offset, 0, -1]) cylinder(h=base_height + 2, d=screw_hole_diameter); translate([total_length - screw_offset, 0, -1]) cylinder(h=base_height + 2, d=screw_hole_diameter); // Screw countersinks translate([screw_offset, 0, base_height - 2]) cylinder(h=2.1, d1=screw_hole_diameter, d2=screw_hole_diameter + 4.2); translate([total_length - screw_offset, 0, base_height - 2]) cylinder(h=2.1, d1=screw_hole_diameter, d2=screw_hole_diameter + 4.2); // Cable cutouts for(i = [0 : number_of_clips - 1]) { cx = flange_length + spacing/2 + i * spacing; cz = base_height + cable_diameter/2; // Inner cable hole translate([cx, 0, cz]) rotate([90, 0, 0]) cylinder(h=strip_depth + 2, d=cable_diameter, center=true); // Snap opening at the top translate([cx, 0, cz + cable_diameter/2]) hull() { // Bottom of the snap cut (blends into the circular hole) translate([0, 0, -cable_diameter/4]) cube([opening_width, strip_depth + 2, 0.1], center=true); // Top of the snap cut (flared for easier cable insertion) translate([0, 0, wall_thickness + 1]) cube([opening_width + flare_extra, strip_depth + 2, 0.1], center=true); } } } } cable_clip_strip();