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