$fn = 64; // --- PARAMETERS --- tape_id = 26.5; // Inner diameter of standard tape roll (~1 inch + clearance) tape_width = 19.5; // Width of standard tape (~3/4 inch + clearance) roll_od = 55; // Max outer diameter of a new tape roll wall = 4; // Wall thickness of the dispenser clearance = 1; // Clearance for smooth rolling tape_cutout_w = tape_width + 4 * clearance; body_width = tape_cutout_w + 2 * wall; body_length = 120; // Total length of the dispenser base_h = 10; // Solid base height for weight/stability base_r = 5; // Base corner radius hub_x = 45; // X position of the tape hub hub_z = 40; // Z position of the tape hub (clears base) spindle_dia = 10; // Diameter of the spindle pins module tape_dispenser() { difference() { union() { // Main Base hull() { translate([base_r, -body_width/2 + base_r, 0]) cylinder(r=base_r, h=base_h); translate([body_length - base_r, -body_width/2 + base_r, 0]) cylinder(r=base_r, h=base_h); translate([base_r, body_width/2 - base_r, 0]) cylinder(r=base_r, h=base_h); translate([body_length - base_r, body_width/2 - base_r, 0]) cylinder(r=base_r, h=base_h); } // Tape Holder Uprights hull() { translate([hub_x, 0, hub_z]) rotate([-90, 0, 0]) cylinder(r=18, h=body_width, center=true); translate([hub_x, 0, base_h/2]) cube([45, body_width, base_h], center=true); } // Front Cutter Support Ramp hull() { translate([body_length - 2, 0, base_h + 20]) cube([4, body_width, 5], center=true); translate([body_length - 15, 0, base_h/2]) cube([30, body_width, base_h], center=true); } } // --- SUBTRACTIONS --- // Central Cutout for Tape translate([hub_x, 0, hub_z + 10]) cube([60, tape_cutout_w, hub_z * 2], center=true); // U-Slots for Spindle Drop-in translate([hub_x, 0, hub_z]) rotate([-90, 0, 0]) cylinder(d=spindle_dia + 1, h=body_width + 2, center=true); translate([hub_x, 0, hub_z + 15]) cube([spindle_dia + 1, body_width + 2, 30], center=true); // Serrated Cutter Teeth // Subtracts 45-degree rotated cubes to create sharp zigzag edge for(i = [-body_width/2 : 2 : body_width/2]) { translate([body_length - 1, i, base_h + 22.5]) rotate([45, 0, 0]) cube([6, 2, 2], center=true); } } } module spindle() { // Positioned beside the dispenser to print in one go translate([hub_x, body_width + 15, spindle_dia/2]) { rotate([-90, 0, 0]) { union() { // Center hub (fits inside tape) cylinder(d=tape_id - 0.5, h=tape_width + clearance, center=true); // Rotation pins cylinder(d=spindle_dia - 0.5, h=body_width + 2, center=true); // Left Flange (keeps tape centered) translate([0, 0, (tape_width + clearance)/2 + 0.5]) cylinder(d=tape_id + 4, h=1, center=true); // Right Flange translate([0, 0, -(tape_width + clearance)/2 - 0.5]) cylinder(d=tape_id + 4, h=1, center=true); } } } } // Render both parts tape_dispenser(); spindle();