2019-06-08 17:10:47 -04:00
//
// 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 <https://www.gnu.org/licenses/>.
//
//
//! Axial fans.
//!
//! Can draw three styles: solid, open frame and open frame with screw bosses.
//
2020-02-29 12:52:36 -05:00
include < ../utils/core/core.scad >
2019-06-08 17:10:47 -04:00
use < screw.scad >
use < nut.scad >
use < washer.scad >
use < ../utils/tube.scad >
2020-06-20 05:17:29 -04:00
fan_colour = grey ( 20 ) ;
2019-06-08 17:10:47 -04:00
function fan_width ( type ) = type [ 0 ] ; //! Width of square
function fan_depth ( type ) = type [ 1 ] ; //! Depth of fan
function fan_bore ( type ) = type [ 2 ] ; //! Diameter of the hole for the blades
function fan_hole_pitch ( type ) = type [ 3 ] ; //! Screw hole pitch
function fan_screw ( type ) = type [ 4 ] ; //! Screw type
function fan_hub ( type ) = type [ 5 ] ; //! Diameter of the hub
function fan_thickness ( type ) = type [ 6 ] ; //! Thickness of the frame
function fan_outer_diameter ( type ) = type [ 7 ] ; //! Outside diameter of the frame
function fan_blades ( type ) = type [ 8 ] ; //! The number of blades
function fan_boss_d ( type ) = type [ 9 ] ; //! Diameter of the screw bosses
function fan_aperture ( type ) = type [ 10 ] ? type [ 10 ] : fan_bore ( type ) ; //! Optional diameter for the aperture, which can be bigger than the bore it has flared corners.
module fan ( type ) { //! Draw specified fan, origin in the centre
width = fan_width ( type ) ;
depth = fan_depth ( type ) ;
thickness = fan_thickness ( type ) ;
hole_pitch = fan_hole_pitch ( type ) ;
corner_radius = width / 2 - hole_pitch ;
screw = fan_screw ( type ) ;
vitamin ( str ( "fan(fan" , width , "x" , depth , "): Fan " , width , "mm x " , depth , "mm" ) ) ;
module squarish ( s , n ) {
polygon ( [
for ( i = [ 0 : n ] ) [ i * s . x / n , s . y + ( i % 2 ) * eps ] ,
for ( i = [ 0 : n ] ) [ s . x - i * s . x / n , ( i % 2 ) * eps ] ,
] ) ;
}
module shape ( )
difference ( ) {
//overall outside
rounded_square ( [ width , width ] , corner_radius ) ;
//main inside bore, less hub
difference ( ) {
circle ( fan_bore ( type ) / 2 ) ;
circle ( fan_hub ( type ) / 2 ) ;
}
//Mounting holes
fan_hole_positions ( type )
circle ( screw_clearance_radius ( screw ) ) ;
}
color ( fan_colour ) {
middle = depth - 2 * thickness ;
if ( middle > 0 ) {
for ( z = [ - 1 , 1 ] )
translate_z ( z * ( depth - thickness ) / 2 )
2020-03-29 15:18:57 -04:00
linear_extrude ( thickness , center = true )
2019-06-08 17:10:47 -04:00
shape ( ) ;
2020-03-29 15:18:57 -04:00
linear_extrude ( middle , center = true )
2019-06-08 17:10:47 -04:00
difference ( ) {
shape ( ) ;
difference ( ) {
circle ( sqrt ( 2 ) * width / 2 ) ;
circle ( d = fan_outer_diameter ( type ) ) ;
if ( fan_boss_d ( type ) )
for ( i = [ - 1 , 1 ] )
hull ( )
for ( side = [ - 1 , 1 ] )
translate ( [ hole_pitch * side * i , hole_pitch * side ] )
circle ( d = fan_boss_d ( type ) ) ;
}
}
}
else
2020-03-29 15:18:57 -04:00
linear_extrude ( depth , center = true )
2019-06-08 17:10:47 -04:00
shape ( ) ;
// Blades
blade_ir = fan_hub ( type ) / 2 - 1 ;
blade_len = fan_bore ( type ) / 2 - 0.75 - blade_ir ;
2020-03-29 15:18:57 -04:00
linear_extrude ( depth - 1 , center = true , convexity = 4 , twist = - 30 , slices = round ( depth / 2 ) )
2019-06-08 17:10:47 -04:00
for ( i = [ 0 : fan_blades ( type ) - 1 ] )
rotate ( ( 360 * i ) / fan_blades ( type ) )
translate ( [ blade_ir , - 1.5 / 2 ] )
squarish ( [ blade_len , 1.5 ] , round ( blade_len / 2 ) ) ;
}
}
module fan_hole_positions ( type , z = undef ) { //! Position children at the screw hole positions
hole_pitch = fan_hole_pitch ( type ) ;
for ( x = [ - hole_pitch , hole_pitch ] )
for ( y = [ - hole_pitch , hole_pitch ] )
translate ( [ x , y , is_undef ( z ) ? fan_depth ( type ) / 2 : z ] )
children ( ) ;
}
2020-12-24 11:04:59 -05:00
module fan_holes ( type , poly = false , screws = true , h = 100 ) { //! Make all the holes for the fan, or just the aperture if `screws` is false. Set `poly` true for poly_holes.
2019-06-08 17:10:47 -04:00
hole_pitch = fan_hole_pitch ( type ) ;
screw = fan_screw ( type ) ;
extrude_if ( h ) {
if ( screws )
fan_hole_positions ( type , z = 0 )
if ( poly )
poly_circle ( r = screw_clearance_radius ( screw ) ) ;
else
drill ( screw_clearance_radius ( screw ) , 0 ) ;
difference ( ) {
intersection ( ) {
square ( fan_bore ( type ) , center = true ) ;
circle ( d = fan_aperture ( type ) ) ;
}
if ( screws )
fan_hole_positions ( type , z = 0 )
circle ( d = washer_diameter ( screw_washer ( screw ) ) + 1 ) ;
}
}
}
2019-10-22 11:21:05 -04:00
function fan_screw_depth ( type , full_depth = false ) = fan_boss_d ( type ) || full_depth ? fan_depth ( type ) : fan_thickness ( type ) ;
2019-06-08 17:10:47 -04:00
2019-10-22 11:21:05 -04:00
function fan_screw_length ( type , thickness , full_depth = false ) =
let ( depth = fan_screw_depth ( type , full_depth ) ,
washers = depth = = fan_depth ( type ) ? 2 : 1 ,
washer = screw_washer ( fan_screw ( type ) ) ,
nut = screw_nut ( fan_screw ( type ) ) )
screw_longer_than ( thickness + depth + washer_thickness ( washer ) * washers + nut_thickness ( nut , true ) ) ; //! Screw length required
module fan_assembly ( type , thickness , include_fan = true , screw = false , full_depth = false ) { //! Fan with its fasteners
2019-06-08 17:10:47 -04:00
translate_z ( - fan_depth ( type ) / 2 ) {
if ( include_fan )
fan ( type ) ;
2019-07-19 05:51:59 -04:00
Screw = screw ? screw : fan_screw ( type ) ;
nut = screw_nut ( Screw ) ;
2019-06-08 17:10:47 -04:00
fan_hole_positions ( type ) {
translate_z ( thickness )
2019-10-22 11:21:05 -04:00
screw_and_washer ( Screw , fan_screw_length ( type , thickness , full_depth ) ) ;
2019-06-08 17:10:47 -04:00
2019-10-22 11:21:05 -04:00
translate_z ( include_fan ? - fan_screw_depth ( type , full_depth ) : 0 )
2019-06-08 17:10:47 -04:00
vflip ( )
2019-10-22 11:21:05 -04:00
if ( fan_screw_depth ( type , full_depth ) = = fan_depth ( type ) )
nut_and_washer ( nut , true ) ;
else
nut ( nut , true ) ;
2019-06-08 17:10:47 -04:00
}
}
}