0024650: Wrong intersection curves obtained for a surface of revolution and a plane.
authorifv <ifvr@opencascade.com>
Thu, 6 Mar 2014 11:11:23 +0000 (15:11 +0400)
committerabv <abv@opencascade.com>
Thu, 6 Mar 2014 11:50:31 +0000 (15:50 +0400)
Test case for issue CR24650

src/GeomInt/GeomInt_IntSS_1.cxx
src/IntPatch/IntPatch_ImpPrmIntersection.cxx
tests/bugs/modalg_2/bug497_5
tests/bugs/modalg_5/bug24650 [new file with mode: 0644]
tests/bugs/moddata_2/bug254

index 38b7552..31f53e0 100644 (file)
@@ -35,6 +35,7 @@
 #include <IntPatch_Line.hxx>
 #include <IntPatch_WLine.hxx>
 #include <IntPatch_GLine.hxx>
+#include <IntPatch_RLine.hxx>
 #include <IntPatch_ALineToWLine.hxx>
 #include <IntPatch_IType.hxx>
 #include <NCollection_IncAllocator.hxx>
@@ -48,6 +49,7 @@
 #include <GeomAbs_SurfaceType.hxx>
 #include <GeomAbs_CurveType.hxx>
 
+#include <GeomAdaptor.hxx>
 #include <Geom_Curve.hxx>
 #include <Geom_Line.hxx>
 #include <Geom_Parabola.hxx>
@@ -57,6 +59,8 @@
 #include <Geom_Ellipse.hxx>
 #include <Geom_BSplineCurve.hxx>
 
+#include <Geom2dAdaptor.hxx>
+#include <Adaptor2d_HCurve2d.hxx>
 #include <Geom2d_Curve.hxx>
 #include <Geom2d_BSplineCurve.hxx>
 #include <Geom2d_TrimmedCurve.hxx>
@@ -64,7 +68,7 @@
 #include <GeomLib_CheckBSplineCurve.hxx>
 #include <GeomLib_Check2dBSplineCurve.hxx>
 #include <GeomProjLib.hxx>
-
+#include <Approx_CurveOnSurface.hxx>
 
 #include <ElSLib.hxx>
 
@@ -141,6 +145,16 @@ static
   void GetQuadric(const Handle(GeomAdaptor_HSurface)& HS1,
                  IntSurf_Quadric& quad1);
 
+static
+    void TreatRLine(const Handle(IntPatch_RLine)& theRL, 
+                    const Handle(GeomAdaptor_HSurface)& theHS1, 
+                    const Handle(GeomAdaptor_HSurface)& theHS2, 
+                    const Standard_Boolean theApprox1, 
+                    const Standard_Boolean theApprox2, 
+                    Handle(Geom_Curve)& theC3d,
+                    Handle(Geom2d_Curve)& theC2d1, 
+                    Handle(Geom2d_Curve)& theC2d2, 
+                    Standard_Real& theTolReached);
 
 //
 
@@ -286,9 +300,9 @@ Standard_Real ProjectPointOnSurf::LowerDistance() const
   Handle(Geom_Curve) newc;
 
   switch (typl) {
-  //########################################  
-  // Line, Parabola, Hyperbola
-  //########################################  
+    //########################################  
+    // Line, Parabola, Hyperbola
+    //########################################  
   case IntPatch_Lin:
   case IntPatch_Parabola: 
   case IntPatch_Hyperbola: {
@@ -305,43 +319,36 @@ Standard_Real ProjectPointOnSurf::LowerDistance() const
     aNbParts=myLConstruct.NbParts();
     for (i=1; i<=aNbParts; i++) {
       myLConstruct.Part(i, fprm, lprm);
-      
+
       if (!Precision::IsNegativeInfinite(fprm) && 
-         !Precision::IsPositiveInfinite(lprm)) {
-       // /cto/900/F1
-       //if (typl == IntPatch_Lin) {
-         //Standard_Real dPrm=1.3e-6;
-         //fprm=fprm-dPrm;
-         //lprm=lprm+dPrm;
-       //}
-       //
-       Handle(Geom_TrimmedCurve) aCT3D=new Geom_TrimmedCurve(newc, fprm, lprm);
-       sline.Append(aCT3D);
-       //
-       if(myApprox1) { 
-         Handle (Geom2d_Curve) C2d;
-         BuildPCurves(fprm, lprm, Tolpc, myHS1->ChangeSurface().Surface(), newc, C2d);
-         if(Tolpc>myTolReached2d || myTolReached2d==0.) { 
-           myTolReached2d=Tolpc;
-         }
-         slineS1.Append(new Geom2d_TrimmedCurve(C2d,fprm,lprm));
-       }
-       else { 
-         slineS1.Append(H1);
-       }
-       //
-       if(myApprox2) { 
-    Handle (Geom2d_Curve) C2d;
-    BuildPCurves(fprm,lprm,Tolpc,myHS2->ChangeSurface().Surface(),newc,C2d);
-    if(Tolpc>myTolReached2d || myTolReached2d==0.) { 
-      myTolReached2d=Tolpc;
-    }
-    //
-    slineS2.Append(new Geom2d_TrimmedCurve(C2d,fprm,lprm));
-  }
-  else { 
-    slineS2.Append(H1);
-  }
+        !Precision::IsPositiveInfinite(lprm)) {
+          Handle(Geom_TrimmedCurve) aCT3D=new Geom_TrimmedCurve(newc, fprm, lprm);
+          sline.Append(aCT3D);
+          //
+          if(myApprox1) { 
+            Handle (Geom2d_Curve) C2d;
+            BuildPCurves(fprm, lprm, Tolpc, myHS1->ChangeSurface().Surface(), newc, C2d);
+            if(Tolpc>myTolReached2d || myTolReached2d==0.) { 
+              myTolReached2d=Tolpc;
+            }
+            slineS1.Append(new Geom2d_TrimmedCurve(C2d,fprm,lprm));
+          }
+          else { 
+            slineS1.Append(H1);
+          }
+          //
+          if(myApprox2) { 
+            Handle (Geom2d_Curve) C2d;
+            BuildPCurves(fprm,lprm,Tolpc,myHS2->ChangeSurface().Surface(),newc,C2d);
+            if(Tolpc>myTolReached2d || myTolReached2d==0.) { 
+              myTolReached2d=Tolpc;
+            }
+            //
+            slineS2.Append(new Geom2d_TrimmedCurve(C2d,fprm,lprm));
+          }
+          else { 
+            slineS2.Append(H1);
+          }
       } // if (!Precision::IsNegativeInfinite(fprm) &&  !Precision::IsPositiveInfinite(lprm))
 
       else {
@@ -389,22 +396,22 @@ Standard_Real ProjectPointOnSurf::LowerDistance() const
         }
       }
     }// end of for (i=1; i<=myLConstruct.NbParts(); i++)
-   }// case IntPatch_Lin:  case IntPatch_Parabola:  case IntPatch_Hyperbola:
-   break;
+  }// case IntPatch_Lin:  case IntPatch_Parabola:  case IntPatch_Hyperbola:
+  break;
 
-  //########################################  
-  // Circle and Ellipse
-  //########################################  
+                           //########################################  
+                           // Circle and Ellipse
+                           //########################################  
   case IntPatch_Circle: 
   case IntPatch_Ellipse: {
 
     if (typl == IntPatch_Circle) {
       newc = new Geom_Circle
-       (Handle(IntPatch_GLine)::DownCast(L)->Circle());
+        (Handle(IntPatch_GLine)::DownCast(L)->Circle());
     }
     else { 
       newc = new Geom_Ellipse
-       (Handle(IntPatch_GLine)::DownCast(L)->Ellipse());
+        (Handle(IntPatch_GLine)::DownCast(L)->Ellipse());
     }
     //
     Standard_Real aPeriod, aRealEpsilon;
@@ -418,127 +425,127 @@ Standard_Real ProjectPointOnSurf::LowerDistance() const
       myLConstruct.Part(i, fprm, lprm);
       //
       if (Abs(fprm) > aRealEpsilon || Abs(lprm-aPeriod) > aRealEpsilon) {
-       //==============================================
-       Handle(Geom_TrimmedCurve) aTC3D=new Geom_TrimmedCurve(newc,fprm,lprm);
-       //
-       sline.Append(aTC3D);
-       //
-       fprm=aTC3D->FirstParameter();
-       lprm=aTC3D->LastParameter ();
-       ////    
-       if(myApprox1) { 
-         Handle (Geom2d_Curve) C2d;
-         BuildPCurves(fprm,lprm,Tolpc,myHS1->ChangeSurface().Surface(),newc,C2d);
-         if(Tolpc>myTolReached2d || myTolReached2d==0.) { 
-           myTolReached2d=Tolpc;
-         }
-         slineS1.Append(C2d);
-       }
-       else { //// 
-         slineS1.Append(H1);
-       }
-       //
-       if(myApprox2) { 
-         Handle (Geom2d_Curve) C2d;
-         BuildPCurves(fprm,lprm,Tolpc,myHS2->ChangeSurface().Surface(),newc,C2d);
-         if(Tolpc>myTolReached2d || myTolReached2d==0) { 
-           myTolReached2d=Tolpc;
-         }
-         slineS2.Append(C2d);
-       }
-       else { 
-         slineS2.Append(H1);  
-       }
-       //==============================================        
+        //==============================================
+        Handle(Geom_TrimmedCurve) aTC3D=new Geom_TrimmedCurve(newc,fprm,lprm);
+        //
+        sline.Append(aTC3D);
+        //
+        fprm=aTC3D->FirstParameter();
+        lprm=aTC3D->LastParameter ();
+        ////   
+        if(myApprox1) { 
+          Handle (Geom2d_Curve) C2d;
+          BuildPCurves(fprm,lprm,Tolpc,myHS1->ChangeSurface().Surface(),newc,C2d);
+          if(Tolpc>myTolReached2d || myTolReached2d==0.) { 
+            myTolReached2d=Tolpc;
+          }
+          slineS1.Append(C2d);
+        }
+        else { //// 
+          slineS1.Append(H1);
+        }
+        //
+        if(myApprox2) { 
+          Handle (Geom2d_Curve) C2d;
+          BuildPCurves(fprm,lprm,Tolpc,myHS2->ChangeSurface().Surface(),newc,C2d);
+          if(Tolpc>myTolReached2d || myTolReached2d==0) { 
+            myTolReached2d=Tolpc;
+          }
+          slineS2.Append(C2d);
+        }
+        else { 
+          slineS2.Append(H1);  
+        }
+        //==============================================       
       } //if (Abs(fprm) > RealEpsilon() || Abs(lprm-2.*M_PI) > RealEpsilon())
       //
       else {//  on regarde si on garde
-       //
-       if (aNbParts==1) {
-         if (Abs(fprm) < RealEpsilon() &&  Abs(lprm-2.*M_PI) < RealEpsilon()) {
-           Handle(Geom_TrimmedCurve) aTC3D=new Geom_TrimmedCurve(newc,fprm,lprm);
-           //
-           sline.Append(aTC3D);
-           fprm=aTC3D->FirstParameter();
-           lprm=aTC3D->LastParameter ();
-           
-           if(myApprox1) { 
-             Handle (Geom2d_Curve) C2d;
-             BuildPCurves(fprm,lprm,Tolpc,myHS1->ChangeSurface().Surface(),newc,C2d);
-             if(Tolpc>myTolReached2d || myTolReached2d==0) { 
-               myTolReached2d=Tolpc;
-             }
-             slineS1.Append(C2d);
-           }
-           else { //// 
-             slineS1.Append(H1);
-           }
-
-           if(myApprox2) { 
-             Handle (Geom2d_Curve) C2d;
-             BuildPCurves(fprm,lprm,Tolpc,myHS2->ChangeSurface().Surface(),newc,C2d);
-             if(Tolpc>myTolReached2d || myTolReached2d==0) { 
-               myTolReached2d=Tolpc;
-             }
-             slineS2.Append(C2d);
-           }
-           else { 
-             slineS2.Append(H1);
-           }
-           break;
-         }
-       }
-       //
-       Standard_Real aTwoPIdiv17, u1, v1, u2, v2, TolX;
-       //
-       aTwoPIdiv17=2.*M_PI/17.;
-       //
-       for (j=0; j<=17; j++) {
-         gp_Pnt ptref (newc->Value (j*aTwoPIdiv17));
-         TolX = Precision::Confusion();
-         
-         Parameters(myHS1, myHS2, ptref, u1, v1, u2, v2);
-         ok = (dom1->Classify(gp_Pnt2d(u1,v1),TolX) != TopAbs_OUT);
-         if(ok) { 
-           ok = (dom2->Classify(gp_Pnt2d(u2,v2),TolX) != TopAbs_OUT);
-         }
-         if (ok) {
-           sline.Append(newc);
-           //==============================================
-           if(myApprox1) { 
-             Handle (Geom2d_Curve) C2d;
-             BuildPCurves(fprm, lprm, Tolpc, myHS1->ChangeSurface().Surface(), newc, C2d);
-             if(Tolpc>myTolReached2d || myTolReached2d==0) { 
-               myTolReached2d=Tolpc;
-             }
-             slineS1.Append(C2d);
-           }
-           else { 
-             slineS1.Append(H1);  
-           }
-           
-           if(myApprox2) { 
-             Handle (Geom2d_Curve) C2d;
-             BuildPCurves(fprm, lprm, Tolpc,myHS2->ChangeSurface().Surface(), newc, C2d);
-             if(Tolpc>myTolReached2d || myTolReached2d==0) { 
-               myTolReached2d=Tolpc;
-             } 
-             slineS2.Append(C2d);
-           }
-           else { 
-             slineS2.Append(H1);  
-           }
-           break;
-         }//  end of if (ok) {
-       }//  end of for (Standard_Integer j=0; j<=17; j++)
+        //
+        if (aNbParts==1) {
+          if (Abs(fprm) < RealEpsilon() &&  Abs(lprm-2.*M_PI) < RealEpsilon()) {
+            Handle(Geom_TrimmedCurve) aTC3D=new Geom_TrimmedCurve(newc,fprm,lprm);
+            //
+            sline.Append(aTC3D);
+            fprm=aTC3D->FirstParameter();
+            lprm=aTC3D->LastParameter ();
+
+            if(myApprox1) { 
+              Handle (Geom2d_Curve) C2d;
+              BuildPCurves(fprm,lprm,Tolpc,myHS1->ChangeSurface().Surface(),newc,C2d);
+              if(Tolpc>myTolReached2d || myTolReached2d==0) { 
+                myTolReached2d=Tolpc;
+              }
+              slineS1.Append(C2d);
+            }
+            else { //// 
+              slineS1.Append(H1);
+            }
+
+            if(myApprox2) { 
+              Handle (Geom2d_Curve) C2d;
+              BuildPCurves(fprm,lprm,Tolpc,myHS2->ChangeSurface().Surface(),newc,C2d);
+              if(Tolpc>myTolReached2d || myTolReached2d==0) { 
+                myTolReached2d=Tolpc;
+              }
+              slineS2.Append(C2d);
+            }
+            else { 
+              slineS2.Append(H1);
+            }
+            break;
+          }
+        }
+        //
+        Standard_Real aTwoPIdiv17, u1, v1, u2, v2, TolX;
+        //
+        aTwoPIdiv17=2.*M_PI/17.;
+        //
+        for (j=0; j<=17; j++) {
+          gp_Pnt ptref (newc->Value (j*aTwoPIdiv17));
+          TolX = Precision::Confusion();
+
+          Parameters(myHS1, myHS2, ptref, u1, v1, u2, v2);
+          ok = (dom1->Classify(gp_Pnt2d(u1,v1),TolX) != TopAbs_OUT);
+          if(ok) { 
+            ok = (dom2->Classify(gp_Pnt2d(u2,v2),TolX) != TopAbs_OUT);
+          }
+          if (ok) {
+            sline.Append(newc);
+            //==============================================
+            if(myApprox1) { 
+              Handle (Geom2d_Curve) C2d;
+              BuildPCurves(fprm, lprm, Tolpc, myHS1->ChangeSurface().Surface(), newc, C2d);
+              if(Tolpc>myTolReached2d || myTolReached2d==0) { 
+                myTolReached2d=Tolpc;
+              }
+              slineS1.Append(C2d);
+            }
+            else { 
+              slineS1.Append(H1);  
+            }
+
+            if(myApprox2) { 
+              Handle (Geom2d_Curve) C2d;
+              BuildPCurves(fprm, lprm, Tolpc,myHS2->ChangeSurface().Surface(), newc, C2d);
+              if(Tolpc>myTolReached2d || myTolReached2d==0) { 
+                myTolReached2d=Tolpc;
+              }        
+              slineS2.Append(C2d);
+            }
+            else { 
+              slineS2.Append(H1);  
+            }
+            break;
+          }//  end of if (ok) {
+        }//  end of for (Standard_Integer j=0; j<=17; j++)
       }//  end of else { on regarde si on garde
     }// for (i=1; i<=myLConstruct.NbParts(); i++)
-  }// IntPatch_Circle: IntPatch_Ellipse:
-    break;
-    
-    //########################################  
-    // Analytic
-    //######################################## 
+  }// IntPatch_Circle: IntPatch_Ellipse
+  break;
+
+                         //########################################  
+                         // Analytic
+                         //######################################## 
   case IntPatch_Analytic: {
     IntSurf_Quadric quad1,quad2;
     //
@@ -546,26 +553,26 @@ Standard_Real ProjectPointOnSurf::LowerDistance() const
     GetQuadric(myHS2, quad2);
     //=========
     IntPatch_ALineToWLine convert (quad1, quad2);
-      
+
     if (!myApprox) {
       Handle(Geom2d_BSplineCurve) aH1, aH2;
       //
       aNbParts=myLConstruct.NbParts();
       for (i=1; i<=aNbParts; i++) {
-       myLConstruct.Part(i, fprm, lprm);
-       Handle(IntPatch_WLine) WL = 
-         convert.MakeWLine(Handle(IntPatch_ALine)::DownCast(L), fprm, lprm);
-       //
-       if(myApprox1) {
-         aH1 = MakeBSpline2d(WL, 1, WL->NbPnts(), Standard_True);
-       }
-       
-       if(myApprox2) {
-         aH2 = MakeBSpline2d(WL, 1, WL->NbPnts(), Standard_False);
-       }
-       sline.Append(MakeBSpline(WL,1,WL->NbPnts()));
-       slineS1.Append(aH1);
-       slineS2.Append(aH2);
+        myLConstruct.Part(i, fprm, lprm);
+        Handle(IntPatch_WLine) WL = 
+          convert.MakeWLine(Handle(IntPatch_ALine)::DownCast(L), fprm, lprm);
+        //
+        if(myApprox1) {
+          aH1 = MakeBSpline2d(WL, 1, WL->NbPnts(), Standard_True);
+        }
+
+        if(myApprox2) {
+          aH2 = MakeBSpline2d(WL, 1, WL->NbPnts(), Standard_False);
+        }
+        sline.Append(MakeBSpline(WL,1,WL->NbPnts()));
+        slineS1.Append(aH1);
+        slineS2.Append(aH2);
       }
     } // if (!myApprox)
 
@@ -574,104 +581,104 @@ Standard_Real ProjectPointOnSurf::LowerDistance() const
       Standard_Real tol2d = myTolApprox;
       //       
       theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, Standard_True);
-      
+
       aNbParts=myLConstruct.NbParts();
       for (i=1; i<=aNbParts; i++) {
-       myLConstruct.Part(i, fprm, lprm);
-       Handle(IntPatch_WLine) WL = 
-         convert.MakeWLine(Handle(IntPatch_ALine):: DownCast(L),fprm,lprm);
-
-       theapp3d.Perform(myHS1,myHS2,WL,Standard_True,myApprox1,myApprox2, 1, WL->NbPnts());
-       if (!theapp3d.IsDone()) {
-         //
-         Handle(Geom2d_BSplineCurve) aH1, aH2;
-
-         if(myApprox1) {
-           aH1 = MakeBSpline2d(WL, 1, WL->NbPnts(), Standard_True);
-         }
-         
-         if(myApprox2) {
-           aH2 = MakeBSpline2d(WL, 1, WL->NbPnts(), Standard_False);
-         }
-         sline.Append(MakeBSpline(WL,1,WL->NbPnts()));
-         slineS1.Append(aH1);
-         slineS2.Append(aH1);
-       }
-       //
-       else {
-         if(myApprox1 || myApprox2) { 
-           if( theapp3d.TolReached2d()>myTolReached2d || myTolReached2d==0) { 
-             myTolReached2d = theapp3d.TolReached2d();
-           }
-         }
-         
-         if( theapp3d.TolReached3d()>myTolReached3d || myTolReached3d==0) { 
-           myTolReached3d = theapp3d.TolReached3d();
-         }
-         
-         Standard_Integer aNbMultiCurves, nbpoles;
-         aNbMultiCurves=theapp3d.NbMultiCurves();
-         for (j=1; j<=aNbMultiCurves; j++) {
-           const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
-           
-           nbpoles = mbspc.NbPoles();
-           TColgp_Array1OfPnt tpoles(1, nbpoles);
-           mbspc.Curve(1, tpoles);
-           Handle(Geom_BSplineCurve) BS=new Geom_BSplineCurve(tpoles,
-                                                              mbspc.Knots(),
-                                                              mbspc.Multiplicities(),
-                                                              mbspc.Degree());
-           
-           GeomLib_CheckBSplineCurve Check(BS, myTolCheck, myTolAngCheck);
-           Check.FixTangent(Standard_True,Standard_True);
-           // 
-           sline.Append(BS);
-           //
-           if(myApprox1) { 
-             TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
-             mbspc.Curve(2,tpoles2d);
-             Handle(Geom2d_BSplineCurve) BS2=new Geom2d_BSplineCurve(tpoles2d,
-                                                                     mbspc.Knots(),
-                                                                     mbspc.Multiplicities(),
-                                                                     mbspc.Degree());
-
-             GeomLib_Check2dBSplineCurve newCheck(BS2,myTolCheck,myTolAngCheck);
-             newCheck.FixTangent(Standard_True,Standard_True);
-             slineS1.Append(BS2);              
-           }
-           else {
-             slineS1.Append(H1);
-           }
-           
-           if(myApprox2) { 
-             TColgp_Array1OfPnt2d tpoles2d(1, nbpoles);
-             Standard_Integer TwoOrThree;
-             TwoOrThree=myApprox1 ? 3 : 2;
-             mbspc.Curve(TwoOrThree, tpoles2d);
-             Handle(Geom2d_BSplineCurve) BS2 =new Geom2d_BSplineCurve(tpoles2d,
-                                                                      mbspc.Knots(),
-                                                                      mbspc.Multiplicities(),
-                                                                      mbspc.Degree());
-               
-             GeomLib_Check2dBSplineCurve newCheck(BS2,myTolCheck,myTolAngCheck);
-             newCheck.FixTangent(Standard_True,Standard_True);
-             //        
-             slineS2.Append(BS2);
-           }
-           else { 
-             slineS2.Append(H1);
-           }
-           // 
-         }// for (j=1; j<=aNbMultiCurves; j++) {
-       }// else from if (!theapp3d.IsDone())
+        myLConstruct.Part(i, fprm, lprm);
+        Handle(IntPatch_WLine) WL = 
+          convert.MakeWLine(Handle(IntPatch_ALine):: DownCast(L),fprm,lprm);
+
+        theapp3d.Perform(myHS1,myHS2,WL,Standard_True,myApprox1,myApprox2, 1, WL->NbPnts());
+        if (!theapp3d.IsDone()) {
+          //
+          Handle(Geom2d_BSplineCurve) aH1, aH2;
+
+          if(myApprox1) {
+            aH1 = MakeBSpline2d(WL, 1, WL->NbPnts(), Standard_True);
+          }
+
+          if(myApprox2) {
+            aH2 = MakeBSpline2d(WL, 1, WL->NbPnts(), Standard_False);
+          }
+          sline.Append(MakeBSpline(WL,1,WL->NbPnts()));
+          slineS1.Append(aH1);
+          slineS2.Append(aH1);
+        }
+        //
+        else {
+          if(myApprox1 || myApprox2) { 
+            if( theapp3d.TolReached2d()>myTolReached2d || myTolReached2d==0) { 
+              myTolReached2d = theapp3d.TolReached2d();
+            }
+          }
+
+          if( theapp3d.TolReached3d()>myTolReached3d || myTolReached3d==0) { 
+            myTolReached3d = theapp3d.TolReached3d();
+          }
+
+          Standard_Integer aNbMultiCurves, nbpoles;
+          aNbMultiCurves=theapp3d.NbMultiCurves();
+          for (j=1; j<=aNbMultiCurves; j++) {
+            const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
+
+            nbpoles = mbspc.NbPoles();
+            TColgp_Array1OfPnt tpoles(1, nbpoles);
+            mbspc.Curve(1, tpoles);
+            Handle(Geom_BSplineCurve) BS=new Geom_BSplineCurve(tpoles,
+              mbspc.Knots(),
+              mbspc.Multiplicities(),
+              mbspc.Degree());
+
+            GeomLib_CheckBSplineCurve Check(BS, myTolCheck, myTolAngCheck);
+            Check.FixTangent(Standard_True,Standard_True);
+            // 
+            sline.Append(BS);
+            //
+            if(myApprox1) { 
+              TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
+              mbspc.Curve(2,tpoles2d);
+              Handle(Geom2d_BSplineCurve) BS2=new Geom2d_BSplineCurve(tpoles2d,
+                mbspc.Knots(),
+                mbspc.Multiplicities(),
+                mbspc.Degree());
+
+              GeomLib_Check2dBSplineCurve newCheck(BS2,myTolCheck,myTolAngCheck);
+              newCheck.FixTangent(Standard_True,Standard_True);
+              slineS1.Append(BS2);             
+            }
+            else {
+              slineS1.Append(H1);
+            }
+
+            if(myApprox2) { 
+              TColgp_Array1OfPnt2d tpoles2d(1, nbpoles);
+              Standard_Integer TwoOrThree;
+              TwoOrThree=myApprox1 ? 3 : 2;
+              mbspc.Curve(TwoOrThree, tpoles2d);
+              Handle(Geom2d_BSplineCurve) BS2 =new Geom2d_BSplineCurve(tpoles2d,
+                mbspc.Knots(),
+                mbspc.Multiplicities(),
+                mbspc.Degree());
+
+              GeomLib_Check2dBSplineCurve newCheck(BS2,myTolCheck,myTolAngCheck);
+              newCheck.FixTangent(Standard_True,Standard_True);
+              //       
+              slineS2.Append(BS2);
+            }
+            else { 
+              slineS2.Append(H1);
+            }
+            // 
+          }// for (j=1; j<=aNbMultiCurves; j++) {
+        }// else from if (!theapp3d.IsDone())
       }// for (i=1; i<=aNbParts; i++) {
     }// else { // myApprox=TRUE
   }// case IntPatch_Analytic:
-    break;
-    
-    //########################################  
-    // Walking
-    //######################################## 
+  break;
+
+                          //########################################  
+                          // Walking
+                          //######################################## 
   case IntPatch_Walking:{
     Handle(IntPatch_WLine) WL = 
       Handle(IntPatch_WLine)::DownCast(L);
@@ -681,24 +688,24 @@ Standard_Real ProjectPointOnSurf::LowerDistance() const
     if (!myApprox) {
       aNbParts=myLConstruct.NbParts();
       for (i=1; i<=aNbParts; i++) {
-       myLConstruct.Part(i, fprm, lprm);
-       ifprm=(Standard_Integer)fprm;
-       ilprm=(Standard_Integer)lprm;
-       //        
-       Handle(Geom2d_BSplineCurve) aH1, aH2;
-
-       if(myApprox1) {
-         aH1 = MakeBSpline2d(WL, ifprm, ilprm, Standard_True);
-       }
-       if(myApprox2) {
-         aH2 = MakeBSpline2d(WL, ifprm, ilprm, Standard_False);
-       }
-       //
-       Handle(Geom_Curve) aBSp=MakeBSpline(WL, ifprm, ilprm);
-       //      
-       sline.Append(aBSp);
-       slineS1.Append(aH1);
-       slineS2.Append(aH2);
+        myLConstruct.Part(i, fprm, lprm);
+        ifprm=(Standard_Integer)fprm;
+        ilprm=(Standard_Integer)lprm;
+        //       
+        Handle(Geom2d_BSplineCurve) aH1, aH2;
+
+        if(myApprox1) {
+          aH1 = MakeBSpline2d(WL, ifprm, ilprm, Standard_True);
+        }
+        if(myApprox2) {
+          aH2 = MakeBSpline2d(WL, ifprm, ilprm, Standard_False);
+        }
+        //
+        Handle(Geom_Curve) aBSp=MakeBSpline(WL, ifprm, ilprm);
+        //     
+        sline.Append(aBSp);
+        slineS1.Append(aH1);
+        slineS2.Append(aH2);
       }
     }
     //
@@ -712,14 +719,14 @@ Standard_Real ProjectPointOnSurf::LowerDistance() const
       tol2d = myTolApprox;
       aTolSS=2.e-7;
       if(myHS1 == myHS2) { 
-       theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, Standard_False);      
+        theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, Standard_False);     
       }
       else { 
-       theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, Standard_True);
+        theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, Standard_True);
       }
       //
       bIsDecomposited = 
-       DecompositionOfWLine(WL, myHS1, myHS2, aTolSS, myLConstruct, aSeqOfL);
+        DecompositionOfWLine(WL, myHS1, myHS2, aTolSS, myLConstruct, aSeqOfL);
       //
       aNbParts=myLConstruct.NbParts();
       aNbSeqOfL=aSeqOfL.Length();
@@ -727,283 +734,322 @@ Standard_Real ProjectPointOnSurf::LowerDistance() const
       nbiter = (bIsDecomposited) ? aNbSeqOfL : aNbParts;
       //
       for(i = 1; i <= nbiter; i++) {
-       if(bIsDecomposited) {
-         WL = Handle(IntPatch_WLine)::DownCast(aSeqOfL.Value(i));
-         ifprm = 1;
-         ilprm = WL->NbPnts();
-       }
-       else {
-         myLConstruct.Part(i, fprm, lprm);
-         ifprm = (Standard_Integer)fprm;
-         ilprm = (Standard_Integer)lprm;
-       }
-       //-- lbr : 
-       //-- Si une des surfaces est un plan , on approxime en 2d
-       //-- sur cette surface et on remonte les points 2d en 3d.
-       GeomAbs_SurfaceType typs1, typs2;
-       typs1 = myHS1->Surface().GetType();
-       typs2 = myHS2->Surface().GetType();
-       //
-       if(typs1 == GeomAbs_Plane) { 
-         theapp3d.Perform(myHS1, myHS2, WL, Standard_False,
-                          Standard_True, myApprox2,
-                          ifprm,  ilprm);
-       }         
-       else if(typs2 == GeomAbs_Plane) { 
-         theapp3d.Perform(myHS1,myHS2,WL,Standard_False,
-                          myApprox1,Standard_True,
-                          ifprm,  ilprm);
-       }
-       else { 
-         //
-         if (myHS1 != myHS2){
-           if ((typs1==GeomAbs_BezierSurface || typs1==GeomAbs_BSplineSurface) &&
-               (typs2==GeomAbs_BezierSurface || typs2==GeomAbs_BSplineSurface)) {
-            
-             theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, Standard_True);
-             //Standard_Boolean bUseSurfaces;
-             //bUseSurfaces=NotUseSurfacesForApprox(myFace1, myFace2, WL, ifprm,  ilprm);
-             //if (bUseSurfaces) {
-               //theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, Standard_False);
-             //}
-           }
-         }
-         //
-         theapp3d.Perform(myHS1,myHS2,WL,Standard_True,
-                          myApprox1,myApprox2,
-                          ifprm,  ilprm);
-       }
-        
-       if (!theapp3d.IsDone()) {
-         //      
-         Handle(Geom2d_BSplineCurve) aH1, aH2;
-         //      
-         Handle(Geom_Curve) aBSp=MakeBSpline(WL, ifprm, ilprm);
-         if(myApprox1) {
-           aH1 = MakeBSpline2d(WL, ifprm, ilprm, Standard_True);
-         }
-         if(myApprox2) {
-           aH2 = MakeBSpline2d(WL, ifprm, ilprm, Standard_False);
-         }
-         //
-         sline.Append(aBSp);
-         slineS1.Append(aH1);
-         slineS2.Append(aH2);
-       }//if (!theapp3d.IsDone())
-       
-       else {
-         if(myApprox1 || myApprox2 || (typs1==GeomAbs_Plane || typs2==GeomAbs_Plane)) { 
-           if( theapp3d.TolReached2d()>myTolReached2d || myTolReached2d==0.) { 
-             myTolReached2d = theapp3d.TolReached2d();
-           }
-         }
-         if(typs1==GeomAbs_Plane || typs2==GeomAbs_Plane) { 
-           myTolReached3d = myTolReached2d;
-         }
-         else  if( theapp3d.TolReached3d()>myTolReached3d || myTolReached3d==0.) { 
-           myTolReached3d = theapp3d.TolReached3d();
-         }
-         
-         Standard_Integer aNbMultiCurves, nbpoles;
-         //
-         aNbMultiCurves=theapp3d.NbMultiCurves(); 
-         for (j=1; j<=aNbMultiCurves; j++) {
-           if(typs1 == GeomAbs_Plane) {
-             const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
-             nbpoles = mbspc.NbPoles();
-             
-             TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
-             TColgp_Array1OfPnt   tpoles(1,nbpoles);
-             
-             mbspc.Curve(1,tpoles2d);
-             const gp_Pln&  Pln = myHS1->Surface().Plane();
-             //
-             Standard_Integer ik; 
-             for(ik = 1; ik<= nbpoles; ik++) { 
-               tpoles.SetValue(ik,
-                               ElSLib::Value(tpoles2d.Value(ik).X(),
-                                             tpoles2d.Value(ik).Y(),
-                                             Pln));
-             }
-             //
-             Handle(Geom_BSplineCurve) BS = 
-               new Geom_BSplineCurve(tpoles,
-                                     mbspc.Knots(),
-                                     mbspc.Multiplicities(),
-                                     mbspc.Degree());
-             GeomLib_CheckBSplineCurve Check(BS,myTolCheck,myTolAngCheck);
-             Check.FixTangent(Standard_True, Standard_True);
-             //        
-             sline.Append(BS);
-             //
-             if(myApprox1) { 
-               Handle(Geom2d_BSplineCurve) BS1 = 
-                 new Geom2d_BSplineCurve(tpoles2d,
-                                         mbspc.Knots(),
-                                         mbspc.Multiplicities(),
-                                         mbspc.Degree());
-               GeomLib_Check2dBSplineCurve Check1(BS1,myTolCheck,myTolAngCheck);
-               Check1.FixTangent(Standard_True,Standard_True);
-               //      
-               AdjustUPeriodic (aS1, BS1);  
-               //
-               slineS1.Append(BS1);
-             }
-             else {
-               slineS1.Append(H1);
-             }
+        if(bIsDecomposited) {
+          WL = Handle(IntPatch_WLine)::DownCast(aSeqOfL.Value(i));
+          ifprm = 1;
+          ilprm = WL->NbPnts();
+        }
+        else {
+          myLConstruct.Part(i, fprm, lprm);
+          ifprm = (Standard_Integer)fprm;
+          ilprm = (Standard_Integer)lprm;
+        }
+        //-- lbr : 
+        //-- Si une des surfaces est un plan , on approxime en 2d
+        //-- sur cette surface et on remonte les points 2d en 3d.
+        GeomAbs_SurfaceType typs1, typs2;
+        typs1 = myHS1->Surface().GetType();
+        typs2 = myHS2->Surface().GetType();
+        //
+        if(typs1 == GeomAbs_Plane) { 
+          theapp3d.Perform(myHS1, myHS2, WL, Standard_False,
+            Standard_True, myApprox2,
+            ifprm,  ilprm);
+        }        
+        else if(typs2 == GeomAbs_Plane) { 
+          theapp3d.Perform(myHS1,myHS2,WL,Standard_False,
+            myApprox1,Standard_True,
+            ifprm,  ilprm);
+        }
+        else { 
+          //
+          if (myHS1 != myHS2){
+            if ((typs1==GeomAbs_BezierSurface || typs1==GeomAbs_BSplineSurface) &&
+              (typs2==GeomAbs_BezierSurface || typs2==GeomAbs_BSplineSurface)) {
+
+                theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, Standard_True);
+                //Standard_Boolean bUseSurfaces;
+                //bUseSurfaces=NotUseSurfacesForApprox(myFace1, myFace2, WL, ifprm,  ilprm);
+                //if (bUseSurfaces) {
+                //theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, Standard_False);
+                //}
+            }
+          }
+          //
+          theapp3d.Perform(myHS1,myHS2,WL,Standard_True,
+            myApprox1,myApprox2,
+            ifprm,  ilprm);
+        }
 
-             if(myApprox2) { 
-               mbspc.Curve(2, tpoles2d);
-               
-               Handle(Geom2d_BSplineCurve) BS2 = new Geom2d_BSplineCurve(tpoles2d,
-                                                                         mbspc.Knots(),
-                                                                         mbspc.Multiplicities(),
-                                                                         mbspc.Degree());
-               GeomLib_Check2dBSplineCurve newCheck(BS2,myTolCheck,myTolAngCheck);
-               newCheck.FixTangent(Standard_True,Standard_True);
-               //
-               AdjustUPeriodic (aS2, BS2);  
-               //
-               slineS2.Append(BS2); 
-             }
-             else { 
-               slineS2.Append(H1); 
-             }
-           }//if(typs1 == GeomAbs_Plane) 
-           //
-           else if(typs2 == GeomAbs_Plane) { 
-             const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
-             nbpoles = mbspc.NbPoles();
-             
-             TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
-             TColgp_Array1OfPnt   tpoles(1,nbpoles);
-             mbspc.Curve((myApprox1==Standard_True)? 2 : 1,tpoles2d);
-             const gp_Pln&  Pln = myHS2->Surface().Plane();
-             //
-             Standard_Integer ik; 
-             for(ik = 1; ik<= nbpoles; ik++) { 
-               tpoles.SetValue(ik,
-                               ElSLib::Value(tpoles2d.Value(ik).X(),
-                                             tpoles2d.Value(ik).Y(),
-                                             Pln));
-               
-             }
-             //
-             Handle(Geom_BSplineCurve) BS=new Geom_BSplineCurve(tpoles,
-                                                                mbspc.Knots(),
-                                                                mbspc.Multiplicities(),
-                                                                mbspc.Degree());
-             GeomLib_CheckBSplineCurve Check(BS,myTolCheck,myTolAngCheck);
-             Check.FixTangent(Standard_True,Standard_True);
-             //        
-             sline.Append(BS);
-             //
-             if(myApprox2) {
-               Handle(Geom2d_BSplineCurve) BS1=new Geom2d_BSplineCurve(tpoles2d,
-                                                                       mbspc.Knots(),
-                                                                       mbspc.Multiplicities(),
-                                                                       mbspc.Degree());
-               GeomLib_Check2dBSplineCurve Check1(BS1,myTolCheck,myTolAngCheck);
-               Check1.FixTangent(Standard_True,Standard_True);
-               //
-               //
-               AdjustUPeriodic (aS2, BS1);  
-               //
-               slineS2.Append(BS1);
-             }
-             else {
-               slineS2.Append(H1);
-             }
-             
-             if(myApprox1) { 
-               mbspc.Curve(1,tpoles2d);
-               Handle(Geom2d_BSplineCurve) BS2=new Geom2d_BSplineCurve(tpoles2d,
-                                                                       mbspc.Knots(),
-                                                                       mbspc.Multiplicities(),
-                                                                       mbspc.Degree());
-               GeomLib_Check2dBSplineCurve Check2(BS2,myTolCheck,myTolAngCheck);
-               Check2.FixTangent(Standard_True,Standard_True);
-               // 
-               //
-               AdjustUPeriodic (aS1, BS2);  
-               //      
-               slineS1.Append(BS2);
-             }
-             else { 
-               slineS1.Append(H1);
-             }
-           } // else if(typs2 == GeomAbs_Plane)
-           //
-           else { // typs1!=GeomAbs_Plane && typs2!=GeomAbs_Plane
-             const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
-             nbpoles = mbspc.NbPoles();
-             TColgp_Array1OfPnt tpoles(1,nbpoles);
-             mbspc.Curve(1,tpoles);
-             Handle(Geom_BSplineCurve) BS=new Geom_BSplineCurve(tpoles,
-                                                                mbspc.Knots(),
-                                                                mbspc.Multiplicities(),
-                                                                mbspc.Degree());
-             GeomLib_CheckBSplineCurve Check(BS,myTolCheck,myTolAngCheck);
-             Check.FixTangent(Standard_True,Standard_True);
-             //        
-        //Check IsClosed()
-        Standard_Real aDist = Max(BS->StartPoint().XYZ().SquareModulus(),
-                                  BS->EndPoint().XYZ().SquareModulus());
-        Standard_Real eps = Epsilon(aDist);
-        if(BS->StartPoint().SquareDistance(BS->EndPoint()) < 2.*eps &&
-          !BS->IsClosed() && !BS->IsPeriodic())
-        {
-          //force Closed()
-          gp_Pnt aPm((BS->Pole(1).XYZ() + BS->Pole(BS->NbPoles()).XYZ()) / 2.);
-          BS->SetPole(1, aPm);
-          BS->SetPole(BS->NbPoles(), aPm);
+        if (!theapp3d.IsDone()) {
+          //     
+          Handle(Geom2d_BSplineCurve) aH1, aH2;
+          //     
+          Handle(Geom_Curve) aBSp=MakeBSpline(WL, ifprm, ilprm);
+          if(myApprox1) {
+            aH1 = MakeBSpline2d(WL, ifprm, ilprm, Standard_True);
+          }
+          if(myApprox2) {
+            aH2 = MakeBSpline2d(WL, ifprm, ilprm, Standard_False);
+          }
+          //
+          sline.Append(aBSp);
+          slineS1.Append(aH1);
+          slineS2.Append(aH2);
+        }//if (!theapp3d.IsDone())
+
+        else {
+          if(myApprox1 || myApprox2 || (typs1==GeomAbs_Plane || typs2==GeomAbs_Plane)) { 
+            if( theapp3d.TolReached2d()>myTolReached2d || myTolReached2d==0.) { 
+              myTolReached2d = theapp3d.TolReached2d();
+            }
+          }
+          if(typs1==GeomAbs_Plane || typs2==GeomAbs_Plane) { 
+            myTolReached3d = myTolReached2d;
+          }
+          else  if( theapp3d.TolReached3d()>myTolReached3d || myTolReached3d==0.) { 
+            myTolReached3d = theapp3d.TolReached3d();
+          }
+
+          Standard_Integer aNbMultiCurves, nbpoles;
+          //
+          aNbMultiCurves=theapp3d.NbMultiCurves(); 
+          for (j=1; j<=aNbMultiCurves; j++) {
+            if(typs1 == GeomAbs_Plane) {
+              const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
+              nbpoles = mbspc.NbPoles();
+
+              TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
+              TColgp_Array1OfPnt   tpoles(1,nbpoles);
+
+              mbspc.Curve(1,tpoles2d);
+              const gp_Pln&  Pln = myHS1->Surface().Plane();
+              //
+              Standard_Integer ik; 
+              for(ik = 1; ik<= nbpoles; ik++) { 
+                tpoles.SetValue(ik,
+                  ElSLib::Value(tpoles2d.Value(ik).X(),
+                  tpoles2d.Value(ik).Y(),
+                  Pln));
+              }
+              //
+              Handle(Geom_BSplineCurve) BS = 
+                new Geom_BSplineCurve(tpoles,
+                mbspc.Knots(),
+                mbspc.Multiplicities(),
+                mbspc.Degree());
+              GeomLib_CheckBSplineCurve Check(BS,myTolCheck,myTolAngCheck);
+              Check.FixTangent(Standard_True, Standard_True);
+              //       
+              sline.Append(BS);
+              //
+              if(myApprox1) { 
+                Handle(Geom2d_BSplineCurve) BS1 = 
+                  new Geom2d_BSplineCurve(tpoles2d,
+                  mbspc.Knots(),
+                  mbspc.Multiplicities(),
+                  mbspc.Degree());
+                GeomLib_Check2dBSplineCurve Check1(BS1,myTolCheck,myTolAngCheck);
+                Check1.FixTangent(Standard_True,Standard_True);
+                //     
+                AdjustUPeriodic (aS1, BS1);  
+                //
+                slineS1.Append(BS1);
+              }
+              else {
+                slineS1.Append(H1);
+              }
+
+              if(myApprox2) { 
+                mbspc.Curve(2, tpoles2d);
+
+                Handle(Geom2d_BSplineCurve) BS2 = new Geom2d_BSplineCurve(tpoles2d,
+                  mbspc.Knots(),
+                  mbspc.Multiplicities(),
+                  mbspc.Degree());
+                GeomLib_Check2dBSplineCurve newCheck(BS2,myTolCheck,myTolAngCheck);
+                newCheck.FixTangent(Standard_True,Standard_True);
+                //
+                AdjustUPeriodic (aS2, BS2);  
+                //
+                slineS2.Append(BS2); 
+              }
+              else { 
+                slineS2.Append(H1); 
+              }
+            }//if(typs1 == GeomAbs_Plane) 
+            //
+            else if(typs2 == GeomAbs_Plane) { 
+              const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
+              nbpoles = mbspc.NbPoles();
+
+              TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
+              TColgp_Array1OfPnt   tpoles(1,nbpoles);
+              mbspc.Curve((myApprox1==Standard_True)? 2 : 1,tpoles2d);
+              const gp_Pln&  Pln = myHS2->Surface().Plane();
+              //
+              Standard_Integer ik; 
+              for(ik = 1; ik<= nbpoles; ik++) { 
+                tpoles.SetValue(ik,
+                  ElSLib::Value(tpoles2d.Value(ik).X(),
+                  tpoles2d.Value(ik).Y(),
+                  Pln));
+
+              }
+              //
+              Handle(Geom_BSplineCurve) BS=new Geom_BSplineCurve(tpoles,
+                mbspc.Knots(),
+                mbspc.Multiplicities(),
+                mbspc.Degree());
+              GeomLib_CheckBSplineCurve Check(BS,myTolCheck,myTolAngCheck);
+              Check.FixTangent(Standard_True,Standard_True);
+              //       
+              sline.Append(BS);
+              //
+              if(myApprox2) {
+                Handle(Geom2d_BSplineCurve) BS1=new Geom2d_BSplineCurve(tpoles2d,
+                  mbspc.Knots(),
+                  mbspc.Multiplicities(),
+                  mbspc.Degree());
+                GeomLib_Check2dBSplineCurve Check1(BS1,myTolCheck,myTolAngCheck);
+                Check1.FixTangent(Standard_True,Standard_True);
+                //
+                //
+                AdjustUPeriodic (aS2, BS1);  
+                //
+                slineS2.Append(BS1);
+              }
+              else {
+                slineS2.Append(H1);
+              }
+
+              if(myApprox1) { 
+                mbspc.Curve(1,tpoles2d);
+                Handle(Geom2d_BSplineCurve) BS2=new Geom2d_BSplineCurve(tpoles2d,
+                  mbspc.Knots(),
+                  mbspc.Multiplicities(),
+                  mbspc.Degree());
+                GeomLib_Check2dBSplineCurve Check2(BS2,myTolCheck,myTolAngCheck);
+                Check2.FixTangent(Standard_True,Standard_True);
+                // 
+                //
+                AdjustUPeriodic (aS1, BS2);  
+                //     
+                slineS1.Append(BS2);
+              }
+              else { 
+                slineS1.Append(H1);
+              }
+            } // else if(typs2 == GeomAbs_Plane)
+            //
+            else { // typs1!=GeomAbs_Plane && typs2!=GeomAbs_Plane
+              const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
+              nbpoles = mbspc.NbPoles();
+              TColgp_Array1OfPnt tpoles(1,nbpoles);
+              mbspc.Curve(1,tpoles);
+              Handle(Geom_BSplineCurve) BS=new Geom_BSplineCurve(tpoles,
+                mbspc.Knots(),
+                mbspc.Multiplicities(),
+                mbspc.Degree());
+              GeomLib_CheckBSplineCurve Check(BS,myTolCheck,myTolAngCheck);
+              Check.FixTangent(Standard_True,Standard_True);
+              //       
+              //Check IsClosed()
+              Standard_Real aDist = Max(BS->StartPoint().XYZ().SquareModulus(),
+                BS->EndPoint().XYZ().SquareModulus());
+              Standard_Real eps = Epsilon(aDist);
+              if(BS->StartPoint().SquareDistance(BS->EndPoint()) < 2.*eps &&
+                !BS->IsClosed() && !BS->IsPeriodic())
+              {
+                //force Closed()
+                gp_Pnt aPm((BS->Pole(1).XYZ() + BS->Pole(BS->NbPoles()).XYZ()) / 2.);
+                BS->SetPole(1, aPm);
+                BS->SetPole(BS->NbPoles(), aPm);
+              }
+              sline.Append(BS);
+
+              if(myApprox1) { 
+                TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
+                mbspc.Curve(2,tpoles2d);
+                Handle(Geom2d_BSplineCurve) BS1=new Geom2d_BSplineCurve(tpoles2d,
+                  mbspc.Knots(),
+                  mbspc.Multiplicities(),
+                  mbspc.Degree());
+                GeomLib_Check2dBSplineCurve newCheck(BS1,myTolCheck,myTolAngCheck);
+                newCheck.FixTangent(Standard_True,Standard_True);
+                //
+                AdjustUPeriodic (aS1, BS1);  
+                //
+                slineS1.Append(BS1);
+              }
+              else {
+                slineS1.Append(H1);
+              }
+              if(myApprox2) { 
+                TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
+                mbspc.Curve((myApprox1==Standard_True)? 3 : 2,tpoles2d);
+                Handle(Geom2d_BSplineCurve) BS2=new Geom2d_BSplineCurve(tpoles2d,
+                  mbspc.Knots(),
+                  mbspc.Multiplicities(),
+                  mbspc.Degree());
+                GeomLib_Check2dBSplineCurve newCheck(BS2,myTolCheck,myTolAngCheck);
+                newCheck.FixTangent(Standard_True,Standard_True);
+                //
+                AdjustUPeriodic (aS2, BS2);  
+                //
+                slineS2.Append(BS2);
+              }
+              else { 
+                slineS2.Append(H1);
+              }
+            }// else { // typs1!=GeomAbs_Plane && typs2!=GeomAbs_Plane
+          }// for (j=1; j<=aNbMultiCurves; j++
         }
-             sline.Append(BS);
-             
-             if(myApprox1) { 
-               TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
-               mbspc.Curve(2,tpoles2d);
-               Handle(Geom2d_BSplineCurve) BS1=new Geom2d_BSplineCurve(tpoles2d,
-                                                                       mbspc.Knots(),
-                                                                       mbspc.Multiplicities(),
-                                                                       mbspc.Degree());
-               GeomLib_Check2dBSplineCurve newCheck(BS1,myTolCheck,myTolAngCheck);
-               newCheck.FixTangent(Standard_True,Standard_True);
-               //
-               AdjustUPeriodic (aS1, BS1);  
-               //
-               slineS1.Append(BS1);
-             }
-             else {
-               slineS1.Append(H1);
-             }
-             if(myApprox2) { 
-               TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
-               mbspc.Curve((myApprox1==Standard_True)? 3 : 2,tpoles2d);
-               Handle(Geom2d_BSplineCurve) BS2=new Geom2d_BSplineCurve(tpoles2d,
-                                                                       mbspc.Knots(),
-                                                                       mbspc.Multiplicities(),
-                                                                       mbspc.Degree());
-               GeomLib_Check2dBSplineCurve newCheck(BS2,myTolCheck,myTolAngCheck);
-               newCheck.FixTangent(Standard_True,Standard_True);
-               //
-               AdjustUPeriodic (aS2, BS2);  
-               //
-               slineS2.Append(BS2);
-             }
-             else { 
-               slineS2.Append(H1);
-             }
-           }// else { // typs1!=GeomAbs_Plane && typs2!=GeomAbs_Plane
-         }// for (j=1; j<=aNbMultiCurves; j++
-       }
       }
     }
   }
-    break;
-    
+  break;
+
   case IntPatch_Restriction: 
+    {
+      GeomAbs_SurfaceType typS1 = myHS1->Surface().GetType();
+      GeomAbs_SurfaceType typS2 = myHS2->Surface().GetType();
+      Standard_Boolean isAnalS1 = Standard_False;
+      switch (typS1)
+      {
+      case GeomAbs_Plane:
+      case GeomAbs_Cylinder:
+      case GeomAbs_Sphere:
+      case GeomAbs_Cone: 
+      case GeomAbs_Torus: isAnalS1 = Standard_True; break;
+      default: break;
+      }
+
+      Standard_Integer isAnalS2 = Standard_False;
+      switch (typS2)
+      {
+      case GeomAbs_Plane:
+      case GeomAbs_Cylinder:
+      case GeomAbs_Sphere:
+      case GeomAbs_Cone: 
+      case GeomAbs_Torus: isAnalS2 = Standard_True; break;
+      default: break;
+      }
+
+      if(!isAnalS1 || !isAnalS2)
+      {
+        Handle(IntPatch_RLine) RL = 
+          Handle(IntPatch_RLine)::DownCast(L);
+        Handle(Geom_Curve) aC3d;
+        Handle(Geom2d_Curve) aC2d1, aC2d2;
+        Standard_Real aTolReached;
+        TreatRLine(RL, myHS1, myHS2, myApprox1, myApprox2, aC3d,
+          aC2d1, aC2d2, aTolReached);
+        sline.Append(aC3d);
+        slineS1.Append(aC2d1);
+        slineS2.Append(aC2d2);
+      }
+    }
     break;
 
   }
@@ -1013,6 +1059,74 @@ Standard_Real ProjectPointOnSurf::LowerDistance() const
 //function : AdjustUPeriodic
 //purpose  : 
 //=======================================================================
+void TreatRLine(const Handle(IntPatch_RLine)& theRL, 
+                const Handle(GeomAdaptor_HSurface)& theHS1, 
+                const Handle(GeomAdaptor_HSurface)& theHS2, 
+                const Standard_Boolean theApprox1, 
+                const Standard_Boolean theApprox2, 
+                Handle(Geom_Curve)& theC3d,
+                Handle(Geom2d_Curve)& theC2d1, 
+                Handle(Geom2d_Curve)& theC2d2, 
+                Standard_Real& theTolReached)
+{
+  Handle(GeomAdaptor_HSurface) aGAHS;
+  Handle(Adaptor2d_HCurve2d) anAHC2d;
+  Standard_Real tf, tl;
+  gp_Lin2d aL;
+  // It is assumed that 2d curve is 2d line (rectangular surface domain)
+  if(theRL->IsArcOnS1())
+  {
+    aGAHS = theHS1;
+    anAHC2d = theRL->ArcOnS1();
+    theRL->ParamOnS1(tf, tl);
+    theC2d1 = Geom2dAdaptor::MakeCurve(theRL->ArcOnS1()->Curve2d());
+  }
+  else if (theRL->IsArcOnS2())
+  {
+    aGAHS = theHS2;
+    anAHC2d = theRL->ArcOnS2();
+    theRL->ParamOnS2(tf, tl);
+    theC2d2 = Geom2dAdaptor::MakeCurve(theRL->ArcOnS2()->Curve2d());
+  }
+  else
+  {
+    return;
+  }
+  //
+  //To provide sameparameter it is necessary to get 3d curve as
+  //approximation of curve on surface.
+  Standard_Integer aMaxDeg = 8;
+  Standard_Integer aMaxSeg = 1000;
+  Approx_CurveOnSurface anApp(anAHC2d, aGAHS, tf, tl, Precision::Confusion(),
+                              GeomAbs_C1, aMaxDeg, aMaxSeg, 
+                              Standard_True, Standard_False);
+  if(anApp.HasResult())
+  {
+    theC3d = anApp.Curve3d();
+    theTolReached = anApp.MaxError3d();
+    Standard_Real aTol = Precision::Confusion();
+    if(theRL->IsArcOnS1() && theApprox2)
+    {
+      Handle(Geom_Surface) aS = GeomAdaptor::MakeSurface(theHS1->Surface());
+      BuildPCurves (tf, tl, aTol, 
+                    aS, theC3d, theC2d2);
+    }
+    if(theRL->IsArcOnS2() && theApprox1)
+    {
+      Handle(Geom_Surface) aS = GeomAdaptor::MakeSurface(theHS2->Surface());
+      BuildPCurves (tf, tl, aTol, 
+                    aS, theC3d, theC2d1);
+    }
+    theTolReached = Max(theTolReached, aTol);
+  }
+  //
+
+}
+//
+//=======================================================================
+//function : AdjustUPeriodic
+//purpose  : 
+//=======================================================================
  void AdjustUPeriodic (const Handle(Geom_Surface)& aS, Handle(Geom2d_Curve)& aC2D)
 {
   if (aC2D.IsNull() || !aS->IsUPeriodic())
index 4f25a9d..7932aab 100644 (file)
@@ -22,6 +22,7 @@
 #include <IntSurf_PntOn2S.hxx>
 #include <IntSurf_LineOn2S.hxx>
 #include <IntSurf.hxx>
+#include <IntSurf_InteriorPoint.hxx>
 
 #include <Adaptor2d_HCurve2d.hxx>
 #include <IntSurf_PathPoint.hxx>
@@ -529,24 +530,67 @@ void IntPatch_ImpPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& Sur
     }
   }
   //
-  // Recherche des points interieurs
-  if (!reversed) {
-    if (myIsStartPnt)
-      solins.Perform(Func,Surf2,myUStart,myVStart);
+  Standard_Boolean SearchIns = Standard_True;
+  if(Quad.TypeQuadric() == GeomAbs_Plane && solrst.NbSegments() > 0)
+  {
+    //For such kind of cases it is possible that whole surface is on one side of plane,
+    //plane only touches surface and does not cross it,
+    //so no inner points exist.
+    SearchIns = Standard_False;
+    Handle(Adaptor3d_TopolTool) T;
+    if(reversed)
+    {
+      T = D1;
+    }
     else
-      solins.Perform(Func,Surf2,D2,TolTang);
+    {
+      T = D2;
+    }
+    Standard_Integer aNbSamples = 0;
+    aNbSamples = T->NbSamples();
+    gp_Pnt2d s2d;
+    gp_Pnt s3d;
+    Standard_Real aValf[1], aUVap[2];
+    math_Vector Valf(aValf,1,1), UVap(aUVap,1,2);
+    T->SamplePoint(1,s2d, s3d);
+    UVap(1)=s2d.X(); 
+    UVap(2)=s2d.Y();
+    Func.Value(UVap,Valf);
+    Standard_Real rvalf = Sign(1.,Valf(1));
+    for(i = 2; i <= aNbSamples; ++i)
+    {
+      D1->SamplePoint(i,s2d, s3d);
+      UVap(1)=s2d.X(); 
+      UVap(2)=s2d.Y();
+      Func.Value(UVap,Valf);
+      if(rvalf * Valf(1) < 0.)
+      {
+        SearchIns = Standard_True;
+        break;
+      }   
+    }
   }
-  else {
-    if (myIsStartPnt)
-      solins.Perform(Func,Surf1,myUStart,myVStart);
-    else
-      solins.Perform(Func,Surf1,D1,TolTang);
+  // Recherche des points interieurs
+  NbPointIns = 0;
+  if(SearchIns) {
+    if (!reversed) {
+      if (myIsStartPnt)
+        solins.Perform(Func,Surf2,myUStart,myVStart);
+      else
+        solins.Perform(Func,Surf2,D2,TolTang);
+    }
+    else {
+      if (myIsStartPnt)
+        solins.Perform(Func,Surf1,myUStart,myVStart);
+      else
+        solins.Perform(Func,Surf1,D1,TolTang);
+    }
+    NbPointIns = solins.NbPoints();
+    for (i=1; i <= NbPointIns; i++) {
+      seqpins.Append(solins.Value(i));
+    }
   }
   //
-  NbPointIns = solins.NbPoints();
-  for (i=1; i <= NbPointIns; i++) {
-    seqpins.Append(solins.Value(i));
-  }
   NbPointDep=seqpdep.Length();
   //
   if (NbPointDep || NbPointIns) {
@@ -722,69 +766,71 @@ void IntPatch_ImpPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& Sur
         wline = new IntPatch_WLine(thelin,Standard_False,trans1,trans2);
 
         if (   iwline->HasFirstPoint() 
-          && iwline->IsTangentAtBegining() == Standard_False) {
-            indfirst = iwline->FirstPointIndex();
-            PPoint = seqpdep(indfirst);
-            tgline = PPoint.Direction3d();
-            Standard_Integer themult = PPoint.Multiplicity();
-            for (i=NbPointRst; i>=1; i--) {
-              if (Destination(i) == indfirst) {
-                if (!reversed) { //-- typeS1 = Pln || Cyl || Sph || Cone
-                  Quad.Parameters(PPoint.Value(),U1,V1);
-
-                  if((V1 < Vmin) && (Vmin-V1 < TolV)) V1 = Vmin;
-                  if((V1 > Vmax) && (V1-Vmax < TolV)) V1 = Vmax;
-
-                  PPoint.Parameters(themult,U2,V2);
-                  Surf2->D1(U2,V2,ptbid,d1u,d1v); //-- @@@@
-                }
-                else {  //-- typeS1 != Pln && Cyl && Sph && Cone
-                  Quad.Parameters(PPoint.Value(),U2,V2);
+          && iwline->IsTangentAtBegining() == Standard_False) 
+        {
+          indfirst = iwline->FirstPointIndex();
+          PPoint = seqpdep(indfirst);
+          tgline = PPoint.Direction3d();
+          Standard_Integer themult = PPoint.Multiplicity();
+          for (i=NbPointRst; i>=1; i--) {
+            if (Destination(i) == indfirst) {
+              if (!reversed) { //-- typeS1 = Pln || Cyl || Sph || Cone
+                Quad.Parameters(PPoint.Value(),U1,V1);
+
+                if((V1 < Vmin) && (Vmin-V1 < TolV)) V1 = Vmin;
+                if((V1 > Vmax) && (V1-Vmax < TolV)) V1 = Vmax;
+
+                PPoint.Parameters(themult,U2,V2);
+                Surf2->D1(U2,V2,ptbid,d1u,d1v); //-- @@@@
+              }
+              else {  //-- typeS1 != Pln && Cyl && Sph && Cone
+                Quad.Parameters(PPoint.Value(),U2,V2);
 
-                  if((V2 < Vmin) && (Vmin-V2 < TolV)) V2 = Vmin;
-                  if((V2 > Vmax) && (V2-Vmax < TolV)) V2 = Vmax;
+                if((V2 < Vmin) && (Vmin-V2 < TolV)) V2 = Vmin;
+                if((V2 > Vmax) && (V2-Vmax < TolV)) V2 = Vmax;
 
-                  PPoint.Parameters(themult,U1,V1);
-                  Surf1->D1(U1,V1,ptbid,d1u,d1v); //-- @@@@
-                }
-
-                VecNormale = d1u.Crossed(d1v);                      
-                //-- Modif du 27 Septembre 94 (Recadrage des pts U,V) 
-                ptdeb.SetValue(PPoint.Value(),TolArc,Standard_False);
-                ptdeb.SetParameters(U1,V1,U2,V2);
-                ptdeb.SetParameter(1.);
+                PPoint.Parameters(themult,U1,V1);
+                Surf1->D1(U1,V1,ptbid,d1u,d1v); //-- @@@@
+              }
 
-                Recadre(reversed,typeS1,typeS2,ptdeb,iwline,1,U1,V1,U2,V2);
+              VecNormale = d1u.Crossed(d1v);                      
+              //-- Modif du 27 Septembre 94 (Recadrage des pts U,V) 
+              ptdeb.SetValue(PPoint.Value(),TolArc,Standard_False);
+              ptdeb.SetParameters(U1,V1,U2,V2);
+              ptdeb.SetParameter(1.);
 
-                currentarc = solrst.Point(i).Arc();
-                currentparam = solrst.Point(i).Parameter();
-                currentarc->D1(currentparam,p2d,d2d);
-                tgrst.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
+              Recadre(reversed,typeS1,typeS2,ptdeb,iwline,1,U1,V1,U2,V2);
 
-                Standard_Real squaremagnitudeVecNormale = VecNormale.SquareMagnitude();
-                if(squaremagnitudeVecNormale > 1e-13) { 
-                  DirNormale=VecNormale;
-                  IntSurf::MakeTransition(tgline,tgrst,DirNormale,TLine,TArc);
-                }
-                else { 
-                  TLine.SetValue(Standard_True,IntSurf_Undecided);
-                  TArc.SetValue(Standard_True,IntSurf_Undecided);
-                }
+              currentarc = solrst.Point(i).Arc();
+              currentparam = solrst.Point(i).Parameter();
+              currentarc->D1(currentparam,p2d,d2d);
+              tgrst.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
 
-                ptdeb.SetArc(reversed,currentarc,currentparam,TLine,TArc);
-                if (!solrst.Point(i).IsNew()) {
-                  ptdeb.SetVertex(reversed,solrst.Point(i).Vertex());
-                }
-                wline->AddVertex(ptdeb);
-                if (themult == 0) {
-                  wline->SetFirstPoint(wline->NbVertex());
-                }
+              Standard_Real squaremagnitudeVecNormale = VecNormale.SquareMagnitude();
+              if(squaremagnitudeVecNormale > 1e-13) { 
+                DirNormale=VecNormale;
+                IntSurf::MakeTransition(tgline,tgrst,DirNormale,TLine,TArc);
+              }
+              else { 
+                TLine.SetValue(Standard_True,IntSurf_Undecided);
+                TArc.SetValue(Standard_True,IntSurf_Undecided);
+              }
 
-                themult--;
+              ptdeb.SetArc(reversed,currentarc,currentparam,TLine,TArc);
+              if (!solrst.Point(i).IsNew()) {
+                ptdeb.SetVertex(reversed,solrst.Point(i).Vertex());
               }
+              wline->AddVertex(ptdeb);
+              if (themult == 0) {
+                wline->SetFirstPoint(wline->NbVertex());
+              }
+
+              themult--;
             }
+          }
         }
-        else if (iwline->IsTangentAtBegining()) {
+        else if (iwline->IsTangentAtBegining()) 
+        {
           gp_Pnt psol = thelin->Value(1).Value();
           thelin->Value(1).ParametersOnS1(U1,V1);
           thelin->Value(1).ParametersOnS2(U2,V2);
@@ -794,7 +840,8 @@ void IntPatch_ImpPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& Sur
           wline->AddVertex(ptdeb);
           wline->SetFirstPoint(wline->NbVertex());
         }
-        else { 
+        else 
+        { 
           gp_Pnt psol = thelin->Value(1).Value();
           thelin->Value(1).ParametersOnS1(U1,V1);
           thelin->Value(1).ParametersOnS2(U2,V2);
@@ -807,71 +854,73 @@ void IntPatch_ImpPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& Sur
 
 
         if (   iwline->HasLastPoint() 
-          && iwline->IsTangentAtEnd() == Standard_False) {
-            indlast = iwline->LastPointIndex();
-            PPoint = seqpdep(indlast);
-            tgline = PPoint.Direction3d().Reversed();
-            Standard_Integer themult = PPoint.Multiplicity();
-            for (i=NbPointRst; i >=1; i--) {
-              if (Destination(i) == indlast) {
-                if (!reversed) {
-                  Quad.Parameters(PPoint.Value(),U1,V1);
-
-                  if((V1 < Vmin) && (Vmin-V1 < TolV)) V1 = Vmin;
-                  if((V1 > Vmax) && (V1-Vmax < TolV)) V1 = Vmax;
-
-                  PPoint.Parameters(themult,U2,V2);
-                  Surf2->D1(U2,V2,ptbid,d1u,d1v); //-- @@@@
-                  VecNormale = d1u.Crossed(d1v);                    //-- @@@@
-                }
-                else {
-                  Quad.Parameters(PPoint.Value(),U2,V2);
-
-                  if((V2 < Vmin) && (Vmin-V2 < TolV)) V2 = Vmin;
-                  if((V2 > Vmax) && (V2-Vmax < TolV)) V2 = Vmax;
+          && iwline->IsTangentAtEnd() == Standard_False) 
+        {
+          indlast = iwline->LastPointIndex();
+          PPoint = seqpdep(indlast);
+          tgline = PPoint.Direction3d().Reversed();
+          Standard_Integer themult = PPoint.Multiplicity();
+          for (i=NbPointRst; i >=1; i--) {
+            if (Destination(i) == indlast) {
+              if (!reversed) {
+                Quad.Parameters(PPoint.Value(),U1,V1);
+
+                if((V1 < Vmin) && (Vmin-V1 < TolV)) V1 = Vmin;
+                if((V1 > Vmax) && (V1-Vmax < TolV)) V1 = Vmax;
+
+                PPoint.Parameters(themult,U2,V2);
+                Surf2->D1(U2,V2,ptbid,d1u,d1v); //-- @@@@
+                VecNormale = d1u.Crossed(d1v);                    //-- @@@@
+              }
+              else {
+                Quad.Parameters(PPoint.Value(),U2,V2);
 
-                  PPoint.Parameters(themult,U1,V1);
-                  Surf1->D1(U1,V1,ptbid,d1u,d1v); //-- @@@@
-                  VecNormale = d1u.Crossed(d1v);                    //-- @@@@
-                }
+                if((V2 < Vmin) && (Vmin-V2 < TolV)) V2 = Vmin;
+                if((V2 > Vmax) && (V2-Vmax < TolV)) V2 = Vmax;
 
-                ptfin.SetValue(PPoint.Value(),TolArc,Standard_False);
-                ptfin.SetParameters(U1,V1,U2,V2);
-                ptfin.SetParameter(Nbpts);
+                PPoint.Parameters(themult,U1,V1);
+                Surf1->D1(U1,V1,ptbid,d1u,d1v); //-- @@@@
+                VecNormale = d1u.Crossed(d1v);                    //-- @@@@
+              }
 
-                Recadre(reversed,typeS1,typeS2,ptfin,iwline,Nbpts-1,U1,V1,U2,V2);
+              ptfin.SetValue(PPoint.Value(),TolArc,Standard_False);
+              ptfin.SetParameters(U1,V1,U2,V2);
+              ptfin.SetParameter(Nbpts);
 
-                currentarc = solrst.Point(i).Arc();
-                currentparam = solrst.Point(i).Parameter();
-                currentarc->D1(currentparam,p2d,d2d);
-                tgrst.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
+              Recadre(reversed,typeS1,typeS2,ptfin,iwline,Nbpts-1,U1,V1,U2,V2);
 
+              currentarc = solrst.Point(i).Arc();
+              currentparam = solrst.Point(i).Parameter();
+              currentarc->D1(currentparam,p2d,d2d);
+              tgrst.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
 
-                Standard_Real squaremagnitudeVecNormale = VecNormale.SquareMagnitude();
-                if(squaremagnitudeVecNormale > 1e-13) { 
-                  DirNormale=VecNormale;
-                  IntSurf::MakeTransition(tgline,tgrst,DirNormale,TLine,TArc);
-                }
-                else { 
-                  TLine.SetValue(Standard_True,IntSurf_Undecided);
-                  TArc.SetValue(Standard_True,IntSurf_Undecided);
-                }
 
+              Standard_Real squaremagnitudeVecNormale = VecNormale.SquareMagnitude();
+              if(squaremagnitudeVecNormale > 1e-13) { 
+                DirNormale=VecNormale;
+                IntSurf::MakeTransition(tgline,tgrst,DirNormale,TLine,TArc);
+              }
+              else { 
+                TLine.SetValue(Standard_True,IntSurf_Undecided);
+                TArc.SetValue(Standard_True,IntSurf_Undecided);
+              }
 
-                ptfin.SetArc(reversed,currentarc,currentparam,TLine,TArc);
-                if (!solrst.Point(i).IsNew()) {
-                  ptfin.SetVertex(reversed,solrst.Point(i).Vertex());
-                }
-                wline->AddVertex(ptfin);
-                if (themult == 0) {
-                  wline->SetLastPoint(wline->NbVertex());
-                }
 
-                themult--;
+              ptfin.SetArc(reversed,currentarc,currentparam,TLine,TArc);
+              if (!solrst.Point(i).IsNew()) {
+                ptfin.SetVertex(reversed,solrst.Point(i).Vertex());
+              }
+              wline->AddVertex(ptfin);
+              if (themult == 0) {
+                wline->SetLastPoint(wline->NbVertex());
               }
+
+              themult--;
             }
+          }
         }
-        else if (iwline->IsTangentAtEnd()) {
+        else if (iwline->IsTangentAtEnd()) 
+        {
           gp_Pnt psol = thelin->Value(Nbpts).Value();
           thelin->Value(Nbpts).ParametersOnS1(U1,V1);
           thelin->Value(Nbpts).ParametersOnS2(U2,V2);
@@ -881,7 +930,8 @@ void IntPatch_ImpPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& Sur
           wline->AddVertex(ptfin);
           wline->SetLastPoint(wline->NbVertex());
         }
-        else { 
+        else 
+        { 
           gp_Pnt psol = thelin->Value(Nbpts).Value();
           thelin->Value(Nbpts).ParametersOnS1(U1,V1);
           thelin->Value(Nbpts).ParametersOnS2(U2,V2);
@@ -983,6 +1033,38 @@ void IntPatch_ImpPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& Sur
   if (NbSegm) {
     for(i=1; i<=NbSegm; i++) {
       thesegm = solrst.Segment(i);  
+      //Check if segment is degenerated
+      if(thesegm.HasFirstPoint() && thesegm.HasLastPoint())
+      {
+        Standard_Real tol2 = Precision::Confusion();
+        tol2 *= tol2;
+        const gp_Pnt& aPf = thesegm.FirstPoint().Value();
+        const gp_Pnt& aPl = thesegm.LastPoint().Value();
+        if(aPf.SquareDistance(aPl) <= tol2)
+        {
+          //segment can be degenerated - check inner point
+          paramf = thesegm.FirstPoint().Parameter();
+          paraml = thesegm.LastPoint().Parameter();
+          gp_Pnt2d _p2d = 
+            thesegm.Curve()->Value(.57735 * paramf + 0.42265 * paraml);
+          gp_Pnt aPm;
+          if(reversed)
+          {
+            Surf1->D0(_p2d.X(), _p2d.Y(), aPm);
+          }
+          else
+          {
+            Surf2->D0(_p2d.X(), _p2d.Y(), aPm);
+          }
+          if(aPm.SquareDistance(aPf) <= tol2)
+          {
+            //Degenerated
+            continue;
+          }
+        }
+      }
+
+
       //----------------------------------------------------------------------      
       // on cree une ligne d intersection contenant uniquement le segment.
       // VOIR POUR LA TRANSITION DE LA LIGNE
index 26fb189..e621918 100755 (executable)
@@ -1,4 +1,3 @@
-
 puts "========="
 puts " OCC497 "
 puts "(case 5)"
@@ -19,5 +18,5 @@ if [catch {bfuse result a_1 a_2 } catch_result] {
 } else {
     puts "OCC497 : function FUSE works without hangs up "
 }
-set square 3233.42
+set square 3280.73
 set 2dviewer 0
diff --git a/tests/bugs/modalg_5/bug24650 b/tests/bugs/modalg_5/bug24650
new file mode 100644 (file)
index 0000000..955ffb5
--- /dev/null
@@ -0,0 +1,34 @@
+puts "==========="
+puts "OCC24650"
+puts "==========="
+puts ""
+##############################################################
+# Wrong intersection curves obtained for a surface of revolution and a plane.
+##############################################################
+
+restore [locate_data_file bug24650_fz1365.brep] b1
+restore [locate_data_file bug24650_fz2495.brep] b2
+
+mksurface sb1 b1
+mksurface sb2 b2
+trimu sb1tu sb1 0.242 0.291
+
+set N [intersect i sb1tu sb2]
+
+if { [llength ${N}] != 1} {
+   puts "Error : Wrong intersection curves"
+} else {
+   set info1 [dump i]
+   set type_of_curve "BSplineCurve"
+   if { [regexp ${type_of_curve} ${info1}] != 1 } {
+      puts "Error : Wrong type of intersection curve"
+   } else {
+      puts "OK : Good type of intersection curve"
+   }
+}
+
+smallview
+donly i
+fit
+set only_screen_axo 1
+
index aab2e06..c641129 100755 (executable)
@@ -1,4 +1,3 @@
-
 puts "================"
 puts "OCC254"
 puts "================"
@@ -13,5 +12,5 @@ checkshape shape3
 common result shape1 shape3
 checkshape result
 
-set length 1231.07
+set length 1194.29
 set 2dviewer 0