/Electronics/BatteryCase.foocad

Uses BatteryTube, but inside there is space for wire(s) running the
length of the tube, with an option for holes in the base for those wires.
You should probably include strain relief (to prevent wires disconnecting, or worse; short-circuiting). This could be as simple as hot glue.
import uk.co.nickthecoder.foocad.extras.v1.*
import static uk.co.nickthecoder.foocad.extras.v1.Extras.*
include BatteryTube.foocad
class BatteryCase : Model {
@Custom( about="The data for the battery size. The final tube will be wider than this." )
var tube = BatteryTube()
@Custom( about="Additional width added to `tube` to accommodate wires(s)" )
var slotSize = 2.0
@Custom( about="Number of slots in the base (0,1 or 2)" )
var baseSlotCount = 2
@Custom( about="Add threads at the bottom of the tube too?" )
var additionalThread = true
meth largerTube() : BatteryTube {
return BatteryTube().apply {
size = Vector2( tube.size.x + slotSize, tube.size.y )
thickness = tube.thickness
baseThickness = tube.baseThickness
clearance = tube.clearance
capHeight = tube.capHeight
extra = tube.extra
}
}
meth slotShape() : Shape2d {
val diameter = tube.size.x
val tube = largerTube()
val outer = Circle( tube.size.x/2 + tube.clearance + 0.1 )
val slot = Square( slotSize*2 ).centerY()
.centerXTo( outer.right )
return slot intersection outer
}
meth fillShape() : Shape2d {
val diameter = tube.size.x
val tube = largerTube()
val outer = Circle( tube.size.x/2 + tube.clearance + 0.1 )
val inner = Circle( diameter/2 + tube.clearance )
.leftTo( outer.left + 0.1 )
val slot = Square( slotSize*2 ).centerY()
.centerXTo( inner.right )
return outer - inner - slot
}
@Piece
meth body() : Shape3d {
val largerTube = largerTube()
val largeBody = largerTube.body()
val fill = fillShape()
.extrude( tube.size.y )
.bottomTo( tube.baseThickness )
val baseHole = slotShape().extrude( tube.baseThickness + 0.2 )
.bottomTo(-0.1)
val baseHoles = if ( baseSlotCount == 1 ) {
baseHole
} else if (baseSlotCount > 1) {
baseHole.mirrorX().also()
} else {
null
}
val baseThreads = largerTube.threads()
return largeBody + baseThreads + fill - baseHoles
}
@Piece
meth cap() : Shape3d {
return largerTube().cap()
}
// An example "cap" that can be screwed to the bottom of the
// body to make a torch.
// You will need a switch, and LED and a current limiting resistor.
// The resistor can be placed in-line with the body's slot.
@Piece
meth torch() : Shape3d {
val largerTube = largerTube()
val threads = largerTube.cap()
.bottomTo( -largerTube.baseThickness ) -
Cube( 100 ).centerXY().topTo(0)
val diameter = threads.size.x
val base = Square( diameter ).center()
.roundAllCorners(6)
val outside = Circle( diameter / 2 )
val thickBase = 4
val extra = ExtrusionBuilder().apply {
crossSection( base.offset(-2) )
forward(2)
crossSection( base )
forward( 8 )
crossSection()
forward( 4 )
crossSection( outside )
crossSection( -largerTube.thickness )
forward( - 2 - 8 - 4 + thickBase )
crossSection( base.offset( - largerTube.thickness ) )
}.build()
// Prevent the cap being twisted on too far.
val stops = Cube( 4, 2, 2 + 8 + 4 - thickBase )
.centerX()
.backTo( extra.back - 0.5 )
.bottomTo( thickBase )
.mirrorY().also()
val ledHole = Cylinder( 10, 5/2 + 0.2 ).center()
val switchHole = Cube( 8, 8, 4 )
.centerY()
.centerXTo( extra.right )
.bottomTo( thickBase )
return extra + stops + threads.translateZ( extra.size.z ) -
ledHole - switchHole
}
@Piece
meth all() : Shape3d {
return body().rightTo(-1) + cap().leftTo(1)
}
@Piece( print="all" )
override fun build() : Shape3d {
val body = body()
val cap = cap().rotateX(180).bottomTo( body.top + 10 )
val torch = torch()
return body + cap + torch().leftTo( body.right + 2 )
}
}

