/Furniture/LaptopBase.foocad

I have a laptop, and want to place it on top of my lap. However, in summer under heavy load, it gets too hot.
So, I want a "tray" for the laptop to sit on, with plenty of air-flow below it, instead of it sitting directly on my lap.
Bolt the four piece to a piece of plywood, which is approximately the same size as the laptop.
Either use round-head wood screws, or machine screws with metal insert placed into the plywood.
I prefer the latter, but my inserts are slightly too long, so I cover them up with piece holeCover.
import uk.co.nickthecoder.foocad.smartextrusion.v1.*
import static uk.co.nickthecoder.foocad.smartextrusion.v1.SmartExtrusion.*
import static uk.co.nickthecoder.foocad.extend.v1.Extend.*
import uk.co.nickthecoder.foocad.extras.v1.*
import static uk.co.nickthecoder.foocad.extras.v1.Extras.*
class LaptopBase : Model {
@Custom( about="Size of the blocks (z does not include the walls)" )
var cornerSize = Vector3( 20, 40, 12 )
@Custom( about="Size of the blocks (z does not include the walls)" )
var edgeSize = Vector3( 14, 40, 12 )
@Custom( about="Thickness and height of the walls" )
var cornerWallSize = Vector2( 4, 2 )
@Custom( about="width and depth of an extra chamfer for the laptop to sit within" )
var cornerChamfer = Vector2( 8, 5 )
@Custom( about="Thickness and height of the walls" )
var edgeWallSize = Vector2( 6, 4 )
@Custom( about="width and depth of an extra chamfer for the laptop to sit within" )
var edgeChamfer = Vector2( 1, 1 )
@Custom( about="Diameter of the bolts e.g. 6.0 for M6 bolts" )
var boltDiameter = 6.0
@Custom( about="Length, thickness and height of the sloted part" )
var slotSize = Vector3( 10, 7, 6 )
@Custom
var radius = 4
meth corner() : Shape3d {
val shape = Square( cornerSize.x, cornerSize.y )
.roundCorner(2, Math.min( cornerSize.x, cornerSize.y )*0.8, 1 )
val roundedShape = shape.roundAllCorners(radius)
val main = roundedShape
.extrude( cornerSize.z + cornerWallSize.y + cornerChamfer.y )
val remove = Square( 100 ).translate( cornerWallSize.x, cornerWallSize.x )
.smartExtrude( cornerWallSize.y + cornerChamfer.y )
.bottom( Chamfer(cornerChamfer.x, cornerChamfer.y) )
.topTo( main.top + 0.01 )
val slotShape = Hull2d( Circle( boltDiameter/2 ).translateX( slotSize.x + cornerSize.x ).also())
val slot = slotShape.ring( slotSize.y )
.smartExtrude( slotSize.z )
.top(Fillet(1))
.bottom(Chamfer(0.5))
.leftTo( 0 ).centerYTo( main.middle.y )
return main -remove + slot
}
meth edge() : Shape3d {
val width = Math.max( edgeSize.x, edgeSize.y )
val depth = Math.min( edgeSize.x, edgeSize.y )
val main = Square( width, depth ).centerX()
.roundAllCorners(radius)
.extrude( edgeSize.z + edgeWallSize.y + edgeChamfer.y )
val remove = Square( 100 )
.centerX().backTo( main.back - edgeWallSize.x )
.smartExtrude( edgeWallSize.y + edgeChamfer.y )
.bottom(Chamfer(edgeChamfer.x,edgeChamfer.y))
.topTo( main.top + 0.01 )
val slotShape = Circle( boltDiameter/2 ).extendY( slotSize.x/2 + depth/2 )
val slot = slotShape.ring( slotSize.y )
.smartExtrude( slotSize.z )
.top(Fillet(1))
.bottom(Chamfer(0.5))
.backTo( main.back )
return main - remove + slot
}
@Custom
var coverSize = Vector2( 30, 2 )
@Custom
var coverRecess = Vector2( 20, 1 )
@Piece
meth holeCover() : Shape3d {
val main = Circle( coverSize.x/2 )
.smartExtrude( coverSize.y )
.bottom( Chamfer( coverSize.y/3 ) )
val recess = if (coverRecess.x > 0 && coverRecess.y > 0) {
Circle( coverRecess.x/2 )
.smartExtrude( coverRecess.y )
.top( Chamfer( coverRecess.y/3 ).reverse() )
.topTo( main.top + 0.01 )
} else {
null
}
return main - recess
}
override fun build() : Shape3d {
val board = Cube( 300, 200, 12 )
.centerXY()
.previewOnly()
val corners = corner()
.leftTo( board.left )
.frontTo( board.front )
.mirrorX().also()
.bottomTo( board.top )
val edges = edge()
.backTo( board.back )
.centerXTo( board.size.x * 0.35 )
.mirrorX().also()
.bottomTo( board.top )
val holeCover = holeCover()
.topTo( board.bottom - 0.01 )
return board + corners + edges + holeCover
}
}