import uk.co.nickthecoder.foocad.threaded.v1.Threaded class WateringCanSpout : Model { @Custom( about="Diameter of the end, where the rose attaches" ) var endD = 23.5 @Custom( about="Length of the slightly tapered region where the rose attaches" ) var endL = 20.0 @Custom( about="Internal diameter of the tube at the can end" ) var midD = 24 @Custom( about="Length of the shaft, not including the threaded part or the rose attachment" ) var length = 180 @Custom( about="Thread depth" ) var threadDepth = 1.0 @Custom( about="Thread pitch" ) var threadPitch = 5.0 @Custom( about="Thread diameter" ) var threadD = 39.5 @Custom( about="Thickness of all the parts" ) var thickness = 1.2 @Custom( about="Length of the threaded portion" ) var bodyL = 23 val shoulder = 10 val taper = 1.0 @Piece fun tube() : Shape3d { val bodyExternalR = threadD / 2 + thickness + threadDepth val stop = (Circle( bodyExternalR ) - Circle( midD / 2 + thickness ) ).extrude( thickness ) val tube = ExtrusionBuilder().apply { crossSection( Circle( bodyExternalR ) ) forward( shoulder ) crossSection( Circle( midD /2 + thickness*2 ) ) forward( length - shoulder ) crossSection( Circle( endD/2 )) forward( endL ) crossSection( -taper ) crossSection( - thickness ) forward( -endL ) crossSection( taper ) forward( -length + shoulder) crossSection( Circle( midD /2 + thickness ) ) forward( -shoulder ) crossSection() }.buildClosed().bottomTo( stop.top ) return tube + stop } @Piece fun body() : Shape3d { val bodyExternalR = threadD / 2 + thickness + threadDepth val threaded = Threaded.create( threadDepth, threadD, threadPitch ).apply { nutProfile = Circle( bodyExternalR ) nutChamfer = 0 } val rubberT = 4 // the size of the rubber washer val stop = (Circle( bodyExternalR ) - Circle( midD / 2 + thickness ) ).extrude( thickness ) val thread = ( threaded.nut( bodyL-rubberT) ).bottomTo( stop.top ) return thread + stop } override fun build() : Shape3d { val tube : Shape3d = tube() val body : Shape3d = body().mirrorZ() return tube + body } }