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.* import uk.co.nickthecoder.foocad.threaded.v1.Threaded import static uk.co.nickthecoder.foocad.threaded.v1.Threaded.* class SpringoSnowman : Model { // If the layers fuse together too much, adjust the gap. // I believe there is "aliasing" between the gap and the layer height. // The gap should be slightly less than a multiple of your layer height. // Look at the print, and you may see some parts have a clear gap, whereas // other places look fused. You want a very small "fused" section. // NOTE. Each slicer may give different results. I use slic3r. @Custom var gap = 0.39 // The height of one piece of the slinky spring (including the gap). // If this is an exact multiple of the layer height, then the alias // artifacts described above line up. // I haven't investigated adjusing this. @Custom var pitch = 2.0 // The difference between the outer and inner radius. @Custom var thickness = 2 @Custom var slack = 0.3 // False if you want to drill holes for facial features yourself. @Custom var includeHoles = true // A small springo to help tune the gap and other settings before printing // the complete snowman. @Piece fun test() = Cylinder( 10, 20 ) - Cylinder( 12, 20-thickness ).translateZ(-1) - Threaded.springo( 60, 10, pitch, gap ) @Piece fun springoSnowman() = snowman() - Threaded.springo( 70, 72, pitch, gap ) @Piece fun printNode() = nose().mirrorZ() @Piece fun eyes() = eye().tileX(2, 1) @Piece fun springoHat() = hat() - Threaded.springo( 30, 8, pitch, gap ).translateZ(2) fun nose() : Shape3d { return Cylinder( 4, 2 ) + Cylinder( 12, 3, 1 ).translate(0,1,4) .color("Orange") } fun eye() : Shape3d { return Cylinder( 4, 2 ) + Sphere( 2.5 ).translateZ( 4 ).color("DarkSlateGray") } fun hat() : Shape3d { val brim = Circle( 17 ).chamferedExtrude(2,0,0.5).color( "DimGray" ) val main = Circle( 12 ).chamferedExtrude( 12,0,1 ).color( "DimGray" ) val hole = Circle( 10 ).internalChamferedExtrude( 11,1,0 ).color("Red") return (brim + main - hole) } fun snowman() : Shape3d { var head : Shape3d = Sphere( 16 ).translateZ(84) if ( includeHoles ) { val eyeHoles = Cylinder( 10, 2 ) .translateZ(-3).rotateX(-88).translateY(14).rotateZ(200) .translateZ(88) .mirrorX().also() val noseHole = Cylinder( 10, 2 ) .translateZ(-3).rotateX(90).translate( 0, -16, 83 ) head = head - eyeHoles - noseHole } val body = Sphere( 30 ).translateZ(20)/Cube(80).centerXY() + Sphere( 22 ).translateZ( 53 ) - Sphere( 30-thickness ).translateZ(20) - Sphere( 22-thickness ).translateZ(53) val snowman = body + head - Cylinder( 25, 12 -thickness ).translateZ(84-16) val springo = snowman return springo } override fun build() : Shape3d { return snowman() + nose().translateZ(-3).rotateX(90).translate( 0, -14, 83 ) + eye().translateZ(-3).rotateX(-90).translateY(14).rotateZ(200) .translateZ(88) .mirrorX().also() + hat().translateZ( 96 ) } }