import static uk.co.nickthecoder.foocad.layout.v1.Layout2d.* import static uk.co.nickthecoder.foocad.layout.v1.Layout3d.* import static uk.co.nickthecoder.foocad.chamferedExtrude.v1.ChamferedExtrude.* class StackingBox : Model { @Custom var boxWidth = 150 @Custom var boxDepth = 90 @Custom var boxHeight = 46.2 // The gap between the lid and the main piece. If you want an interferance fit, // then this must be tuned to your printer. A high uality printer will need a // smaller value than a low quality printer. @Custom var slack = 0.2 @Custom var round = 6 // You can make these @Custom too if you wish! var thickness = 1.2 var lipThickness = 2.0 var lidThickness = 3.0 var baseThickness = 1.2 var lidChamfer = 2 var lidHeight = 4 var baseChamfer = 1 var lip = 5 // Diameter of an additional circle at each corner to aid bed adhesion. // Set to zero if you don't want ears. // I used a brim as well as ears, but for my next print, I will try just a brim. var ears = 0 // End of custom values. // The hole for the tissues. // This is just slightly smaller than the hole in Wilko's tissues. fun hole() : Shape2d = Circle( boxWidth/2 ).sides(120).scale( 0.65, 0.45 ) // The shape of the box seen from above. This is the internal dimensions, // Using the boxWidth and boxDepth, with a 1mm gap. fun profile() : Shape2d { val width = boxWidth + (thickness + 1 ) * 2 val depth = boxDepth + (thickness + 1 ) * 2 return Square( width, depth ).center() .roundAllCorners( round ) } // The main part of the box (the lid is separate). // Built using an extrusion of profile(). // We start at the bottom, to the top, then back down again to hollow out the // box. // A pattern is added to the sides from an SVG file. The file contains other // flowers, so replace "flower1" with the id of another flower, or use a // competley different design. // In Inkscape, press Ctrl+Shift+O in inkscape to see/set the id of the currently // selected object. Note, the object must NOT be a group. // The pattern is ebossed on two sides, and sticks out on the other two. // Change the minus/plus depending on your preferences (I prefer it sticking out). @Piece fun main() = main( boxHeight ) fun main( boxHeight : double ) : Shape3d { val height = boxHeight + baseThickness + 1 val width = boxWidth + (thickness + 1 ) * 2 val depth = boxDepth + (thickness + 1 ) * 2 val lipChamfer = lipThickness + slack val body = ExtrusionBuilder().apply { // Chamfered base crossSection( profile().offset( -baseChamfer ) ) forward( baseChamfer ) crossSection( baseChamfer ) // Main upright forward( height - baseChamfer -lipChamfer - baseThickness) crossSection() // lip forward(lipChamfer) crossSection(lipChamfer) forward(lip) crossSection() // Top crossSection( -lipThickness ) // lip forward( -lip + thickness ) crossSection() forward( -thickness ) crossSection( -thickness ) // Main forward( -height + baseChamfer + lipChamfer ) crossSection() // Chamfered base forward( -baseChamfer ) crossSection( - baseChamfer ) }.build() val foo = Cube(boxWidth,boxDepth,boxHeight).centerXY() .bottomTo( baseThickness ) //.topTo(0) .previewOnly() return body.color("Orange") } @Piece fun lid() : Shape3d { val solid = ExtrusionBuilder().apply { // We are building this upside down, so the top of the lid is pointing downwards // The chamfered top crossSection( profile().offset( lipThickness -lidChamfer ) ) forward( lidChamfer ) crossSection( lidChamfer ) forward( lidHeight ) crossSection() // Lid crossSection( -lipThickness-slack ) forward( lip - thickness ) crossSection() crossSection( -thickness ) val insideChamfer = Math.max( 0, lidChamfer - lipThickness ) // Heading back down forward( -lidHeight -lidChamfer -lip + insideChamfer + lidThickness ) crossSection() forward( -insideChamfer ) crossSection( -insideChamfer ) }.build().color("Green" ) return solid } @Piece fun stack() = main( 9 ).color( "Silver" ) fun ears() : Shape3d { return Circle( ears ).translate( boxWidth/2, boxDepth/2 ).extrude( 0.2 ) .mirrorX().also() .mirrorY().also() .color( "GhostWhite" ) } override fun build() : Shape3d { val lid : Shape3d = lid().mirrorZ().toOriginZ() return main() + stack().translateZ(boxHeight-2).color("Yellow") + main().translateZ(boxHeight + 5) + lid.translateZ(boxHeight*2 + 4) + Cube( boxWidth, boxDepth, boxHeight ) .centerXY().translateZ( baseThickness ) .previewOnly() } }