author | Michael Krelin <hacker@klever.net> | 2016-05-27 13:27:38 (UTC) |
---|---|---|
committer | Michael Krelin <hacker@klever.net> | 2016-05-27 19:40:59 (UTC) |
commit | ead35d4dd76ff079399b9ac6272fa86d3b23a2dc (patch) (unidiff) | |
tree | 966ca9d57989a6b380b67b05c688407e7163bec2 | |
download | fanductory-ead35d4dd76ff079399b9ac6272fa86d3b23a2dc.zip fanductory-ead35d4dd76ff079399b9ac6272fa86d3b23a2dc.tar.gz fanductory-ead35d4dd76ff079399b9ac6272fa86d3b23a2dc.tar.bz2 |
initial import
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | Makefile | 12 | ||||
-rw-r--r-- | fanduct-3jets.scad | 2 | ||||
-rw-r--r-- | fanduct-circular.scad | 2 | ||||
-rw-r--r-- | fanduct.scad | 241 | ||||
-rw-r--r-- | snapper.scad | 27 |
6 files changed, 286 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..edc57ed --- a/dev/null +++ b/.gitignore | |||
@@ -0,0 +1,2 @@ | |||
1 | /Makefile.local | ||
2 | *.stl | ||
diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..3afaa64 --- a/dev/null +++ b/Makefile | |||
@@ -0,0 +1,12 @@ | |||
1 | -include Makefile.local | ||
2 | |||
3 | OPENSCAD_APP?=/Applications/OpenSCAD.app | ||
4 | OPENSCAD_BIN?=${OPENSCAD_APP}/Contents/MacOS/OpenSCAD | ||
5 | |||
6 | default: fanduct-circular.stl fanduct-3jets.stl | ||
7 | |||
8 | fanduct-%.stl: fanduct-%.scad fanduct.scad | ||
9 | |||
10 | |||
11 | %.stl: %.scad | ||
12 | ${OPENSCAD_BIN} ${OPENSCAD_FLAGS} -o "$@" "$<" | ||
diff --git a/fanduct-3jets.scad b/fanduct-3jets.scad new file mode 100644 index 0000000..cd88ab0 --- a/dev/null +++ b/fanduct-3jets.scad | |||
@@ -0,0 +1,2 @@ | |||
1 | use <fanduct.scad>; | ||
2 | fanduct(type="3jets"); | ||
diff --git a/fanduct-circular.scad b/fanduct-circular.scad new file mode 100644 index 0000000..caaf6e4 --- a/dev/null +++ b/fanduct-circular.scad | |||
@@ -0,0 +1,2 @@ | |||
1 | use <fanduct.scad>; | ||
2 | fanduct(type="circular"); | ||
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(); | ||
diff --git a/snapper.scad b/snapper.scad new file mode 100644 index 0000000..0c258ca --- a/dev/null +++ b/snapper.scad | |||
@@ -0,0 +1,27 @@ | |||
1 | /* d - diameter, o - overlap (fraction) */ | ||
2 | function snapper_apart(d,o) = d*(1-o); | ||
3 | module snapper(d,o,l=-1,side=0) { | ||
4 | snapper_apart = d*(1-o); | ||
5 | l_ = (l<0) ? d : l; | ||
6 | lw = d/2; | ||
7 | sfn = 8*d; | ||
8 | module lm() { | ||
9 | translate([-lw/2,0,0]) hull() { | ||
10 | cube(size=[lw,l_-d/2,d]); | ||
11 | translate([lw/2,l_,0]) cylinder(d=d/8,h=d,$fn=sfn); | ||
12 | } | ||
13 | } | ||
14 | if(side==0) { | ||
15 | translate([0,l_,d/2]) sphere(d=d,$fn=sfn); | ||
16 | lm(); | ||
17 | }else if(side==1) { | ||
18 | difference() { | ||
19 | for(x=[-1,1]) translate([x*snapper_apart(d,o),0,0]) { | ||
20 | translate([0,l_,d/2]) sphere(d=d,$fn=sfn); | ||
21 | lm(); | ||
22 | } | ||
23 | translate([0,l_,d/2]) sphere(d=d,$fn=sfn); | ||
24 | } | ||
25 | }else | ||
26 | echo("ERROR: what side?"); | ||
27 | } | ||