include use module side(capped_bottom=true, reinforce=true) { W = hdd_length - hdd_standout; O = capped_bottom ? 4 : hrail_height; H = num_hdd_y * (hrail_height + hdd_height) + O; D = vrail_width / 2; S = 10; offset = 4; // frame side_frame(W, D, H, S, capped_bottom, reinforce); // support render() intersection() { translate([0, 0, H/2 - hrail_height/2]) ccube([W - 2*S, D, H - 2*S]); union() { assign(angle = 40) for (i = [-1:num_hdd_y+1]) for (j = [-1,1]) translate([9, 0, i*(hrail_height + hdd_height) + j*hdd_height/2 - offset]) rotate([0, j*angle, 0]) line(); for (i = [0:num_hdd_y-1]) for (j = [-1, 1]) translate([0, 0, (i+0.5)*(hrail_height + hdd_height) + j*hdd_height/2 - offset]) line(); } } } module side_frame(W, D, H, S, capped_bottom, reinforce) { render() difference() { union() { // outer hull translate([0, 0, H/2]) ccube([W, D, H]); // extend hull where holes for side joins puncture it intersection() { translate([0, 0, H/2]) ccube([large, D, H]); minkowski() { joins(W, D); scale([1, 1, 2]) rotate([0, 45, 0]) ccube(2); }}} ccube([W-2*S, large, large]); // space for support bar for (i = [(capped_bottom ? 1 : 0):num_hdd_y]) for (j = [-1,1]) translate([j*(W/2 - support_bar_width/2 - front_depth/4), 0, i*tray_height - support_bar_width/2 + 1.5]) ccube([support_bar_width, 2*D, support_bar_width]); // space for side joins joins(W, D); } // reinforce first and last horizontal support if (reinforce) for (i = [0,1]) translate([0, 0, i ? (num_hdd_y * tray_height - hrail_height) : S/2]) ccube([W-2*S, D, S]); } module joins(W, D) for (i = [0:num_hdd_y]) for (j = [-1,1]) for (k = [-1,1]) translate([j*(W/2 - 3.74), 0, i*tray_height - 3.5]) rotate(j*90) connector_pos(D, j, k, 0); module line() cube([large, 10, 0.8], center=true); side();