use use $fa = ($preview) ? 12 : 1; $fs = ($preview) ? 2 : 1; $incolor = true; // Config BallDiameter = 65; BallClearance = 2; BallSealWidth = 3; PlateLip = 2; PlateDiameter = BallDiameter + 2*(BallClearance + BallSealWidth + PlateLip); PlateThick = BallSealWidth/2 + 1; //plate_full(); PlateSep = 0; pd = PlateDiameter+PlateSep; pt = PlateThick; echo("PD=", pd); translate([pd+5,0]) plate_top(thickness=pt); translate([0,pd+5]) plate_mid(thickness=pt); translate([pd+5,pd+5]) cap_compression(PlateDiameter, pt); translate([-(pd+5),0]) mold_wall(PlateDiameter, pt, BallDiameter); translate([0,-(pd+5)]) plate_under(); module stack(pt, ed=10 ,expand=false) { d = expand ? pt + ed : pt+.01; for (i = [0:$children-1]) { translate([0,0,d*i]) children(i); } } module mold_wall(pd, pt, bd, sd=4, wt=3) { threadc = $incolor ? "green" : undef; ptol = 2; wh = bd/2+pt+sd; difference() { union() { translate([0,0,2]) cylinder(d=pd, h=wh); color(threadc) metric_thread( diameter=pd+ptol, length=4.01, internal=false); } translate([0,0,-.1]) cylinder(d1=pd-wt, d2=pd-wt-3, h=wh+4+.2); } } module cap_compression(pd, pt, th=7, wt=3, register=true, key=true) { td=pd+2; difference() { cylinder(d=td+wt, h=th); translate([0,0,-.01]) cylinder(d=3, h=5); translate([0,0,-.01]) cylinder(d=6, h=3); translate([0,0,2*pt]) metric_thread(diameter=td,length=th+.01, internal=true); if (register && ! key) translate([0,0,2*pt]) register_seal(); } if (register && key) translate([0,0,2*pt]) register_seal(); } module plate( d=PlateDiameter, thickness = PlateThick) { translate([0,0,-thickness]) cylinder(d=d, h=thickness+.01); } module plate_mid(thickness = 1) { translate([0,0,thickness]) { ball(bottom=false); plate(thickness=thickness); register_seal(); } } module plate_top(thickness = 1) { translate([0,0,thickness]) { ball(bottom=false); difference() { plate(thickness=thickness); register_seal(); } } } module plate_under(thickness = 1) { translate([0,0,thickness]) { underball(); plate(thickness=thickness); register_seal(); } } module ball( bd=BallDiameter, insert=true, top = true, bottom = true) { insertc = $incolor ? "gold" : undef; maxz = top ? bd/2 : 0; minz = bottom ? -bd/2 : 0; echo("maxz:", maxz); echo("minz:", minz); difference() { intersection() { sphere(d=bd); translate([0,0,(maxz+minz)/2]) cube([bd, bd, maxz-minz],center=true); } color(insertc) { if (insert) for (iz = [-bd/2, bd/2]) { rot = (iz < 0) ? 180 : 0; translate([0,0,iz]) rotate([0,rot,0]) thread_insertM25($die=true); } if (! bottom) rotate([0,0,0]) thread_insertM25($die=true); } } } module register_seal( bd = BallDiameter, cl = BallClearance, // Clearance around ball sw = BallSealWidth, // Width of register ) { rotate_extrude() translate([bd/2+cl,0,0]) circle(d=sw); } module underball() { intersection() { translate([0,0,9]) { rotate_extrude(angle=360) translate([10+15/2,0,0]) circle(d=20); translate([0,0,-4]) cylinder(d=55, h=10, center=true); } cylinder(d=70,h=35); } }