uilleann

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

uilleann / rowsome
Neale Pickett  ·  2025-01-01

chanter-full.scad

  1// Based on O'Flynn Rowsome Chanter Measurements
  2// http://pipers.ie/source/media/?mediaId=31307&galleryId=1353
  3
  4overhangs = false; // Are overhangs okay? They typically require supports to be printed.
  5extended = false; // Additional holes for extra scale notes? These will require keys to be added.
  6extended_bumpouts = false; // True if you'd like the extended note bumpouts.
  7
  8module metal() {
  9    color("silver") children();
 10}
 11
 12module leather() {
 13    color("sienna") children();
 14}
 15
 16module ivory() {
 17    color("wheat") children();
 18}
 19
 20module wood() {
 21    color("brown") children();
 22}
 23
 24// A shape like a hamburger patty
 25module patty(h, d) {
 26    intersection() {
 27        cylinder(h=h, d=d);
 28        translate([0, 0, h/2]) {
 29            resize([d, d, h*3]) {
 30                sphere(d=d);
 31            }
 32        }
 33    }
 34}    
 35
 36// A cylinder with something like a compression fitting around it
 37module ringyding(h, id, od) {
 38    margin = h * 0.1;
 39    union() {
 40        leather() cylinder(h=h, d=id);
 41        translate([0, 0, margin]) ivory() patty(h=h*0.8, d=od);
 42    }
 43}
 44
 45// A fillet is a sort of trumpet bell shape
 46module fillet(h, d1, d2) {
 47    r = abs(d1-d2)/2;
 48    resize([d1, d1, h]) {
 49        rotate_extrude() {
 50            translate([d2/2, 0, 0]) {
 51                difference() {
 52                    square([r, r]);
 53                    translate([r, r]) circle(r=r);
 54                }
 55            }
 56        }
 57    }
 58}
 59
 60// An upside-down fillet
 61module tellif(h, d2, d1) {
 62    translate([0, 0, h]) mirror([0, 0, 1]) fillet(h, d1, d2);
 63}
 64
 65// Absolutely nothing: helps make the code look better
 66module nothing(h) {
 67}
 68
 69// Just a rotated cylinder
 70// h: height of the *top* of the protrusion
 71// d: height of the protrusion (diameter?)
 72// protrusion: amount of protrusion
 73// key: true if this is bumpout supports an "extended" node
 74module bumpout(h, d, protrusion, key=false) {
 75    if (!key || extended_bumpouts) {
 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            if (! overhangs) {
 84                translate([0, 0, h-d]) {
 85                    cylinder(h=d, d1=19, d2=50);
 86                }
 87            }
 88        }
 89    }
 90}
 91
 92
 93// A tonehole with :
 94// * height=h
 95// * transverse diameter = td
 96// * longitudinal diameter = ld
 97// * chimney height = ch
 98// * key: true if this hole is an "extended" note requiring a key
 99module tonehole(h, td, ld, ch, key=false) {
100    if (!key || extended) {
101        translate([0, 0, h]) {
102            rotate(a=90, v=[1, 0, 0]) {
103                resize([td, ld, 100]) {
104                    // My best guess is that the "chimney height" is the depth of the hole.
105                    cylinder(h=100, d=100);
106                }
107            }
108        }
109    }
110}
111
112module chanter() {
113    difference() {
114        union() {
115            translate([0, 0,  0]) metal() cylinder(h=22.0, d=17.1);
116            translate([0, 0, 22]) wood() cylinder(h=23.5, d=17.1);  // Rings go around this
117            
118            // Decorative stuff on the bottom
119            translate([0, 0, 32]) {          
120                translate([0, 0, 0.0]) ivory() patty(h=3.4, d=28.7);
121                translate([0, 0, 3.4]) leather() fillet(h=1.8, d1=27, d2=22);
122                translate([0, 0, 4.1]) ringyding(h=4.1, id=21, od=24);
123                translate([0, 0, 8.2]) ringyding(h=5.3, id=21, od=24);
124            }
125
126            if (! overhangs) {
127                translate([0, 0, 22]) wood() cylinder(h=10, d1=17.1, d2=28);
128            }
129            
130            // Main body
131            translate([0, 0, 45.5]) wood() cylinder(h=244.9, d1=20.4, d2=18);
132            
133            // Top decoration
134            translate([0, 0, 290.4]) {
135                color("silver") cylinder(h=40.8, d=17);
136                
137                translate([0, 0,  0.0]) ringyding(h=5.5, id=19, od=21);
138                translate([0, 0,  5.5]) nothing(h=9.7); // metal
139                translate([0, 0, 15.2]) ringyding(h=4.3, id=18, od=20.7);
140                translate([0, 0, 19.5]) nothing(h=6.7); // metal
141                translate([0, 0, 26.2]) ivory() patty(h=2, d=20.2);
142                translate([0, 0, 28.2]) leather() tellif(h=8, d2=19, d1=23);
143                translate([0, 0, 36.2]) ivory() patty(h=4.6, d=25.4);
144            }
145            
146            // I presume this protects the reed and provides a place for tubing to connect
147            translate([0, 0, 324.5]) metal() cylinder(h=32.7, d=14.8);
148            
149            // Bumpouts
150            // These angles are my best guess based on photos
151            rotate(270) wood() bumpout(253.6, 9.3, 4.6, key=true);
152            rotate(200) wood() bumpout(228.6, 15.6, 6, key=true);
153            rotate(100) wood() bumpout(193.7, 15.7, 6, key=true);
154            rotate(220) wood() bumpout(161.2, 14.8, 6); // protrusion guessed
155            rotate(90) wood() bumpout(130.5, 16.9, 6, key=true);
156        }    
157
158        // Inner bore
159        union() {
160            translate([0, 0, -0.01]) { // Go just a bit past the ends
161                translate([0, 0,   0]) cylinder(h=337.01, d1=13.2, d2=5.51);
162                translate([0, 0, 337]) cylinder(h=21, d1=5.51, d2=7.1);
163            }
164        }
165
166
167        // Tone Holes!
168        translate([0, 0, 5]) { // This offset is specified nowhere. I'm guessing to make it fit the bumpouts.
169            rotate(180) tonehole(263, 6.04, 7.95, 10.1); // back D
170            rotate(270) tonehole(257.3, 4.39, 4.36, 11.1, key=true); // high C♯ / D
171            rotate(0) tonehole(246.4, 6.42, 6.57, 11.3); // C♯
172            rotate(180) tonehole(233.3, 4.5, 4.5, 11.5, key=true); // C
173            rotate(0) tonehole(216.2, 6.89, 6.96, 11.3); // B
174            rotate(100) tonehole(198, 4.34, 4.47, 12.6, key=true); // B♭
175            rotate(0) tonehole(182, 8.85, 9.06, 11.4); // A
176            rotate(220) tonehole(165.5, 4.44, 4.44, 12.2, key=true); // G♯
177            rotate(0) tonehole(147.4, 6.98, 7.44, 12.2); //  G
178            rotate(0) tonehole(116.2, 8.39, 8.88, 12.7); // F♯
179            rotate(90) tonehole(105.7, 4.42, 4.42, 13.9, key=true); // F
180            rotate(0) tonehole(84.7, 5.25, 5.49, 14); // E
181            rotate(0) tonehole(53.3, 6.94, 7.16, 14.1); // E♭
182        }
183    }
184}
185
186// XXX: later, make multiple scad files to slice this into smaller pieces
187chanter();