/Bathroom/Bin.foocad

A bin for my bathroom. I have a shop-bought one, but it started to rust (cheap crap).
I considered a hinged lid, but I think a simple lid is better. I also considered a pedal mechanism, but my original bin's mechanism broke, and I doubt an all-plastic mechanism would be long lasting.
The liner is optional. It was included for 2 reasons : 1. Allow the inside to be a different color from the outside (without the need for multi-filament prints). 2. Allow the liner to be cleaned separately from the outside. This is only an issue if the bin has a hinged lid (which makes it harder to clean).
The knob is attached to the lid with a machine screw and a threaded insert.
import uk.co.nickthecoder.foocad.join.v1.PinJoint
import static uk.co.nickthecoder.foocad.join.v1.Slice.*
import static uk.co.nickthecoder.foocad.extras.v1.Extras.*
import uk.co.nickthecoder.foocad.cup.v1.*
import static uk.co.nickthecoder.foocad.cup.v1.Cup.*
import uk.co.nickthecoder.foocad.smartextrusion.v1.*
import static uk.co.nickthecoder.foocad.smartextrusion.v1.SmartExtrusion.*
include Knob.foocad
class Bin : Model {
@Custom
var size = Vector3( 170, 170, 200 )
@Custom
var lidHeight = 20.0
@Custom
var thickness = 1.7
@Custom
var baseThickness = 2.0
@Custom
var lipSize = Vector2(4, 5)
@Custom(about="Extra space for the lip to fit into the groove" )
var gap = 1
@Custom
var chamfer = 10
@Custom
var holeDiameter = 2* 2.3
@Custom( about="If non-zero, the bin is a rounded rectangle" )
var rounded = 0
meth profile() : Shape2d {
return if (rounded == 0) {
if (size.x > size.y) {
(Circle( size.y / 2 ) hull Circle( size.y / 2 ).translateX( size.x - size.y ))
.center()
} else {
Circle( size.x / 2 )
}
} else {
Square( size.x, size.y ).center().roundAllCorners( rounded )
}
}
@Piece
meth main() : Shape3d {
val cup = Cup( profile(), size.z - lidHeight, thickness )
.baseThickness( baseThickness )
.outsideBottom( roundedChamfer( chamfer ) )
.insideBottom( Fillet( chamfer + 1 ) )
.outsideTop( outsideEdge() )
return cup
}
//@Piece
meth lidUpright() : Shape3d {
val fillet = lidHeight / 2
val solid = profile().smartExtrude( lidHeight )
.bottom( outsideEdge() )
.top( roundedChamfer( fillet ) )
val hole = profile().offset(-thickness).smartExtrude(lidHeight - baseThickness)
.top( Fillet( fillet, fillet ) )
val lip = lip().mirrorZ()
val screwHole = Cylinder(solid.height + 1, holeDiameter/2)
return solid - hole.translateZ(-0.01) + lip - screwHole
}
@Piece
meth lid() = lidUpright().mirrorZ().bottomTo(0)
@Piece
meth liner() : Shape3d {
val chamfer = this.chamfer * 2
val height = size.z - lidHeight - baseThickness - gap - lipSize.y
val profile = profile().offset(-thickness - gap * 2 )
val profile2 = PolygonBuilder().apply {
moveTo(0,0)
lineTo( -2, 12 )
}.buildPath()
val cup = Cup( profile, height, thickness )
.baseThickness( baseThickness )
.outsideBottom( roundedChamfer( chamfer ) )
.insideBottom( Fillet( chamfer + 1 ) )
.insideTop( fatLip( 9,2 ) )
return cup
}
meth outsideEdge() = fatLip( 9, 2, 0.5 )
meth lip() : Shape3d {
val overlap = 1
val gap = this.gap + overlap
val extraY = 6
val totalThickness = lipSize.x + gap
val totalHeight = lipSize.y + extraY
val profile = profile().offset(-thickness + overlap )
val lipShape = profile - profile.offset( -totalThickness )
return lipShape.smartExtrude( totalHeight )
.insideBottom( Chamfer( totalThickness ) )
.outsideTop( lipEdge( lipSize, gap ) )
.topTo(lipSize.y)
}
meth lipEdge( lipSize : Vector2, gap : double) : SmartEdge {
val lipProfile = PolygonBuilder().apply {
moveTo(0,0)
lineTo(gap, 0)
lineTo(gap, lipSize.y)
}.build().firstPath
return ProfileEdge( lipProfile )
}
@Piece
meth knob() = Knob(40) // 30
// Print with TPU?
@Piece
meth foot() : Shape3d {
val profile = profile().offset( -chamfer/2 - 1 )
val ring = profile - profile.offset(-12)
return ring.smartExtrude( 2 )
.top( Chamfer(1) )
}
@Piece( printable = false )
override meth build() : Shape3d {
val explode = 0 //30.1
val main = main().color("LightBlue")
val lid = lidUpright().bottomTo( main.top - lipSize.y + explode ).color("SteelBlue")
val liner = liner().bottomTo( baseThickness + gap / 2 ).color("SteelBlue")
val knob = knob().bottomTo( lid.top ).color("LightBlue")
val foot = foot().mirrorZ().topTo( main.bottom - 0.2 ).color( "dimgrey" )
return main + lid + knob + foot //+ liner
}
}

