$fn=64; // --- Parameters --- arm_length = 100; arm_width = 16; arm_thick = 10; hole_d = 5.5; // Clearance for M5 bolts desk_thick = 35; clamp_depth = 40; clamp_width = 20; clamp_thick = 12; lens_inner_d = 75; lens_outer_d = 85; // --- Print Layout --- // Base clamp translate([-80, 0, 0]) base_clamp(); // Lower Arm (Top / Bottom half-laps) translate([0, -40, 0]) arm_segment(arm_length, "bottom"); // Upper Arm (Top / Top half-laps) translate([0, -15, 0]) arm_segment(arm_length, "top"); // Lens Mount (Bottom half-lap) translate([50, 60, 0]) lens_mount(); // Thumbwheels (6x for M5 bolts and nuts) for(i=[0:2]) { translate([10 + i*30, -70, 0]) thumbwheel(); translate([10 + i*30, -95, 0]) thumbwheel(); } // --- Modules --- module base_clamp() { difference() { union() { // Main C-clamp body cube([clamp_depth, desk_thick + clamp_thick*2, clamp_width]); // Joint hub extending UP (Acts as a Bottom half-lap) translate([clamp_depth/2, desk_thick + clamp_thick*1.5, clamp_width]) cylinder(d=arm_width, h=arm_thick/2); } // Cutout for desk translate([-1, clamp_thick, -1]) cube([clamp_depth + 2, desk_thick, clamp_width+2]); // Hole for tightening screw translate([clamp_depth/2, -1, clamp_width/2]) rotate([-90, 0, 0]) cylinder(d=hole_d, h=clamp_thick+2); // Nut trap for tightening screw (outside face, rotated for flat bridging) translate([clamp_depth/2, -0.1, clamp_width/2]) rotate([-90, 30, 0]) cylinder(d=9.6, h=4, $fn=6); // Hole for joint hub translate([clamp_depth/2, desk_thick + clamp_thick*1.5, -1]) cylinder(d=hole_d, h=clamp_width + arm_thick + 2); } } module arm_segment(len, end2_type="bottom") { // Laid flat on its side to print without supports translate([0, arm_thick, arm_width/2]) rotate([90, 0, 0]) difference() { union() { translate([0, -arm_width/2, 0]) cube([len, arm_width, arm_thick]); cylinder(d=arm_width, h=arm_thick); translate([len, 0, 0]) cylinder(d=arm_width, h=arm_thick); } // End 1: Cutout BOTTOM half -> leaves TOP half intact translate([-arm_width, -arm_width, -1]) cube([arm_width*2, arm_width*2, arm_thick/2 + 1]); // End 2 if (end2_type == "bottom") { // Cutout TOP half -> leaves BOTTOM half intact translate([len-arm_width, -arm_width, arm_thick/2]) cube([arm_width*2, arm_width*2, arm_thick/2 + 1]); } else { // Cutout BOTTOM half -> leaves TOP half intact translate([len-arm_width, -arm_width, -1]) cube([arm_width*2, arm_width*2, arm_thick/2 + 1]); } // Joint Holes translate([0, 0, -1]) cylinder(d=hole_d, h=arm_thick+2); translate([len, 0, -1]) cylinder(d=hole_d, h=arm_thick+2); } } module lens_mount() { hub_x = lens_outer_d/2 + 25; difference() { union() { // Lens ring cylinder(d=lens_outer_d, h=arm_thick); // Connecting block translate([lens_outer_d/2 - 2, -arm_width/2, 0]) cube([hub_x - lens_outer_d/2 + 2, arm_width, arm_thick]); // Joint hub translate([hub_x, 0, 0]) cylinder(d=arm_width, h=arm_thick); } // Lens hole translate([0, 0, -1]) cylinder(d=lens_inner_d, h=arm_thick+2); // Lens lip (drop-in from top) translate([0, 0, arm_thick/2]) cylinder(d=lens_inner_d + 4, h=arm_thick); // Hub Cutout TOP half -> leaves BOTTOM half intact translate([hub_x - arm_width, -arm_width, arm_thick/2]) cube([arm_width*2, arm_width*2, arm_thick/2 + 1]); // Joint Hole translate([hub_x, 0, -1]) cylinder(d=hole_d, h=arm_thick+2); } } module thumbwheel() { difference() { cylinder(d=25, h=8, $fn=6); // Hexagonal grip translate([0, 0, -1]) cylinder(d=hole_d, h=10); // Bolt pass-through translate([0, 0, 3.5]) cylinder(d=9.6, h=5, $fn=6); // M5 nut/bolt head trap } }