/GardenFurniture/Hardware/TubeCap.foocad

A cap for tubes (often seen on cardboard tubes used for shipping long goods). I created this to add caps to off-cuts of drain pipe to use them to hold short garden canes.
import uk.co.nickthecoder.foocad.cup.v1.*
import static uk.co.nickthecoder.foocad.cup.v1.Cup.*
import uk.co.nickthecoder.foocad.smartextrusion.v1.*
import static uk.co.nickthecoder.foocad.smartextrusion.v1.SmartExtrusion.*
import uk.co.nickthecoder.foocad.extras.v1.*
import static uk.co.nickthecoder.foocad.extras.v1.Extras.*
class TubeCap : Model {
@Custom
var internalDiameter = 64.0
var baseThickness = 1.8
@Custom( about="Thickness and height" )
var lipSize = Vector2( 1.8, 8 )
@Custom
var tubeThickness = 2.5
@Custom
var overlap = 1.0
@Custom
var insetSize = Vector2( 40, 0 )
@Custom( about="width and height of a rib which holds the cap in place" )
var ribSize = Vector2(0.7, 2)
@Piece
meth cap() : Shape3d {
val base = Circle( internalDiameter/2 + tubeThickness + overlap )
.smartExtrude(baseThickness)
.bottom( Chamfer( 0.5 ) )
val ring = Circle( internalDiameter/2 )
.ring( -lipSize.x )
.smartExtrude( lipSize.y )
.outsideTop( Chamfer( lipSize.x/2 ) )
.bottomTo( base.top )
val rib = if (ribSize.x > 0 && ribSize.y > 0 ) {
Trapezium( ribSize.y + baseThickness, baseThickness/2 + ribSize.x )
.angle(-45)
.rotate(-90)
.leftTo( internalDiameter/2 - baseThickness/2 )
.revolve().sides(20)
.centerZTo( ring.middle.z )
} else {
null
}
if (insetSize.x > 0 && insetSize.y > 0 ) {
val inset = Circle( insetSize.x/2 )
.cup( insetSize.y, baseThickness )
.cavity(true)
.offsetBottom( -insetSize.y )
.mirrorZ().bottomTo(0)
val bar = Trapezium( insetSize.x, insetSize.y )
.angle(-45)
.extrude( baseThickness )
.rotateX(90)
.bottomTo(0)
.centerXY()
return (base and inset insert bar) + ring + rib
} else {
return base + ring + rib
}
}
@Piece( print="cap" )
override fun build() : Shape3d {
val tube = Circle( internalDiameter/2 )
.ring( tubeThickness )
.extrude(30)
.previewOnly()
val cap = cap()
.mirrorZ()
.topTo( tube.top + baseThickness + lipSize.y + 2 )
return tube + cap
}
}