FooCAD Source Codeimport 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
}
}