/Hardware/PaverCover.foocad

I have spare paving blocks that I like to use to weigh things down in the garden, and when woodworking. However, I don't want to damage paintwork etc.
Previously, I tried wrapping them in plastic sheets (like wrapping a present), but the plastic soon deteriorated. Hopefully, using ASA will give a long life???
This provides 3 different "covers".
- Fully cover the block (in 2 pieces
topandbottom) - Partially cover the ends (a pair of piece
sideBumper) - Partially cover the top and bottom (pieces
topBumperandbottomBumper).
While the model has custom values for the size, the location of the blocks' spacers is somewhat hard-coded, and probably will only be suitable for the 200x100x50 blocks that I used. Also note that some blocks of the same size have the spacers mirrored! Therefore, you may need to edit the code, rather than just change @Custom values for this model to work with other blocks.
import static uk.co.nickthecoder.foocad.layout.v1.Layout2d.*
import static uk.co.nickthecoder.foocad.layout.v1.Layout3d.*
import uk.co.nickthecoder.foocad.smartextrusion.v1.*
import static uk.co.nickthecoder.foocad.smartextrusion.v1.SmartExtrusion.*
import uk.co.nickthecoder.foocad.cup.v1.*
import static uk.co.nickthecoder.foocad.cup.v1.Cup.*
class PaverCover : Model {
@Custom
var size = Vector3( 200, 100, 50 )
@Custom
var clearance = 0
@Custom
var round = 4
@Custom
var chamfer = 2
@Custom
var topThickness = 0.8
@Custom
var wallThickness = 1.1
@Custom
var ribSize = Vector2( 4, 2 )
@Custom( about="height and thickness" )
var bumperSize = Vector2( 16, 2 )
// The 2D shape for the outside shape used by `top` and `bottom` pieces.
meth shape() : Shape2d = Square( size.x, size.y )
.roundAllCorners( round )
.offset( wallThickness + clearance )
.center()
// Use to remove parts for the block's spacers (small protruberances on the sides of the block).
meth brickSpacers() : Shape3d {
val rib = Square( 10, 4 )
val x = rib
.backTo( size.y / 2 )
.centerXTo( size.x/2 - 20 )
.translateX( -100 ).also()
.rotate(180).also()
val y = rib.rotate(-90)
.rightTo( size.x / 2 )
.centerYTo( -size.y / 2 + 20 )
.rotate(180).also()
return (x + y).extrude( size.z )
}
// Ribs inside pieces `top` and `bottom` so that the brick fits snuggly inside
// The ribs are the same size as the block's spacers.
meth ribs( height : double ) : Shape3d {
val rib = Square( ribSize )
.roundCorner(1, 1, 1)
.roundCorner(0, 1 ,1)
.extrude( height - topThickness )
.bottomTo( topThickness )
val x = rib
.repeatX( 5, size.x * 0.2 ).rightTo( size.x/2 - 12 )
.backTo( size.y/2 + clearance )
.rotateZ(180).also()
val y = rib.rotateZ(-90)
.repeatY( 3, size.y * 0.4 )
.centerY()
.rightTo( size.x/2 + clearance )
.rotateZ(180).also()
return x + y
}
// When combined with `bottom`, fully encloses the block.
@Piece
meth top() = top( size.z / 2 + topThickness )
meth top( height : double ) : Shape3d {
return Cup( shape(), height, wallThickness )
.baseThickness( topThickness )
.insideTop( Chamfer(-ribSize.y,ribSize.y) )
.bottom( Chamfer( chamfer ) ) +
ribs( height ).mirrorX() -
brickSpacers().mirrorX().bottomTo( topThickness + chamfer )
}
// When combined with `top`, fully encloses the block.
@Piece
meth bottom() = bottom( size.z / 2 + topThickness )
@Piece
meth bottom( height : double ) : Shape3d {
return Cup( shape(), height, wallThickness )
.baseThickness( topThickness )
.insideTop( Chamfer(-ribSize.y,ribSize.y) )
.outsideBottom( Chamfer( 0.5 ) ) +
ribs( height ) -
brickSpacers().bottomTo( topThickness )
}
// Used to test the fit without printing a complete cover.
@Piece
meth test() : Shape3d {
size = Vector3( size.x, size.y, 10 )
return top() -
Cube( size.x * 0.9, size.y * 0.8, 10 ).center()
}
@Piece
meth topBumper() = top( 12 ) -
Square( size.x * 0.9, size.y*0.8 ).roundAllCorners(5).extrude( size.z ).center()
@Piece
meth bottomBumper() = bottom( 12 ) -
Square( size.x * 0.9, size.y*0.8 ).roundAllCorners(5).extrude( size.z ).center()
@Piece
meth sideBumper() : Shape3d {
val shape = Square( size.z, size.y - ribSize.y )
.roundCorner( 3, chamfer, 1 )
.roundCorner( 2, 0.5 )
.roundCorner( 1, 0.5 )
.roundCorner( 0, chamfer, 1 )
.offset( clearance + bumperSize.y )
.center()
val main = Cup( shape, bumperSize.x, bumperSize.y )
.outsideBottom( Chamfer( bumperSize.y *0.7 ) )
val rib = Square( size.z, ribSize.x )
.center()
.extrude( ribSize.y )
.backTo( -size.y/2 + 10 )
.bottomTo( bumperSize.y )
val hole = Square( size.z, size.y ).offset( -10 )
.roundAllCorners(5)
.extrude( size.z )
.center()
return main + rib - hole
}
@Piece( printable=false )
override fun build() : Shape3d {
val bottom = bottom()
val top = top().rotateX(180).translateZ( size.z*2 )
//.previewOnly()
val block = Square( size.x, size.y ).offset( -ribSize.y )
.center()
.roundAllCorners( round )
.extrude( size.z )
.bottomTo( topThickness ).previewOnly()
val sideBlock = block
.rightTo( block.left - 20 )
.bottomTo( bumperSize.y )
val sideBumpers = sideBumper()
.rotateY(90)
.bottomTo(0)
.leftTo( block.left - bumperSize.y )
.centerYTo( sideBlock.middle.y )
.mirrorX().also()
.centerXTo( sideBlock.middle.x )
val block3 = block
.leftTo( block.right + 20 )
val topBumper = topBumper()
.rotateY(180)
.centerXTo( block3.middle.x )
.topTo( block3.top + topThickness*2 )
val bottomBumper = bottomBumper()
.centerXTo( block3.middle.x )
return bottom + top + block +
sideBlock + sideBumpers +
block3 + topBumper + bottomBumper
}
}
