/Printer/FilamentRefillSpool.foocad

The filament I wanted was out of stock, unless I bought a "refill" rather than a spool. So I bought the refill, and made my own reusable spool.
The two halves screw together (with the refill sandwiched between them).
PLA probably isn't the best choice, due to brittleness, but as I get "free" PLA filament of random colour from 3DQF, I used that ;-)
(https://www.3dqf.co.uk/product-page/re-worked-pla1-75mm-uk-made-3d-printer-filament)
import static uk.co.nickthecoder.foocad.layout.v1.Layout2d.*
import static uk.co.nickthecoder.foocad.layout.v1.Layout3d.*
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.*
import uk.co.nickthecoder.foocad.threaded.v2.*
class FilamentRefillSpool : Model {
@Custom( about="Diameter and depth of the hub" )
var hubSize = Vector2(80,62)
@Custom
var spoolDiameter = 195
@Custom
var wallThickness = 1.2
@Custom
var spokeSize = Vector2( 14, 1.8 )
@Custom
var ribSize = Vector2( 1.8, 2.0 )
@Custom
val threadHeight = 12
meth side() : Shape3d {
val outer = Circle( spoolDiameter/2 )
val cutout = (
Sector( spoolDiameter/2 -5, 0, 30 ).offset(-spokeSize.x/2) -
Circle( hubSize.x /2 + 5 )
).repeatAround( 12 )
val filamentHole = Circle( 1.2 ).translateY( 4 )
val filamentHoles = filamentHole.hull(filamentHole.mirrorY())
.translateX( spoolDiameter/2 - 5.5 )
.rotate(15).rotate(-30).also()
.mirrorX().also().rotate(90).also()
val spokes = (outer - cutout - filamentHoles)
.smartExtrude( spokeSize.y )
.inside( Chamfer(0.5) )
.outsideBottom( Chamfer(0.5) )
val spokeRibs = Square( spoolDiameter/2 - hubSize.x/2 - 1, ribSize.x ).centerY()
.rightTo( spoolDiameter/2 - 1 )
.extrude( ribSize.y )
.repeatAroundZ(12)
.bottomTo( spokes.top )
val rim = (outer - outer.offset(-4))
.smartExtrude( ribSize.y ) //2)
.outsideTop( Chamfer(0.5) )
.insideTop( Chamfer(1.5) )
.bottomTo( spokes.top )
return spokes + spokeRibs + rim
}
meth assembly() : Shape3d {
val thread = Thread( hubSize.x - wallThickness - 2, 2 )
.rodChamfer(1)
val side = side()
val maleInnerRim = Circle( hubSize.x/2 + 1 ).extrude(ribSize.y)
.bottomTo( spokeSize.y )
val maleThread = thread.threadedRod( threadHeight ).leadInAngle(40).leadOutAngle(40)
.chamferBottom(false)
.bottomTo( maleInnerRim.top )
val maleHole = Circle(thread.coreRadius() - 1 )
.smartExtrude( maleThread.top + 0.2 )
.edges( Chamfer(0.5).reverse() )
.bottomTo( -0.1 )
val male = (side + maleInnerRim + maleThread - maleHole)
.color("Green").label("male")
val core = Circle( hubSize.x/2 ).extrude( hubSize.y + ribSize.y + spokeSize.y )
// Digs into the cardboard for a tight fit.
val ribs = Triangle(1).extrude( core.size.z-5 )
.frontTo( core.back - 0.2 )
.repeatAroundZ(6)
val femaleThread = thread.threadedHole( threadHeight )
.chamferStart(false)
.topTo( core.top )
val shallowHole = Circle( thread.coreRadius() - 1 )
.smartExtrude( threadHeight + 0.1 )
.top( Chamfer( 2 ).reverse() )
.bottom( Chamfer(0.5).reverse() )
.bottomTo( -0.1 )
val deepHole = Circle( hubSize.x/2 - wallThickness )
.smartExtrude( femaleThread.bottom - threadHeight )
.top( Chamfer(0.5) )
.bottomTo( shallowHole.top-0.01 )
val female = (side + core + ribs - femaleThread - shallowHole - deepHole)
.color("Yellow").label("female")
return male + female.rotateX(180).bottomTo( maleInnerRim.top )
}
@Piece
meth male() = assembly().find("male")
@Piece
meth female() = assembly().find("female")
override fun build() : Shape3d {
val assembly = assembly()
val refill = Cylinder( hubSize.y, hubSize.x/2 )
.translateZ( spokeSize.y + ribSize.y )
.color("Red")
return assembly // + refill
}
}
