From 650b03816f0973d0461793cb19b753cf9a0f663e Mon Sep 17 00:00:00 2001 From: Luke Hubmayer-Werner Date: Sun, 26 Jan 2025 16:02:07 +1030 Subject: [PATCH] Refactor CFTubes neck to EllipticalNeck --- CFTubes.scad | 130 +------------------------------------------- EllipticalNeck.scad | 130 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 131 insertions(+), 129 deletions(-) create mode 100644 EllipticalNeck.scad diff --git a/CFTubes.scad b/CFTubes.scad index 0c794ed..858935a 100644 --- a/CFTubes.scad +++ b/CFTubes.scad @@ -6,6 +6,7 @@ include // Choose your material by only including one of the below // include include +include // 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 @@ -20,135 +21,6 @@ fret_inlays = [[3, "真"], [5, "尊"], [7, "正"], [9, "清"], [12, "評判"], [ // ShinKaiYaku65 22しかし、御霊の実は、愛、喜び、平安、寛容、親切、善意、誠実、 23柔和、自制です。このようなものを禁ずる律法はありません。 // 愛 喜び 平安 寛容 親切 善意 誠実 柔和 自制 -module neck(string_spacing=18, string_margin=4.5, num_strings=3, target_neck_thickness=15, target_neck_thickness_additional_points=[], scallop_depth=3, num_frets=24, fret_width=2.4, filler=false, inlays_only=false, side_markers_only=false, fret_layers_only=false, remove_fret_layers=false, engrave_markers=true) { - 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]) - if (len(target_neck_thickness_additional_points) < 1) { - 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 - } 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) - 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 intersect_fret_layers() { - for (fret = [0:num_frets]) { - translate([-500, fret_scale_length(fret)-fret_width/2, -500]) - cube([1000, fret_width, 1000]); - } - // Some precision error with fret 0 :/ - translate([-500, fret_scale_length(0)-fret_width/2+0.0006, -500]) - cube([1000, fret_width, 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_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 = 5); - } - } - } - - module carved_stock() { - render() difference() { - neck_stock(); - scallops(); - scallop(num_frets+1); - // 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(); - } - } - - 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() intersection() { - difference() { - carved_stock(); - if (engrave_markers) { - fret_inlays(); - fret_side_markers(); - } - if (remove_fret_layers) intersect_fret_layers(); - } - if (fret_layers_only || inlays_only || side_markers_only) union() { - if (fret_layers_only) intersect_fret_layers(); - if (inlays_only) fret_inlays(); - if (side_markers_only) fret_side_markers(); - } - } - } -} - 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; diff --git a/EllipticalNeck.scad b/EllipticalNeck.scad new file mode 100644 index 0000000..c05cdd4 --- /dev/null +++ b/EllipticalNeck.scad @@ -0,0 +1,130 @@ +// Include after common.scad + +module neck(string_spacing=18, string_margin=4.5, num_strings=3, target_neck_thickness=15, target_neck_thickness_additional_points=[], scallop_depth=3, num_frets=24, fret_width=2.4, filler=false, inlays_only=false, side_markers_only=false, fret_layers_only=false, remove_fret_layers=false, engrave_markers=true) { + 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]) + if (len(target_neck_thickness_additional_points) < 1) { + 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 + } 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) - 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 intersect_fret_layers() { + for (fret = [0:num_frets]) { + translate([-500, fret_scale_length(fret)-fret_width/2, -500]) + cube([1000, fret_width, 1000]); + } + // Some precision error with fret 0 :/ + translate([-500, fret_scale_length(0)-fret_width/2+0.0006, -500]) + cube([1000, fret_width, 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_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 = 5); + } + } + } + + module carved_stock() { + render() difference() { + neck_stock(); + scallops(); + scallop(num_frets+1); + // 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(); + } + } + + 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() intersection() { + difference() { + carved_stock(); + if (engrave_markers) { + fret_inlays(); + fret_side_markers(); + } + if (remove_fret_layers) intersect_fret_layers(); + } + if (fret_layers_only || inlays_only || side_markers_only) union() { + if (fret_layers_only) intersect_fret_layers(); + if (inlays_only) fret_inlays(); + if (side_markers_only) fret_side_markers(); + } + } + } +}