-rw-r--r-- | fanduct.scad | 241 |
1 files changed, 241 insertions, 0 deletions
diff --git a/fanduct.scad b/fanduct.scad new file mode 100644 index 0000000..d711166 --- a/dev/null +++ b/fanduct.scad | |||
@@ -0,0 +1,241 @@ | |||
1 | use <snapper.scad>; | ||
2 | extrusion_width=.5; layer_height=.2; // print parameters | ||
3 | |||
4 | epsilon=.005; // for finer cuts | ||
5 | |||
6 | heater_w = 16; // heatblock width | ||
7 | heater_l = 20; // heatblock length | ||
8 | nozzle_offset=4.5;// nozzle offset from the edge of heatblock | ||
9 | |||
10 | fanduct_elevation = 3; // fanduct elevation above nozzle tip | ||
11 | fanduct_h = 6; // inner height of the duct | ||
12 | fanduct_w = 6; // inner width of the duct | ||
13 | fanduct_shell=1.2; // shell thickness | ||
14 | fanduct_ir = sqrt(pow(heater_w/2,2)+pow(heater_l-nozzle_offset,2))+5;// inner radius | ||
15 | |||
16 | jet_angle = 60; // angular width of the jet | ||
17 | |||
18 | inlet_w = 12.5; // inlet width | ||
19 | inlet_h = 17; // inlet height | ||
20 | inlet_l = 7; // inlet length of protrusion (or depth of intrusion:)) | ||
21 | inlet_away = 15;// how far away inlet is | ||
22 | |||
23 | hotend_clearance = 12; | ||
24 | |||
25 | snapper_d = 8; snapper_overlap=0.2;// snip snap | ||
26 | |||
27 | smooth_f = 120; | ||
28 | |||
29 | type="3jets"; // "3jets" ; // circular|3jets | ||
30 | |||
31 | |||
32 | module fanduct(type=type) { | ||
33 | |||
34 | // ***duct is all around! | ||
35 | module duct(what) { | ||
36 | if(what=="in") { | ||
37 | rotate_extrude($fn=smooth_f) | ||
38 | translate([fanduct_ir,0]) | ||
39 | square([fanduct_w+2*fanduct_shell,fanduct_h+2*fanduct_shell]); | ||
40 | }else if(what=="out") { | ||
41 | rotate_extrude($fn=smooth_f) | ||
42 | translate([fanduct_ir+fanduct_shell,fanduct_shell]) | ||
43 | union() { | ||
44 | square([fanduct_w,fanduct_h/2]); | ||
45 | translate([fanduct_w/2,fanduct_h-fanduct_w/2]) | ||
46 | rotate([0,0,90]) circle(d=fanduct_w,$fn=36); | ||
47 | } | ||
48 | } | ||
49 | } | ||
50 | |||
51 | // ***bumps for easier position adjustments in line with hotend | ||
52 | module marks(what) { | ||
53 | if(what=="in") { | ||
54 | for(y=[-1,1]) translate([0,y*(fanduct_ir+fanduct_shell+fanduct_w/2),fanduct_shell*2+fanduct_h]) | ||
55 | rotate([90,0,0]) { | ||
56 | cylinder(r=fanduct_shell,h=fanduct_w,center=true,$fn=30); | ||
57 | for(z=[-1,1]) translate([0,0,z*fanduct_w/2]) | ||
58 | sphere(r=fanduct_shell,$fn=30); | ||
59 | } | ||
60 | } | ||
61 | } | ||
62 | |||
63 | // ***output | ||
64 | module output(what,type=type) { | ||
65 | module guideline(xyxy) { | ||
66 | module pin(xy) { | ||
67 | translate([xy[0],xy[1],0]) | ||
68 | cylinder(d=2*extrusion_width,h=2*fanduct_shell+inlet_h,$fn=6); | ||
69 | } | ||
70 | xyxyxy=concat(xyxy,[[0,0]]); | ||
71 | for(i=[0:1:len(xyxyxy)-2]) | ||
72 | hull() for(j=[i,i+1]) pin(xyxyxy[j]); | ||
73 | } | ||
74 | |||
75 | module circus(what) { | ||
76 | if(what=="in") { | ||
77 | difference() { | ||
78 | rotate_extrude($fn=smooth_f) | ||
79 | polygon([ | ||
80 | [0,-fanduct_elevation], | ||
81 | [fanduct_ir+fanduct_shell,fanduct_shell+fanduct_h/2], | ||
82 | [fanduct_ir+fanduct_shell,0], | ||
83 | [0,-fanduct_elevation-.1]]); | ||
84 | translate([0,0,-1]) | ||
85 | cylinder(r=hotend_clearance,h=fanduct_h+2*fanduct_shell+2,$fn=smooth_f); | ||
86 | mirror([0,0,1]) | ||
87 | translate([0,0,-epsilon]) | ||
88 | cylinder(r=fanduct_ir+fanduct_shell+1,h=fanduct_elevation+.1+2); | ||
89 | } | ||
90 | }else if(what=="out") { | ||
91 | difference() { | ||
92 | rotate_extrude($fn=smooth_f) | ||
93 | polygon([ | ||
94 | [0,-fanduct_elevation], | ||
95 | [fanduct_ir+fanduct_shell+1,fanduct_h/2], | ||
96 | [fanduct_ir+fanduct_shell+1,fanduct_shell], | ||
97 | [0,-fanduct_elevation-.1]]); | ||
98 | circus("airguides"); | ||
99 | } | ||
100 | }else if(what=="airguides") { | ||
101 | inr = fanduct_ir+fanduct_shell; our = inr+fanduct_w; | ||
102 | union() { | ||
103 | for(my=[0,1]) mirror([0,my,0]) { | ||
104 | guideline([ | ||
105 | [-our,inlet_w/6], | ||
106 | [-inr*sin(60),inr*cos(60)] | ||
107 | ]); | ||
108 | a0=30; as=15; a1=180; | ||
109 | for(a=[a0+as:as:a1]) { | ||
110 | f = as/(a1-a+as); | ||
111 | rotate([0,0,a]) guideline([[-inr-fanduct_w*f,0]]); | ||
112 | } | ||
113 | guideline([ | ||
114 | [-our+fanduct_w*cos(30)*3/4,fanduct_w*sin(30)*3/4], | ||
115 | [-inr*cos(10),inr*sin(10)] | ||
116 | ]); | ||
117 | } | ||
118 | }/*union*/ | ||
119 | }/*airguides*/ | ||
120 | } | ||
121 | |||
122 | module jets(what) { | ||
123 | od = fanduct_h/2+fanduct_shell; | ||
124 | difference() { | ||
125 | for(a=[0:120:359]) rotate([0,0,a]) { | ||
126 | if(what=="in") { | ||
127 | hull() { | ||
128 | translate([fanduct_ir+od/2,0,od/2]) | ||
129 | rotate([90,0,0]) | ||
130 | cylinder(d=od,h=2*(fanduct_ir+fanduct_shell+fanduct_w/2)*sin(jet_angle/2)-3,center=true,$fn=36); | ||
131 | translate([0,0,-fanduct_elevation]) sphere(r=.5); | ||
132 | } | ||
133 | }else if(what=="out") { | ||
134 | hull() { | ||
135 | translate([fanduct_ir+od/2,0,od/2]) | ||
136 | rotate([90,0,0]) | ||
137 | cylinder(d=od-2*fanduct_shell,h=2*(fanduct_ir+fanduct_shell+fanduct_w/2)*sin(jet_angle/2)-3-2*fanduct_shell,center=true); | ||
138 | translate([0,0,-fanduct_elevation]) sphere(r=.2); | ||
139 | } | ||
140 | |||
141 | type="3jets"; | ||
142 | } | ||
143 | } | ||
144 | if(what=="in") { | ||
145 | translate([0,0,-fanduct_elevation-2+epsilon]) | ||
146 | cylinder(r=fanduct_ir+fanduct_shell*2+fanduct_w+1,h=fanduct_elevation+2); | ||
147 | translate([0,0,-hotend_clearance]) | ||
148 | rotate([0,0,30]) | ||
149 | cylinder(r1=hotend_clearance*2,r2=0,h=hotend_clearance*2,$fn=6); | ||
150 | } | ||
151 | } | ||
152 | } | ||
153 | |||
154 | if(type=="circular") circus(what); | ||
155 | else if(type=="3jets") jets(what); | ||
156 | } | ||
157 | |||
158 | // ***air intake | ||
159 | module intake(what) { | ||
160 | module placeit() { | ||
161 | translate([-fanduct_ir-2*fanduct_shell-fanduct_w-inlet_away,0,fanduct_shell]) | ||
162 | rotate([0,-90,0]) | ||
163 | children(); | ||
164 | } | ||
165 | if(what=="in") { | ||
166 | placeit() translate([0,-inlet_w/2,0]) { | ||
167 | cube(size=[inlet_h,inlet_w,inlet_l+fanduct_shell]); | ||
168 | // supports | ||
169 | for(i=[-1,0,1]) | ||
170 | translate([-fanduct_shell, | ||
171 | (i+1)*(inlet_w-extrusion_width)/2, | ||
172 | -inlet_away-fanduct_w/2]) | ||
173 | cube(size=[fanduct_shell, | ||
174 | extrusion_width, | ||
175 | inlet_l+fanduct_shell+inlet_away+fanduct_w/2]); | ||
176 | } | ||
177 | hull() { | ||
178 | placeit() translate([-fanduct_shell,-inlet_w/2-fanduct_shell/2,0]) | ||
179 | cube(size=[inlet_h+fanduct_shell,inlet_w+fanduct_shell,fanduct_shell]); | ||
180 | translate([-fanduct_ir-fanduct_shell-fanduct_w/2,0,0]) | ||
181 | translate([0,-inlet_w/2-fanduct_shell/2,0]) | ||
182 | cube(size=[1,inlet_w+fanduct_shell,fanduct_shell*2+fanduct_h]); | ||
183 | } | ||
184 | }else if(what=="out") { | ||
185 | placeit() translate([fanduct_shell,-inlet_w/2+fanduct_shell,0]) | ||
186 | cube(size=[inlet_h-2*fanduct_shell,inlet_w-2*fanduct_shell,inlet_l+fanduct_shell+1]); | ||
187 | hull() { | ||
188 | placeit() translate([fanduct_shell,-inlet_w/2+fanduct_shell,0]) | ||
189 | cube(size=[inlet_h-2*fanduct_shell,inlet_w-2*fanduct_shell,fanduct_shell]); | ||
190 | translate([-fanduct_ir-fanduct_shell-fanduct_w/2,0,fanduct_shell]) | ||
191 | translate([0,-inlet_w/2,0]) | ||
192 | cube(size=[1,inlet_w,fanduct_h]); | ||
193 | } | ||
194 | } | ||
195 | } | ||
196 | |||
197 | // ***DUCT TAILS!!! WOO-OO! (every day they're out there making duct tails…) | ||
198 | module tails(what) { | ||
199 | if(what=="in") { | ||
200 | for(mx=[0,1]) mirror([mx,0,0]) | ||
201 | translate([fanduct_ir+fanduct_shell+fanduct_w/2,0,fanduct_shell+fanduct_h]) | ||
202 | rotate([90,0,90]) | ||
203 | translate([0,0,-snapper_d/2]) | ||
204 | snapper(d=snapper_d,o=snapper_overlap,side=0,l=fanduct_h+fanduct_shell); | ||
205 | } | ||
206 | } | ||
207 | |||
208 | module parts(what) { | ||
209 | union() { | ||
210 | duct(what); | ||
211 | marks(what); | ||
212 | output(what); | ||
213 | intake(what); | ||
214 | tails(what); | ||
215 | } | ||
216 | } | ||
217 | |||
218 | difference() { | ||
219 | parts("in"); | ||
220 | parts("out"); | ||
221 | } | ||
222 | |||
223 | } | ||
224 | |||
225 | view=""; // hcut|vcut|* | ||
226 | |||
227 | hinfinity=4*(fanduct_ir+fanduct_shell*2+fanduct_w+inlet_away); | ||
228 | vinfinity=2*(fanduct_shell*2+fanduct_h+inlet_h); | ||
229 | if(view=="hcut") { | ||
230 | difference() { | ||
231 | fanduct(); | ||
232 | translate([-hinfinity/2,-hinfinity/2,fanduct_shell+fanduct_h/2]) | ||
233 | cube(size=[hinfinity,hinfinity,vinfinity]); | ||
234 | } | ||
235 | }else if(view=="vcut") { | ||
236 | difference() { | ||
237 | fanduct(); | ||
238 | translate([-hinfinity/2,0,-vinfinity/2]) | ||
239 | cube(size=[hinfinity,hinfinity,vinfinity]); | ||
240 | } | ||
241 | }else fanduct(); | ||