3d-printing/filament-spool-cover/cover.scad
Felipe M. ebd213f053
Add filament spool cover model with snap-fit outer rim clips
Parametric dust cover that clips onto the outer rim of a standard 1kg
(200mm) filament spool. Features diagonal clip ramps for supportless
printing and customizable dimensions for different spool sizes.
2026-04-07 17:51:57 +02:00

151 lines
4.7 KiB
OpenSCAD

// ============================================
// 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]
]);
}