FooCAD Source Codeimport static uk.co.nickthecoder.foocad.extend.v1.Extend.*
import uk.co.nickthecoder.foocad.hinge.v1.*
import uk.co.nickthecoder.foocad.extras.v1.*
import static uk.co.nickthecoder.foocad.extras.v1.Extras.*
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.*
import static uk.co.nickthecoder.foocad.layout.v1.Layout2d.*
import static uk.co.nickthecoder.foocad.layout.v1.Layout3d.*
include ComponentOrganiser.foocad
class ComponentOrganiserCase: Model {
@Custom
var size = Vector2( 4, 4 )
@Custom
var baseThickness = 1.2
@Custom
var thickness = 1.2
@Custom
var lipSize = Vector2(1.2, 6)
@Custom
var hinge = Hinge( 40 ).chamfer(0.5)
@Custom
var lidThickness = 1.2
@Custom
var lidClearance = 0.2
// The same diameter bolt is also used for the handle (but the length is different).
@Custom( about="Defines the bolt length & diameter and the distance of the latch" )
var hingedLatch = HingedLatch()
.boltSize( Vector2(20, 3.9) )
.distance( 24 ) // Original was 25.
.ribSize( Vector3(3, 6, 35) )
.chamfer(0.5)
//.realBolt(true) // Uncomment to test the alignment of the holes.
@Custom
var handleSize = Vector3( 100, 33, 8 )
meth handleHinge() = Hinge( handleSize.z * 2 )
.innerDiameter( hingedLatch.boltSize.y )
.outerDiameter( handleSize.z + 2 )
.chamfer(0.5)
meth componentOrganiser() = ComponentOrganiser().apply {
drawerX = size.x
drawerY = size.y
}
meth internalSize() : Vector2 {
val co = componentOrganiser()
return Vector2(
size.x * co.unitWidth + (size.x-1) * co.insertGap,
size.y * co.unitDepth + (size.y-1) * co.insertGap
)
}
meth insideShape() : Shape2d {
return Square( internalSize() )
.roundAllCorners(4)
.center()
}
meth hingePositionFromBoxTop() = -1
@Piece
meth box() : Shape3d {
val co = componentOrganiser()
val bottomPattern = co.drawerBottom().centerXY().bottomTo( baseThickness ).color("Green")
val inserts = co.insert(1,1)
.tileX( size.x, co.insertGap )
.tileY( size.y, co.insertGap )
.centerXY()
.previewOnly()
.bottomTo( bottomPattern.top )
val inside = insideShape()
val outside = inside.offset( thickness )
val lip = ProfileEdge.chamferedStep( lipSize.x, lipSize.y ).reverse() and
ProfileEdge.chamfer(0.5)
val height = baseThickness + bottomPattern.size.z + co.unitHeight
val box = outside
.cup( height, thickness )
.baseThickness( baseThickness )
.bottom( Chamfer( 1 ) )
.outsideTop( lip )
.label("plainBox")
println( "Plain case = $box" )
val hinges = hinge.forBox( outside.back, height + hingePositionFromBoxTop() )
.centerXTo( inside.left + hinge.length*0.8 )
.mirrorX().also().withCavities()
val latchRibs = hingedLatch.ribs()
.centerXTo( inside.left + 30 )
.translateZ( height - hingedLatch.distance -2.5) // Positioned by eye.
.backTo( outside.front + hingedLatch.chamfer )
.label( "latchRibs" )
.mirrorX().also()
//println( "Handle bolt length = ${latchRibs.find("latchRibs").size.x}" )
val handleHinge = handleHinge().forBox( 0, box.top/2 + 6 )
.mirrorY()
val handleMount = Square( handleHinge.size.x + 4, height-2 ).centerX()
.smartExtrude( lipSize.x )
.top( Chamfer(lipSize.x) )
.rotateX(90)
.backTo( outside.front )
.bottomTo( 1 )
.translateX( handleSize.x / 2 - handleSize.z/2 )
val forHandle = (
handleMount +
handleHinge
.centerXTo( handleMount.middle.x )
.backTo( handleMount.front + handleHinge().chamfer )
).label("forHandle").mirrorX().also()
println( "box and hinges.find = ${(box and hinges).find("plainBox")}" )
return (box and hinges) + latchRibs + bottomPattern + forHandle // + inserts
}
@Piece
meth lid() : Shape3d {
val co = componentOrganiser()
val inside = insideShape()
val outside = inside.offset( thickness )
val boxShape = outside.offset( lipSize.x )
val chamfer = 1
val lip = ProfileEdge.chamferedStep( lipSize.x, lipSize.y ).reverse() and
ProfileEdge.chamfer(0.5)
val height = lidThickness + lipSize.y
val cup = boxShape.offset( lidThickness + 1 )
.cup( height, 1 )
.baseThickness( lidThickness )
.bottom( Chamfer( chamfer ) )
val lid = cup -
Cube( cup.size.x, cup.size.y, cup.size.y )
.centerX()
.rotateX(45)
.translateY( cup.back )
val hinges = hinge.forLid( outside.back, lidThickness + lidClearance - hingePositionFromBoxTop() )
.centerXTo( inside.left + hinge.length*0.8 )
.mirrorX().also().withCavities()
val pattern = co.lidPattern()
.extrude(2) // Original was 3.
.bottomTo( lidThickness )
val latchMount = Square( hingedLatch.hinge().length + 6, 2 + chamfer)
.roundCorner( 1, chamfer,1 )
.roundCorner( 0, chamfer,1 )
.centerX()
.smartExtrude( height )
//.edges( Chamfer( chamfer/2 ) )
.backTo( lid.front + chamfer )
val latchHinges = (
hingedLatch.forLid( latchMount.front+chamfer, height-2 ) and
latchMount
)
.centerXTo( inside.left + 30 )
.mirrorX().also()
return ((lid and hinges and latchHinges ) + pattern)
}
@Piece
meth handle() : Shape3d {
val handleHinge = handleHinge()
val shape = PolygonBuilder().apply {
moveTo( 0, handleSize.z/2 )
radius(10)
lineBy( 0, -handleSize.y + handleSize.z/2 )
lineBy( handleSize.x - handleSize.z, 0 )
radius(0)
lineBy( 0, handleSize.y - handleSize.z/2 )
}.buildPath().thickness( handleSize.z ).centerX()
val main = shape.smartExtrude( handleSize.z )
.bottom( ProfileEdge.roundedChamfer( handleSize.z/2 ) )
.top( Fillet( handleSize.z/2-1) )
val holes = Circle( handleHinge.innerDiameter/2 + 0.2 ).safeOverhang().rotate(90)
.extrude( handleSize.x + 2 )
.rotateY(90)
.centerX()
.centerZTo( handleSize.z / 2 )
return main - holes
}
@Piece
@Slice( seamPosition="rear" )
meth latch() = hingedLatch.latch()
@Piece( printable=false )
override meth build() : Shape3d {
val box = box()
val plainBox = box.find("plainBox")
val axis = Vector3( 0, box.back - hinge.outerDiameter/2, box.size.z - hinge.outerDiameter/2)
val lid = lid().mirrorZ()
.topTo( plainBox.top + lidThickness + lidClearance )
.color("Green")
val latches = latch()
.rotateZ(4 - 0) // 4° is the closed position.
.rotateX(90).rotateZ(90)
.translateY( box.front+4 )
.centerXTo( box.left + 32.5 )
.translateZ( lid.top - 4 )
.mirrorX().also()
.color("Violet")
val handle = handle().rotateX(90)
.backTo( plainBox.front - 1 )
.bottomTo(2)
.color("lightBlue")
val rotatedLid = (lid + latches).rotateAxisAbout( 60, Vector3( 1,0,0 ), axis )
return box + rotatedLid + handle
}
}