Exit Full View
Up

/GardenFurniture/later/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.*
/*
Work benches, which I plan to place in front of my shed.

I could have a shorter, narrowed, single door version, which is sandwiched between another pair,
and place a chop saw on the lower bench.

The doors can be finished with tongue and groove, with a trim around the edge.

The floor could be more tongue and groove, or plywood.
*/

class WorkBench : Model {
    
    var length = 1200
    var width = 800
    var height = 800

    var legLumber = Lumber( "Leg", 50, 50, "Blue" )
    var supportLumber = Lumber( "Support", 50, 38, "Grey" )
    var boardLumber = Lumber( "Board", 110 - 5, 15, "ForestGreen" ) // Tongue and groov
    var footLumber = Lumber( "Foot", 120, 25, "LightGreen" )
    var doorJamLumber = Lumber( "DoorJam", 40, 40 ) // Must be thicker than the door!
    var trimLumber = Lumber( "Trim", 40, 18, "Orange" )
    var topLumber = Lumber( "Top", width + 100, 12, "White" )

    @Custom
    var explode = 0

    override fun build() : Shape3d {

        val lap1 = 15
        val lap2 = supportLumber.thickness()-lap1

        val upright = legLumber.cut( height )
            .cutZRatio( LapJoint( legLumber, 0 ).depth( lap1 ), 0 )
            .cutZRatio( LapJoint( legLumber, 0 ).depth( lap1 ), 1 )
            .cutZRatio( LapJoint( legLumber, 1 ).depth( lap1 ), 0 )
            .cutZRatio( LapJoint( legLumber, 1 ).depth( lap1 ), 1 )
            .label( "upright" )
            .rotate(0,0,90)
            .translate( length/2, -width/2 - explode, 0 )

        val frontBack = supportLumber.cut( width )
            .cutZRatio( LapJoint( supportLumber, 3 ).depth( lap2 ), 0 )
            .cutZRatio( LapJoint( supportLumber, 3 ).depth( lap2 ), 1 )
            .label( "frontBack" )
            .alongY().rotate(0,90,0)
            .translate(length/2-supportLumber.thickness(),0,supportLumber.width() - explode).centerY()

        val boardCount = Math.floor(height/boardLumber.width())
        val endBoard = boardLumber.cut( width )
            .label( "endBoard" )
            .alongY2().rotate(0,-90,0)
            .centerY().translate( length/2+ boardLumber.thickness(),0,0)

        val end = upright.mirrorY().also() +
            frontBack.translate( 0,0, height - frontBack.size.z + explode*2 ).also() +
            endBoard.repeatZ( boardCount, boardLumber.width() + 5 )

        val back = boardLumber.cut( length + boardLumber.thickness() * 2 )
            .label( "back" )
            .alongX()
            .repeatZ( boardCount,  boardLumber.width() + 5 )
            .centerX().translate(0,width/2 + explode,0)
            .darker()

        val diagonal = supportLumber.cut( 300 )
            .cutZRatio( MitreJoint( supportLumber, 1 ), 0 )
            .cutZRatio( MitreJoint( supportLumber, 1 ).otherEnd(), 1 )
            .label( "diagonal" )
            .alongY().rotate(0,0,45)
            .translate(-length/2+ 217,-width/2,0)
            .mirrorX().also().mirrorY().also().darker()

        val across = supportLumber.cut( length - lap1*2 )
            .cutZRatio( LapJoint( supportLumber, 3 ).depth( lap2 ).length(lap2), 0 )
            .cutZRatio( LapJoint( supportLumber, 3 ).depth( lap2 ).length(lap2), 1 )
            .label( "across" )
            .alongX().translate(0,-width/2 - explode,0).centerX()

        val mid = supportLumber.cut( length - supportLumber.thickness()*2 )
            .label( "mid" )
            .alongX().centerX().centerY()
            .darker()

        val foot = footLumber.cut( 140 )
            // Cut a notch out of the foot so that it supports the front/back rails.
            .cutZRatio( LapJoint( footLumber, 0 ).depth(40).length(30), 0 )
            .alongY().rotate(0,90,0)
            .translate(-length/2+ supportLumber.thickness(),-width/2+10,40 - explode)

        val doorHeight = height - 40
        val doorWidth = length/2 + boardLumber.thickness() - doorJamLumber.width() - 10

        val doorJam = doorJamLumber.cut( doorHeight )
            .label( "doorJam" )
            .translate( -length/2- boardLumber.thickness(), -width/2- doorJamLumber.thickness(), 0 )

        val doorUpright = trimLumber.cut( doorHeight )
            .cutZRatio( LapJoint( trimLumber, 3 ), 0 )
            .cutZRatio( LapJoint( trimLumber, 3 ), 1 )
            .label( "doorUpright" )

        val doorAcross = trimLumber.cut( doorWidth )
            .cutZRatio( LapJoint( trimLumber, 1 ), 0 )
            .cutZRatio( LapJoint( trimLumber, 1 ), 1 )
            .label( "doorAcross" )
            .alongX()
            .translate( 0,0, -explode/2 )

        val door = doorUpright.translate( doorWidth - trimLumber.width(), 0, 0 ).also() +
            doorAcross.translate( 0, 0, doorHeight - trimLumber.width() + explode ).also()
        
        val top = topLumber.cut( length + 60 )
            .label( "top" )
            .alongX().rotate( 90,0,0 )
            .centerX().translate( 0, width/2 + boardLumber.thickness(), height + explode)

        val positionedDoor = door
            .rotate(0,0,-80).translate( -doorWidth, -width/2-trimLumber.thickness() - explode*2, 0 )

        return end.translate(explode,0,0).mirrorX().also() +
            across.mirrorY().also().translate( 0,0, height - across.size.z ).also() +
            mid +
            foot.mirrorY().also().mirrorX().also() +
            back +
            diagonal.translate( 0,0, height - diagonal.size.z ).also() +
            doorJam.mirrorX().also() +
            positionedDoor.mirrorX().also() +
            top
    }

}