piccolo

3d Printable Piccolo
git clone https://git.woozle.org/neale/piccolo.git

commit
6a3e165
parent
6a3e165
author
Neale Pickett
date
2025-05-12 09:21:28 -0600 MDT
Some initial work
3 files changed,  +235, -0
A README.md
+2, -0
1@@ -0,0 +1,2 @@
2+This is a 3D printable piccolo based on the
3+[Axianov Irish piccolo](https://www.printables.com/model/1176813-axianov-irish-piccolo).
A body.scad
+47, -0
 1@@ -0,0 +1,47 @@
 2+include <common.scad>
 3+
 4+height = 189.68;
 5+id_bot = 10.5;
 6+id_top = 12.6;
 7+
 8+toneholes = [
 9+  [40, 7.0],
10+  [66, 8.5],
11+  [81, 7.0],
12+  [106.5, 7.0],
13+  [125.0, 7.5],
14+  [144.4, 7.0],
15+];
16+
17+difference() {
18+  cylinder(h=height, d1=17.0, d2=21.6);
19+  translate([0, 0, -1]) cylinder(h=height+2, d1=id_bot, d2=id_top);
20+  for (hole = toneholes) {
21+    translate([0, 0, hole[0]]) tonehole(d=hole[1]);
22+  }
23+}
24+
25+translate([50, 0, 0])
26+union() {
27+  difference() {
28+    cylinder(h=83, d=20.4);
29+    // Inner bore
30+    translate([0, 0, 17]) cylinder(h=200, d=id_top);
31+
32+    // Resonance chamber
33+    translate([0, 0, -1]) cylinder(h=18+1, d=6.5);
34+    translate([0, 0, -0.1]) cylinder(h=10+.2, d1=15.5, d2=6.5);
35+    translate([0, 0, 20]) rotate([45, 0, -30]) cylinder(d=6, h=200);
36+
37+    // Embouchure
38+    translate([0, 0, 40]) {
39+      scale([1, 1, 1.2])
40+        rotate([90, 0, 0])
41+      cylinder(d1=id_top, d2=7, h=id_top);
42+    }
43+  }
44+  intersection() {
45+    cylinder(h=83, d=20.4);
46+    translate([-id_top/2, -100, 18]) rotate([0, -45, 0]) cube([200, 200, 1]);
47+  }
48+}
A common.scad
+186, -0
  1@@ -0,0 +1,186 @@
  2+// Make circles circular in final renders.
  3+$fn = $preview ? 0 : 180;
  4+
  5+// clearance in a permanent tenon/mortise joint
  6+clearance = 0.2;
  7+
  8+// www.tauday.com
  9+TAU = PI * 2;
 10+
 11+module brass() {
 12+  color("gold") children();
 13+}
 14+
 15+module derlin() {
 16+  color("dimgray") children();
 17+}
 18+
 19+module ivory() {
 20+  color("ivory") children();
 21+}
 22+
 23+// tube creates a hollow cylinder
 24+module tube(h=10, id=5, od=10) {
 25+  difference() {
 26+    cylinder(h=h, d=od);
 27+    translate([0, 0, -1]) cylinder(h=h+2, d=id);
 28+  }
 29+}
 30+
 31+// donut creates a torus
 32+module donut(h=1, d=10) {
 33+  rotate_extrude(angle=360) {
 34+    translate([d/2, 0]) {
 35+      circle(d=h, $fn=120);
 36+    }
 37+  }
 38+}
 39+
 40+// default height of rings
 41+rings_height = 1.8;
 42+
 43+// rings of adornment.
 44+// This engraves two rings, 1.4mm apart, at a depth of 0.4.
 45+module rings(h=0.4, d=1, depth=0.4, spacing=1.4) {
 46+  tube(h=h, id=d-depth, od=d+1);
 47+  translate([0, 0, spacing]) tube(h=h, id=d-depth, od=d+1);
 48+}
 49+
 50+// default brass tube thickness
 51+brass_thickness = 0.75;
 52+
 53+// brass_tube creates a chamfered hollow cylinder with given inside diameter,
 54+// and wall thickness of 0.75.
 55+// Decorative rings are etched into the top and bottom.
 56+module brass_tube(h=10, id=10, t=brass_thickness) {
 57+  od = id + (t*2);
 58+  cd = (id + od) / 2; // Chamfer diameter
 59+
 60+  brass() {
 61+    difference() {
 62+      tube(h=h, id=id, od=od);
 63+
 64+      // Chamfered ends
 65+      translate([0, 0, 0]) cylinder(h=1, d1=cd, d2=id);
 66+      translate([0, 0, h-1]) cylinder(h=1, d1=id, d2=cd);
 67+
 68+      translate([0, 0, 2]) rings(d=od);
 69+      translate([0, 0, h-2-rings_height]) rings(d=od);
 70+    }
 71+  }
 72+}
 73+
 74+// brass_bend provides a 180 degree bend in brass
 75+module brass_bend(od=12.7, bend_r=16, t=brass_thickness) {
 76+  color("gold") {
 77+    rotate([90, 0, 0]) {
 78+      rotate_extrude(angle=180) {
 79+        translate([bend_r, 0, 0]) {
 80+          difference() {
 81+            circle(d=od);
 82+            circle(d=od-t*2);
 83+          }
 84+        }
 85+      }
 86+    }
 87+  }
 88+}
 89+
 90+
 91+// derlin_tube is a non-chamfered sky blue tube.
 92+// I use blue so it's easier to see in preview.
 93+module derlin_tube(h=10, id=5, od=10) {
 94+  derlin() {
 95+    tube(h=h, id=id, od=od);
 96+  }
 97+}
 98+
 99+// derlin_stop is a derlin tube, chamfered on one end.
100+module derlin_stop(h=10, id=5, od=10) {
101+  chamferh = h/5;
102+  derlin() {
103+    difference() {
104+      union() {
105+        cylinder(h=h-chamferh, d=od);
106+        translate([0, 0, h-chamferh]) cylinder(h=chamferh, d1=od, d2=id);
107+        }
108+      cylinder(h=h, d=id);
109+      }
110+    }
111+}
112+
113+// default bell height
114+bell_height = 17;
115+
116+// derlin_bell makes a decorative flared bell.
117+// od will default to 33% larger than id.
118+module derlin_bell(h=bell_height, id=5, od=0) {
119+  chamferh = 1;
120+  chamferd = 1;
121+  ringsmargin = 1;
122+  toph = rings_height + ringsmargin*2 + chamferh;
123+  flareh = h - toph;
124+  od = (od == 0) ? (id * 1.33) : od;
125+  derlin() {
126+    difference() {
127+      union() {
128+        cylinder(h=flareh, d1=id, d2=od);
129+        translate([0, 0, flareh]) cylinder(h=toph-chamferh, d=od);
130+        translate([0, 0, flareh+toph-chamferh]) cylinder(h=chamferh, d1=od, d2=od-chamferd);
131+      }
132+      cylinder(h=h, d=id);
133+      translate([0, 0, flareh + ringsmargin]) rings(d=od);
134+    }
135+  }
136+}
137+
138+// A tenon joint.
139+//
140+// You have to do this twice, to make two pieces. Glue them together.
141+module tenon(h, od, top, depth=20, thickness=2) {
142+  cl = top ? 0 : clearance;
143+  module cut() {
144+    cutd = od - thickness - cl;
145+    cylinder(h=h+depth, d=cutd);
146+    cylinder(h=h, d=50);
147+    translate([0, 0, h + depth]) cylinder(h=cutd, d1=cutd, d2=0);
148+  }
149+
150+  if (top) {
151+    difference() {
152+      children();
153+      cut();
154+    }
155+  } else {
156+    intersection() {
157+      children();
158+      cut();
159+    }
160+  }
161+}
162+
163+// Round tone hole
164+module tonehole(d=10, h=50) {
165+  rotate([90, 0, 0]) cylinder(d=d, h=h);
166+}
167+
168+// Axianov tonehole with the same surface area as an equivalent cylinder
169+module axianov_hole(d=10, h=50) {
170+  r = d/2;
171+  area = PI*r*r;
172+
173+  rounding_r = 2;
174+  rounding_area = (1 - PI/4) * (rounding_r^2); // area lost to rounding
175+  goal_area = area + rounding_area;
176+
177+  w = max(6.25, d-4); // Marat uses 6.25mm on every hole, so we will too
178+  l = goal_area / w;
179+
180+  translate([-w/2, -l/2, 0]) {
181+    union() {
182+      translate([rounding_r, rounding_r, 0]) cylinder(r=rounding_r, h=h);
183+      translate([rounding_r, 0, 0]) cube([w-rounding_r, l, h]);
184+      translate([0, rounding_r, 0]) cube([w, l-rounding_r, h]);
185+    }
186+  }
187+}