/Garden/BirdHouseFeeder.foocad

I never got around to making this. I have a wooden homemade bird table, which keeps my birds fed.
import static uk.co.nickthecoder.foocad.chamferedextrude.v1.ChamferedExtrude.*
import static uk.co.nickthecoder.foocad.extras.v1.Extras.*
class BirdHouseFeeder : AbstractModel() {
val glass = Vector3( 150, 120, 4 )
var gap = 20
var extra = 3
var exit = 7
var baseMargin = 30
var roofMargin = 20
var troughDepth = 4
var slack = 0.3
fun glass() = Cube( glass )
fun side() : Shape3d {
val profile = Square( extra*2, gap + glass.z*2 + slack*4 + extra*2 )
.center()
.roundCorner(3,2,1)
.roundCorner(0,2,1)
val side = profile.extrude( glass.y + exit + 25 )
val pointed = Cube( side.size.x * 2, side.size.Z, side.size.z ).center().rotateX(45).topTo(side.top)
val groove = Cube( extra * 2, glass.z + slack*2, side.size.z )
.backTo( -gap/2-slack )
.bottomTo( exit + troughDepth)
val grooves = groove.mirrorY().also()
val grometHole = Cylinder( 100, grometD/2 ).center().rotateY(90)
.centerZTo(side.top - grometOffset )
return (side/pointed - grooves - grometHole ).color("Green")
}
@Piece
fun printTop() = top().mirrorZ().bottomTo(0)
fun top() : Shape3d {
val flat = Square( glass.x - extra*2, gap + glass.z*2 + slack*4 + extra*2 ).center()
.extrude( extra * 2 )
.color("LightGreen")
val groove = Cube( flat.size.x * 2, glass.z + slack*2, extra * 2).centerXY()
.frontTo(gap/2)
val grooves = groove.mirrorY().also().topTo( extra )
val hole = Square( gap * 2, gap-4 ).roundAllCorners(4)
.chamferedExtrude(flat.size.z+2, 0, -6)
.center().bottomTo(-1)
return flat - grooves - hole
}
fun base() : Shape3d {
val profile = Square( glass.x + baseMargin*2, gap + glass.z*2 + baseMargin*2 )
.roundAllCorners( 12, 1 )
val base = profile.chamferedExtrude( 12, 0, 2 )
.centerXY()
.color("DimGrey")
val margin = 0
val troughP = Square( glass.x + margin*2, gap + glass.z*2 + slack*4 + extra*2 + margin*2)
.roundAllCorners( 0, 1 )
.center()
val trough = troughP.extrude( troughDepth )
.topTo( base.top )
return base - trough
}
fun roof() : Shape3d {
val half = Cube( glass.x + roofMargin*2, 80, 12 ).centerX()
.topTo(0)
.rotateX(-45)
.bottomTo(0)
val mitred = half / Cube( half.size.x, half.size.y, half.size.z ).centerX().translateY(1)
return mitred.mirrorY().also()
}
@Piece
fun baseAndSides() : Shape3d {
val base : Shape3d = base()
val pane = Cube( glass ).centerX()
.rotateX(90)
.translateY(-gap/2)
.bottomTo(exit+ base.top)
.previewOnly()
val panes = pane.mirrorY().also()
val side : Shape3d = side()
.rightTo( pane.left + extra )
.bottomTo(base.top - troughDepth)
// A flying butress
val buttresSize = 60
val buttress = (Square(buttresSize) - Circle(buttresSize).centerTo(buttresSize,buttresSize))
.extrude(1.5)
.rotateX(90)
.centerY()
.leftTo(side.right)
.bottomTo( side.bottom )
.mirrorX().also()
// Force extra perimeters where the edge joins to the base, giving extra strength.
val pins = Cube(0.1,4, 30).centerXY()
.centerXTo(side.middle.x).frontTo(side.front+2)
.mirrorY().also()
.mirrorX().also()
.bottomTo(0.4)
return base + side.mirrorX().also() + buttress + panes - pins
}
var grometD = 10
var grometOffset = 30
@Piece
fun eve() : Shape3d {
val tri = Triangle( 60, 60 ).rotate(-45) -
Circle( grometD/2 ).translateX(grometOffset)
return tri.chamferedExtrude(3.0,0,1)
.color("GhostWhite")
}
@Piece( printable = false )
override fun build() : Shape3d {
val base : Shape3d = base()
val pane = Cube( glass ).centerX()
.rotateX(90)
.translateY(-gap/2)
.bottomTo(exit+ base.top)
.previewOnly()
val panes = pane.mirrorY().also()
val side : Shape3d = side().bottomTo(base.top - troughDepth)
val sides = side.rightTo( pane.left + extra ).mirrorX().also()
val top : Shape3d = top().bottomTo( pane.top - extra )
val eves = eve().rotateY(90).topTo( side.top ).leftTo(sides.right)
.mirrorX().also()
val roof : Shape3d = roof().topTo( eves.top+17)
return base + sides + roof + top + eves + panes
}
}

