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