FooCAD Source Codeimport uk.co.nickthecoder.foocad.extras.v1.*
import static uk.co.nickthecoder.foocad.extras.v1.Extras.*
import uk.co.nickthecoder.foocad.threaded.v2.*
import uk.co.nickthecoder.foocad.smartextrusion.v1.*
import static uk.co.nickthecoder.foocad.smartextrusion.v1.SmartExtrusion.*
class CubeSnake : Model {
var size = 20
var chamfer = 1
var holeDiameter = 4
var clearance = 0.3
var bumpSize = 1.0
meth thread() : Thread = Thread( size/2 )
meth plainCube() : Shape3d {
return Square( size ).center().roundAllCorners( chamfer, 1 )
.smartExtrude( size )
.edges( Chamfer(chamfer) )
}
@Piece
meth straight() : Shape3d {
val plain = plainCube()
val bumps = bumps().rotateX(90).translateZ(size/2)
val divots = divots().rotateZ(90)
return plain + bumps - straightHole() - divots
}
meth straightHole() : Shape3d {
return Circle( holeDiameter/2 ).safeOverhang()
.extrude(size + 2)
.rotateX(90)
.center()
.translateZ( size/2 )
}
@Piece
meth corner() : Shape3d {
val plain = plainCube()
val holeShape = Circle( holeDiameter/2 )//.safeOverhang().mirrorY()
val path = PolygonBuilder().apply {
moveTo( 0,-1 )
lineBy( 0,1 )
circularArcTo( Vector2(size/2,size/2), size/2, false, false )
lineBy( 1,0 )
}.buildPath()
val hole = holeShape.extrude(path)
.rotateX(-90)
.translateZ(size)
val bumps = bumps().translateZ(size/2)
val divots = divots()
return plain + bumps - hole - divots
}
meth bumps() : Shape3d {
val one = Sphere( 1.5 ).translate(size*0.25, size*0.25, 0 )
.topTo( size/2 + bumpSize )
return one.mirrorX().also().mirrorY().also()
}
meth divots() : Shape3d {
val one = Sphere( 1.5 + clearance ).translate(size*0.25, size*0.25, 0 )
.bottomTo( size/2 - bumpSize - clearance )
return one.mirrorX().also().mirrorY().also()
.rotateY(90).translate(0, 0,size/2)
}
meth end() : Shape3d {
val plain = plainCube()
val hole = straightHole()
val hollow = Square( size - 4 ).extrude( size - 4 ).center().bottomTo(2)
val slice = Cube( size *2 ).centerX().rotateX(45).translateY(-size/2)
val slot = Square( holeDiameter*0.6, size ).centerX().extrude(size).translateZ(size/2)
val connection = Trapezium( size -2, 2 ).angle(-30).centerX().mirrorY()
.extrude(size-4)
.backTo(hollow.back).bottomTo(2)
return plain - connection - slice - hollow - hole - slot
}
@Piece
meth endCover() : Shape3d {
val plain = plainCube()
val hole = straightHole()
val hollow = Square( size - 4 - clearance*2 ).extrude( size - 4 ).center().bottomTo(2)
val slice = Cube( size*2 ).centerX().rotateX(45).translateY(size/2-clearance)
val connection = Trapezium( size -2 - clearance*2, 2 ).angle(-30).centerX().mirrorY()
.roundCorner(3,0.3,1)
.roundCorner(2,0.3,1)
.extrude(size-2-clearance)
.backTo( hollow.back)
val connectionSupport = Square( hollow.size.x, hollow.size.y )
.leftTo( hollow.left ).frontTo( hollow.front )
.extrude( connection.size.z )
val slot = Square( hollow.size.x - 2, size ).centerX().extrude(size)
.translateZ(2)
.frontTo(hollow.front)
return plain - slice + connection + connectionSupport - slot
}
@Piece
meth endA() : Shape3d {
return end() - divots().rotateZ(90)
}
@Piece
meth endB() : Shape3d {
val bumps = bumps().rotateX(-90).translateZ(size/2)
val halfBumps = bumps - Cube( size, size - bumps.size.y, size ).centerXY()
return end() + halfBumps
}
override fun build() : Shape3d {
val endA = endA()
val corner = corner().rotateX(90).bottomTo(0).translateY( size*2 )
val straight = straight().rotateZ(-90).translate(size*1.5,size*1.5,0)
val endB = endB().rotateZ(90).translate(size*3, size*1.5,0)
val covers = endCover().translateX( size*1.5 ).translateX( size*1.5 ).also()
return endA + corner + straight + endB + covers
}
}