Back to home page

EIC code displayed by LXR

 
 

    


Warning, /include/opencascade/IntCurveSurface_Inter.gxx is written in an unsupported language. File is not indexed.

0001 // Created on: 1993-04-09
0002 // Created by: Laurent BUCHARD
0003 // Copyright (c) 1993-1999 Matra Datavision
0004 // Copyright (c) 1999-2014 OPEN CASCADE SAS
0005 //
0006 // This file is part of Open CASCADE Technology software library.
0007 //
0008 // This library is free software; you can redistribute it and/or modify it under
0009 // the terms of the GNU Lesser General Public License version 2.1 as published
0010 // by the Free Software Foundation, with special exception defined in the file
0011 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
0012 // distribution for complete text of the license and disclaimer of any warranty.
0013 //
0014 // Alternatively, this file may be used under the terms of Open CASCADE
0015 // commercial license or contractual agreement.
0016 
0017 //#ifndef OCCT_DEBUG
0018 //#define No_Standard_RangeError
0019 //#define No_Standard_OutOfRange
0020 //#endif
0021 
0022 
0023 #define  TOLTANGENCY         0.00000001
0024 #define  TOLERANCE_ANGULAIRE 1.e-12//0.00000001
0025 #define  TOLERANCE           0.00000001
0026 
0027 #define NBSAMPLESONCIRCLE  32
0028 #define NBSAMPLESONELLIPSE 32
0029 #define NBSAMPLESONPARAB   16
0030 #define NBSAMPLESONHYPR    32
0031 
0032 #include <ElSLib.hxx>
0033 #include <Intf_SectionPoint.hxx>
0034 #include <Intf_TangentZone.hxx>
0035 #include <Intf_Tool.hxx>
0036 #include <math_FunctionSetRoot.hxx>
0037 #include <IntCurveSurface_IntersectionPoint.hxx>
0038 #include <IntCurveSurface_IntersectionSegment.hxx>
0039 #include <IntAna_IntConicQuad.hxx>
0040 #include <IntAna_Quadric.hxx>
0041 #include <gp_Vec.hxx>
0042 #include <gp_Dir.hxx>
0043 #include <Precision.hxx>
0044 #include <IntAna_IntLinTorus.hxx>
0045 
0046 #include <GeomAbs_Shape.hxx>
0047 #include <GeomAbs_CurveType.hxx>
0048 #include <TColStd_Array1OfReal.hxx>
0049 #include <TColgp_Array1OfPnt.hxx>
0050 #include <gp_Pnt.hxx>
0051 #include <gp_Pln.hxx>
0052 #include <gp_Lin.hxx>
0053 #include <GProp_PEquation.hxx>
0054 #include <GProp_PGProps.hxx>
0055 #include <GProp_PrincipalProps.hxx>
0056 #include <Extrema_ExtElC.hxx>
0057 #include <Extrema_POnCurv.hxx>
0058 
0059 
0060 
0061 #include <ProjLib_Plane.hxx>
0062 #include <IntAna2d_AnaIntersection.hxx>
0063 #include <gp_Lin2d.hxx>
0064 #include <IntAna2d_IntPoint.hxx>
0065 #include <gp_Parab2d.hxx>
0066 #include <IntAna2d_Conic.hxx>
0067 #include <IntAna2d_AnaIntersection.hxx>
0068 #include <gp_Hypr2d.hxx>
0069 #include <Adaptor3d_Curve.hxx>
0070 #include <Adaptor3d_Surface.hxx>
0071 
0072 
0073 #include <TColgp_Array2OfPnt.hxx>
0074 #include <TColStd_HArray1OfReal.hxx>
0075 #include <Adaptor3d_TopolTool.hxx>
0076 #include <ElCLib.hxx>
0077 //#define ICS_DEB
0078 static 
0079   void EstLimForInfExtr(const gp_Lin&   Line,
0080                         const TheSurface& surface, 
0081                         const Standard_Boolean IsOffSurf,
0082                         const Standard_Integer nbsu, 
0083                         const Standard_Boolean U1inf, 
0084                         const Standard_Boolean U2inf, 
0085                         const Standard_Boolean V1inf, 
0086                         const Standard_Boolean V2inf, 
0087                         Standard_Real& U1new, 
0088                         Standard_Real& U2new, 
0089                         Standard_Real& V1new, 
0090                         Standard_Real& V2new, 
0091                         Standard_Boolean& NoIntersection);
0092 
0093 static 
0094   void EstLimForInfRevl(const gp_Lin&   Line,
0095                         const TheSurface& surface, 
0096                         const Standard_Boolean U1inf, 
0097                         const Standard_Boolean U2inf, 
0098                         const Standard_Boolean V1inf, 
0099                         const Standard_Boolean V2inf, 
0100                         Standard_Real& U1new, 
0101                         Standard_Real& U2new, 
0102                         Standard_Real& V1new, 
0103                         Standard_Real& V2new, 
0104                         Standard_Boolean& NoIntersection);
0105 
0106 static 
0107   void EstLimForInfOffs(const gp_Lin&   Line,
0108                         const TheSurface& surface, 
0109                         const Standard_Integer nbsu, 
0110                         const Standard_Boolean U1inf, 
0111                         const Standard_Boolean U2inf, 
0112                         const Standard_Boolean V1inf, 
0113                         const Standard_Boolean V2inf, 
0114                         Standard_Real& U1new, 
0115                         Standard_Real& U2new, 
0116                         Standard_Real& V1new, 
0117                         Standard_Real& V2new, 
0118                         Standard_Boolean& NoIntersection);
0119 
0120 static
0121   void EstLimForInfSurf(Standard_Real& U1new, 
0122                         Standard_Real& U2new, 
0123                         Standard_Real& V1new, 
0124                         Standard_Real& V2new);
0125 
0126 static
0127   void SectionPointToParameters(const Intf_SectionPoint& Sp,
0128                                 const IntCurveSurface_ThePolyhedron& Surf,
0129                                 const IntCurveSurface_ThePolygon&    Curv,
0130                                 Standard_Real& u,
0131                                 Standard_Real& v,
0132                                 Standard_Real& w);
0133 
0134 static 
0135   void IntCurveSurface_ComputeTransitions(const TheCurve& curve,
0136                                           const Standard_Real w,
0137                                           IntCurveSurface_TransitionOnCurve&   TransOnCurve,
0138                                           const TheSurface& surface,
0139                                           const Standard_Real u,
0140                                           const Standard_Real v);
0141 
0142 static 
0143   void IntCurveSurface_ComputeParamsOnQuadric(const TheSurface& surface,
0144                                               const gp_Pnt& P,
0145                                               Standard_Real& u,
0146                                               Standard_Real& v);
0147 
0148 static 
0149   void ProjectIntersectAndEstLim(const gp_Lin&        theLine,
0150                                  const gp_Pln&        thePln,
0151                                  const ProjLib_Plane& theBasCurvProj,
0152                                  Standard_Real&       theVmin,
0153                                  Standard_Real&       theVmax,
0154                                  Standard_Boolean&    theNoIntersection);
0155 
0156 //=======================================================================
0157 //function : IntCurveSurface_Inter
0158 //purpose  : 
0159 //=======================================================================
0160 IntCurveSurface_Inter::IntCurveSurface_Inter() 
0161 { 
0162 }
0163 //=======================================================================
0164 //function : DoSurface
0165 //purpose  : 
0166 //=======================================================================
0167 void IntCurveSurface_Inter::DoSurface(const TheSurface&   surface,
0168                                       const Standard_Real u0,
0169                                       const Standard_Real u1,
0170                                       const Standard_Real v0,
0171                                       const Standard_Real v1,
0172                                       TColgp_Array2OfPnt& pntsOnSurface,
0173                                       Bnd_Box&            boxSurface,
0174                                       Standard_Real&      gap)
0175 {
0176   Standard_Integer iU = 0, iV = 0;
0177   Standard_Real U = 0., V = 0;
0178 // modified by NIZHNY-MKK  Mon Oct  3 17:38:45 2005
0179 //   Standard_Real dU = fabs(u1-u0)/50., dV = fabs(v1-v0)/50.;
0180   Standard_Real dU = (u1-u0)/50., dV = (v1-v0)/50.;
0181   gp_Pnt aPnt;
0182 
0183   for(iU = 0; iU < 50; iU++) {
0184     
0185     if(iU == 0)
0186       U = u0;
0187     else if(iU == 49)
0188       U = u1;
0189     else 
0190       U = u0 + dU * ((Standard_Real)iU);
0191     
0192     for(iV = 0; iV < 50; iV++) {
0193 
0194       if(iV == 0)
0195         V = v0;
0196       else if(iV == 49)
0197         V = v1;
0198       else
0199         V = v0 + dV * ((Standard_Real)iV);
0200 
0201       TheSurfaceTool::D0(surface,U,V,aPnt);
0202       boxSurface.Add(aPnt);
0203       pntsOnSurface.SetValue(iU+1,iV+1,aPnt);
0204     }
0205   }
0206   Standard_Real Ures = TheSurfaceTool::UResolution(surface,dU);
0207   Standard_Real Vres = TheSurfaceTool::VResolution(surface,dV);
0208   gap = Max(Ures,Vres);
0209 }
0210 
0211 //=======================================================================
0212 //function : DoNewBounds
0213 //purpose  : 
0214 //=======================================================================
0215 void IntCurveSurface_Inter::DoNewBounds(
0216                                         const TheSurface&           surface,
0217                                         const Standard_Real         u0,
0218                                         const Standard_Real         u1,
0219                                         const Standard_Real         v0,
0220                                         const Standard_Real         v1,
0221                                         const TColgp_Array2OfPnt&   pntsOnSurface,
0222                                         const TColStd_Array1OfReal& X,
0223                                         const TColStd_Array1OfReal& Y,
0224                                         const TColStd_Array1OfReal& Z,
0225                                         TColStd_Array1OfReal&       Bounds)
0226 {
0227   Bounds.SetValue(1,u0);
0228   Bounds.SetValue(2,u1);
0229   Bounds.SetValue(3,v0);
0230   Bounds.SetValue(4,v1);
0231 
0232   Standard_Boolean isUClosed = (TheSurfaceTool::IsUClosed(surface) || TheSurfaceTool::IsUPeriodic(surface));
0233   Standard_Boolean isVClosed = (TheSurfaceTool::IsVClosed(surface) || TheSurfaceTool::IsVPeriodic(surface));
0234   Standard_Boolean checkU = (isUClosed) ? Standard_False : Standard_True;
0235   Standard_Boolean checkV = (isVClosed) ? Standard_False : Standard_True;
0236 
0237   Standard_Integer i = 0, j = 0, k = 0, iU = 0, iV = 0;
0238   Standard_Integer iUmin = 50, iVmin = 50, iUmax = 1, iVmax = 1;
0239 
0240   for(i = 1; i <= 2; i++) {
0241     for(j = 1; j <= 2; j++) {
0242       for(k = 1; k <= 2; k++) {
0243         gp_Pnt aPoint(X(i),Y(j),Z(k));
0244         Standard_Real DistMin = 1.e+100;
0245         Standard_Integer diU = 0, diV = 0;
0246         for(iU = 1; iU <= 50; iU++) {
0247           for(iV = 1; iV <= 50; iV++) {
0248             const gp_Pnt aP = pntsOnSurface.Value(iU,iV);
0249             Standard_Real dist = aP.SquareDistance(aPoint);
0250             if(dist < DistMin) {
0251               DistMin = dist;
0252               diU = iU;
0253               diV = iV;
0254             }
0255           }
0256         }
0257         if(diU > 0 && diU < iUmin) iUmin = diU;
0258         if(diU > 0 && diU > iUmax) iUmax = diU;
0259         if(diV > 0 && diV < iVmin) iVmin = diV;
0260         if(diV > 0 && diV > iVmax) iVmax = diV;
0261       }
0262     }
0263   }
0264 
0265 // modified by NIZHNY-MKK  Mon Oct  3 17:38:43 2005
0266 //   Standard_Real dU = fabs(u1-u0)/50., dV = fabs(v1-v0)/50.;
0267   Standard_Real dU = (u1-u0)/50., dV = (v1-v0)/50.;
0268 
0269   Standard_Real USmin = u0 + dU * ((Standard_Real)(iUmin - 1));
0270   Standard_Real USmax = u0 + dU * ((Standard_Real)(iUmax - 1));
0271   Standard_Real VSmin = v0 + dV * ((Standard_Real)(iVmin - 1));
0272   Standard_Real VSmax = v0 + dV * ((Standard_Real)(iVmax - 1));
0273 
0274   if(USmin > USmax) {
0275     Standard_Real tmp = USmax;
0276     USmax = USmin;
0277     USmin = tmp;
0278   }
0279   if(VSmin > VSmax) {
0280     Standard_Real tmp = VSmax;
0281     VSmax = VSmin;
0282     VSmin = tmp;
0283   }
0284 
0285   USmin -= 1.5*dU;
0286   if(USmin < u0) USmin = u0;
0287   USmax += 1.5*dU;
0288   if(USmax > u1) USmax = u1;
0289   VSmin -= 1.5*dV;
0290   if(VSmin < v0) VSmin = v0;
0291   VSmax += 1.5*dV;
0292   if(VSmax > v1) VSmax = v1;
0293 
0294   if(checkU) {
0295     Bounds.SetValue(1,USmin);
0296     Bounds.SetValue(2,USmax);
0297   }
0298   if(checkV) {
0299     Bounds.SetValue(3,VSmin);
0300     Bounds.SetValue(4,VSmax);
0301   }
0302 }
0303 
0304 //=======================================================================
0305 //function : Perform
0306 //purpose  : Decompose la surface si besoin est 
0307 //=======================================================================
0308 void IntCurveSurface_Inter::Perform(const TheCurve&   curve,
0309                                     const TheSurface& surface)
0310 {
0311   ResetFields();
0312   done = Standard_True;
0313   Standard_Integer NbUOnS = TheSurfaceTool::NbUIntervals(surface,GeomAbs_C2);
0314   Standard_Integer NbVOnS = TheSurfaceTool::NbVIntervals(surface,GeomAbs_C2);
0315   Standard_Real U0,U1,V0,V1; 
0316 
0317   if(NbUOnS > 1)
0318   {
0319     TColStd_Array1OfReal TabU(1,NbUOnS+1);
0320     TheSurfaceTool::UIntervals(surface,TabU,GeomAbs_C2);
0321     for(Standard_Integer iu = 1;iu <= NbUOnS; iu++)
0322     {
0323       U0 = TabU.Value(iu);
0324       U1 = TabU.Value(iu+1);
0325       if(NbVOnS > 1)
0326       {
0327         TColStd_Array1OfReal TabV(1,NbVOnS+1);
0328         TheSurfaceTool::VIntervals(surface,TabV,GeomAbs_C2);
0329         for(Standard_Integer iv = 1;iv <= NbVOnS; iv++)
0330         {
0331           // More than one interval on U and V param space.
0332           V0 = TabV.Value(iv);
0333           V1 = TabV.Value(iv+1);
0334           Perform(curve,surface,U0,V0,U1,V1);
0335         }
0336       }
0337       else
0338       {
0339         // More than one interval only on U param space.
0340         V0 = TheSurfaceTool::FirstVParameter(surface);
0341         V1 = TheSurfaceTool::LastVParameter(surface);
0342         Perform(curve,surface,U0,V0,U1,V1);
0343       }
0344     }
0345   }
0346   else if(NbVOnS > 1)
0347   {
0348     // More than one interval only on V param space.
0349     U0 = TheSurfaceTool::FirstUParameter(surface);
0350     U1 = TheSurfaceTool::LastUParameter(surface);   
0351     TColStd_Array1OfReal TabV(1,NbVOnS+1);
0352     TheSurfaceTool::VIntervals(surface,TabV,GeomAbs_C2);
0353     for(Standard_Integer iv = 1;iv <= NbVOnS; iv++)
0354     {
0355       V0 = TabV.Value(iv);
0356       V1 = TabV.Value(iv+1);
0357       Perform(curve,surface,U0,V0,U1,V1);
0358     }
0359   }
0360   else
0361   {
0362     // One interval on U and V param space.
0363     V0 = TheSurfaceTool::FirstVParameter(surface);
0364     V1 = TheSurfaceTool::LastVParameter(surface);
0365     U0 = TheSurfaceTool::FirstUParameter(surface);
0366     U1 = TheSurfaceTool::LastUParameter(surface);
0367 
0368     Perform(curve,surface,U0,V0,U1,V1);
0369   }
0370 }
0371 //=======================================================================
0372 //function : Perform
0373 //purpose  : 
0374 //=======================================================================
0375 void IntCurveSurface_Inter::Perform(const TheCurve&   curve,
0376                                     const TheSurface& surface,
0377                                     const Standard_Real U1,const Standard_Real V1,
0378                                     const Standard_Real U2,const Standard_Real V2)
0379 {
0380   // Protection from double type overflow.
0381   // This may happen inside square magnitude computation based on normal,
0382   // which was computed on bound parameteres (bug26525).
0383   Standard_Real UU1 = U1, UU2 = U2, VV1 = V1, VV2 = V2;
0384   if (U1 < -1.0e50)
0385     UU1 = -1.0e50;
0386   if (U2 >  1.0e50)
0387     UU2 = 1.0e50;
0388   if (V1 < -1.0e50)
0389     VV1 = -1.0e50;
0390   if (V2 >  1.0e50)
0391     VV2 = 1.0e50;
0392 
0393   GeomAbs_CurveType CurveType = TheCurveTool::GetType(curve);
0394   
0395   switch(CurveType) { 
0396   case GeomAbs_Line:  
0397     { 
0398       PerformConicSurf(TheCurveTool::Line(curve),curve,surface,UU1,VV1,UU2,VV2);
0399       break;
0400     }
0401   case GeomAbs_Circle: 
0402     { 
0403       PerformConicSurf(TheCurveTool::Circle(curve),curve,surface,UU1,VV1,UU2,VV2);
0404       break;
0405     }
0406   case GeomAbs_Ellipse: 
0407     { 
0408       PerformConicSurf(TheCurveTool::Ellipse(curve),curve,surface,UU1,VV1,UU2,VV2);
0409       break;
0410     }    
0411   case GeomAbs_Parabola:  
0412     {
0413       PerformConicSurf(TheCurveTool::Parabola(curve),curve,surface,UU1,VV1,UU2,VV2);
0414       break;
0415     }
0416   case GeomAbs_Hyperbola: 
0417     {
0418       PerformConicSurf(TheCurveTool::Hyperbola(curve),curve,surface,UU1,VV1,UU2,VV2);
0419       break;
0420     }
0421   default:    
0422     {
0423       Standard_Integer nbIntervalsOnCurve = TheCurveTool::NbIntervals(curve,GeomAbs_C2);
0424       GeomAbs_SurfaceType SurfaceType = TheSurfaceTool::GetType(surface);
0425       if(   (SurfaceType != GeomAbs_Plane) 
0426          && (SurfaceType != GeomAbs_Cylinder)
0427          && (SurfaceType != GeomAbs_Cone) 
0428          && (SurfaceType != GeomAbs_Sphere)) { 
0429         
0430         if(nbIntervalsOnCurve > 1) { 
0431           TColStd_Array1OfReal TabW(1,nbIntervalsOnCurve+1);
0432           TheCurveTool::Intervals(curve,TabW,GeomAbs_C2);
0433           for(Standard_Integer i = 1; i<=nbIntervalsOnCurve; i++) { 
0434             Standard_Real u1,u2;
0435             u1 = TabW.Value(i);
0436             u2 = TabW.Value(i+1);
0437 
0438             Handle(TColStd_HArray1OfReal) aPars;
0439             Standard_Real defl = 0.1;
0440             Standard_Integer NbMin = 10;
0441             TheCurveTool::SamplePars(curve, u1, u2, defl, NbMin, aPars);
0442 
0443 //          IntCurveSurface_ThePolygon  polygon(curve,u1,u2,TheCurveTool::NbSamples(curve,u1,u2));
0444             IntCurveSurface_ThePolygon  polygon(curve, aPars->Array1());
0445             InternalPerform(curve,polygon,surface,UU1,VV1,UU2,VV2);
0446           }
0447         }
0448         else {
0449           Standard_Real u1,u2;
0450           u1 = TheCurveTool::FirstParameter(curve);
0451           u2 = TheCurveTool::LastParameter(curve);
0452 
0453           Handle(TColStd_HArray1OfReal) aPars;
0454           Standard_Real defl = 0.1;
0455           Standard_Integer NbMin = 10;
0456           TheCurveTool::SamplePars(curve, u1, u2, defl, NbMin, aPars);
0457 
0458 //        IntCurveSurface_ThePolygon       polygon(curve,TheCurveTool::NbSamples(curve,u1,u2));
0459           IntCurveSurface_ThePolygon  polygon(curve, aPars->Array1());
0460           InternalPerform(curve,polygon,surface,UU1,VV1,UU2,VV2);
0461         }
0462       }
0463       else {   //-- la surface est une quadrique 
0464         InternalPerformCurveQuadric(curve,surface);
0465       }
0466     }
0467   }
0468 }
0469 //=======================================================================
0470 //function : Perform
0471 //purpose  : 
0472 //=======================================================================
0473 void IntCurveSurface_Inter::Perform(const TheCurve&   curve,
0474                                     const IntCurveSurface_ThePolygon& polygon,
0475                                     const TheSurface& surface) {
0476   ResetFields();
0477   done = Standard_True;
0478   Standard_Real u1,v1,u2,v2;
0479   u1 = TheSurfaceTool::FirstUParameter(surface);
0480   v1 = TheSurfaceTool::FirstVParameter(surface);
0481   u2 = TheSurfaceTool::LastUParameter(surface);
0482   v2 = TheSurfaceTool::LastVParameter(surface);
0483   Standard_Integer nbsu,nbsv;
0484   nbsu = TheSurfaceTool::NbSamplesU(surface,u1,u2);
0485   nbsv = TheSurfaceTool::NbSamplesV(surface,v1,v2);
0486   if(nbsu>40) nbsu=40;
0487   if(nbsv>40) nbsv=40;
0488   IntCurveSurface_ThePolyhedron    polyhedron(surface,nbsu,nbsv,u1,v1,u2,v2);
0489   Perform(curve,polygon,surface,polyhedron);
0490 }
0491 //=======================================================================
0492 //function : Perform
0493 //purpose  : 
0494 //=======================================================================
0495 void IntCurveSurface_Inter::Perform(const TheCurve&   curve,
0496                                     const TheSurface& surface,
0497                                     const IntCurveSurface_ThePolyhedron& polyhedron) {
0498   ResetFields();
0499   done = Standard_True;
0500   Standard_Real u1 = TheCurveTool::FirstParameter(curve);
0501   Standard_Real u2 = TheCurveTool::LastParameter(curve);
0502   IntCurveSurface_ThePolygon polygon(curve,TheCurveTool::NbSamples(curve,u1,u2));
0503   Perform(curve,polygon,surface,polyhedron);
0504 }
0505 //=======================================================================
0506 //function : Perform
0507 //purpose  : 
0508 //=======================================================================
0509 void IntCurveSurface_Inter::Perform(const TheCurve&       curve,
0510                                     const IntCurveSurface_ThePolygon&     polygon,
0511                                     const TheSurface&     surface,
0512                                     const IntCurveSurface_ThePolyhedron&  polyhedron) {
0513   ResetFields();
0514   done = Standard_True;
0515   Standard_Real u1,v1,u2,v2;
0516   u1 = TheSurfaceTool::FirstUParameter(surface);
0517   v1 = TheSurfaceTool::FirstVParameter(surface);
0518   u2 = TheSurfaceTool::LastUParameter(surface);
0519   v2 = TheSurfaceTool::LastVParameter(surface);
0520   InternalPerform(curve,polygon,surface,polyhedron,u1,v1,u2,v2);
0521 }
0522 
0523 //=======================================================================
0524 //function : Perform
0525 //purpose  : 
0526 //=======================================================================
0527 void IntCurveSurface_Inter::Perform(const TheCurve&       curve,
0528                                     const IntCurveSurface_ThePolygon&     polygon,
0529                                     const TheSurface&     surface,
0530                                     const IntCurveSurface_ThePolyhedron&  polyhedron,
0531                                     Bnd_BoundSortBox& BndBSB) {
0532   ResetFields();
0533   done = Standard_True;
0534   Standard_Real u1,v1,u2,v2;
0535   u1 = TheSurfaceTool::FirstUParameter(surface);
0536   v1 = TheSurfaceTool::FirstVParameter(surface);
0537   u2 = TheSurfaceTool::LastUParameter(surface);
0538   v2 = TheSurfaceTool::LastVParameter(surface);
0539   InternalPerform(curve,polygon,surface,polyhedron,u1,v1,u2,v2,BndBSB);
0540 }
0541 //=======================================================================
0542 //function : InternalPerform
0543 //purpose  : C a l c u l   d u   p o i n t   a p p r o c h e           
0544 //==              p u i s   d u   p o i n t   E x a c t  
0545 //=======================================================================
0546 void IntCurveSurface_Inter::InternalPerform(const TheCurve&       curve,
0547                                             const IntCurveSurface_ThePolygon&     polygon,
0548                                             const TheSurface&     surface,
0549                                             const IntCurveSurface_ThePolyhedron&  polyhedron,
0550                                             const Standard_Real u0,
0551                                             const Standard_Real v0,
0552                                             const Standard_Real u1, 
0553                                             const Standard_Real v1,
0554                                             Bnd_BoundSortBox& BSB) {
0555   IntCurveSurface_TheInterference  interference(polygon,polyhedron,BSB);
0556   IntCurveSurface_TheCSFunction    theicsfunction(surface,curve);
0557   IntCurveSurface_TheExactInter    intersectionExacte(theicsfunction,TOLTANGENCY);
0558   math_FunctionSetRoot rsnld(intersectionExacte.Function());
0559 
0560 //  Standard_Real    u,v,w,winit;
0561   Standard_Real    u,v,w;
0562   gp_Pnt P;
0563   Standard_Real winf = polygon.InfParameter();
0564   Standard_Real wsup = polygon.SupParameter();
0565   Standard_Integer NbSectionPoints = interference.NbSectionPoints();
0566   Standard_Integer NbTangentZones  = interference.NbTangentZones();
0567 
0568 
0569   //-- Les interferences renvoient parfois de nombreuses fois (>20) les memes points 
0570   
0571   Standard_Integer i,NbStartPoints=NbSectionPoints;
0572   for(i=1; i<= NbTangentZones; i++) {
0573     const Intf_TangentZone& TZ = interference.ZoneValue(i);
0574     Standard_Integer nbpnts = TZ.NumberOfPoints();
0575     NbStartPoints+=nbpnts;
0576   }
0577   
0578   if(NbStartPoints) { 
0579     Standard_Real *TabU = new Standard_Real [NbStartPoints+1];
0580     Standard_Real *TabV = new Standard_Real [NbStartPoints+1];
0581     Standard_Real *TabW = new Standard_Real [NbStartPoints+1];
0582     Standard_Integer IndexPoint=0;
0583     
0584     for(i=1; i<= NbSectionPoints; i++) {
0585       const Intf_SectionPoint& SP = interference.PntValue(i);
0586       SectionPointToParameters(SP,polyhedron,polygon,u,v,w);
0587       TabU[IndexPoint]=u;
0588       TabV[IndexPoint]=v;
0589       TabW[IndexPoint]=w;
0590       IndexPoint++;
0591     }
0592     for(i=1; i<= NbTangentZones; i++) {
0593       const Intf_TangentZone& TZ = interference.ZoneValue(i);
0594       Standard_Integer nbpnts = TZ.NumberOfPoints();
0595       for(Standard_Integer j=1; j<=nbpnts; j++) { 
0596         const Intf_SectionPoint& SP = TZ.GetPoint(j);
0597         SectionPointToParameters(SP,polyhedron,polygon,u,v,w);  
0598         TabU[IndexPoint]=u;
0599         TabV[IndexPoint]=v;
0600         TabW[IndexPoint]=w;
0601         IndexPoint++;
0602       }
0603     }
0604     
0605     //-- Tri
0606     Standard_Real su=0,sv=0,sw=0,ptol;
0607     ptol = 10*Precision::PConfusion();
0608     
0609     //-- Tri suivant la variable W 
0610     Standard_Boolean Triok;
0611     do { 
0612       Triok=Standard_True;
0613       Standard_Integer im1;
0614       for(i=1,im1=0;i<NbStartPoints;im1++,i++) {       
0615         if(TabW[i] < TabW[im1]) { 
0616           Standard_Real t=TabW[i]; TabW[i]=TabW[im1]; TabW[im1]=t;
0617           t=TabU[i]; TabU[i]=TabU[im1]; TabU[im1]=t;
0618           t=TabV[i]; TabV[i]=TabV[im1]; TabV[im1]=t;
0619           Triok=Standard_False;
0620         }
0621       }
0622     }
0623     while(Triok==Standard_False);
0624     
0625     //-- On trie pour des meme W suivant U
0626     do { 
0627       Triok=Standard_True;
0628       Standard_Integer im1;
0629       for(i=1,im1=0;i<NbStartPoints;im1++,i++) {       
0630 // modified by NIZHNY-MKK  Mon Oct  3 17:38:49 2005
0631 //      if(Abs(TabW[i]-TabW[im1])<ptol) { 
0632         if((TabW[i]-TabW[im1])<ptol) { 
0633           TabW[i]=TabW[im1];
0634           if(TabU[i] < TabU[im1]) { 
0635             Standard_Real t=TabU[i]; TabU[i]=TabU[im1]; TabU[im1]=t;
0636             t=TabV[i]; TabV[i]=TabV[im1]; TabV[im1]=t;
0637             Triok=Standard_False;
0638           }
0639         }
0640       }
0641     }
0642     while(Triok==Standard_False);
0643     
0644     //-- On trie pour des meme U et W suivant V
0645     do { 
0646       Triok=Standard_True;
0647       Standard_Integer im1;
0648       for(i=1,im1=0;i<NbStartPoints;im1++,i++) {       
0649 // modified by NIZHNY-MKK  Mon Oct  3 17:38:52 2005
0650 //      if((Abs(TabW[i]-TabW[im1])<ptol) && (Abs(TabU[i]-TabU[im1])<ptol)) { 
0651         if(((TabW[i]-TabW[im1])<ptol) && ((TabU[i]-TabU[im1])<ptol)) { 
0652           TabU[i]=TabU[im1];
0653           if(TabV[i] < TabV[im1]) { 
0654             Standard_Real t=TabV[i]; TabV[i]=TabV[im1]; TabV[im1]=t;
0655             Triok=Standard_False;
0656           }
0657         }
0658       }
0659     }
0660     while(Triok==Standard_False);
0661     
0662     
0663     for(i=0;i<NbStartPoints; i++) { 
0664       u=TabU[i]; v=TabV[i]; w=TabW[i];
0665       if(i==0) {
0666         su=u-1; 
0667       }
0668       if(Abs(u-su)>ptol || Abs(v-sv)>ptol || Abs(w-sw)>ptol) { 
0669         intersectionExacte.Perform(u,v,w,rsnld,u0,u1,v0,v1,winf,wsup);
0670         if(intersectionExacte.IsDone()) { 
0671           if(!intersectionExacte.IsEmpty()) { 
0672             P=intersectionExacte.Point();
0673             w=intersectionExacte.ParameterOnCurve();
0674             intersectionExacte.ParameterOnSurface(u,v);
0675             AppendPoint(curve,w,surface,u,v);
0676           }
0677         }
0678       }
0679       su=TabU[i]; sv=TabV[i]; sw=TabW[i];
0680     }
0681     delete [] TabW;
0682     delete [] TabV;
0683     delete [] TabU;
0684   }
0685 }
0686 
0687 //=======================================================================
0688 //function : InternalPerform
0689 //purpose  : 
0690 //=======================================================================
0691 void IntCurveSurface_Inter::InternalPerform(const TheCurve&       curve,
0692                                             const IntCurveSurface_ThePolygon&     polygon,
0693                                             const TheSurface&     surface,
0694                                             const IntCurveSurface_ThePolyhedron&  polyhedron,
0695                                             const Standard_Real u0,
0696                                             const Standard_Real v0,
0697                                             const Standard_Real u1, 
0698                                             const Standard_Real v1) { 
0699   IntCurveSurface_TheInterference  interference(polygon,polyhedron);
0700   IntCurveSurface_TheCSFunction    theicsfunction(surface,curve);
0701   IntCurveSurface_TheExactInter    intersectionExacte(theicsfunction,TOLTANGENCY);
0702   math_FunctionSetRoot rsnld(intersectionExacte.Function());
0703 
0704 //  Standard_Real    u,v,w,winit;
0705   Standard_Real    u,v,w;
0706   gp_Pnt P;
0707   Standard_Real winf = polygon.InfParameter();
0708   Standard_Real wsup = polygon.SupParameter();
0709   Standard_Integer NbSectionPoints = interference.NbSectionPoints();
0710   Standard_Integer NbTangentZones  = interference.NbTangentZones();
0711 
0712 
0713   //-- Les interferences renvoient parfois de nombreuses fois (>20) les memes points 
0714   
0715   Standard_Integer i,NbStartPoints=NbSectionPoints;
0716   for(i=1; i<= NbTangentZones; i++) {
0717     const Intf_TangentZone& TZ = interference.ZoneValue(i);
0718     Standard_Integer nbpnts = TZ.NumberOfPoints();
0719     NbStartPoints+=nbpnts;
0720   }
0721   
0722   if(NbStartPoints) { 
0723     Standard_Real *TabU = new Standard_Real [NbStartPoints+1];
0724     Standard_Real *TabV = new Standard_Real [NbStartPoints+1];
0725     Standard_Real *TabW = new Standard_Real [NbStartPoints+1];
0726     Standard_Integer IndexPoint=0;
0727     
0728     for(i=1; i<= NbSectionPoints; i++) {
0729       const Intf_SectionPoint& SP = interference.PntValue(i);
0730       SectionPointToParameters(SP,polyhedron,polygon,u,v,w);
0731       TabU[IndexPoint]=u;
0732       TabV[IndexPoint]=v;
0733       TabW[IndexPoint]=w;
0734       IndexPoint++;
0735     }
0736     for(i=1; i<= NbTangentZones; i++) {
0737       const Intf_TangentZone& TZ = interference.ZoneValue(i);
0738       Standard_Integer nbpnts = TZ.NumberOfPoints();
0739       for(Standard_Integer j=1; j<=nbpnts; j++) { 
0740         const Intf_SectionPoint& SP = TZ.GetPoint(j);
0741         SectionPointToParameters(SP,polyhedron,polygon,u,v,w);  
0742         TabU[IndexPoint]=u;
0743         TabV[IndexPoint]=v;
0744         TabW[IndexPoint]=w;
0745         IndexPoint++;
0746       }
0747     }
0748     
0749     //-- Tri
0750     Standard_Real su=0,sv=0,sw=0,ptol;
0751     ptol = 10*Precision::PConfusion();
0752     
0753     //-- Tri suivant la variable W 
0754     Standard_Boolean Triok;
0755     do { 
0756       Triok=Standard_True;
0757       Standard_Integer im1;
0758       for(i=1,im1=0;i<NbStartPoints;im1++,i++) {       
0759         if(TabW[i] < TabW[im1]) { 
0760           Standard_Real t=TabW[i]; TabW[i]=TabW[im1]; TabW[im1]=t;
0761           t=TabU[i]; TabU[i]=TabU[im1]; TabU[im1]=t;
0762           t=TabV[i]; TabV[i]=TabV[im1]; TabV[im1]=t;
0763           Triok=Standard_False;
0764         }
0765       }
0766     }
0767     while(Triok==Standard_False);
0768     
0769     //-- On trie pour des meme W suivant U
0770     do { 
0771       Triok=Standard_True;
0772       Standard_Integer im1;
0773       for(i=1,im1=0;i<NbStartPoints;im1++,i++) {       
0774 // modified by NIZHNY-MKK  Mon Oct  3 17:38:56 2005
0775 //      if(Abs(TabW[i]-TabW[im1])<ptol) { 
0776         if((TabW[i]-TabW[im1])<ptol) { 
0777           TabW[i]=TabW[im1];
0778           if(TabU[i] < TabU[im1]) { 
0779             Standard_Real t=TabU[i]; TabU[i]=TabU[im1]; TabU[im1]=t;
0780             t=TabV[i]; TabV[i]=TabV[im1]; TabV[im1]=t;
0781             Triok=Standard_False;
0782           }
0783         }
0784       }
0785     }
0786     while(Triok==Standard_False);
0787     
0788     //-- On trie pour des meme U et W suivant V
0789     do { 
0790       Triok=Standard_True;
0791       Standard_Integer im1;
0792       for(i=1,im1=0;i<NbStartPoints;im1++,i++) {       
0793 // modified by NIZHNY-MKK  Mon Oct  3 17:38:58 2005
0794 //      if((Abs(TabW[i]-TabW[im1])<ptol) && (Abs(TabU[i]-TabU[im1])<ptol)) { 
0795         if(((TabW[i]-TabW[im1])<ptol) && ((TabU[i]-TabU[im1])<ptol)) { 
0796           TabU[i]=TabU[im1];
0797           if(TabV[i] < TabV[im1]) { 
0798             Standard_Real t=TabV[i]; TabV[i]=TabV[im1]; TabV[im1]=t;
0799             Triok=Standard_False;
0800           }
0801         }
0802       }
0803     }
0804     while(Triok==Standard_False);
0805     
0806     
0807     for(i=0;i<NbStartPoints; i++) { 
0808       u=TabU[i]; v=TabV[i]; w=TabW[i];
0809       if(i==0) {
0810         su=u-1; 
0811       }
0812       if(Abs(u-su)>ptol || Abs(v-sv)>ptol || Abs(w-sw)>ptol) { 
0813         intersectionExacte.Perform(u,v,w,rsnld,u0,u1,v0,v1,winf,wsup);
0814         if(intersectionExacte.IsDone()) { 
0815           if(!intersectionExacte.IsEmpty()) { 
0816             P=intersectionExacte.Point();
0817             w=intersectionExacte.ParameterOnCurve();
0818             intersectionExacte.ParameterOnSurface(u,v);
0819             AppendPoint(curve,w,surface,u,v);
0820           }
0821         }
0822       }
0823       su=TabU[i]; sv=TabV[i]; sw=TabW[i];
0824     }
0825     delete [] TabW;
0826     delete [] TabV;
0827     delete [] TabU;
0828   }
0829 }
0830 //=======================================================================
0831 //function : InternalPerformCurveQuadric
0832 //purpose  : 
0833 //=======================================================================
0834 void IntCurveSurface_Inter::InternalPerformCurveQuadric(const TheCurve&                 curve,
0835                                                         const TheSurface&               surface) { 
0836   IntCurveSurface_TheQuadCurvExactInter QuadCurv(surface,curve);  
0837   if(QuadCurv.IsDone()) { 
0838     Standard_Integer NbRoots = QuadCurv.NbRoots();
0839     Standard_Real u,v,w;
0840     for(Standard_Integer i = 1; i<= NbRoots; i++) { 
0841       w = QuadCurv.Root(i); 
0842       IntCurveSurface_ComputeParamsOnQuadric(surface,TheCurveTool::Value(curve,w),u,v);
0843       AppendPoint(curve,w,surface,u,v); 
0844     }
0845     //-- Intervals non traites .............................................
0846   }
0847 }
0848 
0849 //=======================================================================
0850 //function : InternalPerform
0851 //purpose  : 
0852 //=======================================================================
0853 void IntCurveSurface_Inter::InternalPerform(const TheCurve&       curve,
0854                                             const IntCurveSurface_ThePolygon&  polygon,
0855                                             const TheSurface&     surface,
0856                                             const Standard_Real U1,
0857                                             const Standard_Real V1,
0858                                             const Standard_Real U2,
0859                                             const Standard_Real V2) {
0860   GeomAbs_SurfaceType SurfaceType = TheSurfaceTool::GetType(surface);
0861   if(   (SurfaceType != GeomAbs_Plane) 
0862      && (SurfaceType != GeomAbs_Cylinder)
0863      && (SurfaceType != GeomAbs_Cone) 
0864      && (SurfaceType != GeomAbs_Sphere) ) {
0865     if(SurfaceType != GeomAbs_BSplineSurface) {
0866       Standard_Integer nbsu,nbsv;
0867       nbsu = TheSurfaceTool::NbSamplesU(surface,U1,U2);
0868       nbsv = TheSurfaceTool::NbSamplesV(surface,V1,V2);
0869       if(nbsu>40) nbsu=40;
0870       if(nbsv>40) nbsv=40;
0871       IntCurveSurface_ThePolyhedron polyhedron(surface,nbsu,nbsv,U1,V1,U2,V2);
0872       InternalPerform(curve,polygon,surface,polyhedron,U1,V1,U2,V2); 
0873     }
0874     else {
0875       Handle(Adaptor3d_Surface) aS = TheSurfaceTool::UTrim(surface, U1, U2, 1.e-9);
0876       aS = aS->VTrim(V1, V2, 1.e-9);
0877       Handle(Adaptor3d_TopolTool) aTopTool = new Adaptor3d_TopolTool(aS);
0878       Standard_Real defl = 0.1;
0879       aTopTool->SamplePnts(defl, 10, 10);
0880 
0881       Standard_Integer nbpu = aTopTool->NbSamplesU();
0882       Standard_Integer nbpv = aTopTool->NbSamplesV();
0883       TColStd_Array1OfReal Upars(1, nbpu), Vpars(1, nbpv);
0884       aTopTool->UParameters(Upars);
0885       aTopTool->VParameters(Vpars);
0886 
0887       IntCurveSurface_ThePolyhedron polyhedron(surface,Upars, Vpars);
0888       InternalPerform(curve,polygon,surface,polyhedron,U1,V1,U2,V2); 
0889     }
0890   }
0891   else {
0892     IntCurveSurface_TheQuadCurvExactInter QuadCurv(surface,curve);  
0893     if(QuadCurv.IsDone()) { 
0894       Standard_Integer NbRoots = QuadCurv.NbRoots();
0895       Standard_Real u,v,w;
0896       for(Standard_Integer i = 1; i<= NbRoots; i++) { 
0897         w = QuadCurv.Root(i); 
0898         IntCurveSurface_ComputeParamsOnQuadric(surface,TheCurveTool::Value(curve,w),u,v);
0899         AppendPoint(curve,w,surface,u,v); 
0900       }
0901       //-- Intervalles non traites .............................................
0902     }
0903   } //-- Fin : la Surface  est une quadrique
0904 }
0905 //=======================================================================
0906 //function : PerformConicSurf
0907 //purpose  : 
0908 //=======================================================================
0909 void IntCurveSurface_Inter::PerformConicSurf(const gp_Lin&   Line,
0910                                              const TheCurve&       curve,
0911                                              const TheSurface&     surface,
0912                                              const Standard_Real U1,
0913                                              const Standard_Real V1,
0914                                              const Standard_Real U2,
0915                                              const Standard_Real V2) {
0916   
0917 
0918   GeomAbs_SurfaceType SurfaceType = TheSurfaceTool::GetType(surface);
0919   Standard_Boolean isAnaProcessed = Standard_True;
0920   switch(SurfaceType) { 
0921   case GeomAbs_Plane: 
0922     {
0923       IntAna_IntConicQuad LinPlane(Line,TheSurfaceTool::Plane(surface),TOLERANCE_ANGULAIRE);
0924       AppendIntAna(curve,surface,LinPlane);
0925       break;
0926     }
0927   case GeomAbs_Cylinder:
0928     {
0929       IntAna_IntConicQuad LinCylinder(Line,TheSurfaceTool::Cylinder(surface));
0930       AppendIntAna(curve,surface,LinCylinder);
0931       break;
0932     }
0933   case GeomAbs_Sphere:
0934     {
0935       IntAna_IntConicQuad LinSphere(Line,TheSurfaceTool::Sphere(surface));
0936       AppendIntAna(curve,surface,LinSphere);
0937       break;
0938     }
0939   case GeomAbs_Torus: 
0940     {
0941       IntAna_IntLinTorus intlintorus(Line, TheSurfaceTool::Torus(surface));
0942       if (intlintorus.IsDone()) {
0943         Standard_Integer nbp = intlintorus.NbPoints();
0944         Standard_Real fi, theta, w;
0945         for (Standard_Integer i = 1; i <= nbp; i++) {
0946           const gp_Pnt aDebPnt(intlintorus.Value(i));
0947           (void)aDebPnt;
0948           w = intlintorus.ParamOnLine(i);
0949           intlintorus.ParamOnTorus(i, fi, theta);
0950           AppendPoint(curve, w, surface, fi, theta);
0951         }
0952       }
0953       else
0954         isAnaProcessed = Standard_False;
0955       break;
0956     }
0957   case GeomAbs_Cone:
0958     {
0959       const Standard_Real correction = 1.E+5*Precision::Angular();
0960       gp_Cone cn = TheSurfaceTool::Cone(surface);
0961       if(Abs(cn.SemiAngle()) < M_PI/2.0 - correction) {
0962         IntAna_IntConicQuad LinCone(Line, cn);
0963         AppendIntAna(curve, surface, LinCone);
0964       }
0965       else
0966         isAnaProcessed = Standard_False;
0967       break;
0968     }
0969   default:
0970     isAnaProcessed = Standard_False;
0971   }
0972   if (!isAnaProcessed)
0973   {
0974     Standard_Integer nbsu,nbsv;
0975     nbsu = TheSurfaceTool::NbSamplesU(surface,U1,U2);
0976     nbsv = TheSurfaceTool::NbSamplesV(surface,V1,V2);
0977 
0978     Standard_Boolean U1inf = Precision::IsInfinite(U1);
0979     Standard_Boolean U2inf = Precision::IsInfinite(U2);
0980     Standard_Boolean V1inf = Precision::IsInfinite(V1);
0981     Standard_Boolean V2inf = Precision::IsInfinite(V2);
0982 
0983     Standard_Real U1new=U1, U2new=U2, V1new=V1, V2new=V2;
0984 
0985     Standard_Boolean NoIntersection = Standard_False;
0986 
0987     if(U1inf || U2inf || V1inf || V2inf ) {
0988 
0989       if(SurfaceType == GeomAbs_SurfaceOfExtrusion) {
0990 
0991         EstLimForInfExtr(Line, surface, Standard_False, nbsu,
0992                          U1inf, U2inf, V1inf, V2inf,
0993                          U1new, U2new, V1new, V2new, NoIntersection);
0994 
0995       }
0996       else if (SurfaceType == GeomAbs_SurfaceOfRevolution) {
0997 
0998         EstLimForInfRevl(Line, surface,
0999                          U1inf, U2inf, V1inf, V2inf,
1000                          U1new, U2new, V1new, V2new, NoIntersection);
1001 
1002       }
1003       else if (SurfaceType == GeomAbs_OffsetSurface) {
1004 
1005         EstLimForInfOffs(Line, surface, nbsu,
1006                          U1inf, U2inf, V1inf, V2inf,
1007                          U1new, U2new, V1new, V2new, NoIntersection);
1008       }
1009       else {
1010 
1011         EstLimForInfSurf(U1new, U2new, V1new, V2new);
1012       }
1013 
1014     }
1015 
1016 
1017     if(NoIntersection) return;
1018 
1019 
1020     // modified by NIZHNY-OFV  Mon Aug 20 14:56:47 2001 (60963 begin)
1021     if(nbsu<20) nbsu=20;
1022     if(nbsv<20) nbsv=20;
1023     // modified by NIZHNY-OFV  Mon Aug 20 14:57:06 2001 (60963 end)
1024     IntCurveSurface_ThePolyhedron polyhedron(surface,nbsu,nbsv,U1new,V1new,U2new,V2new);
1025     Intf_Tool                     bndTool;
1026     Bnd_Box                       boxLine;
1027     bndTool.LinBox(Line,polyhedron.Bounding(),boxLine);
1028     for(Standard_Integer nbseg=1; nbseg<= bndTool.NbSegments(); nbseg++) { 
1029       Standard_Real pinf = bndTool.BeginParam(nbseg);
1030       Standard_Real psup = bndTool.EndParam(nbseg);
1031       if((psup - pinf)<1e-10) { pinf-=1e-10; psup+=1e-10; } 
1032       IntCurveSurface_ThePolygon polygon(curve, pinf,psup,2);
1033       InternalPerform(curve,polygon,surface,polyhedron,U1new,V1new,U2new,V2new);
1034     }
1035   }
1036 }
1037 //=======================================================================
1038 //function : PerformConicSurf
1039 //purpose  : 
1040 //=======================================================================
1041 void IntCurveSurface_Inter::PerformConicSurf(const gp_Circ&        Circle,
1042                                              const TheCurve&       curve,
1043                                              const TheSurface&     surface,
1044                                              const Standard_Real U1,
1045                                              const Standard_Real V1,
1046                                              const Standard_Real U2,
1047                                              const Standard_Real V2) { 
1048   
1049   GeomAbs_SurfaceType SurfaceType = TheSurfaceTool::GetType(surface);
1050   switch(SurfaceType) { 
1051   case GeomAbs_Plane: 
1052     {
1053       IntAna_IntConicQuad CircPlane(Circle,TheSurfaceTool::Plane(surface),TOLERANCE_ANGULAIRE,TOLERANCE);
1054       AppendIntAna(curve,surface,CircPlane);
1055       break;
1056     }
1057   case GeomAbs_Cylinder:
1058     {
1059       IntAna_IntConicQuad CircCylinder(Circle,TheSurfaceTool::Cylinder(surface));
1060       AppendIntAna(curve,surface,CircCylinder);
1061       break;
1062     }
1063   case GeomAbs_Cone:
1064     {
1065       IntAna_IntConicQuad CircCone(Circle,TheSurfaceTool::Cone(surface));
1066       AppendIntAna(curve,surface,CircCone);
1067       break;
1068     }   
1069   case GeomAbs_Sphere:
1070     {
1071       IntAna_IntConicQuad CircSphere(Circle,TheSurfaceTool::Sphere(surface));
1072       AppendIntAna(curve,surface,CircSphere);
1073       break;
1074     }
1075   default: 
1076     {
1077       IntCurveSurface_ThePolygon polygon(curve,NBSAMPLESONCIRCLE);
1078       InternalPerform(curve,polygon,surface,U1,V1,U2,V2);
1079     }
1080   }
1081 }
1082 //=======================================================================
1083 //function : PerformConicSurf
1084 //purpose  : 
1085 //=======================================================================
1086 void IntCurveSurface_Inter::PerformConicSurf(const gp_Elips&       Ellipse,
1087                                              const TheCurve&       curve,
1088                                              const TheSurface&     surface,
1089                                              const Standard_Real U1,
1090                                              const Standard_Real V1,
1091                                              const Standard_Real U2,
1092                                              const Standard_Real V2) { 
1093 
1094   GeomAbs_SurfaceType SurfaceType = TheSurfaceTool::GetType(surface);
1095   switch(SurfaceType) { 
1096   case GeomAbs_Plane: 
1097     {
1098       IntAna_IntConicQuad EllipsePlane(Ellipse,TheSurfaceTool::Plane(surface),TOLERANCE_ANGULAIRE,TOLERANCE);
1099       AppendIntAna(curve,surface,EllipsePlane);
1100       break;
1101     }
1102   case GeomAbs_Cylinder:
1103     {
1104       IntAna_IntConicQuad EllipseCylinder(Ellipse,TheSurfaceTool::Cylinder(surface));
1105       AppendIntAna(curve,surface,EllipseCylinder);
1106       break;
1107     }
1108   case GeomAbs_Cone:
1109      {
1110       IntAna_IntConicQuad EllipseCone(Ellipse,TheSurfaceTool::Cone(surface));
1111       AppendIntAna(curve,surface,EllipseCone);
1112       break;
1113     }   
1114   case GeomAbs_Sphere:
1115     {
1116       IntAna_IntConicQuad EllipseSphere(Ellipse,TheSurfaceTool::Sphere(surface));
1117       AppendIntAna(curve,surface,EllipseSphere);
1118       break;
1119     }
1120   default: 
1121     {
1122       IntCurveSurface_ThePolygon polygon(curve,NBSAMPLESONELLIPSE);
1123       InternalPerform(curve,polygon,surface,U1,V1,U2,V2);
1124     }
1125   }
1126 }
1127 //=======================================================================
1128 //function : PerformConicSurf
1129 //purpose  : 
1130 //=======================================================================
1131 void IntCurveSurface_Inter::PerformConicSurf(const gp_Parab&       Parab,
1132                                              const TheCurve&       curve,
1133                                              const TheSurface&     surface,
1134                                              const Standard_Real U1,
1135                                              const Standard_Real V1,
1136                                              const Standard_Real U2,
1137                                              const Standard_Real V2) { 
1138 
1139   GeomAbs_SurfaceType SurfaceType = TheSurfaceTool::GetType(surface);
1140   switch(SurfaceType) { 
1141   case GeomAbs_Plane: 
1142     {
1143       IntAna_IntConicQuad ParabPlane(Parab,TheSurfaceTool::Plane(surface),TOLERANCE_ANGULAIRE);
1144       AppendIntAna(curve,surface,ParabPlane);
1145       break;
1146     }
1147   case GeomAbs_Cylinder:
1148     {
1149       IntAna_IntConicQuad ParabCylinder(Parab,TheSurfaceTool::Cylinder(surface));
1150       AppendIntAna(curve,surface,ParabCylinder);
1151       break;
1152     }
1153   case GeomAbs_Cone:
1154      {
1155       IntAna_IntConicQuad ParabCone(Parab,TheSurfaceTool::Cone(surface));
1156       AppendIntAna(curve,surface,ParabCone);
1157       break;
1158     }   
1159   case GeomAbs_Sphere:
1160     {
1161       IntAna_IntConicQuad ParabSphere(Parab,TheSurfaceTool::Sphere(surface));
1162       AppendIntAna(curve,surface,ParabSphere);
1163       break;
1164     }
1165   default: 
1166     {
1167       Standard_Integer nbsu,nbsv;
1168       nbsu = TheSurfaceTool::NbSamplesU(surface,U1,U2);
1169       nbsv = TheSurfaceTool::NbSamplesV(surface,V1,V2);
1170       if(nbsu>40) nbsu=40;
1171       if(nbsv>40) nbsv=40;
1172       IntCurveSurface_ThePolyhedron polyhedron(surface,nbsu,nbsv,U1,V1,U2,V2);
1173       Intf_Tool                         bndTool;
1174       Bnd_Box                          boxParab;
1175       bndTool.ParabBox(Parab,polyhedron.Bounding(),boxParab);
1176       for(Standard_Integer nbseg=1; nbseg<= bndTool.NbSegments(); nbseg++) { 
1177         IntCurveSurface_ThePolygon polygon(curve,
1178                                            bndTool.BeginParam(nbseg),
1179                                            bndTool.EndParam(nbseg),
1180                                            NBSAMPLESONPARAB);
1181         InternalPerform(curve,polygon,surface,polyhedron,U1,V1,U2,V2);
1182       }
1183     }
1184   }
1185 }
1186 //=======================================================================
1187 //function : PerformConicSurf
1188 //purpose  : 
1189 //=======================================================================
1190 void IntCurveSurface_Inter::PerformConicSurf(const gp_Hypr&        Hypr,
1191                                              const TheCurve&       curve,
1192                                              const TheSurface&     surface,
1193                                              const Standard_Real U1,
1194                                              const Standard_Real V1,
1195                                              const Standard_Real U2,
1196                                              const Standard_Real V2) {
1197  
1198   GeomAbs_SurfaceType SurfaceType = TheSurfaceTool::GetType(surface);
1199   switch(SurfaceType) { 
1200   case GeomAbs_Plane: 
1201     {
1202       IntAna_IntConicQuad HyprPlane(Hypr,TheSurfaceTool::Plane(surface),TOLERANCE_ANGULAIRE);
1203       AppendIntAna(curve,surface,HyprPlane);
1204       break;
1205     }
1206   case GeomAbs_Cylinder:
1207     {
1208       IntAna_IntConicQuad HyprCylinder(Hypr,TheSurfaceTool::Cylinder(surface));
1209       AppendIntAna(curve,surface,HyprCylinder);
1210       break;
1211     }
1212   case GeomAbs_Cone:
1213      {
1214       IntAna_IntConicQuad HyprCone(Hypr,TheSurfaceTool::Cone(surface));
1215       AppendIntAna(curve,surface,HyprCone);
1216       break;
1217     }   
1218   case GeomAbs_Sphere:
1219     {
1220       IntAna_IntConicQuad HyprSphere(Hypr,TheSurfaceTool::Sphere(surface));
1221       AppendIntAna(curve,surface,HyprSphere);
1222       break;
1223     }
1224   default: 
1225     {
1226       Standard_Integer nbsu,nbsv;
1227       nbsu = TheSurfaceTool::NbSamplesU(surface,U1,U2);
1228       nbsv = TheSurfaceTool::NbSamplesV(surface,V1,V2);
1229       if(nbsu>40) nbsu=40;
1230       if(nbsv>40) nbsv=40;
1231       IntCurveSurface_ThePolyhedron polyhedron(surface,nbsu,nbsv,U1,V1,U2,V2);
1232       Intf_Tool                         bndTool;
1233       Bnd_Box                          boxHypr;
1234       bndTool.HyprBox(Hypr,polyhedron.Bounding(),boxHypr);
1235       for(Standard_Integer nbseg=1; nbseg<= bndTool.NbSegments(); nbseg++) { 
1236         IntCurveSurface_ThePolygon polygon(curve,
1237                                            bndTool.BeginParam(nbseg),
1238                                            bndTool.EndParam(nbseg),
1239                                            NBSAMPLESONHYPR);
1240         InternalPerform(curve,polygon,surface,polyhedron,U1,V1,U2,V2);
1241       }
1242     }
1243   }
1244 }
1245 //=======================================================================
1246 //function : AppendIntAna
1247 //purpose  : 
1248 //=======================================================================
1249 void IntCurveSurface_Inter::AppendIntAna(const TheCurve& curve,
1250                                          const TheSurface& surface,
1251                                          const IntAna_IntConicQuad& intana_ConicQuad) {
1252   if(intana_ConicQuad.IsDone()) { 
1253     if(intana_ConicQuad.IsInQuadric()) { 
1254       //-- std::cout<<" Courbe Dans la Quadrique !!! Non Traite !!!"<<std::endl;
1255       myIsParallel = Standard_True;
1256     }
1257     else if(intana_ConicQuad.IsParallel()) { 
1258       //-- std::cout<<" Courbe // a la Quadrique !!! Non Traite !!!"<<std::endl;
1259       myIsParallel = Standard_True;
1260     }
1261     else { 
1262       Standard_Integer nbp = intana_ConicQuad.NbPoints();
1263       Standard_Real u,v,w;
1264       for(Standard_Integer i = 1; i<= nbp; i++) { 
1265         gp_Pnt P(intana_ConicQuad.Point(i));
1266         w = intana_ConicQuad.ParamOnConic(i);
1267         IntCurveSurface_ComputeParamsOnQuadric(surface,P,u,v);
1268         AppendPoint(curve,w,surface,u,v);
1269       }
1270     }
1271   }
1272   else { 
1273     //-- std::cout<<" IntAna Conic Quad Not Done  "<<std::endl;
1274   }
1275 }
1276 //=======================================================================
1277 //function : AppendPoint
1278 //purpose  : 
1279 //=======================================================================
1280 void IntCurveSurface_Inter::AppendPoint(const TheCurve& curve,
1281                                         const Standard_Real lw,
1282                                         const TheSurface& surface,
1283                                         const Standard_Real su,
1284                                         const Standard_Real sv) {
1285  
1286   Standard_Real W0 = TheCurveTool::FirstParameter(curve);
1287   Standard_Real W1 = TheCurveTool::LastParameter(curve);
1288   Standard_Real U0 = TheSurfaceTool::FirstUParameter(surface);
1289   Standard_Real U1 = TheSurfaceTool::LastUParameter(surface);
1290   Standard_Real V0 = TheSurfaceTool::FirstVParameter(surface);
1291   Standard_Real V1 = TheSurfaceTool::LastVParameter(surface);
1292   //-- Test si la courbe est periodique
1293   Standard_Real w = lw, u = su, v = sv;
1294 
1295   GeomAbs_CurveType aCType = TheCurveTool::GetType(curve);
1296 
1297   if(TheCurveTool::IsPeriodic(curve) 
1298      || aCType == GeomAbs_Circle 
1299      || aCType == GeomAbs_Ellipse) {
1300     w = ElCLib::InPeriod(w, W0, W0 + TheCurveTool::Period(curve));
1301   }
1302 
1303   if((W0 - w) >= TOLTANGENCY || (w - W1) >= TOLTANGENCY) return;
1304 
1305   GeomAbs_SurfaceType aSType = TheSurfaceTool::GetType(surface);
1306   if (TheSurfaceTool::IsUPeriodic(surface)
1307       || aSType == GeomAbs_Cylinder
1308       || aSType == GeomAbs_Cone
1309       || aSType == GeomAbs_Sphere) {
1310     u = ElCLib::InPeriod(u, U0, U0 + TheSurfaceTool::UPeriod(surface));
1311   }
1312 
1313   if (TheSurfaceTool::IsVPeriodic(surface)) {
1314     v = ElCLib::InPeriod(v, V0, V0 + TheSurfaceTool::VPeriod(surface));
1315   }
1316 
1317   if((U0 - u) >= TOLTANGENCY || (u - U1) >= TOLTANGENCY) return;
1318   if((V0 - v) >= TOLTANGENCY || (v - V1) >= TOLTANGENCY) return;
1319 
1320   IntCurveSurface_TransitionOnCurve   TransOnCurve;
1321   IntCurveSurface_ComputeTransitions(curve,w,TransOnCurve,
1322                                      surface,u,v);
1323   gp_Pnt P(TheCurveTool::Value(curve,w));
1324   IntCurveSurface_IntersectionPoint IP(P,u,v,w,TransOnCurve);
1325   Append(IP); //-- invoque la methode de IntCurveSurface_Intersection.
1326   
1327 }
1328 
1329 //=======================================================================
1330 //function : AppendSegment
1331 //purpose  : 
1332 //=======================================================================
1333 void IntCurveSurface_Inter::AppendSegment(const TheCurve& ,
1334                                           const Standard_Real ,
1335                                           const Standard_Real ,
1336                                           const TheSurface& ) { 
1337   //std::cout<<" !!! Not Yet Implemented 
1338   //IntCurveSurface_Inter::Append(const IntCurveSurf ...)"<<std::endl;
1339 }
1340 
1341 //=======================================================================
1342 //function : SectionPointToParameters
1343 //purpose  : P o i n t   d   i n t e r f e r e n c e   - - >  
1344 //    U , V       e t   W 
1345 //=======================================================================
1346 void SectionPointToParameters(const Intf_SectionPoint&              Sp,
1347                               const IntCurveSurface_ThePolyhedron&  Polyhedron,
1348                               const IntCurveSurface_ThePolygon&     Polygon,
1349                               Standard_Real& U,
1350                               Standard_Real& V,
1351                               Standard_Real& W) {
1352   
1353   Intf_PIType       typ;
1354   Standard_Integer  Adr1,Adr2;
1355   Standard_Real     Param,u,v;
1356   gp_Pnt P(Sp.Pnt());
1357   
1358   Standard_Integer Pt1,Pt2,Pt3;
1359   Standard_Real u1 = 0.,v1 = 0.,param;
1360   //----------------------------------------------------------------------
1361   //--          Calcul des parametres approches sur la surface          --
1362   //----------------------------------------------------------------------
1363   
1364   Sp.InfoSecond(typ,Adr1,Adr2,Param);
1365   switch(typ) { 
1366   case Intf_VERTEX:   //-- Adr1 est le numero du vertex
1367     {
1368       Polyhedron.Parameters(Adr1,u1,v1);
1369       break;
1370     }
1371   case Intf_EDGE:
1372     {
1373       Polyhedron.Parameters(Adr1,u1,v1);    
1374       Polyhedron.Parameters(Adr2,u,v);
1375       u1+= Param * (u-u1);
1376       v1+= Param * (v-v1);
1377       break;
1378     }
1379   case Intf_FACE:
1380     {
1381       Standard_Real ua,va,ub,vb,uc,vc,ca,cb,cc,cabc;
1382       Polyhedron.Triangle(Adr1,Pt1,Pt2,Pt3);
1383       gp_Pnt PA(Polyhedron.Point(Pt1));
1384       gp_Pnt PB(Polyhedron.Point(Pt2));
1385       gp_Pnt PC(Polyhedron.Point(Pt3));
1386       Polyhedron.Parameters(Pt1,ua,va);
1387       Polyhedron.Parameters(Pt2,ub,vb);
1388       Polyhedron.Parameters(Pt3,uc,vc);
1389       gp_Vec Normale(gp_Vec(PA,PB).Crossed(gp_Vec(PA,PC)));
1390       cc = (gp_Vec(PA,PB).Crossed(gp_Vec(PA,P))).Dot(Normale);
1391       ca = (gp_Vec(PB,PC).Crossed(gp_Vec(PB,P))).Dot(Normale);
1392       cb = (gp_Vec(PC,PA).Crossed(gp_Vec(PC,P))).Dot(Normale);
1393       cabc = ca + cb + cc;
1394       
1395       ca/=cabc;     cb/=cabc;       cc/=cabc;
1396       
1397       u1 = ca * ua + cb * ub + cc * uc;
1398       v1 = ca * va + cb * vb + cc * vc;
1399       break;
1400     }
1401   default: 
1402     {
1403       std::cout<<" Default dans SectionPointToParameters "<<std::endl;
1404       break;
1405     }
1406   }
1407   //----------------------------------------------------------------------
1408   //--                Calcul du point approche sur la Curve             --
1409   //----------------------------------------------------------------------
1410   Standard_Integer SegIndex;
1411 
1412   Sp.InfoFirst(typ,SegIndex,param);
1413   W = Polygon.ApproxParamOnCurve(SegIndex,param);
1414   if(param>1.0 || param<0.0) { 
1415     //-- IntCurveSurface_ThePolyhedronTool::Dump(Polyhedron);
1416     //-- IntCurveSurface_ThePolygonTool::Dump(Polygon);
1417     }
1418   U = u1;
1419   V = v1;
1420 }
1421 //=======================================================================
1422 //function : IntCurveSurface_ComputeTransitions
1423 //purpose  : 
1424 //=======================================================================
1425 void IntCurveSurface_ComputeTransitions(const TheCurve& curve,
1426                                         const Standard_Real w,
1427                                         IntCurveSurface_TransitionOnCurve&   TransOnCurve,
1428                                         const TheSurface& surface,
1429                                         const Standard_Real u,
1430                                         const Standard_Real v) { 
1431   
1432   gp_Vec NSurf,D1U,D1V;//TgCurv;
1433   gp_Pnt Psurf;
1434   Standard_Real CosDir;
1435   
1436   
1437   TheSurfaceTool::D1(surface,u,v,Psurf,D1U,D1V);
1438   NSurf = D1U.Crossed(D1V);
1439   TheCurveTool::D1(curve,w,Psurf,D1U);
1440   Standard_Real Norm = NSurf.Magnitude();
1441   if(Norm>TOLERANCE_ANGULAIRE &&
1442      D1U.SquareMagnitude() > TOLERANCE_ANGULAIRE) { 
1443     D1U.Normalize();
1444     CosDir = NSurf.Dot(D1U);
1445     CosDir/=Norm;
1446     if( -CosDir > TOLERANCE_ANGULAIRE) { 
1447       //--  --Curve--->    <----Surface----
1448       TransOnCurve   = IntCurveSurface_In;
1449     }
1450     else if(CosDir > TOLERANCE_ANGULAIRE) { 
1451       //--  --Curve--->  ----Surface-->
1452       TransOnCurve   = IntCurveSurface_Out;
1453     }     
1454     else { 
1455       TransOnCurve   = IntCurveSurface_Tangent;
1456     }
1457   }
1458   else { 
1459     TransOnCurve   = IntCurveSurface_Tangent;
1460   }
1461 }
1462 //=======================================================================
1463 //function : IntCurveSurface_ComputeParamsOnQuadric
1464 //purpose  : 
1465 //=======================================================================
1466 void IntCurveSurface_ComputeParamsOnQuadric(const TheSurface& surface,
1467                                             const gp_Pnt& P,
1468                                             Standard_Real& u,
1469                                             Standard_Real& v) { 
1470   GeomAbs_SurfaceType SurfaceType = TheSurfaceTool::GetType(surface);
1471   switch(SurfaceType) { 
1472   case GeomAbs_Plane: 
1473     {
1474       ElSLib::Parameters(TheSurfaceTool::Plane(surface),P,u,v);
1475         break;
1476       }
1477   case GeomAbs_Cylinder:
1478     {
1479       ElSLib::Parameters(TheSurfaceTool::Cylinder(surface),P,u,v);
1480         break;
1481       }
1482   case GeomAbs_Cone:
1483     {
1484       ElSLib::Parameters(TheSurfaceTool::Cone(surface),P,u,v);
1485         break;
1486       }   
1487   case GeomAbs_Sphere:
1488     {
1489       ElSLib::Parameters(TheSurfaceTool::Sphere(surface),P,u,v);
1490         break;
1491       }
1492   default:
1493     break;
1494   }
1495 }
1496 //=======================================================================
1497 //function : EstLimForInfExtr
1498 //purpose  : Estimation of limits for infinite surfaces
1499 //=======================================================================
1500 void EstLimForInfExtr(const gp_Lin&   Line,
1501                       const TheSurface& surface, 
1502                       const Standard_Boolean IsOffSurf,
1503                       const Standard_Integer nbsu, 
1504                       const Standard_Boolean U1inf, 
1505                       const Standard_Boolean U2inf, 
1506                       const Standard_Boolean V1inf, 
1507                       const Standard_Boolean V2inf, 
1508                       Standard_Real& U1new, 
1509                       Standard_Real& U2new, 
1510                       Standard_Real& V1new, 
1511                       Standard_Real& V2new, 
1512                       Standard_Boolean& NoIntersection)
1513 
1514 {
1515 
1516   NoIntersection = Standard_False;
1517 
1518   Handle(Adaptor3d_Surface) aBasSurf; 
1519 
1520   if(IsOffSurf) aBasSurf = TheSurfaceTool::BasisSurface(surface);
1521 
1522   gp_Dir aDirOfExt;
1523 
1524   if(IsOffSurf) aDirOfExt = aBasSurf->Direction();
1525   else aDirOfExt = TheSurfaceTool::Direction(surface);
1526 
1527   Standard_Real tolang = TOLERANCE_ANGULAIRE;
1528 
1529   if(aDirOfExt.IsParallel(Line.Direction(), tolang)) {
1530     NoIntersection = Standard_True;
1531     return;
1532   }
1533 
1534   if((V1inf || V2inf) && !(U1inf || U2inf)) {
1535 
1536     Standard_Real vmin = RealLast(), vmax = -vmin;
1537     gp_Lin aL;
1538     Standard_Real step = (U2new - U1new) / nbsu;
1539     Standard_Real u = U1new, v;
1540     gp_Pnt aP;
1541     Extrema_POnCurv aP1, aP2;
1542     Standard_Integer i;
1543 
1544     for(i = 0; i <= nbsu; i++) {
1545 
1546       TheSurfaceTool::D0(surface, u, 0., aP);
1547       aL.SetLocation(aP);
1548       aL.SetDirection(aDirOfExt);
1549 
1550       Extrema_ExtElC aExtr(aL, Line, tolang);
1551       
1552       if(!aExtr.IsDone()) return;
1553 
1554       if(aExtr.IsParallel()) {
1555         NoIntersection = Standard_True;
1556         return;
1557       }
1558 
1559       aExtr.Points(1, aP1, aP2);
1560       v = aP1.Parameter();
1561       vmin = Min(vmin, v);
1562       vmax = Max(vmax, v);
1563 
1564       u += step;
1565 
1566     }
1567 
1568     vmin = vmin - Abs(vmin) - 10.;
1569     vmax = vmax + Abs(vmax) + 10.;
1570 
1571     V1new = Max(V1new, vmin);
1572     V2new = Min(V2new, vmax);
1573 
1574   }
1575   else if(U1inf || U2inf) {
1576 
1577     Standard_Real umin = RealLast(), umax = -umin;
1578     Standard_Real u0 = Min(Max(0., U1new), U2new);
1579     Standard_Real v0 = Min(Max(0., V1new), V2new);
1580     gp_Pnt aP;
1581     TheSurfaceTool::D0(surface, u0, v0, aP);
1582     gp_Pln aRefPln(aP, aDirOfExt);
1583 
1584     Handle(Adaptor3d_Curve) aBasCurv;
1585 
1586     if(IsOffSurf) aBasCurv = aBasSurf->BasisCurve();
1587     else aBasCurv = TheSurfaceTool::BasisCurve(surface);
1588 
1589     ProjLib_Plane Projector(aRefPln);
1590 
1591     Projector.Project(Line);
1592 
1593     if(!Projector.IsDone()) return;
1594 
1595     gp_Lin2d Line2d = Projector.Line();
1596 
1597     GeomAbs_CurveType aCurvTyp = aBasCurv->GetType();
1598 
1599     if(aCurvTyp == GeomAbs_Line) {
1600       
1601       Projector.Project(aBasCurv->Line());
1602 
1603       if(!Projector.IsDone()) return;
1604 
1605       gp_Lin2d aL2d = Projector.Line();
1606 
1607       IntAna2d_AnaIntersection anInter(Line2d, aL2d);
1608 
1609       if(!anInter.IsDone()) return;
1610 
1611       if(anInter.IsEmpty() || anInter.IdenticalElements() || 
1612                               anInter.ParallelElements()     ) {
1613         NoIntersection = Standard_True;
1614         return;
1615       }
1616 
1617       const IntAna2d_IntPoint& anIntPnt = anInter.Point(1);
1618       umin = umax = anIntPnt.ParamOnSecond();
1619     }
1620     else if(aCurvTyp == GeomAbs_Parabola || aCurvTyp == GeomAbs_Hyperbola) {
1621 
1622       IntAna2d_Conic aCon(Line2d);
1623       IntAna2d_AnaIntersection anInter;
1624       
1625       if(aCurvTyp == GeomAbs_Parabola) {
1626         Projector.Project(aBasCurv->Parabola());
1627         if(!Projector.IsDone()) return;
1628 
1629         const gp_Parab2d& aP2d = Projector.Parabola();
1630 
1631         anInter.Perform(aP2d, aCon);
1632       }
1633       else {
1634         Projector.Project(aBasCurv->Hyperbola());
1635         if(!Projector.IsDone()) return;
1636 
1637         const gp_Hypr2d& aH2d = Projector.Hyperbola();
1638         anInter.Perform(aH2d, aCon);
1639       }
1640 
1641       if(!anInter.IsDone()) return;
1642 
1643       if(anInter.IsEmpty()) {
1644         NoIntersection = Standard_True;
1645         return;
1646       }
1647 
1648       Standard_Integer i, nbint = anInter.NbPoints();
1649       for(i = 1; i <= nbint; i++) {
1650 
1651         const IntAna2d_IntPoint& anIntPnt = anInter.Point(i);
1652 
1653         umin = Min(anIntPnt.ParamOnFirst(), umin);
1654         umax = Max(anIntPnt.ParamOnFirst(), umax);
1655  
1656       }
1657 
1658     }
1659     else {
1660       return;
1661     }
1662       
1663     umin = umin - Abs(umin) - 10;
1664     umax = umax + Abs(umax) + 10;
1665 
1666     U1new = Max(U1new, umin);
1667     U2new = Min(U2new, umax);
1668     
1669     if(V1inf || V2inf) {
1670       EstLimForInfExtr(Line, surface, IsOffSurf, nbsu, 
1671                        Standard_False, Standard_False, V1inf, V2inf,
1672                        U1new, U2new, V1new, V2new, NoIntersection);
1673     }
1674   }
1675     
1676   return;
1677   
1678 }
1679 //=======================================================================
1680 //function : ProjectIntersectAndEstLim
1681 //purpose  : project <theLine> and it's X-axe symmetric line to <thePln> and
1682 //           intersect resulting curve with <theBasCurvProj>.
1683 //           Then estimate max and min parameters of intersection on
1684 //           <theBasCurvProj>.
1685 //           Is called from EstLimForInfRevl()
1686 //=======================================================================
1687 void ProjectIntersectAndEstLim(const gp_Lin&        theLine,
1688                                const gp_Pln&        thePln,
1689                                const ProjLib_Plane& theBasCurvProj,
1690                                Standard_Real&       theVmin,
1691                                Standard_Real&       theVmax,
1692                                Standard_Boolean&    theNoIntersection)
1693 {
1694   ProjLib_Plane aLineProj( thePln, theLine );
1695   if (!aLineProj.IsDone()) {
1696 #ifdef OCCT_DEBUG
1697   std::cout
1698   << "Info: IntCurveSurface_Inter::ProjectIntersectAndEstLim(), !aLineProj.IsDone()"
1699   << std::endl;
1700 #endif
1701     return;
1702   }
1703   gp_Lin2d aLin2d = aLineProj.Line();
1704 
1705   // make a second line X-axe symmetric to the first one 
1706   gp_Pnt2d aP1 = aLin2d.Location();
1707   gp_Pnt2d aP2 (aP1.XY() + aLin2d.Direction().XY());
1708   gp_Pnt2d aP1sym (aP1.X(), -aP1.Y());
1709   gp_Pnt2d aP2sym (aP2.X(), -aP2.Y());
1710   gp_Lin2d aLin2dsym (aP1sym, gp_Vec2d(aP1sym,aP2sym));
1711   
1712   // intersect projections
1713   IntAna2d_Conic aCon    (aLin2d);
1714   IntAna2d_Conic aConSym (aLin2dsym);
1715   IntAna2d_AnaIntersection anIntersect;
1716   IntAna2d_AnaIntersection anIntersectSym;
1717   
1718   switch (theBasCurvProj.GetType()) {
1719   case GeomAbs_Line:
1720     anIntersectSym.Perform(theBasCurvProj.Line(), aConSym); 
1721     anIntersect.Perform(theBasCurvProj.Line(), aCon); break;
1722   case GeomAbs_Hyperbola:                         
1723     anIntersectSym.Perform(theBasCurvProj.Hyperbola(), aConSym); 
1724     anIntersect.Perform(theBasCurvProj.Hyperbola(), aCon); break;
1725   case GeomAbs_Parabola:                          
1726     anIntersectSym.Perform(theBasCurvProj.Parabola(), aConSym); 
1727     anIntersect.Perform(theBasCurvProj.Parabola(), aCon); break;
1728   default:
1729     return; // not infinite curve
1730   }
1731 
1732   // retrieve params of intersections
1733   Standard_Integer aNbIntPnt = anIntersect.IsDone() ? anIntersect.NbPoints() : 0;
1734   Standard_Integer aNbIntPntSym = anIntersectSym.IsDone() ? anIntersectSym.NbPoints() : 0;
1735   Standard_Integer iPnt, aNbPnt = Max (aNbIntPnt, aNbIntPntSym);
1736   
1737   if (aNbPnt == 0) {
1738     theNoIntersection = Standard_True;
1739     return;
1740   }
1741   Standard_Real aParam;
1742   for (iPnt = 1; iPnt <= aNbPnt; iPnt++)
1743   {
1744     if (iPnt <= aNbIntPnt) {
1745       const IntAna2d_IntPoint& aIntPnt = anIntersect.Point(iPnt);
1746       aParam = aIntPnt.ParamOnFirst();
1747       theVmin = Min (theVmin, aParam );
1748       theVmax = Max (theVmax, aParam );
1749     }
1750     if (iPnt <= aNbIntPntSym) {
1751       const IntAna2d_IntPoint& aIntPnt = anIntersectSym.Point(iPnt);
1752       aParam = aIntPnt.ParamOnFirst();
1753       theVmin = Min (theVmin, aParam );
1754       theVmax = Max (theVmax, aParam );
1755     }
1756   }
1757 
1758   return;
1759 }
1760 //=======================================================================
1761 //function : EstLimForInfRevl
1762 //purpose  : Estimate V1 and V2 to pass to InternalPerform() if they are
1763 //           infinite for Surface of Revolution
1764 //           Algo: intersect projections of Line and basis curve on the
1765 //           plane passing through revolution axe
1766 //=======================================================================
1767 void EstLimForInfRevl(const gp_Lin&   Line,
1768                       const TheSurface& surface, 
1769                       const Standard_Boolean U1inf, 
1770                       const Standard_Boolean U2inf, 
1771                       const Standard_Boolean V1inf, 
1772                       const Standard_Boolean V2inf, 
1773                       Standard_Real& U1new, 
1774                       Standard_Real& U2new, 
1775                       Standard_Real& V1new, 
1776                       Standard_Real& V2new, 
1777                       Standard_Boolean& NoIntersection)
1778 {
1779 
1780   NoIntersection = Standard_False;
1781 
1782   if (U1inf || U2inf) {
1783     if (U1inf)
1784       U1new = Max (0., U1new);
1785     else
1786       U2new = Min (2 * M_PI, U2new);
1787     if (! V1inf && !V2inf) return;
1788   }
1789 
1790   Handle(Adaptor3d_Curve) aBasisCurve = TheSurfaceTool::BasisCurve(surface);
1791   gp_Ax1 aRevAx = TheSurfaceTool::AxeOfRevolution(surface);
1792   gp_Vec aXVec = aRevAx.Direction();
1793   Standard_Real aTolAng = Precision::Angular();
1794 
1795   // make plane to project a basis curve
1796   gp_Pnt O = aRevAx.Location();
1797   Standard_Real aU = 0.;
1798   gp_Pnt P = aBasisCurve->Value(aU);
1799   while (O.SquareDistance(P) <= Precision::PConfusion() ||
1800          aXVec.IsParallel( gp_Vec(O,P), aTolAng)) {
1801     aU += 1.;
1802     P = aBasisCurve->Value(aU);
1803     if (aU > 3)
1804       // basis curve is a line coinciding with aXVec, P is any not on aXVec
1805       P = gp_Pnt(aU, aU+1, aU+2);
1806   }
1807   gp_Vec aNVec = aXVec ^ gp_Vec(O,P);
1808   gp_Pln aPln (gp_Ax3 (O, aNVec ,aXVec));
1809 
1810   // project basic curve
1811   ProjLib_Plane aBasCurvProj(aPln);
1812   switch (aBasisCurve->GetType()) {
1813   case GeomAbs_Line:
1814     aBasCurvProj.Project(aBasisCurve->Line     ()); break;
1815   case GeomAbs_Hyperbola:                       
1816     aBasCurvProj.Project(aBasisCurve->Hyperbola()); break;
1817   case GeomAbs_Parabola:                        
1818     aBasCurvProj.Project(aBasisCurve->Parabola ()); break;
1819   default:
1820     return; // not infinite curve
1821   }
1822   if (!aBasCurvProj.IsDone()) {
1823 #ifdef OCCT_DEBUG
1824     std::cout << "Info: IntCurveSurface_Inter::EstLimForInfRevl(), !aBasCurvProj.IsDone()" << std::endl;
1825 #endif
1826     return;
1827   }
1828   // make plane to project Line
1829   if (aXVec.IsParallel( Line.Direction(), aTolAng)) {
1830     P = Line.Location();
1831     while (O.SquareDistance(P) <= Precision::PConfusion()) {
1832       aU += 1.;
1833       P = gp_Pnt(aU, aU+1, aU+2); // any not on aXVec
1834     }
1835     aNVec = aXVec ^ gp_Vec(O,P);
1836   } else
1837     aNVec = aXVec.Crossed( Line.Direction() );
1838   
1839   aPln  = gp_Pln (gp_Ax3 (O, aNVec ,aXVec));
1840 
1841   // make a second plane perpendicular to the first one, rotated around aXVec
1842   gp_Pln aPlnPrp = aPln.Rotated (gp_Ax1 (O,aXVec), M_PI/2.);
1843   
1844   // project Line and it's X-axe symmetric one to plane and intersect
1845   // resulting curve with projection of Basic Curev
1846   Standard_Real aVmin = RealLast(), aVmax = -aVmin;
1847   Standard_Boolean aNoInt1 = Standard_False, aNoInt2 = Standard_False;
1848   ProjectIntersectAndEstLim (Line, aPln,    aBasCurvProj, aVmin, aVmax, aNoInt1);
1849   ProjectIntersectAndEstLim (Line, aPlnPrp, aBasCurvProj, aVmin, aVmax, aNoInt2);
1850 
1851   if (aNoInt1 && aNoInt2) {
1852     NoIntersection = Standard_True;
1853     return;
1854   }
1855   
1856   aVmin = aVmin - Abs(aVmin) - 10;
1857   aVmax = aVmax + Abs(aVmax) + 10;
1858 
1859   if (V1inf) V1new = aVmin;
1860   if (V2inf) V2new = aVmax;
1861 
1862   //std::cout << "EstLimForInfRevl: Vmin " << V1new << " Vmax " << V2new << std::endl;
1863   
1864   return;
1865 }
1866 
1867 //=======================================================================
1868 //function : EstLimForInfOffs
1869 //purpose  : 
1870 //=======================================================================
1871 void EstLimForInfOffs(const gp_Lin&   Line,
1872                       const TheSurface& surface, 
1873                       const Standard_Integer nbsu, 
1874                       const Standard_Boolean U1inf, 
1875                       const Standard_Boolean U2inf, 
1876                       const Standard_Boolean V1inf, 
1877                       const Standard_Boolean V2inf, 
1878                       Standard_Real& U1new, 
1879                       Standard_Real& U2new, 
1880                       Standard_Real& V1new, 
1881                       Standard_Real& V2new, 
1882                       Standard_Boolean& NoIntersection)
1883 {
1884 
1885   NoIntersection = Standard_False;
1886 
1887   const Handle(Adaptor3d_Surface)& aBasSurf = TheSurfaceTool::BasisSurface(surface);
1888   Standard_Real anOffVal = TheSurfaceTool::OffsetValue(surface);
1889 
1890   GeomAbs_SurfaceType aTypeOfBasSurf = aBasSurf->GetType();
1891 
1892   //  case for plane, cylinder and cone - make equivalent surface;
1893   if(aTypeOfBasSurf == GeomAbs_Plane) {
1894 
1895     gp_Pln aPln = aBasSurf->Plane();
1896     gp_Vec aT = aPln.Position().XDirection()^aPln.Position().YDirection();
1897     aT *= anOffVal;
1898     aPln.Translate(aT);
1899     IntAna_IntConicQuad LinPlane(Line,aPln,TOLERANCE_ANGULAIRE);
1900 
1901     if(!LinPlane.IsDone()) return;
1902 
1903     if(LinPlane.IsParallel() || LinPlane.IsInQuadric()) {
1904 
1905       NoIntersection = Standard_True;
1906       return;
1907 
1908     }
1909     
1910     Standard_Real u, v;
1911     ElSLib::Parameters(aPln, LinPlane.Point(1), u, v);
1912     U1new = Max(U1new, u - 10.);
1913     U2new = Min(U2new, u + 10.);
1914     V1new = Max(V1new, v - 10.);
1915     V2new = Min(V2new, v + 10.);
1916 
1917   }
1918   else if(aTypeOfBasSurf == GeomAbs_Cylinder) {
1919 
1920     gp_Cylinder aCyl = aBasSurf->Cylinder();
1921 
1922     Standard_Real aR = aCyl.Radius();
1923     gp_Ax3 anA = aCyl.Position();
1924 
1925     if (anA.Direct()) 
1926       aR += anOffVal;
1927     else 
1928       aR -= anOffVal;
1929 
1930     if ( aR >= TOLTANGENCY ) {
1931       aCyl.SetRadius(aR);
1932     }
1933     else if ( aR <= -TOLTANGENCY ){
1934       anA.Rotate(gp_Ax1(anA.Location(), anA.Direction()), M_PI);
1935       aCyl.SetPosition(anA);
1936 // modified by NIZHNY-MKK  Mon Oct  3 17:37:54 2005
1937 //       aCyl.SetRadius(Abs(aR));
1938       aCyl.SetRadius(-aR);
1939     }
1940     else {
1941 
1942       NoIntersection = Standard_True;
1943       return;
1944       
1945     }
1946 
1947     IntAna_IntConicQuad LinCylinder(Line, aCyl);
1948 
1949     if(!LinCylinder.IsDone()) return;
1950 
1951     if(LinCylinder.IsParallel() || LinCylinder.IsInQuadric()) {
1952 
1953       NoIntersection = Standard_True;
1954       return;
1955 
1956     }
1957     
1958     Standard_Integer i, nbp = LinCylinder.NbPoints();
1959     Standard_Real vmin = RealLast(), vmax = -vmin, u, v;
1960 
1961     for(i = 1; i <= nbp; i++) {
1962 
1963       ElSLib::Parameters(aCyl, LinCylinder.Point(i), u, v);
1964       vmin = Min(vmin, v);
1965       vmax = Max(vmax, v);
1966 
1967     } 
1968 
1969     V1new = Max(V1new, vmin - Abs(vmin) - 10.);
1970     V2new = Min(V2new, vmax + Abs(vmax) + 10.);
1971 
1972   }
1973   else if(aTypeOfBasSurf == GeomAbs_Cone) {
1974 
1975     gp_Cone aCon = aBasSurf->Cone();
1976     Standard_Real anAng = aCon.SemiAngle();
1977     Standard_Real aR = aCon.RefRadius() + anOffVal * Cos(anAng);
1978     gp_Ax3 anA = aCon.Position();
1979     if ( aR >= 0.) {
1980 
1981       gp_Vec aZ( anA.Direction());
1982       aZ *= - anOffVal * Sin(anAng);
1983       anA.Translate(aZ);
1984       aCon.SetPosition(anA);
1985       aCon.SetRadius(aR);
1986       aCon.SetSemiAngle(anAng);
1987 
1988     }
1989     else {
1990 
1991       return;
1992 
1993     }
1994 
1995     IntAna_IntConicQuad LinCone(Line, aCon);
1996 
1997     if(!LinCone.IsDone()) return;
1998 
1999     if(LinCone.IsParallel() || LinCone.IsInQuadric()) {
2000 
2001       NoIntersection = Standard_True;
2002       return;
2003 
2004     }
2005     
2006     Standard_Integer i, nbp = LinCone.NbPoints();
2007     Standard_Real vmin = RealLast(), vmax = -vmin, u, v;
2008 
2009     for(i = 1; i <= nbp; i++) {
2010 
2011       ElSLib::Parameters(aCon, LinCone.Point(i), u, v);
2012       vmin = Min(vmin, v);
2013       vmax = Max(vmax, v);
2014 
2015     } 
2016 
2017     V1new = Max(V1new, vmin - Abs(vmin) - 10.);
2018     V2new = Min(V2new, vmax + Abs(vmax) + 10.);
2019 
2020   }
2021   else if(aTypeOfBasSurf == GeomAbs_SurfaceOfExtrusion) {
2022 
2023     Standard_Real anU1 = U1new, anU2 = U2new;
2024 
2025     EstLimForInfExtr(Line, surface, Standard_True, nbsu, 
2026                      U1inf, U2inf, V1inf, V2inf, 
2027                      U1new, U2new, V1new, V2new, NoIntersection);
2028 
2029     if(NoIntersection) return;
2030 
2031     if(U1inf || U2inf) {
2032 
2033       GeomAbs_CurveType aBasCurvType = aBasSurf->BasisCurve()->GetType();
2034       if(aBasCurvType == GeomAbs_Line) {
2035         U1new = Max(anU1, -1.e10);
2036         U2new = Min(anU2,  1.e10);
2037       } 
2038       else if(aBasCurvType == GeomAbs_Parabola) {
2039         gp_Parab aPrb  = aBasSurf->BasisCurve()->Parabola();
2040         Standard_Real aF = aPrb.Focal();
2041         Standard_Real dU = 2.e5 * Sqrt(aF);
2042         U1new = Max(anU1, -dU);
2043         U2new = Min(anU2,  dU);
2044       }
2045       else if(aBasCurvType == GeomAbs_Hyperbola) {
2046         U1new = Max(anU1, -30.);
2047         U2new = Min(anU2,  30.);
2048       }
2049       else {
2050         U1new = Max(anU1, -1.e10);
2051         U2new = Min(anU2,  1.e10);
2052       } 
2053 
2054     }
2055 
2056   }
2057   else if(aTypeOfBasSurf == GeomAbs_SurfaceOfRevolution) {
2058 
2059     GeomAbs_CurveType aBasCurvType = aBasSurf->BasisCurve()->GetType();
2060     if(aBasCurvType == GeomAbs_Line) {
2061       V1new = Max(V1new, -1.e10);
2062       V2new = Min(V2new,  1.e10);
2063     }   
2064     else if(aBasCurvType == GeomAbs_Parabola) {
2065       gp_Parab aPrb  = aBasSurf->BasisCurve()->Parabola();
2066       Standard_Real aF = aPrb.Focal();
2067       Standard_Real dV = 2.e5 * Sqrt(aF);
2068       V1new = Max(V1new, -dV);
2069       V2new = Min(V2new,  dV);
2070     }
2071     else if(aBasCurvType == GeomAbs_Hyperbola) {
2072      V1new  = Max(V1new, -30.);
2073      V2new  = Min(V2new,  30.);
2074     }
2075     else {
2076      V1new  = Max(V1new, -1.e10);
2077      V2new  = Min(V2new,  1.e10);
2078     }   
2079 
2080   }
2081   else {
2082 
2083     V1new = Max(V1new, -1.e10);
2084     V2new = Min(V2new,  1.e10);
2085   }
2086 }
2087 //=======================================================================
2088 //function : EstLimForInfSurf
2089 //purpose  : 
2090 //=======================================================================
2091 void EstLimForInfSurf(Standard_Real& U1new, 
2092                       Standard_Real& U2new, 
2093                       Standard_Real& V1new, 
2094                       Standard_Real& V2new)
2095 {
2096     U1new = Max(U1new, -1.e10);
2097     U2new = Min(U2new,  1.e10);
2098     V1new = Max(V1new, -1.e10);
2099     V2new = Min(V2new,  1.e10);
2100 }