Exit Full View
Up

/GardenFurniture/Workbench.foocad

Workbench
FooCAD Source Code
import static uk.co.nickthecoder.foocad.along.v2.Along.*
import static uk.co.nickthecoder.foocad.layout.v1.Layout2d.*
import static uk.co.nickthecoder.foocad.layout.v1.Layout3d.*

/*
    A bench with storage.
    Designed to be quick and easy to build, with only butt joints, and screws to hold it together.
    The sides are cladded with feather edge boards (like a fence panel).
    The shelves are just two slats, as I intend to use them as runners for large plastic containers.
    I don't intend add a back, as it will be against a wall.

Build Notes :

    * Build the two ends first
    * Attach the long pieces to form a box shape
    * Add the vertical pieces with for the door jam, and support the load.
    * Add the shelving parts. Note consider adding notches to each of the "runners"
*/
class WorkBench : Model {
    
    // The size of the box frame. The total size will be bigger (door thickness / top's overlap )
    var width = 1180
    var height = 850
    var depth = 650

    /*
        The clear Wham 60L box from wilko :
        https://www.wilko.com/en-uk/wham-crystal-60l-box-lid-5pk/p/0464546

        Alternatively the 60L box from homebase :
        https://www.homebase.co.uk/60l-heavy-duty-storage-bin/12831501.html
        //val boxSize = Vector3(630, 430, 345)
    */
    val boxSize = Vector3(600, 400, 330)

    /*
        Clear Wham 45 L from Wilko :
        https://www.wilko.com/en-uk/wham-crystal-45l-box-lid-5pk/p/0464544
    */
    val boxSize2 = Vector3(600, 400, 250)

    var shelfHeight = 430

    var doorCount = 2

    val main = Lumber( "Main", 75, 38, "Green").stockLength(400).cost( 7.36 )
    
    val thinner = Lumber( "Thinner", 38, 30, "Orange" ).stockLength( 2400).cost( 7.36/2 )

    val sheet = SheetLumber( "Marine Ply", 12 )

    // Deck boards for the sides and door, 10mm lap joints between each to allow for expansion/contraction :
    // https://www.wickes.co.uk/Wickes-Deck-Board---25mm-x-120mm-x-2-4m/p/114551
    val tag = Lumber( "deckBoard", 115, 25, "Yellow" ).stockLength( 2400 ).cost( 7.0 )
    
    // Or we could use tongue and groove, but it is the same price, and thinner and narrower!
    // https://www.wickes.co.uk/Wickes-PTGV1S-Cladding---19mm-x-94mm-x-2-4m-Pack-of-4/p/162759
    //val tag = Lumber( "tongueAndGroove", 88, 19, "Yellow" ).apply { stockLength = 2400 }

    fun box( boxSize : Vector3 ) : Shape3d {
        return ExtrusionBuilder().apply {
            crossSection( Square( boxSize.y-40, boxSize.x-40 ).center() )
            forward( boxSize.z )
            crossSection( Square( boxSize.y, boxSize.x ).center() )
        }.build()
    }

    override fun build() : Shape3d {
    

        val sideV = main.cut( height ).brighter().label("corner")
                .rightTo(depth/2).mirrorX().also()
                .rotateZ(-90).rightTo(width/2)
            
        val sideH = main.cut( depth - main.width()*2 ).darker().label("sideA")
                .alongX().centerXY()
                .topTo(height).also()
                .rotateZ(-90).rightTo(sideV.right)

        var side = sideH + sideV

        val across = main.cut(width- main.thickness()*2).label("across")
            .alongX().centerX().frontTo(-depth/2)
            .topTo(height).also()

        var mid = main.cut(height-main.width()*2).brighter().label("mid")
            .repeatX( doorCount-1, width/doorCount ).centerX().frontTo(-depth/2).bottomTo(main.width())

        val box = side.mirrorX().also() +
            across.mirrorY().also() +
            mid.mirrorY().also()

        val shelfAcross = thinner.cut( width-main.thickness()*2 ).label("shelfAcross")
            .alongX().centerX()
            .translateZ(shelfHeight).frontTo(-depth/2+main.thickness())
            .mirrorY().also()
        val shelfBack = thinner.cut(depth-main.thickness()*2).darker().label("shelfBack")
            .alongY().centerY()
            .bottomTo(shelfHeight+thinner.width())
            .repeatX( doorCount * 2, width / 6 ).centerX()
        val shelfSupport = thinner.cut(depth-main.thickness()*2).darker().label("shelfSupport")
            .alongY().centerY()
            .topTo(shelfHeight)
            .rightTo(width/2 - main.thickness()).mirrorX().also()
        val bottomShelf = thinner.cut(depth-main.thickness()*2).label("bottomShelf")
            .alongY().centerY()
            .topTo(main.width())
            .repeatX( doorCount * 2, width / 6 ).centerX()

        //val endPanel = tag.cut( height -main.width()*2 ).label("endPanel")
        //    .rotateZ(90)
        //    .bottomTo( main.width() )
        //    .tileY(5,1).centerY().leftTo( sideH.left )
        val endPanel = sheet.cut(  depth - main.width()* 2 - 2, height - main.width()*2 - 2 )
            .rotateZ(90)
            .bottomTo( main.width() ).centerY().leftTo( sideH.left )

        // Consider putting beading around the edge of the door for decoration, and so that the ply's
        // edge is protected. Cut the sheet smaller, and nail the beading around.
        // The hinges will screw right through the beading into the ply.
        val doorWidth = (width - main.width()*(doorCount-1) - main.thickness()*2) / doorCount  - 4
        //val doorPanel = tag.cut( height - main.width()*2 ).label("door")
        //    .backTo( across.back )
        //    .bottomTo( main.width() )
        //    .tileX(4,1)
        //    .tileX(doorCount,main.width()*0.9).centerX()
        val doorPanel = sheet.cut( doorWidth, height - main.width()*2 - 4 ).label("door")
            .frontTo( across.front )
            .bottomTo( main.width() )
            .tileX(doorCount, main.width()).centerX()

        val shelves = shelfAcross + shelfBack + shelfSupport + bottomShelf

        val top = sheet.cut(width+20,depth+30)
            .alongY2()
            .centerX().backTo(box.back).bottomTo(box.top)

        return top + box + shelves +
            endPanel.mirrorX().also() +
            doorPanel +
            box(boxSize).repeatX(doorCount, width/doorCount)
                .centerXY()
                .bottomTo( main.width() )
                .previewOnly() +
            box(boxSize2).repeatX(doorCount, width/doorCount)
                .centerXY()
                .bottomTo( shelfHeight + thinner.width()*2 )
                .previewOnly()

    }
}