Exit Full View
Up

/Bike/EnguieFrameClamp.foocad

EnguieFrameClamp

My bike's frame is a weird shape, and has built-in attachments.

This let's me attach various things to my bike, such as a water bottle.

It is designed to be flexed into place, and then "locked" using a tapered dovetail.

The bulge at the bottom accomodates the rear brake cable, electric cables. It is fat, because I didn't want to it to be stretched and flattered, maybe pressing on the cables.

PETG is better than PLA due to its flexibility.

Using my "fast" print settings, one male dovetail is a snug fit, and the other is loose. I guess its related to the seem position??? FYI, this suits me just fine. If both were loose, I may have glue one in permanetly!

The ring itself is a very snug fit, and does not slide about.

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

class EnguieMainClamp : Model {

    var sectionSize = Vector2( 49, 108 )
    var sectionRadius = 6
    var clearance = 0

    var width = 12

    var thickness = 1.1
    
    var bulgeSize = Vector2( 20, 16 )

    var gapSize = 10

    meth dovetail() : Shape2d {
        val round = 0.5
        val main = Trapezium( sectionSize.x / 6, 4 )
            .angle(22)
            .centerX()
            .roundCorner(3, round)
            .roundCorner(2, round )
        val bottom = Trapezium( sectionSize.x / 6 + round *2, round )
            .deltaX( -round )
            .centerX()

        return main + bottom
    }    

    meth dovetails( male : bool ) : Shape3d {
        val shape = if (male) dovetail() else dovetail().offset(0.1)

        val chamferSize = 0.5
        val chamfer = if (male) { Chamfer(chamferSize) } else { Chamfer(chamferSize).reverse() }

        val result = shape
            .smartExtrude( width )
                .top( chamfer )
            .translateY( sectionSize.y/2 + thickness )
            .centerXTo( sectionSize.x / 4.5)
            .mirrorX().also()

        return if (male) {
            result
        } else {
            result.margin( 0, -chamferSize, 0 )
        }
        
    }
    
    meth bulge() : Shape2d {
        return Square( bulgeSize.x + thickness, bulgeSize.y )
            .roundCorner( 2, bulgeSize.x/2 )
            .roundCorner( 1, bulgeSize.x/2 )
            .leftTo(sectionSize.x/2 + clearance)
            .frontTo( -sectionSize.y/2 + sectionRadius + thickness )
            
    }

    @Piece
    meth main() : Shape3d {
        val rect = Square( sectionSize.x + clearance*2, sectionSize.y )
            .center()
            .roundAllCorners( sectionRadius )

        val bulge = Square( bulgeSize.x, bulgeSize.y*2 )
            .centerX()
            .centerYTo( rect.front )
            .roundAllCorners( bulgeSize.y * 0.5 )

        val internal = rect + bulge
        val external = internal.offset( thickness ) +
                bulge.offset(thickness).scaleX(1.5)

        val gap = Cube( sectionSize.x/4.2, thickness+0.02, width + 0.02 )
            .centerX().bottomTo(-0.01).frontTo(internal.back-0.01)

        val shape = external - internal

        return shape.extrude( width ) + dovetails(true) - gap
    }

    @Piece //( print="lockPrint" )
    meth lock() : Shape3d {
        val thick = 1.5
        val dovetails = dovetails(false)
            .bottomTo( thickness )

        val rect = Square( dovetails.size.x + thick*4, 9 )//dovetails.size.y + thick )
            .centerX()
            .roundAllCorners(1)
            .frontTo(dovetails.front + 0.2 )

        val solid = rect.smartExtrude( width + thickness )
            .edges( Chamfer( thickness/2 ) )

        // M4 threaded insert
        val screwHole = Cylinder(9, 5.5/2)
            .rotateX(90)
            .backTo( solid.back )
            .centerZTo( solid.middle.z )

        return solid - dovetails - screwHole
    }

    // Printing in this orientation gives a smoother fit,
    // because the layer lines are at right angles, rather than parallel.
    @Piece
    meth lockFaceDown() = lock().backTo(0).rotateX(-90)

    override fun build() : Shape3d {
        val lock = lock()
            .bottomTo(-thickness)
            .previewOnly()
        return main() + lock
    }
}