/Bottles/BirdSeedContainer2.foocad

Containers for bird seed, and other bird food.
If you need a rectangular (not-square) bottle, then ensure that the size.x > size.y
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
}
}
