/* A macro for a concave-concave (minus/plus) lens represented by spheres or aspheres. The aspheres are isosurfaces

The lenses are bounded by plane(s) and/or a cylinder whose dimensions are calculated from the spherical surfaces. In the cases where the aspherics are very large and there would be consequent errors in the profile then some intelligent use of the parameter 'Cutplane' will be required if you want to put flats on the surfaces.

*/

#declare ThisOrigin = NextOrigin; #declare NextOrigin = ThisOrigin+Thk+Nex;
//#debug concat(" Vertex of surface 1 of lens",str(LnzNum,4,0),str(ThisOrigin,9,3))

#if(AspR1 = 0 & AspR2 = 0 )
     #declare Sag1 = -(R1 - sqrt(R1*R1 - D1*D1)); #declare Sag2 = R2 -sqrt(R2*R2 - D2*D2); #declare Lensdia = max(D1,D2);
     #declare LensMP = intersection { cylinder { z*(Sag1-0.01),z*(Sag2+Thk+.01),Lensdia texture { LensBlnk } hollow on}
                                                    sphere { 0,R1 translate -z*R1 inverse}
                                                    sphere { 0,R2 translate z*(R2+Thk) inverse}
                                                    material { LensOpen }
                                                  }
#end

#if ( AspR1 = 1)
     #declare SagSph1 = -(R1 - sqrt(R1*R1 - D1*D1));
     #declare SagAsp1 = Ad*pow(D1,4)+Ae*pow(D1,6)+Af*pow(D1,8)+Ag*pow(D1,10);
     #declare Sag1 = SagSph1 + SagAsp1; #declare Cutplane1 = SagSph1+1; // use this plane to put a flat on the m face
     #debug concat ( " Aspheric sag on surface 1 of lens ",str(LnzNum,3,0),str(SagAsp1,9,3))
     #declare SagSph2 = R2 - sqrt(R2*R2 - D2*D2); #declare BoxD = max(D1,D2);
     #declare Cutplane2 = SagSph2 + Thk-0.25; // use this plane to put a flat on the p face
     #declare LensMP = intersection {isosurface { function { R1 - sqrt(R1*R1 -(x*x+y*y))
                                                                                  - Ad*pow((x*x+y*y),2) - Ae*pow((x*x+y*y),3)
                                                                                   - Af*pow((x*x+y*y),4) - Ag*pow((x*x+y*y),5)
                                                                                   + z
                                                                                 }
                                                                     max_trace IsoMaxtrace accuracy Evalac
                                                                     max_gradient IsoMaxgrad
                                                                     contained_by { box { <-BoxD,-BoxD,-1e6>,<BoxD,BoxD,R2+Thk> } }
                                                                     inverse
                                                                 }
                                                      sphere { 0,R2 translate z*(R2+Thk ) inverse}
                                                        plane { z,Cutplane2 }
                                                     cylinder { -z*R1,z*R2,BoxD texture { LensBlnk } hollow }
                                                     material { LensOpen }
                                                   }

#end

#if ( AspR2 = 1)
     #declare SagSph1 = -(R1 - sqrt(R1*R1 - D1*D1));
     #declare SagSph2 = R2 - sqrt(R2*R2 - D2*D2) ;
     #declare SagAsp2 = Ad*pow(D2,4)+Ae*pow(D2,6)+Af*pow(D2,8)+Ag*pow(D2,10);
     #declare Sag2 = SagSph2 + SagAsp2;
     #if(SagAsp2 > 0  )  #declare Cutplane = SagSph2+SagAsp2+Thk; #end
     #if(SagAsp2 <= 0)  #declare Cutplane = SagSph2+Thk;               #end
     #debug concat ( " Aspheric sag on surface 2 of lens ",str(LnzNum,3,0),str(SagAsp2,9,3))
     #declare LensMP = intersection { isosurface { function { R2 - sqrt(R2*R2-(x*x+y*y)) + Thk
                                                                                   + Ad*pow((x*x+y*y),2) + Ae*pow((x*x+y*y),3)
                                                                                   + Af*pow((x*x+y*y),4) + Ag*pow((x*x+y*y),5)
                                                                                   - z
                                                                                  }
                                                                      max_trace IsoMaxtrace accuracy Evalac
                                                                      max_gradient IsoMaxgrad
                                                                      contained_by { box { <-D1,-D1,-10>,<D1,D1,100> } }
                                                                      inverse
                                                                    }
                                                        cylinder { z*SagSph1,z*R2,D2 texture { LensBlnk } hollow on }
                                                         sphere { 0,R1 translate -z*R1 inverse }
                                                         material { LensOpen }
                                                    }
#end
#debug concat ("\n")
#undef LensOpen