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 } }