/Boxes/TinCanUpcycle.foocad

In two pieces, the main piece, and the "rim", which I print using TPU for a rubbery tight fit ;-) Glue the pieces with super glue.
Insipred by : [https://www.printables.com/model/191072-tin-can-tool-organizer]
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 : AbstractModel() {
@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 )
}
}

