Exit Full View
ZipUp

/Bottles/BirdSeedContainer2.foocad

BirdSeedContainer2

Containers for bird seed, and other bird food.

If you need a rectangular (not-square) bottle, then ensure that the size.x > size.y

FooCAD Source Code
import uk.co.nickthecoder.foocad.cup.v1.*
import static uk.co.nickthecoder.foocad.cup.v1.Cup.*
import static uk.co.nickthecoder.foocad.layout.v1.Layout2d.*
import static uk.co.nickthecoder.foocad.layout.v1.Layout3d.*
import static uk.co.nickthecoder.foocad.circular.v1.Circular.*
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.threaded.v2.*

include Bottle.foocad

class BirdSeedContainer2 : Model {

    @Custom
    var bottle = Bottle().apply {
        size = Vector3( 160, 120, 250 )
        neckHeight = 70
        round = 26
        baseThickness = 12
    }


    meth plugThread() = Thread( Math.min(bottle.size.x, bottle.size.y) - bottle.bottomFillet*2 - 2, 3 )
        .rodChamfer(5)

    @Piece
    @Slice( topSolidLayers=10, bottomSolidLayers=10, perimeters=4 ) // Solid!
    meth cap() = bottle.cap()

    @Piece
    @Slice( seamPosition="back" )
    meth body() : Shape3d {
        Quality.quality(6)

        val plain = bottle.body()
        val plugThread = plugThread()

        val thread = plugThread.threadedHole( bottle.baseThickness )
            .chamferEnd(false)

        return  plain - thread
    }

    @Piece
    meth plug() : Shape3d {
        Quality.quality(6)

        val plugThread = plugThread()
        val thread = plugThread.rodChamfer(1).threadedRod( bottle.baseThickness -1 )
            .chamferBottom(false)
            .bottomTo(1)

        val chamferRadius = plugThread.threadedHole( bottle.baseThickness ).size.x / 2 - 0.5
        val chamfer = Circle( chamferRadius )
            .smartExtrude( plugThread.rodChamfer-1 )
                .top( Chamfer( plugThread.rodChamfer-1 ) )
            
    
        val fingerHoleRadius = Math.min( 40, thread.size.x / 2 - 10 )
        val fingerHole = (Circle(fingerHoleRadius) - Square( 6, thread.size.y ).center() )
            .smartExtrude( bottle.baseThickness - bottle.capThickness )
                .top( Chamfer( 2 ) )
            .bottomTo( -0.01 )

        // Forces additional perimeters near the central bar.
        val reinforce = Cube( 0.1, fingerHole.size.y + 14, thread.top - 1.2 ).centerXY()
            .bottomTo( 0.8 )

        return thread + chamfer - fingerHole - reinforce
    }

    @Piece( printable=false )
    override fun build() : Shape3d {
        val body = body().color("Green")
        val cap = cap().rotateX(180).topTo( body.top + bottle.capThickness*1.5 )
        val plug = plug().translateZ(0)

        return body + cap + plug

    }

}