import static uk.co.nickthecoder.foocad.layout.v1.Layout2d.* import static uk.co.nickthecoder.foocad.layout.v1.Layout3d.* import uk.co.nickthecoder.foocad.extras.v1.* import static uk.co.nickthecoder.foocad.extras.v1.Extras.* import uk.co.nickthecoder.foocad.cup.v1.* import static uk.co.nickthecoder.foocad.cup.v1.Cup.* import uk.co.nickthecoder.foocad.smartextrusion.v1.* import static uk.co.nickthecoder.foocad.smartextrusion.v1.SmartExtrusion.* class VegRack : Model { var size = Vector2( 180, 220 ) var shelfThickness = 8 var angle = 30 var depth = 60 var thickness = 1.2 var baseThickness = 3.0 var runnerSize = Vector2( 8, 2 ) var round = 5 var cutoutSize = Vector2( 90, 15 ) val lipSize = Vector2(2, 3) meth shape() : Shape2d { val basic = Square( size ).rightTo(0) - Square( size * 4 ) .rightTo(10) .backTo(0) .rotate(-angle) return basic.toPolygon().roundAllCorners(round).center() } meth shortSide() = size.y - size.x * Math.tan( angle * Math.PI / 180 ) meth cutoutShape() : Shape2d { return Trapezium( cutoutSize.x, cutoutSize.y ) .deltaX( -cutoutSize.y * 0.4 ) .centerX() .roundCorner(3,cutoutSize.y) .roundCorner(2,cutoutSize.y) } @Piece meth testCutout() = cutoutShape() .smartExtrude(1) .top( Chamfer(0.5) ) meth positionCutout( shape : Shape3d ) = shape .rotateZ(-angle) .translateY( -size.y/2 + (size.y - shortSide())/2 ) meth positionCutout( shape : Shape2d ) = shape .rotate(-angle) .translateY( -size.y/2 + (size.y - shortSide())/2 ) meth lipProfile2() = PolygonBuilder().apply { moveTo(0,0) lineBy(-2, 2) lineBy(2, 2) } meth lipProfile() = PolygonBuilder().apply { moveTo( 0,0 ) lineBy( -lipSize.x, lipSize.x ) lineBy( 0, lipSize.y - 0.5 ) lineBy( 0.5, 0.5 ) }.buildPath() @Piece @Slice( fillDensity=5, topSolidLayers=4 ) meth drawer() : Shape3d { val cup = shape().toPolygon().cup( depth, thickness ) .baseThickness( baseThickness ) .insideBottom( Fillet( round ) ) .outsideBottom( roundedChamfer( round ) ) .insideTop( ProfileEdge( lipProfile() ) ) .outsideTop( Chamfer( 0.5 ) ) val forCutout = cutoutShape() .smartExtrude( depth - baseThickness ) .top( Chamfer(0.5) ) .bottomTo( baseThickness ).translateY(0.1) return cup + positionCutout(forCutout) } meth shelf() : Shape3d { val cutout1 = cutoutShape() val cutout = (cutout1 + cutout1.boundingSquare().backTo(0)) .offset(-2).toPolygon() val shape = (shape() - positionCutout( cutout )) return shape .smartExtrude( shelfThickness ) .top( Fillet(2) ) .bottom( roundedChamfer(2) ) } @Piece( printable=false ) override fun build() : Shape3d { val shelf = shelf() .color("ghostWhite") val drawer = drawer() .bottomTo( shelf.top ) val shelves = shelf.repeatZ(3, depth + shelfThickness +1) val drawers = drawer.repeatZ(2, depth + shelfThickness + 1) val side1 = Cube( 15, size.y, shelves.size.z ) .leftTo( drawer.right + 2 ) .centerY() .color("ghostWhite") val side2 = Cube( 15, shortSide(), shelves.size.z ) .rightTo( drawer.left - 2 ) .backTo( side1.back ) .color("ghostWhite") return shelves + drawers + side1 + side2 } }