import static uk.co.nickthecoder.foocad.layout.v1.Layout2d.* import static uk.co.nickthecoder.foocad.layout.v1.Layout3d.* include PlantPot.foocad class Saucer : Model { @Custom var size = Vector2( 115, 17 ) @Custom var thickness = 2.0 @Custom var ribSize = Vector2( 4, 3 ) fun ring( d : double ) = Circle( d/2 ) - Circle( d/2 - ribSize.x ) @Piece fun saucer() : Shape3d { val path = PolygonBuilder().apply { moveTo(0,0) lineBy( size.x/2, 0 ) lineBy( 0, thickness/2 ) bezierBy( Vector2( 0, size.y * 0.1 ), Vector2( 0, size.y * 0.3 ), Vector2( size.y, size.y ) ) }.buildPath() val saucer = path.thickness( thickness ).revolve().bottomTo(0) val rim = Circle( thickness ).scaleX(0.75).rightTo( saucer.right ).revolve() .centerZTo( saucer.top ) return saucer + rim } /** * Optional, if you want to add a patterned base, giving it extra strength */ @Piece fun ribs() : Shape3d { val inner = size.x * 0.3 val rings = ring( size.x + thickness) + ring( size.x* 0.75 ) + ring( inner ) val radii = Square( size.x/2 - inner/2, ribSize.x ).leftTo(inner/2).centerY() .repeatAround( 6 ) return rings.extrude(ribSize.y).color("Green") + radii.extrude(ribSize.y).color("Orange") } override fun build() : Shape3d { val pot = PlantPot().apply { potDiameter = 150 potHeight = 140 type = "6" }.build().bottomTo( thickness ).previewOnly() return ribs() + saucer().bottomTo(ribSize.y) + pot } }