// ============================================ // Filament Spool Cover // ============================================ // A circular dust cover that clips onto the outer rim // of a filament spool. Snap-fit clips around the // perimeter grip the spool edge to hold the cover // in place. // // Coordinate system: // Origin (0,0,0) = center of the cover disc, bottom face // X/Y = radial plane of the disc // Z = upward (skirt and clips extend in +Z) // ============================================ // CUSTOMIZABLE PARAMETERS // ============================================ /* [Spool] */ // Outer diameter of the filament spool spool_outer_diameter = 200; // [150:1:220] // Thickness of the spool rim (the edge clips grab) spool_rim_thickness = 1; // [1:0.5:5] /* [Cover] */ // Thickness of the cover disc cover_thickness = 1.5; // [1:0.5:3] // Height of the skirt that wraps around the spool rim skirt_height = 5; // [3:0.5:10] // Thickness of the skirt wall skirt_wall = 1.2; // [0.8:0.1:2.0] /* [Clips] */ // Number of clips around the perimeter clip_count = 3; // [3:1:12] // Angular width of each clip in degrees clip_arc = 15; // [5:1:30] // Depth of the clip lip that hooks under the rim clip_lip_depth = 1.5; // [0.5:0.1:3] // Clearance gap for snap fit clip_clearance = 0.3; // [0.1:0.05:0.6] /* [Quality] */ // Rendering resolution resolution = 120; // [60:10:200] // ============================================ // PARAMETER VALIDATION // ============================================ assert(spool_outer_diameter > 0, "Spool outer diameter must be positive"); assert(spool_rim_thickness > 0, "Spool rim thickness must be positive"); assert(cover_thickness >= 1, "Cover thickness should be at least 1mm"); assert(skirt_height > spool_rim_thickness, "Skirt must be taller than rim thickness to clip"); assert(clip_count >= 3, "Need at least 3 clips for a secure hold"); assert(clip_lip_depth > 0, "Clip lip depth must be positive"); // ============================================ // DERIVED DIMENSIONS // ============================================ spool_radius = spool_outer_diameter / 2; // Inner radius of the skirt sits just outside the spool rim skirt_inner_radius = spool_radius + clip_clearance; skirt_outer_radius = skirt_inner_radius + skirt_wall; // ============================================ // MAIN ASSEMBLY // ============================================ cover(); // ============================================ // COMPONENT MODULES // ============================================ // Full cover assembly: disc + skirt + clips module cover() { union() { cover_disc(); skirt(); clips(); } } // Flat circular disc that covers the spool face (sits on the build plate) module cover_disc() { cylinder(h=cover_thickness, r=skirt_outer_radius, $fn=resolution); } // Continuous ring around the edge that extends upward from the disc module skirt() { translate([0, 0, cover_thickness]) difference() { cylinder(h=skirt_height, r=skirt_outer_radius, $fn=resolution); translate([0, 0, -0.01]) cylinder(h=skirt_height + 0.02, r=skirt_inner_radius, $fn=resolution); } } // Evenly spaced snap clips at the top of the skirt module clips() { for (i = [0 : clip_count - 1]) { rotate([0, 0, i * (360 / clip_count)]) clip(); } } // Single snap clip: lip at top grabs the rim, diagonal ramp below for supportless printing // Cross-section profile (radial view, outer left, inner right): // // |_____| <- skirt top: lip extends inward to grab rim // | / | // | / | // | / | // |/ | // | | <- skirt base // // The diagonal ramp prints without supports. module clip() { eps = 0.01; base_z = cover_thickness; ramp_height = skirt_height - spool_rim_thickness; // Full clip profile as a single polygon, extruded as an arc // Coordinates in (r, z) space, relative to (0, base_z) translate([0, 0, base_z]) rotate_extrude(angle=clip_arc, $fn=resolution) translate([skirt_inner_radius - clip_lip_depth, 0, 0]) polygon([ // Bottom-right: flush with skirt inner wall at base [clip_lip_depth, 0], // Bottom-right: outer edge (into skirt wall) [clip_lip_depth + skirt_wall + eps, 0], // Top-right: outer edge at skirt top [clip_lip_depth + skirt_wall + eps, skirt_height], // Top-left: inner edge of lip at skirt top [0, skirt_height], // Ramp starts: flush with skirt inner wall [clip_lip_depth, skirt_height - spool_rim_thickness] ]); }