$fn = 20; din_w = 35; din_w2 = 25; din_wall = 1; din_h = 7.5; tol = 0.1; m = 3; wall = 1.5; module cylindery(l, d) { translate([d/2, 0, d/2]) rotate(90, [-1, 0, 0]) cylinder(l, d/2, d/2); } module cylinderx(l, d) { translate([0, d/2, d/2]) rotate(90, [0, 1, 0]) cylinder(l, d/2, d/2); } module cylinderz(l, d) { translate([d/2, d/2, 0]) cylinder(l, d/2, d/2); } h1 = m + 2; h2 = 3; module top_clip(bar_s) { cube([wall, bar_s.y, din_wall+h2-wall/2]); hull() { translate([0, 0, din_wall]) cube([wall, bar_s.y, wall]); translate([0, 0, din_wall+h2-wall/2]) { cylindery(bar_s.y, wall); translate([-2, 0, 0]) cylindery(bar_s.y, wall); } } z = wall*1.2; translate([wall, bar_s.y/2, 0]) rotate(45, [0, 1, 0]) cube([z, bar_s.y, z], center=true); } module bottom_clip_holes(bar_s) { h = bar_s.y/2 + m; translate([-10, h - wall, m/2 + 0.2]) cylinderx(50, m); } module bottom_clip(bar_s) { h = bar_s.y/2 + m; difference() { union() { cube([wall, bar_s.y, din_wall+h1]); translate([0, 0, din_wall+h1-wall/2]) cylindery(bar_s.y, wall); translate([-wall, 0, 0]) { cube([wall, h, h1 + din_wall]); translate([0, h - (h1+din_wall)/2, 0]) cylinderx(wall, h1 + din_wall); } } bottom_clip_holes(bar_s); } } module main_bar(bar_s) { hull() { cylindery(bar_s.y, wall); translate([bar_s.x - wall, 0, 0]) cylindery(bar_s.y, wall); } } module bottom_ledge(bar_s) { h = bar_s.y / 2 - wall; translate([wall, 0, wall]) { cube([m + wall, h, wall]); translate([0, h - (m+wall)/2, 0]) cylinderz(wall, m+wall); } } module bottom_ledge_holes(bar_s) { h = (bar_s.y - m)/2 - wall; translate([(wall + m)/2, h, -5]) cylinderz(50, m); } tie_w = 3; tie_wall = wall + 1; module tie_holes(bar_s) { w = tie_w; translate([(bar_s.x - 22)/2, 0, 0]) for (y = [tie_wall, bar_s.y - tie_wall - w]) { hull() { for (x = [0, 22]) { translate([x, y, -1]) cylinderz(50, w); } } } } module bar(bar_s) { difference() { union() { main_bar(bar_s); bottom_ledge(bar_s); translate([(bar_s.x - din_w - wall)/2, 0, bar_s.z]) { bottom_clip(bar_s); translate([din_w + wall + 0.5, 0, 0]) top_clip(bar_s); } } bottom_ledge_holes(bar_s); tie_holes(bar_s); } } module fillet(d) { difference() { cube([d, d, wall]); translate([0, 0, -1]) cylinderz(50, d*2); } } joiner_l = 10; // Joins two bars. module joiner(w) { cube([joiner_l, w, wall]); translate([joiner_l, 0, 0]) fillet(3); translate([0, 0, 0]) mirror([1, 0, 0]) fillet(3); translate([0, w, 0]) mirror([1, 1, 0]) fillet(3); translate([joiner_l, w, 0]) mirror([0, 1, 0]) fillet(3); } module assembly(w=50) { max_w = 20; if (w >= max_w*2) { bar_s = [60+10, max_w, wall]; bar(bar_s); translate([0, w - bar_s.y, 0]) bar(bar_s); for (x = [bar_s.x*1/4, bar_s.x*3/4]) { translate([x - joiner_l/2, bar_s.y, 0]) joiner(w - bar_s.y*2); } } else { bar_s = [60+10, w, wall]; bar(bar_s); } } tplink_mc220l_s = [94, 73, 27]; edimax_es550g_s = [98, 71, 25.5]; // Note: filleted edges nanopi_r5c_s = [62.5, 62.5, 29]; u_poe_af_s = [86, 46, 33]; tie_offset = tie_wall * 2 + tie_w; //assembly(tplink_mc220l_s.y + tie_offset); //assembly(edimax_es550g_s.x + tie_offset - 6); //assembly(nanopi_r5c_s.z + tie_offset); //assembly(nanopi_r5c_s.x + tie_offset); assembly(u_poe_af_s.y + tie_offset);