FooCAD Source Codeimport static uk.co.nickthecoder.foocad.along.v2.Along.*
import static uk.co.nickthecoder.foocad.extras.v1.Extras.*
import static uk.co.nickthecoder.foocad.chamferedextrude.v1.ChamferedExtrude.*
import static uk.co.nickthecoder.foocad.layout.v1.Layout2d.*
import static uk.co.nickthecoder.foocad.layout.v1.Layout3d.*
class WoodenComponentOrganiser : Model {
// The size of the inserts. Note "insertGap" is subtracted from the
// x and y sizes of the actual inserts.
// Note Racco states that the smallest A insert is 39x55x47
// Swap width and depth for inserts oriented the other way.
var unitWidth = 55
var unitDepth = 40 // NOTE this isn't 39!
var unitHeight = 46.5 // Does NOT include the feet.
var shoeHeight = 2.0
// The number of 1x1 inserts that can be fitted in a single drawer.
var drawerX = 6
var drawerY = 6
var drawerCount = 4
var baseThickness = 6
var drawerThickness = 12
// The gap between the inserts.
var insertGap = 0.5
var sliderWidth = 10
var storeyGap = 1
var extraDepth = 50
// The radius of the circles in the drawers that the feet fit into.
var shoeRadius = 9
val ply = SheetLumber( "ply", drawerThickness )
val base = SheetLumber( "base", baseThickness )
fun freeWidth() = unitWidth * drawerX
fun freeDepth() = unitDepth * drawerY
fun drawerHeight() = unitHeight + shoeHeight + insertGap + baseThickness
fun drawerWidth() = unitWidth * drawerX + drawerThickness*2
fun drawerDepth() = unitDepth * drawerY + drawerThickness*2
@Piece
fun drawer() : Shape3d {
val width = drawerWidth()
val depth = drawerDepth()
val height = drawerHeight()
val bottom = base.cut( width, depth )
.color("Orange").label("bottom")
.alongY2().center().topToOrigin()
val side = ply.cut( height - base.thickness, depth )
.color("Green").label("side")
.alongY()
.centerY().leftTo(bottom.left).mirrorX().also()
val frontBack = ply.cut( height - base.thickness, width - drawerThickness*2)
.color("Green").brighter().label("frontBack")
.alongX().centerX().frontTo(bottom.front)
.mirrorY().also()
val front = ply.cut( height, width + drawerThickness*2 + sliderWidth*2 - storeyGap * 2 )
.color("Silver").label("front")
.alongX().centerX().backTo(frontBack.front)
.translateZ(-baseThickness)
val handle :Shape3d = handle().backTo( front.front ).centerX()
.bottomTo( -baseThickness ).translateZ( height/2 )
val shoes = shoe()
.tileX( drawerX )
.tileY( drawerY )
.center()
.extrude( 1.8 )
val drawer = bottom + side + frontBack + front + handle + shoes
println( "Drawer size ${drawer.size}" )
return drawer
}
@Piece
fun corner() : Shape3d {
val x = 20
val y = 10
val t = 2
val foo = drawerThickness + sliderWidth
val profile = PolygonBuilder().apply {
moveTo( 0,0 )
lineTo( 0, y )
lineTo( -t, y )
lineTo( -t, 0 )
lineTo( -foo, 0 )
lineTo( -foo, -t )
lineTo( -foo, -t )
radius( 0 )
lineTo( x-t*2, -t )
lineTo( x, 0 )
}.build()
return profile.extrude( drawerHeight() ).color( "Purple" )
}
@Piece
fun handle() : Shape3d {
val w = 80
val t = 10
val d = 30
val profile = PolygonBuilder().apply {
moveTo( w/2, -d )
lineTo( w/2, 0 )
lineTo( w/2-t, 0 )
lineTo( w/2-t, -d+t )
lineTo(-w/2+t, -d+t )
lineTo(-w/2+t, 0 )
lineTo(-w/2, 0 )
lineTo(-w/2, -d )
}.build().roundAllCorners(1,1)
val handle = profile.chamferedExtrude( t, 1 ).color("Purple")
val holes = Cylinder( 20, 2 ).center().rotateX(90)
.translate(w/2-t/2, 0, t/2).mirrorX().also()
return handle - holes
}
@Piece
fun cabinet() : Shape3d {
val width = drawerWidth() + sliderWidth*2 + drawerThickness * 2
val depth = drawerDepth() + extraDepth + drawerThickness
val height = ( drawerHeight() + storeyGap ) * drawerCount + storeyGap
val bottom = ply.cut( width, depth + drawerThickness )
.color("Violet").label("bottom")
.alongY2().center().topToOrigin()
.translateY(-drawerThickness/2)
val side = ply.cut( height, depth )
.color("Blue").label("side")
.alongY()
.centerY().leftTo(bottom.left).mirrorX().also()
val top = ply.cut( width, depth + drawerThickness )
.color("Violet").label("bottom")
.alongY2().center().bottomTo(side.top)
.translateY(-drawerThickness/2)
val back = ply.cut( height, width - drawerThickness*2)
.color("Blue").darker().label("frontBack")
.alongX().centerX().backTo(bottom.back)
val cabinet = bottom + top + side + back
return cabinet
}
@Piece
fun shoe() : Shape2d {
val rect = Square( unitWidth, unitDepth ).center()
val corners = Circle( shoeRadius )
.translate( -unitWidth/2, -unitDepth/2 )
.mirrorX().also().mirrorY().also()
val shape = rect - corners
return shape - shape.offset( -1.8 )
}
@Piece
fun handles() = handle().tileX(2,2).tileY(2,2)
@Piece
fun corners() = corner().repeat( 8, 4, 4, 0 )
@Piece
fun shoes() = shoe()
.tileX( drawerX /2)
.tileY( drawerY /2 )
.extrude( shoeHeight )
override fun build() : Shape3d {
val cabinet : Shape3d = cabinet()
val drawer : Shape3d = drawer().translateZ( baseThickness + storeyGap )
.translateY( -extraDepth / 2 - drawerThickness/2 )
cabinet + drawer.tileZ( drawerCount, storeyGap )
return cabinet + drawer
}
}