Exit Full View
Up

/GardenFurniture/Hardware/TubeCap.foocad

TubeCap

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.

FooCAD Source Code
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
    }
}