import static uk.co.nickthecoder.foocad.along.v3.Along.* import uk.co.nickthecoder.foocad.woodworking.v1.* import static uk.co.nickthecoder.foocad.woodworking.v1.Woodworking.* import static uk.co.nickthecoder.foocad.layout.v1.Layout2d.* import static uk.co.nickthecoder.foocad.layout.v1.Layout3d.* import uk.co.nickthecoder.foocad.smartextrusion.v1.* import static uk.co.nickthecoder.foocad.smartextrusion.v1.SmartExtrusion.* include BoxConstruction.foocad class BirdFeedCrate : Model { var lumberSize = Vector2( 21, 19 ) var unitSize = Vector2( 100, 125 ) var across = 3 var down = 2 meth construction() = BoxConstruction().apply { crossSection = lumberSize } @Piece( about="Required : 4x2" ) meth corner() = construction().cornerB() @Piece( about="Required : 2" ) meth forHandle() : Shape3d { val joints = construction() val through = joints.through( lumberSize.y + joints.thickness*2 ) .rotateY(90) .rotateZ(90) .bottomTo(0) val endStop = joints.endStop( lumberSize.x + joints.thickness ) .leftTo( through.right - joints.thickness ) .frontTo(0) val screwHole = joints.screwHole.rotateY(-90) .centerYTo( through.middle.y ) .centerZTo( through.middle.z ) .leftTo( through.left ) val hole = Cylinder( 20, 3 ) .rotateY(90) .centerYTo( endStop.middle.y ) .centerZTo( endStop.middle.z ) return through + endStop - screwHole - hole } meth cornerShape() : Shape2d { val joints = construction() val extra = joints.cornerExtra + 3 return Square( lumberSize.y + extra, lumberSize.x + extra ).roundCorner( 2, 30 ) } @Piece meth cornerJig() : Shape3d { val shape = cornerShape() val bounds = shape.boundingSquare().offset(1).translate(-0.99,-0.99) val walls = (bounds - bounds.translate(2,2)).extrude(4) return shape.extrude(0.6) + walls } meth base(x : double, y : double) : Shape3d { val plain = Square( x, y ).center().offset(-2) val corners = cornerShape().leftTo( plain.left ).frontTo( plain.front ) .mirrorX().also().mirrorY().also() val shape = plain - corners return shape.extrude(6) } override fun build() : Shape3d { val joints = construction() val wood = Wood( "main", lumberSize.x, lumberSize.y ) val bottle = Square( unitSize ).roundAllCorners(20) .smartExtrude( 270 ) .top( Chamfer(40) ) val bottles = bottle.tileX( across, 2 ).tileY( down, 2 ) .centerXY().previewOnly() val size = bottles.size + Vector3( lumberSize.y * 2, lumberSize.y*2, -90 ) val corners = joints.cornerB() .leftTo( -size.x / 2 - joints.thickness ).mirrorX().also() .frontTo( -size.y / 2 - joints.thickness ).mirrorY().also() .mirrorZ().topTo( size.z + joints.thickness*2 ).also(2) .translateZ(-joints.thickness) .color("Orange") val handleT = forHandle() .bottomTo( -joints.thickness ) .centerY() .centerXTo( size.x/2 + joints.thickness ) .mirrorZ().topTo( size.z + joints.thickness ).also(2) .color("Orange") val across = wood.cut( size.x - lumberSize.y * 2 ) .label("across") .edgeDownAlongX().centerX().frontTo( -size.y / 2 ) .mirrorY().also() .topTo(size.z).also() .color( "LightGreen" ) val along = wood.cut( size.y ) .label("along") .edgeDownAlongY().centerY().rightTo( size.x / 2 ) .mirrorX().also() .topTo(size.z).also() .color("Green") val upright = wood.cut( size.z - lumberSize.x*2 ) .label("upright") .rotateZ(90) .bottomTo( lumberSize.x ) .leftTo( -size.x /2 ) .frontTo( - size.y / 2 ) .mirrorX().also() .mirrorY().also() .color( "LightBlue" ) val handle = wood.cut( size.z - joints.thickness*2 ) .label("handle") .bottomTo( joints.thickness ) .centerY() .leftTo( size.x/2 + joints.thickness ) .color( "LightBlue" ) val base = base( size.x, size.y ) .label( "base" ) .topTo( 0 ) .color( "DarkGray" ) return base + bottles + across + along + upright + handle + corners + handleT } }