Exit Full View
Up

/Bike/Box.foocad

Box
FooCAD Source Code
import uk.co.nickthecoder.foocad.gears.v1.*
import uk.co.nickthecoder.foocad.gears.v1.*
import uk.co.nickthecoder.foocad.screws.v3.*
import uk.co.nickthecoder.foocad.extras.v1.*
import static uk.co.nickthecoder.foocad.extras.v1.Extras.*
import uk.co.nickthecoder.foocad.smartextrusion.v1.*
import static uk.co.nickthecoder.foocad.smartextrusion.v1.SmartExtrusion.*

include Bumper.foocad

class Box : Model {

    var size = Vector3( 450, 550, 350 )
    var thickness = 9

    @Custom
    val rackSize = Vector3( 180, 450, 10 )

    meth rack() : Shape3d {
        val outside = Square( rackSize.x, rackSize.y ).roundAllCorners(20).center()
        return (outside - outside.offset(-rackSize.z )).extrude( rackSize.z )
            .previewOnly()
            .topTo(0).translateY(160)
    }

    @Piece
    meth ramp() : Shape3d {
        val height = 6
        val width = 50
        val flat = 10
        val shape = Triangle( 60, height ).roundCorner(1,1,1) +
            Square( flat, height ).rightTo(0)

        val solid = shape.extrude( width ).rotateX(90).centerY()
        val screwHoles = Countersink().recess(solid.size.z-4)
            .topTo(solid.top).translateX(-flat/2)
            .translateY( solid.size.y/3.5 )
            .mirrorY().also()

        return solid - screwHoles
    }

    var gearThickness = 8
    val gearConfig = GearConfig.lego().module(3)
    val gear = InvoluteGear( gearConfig, 17 )

    @Piece
    meth plainCog() : Shape3d {
        val hole = Circle(3).extrude(gearThickness*3).center()
        val spur = gear.spurProfile().smartExtrude(gearThickness)
            .edges(Chamfer(0.4))
        return spur - hole
    }

    @Piece
    meth lockingCog() = lockingCog(false)
    @Piece
    meth lockingCogAlt() = lockingCog(true)

    meth lockingCog(alt : bool) : Shape3d {
        val fatProfile = Square( 10 ).center().roundAllCorners(2,1)

        val fatPath = PolygonBuilder().apply {
            moveTo( 0, -18 )
            lineTo( 0, -40 )
            circularArcBy( Vector2( 10, -10 ), 10, false, true )
            lineBy( 10, 0 )
        }.buildPath()

        val leverPath = PolygonBuilder().apply {
            moveTo( 18,0 )
            lineTo( 80,0 )
        }.buildPath()

        val extrusions = (
            fatProfile.extrude(fatPath).translateX(-2) +
            fatProfile.extrude(leverPath).rotateZ(35)
        ).bottomTo(0)

        val main = if (alt) {
            extrusions.mirrorX()
        } else {
            extrusions
        }

        return main + plainCog()
    }

    @Piece
    meth previewCogs() : Shape3d {
        val plainA = plainCog().translateX( gear.pitchRadius() )
        val plainB = plainCog().translateX( -gear.pitchRadius() )
        val lockingA = lockingCog().translateX( gear.pitchRadius() * 3 )
        val lockingB = lockingCogAlt().translateX( -gear.pitchRadius() * 3 )

        val cogs = (plainA + plainB + lockingA + lockingB)
            .rotateX(90).mirrorY()
            .frontTo(size.y/2)
            .bottomTo(-20)

        return cogs + rack()
    }
    
    @Piece
    meth guide() : Shape3d {
        val width = 10
        val height = 7
        val shape = Square( width, height )
            .roundCorner(1,1)
            .roundCorner(0,1)
            .center()
        val path = PolygonBuilder().apply {
            moveTo(0,-50)
            radius(9)
            lineTo(0,0)
            radius(0)
            lineTo(100,0)
            bezierBy( Vector2( 40, 0 ), Vector2(30,0), Vector2( 100, 30 ) )
            lineBy( 10, 0 )
        }.buildPath()

        val main = shape.extrude(path).bottomTo(0)
        val ends = Circle( width/2 )
            .translate( path.points[0] )
            .centerTo( path.points[path.points.size()-1] ).also()
            .smartExtrude(height)
                .top( Fillet(1) )
            

        val screwHole = Countersink()
            .topTo( main.top )
        val screwHoles = screwHole.translateX(10)
            .translateX(80).also() +
            screwHole.centerXTo( main.right - 10).centerYTo(30) +
            screwHole.translateY(-40)
        return main + ends - screwHoles
    }

    override meth build() : Shape3d {

        val outline = Cube( size ).centerXY().previewOnly()

        val rack = rack()
    
        val bumper = Bumper().apply {
        }

        val corners = bumper.cornerBumper().mirrorZ().color("DimGray")
            .leftTo( outline.left ).frontTo( outline.front ).topTo( outline.top )
            .mirrorX().also()
            .mirrorY().also()
            .mirrorZ().bottomTo(0).also(2)
        
        val edges = bumper.screwEdgeBumper().color( "DimGray" )
            .leftTo( outline.left ).frontTo( outline.front ).centerZTo( size.z/2 )
            .mirrorX().also()
            .mirrorY().also()

        val base = Square( size.x, size.y ).extrude( thickness ).centerXY()
            .color( "Green" )
        val ends = Cube( size.x - thickness*2, thickness, size.z - thickness )
            .centerX().frontTo( outline.front ).bottomTo( base.top )
            .mirrorY().also()
            .color( "Orange" )
        val sides = Cube( thickness, size.y, size.z - thickness )
            .centerY().rightTo( outline.right ).bottomTo( base.top )
            .mirrorX().also()
            .color( "Yellow" )

        val ramp = ramp().rotateZ(90).mirrorZ()
            .frontTo( rack.front + 10 )

        val guides = guide().mirrorZ().rotateZ(90)
            .frontTo( rack.front-10 )
            .rightTo( rack.left+45 )
            .mirrorX().also()

        val lockingCogs = previewCogs()


        return  base + ends + sides +
            corners + edges +
            rack + ramp + guides + lockingCogs
    }

}