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