include ; $fn = $preview ? 32 : 128; band_arc_radius = 75; band_thickness = 3; band_height = 10; leg_length = 27; edge_radius = 0.5; band_arc = turtle([ "move", leg_length, "arcright", band_arc_radius, 80, "arcright", band_arc_radius * 0.8, 20, "arcright", band_arc_radius * 1.2, 40, "arcright", band_arc_radius * 0.8, 20, "arcright", band_arc_radius, 80, "move", leg_length ]); band_profile = rect( size=[band_thickness, band_height], rounding=edge_radius ); band_length = path_length(band_arc); band_curve_length = band_length-leg_length*2; leg_frac = leg_length/band_length; band_curve_frac = 1-leg_frac*2; tooth_width = 2; tooth_height = 2.5; tooth_offset = band_height/2-2; dense_teeth_count = 70; teeth_step = band_curve_frac/dense_teeth_count; punch_fracs = [ for(frac=[0.07, 0.18, 0.29, 0.5, 0.71, 0.82, 0.93]) frac * band_curve_frac + leg_frac ]; function hole(anchor) = rect( size=[band_height/2+1, band_height/2], rounding=band_height/4, anchor=anchor ); module punch() linear_sweep( region=[ right(1, p=hole(LEFT)), left(1, p=hole(RIGHT)) ], length=band_thickness+2 ); function punch_clearance(tooth_frac, punch_frac) = abs(punch_frac - tooth_frac) > 0.025; module punches() for(punch_frac=punch_fracs) sweep_attach( parent=LEFT, child=BOT, frac=punch_frac, spin=90, overlap=band_thickness+1 ) tag("remove") punch(); module tooth() cyl( d1=tooth_width, d2=edge_radius*2, h=tooth_height, rounding2=edge_radius ); module teeth() for(tooth_frac=[leg_frac:teeth_step:1-leg_frac]) if( all([ for (punch_frac=punch_fracs) punch_clearance(tooth_frac, punch_frac) ]) ) sweep_attach(LEFT, BOT, tooth_frac) { left(tooth_offset) tooth(); right(tooth_offset) tooth(); } pip_count = 4; pip_size = 1.2; pip_frac_step = 0.0045; module pips() for(pip_idx=[0:1:pip_count-1]) sweep_attach( parent=LEFT, child=BOT, frac=leg_frac+pip_idx*pip_frac_step, overlap=pip_size/2 ) tag("remove") sphere(d=pip_size); module ends() attach(["end", "start"]) xcyl( h=band_thickness, d=band_height, rounding=edge_radius ); module band() diff() path_sweep(band_profile, band_arc) { punches(); teeth(); pips(); ends(); } band();