/Games/TwoPieceSphere.foocad
A two piece hollow sphere. Print two hemispheres (both exactly the same), and glue them together. I believe TPU should be possible (not tried it yet).
The overhang is solved by creating a flat spot in the interior, so that the interior poles use bridging before the angle gets too steep.
You can change the position of this flat spot using the @Custom overhang.
There are optional holes in the overlapping region. These can be used to add extra mechanical strenth by inserting dowels or threaded rod prior to gluing. Drill out the holes, insert the dowels with glue, then drill out the holes on the opposite side 0.5mm bigger. This way the dowels won't be pushed out when you close the sphere. Even without dowels, the holes may help, as glue will enter them.
You can override outerSphere() to make a custom sphere, e.g. with writing or other patterns.
import static uk.co.nickthecoder.foocad.layout.v1.Layout2d.* import static uk.co.nickthecoder.foocad.layout.v1.Layout3d.* class TwoPieceSphere : Model { @Custom var diameter = 80 @Custom var thickness = 3 // Extra thickness around the equator to glue the two pieces. @Custom var joinThickness = 12 // The overhang angle where an internal flat spot is placed. @Custom var overhang = 60 @Custom var holeCount = 10 @Custom var holeD = 4 fun outerSphere() = Sphere( diameter/2 ) fun hemiSphere() : Shape3d { val flat = Cube( diameter ).centerXY() .translateZ(Degrees.sin(overhang)* diameter/2) val sphere = outerSphere() - (Sphere( diameter/2 - thickness ) - flat) val result = sphere / Cube( diameter+2 ).centerXY() return result } fun join() : Shape3d { if ( joinThickness <= thickness ) return Cube(0) val spare = joinThickness - thickness val spareR = diameter/2 - thickness- spare/2 val hoop = Circle( diameter/2-thickness/2 ) - Circle( diameter/2-joinThickness ) val solid = hoop.extrude( thickness ) if ( holeCount <= 0 || holeD <= 0 ) return solid val hole = Cylinder.hole( thickness*2+0.02, holeD/2 ).center().translateX(spareR) val holes = hole.repeatAroundZ( holeCount ) return solid - holes } override fun build() : Shape3d { return hemiSphere() + join() } }