GuitarModels/CFTubes.scad

1116 lines
45 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>
include <CFTubes/ABS.scad>
include <EllipticalNeck.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
shumbucker_h = 20.3;
shumbucker_l = 23.1;
shumbucker_w1 = 66.4;
shumbucker_w2 = 82.9; // 1.6mm in, a 2.0mm hole on each side
// 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, "主イエス"], [27, "-"], [29, "-"], [31, "-"], [33, "-"]];
// Galatians 5:22-23
// ShinKaiYaku65 22しかし、御霊の実は、愛、喜び、平安、寛容、親切、善意、誠実、 23柔和、自制です。このようなものを禁ずる律法はありません。
// 愛 喜び 平安 寛容 親切 善意 誠実 柔和 自制
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(render_colour_0=true, render_colour_1=true, render_colour_2=true, render_colour_3=true, from_fret=0, to_fret=1, reference=false) {
colour_0 = "blue";
colour_1 = "white"; // fret layers
colour_2 = "green"; // side markers
colour_3 = "yellow"; // inlays
id_line_0 = "PETG";
id_line_1 = "1δ.α";
fsl_mm = fret_scale_length(0);
// string_diameters_thous = [28, 32, 40, 30, 36, 42]; // Ernie Ball Earthwoods (seemingly counterfeit from Amazon)
string_diameters_thous = [28, 32, 40, 30, 35, 43]; // Artist CLST Classical Nylon Guitar Strings
string_diameters_mm = string_diameters_thous * 0.0254;
num_frets = 21;
num_strings = 6;
// 56mm wide neck
string_spacing = 10; // 50mm E to e
string_margin = 3; // +6
neck_width = string_spacing*(num_strings-1) + string_margin*2;
body_width = 96;
scallop_depth = 2.5;
fret_width=2.4;
target_neck_thickness = 16; //22;
// echo(fret_scale_length(8));
// echo(fret_scale_length(9));
rx0 = -40; // Reinforcing rods start
rx1 = rx0+280;
// target_neck_thickness_additional_points = [];
target_neck_thickness_additional_points = [[rx0+CF_Tube_Len+20, 22], [0, 22]];
// target_neck_thickness_additional_points = [[400.025-fret_width/2, 22], [380, 25], [130, 42], [0, 42]];
// target_neck_thickness_additional_points = [[400.025-fret_width/2, 22], [380, 25], [0, 25]];
// target_neck_thickness_additional_points = [[400.025-fret_width/2, 22], [130, 42], [0, 42]];
echo(str("Making a Nylon 6 String with scale length ", fsl_mm, "mm = ", fsl_mm/25.4, "in and neck width ", neck_width, "mm"));
assert(fsl_mm == Classical_Short_Scale_mm); // Make sure the function correctly uses our changed global
function CF_Span_Coords(full_length = 700, ply = 3) = [for (i=[0:ply-1]) [0, lerp(0, full_length-CF_Tube_Len, i/(ply-1)), CF_Square_Width*i]];
module CF_Span(full_length = 700, ply = 3, hole = true) {
for (v = CF_Span_Coords(full_length, ply))
translate(v) CFSquare(hole=hole);
}
module MyNeck(inlays_only=false, side_markers_only=false, fret_layers_only=false, engrave_markers=false, remove_fret_layers=false) {
render() 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, target_neck_thickness_additional_points=target_neck_thickness_additional_points, inlays_only=inlays_only, side_markers_only=side_markers_only, fret_layers_only=fret_layers_only, engrave_markers=engrave_markers, remove_fret_layers=remove_fret_layers);
}
module MultiColourNeck() {
if (render_colour_0) color(colour_0) MyNeck(engrave_markers=true, remove_fret_layers=true);
if (render_colour_1) color(colour_1) MyNeck(fret_layers_only=true);
if (render_colour_2) color(colour_2) MyNeck(side_markers_only=true);
if (render_colour_3) color(colour_3) MyNeck(inlays_only=true);
}
reinforcing_tube_positions = flatten([
[
for (i=[-1,1]) each [
// Headside reinforcement
[i*21.5, rx1, -4],
// Bridgeside reinforcement
// [i*21.5, rx0, -4],
[i*17.25, rx0, -10],
// [i*17, rx0, -12],
[i*3.95, rx0, -16.5],
]
],
[
// Headside reinforcement
[0, rx1, -4],
[0, rx1, -11],
// Bridgeside reinforcement
// [0, rx0, -11],
]]);
echo(reinforcing_tube_positions);
// Through span construction
span_coords = CF_Span_Coords(ply=2);
reinforcing_square_positions = [
for (i=[-1,1]) each [ for (v = span_coords) [i*10, rx0, -10] + v ]
];
echo(reinforcing_square_positions);
// neck(num_frets=num_frets, num_strings=num_strings, string_margin=string_margin, string_spacing=string_spacing);
// %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);
module NeckFragment(from_fret, to_fret, to_origin=true, include_from_fret=false, test_tolerances_piece=false) {
x0 = fret_scale_length(to_fret) - fret_width/2;
x1 = fret_scale_length(from_fret) + ((include_from_fret)?1:(-1)) * fret_width/2;
xn = fsl_mm + fret_width;
module TestTolerancesPiece() {
for (m=[0,11]) mirror([m, 0, 0]) color([0.4, 0.5, 0.5]) translate([9, 0, -16+(CF_Square_Width*2)]) CFSquareCutout(x0, x1, taper_length=2);
translate([ 12,0,-14]) CFSquareCutout(x0, x1, taper_length=2);
translate([ 12-CF_Square_Width,0,-14]) CFSquareCutout(x0, x1-8, taper_length=2, taper_x2=false);
translate([-12,0,-14]) CFSquareCutout(x0, x1, taper_length=2);
translate([-12+CF_Square_Width,0,-14]) CFSquareCutout(x0+8, x1, taper_length=2, taper_x1=false);
translate([20,0,-6]) CFTubeCutout(x0, x1, taper_length=2);
}
translate([0,to_origin ? -x0 : 0,0]) render() difference() {
MultiColourNeck();
color(colour_1) {
translate([-100, 0, -100]) cube([200, x0, 200]);
translate([-100, x1, -100]) cube([200, xn-x1, 200]);
for (v = reinforcing_tube_positions) CFTubeCutout2(v, x0, x1);
for (v = reinforcing_square_positions) CFSquareCutout2(v, x0, x1);
if (test_tolerances_piece) TestTolerancesPiece();
}
}
}
// Test tolerances piece
module TestTolerancesPiece() {
difference(){
NeckFragment(2, 3, test_tolerances_piece=true);
translate([-20,0,-1]) rotate([-90,180,180]) linear_extrude(3, center=true) text(id_line_0, size=3.5, halign="center", valign="center");
translate([-20,0,-6]) rotate([-90,180,180]) linear_extrude(3, center=true) text(id_line_1, size=3.5, halign="center", valign="center");
}
}
// TestTolerancesPiece();
module RealPiece(from_fret, to_fret, include_from_fret=false) {
midpoint = (fret_scale_length(from_fret) - fret_scale_length(to_fret) + (include_from_fret ? fret_width : 0))/2;
module IDText(thickness = 0.2, inset = 0, extra_line=str("F", to_fret)) {
translate([0,0,-8]) rotate([-90,180,180]) translate([0,0,-thickness-inset]) linear_extrude(thickness) {
text(str(id_line_0, id_line_1), size=2.25, halign="center", valign="center", $fn=100);
translate([0,-3]) text(extra_line, size=2.25, halign="center", valign="center", $fn=100);
}
}
module BackIDText(thickness = 0.2, inset = 0) {
rotate_around([0,0,180], [0,midpoint,0])
IDText(thickness, inset, str("F", from_fret));
}
render() difference(){
NeckFragment(from_fret, to_fret, include_from_fret=include_from_fret);
// Subtract from frets
color("red") {
IDText();
if (include_from_fret) BackIDText();
}
color("red") BackIDText();
}
// // color("red") IDText(inset=0.0001);
// if (render_colour_0) color(colour_1) IDText();
// if (render_colour_0 && include_from_fret) color(colour_1) BackIDText();
// if (render_colour_1 && !include_from_fret) color("red") BackIDText();
}
module HeadPiece() {
x0 = fret_scale_length(0) + fret_width/2;
end_radius = 12;
x1 = x0 - rx0 + end_radius;
module StringHoles() {
for (i = [0:num_strings-1]) translate([(num_strings-i-1)*string_spacing - neck_width/2 + string_margin,0,0]) {
translate([0,0,scallop_depth+fret_width/2+string_diameters_mm[i]]) rotate([-105,0,0]) cylinder(h=30, d=string_diameters_mm[i]*2, $fn=cyl_ld_fn);
// translate([0,23,-4]) rotate([-150,0,0]) translate([0,0,0]) cylinder(h=20, d=4, $fn=cyl_ld_fn);
hull() {
translate([0,29,-3.5]) sphere(d=5.5, $fn=360);
translate([0,29+11,-17]) sphere(d=7, $fn=360);
}
}
}
render() difference(){
hull() {
translate([0,fret_width/2,0]) scale([neck_width/2, 0.01, target_neck_thickness]) sphere(r=1, $fn=360);
translate([0,-rx0-end_radius,0]) scale([neck_width/2, end_radius, target_neck_thickness*0.93]) sphere(r=1, $fn=360);
}
translate([-500, 0, scallop_depth]) cube([1000, 1000, 1000]);
translate([-500, fret_width/2 - 1000, -500]) cube([1000, 1000, 1000]);
translate([0, -fret_scale_length(0), 0]) {
for (v = reinforcing_tube_positions) CFTubeCutout2(v, x0, x1);
for (v = reinforcing_square_positions) CFSquareCutout2(v, x0, x1);
}
StringHoles();
translate([-10,fret_width/2+1,-10]) rotate([90,0,0]) linear_extrude(10) {
text(str(id_line_0, id_line_1), size=2.9, halign="center", valign="center", $fn=100);
}
}
// StringHoles();
}
module TunerPlacement(cutout = false, ear_extra_diameter = 0, ear_extra_height = 0, plate_clearance = 0, shaft_clearance = 0, shaft_tolerance = 0) {
for (m=[0,1]) mirror([m, 0, 0]) translate([29,3,-32]) rotate([0,-90,0]) NylonTuner(cutout, ear_extra_diameter, ear_extra_height, plate_clearance, shaft_clearance, shaft_tolerance);
}
module LoopOrTunerBlock(tuner_block) {
y0 = 116;
y1 = fret_scale_length(22);
z0 = -43;
z_drop = 6;
loop_thick = 8;
loop_slot_thick = 6;
z1 = z0 + z_drop;
module TunerBlockCheekVolumes() {
vw = 50;
for (i=[-1,1]) translate([-vw/2 + i*58, 0, z0]) cube([vw, y0, -z0]);
for (i=[-1,1]) translate([-vw/2 + i*46, 0, -14]) cube([vw, y0, -z0]);
}
if (tuner_block) {
render() difference() {
translate([-body_width/2, 0, z0]) cube([body_width, y0, -z0]);
// Tuner cutouts
TunerPlacement(true, 4, 10, 10, 10, 0.4);
tw = 16;
for (i=[-1,1]) translate([-tw/2 + i*15, 0, z0]) cube([tw, y0, -z0-20]);
// Cheek Volumes
TunerBlockCheekVolumes();
// CF
for (v = reinforcing_tube_positions) CFTubeCutout2(v, y0, y1);
for (v = reinforcing_square_positions) CFSquareCutout2(v, y0, y1);
// Version stamp
translate([0,0.5,-5]) rotate([90,0,0]) linear_extrude(10) {
text(str(id_line_0, id_line_1), size=2.9, halign="center", valign="center", $fn=100);
}
translate([0,y0-0.5,-5]) rotate([90,0,180]) linear_extrude(10) {
text(str(id_line_0, id_line_1), size=2.9, halign="center", valign="center", $fn=100);
}
}
} else {
render() difference() {
hull() {
translate([-neck_width/2, y1-hull_epsilon, z1]) cube([neck_width, hull_epsilon, -z1]);
translate([-body_width/2, y0, z0]) cube([body_width, hull_epsilon, -z0]);
}
// Belt loop slot
hull() {
translate([0, y1-loop_slot_thick, z1+loop_thick]) rotate([0,90,0]) cylinder(d=loop_slot_thick, h=body_width, center=true, $fn=cyl_hd_fn);
translate([0, y0+loop_slot_thick, z0+loop_thick]) rotate([0,90,0]) cylinder(d=loop_slot_thick, h=body_width, center=true, $fn=cyl_hd_fn);
}
// Angled belt loop slot
hull() {
extend_factor = 0.8;
translate([body_width/2, y1-loop_slot_thick + (y1-y0-loop_slot_thick*2)*extend_factor, z1+loop_thick + (z1-z0)*extend_factor]) rotate([0,90,0]) cylinder(d=loop_slot_thick, h=hull_epsilon, $fn=cyl_hd_fn);
translate([0, y0+loop_slot_thick, z0+loop_thick]) rotate([0,90,0]) cylinder(d=loop_slot_thick, h=body_width, center=true, $fn=cyl_hd_fn);
}
// Version stamp
translate([-10,y0+0.5,-30]) rotate([90,0,0]) linear_extrude(10) {
text(str(id_line_0, id_line_1), size=2.9, halign="center", valign="center", $fn=100);
}
translate([-10,y1-0.5,-30]) rotate([90,0,180]) linear_extrude(10) {
text(str(id_line_0, id_line_1), size=2.9, halign="center", valign="center", $fn=100);
}
// CF
for (v = reinforcing_tube_positions) CFTubeCutout2(v, y0, y1);
for (v = reinforcing_square_positions) CFSquareCutout2(v, y0, y1);
}
}
}
bridge_channel_width = 5;
bridge_channel_depth = 7;
if (reference) {
union() {
c_cf = [0.4, 0.5, 0.5];
%MyNeck();
// CF square stacks
for (v = reinforcing_tube_positions) color(c_cf) translate(v) CFTube();
for (v = reinforcing_square_positions) color(c_cf) translate(v) CFSquare();
// Approximate tuner placement
TunerPlacement();
// Render strings above for spacing reference
string_excess = 80;
for (i = [0:num_strings-1]) {
translate([(num_strings-i-1)*string_spacing - neck_width/2 + string_margin,0,5]) rotate([-90,0,0]) translate([0,0,-string_excess/2]) cylinder(h=fsl_mm+string_excess, d=string_diameters_mm[i], $fn=cyl_ld_fn);
}
}
} else if (from_fret >= 0) {
RealPiece(from_fret, to_fret, include_from_fret = (from_fret==0));
} else if (from_fret == -1) {
// String holding headpiece
echo("Making a headpiece");
HeadPiece();
} else if (from_fret == -2) {
echo("Making a filler belt loop");
LoopOrTunerBlock(false);
} else if (from_fret == -3) {
echo("Making a tuner block");
LoopOrTunerBlock(true);
} else if (from_fret == -4) {
echo("Making a bridge");
y_len = 9;
base_height = 7;
saddle_height = 4;
pickup_w = 3;
pickup_h = 2;
render() difference() {
union() {
// Base
translate([-neck_width/2, 0, 0]) cube([neck_width, y_len, base_height]);
// String saddles - rule of thumb: string diameter multiplied by 4
r0 = 0.85;
for (i = [0:num_strings-1]) translate([(num_strings-i-1)*string_spacing - neck_width/2 + string_margin, y_len - string_diameters_mm[i]*4, base_height]) {
step = ($preview) ? 8 : 2;
r = r0 + string_diameters_mm[i]*1.2;
translate([0, 0, saddle_height]) for (a=[90:step:270-step]) hull() {
translate([-sin(a)*r, 0, cos(a)*r]) sphere(r=r0, $fn=cyl_ld_fn);
translate([-sin(a+step)*r, 0, cos(a+step)*r]) sphere(r=r0, $fn=cyl_ld_fn);
translate([-sin(a)*r, -3.7, -saddle_height-r0]) sphere(r=r0, $fn=cyl_ld_fn);
translate([-sin(a+step)*r, -3.7, -saddle_height-r0]) sphere(r=r0, $fn=cyl_ld_fn);
translate([-sin(a)*r, 1.2, -saddle_height-r0]) sphere(r=r0, $fn=cyl_ld_fn);
translate([-sin(a+step)*r, 1.2, -saddle_height-r0]) sphere(r=r0, $fn=cyl_ld_fn);
}
}
// Bridge channel notch
notch_w = bridge_channel_width - CF_Square_Width_tolerance; // Shrink a little for tolerance
notch_d = bridge_channel_depth - CF_Square_Width_tolerance/2;
translate([-notch_w/2, 0, -notch_d]) cube([notch_w, y_len, notch_d]);
}
// Pickup notch
tol = 0.25;
translate([-neck_width/2, 2, -tol]) hull() {
cube([neck_width, pickup_w, pickup_h+tol]);
translate([0, pickup_h*0.8, 0]) cube([neck_width, pickup_w, 0.01]);
}
// Version stamp
y0 = 0;
y1 = y_len;
translate([-15,y0+0.5,4]) rotate([90,0,0]) linear_extrude(10) {
text(str(id_line_0, id_line_1), size=2.9, halign="center", valign="center", $fn=100);
}
translate([-15,y1-0.5,4]) rotate([90,0,180]) linear_extrude(10) {
text(str(id_line_0, id_line_1), size=2.9, halign="center", valign="center", $fn=100);
}
}
} else if (from_fret == -5) {
echo("Making a tailpiece");
y0 = -47;
y1 = 0;
fw_len = 20;
total_len = y1-y0;
fw_height = 43;
rad_diameter = 20.35; //21;
rad_radius = rad_diameter/2;
render() difference() {
hull() {
translate([-body_width/2, -fw_len, -fw_height]) cube([body_width, fw_len, fw_height]);
translate([0, -total_len+rad_radius, -rad_radius]) rotate([0,90,0]) cylinder(h=neck_width, d=rad_diameter, center=true, $fn=cyl_hd_fn);
}
// Tuner cavity line up
tw = 16;
z0 = -43;
for (i=[-1,1]) translate([-tw/2 + i*15, y0, z0+5]) cube([tw, total_len, -z0-25]);
// String channels
for (i = [0:num_strings-1]) translate([(num_strings-i-1)*string_spacing - neck_width/2 + string_margin, y0+rad_radius, -rad_radius]) {
x = [-1,0,1,-1,0,1][i]*4/180;
r = rad_radius + string_diameters_mm[i]*0.5;
for (a = [0:180]) hull() {
translate([a*x, -sin(a)*r, cos(a)*r]) sphere(r=string_diameters_mm[i], $fn=cyl_ld_fn);
translate([a*x, -sin(a+1)*r, cos(a+1)*r]) sphere(r=string_diameters_mm[i], $fn=cyl_ld_fn);
}
}
// Bridge channel
translate([-bridge_channel_width/2, y0+rad_radius, -bridge_channel_depth]) cube([bridge_channel_width, total_len-rad_radius, bridge_channel_depth]);
// Version stamp
translate([-30,y0+0.5,-15]) rotate([90,0,0]) linear_extrude(10) {
text(str(id_line_0, id_line_1), size=2.9, halign="center", valign="center", $fn=100);
}
translate([-30,y1-0.5,-15]) rotate([90,0,180]) linear_extrude(10) {
text(str(id_line_0, id_line_1), size=2.9, halign="center", valign="center", $fn=100);
}
// CF
for (v = reinforcing_tube_positions) CFTubeCutout2(v, y0, y1);
for (v = reinforcing_square_positions) CFSquareCutout2(v, y0, y1);
}
}
// Debug markers to aid part slicing eyeballing
// %for (i = [150:250:1000]) {
%for (i = [0:250:1000]) {
translate([35,i,0]) union() {linear_extrude(1) text(str(i, "mm")); cube([35, 1, 1], center=true);}
}
}
module Steel6String(include_colours, from_fret=0, to_fret=1, reference=false) {
id_line_0 = "ABS";
id_line_1 = "2";
fsl_mm = fret_scale_length(0);
string_diameters_thous = [9, 11, 16, 24, 32, 42]; // Artist ELST942
string_diameters_mm = string_diameters_thous * 0.0254;
num_frets = 22;
num_strings = 6;
// 56mm wide neck
string_spacing_nut = 10; // 50mm E to e
string_spacing_bridge = 11.2; // 56mm E to e
function string_spacing(y) = lerp(string_spacing_bridge, string_spacing_nut, y/fret_scale_length(0));
string_margin = 3; // +6
neck_width_nut = (num_strings-1)*string_spacing_nut + string_margin*2;
neck_width_bridge = (num_strings-1)*string_spacing_bridge + string_margin*2;
function neck_width_mm(y) = lerp(neck_width_bridge, neck_width_nut, y/fret_scale_length(0));
body_width = 96;
scallop_depth = 2.0;
_zero_fret_width = 3.6;
_fret_width = 2.4;
fret_widths = flatten([[_zero_fret_width], [ for (i = [1:num_frets]) _fret_width ]]);
function get_fret_width(fret) = fret_widths[clamp(0, fret, num_frets)];
fret_angle = 60;
max_fret_width = max(fret_widths);
max_fret_height = sin(fret_angle) * max_fret_width/2;
target_neck_thickness = 16;
// echo(fret_scale_length(8));
// echo(fret_scale_length(9));
rx0 = -40; // Reinforcing rods start
rx1 = rx0+280;
target_neck_thickness_additional_points = [];
// target_neck_thickness_additional_points = [[rx0+CF_Tube_Len+20, 22], [0, 22]];
echo(str("Making a Steel 6 String with scale length ", fsl_mm, "mm = ", fsl_mm/25.4, "in and neck width ", neck_width_nut, "mm"));
assert(fsl_mm == Fender_Scale_mm); // Make sure the function correctly uses our changed global
function CF_Span_Coords(full_length = 700, ply = 3) = [for (i=[0:ply-1]) [0, lerp(0, full_length-CF_Tube_Len, i/(ply-1)), CF_Square_Width*i]];
module CF_Span(full_length = 700, ply = 3, hole = true) {
for (v = CF_Span_Coords(full_length, ply))
translate(v) CFSquare(hole=hole);
}
module MyNeck(inlays_only=false, side_markers_only=false, fret_layers_only=false, engrave_markers=false, remove_fret_layers=false) {
render() TaperNeck(
num_frets = num_frets,
fret_widths = fret_widths,
fret_angle = fret_angle,
num_strings = num_strings,
string_margin = string_margin,
string_spacing_nut = string_spacing_nut,
string_spacing_bridge = string_spacing_bridge,
scallop_depth = scallop_depth,
target_neck_thickness = target_neck_thickness,
target_neck_thickness_additional_points = target_neck_thickness_additional_points,
include_colours = include_colours,
);
}
module truss_rods() {
include_from_fret = (from_fret==0);
x0 = fret_scale_length(to_fret) - get_fret_width(to_fret)/2;
//x1 = fret_scale_length(from_fret) + ((include_from_fret)?1:(-1)) * get_fret_width(from_fret)/2;
x1 = include_from_fret ? x0 : (fret_scale_length(from_fret) - get_fret_width(from_fret)/2); // hacky fix for included headpiece
tolerance = reference ? 0 : 0.6;
rod_mm = 630;
v = [0, 40, -9];
// Nut facing bridge
// o = v[1];
// taper_points = reference ? [] : [x0-o, x1-o];
// translate(v) TrussRod(taper_points = taper_points, tolerance = tolerance, extra = !reference);
// Nut facing headstock
o = v[1];
taper_points = reference ? [] : [rod_mm-(x0-o), rod_mm-(x1-o)];
translate(v + [0, rod_mm, 0]) rotate([0, 0, 180]) TrussRod(taper_points = taper_points, tolerance = tolerance, extra = !reference);
}
reinforcing_tube_positions = flatten([
[
for (i=[-1,1]) each [
// Headside reinforcement
[i*20.5, rx1, -4],
// Bridgeside reinforcement
[i*20.5, rx0, -4],
// [i*17.25, rx0, -10],
// [i*17, rx0, -12],
// [i*3.95, rx0, -16.5],
]
],
[
// Headside reinforcement
// [0, rx1, -4],
// [0, rx1, -11],
// Bridgeside reinforcement
// [0, rx0, -11],
]]);
echo(reinforcing_tube_positions);
// Through span construction
rx2 = fret_scale_length(15) - CF_Tube_Len;
reinforcing_square_positions = flatten([
[
for (i=[-1,1]) each [
// Headside reinforcement
// [i*20.5, rx1, -4],
// Bridgeside reinforcement
[i*12, rx2, -6],
// [i*17.25, rx2, -10],
// [i*17, rx0, -12],
// [i*3.95, rx0, -16.5],
]
],
[
// Headside reinforcement
// [0, rx1, -4],
// [0, rx1, -11],
// Bridgeside reinforcement
// [0, rx0, -11],
]]);
echo(reinforcing_square_positions);
// neck(num_frets=num_frets, num_strings=num_strings, string_margin=string_margin, string_spacing=string_spacing);
// %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);
module NeckFragment(from_fret, to_fret, to_origin=true, include_from_fret=false) {
x0 = fret_scale_length(to_fret) - get_fret_width(to_fret)/2;
x1 = fret_scale_length(from_fret) + ((include_from_fret)?1:(-1)) * get_fret_width(from_fret)/2;
xn = fsl_mm + fret_widths[0];
//translate([0,to_origin ? -x0 : 0,0])
render() difference() {
MyNeck();
translate([-100, 0, -100]) cube([200, x0, 200]);
translate([-100, x1, -100]) cube([200, xn-x1, 200]);
for (v = reinforcing_tube_positions) CFTubeCutout2(v, x0, x1);
for (v = reinforcing_square_positions) CFSquareCutout2(v, x0, x1);
truss_rods();
}
}
module RealPiece(from_fret, to_fret, include_from_fret=false) {
// midpoint = (fret_scale_length(from_fret) - fret_scale_length(to_fret) + (include_from_fret ? fret_width : 0))/2;
module IDText(thickness = 0.2, inset = 0, extra_line=str("F", to_fret)) {
translate([0,0,-8]) rotate([-90,180,180]) translate([0,0,-thickness-inset]) linear_extrude(thickness) {
text(str(id_line_0, id_line_1), size=2.25, halign="center", valign="center", $fn=100);
translate([0,-3]) text(extra_line, size=2.25, halign="center", valign="center", $fn=100);
}
}
// module BackIDText(thickness = 0.2, inset = 0) {
// rotate_around([0,0,180], [0,midpoint,0])
// IDText(thickness, inset, str("F", from_fret));
// }
render() difference(){
NeckFragment(from_fret, to_fret, include_from_fret=include_from_fret);
// Subtract from frets
color("red") {
IDText();
// if (include_from_fret) BackIDText();
}
// color("red") BackIDText();
}
}
function string_x(i, y) = (num_strings-i-1)*string_spacing(y) - neck_width_mm(y)/2 + string_margin;
module HeadPiece(label=true) {
string_offsets = [-2.5, 0, 2.5, -2.5, 0, 2.5];
x0 = fret_scale_length(0) + fret_widths[0]/2;
end_radius = 12;
x1 = x0 - rx0 + end_radius;
z1 = scallop_depth + max_fret_height;
module StringHoles() {
for (i = [0:num_strings-1]) translate([string_x(i, x0),0,0]) {
// translate([0,0,z1+string_diameters_mm[i]]) rotate([-105,0,0]) cylinder(h=30, d=string_diameters_mm[i]*2, $fn=cyl_ld_fn);
hull() {
translate([0,0,z1+string_diameters_mm[i]]) sphere(d=min(2.6, string_diameters_mm[i]*1.2 + 1), $fn=360);
translate([string_offsets[i],27,-3.5]) sphere(d=2.6, $fn=360);
}
hull() {
// String ball ends are roughly 3mm by 4mm cylinder(d=4, h=3)
// translate([string_offsets[i],29,-3.5]) sphere(d=5.5, $fn=360);
// translate([string_offsets[i],29+11,-17]) sphere(d=7, $fn=360);
translate([string_offsets[i],27,-3.5]) rotate([0, 90, 0]) cylinder(d=4.5, h=3.5, center=true, $fn=360);
translate([string_offsets[i],27+27,-17]) rotate([0, 90, 0]) cylinder(d=6.5, h=5.0, center=true, $fn=360);
}
}
}
fw2 = fret_widths[0]/2;
render() difference(){
hull() {
translate([0,fw2,0]) scale([neck_width_mm(x0)/2, 0.01, target_neck_thickness]) sphere(r=1, $fn=360);
translate([0,-rx0-end_radius,0]) scale([neck_width_mm(x1)/2, end_radius, target_neck_thickness*1.0]) sphere(r=1, $fn=360);
}
translate([-500, 0, scallop_depth]) cube([1000, 1000, 1000]);
translate([-500, fw2 - 1000, -500]) cube([1000, 1000, 1000]);
translate([0, -fret_scale_length(0), 0]) {
for (v = reinforcing_tube_positions) CFTubeCutout2(v, x0, x1);
for (v = reinforcing_square_positions) CFSquareCutout2(v, x0, x1);
}
StringHoles();
if (label) translate([-10,fw2+1,-10]) rotate([90,0,0]) linear_extrude(10) {
text(str(id_line_0, id_line_1), size=2.9, halign="center", valign="center", $fn=100);
}
}
// StringHoles();
}
module TunerPlacement(cutout = false, ear_extra_diameter = 0, ear_extra_height = 0, plate_clearance = 0, shaft_clearance = 0, shaft_tolerance = 0) {
for (m=[0,1]) mirror([m, 0, 0]) translate([29,3,-32]) rotate([0,-90,0]) NylonTuner(cutout, ear_extra_diameter, ear_extra_height, plate_clearance, shaft_clearance, shaft_tolerance);
}
module LoopOrTunerBlock(tuner_block) {
y0 = 116;
y1 = fret_scale_length(22);
z0 = -43;
z_drop = 6;
loop_thick = 8;
loop_slot_thick = 6;
z1 = z0 + z_drop;
module TunerBlockCheekVolumes() {
vw = 50;
for (i=[-1,1]) translate([-vw/2 + i*58, 0, z0]) cube([vw, y0, -z0]);
for (i=[-1,1]) translate([-vw/2 + i*46, 0, -14]) cube([vw, y0, -z0]);
}
if (tuner_block) {
render() difference() {
translate([-body_width/2, 0, z0]) cube([body_width, y0, -z0]);
// Tuner cutouts
TunerPlacement(true, 4, 10, 10, 10, 0.4);
tw = 16;
for (i=[-1,1]) translate([-tw/2 + i*15, 0, z0]) cube([tw, y0, -z0-20]);
// Cheek Volumes
TunerBlockCheekVolumes();
// CF
for (v = reinforcing_tube_positions) CFTubeCutout2(v, y0, y1);
for (v = reinforcing_square_positions) CFSquareCutout2(v, y0, y1);
// Version stamp
translate([0,0.5,-5]) rotate([90,0,0]) linear_extrude(10) {
text(str(id_line_0, id_line_1), size=2.9, halign="center", valign="center", $fn=100);
}
translate([0,y0-0.5,-5]) rotate([90,0,180]) linear_extrude(10) {
text(str(id_line_0, id_line_1), size=2.9, halign="center", valign="center", $fn=100);
}
}
} else {
render() difference() {
hull() {
translate([-neck_width/2, y1-hull_epsilon, z1]) cube([neck_width, hull_epsilon, -z1]);
translate([-body_width/2, y0, z0]) cube([body_width, hull_epsilon, -z0]);
}
// Belt loop slot
hull() {
translate([0, y1-loop_slot_thick, z1+loop_thick]) rotate([0,90,0]) cylinder(d=loop_slot_thick, h=body_width, center=true, $fn=cyl_hd_fn);
translate([0, y0+loop_slot_thick, z0+loop_thick]) rotate([0,90,0]) cylinder(d=loop_slot_thick, h=body_width, center=true, $fn=cyl_hd_fn);
}
// Angled belt loop slot
hull() {
extend_factor = 0.8;
translate([body_width/2, y1-loop_slot_thick + (y1-y0-loop_slot_thick*2)*extend_factor, z1+loop_thick + (z1-z0)*extend_factor]) rotate([0,90,0]) cylinder(d=loop_slot_thick, h=hull_epsilon, $fn=cyl_hd_fn);
translate([0, y0+loop_slot_thick, z0+loop_thick]) rotate([0,90,0]) cylinder(d=loop_slot_thick, h=body_width, center=true, $fn=cyl_hd_fn);
}
// Version stamp
translate([-10,y0+0.5,-30]) rotate([90,0,0]) linear_extrude(10) {
text(str(id_line_0, id_line_1), size=2.9, halign="center", valign="center", $fn=100);
}
translate([-10,y1-0.5,-30]) rotate([90,0,180]) linear_extrude(10) {
text(str(id_line_0, id_line_1), size=2.9, halign="center", valign="center", $fn=100);
}
// CF
for (v = reinforcing_tube_positions) CFTubeCutout2(v, y0, y1);
for (v = reinforcing_square_positions) CFSquareCutout2(v, y0, y1);
}
}
}
bridge_channel_width = 5;
bridge_channel_depth = 7;
if (reference) {
/*translate([0, -fsl_mm, 0]) */union() {
c_cf = [0.4, 0.5, 0.5];
%MyNeck();
// CF square stacks
truss_rods();
for (v = reinforcing_tube_positions) color(c_cf) translate(v) CFTube();
for (v = reinforcing_square_positions) color(c_cf) translate(v) CFSquare();
// Approximate tuner placement
// TunerPlacement();
// Render strings above for spacing reference
string_excess = 80;
for (i = [0:num_strings-1]) {
hull() {
translate([string_x(i, -string_excess), -string_excess, 5]) sphere(d=string_diameters_mm[i], $fn=cyl_ld_fn);
translate([string_x(i, fsl_mm+5), fsl_mm+5, 5]) sphere(d=string_diameters_mm[i], $fn=cyl_ld_fn);
}
}
}
%HeadPiece(false);
} else if (from_fret >= 0) {
RealPiece(from_fret, to_fret, include_from_fret = (from_fret==0));
if ((from_fret == 0) && list_has(include_colours, 0)) {
echo("Making a headpiece");
render() difference() {
translate([0, fret_scale_length(0), 0]) HeadPiece(false);
truss_rods();
}
}
} else if (from_fret == -1) {
// String holding headpiece
echo("Making a headpiece");
HeadPiece();
} else if (from_fret == -2) {
echo("Making a filler belt loop");
LoopOrTunerBlock(false);
} else if (from_fret == -3) {
echo("Making a tuner block");
LoopOrTunerBlock(true);
} else if (from_fret == -4) {
echo("Making a bridge");
y_len = 9;
base_height = 7;
saddle_height = 4;
pickup_w = 3;
pickup_h = 2;
render() difference() {
union() {
// Base
translate([-neck_width/2, 0, 0]) cube([neck_width, y_len, base_height]);
// String saddles - rule of thumb: string diameter multiplied by 4
r0 = 0.85;
for (i = [0:num_strings-1]) translate([(num_strings-i-1)*string_spacing - neck_width/2 + string_margin, y_len - string_diameters_mm[i]*4, base_height]) {
step = ($preview) ? 8 : 2;
r = r0 + string_diameters_mm[i]*1.2;
translate([0, 0, saddle_height]) for (a=[90:step:270-step]) hull() {
translate([-sin(a)*r, 0, cos(a)*r]) sphere(r=r0, $fn=cyl_ld_fn);
translate([-sin(a+step)*r, 0, cos(a+step)*r]) sphere(r=r0, $fn=cyl_ld_fn);
translate([-sin(a)*r, -3.7, -saddle_height-r0]) sphere(r=r0, $fn=cyl_ld_fn);
translate([-sin(a+step)*r, -3.7, -saddle_height-r0]) sphere(r=r0, $fn=cyl_ld_fn);
translate([-sin(a)*r, 1.2, -saddle_height-r0]) sphere(r=r0, $fn=cyl_ld_fn);
translate([-sin(a+step)*r, 1.2, -saddle_height-r0]) sphere(r=r0, $fn=cyl_ld_fn);
}
}
// Bridge channel notch
notch_w = bridge_channel_width - CF_Square_Width_tolerance; // Shrink a little for tolerance
notch_d = bridge_channel_depth - CF_Square_Width_tolerance/2;
translate([-notch_w/2, 0, -notch_d]) cube([notch_w, y_len, notch_d]);
}
// Pickup notch
tol = 0.25;
translate([-neck_width/2, 2, -tol]) hull() {
cube([neck_width, pickup_w, pickup_h+tol]);
translate([0, pickup_h*0.8, 0]) cube([neck_width, pickup_w, 0.01]);
}
// Version stamp
y0 = 0;
y1 = y_len;
translate([-15,y0+0.5,4]) rotate([90,0,0]) linear_extrude(10) {
text(str(id_line_0, id_line_1), size=2.9, halign="center", valign="center", $fn=100);
}
translate([-15,y1-0.5,4]) rotate([90,0,180]) linear_extrude(10) {
text(str(id_line_0, id_line_1), size=2.9, halign="center", valign="center", $fn=100);
}
}
} else if (from_fret == -5) {
echo("Making a tailpiece");
y0 = -47;
y1 = 0;
fw_len = 20;
total_len = y1-y0;
fw_height = 43;
rad_diameter = 20.35; //21;
rad_radius = rad_diameter/2;
render() difference() {
hull() {
translate([-body_width/2, -fw_len, -fw_height]) cube([body_width, fw_len, fw_height]);
translate([0, -total_len+rad_radius, -rad_radius]) rotate([0,90,0]) cylinder(h=neck_width, d=rad_diameter, center=true, $fn=cyl_hd_fn);
}
// Tuner cavity line up
tw = 16;
z0 = -43;
for (i=[-1,1]) translate([-tw/2 + i*15, y0, z0+5]) cube([tw, total_len, -z0-25]);
// String channels
for (i = [0:num_strings-1]) translate([(num_strings-i-1)*string_spacing - neck_width/2 + string_margin, y0+rad_radius, -rad_radius]) {
x = [-1,0,1,-1,0,1][i]*4/180;
r = rad_radius + string_diameters_mm[i]*0.5;
for (a = [0:180]) hull() {
translate([a*x, -sin(a)*r, cos(a)*r]) sphere(r=string_diameters_mm[i], $fn=cyl_ld_fn);
translate([a*x, -sin(a+1)*r, cos(a+1)*r]) sphere(r=string_diameters_mm[i], $fn=cyl_ld_fn);
}
}
// Bridge channel
translate([-bridge_channel_width/2, y0+rad_radius, -bridge_channel_depth]) cube([bridge_channel_width, total_len-rad_radius, bridge_channel_depth]);
// Version stamp
translate([-30,y0+0.5,-15]) rotate([90,0,0]) linear_extrude(10) {
text(str(id_line_0, id_line_1), size=2.9, halign="center", valign="center", $fn=100);
}
translate([-30,y1-0.5,-15]) rotate([90,0,180]) linear_extrude(10) {
text(str(id_line_0, id_line_1), size=2.9, halign="center", valign="center", $fn=100);
}
// CF
for (v = reinforcing_tube_positions) CFTubeCutout2(v, y0, y1);
for (v = reinforcing_square_positions) CFSquareCutout2(v, y0, y1);
}
}
// Debug markers to aid part slicing eyeballing
// %for (i = [150:250:1000]) {
%for (i = [0:250:1000]) {
translate([35,i,0]) union() {linear_extrude(1) text(str(i, "mm")); cube([35, 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(reference=true);
// translate([0, fret_scale_length(22), 0]) Nylon6String(from_fret=0, to_fret=22);
// translate([0, Guitar_Scale_Length_mm, 0]) rotate([0,0,180]) Nylon6String(reference=true);
// rotate([0,0,180]) Nylon6String(from_fret=-1);
// Nylon6String(from_fret=-2);
// Nylon6String(from_fret=-3);
// Nylon6String(from_fret=-4);
// %Nylon6String(from_fret=-5);
// difference() {
// translate([-15, -60, 0]) cube([50, 120, 8]);
// translate([0, 55, 3]) rotate([180,0,0]) NylonTuner();
// }
// Colour schemes
include <BambuColours.scad>
COLOURSCHEME_ABS_CLOWNFISH = [BAMBU_ABS_ORANGE, BAMBU_ABS_WHITE, BAMBU_ABS_BLACK, BAMBU_ABS_BLACK];
COLOURSCHEME_ABSGF_CLOWNFISH = [BAMBU_ABSGF_ORANGE, BAMBU_ABSGF_WHITE, BAMBU_ABSGF_BLACK, BAMBU_ABSGF_BLACK];
COLOURSCHEME_PA6GF_CLOWNFISH = [BAMBU_PA6GF_ORANGE, BAMBU_PA6GF_WHITE, BAMBU_PA6GF_BLACK, BAMBU_PA6GF_BLACK];
COLOURSCHEME_PETGHF_CLOWNFISH = [BAMBU_PETGHF_ORANGE, BAMBU_PETGHF_WHITE, BAMBU_PETGHF_BLACK, BAMBU_PETGHF_BLACK];
COLOURSCHEME_ABS_BLUE = [BAMBU_ABS_NAVY_BLUE, BAMBU_ABS_AZURE, BAMBU_ABS_AZURE, BAMBU_ABS_AZURE];
COLOURSCHEME_PETGHF_BLUE = [BAMBU_PETGHF_LAKE_BLUE, BAMBU_PETGHF_LAKE_BLUE, "", ""];
// colour_scheme = COLOURSCHEME_ABSGF_CLOWNFISH;
// colour_scheme = COLOURSCHEME_ABS_BLUE;
// color(colour_scheme[0]) rotate([90,0,0]) Steel6String(from_fret=0, to_fret=23, include_colours=[0]);
// color(colour_scheme[1]) rotate([90,0,0]) Steel6String(from_fret=0, to_fret=23, include_colours=[1]);
// color(colour_scheme[2]) rotate([90,0,0]) Steel6String(from_fret=0, to_fret=23, include_colours=[2]);
// color(colour_scheme[3]) rotate([90,0,0]) Steel6String(from_fret=0, to_fret=23, include_colours=[3]);
// rotate([90,0,0]) Steel6String(include_colours=[0,1,2,3], reference=true);
// TrussRodSingleAction();
// translate([20, 0]) TrussRod();
// difference() {
// l = 70;
// w = 20;
// extra = 5;
// translate([-w/2, -extra, 1.6-w/2]) cube([w, l+extra, w]);
// // TrussRod(taper_points=[-extra, l], extra=true, tolerance = 0.24);
// TrussRodSingleAction(taper_points=[-extra, l], extra=true, tolerance = 0.24);
// }
module TwoBangerMk2(include_colours=[0,1]) {
TaperNeck(string_spacing_bridge=20, string_spacing_nut=20, num_strings=2, extra_height=6, fret_widths=concat([3.6], [ for (i=[0:50]) 2.4 ]), num_frets=34, fret_side_marker_x_angle=-23, fret_side_marker_y_angle=5, include_colours=include_colours);
}
Guitar_Scale_Length_mm = PBass_Scale_mm;
colour_scheme = COLOURSCHEME_ABS_BLUE;
color(colour_scheme[0]) TwoBangerMk2([0]);
color(colour_scheme[1]) TwoBangerMk2([1]);
color(colour_scheme[2]) TwoBangerMk2([2]);
color(colour_scheme[3]) TwoBangerMk2([3]);