config: increase x carriage thickness

config: increase x carriage thickness

include <MCAD/stepper.scad>
include <thing_libutils/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>
include <thing_libutils/timing-belts-data.scad>

e=0.01*mm;

// high quality etc
is_build = false;

// minimum size of a fragment
// resolution of any round object (segment length)
// Because of this variable very small circles have a smaller number of fragments than specified using $fa.
// The default value is 2.
$fs = is_build ? 0.5 : 2;

// minimum angle for a fragment.
// The default value is 12 (i.e. 30 fragments for a full circle)
$fa = is_build ? 4 : 12;

$show_vit = is_build ? false : true;

// enable preview model (faster openscad)
$preview_mode = is_build ? false : true;

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;

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

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

// for tapped ends
extrusion_end_nut = MHexNutM6;

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

gantry_connector_thickness = 5;

rod_fit_tolerance=1.01;

ziptie_type = [2*mm, 3*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;
// relative to entire machine
xaxis_rod_offset_x = 0*mm;
xaxis_bearings_top=2;
xaxis_bearings_bottom=1;
xaxis_bearing=bearing_bronze_10_16_12;
xaxis_bearing_bottom=bearing_bronze_10_16_18;
/*xaxis_bearing=bearing_igus_rj4jp_01_10;*/

xaxis_pulley = pulley_2GT_20T;
xaxis_pulley_inner_d = xaxis_pulley[2];
xaxis_pulley_outer_d = xaxis_pulley[3];
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 = TimingBelt_GT2_2;
xaxis_belt_width = 6*mm;
xaxis_beltpath_width = max(xaxis_belt_width+3*mm, xaxis_pulley[0]+2*mm);
xaxis_beltpath_z_offset_pulley = xaxis_pulley_inner_d/2;
/*xaxis_beltpath_z_offsets = [xaxis_beltpath_z_offset_pulley];*/
xaxis_beltpath_z_offsets = [-3*mm-xaxis_beltpath_z_offset_pulley, 3*mm+xaxis_beltpath_z_offset_pulley];
xaxis_beltpath_height_body = xaxis_pulley_outer_d/2+3*mm+v_sum(v_abs(xaxis_beltpath_z_offsets))+5*mm;
xaxis_beltpath_height_holders = max(xaxis_pulley_outer_d+2*mm, xaxis_pulley_inner_d+xaxis_beltpath_z_offsets[0]+3*mm);

xaxis_carriage_bearing_offset_y = ziptie_thickness+3*mm;
xaxis_carriage_beltpath_offset_y = xaxis_carriage_bearing_offset_y+xaxis_bearing[1]/2;

xaxis_motor = dict_replace(Nema17, NemaFrontAxleLength, 22*mm);
xaxis_motor_thread=ThreadM3;
xaxis_motor_nut=MHexNutM3;

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=bearing_bronze_12_18_18;
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 + 10*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];
printbed_size = [213*mm,213*mm,3*mm];

zaxis_rod_d = 11.975*mm;
zaxis_rod_l = 500*mm;
// relative to entire machine
zaxis_rod_offset = [0,-20*mm,0];
zaxis_bearing=bearing_bronze_12_18_18;

// 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, screw_dist, screw_thread
zaxis_nut = [20*mm, 36*mm, 8*mm, 5*mm, 23*mm, 13.5*mm, ThreadM3];

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

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_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_ = max(xaxis_rod_d/2 + zaxis_bearing[1]/2, zaxis_nut[1]/2 - xaxis_rod_d/2);
xaxis_zaxis_distance_y = xaxis_zaxis_distance_y_ + ziptie_type[0]+.5*mm + 1*mm;

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

// offset between Z motor screw and z rod
// 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);

// z rod offset from lower extrusion (outer)
zmotor_mount_rod_offset_x = zmotor_w/2+zaxis_rod_screw_distance_x+zmotor_mount_motor_offset;

// z screw offset from lower extrusion (outer)
zmotor_mount_screw_offset_x = zmotor_mount_rod_offset_x - zaxis_rod_screw_distance_x;

color_extrusion = "DimGray";
color_rods = "CornflowerBlue";
color_part = "DarkRed";
color_gantry_connectors = "OliveDrab";

include <MCAD/stepper.scad>
include <thing_libutils/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>
include <thing_libutils/timing-belts-data.scad>

e=0.01*mm;

// high quality etc
is_build = false;

// minimum size of a fragment
// resolution of any round object (segment length)
// Because of this variable very small circles have a smaller number of fragments than specified using $fa.
// The default value is 2.
$fs = is_build ? 0.5 : 2;

// minimum angle for a fragment.
// The default value is 12 (i.e. 30 fragments for a full circle)
$fa = is_build ? 4 : 12;

$show_vit = is_build ? false : true;

// enable preview model (faster openscad)
$preview_mode = is_build ? false : true;

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;

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

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

// for tapped ends
extrusion_end_nut = MHexNutM6;

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

gantry_connector_thickness = 5;

rod_fit_tolerance=1.01;

ziptie_type = [2*mm, 3*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;
// relative to entire machine
xaxis_rod_offset_x = 0*mm;
xaxis_bearings_top=2;
xaxis_bearings_bottom=1;
xaxis_bearing=bearing_bronze_10_16_12;
xaxis_bearing_bottom=bearing_bronze_10_16_18;
/*xaxis_bearing=bearing_igus_rj4jp_01_10;*/

xaxis_pulley = pulley_2GT_20T;
xaxis_pulley_inner_d = xaxis_pulley[2];
xaxis_pulley_outer_d = xaxis_pulley[3];
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 = TimingBelt_GT2_2;
xaxis_belt_width = 6*mm;
xaxis_beltpath_width = max(xaxis_belt_width+3*mm, xaxis_pulley[0]+2*mm);
xaxis_beltpath_z_offset_pulley = xaxis_pulley_inner_d/2;
/*xaxis_beltpath_z_offsets = [xaxis_beltpath_z_offset_pulley];*/
xaxis_beltpath_z_offsets = [-3*mm-xaxis_beltpath_z_offset_pulley, 3*mm+xaxis_beltpath_z_offset_pulley];
xaxis_beltpath_height_body = xaxis_pulley_outer_d/2+3*mm+v_sum(v_abs(xaxis_beltpath_z_offsets))+5*mm;
xaxis_beltpath_height_holders = max(xaxis_pulley_outer_d+2*mm, xaxis_pulley_inner_d+xaxis_beltpath_z_offsets[0]+3*mm);

xaxis_carriage_bearing_offset_y = ziptie_thickness+1*mm;
xaxis_carriage_beltpath_offset_y = xaxis_carriage_bearing_offset_y+xaxis_bearing[1]/2;

xaxis_motor = dict_replace(Nema17, NemaFrontAxleLength, 22*mm);
xaxis_motor_thread=ThreadM3;
xaxis_motor_nut=MHexNutM3;

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=bearing_bronze_12_18_18;
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 + 10*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];
printbed_size = [213*mm,213*mm,3*mm];

zaxis_rod_d = 11.975*mm;
zaxis_rod_l = 500*mm;
// relative to entire machine
zaxis_rod_offset = [0,-20*mm,0];
zaxis_bearing=bearing_bronze_12_18_18;

// 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, screw_dist, screw_thread
zaxis_nut = [20*mm, 36*mm, 8*mm, 5*mm, 23*mm, 13.5*mm, ThreadM3];

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

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_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_ = max(xaxis_rod_d/2 + zaxis_bearing[1]/2, zaxis_nut[1]/2 - xaxis_rod_d/2);
xaxis_zaxis_distance_y = xaxis_zaxis_distance_y_ + ziptie_type[0]+.5*mm + 1*mm;

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

// offset between Z motor screw and z rod
// 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);

// z rod offset from lower extrusion (outer)
zmotor_mount_rod_offset_x = zmotor_w/2+zaxis_rod_screw_distance_x+zmotor_mount_motor_offset;

// z screw offset from lower extrusion (outer)
zmotor_mount_screw_offset_x = zmotor_mount_rod_offset_x - zaxis_rod_screw_distance_x;

color_extrusion = "DimGray";
color_rods = "CornflowerBlue";
color_part = "DarkRed";
color_gantry_connectors = "OliveDrab";


tighten up for newer, lower spread printer

// $URL: svn+ssh://mrwhat@ssh.boim.com/home/mrwhat/svn/Walker/trunk/motorMount.scad $
// $Id: motorMount.scad 427 2014-08-23 20:42:39Z mrwhat $

// Mount to attach to axles and hold motor drive module

// shape of small gearhead motor GA12YN20 from fasttech.com
module gearheadMotorProxyGA12(pad) { union() {
cube([10+pad,12+pad,9.2+pad],center=true);
translate([0,0,-(9.2+pad)/2-7.9]) difference() {
   cylinder(h=10,r=1.5,$fn=36);
   translate([1,-2,-.1]) cube([2,4,7.7]); }
intersection() {
   translate([0,0,9.2/2-1])cylinder(h=15+pad+1,r=(12+pad)/2,$fn=48);
   cube([10+pad,12+pad,66],center=true); }
}}

// Slightly larger 60RPM gearhead motor.
// same size?  35RPM GA16Y030 fasttech
module gearheadMotorProxyGA16(pad) {
difference() { union(){
translate([0,0,10-29]) cylinder(h=29,r=7.75+pad,$fn=64);
cylinder(h=10+5,r=1.5,$fn=36);
}
translate([ 6  ,-10,10-29-1]) cube([5,20,29-10+1]);
translate([-6-5,-10,10-29-1]) cube([5,20,29-10+1]);
translate([1.5-(3-2.44),-2,1+10]) cube([2,4,5]);
}}

// larger 30RPM gearhead (as delivered) motor GA25Y310 fasttech
// photo and specs on site do not match delivered product.
// drawing is of delivered product, marked 25GA370-98, 30RPM
module gearheadMotorProxyGA25(pad) {
difference() { union(){
translate([0,0,-31]) cylinder(h=32,r=12.2+pad,$fn=64);
cylinder(h=23.5,r=12.6+pad,$fn=64);
translate([0,0,24]) cylinder(h=10,r=2,$fn=36);
translate([0,0,23]) cylinder(h=2.5,r=3.5,$fn=36);
}
translate([1.5,-3,23.5+3]) cube([2,6,8]);
}}

bh=4;
br1=2;
br2=1.5;

module ulc(dx,dy) { translate([-20+dx,-1.5+dy,0]) cylinder(h=bh,r1=br1,r2=br2,$fn=6); }
module urc(dx,dy) { translate([ 20+dx,-1.5+dy,0]) cylinder(h=bh,r1=br1,r2=br2,$fn=6); }
module llc() { translate([ -6, -30,0]) cylinder(h=bh+2,r1=br1,r2=.5,$fn=6); }
module lrc() { translate([  6, -30,0]) cylinder(h=bh+2,r1=br1,r2=.5,$fn=6); }

dtFuzz = 0.08;  // fuzz to add to dove tail slots

module motorMount() {
  difference() {
    union() {
      hull() { ulc(0,0); urc(0,0); }
      hull() { ulc(2,-1); urc(-2,-1); }
      hull() { ulc(0,0); llc(); }
      hull() { urc(0,0); lrc(); }
      for (a=[-1,1]) hull() {
        translate([.6*a, -2,0]) cylinder(h=bh  ,r1=2,r2=0.5,$fn=6);
        translate([ 7*a,-25,0]) cylinder(h=bh+2,r1=2,r2=0.5,$fn=6);
      }

      hull() for (a=[-1,1]) {
        translate([5*a,-24,0]) cylinder(h=bh*2,r1=3.2,r2=3,$fn=6);
        translate([4*a,-32,0]) cylinder(h=20  ,r1=4.6,r2=4,$fn=6);
      }
    }

    // dove-tail receivers, 2x as high as actual, with 2x radius reduction
    // so they have the same wall slope, but are extra long to make
    // sure they cut all the way through the top brace bar
    for (a=[-1,1]) translate([10*a,-1,1-0.1]) rotate([0,0,-30])
       cylinder(h=6,r2=5+dtFuzz,r1=3+dtFuzz,$fn=3);

    #translate([0,-30,3.9]) gearheadMotorProxyGA12(0.4);
  }
}

if (WITH_BRIM) {
union() { color("Cyan") hull() {
  translate([-30,0,0]) cube([60,7,.4]);
  translate([-13,-42,0]) cube([26,.1,.4]); }
translate([0,0,.2]) motorMount();
}}
else { motorMount(); }

//%translate([0,30,0])  gearheadMotorProxyGA16(0);
//%translate([30,0,0])  gearheadMotorProxyGA12(0.2);
//%translate([-40,0,0]) gearheadMotorProxyGA25(0.2);

// $URL: svn+ssh://mrwhat@ssh.boim.com/home/mrwhat/svn/Walker/trunk/motorMount.scad $
// $Id: motorMount.scad 427 2014-08-23 20:42:39Z mrwhat $

// Mount to attach to axles and hold motor drive module

// shape of small gearhead motor GA12YN20 from fasttech.com
module gearheadMotorProxyGA12(pad) { union() {
cube([10+pad,12+pad,9.2+pad],center=true);
translate([0,0,-(9.2+pad)/2-7.9]) difference() {
   cylinder(h=10,r=1.5,$fn=36);
   translate([1,-2,-.1]) cube([2,4,7.7]); }
intersection() {
   translate([0,0,9.2/2-1])cylinder(h=15+pad+1,r=(12+pad)/2,$fn=48);
   cube([10+pad,12+pad,66],center=true); }
}}

// Slightly larger 60RPM gearhead motor.
// same size?  35RPM GA16Y030 fasttech
module gearheadMotorProxyGA16(pad) {
difference() { union(){
translate([0,0,10-29]) cylinder(h=29,r=7.75+pad,$fn=64);
cylinder(h=10+5,r=1.5,$fn=36);
}
translate([ 6  ,-10,10-29-1]) cube([5,20,29-10+1]);
translate([-6-5,-10,10-29-1]) cube([5,20,29-10+1]);
translate([1.5-(3-2.44),-2,1+10]) cube([2,4,5]);
}}

// larger 30RPM gearhead (as delivered) motor GA25Y310 fasttech
// photo and specs on site do not match delivered product.
// drawing is of delivered product, marked 25GA370-98, 30RPM
module gearheadMotorProxyGA25(pad) {
difference() { union(){
translate([0,0,-31]) cylinder(h=32,r=12.2+pad,$fn=64);
cylinder(h=23.5,r=12.6+pad,$fn=64);
translate([0,0,24]) cylinder(h=10,r=2,$fn=36);
translate([0,0,23]) cylinder(h=2.5,r=3.5,$fn=36);
}
translate([1.5,-3,23.5+3]) cube([2,6,8]);
}}

bh=5;
br1=2.2;
br2=2;

module ulc(dx,dy) { translate([-20+dx,-1.5+dy,0]) cylinder(h=bh,r1=br1,r2=br2,$fn=6); }
module urc(dx,dy) { translate([ 20+dx,-1.5+dy,0]) cylinder(h=bh,r1=br1,r2=br2,$fn=6); }
module llc() { translate([ -6, -30,0]) cylinder(h=bh,r1=br1,r2=br2,$fn=6); }
module lrc() { translate([  6, -30,0]) cylinder(h=bh,r1=br1,r2=br2,$fn=6); }

module motorMount() { difference() { union() {
//hull() { translate([-22,-1.5,0]) cube([44,2,5]);
//          translate([ -8,-32 ,0]) cube([16,1,5]); }
hull() { ulc(0,0); urc(0,0); }
hull() { ulc(2,-2); urc(-2,-2); }
//hull() { llc(); lrc(); }
hull() { ulc(0,0); llc(); }
hull() { urc(0,0); lrc(); }
hull() { translate([ 0, -3,0]) cylinder(h=bh,r1=br1,r2=br2,$fn=6);
         translate([-7,-22,0]) cylinder(h=bh,r1=br1,r2=br2,$fn=6); }
hull() { translate([ 0, -3,0]) cylinder(h=bh,r1=br1,r2=br2,$fn=6);
         translate([ 7,-22,0]) cylinder(h=bh,r1=br1,r2=br2,$fn=6); }
//translate([-17,-5,0]) cylinder(h=bh,r1=4.2,r2=4,$fn=6);

//translate([-8,-30,0]) cube([16,13,5]);
hull() {
   translate([-5,-24,0]) cylinder(h=bh*2,r1=3.2,r2=3,$fn=6);
   translate([-4,-32,0]) cylinder(h=20  ,r1=4.6,r2=4,$fn=6);

   translate([ 5,-24,0]) cylinder(h=bh*2,r1=3.2,r2=3,$fn=6);
   translate([ 4,-32,0]) cylinder(h=20  ,r1=4.6,r2=4,$fn=6);
}}
#translate([0,-30,3.9]) gearheadMotorProxyGA12(0.4);
translate([ 10,0,0.8]) rotate([0,0,-30]) cylinder(h=4.4,r2=4+.4,r1=3+.2,$fn=3);
translate([-10,0,0.8]) rotate([0,0,-30]) cylinder(h=4.4,r2=4+.4,r1=3+.2,$fn=3);
}}

if (WITH_BRIM) {
union() { color("Cyan") hull() {
  translate([-30,0,0]) cube([60,7,.4]);
  translate([-13,-42,0]) cube([26,.1,.4]); }
translate([0,0,.2]) motorMount();
}}
else { motorMount(); }

//%translate([0,30,0])  gearheadMotorProxyGA16(0);
//%translate([30,0,0])  gearheadMotorProxyGA12(0.2);
//%translate([-40,0,0]) gearheadMotorProxyGA25(0.2);


bigger rail

bigger rail

module _lower_grip(){
     union(){
          difference(){
               union(){
                    hull(){
                         translate([0., -1.]) circle(0.5);
                         translate([1.25, -1.]) circle(0.5);
                    }
                    translate([0., -1]) square([1.75, 1]);
               }
               hull(){
                    circle(0.55);
                    translate([-0.95, 0.5]) circle(0.05);
                    translate([-1., -0.5]) square(1.);
                    translate([-0.95, -0.5]) circle(0.05);
               }
          }
     }
}

module _upper_grip(){
     union(){
          difference(){
               union(){
                    translate([-1.25, 0.5]) circle(1);
                    translate([-1.5, 0.5]) square(0.5);
                    hull(){
                         translate([-1., 1.]) circle(0.5);
                         translate([1.25, 1.]) circle(0.5);
                    }
                    translate([0., 0]) square([1.75, 1]);
               }
               hull(){
                    circle(0.55);
                    translate([-0.95, 0.5]) circle(0.05);
                    translate([-1., -0.5]) square(1.);
                    translate([-0.95, -0.5]) circle(0.05);
               }
          }
     }
}

module _grip(e=2.){
     union(){
          translate([0., -(e-1)/2]) _lower_grip();
          translate([0.55, -(e-1)/2]) square([1.2, e - 1]);
          translate([0., (e-1)/2]) _upper_grip();
     }
}

module left_grip(e=2., phi_sphere=20., shift=1.){
     angle = (2*(shift+1.75) / phi_sphere) * 180/3.1415926;

          rotate([0, 6, 0]) rotate([0, 0, 90]) rotate([0, -90, 0])
          rotate_extrude(angle=12){
               rotate([0, 0, angle])
               translate([phi_sphere/2, 0])
                    rotate([0, 0, -90]) _grip(e);
     }
}

module right_grip(e=2., phi_sphere=20., shift=1.){
     mirror([0, 1, 0]) left_grip(e=e, phi_sphere=phi_sphere, shift=shift);
}

module _hole(e=2., phi_sphere=20., clear=4.)
{
     angle = (2*(clear/2. + 1.75) / phi_sphere) * 180/3.1415926;
     offset(r=0.15){
          union(){
               rotate([0, 0, angle])
                    translate([phi_sphere/2, 0])
                    union(){
                    rotate([0, 0, -90]) _grip(e=e);
                    translate([-e/2-1, -clear-1.]) square([2+e, clear]);
               }
               rotate([0, 0, -angle])
                    translate([phi_sphere/2, 0])
                    mirror([0, 1, 0])
                    union(){
                    rotate([0, 0, -90]) _grip(e=e);
                    translate([-e/2-1, -clear-1.]) square([2+e, clear]);
               }
               translate([phi_sphere/2+0.8, 0]) square([e+1, 2], center=true);
          }
     }
}
//right_grip(e=2., phi_sphere=20., shift=3);
//left_grip(e=2., phi_sphere=20., shift=3);

module sphere_hole(e=2, phi_sphere=20., clear=1, aperture=120){
     rotate([0, aperture/2, 0])
          rotate([0, 0, 90])
          rotate([0, -90, 0])
          rotate_extrude(angle=aperture){
          _hole(e=e, phi_sphere=phi_sphere, clear=clear);
     }
}

module _lower_grip(){
     union(){
          difference(){
               union(){
                    hull(){
                         translate([0., -1.]) circle(0.5);
                         translate([1.25, -1.]) circle(0.5);
                    }
                    translate([0., -1]) square([1.75, 1]);
               }
               hull(){
                    circle(0.55);
                    translate([-0.95, 0.5]) circle(0.05);
                    translate([-1., -0.5]) square(1.);
                    translate([-0.95, -0.5]) circle(0.05);
               }
          }
     }
}

module _upper_grip(){
     union(){
          difference(){
               union(){
                    translate([-1.25, 0.5]) circle(0.25);
                    translate([-1.5, 0.5]) square(0.5);
                    hull(){
                         translate([-1., 1.]) circle(0.5);
                         translate([1.25, 1.]) circle(0.5);
                    }
                    translate([0., 0]) square([1.75, 1]);
               }
               hull(){
                    circle(0.55);
                    translate([-0.95, 0.5]) circle(0.05);
                    translate([-1., -0.5]) square(1.);
                    translate([-0.95, -0.5]) circle(0.05);
               }
          }
     }
}

module _grip(e=2.){
     union(){
          translate([0., -(e-1)/2]) _lower_grip();
          translate([0.55, -(e-1)/2]) square([1.2, e - 1]);
          translate([0., (e-1)/2]) _upper_grip();
     }
}

module left_grip(e=2., phi_sphere=20., shift=1.){
     angle = (2*(shift+1.75) / phi_sphere) * 180/3.1415926;

          rotate([0, 6, 0]) rotate([0, 0, 90]) rotate([0, -90, 0])
          rotate_extrude(angle=12){
               rotate([0, 0, angle])
               translate([phi_sphere/2, 0])
                    rotate([0, 0, -90]) _grip(e);
     }
}

module right_grip(e=2., phi_sphere=20., shift=1.){
     mirror([0, 1, 0]) left_grip(e=e, phi_sphere=phi_sphere, shift=shift);
}

module _hole(e=2., phi_sphere=20., clear=4.)
{
     angle = (2*(clear/2. + 1.75) / phi_sphere) * 180/3.1415926;
     offset(r=0.15){
          union(){
               rotate([0, 0, angle])
                    translate([phi_sphere/2, 0])
                    union(){
                    rotate([0, 0, -90]) _grip(e=e);
                    translate([-e/2-1, -clear-1.]) square([2+e, clear]);
               }
               rotate([0, 0, -angle])
                    translate([phi_sphere/2, 0])
                    mirror([0, 1, 0])
                    union(){
                    rotate([0, 0, -90]) _grip(e=e);
                    translate([-e/2-1, -clear-1.]) square([2+e, clear]);
               }
               translate([phi_sphere/2+0.8, 0]) square([e+1, 2], center=true);
          }
     }
}
//right_grip(e=2., phi_sphere=20., shift=3);
//left_grip(e=2., phi_sphere=20., shift=3);

module sphere_hole(e=2, phi_sphere=20., clear=1, aperture=120){
     rotate([0, aperture/2, 0])
          rotate([0, 0, 90])
          rotate([0, -90, 0])
          rotate_extrude(angle=aperture){
          _hole(e=e, phi_sphere=phi_sphere, clear=clear);
     }
}


Commented code was removed.

Commented code was removed.

//
// This OpenScad script generates coins, pendants, and ornaments.
//
// Author: Roberto Marquez - http://electronics.onebeartoe.org/
//
// This OpenSCAD script is a derivative of:
//
// Customizable Gimbal v1.0
// by TheNewHobbyist 2014 (http://thenewhobbyist.com)
// http://www.thingiverse.com/thing:340948
// https://github.com/thenewhobbyist/OpenSCAD/tree/master/Customizable%20Gimble
//
// "Customizable Gimbal" as well as this script are licensed under a
// Creative Commons Attribution-NonCommercial 3.0 Unported License.
//
// TheNewHobbyist's Inspiration and attribution:
//
// Printrbot Gimbal by DesignMakeTeach
// http://www.thingiverse.com/thing:317778
// Licensed under the Creative Commons - Attribution - Share Alike license.
//
// Stencil-o-Matic by Benjamin
// http://www.thingiverse.com/thing:55821
// Licensed under the Creative Commons - Attribution - Non-Commercial license.

use <coins/coin.scad>;
use <../shapes/open-cylinder/open-cylinder.scad>

$fn=100;

module ornament(height = 3,
                includeGimbal = "yes", // [yes, no]
                innerIcon = "Batman",
                innerIconXyScale = 1.10,
                innerIconOffsetY = -4,
                outerIcon = "Nothing", //"Tree",
                outerIconXyScale = 0.2,
                outerIconCount = 10)
{
    {
        coinScale =  0.2;//0.199248

        union()
        {
            if(includeGimbal == "yes")
            {
                ring1(height);
                ring2(height);
                ring3(height);

                xyScale = 0.5;
                zTranslate = -height / 2.0;
                translate([0, -22, zTranslate])
                scale([xyScale, xyScale, 1])
                openCylinder(center=true);
            }

            difference()
            {
                color("blue")
                scale([coinScale, -coinScale, 1])
                coin(innerIcon = innerIcon,
                     innerIconXyScale = innerIconXyScale,
                     innerIconOffsetY = innerIconOffsetY,
                     outerIcon = outerIcon,
                     outerIconCount = outerIconCount,
                     outerIconXyScale = outerIconXyScale,
                     radius = 55,
                     height=height
                );

                clipOversizedImages(center=true);
            }
        }
    }
}

module clipOversizedImages()
{
	difference()
	{
		cylinder(r=200, h=10, center=true);
		cylinder(r=11, h=11, center=true);
	}
}

module ring1(height)
{
	difference()
	{
	    color("pink")
    	cylinder(r=19.35, h=height, center=true);

    	cylinder(r=17.35, h=56, center=true);
    	translate([17.45,0,0]) rotate([0,90,0]) cylinder(r1=1.7, r2=0, h=2.1, center=true);
    	translate([-17.45,0,0]) rotate([0,270,0]) cylinder(r1=1.7, r2=0, h=2.1, center=true);
	}
}

module ring2(height)
{
	translate([16.95,0,0]) rotate([0,90,0]) cylinder(r1=1.7, r2=0, h=2.1, center=true);
	translate([-16.95,0,0]) rotate([0,270,0]) cylinder(r1=1.7, r2=0, h=2.1, center=true);
	difference()
	{
	    color("grey")
		cylinder(r=15.95, h=height, center=true);

		cylinder(r=13.95, h=56, center=true);
		translate([0,-14.2,0]) rotate([90,0,0]) cylinder(r1=1.7, r2=0, h=2.1, center=true);
		translate([0,14.2,0]) rotate([270,0,0]) cylinder(r1=1.7, r2=0, h=2.1, center=true);
	}
}

module ring3(height)
{
	translate([0,13.75,0]) rotate([270,0,0]) cylinder(r1=1.7, r2=0, h=2.1, center=true);
	translate([0,-13.75,0]) rotate([90,0,0]) cylinder(r1=1.7, r2=0, h=2.1, center=true);
	difference()
	{
		cylinder(r=12.75, h=height, center=true);
		cylinder(r=10.75, h=56, center=true);
	}
}

//
// This OpenScad script generates coins, pendants, and ornaments.
//
// Author: Roberto Marquez - http://electronics.onebeartoe.org/
//
// This OpenSCAD script is a derivative of:
//
// Customizable Gimbal v1.0
// by TheNewHobbyist 2014 (http://thenewhobbyist.com)
// http://www.thingiverse.com/thing:340948
// https://github.com/thenewhobbyist/OpenSCAD/tree/master/Customizable%20Gimble
//
// "Customizable Gimbal" as well as this script are licensed under a
// Creative Commons Attribution-NonCommercial 3.0 Unported License.
//
// TheNewHobbyist's Inspiration and attribution:
//
// Printrbot Gimbal by DesignMakeTeach
// http://www.thingiverse.com/thing:317778
// Licensed under the Creative Commons - Attribution - Share Alike license.
//
// Stencil-o-Matic by Benjamin
// http://www.thingiverse.com/thing:55821
// Licensed under the Creative Commons - Attribution - Non-Commercial license.

use <coins/coin.scad>;
use <../shapes/open-cylinder/open-cylinder.scad>

$fn=100;

//ornament();

module ornament(height = 3,
                includeGimbal = "yes", // [yes, no]
                innerIcon = "Batman",
                innerIconXyScale = 1.10,
                innerIconOffsetY = -4,
                outerIcon = "Nothing", //"Tree",
                outerIconXyScale = 0.2,
                outerIconCount = 10)
{
    {
        coinScale =  0.2;//0.199248

        union()
        {
            if(includeGimbal == "yes")
            {
                ring1(height);
                ring2(height);
                ring3(height);

                xyScale = 0.5;
                zTranslate = -height / 2.0;
                translate([0, -22, zTranslate])
                scale([xyScale, xyScale, 1])
                openCylinder(center=true);
            }

            difference()
            {
                color("blue")
                scale([coinScale, -coinScale, 1])
                coin(innerIcon = innerIcon,
                     innerIconXyScale = innerIconXyScale,
                     innerIconOffsetY = innerIconOffsetY,
                     outerIcon = outerIcon,
                     outerIconCount = outerIconCount,
                     outerIconXyScale = outerIconXyScale,
                     radius = 55,
                     height=height
                );

                clipOversizedImages(center=true);
            }
        }
    }
}

module clipOversizedImages()
{
	difference()
	{
		cylinder(r=200, h=10, center=true);
		cylinder(r=11, h=11, center=true);
	}
}

module ring1(height)
{
	difference()
	{
	    color("pink")
    	cylinder(r=19.35, h=height, center=true);

    	cylinder(r=17.35, h=56, center=true);
    	translate([17.45,0,0]) rotate([0,90,0]) cylinder(r1=1.7, r2=0, h=2.1, center=true);
    	translate([-17.45,0,0]) rotate([0,270,0]) cylinder(r1=1.7, r2=0, h=2.1, center=true);
	}
}

module ring2(height)
{
	translate([16.95,0,0]) rotate([0,90,0]) cylinder(r1=1.7, r2=0, h=2.1, center=true);
	translate([-16.95,0,0]) rotate([0,270,0]) cylinder(r1=1.7, r2=0, h=2.1, center=true);
	difference()
	{
	    color("grey")
		cylinder(r=15.95, h=height, center=true);

		cylinder(r=13.95, h=56, center=true);
		translate([0,-14.2,0]) rotate([90,0,0]) cylinder(r1=1.7, r2=0, h=2.1, center=true);
		translate([0,14.2,0]) rotate([270,0,0]) cylinder(r1=1.7, r2=0, h=2.1, center=true);
	}
}

module ring3(height)
{
	translate([0,13.75,0]) rotate([270,0,0]) cylinder(r1=1.7, r2=0, h=2.1, center=true);
	translate([0,-13.75,0]) rotate([90,0,0]) cylinder(r1=1.7, r2=0, h=2.1, center=true);
	difference()
	{
		cylinder(r=12.75, h=height, center=true);
		cylinder(r=10.75, h=56, center=true);
	}
}


Citosine

Citosine


xaxis/ends: Rework

xaxis/ends: Rework

Add stop for xrods on motor sid
Remove side functionality, just mirror
Add show_bearing


Fix typo and simplify computation of 2D polygons

/**
 * @license
 * MIT License
 *
 * Copyright (c) 2017 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.
 *
 * Polygon shapes.
 *
 * @package shape/2D
 * @author jsconan
 */

/**
 * Computes the size of a rectangle shape.
 *
 * @param Number|Vector [size] - The size of the rectangle.
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @returns Vector - Returns the size vector.
 */
function sizeRectangle(size, l, w) =
    let(
        size = apply2D(size, l, w)
    )
    [
        divisor(size[0]),
        divisor(size[1])
    ]
;

/**
 * Computes the size of a chamfered rectangle shape.
 *
 * @param Number|Vector [size] - The size of the chamfered rectangle.
 * @param Number|Vector [chamfer] - The size of the chamfers.
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [cl] - The length of the chamfers.
 * @param Number [cw] - The width of the chamfers.
 * @returns Vector[] - Returns an array containing the size vector and the chamfer vector.
 */
function sizeChamferedRectangle(size, chamfer, l, w, cl, cw) =
    let(
        s = apply2D(size, l, w),
        c = apply2D(chamfer, cl, cw),
        size = [
            divisor(s[0] ? s[0] : c[0] * 2),
            divisor(s[1] ? s[1] : c[1] * 2)
        ],
        chamfer = [
            min(size[0] / 2, c[0]),
            min(size[1] / 2, c[1])
        ]
    )
    [ size, chamfer[0] && chamfer[1] ? chamfer : [0, 0] ]
;

/**
 * Computes the size of a trapezium shape.
 *
 * @param Number|Vector [size] - The size of the trapezium.
 * @param Number [a] - The length of the bottom base.
 * @param Number [b] - The length of the top base.
 * @param Number [w] - The width between bases.
 * @returns Vector - Returns the size vector, as [a, b, w].
 */
function sizeTrapezium(size, a, b, w) =
    let(
        size = apply3D(size, a, b, w)
    )
    [
        divisor(size[0]),
        divisor(size[1]),
        divisor(size[2])
    ]
;

/**
 * Computes the size of a regular polygon.
 *
 * @param Number|Vector [size] - The size of the polygon.
 * @param Number [n] - The number of facets (min. 3).
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [s] - The length of a side.
 * @returns Vector - Returns the size vector, as [l, w, n].
 */
function sizeRegularPolygon(size, n, l, w, s) =
    let(
        n = max(3, float(n)),
        size = (s && !size && !l && !w) ? vector2D(2 * divisor(s) / (2 * sin(STRAIGHT / n)))
                                        : apply2D(size, l, w)
    )
    [
        divisor(size[0]),
        divisor(size[1]),
        n
    ]
;

/**
 * Computes the size of a star shape.
 *
 * @param Number|Vector [size] - The outer size of the star.
 * @param Number|Vector [core] - The size of the core.
 * @param Number [edges] - The number of star edges (min. 3).
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [cl] - The core length.
 * @param Number [cw] - The core width.
 * @returns Vector[] - Returns two vectors containing the outer and core size of the star
 */
function sizeStar(size, core, edges, l, w, cl, cw) =
    let(
        edges = max(3, float(edges)),
        size = divisor2D(apply2D(size, l, w)),
        core = apply2D(core, cl, cw)
    )
    [
        size,
        core == [0, 0] ? size * or(1 - 3 / edges, 0.2) : core,
        edges
    ]
;

/**
 * Computes the size of a cross shape.
 *
 * @param Number|Vector [size] - The outer size of the cross.
 * @param Number|Vector [core] - The size of the core.
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [cl] - The core length.
 * @param Number [cw] - The core width.
 * @returns Vector[] - Returns two vectors containing the outer and core size of the cross
 */
function sizeCross(size, core, l, w, cl, cw) =
    let(
        size = divisor2D(apply2D(size, l, w)),
        core = apply2D(core, cl, cw)
    )
    [
        size,
        core
    ]
;

/**
 * Computes the points that draws the sketch of a rectangle shape.
 *
 * @param Number|Vector [size] - The size of the rectangle.
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @returns Vector[]
 */
function drawRectangle(size, l, w) =
    let(
        size = sizeRectangle(size=size, l=l, w=w) / 2
    )
    [
        [ size[0],  size[1]],
        [-size[0],  size[1]],
        [-size[0], -size[1]],
        [ size[0], -size[1]]
    ]
;

/**
 * Computes the points that draws the sketch of a chamfered rectangle shape.
 *
 * @param Number|Vector [size] - The size of the chamfered rectangle.
 * @param Number|Vector [chamfer] - The size of the chamfers.
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [cl] - The length of the chamfers.
 * @param Number [cw] - The width of the chamfers.
 * @returns Vector[]
 */
function drawChamferedRectangle(size, chamfer, l, w, cl, cw) =
    let(
        specs = sizeChamferedRectangle(size=size, chamfer=chamfer, l=l, w=w, cl=cl, cw=cw),
        size = specs[0] / 2,
        chamfer = specs[1]
    )
    chamfer[0]
   ?[
        [ size[0],  size[1] - chamfer[1]],
        [ size[0] - chamfer[0],  size[1]],
        [-size[0] + chamfer[0],  size[1]],
        [-size[0],  size[1] - chamfer[1]],
        [-size[0], -size[1] + chamfer[1]],
        [-size[0] + chamfer[0], -size[1]],
        [ size[0] - chamfer[0], -size[1]],
        [ size[0], -size[1] + chamfer[1]]
    ]
   :[
        [ size[0],  size[1]],
        [-size[0],  size[1]],
        [-size[0], -size[1]],
        [ size[0], -size[1]]
    ]
;

/**
 * Computes the points that draws the sketch of a trapezium shape.
 *
 * @param Number|Vector [size] - The size of the trapezium.
 * @param Number [a] - The length of the bottom base.
 * @param Number [b] - The length of the top base.
 * @param Number [w] - The width between bases.
 * @returns Vector[w]
 */
function drawTrapezium(size, a, b, w) =
    let(
        size = sizeTrapezium(size=size, a=a, b=b, w=w) / 2
    )
    [
        [ size[1],  size[2]],
        [-size[1],  size[2]],
        [-size[0], -size[2]],
        [ size[0], -size[2]]
    ]
;

/**
 * Computes the points that draws the sketch of a regular polygon.
 *
 * @param Number|Vector [size] - The size of the polygon.
 * @param Number [n] - The number of facets (min. 3).
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [s] - The length of a side.
 * @returns Vector[]
 */
function drawRegularPolygon(size, n, l, w, s) =
    let(
        size = sizeRegularPolygon(size=size, n=n, l=l, w=w, s=s),
        n = size[2],
        step = DEGREES / n,
        radius = size / 2
    )
    [
        for(i = [0 : n - 1])
            arcp(radius, i * step + RIGHT)
    ]
;

/**
 * Computes the points that draws the sketch of an hexagon.
 *
 * @param Number|Vector [size] - The size of the hexagon.
 * @param Boolean [pointy] - Tells if the hexagon must be pointy topped (default: false, Flat topped).
 * @param Number [adjust] - An adjust length added on the horizontal side.
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [s] - The length of a side.
 * @returns Vector[]
 */
function drawHexagon(size, pointy, adjust, l, w, s) =
    let(
        n = 6,
        size = sizeRegularPolygon(size=size, n=n, l=l, w=w, s=s),
        step = DEGREES / n,
        radius = size / 2,
        adjust = float(adjust) / 2
    )
    pointy
   ?let(o = [0, adjust])    // pointy topped
        [
            arcp(radius, 30) + o,
            arcp(radius, 90) + o,
            arcp(radius, 150) + o,
            arcp(radius, 210) - o,
            arcp(radius, 270) - o,
            arcp(radius, 330) - o
        ]
   :let(o = [adjust, 0])    // flat topped
        [
            arcp(radius, 0) + o,
            arcp(radius, 60) + o,
            arcp(radius, 120) - o,
            arcp(radius, 180) - o,
            arcp(radius, 240) - o,
            arcp(radius, 300) + o
        ]
;

/**
 * Computes the points that draws the sketch of a star shape.
 *
 * @param Number|Vector [size] - The outer size of the star.
 * @param Number|Vector [core] - The size of the core.
 * @param Number [edges] - The number of star edges (min. 3).
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [cl] - The core length.
 * @param Number [cw] - The core width.
 * @returns Vector[]
 */
function drawStar(size, core, edges, l, w, cl, cw) =
    let(
        size = sizeStar(size=size, core=core, edges=edges, l=l, w=w, cl=cl, cw=cw),
        edges = size[2],
        inner = size[1],
        outer = size[0],
        angle = DEGREES / edges,
        step = angle / 2
    )
    [
        for (i = [0 : 2 * edges - 1])
            let(
                e = floor(i / 2),
                m = i % 2,
                a = angle * e + (m ? step : 0) + RIGHT
            )
            [
                cos(a) * (m ? inner[0] : outer[0]),
                sin(a) * (m ? inner[1] : outer[1])
            ]
    ]
;

/**
 * Computes the points that draws the sketch of a cross shape.
 *
 * @param Number|Vector [size] - The outer size of the cross.
 * @param Number|Vector [core] - The size of the core.
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [cl] - The core length.
 * @param Number [cw] - The core width.
 * @returns Vector[]
 */
function drawCross(size, core, l, w, cl, cw) =
    let(
        size = sizeCross(size=size, core=core, l=l, w=w, cl=cl, cw=cw),
        outer = size[0] / 2,
        inner = size[1] / 2
    )
    inner == [0, 0] ?
    [
        [ outer[0],  outer[1]],
        [-outer[0],  outer[1]],
        [-outer[0], -outer[1]],
        [ outer[0], -outer[1]]
    ]
   :[
        [ inner[0],  inner[1]],
        [ inner[0],  outer[1]],
        [-inner[0],  outer[1]],
        [-inner[0],  inner[1]],
        [-outer[0],  inner[1]],
        [-outer[0], -inner[1]],
        [-inner[0], -inner[1]],
        [-inner[0], -outer[1]],
        [ inner[0], -outer[1]],
        [ inner[0], -inner[1]],
        [ outer[0], -inner[1]],
        [ outer[0],  inner[1]]
    ]
;

/**
 * Creates a rectangle at the origin.
 *
 * @param Number|Vector [size] - The size of the rectangle.
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 */
module rectangle(size, l, w) {
    polygon(
        points = drawRectangle(size=size, l=l, w=w),
        convexity = 10
    );
}

/**
 * Creates a chamfered rectangle at the origin.
 *
 * @param Number|Vector [size] - The size of the chamfered rectangle.
 * @param Number|Vector [chamfer] - The size of the chamfers.
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [cl] - The length of the chamfers.
 * @param Number [cw] - The width of the chamfers.
 */
module chamferedRectangle(size, chamfer, l, w, cl, cw) {
    polygon(
        points = drawChamferedRectangle(size=size, chamfer=chamfer, l=l, w=w, cl=cl, cw=cw),
        convexity = 10
    );
}

/**
 * Creates a trapezium at the origin.
 *
 * @param Number|Vector [size] - The size of the trapezium.
 * @param Number [a] - The length of the bottom base.
 * @param Number [b] - The length of the top base.
 * @param Number [w] - The width between bases.
 */
module trapezium(size, a, b, w) {
    polygon(
        points = drawTrapezium(size=size, a=a, b=b, w=w),
        convexity = 10
    );
}

/**
 * Creates a regular polygon at the origin.
 *
 * @param Number|Vector [size] - The size of the polygon.
 * @param Number [n] - The number of facets (min. 3).
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [s] - The length of a side.
 */
module regularPolygon(size, n, l, w, s) {
    polygon(
        points = drawRegularPolygon(size=size, n=n, l=l, w=w, s=s),
        convexity = 10
    );
}

/**
 * Creates an hexagon at the origin.
 *
 * @param Number|Vector [size] - The size of the hexagon.
 * @param Boolean [pointy] - Tells if the hexagon must be pointy topped (default: false, Flat topped).
 * @param Number [adjust] - An adjust length added on the horizontal side.
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [s] - The length of a side.
 */
module hexagon(size, pointy, adjust, l, w, s) {
    polygon(
        points = drawHexagon(size=size, pointy=pointy, adjust=adjust, l=l, w=w, s=s),
        convexity = 10
    );
}

/**
 * Creates a star at the origin.
 *
 * @param Number|Vector [size] - The outer size of the star.
 * @param Number|Vector [core] - The size of the core.
 * @param Number [edges] - The number of star edges (min. 3).
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [cl] - The core length.
 * @param Number [cw] - The core width.
 */
module star(size, core, edges, l, w, cl, cw) {
    polygon(
        points = drawStar(size=size, core=core, edges=edges, l=l, w=w, cl=cl, cw=cw),
        convexity = 10
    );
}

/**
 * Creates a cross at the origin.
 *
 * @param Number|Vector [size] - The outer size of the cross.
 * @param Number|Vector [core] - The size of the core.
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [cl] - The core length.
 * @param Number [cw] - The core width.
 */
module regularCross(size, core, l, w, cl, cw) {
    polygon(
        points = drawCross(size=size, core=core, l=l, w=w, cl=cl, cw=cw),
        convexity = 10
    );
}

/**
 * Creates a mesh with honeycomb cells using a hex grid pattern.
 *
 * @param Number|Vector [size] - The outer size of the mesh.
 * @param Number|Vector [count] - The number of cells on each lines and each columns.
 * @param Number|Vector [gap] - The space between two cells.
 * @param Boolean [pointy] - Tells if the hexagons in the mesh are pointy topped (default: false, Flat topped).
 * @param Boolean [linear] - Tells if the hex grid is linear instead of radial (default: false).
 * @param Boolean [even] - Tells if the first hexagons of a the linear grid should be below the line (default: false).
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [cx] - The number of cells per lines.
 * @param Number [cy] - The number of cells per columns.
 * @param Number [gx] - The space between two cells on each lines.
 * @param Number [gy] - The space between two cells on each columns.
 */
module mesh(size, count, gap, pointy, linear, even, l, w, cx, cy, gx, gy) {
    size = apply2D(size, l, w);
    count = divisor2D(apply2D(count, cx, cy));
    gap = apply2D(gap, gx, gy);
    cell = sizeHexCell(size=size, count=count, pointy=pointy, linear=linear);
    inner = cell - gap;
    offset = offsetHexGrid(size=cell, count=count, pointy=pointy, linear=linear, even=even);

    for(hex = buildHexGrid(count=count, linear=linear)) {
        translate(offset + coordHexCell(hex=hex, size=cell, linear=linear, even=even, pointy=pointy)) {
            hexagon(size=inner, pointy=pointy);
        }
    }
}

/**
 * @license
 * MIT License
 *
 * Copyright (c) 2017 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.
 *
 * Polygon shapes.
 *
 * @package shape/2D
 * @author jsconan
 */

/**
 * Computes the size of a rectangle shape.
 *
 * @param Number|Vector [size] - The size of the rectangle.
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @returns Vector - Returns the size vector.
 */
function sizeRectangle(size, l, w) =
    let(
        size = apply2D(size, l, w)
    )
    [
        divisor(size[0]),
        divisor(size[1])
    ]
;

/**
 * Computes the size of a chamfered rectangle shape.
 *
 * @param Number|Vector [size] - The size of the chamfered rectangle.
 * @param Number|Vector [chamfer] - The size of the chamfers.
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [cl] - The length of the chamfers.
 * @param Number [cw] - The width of the chamfers.
 * @returns Vector[] - Returns an array containing the size vector and the chamfer vector.
 */
function sizeChamferedRectangle(size, chamfer, l, w, cl, cw) =
    let(
        s = apply2D(size, l, w),
        c = apply2D(chamfer, cl, cw),
        size = [
            divisor(s[0] ? s[0] : c[0] * 2),
            divisor(s[1] ? s[1] : c[1] * 2)
        ],
        chamfer = [
            min(size[0] / 2, c[0]),
            min(size[1] / 2, c[1])
        ]
    )
    [ size, chamfer[0] && chamfer[1] ? chamfer : [0, 0] ]
;

/**
 * Computes the size of a trapezium shape.
 *
 * @param Number|Vector [size] - The size of the trapezium.
 * @param Number [a] - The length of the bottom base.
 * @param Number [b] - The length of the top base.
 * @param Number [w] - The width between bases.
 * @returns Vector - Returns the size vector, as [a, b, w].
 */
function sizeTrapezium(size, a, b, w) =
    let(
        size = apply3D(size, a, b, w)
    )
    [
        divisor(size[0]),
        divisor(size[1]),
        divisor(size[2])
    ]
;

/**
 * Computes the size of a regular polygon.
 *
 * @param Number|Vector [size] - The size of the polygon.
 * @param Number [n] - The number of facets (min. 3).
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [s] - The length of a side.
 * @returns Vector - Returns the size vector, as [l, w, n].
 */
function sizeRegularPolygon(size, n, l, w, s) =
    let(
        n = max(3, float(n)),
        size = (s && !size && !l && !w) ? vector2D(2 * divisor(s) / (2 * sin(STRAIGHT / n)))
                                        : apply2D(size, l, w)
    )
    [
        divisor(size[0]),
        divisor(size[1]),
        n
    ]
;

/**
 * Computes the size of a star shape.
 *
 * @param Number|Vector [size] - The outer size of the star.
 * @param Number|Vector [core] - The size of the core.
 * @param Number [edges] - The number of star edges (min. 3).
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [cl] - The core length.
 * @param Number [cw] - The core width.
 * @returns Vector[] - Returns two vectors containing the outer and core size of the star
 */
function sizeStar(size, core, edges, l, w, cl, cw) =
    let(
        edges = max(3, float(edges)),
        size = divisor2D(apply2D(size, l, w)),
        core = apply2D(core, cl, cw)
    )
    [
        size,
        core == [0, 0] ? size * or(1 - 3 / edges, 0.2) : core,
        edges
    ]
;

/**
 * Computes the size of a cross shape.
 *
 * @param Number|Vector [size] - The outer size of the cross.
 * @param Number|Vector [core] - The size of the core.
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [cl] - The core length.
 * @param Number [cw] - The core width.
 * @returns Vector[] - Returns two vectors containing the outer and core size of the cross
 */
function sizeCross(size, core, l, w, cl, cw) =
    let(
        size = divisor2D(apply2D(size, l, w)),
        core = apply2D(core, cl, cw)
    )
    [
        size,
        core
    ]
;

/**
 * Computes the points that draw the sketch of a rectangle shape.
 *
 * @param Number|Vector [size] - The size of the rectangle.
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @returns Vector[]
 */
function drawRectangle(size, l, w) =
    let(
        size = sizeRectangle(size=size, l=l, w=w),
        half = size / 2
    )
    [
        [ half[0],  half[1]],
        [-half[0],  half[1]],
        [-half[0], -half[1]],
        [ half[0], -half[1]]
    ]
;

/**
 * Computes the points that draw the sketch of a chamfered rectangle shape.
 *
 * @param Number|Vector [size] - The size of the chamfered rectangle.
 * @param Number|Vector [chamfer] - The size of the chamfers.
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [cl] - The length of the chamfers.
 * @param Number [cw] - The width of the chamfers.
 * @returns Vector[]
 */
function drawChamferedRectangle(size, chamfer, l, w, cl, cw) =
    let(
        specs = sizeChamferedRectangle(size=size, chamfer=chamfer, l=l, w=w, cl=cl, cw=cw),
        size = specs[0],
        chamfer = specs[1],
        half = size / 2
    )
    chamfer[0]
   ?[
        [ half[0],  half[1] - chamfer[1]],
        [ half[0] - chamfer[0],  half[1]],
        [-half[0] + chamfer[0],  half[1]],
        [-half[0],  half[1] - chamfer[1]],
        [-half[0], -half[1] + chamfer[1]],
        [-half[0] + chamfer[0], -half[1]],
        [ half[0] - chamfer[0], -half[1]],
        [ half[0], -half[1] + chamfer[1]]
    ]
   :[
        [ half[0],  half[1]],
        [-half[0],  half[1]],
        [-half[0], -half[1]],
        [ half[0], -half[1]]
    ]
;

/**
 * Computes the points that draw the sketch of a trapezium shape.
 *
 * @param Number|Vector [size] - The size of the trapezium.
 * @param Number [a] - The length of the bottom base.
 * @param Number [b] - The length of the top base.
 * @param Number [w] - The width between bases.
 * @returns Vector[w]
 */
function drawTrapezium(size, a, b, w) =
    let(
        size = sizeTrapezium(size=size, a=a, b=b, w=w),
        half = size / 2
    )
    [
        [ half[1],  half[2]],
        [-half[1],  half[2]],
        [-half[0], -half[2]],
        [ half[0], -half[2]]
    ]
;

/**
 * Computes the points that draw the sketch of a regular polygon.
 *
 * @param Number|Vector [size] - The size of the polygon.
 * @param Number [n] - The number of facets (min. 3).
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [s] - The length of a side.
 * @returns Vector[]
 */
function drawRegularPolygon(size, n, l, w, s) =
    let(
        size = sizeRegularPolygon(size=size, n=n, l=l, w=w, s=s),
        n = size[2],
        step = DEGREES / n,
        radius = size / 2
    )
    [
        for(i = [0 : n - 1])
            arcp(radius, i * step + RIGHT)
    ]
;

/**
 * Computes the points that draw the sketch of an hexagon.
 *
 * @param Number|Vector [size] - The size of the hexagon.
 * @param Boolean [pointy] - Tells if the hexagon must be pointy topped (default: false, Flat topped).
 * @param Number [adjust] - An adjust length added on the horizontal side.
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [s] - The length of a side.
 * @returns Vector[]
 */
function drawHexagon(size, pointy, adjust, l, w, s) =
    let(
        n = 6,
        size = sizeRegularPolygon(size=size, n=n, l=l, w=w, s=s),
        step = DEGREES / n,
        radius = size / 2,
        adjust = float(adjust) / 2
    )
    pointy
   ?let(o = [0, adjust])    // pointy topped
        [
            arcp(radius, 30) + o,
            arcp(radius, 90) + o,
            arcp(radius, 150) + o,
            arcp(radius, 210) - o,
            arcp(radius, 270) - o,
            arcp(radius, 330) - o
        ]
   :let(o = [adjust, 0])    // flat topped
        [
            arcp(radius, 0) + o,
            arcp(radius, 60) + o,
            arcp(radius, 120) - o,
            arcp(radius, 180) - o,
            arcp(radius, 240) - o,
            arcp(radius, 300) + o
        ]
;

/**
 * Computes the points that draw the sketch of a star shape.
 *
 * @param Number|Vector [size] - The outer size of the star.
 * @param Number|Vector [core] - The size of the core.
 * @param Number [edges] - The number of star edges (min. 3).
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [cl] - The core length.
 * @param Number [cw] - The core width.
 * @returns Vector[]
 */
function drawStar(size, core, edges, l, w, cl, cw) =
    let(
        size = sizeStar(size=size, core=core, edges=edges, l=l, w=w, cl=cl, cw=cw),
        edges = size[2],
        inner = size[1],
        outer = size[0],
        angle = DEGREES / edges,
        step = angle / 2
    )
    [
        for (i = [0 : 2 * edges - 1])
            let(
                e = floor(i / 2),
                m = i % 2,
                a = angle * e + (m ? step : 0) + RIGHT
            )
            [
                cos(a) * (m ? inner[0] : outer[0]),
                sin(a) * (m ? inner[1] : outer[1])
            ]
    ]
;

/**
 * Computes the points that draw the sketch of a cross shape.
 *
 * @param Number|Vector [size] - The outer size of the cross.
 * @param Number|Vector [core] - The size of the core.
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [cl] - The core length.
 * @param Number [cw] - The core width.
 * @returns Vector[]
 */
function drawCross(size, core, l, w, cl, cw) =
    let(
        size = sizeCross(size=size, core=core, l=l, w=w, cl=cl, cw=cw),
        outer = size[0] / 2,
        inner = size[1] / 2
    )
    inner == [0, 0] ?
    [
        [ outer[0],  outer[1]],
        [-outer[0],  outer[1]],
        [-outer[0], -outer[1]],
        [ outer[0], -outer[1]]
    ]
   :[
        [ inner[0],  inner[1]],
        [ inner[0],  outer[1]],
        [-inner[0],  outer[1]],
        [-inner[0],  inner[1]],
        [-outer[0],  inner[1]],
        [-outer[0], -inner[1]],
        [-inner[0], -inner[1]],
        [-inner[0], -outer[1]],
        [ inner[0], -outer[1]],
        [ inner[0], -inner[1]],
        [ outer[0], -inner[1]],
        [ outer[0],  inner[1]]
    ]
;

/**
 * Creates a rectangle at the origin.
 *
 * @param Number|Vector [size] - The size of the rectangle.
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 */
module rectangle(size, l, w) {
    polygon(
        points = drawRectangle(size=size, l=l, w=w),
        convexity = 10
    );
}

/**
 * Creates a chamfered rectangle at the origin.
 *
 * @param Number|Vector [size] - The size of the chamfered rectangle.
 * @param Number|Vector [chamfer] - The size of the chamfers.
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [cl] - The length of the chamfers.
 * @param Number [cw] - The width of the chamfers.
 */
module chamferedRectangle(size, chamfer, l, w, cl, cw) {
    polygon(
        points = drawChamferedRectangle(size=size, chamfer=chamfer, l=l, w=w, cl=cl, cw=cw),
        convexity = 10
    );
}

/**
 * Creates a trapezium at the origin.
 *
 * @param Number|Vector [size] - The size of the trapezium.
 * @param Number [a] - The length of the bottom base.
 * @param Number [b] - The length of the top base.
 * @param Number [w] - The width between bases.
 */
module trapezium(size, a, b, w) {
    polygon(
        points = drawTrapezium(size=size, a=a, b=b, w=w),
        convexity = 10
    );
}

/**
 * Creates a regular polygon at the origin.
 *
 * @param Number|Vector [size] - The size of the polygon.
 * @param Number [n] - The number of facets (min. 3).
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [s] - The length of a side.
 */
module regularPolygon(size, n, l, w, s) {
    polygon(
        points = drawRegularPolygon(size=size, n=n, l=l, w=w, s=s),
        convexity = 10
    );
}

/**
 * Creates an hexagon at the origin.
 *
 * @param Number|Vector [size] - The size of the hexagon.
 * @param Boolean [pointy] - Tells if the hexagon must be pointy topped (default: false, Flat topped).
 * @param Number [adjust] - An adjust length added on the horizontal side.
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [s] - The length of a side.
 */
module hexagon(size, pointy, adjust, l, w, s) {
    polygon(
        points = drawHexagon(size=size, pointy=pointy, adjust=adjust, l=l, w=w, s=s),
        convexity = 10
    );
}

/**
 * Creates a star at the origin.
 *
 * @param Number|Vector [size] - The outer size of the star.
 * @param Number|Vector [core] - The size of the core.
 * @param Number [edges] - The number of star edges (min. 3).
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [cl] - The core length.
 * @param Number [cw] - The core width.
 */
module star(size, core, edges, l, w, cl, cw) {
    polygon(
        points = drawStar(size=size, core=core, edges=edges, l=l, w=w, cl=cl, cw=cw),
        convexity = 10
    );
}

/**
 * Creates a cross at the origin.
 *
 * @param Number|Vector [size] - The outer size of the cross.
 * @param Number|Vector [core] - The size of the core.
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [cl] - The core length.
 * @param Number [cw] - The core width.
 */
module regularCross(size, core, l, w, cl, cw) {
    polygon(
        points = drawCross(size=size, core=core, l=l, w=w, cl=cl, cw=cw),
        convexity = 10
    );
}

/**
 * Creates a mesh with honeycomb cells using a hex grid pattern.
 *
 * @param Number|Vector [size] - The outer size of the mesh.
 * @param Number|Vector [count] - The number of cells on each lines and each columns.
 * @param Number|Vector [gap] - The space between two cells.
 * @param Boolean [pointy] - Tells if the hexagons in the mesh are pointy topped (default: false, Flat topped).
 * @param Boolean [linear] - Tells if the hex grid is linear instead of radial (default: false).
 * @param Boolean [even] - Tells if the first hexagons of a the linear grid should be below the line (default: false).
 * @param Number [l] - The overall length.
 * @param Number [w] - The overall width.
 * @param Number [cx] - The number of cells per lines.
 * @param Number [cy] - The number of cells per columns.
 * @param Number [gx] - The space between two cells on each lines.
 * @param Number [gy] - The space between two cells on each columns.
 */
module mesh(size, count, gap, pointy, linear, even, l, w, cx, cy, gx, gy) {
    size = apply2D(size, l, w);
    count = divisor2D(apply2D(count, cx, cy));
    gap = apply2D(gap, gx, gy);
    cell = sizeHexCell(size=size, count=count, pointy=pointy, linear=linear);
    inner = cell - gap;
    offset = offsetHexGrid(size=cell, count=count, pointy=pointy, linear=linear, even=even);

    for(hex = buildHexGrid(count=count, linear=linear)) {
        translate(offset + coordHexCell(hex=hex, size=cell, linear=linear, even=even, pointy=pointy)) {
            hexagon(size=inner, pointy=pointy);
        }
    }
}


z/upper_gantry: misc fixes

z/upper_gantry: misc fixes

include <config.scad>
include <thing_libutils/metric-screw.scad>

module zaxis_upper_gantry_zrod_connector()
{
    // how much bigger/smaller is the upper gantry (on each side)
    upper_gantry_width_diff  = (main_upper_width-main_width)/2;
    difference()
    {
        union()
        {
            hull()
            {
                // attach to z rod
                translate([zmotor_mount_rod_offset_x,0,0])
                {
                    cubea([gantry_connector_thickness, zmotor_mount_clamp_width, extrusion_size+gantry_connector_thickness], align=[-1,0,1]);
                }

                // connect upper gantry
                translate([upper_gantry_width_diff, 0, 0])
                    translate([0,0,extrusion_size/2])
                    cubea([gantry_connector_thickness,main_upper_dist_y+extrusion_size,extrusion_size], align=[1,0,0], extrasize=[0,0,gantry_connector_thickness], extrasize_align=[0,0,1]);
            }

            translate([upper_gantry_width_diff, 0, 0])
                translate([0,0,extrusion_size])
                cubea([extrusion_size*2,main_upper_dist_y+extrusion_size,gantry_connector_thickness], align=[-1,0,1]);

        }

        // cut out z rod mounting clamp nut traps and screw holes
        translate([zmotor_mount_rod_offset_x, 0, extrusion_size/2])
        for(i=[-1,1])
        {
            translate([-.1, i*zmotor_mount_clamp_dist/2, 0])
            {
                screw_cut(
                        nut=zmotor_mount_clamp_nut,
                        h=zmotor_mount_rod_offset_x-(extrusion_size*2),
                        orient=[-1,0,0],
                        align=[-1,0,0]
                        );
            }
        }

        translate([upper_gantry_width_diff/2, 0, extrusion_size+gantry_connector_thickness])
        for(x=[-1,1])
        for(y=[-1,1])
        {
            translate([x*extrusion_thread_dia*2, y*main_upper_dist_y/2, 0])
            {
                screw_cut(extrusion_nut, h=gantry_connector_thickness+.1, nut_offset=true, orient=[0,0,-1], align=[0,0,-1]);
            }
        }

        // cutout for z rod
        translate([zmotor_mount_rod_offset_x,0,extrusion_size])
        cylindera(d=zaxis_rod_d*1.01, h=extrusion_size*3, align=[0,0,0], orient=[0,0,1]);
    }
}

/*rotate([0,180,0])*/
/*zaxis_upper_gantry_zrod_connector();*/

include <config.scad>

module zaxis_upper_gantry_zrod_connector()
{
    upper_width_extra = main_upper_width-main_width;
    difference()
    {
        union()
        {
            hull()
            {
                // attach to z rod
                translate([extrusion_size/2+zmotor_mount_rod_offset_x,0,0])
                {
                    cubea([gantry_connector_thickness, zmotor_mount_clamp_width, extrusion_size+gantry_connector_thickness], align=[-1,0,1]);
                }

                // connect upper gantry
                translate([upper_width_extra/2, 0, 0])
                    translate([0,0,extrusion_size/2])
                    cubea([gantry_connector_thickness,main_upper_dist_y+extrusion_size,extrusion_size], align=[1,0,0], extrasize=[0,0,gantry_connector_thickness], extrasize_align=[0,0,1]);
            }

            translate([upper_width_extra/2, 0, 0])
                translate([0,0,extrusion_size])
                cubea([extrusion_size*2,main_upper_dist_y+extrusion_size,gantry_connector_thickness], align=[-1,0,1]);

        }

        // cut out z rod mounting clamp nut traps and screw holes
        translate([0,0,extrusion_size/2])
        translate([upper_width_extra/2, 0, 0])
        for(i=[-1,1])
        {
            translate([-.1, i*zmotor_mount_clamp_dist/2, 0])
            {
                screw_cut(zmotor_mount_clamp_nut, h=200, orient=[1,0,0], align=[1,0,0]);
            }
        }

        translate([0,0,extrusion_size+gantry_connector_thickness])
        /*#cubea(align=[0,0,1])*/

        translate([upper_width_extra/4, 0, 0])
        for(x=[-1,1])
        for(y=[-1,1])
        {
            translate([x*extrusion_thread_dia*2, y*main_upper_dist_y/2, 0])
            {
                screw_cut(extrusion_nut, h=gantry_connector_thickness+.1, nut_offset=true, orient=[0,0,-1], align=[0,0,-1]);
            }
        }

        // cutout for z rod
        translate([lookup(NemaSideSize,zaxis_motor)/2, 0, 0])
        translate([(zaxis_rod_screw_distance_x+zmotor_mount_motor_offset),0,extrusion_size])
        cylindera(d=zaxis_rod_d*1.01, h=extrusion_size*3, align=[0,0,0], orient=[0,0,1]);
    }
}

/*rotate([0,180,0])*/
/*zaxis_upper_gantry_zrod_connector();*/


add the stand top

add the stand top

use <../../../basics/rounded-edges/doughnuts/doughnuts.scad>;

module halfCirclePhoneStand(height = 19.125,
                            minkowskiSphereRadius = 0.5)
{
    halfCirclePhoneStand_stand_top(height = height,
                                   minkowskiSphereRadius = minkowskiSphereRadius);

    halfCirclePhoneStand_stand_base(height = height,
                                    minkowskiSphereRadius = minkowskiSphereRadius);
}

// sub-modules and functions follow

module halfCirclePhoneStand_stand_base(height,
                                       minkowskiSphereRadius)
{
    color("green")
    translate([0, 0, minkowskiSphereRadius])
    roundDoughnut(height = height,
                innerRadius = 4.9,      // 4.9
                outerRadius = 5.59,     // 5.59
                minkowskiSphereRadius = minkowskiSphereRadius);
}

module halfCirclePhoneStand_stand_top(height,
                                      minkowskiSphereRadius)
{
    xTranslate = 8.105;  // 8.05     // 8.1
    yTranslate = 8.85;  // 8.85     // 8.9

    color("green")
    translate([xTranslate, yTranslate, minkowskiSphereRadius])
    roundDoughnut(height = height,
                innerRadius = 1.9,  // 2.0
                outerRadius = 2.6,  // 2.6
                minkowskiSphereRadius = minkowskiSphereRadius);
}

use <../../../basics/rounded-edges/doughnuts/doughnuts.scad>;

module halfCirclePhoneStand(minkowskiSphereRadius = 0.5)
{

    halfCirclePhoneStand_stand_base(minkowskiSphereRadius = minkowskiSphereRadius);
}

// sub-modules and functions follow

module halfCirclePhoneStand_stand_base(minkowskiSphereRadius)
{
    color("green")
    translate([0, 0, minkowskiSphereRadius])
    roundDoughnut(height = 19.125,
                innerRadius = 4.9,
                outerRadius = 5.59,
                minkowskiSphereRadius = minkowskiSphereRadius);
}


increase the internal cutout top radius

increase the internal cutout top radius

// originially from:
// Sine Cube Vase 1 by @Chompworks
// Original at: https://www.thingiverse.com/thing:2666281
// Released under the Creative Commons CC - BY 3.0 licence
// Details here: https://creativecommons.org/licenses/by/3.0/
// customizer modifications by Roberto Marquez
//                              https://www.thingiverse.com/onebeartoe/designs

cubeOrCylinder = "cylinder"; // [cube, cylinder]

internalCutout_bottomRadius = 43; // [30 : 1 : 45]

/* [Hidden] */

step=4; // number of degrees to step for each cuboid element

maxlayers=100; // max number of layers. More layers slows down compilation on [F6], but makes the vase taller

basewidth=50; // basic length of a cuboid

difference() // Take away the two parts at the bottom
{
    union() // this stitches all the cuboids together
    {
        translate([0,0,-80])
        for (layers=[1:maxlayers]) // make each slice
        {
            for (angle=[1:step:360])
            {
                translate([0,0,layers*2]) // move the cuboid up to where it needs to be!
                rotate([0,0,angle]) // rotate the cuboid
                rotate([45,-45,0]) // rotate the cuboid for the best effect
                translate([0,-1,0]) // move the cuboid. This minus 1 offset just worked well!

                if(cubeOrCylinder == "cylinder")
                {
                    cylinderHeight = basewidth + (layers/maxlayers*30) + 10*cos(layers*15) * sin(angle*8);

	                cylinder(r=2, h=cylinderHeight, $fn=20);
                }
                else
                {
                    cube_xLength = basewidth + (layers/maxlayers*30) + 10*cos(layers*15) * sin(angle*8);

    				cube([cube_xLength, 4, 4]);

                        // lets explain this!
                        // make a 4x4 square
                        // then extrude it by:
                            // basewidth - a constant. this is the minimum length of any cuboid
                            // PLUS
                            // (layers/maxlayers*30) - this makes the vase taper outward as it gets taller. A sine function on this could make it act more like a pot/urn [Thin, Fat, Thin]
                            // PLUS
                            // 10*cos(layers*15)*sin(angle*8) - this is a nasty bit of trig at first!
                            // the sine function controls the bumps. Multiplying the angle by 8 means that rather than 1 bump, there are 8 for any given layer
                            // the cosine function (layers*15) makes the bumps also occur in the Z axis as they go up. If you removed this, the vase becomes very straight
                }
            }
        }
    }

    //this removes the cone base and leaves a flat base for the vase
    translate([-500,-500,-100])
    cube([1000,1000,100]);

    // this adds an internal hollow, 5mm up from the base
    internalCutout_TopRadius = internalCutout_bottomRadius + 22;
    translate([0,0,5])
    cylinder(r1 = internalCutout_bottomRadius, r2 = internalCutout_TopRadius, h = maxlayers * 2, $fn = 360/step);
}

// originially from:
// Sine Cube Vase 1 by @Chompworks
// Original at: https://www.thingiverse.com/thing:2666281
// Released under the Creative Commons CC - BY 3.0 licence
// Details here: https://creativecommons.org/licenses/by/3.0/
// customizer modifications by Roberto Marquez
//                              https://www.thingiverse.com/onebeartoe/designs

cubeOrCylinder = "cylinder"; // [cube, cylinder]

internalCutout_bottomRadius = 43; // [30 : 1 : 45]

/* [Hidden] */

step=4; // number of degrees to step for each cuboid element

maxlayers=100; // max number of layers. More layers slows down compilation on [F6], but makes the vase taller

basewidth=50; // basic length of a cuboid

difference() // Take away the two parts at the bottom
{
    union() // this stitches all the cuboids together
    {
        translate([0,0,-80])
        for (layers=[1:maxlayers]) // make each slice
        {
            for (angle=[1:step:360])
            {
                translate([0,0,layers*2]) // move the cuboid up to where it needs to be!
                rotate([0,0,angle]) // rotate the cuboid
                rotate([45,-45,0]) // rotate the cuboid for the best effect
                translate([0,-1,0]) // move the cuboid. This minus 1 offset just worked well!

                if(cubeOrCylinder == "cylinder")
                {
                    cylinderHeight = basewidth + (layers/maxlayers*30) + 10*cos(layers*15) * sin(angle*8);

	                cylinder(r=2, h=cylinderHeight, $fn=20);
                }
                else
                {
                    cube_xLength = basewidth + (layers/maxlayers*30) + 10*cos(layers*15) * sin(angle*8);

    				cube([cube_xLength, 4, 4]);

                        // lets explain this!
                        // make a 4x4 square
                        // then extrude it by:
                            // basewidth - a constant. this is the minimum length of any cuboid
                            // PLUS
                            // (layers/maxlayers*30) - this makes the vase taper outward as it gets taller. A sine function on this could make it act more like a pot/urn [Thin, Fat, Thin]
                            // PLUS
                            // 10*cos(layers*15)*sin(angle*8) - this is a nasty bit of trig at first!
                            // the sine function controls the bumps. Multiplying the angle by 8 means that rather than 1 bump, there are 8 for any given layer
                            // the cosine function (layers*15) makes the bumps also occur in the Z axis as they go up. If you removed this, the vase becomes very straight
                }
            }
        }
    }

    //this removes the cone base and leaves a flat base for the vase
    translate([-500,-500,-100])
    cube([1000,1000,100]);

    // this adds an internal hollow, 5mm up from the base
    internalCutout_TopRadius = internalCutout_bottomRadius + 15;
    translate([0,0,5])
    cylinder(r1 = internalCutout_bottomRadius, r2 = internalCutout_TopRadius, h = maxlayers * 2, $fn = 360/step);
}


moved motor down 1cm.  belts could have been tighter

// $URL: svn+ssh://mrwhat@ssh.boim.com/home/mrwhat/svn/Walker/trunk/motorMount.scad $
// $Id: motorMount.scad 427 2014-08-23 20:42:39Z mrwhat $

// Mount to attach to axles and hold motor drive module

// Distance from top edge of mount to center of motor axle:
// at 30mm offset, belts were not as tight as I'd like.
// ?? try 40?
motorOffset=40;

// shape of small gearhead motor GA12YN20 from fasttech.com
module gearheadMotorProxyGA12(pad) { union() {
cube([10+pad,12+pad,9.2+pad],center=true);
translate([0,0,-(9.2+pad)/2-7.9]) difference() {
   cylinder(h=10,r=1.5,$fn=36);
   translate([1,-2,-.1]) cube([2,4,7.7]); }
intersection() {
   translate([0,0,9.2/2-1])cylinder(h=15+pad+1,r=(12+pad)/2,$fn=48);
   cube([10+pad,12+pad,66],center=true); }
}}

// Slightly larger 60RPM gearhead motor.
// same size?  35RPM GA16Y030 fasttech
module gearheadMotorProxyGA16(pad) {
difference() { union(){
translate([0,0,10-29]) cylinder(h=29,r=7.75+pad,$fn=64);
cylinder(h=10+5,r=1.5,$fn=36);
}
translate([ 6  ,-10,10-29-1]) cube([5,20,29-10+1]);
translate([-6-5,-10,10-29-1]) cube([5,20,29-10+1]);
translate([1.5-(3-2.44),-2,1+10]) cube([2,4,5]);
}}

// larger 30RPM gearhead (as delivered) motor GA25Y310 fasttech
// photo and specs on site do not match delivered product.
// drawing is of delivered product, marked 25GA370-98, 30RPM
module gearheadMotorProxyGA25(pad) {
difference() { union(){
translate([0,0,-31]) cylinder(h=32,r=12.2+pad,$fn=64);
cylinder(h=23.5,r=12.6+pad,$fn=64);
translate([0,0,24]) cylinder(h=10,r=2,$fn=36);
translate([0,0,23]) cylinder(h=2.5,r=3.5,$fn=36);
}
translate([1.5,-3,23.5+3]) cube([2,6,8]);
}}

bh=4;
br1=2;
br2=1.5;

module ulc(dx,dy) { translate([-20+dx,-1.5+dy,0]) cylinder(h=bh,r1=br1,r2=br2,$fn=6); }
module urc(dx,dy) { translate([ 20+dx,-1.5+dy,0]) cylinder(h=bh,r1=br1,r2=br2,$fn=6); }
module llc() { translate([-6,-motorOffset-2,0]) cylinder(h=bh+2,r1=br1,r2=.5,$fn=6); }
module lrc() { translate([ 6,-motorOffset-2,0]) cylinder(h=bh+2,r1=br1,r2=.5,$fn=6); }

dtFuzz = 0.08;  // fuzz to add to dove tail slots

module motorMount() {
  difference() {
    union() {
      hull() { ulc(0,0); urc(0,0); }
      hull() { ulc(2,-1); urc(-2,-1); }
      hull() { ulc(0,0); llc(); }
      hull() { urc(0,0); lrc(); }
      for (a=[-1,1]) hull() {
        translate([.6*a, -2,0]) cylinder(h=bh  ,r1=2,r2=0.5,$fn=6);
        translate([ 7*a,-motorOffset+2,0]) cylinder(h=bh+2,r1=2,r2=0.5,$fn=6);
      }

      hull() for (a=[-1,1]) {
        translate([5*a,-motorOffset+6,0]) cylinder(h=bh*2,r1=3.2,r2=3,$fn=6);
        translate([4*a,-motorOffset-2,0]) cylinder(h=20  ,r1=4.6,r2=4,$fn=6);
      }
    }

    // dove-tail receivers, 2x as high as actual, with 2x radius reduction
    // so they have the same wall slope, but are extra long to make
    // sure they cut all the way through the top brace bar
    for (a=[-1,1]) translate([10*a,-1,1-0.1]) rotate([0,0,-30])
       cylinder(h=6,r2=5+dtFuzz,r1=3+dtFuzz,$fn=3);

    // at 30mm offset, belts were not as tight as I'd like.
    // ?? try 40?
    #translate([0,-motorOffset,3.9]) gearheadMotorProxyGA12(0.4);
  }
}

if (WITH_BRIM) {
union() { color("Cyan") hull() {
  translate([-30,0,0]) cube([60,7,.4]);
  translate([-13,-42,0]) cube([26,.1,.4]); }
translate([0,0,.2]) motorMount();
}}
else { motorMount(); }

//%translate([0,30,0])  gearheadMotorProxyGA16(0);
//%translate([30,0,0])  gearheadMotorProxyGA12(0.2);
//%translate([-40,0,0]) gearheadMotorProxyGA25(0.2);

// $URL: svn+ssh://mrwhat@ssh.boim.com/home/mrwhat/svn/Walker/trunk/motorMount.scad $
// $Id: motorMount.scad 427 2014-08-23 20:42:39Z mrwhat $

// Mount to attach to axles and hold motor drive module

// shape of small gearhead motor GA12YN20 from fasttech.com
module gearheadMotorProxyGA12(pad) { union() {
cube([10+pad,12+pad,9.2+pad],center=true);
translate([0,0,-(9.2+pad)/2-7.9]) difference() {
   cylinder(h=10,r=1.5,$fn=36);
   translate([1,-2,-.1]) cube([2,4,7.7]); }
intersection() {
   translate([0,0,9.2/2-1])cylinder(h=15+pad+1,r=(12+pad)/2,$fn=48);
   cube([10+pad,12+pad,66],center=true); }
}}

// Slightly larger 60RPM gearhead motor.
// same size?  35RPM GA16Y030 fasttech
module gearheadMotorProxyGA16(pad) {
difference() { union(){
translate([0,0,10-29]) cylinder(h=29,r=7.75+pad,$fn=64);
cylinder(h=10+5,r=1.5,$fn=36);
}
translate([ 6  ,-10,10-29-1]) cube([5,20,29-10+1]);
translate([-6-5,-10,10-29-1]) cube([5,20,29-10+1]);
translate([1.5-(3-2.44),-2,1+10]) cube([2,4,5]);
}}

// larger 30RPM gearhead (as delivered) motor GA25Y310 fasttech
// photo and specs on site do not match delivered product.
// drawing is of delivered product, marked 25GA370-98, 30RPM
module gearheadMotorProxyGA25(pad) {
difference() { union(){
translate([0,0,-31]) cylinder(h=32,r=12.2+pad,$fn=64);
cylinder(h=23.5,r=12.6+pad,$fn=64);
translate([0,0,24]) cylinder(h=10,r=2,$fn=36);
translate([0,0,23]) cylinder(h=2.5,r=3.5,$fn=36);
}
translate([1.5,-3,23.5+3]) cube([2,6,8]);
}}

bh=4;
br1=2;
br2=1.5;

module ulc(dx,dy) { translate([-20+dx,-1.5+dy,0]) cylinder(h=bh,r1=br1,r2=br2,$fn=6); }
module urc(dx,dy) { translate([ 20+dx,-1.5+dy,0]) cylinder(h=bh,r1=br1,r2=br2,$fn=6); }
module llc() { translate([ -6, -30,0]) cylinder(h=bh+2,r1=br1,r2=.5,$fn=6); }
module lrc() { translate([  6, -30,0]) cylinder(h=bh+2,r1=br1,r2=.5,$fn=6); }

dtFuzz = 0.08;  // fuzz to add to dove tail slots

module motorMount() {
  difference() {
    union() {
      hull() { ulc(0,0); urc(0,0); }
      hull() { ulc(2,-1); urc(-2,-1); }
      hull() { ulc(0,0); llc(); }
      hull() { urc(0,0); lrc(); }
      for (a=[-1,1]) hull() {
        translate([.6*a, -2,0]) cylinder(h=bh  ,r1=2,r2=0.5,$fn=6);
        translate([ 7*a,-25,0]) cylinder(h=bh+2,r1=2,r2=0.5,$fn=6);
      }

      hull() for (a=[-1,1]) {
        translate([5*a,-24,0]) cylinder(h=bh*2,r1=3.2,r2=3,$fn=6);
        translate([4*a,-32,0]) cylinder(h=20  ,r1=4.6,r2=4,$fn=6);
      }
    }

    // dove-tail receivers, 2x as high as actual, with 2x radius reduction
    // so they have the same wall slope, but are extra long to make
    // sure they cut all the way through the top brace bar
    for (a=[-1,1]) translate([10*a,-1,1-0.1]) rotate([0,0,-30])
       cylinder(h=6,r2=5+dtFuzz,r1=3+dtFuzz,$fn=3);

    #translate([0,-30,3.9]) gearheadMotorProxyGA12(0.4);
  }
}

if (WITH_BRIM) {
union() { color("Cyan") hull() {
  translate([-30,0,0]) cube([60,7,.4]);
  translate([-13,-42,0]) cube([26,.1,.4]); }
translate([0,0,.2]) motorMount();
}}
else { motorMount(); }

//%translate([0,30,0])  gearheadMotorProxyGA16(0);
//%translate([30,0,0])  gearheadMotorProxyGA12(0.2);
//%translate([-40,0,0]) gearheadMotorProxyGA25(0.2);


main/xcarriage: some minor work

main/xcarriage: some minor work

include <thing_libutils/metric-thread.scad>;
include <thing_libutils/metric-hexnut.scad>;
use <thing_libutils/shapes.scad>;
use <thing_libutils/misc.scad>;
use <thing_libutils/attach.scad>;
use <thing_libutils/triangles.scad>
use <thing_libutils/linear-extrusion.scad>;

include <MCAD/stepper.scad>
include <MCAD/motors.scad>

include <config.scad>
include <extruder-direct.scad>

axis_pos_x = -225/2*mm;
axis_range_z=[85,380];
axis_pos_z = axis_range_z[1]*mm/2;

main();

module main()
{
    color(extrusion_color)
    gantry_lower();

    color(extrusion_color)
    translate([0,0,-main_lower_dist_z])
    gantry_lower();

    color(extrusion_color)
    for(i=[-1,1])
    translate([0,i*(main_upper_dist_y/2),0])
    gantry_upper();

    // x axis
    translate([0,0,axis_pos_z])
    {
        translate([axis_pos_x,0,0])
        {
            xaxis_bearing_dist = 10;
            xcarriage_padding=10;
            xcarriage_width = xaxis_bearing[2]*2 + xaxis_bearing_dist + xcarriage_padding;
            // x carriage
            translate([0,xaxis_zaxis_distance_y,0])
            translate([0,-xaxis_bearing[1]/2,0])
            cubea([xcarriage_width, 5, xaxis_rod_distance+xaxis_bearing[1]+xcarriage_padding], align=[0,-1,0]);

            attach([[-motor_offset_x-motorWidth(extruder_motor)/2, 10, -17], [0,0,0]], extruder_conn_xcarriage)
            /*#cubea([10,10,10]);*/
                extruder();

            // x carriage bearings
            for(j=[-1,1])
            translate([j*(xaxis_bearing_dist+xaxis_bearing[2])/2,xaxis_zaxis_distance_y,(xaxis_rod_distance/2)])
            rotate([0,90,0])
                bearing(xaxis_bearing);

            translate([0, xaxis_zaxis_distance_y, -(xaxis_rod_distance/2)])
            rotate([0,90,0])
                bearing(xaxis_bearing);
        }

        // x smooth rods
        for(i=[-1,1])
            translate([0,xaxis_zaxis_distance_y,i*(xaxis_rod_distance/2)])
                fncylindera(h=xaxis_rod_l,d=xaxis_rod_d, orient=[1,0,0]);
    }

    // y smooth rods
    translate([0,0,yaxis_bearing[0]/2])
    {
        for(i=[-1,1])
        translate([i*(yaxis_rod_distance/2), 0, 0])
        {
            fncylindera(h=yaxis_rod_l,d=yaxis_rod_d, orient=[0,1,0]);

            for(j=[-1,1])
                translate([0,j*(yaxis_rod_distance/2),0])
                    rotate([90,0,0])
                    bearing(yaxis_bearing);
        }

        translate([0,0,yaxis_bearing[1]/2])
        {
            // y axis plate
            cubea(ycarriage_size, align=[0,0,1]);
        }
    }

    // z axis
    for(i=[-1,1])
    translate([i*(main_width/2 + lookup(NemaSideSize,zaxis_motor)/2), 0, 0])
    {
        translate([0,0,zaxis_motor_offset_z])
        mirror([i==-1?1:0,0,0])
        {
            zmotor_mount();

            attach([[0,0,0],[0,0,0]],zmotor_mount_conn_motor)
            {
                // z motor/leadscrews
                motor(zaxis_motor, NemaMedium, dualAxis=false, orientation=[0,180,0]);
            }
        }

        // z smooth rods
        translate([i*(zaxis_rod_screw_distance_x+zmotor_mount_motor_offset),0,0])
        {
            translate([0,0,zaxis_motor_offset_z])
                fncylindera(h=zaxis_rod_l,d=zaxis_rod_d,align=[0,0,1]);

            for(j=[-1,1])
                translate([0,0,axis_pos_z-j*xaxis_rod_distance/2])
                    bearing(zaxis_bearing);
        }

        translate([i*zmotor_mount_motor_offset, 0, axis_pos_z-xaxis_rod_distance/2-10])
        {
            difference()
            {
                fncylindera(h=10, d=zaxis_nut[1], align=[0,0,0]);
                union()
                {
                    fncylindera(h=10+1, d=zaxis_nut[0], center= false);
                    translate([0, 13.5, -1]) fncylindera(h=5, r=1.6);
                    translate([0, -13.5, -1]) fncylindera(h=5, r=1.6);
                }
            }
        }
    }
}

zmotor_mount_motor_offset=5;
zmotor_mount_conn_motor=[[-zmotor_mount_motor_offset, 0, 0],[0,1,0]];

module zmotor_mount()
{
    motor_w = lookup(NemaSideSize,zaxis_motor);

    mount_thickness = 5;
    mount_thickness_h = 8;
    mount_thread_dia = lookup(ThreadSize, extrusion_thread);
    mount_width = motor_w+mount_thickness*2 + mount_thread_dia*8;
    mount_h = main_lower_dist_z+extrusion_size+zaxis_motor_offset_z;

    // side triangles
    translate([-motor_w/2, 0, 0])
    for(i=[-1,1])
    {
        translate([mount_thickness, i*((motor_w/2)+mount_thickness/2), 0])
        rotate([90,90,0])
        Right_Angled_Triangle(a=motor_w-mount_thickness+zmotor_mount_motor_offset, b=main_lower_dist_z+extrusion_size+zaxis_motor_offset_z, height=mount_thickness, centerXYZ=[0,0,1]);

        translate([0, i*((motor_w/2)+mount_thickness/2), 0])
        cubea([mount_thickness, mount_thickness, mount_h], align=[1,0,-1]);
    }

    // top mount plate
    difference()
    {
        translate([-motor_w/2,0,-extrusion_size-zaxis_motor_offset_z])
            cubea([mount_thickness, mount_width, extrusion_size], align=[1,0,1]);

        for(i=[-1,1])
            translate([-motor_w/2,i*(motor_w/2+mount_thread_dia*3),-extrusion_size])
                fncylindera(h=mount_thickness*3,d=mount_thread_dia, orient=[1,0,0]);
    }

    // bottom mount plate
    difference()
    {
        translate([-motor_w/2,0,-main_lower_dist_z-extrusion_size-zaxis_motor_offset_z])
            cubea([mount_thickness, mount_width, extrusion_size], align=[1,0,1]);

        for(i=[-1,1])
            translate([-motor_w/2,i*(motor_w/2+mount_thread_dia*3),-extrusion_size-main_lower_dist_z])
                fncylindera(h=mount_thickness*3,d=mount_thread_dia,align=[0,0,0], orient=[1,0,0]);
    }

/*#    cubea([motor_w+mount_thickness,motor_w+mount_thickness,zaxis_motor_offset_z], align=[0,0,-1]);*/

    // top plate
    difference()
    {
        cubea([motor_w, motor_w+mount_thickness*2, mount_thickness_h], align=[0,0,1], extrasize=[5,0,0], extrasize_align=[1,0,0]);

        translate([zmotor_mount_motor_offset,0,-1])
        linear_extrude(mount_thickness_h+2)
        stepper_motor_mount(17, slide_distance=0, mochup=false);
    }
}

module gantry_upper()
{
    for(i=[-1,1])
    translate([i*(main_width/2), 0])
    linear_extrusion(h=main_height, align=[-i,0,1], orient=[0,0,1]);

    translate([0, 0, main_height])
    linear_extrusion(h=main_upper_width, align=[0,0,1], orient=[1,0,0]);
}

module gantry_lower()
{
    for(i=[-1,1])
    translate([0,  i*(main_depth/2), 0])
    linear_extrusion(h=main_width, align=[0,i,-1], orient=[1,0,0]);

    for(i=[-1,1])
    translate([i*(main_width/2), 0, 0])
    linear_extrusion(h=main_depth, align=[-i,0,-1], orient=[0,1,0]);
}

include <thing_libutils/metric-thread.scad>;
include <thing_libutils/metric-hexnut.scad>;
use <thing_libutils/shapes.scad>;
use <thing_libutils/misc.scad>;
use <thing_libutils/attach.scad>;
use <thing_libutils/triangles.scad>
use <thing_libutils/linear-extrusion.scad>;

include <MCAD/stepper.scad>
include <MCAD/motors.scad>

include <config.scad>
include <extruder-direct.scad>

axis_pos_x = -225/2*mm;
axis_range_z=[85,380];
axis_pos_z = axis_range_z[1]*mm/2;

main();

module main()
{
    color(extrusion_color)
    gantry_lower();

    color(extrusion_color)
    translate([0,0,-main_lower_dist_z])
    gantry_lower();

    color(extrusion_color)
    for(i=[-1,1])
    translate([0,i*(main_upper_dist_y/2),0])
    gantry_upper();

    // x axis
    translate([0,0,axis_pos_z])
    {
        translate([axis_pos_x,0,0])
        {
            xaxis_bearing_dist = 10;
            translate([0,xaxis_zaxis_distance_y,0])
            translate([0,xaxis_bearing[1]/2,0])
            cubea([xaxis_bearing[2]*2+xaxis_bearing_dist,5,xaxis_rod_distance+xaxis_bearing[1]], align=[0,1,0]);

            attach([[-8,-15,-16],[-1,0,0]],extruder_conn_xcarriage)
                extruder();

            // x carriage
            for(i=[-1,1])
                for(j=[-1,1])
                    translate([j*(xaxis_bearing_dist+xaxis_bearing[2])/2,xaxis_zaxis_distance_y,i*(xaxis_rod_distance/2)])
                        rotate([0,90,0])
                        bearing(xaxis_bearing);
        }

        // x smooth rods
        for(i=[-1,1])
            translate([0,xaxis_zaxis_distance_y,i*(xaxis_rod_distance/2)])
                fncylindera(h=xaxis_rod_l,d=xaxis_rod_d, orient=[1,0,0]);
    }

    // y smooth rods
    translate([0,0,yaxis_bearing[0]/2])
    {
        for(i=[-1,1])
        translate([i*(yaxis_rod_distance/2), 0, 0])
        {
            fncylindera(h=yaxis_rod_l,d=yaxis_rod_d, orient=[0,1,0]);

            for(j=[-1,1])
                translate([0,j*(yaxis_rod_distance/2),0])
                    rotate([90,0,0])
                    bearing(yaxis_bearing);
        }

        translate([0,0,yaxis_bearing[1]/2])
        {
            // y axis plate
            cubea(ycarriage_size, align=[0,0,1]);
        }
    }

    // z axis
    for(i=[-1,1])
    translate([i*(main_width/2 + lookup(NemaSideSize,zaxis_motor)/2), 0, 0])
    {
        translate([0,0,zaxis_motor_offset_z])
        mirror([i==-1?1:0,0,0])
        {
            zmotor_mount();

            attach([[0,0,0],[0,0,0]],zmotor_mount_conn_motor)
            {
                // z motor/leadscrews
                motor(zaxis_motor, NemaMedium, dualAxis=false, orientation=[0,180,0]);
            }
        }

        // z smooth rods
        translate([i*(zaxis_rod_screw_distance_x+zmotor_mount_motor_offset),0,0])
        {
            translate([0,0,zaxis_motor_offset_z])
                fncylindera(h=zaxis_rod_l,d=zaxis_rod_d,align=[0,0,1]);

            for(j=[-1,1])
                translate([0,0,axis_pos_z-j*xaxis_rod_distance/2])
                    bearing(zaxis_bearing);
        }

        translate([i*zmotor_mount_motor_offset, 0, axis_pos_z-xaxis_rod_distance/2-10])
        {
            difference()
            {
                fncylindera(h=10, d=zaxis_nut[1], align=[0,0,0]);
                union()
                {
                    fncylindera(h=10+1, d=zaxis_nut[0], center= false);
                    translate([0, 13.5, -1]) fncylindera(h=5, r=1.6);
                    translate([0, -13.5, -1]) fncylindera(h=5, r=1.6);
                }
            }
        }
    }
}

zmotor_mount_motor_offset=5;
zmotor_mount_conn_motor=[[-zmotor_mount_motor_offset, 0, 0],[0,1,0]];

module zmotor_mount()
{
    motor_w = lookup(NemaSideSize,zaxis_motor);

    mount_thickness = 5;
    mount_thickness_h = 8;
    mount_thread_dia = lookup(ThreadSize, extrusion_thread);
    mount_width = motor_w+mount_thickness*2 + mount_thread_dia*8;
    mount_h = main_lower_dist_z+extrusion_size+zaxis_motor_offset_z;

    // side triangles
    translate([-motor_w/2, 0, 0])
    for(i=[-1,1])
    {
        translate([mount_thickness, i*((motor_w/2)+mount_thickness/2), 0])
        rotate([90,90,0])
        Right_Angled_Triangle(a=motor_w-mount_thickness+zmotor_mount_motor_offset, b=main_lower_dist_z+extrusion_size+zaxis_motor_offset_z, height=mount_thickness, centerXYZ=[0,0,1]);

        translate([0, i*((motor_w/2)+mount_thickness/2), 0])
        cubea([mount_thickness, mount_thickness, mount_h], align=[1,0,-1]);
    }

    // top mount plate
    difference()
    {
        translate([-motor_w/2,0,-extrusion_size-zaxis_motor_offset_z])
            cubea([mount_thickness, mount_width, extrusion_size], align=[1,0,1]);

        for(i=[-1,1])
            translate([-motor_w/2,i*(motor_w/2+mount_thread_dia*3),-extrusion_size])
                fncylindera(h=mount_thickness*3,d=mount_thread_dia, orient=[1,0,0]);
    }

    // bottom mount plate
    difference()
    {
        translate([-motor_w/2,0,-main_lower_dist_z-extrusion_size-zaxis_motor_offset_z])
            cubea([mount_thickness, mount_width, extrusion_size], align=[1,0,1]);

        for(i=[-1,1])
            translate([-motor_w/2,i*(motor_w/2+mount_thread_dia*3),-extrusion_size-main_lower_dist_z])
                fncylindera(h=mount_thickness*3,d=mount_thread_dia,align=[0,0,0], orient=[1,0,0]);
    }

/*#    cubea([motor_w+mount_thickness,motor_w+mount_thickness,zaxis_motor_offset_z], align=[0,0,-1]);*/

    // top plate
    difference()
    {
        cubea([motor_w, motor_w+mount_thickness*2, mount_thickness_h], align=[0,0,1], extrasize=[5,0,0], extrasize_align=[1,0,0]);

        translate([zmotor_mount_motor_offset,0,-1])
        linear_extrude(mount_thickness_h+2)
        stepper_motor_mount(17, slide_distance=0, mochup=false);
    }
}

module gantry_upper()
{
    for(i=[-1,1])
    translate([i*(main_width/2), 0])
    linear_extrusion(h=main_height, align=[-i,0,1], orient=[0,0,1]);

    translate([0, 0, main_height])
    linear_extrusion(h=main_upper_width, align=[0,0,1], orient=[1,0,0]);
}

module gantry_lower()
{
    for(i=[-1,1])
    translate([0,  i*(main_depth/2), 0])
    linear_extrusion(h=main_width, align=[0,i,-1], orient=[1,0,0]);

    for(i=[-1,1])
    translate([i*(main_width/2), 0, 0])
    linear_extrusion(h=main_depth, align=[-i,0,-1], orient=[0,1,0]);
}