// Under-desk cable tray: sheet-metal U-channel with inward return lips // Units: mm. Z up, part rests on Z=0, length runs along X. /* [Sheet] */ thickness = 1.2; // [0.5:0.1:3] inside_radius = 1.2; // [0.5:0.1:5] k_factor = 0.44; // [0.3:0.01:0.5] /* [Channel (outside dimensions)] */ length = 250; // [100:1:600] width = 42; // [20:1:120] height = 30; // [15:1:100] lip = 8; // [4:0.5:20] return lip, measured from outer wall face /* [Holes] */ hole_d = 5; // [3:0.5:10] hole_count = 6; // [1:1:12] hole_pitch = 40; // [10:1:100] /* [Output] */ mode = "folded"; // [folded, flat] /* [Hidden] */ $fn = 64; T = thickness; R = inside_radius; K = k_factor; S = R + T; // outside setback for 90 deg bend BA = (PI/2) * (R + K*T); // bend allowance per 90 deg bend base_flat = width - 2*S; wall_flat = height - 2*S; lip_flat = lip - S; flat_w = base_flat + 2*wall_flat + 2*lip_flat + 4*BA; hole_x = [for (i=[0:hole_count-1]) length/2 + (i - (hole_count-1)/2)*hole_pitch]; echo(str("BA=",BA," flat=",length," x ",flat_w)); // annulus sector, center c=[y,z], from angle a0 to a1 (deg) module sector(c, a0, a1) { translate(c) intersection() { difference() { circle(r=R+T); circle(r=R); } polygon(concat([[0,0]], [for (a=[a0:(a1-a0)/32:a1]) 2*(R+T)*[cos(a), sin(a)]])); } } // cross-section in (Y,Z) module profile() { // base translate([S, 0]) square([base_flat, T]); // bottom bends sector([S, S], 180, 270); sector([width - S, S], 270, 360); // walls translate([0, S]) square([T, wall_flat]); translate([width - T, S]) square([T, wall_flat]); // top bends sector([S, height - S], 90, 180); sector([width - S, height - S], 0, 90); // return lips translate([S, height - T]) square([lip_flat, T]); translate([width - S - lip_flat, height - T]) square([lip_flat, T]); } module folded() { difference() { rotate([90, 0, 90]) linear_extrude(length) profile(); for (x = hole_x) translate([x, width/2, -1]) cylinder(d=hole_d, h=T+2); } } // flat pattern: X = length, Y = developed width, base centred on Y = flat_w/2 module flat() { difference() { square([length, flat_w]); for (x = hole_x) translate([x, flat_w/2]) circle(d=hole_d); } } if (mode == "flat") flat(); else folded();