#include "functions.inc"     

#macro LumpyBox(X, Y, Z, r, M f) 
  #ifdef (HighDef)
    isosurface {  
        function{   f_rounded_box(
          x + M*f_noise3d(0, f*y, f*z),
          y + M*f_noise3d(f*x, 0, f*z),
          z + M*f_noise3d(f*x, f*y, 0), 
          r, X/2, Y/2, Z/2)  }
        max_gradient 4
        contained_by { box {-(X+Y+Z),(X+Y+Z)} }
    }
  #else  
    box{<-X/2,-Y/2,-Z/2><X/2,Y/2,Z/2>}
  #end
#end


#macro rbox(w,h,d,r)
union
{
  box{ <-w/2,-h/2+r,-d/2+r> <w/2,h/2-r,d/2-r>  }
  box{ <-w/2+r,-h/2,-d/2+r> <w/2-r,h/2,d/2-r>  }
  box{ <-w/2+r,-h/2+r,-d/2> <w/2-r,h/2-r,d/2>  } 
  
  #if ( w/2 > r )
    cylinder{ <-w/2+r,0,0> <+w/2-r,0,0> r translate<0, h/2-r,-d/2+r> }
    cylinder{ <-w/2+r,0,0> <+w/2-r,0,0> r translate<0,-h/2+r,-d/2+r> }
    cylinder{ <-w/2+r,0,0> <+w/2-r,0,0> r translate<0,-h/2+r, d/2-r> }
    cylinder{ <-w/2+r,0,0> <+w/2-r,0,0> r translate<0, h/2-r, d/2-r> } 
  #end
  
  #if ( h/2 > r )
    cylinder{ <0,-h/2+r,0> <0,+h/2-r,0> r translate< w/2-r,0,d/2-r>  } 
    cylinder{ <0,-h/2+r,0> <0,+h/2-r,0> r translate<-w/2+r,0,d/2-r>  } 
    cylinder{ <0,-h/2+r,0> <0,+h/2-r,0> r translate<-w/2+r,0,-d/2+r> } 
    cylinder{ <0,-h/2+r,0> <0,+h/2-r,0> r translate< w/2-r,0,-d/2+r> } 
  #end
  
  #if ( d/2 > r )
    cylinder{ <0,0,-d/2+r> <0,0,+d/2-r> r translate<-w/2+r,h/2-r,0>  } 
    cylinder{ <0,0,-d/2+r> <0,0,+d/2-r> r translate< w/2-r,h/2-r,0>  } 
    cylinder{ <0,0,-d/2+r> <0,0,+d/2-r> r translate<-w/2+r,-h/2+r,0> } 
    cylinder{ <0,0,-d/2+r> <0,0,+d/2-r> r translate<w/2-r,-h/2+r,0>  } 
  #end      
  
  sphere{ <w/2 - r, h/2 - r, d/2 - r> , r}
  sphere{ <w/2 - r, -h/2 + r, d/2 - r> , r}
  sphere{ <w/2 - r, -h/2 + r, -d/2 + r> , r}
  sphere{ <w/2 - r, h/2 - r, -d/2 + r> , r}
  sphere{ <-w/2+  r, h/2 - r, d/2 - r> , r}
  sphere{ <-w/2+  r, -h/2 + r, d/2 - r> , r}
  sphere{ <-w/2+  r, -h/2 + r, -d/2 + r> , r}
  sphere{ <-w/2+  r, h/2 - r, -d/2 + r> , r}
}                       
#end


#macro lozenge(Y,Z,R,r)
union{

   torus{R, r rotate 90*x translate<0, Y-R-r, Z/2-r>}
   torus{R, r rotate 90*x translate<0, Y-R-r,-Z/2+r>}
   
   cylinder{<0,0,-Z/2><0,0,Z/2> R translate<0, Y-R-r, 0>}
   cylinder{<0,0,-Z/2+r><0,0,Z/2-r> R+r translate<0, Y-R-r, 0>} 
   
   cylinder{<0,0,0><0,Y-R-r,0> r translate< R, 0,  Z/2-r>}
   cylinder{<0,0,0><0,Y-R-r,0> r translate<-R, 0,  Z/2-r>}
   cylinder{<0,0,0><0,Y-R-r,0> r translate<-R, 0, -Z/2+r>}
   cylinder{<0,0,0><0,Y-R-r,0> r translate< R, 0, -Z/2+r>}

   box{<-R-r, 0, -Z/2+r><R+r, Y-R, Z/2-r>}
   box{<-R, 0, -Z/2><R, Y-R, Z/2>}
   
}
#end
   
                   
                   
//section of tube radius r sticking out of origin curving into x-y plane radius R for angle A                     
#macro tube(R, A, r)  

 difference{
    torus{R, r rotate 90*z }
    union{
      box{<-2*r-1, -R-r-1, -2*R-2*r-1>< 2*r+1, 0, 2*R+2*r+1>}
      box{<-2*r-1,      0, -2*R-2*r-1>< 2*r+1, R+r+1, 2*R+2*r+1> rotate -A*x}
    } 
    translate -R*z
 }       
#end //of tube  


#macro SquareHoop(X,Z,R,r)
union{
      #declare w1 = X/2-r/2-R;
      #declare w2 = Z/2-r/2-R;     
      
      difference{
        union{
          torus{R+r, r translate<-w1, 0, w2>}
          torus{R+r, r translate<-w1, 0,-w2>}
          torus{R+r, r translate< w1, 0,-w2>}
          torus{R+r, r translate< w1, 0, w2>}
        }
        union{
          box{<-X,-2*r,-w2><X,2*r,w2>}
          box{<-w1,-2*r,-Z><w1,2*r,Z>}
        }
      }
      
      #declare w1 = X/2+r/2;
      #declare w2 = Z/2+r/2;     
      cylinder{<-w1+R,0, w2>< w1-R,0, w2> r}
      cylinder{<-w1+R,0,-w2>< w1-R,0,-w2> r}
      cylinder{<-w1,0,-w2+R><-w1,0, w2-R> r}
      cylinder{< w1,0,-w2+R>< w1,0, w2-R> r}   
}
#end

#macro dohnut(R1,r1,R2,r2,H)
union{

   difference{
     union{
       cylinder{<0, 0,0><0,   H, 0> R1-r1}
       torus{R1-r1, r1 translate <0, H-r1, 0>}
     }
     cylinder{<0,-1,0><0, H+1, 0> R2+r2}
   }          
   
   torus{R2+r2, r2 translate <0, H-r2, 0>}

   difference{
     cylinder{<0, 0,0><0, H-r1, 0> R1   }
     cylinder{<0,-1,0><0,  H+1, 0> R2+r2}
   }       
   
   difference{
     cylinder{<0, 0,0><0, H-r2, 0> R1-r1}
     cylinder{<0,-1,0><0,  H+1, 0> R2+r2}
   }       
   
}
#end //dohnut   

#macro rfillet(R1,r1)

   difference{ 
     cylinder{<0,0,0><0,r1,0> R1 + r1} 
     union{
       cylinder{<0,-1,0><0,r1+1,0> R1}
       torus{R1+r1, r1 translate <0, r1, 0>}
     }
   }          
   
#end //rfillet   

#macro sqfillet(X, Z, R1,r1)

union{                                                    
   #declare w = X/2-R1;
   #declare l = Z/2-R1;                                                    
   union{
     object{rfillet(R1, r1) translate<-w, 0, -l>}
     object{rfillet(R1, r1) translate<-w, 0,  l>}
     object{rfillet(R1, r1) translate< w, 0, -l>}
     object{rfillet(R1, r1) translate< w, 0,  l>}
   }
   
   difference{
     box{     <-w,0, -Z/2-r1><w, r1,-Z/2>}
     cylinder{<-X,r1,-Z/2-r1>< X,r1,-Z/2-r1>r1}
   }
   difference{
     box{     <-w,0,  Z/2+r1><w, r1, Z/2>}
     cylinder{<-X,r1, Z/2+r1>< X,r1, Z/2+r1>r1}
   }
   difference{
     box{     <-X/2-r1,0, -l><-X/2, r1, l>}
     cylinder{<-X/2-r1,r1,-Z><-X/2-r1,r1,Z>r1}
   }
   difference{
     box{     < X/2+r1,0, -l><X/2, r1, l>}
     cylinder{< X/2+r1,r1,-Z><X/2+r1,r1,Z>r1}
   }
}
#end //sqfillet   


#macro sqrDohNut(l,w,R,r)
object                       
{

#declare sdnarc =
intersection
{
  torus{R,r}
  box
  {
    <0,-2*r,0> 
    <2*(R+r),2*r,2*(R+r)>
  }
  translate<-R,0,0>
  rotate<-90,0,0>
}

  union
  {
    cylinder
    {
      <l/2+r,w/2-R+r,0>
      <l/2+r,-w/2+R-r,0>
      r
    }    
    
    cylinder
    {
      <-l/2-r,w/2-R+r,0>
      <-l/2-r,-w/2+R-r,0>
      r
    }
    
    cylinder
    {
      <-l/2-r+R,w/2+r,0>
      <l/2+r-R,w/2+r,0>
      r
    }    
    
    cylinder
    {
      <-l/2-r+R,-w/2-r,0>
      <l/2+r-R,-w/2-r,0>
      r
    } 
    
    object
    {
      sdnarc 
      translate<l/2+r,w/2-R+r,0>
    }
    
    object
    {
      sdnarc
      rotate<0,180,0> 
      translate<-l/2-r,w/2-R+r,0>
    } 
    
    object
    {
      sdnarc
      rotate<180,0,0> 
      translate<l/2+r,-w/2+R-r,0>
    }
    
    
    object
    {
      sdnarc
      rotate<180,0,0>
      rotate<0,180,0> 
      translate<-l/2-r,-w/2+R-r,0>
    }
    
    
  }
  
  rotate 90*x
}
#end


