import static uk.co.nickthecoder.foocad.chamferedextrude.v1.ChamferedExtrude.* class TissueBox : Model { @Custom var boxWidth = 120 @Custom var boxDepth = 120 @Custom var boxHeight = 127 // The gap between the lid and the main piece. If you want an interferance fit, // then this must be tuned to your printer. A qhigh uality printer will need a // smaller value than a low quality printer. @Custom var slack = 0.25 // You can make these @Custom too if you wish! var thickness = 1.2 var topThickness = 3.0 var baseThickness = 3.0 var chamfer = 3 var bottomChamfer = 2.0 var round = 6 var lip = 10 var patternDepth = 0.4 // 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() : Shape3d { val height = boxHeight + baseThickness + 1 val width = boxWidth + (thickness + 1 ) * 2 val depth = boxDepth + (thickness + 1 ) * 2 val body = ExtrusionBuilder().apply { crossSection( profile().offset( thickness -bottomChamfer ) ) forward( bottomChamfer ) crossSection( bottomChamfer ) forward( height - bottomChamfer ) crossSection() crossSection( -thickness ) /* // Makes a thicker part near the top for stength only. // Alas, this caused a visible line on the front, so I've removed it. forward( -lip - slack ) crossSection() crossSection( -1 ) forward( -3 ) crossSection() forward(-1) crossSection( 1 ) */ forward( -height + bottomChamfer + baseThickness ) crossSection() forward( -bottomChamfer ) crossSection( -bottomChamfer ) }.build() val shapes = SVGParser().parseFile( "flowers.svg" ).shapes var pattern1 : Shape2d = shapes["flower1"] pattern1 = pattern1.scale( height*0.7 / pattern1.size.y ) var pattern2 : Shape2d = shapes["flower2"] pattern2 = pattern2.scale( height*0.7 / pattern2.size.y ) val carve1 = pattern1.extrude( patternDepth * 2 ).center() .rotateX(90) .translateZ( height / 2 ) val carve2 = pattern2.extrude( patternDepth * 2 ).center() .rotateX(90) .rotateZ(90) .translateZ( height / 2 ) // Change "+" to "-" for the patterns to be recessed. return body.color("Orange") + carve1.translateY(depth/2 + thickness).rotateZ(180).also() + carve2.translateX(width/2 + thickness).rotateZ(180).also() } @Piece fun lid() : Shape3d { val solid = ExtrusionBuilder().apply { crossSection( profile().offset( thickness -chamfer ) ) forward( chamfer ) crossSection( chamfer ) forward( thickness ) crossSection() crossSection( -thickness-slack ) forward( lip ) crossSection() crossSection( -1 ) forward( -lip -1 ) crossSection() forward( -chamfer+topThickness -1) crossSection( -chamfer+topThickness -1) }.build().color("Green" ) val hole : Shape3d = hole().internalChamferedExtrude(topThickness, topThickness/2, 0) return solid - hole } fun ears() : Shape3d { return Circle( ears ).translate( boxWidth/2, boxDepth/2 ).extrude( 0.2 ) .mirrorX().also() .mirrorY().also() .color( "GhostWhite" ) } override fun build() : Shape3d { return main() + lid().mirrorZ().translateZ(boxHeight + thickness + chamfer + 10) + Cube( boxWidth, boxDepth, boxHeight ) .centerXY().translateZ( baseThickness ) .previewOnly() } }