/Garden/WateringCanSpout2.foocad

My spout has degraded in the sun, but the body is still looking good. 3D printer to save a little plastic ;-)
This version is printed as a single piece, upside-down. But, it is VERY unstable (top heavey).
I have had 2 failed prints at 90% + (at different places, and different types of failure). I then added the "fins"
Print Notes
Add a generous brim. I used 10mm I upped the permimeters to 4, with 50% infill.
import uk.co.nickthecoder.foocad.threaded.v2.*
import static uk.co.nickthecoder.foocad.layout.v1.Layout2d.*
import static uk.co.nickthecoder.foocad.layout.v1.Layout3d.*
class WateringCanSpout2 : AbstractModel() {
@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
// Don't make it too large, or there won't be enough of a lip for the sealing washer.
@Custom( about="Internal diameter of the tube at the can end" )
var midD = 26
@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 connectorL = 19
val shoulder = 10
// Cut the fins off after printing!
@Custom( about="Helps support the wobbly tube while printing. Only needed for plater slingers?" )
var includeFins = true
val taper = 1.0
fun tube() : Shape3d {
val bodyExternalR = threadD / 2 + thickness + threadDepth
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()
return tube
}
fun body() : Shape3d {
val bodyExternalR = threadD / 2 + thickness + threadDepth
val threaded = Thread( threadD, threadPitch )
val stop = (Circle( bodyExternalR ) - Circle( midD / 2 + thickness ) ).extrude( thickness )
val thread = (
threaded.nutHeight( connectorL ).nut()
).bottomTo( stop.top )
return thread + stop
}
override fun build() : Shape3d {
val tube = tube().mirrorZ().bottomTo(0)
val body = body().bottomTo( tube.top )
val fins = if ( includeFins ) {
val rect = Square( 20, 0.8 ).centerY()
ExtrusionBuilder().apply {
crossSection( rect.leftTo( endD/2 - taper ) )
forward( endL )
crossSection( rect.leftTo( endD/2 ) )
forward( (length- shoulder) * 0.5 )
crossSection( rect.scaleX(0.01).leftTo((endD/2 + midD/2+thickness)/2 ) )
}.build()
.color("Green")
.repeatAroundZ(4)
} else {
null
}
return tube + body + fins
}
}

