| @@ -0,0 +1 @@ | |||
| This thing was created by Thingiverse user russross, and is licensed under cc-nc. | |||
| @@ -0,0 +1 @@ | |||
| Raspberry Pi 4 2U rack-mount bracket by russross on Thingiverse: https://www.thingiverse.com/thing:4078710 | |||
| @@ -0,0 +1,221 @@ | |||
| /* [Bolt holes in the corners] */ | |||
| // Pick the size of the long threaded rods that run through | |||
| // the corners and hold everything together. | |||
| // | |||
| // These are the sizes that are commonly available at | |||
| // Home Depot or Lowes: | |||
| // | |||
| // 1/4 inch: 3.175 | |||
| // #12 : 2.778125 | |||
| // #10 : 2.38125 (default and recommended) | |||
| // | |||
| // Note: you should pick the same size and fudge factor | |||
| // for the frame parts. | |||
| bolt_size = 2.38125; | |||
| // Make the bolt holes this much bigger than the size of the bolt | |||
| // to give a more comfortable fit | |||
| bolt_hole_fudge = 0.2; // [0:0.25:1] | |||
| /* [Notches for attaching to the frame parts] */ | |||
| // You can optionally omit the notches for one ear that will | |||
| // join with a frame on the side that has no tabs. | |||
| // For the the other you should leave this at its default of true. | |||
| notches_enabled = true; | |||
| // Make the slot this much taller than the tabs | |||
| // to give a more comfortable fit. | |||
| notch_fudge = 0.3; // [0:0.25:1] | |||
| /* [Bolt holes for mounting to the rack] */ | |||
| // The size of the bolt holes for mounting to the server rack. | |||
| // The default is for M6 bolts. | |||
| ear_bolt_size = 3; | |||
| // Make the ear bolt holes this much longer than they are wide | |||
| // in case the entire assembled rack is not precisely the right | |||
| // length. | |||
| ear_bolt_stretch = 3; | |||
| /* [Hidden] */ | |||
| width = 82; | |||
| length = 90; | |||
| height = 5; | |||
| frame_width = 15.875; | |||
| distance_to_frame = 10; | |||
| distance_between_bolt_holes = 15.875 * 2 + 12.7; | |||
| ear_height = distance_to_frame + frame_width; | |||
| notch_height = 2; | |||
| outer_wall_thickness = 12; | |||
| inner_wall_thickness = 7; | |||
| back_wall_thickness = 5; | |||
| wall_diff = outer_wall_thickness - inner_wall_thickness; | |||
| floor_depth = 3; | |||
| tray_depth = 5; | |||
| tray_slot_depth = 2.5; | |||
| spacer_depth = 3; | |||
| epsilon = 0.001; | |||
| sd_window_width = 40; | |||
| sd_window_height = height - (tray_depth + floor_depth)*2; | |||
| near_pillar_width = 15; | |||
| far_pillar_width = 10; | |||
| floor_window_width = sd_window_width; | |||
| floor_window_border = (width - floor_window_width - outer_wall_thickness*2) / 2; | |||
| floor_window_length = length - back_wall_thickness - floor_window_border*2; | |||
| port_window_width = length - near_pillar_width - far_pillar_width; | |||
| port_window_frame_height = floor_depth + tray_depth + spacer_depth - notch_height; | |||
| bolt_radius = bolt_size + bolt_hole_fudge; | |||
| ear_bolt_radius = ear_bolt_size + bolt_hole_fudge; | |||
| floor_mini_window_width = (floor_window_width - floor_window_border) / 2; | |||
| floor_mini_window_length = (floor_window_length - floor_window_border) / 2; | |||
| difference() { | |||
| union() { | |||
| // the main tray block | |||
| translate([0, -epsilon, 0]) { | |||
| cube([width, length + epsilon, height]); | |||
| } | |||
| // the ear | |||
| translate([0, -height, 0]) { | |||
| cube([width, height, ear_height]); | |||
| } | |||
| // reinforce the joint | |||
| translate([0, 0, 0]) { | |||
| rotate([45, 0, 0]) { | |||
| cube([width, height-0.5, height-0.5]); | |||
| } | |||
| } | |||
| translate([ (width - distance_between_bolt_holes)/2 - ear_bolt_radius, 0, 0]) { | |||
| rotate([45, 0, 0]) { | |||
| cube([distance_between_bolt_holes + 2*ear_bolt_radius, height+1, height+1]); | |||
| } | |||
| } | |||
| } | |||
| // cut the bolt holes | |||
| for (a=[[outer_wall_thickness/2, near_pillar_width/2], | |||
| [outer_wall_thickness/2, length - far_pillar_width/2], | |||
| [width - outer_wall_thickness/2, near_pillar_width/2], | |||
| [width - outer_wall_thickness/2, length - far_pillar_width/2]]) { | |||
| translate([a[0], a[1], -epsilon]) { | |||
| cylinder( h=height + 2*epsilon, | |||
| r=bolt_radius, | |||
| center=false, | |||
| $fn=360); | |||
| } | |||
| } | |||
| // make the sides thinner | |||
| polyhedron( | |||
| points = [ | |||
| [ wall_diff, length-far_pillar_width-wall_diff, height+notch_height+epsilon], | |||
| [ wall_diff, near_pillar_width+wall_diff, height+notch_height+epsilon], | |||
| [ wall_diff, length-far_pillar_width-wall_diff, -epsilon], | |||
| [ wall_diff, near_pillar_width+wall_diff, -epsilon], | |||
| [-wall_diff, length-far_pillar_width+wall_diff, height+notch_height+epsilon], | |||
| [-wall_diff, near_pillar_width-wall_diff, height+notch_height+epsilon], | |||
| [-wall_diff, length-far_pillar_width+wall_diff, -epsilon], | |||
| [-wall_diff, near_pillar_width-wall_diff, -epsilon] | |||
| ], | |||
| faces = [ | |||
| [1,0,2,3], | |||
| [4,5,7,6], | |||
| [0,4,6,2], | |||
| [6,7,3,2], | |||
| [7,5,1,3], | |||
| [5,4,0,1] | |||
| ], | |||
| convexity = 10); | |||
| polyhedron( | |||
| points = [ | |||
| [width-wall_diff, near_pillar_width+wall_diff, height+notch_height+epsilon], | |||
| [width-wall_diff, length-far_pillar_width-wall_diff, height+notch_height+epsilon], | |||
| [width-wall_diff, near_pillar_width+wall_diff, -epsilon], | |||
| [width-wall_diff, length-far_pillar_width-wall_diff, -epsilon], | |||
| [width+wall_diff, near_pillar_width-wall_diff, height+notch_height+epsilon], | |||
| [width+wall_diff, length-far_pillar_width+wall_diff, height+notch_height+epsilon], | |||
| [width+wall_diff, near_pillar_width-wall_diff, -epsilon], | |||
| [width+wall_diff, length-far_pillar_width+wall_diff, -epsilon] | |||
| ], | |||
| faces = [ | |||
| [1,0,2,3], | |||
| [4,5,7,6], | |||
| [0,4,6,2], | |||
| [6,7,3,2], | |||
| [7,5,1,3], | |||
| [5,4,0,1] | |||
| ], | |||
| convexity = 10); | |||
| if (notches_enabled) { | |||
| // cut the notches | |||
| translate([ wall_diff - epsilon, | |||
| near_pillar_width + wall_diff, | |||
| -epsilon]) { | |||
| cube([ inner_wall_thickness-2 + epsilon, | |||
| length - near_pillar_width - far_pillar_width - 2*wall_diff, | |||
| notch_height + notch_fudge + epsilon]); | |||
| } | |||
| translate([ width - wall_diff - (inner_wall_thickness-2), | |||
| near_pillar_width + wall_diff, | |||
| -epsilon]) { | |||
| cube([ inner_wall_thickness-2 + epsilon, | |||
| length - near_pillar_width - far_pillar_width - 2*wall_diff, | |||
| notch_height + notch_fudge + epsilon]); | |||
| } | |||
| } | |||
| // cut some mini windows in the floor | |||
| for (a=[[outer_wall_thickness + floor_window_border, | |||
| floor_window_border], | |||
| [width - outer_wall_thickness - floor_window_border - floor_mini_window_width, | |||
| floor_window_border], | |||
| [outer_wall_thickness + floor_window_border, | |||
| 2*floor_window_border + floor_mini_window_length], | |||
| [width - outer_wall_thickness - floor_window_border - floor_mini_window_width, | |||
| 2*floor_window_border + floor_mini_window_length]]) { | |||
| translate([a[0], a[1], -epsilon]) { | |||
| cube([ floor_mini_window_width, | |||
| floor_mini_window_length, | |||
| height + 2*epsilon]); | |||
| } | |||
| } | |||
| // cut the bolt holes on the ear | |||
| for (a=[ width/2 - distance_between_bolt_holes/2, | |||
| width/2 + distance_between_bolt_holes/2]) { | |||
| for (b=[-ear_bolt_stretch/2, ear_bolt_stretch/2]) { | |||
| translate([ a, | |||
| -height-epsilon, | |||
| ear_height - frame_width/2 + b]) { | |||
| rotate([-90,0,0]) { | |||
| cylinder( h=height + 2*epsilon, | |||
| r=ear_bolt_radius, | |||
| center=false, | |||
| $fn=360); | |||
| } | |||
| } | |||
| } | |||
| translate([ a - ear_bolt_radius, | |||
| -height-epsilon, | |||
| ear_height - frame_width/2 - ear_bolt_stretch/2]) { | |||
| cube([ ear_bolt_radius*2, | |||
| height + 2*epsilon, | |||
| ear_bolt_stretch]); | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,255 @@ | |||
| /* [Bolt holes in the corners] */ | |||
| // Pick the size of the long threaded rods that run through | |||
| // the corners and hold everything together. | |||
| // | |||
| // These are the sizes that are commonly available at | |||
| // Home Depot or Lowes: | |||
| // | |||
| // 1/4 inch: 3.175 | |||
| // #12 : 2.778125 | |||
| // #10 : 2.38125 (default and recommended) | |||
| // | |||
| // Note: you should pick the same size and fudge factor | |||
| // for the ear parts. | |||
| bolt_size = 2.38125; | |||
| // Make the bolt holes this much bigger than the size of the bolt | |||
| // to give a more comfortable fit | |||
| bolt_hole_fudge = 0.2; // [0:0.25:1] | |||
| /* [Notches and tabs for stacking] */ | |||
| // You can optionally omit the notches for the frame on the end | |||
| // that joins with an ear with no tabs. For all of the others | |||
| // you should leave this at its default of true. | |||
| notches_enabled = true; | |||
| // Make the slot this much taller than the tabs | |||
| // to give a more comfortable fit. | |||
| notch_fudge = 0.3; // [0:0.25:1] | |||
| /* [Size] */ | |||
| // The default is to fit 12 units with PoE hats in a standard rack. | |||
| // 12 is a good fit, and it works nicely with many PoE switches, which | |||
| // often come with 12 or 24 ports. You can bump it up to 13 units and | |||
| // they will still fit nicely with PoE hats, or you can go up to 14 | |||
| // of you are not using the hats. | |||
| number_to_fit = 12; // [12:Relaxed fit, 13:Using PoE, 14:Without PoE hats] | |||
| /* [Hidden] */ | |||
| // make the screw holes this much bigger than the | |||
| // actual screw for a more comfortable fit | |||
| // (a bigger number here will make the screws fit looser) | |||
| screw_hole_fudge = 0.15; | |||
| height = (450.85 - 20) / number_to_fit; | |||
| width = 82; | |||
| length = 90; | |||
| // The height of the notches and tabs | |||
| notch_height = 2; | |||
| // epsilon is used to slightly overlap pieces to help the previewer | |||
| epsilon = 0.001; | |||
| bolt_radius = bolt_size + bolt_hole_fudge; | |||
| outer_wall_thickness = 12; | |||
| inner_wall_thickness = 7; | |||
| back_wall_thickness = 5; | |||
| wall_diff = outer_wall_thickness - inner_wall_thickness; | |||
| floor_depth = 3; | |||
| tray_depth = 5; | |||
| tray_slot_depth = 2.5; | |||
| spacer_depth = 3; | |||
| sd_window_width = 40; | |||
| sd_window_height = height - (tray_depth + floor_depth)*2; | |||
| near_pillar_width = 15; | |||
| far_pillar_width = 10; | |||
| floor_window_width = sd_window_width; | |||
| floor_window_border = (width - floor_window_width - outer_wall_thickness*2) / 2; | |||
| floor_window_length = length - back_wall_thickness - floor_window_border*2; | |||
| port_window_width = length - near_pillar_width - far_pillar_width; | |||
| port_window_frame_height = floor_depth + tray_depth + spacer_depth - notch_height; | |||
| difference() { | |||
| union() { | |||
| // the main block | |||
| cube([width, length, height]); | |||
| // the tabs | |||
| translate([ wall_diff, | |||
| near_pillar_width + wall_diff, | |||
| height - epsilon]) { | |||
| cube([ inner_wall_thickness - 2, | |||
| length - near_pillar_width - far_pillar_width - wall_diff*2, | |||
| notch_height + epsilon]); | |||
| } | |||
| translate([ width - outer_wall_thickness + 2, | |||
| near_pillar_width + wall_diff, | |||
| height - epsilon]) { | |||
| cube([ inner_wall_thickness - 2, | |||
| length - near_pillar_width - far_pillar_width - wall_diff*2, | |||
| notch_height + epsilon]); | |||
| } | |||
| } | |||
| // carve out the interior | |||
| translate([outer_wall_thickness, -epsilon, floor_depth]) { | |||
| cube( [width - outer_wall_thickness*2, | |||
| length - back_wall_thickness + epsilon, | |||
| height + notch_height - floor_depth + epsilon]); | |||
| } | |||
| // punch a hole for the sd card | |||
| translate([ (width - sd_window_width) / 2, | |||
| length - back_wall_thickness - epsilon, | |||
| tray_depth + floor_depth]) { | |||
| cube([ sd_window_width, | |||
| back_wall_thickness + 2*epsilon, | |||
| height - port_window_frame_height - tray_depth - floor_depth + notch_height]); | |||
| } | |||
| // punch a hole for side port access | |||
| translate([ -epsilon, | |||
| near_pillar_width, | |||
| port_window_frame_height + notch_height]) { | |||
| cube([ width + 2*epsilon, | |||
| port_window_width, | |||
| height - port_window_frame_height*2]); | |||
| } | |||
| // punch a hole in the bottom | |||
| translate([ outer_wall_thickness + floor_window_border, | |||
| floor_window_border, | |||
| -epsilon]) { | |||
| cube([ floor_window_width, | |||
| floor_window_length, | |||
| floor_depth + 2*epsilon]); | |||
| } | |||
| // open a groove that the speaker jack can slide through | |||
| translate([ outer_wall_thickness - 2, | |||
| -epsilon, | |||
| port_window_frame_height + notch_height]) { | |||
| cube([ 2 + epsilon, | |||
| near_pillar_width + 2*epsilon, | |||
| 8]); | |||
| } | |||
| // soften the leading edge a bit | |||
| translate([ outer_wall_thickness, | |||
| 0, | |||
| floor_depth-0.5]) { | |||
| rotate([25,0,0]) { | |||
| cube([ width - outer_wall_thickness*2, | |||
| 2, | |||
| 2]); | |||
| } | |||
| } | |||
| if (notches_enabled) { | |||
| // cut the notches in the bottom | |||
| translate([ -epsilon, | |||
| near_pillar_width + wall_diff, | |||
| -epsilon]) { | |||
| cube([ outer_wall_thickness - 2 + epsilon, | |||
| length - near_pillar_width - far_pillar_width - wall_diff*2, | |||
| notch_height + notch_fudge + epsilon]); | |||
| } | |||
| translate([ width - outer_wall_thickness + 2, | |||
| near_pillar_width + wall_diff, | |||
| -epsilon]) { | |||
| cube([ outer_wall_thickness - 2 + epsilon, | |||
| length - near_pillar_width - far_pillar_width - wall_diff*2, | |||
| notch_height + notch_fudge + epsilon]); | |||
| } | |||
| } | |||
| // cut out the sides to make them thinner | |||
| polyhedron( | |||
| points = [ | |||
| [ wall_diff, length-far_pillar_width-wall_diff, height+notch_height+epsilon], | |||
| [ wall_diff, near_pillar_width+wall_diff, height+notch_height+epsilon], | |||
| [ wall_diff, length-far_pillar_width-wall_diff, -epsilon], | |||
| [ wall_diff, near_pillar_width+wall_diff, -epsilon], | |||
| [-wall_diff, length-far_pillar_width+wall_diff, height+notch_height+epsilon], | |||
| [-wall_diff, near_pillar_width-wall_diff, height+notch_height+epsilon], | |||
| [-wall_diff, length-far_pillar_width+wall_diff, -epsilon], | |||
| [-wall_diff, near_pillar_width-wall_diff, -epsilon] | |||
| ], | |||
| faces = [ | |||
| [1,0,2,3], | |||
| [4,5,7,6], | |||
| [0,4,6,2], | |||
| [6,7,3,2], | |||
| [7,5,1,3], | |||
| [5,4,0,1] | |||
| ], | |||
| convexity = 10); | |||
| polyhedron( | |||
| points = [ | |||
| [width-wall_diff, near_pillar_width+wall_diff, height+notch_height+epsilon], | |||
| [width-wall_diff, length-far_pillar_width-wall_diff, height+notch_height+epsilon], | |||
| [width-wall_diff, near_pillar_width+wall_diff, -epsilon], | |||
| [width-wall_diff, length-far_pillar_width-wall_diff, -epsilon], | |||
| [width+wall_diff, near_pillar_width-wall_diff, height+notch_height+epsilon], | |||
| [width+wall_diff, length-far_pillar_width+wall_diff, height+notch_height+epsilon], | |||
| [width+wall_diff, near_pillar_width-wall_diff, -epsilon], | |||
| [width+wall_diff, length-far_pillar_width+wall_diff, -epsilon] | |||
| ], | |||
| faces = [ | |||
| [1,0,2,3], | |||
| [4,5,7,6], | |||
| [0,4,6,2], | |||
| [6,7,3,2], | |||
| [7,5,1,3], | |||
| [5,4,0,1] | |||
| ], | |||
| convexity = 10); | |||
| // drill the bolt holes | |||
| for (a=[[outer_wall_thickness/2, near_pillar_width/2], | |||
| [outer_wall_thickness/2, length - far_pillar_width/2], | |||
| [width - outer_wall_thickness/2, near_pillar_width/2], | |||
| [width - outer_wall_thickness/2, length - far_pillar_width/2]]) { | |||
| translate([a[0], a[1], -epsilon]) { | |||
| cylinder( h=height + notch_height + 2*epsilon, | |||
| r=bolt_radius, | |||
| center=false, | |||
| $fn=360); | |||
| } | |||
| } | |||
| // cut the tray insert slots | |||
| // note: the tray will be slightly narrower to | |||
| // give a more comfortable fit. If it is too loose or too tight, | |||
| // adjust the tray. | |||
| for (a=[ outer_wall_thickness, | |||
| width - outer_wall_thickness]) { | |||
| translate([ a, | |||
| -epsilon, | |||
| floor_depth + tray_depth/2]) { | |||
| intersection() { | |||
| rotate([0, 45, 0]) { | |||
| translate([-tray_depth/sqrt(2)/2, 0, -tray_depth/sqrt(2)/2]) { | |||
| cube([ tray_depth/sqrt(2), | |||
| length - back_wall_thickness + epsilon, | |||
| tray_depth/sqrt(2)]); | |||
| } | |||
| } | |||
| translate([-tray_depth/2+0.5, 0, -tray_depth/2]) { | |||
| cube([ tray_depth-1, | |||
| length - back_wall_thickness + epsilon, | |||
| tray_depth]); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,196 @@ | |||
| /* [Screw holes for attaching the Raspberry Pi 4] */ | |||
| // Make the screw holes this much bigger than the | |||
| // actual screw for a more comfortable fit | |||
| // (a bigger number here will make the screws fit looser) | |||
| screw_hole_fudge = 0.15; // [0:0.05:0.5] | |||
| /* [Tray width] */ | |||
| // Make the tray this much narrower on each side | |||
| // for a more comfortable fit in the frame | |||
| // (a bigger number here will make the fit looser) | |||
| tray_insert_fudge = 0.25; // [0:0.05:0.75] | |||
| /* [Hidden] */ | |||
| tray_width = 58; | |||
| tray_length = 85; | |||
| tray_depth = 5; | |||
| tray_lip_overhang = 10; | |||
| inner_wall_thickness = 5; | |||
| spacer_depth = 3; | |||
| spacer_outer_radius = 3; | |||
| screw_radius = 1.25 + screw_hole_fudge; | |||
| screw_head_radius = 3; | |||
| screw_head_depth = 2; | |||
| pcb_depth = 2; | |||
| spacer_center_width = 49; | |||
| spacer_center_length = 58; | |||
| spacer_from_edge = (tray_width - spacer_center_width) / 2; | |||
| sd_window_width = 40; | |||
| floor_window_width = sd_window_width; | |||
| floor_window_border = (tray_width - floor_window_width) / 2; | |||
| floor_window_length = tray_length - floor_window_border*2 - inner_wall_thickness; | |||
| epsilon = 0.001; | |||
| difference() { | |||
| union() { | |||
| // the main tray | |||
| intersection() { | |||
| union() { | |||
| translate([tray_insert_fudge, 0, 0]) { | |||
| cube([ tray_width - 2*tray_insert_fudge, | |||
| tray_length + tray_lip_overhang, | |||
| tray_depth]); | |||
| } | |||
| difference() { | |||
| // the outer part of the curved handle | |||
| translate([ tray_width/2, | |||
| -tray_length*0.5 + 7.5, | |||
| 0]) { | |||
| cylinder( | |||
| h=tray_depth + spacer_depth + pcb_depth, | |||
| r=tray_length*1.5, | |||
| center=false, | |||
| $fn=360); | |||
| } | |||
| // cut away the inside to make it a shell | |||
| translate([ tray_width/2, | |||
| -tray_length*0.5 + 5.4, | |||
| -epsilon]) { | |||
| cylinder( | |||
| h=tray_depth + spacer_depth + pcb_depth + 2*epsilon, | |||
| r=tray_length*1.5, | |||
| center=false, | |||
| $fn=360); | |||
| } | |||
| translate([ tray_width, | |||
| -tray_length, | |||
| -epsilon]) { | |||
| cube([ 2*tray_width, | |||
| 3*tray_length, | |||
| tray_depth + spacer_depth + pcb_depth + 2*epsilon]); | |||
| } | |||
| translate([ -2*tray_width, | |||
| -tray_length, | |||
| -epsilon]) { | |||
| cube([ 2*tray_width, | |||
| 3*tray_length, | |||
| tray_depth + spacer_depth + pcb_depth + 2*epsilon]); | |||
| } | |||
| } | |||
| // reinforce the curved handle | |||
| translate([epsilon, tray_length, tray_depth]) { | |||
| rotate([-75, 0, 0]) { | |||
| cube([tray_width - 2*epsilon, 2*sqrt(2), 6]); | |||
| } | |||
| } | |||
| } | |||
| // cut away the ears of the tray | |||
| // where they jut through the curved handle | |||
| translate([ tray_width/2, | |||
| -tray_length*0.5 + 7.5, | |||
| 0]) { | |||
| cylinder( | |||
| h=tray_depth + spacer_depth + pcb_depth, | |||
| r=tray_length*1.5, | |||
| center=false, | |||
| $fn=360); | |||
| } | |||
| } | |||
| // place the 4 spacers | |||
| for (a=[ [spacer_from_edge, | |||
| spacer_from_edge], | |||
| [spacer_from_edge + spacer_center_width, | |||
| spacer_from_edge], | |||
| [spacer_from_edge, | |||
| spacer_from_edge + spacer_center_length], | |||
| [spacer_from_edge + spacer_center_width, | |||
| spacer_from_edge + spacer_center_length]]) { | |||
| translate([a[0], a[1], tray_depth-epsilon]) { | |||
| // place the spacer | |||
| cylinder( | |||
| h=spacer_depth + epsilon, | |||
| r=spacer_outer_radius, | |||
| center=false, | |||
| $fn=360); | |||
| // place a small cone around it | |||
| cylinder( | |||
| h=2 + epsilon, | |||
| r1=spacer_outer_radius + 1, | |||
| r2=spacer_outer_radius, | |||
| center=false, | |||
| $fn=360); | |||
| } | |||
| } | |||
| // the tray insert edge tabs | |||
| for (a=[ tray_insert_fudge, | |||
| tray_width - tray_insert_fudge]) { | |||
| translate([ a, | |||
| 0, | |||
| tray_depth/2]) { | |||
| intersection() { | |||
| rotate([0, 45, 0]) { | |||
| translate([-tray_depth/sqrt(2)/2, 0, -tray_depth/sqrt(2)/2]) { | |||
| cube([ tray_depth/sqrt(2), | |||
| tray_length, | |||
| tray_depth/sqrt(2)]); | |||
| } | |||
| } | |||
| translate([-tray_depth/2+0.5, 0, -tray_depth/2]) { | |||
| cube([ tray_depth-1, | |||
| tray_length, | |||
| tray_depth]); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| // punch a hole in the bottom | |||
| translate([ floor_window_border, | |||
| floor_window_border, | |||
| -epsilon]) { | |||
| cube([ floor_window_width, | |||
| floor_window_length, | |||
| tray_depth + 2*epsilon]); | |||
| } | |||
| // drill the 4 screw holes | |||
| for (a=[ [spacer_from_edge, | |||
| spacer_from_edge], | |||
| [spacer_from_edge + spacer_center_width, | |||
| spacer_from_edge], | |||
| [spacer_from_edge, | |||
| spacer_from_edge + spacer_center_length], | |||
| [spacer_from_edge + spacer_center_width, | |||
| spacer_from_edge + spacer_center_length]]) { | |||
| translate([a[0], a[1], -epsilon]) { | |||
| // drill the main screw hole | |||
| cylinder( | |||
| h=tray_depth + spacer_depth + 2*epsilon, | |||
| r=screw_radius, | |||
| center=false, | |||
| $fn=360); | |||
| // drill a recessed hole for the screw head | |||
| cylinder( | |||
| h=screw_head_depth + epsilon, | |||
| r=screw_head_radius, | |||
| center=false, | |||
| $fn=360); | |||
| } | |||
| } | |||
| } | |||