Exit Full View
Up

/Bike/ToolBagMount.foocad

ToolBagMount

A two part clip, with holes for two M6 threaded inserts. These attach a small toolbag to the handlebar stem of my bike.

The stem is tapered, so I need 2 different sizes (34 and 36 mm internal diameter). They feel very secure.

FooCAD Source Code
import uk.co.nickthecoder.foocad.threaded.v2.*
import static uk.co.nickthecoder.foocad.threaded.v2.Thread.*
import static uk.co.nickthecoder.foocad.extras.v1.Extras.*
import uk.co.nickthecoder.foocad.smartextrusion.v1.SmartExtrusion
import static uk.co.nickthecoder.foocad.smartextrusion.v1.SmartExtrusion.*

class ToolBagMount : Model {

    @Custom( about="Inner diameter, thickness, height" )
    var size = Vector3( 36, 8, 11 ) // 34 & 36 across.

    @Custom( about="The difference in height between the two pieces" )
    var step = 3

    @Custom
    var chamfer = 1.5

    @Custom
    var screwDistance = 36

    @Custom( about="The difference in side of the male and female dovetails." )
    var clearance = 0.2

    var bracket : Shape3d = null
    var clip : Shape3d = null

    fun createBothPieces() {

        val thickness = size.y
        val innerDiameter = size.x
        val outerDiameter = size.x + size.y*2

        val round = 4
        val frontHalf = Square( outerDiameter, outerDiameter/2 )
            .roundCorner(1,4)
            .roundCorner(0,4)
            .centerX().backTo(0)
            
        val ring = ( Circle( outerDiameter/2 ) + frontHalf ) - Circle( innerDiameter/2 )

        val clipRing = ring intersection Square( 1000 ).centerX()
        val bracketRing = ring intersection Square( 1000 ).centerX().backTo(0)

        /*
        val dovetail = (
                Triangle( thickness * 0.7, 10 ).centerY() intersection
                Square( thickness, 5 ).backTo(chamfer)
            )
            //.leftTo( ring.left + thickness / 3 )
            .leftTo( ring.left )
            .mirrorX().also()
        */
        val dovetail = PolygonBuilder().apply {
            moveTo(0,0)
            lineBy( 0.1, 2 )
            lineBy( 1, 5 )
            lineTo( thickness * 0.4, 5 )
            lineTo( thickness * 0.4, 0 )
            lineTo( thickness * 0.85, -10 )
            lineTo( 2, -10 )
            lineTo( 2, -7 )
            lineTo( 0, -7 )
        }.build().leftTo( ring.left )
            .mirrorX().also()

        val screwHoles = Cylinder( 14, 7.6 / 2 )
            .rotateX(90)
            .centerXTo( screwDistance/2 )
            .frontTo( -outerDiameter/2 - 0.1 )
            .centerZTo( size.z / 2 )
            .mirrorX().also()

        clip = clipRing
            .smartExtrude(size.z - step)
            //.chamferBottom(chamfer)
            .fillet(chamfer) +
            dovetail.smartExtrude( size.z - step ).fillet(chamfer)//.chamferBottom( chamfer )

        bracket = bracketRing
            .smartExtrude(size.z)
            .fillet(chamfer) -
            dovetail.offset(clearance).extrude( size.z ).bottomTo( step - 0.2 ) -
            screwHoles

    }

    @Piece
    fun clip() : Shape3d {
        createBothPieces()
        return clip
    }

    @Piece
    fun bracket() : Shape3d {
        createBothPieces()
        return bracket
    }

    @Piece
    fun both() : Shape3d {
        createBothPieces()

        return bracket +
            clip.translateY(12).color("Green")
    }

    @Piece
    fun boltKnob() : Shape3d {
        val thread = metricThread( 6 )
        val knob = thread.boltKnob().knobSize( 20, 5 )
            .filletRadius( 2 )
            
        return knob +
            thread.bolt(20).preview().previewOnly().mirrorZ().topTo( knob.top )
    }

    override fun build() : Shape3d {
        createBothPieces()

        return bracket +
            clip.translateZ(step).color("Green") +
            boltKnob().backTo( -40 )
    }

}