$fn = 64; // --- PARAMETERS --- palette_width = 160; // Width of the wet palette tray palette_depth = 120; // Depth of the tray angle = 15; // Angle of the tray for easy access (degrees) wall = 4; // Wall thickness for rigidity lip_height = 10; // Height of the front and side retaining lips back_height = 70; // Height of the back mounting plate // Wall mount hook parameters (ArtArsenal / Slatwall style) hook_width = 25; // Width of each mounting hook hook_inset = 20; // Distance of hooks from the left/right edges hook_gap = 6; // Gap for the wall rail hook_drop = 12; // Downward drop of the hook // --- MAIN ASSEMBLY --- wet_palette_holder(); module wet_palette_holder() { union() { // Main Backplate cube([palette_width, wall, back_height]); // Angled Tray translate([0, wall - 0.1, back_height - 15]) rotate([-angle, 0, 0]) union() { // Tray Base cube([palette_width, palette_depth, wall]); // Front Lip translate([0, palette_depth - wall, 0]) cube([palette_width, wall, lip_height + wall]); // Left Lip cube([wall, palette_depth, lip_height + wall]); // Right Lip translate([palette_width - wall, 0, 0]) cube([wall, palette_depth, lip_height + wall]); } // Support Gussets gusset(); translate([palette_width / 2 - wall / 2, 0, 0]) gusset(); translate([palette_width - wall, 0, 0]) gusset(); // Wall Mount Hooks translate([hook_inset, 0, 0]) rail_hook(); translate([palette_width - hook_inset - hook_width, 0, 0]) rail_hook(); } } module gusset() { hull() { // Top point against backplate (touching bottom of tray) translate([0, wall - 0.5, back_height - 15 - 0.5]) cube([wall, 0.5, 0.5]); // Bottom point against backplate translate([0, wall - 0.5, 10]) cube([wall, 0.5, 0.5]); // Point along the tray (underneath) translate([0, wall + (palette_depth * 0.7) * cos(angle), back_height - 15 - (palette_depth * 0.7) * sin(angle) - 0.5]) cube([wall, 0.5, 0.5]); } } module rail_hook() { // Extrude the hook profile along the X axis rotate([0, 90, 0]) linear_extrude(hook_width) polygon([ // Top hook over the rail [back_height, 0.1], [back_height, -hook_gap - wall], [back_height - hook_drop, -hook_gap - wall], [back_height - hook_drop - 2, -hook_gap - wall/2], // Chamfer for easy insertion [back_height - hook_drop, -hook_gap], [back_height - wall, -hook_gap], [back_height - wall, 0.1], // Bottom standoff to keep the holder parallel to the wall [5 + wall, 0.1], [5 + wall, -hook_gap], [5, -hook_gap], [5, 0.1] ]); }