summaryrefslogtreecommitdiffabout
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--.gitignore2
-rw-r--r--Makefile12
-rw-r--r--fanduct-3jets.scad2
-rw-r--r--fanduct-circular.scad2
-rw-r--r--fanduct.scad241
-rw-r--r--snapper.scad27
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
3OPENSCAD_APP?=/Applications/OpenSCAD.app
4OPENSCAD_BIN?=${OPENSCAD_APP}/Contents/MacOS/OpenSCAD
5
6default: fanduct-circular.stl fanduct-3jets.stl
7
8fanduct-%.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 @@
1use <fanduct.scad>;
2fanduct(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 @@
1use <fanduct.scad>;
2fanduct(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 @@
1use <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
23hotend_clearance = 12;
24
25 snapper_d = 8; snapper_overlap=0.2;// snip snap
26
27smooth_f = 120;
28
29type="3jets"; // "3jets" ; // circular|3jets
30
31
32module 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
225view=""; // hcut|vcut|*
226
227hinfinity=4*(fanduct_ir+fanduct_shell*2+fanduct_w+inlet_away);
228vinfinity=2*(fanduct_shell*2+fanduct_h+inlet_h);
229if(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) */
2function snapper_apart(d,o) = d*(1-o);
3module 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}