/Hardware/ShelfBracketWithKeyholes.foocad

A basic shelf bracket without visible screw holes. Keyholes on both surfaces. Therefore the shelf can be removed by sliding it forwards, and the bracket can be removed from the wall by sliding it up.
Designed for shelves in the garden. I want to remove the shelf easily without tools.
import uk.co.nickthecoder.foocad.smartextrusion.v1.*
import static uk.co.nickthecoder.foocad.smartextrusion.v1.SmartExtrusion.*
import uk.co.nickthecoder.foocad.screws.v3.*
include ShelfBracket.foocad
class ShelfBracketWithKeyholes : PlainShelfBracket() {
var keyhole = KeyholeHanger()
init {
//overlap = 3
//depth = 200
}
@Piece
meth bracket() : Shape3d {
val plain = plainBracket()
val wallHole = keyhole
.horizontal()
.mirrorY()
.centerZTo( width/2 )
.backTo( height() - thickness*2 )
val wallMark = Cube( 0.4, 0.4, wallHole.bottom )
.bottomTo( 1 )
.centerYTo( wallHole.front + keyhole.holeDiameter )
.topTo( plain.top - 1 ).also()
.color("red")
val wallHoleWithMark = wallHole + wallMark
val wallHoles = wallHoleWithMark
.frontTo( thickness + round ).also()
val shelfHoles = wallHoleWithMark
.rotateZ(90).mirrorX()
.leftTo( thickness*2 )
.rightTo( plain.right - thickness - round ).also()
return plain - wallHoles - shelfHoles
}
var footSize = 30
var clearance = 0.2
@Piece
meth footConnector() : Shape3d {
val shape = Circle( footSize/2 )
val topShape = (shape intersection shape.translateX(-footSize/4)).toPolygon()
val bottom = shape
.smartExtrude(4)
.edges(Chamfer(chamfer))
val top = topShape
.extrude( thickness + clearance + chamfer )
.bottomTo( bottom.top-chamfer )
val hole = Countersink()
.mirrorZ()
.centerXTo( top.middle.x )
return bottom + top - hole
}
@Piece
meth footPlain() : Shape3d {
val foot = Circle( footSize/2 )
.smartExtrude( 4 + thickness + clearance )
.bottom( Chamfer( chamfer ) )
val hole = Countersink()
.mirrorZ()
return foot - hole
}
@Piece( print="bracket" )
override meth build() : Shape3d {
depth = 200
val shelf = Cube( 240, 400, 20 ).centerXY().previewOnly()
val bracket = bracket()
.rotateX(90)
.mirrorZ()
.leftTo( shelf.left )
val brackets = bracket.translateY( 300 ).also().centerY()
val connectors = footConnector()
.topTo(0)
.rotateZ(90)
.leftTo( shelf.left + 20 )
.backTo( brackets.back -width +6 )
.mirrorY().also()
val plainFeet = footPlain()
.topTo(0)
.rightTo( shelf.right - 20 )
.backTo( brackets.back -width )
.mirrorY().also()
val shelfAndFeet = ( shelf + connectors + plainFeet )
//.translateX(35).rotateZ(10)
return brackets + shelfAndFeet
}
}
