import static uk.co.nickthecoder.foocad.debug.v1.Debug.* import static uk.co.nickthecoder.foocad.layout.v1.Layout2d.* import static uk.co.nickthecoder.foocad.layout.v1.Layout3d.* import static uk.co.nickthecoder.foocad.extras.v1.Extras.* class TinCanUpCycle : Model { @Custom var diameter = 74.5 @Custom var domeHeight = 7 @Custom var sections = 6 @Custom var width = 3 @Custom var rimSize = Vector2(2, 4) @Custom var overhang = 1.0 @Custom var round = 2 @Custom var insideThickness = 2 fun holes( diameter : double ) : Shape2d { val hex = Circle( diameter*0.3 ).sides( sections ) var outer : Shape2d = (Sector( diameter/2-width/2, 0, 360/sections).offset(-width/2) - hex) .toPolygon() .offset(-round).minkowski( Circle( round ) ) // Round the "corners" return outer.repeatAround( sections ) + hex.offset(-width).roundAllCorners(round) } @Piece fun main() : Shape3d { val ring = Circle( diameter/2 )// - Circle( diameter/2 - width ) val r = domeHeight/2 + diameter*diameter/8/domeHeight val dome = Sphere( r ).topTo(domeHeight+width/2) val main = ring.extrude( domeHeight+width ) / dome return main - holes( diameter ).extrude( domeHeight + width ).bottomTo(-1) } @Piece fun requiresSupport() : Shape3d { return (rim().topTo(0) + main() ).bottomTo(0) } @Piece fun base() : Shape3d { return (Circle( diameter/2 - overhang -1 ) - holes( diameter-overhang/2 -1 )) .extrude(insideThickness) } @Piece fun rim() : Shape3d { return ExtrusionBuilder().apply { crossSection( Circle( diameter/2 - overhang -0.3 ) ) forward( rimSize.y / 2 ) crossSection( Circle( diameter/2 - overhang ) ) forward( rimSize.y / 2 ) crossSection( Circle( diameter/2 - overhang -0.3 ) ) }.build() - Cylinder( width+3, diameter/2 - overhang - rimSize.x ).bottomTo(-1) } override fun build() : Shape3d { return main().color("Green") + rim().topTo(0).color("Orange") + Cylinder( diameter*1.3, diameter/2 ).previewOnly().topTo(-10) + base().topTo( -diameter*1.4 ) } }