/Boxes/ThickWalledBox.foocad
A thick walled box which snaps together with an interferance fit of lips. The ouside and inside of the box are smooth.
Comprised of a bottom and a top, and optionaly middle sections, which are hollow tubes (with the same lip connectors). You can include as many middle sections as you like, and either keep them free, or glue them to the bottom.
Print Notes
I highly recommend trying coloured transparent PLA. It give an amazing striped effect from the infill pattern.
Use 2 perimeters, and 10% infill
import static uk.co.nickthecoder.foocad.layout.Layout2d.* import static uk.co.nickthecoder.foocad.layout.Layout3d.* class ThickWalledBox : Model { @Custom var width = 70.0 // Internal size @Custom var depth = 60.0 // Internal size @Custom var middleHeight = 22.0 // Internal size @Custom var topHeight = 10.0 // Internal size @Custom var bottomHeight = 30.0 // Internal size @Custom var thickness = 4.0 // Thickness of the top (sides and top/bottom) @Custom var lipThickness = 2.0 // Should probably be half of thickness (or close to it) @Custom var lipHeight = 6.0 // The height of the lip on the bottom piece. // I created small prototypes to find the best value for this. // It is the additional space in the top part for the bottom's lip // to fit into. I wanted an interferance fit. @Custom var lipSlack = 0.3 @Custom var chamfer = 2.0 // Chamfer of the bottom and top edges. fun profile() : Shape2d = Square( width, depth ).center() fun inset( amount : double ) : Shape2d { val profile : Shape2d = profile() return profile.scale( (profile.size.x - amount * 2) / profile.size.x, (profile.size.y - amount * 2) / profile.size.y ) } @Piece fun top() : Shape3d { val inside = profile() val outside = inset( - thickness ) val outsideChamfer = inset( -thickness + chamfer) val outsideLip = inset( -lipThickness ) val top : Shape3d = ExtrusionBuilder().apply { crossSection( outsideChamfer ) forward( chamfer ) crossSection( outside ) forward( topHeight + thickness - chamfer ) crossSection( outside ) crossSection( outsideLip ) forward( -lipHeight ) crossSection( outsideLip ) crossSection( inside ) forward( -topHeight + lipHeight) crossSection( inside ) }.build().color( "Blue" ) return top.mirrorX() } @Piece fun middle() : Shape3d { val inside = profile() val outside = inset( - thickness ) val slackLip = inset( -lipThickness + lipSlack ) val outsideLip = inset( -lipThickness ) val middleSolid = ExtrusionBuilder().apply { crossSection( outside ) forward( middleHeight ) crossSection( outside ) crossSection( slackLip ) forward( lipHeight ) crossSection( slackLip ) }.build() .color( "Blue" ).brighter() val middleHole = ExtrusionBuilder().apply { forward(-0.1) crossSection( outsideLip ) forward(0.1 + lipHeight + 1 ) crossSection( outsideLip ) forward( thickness ) // Chamfer so that we don't need support material crossSection( inside ) forward( middleHeight - thickness -1 + 0.1) crossSection( inside ) }.build() return ( middleSolid - middleHole ).mirrorX() } @Piece fun bottom() : Shape3d { val inside = profile() val outside = inset( - thickness ) val outsideChamfer = inset( -thickness + chamfer) val slackLip = inset( -lipThickness + lipSlack ) val bottom : Shape3d = ExtrusionBuilder().apply { crossSection( outsideChamfer ) forward( chamfer ) crossSection( outside ) forward( bottomHeight + thickness - chamfer ) crossSection( outside ) crossSection( slackLip ) forward( lipHeight - 1 ) crossSection( slackLip ) crossSection( inside ) forward( -bottomHeight - lipHeight + 1 ) crossSection( inside ) }.build().color( "Blue" ) return bottom } override fun build() : Shape3d { return bottom() + middle().translateZ( bottomHeight + thickness + 1 ).color("Yellow") + top() .rotateX(180) .toOriginZ() .translateZ( bottomHeight + middleHeight + thickness + 2 ) } }