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.*
/*
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()
}
}