Exit Full View
Up

/Games/Wooden Block Puzzle/Box2.foocad

Box2

A two part box, with a lip. I didn't use this one in the end. Opting for three smaller boxes instead of one large box.

See Box3 for my final design.

FooCAD Source Code
include WoodenBlock.foocad

class Box2 : Model {
    
    @Custom
    var part = "view" // top, bottom or debug or view or exploded

    @Custom
    var width = 123 // Internal size

    @Custom
    var depth =  123 // Internal size

    @Custom
    var height = 26 // Internal size

    @Custom
    var topHeight = 20 // Internal size

    @Custom
    var radius = 6 // Radius of the outside. Other radii are calculated.

    @Custom
    var radiusSides = 4

    @Custom
    var thickness = 4 // Thickness of the top (the bottom will be thicker)

    @Custom
    var patternThickness = 0.6

    @Custom
    var lipThickness = 2 // Should probably be half of thickness (or close to it)

    @Custom
    var lipHeight = 6 // 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 // Chamfer of the bottom and top edges.

    override fun build() : Shape3d {

        val contents = Cube( 120, 120, 40 )
            .centerXY()
            .translateZ(thickness + 1)
            .color("Orange")


        val inside = Square( width, depth ).center().roundAllCorners(radius- thickness, radiusSides)

        val outside = Square(
            width + thickness * 2,
            depth + thickness * 2
        ).center().roundAllCorners(radius, radiusSides)

        val outsideChamfer = Square(
            width + thickness * 2 - chamfer * 2,
            depth + thickness * 2 - chamfer * 2
        ).center().roundAllCorners(radius - chamfer, radiusSides)

        val bottomLip = Square(
            width + lipThickness*2,
            depth + lipThickness*2
        ).center().roundAllCorners(radius - thickness + lipThickness, radiusSides)

        val topLip = Square(
            width + lipThickness*2 + lipSlack*2,
            depth + lipThickness*2 + lipSlack*2
        ).center().roundAllCorners(radius - thickness + lipThickness + lipSlack, radiusSides)


        val top = ExtrusionBuilder().apply {
            crossSection( outsideChamfer )
            forward( chamfer )
            crossSection( outside )
            forward( topHeight + thickness - chamfer )
            crossSection( outside )
            crossSection( topLip )
            forward( -lipHeight - 1 )
            crossSection( topLip )
            crossSection( inside )
            forward( -topHeight + lipHeight + 1 )
            crossSection( inside )
        }.build().color( "Blue" )

        val bottom = ExtrusionBuilder().apply {
            crossSection( outsideChamfer )
            forward( chamfer )
            crossSection( outside )
            forward( height + thickness - chamfer )
            crossSection( outside )
            crossSection( bottomLip )

            forward( lipHeight )
            crossSection( bottomLip )
            crossSection( inside )

            forward( -height - lipHeight )
            crossSection( inside )

        }.build().color( "Blue" ).brighter()

        val view = contents + bottom + top.rotateX(180).translateZ( height + topHeight + 9)

        val pattern = topPattern()
            .extrude( patternThickness )
            .translateZ( -0.01)
            .color( "WhiteSmoke" )
                
        return if (part == "top" ) {
            top - pattern
        } else if (part == "bottom" ) {
            bottom - pattern
        } else if (part == "view" ) {
            view
        } else if (part == "exploded" ) {
            contents + bottom + top.rotateX(180).translate( width + 10, 0, height + topHeight + 50)
        } else {
            val inspection =  Cube( 400, 5, 400 ).center() + Cube( 5, 400, 400 ).center() + Cube(400, 1, 400).centerY().rotateZ(45)
            view // inspection
        }

    }

    fun topPattern() : Shape2d{
        var foo = 10

        val result = listOf<Shape2d>()
        for ( x in 10..width.toInt() - foo step foo * 2 ) {
            result.add (
                Square( x, x ).center() -
                Square( x - foo*1.2, x - foo*1.2 ).center()
            )
        }

        val diagonal = Square( width * 4, foo ).center().rotate(45)
        return Union2d( result ) - diagonal.mirrorX().also()
    }

}