GuitarModels/CFTubes.scad

398 lines
15 KiB
OpenSCAD
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

include <common.scad>
include <UBassTuner.scad>
include <NylonTuner.scad>
include <CFTubes/common.scad>
// Choose your material by only including one of the below
// include <CFTubes/PLA.scad>
include <CFTubes/PETG.scad>
// Guitar_Scale_Length_mm = 610; // millimetres, slightly over 24inch (609.6mm) Jaguar scale, should be fine for guitar and u-bass
// assert(fret_scale_length(0) == 610); // Make sure the function correctly uses our changed global
// Philippians 4:8
// Gideon (ShinKaiYaku07) 真実な, 尊ぶべき, 正しい, 清い, 愛すべき, 評判の良い, 徳とされる, 称賛に値する
// ShinKaiYaku65 最後に、兄弟たち。すべての真実なこと、すべての誉れあること、すべての正しいこと、すべてのきよいこと、すべての愛すべきこと、すべての評判の良いこと、そのほか徳と言われること、称賛に値することがあるならば、そのようなことに心を留めなさい。
// I swapped 愛 and 評判 because 12th fret should be the biggest marker, and having only 15 as a 2char marker would be too disorienting
// going with 良 for 21
fret_inlays = [[3, "真"], [5, "尊"], [7, "正"], [9, "清"], [12, "評判"], [15, "愛"], [17, "徳"], [19, "賛"], [21, "良"], [24, "主イエス"]];
module neck(string_spacing=18, string_margin=4.5, num_strings=3, target_neck_thickness=15, scallop_depth=3, num_frets=24, fret_width=2.4, filler=false) {
fw2 = fret_width/2;
neck_length = fret_scale_length(0)+fw2;
neck_width = (num_strings-1)*string_spacing + string_margin*2;
module neck_stock() {
angle_excess = asin((scallop_depth+fw2)/target_neck_thickness);
a0 = 90-angle_excess;
a1 = 270+angle_excess;
rotate([-90, 0, 0])
linear_extrude(neck_length)
polygon([for (i = [0:300]) let(a=lerp(a0, a1, i/300.0)) [neck_width*0.5*sin(a), -target_neck_thickness*cos(a)]]); // Ellipse
}
module scallop(fret) {
x0 = fret_scale_length(fret-1) - fw2;
x1 = fret_scale_length(fret) + fw2;
xmid = lerp(x0, x1, 0.5);
// Radius it?
arc = arc_points([[x0, scallop_depth], [x1, scallop_depth], [xmid, 0]]);
// echo(arc);
rotate([90, 0, 90]) linear_extrude(neck_width, center=true) polygon(arc);
}
module scallops() {
for (fret = [0:num_frets]) {
scallop(fret);
}
}
module fret_bumps() {
for (fret = [0:num_frets]) {
translate([0, fret_scale_length(fret), scallop_depth])
rotate([0, 90]) cylinder(d=fret_width, h = neck_width, center = true, $fn=200);
}
}
module fret_inlays() {
for (num_text = fret_inlays) {
fret = num_text[0];
if (fret <= num_frets) {
x0 = fret_scale_length(fret-1);
x1 = fret_scale_length(fret);
diff = x0 - x1;
translate([0, lerp(x0, x1, 0.5), -0.5])
linear_extrude(30)
text(text = num_text[1], font = JP_Serif_Font, halign = "center", valign = "center", size = clamp(2, diff-fret_width*2-2, 10));
}
}
}
module fret_side_markers() {
for (num_text = fret_inlays) {
fret = num_text[0];
if (fret <= num_frets) {
x0 = fret_scale_length(fret-1);
x1 = fret_scale_length(fret);
diff = x0 - x1;
mid = lerp(x0, x1, 0.67);
rotate([0, -94, 0])
translate([0, mid, neck_width/2-3])
linear_extrude(50)
rotate(-37)
text(text = str(fret), font = JP_Serif_Font, halign = "right", valign = "center", size = 4.5);
}
}
}
if (filler) { // Somewhat placeholder for now
difference() {
neck_stock();
scallop(25);
translate([-neck_width, 0, scallop_depth]) cube([neck_width*2, Guitar_Scale_Length_mm*3, target_neck_thickness*3]);
translate([-neck_width, 0, 0]) cube([neck_width*2, (fret_scale_length(25)+fret_scale_length(24))/2, target_neck_thickness*3]);
}
} else {
render() difference() {
neck_stock();
scallops();
scallop(num_frets+1);
fret_inlays();
fret_side_markers();
// Chop off anything above the frets
translate([-neck_width, 0, scallop_depth]) cube([neck_width*2, Guitar_Scale_Length_mm*3, target_neck_thickness*3]);
// Reduce rest of the body to 0
translate([-neck_width, 0, 0]) cube([neck_width*2, (fret_scale_length(num_frets)+fret_scale_length(num_frets+1))/2, target_neck_thickness*3]);
}
intersection() {
fret_bumps();
neck_stock();
}
}
}
module tailpiece(string_spacing=18, string_margin=4.5, num_strings=3, target_neck_thickness=15, scallop_depth=3, fret_width=2.4*6) {
fw2 = fret_width/2;
neck_length = 84;
neck_width = (num_strings-1)*string_spacing + string_margin*2 + 6 + 6;
module neck_stock() {
angle_excess = asin((scallop_depth+fw2)/target_neck_thickness);
a0 = 90-angle_excess;
a1 = 270+angle_excess;
rotate([-90, 0, 0])
linear_extrude(neck_length)
polygon([for (i = [0:300]) let(a=lerp(a0, a1, i/300.0)) [neck_width*0.5*sin(a), -target_neck_thickness*cos(a)]]);
}
module scallop(fret) {
x0 = fret_scale_length(fret-1) - fw2;
x1 = fret_scale_length(fret) + fw2;
xmid = lerp(x0, x1, 0.5);
// Radius it?
arc = arc_points([[x0, scallop_depth], [x1, scallop_depth], [xmid, 0]]);
// echo(arc);
rotate([90, 0, 90]) linear_extrude(neck_width, center=true) polygon(arc);
}
module fret_bumps() {
translate([0, neck_length-fw2, scallop_depth]) rotate([0, 90]) cylinder(d=fret_width, h=neck_width, center = true, $fn=200);
}
module differences() {
t_offset = -30; //2.7;
t_z = -25; //-23;
module tuner() {
hole_r = 3;
bend_r = 24 + hole_r + 10;
fn=72;
rotate([90, -90, 90]) UBassTuner(from_below=true, from_side=true);
// translate([35,16,0]) cylinder(h=10-t_z, d=7, $fn=72);
translate([36-7,7,1]) for (a = [10:89]) {
hull() {
translate([a/9, bend_r-bend_r*sin(a), bend_r*cos(a)]) sphere(hole_r, $fn=fn);
translate([(a+1)/9, bend_r-bend_r*sin(a+1), bend_r*cos(a+1)]) sphere(hole_r, $fn=fn);
translate([7, bend_r-bend_r*sin(a+1), bend_r*cos(a+1)]) sphere(hole_r, $fn=fn);
}
}
}
translate([t_offset, 49, t_z]) tuner();
mirror([1,0,0]) translate([t_offset, 27, t_z]) tuner();
translate([t_offset, 5, t_z]) tuner();
for (i = [-1:2:1])
translate([i*15, 0, -4])
CFTubeCutout(neck_length, 0, tolerance=0.4);
translate([0, 0, -10])
CFTubeCutout(neck_length, 0, tolerance=0.4);
}
thick = 34;
render() difference() {
color([1,1,1,0.7]) translate([-neck_width/2, 0, -thick]) round_cube([neck_width, neck_length, thick], 4);
differences();
}
// color([1,1,1,0.3]) neck_stock();
}
module fret_tube(from_fret, to_fret, fret_width=2.4) {
fw2 = fret_width/2;
x0 = fret_scale_length(0)+fw2;
x1 = fret_scale_length(from_fret) + ((from_fret==0) ? fw2 : (-fw2));
x2 = fret_scale_length(to_fret)-fw2;
render() difference() {
neck(fret_width=fret_width);
for (i = [-1:2:1])
translate([i*15, 0, -4])
CFTubeCutout(x1, x2);
for (i = [-1:2:1])
translate([i*7.5, 0, -7])
CFSquareCutout(x1, x2);
translate([0, 0, -10])
CFTubeCutout(x1, x2);
translate([-50, 0, -50]) cube([100, x2, 100]);
translate([-50, x1, -50]) cube([100, x0-x1, 100]);
// αβγδεζ
rotate([90, 0, 0]) linear_extrude((x2+0.3)*2, center=true) text(text = "01β", font = "Deja Vu Sans", halign = "center", valign = "center", size = 4);
}
}
module fret_tube_filler(from_fret, to_fret, fret_width=2.4, belthole_length=140, VLH=true) {
fw2 = fret_width/2;
x0 = fret_scale_length(0)+fw2;
x1 = fret_scale_length(from_fret) + ((from_fret==0) ? fw2 : (-fw2));
x2 = (to_fret < 100) ? (fret_scale_length(to_fret)-fw2) : 0;
render() difference() {
neck(fret_width=fret_width, filler=true);
for (i = [-1:1])
translate([i*15, 0, (i==0)?(-10):(-4)])
CFTubeCutout(x1, x2, VLH=VLH);
translate([-50, 0, -50]) cube([100, x2, 100]);
translate([-50, x1, -50]) cube([100, x0-x1, 100]);
// Add a belt hole
arc = arc_points([[16, -20], [-16, -20], [0, -4]]);
belthole_r = 2.5;
belthole_fn = 72;
belthole_x0 = x1-belthole_r-5;
belthole_x1 = belthole_x0 - belthole_length;
render() for (i = [0:len(arc)-2]) {
hull() {
translate([arc[i][0], belthole_x0, arc[i][1]]) sphere(belthole_r, $fn=belthole_fn);
translate([arc[i+1][0], belthole_x0, arc[i+1][1]]) sphere(belthole_r, $fn=belthole_fn);
translate([arc[i][0], belthole_x1, arc[i][1]]) sphere(belthole_r, $fn=belthole_fn);
translate([arc[i+1][0], belthole_x1, arc[i+1][1]]) sphere(belthole_r, $fn=belthole_fn);
}
}
// αβγδεζ
t = "01β.β";
translate([0,0,-3.5]) rotate([90, 0, 0]) linear_extrude((x2+0.3)*2, center=true) text(text = t, font = "Deja Vu Sans", halign = "center", valign = "center", size = 4);
translate([0,x1-0.3,-3]) rotate([90, 0, 180]) linear_extrude((0.3)*2, center=true) text(text = t, font = "Deja Vu Sans", halign = "center", valign = "center", size = 4);
}
}
module headpiece(string_spacing=18, string_margin=4.5, num_strings=3, target_neck_thickness=15, scallop_depth=3, fret_width=2.4) {
headpiece_length = 36;
cf_square_length = 32;
fw2 = fret_width/2;
x0 = fret_scale_length(0)+fw2;
neck_width = (num_strings-1)*string_spacing + string_margin*2;
bend_radius = 24;
module stock() {
angle_excess = asin(scallop_depth/target_neck_thickness);
a0 = 90-angle_excess;
a1 = 270+angle_excess;
translate([0, x0, 0])
rotate([-90, 0, 0])
linear_extrude(headpiece_length)
polygon([for (i = [0:300]) let(a=lerp(a0, a1, i/300.0)) [neck_width*0.5*sin(a), -target_neck_thickness*cos(a)]]);
}
module string_tubes(tolerance = 1.0) {
string_thicknesses = [4.9, 4.2, 3.0];
module string_tube(diameter, fn=36) {
hole_r = diameter/2;
bend_r = bend_radius + hole_r;
union() {
for (a = [0:89]) {
hull() {
translate([0, bend_r*sin(a), bend_r*cos(a)]) sphere(hole_r, $fn=fn);
translate([0, bend_r*sin(a+1), bend_r*cos(a+1)]) sphere(hole_r, $fn=fn);
}
}
hull() {
translate([0, bend_r*sin(90), bend_r*cos(90)]) sphere(hole_r, $fn=fn);
translate([0, bend_r*sin(90), -target_neck_thickness]) sphere(hole_r, $fn=fn);
}
}
};
for (i = [0:num_strings-1]) {
string_diameter = string_thicknesses[i] + tolerance;
x = -neck_width/2 + string_margin + (i*string_spacing);
translate([x, x0+2, -bend_radius+scallop_depth]) string_tube(string_diameter);
}
}
difference() {
stock();
string_tubes();
for (i = [-1:2:1])
translate([i*7.5, 0, -7])
CFSquareCutout(x0+cf_square_length, x0, taper_x1=false);
// αβγδεζ
translate([0, x0+headpiece_length, -5]) rotate([90, 0, 180]) linear_extrude(0.3, center=true) text(text = "01β.γ", font = "Deja Vu Sans", halign = "center", valign = "center", size = 4);
}
}
module bridge(string_spacing=18, string_margin=4.5, num_strings=3, target_neck_thickness=15, scallop_depth=3, fret_width=2.4) {
piece_length = 16;
cf_square_length = 32;
fw2 = fret_width/2;
x0 = 0;
neck_width = (num_strings-1)*string_spacing + string_margin*2;
bend_radius = 24;
string_thicknesses = [4.9, 4.2, 3.0];
module stock() {
angle_excess = asin(scallop_depth/target_neck_thickness);
a0 = 90-angle_excess;
a1 = 270+angle_excess;
translate([0, x0, 0])
rotate([-90, 0, 0])
linear_extrude(piece_length)
polygon([for (i = [0:300]) let(a=lerp(a0, a1, i/300.0)) [neck_width*0.5*sin(a), -target_neck_thickness*cos(a)]]);
intersection() {
r = 14;
translate([0,8,scallop_depth]) rotate([18, -90, 0]) scale([1,0.2,1]) cylinder(r=r, h=neck_width*1.5, center=true, $fn=72);
a0 = -90;
a1 = 90;
translate([0, x0, 0])
rotate([-90, 0, 0])
linear_extrude(piece_length)
polygon([for (i = [0:300]) let(a=lerp(a0, a1, i/300.0)) [neck_width*0.5*sin(a), -target_neck_thickness*cos(a)*3]]);
}
}
module string_tubes(tolerance = 1.0) {
module string_tube(diameter, fn=36) {
hole_r = diameter/2;
bend_r = bend_radius + hole_r;
union() {
for (a = [0:89]) {
hull() {
translate([0, bend_r*sin(a), bend_r*cos(a)]) sphere(hole_r, $fn=fn);
translate([0, bend_r*sin(a+1), bend_r*cos(a+1)]) sphere(hole_r, $fn=fn);
}
}
hull() {
translate([0, bend_r*sin(90), bend_r*cos(90)]) sphere(hole_r, $fn=fn);
translate([0, bend_r*sin(90), -target_neck_thickness]) sphere(hole_r, $fn=fn);
}
}
};
for (i = [0:num_strings-1]) {
string_diameter = string_thicknesses[i] + tolerance;
x = -neck_width/2 + string_margin + (i*string_spacing);
// translate([x, x0+2, -bend_radius+scallop_depth]) string_tube(string_diameter);
translate([x, 0, scallop_depth+string_diameter/2+8]) rotate([-90,0,0]) cylinder(d=string_diameter, h=20, $fn=72);
}
}
// string_tubes();
difference() {
stock();
string_tubes();
for (i = [-1:1])
translate([i*15, 0, (i==0)?(-10):(-4)])
CFTubeCutout(piece_length+0.1, x0-0.1, VLH=false);
// αβγδεζ
translate([0, x0+piece_length, -5]) rotate([90, 0, 180]) linear_extrude(0.3, center=true) text(text = "01β", font = "Deja Vu Sans", halign = "center", valign = "center", size = 4);
}
}
module Nylon6String() {
fsl_mm = fret_scale_length(0);
echo(str("Making a Nylon 6 String with scale length ", fsl_mm, "mm = ", fsl_mm/25.4, "in"))
assert(fsl_mm == Classical_Short_Scale_mm); // Make sure the function correctly uses our changed global
num_frets = 20;
num_strings = 6;
// 56mm wide neck
string_spacing = 10; // 50mm E to e
string_margin = 3; // +6
scallop_depth = 2.5;
target_neck_thickness = 22;
// neck(num_frets=num_frets, num_strings=num_strings, string_margin=string_margin, string_spacing=string_spacing);
module CF_Span(full_length = 700, ply = 3, hole = true) {
for (i=[0:ply-1])
translate([0, lerp(0, full_length-CF_Tube_Len, i/(ply-1)), CF_Square_Width*i]) CFSquare(hole=hole);
}
for (m=[0,11]) mirror([m, 0, 0]) color([0.4, 0.5, 0.5]) translate([9, -40, -16]) CF_Span();
// CFTube();
%neck(num_frets=num_frets, num_strings=num_strings, string_margin=string_margin, string_spacing=string_spacing, scallop_depth=scallop_depth, target_neck_thickness=target_neck_thickness);
// translate([0,0,30]) difference() {
// neck(num_frets=num_frets, num_strings=num_strings, string_margin=string_margin, string_spacing=string_spacing, scallop_depth=scallop_depth, target_neck_thickness=target_neck_thickness);
// for (m=[0,11]) mirror([m, 0, 0]) color([0.4, 0.5, 0.5]) translate([9, -40, -16]) CF_Span(hole=false);
// }
for (m=[0,11]) mirror([m, 0, 0]) translate([29,10,-32]) rotate([0,-90,0]) NylonTuner();
// Debug markers to aid part slicing eyeballing
for (i = [150:250:1000]) {
%translate([50,i,0]) union() {text(str(i, "mm")); cube([50, 1, 1], center=true);}
}
}
// echo(fret_scale_length(0) - fret_scale_length(8)); // 225.724
// echo(fret_scale_length(8) - fret_scale_length(24)); // 240.335
// fret_tube(0, 8);
// //translate([30, 0, 0])
// fret_tube(8, 24);
// headpiece();
// UBassTuner();
// fret_tube_filler(24, 100);
// tailpiece();
// bridge();
Guitar_Scale_Length_mm = Classical_Short_Scale_mm;
Nylon6String();
// difference() {
// translate([-15, -60, 0]) cube([50, 120, 8]);
// translate([0, 55, 3]) rotate([180,0,0]) NylonTuner();
// }