CF_Tube_Len = 420; // Convenient Amazon size, longer would be better of course but prices are important CF_Tube_OD = 5.0; // Outer Diameter CF_Tube_ID = 3.0; CF_Square_Width = 6.0; CF_Square_ID = 5.0; // Inner diameter, sadly doesn't fit the tubes cyl_hd_fn = $preview ? 32 : 512; cyl_ld_fn = $preview ? 24 : 72; module CFTube(hole=true) { // Align +y rotate([0, 0, 90]) render() difference() { rotate([0, 90, 0]) cylinder(h=CF_Tube_Len, d=CF_Tube_OD, $fn=cyl_hd_fn); if (hole) rotate([0, 90, 0]) cylinder(h=CF_Tube_Len, d=CF_Tube_ID, $fn=cyl_ld_fn); } } module CFSquare(hole=true) { rotate([0, 0, 90]) render() difference() { translate([0, -CF_Square_Width/2, -CF_Square_Width/2]) cube([CF_Tube_Len, CF_Square_Width, CF_Square_Width]); if (hole) rotate([0, 90, 0]) cylinder(h=CF_Tube_Len, d=CF_Square_ID, $fn=cyl_ld_fn); } } hull_epsilon = 0.2; module CFTubeCutout(x1, x2, tolerance = CF_Tube_OD_tolerance, VLH = false, taper_length = 5) { tolerance = tolerance + (VLH ? 0.3 : 0); taper_mul = 1.2; taper_direction = (x1 > x2) ? (-1) : 1; x_min = min(x1, x2); x_max = max(x1, x2); fn = 360; translate([0, x_min, 0]) rotate([-90,0,0]) cylinder(h=x_max-x_min, d=CF_Tube_OD+tolerance, $fn=fn); hull() { translate([0, x1]) rotate([-90,0,0]) cylinder(h=hull_epsilon, d=(CF_Tube_OD*taper_mul)+tolerance, $fn=fn); translate([0, x1+(taper_length*taper_direction)]) rotate([-90,0,0]) cylinder(h=hull_epsilon, d=CF_Tube_OD+tolerance, $fn=fn); } hull() { translate([0, x2]) rotate([-90,0,0]) cylinder(h=hull_epsilon, d=(CF_Tube_OD*taper_mul)+tolerance, $fn=fn); translate([0, x2-(taper_length*taper_direction)]) rotate([-90,0,0]) cylinder(h=hull_epsilon, d=CF_Tube_OD+tolerance, $fn=fn); } } module CFSquareCutout(x1, x2, tolerance = CF_Square_Width_tolerance, taper_x1 = true, taper_x2 = true, taper_length = 5) { x = CF_Square_Width+tolerance; taper_mul = 1.2; taper_direction = (x1 > x2) ? (-1) : 1; x_min = min(x1, x2); x_max = max(x1, x2); translate([-x/2, x_min, -x/2]) cube([x, x_max-x_min, x]); if (taper_x1) { hull() { translate([0, x1, 0]) cube([x*taper_mul, hull_epsilon, x*taper_mul], center=true); translate([0, x1+(taper_length*taper_direction), 0]) cube([x, hull_epsilon, x], center=true); } } if (taper_x2){ hull() { translate([0, x2, 0]) cube([x*taper_mul, hull_epsilon, x*taper_mul], center=true); translate([0, x2-(taper_length*taper_direction), 0]) cube([x, hull_epsilon, x], center=true); } } } module CFTubeCutout2(v, block_y0, block_y1, tolerance = CF_Tube_OD_tolerance, VLH = false, taper_length = 2, taper_mul = 1.1, notch = true, tolerance_length = CF_Square_Width_tolerance) { // Alternate approach: supply start vector v, and the bounding y values of the piece, taper on entry points only. tolerance = tolerance + (VLH ? 0.3 : 0); tube_y0 = v[1]; tube_y1 = tube_y0 + CF_Tube_Len; OD = CF_Tube_OD + tolerance; taper_OD = (CF_Tube_OD*taper_mul) + tolerance; fn = 360; // Full cylinder, unconditional translate(v) translate([0, -tolerance_length, 0]) hull() { rotate([-90,0,0]) cylinder(h=CF_Tube_Len+tolerance_length*2, d=OD, $fn=fn); if (notch) translate([-OD*0.02, 0, -OD*0.6]) cube([OD*0.04, CF_Tube_Len, OD*0.6]); } // Check for tapered holes if ((block_y0 >= tube_y0) && (block_y0 < tube_y1)) // Tube protrudes through start of block hull() { translate([v[0], block_y0, v[2]]) rotate([-90,0,0]) cylinder(h=hull_epsilon, d=taper_OD, $fn=fn); translate([v[0], block_y0+taper_length, v[2]]) rotate([-90,0,0]) cylinder(h=hull_epsilon, d=OD, $fn=fn); } if ((block_y1 <= tube_y1) && (block_y1 > tube_y0)) // Tube protrudes through end of block hull() { translate([v[0], block_y1-hull_epsilon, v[2]]) rotate([-90,0,0]) cylinder(h=hull_epsilon, d=taper_OD, $fn=fn); translate([v[0], block_y1-hull_epsilon-taper_length, v[2]]) rotate([-90,0,0]) cylinder(h=hull_epsilon, d=OD, $fn=fn); } } module CFSquareCutout2(v, block_y0, block_y1, tolerance = CF_Square_Width_tolerance, taper_length = 2, taper_mul = 1.1, tolerance_length = CF_Square_Width_tolerance) { w = CF_Square_Width + tolerance; taper_w = (CF_Square_Width * taper_mul) + tolerance; tube_y0 = v[1]; tube_y1 = tube_y0 + CF_Tube_Len; // Full square rod, unconditional translate([v[0]-w/2, v[1] - tolerance_length, v[2]-w/2]) cube([w, CF_Tube_Len + tolerance_length*2, w]); // Check for tapered holes if ((block_y0 >= tube_y0) && (block_y0 < tube_y1)) // Tube protrudes through start of block hull() { translate([v[0], block_y0, v[2]]) cube([taper_w, hull_epsilon*2, taper_w], center=true); translate([v[0], block_y0+taper_length, v[2]]) cube([w, hull_epsilon*2, w], center=true); } if ((block_y1 <= tube_y1) && (block_y1 > tube_y0)) // Tube protrudes through end of block hull() { translate([v[0], block_y1-hull_epsilon, v[2]]) cube([taper_w, hull_epsilon*2, taper_w], center=true); translate([v[0], block_y1-hull_epsilon-taper_length, v[2]]) cube([w, hull_epsilon*2, w], center=true); } // if (taper_x1) { // hull() { // translate([0, x1, 0]) // cube([w*taper_mul, hull_epsilon, w*taper_mul], center=true); // translate([0, x1+(taper_length*taper_direction), 0]) // cube([w, hull_epsilon, w], center=true); // } // } // if (taper_x2){ // hull() { // translate([0, x2, 0]) // cube([w*taper_mul, hull_epsilon, w*taper_mul], center=true); // translate([0, x2-(taper_length*taper_direction), 0]) // cube([w, hull_epsilon, w], center=true); // } // } } module TrussRod(length = 630, tolerance = 0, taper_l = 1.5, taper_extra = 1.0, taper_points=[], extra=false) { $fn = 360; epsilon = 0.00000001; rot = [-90, 180, 0]; module squircle(d, h, w) { render() hull() { circle(d = d); translate([-w/2, h - d/2 - epsilon]) square([w, epsilon]); } } // base profile base_d = 6.0 + tolerance; base_w = base_d; base_h = 9.0 + tolerance; // nut? stage2_d = 7.0 + tolerance; stage2_w = base_w; stage2_h = base_h + (stage2_d - base_d); stage2_l = 55 + tolerance; // Turning end stage3_d = 9.1 + tolerance; stage3_w = stage3_d; stage3_h = base_h + (stage3_d - base_d); stage3_l = 35 + tolerance; // Rod outline stages = [ // Must be ascending order for later [stage3_l, stage3_d, stage3_h, stage3_w], [stage2_l, stage2_d, stage2_h, base_w], [length, base_d, base_h, base_w], ]; for (s = stages) rotate(rot) linear_extrude(s[0]) squircle(s[1], s[2], s[3]); if (extra) { l = 33; s = stages[0]; translate([0, -l, 0]) rotate(rot) linear_extrude(l+s[0]) squircle(s[1], s[2], s[3]); } // Tapers for (x = taper_points) { larger_stages = [ for (s = stages) if (s[0] >= x) s]; if (len(larger_stages)) { s = larger_stages[0]; t2 = taper_extra * 2; render() hull() { translate([0, x-epsilon/2, 0]) rotate(rot) linear_extrude(epsilon) squircle(s[1]+t2, s[2]+t2, s[3]+t2); translate([0, x+taper_l-epsilon, 0]) rotate(rot) linear_extrude(epsilon) squircle(s[1], s[2], s[3]); translate([0, x-taper_l, 0]) rotate(rot) linear_extrude(epsilon) squircle(s[1], s[2], s[3]); } } } }