Exit Full View
Up

/Boxes/TinCanUpcycle.foocad

TinCanUpcycle

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]

FooCAD Source Code
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 )
    }
}