From 4a106406fbeebe9a0cb902f168da81f021206750 Mon Sep 17 00:00:00 2001 From: StanDaMan <0310njs@gmail.com> Date: Fri, 3 Jul 2026 12:11:19 -0400 Subject: [PATCH 1/7] Keystone Update 10InchRackGenerator.scad - Add feature to allow user to remove or add the left and right keystones independently. --- 10InchRackGenerator.scad | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/10InchRackGenerator.scad b/10InchRackGenerator.scad index f0bee05..fea4cf6 100644 --- a/10InchRackGenerator.scad +++ b/10InchRackGenerator.scad @@ -10,7 +10,10 @@ component_height = 28.30; // ======================================== /* [Keystones] */ // Add keystone jacks to the front panel -keystones = false; // [true: Place keystone jacks, false: Remove keystone jacks] +keystones = false; +keystone_left = true; +keystone_right = true; +// [true: Place keystone jacks, false: Remove keystone jacks] // ======================================== /* [Holes] */ @@ -128,8 +131,11 @@ module switch_mount(switch_width, switch_height, switch_depth) { lip_thickness = 1.2; lip_depth = 0.60; // Main cutout minus lip (centered) + + // add offset + translate([ - (rack_width - (cutout_w - 2*lip_thickness)) / 2, + (rack_width - (cutout_w - 2*lip_thickness )) / 2, (height - (cutout_h - 2*lip_thickness)) / 2, -tolerance ]) { @@ -462,17 +468,28 @@ module switch_mount(switch_width, switch_height, switch_depth) { if (air_holes) { air_holes(); } + if (keystones) { - keystone_front_cutout(); - translate([rack_width, 0, 0]) mirror([1, 0, 0]) keystone_front_cutout(); + if (keystone_left) { + keystone_front_cutout(); + } + if (keystone_right){ + translate([rack_width, 0, 0]) mirror([1, 0, 0]) + keystone_front_cutout(); + } } } } - if (keystones) { - // rotate([90,0,0]) maps keystone Y→rack Z (depth), keystone Z→rack -Y (compensated by +keystone_outer_height in translate) + if (keystones) { + //rotate([90,0,0]) maps keystone Y→rack Z (depth), keystone Z→rack -Y (compensated by +keystone_outer_height in translate) + if (keystone_left){ translate([keystone_tx, keystone_ty + keystone_outer_height, 0]) rotate([90,0,0]) keystone(); + } + + if (keystone_right){ translate([rack_width, 0, 0]) mirror([1, 0, 0]) - translate([keystone_tx, keystone_ty + keystone_outer_height, 0]) rotate([90,0,0]) keystone(); + translate([keystone_tx, keystone_ty + keystone_outer_height, 0]) rotate([90,0,0]) keystone(); + } } } } From d89cf6f801e7d213a1f0d3bebe078b515f84359f Mon Sep 17 00:00:00 2001 From: StanDaMan <0310njs@gmail.com> Date: Fri, 3 Jul 2026 12:25:55 -0400 Subject: [PATCH 2/7] Update 10InchRackGenerator.scad Add comments and dclean up code to new feature. --- 10InchRackGenerator.scad | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/10InchRackGenerator.scad b/10InchRackGenerator.scad index fea4cf6..03745a2 100644 --- a/10InchRackGenerator.scad +++ b/10InchRackGenerator.scad @@ -10,10 +10,9 @@ component_height = 28.30; // ======================================== /* [Keystones] */ // Add keystone jacks to the front panel -keystones = false; -keystone_left = true; -keystone_right = true; -// [true: Place keystone jacks, false: Remove keystone jacks] +keystones = false; // [true: Place keystone jacks, false: Remove keystone jacks] +keystone_left = true; // [true: Place keystone jack on the left, false: Remove left keystone jack] +keystone_right = true; // [true: Place keystone jack on the right, false: Remove right keystone jacks] // ======================================== /* [Holes] */ @@ -135,7 +134,7 @@ module switch_mount(switch_width, switch_height, switch_depth) { // add offset translate([ - (rack_width - (cutout_w - 2*lip_thickness )) / 2, + (rack_width - (cutout_w - 2*lip_thickness)) / 2, (height - (cutout_h - 2*lip_thickness)) / 2, -tolerance ]) { @@ -470,10 +469,10 @@ module switch_mount(switch_width, switch_height, switch_depth) { } if (keystones) { - if (keystone_left) { + if (keystone_left) { //Cutout for left Keystone keystone_front_cutout(); } - if (keystone_right){ + if (keystone_right){ //Cutout for Right Keystone translate([rack_width, 0, 0]) mirror([1, 0, 0]) keystone_front_cutout(); } @@ -482,11 +481,10 @@ module switch_mount(switch_width, switch_height, switch_depth) { } if (keystones) { //rotate([90,0,0]) maps keystone Y→rack Z (depth), keystone Z→rack -Y (compensated by +keystone_outer_height in translate) - if (keystone_left){ + if (keystone_left){ //Make left Keystone translate([keystone_tx, keystone_ty + keystone_outer_height, 0]) rotate([90,0,0]) keystone(); } - - if (keystone_right){ + if (keystone_right){ //Make right Keystone translate([rack_width, 0, 0]) mirror([1, 0, 0]) translate([keystone_tx, keystone_ty + keystone_outer_height, 0]) rotate([90,0,0]) keystone(); } From 34e16b3e05ab8eb0695c60f7f10b7bbf21ee31c0 Mon Sep 17 00:00:00 2001 From: StanDaMan <0310njs@gmail.com> Date: Fri, 3 Jul 2026 19:11:18 -0400 Subject: [PATCH 3/7] Component Offset added 10InchRackGenerator.scad Add component_offset varible allowing user to move the component cutout left or right. --- 10InchRackGenerator.scad | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/10InchRackGenerator.scad b/10InchRackGenerator.scad index 03745a2..b365ff0 100644 --- a/10InchRackGenerator.scad +++ b/10InchRackGenerator.scad @@ -2,10 +2,10 @@ rack_width = 254.0; // [ 254.0:10 inch, 152.4:6 inch] // Height of the rack in U units, can be a fraction for partial U (e.g. 1.5 for 1U plus half of the next U) rack_height = 1.0; // [0.5:0.5:5] - component_width = 110.0; component_depth = 122.0; component_height = 28.30; +component_offset = 0; // [-100:0.1:100] // ======================================== /* [Keystones] */ @@ -110,7 +110,7 @@ module switch_mount(switch_width, switch_height, switch_depth) { // Create the main body as a separate module module main_body() { - side_margin = (rack_width - chassis_width) / 2; + side_margin = ((rack_width - chassis_width) / 2) + component_offset; chassis_height = min(switch_height + (2 * case_thickness), height); union() { // Front panel @@ -130,11 +130,8 @@ module switch_mount(switch_width, switch_height, switch_depth) { lip_thickness = 1.2; lip_depth = 0.60; // Main cutout minus lip (centered) - - // add offset - translate([ - (rack_width - (cutout_w - 2*lip_thickness)) / 2, + ((rack_width - (cutout_w - 2*lip_thickness)) / 2) + component_offset, (height - (cutout_h - 2*lip_thickness)) / 2, -tolerance ]) { @@ -142,7 +139,7 @@ module switch_mount(switch_width, switch_height, switch_depth) { } // Switch cutout above the lip (centered) translate([ - (rack_width - cutout_w) / 2, + ((rack_width - cutout_w) / 2) + component_offset, (height - cutout_h) / 2, lip_depth ]) { @@ -153,7 +150,7 @@ module switch_mount(switch_width, switch_height, switch_depth) { z_start = front_plate_hole ? -tolerance : front_plate_thickness; z_depth = front_plate_hole ? chassis_depth_main + 2*tolerance : chassis_depth_main - front_plate_thickness + tolerance; translate([ - (rack_width - cutout_w) / 2, + ((rack_width - cutout_w) / 2) + component_offset, (height - cutout_h) / 2, z_start ]) { @@ -210,8 +207,8 @@ module switch_mount(switch_width, switch_height, switch_depth) { // Power wire cutouts: configurable diameter holes at top and bottom rack hole positions module power_wire_cutouts() { hole_spacing_x = switch_width; // match rack holes - hole_left_x = (rack_width - hole_spacing_x) / 2 - (wire_diameter /5); - hole_right_x = (rack_width + hole_spacing_x) / 2 + (wire_diameter /5); + hole_left_x = (rack_width - hole_spacing_x) / 2 - (wire_diameter /5) + component_offset; + hole_right_x = (rack_width + hole_spacing_x) / 2 + (wire_diameter /5) + component_offset; // Midplane of switch opening mid_y = (height - switch_height) / 2 + switch_height / 2; for (side_x = [hole_left_x, hole_right_x]) { @@ -228,14 +225,14 @@ module switch_mount(switch_width, switch_height, switch_depth) { // Zip tie holes zip_z = switch_depth + solid_z_offset; for (i = [0:zip_tie_hole_count-1]) { - x_pos = (rack_width - switch_width)/2 + (switch_width/(zip_tie_hole_count+1)) * (i+1); + x_pos = (rack_width - switch_width)/2 + component_offset + (switch_width/(zip_tie_hole_count+1)) * (i+1); translate([x_pos, 0, zip_z]) { cube([zip_tie_hole_width, height, zip_tie_hole_length]); } } // Zip tie indents (top and bottom) - x_pos = (rack_width - switch_width)/2; + x_pos = ((rack_width - switch_width)/2) + component_offset; chassis_height = min(switch_height + (2 * case_thickness), height); // Bottom indent translate([x_pos, (height - chassis_height)/2, zip_z]) { @@ -273,7 +270,7 @@ module switch_mount(switch_width, switch_height, switch_depth) { actual_grid_depth = (z_rows - 1) * spacing_z; // Center the grid within the switch cutout area - cutout_center_x = rack_width / 2; + cutout_center_x = (rack_width / 2) + component_offset; cutout_center_z = front_plate_thickness + switch_depth / 2; x_start = cutout_center_x - actual_grid_width / 2; From 18e25a4bb385a9d9447342ab38a884cbf7151fc8 Mon Sep 17 00:00:00 2001 From: StanDaMan <0310njs@gmail.com> Date: Fri, 3 Jul 2026 20:56:26 -0400 Subject: [PATCH 4/7] Add independent wire holes 10InchRackGenerator.scad - Add feature that lets user remove or add wire holes independently --- 10InchRackGenerator.scad | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/10InchRackGenerator.scad b/10InchRackGenerator.scad index b365ff0..9198a84 100644 --- a/10InchRackGenerator.scad +++ b/10InchRackGenerator.scad @@ -18,6 +18,8 @@ keystone_right = true; // [true: Place keystone jack on the right, false: Remove /* [Holes] */ // Adds small cutout a USB or Power cable could be routed through to the front front_wire_holes = false; // [true:Show front wire holes, false:Hide front wire holes] +front_wire_hole_left = true; // [true:Show left wire hole, false:Hide left wire hole] +front_wire_hole_right = true; // [true:Show right wire hole, false:Hide right wire hole] // Diameter of wire to route through front_wire_holes. wire_diameter = 7; // Diameter of power wire holes // Adds hexagon air cutouts to reduce material and improve cooling. @@ -206,20 +208,21 @@ module switch_mount(switch_width, switch_height, switch_depth) { // Power wire cutouts: configurable diameter holes at top and bottom rack hole positions module power_wire_cutouts() { + mid_y = (height - switch_height) / 2 + switch_height / 2; // Midplane of switch opening hole_spacing_x = switch_width; // match rack holes - hole_left_x = (rack_width - hole_spacing_x) / 2 - (wire_diameter /5) + component_offset; - hole_right_x = (rack_width + hole_spacing_x) / 2 + (wire_diameter /5) + component_offset; - // Midplane of switch opening - mid_y = (height - switch_height) / 2 + switch_height / 2; - for (side_x = [hole_left_x, hole_right_x]) { - translate([side_x, mid_y, 0]) { - linear_extrude(height = chassis_depth_main) { - circle(d=wire_diameter); - } + if (front_wire_hole_left){ //make left hole + hole_left_x = (rack_width - hole_spacing_x) / 2 - (wire_diameter /5) + component_offset; + translate([hole_left_x, mid_y, 0]) { + linear_extrude(height = chassis_depth_main) {circle(d=wire_diameter);} + } + } + if (front_wire_hole_right){ //make right hole + hole_right_x = (rack_width + hole_spacing_x) / 2 + (wire_diameter /5) + component_offset; + translate([hole_right_x, mid_y, 0]) { + linear_extrude(height = chassis_depth_main) {circle(d=wire_diameter);} } } } - // Create zip tie holes and indents module zip_tie_features() { // Zip tie holes From 78afeefbdf5ddc112e2078831a98237ea7dea003 Mon Sep 17 00:00:00 2001 From: StanDaMan <0310njs@gmail.com> Date: Sat, 4 Jul 2026 00:22:20 -0400 Subject: [PATCH 5/7] Correct Offset issue 10InchRackGenerator.scad Found bug with offset not moving airholes on the side of chassie with the rest of the model. bug has been corrected. --- 10InchRackGenerator.scad | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/10InchRackGenerator.scad b/10InchRackGenerator.scad index 9198a84..35e3038 100644 --- a/10InchRackGenerator.scad +++ b/10InchRackGenerator.scad @@ -257,7 +257,7 @@ module switch_mount(switch_width, switch_height, switch_depth) { // Chassis dimensions used by both hole sections chassis_height = min(switch_height + (2 * case_thickness), height); chassis_width = min(switch_width + (2 * case_thickness), (rack_width == 152.4) ? 120.65 : 221.5); - side_margin = (rack_width - chassis_width) / 2; + side_margin = ((rack_width - chassis_width) / 2) + component_offset; // TOP/BOTTOM FACE HOLES (Y-axis, penetrating top and bottom chassis walls) // Calculate available space for holes within switch dimensions From ae8ad753b9327de48f4014e2a1489bf94e0c3bb0 Mon Sep 17 00:00:00 2001 From: StanDaMan <0310njs@gmail.com> Date: Sun, 5 Jul 2026 18:29:19 -0400 Subject: [PATCH 6/7] coplanar face fixes KeystoneJack.scad - Use epsilon for coplanar face fixes --- KeystoneJack.scad | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/KeystoneJack.scad b/KeystoneJack.scad index aaa2617..f16c300 100644 --- a/KeystoneJack.scad +++ b/KeystoneJack.scad @@ -33,11 +33,11 @@ module keystone( // Make solid cube cube([jack_width+wall,jack_depth,jack_height+wall]); // Cut out the front hole - translate([(jack_width+wall-front_hole_width)/2,0,front_hole_z_offset]) + translate([(jack_width+wall-front_hole_width)/2,-e,front_hole_z_offset]) color("blue") cube([front_hole_width,jack_depth+wall,front_hole_height]); // Cut out the back hole. It should be extruded to front_large_catch_depth - translate([(jack_width+wall-front_hole_width)/2,front_large_catch_depth,back_hole_z_offset]) + translate([(jack_width+wall-front_hole_width)/2,front_large_catch_depth - e,back_hole_z_offset ]) color("red") cube([front_hole_width,jack_depth+wall-front_large_catch_depth,back_hole_height]); From b1341200681c12d099f75a3dc1bc74cc3a584d50 Mon Sep 17 00:00:00 2001 From: StanDaMan <0310njs@gmail.com> Date: Mon, 13 Jul 2026 22:58:53 -0400 Subject: [PATCH 7/7] Major Overhaul 10InchRackGenerator.scad Summary - optimized code to setup for future features.(moved Modules and Variable around, and Rearranged the structure for building the mount) - Added two more components that can be put side by side - used epsilon for coplanar face fixes making the preview cleaner looking - Used to reduce needed modules and lines of code. - optimized code to set up for future features(More restructuring as code is reduced using modules from walls.scad). - Made wire hole independent for each component and made it dropdown options - Overhauled the air_holes giving user more controls and turning hexes for better printing - Added independent y offset for each component Change Log (This log is in chronological order) - Module (Global) Switch_mount() renamed to component_mount() - Variable (Global) component_width renamed to component1_width - Variable (Global) component_depth renamed to component1_depth - Variable (Global) component_height renamed to component1_height - Variable (Global) component_offset renamed to component1_offset - Variable (Global) component2_width added - Variable (Global) component2_depth added - Variable (Global) component2_height added - Variable (Global) component2_offset added - Variable (Global) component1 added - Variable (Global) component2 added - Variable (Local) (component_mount()) switch_width renamed to component_width - Variable (Local) (component_mount()) switch_height renamed to component_height - Variable (Local) (component_mount()) switch_depth renamed to component_depth - Variable (Local) (component_mount()) component_offset added - Module (Global) front_panel() added - code for making rack plate moved from component_mount() to front_panel() - Module (Local) (component_mount()) capsule_slot_2d() moved from component_mount() to front_panel() - Module (Local) (component_mount()) rounded_rect_2d() moved from component_mount() to front_panel() - Module (Local) (component_mount()) all_rack_holes() moved from component_mount() to front_panel() - Variable (Local) (component_mount()) corner_radius moved from component_mount() to front_panel() - Module (Local) front_panel() all_rack_holes() changed the z values in final translate and linear_extrude commands to clean up the preview model - Module (Local) (component_mount()) switch_cutout() removed from component_mount() and made into global Module - Variable (Local) (component_mount()) cutout_w moved from component_mount() to switch_cutout() - Variable (Local) (component_mount()) cutout_h moved from component_mount() to switch_cutout() - Variable (Local) (component_mount()) cutout_x moved from component_mount() to switch_cutout() - Variable (Local) (component_mount()) cutout_y moved from component_mount() to switch_cutout() - Variable (Local) (component_mount()) solid_z_offset copied from component_mount() to switch_cutout() - Variable (Local) (component_mount()) chassis_depth_main copied from component_mount() to switch_cutout() - Variable (Local) (switch_cutout()) component_width added to switch_cutout() - Variable (Local) (switch_cutout()) component_depth added to switch_cutout() - Variable (Local) (switch_cutout()) component_height added to switch_cutout() - Variable (Local) (switch_cutout()) component_offset added to switch_cutout() - Variable (Local) (component_mount()) zip_tie_hole_count removed from component_mount() and made into global variable - Variable (Local) (component_mount()) zip_tie_hole_width removed from component_mount() and made into global variable - Variable (Local) (component_mount()) zip_tie_hole_length removed from component_mount() and made into global variable - Variable (Local) (component_mount()) zip_tie_indent_depth removed from component_mount() and made into global variable - Variable (Local) (component_mount()) zip_tie_cutout_depth removed from component_mount() and made into global variable - Module (Local) (component_mount()) main_body() renamed to body() - module (Global) make_rack() added - Code form "// Main assembly - cleaner boolean structure" in component_mount() moved to make_rack() - Boolean structure from "// Call the module" moved to make_rack() and replaced with two lines of make_rack() - Module (Global) switch_cutout() renamed to component_cutout() - Module (Local) (component_mount()) zip_tie_features() changed the values in final translate and cube commands to clean up the preview model - Module (Local) (component_mount()) power_wire_cutouts() removed from component_mount() and made into global Module - Variable (Local) (component_mount()) solid_z_offset copied from component_mount() to power_wire_cutouts() - Variable (Local) (component_mount()) chassis_depth_main copied from component_mount() to power_wire_cutouts() - Variable (Local) (switch_cutout()) component_width added to power_wire_cutouts() - Variable (Local) (switch_cutout()) component_depth added to power_wire_cutouts() - Variable (Local) (switch_cutout()) component_height added to power_wire_cutouts() - Variable (Local) (switch_cutout()) component_offset added to power_wire_cutouts() - Module (Local) (component_mount()) keystone_front_cutout() moved to front_panel() - Variable (Local) (component_mount()) keystone_outer_width removed from component_mount() and made into global variable - Variable (Local) (component_mount()) keystone_outer_height removed from component_mount() and made into global variable - Variable (Local) (component_mount()) keystone_tx removed from component_mount() and made into global variable - Variable (Local) (component_mount()) keystone_ty removed from component_mount() and made into global variable - boolean structure for keystone cutouts moved from component_mount() to front_panel() - Module keystone() (Local) (component_mount()) used epsilon for coplanar face fixes - Variable (Local) (component_mount()) e moved to global - Module (Local) front_panel() all_rack_holes() used epsilon for coplanar face fixes - Module (Local) (component_mount()) zip_tie_features() used epsilon for coplanar face fixes - Added "include " and "include " - labeled tops settings for panel size "/* [Panel settings] */" - Module (Local) (front_panel()) rounded_rect_2d() deleted from front_panel() - Module (Local) (front_panel()) rounded_rect_2d() replaced with cuboid() from walls.scad - Module (Local) (front_panel()) capsule_slot_2d() deleted from front_panel() - Module (Local) (front_panel()) capsule_slot_2d() replaced with cuboid() from walls.scad - Variable (Local) (front_panel()) corner_radius deleted from front_panel() - Module (Global) front_panel() boolean structure added for cutting out windows for components - Module (Global) component_cutout() moved inside of component_mount() and made local - Module (Local) (component_mount()) added add_lip() using rect_tube makes lip for eash component mount - Module (Global) component_cutout() boolean structure deleted for making lip - Removed the mirror and translate command from keystone. so now it faces right side up. - Variable (Local) (component_mount()) corner_radius deleted from component_mount() - Variable (Global) front_plate_thickness moved to Panel settings - Variable (Global) front_wire_hole_left deleted - Variable (Global) front_wire_hole_right deleted - Variable (Global) component1_wire_holes added - Variable (Global) component2_wire_holes added - Variable (Global) component3_wire_holes added - Changed wire holes to a drop down with options for left, right, both ,or disabled - Variable (Global) component1_offset renamed to component1_side_offset - Variable (Global) component2_offset renamed to component2_side_offset - Variable (Global) component3_offset renamed to component3_side_offset - Variable (Global) component1_up_offset added - Variable (Global) component2_up_offset added - Variable (Global) component3_up_offset added - Module (Local) (component_mount()) power_wire_cutouts() moved to global - Module (Global) power_wire_cutouts() used in component_mount(), add_lip(), and front_panel() - Module (Global) make_rack() deleted boolean structure for power_wire_cutouts() - Module (Global) component_mount() "Assembly - boolean structure" if statement added to check if component is enabled - Module (Global) make_rack() deleted if statements to check if component if enabled - Module (Local) (front_panel()) component_front_cutout added to for repeated component cuts - Module (Global) front_panel() deleted boolean structure for repeated component cuts - Module (Local) (component_mount()) air_holes() rewrote using walls.scad - Variable (Global) hex_strut added to holes section. - Variable (Global) hex_spacing added to holes section. - Variable (Global) hex_bottom_frame added to holes section. - Module (Global) component_mount() "Assembly - boolean structure" if statement check for added a lip moved to add_lip() - Variable (Local) (component_mount()) hole_total_width deleted - Variable (Local) (component_mount()) space_between_holes deleted - Variable (Local) (power_wire_cutouts()) component_up_offset added - Variable (Local) (component_front_cutout()) component_up_offset added - Variable (Local) (component_mount()) component_up_offset added - y offset for components installed and working independently for each component --- 10InchRackGenerator.scad | 558 +++++++++++++++++---------------------- 1 file changed, 245 insertions(+), 313 deletions(-) diff --git a/10InchRackGenerator.scad b/10InchRackGenerator.scad index 35e3038..70df25f 100644 --- a/10InchRackGenerator.scad +++ b/10InchRackGenerator.scad @@ -1,166 +1,119 @@ +include +include + +/* [Panel settings] */ rack_width = 254.0; // [ 254.0:10 inch, 152.4:6 inch] // Height of the rack in U units, can be a fraction for partial U (e.g. 1.5 for 1U plus half of the next U) rack_height = 1.0; // [0.5:0.5:5] - -component_width = 110.0; -component_depth = 122.0; -component_height = 28.30; -component_offset = 0; // [-100:0.1:100] - +// Thickness of the front panel (the flat face plate). +front_plate_thickness = 3.0; +// ======================================== +/* [Component1] */ +component1 = true; +component1_width = 110.0; +component1_depth = 122.0; +component1_height = 28.30; +component1_side_offset = 0; // [-100:0.1:100] +component1_up_offset = 0; // [-100:0.1:100] +// Adds small cutout a USB or Power cable could be routed through to the front +component1_wire_holes=4; // [1: Both Sides, 2: Left, 3: Right, 4: disable] +// ======================================== +/* [Component2] */ +component2 = true; +component2_width = 110.0; +component2_depth = 122.0; +component2_height = 28.30; +component2_side_offset = 0; // [-100:0.1:100] +component2_up_offset = 0; // [-100:0.1:100] +// Adds small cutout a USB or Power cable could be routed through to the front +component2_wire_holes=4; // [1: Both Sides, 2: Left, 3: Right, 4: disable] +// ======================================== +/* [Component3] */ +component3 = true; +component3_width = 110.0; +component3_depth = 122.0; +component3_height = 28.30; +component3_side_offset = 0; // [-100:0.1:100] +component3_up_offset = 0; // [-100:0.1:100] +// Adds small cutout a USB or Power cable could be routed through to the front +component3_wire_holes=4; // [1: Both Sides, 2: Left, 3: Right, 4: disable] // ======================================== /* [Keystones] */ // Add keystone jacks to the front panel keystones = false; // [true: Place keystone jacks, false: Remove keystone jacks] keystone_left = true; // [true: Place keystone jack on the left, false: Remove left keystone jack] keystone_right = true; // [true: Place keystone jack on the right, false: Remove right keystone jacks] - // ======================================== /* [Holes] */ -// Adds small cutout a USB or Power cable could be routed through to the front -front_wire_holes = false; // [true:Show front wire holes, false:Hide front wire holes] -front_wire_hole_left = true; // [true:Show left wire hole, false:Hide left wire hole] -front_wire_hole_right = true; // [true:Show right wire hole, false:Hide right wire hole] // Diameter of wire to route through front_wire_holes. wire_diameter = 7; // Diameter of power wire holes // Adds hexagon air cutouts to reduce material and improve cooling. air_holes = true; // [true:Show air holes, false:Hide air holes] - +// size of struts between hexs. +hex_strut = 4; +// spacing determines how many hexs will fit in the space. +hex_spacing = 15; +// controls the thickness of the frame around the hex cutout. +hex_bottom_frame = 10; // [8:0.5:13] // ======================================== /* [Advanced] */ // Used when rack_height is a fraction, cuts a half oval for screws, otherwise will cover up the hole half_height_holes = true; // [true:Show partial holes at edges, false:Hide partial holes] // Thickness of the shell that wraps around the part. case_thickness = 6; // Thickness of case walls -// Thickness of the front panel (the flat face plate). -front_plate_thickness = 3.0; // Make the front plate solid (no hole), useful to hide a part not needing to be accessed from the exterior. front_plate_hole = true; // [true:Show front plate hole, false:Solid front plate] // Prevent part from sliding out the front by adding a small 0.6mm lip around the front plate hole. front_lip = true; // [true:Show front lip, false:Hide front lip] // Default gap between part and print walls tolerance = 0.42; - // ======================================== /* [Hidden] */ height = 44.45 * rack_height; - - -// The main module containing all internal variables -module switch_mount(switch_width, switch_height, switch_depth) { - //6 inch racks (mounts=152.4mm; rails=15.875mm; usable space=120.65mm) - //10 inch racks (mounts=254.0mm; rails=15.875mm; usable space=221.5mm) - chassis_width = min(switch_width + (2 * case_thickness), (rack_width == 152.4) ? 120.65 : 221.5); - corner_radius = 4.0; - chassis_edge_radius = 2.0; - tolerance = 0.42; - - zip_tie_hole_count = 8; - zip_tie_hole_width = 1.5; - zip_tie_hole_length = 5; - zip_tie_indent_depth = 2; - zip_tie_cutout_depth = 7; - +//ziptie variables +zip_tie_hole_count = 8; +zip_tie_hole_width = 1.5; +zip_tie_hole_length = 6; +zip_tie_indent_depth = 2; +zip_tie_cutout_depth = 8; +// Keystone placement — jack X span (width) goes horizontal, jack Z span (height) goes vertical +keystone_outer_width = 19.9; // jack_width + wall = (front_hole_width + wall) + wall +keystone_outer_height = 27.5; // jack_height + wall +// Left edge of left keystone pinned to 210/2 from centreline → 210mm outer-to-outer for the mirrored pair +keystone_tx = rack_width/2 - 105; +keystone_ty = (height - keystone_outer_height) / 2; +e=0.01; // epsilon for coplanar face fixes, fixes bug where some faces leave a thin sliver of material +// ============================================================================ +//End parameters + +// Power wire cutouts: Make holes on left and/or right of the component_mount +module power_wire_cutouts(component_width, component_height, component_depth, component_side_offset, component_up_offset, front_wire_holes) { + // When the front is solid the switch slides in from the back, so everything // shifts rearward by front_plate_thickness to keep zip ties at the switch's back face. solid_z_offset = front_plate_hole ? 0 : front_plate_thickness; - chassis_depth_main = switch_depth + zip_tie_cutout_depth + solid_z_offset; - chassis_depth_indented = chassis_depth_main - zip_tie_indent_depth; - - hole_total_width = zip_tie_hole_count * zip_tie_hole_width; - space_between_holes = (rack_width - hole_total_width) / (zip_tie_hole_count + 1); - - $fn = 64; - - // Calculated dimensions - cutout_w = switch_width + (2 * tolerance); - cutout_h = switch_height + (2 * tolerance); - cutout_x = (rack_width - cutout_w) / 2; - cutout_y = (height - cutout_h) / 2; - - // Keystone placement — jack X span (width) goes horizontal, jack Z span (height) goes vertical - keystone_outer_width = 19.9; // jack_width + wall = (front_hole_width + wall) + wall - keystone_outer_height = 27.5; // jack_height + wall - // Left edge of left keystone pinned to 210/2 from centreline → 210mm outer-to-outer for the mirrored pair - keystone_tx = rack_width/2 - 105; - keystone_ty = (height - keystone_outer_height) / 2; - - // Helper modules - module capsule_slot_2d(L, H) { - hull() { - translate([-L/2 + H/2, 0]) circle(r=H/2); - translate([L/2 - H/2, 0]) circle(r=H/2); - } - } - - module rounded_rect_2d(w, h, r) { - hull() { - translate([r, r]) circle(r=r); - translate([w-r, r]) circle(r=r); - translate([w-r, h-r]) circle(r=r); - translate([r, h-r]) circle(r=r); - } - } - - module rounded_chassis_profile(width, height, radius, depth) { - hull() { - translate([radius, radius, 0]) cylinder(h = depth, r = radius); - translate([width - radius, radius, 0]) cylinder(h = depth, r = radius); - translate([radius, height - radius, 0]) cylinder(h = depth, r = radius); - translate([width - radius, height - radius, 0]) cylinder(h = depth, r = radius); - } - } - - // Create the main body as a separate module - module main_body() { - side_margin = ((rack_width - chassis_width) / 2) + component_offset; - chassis_height = min(switch_height + (2 * case_thickness), height); - union() { - // Front panel - linear_extrude(height = front_plate_thickness) { - rounded_rect_2d(rack_width, height, corner_radius); - } - // Chassis body - translate([side_margin, (height - chassis_height) / 2, front_plate_thickness]) { - rounded_chassis_profile(chassis_width, chassis_height, chassis_edge_radius, chassis_depth_main - front_plate_thickness); + chassis_depth_main = component_depth + zip_tie_cutout_depth + solid_z_offset; + + mid_y = height/2 - component_up_offset; // Midplane of switch opening + hole_spacing_x = component_width; // match rack holes + + if (front_wire_holes == 1 || front_wire_holes == 2){ //make left hole + hole_left_x = (rack_width - component_width) / 2 - (wire_diameter /5) + component_side_offset; + translate([hole_left_x, mid_y, -.1]) { + linear_extrude(height = chassis_depth_main + .2) {circle(d=wire_diameter);} } - } } - - // Create switch cutout with optional lip - module switch_cutout() { - if (front_plate_hole && front_lip) { - lip_thickness = 1.2; - lip_depth = 0.60; - // Main cutout minus lip (centered) - translate([ - ((rack_width - (cutout_w - 2*lip_thickness)) / 2) + component_offset, - (height - (cutout_h - 2*lip_thickness)) / 2, - -tolerance - ]) { - cube([cutout_w - 2*lip_thickness, cutout_h - 2*lip_thickness, chassis_depth_main]); + if (front_wire_holes == 1 || front_wire_holes == 3){ //make right hole + hole_right_x = (rack_width + component_width) / 2 + (wire_diameter /5) + component_side_offset; + translate([hole_right_x, mid_y, -.1]) { + linear_extrude(height = chassis_depth_main + .2) {circle(d=wire_diameter);} } - // Switch cutout above the lip (centered) - translate([ - ((rack_width - cutout_w) / 2) + component_offset, - (height - cutout_h) / 2, - lip_depth - ]) { - cube([cutout_w, cutout_h, chassis_depth_main]); - } - } else { - // Full cutout: starts at front face when front_plate_hole, or behind front panel when solid - z_start = front_plate_hole ? -tolerance : front_plate_thickness; - z_depth = front_plate_hole ? chassis_depth_main + 2*tolerance : chassis_depth_main - front_plate_thickness + tolerance; - translate([ - ((rack_width - cutout_w) / 2) + component_offset, - (height - cutout_h) / 2, - z_start - ]) { - cube([cutout_w, cutout_h, z_depth]); - } - } } - +} + +// front_panel: used to create Rack panel with mounting holes +module front_panel() { + $fn = 64; // Create all rack holes module all_rack_holes() { // Rack standard: 3 holes per U, with specific positioning @@ -191,209 +144,196 @@ module switch_mount(switch_width, switch_height, switch_depth) { // Always show holes that are at least partially within the rack height // Always show holes fully inside the rack fully_inside = (hole_y >= slot_height/2 && hole_y <= height - slot_height/2); - // Show partial holes at edge only if half_height_holes is true + // Show partial holes at edge only if half_heighc v v c t_holes is true partially_inside = (hole_y + slot_height/2 > 0 && hole_y - slot_height/2 < height); show_hole = fully_inside || (half_height_holes && partially_inside && !fully_inside); if (show_hole) { - translate([side_x, hole_y, 0]) { - linear_extrude(height = chassis_depth_main) { - capsule_slot_2d(slot_len, slot_height); - } + translate([side_x, hole_y, front_plate_thickness/2]) { + cuboid([slot_len, slot_height, front_plate_thickness + e*2],rounding=3.5,edges=["Z"]); } } } } } } - - // Power wire cutouts: configurable diameter holes at top and bottom rack hole positions - module power_wire_cutouts() { - mid_y = (height - switch_height) / 2 + switch_height / 2; // Midplane of switch opening - hole_spacing_x = switch_width; // match rack holes - if (front_wire_hole_left){ //make left hole - hole_left_x = (rack_width - hole_spacing_x) / 2 - (wire_diameter /5) + component_offset; - translate([hole_left_x, mid_y, 0]) { - linear_extrude(height = chassis_depth_main) {circle(d=wire_diameter);} + // Punch the full keystone footprint through the front face plate + module keystone_front_cutout() { + translate([keystone_tx, keystone_ty, -tolerance]) { + cube([keystone_outer_width, keystone_outer_height, front_plate_thickness + 2 * tolerance]); + } + } + module component_front_cutout(component, component_width, component_height, component_depth, component_side_offset, component_up_offset, component_wire_holes ){ + if (component) { // add y offset here V + translate([rack_width/2 + component_side_offset, height/2 - component_up_offset, front_plate_thickness/2]) + cuboid([component_width + tolerance*2, component_height + tolerance*2, front_plate_thickness+1]); + if (component1_wire_holes < 4){ + power_wire_cutouts(component_width, component_height, component_depth, component_side_offset, component_up_offset, component_wire_holes); } } - if (front_wire_hole_right){ //make right hole - hole_right_x = (rack_width + hole_spacing_x) / 2 + (wire_diameter /5) + component_offset; - translate([hole_right_x, mid_y, 0]) { - linear_extrude(height = chassis_depth_main) {circle(d=wire_diameter);} + } + // Making the plate + //==================================================================================== + difference(){ + translate([rack_width/2, height/2, front_plate_thickness/2]) // this undoes the first translate in the main assembly might get rid of later. Translate Mark + cuboid([rack_width, height, front_plate_thickness], rounding=4, edges=["Z"]); + all_rack_holes(); + if (keystones) { + if (keystone_left) { //Cutout for left Keystone + keystone_front_cutout(); + } + if (keystone_right){ //Cutout for Right Keystone + translate([rack_width, 0, 0]) mirror([1, 0, 0]) + keystone_front_cutout(); } + } //Cutout window in rack panel for componets. will need to change translates later Translate Mark + component_front_cutout(component1, component1_width, component1_height, component1_depth, component1_side_offset, component1_up_offset, component1_wire_holes ); + component_front_cutout(component2, component2_width, component2_height, component2_depth, component2_side_offset, component2_up_offset, component2_wire_holes ); + component_front_cutout(component3, component3_width, component3_height, component3_depth, component3_side_offset, component3_up_offset, component3_wire_holes ); + } + +} +//======================================================================================== +// component_mount: used to make the soild shape of the holder for each component +// with air holes and ziptie modules inside as well. +module component_mount(component, component_width, component_height, component_depth, component_side_offset, component_up_offset, front_wire_holes) { + + //6 inch racks (mounts=152.4mm; rails=15.875mm; usable space=120.65mm) + //10 inch racks (mounts=254.0mm; rails=15.875mm; usable space=221.5mm) + chassis_width = min(component_width + (2 * case_thickness), (rack_width == 152.4) ? 120.65 : 221.5); + chassis_edge_radius = 2.0; + tolerance = 0.42; + + // When the front is solid the switch slides in from the back, so everything + // shifts rearward by front_plate_thickness to keep zip ties at the switch's back face. + solid_z_offset = front_plate_hole ? 0 : front_plate_thickness + tolerance; + chassis_depth_main = component_depth + zip_tie_cutout_depth + solid_z_offset; + chassis_depth_indented = chassis_depth_main - zip_tie_indent_depth; + $fn = 64; + + // Helper module + module rounded_chassis_profile(width, height, radius, depth) { + hull() { + translate([radius, radius, 0]) cylinder(h = depth, r = radius); + translate([width - radius, radius, 0]) cylinder(h = depth, r = radius); + translate([radius, height - radius, 0]) cylinder(h = depth, r = radius); + translate([width - radius, height - radius, 0]) cylinder(h = depth, r = radius); + } + } + // Create the main body as a separate module + module body() { + side_margin = ((rack_width - chassis_width) / 2) + component_side_offset; + chassis_height = min(component_height + (2 * case_thickness), height); + // Chassis body + translate([side_margin, (height - chassis_height) / 2 - component_up_offset, front_plate_thickness]) { + rounded_chassis_profile(chassis_width, chassis_height, chassis_edge_radius, chassis_depth_main - front_plate_thickness); } } + // component_cutout: used to create cutout with optional lip for component_mount + module component_cutout(){ + + // When the front is solid the switch slides in from the back, so everything + // shifts rearward by front_plate_thickness to keep zip ties at the switch's back face. + solid_z_offset = front_plate_hole ? 0 : front_plate_thickness; + chassis_depth_main = component_depth + zip_tie_cutout_depth + solid_z_offset; + + // Calculated dimensions + cutout_w = component_width + (2 * tolerance); + cutout_h = component_height + (2 * tolerance); + cutout_x = (rack_width - cutout_w) / 2; + cutout_y = (height - cutout_h) / 2; + + z_start = front_plate_hole ? -tolerance : front_plate_thickness; + z_depth = front_plate_hole ? chassis_depth_main + 2*tolerance : chassis_depth_main - front_plate_thickness + tolerance; + translate([((rack_width - cutout_w) / 2) + component_side_offset, ((height - cutout_h) / 2) - component_up_offset, z_start]) + cube([cutout_w, cutout_h, z_depth]); +} // Create zip tie holes and indents module zip_tie_features() { // Zip tie holes - zip_z = switch_depth + solid_z_offset; + zip_z = component_depth + solid_z_offset; for (i = [0:zip_tie_hole_count-1]) { - x_pos = (rack_width - switch_width)/2 + component_offset + (switch_width/(zip_tie_hole_count+1)) * (i+1); + x_pos = (rack_width - component_width)/2 + component_side_offset + (component_width/(zip_tie_hole_count + 1)) * (i+1); translate([x_pos, 0, zip_z]) { cube([zip_tie_hole_width, height, zip_tie_hole_length]); } } - // Zip tie indents (top and bottom) - x_pos = ((rack_width - switch_width)/2) + component_offset; - chassis_height = min(switch_height + (2 * case_thickness), height); - // Bottom indent - translate([x_pos, (height - chassis_height)/2, zip_z]) { - cube([switch_width, zip_tie_indent_depth, zip_tie_cutout_depth]); - } + x_pos = ((rack_width - component_width)/2) + component_side_offset; + chassis_height = min(component_height + (2 * case_thickness), height); // Top indent - translate([x_pos, (height + chassis_height)/2 - zip_tie_indent_depth, zip_z]) { - cube([switch_width, zip_tie_indent_depth, zip_tie_cutout_depth]); + translate([x_pos, ((height - chassis_height)/2) - component_up_offset - e, zip_z]) { + cube([component_width, zip_tie_indent_depth + e, zip_tie_cutout_depth + e]); + } + // Bottom indent + translate([x_pos, ((height + chassis_height)/2 - zip_tie_indent_depth) + .1 - component_up_offset, zip_z]) { + cube([component_width, zip_tie_indent_depth + e , zip_tie_cutout_depth + e]); } } - // Simplified air holes with staggered honeycomb pattern on all faces - module air_holes() { - hole_d = 16; - spacing_x = 15; // Horizontal spacing (X and Y directions) - spacing_z = 17; // Vertical spacing (Z direction) - tighter to match visual density - margin = 3; // Keep holes away from edges - - // Chassis dimensions used by both hole sections - chassis_height = min(switch_height + (2 * case_thickness), height); - chassis_width = min(switch_width + (2 * case_thickness), (rack_width == 152.4) ? 120.65 : 221.5); - side_margin = ((rack_width - chassis_width) / 2) + component_offset; - - // TOP/BOTTOM FACE HOLES (Y-axis, penetrating top and bottom chassis walls) - // Calculate available space for holes within switch dimensions - available_width = switch_width - (2 * margin); - available_depth = switch_depth - (2 * margin); - - // Calculate number of holes that fit - x_cols = floor(available_width / spacing_x); - z_rows = floor(available_depth / spacing_z); - - // Calculate actual grid size for centering - actual_grid_width = (x_cols - 1) * spacing_x; - actual_grid_depth = (z_rows - 1) * spacing_z; - - // Center the grid within the switch cutout area - cutout_center_x = (rack_width / 2) + component_offset; - cutout_center_z = front_plate_thickness + switch_depth / 2; - - x_start = cutout_center_x - actual_grid_width / 2; - z_start = cutout_center_z - actual_grid_depth / 2; - - // Cylinder must span the full chassis height in Y, including when chassis_height > height - // (chassis body is centered in height, so it can protrude above/below the front panel bounds) - y_hole_top = (height + chassis_height) / 2 + 1; - y_hole_h = chassis_height + 2; - - // Create top/bottom face holes with VERTICAL staggered pattern - if (x_cols > 0 && z_rows > 0) { - for (i = [0:x_cols-1]) { - for (j = [0:z_rows-1]) { - // Stagger every other COLUMN (i) instead of row (j) for vertical honeycomb pattern - z_offset = (i % 2 == 1) ? spacing_z/2 : 0; - x_pos = x_start + i * spacing_x; - z_pos = z_start + j * spacing_z + z_offset; - - // Only place hole if it fits within bounds after staggering - if (z_pos + hole_d/2 <= cutout_center_z + switch_depth/2 - margin && - z_pos - hole_d/2 >= cutout_center_z - switch_depth/2 + margin) { - translate([x_pos, y_hole_top, z_pos]) { - rotate([90, 0, 0]) { - cylinder(h = y_hole_h, d = hole_d, $fn = 6); - } - } + module air_holes(){ + + test_hex_fit_Y = (component_height + case_thickness*2) - ( hex_spacing + hex_bottom_frame*2); + test_hex_fit_x = (component_width + case_thickness*2) - ( hex_spacing + hex_bottom_frame*2); + + if(air_holes){ + translate([rack_width/2 + component_side_offset, height/2 - component_up_offset, component_depth/2]){ + if(test_hex_fit_x >= 0){ + difference(){ + cuboid([component_width + case_thickness*2 + e*2, component_height + case_thickness*2 + e*2, component_depth],rounding=0,edges=["Z"]); + hex_panel([component_width + case_thickness*2 + e*2, component_depth, component_height + case_thickness*2 + e*2], hex_strut, hex_spacing, frame=hex_bottom_frame, orient=FRONT); } } - } - } - - // SIDE FACE HOLES (X-axis through left and right walls) - - // Calculate available space within chassis height (includes case walls above/below switch) - available_height = chassis_height - (2 * margin); - available_side_depth = switch_depth - (2 * margin); - - // Calculate number of holes that fit on sides - y_cols = floor(available_height / spacing_x); // Use spacing_x for Y direction - z_rows_side = floor(available_side_depth / spacing_z); - - // Calculate actual grid size for sides - actual_grid_height = (y_cols - 1) * spacing_x; - actual_grid_depth_side = (z_rows_side - 1) * spacing_z; - - // Center the grid within the chassis height (Y) and switch depth (Z) - cutout_center_y = height / 2; // Chassis is centered in the 1U height - - y_start = cutout_center_y - actual_grid_height / 2; - z_start_side = cutout_center_z - actual_grid_depth_side / 2; - - // Each cylinder runs from 1mm outside the left wall all the way through to 1mm outside - // the right wall. Using a single cylinder per position avoids the right-side cylinder - // going in the wrong direction (away from the chassis). - if (y_cols > 0 && z_rows_side > 0) { - for (i = [0:y_cols-1]) { - for (j = [0:z_rows_side-1]) { - // Stagger every other COLUMN (i) instead of row (j) for vertical honeycomb pattern - z_offset = (i % 2 == 1) ? spacing_z/2 : 0; - y_pos = y_start + i * spacing_x; - z_pos = z_start_side + j * spacing_z + z_offset; - - // Only place hole if it fits within bounds after staggering - if (y_pos + hole_d/2 <= cutout_center_y + chassis_height/2 - margin && - y_pos - hole_d/2 >= cutout_center_y - chassis_height/2 + margin && - z_pos + hole_d/2 <= cutout_center_z + switch_depth/2 - margin && - z_pos - hole_d/2 >= cutout_center_z - switch_depth/2 + margin) { - translate([side_margin - 1, y_pos, z_pos]) { - rotate([0, 90, 0]) { - rotate([0, 0, 90]) { // Rotate hexagon 90 degrees to match front/back orientation - cylinder(h = chassis_width + 2, d = hole_d, $fn = 6); - } - } - } + if (test_hex_fit_Y >= 0){ + difference(){ + cuboid([component_width+ case_thickness*2 + e*2, component_height + case_thickness*2 + e*2, component_depth],rounding=0,edges=["Z"]); + hex_panel([ component_depth, component_height + case_thickness*2 + e*2, component_width+ case_thickness*2 + e*2 ], hex_strut, hex_spacing, frame=hex_bottom_frame, orient=LEFT); } } } } } - + + // Adds a lip to each component + module add_lip() { + if(front_lip){ + difference() { + translate([rack_width/2 + component_side_offset, height/2 - component_up_offset, 0]) + rect_tube(size=[component_width + tolerance*2,component_height + tolerance*2], wall=.6, h=.6); + power_wire_cutouts(component_width, component_height, component_depth, component_side_offset, component_up_offset, front_wire_holes); + } + } + } // Complete keystone with embossed triangle - module keystone(){ - e=0.01; // epsilon for coplanar face fixes, fixes bug where some faces leave a thin sliver of material + module keystone() { + wall=2.5; front_hole_width=14.9; front_hole_height=16.3; front_hole_z_offset=4.28; front_hole_lip=0; - jack_width=front_hole_width+wall; jack_height=25; jack_depth=9.7; front_large_catch_depth=3; front_chamfer_angle=50; // degrees from horizontal (depth axis) - back_hole_height=24.4; back_hole_z_offset=1.9; - back_small_catch_length=2; back_small_catch_depth=1.4; - back_large_catch_length=2.6; back_large_catch_depth=1.3; - back_chamfer=1.2; - // Flip entire part because I accidentially desinged it upside down - translate([0, 0, jack_height + wall]) - mirror([0, 0, 1]) { union(){ // Back edge chamfer via intersection with hull (4 separate cuts → 1 operation) intersection() { difference(){ cube([jack_width+wall,jack_depth,jack_height+wall]); // Front hole - translate([(jack_width+wall-front_hole_width)/2,0,front_hole_z_offset]) + translate([(jack_width+wall-front_hole_width)/2,-e,front_hole_z_offset]) cube([front_hole_width,jack_depth+wall,front_hole_height]); // Back hole - translate([(jack_width+wall-front_hole_width)/2,front_large_catch_depth,back_hole_z_offset]) + translate([(jack_width+wall-front_hole_width)/2,front_large_catch_depth - e,back_hole_z_offset]) cube([front_hole_width,jack_depth+wall-front_large_catch_depth,back_hole_height]); // Chamfer on front face of small catch translate([wall + front_hole_width, 0, 0]) @@ -441,62 +381,54 @@ module switch_mount(switch_width, switch_height, switch_depth) { ]); } // end union - } // end mirror } // end module keystone - - - - // Punch the full keystone footprint through the front face plate - module keystone_front_cutout() { - translate([keystone_tx, keystone_ty, -tolerance]) { - cube([keystone_outer_width, keystone_outer_height, front_plate_thickness + 2 * tolerance]); - } - } - - // Main assembly - cleaner boolean structure - translate([-rack_width/2, -height/2, 0]) { - difference() { - main_body(); - union() { - switch_cutout(); - all_rack_holes(); + // Assembly - boolean structure + // ============================================================== + if(component){ + union() { + difference() { + body(); + component_cutout(); + power_wire_cutouts(component_width, component_height, component_depth, component_side_offset, component_up_offset, front_wire_holes); zip_tie_features(); - if (front_wire_holes) { - power_wire_cutouts(); - } - if (air_holes) { - air_holes(); - } - - if (keystones) { - if (keystone_left) { //Cutout for left Keystone - keystone_front_cutout(); - } - if (keystone_right){ //Cutout for Right Keystone - translate([rack_width, 0, 0]) mirror([1, 0, 0]) - keystone_front_cutout(); - } - } + air_holes(); } + add_lip(); } - if (keystones) { - //rotate([90,0,0]) maps keystone Y→rack Z (depth), keystone Z→rack -Y (compensated by +keystone_outer_height in translate) - if (keystone_left){ //Make left Keystone - translate([keystone_tx, keystone_ty + keystone_outer_height, 0]) rotate([90,0,0]) keystone(); - } - if (keystone_right){ //Make right Keystone - translate([rack_width, 0, 0]) mirror([1, 0, 0]) + } + if (keystones) { + //rotate([90,0,0]) maps keystone Y→rack Z (depth), keystone Z→rack -Y (compensated by +keystone_outer_height in translate) + if (keystone_left){ //Make left Keystone translate([keystone_tx, keystone_ty + keystone_outer_height, 0]) rotate([90,0,0]) keystone(); - } + } + if (keystone_right){ //Make right Keystone + translate([rack_width, 0, 0]) mirror([1, 0, 0]){ + translate([keystone_tx, keystone_ty + keystone_outer_height, 0]) rotate([90,0,0]) + keystone(); + } } } } +// make_rack(): Main assembly - boolean structure +// ============================================================== +module make_rack(){ + translate([-rack_width/2, -height/2, 0]){ + union(){ + front_panel(); + component_mount(component1, component1_width, component1_height, component1_depth, component1_side_offset, component1_up_offset, component1_wire_holes); + component_mount(component2, component2_width, component2_height, component2_depth, component2_side_offset, component2_up_offset, component2_wire_holes); + component_mount(component3, component3_width, component3_height, component3_depth, component3_side_offset, component3_up_offset, component3_wire_holes); + } + } +} +// ============================================================== // Call the module if ($preview) { rotate([-90,0,0]) - translate([0, -height/2, -component_depth/2]) - switch_mount(component_width, component_height, component_depth); + translate([0, -height/2, -component1_depth/2]){ + make_rack(); + } } else { - switch_mount(component_width, component_height, component_depth); + make_rack(); }