Exit Full View
ZipUp

/Garden/AntiBirdSpikes.foocad

AntiBirdSpikes

Add nails (or pointed plastic spikes) to stop birds perching on the top of the bird table's roof.

Needs a brim/ears for good bed adhesion.

FooCAD Source Code
import uk.co.nickthecoder.foocad.smartextrusion.v1.*
import static uk.co.nickthecoder.foocad.smartextrusion.v1.SmartExtrusion.*
import static uk.co.nickthecoder.foocad.layout.v1.Layout2d.*
import static uk.co.nickthecoder.foocad.layout.v1.Layout3d.*

class AntiBirdSpikes : Model {

    @Custom
    var roofRidgeSize = Vector3( 161, 20, 3.0 ) //Vector3(50,20,3.0)

    @Custom
    var chairBackSize = Vector3( 210, 10, 20 )

    @Custom
    var chairBackGap = 4

    @Custom
    var nailRidgeSize = Vector2( 5, 2 )

    @Custom
    var holeEvery = 7

    @Custom
    var angle = 90

    @Custom
    var headDiameter = 5.0

    @Custom
    var nailDiameter = 2.0

    @Slice( brimWidth=5 )
    @Piece
    meth withNail() : Shape3d {
        var halfAngleRadians = Math.PI/180 * angle/2
        val triangle = PolygonBuilder().apply {
            val x = roofRidgeSize.y * Math.sin( halfAngleRadians )
            val y = roofRidgeSize.y * Math.cos( halfAngleRadians )
            moveTo( -x, 0 )
            lineTo( x, 0 )
            lineTo( 0, y )
        }.build()

        val ridge = Square( nailRidgeSize.x, triangle.back + nailRidgeSize.y ).centerX()
            .roundAllCorners(1,1)

        val solid = (triangle + ridge)
            .extrude(roofRidgeSize.x).rotateX(90)
            .centerY()
        val remove = triangle.translateY(-roofRidgeSize.z / Math.sin( halfAngleRadians ))
            .extrude(roofRidgeSize.x+0.02).rotateX(90)
            .centerY()
        
        val hole = (
            Cylinder( 10, headDiameter/2 ).topTo(remove.top) +
            Cylinder( 20, nailDiameter/2 ).bottomTo(remove.top+0.2)
        ).color("Red")

        val holes = hole.repeatY( roofRidgeSize.x / holeEvery, holeEvery).centerY()


        val attachmentHoles = Cylinder( 50, nailDiameter/2 )
            .rotateY( angle/2 )
            .translateX( remove.right - roofRidgeSize.z *2 -2 )
            .frontTo( solid.front + 10 )
            .mirrorX().also().mirrorY().also()

        return solid - remove - holes - attachmentHoles
    }

    var plasticRidgeSize = Vector2( 14, 5 )

    var plasticRidgeSpacing = 6

    meth plasticRidge( length : double, height : double ) : Shape3d {

        val ridgePiece = Square( plasticRidgeSize.x, height )
            .roundCorners( listOf<int>(3,2), plasticRidgeSize.x/2, 1 )
            .scaleX(0.5)
            .extrude(1.2)
            .rotateX(90).centerXY()
            .rotateZ(90).rotateZ(90).translateZ(-2).also(2)

        return ridgePiece
            .translate( 0, plasticRidgeSpacing, plasticRidgeSize.y/2 ).also()
            .repeatY( length / plasticRidgeSpacing/2, plasticRidgeSpacing*2 )
            .centerXY()
    }

    @Slice( brimWidth=5 )
    @Piece
    meth plastic() : Shape3d {
        var halfAngleRadians = Math.PI/180 * angle/2
        val triangle = PolygonBuilder().apply {
            val x = roofRidgeSize.y * Math.sin( halfAngleRadians )
            val y = roofRidgeSize.y * Math.cos( halfAngleRadians )
            moveTo( -x, 0 )
            lineTo( x, 0 )
            lineTo( 0, y )
        }.build()

        val solid = triangle
            .extrude(roofRidgeSize.x).rotateX(90)
            .centerY()
        val remove = triangle.translateY(-roofRidgeSize.z / Math.sin( halfAngleRadians ))
            .extrude(roofRidgeSize.x+0.02).rotateX(90)
            .centerY()

        val ridge = plasticRidge( roofRidgeSize.x, solid.top + plasticRidgeSize.y )

        val attachmentHoles = Cylinder( 50, nailDiameter/2 )
            .rotateY( angle/2 )
            .translateX( remove.right - roofRidgeSize.z *2 -2 )
            .frontTo( solid.front + 10 )
            .mirrorX().also().mirrorY().also()

        return solid + ridge - remove - attachmentHoles
    }

    @Piece
    meth chairBack() : Shape3d {

        val solid = Square( chairBackSize.y, chairBackSize.z ).centerX()
            .roundCorners(listOf<int>(3,2),chairBackSize.y/2 )
            .extrude(chairBackSize.x).rotateX(90)
            .centerY()
        val remove = Square( chairBackGap, chairBackSize.z ).centerX()
            .roundCorners(listOf<int>(3,2),1,1 )
            .backTo( solid.top - 4 )
            .extrude( chairBackSize.x + 0.02 ).rotateX(90)
            .centerY()

        val ridge = plasticRidge( chairBackSize.x-1, solid.top+2.5 )

        return solid + ridge - remove 
    }

    @Piece( print="withNail" )
    override fun build() : Shape3d {
        return withNail()
    }

}