2024-12-22 01:07:14 +10:30
include < common.scad >
2024-12-26 13:14:01 +10:30
include < UBassTuner.scad >
2025-01-01 22:33:40 +10:30
include < NylonTuner.scad >
2024-12-22 01:07:14 +10:30
2025-01-02 15:11:48 +10:30
include < CFTubes/common.scad >
// Choose your material by only including one of the below
2025-01-04 15:37:24 +10:30
include < CFTubes/PLA.scad >
// include <CFTubes/PETG.scad>
2025-01-01 22:33:40 +10:30
2025-01-02 15:11:48 +10:30
// 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
2024-12-22 01:07:14 +10:30
// Philippians 4:8
2025-01-01 22:33:40 +10:30
// Gideon (ShinKaiYaku07) 真実な, 尊ぶべき, 正しい, 清い, 愛すべき, 評判の良い, 徳とされる, 称賛に値する
2024-12-22 01:07:14 +10:30
// 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 , "主イエス" ] ] ;
2025-01-11 00:48:14 +10:30
// Galatians 5:22-23
// ShinKaiYaku65 22しかし、御霊の実は、愛、喜び、平安、寛容、親切、善意、誠実、 23柔和、自制です。このようなものを禁ずる律法はありません。
// 愛 喜び 平安 寛容 親切 善意 誠実 柔和 自制
2024-12-22 01:07:14 +10:30
2025-01-04 15:37:24 +10:30
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 ) {
2024-12-23 14:47:47 +10:30
fw2 = fret_width / 2 ;
neck_length = fret_scale_length ( 0 ) + fw2 ;
2024-12-22 01:07:14 +10:30
neck_width = ( num_strings - 1 ) * string_spacing + string_margin * 2 ;
module neck_stock ( ) {
2024-12-23 14:47:47 +10:30
angle_excess = asin ( ( scallop_depth + fw2 ) / target_neck_thickness ) ;
a0 = 90 - angle_excess ;
a1 = 270 + angle_excess ;
2024-12-22 01:07:14 +10:30
rotate ( [ - 90 , 0 , 0 ] )
2025-01-04 03:09:41 +10:30
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
}
}
}
2024-12-22 01:07:14 +10:30
}
2024-12-24 21:31:02 +10:30
module scallop ( fret ) {
2024-12-23 14:47:47 +10:30
x0 = fret_scale_length ( fret - 1 ) - fw2 ;
x1 = fret_scale_length ( fret ) + fw2 ;
2024-12-22 01:07:14 +10:30
xmid = lerp ( x0 , x1 , 0.5 ) ;
// Radius it?
arc = arc_points ( [ [ x0 , scallop_depth ] , [ x1 , scallop_depth ] , [ xmid , 0 ] ] ) ;
2024-12-23 13:36:52 +10:30
// echo(arc);
2024-12-22 01:07:14 +10:30
rotate ( [ 90 , 0 , 90 ] ) linear_extrude ( neck_width , center = true ) polygon ( arc ) ;
2024-12-24 21:31:02 +10:30
}
module scallops ( ) {
for ( fret = [ 0 : num_frets ] ) {
scallop ( fret ) ;
2024-12-22 01:07:14 +10:30
}
}
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 ) ;
}
}
2025-01-04 15:37:24 +10:30
module intersect_fret_layers ( ) {
for ( fret = [ 0 : num_frets ] ) {
translate ( [ - 500 , fret_scale_length ( fret ) - fret_width / 2 , - 500 ] )
cube ( [ 1000 , fret_width , 1000 ] ) ;
}
2025-01-11 14:35:19 +10:30
// Some precision error with fret 0 :/
translate ( [ - 500 , fret_scale_length ( 0 ) - fret_width / 2 + 0.0006 , - 500 ] )
cube ( [ 1000 , fret_width , 1000 ] ) ;
2025-01-04 15:37:24 +10:30
}
2024-12-22 01:07:14 +10:30
module fret_inlays ( ) {
for ( num_text = fret_inlays ) {
fret = num_text [ 0 ] ;
2025-01-01 22:33:40 +10:30
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 )
2025-01-11 00:48:14 +10:30
text ( text = num_text [ 1 ] , font = JP_Sans_Font , halign = "center" , valign = "center" , size = clamp ( 2 , diff - fret_width * 2 - 2 , 10 ) ) ;
2025-01-01 22:33:40 +10:30
}
2024-12-22 01:07:14 +10:30
}
}
module fret_side_markers ( ) {
for ( num_text = fret_inlays ) {
fret = num_text [ 0 ] ;
2025-01-01 22:33:40 +10:30
if ( fret < = num_frets ) {
x0 = fret_scale_length ( fret - 1 ) ;
x1 = fret_scale_length ( fret ) ;
diff = x0 - x1 ;
2025-01-02 15:11:48 +10:30
mid = lerp ( x0 , x1 , 0.67 ) ;
rotate ( [ 0 , - 94 , 0 ] )
translate ( [ 0 , mid , neck_width / 2 - 3 ] )
2025-01-01 22:33:40 +10:30
linear_extrude ( 50 )
2025-01-02 15:11:48 +10:30
rotate ( - 37 )
2025-01-11 00:48:14 +10:30
text ( text = str ( fret ) , font = JP_Serif_Font , halign = "right" , valign = "center" , size = 5 ) ;
2025-01-01 22:33:40 +10:30
}
2024-12-22 01:07:14 +10:30
}
}
2024-12-24 21:31:02 +10:30
2025-01-04 15:37:24 +10:30
module carved_stock ( ) {
2024-12-24 21:31:02 +10:30
render ( ) difference ( ) {
neck_stock ( ) ;
scallops ( ) ;
2025-01-02 01:52:19 +10:30
scallop ( num_frets + 1 ) ;
// Chop off anything above the frets
2024-12-24 21:31:02 +10:30
translate ( [ - neck_width , 0 , scallop_depth ] ) cube ( [ neck_width * 2 , Guitar_Scale_Length_mm * 3 , target_neck_thickness * 3 ] ) ;
2025-01-02 01:52:19 +10:30
// 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 ] ) ;
2024-12-24 21:31:02 +10:30
}
intersection ( ) {
fret_bumps ( ) ;
neck_stock ( ) ;
}
2024-12-22 01:07:14 +10:30
}
2025-01-04 15:37:24 +10:30
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 ( ) ;
}
}
}
2024-12-22 01:07:14 +10:30
}
2024-12-27 19:06:45 +10:30
module tailpiece ( string_spacing = 18 , string_margin = 4.5 , num_strings = 3 , target_neck_thickness = 15 , scallop_depth = 3 , fret_width = 2.4 * 6 ) {
2024-12-26 13:14:01 +10:30
fw2 = fret_width / 2 ;
2024-12-28 13:43:39 +10:30
neck_length = 84 ;
neck_width = ( num_strings - 1 ) * string_spacing + string_margin * 2 + 6 + 6 ;
2024-12-26 13:14:01 +10:30
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 ( ) {
2024-12-28 13:43:39 +10:30
t_offset = - 30 ; //2.7;
t_z = - 25 ; //-23;
2024-12-27 19:06:45 +10:30
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);
2024-12-27 19:10:13 +10:30
translate ( [ 36 - 7 , 7 , 1 ] ) for ( a = [ 10 : 89 ] ) {
2024-12-27 19:06:45 +10:30
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 ) ;
2024-12-28 13:43:39 +10:30
translate ( [ 7 , bend_r - bend_r * sin ( a + 1 ) , bend_r * cos ( a + 1 ) ] ) sphere ( hole_r , $fn = fn ) ;
2024-12-27 19:06:45 +10:30
}
}
}
2024-12-28 13:43:39 +10:30
translate ( [ t_offset , 49 , t_z ] ) tuner ( ) ;
mirror ( [ 1 , 0 , 0 ] ) translate ( [ t_offset , 27 , t_z ] ) tuner ( ) ;
2024-12-27 19:10:13 +10:30
translate ( [ t_offset , 5 , t_z ] ) tuner ( ) ;
2024-12-26 13:14:01 +10:30
for ( i = [ - 1 : 2 : 1 ] )
translate ( [ i * 15 , 0 , - 4 ] )
2025-01-02 15:11:48 +10:30
CFTubeCutout ( neck_length , 0 , tolerance = 0.4 ) ;
2024-12-26 13:14:01 +10:30
translate ( [ 0 , 0 , - 10 ] )
2025-01-02 15:11:48 +10:30
CFTubeCutout ( neck_length , 0 , tolerance = 0.4 ) ;
2024-12-26 13:14:01 +10:30
}
2024-12-28 13:43:39 +10:30
thick = 34 ;
2024-12-26 19:05:49 +10:30
render ( ) difference ( ) {
2024-12-28 13:43:39 +10:30
color ( [ 1 , 1 , 1 , 0.7 ] ) translate ( [ - neck_width / 2 , 0 , - thick ] ) round_cube ( [ neck_width , neck_length , thick ] , 4 ) ;
2024-12-26 13:14:01 +10:30
differences ( ) ;
}
// color([1,1,1,0.3]) neck_stock();
}
2024-12-22 16:01:41 +10:30
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 ] )
2025-01-02 15:11:48 +10:30
CFTubeCutout ( x1 , x2 ) ;
2024-12-22 16:01:41 +10:30
for ( i = [ - 1 : 2 : 1 ] )
translate ( [ i * 7.5 , 0 , - 7 ] )
2025-01-02 15:11:48 +10:30
CFSquareCutout ( x1 , x2 ) ;
2024-12-22 16:01:41 +10:30
translate ( [ 0 , 0 , - 10 ] )
2025-01-02 15:11:48 +10:30
CFTubeCutout ( x1 , x2 ) ;
2024-12-22 16:01:41 +10:30
translate ( [ - 50 , 0 , - 50 ] ) cube ( [ 100 , x2 , 100 ] ) ;
translate ( [ - 50 , x1 , - 50 ] ) cube ( [ 100 , x0 - x1 , 100 ] ) ;
2024-12-22 01:07:14 +10:30
2024-12-22 16:01:41 +10:30
// αβγδεζ
2024-12-23 13:36:52 +10:30
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 ) ;
2024-12-22 16:01:41 +10:30
}
2024-12-22 01:07:14 +10:30
}
2024-12-22 16:01:41 +10:30
2024-12-26 18:42:39 +10:30
module fret_tube_filler ( from_fret , to_fret , fret_width = 2.4 , belthole_length = 140 , VLH = true ) {
2024-12-24 21:31:02 +10:30
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 ) ;
2024-12-26 18:42:39 +10:30
for ( i = [ - 1 : 1 ] )
translate ( [ i * 15 , 0 , ( i = = 0 ) ? ( - 10 ) : ( - 4 ) ] )
2025-01-02 15:11:48 +10:30
CFTubeCutout ( x1 , x2 , VLH = VLH ) ;
2024-12-24 21:31:02 +10:30
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 ) ;
}
}
// αβγδεζ
2024-12-26 18:42:39 +10:30
t = "01β.β" ;
2024-12-24 21:31:02 +10:30
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 ) ;
}
}
2024-12-23 14:47:47 +10:30
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 ) ] ] ) ;
}
2024-12-23 19:26:08 +10:30
module string_tubes ( tolerance = 1.0 ) {
2024-12-23 14:47:47 +10:30
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 ] ) {
2024-12-23 19:26:08 +10:30
string_diameter = string_thicknesses [ i ] + tolerance ;
2024-12-23 14:47:47 +10:30
x = - neck_width / 2 + string_margin + ( i * string_spacing ) ;
2024-12-24 03:59:26 +10:30
translate ( [ x , x0 + 2 , - bend_radius + scallop_depth ] ) string_tube ( string_diameter ) ;
2024-12-23 14:47:47 +10:30
}
}
difference ( ) {
stock ( ) ;
string_tubes ( ) ;
for ( i = [ - 1 : 2 : 1 ] )
translate ( [ i * 7.5 , 0 , - 7 ] )
2025-01-02 15:11:48 +10:30
CFSquareCutout ( x0 + cf_square_length , x0 , taper_x1 = false ) ;
2024-12-23 14:47:47 +10:30
// αβγδεζ
2024-12-24 03:59:26 +10:30
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 ) ;
2024-12-23 14:47:47 +10:30
}
}
2024-12-27 19:06:45 +10:30
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 ) ] )
2025-01-02 15:11:48 +10:30
CFTubeCutout ( piece_length + 0.1 , x0 - 0.1 , VLH = false ) ;
2024-12-27 19:06:45 +10:30
// αβγδεζ
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 ) ;
}
}
2025-01-12 18:28:13 +10:30
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 ) {
2025-01-11 00:48:14 +10:30
colour_0 = "blue" ;
colour_1 = "white" ; // fret layers
colour_2 = "green" ; // side markers
colour_3 = "yellow" ; // inlays
2025-01-04 15:37:24 +10:30
id_line_0 = "PLA" ;
2025-01-11 14:35:19 +10:30
id_line_1 = "1δ" ;
2025-01-01 22:33:40 +10:30
fsl_mm = fret_scale_length ( 0 ) ;
2025-01-03 18:20:30 +10:30
string_diameters_thous = [ 28 , 32 , 40 , 30 , 36 , 42 ] ;
string_diameters_mm = string_diameters_thous * 0.0254 ;
2025-01-01 22:33:40 +10:30
2025-01-11 00:48:14 +10:30
num_frets = 21 ;
2025-01-01 22:33:40 +10:30
num_strings = 6 ;
// 56mm wide neck
string_spacing = 10 ; // 50mm E to e
string_margin = 3 ; // +6
2025-01-03 18:20:30 +10:30
neck_width = string_spacing * ( num_strings - 1 ) + string_margin * 2 ;
2025-01-02 01:52:19 +10:30
scallop_depth = 2.5 ;
2025-01-02 15:59:23 +10:30
fret_width = 2.4 ;
2025-01-11 00:48:14 +10:30
target_neck_thickness = 16 ; //22;
2025-01-12 21:56:24 +10:30
// echo(fret_scale_length(8));
// echo(fret_scale_length(9));
2025-01-11 00:48:14 +10:30
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 ] ] ;
2025-01-04 03:09:41 +10:30
// target_neck_thickness_additional_points = [[400.025-fret_width/2, 22], [380, 25], [130, 42], [0, 42]];
2025-01-04 15:37:24 +10:30
// target_neck_thickness_additional_points = [[400.025-fret_width/2, 22], [380, 25], [0, 25]];
2025-01-04 03:09:41 +10:30
// target_neck_thickness_additional_points = [[400.025-fret_width/2, 22], [130, 42], [0, 42]];
2025-01-01 22:33:40 +10:30
2025-01-03 18:20:30 +10:30
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
2025-01-01 22:33:40 +10:30
2025-01-03 18:20:30 +10:30
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 ] ] ;
2025-01-02 15:11:48 +10:30
module CF_Span ( full_length = 700 , ply = 3 , hole = true ) {
2025-01-03 18:20:30 +10:30
for ( v = CF_Span_Coords ( full_length , ply ) )
translate ( v ) CFSquare ( hole = hole ) ;
2025-01-01 22:33:40 +10:30
}
2025-01-04 15:37:24 +10:30
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 ( ) {
2025-01-11 00:48:14 +10:30
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 ) ;
2025-01-04 03:09:41 +10:30
}
2025-01-03 18:20:30 +10:30
reinforcing_tube_positions = flatten ( [
[
for ( i = [ - 1 , 1 ] ) each [
// Headside reinforcement
2025-01-11 00:48:14 +10:30
[ i * 21.5 , rx1 , - 4 ] ,
2025-01-03 18:20:30 +10:30
// Bridgeside reinforcement
2025-01-11 00:48:14 +10:30
// [i*21.5, rx0, -4],
[ i * 17.25 , rx0 , - 10 ] ,
// [i*17, rx0, -12],
[ i * 3.95 , rx0 , - 16.5 ] ,
2025-01-03 18:20:30 +10:30
]
] ,
[
2025-01-11 00:48:14 +10:30
// Headside reinforcement
[ 0 , rx1 , - 4 ] ,
[ 0 , rx1 , - 11 ] ,
2025-01-03 18:20:30 +10:30
// Bridgeside reinforcement
2025-01-11 00:48:14 +10:30
// [0, rx0, -11],
2025-01-03 18:20:30 +10:30
] ] ) ;
echo ( reinforcing_tube_positions ) ;
// Through span construction
2025-01-04 15:37:24 +10:30
span_coords = CF_Span_Coords ( ply = 2 ) ;
2025-01-03 18:20:30 +10:30
reinforcing_square_positions = [
2025-01-11 00:48:14 +10:30
for ( i = [ - 1 , 1 ] ) each [ for ( v = span_coords ) [ i * 10 , rx0 , - 10 ] + v ]
2025-01-03 18:20:30 +10:30
] ;
echo ( reinforcing_square_positions ) ;
// neck(num_frets=num_frets, num_strings=num_strings, string_margin=string_margin, string_spacing=string_spacing);
2025-01-02 15:59:23 +10:30
// %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);
2025-01-03 18:20:30 +10:30
module NeckFragment ( from_fret , to_fret , to_origin = true , include_from_fret = false , test_tolerances_piece = false ) {
2025-01-02 15:59:23 +10:30
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 ;
2025-01-03 18:20:30 +10:30
module TestTolerancesPiece ( ) {
2025-01-02 15:59:23 +10:30
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 ) ;
2025-01-03 00:03:47 +10:30
translate ( [ 12 - CF_Square_Width , 0 , - 14 ] ) CFSquareCutout ( x0 , x1 - 8 , taper_length = 2 , taper_x2 = false ) ;
2025-01-02 15:59:23 +10:30
translate ( [ - 12 , 0 , - 14 ] ) CFSquareCutout ( x0 , x1 , taper_length = 2 ) ;
2025-01-03 00:03:47 +10:30
translate ( [ - 12 + CF_Square_Width , 0 , - 14 ] ) CFSquareCutout ( x0 + 8 , x1 , taper_length = 2 , taper_x1 = false ) ;
2025-01-02 15:59:23 +10:30
translate ( [ 20 , 0 , - 6 ] ) CFTubeCutout ( x0 , x1 , taper_length = 2 ) ;
}
2025-01-03 18:20:30 +10:30
translate ( [ 0 , to_origin ? - x0 : 0 , 0 ] ) render ( ) difference ( ) {
2025-01-04 15:37:24 +10:30
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 ( ) ;
}
2025-01-03 18:20:30 +10:30
}
2025-01-02 15:59:23 +10:30
}
2025-01-03 18:20:30 +10:30
// Test tolerances piece
module TestTolerancesPiece ( ) {
difference ( ) {
NeckFragment ( 2 , 3 , test_tolerances_piece = true ) ;
2025-01-04 15:37:24 +10:30
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" ) ;
2025-01-03 18:20:30 +10:30
}
2025-01-02 15:59:23 +10:30
}
2025-01-03 18:20:30 +10:30
// TestTolerancesPiece();
2025-01-01 22:33:40 +10:30
2025-01-03 18:20:30 +10:30
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 ;
2025-01-04 17:16:21 +10:30
module IDText ( thickness = 0.2 , inset = 0 , extra_line = str ( "F" , to_fret ) ) {
2025-01-11 00:48:14 +10:30
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 ) ;
2025-01-04 17:16:21 +10:30
}
}
module BackIDText ( thickness = 0.2 , inset = 0 ) {
rotate_around ( [ 0 , 0 , 180 ] , [ 0 , midpoint , 0 ] )
IDText ( thickness , inset , str ( "F" , from_fret ) ) ;
2025-01-04 15:37:24 +10:30
}
2025-01-03 18:20:30 +10:30
render ( ) difference ( ) {
NeckFragment ( from_fret , to_fret , include_from_fret = include_from_fret ) ;
2025-01-04 17:16:21 +10:30
// Subtract from frets
2025-01-11 00:48:14 +10:30
color ( "red" ) {
2025-01-04 17:16:21 +10:30
IDText ( ) ;
if ( include_from_fret ) BackIDText ( ) ;
}
2025-01-11 00:48:14 +10:30
color ( "red" ) BackIDText ( ) ;
2025-01-03 18:20:30 +10:30
}
2025-01-11 00:48:14 +10:30
// // 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();
2025-01-03 18:20:30 +10:30
}
2025-01-12 21:56:24 +10:30
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();
}
2025-01-12 18:28:13 +10:30
if ( reference ) {
union ( ) {
2025-01-04 15:37:24 +10:30
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
for ( m = [ 0 , 1 ] ) mirror ( [ m , 0 , 0 ] ) translate ( [ 29 , 10 , - 32 ] ) rotate ( [ 0 , - 90 , 0 ] ) NylonTuner ( ) ;
// 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 ) ;
}
2025-01-03 18:20:30 +10:30
}
2025-01-12 21:56:24 +10:30
} else if ( from_fret >= 0 ) {
2025-01-12 18:28:13 +10:30
RealPiece ( from_fret , to_fret , include_from_fret = ( from_fret = = 0 ) ) ;
2025-01-12 21:56:24 +10:30
} else if ( from_fret = = - 1 ) {
// String holding headpiece
echo ( "Making a headpiece" ) ;
HeadPiece ( ) ;
2025-01-03 18:20:30 +10:30
}
2025-01-01 22:33:40 +10:30
// Debug markers to aid part slicing eyeballing
2025-01-03 18:20:30 +10:30
// %for (i = [150:250:1000]) {
% for ( i = [ 0 : 250 : 1000 ] ) {
2025-01-11 00:48:14 +10:30
translate ( [ 35 , i , 0 ] ) union ( ) { linear_extrude ( 1 ) text ( str ( i , "mm" ) ) ; cube ( [ 35 , 1 , 1 ] , center = true ) ; }
2025-01-01 22:33:40 +10:30
}
}
// echo(fret_scale_length(0) - fret_scale_length(8)); // 225.724
// echo(fret_scale_length(8) - fret_scale_length(24)); // 240.335
2024-12-23 14:47:47 +10:30
// fret_tube(0, 8);
// //translate([30, 0, 0])
// fret_tube(8, 24);
2024-12-24 03:59:26 +10:30
// headpiece();
2024-12-24 21:31:02 +10:30
// UBassTuner();
2024-12-26 19:05:49 +10:30
// fret_tube_filler(24, 100);
2025-01-01 22:33:40 +10:30
// tailpiece();
2024-12-27 19:06:45 +10:30
// bridge();
2025-01-01 22:33:40 +10:30
Guitar_Scale_Length_mm = Classical_Short_Scale_mm ;
2025-01-12 21:56:24 +10:30
// translate([0, Guitar_Scale_Length_mm, 0]) rotate([0,0,180]) Nylon6String(reference=true);
rotate ( [ 0 , 0 , 180 ] ) Nylon6String ( from_fret = - 1 ) ;
2025-01-01 22:33:40 +10:30
2025-01-02 01:52:19 +10:30
// difference() {
// translate([-15, -60, 0]) cube([50, 120, 8]);
// translate([0, 55, 3]) rotate([180,0,0]) NylonTuner();
// }