bearings/bearing_mount_holes: extend with ziptie_dist param

use <thing_libutils/shapes.scad>;

// radial bearings
// inner_d, outer_d, length
bearing_608 = [8,22,7];
bearing_626 = [8,19,6];
bearing_625 = [5,16,5];
bearing_608 = [8,22,7];
bearing_MR128 = [8,12,3.5];

// linear bearings
// inner_d, outer_d, length, clips_len, clips_d

// http://www.igus.eu/wpck/12157/Motek14_N14_6_3_Vollkunststofflager?L=en
bearing_igus_rj4jp_01_08 = [8,15,24,17.5,14.3];
bearing_igus_rj4jp_01_10 = [10,19,29,22.5,18];
bearing_igus_rj4jp_01_12 = [12,21,30,23.5,20];
bearing_igus_rj4jp_01_16 = [16,28,37,26.5,26.6];
bearing_igus_rj4jp_01_20 = [20,32,42,30.5,30.3];

module bearing(bearing_type, orient=[0,0,1])
{
    orient(orient)
    difference()
    {
        // outer
        fncylindera(h=bearing_type[2], d=bearing_type[1], align=[0,0,0]);
        // inner
        fncylindera(h=bearing_type[2]+1, d=bearing_type[0], align=[0,0,0]);
        // clips
        if(len(bearing_type) > 3)
        {
            clip_depth=.5;
            for(j=[-1,1])
            translate([0,0,j*bearing_type[3]/2])
            difference()
            {
                fncylindera(h=1, d=bearing_type[2]+1, align=[0,0,0]);
                fncylindera(h=2, d=bearing_type[4]-clip_depth, align=[0,0,0]);
            }

        }
    }
}

module bearing_mount_holes(bearing_type, orient=[1,0,0], ziptie_dist=undef)
{
    orient(orient)
    {
        // Main bearing cut
        difference()
        {
            fncylindera(h=bearing_type[2], d=bearing_type[1]*rod_fit_tolerance, orient=[0,0,1]);
        }

        difference()
        {
            union()
            {
                ziptie_dist_ = ziptie_dist==undef?bearing_type[3]/2:ziptie_dist;
                for(i=[-1,1])
                translate([0,0,i*ziptie_dist_])
                fncylindera(h=ziptie_width, d=bearing_type[1]+ziptie_bearing_distance+ziptie_thickness, orient=[0,0,1]);
            }
            fncylindera(h=bearing_type[2], d=bearing_type[1]+ziptie_bearing_distance, orient=[0,0,1]);
        }

        // for linear rod
        fncylindera(d=bearing_type[0]*1.5, h=100, orient=[0,0,1]);
    }
}

use <thing_libutils/shapes.scad>;

// radial bearings
// inner_d, outer_d, length
bearing_608 = [8,22,7];
bearing_626 = [8,19,6];
bearing_625 = [5,16,5];
bearing_608 = [8,22,7];
bearing_MR128 = [8,12,3.5];

// linear bearings
// inner_d, outer_d, length, clips_len, clips_d

// http://www.igus.eu/wpck/12157/Motek14_N14_6_3_Vollkunststofflager?L=en
bearing_igus_rj4jp_01_08 = [8,15,24,17.5,14.3];
bearing_igus_rj4jp_01_10 = [10,19,29,22.5,18];
bearing_igus_rj4jp_01_12 = [12,21,30,23.5,20];
bearing_igus_rj4jp_01_16 = [16,28,37,26.5,26.6];
bearing_igus_rj4jp_01_20 = [20,32,42,30.5,30.3];

module bearing(bearing_type, orient=[0,0,1])
{
    orient(orient)
    difference()
    {
        // outer
        fncylindera(h=bearing_type[2], d=bearing_type[1], align=[0,0,0]);
        // inner
        fncylindera(h=bearing_type[2]+1, d=bearing_type[0], align=[0,0,0]);
        // clips
        if(len(bearing_type) > 3)
        {
            clip_depth=.5;
            for(j=[-1,1])
            translate([0,0,j*bearing_type[3]/2])
            difference()
            {
                fncylindera(h=1, d=bearing_type[2]+1, align=[0,0,0]);
                fncylindera(h=2, d=bearing_type[4]-clip_depth, align=[0,0,0]);
            }

        }
    }
}

module bearing_mount_holes(bearing_type, orient=[1,0,0])
{
    orient(orient)
    {
        // Main bearing cut
        difference()
        {
            fncylindera(h=bearing_type[2], d=bearing_type[1]*rod_fit_tolerance, orient=[0,0,1]);
        }

        difference()
        {
            union()
            {
                for(i=[-1,1])
                translate([0,0,i*bearing_type[3]/2])
                fncylindera(h=ziptie_width, d=bearing_type[1]+ziptie_bearing_distance+ziptie_thickness, orient=[0,0,1]);
            }
            fncylindera(h=bearing_type[2], d=bearing_type[1]+ziptie_bearing_distance, orient=[0,0,1]);
        }

        // for linear rod
        fncylindera(d=bearing_type[0]*1.5, h=100, orient=[0,0,1]);
    }
}


feat: add an operator to animate a rotation

/**
 * @license
 * MIT License
 *
 * Copyright (c) 2022 Jean-Sebastien CONAN
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

/**
 * Part of the camelSCAD library.
 *
 * Operators that animate child modules with respect to particular rules.
 *
 * @package operator/animate
 * @author jsconan
 */

/**
 * Rotates the child modules, interpolating the angles with respect to the `$t` variable.
 *
 * @param Vector [from] - The angles from where start the interpolation.
 * @param Vector [to] - The angles to where end the interpolation.
 * @param Number [start] - The start threshold under what the from-angles will persist and above what it will be interpolated.
 * @param Number [end] - The end threshold above what the to-angles will persist and under what it will be interpolated.
 * @param Number [domain] - The percentage domain used to compute the thresholds (default: 100).
 * @param Vector [values] - A list of angles composing the range to interpolate.
 * @param Vector [range] - A pre-built interpolation range. If missing, it will be built from the parameters `from`, `to`, `start`, `end`, `domain`.
 * @returns Number
 */
module rotateAnimate(from, to, start, end, domain, values, range) {
    rotate(interpolateStep3D(step=$t, low=from, high=to, start=start, end=end, domain=domain, values=values, range=range)) {
        children();
    }
}

error: pathspec 'operator/animate/rotate.scad' did not match any file(s) known to git


adjust camera stand to fit in the zoom compartement

use <dummies.scad>;
$fn = 36;
phi_ext = 26;

module camera(){
// http://www.arducam.com/spy-camera-raspberry-pi/
// Not the same cam exactly, but view angle is given
// as 54x41°, i.e 0.94 rad
     translate([0, 0, 2]) cylinder(d=7.4, h=3);
     translate([0, 1.5, 1.5]) cube([8.5, 11.3, 3], center=true);
     translate([0, 7, -1.2])
          union(){
          rotate([0, 0, -90]) translate([0, 3.75, 0]) rotate([90, 0, 0])
               difference(){
               cylinder(d=4, h=7.5);
               translate([0, 0, -1]) cylinder(d=3.6, h=9, $fn=36);
               translate([0, -5, -1]) cube(10);
          }
          translate([-3.75, -12, -2]) cube([7.5, 12, 0.2], center=false);
     }
}

module base_plate(){
     difference(){
          cylinder(d=phi_ext, h=6);
          for (i=[0:5])
               rotate([0, 0, 60*i]) translate([-phi_ext/2+1, 0, 0.9])
                    union(){
                    translate([0, -3.5, -1]) cylinder(h=10, d=3);
                    translate([0, 3.5, -1]) cylinder(h=10, d=3);
               }
     }
}

module camera_stand(){
     difference(){
          base_plate();
          translate([0, 2.5, 1.5]) cube([8.6, 13.6, 3], center=true);
          translate([0, 0, -2]) cylinder(d=7.8, h=12);
          translate([0, 0, 3]) ring(6, 22, 30);
     }
}

module lens_75(){
     translate([0, 0, -5.2]) union(){
          translate([0, 0, 0]) ring(3.2, 4.4, 8.4);
          translate([0, 0, -3.2]) ring(3.2, 7.2, 9.2);
     }
}

module lens_75_stand(){
     difference(){
          base_plate();
          translate([0, 0, -2]) cylinder(d=9.3, h=5.2);
          translate([0, 0, -2]) cylinder(d=8.1, h=12);
     }
}

module sequins_stand(){
     difference(){
          translate([0, 0, -5])  base_plate();
          for (i=[0:5])
               rotate([0, 0, 60*i]) translate([-10, 0, -1])
                    union(){
                    cube([2.2, 9.2, 4.2], center=true);
                    translate([2, 0, 0.1]) cube([4, 6, 4.1], center=true);
               }
          translate([0, 0, -8]) cylinder(d=16, h=12);

     }
}

module leds_sequins(){
     for (i=[0:5])
          rotate([0, 0, 60*i]) translate([-10, 0, -1]) sequin();
}

//
module sequin(){
     difference() {
          minkowski(){
               cube([1, 7, 2], center=true);
               rotate([0, 90, 0]) cylinder(r=1, h=1, center=true);
          }
          translate([-2, 3.5, 0]) rotate([0, 90, 0]) cylinder(r=0.5, h=4);
          translate([-2, -3.5, 0]) rotate([0, 90, 0]) cylinder(r=0.5, h=4);
     }
     translate([1., 0, 1]) cube([0.4, 0.4, 0.4], center=true);
}

module detection(){
     translate([0, 0, -17.65]) union() {
          camera_stand();
          camera();
          translate([0, 0, 6.05]) lens_75_stand();
     }
}

/* difference(){ */
/*      union(){ */
/*           color(c=[0.2, 0.0, 0.1, 0.3]) {detection();} */
/*           color(c=[0.8, 0.0, 0.1, 0.3]) {lens_75();} */
/*      } */
/*      translate([-30, 0, 0]) cube([60, 60, 60], center=true); */
/* } */

difference(){
     union(){

color([0.1, 0.1, 0.6]) {translate([0, 0, 0.1]) leds_sequins();}
sequins_stand();
color(c=[0.4, 0.8, 0.4]) {detection();}

color(c=[0.8, 0.1, 0.1]) {lens_75();}
translate([0, 0, 2.1]) ring(1, 22.9, phi_ext);

     }
     translate([-30, 0, 0]) cube([60, 60, 60], center=true);
}

//detection();

use <dummies.scad>;
$fn = 36;
phi_ext = 26;

module camera(){
// http://www.arducam.com/spy-camera-raspberry-pi/
// Not the same cam exactly, but view angle is given
// as 54x41°, i.e 0.94 rad
     translate([0, 0, 2]) cylinder(d=7.4, h=3);
     translate([0, 1.5, 0.5]) cube([8.5, 11.3, 3], center=true);
     translate([0, 7, -2.2])
          union(){
          rotate([0, 0, -90]) translate([0, 3.75, 0]) rotate([90, 0, 0])
               difference(){
               cylinder(d=4, h=7.5);
               translate([0, 0, -1]) cylinder(d=3.6, h=9, $fn=36);
               translate([0, -5, -1]) cube(10);
          }
          translate([-3.75, -12, -2]) cube([7.5, 12, 0.2], center=false);
     }
}

module base_plate(){
     difference(){
          cylinder(d=phi_ext, h=6);
          for (i=[0:5])
               rotate([0, 0, 60*i]) translate([-phi_ext/2+1, 0, 0.9])
                    union(){
                    translate([0, -3.5, -1]) cylinder(h=10, d=3);
                    translate([0, 3.5, -1]) cylinder(h=10, d=3);
               }
     }
}

module camera_stand(){
     difference(){
          base_plate();
          translate([0, 1.5, 0.5]) cube([8.6, 11.6, 3], center=true);
          translate([0, 0, -2]) cylinder(d=7.8, h=12);
     }
}

module lens_75(){
     translate([0, 0, -5.2]) union(){
          translate([0, 0, 0]) ring(3.2, 4.4, 8.4);
          translate([0, 0, -3.2]) ring(3.2, 7.2, 9.2);
     }
}

module lens_75_stand(){
     difference(){
          base_plate();
          translate([0, 0, -2]) cylinder(d=9.3, h=5.2);
          translate([0, 0, -2]) cylinder(d=8.1, h=12);
     }
}

module sequins_stand(){
     difference(){
          translate([0, 0, -5])  base_plate();
          for (i=[0:5])
               rotate([0, 0, 60*i]) translate([-10, 0, -1])
                    union(){
                    cube([2.2, 9.2, 4.2], center=true);
                    translate([2, 0, 0.1]) cube([4, 6, 4.1], center=true);
               }
          translate([0, 0, -8]) cylinder(d=16, h=12);

     }
}

module leds_sequins(){
     for (i=[0:5])
          rotate([0, 0, 60*i]) translate([-10, 0, -1]) sequin();
}

//
module sequin(){
     difference() {
          minkowski(){
               cube([1, 7, 2], center=true);
               rotate([0, 90, 0]) cylinder(r=1, h=1, center=true);
          }
          translate([-2, 3.5, 0]) rotate([0, 90, 0]) cylinder(r=0.5, h=4);
          translate([-2, -3.5, 0]) rotate([0, 90, 0]) cylinder(r=0.5, h=4);
     }
     translate([1., 0, 1]) cube([0.4, 0.4, 0.4], center=true);
}

module detection(){
     translate([0, 0, -17.65]) union() {
          camera_stand();
          camera();
          translate([0, 0, 6.05]) lens_75_stand();
     }
}

/* difference(){ */
/*      union(){ */
/*           color(c=[0.2, 0.0, 0.1, 0.3]) {detection();} */
/*           color(c=[0.8, 0.0, 0.1, 0.3]) {lens_75();} */
/*      } */
/*      translate([-30, 0, 0]) cube([60, 60, 60], center=true); */
/* } */

color([0.1, 0.1, 0.6]) {translate([0, 0, 0.1]) leds_sequins();}
sequins_stand();
color(c=[0.4, 0.8, 0.4]) {detection();}

color(c=[0.8, 0.1, 0.1]) {lens_75();}
translate([0, 0, 2.1]) ring(1, 20, phi_ext);

//detection();


nine has tub for breadboard.

nine has tub for breadboard.

// OpenSCAD for a "mezzanine" extension for a Turtlebot3 burger
//           It includes a well for a breadboard and
//           rivet holes for a battery.
thickness = 4;
wide_y  = 36;    // The length of the wide rectangular portion
fillet_side= 16;    // End of flare to narrow
full_y  = 86;    // Greatest extent of the plate
wide_x  = 110;   // 1/2 width of the "wings"
narrow_x= 45;    // 1/2 width of the battery holder
breadboard_x = 52;  // Chopped
breadboard_y = 26;  // Chopped
breadboard_z = 10;
pillar_x     = 24;    // Center-line to center of pillar
pillar_y     = 30;    // Baseline to center of pillar
rim          = 3;     // Width of rim
rivet1_x     = 54;
rivet2_x     = 60;
rivet_y      = 8;
rivet_radius = 2.5;   // Hole radius for rivet attachment
round_radius = 2;     // Radius of the corner arcs

// This is the holder for the chopped off breadboard.
// rwidth is the rim width
module tub(z,rwidth) {
    linear_extrude(height=z,center=false,convexity=10) {
        difference() {
            square([breadboard_x+2*rwidth,breadboard_y+2*rwidth],true);
            square([breadboard_x,breadboard_y],true);
        }
    }
}
// Subtract this from the base platform
// These are the posts
module post_holes(z) {
    for(i=[[pillar_x,-pillar_y],[-pillar_x,-pillar_y]]) {
        translate(i)
        cylinder(r=5,h=z,$fn=6);
    }
}

// These are the various holes for rivets
// z - thickness
module rivet_holes(z) {
    for(i=[[rivet1_x,-rivet_y],[rivet2_x,-rivet_y],
           [-rivet1_x,-rivet_y],[-rivet2_x,-rivet_y]]) {
        translate(i)
        cylinder(r=rivet_radius,h=z);
    }
}
// 0,0 is upper left corner
module fillet(radius,angle) {
    rotate(angle,[0,0,1])
    difference() {
        square(radius,false);
        translate([radius,radius,0])
        circle(r=radius);
    }

}
// This is the basic plate. The baseline is y=0 along the GPIO pins.
// This object cannot be translated once created.
// y is negative towards us. Couldn't make a single hull work.
module base(z) {
    $fn=100;
    linear_extrude(height=z,center=false,convexity=10) {
        union() {
        hull() {
            // place 4 circles in the corners, with the rounding radius
            translate([-wide_x+round_radius/2, round_radius/2, 0])
            circle(r=round_radius);

            translate([wide_x-round_radius/2, round_radius/2, 0])
            circle(r=round_radius);

            translate([wide_x-round_radius/2, -wide_y+round_radius/2, 0])
            circle(r=round_radius);

            translate([-wide_x+round_radius/2, -wide_y+round_radius/2, 0])
            circle(r=round_radius);
            }
        };
        hull() {
            translate([narrow_x-round_radius/2, -wide_y+round_radius/2, 0])
            circle(r=round_radius);

            translate([narrow_x-round_radius/2, -full_y+round_radius/2, 0])
            circle(r=round_radius);

            translate([-narrow_x+round_radius/2, -full_y+round_radius/2, 0])
            circle(r=round_radius);

            translate([-narrow_x+round_radius/2, -wide_y+round_radius/2, 0])
            circle(r=round_radius);
        }
        translate([narrow_x,-wide_y,0])
        fillet(fillet_side,270);
        translate([-narrow_x,-wide_y,0])
        fillet(fillet_side,180);
    }
}

// This is the basic plate less a rim width all around. This is meant to
// be subtracted from the standard plate.
// There should be no rim where the hulls join
module base_cutout(z,rwidth) {
    $fn=100;
    linear_extrude(height=z,center=false,convexity=10) {
        union() {
        hull() {
            translate([-wide_x+round_radius/2+rwidth, round_radius/2-rwidth, 0])
            circle(r=round_radius);

            translate([wide_x-round_radius/2-rwidth, round_radius/2-rwidth, 0])
            circle(r=round_radius);

            translate([wide_x-round_radius/2-rwidth, -wide_y+round_radius/2+rwidth, 0])
            circle(r=round_radius);

            translate([-wide_x+round_radius/2+rwidth, -wide_y+round_radius/2+rwidth, 0])
            circle(r=round_radius);
            }
        };
        hull() {
            translate([narrow_x-round_radius/2-rwidth, -wide_y+round_radius/2, 0])
            circle(r=round_radius);

            translate([narrow_x-round_radius/2-rwidth, -full_y+round_radius/2+rwidth, 0])
            circle(r=round_radius);

            translate([-narrow_x+round_radius/2+rwidth,-full_y+round_radius/2+rwidth, 0])
            circle(r=round_radius);

            translate([-narrow_x+round_radius/2+rwidth, -wide_y+round_radius/2, 0])
            circle(r=round_radius);
        }
        translate([narrow_x-rwidth,-wide_y+rwidth,0])
        fillet(fillet_side,270);
        translate([-narrow_x+rwidth,-wide_y+rwidth,0])
        fillet(fillet_side,180);
    }
}

// --------------------- Final Assembly ----------------------
// Baseplate
translate([0,0,-thickness/2])
difference() {
    base(thickness);
    rivet_holes(thickness);
    post_holes(thickness);
}
translate([0,0,thickness/2])
difference() {
        base(thickness);
        base_cutout(thickness,rim);
 }
 translate([0,-breadboard_y/2,thickness/2])
 tub(thickness,rim);

// OpenSCAD for a "mezzanine" extension for a Turtlebot3 burger
//           It includes a well for a breadboard and
//           rivet holes for a battery.
thickness = 4;
wide_y  = 26;    // The length of the wide rectangular portion
fillet_side= 16;    // End of flare to narrow
full_y  = 86;    // Greatest extent of the plate
wide_x  = 110;   // 1/2 width of the "wings"
narrow_x= 45;    // 1/2 width of the battery holder
breadboard_x = 52;  // Chopped
breadboard_y = 26;  // Chopped
breadboard_z = 10;
pillar_x     = 24;    // Center-line to center of pillar
pillar_y     = 30;    // Baseline to center of pillar
rim          = 3;     // Width of rim
rivet1_x     = 54;
rivet2_x     = 60;
rivet_y      = 8;
rivet_radius = 2.5;   // Hole radius for rivet attachment
round_radius = 2;     // Radius of the corner arcs

// 0,0 is upper left corner
module fillet(radius,angle) {
    rotate(angle,[0,0,1])
    difference() {
        square(radius,false);
        translate([radius,radius,0])
        circle(r=radius);
    }

}
// This is the basic plate. The baseline is y=0 along the GPIO pins.
// This object cannot be translated once created.
// y is negative towards us. Couldn't make a single hull work.
module base(z) {
    $fn=100;
    linear_extrude(height=z,center=false,convexity=10) {
        union() {
        hull() {
            // place 4 circles in the corners, with the rounding radius
            translate([-wide_x+round_radius/2, round_radius/2, 0])
            circle(r=round_radius);

            translate([wide_x-round_radius/2, round_radius/2, 0])
            circle(r=round_radius);

            translate([wide_x-round_radius/2, -wide_y+round_radius/2, 0])
            circle(r=round_radius);

            translate([-wide_x+round_radius/2, -wide_y+round_radius/2, 0])
            circle(r=round_radius);
            }
        };
        hull() {
            translate([narrow_x-round_radius/2, -wide_y+round_radius/2, 0])
            circle(r=round_radius);

            translate([narrow_x-round_radius/2, -full_y+round_radius/2, 0])
            circle(r=round_radius);

            translate([-narrow_x+round_radius/2, -full_y+round_radius/2, 0])
            circle(r=round_radius);

            translate([-narrow_x+round_radius/2, -wide_y+round_radius/2, 0])
            circle(r=round_radius);
        }
        translate([narrow_x,-wide_y,0])
        fillet(fillet_side,270);
        translate([-narrow_x,-wide_y,0])
        fillet(fillet_side,180);
    }
}

// This is the basic plate less a rim width all around. This is meant to
// be subtracted from the standard plate.
// There should be no rim where the hulls join
module base_cutout(z,rwidth) {
    $fn=100;
    linear_extrude(height=z,center=false,convexity=10) {
        union() {
        hull() {
            translate([-wide_x+round_radius/2+rwidth, round_radius/2-rwidth, 0])
            circle(r=round_radius);

            translate([wide_x-round_radius/2-rwidth, round_radius/2-rwidth, 0])
            circle(r=round_radius);

            translate([wide_x-round_radius/2-rwidth, -wide_y+round_radius/2+rwidth, 0])
            circle(r=round_radius);

            translate([-wide_x+round_radius/2+rwidth, -wide_y+round_radius/2+rwidth, 0])
            circle(r=round_radius);
            }
        };
        hull() {
            translate([narrow_x-round_radius/2-rwidth, -wide_y+round_radius/2, 0])
            circle(r=round_radius);

            translate([narrow_x-round_radius/2-rwidth, -full_y+round_radius/2+rwidth, 0])
            circle(r=round_radius);

            translate([-narrow_x+round_radius/2+rwidth,-full_y+round_radius/2+rwidth, 0])
            circle(r=round_radius);

            translate([-narrow_x+round_radius/2+rwidth, -wide_y+round_radius/2, 0])
            circle(r=round_radius);
        }
        translate([narrow_x-rwidth,-wide_y+rwidth,0])
        fillet(fillet_side,270);
        translate([-narrow_x+rwidth,-wide_y+rwidth,0])
        fillet(fillet_side,180);
    }
}

// --------------------- Final Assembly ----------------------
// Baseplate
translate([0,0,-thickness/2])
base(thickness);
translate([0,0,thickness/2])
difference() {
        base(thickness);
        base_cutout(thickness,rim);
  }


Fixed type in comment.

Fixed type in comment.

//See:
// http://edutechwiki.unige.ch/en/OpenScad_beginners_tutorial
// https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/

// Global variables.
overcut = 0.1;  // Overcut for solid difference(), to assure complete holes.
overlap = 0.1;  // Intersection for solid union() to avoid the manifold problem.

include <misc_parts.scad>;
include <boards.scad>;
include <rounded_cube.scad>;

// Box internal size.
x_size  = 115.0;
y_size  = 144.0;
z_size  =  29.0;
thick   =   2.2;
chamfer =  13.0;

// Mounting screw holes.
screw_hole1_y = 24;
screw_hole2_y = y_size - 26;
screw_diam    = 3.6;

// Position and size of push button hole.
button_x = x_size;
button_y = 64;
button_z = 16.0;
button_d = 6.4;

// Position and size of power socket hole.
psocket_x = x_size / 2;
psocket_z = 7;
psocket_d = 8.2;

// Position and size for temperature sensor grommet.
tsensor_x  = -thick - 1;
tsensor_y  = 78;
tsensor_z  = 13;
tsensor_h  = thick + 9;
tsensor_d1 = 9.0;
tsensor_d2 = 5.5;

// Positon and size for boiler cable grommet (cable is 5.5 x 3.5 mm).
bcable_x  = 19;
bcable_y  = -thick - 1;
bcable_z  = 9.5;
bcable_h  = thick + 9;
bcable_t  = 1.7; // Grommet thickness
bcable_d1 = 5.4; // Rectangular hole X
bcable_d2 = 3.4; // Rectangular hole Y
bcable_r  = 1.5; // Chamfer radius

//-------------------------------------------------------------------------
// Housing for a rubber foot.
//-------------------------------------------------------------------------
module rubber_foot(d1, d2, h) {
    $fn = 48;
    difference() {
        cylinder(r=(d1 / 2), h=h);
        translate([0, 0, -overcut]) cylinder(r=(d2 / 2), h=(h + overcut * 2));
    }
}

//-------------------------------------------------------------------------
// Housings for rubber feet (grows towards negative z axis).
//-------------------------------------------------------------------------
module box_feet(x, y, margin) {
    d1 = 11.0;
    d2 =  8.2;
    h  =  0.8;
    translate([margin,     margin,     -h]) rubber_foot(d1, d2, h + overlap);
    translate([x - margin, margin,     -h]) rubber_foot(d1, d2, h + overlap);
    translate([x - margin, y - margin, -h]) rubber_foot(d1, d2, h + overlap);
    translate([margin,     y - margin, -h]) rubber_foot(d1, d2, h + overlap);
}

//-------------------------------------------------------------------------
// Flange for screw hole.
//-------------------------------------------------------------------------
module screw_flange(r, t) {
    $fn = 60;
    screw_diameter = 2.2;
    r1 = r * 1.1;
    difference() {
        intersection() {
            cylinder(r=r1, h=t);
            union() {
                translate([r, r, 0]) cylinder(r=r, h=t);
                translate([r, 0, 0]) cube([r, r, t]);
                translate([0, r, 0]) cube([r, r, t]);}}
        translate([r1 / 2, r1 / 2, -overcut]) cylinder(r=(screw_diameter * 0.75 / 2), h=(t + overcut * 2), $fn=24);
    }
}

//-------------------------------------------------------------------------
// Add a flange to the rounded_box() module.
//-------------------------------------------------------------------------
module rounded_box_flange(x, y, z, r) {
    w = 1.5;
    difference() {
        rounded_cube(x_size, y_size, z, r);
        translate([w, w, -overcut])
            rounded_cube(x_size - w * 2, y_size - w * 2, z + overcut * 2, r);
    }
    translate([0, 0, 0]) rotate(a=0 ,  v=[0, 0, 1]) screw_flange(r, z);
    translate([x, 0, 0]) rotate(a=90,  v=[0, 0, 1]) screw_flange(r, z);
    translate([x, y, 0]) rotate(a=180, v=[0, 0, 1]) screw_flange(r, z);
    translate([0, y, 0]) rotate(a=270, v=[0, 0, 1]) screw_flange(r, z);
}

//-------------------------------------------------------------------------
// Round cable grommet.
//-------------------------------------------------------------------------
module cable_grommet(h, d1, d2) {
    $fn = 32;
    cut_width = 3;
    difference() {
        union() {
            cylinder(r=(d1 / 2), h=h);
            translate([0, 0, h - 2.4]) cylinder(r=((d1 + 1.0) / 2), h=2.4);
        }
        translate([0, 0, -overcut]) cylinder(r=(d2 / 2), h=(h + 2 * overcut));
        translate([(d2 / 4), -(d1 / 2), h - (cut_width + 2.5)])
            cube([(d1 / 2), d1, cut_width]);
    }
}

//-------------------------------------------------------------------------
// Rectangular (with chamfer) cable grommet.
// h = height, x, y = hole inner size, r = chamfer radius, t = thickness
//-------------------------------------------------------------------------
module cable_grommet_rect(h, x, y, r, t) {
    cut_width = 3;
    difference() {
        union() {
            translate([-x / 2, -y / 2, 0]) rounded_cube_border(x, y, h, r, t);
            translate([-x / 2, -y / 2, h - 2.4]) rounded_cube_border(x, y, 2.4, r, t + 0.5);
        }
        translate([-(x / 2) - t - overcut, 0, h - (cut_width + 2.5)])
            cube([x + (t + overcut) * 2, y / 2 + t + overcut, cut_width]);
    }
}

//-------------------------------------------------------------------------
// Drill a screw hole with cuts for horizontal and vertical wall mount.
// Screw body diameter is d, head diameter will be d * 2.
//-------------------------------------------------------------------------
module screw_hole(d, depth) {
    $fn = 32;
    hole_depth = depth + overcut * 2;
    hole_bottom = -(depth + overcut);
    cut_length = d * 2;
    union() {
        translate([0, 0, hole_bottom])          cylinder(r=d, h=hole_depth);
        translate([-(d / 2), 0, hole_bottom])   cube([d, cut_length, hole_depth]);
        translate([0, -(d / 2), hole_bottom])   cube([cut_length, d, hole_depth]);
        translate([0, cut_length, hole_bottom]) cylinder(r=(d / 2), h=hole_depth);
        translate([cut_length, 0, hole_bottom]) cylinder(r=(d / 2), h=hole_depth);
    }
}

//-------------------------------------------------------------------------
// Build a cap to place over a screw hole.
// Screw body diameter = d
// Screw head diameter = d * 2
// Screw head height   = d * 0.6
//-------------------------------------------------------------------------
module screw_hole_cap(d, thick) {
    $fn = 36;
    r2 = 1.4142;
    pin_radius = thick * 1.3;
    pin_heigh = (d * 0.6) + (overlap * 2);
    pin_base = -overlap;
    offset = (((pin_radius * r2) - pin_radius) / r2) + ((pin_radius * 2) / r2) + (d / r2);
    size1 = (offset + overlap) * 2;
    size2 = size1 + d * 2;
    translate([-(size1 / 2), -(size1 / 2), 0]) {
        union() {
            translate([0, 0, d * 0.6]) rounded_cube(size1, size2, thick, pin_radius);
            translate([0, 0, d * 0.6]) rounded_cube(size2, size1, thick, pin_radius);
            translate([pin_radius, pin_radius, pin_base])                 cylinder(r=pin_radius, h=pin_heigh);
            translate([size2 - pin_radius, pin_radius, pin_base])         cylinder(r=pin_radius, h=pin_heigh);
            translate([size2 - pin_radius, size1 - pin_radius, pin_base]) cylinder(r=pin_radius, h=pin_heigh);
            translate([size1 - pin_radius, size2 - pin_radius, pin_base]) cylinder(r=pin_radius, h=pin_heigh);
            translate([pin_radius, size2 - pin_radius, pin_base])         cylinder(r=pin_radius, h=pin_heigh);
        }
    }
}

//-------------------------------------------------------------------------
// Make a box with the requested internal size and rounded corners.
// The origin is the lower-left internal corner.
//-------------------------------------------------------------------------
module rounded_box(x_size, y_size, z_size, chamfer, thick) {
    cover_thick = 2;
    union() {
        translate([-overlap, -overlap, -thick])
            rounded_cube(x_size + overlap * 2, y_size + overlap * 2, thick, chamfer + overlap);
        translate([0, 0, -thick])
            rounded_cube_border(x_size, y_size, z_size + thick, chamfer, thick);
        translate([-overlap, -overlap, z_size - cover_thick - thick])
            rounded_box_flange(x_size + overlap * 2, y_size + overlap * 2, thick, chamfer + overlap);
        translate([0, 0, -thick])
            box_feet(x_size, y_size, 10);
        // Draw the box cover, for dimension testing.
        //translate([0, 0, z_size - cover_thick])
        //    %rounded_cube(x_size, y_size, cover_thick, chamfer);
    }
}

//-------------------------------------------------------------------------
// Make a box with rounded corners, drill all the required holes.
//-------------------------------------------------------------------------
module rounded_box_holes(x_size, y_size, z_size, chamfer, thick) {

    holes_diam = 3.5;

    // Boiler cable grommet.
    translate([bcable_x, bcable_y, bcable_z])
        rotate(a=180, v=[0, 1, 0])
            rotate(a=270, v=[1, 0, 0])
                cable_grommet_rect(bcable_h, bcable_d1, bcable_d2, bcable_r, bcable_t);

    // Temperature sensor cable grommet.
    translate([tsensor_x, tsensor_y, tsensor_z])
        rotate(a=90, v=[1, 0, 0])
            rotate(a=90, v=[0, 1, 0])
                cable_grommet(tsensor_h, tsensor_d1, tsensor_d2);

    difference() {
        rounded_box(x_size, y_size, z_size, chamfer, thick);

        // Bottom venting holes.
        translate([x_size / 2, 0, z_size / 2])
            rotate(a=90, v=[1, 0, 0]) vent_holes(12, 3, holes_diam, thick);

        // Top venting holes.
        translate([x_size / 2, y_size + thick, z_size / 2])
            rotate(a=90, v=[1, 0, 0]) vent_holes(11, 3, holes_diam, thick);

        // Backplane venting holes.
        translate([83, 88, -thick]) vent_holes(8, 6, holes_diam, thick);
        translate([25, 38, -thick]) vent_holes(5, 4, holes_diam, thick);

        // Mounting screw holes.
        translate([x_size / 2, screw_hole1_y, 0]) rotate(a=90, v=[0, 0, 1]) screw_hole(screw_diam, thick);
        translate([x_size / 2, screw_hole2_y, 0]) rotate(a=90, v=[0, 0, 1]) screw_hole(screw_diam, thick);

        // Temperature sensor hole.
        translate([-(thick + overcut), tsensor_y, tsensor_z])
            rotate(a=90, v=[0, 1, 0]) cylinder(r=(tsensor_d2 / 2), h=(thick + overcut * 2), $fn=24);

        // Push-button hole.
        translate([button_x - overcut, button_y, button_z])
            rotate(a=90, v=[0, 1, 0]) cylinder(r=(button_d / 2), h=(thick + overcut * 2), $fn=24);

        // Power socket hole.
        translate([psocket_x, overcut, psocket_z])
            rotate(a=90, v=[1, 0, 0]) cylinder(r=(psocket_d / 2), h=(thick + overcut * 2), $fn=24);

        // Boiler cable hole.
        translate([bcable_x, bcable_y - overcut, bcable_z])
            rotate(a=270, v=[1, 0, 0]) rounded_cube_centered(bcable_d1, bcable_d2, bcable_h + overcut * 2, bcable_r);

    }

    // Reinforce for power socket hole.
    difference() {
        translate([psocket_x, 0, psocket_z]) rotate(a=90, v=[1, 0, 0]) cylinder(r=(psocket_d / 2) + 2.5, h=thick);
        translate([psocket_x, overcut, psocket_z])
            rotate(a=90, v=[1, 0, 0]) cylinder(r=(psocket_d / 2), h=(thick + overcut * 2), $fn=24);
    }

    // Reinforce for boiler cable hole.
    difference() {
        translate([bcable_x, 0, bcable_z])
            rotate(a=90, v=[1, 0, 0]) rounded_cube_centered(bcable_d1 + 5.5, bcable_d2 + 5.5, thick, 3);
        translate([bcable_x, overcut, bcable_z])
            rotate(a=90, v=[1, 0, 0]) rounded_cube_centered(bcable_d1, bcable_d2, (thick + overcut * 2), bcable_r);
    }

    // Mounting screws holes.
    translate([x_size / 2, screw_hole1_y, 0]) rotate(a=90, v=[0, 0, 1]) #screw_hole_cap(screw_diam, 1.7);
    translate([x_size / 2, screw_hole2_y, 0]) rotate(a=90, v=[0, 0, 1]) #screw_hole_cap(screw_diam, 1.7);
}

//-------------------------------------------------------------------------
// Drill a grid of rows x columns vent holes. Each hole has the
// specified diameter and depth, the grid is centered into the origin.
//-------------------------------------------------------------------------
module vent_holes(x, y, diameter, depth) {
    $fn = 6; // 18 = rounded holes, 6 = hexagonal
    step = diameter * 2;
    radius = diameter / 1.8;  // Divide by 2.0 if rounded holes, 1.8 if hexagonal.
    offset_x = (step * (x - 1)) / 2;
    offset_y = (step * (y - 1)) / 2;
    for (i = [1:x]) {
        for (j = [1:y]) {
            translate([(i - 1) * step - offset_x, (j -1) * step - offset_y, -overcut])
              cylinder(r=radius, h=(depth + overcut * 2));
        }
    }
    for (i = [1:x-1]) {
        for (j = [1:y-1]) {
            translate([(i - 1) * step - offset_x + step / 2, (j -1) * step - offset_y + step / 2, -overcut])
                cylinder(r=radius, h=(depth + overcut * 2));
        }
    }
}

//-------------------------------------------------------------------------
// Screw stub: d1 is the outer diameter, d2 is the screw diameter.
// The stub height must be grather than the depth of the hole.
//-------------------------------------------------------------------------
module stub(d1, height, d2, hole_depth) {
    $fn = 36;
    // The hole for a self-tapping screw is narrower than the screw.
    hole_diameter = d2 * 0.75;
    difference() {
        translate([0, 0, -overlap]) {
            union() {
                cylinder(r=(d1 / 2), h=(height + overlap));
                cylinder(r1=(d1 * 0.7), r2=(d1 / 2), h=(4 + overlap));
            }
        }
        translate([0, 0, height - hole_depth])
            cylinder(r=(hole_diameter / 2), h=(hole_depth + overcut));
    }
}

//-------------------------------------------------------------------------
// Screw stubs for relay board (SainSmart like manufacturer).
//-------------------------------------------------------------------------
module stubs_2relays_sainsmart(height) {
    diameter = 7;
    screw_diameter = 2.2;
    hole_depth = 6;
    // Offset of first (lower left) hole from edge.
    translate([2.75, 2.75, 0]) {
        translate([ 0,      0, 0]) stub(diameter, height, screw_diameter, hole_depth);
        translate([33.5,    0, 0]) stub(diameter, height, screw_diameter, hole_depth);
        translate([0,    45.5, 0]) stub(diameter, height, screw_diameter, hole_depth);
        translate([33.5, 45.5, 0]) stub(diameter, height, screw_diameter, hole_depth);
    }
}

//-------------------------------------------------------------------------
// Screw stubs for relay board (Keyes manufacturer).
//-------------------------------------------------------------------------
module stubs_2relays_keyes(height) {
    diameter = 7;
    screw_diameter = 2.2;
    hole_depth = 6;
    // Offset of first (lower left) hole from edge.
    translate([3.5, 9, 0]) {
        translate([ 0,  0, 0]) stub(diameter, height, screw_diameter, hole_depth);
        translate([38,  0, 0]) stub(diameter, height, screw_diameter, hole_depth);
        translate([0,  40, 0]) stub(diameter, height, screw_diameter, hole_depth);
        translate([38, 40, 0]) stub(diameter, height, screw_diameter, hole_depth);
    }
}

//-------------------------------------------------------------------------
// Screw stubs for PCD8544 LCD (Nokia 5110/3310), blue PCB model.
//-------------------------------------------------------------------------
module stubs_pcd8544_blue(height) {
    diameter = 6.5;
    screw_diameter = 2.2;
    hole_depth = 6;
    // Offset of first (lower left) hole from edge.
    translate([4.25, 2.25, 0]) {
        translate([ 0,    0, 0]) stub(diameter, height, screw_diameter, hole_depth);
        translate([34.5,  0, 0]) stub(diameter, height, screw_diameter, hole_depth);
        translate([0,    41, 0]) stub(diameter, height, screw_diameter, hole_depth);
        translate([34.5, 41, 0]) stub(diameter, height, screw_diameter, hole_depth);
    }
}

//-------------------------------------------------------------------------
// Screw stubs for PCD8544 LCD (Nokia 5110/3310), red PCB model.
//-------------------------------------------------------------------------
module stubs_pcd8544_red(height) {
    diameter = 6.0;
    screw_diameter = 2.2;
    hole_depth = 6;
    // Offset of first (lower left) hole from edge.
    translate([1.75, 2.0, 0]) {
        translate([ 0,  0, 0]) stub(diameter, height, screw_diameter, hole_depth);
        translate([40,  0, 0]) stub(diameter, height, screw_diameter, hole_depth);
        translate([ 0, 39, 0]) stub(diameter, height, screw_diameter, hole_depth);
        translate([40, 39, 0]) stub(diameter, height, screw_diameter, hole_depth);
    }
}

//-------------------------------------------------------------------------
// Screw stubs for Raspberry Pi Model B v.2.
//-------------------------------------------------------------------------
module stubs_raspberrypi_model_b_v2(height) {
    screw_diameter = 2.2;
    hole_depth = 6;
    translate([38, 25.5, 0]) {
        translate([    0,    0, 0]) stub(6.5, height, screw_diameter, hole_depth);
        translate([-25.5, 54.5, 0]) stub(6.5, height, screw_diameter, hole_depth);
    }
}

//-------------------------------------------------------------------------
// Main procedure.
//-------------------------------------------------------------------------
translate([-(x_size / 2), -(y_size/2), 0]) {
    rounded_box_holes(x_size, y_size, z_size, chamfer, thick);
    translate([ 5, 12,  0.0]) stubs_2relays_sainsmart(5.0);
    translate([ 8, 90,  0.0]) stubs_pcd8544_red(20.5); // Non diminuire Y sennò tocca il coprivite!
    translate([55, 37,  0.0]) stubs_raspberrypi_model_b_v2(5.0);
    //translate([55, 37 , 5.0]) board_raspberrypi_model_b_v2();
    //translate([ 8, 90, 20.5]) board_pcd8544_red();
    //translate([ 5, 12,  5.0]) board_2relays_sainsmart();
    //translate([button_x, button_y, button_z]) rotate(a=90, v=[0, 1, 0]) push_button();
    //translate([psocket_x, -thick, psocket_z]) rotate(a=90, v=[1, 0, 0]) coax_power_jack();
}

include <RigacciOrg.scad>;
translate([-x_size / 2 - thick + overlap, -29, 13])
    rotate(a=270, v=[0,0,1]) rotate(a=90, v=[1,0,0]) {
        //#cube([55, 12.54, 0.5], center=true);
        RigacciOrg(0.5);
    }

include <ccbysa.scad>;
translate([-x_size / 2 - thick + overlap, 34, 13])
    rotate(a=270, v=[0,0,1]) rotate(a=90, v=[1,0,0]) {
        //#cube([35.60, 12.54, 0.5], center=true);
        ccbysa(0.5);
    }

//See:
// http://edutechwiki.unige.ch/en/OpenScad_beginners_tutorial
// https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/

// Global variables.
overcut = 0.1;  // Overcut for solid difference(), to assure complete holes.
overlap = 0.1;  // Intersection for solid union() to avoid the manifold problem.

include <misc_parts.scad>;
include <boards.scad>;
include <rounded_cube.scad>;

// Box internal size.
x_size  = 115.0;
y_size  = 144.0;
z_size  =  29.0;
thick   =   2.2;
chamfer =  13.0;

// Mounting screw holes.
screw_hole1_y = 24;
screw_hole2_y = y_size - 26;
screw_diam    = 3.6;

// Position and size of push button hole.
button_x = x_size;
button_y = 64;
button_z = 16.0;
button_d = 6.4;

// Position and size of power socket hole.
psocket_x = x_size / 2;
psocket_z = 7;
psocket_d = 8.2;

// Position and size for temperature sensor grommet.
tsensor_x  = -thick - 1;
tsensor_y  = 78;
tsensor_z  = 13;
tsensor_h  = thick + 9;
tsensor_d1 = 9.0;
tsensor_d2 = 5.5;

// Positon and size for boiler cable grommet (cable is 5.5 x 3.5 mm).
bcable_x  = 19;
bcable_y  = -thick - 1;
bcable_z  = 9.5;
bcable_h  = thick + 9;
bcable_t  = 1.7; // Grommet thickness
bcable_d1 = 5.4; // Rectangular hole X
bcable_d2 = 3.4; // Rectangular hole Y
bcable_r  = 1.5; // Chamfer radius

//-------------------------------------------------------------------------
// Housing for a rubber foot.
//-------------------------------------------------------------------------
module rubber_foot(d1, d2, h) {
    $fn = 48;
    difference() {
        cylinder(r=(d1 / 2), h=h);
        translate([0, 0, -overcut]) cylinder(r=(d2 / 2), h=(h + overcut * 2));
    }
}

//-------------------------------------------------------------------------
// Housings for rubber feet (grows towards negative z axis).
//-------------------------------------------------------------------------
module box_feet(x, y, margin) {
    d1 = 11.0;
    d2 =  8.2;
    h  =  0.8;
    translate([margin,     margin,     -h]) rubber_foot(d1, d2, h + overlap);
    translate([x - margin, margin,     -h]) rubber_foot(d1, d2, h + overlap);
    translate([x - margin, y - margin, -h]) rubber_foot(d1, d2, h + overlap);
    translate([margin,     y - margin, -h]) rubber_foot(d1, d2, h + overlap);
}

//-------------------------------------------------------------------------
// Flange for screw hole.
//-------------------------------------------------------------------------
module screw_flange(r, t) {
    $fn = 60;
    screw_diameter = 2.2;
    r1 = r * 1.1;
    difference() {
        intersection() {
            cylinder(r=r1, h=t);
            union() {
                translate([r, r, 0]) cylinder(r=r, h=t);
                translate([r, 0, 0]) cube([r, r, t]);
                translate([0, r, 0]) cube([r, r, t]);}}
        translate([r1 / 2, r1 / 2, -overcut]) cylinder(r=(screw_diameter * 0.75 / 2), h=(t + overcut * 2), $fn=24);
    }
}

//-------------------------------------------------------------------------
// Add a flange to the rounded_box() module.
//-------------------------------------------------------------------------
module rounded_box_flange(x, y, z, r) {
    w = 1.5;
    difference() {
        rounded_cube(x_size, y_size, z, r);
        translate([w, w, -overcut])
            rounded_cube(x_size - w * 2, y_size - w * 2, z + overcut * 2, r);
    }
    translate([0, 0, 0]) rotate(a=0 ,  v=[0, 0, 1]) screw_flange(r, z);
    translate([x, 0, 0]) rotate(a=90,  v=[0, 0, 1]) screw_flange(r, z);
    translate([x, y, 0]) rotate(a=180, v=[0, 0, 1]) screw_flange(r, z);
    translate([0, y, 0]) rotate(a=270, v=[0, 0, 1]) screw_flange(r, z);
}

//-------------------------------------------------------------------------
// Round cable grommet.
//-------------------------------------------------------------------------
module cable_grommet(h, d1, d2) {
    $fn = 32;
    cut_width = 3;
    difference() {
        union() {
            cylinder(r=(d1 / 2), h=h);
            translate([0, 0, h - 2.4]) cylinder(r=((d1 + 1.0) / 2), h=2.4);
        }
        translate([0, 0, -overcut]) cylinder(r=(d2 / 2), h=(h + 2 * overcut));
        translate([(d2 / 4), -(d1 / 2), h - (cut_width + 2.5)])
            cube([(d1 / 2), d1, cut_width]);
    }
}

//-------------------------------------------------------------------------
// Rectangular (with chamfer) cable grommet.
// h = height, x, y = hole inner size, r = chamfer radius, t = thickness
//-------------------------------------------------------------------------
module cable_grommet_rect(h, x, y, r, t) {
    cut_width = 3;
    difference() {
        union() {
            translate([-x / 2, -y / 2, 0]) rounded_cube_border(x, y, h, r, t);
            translate([-x / 2, -y / 2, h - 2.4]) rounded_cube_border(x, y, 2.4, r, t + 0.5);
        }
        translate([-(x / 2) - t - overcut, 0, h - (cut_width + 2.5)])
            cube([x + (t + overcut) * 2, y / 2 + t + overcut, cut_width]);
    }
}

//-------------------------------------------------------------------------
// Drill a screw hole with cuts for horizontal and vertical wall mount.
// Screw body diameter is d, head diameter will be d * 2.
//-------------------------------------------------------------------------
module screw_hole(d, depth) {
    $fn = 32;
    hole_depth = depth + overcut * 2;
    hole_bottom = -(depth + overcut);
    cut_length = d * 2;
    union() {
        translate([0, 0, hole_bottom])          cylinder(r=d, h=hole_depth);
        translate([-(d / 2), 0, hole_bottom])   cube([d, cut_length, hole_depth]);
        translate([0, -(d / 2), hole_bottom])   cube([cut_length, d, hole_depth]);
        translate([0, cut_length, hole_bottom]) cylinder(r=(d / 2), h=hole_depth);
        translate([cut_length, 0, hole_bottom]) cylinder(r=(d / 2), h=hole_depth);
    }
}

//-------------------------------------------------------------------------
// Build a cap to place over a screw hole.
// Screw body diameter = d
// Screw head diameter = d * 2
// Screw head height   = d * 0.6
//-------------------------------------------------------------------------
module screw_hole_cap(d, thick) {
    $fn = 36;
    r2 = 1.4142;
    pin_radius = thick * 1.3;
    pin_heigh = (d * 0.6) + (overlap * 2);
    pin_base = -overlap;
    offset = (((pin_radius * r2) - pin_radius) / r2) + ((pin_radius * 2) / r2) + (d / r2);
    size1 = (offset + overlap) * 2;
    size2 = size1 + d * 2;
    translate([-(size1 / 2), -(size1 / 2), 0]) {
        union() {
            translate([0, 0, d * 0.6]) rounded_cube(size1, size2, thick, pin_radius);
            translate([0, 0, d * 0.6]) rounded_cube(size2, size1, thick, pin_radius);
            translate([pin_radius, pin_radius, pin_base])                 cylinder(r=pin_radius, h=pin_heigh);
            translate([size2 - pin_radius, pin_radius, pin_base])         cylinder(r=pin_radius, h=pin_heigh);
            translate([size2 - pin_radius, size1 - pin_radius, pin_base]) cylinder(r=pin_radius, h=pin_heigh);
            translate([size1 - pin_radius, size2 - pin_radius, pin_base]) cylinder(r=pin_radius, h=pin_heigh);
            translate([pin_radius, size2 - pin_radius, pin_base])         cylinder(r=pin_radius, h=pin_heigh);
        }
    }
}

//-------------------------------------------------------------------------
// Make a box with the requested internal size and rounded corners.
// The origin is the lower-left internal corner.
//-------------------------------------------------------------------------
module rounded_box(x_size, y_size, z_size, chamfer, thick) {
    cover_thick = 2;
    union() {
        translate([-overlap, -overlap, -thick])
            rounded_cube(x_size + overlap * 2, y_size + overlap * 2, thick, chamfer + overlap);
        translate([0, 0, -thick])
            rounded_cube_border(x_size, y_size, z_size + thick, chamfer, thick);
        translate([-overlap, -overlap, z_size - cover_thick - thick])
            rounded_box_flange(x_size + overlap * 2, y_size + overlap * 2, thick, chamfer + overlap);
        translate([0, 0, -thick])
            box_feet(x_size, y_size, 10);
        // Draw the box cover, for dimension testing.
        //translate([0, 0, z_size - cover_thick])
        //    %rounded_cube(x_size, y_size, cover_thick, chamfer);
    }
}

//-------------------------------------------------------------------------
// Make a box with rounded corners, drill all the required holes.
//-------------------------------------------------------------------------
module rounded_box_holes(x_size, y_size, z_size, chamfer, thick) {

    holes_diam = 3.5;

    // Boiler cable grommet.
    translate([bcable_x, bcable_y, bcable_z])
        rotate(a=180, v=[0, 1, 0])
            rotate(a=270, v=[1, 0, 0])
                cable_grommet_rect(bcable_h, bcable_d1, bcable_d2, bcable_r, bcable_t);

    // Temperature sensor cable grommet.
    translate([tsensor_x, tsensor_y, tsensor_z])
        rotate(a=90, v=[1, 0, 0])
            rotate(a=90, v=[0, 1, 0])
                cable_grommet(tsensor_h, tsensor_d1, tsensor_d2);

    difference() {
        rounded_box(x_size, y_size, z_size, chamfer, thick);

        // Bottom venting holes.
        translate([x_size / 2, 0, z_size / 2])
            rotate(a=90, v=[1, 0, 0]) vent_holes(12, 3, holes_diam, thick);

        // Top venting holes.
        translate([x_size / 2, y_size + thick, z_size / 2])
            rotate(a=90, v=[1, 0, 0]) vent_holes(11, 3, holes_diam, thick);

        // Backplane venting holes.
        translate([83, 88, -thick]) vent_holes(8, 6, holes_diam, thick);
        translate([25, 38, -thick]) vent_holes(5, 4, holes_diam, thick);

        // Mounting screw holes.
        translate([x_size / 2, screw_hole1_y, 0]) rotate(a=90, v=[0, 0, 1]) screw_hole(screw_diam, thick);
        translate([x_size / 2, screw_hole2_y, 0]) rotate(a=90, v=[0, 0, 1]) screw_hole(screw_diam, thick);

        // Temperature sensor hole.
        translate([-(thick + overcut), tsensor_y, tsensor_z])
            rotate(a=90, v=[0, 1, 0]) cylinder(r=(tsensor_d2 / 2), h=(thick + overcut * 2), $fn=24);

        // Bush-button hole.
        translate([button_x - overcut, button_y, button_z])
            rotate(a=90, v=[0, 1, 0]) cylinder(r=(button_d / 2), h=(thick + overcut * 2), $fn=24);

        // Power socket hole.
        translate([psocket_x, overcut, psocket_z])
            rotate(a=90, v=[1, 0, 0]) cylinder(r=(psocket_d / 2), h=(thick + overcut * 2), $fn=24);

        // Boiler cable hole.
        translate([bcable_x, bcable_y - overcut, bcable_z])
            rotate(a=270, v=[1, 0, 0]) rounded_cube_centered(bcable_d1, bcable_d2, bcable_h + overcut * 2, bcable_r);

    }

    // Reinforce for power socket hole.
    difference() {
        translate([psocket_x, 0, psocket_z]) rotate(a=90, v=[1, 0, 0]) cylinder(r=(psocket_d / 2) + 2.5, h=thick);
        translate([psocket_x, overcut, psocket_z])
            rotate(a=90, v=[1, 0, 0]) cylinder(r=(psocket_d / 2), h=(thick + overcut * 2), $fn=24);
    }

    // Reinforce for boiler cable hole.
    difference() {
        translate([bcable_x, 0, bcable_z])
            rotate(a=90, v=[1, 0, 0]) rounded_cube_centered(bcable_d1 + 5.5, bcable_d2 + 5.5, thick, 3);
        translate([bcable_x, overcut, bcable_z])
            rotate(a=90, v=[1, 0, 0]) rounded_cube_centered(bcable_d1, bcable_d2, (thick + overcut * 2), bcable_r);
    }

    // Mounting screws holes.
    translate([x_size / 2, screw_hole1_y, 0]) rotate(a=90, v=[0, 0, 1]) #screw_hole_cap(screw_diam, 1.7);
    translate([x_size / 2, screw_hole2_y, 0]) rotate(a=90, v=[0, 0, 1]) #screw_hole_cap(screw_diam, 1.7);
}

//-------------------------------------------------------------------------
// Drill a grid of rows x columns vent holes. Each hole has the
// specified diameter and depth, the grid is centered into the origin.
//-------------------------------------------------------------------------
module vent_holes(x, y, diameter, depth) {
    $fn = 6; // 18 = rounded holes, 6 = hexagonal
    step = diameter * 2;
    radius = diameter / 1.8;  // Divide by 2.0 if rounded holes, 1.8 if hexagonal.
    offset_x = (step * (x - 1)) / 2;
    offset_y = (step * (y - 1)) / 2;
    for (i = [1:x]) {
        for (j = [1:y]) {
            translate([(i - 1) * step - offset_x, (j -1) * step - offset_y, -overcut])
              cylinder(r=radius, h=(depth + overcut * 2));
        }
    }
    for (i = [1:x-1]) {
        for (j = [1:y-1]) {
            translate([(i - 1) * step - offset_x + step / 2, (j -1) * step - offset_y + step / 2, -overcut])
                cylinder(r=radius, h=(depth + overcut * 2));
        }
    }
}

//-------------------------------------------------------------------------
// Screw stub: d1 is the outer diameter, d2 is the screw diameter.
// The stub height must be grather than the depth of the hole.
//-------------------------------------------------------------------------
module stub(d1, height, d2, hole_depth) {
    $fn = 36;
    // The hole for a self-tapping screw is narrower than the screw.
    hole_diameter = d2 * 0.75;
    difference() {
        translate([0, 0, -overlap]) {
            union() {
                cylinder(r=(d1 / 2), h=(height + overlap));
                cylinder(r1=(d1 * 0.7), r2=(d1 / 2), h=(4 + overlap));
            }
        }
        translate([0, 0, height - hole_depth])
            cylinder(r=(hole_diameter / 2), h=(hole_depth + overcut));
    }
}

//-------------------------------------------------------------------------
// Screw stubs for relay board (SainSmart like manufacturer).
//-------------------------------------------------------------------------
module stubs_2relays_sainsmart(height) {
    diameter = 7;
    screw_diameter = 2.2;
    hole_depth = 6;
    // Offset of first (lower left) hole from edge.
    translate([2.75, 2.75, 0]) {
        translate([ 0,      0, 0]) stub(diameter, height, screw_diameter, hole_depth);
        translate([33.5,    0, 0]) stub(diameter, height, screw_diameter, hole_depth);
        translate([0,    45.5, 0]) stub(diameter, height, screw_diameter, hole_depth);
        translate([33.5, 45.5, 0]) stub(diameter, height, screw_diameter, hole_depth);
    }
}

//-------------------------------------------------------------------------
// Screw stubs for relay board (Keyes manufacturer).
//-------------------------------------------------------------------------
module stubs_2relays_keyes(height) {
    diameter = 7;
    screw_diameter = 2.2;
    hole_depth = 6;
    // Offset of first (lower left) hole from edge.
    translate([3.5, 9, 0]) {
        translate([ 0,  0, 0]) stub(diameter, height, screw_diameter, hole_depth);
        translate([38,  0, 0]) stub(diameter, height, screw_diameter, hole_depth);
        translate([0,  40, 0]) stub(diameter, height, screw_diameter, hole_depth);
        translate([38, 40, 0]) stub(diameter, height, screw_diameter, hole_depth);
    }
}

//-------------------------------------------------------------------------
// Screw stubs for PCD8544 LCD (Nokia 5110/3310), blue PCB model.
//-------------------------------------------------------------------------
module stubs_pcd8544_blue(height) {
    diameter = 6.5;
    screw_diameter = 2.2;
    hole_depth = 6;
    // Offset of first (lower left) hole from edge.
    translate([4.25, 2.25, 0]) {
        translate([ 0,    0, 0]) stub(diameter, height, screw_diameter, hole_depth);
        translate([34.5,  0, 0]) stub(diameter, height, screw_diameter, hole_depth);
        translate([0,    41, 0]) stub(diameter, height, screw_diameter, hole_depth);
        translate([34.5, 41, 0]) stub(diameter, height, screw_diameter, hole_depth);
    }
}

//-------------------------------------------------------------------------
// Screw stubs for PCD8544 LCD (Nokia 5110/3310), red PCB model.
//-------------------------------------------------------------------------
module stubs_pcd8544_red(height) {
    diameter = 6.0;
    screw_diameter = 2.2;
    hole_depth = 6;
    // Offset of first (lower left) hole from edge.
    translate([1.75, 2.0, 0]) {
        translate([ 0,  0, 0]) stub(diameter, height, screw_diameter, hole_depth);
        translate([40,  0, 0]) stub(diameter, height, screw_diameter, hole_depth);
        translate([ 0, 39, 0]) stub(diameter, height, screw_diameter, hole_depth);
        translate([40, 39, 0]) stub(diameter, height, screw_diameter, hole_depth);
    }
}

//-------------------------------------------------------------------------
// Screw stubs for Raspberry Pi Model B v.2.
//-------------------------------------------------------------------------
module stubs_raspberrypi_model_b_v2(height) {
    screw_diameter = 2.2;
    hole_depth = 6;
    translate([38, 25.5, 0]) {
        translate([    0,    0, 0]) stub(6.5, height, screw_diameter, hole_depth);
        translate([-25.5, 54.5, 0]) stub(6.5, height, screw_diameter, hole_depth);
    }
}

//-------------------------------------------------------------------------
// Main procedure.
//-------------------------------------------------------------------------
translate([-(x_size / 2), -(y_size/2), 0]) {
    rounded_box_holes(x_size, y_size, z_size, chamfer, thick);
    translate([ 5, 12,  0.0]) stubs_2relays_sainsmart(5.0);
    translate([ 8, 90,  0.0]) stubs_pcd8544_red(20.5); // Non diminuire Y sennò tocca il coprivite!
    translate([55, 37,  0.0]) stubs_raspberrypi_model_b_v2(5.0);
    //translate([55, 37 , 5.0]) board_raspberrypi_model_b_v2();
    //translate([ 8, 90, 20.5]) board_pcd8544_red();
    //translate([ 5, 12,  5.0]) board_2relays_sainsmart();
    //translate([button_x, button_y, button_z]) rotate(a=90, v=[0, 1, 0]) push_button();
    //translate([psocket_x, -thick, psocket_z]) rotate(a=90, v=[1, 0, 0]) coax_power_jack();
}

include <RigacciOrg.scad>;
translate([-x_size / 2 - thick + overlap, -29, 13])
    rotate(a=270, v=[0,0,1]) rotate(a=90, v=[1,0,0]) {
        //#cube([55, 12.54, 0.5], center=true);
        RigacciOrg(0.5);
    }

include <ccbysa.scad>;
translate([-x_size / 2 - thick + overlap, 34, 13])
    rotate(a=270, v=[0,0,1]) rotate(a=90, v=[1,0,0]) {
        //#cube([35.60, 12.54, 0.5], center=true);
        ccbysa(0.5);
    }


config: Add extrusion screw nut variables

include <MCAD/stepper.scad>
include <bearings.scad>
include <screws.scad>
include <thing_libutils/metric-thread.scad>
include <thing_libutils/metric-hexnut.scad>
include <thing_libutils/misc.scad>

e=0.01;

// resolution of any round object (segment length)
fnr                         = 0.4;

extrusion_height            = 0.4*mm;

// width of a single wall, should match your slicer settings
extrusion_width             = 0.4*mm;

// how many lines should a normal wall have (i.e. 0.6(extrusion_width)*6(normal_wall_factor)= 3.6mm wall width)
normal_wall_factor          = 3;

thick_wall_factor           = 4;

// diameter of your filament.
filament_d                  = 1.75*mm;
filament_r                  = filament_d/2;

// enable preview model (faster openscad)
preview_mode=true;

main_width = 300*mm;
main_depth = 420*mm;
main_height = 400*mm;
main_upper_width = 420*mm;

extrusion_color = [0.5,0.5,0.5];
extrusion_size = 20*mm;
extrusion_thread = ThreadM5;
extrusion_thread_dia = lookup(ThreadSize, extrusion_thread);
extrusion_nut = MHexNutM5;
extrusion_nut_dia = lookup(MHexNutWidthMax, extrusion_nut);

main_lower_dist_z= 80*mm;
main_upper_dist_y= 160*mm;

gantry_connector_thickness = 5;

rod_fit_tolerance=1.01;

ziptie_thickness = 4;
ziptie_width = 4;
ziptie_bearing_distance=2;

xaxis_rod_distance = 60*mm;
xaxis_rod_d = 9.975*mm;
xaxis_rod_l = 500*mm;
xaxis_bearing=bearing_igus_rj4jp_01_10;
xaxis_pulley_d = 12.2;
xaxis_belt_width = 6*mm;

xaxis_carriage_bearing_offset_z = ziptie_thickness/2;
xaxis_carriage_beltpath_offset = xaxis_carriage_bearing_offset_z+xaxis_bearing[1]/2;

yaxis_rod_distance = 170*mm;
yaxis_rod_d = 11.975*mm;
yaxis_rod_l = 500*mm;
yaxis_bearing=bearing_igus_rj4jp_01_12;
yaxis_bearing_distance_y = 7*cm;

yaxis_motor = dict_replace(Nema17, NemaFrontAxleLength, 21.5*mm);

// 2GT2 20T pulley
yaxis_pulley_d = 18;
ymotor_mount_thickness = 5;
ymotor_mount_thickness_h = 5;
yaxis_motor_offset_x = lookup(NemaSideSize,yaxis_motor)/2+ymotor_mount_thickness;
yaxis_motor_offset_z = -5*mm;
yaxis_belt_path_offset_x = -yaxis_pulley_d/2;
yaxis_belt_path_offset_z = yaxis_motor_offset_z + 15*mm;

yaxis_idler_mount_thickness = 5;
yaxis_idler_pulley_tight_len = 20*mm;
yaxis_idler_pulley_offset_y = yaxis_idler_mount_thickness + yaxis_pulley_d/2 + yaxis_idler_pulley_tight_len;
yaxis_idler_offset_x = lookup(NemaSideSize,yaxis_motor)/2+ymotor_mount_thickness;
yaxis_idler_offset_z = 10*mm;
yaxis_idler_pulley_h = 8.65*mm;

yaxis_carriage_size=[220*mm,220*mm,5*mm];

zaxis_rod_d = 11.975*mm;
zaxis_rod_l = 500*mm;
zaxis_bearing=bearing_igus_rj4jp_01_12;

// Nema17 motor w/340mm long 8*mm leadscrew
zaxis_motor = dict_replace_multiple(Nema17,
        [
        [NemaAxleDiameter, 8*mm],
        [NemaFrontAxleLength, 340*mm],
        ]);

zaxis_motor_offset_z = 10*mm;
zmotor_mount_thickness = 5;
zmotor_mount_thickness_h = 10;
zmotor_mount_motor_offset=5;

// GT2
// there is bunch of GT2 belts with different tooth-to-tooth distance
// this one is most common in reprap world
// adjust to your needs.
belt_width = 6.5;
belt_tooth_distance = 2;
belt_tooth_ratio = 0.5;
belt_thickness = 0.8;

//T2.5
//belt_tooth_distance = 2.5;
//belt_tooth_ratio = 0.5;

//T5 (strongly discouraged)
//belt_tooth_distance = 5;
//belt_tooth_ratio = 0.75;

//HTD3
//belt_tooth_distance = 3;
//belt_tooth_ratio = 0.75;

//MXL
//belt_tooth_distance = 2.032;
//belt_tooth_ratio = 0.64;

include <MCAD/stepper.scad>
include <bearings.scad>
include <screws.scad>
include <thing_libutils/metric-thread.scad>
include <thing_libutils/metric-hexnut.scad>
include <thing_libutils/misc.scad>

e=0.01;

// resolution of any round object (segment length)
fnr                         = 0.4;

extrusion_height            = 0.4*mm;

// width of a single wall, should match your slicer settings
extrusion_width             = 0.4*mm;

// how many lines should a normal wall have (i.e. 0.6(extrusion_width)*6(normal_wall_factor)= 3.6mm wall width)
normal_wall_factor          = 3;

thick_wall_factor           = 4;

// diameter of your filament.
filament_d                  = 1.75*mm;
filament_r                  = filament_d/2;

// enable preview model (faster openscad)
preview_mode=true;

main_width = 300*mm;
main_depth = 420*mm;
main_height = 400*mm;
main_upper_width = 420*mm;

extrusion_color = [0.5,0.5,0.5];
extrusion_size = 20*mm;
extrusion_thread = ThreadM5;
extrusion_thread_dia = lookup(ThreadSize, extrusion_thread);

main_lower_dist_z= 80*mm;
main_upper_dist_y= 160*mm;

gantry_connector_thickness = 5;

rod_fit_tolerance=1.01;

ziptie_thickness = 4;
ziptie_width = 4;
ziptie_bearing_distance=2;

xaxis_rod_distance = 60*mm;
xaxis_rod_d = 9.975*mm;
xaxis_rod_l = 500*mm;
xaxis_bearing=bearing_igus_rj4jp_01_10;
xaxis_pulley_d = 12.2;
xaxis_belt_width = 6*mm;

xaxis_carriage_bearing_offset_z = ziptie_thickness/2;
xaxis_carriage_beltpath_offset = xaxis_carriage_bearing_offset_z+xaxis_bearing[1]/2;

yaxis_rod_distance = 170*mm;
yaxis_rod_d = 11.975*mm;
yaxis_rod_l = 500*mm;
yaxis_bearing=bearing_igus_rj4jp_01_12;
yaxis_bearing_distance_y = 7*cm;

yaxis_motor = dict_replace(Nema17, NemaFrontAxleLength, 21.5*mm);

// 2GT2 20T pulley
yaxis_pulley_d = 18;
ymotor_mount_thickness = 5;
ymotor_mount_thickness_h = 5;
yaxis_motor_offset_x = lookup(NemaSideSize,yaxis_motor)/2+ymotor_mount_thickness;
yaxis_motor_offset_z = -5*mm;
yaxis_belt_path_offset_x = -yaxis_pulley_d/2;
yaxis_belt_path_offset_z = yaxis_motor_offset_z + 15*mm;

yaxis_idler_mount_thickness = 5;
yaxis_idler_pulley_tight_len = 20*mm;
yaxis_idler_pulley_offset_y = yaxis_idler_mount_thickness + yaxis_pulley_d/2 + yaxis_idler_pulley_tight_len;
yaxis_idler_offset_x = lookup(NemaSideSize,yaxis_motor)/2+ymotor_mount_thickness;
yaxis_idler_offset_z = 10*mm;
yaxis_idler_pulley_h = 8.65*mm;

yaxis_carriage_size=[220*mm,220*mm,5*mm];

zaxis_rod_d = 11.975*mm;
zaxis_rod_l = 500*mm;
zaxis_bearing=bearing_igus_rj4jp_01_12;

// Nema17 motor w/340mm long 8*mm leadscrew
zaxis_motor = dict_replace_multiple(Nema17,
        [
        [NemaAxleDiameter, 8*mm],
        [NemaFrontAxleLength, 340*mm],
        ]);

zaxis_motor_offset_z = 10*mm;
zmotor_mount_thickness = 5;
zmotor_mount_thickness_h = 10;
zmotor_mount_motor_offset=5;

// GT2
// there is bunch of GT2 belts with different tooth-to-tooth distance
// this one is most common in reprap world
// adjust to your needs.
belt_width = 6.5;
belt_tooth_distance = 2;
belt_tooth_ratio = 0.5;
belt_thickness = 0.8;

//T2.5
//belt_tooth_distance = 2.5;
//belt_tooth_ratio = 0.5;

//T5 (strongly discouraged)
//belt_tooth_distance = 5;
//belt_tooth_ratio = 0.75;

//HTD3
//belt_tooth_distance = 3;
//belt_tooth_ratio = 0.75;

//MXL
//belt_tooth_distance = 2.032;
//belt_tooth_ratio = 0.64;


config/xz: increase x to z distance w/1mm

include <MCAD/stepper.scad>
include <screws.scad>
include <pulley.scad>
include <thing_libutils/bearing_data.scad>
include <thing_libutils/metric-thread-data.scad>
include <thing_libutils/metric-hexnut-data.scad>
include <thing_libutils/misc.scad>

e=0.01;

// resolution of any round object (segment length)
fnr                         = 0.4;

extrusion_height            = 0.4*mm;

// width of a single wall, should match your slicer settings
extrusion_width             = 0.4*mm;

// how many lines should a normal wall have (i.e. 0.6(extrusion_width)*6(normal_wall_factor)= 3.6mm wall width)
normal_wall_factor          = 3;

thick_wall_factor           = 4;

// diameter of your filament.
filament_d                  = 1.75*mm;
filament_r                  = filament_d/2;

// enable preview model (faster openscad)
preview_mode=true;

main_width = 340*mm;
main_depth = 420*mm;
main_height = 400*mm;
main_upper_width = 420*mm;

extrusion_color = [0.5,0.5,0.5];
extrusion_size = 20*mm;
extrusion_thread = ThreadM5;
extrusion_thread_dia = lookup(ThreadSize, extrusion_thread);
extrusion_nut = MHexNutM5;
extrusion_nut_dia = lookup(MHexNutWidthMax, extrusion_nut);

main_lower_dist_z= 80*mm;
main_upper_dist_y= 160*mm;

gantry_connector_thickness = 5;

rod_fit_tolerance=1.01;

ziptie_type = [1.1*mm, 2.4*mm];
ziptie_thickness = ziptie_type[0];
ziptie_width = ziptie_type[1]+0.6*mm;
ziptie_bearing_distance=3*mm;

xaxis_rod_distance = 60*mm;
xaxis_rod_d = 9.975*mm;
xaxis_rod_l = 500*mm;
xaxis_rod_offset_x = 20*mm;
xaxis_bearing=bearing_igus_rj4jp_01_10;

xaxis_pulley = pulley_2GT_20T;
xaxis_pulley_inner_d = xaxis_pulley[2];
xaxis_idler_pulley = pulley_2GT_20T_idler;
xaxis_idler_pulley_inner_d = xaxis_idler_pulley[2];
xaxis_idler_pulley_outer_d = xaxis_idler_pulley[3];

xaxis_belt_width = 6*mm;

xaxis_carriage_bearing_offset_z = ziptie_thickness/2;
xaxis_carriage_beltpath_offset = xaxis_carriage_bearing_offset_z+xaxis_bearing[1]/2;

xaxis_motor = dict_replace(Nema17, NemaFrontAxleLength, 22*mm);

yaxis_rod_distance = 170*mm;
yaxis_rod_d = 11.975*mm;
yaxis_rod_l = 500*mm;
yaxis_bearing=bearing_igus_rj4jp_01_12;
yaxis_bearing_distance_y = 7*cm;

yaxis_motor = dict_replace(Nema17, NemaFrontAxleLength, 22*mm);

yaxis_pulley = pulley_2GT_20T;
yaxis_pulley_inner_d = yaxis_pulley[2];
ymotor_mount_thickness = 5;
ymotor_mount_thickness_h = 5;
yaxis_motor_offset_x = lookup(NemaSideSize,yaxis_motor)/2+ymotor_mount_thickness;
yaxis_motor_offset_z = -5*mm;
yaxis_belt_path_offset_x = -yaxis_pulley_inner_d/2;
yaxis_belt_path_offset_z = yaxis_motor_offset_z + 15*mm;

yaxis_idler_pulley = pulley_2GT_20T_idler;
yaxis_idler_pulley_inner_d = yaxis_idler_pulley[2];
yaxis_idler_pulley_outer_d = yaxis_idler_pulley[3];
yaxis_idler_pulley_h = yaxis_idler_pulley[0];
yaxis_idler_mount_thickness = 5;
yaxis_idler_pulley_tight_len = 20*mm;
yaxis_idler_pulley_offset_y = yaxis_idler_mount_thickness + yaxis_pulley_inner_d/2 + yaxis_idler_pulley_tight_len;
yaxis_idler_offset_x = lookup(NemaSideSize,yaxis_motor)/2+ymotor_mount_thickness;
yaxis_idler_offset_z = 10*mm;

yaxis_carriage_size=[220*mm,220*mm,5*mm];

zaxis_rod_d = 11.975*mm;
zaxis_rod_l = 500*mm;
zaxis_bearing=bearing_igus_rj4jp_01_12;

// Nema17 motor w/340mm long 8*mm leadscrew
zaxis_motor = dict_replace_multiple(Nema17,
        [
        [NemaAxleDiameter, 8*mm],
        [NemaFrontAxleLength, 340*mm],
        ]);

zmotor_w = lookup(NemaSideSize,zaxis_motor);
zmotor_h = lookup(NemaLengthLong,zaxis_motor);

// inner_d, outer_d, thread, outer_h, full_h
zaxis_nut = [20*mm, 36*mm, 8*mm, 5*mm, 23*mm];

zaxis_nut_mount_outer = zaxis_nut[1]/2 + zaxis_rod_d/2 + 1*mm;

// place z rod as close as possible (depends on z nut and also motor etc)
zaxis_rod_screw_distance_x = max(zaxis_nut_mount_outer, zaxis_rod_d/2 + zmotor_w/2 + 1*mm);

zaxis_motor_offset_z = 10*mm;
zmotor_mount_thickness = 5;
zmotor_mount_thickness_h = 10;
zmotor_mount_motor_offset=5;
zmotor_mount_rod_offset_x = zmotor_w/2 + zaxis_rod_screw_distance_x + zmotor_mount_motor_offset;

zmotor_w = lookup(NemaSideSize,zaxis_motor);
zmotor_h = lookup(NemaLengthLong,zaxis_motor);
zmotor_mount_thread_dia = lookup(ThreadSize, extrusion_thread);
zmotor_mount_width = zmotor_w+zmotor_mount_thickness*2 + zmotor_mount_thread_dia*8;
zmotor_mount_h = main_lower_dist_z+extrusion_size+zaxis_motor_offset_z;
zmotor_mount_rod_offset_x = zmotor_w/2+zaxis_rod_screw_distance_x+zmotor_mount_motor_offset;

zmotor_mount_clamp_dist = zaxis_rod_d*2.5;
zmotor_mount_clamp_thread = ThreadM4;
zmotor_mount_clamp_nut = MHexNutM4;
zmotor_mount_clamp_thread_dia = lookup(ThreadSize, zmotor_mount_clamp_thread);
zmotor_mount_clamp_nut_dia = lookup(MHexNutWidthMin, zmotor_mount_clamp_nut);
zmotor_mount_clamp_nut_thick = lookup(MHexNutThickness, zmotor_mount_clamp_nut);

zmotor_mount_clamp_width = zmotor_mount_clamp_dist+zmotor_mount_clamp_thread_dia*3;
xaxis_zaxis_distance_y = 1*mm + xaxis_rod_d/2 + zaxis_bearing[1]/2;

// GT2
// there is bunch of GT2 belts with different tooth-to-tooth distance
// this one is most common in reprap world
// adjust to your needs.
belt_width = 6.5;
belt_tooth_distance = 2;
belt_tooth_ratio = 0.5;
belt_thickness = 0.8;

//T2.5
//belt_tooth_distance = 2.5;
//belt_tooth_ratio = 0.5;

//T5 (strongly discouraged)
//belt_tooth_distance = 5;
//belt_tooth_ratio = 0.75;

//HTD3
//belt_tooth_distance = 3;
//belt_tooth_ratio = 0.75;

//MXL
//belt_tooth_distance = 2.032;
//belt_tooth_ratio = 0.64;

include <MCAD/stepper.scad>
include <screws.scad>
include <pulley.scad>
include <thing_libutils/bearing_data.scad>
include <thing_libutils/metric-thread-data.scad>
include <thing_libutils/metric-hexnut-data.scad>
include <thing_libutils/misc.scad>

e=0.01;

// resolution of any round object (segment length)
fnr                         = 0.4;

extrusion_height            = 0.4*mm;

// width of a single wall, should match your slicer settings
extrusion_width             = 0.4*mm;

// how many lines should a normal wall have (i.e. 0.6(extrusion_width)*6(normal_wall_factor)= 3.6mm wall width)
normal_wall_factor          = 3;

thick_wall_factor           = 4;

// diameter of your filament.
filament_d                  = 1.75*mm;
filament_r                  = filament_d/2;

// enable preview model (faster openscad)
preview_mode=true;

main_width = 340*mm;
main_depth = 420*mm;
main_height = 400*mm;
main_upper_width = 420*mm;

extrusion_color = [0.5,0.5,0.5];
extrusion_size = 20*mm;
extrusion_thread = ThreadM5;
extrusion_thread_dia = lookup(ThreadSize, extrusion_thread);
extrusion_nut = MHexNutM5;
extrusion_nut_dia = lookup(MHexNutWidthMax, extrusion_nut);

main_lower_dist_z= 80*mm;
main_upper_dist_y= 160*mm;

gantry_connector_thickness = 5;

rod_fit_tolerance=1.01;

ziptie_type = [1.1*mm, 2.4*mm];
ziptie_thickness = ziptie_type[0];
ziptie_width = ziptie_type[1]+0.6*mm;
ziptie_bearing_distance=3*mm;

xaxis_rod_distance = 60*mm;
xaxis_rod_d = 9.975*mm;
xaxis_rod_l = 500*mm;
xaxis_rod_offset_x = 20*mm;
xaxis_bearing=bearing_igus_rj4jp_01_10;

xaxis_pulley = pulley_2GT_20T;
xaxis_pulley_inner_d = xaxis_pulley[2];
xaxis_idler_pulley = pulley_2GT_20T_idler;
xaxis_idler_pulley_inner_d = xaxis_idler_pulley[2];
xaxis_idler_pulley_outer_d = xaxis_idler_pulley[3];

xaxis_belt_width = 6*mm;

xaxis_carriage_bearing_offset_z = ziptie_thickness/2;
xaxis_carriage_beltpath_offset = xaxis_carriage_bearing_offset_z+xaxis_bearing[1]/2;

xaxis_motor = dict_replace(Nema17, NemaFrontAxleLength, 22*mm);

yaxis_rod_distance = 170*mm;
yaxis_rod_d = 11.975*mm;
yaxis_rod_l = 500*mm;
yaxis_bearing=bearing_igus_rj4jp_01_12;
yaxis_bearing_distance_y = 7*cm;

yaxis_motor = dict_replace(Nema17, NemaFrontAxleLength, 22*mm);

yaxis_pulley = pulley_2GT_20T;
yaxis_pulley_inner_d = yaxis_pulley[2];
ymotor_mount_thickness = 5;
ymotor_mount_thickness_h = 5;
yaxis_motor_offset_x = lookup(NemaSideSize,yaxis_motor)/2+ymotor_mount_thickness;
yaxis_motor_offset_z = -5*mm;
yaxis_belt_path_offset_x = -yaxis_pulley_inner_d/2;
yaxis_belt_path_offset_z = yaxis_motor_offset_z + 15*mm;

yaxis_idler_pulley = pulley_2GT_20T_idler;
yaxis_idler_pulley_inner_d = yaxis_idler_pulley[2];
yaxis_idler_pulley_outer_d = yaxis_idler_pulley[3];
yaxis_idler_pulley_h = yaxis_idler_pulley[0];
yaxis_idler_mount_thickness = 5;
yaxis_idler_pulley_tight_len = 20*mm;
yaxis_idler_pulley_offset_y = yaxis_idler_mount_thickness + yaxis_pulley_inner_d/2 + yaxis_idler_pulley_tight_len;
yaxis_idler_offset_x = lookup(NemaSideSize,yaxis_motor)/2+ymotor_mount_thickness;
yaxis_idler_offset_z = 10*mm;

yaxis_carriage_size=[220*mm,220*mm,5*mm];

zaxis_rod_d = 11.975*mm;
zaxis_rod_l = 500*mm;
zaxis_bearing=bearing_igus_rj4jp_01_12;

// Nema17 motor w/340mm long 8*mm leadscrew
zaxis_motor = dict_replace_multiple(Nema17,
        [
        [NemaAxleDiameter, 8*mm],
        [NemaFrontAxleLength, 340*mm],
        ]);

zmotor_w = lookup(NemaSideSize,zaxis_motor);
zmotor_h = lookup(NemaLengthLong,zaxis_motor);

// inner_d, outer_d, thread, outer_h, full_h
zaxis_nut = [20*mm, 36*mm, 8*mm, 5*mm, 23*mm];

zaxis_nut_mount_outer = zaxis_nut[1]/2 + zaxis_rod_d/2 + 1*mm;

// place z rod as close as possible (depends on z nut and also motor etc)
zaxis_rod_screw_distance_x = max(zaxis_nut_mount_outer, zaxis_rod_d/2 + zmotor_w/2 + 1*mm);

zaxis_motor_offset_z = 10*mm;
zmotor_mount_thickness = 5;
zmotor_mount_thickness_h = 10;
zmotor_mount_motor_offset=5;
zmotor_mount_rod_offset_x = zmotor_w/2 + zaxis_rod_screw_distance_x + zmotor_mount_motor_offset;

zmotor_w = lookup(NemaSideSize,zaxis_motor);
zmotor_h = lookup(NemaLengthLong,zaxis_motor);
zmotor_mount_thread_dia = lookup(ThreadSize, extrusion_thread);
zmotor_mount_width = zmotor_w+zmotor_mount_thickness*2 + zmotor_mount_thread_dia*8;
zmotor_mount_h = main_lower_dist_z+extrusion_size+zaxis_motor_offset_z;
zmotor_mount_rod_offset_x = zmotor_w/2+zaxis_rod_screw_distance_x+zmotor_mount_motor_offset;

zmotor_mount_clamp_dist = zaxis_rod_d*2.5;
zmotor_mount_clamp_thread = ThreadM4;
zmotor_mount_clamp_nut = MHexNutM4;
zmotor_mount_clamp_thread_dia = lookup(ThreadSize, zmotor_mount_clamp_thread);
zmotor_mount_clamp_nut_dia = lookup(MHexNutWidthMin, zmotor_mount_clamp_nut);
zmotor_mount_clamp_nut_thick = lookup(MHexNutThickness, zmotor_mount_clamp_nut);

zmotor_mount_clamp_width = zmotor_mount_clamp_dist+zmotor_mount_clamp_thread_dia*3;
xaxis_zaxis_distance_y = 0*mm + xaxis_rod_d/2 + zaxis_bearing[1]/2;

// GT2
// there is bunch of GT2 belts with different tooth-to-tooth distance
// this one is most common in reprap world
// adjust to your needs.
belt_width = 6.5;
belt_tooth_distance = 2;
belt_tooth_ratio = 0.5;
belt_thickness = 0.8;

//T2.5
//belt_tooth_distance = 2.5;
//belt_tooth_ratio = 0.5;

//T5 (strongly discouraged)
//belt_tooth_distance = 5;
//belt_tooth_ratio = 0.75;

//HTD3
//belt_tooth_distance = 3;
//belt_tooth_ratio = 0.75;

//MXL
//belt_tooth_distance = 2.032;
//belt_tooth_ratio = 0.64;