$fn=64; // --- PARAMETERS --- rail_length = 600; rail_height = 40; rail_depth = 12; chamfer = 8; tolerance = 0.4; // Clearance for sliding fit // --- MAIN ASSEMBLY --- // Display the rail main_rail(); // Display the modular attachments slid onto the rail translate([80, 0, 0]) hook_module(); translate([200, 0, 0]) double_hook_module(); translate([350, 0, 0]) bin_module(); // --- MODULES --- // 1. Base Rail Profile (used for both the rail and the cutouts) module rail_shape(len, tol=0) { rotate([0, -90, 0]) translate([0, 0, -len]) linear_extrude(height=len) offset(delta=tol) polygon([ [0, 0], [chamfer, rail_depth], [rail_height - chamfer, rail_depth], [rail_height, 0] ]); } // 2. Main Wall-Mounted Rail module main_rail() { difference() { rail_shape(rail_length, 0); // Countersunk mounting holes every 100mm for(i = [50 : 100 : rail_length - 50]) { translate([i, 0, rail_height / 2]) { rotate([-90, 0, 0]) { // Screw shaft translate([0, 0, -1]) cylinder(h=rail_depth + 2, d=5); // Countersink head translate([0, 0, rail_depth - 4]) cylinder(h=5, d1=5, d2=10); } } } } } // 3. Single Hook Module (for leashes/collars) module hook_module() { w = 40; difference() { // Base block cube([w, rail_depth + 6, rail_height]); // Sliding dovetail cutout translate([-1, 0, 0]) rail_shape(w + 2, tolerance); } // Hook geometry translate([w / 2, rail_depth + 4, rail_height / 2 - 5]) { rotate([-45, 0, 0]) { cylinder(h=32, d=12); translate([0, 0, 32]) sphere(d=16); } } } // 4. Double Hook Module module double_hook_module() { w = 80; difference() { // Base block cube([w, rail_depth + 6, rail_height]); // Sliding dovetail cutout translate([-1, 0, 0]) rail_shape(w + 2, tolerance); } // Two hooks for(x = [20, 60]) { translate([x, rail_depth + 4, rail_height / 2 - 5]) { rotate([-45, 0, 0]) { cylinder(h=28, d=10); translate([0, 0, 28]) sphere(d=14); } } } } // 5. Bin Module (for treats or poop bag rolls) module bin_module() { w = 120; bin_d = 60; bin_h = 60; difference() { union() { // Base block cube([w, rail_depth + 6, rail_height]); // Bin outer shell translate([0, rail_depth + 4, rail_height - bin_h]) cube([w, bin_d, bin_h]); } // Sliding dovetail cutout translate([-1, 0, 0]) rail_shape(w + 2, tolerance); // Hollow out the bin (4mm walls) translate([4, rail_depth + 8, rail_height - bin_h + 4]) cube([w - 8, bin_d - 8, bin_h]); } }