import static uk.co.nickthecoder.foocad.changefilament.v1.ChangeFilament.* import static uk.co.nickthecoder.foocad.chamferedextrude.v1.ChamferedExtrude.* import static uk.co.nickthecoder.foocad.layout.v1.Layout2d.* import static uk.co.nickthecoder.foocad.layout.v1.Layout3d.* class JigsawSuits : Model { var pieceSize = 60 var cornerRadius = 3 var thickness = 3.0 var slack = 0.5 // Pieces are chamfered. The bottom chamfer is larger to account for elephant foot on the first layer. var chamfer1 = 0.9 var chamfer2 = 0.6 fun piece() = Square( pieceSize -slack ).center().roundAllCorners( cornerRadius ) fun extrude( piece : Shape2d ) = piece.chamferedExtrude( thickness, chamfer1, chamfer2 ) fun hole( shape : Shape2d ) = shape.translateY(-pieceSize).mirrorY().offset(slack) var heart : Shape2d = Square(1) var spade : Shape2d = Square(1) var club : Shape2d = Square(1) @Custom var pauseHalfWay = true init { val svg = SVGParser().parseFile( "JigsawSuits.svg" ) heart = svg.shapes["heart"] .leftTo(-0.1).mirrorX().also() .frontTo(-4) spade = svg.shapes["spade"] .leftTo(-0.01).mirrorX().also() .frontTo(-3) club = svg.shapes["club"] .leftTo(-0.1).mirrorX().also() .frontTo(-3) } fun heart() : Shape2d { return heart.scale( pieceSize * 0.33 / heart.size.x ) .translateY( pieceSize/2 ) } fun spade() : Shape2d { return spade.scale( pieceSize * 0.33 / spade.size.x ) .translateY( pieceSize/2 ) } fun club() : Shape2d { return club.scale( pieceSize * 0.33 / club.size.x ) .translateY( pieceSize/2 ) } fun diamond() : Shape2d { val size = pieceSize * 0.17 val diamond = Circle( size ).sides(4).translateY(size/2+2) val withSquare = (diamond + Circle( diamond.size.x ).sides(4) .scale(1,0.1).center().backTo(0)) .roundCorner( 4, 2 ) .roundCorner( 0, 2 ) return withSquare.translateY( pieceSize/2 ) } fun at( piece : Shape3d, x : double, y : double ) = piece.translate( x * pieceSize*1.4, y * pieceSize*1.4, 0 ) fun piece( top : Shape2d, left : Shape2d, bottom : Shape2d, right : Shape2d ) = extrude( piece() + top + left.rotate(90) - hole( bottom ).rotate(180) - hole( right ).rotate(-90) ) @Piece fun pieceA() = piece( heart(), club(), heart(), spade() ) @Piece fun pieceB() = piece( diamond(), spade(), diamond(), heart() ) @Piece fun pieceC() = piece( spade(), spade(), club(), heart() ) @Piece fun pieceD() = piece( diamond(), heart(), heart(), diamond() ) @Piece fun pieceE() = piece( heart(), club(), club(), diamond() ) @Piece fun pieceF() = piece( diamond(), spade(), heart(), spade() ) @Piece fun pieceG() = piece( spade(), heart(), club(), spade() ) @Piece fun pieceH() = piece( club(), diamond(),diamond(), club() ) @Piece fun pieceI() = piece( diamond(), heart(), club(), club() ) @Piece fun row1() = pieceA() + at( pieceB(), 1, 0 ) + at( pieceC(), 2, 0 ) @Piece fun row2() = at( pieceD(), 0, -1 ) + at( pieceE(), 1, -1 ) + at( pieceF(), 2, -1 ) @Piece fun row3() = at( pieceG(), 0, -2 ) + at( pieceH(), 1, -2 ) + at( pieceI(), 2, -2 ) @Piece fun holder() : Shape3d { val stack = layoutZ( 0.2, pieceA(), pieceB(), pieceC(), pieceD(), pieceE(), pieceF(), pieceG(), pieceH(), pieceI() ) val base = piece().extrude(thickness) val corner = Square( base.size.x/2 + thickness ).roundCorner( 2, cornerRadius ) .translate(-thickness, -thickness) val wall = (corner.translate( thickness, thickness ) - corner) .extrude( stack.size.z + thickness ) .color("Green") val peg = (Circle(3).sides(12) hull Circle(3).sides(12).translateX(5.5)) .rotate(120).also() .extrude( wall.size.z ) .rightTo(wall.right) .color("Orange") val pegs = peg.mirrorX().rotateZ(-90).also(2) return base + pegs + wall + stack.rotateZ(90).bottomTo( thickness ).previewOnly() } override fun build() = row1() + row2() + row3() /* override fun postProcess(pieceName : String, gcode : GCode) { if (pieceName != "holder" && pauseHalfWay) { pauseAtHeight( gcode, thickness/2, "Change Filament" ) } } */ }