import uk.co.nickthecoder.foocad.extras.v1.* import static uk.co.nickthecoder.foocad.extras.v1.Extras.* import static uk.co.nickthecoder.foocad.layout.v1.Layout2d.* import static uk.co.nickthecoder.foocad.layout.v1.Layout3d.* class SnailKiller : Model { @Custom var size = Vector3( 60, 50, 40 ) @Custom var thickness = 2 @Custom( about="Diameter and height of the nail's head" ) var nailHeadSize = Vector2( 4, 1 ) @Custom var nailSpacing = 7 @Custom var clearance = 0.5 meth layoutNails( shape : Shape2d ) : Shape2d { val across : int = size.x / nailSpacing val down : int = size.y / nailSpacing val evenLine = shape.repeatX( across, nailSpacing ) .centerX() val oddLine = shape.repeatX( across-1, nailSpacing ) .centerX() .translateY( nailSpacing ) return (evenLine + oddLine) .repeatY( down/2, nailSpacing*2 ) .center() } meth nailHolderShape() : Shape2d { return Square( size.x, size.y ) .roundAllCorners(1) .center() } meth nailHolderCorners() : Shape2d { val square = nailHolderShape() return Triangle( 4, 4 ) .leftTo( square.left ) .frontTo( square.front ) .intersection( square ) .mirrorX().also().mirrorY().also() } meth nailHolder() : Shape3d { val square = nailHolderShape() val plate = square .extrude( thickness*2 ) val corners = nailHolderCorners() .extrude( thickness ) .bottomTo( plate.top ) val headHoles = layoutNails( Circle( nailHeadSize.x/2 ) ) .extrude( nailHeadSize.y ) .topTo( plate.top + 0.01 ) val holes = layoutNails( Circle( 1 ) ) .extrude( plate.size.z + 2 ) .topTo( plate.top + 1 ) return plate - headHoles - holes + corners } meth nailHolderLid() : Shape3d { val square = nailHolderShape() val corners = nailHolderCorners().offset(clearance) return (square - corners).extrude(thickness) } override fun build() : Shape3d { val nailHolder = nailHolder() .color("Green") val nailHolderLid = nailHolderLid() .topTo( nailHolder.top ) .color("LightGreen") val nails = layoutNails( Circle( 1 ) ) .extrude( 30 ) .topTo( nailHolderLid.bottom ) .previewOnly() return nailHolder + nailHolderLid + nails } }