0030675: Visualization - remove redundant proxy classes in hierarchy of PrsMgr_Presen...
[occt.git] / src / IntTools / IntTools_FaceFace.cxx
index e3a2aed..759e5dd 100644 (file)
 #include <TopoDS_Edge.hxx>
 #include <gp_Elips.hxx>
 
-static
-  void TolR3d(const Standard_Real aTolF1,
-              const Standard_Real aTolF2,
-              Standard_Real& myTolReached3d);
-
 static 
   void Parameters(const Handle(GeomAdaptor_HSurface)&,
                   const Handle(GeomAdaptor_HSurface)&,
@@ -95,17 +90,16 @@ static
   Standard_Boolean  ApproxWithPCurves(const gp_Cylinder& theCyl, 
                                       const gp_Sphere& theSph);
 
-static void  PerformPlanes(const Handle(GeomAdaptor_HSurface)& theS1, 
-                           const Handle(GeomAdaptor_HSurface)& theS2, 
+static void  PerformPlanes(const Handle(GeomAdaptor_HSurface)& theS1,
+                           const Handle(GeomAdaptor_HSurface)& theS2,
                            const Standard_Real TolF1,
                            const Standard_Real TolF2,
-                           const Standard_Real TolAng, 
-                           const Standard_Real TolTang, 
+                           const Standard_Real TolAng,
+                           const Standard_Real TolTang,
                            const Standard_Boolean theApprox1,
                            const Standard_Boolean theApprox2,
-                           IntTools_SequenceOfCurves& theSeqOfCurve, 
-                           Standard_Boolean& theTangentFaces,
-                           Standard_Real& TolReached3d);
+                           IntTools_SequenceOfCurves& theSeqOfCurve,
+                           Standard_Boolean& theTangentFaces);
 
 static Standard_Boolean ClassifyLin2d(const Handle(GeomAdaptor_HSurface)& theS, 
                                       const gp_Lin2d& theLin2d, 
@@ -134,7 +128,8 @@ static
 //
 static
   Standard_Boolean CheckPCurve(const Handle(Geom2d_Curve)& aPC, 
-                               const TopoDS_Face& aFace);
+                               const TopoDS_Face& aFace,
+                               const Handle(IntTools_Context)& theCtx);
 
 static
   Standard_Real MaxDistance(const Handle(Geom_Curve)& theC,
@@ -172,9 +167,6 @@ IntTools_FaceFace::IntTools_FaceFace()
   //
   myHS1 = new GeomAdaptor_HSurface ();
   myHS2 = new GeomAdaptor_HSurface ();
-  myTolReached2d=0.; 
-  myTolReached3d=0.;
-  myTolReal = 0.;
   myTolF1 = 0.;
   myTolF2 = 0.;
   myTol = 0.;
@@ -238,22 +230,6 @@ Standard_Boolean IntTools_FaceFace::IsDone() const
   return myIsDone;
 }
 //=======================================================================
-//function : TolReached3d
-//purpose  : 
-//=======================================================================
-Standard_Real IntTools_FaceFace::TolReached3d() const
-{
-  return myTolReached3d;
-}
-//=======================================================================
-//function : TolReal
-//purpose  : 
-//=======================================================================
-Standard_Real IntTools_FaceFace::TolReal() const
-{
-  return myTolReal;
-}
-//=======================================================================
 //function : Lines
 //purpose  : return lines of intersection
 //=======================================================================
@@ -264,14 +240,6 @@ const IntTools_SequenceOfCurves& IntTools_FaceFace::Lines() const
      "IntTools_FaceFace::Lines() => myIntersector NOT DONE");
   return mySeqOfCurve;
 }
-//=======================================================================
-//function : TolReached2d
-//purpose  : 
-//=======================================================================
-Standard_Real IntTools_FaceFace::TolReached2d() const
-{
-  return myTolReached2d;
-}
 // =======================================================================
 // function: SetParameters
 //
@@ -313,26 +281,25 @@ void IntTools_FaceFace::SetList(IntSurf_ListOfPntOn2S& aListOfPnts)
 }
 
 
-static Standard_Boolean isTreatAnalityc(const TopoDS_Face& theF1,
-                                        const TopoDS_Face& theF2,
+static Standard_Boolean isTreatAnalityc(const BRepAdaptor_Surface& theBAS1,
+                                        const BRepAdaptor_Surface& theBAS2,
                                         const Standard_Real theTol)
 {
   const Standard_Real Tolang = 1.e-8;
   Standard_Real aHigh = 0.0;
 
-  const BRepAdaptor_Surface aBAS1(theF1), aBAS2(theF2);
-  const GeomAbs_SurfaceType aType1=aBAS1.GetType();
-  const GeomAbs_SurfaceType aType2=aBAS2.GetType();
+  const GeomAbs_SurfaceType aType1=theBAS1.GetType();
+  const GeomAbs_SurfaceType aType2=theBAS2.GetType();
   
   gp_Pln aS1;
   gp_Cylinder aS2;
   if(aType1 == GeomAbs_Plane)
   {
-    aS1=aBAS1.Plane();
+    aS1=theBAS1.Plane();
   }
   else if(aType2 == GeomAbs_Plane)
   {
-    aS1=aBAS2.Plane();
+    aS1=theBAS2.Plane();
   }
   else
   {
@@ -341,9 +308,9 @@ static Standard_Boolean isTreatAnalityc(const TopoDS_Face& theF1,
 
   if(aType1 == GeomAbs_Cylinder)
   {
-    aS2=aBAS1.Cylinder();
-    const Standard_Real VMin = aBAS1.FirstVParameter();
-    const Standard_Real VMax = aBAS1.LastVParameter();
+    aS2=theBAS1.Cylinder();
+    const Standard_Real VMin = theBAS1.FirstVParameter();
+    const Standard_Real VMax = theBAS1.LastVParameter();
 
     if( Precision::IsNegativeInfinite(VMin) ||
         Precision::IsPositiveInfinite(VMax))
@@ -353,10 +320,10 @@ static Standard_Boolean isTreatAnalityc(const TopoDS_Face& theF1,
   }
   else if(aType2 == GeomAbs_Cylinder)
   {
-    aS2=aBAS2.Cylinder();
+    aS2=theBAS2.Cylinder();
 
-    const Standard_Real VMin = aBAS2.FirstVParameter();
-    const Standard_Real VMax = aBAS2.LastVParameter();
+    const Standard_Real VMin = theBAS2.FirstVParameter();
+    const Standard_Real VMax = theBAS2.LastVParameter();
 
     if( Precision::IsNegativeInfinite(VMin) ||
         Precision::IsPositiveInfinite(VMax))
@@ -391,24 +358,19 @@ static Standard_Boolean isTreatAnalityc(const TopoDS_Face& theF1,
 void IntTools_FaceFace::Perform(const TopoDS_Face& aF1,
                                 const TopoDS_Face& aF2)
 {
-  Standard_Boolean RestrictLine = Standard_False;
-  
   if (myContext.IsNull()) {
     myContext=new IntTools_Context;
   }
 
   mySeqOfCurve.Clear();
-  myTolReached2d=0.;
-  myTolReached3d=0.;
-  myTolReal = 0.;
   myIsDone = Standard_False;
   myNbrestr=0;//?
 
   myFace1=aF1;
   myFace2=aF2;
 
-  const BRepAdaptor_Surface aBAS1(myFace1, Standard_False);
-  const BRepAdaptor_Surface aBAS2(myFace2, Standard_False);
+  const BRepAdaptor_Surface& aBAS1 = myContext->SurfaceAdaptor(myFace1);
+  const BRepAdaptor_Surface& aBAS2 = myContext->SurfaceAdaptor(myFace2);
   GeomAbs_SurfaceType aType1=aBAS1.GetType();
   GeomAbs_SurfaceType aType2=aBAS2.GetType();
 
@@ -462,48 +424,32 @@ void IntTools_FaceFace::Perform(const TopoDS_Face& aF1,
   if(aType1==GeomAbs_Plane && aType2==GeomAbs_Plane)  {
     Standard_Real umin, umax, vmin, vmax;
     //
-    BRepTools::UVBounds(myFace1, umin, umax, vmin, vmax);
-    CorrectPlaneBoundaries(umin, umax, vmin, vmax);
+    myContext->UVBounds(myFace1, umin, umax, vmin, vmax);
     myHS1->ChangeSurface().Load(S1, umin, umax, vmin, vmax);
     //
-    BRepTools::UVBounds(myFace2, umin, umax, vmin, vmax);
-    CorrectPlaneBoundaries(umin, umax, vmin, vmax);
+    myContext->UVBounds(myFace2, umin, umax, vmin, vmax);
     myHS2->ChangeSurface().Load(S2, umin, umax, vmin, vmax);
     //
     Standard_Real TolAng = 1.e-8;
     //
-    PerformPlanes(myHS1, myHS2, 
-                  myTolF1, myTolF2, TolAng, TolTang, 
-                  myApprox1, myApprox2, 
-                  mySeqOfCurve, myTangentFaces, myTolReached3d);
+    PerformPlanes(myHS1, myHS2,
+                  myTolF1, myTolF2, TolAng, TolTang,
+                  myApprox1, myApprox2,
+                  mySeqOfCurve, myTangentFaces);
     //
     myIsDone = Standard_True;
-    
-    if(!myTangentFaces) {
+    //
+    if (!myTangentFaces) {
       const Standard_Integer NbLinPP = mySeqOfCurve.Length();
-      if(NbLinPP) {
-        Standard_Real aTolFMax;
-        aTolFMax=Max(myTolF1, myTolF2);
-        myTolReal = Precision::Confusion();
-        if (aTolFMax > myTolReal) {
-          myTolReal = aTolFMax;
-        }
-        if (aTolFMax > myTolReached3d) {
-          myTolReached3d = aTolFMax;
-        }
-        //
-        myTolReached2d = myTolReal;
-
-        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);
-          }
+      if (NbLinPP && 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);
         }
       }
     }
@@ -514,11 +460,11 @@ void IntTools_FaceFace::Perform(const TopoDS_Face& aF1,
   {
     Standard_Real umin, umax, vmin, vmax;
     // F1
-    BRepTools::UVBounds(myFace1, umin, umax, vmin, vmax); 
+    myContext->UVBounds(myFace1, umin, umax, vmin, vmax); 
     CorrectPlaneBoundaries(umin, umax, vmin, vmax);
     myHS1->ChangeSurface().Load(S1, umin, umax, vmin, vmax);
     // F2
-    BRepTools::UVBounds(myFace2, umin, umax, vmin, vmax);
+    myContext->UVBounds(myFace2, umin, umax, vmin, vmax);
     CorrectSurfaceBoundaries(myFace2, myTol * 2., umin, umax, vmin, vmax);
     myHS2->ChangeSurface().Load(S2, umin, umax, vmin, vmax);
   }
@@ -526,21 +472,21 @@ void IntTools_FaceFace::Perform(const TopoDS_Face& aF1,
   {
     Standard_Real umin, umax, vmin, vmax;
     //F1
-    BRepTools::UVBounds(myFace1, umin, umax, vmin, vmax);
+    myContext->UVBounds(myFace1, umin, umax, vmin, vmax);
     CorrectSurfaceBoundaries(myFace1, myTol * 2., umin, umax, vmin, vmax);
     myHS1->ChangeSurface().Load(S1, umin, umax, vmin, vmax);
     // F2
-    BRepTools::UVBounds(myFace2, umin, umax, vmin, vmax);
+    myContext->UVBounds(myFace2, umin, umax, vmin, vmax);
     CorrectPlaneBoundaries(umin, umax, vmin, vmax);
     myHS2->ChangeSurface().Load(S2, umin, umax, vmin, vmax);
   }
   else
   {
     Standard_Real umin, umax, vmin, vmax;
-    BRepTools::UVBounds(myFace1, umin, umax, vmin, vmax);
+    myContext->UVBounds(myFace1, umin, umax, vmin, vmax);
     CorrectSurfaceBoundaries(myFace1, myTol * 2., umin, umax, vmin, vmax);
     myHS1->ChangeSurface().Load(S1, umin, umax, vmin, vmax);
-    BRepTools::UVBounds(myFace2, umin, umax, vmin, vmax);
+    myContext->UVBounds(myFace2, umin, umax, vmin, vmax);
     CorrectSurfaceBoundaries(myFace2, myTol * 2., umin, umax, vmin, vmax);
     myHS2->ChangeSurface().Load(S2, umin, umax, vmin, vmax);
   }
@@ -559,14 +505,6 @@ void IntTools_FaceFace::Perform(const TopoDS_Face& aF1,
     myIntersector.SetTolerances(TolArc, TolTang, UVMaxStep, Deflection); 
   }
   
-  if((myHS1->IsUClosed() && !myHS1->IsUPeriodic()) || 
-     (myHS1->IsVClosed() && !myHS1->IsVPeriodic()) ||
-     (myHS2->IsUClosed() && !myHS2->IsUPeriodic()) || 
-     (myHS2->IsVClosed() && !myHS2->IsVPeriodic()))
-  {
-    RestrictLine = Standard_True;
-  }
-  //
   if((aType1 != GeomAbs_BSplineSurface) &&
       (aType1 != GeomAbs_BezierSurface)  &&
      (aType1 != GeomAbs_OtherSurface)  &&
@@ -574,8 +512,6 @@ void IntTools_FaceFace::Perform(const TopoDS_Face& aF1,
       (aType2 != GeomAbs_BezierSurface)  &&
      (aType2 != GeomAbs_OtherSurface))
   {
-    RestrictLine = Standard_True;
-
     if ((aType1 == GeomAbs_Torus) ||
         (aType2 == GeomAbs_Torus))
     {
@@ -583,33 +519,9 @@ void IntTools_FaceFace::Perform(const TopoDS_Face& aF1,
     }
   }
 
-  //
-  if(!RestrictLine)
-  {
-    TopExp_Explorer aExp;
-    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;
-        }
-      }
-    }
-  }
-
 #ifdef INTTOOLS_FACEFACE_DEBUG
     if(!myListOfPnts.IsEmpty()) {
       char aBuff[10000];
-      const IntSurf_PntOn2S& aPt = myListOfPnts.First();
-      Standard_Real u1, v1, u2, v2;
-      aPt.Parameters(u1, v1, u2, v2);
 
       Sprintf(aBuff,"bopcurves <face1 face2> -2d");
       IntSurf_ListIteratorOfListOfPntOn2S IterLOP1(myListOfPnts);
@@ -626,9 +538,12 @@ void IntTools_FaceFace::Perform(const TopoDS_Face& aF1,
     }
 #endif
 
-  const Standard_Boolean isGeomInt = isTreatAnalityc(aF1, aF2, myTol);
-  myIntersector.Perform(myHS1, dom1, myHS2, dom2, TolArc, TolTang, 
-                                  myListOfPnts, RestrictLine, isGeomInt);
+  const Standard_Boolean isGeomInt = isTreatAnalityc(aBAS1, aBAS2, myTol);
+  if (aF1.IsSame(aF2))
+    myIntersector.Perform(myHS1, dom1, TolArc, TolTang);
+  else
+    myIntersector.Perform(myHS1, dom1, myHS2, dom2, TolArc, TolTang, 
+                          myListOfPnts, isGeomInt);
 
   myIsDone = myIntersector.IsDone();
 
@@ -639,10 +554,6 @@ void IntTools_FaceFace::Perform(const TopoDS_Face& aF1,
       return;
     }
     //
-    if(RestrictLine) {
-      myListOfPnts.Clear(); // to use LineConstructor
-    }
-    //
     const Standard_Integer aNbLinIntersector = myIntersector.NbLines();
     for (Standard_Integer i=1; i <= aNbLinIntersector; ++i) {
       MakeCurve(i, dom1, dom2, TolArc);
@@ -709,121 +620,78 @@ void IntTools_FaceFace::Perform(const TopoDS_Face& aF1,
 }
 
 //=======================================================================
-//function : ComputeTolerance
+//function :ComputeTolReached3d 
 //purpose  : 
 //=======================================================================
-Standard_Real IntTools_FaceFace::ComputeTolerance()
+void IntTools_FaceFace::ComputeTolReached3d()
 {
-  Standard_Integer i, j, aNbLin;
-  Standard_Real aFirst, aLast, aD, aDMax, aT;
-  Handle(Geom_Surface) aS1, aS2;
+  Standard_Integer i, j, aNbLin = mySeqOfCurve.Length();
+  if (!aNbLin) {
+    return;
+  }
   //
-  aDMax = 0;
-  aNbLin = mySeqOfCurve.Length();
+  // Minimal tangential tolerance for the curve
+  Standard_Real aTolFMax = Max(myTolF1, myTolF2);
   //
-  aS1 = myHS1->ChangeSurface().Surface();
-  aS2 = myHS2->ChangeSurface().Surface();
+  const Handle(Geom_Surface)& aS1 = myHS1->ChangeSurface().Surface();
+  const Handle(Geom_Surface)& aS2 = myHS2->ChangeSurface().Surface();
   //
   for (i = 1; i <= aNbLin; ++i)
   {
-    const IntTools_Curve& aIC = mySeqOfCurve(i);
+    IntTools_Curve& aIC = mySeqOfCurve(i);
     const Handle(Geom_Curve)& aC3D = aIC.Curve();
     if (aC3D.IsNull())
     {
       continue;
     }
     //
-    aFirst = aC3D->FirstParameter();
-    aLast  = aC3D->LastParameter();
+    Standard_Real aTolC = aIC.Tolerance();
+    Standard_Real aFirst = aC3D->FirstParameter();
+    Standard_Real aLast  = aC3D->LastParameter();
     //
+    // Compute the tolerance for the curve
     const Handle(Geom2d_Curve)& aC2D1 = aIC.FirstCurve2d();
     const Handle(Geom2d_Curve)& aC2D2 = aIC.SecondCurve2d();
     //
     for (j = 0; j < 2; ++j)
     {
       const Handle(Geom2d_Curve)& aC2D = !j ? aC2D1 : aC2D2;
-      const Handle(Geom_Surface)& aS = !j ? aS1 : aS2;
-      //
       if (!aC2D.IsNull())
       {
+        // Look for the maximal deviation between 3D and 2D curves
+        Standard_Real aD, aT;
+        const Handle(Geom_Surface)& aS = !j ? aS1 : aS2;
         if (IntTools_Tools::ComputeTolerance
             (aC3D, aC2D, aS, aFirst, aLast, aD, aT))
         {
-          if (aD > aDMax)
+          if (aD > aTolC)
           {
-            aDMax = aD;
+            aTolC = aD;
           }
         }
       }
       else
       {
+        // Look for the maximal deviation between 3D curve and surface
         const TopoDS_Face& aF = !j ? myFace1 : myFace2;
-        aD = FindMaxDistance(aC3D, aFirst, aLast, aF, myContext);
-        if (aD > aDMax)
+        Standard_Real aD = FindMaxDistance(aC3D, aFirst, aLast, aF, myContext);
+        if (aD > aTolC)
         {
-          aDMax = aD;
+          aTolC = aD;
         }
       }
     }
-  }
-  //
-  return aDMax;
-}
-
-//=======================================================================
-//function :ComputeTolReached3d 
-//purpose  : 
-//=======================================================================
-void IntTools_FaceFace::ComputeTolReached3d()
-{
-  Standard_Integer aNbLin;
-  GeomAbs_SurfaceType aType1, aType2;
-  //
-  aNbLin=myIntersector.NbLines();
-  if (!aNbLin) {
-    return;
-  }
-  //
-  aType1=myHS1->Surface().GetType();
-  aType2=myHS2->Surface().GetType();
-  //
-  if (aType1==GeomAbs_Cylinder && aType2==GeomAbs_Cylinder)
-  {
-    if (aNbLin==2)
-    { 
-      Handle(IntPatch_Line) aIL1, aIL2;
-      IntPatch_IType aTL1, aTL2;
-      //
-      aIL1=myIntersector.Line(1);
-      aIL2=myIntersector.Line(2);
-      aTL1=aIL1->ArcType();
-      aTL2=aIL2->ArcType();
-      if (aTL1==IntPatch_Lin && aTL2==IntPatch_Lin) {
-        Standard_Real aD, aDTresh, dTol;
-        gp_Lin aL1, aL2;
-        //
-        dTol=1.e-8;
-        aDTresh=1.5e-6;
-        //
-        aL1=Handle(IntPatch_GLine)::DownCast(aIL1)->Line();
-        aL2=Handle(IntPatch_GLine)::DownCast(aIL2)->Line();
-        aD=aL1.Distance(aL2);
-        aD=0.5*aD;
-        if (aD<aDTresh)
-        {//In order to avoid creation too thin face
-          myTolReached3d=aD+dTol;
-        }
-      }
+    // Set the valid tolerance for the curve
+    aIC.SetTolerance(aTolC);
+    //
+    // Set the tangential tolerance for the curve.
+    // Note, that, currently, computation of the tangential tolerance is
+    // implemented for the Plane/Plane case only.
+    // Thus, set the tangential tolerance equal to maximal tolerance of faces.
+    if (aIC.TangentialTolerance() < aTolFMax) {
+      aIC.SetTangentialTolerance(aTolFMax);
     }
-  }// if (aType1==GeomAbs_Cylinder && aType2==GeomAbs_Cylinder) {
-  //
-
-  Standard_Real aDMax = ComputeTolerance();
-  if (aDMax > myTolReached3d)
-  {
-    myTolReached3d = aDMax;
   }
-  myTolReal = myTolReached3d;
 }
 
 //=======================================================================
@@ -844,8 +712,8 @@ void IntTools_FaceFace::MakeCurve(const Standard_Integer Index,
   IntPatch_IType typl;
   Handle(Geom_Curve) newc;
   //
-  const Standard_Real TOLCHECK   =0.0000001;
-  const Standard_Real TOLANGCHECK=0.1;
+  const Standard_Real TOLCHECK    = 1.e-7;
+  const Standard_Real TOLANGCHECK = 1.e-6;
   //
   rejectSurface = Standard_False;
   reApprox = Standard_False;
@@ -928,11 +796,6 @@ void IntTools_FaceFace::MakeCurve(const Standard_Integer Index,
         new Geom_Hyperbola (Handle(IntPatch_GLine)::DownCast(L)->Hyperbola());
     }
     //
-    // myTolReached3d
-    if (typl == IntPatch_Lin) {
-      TolR3d (myTolF1, myTolF2, myTolReached3d);
-    }
-    //
     aNbParts=myLConstruct.NbParts();
     for (i=1; i<=aNbParts; i++) {
       Standard_Boolean bFNIt, bLPIt;
@@ -949,41 +812,32 @@ void IntTools_FaceFace::MakeCurve(const Standard_Integer Index,
         Handle(Geom_TrimmedCurve) aCT3D=new Geom_TrimmedCurve(newc, fprm, lprm);
         aCurve.SetCurve(aCT3D);
         if (typl == IntPatch_Parabola) {
-          myTolReached3d=IntTools_Tools::CurveTolerance(aCT3D, myTol);
+          Standard_Real aTolC = IntTools_Tools::CurveTolerance(aCT3D, myTol);
+          aCurve.SetTolerance(aTolC);
         }
         //
-        aCurve.SetCurve(new Geom_TrimmedCurve(newc, fprm, lprm));
         if(myApprox1) { 
           Handle (Geom2d_Curve) C2d;
           GeomInt_IntSS::BuildPCurves(fprm, lprm, Tolpc,
                 myHS1->ChangeSurface().Surface(), newc, C2d);
-          if(Tolpc>myTolReached2d || myTolReached2d==0.) { 
-            myTolReached2d=Tolpc;
-          }
-            //            
-            aCurve.SetFirstCurve2d(new Geom2d_TrimmedCurve(C2d,fprm,lprm));
-          }
-          else { 
-            Handle(Geom2d_BSplineCurve) H1;
-            //
-            aCurve.SetFirstCurve2d(H1);
-          }
+
+          if (C2d.IsNull())
+            continue;
+
+          aCurve.SetFirstCurve2d(new Geom2d_TrimmedCurve(C2d, fprm, lprm));
+        }
         //
         if(myApprox2) { 
           Handle (Geom2d_Curve) C2d;
           GeomInt_IntSS::BuildPCurves(fprm, lprm, Tolpc,
                     myHS2->ChangeSurface().Surface(), newc, C2d);
-          if(Tolpc>myTolReached2d || myTolReached2d==0.) { 
-            myTolReached2d=Tolpc;
-          }
-          //
-          aCurve.SetSecondCurve2d(new Geom2d_TrimmedCurve(C2d,fprm,lprm));
-          }
-        else { 
-          Handle(Geom2d_BSplineCurve) H1;
-          //
-          aCurve.SetSecondCurve2d(H1);
+
+          if (C2d.IsNull())
+            continue;
+
+          aCurve.SetSecondCurve2d(new Geom2d_TrimmedCurve(C2d, fprm, lprm));
         }
+        //
         mySeqOfCurve.Append(aCurve);
       } //if (!bFNIt && !bLPIt) {
       else {
@@ -1050,9 +904,6 @@ void IntTools_FaceFace::MakeCurve(const Standard_Integer Index,
         (Handle(IntPatch_GLine)::DownCast(L)->Ellipse());
     }
     //
-    // myTolReached3d
-    TolR3d (myTolF1, myTolF2, myTolReached3d);
-    //
     aNbParts=myLConstruct.NbParts();
     //
     Standard_Real aPeriod, aNul;
@@ -1076,10 +927,8 @@ void IntTools_FaceFace::MakeCurve(const Standard_Integer Index,
         else {
           gp_Pnt P1 = newc->Value(fprm);
           gp_Pnt P2 = newc->Value(aPeriod);
-          Standard_Real aTolDist = myTol;
-          aTolDist = (myTolReached3d > aTolDist) ? myTolReached3d : aTolDist;
 
-          if(P1.Distance(P2) > aTolDist) {
+          if(P1.Distance(P2) > myTol) {
             Standard_Real anewpar = fprm;
 
             if(ParameterOutOfBoundary(fprm, newc, myFace1, myFace2, 
@@ -1099,10 +948,8 @@ void IntTools_FaceFace::MakeCurve(const Standard_Integer Index,
         else {
           gp_Pnt P1 = newc->Value(aNul);
           gp_Pnt P2 = newc->Value(lprm);
-          Standard_Real aTolDist = myTol;
-          aTolDist = (myTolReached3d > aTolDist) ? myTolReached3d : aTolDist;
 
-          if(P1.Distance(P2) > aTolDist) {
+          if(P1.Distance(P2) > myTol) {
             Standard_Real anewpar = lprm;
 
             if(ParameterOutOfBoundary(lprm, newc, myFace1, myFace2, 
@@ -1120,7 +967,6 @@ void IntTools_FaceFace::MakeCurve(const Standard_Integer Index,
         aSeqLprm.Append(lprm);
       }
     }
-    
     //
     aNbParts=aSeqFprm.Length();
     for (i=1; i<=aNbParts; i++) {
@@ -1142,39 +988,17 @@ void IntTools_FaceFace::MakeCurve(const Standard_Integer Index,
             Handle (Geom2d_Curve) C2d;
             GeomInt_IntSS::BuildPCurves(fprm, lprm, Tolpc, 
                         myHS1->ChangeSurface().Surface(), newc, C2d);
-            if(Tolpc>myTolReached2d || myTolReached2d==0) { 
-              myTolReached2d=Tolpc;
-            }
-            //
             aCurve.SetFirstCurve2d(C2d);
           }
-          else { //// 
-            Handle(Geom2d_BSplineCurve) H1;
-            aCurve.SetFirstCurve2d(H1);
-          }
-
 
           if(myApprox2) { 
             Handle (Geom2d_Curve) C2d;
             GeomInt_IntSS::BuildPCurves(fprm,lprm,Tolpc,
                     myHS2->ChangeSurface().Surface(),newc,C2d);
-            if(Tolpc>myTolReached2d || myTolReached2d==0) { 
-              myTolReached2d=Tolpc;
-            }
-            //
             aCurve.SetSecondCurve2d(C2d);
           }
-          else { 
-            Handle(Geom2d_BSplineCurve) H1;
-            aCurve.SetSecondCurve2d(H1);
-          }
-        }
-        
-        else { 
-          Handle(Geom2d_BSplineCurve) H1;
-          aCurve.SetFirstCurve2d(H1);
-          aCurve.SetSecondCurve2d(H1);
         }
+        //
         mySeqOfCurve.Append(aCurve);
           //==============================================        
       } //if (Abs(fprm) > RealEpsilon() || Abs(lprm-2.*M_PI) > RealEpsilon())
@@ -1195,31 +1019,16 @@ void IntTools_FaceFace::MakeCurve(const Standard_Integer Index,
               Handle (Geom2d_Curve) C2d;
               GeomInt_IntSS::BuildPCurves(fprm,lprm,Tolpc,
                     myHS1->ChangeSurface().Surface(),newc,C2d);
-              if(Tolpc>myTolReached2d || myTolReached2d==0) { 
-                myTolReached2d=Tolpc;
-              }
-              //
               aCurve.SetFirstCurve2d(C2d);
             }
-            else { //// 
-              Handle(Geom2d_BSplineCurve) H1;
-              aCurve.SetFirstCurve2d(H1);
-            }
 
             if(myApprox2) { 
               Handle (Geom2d_Curve) C2d;
               GeomInt_IntSS::BuildPCurves(fprm,lprm,Tolpc,
                     myHS2->ChangeSurface().Surface(),newc,C2d);
-              if(Tolpc>myTolReached2d || myTolReached2d==0) { 
-                myTolReached2d=Tolpc;
-              }
-              //
               aCurve.SetSecondCurve2d(C2d);
             }
-            else { 
-              Handle(Geom2d_BSplineCurve) H1;
-              aCurve.SetSecondCurve2d(H1);
-            }
+            //
             mySeqOfCurve.Append(aCurve);
             break;
           }
@@ -1248,40 +1057,16 @@ void IntTools_FaceFace::MakeCurve(const Standard_Integer Index,
                 Handle (Geom2d_Curve) C2d;
                 GeomInt_IntSS::BuildPCurves(fprm, lprm, Tolpc, 
                         myHS1->ChangeSurface().Surface(), newc, C2d);
-                if(Tolpc>myTolReached2d || myTolReached2d==0) { 
-                  myTolReached2d=Tolpc;
-                }
-                // 
                 aCurve.SetFirstCurve2d(C2d);
               }
-              else { 
-                Handle(Geom2d_BSplineCurve) H1;
-                aCurve.SetFirstCurve2d(H1);
-              }
-                
+
               if(myApprox2) { 
                 Handle (Geom2d_Curve) C2d;
                 GeomInt_IntSS::BuildPCurves(fprm, lprm, Tolpc,
                         myHS2->ChangeSurface().Surface(), newc, C2d);
-                if(Tolpc>myTolReached2d || myTolReached2d==0) { 
-                  myTolReached2d=Tolpc;
-                }
-                //                 
                 aCurve.SetSecondCurve2d(C2d);
               }
-                
-              else { 
-                Handle(Geom2d_BSplineCurve) H1;
-                aCurve.SetSecondCurve2d(H1);
-              }
             }//  end of if (typl == IntPatch_Circle || typl == IntPatch_Ellipse)
-             
-            else { 
-              Handle(Geom2d_BSplineCurve) H1;
-              //         
-              aCurve.SetFirstCurve2d(H1);
-              aCurve.SetSecondCurve2d(H1);
-            }
             //==============================================        
             //
             mySeqOfCurve.Append(aCurve);
@@ -1407,14 +1192,13 @@ void IntTools_FaceFace::MakeCurve(const Standard_Integer Index,
                              aSeqOfL, 
                              aReachedTol,
                              myContext);
-      if ( bIsDecomposited && ( myTolReached3d < aReachedTol ) ) {
-        myTolReached3d = aReachedTol;
-      }
       //
       aNbSeqOfL=aSeqOfL.Length();
       //
+      Standard_Real aTolC = 0.;
       if (bIsDecomposited) {
         nbiter=aNbSeqOfL;
+        aTolC = aReachedTol;
       }
       else {
         nbiter=1;
@@ -1492,27 +1276,16 @@ void IntTools_FaceFace::MakeCurve(const Standard_Integer Index,
           IntTools_Curve aIC(aBSp, H1, H2);
           mySeqOfCurve.Append(aIC);
         }
-        
         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;
+          if (typs1 == GeomAbs_Plane || typs2 == GeomAbs_Plane) {
             //
-            if (typs1==GeomAbs_Torus || typs2==GeomAbs_Torus) {
-              if (myTolReached3d<1.e-6) {
-                myTolReached3d = theapp3d.TolReached3d();
-                myTolReached3d=1.e-6;
+            if (typs1 == GeomAbs_Torus || typs2 == GeomAbs_Torus) {
+              if (aTolC < 1.e-6) {
+                aTolC = 1.e-6;
               }
             }
           }
-          else  if( theapp3d.TolReached3d()>myTolReached3d || myTolReached3d==0.) { 
-            myTolReached3d = theapp3d.TolReached3d();
-          }
-          
+          //
           Standard_Integer aNbMultiCurves, nbpoles;
           aNbMultiCurves=theapp3d.NbMultiCurves(); 
           for (j=1; j<=aNbMultiCurves; j++) {
@@ -1565,10 +1338,6 @@ void IntTools_FaceFace::MakeCurve(const Standard_Integer Index,
                 // ############################################
                 aCurve.SetFirstCurve2d(BS1);
               }
-              else {
-                Handle(Geom2d_BSplineCurve) H1;
-                aCurve.SetFirstCurve2d(H1);
-              }
 
               if(myApprox2) { 
                 mbspc.Curve(2, tpoles2d);
@@ -1592,11 +1361,8 @@ void IntTools_FaceFace::MakeCurve(const Standard_Integer Index,
                 // 
                 aCurve.SetSecondCurve2d(BS2);
               }
-              else { 
-                Handle(Geom2d_BSplineCurve) H2;
-                //                 
-                  aCurve.SetSecondCurve2d(H2);
-              }
+              //
+              aCurve.SetTolerance(aTolC);
               //
               mySeqOfCurve.Append(aCurve);
 
@@ -1630,6 +1396,7 @@ void IntTools_FaceFace::MakeCurve(const Standard_Integer Index,
               //         
               IntTools_Curve aCurve;
               aCurve.SetCurve(BS);
+              aCurve.SetTolerance(aTolC);
 
               if(myApprox2) {
                 Handle(Geom2d_BSplineCurve) BS1=new Geom2d_BSplineCurve(tpoles2d,
@@ -1648,14 +1415,10 @@ void IntTools_FaceFace::MakeCurve(const Standard_Integer Index,
                   }
                 }
                 // ###########################################
-                bPCurvesOk = CheckPCurve(BS1, myFace2);
+                bPCurvesOk = CheckPCurve(BS1, myFace2, myContext);
                 aCurve.SetSecondCurve2d(BS1);
               }
-              else {
-                Handle(Geom2d_BSplineCurve) H2;
-                aCurve.SetSecondCurve2d(H2);
-              }
-              
+
               if(myApprox1) { 
                 mbspc.Curve(1,tpoles2d);
                 Handle(Geom2d_BSplineCurve) BS2=new Geom2d_BSplineCurve(tpoles2d,
@@ -1674,14 +1437,9 @@ void IntTools_FaceFace::MakeCurve(const Standard_Integer Index,
                   }
                 }
                 // ###########################################
-                bPCurvesOk = bPCurvesOk && CheckPCurve(BS2, myFace1);
+                bPCurvesOk = bPCurvesOk && CheckPCurve(BS2, myFace1, myContext);
                 aCurve.SetFirstCurve2d(BS2);
               }
-              else { 
-                Handle(Geom2d_BSplineCurve) H1;
-                //                 
-                aCurve.SetFirstCurve2d(H1);
-              }
               //
               //if points of the pcurves are out of the faces bounds
               //create 3d and 2d curves without approximation
@@ -1693,18 +1451,18 @@ void IntTools_FaceFace::MakeCurve(const Standard_Integer Index,
                 
                 if(myApprox1) {
                   H1 = GeomInt_IntSS::MakeBSpline2d(WL, ifprm, ilprm, Standard_True);
-                  bPCurvesOk = CheckPCurve(H1, myFace1);
+                  bPCurvesOk = CheckPCurve(H1, myFace1, myContext);
                 }
                 
                 if(myApprox2) {
                   H2 = GeomInt_IntSS::MakeBSpline2d(WL, ifprm, ilprm, Standard_False);
-                  bPCurvesOk = bPCurvesOk && CheckPCurve(H2, myFace2);
+                  bPCurvesOk = bPCurvesOk && CheckPCurve(H2, myFace2, myContext);
                 }
                 //
                 //if pcurves created without approximation are out of the 
                 //faces bounds, use approximated 3d and 2d curves
                 if (bPCurvesOk) {
-                  IntTools_Curve aIC(aBSp, H1, H2);
+                  IntTools_Curve aIC(aBSp, H1, H2, aTolC);
                   mySeqOfCurve.Append(aIC);
                 } else {
                   mySeqOfCurve.Append(aCurve);
@@ -1718,8 +1476,7 @@ void IntTools_FaceFace::MakeCurve(const Standard_Integer Index,
             else { //typs2 != GeomAbs_Plane && typs1 != GeomAbs_Plane
               Standard_Boolean bIsValid1, bIsValid2;
               Handle(Geom_BSplineCurve) BS;
-              Handle(Geom2d_BSplineCurve) aH2D;        
-              IntTools_Curve aCurve; 
+              IntTools_Curve aCurve;
               //
               bIsValid1=Standard_True;
               bIsValid2=Standard_True;
@@ -1734,10 +1491,9 @@ void IntTools_FaceFace::MakeCurve(const Standard_Integer Index,
                                                                  mbspc.Degree());
               GeomLib_CheckBSplineCurve Check(BS,TOLCHECK,TOLANGCHECK);
               Check.FixTangent(Standard_True,Standard_True);
-              //                 
+              //
               aCurve.SetCurve(BS);
-              aCurve.SetFirstCurve2d(aH2D);
-              aCurve.SetSecondCurve2d(aH2D);
+              aCurve.SetTolerance(aTolC);
               //
               if(myApprox1) { 
                 if(anApprox1) {
@@ -1746,14 +1502,14 @@ void IntTools_FaceFace::MakeCurve(const Standard_Integer Index,
                   mbspc.Curve(2,tpoles2d);
                   //
                   BS1=new Geom2d_BSplineCurve(tpoles2d,
-                                                                        mbspc.Knots(),
-                                                                        mbspc.Multiplicities(),
-                                                                        mbspc.Degree());
+                                              mbspc.Knots(),
+                                              mbspc.Multiplicities(),
+                                              mbspc.Degree());
                   GeomLib_Check2dBSplineCurve newCheck(BS1,TOLCHECK,TOLANGCHECK);
                   newCheck.FixTangent(Standard_True,Standard_True);
                   //         
                   if (!reApprox) {
-                    bIsValid1=CheckPCurve(BS1, myFace1);
+                    bIsValid1=CheckPCurve(BS1, myFace1, myContext);
                   }
                   //
                   aCurve.SetFirstCurve2d(BS1);
@@ -1785,7 +1541,7 @@ void IntTools_FaceFace::MakeCurve(const Standard_Integer Index,
                   newCheck.FixTangent(Standard_True,Standard_True);
                 //                 
                   if (!reApprox) {
-                    bIsValid2=CheckPCurve(BS2, myFace2);        
+                    bIsValid2=CheckPCurve(BS2, myFace2, myContext);
                   }
                   aCurve.SetSecondCurve2d(BS2);
                 }
@@ -1955,7 +1711,7 @@ void IntTools_FaceFace::MakeCurve(const Standard_Integer Index,
     quad1.SetValue(HS1->Surface().Torus());
     break;
   default:
-    Standard_ConstructionError::Raise("GeomInt_IntSS::MakeCurve");
+    throw Standard_ConstructionError("GeomInt_IntSS::MakeCurve");
   }
   
   typs = HS2->Surface().GetType();
@@ -1976,7 +1732,7 @@ void IntTools_FaceFace::MakeCurve(const Standard_Integer Index,
     quad2.SetValue(HS2->Surface().Torus());
     break;
   default:
-    Standard_ConstructionError::Raise("GeomInt_IntSS::MakeCurve");
+    throw Standard_ConstructionError("GeomInt_IntSS::MakeCurve");
   }
 
   quad1.Parameters(Ptref,U1,V1);
@@ -2238,24 +1994,6 @@ Handle(Geom_Curve) MakeBSpline  (const Handle(IntPatch_WLine)& WL,
   }
 }
 
-//=======================================================================
-//function : TolR3d
-//purpose  : 
-//=======================================================================
-void TolR3d(const Standard_Real aTolF1,
-            const Standard_Real aTolF2,
-            Standard_Real& myTolReached3d)
-{
-  Standard_Real aTolFMax, aTolTresh;
-      
-  aTolTresh=2.999999e-3;
-  aTolFMax=Max(aTolF1, aTolF2);
-  
-  if (aTolFMax>aTolTresh) {
-    myTolReached3d=aTolFMax;
-  }
-}
-
 // ------------------------------------------------------------------------------------------------
 // static function: ParameterOutOfBoundary
 // purpose:         Computes a new parameter for given curve. The corresponding 2d points 
@@ -2440,17 +2178,16 @@ Standard_Boolean ApproxWithPCurves(const gp_Cylinder& theCyl,
 //function : PerformPlanes
 //purpose  : 
 //=======================================================================
-void  PerformPlanes(const Handle(GeomAdaptor_HSurface)& theS1, 
-                    const Handle(GeomAdaptor_HSurface)& theS2, 
-                    const Standard_Real TolF1, 
-                    const Standard_Real TolF2, 
-                    const Standard_Real TolAng, 
-                    const Standard_Real TolTang, 
+void  PerformPlanes(const Handle(GeomAdaptor_HSurface)& theS1,
+                    const Handle(GeomAdaptor_HSurface)& theS2,
+                    const Standard_Real TolF1,
+                    const Standard_Real TolF2,
+                    const Standard_Real TolAng,
+                    const Standard_Real TolTang,
                     const Standard_Boolean theApprox1,
                     const Standard_Boolean theApprox2,
-                    IntTools_SequenceOfCurves& theSeqOfCurve, 
-                    Standard_Boolean& theTangentFaces,
-                    Standard_Real& TolReached3d)
+                    IntTools_SequenceOfCurves& theSeqOfCurve,
+                    Standard_Boolean& theTangentFaces)
 {
 
   gp_Pln aPln1 = theS1->Surface().Plane();
@@ -2531,10 +2268,13 @@ void  PerformPlanes(const Handle(GeomAdaptor_HSurface)& theS1,
     Handle(Geom2d_Curve) H1;
     aCurve.SetFirstCurve2d(H1);
   }
-
-  theSeqOfCurve.Append(aCurve);
   //
-  // computation of the tolerance reached
+  // Valid tolerance for the intersection curve between planar faces
+  // is the maximal tolerance between tolerances of faces
+  Standard_Real aTolC = Max(TolF1, TolF2);
+  aCurve.SetTolerance(aTolC);
+  //
+  // Computation of the tangential tolerance
   Standard_Real anAngle, aDt;
   gp_Dir aD1, aD2;
   //
@@ -2543,7 +2283,11 @@ void  PerformPlanes(const Handle(GeomAdaptor_HSurface)& theS1,
   anAngle = aD1.Angle(aD2);
   //
   aDt = IntTools_Tools::ComputeIntRange(TolF1, TolF2, anAngle);
-  TolReached3d = sqrt(aDt*aDt + TolF1*TolF1);
+  Standard_Real aTangTol = sqrt(aDt*aDt + TolF1*TolF1);
+  //
+  aCurve.SetTangentialTolerance(aTangTol);
+  //
+  theSeqOfCurve.Append(aCurve);
 }
 
 //=======================================================================
@@ -2899,28 +2643,25 @@ Standard_Real FindMaxDistance(const Handle(Geom_Curve)& theC,
   aA = theFirst;
   aB = theLast;
   //
-  aX1 = aB - aCf * (aB - aA);
+  aX1=aB - aCf*(aB-aA);
   aF1 = MaxDistance(theC, aX1, theProjPS);
   aX2 = aA + aCf * (aB - aA);
   aF2 = MaxDistance(theC, aX2, theProjPS);
-  //
-  for (;;) {
-    if ((aB - aA) < theEps) {
-      break;
-    }
-    //
+
+  while (Abs(aX1-aX2) > theEps)
+  {
     if (aF1 > aF2) {
       aB = aX2;
       aX2 = aX1;
       aF2 = aF1;
-      aX1 = aB - aCf * (aB - aA); 
+      aX1 = aB-aCf*(aB-aA);
       aF1 = MaxDistance(theC, aX1, theProjPS);
     }
     else {
       aA = aX1;
       aX1 = aX2;
       aF1 = aF2;
-      aX2 = aA + aCf * (aB - aA);
+      aX2=aA+aCf*(aB-aA);
       aF2 = MaxDistance(theC, aX2, theProjPS);
     }
   }
@@ -2961,14 +2702,15 @@ Standard_Real MaxDistance(const Handle(Geom_Curve)& theC,
 //function : CheckPCurve
 //purpose  : Checks if points of the pcurve are out of the face bounds.
 //=======================================================================
-  Standard_Boolean CheckPCurve(const Handle(Geom2d_Curve)& aPC, 
-                               const TopoDS_Face& aFace) 
+  Standard_Boolean CheckPCurve(const Handle(Geom2d_Curve)& aPC,
+                               const TopoDS_Face& aFace,
+                               const Handle(IntTools_Context)& theCtx)
 {
   const Standard_Integer NPoints = 23;
   Standard_Integer i;
   Standard_Real umin,umax,vmin,vmax;
 
-  BRepTools::UVBounds(aFace, umin, umax, vmin, vmax);
+  theCtx->UVBounds(aFace, umin, umax, vmin, vmax);
   Standard_Real tolU = Max ((umax-umin)*0.01, Precision::Confusion());
   Standard_Real tolV = Max ((vmax-vmin)*0.01, Precision::Confusion());
   Standard_Real fp = aPC->FirstParameter();