uilleann

3d printable Uilleann bagpipes
git clone https://git.woozle.org/neale/uilleann.git

commit
cb65741
parent
78c7c9f
author
Neale Pickett
date
2025-11-27 21:16:51 -0700 MST
new update to rowsome
7 files changed,  +249, -0
A pickett-d/Makefile
+8, -0
1@@ -0,0 +1,8 @@
2+rev=$(shell git log -1 --pretty='format:%cd' --date='format:%Y-%m-%d')
3+
4+all: top.3mf bottom.3mf
5+clean:
6+	rm -f *.3mf
7+
8+%.3mf: %.scad chanter.scad
9+	openscad -D rev=\"$(rev)\" -o $@ $<
A pickett-d/bottom.scad
+5, -0
1@@ -0,0 +1,5 @@
2+use <./chanter.scad>
3+
4+split(top=false) {
5+  chanter();
6+}
A pickett-d/chanter.scad
+176, -0
  1@@ -0,0 +1,176 @@
  2+// Based on O'Flynn Rowsome Chanter Measurements
  3+// http://pipers.ie/source/media/?mediaId=31307&galleryId=1353
  4+
  5+use <./tenon.scad>
  6+
  7+$fn =60;
  8+
  9+// Diameter of screw hole
 10+Screwhole = 4; // [1:10]
 11+
 12+module metal() {
 13+    color("silver") children();
 14+}
 15+
 16+module leather() {
 17+    color("sienna") children();
 18+}
 19+
 20+module ivory() {
 21+    color("wheat") children();
 22+}
 23+
 24+module wood() {
 25+    color("saddlebrown") children();
 26+}
 27+
 28+// A shape like a hamburger patty
 29+module patty(h, d) {
 30+    intersection() {
 31+        cylinder(h=h, d=d);
 32+        translate([0, 0, h/2]) {
 33+            resize([d, d, h*3]) {
 34+                sphere(d=d);
 35+            }
 36+        }
 37+    }
 38+}    
 39+
 40+// A cylinder with something like a compression fitting around it
 41+module ringyding(h, d) {
 42+  ivory() resize([d, d, h]) sphere(d=d);
 43+}
 44+
 45+// A fillet is a sort of trumpet bell shape
 46+module fillet(h, d1, d2) {
 47+  r = abs(d1-d2)/2;
 48+  render(convexity=4) {
 49+    resize([d1, d1, h]) {
 50+      rotate_extrude() {
 51+        translate([d2/2, 0, 0]) {
 52+          difference() {
 53+            square([r, r]);
 54+            translate([r, r]) circle(r=r);
 55+          }
 56+        }
 57+      }
 58+    }
 59+  }
 60+}
 61+
 62+// An upside-down fillet
 63+module tellif(h, d2, d1) {
 64+    translate([0, 0, h]) mirror([0, 0, 1]) fillet(h, d1, d2);
 65+}
 66+
 67+// Absolutely nothing: helps make the code look better
 68+module nothing(h) {
 69+}
 70+
 71+// Just a rotated cylinder
 72+// h: height of the *top* of the protrusion
 73+// d: height of the protrusion (diameter?)
 74+// protrusion: amount of protrusion
 75+module bumpout(h, d, protrusion) {
 76+    intersection() {
 77+        translate([0, -protrusion, h-d]) {
 78+            cylinder(h=d, d=20.4);
 79+        }
 80+        translate([0, -protrusion, h-d/2]) {
 81+            sphere(d=protrusion*4);
 82+        }
 83+        translate([0, 0, h-d]) {
 84+            cylinder(h=d, d1=19, d2=50);
 85+        }
 86+    }
 87+}
 88+
 89+
 90+// A tonehole with :
 91+// * height=h
 92+// * transverse diameter = td
 93+// * longitudinal diameter = ld
 94+// * chimney height = ch
 95+// * undercut multiplier
 96+module tonehole(h, td, ld, ch, undercut=1) {
 97+  translate([0, 0, h]) {
 98+    rotate(a=90, v=[1, 0, 0]) {
 99+      resize([td*undercut, ld*undercut, ch]) {
100+        cylinder(h=1, d2=100, d1=100*undercut);
101+      }
102+    }
103+  }
104+}
105+
106+module chanter() {
107+    difference() {
108+        union() {
109+            translate([0, 0,  0]) metal() cylinder(h=22.0, d=17.1);
110+            translate([0, 0, 22]) wood() cylinder(h=23.5, d=17.1);  // Rings go around this
111+            
112+            // Decorative stuff on the bottom
113+            translate([0, 0, 32]) {          
114+                translate([0, 0, 1.7]) ringyding(h=8, d=28);
115+                translate([0, 0, 8.2]) ringyding(h=5, d=22);
116+            }
117+
118+            // A taper on that bottom ring so it will print nicely
119+            translate([0, 0, 12]) wood() tellif(h=20, d1=25.5, d2=100);
120+            
121+            // Main body
122+            translate([0, 0, 32.5]) wood() cylinder(h=258, d1=20.4, d2=18);
123+            
124+            // Top decoration
125+          translate([0, 0, 290.4]) {
126+                color("silver") cylinder(h=40.8, d=17);
127+                
128+                translate([0, 0,  0.0]) ringyding(h=5.5, d=20);
129+                translate([0, 0,  5.5]) nothing(h=9.7); // metal
130+                translate([0, 0, 15.2]) ringyding(h=4.3, d=19);
131+                translate([0, 0, 19.5]) nothing(h=6.7); // metal
132+                translate([0, 0, 27.2]) ringyding(h=5.5, d=20.2);
133+                translate([0, 0, 28.2]) leather() {
134+                  // XXX: kludge
135+                  tellif(h=8, d2=19, d1=23);
136+                  cylinder(h=8, d=19);
137+                }
138+                translate([0, 0, 37.9]) ringyding(h=8, d=25.4);
139+            }
140+            
141+            // This protects the reed and provides a place for tubing to connect
142+            translate([0, 0, 324.5]) metal() cylinder(h=32.7, d=14.8);
143+            
144+            // Bumpouts
145+            // These angles are my best guess based on photos
146+            rotate(220) wood() bumpout(161.2, 14.8, 6); // protrusion guessed
147+        }
148+
149+        // Inner bore
150+        union() {
151+            translate([0, 0, -0.01]) { // Go just a bit past the ends
152+                translate([0, 0,   0]) cylinder(h=337.01, d1=13.2, d2=5.51);
153+                translate([0, 0, 337]) cylinder(h=21, d1=5.51, d2=7.1);
154+            }
155+        }
156+
157+        // Tone Holes!
158+        translate([0, 0, 5]) { // This offset is specified nowhere. I'm guessing to make it fit the bumpouts.
159+          rotate(180) tonehole(263, 6.04, 7.95, 10.1, 1.2); // back D
160+          rotate(0) tonehole(246.4, 6.42, 6.57, 11.3); // C♯
161+          rotate(0) tonehole(216.2, 6.89, 6.96, 11.3); // B
162+          rotate(0) tonehole(182, 8.85, 9.06, 11.4); // A
163+          rotate(0) tonehole(147.4, 6.98, 7.44, 12.2); //  G
164+          rotate(0) tonehole(116.2, 8.39, 8.88, 12.7); // F♯
165+          rotate(0) tonehole(84.7, 5.25, 5.49, 14); // E
166+          rotate(0) tonehole(53.3, 6.94, 7.16, 14.1); // E♭
167+        }
168+    }
169+}
170+
171+module split(top=false) {
172+  tenon(top=top, h=162, d=15, depth=15) {
173+    children();
174+  }
175+}
176+
177+chanter();
A pickett-d/ruby.svg
+9, -0
 1@@ -0,0 +1,9 @@
 2+<?xml version="1.0" encoding="utf-8"?>
 3+<svg xmlns="http://www.w3.org/2000/svg" height="1cm" width="0.924cm" viewBox="0 0 500 500" xmlns:bx="https://boxy-svg.com">
 4+  <defs>
 5+    <bx:export>
 6+      <bx:file format="png" path="ruby.png"/>
 7+    </bx:export>
 8+  </defs>
 9+  <path style="stroke: rgb(0, 0, 0); fill: rgb(107, 84, 84); transform-box: fill-box; transform-origin: 50% 50%;" d="M 187.594 147.071 C 222.949 153.12 270.972 155.731 309.277 143.299 C 317.317 140.69 324.255 101.717 337.777 84.73 C 365.301 50.153 418.636 3.565 440.95 1.462 C 463.264 -0.641 461.076 -0.732 469.218 12.046 C 477.36 24.824 453.472 138.031 453.472 138.031 C 453.472 138.031 453.953 147.266 444.263 160.449 C 434.573 173.632 447.673 167.61 440.944 190.185 C 434.215 212.76 438.017 200.224 427.718 215.259 C 417.419 230.294 397.67 242.025 388.524 251.061 C 379.378 260.097 386.798 291.019 386.798 291.019 C 386.798 291.019 387.847 326.31 381.141 347.368 C 374.435 368.426 346.18 391.255 346.18 391.255 C 346.18 391.255 325.323 472.928 268.206 481.757 C 211.089 490.586 166.483 394.938 166.483 394.938 C 166.483 394.938 144.005 389.647 131.704 371.16 C 119.403 352.673 108.748 336.052 108.361 311.035 C 107.974 286.018 101.518 264.509 101.518 264.509 C 101.518 264.509 89.405 262.542 85.275 256.613 C 81.145 250.684 78.859 245.845 70.152 238.568 C 59.127 229.354 42.841 226.273 39.22 199.414 C 35.599 172.555 36.125 179.11 36.125 179.11 C 36.125 179.11 23.121 168.902 31.274 144.728 C 39.427 120.554 89.353 134.561 107.159 120.958 C 124.965 107.355 114.883 115.961 133.013 98.781 C 151.143 81.601 175.442 122.255 175.442 122.255 C 175.442 122.255 178.724 145.553 187.594 147.071 Z" id="object-1" transform="matrix(0.999073, 0.043046, -0.043046, 0.999073, 0.014376, 0.000286)"/>
10+</svg>
A pickett-d/sigil.scad
+21, -0
 1@@ -0,0 +1,21 @@
 2+use <MCAD/regular_shapes.scad>
 3+
 4+module sigil(d, stamp, rot=0) {
 5+  // Sigil
 6+  translate([0, 0, 4]) intersection() {
 7+    cylinder_tube(50, d/2+0.5, 1);
 8+    union() {
 9+      rotate([90, 0, -90]) {
10+        linear_extrude(height=d, convexity=4) {
11+          translate([-4, 0]) import("ruby.svg");
12+          // XXX: when this is in openscad prod, add center to import and remove translate
13+        }
14+      }
15+      rotate([90, 90, -160]) {
16+        linear_extrude(height=d, convexity=10) {
17+          text(stamp, size=2, halign="right", valign="center");
18+        }
19+      }
20+    }
21+  }
22+}
A pickett-d/tenon.scad
+24, -0
 1@@ -0,0 +1,24 @@
 2+use <BOSL/math.scad>
 3+
 4+module tenon(top=false, h=100, d=5, depth=20, thickness=2, clearance=0.2) {
 5+  module cut() {
 6+    id = d-thickness+clearance;
 7+    translate([0, 0, h+depth]) cylinder(h=id/2, d1=id, d2=0);
 8+    cylinder(h=h+depth, d=id);
 9+    cylinder(h=h, d=id+40);
10+  }
11+
12+  if (top) {
13+    difference() {
14+      children();
15+      cut();
16+    }
17+  } else {
18+    intersection() {
19+      children();
20+      cut();
21+    }
22+  }
23+}
24+
25+chanter();
A pickett-d/top.scad
+6, -0
1@@ -0,0 +1,6 @@
2+use <./chanter.scad>
3+use <./tenon.scad>
4+
5+split(top=true) {
6+  chanter();
7+}