/Boxes/EpoxyResinBox.foocad
A case for two-part Epoxy resin. I buy the cheapest, which comes in two tubes, and minimal packaging, so I need somewhere to keep the two tubes safe from damage, and without touching each other.
Print Notes
Print the hinge using flexile filament, and simply glue it to both halves.
import static uk.co.nickthecoder.foocad.layout.v1.Layout2d.* import static uk.co.nickthecoder.foocad.layout.v1.Layout3d.* include ThickWalledBox2.foocad class TrapeziumBox(val size : Vector2, val squish : double ) : RoundedThickWalledBox2() { override fun profile() = PolygonBuilder().apply { moveTo( -size.x/2, -size.y/2 ) lineBy( size.x, size.y * squish ) lineBy( 0, size.y * (1-squish*2) ) lineBy( -size.x, size.y * squish ) }.build() } class EpoxyResinBox : Model { @Custom( about="Length and width of one compartment" ) var tubeSize = Vector2( 100, 30 ) @Custom( about="How much to squish one end to form a trapezium" ) var squish = 0.1 @Custom( about="Thickness of the dividers" ) var dividerT = 1.2 @Custom( about="Gap between the dividers for the spreader tool" ) var gap = 4.0 fun box() = TrapeziumBox( Vector2( tubeSize.x, tubeSize.y * 2 + dividerT* 2 + gap ), squish).apply { bottomHeight=13 topHeight = 6 } @Piece fun bottom() : Shape3d { val box : TrapeziumBox = box() val bottom = box.bottom() val dividers = Cube( bottom.size.x - box.thickness*2, dividerT, bottom.size.z - box.thickness ) .centerXY() .bottomTo( box.baseThickness ) .tileY( 2, gap ).centerY() val finger = Cylinder( gap *2 + dividerT * 2, 20 ).rotateX(90).center().bottomTo( dividers.top - 8 ) return bottom + dividers - finger } @Piece fun top() : Shape3d { val top = box().top() val text = Text("Epoxy",BOLD, 20) val outline = (text.offset(0.5) - text.offset(-0.25)).extrude(0.6).centerXY().mirrorX() return top - outline } // Add colour coordinated inlays to the bottom of each section, so that the tubes are placed // back in the "correct" side. If there is spillage, it won't harden. @Piece fun inlay() : Shape3d { val box : TrapeziumBox = box() return (box.profile() / Square( 1000 ).centerX().frontTo(dividerT+gap/2)).extrude(0.8) } @Piece fun hinge() : Shape3d { val box : TrapeziumBox = box() return Square( box.size.x, 20 ).roundAllCorners(5) .extrude( 0.6 ) } override fun build() : Shape3d { val bottom : Shape3d = bottom() val top : Shape3d = top().rotateX(180).rotateZ(180).bottomTo( bottom.top + 10 ) return bottom + top } }