import static uk.co.nickthecoder.foocad.layout.v1.Layout2d.* import static uk.co.nickthecoder.foocad.layout.v1.Layout3d.* include SmoothOutsideBox.foocad class Box( val width : double, val depth : double, val bh : double, val th : double ) : SmoothOutsideBox() { init { wallThickness = 1.6 lipThickness = 1.6 topChamfer = 1 height = bh topHeight = th lipHeight = 3 slack = 0.1 } override fun profile() = Square( width, depth ).center().roundAllCorners(2) override fun inset( amount : double ) = profile().offset(-amount) } /** A housing for a boost module, and a simple circuit board with (up to) 4 USB charging sockets. */ class USBCharger : Model { @Custom var socketCount = 3 @Custom var moduleCount = 1 // Must be wider if you want 4 or more outputs. @Custom var width = 65 @Custom var depth = 47 // 71 for dual buck module. @Custom var bottomHeight = 13 @Custom var topHeight = 9 // Should the power lead be fed from the side (or the back)? @Custom var sideEntry = false // Should the USB ports exit the front (or the top)? @Custom var frontExit = true // Used for debugging only. Shows the size of the boost module, as well // as the mounting holes. fun buckModule() : Shape3d { val board = Cube( 43.5, 21.5, 1.5 ).color("Green") val components = Cube(43.5, 21.5, 14).translateZ(1.5).color("WhiteSmoke") val holes = Cylinder.hole( 20, 1.5 ).translate(15,-7.5,-1) .translate(-30,15,-1).also() return (board + components).centerXY() - holes } fun box() = Box( width, depth, bottomHeight, topHeight ) @Piece fun top() : Shape3d { val box : Box = box() val top = box.build("top").color("Purple") return if ( frontExit ) { top } else { val usbHoles = Cube( 6, 13.5, 10 ).bottomTo( 4 ).center() .frontTo( -depth/2 + 4 ) .repeatX( socketCount, 2.54 * 4 ) .centerX() val sockets = Cube( 5.5, 13.5, 15).centerX() .repeatX( socketCount, 2.54 * 4 ) .previewOnly().centerXY() .frontTo(-depth/2+4).bottomTo(0) val shelf = Cube( usbHoles.size.x, 2, 16 ).centerXY().frontTo( sockets.back ) .backTo( sockets.front ).also() top - usbHoles + shelf + sockets } } @Piece fun bottom() : Shape3d { val box : Box = box() val bottom = box.build("bottom") var hole : Shape3d = Cylinder( 10, 8.5/2 ) .center() .rotateX(90) .translateZ(7) if ( sideEntry ) { hole = hole.rotateZ(90).translateX( -width/2 ).translateY( depth/2 - 8 ) //strain = strain.rotateZ(90).leftTo( -width/2 ).translateY( depth/2 - 8 ) } else { hole = hole.translateY( depth/2 ).translateX(-width/2 + 8) //strain = strain.backTo(depth/2).translateX(-width/2 + 8) } val boxWithHole = bottom - hole return if ( frontExit ) { val usbHoles = Cube( 13.5, 10, 6 ).bottomTo( 4 ).centerX() .frontTo( -box.depth/2-4 ) .repeatX( socketCount, 2.54 * 7 ) .centerX() val sockets = Cube(13.5, 15, 5.5).centerX() .repeatX( socketCount, 2.54 * 7 ) .previewOnly().centerXY() .frontTo(-depth/2).bottomTo(4) val shelf = Cube( 59, 7, 4 ).centerXY().backTo( sockets.back ) boxWithHole + shelf + sockets - usbHoles } else { boxWithHole } } override fun build() : Shape3d { return top().rotateY(180).translateZ( bottomHeight + topHeight + 1 ) + bottom() + buckModule().tileY( moduleCount, 2 ) .rightTo(width/2-4) .bottomTo( 3 ) .backTo( depth/2 - 4) .previewOnly() } }