import static uk.co.nickthecoder.foocad.chamferedextrude.v1.ChamferedExtrude.* import static uk.co.nickthecoder.foocad.layout.v1.Layout2d.* import static uk.co.nickthecoder.foocad.layout.v1.Layout3d.* import uk.co.nickthecoder.foocad.threaded.v1.Threaded class NutBoltAndInsert : Model { @Custom var threadSize = 2.0 @Custom var threadD = 20.0 @Custom var threadPitch = 16.0 @Custom(about="Number of threads") var threadCount = 3 @Custom var nutSize = 10.0 @Custom var nutChamfer = 1.2 @Custom var boltLength = 30.0 @Custom var boltChamfer = 2.0 @Custom( about="The width and depth of the slot in the bolt head" ) var slotSize = Vector2( 10, 6 ) @Custom(about="Length and diameter of the insert") var insertSize = Vector2(20, 24.5) @Custom(about="Diameter and thickness of the front of the insert") var insertFront = Vector2( 1, 32 ) @Custom var keySize = Vector2(70, 8) @Custom var keyChamfer = 2.0 @Custom var keyRadius = 4.0 @Custom(about="Diameter and thickness of the washer" ) var washerSize = Vector2( 2, 40 ) @Custom(about="Diameter and thickness of the rubber washer" ) var rubberSize = Vector2( 4, 40 ) fun threaded() : Threaded { val thread = Threaded.create( threadSize, threadD, threadPitch ) thread.threadCount = threadCount thread.nutChamfer = nutChamfer thread.rodChamfer = boltChamfer return thread } @Piece fun bolt() : Shape3d { val bolt = threaded().bolt( boltLength, 10 ).color( "Orange" ) return if ( slotSize.x > 0 ) { bolt - Cube( slotSize.x, bolt.size.x * 2, slotSize.y + 1 ).centerXY().bottomTo(-1) } else { bolt } } /* Insert into the bolt's slot to make it easier to turn the bolt. */ @Piece fun key() : Shape3d { if ( slotSize.x <= 0 ) return Cube() // Cannot have a key when there is no slot. return Square( slotSize.x-0.5, keySize.x ) .roundAllCorners( keyRadius ) .center() .chamferedExtrude( keySize.y, Math.min(0.8, keyChamfer), keyChamfer ) } @Piece fun nut() : Shape3d { return threaded().nut(nutSize) } @Piece fun insert() : Shape3d { val hole = threaded().hole( insertSize.x + 10 ) .bottomTo(-5) .color( "Red" ) val solid = Cylinder( insertFront.x, insertFront.y/2 ) + Cylinder( insertSize.x+insertFront.x, insertSize.y/2 ) return solid - hole } @Piece fun washer() : Shape3d { val ring = Circle( washerSize.y / 2 ) - Circle( threadD / 2 + threadSize/2 ) return ring.extrude( washerSize.x ).color("Grey") } /* A rubber washer, which does not freely move over the threads due to the three "pips" */ @Piece fun rubber() : Shape3d { val ring = Circle( rubberSize.y / 2 ) - Circle( threadD / 2 ) val pips = Circle( threadSize ).translateX(threadD/2) .repeatAround( 3 ) val shape = ring + pips return shape.extrude( rubberSize.x ).color("DarkSlateGrey") } override fun build() : Shape3d { return bolt() + rubber().translateZ( boltLength - 6 ) + washer().translateZ( boltLength - 10 ) + key().mirrorZ().topTo( slotSize.y ) + nut().translateZ(boltLength+10) + insert().topTo(-10) } }