//
// NopSCADlib Copyright Chris Palmer 2018
// nop.head@gmail.com
// hydraraptor.blogspot.com
//
// This file is part of NopSCADlib.
//
// NopSCADlib is free software: you can redistribute it and/or modify it under the terms of the
// GNU General Public License as published by the Free Software Foundation, either version 3 of
// the License, or (at your option) any later version.
//
// NopSCADlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with NopSCADlib.
// If not, see .
//
//! Pintable fan finger guard to match the specified fan. To be ```include```d, not ```use```d.
//!
//! The ring spacing as well as the number of spokes can be specified, if zero a gasket is generated instead of a guard.
//
use
function fan_guard_thickness() = 2; //! Default thickness
function fan_guard_wall() = extrusion_width - layer_height / 2 + nozzle / 2 + extrusion_width / 2;
function fan_guard_corner_r(type) = washer_diameter(screw_washer(fan_screw(type))) / 2 + 0.5; //! Corner radius of the guard
function fan_guard_width(type) = max(2 * (fan_hole_pitch(type) + fan_guard_corner_r(type)), fan_bore(type) + 4 * fan_guard_wall()); //! Width of the guard
module fan_guard(type, name = false, thickness = fan_guard_thickness(), spokes = 4, finger_width = 7, grill = false) { //! Generate the STL
if(thickness)
stl(name ? name : str("fan_guard_", fan_width(type)));
hole_pitch = fan_hole_pitch(type);
corner_radius = fan_guard_corner_r(type);
wall = grill ? 2 : fan_guard_wall();
spoke = grill ? 3 : wall;
width = fan_guard_width(type);
hole = fan_aperture(type) / 2;
max_ring_pitch = finger_width + wall;
inner_ring = max_ring_pitch / 2;
gap = hole + wall / 2 - inner_ring;
rings = ceil(gap / max_ring_pitch);
ring_pitch = gap / rings;
spoke_end = grill && fan_aperture(type) > fan_bore(type) ? hole - ring_pitch : hole;
spoke_start = grill && rings > 1 ? inner_ring + ring_pitch : inner_ring;
rounding = grill ? 1.5 : 0;
extrude_if(thickness, center = false) {
difference() {
offset(-rounding) offset(rounding) {
difference() {
rounded_square([width, width], r = width / 2 - hole_pitch);
fan_holes(type, !grill, !grill, h = 0);
}
if(spokes) {
intersection() {
union() {
for(i = [(grill ? 1 : 0) : 1 : rings - 1]) {
r = inner_ring + i * ring_pitch;
ring(or = r + wall / 2, ir = r - wall / 2);
}
for(i = [0 : spokes - 1])
rotate(i * 360 / spokes + 45)
translate([spoke_start, -spoke / 2])
square([spoke_end - spoke_start + eps, spoke]);
}
square(width - eps, center = true);
}
}
}
if(grill)
fan_hole_positions(type, z = 0)
drill(screw_clearance_radius(fan_screw(type)), 0);
}
if(grill)
difference() {
r = min(inner_ring + ring_pitch, fan_hub(type) / 2);
circle(r);
for(a = [45 : 90 : 360])
rotate(a)
translate([r / 2, 0])
circle(wall);
}
}
}