Refactoring for Truss Rod guitars

This commit is contained in:
Luke Hubmayer-Werner 2025-02-02 00:17:00 +10:30
parent b6a25ae821
commit 56c70c68e5
3 changed files with 525 additions and 13 deletions

View File

@ -626,6 +626,353 @@ module Nylon6String(render_colour_0=true, render_colour_1=true, render_colour_2=
}
}
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
string_margin = 3; // +6
neck_width = string_spacing_bridge*(num_strings-1) + string_margin*2;
body_width = 96;
scallop_depth = 2.5;
_zero_fret_width = 3.0;
_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)];
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]];
echo(str("Making a Steel 6 String with scale length ", fsl_mm, "mm = ", fsl_mm/25.4, "in and neck width ", neck_width, "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,
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,
);
}
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) {
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);
}
}
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();
}
}
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);}
}
}
// 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);
@ -639,7 +986,7 @@ module Nylon6String(render_colour_0=true, render_colour_1=true, render_colour_2=
// tailpiece();
// bridge();
Guitar_Scale_Length_mm = Classical_Short_Scale_mm;
// 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);
@ -666,18 +1013,18 @@ COLOURSCHEME_PETGHF_CLOWNFISH = [BAMBU_PETGHF_ORANGE, BAMBU_PETGHF_WHITE, BAMBU_
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_ABSGF_CLOWNFISH;
// colour_scheme = COLOURSCHEME_ABS_BLUE;
// color(colour_scheme[0]) Nylon6String(from_fret=0, to_fret=22, render_colour_0=true, render_colour_1=false, render_colour_2=false, render_colour_3=false);
// color(colour_scheme[1]) Nylon6String(from_fret=0, to_fret=22, render_colour_0=false, render_colour_1=true, render_colour_2=false, render_colour_3=false);
// color(colour_scheme[2]) Nylon6String(from_fret=0, to_fret=22, render_colour_0=false, render_colour_1=false, render_colour_2=true, render_colour_3=false);
// color(colour_scheme[3]) Nylon6String(from_fret=0, to_fret=22, render_colour_0=false, render_colour_1=false, render_colour_2=false, render_colour_3=true);
color(colour_scheme[0]) Steel6String(from_fret=0, to_fret=23, include_colours=[0]);
color(colour_scheme[1]) Steel6String(from_fret=0, to_fret=23, include_colours=[1]);
color(colour_scheme[2]) Steel6String(from_fret=0, to_fret=23, include_colours=[2]);
color(colour_scheme[3]) Steel6String(from_fret=0, to_fret=23, include_colours=[3]);
// 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);
}
// 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);
// }

View File

@ -128,3 +128,166 @@ module neck(string_spacing=18, string_margin=4.5, num_strings=3, target_neck_thi
}
}
}
module TaperNeck(
string_spacing_nut = 10.0,
string_spacing_bridge = 11.6,
num_strings = 6,
string_margin = 4.5,
target_neck_thickness = 15,
target_neck_thickness_additional_points = [],
scallop_depth = 2,
num_frets = 24,
fret_widths = [],
fret_angle = 60, // 90 is semicircle
filler = false,
include_colours = [0, 1, 2, 3], // 0: Base neck/fretboard 1: Frets 2: Inlays 3: Side markers
){
neck_length = fret_scale_length(0) + fret_widths[0]/2;
// neck_width = (num_strings-1)*string_spacing_nut + string_margin*2;
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(fret) = lerp(neck_width_bridge, neck_width_nut, 2^(-fret/12));
function neck_width_mm(mm) = lerp(neck_width_bridge, neck_width_nut, mm/fret_scale_length(0));
max_fret_width = max(fret_widths);
max_fret_height = sin(fret_angle) * max_fret_width/2;
module neck_stock() {
angle_excess = asin((scallop_depth + max_fret_height)/target_neck_thickness);
a0 = 90-angle_excess;
a1 = 270+angle_excess;
rotate([-90, 0, 0])
if (len(target_neck_thickness_additional_points) < 1) {
render() hull() {
translate([0,0,neck_length-0.0001]) linear_extrude(0.0001)
polygon([for (i = [0:300]) let(a=lerp(a0, a1, i/300.0)) [neck_width_mm(neck_length)*0.5*sin(a), -target_neck_thickness*cos(a)]]); // Ellipse
translate([0,0,0]) linear_extrude(0.0001)
polygon([for (i = [0:300]) let(a=lerp(a0, a1, i/300.0)) [neck_width_mm(0)*0.5*sin(a), -target_neck_thickness*cos(a)]]); // Ellipse
}
} else {
pts = flatten([[[neck_length, target_neck_thickness]], target_neck_thickness_additional_points]);
echo(pts);
for (i = [0:len(pts)-2]) {
pt0 = pts[i];
pt1 = pts[i+1];
echo(i, pt0, pt1);
render() hull() {
translate([0,0,pt0[0]]) linear_extrude(0.01)
polygon([for (i = [0:300]) let(a=lerp(a0, a1, i/300.0)) [neck_width*0.5*sin(a), -pt0[1]*cos(a)]]); // Ellipse
translate([0,0,pt1[0]]) linear_extrude(0.01)
polygon([for (i = [0:300]) let(a=lerp(a0, a1, i/300.0)) [neck_width*0.5*sin(a), -pt1[1]*cos(a)]]); // Ellipse
}
}
}
}
module scallop(fret) {
x0 = fret_scale_length(fret-1) - fret_widths[max(0, fret-1)]/2;
x1 = fret_scale_length(fret) + fret_widths[min(num_frets, fret)]/2;
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_bridge, center=true) polygon(arc);
}
module scallops() {
for (fret = [0:num_frets]) {
scallop(fret);
}
}
module fret_bump(fw, a = fret_angle) {
// a must be in range (0,90] for correct geometry
fn = 50;
fn2 = fn * 2;
ca = cos(a);
sa = sin(a);
r = fw / (2*sa);
arc = [ for (i = [-fn:fn]) [fw*i/fn2, r*(sqrt(1 - pow(sa*(i/fn), 2))-ca)] ];
// echo("fret_bump", a, ca, arc);
rotate([90, 0, 90]) linear_extrude(neck_width_bridge, center=true) polygon(arc);
}
module fret_bumps() {
for (fret = [0:num_frets])
translate([0, fret_scale_length(fret), scallop_depth])
fret_bump(fret_widths[fret]);
}
module intersect_fret_layers() {
for (fret = [0:num_frets]) {
translate([-500, fret_scale_length(fret)-fret_widths[fret]/2, -500])
cube([1000, fret_widths[fret], 1000]);
}
// Some precision error with fret 0 :/
translate([-500, fret_scale_length(0)-fret_widths[0]/2+0.0006, -500])
cube([1000, fret_widths[0], 1000]);
}
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_Sans_Font, halign = "center", valign = "center", size = clamp(2, diff-fret_widths[fret]*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_mm(mid)/2-3])
linear_extrude(50)
rotate(-37)
text(text = str(fret), font = JP_Serif_Font, halign = "right", valign = "center", size = 5);
}
}
}
module carved_stock() {
render() difference() {
neck_stock();
scallops();
scallop(num_frets+1);
// Chop off anything above the frets
translate([-neck_width_bridge, 0, scallop_depth]) cube([neck_width_bridge*2, Guitar_Scale_Length_mm*3, target_neck_thickness*3]);
// Reduce rest of the body to 0
translate([-neck_width_bridge, 0, 0]) cube([neck_width_bridge*2, (fret_scale_length(num_frets)+fret_scale_length(num_frets+1))/2, target_neck_thickness*3]);
}
intersection() {
fret_bumps();
neck_stock();
}
}
if (filler) { // Somewhat placeholder for now
difference() {
neck_stock();
scallop(25);
translate([-neck_width_bridge, 0, scallop_depth]) cube([neck_width_bridge*2, Guitar_Scale_Length_mm*3, target_neck_thickness*3]);
translate([-neck_width_bridge, 0, 0]) cube([neck_width_bridge*2, (fret_scale_length(25)+fret_scale_length(24))/2, target_neck_thickness*3]);
}
} else {
has1 = list_has(include_colours, 1);
has2 = list_has(include_colours, 2);
has3 = list_has(include_colours, 3);
render() intersection() {
difference() {
carved_stock();
if (!has1) intersect_fret_layers();
if (!has2) fret_inlays();
if (!has3) fret_side_markers();
}
if (has1 || has2 || has3) union() {
if (has1) intersect_fret_layers();
if (has2) fret_inlays();
if (has3) fret_side_markers();
}
}
}
}

View File

@ -38,6 +38,8 @@ function arc_points(tri_points, fragments_per_mm=5) =
)
[for (i = [0:steps]) r*[cos(a_start+i*a_step), sin(a_start+i*a_step)] + cc];
function list_has(list, value) = len(search(value, list)) > 0;
module round_cube(size, r) {
translate([r, r, r]) minkowski() {
cube(size-[r*2,r*2,r*2]);