import static uk.co.nickthecoder.foocad.layout.v1.Layout2d.* import static uk.co.nickthecoder.foocad.layout.v1.Layout3d.* import static uk.co.nickthecoder.foocad.chamferedextrude.v1.ChamferedExtrude.* import static uk.co.nickthecoder.foocad.screws.v2.Screws.* import uk.co.nickthecoder.foocad.threaded.v1.Threaded class JengaFeet : Model { val diameter = 40 val pitch = 5 val threadSize = 2.0 val height = 25 val wallThicknss = 4 val baseThickness = 2 val extraNutHeight = 0 val extraRodHeight = 10 fun threaded() = Threaded.create( threadSize, diameter, pitch ).apply { sides = 52 // Hmm, some values cause the rendered version to fail??? nutProfile = Circle( diameter * 0.6 + 4 ).sides( 6 ).roundAllCorners(5) nutChamfer = baseThickness } // Screw is 8mm inside the "rod". // I plan on using 20mm screws, so 12mm is into the wood. fun countersink() = Countersink() .recess(height + extraRodHeight - 8) @Piece fun nut() : Shape3d { val thread = threaded() val nut = thread.nut(height + baseThickness + extraNutHeight ) val base = thread.nutProfile.chamferedExtrude( baseThickness, thread.nutChamfer, 0 ) return nut + base } fun holes() : Shape3d { return countersink().mirrorZ().bottomTo(0).translateX( diameter*0.25 ) .repeatAroundZ(3) } @Piece fun rod() : Shape3d { val thread = threaded() val rod = thread.rod( height, 180, 30 ) val holes : Shape3d = holes() val extra = Circle(thread.innerR).sides(thread.sides) .extrude( extraRodHeight + thread.rodChamfer ) .bottomTo( height - thread.rodChamfer ) return rod + extra - holes } // A template to help mark pilot holes for the screws. @Piece fun template() : Shape3d { return (Circle( diameter/2 ) + Square( diameter/2 )).extrude(0.4) - holes().topTo(1) } override fun build() : Shape3d { return nut().color("Orange") + rod().color("Green").bottomTo( baseThickness + extraNutHeight ) } }