piccolo

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

commit
956a01c
parent
84ae56f
author
Neale Pickett
date
2025-12-02 13:35:23 -0700 MST
Fix rotation of tone holes
4 files changed,  +48, -52
M body.scad
+42, -49
  1@@ -9,66 +9,59 @@ stamp = str(rev);
  2 module body() {
  3   d1 = 17.0;
  4   d2 = 20.4;
  5-  toneholes = [
  6-               [40, 7.0],
  7-               [66, 8.5],
  8-               [81, 7.0],
  9-               [106.5, 7.0],
 10-               [125.0, 7.5],
 11-               [144.4, 7.0],
 12-               ];
 13 
 14-
 15-  union() {
 16-    difference() {
 17-      // Combine cylinders to make it look curvy
 18-      union() {
 19-        bend_bot = 100;
 20-        bend_top = 180;
 21-        cylinder(h=body_height, d1=d1, d2=(d1+d2)/2);
 22-        translate([0, 0, bend_bot]) cylinder(h=bend_top-bend_bot, d1=d1, d2=d2);
 23-        translate([0, 0, bend_top]) cylinder(h=body_height-bend_top, d=d2);
 24+  difference() {
 25+    // Combine cylinders to make it look curvy
 26+    union() {
 27+      bend_bot = 100;
 28+      bend_top = 180;
 29+      cylinder(h=body_height, d1=d1, d2=(d1+d2)/2);
 30+      translate([0, 0, bend_bot]) cylinder(h=bend_top-bend_bot, d1=d1, d2=d2);
 31+      translate([0, 0, bend_top]) cylinder(h=body_height-bend_top, d=d2);
 32+        
 33+      // Rings
 34+      translate([0, 0, body_height-1.5]) torus((d2+3)/2, (d2-3)/2);
 35+      difference() {
 36+        // Fat one at the bottom, for good bed adhesion
 37+        translate([0, 0, 0]) torus((d1+3)/2, (d1-3)/2);
 38+        translate([0, 0, -25]) cube(50, center=true);
 39       }
 40+    }
 41 
 42-      // Inner bore, the most important part of the whole instrument!
 43-      translate([0, 0, -1]) cylinder(h=body_height+2, d1=id_bot, d2=id_top);
 44+    // Inner bore, the most important part of the whole instrument!
 45+    translate([0, 0, -1]) cylinder(h=body_height+2, d1=id_bot, d2=id_top);
 46 
 47-      // Tone holes
 48-      for (hole = toneholes) {
 49-        translate([0, 0, hole[0]]) tonehole(d=hole[1]);
 50-      }
 51+    // Tone holes
 52+    translate([0, 0, 40]) axianov_hole(d=7.0, flipped=true);
 53+    translate([0, 0, 66]) axianov_hole(d=8.5, flipped=true);
 54+    translate([0, 0, 81]) axianov_hole(d=7.0, flipped=true);
 55+    translate([0, 0, 106.5]) axianov_hole(d=7.0);
 56+    translate([0, 0, 125.0]) axianov_hole(d=7.5);
 57+    translate([0, 0, 144.4]) axianov_hole(d=7.0);
 58 
 59-      // Mortise
 60-      translate([0, 0, body_height-25]) {
 61-        d = 16.9;
 62-        cylinder(h=25, d=d);
 63-        translate([0, 0, -d/2]) cylinder(h=d/2, d1=0, d2=d);
 64-      }
 65+    // Mortise
 66+    translate([0, 0, body_height-25]) {
 67+      d = 16.9;
 68+      cylinder(h=25, d=d);
 69+      translate([0, 0, -d/2]) cylinder(h=d/2, d1=0, d2=d);
 70+    }
 71 
 72-      translate([0, 0, 4]) intersection() {
 73-        cylinder_tube(50, d1/2+0.5, 1);
 74-        union() {
 75-          rotate([90, 90, -90]) {
 76-            linear_extrude(height=d1, convexity=4) {
 77-              translate([-8, -5]) import("ruby.svg");
 78-            }
 79+    // Sigil
 80+    translate([0, 0, 4]) intersection() {
 81+      cylinder_tube(50, d1/2+0.5, 1);
 82+      union() {
 83+        rotate([90, 90, -90]) {
 84+          linear_extrude(height=d1, convexity=4) {
 85+            translate([-8, -5]) import("ruby.svg");
 86           }
 87-          rotate([90, 90, -160]) {
 88-            linear_extrude(height=d1, convexity=10) {
 89-              text(stamp, size=2, halign="right", valign="center");
 90-            }
 91+        }
 92+        rotate([90, 90, -160]) {
 93+          linear_extrude(height=d1, convexity=10) {
 94+            text(stamp, size=2, halign="right", valign="center");
 95           }
 96         }
 97       }
 98     }
 99-
100-    // Rings
101-    translate([0, 0, body_height-1.5]) torus((d2+3)/2, (d2-3)/2);
102-    difference() {
103-      // Fat one at the bottom, for good bed adhesion
104-      translate([0, 0, 0]) torus((d1+3)/2, (d1-3)/2);
105-      translate([0, 0, -25]) cube(50, center=true);
106-    }
107   }
108 }
109 
M common.scad
+4, -1
 1@@ -10,7 +10,7 @@ module tonehole(d=10, h=50) {
 2 }
 3 
 4 // Axianov tonehole with the same surface area as an equivalent cylinder
 5-module axianov_hole(d=10, h=50) {
 6+module axianov_hole(d=10, h=50, angle=45, flipped=false) {
 7   r = d/2;
 8   area = PI*r*r;
 9 
10@@ -21,6 +21,9 @@ module axianov_hole(d=10, h=50) {
11   w = max(6.25, d-4); // Marat uses 6.25mm on every hole, so we will too
12   l = goal_area / w;
13 
14+  mirror([flipped?1:0, 0, 0])
15+  rotate([0, -45, 0])
16+  rotate([0, 90, -90])
17   translate([-w/2, -l/2, 0]) {
18     union() {
19       translate([rounding_r, rounding_r, 0]) cylinder(r=rounding_r, h=h);
M head.3mf
+0, -0
M head.scad
+2, -2
 1@@ -40,7 +40,7 @@ module head() {
 2       translate([0, 0, 16]) rotate([30, 0, -30]) cylinder(d=6, h=200);
 3 
 4       // Embouchure
 5-      translate([0, 0, 45]) {
 6+      translate([0, 0, 48]) {
 7         rotate([90, 90, 0]) {
 8           // https://vintagefluteshop.com/articles/embouchure/art5.html
 9           undercut = 10; // degrees
10@@ -49,7 +49,7 @@ module head() {
11             // This part is where the air hits,
12             // so we try to optimize for the hard edge.
13             translate([0, 0, od_top/2]) {
14-              for (vertex = [[-3, -2], [3, -2]]) {
15+              for (vertex = [[-5, -3], [5, -3]]) {
16                 translate(vertex) rotate([180-undercut, 0, 0]) cylinder(r=corner_r, h=(od_top-id_top)/2);
17               }
18             }