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 } }