// ---------------------------------------------------------------- // Customizable flexrails // // inspired by: // https://www.printables.com/model/146321-fischertechnik-compatible-flex-rail-flexschiene-15/files // // This package contains straight and circle flexrails. // The straight flexrail has a customizable length and height. // The circular flexrail has acustomizable radius and angle and, // in addition, the outer wall can be set to an other value than // the inner wall /* [Flexrail options] */ // Type Flexrail_type = 0; // [0 : no output, 1:Straight flexrail, 2:Circular flexrail, 3 : Pair of pins] // Outer height of the wall, may be used for circular flexrails Outer_height = 5.5; // Inner height of the wall, also used for both walls of the straight flexrail Inner_height = 5.5; // Add the required pins? Set_pins = true; /* [Options for the straight flexrail] */ // Length of the flexrail, uses standard ft lengths Length = 60; // [30, 45, 60, 75, 90, 105, 120, 135, 150, 165, 180] /* [Options for the circular flexrail] */ // The outer radius of the flexrail Radius = 45; // The angle of the flexrail Angle = 270; // [30 : 15 : 345] /* [Options for the flexrail pins] */ // The number of rows and columns of pins Count = [5, 4]; /* [Hidden] */ // ********************** // ** Static Settings: ** // ********************** include $fn=104; // The thickness of the flexrail base and walls thickness = 1.5; // The width of the flexrail flex_width = FT_GRID_SIZE; // width of the pin plate Pin_width = 9.1; // Length of the pin plate Pin_length = 7.1; // length and width of the quadratic hole through the flexrail Pin_hole = 5.01; // ********************* // ** Helper Modules: ** // ********************* // -------------------------------------------------------------------- // Cutout for the pins. The pins are separated from the rails to avoid // the need for support when printing the rail. // The pins may be glued into their cutouts, but hey, it's then // difficult to replace them ;-) // -------------------------------------------------------------------- module cutout(base_width = FT_GRID_SIZE, width = Pin_width, length = Pin_length, height = thickness, hole = Pin_hole, up = 0 ) { cutout_height = 1.5; offset = height / 2; union() { translate([base_width / 2 - hole / 2, base_width / 2 - hole / 2, -MANIFOLD_CORRECTION / 2]) cube([hole, hole, cutout_height]); if (up == 1) translate([base_width / 2 - width / 2, base_width / 2 - length / 2, offset]) cube([width, length, cutout_height]); else translate([base_width / 2 - length / 2, base_width / 2 - width / 2, offset]) cube([length, width, cutout_height]); } } // -------------------------------------------------------------------- // the slots in the rail // -------------------------------------------------------------------- module slot(slot_width, slot_length, slot_height) { translate([0, -MANIFOLD_CORRECTION / 2, -MANIFOLD_CORRECTION / 2]) cube([slot_width, slot_length, slot_height]); } // -------------------------------------------------------------------- // A slice of a circle to cut a piece out of the circle rail // -------------------------------------------------------------------- module slice(r = 10, deg = 30) { degn = (deg % 360 > 0) ? deg % 360 : deg % 360 + 360; difference() { circle(r); if (degn > 180) intersection_for(a = [0, 180 - degn]) rotate(a) translate([-r, 0, 0]) square(r * 2); else union() for(a = [0, 180 - degn]) rotate(a) translate([-r, 0, 0]) square(r * 2); } } // *********************** // ** Flexrail Modules: ** // *********************** // -------------------------------------------------------------------- // A plate with a pin fitting in the cutouts of the flexrails . // They may be glued into the pin hole, but hey: It is difficult to // remove them again whenever maintainance is needed ;-) // -------------------------------------------------------------------- module flexrail_pin(width = Pin_width, length = Pin_length, height = thickness, hole = 5) { correction = 0.5; translate([0, 0,height]) union() { translate([0, 0,-(height / 4)]) union() { cube ([hole - correction, hole - correction, height / 2], center = true); translate([0, 0, -(height / 2)]) cube ([width - correction, length - correction, height / 2], center = true); } pin(); } } // -------------------------------------------------------------------- // A straight flexrail // -------------------------------------------------------------------- module flexrail(length = Length, height = Inner_height) { wall_thickness = thickness; width = flex_width; y_center = width / 2; slot_width = 1.1; slot_length = width - wall_thickness + MANIFOLD_CORRECTION; slot_height = height + MANIFOLD_CORRECTION; slot_distance = 10.0; difference() { cube([length, width, height]); // cut out the inner rail part translate([-MANIFOLD_CORRECTION / 2, wall_thickness, wall_thickness]) cube([length + MANIFOLD_CORRECTION, width - 2 * wall_thickness, height]); // then cut out the holes for the pins on both ends cutout(); translate([length - width, 0, 0]) cutout(); // finally cut out the slots on both sides, but leave a bit // of the flexrail before the wall (substract or add the // MANIFOLD_CORRECTION to the y-axis) for(i=[width : slot_distance : length -width]) { translate([i, -MANIFOLD_CORRECTION, 0]) slot(slot_width, slot_length, slot_height); } for(i=[width + slot_distance / 2 : slot_distance : length -width]) { translate([i, wall_thickness + MANIFOLD_CORRECTION, 0]) slot(slot_width, slot_length, slot_height); } } } // -------------------------------------------------------------------- // a circle rail without cutouts // -------------------------------------------------------------------- module circle_rail(radius = 40, outer_height = Outer_height, inner_height = Inner_height, width = flex_width, angle = 270) { v_wall_thickness = thickness; bottom_thickness = thickness; difference() { union() { difference() { cylinder(r = radius, h = outer_height); translate([0, 0, bottom_thickness]) cylinder(r = radius - v_wall_thickness, h = outer_height); } cylinder(r = radius - width + v_wall_thickness, h = inner_height); } translate([0, 0,-MANIFOLD_CORRECTION / 2]) cylinder(r = radius - width, h = inner_height + MANIFOLD_CORRECTION); // finally substract a a slice so that the remaining circle covers // the angle given as parameter if (angle % 360 != 0) translate([0, 0, -MANIFOLD_CORRECTION / 2]) linear_extrude(outer_height + MANIFOLD_CORRECTION*2) slice(r = radius + MANIFOLD_CORRECTION , deg = 360 - angle); } } // -------------------------------------------------------------------- // cut slots into the circular flex rail // -------------------------------------------------------------------- module slot_circle(radius = 40.0, height = Inner_height, width = flex_width, start_angle = 30, end_angle = 270, segment_angle = 30, offset = 0) { wall_thickness = 1.5; slot_width = 1.1; slot_length = width - wall_thickness + MANIFOLD_CORRECTION + 1.4; slot_height = height + MANIFOLD_CORRECTION; for(i=[start_angle : segment_angle : end_angle]) { // echo(i); rotate([0, 0,i]) translate([radius - slot_length + offset, 0, -MANIFOLD_CORRECTION / 2]) cube([slot_length, slot_width, slot_height]); } } // -------------------------------------------------------------------- // Draw a slotted circular flexrail with pin cutouts. // -------------------------------------------------------------------- module circle_flexrail(radius = 40, outer_height = outer_height, inner_height = inner_height, width = flex_width, angle = 360) { seg_angle = 900 / radius; difference() { circle_rail(radius = radius, outer_height = outer_height, inner_height = inner_height, width = width, angle = angle); // cut out the pin holes translate([radius - width, 0, 0]) cutout(up = 1); rotate([0, 0, angle]) translate([radius - width, -width, 0]) cutout(up = 1); // cut out the slots on both sides, but leave a bit of the // flexrail before the wall (that's what the offset is for) slot_circle(radius = radius, height = inner_height, width = width, start_angle = seg_angle * 1.5, end_angle = angle - seg_angle, segment_angle = seg_angle, offset = -1.8); slot_circle(radius = radius, height = outer_height, width = width, start_angle = seg_angle * 2, end_angle = angle - seg_angle * 1.5, segment_angle = seg_angle, offset = 2.0); } } // ******************** // ** Build section: ** // ******************** module main() { if (Flexrail_type == 1) { flexrail(length = Length, height = Inner_height); if(Set_pins) { translate([-10, 7.5, 0]) rotate([0, 0, 90]) flexrail_pin(); translate([Length + 10, 7.5, 0]) rotate([0, 0, 90]) flexrail_pin(); } } else if (Flexrail_type == 2) { circle_flexrail(radius = Radius, angle = Angle, outer_height = Outer_height, inner_height = Inner_height); if (Set_pins) { translate([-5, 5, 0]) rotate([0, 0, 90]) flexrail_pin(); translate([5, 5, 0]) rotate([0, 0, 90]) flexrail_pin(); } } else if (Flexrail_type == 3) { for (i = [0 : 10 : (Count[1] - 1) * 10]) for (j = [0 : 10 : (Count[0] - 1) * 10]) translate([i, j, 0]) flexrail_pin(); } } main();