Inspired by Project Binky who doubtless were working from Screw To Win.
Generates split-block cable and pipe clamps in OpenSCAD for you to mill or 3D print or just use the measurements to work out where to drill!
If you want instant gratification you can also use the online version to generate a scale drawing and a drilling list.
Clamp produced by V0.1
Clamp produced by V0.2
// // +++++++++++++++++++++ // Binky Bracketeer V0.2 // +++++++++++++++++++++ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Copyright 2019 Fuddymuckers.co.uk // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Parametrically create cable/hose clamps a-la Project Binky or Screw To Win // // No warranty, guarantee, claims of suitability, delusions of adequacy. // High likelihood of tragedy, death, fire, pestilence and plague if used. // // ================================ // TODO: // ----- // Optional single mounting, centre mounting // Optional locating features // Rounded ends // Add labels / text, logo, flames, go-faster stripes... // // Revision history: // ----------------- // V0.2 - Added hole chamfering, counterbore, split options // --- // V0.1 - 1st stab, very basic // --- // +++++++++++++++++++++++++++++++++++++++++++++++ // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // // Configuration options below this line, change as required // // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // // Do we split this in half and mill/print it as two pieces? // Advantage: can be made in one operation on a 3-axis mill or 3D printer // Disadvantage: Not as neat, more complicated // split = 1; // 1 = Yes, 0 = No, 5 is right out. // // Overall dimension of finished piece - width will be calculated // height = 20; // Height of block in mm depth = 20; // Depth of holes in mm // // Clamping holes // holes = [6,4,7,4,10]; // Holes to make, in mm, add/remove as required space = 5; // Space between each hole, mm chamfer = 1; // Amount to chamfer the holes, 0 = don't. // // Mounting holes, currently at either end only. // mounting_hole = 6; // Mounting holes, in mm space_to_edge = 10; // Space from mounting hole to edge of piece space_to_hole = 0; // Space from mounting hole to through-hole (space will be added too) num_mounts = 2; // Leave at 2 - other numbers as yet unhandled counterbore = 1; // 1=enable, 0=disable screw_head_dia = 10; // Diameter of hole to counterbore, mm screw_head_depth = 5; // How deep to counterbore, mm // Smoother holes - RTFM $fn = 50; // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // // Code below this line, shouldn't need touching for intended use // // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // Count number of holes in matrix num_holes = len(holes)-1; // How much space one mount requires mount_space = (mounting_hole + space_to_edge + space_to_hole); // Simple matrix adding up from TFM function add(v) = [for(p=v) 1]*v; // Add matrix starting at element i function add2(v, i, r = 0) = i < len(v) ? add2(v, i + 1, r + v[i]) : r; // Add matrix stopping at element e function add3(v, e, i = 0, r = 0) = i < min(len(v), e) ? add3(v, e, i + 1, r + v[i]) : r; tot_hole_space = add(holes) + (num_holes * space); tot_mount_space = mount_space * num_mounts; width = tot_hole_space + tot_mount_space; start = mount_space; echo("Width=", width, " Height=", height, " Depth=", depth); module bracket() { difference() { // Solid base chunk cube([width, depth, height]); // Visual-only split translate([-1,(depth/2)-0.5,-1]) { // % means show but don't use - ghost object %cube([width+2, 1, height+2]); } // Things to remove from base - or "holes" as they're known union() { // Make clamping holes union() { for(n=[0:num_holes]) { dia = holes[n]; ct = add3(holes, n); xt = start + (space * (n)) + ct + dia/2; echo("Hole=", n, " Dia=", dia, " Tot=", ct, " Offset=", xt); translate([xt,height/2,-1]) { cylinder(depth+2,d=dia, false); } if(chamfer > 0) { hc = chamfer/2; translate([xt,height/2,depth-chamfer]) { cylinder(chamfer+1,d1=dia, d2=dia+chamfer+2, false); } translate([xt,height/2,0-chamfer]) { cylinder(chamfer+1,d2=dia, d1=dia+chamfer+2, false); } } } } // Make mounting holes union() { translate([space_to_edge,depth+1,height/2]) { rotate([90,0,0]) { cylinder(depth+2,d=mounting_hole, false); if(counterbore == 1) { cylinder(screw_head_depth+1,d=screw_head_dia, false); } } } translate([width - space_to_edge,depth+1,height/2]) { rotate([90,0,0]) { cylinder(depth+2,d=mounting_hole, false); if(counterbore == 1) { cylinder(screw_head_depth+1,d=screw_head_dia, false); } } } } } } } // // Do we draw the basic thing or split it in half? // if(split > 0) { difference() { // Draw two brackets, laid opposite each other union() { translate([0,0 - (depth+5),height]) { rotate([-90,0,0]) { bracket(); } } translate([0,(depth+5),0]) { rotate([90,0,0]) { bracket(); } } } // Draw a cube to slice the top off translate([-1,0-(depth+10),height/2]) { cube(size=[width+2,((depth + 10) * 2), height/2+1]); } } } else { bracket(); }