Exit Full View
Up

/Garden/WateringJug.foocad

WateringJug
FooCAD Source Code
class WateringJug : Model {
    
    @Custom
    var thickness = 1.4

    // The height of the jug portion. To spout is higher than this!
    @Custom
    var height = 150

    // Squashes the jug. Note this will affect the wall thickness too.
    // If squashed < 1, then the x values are scaled (making the jug narrower)
    // If squashed = 1, then the jug is circular
    // If squahsed > 1, then the y values are scaled

    @Custom
    var squashed = 1.0

    override fun build() : Shape3d {
    
        val shapes = SVGParser().parseFile( "WateringJug.svg" ).shapes

        // So that we can print at any scale, but still respecting the @Custom thickness
        // We build the jug at the "normal" size, and then scale the whole thing at the end.
        val scale = height / shapes["jug"].size.y
        val scaledThickness = thickness / scale

        val jugP = shapes["jug"].toOrigin().translateX(0.001)
        val insideP = jugP.offset( -scaledThickness )
   
        val jug = jugP.translateX(0.1).revolve()

        val jugInside = insideP.revolve() +
            Cylinder( scaledThickness * 3, insideP.size.x ).translateZ( insideP.size.y ) +
            Cylinder( insideP.size.y, scaledThickness*2 ).translateZ( scaledThickness )

        val spoutP = shapes["spout"].toOrigin().translateX(0.001)
        val spoutInsideP = spoutP.offset( -scaledThickness )
        
        val sliceEnd = Cube( 100 ).centerXY().rotateX(-45).translateZ(spoutP.size.y-16)
        val sliceBase = Cube( 140 ).centerXY().translateZ(-80).rotateX(30)

        val spout = spoutP.revolve() - sliceEnd - sliceBase
        val spoutInside = spoutInsideP.revolve() - sliceBase +
            Cylinder( spoutInsideP.size.y, scaledThickness+1 ).translateZ( scaledThickness )

        val placedSpoutInside = spoutInside.rotateX(34).translate(0,6,90)
        val placedSpout = spout.rotateX(34).translate(0,6,90)

        val radius = shapes["opening"].size.x + scaledThickness + 0.5
        val rim = (
                Circle(scaledThickness*1.1).translate(-scaledThickness*2,scaledThickness*3)
                    .hull( Circle(scaledThickness/2) )
            )
            .translate( radius, insideP.size.y )
            .revolve().color("Red")

        var result : Shape3d = (jug + placedSpout - jugInside - placedSpoutInside + rim)
        
        if ( squashed < 1 ) {
            result = result.scale(scale * squashed, scale, scale)
        } else {
            result = result.scale(scale, scale * squashed, scale)
        }


        return result // Cube(1, jugP.size.y,  jugP.size.y*1.2 ).scale(scale).centerXY()
         
    }
}