beef up support for printability under cura

// $URL: svn+ssh://mrwhat@ssh.boim.com/home/mrwhat/svn/Walker/trunk/JansenBED.scad $
// $Id: JansenBED.scad 435 2015-03-02 15:21:04Z mrwhat $

// main BED code, more injection-mold-like model

// Uses a ton of stuff from Jansen.scad.
// Use from an #include in  Jansen.scad.

forkLen = 3.5*LinkRad;  // forks around linkage in BED
nf=24;  // faces for hull components

module BEDhull(dLeft,dPerp,dRight,ph,rp) { hull() {
translate([-dLeft,-1,    0]) cylinder(h=1,r1=1,r2=.1,$fn=nf);
translate([dRight,-1,    0]) cylinder(h=1,r1=1,r2=.1,$fn=nf);
translate([ rp,dPerp+1,0]) cylinder(h=1,r1=1,r2=.1,$fn=nf);
translate([-rp,dPerp+1,0]) cylinder(h=1,r1=1,r2=.1,$fn=nf);
translate([ 0,dPerp-rp,ph-1]) sphere(r=1,$fn=nf);
translate([4-dLeft ,1,2]) sphere(r=1,$fn=nf);
translate([dRight-4,1,2]) sphere(r=1,$fn=nf);
}}

module BEDsideRail(x,dPerp,ph) {
hull() {
   translate([x,-1,  0]) {
     cylinder(h=1,r1=1.2,r2=.1,$fn=nf);
     translate([0,0,2]) sphere(r=.6,$fn=nf); }
   translate([0,dPerp+2,0]) {
     cylinder(h=1,r1=1.5,r2=.1,$fn=nf);
     translate([0,0,ph-.6]) sphere(r=.6,$fn=nf); }
   }
hull() {
   if (x < 0) { translate([x+2,0,0]) cylinder(h=2,r1=2.5,r2=2,$fn=nf); }
   else       { translate([x-2,0,0]) cylinder(h=2,r1=2.5,r2=2,$fn=nf); }
   translate([0,dPerp,0]) cylinder(h=2,r1=2.5,r2=2,$fn=nf);
   }
}

module BEDrails(dLeft,dPerp,dRight,ph,rp) {
union() {
   BEDsideRail(-dLeft,dPerp,ph);
   BEDsideRail(dRight,dPerp,ph);
   hull() { // vert bar part, DE
     translate([-dLeft,-1,0]) { cylinder(h=1,r1=1.5,r2=.1,$fn=6);
     translate([0,0,3]) sphere(r=.6,$fn=nf); }
     translate([dRight,-1,0]) { cylinder(h=1,r1=1.5,r2=.1,$fn=6);
     translate([0,0,3]) sphere(r=.6,$fn=nf); }
   }
   hull() { // horiz, flat part of DE segment
     translate([-dLeft+2,0,0]) cylinder(h=2,r1=2.5,r2=2,$fn=6);
     translate([dRight-2,0,0]) cylinder(h=2,r1=2.5,r2=2,$fn=6);
   }
   hull() {
     translate([dRight-5,6,0]) cylinder(h=2,r1=1.5,r2=1,$fn=6);
     translate([dRight+1,2,0]) cylinder(h=2,r1=1.5,r2=1,$fn=6);
   }
}}

module forkTab(h,r1,r2,len) {
difference(){
hull() { cylinder(h=h,r1=r1,r2=r2,$fn=48);
  translate([len+2,0,0]) cylinder(h=2,r1=2,r2=1,$fn=12); }
translate([len,0,-.1]) cylinder(h=3*NodeHeight,r=.6,$fn=6);
    drillHole(rad4);
}}

module imBEDmain(dLeft,dBase,dPerp) { //------------------------------------ BED
perpHeight = NodeHeight3; //3*TrueNodeHeight;  // same height as long hinge-pin
difference() { union() {
  difference() { union() {
     BEDhull(dLeft*.8,dPerp,.75*(dBase-dLeft),perpHeight,Brad);

     translate([-dLeft,0,0]) {
        rotate([0,0,5]) hull() {
           translate([0,0,NodeHeight+0.3]) forkTab(ForkHeight,Drad+2,rad4+1.4,forkLen);
           translate([NodeHeight, 0 , 0 ]) forkTab(    2     ,Drad+2,rad4+1.4,forkLen); }

        translate([dBase,0,0]) rotate([0,0,-5]) difference() {
           hull() { translate([-5*Drad,0,1.5]) sphere(r=1.5,$fn=12);
               cylinder(h=NodeHeight,r1=Drad+2, r2=Drad+1.8, $fn=48); }
           // hollow out hull a but...  injction mold style
           translate([0,0,-1.5]) { difference() { hull() {
               translate([-4*Drad+3,0,0]) cylinder(h=NodeHeight-1,r1=.4,r2=.2,$fn=6);
               cylinder(h=NodeHeight,r1=Drad-.1 ,r2=Drad-.4,$fn=24); }
               cylinder(h=NodeHeight,r1=Drad+1.7,r2=Drad+1.9,$fn=24); }}
       }

     } // end translate
   } // union

   translate([0,2,-1])
      BEDhull(dLeft*.8-3,dPerp-3,.75*(dBase-dLeft)-3,perpHeight-2,Drad-1);
   } // inner diff

   translate([0,dPerp,0])
      cylinder(h=perpHeight,r1=Brad+2.4,r2=Brad+1.8,$fn=48);
   }   // end second union

   //------------- main holes/knock outs
   translate([0,dPerp,0])drillHole(BradFree); // a little larger to move freely
   translate([(dBase-dLeft),0,0]) drillHole(Drad);

   // for Maxi version, drill hole in top half of "fork" node,
   // and knock out slot for in-plane CD linkage
   translate([-dLeft,0,0]) {

      translate([0,0,-.1]) {
         difference() { cube([28,33,2*(NodeHeight+.3)],center=true);
            hull() {
              translate([Drad+7,1,0]) cylinder(h=NodeHeight+.31,r=3,$fn=16);
              translate([Drad+14,2,0]) cylinder(h=NodeHeight+3,r=5,$fn=6);
              translate([Drad+14,10,0]) cylinder(h=NodeHeight+3,r=5,$fn=6);
            }
         }
      }
      drillHole(rad4);

      // drill hole to help allign fork linkage, must match linkage length below
      rotate([0,0,5]) translate([forkLen,0,0]) cylinder(h=3*NodeHeight,r=.6,$fn=6);
   }

  // diagnostic slice to examine walls
  //translate([0,-2,-2]) cube([4,44,33]);
}

// add other side of fork
//translate([-dLeft+0.7*forkLen,1.2*forkLen,0]) rotate([0,0,40])
//    forkTab(ForkHeight,Drad+2,rad4+1.4,forkLen);
}
//------------------------------------- end of imBEDmain

module BED1main(dLeft,dBase,dPerp) { //------------------------------------ BED
perpHeight = NodeHeight3; //3*TrueNodeHeight;  // same height as long hinge-pin
difference() { union() {
  difference() { union() {
     BEDrails(dLeft*.8,dPerp,.75*(dBase-dLeft),perpHeight,Brad);

     translate([-dLeft,0,0]) {
        rotate([0,0,5]) hull() {
           translate([0,0,NodeHeight+0.3]) forkTab(ForkHeight,Drad+2,rad4+1.4,forkLen-2);
           translate([NodeHeight, 0 , 0 ]) forkTab(    2     ,Drad+2,rad4+1.4,forkLen-2); }

        translate([dBase,0,0]) rotate([0,0,-5]) difference() {
           hull() { translate([-4*Drad,0,1.5]) sphere(r=1.5,$fn=12);
               cylinder(h=NodeHeight,r1=Drad+2, r2=Drad+1.8, $fn=48); }
           // hollow out hull a but...  injction mold style
           translate([0,0,-1.5]) { difference() { hull() {
               translate([-4*Drad+3,0,0]) cylinder(h=NodeHeight-1,r1=.4,r2=.2,$fn=6);
               cylinder(h=NodeHeight,r1=Drad-.1 ,r2=Drad-.4,$fn=24); }
               cylinder(h=NodeHeight,r1=Drad+1.7,r2=Drad+1.9,$fn=24); }}
       }

     } // end translate
   } // union

   //translate([0,2,-1])
   //   BEDhull(dLeft*.8-3,dPerp-3,.75*(dBase-dLeft)-3,perpHeight-2,Drad-1);
   } // inner diff

   translate([0,dPerp,0])
      cylinder(h=perpHeight,r1=Brad+2.4,r2=Brad+1.8,$fn=48);
   }   // end second union

   //------------- main holes/knock outs
   translate([0,dPerp,0])drillHole(BradFree); // a little larger to move freely
   translate([(dBase-dLeft),0,0]) drillHole(Drad);

   // for Maxi version, drill hole in top half of "fork" node,
   // and knock out slot for in-plane CD linkage
   translate([-dLeft,0,0]) {

      translate([0,0,-.1]) {
         difference() { cube([28,33,2*(NodeHeight+.3)],center=true);
            hull() {
              translate([Drad+7,1,0]) cylinder(h=NodeHeight+.31,r=3,$fn=16);
              translate([Drad+14,2,0]) cylinder(h=NodeHeight+3,r=5,$fn=6);
              translate([Drad+14,10,0]) cylinder(h=NodeHeight+3,r=5,$fn=6);
            }
         }
      }
      drillHole(rad4);

      // drill hole to help allign fork linkage, must match linkage length below
      rotate([0,0,5]) translate([forkLen,0,0]) cylinder(h=3*NodeHeight,r=.6,$fn=6);
   }

  // diagnostic slice to examine walls
  //translate([0,-2,-2]) cube([4,44,33]);
}

// custom support
sW=0.41;  // support width
sH=4.4;  // support height
sH2=sH/2;
color("Cyan") union() {
  translate([-28,1,sH2]) rotate([0,0,10]) cube([sW,8,sH],center=true);
  translate([-29.5,0,sH2]) rotate([0,0,5]) cube([sW,9,sH],center=true);
  translate([-31,0,sH2]) rotate([0,0,5]) cube([sW,9,sH],center=true);
  translate([-32.5,0,sH2]) rotate([0,0,5]) cube([sW,10,sH],center=true);
  translate([-34,0,sH2]) rotate([0,0,5]) cube([sW,10,sH],center=true);
  translate([-35.5,0,sH2]) rotate([0,0,5]) cube([sW,10,sH],center=true);
  translate([-37,0,sH2]) rotate([0,0,5]) cube([sW,9,sH],center=true);
  translate([-36.5,-2.5,sH2]) rotate([0,0,40]) cube([sW,7,sH],center=true);
  translate([-36.5,2.5,sH2]) rotate([0,0,-40]) cube([sW,7,sH],center=true);
  translate([-30,-2.5,sH2]) rotate([0,0,10]) cube([8,sW,sH],center=true);
  translate([-31,3.5,sH2]) rotate([0,0,-10]) cube([8,sW,sH],center=true);
  hull() {
    translate([-34,0,0]) cylinder(r1=2,r2=5,h=3.6,$fn=11);
    translate([-29,0.5,0]) rotate([0,0,15])
        scale([1,3,1]) cylinder(r1=.3,r2=1.5,h=3.6,$fn=6);
  }
}

}

//------------------------------------- end of BED1main

module imBED(dLeft,dBase,dPerp) { //------------------------------------ BED
imBEDmain(dLeft,dBase,dPerp);

// add other side of fork
translate([-dLeft+0.7*forkLen,1.2*forkLen,0]) rotate([0,0,40])
    forkTab(ForkHeight+.1,Drad+2,rad4+1.4,forkLen);
}

// Complete (Joined) version of BED, with in-place fork
module imBEDj(dLeft,dBase,dPerp) { //------------------------------------ BED
union() {
imBEDmain(dLeft,dBase,dPerp);

// add other side of fork, in place
translate([-dLeft,0,-.01]) { rotate([0,0,5]) {
    rotate([180,0,0]) forkTab(ForkHeight+.2,Drad+2,rad4+1.4,forkLen);

#hull(){
  translate([forkLen  ,0,0])cylinder(h=NodeHeight-2,r=2.8,$fn=12);
  translate([forkLen+1.5,4,1.1])sphere(r=1,$fn=6);
  translate([forkLen+2,0,0])cylinder(h=NodeHeight-2,r=2.2,$fn=12);}
}}

}}

//imBED(DEleft,DE,DEperp);

// version of BED intended for one-sided injection mold
module BED1(dLeft,dBase,dPerp) { //------------------------------------ BED
BED1main(dLeft,dBase,dPerp);

// add other side of fork
translate([-dLeft+0.7*forkLen,1.2*forkLen,0]) rotate([0,0,40])
    forkTab(ForkHeight+.1,Drad+2,rad4+1.4,forkLen);
}

// $URL: svn+ssh://mrwhat@ssh.boim.com/home/mrwhat/svn/Walker/trunk/JansenBED.scad $
// $Id: JansenBED.scad 435 2015-03-02 15:21:04Z mrwhat $

// main BED code, more injection-mold-like model

// Uses a ton of stuff from Jansen.scad.
// Use from an #include in  Jansen.scad.

forkLen = 3.5*LinkRad;  // forks around linkage in BED
nf=24;  // faces for hull components

module BEDhull(dLeft,dPerp,dRight,ph,rp) { hull() {
translate([-dLeft,-1,    0]) cylinder(h=1,r1=1,r2=.1,$fn=nf);
translate([dRight,-1,    0]) cylinder(h=1,r1=1,r2=.1,$fn=nf);
translate([ rp,dPerp+1,0]) cylinder(h=1,r1=1,r2=.1,$fn=nf);
translate([-rp,dPerp+1,0]) cylinder(h=1,r1=1,r2=.1,$fn=nf);
translate([ 0,dPerp-rp,ph-1]) sphere(r=1,$fn=nf);
translate([4-dLeft ,1,2]) sphere(r=1,$fn=nf);
translate([dRight-4,1,2]) sphere(r=1,$fn=nf);
}}

module BEDsideRail(x,dPerp,ph) {
hull() {
   translate([x,-1,  0]) {
     cylinder(h=1,r1=1.2,r2=.1,$fn=nf);
     translate([0,0,2]) sphere(r=.6,$fn=nf); }
   translate([0,dPerp+2,0]) {
     cylinder(h=1,r1=1.5,r2=.1,$fn=nf);
     translate([0,0,ph-.6]) sphere(r=.6,$fn=nf); }
   }
hull() {
   if (x < 0) { translate([x+2,0,0]) cylinder(h=2,r1=2.5,r2=2,$fn=nf); }
   else       { translate([x-2,0,0]) cylinder(h=2,r1=2.5,r2=2,$fn=nf); }
   translate([0,dPerp,0]) cylinder(h=2,r1=2.5,r2=2,$fn=nf);
   }
}

module BEDrails(dLeft,dPerp,dRight,ph,rp) {
union() {
   BEDsideRail(-dLeft,dPerp,ph);
   BEDsideRail(dRight,dPerp,ph);
   hull() { // vert bar part, DE
     translate([-dLeft,-1,0]) { cylinder(h=1,r1=1.5,r2=.1,$fn=6);
     translate([0,0,3]) sphere(r=.6,$fn=nf); }
     translate([dRight,-1,0]) { cylinder(h=1,r1=1.5,r2=.1,$fn=6);
     translate([0,0,3]) sphere(r=.6,$fn=nf); }
   }
   hull() { // horiz, flat part of DE segment
     translate([-dLeft+2,0,0]) cylinder(h=2,r1=2.5,r2=2,$fn=6);
     translate([dRight-2,0,0]) cylinder(h=2,r1=2.5,r2=2,$fn=6);
   }
   hull() {
     translate([dRight-5,6,0]) cylinder(h=2,r1=1.5,r2=1,$fn=6);
     translate([dRight+1,2,0]) cylinder(h=2,r1=1.5,r2=1,$fn=6);
   }
}}

module forkTab(h,r1,r2,len) {
difference(){
hull() { cylinder(h=h,r1=r1,r2=r2,$fn=48);
  translate([len+2,0,0]) cylinder(h=2,r1=2,r2=1,$fn=12); }
translate([len,0,-.1]) cylinder(h=3*NodeHeight,r=.6,$fn=6);
    drillHole(rad4);
}}

module imBEDmain(dLeft,dBase,dPerp) { //------------------------------------ BED
perpHeight = NodeHeight3; //3*TrueNodeHeight;  // same height as long hinge-pin
difference() { union() {
  difference() { union() {
     BEDhull(dLeft*.8,dPerp,.75*(dBase-dLeft),perpHeight,Brad);

     translate([-dLeft,0,0]) {
        rotate([0,0,5]) hull() {
           translate([0,0,NodeHeight+0.3]) forkTab(ForkHeight,Drad+2,rad4+1.4,forkLen);
           translate([NodeHeight, 0 , 0 ]) forkTab(    2     ,Drad+2,rad4+1.4,forkLen); }

        translate([dBase,0,0]) rotate([0,0,-5]) difference() {
           hull() { translate([-5*Drad,0,1.5]) sphere(r=1.5,$fn=12);
               cylinder(h=NodeHeight,r1=Drad+2, r2=Drad+1.8, $fn=48); }
           // hollow out hull a but...  injction mold style
           translate([0,0,-1.5]) { difference() { hull() {
               translate([-4*Drad+3,0,0]) cylinder(h=NodeHeight-1,r1=.4,r2=.2,$fn=6);
               cylinder(h=NodeHeight,r1=Drad-.1 ,r2=Drad-.4,$fn=24); }
               cylinder(h=NodeHeight,r1=Drad+1.7,r2=Drad+1.9,$fn=24); }}
       }

     } // end translate
   } // union

   translate([0,2,-1])
      BEDhull(dLeft*.8-3,dPerp-3,.75*(dBase-dLeft)-3,perpHeight-2,Drad-1);
   } // inner diff

   translate([0,dPerp,0])
      cylinder(h=perpHeight,r1=Brad+2.4,r2=Brad+1.8,$fn=48);
   }   // end second union

   //------------- main holes/knock outs
   translate([0,dPerp,0])drillHole(BradFree); // a little larger to move freely
   translate([(dBase-dLeft),0,0]) drillHole(Drad);

   // for Maxi version, drill hole in top half of "fork" node,
   // and knock out slot for in-plane CD linkage
   translate([-dLeft,0,0]) {

      translate([0,0,-.1]) {
         difference() { cube([28,33,2*(NodeHeight+.3)],center=true);
            hull() {
              translate([Drad+7,1,0]) cylinder(h=NodeHeight+.31,r=3,$fn=16);
              translate([Drad+14,2,0]) cylinder(h=NodeHeight+3,r=5,$fn=6);
              translate([Drad+14,10,0]) cylinder(h=NodeHeight+3,r=5,$fn=6);
            }
         }
      }
      drillHole(rad4);

      // drill hole to help allign fork linkage, must match linkage length below
      rotate([0,0,5]) translate([forkLen,0,0]) cylinder(h=3*NodeHeight,r=.6,$fn=6);
   }

  // diagnostic slice to examine walls
  //translate([0,-2,-2]) cube([4,44,33]);
}

// add other side of fork
//translate([-dLeft+0.7*forkLen,1.2*forkLen,0]) rotate([0,0,40])
//    forkTab(ForkHeight,Drad+2,rad4+1.4,forkLen);
}
//------------------------------------- end of imBEDmain

module BED1main(dLeft,dBase,dPerp) { //------------------------------------ BED
perpHeight = NodeHeight3; //3*TrueNodeHeight;  // same height as long hinge-pin
difference() { union() {
  difference() { union() {
     BEDrails(dLeft*.8,dPerp,.75*(dBase-dLeft),perpHeight,Brad);

     translate([-dLeft,0,0]) {
        rotate([0,0,5]) hull() {
           translate([0,0,NodeHeight+0.3]) forkTab(ForkHeight,Drad+2,rad4+1.4,forkLen-2);
           translate([NodeHeight, 0 , 0 ]) forkTab(    2     ,Drad+2,rad4+1.4,forkLen-2); }

        translate([dBase,0,0]) rotate([0,0,-5]) difference() {
           hull() { translate([-4*Drad,0,1.5]) sphere(r=1.5,$fn=12);
               cylinder(h=NodeHeight,r1=Drad+2, r2=Drad+1.8, $fn=48); }
           // hollow out hull a but...  injction mold style
           translate([0,0,-1.5]) { difference() { hull() {
               translate([-4*Drad+3,0,0]) cylinder(h=NodeHeight-1,r1=.4,r2=.2,$fn=6);
               cylinder(h=NodeHeight,r1=Drad-.1 ,r2=Drad-.4,$fn=24); }
               cylinder(h=NodeHeight,r1=Drad+1.7,r2=Drad+1.9,$fn=24); }}
       }

     } // end translate
   } // union

   //translate([0,2,-1])
   //   BEDhull(dLeft*.8-3,dPerp-3,.75*(dBase-dLeft)-3,perpHeight-2,Drad-1);
   } // inner diff

   translate([0,dPerp,0])
      cylinder(h=perpHeight,r1=Brad+2.4,r2=Brad+1.8,$fn=48);
   }   // end second union

   //------------- main holes/knock outs
   translate([0,dPerp,0])drillHole(BradFree); // a little larger to move freely
   translate([(dBase-dLeft),0,0]) drillHole(Drad);

   // for Maxi version, drill hole in top half of "fork" node,
   // and knock out slot for in-plane CD linkage
   translate([-dLeft,0,0]) {

      translate([0,0,-.1]) {
         difference() { cube([28,33,2*(NodeHeight+.3)],center=true);
            hull() {
              translate([Drad+7,1,0]) cylinder(h=NodeHeight+.31,r=3,$fn=16);
              translate([Drad+14,2,0]) cylinder(h=NodeHeight+3,r=5,$fn=6);
              translate([Drad+14,10,0]) cylinder(h=NodeHeight+3,r=5,$fn=6);
            }
         }
      }
      drillHole(rad4);

      // drill hole to help allign fork linkage, must match linkage length below
      rotate([0,0,5]) translate([forkLen,0,0]) cylinder(h=3*NodeHeight,r=.6,$fn=6);
   }

  // diagnostic slice to examine walls
  //translate([0,-2,-2]) cube([4,44,33]);
}

// custom support
color("Cyan") union() {
  translate([-28,1,2.2]) rotate([0,0,10]) cube([0.35,8,4.4],center=true);
  translate([-29.5,0,2.2]) rotate([0,0,5]) cube([0.35,9,4.4],center=true);
  translate([-31,0,2.2]) rotate([0,0,5]) cube([0.35,9,4.4],center=true);
  translate([-32.5,0,2.2]) rotate([0,0,5]) cube([0.35,10,4.4],center=true);
  translate([-34,0,2.2]) rotate([0,0,5]) cube([0.35,10,4.4],center=true);
  translate([-35.5,0,2.2]) rotate([0,0,5]) cube([0.35,10,4.4],center=true);
  translate([-37,0,2.2]) rotate([0,0,5]) cube([0.35,9,4.4],center=true);
  translate([-36.5,-2.5,2.2]) rotate([0,0,40]) cube([0.35,7,4.4],center=true);
  translate([-36.5,2.5,2.2]) rotate([0,0,-40]) cube([0.35,7,4.4],center=true);
  translate([-30,-2.5,2.2]) rotate([0,0,10]) cube([8,0.35,4.4],center=true);
  translate([-31,3.5,2.2]) rotate([0,0,-10]) cube([8,0.35,4.4],center=true);
}

}

//------------------------------------- end of BED1main

module imBED(dLeft,dBase,dPerp) { //------------------------------------ BED
imBEDmain(dLeft,dBase,dPerp);

// add other side of fork
translate([-dLeft+0.7*forkLen,1.2*forkLen,0]) rotate([0,0,40])
    forkTab(ForkHeight+.1,Drad+2,rad4+1.4,forkLen);
}

// Complete (Joined) version of BED, with in-place fork
module imBEDj(dLeft,dBase,dPerp) { //------------------------------------ BED
union() {
imBEDmain(dLeft,dBase,dPerp);

// add other side of fork, in place
translate([-dLeft,0,-.01]) { rotate([0,0,5]) {
    rotate([180,0,0]) forkTab(ForkHeight+.2,Drad+2,rad4+1.4,forkLen);

#hull(){
  translate([forkLen  ,0,0])cylinder(h=NodeHeight-2,r=2.8,$fn=12);
  translate([forkLen+1.5,4,1.1])sphere(r=1,$fn=6);
  translate([forkLen+2,0,0])cylinder(h=NodeHeight-2,r=2.2,$fn=12);}
}}

}}

//imBED(DEleft,DE,DEperp);

// version of BED intended for one-sided injection mold
module BED1(dLeft,dBase,dPerp) { //------------------------------------ BED
BED1main(dLeft,dBase,dPerp);

// add other side of fork
translate([-dLeft+0.7*forkLen,1.2*forkLen,0]) rotate([0,0,40])
    forkTab(ForkHeight+.1,Drad+2,rad4+1.4,forkLen);
}


Tail still messed

Tail still messed

// Unicorn by Paul Houghton © 2015, CC BY-NC-AS license, https://creativecommons.org/licenses/
$fn=12;

scale = 1;

head_big_radius = 10*scale;
head_small_radius = 4.5*scale;
head_length = 18*scale;
head_angle = 50;

horn_length = 20*scale;
horn_radius = 2.8*scale;

mane_thickness = 2*horn_radius;
mane_radius = head_big_radius;
mane_height = head_big_radius * 0.7;
mane_x = head_big_radius * 0.28;
mane_length_x = 10*scale;
mane_length_z = 20*scale;

hair_thickness = mane_thickness / 8;
hair_spacing = mane_thickness / 2;

neck_radius = 3*scale;
neck_ratio = .2; // Flattens the interface to the top body
neck_top_x = 3*scale;

body_x = 15*scale;
body_z = 28*scale;
body_radius = 14*scale;
body_back_radius = 12*scale;
body_length = 33*scale;

leg_length = (33*scale + body_radius);
leg_radius = 4*scale;

cute_leg_first_ratio = 0.5;
cute_leg_second_ratio = 0.25;
cute_leg_third_ratio = 0.11;

tail_thickness = mane_thickness;
tail_radius = 1.5 * body_back_radius / 3;
tail_x = 2*body_x + body_length - tail_radius;
tail_height = -body_z + 1.7*tail_radius;
tail_tip_length = 30;

base_thickness = 10*scale;
base_width = 40*scale;
base_corner_radius = 5*scale;
base_length = 100*scale;

module head() {
    rotate([0, -head_angle, 0]) {
        hull () {
            sphere(r=head_big_radius);
            translate([-head_length, 0, 0])
                sphere(r=head_small_radius);
        }
    }
}

module horn() {
    rotate([0, -head_angle, 0]) {
        translate([0, 0, head_big_radius - .2*scale])
        cylinder(h = horn_length, r1 = horn_radius, r2 = 0);
    }
}

module neck() {
    hull() {
        translate([neck_top_x, 0, 0]) rotate([0, 180, 0]) {
            cylinder(h = head_big_radius - .2*scale, r1 = neck_radius, r2 = neck_radius);
        }
        translate([body_x, 0, -body_z])
            difference() {
                sphere(r = body_radius);
                translate([body_radius*neck_ratio, -body_radius, -body_radius])
                    cube([body_radius, 2*body_radius, 2*body_radius]);
            }
        }
}

module hair_line(x = 0, z = 0, hair_radius = mane_radius, delta_x = body_x, delta_z = body_z) {
    translate([x, 0, z])
            difference() {
                hull() {
                    cylinder(h = mane_thickness, r = hair_radius);
                    translate([delta_x, -delta_z, 0])
                        cylinder(h = mane_thickness, r = hair_radius);
                }
                hull() {
                    cylinder(h = mane_thickness, r = hair_radius - hair_spacing);
                    translate([delta_x, -delta_z, 0])
                        cylinder(h = mane_thickness, r = hair_radius - hair_spacing);
                }
            }
}

module mane() {
    translate([mane_x, mane_thickness/2, mane_height])
        rotate([90, 0, 0]) {
                hull() {
                    translate([0, 0, hair_thickness])
                    cylinder(h = mane_thickness - 2*hair_thickness, r = mane_radius);
                    translate([body_x, -body_z, 0])
                       cylinder(h = mane_thickness - 2*hair_thickness, r = mane_radius);
                }
              hair_line();
              hair_line(hair_radius = mane_radius - 2*hair_spacing);
        }
}

module body() {
    translate([body_x, 0, -body_z])
        hull() {
            sphere(r = body_radius);
            translate([body_length, 0, 0])
                sphere(r = body_back_radius);
        }
}

module leg(lengthwards=0, sideways=0, theta=20) {
    translate([body_x + lengthwards, sideways, -body_z])
        rotate([180 + theta, 0, 0]) {
        cylinder(h = leg_length, r1 = leg_radius, r2 = leg_radius);
        }
}

module cute_leg(lengthwards=0, sideways=0, downwards=0, theta=20, rise_angle=70) {
    translate([body_x + lengthwards, sideways, -body_z - downwards])
        rotate([180 + theta, rise_angle, 0]) {
            cylinder(h = leg_length*cute_leg_first_ratio, r1 = leg_radius, r2 = leg_radius);
            translate([0, 0, leg_length*cute_leg_first_ratio])
                union() {
                    sphere(r = leg_radius);
                    rotate([0, 90, 0]) {
                        cylinder(h = leg_length*cute_leg_second_ratio, r1 = leg_radius, r2 = leg_radius);
                    }
                    translate([leg_length*cute_leg_second_ratio, 0, 0])
                        union() {
                            sphere(r = leg_radius);
                            rotate([0, 90 + rise_angle, 0]) {
                                cylinder(h = leg_length*cute_leg_third_ratio, r1 = leg_radius, r2 = leg_radius);
                            }
                        }
                }
    }
}

module tailhair_line(x = 0, z = 0, delta_x = body_x, delta_z = 1.2*body_z) {
    translate([x, 0, z - hair_thickness])
            difference() {
                hull() {
                    cylinder(h = tail_thickness, r = tail_radius);
                    translate([delta_x, -delta_z, 0])
                        cube([tail_tip_length, tail_tip_length - hair_thickness, tail_thickness]);
                }
                hull() {
                    cylinder(h = tail_thickness, r = tail_radius - hair_spacing);
                    translate([delta_x + hair_spacing, -delta_z + hair_spacing, 0])
 #                       cube([tail_tip_length, tail_tip_length - hair_thickness, tail_thickness]);
                }
            }
}

module tail() {
    translate([tail_x, tail_thickness/2 - hair_thickness, tail_height])
        rotate([90, 0, 0]) {
            intersection() {
                union() {
                    hull() {
                        cylinder(h = tail_thickness - 2*hair_thickness, r = tail_radius);
                        translate([body_x, -1.2*body_z, 0])
                            cube([tail_tip_length, tail_tip_length, tail_thickness - 2*hair_thickness]);
                    }
color("blue")                  tailhair_line();
                }
                cylinder(h = tail_thickness, r = tail_tip_length*1.25);
            }
        }
}

module base() {
    translate([body_x + 0.6*body_length, 0, -leg_length - body_z])
        minkowski() {
            cylinder(h = base_thickness / 3, r = base_corner_radius);
            cube([base_length, base_width - 2*base_corner_radius, base_thickness/3], center = true);
        }
}

difference() { // difference() -> no base, or union() -> solid base
    union() {
        head();
        horn();
        neck();
        mane();
        body();
        leg(theta=5, sideways=3*scale);
        cute_leg(theta=-5, sideways=-3*scale, downwards=3*scale);
        leg(lengthwards = body_length, sideways=2*scale, theta=15);
        leg(lengthwards = body_length, sideways=-2*scale, theta=-15);
        tail();
    }
    base();
}

// Unicorn by Paul Houghton © 2015, CC BY-NC-AS license, https://creativecommons.org/licenses/
$fn=90;

scale = 1;

head_big_radius = 10*scale;
head_small_radius = 4.5*scale;
head_length = 18*scale;
head_angle = 50;

horn_length = 20*scale;
horn_radius = 2.8*scale;

mane_thickness = 2*horn_radius;
mane_radius = head_big_radius;
mane_height = head_big_radius * 0.7;
mane_x = head_big_radius * 0.28;
mane_length_x = 10*scale;
mane_length_z = 20*scale;

neck_radius = 3*scale;
neck_ratio = .2; // Flattens the interface to the top body
neck_top_x = 3*scale;

body_x = 15*scale;
body_z = 28*scale;
body_radius = 14*scale;
body_back_radius = 12*scale;
body_length = 33*scale;

leg_length = (33*scale + body_radius);
leg_radius = 4*scale;

cute_leg_first_ratio = 0.5;
cute_leg_second_ratio = 0.25;
cute_leg_third_ratio = 0.11;

base_thickness = 10*scale;
base_width = 40*scale;
base_corner_radius = 5*scale;
base_length = 100*scale;

module head() {
    rotate([0, -head_angle, 0]) {
        hull () {
            sphere(r=head_big_radius);
            translate([-head_length, 0, 0])
                sphere(r=head_small_radius);
        }
    }
}

module horn() {
    rotate([0, -head_angle, 0]) {
        translate([0, 0, head_big_radius - .2*scale])
        cylinder(h = horn_length, r1 = horn_radius, r2 = 0);
    }
}

module neck() {
    hull() {
        translate([neck_top_x, 0, 0]) rotate([0, 180, 0]) {
            cylinder(h = head_big_radius - .2*scale, r1 = neck_radius, r2 = neck_radius);
        }
        translate([body_x, 0, -body_z])
            difference() {
                sphere(r = body_radius);
                translate([body_radius*neck_ratio, -body_radius, -body_radius])
                    cube([body_radius, 2*body_radius, 2*body_radius]);
            }
        }
}

hair_thickness = mane_thickness / 10;
hair_spacing = mane_thickness / 2;

module hair_line(x = 0, z = 0, hair_radius = mane_radius, delta_x = body_x, delta_z = body_z) {
    translate([x, mane_thickness/2, z])
            difference() {
                hull() {
                    cylinder(h = mane_thickness, r = hair_radius);
                    translate([delta_x, -delta_z, 0])
                        cylinder(h = mane_thickness, r = hair_radius);
                }
                hull() {
                    cylinder(h = mane_thickness, r = hair_radius - hair_spacing);
                    translate([delta_x, -delta_z, 0])
                        cylinder(h = mane_thickness, r = hair_radius - hair_spacing);
                }
            }
}

module mane() {
    translate([mane_x, mane_thickness/2, mane_height])
        rotate([90, 0, 0]) {
                hull() {
                    translate([0, 0, hair_thickness])
                    cylinder(h = mane_thickness - 2*hair_thickness, r = mane_radius);
                    translate([body_x, -body_z, 0])
                       cylinder(h = mane_thickness - 2*hair_thickness, r = mane_radius);
                }
              hair_line();
              hair_line(hair_radius = mane_radius - 2*hair_spacing);
        }
}

module body() {
    translate([body_x, 0, -body_z])
        hull() {
            sphere(r = body_radius);
            translate([body_length, 0, 0])
                sphere(r = body_back_radius);
        }
}

module leg(lengthwards=0, sideways=0, theta=20) {
    translate([body_x + lengthwards, sideways, -body_z])
        rotate([180 + theta, 0, 0]) {
        cylinder(h = leg_length, r1 = leg_radius, r2 = leg_radius);
        }
}

module cute_leg(lengthwards=0, sideways=0, downwards=0, theta=20, rise_angle=70) {
    translate([body_x + lengthwards, sideways, -body_z - downwards])
        rotate([180 + theta, rise_angle, 0]) {
            cylinder(h = leg_length*cute_leg_first_ratio, r1 = leg_radius, r2 = leg_radius);
            translate([0, 0, leg_length*cute_leg_first_ratio])
                union() {
                    sphere(r = leg_radius);
                    rotate([0, 90, 0]) {
                        cylinder(h = leg_length*cute_leg_second_ratio, r1 = leg_radius, r2 = leg_radius);
                    }
                    translate([leg_length*cute_leg_second_ratio, 0, 0])
                        union() {
                            sphere(r = leg_radius);
                            rotate([0, 90 + rise_angle, 0]) {
                                cylinder(h = leg_length*cute_leg_third_ratio, r1 = leg_radius, r2 = leg_radius);
                            }
                        }
                }
    }
}

tail_x = 2*body_x + body_length;
tail_thickness = mane_thickness;
tail_radius = body_back_radius;
tail_height = -body_z + tail_radius/2;

module tail() {
    translate([tail_x, tail_thickness/2, tail_height])
        rotate([90, 0, 0]) {
            hull() {
                cylinder(h = mane_thickness, r = tail_radius);
                translate([1.5*body_x, 1.5*(-body_z), 0])
                    cube([tail_thickness, tail_thickness, tail_thickness]);
            }
        }
}

module base() {
    translate([body_x + 0.6*body_length, 0, -leg_length - body_z])
        minkowski() {
            cylinder(h = base_thickness / 3, r = base_corner_radius);
            cube([base_length, base_width - 2*base_corner_radius, base_thickness/3], center = true);
        }
}

difference() { // difference() -> no base, or union() -> solid base
    union() {
        head();
        horn();
        neck();
        mane();
        body();
        leg(theta=5, sideways=3*scale);
        cute_leg(theta=-5, sideways=-3*scale, downwards=3*scale);
        leg(lengthwards = body_length, sideways=2*scale, theta=15);
        leg(lengthwards = body_length, sideways=-2*scale, theta=-15);
        tail();
    }
 #   base();
}


Added the boom and placed/sized/rotated parts.

module makeMainShape(shrinkValue){
	translate([shrinkValue/2,0,shrinkValue])
	cube([boardLength-shrinkValue,boardWidth-shrinkValue*2,totalHeight],true);
	rotate([0,90,0])translate([0,0,(boardLength+cowlingLength)/2-1-shrinkValue])
	intersection(){
		cylinder(cowlingLength+1, cowlingTailRadius-shrinkValue, cowlingTipRadius-shrinkValue,true);
		translate([-shrinkValue,0,0]) cube([totalHeight,boardWidth-shrinkValue*2,cowlingLength-shrinkValue*2],true);
	}
}

tipDiameter = 15;
shoulderRadius = 15;
noseLength = 40;
wallThickeness = 0.4;
boomDiameter = 7.5;
boomLength = 825;
fuselageCornerRadius = 8.7;

servoWidth = 23;
servoHeight = 12;
servoDepth = 23;
servoMountThickness = 3;
servoMountOffset = 7;
servoMountWidth = 33;

servoPosOnBoom = 127;

module makeServo() {
	cube([servoWidth,servoHeight,servoDepth],true);
	translate([0,0,servoMountOffset/2]) cube([servoMountWidth,servoHeight,servoMountThickness],true);
}

module makeNose(offset){
	hull(){
		translate([0,0,noseLength]) sphere(tipDiameter-offset);
		translate([0,0,-offset]) mainFuselage(offset, 1);
		//sphere(shoulderRadius-offset);
	}
}

module hollowNose(){
	difference(){
		makeNose(0);
		union(){
			makeNose(wallThickeness);
			translate([0,0,-shoulderRadius/2])
				cube([shoulderRadius*2,shoulderRadius*2,shoulderRadius],true);
		}
	}
}

module solidNose(){
	difference(){
		union(){
			makeNose(0);
			translate([0,0,-5])
				mainFuselage(wallThickeness*2, 5);
		}
		cylinder(noseLength*2, boomDiameter/2+1, boomDiameter/2+1,true);
	}
}

module mainFuselage(offset, length){
hull()
for ( i = [0 : 3] )
	{
		rotate( i * 360 / 4 + 360 / 8, [0, 0, 1])
		translate([0, shoulderRadius, 0])
		cylinder(length,fuselageCornerRadius-offset,fuselageCornerRadius-offset);
	}
}
module fuselageLength(length){
	difference(){
		translate([0,0,-length])mainFuselage(0, length);
		translate([0,0,-length-wallThickeness])mainFuselage(wallThickeness, length+wallThickeness*2);
	}
}
module makeServoGroup(){
	translate([-4.5,boomDiameter/2+servoHeight/2,noseLength-servoMountWidth/2-servoPosOnBoom]) rotate(90,[0,1,0]) {
		makeServo();
		translate([28,0,9]) rotate(180,[1,0,0]) makeServo();
	}
}
module makeBoom() {
	translate([0,0,noseLength-boomLength/2])
		cylinder(boomLength, boomDiameter/2, boomDiameter/2,true);
}
module makeNonPrintedParts() {
	makeServoGroup();
	makeBoom();
}
solidNose();
%fuselageLength(150);
//hollowNose();
//mainFuselage(0,1);
makeNonPrintedParts();

module makeMainShape(shrinkValue){
	translate([shrinkValue/2,0,shrinkValue])
	cube([boardLength-shrinkValue,boardWidth-shrinkValue*2,totalHeight],true);
	rotate([0,90,0])translate([0,0,(boardLength+cowlingLength)/2-1-shrinkValue])
	intersection(){
		cylinder(cowlingLength+1, cowlingTailRadius-shrinkValue, cowlingTipRadius-shrinkValue,true);
		translate([-shrinkValue,0,0]) cube([totalHeight,boardWidth-shrinkValue*2,cowlingLength-shrinkValue*2],true);
	}
}

tipDiameter = 15;
shoulderRadius = 18;
noseLength = 40;
wallThickeness = 0.4;
boomDiameter = 7.5;
boomLength = 825;
fuselageCornerRadius = 8.7;

module makeServo(){
	servoWidth = 23;
	servoHeight = 12;
	servoDepth = 23;
	servoMountThickness = 3;
	servoMountOffset = 7;
	servoMountWidth = 33;

	cube([servoWidth,servoHeight,servoDepth],true);
	translate([0,0,servoMountOffset/2]) cube([servoMountWidth,servoHeight,servoMountThickness],true);
}

module makeNose(offset){
	hull(){
		translate([0,0,noseLength]) sphere(tipDiameter-offset);
		translate([0,0,-offset]) mainFuselage(offset, 1);
		//sphere(shoulderRadius-offset);
	}
}

module hollowNose(){
	difference(){
		makeNose(0);
		union(){
			makeNose(wallThickeness);
			translate([0,0,-shoulderRadius/2])
				cube([shoulderRadius*2,shoulderRadius*2,shoulderRadius],true);
		}
	}
}

module solidNose(){
	difference(){
		union(){
			makeNose(0);
			translate([0,0,-5])
				mainFuselage(wallThickeness*2, 5);
		}
		cylinder(noseLength, boomDiameter, boomDiameter,true);
	}
}

module mainFuselage(offset, length){
hull()
for ( i = [0 : 3] )
	{
		rotate( i * 360 / 4, [0, 0, 1])
		translate([0, shoulderRadius, 0])
		cylinder(length,fuselageCornerRadius-offset,fuselageCornerRadius-offset);
	}
}
module fuselageLength(length){
	difference(){
		translate([0,0,-length])mainFuselage(0, length);
		translate([0,0,-length-wallThickeness])mainFuselage(wallThickeness, length+wallThickeness*2);
	}
}
module makeServoGroup(){
	makeServo();
	translate([28,0,9]) rotate(180,[1,0,0]) makeServo();
}
//solidNose();
fuselageLength(15);
//hollowNose();
//mainFuselage(0,1);
%makeServoGroup();


config: define y motor z offset from belt path

include <thing_libutils/units.scad>
include <thing_libutils/system.scad>
include <thing_libutils/bearing_data.scad>
include <thing_libutils/pulley.scad>
include <thing_libutils/bearing-linear-data.scad>
/*include <thing_libutils/thread-data.scad>*/
include <thing_libutils/nut-data.scad>
include <thing_libutils/timing-belts-data.scad>

include <MCAD/stepper.scad>

use <thing_libutils/misc.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 : 1;

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

$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;
Mat_filament = Mat_PlasticBlack;

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 = NutHexM5;
extrusion_nut_dia = lookup(NutWidthMax, extrusion_nut);

extrusion_mount_thread = ThreadM4;

// for tapped ends
extrusion_end_nut = NutHexM6;

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

gantry_connector_thickness = 5;

rod_fit_tolerance=1.01;

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

xaxis_rod_distance = 65*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_top = LinearBearingLM10;
xaxis_bearing_bottom = xaxis_bearing_top;

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+get(LinearBearingOuterDiameter, xaxis_bearing_top)/2;

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

xaxis_endstop_type = "SWITCH";
/*xaxis_endstop_type = "SN04";*/

yaxis_rod_distance = 170*mm;
yaxis_rod_d = 11.975*mm;
yaxis_rod_l = 500*mm;
yaxis_bearing = LinearBearingLM12;
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_belt = TimingBelt_GT2_2;
yaxis_belt_width = 6*mm;
yaxis_belt_path_offset_x = -yaxis_pulley_inner_d/2;
yaxis_belt_path_offset_z = 5*mm;

yaxis_motor_offset_z = yaxis_belt_path_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 = 10*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];
Mat_PrintCarriage = Mat_Aluminium;
Mat_PrintBed = [.6,.5,.5];

zaxis_rod_d = 11.975*mm;
zaxis_rod_l = 500*mm;
// relative to entire machine
zaxis_rod_offset = [0,-20*mm,0];
zaxis_bearing = LinearBearingLMH12L;
zaxis_bearing_ID=get(LinearBearingInnerDiameter,zaxis_bearing);
zaxis_bearing_OD=get(LinearBearingOuterDiameter,zaxis_bearing);
zaxis_bearing_L=get(LinearBearingLength,zaxis_bearing);

// 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_nut_mat = Mat_PlasticBlack;

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 = extrusion_mount_thread;
zmotor_mount_clamp_nut = NutHexM4;
zmotor_mount_clamp_thread_dia = lookup(ThreadSize, zmotor_mount_clamp_thread);
zmotor_mount_clamp_nut_dia = lookup(NutWidthMin, zmotor_mount_clamp_nut);
zmotor_mount_clamp_nut_thick = lookup(NutThickness, 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_OD/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 screw offset from lower extrusion (outer)
zmotor_mount_screw_offset_x = zmotor_w/2 + zmotor_mount_motor_offset;

// z rod offset from lower extrusion (outer)
zmotor_mount_rod_offset_x = zmotor_mount_screw_offset_x + zaxis_rod_screw_distance_x;

include <thing_libutils/units.scad>
include <thing_libutils/system.scad>
include <thing_libutils/bearing_data.scad>
include <thing_libutils/pulley.scad>
include <thing_libutils/bearing-linear-data.scad>
/*include <thing_libutils/thread-data.scad>*/
include <thing_libutils/nut-data.scad>
include <thing_libutils/timing-belts-data.scad>

include <MCAD/stepper.scad>

use <thing_libutils/misc.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 : 1;

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

$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;
Mat_filament = Mat_PlasticBlack;

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 = NutHexM5;
extrusion_nut_dia = lookup(NutWidthMax, extrusion_nut);

extrusion_mount_thread = ThreadM4;

// for tapped ends
extrusion_end_nut = NutHexM6;

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

gantry_connector_thickness = 5;

rod_fit_tolerance=1.01;

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

xaxis_rod_distance = 65*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_top = LinearBearingLM10;
xaxis_bearing_bottom = xaxis_bearing_top;

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+get(LinearBearingOuterDiameter, xaxis_bearing_top)/2;

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

xaxis_endstop_type = "SWITCH";
/*xaxis_endstop_type = "SN04";*/

yaxis_rod_distance = 170*mm;
yaxis_rod_d = 11.975*mm;
yaxis_rod_l = 500*mm;
yaxis_bearing = LinearBearingLM12;
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 = TimingBelt_GT2_2;
yaxis_belt_width = 6*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 = 10*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];
Mat_PrintCarriage = Mat_Aluminium;
Mat_PrintBed = [.6,.5,.5];

zaxis_rod_d = 11.975*mm;
zaxis_rod_l = 500*mm;
// relative to entire machine
zaxis_rod_offset = [0,-20*mm,0];
zaxis_bearing = LinearBearingLMH12L;
zaxis_bearing_ID=get(LinearBearingInnerDiameter,zaxis_bearing);
zaxis_bearing_OD=get(LinearBearingOuterDiameter,zaxis_bearing);
zaxis_bearing_L=get(LinearBearingLength,zaxis_bearing);

// 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_nut_mat = Mat_PlasticBlack;

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 = extrusion_mount_thread;
zmotor_mount_clamp_nut = NutHexM4;
zmotor_mount_clamp_thread_dia = lookup(ThreadSize, zmotor_mount_clamp_thread);
zmotor_mount_clamp_nut_dia = lookup(NutWidthMin, zmotor_mount_clamp_nut);
zmotor_mount_clamp_nut_thick = lookup(NutThickness, 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_OD/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 screw offset from lower extrusion (outer)
zmotor_mount_screw_offset_x = zmotor_w/2 + zmotor_mount_motor_offset;

// z rod offset from lower extrusion (outer)
zmotor_mount_rod_offset_x = zmotor_mount_screw_offset_x + zaxis_rod_screw_distance_x;


Create deksobiroza_2.scad

Create deksobiroza_2.scad

error: pathspec '3D-models/SCAD/deksobiroza_2.scad' did not match any file(s) known to git


Add micro USB port for Pro Micro board

Add micro USB port for Pro Micro board

/*
  Vitamin: Pro Micro
  Model of an Arduino Pro Micro

  Derived from: https://github.com/sparkfun/Pro_Micro/
           and: https://github.com/sparkfun/Arduino_Pro_Mini_328/

  Authors:
    Jamie Osborne (@jmeosbn)

  Local Frame:
    Point of origin is the centre of the bottom left pin (9)

  Parameters:
    FIXME: type: can be "mini", or "micro";
           otherwise returns a blank board with header pin holes

  Returns:
    FIXME: Model of an Arduino Pro Mini/Micro with header holes
*/

// PCB Variables
holeDiam  = 1.25;         // The hole diameter in mm
holeSpace = 2.54;         // The spacing of the holes in mm
holeInset = holeSpace/2;  // The spacing of the holes in mm
pcbHeight = .063 * 25.4;  // The thickness of the PCB in mm
pcbLength =  1.3 * 25.4;  // The length of the PCB in mm
pcbWidth  =  0.7 * 25.4;  // The width of the PCB in mm

// Pro Micro/Mini
board_colour = [26/255, 90/255, 160/255];
metal_colour = [220/255, 220/255, 220/255];

module Micro_USB_Clearance() {
  // Rough dimensions for micro usb header
  micro_usb_area    = [7.7, 5.2];
  micro_usb_height  = 2.7;

  color(metal_colour)
  translate([pcbWidth/2 - holeInset, pcbLength - holeSpace, pcbHeight])
  linear_extrude(height=2.7)
    square(size = micro_usb_area, center = true);
}

module ArduinoPro_PCB() {
  // Bare PCB, origin at location for bottom left hole
  translate([-holeInset, -holeInset, 0]) {
    square(size = [pcbWidth, pcbLength]);
  }
}

module ArduinoPro_Headers() {
  // distance between the two header rows
  rowpitch  = pcbWidth - holeInset*2;
  // length for holes, leaving room for end header and insets
  rowlength = pcbLength - holeSpace - holeInset*2;

  // Add headers to either side (along y)
  for (x = [0, rowpitch], y = [0 : holeSpace : rowlength]) {
    translate([x, y, 0]) {
      // Standard PCB hole
      circle(r = holeDiam/2);
    }
  }

}

module ArduinoPro_Serial_Header() {
  // y position for header
  header_y = pcbLength - holeInset*2;
  // width for holes, leaving room for insets
  rowwidth = pcbWidth - holeInset*2;

  // Add serial header along top of board (along x)
  for (x = [holeInset : holeSpace : rowwidth]) {
    translate([x, header_y, 0]) {
      // Standard PCB hole
      circle(r = holeDiam/2);
    }
  }
}

module ArduinoPro(type = "mini") {
  union() {
    color(board_colour)
    linear_extrude(height=pcbHeight)
    difference() {
      // Common Features for Pro Mini/Micro
      ArduinoPro_PCB();
      ArduinoPro_Headers();

      // Features for Pro Mini
      if (type == "mini") {
        // Pro Mini Serial Header
        ArduinoPro_Serial_Header();
      }
    }

    // Features for Pro Micro
    if (type == "micro") {
      // Pro Micro USB port
      Micro_USB_Clearance();
    }
  }
}

ArduinoPro("mini");
*ArduinoPro("micro");

/*
  Vitamin: Pro Micro
  Model of an Arduino Pro Micro

  Derived from: https://github.com/sparkfun/Pro_Micro/
           and: https://github.com/sparkfun/Arduino_Pro_Mini_328/

  Authors:
    Jamie Osborne (@jmeosbn)

  Local Frame:
    Point of origin is the centre of the bottom left pin (9)

  Parameters:
    FIXME: type: can be "mini", or "micro";
           otherwise returns a blank board with header pin holes

  Returns:
    FIXME: Model of an Arduino Pro Mini/Micro with header holes
*/

// PCB Variables
holeDiam  = 1.25;         // The hole diameter in mm
holeSpace = 2.54;         // The spacing of the holes in mm
holeInset = holeSpace/2;  // The spacing of the holes in mm
pcbHeight = .063 * 25.4;  // The thickness of the PCB in mm
pcbLength =  1.3 * 25.4;  // The length of the PCB in mm
pcbWidth  =  0.7 * 25.4;  // The width of the PCB in mm

module ArduinoPro_PCB() {
  // Bare PCB, origin at location for bottom left hole
  translate([-holeInset, -holeInset, 0]) {
    square(size = [pcbWidth, pcbLength]);
  }
}

module ArduinoPro_Headers() {
  // distance between the two header rows
  rowpitch  = pcbWidth - holeInset*2;
  // length for holes, leaving room for end header and insets
  rowlength = pcbLength - holeSpace - holeInset*2;

  // Add headers to either side (along y)
  for (x = [0, rowpitch], y = [0 : holeSpace : rowlength]) {
    translate([x, y, 0]) {
      // Standard PCB hole
      circle(r = holeDiam/2);
    }
  }

}

module ArduinoPro_Serial_Header() {
  // y position for header
  header_y = pcbLength - holeInset*2;
  // width for holes, leaving room for insets
  rowwidth = pcbWidth - holeInset*2;

  // Add serial header along top of board (along x)
  for (x = [holeInset : holeSpace : rowwidth]) {
    translate([x, header_y, 0]) {
      // Standard PCB hole
      circle(r = holeDiam/2);
    }
  }

}

module ArduinoPro(type = "mini") {
  color([26/255, 90/255, 160/255])
  linear_extrude(height=pcbHeight)
  difference() {
    // Common Features for Pro Mini/Micro
    ArduinoPro_PCB();
    ArduinoPro_Headers();

    // Features for Pro Mini
    if (type == "mini") {
      // Pro Mini Serial Header
      ArduinoPro_Serial_Header();
    }
  }

  // Features for Pro Micro
  if (type == "micro") {
  }
}

ArduinoPro("mini");
*ArduinoPro("micro");


supported dome routines

supported dome routines

include <../config/config.scad>

DebugCoordinateFrames = true;
DebugConnectors = true;

sw = 2 * 0.5;  // approx 2 perimeters

function sqr(a) = a*a;

function circumference(radius) = 2 * PI * radius;
function arcLength(radius, theta) = PI * radius * theta / 180;
function chordLength(radius, theta) = radius * sqrt(2 - 2*cos(theta));
function segmentHeight(radius, theta) = radius - sqrt(sqr(radius) - sqr(chordLength(radius, theta))/4);
function segmentDistance(radius,theta) = radius - segmentHeight(radius,theta);

// 2D
// in XY plane
// chord begins at intersection of x+
// extends towards y+
// theta should be <= 180 degrees
module circularSegment(radius, theta) {
	echo(segmentHeight(radius,theta));
	intersection() {
		circle(radius);

		// chord hull
		polygon(
		[
			[radius, 0],
			[2*radius * cos(theta*0.25), 2*radius * sin(theta*0.1)],
			[2*radius * cos(theta*0.5), 2*radius * sin(theta*0.5)],
			[2*radius * cos(theta*0.75), 2*radius * sin(theta*0.9)],
			[radius * cos(theta), radius * sin(theta)]
		], 5);
	}
}

module domeSupportSegment(radius=100, inset=0, thickness=1, supportAngle=45) {
	insetAng = asin(inset/radius);
	theta = 180 - 2*supportAngle - 2*insetAng;

	rotate([0,0,90 - theta - insetAng])
		linear_extrude(thickness)
		circularSegment(radius,theta);
}

module shell() {
	// shell with hole for LED
	//render()
		difference() {
			union() {
				// curved shell with centre hole for pen
				rotate_extrude()
					difference() {
						// outer shell
						donutSector2D(
							or=BaseDiameter/2 + Shell_NotchTol + sw,
							ir=BaseDiameter/2 + Shell_NotchTol,
							a=90
						);

						// clearance for pen
						square([PenHoleDiameter/2, BaseDiameter]);

					}

				// large support ribs
				for (i=[0:9])
					rotate([0,0,i*360/10])
					rotate([90,0,0])
					domeSupportSegment(BaseDiameter/2, PenHoleDiameter/2, perim, 50);

				// small support ribs
				for (i=[0:9])
					rotate([0,0,i*360/10 + 360/20])
					rotate([90,0,0])
					domeSupportSegment(BaseDiameter/2, PenHoleDiameter/2 + 10, perim, 50);
			}

			// section
			*translate([-100,-200,-100])
				cube([200,200,200]);
		}
}

shell();

error: pathspec 'hardware/sandbox/SupportedShell.scad' did not match any file(s) known to git


feat: register the collection of animate operators

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

/**
 * Entry point of the camelSCAD library.
 *
 * Features set: Includes the core components and the operators.
 *
 * @author jsconan
 */

/* CORE */
include <core.scad>

/* OPERATORS */
include <operator/animate/mirror.scad>
include <operator/animate/resize.scad>
include <operator/animate/rotate.scad>
include <operator/animate/scale.scad>
include <operator/animate/translate.scad>

include <operator/distribute/grid.scad>
include <operator/distribute/mirror.scad>
include <operator/distribute/rotate.scad>
include <operator/distribute/translate.scad>

include <operator/extrude/negative.scad>

include <operator/repeat/alternate.scad>
include <operator/repeat/grid.scad>
include <operator/repeat/mirror.scad>
include <operator/repeat/rotate.scad>
include <operator/repeat/translate.scad>

include <operator/rotate/axis.scad>
include <operator/rotate/origin.scad>

include <operator/translate/axis.scad>

include <operator/operation.scad>
include <operator/transform.scad>
include <operator/sample.scad>

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

/**
 * Entry point of the camelSCAD library.
 *
 * Features set: Includes the core components and the operators.
 *
 * @author jsconan
 */

/* CORE */
include <core.scad>

/* OPERATORS */
include <operator/distribute/grid.scad>
include <operator/distribute/mirror.scad>
include <operator/distribute/rotate.scad>
include <operator/distribute/translate.scad>

include <operator/extrude/negative.scad>

include <operator/repeat/alternate.scad>
include <operator/repeat/grid.scad>
include <operator/repeat/mirror.scad>
include <operator/repeat/rotate.scad>
include <operator/repeat/translate.scad>

include <operator/rotate/axis.scad>
include <operator/rotate/origin.scad>

include <operator/translate/axis.scad>

include <operator/operation.scad>
include <operator/transform.scad>
include <operator/sample.scad>


adjusted cut offset parameter

adjusted cut offset parameter

use <projector_plate.scad>;
include <projector.scad>;
use <plate.scad>;
include <profile.scad>;
use <../scad/ob_wheel.scad>
use <../scad/ob_spacer.scad>
include <gantry_cart.scad>
use <../scad/brackets.scad>
use <../scad/geom.scad>
use <support_projector_beam.scad>
include <materials.scad>
use <basin_support.scad>
use <big_screw.scad>

module printer(projector_position = 0) {
  offset_depth = 50;

  middle_sections = 2;

  height = 500;
  width = 560;
  base_depth = 440;
  display_projection = true;
  base_sections = 3;

  projector_movement = height / 2 - acer_projector_distances[projector_position] + 20;

  // projector
  translate([0, 0, -offset_depth]) {
    translate([0, projector_movement, 0]) {
      center_projector() {
        Acer_Plate(160, 120, 85, 100);
        Acer_H6510BD(display_projection);
      }
    }
  }
  beam_offset = 10;
  beam_width = width - 2 * beam_offset;

  carriage_tower_sections = 3;

  translate([0, projector_movement, -offset_depth]) {
    translate([-beam_width/2,-20 * base_sections,-10])
      rotate([90,90,90])
        profile(base_sections, beam_width);
  /*
    translate([beam_width/2,-60,-10])
      rotate([90,0,90])
        gantry_cart_big(carriage_tower_sections, offset = 1);
    translate([-beam_width/2,-60,-10])
      rotate([90,0,-90])
        gantry_cart_big(carriage_tower_sections, offset = 1);
  */
  }

  // projector towers
  translate([0, 0, -offset_depth]) {
    translate([-width/2,-height/2,-10])
      rotate([-90,0,0])
        profile(carriage_tower_sections, height);
    translate([width/2,-height/2,-10])
      rotate([-90,0,0])
        profile(carriage_tower_sections, height);
  }

  // supports for horizontal beam
  translate([0, 20, -offset_depth])
  for(d = acer_projector_distances) {
    translate([0,d-height/2+10,0])
      support_projector_beam(width-60);
  }
  //height / 2 - d

  // base
  module base(width, depth, sections = 2) {
    translate([-width/2,0,-base_depth/2])
      rotate([0,0,0])
        profile(sections, base_depth);

    translate([width/2,0,-base_depth/2])
      rotate([0,0,0])
        profile(sections, base_depth);

    lateral_beam_width = width - 20;
    translate([-lateral_beam_width/2,0,-base_depth/2+10])
      rotate([0,90,0])
        profile(sections, lateral_beam_width);

    translate([-lateral_beam_width/2,0,base_depth/2-10])
      rotate([0,90,0])
        profile(sections, lateral_beam_width);
  }

  module baser(width, depth, sections = 2) {
    translate([(- width + sections * 20) / 2 - 10, -10, -base_depth/2])
      rotate([0,0,90])
        profile(sections, base_depth);

    translate([(  width - sections * 20) / 2 + 10, -10, -base_depth/2])
      rotate([0,0,90])
        profile(sections, base_depth);

    lateral_beam_width = width - 30 * sections;
    translate([-lateral_beam_width/2, -10, -base_depth/2+20])
      rotate([90,0,90])
        profile(sections, lateral_beam_width);
    translate([-lateral_beam_width/2, -10, base_depth/2-20])
      rotate([90,0,90])
        profile(sections, lateral_beam_width);
  }

  bottom_sections = 2;
  translate([0,-(height+bottom_sections*20)/2,0])
    base(width, base_depth, bottom_sections);

  translate([0,(height+middle_sections*20)/2,0])
    baser(width, base_depth, 2);

  // support towers
  tower_pos = base_depth / 2 - 10;
  translate([-width/2,-height/2,tower_pos])
    rotate([-90,0,0])
      profile(1, height);
  translate([width/2,-height/2,tower_pos])
    rotate([-90,0,0])
      profile(1, height);

  rotate([0,180,0]) {

    offset = 16;
    plate_width = width - 20 - offset * 2;
    plate_depth = base_depth - 40 * 2;
    cut_width = 440;
    cut_offset = 1.0;
    translate([
      -plate_width/2,
      height/2 + 20,
      -plate_depth / 2 + 20 - offset])
      basin_support(plate_width, plate_depth, cut_width, cut_offset);

    translate([0, height/2 + 20 * middle_sections, base_depth / 2 + 20])
      big_screw();

    // TODO review
    screw_height = 640;
    rail_sections = 2;
    rotate([-90, 0, 0]) {
      translate([65, -base_depth / 2 - 20, -height / 2 - 20 * (bottom_sections)]) {
        profile(rail_sections, screw_height + height + 20 * (bottom_sections + middle_sections));
      }
      translate([-65, -base_depth / 2 - 20, -height / 2 - 20 * (bottom_sections)]) {
        profile(rail_sections, screw_height + height + 20 * (bottom_sections + middle_sections));
      }
    }
    translate([0,0,30]) {
      translate([40, height / 2 + 20 * middle_sections + 260, base_depth / 2 + 20])
        rotate([0, 180, 0])
          profile(4, width / 2 + rail_sections * 2 - 5);
      translate([-40, height / 2 + 20 * middle_sections + 260, base_depth / 2 + 20])
        rotate([0, 180, 0])
          profile(4, width / 2 + rail_sections * 2 - 5);
      translate([-50, height / 2 + 20 * middle_sections + 300, base_depth / 2 -60])
        plate(100, 4, 80);
      translate([-50, height / 2 + 20 * middle_sections + 216, base_depth / 2 -60])
        plate(100, 4, 80);
      translate([0, height / 2 + 20 * middle_sections + 300, base_depth / 2 - width / 2 + 30])
        rotate([90,90,0])
          profile(3, 120);

      translate([65, height / 2 + 20 * middle_sections + 300 - 10, base_depth / 2 - 20 - rail_sections * 10])
        rotate([0,90,0])
          ob_solid_wheel();
      translate([65, height / 2 + 20 * middle_sections + 240 - 10, base_depth / 2 - 20 - rail_sections * 10])
        rotate([0,90,0])
          ob_solid_wheel();
      translate([65, height / 2 + 20 * middle_sections + 270 - 10, base_depth / 2 + rail_sections * 10])
        rotate([0,90,0])
          ob_solid_wheel();

      translate([-65, height / 2 + 20 * middle_sections + 300 - 10, base_depth / 2 - 20 - rail_sections * 10])
        rotate([0,90,0])
          ob_solid_wheel();
      translate([-65, height / 2 + 20 * middle_sections + 240 - 10, base_depth / 2 - 20 - rail_sections * 10])
        rotate([0,90,0])
          ob_solid_wheel();
      translate([-65, height / 2 + 20 * middle_sections + 270 - 10, base_depth / 2 + rail_sections * 10])
        rotate([0,90,0])
          ob_solid_wheel();
    }
  }
}

use <projector_plate.scad>;
include <projector.scad>;
use <plate.scad>;
include <profile.scad>;
use <../scad/ob_wheel.scad>
use <../scad/ob_spacer.scad>
include <gantry_cart.scad>
use <../scad/brackets.scad>
use <../scad/geom.scad>
use <support_projector_beam.scad>
include <materials.scad>
use <basin_support.scad>
use <big_screw.scad>

module printer(projector_position = 0) {
  offset_depth = 50;

  middle_sections = 2;

  height = 500;
  width = 560;
  base_depth = 440;
  display_projection = true;
  base_sections = 3;

  projector_movement = height / 2 - acer_projector_distances[projector_position] + 20;

  // projector
  translate([0, 0, -offset_depth]) {
    translate([0, projector_movement, 0]) {
      center_projector() {
        Acer_Plate(160, 120, 85, 100);
        Acer_H6510BD(display_projection);
      }
    }
  }
  beam_offset = 10;
  beam_width = width - 2 * beam_offset;

  carriage_tower_sections = 3;

  translate([0, projector_movement, -offset_depth]) {
    translate([-beam_width/2,-20 * base_sections,-10])
      rotate([90,90,90])
        profile(base_sections, beam_width);
  /*
    translate([beam_width/2,-60,-10])
      rotate([90,0,90])
        gantry_cart_big(carriage_tower_sections, offset = 1);
    translate([-beam_width/2,-60,-10])
      rotate([90,0,-90])
        gantry_cart_big(carriage_tower_sections, offset = 1);
  */
  }

  // projector towers
  translate([0, 0, -offset_depth]) {
    translate([-width/2,-height/2,-10])
      rotate([-90,0,0])
        profile(carriage_tower_sections, height);
    translate([width/2,-height/2,-10])
      rotate([-90,0,0])
        profile(carriage_tower_sections, height);
  }

  // supports for horizontal beam
  translate([0, 20, -offset_depth])
  for(d = acer_projector_distances) {
    translate([0,d-height/2+10,0])
      support_projector_beam(width-60);
  }
  //height / 2 - d

  // base
  module base(width, depth, sections = 2) {
    translate([-width/2,0,-base_depth/2])
      rotate([0,0,0])
        profile(sections, base_depth);

    translate([width/2,0,-base_depth/2])
      rotate([0,0,0])
        profile(sections, base_depth);

    lateral_beam_width = width - 20;
    translate([-lateral_beam_width/2,0,-base_depth/2+10])
      rotate([0,90,0])
        profile(sections, lateral_beam_width);

    translate([-lateral_beam_width/2,0,base_depth/2-10])
      rotate([0,90,0])
        profile(sections, lateral_beam_width);
  }

  module baser(width, depth, sections = 2) {
    translate([(- width + sections * 20) / 2 - 10, -10, -base_depth/2])
      rotate([0,0,90])
        profile(sections, base_depth);

    translate([(  width - sections * 20) / 2 + 10, -10, -base_depth/2])
      rotate([0,0,90])
        profile(sections, base_depth);

    lateral_beam_width = width - 30 * sections;
    translate([-lateral_beam_width/2, -10, -base_depth/2+20])
      rotate([90,0,90])
        profile(sections, lateral_beam_width);
    translate([-lateral_beam_width/2, -10, base_depth/2-20])
      rotate([90,0,90])
        profile(sections, lateral_beam_width);
  }

  bottom_sections = 2;
  translate([0,-(height+bottom_sections*20)/2,0])
    base(width, base_depth, bottom_sections);

  translate([0,(height+middle_sections*20)/2,0])
    baser(width, base_depth, 2);

  // support towers
  tower_pos = base_depth / 2 - 10;
  translate([-width/2,-height/2,tower_pos])
    rotate([-90,0,0])
      profile(1, height);
  translate([width/2,-height/2,tower_pos])
    rotate([-90,0,0])
      profile(1, height);

  rotate([0,180,0]) {

    offset = 16;
    plate_width = width - 20 - offset * 2;
    plate_depth = base_depth - 40 * 2;
    cut_width = 440;
    cut_offset = 7.5;
    translate([
      -plate_width/2,
      height/2 + 20,
      -plate_depth / 2 + 20 - offset])
      basin_support(plate_width, plate_depth, cut_width, cut_offset);

    translate([0, height/2 + 20 * middle_sections, base_depth / 2 + 20])
      big_screw();

    // TODO review
    screw_height = 640;
    rail_sections = 2;
    rotate([-90, 0, 0]) {
      translate([65, -base_depth / 2 - 20, -height / 2 - 20 * (bottom_sections)]) {
        profile(rail_sections, screw_height + height + 20 * (bottom_sections + middle_sections));
      }
      translate([-65, -base_depth / 2 - 20, -height / 2 - 20 * (bottom_sections)]) {
        profile(rail_sections, screw_height + height + 20 * (bottom_sections + middle_sections));
      }
    }
    translate([0,0,30]) {
      translate([40, height / 2 + 20 * middle_sections + 260, base_depth / 2 + 20])
        rotate([0, 180, 0])
          profile(4, width / 2 + rail_sections * 2 - 5);
      translate([-40, height / 2 + 20 * middle_sections + 260, base_depth / 2 + 20])
        rotate([0, 180, 0])
          profile(4, width / 2 + rail_sections * 2 - 5);
      translate([-50, height / 2 + 20 * middle_sections + 300, base_depth / 2 -60])
        plate(100, 4, 80);
      translate([-50, height / 2 + 20 * middle_sections + 216, base_depth / 2 -60])
        plate(100, 4, 80);
      translate([0, height / 2 + 20 * middle_sections + 300, base_depth / 2 - width / 2 + 30])
        rotate([90,90,0])
          profile(3, 120);

      translate([65, height / 2 + 20 * middle_sections + 300 - 10, base_depth / 2 - 20 - rail_sections * 10])
        rotate([0,90,0])
          ob_solid_wheel();
      translate([65, height / 2 + 20 * middle_sections + 240 - 10, base_depth / 2 - 20 - rail_sections * 10])
        rotate([0,90,0])
          ob_solid_wheel();
      translate([65, height / 2 + 20 * middle_sections + 270 - 10, base_depth / 2 + rail_sections * 10])
        rotate([0,90,0])
          ob_solid_wheel();

      translate([-65, height / 2 + 20 * middle_sections + 300 - 10, base_depth / 2 - 20 - rail_sections * 10])
        rotate([0,90,0])
          ob_solid_wheel();
      translate([-65, height / 2 + 20 * middle_sections + 240 - 10, base_depth / 2 - 20 - rail_sections * 10])
        rotate([0,90,0])
          ob_solid_wheel();
      translate([-65, height / 2 + 20 * middle_sections + 270 - 10, base_depth / 2 + rail_sections * 10])
        rotate([0,90,0])
          ob_solid_wheel();
    }
  }
}


lens tube

lens tube

// contact lens

phi_cl = 13.8;
RC_cl = 8.6;
e_cl = 1;
d1_cl = sqrt(pow(RC_cl, 2) - pow(phi_cl/2, 2));

module contact_lens(phi_cl, RC_cl, e_cl, d1_cl){
     translate([0, 0, e_cl-RC_cl])
     difference(){
	  difference(){
	       sphere(RC_cl+e_cl, $fn=36);
	       sphere(RC_cl, $fn=36);
	       translate([0, 0, -d1_cl])
		    cube([4 * RC_cl, 4*RC_cl,
			  2*d1_cl + RC_cl],
			 center=true);
	  }
     };
}

%contact_lens(phi_cl, RC_cl, e_cl, d1_cl);

h=5;
module lens_tube(h, phi_cl, RC_cl, e_cl, d1_cl){
     translate([0, 0, -h-d1_cl+2*e_cl])
	  difference(){
	  cylinder(h=h, d=phi_cl+4*e_cl);
	  union(){
	       translate([0, 0, -e_cl/2])
		    cylinder(h=h+e_cl,
			     d=phi_cl+e_cl);
	       translate([0, 0, h-e_cl+0.1])
		    cylinder(h=e_cl, d=phi_cl+3*e_cl);
	  }
     }
}
lens_tube(h, phi_cl, RC_cl, e_cl, d1_cl);

// contact lens

phi_cl = 13.8;
RC_cl = 8.6;
e_cl = 1;

module contact_lens(phi_cl, RC_cl, e_cl){
     d1_cl = sqrt(pow(RC_cl, 2) - pow(phi_cl/2, 2));
     translate([0, 0, e_cl-RC_cl])
     difference(){
	  difference(){
	       sphere(RC_cl+e_cl, $fn=36);
	       sphere(RC_cl, $fn=36);
	       translate([0, 0, -d1_cl]) cube([4 * RC_cl, 4*RC_cl,
					       2*d1_cl + RC_cl],
					      center=true);
	  }
     };
}

%contact_lens(phi_cl, RC_cl, e_cl);


pulley: add flip param

pulley: add flip param

include <thing_libutils/units.scad>
include <thing_libutils/shapes.scad>

// h, full_h, inner_d, outer_d, walls, bore
pulley_2GT_20T_idler = [8.65*mm, undef, 12*mm, 18*mm, 1*mm, 5*mm];
pulley_2GT_20T       = [8.65*mm, 16*mm, 12*mm, 16*mm, 1.15*mm, 5*mm];

module pulley(pulley=pulley_2GT_20T, flip=false, align=[0,0,0], orient = [0,0,1])
{
    is_idler = pulley[1] == undef;
    pulley_full(
            is_idler=is_idler,
            h=pulley[0],
            full_h=is_idler?0:pulley[1],
            inner_d=pulley[2],
            outer_d=pulley[3],
            walls=pulley[4],
            bore=pulley[5],
            flip=flip,
            align=align,
            orient=orient
            );
}

module pulley_full(h, inner_d, outer_d, bore, walls, is_idler=false, full_h, flip=false, align=[0,0,0], orient = [0,0,1])
{
    size_align(size=[outer_d, outer_d, full_h==undef?h:full_h], align=align, orient=orient)
    {
        //for flipping
        mirror([0,0,flip?-1:0])
        //center
        translate([0,0,full_h==undef?-h/2:-full_h/2])
        difference()
        {
            union()
            {
                fncylindera(d = outer_d, h = walls, align=[0,0,1], orient=[0,0,1]);

                translate([0,0,0])
                fncylindera(d = inner_d, h = h, align=[0,0,1], orient=[0,0,1]);

                translate([0,0,h-walls])
                fncylindera(d = outer_d, h = walls, align=[0,0,1], orient=[0,0,1]);

                translate([0,0,h])
                if(!is_idler)
                {
                    fncylindera(d = outer_d, h = full_h-h, align=[0,0,1], orient=[0,0,1]);
                }
            }
            translate([0,0,-.1])
            fncylindera(d = bore, h = full_h+.2, align=[0,0,1], orient=[0,0,1]);
        }
    }
}

/*debug = true;*/
/*if(debug)*/
/*{*/
    /*[>pulley(pulley_2GT_20T_idler, align=[0,0,1], orient=[0,0,1]);<]*/
    /*[>pulley(pulley_2GT_20T, align=[0,0,1], orient=[0,0,1], flip=false);<]*/
    /*pulley(pulley_2GT_20T, align=[0,0,-1], orient=[0,0,1], flip=false);*/
/*}*/

include <thing_libutils/units.scad>
include <thing_libutils/shapes.scad>

// h, full_h, inner_d, outer_d, walls, bore
pulley_2GT_20T_idler = [8.65*mm, undef, 12*mm, 18*mm, 1*mm, 5*mm];
pulley_2GT_20T       = [8.65*mm, 16*mm, 12*mm, 16*mm, 1*mm, 5*mm];

module pulley(pulley=pulley_2GT_20T, align=[0,0,0], orient = [0,0,1])
{
    is_idler = pulley[1] == undef;
    pulley_full(
            is_idler=is_idler,
            h=pulley[0],
            full_h=is_idler?0:pulley[1],
            inner_d=pulley[2],
            outer_d=pulley[3],
            walls=pulley[4],
            bore=pulley[5],
            align=align,
            orient=orient
            );
}

module pulley_full(h, inner_d, outer_d, bore, walls, is_idler=false, full_h, align=[0,0,0], orient = [0,0,1])
{
    size_align(size=[outer_d, outer_d, h], align=align, orient=orient)
    {
        difference()
        {
            union()
            {
                for(z=[-1,1])
                    translate([0,0,z*h/2])
                        fncylindera(d = outer_d, h = walls, align=[0,0,-z], orient=[0,0,1]);

                fncylindera(d = inner_d, h = h, align=[0,0,0], orient=[0,0,1]);

                if(!is_idler)
                {
                    translate([0,0,h-walls])
                        fncylindera(d = outer_d, h = full_h-h, align=[0,0,0], orient=[0,0,1]);
                }
            }
            fncylindera(d = bore, h = full_h, align=[0,0,0], orient=[0,0,1]);
        }
    }
}

/*debug = false;*/
if(debug)
{
    /*pulley(pulley_2GT_20T_idler, align=[0,0,1], orient=[0,0,1]);*/
    /*pulley(pulley_2GT_20T, align=[0,0,1], orient=[0,0,1]);*/
}


Incremental improvement to fan filter holder

/* Fits the standard Hakko FA400 filters, holes for 120mm fan */

module XYCenteredCube(size) {
    translate([-size[0]/2, -size[1]/2]) cube(size);
}

module XYCenteredClippedCube(size, clip) {
    difference() {
        XYCenteredCube(size);
        for(rotate=[0,90,180,270]) {
            rotate([0,0,rotate])
            linear_extrude(100)
            polygon(points=[
                [size[0]/2 - clip, size[1]/2],
                [size[0]/2, size[1]/2 - clip],
                [size[0] / 2, size[1] / 2]]);
        }
    }
}

module ThinWallCube(dims, thick=1.2) {
    /* dims is outer size, centers in XY */
    inner_dim0 = dims[0] - thick * 2;
    inner_dim1 = dims[1] - thick * 2;
    difference() {
        translate([-dims[0]/2,0,0])
            cube(dims);
        translate([-inner_dim0/2,thick,-1])
            cube([inner_dim0, inner_dim1, dims[2] + 2]);
    }
}

module Arch(dims) {
    r = dims[0] / 2;
    translate([-dims[0]/2,0])
        square([dims[0], dims[1]-r]);
    translate([0,dims[1]-r])
        circle(r=r);
}

module ThinWallArch(dims, thick=1.2) {
    /* origin is at outer middle of square end (X). dims is total outer. */
    linear_extrude(height=dims[2]) difference() {
        Arch(dims);
        translate([0,thick]) Arch([dims[0]-thick*2, dims[1]-thick*2]);
    }
}

module Roundover(r=3,h=100) {
/* origin is  middle in z, and outer edge */
translate([-r,-r,-h/2]) difference() {
cube([r+r,r+r,h]);
translate([0,0,-1]) cylinder(r=r,h=h+2);
}
}

/* rear */
translate([-20,0,0]) {
cube([6.5,30,6]);
cube([6.5,3,8]);
}

/* front */
translate([-30,10,0])
difference() {
    cube([6.5,20,6]);
    translate([0,0,6]) rotate([90,0,0]) rotate([0,-90,0]) Roundover($fn=100);
}

translate([0,0,0]) {
cube([8,12,8]);
translate([4,20,4]) rotate([0,22.5,0]) rotate([90,0,0]) cylinder(r=3.5,h=10,$fn=8);
}

/*ThinWallArch([10,16,6], $fn=100);
translate([20,0,0]) ThinWallCube([10,16,6]);
*/

module Arrow(l=10, w=3, r=1) {
    /* stem */
    hull() {
        circle(r=r);
        translate([0,-l]) circle(r=r);
    }
    /* left */
    hull() {
        circle(r=r);
        translate([-w, -w]) circle(r=r);
    }
    /* right */
    hull() {
        circle(r=r);
        translate([w, -w]) circle(r=r);
    }
}

/*translate([-70,-70])
    cube([140,140,6]);
// inset for filter
translate([0,0,2])
    XYCenteredCube([130,130,10]);
// holes
for(rotate=[0:90:360])
    rotate([0,0,rotate])
    translate([105/2, 105/2,-1]) cylinder(r=2.6,h=100);
*/
module Main() {
union () {
    ThinWallCube([10,12,7]);
    translate([0,6.2,5]) rotate([90,0,0])
        linear_extrude(height=1)
        Arrow(l=4,$fn=16);
}

/* back leg */
translate([-3.5,-4.5,-20])
    cube([7,5,40]);
/* back top retainer */
translate([-3.5,-6,15])
    cube([7,4,5]);
/* back piece */
translate([-130/2,-6,-131])
    cube([130,6.5,130]);

/* front leg */
translate([-3.5,1,-20])
    cube([7,3.5,28]);
/* front piece */
translate([-130/2,2,-131])
    cube([130,6.5,130]);

}

module thin_wall_cube(dims, thick=1) {
    /* centers in XY */
    inner_dim0 = dims[0] - thick * 2;
    inner_dim1 = dims[1] - thick * 2;
    difference() {
        translate([-dims[0]/2,-dims[1]/2,0])
            cube(dims);
        translate([-inner_dim0/2,-inner_dim1/2,-1])
            cube([inner_dim0, inner_dim1, dims[2] + 2]);
    }
}

module arrow(l=10, w=3, r=1) {
    /* stem */
    hull() {
        circle(r=r);
        translate([0,-l]) circle(r=r);
    }
    /* left */
    hull() {
        circle(r=r);
        translate([-w, -w]) circle(r=r);
    }
    /* right */
    hull() {
        circle(r=r);
        translate([w, -w]) circle(r=r);
    }
}

union () {
    thin_wall_cube([10,12,7]);
    translate([0,6.2,5]) rotate([90,0,0])
        linear_extrude(height=1)
        arrow(l=4,$fn=16);
}

/* back leg */
translate([-3.5,-4.5,-20])
    cube([7,5,40]);
/* back top retainer */
translate([-3.5,-6,15])
    cube([7,4,5]);
/* back piece */
translate([-130/2,-6,-131])
    cube([130,6.5,130]);

/* front leg */
translate([-3.5,1,-20])
    cube([7,3.5,28]);
/* front piece */
translate([-130/2,2,-131])
    cube([130,6.5,130]);


prototype

prototype

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


wanhao-i3-z-stop: make SideClamp a little bigger and easier to print

include <../libs/trig.scad>;

// enlarged to account for shrink
g3mm = 3.45;
g3mmnut = 5.85;
g2mm = 2.0;
gNutChamfer = 0.5;

gMicroswitchHoleSpacing = 6.0;
gSideClampHole1 = 0;
gSideClampHole2 = 10;

gTopClampY1 = 15;
gTopClampY2 = 30;
gClampOffset = 10;
gSideClampOffset = 0;

module NutTrap(x,h=100) {
    cylinder(d=x/0.866,h=h,$fn=6);
    translate([0,0,-0.01])
        cylinder(d1=(x+gNutChamfer)/0.866,d2=x/0.866,h=gNutChamfer,$fn=6);
}

/* cylinder_wall_thick should be a small integer *nozzle_dia */
module NutTrapSupport(d,h,cylinder_wall_thick=0.7,cylinder_wall_offset=0.1) {
    cylinder(d=d+cylinder_wall_offset*2,h=h,$fn=16);
}

module Fillet(r,h=100) {
    difference() {
        cube([r,r,h]);
        translate([0,0,-1]) cylinder(r=r,h=h+2);
    }
}

/* Side clamp, in two parts */

module SideBody() {
    difference() {
        translate([0,-4,0]) cube([22,24,5+gSideClampOffset]);
        translate([-1,-5,3.5]) cube([11,27,5+gSideClampOffset]);
        translate([14,17,-1]) cylinder(d=g2mm,h=100,$fn=32);
        translate([14+gMicroswitchHoleSpacing,17,-1]) cylinder(d=g2mm,h=100,$fn=32);
        translate([8,gSideClampHole1,-1]) cylinder(d=g3mm,h=100,$fn=32);
        translate([8,gSideClampHole2,-1]) cylinder(d=g3mm,h=100,$fn=32);
    }
}

gSidePos1 = [8,18];
gSidePos2 = [11,4];
gSideCutoutRad = 25;

module SideClamp() {
    difference() {
        hull() for(c=[[4,-2],[11,-2],[4,18],gSidePos1,gSidePos2])
            translate(c) cylinder(r=2,h=5,$fn=32);
        translate([0,0,-1])
            translate(CircleCircleIntersection(gSidePos1, gSidePos2, 2, gSideCutoutRad))
            cylinder(r=gSideCutoutRad,h=10,$fn=100);
        //translate(gSidePos1) cylinder(r=2,h=10);
        //translate(gSidePos2) cylinder(r=2,h=10);
        translate([8,gSideClampHole1,-1]) union() {
            cylinder(d=g3mm,h=100,$fn=32);
            translate([0,0,6.1]) scale([1,1,-1]) NutTrap(g3mmnut,3);
        }
        translate([8,gSideClampHole2,-1]) {
            cylinder(d=g3mm,h=100,$fn=32);
            translate([0,0,6.1]) scale([1,1,-1]) NutTrap(g3mmnut,3);
        }
    }
}

/* Top clamp, in two parts */

module TopBody() {
    difference() {
        union() {
            translate([-1,0,0]) cube([11,35,12]);
            /* thing adjustment screw goes on */
            hull() for(x=[-9,0])
                for(y=[1,9])
                    translate([x,y]) cylinder(r=1,h=12);
            translate([-2.99,11.99,0]) rotate([0,0,-90]) Fillet(2,12);
        }
        hull() {
            for(x=[5,10])
                for(y=[10,50])
                    translate([x,y,3])
                    cylinder(r=2,h=100);
        }
        hull() {
            for(x=[5+1.7,10])
                for(y=[10+1.7,50])
                    translate([x,y,-1])
                    cylinder(r=2,h=100);
        }
        /* adjustment screw */
        translate([-5,5,0]) {
            NutTrap(g3mmnut,3);
            cylinder(d=g3mm,h=200);
        }
        /* notch for frame */
        hull() {
            for(x=[8,20])
            translate([x,0,-1]) cylinder(r=2,h=100);
        }
        /* clamp holes */
        for(y=[gTopClampY1,gTopClampY2])
            translate([-10,y,6])
            rotate([0,90,0]) cylinder(d=g3mm,h=100);
    }
    /* adjustment screw support */
    translate([-5,5,0]) NutTrapSupport(g3mm,3);
}

module TopClamp() {
    difference() {
        intersection() {
            cube([12,25,6]);
            hull() {
                translate([0,2,4]) rotate([0,90,0]) cylinder(r=2,h=100);
                translate([0,50,4]) rotate([0,90,0]) cylinder(r=2,h=100);
                translate([0,50,-50]) rotate([0,90,0]) cylinder(r=2,h=100);
                translate([0,2,-50]) rotate([0,90,0]) cylinder(r=2,h=100);
            }
        }
        /* clamp holes */
        for(y=[gTopClampY1,gTopClampY2])
            translate([6,y-gClampOffset,0]) {
                cylinder(d=g3mm,h=100);
                NutTrap(g3mmnut,3);
            }
    }
    /* clamp holes support */
    for(y=[gTopClampY1,gTopClampY2])
        translate([6,y-gClampOffset,0])
            NutTrapSupport(g3mm,3);
}

TopBody($fn=32);

/* to visualize together */
/* translate([11,gClampOffset,0]) rotate([0,-90,0]) Clamper($fn=32); */
/* for printing */
translate([7,gClampOffset+2,0]) TopClamp($fn=32);

translate([-25,15,0]) SideBody();
/* to visualise together  */
/* translate([-25,15,5]) SideClamp(); */
/* for printing */
translate([-15,-3,0]) rotate([0,0,90]) SideClamp();

// enlarged to account for shrink
g3mm = 3.45;
g3mmnut = 5.85;
g2mm = 2.0;
gNutChamfer = 0.5;

gMicroswitchHoleSpacing = 6.0;
gSideClampHole1 = 0;
gSideClampHole2 = 10;

gTopClampY1 = 15;
gTopClampY2 = 30;
gClampOffset = 10;

module NutTrap(x,h=100) {
    cylinder(d=x/0.866,h=h,$fn=6);
    translate([0,0,-0.01])
        cylinder(d1=(x+gNutChamfer)/0.866,d2=x/0.866,h=gNutChamfer,$fn=6);
}

/* cylinder_wall_thick should be a small integer *nozzle_dia */
module NutTrapSupport(d,h,cylinder_wall_thick=0.7,cylinder_wall_offset=0.1) {
    cylinder(d=d+cylinder_wall_offset*2,h=h,$fn=16);
}

module Fillet(r,h=100) {
    difference() {
        cube([r,r,h]);
        translate([0,0,-1]) cylinder(r=r,h=h+2);
    }
}

/* Side clamp, in two parts */

module SideBody() {
    difference() {
        translate([0,-4,0]) cube([22,24,5]);
        translate([-1,-5,3.5]) cube([11,27,5]);
        translate([14,17,-1]) cylinder(d=g2mm,h=100,$fn=32);
        translate([14+gMicroswitchHoleSpacing,17,-1]) cylinder(d=g2mm,h=100,$fn=32);
        translate([8,gSideClampHole1,-1]) cylinder(d=g3mm,h=100,$fn=32);
        translate([8,gSideClampHole2,-1]) cylinder(d=g3mm,h=100,$fn=32);
    }

}

module SideClamp() {
    difference() {
        translate([3,-4,0]) cube([9,18,5]);
        translate([30+10,15,-1]) cylinder(r=30,h=100,$fn=100);
        translate([8,gSideClampHole1,-1]) union() {
            cylinder(d=g3mm,h=100,$fn=32);
            translate([0,0,6.1]) scale([1,1,-1]) NutTrap(g3mmnut,3);
        }
        translate([8,gSideClampHole2,-1]) {
            cylinder(d=g3mm,h=100,$fn=32);
            translate([0,0,6.1]) scale([1,1,-1]) NutTrap(g3mmnut,3);
        }
    }
}

/* Top clamp, in two parts */

module TopBody() {
    difference() {
        union() {
            translate([-1,0,0]) cube([11,35,12]);
            /* thing adjustment screw goes on */
            hull() for(x=[-9,0])
                for(y=[1,9])
                    translate([x,y]) cylinder(r=1,h=12);
            translate([-2.99,11.99,0]) rotate([0,0,-90]) Fillet(2,12);
        }
        hull() {
            for(x=[5,10])
                for(y=[10,50])
                    translate([x,y,3])
                    cylinder(r=2,h=100);
        }
        hull() {
            for(x=[5+1.7,10])
                for(y=[10+1.7,50])
                    translate([x,y,-1])
                    cylinder(r=2,h=100);
        }
        /* adjustment screw */
        translate([-5,5,0]) {
            NutTrap(g3mmnut,3);
            cylinder(d=g3mm,h=200);
        }
        /* notch for frame */
        hull() {
            for(x=[8,20])
            translate([x,0,-1]) cylinder(r=2,h=100);
        }
        /* clamp holes */
        for(y=[gTopClampY1,gTopClampY2])
            translate([-10,y,6])
            rotate([0,90,0]) cylinder(d=g3mm,h=100);
    }
    /* adjustment screw support */
    translate([-5,5,0]) NutTrapSupport(g3mm,3);
}

module TopClamp() {
    difference() {
        intersection() {
            cube([12,25,6]);
            hull() {
                translate([0,2,4]) rotate([0,90,0]) cylinder(r=2,h=100);
                translate([0,50,4]) rotate([0,90,0]) cylinder(r=2,h=100);
                translate([0,50,-50]) rotate([0,90,0]) cylinder(r=2,h=100);
                translate([0,2,-50]) rotate([0,90,0]) cylinder(r=2,h=100);
            }
        }
        /* clamp holes */
        for(y=[gTopClampY1,gTopClampY2])
            translate([6,y-gClampOffset,0]) {
                cylinder(d=g3mm,h=100);
                NutTrap(g3mmnut,3);
            }

    }
    /* clamp holes support */
    for(y=[gTopClampY1,gTopClampY2])
        translate([6,y-gClampOffset,0])
            NutTrapSupport(g3mm,3);
}

TopBody($fn=32);

/* to visualize together */
/* translate([11,gClampOffset,0]) rotate([0,-90,0]) Clamper($fn=32); */
/* for printing */
translate([7,gClampOffset+2,0]) TopClamp($fn=32);

translate([-25,15,0]) SideBody();
translate([-15,-2,0]) rotate([0,0,90]) SideClamp();