Exit Full View
Up

/Games/ThickWalledBox.foocad

ThickWalledBox
FooCAD Source Code
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 )
    }

}