Exit Full View
Up

/Boxes/ScrewLidContainer.foocad

ScrewLidContainer
FooCAD Source Code
import static uk.co.nickthecoder.foocad.arrange.v1.Arrange.*
import uk.co.nickthecoder.foocad.smartextrusion.v1.*
import static uk.co.nickthecoder.foocad.smartextrusion.v1.SmartExtrusion.*
import uk.co.nickthecoder.foocad.cup.v1.*
import static uk.co.nickthecoder.foocad.cup.v1.Cup.*
import uk.co.nickthecoder.foocad.threaded.v2.*

class ScrewLidContainer : Model {

    @Custom( about="Thickness of walls, bottom and lid" )
    var thickness = 1.2

    var outerDiameter = 60

    @Custom( about="Internal height of the container" )
    var height = 60

    @Custom( about="Radius of corners" )
    var round = 3

    @Custom( about="Distance between the peaks of the threads" )
    var threadSize = 2

    @Custom( about="Increase to make it easier to screw on/off, at the expense of tightness" )
    var threadCount = 4

    @Custom( about="Width and thickness of the space for the gasket" )
    var gasketSize = Vector2( 4, 1.2 )

    var lipWidth = 4

    var threadHeight = 8

    meth thread() = Thread.forRod( outerDiameter, threadSize )
        .rodChamfer(thickness)
        .threads( threadCount )

    meth single() : Shape3d {
        val cup = Circle( outerDiameter / 2 )
            .cup( height + thickness, thickness )
                .insideBottom( Fillet( round ) )
                .outsideBottom( roundedChamfer(round) )
        val topThread = thread()
            .threadedRod(threadHeight)
                .leadInAngle(90)
                .leadOutAngle(90)
            .threadsOnly()
            .topTo( cup.top )
        return cup + topThread
    }

    @Piece
    meth lid() : Shape3d {
        val thread = thread()

        val gasketOutsideRadius = thread.diameter/2 + thread.clearance 
        val outer = Circle( thread.coreRadius() + thread.threadSize.x + thread.clearance + thickness )
        val inner = outer.offset( -lipWidth )

        val extraEdge = if (gasketSize.y <= 0) {
            Chamfer( -2, round-thickness-0.1 )
        } else {
            null
        }
        val extra = inner
            .smartExtrude( round - thickness )
                .top( extraEdge )
            .bottomTo( thickness )

        val forGasket = if ( gasketSize.y > 0 ) {
            Circle( gasketOutsideRadius )
                .smartExtrude( gasketSize.y + thread.threadSize.x )
                    .top( Chamfer( thread.threadSize.x ) )
                .bottomTo( extra.top - 1 )
        } else {
            null
        }

        val solid = outer
            .smartExtrude( round + gasketSize.y + threadHeight )
                .bottom( roundedChamfer(round) )
                .top( Chamfer(thickness/3) )

        val threadedHole = thread.threadedHole( threadHeight + gasketSize.y )
            .chamferStart( false )
            .bottomTo( round )

        return solid - extra - forGasket - threadedHole
    }

    @Piece
    meth testFingerTwist() = fingerTwist( 40, 10, 10, 3 )

    meth fingerTwist( diameter : double, gap : double, depth : double, thickness : double ) : Shape3d {

        val round = 2
        val semi = (
                Circle( diameter/2 ) -
                Square( diameter ).centerY().leftTo(-gap/2 - round)
        ).toPolygon()
        val roundingCircle = Circle( round ).backTo( semi.back ).centerXTo( semi.right )
        val edge = roundingCircle hull roundingCircle.mirrorY()
        val inner = (semi + edge).mirrorX().also().cup( depth, thickness )
                .baseThickness(1)
                .insideTop( Chamfer(1,1) )
                .insideBottom( roundedChamfer(3) )
                .outsideBottom( Fillet(1) )
            .cavity( true )
            .mirrorZ().bottomTo(0)

        return lid() and inner
    }

    override meth build() : Shape3d {
        val single = single()
        val lid = lid().rotateX(180).bottomTo( single.top + 20 )

        return single + lid
    }

}