spool_tape_tolerance=1; spool_inner_radius=4; spool_outer_radius=18; spool_plate_height=2; spool_plate_holes=3; spool_plate_hole_angle=360/spool_plate_holes * 0.5; spool_plate_hole_inner_rim=1; spool_plate_hole_outer_rim=4; spindle_diam_tolerance=0.2; // dependency: https://github.com/revarbat/BOSL use module spindle(d, h, traction=false) { color("Sienna") cylinder(h=h, d=d, $fn=(traction ? 6 : 20)); } module spool( r_in, r_out, in_rim=1, out_rim=4, in_height=5, plate_height=1, center=false, slit_depth=0.5, spindle_diam=3, spindle_diam_tolerance=0.1, spindle_traction=false, spokes=3 ) { height = plate_height*2 + in_height; tape_height=in_height; module spool_plate() { $fn = ($preview ? 18 : 100); if (spokes > 0 && r_out - r_in > out_rim) { union() { cylinder(h=plate_height, r=r_in + in_rim); intersection() { cylinder(h=plate_height, r=r_out - out_rim); for (i = [1:spokes]) { zrot(360/spokes * i) { right(r_out/2) up(plate_height/2) cube([r_out, r_in, plate_height], center=true); } } } difference() { cylinder(h=plate_height, r=r_out); scale(1.01) cylinder(h=plate_height, r=r_out - out_rim); } } } else { cylinder(h=plate_height, r=r_out); } } module spool_inner() { $fn = ($preview ? 10 : 60); cylinder(h=in_height, r=r_in); } down(center ? height/2 : 0) difference() { color("Azure") { spool_plate(); up(plate_height) spool_inner(); up(plate_height + in_height) spool_plate(); } if (slit_depth > 0) { up(plate_height + in_height/2) cube([r_in*2, slit_depth, in_height], center=true); } down(height) scale(1 + spindle_diam_tolerance/spindle_diam) spindle(d=spindle_diam+spindle_diam_tolerance, h=height*3, traction=spindle_traction); } } // test spindle_diam=2; tape_height=5; traction=true; spool(r_in=4, r_out=20, in_height=tape_height, spindle_diam=spindle_diam, spindle_traction=traction); down(3) spindle(d=spindle_diam, h=tape_height + 8, traction=traction);