/Printer/SpoolPost.foocad
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
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
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) } }