0024005: Intersecting a slightly off angle plane with a cylinder takes 7+ seconds
authornbv <nbv@opencascade.com>
Thu, 19 Sep 2013 12:46:17 +0000 (16:46 +0400)
committerbugmaster <bugmaster@opencascade.com>
Fri, 20 Sep 2013 08:09:50 +0000 (12:09 +0400)
Checking of possibility of bad result.
Adding test case for issue CR24005
Correction of test case for issue CR24005

src/ChFi3d/ChFi3d_Builder_0.cxx
src/Draft/Draft_Modification_1.cxx
src/IntAna/IntAna_QuadQuadGeo.cxx
src/IntPatch/IntPatch_GLine.cxx
src/IntPatch/IntPatch_ImpImpIntersection_2.gxx
src/IntPatch/IntPatch_Intersection.cdl
src/IntPatch/IntPatch_Intersection.cxx
src/IntTools/IntTools_FaceFace.cdl
src/IntTools/IntTools_FaceFace.cxx
src/QABugs/QABugs_19.cxx
tests/bugs/modalg_5/bug24005 [new file with mode: 0755]

index 211cbc8..d303c66 100755 (executable)
@@ -3068,7 +3068,17 @@ Standard_Boolean ChFi3d_ComputeCurves(Handle(Adaptor3d_HSurface)&   S1,
       cyl = S1->Cylinder();
     }
     IntAna_QuadQuadGeo ImpKK(pl,cyl,Precision::Angular(),tol3d);
-    if (ImpKK.IsDone()) {
+    Standard_Boolean isIntDone = ImpKK.IsDone();
+
+    if(ImpKK.TypeInter() == IntAna_Ellipse)
+    {
+      const gp_Elips anEl = ImpKK.Ellipse(1);
+      const Standard_Real aMajorR = anEl.MajorRadius();
+      const Standard_Real aMinorR = anEl.MinorRadius();
+      isIntDone = (aMajorR < 100000.0 * aMinorR);
+    }
+
+    if (isIntDone) {
       Standard_Boolean c1line = 0;
       switch  (ImpKK.TypeInter()) {
       case IntAna_Line:
index a7800c5..d33a730 100755 (executable)
@@ -1627,10 +1627,21 @@ Handle(Geom_Surface) Draft_Modification::NewSurface
 #endif
       return NewS;
     }
-    if (Abs(Angle) > Precision::Angular()) {
+    if (Abs(Angle) > Precision::Angular())
+    {
       IntAna_QuadQuadGeo i2s;
       i2s.Perform(NeutralPlane,Cy,Precision::Angular(),Precision::Confusion());
-      if (!i2s.IsDone() || i2s.TypeInter() != IntAna_Circle) {
+      Standard_Boolean isIntDone = i2s.IsDone();
+
+      if(i2s.TypeInter() == IntAna_Ellipse)
+      {
+        const gp_Elips anEl = i2s.Ellipse(1);
+        const Standard_Real aMajorR = anEl.MajorRadius();
+        const Standard_Real aMinorR = anEl.MinorRadius();
+        isIntDone = (aMajorR < 100000.0 * aMinorR);
+      }
+
+      if (!isIntDone || i2s.TypeInter() != IntAna_Circle) {
 #ifdef DEB
     cout << "NewSurfaceCyl:Draft_Intersection_Neutral_Cylinder_NotDone" << endl;
 #endif
index e803a1c..5a9e4b3 100755 (executable)
@@ -534,13 +534,7 @@ gp_Ax2 DirToAx2(const gp_Pnt& P,const gp_Dir& D)
       param1bis = radius;
     }
   }
-  if(typeres == IntAna_Ellipse) { 
-    if(   param1>100000.0*param1bis 
-       || param1bis>100000.0*param1) { 
-      done = Standard_False;
-      return;
-    }
-  }
+
   done = Standard_True;
 }
 //=======================================================================
index a88bbed..ef84e89 100755 (executable)
@@ -550,185 +550,289 @@ void IntPatch_GLine::ComputeVertexParameters(const Standard_Real /*Tol*/)
 
     SortAgain = Standard_False;
     SortIsOK = Standard_True; 
-    for(i=2; i<=nbvtx && SortIsOK; i++) { 
+    for(i=2; i<=nbvtx && SortIsOK; i++)
+    { 
       IntPatch_Point& VTX   = svtx.ChangeValue(i);      
-      for(j=1; j<=nbvtx && SortIsOK; j++) {
-       if(i!=j) { 
-         IntPatch_Point& VTXM1 = svtx.ChangeValue(j);
-         Standard_Boolean kill   = Standard_False;
-         Standard_Boolean killm1 = Standard_False;
-         if(Abs(VTXM1.ParameterOnLine()-VTX.ParameterOnLine())<PrecisionPConfusion) { 
-           if(VTXM1.IsOnDomS1() && VTX.IsOnDomS1()) {  //-- OnS1    OnS1
-             if(VTXM1.ArcOnS1() == VTX.ArcOnS1()) {    //-- OnS1 == OnS1
-               if(VTXM1.IsOnDomS2()) {                 //-- OnS1 == OnS1  OnS2  
-                 if(VTX.IsOnDomS2()==Standard_False) {   //-- OnS1 == OnS1  OnS2 PasOnS2
-                   kill=Standard_True;   
-                 }
-                 else {
-                   if(VTXM1.ArcOnS2() == VTX.ArcOnS2()) { //-- OnS1 == OnS1  OnS2 == OnS2
-                     if(VTXM1.IsVertexOnS2()) {                      
-                       kill=Standard_True;
-                     }
-                     else { 
-                       killm1=Standard_True;
-                     }
-                   }
-                 }
-               }
-               else {                                  //-- OnS1 == OnS1  PasOnS2  
-                 if(VTX.IsOnDomS2()) {                 //-- OnS1 == OnS1  PasOnS2  OnS2
-                   killm1=Standard_True;
-                 }
-               }
-             }
-           }
-           else { //-- Pas OnS1  et  OnS1
-             if(VTXM1.IsOnDomS2()==Standard_False && VTX.IsOnDomS2()==Standard_False) { 
-               if(VTXM1.IsOnDomS1() && VTX.IsOnDomS1()==Standard_False) { 
-                 kill=Standard_True;
-               }
-               else  if(VTX.IsOnDomS1() && VTXM1.IsOnDomS1()==Standard_False) { 
-                 killm1=Standard_True;
-               }
-             }
-           }
-           
-           if(!(kill || killm1)) {
-             if(VTXM1.IsOnDomS2() && VTX.IsOnDomS2()) {  //-- OnS2    OnS2
-               if(VTXM1.ArcOnS2() == VTX.ArcOnS2()) {    //-- OnS2 == OnS2
-                 if(VTXM1.IsOnDomS1()) {                 //-- OnS2 == OnS2  OnS1  
-                   if(VTX.IsOnDomS1()==Standard_False) {   //-- OnS2 == OnS2  OnS1 PasOnS1
-                     kill=Standard_True;   
-                   }
-                   else {
-                     if(VTXM1.ArcOnS1() == VTX.ArcOnS1()) { //-- OnS2 == OnS2  OnS1 == OnS1
-                       if(VTXM1.IsVertexOnS1()) {                    
-                         kill=Standard_True;                //-- OnS2 == OnS2  OnS1 == OnS1  Vtx PasVtx
-                       }
-                       else { 
-                         killm1=Standard_True;              //-- OnS2 == OnS2  OnS1 == OnS1  PasVtx Vtx
-                       } 
-                     }
-                   }
-                 }
-                 else {                                  //-- OnS2 == OnS2  PasOnS1  
-                   if(VTX.IsOnDomS1()) {                 //-- OnS2 == OnS2  PasOnS1  OnS1
-                     killm1=Standard_True;
-                   }
-                 }
-               }
-             }
-             else { //-- Pas OnS2  et  OnS2
-               if(VTXM1.IsOnDomS1()==Standard_False && VTX.IsOnDomS1()==Standard_False) { 
-                 if(VTXM1.IsOnDomS2() && VTX.IsOnDomS2()==Standard_False) { 
-                   kill=Standard_True;
-                 }
-                 else  if(VTX.IsOnDomS2() && VTXM1.IsOnDomS2()==Standard_False) { 
-                   killm1=Standard_True;
-                 }
-               }
-             }
-           }
-           //-- On a j < i 
-           if(kill) { 
-             SortIsOK = Standard_False;
-             if(lapt) { if(indl>i) indl--; else if(indl==i) indl=j; } 
-             if(fipt) { if(indf>i) indf--; else if(indf==i) indf=j; } 
-             svtx.Remove(i);
-             nbvtx--;
-           }
-           else if(killm1) { 
-             SortIsOK = Standard_False;
-             if(lapt) { if(indl>j) indl--;  else if(indl==j) indl=i-1;} 
-             if(fipt) { if(indf>j) indf--;  else if(indf==j) indf=i-1;} 
-             svtx.Remove(j);
-             nbvtx--; 
-           }
-//         else
-           else if(ArcType()==IntPatch_Circle || ArcType()==IntPatch_Ellipse) { // eap
-             //-- deux points de meme parametre qui ne peuvent etre confondus
-             //-- On change les parametres d un des points si les points UV sont
-             //-- differents. Ceci distingue le cas des aretes de couture.
-             // ==========================================================
-             //-- 2 points with the same parameters
-             //-- Change parametres of one point if points UV are
-             //-- different. This is the case of seam edge
-             Standard_Real ponline = VTX.ParameterOnLine();
-             // eap, =>>
-             Standard_Real newParam = ponline;
-             const Standard_Real PiPi = M_PI+M_PI;
-             Standard_Boolean is2PI = ( Abs(ponline-PiPi) <= PrecisionPConfusion );
-
-             if (nbvtx > 2 && // do this check if seam edge only gives vertices 
-                 !is2PI)      // but always change 2PI -> 0
-               continue;
-             
-             if (is2PI)
-               newParam = 0;
-             else if (Abs(ponline) <= PrecisionPConfusion)
-               newParam = PiPi;
-             else 
-               newParam -= PiPi;
-//           if(  (Abs(ponline)<=PrecisionPConfusion)
-//                ||(Abs(ponline-M_PI-M_PI) <=PrecisionPConfusion)) 
-             // eap, <<=
-               Standard_Real u1a,v1a,u2a,v2a,u1b,v1b,u2b,v2b; 
-               VTXM1.Parameters(u1a,v1a,u2a,v2a);
-               VTX.Parameters(u1b,v1b,u2b,v2b);
-               Standard_Integer flag  = 0;
-               
-               if(   (Abs(u1a-u1b)<=PrecisionPConfusion) ) flag|=1;
-               if(   (Abs(v1a-v1b)<=PrecisionPConfusion) ) flag|=2;
-               if(   (Abs(u2a-u2b)<=PrecisionPConfusion) ) flag|=4;
-               if(   (Abs(v2a-v2b)<=PrecisionPConfusion) ) flag|=8;
-               Standard_Boolean TestOn1 = Standard_False;
-               Standard_Boolean TestOn2 = Standard_False;
-               switch(flag) { 
-               case 3:   //-- meme point U1 V1  
-               case 7:  //-- meme point U1 V1   meme U2            
-               case 12:  //--                    meme U2 V2
-               case 13:  //-- meme point U1      meme U2 V2
-               case 10:  //-- meme point    V1   meme    V2   Test si U1a=U1b Mod 2PI et Test si U2a=U2b Mod 2PI
-                 break;
-               case 11:   //-- meme point U1 V1   meme    V2   Test si U2a=U2b Mod 2PI   
-                 { TestOn2 = Standard_True; break; } 
-               case 14:  //-- meme point    V1   meme U2 V2   Test si U1a=U1b Mod 2PI
-                 { TestOn1 = Standard_True; break; } 
-               default: break;
-               };
-               // eap
-               //if(ArcType()==IntPatch_Circle || ArcType()==IntPatch_Ellipse) {}
-                 if(TestOn1) { 
-                   //// modified by jgv, 2.11.01 for BUC61033 ////
-                   Standard_Real U1A = (u1a < u1b)? u1a : u1b;
-                   Standard_Real U1B = (u1a < u1b)? u1b : u1a;
-                   if (u1min == RealLast())
-                     {
-                       u1min = U1A;
-                       u1max = U1B;
-                     }
-                   else
-                     {
-                       if (Abs(U1A-u1min) > PrecisionPConfusion)
-                         ToBreak = Standard_True;
-                       if (Abs(U1B-u1max) > PrecisionPConfusion)
-                         ToBreak = Standard_True;
-                     }
+      for(j=1; j<=nbvtx && SortIsOK; j++)
+      {
+        if(i!=j)
+        {
+          IntPatch_Point& VTXM1 = svtx.ChangeValue(j);
+          Standard_Boolean kill   = Standard_False;
+          Standard_Boolean killm1 = Standard_False;
+          if(Abs(VTXM1.ParameterOnLine()-VTX.ParameterOnLine())<PrecisionPConfusion)
+          {
+            if(VTXM1.IsOnDomS1() && VTX.IsOnDomS1()) //-- OnS1    OnS1
+            {
+              if(VTXM1.ArcOnS1() == VTX.ArcOnS1())//-- OnS1 == OnS1
+              {
+                if(VTXM1.IsOnDomS2())             //-- OnS1 == OnS1  OnS2  
+                {
+                  if(VTX.IsOnDomS2()==Standard_False)//-- OnS1 == OnS1  OnS2 PasOnS2
+                  {
+                    kill=Standard_True;
+                  }
+                  else
+                  {
+                    if(VTXM1.ArcOnS2() == VTX.ArcOnS2()) //-- OnS1 == OnS1  OnS2 == OnS2
+                    {
+                      if(VTXM1.IsVertexOnS2())
+                      {
+                        kill=Standard_True;
+                      }
+                      else
+                      {
+                        killm1=Standard_True;
+                      }
+                    }
+                  }
+                }
+                else                    //-- OnS1 == OnS1  PasOnS2  
+                {
+                  if(VTX.IsOnDomS2())   //-- OnS1 == OnS1  PasOnS2  OnS2
+                  {
+                    killm1=Standard_True;
+                  }
+                }
+              }
+            }
+            else                        //-- Pas OnS1  et  OnS1
+            {
+              if(VTXM1.IsOnDomS2()==Standard_False && VTX.IsOnDomS2()==Standard_False)
+              {
+                if(VTXM1.IsOnDomS1() && VTX.IsOnDomS1()==Standard_False)
+                {
+                  kill=Standard_True;
+                }
+                else if(VTX.IsOnDomS1() && VTXM1.IsOnDomS1()==Standard_False)
+                {
+                  killm1=Standard_True;
+                }
+              }
+            }
+
+            if(!(kill || killm1))
+            {
+              if(VTXM1.IsOnDomS2() && VTX.IsOnDomS2())  //-- OnS2    OnS2
+              {
+                if(VTXM1.ArcOnS2() == VTX.ArcOnS2())    //-- OnS2 == OnS2
+                {
+                  if(VTXM1.IsOnDomS1())                 //-- OnS2 == OnS2  OnS1 
+                  {
+                    if(VTX.IsOnDomS1()==Standard_False) //-- OnS2 == OnS2  OnS1 PasOnS1
+                    {
+                      kill=Standard_True;
+                    }
+                    else
+                    {
+                      if(VTXM1.ArcOnS1() == VTX.ArcOnS1()) //-- OnS2 == OnS2  OnS1 == OnS1
+                      {
+                        if(VTXM1.IsVertexOnS1())
+                        {
+                          kill=Standard_True;              //-- OnS2 == OnS2  OnS1 == OnS1  Vtx PasVtx
+                        }
+                        else
+                        {
+                          killm1=Standard_True;            //-- OnS2 == OnS2  OnS1 == OnS1  PasVtx Vtx
+                        }
+                      }
+                    }
+                  }
+                  else
+                  {                           //-- OnS2 == OnS2  PasOnS1
+                    if(VTX.IsOnDomS1())       //-- OnS2 == OnS2  PasOnS1  OnS1
+                    {
+                      killm1=Standard_True;
+                    }
+                  }
+                }
+              }
+              else //-- Pas OnS2  et  OnS2
+              {
+                if(VTXM1.IsOnDomS1()==Standard_False && VTX.IsOnDomS1()==Standard_False)
+                {
+                  if(VTXM1.IsOnDomS2() && VTX.IsOnDomS2()==Standard_False)
+                  {
+                    kill=Standard_True;
+                  }
+                  else if(VTX.IsOnDomS2() && VTXM1.IsOnDomS2()==Standard_False)
+                  {
+                    killm1=Standard_True;
+                  }
+                }
+              }
+            }
+
+            //-- On a j < i
+            if(kill)
+            {
+              SortIsOK = Standard_False;
+              if(lapt)
+              {
+                if(indl>i)
+                  indl--;
+                else if(indl==i)
+                  indl=j;
+              }
+
+              if(fipt)
+              {
+                if(indf>i)
+                  indf--;
+                else if(indf==i)
+                  indf=j;
+              }
+
+              svtx.Remove(i);
+              nbvtx--;
+            }
+            else if(killm1)
+            {
+              SortIsOK = Standard_False;
+              if(lapt)
+              {
+                if(indl>j)
+                  indl--;
+                else if(indl==j)
+                  indl=i-1;
+              } 
+
+              if(fipt)
+              {
+                if(indf>j)
+                  indf--;
+                else if(indf==j)
+                  indf=i-1;
+              }
+
+              svtx.Remove(j);
+              nbvtx--;
+            }//            else
+            else if(ArcType()==IntPatch_Circle || ArcType()==IntPatch_Ellipse) // eap
+            {
+              //-- deux points de meme parametre qui ne peuvent etre confondus
+              //-- On change les parametres d un des points si les points UV sont
+              //-- differents. Ceci distingue le cas des aretes de couture.
+              // ==========================================================
+              //-- 2 points with the same parameters
+              //-- Change parametres of one point if points UV are
+              //-- different. This is the case of seam edge
+
+              Standard_Real ponline = VTX.ParameterOnLine();
+              // eap, =>>
+              Standard_Real newParam = ponline;
+              const Standard_Real PiPi = M_PI+M_PI;
+              Standard_Boolean is2PI = ( Abs(ponline-PiPi) <= PrecisionPConfusion );
+
+              if (nbvtx > 2 && // do this check if seam edge only gives vertices 
+                  !is2PI)      // but always change 2PI -> 0
+                        continue;
+
+              if (is2PI)
+                newParam = 0;
+              else if (Abs(ponline) <= PrecisionPConfusion)
+                newParam = PiPi;
+              else
+                newParam -= PiPi;
+
+              //             if(  (Abs(ponline)<=PrecisionPConfusion)
+              //                  ||(Abs(ponline-M_PI-M_PI) <=PrecisionPConfusion))
+              // eap, <<=
+
+              Standard_Real u1a,v1a,u2a,v2a,u1b,v1b,u2b,v2b;
+              VTXM1.Parameters(u1a,v1a,u2a,v2a);
+              VTX.Parameters(u1b,v1b,u2b,v2b);
+              Standard_Integer flag  = 0;
+
+              if(   (Abs(u1a-u1b)<=PrecisionPConfusion) )
+                flag|=1;
+
+              if(   (Abs(v1a-v1b)<=PrecisionPConfusion) )
+                flag|=2;
+              if(   (Abs(u2a-u2b)<=PrecisionPConfusion) )
+                flag|=4;
+
+              if(   (Abs(v2a-v2b)<=PrecisionPConfusion) )
+                flag|=8;
+
+              Standard_Boolean TestOn1 = Standard_False;
+              Standard_Boolean TestOn2 = Standard_False;
+
+              switch(flag)
+              { 
+              case 3:   //-- meme point U1 V1  
+              case 7:  //-- meme point U1 V1   meme U2
+              case 12:  //--                    meme U2 V2
+              case 13:  //-- meme point U1      meme U2 V2
+              case 10:  //-- meme point    V1   meme    V2   Test si U1a=U1b Mod 2PI et Test si U2a=U2b Mod 2PI
+                break;
+              case 11:   //-- meme point U1 V1   meme    V2   Test si U2a=U2b Mod 2PI
+                {
+                  TestOn2 = Standard_True;
+                  break;
+                }
+
+              case 14:  //-- meme point    V1   meme U2 V2   Test si U1a=U1b Mod 2PI
+                {
+                  TestOn1 = Standard_True;
+                  break;
+                }
+              default:
+                break;
+              };
+
+              // eap
+              //if(ArcType()==IntPatch_Circle || ArcType()==IntPatch_Ellipse) {}
+              if(TestOn1)
+              {
+                //// modified by jgv, 2.11.01 for BUC61033 ////
+                Standard_Real U1A = (u1a < u1b)? u1a : u1b;
+                Standard_Real U1B = (u1a < u1b)? u1b : u1a;
+                
+                if (u1min == RealLast())
+                {
+                  u1min = U1A;
+                  u1max = U1B;
+                }
+                else
+                {
+                  if (Abs(U1A-u1min) > PrecisionPConfusion)
+                    ToBreak = Standard_True;
+                  if (Abs(U1B-u1max) > PrecisionPConfusion)
+                    ToBreak = Standard_True;
+                }
                    ///////////////////////////////////////////////
                    // eap, =>>
 //                   if (Abs(ponline) <= PrecisionPConfusion) { 
 //                   const Standard_Real PiPi = M_PI+M_PI;
-                     if(newParam >= ParamMinOnLine && newParam <= ParamMaxOnLine
-                        /*PiPi >= ParamMinOnLine && PiPi<=ParamMaxOnLine*/) { 
-                       SortAgain = Standard_True;
-                       SortIsOK = Standard_False;
-                       if (newParam > ponline)
-                         if(u1a < u1b) { VTX.SetParameter(newParam); } 
-                         else          { VTXM1.SetParameter(newParam); }
-                       else
-                         if(u1a > u1b) { VTX.SetParameter(newParam); } 
-                         else          { VTXM1.SetParameter(newParam); } 
-                     }
+                if(newParam >= ParamMinOnLine && newParam <= ParamMaxOnLine
+                  /*PiPi >= ParamMinOnLine && PiPi<=ParamMaxOnLine*/)
+                {
+                  SortAgain = Standard_True;
+                  SortIsOK = Standard_False;
+                  if (newParam > ponline)
+                  {
+                    if(u1a < u1b)
+                    {
+                      VTX.SetParameter(newParam);
+                    } 
+                    else
+                    {
+                      VTXM1.SetParameter(newParam);
+                    }
+                  }
+                  else
+                  {
+                    if(u1a > u1b)
+                    {
+                      VTX.SetParameter(newParam);
+                    }
+                    else
+                    {
+                      VTXM1.SetParameter(newParam);
+                    } 
+                  }
+                }
 //                 }
 //                 else { 
 //                   if(0.0 >= ParamMinOnLine && 0.0<=ParamMaxOnLine) { 
@@ -739,38 +843,59 @@ void IntPatch_GLine::ComputeVertexParameters(const Standard_Real /*Tol*/)
 //                   }
 //                 }
                    // eap, <<=
-                 }
-                 if(TestOn2) { 
-                   //// modified by jgv, 2.11.01 for BUC61033 ////
-                   Standard_Real U2A = (u2a < u2b)? u2a : u2b;
-                   Standard_Real U2B = (u2a < u2b)? u2b : u2a;
-                   if (u2min == RealLast())
-                     {
-                       u2min = U2A;
-                       u2max = U2B;
-                     }
-                   else
-                     {
-                       if (Abs(U2A-u2min) > PrecisionPConfusion)
-                         ToBreak = Standard_True;
-                       if (Abs(U2B-u2max) > PrecisionPConfusion)
-                         ToBreak = Standard_True;
-                     }
+              }
+
+              if(TestOn2)
+              {
+                //// modified by jgv, 2.11.01 for BUC61033 ////
+                Standard_Real U2A = (u2a < u2b)? u2a : u2b;
+                Standard_Real U2B = (u2a < u2b)? u2b : u2a;
+                if (u2min == RealLast())
+                {
+                  u2min = U2A;
+                  u2max = U2B;
+                }
+                else
+                {
+                  if (Abs(U2A-u2min) > PrecisionPConfusion)
+                    ToBreak = Standard_True;
+                  
+                  if (Abs(U2B-u2max) > PrecisionPConfusion)
+                    ToBreak = Standard_True;
+
+                }
                    ///////////////////////////////////////////////
                    // eap, =>>
 //                 if (Abs(ponline) <= PrecisionPConfusion) { 
 //                   const Standard_Real PiPi = M_PI+M_PI;
-                     if(newParam >= ParamMinOnLine && newParam <= ParamMaxOnLine
-                        /*PiPi >= ParamMinOnLine && PiPi<=ParamMaxOnLine*/) {
-                       SortAgain = Standard_True;
-                       SortIsOK = Standard_False;
-                       if (newParam > ponline)
-                         if(u2a < u2b) { VTX.SetParameter(newParam); } 
-                         else          { VTXM1.SetParameter(newParam); }
-                       else
-                         if(u2a > u2b) { VTX.SetParameter(newParam); } 
-                         else          { VTXM1.SetParameter(newParam); } 
-                     }
+                if(newParam >= ParamMinOnLine && newParam <= ParamMaxOnLine
+                  /*PiPi >= ParamMinOnLine && PiPi<=ParamMaxOnLine*/)
+                {
+                  SortAgain = Standard_True;
+                  SortIsOK = Standard_False;
+                  if (newParam > ponline)
+                  {
+                    if(u2a < u2b)
+                    {
+                      VTX.SetParameter(newParam);
+                    }
+                    else
+                    {
+                      VTXM1.SetParameter(newParam);
+                    }
+                  }
+                  else
+                  {
+                    if(u2a > u2b)
+                    {
+                      VTX.SetParameter(newParam);
+                    }
+                    else
+                    {
+                      VTXM1.SetParameter(newParam);
+                    }
+                  }
+                }
 //                 }
 //                 else { 
 //                   if(0.0 >= ParamMinOnLine && 0.0<=ParamMaxOnLine) {
@@ -783,10 +908,10 @@ void IntPatch_GLine::ComputeVertexParameters(const Standard_Real /*Tol*/)
 //               }
 //             }
              // eap, <<=
-             }
-           }
-         }
-       }
+              }
+            }
+          }
+        }
       } //-- if(i!=j)
     }
   }
@@ -809,6 +934,7 @@ void IntPatch_GLine::ComputeVertexParameters(const Standard_Real /*Tol*/)
       }
     }
     while(!SortIsOK);
+
     indl=nbvtx;
     indf=1;
   }
index 3984ca5..ca48848 100755 (executable)
@@ -76,7 +76,7 @@ void IntPatch_ImpImpIntersection::Perform(const Handle(Adaptor3d_HSurface)&  S1,
   IntSurf_Quadric quad1;
   IntSurf_Quadric quad2;
   IntPatch_ArcFunction AFunc;
-  Standard_Real Tolang = 1.e-8;
+  const Standard_Real Tolang = 1.e-8;
   GeomAbs_SurfaceType typs1 = S1->GetType();
   GeomAbs_SurfaceType typs2 = S2->GetType();
   //
index f03835e..2afc0b0 100755 (executable)
 
 class Intersection from IntPatch
 
-       ---Purpose: This class provides a generic algorithm to intersect
+  ---Purpose: This class provides a generic algorithm to intersect
        --          2 surfaces.
 
 uses
-     HVertex        from Adaptor3d,
-     HCurve2d       from Adaptor2d,
-     HSurface       from Adaptor3d,
-     Point          from IntPatch,
+     HVertex         from Adaptor3d,
+     HCurve2d        from Adaptor2d,
+     HSurface        from Adaptor3d,
+     Point           from IntPatch,
      SequenceOfPoint from IntPatch,
-     TopolTool      from Adaptor3d,
-     SequenceOfLine from IntPatch,
-     Line           from IntPatch,
-     --amv
-     ListOfPntOn2S  from IntSurf
+     TopolTool       from Adaptor3d,
+     SequenceOfLine  from IntPatch,
+     Line            from IntPatch,
+     SurfaceType     from GeomAbs,
+     ListOfPntOn2S   from IntSurf
  
 raises NotDone           from StdFail,
        OutOfRange        from Standard,
@@ -52,147 +52,160 @@ is
             S2: HSurface from Adaptor3d; D2: TopolTool from Adaptor3d;
             TolArc,TolTang: Real from Standard)
            
-       returns Intersection from IntPatch
-       
-       raises ConstructionError from Standard;
+      returns Intersection from IntPatch
+           raises ConstructionError from Standard;
 
     Create (S1: HSurface from Adaptor3d; D1: TopolTool from Adaptor3d;
             TolArc,TolTang: Real from Standard)
            
-       returns Intersection from IntPatch
-       
-       raises ConstructionError from Standard;
+      returns Intersection from IntPatch
+      raises ConstructionError from Standard;
 
 
     SetTolerances(me       : in out;
                   TolArc   : Real from Standard;
-                 TolTang  : Real from Standard;
-                 UVMaxStep: Real from Standard;
-                 Fleche   : Real from Standard)
+                  TolTang  : Real from Standard;
+                  UVMaxStep: Real from Standard;
+                  Fleche   : Real from Standard)
                  
-       ---Purpose: Set the tolerances used by the algorithms:
-       --          --- Implicit   - Parametric  
-       --          --- Parametric - Parametric 
-       --          --- Implicit   - Implicit 
-       --         
-       --          TolArc   is  used  to   compute  the intersections
-       --          between the restrictions   of  a  surface   and  a
-       --          walking line.
-       --          
-       --          TolTang is used to compute the points on a walking
-       --          line, and in geometric algorithms.
-       --          
-       --          Fleche  is  a  parameter   used in    the  walking
-       --          algorithms to provide small curvatures on a line.
-       --          
-       --          UVMaxStep is  a  parameter   used in  the  walking
-       --          algorithms  to    compute the  distance between to
-       --          points in their respective parametrtic spaces.
-       --          
-        is static;
-
-    Perform (me: in out;
-             S1: HSurface from Adaptor3d; D1: TopolTool from Adaptor3d;
-             S2: HSurface from Adaptor3d; D2: TopolTool from Adaptor3d;
-             TolArc,TolTang: Real from Standard)            
+      ---Purpose: Set the tolerances used by the algorithms:
+      --          --- Implicit   - Parametric  
+      --          --- Parametric - Parametric 
+      --          --- Implicit   - Implicit 
+      --         
+      --          TolArc   is  used  to   compute  the intersections
+      --          between the restrictions   of  a  surface   and  a
+      --          walking line.
+      --          
+      --          TolTang is used to compute the points on a walking
+      --          line, and in geometric algorithms.
+      --          
+      --          Fleche  is  a  parameter   used in    the  walking
+      --          algorithms to provide small curvatures on a line.
+      --          
+      --          UVMaxStep is  a  parameter   used in  the  walking
+      --          algorithms  to    compute the  distance between to
+      --          points in their respective parametrtic spaces.
+      --
+      
+      is static;
 
-       raises ConstructionError from Standard    
-
-        is static;
-    
-    --amv
     Perform (me: in out;
              S1: HSurface from Adaptor3d; D1: TopolTool from Adaptor3d;
              S2: HSurface from Adaptor3d; D2: TopolTool from Adaptor3d;
              TolArc,TolTang: Real from Standard;
-            LOfPnts: in out ListOfPntOn2S from IntSurf;
-            RestrictLine: Boolean from Standard = Standard_True)
-
-       raises ConstructionError from Standard    
-
-       is static;
-
-    Perform (me: in out;
-             S1: HSurface from Adaptor3d; D1: TopolTool from Adaptor3d;
-             S2: HSurface from Adaptor3d; D2: TopolTool from Adaptor3d;
-            U1,V1,U2,V2 : Real from Standard;
-             TolArc,TolTang: Real from Standard)
+             isGeomInt : Boolean from Standard = Standard_True)             
 
-       raises ConstructionError from Standard    
-
-       is static;
+      raises ConstructionError from Standard    
+      is static;
+    
+      --amv
+    Perform ( me: in out;
+              S1: HSurface from Adaptor3d; D1: TopolTool from Adaptor3d;
+              S2: HSurface from Adaptor3d; D2: TopolTool from Adaptor3d;
+              TolArc,TolTang: Real from Standard;
+              LOfPnts: in out ListOfPntOn2S from IntSurf;
+              RestrictLine: Boolean from Standard = Standard_True;
+              isGeomInt : Boolean from Standard = Standard_True)
+              
+      ---Purpose: If isGeomInt == Standard_False, then method 
+      --          Param-Param intersection will be used.
+      
+      raises ConstructionError from Standard
+      is static;
+
+    Perform ( me: in out;
+              S1: HSurface from Adaptor3d; D1: TopolTool from Adaptor3d;
+              S2: HSurface from Adaptor3d; D2: TopolTool from Adaptor3d;
+              U1,V1,U2,V2 : Real from Standard;
+              TolArc,TolTang: Real from Standard)
+              
+      raises ConstructionError from Standard
+      is static;
 
     Perform (me: in out;
              S1: HSurface from Adaptor3d; D1: TopolTool from Adaptor3d;
              TolArc,TolTang: Real from Standard)
-
-       raises ConstructionError from Standard    
-
-       is static;
-
-
+      
+      raises ConstructionError from Standard
+      is static;
+  
+    ParamParamPerfom( me: in out;
+                      S1: HSurface from Adaptor3d; D1: TopolTool from Adaptor3d;
+                      S2: HSurface from Adaptor3d; D2: TopolTool from Adaptor3d;
+                      TolArc,TolTang: Real from Standard;
+                      LOfPnts: in out ListOfPntOn2S from IntSurf;
+                      RestrictLine: Boolean from Standard;
+                      typs1, typs2: SurfaceType from GeomAbs)
+
+      is private;
+      
+    GeomGeomPerfom( me: in out;
+                    S1: HSurface from Adaptor3d; D1: TopolTool from Adaptor3d;
+                    S2: HSurface from Adaptor3d; D2: TopolTool from Adaptor3d;
+                    TolArc,TolTang: Real from Standard;
+                    LOfPnts: in out ListOfPntOn2S from IntSurf;
+                    RestrictLine: Boolean from Standard;
+                    typs1, typs2: SurfaceType from GeomAbs)
+
+      is private;
+                    
+    GeomParamPerfom(me: in out;
+                    S1: HSurface from Adaptor3d; D1: TopolTool from Adaptor3d;
+                    S2: HSurface from Adaptor3d; D2: TopolTool from Adaptor3d;
+                    isNotAnalitical: Boolean from Standard;
+                    typs1, typs2: SurfaceType from GeomAbs)
+      
+      is private;
+      
     IsDone(me)
     
        ---Purpose: Returns True if the calculus was succesfull.
 
        returns Boolean from Standard
-       ---C++: inline
-       
+      ---C++: inline
+      
        is static;
 
 
     IsEmpty(me)
-    
-       ---Purpose: Returns true if the is no intersection.
-
-       returns Boolean from Standard
-       ---C++: inline
-
-       raises NotDone from StdFail
-
-       is static;
+      ---Purpose: Returns true if the is no intersection.
+      ---C++: inline
+      returns Boolean from Standard
+      raises NotDone from StdFail
+      is static;
 
 
     TangentFaces(me)
-    
-       ---Purpose: Returns True if the two patches are considered as
-       --          entierly tangent, i-e every restriction arc of one
-       --          patch is inside the geometric base of the other patch.
-
-       returns Boolean from Standard
-       ---C++: inline
-       
-       raises NotDone from StdFail
-       
-       is static;
-
-
+      ---Purpose: Returns True if the two patches are considered as
+      --          entierly tangent, i-e every restriction arc of one
+      --          patch is inside the geometric base of the other patch.
+      ---C++: inline
+      
+      returns Boolean from Standard
+      raises NotDone from StdFail
+      is static;
+      
     OppositeFaces(me)
-    
-       ---Purpose: Returns True when the TangentFaces returns True and the
-       --          normal vectors evaluated at a point on the first and the
-       --          second surface are opposite. 
-       --          The exception DomainError is raised if TangentFaces
-       --          returns False.
+      ---Purpose: Returns True when the TangentFaces returns True and the
+      --          normal vectors evaluated at a point on the first and the
+      --          second surface are opposite. 
+      --          The exception DomainError is raised if TangentFaces
+      --          returns False.
+      ---C++: inline
 
        returns Boolean from Standard
-       ---C++: inline
-       
-       raises NotDone     from StdFail,
-               DomainError from Standard
-       
-       is static;
+      raises  NotDone     from StdFail,
+              DomainError from Standard
+      is static;
 
 
     NbPnts(me)
-    
-       ---Purpose: Returns the number of "single" points.
+      ---Purpose: Returns the number of "single" points.
+      ---C++: inline
 
        returns Integer from Standard
-       ---C++: inline
-
        raises NotDone from StdFail
-       
        is static;
 
 
@@ -200,52 +213,46 @@ is
     
        ---Purpose: Returns the point of range Index.
        --          An exception is raised if Index<=0 or Index>NbPnt.
+      ---C++: return const&
+      ---C++: inline
 
        returns Point from IntPatch
-       ---C++: return const&
-       ---C++: inline
-
-       raises NotDone    from StdFail,
-               OutOfRange from Standard
+       raises  NotDone    from StdFail,
+              OutOfRange from Standard
 
        is static;
 
 
     NbLines(me)
-    
-       ---Purpose: Returns the number of intersection lines.
-
-       returns Integer from Standard
-       ---C++: inline
-
-       raises NotDone from StdFail
-
-       is static;
-
-
+      ---Purpose: Returns the number of intersection lines.
+      ---C++: inline
+      
+      returns Integer from Standard
+      raises NotDone from StdFail
+      is static;
+      
     Line(me; Index: Integer from Standard)
-    
-       ---Purpose: Returns the line of range Index.
+      ---Purpose: Returns the line of range Index.
        --          An exception is raised if Index<=0 or Index>NbLine.
+      ---C++: return const&
+      ---C++: inline
 
        returns Line from IntPatch
-       ---C++: return const&
-       ---C++: inline
-
-       raises NotDone    from StdFail,
-               OutOfRange from Standard
+       raises  NotDone    from StdFail,
+              OutOfRange from Standard
+              
+      is static;
+      
+    SequenceOfLine(me)
+      ---C++: return const&
+      
+      returns SequenceOfLine from IntPatch
+      raises NotDone    from StdFail
+      is static;
        
-       is static;
-       
-    SequenceOfLine(me) 
-       returns SequenceOfLine from IntPatch
-       ---C++: return const&
-        raises NotDone    from StdFail
-       is static;
-       
-    Dump(me; Mode: Integer from Standard;
-             S1: HSurface from Adaptor3d; D1: TopolTool from Adaptor3d;
-             S2: HSurface from Adaptor3d; D2: TopolTool from Adaptor3d) 
+    Dump(me; Mode : Integer from Standard;
+             S1   : HSurface from Adaptor3d; D1: TopolTool from Adaptor3d;
+             S2   : HSurface from Adaptor3d; D2: TopolTool from Adaptor3d) 
        ---Purpose: Dump of each result line. 
        ---         Mode for more accurate dumps. 
        --          
index 369d9af..842d53c 100755 (executable)
@@ -32,7 +32,7 @@
 #include <stdio.h>
 
 #define DEBUG 0 
-static Standard_Integer NBPOINTSSURALINE = 200;
+static const Standard_Integer aNbPointsInALine = 200;
 
 //======================================================================
 // function: SequenceOfLine
@@ -708,18 +708,21 @@ static void FUN_TrimBothSurf(const Handle(Adaptor3d_HSurface)& S1,
 //function : Perform
 //purpose  : 
 //=======================================================================
-void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)&  S1,
-                                    const Handle(Adaptor3d_TopolTool)& D1,
-                                    const Handle(Adaptor3d_HSurface)&  S2,
-                                    const Handle(Adaptor3d_TopolTool)& D2,
+void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)&  theS1,
+                                    const Handle(Adaptor3d_TopolTool)& theD1,
+                                    const Handle(Adaptor3d_HSurface)&  theS2,
+                                    const Handle(Adaptor3d_TopolTool)& theD2,
                                     const Standard_Real TolArc,
-                                    const Standard_Real TolTang)
-{  
+                                    const Standard_Real TolTang,
+                                    const Standard_Boolean isGeomInt)
+{
   myTolArc = TolArc;
   myTolTang = TolTang;
-  if(myFleche == 0.0) myFleche = 0.01;
-  if(myUVMaxStep == 0.0) myUVMaxStep = 0.01;
-    
+  if(myFleche <= Precision::PConfusion())
+    myFleche = 0.01;
+  if(myUVMaxStep <= Precision::PConfusion())
+    myUVMaxStep = 0.01;
+
   done = Standard_False;
   spnt.Clear();
   slin.Clear();
@@ -727,92 +730,108 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)&  S1,
   tgte = Standard_False;
   oppo = Standard_False;
 
-  Standard_Integer i;
-
-  GeomAbs_SurfaceType typs1 = S1->GetType();
-  GeomAbs_SurfaceType typs2 = S2->GetType();
+  GeomAbs_SurfaceType typs1 = theS1->GetType();
+  GeomAbs_SurfaceType typs2 = theS2->GetType();
   
   Standard_Boolean TreatAsBiParametric = Standard_False;
-  if(typs1 == GeomAbs_Cone)    {
-    Standard_Real a1 = S1->Cone().SemiAngle();
-    if(a1<0.0) a1=-a1;
-    if(a1<2.e-2 || a1>1.55)    { 
-      if(typs2==GeomAbs_Plane)     {
-       if(a1<2e-2)             { 
-         const gp_Dir axec = S1->Cone().Axis().Direction();
-         const gp_Dir axep = S2->Plane().Axis().Direction();
-         Standard_Real ps=axec.Dot(axep);
-         if(ps<0.0) {
-           ps=-ps;
-         }
-         if(ps<0.015) {
-           TreatAsBiParametric = Standard_True;
-         }
-       }
+  if(typs1 == GeomAbs_Cone)
+  {
+    const gp_Cone Con1 = theS1->Cone();
+    const Standard_Real a1 = Abs(Con1.SemiAngle());
+    if((a1 < 0.02) || (a1 > 1.55))
+    {
+      if(typs2==GeomAbs_Plane)
+      {
+        if(a1 < 0.02)
+        {
+          const gp_Pln Plan2 = theS2->Plane();
+          const gp_Dir axec = Con1.Axis().Direction();
+          const gp_Dir axep = Plan2.Axis().Direction();
+          const Standard_Real ps = Abs(axec.Dot(axep));
+          if(ps < 0.015)
+          {
+            TreatAsBiParametric = Standard_True;
+          }
+        }
       }
-      else TreatAsBiParametric = Standard_True;
+      else
+        TreatAsBiParametric = Standard_True;
     }
   }
-  if(typs2 == GeomAbs_Cone)  {
-    gp_Cone Con2 = S2->Cone();
-    Standard_Real a2 = Con2.SemiAngle();
-    if(a2<0.0) a2=-a2;
-    if(a2<2.e-2 || a2>1.55)    {
-      if(typs1==GeomAbs_Plane)   {
-       if(a2<2e-2)             {
-         const gp_Dir axec = S2->Cone().Axis().Direction();
-         const gp_Dir axep = S1->Plane().Axis().Direction();
-         Standard_Real ps=axec.Dot(axep);
-         if(ps<0.0) {
-           ps=-ps;
-         }
-         if(ps<0.015){
-           TreatAsBiParametric = Standard_True;
-         }
-       }
+
+  if(typs2 == GeomAbs_Cone)
+  {
+    const gp_Cone Con2 = theS2->Cone();
+    const Standard_Real a2 = Abs(Con2.SemiAngle());
+    if((a2 < 0.02) || (a2 > 1.55))
+    {
+      if(typs1 == GeomAbs_Plane)
+      {
+        if(a2 < 0.02)
+        {
+          const gp_Pln Plan1 = theS1->Plane();
+          const gp_Dir axec = Con2.Axis().Direction();
+          const gp_Dir axep = Plan1.Axis().Direction();
+          const Standard_Real ps = Abs(axec.Dot(axep));
+          if(ps<0.015)
+          {
+            TreatAsBiParametric = Standard_True;
+          }
+        }
       }
-      else TreatAsBiParametric = Standard_True;
+      else
+        TreatAsBiParametric = Standard_True;
     }
+
     //// modified by jgv, 15.12.02 for OCC565 ////
-    if (typs1 == GeomAbs_Cone)    {
-      gp_Cone Con1 = S1->Cone();
-      Standard_Real a1 = Con1.SemiAngle();
-      if (a1 < 0.0) a1 = -a1;
-      if (a1 < 2.e-2 && a2 < 2.e-2) {//quasi-cylinders: if same domain, treat as canonic
-       gp_Ax1 A1 = Con1.Axis(), A2 = Con2.Axis();
-       if (A1.IsParallel(A2,Precision::Angular()))    {
-         gp_Lin L1(A1);
-         if (L1.Distance( A2.Location() ) <= Precision::Confusion()){
-           TreatAsBiParametric = Standard_False;
-         }
-       }
+    if (typs1 == GeomAbs_Cone)
+    {
+      const gp_Cone Con1 = theS1->Cone();
+      const Standard_Real a1 = Abs(Con1.SemiAngle());
+      if (a1 < 0.02 && a2 < 0.02) //quasi-cylinders: if same domain, treat as canonic
+      {
+        const gp_Ax1 A1 = Con1.Axis(), A2 = Con2.Axis();
+        if (A1.IsParallel(A2,Precision::Angular()))
+        {
+          const gp_Lin L1(A1);
+          if (L1.Distance(A2.Location()) <= Precision::Confusion())
+          {
+            TreatAsBiParametric = Standard_False;
+          }
+        }
       }
-      else if (a1 > 1.55 && a2 > 1.55) { //quasi-planes: if same domain, treat as canonic
-       gp_Ax1 A1 = Con1.Axis(), A2 = Con2.Axis();
-       if (A1.IsParallel(A2,Precision::Angular()))         {
-         gp_Pnt Apex1 = Con1.Apex(), Apex2 = Con2.Apex();
-         gp_Pln Plan1( Apex1, A1.Direction() );
-         if (Plan1.Distance( Apex2 ) <= Precision::Confusion()){
-           TreatAsBiParametric = Standard_False;
-         }
-       }
+      else if (a1 > 1.55 && a2 > 1.55) //quasi-planes: if same domain, treat as canonic
+      {
+        const gp_Ax1 A1 = Con1.Axis(), A2 = Con2.Axis();
+        if (A1.IsParallel(A2,Precision::Angular()))
+        {
+          const gp_Pnt Apex1 = Con1.Apex(), Apex2 = Con2.Apex();
+          const gp_Pln Plan1( Apex1, A1.Direction() );
+          if (Plan1.Distance( Apex2 ) <= Precision::Confusion())
+          {
+            TreatAsBiParametric = Standard_False;
+          }
+        }
       }
-      else if ((a1 > 1.55 && a2 < 1.55) || (a2 > 1.55 && a1 < 1.55) ) {
-       gp_Ax1 A1 = Con1.Axis(), A2 = Con2.Axis();
-       if (A1.IsCoaxial(A2,Precision::Angular(),Precision::Confusion()))  {
-         TreatAsBiParametric = Standard_False;
-       }
+      else if ((a1 > 1.55) || (a2 > 1.55))
+      {
+        const gp_Ax1 A1 = Con1.Axis(), A2 = Con2.Axis();
+        if (A1.IsCoaxial(A2,Precision::Angular(),Precision::Confusion()))
+        {
+          TreatAsBiParametric = Standard_False;
+        }
       }
     }// if (typs1 == GeomAbs_Cone)    {
   }// if(typs2 == GeomAbs_Cone)  {
-  //
-  if(D1->DomainIsInfinite() || D2->DomainIsInfinite()) {
+
+  if(theD1->DomainIsInfinite() || theD2->DomainIsInfinite()) {
     TreatAsBiParametric= Standard_False;
   }
 
 //  Modified by skv - Mon Sep 26 14:58:30 2005 Begin
 //   if(TreatAsBiParametric) { typs1 = typs2 = GeomAbs_BezierSurface; }
-  if(TreatAsBiParametric) {
+  if(TreatAsBiParametric)
+  {
     if (typs1 == GeomAbs_Cone && typs2 == GeomAbs_Plane)
       typs1 = GeomAbs_BezierSurface; // Using Imp-Prm Intersector
     else if (typs1 == GeomAbs_Plane && typs2 == GeomAbs_Cone)
@@ -835,6 +854,7 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)&  S1,
     case GeomAbs_Cone: ts1 = 1; break;
     default: break;
   }
+
   Standard_Integer ts2 = 0;
   switch (typs2)
   {
@@ -844,6 +864,7 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)&  S1,
     case GeomAbs_Cone: ts2 = 1; break;
     default: break;
   }
+
   // Possible intersection types: 1. ts1 == ts2 == 1 <Geom-Geom>
   //                              2. ts1 != ts2      <Geom-Param>
   //                              3. ts1 == ts2 == 0 <Param-Param>
@@ -851,189 +872,33 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)&  S1,
   // Geom - Geom
   if(ts1 == ts2 && ts1 == 1)
   {
-    IntPatch_ImpImpIntersection interii(S1,D1,S2,D2,myTolArc,myTolTang);
-    if (interii.IsDone())
-       {
-         done = Standard_True;
-         empt = interii.IsEmpty();
-         if (!empt)
-         {
-           tgte = interii.TangentFaces();
-           if (tgte) oppo = interii.OppositeFaces();
-           for (i = 1; i <= interii.NbLines(); i++)
-               {
-                 const Handle_IntPatch_Line& line = interii.Line(i);
-                 if (line->ArcType() == IntPatch_Analytic)
-                 { 
-                   const GeomAbs_SurfaceType typs1 = S1->GetType();
-                   const GeomAbs_SurfaceType typs2 = S2->GetType();
-                   IntSurf_Quadric Quad1,Quad2;
-                   switch(typs1)
-                       {
-                         case GeomAbs_Plane:    Quad1.SetValue(S1->Plane());    break;
-                         case GeomAbs_Cylinder: Quad1.SetValue(S1->Cylinder()); break;
-                         case GeomAbs_Sphere:   Quad1.SetValue(S1->Sphere());   break;
-                         case GeomAbs_Cone:     Quad1.SetValue(S1->Cone());     break;
-                         default: break;
-                       }
-                   switch(typs2)
-                       { 
-                         case GeomAbs_Plane:    Quad2.SetValue(S2->Plane());    break;
-                         case GeomAbs_Cylinder: Quad2.SetValue(S2->Cylinder()); break;
-                         case GeomAbs_Sphere:   Quad2.SetValue(S2->Sphere());   break;
-                         case GeomAbs_Cone:     Quad2.SetValue(S2->Cone());     break;
-                         default: break;
-                       }
-                   IntPatch_ALineToWLine AToW(Quad1,Quad2,0.01,0.05,NBPOINTSSURALINE);
-                   Handle(IntPatch_Line) wlin=AToW.MakeWLine((*((Handle_IntPatch_ALine *)(&line))));
-                   slin.Append(wlin);
-                 }
-                 else slin.Append(interii.Line(i));
-               }
-           for (i = 1; i <= interii.NbPnts(); i++) spnt.Append(interii.Point(i));
-         }
-       }
-    else goto prm;
+    const Standard_Boolean RestrictLine = Standard_True;
+    IntSurf_ListOfPntOn2S ListOfPnts;
+    ListOfPnts.Clear();
+    if(isGeomInt)
+    {
+      GeomGeomPerfom(theS1, theD1, theS2, theD2, TolArc, TolTang, ListOfPnts, RestrictLine, typs1, typs2);
+    }
+    else
+    {
+      ParamParamPerfom(theS1, theD1, theS2, theD2, TolArc, TolTang, ListOfPnts, RestrictLine, typs1, typs2);
+    }
   }
+
   // Geom - Param
   if(ts1 != ts2)
   {
-    //cout << "IP" << endl;
-    IntPatch_ImpPrmIntersection interip;
-    if (myIsStartPnt) {
-         if (ts1 == 0) interip.SetStartPoint(myU1Start,myV1Start);
-         else          interip.SetStartPoint(myU2Start,myV2Start);
-    }
-    if(D1->DomainIsInfinite() && D2->DomainIsInfinite())
-       {
-         Standard_Boolean IsPLInt = Standard_False;
-         TColgp_SequenceOfPnt sop;
-         gp_Vec v;
-         FUN_PL_Intersection(S1,typs1,S2,typs2,IsPLInt,sop,v);
-         if(IsPLInt)
-         {
-           if(sop.Length() > 0)
-               {
-                 for(Standard_Integer ip = 1; ip <= sop.Length(); ip++)
-                 {
-                   gp_Lin lin(sop.Value(ip),gp_Dir(v));
-                   Handle(IntPatch_GLine) gl = new IntPatch_GLine(lin,Standard_False);
-                   slin.Append(*(Handle_IntPatch_Line *)&gl);
-                 }
-                 done = Standard_True;
-               }
-           else done = Standard_False;
-           return;
-         }
-         else
-         {
-           Handle(Adaptor3d_HSurface) nS1 = S1;
-           Handle(Adaptor3d_HSurface) nS2 = S2;
-           FUN_TrimBothSurf(S1,typs1,S2,typs2,1.e+5,nS1,nS2);
-           interip.Perform(nS1,D1,nS2,D2,myTolArc,myTolTang,myFleche,myUVMaxStep);
-         }
-       }
-    else interip.Perform(S1,D1,S2,D2,myTolArc,myTolTang,myFleche,myUVMaxStep);
-//      IntPatch_ImpPrmIntersection interip(S1,D1,S2,D2,myTolArc,myTolTang,myFleche,myUVMaxStep);
-    if (interip.IsDone()) 
-       {
-         done = Standard_True;
-         empt = interip.IsEmpty();
-         if (!empt) 
-         {
-           for(i = 1; i <= interip.NbLines(); i++)
-               {
-                 if(interip.Line(i)->ArcType() != IntPatch_Walking) slin.Append(interip.Line(i));
-               }
-           for(i = 1; i <= interip.NbLines(); i++) 
-               {
-                 if(interip.Line(i)->ArcType() == IntPatch_Walking) slin.Append(interip.Line(i));
-               }
-           for (i = 1; i <= interip.NbPnts(); i++) spnt.Append(interip.Point(i));
-         }
-       }
+    GeomParamPerfom(theS1, theD1, theS2, theD2, ts1 == 0, typs1, typs2);
   }
+
   // Param - Param 
   if(ts1 == ts2 && ts1 == 0)
   {
-      //cout << "PP" << endl;
-prm:; // this algorithm was modified last by OFV [29-Oct-2001] -> [2-Nov-2001]
-    IntPatch_PrmPrmIntersection interpp;
-    if(!D1->DomainIsInfinite() && !D2->DomainIsInfinite())
-       {
-      interpp.Perform(S1,D1,S2,D2,TolArc,TolTang,myFleche,myUVMaxStep);
-         goto met;
-       }
-    else if( (!D1->DomainIsInfinite() && D2->DomainIsInfinite()) || (D1->DomainIsInfinite() && !D2->DomainIsInfinite()) )
-       {
-      gp_Pnt pMaxXYZ, pMinXYZ;
-         if(D1->DomainIsInfinite())
-         {
-           FUN_GetMinMaxXYZPnt( S2, pMinXYZ, pMaxXYZ );
-           const Standard_Real MU = Max(Abs(S2->FirstUParameter()),Abs(S2->LastUParameter()));
-           const Standard_Real MV = Max(Abs(S2->FirstVParameter()),Abs(S2->LastVParameter()));
-           const Standard_Real AP = Max(MU, MV);
-           Handle(Adaptor3d_HSurface) SS;
-           FUN_TrimInfSurf(pMinXYZ, pMaxXYZ, S1, AP, SS);
-           interpp.Perform(SS,D1,S2,D2,TolArc,TolTang,myFleche,myUVMaxStep);
-         }
-         else
-         {
-           FUN_GetMinMaxXYZPnt( S1, pMinXYZ, pMaxXYZ );
-           const Standard_Real MU = Max(Abs(S1->FirstUParameter()),Abs(S1->LastUParameter()));
-           const Standard_Real MV = Max(Abs(S1->FirstVParameter()),Abs(S1->LastVParameter()));
-           const Standard_Real AP = Max(MU, MV);
-           Handle(Adaptor3d_HSurface) SS;
-           FUN_TrimInfSurf(pMinXYZ, pMaxXYZ, S2, AP, SS);
-           interpp.Perform(S1,D1,SS,D2,TolArc,TolTang,myFleche,myUVMaxStep);
-         }
-      goto met;
-       }//(!D1->DomainIsInfinite() && D2->DomainIsInfinite()) || (D1->DomainIsInfinite() && !D2->DomainIsInfinite())
-    else 
-       {
-         if(typs1 == GeomAbs_OtherSurface || typs2 == GeomAbs_OtherSurface){ done = Standard_False;  return; }
-         Standard_Boolean IsPLInt = Standard_False;
-         TColgp_SequenceOfPnt sop;
-         gp_Vec v;
-         FUN_PL_Intersection(S1,typs1,S2,typs2,IsPLInt,sop,v);
-         if(IsPLInt)
-         {
-           if(sop.Length() > 0)
-               {
-                 for(Standard_Integer ip = 1; ip <= sop.Length(); ip++)
-                 {
-                   gp_Lin lin(sop.Value(ip),gp_Dir(v));
-                   Handle(IntPatch_GLine) gl = new IntPatch_GLine(lin,Standard_False);
-                   slin.Append(*(Handle_IntPatch_Line *)&gl);
-                 }
-                 done = Standard_True;
-               }
-           else done = Standard_False;
-           return;
-         } // 'COLLINEAR LINES'
-         else
-         {
-           Handle(Adaptor3d_HSurface) nS1 = S1;
-           Handle(Adaptor3d_HSurface) nS2 = S2;
-           FUN_TrimBothSurf(S1,typs1,S2,typs2,1.e+8,nS1,nS2);
-           interpp.Perform(nS1,D1,nS2,D2,TolArc,TolTang,myFleche,myUVMaxStep);
-           goto met;
-         }// 'NON - COLLINEAR LINES'
-       }// both domains are infinite
-met:if (interpp.IsDone())
-       {
-         done = Standard_True;
-         tgte = Standard_False;
-         empt = interpp.IsEmpty();
-         for(i=1; i <= interpp.NbLines(); i++)
-         {
-           if(interpp.Line(i)->ArcType() != IntPatch_Walking) slin.Append(interpp.Line(i));
-         }
-         for(i=1; i <= interpp.NbLines(); i++)
-         {
-           if(interpp.Line(i)->ArcType() == IntPatch_Walking) slin.Append(interpp.Line(i));
-         }
-       }
+    const Standard_Boolean RestrictLine = Standard_True;
+    IntSurf_ListOfPntOn2S ListOfPnts;
+    ListOfPnts.Clear();
+
+    ParamParamPerfom(theS1, theD1, theS2, theD2, TolArc, TolTang, ListOfPnts, RestrictLine, typs1, typs2);
   }
 }
                      
@@ -1041,19 +906,22 @@ met:if (interpp.IsDone())
 //function : Perform
 //purpose  : 
 //=======================================================================
-void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)&  S1,
-                                    const Handle(Adaptor3d_TopolTool)& D1,
-                                    const Handle(Adaptor3d_HSurface)&  S2,
-                                    const Handle(Adaptor3d_TopolTool)& D2,
+void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)&  theS1,
+                                    const Handle(Adaptor3d_TopolTool)& theD1,
+                                    const Handle(Adaptor3d_HSurface)&  theS2,
+                                    const Handle(Adaptor3d_TopolTool)& theD2,
                                     const Standard_Real TolArc,
                                     const Standard_Real TolTang,
                                     IntSurf_ListOfPntOn2S& ListOfPnts,
-                                    const Standard_Boolean RestrictLine)
+                                    const Standard_Boolean RestrictLine,
+                                    const Standard_Boolean isGeomInt)
 {
   myTolArc = TolArc;
   myTolTang = TolTang;
-  if(myFleche == 0.0) myFleche = 0.01;
-  if(myUVMaxStep == 0.0) myUVMaxStep = 0.01;
+  if(myFleche <= Precision::PConfusion())
+    myFleche = 0.01;
+  if(myUVMaxStep <= Precision::PConfusion())
+    myUVMaxStep = 0.01;
     
   done = Standard_False;
   spnt.Clear();
@@ -1062,101 +930,109 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)&  S1,
   tgte = Standard_False;
   oppo = Standard_False;
 
-  Standard_Integer i;
-
-  GeomAbs_SurfaceType typs1 = S1->GetType();
-  GeomAbs_SurfaceType typs2 = S2->GetType();
+  GeomAbs_SurfaceType typs1 = theS1->GetType();
+  GeomAbs_SurfaceType typs2 = theS2->GetType();
   
   Standard_Boolean TreatAsBiParametric = Standard_False;
-  if(typs1 == GeomAbs_Cone)  {
-    Standard_Real a1 = S1->Cone().SemiAngle();
-    if(a1<0.0) a1=-a1;
-    if(a1<2e-2 || a1>1.55)     { 
-      if(typs2==GeomAbs_Plane)   {
-       if(a1<2e-2)             { 
-         gp_Dir axec = S1->Cone().Axis().Direction();
-         gp_Dir axep = S2->Plane().Axis().Direction();
-         Standard_Real ps=axec.Dot(axep);
-         if(ps<0.0) {
-           ps=-ps;
-         }
-         if(ps<0.015) {
-           TreatAsBiParametric = Standard_True;
-         }
-       }
+  if(typs1 == GeomAbs_Cone)
+  {
+    const gp_Cone Con1 = theS1->Cone();
+    const Standard_Real a1 = Abs(Con1.SemiAngle());
+    if((a1 < 0.02) || (a1 > 1.55))
+    {
+      if(typs2==GeomAbs_Plane)
+      {
+        if(a1 < 0.02)
+        {
+          const gp_Pln Plan2 = theS2->Plane();
+          const gp_Dir axec = Con1.Axis().Direction();
+          const gp_Dir axep = Plan2.Axis().Direction();
+          const Standard_Real ps = Abs(axec.Dot(axep));
+          if(ps < 0.015)
+          {
+            TreatAsBiParametric = Standard_True;
+          }
+        }
       }
-      else {
-       TreatAsBiParametric = Standard_True;
+      else
+        TreatAsBiParametric = Standard_True;
+    }
+  }
+
+  if(typs2 == GeomAbs_Cone)
+  {
+    const gp_Cone Con2 = theS2->Cone();
+    const Standard_Real a2 = Abs(Con2.SemiAngle());
+    if((a2 < 0.02) || (a2 > 1.55))
+    {
+      if(typs1 == GeomAbs_Plane)
+      {
+        if(a2 < 0.02)
+        {
+          const gp_Pln Plan1 = theS1->Plane();
+          const gp_Dir axec = Con2.Axis().Direction();
+          const gp_Dir axep = Plan1.Axis().Direction();
+          const Standard_Real ps = Abs(axec.Dot(axep));
+          if(ps<0.015)
+          {
+            TreatAsBiParametric = Standard_True;
+          }
+        }
       }
+      else
+        TreatAsBiParametric = Standard_True;
     }
-  } 
-  if(typs2 == GeomAbs_Cone)  {
-    Standard_Real a2 = S2->Cone().SemiAngle();
-    if(a2<0.0) a2=-a2;
-    if(a2<2.e-2 || a2>1.55)    {
-      if(typs1==GeomAbs_Plane) {
-       if(a2<2e-2)       {
-         const gp_Dir axec = S2->Cone().Axis().Direction();
-         const gp_Dir axep = S1->Plane().Axis().Direction();
-         Standard_Real ps=axec.Dot(axep);
-         if(ps<0.0){
-           ps=-ps;
-         }
-         if(ps<0.015){
-           TreatAsBiParametric = Standard_True;
-         }
-       }
+
+    //// modified by jgv, 15.12.02 for OCC565 ////
+    if (typs1 == GeomAbs_Cone)
+    {
+      const gp_Cone Con1 = theS1->Cone();
+      const Standard_Real a1 = Abs(Con1.SemiAngle());
+      if (a1 < 0.02 && a2 < 0.02) //quasi-cylinders: if same domain, treat as canonic
+      {
+        const gp_Ax1 A1 = Con1.Axis(), A2 = Con2.Axis();
+        if (A1.IsParallel(A2,Precision::Angular()))
+        {
+          const gp_Lin L1(A1);
+          if (L1.Distance(A2.Location()) <= Precision::Confusion())
+          {
+            TreatAsBiParametric = Standard_False;
+          }
+        }
       }
-      else {
-       TreatAsBiParametric = Standard_True;
+      else if (a1 > 1.55 && a2 > 1.55) //quasi-planes: if same domain, treat as canonic
+      {
+        const gp_Ax1 A1 = Con1.Axis(), A2 = Con2.Axis();
+        if (A1.IsParallel(A2,Precision::Angular()))
+        {
+          const gp_Pnt Apex1 = Con1.Apex(), Apex2 = Con2.Apex();
+          const gp_Pln Plan1( Apex1, A1.Direction() );
+          if (Plan1.Distance( Apex2 ) <= Precision::Confusion())
+          {
+            TreatAsBiParametric = Standard_False;
+          }
+        }
       }
-    }
-  }
-  //// modified by jgv, 15.12.02 for OCC565 ////
-  if (typs1 == GeomAbs_Cone && typs2 == GeomAbs_Cone)
-  {
-    gp_Cone Con1 = S1->Cone();
-    gp_Cone Con2 = S2->Cone();
-    Standard_Real a1 = Con1.SemiAngle();
-    if (a1 < 0.0) a1 = -a1;
-    Standard_Real a2 = Con2.SemiAngle();
-    if (a2 < 0.0) a2 = -a2;
-    if (a1 < 2e-2 && a2 < 2e-2) //quasi-cylinders: if same domain, treat as canonic
-       {
-         gp_Ax1 A1 = Con1.Axis(), A2 = Con2.Axis();
-         if (A1.IsParallel(A2,Precision::Angular()))
-         {
-           gp_Lin L1(A1);
-           if (L1.Distance( A2.Location() ) <= Precision::Confusion())
+      else if ((a1 > 1.55) || (a2 > 1.55))
+      {
+        const gp_Ax1 A1 = Con1.Axis(), A2 = Con2.Axis();
+        if (A1.IsCoaxial(A2,Precision::Angular(),Precision::Confusion()))
+        {
           TreatAsBiParametric = Standard_False;
-         }
-       }
-    else if (a1 > 1.55 && a2 > 1.55) //quasi-planes: if same domain, treat as canonic
-       {
-         gp_Ax1 A1 = Con1.Axis(), A2 = Con2.Axis();
-         if (A1.IsParallel(A2,Precision::Angular()))
-         {
-           gp_Pnt Apex1 = Con1.Apex(), Apex2 = Con2.Apex();
-           gp_Pln Plan1( Apex1, A1.Direction() );
-           if (Plan1.Distance( Apex2 ) <= Precision::Confusion())
-                 TreatAsBiParametric = Standard_False;
-         }
-       }
-    else if ((a1 > 1.55 && a2 < 1.55) || (a2 > 1.55 && a1 < 1.55) ) {
-      gp_Ax1 A1 = Con1.Axis(), A2 = Con2.Axis();
-      if (A1.IsCoaxial(A2,Precision::Angular(),Precision::Confusion()))  {
-       TreatAsBiParametric = Standard_False;
+        }
       }
-    }
-  }
-  //////////////////////////////////////////////
+    }// if (typs1 == GeomAbs_Cone)    {
+  }// if(typs2 == GeomAbs_Cone)  {
 
-  if(D1->DomainIsInfinite() || D2->DomainIsInfinite()) {
+  if(theD1->DomainIsInfinite() || theD2->DomainIsInfinite()) {
     TreatAsBiParametric= Standard_False;
   }
-  if(TreatAsBiParametric) { 
-    typs1 = GeomAbs_BezierSurface; 
-    typs2 = GeomAbs_BezierSurface; 
+
+  if(TreatAsBiParametric)
+  {
+    // Using Prm-Prm Intersector
+    typs1 = GeomAbs_BezierSurface;
+    typs2 = GeomAbs_BezierSurface;
   }
 
   // Surface type definition
@@ -1169,6 +1045,7 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)&  S1,
     case GeomAbs_Cone: ts1 = 1; break;
     default: break;
   }
+
   Standard_Integer ts2 = 0;
   switch (typs2)
   {
@@ -1178,206 +1055,319 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)&  S1,
     case GeomAbs_Cone: ts2 = 1; break;
     default: break;
   }
+
   // Possible intersection types: 1. ts1 == ts2 == 1 <Geom-Geom>
   //                              2. ts1 != ts2      <Geom-Param>
   //                              3. ts1 == ts2 == 0 <Param-Param>
 
-  // Geom - Geom
-  if(ts1 == ts2 && ts1 == 1)
+  if(!isGeomInt)
   {
-    IntPatch_ImpImpIntersection interii(S1,D1,S2,D2,myTolArc,myTolTang);
-    if (interii.IsDone())
-       {
-         done = Standard_True;
-         empt = interii.IsEmpty();
-         if (!empt)
-         {
-           tgte = interii.TangentFaces();
-           if (tgte) oppo = interii.OppositeFaces();
-           for (i = 1; i <= interii.NbLines(); i++)
-               {
-                 const Handle_IntPatch_Line& line = interii.Line(i);
-                 if (line->ArcType() == IntPatch_Analytic)
-                 { 
-                   const GeomAbs_SurfaceType typs1 = S1->GetType();
-                   const GeomAbs_SurfaceType typs2 = S2->GetType();
-                   IntSurf_Quadric Quad1,Quad2;
-                   switch(typs1)
-                       {
-                         case GeomAbs_Plane:    Quad1.SetValue(S1->Plane());    break;
-                         case GeomAbs_Cylinder: Quad1.SetValue(S1->Cylinder()); break;
-                         case GeomAbs_Sphere:   Quad1.SetValue(S1->Sphere());   break;
-                         case GeomAbs_Cone:     Quad1.SetValue(S1->Cone());     break;
-                         default: break;
-                       }
-                   switch(typs2)
-                       { 
-                         case GeomAbs_Plane:    Quad2.SetValue(S2->Plane());    break;
-                         case GeomAbs_Cylinder: Quad2.SetValue(S2->Cylinder()); break;
-                         case GeomAbs_Sphere:   Quad2.SetValue(S2->Sphere());   break;
-                         case GeomAbs_Cone:     Quad2.SetValue(S2->Cone());     break;
-                         default: break;
-                       }
-                   IntPatch_ALineToWLine AToW(Quad1,Quad2,0.01,0.05,NBPOINTSSURALINE);
-                   Handle(IntPatch_Line) wlin=AToW.MakeWLine((*((Handle_IntPatch_ALine *)(&line))));
-                   slin.Append(wlin);
-                 }
-                 else slin.Append(interii.Line(i));
-               }
-        for (i = 1; i <= interii.NbPnts(); i++) spnt.Append(interii.Point(i));
-         }
-       }
-    else goto prm; 
+    ParamParamPerfom(theS1, theD1, theS2, theD2, TolArc, TolTang, ListOfPnts, RestrictLine, typs1, typs2);
   }
-  // Geom - Param
-  if(ts1 != ts2)
+  else if(ts1 != ts2)
+  {
+    GeomParamPerfom(theS1, theD1, theS2, theD2, ts1 == 0, typs1, typs2);
+  }
+  else if (ts1 == 0)
+  {
+    ParamParamPerfom(theS1, theD1, theS2, theD2, TolArc, TolTang, ListOfPnts, RestrictLine, typs1, typs2);
+  }
+  else if(ts1 == 1)
+  {
+    GeomGeomPerfom(theS1, theD1, theS2, theD2, TolArc, TolTang, ListOfPnts, RestrictLine, typs1, typs2);
+  }
+}
+
+//=======================================================================
+//function : ParamParamPerfom
+//purpose  : 
+//=======================================================================
+void IntPatch_Intersection::ParamParamPerfom(const Handle(Adaptor3d_HSurface)&  theS1,
+                                             const Handle(Adaptor3d_TopolTool)& theD1,
+                                             const Handle(Adaptor3d_HSurface)&  theS2,
+                                             const Handle(Adaptor3d_TopolTool)& theD2,
+                                             const Standard_Real TolArc,
+                                             const Standard_Real TolTang,
+                                             IntSurf_ListOfPntOn2S& ListOfPnts,
+                                             const Standard_Boolean RestrictLine,
+                                             const GeomAbs_SurfaceType typs1,
+                                             const GeomAbs_SurfaceType typs2)
+{
+  IntPatch_PrmPrmIntersection interpp;
+  if(!theD1->DomainIsInfinite() && !theD2->DomainIsInfinite())
   {
-    //cout << "IP" << endl;
-    IntPatch_ImpPrmIntersection interip;
-    if (myIsStartPnt) {
-         if (ts1 == 0) interip.SetStartPoint(myU1Start,myV1Start);
-         else          interip.SetStartPoint(myU2Start,myV2Start);
+    Standard_Boolean ClearFlag = Standard_True;
+    if(!ListOfPnts.IsEmpty())
+    {
+      interpp.Perform(theS1,theD1,theS2,theD2,TolArc,TolTang,myFleche,myUVMaxStep, ListOfPnts, RestrictLine);
+      ClearFlag = Standard_False;
     }
-    if(D1->DomainIsInfinite() && D2->DomainIsInfinite())
-       {
-         Standard_Boolean IsPLInt = Standard_False;
-         TColgp_SequenceOfPnt sop;
-         gp_Vec v;
-         FUN_PL_Intersection(S1,typs1,S2,typs2,IsPLInt,sop,v);
-         if(IsPLInt)
-         {
-           if(sop.Length() > 0)
-               {
-                 for(Standard_Integer ip = 1; ip <= sop.Length(); ip++)
-                 {
-                   gp_Lin lin(sop.Value(ip),gp_Dir(v));
-                   Handle(IntPatch_GLine) gl = new IntPatch_GLine(lin,Standard_False);
-                   slin.Append(*(Handle_IntPatch_Line *)&gl);
-                 }
-                 done = Standard_True;
-               }
-           else done = Standard_False;
-           return;
-         }
-         else
-         {
-           Handle(Adaptor3d_HSurface) nS1 = S1;
-           Handle(Adaptor3d_HSurface) nS2 = S2;
-           FUN_TrimBothSurf(S1,typs1,S2,typs2,1.e+5,nS1,nS2);
-           interip.Perform(nS1,D1,nS2,D2,myTolArc,myTolTang,myFleche,myUVMaxStep);
-         }
-       }
-    else interip.Perform(S1,D1,S2,D2,myTolArc,myTolTang,myFleche,myUVMaxStep);
-//      IntPatch_ImpPrmIntersection interip(S1,D1,S2,D2,myTolArc,myTolTang,myFleche,myUVMaxStep);
-    if (interip.IsDone()) 
-       {
-         done = Standard_True;
-         empt = interip.IsEmpty();
-         if (!empt) 
-         {
-           for(i = 1; i <= interip.NbLines(); i++)
-               {
-                 if(interip.Line(i)->ArcType() != IntPatch_Walking) slin.Append(interip.Line(i));
-               }
-           for(i = 1; i <= interip.NbLines(); i++) 
-               {
-                 if(interip.Line(i)->ArcType() == IntPatch_Walking) slin.Append(interip.Line(i));
-               }
-           for (i = 1; i <= interip.NbPnts(); i++) spnt.Append(interip.Point(i));
-         }
-       }
+    interpp.Perform(theS1,theD1,theS2,theD2,TolArc,TolTang,myFleche,myUVMaxStep,ClearFlag);   //double call!!!!!!!
   }
-  // Param - Param 
-  if(ts1 == ts2 && ts1 == 0)
+  else if((theD1->DomainIsInfinite()) ^ (theD2->DomainIsInfinite()))
   {
-      //cout << "PP" << endl;
-prm:; // this algorithm was modified last by OFV [29-Oct-2001] -> [2-Nov-2001]
-    IntPatch_PrmPrmIntersection interpp;
-    if(!D1->DomainIsInfinite() && !D2->DomainIsInfinite())
-       {
-      // modified by NIZHNY-AMV  Tue Oct 18 12:37:02 2005.BEGIN
-      Standard_Boolean ClearFlag = Standard_True;
-      if(!ListOfPnts.IsEmpty()){
-        interpp.Perform(S1,D1,S2,D2,TolArc,TolTang,myFleche,myUVMaxStep, ListOfPnts, RestrictLine);
-        ClearFlag = Standard_False;
+    gp_Pnt pMaxXYZ, pMinXYZ;
+    if(theD1->DomainIsInfinite())
+    {
+      FUN_GetMinMaxXYZPnt( theS2, pMinXYZ, pMaxXYZ );
+      const Standard_Real MU = Max(Abs(theS2->FirstUParameter()),Abs(theS2->LastUParameter()));
+      const Standard_Real MV = Max(Abs(theS2->FirstVParameter()),Abs(theS2->LastVParameter()));
+      const Standard_Real AP = Max(MU, MV);
+      Handle(Adaptor3d_HSurface) SS;
+      FUN_TrimInfSurf(pMinXYZ, pMaxXYZ, theS1, AP, SS);
+      interpp.Perform(SS,theD1,theS2,theD2,TolArc,TolTang,myFleche,myUVMaxStep);
+    }
+    else
+    {
+      FUN_GetMinMaxXYZPnt( theS1, pMinXYZ, pMaxXYZ );
+      const Standard_Real MU = Max(Abs(theS1->FirstUParameter()),Abs(theS1->LastUParameter()));
+      const Standard_Real MV = Max(Abs(theS1->FirstVParameter()),Abs(theS1->LastVParameter()));
+      const Standard_Real AP = Max(MU, MV);
+      Handle(Adaptor3d_HSurface) SS;
+      FUN_TrimInfSurf(pMinXYZ, pMaxXYZ, theS2, AP, SS);
+      interpp.Perform(theS1, theD1, SS, theD2,TolArc,TolTang,myFleche,myUVMaxStep);
+    }
+  }//(theD1->DomainIsInfinite()) ^ (theD2->DomainIsInfinite())
+  else
+  {
+    if(typs1 == GeomAbs_OtherSurface || typs2 == GeomAbs_OtherSurface)
+    {
+      done = Standard_False;
+      return;
+    }
+
+    Standard_Boolean IsPLInt = Standard_False;
+    TColgp_SequenceOfPnt sop;
+    gp_Vec v;
+    FUN_PL_Intersection(theS1,typs1,theS2,typs2,IsPLInt,sop,v);
+
+    if(IsPLInt)
+    {
+      if(sop.Length() > 0)
+      {
+        for(Standard_Integer ip = 1; ip <= sop.Length(); ip++)
+        {
+          gp_Lin lin(sop.Value(ip),gp_Dir(v));
+          Handle(IntPatch_GLine) gl = new IntPatch_GLine(lin,Standard_False);
+          slin.Append(*(Handle_IntPatch_Line *)&gl);
+        }
+
+        done = Standard_True;
       }
-      // modified by NIZHNY-AMV  Tue Oct 18 12:37:02 2005.END
-      interpp.Perform(S1,D1,S2,D2,TolArc,TolTang,myFleche,myUVMaxStep,ClearFlag);
-         goto met;
-       }
-    else if( (!D1->DomainIsInfinite() && D2->DomainIsInfinite()) || (D1->DomainIsInfinite() && !D2->DomainIsInfinite()) )
-   {
-      gp_Pnt pMaxXYZ, pMinXYZ;
-         if(D1->DomainIsInfinite())
-         {
-           FUN_GetMinMaxXYZPnt( S2, pMinXYZ, pMaxXYZ );
-           const Standard_Real MU = Max(Abs(S2->FirstUParameter()),Abs(S2->LastUParameter()));
-           const Standard_Real MV = Max(Abs(S2->FirstVParameter()),Abs(S2->LastVParameter()));
-           const Standard_Real AP = Max(MU, MV);
-           Handle(Adaptor3d_HSurface) SS;
-           FUN_TrimInfSurf(pMinXYZ, pMaxXYZ, S1, AP, SS);
-           interpp.Perform(SS,D1,S2,D2,TolArc,TolTang,myFleche,myUVMaxStep);
-         }
-         else
-         {
-           FUN_GetMinMaxXYZPnt( S1, pMinXYZ, pMaxXYZ );
-           const Standard_Real MU = Max(Abs(S1->FirstUParameter()),Abs(S1->LastUParameter()));
-           const Standard_Real MV = Max(Abs(S1->FirstVParameter()),Abs(S1->LastVParameter()));
-           const Standard_Real AP = Max(MU, MV);
-           Handle(Adaptor3d_HSurface) SS;
-           FUN_TrimInfSurf(pMinXYZ, pMaxXYZ, S2, AP, SS);
-           interpp.Perform(S1,D1,SS,D2,TolArc,TolTang,myFleche,myUVMaxStep);
-         }
-      goto met;
-       }//(!D1->DomainIsInfinite() && D2->DomainIsInfinite()) || (D1->DomainIsInfinite() && !D2->DomainIsInfinite())
-    else 
-       {
-         if(typs1 == GeomAbs_OtherSurface || typs2 == GeomAbs_OtherSurface){ done = Standard_False;  return; }
-         Standard_Boolean IsPLInt = Standard_False;
-         TColgp_SequenceOfPnt sop;
-         gp_Vec v;
-         FUN_PL_Intersection(S1,typs1,S2,typs2,IsPLInt,sop,v);
-         if(IsPLInt)
-         {
-           if(sop.Length() > 0)
-               {
-                 for(Standard_Integer ip = 1; ip <= sop.Length(); ip++)
-                 {
-                   gp_Lin lin(sop.Value(ip),gp_Dir(v));
-                   Handle(IntPatch_GLine) gl = new IntPatch_GLine(lin,Standard_False);
-                   slin.Append(*(Handle_IntPatch_Line *)&gl);
-                 }
-                 done = Standard_True;
-               }
-           else done = Standard_False;
-           return;
-         } // 'COLLINEAR LINES'
-         else
-         {
-           Handle(Adaptor3d_HSurface) nS1 = S1;
-           Handle(Adaptor3d_HSurface) nS2 = S2;
-           FUN_TrimBothSurf(S1,typs1,S2,typs2,1.e+8,nS1,nS2);
-           interpp.Perform(nS1,D1,nS2,D2,TolArc,TolTang,myFleche,myUVMaxStep);
-           goto met;
-         }// 'NON - COLLINEAR LINES'
-       }// both domains are infinite
-met:  if (interpp.IsDone())
-       {
-         done = Standard_True;
-         tgte = Standard_False;
-         empt = interpp.IsEmpty();
-         for(i=1; i <= interpp.NbLines(); i++)
-         {
-           if(interpp.Line(i)->ArcType() != IntPatch_Walking) slin.Append(interpp.Line(i));
-         }
-         for (i=1; i <= interpp.NbLines(); i++)
-         {
-           if(interpp.Line(i)->ArcType() == IntPatch_Walking) slin.Append(interpp.Line(i));
-         }
-       }
+      else
+        done = Standard_False;
+
+      return;
+    }// 'COLLINEAR LINES'
+    else
+    {
+      Handle(Adaptor3d_HSurface) nS1 = theS1;
+      Handle(Adaptor3d_HSurface) nS2 = theS2;
+      FUN_TrimBothSurf(theS1,typs1,theS2,typs2,1.e+8,nS1,nS2);
+      interpp.Perform(nS1,theD1,nS2,theD2,TolArc,TolTang,myFleche,myUVMaxStep);
+    }// 'NON - COLLINEAR LINES'
+  }// both domains are infinite
+
+  if (interpp.IsDone())
+  {
+    done = Standard_True;
+    tgte = Standard_False;
+    empt = interpp.IsEmpty();
+
+    for(Standard_Integer i = 1; i <= interpp.NbLines(); i++)
+    {
+      if(interpp.Line(i)->ArcType() != IntPatch_Walking)
+        slin.Append(interpp.Line(i));
+    }
+
+    for (Standard_Integer i = 1; i <= interpp.NbLines(); i++)
+    {
+      if(interpp.Line(i)->ArcType() == IntPatch_Walking)
+        slin.Append(interpp.Line(i));
+    }
+  }
+}
+
+//=======================================================================
+////function : GeomGeomPerfom
+//purpose  : 
+//=======================================================================
+void IntPatch_Intersection::GeomGeomPerfom(const Handle(Adaptor3d_HSurface)& theS1,
+                                           const Handle(Adaptor3d_TopolTool)& theD1,
+                                           const Handle(Adaptor3d_HSurface)& theS2,
+                                           const Handle(Adaptor3d_TopolTool)& theD2,
+                                           const Standard_Real TolArc,
+                                           const Standard_Real TolTang,
+                                           IntSurf_ListOfPntOn2S& ListOfPnts,
+                                           const Standard_Boolean RestrictLine,
+                                           const GeomAbs_SurfaceType typs1,
+                                           const GeomAbs_SurfaceType typs2)
+{
+  IntPatch_ImpImpIntersection interii(theS1,theD1,theS2,theD2,myTolArc,myTolTang);
+  const Standard_Boolean anIS = interii.IsDone();
+  if (anIS)
+  {
+    done = anIS;
+    empt = interii.IsEmpty();
+    if (!empt)
+    {
+      tgte = interii.TangentFaces();
+      if (tgte)
+        oppo = interii.OppositeFaces();
+
+      for (Standard_Integer i = 1; i <= interii.NbLines(); i++)
+      {
+        const Handle_IntPatch_Line& line = interii.Line(i);
+        if (line->ArcType() == IntPatch_Analytic)
+        {
+          const GeomAbs_SurfaceType typs1 = theS1->GetType();
+          const GeomAbs_SurfaceType typs2 = theS2->GetType();
+          IntSurf_Quadric Quad1,Quad2;
+          
+          switch(typs1)
+          {
+          case GeomAbs_Plane:
+            Quad1.SetValue(theS1->Plane());
+            break;
+
+          case GeomAbs_Cylinder:
+            Quad1.SetValue(theS1->Cylinder());
+            break;
+
+          case GeomAbs_Sphere:
+            Quad1.SetValue(theS1->Sphere());
+            break;
+
+          case GeomAbs_Cone:
+            Quad1.SetValue(theS1->Cone());
+            break;
+
+          default:
+            break;
+          }
+
+          switch(typs2)
+          {
+          case GeomAbs_Plane:
+            Quad2.SetValue(theS2->Plane());
+            break;
+          case GeomAbs_Cylinder:
+            Quad2.SetValue(theS2->Cylinder());
+            break;
+
+          case GeomAbs_Sphere:
+            Quad2.SetValue(theS2->Sphere());
+            break;
+
+          case GeomAbs_Cone:
+            Quad2.SetValue(theS2->Cone());
+            break;
+
+          default:
+            break;
+          }
+
+          IntPatch_ALineToWLine AToW(Quad1,Quad2,0.01,0.05,aNbPointsInALine);
+          Handle(IntPatch_Line) wlin=AToW.MakeWLine((*((Handle_IntPatch_ALine *)(&line))));
+          slin.Append(wlin);
+        }
+        else
+          slin.Append(interii.Line(i));
+      }
+
+      for (Standard_Integer i = 1; i <= interii.NbPnts(); i++)
+      {
+        spnt.Append(interii.Point(i));
+      }
+    }
   }
+  else
+    ParamParamPerfom(theS1, theD1, theS2, theD2, TolArc, TolTang, ListOfPnts, RestrictLine, typs1, typs2);
 }
 
+//=======================================================================
+////function : GeomParamPerfom
+//purpose  : 
+//=======================================================================
+void IntPatch_Intersection::GeomParamPerfom(const Handle(Adaptor3d_HSurface)&  theS1,
+                                            const Handle(Adaptor3d_TopolTool)& theD1,
+                                            const Handle(Adaptor3d_HSurface)&  theS2,
+                                            const Handle(Adaptor3d_TopolTool)& theD2,
+                                            const Standard_Boolean isNotAnalitical,
+                                            const GeomAbs_SurfaceType typs1,
+                                            const GeomAbs_SurfaceType typs2)
+{
+  IntPatch_ImpPrmIntersection interip;
+  if (myIsStartPnt)
+  {
+    if (isNotAnalitical/*ts1 == 0*/)
+      interip.SetStartPoint(myU1Start,myV1Start);
+    else
+      interip.SetStartPoint(myU2Start,myV2Start);
+  }
+
+  if(theD1->DomainIsInfinite() && theD2->DomainIsInfinite())
+  {
+    Standard_Boolean IsPLInt = Standard_False;
+    TColgp_SequenceOfPnt sop;
+    gp_Vec v;
+    FUN_PL_Intersection(theS1,typs1,theS2,typs2,IsPLInt,sop,v);
+    
+    if(IsPLInt)
+    {
+      if(sop.Length() > 0)
+      {
+        for(Standard_Integer ip = 1; ip <= sop.Length(); ip++)
+        {
+          gp_Lin lin(sop.Value(ip),gp_Dir(v));
+          Handle(IntPatch_GLine) gl = new IntPatch_GLine(lin,Standard_False);
+          slin.Append(*(Handle_IntPatch_Line *)&gl);
+        }
+
+        done = Standard_True;
+      }
+      else
+        done = Standard_False;
+
+      return;
+    }
+    else
+    {
+      Handle(Adaptor3d_HSurface) nS1 = theS1;
+      Handle(Adaptor3d_HSurface) nS2 = theS2;
+      FUN_TrimBothSurf(theS1,typs1,theS2,typs2,1.e+5,nS1,nS2);
+      interip.Perform(nS1,theD1,nS2,theD2,myTolArc,myTolTang,myFleche,myUVMaxStep);
+    }
+  }
+  else
+    interip.Perform(theS1,theD1,theS2,theD2,myTolArc,myTolTang,myFleche,myUVMaxStep);
+
+  if (interip.IsDone()) 
+  {
+    done = Standard_True;
+    empt = interip.IsEmpty();
+
+    if (!empt)
+    {
+      for(Standard_Integer i = 1; i <= interip.NbLines(); i++)
+      {
+        if(interip.Line(i)->ArcType() != IntPatch_Walking)
+          slin.Append(interip.Line(i));
+      }
+
+      for(Standard_Integer i = 1; i <= interip.NbLines(); i++)
+      {
+        if(interip.Line(i)->ArcType() == IntPatch_Walking)
+          slin.Append(interip.Line(i));
+      }
+
+      for (Standard_Integer i = 1; i <= interip.NbPnts(); i++)
+        spnt.Append(interip.Point(i));
+    }
+  }
+}
+
+
 void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)&  S1,
                                     const Handle(Adaptor3d_TopolTool)& D1,
                                     const Handle(Adaptor3d_HSurface)&  S2,
index fc8678e..2f87172 100755 (executable)
@@ -25,13 +25,13 @@ class FaceFace from IntTools
 
 uses 
 
-    TopolTool from Adaptor3d, 
-    HSurface  from GeomAdaptor, 
-    ListOfPntOn2S from IntSurf ,
-    Intersection from IntPatch,
-    Face from TopoDS,
-    SequenceOfCurves from IntTools,
-    LineConstructor from IntTools,
+    TopolTool             from Adaptor3d, 
+    HSurface              from GeomAdaptor, 
+    ListOfPntOn2S         from IntSurf ,
+    Intersection          from IntPatch,
+    Face                  from TopoDS,
+    SequenceOfCurves      from IntTools,
+    LineConstructor       from IntTools,
     SequenceOfPntOn2Faces from IntTools, 
     Context from BOPInt
     
index 30a6804..7815d6a 100755 (executable)
@@ -283,11 +283,8 @@ static
 
 static
   void Tolerances(const Handle(GeomAdaptor_HSurface)& aHS1,
-                 const Handle(GeomAdaptor_HSurface)& aHS2,
-                 Standard_Real& aTolArc,
-                 Standard_Real& aTolTang,
-                 Standard_Real& aUVMaxStep,
-                 Standard_Real& aDeflection);
+                  const Handle(GeomAdaptor_HSurface)& aHS2,
+                  Standard_Real& aTolTang);
 
 static
   Standard_Boolean SortTypes(const GeomAbs_SurfaceType aType1,
@@ -413,7 +410,7 @@ const IntTools_SequenceOfCurves& IntTools_FaceFace::Lines() const
 {
   StdFail_NotDone_Raise_if
     (!myIsDone,
-     "IntTools_FaceFace::Lines() => !myIntersector.IsDone()");
+     "IntTools_FaceFace::Lines() => myIntersector NOT DONE");
   return mySeqOfCurve;
 }
 //=======================================================================
@@ -446,127 +443,209 @@ void IntTools_FaceFace::SetList(IntSurf_ListOfPntOn2S& aListOfPnts)
 {
   myListOfPnts = aListOfPnts;  
 }
+
+
+static Standard_Boolean isTreatAnalityc(const TopoDS_Face& theF1,
+                                        const TopoDS_Face& theF2)
+{
+  const Standard_Real Tolang = 1.e-8;
+  const Standard_Real aTolF1=BRep_Tool::Tolerance(theF1);
+  const Standard_Real aTolF2=BRep_Tool::Tolerance(theF2);
+  const Standard_Real aTolSum = aTolF1 + aTolF2;
+  Standard_Real aHigh = 0.0;
+
+  const BRepAdaptor_Surface aBAS1(theF1), aBAS2(theF2);
+  const GeomAbs_SurfaceType aType1=aBAS1.GetType();
+  const GeomAbs_SurfaceType aType2=aBAS2.GetType();
+  
+  gp_Pln aS1;
+  gp_Cylinder aS2;
+  if(aType1 == GeomAbs_Plane)
+  {
+    aS1=aBAS1.Plane();
+  }
+  else if(aType2 == GeomAbs_Plane)
+  {
+    aS1=aBAS2.Plane();
+  }
+  else
+  {
+    return Standard_True;
+  }
+
+  if(aType1 == GeomAbs_Cylinder)
+  {
+    aS2=aBAS1.Cylinder();
+    const Standard_Real VMin = aBAS1.FirstVParameter();
+    const Standard_Real VMax = aBAS1.LastVParameter();
+
+    if( Precision::IsNegativeInfinite(VMin) ||
+        Precision::IsPositiveInfinite(VMax))
+          return Standard_True;
+    else
+      aHigh = VMax - VMin;
+  }
+  else if(aType2 == GeomAbs_Cylinder)
+  {
+    aS2=aBAS2.Cylinder();
+
+    const Standard_Real VMin = aBAS2.FirstVParameter();
+    const Standard_Real VMax = aBAS2.LastVParameter();
+
+    if( Precision::IsNegativeInfinite(VMin) ||
+        Precision::IsPositiveInfinite(VMax))
+          return Standard_True;
+    else
+      aHigh = VMax - VMin;
+  }
+  else
+  {
+    return Standard_True;
+  }
+
+  IntAna_QuadQuadGeo inter;
+  inter.Perform(aS1,aS2,Tolang,aTolSum, aHigh);
+  if(inter.TypeInter() == IntAna_Ellipse)
+  {
+    const gp_Elips anEl = inter.Ellipse(1);
+    const Standard_Real aMajorR = anEl.MajorRadius();
+    const Standard_Real aMinorR = anEl.MinorRadius();
+    
+    return (aMajorR < 100000.0 * aMinorR);
+  }
+  else
+  {
+    return inter.IsDone();
+  }
+}
+
+
+
 //=======================================================================
 //function : Perform
 //purpose  : intersect surfaces of the faces
 //=======================================================================
   void IntTools_FaceFace::Perform(const TopoDS_Face& aF1,
-                                 const TopoDS_Face& aF2)
+                                  const TopoDS_Face& aF2)
 {
-  Standard_Boolean hasCone, RestrictLine, bTwoPlanes, bReverse;
-  Standard_Integer aNbLin, aNbPnts, i, NbLinPP;
-  Standard_Real TolArc, TolTang, Deflection, UVMaxStep;
-  Standard_Real umin, umax, vmin, vmax;
-  Standard_Real aTolF1, aTolF2;
-  GeomAbs_SurfaceType aType1, aType2;
-  Handle(Geom_Surface) S1, S2;
-  Handle(IntTools_TopolTool) dom1, dom2;
-  BRepAdaptor_Surface aBAS1, aBAS2;
-  //
+  Standard_Boolean RestrictLine = Standard_False, hasCone = Standard_False;
+  
   if (myContext.IsNull()) {
     myContext=new BOPInt_Context;
   }
-  //
+
   mySeqOfCurve.Clear();
   myTolReached2d=0.;
   myTolReached3d=0.;
   myIsDone = Standard_False;
   myNbrestr=0;//?
-  hasCone = Standard_False;
-  bTwoPlanes = Standard_False;
-  //
+
   myFace1=aF1;
   myFace2=aF2;
-  //
-  aBAS1.Initialize(myFace1, Standard_False);
-  aBAS2.Initialize(myFace2, Standard_False);
-  aType1=aBAS1.GetType();
-  aType2=aBAS2.GetType();
-  //
-  bReverse=SortTypes(aType1, aType2);
-  if (bReverse) {
+
+  const BRepAdaptor_Surface aBAS1(myFace1, Standard_False);
+  const BRepAdaptor_Surface aBAS2(myFace2, Standard_False);
+  GeomAbs_SurfaceType aType1=aBAS1.GetType();
+  GeomAbs_SurfaceType aType2=aBAS2.GetType();
+
+  const Standard_Boolean bReverse=SortTypes(aType1, aType2);
+  if (bReverse)
+  {
     myFace1=aF2;
     myFace2=aF1;
     aType1=aBAS2.GetType();
     aType2=aBAS1.GetType();
-    //
-    if (myListOfPnts.Extent()) {
+
+    if (myListOfPnts.Extent())
+    {
       Standard_Real aU1,aV1,aU2,aV2;
       IntSurf_ListIteratorOfListOfPntOn2S aItP2S;
       //
       aItP2S.Initialize(myListOfPnts);
-      for (; aItP2S.More(); aItP2S.Next()){
-       IntSurf_PntOn2S& aP2S=aItP2S.Value();
-       aP2S.Parameters(aU1,aV1,aU2,aV2);
-       aP2S.SetValue(aU2,aV2,aU1,aV1);
+      for (; aItP2S.More(); aItP2S.Next())
+      {
+        IntSurf_PntOn2S& aP2S=aItP2S.Value();
+        aP2S.Parameters(aU1,aV1,aU2,aV2);
+        aP2S.SetValue(aU2,aV2,aU1,aV1);
       }
     }
   }
-  //
-  S1=BRep_Tool::Surface(myFace1);
-  S2=BRep_Tool::Surface(myFace2);
-  //
-  aTolF1=BRep_Tool::Tolerance(myFace1);
-  aTolF2=BRep_Tool::Tolerance(myFace2);
-  //
-  TolArc= aTolF1 + aTolF2;
-  TolTang = TolArc;
-  //
-  NbLinPP = 0;
-  if(aType1==GeomAbs_Plane && aType2==GeomAbs_Plane){
-    bTwoPlanes = Standard_True;
 
+
+  const Handle(Geom_Surface) S1=BRep_Tool::Surface(myFace1);
+  const Handle(Geom_Surface) S2=BRep_Tool::Surface(myFace2);
+
+  const Standard_Real aTolF1=BRep_Tool::Tolerance(myFace1);
+  const Standard_Real aTolF2=BRep_Tool::Tolerance(myFace2);
+
+  Standard_Real TolArc = aTolF1 + aTolF2;
+  Standard_Real TolTang = TolArc;
+
+  const Standard_Boolean isFace1Quad = (aType1 == GeomAbs_Cylinder ||
+                                        aType1 == GeomAbs_Cone ||
+                                        aType1 == GeomAbs_Torus);
+
+  const Standard_Boolean isFace2Quad = (aType2 == GeomAbs_Cylinder ||
+                                        aType2 == GeomAbs_Cone ||
+                                        aType2 == GeomAbs_Torus);
+
+  if(aType1==GeomAbs_Plane && aType2==GeomAbs_Plane)
+  {
+    Standard_Real umin, umax, vmin, vmax;
     BRepTools::UVBounds(myFace1, umin, umax, vmin, vmax);
     myHS1->ChangeSurface().Load(S1, umin, umax, vmin, vmax);
     //
     BRepTools::UVBounds(myFace2, umin, umax, vmin, vmax);
     myHS2->ChangeSurface().Load(S2, umin, umax, vmin, vmax);
     Standard_Real TolAng = 1.e-8;
-    PerformPlanes(myHS1, myHS2, TolAng, TolTang, myApprox1, myApprox2, 
-                 mySeqOfCurve, myTangentFaces);
+
+    PerformPlanes(myHS1, myHS2, TolAng, TolTang, myApprox1, myApprox2,
+                                          mySeqOfCurve, myTangentFaces);
 
     myIsDone = Standard_True;
     
-    if(!myTangentFaces) {
-      //
-      NbLinPP = mySeqOfCurve.Length();
-      if(NbLinPP) {
-       Standard_Real aTolFMax;
-       //
-       myTolReached3d = 1.e-7;
-       //
-       aTolFMax=Max(aTolF1, aTolF2);
-       //
-       if (aTolFMax>myTolReached3d) {
-         myTolReached3d=aTolFMax;
-       }
-       myTolReached2d = myTolReached3d;
-       //
-       if (bReverse) {
-         Handle(Geom2d_Curve) aC2D1, aC2D2;
-         //
-         aNbLin=mySeqOfCurve.Length();
-         for (i=1; i<=aNbLin; ++i) {
-           IntTools_Curve& aIC=mySeqOfCurve(i);
-           aC2D1=aIC.FirstCurve2d();
-           aC2D2=aIC.SecondCurve2d();
-           //
-           aIC.SetFirstCurve2d(aC2D2);
-           aIC.SetSecondCurve2d(aC2D1);
-         }
-       }
+    if(!myTangentFaces)
+    {
+      const Standard_Integer NbLinPP = mySeqOfCurve.Length();
+      if(NbLinPP)
+      {
+        Standard_Real aTolFMax;
+        myTolReached3d = 1.e-7;
+        aTolFMax=Max(aTolF1, aTolF2);
+        if (aTolFMax>myTolReached3d)
+        {
+          myTolReached3d=aTolFMax;
+        }
+
+        myTolReached2d = myTolReached3d;
+
+        if (bReverse)
+        {
+          Handle(Geom2d_Curve) aC2D1, aC2D2;
+          const Standard_Integer aNbLin = mySeqOfCurve.Length();
+          for (Standard_Integer i = 1; i <= aNbLin; ++i)
+          {
+            IntTools_Curve& aIC=mySeqOfCurve(i);
+            aC2D1=aIC.FirstCurve2d();
+            aC2D2=aIC.SecondCurve2d();
+            aIC.SetFirstCurve2d(aC2D2);
+            aIC.SetSecondCurve2d(aC2D1);
+          }
+        }
       }
     }
+
     return;
   }//if(aType1==GeomAbs_Plane && aType2==GeomAbs_Plane){
-  //
-  if (aType1==GeomAbs_Plane && 
-      (aType2==GeomAbs_Cylinder ||
-       aType2==GeomAbs_Cone ||
-       aType2==GeomAbs_Torus)) {
+
+  if ((aType1==GeomAbs_Plane) && isFace2Quad)
+  {
     Standard_Real dU, dV;
+
     // F1
+    Standard_Real umin, umax, vmin, vmax;
     BRepTools::UVBounds(myFace1, umin, umax, vmin, vmax);
+
     dU=0.1*(umax-umin);
     dV=0.1*(vmax-vmin);
     umin=umin-dU;
@@ -584,13 +663,12 @@ void IntTools_FaceFace::SetList(IntSurf_ListOfPntOn2S& aListOfPnts)
       hasCone = Standard_True; 
     }
   }
-  //
-  else if ((aType1==GeomAbs_Cylinder||
-           aType1==GeomAbs_Cone ||
-           aType1==GeomAbs_Torus) && 
-          aType2==GeomAbs_Plane) {
+  else if ((aType2==GeomAbs_Plane) && isFace1Quad)
+  {
     Standard_Real dU, dV;
+
     //F1
+    Standard_Real umin, umax, vmin, vmax;
     BRepTools::UVBounds(myFace1, umin, umax, vmin, vmax);
     CorrectSurfaceBoundaries(myFace1, (aTolF1 + aTolF2) * 2., umin, umax, vmin, vmax);
     myHS1->ChangeSurface().Load(S1, umin, umax, vmin, vmax);
@@ -609,80 +687,84 @@ void IntTools_FaceFace::SetList(IntSurf_ListOfPntOn2S& aListOfPnts)
       hasCone = Standard_True; 
     }
   }
-  
-  //
-  else {
+  else
+  {
+    Standard_Real umin, umax, vmin, vmax;
     BRepTools::UVBounds(myFace1, umin, umax, vmin, vmax);
-      //
     CorrectSurfaceBoundaries(myFace1, (aTolF1 + aTolF2) * 2., umin, umax, vmin, vmax);
-    // 
     myHS1->ChangeSurface().Load(S1, umin, umax, vmin, vmax);
-    //
     BRepTools::UVBounds(myFace2, umin, umax, vmin, vmax);
-    // 
     CorrectSurfaceBoundaries(myFace2, (aTolF1 + aTolF2) * 2., umin, umax, vmin, vmax);
-    //   
     myHS2->ChangeSurface().Load(S2, umin, umax, vmin, vmax);
   }
-  //
-  dom1 = new IntTools_TopolTool(myHS1);
-  dom2 = new IntTools_TopolTool(myHS2);
-  //
+
+  const Handle(IntTools_TopolTool) dom1 = new IntTools_TopolTool(myHS1);
+  const Handle(IntTools_TopolTool) dom2 = new IntTools_TopolTool(myHS2);
+
   myLConstruct.Load(dom1, dom2, myHS1, myHS2);
-  //
-  Deflection = (hasCone) ? 0.085 : 0.1;
-  UVMaxStep  = 0.001;
-  //
-  Tolerances(myHS1, myHS2, TolArc, TolTang, UVMaxStep, Deflection);
-  //
-  myIntersector.SetTolerances(TolArc, TolTang, UVMaxStep, Deflection); 
-  //
-  RestrictLine = Standard_False;
-  //
+  
+
+  Tolerances(myHS1, myHS2, TolTang);
+
+  {
+    const Standard_Real UVMaxStep = 0.001;
+    const Standard_Real Deflection = (hasCone) ? 0.085 : 0.1;
+    myIntersector.SetTolerances(TolArc, TolTang, UVMaxStep, Deflection);
+  }
+  
   if((myHS1->IsUClosed() && !myHS1->IsUPeriodic()) || 
      (myHS1->IsVClosed() && !myHS1->IsVPeriodic()) ||
      (myHS2->IsUClosed() && !myHS2->IsUPeriodic()) || 
-     (myHS2->IsVClosed() && !myHS2->IsVPeriodic())) {
+     (myHS2->IsVClosed() && !myHS2->IsVPeriodic()))
+  {
     RestrictLine = Standard_True;
   }
   //
-  if(((aType1 != GeomAbs_BSplineSurface) &&
-      (aType1 != GeomAbs_BezierSurface)  &&
-      (aType1 != GeomAbs_OtherSurface))  &&
-     ((aType2 != GeomAbs_BSplineSurface) &&
-      (aType2 != GeomAbs_BezierSurface)  &&
-      (aType2 != GeomAbs_OtherSurface))) {
+  if((aType1 != GeomAbs_BSplineSurface) &&
+     (aType1 != GeomAbs_BezierSurface) &&
+     (aType1 != GeomAbs_OtherSurface)  &&
+     (aType2 != GeomAbs_BSplineSurface) &&
+     (aType2 != GeomAbs_BezierSurface) &&
+     (aType2 != GeomAbs_OtherSurface))
+  {
     RestrictLine = Standard_True;
-    //
+
     if ((aType1 == GeomAbs_Torus) ||
-       (aType2 == GeomAbs_Torus) ) {
+        (aType2 == GeomAbs_Torus))
+    {
       myListOfPnts.Clear();
     }
   }
+
   //
-  if(!RestrictLine) {
+  if(!RestrictLine)
+  {
     TopExp_Explorer aExp;
-    //
-    for(i = 0; (!RestrictLine) && (i < 2); i++) {
+    for(Standard_Integer i = 0; (!RestrictLine) && (i < 2); i++)
+    {
       const TopoDS_Face& aF=(!i) ? myFace1 : myFace2;
       aExp.Init(aF, TopAbs_EDGE);
-      for(; aExp.More(); aExp.Next()) {
-       const TopoDS_Edge& aE=TopoDS::Edge(aExp.Current());
-       //
-       if(BRep_Tool::Degenerated(aE)) {
-         RestrictLine = Standard_True;
-         break;
-       }
+      for(; aExp.More(); aExp.Next())
+      {
+        const TopoDS_Edge& aE=TopoDS::Edge(aExp.Current());
+
+        if(BRep_Tool::Degenerated(aE))
+        {
+          RestrictLine = Standard_True;
+          break;
+        }
       }
     }
   }
-  //
-  myIntersector.Perform(myHS1, dom1, myHS2, dom2, 
-                       TolArc, TolTang, 
-                       myListOfPnts, RestrictLine); 
-  //
+
+  const Standard_Boolean isGeomInt = isTreatAnalityc(aF1, aF2);
+  myIntersector.Perform(myHS1, dom1, myHS2, dom2, TolArc, TolTang, 
+                                  myListOfPnts, RestrictLine, isGeomInt);
+
   myIsDone = myIntersector.IsDone();
-  if (myIsDone) {
+
+  if (myIsDone)
+  {
     myTangentFaces=myIntersector.TangentFaces();
     if (myTangentFaces) {
       return;
@@ -692,8 +774,8 @@ void IntTools_FaceFace::SetList(IntSurf_ListOfPntOn2S& aListOfPnts)
       myListOfPnts.Clear(); // to use LineConstructor
     }
     //
-    aNbLin = myIntersector.NbLines();
-    for (i=1; i<=aNbLin; ++i) {
+    const Standard_Integer aNbLin = myIntersector.NbLines();
+    for (Standard_Integer i=1; i <= aNbLin; ++i) {
       MakeCurve(i, dom1, dom2);
     }
     //
@@ -702,43 +784,47 @@ void IntTools_FaceFace::SetList(IntSurf_ListOfPntOn2S& aListOfPnts)
     if (bReverse) {
       Handle(Geom2d_Curve) aC2D1, aC2D2;
       //
-      aNbLin=mySeqOfCurve.Length();
-      for (i=1; i<=aNbLin; ++i) {
-       IntTools_Curve& aIC=mySeqOfCurve(i);
-       aC2D1=aIC.FirstCurve2d();
-       aC2D2=aIC.SecondCurve2d();
-       //
-       aIC.SetFirstCurve2d(aC2D2);
-       aIC.SetSecondCurve2d(aC2D1);
+      const Standard_Integer aNbLin=mySeqOfCurve.Length();
+      for (Standard_Integer i=1; i<=aNbLin; ++i)
+      {
+        IntTools_Curve& aIC=mySeqOfCurve(i);
+        aC2D1=aIC.FirstCurve2d();
+        aC2D2=aIC.SecondCurve2d();
+        aIC.SetFirstCurve2d(aC2D2);
+        aIC.SetSecondCurve2d(aC2D1);
       }
     }
-    //
+
     // Points
     Standard_Real U1,V1,U2,V2;
     IntTools_PntOnFace aPntOnF1, aPntOnF2;
     IntTools_PntOn2Faces aPntOn2Faces;
     //
-    aNbPnts=myIntersector.NbPnts();
-    for (i=1; i<=aNbPnts; ++i) {
+    const Standard_Integer aNbPnts = myIntersector.NbPnts();
+    for (Standard_Integer i=1; i <= aNbPnts; ++i)
+    {
       const IntSurf_PntOn2S& aISPnt=myIntersector.Point(i).PntOn2S();
       const gp_Pnt& aPnt=aISPnt.Value();
       aISPnt.Parameters(U1,V1,U2,V2);
       aPntOnF1.Init(myFace1, aPnt, U1, V1);
       aPntOnF2.Init(myFace2, aPnt, U2, V2);
       //
-      if (!bReverse) {
-       aPntOn2Faces.SetP1(aPntOnF1);
-       aPntOn2Faces.SetP2(aPntOnF2);
+      if (!bReverse)
+      {
+        aPntOn2Faces.SetP1(aPntOnF1);
+        aPntOn2Faces.SetP2(aPntOnF2);
       }
-      else {
-       aPntOn2Faces.SetP2(aPntOnF1);
-       aPntOn2Faces.SetP1(aPntOnF2);
+      else
+      {
+        aPntOn2Faces.SetP2(aPntOnF1);
+        aPntOn2Faces.SetP1(aPntOnF2);
       }
+
       myPnts.Append(aPntOn2Faces);
     }
-    //
   }
 }
+
 //=======================================================================
 //function :ComputeTolReached3d 
 //purpose  : 
@@ -4656,11 +4742,8 @@ void ApproxParameters(const Handle(GeomAdaptor_HSurface)& aHS1,
 //purpose  : 
 //=======================================================================
 void Tolerances(const Handle(GeomAdaptor_HSurface)& aHS1,
-               const Handle(GeomAdaptor_HSurface)& aHS2,
-               Standard_Real& ,//aTolArc,
-               Standard_Real& aTolTang,
-               Standard_Real& ,//aUVMaxStep,
-               Standard_Real& )//aDeflection)
+                const Handle(GeomAdaptor_HSurface)& aHS2,
+                Standard_Real& aTolTang)
 {
   GeomAbs_SurfaceType aTS1, aTS2;
   //
index 13f8787..2744491 100755 (executable)
@@ -1144,6 +1144,96 @@ static Standard_Integer OCC11758 (Draw_Interpretor& di, Standard_Integer n, cons
   return 0;
 }
 
+#include <Geom_CylindricalSurface.hxx>
+#include <IntTools_FaceFace.hxx>
+#include <IntTools_Curve.hxx>
+#include <IntTools_PntOn2Faces.hxx>
+
+static Standard_Integer OCC24005 (Draw_Interpretor& theDI, Standard_Integer theNArg, const char** theArgv) 
+{
+  if(theNArg < 2)
+  {
+    theDI << "Wrong a number of arguments!\n";
+    return 1;
+  }
+
+  Handle_Geom_Plane plane(new Geom_Plane(
+                                  gp_Ax3( gp_Pnt(-72.948737453424499, 754.30437716359393, 259.52151854671678),
+                                  gp_Dir(6.2471473085930200e-007, -0.99999999999980493, 0.00000000000000000),
+                                  gp_Dir(0.99999999999980493, 6.2471473085930200e-007, 0.00000000000000000))));
+  Handle(Geom_CylindricalSurface) cylinder(
+                  new Geom_CylindricalSurface(
+                                  gp_Ax3(gp_Pnt(-6.4812490053250649, 753.39408794522092, 279.16400974257465),
+                                  gp_Dir(1.0000000000000000, 0.0, 0.00000000000000000),
+                                  gp_Dir(0.0, 1.0000000000000000, 0.00000000000000000)),
+                                                                                          19.712534607908712));
+
+  DrawTrSurf::Set("pln", plane);
+  theDI << "pln\n";
+  DrawTrSurf::Set("cyl", cylinder);
+  theDI << "cyl\n";
+
+  BRep_Builder builder;
+  TopoDS_Face face1, face2;
+  builder.MakeFace(face1, plane, Precision::Confusion());
+  builder.MakeFace(face2, cylinder, Precision::Confusion());
+  IntTools_FaceFace anInters;
+  anInters.SetParameters(false, true, true, Precision::Confusion());
+  anInters.Perform(face1, face2);
+
+  if (!anInters.IsDone())
+  {
+    theDI<<"No intersections found!"<<"\n";
+
+    return 1;
+  }
+
+  //Handle(Geom_Curve) aResult;
+  //gp_Pnt             aPoint;
+
+  const IntTools_SequenceOfCurves& aCvsX=anInters.Lines();
+  const IntTools_SequenceOfPntOn2Faces& aPntsX=anInters.Points();
+
+  char buf[1024];  
+  Standard_Integer aNbCurves, aNbPoints;
+
+  aNbCurves=aCvsX.Length();
+  aNbPoints=aPntsX.Length();
+
+  if (aNbCurves >= 2)
+  {
+    for (Standard_Integer i=1; i<=aNbCurves; ++i)
+    {
+      Sprintf(buf, "%s_%d",theArgv[1],i);
+      theDI << buf << " ";
+      
+      const IntTools_Curve& aIC = aCvsX(i);
+      const Handle(Geom_Curve)& aC3D= aIC.Curve();
+      DrawTrSurf::Set(buf,aC3D);
+    }
+  }
+  else if (aNbCurves == 1)
+  {
+    const IntTools_Curve& aIC = aCvsX(1);
+    const Handle(Geom_Curve)& aC3D= aIC.Curve();
+    Sprintf(buf, "%s",theArgv[1]);
+    theDI << buf << " ";
+    DrawTrSurf::Set(buf,aC3D);
+  }
+
+  for (Standard_Integer i = 1; i<=aNbPoints; ++i)
+  {
+    const IntTools_PntOn2Faces& aPi=aPntsX(i);
+    const gp_Pnt& aP=aPi.P1().Pnt();
+    
+    Sprintf(buf,"%s_p_%d",theArgv[1],i);
+    theDI << buf << " ";
+    DrawTrSurf::Set(buf, aP);
+  }
+
+  return 0;
+}
+
 void QABugs::Commands_19(Draw_Interpretor& theCommands) {
   const char *group = "QABugs";
 
@@ -1163,6 +1253,6 @@ void QABugs::Commands_19(Draw_Interpretor& theCommands) {
   theCommands.Add("OCC23945", "OCC23945 surfname U V X Y Z [DUX DUY DUZ DVX DVY DVZ [D2UX D2UY D2UZ D2VX D2VY D2VZ D2UVX D2UVY D2UVZ]]", __FILE__, OCC23945,group);
   theCommands.Add ("OCC24019", "OCC24019 aShape", __FILE__, OCC24019, group);
   theCommands.Add ("OCC11758", "OCC11758", __FILE__, OCC11758, group);
-
+  theCommands.Add ("OCC24005", "OCC24005 result", __FILE__, OCC24005, group);
   return;
 }
diff --git a/tests/bugs/modalg_5/bug24005 b/tests/bugs/modalg_5/bug24005
new file mode 100755 (executable)
index 0000000..43d6dcc
--- /dev/null
@@ -0,0 +1,35 @@
+puts "============"
+puts "OCC24005"
+puts "============"
+puts ""
+###############################
+## Intersecting a slightly off angle plane with a cylinder takes 7+ seconds
+###############################
+
+pload QAcommands
+
+dchrono h reset
+dchrono h start
+
+OCC24005 result
+
+dchrono h stop
+set q [dchrono h show]
+
+regexp {CPU user time: ([-0-9.+eE]+) seconds} $q full z
+puts "$z"
+
+set max_time 0.1
+if { $z > ${max_time} } {                                         
+    puts "Elapsed time is more than ${max_time} seconds - Faulty"
+} else {
+    puts "Elapsed time is less than ${max_time} seconds - OK"
+}
+
+if { [regexp {Ellipse} [dump result]] == 1 } {
+    puts "result is OK"
+} else {
+    puts "result is Faulty"
+}
+
+set 2dviewer 1