Exit Full View
Up

/Printer/SpoolPost.foocad

SpoolPost

A filament spool holder, which runs on the internal hole of the spool.

Also requires a wooden dowel, a scrap of wood, two bearing. Plus a shelf bracket (or use piece "wallBracket").

I found all-plastic versions on thingiverse, but they seemed very over engineered (using a lot of plastic), and yet still not strong!

So my solution is multi-material. A wooden dowel to support the spool. A metal shelf bracket with a thin "shelf" from a scrap of wood. These are joined together with 2 pairs of plastic pieces with the bearings in between.

Wood is coloured yellow in the results. The red and orange pieces are the only parts that are 3d printed. Cut the dowel and wood scrap to suit your spool widths.

The red endGuides are simply glued to the wood scrap (the only take weight downwards, so the strength of the joint isn't important) The orange rodAxis can be glued to the dowel if you want, but will work without glue.

The piece "wallBracket" can be useful to attach the wooden "shelf" piece instead of a metal shelf bracket. Not as strong as a metal shelf bracket, but has the advantage that the wooden shelf can be taken out easily.

Print Notes

For the wallBracket, use lots of perimeters / top & bottom laters / high infill. 6 perminters, 4 top & bottom solid layers 40% infill

FooCAD Source Code
import static uk.co.nickthecoder.foocad.along.v2.Along.*
import static uk.co.nickthecoder.foocad.layout.v1.Layout2d.*
import static uk.co.nickthecoder.foocad.layout.v1.Layout3d.*
import static uk.co.nickthecoder.foocad.chamferedextrude.v1.ChamferedExtrude.*
import static uk.co.nickthecoder.foocad.screws.v1.Screws.*

class SpoolPost : Model {
    
    @Custom
    var bearingD = 22.0

    @Custom
    var bearingD2 = 8.0

    @Custom
    var bearingT = 7.0

    @Custom
    var slack = 0.3

    @Custom
    var guideH = 3

    @Custom
    var rodD = 25.0

    @Custom
    var axisT = 5.0

    @Custom
    var axisLength = 10

    @Custom
    var axisExtra = 2.0

    fun bearing() : Shape3d {
        return (Circle( bearingD/2 ) - Circle( bearingD2 / 2 )).extrude( bearingT ).previewOnly()
    }

    @Piece
    fun endGuide() : Shape3d {
        val baseHeight = 3
        val width = bearingD + axisT*2
        var baseP = Circle( width / 2 ) - (Square( width ).centerY().rightTo(0)) + Square( width/2 + guideH, width ).centerY() - Circle( 14/2 )
        val guideP = baseP - Square( width + 1 ).centerY().rightTo(0) -
            Circle( bearingD/2 + slack )
        
        val result = baseP.extrude( baseHeight ) +
            guideP.extrude( bearingT ).bottomTo( baseHeight )
            
        return result.color( "Red" ) + bearing().bottomTo( baseHeight )
    }

    
    @Piece
    fun rodAxis() : Shape3d {

        return ExtrusionBuilder().apply {
            forward( axisLength )
            crossSection( Circle.hole( rodD / 2 ) )
            forward( -axisLength )
            crossSection()
            crossSection( Circle.hole( rodD / 2 + axisT ) )
            forward( axisLength + axisExtra )
            crossSection()
    
            crossSection( Circle( bearingD2/2 + 2 ) )
            forward( 1 )
            crossSection()    

            crossSection( Circle( bearingD2/2 ) )
            forward( bearingT )
            crossSection()
        }.build().color( "Orange" )
    }

    @Piece
    fun all() : Shape3d {
        return layoutY( 1,
            rodAxis().leftTo(1).mirrorX().also(),
            endGuide().translateX(1).mirrorX().also()
            )
    }

    var postSize = Vector2( 39, 23 )
    var bracketT = 10
    var bracketAngle = 2

    @Piece
    fun wallBracket() : Shape3d {

        val height = bracketT * 2 + postSize.y
        val backT = bracketT
        val inset = 35
        val width = inset + backT

        val profile = PolygonBuilder().apply {
            moveTo(0,0)
            radius(3)
            lineTo( backT + inset, 0 )
            lineBy( 0, bracketT )
            lineBy( -inset, 0 )
            lineBy( 0, postSize.y )
            lineBy( inset, 0 )
            lineBy( 0, bracketT )
            lineBy( -inset, 0 )
            radius(0)
            lineBy( -backT, 0 )
        }.build()
            // Tilt it slightly, so that the wood points "upwards", never "downwards".
            .rotate(bracketAngle) / Square( 100 )

        val body = profile.extrude( postSize.x )
        val hole = Cylinder(bracketT+5, 7/2).rotateX(90).rotateZ(bracketAngle)
            .leftTo(body.right-16).frontTo(-1).centerZTo(body.size.z/2)

        val screwHoles = countersink( 4, 8, 4, 100 )
            .rotateY(90)//.centerZTo(body.size.z/2)
            .tileZ(2,body.size.z*0.4).centerZTo( body.size.z/2 )
            .translateY( bracketT + postSize.y/2 )
            .rightTo( backT + 1 )
            //.centerYTo(profile.size.y - extra/2).also()

        val end = Hull2d(profile).chamferedExtrude(2,1,0).topTo(0).color("Green")
        val main = (body - hole - screwHoles) + end

        return main.bottomTo(0) + end.mirrorZ().bottomTo(0).rightTo(-2)
    }
    
    /**
        Taper a wooden lolly stick, and insert it to form an end stop, so that the
        spool can never jump off.
    */
    @Piece
    fun endStop() : Shape3d {
        val thickness = 1.2
        val main = Square( endStopSize.x + 10, endStopSize.y + thickness *2)
            .roundCorner(1,3).roundCorner(0,3)
            .extrude( endStopSize.z )
            .centerXY()
        val hole = Square( endStopSize.x, endStopSize.y ).center().extrude( main.size.z, 0.9 )
        return (main - hole) //.rotateX(90).bottomTo(0)
    }
    var endStopSize = Vector3( 9.6, 2.6, 14 )


    override fun build() : Shape3d {
        val endGuide = endGuide()
        val axis = rodAxis().mirrorZ().bottomTo( endGuide.top + 2 )
        val rod = Cylinder( 100, rodD/2 ).bottomTo( axis.top + 2 )

        val axis2 = axis.mirrorZ().bottomTo( rod.top + 2 )
        val endGuide2 = endGuide.bottomTo( axis2.top )
        
        val wood = Cube( 10, endGuide2.size.y, endGuide2.top )
            .leftTo( endGuide.right )
            .centerY()

        val spool1 = (Cylinder( 5, 100 ).translateZ( 80 ).also() + Cylinder( 80, 70 )) -
            Cylinder( 200, 35 )
        val spool = spool1.center().alongX().leftTo( rod.left + 10 ).translateZ(-25).previewOnly()

        return (endGuide + axis + rod + axis2 + endGuide2 + wood).rotateY(90)
    }
}