$fn=64; // --- Parameters --- // Overall width of the wall plate plate_width = 80; // Overall height of the wall plate plate_height = 50; // Base thickness of the wall plate plate_thickness = 6; // Depth of the rear rail attachment lip rail_lip_depth = 8; // Height of the rear rail attachment lip rail_lip_height = 12; // Thickness of the downward catch for the rail rail_catch_thickness = 4; // Distance between the two hooks hook_spacing = 45; // Outward length of each hook hook_length = 35; // Diameter of the hook shafts hook_diam = 10; // Height of the upward lip at the end of each hook hook_lip = 15; // --- Modules --- // Generates the backplate with a generic rail attachment profile module backplate() { translate([-plate_width/2, 0, 0]) rotate([0, 90, 0]) linear_extrude(plate_width) polygon([ [0, 0], [-plate_height, 0], [-plate_height, -plate_thickness], [-plate_height, -plate_thickness - rail_lip_depth], [-plate_height + rail_lip_height, -plate_thickness - rail_lip_depth], [-plate_height + rail_lip_height, -plate_thickness - rail_lip_depth + rail_catch_thickness], [-plate_height + rail_lip_height + 5, -plate_thickness], [-rail_lip_height, -plate_thickness], [-rail_lip_height, -plate_thickness - rail_lip_depth], [0, -plate_thickness - rail_lip_depth] ]); } // Generates a single leash hook with a reinforced base module single_hook() { // Reinforced base fillet hull() { rotate([-90, 0, 0]) cylinder(h=0.2, d=hook_diam + 8); translate([0, hook_length * 0.3, 0]) rotate([-90, 0, 0]) cylinder(h=0.1, d=hook_diam); } // Main horizontal shaft rotate([-90, 0, 0]) cylinder(h=hook_length, d=hook_diam); // Corner joint translate([0, hook_length, 0]) sphere(d=hook_diam); // Upward vertical lip translate([0, hook_length, 0]) cylinder(h=hook_lip, d=hook_diam); // Rounded tip translate([0, hook_length, hook_lip]) sphere(d=hook_diam); } // --- Assembly --- union() { backplate(); // Left Hook (translated slightly into the plate to ensure manifold geometry) translate([-hook_spacing/2, -0.1, plate_height/2 - hook_diam/2]) single_hook(); // Right Hook translate([hook_spacing/2, -0.1, plate_height/2 - hook_diam/2]) single_hook(); }