$fn=64; // --- Parameters --- card_width = 90; // Width of the business card slot slot_depth = 15; // Capacity depth of the holder wall_thickness = 3; // Thickness of the walls back_height = 45; // Height of the backrest tilt_angle = 15; // Viewing angle tilt base_radius = 65; // Size of the hexagonal base // --- Main Assembly --- difference() { union() { // Hexagonal Base with chamfered edge hull() { rotate([0, 0, 30]) cylinder(r=base_radius, h=1, $fn=6); rotate([0, 0, 30]) cylinder(r=base_radius - 2, h=wall_thickness, $fn=6); } // Card Holder Body translate([0, 0, wall_thickness]) rotate([tilt_angle, 0, 0]) holder_body(); } // Clean up the bottom to ensure it sits perfectly flat on the build plate translate([0, 0, -50]) cube([200, 200, 100], center=true); } // --- Modules --- module holder_body() { // Backrest with hex cutouts difference() { translate([0, slot_depth/2 + wall_thickness/2, back_height/2]) cube([card_width, wall_thickness, back_height], center=true); // Hex Cutouts applied to backrest translate([0, slot_depth/2 + wall_thickness/2, back_height/2]) rotate([90, 0, 0]) hex_grid_cutout(); } // Front Lip translate([0, -slot_depth/2 - wall_thickness/2, 10/2]) cube([card_width, wall_thickness, 10], center=true); // Floor / Base connector // Top surface matches slot bottom, extends downwards to merge safely with the base translate([0, 0, -1.5]) cube([card_width, slot_depth + wall_thickness*2, 9], center=true); // Side guards to keep cards aligned for (x = [-card_width/2 + wall_thickness/2, card_width/2 - wall_thickness/2]) { translate([x, 0, 10/2]) cube([wall_thickness, slot_depth + wall_thickness*2, 10], center=true); } } module hex_grid_cutout() { hex_r = 4.5; spacing = 2; x_step = hex_r * sqrt(3) + spacing; y_step = hex_r * 1.5 + spacing * sqrt(3)/2; intersection() { // Bounding box to leave a solid structural border around the cutouts cube([card_width - 12, back_height - 12, wall_thickness * 10], center=true); union() { for (x = [-6 : 6]) { for (y = [-4 : 4]) { // Offset every other row for a honeycomb pattern x_offset = (abs(y) % 2 == 1) ? (x_step / 2) : 0; translate([x * x_step + x_offset, y * y_step, 0]) rotate([0, 0, 30]) cylinder(r=hex_r, h=wall_thickness*5, center=true, $fn=6); } } } } }