Exit Full View
Up

/Garden/BirdHouseFeeder.foocad

BirdHouseFeeder

I never got around to making this. I have a wooden homemade bird table, which keeps my birds fed.

FooCAD Source Code
import static uk.co.nickthecoder.foocad.chamferedextrude.v1.ChamferedExtrude.*
import static uk.co.nickthecoder.foocad.extras.v1.Extras.*

class BirdHouseFeeder : Model {
    
    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")
    }

    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
    }
}