/Electronics/JunctionBox.foocad

A junction box to connect wires. The central hole is for a short woodscrew which secures the lid. The other two holes are to screw the box to the wall, cabinet etc.
The cableGrips pieces should be printed with PETG. PLA cannot be used.
import uk.co.nickthecoder.foocad.threaded.v2.*
import uk.co.nickthecoder.foocad.screws.v3.*
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 JunctionBox : Model {
@Custom( about="Overall size of the case (not including the thickness of the lid)" )
var size = Vector3( 70, 50, 14 )
@Custom( about="Thickness of the walls" )
var thickness = 1.8
@Custom( about="Thickness of the bottom and the lid" )
var baseThickness = 1.0
@Custom( about="Thickness and height of the lip (which aligns the lid with the box)" )
var lipSize = Vector2( 1.8, 2 )
@Custom( about="Gap for the cable (in its relaxed state). Set smaller than the cable's diameter." )
var gripWidth = 2
@Custom( about="Width and height of the opening. See gripWidth" )
var openingSize = Vector2(18,6)
@Custom( about="2..4" )
var openingCount = 3
@Custom( about="Clearance which makes pieces fit together easily" )
var clearance = 0.2
meth shape() : Shape2d = Square( size.x, size.y ).center()
.roundAllCorners(5)
meth lump( height : double ) : Shape3d {
return Square( 10 ).center()
.roundAllCorners(2)
.smartExtrude( height )
.top( Chamfer(0.5) )
}
@Piece
meth box() : Shape3d {
val box = shape().cup( size.z, thickness )
.baseThickness( baseThickness )
val lumpHeight = size.z - baseThickness - lipSize.y - clearance
val lump = lump( lumpHeight )
.bottomTo( baseThickness )
val leftLump = lump.leftTo( box.left )
val sideLumps = leftLump.mirrorX().also()
val centerHole = Thread.woodScrew(1)
.threadedHole(lump.top)
val sideHoles = Circle(2)
.extrude( size.z + 0.02 )
.centerXTo( box.left + lump.size.x / 2 + lipSize.x + clearance )
.bottomTo(-0.01)
.mirrorX().also()
val slot = Cube( openingSize.x + thickness * 2, thickness + 2, size.z )
.frontTo(box.front-1)
.centerXTo( (size.x-6)/4 )
.bottomTo( baseThickness )
val frontSlots = if (openingCount > 2 ) {
slot.mirrorX().also()
} else {
slot
}
val backSlots = if (openingCount > 3 ) {
slot.mirrorY().mirrorX().also()
} else {
slot.mirrorY()
}
return box + lump + sideLumps - centerHole - sideHoles - frontSlots - backSlots
}
@Piece
meth cableGrip() : Shape3d {
val plainShape = Square( openingSize.x + 10, thickness * 3 + clearance *2 )
.center()
.roundAllCorners(1)
val cutoutShape = Square( 5 - thickness + clearance*2, thickness + clearance )
.centerY().leftTo( plainShape.left - 0.01 )
val shape = (plainShape - cutoutShape.mirrorX().also())
val solid = shape
.smartExtrude( size.z - baseThickness )
.top( Chamfer(0.5) )
val removeTop = Square( plainShape.size.x + 2, plainShape.size.y )
.extrude( solid.size.z )
.centerX()
.frontTo( thickness/2 )
.bottomTo( solid.top - lipSize.y - clearance )
val removeBack = Square( openingSize.x, solid.size.y ).centerX()
.frontTo( solid.front + thickness*2 )
.extrude( solid.size.z )
.bottomTo(-0.02)
val hole = Square( openingSize.x, plainShape.size.y + 2 )
.center()
.extrude( solid.size.z )
.bottomTo( thickness )
val gripLength = (openingSize.x - gripWidth)/2 / Math.sin( 40/180 * Math.PI )
val grips = Square( thickness, gripLength )
.extrude( openingSize.y + thickness )
.rotateZ(40)
.frontTo( solid.front )
.translateX( openingSize.x/2 )
.mirrorX().also()
val gripMinus = Cube( openingSize.x, thickness*2 + 1, thickness + 1 )
.centerX()
.frontTo( solid.front)
.bottomTo(-0.01)
return solid - hole - removeTop - removeBack + (grips - gripMinus)
}
@Piece
meth lid() : Shape3d {
val base = shape()
.smartExtrude( baseThickness )
.bottom( Chamfer(0.5) )
val lipShape = shape().offset( -thickness - clearance )
val lip = (lipShape - lipShape.offset( -lipSize.x ))
.smartExtrude( lipSize.y )
.outsideTop( Chamfer(0.5) )
.bottomTo( base.top )
val lump = lump( lipSize.y )
.bottomTo( base.top )
val leftLump = lump.leftTo( lip.left )
val sideLumps = leftLump.mirrorX().also()
val sideHoles = Countersink().mirrorZ()
.centerXTo( leftLump.middle.x )
.mirrorX().also()
val centerHole = Countersink(4,6).mirrorZ()
val opening = Square( openingSize.x-clearance*2, thickness )
.frontTo( base.front )
.centerXTo( -(size.x-6)/4 )
.extrude( size.z - openingSize.y - thickness - baseThickness - clearance )
.bottomTo( base.top )
val backOpening = if (openingCount > 2 ) {
opening.mirrorX().also()
} else {
opening
}
val frontOpening = if (openingCount > 3 ) {
opening.mirrorY().mirrorX().also()
} else {
opening.mirrorY()
}
return base + lip + lump + sideLumps - sideHoles - centerHole +
frontOpening + backOpening
}
override fun build() : Shape3d {
val box = box().color("Green")
val lid = lid().rotateY(180).topTo( box.top + baseThickness + 0 )
val grip = cableGrip()
.bottomTo( baseThickness + 0.01 )
.centerXTo( (size.x-6) / 4 )
.frontTo( box.front - thickness - clearance )
.color("Orange")
return box + grip + lid
}
}
